HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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  if (myGdp)
19  {
20  while (myPrimIndex < myGdp->getNumPrimitives())
21  {
22  myPrimitive =
23  myGdp->getGEOPrimitive(myGdp->primitiveOffset(myPrimIndex));
24 
25  // Ignore invalid primitives and broken constraints. There also
26  // must be subdata attached in order to get any attribute values.
27  if (myPrimitive->getVertexCount() == 2 &&
28  !(myBrokenGroup && myBrokenGroup->contains(myPrimitive)) &&
30  {
31  break;
32  }
33  ++myPrimIndex;
34  }
35  }
36 }
37 
38 inline void
40 {
41  myPrimIndex = 0;
42  myConstraintIndex = 0;
43  skipInvalid();
44 }
45 
46 inline bool
48 {
49  return !myGdp || myPrimIndex >= myGdp->getNumPrimitives();
50 }
51 
52 inline void
54 {
55  ++myPrimIndex;
56  ++myConstraintIndex;
57  skipInvalid();
58 }
59 
60 inline GA_Offset
62 {
63  return myPrimitive->getMapOffset();
64 }
65 
66 inline ConstraintType
68 {
69  // If the 'constraint_type' attribute is missing, default to constraining
70  // position.
71  if (!myConstraintTypeRef.isValid())
73 
74  const GA_StringIndexType idx =
75  myConstraintTypeRef.getIndex(myPrimitive->getMapOffset());
76  if (idx == GA_INVALID_STRING_INDEX)
78 
79  UT_ASSERT_P(idx < myConstraintTypes.entries());
80  return myConstraintTypes[idx];
81 }
82 
83 inline GA_Offset
84 const_iterator::getPointOffset(bool anchor1) const
85 {
86  return myPrimitive->getPointOffset(anchor1 ? 1 : 0);
87 }
88 
89 inline GA_Index
90 const_iterator::getPointNumber(bool anchor1) const
91 {
92  return myGdp->pointIndex(getPointOffset(anchor1));
93 }
94 
95 inline GA_Index
97 {
98  const CachedObjectData *data = getCachedData(anchor1);
99  GA_Offset off = getAnchorPointOffset(anchor1, data);
100 
101  return off == GA_INVALID_OFFSET ? GA_INVALID_INDEX :
102  data->getGdp()->pointIndex(off);
103 }
104 
105 inline int
107 {
108  return myNumDOFsRef.isValid() ? myNumDOFsRef.get(getPointOffset(anchor1)) :
109  3;
110 }
111 
112 inline UT_Vector3
114 {
115  return myDOFVectorRef.isValid() ?
116  myDOFVectorRef.get(getPointOffset(anchor1)) :
117  UT_Vector3(0, 1, 0);
118 }
119 
120 inline UT_StringHolder
121 const_iterator::getAnchorName(bool anchor1) const
122 {
123  return myNameRef.isValid() ?
124  UT_StringHolder(myNameRef.get(getPointOffset(anchor1))) :
126 }
127 
128 inline int
129 const_iterator::getAnchorId(bool anchor1) const
130 {
131  return myAnchorIdRef.isValid() ?
132  GA_Index(myAnchorIdRef.get(getPointOffset(anchor1))) :
134 }
135 
136 inline UT_Quaternion
137 const_iterator::getInitialAnchorOrientation(bool anchor1) const
138 {
139  if (myOrientRef.isValid())
140  return myOrientRef.get(getPointOffset(anchor1));
141  else if (myRotationRef.isValid())
142  {
143  UT_Vector3 rotation = myRotationRef.get(getPointOffset(anchor1));
144  rotation.degToRad();
145  UT_XformOrder order;
146  return UT_Quaternion(rotation, order);
147  }
148  else
149  return UT_Quaternion(0, 0, 0, 1);
150 }
151 
152 // The type of position depends on whwther the 'name' and 'point_id' point
153 // attributes are defined on the constraint network geometry.
154 // If the 'name' and 'point_id' together refer to a valid point on a simulation
155 // object, then POSITION_GEOMETRYPOINT is returned.
156 // If the 'name' refers to a valid object, and 'point_id' wither doesnt exist,
157 // or is -1, then POSITION_RELATIVEOFFSET is returned.
158 // Otherwise POSITION_WORLDSPACE is returned.
159 inline PositionType
161 {
163 
164  // If there is no name specified, we just have a world space position.
165  // Otherwise, check whether this is a relative position or an actual point
166  // on the geometry.
167  const CachedObjectData *data = getCachedData(anchor1);
168  if (data)
169  {
170  // Look up point offset of pointid on named object
171  const GA_Offset ptoff = getAnchorPointOffset(anchor1, data);
172  const AnchorType anchor_type = getAnchorType(anchor1);
173 
174  if (anchor_type == AnchorType::Agent &&
175  (myLocalPosRef.isValid() || myLocalOrientRef.isValid()))
176  {
178  }
179  else if (ptoff != GA_INVALID_OFFSET)
181  else if (getAnchorId(anchor1) == -1)
183  }
184 
185  return type;
186 }
187 
188 inline GA_StringIndexType
189 const_iterator::getAnchorNameIndex(bool anchor1) const
190 {
191  return myNameRef.isValid() ? myNameRef.getIndex(getPointOffset(anchor1)) :
193 }
194 
195 inline const const_iterator::CachedObjectData *
196 const_iterator::getCachedData(bool anchor1) const
197 {
198  const CachedObjectData *data = nullptr;
199  GA_StringIndexType str_idx = getAnchorNameIndex(anchor1);
200  if (str_idx >= 0 && str_idx < myCachedData.entries())
201  data = myCachedData(str_idx).get();
202 
203  return data;
204 }
205 
206 template <typename T, typename Detail, typename AttributeRef>
207 void
208 const_iterator::get(const UT_StringRef &attribute_name, Detail &gdp,
209  UT_StringMap<AttributeRef> &cache, T &value) const
210 {
211  // If the primitive attribute doesn't exist, look for the attribute on the
212  // SIM_ConRel subdata.
213  if (!getPrimitiveAttribute(attribute_name, gdp, cache, value))
214  value = getDataOption<T>(attribute_name);
215 }
216 
217 template <typename Detail, typename AttributeRef>
218 void
219 const_iterator::get(const UT_StringRef &attribute_name, Detail &gdp,
220  UT_StringMap<AttributeRef> &cache, fpreal &value) const
221 {
222  value = getDataOption<fpreal>(attribute_name);
223 
224  fpreal attrib_value = 0;
225  if (getPrimitiveAttribute(attribute_name, gdp, cache, attrib_value))
226  value *= attrib_value;
227 }
228 
229 template <typename T, typename Detail, typename AttributeRef>
230 bool
232  Detail &gdp,
234  T &value) const
235 {
236  // First, look for a cached attribute reference.
238  cache.find(attribute_name);
239  if (it != cache.end())
240  {
241  if (it->second.isValid())
242  {
243  GA_ROHandleT<T> h(it->second);
244  if (h.isValid())
245  {
246  value = h.get(myPrimitive->getMapOffset());
247  return true;
248  }
249  }
250 
251  return false;
252  }
253  else
254  {
255  // Otherwise, look up the attribute. Even if it's invalid, we still
256  // want to cache that result so that we don't try to look for it again.
257  AttributeRef attrib =
258  gdp.findPrimitiveAttribute(GA_SCOPE_PUBLIC, attribute_name);
259  cache.emplace(attribute_name, attrib);
260 
261  if (attrib.isValid())
262  {
263  GA_ROHandleT<T> h(attrib);
264  if (h.isValid())
265  {
266  value = h.get(myPrimitive->getMapOffset());
267  return true;
268  }
269  }
270 
271  return false;
272  }
273 }
274 
275 inline const SIM_Data *
277 {
278  const GA_StringIndexType idx =
279  myConstraintNameRef.getIndex(myPrimitive->getMapOffset());
280  UT_ASSERT_P(idx < myConstraintDataCache.entries());
281  return idx >= 0 ? myConstraintDataCache(idx).first : 0;
282 }
283 
284 /// Retrieve a value from the attached subdata for the constraint.
285 template <typename T>
286 T
287 const_iterator::getDataOption(const UT_StringRef &attribute_name) const
288 {
289  const GA_StringIndexType idx =
290  myConstraintNameRef.getIndex(myPrimitive->getMapOffset());
292  idx < myConstraintDataCache.entries());
293  const SIM_OptionsUser *data = myConstraintDataCache(idx).second;
294 
295  T value;
296  getOption(data, attribute_name, value);
297  return value;
298 }
299 
300 template <typename T>
301 T
303  const T &default_value) const
304 {
305  if (!myGdp)
306  return default_value;
307 
308  GA_ROHandleT<T> attrib(
309  myGdp->findGlobalAttribute(GA_SCOPE_PUBLIC, attribute_name));
310 
311  return attrib.isValid() ? attrib.get(GA_DETAIL_OFFSET) : default_value;
312 }
313 }
314 
315 #endif
PositionType
How the position of the anchor is interpreted.
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GA_Primitive.h:249
SYS_FORCE_INLINE const GA_Attribute * findGlobalAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:978
SYS_FORCE_INLINE GA_Size getVertexCount() const
Return the number of vertices used by this primitive.
Definition: GA_Primitive.h:227
UT_Vector3T< float > UT_Vector3
Standard user attribute level.
Definition: GA_Types.h:127
bool getPrimitiveAttribute(const UT_StringRef &attribute_name, T &value) const
Retrieve a value from a primitive attribute of the constraint.
T get(const UT_StringRef &attribute_name) const
void degToRad()
conversion between degrees and radians
PositionType getAnchorPositionType(bool anchor1) const
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:101
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:917
SYS_FORCE_INLINE GEO_Primitive * getGEOPrimitive(GA_Offset primoff)
Definition: GEO_Detail.h:1089
GA_Size GA_Offset
Definition: GA_Types.h:617
UT_StringHolder getAnchorName(bool anchor1) const
static const UT_StringHolder theEmptyString
GA_Offset getAnchorPointOffset(bool anchor1) const
T getDetailAttribute(const UT_StringRef &attribute_name, const T &default_value) const
#define GA_INVALID_STRING_INDEX
SYS_FORCE_INLINE T get(GA_Offset off, int comp=0) const
Definition: GA_Handle.h:194
SYS_FORCE_INLINE bool isValid() const
Definition: GA_Handle.h:912
GLboolean * data
Definition: glcorearb.h:130
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 bool isValid() const
Definition: GA_Handle.h:185
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:446
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
Definition: GA_Detail.h:296
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:925
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:269
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.
SYS_FORCE_INLINE GA_Offset primitiveOffset(GA_Index index) const
Given a primitive's index (in append order), return its data offset.
Definition: GA_Detail.h:359
SYS_FORCE_INLINE GA_Offset getMapOffset() const
Gets the offset of this primitive in the detail containing it.
Definition: GA_Primitive.h:137
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
Definition: GA_Detail.h:348
GA_BlobIndex GA_StringIndexType
#define GA_INVALID_INDEX
Definition: GA_Types.h:653
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
GA_Index getPointNumber(bool anchor1) const
The point number for this anchor in the constraint network geometry.
#define GA_DETAIL_OFFSET
Definition: GA_Types.h:658
GA_Offset getPrimOffset() const
The primitive offset.
Parent::const_iterator const_iterator
Definition: UT_StringMap.h:50
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:169