Skip to content

Commit

Permalink
Merge pull request #1737 from zenustech/improve-abc-faceset-write
Browse files Browse the repository at this point in the history
Improve abc faceset write
  • Loading branch information
teachmain authored Jan 22, 2024
2 parents 6b67eae + 1fdb8bb commit a9113c6
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 58 deletions.
56 changes: 47 additions & 9 deletions projects/Alembic/ReadAlembic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ static std::shared_ptr<PrimitiveObject> foundABCMesh(Alembic::AbcGeom::IPolyMesh
ud.set2("faceset_count", int(faceSetNames.size()));
for (auto i = 0; i < faceSetNames.size(); i++) {
auto n = faceSetNames[i];
ud.set2(zeno::format("faceset_{:04}", i), n);
ud.set2(zeno::format("faceset_{}", i), n);
IFaceSet faceSet = mesh.getFaceSet(n);
IFaceSetSchema::Sample faceSetSample = faceSet.getSchema().getValue();
size_t s = faceSetSample.getFaces()->size();
Expand Down Expand Up @@ -601,7 +601,7 @@ static std::shared_ptr<PrimitiveObject> foundABCSubd(Alembic::AbcGeom::ISubDSche
ud.set2("faceset_count", int(faceSetNames.size()));
for (auto i = 0; i < faceSetNames.size(); i++) {
auto n = faceSetNames[i];
ud.set2(zeno::format("faceset_{:04}", i), n);
ud.set2(zeno::format("faceset_{}", i), n);
IFaceSet faceSet = subd.getFaceSet(n);
IFaceSetSchema::Sample faceSetSample = faceSet.getSchema().getValue();
size_t s = faceSetSample.getFaces()->size();
Expand Down Expand Up @@ -914,7 +914,7 @@ struct AlembicSplitByName: INode {
{
auto namelist = std::make_shared<zeno::ListObject>();
for (auto f = 0; f < faceset_count; f++) {
auto name = prim->userData().get2<std::string>(zeno::format("faceset_{:04}", f));
auto name = prim->userData().get2<std::string>(zeno::format("faceset_{}", f));
namelist->arr.push_back(std::make_shared<StringObject>(name));
}
set_output("namelist", namelist);
Expand All @@ -932,7 +932,7 @@ struct AlembicSplitByName: INode {
faceset_map[f].push_back(j);
}
for (auto f = 0; f < faceset_count; f++) {
auto name = prim->userData().get2<std::string>(zeno::format("faceset_{:04}", f));
auto name = prim->userData().get2<std::string>(zeno::format("faceset_{}", f));
auto new_prim = std::dynamic_pointer_cast<PrimitiveObject>(prim->clone());
new_prim->polys.resize(faceset_map[f].size());
for (auto i = 0; i < faceset_map[f].size(); i++) {
Expand All @@ -945,11 +945,12 @@ struct AlembicSplitByName: INode {
arr[i] = attr[faceset_map[f][i]];
}
});
new_prim->userData().del("faceset_count");
for (auto j = 0; j < faceset_count; j++) {
new_prim->userData().del(zeno::format("faceset_{:04}", j));
new_prim->userData().del(zeno::format("faceset_{}", j));
}
new_prim->userData().set2("_abc_faceset", name);
new_prim->userData().set2("faceset_count", 1);
new_prim->userData().set2("faceset_0", name);
dict->lut[name] = std::move(new_prim);
}
}
Expand All @@ -964,7 +965,7 @@ struct AlembicSplitByName: INode {
faceset_map[f].push_back(j);
}
for (auto f = 0; f < faceset_count; f++) {
auto name = prim->userData().get2<std::string>(zeno::format("faceset_{:04}", f));
auto name = prim->userData().get2<std::string>(zeno::format("faceset_{}", f));
auto new_prim = std::dynamic_pointer_cast<PrimitiveObject>(prim->clone());
new_prim->tris.resize(faceset_map[f].size());
for (auto i = 0; i < faceset_map[f].size(); i++) {
Expand All @@ -977,11 +978,12 @@ struct AlembicSplitByName: INode {
arr[i] = attr[faceset_map[f][i]];
}
});
new_prim->userData().del("faceset_count");
for (auto j = 0; j < faceset_count; j++) {
new_prim->userData().del(zeno::format("faceset_{:04}", j));
new_prim->userData().del(zeno::format("faceset_{}", j));
}
new_prim->userData().set2("_abc_faceset", name);
new_prim->userData().set2("faceset_count", 1);
new_prim->userData().set2("faceset_0", name);
dict->lut[name] = std::move(new_prim);
}
}
Expand Down Expand Up @@ -1165,6 +1167,42 @@ ZENDEFNODE(PrimsFilterInUserdataPython, {
{},
{"alembic"},
});

struct SetFaceset: INode {
void apply() override {
auto prim = get_input<PrimitiveObject>("prim");
int faceset_count = prim->userData().get2<int>("faceset_count",0);
for (auto j = 0; j < faceset_count; j++) {
prim->userData().del(zeno::format("faceset_{}", j));
}
prim->userData().set2("faceset_count", 1);
auto faceset_name = get_input2<std::string>("facesetName");
prim->userData().set2("faceset_0", faceset_name);

if (prim->tris.size() > 0) {
prim->tris.add_attr<int>("faceset").assign(prim->tris.size(),0);
}
if (prim->quads.size() > 0) {
prim->quads.add_attr<int>("faceset").assign(prim->quads.size(),0);
}
if (prim->polys.size() > 0) {
prim->polys.add_attr<int>("faceset").assign(prim->polys.size(),0);
}
set_output("out", prim);
}
};

ZENDEFNODE(SetFaceset, {
{
"prim",
{"string", "facesetName", "defFS"},
},
{
{"out"},
},
{},
{"alembic"},
});
#endif


Expand Down
84 changes: 35 additions & 49 deletions projects/Alembic/WriteAlembic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,39 @@ void write_user_data(std::map<std::string, std::any> &user_attrs, std::string pa
}
}
}

static void write_faceset(std::shared_ptr<PrimitiveObject> prim, OPolyMeshSchema &mesh) {
auto &ud = prim->userData();
std::vector<std::string> faceSetNames;
std::vector<std::vector<int>> faceset_idxs;
if (ud.has<int>("faceset_count")) {
int faceset_count = ud.get2<int>("faceset_count");
for (auto i = 0; i < faceset_count; i++) {
faceSetNames.emplace_back(ud.get2<std::string>(zeno::format("faceset_{}", i)));
}
faceset_idxs.resize(faceset_count);
std::vector<int> faceset;
if (prim->polys.size() && prim->polys.attr_is<int>("faceset")) {
faceset = prim->polys.attr<int>("faceset");
}
else if (prim->tris.size() && prim->tris.attr_is<int>("faceset")) {
faceset = prim->tris.attr<int>("faceset");
}
for (auto i = 0; i < faceset.size(); i++) {
if (faceset[i] >= 0) {
faceset_idxs[faceset[i]].push_back(i);
}
}
for (auto i = 0; i < faceset_count; i++) {
OFaceSet faceset = mesh.createFaceSet(faceSetNames[i]);
OFaceSetSchema facesetSchema = faceset.getSchema ();
OFaceSetSchema::Sample my_face_set_samp ( faceset_idxs[i] );
// faceset is visible, doesn't change.
facesetSchema.set ( my_face_set_samp );
facesetSchema.setFaceExclusivity ( kFaceSetExclusive );
}
}
}
struct WriteAlembic2 : INode {
OArchive archive;
OPolyMesh meshyObj;
Expand Down Expand Up @@ -463,36 +496,7 @@ struct WriteAlembic2 : INode {
if (prim->polys.size() || prim->tris.size()) {
// Create a PolyMesh class.
OPolyMeshSchema &mesh = meshyObj.getSchema();
auto &ud = prim->userData();
std::vector<std::string> faceSetNames;
std::vector<std::vector<int>> faceset_idxs;
if (ud.has<int>("faceset_count")) {
int faceset_count = ud.get2<int>("faceset_count");
for (auto i = 0; i < faceset_count; i++) {
faceSetNames.emplace_back(ud.get2<std::string>(zeno::format("faceset_{:04}", i)));
}
faceset_idxs.resize(faceset_count);
std::vector<int> faceset;
if (prim->polys.size() && prim->polys.attr_is<int>("faceset")) {
faceset = prim->polys.attr<int>("faceset");
}
else if (prim->tris.size() && prim->tris.attr_is<int>("faceset")) {
faceset = prim->tris.attr<int>("faceset");
}
for (auto i = 0; i < faceset.size(); i++) {
if (faceset[i] >= 0) {
faceset_idxs[faceset[i]].push_back(i);
}
}
for (auto i = 0; i < faceset_count; i++) {
OFaceSet faceset = mesh.createFaceSet(faceSetNames[i]);
OFaceSetSchema facesetSchema = faceset.getSchema ();
OFaceSetSchema::Sample my_face_set_samp ( faceset_idxs[i] );
// faceset is visible, doesn't change.
facesetSchema.set ( my_face_set_samp );
facesetSchema.setFaceExclusivity ( kFaceSetExclusive );
}
}
write_faceset(prim, mesh);

OCompoundProperty user = mesh.getUserProperties();
write_user_data(user_attrs, "", prim, user);
Expand Down Expand Up @@ -737,25 +741,7 @@ struct WriteAlembicPrims : INode {
auto &ud = prim->userData();
std::vector<std::string> faceSetNames;
std::vector<std::vector<int>> faceset_idxs;
if (ud.has<int>("faceset_count")) {
int faceset_count = ud.get2<int>("faceset_count");
for (auto i = 0; i < faceset_count; i++) {
faceSetNames.emplace_back(ud.get2<std::string>(zeno::format("faceset_{:04}", i)));
}
faceset_idxs.resize(faceset_count);
auto &faceset = prim->polys.attr<int>("faceset");
for (auto i = 0; i < faceset.size(); i++) {
faceset_idxs[faceset[i]].push_back(i);
}
for (auto i = 0; i < faceset_count; i++) {
OFaceSet faceset = mesh.createFaceSet(faceSetNames[i]);
OFaceSetSchema facesetSchema = faceset.getSchema ();
OFaceSetSchema::Sample my_face_set_samp ( faceset_idxs[i] );
// faceset is visible, doesn't change.
facesetSchema.set ( my_face_set_samp );
facesetSchema.setFaceExclusivity ( kFaceSetExclusive );
}
}
write_faceset(prim, mesh);

OCompoundProperty user = mesh.getUserProperties();
write_user_data(user_attrs, path, prim, user);
Expand Down
58 changes: 58 additions & 0 deletions zeno/src/nodes/neo/PrimMerge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <zeno/types/UserData.h>
#include <zeno/utils/log.h>
#include <zeno/zeno.h>
#include <unordered_set>

namespace zeno {

Expand Down Expand Up @@ -500,6 +501,8 @@ struct PrimMerge : INode {
//initialize

std::vector<std::string> matNameList(0);
std::vector<std::string> facesetNameList;
std::unordered_set<std::string> facesetNameSet;
for (auto &p : primList) {
//if p has material
int matNum = p->userData().get2<int>("matNum", 0);
Expand Down Expand Up @@ -544,6 +547,49 @@ struct PrimMerge : INode {
p->polys.attr<int>("matid").assign(p->polys.size(), -1);
}
}
int faceset_count = p->userData().get2<int>("faceset_count", 0);
if (faceset_count > 0) {
for (int i = 0; i < p->tris.size(); i++) {
if (p->tris.attr<int>("faceset")[i] != -1) {
p->tris.attr<int>("faceset")[i] += int(facesetNameList.size());
}
}
for (int i = 0; i < p->quads.size(); i++) {
if (p->quads.attr<int>("faceset")[i] != -1) {
p->quads.attr<int>("faceset")[i] += int(facesetNameList.size());
}
}
for (int i = 0; i < p->polys.size(); i++) {
if (p->polys.attr<int>("faceset")[i] != -1) {
p->polys.attr<int>("faceset")[i] += int(facesetNameList.size());
}
}
for (int i = 0; i < faceset_count; i++) {
auto facesetIdx = "faceset_" + to_string(i);
auto facesetName = p->userData().get2<std::string>(facesetIdx, "Default");
std::string newFacesetName = facesetName;
int j = 0;
while (facesetNameSet.count(newFacesetName)) {
j++;
newFacesetName = zeno::format("{}_{}", facesetName, j);
}
facesetNameList.emplace_back(newFacesetName);
facesetNameSet.insert(newFacesetName);
}
} else {
if (p->tris.size() > 0) {
p->tris.add_attr<int>("faceset");
p->tris.attr<int>("faceset").assign(p->tris.size(), -1);
}
if (p->quads.size() > 0) {
p->quads.add_attr<int>("faceset");
p->quads.attr<int>("faceset").assign(p->quads.size(), -1);
}
if (p->polys.size() > 0) {
p->polys.add_attr<int>("faceset");
p->polys.attr<int>("faceset").assign(p->polys.size(), -1);
}
}
}

auto outprim = primMerge(primList, tagAttr);
Expand All @@ -563,6 +609,18 @@ struct PrimMerge : INode {
}
int oMatNum = matNameList.size();
outprim->userData().set2("matNum", oMatNum);
{
if (facesetNameList.size() > 0) {
int i = 0;
for (auto name : facesetNameList) {
auto facesetIdx = "faceset_" + to_string(i);
outprim->userData().setLiterial(facesetIdx, name);
i++;
}
}
int faceset_count = facesetNameList.size();
outprim->userData().set2("faceset_count", faceset_count);
}
//auto outprim = std::make_shared<PrimitiveObject>(*primList[0]);
set_output("prim", std::move(outprim));
}
Expand Down

0 comments on commit a9113c6

Please sign in to comment.