82 using namespace UT::Literal;
84 namespace HDK_Sample {
100 guGetTransformTypeInfo(
const GA_ATINumeric *attrib,
const bool has_transform_matrices)
103 if (tuple_size < 3 || !attrib->needsTransform())
113 return attrib_type_info;
116 else if (tuple_size == 4)
120 return attrib_type_info;
122 else if (tuple_size == 9)
126 return attrib_type_info;
128 else if (tuple_size == 16)
131 return attrib_type_info;
150 attribs_to_delete.
clear();
151 bool pos_storage_mismatch =
false;
154 &attribs_to_delete,output_geo,&pos_storage_mismatch,
155 target_group_info,target_attrib_info,target,cache](
GA_Attribute *attrib)
160 (is_group && UTverify_cast<GA_ElementGroup*>(attrib)->isInternal()))
164 attribs_to_delete.
append(attrib);
172 it = target_info->
find(name);
173 if (!target_info || it.atEnd() || it->second.myCopyTo != owner)
179 pos_storage_mismatch = (source_attrib !=
nullptr);
181 attribs_to_delete.
append(attrib);
193 if (!source_dataids[owner].
contains(name) && attrib != output_geo->
getP())
195 attribs_to_delete.
append(attrib);
206 attribs_to_delete.
append(attrib);
221 if (source_dataids[owner].
contains(name))
223 attribs_to_delete.
append(attrib);
229 attribs_to_delete.
append(attrib);
240 if (!source_dataids[owner].
contains(name))
242 attribs_to_delete.
append(attrib);
247 for (
exint i = 0,
n = attribs_to_delete.
size(); i <
n; ++i)
269 if (pos_storage_mismatch)
273 UTverify_cast<const GA_ATINumeric*>(source->
getP())->getStorage());
286 edgegroups_to_delete.
append(edgegroup);
290 if (!source_edgegroup || source_edgegroup->
isInternal())
292 edgegroups_to_delete.
append(edgegroup);
295 for (
exint i = 0,
n = edgegroups_to_delete.
size(); i <
n; ++i)
308 const bool transform_using_more_than_P,
309 const bool allow_implicit_N,
310 bool &transforms_changed)
312 const exint num_target_points = target_point_list.
size();
316 transforms_changed =
true;
319 if (num_target_points == 0)
326 bool using_implicit_N =
false;
327 if (transform_using_more_than_P)
332 using_implicit_N =
true;
338 if (using_implicit_N)
344 transforms_changed |=
357 target_transform_attribs.
getDataIds(new_transform_data_ids);
358 transforms_changed |=
362 if (!transforms_changed)
373 transforms_changed =
true;
378 if (transforms_changed)
387 bool onlyP = !target_transform_attribs.
hasAnyAttribs() && !using_implicit_N;
405 GA_Offset target_ptoff = target_point_list[i];
406 translates[i] = targetP.get(target_ptoff);
409 if (num_target_points > 1024)
422 if (using_implicit_N)
429 target_transform_attribs.
setN(implicitN.get());
435 auto &&functor = [&target_transform_attribs,&target_point_list,&targetP,matrices,translates](
const UT_BlockedRange<exint> &
r)
439 GA_Offset target_ptoff = target_point_list[i];
441 target_transform_attribs.
getMatrix(transform, targetP.get(target_ptoff), target_ptoff);
448 if (num_target_points > 512)
460 exint *num_source_attribs,
461 bool has_transform_matrices,
462 bool *needed_transforms,
466 exint *num_target_attribs)
474 [owner,output_geo,num_source_attribs,
475 needed_transforms,has_transform_matrices,
479 if (target_attrib_info)
488 auto it = target_attrib_info->
find(name);
489 if (!it.atEnd() && (it->second.myCopyTo == owner || it->second.myCopyTo == guConflictAttribOwner(owner)) &&
490 it->second.myCombineMethod == AttribCombineMethod::COPY)
505 dest_attrib->
replace(*source_attrib);
509 if (num_source_attribs)
510 ++num_source_attribs[owner];
515 if (!needed_transforms)
521 GA_TypeInfo transform_type = guGetTransformTypeInfo(dest_numeric, has_transform_matrices);
524 using namespace NeededTransforms;
528 needed_transforms[
matrix3f] |= !double_precision;
529 needed_transforms[
translate3f] |= !double_precision;
533 needed_transforms[
matrix3f] |= !double_precision;
537 needed_transforms[
inverse3d] |= double_precision;
538 needed_transforms[
inverse3f] |= !double_precision;
542 needed_transforms[
quaterniond] |= double_precision;
543 needed_transforms[
quaternionf] |= !double_precision;
547 needed_transforms[
matrix3f] |= !double_precision;
564 if (target_group_info)
567 auto it = target_group_info->
find(source_group->
getName());
568 if (!it.atEnd() && it->second.myCopyTo == owner)
576 UT_ASSERT_MSG(!dest_group->
isOrdered(),
"Writing to groups in parallel requires unordered groups, and ordering isn't as useful for copied geometry");
582 if (num_source_attribs)
583 ++num_source_attribs[owner];
604 if (!target || !target_attrib_info || !target_group_info)
607 for (
auto it = target_attrib_info->
begin(); !it.
atEnd(); ++it)
611 AttribCombineMethod method = it->second.myCombineMethod;
612 if (source && method != AttribCombineMethod::COPY)
619 if (num_target_attribs)
620 ++num_target_attribs[output_owner];
636 it->second.myCopyTo = conflict_owner;
637 if (num_target_attribs)
638 ++num_target_attribs[conflict_owner];
657 if (method == AttribCombineMethod::MULTIPLY ||
658 method == AttribCombineMethod::ADD)
660 it->second.myCombineMethod = AttribCombineMethod::COPY;
668 if (num_target_attribs)
669 ++num_target_attribs[output_owner];
672 for (
auto it = target_group_info->
begin(); !it.
atEnd(); ++it)
676 AttribCombineMethod method = it->second.myCombineMethod;
677 if (source && method != AttribCombineMethod::COPY)
684 if (num_target_attribs)
685 ++num_target_attribs[output_owner];
701 it->second.myCopyTo = conflict_owner;
702 if (num_target_attribs)
703 ++num_target_attribs[conflict_owner];
718 if (method == AttribCombineMethod::MULTIPLY ||
719 method == AttribCombineMethod::ADD)
721 it->second.myCombineMethod = AttribCombineMethod::COPY;
725 if (method == AttribCombineMethod::SUBTRACT)
730 UT_ASSERT_MSG(!dest_group->isOrdered(),
"Writing to groups in parallel requires unordered groups, and ordering isn't as useful for copied geometry");
732 if (num_target_attribs)
733 ++num_target_attribs[output_owner];
740 exint num_target_points,
741 bool transforms_changed,
744 using namespace NeededTransforms;
747 if (needed_transforms[
translate3f] && num_target_points > 0)
749 bool compute = transforms_changed;
766 if (num_target_points > 1024)
773 if (!has_transform_matrices)
783 if (num_target_points <= 0)
788 bool compute = transforms_changed;
805 if (num_target_points > 1024)
813 bool compute = transforms_changed;
834 auto singular = matrices3d[i].
invert(inverse);
845 if (matrices3d[i].determinant() < 0)
846 inverse.
scale(-1, -1, -1);
849 inverses3d[i] = inverse;
854 if (num_target_points > 512)
862 bool compute = transforms_changed;
886 quaternionsd[i] = quaternion;
891 if (num_target_points > 512)
903 exint &piece_elementi,
904 exint &piece_element_count,
907 const exint *
const piece_offset_starts,
908 const exint *
const piece_offset_starts_end,
909 const exint num_target_points,
910 const exint *
const target_to_piecei,
914 const exint source_offset_list_size)
916 const exint output_primi = start - start_offset;
917 if (piece_offset_starts)
922 targeti = (std::upper_bound(
924 piece_offset_starts_end,
925 output_primi) - piece_offset_starts) - 1;
926 UT_ASSERT_P(targeti >= 0 && targeti < num_target_points);
927 piece_elementi = output_primi - piece_offset_starts[targeti];
928 const exint piecei = target_to_piecei[targeti];
931 piece_element_count = local_piece_offset_list.
size();
932 if (piece_offset_list !=
nullptr)
933 *piece_offset_list = &local_piece_offset_list;
937 piece_element_count = source_offset_list_size;
938 if (piece_offset_list !=
nullptr)
941 *piece_offset_list = source_offset_list;
943 targeti = output_primi / piece_element_count;
944 piece_elementi = output_primi % piece_element_count;
949 guIteratePieceElement(
950 exint &piece_elementi,
951 exint &piece_element_count,
953 const exint *
const piece_offset_starts,
954 const exint num_target_points,
955 const exint *
const target_to_piecei,
962 while (piece_elementi >= piece_element_count)
967 if (targeti >= num_target_points)
970 if (piece_offset_starts !=
nullptr)
972 exint piecei = target_to_piecei[targeti];
975 piece_element_count = piece_offset_list->
size();
983 guIteratePieceElementOff(
984 exint &piece_elementi,
985 exint &piece_element_count,
987 const exint *
const piece_offset_starts,
988 const exint num_target_points,
989 const exint *
const target_to_piecei,
997 while (piece_elementi >= piece_element_count)
1002 if (targeti >= num_target_points)
1005 target_off = target_point_list[targeti];
1007 if (piece_offset_starts !=
nullptr)
1009 exint piecei = target_to_piecei[targeti];
1012 piece_element_count = piece_offset_list.
size();
1020 guIteratePieceElementGroup(
1021 exint &piece_elementi,
1022 exint &piece_element_count,
1024 const exint *
const piece_offset_starts,
1025 const exint num_target_points,
1026 const exint *
const target_to_piecei,
1029 bool &target_in_group,
1035 while (piece_elementi >= piece_element_count)
1040 if (targeti >= num_target_points)
1043 const GA_Offset target_off = target_point_list[targeti];
1044 target_in_group = target_group->
contains(target_off);
1046 if (piece_offset_starts !=
nullptr)
1048 exint piecei = target_to_piecei[targeti];
1051 piece_element_count = piece_offset_list.
size();
1057 guApplyTransformToAttribute(
1063 const bool copy_source_attribs_in_parallel,
1067 const exint *target_to_piecei,
1068 const exint num_target_points,
1069 const exint *piece_offset_starts,
1070 const exint *piece_offset_starts_end,
1077 int owneri = output_numeric->
getOwner();
1085 auto &&functor = [output_numeric,source_numeric,&source_offset_list,
1086 transform_matrices_3f,transform_matrices_3d,transform_translates_3f,transform_translates_3d,
1087 start_offset,piece_offset_starts,piece_offset_starts_end,
1094 exint piece_elementi;
1095 exint piece_element_count;
1097 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
1098 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
1099 num_target_points, target_to_piecei, piece_data, owneri,
1100 &source_offset_list, source_offset_list.
size());
1107 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1109 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1111 if (transform_matrices_3f)
1112 pos = (pos * transform_matrices_3f[targeti]) + transform_translates_3f[targeti];
1114 pos += transform_translates_3f[targeti];
1117 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1118 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1126 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1128 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1130 if (transform_matrices_3d)
1131 pos = (pos * transform_matrices_3d[targeti]) + transform_translates_3d[targeti];
1133 pos += transform_translates_3d[targeti];
1136 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1137 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1144 UT_ASSERT_P(output_data.isValid() && source_data.isValid());
1146 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1148 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1150 if (transform_matrices_3f)
1151 pos = (pos * transform_matrices_3f[targeti]) + transform_translates_3f[targeti];
1153 pos += transform_translates_3f[targeti];
1154 output_data.
set(dest_off, pos);
1156 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1157 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1162 if (copy_source_attribs_in_parallel)
1165 functor(output_splittable_range);
1169 auto &&functor = [output_numeric,source_numeric,&source_offset_list,
1170 transform_matrices_3f,transform_matrices_3d,
1171 start_offset,piece_offset_starts,piece_offset_starts_end,
1178 exint piece_elementi;
1179 exint piece_element_count;
1181 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
1182 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
1183 num_target_points, target_to_piecei, piece_data, owneri,
1184 &source_offset_list, source_offset_list.
size());
1192 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1194 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1196 vec.rowVecMult(transform_matrices_3f[targeti]);
1199 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1200 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1209 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1211 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1213 vec.rowVecMult(transform_matrices_3d[targeti]);
1216 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1217 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1225 UT_ASSERT_P(output_data.isValid() && source_data.isValid());
1227 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1229 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1231 vec.
rowVecMult(transform_matrices_3f[targeti]);
1232 output_data.
set(dest_off, vec);
1234 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1235 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1240 if (copy_source_attribs_in_parallel)
1243 functor(output_splittable_range);
1249 auto &&functor = [output_numeric,source_numeric,&source_offset_list,
1250 transform_inverse_3f,transform_inverse_3d,
1251 start_offset,piece_offset_starts,piece_offset_starts_end,
1258 exint piece_elementi;
1259 exint piece_element_count;
1261 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
1262 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
1263 num_target_points, target_to_piecei, piece_data, owneri,
1264 &source_offset_list, source_offset_list.
size());
1272 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1274 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1276 float orig_length2 = nml.length2();
1277 nml.colVecMult(transform_inverse_3f[targeti]);
1278 float new_length2 = nml.length2();
1280 if (new_length2 != 0)
1281 nml *= SYSsqrt(orig_length2/new_length2);
1284 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1285 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1294 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1296 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1298 float orig_length2 = nml.length2();
1299 nml.colVecMult(transform_inverse_3d[targeti]);
1300 float new_length2 = nml.length2();
1302 if (new_length2 != 0)
1303 nml *= SYSsqrt(orig_length2/new_length2);
1306 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1307 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1315 UT_ASSERT_P(output_data.isValid() && source_data.isValid());
1317 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1319 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1321 float orig_length2 = nml.
length2();
1322 nml.
colVecMult(transform_inverse_3f[targeti]);
1323 float new_length2 = nml.
length2();
1325 if (new_length2 != 0)
1326 nml *= SYSsqrt(orig_length2/new_length2);
1327 output_data.
set(dest_off, nml);
1329 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1330 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1335 if (copy_source_attribs_in_parallel)
1338 functor(output_splittable_range);
1344 auto &&functor = [output_numeric,source_numeric,&source_offset_list,
1345 transform_quaternions_3f,transform_quaternions_3d,
1346 start_offset,piece_offset_starts,piece_offset_starts_end,
1353 exint piece_elementi;
1354 exint piece_element_count;
1356 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
1357 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
1358 num_target_points, target_to_piecei, piece_data, owneri,
1359 &source_offset_list, source_offset_list.
size());
1367 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1369 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1371 q = transform_quaternions_3f[targeti] *
q;
1374 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1375 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1384 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1386 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1388 q = transform_quaternions_3d[targeti] *
q;
1391 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1392 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1400 UT_ASSERT_P(output_data.isValid() && source_data.isValid());
1402 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1404 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1406 q = transform_quaternions_3f[targeti] *
q;
1407 output_data.
set(dest_off, q);
1409 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1410 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1415 if (copy_source_attribs_in_parallel)
1418 functor(output_splittable_range);
1422 auto &&functor = [output_numeric,source_numeric,&source_offset_list,
1423 transform_matrices_3f,transform_matrices_3d,transform_translates_3f,transform_translates_3d,
1424 start_offset,piece_offset_starts,piece_offset_starts_end,
1433 exint piece_elementi;
1434 exint piece_element_count;
1436 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
1437 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
1438 num_target_points, target_to_piecei, piece_data, owneri,
1439 &source_offset_list, source_offset_list.
size());
1446 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1448 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1452 transform.setTranslates(transform_translates_3f[targeti]);
1457 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1458 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1466 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1468 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1472 transform.setTranslates(transform_translates_3d[targeti]);
1477 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1478 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1485 UT_ASSERT_P(output_data.isValid() && source_data.isValid());
1487 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1489 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1493 transform.setTranslates(transform_translates_3f[targeti]);
1496 output_data.
set(dest_off, hp);
1498 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1499 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1504 if (copy_source_attribs_in_parallel)
1507 functor(output_splittable_range);
1512 auto &&functor = [output_numeric,source_numeric,&source_offset_list,
1513 transform_matrices_3f,transform_matrices_3d,
1514 start_offset,piece_offset_starts,piece_offset_starts_end,
1521 exint piece_elementi;
1522 exint piece_element_count;
1524 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
1525 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
1526 num_target_points, target_to_piecei, piece_data, owneri,
1527 &source_offset_list, source_offset_list.
size());
1535 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1537 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1539 mat *= transform_matrices_3f[targeti];
1542 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1543 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1552 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1554 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1556 mat *= transform_matrices_3d[targeti];
1559 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1560 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1568 UT_ASSERT_P(output_data.isValid() && source_data.isValid());
1570 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1572 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1574 mat *= transform_matrices_3f[targeti];
1575 output_data.
set(dest_off, mat);
1577 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1578 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1583 if (copy_source_attribs_in_parallel)
1586 functor(output_splittable_range);
1592 auto &&functor = [output_numeric,source_numeric,&source_offset_list,
1593 transform_matrices_3f,transform_matrices_3d,transform_translates_3f,transform_translates_3d,
1594 start_offset,piece_offset_starts,piece_offset_starts_end,
1601 exint piece_elementi;
1602 exint piece_element_count;
1604 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
1605 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
1606 num_target_points, target_to_piecei, piece_data, owneri,
1607 &source_offset_list, source_offset_list.
size());
1614 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1616 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1618 if (transform_matrices_3f)
1621 transform.setTranslates(transform_translates_3f[targeti]);
1625 mat.translate(transform_translates_3f[targeti]);
1628 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1629 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1637 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1639 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1641 if (transform_matrices_3d)
1644 transform.setTranslates(transform_translates_3d[targeti]);
1648 mat.translate(transform_translates_3d[targeti]);
1651 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1652 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1659 UT_ASSERT_P(output_data.isValid() && source_data.isValid());
1661 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
1663 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
1665 if (transform_matrices_3f)
1668 transform.setTranslates(transform_translates_3f[targeti]);
1672 mat.
translate(transform_translates_3f[targeti]);
1673 output_data.
set(dest_off, mat);
1675 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
1676 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
1681 if (copy_source_attribs_in_parallel)
1684 functor(output_splittable_range);
1695 const exint ncopies)
1697 exint source_point_count = source_point_list_cache.
size();
1698 exint source_vertex_count = source_vertex_list_cache.
size();
1699 exint source_prim_count = source_prim_list_cache.
size();
1701 GA_Size totalnpoints = source_point_count * ncopies;
1704 if (source_prim_count <= 0)
1710 if (!all_source_prims)
1713 UT_ASSERT(!prim_type_count_pairs.isEmpty());
1718 bool have_reverse_point_map = !all_source_points && !source_point_list_cache.
isTrivial();
1719 if (have_reverse_point_map)
1723 for (
exint pointi = 0; pointi < source_point_count; ++pointi)
1725 source_ptoff_to_pointi.set(source_point_list_cache[pointi], pointi);
1731 bool hassharedpoints =
true;
1733 bool hascontiguouspoints =
false;
1734 if (source_point_count >= source_vertex_count)
1741 hascontiguouspoints =
true;
1742 hassharedpoints =
false;
1746 for (
exint primi = 0; primi < source_prim_count; ++primi)
1748 GA_Offset primoff = source_prim_list_cache[primi];
1750 if (vertices.
size() == 0)
1755 if (last_point != source_point_list_cache[0])
1757 hascontiguouspoints =
false;
1763 hascontiguouspoints &= (current_point == last_point+1);
1770 hassharedpoints |= (current_point <= last_point);
1771 if (hassharedpoints)
1773 last_point = current_point;
1775 for (
exint i = 1,
n = vertices.
size(); i <
n; ++i)
1778 hascontiguouspoints &= (current_point == last_point+1);
1781 hassharedpoints |= (current_point <= last_point);
1782 if (hassharedpoints)
1784 last_point = current_point;
1786 if (hassharedpoints)
1794 closed_span_lengths.
append(0);
1795 exint *vertexpointnumbers = vertexpointnumbers_deleter.get();
1798 for (
exint primi = 0; primi < source_prim_count; ++primi)
1800 GA_Offset primoff = source_prim_list_cache[primi];
1804 vertexlistsizelist.
append(n);
1810 if ((closed_span_lengths.
size()&1) ==
exint(closed))
1811 closed_span_lengths.
append(1);
1813 ++(closed_span_lengths.
last());
1815 if (!hascontiguouspoints)
1817 if (have_reverse_point_map)
1819 for (
exint i = 0; i <
n; ++i)
1822 exint pointi = source_ptoff_to_pointi.get(source_ptoff);
1823 vertexpointnumbers[vertexi] = pointi;
1827 else if (source_point_list_cache.
isTrivial())
1829 for (
exint i = 0; i <
n; ++i)
1832 exint pointi = source_point_list_cache.
find(source_ptoff);
1834 vertexpointnumbers[vertexi] = pointi;
1840 for (
exint i = 0; i <
n; ++i)
1844 vertexpointnumbers[vertexi] = pointi;
1853 prim_type_count_pairs.getArray(),
1866 exint num_polys_and_tets =
1877 for (
GA_Offset dest_off =
r.begin(), end =
r.end(); dest_off <
end; ++dest_off)
1879 exint sourcei =
exint(dest_off) % source_prim_count;
1880 GA_Offset source_off = source_prim_list_cache[sourcei];
1881 const GA_Primitive *source_prim = source->getPrimitive(source_off);
1903 if (group ==
nullptr)
1909 offset_list.
clear();
1924 const exint source_point_count,
1925 const exint source_vertex_count,
1926 const exint source_prim_count,
1932 const exint ncopies)
1936 source_vertex_list_cache.
clear();
1940 if (source_prim_count <= 0)
1942 source_vertex_list_cache.
clear();
1944 GA_Size totalnpoints = source_point_count * ncopies;
1954 source_vertex_list_cache.
clear();
1959 for (
GA_Offset primoff = start; primoff <
end; ++primoff)
1962 source_vertex_list_cache.
append(vertices);
1966 UT_ASSERT(source_vertex_list_cache.
size() == source_vertex_count);
1971 source_point_list_cache,
1972 source_vertex_list_cache,
1973 source_prim_list_cache,
1980 const exint num_packed_prims)
1982 if (num_packed_prims <= 0)
1987 GA_Offset end_ptoff = start_ptoff+num_packed_prims;
1993 GA_Offset end_vtxoff = start_vtxoff+num_packed_prims;
2002 geo_SetTopoMappedParallel<int>(vertexToPoint, start_ptoff, start_vtxoff,
nullptr));
2007 geo_SetTopoMappedParallel<int>(pointToVertex, start_vtxoff, start_ptoff,
nullptr));
2016 const exint num_target_points,
2019 const exint *
const num_source_attribs,
2020 const bool no_transforms,
2021 const bool had_transform_matrices,
2022 const bool has_transform_matrices,
2023 const bool topology_changed,
2024 const bool transforms_changed,
2028 const exint *
const target_to_piecei,
2032 if (num_target_points <= 0)
2037 UT_ASSERT(source_offset_lists !=
nullptr);
2039 UT_ASSERT((target ==
nullptr && no_transforms) || cache !=
nullptr);
2040 const exint num_output_elements =
2044 const bool copy_source_attribs_in_parallel = num_output_elements >= 4096;
2046 for (
int owneri = 0; owneri < 3; ++owneri)
2048 const exint *piece_offset_starts =
nullptr;
2049 const exint *piece_offset_starts_end =
nullptr;
2050 if (owner_piece_offset_starts)
2052 auto &array = owner_piece_offset_starts[owneri];
2053 piece_offset_starts = array.
getArray();
2054 piece_offset_starts_end = array.getArray() + array.size();
2057 const GA_OffsetList &source_offset_list = source_offset_lists[owneri];
2066 output_splittable_ranges[owneri].iterateCreate(iterator_state);
2069 output_splittable_ranges[owneri].iterateRewind(iterator_state, start_offset, first_block_end);
2083 auto target_it = target_attrib_info->
find(name);
2084 if (!target_it.atEnd())
2086 if (target_it->second.myCopyTo == owner)
2088 target_method = target_it->second.myCombineMethod;
2091 if (target_method == AttribCombineMethod::COPY)
2094 else if (target_it->second.myCombineMethod == AttribCombineMethod::COPY &&
2095 target_it->second.myCopyTo == guConflictAttribOwner(owner))
2109 bool target_changed =
false;
2113 if (!prev_target_it.atEnd())
2115 if (prev_target_it->second.myCopyTo == owner)
2117 prev_target_method = prev_target_it->second.myCombineMethod;
2122 GA_DataId prev_target_dataid = prev_target_it->second.myDataID;
2123 target_changed = !target_attrib ||
2126 target_attrib->
getDataId() != prev_target_dataid;
2130 if (target_method != prev_target_method)
2132 target_changed =
true;
2141 GA_TypeInfo transform_type = no_transforms ?
GA_TYPE_VOID : guGetTransformTypeInfo(output_numeric, has_transform_matrices);
2148 if (!topology_changed && !transforms_changed && !target_changed)
2161 if (target && !prev_target_it.atEnd())
2164 guApplyTransformToAttribute(
2170 copy_source_attribs_in_parallel,
2172 output_splittable_ranges[owneri],
2176 piece_offset_starts,
2177 piece_offset_starts_end,
2182 if (cache !=
nullptr)
2185 if (!topology_changed && !target_changed)
2193 if (no_transforms || has_transform_matrices || !had_transform_matrices)
2198 GA_TypeInfo old_transform_type = guGetTransformTypeInfo(output_numeric, has_transform_matrices);
2211 if (target && !prev_target_it.atEnd())
2217 auto &&functor = [output_numeric,source_numeric,&source_offset_list,
2218 piece_offset_starts,piece_offset_starts_end,num_target_points,
2221 auto &output_data = output_numeric->
getData();
2222 const auto &source_data = source_numeric->getData();
2229 exint piece_elementi;
2230 exint piece_element_count;
2232 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
2233 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
2234 num_target_points, target_to_piecei, piece_data, owneri,
2235 &source_offset_list, source_offset_list.
size());
2238 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
2240 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
2243 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
2244 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
2248 if (copy_source_attribs_in_parallel)
2251 functor(output_splittable_ranges[owneri]);
2257 if (cache !=
nullptr)
2260 if (!topology_changed && !target_changed)
2270 if (target && !prev_target_it.atEnd())
2281 auto &&functor = [output_string,source_string,&source_offset_list,
2282 piece_offset_starts,piece_offset_starts_end,num_target_points,
2293 exint piece_elementi;
2294 exint piece_element_count;
2296 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
2297 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
2298 num_target_points, target_to_piecei, piece_data, owneri,
2299 &source_offset_list, source_offset_list.
size());
2301 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
2303 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
2304 output_string_handle.
set(dest_off, source_string_handle.get(source_off));
2306 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
2307 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
2311 if (copy_source_attribs_in_parallel)
2314 functor(output_splittable_ranges[owneri]);
2318 auto &&functor = [output_attrib,source_attrib,&source_offset_list,
2319 piece_offset_starts,piece_offset_starts_end,num_target_points,
2327 exint piece_elementi;
2328 exint piece_element_count;
2330 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
2331 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
2332 num_target_points, target_to_piecei, piece_data, owneri,
2333 &source_offset_list, source_offset_list.
size());
2335 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
2337 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
2338 output_attrib->
copy(dest_off, *source_attrib, source_off);
2340 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
2341 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
2345 if (copy_source_attribs_in_parallel)
2348 functor(output_splittable_ranges[owneri]);
2355 for (
int owneri = 0; owneri < 3; ++owneri)
2357 const exint *piece_offset_starts =
nullptr;
2358 const exint *piece_offset_starts_end =
nullptr;
2359 if (owner_piece_offset_starts)
2361 auto &array = owner_piece_offset_starts[owneri];
2362 piece_offset_starts = array.
getArray();
2363 piece_offset_starts_end = array.getArray() + array.size();
2366 const GA_OffsetList &source_offset_list = source_offset_lists[owneri];
2375 output_splittable_ranges[owner].iterateCreate(iterator_state);
2378 output_splittable_ranges[owner].iterateRewind(iterator_state, start_offset, first_block_end);
2384 "GUremoveUnnecessaryAttribs removes internal groups and "
2385 "GUaddAttributesFromSourceOrTarget doesn't add them");
2393 auto target_it = target_group_info->
find(name);
2394 if (!target_it.atEnd())
2396 if (target_it->second.myCopyTo == owner)
2398 target_method = target_it->second.myCombineMethod;
2401 if (target_method == AttribCombineMethod::COPY)
2404 else if (target_it->second.myCombineMethod == AttribCombineMethod::COPY &&
2405 target_it->second.myCopyTo == guConflictAttribOwner(owner))
2419 bool target_changed =
false;
2423 if (!prev_target_it.atEnd())
2425 if (prev_target_it->second.myCopyTo == owner)
2427 prev_target_method = prev_target_it->second.myCombineMethod;
2432 GA_DataId prev_target_dataid = prev_target_it->second.myDataID;
2433 target_changed = !target_group ||
2436 target_group->
getDataId() != prev_target_dataid;
2440 if (target_method != prev_target_method)
2442 target_changed =
true;
2449 if (cache !=
nullptr)
2452 if (!topology_changed && !target_changed)
2462 if (target && !prev_target_it.atEnd())
2469 auto &&functor = [output_group,source_group,&source_offset_list,
2470 piece_offset_starts,piece_offset_starts_end,owneri,target_to_piecei,piece_data,
2478 exint piece_elementi;
2479 exint piece_element_count;
2481 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
2482 &piece_offset_list, start_offset, piece_offset_starts, piece_offset_starts_end,
2483 num_target_points, target_to_piecei, piece_data, owneri,
2484 &source_offset_list, source_offset_list.
size());
2486 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
2488 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
2489 output_group->
setElement(dest_off, source_group->contains(source_off));
2491 guIteratePieceElement(piece_elementi, piece_element_count, targeti, piece_offset_starts,
2492 num_target_points, target_to_piecei, piece_data, owneri, piece_offset_list);
2496 if (copy_source_attribs_in_parallel)
2499 functor(output_splittable_ranges[owneri]);
2506 bool all_source_points;
2512 if (!all_source_points)
2515 for (
exint i = 0,
n = source_point_list.
size(); i <
n; ++i)
2517 source_to_sourcei.
set(source_point_list[i], i);
2525 "GUremoveUnnecessaryAttribs removes internal groups and "
2526 "GUaddAttributesFromSourceOrTarget doesn't add them");
2530 if (cache !=
nullptr)
2533 if (!topology_changed)
2536 if (!it.atEnd() && it->second !=
GA_INVALID_DATAID && it->second == source_group->getDataId())
2555 for (
auto it = source_group->begin(); !it.atEnd(); ++it)
2557 const GA_Edge source_edge = it.getEdge();
2560 if (all_source_points)
2571 if (index0 == -1 || index1 == -1)
2579 output_group->
add(output_edge);
2583 output_edge.p0() += source_point_count;
2584 output_edge.p1() += source_point_count;
2585 output_group->
add(output_edge);
2597 const exint *piece_offset_starts =
nullptr;
2598 const exint *piece_offset_starts_end =
nullptr;
2599 if (owner_piece_offset_starts)
2602 piece_offset_starts = array.
getArray();
2603 piece_offset_starts_end = array.getArray() + array.size();
2609 auto &&functor = [transform_matrices_3d,transform_translates_3d,output_geo,
2610 piece_offset_starts,piece_offset_starts_end,target_to_piecei,piece_data,
2613 const exint source_prim_count = source_prim_list.
size();
2620 exint piece_elementi;
2621 exint piece_element_count;
2623 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
2624 &piece_offset_list, start_primoff, piece_offset_starts, piece_offset_starts_end,
2626 &source_prim_list, source_prim_count);
2629 if (transform_matrices_3d)
2630 transform =
UT_Matrix4D(transform_matrices_3d[targeti]);
2639 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
2641 GEO_Primitive *prim = output_geo->getGEOPrimitive(dest_off);
2643 if (!topology_changed)
2649 GA_Offset source_off = (*piece_offset_list)[piece_elementi];
2650 const GA_Primitive *source_prim = source->getPrimitive(source_off);
2660 while (piece_elementi >= piece_element_count)
2665 if (targeti >= num_target_points)
2668 if (transform_matrices_3d)
2669 transform =
UT_Matrix4D(transform_matrices_3d[targeti]);
2677 if (piece_offset_starts !=
nullptr)
2679 exint piecei = target_to_piecei[targeti];
2682 piece_element_count = piece_offset_list->
size();
2688 if (copy_source_attribs_in_parallel)
2691 functor(output_splittable_ranges[GA_ATTRIB_PRIMITIVE]);
2694 if (copy_source_attribs_in_parallel)
2702 const exint ncopies,
2704 const exint source_point_count,
2705 const exint source_vertex_count,
2706 const exint source_prim_count,
2707 const exint *
const num_target_attribs,
2712 const bool topology_changed,
2713 const exint *
const target_to_piecei,
2722 const exint num_target_output_elements =
2726 const bool copy_target_attribs_in_parallel = num_target_output_elements >= 4096;
2728 if (num_target_output_elements <= 0)
2731 exint source_element_counts[3] =
2733 source_vertex_count,
2738 "Arrays above and loop below are assuming the order of GA_AttributeOwner enum");
2740 const exint num_target_points = target_point_list.
size();
2743 for (
auto it = target_attrib_info.
begin(); !it.
atEnd(); ++it)
2760 output_splittable_ranges[owner].iterateCreate(iterator_state);
2763 output_splittable_ranges[owner].iterateRewind(iterator_state, start_offset, first_block_end);
2765 exint num_elements_per_copy = source_element_counts[owner];
2766 const AttribCombineMethod method = it->second.myCombineMethod;
2770 if (!topology_changed)
2776 if (!prev_it.atEnd() &&
2777 prev_it->second.myDataID == it->second.myDataID &&
2778 prev_it->second.myCopyTo == it->second.myCopyTo &&
2779 prev_it->second.myCombineMethod == it->second.myCombineMethod)
2785 const exint *piece_offset_starts =
nullptr;
2786 const exint *piece_offset_starts_end =
nullptr;
2787 if (owner_piece_offset_starts)
2789 auto &array = owner_piece_offset_starts[owner];
2790 piece_offset_starts = array.
getArray();
2791 piece_offset_starts_end = array.getArray() + array.size();
2796 if (method == AttribCombineMethod::COPY)
2801 auto &&functor = [output_attrib,target_attrib,&target_point_list,num_elements_per_copy,
2802 start_offset,piece_offset_starts,piece_offset_starts_end,
2810 exint piece_elementi;
2811 exint piece_element_count;
2812 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
2813 nullptr, start_offset, piece_offset_starts, piece_offset_starts_end,
2814 num_target_points, target_to_piecei, piece_data, owner,
2815 nullptr, num_elements_per_copy);
2817 GA_Offset target_off = target_point_list[targeti];
2820 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
2822 output_attrib->
copy(dest_off, *target_attrib, target_off);
2824 guIteratePieceElementOff(piece_elementi, piece_element_count, targeti, piece_offset_starts,
2825 num_target_points, target_to_piecei, piece_data, owner, target_off, target_point_list);
2829 if (copy_target_attribs_in_parallel)
2832 functor(output_splittable_ranges[owner]);
2841 if (method == AttribCombineMethod::MULTIPLY)
2844 auto &&functor = [&output_data,&target_data,&target_point_list,num_elements_per_copy,min_tuple_size,
2845 start_offset,piece_offset_starts,piece_offset_starts_end,
2853 exint piece_elementi;
2854 exint piece_element_count;
2855 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
2856 nullptr, start_offset, piece_offset_starts, piece_offset_starts_end,
2857 num_target_points, target_to_piecei, piece_data, owner,
2858 nullptr, num_elements_per_copy);
2860 GA_Offset target_off = target_point_list[targeti];
2863 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
2865 for (
exint component = 0; component < min_tuple_size; ++component)
2875 fpreal64 product = existing_value*target_value;
2876 output_data.set(dest_off, component, product);
2879 guIteratePieceElementOff(piece_elementi, piece_element_count, targeti, piece_offset_starts,
2880 num_target_points, target_to_piecei, piece_data, owner, target_off, target_point_list);
2884 if (copy_target_attribs_in_parallel)
2887 functor(output_splittable_ranges[owner]);
2889 else if (method == AttribCombineMethod::ADD)
2892 auto &&functor = [&output_data,&target_data,&target_point_list,num_elements_per_copy,min_tuple_size,
2893 start_offset,piece_offset_starts,piece_offset_starts_end,
2901 exint piece_elementi;
2902 exint piece_element_count;
2903 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
2904 nullptr, start_offset, piece_offset_starts, piece_offset_starts_end,
2905 num_target_points, target_to_piecei, piece_data, owner,
2906 nullptr, num_elements_per_copy);
2908 GA_Offset target_off = target_point_list[targeti];
2911 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
2913 for (
exint component = 0; component < min_tuple_size; ++component)
2921 fpreal64 sum = existing_value + target_value;
2922 output_data.set(dest_off, component, sum);
2925 guIteratePieceElementOff(piece_elementi, piece_element_count, targeti, piece_offset_starts,
2926 num_target_points, target_to_piecei, piece_data, owner, target_off, target_point_list);
2930 if (copy_target_attribs_in_parallel)
2933 functor(output_splittable_ranges[owner]);
2938 auto &&functor = [&output_data,&target_data,&target_point_list,num_elements_per_copy,min_tuple_size,
2939 start_offset,piece_offset_starts,piece_offset_starts_end,
2947 exint piece_elementi;
2948 exint piece_element_count;
2949 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
2950 nullptr, start_offset, piece_offset_starts, piece_offset_starts_end,
2951 num_target_points, target_to_piecei, piece_data, owner,
2952 nullptr, num_elements_per_copy);
2954 GA_Offset target_off = target_point_list[targeti];
2957 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
2959 for (
exint component = 0; component < min_tuple_size; ++component)
2967 fpreal64 difference = existing_value - target_value;
2968 output_data.set(dest_off, component, difference);
2971 guIteratePieceElementOff(piece_elementi, piece_element_count, targeti, piece_offset_starts,
2972 num_target_points, target_to_piecei, piece_data, owner, target_off, target_point_list);
2976 if (copy_target_attribs_in_parallel)
2979 functor(output_splittable_ranges[owner]);
2983 for (
auto it = target_group_info.
begin(); !it.
atEnd(); ++it)
3000 output_splittable_ranges[owner].iterateCreate(iterator_state);
3003 output_splittable_ranges[owner].iterateRewind(iterator_state, start_offset, first_block_end);
3005 const AttribCombineMethod method = it->second.myCombineMethod;
3009 if (!topology_changed)
3015 if (!prev_it.atEnd() &&
3016 prev_it->second.myDataID == it->second.myDataID &&
3017 prev_it->second.myCopyTo == it->second.myCopyTo &&
3018 prev_it->second.myCombineMethod == it->second.myCombineMethod)
3024 const exint *piece_offset_starts =
nullptr;
3025 const exint *piece_offset_starts_end =
nullptr;
3026 if (owner_piece_offset_starts)
3028 auto &array = owner_piece_offset_starts[owner];
3029 piece_offset_starts = array.
getArray();
3030 piece_offset_starts_end = array.getArray() + array.size();
3036 if (method == AttribCombineMethod::COPY)
3039 exint num_elements_per_copy = source_element_counts[owner];
3040 auto &&functor = [output_group,target_group,&target_point_list,num_elements_per_copy,
3041 start_offset,piece_offset_starts,piece_offset_starts_end,
3049 exint piece_elementi;
3050 exint piece_element_count;
3051 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
3052 nullptr, start_offset, piece_offset_starts, piece_offset_starts_end,
3053 num_target_points, target_to_piecei, piece_data, owner,
3054 nullptr, num_elements_per_copy);
3056 GA_Offset target_off = target_point_list[targeti];
3057 bool target_in_group = target_group->contains(target_off);
3060 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
3062 output_group->
setElement(dest_off, target_in_group);
3064 guIteratePieceElementGroup(piece_elementi, piece_element_count, targeti, piece_offset_starts,
3065 num_target_points, target_to_piecei, piece_data, owner, target_in_group, target_point_list, target_group);
3069 if (copy_target_attribs_in_parallel)
3072 functor(output_splittable_ranges[owner]);
3074 else if (method == AttribCombineMethod::MULTIPLY)
3077 exint num_elements_per_copy = source_element_counts[owner];
3078 auto &&functor = [output_group,target_group,&target_point_list,num_elements_per_copy,
3079 start_offset,piece_offset_starts,piece_offset_starts_end,
3087 exint piece_elementi;
3088 exint piece_element_count;
3089 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
3090 nullptr, start_offset, piece_offset_starts, piece_offset_starts_end,
3091 num_target_points, target_to_piecei, piece_data, owner,
3092 nullptr, num_elements_per_copy);
3094 GA_Offset target_off = target_point_list[targeti];
3095 bool target_in_group = target_group->contains(target_off);
3098 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
3100 if (!target_in_group)
3103 guIteratePieceElementGroup(piece_elementi, piece_element_count, targeti, piece_offset_starts,
3104 num_target_points, target_to_piecei, piece_data, owner, target_in_group, target_point_list, target_group);
3108 if (copy_target_attribs_in_parallel)
3111 functor(output_splittable_ranges[owner]);
3113 else if (method == AttribCombineMethod::ADD)
3116 exint num_elements_per_copy = source_element_counts[owner];
3117 auto &&functor = [output_group,target_group,&target_point_list,num_elements_per_copy,
3118 start_offset,piece_offset_starts,piece_offset_starts_end,
3126 exint piece_elementi;
3127 exint piece_element_count;
3128 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
3129 nullptr, start_offset, piece_offset_starts, piece_offset_starts_end,
3130 num_target_points, target_to_piecei, piece_data, owner,
3131 nullptr, num_elements_per_copy);
3133 GA_Offset target_off = target_point_list[targeti];
3134 bool target_in_group = target_group->contains(target_off);
3137 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
3139 if (target_in_group)
3142 guIteratePieceElementGroup(piece_elementi, piece_element_count, targeti, piece_offset_starts,
3143 num_target_points, target_to_piecei, piece_data, owner, target_in_group, target_point_list, target_group);
3147 if (copy_target_attribs_in_parallel)
3150 functor(output_splittable_ranges[owner]);
3155 exint num_elements_per_copy = source_element_counts[owner];
3156 auto &&functor = [output_group,target_group,&target_point_list,num_elements_per_copy,
3157 start_offset,piece_offset_starts,piece_offset_starts_end,
3165 exint piece_elementi;
3166 exint piece_element_count;
3167 guFindStartInTarget(start, targeti, piece_elementi, piece_element_count,
3168 nullptr, start_offset, piece_offset_starts, piece_offset_starts_end,
3169 num_target_points, target_to_piecei, piece_data, owner,
3170 nullptr, num_elements_per_copy);
3172 GA_Offset target_off = target_point_list[targeti];
3173 bool target_in_group = target_group->contains(target_off);
3176 for (
GA_Offset dest_off = start; dest_off <
end; ++dest_off)
3178 if (target_in_group)
3181 guIteratePieceElementGroup(piece_elementi, piece_element_count, targeti, piece_offset_starts,
3182 num_target_points, target_to_piecei, piece_data, owner, target_in_group, target_point_list, target_group);
3186 if (copy_target_attribs_in_parallel)
3189 functor(output_splittable_ranges[owner]);
3193 if (copy_target_attribs_in_parallel)
3198 target_attrib_info.
clear();
3199 target_group_info.
clear();
3206 const bool had_transform_matrices,
3207 const exint num_packed_prims,
3212 if (num_packed_prims <= 0)
3221 auto &&functor = [output_geo,
3222 start_ptoff,start_primoff,transform_translates_3d,transform_matrices_3d,
3223 output_pos3f,output_pos3d,had_transform_matrices,constant_pivot](
const GA_Range &
r)
3229 if (transform_matrices_3d || had_transform_matrices)
3232 if (!transform_matrices_3d)
3235 exint transformi = start - start_primoff;
3236 for (
GA_Offset primoff = start; primoff <
end; ++primoff, ++transformi)
3240 if (transform_matrices_3d)
3252 if (!constant_pivot)
3255 exint transformi = start - start_primoff;
3256 for (
GA_Offset primoff = start; primoff <
end; ++primoff, ++transformi)
3260 GA_Offset ptoff = start_ptoff + transformi;
3265 if (transform_matrices_3d)
3266 transformed_pivot = transformed_pivot*transform_matrices_3d[transformi];
3267 if (transform_translates_3d)
3268 transformed_pivot += transform_translates_3d[transformi];
3269 output_pos3d.set(ptoff, transformed_pivot);
3276 exint transformi = start - start_primoff;
3277 GA_Offset local_start_ptoff = start_ptoff + transformi;
3278 GA_Offset local_end_ptoff = start_ptoff + (end-start_primoff);
3279 if (!transform_translates_3d)
3281 for (
GA_Offset ptoff = local_start_ptoff; ptoff < local_end_ptoff; ++ptoff, ++transformi)
3285 if (transform_matrices_3d)
3286 transformed_pivot = transformed_pivot*transform_matrices_3d[transformi];
3288 output_pos3d.set(ptoff, transformed_pivot);
3291 else if (constant_pivot->
isZero())
3295 for (
GA_Offset ptoff = local_start_ptoff; ptoff < local_end_ptoff; ++ptoff, ++transformi)
3297 output_pos3d.set(ptoff, transform_translates_3d[transformi]);
3302 for (
GA_Offset ptoff = local_start_ptoff; ptoff < local_end_ptoff; ++ptoff, ++transformi)
3304 output_pos3f.set(ptoff,
UT_Vector3F(transform_translates_3d[transformi]));
3310 for (
GA_Offset ptoff = local_start_ptoff; ptoff < local_end_ptoff; ++ptoff, ++transformi)
3314 if (transform_matrices_3d)
3315 transformed_pivot = transformed_pivot*transform_matrices_3d[transformi];
3317 output_pos3d.set(ptoff, transform_translates_3d[transformi] + transformed_pivot);
3323 constexpr
exint PARALLEL_THRESHOLD = 2048;
3324 if (num_packed_prims >= PARALLEL_THRESHOLD)
3334 const bool topology_changed,
3335 const bool had_transform_matrices,
3344 exint num_target_points = target_point_list.
size();
3349 if (!topology_changed)
3356 &target_attrib_info,
3357 &target_group_info);
3361 exint num_target_attribs[3] = {0,0,0};
3363 "Array above is assuming the order of GA_AttributeOwner enum");
3372 &target_attrib_info,
3374 num_target_attribs);
3384 "Array above is assuming the order of GA_AttributeOwner enum");
3388 output_splittable_ranges,
3410 bool source_topology_changed,
3411 bool had_transform_matrices,
3412 bool transforms_changed,
3413 const exint num_packed_prims,
3419 const bool topology_changed =
3424 const bool source_changed =
3428 source_topology_changed;
3430 const bool source_intrinsic_changed =
3437 if (topology_changed)
3450 if ((source_intrinsic_changed || source_changed || topology_changed) && num_packed_prims > 0)
3455 const bool impl_changed = (source_changed || topology_changed);
3459 if (!source_primgroup && !source_pointgroup)
3486 exint num_source_attribs[3];
3488 "Array above depends on owners other than detail being less than 3");
3492 num_source_attribs);
3501 "Array above is assuming the order of GA_AttributeOwner enum");
3505 output_splittable_ranges,
3520 packed_geo = packed_geo_nc;
3544 auto &&functor = [output_geo,packed_geo_nc,
3547 for (
GA_Offset primoff =
r.begin(), end =
r.end(); primoff <
end; ++primoff)
3567 constexpr
exint PARALLEL_THRESHOLD = 2048;
3568 if (num_packed_prims >= PARALLEL_THRESHOLD)
3571 functor(prim_range);
3573 else if ((num_packed_prims > 0) && centroid_pivot)
3579 packed_impl->getBoundsCached(bbox);
3584 const bool pivots_changed =
3586 (centroid_pivot && source_changed);
3588 if (num_packed_prims > 0)
3590 if (target !=
nullptr)
3592 UT_ASSERT(target_point_list !=
nullptr && num_packed_prims == target_point_list->
size());
3597 had_transform_matrices,
3600 *target_attrib_info,
3610 had_transform_matrices,
3616 if (topology_changed)
3620 if (source_changed && num_packed_prims > 0)
3624 if (transforms_changed || pivots_changed)
3630 if ((has_transform_matrices || had_transform_matrices) && !source_changed)
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, const GA_OffsetListRef *target_point_list, GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info, GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info)
SYS_FORCE_INLINE void clear()
clear removes all of the entries
SYS_FORCE_INLINE const GU_PackedImpl * sharedImplementation() const
A class to manage an ordered array which has fixed offset handles.
constexpr SYS_FORCE_INLINE T length2() const noexcept
void GUcreatePointOrPrimList(GA_OffsetList &offset_list, const GU_Detail *const detail, const GA_ElementGroup *const group, const GA_AttributeOwner owner)
GA_DataId myPrevSourceGroupDataID
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, const GU_CopyToPointsCache::TargetAttribInfoMap *const target_attrib_info, const GU_CopyToPointsCache::TargetAttribInfoMap *const target_group_info, const exint *const target_to_piecei, const UT_Array< exint > *const owner_piece_offset_starts, const GU_CopyToPointsCache::PieceData *const piece_data)
SYS_FORCE_INLINE void bumpDataId()
SYS_FORCE_INLINE void forEachAttribute(FUNCTOR &&functor) const
static SYS_FORCE_INLINE bool isType(const GA_Attribute *attrib)
Definition of a geometry attribute.
UT_Matrix4T< fpreal64 > UT_Matrix4D
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)
Data has no numeric representation.
void GUupdatePackedPrimTransforms(GU_Detail *output_geo, GU_CopyToPointsCache *cache, const bool had_transform_matrices, const exint num_packed_prims, const UT_Vector3 *const constant_pivot)
UT_ArrayStringMap< GA_DataId > mySourceGroupDataIDs[3]
SYS_FORCE_INLINE GA_Primitive * getPrimitive(GA_Offset prim_off)
SYS_FORCE_INLINE const GA_AttributeDict & pointAttribs() 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.
const GA_IndexMap & getPrimitiveMap() const
GA_DataId getDataId() const
Iteration over a range of elements.
FromType find(ToType value, FromType s=FromType(0)) const
void scale(T sx, T sy, T sz)
#define SYS_STATIC_ASSERT_MSG(expr, msg)
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
const DataType & getData() const
SYS_FORCE_INLINE const GA_IndexMap & getIndexMap() const
SYS_FORCE_INLINE void colVecMult(const UT_Matrix3F &m)
virtual void copySubclassData(const GA_Primitive *source)
SYS_FORCE_INLINE bool atEnd() const
GA_Size entries() const overridefinal
Will return the number of primary elements.
void homogenize()
Express the point in homogeneous coordinates or vice-versa.
void clearAndDestroy()
Clear all the points/primitives out of this detail.
GA_ElementGroup * findElementGroup(GA_AttributeOwner owner, const UT_StringRef &name)
void getDataIds(GA_DataId data_ids[theNumAttribs]) const
SYS_FORCE_INLINE bool isValid() const
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)
SYS_FORCE_INLINE bool getExtraFlag() const
Synonym for isClosed()
GA_DataId getDataId() const
Return the data ID for the topology attributes.
SYS_FORCE_INLINE DEST_DATA_T get(GA_Offseti, exint component=0) const
void GUcomputeTransformTypeCaches(GU_PointTransformCache *cache, exint num_target_points, bool transforms_changed, const bool needed_transforms[NeededTransforms::num_needed_transforms])
GA_Attribute * getP()
Convenience method to access the P attribute.
SYS_FORCE_INLINE GA_AttributeScope getScope() const
void setTrivialRange(FromType startindex, ToType startvalue, GA_Size nelements)
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.
void clearOrdered()
Clear all order information, including any mixed entries.
exint myPrevSourceMetaCacheCount
void GEO_API GEOcomputeNormals(const GEO_Detail &detail, const GA_RWHandleV3 &normalattrib, const GA_Group *group=NULL, const float cuspangledegrees=GEO_DEFAULT_ADJUSTED_CUSP_ANGLE, const GEO_NormalMethod method=GEO_NormalMethod::ANGLE_WEIGHTED, const bool copy_orig_if_zero=false)
bool hasTransformingPrimitives() const
void UTparallelForLightItems(const Range &range, const Body &body, const bool force_use_task_scope=true)
GA_EdgeGroupTable & edgeGroups()
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
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, const UT_Array< exint > *const owner_piece_offset_starts, const GU_CopyToPointsCache::PieceData *const piece_data)
Standard user attribute level.
SYS_FORCE_INLINE UT_FixedVector< DEST_DATA_T, DEST_TSIZE > getVector(GA_Offseti) const
GLdouble GLdouble GLdouble q
#define GA_INVALID_DATAID
virtual bool matchesStorage(const GA_Attribute *that) const
constexpr UT_Vector4T< SYS_FixedArrayElement_t< TS > > UTmakeVector4T(const TS &as) noexcept
bool getBoundsCached(UT_BoundingBox &box) const
SYS_FORCE_INLINE void set(GA_Offseti, SRC_DATA_T v)
component == 0 in this version
SYS_FORCE_INLINE bool GAisValid(GA_Size v)
GA_OffsetList mySourceOffsetLists[3]
exint GA_Size
Defines the bit width for index and offset types in GA.
UT_Matrix4T< float > UT_Matrix4
SYS_FORCE_INLINE iterator begin(GA_AttributeScope scope=GA_SCOPE_INVALID) const
#define GA_INVALID_OFFSET
iterator find(const Key &key)
GA_Size countPrimitiveType(const GA_PrimitiveTypeId &type) const
bool hasAnyAttribs() const
Returns true if there are any attributes bound.
GA_GroupTable::iterator< GA_EdgeGroup > beginTraverse() const
Geometry Embedded procedural.
A range of elements in an index-map.
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
SYS_FORCE_INLINE GA_ElementGroup * find(const UT_StringRef &name) const
SYS_FORCE_INLINE const UT_StringHolder & getName() const
void setViewportLOD(GEO_ViewportLOD vlod)
#define UT_ASSERT_MSG(ZZ,...)
void allocateAndSet(GU_Detail *gdp, bool own=true)
tbb::task_group_status wait()
void updateFromArbitraryMatrix(const UT_Matrix3 &)
Parent::const_iterator const_iterator
SYS_FORCE_INLINE bool isTrivial() const
const GA_ElementGroupTable & getElementGroupTable(GA_AttributeOwner owner) const
GA_Size myPrevTargetPtCount
const GA_EdgeGroup * findEdgeGroup(const UT_StringRef &name) const
const GA_ROHandleV3D & getN() const
GA_Range getPointRange(const GA_PointGroup *group=0) const
Get a range of all points in the detail.
const GA_IndexMap & getPointMap() const
GA_Attribute * cloneAttribute(GA_AttributeOwner owner, const UT_StringHolder &name, namevalidcertificate, const GA_Attribute &src, bool clone_options, GA_DataIdStrategy data_id_strategy=GA_DATA_ID_BUMP, const GA_ReuseStrategy &reuse=GA_ReuseStrategy())
UT_QuaternionT< fpreal32 > UT_QuaternionF
void identity()
Set the matrix to identity.
constexpr UT_Matrix3T< SYS_FixedArrayElement_t< TS > > UTmakeMatrix3T(const TS &as) noexcept
UT_Vector3T< T > center() const
SYS_FORCE_INLINE void setElement(GA_Offset ai, bool v)
virtual void replace(const GA_Attribute &src)=0
SYS_FORCE_INLINE GA_Offset appendPointBlock(GA_Size npoints)
Append new points, returning the first offset of the contiguous block.
SYS_FORCE_INLINE bool destroyElementGroup(GA_AttributeOwner owner, const UT_StringRef &name)
void bumpDataId()
Use this to mark primitives or their intrinsic data as dirty.
GEO_ViewportLOD myPrevViewportLOD
void GUcreateEmptyPackedGeometryPrims(GU_Detail *const output_geo, const exint num_packed_prims)
void UTparallelForRunInTaskGroup(UT_TaskGroup &task_group, RANGE &&range, BODY &&body)
static constexpr int theNumAttribs
SYS_FORCE_INLINE const GA_PointGroup * findPointGroup(const UT_StringRef &name) const
static SYS_FORCE_INLINE GA_ATINumeric * cast(GA_Attribute *attrib)
SYS_FORCE_INLINE GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const
void getMatrix(UT_Matrix4 &xform, const UT_Vector3 &P, GA_Offset offset, float default_pscale=1) const
GEO_API 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=1)
void setLocalTransform(const UT_Matrix3D &matrix) override
iterator begin()
Returns a non-const iterator for the beginning of the set.
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)
GLsizei GLsizei GLchar * source
GA_AttributeSet & getAttributes()
constexpr UT_Matrix4T< SYS_FixedArrayElement_t< TS > > UTmakeMatrix4T(const TS &as) noexcept
const GA_IndexMap & getIndexMap(GA_AttributeOwner owner) const
SYS_FORCE_INLINE void rowVecMult(const UT_Matrix3F &m)
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
UT_ArrayStringMap< GA_DataId > mySourceAttribDataIDs[3]
Parent::iterator iterator
SYS_FORCE_INLINE GA_Offset getNumPointOffsets() const
GA_OffsetList mySourceOffsetLists[3]
static SYS_FORCE_INLINE GA_ATIString * cast(GA_Attribute *attrib)
virtual void setPivot(const UT_Vector3 &pos)
UT_Matrix3T< fpreal32 > UT_Matrix3F
const GA_IndexMap & getVertexMap() const
GA_GroupTable::iterator< GA_ElementGroup > beginTraverse() const
exint myPrevOutputDetailID
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
void identity()
Set the matrix to identity.
bool isOrdered() const overridefinal
Returns true if the group is currently ordered.
GA_Group * newGroup(const UT_StringHolder &name)
GLuint const GLchar * name
GA_OffsetList mySourceOffsetLists[3]
SYS_FORCE_INLINE GA_DataId getDataId() const
SYS_FORCE_INLINE const GA_Attribute * findAttribute(GA_AttributeScope scope, const UT_StringRef &name, const GA_AttributeOwner search_order[], int search_size) const
const UT_StringHolder & getName() const
SYS_FORCE_INLINE bool destroyEdgeGroup(const UT_StringRef &name)
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
GA_API const UT_StringHolder transform
virtual void copyNonStorageMetadata(const GA_Attribute *that)
void getPrimitiveTypeCounts(UT_Array< std::pair< int, exint >> &type_count_pairs, const GA_Range *range=nullptr) const
UT_UniquePtr< GA_Attribute > GA_AttributeUPtr
exint getUniqueId() const
void setTranslates(const UT_Vector3T< S > &translates)
GA_Topology & getTopology()
exint mySourceVertexCount
virtual void getPivot(UT_Vector3 &pos) const
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 bool isValid() const
UT_Vector3T< fpreal32 > UT_Vector3F
Define a range based on a specific offset list.
bool isSame(const GA_ListTypeRef &that) const
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
void moveRange(GA_Offsetsrcstart, GA_Offsetdeststart, GA_Offsetnelements)
virtual void transform(const UT_Matrix4 &)
SYS_FORCE_INLINE GA_Size getNumVertices() const
Return the number verticies in the entire detail.
Data represents a quaternion. Token "quaternion".
void GUaddAttributesFromSourceOrTarget(GU_Detail *output_geo, const GU_Detail *source, exint *num_source_attribs, bool has_transform_matrices, bool *needed_transforms, const GU_Detail *target, GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info, GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info, exint *num_target_attribs)
void setSize(GA_Offsetnewsize)
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)
void intrusive_ptr_add_ref(T *x)
void translate(T dx, T dy, T dz=0)
SYS_FORCE_INLINE GA_TypeInfo getTypeInfo() const
constexpr UT_Vector3T< SYS_FixedArrayElement_t< TS > > UTmakeVector3T(const TS &as) noexcept
SYS_FORCE_INLINE bool isValid() const
Check whether the bounding box contains at least one point.
SYS_FORCE_INLINE GA_Index indexSize() const
SYS_FORCE_INLINE GA_Offset primitiveOffset(GA_Index index) const
Given a primitive's index (in append order), return its data offset.
virtual bool copy(GA_Offset desti, GA_Offset srci)
Data represents a normal vector. Token "normal".
void append(GA_Size size, GA_Size count=1)
SYS_FORCE_INLINE const GA_ATITopology * getVertexRef() const
constexpr SYS_FORCE_INLINE bool isZero() const noexcept
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
constexpr UT_QuaternionT< SYS_FixedArrayElement_t< TS > > UTmakeQuaternionT(const TS &as) noexcept
iterator erase(iterator pos)
Compute an instance transform given a set of attributes.
Data represents a direction vector. Token "vector".
int64 getMetaCacheCount() const
UT_ArrayStringMap< GA_DataId > mySourceEdgeGroupDataIDs
void swap(set_type &that)
Swaps another set with this one.
GA_API const UT_StringHolder pivot
const GA_PrimitiveList & getPrimitiveList() const
void setDetailPtr(const GU_DetailHandle &d)
bool add(const GA_Edge &edge, GA_Offset primoff=GA_INVALID_OFFSET)
Data represents a position in space. Token "point".
SYS_FORCE_INLINE GA_AttributeOwner getOwner() const
void setN(const GA_Attribute *N)
Overrides the N attribute with the specified attribute.
PackedPivot myPrevPivotEnum
SYS_FORCE_INLINE const GA_PageArray< DEST_DATA_T, TSIZE, TABLEHARDENED, PAGESHARDENED > & castType() const
SYS_FORCE_INLINE void set(GA_Offset off, const HOLDER &str)
Store the str at the given offset.
SYS_FORCE_INLINE void setVector(GA_Offseti, const TS &as)
void dehomogenize()
Express the point in homogeneous coordinates or vice-versa.
const GA_AttributeDict & getAttributeDict(GA_AttributeOwner owner) const
TargetAttribInfoMap myTargetGroupInfo
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 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.
bool OIIO_UTIL_API contains(string_view a, string_view b)
Does 'a' contain the string 'b' within it?
exint myPrevSourceUniqueID
These are only used when myPrevPack is true.
void destroyAttribute(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, const GA_AttributeFilter *filter=0)
void bumpDataIdsForAddOrRemove(bool added_or_removed_points, bool added_or_removed_vertices, bool added_or_removed_primitives)
SYS_FORCE_INLINE GA_Offset pointOffset(GA_Index index) const
Given a point's index (in append order), return its data offset.
SYS_FORCE_INLINE const GA_ATITopology * getPointRef() const
Data represents a transform matrix. Token "matrix".
void initialize(const GA_AttributeDict &dict, const UT_StringRef &N_name=GA_Names::N, const UT_StringRef &v_name=GA_Names::v)
void invalidateGroupEntries()
GA_OffsetList getOffsetFromIndexList() const
bool fullBlockAdvance(GA_Offset &start, GA_Offset &end)
TargetAttribInfoMap myTargetAttribInfo
SYS_FORCE_INLINE FromType size() const
Returns the number of used elements in the list (always <= capacity())
void getTranslates(UT_Vector3T< S > &translates) const
static GA_PrimitiveTypeId typeId()
Get the type ID for the GU_PackedGeometry primitive type.
SYS_FORCE_INLINE bool contains(GA_Offset offset) const
UT_Matrix3T< fpreal64 > UT_Matrix3D
SYS_FORCE_INLINE GA_Size getNumPoints() const
Return the number of points.
GA_Storage getStorage() const
GA_Offset appendPrimitivesAndVertices(const GA_PrimitiveTypeId &type, GA_Size nprimitives, GA_Size nvertices_each, GA_Offset &vertex_block_start, bool closed_flag=false)