Skip to content

Commit

Permalink
Fix properties (elalish#587)
Browse files Browse the repository at this point in the history
* fix testing

* added test

* add comments

* tests pass

* cleanup
  • Loading branch information
elalish authored Nov 2, 2023
1 parent 2942229 commit a842de9
Show file tree
Hide file tree
Showing 5 changed files with 471 additions and 35 deletions.
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;
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();

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

0 comments on commit a842de9

Please sign in to comment.