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 <UT/UT_Map.h>
22 #include <UT/UT_Set.h>
23 #include <UT/UT_Vector3.h>
24 #include <UT/UT_Vector4.h>
25 #include <stddef.h>
26 
27 class GEO_Face;
28 class GEO_PrimPoly;
29 class GEO_Detail;
30 class GA_EdgeGroup;
31 class GA_PointGroup;
32 class GA_PrimitiveGroup;
33 class GU_Detail;
34 
36 {
37 public:
38  GU_EdgeDiv(const GEO_PrimPoly &poly, const GA_Edge &edge, int numcuts,
39  float fraction) :
40  myPoly(poly), myEdge(edge), myNumCuts(numcuts), myFraction(fraction)
41  {
42  UT_ASSERT(SYSisLessOrEqual(fraction * numcuts, 1.0f));
43  }
44 
47  int myNumCuts;
48  float myFraction;
49 };
50 
51 ////////////////////////////////////////////////////////////////////
52 // Useful edge-related functions
53 
54 // Computes the position resulting from insetting vertex at index "vtx" of
55 // "face" by an amount of "inset".
56 GU_API extern UT_Vector3 GUcomputeInsetPos(const GEO_Face &face, int vtx,
57  float inset);
58 
59 // Returns true if the three points are collinear and false otherwise.
60 GU_API extern bool GUisPointInline(const UT_Vector3 &start,
61  const UT_Vector3 &mid,
62  const UT_Vector3 &end, float tol);
63 
64 // Gets the points corresponding to edge edgenum in face. Returns true if
65 // successful, and false otherwise. A true return status does not imply that
66 // both p0 and p1 are valid.
67 GU_API extern bool GUgetEdgePoints(const GEO_Face &face, int edgenum,
68  GA_Offset &p0, GA_Offset &p1);
69 
70 /// Iterates through the primitives of the detail, calling edgeApply
71 /// on each primitive to count the number of times each (unordered) edge is
72 /// present, and adds any edges that appear only once.
73 /// If prims_on_edges is true, each edge in the edge group will
74 /// reference the primitive it's associated with.
75 /// WARNING: A lot of things can go bonkers if you use prims_on_edges!
76 /// For example, toggling the edge group will result in a
77 /// group that contains all of the original edges plus
78 /// every edge, so more edges than the total number.
80  const GEO_Detail &detail,
81  GA_EdgeGroup &edges,
82  const GA_PrimitiveGroup *primgroup = NULL,
83  bool prims_on_edges = false);
84 
85 /// Iterates through the primitives of the detail, calling edgeApply
86 /// on each primitive to count the number of times each (unordered) edge is
87 /// present, and adds any edges that appear only once, in the direction
88 /// they appear.
89 /// WARNING: GA_DirectedEdgeSet is an unordered set, so iteration order
90 /// can't be relied upon if you use that version.
91 /// @{
93  const GEO_Detail &detail,
94  GA_DirectedEdgeSet &edges,
95  const GA_PrimitiveGroup *primgroup = NULL);
97  const GEO_Detail &detail,
99  const GA_PrimitiveGroup *primgroup = NULL);
100 /// @}
101 
102 // convenience function to split an edge loop on the given detail with the
103 // loops(s) specified by pt0, pt1 and either u, or if splits is non-zero, splits
104 // number of edge loops evenly spaced along the edge, or if parallel is true
105 // then it is an equal edge length split
106 // This is also an example of how to calculate the edge loop and then apply it
107 // if you want to do it yourself elsewhere
108 // warningCoords is filled with coordinates of points that are clamped when
109 // a parallel loop hits the edge of the defining loop
111  fpreal u, exint splits = 0, bool parallel = false,
112  GA_EdgeGroup *edgeGroup = NULL,
113  UT_Fpreal32Array* warningCoords = NULL);
114 
115 // utility class to help identify individual splits when splitting a new edge
116 // loop - used by topobuild state and the polysplit sop
118 {
119 public:
120  // pt0 pt1 defines the edge which the edge loop will be generated from
121  GU_LoopFinder(const GU_Detail &gdp, GA_Offset pt0, GA_Offset pt1);
122 
123  const UT_Array<GA_Edge> &getSplits() const { return mySplits; }
124 
125  // cu is the edge percentage to create a single loop at. Ignored if
126  // splits > 0
127  // splits is the number of loops to create. Values > 0 force the positions
128  // pts0 is the starts of the edges
129  // pts1 is the ends of the new edges
130  // pos is the positions of the new points
131  // us is the list of edge percentages of the new points
132  // pts0, pts1, pos, and us are to be passed in as newly initialized
133  // structures which are filled in by this method. Each element of pts0 is
134  // paired with an element of pts1. If the pts1 element is GA_INVALID_INDEX,
135  // then the point has already been created by a previous split edge, and the
136  // pts0 element is just the index of that point. pos and us only contain an
137  // element for each non-GA_INVALID_INDEX value in pts1, and have been
138  // compacted, so a separate index needs to be maintained while iterating
139  // over these arrays.
140  void findAllLoops(fpreal cu, exint splits, GA_IndexArray &pts0,
141  GA_IndexArray &pts1, UT_Vector3Array &pos, UT_FprealArray &us) const;
142  // similare to the previous funcion, but follows one side of the defining
143  // geometry. dist is the distance along each edge to cross at, and
144  // warningCoords will be filled with a list of positions which are collided
145  // with when the distance is larger than the edge being crossed. This can
146  // be used to render these points as warnings in MSS files.
147  void findAllParallelLoops(fpreal dist, exint splits, GA_IndexArray &pts0,
149  UT_Fpreal32Array* warningCoords = NULL) const;
150 
151 private:
152  void split(const GEO_PrimPoly *poly, exint i);
153  void splitH15_5(const GEO_PrimPoly *poly, exint i);
154  bool getManifoldQuads(GA_Offset pt0, GA_Offset pt1,
155  GA_Offset &vtx0, GA_Offset &vtx1,
156  GA_OffsetArray &scratch) const;
157 
158  const GU_Detail &myGdp;
159  // list of edge pairs defining polygons being split
160  UT_Array<GA_Edge> mySplits;
161 };
162 
163 // utility class to actually change the geometry of the detail to add splits
164 // used by the topobuild and polysplit sops
166 {
167 public:
169 
170  GA_Offset splitEdge(GA_Offset pt0, GA_Offset pt1, fpreal u);
171  void splitPolygons(GA_Offset pt0, GA_Offset pt1);
172 
173 private:
174  GU_Detail &myGdp;
175  GA_PointWrangler myPointWrangler;
176  GA_PrimitiveWrangler myPrimWrangler;
177  GA_VertexWrangler myVtxWrangler;
178 };
179 
180 GU_API void GUgetEdges(UT_Set<GA_Edge> &edges, const GA_PrimitiveGroup &grp);
181 GU_API void GUgetEdges(UT_Set<GA_Edge> &edges, const GA_PointGroup &grp);
182 
183 // utility function that will move connected points into circles
184 // only loops containing points participating in two edges will be moved
186  const GU_Detail &gdp,
187  const UT_Set<GA_Edge> &gaedges,
188  const fpreal *radius=nullptr,
189  bool proj_nml = false);
190 
195 };
196 
197 // utility function that tries to make all connected edges the same length
198 // each connected island edges will move towards its own target length
200  const GU_Detail &gdp,
201  const UT_Set<GA_Edge> &gaedges,
203 
204 // utility function that will project connected points along a line
205 // only points participating in two edges will be moved
207  const GU_Detail &gdp,
208  const UT_Set<GA_Edge> &gaedges,
209  const UT_Vector3 *constrain_nml);
210 
211 // utility function to identify vertices along bridge paths
213  GA_OffsetArray &path1,
214  const GU_Detail &gdp,
215  const UT_Set<GA_Edge> &gaedges);
216 
217 // returns a list of points found walking along unshared edges
219  const GU_Detail &gdp,
221  GA_Offset end);
222 
223 // creates bridge polygons
224 GU_API void GUbridgeEdges(GU_Detail &gdp,
225  const UT_Set<GA_Edge> &gaedges,
226  bool connected);
227 
228 #endif
GA_Edge myEdge
Definition: GU_EdgeUtils.h:46
GA_API const UT_StringHolder dist
OIIO_API std::vector< std::string > splits(string_view str, string_view sep="", int maxsplit=-1)
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:45
GU_API void GUgetUnsharedPath(GA_OffsetArray &path, const GU_Detail &gdp, GA_Offset start, GA_Offset end)
Unsorted map container.
Definition: UT_Map.h:83
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)
GU_EdgeDiv(const GEO_PrimPoly &poly, const GA_Edge &edge, int numcuts, float fraction)
Definition: GU_EdgeUtils.h:38
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)
GA_Size GA_Offset
Definition: GA_Types.h:637
void OIIO_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
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)
GLclampf f
Definition: glew.h:3499
GU_API void GUbridgeEdges(GU_Detail &gdp, const UT_Set< GA_Edge > &gaedges, bool connected)
int64 exint
Definition: SYS_Types.h:120
GLuint GLuint end
Definition: glew.h:1253
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)
GLuint start
Definition: glew.h:1253
GU_API UT_Vector3 GUcomputeInsetPos(const GEO_Face &face, int vtx, float inset)
GLenum GLuint GLint GLenum face
Definition: glew.h:4616
GLsizei const GLchar *const * path
Definition: glew.h:6461
double fpreal
Definition: SYS_Types.h:276
const UT_Array< GA_Edge > & getSplits() const
Definition: GU_EdgeUtils.h:123
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:135
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:48
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:191