35 #include "SOP_OrientAlongCurve.proto.h"
60 using namespace UT::Literal;
63 namespace HDK_Sample {
78 void cook(
const CookParms &cookparms)
const override;
94 const UT_StringHolder SOP_OrientAlongCurveVerb::theSOPTypeName(
"hdk_orientalongcurve"_sh);
116 mySopFlags.setManagesDataIDs(
true);
124 return cookMyselfAsVerb(context);
133 case 0:
return "Curves";
134 default:
return "Invalid Source";
152 static PRM_TemplateBuilder templ(
"SOP_OrientAlongCurve.C"_sh, SOP_OrientAlongCurveVerb::theDsFile);
162 return SOP_OrientAlongCurveVerb::theVerb.get();
174 "HDK Orientation Along Curve",
183 namespace HDK_Sample {
190 const char *
const SOP_OrientAlongCurveVerb::theDsFile = R
"THEDSFILE(
199 parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Primitives,)\nkwargs['inputindex'] = 0\nsoputils.selectGroupParm(kwargs)" }
200 parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." }
201 parmtag { "script_action_icon" "BUTTONS_reselect" }
209 cppname "TangentType"
212 default { "0" } // Default to first entry in menu, "avgdir"
214 "avgdir" "Average of Edge Directions"
215 "diff" "Central Difference"
216 "prev" "Previous Edge"
218 "none" "Z Axis (Ignore Curve)"
222 name "continuousclosed"
223 cppname "ContinuousClosed"
224 label "Make Closed Curve Orientations Continuous"
227 disablewhen "{ tangenttype == none }"
230 name "extrapolateendtangents"
231 cppname "ExtrapolateEndTangents"
232 label "Extrapolate End Tangents"
235 disablewhen "{ tangenttype == none }"
238 name "transformbyattribs"
239 cppname "TransformByAttribs"
240 label "Transform Using Point Attributes"
246 // cppname "OrientType"
247 // label "Orientation Type"
249 // default { "0" } // Default to first entry in menu, "minrot"
251 // "minrot" "Minimal Rotation"
252 // "curvature" "Curvature"
253 // "bank" "Bank Around Turns"
255 // disablewhen "{ tangenttype == none }"
265 cppname "UpVectorType"
266 label "Target Up Vector"
268 default { "0" } // Default to first entry in menu, "normal"
270 "normal" "Curve Normal"
277 disablewhen "{ tangenttype == none }"
280 // name "usenormalup"
281 // cppname "UseNormalUp"
282 // label "Use Curve Normal as Up Vector (When Valid)"
285 // disablewhen "{ tangenttype == none }"
288 name "upvectoratstart"
289 cppname "UpVectorAtStart"
290 label "Target Up Vector at Start (else Average)"
293 disablewhen "{ tangenttype == none }"
296 name "useendupvector"
297 cppname "UseEndUpVector"
298 label "Use Target End Up Vector"
301 disablewhen "{ tangenttype == none } { upvectoratstart == 0 }"
304 name "upvectorattrib"
305 cppname "UpVectorAttrib"
306 label "Start Up Attribute"
308 default { "target_up" }
309 disablewhen "{ tangenttype == none } { upvectortype != attrib }"
310 hidewhen "{ tangenttype == none } { upvectortype != attrib }"
313 name "endupvectorattrib"
314 cppname "EndUpVectorAttrib"
315 label "End Up Attribute"
317 default { "target_up_end" }
318 disablewhen "{ tangenttype == none } { upvectortype != attrib } { useendupvector == 0 } { upvectoratstart == 0 }"
319 hidewhen "{ tangenttype == none } { upvectortype != attrib } { useendupvector == 0 } { upvectoratstart == 0 }"
324 label "Start Up Vector"
327 default { "0" "1" "0" }
328 disablewhen "{ tangenttype == none } { upvectortype != custom }"
329 hidewhen "{ tangenttype == none } { upvectortype != custom }"
333 cppname "EndUpVector"
334 label "End Up Vector"
337 default { "0" "1" "0" }
338 disablewhen "{ tangenttype == none } { upvectortype != custom } { useendupvector == 0 } { upvectoratstart == 0 }"
339 hidewhen "{ tangenttype == none } { upvectortype != custom } { useendupvector == 0 } { upvectoratstart == 0 }"
347 name "rotation_folder"
348 label "Additional Rotations"
349 grouptag { "group_type" "collapsible" }
350 parmtag { "group_default" "0" }
357 // NOTE: The default rotation order X,Y,Z is semi-arbitrary, but Z
358 // should probably be last, since it always needs to twist
359 // around the curve tangent. The X and Y rotations may have
360 // just been to reorient a cross-section before copying.
363 "xyz" "Pitch, Yaw, Roll"
364 "xzy" "Pitch, Roll, Yaw"
365 "yxz" "Yaw, Pitch, Roll"
366 "yzx" "Yaw, Roll, Pitch"
367 "zxy" "Roll, Pitch, Yaw"
368 "zyx" "Roll, Yaw, Pitch"
374 label "Apply Roll or Twist"
384 hidewhen "{ applyroll == 0 }"
391 default { "4" } // Default to "fulldistance" entry in menu
394 "distance" "Per Unit Distance"
395 "attrib" "Scale by Attribute"
396 "fulledges" "Per Full Curve by Edges"
397 "fulldistance" "Per Full Curve by Distance"
399 hidewhen "{ applyroll == 0 }"
408 hidewhen "{ applyroll == 0 }"
413 label "Partial Twist"
417 hidewhen "{ applyroll == 0 }"
422 label "Twist Ramp Attribute"
425 disablewhen "{ applyroll == 0 } { applyroll == 1 rollper != attrib }"
426 hidewhen "{ applyroll == 0 } { applyroll == 1 rollper != attrib }"
433 hidewhen "{ applyroll == 0 }"
448 hidewhen "{ applyyaw == 0 }"
455 default { "4" } // Default to "fulldistance" entry in menu
458 "distance" "Per Unit Distance"
459 "attrib" "Scale By Attribute"
460 "fulledges" "Per Full Curve by Edges"
461 "fulldistance" "Per Full Curve by Distance"
463 hidewhen "{ applyyaw == 0 }"
468 label "Incremental Yaw"
472 hidewhen "{ applyyaw == 0 }"
477 label "Yaw Ramp Attribute"
480 disablewhen "{ applyyaw == 0 } { applyyaw == 1 yawper != attrib }"
481 hidewhen "{ applyyaw == 0 } { applyyaw == 1 yawper != attrib }"
488 hidewhen "{ applyyaw == 0 }"
503 hidewhen "{ applypitch == 0 }"
510 default { "4" } // Default to "fulldistance" entry in menu
513 "distance" "Per Unit Distance"
514 "attrib" "Scale By Attribute"
515 "fulledges" "Per Full Curve by Edges"
516 "fulldistance" "Per Full Curve by Distance"
518 hidewhen "{ applypitch == 0 }"
523 label "Incremental Pitch"
527 hidewhen "{ applypitch == 0 }"
531 cppname "PitchAttrib"
532 label "Pitch Ramp Attribute"
535 disablewhen "{ applypitch == 0 } { applypitch == 1 pitchper != attrib }"
536 hidewhen "{ applypitch == 0 } { applypitch == 1 pitchper != attrib }"
545 label "Scales and Shears"
546 grouptag { "group_type" "collapsible" }
547 parmtag { "group_default" "0" }
551 label "Normalize Scales"
557 label "Uniform Scale"
563 name "stretcharoundturns"
564 cppname "StretchAroundTurns"
565 label "Stretch Around Turns"
570 name "maxstretcharoundturns"
571 cppname "MaxStretchAroundTurns"
576 disablewhen "{ stretcharoundturns == 0 }"
585 label "Output Attributes"
586 grouptag { "group_type" "collapsible" }
587 parmtag { "group_default" "1" }
594 default { "0" } // Default to first entry in menu, "point"
603 // cppname "Precision"
606 // default { "1" } // Default to first entry in menu, "32"
615 cppname "OutputXAxis"
616 label "Output X Axis"
628 disablewhen "{ outputxaxis == 0 }"
632 cppname "OutputYAxis"
633 label "Output Y Axis"
645 disablewhen "{ outputyaxis == 0 }"
649 cppname "OutputZAxis"
650 label "Output Z Axis"
659 label "Tangent (Z Axis)"
662 disablewhen "{ outputzaxis == 0 }"
671 name "outputtranslation"
672 cppname "OutputTranslation"
673 label "Output Translation"
680 name "translationname"
681 cppname "TranslationName"
685 disablewhen "{ outputtranslation == 0 }"
688 name "outputquaternion"
689 cppname "OutputQuaternion"
690 label "Output Quaternion"
697 name "quaternionname"
698 cppname "QuaternionName"
702 disablewhen "{ outputquaternion == 0 }"
705 name "outputtransform3"
706 cppname "OutputTransform3"
707 label "Output 3x3 Transform"
714 name "transform3name"
715 cppname "Transform3Name"
716 label "3x3 Transform"
718 default { "transform" }
719 disablewhen "{ outputtransform3 == 0 }"
722 name "outputtransform4"
723 cppname "OutputTransform4"
724 label "Output 4x4 Transform"
731 name "transform4name"
732 cppname "Transform4Name"
733 label "4x4 Transform"
735 default { "transform" }
736 disablewhen "{ outputtransform4 == 0 }"
746 using namespace SOP_OrientAlongCurveEnums;
747 using namespace GU_CurveFrame;
751 sopSetupTransformAttribs(
757 const exint tuple_size,
766 output_attrib =
nullptr;
784 if (output_attrib->
getStorage() != output_storage)
794 intermediate_attrib = intermediate_attrib_deleter.get();
798 intermediate_attrib = output_attrib;
804 sopCreateQuaternionAttrib(
816 sopSetupTransformAttribs<T>(
817 output_geo, cookparms, axis_attrib_name,
818 output_owner, output_storage, 4, output_attrib,
819 intermediate_attrib, intermediate_attrib_deleter,
847 auto &&functor = [output_geo,curve_group,&output_handle,&quat_attrib](
const GA_SplittableRange &
r)
857 exint num_vertices = 0;
859 for (
GA_Offset vtxoff = output_geo->pointVertex(ptoff);
GAisValid(vtxoff); vtxoff = output_geo->vertexToNextVertex(vtxoff))
864 GA_Offset primoff = output_geo->vertexPrimitive(vtxoff);
865 if (!curve_group->contains(primoff))
870 if (num_vertices == 0)
880 if (
dot(direction_sum, direction) < 0)
887 if (num_vertices == 1)
888 output_handle.set(ptoff, direction_sum);
889 else if (num_vertices > 1)
893 output_handle.set(ptoff, direction_sum);
901 point_group.combine(curve_group);
911 template<
typename T,
bool include_translates>
913 sopCreateTransformAttrib(
922 const int tuple_size = include_translates ? 16 : 9;
926 sopSetupTransformAttribs<T>(
927 output_geo, cookparms, axis_attrib_name,
928 output_owner, output_storage, tuple_size, output_attrib,
929 intermediate_attrib, intermediate_attrib_deleter,
937 if (!include_translates)
967 UT_ASSERT(output3_handle.isValid() || output4_handle.isValid());
969 auto &&functor = [output_geo,curve_group,&output3_handle,&output4_handle,&transform3_attrib,&transform4_attrib](
const GA_SplittableRange &
r)
985 exint num_vertices = 0;
987 for (
GA_Offset vtxoff = output_geo->pointVertex(ptoff);
GAisValid(vtxoff); vtxoff = output_geo->vertexToNextVertex(vtxoff))
992 GA_Offset primoff = output_geo->vertexPrimitive(vtxoff);
993 if (!curve_group->contains(primoff))
997 if (!include_translates)
1000 if (num_vertices == 0)
1003 first_matrix3 = matrix3;
1007 if (num_vertices == 1)
1014 stretch_matrix_sum += stretch_matrix;
1018 if (
dot(direction_sum, direction) < 0)
1026 if (num_vertices == 0)
1029 first_matrix4 = matrix4;
1033 if (num_vertices == 1)
1043 stretch_matrix_sum += stretch_matrix;
1047 if (
dot(direction_sum, direction) < 0)
1058 if (num_vertices == 1)
1060 if (!include_translates)
1061 output3_handle.set(ptoff, first_matrix3);
1063 output4_handle.set(ptoff, first_matrix4);
1065 else if (num_vertices > 1)
1069 stretch_matrix_sum /= num_vertices;
1075 if (!include_translates)
1077 output3_handle.set(ptoff, matrix3);
1081 translate_sum /= num_vertices;
1084 output4_handle.set(ptoff, matrix4);
1093 point_group.combine(curve_group);
1103 template<
int AXIS,
typename T>
1105 sopCreateAxisAttrib(
1117 sopSetupTransformAttribs<T>(
1118 output_geo, cookparms, axis_attrib_name,
1119 output_owner, output_storage, 3, output_attrib,
1120 intermediate_attrib, intermediate_attrib_deleter,
1128 extractAxisAttrib<AXIS>(output_geo, curve_group, transform_attrib, axis_attrib);
1140 auto &&functor = [output_geo,curve_group,&output_handle,&axis_attrib](
const GA_SplittableRange &
r)
1151 exint num_vertices = 0;
1153 for (
GA_Offset vtxoff = output_geo->pointVertex(ptoff);
GAisValid(vtxoff); vtxoff = output_geo->vertexToNextVertex(vtxoff))
1158 GA_Offset primoff = output_geo->vertexPrimitive(vtxoff);
1159 if (!curve_group->contains(primoff))
1164 if (num_vertices == 0)
1171 if (num_vertices == 1)
1176 if (
dot(direction_sum, direction) < 0)
1183 if (num_vertices == 1)
1184 output_handle.set(ptoff, direction_sum);
1185 else if (num_vertices > 1)
1189 output_handle.set(ptoff, direction_sum*(length_sum/num_vertices));
1197 point_group.combine(curve_group);
1208 void SOP_OrientAlongCurveVerb::cook(
const CookParms &cookparms)
const
1217 auto &&sopparms = cookparms.
parms<SOP_OrientAlongCurveParms>();
1228 output_geo->replaceWith(*curve_input);
1234 if (sopparms.getCurveGroup().isstring()) {
1244 cookparms.
sopAddWarning(
SOP_MESSAGE,
"Input geometry contains non-polygon primitives, so results may not be as expected");
1257 GA_RWHandleM4D transform_attrib(detached_transform_attrib.get());
1262 parms.myExtrapolateEndTangents = sopparms.getExtrapolateEndTangents();
1263 parms.myTransformByInstanceAttribs = sopparms.getTransformByAttribs();
1267 const bool applypitch = sopparms.getApplyPitch();
1268 const bool applyyaw = sopparms.getApplyYaw();
1269 const bool applyroll = sopparms.getApplyRoll();
1271 applypitch ? SYSdegToRad(sopparms.getPitch()) : 0.0,
1272 applyyaw ? SYSdegToRad(sopparms.getYaw()) : 0.0,
1273 applyroll ? SYSdegToRad(sopparms.getRoll()) : 0.0);
1274 parms.myAngles = angles;
1276 applypitch ? SYSdegToRad(sopparms.getIncPitch()) : 0.0,
1277 applyyaw ? SYSdegToRad(sopparms.getIncYaw()) : 0.0,
1278 applyroll ? SYSdegToRad(sopparms.getIncRoll() + 360.0*sopparms.getFullTwists()) : 0.0);
1279 parms.myIncAngles = incangles;
1291 parms.myRotAttribs[0].bind(output_geo->findAttribute(sopparms.getPitchAttrib(), search_order, 4));
1293 parms.myRotAttribs[1].bind(output_geo->findAttribute(sopparms.getYawAttrib(), search_order, 4));
1295 parms.myRotAttribs[2].bind(output_geo->findAttribute(sopparms.getRollAttrib(), search_order, 4));
1299 switch (sopparms.getUpVectorType())
1307 parms.myTargetUpVectorAttrib.bind(output_geo,
GA_ATTRIB_PRIMITIVE, sopparms.getUpVectorAttrib());
1308 if (!parms.myTargetUpVectorAttrib.isValid())
1310 parms.myTargetUpVectorAttrib.bind(output_geo,
GA_ATTRIB_DETAIL, sopparms.getUpVectorAttrib());
1312 if (parms.myTargetUpVectorAttrib.isValid() && parms.myTargetUpVectorAttrib->getOwner() ==
GA_ATTRIB_DETAIL)
1315 parms.myTargetUpVector = parms.myTargetUpVectorAttrib.get(
GA_DETAIL_OFFSET);
1316 parms.myTargetUpVectorAttrib.clear();
1320 if (!parms.myTargetUpVectorAttrib.isValid())
1328 case UpVectorType::CUSTOM: parms.myTargetUpVector = sopparms.getUpVector();
break;
1330 parms.myUseCurveNormalAsTargetUp = (sopparms.getUpVectorType() == UpVectorType::NORMAL);
1331 parms.myTargetUpVectorAtStart = sopparms.getUpVectorAtStart();
1332 parms.myContinuousClosedCurves = sopparms.getContinuousClosed();
1334 if (parms.myTargetUpVectorAtStart && sopparms.getUseEndUpVector())
1336 parms.myUseEndTargetUpVector =
true;
1339 parms.myEndTargetUpVectorAttrib.bind(output_geo,
GA_ATTRIB_PRIMITIVE, sopparms.getEndUpVectorAttrib());
1340 if (!parms.myEndTargetUpVectorAttrib.isValid())
1342 parms.myEndTargetUpVectorAttrib.bind(output_geo,
GA_ATTRIB_DETAIL, sopparms.getEndUpVectorAttrib());
1344 if (parms.myEndTargetUpVectorAttrib.isValid() && parms.myEndTargetUpVectorAttrib->getOwner() ==
GA_ATTRIB_DETAIL)
1347 parms.myEndTargetUpVector = parms.myEndTargetUpVectorAttrib.get(
GA_DETAIL_OFFSET);
1348 parms.myEndTargetUpVectorAttrib.clear();
1352 if (!parms.myEndTargetUpVectorAttrib.isValid())
1354 cookparms.
sopAddWarning(
SOP_MESSAGE,
"End target up vector attribute not found; defaulting to no end target up vector.");
1355 parms.myUseEndTargetUpVector =
false;
1360 else if (sopparms.getUpVectorType() == UpVectorType::CUSTOM)
1362 parms.myEndTargetUpVector = sopparms.getEndUpVector();
1366 parms.myEndTargetUpVector = parms.myTargetUpVector;
1370 parms.myNormalizeScales = sopparms.getNormalize();
1372 parms.myUniformScale = sopparms.getScale();
1373 parms.myStretchAroundTurns = sopparms.getStretchAroundTurns();
1374 parms.myMaxStretchScale = sopparms.getMaxStretchAroundTurns();
1390 (sopparms.getPrecision() == Precision::_16)
1392 : ((sopparms.getPrecision() == Precision::_32)
1398 if (sopparms.getOutputXAxis() && sopparms.getXAxisName().isstring())
1401 if (intermediate_storage == GA_STORE_REAL32)
1403 sopCreateAxisAttrib<0,fpreal32>(
1404 output_geo, curve_group, cookparms, transform_attrib,
1405 sopparms.getXAxisName(), output_owner, output_storage);
1409 sopCreateAxisAttrib<0,fpreal64>(
1410 output_geo, curve_group, cookparms, transform_attrib,
1411 sopparms.getXAxisName(), output_owner, output_storage);
1414 if (sopparms.getOutputYAxis() && sopparms.getYAxisName().isstring())
1416 if (intermediate_storage == GA_STORE_REAL32)
1418 sopCreateAxisAttrib<1,fpreal32>(
1419 output_geo, curve_group, cookparms, transform_attrib,
1420 sopparms.getYAxisName(), output_owner, output_storage);
1424 sopCreateAxisAttrib<1,fpreal64>(
1425 output_geo, curve_group, cookparms, transform_attrib,
1426 sopparms.getYAxisName(), output_owner, output_storage);
1429 if (sopparms.getOutputZAxis() && sopparms.getZAxisName().isstring())
1431 if (intermediate_storage == GA_STORE_REAL32)
1433 sopCreateAxisAttrib<2,fpreal32>(
1434 output_geo, curve_group, cookparms, transform_attrib,
1435 sopparms.getZAxisName(), output_owner, output_storage);
1439 sopCreateAxisAttrib<2,fpreal64>(
1440 output_geo, curve_group, cookparms, transform_attrib,
1441 sopparms.getZAxisName(), output_owner, output_storage);
1444 if (sopparms.getOutputTranslation() && sopparms.getTranslationName().isstring())
1446 if (intermediate_storage == GA_STORE_REAL32)
1448 sopCreateAxisAttrib<3,fpreal32>(
1449 output_geo, curve_group, cookparms, transform_attrib,
1450 sopparms.getTranslationName(), output_owner, output_storage);
1454 sopCreateAxisAttrib<3,fpreal64>(
1455 output_geo, curve_group, cookparms, transform_attrib,
1456 sopparms.getTranslationName(), output_owner, output_storage);
1459 if (sopparms.getOutputQuaternion() && sopparms.getQuaternionName().isstring())
1461 if (intermediate_storage == GA_STORE_REAL32)
1463 sopCreateQuaternionAttrib<fpreal32>(
1464 output_geo, curve_group, cookparms, transform_attrib,
1465 sopparms.getQuaternionName(), output_owner, output_storage);
1469 sopCreateQuaternionAttrib<fpreal64>(
1470 output_geo, curve_group, cookparms, transform_attrib,
1471 sopparms.getQuaternionName(), output_owner, output_storage);
1474 if (sopparms.getOutputTransform3() && sopparms.getTransform3Name().isstring())
1476 if (intermediate_storage == GA_STORE_REAL32)
1478 sopCreateTransformAttrib<fpreal32,false>(
1479 output_geo, curve_group, cookparms, transform_attrib,
1480 sopparms.getTransform3Name(), output_owner, output_storage);
1484 sopCreateTransformAttrib<fpreal64,false>(
1485 output_geo, curve_group, cookparms, transform_attrib,
1486 sopparms.getTransform3Name(), output_owner, output_storage);
1489 if (sopparms.getOutputTransform4() && sopparms.getTransform4Name().isstring())
1491 if (intermediate_storage == GA_STORE_REAL32)
1493 sopCreateTransformAttrib<fpreal32,true>(
1494 output_geo, curve_group, cookparms, transform_attrib,
1495 sopparms.getTransform4Name(), output_owner, output_storage);
1499 sopCreateTransformAttrib<fpreal64,true>(
1500 output_geo, curve_group, cookparms, transform_attrib,
1501 sopparms.getTransform4Name(), output_owner, output_storage);
static PRM_ChoiceList primGroupMenu
SYS_FORCE_INLINE void bumpDataId()
void UTparallelFor(const Range &range, const Body &body, const int subscribe_ratio=2, const int min_grain_size=1, const bool force_use_task_scope=true)
int isRefInput(OP_InputIdx i) const override
~SOP_OrientAlongCurve() override
Iteration over a range of elements.
void setChoiceListPtr(const UT_StringRef &name, PRM_ChoiceList *list)
UT_ErrorSeverity sopAddWarning(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
GOP_GroupParse::GroupCreator GroupCreator
static const UT_StringHolder theSOPTypeName
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
bool blockAdvance(GA_Offset &start, GA_Offset &end)
bool setTupleSize(int size)
CookMode cookMode(const SOP_NodeParms *parms) const override
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *op)
static const SOP_NodeVerb::Register< SOP_OrientAlongCurveVerb > theVerb
static const char *const theDsFile
This is the parameter interface string, below.
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
GA_API const UT_StringHolder P
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
void getRotationMatrix(UT_Matrix3 &mat) const
This is the SOP class definition.
SYS_FORCE_INLINE bool GAisValid(GA_Size v)
SOP_NodeParms * allocParms() const override
GA_Size countPrimitiveType(const GA_PrimitiveTypeId &type) const
SOP_OrientAlongCurve(OP_Network *net, const char *name, OP_Operator *op)
void updateFromArbitraryMatrix(const UT_Matrix3 &)
Constructs a PRM_Template list from an embedded .ds file or an istream.
const char * inputLabel(OP_InputIdx idx) const override
These are the labels that appear when hovering over the inputs.
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)
constexpr SYS_FORCE_INLINE void negate() noexcept
PRM_Template * templates() const
const GA_PrimitiveGroup * parsePrimitiveGroups(const char *pat, const GroupCreator &creator, bool numok=true, bool ordered=false, bool strict=false, GA_Index prim_offset=GA_Index(0), ParseInfo *info=0)
static SYS_FORCE_INLINE GA_ATINumeric * cast(GA_Attribute *attrib)
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
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)
SYS_FORCE_INLINE GA_ATINumericUPtr createDetachedTupleAttribute(GA_AttributeOwner owner, GA_Storage storage, int tuple_size, const GA_Defaults &defaults=GA_Defaults(0.0f), const GA_AttributeOptions *attribute_options=nullptr) const
void newSopOperator(OP_OperatorTable *table)
SYS_FORCE_INLINE const char * c_str() const
UT_Vector3T< fpreal64 > UT_Vector3D
GLuint const GLchar * name
bool setStorage(GA_Storage storage)
SYS_FORCE_INLINE const GA_Attribute * findAttribute(GA_AttributeScope scope, const UT_StringRef &name, const GA_AttributeOwner search_order[], int search_size) const
GA_API const UT_StringHolder transform
GLenum GLenum GLsizei void * table
static UT_XformOrder::xyzOrder getRotOrder(int xyz)
Translate a XYZ parameter menu index into the UT_XformOrder type.
void setTranslates(const UT_Vector3T< S > &translates)
Data represents a quaternion. Token "quaternion".
GA_API const UT_StringHolder parms
UT_StringHolder name() const override
static PRM_Template * buildTemplates()
Data represents a normal vector. Token "normal".
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
Data represents a direction vector. Token "vector".
GA_API const UT_StringHolder N
const GU_Detail * inputGeo(exint idx) const
Data represents a position in space. Token "point".
SYS_FORCE_INLINE UT_StorageMathFloat_t< T > normalize() noexcept
OP_ERROR cookMySop(OP_Context &context) override
Since this SOP implements a verb, cookMySop just delegates to the verb.
PUGI__FN char_t * translate(char_t *buffer, const char_t *from, const char_t *to, size_t to_length)
SYS_FORCE_INLINE void setTypeInfo(GA_TypeInfo type)
Data represents a transform matrix. Token "matrix".
UT_UniquePtr< GA_ATINumeric > GA_ATINumericUPtr
GU_DetailHandle & gdh() const
The initial state of gdh depends on the cookMode()
GA_Attribute * createTupleAttribute(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringHolder &name, GA_Storage storage, int tuple_size, const GA_Defaults &defaults=GA_Defaults(0.0f), const UT_Options *create_args=nullptr, const GA_AttributeOptions *attribute_options=nullptr)
void getTranslates(UT_Vector3T< S > &translates) const
bool makeRotationMatrix(UT_Matrix3T< T > *stretch=nullptr, bool reverse=true, const int max_iter=64, const T rel_tol=FLT_EPSILON)
void updateFromRotationMatrix(const UT_Matrix3 &)
UT_Matrix3T< fpreal64 > UT_Matrix3D
GA_Storage getStorage() const