1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkPlanes.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 #include "vtkPlanes.h"
16 
17 #include "vtkDoubleArray.h"
18 #include "vtkObjectFactory.h"
19 #include "vtkPlane.h"
20 #include "vtkPoints.h"
21 
22 #include <cmath>
23 
24 vtkStandardNewMacro(vtkPlanes);
25 vtkCxxSetObjectMacro(vtkPlanes,Points,vtkPoints);
26 
27 //----------------------------------------------------------------------------
vtkPlanes()28 vtkPlanes::vtkPlanes()
29 {
30   int i;
31 
32   this->Points = nullptr;
33   this->Normals = nullptr;
34   this->Plane = vtkPlane::New();
35 
36   for (i=0; i<24; i++)
37   {
38     this->Planes[i] = 0.0;
39   }
40   for (i=0; i<6; i++)
41   {
42     this->Bounds[i] = 0.0;
43   }
44 }
45 
46 //----------------------------------------------------------------------------
~vtkPlanes()47 vtkPlanes::~vtkPlanes()
48 {
49   if ( this->Points )
50   {
51     this->Points->UnRegister(this);
52   }
53   if ( this->Normals )
54   {
55     this->Normals->UnRegister(this);
56   }
57   this->Plane->Delete();
58 }
59 
60 //----------------------------------------------------------------------------
SetNormals(vtkDataArray * normals)61 void vtkPlanes::SetNormals(vtkDataArray* normals)
62 {
63   vtkDebugMacro(<< this->GetClassName() << " (" << this
64                 << "): setting Normals to " << normals );
65 
66   if (normals && normals->GetNumberOfComponents() != 3)
67   {
68     vtkWarningMacro("This array does not have 3 components. Ignoring normals.");
69     return;
70   }
71 
72   if (this->Normals != normals)
73   {
74     if (this->Normals != nullptr) { this->Normals->UnRegister(this); }
75     this->Normals = normals;
76     if (this->Normals != nullptr) { this->Normals->Register(this); }
77     this->Modified();
78   }
79 }
80 
81 //----------------------------------------------------------------------------
82 // Evaluate plane equations. Return the largest value.
EvaluateFunction(double x[3])83 double vtkPlanes::EvaluateFunction(double x[3])
84 {
85   int numPlanes, i;
86   double val, maxVal;
87   double normal[3], point[3];
88 
89   if ( !this->Points || ! this->Normals )
90   {
91     vtkErrorMacro(<<"Please define points and/or normals!");
92     return VTK_DOUBLE_MAX;
93   }
94 
95   if ( (numPlanes=this->Points->GetNumberOfPoints()) != this->Normals->GetNumberOfTuples() )
96   {
97     vtkErrorMacro(<<"Number of normals/points inconsistent!");
98     return VTK_DOUBLE_MAX;
99   }
100 
101   for (maxVal=-VTK_DOUBLE_MAX, i=0; i < numPlanes; i++)
102   {
103     this->Normals->GetTuple(i,normal);
104     this->Points->GetPoint(i,point);
105     val = this->Plane->Evaluate(normal, point,  x);
106     if (val > maxVal )
107     {
108       maxVal = val;
109     }
110   }
111 
112   return maxVal;
113 }
114 
115 //----------------------------------------------------------------------------
116 // Evaluate planes gradient.
EvaluateGradient(double x[3],double n[3])117 void vtkPlanes::EvaluateGradient(double x[3], double n[3])
118 {
119   int numPlanes, i;
120   double val, maxVal;
121   double nTemp[3];
122   double pTemp[3];
123 
124   if ( !this->Points || ! this->Normals )
125   {
126     vtkErrorMacro(<<"Please define points and/or normals!");
127     return;
128   }
129 
130   if ( (numPlanes=this->Points->GetNumberOfPoints()) !=
131        this->Normals->GetNumberOfTuples() )
132   {
133     vtkErrorMacro(<<"Number of normals/points inconsistent!");
134     return;
135   }
136 
137   for (maxVal=-VTK_DOUBLE_MAX, i=0; i < numPlanes; i++)
138   {
139     this->Normals->GetTuple(i, nTemp);
140     this->Points->GetPoint(i, pTemp);
141     val = this->Plane->Evaluate(nTemp, pTemp, x);
142     if ( val > maxVal )
143     {
144       maxVal = val;
145       n[0] = nTemp[0];
146       n[1] = nTemp[1];
147       n[2] = nTemp[2];
148     }
149   }
150 }
151 
152 //----------------------------------------------------------------------------
SetFrustumPlanes(double planes[24])153 void vtkPlanes::SetFrustumPlanes(double planes[24])
154 {
155   int i;
156   double *plane, n[3], x[3];
157 
158   for (i=0; i<24; i++)
159   {
160     if ( this->Planes[i] != planes[i] )
161     {
162       break;
163     }
164   }
165   if ( i >= 24 )
166   {
167     return; //same as before don't modify
168   }
169 
170   // okay, need to allocate stuff
171   this->Modified();
172   vtkPoints *pts = vtkPoints::New();
173   vtkDoubleArray *normals = vtkDoubleArray::New();
174 
175   pts->SetNumberOfPoints(6);
176   normals->SetNumberOfComponents(3);
177   normals->SetNumberOfTuples(6);
178   this->SetPoints(pts);
179   this->SetNormals(normals);
180 
181   for (i=0; i<6; i++)
182   {
183     plane = planes + 4*i;
184     n[0] = -plane[0];
185     n[1] = -plane[1];
186     n[2] = -plane[2];
187     x[0] = x[1] = x[2] = 0.0;
188     if ( n[0] != 0.0 )
189     {
190       x[0] = plane[3] / n[0];
191     }
192     else if ( n[1] != 0.0 )
193     {
194       x[1] = plane[3] / n[1];
195     }
196     else
197     {
198       x[2] = plane[3] / n[2];
199     }
200     pts->SetPoint(i,x);
201     normals->SetTuple(i,n);
202   }
203 
204   pts->Delete(); //ok reference counting
205   normals->Delete();
206 }
207 
208 //----------------------------------------------------------------------------
SetBounds(const double bounds[6])209 void vtkPlanes::SetBounds(const double bounds[6])
210 {
211   int i;
212   double n[3], x[3];
213 
214   for (i=0; i<6; i++)
215   {
216     if ( this->Bounds[i] != bounds[i] )
217     {
218       break;
219     }
220   }
221   if ( i >= 6 )
222   {
223     return; //same as before don't modify
224   }
225 
226   // okay, need to allocate stuff
227   this->Modified();
228   vtkPoints *pts = vtkPoints::New();
229   vtkDoubleArray *normals = vtkDoubleArray::New();
230 
231   pts->SetNumberOfPoints(6);
232   normals->SetNumberOfComponents(3);
233   normals->SetNumberOfTuples(6);
234   this->SetPoints(pts);
235   this->SetNormals(normals);
236 
237   // Define the six planes
238   // The x planes
239   n[0] = -1.0;
240   n[1] = 0.0;
241   n[2] = 0.0;
242   x[0] = this->Bounds[0] = bounds[0];
243   x[1] = 0.0;
244   x[2] = 0.0;
245   pts->SetPoint(0,x);
246   normals->SetTuple(0,n);
247 
248   n[0] = 1.0;
249   x[0] = this->Bounds[1] = bounds[1];
250   pts->SetPoint(1,x);
251   normals->SetTuple(1,n);
252 
253   // The y planes
254   n[0] = 0.0;
255   n[1] = -1.0;
256   n[2] = 0.0;
257   x[0] = 0.0;
258   x[1] = this->Bounds[2] = bounds[2];
259   x[2] = 0.0;
260   pts->SetPoint(2,x);
261   normals->SetTuple(2,n);
262 
263   n[1] = 1.0;
264   x[1] = this->Bounds[3] = bounds[3];
265   pts->SetPoint(3,x);
266   normals->SetTuple(3,n);
267 
268   // The z planes
269   n[0] = 0.0;
270   n[1] = 0.0;
271   n[2] = -1.0;
272   x[0] = 0.0;
273   x[1] = 0.0;
274   x[2] = this->Bounds[4] = bounds[4];
275   pts->SetPoint(4,x);
276   normals->SetTuple(4,n);
277 
278   n[2] = 1.0;
279   x[2] = this->Bounds[5] = bounds[5];
280   pts->SetPoint(5,x);
281   normals->SetTuple(5,n);
282 
283   pts->Delete(); //ok reference counting
284   normals->Delete();
285 }
286 
287 //----------------------------------------------------------------------------
SetBounds(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax)288 void vtkPlanes::SetBounds(double xmin, double xmax, double ymin, double ymax,
289                           double zmin, double zmax)
290 {
291   double bounds[6];
292   bounds[0] = xmin;
293   bounds[1] = xmax;
294   bounds[2] = ymin;
295   bounds[3] = ymax;
296   bounds[4] = zmin;
297   bounds[5] = zmax;
298 
299   this->SetBounds(bounds);
300 }
301 
302 //----------------------------------------------------------------------------
GetNumberOfPlanes()303 int vtkPlanes::GetNumberOfPlanes()
304 {
305   if ( this->Points && this->Normals )
306   {
307     int npts = this->Points->GetNumberOfPoints();
308     int nnormals = this->Normals->GetNumberOfTuples();
309     return ( npts <= nnormals ? npts : nnormals );
310   }
311   else
312   {
313     return 0;
314   }
315 }
316 
317 //----------------------------------------------------------------------------
GetPlane(int i)318 vtkPlane *vtkPlanes::GetPlane(int i)
319 {
320   double normal[3];
321   double point[3];
322 
323   if ( i >= 0 && i < this->GetNumberOfPlanes() )
324   {
325     this->Normals->GetTuple(i,normal);
326     this->Points->GetPoint(i,point);
327     this->Plane->SetNormal(normal);
328     this->Plane->SetOrigin(point);
329     return this->Plane;
330   }
331   else
332   {
333     return nullptr;
334   }
335 }
336 
337 //----------------------------------------------------------------------------
GetPlane(int i,vtkPlane * plane)338 void vtkPlanes::GetPlane(int i, vtkPlane *plane)
339 {
340   if ( i >= 0 && i < this->GetNumberOfPlanes() )
341   {
342     double normal[3];
343     double point[3];
344     this->Normals->GetTuple(i,normal);
345     this->Points->GetPoint(i,point);
346     plane->SetNormal(normal);
347     plane->SetOrigin(point);
348   }
349 }
350 
351 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)352 void vtkPlanes::PrintSelf(ostream& os, vtkIndent indent)
353 {
354   this->Superclass::PrintSelf(os,indent);
355 
356   int numPlanes;
357 
358   if ( this->Points && (numPlanes=this->Points->GetNumberOfPoints()) > 0 )
359   {
360     os << indent << "Number of Planes: " << numPlanes << "\n";
361   }
362   else
363   {
364     os << indent << "No Planes Defined.\n";
365   }
366 
367   if ( this->Normals )
368   {
369     os << indent << "Normals: " << this->Normals << "\n";
370   }
371   else
372   {
373     os << indent << "Normals: (none)\n";
374   }
375 }
376