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