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