[vtkusers] Rendering/Computing normals of a surface

Kilgus, Thomas t.kilgus at Dkfz-Heidelberg.de
Fri Apr 12 08:28:43 EDT 2013


Hi everyone,

I'm trying to compute and render normals of certain vertices of a mesh (in fact a Kinect mesh). I assume that I have to compute the normals via vtkPolyDataNormals and display them using a vtkGlyph3d?

I observed some strange behavior which really confused me:


1.       If I create a vtkPlaneSource or load a ball from hard disc and compute normals for that data, everything seems fine. If I load an "open" surface (my Kinect mesh), there are no normals displayed. The documentation says that SetAutoOrientNormals does only work with closed surfaces. But at the moment I don't care about orientation. There should be normals for at least some vertices of an open mesh, shouldn't there?

2.       If I load my Kinect mesh and make a new polydata which contains as much points at (0,0,0) as I have normals and set the normals for the new polydata, the glyph will produce arrows pointing from (0,0,0) to somewhere. This looks pretty good could but could be a random result with empty memory.

3.       If I connect my vtkPlaneSource or the ball directly to the glyph (I skip the vtkPolyDataNormals), normals are still rendered correctly. Does this mean my vtkPlaneSource already contains them from the beginning? Are they computed in the background somewhere inside the glyph3d? Is the vtkPolyDataNormals even necessary? This only works for the plane and the ball - not for the Kinect mesh. I can imagine that a plane automatically computes its normal on Update(), but why does my ball have normals already?

4.       How can I get the normal of a certain vertex Id? If I use vtkFloatArray::SafeDownCast(output->GetPointData()->GetNormals()) are Id's equal to the vertex Id's of the polydata? What happens if I turn splitting on and get multiple normals for each vertex? How is the mapping done?

My code looks as follows:

vtkSmartPointer<vtkPolyData> inputPolyData = //load some data

  // Generate normals
  vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
  normalGenerator->SetInput( inputPolyData );
  normalGenerator->ComputePointNormalsOn();
  normalGenerator->ComputeCellNormalsOff();
  normalGenerator->SetSplitting(0); //I want exactly one normal per vertex
  normalGenerator->Update();

  vtkSmartPointer<vtkPolyDataMapper> mapperNormals =
      vtkSmartPointer<vtkPolyDataMapper>::New();

  //I chose arrows as representation
  vtkSmartPointer<vtkArrowSource> arrow = vtkSmartPointer<vtkArrowSource>::New();
  arrow->Update();

//use the output of vtkPolyDataNormals as input for the glyph3d
vtkSmartPointer<vtkGlyph3D> glyph = vtkSmartPointer<vtkMaskedGlyph3D>::New();
  glyph->SetInput( normalGenerator->GetOutput() );
  glyph->SetSourceConnection(arrow->GetOutputPort());
  glyph->OrientOn();
  glyph->SetVectorModeToUseNormal();
  glyph->Update();

  mapperNormals->SetInputConnection(glyph->GetOutputPort());

//now follows standard code which could be taken from almost any example...
  vtkSmartPointer<vtkActor> actorNormals =
      vtkSmartPointer<vtkActor>::New();
  actorNormals->SetMapper(mapperNormals);

  // Create a renderer, render window, and interactor
  vtkSmartPointer<vtkRenderer> renderer =
      vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow =
      vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
      vtkSmartPointer<vtkRenderWindowInteractor>::New();
  vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
  renderWindowInteractor->SetInteractorStyle(style);
  renderWindowInteractor->SetRenderWindow(renderWindow);

  // Add the actor to the scene
  renderer->AddActor(actorNormals);

  // Render and interact
  renderWindow->Render();
  renderWindowInteractor->Start();

Regards,
Thomas


Thomas Kilgus
German Cancer Research Center (DKFZ)
Div. Medical and Biological Informatics
Junior group: Computer-assisted Interventions (E131)
Im Neuenheimer Feld 280
69120 Heidelberg, Germany
Phone: +49(0) 6221-42-3545

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20130412/5c056518/attachment.htm>


More information about the vtkusers mailing list