HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_CurveFrame.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_CurveFrame.h (GU Library, C++)
7  *
8  * COMMENTS: Declarations of functions for computing reference frames
9  * for curve vertices.
10  */
11 
12 #pragma once
13 
14 #include "GU_API.h"
15 #include <GEO/GEO_Detail.h>
16 #include <GA/GA_ElementGroup.h>
17 #include <GA/GA_Handle.h>
18 #include <GA/GA_Iterator.h>
19 #include <GA/GA_OffsetList.h>
20 #include <GA/GA_SplittableRange.h>
21 #include <GA/GA_Types.h>
22 #include <UT/UT_Interrupt.h>
23 #include <UT/UT_ParallelUtil.h>
24 #include <UT/UT_Matrix4.h>
25 #include <UT/UT_Vector3.h>
26 #include <UT/UT_Vector4.h>
27 #include <SYS/SYS_Inline.h>
28 #include <SYS/SYS_Types.h>
29 
30 class GA_PrimitiveGroup;
31 
32 namespace GU_CurveFrame {
33 
34 static constexpr int theCurveUVComponent = 0; // u. FIXME: Should this be v?
35 static constexpr int theCrossSectionUVComponent = 1; // v. FIXME: Should this be u?
36 
38 {
39  /// Average of normalized direction vectors of adjacent edges.
40  /// Extrapolation rotates tangent from prev/next edge as much
41  /// as prev/next tangent rotated to that edge.
43 
44  /// Central difference of (unnormalized) adjacent edges, e.g.
45  /// computing velocity from motion trails.
46  /// This is the tangent that a subdivision curve would have at each point.
47  /// Extrapolation applies half the difference between the two
48  /// prev/next edges to the prev/next edge to get the tangent.
50 
51  /// Tangent is the previous edge.
52  /// Extrapolation (only back from the beginning of the curve) applies the
53  /// negative difference between the two next edges to the next edge.
55 
56  /// Tangent is the next edge.
57  /// Extrapolation (only forward from the end of the curve) applies the
58  /// difference between the two prev edges to the prev edge.
60 
61  /// Tangent is the Z axis (ignoring the curve tangent).
62  /// Extrapolation does nothing.
64 };
65 
67 {
68  /// Apply angle increment to each edge on top of previous edge's rotation
70 
71  /// Apply angle increment times edge length to each edge on top of previous
72  /// edge's rotation.
74 
75  /// Apply angle increment times rotation ramp attribute value on top of
76  /// starting rotation of the primitive.
78 
79  /// Apply (angle increment / num edges) to each edge on top of previous
80  /// edge's rotation.
82 
83  /// Apply (angle increment * edge length / total length) to each edge on
84  /// top of previous edge's rotation.
86 };
87 
88 GU_API bool
90  const GEO_Detail *geometry,
91  const GA_OffsetListRef &vertices,
92  exint &nedges,
93  bool &closed,
94  bool &unrolled);
95 
98  const GEO_Detail *geometry,
99  const GA_Offset primoff,
100  exint &nedges,
101  bool &closed,
102  bool &unrolled)
103 {
104  const GA_OffsetListRef vertices = geometry->getPrimitiveVertexList(primoff);
105  return getPolyProperties(geometry, vertices, nedges, closed, unrolled);
106 }
107 
108 template<typename T>
110 {
113 
114  /// Use incoming N, up, rot, orient, pscale, scale, pivot, trans, transform.
116 
120  /// NOTE: myIncAnglePer[2] will also be used for ensuring closed curve continuity.
122  /// Component of myRotAttribs being read. (default 0)
124  /// "pitch" (X), "yaw" (Y), and "roll" (Z) attributes to add
125  /// to rotation angles, to be multiplied by myIncAngles if myIncAnglePer is ATTRIB,
126  /// and they can be vertex, point, primitive, or detail attributes.
128 
133  const GEO_Detail *myBankingCurveGeo = nullptr;
135  /// When true, the target up vector will be used as the starting up vector.
136  /// When false, it will be used as the *average* up vector.
138  /// NOTE: This should only be true if myTargetUpVectorAtStart is true.
139  /// It also only applies to open curves.
141  /// Banking curve overrides instance up attribute.
142  bool myUseBankingCurve = false;
143 
144  /// When true, transformations for closed curves (and for "unrolled" curves
145  /// that share a first and last point) will have an incremental roll added
146  /// to ensure that any net roll introduced by non-planarity of the curve
147  /// will be spread out, instead of being all cancelled in the very last
148  /// edge. When false, this roll will be uncorrected, so there can be
149  /// a large roll around the last edge.
150  ///
151  /// This is important to turn off if, for example,
152  /// myRotRampAttrib already accounts for this extra roll.
153  ///
154  /// If this is enabled and myIncAngles[2] is non-zero, the total roll
155  /// around the curve, including the inherent roll, will be rounded to
156  /// be a multiple of a full turn to ensure continuity. If myIncAnglePer[2]
157  /// is ATTRIB, the full range of the attribute along the curve is assumed to
158  /// be 0-1, so if this is not the true range, that roll may need to be
159  /// applied separately.
161 
164  UT_Ramp *myScaleRamp = nullptr;
167 
168  // For ajusting the up vectors by the curvature.
169  bool myAdjustUpByCurvature = false;
173 };
174 
175 /// Computes transforms for vertex attribute transform_attrib based on
176 /// primitives (assumed to be polygon primitives if not NURBS or Bezier)
177 /// in geo and based on settings in parms.
178 ///
179 /// NOTE: End vertices on unrolled curves are not written-to.
180 /// Use extractAttribFromTransform to extract values to a more permanent
181 /// vertex attribute.
182 ///
183 /// This is instantiated for fpreal32 and fpreal64.
184 template<typename T>
185 GU_API void
187  const GEO_Detail *const geo,
188  const GA_PrimitiveGroup *curve_group,
189  const GA_RWHandleT<UT_Matrix4T<T>> &transform_attrib,
190  const CurveFrameParms<T> &parms);
191 
192 template<typename T,typename OUTPUT_T,typename FUNCTOR>
193 void
195  GEO_Detail *geo,
196  const GA_PrimitiveGroup *curve_group,
197  const GA_ROHandleT<UT_Matrix4T<T>> &transform_attrib,
198  const GA_RWHandleT<OUTPUT_T> &output_attrib,
199  FUNCTOR &&extract_functor)
200 {
201  // Start an interruptible block. The message will appear in the status bar
202  // if wasInterrupted() is called after about a second of cooking.
203  UT_AutoInterrupt interrupt("Writing curve transforms");
204  if (interrupt.wasInterrupted()) {
205  return;
206  }
207 
208  // We're going to be writing to axis_attrib in parallel, and although
209  // we're using GA_SplittableRange, we're splitting over primitive pages,
210  // not vertex pages, so we have to harden in advance.
211  output_attrib->hardenAllPages();
212 
213  // Loop over primitives in parallel, using a splittable range and a lambda functor.
215  [geo,&transform_attrib,&interrupt,&output_attrib,&extract_functor](const GA_SplittableRange &r) {
216 
217  // Inside the functor, we have a sub-range of primitives, so loop over that range.
218  // We use blockAdvance, instead of !it.atEnd() and ++it, for less looping overhead.
220  for (GA_Iterator it(r); it.blockAdvance(start,end); ) {
221  // We probably don't need to check for interruption on every curve,
222  // (unless people put in a curve with millions of vertices), so we
223  // can check it once for every contiguous block of up to GA_PAGE_SIZE
224  // primitive offsets.
225  if (interrupt.wasInterrupted()) {
226  return;
227  }
228 
229  // Loop over all primitives in this contiguous block of offsets.
230  for (GA_Offset primoff = start; primoff < end; ++primoff) {
231  const GA_OffsetListRef vertices = geo->getPrimitiveVertexList(primoff);
232  GA_Size nedges;
233  bool closed;
234  bool unrolled;
235  bool nonempty = getPolyProperties(geo, vertices, nedges, closed, unrolled);
236  const GA_Size npoints = nedges + !closed;
237 
238  // Nothing to do if no vertices
239  if (!nonempty) {
240  continue;
241  }
242 
243  // NOTE: Although we're really iterating over vertices,
244  // we didn't write to the last vertex of unrolled curves
245  // (open but last point same as first).
246  for (GA_Size i = 0; i < npoints; ++i) {
247  GA_Offset vtxoff = vertices(i);
248  output_attrib.set(vtxoff, extract_functor(transform_attrib.get(vtxoff)));
249  }
250  if (unrolled) {
251  GA_Offset dest_vtxoff = vertices(npoints);
252  GA_Offset src_vtxoff = vertices(0);
253  output_attrib.set(dest_vtxoff, extract_functor(transform_attrib.get(src_vtxoff)));
254  }
255  }
256  }
257  });
258 }
259 
260 /// This works for AXIS == 0 (x), 1 (y), 2 (z), and 3 (translation).
261 template<int AXIS,typename T,typename OUTPUT_T>
262 void
264  GEO_Detail *geo,
265  const GA_PrimitiveGroup *curve_group,
266  const GA_ROHandleT<UT_Matrix4T<T>> &transform_attrib,
267  const GA_RWHandleT<UT_Vector3T<OUTPUT_T>> &axis_attrib)
268 {
269  extractAttribFromTransform(geo, curve_group, transform_attrib, axis_attrib,
271  return UT_Vector3T<OUTPUT_T>(transform[AXIS]);
272  });
273 }
274 
275 }
Apply angle increment to each edge on top of previous edge's rotation.
Definition: GU_CurveFrame.h:69
Iteration over a range of elements.
Definition: GA_Iterator.h:29
bool blockAdvance(GA_Offset &start, GA_Offset &end)
GLuint start
Definition: glcorearb.h:475
int64 exint
Definition: SYS_Types.h:125
void UTparallelForLightItems(const Range &range, const Body &body, const bool force_use_task_scope=true)
3D Vector class.
GA_ROHandleT< T > myRotAttribs[3]
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
GA_Size GA_Offset
Definition: GA_Types.h:641
void extractAttribFromTransform(GEO_Detail *geo, const GA_PrimitiveGroup *curve_group, const GA_ROHandleT< UT_Matrix4T< T >> &transform_attrib, const GA_RWHandleT< OUTPUT_T > &output_attrib, FUNCTOR &&extract_functor)
SYS_FORCE_INLINE GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const
Definition: GA_Primitive.h:886
GLuint GLuint end
Definition: glcorearb.h:475
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
UT_Vector3T< T > myEndTargetUpVector
GU_API void computeCurveTransforms(const GEO_Detail *const geo, const GA_PrimitiveGroup *curve_group, const GA_RWHandleT< UT_Matrix4T< T >> &transform_attrib, const CurveFrameParms< T > &parms)
#define GU_API
Definition: GU_API.h:14
GA_API const UT_StringHolder transform
bool myTransformByInstanceAttribs
Use incoming N, up, rot, orient, pscale, scale, pivot, trans, transform.
RotationPer myIncAnglePer[3]
NOTE: myIncAnglePer[2] will also be used for ensuring closed curve continuity.
const GEO_Detail * myBankingCurveGeo
void hardenAllPages(GA_Offset start_offset=GA_Offset(0), GA_Offset end_offset=GA_INVALID_OFFSET) override
Harden data pages.
SYS_FORCE_INLINE void set(GA_Offset off, const T &val) const
Definition: GA_Handle.h:354
GA_ROHandleT< UT_Vector3T< T > > myTargetUpVectorAttrib
Utility class for containing a color ramp.
Definition: UT_Ramp.h:88
void extractAxisAttrib(GEO_Detail *geo, const GA_PrimitiveGroup *curve_group, const GA_ROHandleT< UT_Matrix4T< T >> &transform_attrib, const GA_RWHandleT< UT_Vector3T< OUTPUT_T >> &axis_attrib)
This works for AXIS == 0 (x), 1 (y), 2 (z), and 3 (translation).
GA_ROHandleT< T > myCurvatureScaleAttrib
UT_XformOrder::xyzOrder myRotationOrder
GA_ROHandleT< UT_Vector3T< T > > myEndTargetUpVectorAttrib
int myRotAttribComponent
Component of myRotAttribs being read. (default 0)
GLboolean r
Definition: glcorearb.h:1222
GA_Range getPrimitiveRange(const GA_PrimitiveGroup *group=0) const
Get a range of all primitives in the detail.
Definition: GA_Detail.h:1733
GU_API bool getPolyProperties(const GEO_Detail *geometry, const GA_OffsetListRef &vertices, exint &nedges, bool &closed, bool &unrolled)
bool myUseBankingCurve
Banking curve overrides instance up attribute.
UT_Vector3T< T > myTargetUpVector