HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 
22 #include <GEO/GEO_Detail.h>
23 
24 #include <UT/UT_PriorityQueue.h>
25 
26 #include <tuple>
27 
28 #define ONE_PLUS_TOLERANCE 1.000001
29 
30 class GA_PointGroup;
31 class SoftSymmetryParms;
32 
33 
34 // keep this synced with the parameter in $PRM/PRM_Shared.C
36 {
41  GU_SOFT_METRIC_INVALID
42 };
43 
44 // comparator functors for priority queue for use in computeSurfaceDistance
45 // modelled on the ones used in SOP_FindShortestPath
46 
47 // SurfaceDistanceQueueEntry: the type parameters represent
48 // distance, point offset, root point index
49 typedef std::tuple<fpreal, GA_Offset, GA_Index> GU_SurfaceDistanceQueueEntry;
50 
52 {
53 public:
56  const GU_SurfaceDistanceQueueEntry& p2) const
57  {
58  // NOTE: UT_PriorityQueue is a *max* heap, so the comparison
59  // direction is backwards
60  // NOTE: The second conditions order from smallest offset to largest
61  // offset in cases of equal or almost-equal path lengths.
62  // NOTE: The second tie breaker is whichever has a smaller source ptoff
63  // which comes up on perfect grids or highly symmetric models
64  fpreal dist1 = std::get<0>(p1);
65  GA_Offset ptoff1 = std::get<1>(p1);
66  fpreal dist2 = std::get<0>(p2);
67  GA_Offset ptoff2 = std::get<1>(p2);
68 
69  return (dist1 > ONE_PLUS_TOLERANCE * dist2)
70  || ((ONE_PLUS_TOLERANCE * dist1 > dist2)
71  && (ptoff1 > ptoff2));
72  }
73 };
74 
75 // Contains all the data used by GUsurfaceDistance method. It can be held and
76 // passed in by a SOP that wants to save time on repeated calls, typically due
77 // to small increases or decreases in the radius.
78 // The data in this class is only modifiable by GUsurfaceDistance
80 {
81 public:
83 
85  {
86  delete myDistances;
87  delete mySourcePoints;
88  delete myQueue;
89 
90  if (myAffectedGroup == myMaxAffectedGroup)
91  {
92  myMaxAffectedGroup = NULL;
93  }
94  delete myAffectedGroup;
95  delete myMaxAffectedGroup;
96  }
97 
98  // implicit cast to super class because we don't want anyone else messing
99  // with our distances
100  const GA_ROHandleF* getDistances() { return myDistances; }
101 
102  // ditto ^
103  const GA_ROHandleID* getSourcePoints() { return mySourcePoints; }
104 
105  const GA_PointGroup* getAffectedGroup() { return myAffectedGroup; }
106 
107  GU_SoftDistanceMetric getPrevMetric() { return myPrevMetric; }
109 private:
110  void initialize(GEO_Detail* gdp);
111  void reset(GEO_Detail* gdp);
112 
113  // the point in the input group that the current point is closest to
114  GA_RWHandleID* mySourcePoints;
117  false>* myQueue;
118  GA_PointGroup* myAffectedGroup;
119  GA_PointGroup* myMaxAffectedGroup;
120 
121  float myPrevRadius;
122  GU_SoftDistanceMetric myPrevMetric;
123 
124  // cache data ids so if the input gdp changed, we need to reset the surface
125  // distance cache
126  exint myGdpPositionId;
127  exint myGdpPrimitiveId;
128  exint myGdpTopologyId;
129 
130  friend void GU_API GUsurfaceDistance(GEO_Detail*, const GA_Group*,
131  const fpreal, const GU_SoftDistanceMetric,
133  const GEO_Rolloff* rolloff,
135  friend void guSurfaceDistance(GEO_Detail*, const GA_Group*,
136  const fpreal, const GU_SoftDistanceMetric,
139 };
140 
141 // computes distance radiating out from the input group, limited to radius size.
142 //
143 // cache can be stored and then passed in again the next time you need to
144 // compute the surface distance to save time when increasing or decreasing the
145 // radius. It is the caller's responsibility to reset the cache if the input
146 // group, or the symmetry plane changes. See SOP_SoftTransform for an example.
147 //
148 // Note that this is an approximation and does not compute the exact geodesic
149 // distance, as that is computationally expensive.
150 //
151 // symmetry - the distance is cut off by the symmetry plane, and if a point on
152 // the symmetry plane is in the input group, it will calculate
153 // distance in the positive direction of the plane normal only
155  GEO_Detail* gdp,
156  const GA_Group* srcptgroup,
157  const fpreal radius,
158  const GU_SoftDistanceMetric metric,
160  const GEO_Rolloff* rolloff = NULL,
161  const GEO_Detail::SoftSymmetryParms* symmetry = NULL);
162 
163 #endif
GU_SoftDistanceMetric getPrevMetric()
enum GU_API GU_SoftDistanceMetric
void GU_API GUsurfaceDistance(GEO_Detail *gdp, const GA_Group *srcptgroup, const fpreal radius, const GU_SoftDistanceMetric metric, GU_SurfaceDistanceCache &cache, const GEO_Rolloff *rolloff=NULL, const GEO_Detail::SoftSymmetryParms *symmetry=NULL)
bool operator()(const GU_SurfaceDistanceQueueEntry &p1, const GU_SurfaceDistanceQueueEntry &p2) const
#define ONE_PLUS_TOLERANCE
const GA_PointGroup * getAffectedGroup()
GU_SOFT_DISTANCE_ALONG_CONNECTED_EDGES
GA_Size GA_Offset
Definition: GA_Types.h:617
int64 exint
Definition: SYS_Types.h:109
const GA_ROHandleID * getSourcePoints()
GU_SOFT_GLOBAL_DISTANCE_WITH_CONNECTIVITY
std::tuple< fpreal, GA_Offset, GA_Index > GU_SurfaceDistanceQueueEntry
#define GU_API
Definition: GU_API.h:11
OPENVDB_API void initialize()
Global registration of basic types.
Definition: logging.h:316
GU_SOFT_SURFACE_DISTANCE
double fpreal
Definition: SYS_Types.h:263
const GA_ROHandleF * getDistances()
GU_SOFT_GLOBAL_DISTANCE