HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_PrimPolygonMesh.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GT_PrimPolygonMesh.h ( GT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GT_PrimPolygonMesh__
12 #define __GT_PrimPolygonMesh__
13 
14 #include "GT_API.h"
15 #include "GT_Primitive.h"
16 #include "GT_CountArray.h"
17 #include "GT_FaceSetMap.h"
18 #include <GA/GA_Names.h>
19 
20 class GT_DataArray;
21 class GT_PrimPolygon;
22 class GT_AttributeList;
23 class GT_AttributeMerge;
24 class UT_StringRef;
25 
26 /// Note this is all just copied from GEO_Normal
27 #define GT_DEFAULT_CUSP_ANGLE 60.0
28 
29 /// Magic tolerance factor of 1.001 on GT_DEFAULT_CUSP_ANGLE so that
30 /// hexagonal tubes will be smooth by default, even with a bit of roundoff
31 /// or slight deformation.
32 #define GT_DEFAULT_ADJUSTED_CUSP_ANGLE 60.06
33 
34 /// @brief A mesh of polygons
36 {
37 public:
38  /// Default constructor
40  : myVMerge(NULL)
41  , myUMerge(NULL)
42  , myConvexFlag(false)
43  {
44  }
45  /// Useful constructor
47  const GT_DataArrayHandle &vtx_indices,
48  const GT_AttributeListHandle &shared,
49  const GT_AttributeListHandle &vertex,
50  const GT_AttributeListHandle &uniform,
51  const GT_AttributeListHandle &detail,
53  GT_Size min_vertex_count=0,
54  GT_Size max_vertex_count=0)
55  : myVMerge(NULL)
56  , myUMerge(NULL)
57  , myConvexFlag(false)
58  {
59  init(vtx_counts, vtx_indices, shared, vertex, uniform, detail,
60  indexing, min_vertex_count, max_vertex_count);
61  }
62 
63  GT_PrimPolygonMesh(const GT_CountArray &vtx_counts,
64  const GT_DataArrayHandle &vtx_indices,
65  const GT_AttributeListHandle &shared,
66  const GT_AttributeListHandle &vertex,
67  const GT_AttributeListHandle &uniform,
68  const GT_AttributeListHandle &detail)
69  : myVMerge(nullptr)
70  , myUMerge(nullptr)
71  , myConvexFlag(false)
72  {
73  init(vtx_counts, vtx_indices, shared, vertex, uniform, detail);
74  }
75 
76  /// Copy the topology information from the source pmesh, but use different
77  /// attribute lists.
79  const GT_AttributeListHandle &shared,
80  const GT_AttributeListHandle &vertex,
81  const GT_AttributeListHandle &uniform,
82  const GT_AttributeListHandle &detail);
83 
84  /// Create a new polygon mesh with re-mapped vertices (used by
85  /// removeUnusedPoints).
86  ///
87  /// Since the polygon faces are remapped you'll have to pass in a new face
88  /// set map.
90  const GT_DataArrayHandle &vtx_indices,
91  const GT_AttributeListHandle &shared);
92 
93  /// Copy c-tor
95 
96  /// Construct a polygon mesh from a GT_PrimPolygon
98  /// Destructor
99  ~GT_PrimPolygonMesh() override;
100 
101  const char *className() const override { return "GT_PrimPolygonMesh"; }
102  bool save(UT_JSONWriter &w) const override;
103 
104  /// @{
105  /// Methods defined on GT_Primitive
106  void enlargeBounds(UT_BoundingBox boxes[],
107  int nsegments) const override;
108  int getPrimitiveType() const override;
109  bool refine(GT_Refine &refiner,
110  const GT_RefineParms *parms) const override;
111  int getMotionSegments() const override;
112  int64 getMemoryUsage() const override;
113  /// @}
114 
115  /// @{
116  /// Initialize the mesh
117  /// - @c vtx_counts @n
118  /// An integer array, representing the number of vertices in each face.
119  /// The length of the array determines the number of faces in the mesh.
120  /// - @c vtx_indices @n
121  /// An array of vertex references. There is an entry for every vertex in
122  /// every face. These indices refer to the shared attribute data.
123  /// - @c shared @n
124  /// Shared attribute data. This data is referenced by the vertex arrays.
125  /// - @c vertex @n
126  /// Unique data per vertex. The length of these attribute arrays should
127  /// be the same as the length of the vtx_indices array.
128  /// - @c uniform @n
129  /// Attribute per face. There should be one entry for each entry in the
130  /// @c vtx_counts array.
131  /// - @c detail @n
132  /// Constant attribute for all faces.
133  /// @c vtx_counts array.
134  /// - @c indexing @n
135  /// What type of indexing is required
136  void init(const GT_DataArrayHandle &vtx_counts,
137  const GT_DataArrayHandle &vtx_indices,
138  const GT_AttributeListHandle &shared,
139  const GT_AttributeListHandle &vertex,
140  const GT_AttributeListHandle &uniform,
141  const GT_AttributeListHandle &detail,
143  GT_Size min_vertex_count=0,
144  GT_Size max_vertex_count=0);
145  void init(const GT_CountArray &vtx_counts,
146  const GT_DataArrayHandle &vtx_indices,
147  const GT_AttributeListHandle &shared,
148  const GT_AttributeListHandle &vertex,
149  const GT_AttributeListHandle &uniform,
150  const GT_AttributeListHandle &detail);
151  /// @}
152 
153  /// Return the number of faces in the mesh
154  GT_Size getFaceCount() const;
155  /// Return a pointer to the individual face
156  GT_PrimitiveHandle getFace(GT_Offset i) const;
157 
158  /// Return the number of vertices
160  {
161  return myVertexList ? myVertexList->entries() : 0;
162  }
163  /// Return the number of points
165  {
166  return myShared ? myShared->get(0)->entries() : 0;
167  }
168 
169  /// @{
170  /// Query the minimum/maximum number of vertices per face
171  GT_Size getMinVertexCount() const { return myFaceOffsets.getMinCount();}
172  GT_Size getMaxVertexCount() const { return myFaceOffsets.getMaxCount();}
173  /// @}
174 
175  /// @{
176  /// Accessor
177  const GT_DataArrayHandle &getVertexList() const override
178  { return myVertexList; }
180  { return myFaceOffsets; }
181 #if 0
182  const GT_DataArrayHandle &getFaceOffsets() const
183  { return myFaceOffsets; }
184 #endif
186  { return myShared; }
188  { return myVertex; }
190  { return myUniform; }
192  { return myDetail; }
193  /// @}
194 
195  /// @{
196  /// Access to the face sets
197  const GT_FaceSetMapPtr &faceSetMap() const { return myFaceSetMap; }
199  { myFaceSetMap = v; }
200  void addFaceSet(const UT_StringHolder &name,
201  const GT_FaceSetPtr &set);
202  /// @}
203 
204  /// Harden all attributes so there are no dangling dependencies
205  GT_PrimitiveHandle doHarden() const override;
207  { return new GT_PrimPolygonMesh(*this); }
208 
209  /// The virtual implementation of attribute merging
211  const GT_Primitive &src,
212  const UT_StringMMPattern *vertex,
213  const UT_StringMMPattern *point,
214  const UT_StringMMPattern *uniform,
215  const UT_StringMMPattern *detail
216  ) const override;
217 
218  /// @{
219  /// Access attributes
221  { return myVertex; }
223  { return myShared; }
225  { return myUniform; }
227  { return myDetail; }
228  /// @}
229 
230  /// Return the offset into the vertex list for the given face
232  { return myFaceOffsets.getOffset(face); }
233  /// Return the length of the vertex list for the given face
235  { return myFaceOffsets.getCount(face); }
236  /// For a given face, find the shared point numbers for the given vertex
237  /// and the next vertex (i.e. the edge starting from the given vertex).
238  void getEdgePoints(GT_Offset face, GT_Offset vertex,
239  GT_Offset &p0, GT_Offset &p1) const;
240 
241  /// Returns true if this mesh has been convexed
242  bool isConvexed() const { return myConvexFlag; }
243 
244  /// Set the convex flag on the mesh
245  void setConvexed(bool c) { myConvexFlag = c; }
246 
247  /// Return an array containing the face counts per-face
249  getFaceCounts(GT_IndexingMode indexing=GT_INDEXING_QUICK) const;
250 
251  /// The polygon mesh may have shared points which aren't used. That is,
252  /// there may be elements in the shared element list which aren't
253  /// referenced by any vertex. This method will build a list of indices for
254  /// all the used points.
255  ///
256  /// The list returned will be monotonically ascending.
257  const GT_DataArrayHandle
258  getUsedPointList(GT_IndexingMode idx=GT_INDEXING_QUICK) const;
259 
260  /// Ensure all polygons in the mesh are convex
261  ///
262  /// If the @c holes set is passed in, then the faces in that set will be
263  /// excluded from the convexed result.
264  GT_PrimitiveHandle convex(int max_points_per_poly=3,
265  bool keep_degenerate = false,
266  bool allow_interrupt = true,
267  bool allow_indirect_flattening = false,
268  const UT_Set<int> *holes = nullptr) const;
269 
270  /// Using the indirect arrays and vertex list from a convexed mesh,
271  /// convex this mesh (assumes topology is the same).
272  GT_PrimitiveHandle adoptConvexing(
273  const GT_DataArrayHandle &verts,
274  const GT_DataArrayHandle &uniform_indexing,
275  const GT_DataArrayHandle &vertex_indexing,
276  const GT_DataArrayHandle &vert_info,
277  const GT_DataArrayHandle &prim_info)
278  const;
279 
280  /// Fetches the convexed arrays from the mesh, to be used by adoptConvexing
281  /// on a different mesh with the same topology.
282  void getConvexArrays(
283  GT_DataArrayHandle &verts,
284  GT_DataArrayHandle &uniform_indexing,
285  GT_DataArrayHandle &vertex_indexing,
286  GT_DataArrayHandle &vert_info,
287  GT_DataArrayHandle &prim_info) const;
288 
289  /// Remove unused points. This will collapse the varying point arrays,
290  /// leaving only the points referenced by the vertices.
291  GT_PrimitiveHandle removeUnusedPoints(const int32 *idx=NULL) const;
292 
293  /// @{
294  /// Compute face normals. This will use the shared attribute named P to
295  /// compute the normals for each face.
296  /// fpreal16 must have the proper vector length
297  bool faceNormals(UT_Vector3 *N,
298  int segment=0,
299  const UT_StringRef &P=GA_Names::P) const;
300  bool faceNormals(UT_Vector3D *N64,
301  int segment=0,
302  const UT_StringRef &P=GA_Names::P) const;
303  bool faceNormals(fpreal16 *N16,
304  int segment=0,
305  const UT_StringRef &P=GA_Names::P) const;
306  GT_DataArrayHandle faceNormals(int segment=0,
307  const UT_StringRef &P=GA_Names::P,
308  GT_Storage store=GT_STORE_REAL32) const;
309  /// @}
310 
311  /// @{
312  /// Compute shared normals. This will use the shared attribute named P to
313  /// compute the normals for each shared point.
314  bool pointNormals(UT_Vector3T<fpreal16> *N,
315  GT_Size npts,
316  int segment=0,
317  const UT_StringRef &P=GA_Names::P,
318  bool normalize=true,
319  const fpreal32 *pntdata = NULL) const;
320  bool pointNormals(UT_Vector3 *N, GT_Size npts,
321  int segment=0,
322  const UT_StringRef &P=GA_Names::P,
323  bool normalize=true,
324  const fpreal32 *pntdata = NULL) const;
325  bool pointNormals(UT_Vector3D *N, GT_Size npts,
326  int segment=0,
327  const UT_StringRef &P=GA_Names::P,
328  bool normalize=true,
329  const fpreal32 *pntdata = NULL) const;
331  const UT_StringRef &P=GA_Names::P,
332  bool normalize=true,
333  const fpreal32 *pntdata = NULL,
335  ) const override;
336  /// @}
337 
338  /// @{
339  /// Compute vertex normals. This will use the shared attribute named P to
340  /// compute the normals for each vertex.
341  bool vertexNormals(UT_Vector3T<fpreal16> *N,
342  GT_Size npts,
343  int segment=0,
344  const UT_StringRef &P=GA_Names::P,
345  fpreal maxangledegrees=GT_DEFAULT_ADJUSTED_CUSP_ANGLE,
346  bool normalize=true) const;
347  bool vertexNormals(UT_Vector3 *N,
348  GT_Size npts,
349  int segment=0,
350  const UT_StringRef &P=GA_Names::P,
351  fpreal maxangledegrees=GT_DEFAULT_ADJUSTED_CUSP_ANGLE,
352  bool normalize=true) const;
353  bool vertexNormals(UT_Vector3D *N,
354  GT_Size npts,
355  int segment=0,
356  const UT_StringRef &P=GA_Names::P,
357  fpreal maxangledegrees=GT_DEFAULT_ADJUSTED_CUSP_ANGLE,
358  bool normalize=true) const;
359  virtual GT_DataArrayHandle createVertexNormals(int segment=0,
360  const UT_StringRef &P=GA_Names::P,
361  fpreal maxangledegrees=GT_DEFAULT_ADJUSTED_CUSP_ANGLE,
362  bool normalize=true,
363  GT_Storage store =GT_STORE_REAL32) const;
364  /// @}
365 
366 
367  /// @brief Create point normals on a new mesh if no normals are found.
368  /// If no point or vertex normals are found, generate point normals from P
369  /// and return a new mesh. If normals are found, return NULL.
370  ///
371  /// If the segement is less than 0, normals for *all* segments will be
372  /// computed (if required)
373  GT_PrimPolygonMesh *createPointNormalsIfMissing(
374  const UT_StringRef &P=GA_Names::P,
375  bool normalize=true,
376  bool *error = nullptr) const;
377 
378  GT_PrimPolygonMesh *createVertexNormalsIfMissing(
379  const UT_StringRef &P=GA_Names::P,
380  fpreal cuspangledegrees=GT_DEFAULT_ADJUSTED_CUSP_ANGLE,
381  bool normalize=true,
382  bool *error = nullptr) const;
383 
384  /// @brief Divide a mesh into smaller meshes if it exceeds the poly_limit.
385  /// If this mesh has more than polygon_limit polygons, this will split the
386  /// mesh into multiple sub-meshes, attempting to keep them all roughly the
387  /// same number of polygons. If this mesh has fewer than polygon_limit
388  /// polygons, it will return false and not add any meshes to split_meshes.
389  /// If remove_unused_points is true, each submesh will have unused points
390  // removed.
391  bool splitMesh(GT_Size polygon_limit,
392  UT_Array<GT_PrimitiveHandle> &split_meshes,
393  bool remove_unused_points = true) const;
394 
395  /// @{
396  /// Methods for GEO/GU support.
397  fpreal computePerimeter(int seg) const override;
398  fpreal computeSurfaceArea(int seg) const override;
399  fpreal computeVolume(const UT_Vector3 &ref_P, int seg) const override;
400  /// @}
401 
402  bool updateGeoPrim(const GU_ConstDetailHandle &dtl,
403  const GT_RefineParms &refine) override;
404 
405 protected:
406  void hardenAttributes();
407 
408  // We have "clone" methods so that sub-classes (i.e.
409  // GT_PrimSubdivisionMesh) can create an appropriate clone. These are used
410  // by methods internal when duplicating the mesh (i.e. removeUnusedPoints)
411  virtual GT_PrimPolygonMesh *clone(const GT_DataArrayHandle &vtx_counts,
412  const GT_DataArrayHandle &vtx_indices,
413  const GT_AttributeListHandle &shared,
414  const GT_AttributeListHandle &vertex,
415  const GT_AttributeListHandle &uniform,
416  const GT_AttributeListHandle &detail,
418  GT_Size min_vertex_count=0,
419  GT_Size max_vertex_count=0) const
420  {
421  return new GT_PrimPolygonMesh(vtx_counts, vtx_indices,
422  shared, vertex, uniform, detail, indexing,
423  min_vertex_count, max_vertex_count);
424  }
425  virtual GT_PrimPolygonMesh *clone(const GT_CountArray &vtx_counts,
426  const GT_DataArrayHandle &vtx_indices,
427  const GT_AttributeListHandle &shared,
428  const GT_AttributeListHandle &vertex,
429  const GT_AttributeListHandle &uniform,
430  const GT_AttributeListHandle &detail) const
431  {
432  return new GT_PrimPolygonMesh(vtx_counts, vtx_indices,
433  shared, vertex, uniform, detail);
434  }
436  const GT_AttributeListHandle &vertex,
437  const GT_AttributeListHandle &uniform,
438  const GT_AttributeListHandle &detail) const
439  {
440  return new GT_PrimPolygonMesh(*this, shared, vertex, uniform, detail);
441  }
442  virtual GT_PrimPolygonMesh *clone(const GT_DataArrayHandle &vtx_indices,
443  const GT_AttributeListHandle &shared) const
444  {
445  return new GT_PrimPolygonMesh(*this, vtx_indices, shared);
446  }
447 
452 
453 private:
454  template <typename VECTOR_T>
455  GT_DataArrayHandle getVertexNormalHandle(
456  const UT_StringRef &P_name,
457  int seg,
458  fpreal maxangledegrees,
459  bool normalize) const;
460  template <typename VECTOR_T>
461  bool computePointNormals(
463  GT_Size Nsize,
464  const UT_StringRef &P,
465  int segment,
466  bool normalize,
467  const fpreal32 *point_data) const;
468  template <typename VECTOR_T>
469  bool computeVertexNormals(
471  GT_Size Nsize,
472  const UT_StringRef &P,
473  int segment,
474  fpreal maxangledegrees,
475  bool normalize) const;
476 
477  void makeMerge();
478 
479  GT_DataArrayHandle myVertexList;
480  GT_CountArray myFaceOffsets;
481  GT_FaceSetMapPtr myFaceSetMap;
482  GT_AttributeMerge *myVMerge, *myUMerge;
483  bool myConvexFlag;
484 };
485 
486 #endif
487 
GT_Size getPointCount() const
Return the number of points.
GT_Storage
Definition: GT_Types.h:18
virtual int getMotionSegments() const =0
Keep track of merging of attribute maps.
GT_PrimPolygonMesh(const GT_CountArray &vtx_counts, const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail)
const GT_AttributeListHandle & getVertexAttributes() const override
virtual bool updateGeoPrim(const GU_ConstDetailHandle &dtl, const GT_RefineParms &parms)
update any cached data for geometry and its attributes
int int32
Definition: SYS_Types.h:39
virtual bool refine(GT_Refine &refiner, const GT_RefineParms *parms=NULL) const
const GT_AttributeListHandle & getPointAttributes() const override
void setFaceSetMap(const GT_FaceSetMapPtr &v)
A mesh of polygons.
virtual int getPrimitiveType() const
virtual fpreal computePerimeter(int seg=0) const
GLuint segment
Definition: glew.h:12701
virtual fpreal computeVolume(const UT_Vector3 &ref_P, int seg=0) const
#define GT_DEFAULT_ADJUSTED_CUSP_ANGLE
GT_Size getMinVertexCount() const
GT_Size getVertexCount(GT_Offset face) const
Return the length of the vertex list for the given face.
const GLfloat * c
Definition: glew.h:16631
const GT_CountArray & getFaceCountArray() const
GT_AttributeListHandle myShared
GT_IndexingMode
Definition: GT_Types.h:102
#define GT_API
Definition: GT_API.h:11
GT_PrimPolygonMesh(const GT_DataArrayHandle &vtx_counts, const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail, GT_IndexingMode indexing=GT_INDEXING_QUICK, GT_Size min_vertex_count=0, GT_Size max_vertex_count=0)
Useful constructor.
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:35
GA_API const UT_StringHolder P
GLuint const GLchar * name
Definition: glcorearb.h:785
GT_Size getVertexCount() const
Return the number of vertices.
GLenum src
Definition: glcorearb.h:1792
3D Vector class.
float fpreal32
Definition: SYS_Types.h:200
const GT_AttributeListHandle & getShared() const
bool isConvexed() const
Returns true if this mesh has been convexed.
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
const GT_AttributeListHandle & getVertex() const
const GT_AttributeListHandle & getUniform() const
virtual GT_PrimPolygonMesh * clone(const GT_DataArrayHandle &vtx_counts, const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail, GT_IndexingMode indexing=GT_INDEXING_QUICK, GT_Size min_vertex_count=0, GT_Size max_vertex_count=0) const
GT_PrimPolygonMesh()
Default constructor.
Abstract data class for an array of float, int or string data.
Definition: GT_DataArray.h:40
GT_PrimitiveHandle doSoftCopy() const override
virtual fpreal computeSurfaceArea(int seg=0) const
const GLdouble * v
Definition: glcorearb.h:836
virtual GT_PrimPolygonMesh * clone(const GT_CountArray &vtx_counts, const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail) const
void setConvexed(bool c)
Set the convex flag on the mesh.
int64 GT_Offset
Definition: GT_Types.h:124
long long int64
Definition: SYS_Types.h:116
GT_Size getMaxVertexCount() const
The base class for all GT primitive types.
Definition: GT_Primitive.h:43
virtual GT_PrimitiveHandle doHarden() const
const char * className() const override
virtual int64 getMemoryUsage() const =0
virtual GT_PrimPolygonMesh * clone(const GT_DataArrayHandle &vtx_indices, const GT_AttributeListHandle &shared) const
Processes primitives generated by refinement process.
Definition: GT_Refine.h:20
int64 GT_Size
Definition: GT_Types.h:123
GT_AttributeListHandle myVertex
GT_AttributeListHandle myUniform
fpreal64 fpreal
Definition: SYS_Types.h:277
const GT_AttributeListHandle & getDetailAttributes() const override
virtual bool save(UT_JSONWriter &w) const
GA_API const UT_StringHolder N
fp normalize(fp value)
Definition: format-inl.h:1160
GT_Offset getVertexOffset(GT_Offset face) const
Return the offset into the vertex list for the given face.
virtual GT_DataArrayHandle createPointNormals(int segment=0, const UT_StringRef &P=GA_Names::P, bool normalize=true, const fpreal32 *pntdata=NULL, GT_Storage store=GT_STORE_REAL32) const
GT_AttributeListHandle myDetail
virtual GT_PrimPolygonMesh * clone(const GT_AttributeListHandle &shared, const GT_AttributeListHandle &vertex, const GT_AttributeListHandle &uniform, const GT_AttributeListHandle &detail) const
virtual GT_PrimitiveHandle doAttributeMerge(const GT_Primitive &src, const UT_StringMMPattern *vertex, const UT_StringMMPattern *point, const UT_StringMMPattern *uniform, const UT_StringMMPattern *detail) const
The virtual implementation of attribute merging.
virtual void enlargeBounds(UT_BoundingBox boxes[], int nsegments) const =0
const GT_FaceSetMapPtr & faceSetMap() const
Single closed polygon.
const GT_AttributeListHandle & getDetail() const
const GT_AttributeListHandle & getUniformAttributes() const override
GLenum GLuint GLint GLenum face
Definition: glew.h:4630
const GT_DataArrayHandle & getVertexList() const override