1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    TestPolyhedron1.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 #include "vtkDataSetMapper.h"
17 #include "vtkActor.h"
18 #include "vtkRenderer.h"
19 #include "vtkRenderWindow.h"
20 #include "vtkRenderWindowInteractor.h"
21 #include "vtkSmartPointer.h"
22 #include "vtkExtractEdges.h"
23 #include "vtkProperty.h"
24 #include "vtkUnstructuredGrid.h"
25 #include "vtkPolyhedron.h"
26 #include "vtkCellArray.h"
27 #include "vtkPointData.h"
28 #include "vtkCellData.h"
29 #include "vtkPoints.h"
30 #include "vtkDataArray.h"
31 #include "vtkPointLocator.h"
32 #include "vtkPlaneSource.h"
33 #include "vtkPlane.h"
34 #include "vtkDoubleArray.h"
35 #include "vtkMath.h"
36 
37 #include "vtkTestUtilities.h"
38 #include "vtkRegressionTestImage.h"
39 
40 // Test of vtkPolyhedron. A dodecahedron is created for testing clip and contour
TestPolyhedron1(int argc,char * argv[])41 int TestPolyhedron1( int argc, char* argv[] )
42 {
43   // create a dodecahedron
44   double dodechedronPoint[20][3] = { {1.21412,    0,          1.58931},
45                                      {0.375185,   1.1547,     1.58931},
46                                      {-0.982247,  0.713644,   1.58931},
47                                      {-0.982247,  -0.713644,  1.58931},
48                                      {0.375185,   -1.1547,    1.58931},
49                                      {1.96449,    0,          0.375185},
50                                      {0.607062,   1.86835,    0.375185},
51                                      {-1.58931,   1.1547,     0.375185},
52                                      {-1.58931,   -1.1547,    0.375185},
53                                      {0.607062,   -1.86835,   0.375185},
54                                      {1.58931,    1.1547,     -0.375185},
55                                      {-0.607062,  1.86835,    -0.375185},
56                                      {-1.96449,   0,          -0.375185},
57                                      {-0.607062,  -1.86835,   -0.375185},
58                                      {1.58931,    -1.1547,    -0.375185},
59                                      {0.982247,   0.713644,   -1.58931},
60                                      {-0.375185,  1.1547,     -1.58931},
61                                      {-1.21412,   0,          -1.58931},
62                                      {-0.375185,  -1.1547,    -1.58931},
63                                      {0.982247,   -0.713644,  -1.58931}};
64   vtkSmartPointer<vtkPoints> dodechedronPoints = vtkSmartPointer<vtkPoints>::New();
65   dodechedronPoints->Initialize();
66   for (int i = 0; i < 20; i++)
67   {
68     dodechedronPoints->InsertNextPoint(dodechedronPoint[i]);
69   }
70 
71   vtkIdType dodechedronPointsIds[20] = {0,   1,  2,  3,  4,  5,  6,  7,  8,  9,
72                                         10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
73 
74   vtkIdType dodechedronFace[12][5] = {{0, 1, 2, 3, 4},
75                                       {0, 5, 10, 6, 1},
76                                       {1, 6, 11, 7, 2},
77                                       {2, 7, 12, 8, 3},
78                                       {3, 8, 13, 9, 4},
79                                       {4, 9, 14, 5, 0},
80                                       {15, 10, 5, 14, 19},
81                                       {16, 11, 6, 10, 15},
82                                       {17, 12, 7, 11, 16},
83                                       {18, 13, 8, 12, 17},
84                                       {19, 14, 9, 13, 18},
85                                       {19, 18, 17, 16, 15}};
86 
87   vtkSmartPointer<vtkCellArray> dodechedronFaces = vtkSmartPointer<vtkCellArray>::New();
88   for (int i = 0; i < 12; i++)
89   {
90     dodechedronFaces->InsertNextCell(5, dodechedronFace[i]);
91   }
92 
93   double offset = 0;//0.375185;
94 
95 
96   double normal[3] = {0.0, 0.0, 1.0};
97   double origin[3] = {0.0, 0.0, offset};
98   double x[3] = {1.0, 0.0, 0.0};
99   double y[3] = {0.0, 1.0, 0.0};
100 
101   vtkSmartPointer<vtkPlaneSource> planeSource = vtkSmartPointer<vtkPlaneSource>::New();
102   planeSource->SetNormal(normal);
103   planeSource->SetOrigin(origin);
104   planeSource->SetPoint1(origin[0] + 5*x[0], origin[1] + 5*x[1], origin[2] + 5*x[2]);
105   planeSource->SetPoint2(origin[0] + 7*y[0], origin[1] + 7*y[1], origin[2] + 7*y[2]);
106   planeSource->SetCenter(origin);
107   planeSource->SetResolution(1, 1);
108   planeSource->Update();
109 
110 
111   vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
112   plane->SetNormal(normal);
113   plane->SetOrigin(origin);
114   vtkSmartPointer<vtkDoubleArray> pointDataArray =
115     vtkSmartPointer<vtkDoubleArray>::New();
116   pointDataArray->Initialize();
117   for (int i = 0; i < 20; i++)
118   {
119     cout << plane->EvaluateFunction(dodechedronPoint[i]) << endl;
120     pointDataArray->InsertNextValue(plane->EvaluateFunction(dodechedronPoint[i])+0.01);
121   }
122 
123   vtkSmartPointer<vtkDoubleArray> cellDataArray =
124     vtkSmartPointer<vtkDoubleArray>::New();
125   cellDataArray->Initialize();
126   for (int i = 0; i < 12; i++)
127   {
128     cellDataArray->InsertNextValue(static_cast<double>(1.0));
129   }
130 
131   vtkSmartPointer<vtkUnstructuredGrid> ugrid =
132     vtkSmartPointer<vtkUnstructuredGrid>::New();
133   ugrid->SetPoints(dodechedronPoints);
134   ugrid->InsertNextCell(VTK_POLYHEDRON, 20, dodechedronPointsIds,
135     12, dodechedronFaces->GetPointer());
136   ugrid->GetPointData()->SetScalars(pointDataArray);
137   //ugrid->GetCellData()->SetScalars(cellDataArray);
138 
139   vtkPolyhedron *polyhedron = static_cast<vtkPolyhedron*>(ugrid->GetCell(0));
140   vtkPolyData * planePoly = planeSource->GetOutput();
141   polyhedron->GetPolyData()->GetPointData()->SetScalars(pointDataArray);
142   //polyhedron->GetPolyData()->GetCellData()->SetScalars(cellDataArray);
143 
144   // test contour
145   vtkSmartPointer<vtkPointLocator> locator =
146     vtkSmartPointer<vtkPointLocator>::New();
147   vtkSmartPointer<vtkCellArray> resultPolys =
148     vtkSmartPointer<vtkCellArray>::New();
149   vtkSmartPointer<vtkPointData> resultPd =
150     vtkSmartPointer<vtkPointData>::New();
151   vtkSmartPointer<vtkCellData> resultCd =
152     vtkSmartPointer<vtkCellData>::New();
153   vtkSmartPointer<vtkPoints> resultPoints =
154     vtkSmartPointer<vtkPoints>::New();
155   resultPoints->DeepCopy(ugrid->GetPoints());
156   locator->InitPointInsertion(resultPoints, ugrid->GetBounds());
157 
158   polyhedron->Contour(0, ugrid->GetPointData()->GetScalars(), locator,
159                       nullptr, nullptr, resultPolys,
160                       ugrid->GetPointData(), resultPd,
161                       ugrid->GetCellData(), 0, resultCd);
162 
163   // output the contour
164   vtkSmartPointer<vtkUnstructuredGrid> contourResult =
165     vtkSmartPointer<vtkUnstructuredGrid>::New();
166   contourResult->SetPoints(locator->GetPoints());
167   contourResult->SetCells(VTK_POLYGON, resultPolys);
168   contourResult->GetPointData()->DeepCopy(resultPd);
169 
170   // test clip
171   vtkSmartPointer<vtkPointLocator> locator1 =
172     vtkSmartPointer<vtkPointLocator>::New();
173   vtkSmartPointer<vtkCellArray> resultPolys1 =
174     vtkSmartPointer<vtkCellArray>::New();
175   vtkSmartPointer<vtkPointData> resultPd1 =
176     vtkSmartPointer<vtkPointData>::New();
177   vtkSmartPointer<vtkCellData> resultCd1 =
178     vtkSmartPointer<vtkCellData>::New();
179   vtkSmartPointer<vtkPoints> resultPoints1 =
180     vtkSmartPointer<vtkPoints>::New();
181   resultPoints1->DeepCopy(ugrid->GetPoints());
182   locator1->InitPointInsertion(resultPoints1, ugrid->GetBounds());
183 
184   polyhedron->Clip(0, ugrid->GetPointData()->GetScalars(), locator1,
185                    resultPolys1, ugrid->GetPointData(), resultPd1,
186                    ugrid->GetCellData(), 0, resultCd1, 1);
187 
188   // output the clipped polyhedron
189   vtkSmartPointer<vtkUnstructuredGrid> clipResult =
190     vtkSmartPointer<vtkUnstructuredGrid>::New();
191   clipResult->SetPoints(locator1->GetPoints());
192   clipResult->SetCells(VTK_POLYHEDRON, resultPolys1);
193   clipResult->GetPointData()->DeepCopy(resultPd1);
194 
195   // create actors
196   vtkSmartPointer<vtkDataSetMapper> mapper =
197     vtkSmartPointer<vtkDataSetMapper>::New();
198   mapper->SetInputData(polyhedron->GetPolyData());
199 
200   vtkSmartPointer<vtkActor> actor =
201     vtkSmartPointer<vtkActor>::New();
202   actor->SetMapper(mapper);
203 
204   vtkSmartPointer<vtkDataSetMapper> planeMapper =
205     vtkSmartPointer<vtkDataSetMapper>::New();
206   planeMapper->SetInputData(planePoly);
207 
208   vtkSmartPointer<vtkActor> planeActor =
209     vtkSmartPointer<vtkActor>::New();
210   planeActor->SetMapper(planeMapper);
211 
212 
213   vtkSmartPointer<vtkDataSetMapper> contourMapper =
214     vtkSmartPointer<vtkDataSetMapper>::New();
215   contourMapper->SetInputData(contourResult);
216 
217   vtkSmartPointer<vtkActor> contourActor =
218     vtkSmartPointer<vtkActor>::New();
219   contourActor->SetMapper(contourMapper);
220 
221   vtkSmartPointer<vtkDataSetMapper> clipPolyhedronMapper =
222     vtkSmartPointer<vtkDataSetMapper>::New();
223   clipPolyhedronMapper->SetInputData(clipResult);
224 
225   vtkSmartPointer<vtkActor> clipPolyhedronActor =
226     vtkSmartPointer<vtkActor>::New();
227   clipPolyhedronActor->SetMapper(clipPolyhedronMapper);
228 
229   // Create rendering infrastructure
230   vtkSmartPointer<vtkProperty> prop = vtkSmartPointer<vtkProperty>::New();
231   prop->LightingOff();
232   prop->SetRepresentationToSurface();
233   prop->EdgeVisibilityOn();
234   prop->SetLineWidth(3.0);
235   prop->SetOpacity(1.0);
236   prop->SetInterpolationToFlat();
237 
238   vtkSmartPointer<vtkProperty> prop1 = vtkSmartPointer<vtkProperty>::New();
239   prop1->LightingOff();
240   prop1->SetRepresentationToSurface();
241   prop1->EdgeVisibilityOn();
242   prop1->SetLineWidth(3.0);
243   prop1->SetOpacity(0.5);
244   prop1->SetInterpolationToFlat();
245 
246   // set property
247   actor->SetProperty(prop1);
248   planeActor->SetProperty(prop1);
249   contourActor->SetProperty(prop1);
250   clipPolyhedronActor->SetProperty(prop);
251 
252   vtkSmartPointer<vtkRenderer> ren =
253     vtkSmartPointer<vtkRenderer>::New();
254   ren->AddActor(actor);
255   ren->AddActor(planeActor);
256   ren->AddActor(contourActor);
257   ren->AddActor(clipPolyhedronActor);
258   ren->SetBackground(.5,.5,.5);
259 
260   vtkSmartPointer<vtkRenderWindow> renWin =
261     vtkSmartPointer<vtkRenderWindow>::New();
262   renWin->SetMultiSamples(0);
263   renWin->AddRenderer(ren);
264 
265   vtkSmartPointer<vtkRenderWindowInteractor> iren =
266     vtkSmartPointer<vtkRenderWindowInteractor>::New();
267   iren->SetRenderWindow(renWin);
268 
269   iren->Initialize();
270 
271   renWin->Render();
272 
273   int retVal = vtkRegressionTestImage( renWin );
274   if ( retVal == vtkRegressionTester::DO_INTERACTOR)
275   {
276     iren->Start();
277   }
278 
279   return !retVal;
280 }
281