HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_EdgeUtils.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 Library.
7  *
8  * COMMENTS: This file contains useful edge related tools.
9  *
10  */
11 
12 #pragma once
13 
14 #ifndef __GU_EdgeUtils_h__
15 #define __GU_EdgeUtils_h__
16 
17 #include "GU_API.h"
18 #include <GA/GA_Edge.h>
19 #include <GA/GA_EdgeSet.h>
20 #include <GA/GA_ElementWrangler.h>
21 #include <SYS/SYS_Deprecated.h>
22 #include <UT/UT_Map.h>
23 #include <UT/UT_Set.h>
24 #include <UT/UT_Vector3.h>
25 #include <UT/UT_Vector4.h>
26 #include <stddef.h>
27 
28 class GEO_Face;
29 class GEO_PrimPoly;
30 class GEO_Detail;
31 class GA_EdgeGroup;
32 class GA_PointGroup;
33 class GA_PrimitiveGroup;
34 class GU_Detail;
35 
37 {
38 public:
40  GU_EdgeDiv(const GEO_PrimPoly &poly, const GA_Edge &edge, int numcuts,
41  float fraction) :
42  myPoly(poly), myEdge(edge), myNumCuts(numcuts), myFraction(fraction)
43  {
44  UT_ASSERT(SYSisLessOrEqual(fraction * numcuts, 1.0f));
45  }
46 
49  int myNumCuts;
50  float myFraction;
51 };
52 
53 ////////////////////////////////////////////////////////////////////
54 // Useful edge-related functions
55 
56 // Computes the position resulting from insetting vertex at index "vtx" of
57 // "face" by an amount of "inset".
58 GU_API extern UT_Vector3 GUcomputeInsetPos(const GEO_Face &face, int vtx,
59  float inset);
60 
61 // Returns true if the three points are collinear and false otherwise.
62 GU_API extern bool GUisPointInline(const UT_Vector3 &start,
63  const UT_Vector3 &mid,
64  const UT_Vector3 &end, float tol);
65 
66 // Gets the points corresponding to edge edgenum in face. Returns true if
67 // successful, and false otherwise. A true return status does not imply that
68 // both p0 and p1 are valid.
69 GU_API extern bool GUgetEdgePoints(const GEO_Face &face, int edgenum,
70  GA_Offset &p0, GA_Offset &p1);
71 
72 /// Iterates through the primitives of the detail, calling edgeApply
73 /// on each primitive to count the number of times each (unordered) edge is
74 /// present, and adds any edges that appear only once.
75 /// If prims_on_edges is true, each edge in the edge group will
76 /// reference the primitive it's associated with.
77 /// WARNING: A lot of things can go bonkers if you use prims_on_edges!
78 /// For example, toggling the edge group will result in a
79 /// group that contains all of the original edges plus
80 /// every edge, so more edges than the total number.
82  const GEO_Detail &detail,
83  GA_EdgeGroup &edges,
84  const GA_PrimitiveGroup *primgroup = NULL,
85  bool prims_on_edges = false);
86 
87 /// Iterates through the primitives of the detail, calling edgeApply
88 /// on each primitive to count the number of times each (unordered) edge is
89 /// present, and adds any edges that appear only once, in the direction
90 /// they appear.
91 /// WARNING: GA_DirectedEdgeSet is an unordered set, so iteration order
92 /// can't be relied upon if you use that version.
93 /// @{
95  const GEO_Detail &detail,
96  GA_DirectedEdgeSet &edges,
97  const GA_PrimitiveGroup *primgroup = NULL);
99  const GEO_Detail &detail,
101  const GA_PrimitiveGroup *primgroup = NULL);
102 /// @}
103 
104 // convenience function to split an edge loop on the given detail with the
105 // loops(s) specified by pt0, pt1 and either u, or if splits is non-zero, splits
106 // number of edge loops evenly spaced along the edge, or if parallel is true
107 // then it is an equal edge length split
108 // This is also an example of how to calculate the edge loop and then apply it
109 // if you want to do it yourself elsewhere
110 // warningCoords is filled with coordinates of points that are clamped when
111 // a parallel loop hits the edge of the defining loop
113  fpreal u, exint splits = 0, bool parallel = false,
114  GA_EdgeGroup *edgeGroup = NULL,
115  UT_Fpreal32Array* warningCoords = NULL);
116 
117 // utility class to help identify individual splits when splitting a new edge
118 // loop - used by topobuild state and the polysplit sop
120 {
121 public:
122  // pt0 pt1 defines the edge which the edge loop will be generated from
123  GU_LoopFinder(const GU_Detail &gdp, GA_Offset pt0, GA_Offset pt1);
124 
125  const UT_Array<GA_Edge> &getSplits() const { return mySplits; }
126 
127  // cu is the edge percentage to create a single loop at. Ignored if
128  // splits > 0
129  // splits is the number of loops to create. Values > 0 force the positions
130  // pts0 is the starts of the edges
131  // pts1 is the ends of the new edges
132  // pos is the positions of the new points
133  // us is the list of edge percentages of the new points
134  // pts0, pts1, pos, and us are to be passed in as newly initialized
135  // structures which are filled in by this method. Each element of pts0 is
136  // paired with an element of pts1. If the pts1 element is GA_INVALID_INDEX,
137  // then the point has already been created by a previous split edge, and the
138  // pts0 element is just the index of that point. pos and us only contain an
139  // element for each non-GA_INVALID_INDEX value in pts1, and have been
140  // compacted, so a separate index needs to be maintained while iterating
141  // over these arrays.
142  void findAllLoops(fpreal cu, exint splits, GA_IndexArray &pts0,
143  GA_IndexArray &pts1, UT_Vector3Array &pos, UT_FprealArray &us) const;
144  // similare to the previous funcion, but follows one side of the defining
145  // geometry. dist is the distance along each edge to cross at, and
146  // warningCoords will be filled with a list of positions which are collided
147  // with when the distance is larger than the edge being crossed. This can
148  // be used to render these points as warnings in MSS files.
149  void findAllParallelLoops(fpreal dist, exint splits, GA_IndexArray &pts0,
151  UT_Fpreal32Array* warningCoords = NULL) const;
152 
153 private:
154  void split(const GEO_PrimPoly *poly, exint i);
155  void splitH15_5(const GEO_PrimPoly *poly, exint i);
156  bool getManifoldQuads(GA_Offset pt0, GA_Offset pt1,
157  GA_Offset &vtx0, GA_Offset &vtx1,
158  GA_OffsetArray &scratch) const;
159 
160  const GU_Detail &myGdp;
161  // list of edge pairs defining polygons being split
162  UT_Array<GA_Edge> mySplits;
163 };
164 
165 // utility class to actually change the geometry of the detail to add splits
166 // used by the topobuild and polysplit sops
168 {
169 public:
171 
172  GA_Offset splitEdge(GA_Offset pt0, GA_Offset pt1, fpreal u);
173  void splitPolygons(GA_Offset pt0, GA_Offset pt1);
174 
175 private:
176  GU_Detail &myGdp;
177  GA_PointWrangler myPointWrangler;
178  GA_PrimitiveWrangler myPrimWrangler;
179  GA_VertexWrangler myVtxWrangler;
180 };
181 
182 GU_API void GUgetEdges(UT_Set<GA_Edge> &edges, const GA_PrimitiveGroup &grp);
183 GU_API void GUgetEdges(UT_Set<GA_Edge> &edges, const GA_PointGroup &grp);
184 
185 // utility function that will move connected points into circles
186 // only loops containing points participating in two edges will be moved
188  const GU_Detail &gdp,
189  const UT_Set<GA_Edge> &gaedges,
190  const fpreal *radius=nullptr,
191  bool proj_nml = false,
192  fpreal scale = 1.0);
193 
198 };
199 
200 // utility function that tries to make all connected edges the same length
201 // each connected island edges will move towards its own target length
203  const GU_Detail &gdp,
204  const UT_Set<GA_Edge> &gaedges,
206 
207 // utility function that will project connected points along a line
208 // only points participating in two edges will be moved
210  const GU_Detail &gdp,
211  const UT_Set<GA_Edge> &gaedges,
212  const UT_Vector3 *constrain_nml);
213 
214 // utility function to identify vertices along bridge paths
216  GA_OffsetArray &path1,
217  const GU_Detail &gdp,
218  const UT_Set<GA_Edge> &gaedges);
219 
220 // returns a list of points found walking along unshared edges
222  const GU_Detail &gdp,
224  GA_Offset end);
225 
226 // creates bridge polygons
227 GU_API void GUbridgeEdges(GU_Detail &gdp,
228  const UT_Set<GA_Edge> &gaedges,
229  bool connected);
230 
231 /// Describes the per-edge fraction and number of divisions per edge for
232 /// GUdivideEdges().
233 /// If myPrimOffset is GA_INVALID_OFFSET, all primitives referencing the edge
234 /// will be modified.
236 {
237 public:
239  const GA_Edge &edge,
240  GA_Offset primoff,
241  int numcuts,
242  float fraction)
243  : myEdge(edge)
244  , myPrimOffset(primoff)
245  , myNumCuts(numcuts)
246  , myFraction(fraction)
247  {
248  UT_ASSERT(SYSisLessOrEqual(fraction * numcuts, 1.0f));
249  }
250 
254  float myFraction;
255 };
256 
257 /// Inserts points on edges, with a different fraction and number of
258 /// divisions per edge.
259 GU_API void GUdivideEdges(
260  GU_Detail &detail,
261  const UT_Array<GU_PerEdgeDiv> &div_locs,
262  GA_PointGroup &new_points_group);
263 
264 #endif
GA_Edge myEdge
Definition: GU_EdgeUtils.h:48
GA_API const UT_StringHolder dist
Definition: UT_Set.h:58
GU_API void GUfindUnsharedEdges(const GEO_Detail &detail, GA_EdgeGroup &edges, const GA_PrimitiveGroup *primgroup=NULL, bool prims_on_edges=false)
const GEO_PrimPoly & myPoly
Definition: GU_EdgeUtils.h:47
GU_API void GUgetUnsharedPath(GA_OffsetArray &path, const GU_Detail &gdp, GA_Offset start, GA_Offset end)
Unsorted map container.
Definition: UT_Map.h:107
GU_API void GUedgeLoopSplit(GU_Detail &gdp, GA_Offset pt0, GA_Offset pt1, fpreal u, exint splits=0, bool parallel=false, GA_EdgeGroup *edgeGroup=NULL, UT_Fpreal32Array *warningCoords=NULL)
GLuint start
Definition: glcorearb.h:475
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
int64 exint
Definition: SYS_Types.h:125
GU_API void GUevenlySpaceEdges(UT_Map< GA_Offset, UT_Vector3 > &edits, const GU_Detail &gdp, const UT_Set< GA_Edge > &gaedges, GU_EvenlySpaceMethod method=GU_EVENLY_SPACE_AVERAGE)
GU_API void GUdivideEdges(GU_Detail &detail, const UT_Array< GU_PerEdgeDiv > &div_locs, GA_PointGroup &new_points_group)
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
GA_Size GA_Offset
Definition: GA_Types.h:641
GA_API const UT_StringHolder scale
GLfloat f
Definition: glcorearb.h:1926
GU_API void GUbridgeEdges(GU_Detail &gdp, const UT_Set< GA_Edge > &gaedges, bool connected)
GLuint GLuint end
Definition: glcorearb.h:475
GA_Edge myEdge
Definition: GU_EdgeUtils.h:251
GU_PerEdgeDiv(const GA_Edge &edge, GA_Offset primoff, int numcuts, float fraction)
Definition: GU_EdgeUtils.h:238
GU_API bool GUgetBridgePaths(GA_OffsetArray &path0, GA_OffsetArray &path1, const GU_Detail &gdp, const UT_Set< GA_Edge > &gaedges)
#define GU_API
Definition: GU_API.h:14
GU_API bool GUgetEdgePoints(const GEO_Face &face, int edgenum, GA_Offset &p0, GA_Offset &p1)
GU_API UT_Vector3 GUcomputeInsetPos(const GEO_Face &face, int vtx, float inset)
fpreal64 fpreal
Definition: SYS_Types.h:277
const UT_Array< GA_Edge > & getSplits() const
Definition: GU_EdgeUtils.h:125
OIIO_UTIL_API std::vector< std::string > splits(string_view str, string_view sep="", int maxsplit=-1)
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
#define const
Definition: zconf.h:214
GU_API void GUcircleEdges(UT_Map< GA_Offset, UT_Vector3 > &edits, const GU_Detail &gdp, const UT_Set< GA_Edge > &gaedges, const fpreal *radius=nullptr, bool proj_nml=false, fpreal scale=1.0)
void OIIO_UTIL_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
GU_API void GUstraightenEdges(UT_Map< GA_Offset, UT_Vector3 > &edits, const GU_Detail &gdp, const UT_Set< GA_Edge > &gaedges, const UT_Vector3 *constrain_nml)
float myFraction
Definition: GU_EdgeUtils.h:50
GA_Offset myPrimOffset
Definition: GU_EdgeUtils.h:252
GU_API void GUgetEdges(UT_Set< GA_Edge > &edges, const GA_PrimitiveGroup &grp)
GU_API bool GUisPointInline(const UT_Vector3 &start, const UT_Vector3 &mid, const UT_Vector3 &end, float tol)
GU_EvenlySpaceMethod
Definition: GU_EdgeUtils.h:194