HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_SurfaceDistance.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_SurfaceDistance.h (GU Library, C++)
7  *
8  * COMMENTS:
9  * Approximates geodesic distance.
10  * This code is related to the soft falloff code in GEO_Transform, but is
11  * mostly a replacement for it as of Houdini 16.5.
12  */
13 
14 #ifndef __GU_SurfaceDistance_h__
15 #define __GU_SurfaceDistance_h__
16 
17 #include "GU_API.h"
18 
19 #include <GA/GA_Types.h>
20 #include <GA/GA_Handle.h>
21 #include <GEO/GEO_Detail.h>
22 
23 // keep this synced with the parameter in $PRM/PRM_Shared.C
25 {
31  GU_SOFT_METRIC_INVALID
32 };
33 
34 // Utility class for measuring distances along a surface (or along edges).
35 // Call findDistances() to discover distances to points within 'max_dist' from
36 // the seed points/position.
37 //
38 // The geometry given to the constructor will be converted to polygons (or
39 // polylines if measuring along edges). The converted geometry can be explored
40 // with methods on this class.
42 {
43 public:
44  GU_SurfaceDistance(const GEO_Detail &gdp, bool as_polylines);
45 
46  // Returns true if the converted geometry representation is polylines.
47  bool getAsPolylines() const { return myAsPolylines; }
48 
49  // Returns number of polygons in the converted geometry.
50  exint getNumPrimitives() const { return myPrimEnd.entries(); }
51 
52  // Returns range of vertices for the given converted polygon.
53  void getVertexRange(exint pr, exint &start, exint &end) const
54  {
55  end = myPrimEnd(pr);
56  start = pr ? myPrimEnd(pr - 1) : 0;
57  }
58 
59  // Returns the first vertex referencing the given point.
60  exint firstVertex(GA_Offset pt) const { return myPtFirstVtx(exint(pt)); }
61 
62  // Returns the next vertex referencing the same point.
63  exint nextVertex(exint vtx) const { return myVtxNextVtx(vtx); }
64 
65  // Returns the point the given vertex references.
66  GA_Offset vertexPoint(exint vtx) const { return myVtxPt(vtx); }
67 
68  // Returns the primitive to which the given vertex belongs.
69  exint vertexPrimitive(exint vtx) const { return myVtxPrim(vtx); }
70 
71  // Seeds known distances for a set of points. All found distances within
72  // 'max_dist' are reported by calling 'func'.
73  void findDistances(const GA_ROHandleV3 &p_attr,
74  fpreal max_dist, // negative means no max_dist
75  const GA_OffsetArray &pts,
76  const UT_FloatArray &dists,
77  const std::function<void(GA_Offset, fpreal)> &func) const;
78 
79  // Seeds known distances for a set of points. All found distances within
80  // 'max_dist' are reported by calling 'func'.
81  void findDistances(const GA_ROHandleV3 &p_attr,
82  fpreal max_dist, // negative means no max_dist
83  const GA_OffsetArray &pts,
84  const UT_FloatArray &dists,
85  const UT_Array<exint> &src,
86  const std::function<void(GA_Offset, fpreal, exint)> &func) const;
87 
88 private:
89  void internalVertex(GA_Offset pt);
90  void internalEndPrimitive() { myPrimEnd.append(myVtxPt.entries()); }
91 
92  // The following are used by convertPrimitive() to record polygon
93  // representation of geometry. They will discard invalid vertices
94  // and convex the results before passing the data along to the internal*
95  // methods.
96  void polyVertex(GA_OffsetArray &pts, GA_Offset pt)
97  {
98  if(pt != GA_INVALID_OFFSET)
99  pts.append(pt);
100  }
101  void endPolygon(GA_OffsetArray &pts);
102  void endPolyline(GA_OffsetArray &pts);
103 
104  bool myAsPolylines;
105 
106  // points
107  UT_Array<exint> myPtFirstVtx; // first vertex referencing the point
108 
109  // converted prim data
110  UT_Array<exint> myPrimEnd; // end of vertex list for a given polygon
111 
112  // converted vertex data
113  UT_Array<GA_Offset> myVtxPt; // vertexPoint
114  UT_Array<exint> myVtxPrim; // vertexPrimitive
115  UT_Array<exint> myVtxNextVtx; // next vertex referencing the point or -1
116 };
117 
118 // This class contains all the data needed to efficiently compute surface
119 // distances. It will automatically invalidate cache items when inputs to the
120 // query are incompatible with the cached data. This can help SOPs that want
121 // to save time on repeated calls.
123 {
124 public:
125  GU_SurfaceDistanceCache() { clear(); }
127 
128  void clear();
129 
130  // utility method to support multithreading of the surfdist VEX function
131  bool canReuse(const GEO_Detail &gdp, const char *p_attr, fpreal radius,
132  GU_SoftDistanceMetric metric) const;
133 
134  // group of points with valid distances (and lead points)
136  { return myAffectedGroup.get(); }
137 
138  // handle to detached attribute describing measured distances
140  { return GA_ROHandleF(myDistances.get()); }
141 
142  // handle to detached attribute describing closest lead point
144  { return GA_ROHandleID(mySourcePoints.get()); }
145 
146  // compute distances for points within the radius
147  void updateDistances(const GEO_Detail &gdp,
148  const GA_Group *srcgroup,
149  fpreal radius,
150  GU_SoftDistanceMetric metric,
151  const char *p_attr = "P",
152  const GEO_Detail::SoftSymmetryParms *symmetry = nullptr,
153  const GEO_Rolloff *rolloff = nullptr);
154 
155 private:
156  bool hasSameTopology(const GEO_Detail &gdp) const;
157 
158  void updateSurfAndEdgeDistances(const GEO_Detail &gdp,
159  const GA_PointGroup *srcgroup,
160  fpreal radius,
161  GU_SoftDistanceMetric metric,
162  const GA_ROHandleV3 &p_attrib,
163  const GEO_Detail::SoftSymmetryParms *symmetry);
164 
166 
167  // set of points with computed distances (and lead points)
168  UT_UniquePtr<GA_PointGroup> myAffectedGroup;
169  // distance to the closest point in the input group
170  UT_UniquePtr<GA_Attribute> myDistances;
171  // the point in the input group that the current point is closest to
172  UT_UniquePtr<GA_Attribute> mySourcePoints;
173 
174  // values used to determine when to invalidate cached data
175  GU_SoftDistanceMetric myMetric;
176  fpreal myRadius;
177  GA_DataId myGdpPrimitiveId;
178  GA_DataId myGdpTopologyId;
179 
180  bool myHasSymmetryParms;
181  bool myHasPtGroup;
182  GEO_Detail::SoftSymmetryParms mySymmetryParms;
183  UT_String myPAttrib;
184  GA_OffsetArray myPts;
185 };
186 
187 #endif
enum GU_API GU_SoftDistanceMetric
GA_ROHandleF getDistances() const
void getVertexRange(exint pr, exint &start, exint &end) const
GLenum src
Definition: glew.h:2410
int64 GA_DataId
Definition: GA_Types.h:683
exint nextVertex(exint vtx) const
const GA_PointGroup * getAffectedGroup() const
GA_ROHandleT< int64 > GA_ROHandleID
Definition: GA_Handle.h:1274
GU_SOFT_CUSTOM
exint vertexPrimitive(exint vtx) const
#define GA_INVALID_OFFSET
Definition: GA_Types.h:674
GU_SOFT_DISTANCE_ALONG_CONNECTED_EDGES
GA_Size GA_Offset
Definition: GA_Types.h:637
int64 exint
Definition: SYS_Types.h:120
GA_ROHandleID getSourcePoints() const
exint firstVertex(GA_Offset pt) const
GA_ROHandleT< fpreal32 > GA_ROHandleF
Definition: GA_Handle.h:1244
GLuint GLuint end
Definition: glew.h:1253
bool getAsPolylines() const
GU_SOFT_GLOBAL_DISTANCE_WITH_CONNECTIVITY
GA_Offset vertexPoint(exint vtx) const
#define GU_API
Definition: GU_API.h:14
GLuint start
Definition: glew.h:1253
GU_SOFT_SURFACE_DISTANCE
double fpreal
Definition: SYS_Types.h:276
GLenum func
Definition: glcorearb.h:782
GU_SOFT_GLOBAL_DISTANCE
exint append(void)
Definition: UT_Array.h:95
exint getNumPrimitives() const