[vtkusers] Using vtkTriangleFilter to reduce concave polygons to convex

Bill Lorensen bill.lorensen at gmail.com
Sat Jun 30 12:07:29 EDT 2012


Here's a not so elegant solution. It perturbs each point by a small
random number, does the triangulation and then reassigns the original
points to the polydata.

#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkCubeSource.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkPointData.h>
#include <vtkTriangleFilter.h>
#include <vtkMath.h>

using namespace std;

int main()
{
   vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkPoints> ptsDelta = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> cellArray =
vtkSmartPointer<vtkCellArray>::New();

   vtkSmartPointer<vtkTriangleFilter> triFilter =
vtkSmartPointer<vtkTriangleFilter>::New();
   vtkSmartPointer<vtkPolyData> pd1 = vtkSmartPointer<vtkPolyData>::New();
   vtkPolyData *pd2;

   // Generate a concave polygon that is NOT flat (i.e. not in one plane)
   pts->InsertNextPoint( 1.00, 2.48, 0.00 );
   pts->InsertNextPoint( 1.00, 0.00, 0.00 );
   pts->InsertNextPoint( 1.00, 1.24, 0.29 );
   pts->InsertNextPoint( 0.00, 0.00, 0.00 );
   pts->InsertNextPoint( 0.00, 2.4801, 0.00 );
   int p[5] = {0, 1, 2, 3, 4};
   cellArray->InsertNextCell(5,p);

   for (unsigned int i = 0; i < pts->GetNumberOfPoints(); ++i)
     {
     double x, y, z;
     x = pts->GetPoint(i)[0] + vtkMath::Random(0.0, .00001);
     y = pts->GetPoint(i)[1] + vtkMath::Random(0.0, .00001);
     z = pts->GetPoint(i)[2] + vtkMath::Random(0.0, .00001);
     ptsDelta->InsertNextPoint(x, y, z);
     }
   pd1->SetPoints( ptsDelta );
   pd1->SetPolys( cellArray );



#if VTK_MAJOR_VERSION <= 5
   triFilter->SetInput( pd1 );
#else
   triFilter->SetInputData( pd1 );
#endif
   triFilter->Update();
   pd2 = triFilter->GetOutput();
   pd2->SetPoints(pts);

   // Create a renderer, render window, and interactor
   vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
   vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
   vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();

   renderWindow->AddRenderer(renderer);
   renderWindowInteractor->SetRenderWindow(renderWindow);

   // map filtered data
   vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
   vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();

#if VTK_MAJOR_VERSION <= 5
   mapper->SetInput( pd2 );  // change to pd1 to see bad polygon
#else
   mapper->SetInputData( pd2 );  // change to pd1 to see bad polygon
#endif
   actor->SetMapper( mapper );
   renderer->AddActor( actor );

   renderer->SetBackground(.5, .1, .1);

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

 return 0;
}



More information about the vtkusers mailing list