8 #ifndef OPENVDB_HOUDINI_ATTRIBUTE_TRANSFER_UTIL_HAS_BEEN_INCLUDED
9 #define OPENVDB_HOUDINI_ATTRIBUTE_TRANSFER_UTIL_HAS_BEEN_INCLUDED
17 #include <GA/GA_PageIterator.h>
18 #include <GA/GA_SplittableRange.h>
19 #include <GEO/GEO_PrimPolySoup.h>
20 #include <SYS/SYS_Types.h>
29 #include <type_traits>
40 template <
typename ValueType>
inline ValueType
41 evalAttr(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
42 GA_Offset off,
int idx)
45 aif->get(atr, off, value, idx);
46 return ValueType(value);
49 template <>
inline float
51 GA_Offset off,
int idx)
54 aif->get(atr, off, value, idx);
59 evalAttr<openvdb::Int32>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
60 GA_Offset off,
int idx)
63 aif->get(atr, off, value, idx);
68 evalAttr<openvdb::Int64>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
69 GA_Offset off,
int idx)
72 aif->get(atr, off, value, idx);
77 evalAttr<openvdb::Vec3i>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
83 aif->get(atr, off, comp, 0);
86 aif->get(atr, off, comp, 1);
89 aif->get(atr, off, comp, 2);
96 evalAttr<openvdb::Vec3s>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
102 aif->get(atr, off, comp, 0);
103 vec[0] = float(comp);
105 aif->get(atr, off, comp, 1);
106 vec[1] = float(comp);
108 aif->get(atr, off, comp, 2);
109 vec[2] = float(comp);
115 evalAttr<openvdb::Vec3d>(
const GA_Attribute* atr,
const GA_AIFTuple* aif,
121 aif->get(atr, off, comp, 0);
122 vec[0] = double(comp);
124 aif->get(atr, off, comp, 1);
125 vec[1] = double(comp);
127 aif->get(atr, off, comp, 2);
128 vec[2] = double(comp);
139 template <
typename ValueType>
inline ValueType
140 combine(
const ValueType& v0,
const ValueType& v1,
const ValueType& v2,
143 return ValueType(v0 * w[0] + v1 * w[1] + v2 * w[2]);
150 if (w[2] > w[0] && w[2] > w[1])
return v2;
151 if (w[1] > w[0] && w[1] > w[2])
return v1;
159 if (w[2] > w[0] && w[2] > w[1])
return v2;
160 if (w[1] > w[0] && w[1] > w[2])
return v1;
168 if (w[2] > w[0] && w[2] > w[1])
return v2;
169 if (w[1] > w[0] && w[1] > w[2])
return v1;
179 vec[0] = float(v0[0] * w[0] + v1[0] * w[1] + v2[0] * w[2]);
180 vec[1] = float(v0[1] * w[0] + v1[1] * w[1] + v2[1] * w[2]);
181 vec[2] = float(v0[2] * w[0] + v1[2] * w[1] + v2[2] * w[2]);
192 vec[0] = v0[0] * w[0] + v1[0] * w[1] + v2[0] * w[2];
193 vec[1] = v0[1] * w[0] + v1[1] * w[1] + v2[1] * w[2];
194 vec[2] = v0[2] * w[0] + v1[2] * w[1] + v2[2] * w[2];
205 template <
typename ValueType>
inline ValueType
209 defaults.get(idx, value);
210 return ValueType(value);
213 template <>
inline float
217 defaults.get(0, value);
222 evalAttrDefault<openvdb::Int32>(
const GA_Defaults& defaults,
int idx)
225 defaults.get(idx, value);
230 evalAttrDefault<openvdb::Int64>(
const GA_Defaults& defaults,
int idx)
233 defaults.get(idx, value);
238 evalAttrDefault<openvdb::Vec3i>(
const GA_Defaults& defaults,
int)
243 defaults.get(0, value);
246 defaults.get(1, value);
249 defaults.get(2, value);
256 evalAttrDefault<openvdb::Vec3s>(
const GA_Defaults& defaults,
int)
261 defaults.get(0, value);
262 vec[0] = float(value);
264 defaults.get(1, value);
265 vec[1] = float(value);
267 defaults.get(2, value);
268 vec[2] = float(value);
274 evalAttrDefault<openvdb::Vec3d>(
const GA_Defaults& defaults,
int)
279 defaults.get(0, value);
280 vec[0] = double(value);
282 defaults.get(1, value);
283 vec[1] = double(value);
285 defaults.get(2, value);
286 vec[2] = double(value);
291 template <>
inline openvdb::math::Quat<float>
292 evalAttrDefault<openvdb::math::Quat<float>>(
const GA_Defaults& defaults, int)
294 openvdb::math::Quat<float> quat;
297 for (
int i = 0; i < 4; i++) {
298 defaults.get(i, value);
299 quat[i] = float(value);
305 template <>
inline openvdb::math::Quat<double>
306 evalAttrDefault<openvdb::math::Quat<double>>(
const GA_Defaults& defaults, int)
308 openvdb::math::Quat<double> quat;
311 for (
int i = 0; i < 4; i++) {
312 defaults.get(i, value);
313 quat[i] = double(value);
319 template <>
inline openvdb::math::Mat3<float>
320 evalAttrDefault<openvdb::math::Mat3<float>>(
const GA_Defaults& defaults, int)
322 openvdb::math::Mat3<float> mat;
324 float* data = mat.asPointer();
326 for (
int i = 0; i < 9; i++) {
327 defaults.get(i, value);
328 data[i] = float(value);
334 template <>
inline openvdb::math::Mat3<double>
335 evalAttrDefault<openvdb::math::Mat3<double>>(
const GA_Defaults& defaults, int)
337 openvdb::math::Mat3<double> mat;
339 double* data = mat.asPointer();
341 for (
int i = 0; i < 9; i++) {
342 defaults.get(i, value);
343 data[i] = double(value);
349 template <>
inline openvdb::math::Mat4<float>
350 evalAttrDefault<openvdb::math::Mat4<float>>(
const GA_Defaults& defaults, int)
352 openvdb::math::Mat4<float> mat;
354 float* data = mat.asPointer();
356 for (
int i = 0; i < 16; i++) {
357 defaults.get(i, value);
358 data[i] = float(value);
364 template <>
inline openvdb::math::Mat4<double>
365 evalAttrDefault<openvdb::math::Mat4<double>>(
const GA_Defaults& defaults, int)
367 openvdb::math::Mat4<double> mat;
369 double* data = mat.asPointer();
371 for (
int i = 0; i < 16; i++) {
372 defaults.get(i, value);
373 data[i] = double(value);
386 using Ptr = std::shared_ptr<AttributeDetailBase>;
399 virtual std::string&
name() = 0;
414 template <
class VDBGr
idType>
422 const GA_Attribute* attribute,
423 const GA_AIFTuple* tupleAIF,
424 const int tupleIndex,
425 const bool isVector =
false);
433 std::string&
name()
override {
return mName; }
442 typename VDBGridType::Accessor mAccessor;
444 const GA_Attribute* mAttribute;
445 const GA_AIFTuple* mTupleAIF;
446 const int mTupleIndex;
451 template <
class VDBGr
idType>
460 template <
class VDBGr
idType>
463 const GA_Attribute* attribute,
464 const GA_AIFTuple* tupleAIF,
465 const int tupleIndex,
466 const bool isVector):
468 mAccessor(
openvdb::GridBase::grid<VDBGridType>(mGrid)->getAccessor()),
469 mAttribute(attribute),
471 mTupleIndex(tupleIndex)
473 std::ostringstream
name;
474 name << mAttribute->getName();
476 const int tupleSize = mTupleAIF->getTupleSize(mAttribute);
478 if(!isVector && tupleSize != 1) {
479 name <<
"_" << mTupleIndex;
486 template <
class VDBGr
idType>
492 mAttribute, mTupleAIF, offsets[0], mTupleIndex);
495 mAttribute, mTupleAIF, offsets[1], mTupleIndex);
498 mAttribute, mTupleAIF, offsets[2], mTupleIndex);
500 mAccessor.setValue(ijk, combine<ValueType>(v0, v1, v2, weights));
503 template <
class VDBGr
idType>
507 mAccessor.setValue(ijk,
508 evalAttr<ValueType>(mAttribute, mTupleAIF, offset, mTupleIndex));
511 template <
class VDBGr
idType>
528 using IterRange = openvdb::tree::IteratorRange<openvdb::Int32Tree::LeafCIter>;
536 const openvdb::math::Transform& transform,
537 const GU_Detail& meshGdp);
555 const openvdb::math::Transform& mTransform;
557 const GA_Detail &mMeshGdp;
566 const openvdb::math::Transform& transform,
567 const GU_Detail& meshGdp):
568 mPointAttributes(pointAttributes),
569 mVertexAttributes(vertexAttributes),
570 mPrimitiveAttributes(primitiveAttributes),
571 mClosestPrimGrid(closestPrimGrid),
572 mTransform(transform),
579 mPointAttributes(other.mPointAttributes.size()),
580 mVertexAttributes(other.mVertexAttributes.size()),
581 mPrimitiveAttributes(other.mPrimitiveAttributes.size()),
582 mClosestPrimGrid(other.mClosestPrimGrid),
583 mTransform(other.mTransform),
584 mMeshGdp(other.mMeshGdp)
589 for (
size_t i = 0, N = other.mPointAttributes.size(); i < N; ++i) {
590 mPointAttributes[i] = other.mPointAttributes[i]->copy();
593 for (
size_t i = 0, N = other.mVertexAttributes.size(); i < N; ++i) {
594 mVertexAttributes[i] = other.mVertexAttributes[i]->copy();
597 for (
size_t i = 0, N = other.mPrimitiveAttributes.size(); i < N; ++i) {
598 mPrimitiveAttributes[i] = other.mPrimitiveAttributes[i]->copy();
607 tbb::parallel_for(range, *
this);
625 const bool ptnAttrTransfer = mPointAttributes.size() > 0;
626 const bool vtxAttrTransfer = mVertexAttributes.size() > 0;
628 GA_Offset vtxOffsetList[4], ptnOffsetList[4], vtxOffsets[3], ptnOffsets[3], prmOffset;
631 for ( ; range; ++range) {
632 iter = range.iterator()->beginValueOn();
633 for ( ; iter; ++iter) {
637 const GA_Index prmIndex = iter.
getValue();
638 prmOffset = mMeshGdp.primitiveOffset(prmIndex);
641 for (
size_t i = 0, N = mPrimitiveAttributes.size(); i < N; ++i) {
642 mPrimitiveAttributes[i]->set(ijk, prmOffset);
645 if (!ptnAttrTransfer && !vtxAttrTransfer)
continue;
648 const GA_Primitive * primRef = mMeshGdp.getPrimitiveList().get(prmOffset);
650 const GA_Size vtxn = primRef->getVertexCount();
653 for (GA_Size vtx = 0; vtx < vtxn; ++vtx) {
654 const GA_Offset vtxoff = primRef->getVertexOffset(vtx);
655 ptnOffsetList[vtx] = mMeshGdp.vertexPoint(vtxoff);
656 vtxOffsetList[vtx] = vtxoff;
658 UT_Vector3 p = mMeshGdp.getPos3(ptnOffsetList[vtx]);
659 ptnList[vtx][0] = double(p[0]);
660 ptnList[vtx][1] = double(p[1]);
661 ptnList[vtx][2] = double(p[2]);
664 xyz = mTransform.indexToWorld(ijk);
669 ptnList[0], ptnList[2], ptnList[1], xyz, uvw);
671 vtxOffsets[0] = vtxOffsetList[0];
672 ptnOffsets[0] = ptnOffsetList[0];
673 vtxOffsets[1] = vtxOffsetList[2];
674 ptnOffsets[1] = ptnOffsetList[2];
675 vtxOffsets[2] = vtxOffsetList[1];
676 ptnOffsets[2] = ptnOffsetList[1];
680 ptnList[0], ptnList[3], ptnList[2], xyz, uvw2);
682 if ((cpt2 - xyz).lengthSqr() < (
cpt - xyz).lengthSqr()) {
684 vtxOffsets[1] = vtxOffsetList[3];
685 ptnOffsets[1] = ptnOffsetList[3];
686 vtxOffsets[2] = vtxOffsetList[2];
687 ptnOffsets[2] = ptnOffsetList[2];
692 for (
size_t i = 0, N = mVertexAttributes.size(); i < N; ++i) {
693 mVertexAttributes[i]->set(ijk, vtxOffsets, uvw);
697 for (
size_t i = 0, N = mPointAttributes.size(); i < N; ++i) {
698 mPointAttributes[i]->set(ijk, ptnOffsets, uvw);
715 using IterRange = openvdb::tree::IteratorRange<openvdb::Int32Tree::LeafCIter>;
720 const GU_Detail& ptGeop);
735 const GA_Detail &mPtGeo;
742 const GU_Detail& ptGeop):
743 mPointAttributes(pointAttributes),
744 mClosestPtnIdxGrid(closestPtnIdxGrid),
751 mPointAttributes(other.mPointAttributes.size()),
752 mClosestPtnIdxGrid(other.mClosestPtnIdxGrid),
758 for (
size_t i = 0, N = other.mPointAttributes.size(); i < N; ++i) {
759 mPointAttributes[i] = other.mPointAttributes[i]->copy();
768 tbb::parallel_for(range, *
this);
785 for ( ; range; ++range) {
786 iter = range.iterator()->beginValueOn();
787 for ( ; iter; ++iter) {
791 const GA_Index pointIndex = iter.
getValue();
792 const GA_Offset pointOffset = mPtGeo.pointOffset(pointIndex);
795 for (
size_t i = 0, N = mPointAttributes.size(); i < N; ++i) {
796 mPointAttributes[i]->set(ijk, pointOffset);
810 using Ptr = std::shared_ptr<AttributeCopyBase>;
813 virtual void copy(GA_Offset , GA_Offset ) = 0;
814 virtual void copy(GA_Offset&, GA_Offset&, GA_Offset&, GA_Offset ,
821 template<
class ValueType>
826 : mSourceAttr(sourceAttr)
827 , mTargetAttr(targetAttr)
828 , mAIFTuple(*mSourceAttr.getAIFTuple())
829 , mTupleSize(mAIFTuple.getTupleSize(&mSourceAttr))
833 void copy(GA_Offset source, GA_Offset target)
override
836 for (
int i = 0; i < mTupleSize; ++i) {
837 mAIFTuple.get(&mSourceAttr, source, data, i);
838 mAIFTuple.set(&mTargetAttr, target, data, i);
842 void copy(GA_Offset& v0, GA_Offset& v1, GA_Offset& v2, GA_Offset target,
845 doCopy<ValueType>(v0, v1, v2, target, uvw);
850 typename std::enable_if<std::is_integral<T>::value>::type
851 doCopy(GA_Offset& v0, GA_Offset& v1, GA_Offset& v2, GA_Offset target,
const openvdb::Vec3d& uvw)
853 GA_Offset source = v0;
860 if (uvw[2] <
min) source = v2;
864 for (
int i = 0; i < mTupleSize; ++i) {
865 mAIFTuple.get(&mSourceAttr, source, data, i);
866 mAIFTuple.set(&mTargetAttr, target, data, i);
870 template <
typename T>
871 typename std::enable_if<std::is_floating_point<T>::value>::type
872 doCopy(GA_Offset& v0, GA_Offset& v1, GA_Offset& v2, GA_Offset target,
const openvdb::Vec3d& uvw)
875 for (
int i = 0; i < mTupleSize; ++i) {
876 mAIFTuple.get(&mSourceAttr, v0, a, i);
877 mAIFTuple.get(&mSourceAttr, v1, b, i);
878 mAIFTuple.get(&mSourceAttr, v2, c, i);
879 mAIFTuple.set(&mTargetAttr, target, a*uvw[0] + b*uvw[1] + c*uvw[2], i);
884 const GA_Attribute& mSourceAttr;
885 GA_Attribute& mTargetAttr;
886 const GA_AIFTuple& mAIFTuple;
902 void copy(GA_Offset source, GA_Offset target)
override
909 void copy(GA_Offset& v0, GA_Offset& v1, GA_Offset& v2, GA_Offset target,
912 GA_Offset source = v0;
919 if (uvw[2] <
min) source = v2;
929 const GA_AIFSharedStringTuple&
mAIF;
940 const GA_AIFTuple * aifTuple = sourceAttr.getAIFTuple();
944 const GA_Storage sourceStorage = aifTuple->getStorage(&sourceAttr);
945 const GA_Storage targetStorage = aifTuple->getStorage(&targetAttr);
947 const int sourceTupleSize = aifTuple->getTupleSize(&sourceAttr);
948 const int targetTupleSize = aifTuple->getTupleSize(&targetAttr);
950 if (sourceStorage == targetStorage && sourceTupleSize == targetTupleSize) {
951 switch (sourceStorage)
962 case GA_STORE_REAL16:
963 case GA_STORE_REAL32:
967 case GA_STORE_REAL64:
976 const GA_AIFSharedStringTuple * aifString = sourceAttr.getAIFSharedStringTuple();
991 const GU_Detail& geo,
const std::set<GA_Index>& primitives,
const openvdb::Vec3d& p,
992 GA_Offset& vert0, GA_Offset& vert1, GA_Offset& vert2,
openvdb::Vec3d& uvw)
994 std::set<GA_Index>::const_iterator it = primitives.begin();
996 GA_Offset primOffset = GA_INVALID_OFFSET;
997 const GA_Primitive * primRef =
nullptr;
1001 UT_Vector3 tmpPoint;
1003 for (; it != primitives.end(); ++it) {
1005 const GA_Offset offset = geo.primitiveOffset(*it);
1006 primRef = geo.getPrimitiveList().get(offset);
1008 const GA_Size vertexCount = primRef->getVertexCount();
1011 if (vertexCount == 3 || vertexCount == 4) {
1013 tmpPoint = geo.getPos3(primRef->getPointOffset(0));
1014 a[0] = tmpPoint.
x();
1015 a[1] = tmpPoint.y();
1016 a[2] = tmpPoint.z();
1018 tmpPoint = geo.getPos3(primRef->getPointOffset(1));
1019 b[0] = tmpPoint.x();
1020 b[1] = tmpPoint.y();
1021 b[2] = tmpPoint.z();
1023 tmpPoint = geo.getPos3(primRef->getPointOffset(2));
1024 c[0] = tmpPoint.x();
1025 c[1] = tmpPoint.y();
1026 c[2] = tmpPoint.z();
1031 if (tmpDist < minDist) {
1033 primOffset = offset;
1035 vert0 = primRef->getVertexOffset(0);
1036 vert1 = primRef->getVertexOffset(2);
1037 vert2 = primRef->getVertexOffset(1);
1040 if (vertexCount == 4) {
1041 tmpPoint = geo.getPos3(primRef->getPointOffset(3));
1042 d[0] = tmpPoint.x();
1043 d[1] = tmpPoint.y();
1044 d[2] = tmpPoint.z();
1047 a, d, c, p, tmpUVW)).lengthSqr();
1048 if (tmpDist < minDist) {
1050 primOffset = offset;
1052 vert0 = primRef->getVertexOffset(0);
1053 vert1 = primRef->getVertexOffset(3);
1054 vert2 = primRef->getVertexOffset(2);
1068 const GU_Detail& geo, std::vector<GA_Index>& primitives,
const openvdb::Vec3d& p,
1069 GA_Offset& vert0, GA_Offset& vert1, GA_Offset& vert2,
openvdb::Vec3d& uvw)
1071 GA_Offset primOffset = GA_INVALID_OFFSET;
1072 const GA_Primitive * primRef =
nullptr;
1076 UT_Vector3 tmpPoint;
1078 std::sort(primitives.begin(), primitives.end());
1080 GA_Index lastPrim = -1;
1081 for (
size_t n = 0, N = primitives.size(); n < N; ++n) {
1082 if (primitives[n] == lastPrim)
continue;
1083 lastPrim = primitives[n];
1085 const GA_Offset offset = geo.primitiveOffset(lastPrim);
1086 primRef = geo.getPrimitiveList().get(offset);
1088 const GA_Size vertexCount = primRef->getVertexCount();
1091 if (vertexCount == 3 || vertexCount == 4) {
1093 tmpPoint = geo.getPos3(primRef->getPointOffset(0));
1094 a[0] = tmpPoint.x();
1095 a[1] = tmpPoint.y();
1096 a[2] = tmpPoint.z();
1098 tmpPoint = geo.getPos3(primRef->getPointOffset(1));
1099 b[0] = tmpPoint.x();
1100 b[1] = tmpPoint.y();
1101 b[2] = tmpPoint.z();
1103 tmpPoint = geo.getPos3(primRef->getPointOffset(2));
1104 c[0] = tmpPoint.x();
1105 c[1] = tmpPoint.y();
1106 c[2] = tmpPoint.z();
1111 if (tmpDist < minDist) {
1113 primOffset = offset;
1115 vert0 = primRef->getVertexOffset(0);
1116 vert1 = primRef->getVertexOffset(2);
1117 vert2 = primRef->getVertexOffset(1);
1120 if (vertexCount == 4) {
1121 tmpPoint = geo.getPos3(primRef->getPointOffset(3));
1122 d[0] = tmpPoint.x();
1123 d[1] = tmpPoint.y();
1124 d[2] = tmpPoint.z();
1127 a, d, c, p, tmpUVW)).lengthSqr();
1128 if (tmpDist < minDist) {
1130 primOffset = offset;
1132 vert0 = primRef->getVertexOffset(0);
1133 vert1 = primRef->getVertexOffset(3);
1134 vert2 = primRef->getVertexOffset(2);
1148 template<
class Gr
idType>
1157 const GU_Detail& sourceGeo,
1158 GU_Detail& targetGeo,
1159 const GridType& indexGrid,
1162 : mSourceGeo(sourceGeo)
1163 , mTargetGeo(targetGeo)
1164 , mIndexGrid(indexGrid)
1165 , mPrimAttributes(primAttributes)
1166 , mVertAttributes(vertAttributes)
1170 inline void operator()(
const GA_SplittableRange&)
const;
1173 inline void copyPrimAttrs(
const GA_Primitive&,
const UT_Vector3&,
IndexAccT&)
const;
1175 template<
typename PrimT>
1176 inline void copyVertAttrs(
const PrimT&,
const UT_Vector3&,
IndexAccT&)
const;
1178 const GU_Detail& mSourceGeo;
1179 GU_Detail& mTargetGeo;
1180 const GridType& mIndexGrid;
1186 template<
class Gr
idType>
1190 if (mPrimAttributes.empty() && mVertAttributes.empty())
return;
1192 auto polyIdxAcc = mIndexGrid.getConstAccessor();
1194 for (GA_PageIterator pageIt = range.beginPages(); !pageIt.atEnd(); ++pageIt) {
1195 auto start = GA_Offset(), end = GA_Offset();
1196 for (GA_Iterator blockIt(pageIt.begin()); blockIt.blockAdvance(start, end); ) {
1197 for (
auto targetOffset = start; targetOffset < end; ++targetOffset) {
1198 const auto* target = mTargetGeo.getPrimitiveList().get(targetOffset);
1199 if (!target)
continue;
1201 const auto targetN = mTargetGeo.getGEOPrimitive(targetOffset)->computeNormal();
1203 if (!mPrimAttributes.empty()) {
1205 copyPrimAttrs(*target, targetN, polyIdxAcc);
1208 if (!mVertAttributes.empty()) {
1209 if (target->getTypeId() != GA_PRIMPOLYSOUP) {
1210 copyVertAttrs(*target, targetN, polyIdxAcc);
1212 if (
const auto* soup = UTverify_cast<const GEO_PrimPolySoup*>(target)) {
1214 using SizeRange = UT_BlockedRange<GA_Size>;
1215 const auto processPolyRange = [&](
const SizeRange& range) {
1216 auto threadLocalPolyIdxAcc = mIndexGrid.getConstAccessor();
1217 for (GEO_PrimPolySoup::PolygonIterator it(*soup, range.begin());
1218 !it.atEnd() && (it.polygon() < range.end()); ++it)
1220 copyVertAttrs(it, it.computeNormal(), threadLocalPolyIdxAcc);
1223 UTparallelFor(
SizeRange(0, soup->getPolygonCount()), processPolyRange);
1238 template<
class Gr
idType>
1241 const GA_Primitive& targetPrim,
1242 const UT_Vector3& targetNormal,
1243 IndexAccT& polyIdxAcc)
const
1245 const auto& transform = mIndexGrid.transform();
1247 UT_Vector3 sourceN, targetN = targetNormal;
1248 const bool isPolySoup = (targetPrim.getTypeId() == GA_PRIMPOLYSOUP);
1252 int count =
static_cast<int>(targetPrim.getVertexCount());
1253 for (
int vtx = 0; vtx < count; ++vtx) {
1254 pos += UTvdbConvert(targetPrim.getPos3(vtx));
1256 if (count > 1) pos /= double(count);
1261 std::vector<GA_Index> primitives, similarPrimitives;
1265 primitives.reserve(8);
1266 similarPrimitives.reserve(8);
1267 for (
int d = 0; d < 8; ++d) {
1268 ijk[0] = coord[0] + (((d & 0x02) >> 1) ^ (d & 0x01));
1269 ijk[1] = coord[1] + ((d & 0x02) >> 1);
1270 ijk[2] = coord[2] + ((d & 0x04) >> 2);
1272 if (polyIdxAcc.probeValue(ijk, primIndex) &&
1275 GA_Offset tmpOffset = mSourceGeo.primitiveOffset(primIndex);
1276 sourceN = mSourceGeo.getGEOPrimitive(tmpOffset)->computeNormal();
1281 if (isPolySoup || sourceN.dot(targetN) > 0.5) {
1282 similarPrimitives.push_back(primIndex);
1284 primitives.push_back(primIndex);
1289 if (!primitives.empty() || !similarPrimitives.empty()) {
1290 GA_Offset source, v0, v1, v2;
1292 if (!similarPrimitives.empty()) {
1294 mSourceGeo, similarPrimitives, pos, v0, v1, v2, uvw);
1297 mSourceGeo, primitives, pos, v0, v1, v2, uvw);
1301 const auto targetOffset = targetPrim.getMapOffset();
1302 for (
size_t n = 0, N = mPrimAttributes.size(); n < N; ++n) {
1303 mPrimAttributes[n]->copy(source, targetOffset);
1314 template<
typename Gr
idType>
1315 template<
typename PrimT>
1317 TransferPrimitiveAttributesOp<GridType>::copyVertAttrs(
1318 const PrimT& targetPrim,
1319 const UT_Vector3& targetNormal,
1320 IndexAccT& polyIdxAcc)
const
1322 const auto& transform = mIndexGrid.transform();
1326 UT_Vector3 sourceNormal;
1327 std::vector<GA_Index> primitives, similarPrimitives;
1329 primitives.reserve(8);
1330 similarPrimitives.reserve(8);
1331 for (GA_Size vtx = 0, vtxN = targetPrim.getVertexCount(); vtx < vtxN; ++vtx) {
1332 pos = UTvdbConvert(targetPrim.getPos3(vtx));
1336 similarPrimitives.clear();
1338 for (
int d = 0; d < 8; ++d) {
1339 ijk[0] = coord[0] + (((d & 0x02) >> 1) ^ (d & 0x01));
1340 ijk[1] = coord[1] + ((d & 0x02) >> 1);
1341 ijk[2] = coord[2] + ((d & 0x04) >> 2);
1343 if (polyIdxAcc.probeValue(ijk, primIndex) &&
1346 GA_Offset tmpOffset = mSourceGeo.primitiveOffset(primIndex);
1347 sourceNormal = mSourceGeo.getGEOPrimitive(tmpOffset)->computeNormal();
1348 if (sourceNormal.dot(targetNormal) > 0.5) {
1349 primitives.push_back(primIndex);
1354 if (!primitives.empty() || !similarPrimitives.empty()) {
1355 GA_Offset v0, v1, v2;
1356 if (!similarPrimitives.empty()) {
1362 for (
size_t n = 0, N = mVertAttributes.size(); n < N; ++n) {
1363 mVertAttributes[n]->copy(v0, v1, v2, targetPrim.getVertexOffset(vtx), uvw);
1373 template<
class Gr
idType>
1378 const GU_Detail& sourceGeo, GU_Detail& targetGeo,
const GridType& indexGrid,
1379 std::vector<AttributeCopyBase::Ptr>& pointAttributes,
1380 const GA_PrimitiveGroup* surfacePrims =
nullptr);
1382 void operator()(
const GA_SplittableRange&)
const;
1384 const GU_Detail& mSourceGeo;
1385 GU_Detail& mTargetGeo;
1386 const GridType& mIndexGrid;
1387 std::vector<AttributeCopyBase::Ptr>& mPointAttributes;
1388 const GA_PrimitiveGroup* mSurfacePrims;
1391 template<
class Gr
idType>
1393 const GU_Detail& sourceGeo, GU_Detail& targetGeo,
const GridType& indexGrid,
1394 std::vector<AttributeCopyBase::Ptr>& pointAttributes,
1395 const GA_PrimitiveGroup* surfacePrims)
1396 : mSourceGeo(sourceGeo)
1397 , mTargetGeo(targetGeo)
1398 , mIndexGrid(indexGrid)
1399 , mPointAttributes(pointAttributes)
1400 , mSurfacePrims(surfacePrims)
1404 template<
class Gr
idType>
1408 using IndexT =
typename GridType::ValueType;
1410 GA_Offset start, end, vtxOffset, primOffset, target, v0, v1, v2;
1412 typename GridType::ConstAccessor polyIdxAcc = mIndexGrid.getConstAccessor();
1413 const openvdb::math::Transform& transform = mIndexGrid.transform();
1415 std::vector<GA_Index> primitives;
1418 primitives.reserve(8);
1419 for (GA_PageIterator pageIt = range.beginPages(); !pageIt.atEnd(); ++pageIt) {
1420 for (GA_Iterator blockIt(pageIt.begin()); blockIt.blockAdvance(start, end); ) {
1421 for (target = start; target < end; ++target) {
1424 vtxOffset = mTargetGeo.pointVertex(target);
1427 if (mSurfacePrims) {
1428 bool surfacePrim =
false;
1430 while (GAisValid(vtxOffset)) {
1432 primOffset = mTargetGeo.vertexPrimitive(vtxOffset);
1434 if (mSurfacePrims->containsIndex(mTargetGeo.primitiveIndex(primOffset))) {
1439 vtxOffset = mTargetGeo.vertexToNextVertex(vtxOffset);
1442 if (!surfacePrim)
continue;
1445 const UT_Vector3 p = mTargetGeo.getPos3(target);
1450 indexPos = transform.worldToIndex(pos);
1451 coord[0] = int(std::floor(indexPos[0]));
1452 coord[1] = int(std::floor(indexPos[1]));
1453 coord[2] = int(std::floor(indexPos[2]));
1458 for (
int d = 0; d < 8; ++d) {
1459 ijk[0] = coord[0] + (((d & 0x02) >> 1) ^ (d & 0x01));
1460 ijk[1] = coord[1] + ((d & 0x02) >> 1);
1461 ijk[2] = coord[2] + ((d & 0x04) >> 2);
1463 if (polyIdxAcc.probeValue(ijk, primIndex) &&
1465 primitives.push_back(primIndex);
1469 if (!primitives.empty()) {
1472 v0 = mSourceGeo.vertexPoint(v0);
1473 v1 = mSourceGeo.vertexPoint(v1);
1474 v2 = mSourceGeo.vertexPoint(v2);
1476 for (
size_t n = 0, N = mPointAttributes.size(); n < N; ++n) {
1477 mPointAttributes[n]->copy(v0, v1, v2, target, uvw);
1489 template<
class Gr
idType>
1492 const GU_Detail& sourceGeo,
1493 GU_Detail& targetGeo,
1494 GridType& indexGrid,
1496 const GA_PrimitiveGroup* primitives =
nullptr)
1499 GA_AttributeDict::iterator it = sourceGeo.primitiveAttribs().begin(GA_SCOPE_PUBLIC);
1501 if (indexGrid.activeVoxelCount() == 0)
return;
1503 std::vector<AttributeCopyBase::Ptr> primAttributeList;
1506 for (; !it.atEnd(); ++it) {
1507 const GA_Attribute* sourceAttr = it.attrib();
1508 if (
nullptr == targetGeo.findPrimitiveAttribute(it.name())) {
1509 targetGeo.addPrimAttrib(sourceAttr);
1511 GA_Attribute* targetAttr = targetGeo.findPrimitiveAttribute(it.name());
1513 if (sourceAttr && targetAttr) {
1515 if(att) primAttributeList.push_back(att);
1521 std::vector<AttributeCopyBase::Ptr> vertAttributeList;
1523 it = sourceGeo.vertexAttribs().begin(GA_SCOPE_PUBLIC);
1526 for (; !it.atEnd(); ++it) {
1527 const GA_Attribute* sourceAttr = it.attrib();
1528 if (
nullptr == targetGeo.findVertexAttribute(it.name())) {
1529 targetGeo.addVertexAttrib(sourceAttr);
1531 GA_Attribute* targetAttr = targetGeo.findVertexAttribute(it.name());
1533 if (sourceAttr && targetAttr) {
1534 targetAttr->hardenAllPages();
1536 if(att) vertAttributeList.push_back(att);
1540 if (!boss.
wasInterrupted() && (!primAttributeList.empty() || !vertAttributeList.empty())) {
1542 UTparallelFor(GA_SplittableRange(targetGeo.getPrimitiveRange(primitives)),
1544 primAttributeList, vertAttributeList));
1548 std::vector<AttributeCopyBase::Ptr> pointAttributeList;
1549 it = sourceGeo.pointAttribs().begin(GA_SCOPE_PUBLIC);
1552 for (; !it.atEnd(); ++it) {
1553 if (std::string(it.name()) ==
"P")
continue;
1555 const GA_Attribute* sourceAttr = it.attrib();
1556 if (
nullptr == targetGeo.findPointAttribute(it.name())) {
1557 targetGeo.addPointAttrib(sourceAttr);
1559 GA_Attribute* targetAttr = targetGeo.findPointAttribute(it.name());
1561 if (sourceAttr && targetAttr) {
1563 if(att) pointAttributeList.push_back(att);
1568 UTparallelFor(GA_SplittableRange(targetGeo.getPointRange()),
1570 pointAttributeList, primitives));
SharedPtr< GridBase > Ptr
Definition: Grid.h:80
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:577
TreeType & tree()
Return a reference to this grid's tree, which might be shared with other grids.
Definition: Grid.h:917
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:26
Int32 x() const
Definition: Coord.h:131
static Coord floor(const Vec3< T > &xyz)
Return the largest integer coordinates that are not greater than xyz (node centered conversion).
Definition: Coord.h:57
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:89
Base class for tree-traversal iterators over tile and voxel values.
Definition: TreeIterator.h:617
const ValueT & getValue() const
Return the tile or voxel value to which this iterator is currently pointing.
Definition: TreeIterator.h:692
Coord getCoord() const
Return the global coordinates of the voxel or tile to which this iterator is currently pointing.
Definition: TreeIterator.h:671
Definition: AttributeTransferUtil.h:384
virtual void set(const openvdb::Coord &ijk, GA_Offset offset)=0
virtual std::string & name()=0
virtual openvdb::GridBase::Ptr & grid()=0
std::shared_ptr< AttributeDetailBase > Ptr
Definition: AttributeTransferUtil.h:386
AttributeDetailBase()
Definition: AttributeTransferUtil.h:404
virtual void set(const openvdb::Coord &ijk, const GA_Offset(&offsets)[3], const openvdb::Vec3d &weights)=0
AttributeDetailBase & operator=(const AttributeDetailBase &)=default
virtual AttributeDetailBase::Ptr copy()=0
AttributeDetailBase(const AttributeDetailBase &)=default
virtual ~AttributeDetailBase()=default
Definition: AttributeTransferUtil.h:416
std::string & name() override
Definition: AttributeTransferUtil.h:433
typename VDBGridType::ValueType ValueType
Definition: AttributeTransferUtil.h:418
openvdb::GridBase::Ptr & grid() override
Definition: AttributeTransferUtil.h:432
void set(const openvdb::Coord &ijk, const GA_Offset(&offsets)[3], const openvdb::Vec3d &weights) override
Definition: AttributeTransferUtil.h:488
AttributeDetail()
Definition: AttributeTransferUtil.h:452
AttributeDetailBase::Ptr copy() override
Definition: AttributeTransferUtil.h:513
Wrapper class that adapts a Houdini UT_Interrupt object for use with OpenVDB library routines.
Definition: openvdb_houdini/openvdb_houdini/Utils.h:174
bool wasInterrupted(int percent=-1)
Check if an interruptible operation should be aborted.
Definition: openvdb_houdini/openvdb_houdini/Utils.h:195
Definition: AttributeTransferUtil.h:526
void runSerial()
Definition: AttributeTransferUtil.h:611
void runParallel()
Main calls.
Definition: AttributeTransferUtil.h:604
~MeshAttrTransfer()
Definition: AttributeTransferUtil.h:543
void operator()(IterRange &range) const
Definition: AttributeTransferUtil.h:619
MeshAttrTransfer(AttributeDetailList &pointAttributes, AttributeDetailList &vertexAttributes, AttributeDetailList &primitiveAttributes, const openvdb::Int32Grid &closestPrimGrid, const openvdb::math::Transform &transform, const GU_Detail &meshGdp)
Definition: AttributeTransferUtil.h:561
openvdb::tree::IteratorRange< openvdb::Int32Tree::LeafCIter > IterRange
Definition: AttributeTransferUtil.h:528
Definition: AttributeTransferUtil.h:713
void runSerial()
Definition: AttributeTransferUtil.h:772
void runParallel()
Main calls.
Definition: AttributeTransferUtil.h:765
void operator()(IterRange &range) const
Definition: AttributeTransferUtil.h:780
~PointAttrTransfer()
Definition: AttributeTransferUtil.h:724
openvdb::tree::IteratorRange< openvdb::Int32Tree::LeafCIter > IterRange
Definition: AttributeTransferUtil.h:715
PointAttrTransfer(AttributeDetailList &pointAttributes, const openvdb::Int32Grid &closestPtnIdxGrid, const GU_Detail &ptGeop)
Definition: AttributeTransferUtil.h:739
Definition: AttributeTransferUtil.h:1375
TransferPointAttributesOp(const GU_Detail &sourceGeo, GU_Detail &targetGeo, const GridType &indexGrid, std::vector< AttributeCopyBase::Ptr > &pointAttributes, const GA_PrimitiveGroup *surfacePrims=nullptr)
Definition: AttributeTransferUtil.h:1392
void operator()(const GA_SplittableRange &) const
Definition: AttributeTransferUtil.h:1406
Definition: AttributeTransferUtil.h:1150
typename GridType::ValueType IndexT
Definition: AttributeTransferUtil.h:1152
void operator()(const GA_SplittableRange &) const
Definition: AttributeTransferUtil.h:1188
TransferPrimitiveAttributesOp(const GU_Detail &sourceGeo, GU_Detail &targetGeo, const GridType &indexGrid, AttrCopyPtrVec &primAttributes, AttrCopyPtrVec &vertAttributes)
Definition: AttributeTransferUtil.h:1156
typename GridType::ConstAccessor IndexAccT
Definition: AttributeTransferUtil.h:1153
std::vector< AttributeCopyBase::Ptr > AttrCopyPtrVec
Definition: AttributeTransferUtil.h:1154
tbb::blocked_range< SizeType > SizeRange
Definition: ConjGradient.h:35
Vec3< double > Vec3d
Definition: Vec3.h:668
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...
Vec3< int32_t > Vec3i
Definition: Vec3.h:665
Vec3< float > Vec3s
Definition: Vec3.h:667
OPENVDB_API const Index32 INVALID_IDX
int64_t Int64
Definition: openvdb/Types.h:53
uint32_t Index32
Definition: openvdb/Types.h:48
int32_t Int32
Definition: openvdb/Types.h:52
Definition: AttributeTransferUtil.h:33
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:990
float evalAttr< float >(const GA_Attribute *atr, const GA_AIFTuple *aif, GA_Offset off, int idx)
Definition: AttributeTransferUtil.h:50
ValueType combine(const ValueType &v0, const ValueType &v1, const ValueType &v2, const openvdb::Vec3d &w)
Combine different value types.
Definition: AttributeTransferUtil.h:140
ValueType evalAttr(const GA_Attribute *atr, const GA_AIFTuple *aif, GA_Offset off, int idx)
Definition: AttributeTransferUtil.h:41
AttributeCopyBase::Ptr createAttributeCopier(const GA_Attribute &sourceAttr, GA_Attribute &targetAttr)
Definition: AttributeTransferUtil.h:938
void transferPrimitiveAttributes(const GU_Detail &sourceGeo, GU_Detail &targetGeo, GridType &indexGrid, Interrupter &boss, const GA_PrimitiveGroup *primitives=nullptr)
Definition: AttributeTransferUtil.h:1491
std::vector< AttributeDetailBase::Ptr > AttributeDetailList
Definition: AttributeTransferUtil.h:408
ValueType evalAttrDefault(const GA_Defaults &defaults, int idx)
Get an OpenVDB-specific value by evaluating GA_Default::get() with appropriate arguments.
Definition: AttributeTransferUtil.h:206
float evalAttrDefault< float >(const GA_Defaults &defaults, int)
Definition: AttributeTransferUtil.h:214
Definition: openvdb/Exceptions.h:13
Utility code generation methods for performing various llvm operations.
Definition: AttributeTransferUtil.h:809
virtual ~AttributeCopyBase()
Definition: AttributeTransferUtil.h:812
std::shared_ptr< AttributeCopyBase > Ptr
Definition: AttributeTransferUtil.h:810
virtual void copy(GA_Offset, GA_Offset)=0
virtual void copy(GA_Offset &, GA_Offset &, GA_Offset &, GA_Offset, const openvdb::Vec3d &)=0
AttributeCopyBase()
Definition: AttributeTransferUtil.h:817
Definition: AttributeTransferUtil.h:823
void copy(GA_Offset source, GA_Offset target) override
Definition: AttributeTransferUtil.h:833
void copy(GA_Offset &v0, GA_Offset &v1, GA_Offset &v2, GA_Offset target, const openvdb::Vec3d &uvw) override
Definition: AttributeTransferUtil.h:842
AttributeCopy(const GA_Attribute &sourceAttr, GA_Attribute &targetAttr)
Definition: AttributeTransferUtil.h:825
Definition: AttributeTransferUtil.h:892
void copy(GA_Offset source, GA_Offset target) override
Definition: AttributeTransferUtil.h:902
const GA_Attribute & mSourceAttr
Definition: AttributeTransferUtil.h:927
void copy(GA_Offset &v0, GA_Offset &v1, GA_Offset &v2, GA_Offset target, const openvdb::Vec3d &uvw) override
Definition: AttributeTransferUtil.h:909
const GA_AIFSharedStringTuple & mAIF
Definition: AttributeTransferUtil.h:929
int mTupleSize
Definition: AttributeTransferUtil.h:930
StrAttributeCopy(const GA_Attribute &sourceAttr, GA_Attribute &targetAttr)
Definition: AttributeTransferUtil.h:894
GA_Attribute & mTargetAttr
Definition: AttributeTransferUtil.h:928