1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkPlatonicSolidSource.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 "vtkPlatonicSolidSource.h"
16
17 #include "vtkInformation.h"
18 #include "vtkInformationVector.h"
19 #include "vtkObjectFactory.h"
20 #include "vtkPolyData.h"
21 #include "vtkCellArray.h"
22 #include "vtkCellData.h"
23 #include "vtkPoints.h"
24
25 vtkStandardNewMacro(vtkPlatonicSolidSource);
26
27 // Wrapping this in namespaces because the short names (a, b, c, etc) are
28 // throwing warnings on MSVC when inlined methods in vtkGenericDataArray are
29 // being used ('warning C4459: declaration of 'c' hides global declaration')
30 namespace {
31 namespace vtkPlatonicSolidSourceDetail {
32 // The geometry and topology of each solid. Solids are centered at
33 // the origin with radius 1.0.
34 // The golden ration phi = (1+sqrt(5))/2=1.61803398875 enters into many
35 // of these values.
36 static double TetraPoints[] = {
37 1.0,1.0,1.0, -1.0,1.0,-1.0, 1.0,-1.0,-1.0, -1.0,-1.0,1.0
38 };
39 static vtkIdType TetraVerts[] = {
40 0,1,2, 1,3,2, 0,2,3, 0,3,1
41 };
42
43 static double CubePoints[] = {
44 -1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,1.0,-1.0, -1.0,1.0,-1.0,
45 -1.0,-1.0,1.0, 1.0,-1.0,1.0, 1.0,1.0,1.0, -1.0,1.0,1.0
46 };
47 static vtkIdType CubeVerts[] = {
48 0,1,5,4, 0,4,7,3, 4,5,6,7, 3,7,6,2, 1,2,6,5, 0,3,2,1
49 };
50
51 static double OctPoints[] = {
52 -1.0,-1.0,0.0, 1.0,-1.0,0.0, 1.0,1.0,0.0, -1.0,1.0,0.0,
53 0.0,0.0,-1.4142135623731, 0.0,0.0,1.4142135623731
54 };
55 static vtkIdType OctVerts[] = {
56 4,1,0, 4,2,1, 4,3,2, 4,0,3, 0,1,5, 1,2,5, 2,3,5, 3,0,5
57 };
58
59 static double a_0 = 0.61803398875;
60 static double b = 0.381966011250;
61 static double DodePoints[] = {
62 b, 0, 1, -b, 0, 1, b, 0,-1, -b, 0,-1, 0, 1,-b,
63 0, 1, b, 0,-1,-b, 0,-1, b, 1, b, 0, 1,-b, 0,
64 -1, b, 0, -1,-b, 0, -a_0, a_0, a_0, a_0,-a_0, a_0, -a_0,-a_0,-a_0,
65 a_0, a_0,-a_0, a_0, a_0, a_0, -a_0, a_0,-a_0, -a_0,-a_0, a_0, a_0,-a_0,-a_0
66 };
67 static vtkIdType DodeVerts[] = {
68 0,16,5,12,1, 1,18,7,13,0, 2,19,6,14,3, 3,17,4,15,2, 4,5,16,8,15,
69 5,4,17,10,12, 6,7,18,11,14, 7,6,19,9,13, 8,16,0,13,9, 9,19,2,15,8,
70 10,17,3,14,11, 11,18,1,12,10
71 };
72
73 static double c = 0.5;
74 static double d = 0.30901699;
75 static double IcosaPoints[] = {
76 0.0,d,-c, 0.0,d,c, 0.0,-d,c, -d,c,0.0,
77 -d,-c,0.0, d,c,0.0, d,-c,0.0, 0.0,-d,-c,
78 c,0.0,d, -c,0.0,d, -c,0.0,-d, c,0.0,-d
79 };
80 static vtkIdType IcosaVerts[] = {
81 0,5,3, 1,3,5, 1,2,9, 1,8,2, 0,7,11, 0,10,7, 2,6,4, 7,4,6, 3,9,10,
82 4,10,9, 5,11,8, 6,8,11, 1,9,3, 1,5,8, 0,3,10, 0,11,5, 7,10,4, 7,6,11,
83 2,4,9, 2,8,6
84 };
85 } // end namespace detail
86 } // end anon namespace
87
vtkPlatonicSolidSource()88 vtkPlatonicSolidSource::vtkPlatonicSolidSource()
89 {
90 this->SolidType = VTK_SOLID_TETRAHEDRON;
91 this->OutputPointsPrecision = SINGLE_PRECISION;
92 this->SetNumberOfInputPorts(0);
93 }
94
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * outputVector)95 int vtkPlatonicSolidSource::RequestData(
96 vtkInformation *vtkNotUsed(request),
97 vtkInformationVector **vtkNotUsed(inputVector),
98 vtkInformationVector *outputVector)
99 {
100 // get the info object
101 vtkInformation *outInfo = outputVector->GetInformationObject(0);
102
103 // get the output
104 vtkPolyData *output = vtkPolyData::SafeDownCast(
105 outInfo->Get(vtkDataObject::DATA_OBJECT()));
106
107 int i;
108 double *pptr, *solidPoints=nullptr, solidScale=1.0;
109 vtkIdType *cptr, numPts=0, numCells=0, cellSize=0, *solidVerts=nullptr;
110
111 vtkDebugMacro(<<"Creating Platonic solid");
112
113 // Based on type, select correct connectivity and point arrays
114 //
115 switch (this->SolidType)
116 {
117 case VTK_SOLID_TETRAHEDRON:
118 numPts = 4;
119 cellSize = 3;
120 numCells = 4;
121 solidPoints = vtkPlatonicSolidSourceDetail::TetraPoints;
122 solidVerts = vtkPlatonicSolidSourceDetail::TetraVerts;
123 solidScale = 1.0/sqrt(3.0);
124 break;
125
126 case VTK_SOLID_CUBE:
127 numPts = 8;
128 cellSize = 4;
129 numCells = 6;
130 solidPoints = vtkPlatonicSolidSourceDetail::CubePoints;
131 solidVerts = vtkPlatonicSolidSourceDetail::CubeVerts;
132 solidScale = 1.0/sqrt(3.0);
133 break;
134
135 case VTK_SOLID_OCTAHEDRON:
136 numPts = 6;
137 cellSize = 3;
138 numCells = 8;
139 solidPoints = vtkPlatonicSolidSourceDetail::OctPoints;
140 solidVerts = vtkPlatonicSolidSourceDetail::OctVerts;
141 solidScale = 1.0/sqrt(2.0);
142 break;
143
144 case VTK_SOLID_ICOSAHEDRON:
145 numPts = 12;
146 cellSize = 3;
147 numCells = 20;
148 solidPoints = vtkPlatonicSolidSourceDetail::IcosaPoints;
149 solidVerts = vtkPlatonicSolidSourceDetail::IcosaVerts;
150 solidScale = 1.0/0.58778524999243;
151 break;
152
153 case VTK_SOLID_DODECAHEDRON:
154 numPts = 20;
155 cellSize = 5;
156 numCells = 12;
157 solidPoints = vtkPlatonicSolidSourceDetail::DodePoints;
158 solidVerts = vtkPlatonicSolidSourceDetail::DodeVerts;
159 solidScale = 1.0/1.070466269319;
160 break;
161 }
162
163 // Create the solids
164 //
165 vtkPoints *pts = vtkPoints::New();
166
167 // Set the desired precision for the points in the output.
168 if(this->OutputPointsPrecision == vtkAlgorithm::DOUBLE_PRECISION)
169 {
170 pts->SetDataType(VTK_DOUBLE);
171 }
172 else
173 {
174 pts->SetDataType(VTK_FLOAT);
175 }
176
177 pts->SetNumberOfPoints(numPts);
178 vtkCellArray *polys = vtkCellArray::New();
179 polys->Allocate(polys->EstimateSize(numCells,cellSize));
180 vtkIntArray *colors = vtkIntArray::New();
181 colors->SetNumberOfComponents(1);
182 colors->SetNumberOfTuples(numCells);
183
184 // Points
185 for ( i=0, pptr=solidPoints; i<numPts; i++, pptr+=3 )
186 {
187 pts->SetPoint(i, solidScale*(pptr[0]), solidScale*(pptr[1]),
188 solidScale*(pptr[2]));
189 }
190
191 // Cells
192 for ( i=0, cptr=solidVerts; i<numCells; i++, cptr+=cellSize )
193 {
194 polys->InsertNextCell(cellSize,cptr);
195 colors->SetTuple1(i,i);
196 }
197
198 // Assemble the output
199 output->SetPoints(pts);
200 output->SetPolys(polys);
201 int idx = output->GetCellData()->AddArray(colors);
202 output->GetCellData()->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
203
204 pts->Delete();
205 polys->Delete();
206 colors->Delete();
207
208 return 1;
209 }
210
PrintSelf(ostream & os,vtkIndent indent)211 void vtkPlatonicSolidSource::PrintSelf(ostream& os, vtkIndent indent)
212 {
213 this->Superclass::PrintSelf(os,indent);
214
215 os << indent << "Solid Type: " << "\n";
216 if ( this->SolidType == VTK_SOLID_TETRAHEDRON )
217 {
218 os << "Tetrahedron\n";
219 }
220 else if ( this->SolidType == VTK_SOLID_CUBE )
221 {
222 os << "Cube\n";
223 }
224 else if ( this->SolidType == VTK_SOLID_OCTAHEDRON )
225 {
226 os << "Octahedron\n";
227 }
228 else if ( this->SolidType == VTK_SOLID_ICOSAHEDRON )
229 {
230 os << "Icosahedron\n";
231 }
232 else //if ( this->SolidType == VTK_SOLID_DODECAHEDRON )
233 {
234 os << "Dodecahedron\n";
235 }
236
237 os << indent << "Output Points Precision: " << this->OutputPointsPrecision
238 << "\n";
239 }
240