gVirtualXRay  2.0.10
VirtualX-RayImagingLibraryonGPU
CuboidMesh.inl
Go to the documentation of this file.
1 /*
2 
3 Copyright (c) 2023, 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> CuboidMesh<T>::CuboidMesh(double aWidth,
72  double aHeight,
73  double aDepth,
74  int anIndexDataType):
75 //------------------------------------------------------------------
76  PolygonMesh()
77 //------------------------------------------------------------------
78 {
79  create(aWidth, aHeight, aDepth, anIndexDataType);
80 }
81 
82 
83 //------------------------------------------------------------------
84 template<typename T> void CuboidMesh<T>::create(double aWidth,
85  double aHeight,
86  double aDepth,
87  int anIndexDataType)
88 //------------------------------------------------------------------
89 {
90  // Reset the mesh
91  reset();
92  m_external_data_flag = false;
93 
94  // Cache the half lengths
95  double half_width(aWidth / 2.0);
96  double half_height(aHeight / 2.0);
97  double half_depth(aDepth / 2.0);
98 
99  m_local_min_corner = VEC3(-half_width, -half_height, -half_depth);
100  m_local_max_corner = VEC3( half_width, half_height, half_depth);
101 
102  // Find the 8 corners
103 
104  // Top
105  VEC3 top_far_left( -half_width, half_height, -half_depth);
106  VEC3 top_near_left( -half_width, half_height, half_depth);
107  VEC3 top_far_right( half_width, half_height, -half_depth);
108  VEC3 top_near_right( half_width, half_height, half_depth);
109 
110  // Bottom
111  VEC3 bottom_far_left( top_far_left.getX(), -top_far_left.getY(), top_far_left.getZ());
112  VEC3 bottom_near_left( top_near_left.getX(), -top_near_left.getY(), top_near_left.getZ());
113  VEC3 bottom_far_right( top_far_right.getX(), -top_far_right.getY(), top_far_right.getZ());
114  VEC3 bottom_near_right(top_near_right.getX(), -top_near_right.getY(), top_near_right.getZ());
115 
116  // Store vertices, normal vectors and indices
117  std::vector<T> p_vertex_set;
118  std::vector<T> p_normal_set;
119  std::vector<unsigned char> p_ubyte_index_set;
120 
121  // Vertices
122  p_vertex_set.push_back(top_far_left.getX());
123  p_vertex_set.push_back(top_far_left.getY());
124  p_vertex_set.push_back(top_far_left.getZ());
125 
126  p_vertex_set.push_back(top_near_left.getX());
127  p_vertex_set.push_back(top_near_left.getY());
128  p_vertex_set.push_back(top_near_left.getZ());
129 
130  p_vertex_set.push_back(top_far_right.getX());
131  p_vertex_set.push_back(top_far_right.getY());
132  p_vertex_set.push_back(top_far_right.getZ());
133 
134  p_vertex_set.push_back(top_near_right.getX());
135  p_vertex_set.push_back(top_near_right.getY());
136  p_vertex_set.push_back(top_near_right.getZ());
137 
138  p_vertex_set.push_back(bottom_far_left.getX());
139  p_vertex_set.push_back(bottom_far_left.getY());
140  p_vertex_set.push_back(bottom_far_left.getZ());
141 
142  p_vertex_set.push_back(bottom_near_left.getX());
143  p_vertex_set.push_back(bottom_near_left.getY());
144  p_vertex_set.push_back(bottom_near_left.getZ());
145 
146  p_vertex_set.push_back(bottom_far_right.getX());
147  p_vertex_set.push_back(bottom_far_right.getY());
148  p_vertex_set.push_back(bottom_far_right.getZ());
149 
150  p_vertex_set.push_back(bottom_near_right.getX());
151  p_vertex_set.push_back(bottom_near_right.getY());
152  p_vertex_set.push_back(bottom_near_right.getZ());
153 
154  // Indices and normal vectors
155 
156  // Top face
157  p_ubyte_index_set.push_back(1);
158  p_ubyte_index_set.push_back(2);
159  p_ubyte_index_set.push_back(0);
160 
161  p_ubyte_index_set.push_back(2);
162  p_ubyte_index_set.push_back(1);
163  p_ubyte_index_set.push_back(3);
164 
165  for (unsigned int i = 0; i < 2; ++i)
166  {
167  p_normal_set.push_back(0);
168  p_normal_set.push_back(1);
169  p_normal_set.push_back(0);
170  }
171 
172  // Bottom face
173  p_ubyte_index_set.push_back(6);
174  p_ubyte_index_set.push_back(5);
175  p_ubyte_index_set.push_back(4);
176 
177  p_ubyte_index_set.push_back(5);
178  p_ubyte_index_set.push_back(6);
179  p_ubyte_index_set.push_back(7);
180 
181  for (unsigned int i = 0; i < 2; ++i)
182  {
183  p_normal_set.push_back(0);
184  p_normal_set.push_back(-1);
185  p_normal_set.push_back(0);
186  }
187 
188  // Front face
189  p_ubyte_index_set.push_back(5);
190  p_ubyte_index_set.push_back(3);
191  p_ubyte_index_set.push_back(1);
192 
193  p_ubyte_index_set.push_back(3);
194  p_ubyte_index_set.push_back(5);
195  p_ubyte_index_set.push_back(7);
196 
197  for (unsigned int i = 0; i < 2; ++i)
198  {
199  p_normal_set.push_back(0);
200  p_normal_set.push_back(0);
201  p_normal_set.push_back(1);
202  }
203 
204  // Back face
205  p_ubyte_index_set.push_back(2);
206  p_ubyte_index_set.push_back(4);
207  p_ubyte_index_set.push_back(0);
208 
209  p_ubyte_index_set.push_back(4);
210  p_ubyte_index_set.push_back(2);
211  p_ubyte_index_set.push_back(6);
212 
213  for (unsigned int i = 0; i < 2; ++i)
214  {
215  p_normal_set.push_back(0);
216  p_normal_set.push_back(0);
217  p_normal_set.push_back(-1);
218  }
219 
220  // Left face
221  p_ubyte_index_set.push_back(5);
222  p_ubyte_index_set.push_back(0);
223  p_ubyte_index_set.push_back(4);
224 
225  p_ubyte_index_set.push_back(0);
226  p_ubyte_index_set.push_back(5);
227  p_ubyte_index_set.push_back(1);
228 
229  for (unsigned int i = 0; i < 2; ++i)
230  {
231  p_normal_set.push_back(-1);
232  p_normal_set.push_back(0);
233  p_normal_set.push_back(0);
234  }
235 
236  // Right face
237  p_ubyte_index_set.push_back(2);
238  p_ubyte_index_set.push_back(7);
239  p_ubyte_index_set.push_back(6);
240 
241  p_ubyte_index_set.push_back(7);
242  p_ubyte_index_set.push_back(2);
243  p_ubyte_index_set.push_back(3);
244 
245  for (unsigned int i = 0; i < 2; ++i)
246  {
247  p_normal_set.push_back(1);
248  p_normal_set.push_back(0);
249  p_normal_set.push_back(0);
250  }
251 
252  if (anIndexDataType)
253  {
254  // Use vertex normals
255  std::vector<T> p_normal_set2;
256 
257  for (unsigned int vertex_id = 0; vertex_id < p_vertex_set.size() / 3; ++vertex_id)
258  {
259  double x = 0;
260  double y = 0;
261  double z = 0;
262 
263  unsigned int counter = 0;
264 
265  for (unsigned int face_id = 0; face_id < p_ubyte_index_set.size() / 3; ++face_id)
266  {
267  if (p_ubyte_index_set[face_id * 3] == vertex_id ||
268  p_ubyte_index_set[face_id * 3 + 1] == vertex_id ||
269  p_ubyte_index_set[face_id * 3 + 2] == vertex_id)
270  {
271  counter++;
272  x += p_normal_set[face_id * 3];
273  y += p_normal_set[face_id * 3 + 1];
274  z += p_normal_set[face_id * 3 + 2];
275  }
276  }
277 
278  if (counter > 0)
279  {
280  x /= counter;
281  y /= counter;
282  z /= counter;
283  }
284 
285  p_normal_set2.push_back(x);
286  p_normal_set2.push_back(y);
287  p_normal_set2.push_back(z);
288  }
289 
290  switch (anIndexDataType)
291  {
292  case GL_UNSIGNED_INT:
293  {
294  std::vector<GLuint> p_uint_index_set;
295 
296  for (std::vector<GLubyte>::const_iterator ite(p_ubyte_index_set.begin());
297  ite != p_ubyte_index_set.end();
298  ++ite)
299  {
300  p_uint_index_set.push_back(*ite);
301  }
302 
303  setInternalData(GL_TRIANGLES,
304  &p_vertex_set,
305  &p_normal_set2,
306  &p_uint_index_set,
307  false,
308  GL_STATIC_DRAW);
309  }
310  break;
311 
312  case GL_UNSIGNED_SHORT:
313  {
314  std::vector<GLushort> p_ushort_index_set;
315 
316  for (std::vector<GLubyte>::const_iterator ite(p_ubyte_index_set.begin());
317  ite != p_ubyte_index_set.end();
318  ++ite)
319  {
320  p_ushort_index_set.push_back(*ite);
321  }
322 
323  setInternalData(GL_TRIANGLES,
324  &p_vertex_set,
325  &p_normal_set2,
326  &p_ushort_index_set,
327  false,
328  GL_STATIC_DRAW);
329  }
330  break;
331 
332  case GL_UNSIGNED_BYTE:
333  {
334  setInternalData(GL_TRIANGLES,
335  &p_vertex_set,
336  &p_normal_set2,
337  &p_ubyte_index_set,
338  false,
339  GL_STATIC_DRAW);
340  }
341  break;
342 
343  default:
344  throw Exception(__FILE__, __FUNCTION__, __LINE__,
345  "Invalid data type.");
346  }
347  }
348  // Don't use an index
349  else
350  {
351  std::vector<T> p_vertex_set2;
352  std::vector<T> p_normal_set2;
353 
354  int normal_id = 0;
355  for (std::vector<unsigned char>::const_iterator ite = p_ubyte_index_set.begin();
356  ite != p_ubyte_index_set.end();
357  ++ite, ++normal_id)
358  {
359  p_vertex_set2.push_back(p_vertex_set[*ite * 3 + 0]);
360  p_vertex_set2.push_back(p_vertex_set[*ite * 3 + 1]);
361  p_vertex_set2.push_back(p_vertex_set[*ite * 3 + 2]);
362 
363  p_normal_set2.push_back(p_normal_set[3 * (normal_id / 3) + 0]);
364  p_normal_set2.push_back(p_normal_set[3 * (normal_id / 3) + 1]);
365  p_normal_set2.push_back(p_normal_set[3 * (normal_id / 3) + 2]);
366  }
367 
368  setInternalData(GL_TRIANGLES,
369  &p_vertex_set2,
370  &p_normal_set2,
371  false,
372  GL_STATIC_DRAW);
373  }
374 }
375 
376 } // namespace gVirtualXRay
CuboidMesh(double aWidth=1.0 *cm, double aHeight=1.0 *cm, double aDepth=1.0 *cm, int anIndexDataType=0)
Default constructor.
Definition: CuboidMesh.inl:71
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
void create(double aWidth=1.0 *cm, double aHeight=1.0 *cm, double aDepth=1.0 *cm, int anIndexDataType=0)
Create a new cuboid.
Definition: CuboidMesh.inl:84
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