1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkSpheres.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 "vtkSpheres.h"
16
17 #include "vtkDoubleArray.h"
18 #include "vtkObjectFactory.h"
19 #include "vtkPoints.h"
20 #include "vtkSphere.h"
21
22 #include <cmath>
23
24 vtkStandardNewMacro(vtkSpheres);
25 vtkCxxSetObjectMacro(vtkSpheres, Centers, vtkPoints);
26
27 //------------------------------------------------------------------------------
vtkSpheres()28 vtkSpheres::vtkSpheres()
29 {
30 this->Centers = nullptr;
31 this->Radii = nullptr;
32 this->Sphere = vtkSphere::New();
33 }
34
35 //------------------------------------------------------------------------------
~vtkSpheres()36 vtkSpheres::~vtkSpheres()
37 {
38 if (this->Centers)
39 {
40 this->Centers->UnRegister(this);
41 }
42 if (this->Radii)
43 {
44 this->Radii->UnRegister(this);
45 }
46 this->Sphere->Delete();
47 }
48
49 //------------------------------------------------------------------------------
SetRadii(vtkDataArray * radii)50 void vtkSpheres::SetRadii(vtkDataArray* radii)
51 {
52 vtkDebugMacro(<< this->GetClassName() << " (" << this << "): setting Radii to " << radii);
53
54 if (radii && radii->GetNumberOfComponents() != 1)
55 {
56 vtkWarningMacro("This array does not have 1 components. Ignoring radii.");
57 return;
58 }
59
60 if (this->Radii != radii)
61 {
62 if (this->Radii != nullptr)
63 {
64 this->Radii->UnRegister(this);
65 }
66 this->Radii = radii;
67 if (this->Radii != nullptr)
68 {
69 this->Radii->Register(this);
70 }
71 this->Modified();
72 }
73 }
74
75 //------------------------------------------------------------------------------
76 // Evaluate sphere equations. Return smallest absolute value.
EvaluateFunction(double x[3])77 double vtkSpheres::EvaluateFunction(double x[3])
78 {
79 int numSpheres, i;
80 double val, minVal;
81 double radius[1], center[3];
82
83 if (!this->Centers || !this->Radii)
84 {
85 vtkErrorMacro(<< "Please define points and/or radii!");
86 return VTK_DOUBLE_MAX;
87 }
88
89 if ((numSpheres = this->Centers->GetNumberOfPoints()) != this->Radii->GetNumberOfTuples())
90 {
91 vtkErrorMacro(<< "Number of radii/points inconsistent!");
92 return VTK_DOUBLE_MAX;
93 }
94
95 for (minVal = VTK_DOUBLE_MAX, i = 0; i < numSpheres; i++)
96 {
97 this->Radii->GetTuple(i, radius);
98 this->Centers->GetPoint(i, center);
99 val = vtkSphere::Evaluate(center, radius[0], x);
100 if (val < minVal)
101 {
102 minVal = val;
103 }
104 }
105
106 return minVal;
107 }
108
109 //------------------------------------------------------------------------------
110 // Evaluate spheres gradient.
EvaluateGradient(double x[3],double n[3])111 void vtkSpheres::EvaluateGradient(double x[3], double n[3])
112 {
113 int numSpheres, i;
114 double val, minVal;
115 double rTemp[1];
116 double cTemp[3];
117
118 if (!this->Centers || !this->Radii)
119 {
120 vtkErrorMacro(<< "Please define centers and radii!");
121 return;
122 }
123
124 if ((numSpheres = this->Centers->GetNumberOfPoints()) != this->Radii->GetNumberOfTuples())
125 {
126 vtkErrorMacro(<< "Number of radii/centersinconsistent!");
127 return;
128 }
129
130 for (minVal = VTK_DOUBLE_MAX, i = 0; i < numSpheres; i++)
131 {
132 this->Radii->GetTuple(i, rTemp);
133 this->Centers->GetPoint(i, cTemp);
134 val = vtkSphere::Evaluate(cTemp, rTemp[0], x);
135 if (val < minVal)
136 {
137 minVal = val;
138 n[0] = x[0] - cTemp[0];
139 n[1] = x[1] - cTemp[1];
140 n[2] = x[2] - cTemp[2];
141 }
142 }
143 }
144
145 //------------------------------------------------------------------------------
GetNumberOfSpheres()146 int vtkSpheres::GetNumberOfSpheres()
147 {
148 if (this->Centers && this->Radii)
149 {
150 int npts = this->Centers->GetNumberOfPoints();
151 int nradii = this->Radii->GetNumberOfTuples();
152 return (npts <= nradii ? npts : nradii);
153 }
154 else
155 {
156 return 0;
157 }
158 }
159
160 //------------------------------------------------------------------------------
GetSphere(int i)161 vtkSphere* vtkSpheres::GetSphere(int i)
162 {
163 double radius[1];
164 double center[3];
165
166 if (i >= 0 && i < this->GetNumberOfSpheres())
167 {
168 this->Radii->GetTuple(i, radius);
169 this->Centers->GetPoint(i, center);
170 this->Sphere->SetRadius(radius[0]);
171 this->Sphere->SetCenter(center);
172 return this->Sphere;
173 }
174 else
175 {
176 return nullptr;
177 }
178 }
179
180 //------------------------------------------------------------------------------
GetSphere(int i,vtkSphere * sphere)181 void vtkSpheres::GetSphere(int i, vtkSphere* sphere)
182 {
183 if (i >= 0 && i < this->GetNumberOfSpheres())
184 {
185 double radius[1];
186 double center[3];
187 this->Radii->GetTuple(i, radius);
188 this->Centers->GetPoint(i, center);
189 sphere->SetRadius(radius[0]);
190 sphere->SetCenter(center);
191 }
192 }
193
194 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)195 void vtkSpheres::PrintSelf(ostream& os, vtkIndent indent)
196 {
197 this->Superclass::PrintSelf(os, indent);
198
199 int numSpheres;
200 if (this->Centers && (numSpheres = this->Centers->GetNumberOfPoints()) > 0)
201 {
202 os << indent << "Number of Spheres: " << numSpheres << "\n";
203 }
204 else
205 {
206 os << indent << "No Spheres Defined.\n";
207 }
208
209 if (this->Radii)
210 {
211 os << indent << "Radii: " << this->Radii << "\n";
212 }
213 else
214 {
215 os << indent << "Radii: (none)\n";
216 }
217 }
218