The filter vtkWarpScalar can help us to move the point along point normal by the scalar amount times the scale factor. We can change the size of the original model with it as long as there are normals in data.
The following example has two renderers, the left renderer shows the changed sphere by vtkWarpScalar and the right one has the original sphere. I set up the same active camera for both renderers to make interaction operations work on both sides.

#include <vtkActor.h>
#include <vtkDoubleArray.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkWarpScalar.h>
#include <vtkProperty.h>
#include <vtkCamera.h>
#include <vtkMath.h>

int main(int, char *[])
{
  vtkSmartPointer<vtkSphereSource> sphereSource =
    vtkSmartPointer<vtkSphereSource>::New();
  sphereSource->Update();

  vtkSmartPointer<vtkDoubleArray> scalars =
    vtkSmartPointer<vtkDoubleArray>::New();
  int numberOfPoints = sphereSource->GetOutput()->GetNumberOfPoints();
  scalars->SetNumberOfTuples(numberOfPoints);

  for(vtkIdType i = 0; i < numberOfPoints; ++i)
  {
    scalars->SetTuple1(i, 1);
  }

  sphereSource->GetOutput()->GetPointData()->SetScalars(scalars);

  vtkSmartPointer<vtkWarpScalar> warpScalar =
    vtkSmartPointer<vtkWarpScalar>::New();
  warpScalar->SetInputConnection(sphereSource->GetOutputPort());
  warpScalar->SetScaleFactor(1); // use the scalars themselves
  warpScalar->UseNormalOff();
  warpScalar->Update();

  // Visualize
  vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  sphereMapper->SetInputConnection(sphereSource->GetOutputPort());

  vtkSmartPointer<vtkActor> sphereActor =
    vtkSmartPointer<vtkActor>::New();
  sphereActor->SetMapper(sphereMapper);
  sphereActor->GetProperty()->SetColor( 1, 1, 0 );

  vtkSmartPointer<vtkPolyDataMapper> warpMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  warpMapper->SetInputConnection(warpScalar->GetOutputPort());

  vtkSmartPointer<vtkActor> warpActor =
    vtkSmartPointer<vtkActor>::New();
  warpActor->SetMapper(warpMapper);

  // Define viewport ranges
  // (xmin, ymin, xmax, ymax) left-top and right-bottom point
  double leftViewport[4] = {0.0, 0.0, 0.5, 1.0};
  double rightViewport[4] = {0.5, 0.0, 1.0, 1.0};

  // Setup renderers
  vtkSmartPointer<vtkRenderer> leftRenderer =
    vtkSmartPointer<vtkRenderer>::New();
  leftRenderer->SetViewport(leftViewport);
  leftRenderer->SetBackground(.6, .5, .4);

  vtkSmartPointer<vtkRenderer> rightRenderer =
    vtkSmartPointer<vtkRenderer>::New();
  rightRenderer->SetViewport(rightViewport);
  rightRenderer->SetBackground(.4, .5, .6); // rgb

  leftRenderer->AddActor( warpActor );
  rightRenderer->AddActor( sphereActor );

  renderWindow->AddRenderer(leftRenderer);
  renderWindow->AddRenderer(rightRenderer);

  vtkSmartPointer<vtkCamera> camera = 
    vtkSmartPointer<vtkCamera>::New();
  leftRenderer->SetActiveCamera( camera );
  rightRenderer->SetActiveCamera( camera );
  leftRenderer->ResetCamera();

  renderWindow->Render();
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}


If we set different scalars for the sphere, then the filter vtkWarpScalar will move a few points further than others due to the different scalar data. The color of spheres will also be changed.

  vtkMath::RandomSeed(8775070); // for reproducibility
  for(vtkIdType i = 0; i < numberOfPoints; ++i)
  {
    scalars->SetTuple1(i, vtkMath::Random(0.0, 0.5));
  }


If we define normal for vtkWarpScalar object, it will move points along the normal direction.

  warpScalar->UseNormalOn();
  warpScalar->SetNormal(0, 0, 1);


 


0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You cannot copy content of this page