Fermat
MeshBase.h
1 /*
2  * Fermat
3  *
4  * Copyright (c) 2008-2019, NVIDIA CORPORATION. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the NVIDIA CORPORATION nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #pragma once
30 
31 #include "MeshException.h"
32 
33 #include <string>
34 #include <map>
35 #include <vector>
36 
37 static const int MESH_ATTRIBUTE_NOT_PROVIDED = -1;
38 
39 
40 /* --------------------------------------------------------------------------------
41  * Materials
42  */
43 
44 // TODO: Revise these in an sutil-centric way, rather than a .obj-centric way
45 /* Mimics the shading type enum found in GLM for obj shading types */
46 enum {
47  MESH_SHADING_NONE = (0),
48  MESH_SHADING_FLAT = (1 << 0),
49  MESH_SHADING_SMOOTH = (1 << 1),
50  MESH_SHADING_TEXTURE = (1 << 2),
51  MESH_SHADING_COLOR = (1 << 3),
52  MESH_SHADING_MATERIAL = (1 << 4),
53  MESH_SHADING_FLAT_SHADE = (1 << 5),
54  MESH_SHADING_SPECULAR_SHADE = (1 << 6)
55 };
56 
57 class SUTILCLASSAPI MeshTextureMap {
58 public:
59 
60  SUTILAPI MeshTextureMap() { }
61  SUTILAPI ~MeshTextureMap() { } // So the CRT deletes it on the correct heap
62 
63  std::string name;
64  float scaling[2];
65 };
66 
67 class SUTILCLASSAPI MeshMaterialParams {
68 public:
69 
70  SUTILAPI MeshMaterialParams() { setToDefaultParams(); }
71  SUTILAPI ~MeshMaterialParams() { } // To ensure it's del'ed on the correct heap
72 
73  SUTILAPI void setToDefaultParams();
74 
75  std::string name;
76 
77  float diffuse[4];
78  float diffuse_trans[4];
79  float ambient[4];
80  float specular[4];
81  float emissive[4];
82  float phong_exponent;
83  float index_of_refraction;
84  float opacity;
85  float reflectivity[4];
86 
87  int flags;
88  int shading_type;
89 
90  /* Texture maps */
91  MeshTextureMap ambient_map;
92  MeshTextureMap diffuse_map;
93  MeshTextureMap diffuse_trans_map;
94  MeshTextureMap specular_map;
95  MeshTextureMap emissive_map;
96  MeshTextureMap opacity_map;
97  MeshTextureMap bump_map;
98 };
99 
100 typedef std::map<std::string, int> MeshMaterialNumbersMap;
101 
102 
103 /* --------------------------------------------------------------------------------
104  * Groups
105  */
106 class SUTILCLASSAPI MeshGroup {
107 public:
108 
109  SUTILAPI MeshGroup() :
110  num_triangles( 0 ),
111  vertex_indices( 0 ),
112  normal_indices( 0 ),
113  color_indices( 0 ),
114  texture_coordinate_indices( 0 ),
115  material_indices( 0 ),
116  material_number( 0 )
117  { }
118 
119  SUTILAPI ~MeshGroup() { } // So the CRT deletes it on the correct heap
120 
121  std::string name;
122 
123  int num_triangles;
124 
125  int* vertex_indices;
126  int* normal_indices;
127  int* color_indices;
128  int* texture_coordinate_indices;
129  int* material_indices;
130 
131  int material_number;
132 };
133 
134 typedef std::map<std::string, MeshGroup> MeshGroupMap;
135 
136 enum MeshGrouping {
137  kMergeGroups = 0,
138  kKeepGroups = 1,
139  kKeepSubgroups = 2,
140 };
141 
142 /* --------------------------------------------------------------------------------
143  * MeshBase abstract class.
144  *
145  * Implements common functionality for concrete Mesh classes, and provides
146  * interface for methods that all Meshes should implement.
147  */
148 class MeshBase {
149 public:
150 
151  MeshBase();
152 
153  // This destructor handles no de-allocation of itself, since resource
154  // allocation is delegated to subclasses
155  virtual ~MeshBase();
156 
201  virtual void loadModel( const std::string& filename, bool insertDefaultMaterial = true, const MeshMaterialParams& defaultMaterial = MeshMaterialParams() );
202 
207  template <class Functor>
208  void forEachGroup( Functor functor ) const;
209 
210  template <class Functor>
211  void forEachGroup( Functor functor );
212 
213  int getNumVertices() const { return m_num_vertices; }
214  int getNumNormals() const { return m_num_normals; }
215  int getNumColors() const { return m_num_colors; }
216  int getNumTextureCoordinates() const { return m_num_texture_coordinates; }
217 
218  int getNumTriangles() const { return m_num_triangles; }
219  int getNumGroups() const { return (int)m_mesh_groups.size(); }
220 
221  float* getVertexData() { return m_vertex_data; }
222  const float* getVertexData() const { return m_vertex_data; }
223 
224  float* getNormalData() { return m_normal_data; }
225  const float* getNormalData() const { return m_normal_data; }
226 
227  unsigned char* getColorData() { return m_color_data; }
228  const unsigned char* getColorData() const { return m_color_data; }
229 
230  float* getTextureCoordinateData() { return m_texture_coordinate_data; }
231  const float* getTextureCoordinateData() const { return m_texture_coordinate_data; }
232 
233  int getVertexStride() const { return m_vertex_stride; }
234  int getNormalStride() const { return m_normal_stride; }
235  int getColorStride() const { return m_color_stride; }
236  int getTextureCoordinateStride() const { return m_texture_coordinate_stride; }
237 
238  const float* getBBoxMin() const { return m_bbox_min; }
239  const float* getBBoxMax() const { return m_bbox_max; }
240 
241  void updateBBox();
242 
243  const std::string& getMaterialLibraryName() const { return m_material_library_name; }
244 
245  MeshGroup& getMeshGroup(const std::string& group_name) {
246  MeshGroupMap::iterator found = m_mesh_groups.find(group_name);
247  if( found != m_mesh_groups.end() ) {
248  return found->second;
249  }
250  else {
251  throw MeshException( "Could not find group named '" + group_name + "'" );
252  }
253  }
254 
255  const MeshGroup& getMeshGroup(const std::string& group_name) const {
256  MeshGroupMap::const_iterator found = m_mesh_groups.find(group_name);
257  if( found != m_mesh_groups.end() ) {
258  return found->second;
259  }
260  else {
261  throw MeshException( "Could not find group named '" + group_name + "'" );
262  }
263  }
264 
265  size_t getMaterialCount() const { return m_material_params.size(); }
266 
267  void setMeshMaterialParams( int i, const MeshMaterialParams& params ) {
268  m_material_params[i] = params;
269  }
270 
271  MeshMaterialParams& getMeshMaterialParams( int i ) {
272  return m_material_params[i];
273  }
274 
275  const MeshMaterialParams& getMeshMaterialParams( int i ) const
276  {
277  return m_material_params[i];
278  }
279 
280  void setMeshGrouping(MeshGrouping grouping) { m_grouping = grouping; }
281  MeshGrouping getMeshGrouping() const { return m_grouping; }
282 
283 
284  /*--------------------------------------------------------------------------------
285  * Load functions
286  */
287  void loadFromObj( const std::string& filename, bool insertDefaultMaterial, const MeshMaterialParams& defaultMaterial );
288 
292  void loadMaterials( const std::string& material_filename );
293 
297  void loadFromPly( const std::string& filename, bool insertDefaultMaterial, const MeshMaterialParams& defaultMaterial );
298 
299 protected:
300 
304  void setVertexData( float* vertex_data ) { m_vertex_data = vertex_data; }
305  void setNormalData( float* normal_data ) { m_normal_data = normal_data; }
306  void setColorData( unsigned char* color_data ) { m_color_data = color_data; }
307  void setTextureCoordinateData( float* texture_coordinate_data ) { m_texture_coordinate_data = texture_coordinate_data; }
308  void setMaterialIndices(int* material_indices) { m_material_indices = material_indices; }
309 
310  void setVertexStride( int vertex_stride ) { m_vertex_stride = vertex_stride; }
311  void setNormalStride( int normal_stride ) { m_normal_stride = normal_stride; }
312  void setColorStride( int color_stride ) { m_color_stride = color_stride; }
313  void setTextureCoordinateStride( int texture_coordinate_stride ) { m_texture_coordinate_stride = texture_coordinate_stride; }
314 
315  void setVertexIndexStride( int index_stride ) { m_vertex_index_stride = index_stride; }
316  void setNormalIndexStride( int index_stride ) { m_normal_index_stride = index_stride; }
317  void setColorIndexStride( int index_stride ) { m_color_index_stride = index_stride; }
318  void setTextureIndexStride( int index_stride ) { m_texture_index_stride = index_stride; }
319 
320  const std::string& getFilename() const { return m_filename; }
321  const std::string& getPathName() const { return m_pathname; }
322 
328  //virtual int addMaterial(MeshMaterialParams& params) = 0;
329 
330  virtual int getVertexTriangleSize() const = 0;
331  virtual int getNormalTriangleSize() const = 0;
332  virtual int getTextureTriangleSize() const = 0;
333 
338  virtual void preProcess() = 0;
339 
345  virtual void allocateData() = 0;
346 
354  virtual void startWritingData() = 0;
355 
359  virtual void postProcess() = 0;
360 
364  virtual void finishWritingData() = 0;
365 
366  /* --------------------------------------------------------------------------------
367  * Utility functions
368  */
369  void computeAabb();
370 
371 private:
372  /*--------------------------------------------------------------------------------
373  * Load functions
374  */
375 
381  void loadInfoFromObj( const std::string& filename, bool insertDefaultMaterial, const MeshMaterialParams& defaultMaterial );
382 
390  void loadDataFromObj( const std::string& filename, bool insertDefaultMaterial, const MeshMaterialParams& defaultMaterial );
391 
395  void loadInfoFromPly( const std::string& filename, bool insertDefaultMaterial );
396 
400  void loadDataFromPly( const std::string& filename );
401 
402  // For loaders that only use a single group, initializes m_mesh_groups with that
403  // one group.
404  void initSingleGroup();
405 
406  // Return a reference to the first group found in m_mesh_groups; mostly useful for
407  // loaders that only use a single group. Throws if m_mesh_groups is empty.
408  MeshGroup& getFirstGroup();
409 
414  MeshGroup& getOrAddGroup( const std::string& name );
415 
416  std::string m_filename;
417  std::string m_pathname;
418 
419  int m_num_vertices;
420  int m_num_normals;
421  int m_num_colors;
422  int m_num_texture_coordinates;
423 
424  /* If any of these are 0, then load() won't bother write to the
425  * array for that attribute, and it won't write indices for that attribute in
426  * any of the groups.
427  *
428  * It is up to sub classes to implement their own logic for whether data are
429  * allocated or not.
430  */
431  float* m_vertex_data;
432  float* m_normal_data;
433  unsigned char* m_color_data;
434  float* m_texture_coordinate_data;
435  int* m_material_indices;
436 
437  /* Measured in 'floats'. 0 indicates compacted data, equivalent to '2' for
438  * texture_coordinates and '3' for the others.
439  */
440  int m_vertex_stride;
441  int m_normal_stride;
442  int m_color_stride;
443  int m_texture_coordinate_stride;
444 
445  /* Measured in 'ints' per triangle. 0 indicates compacted data, equivalent to '3'.
446  */
447  int m_vertex_index_stride;
448  int m_normal_index_stride;
449  int m_color_index_stride;
450  int m_texture_index_stride;
451 
452  int m_num_triangles;
453 
454  MeshGrouping m_grouping;
455  MeshGroupMap m_mesh_groups;
456  MeshMaterialNumbersMap m_material_numbers_by_name; // TODO: replace these two lines with a map from name to material parameters
457  std::vector<MeshMaterialParams> m_material_params;
458 
459  std::string m_material_library_name;
460 
461  float m_bbox_min[3];
462  float m_bbox_max[3];
463 };
464 
465 
466 template <class Functor>
467 void MeshBase::forEachGroup( Functor functor ) const
468 {
469  MeshGroupMap::const_iterator groups_end = m_mesh_groups.end();
470  for( MeshGroupMap::const_iterator groups_iter = m_mesh_groups.begin();
471  groups_iter != groups_end; )
472  {
473  functor( (groups_iter++)->second );
474  // The post-increment ++ ensures the iterator is updated before functor()
475  // runs, since functor may invalidate the iterator
476  }
477 }
478 
479 template <class Functor>
480 void MeshBase::forEachGroup( Functor functor )
481 {
482  MeshGroupMap::iterator groups_end = m_mesh_groups.end();
483  for( MeshGroupMap::iterator groups_iter = m_mesh_groups.begin();
484  groups_iter != groups_end; )
485  {
486  functor( (groups_iter++)->second );
487  // The post-increment ++ ensures the iterator is updated before functor()
488  // runs, since functor may invalidate the iterator
489  }
490 }
Definition: MeshBase.h:57
void forEachGroup(Functor functor) const
Definition: MeshBase.h:467
Definition: MeshException.h:38
Definition: MeshBase.h:106
void setVertexData(float *vertex_data)
Definition: MeshBase.h:304
Definition: MeshBase.h:148
Definition: MeshBase.h:67