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);
132 case 0:
return "Curves";
133 default:
return "Invalid Source";
150 static PRM_TemplateBuilder templ(
"SOP_OrientAlongCurve.C"_sh, SOP_OrientAlongCurveVerb::theDsFile);
160 return SOP_OrientAlongCurveVerb::theVerb.get();
172 "HDK Orientation Along Curve",
181 namespace HDK_Sample {
188 const char *
const SOP_OrientAlongCurveVerb::theDsFile = R
"THEDSFILE(
197 parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Primitives,)\nkwargs['inputindex'] = 0\nsoputils.selectGroupParm(kwargs)" }
198 parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." }
199 parmtag { "script_action_icon" "BUTTONS_reselect" }
207 cppname "TangentType"
210 default { "0" } // Default to first entry in menu, "avgdir"
212 "avgdir" "Average of Edge Directions"
213 "diff" "Central Difference"
214 "prev" "Previous Edge"
216 "none" "Z Axis (Ignore Curve)"
220 name "continuousclosed"
221 cppname "ContinuousClosed"
222 label "Make Closed Curve Orientations Continuous"
225 disablewhen "{ tangenttype == none }"
228 name "extrapolateendtangents"
229 cppname "ExtrapolateEndTangents"
230 label "Extrapolate End Tangents"
233 disablewhen "{ tangenttype == none }"
236 name "transformbyattribs"
237 cppname "TransformByAttribs"
238 label "Transform Using Point Attributes"
244 // cppname "OrientType"
245 // label "Orientation Type"
247 // default { "0" } // Default to first entry in menu, "minrot"
249 // "minrot" "Minimal Rotation"
250 // "curvature" "Curvature"
251 // "bank" "Bank Around Turns"
253 // disablewhen "{ tangenttype == none }"
263 cppname "UpVectorType"
264 label "Target Up Vector"
266 default { "0" } // Default to first entry in menu, "normal"
268 "normal" "Curve Normal"
275 disablewhen "{ tangenttype == none }"
278 // name "usenormalup"
279 // cppname "UseNormalUp"
280 // label "Use Curve Normal as Up Vector (When Valid)"
283 // disablewhen "{ tangenttype == none }"
286 name "upvectoratstart"
287 cppname "UpVectorAtStart"
288 label "Target Up Vector at Start (else Average)"
291 disablewhen "{ tangenttype == none }"
294 name "useendupvector"
295 cppname "UseEndUpVector"
296 label "Use Target End Up Vector"
299 disablewhen "{ tangenttype == none } { upvectoratstart == 0 }"
302 name "upvectorattrib"
303 cppname "UpVectorAttrib"
304 label "Start Up Attribute"
306 default { "target_up" }
307 disablewhen "{ tangenttype == none } { upvectortype != attrib }"
308 hidewhen "{ tangenttype == none } { upvectortype != attrib }"
311 name "endupvectorattrib"
312 cppname "EndUpVectorAttrib"
313 label "End Up Attribute"
315 default { "target_up_end" }
316 disablewhen "{ tangenttype == none } { upvectortype != attrib } { useendupvector == 0 } { upvectoratstart == 0 }"
317 hidewhen "{ tangenttype == none } { upvectortype != attrib } { useendupvector == 0 } { upvectoratstart == 0 }"
322 label "Start Up Vector"
325 default { "0" "1" "0" }
326 disablewhen "{ tangenttype == none } { upvectortype != custom }"
327 hidewhen "{ tangenttype == none } { upvectortype != custom }"
331 cppname "EndUpVector"
332 label "End Up Vector"
335 default { "0" "1" "0" }
336 disablewhen "{ tangenttype == none } { upvectortype != custom } { useendupvector == 0 } { upvectoratstart == 0 }"
337 hidewhen "{ tangenttype == none } { upvectortype != custom } { useendupvector == 0 } { upvectoratstart == 0 }"
345 name "rotation_folder"
346 label "Additional Rotations"
347 grouptag { "group_type" "collapsible" }
348 parmtag { "group_default" "0" }
355 // NOTE: The default rotation order X,Y,Z is semi-arbitrary, but Z
356 // should probably be last, since it always needs to twist
357 // around the curve tangent. The X and Y rotations may have
358 // just been to reorient a cross-section before copying.
361 "xyz" "Pitch, Yaw, Roll"
362 "xzy" "Pitch, Roll, Yaw"
363 "yxz" "Yaw, Pitch, Roll"
364 "yzx" "Yaw, Roll, Pitch"
365 "zxy" "Roll, Pitch, Yaw"
366 "zyx" "Roll, Yaw, Pitch"
372 label "Apply Roll or Twist"
382 hidewhen "{ applyroll == 0 }"
389 default { "4" } // Default to "fulldistance" entry in menu
392 "distance" "Per Unit Distance"
393 "attrib" "Scale by Attribute"
394 "fulledges" "Per Full Curve by Edges"
395 "fulldistance" "Per Full Curve by Distance"
397 hidewhen "{ applyroll == 0 }"
406 hidewhen "{ applyroll == 0 }"
411 label "Partial Twist"
415 hidewhen "{ applyroll == 0 }"
420 label "Twist Ramp Attribute"
423 disablewhen "{ applyroll == 0 } { applyroll == 1 rollper != attrib }"
424 hidewhen "{ applyroll == 0 } { applyroll == 1 rollper != attrib }"
431 hidewhen "{ applyroll == 0 }"
446 hidewhen "{ applyyaw == 0 }"
453 default { "4" } // Default to "fulldistance" entry in menu
456 "distance" "Per Unit Distance"
457 "attrib" "Scale By Attribute"
458 "fulledges" "Per Full Curve by Edges"
459 "fulldistance" "Per Full Curve by Distance"
461 hidewhen "{ applyyaw == 0 }"
466 label "Incremental Yaw"
470 hidewhen "{ applyyaw == 0 }"
475 label "Yaw Ramp Attribute"
478 disablewhen "{ applyyaw == 0 } { applyyaw == 1 yawper != attrib }"
479 hidewhen "{ applyyaw == 0 } { applyyaw == 1 yawper != attrib }"
486 hidewhen "{ applyyaw == 0 }"
501 hidewhen "{ applypitch == 0 }"
508 default { "4" } // Default to "fulldistance" entry in menu
511 "distance" "Per Unit Distance"
512 "attrib" "Scale By Attribute"
513 "fulledges" "Per Full Curve by Edges"
514 "fulldistance" "Per Full Curve by Distance"
516 hidewhen "{ applypitch == 0 }"
521 label "Incremental Pitch"
525 hidewhen "{ applypitch == 0 }"
529 cppname "PitchAttrib"
530 label "Pitch Ramp Attribute"
533 disablewhen "{ applypitch == 0 } { applypitch == 1 pitchper != attrib }"
534 hidewhen "{ applypitch == 0 } { applypitch == 1 pitchper != attrib }"
543 label "Scales and Shears"
544 grouptag { "group_type" "collapsible" }
545 parmtag { "group_default" "0" }
549 label "Normalize Scales"
555 label "Uniform Scale"
561 name "stretcharoundturns"
562 cppname "StretchAroundTurns"
563 label "Stretch Around Turns"
568 name "maxstretcharoundturns"
569 cppname "MaxStretchAroundTurns"
574 disablewhen "{ stretcharoundturns == 0 }"
583 label "Output Attributes"
584 grouptag { "group_type" "collapsible" }
585 parmtag { "group_default" "1" }
592 default { "0" } // Default to first entry in menu, "point"
601 // cppname "Precision"
604 // default { "1" } // Default to first entry in menu, "32"
613 cppname "OutputXAxis"
614 label "Output X Axis"
626 disablewhen "{ outputxaxis == 0 }"
630 cppname "OutputYAxis"
631 label "Output Y Axis"
643 disablewhen "{ outputyaxis == 0 }"
647 cppname "OutputZAxis"
648 label "Output Z Axis"
657 label "Tangent (Z Axis)"
660 disablewhen "{ outputzaxis == 0 }"
669 name "outputtranslation"
670 cppname "OutputTranslation"
671 label "Output Translation"
678 name "translationname"
679 cppname "TranslationName"
683 disablewhen "{ outputtranslation == 0 }"
686 name "outputquaternion"
687 cppname "OutputQuaternion"
688 label "Output Quaternion"
695 name "quaternionname"
696 cppname "QuaternionName"
700 disablewhen "{ outputquaternion == 0 }"
703 name "outputtransform3"
704 cppname "OutputTransform3"
705 label "Output 3x3 Transform"
712 name "transform3name"
713 cppname "Transform3Name"
714 label "3x3 Transform"
716 default { "transform" }
717 disablewhen "{ outputtransform3 == 0 }"
720 name "outputtransform4"
721 cppname "OutputTransform4"
722 label "Output 4x4 Transform"
729 name "transform4name"
730 cppname "Transform4Name"
731 label "4x4 Transform"
733 default { "transform" }
734 disablewhen "{ outputtransform4 == 0 }"
744 using namespace SOP_OrientAlongCurveEnums;
745 using namespace GU_CurveFrame;
749 sopSetupTransformAttribs(
755 const exint tuple_size,
764 output_attrib =
nullptr;
782 if (output_attrib->
getStorage() != output_storage)
792 intermediate_attrib = intermediate_attrib_deleter.get();
796 intermediate_attrib = output_attrib;
802 sopCreateQuaternionAttrib(
814 sopSetupTransformAttribs<T>(
815 output_geo, cookparms, axis_attrib_name,
816 output_owner, output_storage, 4, output_attrib,
817 intermediate_attrib, intermediate_attrib_deleter,
845 auto &&functor = [output_geo,curve_group,&output_handle,&quat_attrib](
const GA_SplittableRange &
r)
855 exint num_vertices = 0;
857 for (
GA_Offset vtxoff = output_geo->pointVertex(ptoff);
GAisValid(vtxoff); vtxoff = output_geo->vertexToNextVertex(vtxoff))
862 GA_Offset primoff = output_geo->vertexPrimitive(vtxoff);
863 if (!curve_group->contains(primoff))
868 if (num_vertices == 0)
878 if (
dot(direction_sum, direction) < 0)
885 if (num_vertices == 1)
886 output_handle.set(ptoff, direction_sum);
887 else if (num_vertices > 1)
891 output_handle.set(ptoff, direction_sum);
899 point_group.combine(curve_group);
909 template<
typename T,
bool include_translates>
911 sopCreateTransformAttrib(
920 const int tuple_size = include_translates ? 16 : 9;
924 sopSetupTransformAttribs<T>(
925 output_geo, cookparms, axis_attrib_name,
926 output_owner, output_storage, tuple_size, output_attrib,
927 intermediate_attrib, intermediate_attrib_deleter,
935 if (!include_translates)
965 UT_ASSERT(output3_handle.isValid() || output4_handle.isValid());
967 auto &&functor = [output_geo,curve_group,&output3_handle,&output4_handle,&transform3_attrib,&transform4_attrib](
const GA_SplittableRange &
r)
983 exint num_vertices = 0;
985 for (
GA_Offset vtxoff = output_geo->pointVertex(ptoff);
GAisValid(vtxoff); vtxoff = output_geo->vertexToNextVertex(vtxoff))
990 GA_Offset primoff = output_geo->vertexPrimitive(vtxoff);
991 if (!curve_group->contains(primoff))
995 if (!include_translates)
998 if (num_vertices == 0)
1001 first_matrix3 = matrix3;
1005 if (num_vertices == 1)
1012 stretch_matrix_sum += stretch_matrix;
1016 if (
dot(direction_sum, direction) < 0)
1024 if (num_vertices == 0)
1027 first_matrix4 = matrix4;
1031 if (num_vertices == 1)
1041 stretch_matrix_sum += stretch_matrix;
1045 if (
dot(direction_sum, direction) < 0)
1056 if (num_vertices == 1)
1058 if (!include_translates)
1059 output3_handle.set(ptoff, first_matrix3);
1061 output4_handle.set(ptoff, first_matrix4);
1063 else if (num_vertices > 1)
1067 stretch_matrix_sum /= num_vertices;
1073 if (!include_translates)
1075 output3_handle.set(ptoff, matrix3);
1079 translate_sum /= num_vertices;
1082 output4_handle.set(ptoff, matrix4);
1091 point_group.combine(curve_group);
1101 template<
int AXIS,
typename T>
1103 sopCreateAxisAttrib(
1115 sopSetupTransformAttribs<T>(
1116 output_geo, cookparms, axis_attrib_name,
1117 output_owner, output_storage, 3, output_attrib,
1118 intermediate_attrib, intermediate_attrib_deleter,
1126 extractAxisAttrib<AXIS>(output_geo, curve_group, transform_attrib, axis_attrib);
1138 auto &&functor = [output_geo,curve_group,&output_handle,&axis_attrib](
const GA_SplittableRange &
r)
1149 exint num_vertices = 0;
1151 for (
GA_Offset vtxoff = output_geo->pointVertex(ptoff);
GAisValid(vtxoff); vtxoff = output_geo->vertexToNextVertex(vtxoff))
1156 GA_Offset primoff = output_geo->vertexPrimitive(vtxoff);
1157 if (!curve_group->contains(primoff))
1162 if (num_vertices == 0)
1169 if (num_vertices == 1)
1174 if (
dot(direction_sum, direction) < 0)
1181 if (num_vertices == 1)
1182 output_handle.set(ptoff, direction_sum);
1183 else if (num_vertices > 1)
1187 output_handle.set(ptoff, direction_sum*(length_sum/num_vertices));
1195 point_group.combine(curve_group);
1206 void SOP_OrientAlongCurveVerb::cook(
const CookParms &cookparms)
const
1215 auto &&sopparms = cookparms.
parms<SOP_OrientAlongCurveParms>();
1226 output_geo->replaceWith(*curve_input);
1232 if (sopparms.getCurveGroup().isstring()) {
1242 cookparms.
sopAddWarning(
SOP_MESSAGE,
"Input geometry contains non-polygon primitives, so results may not be as expected");
1255 GA_RWHandleM4D transform_attrib(detached_transform_attrib.get());
1260 parms.myExtrapolateEndTangents = sopparms.getExtrapolateEndTangents();
1261 parms.myTransformByInstanceAttribs = sopparms.getTransformByAttribs();
1265 const bool applypitch = sopparms.getApplyPitch();
1266 const bool applyyaw = sopparms.getApplyYaw();
1267 const bool applyroll = sopparms.getApplyRoll();
1269 applypitch ? SYSdegToRad(sopparms.getPitch()) : 0.0,
1270 applyyaw ? SYSdegToRad(sopparms.getYaw()) : 0.0,
1271 applyroll ? SYSdegToRad(sopparms.getRoll()) : 0.0);
1272 parms.myAngles = angles;
1274 applypitch ? SYSdegToRad(sopparms.getIncPitch()) : 0.0,
1275 applyyaw ? SYSdegToRad(sopparms.getIncYaw()) : 0.0,
1276 applyroll ? SYSdegToRad(sopparms.getIncRoll() + 360.0*sopparms.getFullTwists()) : 0.0);
1277 parms.myIncAngles = incangles;
1289 parms.myRotAttribs[0].bind(output_geo->findAttribute(sopparms.getPitchAttrib(), search_order, 4));
1291 parms.myRotAttribs[1].bind(output_geo->findAttribute(sopparms.getYawAttrib(), search_order, 4));
1293 parms.myRotAttribs[2].bind(output_geo->findAttribute(sopparms.getRollAttrib(), search_order, 4));
1297 switch (sopparms.getUpVectorType())
1305 parms.myTargetUpVectorAttrib.bind(output_geo,
GA_ATTRIB_PRIMITIVE, sopparms.getUpVectorAttrib());
1306 if (!parms.myTargetUpVectorAttrib.isValid())
1308 parms.myTargetUpVectorAttrib.bind(output_geo,
GA_ATTRIB_DETAIL, sopparms.getUpVectorAttrib());
1310 if (parms.myTargetUpVectorAttrib.isValid() && parms.myTargetUpVectorAttrib->getOwner() ==
GA_ATTRIB_DETAIL)
1313 parms.myTargetUpVector = parms.myTargetUpVectorAttrib.get(
GA_DETAIL_OFFSET);
1314 parms.myTargetUpVectorAttrib.clear();
1318 if (!parms.myTargetUpVectorAttrib.isValid())
1326 case UpVectorType::CUSTOM: parms.myTargetUpVector = sopparms.getUpVector();
break;
1328 parms.myUseCurveNormalAsTargetUp = (sopparms.getUpVectorType() == UpVectorType::NORMAL);
1329 parms.myTargetUpVectorAtStart = sopparms.getUpVectorAtStart();
1330 parms.myContinuousClosedCurves = sopparms.getContinuousClosed();
1332 if (parms.myTargetUpVectorAtStart && sopparms.getUseEndUpVector())
1334 parms.myUseEndTargetUpVector =
true;
1337 parms.myEndTargetUpVectorAttrib.bind(output_geo,
GA_ATTRIB_PRIMITIVE, sopparms.getEndUpVectorAttrib());
1338 if (!parms.myEndTargetUpVectorAttrib.isValid())
1340 parms.myEndTargetUpVectorAttrib.bind(output_geo,
GA_ATTRIB_DETAIL, sopparms.getEndUpVectorAttrib());
1342 if (parms.myEndTargetUpVectorAttrib.isValid() && parms.myEndTargetUpVectorAttrib->getOwner() ==
GA_ATTRIB_DETAIL)
1345 parms.myEndTargetUpVector = parms.myEndTargetUpVectorAttrib.get(
GA_DETAIL_OFFSET);
1346 parms.myEndTargetUpVectorAttrib.clear();
1350 if (!parms.myEndTargetUpVectorAttrib.isValid())
1352 cookparms.
sopAddWarning(
SOP_MESSAGE,
"End target up vector attribute not found; defaulting to no end target up vector.");
1353 parms.myUseEndTargetUpVector =
false;
1358 else if (sopparms.getUpVectorType() == UpVectorType::CUSTOM)
1360 parms.myEndTargetUpVector = sopparms.getEndUpVector();
1364 parms.myEndTargetUpVector = parms.myTargetUpVector;
1368 parms.myNormalizeScales = sopparms.getNormalize();
1370 parms.myUniformScale = sopparms.getScale();
1371 parms.myStretchAroundTurns = sopparms.getStretchAroundTurns();
1372 parms.myMaxStretchScale = sopparms.getMaxStretchAroundTurns();
1388 (sopparms.getPrecision() == Precision::_16)
1390 : ((sopparms.getPrecision() == Precision::_32)
1396 if (sopparms.getOutputXAxis() && sopparms.getXAxisName().isstring())
1399 if (intermediate_storage == GA_STORE_REAL32)
1401 sopCreateAxisAttrib<0,fpreal32>(
1402 output_geo, curve_group, cookparms, transform_attrib,
1403 sopparms.getXAxisName(), output_owner, output_storage);
1407 sopCreateAxisAttrib<0,fpreal64>(
1408 output_geo, curve_group, cookparms, transform_attrib,
1409 sopparms.getXAxisName(), output_owner, output_storage);
1412 if (sopparms.getOutputYAxis() && sopparms.getYAxisName().isstring())
1414 if (intermediate_storage == GA_STORE_REAL32)
1416 sopCreateAxisAttrib<1,fpreal32>(
1417 output_geo, curve_group, cookparms, transform_attrib,
1418 sopparms.getYAxisName(), output_owner, output_storage);
1422 sopCreateAxisAttrib<1,fpreal64>(
1423 output_geo, curve_group, cookparms, transform_attrib,
1424 sopparms.getYAxisName(), output_owner, output_storage);
1427 if (sopparms.getOutputZAxis() && sopparms.getZAxisName().isstring())
1429 if (intermediate_storage == GA_STORE_REAL32)
1431 sopCreateAxisAttrib<2,fpreal32>(
1432 output_geo, curve_group, cookparms, transform_attrib,
1433 sopparms.getZAxisName(), output_owner, output_storage);
1437 sopCreateAxisAttrib<2,fpreal64>(
1438 output_geo, curve_group, cookparms, transform_attrib,
1439 sopparms.getZAxisName(), output_owner, output_storage);
1442 if (sopparms.getOutputTranslation() && sopparms.getTranslationName().isstring())
1444 if (intermediate_storage == GA_STORE_REAL32)
1446 sopCreateAxisAttrib<3,fpreal32>(
1447 output_geo, curve_group, cookparms, transform_attrib,
1448 sopparms.getTranslationName(), output_owner, output_storage);
1452 sopCreateAxisAttrib<3,fpreal64>(
1453 output_geo, curve_group, cookparms, transform_attrib,
1454 sopparms.getTranslationName(), output_owner, output_storage);
1457 if (sopparms.getOutputQuaternion() && sopparms.getQuaternionName().isstring())
1459 if (intermediate_storage == GA_STORE_REAL32)
1461 sopCreateQuaternionAttrib<fpreal32>(
1462 output_geo, curve_group, cookparms, transform_attrib,
1463 sopparms.getQuaternionName(), output_owner, output_storage);
1467 sopCreateQuaternionAttrib<fpreal64>(
1468 output_geo, curve_group, cookparms, transform_attrib,
1469 sopparms.getQuaternionName(), output_owner, output_storage);
1472 if (sopparms.getOutputTransform3() && sopparms.getTransform3Name().isstring())
1474 if (intermediate_storage == GA_STORE_REAL32)
1476 sopCreateTransformAttrib<fpreal32,false>(
1477 output_geo, curve_group, cookparms, transform_attrib,
1478 sopparms.getTransform3Name(), output_owner, output_storage);
1482 sopCreateTransformAttrib<fpreal64,false>(
1483 output_geo, curve_group, cookparms, transform_attrib,
1484 sopparms.getTransform3Name(), output_owner, output_storage);
1487 if (sopparms.getOutputTransform4() && sopparms.getTransform4Name().isstring())
1489 if (intermediate_storage == GA_STORE_REAL32)
1491 sopCreateTransformAttrib<fpreal32,true>(
1492 output_geo, curve_group, cookparms, transform_attrib,
1493 sopparms.getTransform4Name(), output_owner, output_storage);
1497 sopCreateTransformAttrib<fpreal64,true>(
1498 output_geo, curve_group, cookparms, transform_attrib,
1499 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)
~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
int isRefInput(unsigned i) const override
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.
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".
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()
TangentType myTangentType
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)
const char * inputLabel(unsigned idx) const override
These are the labels that appear when hovering over the inputs.
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