HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_Path.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_Path.h (GEO Utility library, C++)
7  *
8  * COMMENTS: This class implements the utilities for the path. Path
9  * is a curve that behaves like a rope or semi-flexible string
10  * (but the behaviour of the path may be extended in the future
11  * to incorporate other behaviours). Path curve has normal
12  * attribute (and potentially a twist attribute) to define
13  * the orientation of the rope, so that it can simulate
14  * the twisting behavoiur in addition to the bending behaviour.
15  *
16  * Primary use of this class is intended for the object level
17  * path normal computation (which is used when generating
18  * bones on the path and solving them in follow curve IK chop).
19  * We are primarily interested in the normals at sample points.
20  * The sample points are taken from the Bezier or NURBS curve.
21  * The setup of the object level path is such that only
22  * breakpoints are intended for maniputaling curve (via
23  * object level Path CVs). Thus the GU_Path, obtains
24  * the breakpoint data (normals, twists, etc) and uses it
25  * for interpolating the brakpoint normals among the sampled
26  * points. So, Bezier segments are preferable inputs to the
27  * GU_Path, but NRBS curves are also handled: the breakpoint
28  * data is evaluated from the CVs and then used as for Bezier
29  * curves.
30  */
31 
32 #ifndef __GU_Path_H__
33 #define __GU_Path_H__
34 
35 
36 #include "GU_API.h"
37 // includes
38 #include <UT/UT_Vector3Array.h>
39 #include <UT/UT_IntArray.h>
40 #include <UT/UT_Vector3.h>
41 #include <UT/UT_VectorTypes.h>
42 
43 // class declarations
44 class GA_ROAttributeRef;
45 class GEO_PrimPoly;
46 class GEO_Primitive;
47 class GEO_Curve;
48 class GU_Detail;
49 
50 
51 // Path class
53 {
54 public:
55 
56  // the calculation method of the normals
58  {
59  GU_CALC_DEFAULT, // default
60  GU_CALC_NONE, // no normals are computed
61  GU_CALC_QUAT, // interpolating with quaternions
62  GU_CALC_TWIST_SHORT,// interpolating with twist angles in 0..180 range
63  GU_CALC_TWIST_FULL // interpolating with twist angles in any range
64  };
65 
66  // constructor
67  GU_Path();
68 
69  // destructor
70  ~GU_Path();
71 
72  // Calculate the path object from the curve object.
73  // Normals associated with the curve's breakpoints (!)
74  // are retargeted for the path object, if curve has normal attribute.
75  // Otherwise path object will not
76  // have normals. If curve has twist attribute, the normals for the path
77  // are interpolated according to the angle around the path (like a twisted
78  // rope or string), otherwise a quaternion interpolation of curve normals
79  // is used.
80  // INPUT:
81  // curve - the detail whose first primitive is a curve.
82  // It may have normal attribute
83  // and twist attribute. Twist is the angle of rotation
84  // around the path (synonims: curve, rope) measured from
85  // its natural "rest" orientation (presumably defined
86  // at the path creation time). If
87  // mat - the matrix used to transform the curve's sampled points,
88  // before assigning them to the path.
89  // normal_comp_type - a method for interpolating the normals at
90  // the breakpoints. Default uses best method for which
91  // we have enough information.
92  // prim_num - prim index to use
93  // lod - GEO_ConvertParms ULod to use when converting curves to poly.
94  // RETURN:
95  // true on success, false if failed
96  bool computePathFromCurve(
97  const GU_Detail * curve,
98  const UT_DMatrix4 & mat,
99  gu_CalcMethod normal_comp_type = GU_CALC_DEFAULT,
100  int prim_num = 0,
101  float lod=1.f );
102 
103  // Calculate the path from detail object containing a curve.
104  // Normals for the path are calculated so that they flow naturally
105  // without any twist differences between breakpoints.
106  // INPUT:
107  // curve - detail containing a curve
108  // normal - a normal to match on cv_index-th breakpoint of the curve
109  // cv_index - index of the breakpoint whose normal should be the same
110  // as 'normal' argument
111  // RETURN:
112  // true on success, false if failed
113  bool computeNaturalPathFromCurve( const GU_Detail * curve,
114  const UT_Vector3& normal,
115  int cv_index = 0);
116 
117  // calculates the positions of the joints along the path.
118  // The joints mark uniform arc length segments along the path.
119  // INPUT:
120  // num_of_segments - number of segments (n+1 sample points) for resampling
121  // OUTPUT:
122  // joints - array of vertices that resample the path
123  // normals - array of normals associated with joints. This array
124  // is set to empty if path has no normals.
125  void resamplePath( int num_of_segments,
126  UT_Vector3Array & joints,
127  UT_Vector3Array & normals ) const;
128 
129  // obtains the twist angles between path's breakpoint normals
130  // and the vectors passed in
131  // INPUT:
132  // vectors - vectors against which to compute twist angles. Should
133  // be the same size as the array returned by getBreakpointNormals()
134  // OUTPUT:
135  // angles - angles in degrees by which i-th breakpoint normal needs to be
136  // rotated while traversing the path to match the i+1-th vector.
137  // The angles are in the interval [-180, 180].
138  // RETURN:
139  // true on success, false on failure
140  bool getBreakpointTwists( const UT_Vector3Array & vectors,
141  UT_FloatArray & angles );
142 
143  // do a spherical linear interpolation (slerp) between two vectors
144  // using t = [0, 1] as a blending factor
145  static UT_Vector3 slerp( const UT_Vector3 & v0, const UT_Vector3 & v1,
146  double t );
147 
148  // obtains path's vertices
149  const UT_Vector3Array & getVertices() const
150  {
151  return myVertices;
152  }
153 
154  // obtains path's normals
155  const UT_Vector3Array & getNormals() const
156  {
157  return myNormals;
158  }
159 
160  // obtains path breakpoints' normals
162  {
163  return myBreakpointNormals;
164  }
165 
166  // true if path is closed
167  bool isClosed() const
168  {
169  return myIsClosed;
170  }
171 
172  // obtains a tangent at the path start point
174  {
175  return myHeadTangent;
176  }
177 
178  // obtains a tangent at the path end point
180  {
181  return myTailTangent;
182  }
183 
184 private: // methods
185 
186  // suck data from the poly and transfer it to ourselves. Curve
187  // is used for finding and interpolating the attributes like
188  // the normals. If it is NULL, then no normals will be computed
189  // for the path object. Otherwise the normal_comp_type determines
190  // the method for interpolating the normals (provided enough
191  // information is given in curve)
192  void getDataFromPoly( const GU_Detail * detail,
193  const GEO_PrimPoly * poly,
194  const GEO_Curve * curve,
195  const UT_DMatrix4 & mat,
196  gu_CalcMethod normal_comp_type =
197  GU_CALC_DEFAULT );
198 
199  // construct the path from poly, and assign natually flowing normals
200  // to the vertices. If curve is not NULL, also the breakpoint normals
201  // for that curve are computed and stored in member data field.
202  void computeNaturalPathFromPoly(const GEO_PrimPoly * poly,
203  const GEO_Curve * curve,
204  const UT_Vector3& normal, int cv_index );
205 
206  // interpolate normals between the breakpoints of the curve and
207  // set them for our path object
208  // (i.e., for each verex in myVertices compute appropriate normal
209  // in myNormals)
210  // NB: curve must have the normal attribute
211  void setInterpolatedNormals( const GU_Detail * detail,
212  const GEO_Curve * curve );
213 
214  // for each vertex in myVertices interpolate twist (rotation angle
215  // around the curve) between the breakpoints of the curve and
216  // use this twist to find the normal (and set it in myNormals).
217  // If clamp_range is true, the twist between the breakpoints
218  // is going to be within [-180, 180]. Otherwise the twist is unlimited
219  // in its range
220  // NB: curve must have the normal attribute
221  // NB: all the breakpoints of the curve, must have a corresponding point
222  // in vertices array myVertices that have the same position.
223  void setTwistedNormals( const GU_Detail * detail,
224  const GEO_Curve * curve,
225  bool clamp_range = false);
226 
227  // for each vertex in myVertices assign a normal (stored in myNormals)
228  // using the natural flow. If curve is not null then its index-th control
229  // will have the 'normal' orientation. If curve is null the index-th
230  // vertex will have the orientation alligned with normal.
231  void setNaturalNormals( const GEO_Curve *curve,
232  const UT_Vector3& normal, int index );
233 
234  // sets our normals from the poly. It is one to one correspondence
235  // with the poly (the normals), thus the poly must have the same
236  // number of vertices as we do.
237  void setPolyNormals( const GU_Detail *detail,
238  const GEO_PrimPoly * poly );
239 
240  // calculates length as a sum of distances between 'points'. Points
241  // should have at least 2 entries. Additionally, if curve and
242  // break_arc_lengts are not null, break_arc_lengths will be filled
243  // with arc length parameter for each of curve's breakpoint measured
244  // along the points. All curve's breakpoint locations must coincide
245  // with some of the points (up to tollerance level). If
246  // vertex_indices is not null it is filled with vertex indices that
247  // coincide with the curve's breakpoints.
248  float calculateLength( const UT_Vector3Array & points,
249  const GEO_Curve * curve = NULL,
250  UT_FloatArray * break_arc_lengths = NULL,
251  UT_IntArray * break_vertex_indices =NULL)const;
252 
253  // returns the angular twist (radians) difference around the curve. That is,
254  // the angle by which the normal n0 needs to be rotated, as we traverse
255  // down the curve, to allign it with n1. index0 and index1 are point indices
256  // corresponing to the normals n0 and n1.
257  // RETURNS:
258  // the twist angle between points index0 and index1 that alligns
259  // the normals
260  float calculateTwistDelta( int index0, int index1,
261  const UT_Vector3 & n0, const UT_Vector3 & n1,
262  const UT_Vector3Array & points ) const;
263 
264  // rotates to_transform according to the quaternion rotation of the from
265  // vector to the to vector
266  void rotateVector( UT_Vector3 from, UT_Vector3 to,
267  UT_Vector3 & to_transform ) const;
268 
269  // rotates to_transform vector around about vector by the angle
270  void rotateVector( UT_Vector3 about, float angle,
271  UT_Vector3 & to_transform ) const;
272 
273  // pushes the normal forward along the points preserwing zero twist
274  // INPUTS:
275  // from_index - the vertex index from which to move normal
276  // normal - normal to move ( associated with from_index-th vertex )
277  // reuse_direction - the normalized direction from vertex from_index
278  // to vertex from_index+1. If vector is zero, it is
279  // computed internaly. This is intended for reuse during
280  // forward traversals.
281  // OUTPUTS:
282  // normal - moved and transformed normal
283  // reuse_direction - the normalized direction from vertex from_index+1
284  // to vertex from_index+2. If no vertices of such indecis
285  // it is set to zero.
286  void moveNormalForward( const UT_Vector3Array & vertices,
287  int from_index, UT_Vector3 & reuse_direction,
288  UT_Vector3 & normal ) const;
289 
290  // pushes the normal backward along the points preserving zero twist
291  // INPUTS:
292  // from_index - the vertex index from which to move normal
293  // normal - normal to move ( associated with from_index-th vertex )
294  // reuse_direction - the normalized direction from vertex from_index
295  // to vertex from_index-1. If vector is zero, it is
296  // computed internaly. This is intended for reuse during
297  // backward traversals.
298  // OUTPUTS:
299  // normal - moved and transformed normal
300  // reuse_direction - the normalized direction from vertex from_index-1
301  // to vertex from_index-2. If no vertices of such indecis
302  // it is set to zero.
303  void moveNormalBackward( const UT_Vector3Array & vertices,
304  int from_index, UT_Vector3 & reuse_direction,
305  UT_Vector3 & normal ) const;
306 
307  // calculates the start and end tangents of a prim and set them
308  // as the path front and back tangents
309  void setTangents( const GEO_Primitive * prim, const UT_DMatrix4 & mat );
310 
311 
312 private: // data
313 
314  bool myIsClosed; // true if path is a closed loop
315  UT_Vector3Array myVertices; // vertices of the path (sampled rope)
316  UT_Vector3Array myNormals; // normals of the vertices
317  UT_Vector3Array myBreakpointNormals; // normals of breakpoint
318  // contol vertices
319  UT_IntArray myBreakpointIndices; // indices to myVertices for each
320  // breakpoint
321  UT_Vector3 myHeadTangent; // tangent at the path start point
322  UT_Vector3 myTailTangent; // tangent at the path end point
323 };
324 
325 #endif // __GU_Path_H__
GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glad.h:2676
SIM_API const UT_StringHolder angle
bool isClosed() const
Definition: GU_Path.h:167
const UT_Vector3Array & getBreakpointNormals() const
Definition: GU_Path.h:161
GLfloat f
Definition: glcorearb.h:1926
This class provides a way to manage a reference to an attribute permitting Read-Only access...
const UT_Vector3Array & getNormals() const
Definition: GU_Path.h:155
UT_Vector3 getHeadTangent() const
Definition: GU_Path.h:173
const UT_Vector3Array & getVertices() const
Definition: GU_Path.h:149
#define GU_API
Definition: GU_API.h:14
UT_Vector3 getTailTangent() const
Definition: GU_Path.h:179
GLdouble t
Definition: glad.h:2397
GLfloat v0
Definition: glcorearb.h:816
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Quat< T > slerp(const Quat< T > &q1, const Quat< T > &q2, T t) IMATH_NOEXCEPT
Definition: ImathQuat.h:531
GLuint index
Definition: glcorearb.h:786
GLfloat GLfloat v1
Definition: glcorearb.h:817
GLint lod
Definition: glcorearb.h:2765
gu_CalcMethod
Definition: GU_Path.h:57