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  && !(mySkipBroken && myBrokenGroup
29  && myBrokenGroup->contains(myPrimOffset)))
30  {
31  GA_OffsetListRef vertices = myGdp->getPrimitiveVertexList(
32  myPrimOffset);
33  if (vertices.size() == 2)
34  {
35  myPtAOffset = myGdp->vertexPoint(vertices[0]);
36  myPtBOffset = myGdp->vertexPoint(vertices[1]);
37  break;
38  }
39  }
40 
41  myPrimIterator.advance();
42  }
43 }
44 
45 inline void
47 {
48  myPrimIterator.rewind();
49  myConstraintIndex = 0;
50 
51  if (myGdp)
52  skipInvalid();
53 }
54 
55 inline bool
57 {
58  return !myGdp || myPrimIterator.atEnd();
59 }
60 
61 inline void
63 {
64  myPrimIterator.advance();
65  ++myConstraintIndex;
66 
67  skipInvalid();
68 }
69 
70 inline GA_Index
72 {
73  return myGdp->primitiveIndex(myPrimOffset);
74 }
75 
76 inline bool
78 {
79  return myBrokenGroup && myBrokenGroup->contains(myPrimOffset);
80 }
81 
82 inline ConstraintType
84 {
85  // If the 'constraint_type' attribute is missing, default to constraining
86  // position.
87  if (!myConstraintTypeRef.isValid())
89 
90  const GA_StringIndexType idx = myConstraintTypeRef.getIndex(myPrimOffset);
91  if (idx == GA_INVALID_STRING_INDEX)
93 
94  UT_ASSERT_P(idx < myConstraintTypes.entries());
95  return myConstraintTypes[idx];
96 }
97 
99 const_iterator::getPointOffset(bool anchor1) const
100 {
101  return anchor1 ? myPtBOffset : myPtAOffset;
102 }
103 
104 inline GA_Index
106 {
107  return myGdp->pointIndex(getPointOffset(anchor1));
108 }
109 
110 inline exint
112 {
113  // This function should only be called when the iterator is on a valid
114  // constraint primitive.
115  UT_ASSERT_P(myConstraintDataIndex >= 0);
116  return myConstraintDataIndex;
117 }
118 
119 inline void
121 {
122  myConstraintDataIndex = constraint_idx;
123  myPrimOffset = primoff;
124 }
125 
126 inline const SIM_Data *
128 {
129  return myConstraintData[myConstraintDataIndex];
130 }
131 
132 template <typename T>
133 T
134 GenericConstraintAccessor::get(const UT_StringRef &attribute_name) const
135 {
136  T value;
137  get(attribute_name, *myGdp, myCachedAttributes, value);
138  return value;
139 }
140 
141 template <typename T>
142 T
144  const UT_StringRef &attribute_name) const
145 {
146  const SIM_OptionsUser *options =
147  myConstraintDataOptions[myConstraintDataIndex];
148 
149  T value;
150  getOption(options, attribute_name, value);
151  return value;
152 }
153 
154 template <typename T>
155 bool
157  const UT_StringRef &attribute_name, T &value) const
158 {
159  return getPrimitiveAttribute(
160  attribute_name, *myGdp, myCachedAttributes, value);
161 }
162 
163 template <typename T>
164 bool
166  const UT_StringRef &attribute_name, const GU_Detail &gdp,
167  AttribCache &cache, T &value) const
168 {
169  // First, look for a cached attribute reference.
170  auto it = cache.find(attribute_name);
171  if (it != cache.end())
172  {
173  if (it->second)
174  {
175  GA_ROHandleT<T> h(it->second);
176  if (h.isValid())
177  {
178  value = h.get(myPrimOffset);
179  return true;
180  }
181  }
182 
183  return false;
184  }
185  else
186  {
187  // Otherwise, look up the attribute. Even if it's invalid, we still
188  // want to cache that result so that we don't try to look for it again.
189  const GA_Attribute *attrib = gdp.findPrimitiveAttribute(attribute_name);
190  cache.emplace(attribute_name, attrib);
191 
192  if (attrib)
193  {
194  GA_ROHandleT<T> h(attrib);
195  if (h.isValid())
196  {
197  value = h.get(myPrimOffset);
198  return true;
199  }
200  }
201 
202  return false;
203  }
204 }
205 
206 template <typename T>
207 void
209  const UT_StringRef &attribute_name, const GU_Detail &gdp,
210  AttribCache &cache, T &value) const
211 {
212  // If the primitive attribute doesn't exist, look for the attribute on the
213  // SIM_ConRel subdata.
214  if (!getPrimitiveAttribute(attribute_name, gdp, cache, value))
215  value = getDataOption<T>(attribute_name);
216 }
217 
218 inline void
220  const UT_StringRef &attribute_name, const GU_Detail &gdp,
221  AttribCache &cache, fpreal &value) const
222 {
223  value = getDataOption<fpreal>(attribute_name);
224 
225  fpreal attrib_value = 0;
226  if (getPrimitiveAttribute(attribute_name, gdp, cache, attrib_value))
227  value *= attrib_value;
228 }
229 
230 inline GA_Index
232 {
233  const CachedObjectData *data = getCachedData(anchor1);
234  GA_Offset off = getAnchorPointOffset(anchor1, data);
235 
236  return off == GA_INVALID_OFFSET ? GA_INVALID_INDEX :
237  data->getGdp()->pointIndex(off);
238 }
239 
240 inline int
242 {
243  return myNumDOFsRef.isValid() ? myNumDOFsRef.get(getPointOffset(anchor1)) :
244  3;
245 }
246 
247 inline UT_Vector3
249 {
250  return myDOFVectorRef.isValid() ?
251  myDOFVectorRef.get(getPointOffset(anchor1)) :
252  UT_Vector3(0, 1, 0);
253 }
254 
255 inline const UT_StringHolder &
257 {
258  return myNameRef.isValid() ? myNameRef.get(getPointOffset(anchor1)) :
260 }
261 
262 inline int
263 GenericAnchorAccessor::getAnchorId(bool anchor1) const
264 {
265  return myAnchorIdRef.isValid() ?
266  GA_Index(myAnchorIdRef.get(getPointOffset(anchor1))) :
268 }
269 
270 inline UT_Quaternion
271 GenericAnchorAccessor::getInitialAnchorOrientation(bool anchor1) const
272 {
273  if (myOrientRef.isValid())
274  return myOrientRef.get(getPointOffset(anchor1));
275  else if (myRotationRef.isValid())
276  {
277  UT_Vector3 rotation = myRotationRef.get(getPointOffset(anchor1));
278  rotation.degToRad();
280  return UT_Quaternion(rotation, order);
281  }
282  else
283  return UT_Quaternion(0, 0, 0, 1);
284 }
285 
286 // The type of position depends on whwther the 'name' and 'point_id' point
287 // attributes are defined on the constraint network geometry.
288 // If the 'name' and 'point_id' together refer to a valid point on a simulation
289 // object, then POSITION_GEOMETRYPOINT is returned.
290 // If the 'name' refers to a valid object, and 'point_id' wither doesnt exist,
291 // or is -1, then POSITION_RELATIVEOFFSET is returned.
292 // Otherwise POSITION_WORLDSPACE is returned.
293 inline PositionType
295 {
297 
298  // If there is no name specified, we just have a world space position.
299  // Otherwise, check whether this is a relative position or an actual point
300  // on the geometry.
301  const CachedObjectData *data = getCachedData(anchor1);
302  if (data)
303  {
304  // Look up point offset of pointid on named object
305  const GA_Offset ptoff = getAnchorPointOffset(anchor1, data);
306  const AnchorType anchor_type = getAnchorType(anchor1);
307 
308  if (anchor_type == AnchorType::Agent &&
309  (myLocalPosRef.isValid() || myLocalOrientRef.isValid()))
310  {
312  }
313  else if (ptoff != GA_INVALID_OFFSET)
315  else if (getAnchorId(anchor1) == -1)
317  }
318 
319  return type;
320 }
321 
322 inline GA_StringIndexType
323 GenericAnchorAccessor::getAnchorNameIndex(bool anchor1) const
324 {
325  return myNameRef.isValid() ? myNameRef.getIndex(getPointOffset(anchor1)) :
327 }
328 
329 inline const GenericAnchorAccessor::CachedObjectData *
330 GenericAnchorAccessor::getCachedData(bool anchor1) const
331 {
332  const CachedObjectData *data = nullptr;
333  GA_StringIndexType str_idx = getAnchorNameIndex(anchor1);
334  if (str_idx >= 0 && str_idx < myCachedData.entries())
335  data = myCachedData(str_idx).get();
336 
337  return data;
338 }
339 
340 }
341 
342 #endif
SIM_API const UT_StringHolder anchor_type
Definition of a geometry attribute.
Definition: GA_Attribute.h:198
PositionType
How the position of the anchor is interpreted.
bool getBitFast(exint index) const
Definition: UT_BitArray.h:333
GA_Offset getAnchorPointOffset(bool anchor1) const
GLboolean * data
Definition: glcorearb.h:131
Transformation order of scales, rotates, and translates.
Definition: UT_XformOrder.h:23
GLsizei const GLfloat * value
Definition: glcorearb.h:824
UT_Vector3T< float > UT_Vector3
bool getPrimitiveAttribute(const UT_StringRef &attribute_name, T &value) const
int64 exint
Definition: SYS_Types.h:125
SYS_FORCE_INLINE bool isValid() const
Definition: GA_Handle.h:906
SYS_FORCE_INLINE const HOLDER & get(GA_Offset off, int comp=0) const
Get the string at the given offset.
Definition: GA_Handle.h:911
SYS_FORCE_INLINE INDEXTYPE getIndex(GA_Offset off, int comp=0) const
Get the string index at the given offset.
Definition: GA_Handle.h:919
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:678
GA_Size GA_Offset
Definition: GA_Types.h:641
bool atEnd() const
Definition: GA_Iterator.h:93
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:423
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
static const UT_StringHolder theEmptyString
SYS_FORCE_INLINE GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const
Definition: GA_Primitive.h:886
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
void rewind()
const UT_StringHolder & getAnchorName(bool anchor1) const
GLdouble GLdouble GLint GLint order
Definition: glad.h:2676
SIM_API const UT_StringHolder rotation
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:203
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
Definition: GA_Detail.h:529
GA_Index getPrimIndex() const
The primitive index.
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:635
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:1048
SYS_FORCE_INLINE bool isValid() const
Definition: GA_Handle.h:187
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:648
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
Definition: GA_Detail.h:349
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
ConstraintType
The type of a constraint (linear, angular, or both).
UT_QuaternionT< fpreal32 > UT_Quaternion
fpreal64 fpreal
Definition: SYS_Types.h:277
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:677
void advance()
Definition: GA_Iterator.h:94
Definition: core.h:1131
GA_Index getPointNumber(bool anchor1) const
The point number for this anchor in the constraint network geometry.
type
Definition: core.h:1059
GA_Offset getPointOffset(bool anchor1) const
The point offset for this anchor in the constraint network geometry.
Definition: format.h:895
SYS_FORCE_INLINE FromType size() const
Returns the number of used elements in the list (always <= capacity())