HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_TriDivide.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: GU_TriDivide.h ( GU Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GU_TriDivide__
12 #define __GU_TriDivide__
13 
14 #include "GU_API.h"
15 #include <GA/GA_Edge.h>
16 #include <GA/GA_ElementWrangler.h>
17 #include <UT/UT_Map.h>
18 #include <UT/UT_PriorityQueue.h>
19 #include <UT/UT_Interrupt.h>
20 
21 class GA_PrimitiveGroup;
22 class guDivTri;
23 class guDivTriEdge;
24 class guDivTriEdgeCompare;
25 class guEdgeToTrisMap;
26 struct guTriVtxPair;
27 template<exint BUFFERSIZE>
29 
31 {
32 public:
33  GU_TriDivide(GU_Detail &gdp, const GU_Detail *refgdp, fpreal minlength, UT_Interrupt *boss = nullptr);
34 
35  virtual ~GU_TriDivide();
36 
37  /// Wrapper method for TriDivide that does pre-processing, the subdivision,
38  /// and post-processing.
39  void tridivide(int depth, fpreal minarea,
40  const UT_Matrix4D &projmatrix,
41  const UT_BoundingBoxD &bbox,
42  bool expand,
43  int numsplit, const GA_PrimitiveGroup *grp = nullptr);
44 
45 private:
47 
48  /// Builds the triangle list.
49  void buildTopology(const GA_PrimitiveGroup *grp = nullptr);
50 
51  /// Does root(3) subdivision. If minarea > 0, at each iteration any triangles
52  /// with area less than minarea are not processed and left as is in the mesh.
53  /// If a projection matrix is supplied, a perspective projection is applied to
54  /// each point before measuring area, allowing culling in pixel space, for example.
55  /// The point can be further tested for culling against a provided bounding box.
56  /// If expand is true, the boundary of the culled triangles is expanded by one ring
57  /// outward which gives a smoother subdivision over several iterations.
58  void subdivide(int depth, fpreal minarea,
59  const UT_Matrix4D &projmatrix,
60  const UT_BoundingBoxD &bbox,
61  bool expand);
62 
63  /// Equalizes edges by splitting the longest edges.
64  /// Splits are done until every edge is less than minlength
65  /// or number of splits numsplits has been done. A value of
66  /// -1 is ignored.
67  void equalizeEdges(int numsplit);
68 
69  /// Transforms the triangle list into actual triangles.
70  void buildGeometry();
71 
72  /// If edge is longer than minlength, add the triangle it belongs to
73  /// in the mapping of edges to adjacent triangles.
74  void addToEdgeMapIfLong(guEdgeToTrisMap &edgemap, const GA_Edge &edge, const guTriVtxPair &pair, const UT_Vector3Array &refpos) const;
75 
76  /// If edge is longer than minlength, add it to the priority queue
77  /// of edges to be split, ordered from longest to shortest.
78  void addToEdgeQueueIfLong(guDivTriEdgeQueue &queue, GA_Offset pt_a, GA_Offset pt_b, const UT_Vector3Array &refpos) const;
79 
80  /// Calculate square of the distance between points a and b.
81  fpreal calculateLength2(GA_Offset a, GA_Offset b,
82  const UT_Vector3Array &refpos) const;
83 
84  /// Find all tris that either have no points within the provided bbox
85  /// or area less than minarea and add them to culledtris.
86  /// If a non-identity projection matrix is supplied, the previous tests
87  /// are performed after doing a toNDC-style perspective projection.
88  /// To index the remaining valid tris, the trioffsetstoindices and
89  /// triindicestooffsets are filled where offset refers to a tri's
90  /// position in myTriList and index refers to its order among
91  /// the valid tris.
92  exint cullByArea(UT_Array<guDivTri> &culledtris,
93  UT_Array<exint> &trioffsetstoindices,
94  UT_Array<exint> &triindicestooffsets,
95  fpreal minarea, const UT_Matrix4D &proj,
96  const UT_BoundingBoxD &bbox, bool expand,
97  const UT_Vector3Array &refpos,
98  UT_Array<bool> &culledstorage,
99  UT_Array<exint> &culledtriindicestooffsets) const;
100 
101  /// Free the arrays in myPointToVtxsList by iterating over the
102  /// points in myGdp. This must be done as these buffer arrays
103  /// do not have a destructor as they are POD types.
104  void destructMyPointToVtxsList();
105 
106  /// Relax points and if depth > 0 then update myPtToVtxsList
107  /// for all points excluding the newly added barycenter points.
108  /// If depth is 0, then free myPtToVtxsList instead.
109  void relaxPointsAndUpdatePointVtxs(UT_Vector3Array &newpos, UT_Vector3Array &newrefpos,
110  const UT_Vector3Array &pos, const UT_Vector3Array &refpos, const GA_Range &ptrange,
111  bool lastdepth, exint nvalid, const UT_Array<exint> *trioffsetstoindicesptr);
112 
113  /// Subdivide and flip all unculled triangles and if depth > 0
114  /// then update myPtToVtxsList for the newly added barycenter
115  /// points. Note that subdividing and flipping is done directly
116  /// as a single step, not as two separate steps.
117  void subdivideAndFlipAndUpdateBarycenterVtxs(UT_Array<guDivTri> &newtrilist, GA_Offset barycenters_start_offset, bool lastdepth, exint nvalid,
118  const UT_Array<exint> *triindicestooffsetsptr, const UT_Array<exint> *trioffsetstoindicesptr);
119 
120  /// Set the mate offsets for the tris adjacent to a point.
121  void setMatesForTrisAtPoint(GA_Offset ptoff);
122 
123  /// Split the longest edge longer than minlength.
124  void splitEdge(guEdgeToTrisMap &edgemap, guDivTriEdgeQueue &queue, UT_Vector3Array &refpos,
125  const guDivTriEdge &triedge, fpreal ratio);
126 
127  /// The geometry to be subdivided and an optional reference geometry
128  /// to be used for point positions if passed in and if it has at
129  /// least as many points as myGdp.
130  GU_Detail &myGdp;
131  const GU_Detail * const myRefGdp;
132 
133  /// Array of triangles of the current state of the mesh.
134  /// guDivTri is a POD type, so setSizeNoInit() should be used
135  /// to grow it and elements should be initialized in parallel
136  /// for performance.
137  UT_Array<guDivTri> myTriList;
138 
139  /// Point wrangler for averaging attribute values and positions
140  /// for newly added points. These are either the barycenters
141  /// during subdivision or midpoints during edge splits.
142  GA_PointWrangler myPointWrangler;
143 
144  /// Array for mapping points to the vertex and triangle pairs
145  /// referencing that point in myTriList.
146  /// This array contains the POD type guTrisStackBufferArray so
147  /// setSizeNoInit() should be used to grow it and elements should
148  /// be initialized in parallel for performance.
149  /// There should only be elements at point offsets in myGdp and
150  /// since they do not have a destructor, the point offsets will
151  /// have to be iterated over to manually destruct them.
152  static constexpr exint PTTOVTXSBUFFERSIZE = 6;
154  UT_Array<guPointVtxsBuffer> myPointToVtxsList;
155 
156  /// Group of all triangles from the original mesh as they need to
157  /// be deleted at the end and replaced with the subdivied mesh.
158  GA_PrimitiveGroup * const myDelGrp;
159 
160  /// The min length and its square for edge splitting.
161  const fpreal myMinLength;
162  const fpreal myMinLength2;
163 
164  UT_Interrupt * const myBoss;
165 };
166 
167 #endif
168 
int64 exint
Definition: SYS_Types.h:125
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
A range of elements in an index-map.
Definition: GA_Range.h:42
GA_Size GA_Offset
Definition: GA_Types.h:641
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the queue
Definition: thread.h:623
#define GU_API
Definition: GU_API.h:14
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glcorearb.h:476
fpreal64 fpreal
Definition: SYS_Types.h:277