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 
169 /// Computes transforms for vertex attribute transform_attrib based on
170 /// primitives (assumed to be polygon primitives if not NURBS or Bezier)
171 /// in geo and based on settings in parms.
172 ///
173 /// NOTE: End vertices on unrolled curves are not written-to.
174 /// Use extractAttribFromTransform to extract values to a more permanent
175 /// vertex attribute.
176 ///
177 /// This is instantiated for fpreal32 and fpreal64.
178 template<typename T>
179 GU_API void
181  const GEO_Detail *const geo,
182  const GA_PrimitiveGroup *curve_group,
183  const GA_RWHandleT<UT_Matrix4T<T>> &transform_attrib,
184  const CurveFrameParms<T> &parms);
185 
186 template<typename T,typename OUTPUT_T,typename FUNCTOR>
187 void
189  GEO_Detail *geo,
190  const GA_PrimitiveGroup *curve_group,
191  const GA_ROHandleT<UT_Matrix4T<T>> &transform_attrib,
192  const GA_RWHandleT<OUTPUT_T> &output_attrib,
193  FUNCTOR &&extract_functor)
194 {
195  // Start an interruptible block. The message will appear in the status bar
196  // if wasInterrupted() is called after about a second of cooking.
197  UT_AutoInterrupt interrupt("Writing curve transforms");
198  if (interrupt.wasInterrupted()) {
199  return;
200  }
201 
202  // We're going to be writing to axis_attrib in parallel, and although
203  // we're using GA_SplittableRange, we're splitting over primitive pages,
204  // not vertex pages, so we have to harden in advance.
205  output_attrib->hardenAllPages();
206 
207  // Loop over primitives in parallel, using a splittable range and a lambda functor.
209  [geo,&transform_attrib,&interrupt,&output_attrib,&extract_functor](const GA_SplittableRange &r) {
210 
211  // Inside the functor, we have a sub-range of primitives, so loop over that range.
212  // We use blockAdvance, instead of !it.atEnd() and ++it, for less looping overhead.
214  for (GA_Iterator it(r); it.blockAdvance(start,end); ) {
215  // We probably don't need to check for interruption on every curve,
216  // (unless people put in a curve with millions of vertices), so we
217  // can check it once for every contiguous block of up to GA_PAGE_SIZE
218  // primitive offsets.
219  if (interrupt.wasInterrupted()) {
220  return;
221  }
222 
223  // Loop over all primitives in this contiguous block of offsets.
224  for (GA_Offset primoff = start; primoff < end; ++primoff) {
225  const GA_OffsetListRef vertices = geo->getPrimitiveVertexList(primoff);
226  GA_Size nedges;
227  bool closed;
228  bool unrolled;
229  bool nonempty = getPolyProperties(geo, vertices, nedges, closed, unrolled);
230  const GA_Size npoints = nedges + !closed;
231 
232  // Nothing to do if no vertices
233  if (!nonempty) {
234  continue;
235  }
236 
237  // NOTE: Although we're really iterating over vertices,
238  // we didn't write to the last vertex of unrolled curves
239  // (open but last point same as first).
240  for (GA_Size i = 0; i < npoints; ++i) {
241  GA_Offset vtxoff = vertices(i);
242  output_attrib.set(vtxoff, extract_functor(transform_attrib.get(vtxoff)));
243  }
244  if (unrolled) {
245  GA_Offset dest_vtxoff = vertices(npoints);
246  GA_Offset src_vtxoff = vertices(0);
247  output_attrib.set(dest_vtxoff, extract_functor(transform_attrib.get(src_vtxoff)));
248  }
249  }
250  }
251  });
252 }
253 
254 /// This works for AXIS == 0 (x), 1 (y), 2 (z), and 3 (translation).
255 template<int AXIS,typename T,typename OUTPUT_T>
256 void
258  GEO_Detail *geo,
259  const GA_PrimitiveGroup *curve_group,
260  const GA_ROHandleT<UT_Matrix4T<T>> &transform_attrib,
261  const GA_RWHandleT<UT_Vector3T<OUTPUT_T>> &axis_attrib)
262 {
263  extractAttribFromTransform(geo, curve_group, transform_attrib, axis_attrib,
265  return UT_Vector3T<OUTPUT_T>(transform[AXIS]);
266  });
267 }
268 
269 }
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:28
GLuint GLenum GLenum transform
Definition: glew.h:14742
bool blockAdvance(GA_Offset &start, GA_Offset &end)
int64 exint
Definition: SYS_Types.h:125
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:233
GA_Size GA_Offset
Definition: GA_Types.h:639
void UTparallelForLightItems(const Range &range, const Body &body)
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:859
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLuint GLuint end
Definition: glew.h:1253
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
GLuint start
Definition: glew.h:1253
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:322
GA_ROHandleT< UT_Vector3T< T > > myTargetUpVectorAttrib
Utility class for containing a color ramp.
Definition: UT_Ramp.h:84
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).
UT_XformOrder::xyzOrder myRotationOrder
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
GA_ROHandleT< UT_Vector3T< T > > myEndTargetUpVectorAttrib
int myRotAttribComponent
Component of myRotAttribs being read. (default 0)
GA_Range getPrimitiveRange(const GA_PrimitiveGroup *group=0) const
Get a range of all primitives in the detail.
Definition: GA_Detail.h:1669
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