Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix properties #587

Merged
merged 5 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions meshIO/src/meshIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ void ExportMesh(const std::string& filename, const MeshGL& mesh,
? 1
: mesh.vertProperties[i * mesh.numProp +
options.mat.colorChannels[j]];
c = glm::saturate(c);
mesh_out->mColors[0][i] = aiColor4D(c.r, c.g, c.b, c.a);
}
}
Expand Down
33 changes: 17 additions & 16 deletions src/manifold/src/boolean_result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,9 +463,8 @@ struct MapTriRef {
}
};

Vec<TriRef> UpdateReference(Manifold::Impl &outR, const Manifold::Impl &inP,
const Manifold::Impl &inQ, bool invertQ) {
Vec<TriRef> refPQ = outR.meshRelation_.triRef;
void UpdateReference(Manifold::Impl &outR, const Manifold::Impl &inP,
const Manifold::Impl &inQ, bool invertQ) {
const int offsetQ = Manifold::Impl::meshIDCounter_;
for_each_n(
autoPolicy(outR.NumTri()), outR.meshRelation_.triRef.begin(),
Expand All @@ -480,7 +479,6 @@ Vec<TriRef> UpdateReference(Manifold::Impl &outR, const Manifold::Impl &inP,
outR.meshRelation_.meshIDtransform[pair.first + offsetQ].backSide ^=
invertQ;
}
return refPQ;
}

struct Barycentric {
Expand Down Expand Up @@ -514,8 +512,8 @@ struct Barycentric {
}
};

void CreateProperties(Manifold::Impl &outR, const Vec<TriRef> &refPQ,
const Manifold::Impl &inP, const Manifold::Impl &inQ) {
void CreateProperties(Manifold::Impl &outR, const Manifold::Impl &inP,
const Manifold::Impl &inQ) {
const int numPropP = inP.NumProp();
const int numPropQ = inQ.NumProp();
const int numProp = glm::max(numPropP, numPropQ);
Expand All @@ -526,7 +524,8 @@ void CreateProperties(Manifold::Impl &outR, const Vec<TriRef> &refPQ,
outR.meshRelation_.triProperties.resize(numTri);

Vec<glm::vec3> bary(outR.halfedge_.size());
for_each_n(autoPolicy(numTri), zip(countAt(0), refPQ.cbegin()), numTri,
for_each_n(autoPolicy(numTri),
zip(countAt(0), outR.meshRelation_.triRef.cbegin()), numTri,
Barycentric({bary, inP.vertPos_, inQ.vertPos_, outR.vertPos_,
inP.halfedge_, inQ.halfedge_, outR.halfedge_,
outR.precision_}));
Expand All @@ -541,23 +540,22 @@ void CreateProperties(Manifold::Impl &outR, const Vec<TriRef> &refPQ,
// Skip collapsed triangles
if (outR.halfedge_[3 * tri].startVert < 0) continue;

const int triPQ = refPQ[tri].tri;
const bool PQ = refPQ[tri].meshID == 0;
const TriRef ref = outR.meshRelation_.triRef[tri];
const bool PQ = ref.meshID == 0;
const int oldNumProp = PQ ? numPropP : numPropQ;
const auto &properties =
PQ ? inP.meshRelation_.properties : inQ.meshRelation_.properties;
const glm::ivec3 &triProp = oldNumProp == 0 ? glm::ivec3(-1)
: PQ ? inP.meshRelation_.triProperties[triPQ]
: inQ.meshRelation_.triProperties[triPQ];
: PQ ? inP.meshRelation_.triProperties[ref.tri]
: inQ.meshRelation_.triProperties[ref.tri];

for (const int i : {0, 1, 2}) {
const int vert = outR.halfedge_[3 * tri + i].startVert;
const glm::vec3 &uvw = bary[3 * tri + i];

glm::ivec4 key(PQ, idMissProp, -1, -1);
if (oldNumProp > 0) {
key[1] = vert;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the key fix: for anything close to a retained vert, only key on the propVert, since the separate verts are close together and will get collapsed anyway - this was causing us to duplicate propVerts unnecessarily.

int edge = -1;
int edge = -2;
for (const int j : {0, 1, 2}) {
if (uvw[j] == 1) {
// On a retained vert, the propVert must also match
Expand All @@ -571,8 +569,11 @@ void CreateProperties(Manifold::Impl &outR, const Vec<TriRef> &refPQ,
// On an edge, both propVerts must match
const int p0 = triProp[Next3(edge)];
const int p1 = triProp[Prev3(edge)];
key[1] = vert;
key[2] = glm::min(p0, p1);
key[3] = glm::max(p0, p1);
} else if (edge == -2) {
key[1] = vert;
}
}

Expand Down Expand Up @@ -770,11 +771,11 @@ Manifold::Impl Boolean3::Result(OpType op) const {
if (ManifoldParams().intermediateChecks)
ASSERT(outR.IsManifold(), logicErr, "triangulated mesh is not manifold!");

Vec<TriRef> refPQ = UpdateReference(outR, inP_, inQ_, invertQ);
CreateProperties(outR, inP_, inQ_);

outR.SimplifyTopology();
UpdateReference(outR, inP_, inQ_, invertQ);

CreateProperties(outR, refPQ, inP_, inQ_);
outR.SimplifyTopology();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for refPQ anymore since now everything happens in a logical order.


if (ManifoldParams().intermediateChecks)
ASSERT(outR.Is2Manifold(), logicErr, "simplified mesh is not 2-manifold!");
Expand Down
25 changes: 10 additions & 15 deletions src/manifold/src/edge_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,25 +501,20 @@ void Manifold::Impl::CollapseEdge(const int edge, std::vector<int>& edges) {
const int tri1 = toRemove.pairedHalfedge / 3;
const int triVert0 = (edge + 1) % 3;
const int triVert1 = toRemove.pairedHalfedge % 3;
const int prop0 = triProp.size() > 0 ? triProp[tri0][edge % 3] : -1;
const int prop1 = triProp.size() > 0
? triProp[tri1][(toRemove.pairedHalfedge + 1) % 3]
: -1;
current = start;
while (current != tri0edge[2]) {
current = NextHalfedge(current);

// Update the shifted triangles to the vertBary of endVert
const int tri = current / 3;
const int vIdx = current - 3 * tri;

if (!shortEdge) {
if (triProp.size() > 0) {
if (triProp[tri][vIdx] == prop0) {
triProp[tri][vIdx] = triProp[tri0][triVert0];
} else if (triProp[tri][vIdx] == prop1) {
triProp[tri][vIdx] = triProp[tri1][triVert1];
}
if (triProp.size() > 0) {
// Update the shifted triangles to the vertBary of endVert
const int tri = current / 3;
const int vIdx = current - 3 * tri;
if (triRef[tri].meshID == triRef[tri0].meshID &&
triRef[tri].tri == triRef[tri0].tri) {
triProp[tri][vIdx] = triProp[tri0][triVert0];
} else if (triRef[tri].meshID == triRef[tri1].meshID &&
triRef[tri].tri == triRef[tri1].tri) {
triProp[tri][vIdx] = triProp[tri1][triVert1];
}
}

Expand Down
Loading