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 class guPointVtxsChunks;
27 struct guTriVtxPair;
28 template<exint BUFFERSIZE>
30 
32 {
33 public:
34  GU_TriDivide(GU_Detail &gdp, const GU_Detail *refgdp, fpreal minlength, UT_Interrupt *boss = nullptr);
35 
36  virtual ~GU_TriDivide();
37 
38  /// Wrapper method for TriDivide that does pre-processing, the subdivision,
39  /// and post-processing.
40  void tridivide(int depth, fpreal minarea,
41  const UT_Matrix4D &projmatrix,
42  const UT_BoundingBoxD &bbox,
43  bool expand,
44  int numsplit, const GA_PrimitiveGroup *grp = nullptr);
45 
46 private:
48 
49  /// Builds the triangle list.
50  void buildTopology(const GA_PrimitiveGroup *grp = nullptr);
51 
52  /// Does root(3) subdivision. If minarea > 0, at each iteration any triangles
53  /// with area less than minarea are not processed and left as is in the mesh.
54  /// If a projection matrix is supplied, a perspective projection is applied to
55  /// each point before measuring area, allowing culling in pixel space, for example.
56  /// The point can be further tested for culling against a provided bounding box.
57  /// If expand is true, the boundary of the culled triangles is expanded by one ring
58  /// outward which gives a smoother subdivision over several iterations.
59  void subdivide(int depth, fpreal minarea,
60  const UT_Matrix4D &projmatrix,
61  const UT_BoundingBoxD &bbox,
62  bool expand);
63 
64  /// Equalizes edges by splitting the longest edges.
65  /// Splits are done until every edge is less than minlength
66  /// or number of splits numsplits has been done. A value of
67  /// -1 is ignored.
68  void equalizeEdges(int numsplit);
69 
70  /// Transforms the triangle list into actual triangles.
71  void buildGeometry();
72 
73  /// If edge is longer than minlength, add the triangle it belongs to
74  /// in the mapping of edges to adjacent triangles.
75  void addToEdgeMapIfLong(guEdgeToTrisMap &edgemap, const GA_Edge &edge, const guTriVtxPair &pair, const UT_Vector3Array &refpos) const;
76 
77  /// If edge is longer than minlength, add it to the priority queue
78  /// of edges to be split, ordered from longest to shortest.
79  void addToEdgeQueueIfLong(guDivTriEdgeQueue &queue, GA_Offset pt_a, GA_Offset pt_b, const UT_Vector3Array &refpos) const;
80 
81  /// Calculate square of the distance between points a and b.
82  fpreal calculateLength2(GA_Offset a, GA_Offset b,
83  const UT_Vector3Array &refpos) const;
84 
85  /// Find all tris that either have no points within the provided bbox
86  /// or area less than minarea and append them as a new, exactly-sized
87  /// chunk onto culledtrischunks (one chunk per call, rather than
88  /// growing a single array in place, since culling tends to arrive in
89  /// a few enormous bursts rather than gradually -- growing one array
90  /// across calls would mean repeatedly re-copying everything collected
91  /// by earlier calls).
92  /// If a non-identity projection matrix is supplied, the previous tests
93  /// are performed after doing a toNDC-style perspective projection.
94  /// To index the remaining valid tris, the trioffsetstoindices and
95  /// triindicestooffsets are filled where offset refers to a tri's
96  /// position in myTriList and index refers to its order among
97  /// the valid tris.
98  exint cullByArea(UT_Array<UT_Array<guDivTri>> &culledtrischunks,
99  UT_Array<exint> &trioffsetstoindices,
100  UT_Array<exint> &triindicestooffsets,
101  fpreal minarea, const UT_Matrix4D &proj,
102  const UT_BoundingBoxD &bbox, bool expand,
103  const UT_Vector3Array &refpos,
104  UT_Array<bool> &culledstorage,
105  UT_Array<exint> &culledtriindicestooffsets) const;
106 
107  /// Free the arrays in myPointToVtxsList by iterating over the
108  /// points in myGdp. This must be done as these buffer arrays
109  /// do not have a destructor as they are POD types.
110  void destructMyPointToVtxsList();
111 
112  /// Relax points and if depth > 0 then update myPtToVtxsList
113  /// for all points excluding the newly added barycenter points.
114  /// If depth is 0, then free myPtToVtxsList instead.
115  void relaxPointsAndUpdatePointVtxs(UT_Vector3Array &newpos, UT_Vector3Array &newrefpos,
116  const UT_Vector3Array &pos, const UT_Vector3Array &refpos, bool useref,
117  const GA_Range &ptrange,
118  bool lastdepth, exint nvalid, const UT_Array<exint> *trioffsetstoindicesptr);
119 
120  /// Subdivide and flip all unculled triangles and if depth > 0
121  /// then update myPtToVtxsList for the newly added barycenter
122  /// points. Note that subdividing and flipping is done directly
123  /// as a single step, not as two separate steps.
124  void subdivideAndFlipAndUpdateBarycenterVtxs(UT_Array<guDivTri> &newtrilist, GA_Offset barycenters_start_offset, bool lastdepth, exint nvalid,
125  const UT_Array<exint> *triindicestooffsetsptr, const UT_Array<exint> *trioffsetstoindicesptr);
126 
127  /// Set the mate offsets for the tris adjacent to a point.
128  void setMatesForTrisAtPoint(GA_Offset ptoff);
129 
130  /// Split the longest edge longer than minlength.
131  void splitEdge(guEdgeToTrisMap &edgemap, guDivTriEdgeQueue &queue, UT_Vector3Array &refpos,
132  const guDivTriEdge &triedge, fpreal ratio);
133 
134  /// The geometry to be subdivided and an optional reference geometry
135  /// to be used for point positions if passed in and if it has at
136  /// least as many points as myGdp.
137  GU_Detail &myGdp;
138  const GU_Detail * const myRefGdp;
139 
140  // Separate GU_Detail that holds the source primitives IFF we need to
141  // copy primitive attributes onto the subdivided result. See
142  // buildTopology for where it's built and buildGeometry where it's used
143  // for copying then deleted.
144  UT_UniquePtr<GU_Detail> mySrcGdp;
145 
146  /// Array of triangles of the current state of the mesh.
147  /// guDivTri is a POD type, so setSizeNoInit() should be used
148  /// to grow it and elements should be initialized in parallel
149  /// for performance.
150  UT_Array<guDivTri> myTriList;
151 
152  /// Point wrangler for averaging attribute values and positions
153  /// for newly added points. These are either the barycenters
154  /// during subdivision or midpoints during edge splits.
155  GA_PointWrangler myPointWrangler;
156 
157  /// Maps point offsets to the vertex/triangle pairs referencing that
158  /// point in myTriList. Backed by chunked storage (guPointVtxsChunks,
159  /// defined in GU_TriDivide.C) rather than one flat array grown in place
160  /// across subdivide() iterations -- see that class for why. Held by
161  /// pointer since guPointVtxsChunks is a private implementation detail
162  /// not exposed here, same as guDivTri/guEdgeToTrisMap/etc. above.
163  /// There should only be elements at point offsets in myGdp and, since
164  /// they do not have a destructor, the point offsets will have to be
165  /// iterated over to manually destruct them (destructMyPointToVtxsList()).
166  guPointVtxsChunks *myPointToVtxsList;
167 
168  /// The min length and its square for edge splitting.
169  const fpreal myMinLength;
170  const fpreal myMinLength2;
171 
172  UT_Interrupt * const myBoss;
173 };
174 
175 #endif
176 
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
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
GA_Size GA_Offset
Definition: GA_Types.h:653
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the queue
Definition: thread.h:632
#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:283