1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    BoxClipPolyData.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 /*----------------------------------------------------------------------------
17  Copyright (c) Sandia Corporation
18  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
19 ----------------------------------------------------------------------------*/
20 
21 #include "vtkActor.h"
22 #include "vtkBoxClipDataSet.h"
23 #include "vtkCellArray.h"
24 #include "vtkCellData.h"
25 #include "vtkCutter.h"
26 #include "vtkDataSetSurfaceFilter.h"
27 #include "vtkDoubleArray.h"
28 #include "vtkPlane.h"
29 #include "vtkPolyDataMapper.h"
30 #include "vtkProperty.h"
31 #include "vtkRenderer.h"
32 #include "vtkRenderWindow.h"
33 #include "vtkRenderWindowInteractor.h"
34 #include "vtkSphereSource.h"
35 #include "vtkUnstructuredGrid.h"
36 
37 #include "vtkSmartPointer.h"
38 #define VTK_CREATE(type, var) \
39   vtkSmartPointer<type> var = vtkSmartPointer<type>::New()
40 
41 const double minpoint1[] = { -1.00002, -0.50002, -0.50002 };
42 const double maxpoint1[] = { -0.0511337, 0.5, 0.5 };
43 
44 const double minpoint2[] = { -3.0, -1.0, -1.0 };
45 const double maxpoint2[] = { -1.0, 1.0, 1.0 };
46 
47 const double minpoint3[] = { -3.0, -1.0, 0.0 };
48 const double maxpoint3[] = { 0.0, 0.5, 1.0 };
49 
50 const double minusx[] = { -1.0, 0.0, 0.0 };
51 const double minusy[] = { 0.0, -1.0, 0.0 };
52 const double minusz[] = { 0.0, 0.0, -1.0 };
53 const double plusx[] = { 1.0, 0.0, 0.0 };
54 const double plusy[] = { 0.0, 1.0, 0.0 };
55 const double plusz[] = { 0.0, 0.0, 1.0 };
56 
57 const int numTriangles = 6;
58 const int numTrianglePoints = numTriangles*3*3;
59 static double trianglePointData[numTrianglePoints] = {
60   -4.0, -1.0, 0.0,
61   -2.0, -1.0, 0.0,
62   -3.0, -0.5, 0.0,
63 
64   -2.0, -1.0, 0.0,
65   -1.0e-17, -1.0, 0.0,
66   -1.0, -0.5, 0.0,
67 
68   -3.0, 0.25, 0.0,
69   -4.0, -0.25, 0.0,
70   -2.0, -0.25, 0.0,
71 
72   -1.0, 0.25, 0.0,
73   -2.0, -0.25, 0.0,
74   1.0e-17, -0.25, 0.0,
75 
76   -2.0, 0.5, 0.0,
77   -3.0, 1.0, 0.0,
78   -4.0, 0.5, 0.0,
79 
80   1.0e-17, 0.5, 0.0,
81   -1.0, 1.0, 0.0,
82   -2.0, 0.5, 0.0
83 };
84 
85 //-----------------------------------------------------------------------------
86 
87 const int numPolySets = 5;
88 
TestPolyData(vtkPolyData * data,int num,vtkRenderWindow * renwin,const double minBoxPoint[3],const double maxBoxPoint[3])89 static void TestPolyData(vtkPolyData *data, int num, vtkRenderWindow *renwin,
90                          const double minBoxPoint[3],
91                          const double maxBoxPoint[3])
92 {
93   // Set up test of normal box.
94   VTK_CREATE(vtkBoxClipDataSet, clipper1);
95   clipper1->SetInputData(data);
96   clipper1->GenerateClippedOutputOff();
97   clipper1->SetBoxClip(minBoxPoint[0], maxBoxPoint[0],
98                        minBoxPoint[1], maxBoxPoint[1],
99                        minBoxPoint[2], maxBoxPoint[2]);
100 
101   VTK_CREATE(vtkDataSetSurfaceFilter, surface1);
102   surface1->SetInputConnection(0, clipper1->GetOutputPort(0));
103 
104   VTK_CREATE(vtkPolyDataMapper, mapper1);
105   mapper1->SetInputConnection(0, surface1->GetOutputPort(0));
106 
107   VTK_CREATE(vtkActor, actor1);
108   actor1->SetMapper(mapper1);
109   actor1->GetProperty()->SetPointSize(3.0f);
110 
111   VTK_CREATE(vtkRenderer, renderer1);
112   renderer1->AddActor(actor1);
113   renderer1->SetBackground(0.0, 0.5, 0.5);
114   renderer1->SetViewport(static_cast<double>(num)/numPolySets, 0.75,
115                          static_cast<double>(num+1)/numPolySets, 1.0);
116   renwin->AddRenderer(renderer1);
117 
118   // Set up test of normal box with generation of clipped output.
119   VTK_CREATE(vtkBoxClipDataSet, clipper2);
120   clipper2->SetInputData(data);
121   clipper2->GenerateClippedOutputOn();
122   clipper2->SetBoxClip(minBoxPoint[0], maxBoxPoint[0],
123                        minBoxPoint[1], maxBoxPoint[1],
124                        minBoxPoint[2], maxBoxPoint[2]);
125 
126   VTK_CREATE(vtkDataSetSurfaceFilter, surface2_1);
127   surface2_1->SetInputConnection(0, clipper2->GetOutputPort(0));
128 
129   VTK_CREATE(vtkPolyDataMapper, mapper2_1);
130   mapper2_1->SetInputConnection(0, surface2_1->GetOutputPort(0));
131 
132   VTK_CREATE(vtkActor, actor2_1);
133   actor2_1->SetMapper(mapper2_1);
134   actor2_1->GetProperty()->SetPointSize(3.0f);
135 
136   VTK_CREATE(vtkDataSetSurfaceFilter, surface2_2);
137   surface2_2->SetInputConnection(clipper2->GetOutputPort(1));
138 
139   VTK_CREATE(vtkPolyDataMapper, mapper2_2);
140   mapper2_2->SetInputConnection(0, surface2_2->GetOutputPort(0));
141 
142   VTK_CREATE(vtkActor, actor2_2);
143   actor2_2->SetMapper(mapper2_2);
144   actor2_2->GetProperty()->SetColor(1.0, 0.5, 0.5);
145   actor2_2->GetProperty()->SetPointSize(3.0f);
146 
147   VTK_CREATE(vtkRenderer, renderer2);
148   renderer2->AddActor(actor2_1);
149   renderer2->AddActor(actor2_2);
150   renderer2->SetBackground(0.0, 0.5, 0.5);
151   renderer2->SetViewport(static_cast<double>(num)/numPolySets, 0.5,
152                          static_cast<double>(num+1)/numPolySets, 0.75);
153   renwin->AddRenderer(renderer2);
154 
155   // Set up test of an oriented box.
156   VTK_CREATE(vtkBoxClipDataSet, clipper3);
157   clipper3->SetInputData(data);
158   clipper3->GenerateClippedOutputOff();
159   clipper3->SetBoxClip(minusx, minBoxPoint,
160                        minusy, minBoxPoint,
161                        minusz, minBoxPoint,
162                        plusx, maxBoxPoint,
163                        plusy, maxBoxPoint,
164                        plusz, maxBoxPoint);
165 
166   VTK_CREATE(vtkDataSetSurfaceFilter, surface3);
167   surface3->SetInputConnection(0, clipper3->GetOutputPort(0));
168 
169   VTK_CREATE(vtkPolyDataMapper, mapper3);
170   mapper3->SetInputConnection(0, surface3->GetOutputPort(0));
171 
172   VTK_CREATE(vtkActor, actor3);
173   actor3->SetMapper(mapper3);
174   actor3->GetProperty()->SetPointSize(3.0f);
175 
176   VTK_CREATE(vtkRenderer, renderer3);
177   renderer3->AddActor(actor3);
178   renderer3->SetBackground(0.0, 0.5, 0.5);
179   renderer3->SetViewport(static_cast<double>(num)/numPolySets, 0.25,
180                          static_cast<double>(num+1)/numPolySets, 0.5);
181   renwin->AddRenderer(renderer3);
182 
183   // Set up test of an oriented box with generation of clipped output.
184   VTK_CREATE(vtkBoxClipDataSet, clipper4);
185   clipper4->SetInputData(data);
186   clipper4->GenerateClippedOutputOn();
187   clipper4->SetBoxClip(minusx, minBoxPoint,
188                        minusy, minBoxPoint,
189                        minusz, minBoxPoint,
190                        plusx, maxBoxPoint,
191                        plusy, maxBoxPoint,
192                        plusz, maxBoxPoint);
193 
194   VTK_CREATE(vtkDataSetSurfaceFilter, surface4_1);
195   surface4_1->SetInputConnection(0, clipper4->GetOutputPort(0));
196 
197   VTK_CREATE(vtkPolyDataMapper, mapper4_1);
198   mapper4_1->SetInputConnection(0, surface4_1->GetOutputPort(0));
199 
200   VTK_CREATE(vtkActor, actor4_1);
201   actor4_1->SetMapper(mapper4_1);
202   actor4_1->GetProperty()->SetPointSize(3.0f);
203 
204   VTK_CREATE(vtkDataSetSurfaceFilter, surface4_2);
205   surface4_2->SetInputConnection(clipper4->GetOutputPort(1));
206 
207   VTK_CREATE(vtkPolyDataMapper, mapper4_2);
208   mapper4_2->SetInputConnection(0, surface4_2->GetOutputPort(0));
209 
210   VTK_CREATE(vtkActor, actor4_2);
211   actor4_2->SetMapper(mapper4_2);
212   actor4_2->GetProperty()->SetColor(1.0, 0.5, 0.5);
213   actor4_2->GetProperty()->SetPointSize(3.0f);
214 
215   VTK_CREATE(vtkRenderer, renderer4);
216   renderer4->AddActor(actor4_1);
217   renderer4->AddActor(actor4_2);
218   renderer4->SetBackground(0.0, 0.5, 0.5);
219   renderer4->SetViewport(static_cast<double>(num)/numPolySets, 0.0,
220                          static_cast<double>(num+1)/numPolySets, 0.25);
221   renwin->AddRenderer(renderer4);
222 }
223 
224 //-----------------------------------------------------------------------------
225 
BoxClipPolyData(int,char * [])226 int BoxClipPolyData(int, char *[])
227 {
228   vtkIdType i;
229 
230   // The render window.
231   VTK_CREATE(vtkRenderWindow, renwin);
232   renwin->SetSize(800, 640);
233 
234   VTK_CREATE(vtkRenderWindowInteractor, iren);
235   iren->SetRenderWindow(renwin);
236 
237   // Test polygons on a sphere
238   VTK_CREATE(vtkSphereSource, sphere);
239   sphere->Update();
240 
241   TestPolyData(sphere->GetOutput(), 0, renwin, minpoint1, maxpoint1);
242 
243   // Test a triangle with points right on the box.
244   VTK_CREATE(vtkDoubleArray, trianglePointsArray);
245   trianglePointsArray->SetArray(trianglePointData, numTrianglePoints, 1);
246   trianglePointsArray->SetNumberOfComponents(3);
247   trianglePointsArray->SetNumberOfTuples(numTriangles*3);
248 
249   VTK_CREATE(vtkPoints, trianglePoints);
250   trianglePoints->SetData(trianglePointsArray);
251 
252   VTK_CREATE(vtkDoubleArray, triangleNormals);
253   triangleNormals->SetName("Normals");
254   triangleNormals->SetNumberOfComponents(3);
255   triangleNormals->SetNumberOfTuples(numTriangles);
256 
257   VTK_CREATE(vtkCellArray, triangleCells);
258   triangleCells->Allocate(numTriangles*4);
259 
260   for (i = 0; i < numTriangles; i++)
261     {
262     triangleNormals->SetTuple3(i, 0.0, 0.0, 1.0);
263 
264     vtkIdType pts[3];
265     pts[0] = i*3+0;  pts[1] = i*3+1;  pts[2] = i*3+2;
266     triangleCells->InsertNextCell(3, pts);
267     }
268 
269   VTK_CREATE(vtkPolyData, triangles);
270   triangles->SetPoints(trianglePoints);
271   triangles->SetPolys(triangleCells);
272   triangles->GetCellData()->SetNormals(triangleNormals);
273 
274   TestPolyData(triangles, 1, renwin, minpoint2, maxpoint2);
275 
276   // Test triangles co-planer with a face of the bounding box.
277   TestPolyData(triangles, 2, renwin, minpoint3, maxpoint3);
278 
279   // Test lines.
280   VTK_CREATE(vtkPolyData, sphereNoNormals);
281   sphereNoNormals->CopyStructure(sphere->GetOutput());
282 
283   VTK_CREATE(vtkPlane, plane);
284   plane->SetOrigin(0.0, 0.0, 0.0);
285   plane->SetNormal(0.0, 0.0, 1.0);
286 
287   VTK_CREATE(vtkCutter, cutter);
288   cutter->SetInputData(sphereNoNormals);
289   cutter->SetCutFunction(plane);
290   cutter->Update();
291 
292   TestPolyData(cutter->GetOutput(), 3, renwin, minpoint1, maxpoint1);
293 
294   // Test verts.
295   VTK_CREATE(vtkPolyData, verts);
296   vtkPoints *vertsPoints = sphereNoNormals->GetPoints();
297   verts->SetPoints(vertsPoints);
298 
299   VTK_CREATE(vtkCellArray, vertsCells);
300   vertsCells->Allocate(2*vertsPoints->GetNumberOfPoints());
301   for (i = 0; i < vertsPoints->GetNumberOfPoints(); i++)
302     {
303     vertsCells->InsertNextCell(1, &i);
304     }
305   verts->SetVerts(vertsCells);
306 
307   TestPolyData(verts, 4, renwin, minpoint1, maxpoint1);
308 
309   // Run the regression test.
310   renwin->Render();
311   iren->Start();
312 
313   return EXIT_SUCCESS;
314 }
315