gVirtualXRay  2.0.10
VirtualX-RayImagingLibraryonGPU
CubeMesh.inl
Go to the documentation of this file.
1 /*
2 
3 Copyright (c) 2014, Dr Franck P. Vidal (franck.p.vidal@fpvidal.net),
4 http://www.fpvidal.net/
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation and/or
15 other materials provided with the distribution.
16 
17 3. Neither the name of the Bangor University nor the names of its contributors
18 may be used to endorse or promote products derived from this software without
19 specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 
32 */
33 
34 
64 //******************************************************************************
65 // namespace
66 //******************************************************************************
67 namespace gVirtualXRay {
68 
69 
70 //-------------------------------------------------------------
71 template<typename T> CubeMesh<T>::CubeMesh(double aLength,
72  int anIndexDataType):
73 //-------------------------------------------------------------
74  PolygonMesh()
75 //-------------------------------------------------------------
76 {
77  create(aLength, anIndexDataType);
78 }
79 
80 
81 //----------------------------------------------------------------
82 template<typename T> void CubeMesh<T>::create(double aLength,
83  int anIndexDataType)
84 //----------------------------------------------------------------
85 {
86  // Reset the mesh
87  reset();
88  m_external_data_flag = false;
89 
90  // Cache the half length
91  double half_length(aLength / 2.0);
92 
93  m_local_min_corner = VEC3(-half_length, -half_length, -half_length);
94  m_local_max_corner = VEC3( half_length, half_length, half_length);
95 
96  // Find the 8 corners
97 
98  // Top
99  VEC3 top_far_left( -half_length, half_length, -half_length);
100  VEC3 top_near_left( -half_length, half_length, half_length);
101  VEC3 top_far_right( half_length, half_length, -half_length);
102  VEC3 top_near_right( half_length, half_length, half_length);
103 
104  // Bottom
105  VEC3 bottom_far_left( top_far_left.getX(), -top_far_left.getY(), top_far_left.getZ());
106  VEC3 bottom_near_left( top_near_left.getX(), -top_near_left.getY(), top_near_left.getZ());
107  VEC3 bottom_far_right( top_far_right.getX(), -top_far_right.getY(), top_far_right.getZ());
108  VEC3 bottom_near_right(top_near_right.getX(), -top_near_right.getY(), top_near_right.getZ());
109 
110  // Store vertices, normal vectors and indices
111  std::vector<T> p_vertex_set;
112  std::vector<T> p_normal_set;
113  std::vector<unsigned char> p_ubyte_index_set;
114 
115  // Vertices
116  p_vertex_set.push_back(top_far_left.getX());
117  p_vertex_set.push_back(top_far_left.getY());
118  p_vertex_set.push_back(top_far_left.getZ());
119 
120  p_vertex_set.push_back(top_near_left.getX());
121  p_vertex_set.push_back(top_near_left.getY());
122  p_vertex_set.push_back(top_near_left.getZ());
123 
124  p_vertex_set.push_back(top_far_right.getX());
125  p_vertex_set.push_back(top_far_right.getY());
126  p_vertex_set.push_back(top_far_right.getZ());
127 
128  p_vertex_set.push_back(top_near_right.getX());
129  p_vertex_set.push_back(top_near_right.getY());
130  p_vertex_set.push_back(top_near_right.getZ());
131 
132  p_vertex_set.push_back(bottom_far_left.getX());
133  p_vertex_set.push_back(bottom_far_left.getY());
134  p_vertex_set.push_back(bottom_far_left.getZ());
135 
136  p_vertex_set.push_back(bottom_near_left.getX());
137  p_vertex_set.push_back(bottom_near_left.getY());
138  p_vertex_set.push_back(bottom_near_left.getZ());
139 
140  p_vertex_set.push_back(bottom_far_right.getX());
141  p_vertex_set.push_back(bottom_far_right.getY());
142  p_vertex_set.push_back(bottom_far_right.getZ());
143 
144  p_vertex_set.push_back(bottom_near_right.getX());
145  p_vertex_set.push_back(bottom_near_right.getY());
146  p_vertex_set.push_back(bottom_near_right.getZ());
147 
148  // Indices and normal vectors
149 
150  // Top face
151  p_ubyte_index_set.push_back(1);
152  p_ubyte_index_set.push_back(2);
153  p_ubyte_index_set.push_back(0);
154 
155  p_ubyte_index_set.push_back(2);
156  p_ubyte_index_set.push_back(1);
157  p_ubyte_index_set.push_back(3);
158 
159  for (unsigned int i = 0; i < 2; ++i)
160  {
161  p_normal_set.push_back(0);
162  p_normal_set.push_back(1);
163  p_normal_set.push_back(0);
164  }
165 
166  // Bottom face
167  p_ubyte_index_set.push_back(6);
168  p_ubyte_index_set.push_back(5);
169  p_ubyte_index_set.push_back(4);
170 
171  p_ubyte_index_set.push_back(5);
172  p_ubyte_index_set.push_back(6);
173  p_ubyte_index_set.push_back(7);
174 
175  for (unsigned int i = 0; i < 2; ++i)
176  {
177  p_normal_set.push_back(0);
178  p_normal_set.push_back(-1);
179  p_normal_set.push_back(0);
180  }
181 
182  // Front face
183  p_ubyte_index_set.push_back(5);
184  p_ubyte_index_set.push_back(3);
185  p_ubyte_index_set.push_back(1);
186 
187  p_ubyte_index_set.push_back(3);
188  p_ubyte_index_set.push_back(5);
189  p_ubyte_index_set.push_back(7);
190 
191  for (unsigned int i = 0; i < 2; ++i)
192  {
193  p_normal_set.push_back(0);
194  p_normal_set.push_back(0);
195  p_normal_set.push_back(1);
196  }
197 
198  // Back face
199  p_ubyte_index_set.push_back(2);
200  p_ubyte_index_set.push_back(4);
201  p_ubyte_index_set.push_back(0);
202 
203  p_ubyte_index_set.push_back(4);
204  p_ubyte_index_set.push_back(2);
205  p_ubyte_index_set.push_back(6);
206 
207  for (unsigned int i = 0; i < 2; ++i)
208  {
209  p_normal_set.push_back(0);
210  p_normal_set.push_back(0);
211  p_normal_set.push_back(-1);
212  }
213 
214  // Left face
215  p_ubyte_index_set.push_back(5);
216  p_ubyte_index_set.push_back(0);
217  p_ubyte_index_set.push_back(4);
218 
219  p_ubyte_index_set.push_back(0);
220  p_ubyte_index_set.push_back(5);
221  p_ubyte_index_set.push_back(1);
222 
223  for (unsigned int i = 0; i < 2; ++i)
224  {
225  p_normal_set.push_back(-1);
226  p_normal_set.push_back(0);
227  p_normal_set.push_back(0);
228  }
229 
230  // Right face
231  p_ubyte_index_set.push_back(2);
232  p_ubyte_index_set.push_back(7);
233  p_ubyte_index_set.push_back(6);
234 
235  p_ubyte_index_set.push_back(7);
236  p_ubyte_index_set.push_back(2);
237  p_ubyte_index_set.push_back(3);
238 
239  for (unsigned int i = 0; i < 2; ++i)
240  {
241  p_normal_set.push_back(1);
242  p_normal_set.push_back(0);
243  p_normal_set.push_back(0);
244  }
245 
246  if (anIndexDataType)
247  {
248  // Use vertex normals
249  std::vector<T> p_normal_set2;
250 
251  for (unsigned int vertex_id = 0; vertex_id < p_vertex_set.size() / 3; ++vertex_id)
252  {
253  double x = 0;
254  double y = 0;
255  double z = 0;
256 
257  unsigned int counter = 0;
258 
259  for (unsigned int face_id = 0; face_id < p_ubyte_index_set.size() / 3; ++face_id)
260  {
261  if (p_ubyte_index_set[face_id * 3] == vertex_id ||
262  p_ubyte_index_set[face_id * 3 + 1] == vertex_id ||
263  p_ubyte_index_set[face_id * 3 + 2] == vertex_id)
264  {
265  counter++;
266  x += p_normal_set[face_id * 3];
267  y += p_normal_set[face_id * 3 + 1];
268  z += p_normal_set[face_id * 3 + 2];
269  }
270  }
271 
272  if (counter > 0)
273  {
274  x /= counter;
275  y /= counter;
276  z /= counter;
277  }
278 
279  p_normal_set2.push_back(x);
280  p_normal_set2.push_back(y);
281  p_normal_set2.push_back(z);
282  }
283 
284  switch (anIndexDataType)
285  {
286  case GL_UNSIGNED_INT:
287  {
288  std::vector<GLuint> p_uint_index_set;
289 
290  for (std::vector<GLubyte>::const_iterator ite(p_ubyte_index_set.begin());
291  ite != p_ubyte_index_set.end();
292  ++ite)
293  {
294  p_uint_index_set.push_back(*ite);
295  }
296 
297  setInternalData(GL_TRIANGLES,
298  &p_vertex_set,
299  &p_normal_set2,
300  &p_uint_index_set,
301  false,
302  GL_STATIC_DRAW);
303  }
304  break;
305 
306  case GL_UNSIGNED_SHORT:
307  {
308  std::vector<GLushort> p_ushort_index_set;
309 
310  for (std::vector<GLubyte>::const_iterator ite(p_ubyte_index_set.begin());
311  ite != p_ubyte_index_set.end();
312  ++ite)
313  {
314  p_ushort_index_set.push_back(*ite);
315  }
316 
317  setInternalData(GL_TRIANGLES,
318  &p_vertex_set,
319  &p_normal_set2,
320  &p_ushort_index_set,
321  false,
322  GL_STATIC_DRAW);
323  }
324  break;
325 
326  case GL_UNSIGNED_BYTE:
327  {
328  setInternalData(GL_TRIANGLES,
329  &p_vertex_set,
330  &p_normal_set2,
331  &p_ubyte_index_set,
332  false,
333  GL_STATIC_DRAW);
334  }
335  break;
336 
337  default:
338  throw Exception(__FILE__, __FUNCTION__, __LINE__,
339  "Invalid data type.");
340  }
341  }
342  // Don't use an index
343  else
344  {
345  std::vector<T> p_vertex_set2;
346  std::vector<T> p_normal_set2;
347 
348  int normal_id = 0;
349  for (std::vector<unsigned char>::const_iterator ite = p_ubyte_index_set.begin();
350  ite != p_ubyte_index_set.end();
351  ++ite, ++normal_id)
352  {
353  p_vertex_set2.push_back(p_vertex_set[*ite * 3 + 0]);
354  p_vertex_set2.push_back(p_vertex_set[*ite * 3 + 1]);
355  p_vertex_set2.push_back(p_vertex_set[*ite * 3 + 2]);
356 
357  p_normal_set2.push_back(p_normal_set[3 * (normal_id / 3) + 0]);
358  p_normal_set2.push_back(p_normal_set[3 * (normal_id / 3) + 1]);
359  p_normal_set2.push_back(p_normal_set[3 * (normal_id / 3) + 2]);
360  }
361 
362  setInternalData(GL_TRIANGLES,
363  &p_vertex_set2,
364  &p_normal_set2,
365  false,
366  GL_STATIC_DRAW);
367  }
368 }
369 
370 } // namespace gVirtualXRay
T getX() const
Accessor on the position along the x-axis.
Definition: Vec3.inl:115
T getZ() const
Accessor on the position along the z-axis.
Definition: Vec3.inl:131
Exception is a class to handle exceptions.
Definition: Exception.h:109
T getY() const
Accessor on the position along the y-axis.
Definition: Vec3.inl:123
CubeMesh is a class to handle 3D meshes of cubes.
Definition: CubeMesh.h:95
PolygonMesh is a class to handle polygon (triangles) meshes.
Definition: PolygonMesh.h:114
Vec3< RATIONAL_NUMBER > VEC3
Type of data used to store 3D vectors.
Definition: Types.h:115
CubeMesh(double aLength=1.0 *cm, int anIndexDataType=0)
Default constructor.
Definition: CubeMesh.inl:71