36 #include "SOP_CopyToPointsHDK.proto.h"
62 using namespace UT::Literal;
64 namespace HDK_Sample {
66 using namespace GU_Copy;
85 {
return COOK_GENERIC; }
87 void cook(
const CookParms &cookparms)
const override;
105 const UT_StringHolder SOP_CopyToPointsHDKVerb::theSOPTypeName(
"hdk_copytopoints"_sh);
113 const char *
const SOP_CopyToPointsHDKVerb::theDsFile = R
"THEDSFILE(
118 cppname "SourceGroup"
122 parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = kwargs['node'].parmTuple('sourcegrouptype')\nkwargs['inputindex'] = 0\nsoputils.selectGroupParm(kwargs)" }
123 parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." }
124 parmtag { "script_action_icon" "BUTTONS_reselect" }
125 parmtag { "sop_input" "0" }
128 name "sourcegrouptype"
129 cppname "SourceGroupType"
130 label "Source Group Type"
134 "guess" "Guess from Group"
141 cppname "TargetGroup"
142 label "Target Points"
145 parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Points,)\nkwargs['inputindex'] = 1\nsoputils.selectGroupParm(kwargs)" }
146 parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." }
147 parmtag { "script_action_icon" "BUTTONS_reselect" }
148 parmtag { "sop_input" "1" }
152 cppname "UseIDAttrib"
153 label "Piece Attribute"
162 label "Piece Attribute"
164 default { "variant" }
165 parmtag { "sop_input" "1" }
166 disablewhen "{ useidattrib == 0 }"
170 label "Pack and Instance"
176 label "Pivot Location"
178 default { "centroid" }
179 hidewhen "{ pack == 0 }"
182 "centroid" "Centroid"
187 cppname "ViewportLOD"
191 hidewhen "{ pack == 0 }"
193 "full" "Full Geometry"
194 "points" "Point Cloud"
196 "centroid" "Centroid"
202 label "Transform Using Target Point Orientations"
208 cppname "UseImplicitN"
209 label "Transform Using Implicit Target Point Normals If No Point N Attribute"
212 disablewhen "{ transform == 0 }"
215 name "resettargetattribs"
216 label "Reset Attributes from Target"
222 cppname "TargetAttribs"
223 label "Attributes from Target"
228 label "Apply Attributes"
264 parmtag { "sop_input" "1" }
277 static const char *
const theViewportLODNames[5] =
298 using namespace SOP_CopyToPointsHDKEnums;
304 case Pivot::CENTROID:
324 void resetTargetAttribs();
327 const char *inputLabel(
unsigned idx)
const override;
328 int isRefInput(
unsigned int i)
const;
332 sopResetTargetAttribsWrapper(
345 SOP_CopyToPointsHDK::resetTargetAttribs()
347 setInt(
"targetattribs", 0,
fpreal(0.0), 3);
348 int multiparm_index = 1;
349 setIntInst(1,
"useapply#", &multiparm_index, 0,
fpreal(0.0));
350 setIntInst(0,
"applyto#", &multiparm_index, 0,
fpreal(0.0));
351 setIntInst(
int(sop_AttribCombineMethod::COPY),
"applymethod#", &multiparm_index, 0,
fpreal(0.0));
352 setStringInst(
"*,^v,^Alpha,^N,^up,^pscale,^scale,^orient,^rot,^pivot,^trans,^transform",
CH_StringMeaning::CH_STRING_LITERAL,
"applyattribs#", &multiparm_index, 0,
fpreal(0.0));
354 setIntInst(1,
"useapply#", &multiparm_index, 0,
fpreal(0.0));
355 setIntInst(0,
"applyto#", &multiparm_index, 0,
fpreal(0.0));
356 setIntInst(
int(sop_AttribCombineMethod::MULTIPLY),
"applymethod#", &multiparm_index, 0,
fpreal(0.0));
359 setIntInst(1,
"useapply#", &multiparm_index, 0,
fpreal(0.0));
360 setIntInst(0,
"applyto#", &multiparm_index, 0,
fpreal(0.0));
361 setIntInst(
int(sop_AttribCombineMethod::ADD),
"applymethod#", &multiparm_index, 0,
fpreal(0.0));
366 sopApproveStringIntAttribs(
const GA_Attribute *attrib,
void*)
378 sopBuildStringIntPointAttribMenu(
379 void *data,
PRM_Name *menu_entries,
int menu_size,
382 SOP_CopyToPointsHDK *sop = (SOP_CopyToPointsHDK *)data;
383 if (!sop || !sop->getInput(1))
386 sop->fillAttribNameMenu(menu_entries, menu_size,
391 sopBuildTargetPointAttribMenu(
392 void *data,
PRM_Name *menu_entries,
int menu_size,
395 SOP_CopyToPointsHDK *sop = (SOP_CopyToPointsHDK *)data;
396 if (!sop || !sop->getInput(1))
399 sop->fillAttribNameMenu(menu_entries, menu_size,
405 sopBuildStringIntPointAttribMenu);
409 sopBuildTargetPointAttribMenu);
412 SOP_CopyToPointsHDK::buildTemplates()
414 static PRM_TemplateBuilder templ(
"SOP_CopyToPointsHDK.C"_sh, SOP_CopyToPointsHDKVerb::theDsFile);
421 templ.
setCallback(
"resettargetattribs", &sopResetTargetAttribsWrapper);
453 if (param_group_type == SOP_CopyToPointsHDKEnums::SourceGroupType::POINTS)
455 else if (param_group_type == SOP_CopyToPointsHDKEnums::SourceGroupType::PRIMS)
459 OP_ERROR ret =
cookInputAllGroups(context, source_group, alone,
true, 0, 1, group_type,
true,
true,
false,
GroupCreator(detail));
490 "HDK Copy to Points",
499 namespace HDK_Sample {
507 const SOP_CopyToPointsHDKParms &sopparms,
508 SOP_CopyToPointsHDKCache *sopcache,
513 const bool source_topology_changed,
537 buf.
appendSprintf(
"Target Piece Attribute (%s) is a floating-point "
538 "attribute; it must be an integer or string attribute, "
539 "so ignoring Piece Attribute.",
540 idattribname.
c_str());
546 if (!source_int_idattrib.
isValid())
554 target_int_idattrib.
bind(idnumeric);
561 if (!source_str_idattrib.
isValid())
565 if (!source_str_idattrib.
isValid())
569 "attribute; source has no corresponding string point or "
570 "primitive attribute, so ignoring Piece Attribute.",
571 idattribname.
c_str());
576 target_str_idattrib.
bind(idstring);
577 source_id_owner = source_str_idattrib->
getOwner();
583 "or string attribute in the target input, so ignoring Piece Attribute.",
584 idattribname.
c_str());
589 bool target_group_changed =
590 (target_group !=
nullptr) != (sopcache->myPrevHadTargetGroup);
591 bool target_group_maybe_changed = target_group_changed;
592 if (!target_group_changed && target_group)
596 bool different_group = target_group->
isDetached() ||
597 (target_group->
getDataId() != sopcache->myPrevTargetGroupDataID);
598 target_group_maybe_changed = different_group;
604 bool topology_changed =
605 (output_geo->
getUniqueId() != sopcache->myPrevOutputDetailID) ||
606 source_topology_changed ||
607 target_group_changed ||
608 (sopparms.getPack() != sopcache->myPrevPack);
611 topology_changed |= (target_idattrib_dataid != sopcache->myTargetIDAttribDataID);
612 sopcache->myTargetIDAttribDataID = target_idattrib_dataid;
614 topology_changed |= (source_id_owner != sopcache->mySourceIDAttribOwner);
615 sopcache->mySourceIDAttribOwner = source_id_owner;
618 if (source_int_idattrib.
isValid())
620 source_idattrib_dataid = source_int_idattrib->
getDataId();
621 topology_changed |= (source_idattrib_dataid != sopcache->mySourceIDAttribDataID);
623 else if (source_str_idattrib.
isValid())
625 source_idattrib_dataid = source_str_idattrib->
getDataId();
626 topology_changed |= (source_idattrib_dataid != sopcache->mySourceIDAttribDataID);
635 sopcache->mySourceIDAttribDataID = source_idattrib_dataid;
637 using PieceData = SOP_CopyToPointsHDKCache::PieceData;
641 bool recompute_mapping = topology_changed || target_group_maybe_changed;
642 if (recompute_mapping)
653 if (target_int_idattrib.
isValid())
669 bool new_value = !target_int_to_source.
contains(value);
672 std::pair<exint,GA_OffsetList> &pair = target_int_to_source[
value];
674 pair.first =
GA_Size(end-start);
677 pair.first +=
GA_Size(end-start);
681 if (!source_int_idattrib.
isValid() &&
688 if (!source_primgroup || source_primgroup->
contains(source_primoff))
689 pair.second.append(source_primoff);
694 for (
GA_Offset target_ptoff = start; target_ptoff <
end; ++target_ptoff)
696 exint value = target_int_idattrib.
get(target_ptoff);
701 bool new_value = !target_int_to_source.
contains(value);
704 std::pair<exint,GA_OffsetList> &pair = target_int_to_source[
value];
713 if (!source_int_idattrib.
isValid() &&
720 if (!source_primgroup || source_primgroup->
contains(source_primoff))
721 pair.second.append(source_primoff);
727 if (source_int_idattrib.
isValid())
747 exint value = source_int_idattrib.
get(start);
751 if (!target_int_to_source.
contains(value))
760 for (
GA_Offset source_offset = start; source_offset <
end; ++source_offset)
762 exint value = source_int_idattrib.
get(source_offset);
766 if (!target_int_to_source.
contains(value))
770 list.
append(source_offset);
778 exint original_num_integers = target_int_to_source.
size();
779 for (
auto it = target_int_to_source.
begin(); !it.atEnd(); )
781 if (it->second.second.size() == 0)
782 it = target_int_to_source.
erase(it);
786 if (target_int_to_source.
size() != original_num_integers)
788 for (
exint i = 0,
n = input_target_point_list.
size(); i <
n; ++i)
790 GA_Offset ptoff = input_target_point_list[i];
791 exint value = target_int_idattrib.
get(ptoff);
792 if (target_int_to_source.
contains(value))
793 limited_target_point_list_nc.append(ptoff);
795 input_target_point_list = std::move(limited_target_point_list_nc);
813 bool new_value = !target_str_to_source.
contains(value);
816 std::pair<exint,GA_OffsetList> &pair = target_str_to_source[
value];
818 pair.first =
GA_Size(end-start);
820 pair.first +=
GA_Size(end-start);
824 for (
GA_Offset target_ptoff = start; target_ptoff <
end; ++target_ptoff)
829 bool new_value = !target_str_to_source.
contains(value);
832 std::pair<exint,GA_OffsetList> &pair = target_str_to_source[
value];
859 if (!target_str_to_source.
contains(value))
868 for (
GA_Offset source_offset = start; source_offset <
end; ++source_offset)
872 if (!target_str_to_source.
contains(value))
876 list.
append(source_offset);
883 exint original_num_strings = target_str_to_source.
size();
884 for (
auto it = target_str_to_source.
begin(); !it.atEnd(); )
886 if (it->second.second.size() == 0)
887 it = target_str_to_source.
erase(it);
891 if (target_str_to_source.
size() != original_num_strings)
893 for (
exint i = 0, n = input_target_point_list.
size(); i <
n; ++i)
895 GA_Offset ptoff = input_target_point_list[i];
897 if (target_str_to_source.
contains(value))
898 limited_target_point_list_nc.append(ptoff);
900 input_target_point_list = std::move(limited_target_point_list_nc);
906 target_group_changed |=
907 (!target_group && input_target_point_list.
size() != sopcache->myPrevTargetPtCount);
908 if (!target_group_changed && target_group)
911 bool different_group = target_group->
isDetached() ||
912 (target_group->
getDataId() != sopcache->myPrevTargetGroupDataID);
915 UT_ASSERT(sopcache->myTargetOffsetList.size() == input_target_point_list.
size());
916 bool equal_group = sopcache->myTargetOffsetList.isEqual(input_target_point_list, 0, input_target_point_list.
size());
919 target_group_changed =
true;
923 sopcache->myTargetOffsetList = input_target_point_list;
924 sopcache->myPrevHadTargetGroup = (target_group !=
nullptr);
926 topology_changed |= target_group_changed;
931 if (topology_changed)
938 if (!target_int_to_source.
empty())
942 for (
auto it = target_int_to_source.
ordered_begin(std::less<exint>()); !it.atEnd(); ++it, ++piecei)
944 PieceData ¤t_piece = piece_data[piecei];
945 current_piece.myRefCount = it->second.first;
947 it->second.first = piecei;
949 current_piece.mySourceOffsetLists[source_id_owner] = std::move(it->second.second);
952 else if (!target_str_to_source.
empty())
956 for (
auto it = target_str_to_source.
ordered_begin(std::less<UT_StringHolder>()); !it.atEnd(); ++it, ++piecei)
958 PieceData ¤t_piece = piece_data[piecei];
959 current_piece.myRefCount = it->second.first;
961 it->second.first = piecei;
963 current_piece.mySourceOffsetLists[source_id_owner] = std::move(it->second.second);
967 exint num_target_points = input_target_point_list.
size();
972 if (target_int_idattrib.
isValid())
974 for (
exint target_pointi = 0; target_pointi < num_target_points; ++target_pointi)
976 GA_Offset target_ptoff = input_target_point_list[target_pointi];
977 exint target_value = target_int_idattrib.
get(target_ptoff);
978 exint piecei = target_int_to_source[target_value].first;
979 target_to_piecei[target_pointi] = piecei;
985 for (
exint target_pointi = 0; target_pointi < num_target_points; ++target_pointi)
987 GA_Offset target_ptoff = input_target_point_list[target_pointi];
989 exint piecei = target_str_to_source[target_value].first;
990 target_to_piecei[target_pointi] = piecei;
998 bool had_transform_matrices = (sopcache->myTransformMatrices3D.get() !=
nullptr);
1006 bool transforms_changed = target_group_changed;
1007 GUsetupPointTransforms(sopcache, target_point_list, target, sopparms.getTransform(), sopparms.getUseImplicitN(), transforms_changed);
1009 const bool has_transform_matrices = (sopcache->myTransformMatrices3D.get() !=
nullptr);
1011 if (topology_changed)
1014 const exint npieces = piece_data.
size();
1015 for (
exint piecei = 0; piecei < npieces; ++piecei)
1017 PieceData ¤t_piece = piece_data[piecei];
1027 if (source_point_list.
size() == 1)
1042 source_prim_list.
append(primoff);
1050 for (
exint i = 0, n = source_point_list.
size(); i <
n; ++i)
1053 points_in_piece.
set<
true>(ptoff);
1057 prims_in_piece.set<
true>(primoff);
1068 prims_in_piece.getConstantSpan(start, end, size, value);
1075 for (
GA_Offset primoff = start; primoff < local_end; ++primoff)
1077 bool all_points_present =
true;
1079 for (
exint i = 0, n = vertices.
size(); i <
n; ++i)
1082 all_points_present &= points_in_piece.get(ptoff);
1084 if (all_points_present)
1085 source_prim_list.
append(primoff);
1103 for (
exint i = 0, n = source_prim_list.
size(); i <
n; ++i)
1105 GA_Offset primoff = source_prim_list[i];
1107 for (
exint i = 0, n = vertices.
size(); i <
n; ++i)
1110 points_in_piece.set<
true>(ptoff);
1119 points_in_piece.getConstantSpan(start, end, size, value);
1133 for (
exint i = 0, n = source_prim_list.
size(); i <
n; ++i)
1135 GA_Offset primoff = source_prim_list[i];
1137 source_vert_list.
append(vertices);
1141 exint nvertices = source_vert_list.
size();
1142 if (nvertices < 16 || source_point_list.
isTrivial())
1147 for (
exint i = 0; i < nvertices; ++i)
1151 exint rel_pointi = source_point_list.
find(ptoff);
1152 current_piece.myRelVtxToPt.append(rel_pointi);
1159 exint npoints = source_point_list.
size();
1162 ptoff_to_piecei.
reserve(npoints);
1164 for (
exint pointi = 0; pointi < npoints; ++pointi)
1166 GA_Offset ptoff = source_point_list[pointi];
1167 ptoff_to_piecei[ptoff] = pointi;
1170 for (
exint i = 0; i < nvertices; ++i)
1174 exint rel_pointi = ptoff_to_piecei[ptoff];
1175 current_piece.myRelVtxToPt.append(rel_pointi);
1181 const exint npieces = piece_data.
size();
1182 const exint num_target_points = target_to_piecei.
size();
1184 if (sopparms.getPack())
1186 const GEO_ViewportLOD lod = sopViewportLODFromParam(sopparms.getViewportLOD());
1187 const bool source_changed =
1188 source->
getUniqueId() != sopcache->myPrevSourceUniqueID ||
1190 source_topology_changed;
1191 const bool lod_changed = (lod != sopcache->myPrevViewportLOD);
1192 const bool source_intrinsic_changed =
1194 sopCachePivotType(sopparms.getPivot()) != sopcache->myPrevPivotEnum ||
1202 if (topology_changed || source_changed)
1206 if (num_target_points > 0)
1210 packed_geos.setSizeNoInit(npieces);
1214 for (
exint piecei = r.begin(), end = r.end(); piecei <
end; ++piecei)
1216 PieceData ¤t_piece = piece_data[piecei];
1231 exint num_source_attribs[3] = {0,0,0};
1233 "Array above depends on owners other than detail being less than 3");
1237 num_source_attribs);
1246 "Arrays above and loop below are assuming the order of GA_AttributeOwner enum");
1251 output_splittable_ranges,
1255 current_piece.mySourceOffsetLists,
1274 packed_geos[piecei] = packed_geo;
1279 bool centroid_pivot = (sopparms.getPivot() == SOP_CopyToPointsHDKEnums::Pivot::CENTROID);
1281 if (topology_changed || source_intrinsic_changed)
1286 auto &&functor = [output_geo,&packed_geos,start_primoff,
1287 &target_to_piecei,centroid_pivot,
lod,
1290 exint target_pointi =
GA_Size(r.begin()-start_primoff);
1291 for (
GA_Offset primoff = r.begin(), end = r.end(); primoff <
end; ++primoff, ++target_pointi)
1295 exint piecei = target_to_piecei[target_pointi];
1297 if (topology_changed || source_changed)
1325 constexpr
exint PARALLEL_THRESHOLD = 256;
1326 if (num_target_points >= PARALLEL_THRESHOLD)
1329 functor(prim_range);
1332 const bool pivots_changed =
1333 sopCachePivotType(sopparms.getPivot()) != sopcache->myPrevPivotEnum ||
1334 (centroid_pivot && source_changed);
1343 had_transform_matrices,
1348 !centroid_pivot ? &pivot :
nullptr);
1350 if (topology_changed)
1358 if (transforms_changed || pivots_changed)
1363 bool has_transform_matrices = (sopcache->myTransformMatrices3D.get() !=
nullptr);
1364 if ((has_transform_matrices || had_transform_matrices) && !source_changed)
1372 sopcache->myPrevPack =
true;
1373 sopcache->myPrevTargetPtCount = num_target_points;
1374 sopcache->myPrevSourceGroupDataID = source->
getUniqueId();
1376 sopcache->myPrevPivotEnum = sopCachePivotType(sopparms.getPivot());
1377 sopcache->myPrevViewportLOD =
lod;
1378 sopcache->myPrevOutputDetailID = output_geo->
getUniqueId();
1379 sopcache->myPrevSourceUniqueID = source->
getUniqueId();
1389 sopcache->mySourceEdgeGroupDataIDs.clear();
1397 if (topology_changed)
1403 for (
exint piecei = r.begin(), end = r.end(); piecei <
end; ++piecei)
1405 PieceData ¤t_piece = piece_data[piecei];
1416 bool hassharedpoints =
true;
1419 bool hascontiguouspoints =
false;
1423 exint piece_point_count = piece_point_list.
size();
1424 exint piece_vertex_count = piece_vertex_list.
size();
1425 exint piece_prim_count = piece_prim_list.
size();
1426 UT_ASSERT_P(piece_vertex_count == current_piece.myRelVtxToPt.size());
1427 if (piece_point_count >= piece_vertex_count)
1434 hascontiguouspoints = current_piece.myRelVtxToPt.isTrivial();
1435 hassharedpoints =
false;
1437 if (!hascontiguouspoints && piece_vertex_count > 0)
1443 exint last_point = current_piece.myRelVtxToPt[0];
1444 for (
exint vtxi = 1; vtxi < piece_vertex_count; ++vtxi)
1446 exint current_point = current_piece.myRelVtxToPt[vtxi];
1453 hassharedpoints |= (current_point <= last_point);
1454 if (hassharedpoints)
1456 last_point = current_point;
1460 current_piece.myHasSharedPoints = hassharedpoints;
1461 current_piece.myHasContiguousPoints = hascontiguouspoints;
1463 GA_PolyCounts &vertexlistsizelist = current_piece.myVertexListSizeList;
1464 vertexlistsizelist.
clear();
1465 auto &prim_type_count_pairs = current_piece.myPrimTypeCountPairs;
1466 prim_type_count_pairs.clear();
1468 closed_span_lengths.
clear();
1470 if (piece_prim_count > 0)
1475 vertexlistsizelist.
append(vertex_count);
1478 prim_type_count_pairs.append(std::make_pair(primtype,1));
1485 closed_span_lengths.
append(0);
1487 closed_span_lengths.
append(1);
1489 for (
exint primi = 1; primi < piece_prim_count; ++primi)
1491 GA_Offset primoff = piece_prim_list[primi];
1494 vertexlistsizelist.
append(vertex_count);
1497 if (prim_type_count_pairs.last().first == primtype)
1498 ++(prim_type_count_pairs.last().second);
1500 prim_type_count_pairs.append(std::make_pair(primtype,1));
1506 if ((closed_span_lengths.
size()&1) ==
exint(closed))
1507 closed_span_lengths.
append(1);
1509 ++(closed_span_lengths.
last());
1517 bool hassharedpoints =
false;
1518 bool hascontiguouspoints =
true;
1519 exint total_nvertices = 0;
1520 exint total_nprims = 0;
1521 for (
exint piecei = 0; piecei < npieces; ++piecei)
1523 PieceData ¤t_piece = piece_data[piecei];
1524 hassharedpoints |= current_piece.myHasSharedPoints;
1525 hascontiguouspoints &= current_piece.myHasContiguousPoints;
1528 total_nvertices += current_piece.myRefCount * piece_nvertices;
1529 total_nprims += current_piece.myRefCount * piece_nprims;
1535 if (total_nprims > 0)
1536 closed_span_lengths.
append(0);
1540 vertexpointnumbers.
setSizeNoInit(hascontiguouspoints ? 0 : total_nvertices);
1547 exint piece_point_start = 0;
1548 exint piece_vertex_start = 0;
1549 exint piece_prim_start = 0;
1550 for (
exint targeti = 0; targeti < num_target_points; ++targeti)
1552 exint piecei = target_to_piecei[targeti];
1553 PieceData ¤t_piece = piece_data[piecei];
1555 piece_point_starts[targeti] = piece_point_start;
1556 piece_vertex_starts[targeti] = piece_vertex_start;
1557 piece_prim_starts[targeti] = piece_prim_start;
1563 exint num_prim_type_count_pairs = current_piece.myPrimTypeCountPairs.size();
1564 if (num_prim_type_count_pairs > 0)
1567 if (prim_type_count_pairs.
size() > 0 &&
1568 prim_type_count_pairs.
last().first == current_piece.myPrimTypeCountPairs[0].first)
1570 prim_type_count_pairs.
last().second += current_piece.myPrimTypeCountPairs[0].second;
1573 for (; pairi < num_prim_type_count_pairs; ++pairi)
1575 prim_type_count_pairs.
append(current_piece.myPrimTypeCountPairs[pairi]);
1578 vertexlistsizelist.
append(current_piece.myVertexListSizeList);
1580 if (!vertexpointnumbers.
isEmpty())
1582 for (
exint i = 0; i < local_nvertices; ++i)
1584 vertexpointnumbers[piece_vertex_start+i] = current_piece.myRelVtxToPt[i] + piece_point_start;
1588 auto &local_closed_span_lengths = current_piece.myClosedSpanLengths;
1589 exint spani = (local_closed_span_lengths[0] == 0);
1590 if (((closed_span_lengths.
size()-1)&1) == (spani&1))
1592 closed_span_lengths.
last() += local_closed_span_lengths[spani];
1595 for (
exint nspans = local_closed_span_lengths.size(); spani < nspans; ++spani)
1597 closed_span_lengths.
append(local_closed_span_lengths[spani]);
1601 piece_point_start += local_npoints;
1602 piece_vertex_start += local_nvertices;
1603 piece_prim_start += local_nprims;
1606 exint total_npoints = piece_point_start;
1623 exint num_polys_and_tets =
1630 auto &&functor = [output_geo,
source,&piece_prim_starts,start_primoff,
1633 exint output_primi = r.begin() - start_primoff;
1637 exint targeti = (std::upper_bound(
1638 piece_prim_starts.getArray(),
1639 piece_prim_starts.getArray()+piece_prim_starts.size(),
1640 output_primi) - piece_prim_starts.getArray()) - 1;
1641 UT_ASSERT_P(targeti >= 0 && targeti < num_target_points);
1643 exint piece_prim_start = piece_prim_starts[targeti];
1644 exint piece_primi = output_primi - piece_prim_start;
1645 exint piecei = target_to_piecei[targeti];
1646 PieceData *current_piece = &piece_data[piecei];
1649 for (
GA_Offset dest_off = r.begin(), end = r.end(); dest_off <
end; ++dest_off)
1651 GA_Offset source_off = (*piece_prim_list)[piece_primi];
1652 const GA_Primitive *source_prim = source->getPrimitive(source_off);
1658 while (piece_primi >= piece_prim_list->
size())
1662 if (targeti >= num_target_points)
1664 piecei = target_to_piecei[targeti];
1665 current_piece = &piece_data[piecei];
1680 sopcache->myPrevOutputDetailID = output_geo->
getUniqueId();
1681 sopcache->myPrevTargetPtCount = num_target_points;
1682 sopcache->myPrevPack =
false;
1690 sopcache->mySourceEdgeGroupDataIDs.clear();
1691 sopcache->myTargetAttribInfo.clear();
1692 sopcache->myTargetGroupInfo.clear();
1697 if (!topology_changed)
1704 &target_attrib_info,
1705 &target_group_info);
1710 needed_transforms[i] =
false;
1713 exint num_source_attribs[3] = {0,0,0};
1714 exint num_target_attribs[3] = {0,0,0};
1716 "Arrays above are assuming the order of GA_AttributeOwner enum");
1722 has_transform_matrices,
1725 &target_attrib_info,
1727 num_target_attribs);
1746 "Arrays above and loop below are assuming the order of GA_AttributeOwner enum");
1750 cookparms.
sopAddWarning(
SOP_MESSAGE,
"Edge groups aren't yet supported when Piece Attribute is enabled and Pack and Instance is disabled.");
1755 output_splittable_ranges,
1759 sopcache->mySourceOffsetLists,
1762 had_transform_matrices,
1763 has_transform_matrices,
1767 &target_attrib_info,
1769 target_to_piecei.getArray(),
1770 sopcache->myPieceOffsetStarts,
1771 piece_data.getArray());
1777 output_splittable_ranges,
1789 target_to_piecei.getArray(),
1790 sopcache->myPieceOffsetStarts,
1791 piece_data.getArray());
1793 if (topology_changed)
1806 using namespace SOP_CopyToPointsHDKEnums;
1807 auto &&sopparms = cookparms.
parms<SOP_CopyToPointsHDKParms>();
1823 if (source_groupname.isstring())
1830 const GA_Group *temp_source_group =
1831 group_parser.parseGroupDetached(source_groupname, gagrouptype, source,
true,
true, ok);
1835 if (temp_source_group !=
nullptr)
1837 gagrouptype = temp_source_group->
classType();
1841 source_group = source_primgroup;
1846 source_primgroup_deleter = UTmakeUnique<GA_PrimitiveGroup>(*source);
1847 source_primgroup_deleter->
copyMembership(*source_primgroup,
false);
1848 source_primgroup = source_primgroup_deleter.get();
1852 source_pointgroup_deleter = UTmakeUnique<GA_PointGroup>(*source);
1853 source_pointgroup_deleter->
combine(source_primgroup);
1854 source_pointgroup_deleter->makeUnordered();
1855 source_pointgroup = source_pointgroup_deleter.get();
1860 source_group = source_pointgroup;
1866 source_primgroup_deleter = UTmakeUnique<GA_PrimitiveGroup>(*source);
1867 source_primgroup_deleter->
combine(source_group);
1868 source_primgroup_deleter->makeUnordered();
1869 source_primgroup = source_primgroup_deleter.get();
1871 if (!source_primgroup->
isEmpty())
1879 for (
GA_Offset primoff = start; primoff <
end; ++primoff)
1882 for (
exint i = 0, n = vertices.
size(); i <
n; ++i)
1884 GA_Offset ptoff = source->vertexPoint(vertices[i]);
1885 if (!source_pointgroup->
contains(ptoff))
1887 source_primgroup_deleter->removeOffset(primoff);
1906 if (target_groupname.isstring())
1910 target_group = group_parser.parsePointDetached(target_groupname, target,
true,
true, ok);
1928 target_point_list.setTrivialRange(target_point_list.
size(),
start, end-
start);
1934 GA_DataId source_primlist_data_id = source->getPrimitiveList().getDataId();
1935 GA_DataId source_topology_data_id = source->getTopology().getDataId();
1936 bool source_topology_changed =
1937 source_primlist_data_id != sopcache->myPrevSourcePrimListDataID ||
1938 source_topology_data_id != sopcache->myPrevSourceTopologyDataID;
1939 if (!source_topology_changed)
1941 source_topology_changed |= (source_group !=
nullptr) != (sopcache->myPrevHadSourceGroup);
1942 if (!source_topology_changed && (source_group !=
nullptr))
1944 bool different_group = source_group->isDetached() ||
1945 (source_group->getDataId() != sopcache->myPrevSourceGroupDataID);
1946 if (different_group)
1954 source_topology_changed =
true;
1963 source_topology_changed =
true;
1969 sopcache->myPrevHadSourceGroup = (source_group !=
nullptr);
1970 sopcache->myPrevSourceGroupDataID = ((!source_group || source_group->isDetached()) ?
GA_INVALID_DATAID : source_group->getDataId());
1971 sopcache->myPrevSourcePrimListDataID = source_primlist_data_id;
1972 sopcache->myPrevSourceTopologyDataID = source_topology_data_id;
1973 sopcache->mySourceOffsetLists[
GA_ATTRIB_POINT] = std::move(source_point_list);
1976 exint source_point_count = source_pointgroup ? source_pointgroup->
entries() : source->getNumPoints();
1977 exint source_prim_count = source_primgroup ? source_primgroup->
entries() : source->getNumPrimitives();
1978 exint source_vertex_count = 0;
1979 if (!source_primgroup)
1981 source_vertex_count = source->getNumVertices();
1982 sopcache->mySourceVertexCount = source_vertex_count;
1984 else if (source_primgroup->
entries() > 0)
1986 struct CountVerticesFunctor
1988 CountVerticesFunctor(
const GA_Detail &detail)
1992 CountVerticesFunctor(
const CountVerticesFunctor &that,
UT_Split)
1993 : myDetail(that.myDetail)
1999 auto &primlist = myDetail.getPrimitiveList();
2005 bool constant_page = primlist.isVertexListPageConstant(pagenum);
2008 nvertices += primlist.getConstantVertexListPage(pagenum).size() * (end-
start);
2013 nvertices += myDetail.getPrimitiveVertexCount(off);
2016 myVertexCount += nvertices;
2018 void join(
const CountVerticesFunctor &that)
2020 myVertexCount += that.myVertexCount;
2022 GA_Size getVertexCount()
const
2024 return myVertexCount;
2027 exint myVertexCount;
2029 if (source_topology_changed)
2031 CountVerticesFunctor functor(*source);
2033 source_vertex_count = functor.getVertexCount();
2034 sopcache->mySourceVertexCount = source_vertex_count;
2038 source_vertex_count = sopcache->mySourceVertexCount;
2063 for (
exint target_attribsi = 0, ntarget_attribs = target_attribs.size(); target_attribsi < ntarget_attribs; ++target_attribsi)
2065 const SOP_CopyToPointsHDKParms::TargetAttribs &target_attrib_pattern = target_attribs[target_attribsi];
2066 if (!target_attrib_pattern.useapply)
2069 const UT_StringHolder &attrib_pattern = target_attrib_pattern.applyattribs;
2070 if (!attrib_name_wrap.multiMatch(attrib_pattern))
2076 if (target_attrib_pattern.applyto == 0)
2078 else if (target_attrib_pattern.applyto == 1)
2083 sop_AttribCombineMethod method = sop_AttribCombineMethod(target_attrib_pattern.applymethod);
2089 target_group_info.erase(attrib_name);
2091 target_attrib_info.erase(attrib_name);
2097 target_group_info[attrib_name] :
2098 target_attrib_info[attrib_name];
2106 method != sop_AttribCombineMethod::COPY)
2108 method = sop_AttribCombineMethod::COPY;
2114 if (sopparms.getUseIDAttrib() && sopparms.getIDAttrib().isstring())
2116 bool used_idattrib = sopCopyByIDAttrib(
2124 source_topology_changed,
2139 if (
GAisValid(sopcache->myTargetIDAttribDataID))
2144 source_topology_changed =
true;
2145 sopcache->myPrevOutputDetailID = -1;
2149 sopcache->myPieceData.clear();
2150 sopcache->myTargetToPiece.clear();
2162 bool target_group_changed =
2163 (target_group !=
nullptr) != (sopcache->myPrevHadTargetGroup) ||
2164 (target_point_list.
size() != sopcache->myPrevTargetPtCount);
2165 if (!target_group_changed && (target_group!=
nullptr))
2168 bool different_group = target_group->
isDetached() ||
2169 (target_group->
getDataId() != sopcache->myPrevTargetGroupDataID);
2170 if (different_group)
2172 UT_ASSERT(sopcache->myTargetOffsetList.size() == target_point_list.
size());
2173 bool equal_group = sopcache->myTargetOffsetList.isEqual(target_point_list, 0, target_point_list.
size());
2176 target_group_changed =
true;
2180 sopcache->myTargetOffsetList = target_point_list;
2181 sopcache->myPrevHadTargetGroup = (target_group !=
nullptr);
2186 const bool had_transform_matrices = (sopcache->myTransformMatrices3D.get() !=
nullptr);
2190 bool transforms_changed = target_group_changed;
2191 GUsetupPointTransforms(sopcache, target_point_list, target, sopparms.getTransform(), sopparms.getUseImplicitN(), transforms_changed);
2193 const bool has_transform_matrices = (sopcache->myTransformMatrices3D.get() !=
nullptr);
2195 GA_Size num_target_points = target_point_list.
size();
2197 if (sopparms.getPack())
2199 const GEO_ViewportLOD lod = sopViewportLODFromParam(sopparms.getViewportLOD());
2211 source_topology_changed,
2212 had_transform_matrices,
2217 &target_attrib_info,
2218 &target_group_info);
2227 sopcache->mySourceEdgeGroupDataIDs.clear();
2235 bool topology_changed =
2236 (output_detail_id != sopcache->myPrevOutputDetailID) ||
2237 source_topology_changed ||
2238 (num_target_points != sopcache->myPrevTargetPtCount) ||
2239 sopcache->myPrevPack;
2240 if (topology_changed)
2248 source_vertex_count,
2257 sopcache->myPrevOutputDetailID = output_detail_id;
2258 sopcache->myPrevTargetPtCount = num_target_points;
2259 sopcache->myPrevPack =
false;
2267 sopcache->mySourceEdgeGroupDataIDs.clear();
2268 sopcache->myTargetAttribInfo.clear();
2269 sopcache->myTargetGroupInfo.clear();
2312 if (!topology_changed)
2319 &target_attrib_info,
2320 &target_group_info);
2325 needed_transforms[i] =
false;
2328 exint num_source_attribs[3] = {0,0,0};
2329 exint num_target_attribs[3] = {0,0,0};
2331 "Arrays above are assuming the order of GA_AttributeOwner enum");
2337 has_transform_matrices,
2340 &target_attrib_info,
2342 num_target_attribs);
2361 "Arrays above and loop below are assuming the order of GA_AttributeOwner enum");
2365 output_splittable_ranges,
2369 sopcache->mySourceOffsetLists,
2372 had_transform_matrices,
2373 has_transform_matrices,
2377 &target_attrib_info,
2378 &target_group_info);
2384 output_splittable_ranges,
2388 source_vertex_count,
2397 if (topology_changed)
2408 case 0:
return "Geometry to Copy";
2409 case 1:
return "Target Points to Copy to";
2412 return "Invalid Source";
static PRM_ChoiceList primGroupMenu
SYS_FORCE_INLINE const GU_PackedImpl * sharedImplementation() const
static SYS_FORCE_INLINE bool isType(const GA_Attribute *attrib)
SYS_FORCE_INLINE void bumpDataId()
SYS_FORCE_INLINE void forEachAttribute(FUNCTOR &&functor) const
SOP_CopyToPointsHDKVerb()
Definition of a geometry attribute.
GLenum GLuint GLenum GLsizei const GLchar * buf
SYS_FORCE_INLINE GA_Offset getPrimitiveVertexOffset(GA_Offset primoff, GA_Size i) const
~SOP_CopyToPointsHDKVerb() override
SYS_FORCE_INLINE GA_Primitive * getPrimitive(GA_Offset prim_off)
GU_API void GUcreatePointOrPrimList(GA_OffsetList &offset_list, const GU_Detail *const detail, const GA_ElementGroup *const group, const GA_AttributeOwner owner)
UT::ArraySet< std::pair< Key, T >, MULTI, MAX_LOAD_FACTOR_256, Clearer, MapKeyHash< Hash, Key, T >, MapKeyEqual< KeyEqual, Key, T > >::size size_type size() const
Returns the number of items in the set.
SYS_FORCE_INLINE const GA_AttributeDict & pointAttribs() const
SOP_Node * getNode() const
bool copyMembership(const GA_ATIGroupBool &src, bool copy_ordering=true)
int isRefInput(unsigned int i) const
FromType append(ToType value)
Add a single entry (may grow array)
GA_Range getVertexRange(const GA_VertexGroup *group=0) const
Get a range of all vertices in the detail.
OP_ERROR cookInputGroups(OP_Context &context, int alone=0) override
Iteration over a range of elements.
FromType find(ToType value, FromType s=FromType(0)) const
static SYS_FORCE_INLINE bool isType(const GA_Attribute *attrib)
void setChoiceListPtr(const UT_StringRef &name, PRM_ChoiceList *list)
UT_ErrorSeverity sopAddWarning(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
bool contains(const Key &key) const
static const SOP_NodeVerb::Register< SOP_CopyToPointsHDKVerb > theVerb
SYS_FORCE_INLINE int getPrimitiveTypeId(GA_Offset primoff) const
#define SYS_STATIC_ASSERT_MSG(expr, msg)
~SOP_CopyToPointsHDK() override
void UTparallelForEachNumber(IntType nitems, const Body &body, const bool force_use_task_scope=true)
void bind(const GA_Detail *gdp, GA_AttributeOwner owner, const UT_StringRef &name, int minsize=1)
virtual void copySubclassData(const GA_Primitive *source)
bool blockAdvance(GA_Offset &start, GA_Offset &end)
GLsizei const GLfloat * value
GA_Size entries() const overridefinal
Will return the number of primary elements.
void setSizeNoInit(exint newsize)
void clearAndDestroy()
Clear all the points/primitives out of this detail.
static const char *const theDsFile
This is the parameter interface string, below.
**And then you can **find out if it s done
SYS_FORCE_INLINE bool getExtraFlag() const
Synonym for isClosed()
SYS_FORCE_INLINE bool isValid() const
GA_Attribute * getP()
Convenience method to access the P attribute.
SYS_FORCE_INLINE const HOLDER & get(GA_Offset off, int comp=0) const
Get the string at the given offset.
SYS_FORCE_INLINE const char * buffer() const
SYS_FORCE_INLINE GA_AttributeScope getScope() const
UT::ArraySet< std::pair< Key, T >, MULTI, MAX_LOAD_FACTOR_256, Clearer, MapKeyHash< Hash, Key, T >, MapKeyEqual< KeyEqual, Key, T > >::empty bool empty() const
Returns true iff there are no items in the set.
void setTrivialRange(FromType startindex, ToType startvalue, GA_Size nelements)
SOP_NodeCache * allocCache() const override
void UTparallelForLightItems(const Range &range, const Body &body, const bool force_use_task_scope=true)
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
GA_API const UT_StringHolder P
#define UT_ASSERT_MSG_P(ZZ,...)
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
GU_API void GUcreateVertexListAndGeometryFromSource(GU_Detail *output_geo, const GU_Detail *const source, const exint source_point_count, const exint source_vertex_count, const exint source_prim_count, const GA_OffsetList &source_point_list_cache, GA_OffsetList &source_vertex_list_cache, const GA_OffsetList &source_prim_list_cache, const GA_PointGroup *const source_pointgroup, const GA_PrimitiveGroup *const source_primgroup, const exint ncopies)
Standard user attribute level.
#define GA_INVALID_DATAID
ordered_iterator_t< true > ordered_begin(const COMPARATOR &comparator) const
bool getBoundsCached(UT_BoundingBox &box) const
static PRM_ChoiceList pointGroupMenu
SYS_FORCE_INLINE bool GAisValid(GA_Size v)
GU_API void GUsetupPointTransforms(GU_PointTransformCache *cache, const GA_OffsetListRef &target_point_list, const GU_Detail *target, const bool transform_using_more_than_P, const bool allow_implicit_N, bool &transforms_changed)
void setSize(exint newsize)
exint GA_Size
Defines the bit width for index and offset types in GA.
#define GA_INVALID_OFFSET
GA_Size countPrimitiveType(const GA_PrimitiveTypeId &type) const
Geometry Embedded procedural.
A range of elements in an index-map.
SYS_FORCE_INLINE const UT_StringHolder & getName() const
void setViewportLOD(GEO_ViewportLOD vlod)
bool combine(const GA_Group *src) overridefinal
void set(FromType index, ToType value)
Set the index to the value.
void allocateAndSet(GU_Detail *gdp, bool own=true)
GA_Offset GEObuildPrimitives(GEO_Detail *detail, const std::pair< int, exint > *primtype_count_pairs, const GA_Offset init_startpt, const GA_Size npoints_per_copy, const GA_PolyCounts &vertexlistsizelist, const INT_T *vertexpointnumbers, const bool hassharedpoints, const exint *closed_span_lengths, const exint ncopies)
GU_API void GUcreateEmptyPackedGeometryPrims(GU_Detail *const output_geo, const exint num_packed_prims)
void resetTargetAttribs()
GU_ConstDetailHandle inputGeoHandle(exint idx) const
SYS_FORCE_INLINE bool isTrivial() const
GA_Range getPointRange(const GA_PointGroup *group=0) const
Get a range of all points in the detail.
const GA_IndexMap & getPointMap() const
GU_API void GUcreateGeometryFromSource(GU_Detail *output_geo, const GU_Detail *const source, const GA_OffsetList &source_point_list_cache, const GA_OffsetList &source_vertex_list_cache, const GA_OffsetList &source_prim_list_cache, const exint ncopies)
NOTE: This does not clear output_geo.
bool isEqual(const GA_ListTypeRef &other, FromType start, FromType end) const
Test a sub-block for equality with another list.
Constructs a PRM_Template list from an embedded .ds file or an istream.
void bind(const GA_Detail *gdp, GA_AttributeOwner owner, const UT_StringRef &name, int minsize=1)
UT_Vector3T< T > center() const
GA_AttributeOwner myCopyTo
SYS_FORCE_INLINE GA_OffsetListRef getVertexList(GA_Offset primoff) const
SYS_FORCE_INLINE GA_Offset appendPointBlock(GA_Size npoints)
Append new points, returning the first offset of the contiguous block.
const GU_Detail * inputGeo(int index, OP_Context &)
GOP_Manager::GroupCreator GroupCreator
Typedef to help make use of GroupCreator less verbose.
void bumpDataId()
Use this to mark primitives or their intrinsic data as dirty.
GA_StorageClass getStorageClass() const
Returns the approximate type of the attribute.
PRM_Template * templates() const
CookMode cookMode(const SOP_NodeParms *parms) const override
static SYS_FORCE_INLINE GA_ATINumeric * cast(GA_Attribute *attrib)
SYS_FORCE_INLINE GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const
SYS_FORCE_INLINE GA_PageNum GAgetPageNum(GA_Offset v)
UT::ArraySet< std::pair< Key, T >, MULTI, MAX_LOAD_FACTOR_256, Clearer, MapKeyHash< Hash, Key, T >, MapKeyEqual< KeyEqual, Key, T > >::begin iterator begin()
Returns a non-const iterator for the beginning of the set.
GLsizei GLsizei GLchar * source
OP_ERROR cookMyselfAsVerb(OP_Context &context)
GU_API void GUaddAttributesFromSourceOrTarget(GU_Detail *output_geo, const GU_Detail *source, exint *num_source_attribs=nullptr, bool has_transform_matrices=false, bool *needed_transforms=nullptr, const GU_Detail *target=nullptr, GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info=nullptr, GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info=nullptr, exint *num_target_attribs=nullptr)
SYS_FORCE_INLINE GA_Offset pointVertex(GA_Offset point) const
UT_UniquePtr< GA_PrimitiveGroup > GA_PrimitiveGroupUPtr
SYS_FORCE_INLINE GA_Offset getNumPointOffsets() const
OP_ERROR cookInputPointGroups(OP_Context &context, const GA_PointGroup *&group, bool alone=false, bool do_selection=true, int parm_index=0, int group_type_index=-1, bool allow_reference=true, bool ordered=false, bool detached=true, int input_index=0)
See cookInputPrimitiveGroups.
size_type erase(const Key &key)
SOP_NodeParms * allocParms() const override
SYS_FORCE_INLINE const char * c_str() const
static SYS_FORCE_INLINE GA_ATIString * cast(GA_Attribute *attrib)
void setCallback(const UT_StringRef &name, PRM_Callback callback)
virtual void setPivot(const UT_Vector3 &pos)
SYS_FORCE_INLINE T get(GA_Offset off, int comp=0) const
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
OP_ERROR cookMySop(OP_Context &context) override
bool isOrdered() const overridefinal
Returns true if the group is currently ordered.
GLuint const GLchar * name
SYS_FORCE_INLINE GA_DataId getDataId() const
static PRM_Template * buildTemplates()
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
bool contains(const GA_Primitive *prim) const
GLenum GLenum GLsizei void * table
void setManagesDataIDs(bool onOff)
SYS_FORCE_INLINE GA_Offset vertexToNextVertex(GA_Offset vtx) const
SYS_FORCE_INLINE bool isPageConstant(GA_PageNum pagenum) const
GA_GroupType classType() const
void newSopOperator(OP_OperatorTable *table)
exint getUniqueId() const
SYS_FORCE_INLINE const GA_Attribute * findPrimitiveAttribute(GA_AttributeScope s, const UT_StringRef &name) const
SYS_FORCE_INLINE bool isValid() const
void notifyGroupParmListeners(SOP_Node *oldsop, int groupparm_idx, int grouptype_idx, const GU_Detail *gdp, const GA_Group *group) const
GU_API void GUcomputeTransformTypeCaches(GU_PointTransformCache *cache, exint num_target_points, bool transforms_changed, const bool needed_transforms[NeededTransforms::num_needed_transforms])
void assign(T xx=0.0f, T yy=0.0f, T zz=0.0f)
Set the values of the vector components.
GU_API void GUremoveUnnecessaryAttribs(GU_Detail *output_geo, const GU_Detail *source, const GU_Detail *target, GU_CopyToPointsCache *cache, const GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info, const GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info)
SYS_FORCE_INLINE GA_Offset vertexPrimitive(GA_Offset vertex) const
int int appendSprintf(const char *fmt,...) SYS_PRINTF_CHECK_ATTRIBUTE(2
OP_ERROR cookInputAllGroups(OP_Context &context, const GA_Group *&group, bool alone=false, bool do_selection=true, int parm_index=0, int group_type_index=-1, GA_GroupType grouptype=GA_GROUP_INVALID, bool allow_reference=true, bool is_default_prim=true, bool ordered=false, bool detached=true, int input_index=0)
void intrusive_ptr_add_ref(T *x)
GU_API void GUcopyAttributesFromSource(GU_Detail *const output_geo, const GA_SplittableRange *const output_splittable_ranges, const GU_Detail *const source, const exint num_target_points, GU_CopyToPointsCache *const cache, const GA_OffsetList *const source_offset_lists, const exint *const num_source_attribs, const bool no_transforms, const bool had_transform_matrices, const bool has_transform_matrices, const bool topology_changed, const bool transforms_changed, const GU_Detail *const target=nullptr, const GU_CopyToPointsCache::TargetAttribInfoMap *const target_attrib_info=nullptr, const GU_CopyToPointsCache::TargetAttribInfoMap *const target_group_info=nullptr, const exint *const target_to_piecei=nullptr, const UT_Array< exint > *const owner_piece_offset_starts=nullptr, const GU_CopyToPointsCache::PieceData *const piece_data=nullptr, UT_Interrupt *boss=nullptr)
SYS_FORCE_INLINE GA_Offset getNumPrimitiveOffsets() const
SYS_FORCE_INLINE bool isValid() const
Check whether the bounding box contains at least one point.
UT_StringHolder name() const override
SYS_FORCE_INLINE GA_Offset primitiveOffset(GA_Index index) const
Given a primitive's index (in append order), return its data offset.
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *entry)
GU_API void GUcopyPackAllSame(GU_Detail *output_geo, const GEO_ViewportLOD lod, const GU_CopyToPointsCache::PackedPivot pivot_type, GU_CopyToPointsCache *cache, const GU_ConstDetailHandle source_handle, const GU_Detail *source, const GA_PointGroup *source_pointgroup, const GA_PrimitiveGroup *source_primgroup, bool source_topology_changed, bool had_transform_matrices, bool transforms_changed, const exint num_packed_prims, const GU_Detail *target=nullptr, const GA_OffsetListRef *target_point_list=nullptr, GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info=nullptr, GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info=nullptr)
void append(GA_Size size, GA_Size count=1)
GA_GroupType
An ordinal enum for the different types of groups in GA.
AttribCombineMethod myCombineMethod
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
iterator erase(iterator pos)
GEO_API const char * GEOviewportLOD(GEO_ViewportLOD type, bool label=false)
int64 getMetaCacheCount() const
GA_API const UT_StringHolder pivot
const GU_Detail * inputGeo(exint idx) const
const GA_PrimitiveList & getPrimitiveList() const
SOP_NodeCache * cache() const
void setDetailPtr(const GU_DetailHandle &d)
SYS_FORCE_INLINE GA_AttributeOwner getOwner() const
Container class for all geometry.
GU_API void GUhandleTargetAttribsForPackedPrims(GU_Detail *output_geo, GU_CopyToPointsCache *cache, const bool topology_changed, const bool had_transform_matrices, const GU_Detail *const target, const GA_OffsetListRef &target_point_list, GU_CopyToPointsCache::TargetAttribInfoMap &target_attrib_info, GU_CopyToPointsCache::TargetAttribInfoMap &target_group_info, const UT_Vector3 *const constant_pivot)
SYS_FORCE_INLINE GA_Size getPrimitiveVertexCount(GA_Offset primoff) const
exint evalInt(int pi, int vi, fpreal t) const
UT_UniquePtr< GA_PointGroup > GA_PointGroupUPtr
SYS_FORCE_INLINE bool isEmpty() const
Query whether the group is empty of primary elements.
void cook(const CookParms &cookparms) const override
Compute the output geometry.
void clear()
Resets list to an empty list.
SYS_FORCE_INLINE void setImplementation(const GU_PackedImpl *impl, bool add_ref=true, bool remove_ref=true)
SYS_FORCE_INLINE bool isPageConstant(GA_PageNum pagenum) const
SYS_FORCE_INLINE const GA_Attribute * findPointAttribute(GA_AttributeScope s, const UT_StringRef &name) const
GA_Range getPrimitiveRange(const GA_PrimitiveGroup *group=0) const
Get a range of all primitives in the detail.
UT_ArrayStringMap< TargetAttribInfo > TargetAttribInfoMap
const SOP_NodeVerb * cookVerb() const override
void bumpDataIdsForAddOrRemove(bool added_or_removed_points, bool added_or_removed_vertices, bool added_or_removed_primitives)
GU_API void GUcopyAttributesFromTarget(GU_Detail *const output_geo, const GA_SplittableRange *const output_splittable_ranges, const exint ncopies, GU_CopyToPointsCache *const cache, const exint source_point_count, const exint source_vertex_count, const exint source_prim_count, const exint *const num_target_attribs, const GA_OffsetListRef &target_point_list, const GU_Detail *const target, GU_CopyToPointsCache::TargetAttribInfoMap &target_attrib_info, GU_CopyToPointsCache::TargetAttribInfoMap &target_group_info, const bool topology_changed, const exint *const target_to_piecei=nullptr, const UT_Array< exint > *const owner_piece_offset_starts=nullptr, const GU_CopyToPointsCache::PieceData *const piece_data=nullptr, UT_Interrupt *boss=nullptr)
static SYS_FORCE_INLINE bool isType(const GA_Attribute *attrib)
GU_DetailHandle & gdh() const
The initial state of gdh depends on the cookMode()
GA_OffsetList getOffsetFromIndexList() const
bool fullBlockAdvance(GA_Offset &start, GA_Offset &end)
SYS_FORCE_INLINE FromType size() const
Returns the number of used elements in the list (always <= capacity())
const char * inputLabel(unsigned idx) const override
void UTparallelReduceLightItems(const Range &range, Body &body)
SYS_FORCE_INLINE bool contains(GA_Offset offset) const
static const UT_StringHolder theSOPTypeName
bool isEmpty() const
Returns true iff there are no occupied elements in the array.
UT::ArraySet< std::pair< Key, T >, MULTI, MAX_LOAD_FACTOR_256, Clearer, MapKeyHash< Hash, Key, T >, MapKeyEqual< KeyEqual, Key, T > >::reserve void reserve(size_type num_items)