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 #include <UT/UT_Function.h>
23 
24 
25 // keep this synced with the parameter in $PRM/PRM_Shared.C
27 {
34 };
35 
36 // Utility class for measuring distances along a surface (or along edges).
37 // Call findDistances() to discover distances to points within 'max_dist' from
38 // the seed points/position.
39 //
40 // The geometry given to the constructor will be converted to polygons (or
41 // polylines if measuring along edges). The converted geometry can be explored
42 // with methods on this class.
44 {
45 public:
47  GU_SurfaceDistance(const GEO_Detail &gdp, bool as_polylines);
48 
49  // Returns true if the converted geometry representation is polylines.
50  bool getAsPolylines() const { return myAsPolylines; }
51 
52  // Returns number of polygons in the converted geometry.
53  exint getNumPrimitives() const { return myPrimEnd.entries(); }
54 
55  // Returns range of vertices for the given converted polygon.
56  void getVertexRange(exint pr, exint &start, exint &end) const
57  {
58  end = myPrimEnd(pr);
59  start = pr ? myPrimEnd(pr - 1) : 0;
60  }
61 
62  // Returns the first vertex referencing the given point.
63  exint firstVertex(GA_Offset pt) const { return myPtFirstVtx(exint(pt)); }
64 
65  // Returns the next vertex referencing the same point.
66  exint nextVertex(exint vtx) const { return myVtxNextVtx(vtx); }
67 
68  // Returns the point the given vertex references.
69  GA_Offset vertexPoint(exint vtx) const { return myVtxPt(vtx); }
70 
71  // Returns the primitive to which the given vertex belongs.
72  exint vertexPrimitive(exint vtx) const { return myVtxPrim(vtx); }
73 
74  // Seeds known distances for a set of points. All found distances within
75  // 'max_dist' are reported by calling 'func'.
76  void findDistances(const GA_ROHandleV3 &p_attr,
77  fpreal max_dist, // negative means no max_dist
78  const GA_OffsetArray &pts,
79  const UT_FloatArray &dists,
80  const UT_Function<void(GA_Offset, fpreal)> &func) const;
81 
82  // Seeds known distances for a set of points. All found distances within
83  // 'max_dist' are reported by calling 'func'.
84  void findDistances(const GA_ROHandleV3 &p_attr,
85  fpreal max_dist, // negative means no max_dist
86  const GA_OffsetArray &pts,
87  const UT_FloatArray &dists,
88  const UT_Array<exint> &src,
89  const UT_Function<void(GA_Offset, fpreal, exint)> &func) const;
90 
91  int64 getMemoryUsage(bool inclusive) const;
92 private:
93  void internalVertex(GA_Offset pt);
94  void internalEndPrimitive() { myPrimEnd.append(myVtxPt.entries()); }
95 
96  // The following are used by convertPrimitive() to record polygon
97  // representation of geometry. They will discard invalid vertices
98  // and convex the results before passing the data along to the internal*
99  // methods.
100  void polyVertex(GA_OffsetArray &pts, GA_Offset pt)
101  {
102  if(pt != GA_INVALID_OFFSET)
103  pts.append(pt);
104  }
105  void endPolygon(GA_OffsetArray &pts);
106  void endPolyline(GA_OffsetArray &pts);
107 
108  bool myAsPolylines;
109 
110  // points
111  UT_Array<exint> myPtFirstVtx; // first vertex referencing the point
112 
113  // converted prim data
114  UT_Array<exint> myPrimEnd; // end of vertex list for a given polygon
115 
116  // converted vertex data
117  UT_Array<GA_Offset> myVtxPt; // vertexPoint
118  UT_Array<exint> myVtxPrim; // vertexPrimitive
119  UT_Array<exint> myVtxNextVtx; // next vertex referencing the point or -1
120 };
121 
122 // This class contains all the data needed to efficiently compute surface
123 // distances. It will automatically invalidate cache items when inputs to the
124 // query are incompatible with the cached data. This can help SOPs that want
125 // to save time on repeated calls.
127 {
128 public:
130  GU_SurfaceDistanceCache() { clear(); }
134 
135  void clear();
136 
137  // utility method to support multithreading of the surfdist VEX function
138  bool canReuse(const GEO_Detail &gdp, const char *p_attr, fpreal radius,
139  GU_SoftDistanceMetric metric) const;
140 
141  // group of points with valid distances (and lead points)
143  { return myAffectedGroup.get(); }
144 
145  // handle to detached attribute describing measured distances
147  { return GA_ROHandleF(myDistances.get()); }
148 
149  // handle to detached attribute describing closest lead point
151  { return GA_ROHandleID(mySourcePoints.get()); }
152 
153  // compute distances from the point specified by hit_prim and hit_uv, for points within the radius,
154  void updateDistancesFromHitPos(const GEO_Detail &gdp,
155  const GU_SurfaceDistance& surf_dist,
156  int64 hit_prim, UT_Vector3 hit_pos,
157  fpreal radius,
158  GU_SoftDistanceMetric metric,
159  const char *p_attr = "P",
160  const GEO_Detail::SoftSymmetryParms *symmetry = nullptr,
161  const GEO_Rolloff *rolloff = nullptr);
162 
163  // compute distances from the closest member of the point group, for points within the radius
164  void updateDistances(const GEO_Detail &gdp,
165  const GU_SurfaceDistance& surf_dist,
166  const GA_Group *srcgroup,
167  fpreal radius,
168  GU_SoftDistanceMetric metric,
169  const char *p_attr = "P",
170  const GEO_Detail::SoftSymmetryParms *symmetry = nullptr,
171  const GEO_Rolloff *rolloff = nullptr);
172 
173  int64 getMemoryUsage(bool inclusive) const;
174 private:
175  // validates whether the arguments to updateDistances() require recomputation
176  bool shouldUpdateDistances(const GEO_Detail &gdp,
177  fpreal radius,
178  GU_SoftDistanceMetric metric,
179  GA_ROHandleV3 p_attrib,
180  const GEO_Detail::SoftSymmetryParms *symmetry);
181 
182  bool hasSameTopology(const GEO_Detail &gdp) const;
183 
184  void updateSurfAndEdgeDistances(const GEO_Detail &gdp,
185  const GU_SurfaceDistance& surf_dist,
186  const GA_PointGroup *srcgroup,
187  fpreal radius,
188  GU_SoftDistanceMetric metric,
189  const GA_ROHandleV3 &p_attrib,
190  const GEO_Detail::SoftSymmetryParms *symmetry);
191 
192  // set of points with computed distances (and lead points)
193  GA_PointGroupUPtr myAffectedGroup;
194  // distance to the closest point in the input group
195  GA_AttributeUPtr myDistances;
196  // the point in the input group that the current point is closest to
197  GA_AttributeUPtr mySourcePoints;
198 
199  // values used to determine when to invalidate cached data
200  int64 myHitPrim;
201  UT_Vector3 myHitUV;
202  UT_Vector3 myHitPos;
203  GU_SoftDistanceMetric myMetric;
204  fpreal myRadius;
205  GA_DataId myGdpUniqueId;
206  GA_DataId myGdpPrimitiveId;
207  GA_DataId myGdpTopologyId;
208 
209  bool myHasSymmetryParms;
210  bool myHasPtGroup;
211  GEO_Detail::SoftSymmetryParms mySymmetryParms;
212  UT_String myPAttrib;
213  GA_OffsetArray myPts;
214 };
215 
216 // Utility class for measuring the distances along a surface from a point on the mesh
217 // to the point groups for the same mesh. Allows to compute distances to multiple point groups
218 // at the same time.
220  const GEO_Detail &gdp,
221  const GA_ROHandleV3 &p_attrib,
222  const GA_Offset &pt, // starting point
223  const UT_Array<GA_PointGroupUPtr> &psubset, // points we want to measure the distance to
224  int k, // stop when we find the k closest points for each group in the psubset
225  UT_Array<GA_PointGroupUPtr> &affectedgroups, // set of k closest points to pt with computed distances
226  GA_RWHandleF &h_dists); // distances from the pt to the points in the affectedgroups
227 #endif
GA_ROHandleF getDistances() const
void GU_API GU_FindDistancesToPointGroups(const GU_SurfaceDistance &sdist, const GEO_Detail &gdp, const GA_ROHandleV3 &p_attrib, const GA_Offset &pt, const UT_Array< GA_PointGroupUPtr > &psubset, int k, UT_Array< GA_PointGroupUPtr > &affectedgroups, GA_RWHandleF &h_dists)
void getVertexRange(exint pr, exint &start, exint &end) const
int64 GA_DataId
Definition: GA_Types.h:696
GLuint start
Definition: glcorearb.h:475
int64 exint
Definition: SYS_Types.h:125
exint nextVertex(exint vtx) const
const GA_PointGroup * getAffectedGroup() const
GA_ROHandleT< int64 > GA_ROHandleID
Definition: GA_Handle.h:1408
exint vertexPrimitive(exint vtx) const
#define GA_INVALID_OFFSET
Definition: GA_Types.h:687
GA_Size GA_Offset
Definition: GA_Types.h:646
GA_ROHandleID getSourcePoints() const
exint firstVertex(GA_Offset pt) const
GLuint GLuint end
Definition: glcorearb.h:475
GA_ROHandleT< fpreal32 > GA_ROHandleF
Definition: GA_Handle.h:1375
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
GU_SoftDistanceMetric
long long int64
Definition: SYS_Types.h:116
bool getAsPolylines() const
GA_Offset vertexPoint(exint vtx) const
#define GU_API
Definition: GU_API.h:14
std::function< T > UT_Function
Definition: UT_Function.h:37
exint append()
Definition: UT_Array.h:142
UT_UniquePtr< GA_Attribute > GA_AttributeUPtr
Definition: GA_Attribute.h:943
GLenum func
Definition: glcorearb.h:783
fpreal64 fpreal
Definition: SYS_Types.h:278
LeafData & operator=(const LeafData &)=delete
UT_UniquePtr< GA_PointGroup > GA_PointGroupUPtr
exint getNumPrimitives() const
GLenum src
Definition: glcorearb.h:1793