[vtkusers] Using vtkTriangleFilter to reduce concave polygons to convex

Alex Southern mrapsouthern at gmail.com
Sat Jun 30 09:14:05 EDT 2012


Hi, Ive had a little success but it is still not right, here is a fully 
contained example that defines a bad polygon and then attempts to 
correct it with a vtkTriangleFilter.

The result is that only one triangle is present, which is clearly not 
correct.

Im not sure anymore if vtkTriangleFilter is the right choice...

Can anyone see a solution?

note, change line,

mapper->SetInput( pd2 );
to
mapper->SetInput( pd1 );

in order to seee the initial bad polygon.

Thanks
A.

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>

using namespace std;

int main()
{
     vtkSmartPointer<vtkPoints> pts = 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.48, 0.00 );
     int p[5] = {0, 1, 2, 3, 4};
     cellArray->InsertNextCell(5,p);

     pd1->SetPoints( pts );
     pd1->SetPolys( cellArray );

     triFilter->SetInput( pd1 );
     triFilter->Update();
     pd2 = triFilter->GetOutput();

     //  // 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();

     mapper->SetInput( pd2 );  // change to pd1 to see bad polygon
     actor->SetMapper( mapper );
     renderer->AddActor( actor );

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

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

   return 0;
}

On 6/30/2012 3:37 PM, David Doria wrote:
> David
>
>
> On Sat, Jun 30, 2012 at 8:32 AM, Alex Southern <mrapsouthern at gmail.com> wrote:
>> Hi,
>>
>> The pd1 vtkPolyData contains concave polygons, that I would like to reduce
>> into triangles.
>>
>> vtkTriangleFilter was mentioned as being appropriate, but no actual solution
>> was posted.
>> http://www.vtk.org/pipermail/vtkusers/2009-November/103551.html
>>
>> I want to apply the filter and put triangulated data back into pd2.
>>
>> If I view pd1 I can see the model, but with flickering due to the concave
>> polygons. But pd2 displays nothing -  could someone give me a nudge in the
>> right direction?
>>
>> Cheers
>> A.
>>
>> vtkSmartPointer<vtkPolyData> pd1 = vtkSmartPointer<vtkPolyData>::New();
>> vtkSmartPointer<vtkPolyData> pd2 = vtkSmartPointer<vtkPolyData>::New();
>> vtkSmartPointer<vtkTriangleFilter> triFilter =
>> vtkSmartPointer<vtkTriangleFilter>::New();
>>
>> triFilter->SetInput( pd1 );
>> pd2= triFilter->GetOutput();
> First, it is wrong to allocate pd2, because then you are leaking
> memory when you assign the pointer to the triFilter output. You should
> do instead:
>
> vtkSmartPointer<vtkPolyData> pd1 = vtkSmartPointer<vtkPolyData>::New();
>
> vtkSmartPointer<vtkTriangleFilter> triFilter =
> vtkSmartPointer<vtkTriangleFilter>::New();
> triFilter->SetInput( pd1 );
> vtkPolyData* pd2 = triFilter->GetOutput();
>
> Second, you need to call Update() because you can use the result in
> produced by the filter:
>
> vtkSmartPointer<vtkTriangleFilter> triFilter =
> vtkSmartPointer<vtkTriangleFilter>::New();
> triFilter->SetInput( pd1 );
> triFilter->Update();
> vtkPolyData* pd2 = triFilter->GetOutput();
>
> However, depending on what you are doing after that, it might have
> been updated even if you didn't call it explicitly. After trying that,
> if it still doesn't work I'd suggest you post code that
> programmatically generates data and then shows your problem.
>
> David





More information about the vtkusers mailing list