Difference between revisions of "VTK/Examples/Cxx/PolyData/PolyDataExtractNormals"

From KitwarePublic
< VTK‎ | Examples‎ | Cxx
Jump to: navigation, search
 
(8 intermediate revisions by 2 users not shown)
Line 3: Line 3:
 
==PolyDataExtractNormals.cxx==
 
==PolyDataExtractNormals.cxx==
 
<source lang="cpp">
 
<source lang="cpp">
 +
#include <vtkVersion.h>
 
#include <vtkCellData.h>
 
#include <vtkCellData.h>
 
#include <vtkDoubleArray.h>
 
#include <vtkDoubleArray.h>
 +
#include <vtkFloatArray.h>
 
#include <vtkPoints.h>
 
#include <vtkPoints.h>
 
#include <vtkPolyData.h>
 
#include <vtkPolyData.h>
 +
#include <vtkPolyDataNormals.h>
 
#include <vtkPointData.h>
 
#include <vtkPointData.h>
 
#include <vtkSmartPointer.h>
 
#include <vtkSmartPointer.h>
 +
#include <vtkSphereSource.h>
 
#include <vtkXMLPolyDataReader.h>
 
#include <vtkXMLPolyDataReader.h>
#include <vtkPolyDataNormals.h>
 
  
bool ReadNormals(vtkPolyData* polydata);
+
void TestPointNormals(vtkPolyData* polydata);
 +
void TestCellNormals(vtkPolyData* polydata);
 +
 
 +
bool GetPointNormals(vtkPolyData* polydata);
 +
bool GetCellNormals(vtkPolyData* polydata);
  
 
int main(int argc, char *argv[])
 
int main(int argc, char *argv[])
 
{
 
{
   //Read File
+
   vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
  vtkstd::string filename = argv[1]; //first command line argument
+
 
    
 
    
   vtkSmartPointer<vtkXMLPolyDataReader> reader =  
+
   // If a file is provided, read it. Else, create a sphere.
      vtkSmartPointer<vtkXMLPolyDataReader>::New();
+
  if(argc == 2)
  cout << "Reading " << filename << endl;
+
    {
  reader->SetFileName(filename.c_str());
+
   
  reader->Update();
+
    // Read File
  vtkPolyData* polydata = reader->GetOutput();
+
    std::string filename = argv[1]; //first command line argument
 +
    std::cout << "Reading file " << filename << "..." << std::endl;
 
    
 
    
  // Try to read normals directly
+
    vtkSmartPointer<vtkXMLPolyDataReader> reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();
  bool hasNormals = ReadNormals(polydata);
+
    std::cout << "Reading " << filename << std::endl;
 
+
    reader->SetFileName(filename.c_str());
  if(hasNormals)
+
    reader->Update();
 +
    polydata->DeepCopy(reader->GetOutput());
 +
    }
 +
  else
 
     {
 
     {
     return EXIT_FAILURE;
+
     std::cout << "Creating a sphere..." << std::endl;
 +
    vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
 +
    sphereSource->Update();
 +
    std::cout << "In main: " << sphereSource->GetOutput()->GetNumberOfPoints() << std::endl;
 +
    polydata->DeepCopy(sphereSource->GetOutput());
 
     }
 
     }
 
+
 
   // generate normals
+
   std::cout << "PolyData address: " << polydata << std::endl;
  vtkSmartPointer<vtkPolyDataNormals> normalGenerator =
+
      vtkSmartPointer<vtkPolyDataNormals>::New();
+
 
    
 
    
   normalGenerator->SetInput(polydata);
+
   TestPointNormals(polydata);
  normalGenerator->Update();
+
  polydata = normalGenerator->GetOutput();
+
 
+
  /*
+
  //optional settings
+
  normalGenerator->SetFeatureAngle(0.1);
+
  normalGenerator->SetSplitting(1);
+
  normalGenerator->SetConsistency(0);
+
  normalGenerator->SetAutoOrientNormals(0);
+
  normalGenerator->SetComputePointNormals(1);
+
  normalGenerator->SetComputeCellNormals(0);
+
  normalGenerator->SetFlipNormals(0);
+
  normalGenerator->SetNonManifoldTraversal(1);
+
  */
+
 
+
  // Try to read normals again
+
  ReadNormals(polydata);
+
 
    
 
    
 +
  TestCellNormals(polydata);
 +
 
   return EXIT_SUCCESS;
 
   return EXIT_SUCCESS;
 
}
 
}
  
bool ReadNormals(vtkPolyData* polydata)
+
void TestPointNormals(vtkPolyData* polydata)
 
{
 
{
   cout << "Reading normals..." << endl;
+
   std::cout << "In TestPointNormals: " << polydata->GetNumberOfPoints() << std::endl;
    
+
  // Try to read normals directly
   //count points
+
  bool hasPointNormals = GetPointNormals(polydata);
 +
 
 +
  if(!hasPointNormals)
 +
    {
 +
    std::cout << "No point normals were found. Computing normals..." << std::endl;
 +
 
 +
    // Generate normals
 +
    vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
 +
#if VTK_MAJOR_VERSION <= 5
 +
    normalGenerator->SetInput(polydata);
 +
#else
 +
    normalGenerator->SetInputData(polydata);
 +
#endif
 +
    normalGenerator->ComputePointNormalsOn();
 +
    normalGenerator->ComputeCellNormalsOff();
 +
    normalGenerator->Update();
 +
    /*
 +
    // Optional settings
 +
    normalGenerator->SetFeatureAngle(0.1);
 +
    normalGenerator->SetSplitting(1);
 +
    normalGenerator->SetConsistency(0);
 +
    normalGenerator->SetAutoOrientNormals(0);
 +
    normalGenerator->SetComputePointNormals(1);
 +
    normalGenerator->SetComputeCellNormals(0);
 +
    normalGenerator->SetFlipNormals(0);
 +
    normalGenerator->SetNonManifoldTraversal(1);
 +
    */
 +
 
 +
    polydata = normalGenerator->GetOutput();
 +
 
 +
    // Try to read normals again
 +
    hasPointNormals = GetPointNormals(polydata);
 +
 
 +
    std::cout << "On the second try, has point normals? " << hasPointNormals << std::endl;
 +
 
 +
    }
 +
   else
 +
    {
 +
    std::cout << "Point normals were found!" << std::endl;
 +
    }
 +
}
 +
 
 +
void TestCellNormals(vtkPolyData* polydata)
 +
{
 +
  // Try to read normals directly
 +
  bool hasCellNormals = GetCellNormals(polydata);
 +
 
 +
  if(!hasCellNormals)
 +
    {
 +
    std::cout << "No cell normals were found. Computing normals..." << std::endl;
 +
 
 +
    // Generate normals
 +
    vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
 +
#if VTK_MAJOR_VERSION <= 5
 +
    normalGenerator->SetInput(polydata);
 +
#else
 +
    normalGenerator->SetInputData(polydata);
 +
#endif
 +
    normalGenerator->ComputePointNormalsOff();
 +
    normalGenerator->ComputeCellNormalsOn();
 +
    normalGenerator->Update();
 +
    /*
 +
    // Optional settings
 +
    normalGenerator->SetFeatureAngle(0.1);
 +
    normalGenerator->SetSplitting(1);
 +
    normalGenerator->SetConsistency(0);
 +
    normalGenerator->SetAutoOrientNormals(0);
 +
    normalGenerator->SetComputePointNormals(1);
 +
    normalGenerator->SetComputeCellNormals(0);
 +
    normalGenerator->SetFlipNormals(0);
 +
    normalGenerator->SetNonManifoldTraversal(1);
 +
    */
 +
 
 +
    polydata = normalGenerator->GetOutput();
 +
 
 +
    // Try to read normals again
 +
    hasCellNormals = GetCellNormals(polydata);
 +
 
 +
    std::cout << "On the second try, has cell normals? " << hasCellNormals << std::endl;
 +
 
 +
    }
 +
  else
 +
    {
 +
    std::cout << "Cell normals were found!" << std::endl;
 +
    }
 +
}
 +
 
 +
 
 +
 
 +
bool GetPointNormals(vtkPolyData* polydata)
 +
{
 +
  std::cout << "In GetPointNormals: " << polydata->GetNumberOfPoints() << std::endl;
 +
  std::cout << "Looking for point normals..." << std::endl;
 +
 
 +
   // Count points
 
   vtkIdType numPoints = polydata->GetNumberOfPoints();
 
   vtkIdType numPoints = polydata->GetNumberOfPoints();
 
   std::cout << "There are " << numPoints << " points." << std::endl;
 
   std::cout << "There are " << numPoints << " points." << std::endl;
  
   //count triangles
+
   // Count triangles
 
   vtkIdType numPolys = polydata->GetNumberOfPolys();
 
   vtkIdType numPolys = polydata->GetNumberOfPolys();
 
   std::cout << "There are " << numPolys << " polys." << std::endl;
 
   std::cout << "There are " << numPolys << " polys." << std::endl;
 
+
 
 
   ////////////////////////////////////////////////////////////////
 
   ////////////////////////////////////////////////////////////////
   //normals in an array
+
   // Double normals in an array
   vtkSmartPointer<vtkDoubleArray> normalData1 =  
+
   vtkDoubleArray* normalDataDouble =
 
     vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetArray("Normals"));
 
     vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetArray("Normals"));
 
+
 
   if(normalData1)
+
   if(normalDataDouble)
     {  
+
     {
     int nc = normalData1->GetNumberOfTuples();
+
     int nc = normalDataDouble->GetNumberOfTuples();
     cout << "There are " << nc << " components in NormalData1 (double Point \"Normals\")" << endl;
+
     std::cout << "There are " << nc
 +
            << " components in normalDataDouble" << std::endl;
 
     return true;
 
     return true;
 
     }
 
     }
 
+
 
 
   ////////////////////////////////////////////////////////////////
 
   ////////////////////////////////////////////////////////////////
   //double point normals
+
   // Double normals in an array
   vtkSmartPointer<vtkDoubleArray> normalData2 =  
+
   vtkFloatArray* normalDataFloat =
     vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetNormals());
+
     vtkFloatArray::SafeDownCast(polydata->GetPointData()->GetArray("Normals"));
 
+
 
   if(normalData2)
+
   if(normalDataFloat)
     {  
+
     {
     cout << "There are " << normalData2->GetNumberOfComponents() << " components in NormalData2 (double Point Normals)" << endl;
+
     int nc = normalDataFloat->GetNumberOfTuples();
 +
    std::cout << "There are " << nc
 +
            << " components in normalDataFloat" << std::endl;
 
     return true;
 
     return true;
 
     }
 
     }
 
 
 
 
  /////////////////////////////////////////////////////////////////////
 
  //double generic (double) point normals
 
  vtkSmartPointer<vtkDataArray> normalData3 = polydata->GetPointData()->GetNormals(); //works
 
  if(normalData3)
 
    {
 
    cout << "There are " << normalData3->GetNumberOfTuples() << " normals in NormalData3 (float Point Normals)" << endl;
 
   
 
    //works
 
    double testDouble[3];
 
    normalData3->GetTuple(0, testDouble);
 
   
 
    cout << "Double: " << testDouble[0] << " " << testDouble[1] << " " << testDouble[2] << endl;
 
 
      
 
      
 +
  ////////////////////////////////////////////////////////////////
 +
  // Point normals
 +
  vtkDoubleArray* normalsDouble =
 +
    vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetNormals());
 +
 +
  if(normalsDouble)
 +
    {
 +
    std::cout << "There are " << normalsDouble->GetNumberOfComponents()
 +
              << " components in normalsDouble" << std::endl;
 
     return true;
 
     return true;
 
     }
 
     }
 
+
 
   ///////////////////////////////////////////////////////////////////////////////////
+
   ////////////////////////////////////////////////////////////////
   //double cell normals
+
   // Point normals
   vtkSmartPointer<vtkDoubleArray> normalData4 = vtkDoubleArray::SafeDownCast(polydata->GetCellData()->GetNormals("cellNormals"));
+
   vtkFloatArray* normalsFloat =
 
+
    vtkFloatArray::SafeDownCast(polydata->GetPointData()->GetNormals());
   if(normalData4)
+
 
     {  
+
   if(normalsFloat)
     cout << "There are " << normalData4->GetNumberOfComponents() << " components in NormalData4 (double Cell \"Cell Normals\")" << endl;
+
     {
 +
     std::cout << "There are " << normalsFloat->GetNumberOfComponents()
 +
              << " components in normalsFloat" << std::endl;
 
     return true;
 
     return true;
 
     }
 
     }
    
+
   
   //if the function has not yet quit, there were none of these types of normals
+
   /////////////////////////////////////////////////////////////////////
   cout << "Normals not found!" << endl;
+
   // Generic type point normals
 +
  vtkDataArray* normalsGeneric = polydata->GetPointData()->GetNormals(); //works
 +
  if(normalsGeneric)
 +
    {
 +
    std::cout << "There are " << normalsGeneric->GetNumberOfTuples()
 +
              << " normals in normalsGeneric" << std::endl;
 +
 
 +
    double testDouble[3];
 +
    normalsGeneric->GetTuple(0, testDouble);
 +
 
 +
    std::cout << "Double: " << testDouble[0] << " "
 +
              << testDouble[1] << " " << testDouble[2] << std::endl;
 +
 
 +
    // Can't do this:
 +
    /*
 +
    float testFloat[3];
 +
    normalsGeneric->GetTuple(0, testFloat);
 +
 
 +
    std::cout << "Float: " << testFloat[0] << " "
 +
              << testFloat[1] << " " << testFloat[2] << std::endl;
 +
    */
 +
    return true;
 +
    }
 +
 
 +
 
 +
  // If the function has not yet quit, there were none of these types of normals
 +
   std::cout << "Normals not found!" << std::endl;
 
   return false;
 
   return false;
  
 
}
 
}
  
</source>
 
  
==CMakeLists.txt==
+
bool GetCellNormals(vtkPolyData* polydata)
<source lang="cmake">
+
{
cmake_minimum_required(VERSION 2.6)
+
  std::cout << "Looking for cell normals..." << std::endl;
PROJECT(ReadNormals)
+
  
FIND_PACKAGE(VTK REQUIRED)
+
  // Count points
INCLUDE(${VTK_USE_FILE})
+
  vtkIdType numCells = polydata->GetNumberOfCells();
 +
  std::cout << "There are " << numCells << " cells." << std::endl;
  
ADD_EXECUTABLE(ReadNormals ReadNormals.cpp)
+
  // Count triangles
TARGET_LINK_LIBRARIES(ReadNormals  vtkHybrid)
+
  vtkIdType numPolys = polydata->GetNumberOfPolys();
 +
  std::cout << "There are " << numPolys << " polys." << std::endl;
  
 +
  ////////////////////////////////////////////////////////////////
 +
  // Double normals in an array
 +
  vtkDoubleArray* normalDataDouble =
 +
    vtkDoubleArray::SafeDownCast(polydata->GetCellData()->GetArray("Normals"));
  
 +
  if(normalDataDouble)
 +
    {
 +
    int nc = normalDataDouble->GetNumberOfTuples();
 +
    std::cout << "There are " << nc
 +
            << " components in normalDataDouble" << std::endl;
 +
    return true;
 +
    }
 +
 +
  ////////////////////////////////////////////////////////////////
 +
  // Double normals in an array
 +
  vtkFloatArray* normalDataFloat =
 +
    vtkFloatArray::SafeDownCast(polydata->GetCellData()->GetArray("Normals"));
 +
 +
  if(normalDataFloat)
 +
    {
 +
    int nc = normalDataFloat->GetNumberOfTuples();
 +
    std::cout << "There are " << nc
 +
            << " components in normalDataFloat" << std::endl;
 +
    return true;
 +
    }
 +
 +
  ////////////////////////////////////////////////////////////////
 +
  // Point normals
 +
  vtkDoubleArray* normalsDouble =
 +
    vtkDoubleArray::SafeDownCast(polydata->GetCellData()->GetNormals());
 +
 +
  if(normalsDouble)
 +
    {
 +
    std::cout << "There are " << normalsDouble->GetNumberOfComponents()
 +
              << " components in normalsDouble" << std::endl;
 +
    return true;
 +
    }
 +
 +
  ////////////////////////////////////////////////////////////////
 +
  // Point normals
 +
  vtkFloatArray* normalsFloat =
 +
    vtkFloatArray::SafeDownCast(polydata->GetCellData()->GetNormals());
 +
 +
  if(normalsFloat)
 +
    {
 +
    std::cout << "There are " << normalsFloat->GetNumberOfComponents()
 +
              << " components in normalsFloat" << std::endl;
 +
    return true;
 +
    }
 +
 +
  /////////////////////////////////////////////////////////////////////
 +
  // Generic type point normals
 +
  vtkDataArray* normalsGeneric = polydata->GetCellData()->GetNormals(); //works
 +
  if(normalsGeneric)
 +
    {
 +
    std::cout << "There are " << normalsGeneric->GetNumberOfTuples()
 +
              << " normals in normalsGeneric" << std::endl;
 +
 +
    double testDouble[3];
 +
    normalsGeneric->GetTuple(0, testDouble);
 +
 +
    std::cout << "Double: " << testDouble[0] << " "
 +
              << testDouble[1] << " " << testDouble[2] << std::endl;
 +
 +
    // Can't do this:
 +
    /*
 +
    float testFloat[3];
 +
    normalsGeneric->GetTuple(0, testFloat);
 +
 +
    std::cout << "Float: " << testFloat[0] << " "
 +
              << testFloat[1] << " " << testFloat[2] << std::endl;
 +
    */
 +
    return true;
 +
    }
 +
 +
 +
  // If the function has not yet quit, there were none of these types of normals
 +
  std::cout << "Normals not found!" << std::endl;
 +
  return false;
 +
 +
}
 
</source>
 
</source>
 +
 +
{{VTKCMakeLists|{{SUBPAGENAME}}}}
 +
 +
[[Category:VTKNoVizRequired]]

Latest revision as of 17:57, 9 December 2012

This demo looks for multiple types of normals in a polydata and generates them if they do not exist.

PolyDataExtractNormals.cxx

#include <vtkVersion.h>
#include <vtkCellData.h>
#include <vtkDoubleArray.h>
#include <vtkFloatArray.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataNormals.h>
#include <vtkPointData.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkXMLPolyDataReader.h>
 
void TestPointNormals(vtkPolyData* polydata);
void TestCellNormals(vtkPolyData* polydata);
 
bool GetPointNormals(vtkPolyData* polydata);
bool GetCellNormals(vtkPolyData* polydata);
 
int main(int argc, char *argv[])
{
  vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
 
  // If a file is provided, read it. Else, create a sphere.
  if(argc == 2)
    {
 
    // Read File
    std::string filename = argv[1]; //first command line argument
    std::cout << "Reading file " << filename << "..." << std::endl;
 
    vtkSmartPointer<vtkXMLPolyDataReader> reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();
    std::cout << "Reading " << filename << std::endl;
    reader->SetFileName(filename.c_str());
    reader->Update();
    polydata->DeepCopy(reader->GetOutput());
    }
  else
    {
    std::cout << "Creating a sphere..." << std::endl;
    vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->Update();
    std::cout << "In main: " << sphereSource->GetOutput()->GetNumberOfPoints() << std::endl;
    polydata->DeepCopy(sphereSource->GetOutput());
    }
 
  std::cout << "PolyData address: " << polydata << std::endl;
 
  TestPointNormals(polydata);
 
  TestCellNormals(polydata);
 
  return EXIT_SUCCESS;
}
 
void TestPointNormals(vtkPolyData* polydata)
{
  std::cout << "In TestPointNormals: " << polydata->GetNumberOfPoints() << std::endl;
  // Try to read normals directly
  bool hasPointNormals = GetPointNormals(polydata);
 
  if(!hasPointNormals)
    {
    std::cout << "No point normals were found. Computing normals..." << std::endl;
 
    // Generate normals
    vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
#if VTK_MAJOR_VERSION <= 5
    normalGenerator->SetInput(polydata);
#else
    normalGenerator->SetInputData(polydata);
#endif
    normalGenerator->ComputePointNormalsOn();
    normalGenerator->ComputeCellNormalsOff();
    normalGenerator->Update();
    /*
    // Optional settings
    normalGenerator->SetFeatureAngle(0.1);
    normalGenerator->SetSplitting(1);
    normalGenerator->SetConsistency(0);
    normalGenerator->SetAutoOrientNormals(0);
    normalGenerator->SetComputePointNormals(1);
    normalGenerator->SetComputeCellNormals(0);
    normalGenerator->SetFlipNormals(0);
    normalGenerator->SetNonManifoldTraversal(1);
    */
 
    polydata = normalGenerator->GetOutput();
 
    // Try to read normals again
    hasPointNormals = GetPointNormals(polydata);
 
    std::cout << "On the second try, has point normals? " << hasPointNormals << std::endl;
 
    }
  else
    {
    std::cout << "Point normals were found!" << std::endl;
    }
}
 
void TestCellNormals(vtkPolyData* polydata)
{
  // Try to read normals directly
  bool hasCellNormals = GetCellNormals(polydata);
 
  if(!hasCellNormals)
    {
    std::cout << "No cell normals were found. Computing normals..." << std::endl;
 
    // Generate normals
    vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
#if VTK_MAJOR_VERSION <= 5
    normalGenerator->SetInput(polydata);
#else
    normalGenerator->SetInputData(polydata);
#endif
    normalGenerator->ComputePointNormalsOff();
    normalGenerator->ComputeCellNormalsOn();
    normalGenerator->Update();
    /*
    // Optional settings
    normalGenerator->SetFeatureAngle(0.1);
    normalGenerator->SetSplitting(1);
    normalGenerator->SetConsistency(0);
    normalGenerator->SetAutoOrientNormals(0);
    normalGenerator->SetComputePointNormals(1);
    normalGenerator->SetComputeCellNormals(0);
    normalGenerator->SetFlipNormals(0);
    normalGenerator->SetNonManifoldTraversal(1);
    */
 
    polydata = normalGenerator->GetOutput();
 
    // Try to read normals again
    hasCellNormals = GetCellNormals(polydata);
 
    std::cout << "On the second try, has cell normals? " << hasCellNormals << std::endl;
 
    }
  else
    {
    std::cout << "Cell normals were found!" << std::endl;
    }
}
 
 
 
bool GetPointNormals(vtkPolyData* polydata)
{
  std::cout << "In GetPointNormals: " << polydata->GetNumberOfPoints() << std::endl;
  std::cout << "Looking for point normals..." << std::endl;
 
  // Count points
  vtkIdType numPoints = polydata->GetNumberOfPoints();
  std::cout << "There are " << numPoints << " points." << std::endl;
 
  // Count triangles
  vtkIdType numPolys = polydata->GetNumberOfPolys();
  std::cout << "There are " << numPolys << " polys." << std::endl;
 
  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkDoubleArray* normalDataDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetArray("Normals"));
 
  if(normalDataDouble)
    {
    int nc = normalDataDouble->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataDouble" << std::endl;
    return true;
    }
 
  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkFloatArray* normalDataFloat =
    vtkFloatArray::SafeDownCast(polydata->GetPointData()->GetArray("Normals"));
 
  if(normalDataFloat)
    {
    int nc = normalDataFloat->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataFloat" << std::endl;
    return true;
    }
 
  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkDoubleArray* normalsDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetNormals());
 
  if(normalsDouble)
    {
    std::cout << "There are " << normalsDouble->GetNumberOfComponents()
              << " components in normalsDouble" << std::endl;
    return true;
    }
 
  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkFloatArray* normalsFloat =
    vtkFloatArray::SafeDownCast(polydata->GetPointData()->GetNormals());
 
  if(normalsFloat)
    {
    std::cout << "There are " << normalsFloat->GetNumberOfComponents()
              << " components in normalsFloat" << std::endl;
    return true;
    }
 
  /////////////////////////////////////////////////////////////////////
  // Generic type point normals
  vtkDataArray* normalsGeneric = polydata->GetPointData()->GetNormals(); //works
  if(normalsGeneric)
    {
    std::cout << "There are " << normalsGeneric->GetNumberOfTuples()
              << " normals in normalsGeneric" << std::endl;
 
    double testDouble[3];
    normalsGeneric->GetTuple(0, testDouble);
 
    std::cout << "Double: " << testDouble[0] << " "
              << testDouble[1] << " " << testDouble[2] << std::endl;
 
    // Can't do this:
    /*
    float testFloat[3];
    normalsGeneric->GetTuple(0, testFloat);
 
    std::cout << "Float: " << testFloat[0] << " "
              << testFloat[1] << " " << testFloat[2] << std::endl;
    */
    return true;
    }
 
 
  // If the function has not yet quit, there were none of these types of normals
  std::cout << "Normals not found!" << std::endl;
  return false;
 
}
 
 
bool GetCellNormals(vtkPolyData* polydata)
{
  std::cout << "Looking for cell normals..." << std::endl;
 
  // Count points
  vtkIdType numCells = polydata->GetNumberOfCells();
  std::cout << "There are " << numCells << " cells." << std::endl;
 
  // Count triangles
  vtkIdType numPolys = polydata->GetNumberOfPolys();
  std::cout << "There are " << numPolys << " polys." << std::endl;
 
  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkDoubleArray* normalDataDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetCellData()->GetArray("Normals"));
 
  if(normalDataDouble)
    {
    int nc = normalDataDouble->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataDouble" << std::endl;
    return true;
    }
 
  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkFloatArray* normalDataFloat =
    vtkFloatArray::SafeDownCast(polydata->GetCellData()->GetArray("Normals"));
 
  if(normalDataFloat)
    {
    int nc = normalDataFloat->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataFloat" << std::endl;
    return true;
    }
 
  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkDoubleArray* normalsDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetCellData()->GetNormals());
 
  if(normalsDouble)
    {
    std::cout << "There are " << normalsDouble->GetNumberOfComponents()
              << " components in normalsDouble" << std::endl;
    return true;
    }
 
  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkFloatArray* normalsFloat =
    vtkFloatArray::SafeDownCast(polydata->GetCellData()->GetNormals());
 
  if(normalsFloat)
    {
    std::cout << "There are " << normalsFloat->GetNumberOfComponents()
              << " components in normalsFloat" << std::endl;
    return true;
    }
 
  /////////////////////////////////////////////////////////////////////
  // Generic type point normals
  vtkDataArray* normalsGeneric = polydata->GetCellData()->GetNormals(); //works
  if(normalsGeneric)
    {
    std::cout << "There are " << normalsGeneric->GetNumberOfTuples()
              << " normals in normalsGeneric" << std::endl;
 
    double testDouble[3];
    normalsGeneric->GetTuple(0, testDouble);
 
    std::cout << "Double: " << testDouble[0] << " "
              << testDouble[1] << " " << testDouble[2] << std::endl;
 
    // Can't do this:
    /*
    float testFloat[3];
    normalsGeneric->GetTuple(0, testFloat);
 
    std::cout << "Float: " << testFloat[0] << " "
              << testFloat[1] << " " << testFloat[2] << std::endl;
    */
    return true;
    }
 
 
  // If the function has not yet quit, there were none of these types of normals
  std::cout << "Normals not found!" << std::endl;
  return false;
 
}

Please try the new VTKExamples website.

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
 
PROJECT(PolyDataExtractNormals)
 
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
 
add_executable(PolyDataExtractNormals MACOSX_BUNDLE PolyDataExtractNormals.cxx)
 
if(VTK_LIBRARIES)
  target_link_libraries(PolyDataExtractNormals ${VTK_LIBRARIES})
else()
  target_link_libraries(PolyDataExtractNormals vtkHybrid vtkWidgets)
endif()

Download and Build PolyDataExtractNormals

Click here to download PolyDataExtractNormals. and its CMakeLists.txt file.

Once the tarball PolyDataExtractNormals.tar has been downloaded and extracted,

cd PolyDataExtractNormals/build 
  • If VTK is installed:
cmake ..
  • If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..

Build the project:

make

and run it:

./PolyDataExtractNormals

WINDOWS USERS PLEASE NOTE: Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.