HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_ConstraintNetworkIterator.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_ConstraintNetworkIterator_h__
8 #define __SIM_ConstraintNetworkIterator_h__
9 
10 #include "SIM_API.h"
11 
12 #include "SIM_DataFilter.h"
13 #include "SIM_OptionsUser.h"
14 
15 #include <GA/GA_AttributeRef.h>
16 #include <GA/GA_Handle.h>
17 #include <GU/GU_DetailHandle.h>
18 #include <UT/UT_NonCopyable.h>
19 #include <UT/UT_StringMap.h>
20 #include <UT/UT_VectorTypes.h>
21 
22 class GA_Primitive;
23 class GA_PrimitiveGroup;
24 class GU_Detail;
26 class SIM_Data;
27 class SIM_Geometry;
29 class SIM_GeometryCopy;
30 class SIM_Object;
31 class SIM_Time;
32 
33 namespace SIM_ConstraintNetwork
34 {
35  /// The type of a constraint (linear, angular, or both).
36  enum class ConstraintType
37  {
38  Position,
39  Rotation,
40  All
41  };
42 
43  /// The type of anchor specfied by 'anchor_type' attribute. Defaults to
44  /// point.
45  enum class AnchorType
46  {
47  Point,
48  Vertex,
49  Agent
50  };
51 
52  /// How the position of the anchor is interpreted.
53  enum class PositionType
54  {
55  WorldSpace,
59  };
60 
61  /// Creates the 'force' and 'distance' primitive attributes.
64  /// Creates the 'torque' and 'angle' primitive attributes.
67  /// Returns the 'constraint_name' primitive attribute.
69 
70  /// Implements filtering of the constraint types that are recognized by the
71  /// caller, as well as caching / reading those constraint's parameter
72  /// values.
73  /// See @ref GenericConstraintAccessor for the default implementation.
75  {
76  public:
77  virtual ~ConstraintAccessor() {}
78 
79  /// Initialize with the constraint network's GU_Detail, and the number
80  /// of constraint types referenced by the geometry (from the
81  /// 'constraint_name' primitive attribute).
82  virtual void init(const GU_Detail *gdp, exint num_constraint_types) = 0;
83 
84  /// Returns whether the constraint type should be included when
85  /// iterating over the constraint network, and performs any necessary
86  /// caching with the constraint data and its index.
87  virtual bool acceptConstraint(const SIM_Data &constraint_data,
88  exint idx) = 0;
89  };
90 
91  /// Implements the mapping of anchors to objects recognized by the solver,
92  /// as well as evaluating anchor attributes (position, orientation, etc).
93  /// See @ref GenericAnchorAccessor for the default implementation.
95  {
96  public:
97  virtual ~AnchorAccessor() {}
98 
99  /// Initialize with the constraint network's GU_Detail and transform.
100  virtual bool init(
101  const GU_Detail &gdp, const UT_Matrix4D &xform,
102  const SIM_Data &container, const SIM_Data &data_root,
103  const SIM_Time &t) = 0;
104  };
105 
106  /// Returns false if there were no valid constraint data types (or nothing
107  /// matched the accessor's filter).
108  /// 'valid_constraint_data' indicates which string indices from the
109  /// constraint_name attribute have valid constraint data.
110  SIM_API bool
112  const GA_ROHandleS &constraint_name_attrib,
113  const SIM_Data &root_data,
114  ConstraintAccessor &constraint_accessor,
115  UT_BitArray &valid_constraint_data);
116 
118  {
119  public:
120  /// @param container A SIM_Relationship or SIM_Object that contains the
121  /// constraint network as subdata.
122  /// @param data_root Parent of the SIM_ConRel subdata.
123  const_iterator(const SIM_Data &container, const SIM_Data &data_root,
124  const SIM_Geometry *geo, const SIM_Time &t,
125  ConstraintAccessor &constraint_accessor,
126  AnchorAccessor &anchor_accessor);
127 
128  const_iterator(const SIM_Data &container, const SIM_Data &data_root,
129  const SIM_Geometry *geo, const GU_Detail *gdp,
130  const GA_PrimitiveGroup *broken_group, const SIM_Time &t,
131  ConstraintAccessor &constraint_accessor,
132  AnchorAccessor &anchor_accessor);
133 
134  void rewind();
135  bool atEnd() const;
136  void advance();
137 
138  /// The constraint network geometry.
139  const GU_Detail &getGdp() const { return *myGdp; }
140  /// The number of valid constraints that have been seen so far.
141  exint getConstraintIndex() const { return myConstraintIndex; }
142  /// The primitive index.
143  GA_Index getPrimIndex() const;
144  /// The primitive offset.
145  GA_Offset getPrimOffset() const { return myPrimOffset; }
146 
147  /// Returns the index of the current constraint data type.
148  exint getConstraintDataIndex() const;
149 
150  /// Returns whether the constraint affects position / rotation / all.
151  ConstraintType getConstraintType() const;
152 
153  /// The point offset for this anchor in the constraint network geometry.
154  GA_Offset getPointOffset(bool anchor1) const;
155 
156  /// The point number for this anchor in the constraint network geometry.
157  GA_Index getPointNumber(bool anchor1) const;
158 
159  private:
160  void init(
161  const SIM_Data &container, const SIM_Geometry &geo,
162  const GU_Detail &gdp, const SIM_Time &t,
163  ConstraintAccessor &constraint_accessor,
164  AnchorAccessor &anchor_accessor);
165 
166  void skipInvalid();
167 
168  void buildConstraintTypeCache();
169 
170  const SIM_Data &myRootData;
171 
173  const GU_Detail *myGdp;
174 
175  GA_Offset myPrimOffset;
176  exint myConstraintDataIndex;
177  GA_Iterator myPrimIterator;
178 
179  /// Cached offsets for the primitive's two points.
180  GA_Offset myPtAOffset;
181  GA_Offset myPtBOffset;
182 
183  /// Track how many constraints we've seen so far.
184  exint myConstraintIndex;
185 
186  /// Primitive group containing constraints that have been broken.
187  /// These are ignored by the iterator.
188  const GA_PrimitiveGroup *myBrokenGroup;
189 
190  /// Map from the 'constraint_type' attribute's string indices to the
191  /// corresponding ConstraintType enum values.
192  UT_Array<ConstraintType> myConstraintTypes;
193 
194  /// Track whether each unique value of 'constraint_name' is a valid
195  /// constraint data type.
196  UT_BitArray myValidConstraintData;
197 
198  GA_ROHandleS myConstraintNameRef;
199  GA_ROHandleS myConstraintTypeRef;
200  };
201 
202  /// Provides a convenient way to process all of the constraints in the
203  /// network, and update attributes of the constraints.
205  {
206  public:
207  /// Use the filter parameter to process only a certain constraint type.
208  /// The default behaviour is to process everything.
209  iterator(
210  const SIM_Data &container, const SIM_Data &data_root,
211  SIM_GeometryCopy *geo, const SIM_Time &t,
212  ConstraintAccessor &constraint_accessor,
213  AnchorAccessor &anchor_accessor);
214  ~iterator();
215 
216  void rewind() { return myImpl.rewind(); }
217  bool atEnd() const { return myImpl.atEnd(); }
218  void advance() { myImpl.advance(); }
219 
220  /// Return the number of constraints that have been seen so far.
221  exint getConstraintIndex() const { return myImpl.getConstraintIndex(); }
222 
223  /// Return the primitive number corresponding to the current constraint.
224  GA_Index getPrimIndex() const { return myImpl.getPrimIndex(); }
225  GA_Offset getPrimOffset() const { return myImpl.getPrimOffset(); }
226 
227  /// Returns the index of the current constraint data type.
228  exint getConstraintDataIndex() const { return myImpl.getConstraintDataIndex(); }
229 
230  /// Return the point number corresponding to an anchor.
231  GA_Index getPointNumber(bool anchor1) const;
232 
233  GU_Detail &getGdp() const { return *myWriteableGdp; }
234 
235  /// Mark the current constraint as being broken.
236  /// This will cause it to switch to the next constraint type (if
237  /// defined) or break and be skipped on any further traversals of the
238  /// constraints. The broken constraints are placed into a primitive
239  /// group, which can then be used in a SOP solver to trigger events
240  /// when constraints break.
241  void breakConstraint();
242 
243  /// Convenience method to update the constraint about the
244  /// forces or torques applied to satisfy it.
245  void updateLinearConstraintState(fpreal force, fpreal distance);
246  void updateAngularConstraintState(fpreal torque, fpreal angle);
247 
248  /// Returns the underlying const_iterator
249  const_iterator &getConstIterator() { return myImpl; }
250 
251  private:
252  static GA_PrimitiveGroup *getBrokenGroup(GU_Detail *gdp);
253 
254  SIM_GeometryCopy *myGeoCopy;
256  GU_Detail *myWriteableGdp;
257  GA_PrimitiveGroup *myBrokenGroup;
258 
259  GA_RWHandleF myForceAttrib;
260  GA_RWHandleF myDistanceAttrib;
261  GA_RWHandleF myTorqueAttrib;
262  GA_RWHandleF myAngleAttrib;
263 
264  GA_RWHandleS myConstraintName;
265  GA_RWHandleS myConstraintType;
266  GA_RWHandleS myNextConstraintName;
267  GA_RWHandleS myNextConstraintType;
268  bool myHasBrokenConstraints;
269 
270  const_iterator myImpl;
271  };
272 
273  /// Generic implementation of @ref ConstraintAccessor, which evaluates
274  /// constraint parameter values by name.
276  {
277  public:
278  /// Default constructor uses SIM_DataFilterAll.
280 
282 
283  void init(const GU_Detail *gdp, exint num_constraint_types) override;
284  bool acceptConstraint(const SIM_Data &constraint_data,
285  exint idx) override;
286 
287  /// Update the current constraint data type index and primitive offset.
288  void advance(exint constraint_idx, GA_Offset primoff);
289 
290  const SIM_Data *getConstraintData() const;
291 
292  /// Returns the value of an attribute of the constraint. If there is no
293  /// primitive attribute with that name, a default value will be taken
294  /// from the attached subdata if possible.
295  template <typename T>
296  T get(const UT_StringRef &attribute_name) const;
297 
298  /// Retrieve a value from the attached subdata for the constraint.
299  template <typename T>
300  T getDataOption(const UT_StringRef &attribute_name) const;
301 
302  /// Looks up a value for a primitive attribute.
303  /// Returns true if the attribute exists, and false otherwise.
304  template <typename T>
305  bool getPrimitiveAttribute(
306  const UT_StringRef &attribute_name, T &value) const;
307 
308  private:
310 
311  /// Looks up a value for a primitive attribute.
312  /// Returns true if the attribute exists, and false otherwise.
313  template <typename T>
314  bool getPrimitiveAttribute(
315  const UT_StringRef &attribute_name, const GU_Detail &gdp,
316  AttribCache &cache, T &value) const;
317 
318  /// Look up an attribute value. If the primitive attribute is not
319  /// present, the value from the subdata will be used.
320  template <typename T>
321  void get(const UT_StringRef &attribute_name, const GU_Detail &gdp,
322  AttribCache &cache, T &value) const;
323 
324  /// Look up a floating-point attribute value. If present, the primitive
325  /// attribute value will be multiplied with the value from the subdata.
326  void get(const UT_StringRef &attribute_name, const GU_Detail &gdp,
327  AttribCache &cache, fpreal &value) const;
328 
329  /// @{
330  /// Helper functions to look up values in a SIM_OptionsUser object.
331  static void getOption(
332  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
333  int &value)
334  {
335  value = data ? data->getOptions().getOptionI(attribute_name) : 0;
336  }
337  static void getOption(
338  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
339  fpreal &value)
340  {
341  value = data ? data->getOptions().getOptionF(attribute_name) : 0;
342  }
343 
344  static void getOption(
345  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
346  UT_Vector2 &value)
347  {
348  value = data ? data->getOptions().getOptionV2(attribute_name) :
349  UT_Vector2D(0, 0);
350  }
351 
352  static void getOption(
353  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
354  UT_Vector3 &value)
355  {
356  value = data ? data->getOptions().getOptionV3(attribute_name) :
357  UT_Vector3D(0, 0, 0);
358  }
359 
360  static void getOption(
361  const SIM_OptionsUser *data, const UT_StringRef &attribute_name,
362  UT_Quaternion &value)
363  {
364  value = data ? data->getOptions().getOptionQ(attribute_name) :
365  UT_QuaternionD(0, 0, 0, 1);
366  }
367  /// @}
368 
369  const GU_Detail *myGdp;
370  UT_Array<const SIM_Data *> myConstraintData;
371  UT_Array<const SIM_OptionsUser *> myConstraintDataOptions;
372 
373  exint myConstraintDataIndex;
374  GA_Offset myPrimOffset;
375 
376  /// Cache references to attributes.
377  mutable AttribCache myCachedAttributes;
378 
380  };
381 
382  /// Generic implementation of @ref AnchorAccessor, which builds its own
383  /// cache of the objects (transforms, etc) referenced by the anchor points.
385  {
386  public:
387  GenericAnchorAccessor(bool need_object_centroid = false);
388 
389  bool init(
390  const GU_Detail &gdp, const UT_Matrix4D &xform,
391  const SIM_Data &container, const SIM_Data &data_root,
392  const SIM_Time &t) override;
393 
394  void advance(GA_Offset pt_a, GA_Offset pt_b)
395  {
396  myPtAOffset = pt_a;
397  myPtBOffset = pt_b;
398  }
399 
400  /// Get the point offset of the point referred to by the anchor.
401  /// Either the anchor directly references a point on an object,
402  /// or it references a vertex on an object which has an associated
403  /// point. Returns GA_INVALID_OFFSET in the case where the anchor doesnt
404  /// reference a point. If 'anchor_pid' or 'anchor_vid' is present, then
405  /// return the first point (or vertex) with same id as on the
406  /// constraint.
407  GA_Offset getAnchorPointOffset(bool anchor1) const;
408 
409  /// Gets the point index of the point referred to by the anchor in a
410  /// similar way to getAnchorPointOffset.
411  GA_Index getAnchorPointIndex(bool anchor1) const;
412 
413  UT_Vector3 getAnchorPosition(bool anchor1) const;
414  UT_Vector3 getAnchorVelocity(bool anchor1) const;
415  /// Returns the type of position described by the anchor (e.g. relative
416  /// offset).
417  PositionType getAnchorPositionType(bool anchor1) const;
418 
419  UT_Quaternion getAnchorOrientation(bool anchor1) const;
420  UT_Vector3 getAnchorAngularVelocity(bool anchor1) const;
421 
422  bool getObjectCentroid(bool anchor1, UT_Vector3 &pos) const;
423 
424  int getAnchorNumConDOFs(bool anchor1) const;
425  UT_Vector3 getAnchorDOFVector(bool anchor1) const;
426 
427  const UT_StringHolder &getAnchorName(bool anchor1) const;
428 
429  /// Returns the id of the object named by the anchor.
430  /// Returns -1 of the anchor does not name an object.
431  int getObjectId(bool anchor1) const;
432  const SIM_Object *getObject(bool anchor1) const;
433 
434  private:
435  class CachedObjectData
436  {
437  public:
438  CachedObjectData(const SIM_BaseObjectReader &reader,
439  bool need_object_geo,
440  bool need_object_centroid,
441  const UT_Matrix4D *agent_xform);
442  ~CachedObjectData() {}
443 
444  const GU_Detail *getGdp() const
445  {
446  if (myGeoReadLock)
447  {
448  const GU_Detail *gdp = myGeoReadLock->getGdp();
449  UT_ASSERT(gdp);
450  return gdp;
451  }
452  else
453  return 0;
454  }
455 
456  const SIM_Object &myObject;
458 
459  UT_DMatrix4 myPosXform;
460  UT_DMatrix4 myGeoXform;
461  UT_Matrix4D myAgentXform;
462  UT_Quaternion myPosRotation;
463  UT_Quaternion myGeoRotation;
464  UT_Quaternion myAgentRotation;
465  const UT_Vector3 myCentroid;
466 
467  GA_ROHandleQ myOrientRef;
468  GA_ROHandleV3 myVelocityRef;
469  GA_ROHandleV3 myWRef;
470 
471  GA_ROHandleI myAnchorPIDRef;
472  GA_ROHandleI myAnchorVIDRef;
473  };
474 
475  /// Get the point offset of the point referenced by the anchor.
476  /// Either the anchor directly references a point on an object,
477  /// or it references a vertex on an object which has an associated
478  /// point. Returns GA_INVALID_OFFSET in the case where the anchor doesnt
479  /// reference a point
480  GA_Offset
481  getAnchorPointOffset(bool anchor1, const CachedObjectData *data) const;
482 
483  /// Returns the cached data for an anchor by looking up the name
484  const CachedObjectData *getCachedData(bool anchor1) const;
485 
486  /// Get the value in the anchor's anchor_id attribute
487  /// (-1 if no such attribute exists)
488  int getAnchorId(bool anchor1) const;
489 
490  /// Get the type of the Anchor (Point or Vertex)
491  AnchorType getAnchorType(bool anchor1) const;
492 
493  UT_Quaternion getInitialAnchorOrientation(bool anchor1) const;
494 
495  GA_StringIndexType getAnchorNameIndex(bool anchor1) const;
496 
497  SYS_FORCE_INLINE GA_Offset getPointOffset(bool anchor1) const
498  {
499  return anchor1 ? myPtBOffset : myPtAOffset;
500  }
501 
502  const GU_Detail *myGdp;
503 
504  GA_Offset myPtAOffset;
505  GA_Offset myPtBOffset;
506 
507  /// Mapping from object names to cached data necessary for certain
508  /// functions
510 
511  UT_DMatrix4 myXform;
512  UT_Quaternion myOrient;
513  const SIM_Data *myRootData;
514  bool myNeedObjectCentroid;
515 
516  GA_ROHandleS myNameRef;
517  GA_ROHandleI myNumDOFsRef;
518  GA_ROHandleV3 myDOFVectorRef;
519  GA_ROHandleV3 myLocalPosRef;
520  GA_ROHandleQ myLocalOrientRef;
521  GA_ROHandleI myAnchorIdRef;
522  GA_ROHandleS myAnchorTypeRef;
523  GA_ROHandleV3 myVelocityRef;
524  GA_ROHandleV3 myRotationRef;
525  GA_ROHandleQ myOrientRef;
526  GA_ROHandleV3 myAngularVelocityRef;
527  };
528 
529 }
530 
532 
533 #endif
PositionType
How the position of the anchor is interpreted.
GA_Index getPrimIndex() const
Return the primitive number corresponding to the current constraint.
const UT_Vector2D & getOptionV2(const UT_StringRef &name) const
const_iterator & getConstIterator()
Returns the underlying const_iterator.
Iteration over a range of elements.
Definition: GA_Iterator.h:28
UT_Vector2T< fpreal64 > UT_Vector2D
exint getConstraintIndex() const
The number of valid constraints that have been seen so far.
int64 exint
Definition: SYS_Types.h:125
int64 getOptionI(const UT_StringRef &name) const
const UT_Vector3D & getOptionV3(const UT_StringRef &name) const
SIM_API bool buildConstraintDataCache(const GU_Detail &gdp, const GA_ROHandleS &constraint_name_attrib, const SIM_Data &root_data, ConstraintAccessor &constraint_accessor, UT_BitArray &valid_constraint_data)
GLdouble GLdouble t
Definition: glew.h:1403
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:33
GA_Size GA_Offset
Definition: GA_Types.h:640
SIM_API void addTorqueAttributes(GU_Detail &gdp, GA_RWHandleF &torque, GA_RWHandleF &angle)
Creates the 'torque' and 'angle' primitive attributes.
exint getConstraintDataIndex() const
Returns the index of the current constraint data type.
SIM_API void addForceAttributes(GU_Detail &gdp, GA_RWHandleF &force, GA_RWHandleF &distance)
Creates the 'force' and 'distance' primitive attributes.
GLsizei GLsizei GLfloat distance
Definition: glew.h:13923
UT_QuaternionT< fpreal64 > UT_QuaternionD
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1296
UT_Vector3T< fpreal64 > UT_Vector3D
const UT_QuaternionD & getOptionQ(const UT_StringRef &name) const
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:634
const GU_Detail & getGdp() const
The constraint network geometry.
const SIM_Options & getOptions() const
GLboolean * data
Definition: glcorearb.h:130
SIM_API GA_ROHandleS getConstraintNameAttrib(const GU_Detail &gdp)
Returns the 'constraint_name' primitive attribute.
ConstraintType
The type of a constraint (linear, angular, or both).
exint getConstraintIndex() const
Return the number of constraints that have been seen so far.
fpreal64 fpreal
Definition: SYS_Types.h:277
#define SIM_API
Definition: SIM_API.h:10
GA_BlobIndex GA_StringIndexType
GLsizei const GLfloat * value
Definition: glcorearb.h:823
GLdouble angle
Definition: glew.h:9177
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:171
GA_Offset getPrimOffset() const
The primitive offset.
fpreal64 getOptionF(const UT_StringRef &name) const
This implements a SIM_Geometry that copies the source geometry.