Commit d8611b57 authored by T.J. Corona's avatar T.J. Corona
Browse files

Extend vtkPolygonBuilder to return multiple disjoint polygons, if present.

This fix is in reference to bug report 0015582. In cases where a single cell
is cut into multiple cells, it is necessary to return disjoint polygon elements
in vtkPolygonBuilder. Additionally, a test provided by Andreas Buykx has been
included that tests the ability of vtkPolygonBuilder to construct multiple
disjoint polygons.
parent dc80f419
......@@ -12,7 +12,7 @@
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkIdList.h"
#include "vtkIdListCollection.h"
#include "vtkNew.h"
#include "vtkPoints.h"
#include "vtkPolygonBuilder.h"
......@@ -41,12 +41,21 @@ int TestPolygonBuilder(int, char* [])
builder.InsertTriangle(p);
}
vtkNew<vtkIdList> poly;
builder.GetPolygon(poly.GetPointer());
vtkNew<vtkIdListCollection> polys;
builder.GetPolygons(polys.GetPointer());
if (polys->GetNumberOfItems()!=1)
{
return EXIT_FAILURE;
}
vtkIdList* poly = polys->GetItem(0);
if(poly->GetNumberOfIds()!=4)
{
return EXIT_FAILURE;
}
poly->Delete();
polys->RemoveAllItems();
return EXIT_SUCCESS;
}
......@@ -13,7 +13,7 @@
=========================================================================*/
#include "vtkPolygonBuilder.h"
#include "vtkIdList.h"
#include "vtkIdListCollection.h"
vtkPolygonBuilder::vtkPolygonBuilder()
{
......@@ -36,7 +36,7 @@ void vtkPolygonBuilder::InsertTriangle(vtkIdType* abc)
{
this->Edges.insert(std::make_pair(edge.first,edge.second));
}
else if (nInstances == 2)
else if (nInstances == 2)
{
std::pair<EdgeMap::iterator, EdgeMap::iterator> range = Edges.equal_range(edge.first);
......@@ -55,9 +55,9 @@ void vtkPolygonBuilder::InsertTriangle(vtkIdType* abc)
return;
}
void vtkPolygonBuilder::GetPolygon(vtkIdList* poly)
void vtkPolygonBuilder::GetPolygons(vtkIdListCollection* polys)
{
poly->Reset();
polys->RemoveAllItems();
// We now have exactly two instances of each outer edge, corresponding to a
// clockwise and counterclockwise traversal
......@@ -66,30 +66,40 @@ void vtkPolygonBuilder::GetPolygon(vtkIdList* poly)
return;
}
EdgeMap::iterator edgeIt = this->Edges.begin();
vtkIdType firstVtx,vtx1,vtx2;
firstVtx = vtx1 = (*edgeIt).first;
poly->InsertNextId(vtx1);
while (!(this->Edges.empty()))
{
vtkIdList* poly = vtkIdList::New();
vtx2 = (*edgeIt).second;
Edge edge = *(this->Edges.begin());
EdgeMap::iterator edgeIt = this->Edges.begin();
while (vtx2 != firstVtx)
{
poly->InsertNextId(vtx2);
vtkIdType firstVtx = edge.first;
// we will find either the inverse to our current edge, or the next edge
// in the path.
edgeIt = this->Edges.find(vtx2);
if ((*edgeIt).second == vtx1)
do
{
// we have found the inverse. Remove it and look agian.
this->Edges.erase(edgeIt);
edgeIt = this->Edges.find(vtx2);
poly->InsertNextId(edge.first);
// we will find either the inverse to our current edge, or the next edge
// in the path.
std::pair<EdgeMap::iterator, EdgeMap::iterator> range =
this->Edges.equal_range(edge.second);
edgeIt = range.first;
vtkIdType previousVtx = edge.first;
while (edgeIt != range.second)
{
if ((*edgeIt).second != previousVtx)
{
// we have found the next edge in the path
edge.first = edge.second;
edge.second = edgeIt->second;
}
this->Edges.erase(edgeIt++);
}
}
while (edge.first != firstVtx);
vtx1 = vtx2;
vtx2 = edgeIt->second;
polys->AddItem(poly);
}
this->Reset();
......
......@@ -29,14 +29,26 @@
#include "vtkType.h" //for basic types
#include <cstddef> //for size_t
#include "vtkObject.h"
class vtkIdList;
class vtkIdListCollection;
class VTKCOMMONMISC_EXPORT vtkPolygonBuilder
{
public:
vtkPolygonBuilder();
// Description:
// Insert a triangle as a triplet of point IDs.
void InsertTriangle(vtkIdType* abc);
void GetPolygon(vtkIdList* poly);
// Description:
// Populate polys with lists of polygons, defined as sequential external
// vertices. It is the responsibility of the user to delete these generated
// lists in order to avoid memory leaks.
void GetPolygons(vtkIdListCollection* polys);
// Description:
// Prepare the builder for a new set of inputs.
void Reset();
private:
......
......@@ -35,6 +35,7 @@ vtk_add_test_python(
contourQuadraticTetra.py,NO_RT
createBFont.py
cutLoop.py
cutPolygons.py
cutter.py
dispPlot.py
fieldToPolyData.py
......
......@@ -29,7 +29,7 @@ class TestGridSynchronizedTemplates3D(Testing.vtkTest):
self.failUnlessEqual(
cf.GetOutputDataObject(0).GetNumberOfPoints(), 4674)
self.failUnlessEqual(
cf.GetOutputDataObject(0).GetNumberOfCells(), 4011)
cf.GetOutputDataObject(0).GetNumberOfCells(), 4012)
cf.GenerateTrianglesOn()
cf.Update()
......
......@@ -21,7 +21,7 @@ class TestSynchronizedTemplates3D(Testing.vtkTest):
stemp.GenerateTrianglesOff()
stemp.Update()
self.failUnlessEqual(stemp.GetOutputDataObject(0).GetNumberOfPoints(),39315)
self.failUnlessEqual(stemp.GetOutputDataObject(0).GetNumberOfCells(),38380)
self.failUnlessEqual(stemp.GetOutputDataObject(0).GetNumberOfCells(),39067)
stemp.GenerateTrianglesOn()
stemp.Update()
......
import vtk
from math import sqrt
from vtk.test import Testing
plane = vtk.vtkPlane()
plane.SetOrigin(5,5,9.8)
plane.SetNormal(0,0,1)
coords = [(0,0,0),(10,0,0),(10,10,0),(0,10,0),
(0,0,10),(10,0,10),(10,10,10),(0,10,10),
(5,0,0),(10,5,0),(5,10,0),(0,5,0),
(5,0,9.5),(10,5,9.3),(5,10,9.5),(0,5,9.3),
(0,0,5),(10,0,5),(10,10,5),(0,10,5)]
data = vtk.vtkFloatArray()
points = vtk.vtkPoints()
ptIds = vtk.vtkIdList()
mesh = vtk.vtkUnstructuredGrid()
mesh.SetPoints(points)
mesh.GetPointData().SetScalars(data)
for id in range(0,20):
x=coords[id][0]
y=coords[id][1]
z=coords[id][2]
ptIds.InsertNextId(id)
points.InsertNextPoint(x,y,z)
data.InsertNextValue(sqrt(x*x + y*y + z*z))
mesh.InsertNextCell(vtk.VTK_QUADRATIC_HEXAHEDRON,ptIds)
ptIds.Reset()
for id in range(0,8):
x=coords[id][0] + 20
y=coords[id][1] + 20
z=coords[id][2]
ptIds.InsertNextId(id + 20)
points.InsertNextPoint(x,y,z)
data.InsertNextValue(sqrt(x*x + y*y + z*z))
mesh.InsertNextCell(vtk.VTK_HEXAHEDRON,ptIds)
print( "Mesh bounding box : ({0})".format( mesh.GetPoints().GetBounds() ) )
triCutter = vtk.vtkCutter()
triCutter.SetInputData(mesh)
triCutter.SetCutFunction(plane)
triCutter.GenerateTrianglesOn()
triCutter.Update()
print( "Triangle cutter bounding box : ({0})".format( triCutter.GetOutput().GetPoints().GetBounds() ) )
polyCutter = vtk.vtkCutter()
polyCutter.SetInputData(mesh)
polyCutter.SetCutFunction(plane)
polyCutter.GenerateTrianglesOff()
polyCutter.Update()
print( "Polygon cutter bounding box : ({0})".format( polyCutter.GetOutput().GetPoints().GetBounds() ) )
# Display input and output side-by-side
meshMapper = vtk.vtkDataSetMapper()
meshMapper.SetInputData(mesh)
meshActor=vtk.vtkActor()
meshActor.SetMapper(meshMapper)
meshRen = vtk.vtkRenderer()
meshRen.AddActor(meshActor)
meshRen.SetViewport(0.0,0.0,0.5,1.0)
triCutMapper = vtk.vtkPolyDataMapper()
triCutMapper.SetInputData(triCutter.GetOutput())
triCutActor=vtk.vtkActor()
triCutActor.SetMapper(triCutMapper)
triCutActor.GetProperty().EdgeVisibilityOn()
triCutActor.GetProperty().SetEdgeColor(1,1,1)
triCutRen = vtk.vtkRenderer()
triCutRen.AddActor(triCutActor)
triCutRen.SetViewport(0.5,0.5,1.0,1.0)
polyCutMapper = vtk.vtkPolyDataMapper()
polyCutMapper.SetInputData(polyCutter.GetOutput())
polyCutActor=vtk.vtkActor()
polyCutActor.SetMapper(polyCutMapper)
polyCutActor.GetProperty().EdgeVisibilityOn()
polyCutActor.GetProperty().SetEdgeColor(1,1,1)
polyCutRen = vtk.vtkRenderer()
polyCutRen.AddActor(polyCutActor)
polyCutRen.SetViewport(0.5,0.0,1.0,0.5)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(meshRen)
renWin.AddRenderer(triCutRen)
renWin.AddRenderer(polyCutRen)
renWin.SetSize(800,400)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
renWin.Render()
iren.Initialize()
......@@ -19,7 +19,7 @@
#include "vtkPointData.h"
#include "vtkCellData.h"
#include "vtkPolygonBuilder.h"
#include "vtkIdList.h"
#include "vtkIdListCollection.h"
#include "vtkCell.h"
#include "vtkDataArray.h"
......@@ -50,14 +50,14 @@ vtkContourHelper::vtkContourHelper(vtkIncrementalPointLocator *locator,
this->Tris->Allocate(estimatedSize,estimatedSize/2);
this->TriOutCd->Initialize();
}
this->Poly = vtkIdList::New();
this->PolyCollection = vtkIdListCollection::New();
}
vtkContourHelper::~vtkContourHelper()
{
this->Tris->Delete();
this->TriOutCd->Delete();
this->Poly->FastDelete();
this->PolyCollection->Delete();
}
void vtkContourHelper::Contour(vtkCell* cell, double value, vtkDataArray *cellScalars, vtkIdType cellId)
......@@ -96,11 +96,18 @@ void vtkContourHelper::Contour(vtkCell* cell, double value, vtkDataArray *cellSc
}
}
this->PolyBuilder.GetPolygon(this->Poly);
if(this->Poly->GetNumberOfIds()!=0)
this->PolyBuilder.GetPolygons(this->PolyCollection);
int nPolys = this->PolyCollection->GetNumberOfItems();
for (int polyId = 0; polyId < nPolys; ++polyId)
{
vtkIdType outCellId = this->Polys->InsertNextCell(this->Poly);
this->OutCd->CopyData(this->InCd, cellId, outCellId);
vtkIdList* poly = this->PolyCollection->GetItem(polyId);
if(poly->GetNumberOfIds()!=0)
{
vtkIdType outCellId = this->Polys->InsertNextCell(poly);
this->OutCd->CopyData(this->InCd, cellId, outCellId);
}
poly->Delete();
}
this->PolyCollection->RemoveAllItems();
}
}
......@@ -32,7 +32,7 @@ class vtkPointData;
class vtkCellData;
class vtkCell;
class vtkDataArray;
class vtkIdList;
class vtkIdListCollection;
class VTKFILTERSCORE_EXPORT vtkContourHelper
{
......@@ -63,7 +63,7 @@ public:
vtkCellArray* Tris;
vtkPolygonBuilder PolyBuilder;
vtkIdList* Poly;
vtkIdListCollection* PolyCollection;
bool GenerateTriangles;
};
......
......@@ -20,6 +20,7 @@
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkGridSynchronizedTemplates3D.h"
#include "vtkIdListCollection.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkIntArray.h"
......@@ -411,7 +412,8 @@ void ContourGrid(vtkGridSynchronizedTemplates3D *self,
vtkFloatArray *newNormals = NULL;
vtkFloatArray *newGradients = NULL;
vtkPolygonBuilder polyBuilder;
vtkSmartPointer<vtkIdList> poly = vtkSmartPointer<vtkIdList>::New();
vtkSmartPointer<vtkIdListCollection> polys =
vtkSmartPointer<vtkIdListCollection>::New();
if (ComputeScalars)
{
......@@ -734,12 +736,19 @@ void ContourGrid(vtkGridSynchronizedTemplates3D *self,
}
if(!outputTriangles)
{
polyBuilder.GetPolygon(poly);
if(poly->GetNumberOfIds()>0)
polyBuilder.GetPolygons(polys);
int nPolys = polys->GetNumberOfItems();
for (int polyId = 0; polyId < nPolys; ++polyId)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
vtkIdList* poly = polys->GetItem(polyId);
if(poly->GetNumberOfIds()!=0)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
}
poly->Delete();
}
polys->RemoveAllItems();
}
}
}
......
......@@ -19,6 +19,7 @@
#include "vtkCharArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIdListCollection.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkIntArray.h"
......@@ -298,7 +299,8 @@ void ContourRectilinearGrid(vtkRectilinearSynchronizedTemplates *self, int *exEx
double x1, x2, y2, z2;
double spacing[6];
vtkPolygonBuilder polyBuilder;
vtkSmartPointer<vtkIdList> poly = vtkSmartPointer<vtkIdList>::New();
vtkSmartPointer<vtkIdListCollection> polys =
vtkSmartPointer<vtkIdListCollection>::New();
if (ComputeScalars)
{
......@@ -616,12 +618,19 @@ void ContourRectilinearGrid(vtkRectilinearSynchronizedTemplates *self, int *exEx
}
if(!outputTriangles)
{
polyBuilder.GetPolygon(poly);
if(poly->GetNumberOfIds()>0)
polyBuilder.GetPolygons(polys);
int nPolys = polys->GetNumberOfItems();
for (int polyId = 0; polyId < nPolys; ++polyId)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
vtkIdList* poly = polys->GetItem(polyId);
if(poly->GetNumberOfIds()!=0)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
}
poly->Delete();
}
polys->RemoveAllItems();
}
}
inPtrX += xInc;
......
......@@ -19,6 +19,7 @@
#include "vtkCharArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIdListCollection.h"
#include "vtkInformation.h"
#include "vtkInformationIntegerVectorKey.h"
#include "vtkInformationVector.h"
......@@ -300,7 +301,8 @@ void ContourImage(vtkSynchronizedTemplates3D *self, int* exExt,
vtkCellArray *newPolys;
ptr += self->GetArrayComponent();
vtkPolygonBuilder polyBuilder;
vtkSmartPointer<vtkIdList> poly = vtkSmartPointer<vtkIdList>::New();
vtkSmartPointer<vtkIdListCollection> polys =
vtkSmartPointer<vtkIdListCollection>::New();
if (ComputeScalars)
{
......@@ -607,12 +609,19 @@ void ContourImage(vtkSynchronizedTemplates3D *self, int* exExt,
}
if(!outputTriangles)
{
polyBuilder.GetPolygon(poly);
if(poly->GetNumberOfIds()>0)
polyBuilder.GetPolygons(polys);
int nPolys = polys->GetNumberOfItems();
for (int polyId = 0; polyId < nPolys; ++polyId)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
vtkIdList* poly = polys->GetItem(polyId);
if(poly->GetNumberOfIds()!=0)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
}
poly->Delete();
}
polys->RemoveAllItems();
}
}
inPtrX += xInc;
......
......@@ -37,6 +37,7 @@
#include "vtkUnsignedShortArray.h"
#include "vtkPolygonBuilder.h"
#include "vtkIdList.h"
#include "vtkIdListCollection.h"
#include "vtkSmartPointer.h"
#include <math.h>
......@@ -158,7 +159,8 @@ void ContourImage(vtkSynchronizedTemplatesCutter3D *self, int *exExt,
vtkCellArray *newPolys;
ptr += self->GetArrayComponent();
vtkPolygonBuilder polyBuilder;
vtkSmartPointer<vtkIdList> poly = vtkSmartPointer<vtkIdList>::New();
vtkSmartPointer<vtkIdListCollection> polys =
vtkSmartPointer<vtkIdListCollection>::New();
vtkSynchronizedTemplatesCutter3DInitializeOutput(exExt, self->GetOutputPointsPrecision(), data, output);
newPts = output->GetPoints();
......@@ -507,12 +509,19 @@ void ContourImage(vtkSynchronizedTemplatesCutter3D *self, int *exExt,
}
if(!outputTriangles)
{
polyBuilder.GetPolygon(poly);
if(poly->GetNumberOfIds()>0)
polyBuilder.GetPolygons(polys);
int nPolys = polys->GetNumberOfItems();
for (int polyId = 0; polyId < nPolys; ++polyId)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
vtkIdList* poly = polys->GetItem(polyId);
if(poly->GetNumberOfIds()!=0)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
}
poly->Delete();
}
polys->RemoveAllItems();
}
}
inPtrX += xIncFunc;
......
......@@ -19,6 +19,7 @@
#include "vtkCharArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIdListCollection.h"
#include "vtkInformation.h"
#include "vtkInformationIntegerVectorKey.h"
#include "vtkInformationVector.h"
......@@ -308,7 +309,8 @@ void ContourImage(vtkThreadedSynchronizedTemplates3D *self, int* exExt,
ptr += self->GetArrayComponent();
vtkPolygonBuilder polyBuilder;
vtkSmartPointer<vtkIdList> poly = vtkSmartPointer<vtkIdList>::New();
vtkSmartPointer<vtkIdListCollection> polys =
vtkSmartPointer<vtkIdListCollection>::New();
newPts = output->GetPoints();
newPolys = output->GetPolys();
......@@ -599,12 +601,19 @@ void ContourImage(vtkThreadedSynchronizedTemplates3D *self, int* exExt,
}
if(!outputTriangles)
{
polyBuilder.GetPolygon(poly);
if(poly->GetNumberOfIds()>0)
polyBuilder.GetPolygons(polys);
int nPolys = polys->GetNumberOfItems();
for (int polyId = 0; polyId < nPolys; ++polyId)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
vtkIdList* poly = polys->GetItem(polyId);
if(poly->GetNumberOfIds()!=0)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
}
poly->Delete();
}
polys->RemoveAllItems();
}
}
inPtrX += xInc;
......
......@@ -37,6 +37,7 @@
#include "vtkUnsignedShortArray.h"
#include "vtkPolygonBuilder.h"
#include "vtkIdList.h"
#include "vtkIdListCollection.h"
#include "vtkSmartPointer.h"
#include <math.h>
......@@ -211,7 +212,8 @@ void ContourImage(vtkThreadedSynchronizedTemplatesCutter3D *self, int *exExt,
vtkCellArray *newPolys;
ptr += self->GetArrayComponent();
vtkPolygonBuilder polyBuilder;
vtkSmartPointer<vtkIdList> poly = vtkSmartPointer<vtkIdList>::New();
vtkSmartPointer<vtkIdListCollection> polys =
vtkSmartPointer<vtkIdListCollection>::New();
newPts = output->GetPoints();
newPolys = output->GetPolys();
......@@ -582,12 +584,19 @@ void ContourImage(vtkThreadedSynchronizedTemplatesCutter3D *self, int *exExt,
}
if(!outputTriangles)
{
polyBuilder.GetPolygon(poly);
if(poly->GetNumberOfIds()>0)
polyBuilder.GetPolygons(polys);
int nPolys = polys->GetNumberOfItems();
for (int polyId = 0; polyId < nPolys; ++polyId)
{
outCellId = newPolys->InsertNextCell(poly);
outCD->CopyData(inCD, inCellId, outCellId);
vtkIdList* poly = polys->GetItem(polyId);
if(poly->GetNumberOfIds()!=0)