8 #ifndef OPENVDB_HOUDINI_ATTRIBUTE_TRANSFER_UTIL_HAS_BEEN_INCLUDED 9 #define OPENVDB_HOUDINI_ATTRIBUTE_TRANSFER_UTIL_HAS_BEEN_INCLUDED 18 #include <GA/GA_PageIterator.h> 19 #include <GA/GA_SplittableRange.h> 20 #include <GEO/GEO_PrimPolySoup.h> 21 #include <SYS/SYS_Types.h> 30 #include <type_traits> 41 template <
typename ValueType>
inline ValueType
42 evalAttr(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
43 GA_Offset off,
int idx)
46 aif->get(atr, off, value, idx);
47 return ValueType(value);
50 template <>
inline float 52 GA_Offset off,
int idx)
55 aif->get(atr, off, value, idx);
60 evalAttr<openvdb::Int32>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
61 GA_Offset off,
int idx)
64 aif->get(atr, off, value, idx);
69 evalAttr<openvdb::Int64>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
70 GA_Offset off,
int idx)
73 aif->get(atr, off, value, idx);
78 evalAttr<openvdb::Vec3i>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
84 aif->get(atr, off, comp, 0);
87 aif->get(atr, off, comp, 1);
90 aif->get(atr, off, comp, 2);
97 evalAttr<openvdb::Vec3s>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
103 aif->get(atr, off, comp, 0);
104 vec[0] = float(comp);
106 aif->get(atr, off, comp, 1);
107 vec[1] = float(comp);
109 aif->get(atr, off, comp, 2);
110 vec[2] = float(comp);
115 template <>
inline openvdb::Vec3d
116 evalAttr<openvdb::Vec3d>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
122 aif->get(atr, off, comp, 0);
123 vec[0] = double(comp);
125 aif->get(atr, off, comp, 1);
126 vec[1] = double(comp);
128 aif->get(atr, off, comp, 2);
129 vec[2] = double(comp);
140 template <
typename ValueType>
inline ValueType
141 combine(
const ValueType& v0,
const ValueType& v1,
const ValueType& v2,
142 const openvdb::Vec3d& w)
144 return ValueType(v0 * w[0] + v1 * w[1] + v2 * w[2]);
151 if (w[2] > w[0] && w[2] > w[1])
return v2;
152 if (w[1] > w[0] && w[1] > w[2])
return v1;
160 if (w[2] > w[0] && w[2] > w[1])
return v2;
161 if (w[1] > w[0] && w[1] > w[2])
return v1;
169 if (w[2] > w[0] && w[2] > w[1])
return v2;
170 if (w[1] > w[0] && w[1] > w[2])
return v1;
180 vec[0] = float(v0[0] * w[0] + v1[0] * w[1] + v2[0] * w[2]);
181 vec[1] = float(v0[1] * w[0] + v1[1] * w[1] + v2[1] * w[2]);
182 vec[2] = float(v0[2] * w[0] + v1[2] * w[1] + v2[2] * w[2]);
187 template <>
inline openvdb::Vec3d
188 combine(
const openvdb::Vec3d& v0,
const openvdb::Vec3d& v1,
189 const openvdb::Vec3d& v2,
const openvdb::Vec3d& w)
193 vec[0] = v0[0] * w[0] + v1[0] * w[1] + v2[0] * w[2];
194 vec[1] = v0[1] * w[0] + v1[1] * w[1] + v2[1] * w[2];
195 vec[2] = v0[2] * w[0] + v1[2] * w[1] + v2[2] * w[2];
206 template <
typename ValueType>
inline ValueType
210 defaults.get(idx, value);
211 return ValueType(value);
214 template <>
inline float 218 defaults.get(0, value);
223 evalAttrDefault<openvdb::Int32>(
const GA_Defaults& defaults,
int idx)
226 defaults.get(idx, value);
231 evalAttrDefault<openvdb::Int64>(
const GA_Defaults& defaults,
int idx)
234 defaults.get(idx, value);
239 evalAttrDefault<openvdb::Vec3i>(
const GA_Defaults& defaults, int)
244 defaults.get(0, value);
247 defaults.get(1, value);
250 defaults.get(2, value);
257 evalAttrDefault<openvdb::Vec3s>(
const GA_Defaults& defaults, int)
262 defaults.get(0, value);
263 vec[0] = float(value);
265 defaults.get(1, value);
266 vec[1] = float(value);
268 defaults.get(2, value);
269 vec[2] = float(value);
274 template <>
inline openvdb::Vec3d
275 evalAttrDefault<openvdb::Vec3d>(
const GA_Defaults& defaults, int)
280 defaults.get(0, value);
281 vec[0] = double(value);
283 defaults.get(1, value);
284 vec[1] = double(value);
286 defaults.get(2, value);
287 vec[2] = double(value);
292 template <>
inline openvdb::math::Quat<float>
293 evalAttrDefault<openvdb::math::Quat<float>>(
const GA_Defaults& defaults, int)
295 openvdb::math::Quat<float> quat;
298 for (
int i = 0; i < 4; i++) {
299 defaults.get(i, value);
300 quat[i] = float(value);
306 template <>
inline openvdb::math::Quat<double>
307 evalAttrDefault<openvdb::math::Quat<double>>(
const GA_Defaults& defaults, int)
309 openvdb::math::Quat<double> quat;
312 for (
int i = 0; i < 4; i++) {
313 defaults.get(i, value);
314 quat[i] = double(value);
320 template <>
inline openvdb::math::Mat3<float>
321 evalAttrDefault<openvdb::math::Mat3<float>>(
const GA_Defaults& defaults, int)
323 openvdb::math::Mat3<float> mat;
325 float* data = mat.asPointer();
327 for (
int i = 0; i < 9; i++) {
328 defaults.get(i, value);
329 data[i] = float(value);
335 template <>
inline openvdb::math::Mat3<double>
336 evalAttrDefault<openvdb::math::Mat3<double>>(
const GA_Defaults& defaults, int)
338 openvdb::math::Mat3<double> mat;
340 double* data = mat.asPointer();
342 for (
int i = 0; i < 9; i++) {
343 defaults.get(i, value);
344 data[i] = double(value);
350 template <>
inline openvdb::math::Mat4<float>
351 evalAttrDefault<openvdb::math::Mat4<float>>(
const GA_Defaults& defaults, int)
353 openvdb::math::Mat4<float> mat;
355 float* data = mat.asPointer();
357 for (
int i = 0; i < 16; i++) {
358 defaults.get(i, value);
359 data[i] = float(value);
365 template <>
inline openvdb::math::Mat4<double>
366 evalAttrDefault<openvdb::math::Mat4<double>>(
const GA_Defaults& defaults, int)
368 openvdb::math::Mat4<double> mat;
370 double* data = mat.asPointer();
372 for (
int i = 0; i < 16; i++) {
373 defaults.get(i, value);
374 data[i] = double(value);
387 using Ptr = std::shared_ptr<AttributeDetailBase>;
394 virtual void set(
const openvdb::Coord& ijk,
const GA_Offset (&offsets)[3],
395 const openvdb::Vec3d& weights) = 0;
397 virtual void set(
const openvdb::Coord& ijk, GA_Offset offset) = 0;
400 virtual std::string&
name() = 0;
415 template <
class VDBGr
idType>
423 const GA_Attribute* attribute,
424 const GA_AIFTuple* tupleAIF,
425 const int tupleIndex,
426 const bool isVector =
false);
428 void set(
const openvdb::Coord& ijk,
const GA_Offset (&offsets)[3],
429 const openvdb::Vec3d& weights)
override;
431 void set(
const openvdb::Coord& ijk, GA_Offset offset)
override;
434 std::string&
name()
override {
return mName; }
443 typename VDBGridType::Accessor mAccessor;
445 const GA_Attribute* mAttribute;
446 const GA_AIFTuple* mTupleAIF;
447 const int mTupleIndex;
452 template <
class VDBGr
idType>
461 template <
class VDBGr
idType>
464 const GA_Attribute* attribute,
465 const GA_AIFTuple* tupleAIF,
466 const int tupleIndex,
467 const bool isVector):
469 mAccessor(
openvdb::GridBase::grid<VDBGridType>(mGrid)->getAccessor()),
470 mAttribute(attribute),
472 mTupleIndex(tupleIndex)
474 std::ostringstream
name;
475 name << mAttribute->getName();
477 const int tupleSize = mTupleAIF->getTupleSize(mAttribute);
479 if(!isVector && tupleSize != 1) {
480 name <<
"_" << mTupleIndex;
487 template <
class VDBGr
idType>
490 const GA_Offset (&offsets)[3],
const openvdb::Vec3d& weights)
493 mAttribute, mTupleAIF, offsets[0], mTupleIndex);
496 mAttribute, mTupleAIF, offsets[1], mTupleIndex);
499 mAttribute, mTupleAIF, offsets[2], mTupleIndex);
501 mAccessor.setValue(ijk, combine<ValueType>(v0, v1, v2, weights));
504 template <
class VDBGr
idType>
508 mAccessor.setValue(ijk,
509 evalAttr<ValueType>(mAttribute, mTupleAIF, offset, mTupleIndex));
512 template <
class VDBGr
idType>
529 using IterRange = openvdb::tree::IteratorRange<openvdb::Int32Tree::LeafCIter>;
537 const openvdb::math::Transform& transform,
538 const GU_Detail& meshGdp);
547 inline void runParallel();
548 inline void runSerial();
550 inline void operator()(
IterRange &range)
const;
556 const openvdb::math::Transform& mTransform;
558 const GA_Detail &mMeshGdp;
567 const openvdb::math::Transform& transform,
568 const GU_Detail& meshGdp):
569 mPointAttributes(pointAttributes),
570 mVertexAttributes(vertexAttributes),
571 mPrimitiveAttributes(primitiveAttributes),
572 mClosestPrimGrid(closestPrimGrid),
573 mTransform(transform),
580 mPointAttributes(other.mPointAttributes.size()),
581 mVertexAttributes(other.mVertexAttributes.size()),
582 mPrimitiveAttributes(other.mPrimitiveAttributes.size()),
583 mClosestPrimGrid(other.mClosestPrimGrid),
584 mTransform(other.mTransform),
585 mMeshGdp(other.mMeshGdp)
590 for (
size_t i = 0, N = other.mPointAttributes.size(); i < N; ++i) {
591 mPointAttributes[i] = other.mPointAttributes[i]->copy();
594 for (
size_t i = 0, N = other.mVertexAttributes.size(); i < N; ++i) {
595 mVertexAttributes[i] = other.mVertexAttributes[i]->copy();
598 for (
size_t i = 0, N = other.mPrimitiveAttributes.size(); i < N; ++i) {
599 mPrimitiveAttributes[i] = other.mPrimitiveAttributes[i]->copy();
608 tbb::parallel_for(range, *
this);
626 const bool ptnAttrTransfer = mPointAttributes.size() > 0;
627 const bool vtxAttrTransfer = mVertexAttributes.size() > 0;
629 GA_Offset vtxOffsetList[4], ptnOffsetList[4], vtxOffsets[3], ptnOffsets[3], prmOffset;
630 openvdb::Vec3d ptnList[4], xyz,
cpt, cpt2, uvw, uvw2;
632 for ( ; range; ++range) {
633 iter = range.iterator()->beginValueOn();
634 for ( ; iter; ++iter) {
638 const GA_Index prmIndex = iter.
getValue();
639 prmOffset = mMeshGdp.primitiveOffset(prmIndex);
642 for (
size_t i = 0, N = mPrimitiveAttributes.size(); i < N; ++i) {
643 mPrimitiveAttributes[i]->set(ijk, prmOffset);
646 if (!ptnAttrTransfer && !vtxAttrTransfer)
continue;
649 const GA_Primitive * primRef = mMeshGdp.getPrimitiveList().get(prmOffset);
651 const GA_Size vtxn = primRef->getVertexCount();
654 for (GA_Size vtx = 0; vtx < vtxn; ++vtx) {
655 const GA_Offset vtxoff = primRef->getVertexOffset(vtx);
656 ptnOffsetList[vtx] = mMeshGdp.vertexPoint(vtxoff);
657 vtxOffsetList[vtx] = vtxoff;
659 UT_Vector3 p = mMeshGdp.getPos3(ptnOffsetList[vtx]);
660 ptnList[vtx][0] = double(p[0]);
661 ptnList[vtx][1] = double(p[1]);
662 ptnList[vtx][2] = double(p[2]);
665 xyz = mTransform.indexToWorld(ijk);
670 ptnList[0], ptnList[2], ptnList[1], xyz, uvw);
672 vtxOffsets[0] = vtxOffsetList[0];
673 ptnOffsets[0] = ptnOffsetList[0];
674 vtxOffsets[1] = vtxOffsetList[2];
675 ptnOffsets[1] = ptnOffsetList[2];
676 vtxOffsets[2] = vtxOffsetList[1];
677 ptnOffsets[2] = ptnOffsetList[1];
681 ptnList[0], ptnList[3], ptnList[2], xyz, uvw2);
683 if ((cpt2 - xyz).lengthSqr() < (cpt - xyz).lengthSqr()) {
685 vtxOffsets[1] = vtxOffsetList[3];
686 ptnOffsets[1] = ptnOffsetList[3];
687 vtxOffsets[2] = vtxOffsetList[2];
688 ptnOffsets[2] = ptnOffsetList[2];
693 for (
size_t i = 0, N = mVertexAttributes.size(); i < N; ++i) {
694 mVertexAttributes[i]->set(ijk, vtxOffsets, uvw);
698 for (
size_t i = 0, N = mPointAttributes.size(); i < N; ++i) {
699 mPointAttributes[i]->set(ijk, ptnOffsets, uvw);
716 using IterRange = openvdb::tree::IteratorRange<openvdb::Int32Tree::LeafCIter>;
721 const GU_Detail& ptGeop);
736 const GA_Detail &mPtGeo;
743 const GU_Detail& ptGeop):
744 mPointAttributes(pointAttributes),
745 mClosestPtnIdxGrid(closestPtnIdxGrid),
752 mPointAttributes(other.mPointAttributes.size()),
753 mClosestPtnIdxGrid(other.mClosestPtnIdxGrid),
759 for (
size_t i = 0, N = other.mPointAttributes.size(); i < N; ++i) {
760 mPointAttributes[i] = other.mPointAttributes[i]->copy();
769 tbb::parallel_for(range, *
this);
786 for ( ; range; ++range) {
787 iter = range.iterator()->beginValueOn();
788 for ( ; iter; ++iter) {
792 const GA_Index pointIndex = iter.
getValue();
793 const GA_Offset pointOffset = mPtGeo.pointOffset(pointIndex);
796 for (
size_t i = 0, N = mPointAttributes.size(); i < N; ++i) {
797 mPointAttributes[i]->set(ijk, pointOffset);
811 using Ptr = std::shared_ptr<AttributeCopyBase>;
814 virtual void copy(GA_Offset , GA_Offset ) = 0;
815 virtual void copy(GA_Offset&, GA_Offset&, GA_Offset&, GA_Offset ,
816 const openvdb::Vec3d& ) = 0;
822 template<
class ValueType>
827 : mSourceAttr(sourceAttr)
828 , mTargetAttr(targetAttr)
829 , mAIFTuple(*mSourceAttr.getAIFTuple())
830 , mTupleSize(mAIFTuple.getTupleSize(&mSourceAttr))
834 void copy(GA_Offset source, GA_Offset target)
override 837 for (
int i = 0; i < mTupleSize; ++i) {
838 mAIFTuple.get(&mSourceAttr, source, data, i);
839 mAIFTuple.set(&mTargetAttr, target, data, i);
843 void copy(GA_Offset& v0, GA_Offset& v1, GA_Offset& v2, GA_Offset target,
844 const openvdb::Vec3d& uvw)
override 846 doCopy<ValueType>(v0, v1, v2, target, uvw);
852 doCopy(GA_Offset& v0, GA_Offset& v1, GA_Offset& v2, GA_Offset target,
const openvdb::Vec3d& uvw)
854 GA_Offset source = v0;
861 if (uvw[2] < min) source = v2;
865 for (
int i = 0; i < mTupleSize; ++i) {
866 mAIFTuple.get(&mSourceAttr, source, data, i);
867 mAIFTuple.set(&mTargetAttr, target, data, i);
871 template <
typename T>
873 doCopy(GA_Offset& v0, GA_Offset& v1, GA_Offset& v2, GA_Offset target,
const openvdb::Vec3d& uvw)
876 for (
int i = 0; i < mTupleSize; ++i) {
877 mAIFTuple.get(&mSourceAttr, v0, a, i);
878 mAIFTuple.get(&mSourceAttr, v1, b, i);
879 mAIFTuple.get(&mSourceAttr, v2, c, i);
880 mAIFTuple.set(&mTargetAttr, target, a*uvw[0] + b*uvw[1] + c*uvw[2], i);
885 const GA_Attribute& mSourceAttr;
886 GA_Attribute& mTargetAttr;
887 const GA_AIFTuple& mAIFTuple;
896 : mSourceAttr(sourceAttr)
897 , mTargetAttr(targetAttr)
898 , mAIF(*mSourceAttr.getAIFSharedStringTuple())
899 , mTupleSize(mAIF.getTupleSize(&mSourceAttr))
903 void copy(GA_Offset source, GA_Offset target)
override 905 for (
int i = 0; i < mTupleSize; ++i) {
906 mAIF.setString(&mTargetAttr, target, mAIF.getString(&mSourceAttr, source, i), i);
910 void copy(GA_Offset& v0, GA_Offset& v1, GA_Offset& v2, GA_Offset target,
911 const openvdb::Vec3d& uvw)
override 913 GA_Offset source = v0;
920 if (uvw[2] < min) source = v2;
922 for (
int i = 0; i < mTupleSize; ++i) {
923 mAIF.setString(&mTargetAttr, target, mAIF.getString(&mSourceAttr, source, i), i);
930 const GA_AIFSharedStringTuple&
mAIF;
941 const GA_AIFTuple * aifTuple = sourceAttr.getAIFTuple();
945 const GA_Storage sourceStorage = aifTuple->getStorage(&sourceAttr);
946 const GA_Storage targetStorage = aifTuple->getStorage(&targetAttr);
948 const int sourceTupleSize = aifTuple->getTupleSize(&sourceAttr);
949 const int targetTupleSize = aifTuple->getTupleSize(&targetAttr);
951 if (sourceStorage == targetStorage && sourceTupleSize == targetTupleSize) {
952 switch (sourceStorage)
963 case GA_STORE_REAL16:
964 case GA_STORE_REAL32:
968 case GA_STORE_REAL64:
977 const GA_AIFSharedStringTuple * aifString = sourceAttr.getAIFSharedStringTuple();
992 const GU_Detail& geo,
const std::set<GA_Index>& primitives,
const openvdb::Vec3d& p,
993 GA_Offset& vert0, GA_Offset& vert1, GA_Offset& vert2, openvdb::Vec3d& uvw)
995 std::set<GA_Index>::const_iterator it = primitives.begin();
997 GA_Offset primOffset = GA_INVALID_OFFSET;
998 const GA_Primitive * primRef =
nullptr;
1001 openvdb::Vec3d a, b, c, d, tmpUVW;
1002 UT_Vector3 tmpPoint;
1004 for (; it != primitives.end(); ++it) {
1006 const GA_Offset offset = geo.primitiveOffset(*it);
1007 primRef = geo.getPrimitiveList().get(offset);
1009 const GA_Size vertexCount = primRef->getVertexCount();
1012 if (vertexCount == 3 || vertexCount == 4) {
1014 tmpPoint = geo.getPos3(primRef->getPointOffset(0));
1015 a[0] = tmpPoint.x();
1016 a[1] = tmpPoint.y();
1017 a[2] = tmpPoint.z();
1019 tmpPoint = geo.getPos3(primRef->getPointOffset(1));
1020 b[0] = tmpPoint.x();
1021 b[1] = tmpPoint.y();
1022 b[2] = tmpPoint.z();
1024 tmpPoint = geo.getPos3(primRef->getPointOffset(2));
1025 c[0] = tmpPoint.x();
1026 c[1] = tmpPoint.y();
1027 c[2] = tmpPoint.z();
1032 if (tmpDist < minDist) {
1034 primOffset = offset;
1036 vert0 = primRef->getVertexOffset(0);
1037 vert1 = primRef->getVertexOffset(2);
1038 vert2 = primRef->getVertexOffset(1);
1041 if (vertexCount == 4) {
1042 tmpPoint = geo.getPos3(primRef->getPointOffset(3));
1043 d[0] = tmpPoint.x();
1044 d[1] = tmpPoint.y();
1045 d[2] = tmpPoint.z();
1048 a, d, c, p, tmpUVW)).lengthSqr();
1049 if (tmpDist < minDist) {
1051 primOffset = offset;
1053 vert0 = primRef->getVertexOffset(0);
1054 vert1 = primRef->getVertexOffset(3);
1055 vert2 = primRef->getVertexOffset(2);
1069 const GU_Detail& geo, std::vector<GA_Index>& primitives,
const openvdb::Vec3d& p,
1070 GA_Offset& vert0, GA_Offset& vert1, GA_Offset& vert2, openvdb::Vec3d& uvw)
1072 GA_Offset primOffset = GA_INVALID_OFFSET;
1073 const GA_Primitive * primRef =
nullptr;
1076 openvdb::Vec3d a, b, c, d, tmpUVW;
1077 UT_Vector3 tmpPoint;
1079 std::sort(primitives.begin(), primitives.end());
1081 GA_Index lastPrim = -1;
1082 for (
size_t n = 0, N = primitives.size(); n < N; ++n) {
1083 if (primitives[n] == lastPrim)
continue;
1084 lastPrim = primitives[n];
1086 const GA_Offset offset = geo.primitiveOffset(lastPrim);
1087 primRef = geo.getPrimitiveList().get(offset);
1089 const GA_Size vertexCount = primRef->getVertexCount();
1092 if (vertexCount == 3 || vertexCount == 4) {
1094 tmpPoint = geo.getPos3(primRef->getPointOffset(0));
1095 a[0] = tmpPoint.x();
1096 a[1] = tmpPoint.y();
1097 a[2] = tmpPoint.z();
1099 tmpPoint = geo.getPos3(primRef->getPointOffset(1));
1100 b[0] = tmpPoint.x();
1101 b[1] = tmpPoint.y();
1102 b[2] = tmpPoint.z();
1104 tmpPoint = geo.getPos3(primRef->getPointOffset(2));
1105 c[0] = tmpPoint.x();
1106 c[1] = tmpPoint.y();
1107 c[2] = tmpPoint.z();
1112 if (tmpDist < minDist) {
1114 primOffset = offset;
1116 vert0 = primRef->getVertexOffset(0);
1117 vert1 = primRef->getVertexOffset(2);
1118 vert2 = primRef->getVertexOffset(1);
1121 if (vertexCount == 4) {
1122 tmpPoint = geo.getPos3(primRef->getPointOffset(3));
1123 d[0] = tmpPoint.x();
1124 d[1] = tmpPoint.y();
1125 d[2] = tmpPoint.z();
1128 a, d, c, p, tmpUVW)).lengthSqr();
1129 if (tmpDist < minDist) {
1131 primOffset = offset;
1133 vert0 = primRef->getVertexOffset(0);
1134 vert1 = primRef->getVertexOffset(3);
1135 vert2 = primRef->getVertexOffset(2);
1149 template<
class Gr
idType>
1158 const GU_Detail& sourceGeo,
1159 GU_Detail& targetGeo,
1163 : mSourceGeo(sourceGeo)
1164 , mTargetGeo(targetGeo)
1165 , mIndexGrid(indexGrid)
1166 , mPrimAttributes(primAttributes)
1167 , mVertAttributes(vertAttributes)
1171 inline void operator()(
const GA_SplittableRange&)
const;
1174 inline void copyPrimAttrs(
const GA_Primitive&,
const UT_Vector3&,
IndexAccT&)
const;
1176 template<
typename PrimT>
1177 inline void copyVertAttrs(
const PrimT&,
const UT_Vector3&,
IndexAccT&)
const;
1179 const GU_Detail& mSourceGeo;
1180 GU_Detail& mTargetGeo;
1187 template<
class Gr
idType>
1191 if (mPrimAttributes.empty() && mVertAttributes.empty())
return;
1193 auto polyIdxAcc = mIndexGrid.getConstAccessor();
1195 for (GA_PageIterator pageIt = range.beginPages(); !pageIt.atEnd(); ++pageIt) {
1196 auto start = GA_Offset(), end = GA_Offset();
1197 for (GA_Iterator blockIt(pageIt.begin()); blockIt.blockAdvance(start, end); ) {
1198 for (
auto targetOffset = start; targetOffset < end; ++targetOffset) {
1199 const auto* target = mTargetGeo.getPrimitiveList().get(targetOffset);
1200 if (!target)
continue;
1202 const auto targetN = mTargetGeo.getGEOPrimitive(targetOffset)->computeNormal();
1204 if (!mPrimAttributes.empty()) {
1206 copyPrimAttrs(*target, targetN, polyIdxAcc);
1209 if (!mVertAttributes.empty()) {
1210 if (target->getTypeId() != GA_PRIMPOLYSOUP) {
1211 copyVertAttrs(*target, targetN, polyIdxAcc);
1213 if (
const auto* soup = UTverify_cast<const GEO_PrimPolySoup*>(target)) {
1215 using SizeRange = UT_BlockedRange<GA_Size>;
1216 const auto processPolyRange = [&](
const SizeRange& range) {
1217 auto threadLocalPolyIdxAcc = mIndexGrid.getConstAccessor();
1218 for (GEO_PrimPolySoup::PolygonIterator it(*soup, range.begin());
1219 !it.atEnd() && (it.polygon() < range.end()); ++it)
1221 copyVertAttrs(it, it.computeNormal(), threadLocalPolyIdxAcc);
1224 UTparallelFor(
SizeRange(0, soup->getPolygonCount()), processPolyRange);
1239 template<
class Gr
idType>
1242 const GA_Primitive& targetPrim,
1243 const UT_Vector3& targetNormal,
1246 const auto& transform = mIndexGrid.transform();
1248 UT_Vector3 sourceN, targetN = targetNormal;
1249 const bool isPolySoup = (targetPrim.getTypeId() == GA_PRIMPOLYSOUP);
1252 openvdb::Vec3d pos(0, 0, 0);
1253 int count =
static_cast<int>(targetPrim.getVertexCount());
1254 for (
int vtx = 0; vtx < count; ++vtx) {
1255 pos += UTvdbConvert(targetPrim.getPos3(vtx));
1257 if (count > 1) pos /= double(count);
1260 const auto coord = openvdb::Coord::floor(transform.worldToIndex(pos));
1262 std::vector<GA_Index> primitives, similarPrimitives;
1266 primitives.reserve(8);
1267 similarPrimitives.reserve(8);
1268 for (
int d = 0; d < 8; ++d) {
1269 ijk[0] = coord[0] + (((d & 0x02) >> 1) ^ (d & 0x01));
1270 ijk[1] = coord[1] + ((d & 0x02) >> 1);
1271 ijk[2] = coord[2] + ((d & 0x04) >> 2);
1273 if (polyIdxAcc.probeValue(ijk, primIndex) &&
1276 GA_Offset tmpOffset = mSourceGeo.primitiveOffset(primIndex);
1277 sourceN = mSourceGeo.getGEOPrimitive(tmpOffset)->computeNormal();
1282 if (isPolySoup || sourceN.dot(targetN) > 0.5) {
1283 similarPrimitives.push_back(primIndex);
1285 primitives.push_back(primIndex);
1290 if (!primitives.empty() || !similarPrimitives.empty()) {
1291 GA_Offset source, v0, v1, v2;
1293 if (!similarPrimitives.empty()) {
1295 mSourceGeo, similarPrimitives, pos, v0, v1, v2, uvw);
1298 mSourceGeo, primitives, pos, v0, v1, v2, uvw);
1302 const auto targetOffset = targetPrim.getMapOffset();
1303 for (
size_t n = 0, N = mPrimAttributes.size(); n < N; ++n) {
1304 mPrimAttributes[n]->copy(source, targetOffset);
1315 template<
typename Gr
idType>
1316 template<
typename PrimT>
1319 const PrimT& targetPrim,
1320 const UT_Vector3& targetNormal,
1323 const auto& transform = mIndexGrid.transform();
1325 openvdb::Vec3d pos, uvw;
1327 UT_Vector3 sourceNormal;
1328 std::vector<GA_Index> primitives, similarPrimitives;
1330 primitives.reserve(8);
1331 similarPrimitives.reserve(8);
1332 for (GA_Size vtx = 0, vtxN = targetPrim.getVertexCount(); vtx < vtxN; ++vtx) {
1333 pos = UTvdbConvert(targetPrim.getPos3(vtx));
1334 const auto coord = openvdb::Coord::floor(transform.worldToIndex(pos));
1337 similarPrimitives.clear();
1339 for (
int d = 0; d < 8; ++d) {
1340 ijk[0] = coord[0] + (((d & 0x02) >> 1) ^ (d & 0x01));
1341 ijk[1] = coord[1] + ((d & 0x02) >> 1);
1342 ijk[2] = coord[2] + ((d & 0x04) >> 2);
1344 if (polyIdxAcc.probeValue(ijk, primIndex) &&
1347 GA_Offset tmpOffset = mSourceGeo.primitiveOffset(primIndex);
1348 sourceNormal = mSourceGeo.getGEOPrimitive(tmpOffset)->computeNormal();
1349 if (sourceNormal.dot(targetNormal) > 0.5) {
1350 primitives.push_back(primIndex);
1355 if (!primitives.empty() || !similarPrimitives.empty()) {
1356 GA_Offset v0, v1, v2;
1357 if (!similarPrimitives.empty()) {
1363 for (
size_t n = 0, N = mVertAttributes.size(); n < N; ++n) {
1364 mVertAttributes[n]->copy(v0, v1, v2, targetPrim.getVertexOffset(vtx), uvw);
1374 template<
class Gr
idType>
1379 const GU_Detail& sourceGeo, GU_Detail& targetGeo,
const GridType& indexGrid,
1380 std::vector<AttributeCopyBase::Ptr>& pointAttributes,
1381 const GA_PrimitiveGroup* surfacePrims =
nullptr);
1383 void operator()(
const GA_SplittableRange&)
const;
1385 const GU_Detail& mSourceGeo;
1386 GU_Detail& mTargetGeo;
1388 std::vector<AttributeCopyBase::Ptr>& mPointAttributes;
1389 const GA_PrimitiveGroup* mSurfacePrims;
1392 template<
class Gr
idType>
1394 const GU_Detail& sourceGeo, GU_Detail& targetGeo,
const GridType& indexGrid,
1395 std::vector<AttributeCopyBase::Ptr>& pointAttributes,
1396 const GA_PrimitiveGroup* surfacePrims)
1397 : mSourceGeo(sourceGeo)
1398 , mTargetGeo(targetGeo)
1399 , mIndexGrid(indexGrid)
1400 , mPointAttributes(pointAttributes)
1401 , mSurfacePrims(surfacePrims)
1405 template<
class Gr
idType>
1409 using IndexT =
typename GridType::ValueType;
1411 GA_Offset start, end, vtxOffset, primOffset, target, v0, v1, v2;
1413 typename GridType::ConstAccessor polyIdxAcc = mIndexGrid.getConstAccessor();
1414 const openvdb::math::Transform& transform = mIndexGrid.transform();
1415 openvdb::Vec3d pos, indexPos, uvw;
1416 std::vector<GA_Index> primitives;
1417 openvdb::Coord ijk, coord;
1419 primitives.reserve(8);
1420 for (GA_PageIterator pageIt = range.beginPages(); !pageIt.atEnd(); ++pageIt) {
1421 for (GA_Iterator blockIt(pageIt.begin()); blockIt.blockAdvance(start, end); ) {
1422 for (target = start; target < end; ++target) {
1425 vtxOffset = mTargetGeo.pointVertex(target);
1428 if (mSurfacePrims) {
1429 bool surfacePrim =
false;
1431 while (GAisValid(vtxOffset)) {
1433 primOffset = mTargetGeo.vertexPrimitive(vtxOffset);
1435 if (mSurfacePrims->containsIndex(mTargetGeo.primitiveIndex(primOffset))) {
1440 vtxOffset = mTargetGeo.vertexToNextVertex(vtxOffset);
1443 if (!surfacePrim)
continue;
1446 const UT_Vector3 p = mTargetGeo.getPos3(target);
1451 indexPos = transform.worldToIndex(pos);
1452 coord[0] = int(std::floor(indexPos[0]));
1453 coord[1] = int(std::floor(indexPos[1]));
1454 coord[2] = int(std::floor(indexPos[2]));
1459 for (
int d = 0; d < 8; ++d) {
1460 ijk[0] = coord[0] + (((d & 0x02) >> 1) ^ (d & 0x01));
1461 ijk[1] = coord[1] + ((d & 0x02) >> 1);
1462 ijk[2] = coord[2] + ((d & 0x04) >> 2);
1464 if (polyIdxAcc.probeValue(ijk, primIndex) &&
1466 primitives.push_back(primIndex);
1470 if (!primitives.empty()) {
1473 v0 = mSourceGeo.vertexPoint(v0);
1474 v1 = mSourceGeo.vertexPoint(v1);
1475 v2 = mSourceGeo.vertexPoint(v2);
1477 for (
size_t n = 0, N = mPointAttributes.size(); n < N; ++n) {
1478 mPointAttributes[n]->copy(v0, v1, v2, target, uvw);
1490 template<
class Gr
idType>
1493 const GU_Detail& sourceGeo,
1494 GU_Detail& targetGeo,
1496 openvdb::util::NullInterrupter& boss,
1497 const GA_PrimitiveGroup* primitives =
nullptr)
1500 GA_AttributeDict::iterator it = sourceGeo.primitiveAttribs().begin(GA_SCOPE_PUBLIC);
1502 if (indexGrid.activeVoxelCount() == 0)
return;
1504 std::vector<AttributeCopyBase::Ptr> primAttributeList;
1507 for (; !it.atEnd(); ++it) {
1508 const GA_Attribute* sourceAttr = it.attrib();
1509 if (
nullptr == targetGeo.findPrimitiveAttribute(it.name())) {
1510 targetGeo.addPrimAttrib(sourceAttr);
1512 GA_Attribute* targetAttr = targetGeo.findPrimitiveAttribute(it.name());
1514 if (sourceAttr && targetAttr) {
1516 if(att) primAttributeList.push_back(att);
1520 if (boss.wasInterrupted())
return;
1522 std::vector<AttributeCopyBase::Ptr> vertAttributeList;
1524 it = sourceGeo.vertexAttribs().begin(GA_SCOPE_PUBLIC);
1527 for (; !it.atEnd(); ++it) {
1528 const GA_Attribute* sourceAttr = it.attrib();
1529 if (
nullptr == targetGeo.findVertexAttribute(it.name())) {
1530 targetGeo.addVertexAttrib(sourceAttr);
1532 GA_Attribute* targetAttr = targetGeo.findVertexAttribute(it.name());
1534 if (sourceAttr && targetAttr) {
1535 targetAttr->hardenAllPages();
1537 if(att) vertAttributeList.push_back(att);
1541 if (!boss.wasInterrupted() && (!primAttributeList.empty() || !vertAttributeList.empty())) {
1543 UTparallelFor(GA_SplittableRange(targetGeo.getPrimitiveRange(primitives)),
1545 primAttributeList, vertAttributeList));
1548 if (!boss.wasInterrupted()) {
1549 std::vector<AttributeCopyBase::Ptr> pointAttributeList;
1550 it = sourceGeo.pointAttribs().begin(GA_SCOPE_PUBLIC);
1553 for (; !it.atEnd(); ++it) {
1554 if (std::string(it.name()) ==
"P")
continue;
1556 const GA_Attribute* sourceAttr = it.attrib();
1557 if (
nullptr == targetGeo.findPointAttribute(it.name())) {
1558 targetGeo.addPointAttrib(sourceAttr);
1560 GA_Attribute* targetAttr = targetGeo.findPointAttribute(it.name());
1562 if (sourceAttr && targetAttr) {
1564 if(att) pointAttributeList.push_back(att);
1568 if (!boss.wasInterrupted() && !pointAttributeList.empty()) {
1569 UTparallelFor(GA_SplittableRange(targetGeo.getPointRange()),
1571 pointAttributeList, primitives));
1577 template<
class Gr
idType>
1580 const GU_Detail& sourceGeo,
1581 GU_Detail& targetGeo,
1584 const GA_PrimitiveGroup* primitives =
nullptr)
1591 #endif // OPENVDB_HOUDINI_ATTRIBUTE_TRANSFER_UTIL_HAS_BEEN_INCLUDED virtual openvdb::GridBase::Ptr & grid()=0
Definition: AttributeTransferUtil.h:416
void copy(GA_Offset source, GA_Offset target) override
Definition: AttributeTransferUtil.h:903
const GA_AIFSharedStringTuple & mAIF
Definition: AttributeTransferUtil.h:930
OPENVDB_API const Index32 INVALID_IDX
void set(const openvdb::Coord &ijk, const GA_Offset(&offsets)[3], const openvdb::Vec3d &weights) override
Definition: AttributeTransferUtil.h:489
AttributeCopyBase()
Definition: AttributeTransferUtil.h:818
void copy(GA_Offset &v0, GA_Offset &v1, GA_Offset &v2, GA_Offset target, const openvdb::Vec3d &uvw) override
Definition: AttributeTransferUtil.h:910
AttributeDetailBase::Ptr copy() override
Definition: AttributeTransferUtil.h:514
std::shared_ptr< AttributeDetailBase > Ptr
Definition: AttributeTransferUtil.h:387
virtual ~AttributeDetailBase()=default
ValueType evalAttr(const GA_Attribute *atr, const GA_AIFTuple *aif, GA_Offset off, int idx)
Definition: AttributeTransferUtil.h:42
void operator()(const GA_SplittableRange &) const
Definition: AttributeTransferUtil.h:1407
SharedPtr< GridBase > Ptr
Definition: Grid.h:80
GA_Offset findClosestPrimitiveToPoint(const GU_Detail &geo, const std::set< GA_Index > &primitives, const openvdb::Vec3d &p, GA_Offset &vert0, GA_Offset &vert1, GA_Offset &vert2, openvdb::Vec3d &uvw)
Definition: AttributeTransferUtil.h:991
AttributeDetail()
Definition: AttributeTransferUtil.h:453
Vec3< int32_t > Vec3i
Definition: Vec3.h:665
openvdb::tree::IteratorRange< openvdb::Int32Tree::LeafCIter > IterRange
Definition: AttributeTransferUtil.h:716
TransferPrimitiveAttributesOp(const GU_Detail &sourceGeo, GU_Detail &targetGeo, const GridType &indexGrid, AttrCopyPtrVec &primAttributes, AttrCopyPtrVec &vertAttributes)
Definition: AttributeTransferUtil.h:1157
void runParallel()
Main calls.
Definition: AttributeTransferUtil.h:766
~MeshAttrTransfer()
Definition: AttributeTransferUtil.h:544
void copy(GA_Offset source, GA_Offset target) override
Definition: AttributeTransferUtil.h:834
void operator()(IterRange &range) const
Definition: AttributeTransferUtil.h:781
openvdb::util::NullInterrupter & interrupter()
Return a reference to the base class of the stored interrupter.
Definition: Utils.h:227
virtual ~AttributeCopyBase()
Definition: AttributeTransferUtil.h:813
Definition: AttributeTransferUtil.h:1150
int mTupleSize
Definition: AttributeTransferUtil.h:931
Utility classes and functions for OpenVDB plugins.
typename VDBGridType::ValueType ValueType
Definition: AttributeTransferUtil.h:419
std::vector< AttributeCopyBase::Ptr > AttrCopyPtrVec
Definition: AttributeTransferUtil.h:1155
GA_Attribute & mTargetAttr
Definition: AttributeTransferUtil.h:929
const GA_Attribute & mSourceAttr
Definition: AttributeTransferUtil.h:928
int64_t Int64
Definition: Types.h:57
MeshAttrTransfer(AttributeDetailList &pointAttributes, AttributeDetailList &vertexAttributes, AttributeDetailList &primitiveAttributes, const openvdb::Int32Grid &closestPrimGrid, const openvdb::math::Transform &transform, const GU_Detail &meshGdp)
Definition: AttributeTransferUtil.h:562
float evalAttr< float >(const GA_Attribute *atr, const GA_AIFTuple *aif, GA_Offset off, int idx)
Definition: AttributeTransferUtil.h:51
Definition: AttributeTransferUtil.h:526
std::shared_ptr< AttributeCopyBase > Ptr
Definition: AttributeTransferUtil.h:811
OPENVDB_API Vec3d closestPointOnTriangleToPoint(const Vec3d &a, const Vec3d &b, const Vec3d &c, const Vec3d &p, Vec3d &uvw)
Closest Point on Triangle to Point. Given a triangle abc and a point p, return the point on abc close...
StrAttributeCopy(const GA_Attribute &sourceAttr, GA_Attribute &targetAttr)
Definition: AttributeTransferUtil.h:895
std::vector< AttributeDetailBase::Ptr > AttributeDetailList
Definition: AttributeTransferUtil.h:409
TreeType & tree()
Return a reference to this grid's tree, which might be shared with other grids.
Definition: Grid.h:917
std::string & name() override
Definition: AttributeTransferUtil.h:434
PointAttrTransfer(AttributeDetailList &pointAttributes, const openvdb::Int32Grid &closestPtnIdxGrid, const GU_Detail &ptGeop)
Definition: AttributeTransferUtil.h:740
float evalAttrDefault< float >(const GA_Defaults &defaults, int)
Definition: AttributeTransferUtil.h:215
Definition: AttributeTransferUtil.h:823
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:616
typename GridType::ConstAccessor IndexAccT
Definition: AttributeTransferUtil.h:1154
AttributeCopy(const GA_Attribute &sourceAttr, GA_Attribute &targetAttr)
Definition: AttributeTransferUtil.h:826
AttributeDetailBase & operator=(const AttributeDetailBase &)=default
void runSerial()
Definition: AttributeTransferUtil.h:773
Definition: Exceptions.h:13
AttributeDetailBase()
Definition: AttributeTransferUtil.h:405
Definition: AttributeTransferUtil.h:809
ValueT value
Definition: GridBuilder.h:1287
virtual AttributeDetailBase::Ptr copy()=0
const ValueT & getValue() const
Return the tile or voxel value to which this iterator is currently pointing.
Definition: TreeIterator.h:692
Definition: AttributeTransferUtil.h:1375
typename GridType::ValueType IndexT
Definition: AttributeTransferUtil.h:1153
openvdb::tree::IteratorRange< openvdb::Int32Tree::LeafCIter > IterRange
Definition: AttributeTransferUtil.h:529
openvdb::GridBase::Ptr & grid() override
Definition: AttributeTransferUtil.h:433
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:28
Definition: AttributeTransferUtil.h:713
Deprecated wrapper class with the same interface as HoudiniInterrupter, however it does not derive fr...
Definition: Utils.h:208
Definition: AttributeTransferUtil.h:892
Definition: AttributeTransferUtil.h:34
GridType
List of types that are currently supported by NanoVDB.
Definition: NanoVDB.h:216
~PointAttrTransfer()
Definition: AttributeTransferUtil.h:725
void transferPrimitiveAttributes(const GU_Detail &sourceGeo, GU_Detail &targetGeo, GridType &indexGrid, openvdb::util::NullInterrupter &boss, const GA_PrimitiveGroup *primitives=nullptr)
Definition: AttributeTransferUtil.h:1492
Coord getCoord() const
Return the global coordinates of the voxel or tile to which this iterator is currently pointing...
Definition: TreeIterator.h:671
int32_t Int32
Definition: Types.h:56
void copy(GA_Offset &v0, GA_Offset &v1, GA_Offset &v2, GA_Offset target, const openvdb::Vec3d &uvw) override
Definition: AttributeTransferUtil.h:843
Vec3< float > Vec3s
Definition: Vec3.h:667
ValueType evalAttrDefault(const GA_Defaults &defaults, int idx)
Get an OpenVDB-specific value by evaluating GA_Default::get() with appropriate arguments.
Definition: AttributeTransferUtil.h:207
uint32_t Index32
Definition: Types.h:52
virtual std::string & name()=0
void operator()(const GA_SplittableRange &) const
Definition: AttributeTransferUtil.h:1189
AttributeCopyBase::Ptr createAttributeCopier(const GA_Attribute &sourceAttr, GA_Attribute &targetAttr)
Definition: AttributeTransferUtil.h:939
Definition: AttributeTransferUtil.h:384
void runParallel()
Main calls.
Definition: AttributeTransferUtil.h:605
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:141
void runSerial()
Definition: AttributeTransferUtil.h:612
void operator()(IterRange &range) const
Definition: AttributeTransferUtil.h:620
tbb::blocked_range< SizeType > SizeRange
Definition: ConjGradient.h:35
TransferPointAttributesOp(const GU_Detail &sourceGeo, GU_Detail &targetGeo, const GridType &indexGrid, std::vector< AttributeCopyBase::Ptr > &pointAttributes, const GA_PrimitiveGroup *surfacePrims=nullptr)
Definition: AttributeTransferUtil.h:1393