14 #ifndef _itkSphereTessellator_hxx 15 #define _itkSphereTessellator_hxx 27 template <
typename TElement>
31 m_BasicShape = ICOSAHEDRON;
40 m_NumberOfVertices = 0;
48 template <
typename TElement>
52 if (vertices) free (vertices);
53 if (faces) free (faces);
60 template <
typename TElement>
73 template <
typename TElement>
85 template <
typename TElement>
96 template <
typename TElement>
101 double sqrt3 = 1 / vcl_sqrt(3.0);
102 double tetrahedron_vertices[] = {sqrt3, sqrt3, sqrt3,
103 -sqrt3, -sqrt3, sqrt3,
104 -sqrt3, sqrt3, -sqrt3,
105 sqrt3, -sqrt3, -sqrt3};
106 int tetrahedron_faces[] = {0, 2, 1, 0, 1, 3, 2, 3, 1, 3, 2, 0};
111 vertices = (
double*)malloc(3*n_vertices*
sizeof(
double));
112 faces = (
int*)malloc(3*n_faces*
sizeof(
int));
113 memcpy ((
void*)vertices, (
void*)tetrahedron_vertices, 3*n_vertices*
sizeof(
double));
114 memcpy ((
void*)faces, (
void*)tetrahedron_faces, 3*n_faces*
sizeof(
int));
117 template <
typename TElement>
122 double octahedron_vertices[] = {0.0, 0.0, -1.0,
128 int octahedron_faces[] = {0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1, 5, 2, 1, 5, 3, 2, 5, 4, 3, 5, 1, 4};
133 vertices = (
double*)malloc(3*n_vertices*
sizeof(
double));
134 faces = (
int*)malloc(3*n_faces*
sizeof(
int));
135 memcpy ((
void*)vertices, (
void*)octahedron_vertices, 3*n_vertices*
sizeof(
double));
136 memcpy ((
void*)faces, (
void*)octahedron_faces, 3*n_faces*
sizeof(
int));
139 template <
typename TElement>
144 double t = (1+vcl_sqrt(5))/2;
145 double tau = t/vcl_sqrt(1+t*t);
146 double one = 1/vcl_sqrt(1+t*t);
148 double icosahedron_vertices[] = {tau, one, 0.0,
160 int icosahedron_faces[] = {4, 8, 7,
184 vertices = (
double*)malloc(3*n_vertices*
sizeof(
double));
185 faces = (
int*)malloc(3*n_faces*
sizeof(
int));
186 memcpy ((
void*)vertices, (
void*)icosahedron_vertices, 3*n_vertices*
sizeof(
double));
187 memcpy ((
void*)faces, (
void*)icosahedron_faces, 3*n_faces*
sizeof(
int));
190 template <
typename TElement>
196 for (i=0; i<edge_walk; i++)
197 if ((start[i] == index_start && end[i] == index_end) ||
198 (start[i] == index_end && end[i] == index_start))
200 int res = midpoint[i];
203 start[i] = start[edge_walk-1];
204 end[i] = end[edge_walk-1];
205 midpoint[i] = midpoint[edge_walk-1];
212 start[edge_walk] = index_start;
213 end[edge_walk] = index_end;
214 midpoint[edge_walk] = n_vertices;
217 vertices[3*n_vertices] = (vertices[3*index_start] + vertices[3*index_end]) / 2.0;
218 vertices[3*n_vertices+1] = (vertices[3*index_start+1] + vertices[3*index_end+1]) / 2.0;
219 vertices[3*n_vertices+2] = (vertices[3*index_start+2] + vertices[3*index_end+2]) / 2.0;
222 double length = vcl_sqrt (vertices[3*n_vertices] * vertices[3*n_vertices] +
223 vertices[3*n_vertices+1] * vertices[3*n_vertices+1] +
224 vertices[3*n_vertices+2] * vertices[3*n_vertices+2]);
226 vertices[3*n_vertices] *= length;
227 vertices[3*n_vertices+1] *= length;
228 vertices[3*n_vertices+2] *= length;
232 return midpoint[edge_walk-1];
235 template <
typename TElement>
240 unsigned int n_vertices_new = n_vertices+2*n_edges;
241 unsigned int n_faces_new = 4*n_faces;
245 n_edges = 2*n_vertices + 3*n_faces;
246 start = (
int*)malloc(n_edges*
sizeof (
int));
247 end = (
int*)malloc(n_edges*
sizeof (
int));
248 midpoint = (
int*)malloc(n_edges*
sizeof (
int));
250 int *faces_old = (
int*)malloc (3*n_faces*
sizeof(
int));
251 faces_old = (
int*)memcpy((
void*)faces_old, (
void*)faces, 3*n_faces*
sizeof(
int));
252 vertices = (
double*)realloc ((
void*)vertices, 3*n_vertices_new*
sizeof(double));
253 faces = (
int*)realloc ((
void*)faces, 3*n_faces_new*
sizeof(int));
256 for (i=0; i<n_faces; i++)
258 int a = faces_old[3*i];
259 int b = faces_old[3*i+1];
260 int c = faces_old[3*i+2];
262 int ab_midpoint = SearchMidpoint (b, a);
263 int bc_midpoint = SearchMidpoint (c, b);
264 int ca_midpoint = SearchMidpoint (a, c);
266 faces[3*n_faces_new] = a;
267 faces[3*n_faces_new+1] = ab_midpoint;
268 faces[3*n_faces_new+2] = ca_midpoint;
270 faces[3*n_faces_new] = ca_midpoint;
271 faces[3*n_faces_new+1] = ab_midpoint;
272 faces[3*n_faces_new+2] = bc_midpoint;
274 faces[3*n_faces_new] = ca_midpoint;
275 faces[3*n_faces_new+1] = bc_midpoint;
276 faces[3*n_faces_new+2] = c;
278 faces[3*n_faces_new] = ab_midpoint;
279 faces[3*n_faces_new+1] = b;
280 faces[3*n_faces_new+2] = bc_midpoint;
283 n_faces = n_faces_new;
293 template <
typename TElement>
298 switch (m_BasicShape)
311 for (
unsigned int k=1; k < m_Order; k++)
317 template <
typename TElement>
323 m_NumberOfVertices = n_vertices;
324 m_NumberOfFaces = n_faces;
325 m_NumberOfEdges = n_edges;
327 m_Points.set_size(n_vertices, 3);
328 m_Cells.set_size(n_faces, 3);
330 for (
unsigned int k=0; k<n_vertices; k++)
332 m_Points(k,0) = vertices[3*k];
333 m_Points(k,1) = vertices[3*k+1];
334 m_Points(k,2) = vertices[3*k+2];
336 for (
unsigned int k=0; k<n_faces; k++)
338 m_Cells(k,0) = faces[3*k];
339 m_Cells(k,1) = faces[3*k+1];
340 m_Cells(k,2) = faces[3*k+2];
344 template <
typename TElement>
349 Superclass::PrintSelf(os,indent);
350 os << indent <<
"tessellation order = " << m_Order << std::endl;
void PrintSelf(std::ostream &os, Indent indent) const ITK_OVERRIDE
virtual ~SphereTessellator()
int SearchMidpoint(int index_start, int index_end)