Skip to content
Snippets Groups Projects
vtkDataSetToScaledDataSet.cpp 3.9 KiB
Newer Older
#include "MantidVatesAPI/vtkDataSetToScaledDataSet.h"
#include "MantidKernel/Logger.h"

#include <vtkFieldData.h>
#include <vtkFloatArray.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkUnsignedCharArray.h>
#include <vtkUnstructuredGrid.h>
#include <vtkSmartPointer.h>
#include <vtkMatrix4x4.h>
#include <vtkPVChangeOfBasisHelper.h>

namespace {
Mantid::Kernel::Logger g_log("vtkDataSetTOScaledDataSet");
}

namespace Mantid {
namespace VATES {
/**
 * Standard constructor for object.
 * @param input : The dataset to scale
 * @param output : The resulting scaled dataset
 */
vtkDataSetToScaledDataSet::vtkDataSetToScaledDataSet(
    vtkUnstructuredGrid *input, vtkUnstructuredGrid *output)
    : m_inputData(input), m_outputData(output){
  if (NULL == m_inputData) {
    throw std::runtime_error("Cannot construct vtkDataSetToScaledDataSet with "
                             "NULL input vtkUnstructuredGrid");
  if (NULL == m_outputData) {
    throw std::runtime_error("Cannot construct vtkDataSetToScaledDataSet with "
                             "NULL output vtkUnstructuredGrid");
}

vtkDataSetToScaledDataSet::~vtkDataSetToScaledDataSet() {}

/**
 * Process the input data. First, scale a copy of the points and apply
 * that to the output data. Next, update the metadata for range information.
 * @param xScale : Scale factor for the x direction
 * @param yScale : Scale factor for the y direction
 * @param zScale : Scale factor for the z direction
 */
void vtkDataSetToScaledDataSet::execute(double xScale, double yScale,
                                        double zScale) {
  vtkPoints *points = m_inputData->GetPoints();

  double *point;
  vtkPoints *newPoints = vtkPoints::New();
  newPoints->Allocate(points->GetNumberOfPoints());
  for (int i = 0; i < points->GetNumberOfPoints(); i++) {
    point = points->GetPoint(i);
    point[0] *= xScale;
    point[1] *= yScale;
    point[2] *= zScale;
    newPoints->InsertNextPoint(point);
  }
  // Shallow copy the input.
  m_outputData->ShallowCopy(m_inputData);
  // Give the output dataset the scaled set of points.
  m_outputData->SetPoints(newPoints);
  this->updateMetaData(xScale, yScale, zScale);
}

/**
 * In order for the axis range and labels to not come out scaled,
 * this function set metadata that ParaView will read to override
 * the scaling to return the original presentation.
 * See
 * http://www.paraview.org/ParaQ/Doc/Nightly/html/classvtkCubeAxesRepresentation.html
 * and
 * http://www.paraview.org/ParaView/Doc/Nightly/www/cxx-doc/classvtkPVChangeOfBasisHelper.html
 * for a better understanding.
 * @param xScale : Scale factor for the x direction
 * @param yScale : Scale factor for the y direction
 * @param zScale : Scale factor for the z direction
void vtkDataSetToScaledDataSet::updateMetaData(double xScale, double yScale,
                                               double zScale) {
  // We need to put the scaling on the diagonal elements of the ChangeOfBasis
  // (COB) Matrix.
  vtkSmartPointer<vtkMatrix4x4> cobMatrix =
      vtkSmartPointer<vtkMatrix4x4>::New();
  cobMatrix->Identity();
  cobMatrix->Element[0][0] *= xScale;
  cobMatrix->Element[1][1] *= yScale;
  cobMatrix->Element[2][2] *= zScale;

  if (!vtkPVChangeOfBasisHelper::AddChangeOfBasisMatrixToFieldData(m_outputData,
                                                                   cobMatrix)) {
    g_log.warning("The Change-of-Basis-Matrix could not be added to the field "
                  "data of the scaled data set.\n");
  // We also need to update the bounding box for the COB Matrix
  double boundingBox[6];
  m_inputData->GetBounds(boundingBox);
  if (!vtkPVChangeOfBasisHelper::AddBoundingBoxInBasis(m_outputData,
                                                       boundingBox)) {
    g_log.warning("The bounding box could not be added to the field data of "
                  "the scaled data set.\n");

} // namespace VATES
} // namespace Mantid