From f9b5f9c05fd064369a388be8cd43c547624de118 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Tue, 19 Mar 2024 14:20:14 +0800 Subject: [PATCH 01/17] import skin root name --- projects/FBX/FBXSDK.cpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/projects/FBX/FBXSDK.cpp b/projects/FBX/FBXSDK.cpp index ec0a58829c..3939dcca0c 100644 --- a/projects/FBX/FBXSDK.cpp +++ b/projects/FBX/FBXSDK.cpp @@ -359,9 +359,14 @@ void PrintAttribute(FbxNodeAttribute* pAttribute) { // // printf("\n"); //} -bool GetMesh(FbxNode* pNode, std::shared_ptr prim) { +bool GetMesh(FbxNode* pNode, std::shared_ptr prim, std::string name) { FbxMesh* pMesh = pNode->GetMesh(); if (!pMesh) return false; + std::string nodeName = pNode->GetName(); + if (name.size() > 0 && nodeName != name) { + return false; + } + prim->userData().set2("RootName", nodeName); FbxAMatrix bindMatrix = pNode->EvaluateGlobalTransform(); auto s = bindMatrix.GetS(); @@ -476,9 +481,26 @@ struct NewFBXImportSkin : INode { auto &ud = prim->userData(); ud.set2("version", vec3i(major, minor, revision)); FbxNode* lRootNode = lScene->GetRootNode(); + std::vector availableRootNames; + if(lRootNode) { + for(int i = 0; i < lRootNode->GetChildCount(); i++) { + auto pNode = lRootNode->GetChild(i); + FbxMesh* pMesh = pNode->GetMesh(); + if (pMesh) { + std::string meshName = pNode->GetName(); + availableRootNames.emplace_back(meshName); + } + } + ud.set2("AvailableRootName_count", int(availableRootNames.size())); + for (int i = 0; i < availableRootNames.size(); i++) { + ud.set2(format("AvailableRootName_{}", i), availableRootNames[i]); + } + } + auto rootName = get_input2("rootName"); if(lRootNode) { for(int i = 0; i < lRootNode->GetChildCount(); i++) { - if (GetMesh(lRootNode->GetChild(i), prim)) { + auto pNode = lRootNode->GetChild(i); + if (GetMesh(pNode, prim, rootName)) { break; } } @@ -497,6 +519,7 @@ struct NewFBXImportSkin : INode { ZENDEFNODE(NewFBXImportSkin, { { {"readpath", "path"}, + {"string", "rootName", ""}, {"bool", "ConvertUnits", "1"}, }, { From 56110802153fd4ce8a53dfedc304e2a468c5d785 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Tue, 19 Mar 2024 19:38:08 +0800 Subject: [PATCH 02/17] import normal --- projects/FBX/FBXSDK.cpp | 99 +++++++++++++++++++++++++++++ zeno/src/nodes/neo/PrimCodecUVs.cpp | 74 +++++++++++++++++++++ 2 files changed, 173 insertions(+) diff --git a/projects/FBX/FBXSDK.cpp b/projects/FBX/FBXSDK.cpp index ec0a58829c..b111f862bb 100644 --- a/projects/FBX/FBXSDK.cpp +++ b/projects/FBX/FBXSDK.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -359,6 +360,39 @@ void PrintAttribute(FbxNodeAttribute* pAttribute) { // // printf("\n"); //} + +template +void getAttr(T* arr, std::string name, std::shared_ptr prim) { + if (arr->GetMappingMode() == FbxLayerElement::EMappingMode::eByControlPoint) { + zeno::log_info("{}, eByControlPoint", name); + auto &attr = prim->verts.add_attr(name); + for (auto i = 0; i < prim->verts.size(); i++) { + int pIndex = i; + if (arr->GetReferenceMode() == FbxLayerElement::EReferenceMode::eIndexToDirect) { + pIndex = arr->GetIndexArray().GetAt(i); + } + auto x = arr->GetDirectArray().GetAt(pIndex)[0]; + auto y = arr->GetDirectArray().GetAt(pIndex)[1]; + auto z = arr->GetDirectArray().GetAt(pIndex)[2]; + attr[i] = vec3f(x, y, z); + } + } + else if (arr->GetMappingMode() == FbxLayerElement::EMappingMode::eByPolygonVertex) { + zeno::log_info("{}, eByPolygonVertex", name); + auto &attr = prim->loops.add_attr(name); + for (auto i = 0; i < prim->loops.size(); i++) { + int pIndex = i; + if (arr->GetReferenceMode() == FbxLayerElement::EReferenceMode::eIndexToDirect) { + pIndex = arr->GetIndexArray().GetAt(i); + } + auto x = arr->GetDirectArray().GetAt(pIndex)[0]; + auto y = arr->GetDirectArray().GetAt(pIndex)[1]; + auto z = arr->GetDirectArray().GetAt(pIndex)[2]; + attr[i] = vec3f(x, y, z); + } + } +} + bool GetMesh(FbxNode* pNode, std::shared_ptr prim) { FbxMesh* pMesh = pNode->GetMesh(); if (!pMesh) return false; @@ -433,6 +467,50 @@ bool GetMesh(FbxNode* pNode, std::shared_ptr prim) { ud.set2(zeno::format("boneName_{}", i), bone_names[i]); } } + if (pMesh->GetElementUVCount() > 0) { + auto* arr = pMesh->GetElementUV(0); + std::string name = "uv"; + if (arr->GetMappingMode() == FbxLayerElement::EMappingMode::eByControlPoint) { + zeno::log_info("{}, eByControlPoint", name); + auto &attr = prim->verts.add_attr(name); + for (auto i = 0; i < prim->verts.size(); i++) { + int pIndex = i; + if (arr->GetReferenceMode() == FbxLayerElement::EReferenceMode::eIndexToDirect) { + pIndex = arr->GetIndexArray().GetAt(i); + } + auto x = arr->GetDirectArray().GetAt(pIndex)[0]; + auto y = arr->GetDirectArray().GetAt(pIndex)[1]; + attr[i] = vec3f(x, y, 0); + } + } + else if (arr->GetMappingMode() == FbxLayerElement::EMappingMode::eByPolygonVertex) { + zeno::log_info("{}, eByPolygonVertex", name); + if (arr->GetReferenceMode() == FbxLayerElement::EReferenceMode::eDirect) { + auto &uvs = prim->loops.add_attr("uvs"); + std::iota(uvs.begin(), uvs.end(), 0); + prim->uvs.resize(prim->loops.size()); + } + else if (arr->GetReferenceMode() == FbxLayerElement::EReferenceMode::eIndexToDirect) { + auto &uvs = prim->loops.add_attr("uvs"); + for (auto i = 0; i < prim->loops.size(); i++) { + uvs[i] = arr->GetIndexArray().GetAt(i); + } + int count = arr->GetDirectArray().GetCount(); + prim->uvs.resize(count); + } + for (auto i = 0; i < prim->uvs.size(); i++) { + auto x = arr->GetDirectArray().GetAt(i)[0]; + auto y = arr->GetDirectArray().GetAt(i)[1]; + prim->uvs[i] = vec2f(x, y); + } + } + } + if (pMesh->GetElementNormalCount() > 0) { + getAttr(pMesh->GetElementNormal(0), "nrm", prim); + } + if (pMesh->GetElementTangentCount() > 0) { + getAttr(pMesh->GetElementTangent(0), "tang", prim); + } return true; } @@ -866,6 +944,10 @@ struct NewFBXBoneDeform : INode { auto p = transform * glm::vec4(pos[0], pos[1], pos[2], 1); return {p.x, p.y, p.z}; } + vec3f transform_nrm(glm::mat4 &transform, vec3f pos) { + auto p = glm::transpose(glm::inverse(transform)) * glm::vec4(pos[0], pos[1], pos[2], 0); + return {p.x, p.y, p.z}; + } virtual void apply() override { auto geometryToDeform = get_input2("GeometryToDeform"); auto geometryToDeformBoneNames = getBoneNames(geometryToDeform.get()); @@ -907,6 +989,23 @@ struct NewFBXBoneDeform : INode { } prim->verts[i] = pos / w; } + if (prim->verts.attr_is("nrm")) { + auto &nrms = prim->verts.attr("nrm"); + for (auto i = 0; i < vert_count; i++) { + glm::mat4 matrix(0); + float w = 0; + for (auto j = 0; j < 4; j++) { + if (bi[i][j] < 0) { + continue; + } + matrix += matrixs[bi[i][j]] * bw[i][j]; + w += bw[i][j]; + } + matrix = matrix / w; + auto nrm = transform_nrm(matrix, nrms[i]); + nrms[i] = zeno::normalize(nrm ); + } + } set_output("prim", prim); } diff --git a/zeno/src/nodes/neo/PrimCodecUVs.cpp b/zeno/src/nodes/neo/PrimCodecUVs.cpp index 182d172fb9..ca62976819 100644 --- a/zeno/src/nodes/neo/PrimCodecUVs.cpp +++ b/zeno/src/nodes/neo/PrimCodecUVs.cpp @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include namespace zeno { @@ -175,6 +178,77 @@ ZENO_DEFNODE(PrimUVEdgeDuplicate)({ {"primitive"}, }); +struct PrimSplitVertexForSharedNormal : INode { + virtual void apply() override { + auto prim = get_input("prim"); + if (prim->loops.attr_is("nrm")) { + std::vector indexs; + indexs.reserve(prim->loops.size()); + std::map, int> mapping; + { + auto &nrm = prim->loops.attr("nrm"); + for (auto i = 0; i < prim->loops.size(); i++) { + std::tuple n = {nrm[i][0], nrm[i][1], nrm[i][2]}; + if (mapping.count(n) == 0) { + int count = mapping.size(); + mapping[n] = count; + } + indexs.push_back(mapping[n]); + } + prim->loops.erase_attr("nrm"); + } + std::map revert_mapping; + for (auto [k, v]: mapping) { + revert_mapping[v] = {std::get<0>(k), std::get<1>(k), std::get<2>(k)}; + } + std::map, int> new_mapping; + std::vector new_indexs; + for (auto i = 0; i < prim->loops.size(); i++) { + std::pair new_index = {prim->loops[i], indexs[i]}; + if (new_mapping.count(new_index) == 0) { + int count = new_mapping.size(); + new_mapping[new_index] = count; + } + new_indexs.push_back(new_mapping[new_index]); + } + std::map> revert_new_mapping; + for (auto [k, v]: new_mapping) { + revert_new_mapping[v] = k; + } + AttrVector verts(new_mapping.size()); + auto &nrm = verts.add_attr("nrm"); + for (auto i = 0; i < verts.size(); i++) { + verts[i] = prim->verts[revert_new_mapping[i].first]; + nrm[i] = revert_mapping[revert_new_mapping[i].second]; + } + prim->verts.foreach_attr([&](auto const &key, auto &arr) { + using T = std::decay_t; + zeno::log_info("key: {}", key); + auto &attr = verts.add_attr(key); + for (auto i = 0; i < attr.size(); i++) { + attr[i] = arr[revert_new_mapping[i].first]; + } + }); + + prim->verts = verts; + for (auto i = 0; i < prim->loops.size(); i++) { + prim->loops[i] = new_indexs[i]; + } + } + set_output("prim", std::move(prim)); + } +}; + +ZENO_DEFNODE(PrimSplitVertexForSharedNormal)({ + { + "prim", + }, + { + "prim", + }, + {}, + {"primitive"}, +}); } } From 67e38743de0ca1c8826168f01ebf44d4cc9e9940 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Wed, 20 Mar 2024 13:57:23 +0800 Subject: [PATCH 03/17] NormalView --- projects/FBX/FBXSDK.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/projects/FBX/FBXSDK.cpp b/projects/FBX/FBXSDK.cpp index b111f862bb..e99ebc0666 100644 --- a/projects/FBX/FBXSDK.cpp +++ b/projects/FBX/FBXSDK.cpp @@ -1023,5 +1023,37 @@ ZENDEFNODE(NewFBXBoneDeform, { {}, {"primitive"}, }); + + +struct NormalView : INode { + virtual void apply() override { + auto prim = get_input2("prim"); + auto &nrms = prim->verts.attr("nrm"); + auto scale = get_input2("scale"); + auto normals = std::make_shared(); + normals->verts.resize(prim->verts.size() * 2); + for (auto i = 0; i < prim->verts.size(); i++) { + normals->verts[i] = prim->verts[i]; + normals->verts[i + prim->size()] = prim->verts[i] + nrms[i] * scale; + } + normals->lines.resize(prim->verts.size()); + for (auto i = 0; i < prim->verts.size(); i++) { + normals->lines[i] = vec2i(i, i + prim->verts.size()); + } + set_output("normals", normals); + } +}; + +ZENDEFNODE(NormalView, { + { + "prim", + {"float", "scale", "0.01"}, + }, + { + "normals", + }, + {}, + {"debug"}, +}); } #endif \ No newline at end of file From b4bd071d892956d917bc5ba39b7d1440829c7232 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Wed, 20 Mar 2024 17:36:50 +0800 Subject: [PATCH 04/17] fbx camera --- projects/FBX/FBXSDK.cpp | 176 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) diff --git a/projects/FBX/FBXSDK.cpp b/projects/FBX/FBXSDK.cpp index e99ebc0666..e0a460ba13 100644 --- a/projects/FBX/FBXSDK.cpp +++ b/projects/FBX/FBXSDK.cpp @@ -890,6 +890,182 @@ ZENDEFNODE(NewFBXImportAnimation, { {}, {"primitive"}, }); + +struct NewFBXImportCamera : INode { + virtual void apply() override { + int frameid; + if (has_input("frameid")) { + frameid = std::lround(get_input2("frameid")); + } else { + frameid = getGlobalState()->frameid; + } + float fps = get_input2("fps"); + float t = float(frameid) / fps; + FbxTime curTime; // The time for each key in the animation curve(s) + curTime.SetSecondDouble(t); // Starting time + + // Change the following filename to a suitable filename value. + auto lFilename = get_input2("path"); + + // Initialize the SDK manager. This object handles all our memory management. + FbxManager* lSdkManager = FbxManager::Create(); + + // Create the IO settings object. + FbxIOSettings *ios = FbxIOSettings::Create(lSdkManager, IOSROOT); + lSdkManager->SetIOSettings(ios); + // Destroy the SDK manager and all the other objects it was handling. + zeno::scope_exit sp([=]() { lSdkManager->Destroy(); }); + + // Create an importer using the SDK manager. + FbxImporter* lImporter = FbxImporter::Create(lSdkManager,""); + + // Use the first argument as the filename for the importer. + if(!lImporter->Initialize(lFilename.c_str(), -1, lSdkManager->GetIOSettings())) { + printf("Call to FbxImporter::Initialize() failed.\n"); + printf("Error returned: %s\n\n", lImporter->GetStatus().GetErrorString()); + exit(-1); + } + int major, minor, revision; + lImporter->GetFileVersion(major, minor, revision); + + // Create a new scene so that it can be populated by the imported file. + FbxScene* lScene = FbxScene::Create(lSdkManager,"myScene"); + + // Import the contents of the file into the scene. + lImporter->Import(lScene); + + // The file is imported; so get rid of the importer. + lImporter->Destroy(); + + // Print the nodes of the scene and their attributes recursively. + // Note that we are not printing the root node because it should + // not contain any attributes. + auto prim = std::make_shared(); + auto &ud = prim->userData(); + ud.set2("version", vec3i(major, minor, revision)); + + FbxArray animationStackNames; + std::vector clip_names; + lScene->FillAnimStackNameArray(animationStackNames); + for (auto i = 0; i < animationStackNames.GetCount(); i++) { + clip_names.emplace_back(animationStackNames[i]->Buffer()); + } + for (auto i = 0; i < clip_names.size(); i++) { + ud.set2(format("avail_anim_clip_{}", i), clip_names[i]); + } + ud.set2("avail_anim_clip_count", int(clip_names.size())); + + auto clip_name = get_input2("clipName"); + if (clip_name == "") { + clip_name = lScene->ActiveAnimStackName.Get().Buffer(); + } + + int stack_index = int(std::find(clip_names.begin(), clip_names.end(), clip_name) - clip_names.begin()); + if (stack_index == clip_names.size()) { + zeno::log_error("FBX: Can not find clip name"); + } + + + FbxAnimStack* animStack = lScene->GetSrcObject(stack_index); + ud.set2("clipinfo.name", std::string(animStack->GetName())); + + + lScene->SetCurrentAnimationStack(animStack); + + FbxTime mStart, mStop; + FbxTakeInfo* lCurrentTakeInfo = lScene->GetTakeInfo(*(animationStackNames[stack_index])); + float src_fps = 0; + if (lCurrentTakeInfo) { + mStart = lCurrentTakeInfo->mLocalTimeSpan.GetStart(); + mStop = lCurrentTakeInfo->mLocalTimeSpan.GetStop(); + int frameCount = lCurrentTakeInfo->mLocalTimeSpan.GetDuration().GetFrameCount(); + src_fps = frameCount / lCurrentTakeInfo->mLocalTimeSpan.GetDuration().GetSecondDouble(); + } + else { + // Take the time line value + FbxTimeSpan lTimeLineTimeSpan; + lScene->GetGlobalSettings().GetTimelineDefaultTimeSpan(lTimeLineTimeSpan); + + mStart = lTimeLineTimeSpan.GetStart(); + mStop = lTimeLineTimeSpan.GetStop(); + int frameCount = lTimeLineTimeSpan.GetDuration().GetFrameCount(); + src_fps = frameCount / lTimeLineTimeSpan.GetDuration().GetSecondDouble(); + } + + ud.set2("clipinfo.source_range", vec2f(mStart.GetSecondDouble(), mStop.GetSecondDouble())); + ud.set2("clipinfo.source_fps", src_fps); + ud.set2("clipinfo.fps", fps); + + { + auto node_count = lScene->GetNodeCount(); + for (int j = 0; j < node_count; ++j) { + auto pNode = lScene->GetNode(j); + FbxAMatrix lGlobalPosition = pNode->EvaluateGlobalTransform(curTime); + FbxMatrix transformMatrix; + memcpy(&transformMatrix, &lGlobalPosition, sizeof(FbxMatrix)); + auto t = transformMatrix.GetRow(3); + auto pos = vec3f(t[0], t[1], t[2]); + + auto r0 = transformMatrix.GetRow(0); + auto r1 = transformMatrix.GetRow(1); + auto r2 = transformMatrix.GetRow(2); + auto view = vec3f(r0[0], r0[1], r0[2]); + auto up = vec3f(r1[0], r1[1], r1[2]); + auto right = vec3f(r2[0], r2[1], r2[2]); + FbxCamera* pCamera = pNode->GetCamera(); + if (pCamera) { + set_output2("pos", pos); + set_output2("right", right); + set_output2("up", up); + set_output2("view", view); + + float focal_length = pCamera->FocalLength.Get(); + set_output2("focal_length", focal_length); + float m_ha = pCamera->GetApertureWidth() * 25.4; // inch -> mm + float m_va = pCamera->GetApertureHeight() * 25.4; // inch -> mm + set_output2("horizontalAperture", m_ha); + set_output2("verticalAperture", m_va); + auto m_nx = get_input2("nx"); + auto m_ny = get_input2("ny"); + float c_aspect = m_ha/m_va; + float u_aspect = m_nx/m_ny; + float fov_y = glm::degrees(2.0f * std::atan(m_va/(u_aspect/c_aspect) / (2.0f * focal_length))); + set_output2("fov_y", fov_y); + float _near = pCamera->NearPlane.Get(); + float _far = pCamera->FarPlane.Get(); + set_output2("near", _near); + set_output2("far", _far); + } + } + } + } +}; + +ZENDEFNODE(NewFBXImportCamera, { + { + {"readpath", "path"}, + {"string", "clipName", ""}, + {"frameid"}, + {"float", "fps", "25"}, + {"bool", "ConvertUnits", "1"}, + {"int", "nx", "1920"}, + {"int", "ny", "1080"}, + }, + { + "pos", + "up", + "view", + "right", + "fov_y", + "focal_length", + "horizontalAperture", + "verticalAperture", + "near", + "far", + }, + {}, + {"primitive"}, +}); struct NewFBXBoneDeform : INode { std::vector getBoneNames(PrimitiveObject *prim) { auto boneName_count = prim->userData().get2("boneName_count"); From 1a8a3bc723ead640b8b876cbddb4629496cd6417 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Mon, 25 Mar 2024 15:00:19 +0800 Subject: [PATCH 05/17] real_frame_start --- projects/Alembic/WriteAlembic.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/projects/Alembic/WriteAlembic.cpp b/projects/Alembic/WriteAlembic.cpp index 8bb21c6876..ff3bae5be0 100644 --- a/projects/Alembic/WriteAlembic.cpp +++ b/projects/Alembic/WriteAlembic.cpp @@ -471,6 +471,7 @@ struct WriteAlembic2 : INode { std::map user_attrs; std::map o_faceset; std::map o_faceset_schema; + int real_frame_start = -1; virtual void apply() override { auto prim = get_input("prim"); @@ -499,7 +500,7 @@ struct WriteAlembic2 : INode { "Zeno : " + getGlobalState()->zeno_version, "None" ); - archive.addTimeSampling(TimeSampling(1.0/fps, frame_start / fps)); + real_frame_start = -1; meshyObj = OPolyMesh( OObject( archive, 1 ), "mesh" ); attrs.clear(); user_attrs.clear(); @@ -507,6 +508,10 @@ struct WriteAlembic2 : INode { if (!(frame_start <= frameid && frameid <= frame_end)) { return; } + if (real_frame_start == -1) { + real_frame_start = frameid; + archive.addTimeSampling(TimeSampling(1.0/fps, real_frame_start / fps)); + } if (archive.valid() == false) { zeno::makeError("Not init. Check whether in correct correct frame range."); } @@ -659,6 +664,7 @@ struct WriteAlembicPrims : INode { std::map user_attrs; std::map> o_faceset; std::map> o_faceset_schema; + int real_frame_start = -1; virtual void apply() override { std::vector> prims; @@ -751,12 +757,12 @@ struct WriteAlembicPrims : INode { "Zeno : " + getGlobalState()->zeno_version, "None" ); - archive.addTimeSampling(TimeSampling(1.0/fps, frame_start / fps)); meshyObjs.clear(); attrs.clear(); user_attrs.clear(); o_faceset.clear(); o_faceset_schema.clear(); + real_frame_start = -1; for (auto prim: new_prims) { auto path = prim->userData().get2("abcpath_0"); if (!starts_with(path, "/ABC/")) { @@ -780,6 +786,10 @@ struct WriteAlembicPrims : INode { if (!(frame_start <= frameid && frameid <= frame_end)) { return; } + if (real_frame_start == -1) { + real_frame_start = frameid; + archive.addTimeSampling(TimeSampling(1.0/fps, real_frame_start / fps)); + } if (archive.valid() == false) { zeno::makeError("Not init. Check whether in correct correct frame range."); } From 03a15ddb1a954c56343781f858eaed929aa07616 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Mon, 25 Mar 2024 16:25:07 +0800 Subject: [PATCH 06/17] remove log --- projects/Alembic/ReadAlembic.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/Alembic/ReadAlembic.cpp b/projects/Alembic/ReadAlembic.cpp index 5fd07af800..8059856c48 100644 --- a/projects/Alembic/ReadAlembic.cpp +++ b/projects/Alembic/ReadAlembic.cpp @@ -82,7 +82,6 @@ static void read_attributes(std::shared_ptr prim, ICompoundProp size_t numProps = arbattrs.getNumProperties(); for (auto i = 0; i < numProps; i++) { PropertyHeader p = arbattrs.getPropertyHeader(i); - zeno::log_error("getName {}", p.getName()); if (IFloatGeomParam::matches(p)) { IFloatGeomParam param(arbattrs, p.getName()); From 87f6986f106eadc4d87a7d56c2d1e0ca42fa9107 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Mon, 25 Mar 2024 18:05:26 +0800 Subject: [PATCH 07/17] improve write abc attr --- projects/Alembic/WriteAlembic.cpp | 115 +++++++++++++++++------------- 1 file changed, 65 insertions(+), 50 deletions(-) diff --git a/projects/Alembic/WriteAlembic.cpp b/projects/Alembic/WriteAlembic.cpp index ff3bae5be0..fa252e3e33 100644 --- a/projects/Alembic/WriteAlembic.cpp +++ b/projects/Alembic/WriteAlembic.cpp @@ -186,8 +186,15 @@ ZENDEFNODE(WriteAlembic, { {"deprecated"}, }); -template -void write_attrs(std::map &attrs, std::string path, std::shared_ptr prim, T1& schema, T2& samp) { +template +void write_attrs( + std::map &verts_attrs + , std::map &loops_attrs + , std::map &polys_attrs + , std::string path + , std::shared_ptr prim + , T1& schema +) { OCompoundProperty arbAttrs = schema.getArbGeomParams(); prim->verts.foreach_attr>([&](auto const &key, auto &arr) { if (key == "v" || key == "nrm") { @@ -196,8 +203,8 @@ void write_attrs(std::map &attrs, std::string path, std:: std::string full_key = path + '/' + key; using T = std::decay_t; if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kVaryingScope, 3); + if (verts_attrs.count(full_key) == 0) { + verts_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kVaryingScope, 3); } auto samp = OFloatGeomParam::Sample(); std::vector v(arr.size() * 3); @@ -207,21 +214,21 @@ void write_attrs(std::map &attrs, std::string path, std:: v[i * 3 + 2] = arr[i][2]; } samp.setVals(v); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(verts_attrs[full_key]).set(samp); } else if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kVaryingScope, 1); + if (verts_attrs.count(full_key) == 0) { + verts_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kVaryingScope, 1); } auto samp = OFloatGeomParam::Sample(); samp.setVals(arr); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(verts_attrs[full_key]).set(samp); } else if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kVaryingScope, 1); + if (verts_attrs.count(full_key) == 0) { + verts_attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kVaryingScope, 1); } auto samp = OInt32GeomParam::Sample(); samp.setVals(arr); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(verts_attrs[full_key]).set(samp); } }); if (prim->loops.size() > 0) { @@ -229,8 +236,8 @@ void write_attrs(std::map &attrs, std::string path, std:: std::string full_key = path + '/' + key; using T = std::decay_t; if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kFacevaryingScope, 3); + if (loops_attrs.count(full_key) == 0) { + loops_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kFacevaryingScope, 3); } auto samp = OFloatGeomParam::Sample(); std::vector v(arr.size() * 3); @@ -240,21 +247,21 @@ void write_attrs(std::map &attrs, std::string path, std:: v[i * 3 + 2] = arr[i][2]; } samp.setVals(v); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(loops_attrs[full_key]).set(samp); } else if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kFacevaryingScope, 1); + if (loops_attrs.count(full_key) == 0) { + loops_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kFacevaryingScope, 1); } auto samp = OFloatGeomParam::Sample(); samp.setVals(arr); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(loops_attrs[full_key]).set(samp); } else if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kFacevaryingScope, 1); + if (loops_attrs.count(full_key) == 0) { + loops_attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kFacevaryingScope, 1); } auto samp = OInt32GeomParam::Sample(); samp.setVals(arr); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(loops_attrs[full_key]).set(samp); } }); } @@ -266,8 +273,8 @@ void write_attrs(std::map &attrs, std::string path, std:: std::string full_key = path + '/' + key; using T = std::decay_t; if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 3); + if (polys_attrs.count(full_key) == 0) { + polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 3); } auto samp = OFloatGeomParam::Sample(); std::vector v(arr.size() * 3); @@ -277,21 +284,21 @@ void write_attrs(std::map &attrs, std::string path, std:: v[i * 3 + 2] = arr[i][2]; } samp.setVals(v); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(polys_attrs[full_key]).set(samp); } else if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 1); + if (polys_attrs.count(full_key) == 0) { + polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 1); } auto samp = OFloatGeomParam::Sample(); samp.setVals(arr); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(polys_attrs[full_key]).set(samp); } else if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kUniformScope, 1); + if (polys_attrs.count(full_key) == 0) { + polys_attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kUniformScope, 1); } auto samp = OInt32GeomParam::Sample(); samp.setVals(arr); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(polys_attrs[full_key]).set(samp); } }); } @@ -304,8 +311,8 @@ void write_attrs(std::map &attrs, std::string path, std:: std::string full_key = path + '/' + key; using T = std::decay_t; if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 3); + if (polys_attrs.count(full_key) == 0) { + polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 3); } auto samp = OFloatGeomParam::Sample(); std::vector v(arr.size() * 3); @@ -315,22 +322,22 @@ void write_attrs(std::map &attrs, std::string path, std:: v[i * 3 + 2] = arr[i][2]; } samp.setVals(v); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(polys_attrs[full_key]).set(samp); } else if constexpr (std::is_same_v) { // zeno::log_info("std::is_same_v"); - if (attrs.count(full_key) == 0) { - attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 1); + if (polys_attrs.count(full_key) == 0) { + polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 1); } auto samp = OFloatGeomParam::Sample(); samp.setVals(arr); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(polys_attrs[full_key]).set(samp); } else if constexpr (std::is_same_v) { - if (attrs.count(full_key) == 0) { - attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kUniformScope, 1); + if (polys_attrs.count(full_key) == 0) { + polys_attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kUniformScope, 1); } auto samp = OInt32GeomParam::Sample(); samp.setVals(arr); - std::any_cast(attrs[full_key]).set(samp); + std::any_cast(polys_attrs[full_key]).set(samp); } }); } @@ -467,7 +474,9 @@ struct WriteAlembic2 : INode { OArchive archive; OPolyMesh meshyObj; std::string usedPath; - std::map attrs; + std::map verts_attrs; + std::map loops_attrs; + std::map polys_attrs; std::map user_attrs; std::map o_faceset; std::map o_faceset_schema; @@ -502,7 +511,9 @@ struct WriteAlembic2 : INode { ); real_frame_start = -1; meshyObj = OPolyMesh( OObject( archive, 1 ), "mesh" ); - attrs.clear(); + verts_attrs.clear(); + loops_attrs.clear(); + polys_attrs.clear(); user_attrs.clear(); } if (!(frame_start <= frameid && frameid <= frame_end)) { @@ -574,7 +585,7 @@ struct WriteAlembic2 : INode { uvsamp); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(attrs, "", prim, mesh, mesh_samp); + write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh); mesh.set( mesh_samp ); } else { @@ -584,7 +595,7 @@ struct WriteAlembic2 : INode { Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(attrs, "", prim, mesh, mesh_samp); + write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh); mesh.set( mesh_samp ); } } @@ -623,7 +634,7 @@ struct WriteAlembic2 : INode { uvsamp); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(attrs, "", prim, mesh, mesh_samp); + write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh); mesh.set( mesh_samp ); } else { OPolyMeshSchema::Sample mesh_samp( @@ -632,7 +643,7 @@ struct WriteAlembic2 : INode { Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(attrs, "", prim, mesh, mesh_samp); + write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh); mesh.set( mesh_samp ); } } @@ -660,7 +671,9 @@ struct WriteAlembicPrims : INode { OArchive archive; std::string usedPath; std::map meshyObjs; - std::map attrs; + std::map verts_attrs; + std::map loops_attrs; + std::map polys_attrs; std::map user_attrs; std::map> o_faceset; std::map> o_faceset_schema; @@ -758,7 +771,9 @@ struct WriteAlembicPrims : INode { "None" ); meshyObjs.clear(); - attrs.clear(); + verts_attrs.clear(); + loops_attrs.clear(); + polys_attrs.clear(); user_attrs.clear(); o_faceset.clear(); o_faceset_schema.clear(); @@ -857,7 +872,7 @@ struct WriteAlembicPrims : INode { uvsamp); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(attrs, path, prim, mesh, mesh_samp); + write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh); mesh.set( mesh_samp ); } else { @@ -867,7 +882,7 @@ struct WriteAlembicPrims : INode { Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(attrs, path, prim, mesh, mesh_samp); + write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh); mesh.set( mesh_samp ); } } @@ -906,7 +921,7 @@ struct WriteAlembicPrims : INode { uvsamp); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(attrs, path, prim, mesh, mesh_samp); + write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh); mesh.set( mesh_samp ); } else { OPolyMeshSchema::Sample mesh_samp( @@ -915,7 +930,7 @@ struct WriteAlembicPrims : INode { Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(attrs, path, prim, mesh, mesh_samp); + write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh); mesh.set( mesh_samp ); } } From c77add20435b5e8d59b07739ef50b9d048f56131 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Mon, 25 Mar 2024 19:58:24 +0800 Subject: [PATCH 08/17] ReadAlembic --- projects/Alembic/ReadAlembic.cpp | 283 +++++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) diff --git a/projects/Alembic/ReadAlembic.cpp b/projects/Alembic/ReadAlembic.cpp index 8059856c48..e424378a5c 100644 --- a/projects/Alembic/ReadAlembic.cpp +++ b/projects/Alembic/ReadAlembic.cpp @@ -74,7 +74,290 @@ static void read_velocity(std::shared_ptr prim, V3fArraySampleP } } } +template +void attr_from_data(std::shared_ptr prim, GeometryScope scope, std::string attr_name, std::vector &data) { + if (scope == GeometryScope::kUniformScope) { + if (prim->polys.size() == data.size()) { + auto &attr = prim->polys.add_attr(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = data[i]; + } + } + else if (prim->polys.size() * 2 == data.size()) { + auto &attr = prim->polys.add_attr>(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = {data[2 * i], data[2 * i + 1]}; + } + } + else if (prim->polys.size() * 3 == data.size()) { + auto &attr = prim->polys.add_attr>(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = {data[3 * i], data[3 * i + 1], data[3 * i + 2]}; + } + } + else if (prim->polys.size() * 4 == data.size()) { + auto &attr = prim->polys.add_attr>(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = {data[4 * i], data[4 * i + 1], data[4 * i + 2], data[4 * i + 3]}; + } + } + else { + log_warn("[alembic] can not load {} attr {}: {} in kUniformScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + } + else if (scope == GeometryScope::kFacevaryingScope) { + if (prim->loops.size() == data.size()) { + auto &attr = prim->loops.add_attr(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = data[i]; + } + } + else if (prim->loops.size() * 2 == data.size()) { + auto &attr = prim->loops.add_attr>(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = {data[2 * i], data[2 * i + 1]}; + } + } + else if (prim->loops.size() * 3 == data.size()) { + auto &attr = prim->loops.add_attr>(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = {data[3 * i], data[3 * i + 1], data[3 * i + 2]}; + } + } + else if (prim->loops.size() * 4 == data.size()) { + auto &attr = prim->loops.add_attr>(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = {data[4 * i], data[4 * i + 1], data[4 * i + 2], data[4 * i + 3]}; + } + } + else { + log_warn("[alembic] can not load {} attr {}: {} in kFacevaryingScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + } + else { + if (prim->verts.size() == data.size()) { + auto &attr = prim->verts.add_attr(attr_name); + for (auto i = 0; i < prim->verts.size(); i++) { + attr[i] = data[i]; + } + } + else if (prim->verts.size() * 2 == data.size()) { + auto &attr = prim->verts.add_attr>(attr_name); + for (auto i = 0; i < prim->verts.size(); i++) { + attr[i] = {data[2 * i], data[2 * i + 1]}; + } + } + else if (prim->verts.size() * 3 == data.size()) { + auto &attr = prim->verts.add_attr>(attr_name); + for (auto i = 0; i < prim->verts.size(); i++) { + attr[i] = {data[3 * i], data[3 * i + 1], data[3 * i + 2]}; + } + } + else if (prim->verts.size() * 4 == data.size()) { + auto &attr = prim->verts.add_attr>(attr_name); + for (auto i = 0; i < prim->verts.size(); i++) { + attr[i] = {data[4 * i], data[4 * i + 1], data[4 * i + 2], data[4 * i + 3]}; + } + } + else if (prim->polys.size() == data.size()) { + auto &attr = prim->polys.add_attr(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = data[i]; + } + } + else if (prim->polys.size() * 2 == data.size()) { + auto &attr = prim->polys.add_attr>(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = {data[2 * i], data[2 * i + 1]}; + } + } + else if (prim->polys.size() * 3 == data.size()) { + auto &attr = prim->polys.add_attr>(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = {data[3 * i], data[3 * i + 1], data[3 * i + 2]}; + } + } + else if (prim->polys.size() * 4 == data.size()) { + auto &attr = prim->polys.add_attr>(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = {data[4 * i], data[4 * i + 1], data[4 * i + 2], data[4 * i + 3]}; + } + } + else if (prim->loops.size() == data.size()) { + auto &attr = prim->loops.add_attr(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = data[i]; + } + } + else if (prim->loops.size() * 2 == data.size()) { + auto &attr = prim->loops.add_attr>(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = {data[2 * i], data[2 * i + 1]}; + } + } + else if (prim->loops.size() * 3 == data.size()) { + auto &attr = prim->loops.add_attr>(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = {data[3 * i], data[3 * i + 1], data[3 * i + 2]}; + } + } + else if (prim->loops.size() * 4 == data.size()) { + auto &attr = prim->loops.add_attr>(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = {data[4 * i], data[4 * i + 1], data[4 * i + 2], data[4 * i + 3]}; + } + } + else { + if (scope == GeometryScope::kVaryingScope) { + log_warn("[alembic] can not load {} attr {}: {} in kVaryingScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + else if (scope == GeometryScope::kVertexScope) { + log_warn("[alembic] can not load {} attr {}: {} in kVertexScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + else if (scope == GeometryScope::kUnknownScope) { + log_warn("[alembic] can not load {} attr {}: {} in kUnknownScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + } + } +} +template +void attr_from_data_vec(std::shared_ptr prim, GeometryScope scope, std::string attr_name, std::vector &data) { + if (scope == GeometryScope::kUniformScope) { + if (prim->polys.size() == data.size()) { + auto &attr = prim->polys.add_attr(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = data[i]; + } + } + else { + log_warn("[alembic] can not load {} attr {}: {} in kUniformScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + } + else if (scope == GeometryScope::kFacevaryingScope) { + if (prim->loops.size() == data.size()) { + auto &attr = prim->loops.add_attr(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = data[i]; + } + } + else { + log_warn("[alembic] can not load {} attr {}: {} in kFacevaryingScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + } + else { + if (prim->verts.size() == data.size()) { + auto &attr = prim->verts.add_attr(attr_name); + for (auto i = 0; i < prim->verts.size(); i++) { + attr[i] = data[i]; + } + } + else if (prim->polys.size() == data.size()) { + auto &attr = prim->polys.add_attr(attr_name); + for (auto i = 0; i < prim->polys.size(); i++) { + attr[i] = data[i]; + } + } + else if (prim->loops.size() == data.size()) { + auto &attr = prim->loops.add_attr(attr_name); + for (auto i = 0; i < prim->loops.size(); i++) { + attr[i] = data[i]; + } + } + else { + if (scope == GeometryScope::kVaryingScope) { + log_warn("[alembic] can not load {} attr {}: {} in kVaryingScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + else if (scope == GeometryScope::kVertexScope) { + log_warn("[alembic] can not load {} attr {}: {} in kVertexScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + else if (scope == GeometryScope::kUnknownScope) { + log_warn("[alembic] can not load {} attr {}: {} in kUnknownScope scope.", typeid(data[0]).name(), attr_name, data.size()); + } + } + } +} +static void read_attributes2(std::shared_ptr prim, ICompoundProperty arbattrs, const ISampleSelector &iSS, bool read_done) { + if (!arbattrs) { + return; + } + size_t numProps = arbattrs.getNumProperties(); + for (auto i = 0; i < numProps; i++) { + PropertyHeader p = arbattrs.getPropertyHeader(i); + if (IFloatGeomParam::matches(p)) { + IFloatGeomParam param(arbattrs, p.getName()); + IFloatGeomParam::Sample samp = param.getIndexedValue(iSS); + std::vector data; + data.resize(samp.getVals()->size()); + for (auto i = 0; i < samp.getVals()->size(); i++) { + data[i] = samp.getVals()->get()[i]; + } + if (!read_done) { + log_info("[alembic] float attr {}, len {}.", p.getName(), data.size()); + } + attr_from_data(prim, samp.getScope(), p.getName(), data); + } + else if (IInt32GeomParam::matches(p)) { + IInt32GeomParam param(arbattrs, p.getName()); + + IInt32GeomParam::Sample samp = param.getIndexedValue(iSS); + std::vector data; + data.resize(samp.getVals()->size()); + for (auto i = 0; i < samp.getVals()->size(); i++) { + data[i] = samp.getVals()->get()[i]; + } + if (!read_done) { + log_info("[alembic] int attr {}, len {}.", p.getName(), data.size()); + } + attr_from_data(prim, samp.getScope(), p.getName(), data); + } + else if (IV3fGeomParam::matches(p)) { + IV3fGeomParam param(arbattrs, p.getName()); + + IV3fGeomParam::Sample samp = param.getIndexedValue(iSS); + std::vector data; + data.resize(samp.getVals()->size()); + for (auto i = 0; i < samp.getVals()->size(); i++) { + auto v = samp.getVals()->get()[i]; + data[i] = {v[0], v[1], v[2]}; + } + if (!read_done) { + log_info("[alembic] V3f attr {}, len {}.", p.getName(), data.size()); + } + attr_from_data_vec(prim, samp.getScope(), p.getName(), data); + } + else if (IN3fGeomParam::matches(p)) { + IN3fGeomParam param(arbattrs, p.getName()); + + IN3fGeomParam::Sample samp = param.getIndexedValue(iSS); + std::vector data; + data.resize(samp.getVals()->size()); + for (auto i = 0; i < samp.getVals()->size(); i++) { + auto v = samp.getVals()->get()[i]; + data[i] = {v[0], v[1], v[2]}; + } + if (!read_done) { + log_info("[alembic] N3f attr {}, len {}.", p.getName(), data.size()); + } + attr_from_data_vec(prim, samp.getScope(), p.getName(), data); + } + else if (IC3fGeomParam::matches(p)) { + IC3fGeomParam param(arbattrs, p.getName()); + + IC3fGeomParam::Sample samp = param.getIndexedValue(iSS); + std::vector data; + data.resize(samp.getVals()->size()); + for (auto i = 0; i < samp.getVals()->size(); i++) { + auto v = samp.getVals()->get()[i]; + data[i] = {v[0], v[1], v[2]}; + } + if (!read_done) { + log_info("[alembic] C3f attr {}, len {}.", p.getName(), data.size()); + } + attr_from_data_vec(prim, samp.getScope(), p.getName(), data); + } + } +} static void read_attributes(std::shared_ptr prim, ICompoundProperty arbattrs, const ISampleSelector &iSS, bool read_done) { if (!arbattrs) { return; From c20c04938632dfa0be8b867546980d317e28d283 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Tue, 26 Mar 2024 14:31:24 +0800 Subject: [PATCH 09/17] improve --- projects/Alembic/ReadAlembic.cpp | 213 +------------------------------ 1 file changed, 4 insertions(+), 209 deletions(-) diff --git a/projects/Alembic/ReadAlembic.cpp b/projects/Alembic/ReadAlembic.cpp index e424378a5c..72a07be5b2 100644 --- a/projects/Alembic/ReadAlembic.cpp +++ b/projects/Alembic/ReadAlembic.cpp @@ -358,211 +358,6 @@ static void read_attributes2(std::shared_ptr prim, ICompoundPro } } } -static void read_attributes(std::shared_ptr prim, ICompoundProperty arbattrs, const ISampleSelector &iSS, bool read_done) { - if (!arbattrs) { - return; - } - size_t numProps = arbattrs.getNumProperties(); - for (auto i = 0; i < numProps; i++) { - PropertyHeader p = arbattrs.getPropertyHeader(i); - if (IFloatGeomParam::matches(p)) { - IFloatGeomParam param(arbattrs, p.getName()); - - IFloatGeomParam::Sample samp = param.getIndexedValue(iSS); - std::vector data; - data.resize(samp.getVals()->size()); - for (auto i = 0; i < samp.getVals()->size(); i++) { - data[i] = samp.getVals()->get()[i]; - } - if (!read_done) { - log_info("[alembic] float attr {}, len {}.", p.getName(), data.size()); - } - - if (prim->verts.size() == data.size()) { - auto &attr = prim->add_attr(p.getName()); - for (auto i = 0; i < prim->verts.size(); i++) { - attr[i] = data[i]; - } - } - else if (prim->verts.size() * 3 == data.size()) { - auto &attr = prim->add_attr(p.getName()); - for (auto i = 0; i < prim->verts.size(); i++) { - attr[i] = { data[ 3 * i], data[3 * i + 1], data[3 * i + 2]}; - } - } - else if (prim->polys.size() == data.size()) { - auto &attr = prim->polys.add_attr(p.getName()); - for (auto i = 0; i < prim->polys.size(); i++) { - attr[i] = data[i]; - } - } - else if (prim->polys.size() * 3 == data.size()) { - auto &attr = prim->polys.add_attr(p.getName()); - for (auto i = 0; i < prim->polys.size(); i++) { - attr[i] = { data[ 3 * i], data[3 * i + 1], data[3 * i + 2]}; - } - } - else if (prim->loops.size() == data.size()) { - auto &attr = prim->loops.add_attr(p.getName()); - for (auto i = 0; i < prim->loops.size(); i++) { - attr[i] = data[i]; - } - } - else if (prim->loops.size() * 3 == data.size()) { - auto &attr = prim->loops.add_attr(p.getName()); - for (auto i = 0; i < prim->loops.size(); i++) { - attr[i] = { data[ 3 * i], data[3 * i + 1], data[3 * i + 2]}; - } - } - else { - if (!read_done) { - log_warn("[alembic] can not load float attr {}: {}.", p.getName(), data.size()); - } - } - } - else if (IInt32GeomParam::matches(p)) { - IInt32GeomParam param(arbattrs, p.getName()); - - IInt32GeomParam::Sample samp = param.getIndexedValue(iSS); - std::vector data; - data.resize(samp.getVals()->size()); - for (auto i = 0; i < samp.getVals()->size(); i++) { - data[i] = samp.getVals()->get()[i]; - } - if (!read_done) { - log_info("[alembic] i32 attr {}, len {}.", p.getName(), data.size()); - } - - if (prim->verts.size() == data.size()) { - auto &attr = prim->add_attr(p.getName()); - for (auto i = 0; i < prim->verts.size(); i++) { - attr[i] = data[i]; - } - } - else if (prim->loops.size() == data.size()) { - auto &attr = prim->loops.add_attr(p.getName()); - for (auto i = 0; i < prim->loops.size(); i++) { - attr[i] = data[i]; - } - } - else if (prim->polys.size() == data.size()) { - auto &attr = prim->polys.add_attr(p.getName()); - for (auto i = 0; i < prim->polys.size(); i++) { - attr[i] = data[i]; - } - } - else { - if (!read_done) { - log_warn("[alembic] can not load int attr {}:{}.", p.getName(), data.size()); - } - } - } - else if (IV3fGeomParam::matches(p)) { - IV3fGeomParam param(arbattrs, p.getName()); - if (!read_done) { - log_info("[alembic] vec3f attr {}.", p.getName()); - } - IV3fGeomParam::Sample samp = param.getIndexedValue(iSS); - if (prim->verts.size() == samp.getVals()->size()) { - auto &attr = prim->add_attr(p.getName()); - for (auto i = 0; i < prim->verts.size(); i++) { - auto v = samp.getVals()->get()[i]; - attr[i] = {v[0], v[1], v[2]}; - } - } - else if (prim->loops.size() == samp.getVals()->size()) { - auto &attr = prim->loops.add_attr(p.getName()); - for (auto i = 0; i < prim->loops.size(); i++) { - auto v = samp.getVals()->get()[i]; - attr[i] = {v[0], v[1], v[2]}; - } - } - else if (prim->polys.size() == samp.getVals()->size()) { - auto &attr = prim->polys.add_attr(p.getName()); - for (auto i = 0; i < prim->polys.size(); i++) { - auto v = samp.getVals()->get()[i]; - attr[i] = {v[0], v[1], v[2]}; - } - } - else { - if (!read_done) { - log_warn("[alembic] can not load vec3f attr {}:{}.", p.getName(), int(samp.getVals()->size())); - } - } - } - else if (IN3fGeomParam::matches(p)) { - if (!read_done) { - log_info("[alembic] IN3fGeomParam attr {}.", p.getName()); - } - IN3fGeomParam param(arbattrs, p.getName()); - IN3fGeomParam::Sample samp = param.getIndexedValue(iSS); - if (prim->verts.size() == samp.getVals()->size()) { - auto &attr = prim->add_attr(p.getName()); - for (auto i = 0; i < prim->verts.size(); i++) { - auto v = samp.getVals()->get()[i]; - attr[i] = {v[0], v[1], v[2]}; - } - } - else if (prim->loops.size() == samp.getVals()->size()) { - auto &attr = prim->loops.add_attr(p.getName()); - for (auto i = 0; i < prim->loops.size(); i++) { - auto v = samp.getVals()->get()[i]; - attr[i] = {v[0], v[1], v[2]}; - } - } - else if (prim->polys.size() == samp.getVals()->size()) { - auto &attr = prim->polys.add_attr(p.getName()); - for (auto i = 0; i < prim->polys.size(); i++) { - auto v = samp.getVals()->get()[i]; - attr[i] = {v[0], v[1], v[2]}; - } - } - else { - if (!read_done) { - log_warn("[alembic] can not load N3f attr {}:{}.", p.getName(), int(samp.getVals()->size())); - } - } - } - else if (IC3fGeomParam::matches(p)) { - if (!read_done) { - log_info("[alembic] IC3fGeomParam attr {}.", p.getName()); - } - IC3fGeomParam param(arbattrs, p.getName()); - IC3fGeomParam::Sample samp = param.getIndexedValue(iSS); - if (prim->verts.size() == samp.getVals()->size()) { - auto &attr = prim->add_attr(p.getName()); - for (auto i = 0; i < prim->verts.size(); i++) { - auto v = samp.getVals()->get()[i]; - attr[i] = {v[0], v[1], v[2]}; - } - } - else if (prim->loops.size() == samp.getVals()->size()) { - auto &attr = prim->loops.add_attr(p.getName()); - for (auto i = 0; i < prim->loops.size(); i++) { - auto v = samp.getVals()->get()[i]; - attr[i] = {v[0], v[1], v[2]}; - } - } - else if (prim->polys.size() == samp.getVals()->size()) { - auto &attr = prim->polys.add_attr(p.getName()); - for (auto i = 0; i < prim->polys.size(); i++) { - auto v = samp.getVals()->get()[i]; - attr[i] = {v[0], v[1], v[2]}; - } - } - else { - if (!read_done) { - log_warn("[alembic] can not load C3f attr {}:{}.", p.getName(), int(samp.getVals()->size())); - } - } - } - else { - if (!read_done) { - log_warn("[alembic] can not load attr {}..", p.getName()); - } - } - } -} static void read_user_data(std::shared_ptr prim, ICompoundProperty arbattrs, const ISampleSelector &iSS, bool read_done) { if (!arbattrs) { @@ -760,7 +555,7 @@ static std::shared_ptr foundABCMesh( } } ICompoundProperty arbattrs = mesh.getArbGeomParams(); - read_attributes(prim, arbattrs, iSS, read_done); + read_attributes2(prim, arbattrs, iSS, read_done); ICompoundProperty usrData = mesh.getUserProperties(); read_user_data(prim, usrData, iSS, read_done); @@ -909,7 +704,7 @@ static std::shared_ptr foundABCSubd(Alembic::AbcGeom::ISubDSche } } ICompoundProperty arbattrs = subd.getArbGeomParams(); - read_attributes(prim, arbattrs, iSS, read_done); + read_attributes2(prim, arbattrs, iSS, read_done); ICompoundProperty usrData = subd.getUserProperties(); read_user_data(prim, usrData, iSS, read_done); @@ -1005,7 +800,7 @@ static std::shared_ptr foundABCPoints(Alembic::AbcGeom::IPoints } read_velocity(prim, mesamp.getVelocities(), read_done); ICompoundProperty arbattrs = mesh.getArbGeomParams(); - read_attributes(prim, arbattrs, iSS, read_done); + read_attributes2(prim, arbattrs, iSS, read_done); ICompoundProperty usrData = mesh.getUserProperties(); read_user_data(prim, usrData, iSS, read_done); return prim; @@ -1050,7 +845,7 @@ static std::shared_ptr foundABCCurves(Alembic::AbcGeom::ICurves } } ICompoundProperty arbattrs = mesh.getArbGeomParams(); - read_attributes(prim, arbattrs, iSS, read_done); + read_attributes2(prim, arbattrs, iSS, read_done); ICompoundProperty usrData = mesh.getUserProperties(); read_user_data(prim, usrData, iSS, read_done); return prim; From 19190b29e8c022773a5cb6bd5b88a8ffcc1de477 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Wed, 27 Mar 2024 14:36:59 +0800 Subject: [PATCH 10/17] write userdata when empty --- projects/Alembic/WriteAlembic.cpp | 66 +++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/projects/Alembic/WriteAlembic.cpp b/projects/Alembic/WriteAlembic.cpp index fa252e3e33..97adaa7306 100644 --- a/projects/Alembic/WriteAlembic.cpp +++ b/projects/Alembic/WriteAlembic.cpp @@ -342,7 +342,14 @@ void write_attrs( }); } } -void write_user_data(std::map &user_attrs, std::string path, std::shared_ptr prim, OCompoundProperty& user) { +void write_user_data( + std::map &user_attrs + , std::string path + , std::shared_ptr prim + , OCompoundProperty& user + , int frameid + , int real_frame_start +) { auto &ud = prim->userData(); for (const auto& [key, value] : ud.m_data) { std::string full_key = path + '/' + key; @@ -360,6 +367,11 @@ void write_user_data(std::map &user_attrs, std::string pa auto p = OInt32Property(user, key); p.setTimeSampling(1); user_attrs[full_key] = p; + if (real_frame_start != frameid) { + for (auto i = real_frame_start; i < frameid; i++) { + p.set({}); + } + } } std::any_cast(user_attrs[full_key]).set(ud.get2(key)); } @@ -368,6 +380,11 @@ void write_user_data(std::map &user_attrs, std::string pa auto p = OFloatProperty(user, key); p.setTimeSampling(1); user_attrs[full_key] = p; + if (real_frame_start != frameid) { + for (auto i = real_frame_start; i < frameid; i++) { + p.set({}); + } + } } std::any_cast(user_attrs[full_key]).set(ud.get2(key)); } @@ -376,6 +393,11 @@ void write_user_data(std::map &user_attrs, std::string pa auto p = OV2iProperty(user, key); p.setTimeSampling(1); user_attrs[full_key] = p; + if (real_frame_start != frameid) { + for (auto i = real_frame_start; i < frameid; i++) { + p.set({}); + } + } } auto v = ud.get2(key); std::any_cast(user_attrs[full_key]).set(Imath::V2i(v[0], v[1])); @@ -385,6 +407,11 @@ void write_user_data(std::map &user_attrs, std::string pa auto p = OV3iProperty(user, key); p.setTimeSampling(1); user_attrs[full_key] = p; + if (real_frame_start != frameid) { + for (auto i = real_frame_start; i < frameid; i++) { + p.set({}); + } + } } auto v = ud.get2(key); std::any_cast(user_attrs[full_key]).set(Imath::V3i(v[0], v[1], v[2])); @@ -394,6 +421,11 @@ void write_user_data(std::map &user_attrs, std::string pa auto p = OV2fProperty(user, key); p.setTimeSampling(1); user_attrs[full_key] = p; + if (real_frame_start != frameid) { + for (auto i = real_frame_start; i < frameid; i++) { + p.set({}); + } + } } auto v = ud.get2(key); std::any_cast(user_attrs[full_key]).set(Imath::V2f(v[0], v[1])); @@ -403,6 +435,11 @@ void write_user_data(std::map &user_attrs, std::string pa auto p = OV3fProperty(user, key); p.setTimeSampling(1); user_attrs[full_key] = p; + if (real_frame_start != frameid) { + for (auto i = real_frame_start; i < frameid; i++) { + p.set({}); + } + } } auto v = ud.get2(key); std::any_cast(user_attrs[full_key]).set(Imath::V3f(v[0], v[1], v[2])); @@ -412,6 +449,11 @@ void write_user_data(std::map &user_attrs, std::string pa auto p = OStringProperty(user, key); p.setTimeSampling(1); user_attrs[full_key] = p; + if (real_frame_start != frameid) { + for (auto i = real_frame_start; i < frameid; i++) { + p.set({}); + } + } } std::any_cast(user_attrs[full_key]).set(ud.get2(key)); } @@ -480,6 +522,7 @@ struct WriteAlembic2 : INode { std::map user_attrs; std::map o_faceset; std::map o_faceset_schema; + std::map prim_size_per_frame; int real_frame_start = -1; virtual void apply() override { @@ -515,6 +558,7 @@ struct WriteAlembic2 : INode { loops_attrs.clear(); polys_attrs.clear(); user_attrs.clear(); + prim_size_per_frame.clear(); } if (!(frame_start <= frameid && frameid <= frame_end)) { return; @@ -536,7 +580,7 @@ struct WriteAlembic2 : INode { write_faceset(prim, mesh, o_faceset, o_faceset_schema); OCompoundProperty user = mesh.getUserProperties(); - write_user_data(user_attrs, "", prim, user); + write_user_data(user_attrs, "", prim, user, frameid, real_frame_start); mesh.setTimeSampling(1); @@ -553,6 +597,13 @@ struct WriteAlembic2 : INode { std::vector vertex_count_per_face; if (prim->loops.size()) { + { + prim_size_per_frame[frameid] = { + int(prim->verts.size()), + int(prim->loops.size()), + int(prim->polys.size()), + }; + } for (const auto& [start, size]: prim->polys) { for (auto i = 0; i < size; i++) { vertex_index_per_face.push_back(prim->loops[start + i]); @@ -600,6 +651,13 @@ struct WriteAlembic2 : INode { } } else { + { + prim_size_per_frame[frameid] = { + int(prim->verts.size()), + int(prim->tris.size() * 3), + int(prim->tris.size()), + }; + } for (auto i = 0; i < prim->tris.size(); i++) { vertex_index_per_face.push_back(prim->tris[i][0]); vertex_index_per_face.push_back(prim->tris[i][1]); @@ -666,7 +724,7 @@ ZENDEFNODE(WriteAlembic2, { {}, {"alembic"}, }); - +/* struct WriteAlembicPrims : INode { OArchive archive; std::string usedPath; @@ -955,6 +1013,6 @@ ZENDEFNODE(WriteAlembicPrims, { {}, {"alembic"}, }); - +*/ } // namespace } // namespace zeno From db376f23e2d8e80844cd9c15dccd9982053413c7 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Wed, 27 Mar 2024 19:17:01 +0800 Subject: [PATCH 11/17] fix WriteAlembic2 --- projects/Alembic/WriteAlembic.cpp | 85 +++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/projects/Alembic/WriteAlembic.cpp b/projects/Alembic/WriteAlembic.cpp index 97adaa7306..bcf1ed1894 100644 --- a/projects/Alembic/WriteAlembic.cpp +++ b/projects/Alembic/WriteAlembic.cpp @@ -37,7 +37,7 @@ void write_velocity(std::shared_ptr prim, T& mesh_samp) { static void write_normal(std::shared_ptr prim, OPolyMeshSchema::Sample& mesh_samp) { if (prim->verts.has_attr("nrm")) { auto &nrm = (std::vector&)prim->verts.attr("nrm"); - ON3fGeomParam::Sample oNormalsSample(nrm, kFacevaryingScope); + ON3fGeomParam::Sample oNormalsSample(nrm, kVaryingScope); mesh_samp.setNormals(oNormalsSample); } } @@ -194,6 +194,9 @@ void write_attrs( , std::string path , std::shared_ptr prim , T1& schema + , int frameid + , int real_frame_start + , std::map &prim_size_per_frame ) { OCompoundProperty arbAttrs = schema.getArbGeomParams(); prim->verts.foreach_attr>([&](auto const &key, auto &arr) { @@ -205,6 +208,12 @@ void write_attrs( if constexpr (std::is_same_v) { if (verts_attrs.count(full_key) == 0) { verts_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kVaryingScope, 3); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OFloatGeomParam::Sample(); + std::vector v(std::get<0>(prim_size_per_frame[i]) * 3); + samp.setVals(v); + std::any_cast(verts_attrs[full_key]).set(samp); + } } auto samp = OFloatGeomParam::Sample(); std::vector v(arr.size() * 3); @@ -218,6 +227,12 @@ void write_attrs( } else if constexpr (std::is_same_v) { if (verts_attrs.count(full_key) == 0) { verts_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kVaryingScope, 1); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OFloatGeomParam::Sample(); + std::vector v(std::get<0>(prim_size_per_frame[i])); + samp.setVals(v); + std::any_cast(verts_attrs[full_key]).set(samp); + } } auto samp = OFloatGeomParam::Sample(); samp.setVals(arr); @@ -225,6 +240,12 @@ void write_attrs( } else if constexpr (std::is_same_v) { if (verts_attrs.count(full_key) == 0) { verts_attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kVaryingScope, 1); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OInt32GeomParam::Sample(); + std::vector v(std::get<0>(prim_size_per_frame[i])); + samp.setVals(v); + std::any_cast(verts_attrs[full_key]).set(samp); + } } auto samp = OInt32GeomParam::Sample(); samp.setVals(arr); @@ -238,6 +259,12 @@ void write_attrs( if constexpr (std::is_same_v) { if (loops_attrs.count(full_key) == 0) { loops_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kFacevaryingScope, 3); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OFloatGeomParam::Sample(); + std::vector v(std::get<1>(prim_size_per_frame[i]) * 3); + samp.setVals(v); + std::any_cast(loops_attrs[full_key]).set(samp); + } } auto samp = OFloatGeomParam::Sample(); std::vector v(arr.size() * 3); @@ -251,6 +278,12 @@ void write_attrs( } else if constexpr (std::is_same_v) { if (loops_attrs.count(full_key) == 0) { loops_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kFacevaryingScope, 1); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OFloatGeomParam::Sample(); + std::vector v(std::get<1>(prim_size_per_frame[i])); + samp.setVals(v); + std::any_cast(loops_attrs[full_key]).set(samp); + } } auto samp = OFloatGeomParam::Sample(); samp.setVals(arr); @@ -258,6 +291,12 @@ void write_attrs( } else if constexpr (std::is_same_v) { if (loops_attrs.count(full_key) == 0) { loops_attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kFacevaryingScope, 1); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OInt32GeomParam::Sample(); + std::vector v(std::get<1>(prim_size_per_frame[i])); + samp.setVals(v); + std::any_cast(loops_attrs[full_key]).set(samp); + } } auto samp = OInt32GeomParam::Sample(); samp.setVals(arr); @@ -275,6 +314,12 @@ void write_attrs( if constexpr (std::is_same_v) { if (polys_attrs.count(full_key) == 0) { polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 3); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OFloatGeomParam::Sample(); + std::vector v(std::get<2>(prim_size_per_frame[i]) * 3); + samp.setVals(v); + std::any_cast(polys_attrs[full_key]).set(samp); + } } auto samp = OFloatGeomParam::Sample(); std::vector v(arr.size() * 3); @@ -288,6 +333,12 @@ void write_attrs( } else if constexpr (std::is_same_v) { if (polys_attrs.count(full_key) == 0) { polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 1); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OFloatGeomParam::Sample(); + std::vector v(std::get<2>(prim_size_per_frame[i])); + samp.setVals(v); + std::any_cast(polys_attrs[full_key]).set(samp); + } } auto samp = OFloatGeomParam::Sample(); samp.setVals(arr); @@ -295,6 +346,12 @@ void write_attrs( } else if constexpr (std::is_same_v) { if (polys_attrs.count(full_key) == 0) { polys_attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kUniformScope, 1); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OInt32GeomParam::Sample(); + std::vector v(std::get<2>(prim_size_per_frame[i])); + samp.setVals(v); + std::any_cast(polys_attrs[full_key]).set(samp); + } } auto samp = OInt32GeomParam::Sample(); samp.setVals(arr); @@ -313,6 +370,12 @@ void write_attrs( if constexpr (std::is_same_v) { if (polys_attrs.count(full_key) == 0) { polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 3); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OFloatGeomParam::Sample(); + std::vector v(std::get<2>(prim_size_per_frame[i]) * 3); + samp.setVals(v); + std::any_cast(polys_attrs[full_key]).set(samp); + } } auto samp = OFloatGeomParam::Sample(); std::vector v(arr.size() * 3); @@ -327,6 +390,12 @@ void write_attrs( // zeno::log_info("std::is_same_v"); if (polys_attrs.count(full_key) == 0) { polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 1); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OFloatGeomParam::Sample(); + std::vector v(std::get<2>(prim_size_per_frame[i])); + samp.setVals(v); + std::any_cast(polys_attrs[full_key]).set(samp); + } } auto samp = OFloatGeomParam::Sample(); samp.setVals(arr); @@ -334,6 +403,12 @@ void write_attrs( } else if constexpr (std::is_same_v) { if (polys_attrs.count(full_key) == 0) { polys_attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kUniformScope, 1); + for (auto i = real_frame_start; i < frameid; i++) { + auto samp = OInt32GeomParam::Sample(); + std::vector v(std::get<2>(prim_size_per_frame[i])); + samp.setVals(v); + std::any_cast(polys_attrs[full_key]).set(samp); + } } auto samp = OInt32GeomParam::Sample(); samp.setVals(arr); @@ -636,7 +711,7 @@ struct WriteAlembic2 : INode { uvsamp); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh); + write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh, frameid, real_frame_start, prim_size_per_frame); mesh.set( mesh_samp ); } else { @@ -646,7 +721,7 @@ struct WriteAlembic2 : INode { Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh); + write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh, frameid, real_frame_start, prim_size_per_frame); mesh.set( mesh_samp ); } } @@ -692,7 +767,7 @@ struct WriteAlembic2 : INode { uvsamp); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh); + write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh, frameid, real_frame_start, prim_size_per_frame); mesh.set( mesh_samp ); } else { OPolyMeshSchema::Sample mesh_samp( @@ -701,7 +776,7 @@ struct WriteAlembic2 : INode { Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh); + write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh, frameid, real_frame_start, prim_size_per_frame); mesh.set( mesh_samp ); } } From a7d171d2ef2ae300ed83f299a770b46525006029 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Thu, 28 Mar 2024 13:11:22 +0800 Subject: [PATCH 12/17] avoid write uvs on loops --- projects/Alembic/WriteAlembic.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/projects/Alembic/WriteAlembic.cpp b/projects/Alembic/WriteAlembic.cpp index bcf1ed1894..0842362e71 100644 --- a/projects/Alembic/WriteAlembic.cpp +++ b/projects/Alembic/WriteAlembic.cpp @@ -254,6 +254,9 @@ void write_attrs( }); if (prim->loops.size() > 0) { prim->loops.foreach_attr>([&](auto const &key, auto &arr) { + if (key == "uvs") { + return; + } std::string full_key = path + '/' + key; using T = std::decay_t; if constexpr (std::is_same_v) { From ba9c2bc4822ae935d8d4b0746f55298011a150f7 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Thu, 28 Mar 2024 14:37:09 +0800 Subject: [PATCH 13/17] WriteAlembicPrims --- projects/Alembic/WriteAlembic.cpp | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/projects/Alembic/WriteAlembic.cpp b/projects/Alembic/WriteAlembic.cpp index 0842362e71..b5122726d2 100644 --- a/projects/Alembic/WriteAlembic.cpp +++ b/projects/Alembic/WriteAlembic.cpp @@ -802,7 +802,7 @@ ZENDEFNODE(WriteAlembic2, { {}, {"alembic"}, }); -/* + struct WriteAlembicPrims : INode { OArchive archive; std::string usedPath; @@ -813,6 +813,7 @@ struct WriteAlembicPrims : INode { std::map user_attrs; std::map> o_faceset; std::map> o_faceset_schema; + std::map> prim_size_per_frame; int real_frame_start = -1; virtual void apply() override { @@ -913,6 +914,7 @@ struct WriteAlembicPrims : INode { user_attrs.clear(); o_faceset.clear(); o_faceset_schema.clear(); + prim_size_per_frame.clear(); real_frame_start = -1; for (auto prim: new_prims) { auto path = prim->userData().get2("abcpath_0"); @@ -959,7 +961,7 @@ struct WriteAlembicPrims : INode { write_faceset(prim, mesh, o_faceset[path], o_faceset_schema[path]); OCompoundProperty user = mesh.getUserProperties(); - write_user_data(user_attrs, path, prim, user); + write_user_data(user_attrs, path, prim, user, frameid, real_frame_start); mesh.setTimeSampling(1); @@ -976,6 +978,13 @@ struct WriteAlembicPrims : INode { std::vector vertex_count_per_face; if (prim->loops.size()) { + { + prim_size_per_frame[path][frameid] = { + int(prim->verts.size()), + int(prim->loops.size()), + int(prim->polys.size()), + }; + } for (const auto& [start, size]: prim->polys) { for (auto i = 0; i < size; i++) { vertex_index_per_face.push_back(prim->loops[start + i]); @@ -1008,7 +1017,7 @@ struct WriteAlembicPrims : INode { uvsamp); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh); + write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh, frameid, real_frame_start, prim_size_per_frame[path]); mesh.set( mesh_samp ); } else { @@ -1018,11 +1027,18 @@ struct WriteAlembicPrims : INode { Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh); + write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh, frameid, real_frame_start, prim_size_per_frame[path]); mesh.set( mesh_samp ); } } else { + { + prim_size_per_frame[path][frameid] = { + int(prim->verts.size()), + int(prim->tris.size() * 3), + int(prim->tris.size()), + }; + } for (auto i = 0; i < prim->tris.size(); i++) { vertex_index_per_face.push_back(prim->tris[i][0]); vertex_index_per_face.push_back(prim->tris[i][1]); @@ -1057,7 +1073,7 @@ struct WriteAlembicPrims : INode { uvsamp); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh); + write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh, frameid, real_frame_start, prim_size_per_frame[path]); mesh.set( mesh_samp ); } else { OPolyMeshSchema::Sample mesh_samp( @@ -1066,7 +1082,7 @@ struct WriteAlembicPrims : INode { Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); write_velocity(prim, mesh_samp); write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh); + write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh, frameid, real_frame_start, prim_size_per_frame[path]); mesh.set( mesh_samp ); } } @@ -1091,6 +1107,6 @@ ZENDEFNODE(WriteAlembicPrims, { {}, {"alembic"}, }); -*/ + } // namespace } // namespace zeno From ccc465a29fa70475c16b460851c861d354b32116 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Fri, 29 Mar 2024 13:14:27 +0800 Subject: [PATCH 14/17] primPolygonate-triangles-before-write --- projects/Alembic/WriteAlembic.cpp | 177 ++---------------------------- 1 file changed, 8 insertions(+), 169 deletions(-) diff --git a/projects/Alembic/WriteAlembic.cpp b/projects/Alembic/WriteAlembic.cpp index b5122726d2..afc60f7028 100644 --- a/projects/Alembic/WriteAlembic.cpp +++ b/projects/Alembic/WriteAlembic.cpp @@ -362,63 +362,6 @@ void write_attrs( } }); } - if (prim->tris.size() > 0) { - prim->tris.foreach_attr>([&](auto const &key, auto &arr) { - if (key == "faceset" || key == "matid" || key == "abcpath") { - return; - } - // zeno::log_info("{} {}", key, int(arr.size())); - std::string full_key = path + '/' + key; - using T = std::decay_t; - if constexpr (std::is_same_v) { - if (polys_attrs.count(full_key) == 0) { - polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 3); - for (auto i = real_frame_start; i < frameid; i++) { - auto samp = OFloatGeomParam::Sample(); - std::vector v(std::get<2>(prim_size_per_frame[i]) * 3); - samp.setVals(v); - std::any_cast(polys_attrs[full_key]).set(samp); - } - } - auto samp = OFloatGeomParam::Sample(); - std::vector v(arr.size() * 3); - for (auto i = 0; i < arr.size(); i++) { - v[i * 3 + 0] = arr[i][0]; - v[i * 3 + 1] = arr[i][1]; - v[i * 3 + 2] = arr[i][2]; - } - samp.setVals(v); - std::any_cast(polys_attrs[full_key]).set(samp); - } else if constexpr (std::is_same_v) { - // zeno::log_info("std::is_same_v"); - if (polys_attrs.count(full_key) == 0) { - polys_attrs[full_key] = OFloatGeomParam(arbAttrs.getPtr(), key, false, kUniformScope, 1); - for (auto i = real_frame_start; i < frameid; i++) { - auto samp = OFloatGeomParam::Sample(); - std::vector v(std::get<2>(prim_size_per_frame[i])); - samp.setVals(v); - std::any_cast(polys_attrs[full_key]).set(samp); - } - } - auto samp = OFloatGeomParam::Sample(); - samp.setVals(arr); - std::any_cast(polys_attrs[full_key]).set(samp); - } else if constexpr (std::is_same_v) { - if (polys_attrs.count(full_key) == 0) { - polys_attrs[full_key] = OInt32GeomParam (arbAttrs.getPtr(), key, false, kUniformScope, 1); - for (auto i = real_frame_start; i < frameid; i++) { - auto samp = OInt32GeomParam::Sample(); - std::vector v(std::get<2>(prim_size_per_frame[i])); - samp.setVals(v); - std::any_cast(polys_attrs[full_key]).set(samp); - } - } - auto samp = OInt32GeomParam::Sample(); - samp.setVals(arr); - std::any_cast(polys_attrs[full_key]).set(samp); - } - }); - } } void write_user_data( std::map &user_attrs @@ -674,7 +617,10 @@ struct WriteAlembic2 : INode { std::vector vertex_index_per_face; std::vector vertex_count_per_face; - if (prim->loops.size()) { + if (prim->tris.size()) { + zeno::primPolygonate(prim.get(), true); + } + { { prim_size_per_frame[frameid] = { int(prim->verts.size()), @@ -728,61 +674,6 @@ struct WriteAlembic2 : INode { mesh.set( mesh_samp ); } } - else { - { - prim_size_per_frame[frameid] = { - int(prim->verts.size()), - int(prim->tris.size() * 3), - int(prim->tris.size()), - }; - } - for (auto i = 0; i < prim->tris.size(); i++) { - vertex_index_per_face.push_back(prim->tris[i][0]); - vertex_index_per_face.push_back(prim->tris[i][1]); - vertex_index_per_face.push_back(prim->tris[i][2]); - } - vertex_count_per_face.resize(prim->tris.size(), 3); - if (prim->tris.has_attr("uv0")) { - std::vector uv_data; - std::vector uv_indices; - auto& uv0 = prim->tris.attr("uv0"); - auto& uv1 = prim->tris.attr("uv1"); - auto& uv2 = prim->tris.attr("uv2"); - for (auto i = 0; i < prim->tris.size(); i++) { - uv_data.emplace_back(uv0[i][0], uv0[i][1]); - uv_data.emplace_back(uv1[i][0], uv1[i][1]); - uv_data.emplace_back(uv2[i][0], uv2[i][1]); - uv_indices.push_back(uv_indices.size()); - uv_indices.push_back(uv_indices.size()); - uv_indices.push_back(uv_indices.size()); - } - - // UVs and Normals use GeomParams, which can be written or read - // as indexed or not, as you'd like. - OV2fGeomParam::Sample uvsamp; - uvsamp.setVals(V2fArraySample( (const V2f *)uv_data.data(), uv_data.size())); - uvsamp.setIndices(UInt32ArraySample( uv_indices.data(), uv_indices.size() )); - uvsamp.setScope(kFacevaryingScope); - OPolyMeshSchema::Sample mesh_samp( - V3fArraySample( ( const V3f * )prim->verts.data(), prim->verts.size() ), - Int32ArraySample( vertex_index_per_face.data(), vertex_index_per_face.size() ), - Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() ), - uvsamp); - write_velocity(prim, mesh_samp); - write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh, frameid, real_frame_start, prim_size_per_frame); - mesh.set( mesh_samp ); - } else { - OPolyMeshSchema::Sample mesh_samp( - V3fArraySample( ( const V3f * )prim->verts.data(), prim->verts.size() ), - Int32ArraySample( vertex_index_per_face.data(), vertex_index_per_face.size() ), - Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); - write_velocity(prim, mesh_samp); - write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, "", prim, mesh, frameid, real_frame_start, prim_size_per_frame); - mesh.set( mesh_samp ); - } - } } } }; @@ -977,7 +868,10 @@ struct WriteAlembicPrims : INode { std::vector vertex_index_per_face; std::vector vertex_count_per_face; - if (prim->loops.size()) { + if (prim->tris.size()) { + zeno::primPolygonate(prim.get(), true); + } + { { prim_size_per_frame[path][frameid] = { int(prim->verts.size()), @@ -1031,61 +925,6 @@ struct WriteAlembicPrims : INode { mesh.set( mesh_samp ); } } - else { - { - prim_size_per_frame[path][frameid] = { - int(prim->verts.size()), - int(prim->tris.size() * 3), - int(prim->tris.size()), - }; - } - for (auto i = 0; i < prim->tris.size(); i++) { - vertex_index_per_face.push_back(prim->tris[i][0]); - vertex_index_per_face.push_back(prim->tris[i][1]); - vertex_index_per_face.push_back(prim->tris[i][2]); - } - vertex_count_per_face.resize(prim->tris.size(), 3); - if (prim->tris.has_attr("uv0")) { - std::vector uv_data; - std::vector uv_indices; - auto& uv0 = prim->tris.attr("uv0"); - auto& uv1 = prim->tris.attr("uv1"); - auto& uv2 = prim->tris.attr("uv2"); - for (auto i = 0; i < prim->tris.size(); i++) { - uv_data.emplace_back(uv0[i][0], uv0[i][1]); - uv_data.emplace_back(uv1[i][0], uv1[i][1]); - uv_data.emplace_back(uv2[i][0], uv2[i][1]); - uv_indices.push_back(uv_indices.size()); - uv_indices.push_back(uv_indices.size()); - uv_indices.push_back(uv_indices.size()); - } - - // UVs and Normals use GeomParams, which can be written or read - // as indexed or not, as you'd like. - OV2fGeomParam::Sample uvsamp; - uvsamp.setVals(V2fArraySample( (const V2f *)uv_data.data(), uv_data.size())); - uvsamp.setIndices(UInt32ArraySample( uv_indices.data(), uv_indices.size() )); - uvsamp.setScope(kFacevaryingScope); - OPolyMeshSchema::Sample mesh_samp( - V3fArraySample( ( const V3f * )prim->verts.data(), prim->verts.size() ), - Int32ArraySample( vertex_index_per_face.data(), vertex_index_per_face.size() ), - Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() ), - uvsamp); - write_velocity(prim, mesh_samp); - write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh, frameid, real_frame_start, prim_size_per_frame[path]); - mesh.set( mesh_samp ); - } else { - OPolyMeshSchema::Sample mesh_samp( - V3fArraySample( ( const V3f * )prim->verts.data(), prim->verts.size() ), - Int32ArraySample( vertex_index_per_face.data(), vertex_index_per_face.size() ), - Int32ArraySample( vertex_count_per_face.data(), vertex_count_per_face.size() )); - write_velocity(prim, mesh_samp); - write_normal(prim, mesh_samp); - write_attrs(verts_attrs, loops_attrs, polys_attrs, path, prim, mesh, frameid, real_frame_start, prim_size_per_frame[path]); - mesh.set( mesh_samp ); - } - } } } } From a165b517a9d348ddabe206ed0445e49a1f5e103f Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Fri, 29 Mar 2024 15:11:52 +0800 Subject: [PATCH 15/17] BoneTransformView --- projects/FBX/FBXSDK.cpp | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/projects/FBX/FBXSDK.cpp b/projects/FBX/FBXSDK.cpp index 5975ef55f1..9e60135789 100644 --- a/projects/FBX/FBXSDK.cpp +++ b/projects/FBX/FBXSDK.cpp @@ -1254,5 +1254,53 @@ ZENDEFNODE(NormalView, { {}, {"debug"}, }); + +struct BoneTransformView : INode { + virtual void apply() override { + auto bones = get_input2("bones"); + auto view = std::make_shared(); + auto scale = get_input2("scale"); + auto index = get_input2("index"); + view->verts.resize(bones->verts.size() * 6); + auto &transform_r0 = bones->verts.attr("transform_r0"); + auto &transform_r1 = bones->verts.attr("transform_r1"); + auto &transform_r2 = bones->verts.attr("transform_r2"); + auto &clr = view->verts.add_attr("clr"); + for (auto i = 0; i < bones->verts.size(); i++) { + view->verts[i * 6 + 0] = bones->verts[i]; + view->verts[i * 6 + 1] = bones->verts[i] + transform_r0[i] * scale; + view->verts[i * 6 + 2] = bones->verts[i]; + view->verts[i * 6 + 3] = bones->verts[i] + transform_r1[i] * scale; + view->verts[i * 6 + 4] = bones->verts[i]; + view->verts[i * 6 + 5] = bones->verts[i] + transform_r2[i] * scale; + clr[i * 6 + 0] = {0.8, 0.2, 0.2}; + clr[i * 6 + 1] = {0.8, 0.2, 0.2}; + clr[i * 6 + 2] = {0.2, 0.8, 0.2}; + clr[i * 6 + 3] = {0.2, 0.8, 0.2}; + clr[i * 6 + 4] = {0.2, 0.2, 0.8}; + clr[i * 6 + 5] = {0.2, 0.2, 0.8}; + } + view->loops.resize(view->verts.size()); + std::iota(view->loops.begin(), view->loops.end(), 0); + view->polys.resize(bones->verts.size() * 3); + for (auto i = 0; i < bones->verts.size() * 3; i++) { + view->polys[i] = {i * 2, 2}; + } + set_output("view", view); + } +}; + +ZENDEFNODE(BoneTransformView, { + { + "bones", + {"float", "scale", "0.1"}, + {"int", "index", "-1"}, + }, + { + "view", + }, + {}, + {"debug"}, +}); } #endif \ No newline at end of file From 47fc5edc5b9872f95ca048aca737783a68cd2d10 Mon Sep 17 00:00:00 2001 From: luzh Date: Fri, 29 Mar 2024 17:36:51 +0800 Subject: [PATCH 16/17] [fix] name mangling of output socket. --- ui/zenoedit/launch/serialize.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/zenoedit/launch/serialize.cpp b/ui/zenoedit/launch/serialize.cpp index da8e03010e..27a8877b5c 100644 --- a/ui/zenoedit/launch/serialize.cpp +++ b/ui/zenoedit/launch/serialize.cpp @@ -50,7 +50,8 @@ void resolveOutputSocket( AddStringList({"addNodeOutput", mockNode, outSock}, writer); //add link from source output node to mockNode(ExtractDict). - AddStringList({"bindNodeInput", mockNode, mockSocket, outNodeId, dictlistName}, writer); + const QString& mockOutNode = nameMangling(graphIdPrefix, outNodeId); + AddStringList({"bindNodeInput", mockNode, mockSocket, mockOutNode, dictlistName}, writer); realOutputId = mockNode; realOutputSock = outSock; From c3223e0460797f7261c00755292c65eb97c8f299 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Mon, 1 Apr 2024 17:42:02 +0800 Subject: [PATCH 17/17] fix-primPolygonate --- zeno/include/zeno/types/AttrVector.h | 4 +++ zeno/src/nodes/neo/PrimFlipFaces.cpp | 4 +-- zeno/src/nodes/prim/PrimitivePolygonate.cpp | 37 +++++++++++++++----- zeno/src/nodes/prim/PrimitiveTriangulate.cpp | 10 +++--- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/zeno/include/zeno/types/AttrVector.h b/zeno/include/zeno/types/AttrVector.h index e4ede4fa37..6da0cd9658 100644 --- a/zeno/include/zeno/types/AttrVector.h +++ b/zeno/include/zeno/types/AttrVector.h @@ -506,6 +506,10 @@ struct AttrVector { std::visit([&](auto &val) { val.clear(); }, val); } } + void clear_with_attr() { + values.clear(); + attrs = {}; + } }; } diff --git a/zeno/src/nodes/neo/PrimFlipFaces.cpp b/zeno/src/nodes/neo/PrimFlipFaces.cpp index 709a8cd425..3b682af5ae 100644 --- a/zeno/src/nodes/neo/PrimFlipFaces.cpp +++ b/zeno/src/nodes/neo/PrimFlipFaces.cpp @@ -20,10 +20,10 @@ ZENO_API void primFlipFaces(PrimitiveObject *prim) { std::swap(tri[2], tri[0]); }); if (prim->tris.attr_is("uv0")) { - auto &uv1 = prim->tris.add_attr("uv1"); + auto &uv0 = prim->tris.add_attr("uv0"); auto &uv2 = prim->tris.add_attr("uv2"); for (auto i = 0; i < prim->tris.size(); i++) { - std::swap(uv1[i], uv2[i]); + std::swap(uv0[i], uv2[i]); } } } diff --git a/zeno/src/nodes/prim/PrimitivePolygonate.cpp b/zeno/src/nodes/prim/PrimitivePolygonate.cpp index 3090023dd7..9d62f94161 100644 --- a/zeno/src/nodes/prim/PrimitivePolygonate.cpp +++ b/zeno/src/nodes/prim/PrimitivePolygonate.cpp @@ -24,6 +24,7 @@ ZENO_API void primPolygonate(PrimitiveObject *prim, bool with_uv) { prim->loops.push_back(ind[2]); prim->polys.push_back({base + i * 3, 3}); } + prim->polys.update(); prim->tris.foreach_attr([&](auto const &key, auto const &arr) { if (key == "uv0" || key == "uv1" || key == "uv2") { @@ -31,7 +32,9 @@ ZENO_API void primPolygonate(PrimitiveObject *prim, bool with_uv) { } using T = std::decay_t; auto &newarr = prim->polys.add_attr(key); - newarr.insert(newarr.end(), arr.begin(), arr.end()); + for (auto i = 0; i < arr.size(); i++) { + newarr[polynum + i] = arr[i]; + } }); } @@ -46,6 +49,7 @@ ZENO_API void primPolygonate(PrimitiveObject *prim, bool with_uv) { prim->loops.push_back(ind[3]); prim->polys.push_back({base + i * 4, 4}); } + prim->polys.update(); prim->quads.foreach_attr([&](auto const &key, auto const &arr) { if (key == "uv0" || key == "uv1" || key == "uv2" || key == "uv3") { @@ -53,10 +57,13 @@ ZENO_API void primPolygonate(PrimitiveObject *prim, bool with_uv) { } using T = std::decay_t; auto &newarr = prim->polys.add_attr(key); - newarr.insert(newarr.end(), arr.begin(), arr.end()); + for (auto i = 0; i < arr.size(); i++) { + newarr[polynum + i] = arr[i]; + } }); } + polynum = prim->polys.size(); if (prim->lines.size()) { int base = prim->loops.size(); for (int i = 0; i < prim->lines.size(); i++) { @@ -65,14 +72,18 @@ ZENO_API void primPolygonate(PrimitiveObject *prim, bool with_uv) { prim->loops.push_back(ind[1]); prim->polys.push_back({base + i * 2, 2}); } + prim->polys.update(); prim->lines.foreach_attr([&](auto const &key, auto const &arr) { using T = std::decay_t; auto &newarr = prim->polys.add_attr(key); - newarr.insert(newarr.end(), arr.begin(), arr.end()); + for (auto i = 0; i < arr.size(); i++) { + newarr[polynum + i] = arr[i]; + } }); } + polynum = prim->polys.size(); if (prim->points.size()) { int base = prim->loops.size(); for (int i = 0; i < prim->points.size(); i++) { @@ -80,11 +91,14 @@ ZENO_API void primPolygonate(PrimitiveObject *prim, bool with_uv) { prim->loops.push_back(ind); prim->polys.push_back({base + i, 1}); } + prim->polys.update(); prim->points.foreach_attr([&](auto const &key, auto const &arr) { using T = std::decay_t; auto &newarr = prim->polys.add_attr(key); - newarr.insert(newarr.end(), arr.begin(), arr.end()); + for (auto i = 0; i < arr.size(); i++) { + newarr[polynum + i] = arr[i]; + } }); } @@ -113,17 +127,22 @@ ZENO_API void primPolygonate(PrimitiveObject *prim, bool with_uv) { for (auto i = 0; i < prim->loops.size(); i++) { vec2f uv = prim->uvs[loopsuv[i]]; if (mapping.count({uv[0], uv[1]}) == false) { - mapping[{uv[0], uv[1]}] = loopsuv[i]; + auto index = mapping.size(); + mapping[{uv[0], uv[1]}] = index; } loopsuv[i] = mapping[{uv[0], uv[1]}]; } + prim->uvs.resize(mapping.size()); + for (auto const&[uv, index]: mapping) { + prim->uvs[index] = {std::get<0>(uv), std::get<1>(uv)}; + } } } - prim->tris.clear(); - prim->quads.clear(); - prim->lines.clear(); - prim->points.clear(); + prim->tris.clear_with_attr(); + prim->quads.clear_with_attr(); + prim->lines.clear_with_attr(); + prim->points.clear_with_attr(); } namespace { diff --git a/zeno/src/nodes/prim/PrimitiveTriangulate.cpp b/zeno/src/nodes/prim/PrimitiveTriangulate.cpp index 7f1b184707..c7e666fba5 100644 --- a/zeno/src/nodes/prim/PrimitiveTriangulate.cpp +++ b/zeno/src/nodes/prim/PrimitiveTriangulate.cpp @@ -8,6 +8,9 @@ namespace zeno { ZENO_API void primTriangulateQuads(PrimitiveObject *prim) { + if (prim->quads.size() == 0) { + return; + } auto base = prim->tris.size(); prim->tris.resize(base + prim->quads.size() * 2); bool hasmat = prim->quads.has_attr("matid"); @@ -160,10 +163,9 @@ ZENO_API void primTriangulate(PrimitiveObject *prim, bool with_uv, bool has_line } }); } - prim->loops.clear(); - prim->polys.clear(); - prim->loops.erase_attr("uvs"); - prim->uvs.clear(); + prim->loops.clear_with_attr(); + prim->polys.clear_with_attr(); + prim->uvs.clear_with_attr(); }); }