HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_ConstraintNetworkIteratorImpl.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 
7 #ifndef __SIM_ConstraintNetworkIteratorImpl_h__
8 #define __SIM_ConstraintNetworkIteratorImpl_h__
9 
10 #include <GA/GA_Primitive.h>
11 #include <GU/GU_Detail.h>
12 
13 namespace SIM_ConstraintNetwork
14 {
15 inline void
16 const_iterator::skipInvalid()
17 {
18  while (!myPrimIterator.atEnd())
19  {
20  myPrimOffset = *myPrimIterator;
21 
22  myConstraintDataIndex = myConstraintNameRef.getIndex(myPrimOffset);
23 
24  // Ignore invalid primitives and broken constraints. There also
25  // must be subdata attached in order to get any attribute values.
26  if ((myConstraintDataIndex >= 0
27  && myValidConstraintData.getBitFast(myConstraintDataIndex))
28  && !(myBrokenGroup && myBrokenGroup->contains(myPrimOffset)))
29  {
30  GA_OffsetListRef vertices = myGdp->getPrimitiveVertexList(
31  myPrimOffset);
32  if (vertices.size() == 2)
33  {
34  myPtAOffset = myGdp->vertexPoint(vertices[0]);
35  myPtBOffset = myGdp->vertexPoint(vertices[1]);
36  break;
37  }
38  }
39 
40  myPrimIterator.advance();
41  }
42 }
43 
44 inline void
46 {
47  myPrimIterator.rewind();
48  myConstraintIndex = 0;
49 
50  if (myGdp)
51  skipInvalid();
52 }
53 
54 inline bool
56 {
57  return !myGdp || myPrimIterator.atEnd();
58 }
59 
60 inline void
62 {
63  myPrimIterator.advance();
64  ++myConstraintIndex;
65 
66  skipInvalid();
67 }
68 
69 inline GA_Index
71 {
72  return myGdp->primitiveIndex(myPrimOffset);
73 }
74 
75 inline ConstraintType
77 {
78  // If the 'constraint_type' attribute is missing, default to constraining
79  // position.
80  if (!myConstraintTypeRef.isValid())
82 
83  const GA_StringIndexType idx = myConstraintTypeRef.getIndex(myPrimOffset);
84  if (idx == GA_INVALID_STRING_INDEX)
86 
87  UT_ASSERT_P(idx < myConstraintTypes.entries());
88  return myConstraintTypes[idx];
89 }
90 
92 const_iterator::getPointOffset(bool anchor1) const
93 {
94  return anchor1 ? myPtBOffset : myPtAOffset;
95 }
96 
97 inline GA_Index
98 const_iterator::getPointNumber(bool anchor1) const
99 {
100  return myGdp->pointIndex(getPointOffset(anchor1));
101 }
102 
103 inline exint
105 {
106  // This function should only be called when the iterator is on a valid
107  // constraint primitive.
108  UT_ASSERT_P(myConstraintDataIndex >= 0);
109  return myConstraintDataIndex;
110 }
111 
112 inline void
114 {
115  myConstraintDataIndex = constraint_idx;
116  myPrimOffset = primoff;
117 }
118 
119 inline const SIM_Data *
121 {
122  return myConstraintData[myConstraintDataIndex];
123 }
124 
125 template <typename T>
126 T
127 GenericConstraintAccessor::get(const UT_StringRef &attribute_name) const
128 {
129  T value;
130  get(attribute_name, *myGdp, myCachedAttributes, value);
131  return value;
132 }
133 
134 template <typename T>
135 T
137  const UT_StringRef &attribute_name) const
138 {
139  const SIM_OptionsUser *options =
140  myConstraintDataOptions[myConstraintDataIndex];
141 
142  T value;
143  getOption(options, attribute_name, value);
144  return value;
145 }
146 
147 template <typename T>
148 bool
150  const UT_StringRef &attribute_name, T &value) const
151 {
152  return getPrimitiveAttribute(
153  attribute_name, *myGdp, myCachedAttributes, value);
154 }
155 
156 template <typename T>
157 bool
159  const UT_StringRef &attribute_name, const GU_Detail &gdp,
160  AttribCache &cache, T &value) const
161 {
162  // First, look for a cached attribute reference.
163  auto it = cache.find(attribute_name);
164  if (it != cache.end())
165  {
166  if (it->second)
167  {
168  GA_ROHandleT<T> h(it->second);
169  if (h.isValid())
170  {
171  value = h.get(myPrimOffset);
172  return true;
173  }
174  }
175 
176  return false;
177  }
178  else
179  {
180  // Otherwise, look up the attribute. Even if it's invalid, we still
181  // want to cache that result so that we don't try to look for it again.
182  const GA_Attribute *attrib = gdp.findPrimitiveAttribute(attribute_name);
183  cache.emplace(attribute_name, attrib);
184 
185  if (attrib)
186  {
187  GA_ROHandleT<T> h(attrib);
188  if (h.isValid())
189  {
190  value = h.get(myPrimOffset);
191  return true;
192  }
193  }
194 
195  return false;
196  }
197 }
198 
199 template <typename T>
200 void
202  const UT_StringRef &attribute_name, const GU_Detail &gdp,
203  AttribCache &cache, T &value) const
204 {
205  // If the primitive attribute doesn't exist, look for the attribute on the
206  // SIM_ConRel subdata.
207  if (!getPrimitiveAttribute(attribute_name, gdp, cache, value))
208  value = getDataOption<T>(attribute_name);
209 }
210 
211 inline void
213  const UT_StringRef &attribute_name, const GU_Detail &gdp,
214  AttribCache &cache, fpreal &value) const
215 {
216  value = getDataOption<fpreal>(attribute_name);
217 
218  fpreal attrib_value = 0;
219  if (getPrimitiveAttribute(attribute_name, gdp, cache, attrib_value))
220  value *= attrib_value;
221 }
222 
223 inline GA_Index
225 {
226  const CachedObjectData *data = getCachedData(anchor1);
227  GA_Offset off = getAnchorPointOffset(anchor1, data);
228 
229  return off == GA_INVALID_OFFSET ? GA_INVALID_INDEX :
230  data->getGdp()->pointIndex(off);
231 }
232 
233 inline int
235 {
236  return myNumDOFsRef.isValid() ? myNumDOFsRef.get(getPointOffset(anchor1)) :
237  3;
238 }
239 
240 inline UT_Vector3
242 {
243  return myDOFVectorRef.isValid() ?
244  myDOFVectorRef.get(getPointOffset(anchor1)) :
245  UT_Vector3(0, 1, 0);
246 }
247 
248 inline const UT_StringHolder &
250 {
251  return myNameRef.isValid() ? myNameRef.get(getPointOffset(anchor1)) :
253 }
254 
255 inline int
256 GenericAnchorAccessor::getAnchorId(bool anchor1) const
257 {
258  return myAnchorIdRef.isValid() ?
259  GA_Index(myAnchorIdRef.get(getPointOffset(anchor1))) :
261 }
262 
263 inline UT_Quaternion
264 GenericAnchorAccessor::getInitialAnchorOrientation(bool anchor1) const
265 {
266  if (myOrientRef.isValid())
267  return myOrientRef.get(getPointOffset(anchor1));
268  else if (myRotationRef.isValid())
269  {
270  UT_Vector3 rotation = myRotationRef.get(getPointOffset(anchor1));
271  rotation.degToRad();
272  UT_XformOrder order;
273  return UT_Quaternion(rotation, order);
274  }
275  else
276  return UT_Quaternion(0, 0, 0, 1);
277 }
278 
279 // The type of position depends on whwther the 'name' and 'point_id' point
280 // attributes are defined on the constraint network geometry.
281 // If the 'name' and 'point_id' together refer to a valid point on a simulation
282 // object, then POSITION_GEOMETRYPOINT is returned.
283 // If the 'name' refers to a valid object, and 'point_id' wither doesnt exist,
284 // or is -1, then POSITION_RELATIVEOFFSET is returned.
285 // Otherwise POSITION_WORLDSPACE is returned.
286 inline PositionType
288 {
290 
291  // If there is no name specified, we just have a world space position.
292  // Otherwise, check whether this is a relative position or an actual point
293  // on the geometry.
294  const CachedObjectData *data = getCachedData(anchor1);
295  if (data)
296  {
297  // Look up point offset of pointid on named object
298  const GA_Offset ptoff = getAnchorPointOffset(anchor1, data);
299  const AnchorType anchor_type = getAnchorType(anchor1);
300 
301  if (anchor_type == AnchorType::Agent &&
302  (myLocalPosRef.isValid() || myLocalOrientRef.isValid()))
303  {
305  }
306  else if (ptoff != GA_INVALID_OFFSET)
308  else if (getAnchorId(anchor1) == -1)
310  }
311 
312  return type;
313 }
314 
315 inline GA_StringIndexType
316 GenericAnchorAccessor::getAnchorNameIndex(bool anchor1) const
317 {
318  return myNameRef.isValid() ? myNameRef.getIndex(getPointOffset(anchor1)) :
320 }
321 
322 inline const GenericAnchorAccessor::CachedObjectData *
323 GenericAnchorAccessor::getCachedData(bool anchor1) const
324 {
325  const CachedObjectData *data = nullptr;
326  GA_StringIndexType str_idx = getAnchorNameIndex(anchor1);
327  if (str_idx >= 0 && str_idx < myCachedData.entries())
328  data = myCachedData(str_idx).get();
329 
330  return data;
331 }
332 
333 }
334 
335 #endif
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
PositionType
How the position of the anchor is interpreted.
bool getBitFast(exint index) const
Definition: UT_BitArray.h:317
GA_Offset getAnchorPointOffset(bool anchor1) const
UT_Vector3T< float > UT_Vector3
bool getPrimitiveAttribute(const UT_StringRef &attribute_name, T &value) const
ConstraintType getConstraintType() const
Returns whether the constraint affects position / rotation / all.
void degToRad()
conversion between degrees and radians
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
SYS_FORCE_INLINE const UT_StringHolder & get(GA_Offset off, int comp=0) const
Get the string at the given offset.
Definition: GA_Handle.h:808
GA_Size GA_Offset
Definition: GA_Types.h:617
bool atEnd() const
Definition: GA_Iterator.h:100
void advance(exint constraint_idx, GA_Offset primoff)
Update the current constraint data type index and primitive offset.
SYS_FORCE_INLINE GA_Index primitiveIndex(GA_Offset offset) const
Given a primitive's data offset, return its index.
Definition: GA_Detail.h:367
int64 exint
Definition: SYS_Types.h:116
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:125
static const UT_StringHolder theEmptyString
SYS_FORCE_INLINE GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const
Definition: GA_Primitive.h:796
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
void rewind()
const UT_StringHolder & getAnchorName(bool anchor1) const
exint getConstraintDataIndex() const
Returns the index of the current constraint data type.
#define GA_INVALID_STRING_INDEX
SYS_FORCE_INLINE T get(GA_Offset off, int comp=0) const
Definition: GA_Handle.h:191
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
Definition: GA_Detail.h:473
SYS_FORCE_INLINE bool isValid() const
Definition: GA_Handle.h:803
GLboolean * data
Definition: glcorearb.h:130
GA_Index getPrimIndex() const
The primitive index.
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
bool contains(const GA_Primitive *prim) const
SYS_FORCE_INLINE const GA_Attribute * findPrimitiveAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:984
SYS_FORCE_INLINE bool isValid() const
Definition: GA_Handle.h:182
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:453
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
Definition: GA_Detail.h:300
SYS_FORCE_INLINE GA_StringIndexType getIndex(GA_Offset off, int comp=0) const
Get the string index at the given offset.
Definition: GA_Handle.h:816
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:270
ConstraintType
The type of a constraint (linear, angular, or both).
UT_QuaternionT< fpreal32 > UT_Quaternion
T getDataOption(const UT_StringRef &attribute_name) const
Retrieve a value from the attached subdata for the constraint.
GA_BlobIndex GA_StringIndexType
#define GA_INVALID_INDEX
Definition: GA_Types.h:653
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
void advance()
Definition: GA_Iterator.h:101
GA_Index getPointNumber(bool anchor1) const
The point number for this anchor in the constraint network geometry.
GA_Offset getPointOffset(bool anchor1) const
The point offset for this anchor in the constraint network geometry.
SYS_FORCE_INLINE FromType size() const
Returns the number of used elements in the list (always <= capacity())
MatType rotation(const Quat< typename MatType::value_type > &q, typename MatType::value_type eps=static_cast< typename MatType::value_type >(1.0e-8))
Return the rotation matrix specified by the given quaternion.
Definition: Mat.h:204