1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: TestImplicitPolyDataDistance.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 #include "vtkActor.h"
15 #include "vtkCamera.h"
16 #include "vtkGlyph3D.h"
17 #include "vtkImplicitPolyDataDistance.h"
18 #include "vtkNew.h"
19 #include "vtkPlaneSource.h"
20 #include "vtkPolyDataMapper.h"
21 #include "vtkProperty.h"
22 #include "vtkRegressionTestImage.h"
23 #include "vtkRenderer.h"
24 #include "vtkRenderWindow.h"
25 #include "vtkRenderWindowInteractor.h"
26 #include "vtkSmartPointer.h"
27 #include "vtkSphereSource.h"
28 #include "vtkTesting.h"
29 #include "vtkXMLPolyDataReader.h"
30
31 #include <vector>
32
TestImplicitPolyDataDistance(int argc,char * argv[])33 int TestImplicitPolyDataDistance(int argc, char* argv[])
34 {
35 vtkSmartPointer<vtkTesting> testHelper =
36 vtkSmartPointer<vtkTesting>::New();
37 testHelper->AddArguments(argc, argv);
38 if (!testHelper->IsFlagSpecified("-D"))
39 {
40 std::cerr << "Error: -D /path/to/data was not specified.";
41 return EXIT_FAILURE;
42 }
43
44 std::string dataRoot = testHelper->GetDataRoot();
45 std::string fileName = dataRoot + "/Data/CuspySurface.vtp";
46 std::cout << fileName << std::endl;
47
48 // Set up reader
49 vtkNew<vtkXMLPolyDataReader> reader;
50 reader->SetFileName(fileName.c_str());
51 reader->Update();
52
53 // Set up distance calculator
54 vtkNew<vtkImplicitPolyDataDistance> implicitDistance;
55 implicitDistance->SetInput(reader->GetOutput());
56
57 // Test SetNoClosestPoint() and GetNoClosestPoint()
58 double noClosestPoint[3] = {1.0, 1.0, 1.0};
59 implicitDistance->SetNoClosestPoint(noClosestPoint);
60 implicitDistance->GetNoClosestPoint(noClosestPoint);
61 if(noClosestPoint[0] != 1.0 && noClosestPoint[1] != 1.0 && noClosestPoint[2] != 1.0)
62 {
63 return EXIT_FAILURE;
64 }
65
66 // Compute distances to test points, saving those within the cuspy surface for display
67 vtkNew<vtkPoints> insidePoints;
68 vtkNew<vtkPoints> surfacePoints;
69 double xRange[2] = {-47.6, 46.9};
70 double yRange[2] = {-18.2, 82.1};
71 double zRange[2] = {1.63, 102};
72 const double spacing = 10.0;
73 for (double z = zRange[0]; z < zRange[1]; z += spacing)
74 {
75 for (double y = yRange[0]; y < yRange[1]; y += spacing)
76 {
77 for (double x = xRange[0]; x < xRange[1]; x += spacing)
78 {
79 double point[3] = {x, y, z};
80 double surfacePoint[3];
81 double distance = implicitDistance->EvaluateFunctionAndGetClosestPoint(point, surfacePoint);
82 if (distance <= 0.0)
83 {
84 insidePoints->InsertNextPoint(point);
85 surfacePoints->InsertNextPoint(surfacePoint);
86 }
87 }
88 }
89 }
90
91 // Set up inside points data structure
92 vtkNew<vtkPolyData> insidePointsPolyData;
93 insidePointsPolyData->SetPoints(insidePoints);
94
95 // Glyph the points
96 vtkNew<vtkSphereSource> insidePointSphere;
97 insidePointSphere->SetRadius(3);
98 vtkNew<vtkGlyph3D> insidePointsGlypher;
99 insidePointsGlypher->SetInputData(insidePointsPolyData);
100 insidePointsGlypher->SetSourceConnection(insidePointSphere->GetOutputPort());
101
102 // Display the glyphs
103 vtkNew<vtkPolyDataMapper> insidePointMapper;
104 insidePointMapper->SetInputConnection(insidePointsGlypher->GetOutputPort());
105
106 vtkNew<vtkActor> insidePointActor;
107 insidePointActor->SetMapper(insidePointMapper);
108 insidePointActor->GetProperty()->SetColor(1.0, 0.0, 0.0);
109
110 // Set up surface points data structure
111 vtkNew<vtkPolyData> surfacePointsPolyData;
112 surfacePointsPolyData->SetPoints(surfacePoints);
113
114 // Glyph the points
115 vtkNew<vtkSphereSource> surfacePointSphere;
116 surfacePointSphere->SetRadius(3);
117 vtkNew<vtkGlyph3D> surfacePointsGlypher;
118 surfacePointsGlypher->SetInputData(surfacePointsPolyData);
119 surfacePointsGlypher->SetSourceConnection(surfacePointSphere->GetOutputPort());
120
121 // Display the glyphs
122 vtkNew<vtkPolyDataMapper> surfacePointMapper;
123 surfacePointMapper->SetInputConnection(surfacePointsGlypher->GetOutputPort());
124
125 vtkNew<vtkActor> surfacePointActor;
126 surfacePointActor->SetMapper(surfacePointMapper);
127 surfacePointActor->GetProperty()->SetColor(0.0, 0.0, 1.0);
128
129 // Display the bounding surface
130 vtkNew<vtkPolyDataMapper> surfaceMapper;
131 surfaceMapper->SetInputConnection(reader->GetOutputPort());
132
133 vtkNew<vtkActor> surfaceActor;
134 surfaceActor->SetMapper(surfaceMapper);
135 surfaceActor->GetProperty()->FrontfaceCullingOn();
136
137 // Standard rendering classes
138 vtkSmartPointer<vtkRenderer> renderer =
139 vtkSmartPointer<vtkRenderer>::New();
140 vtkSmartPointer<vtkRenderWindow> renWin =
141 vtkSmartPointer<vtkRenderWindow>::New();
142 renWin->SetMultiSamples(0);
143 renWin->AddRenderer(renderer);
144 vtkSmartPointer<vtkRenderWindowInteractor> iren =
145 vtkSmartPointer<vtkRenderWindowInteractor>::New();
146 iren->SetRenderWindow(renWin);
147
148 renderer->AddActor(insidePointActor);
149 renderer->AddActor(surfacePointActor);
150 renderer->AddActor(surfaceActor);
151
152 // Standard testing code.
153 renderer->SetBackground(0.0, 0.0, 0.0);
154 renWin->SetSize(300,300);
155
156 vtkCamera *camera = renderer->GetActiveCamera();
157 renderer->ResetCamera();
158 camera->Azimuth(30);
159 camera->Elevation(-20);
160
161 iren->Initialize();
162
163 renWin->Render();
164
165 int retVal = vtkRegressionTestImage(renWin);
166 if (retVal == vtkRegressionTester::DO_INTERACTOR)
167 {
168 iren->Start();
169 }
170
171 return !retVal;
172 }
173