Skip to content

Commit

Permalink
Use ForVert (#778)
Browse files Browse the repository at this point in the history
* updated a bunch of do loops to ForVert

* more cleanup
  • Loading branch information
elalish committed Mar 26, 2024
1 parent 3e05284 commit 32eefe9
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 86 deletions.
39 changes: 14 additions & 25 deletions src/manifold/src/edge_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@ struct FlagEdge {
current = NextHalfedge(halfedge[current].pairedHalfedge);
int tri = current / 3;
const TriRef ref = triRef[tri];
if ((ref.meshID != ref0.meshID || ref.tri != ref0.tri) &&
(ref.meshID != ref1.meshID || ref.tri != ref1.tri))
return false;
if (!ref.SameFace(ref0) && !ref.SameFace(ref1)) return false;
}
return true;
}
Expand Down Expand Up @@ -325,12 +323,10 @@ void Manifold::Impl::DedupeEdge(const int edge) {
vertPos_.push_back(vertPos_[endVert]);
if (vertNormal_.size() > 0) vertNormal_.push_back(vertNormal_[endVert]);

do {
ForVert(current, [this, newVert](int current) {
halfedge_[current].endVert = newVert;
current = NextHalfedge(current);
halfedge_[current].startVert = newVert;
current = halfedge_[current].pairedHalfedge;
} while (current != edge);
halfedge_[halfedge_[current].pairedHalfedge].startVert = newVert;
});
}

// Orbit startVert
Expand All @@ -350,12 +346,10 @@ void Manifold::Impl::DedupeEdge(const int edge) {
vertPos_.push_back(vertPos_[endVert]);
if (vertNormal_.size() > 0) vertNormal_.push_back(vertNormal_[endVert]);

do {
ForVert(current, [this, newVert](int current) {
halfedge_[current].endVert = newVert;
current = NextHalfedge(current);
halfedge_[current].startVert = newVert;
current = halfedge_[current].pairedHalfedge;
} while (current != pair);
halfedge_[halfedge_[current].pairedHalfedge].startVert = newVert;
});
}
}

Expand Down Expand Up @@ -482,9 +476,9 @@ void Manifold::Impl::CollapseEdge(const int edge, std::vector<int>& edges) {
const glm::mat3x2 projection = GetAxisAlignedProjection(faceNormal_[tri]);
// Don't collapse if the edge is not redundant (this may have changed due
// to the collapse of neighbors).
if (ref.meshID != refCheck.meshID || ref.tri != refCheck.tri) {
if (!ref.SameFace(refCheck)) {
refCheck = triRef[edge / 3];
if (ref.meshID != refCheck.meshID || ref.tri != refCheck.tri) {
if (!ref.SameFace(refCheck)) {
return;
} else {
// Don't collapse if the edges separating the faces are not colinear
Expand Down Expand Up @@ -522,11 +516,9 @@ void Manifold::Impl::CollapseEdge(const int edge, std::vector<int>& edges) {
// 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) {
if (triRef[tri].SameFace(triRef[tri0])) {
triProp[tri][vIdx] = triProp[tri0][triVert0];
} else if (triRef[tri].meshID == triRef[tri1].meshID &&
triRef[tri].tri == triRef[tri1].tri) {
} else if (triRef[tri].SameFace(triRef[tri1])) {
triProp[tri][vIdx] = triProp[tri1][triVert1];
}
}
Expand Down Expand Up @@ -676,14 +668,11 @@ void Manifold::Impl::SplitPinchedVerts() {
} else {
vertProcessed[vert] = true;
}
int current = i;
do {
ForVert(i, [this, &halfedgeProcessed, vert](int current) {
halfedgeProcessed[current] = true;
halfedge_[current].startVert = vert;
current = halfedge_[current].pairedHalfedge;
halfedge_[current].endVert = vert;
current = NextHalfedge(current);
} while (current != i);
halfedge_[halfedge_[current].pairedHalfedge].endVert = vert;
});
}
}
} // namespace manifold
2 changes: 1 addition & 1 deletion src/manifold/src/impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ struct Manifold::Impl {
inline void ForVert(int halfedge, std::function<void(int halfedge)> func) {
int current = halfedge;
do {
func(current);
current = NextHalfedge(halfedge_[current].pairedHalfedge);
func(current);
} while (current != halfedge);
}

Expand Down
116 changes: 56 additions & 60 deletions src/manifold/src/smoothing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,36 +663,35 @@ void Manifold::Impl::SetNormals(int normalIdx, float minSharpAngle) {
for (int tri = 0; tri < numTri; ++tri) {
for (const int i : {0, 1, 2}) {
if (meshRelation_.triProperties[tri][i] >= 0) continue;
int current = 3 * tri + i;
const int startEdge = current;
const int vert = halfedge_[current].startVert;
int startEdge = 3 * tri + i;
const int vert = halfedge_[startEdge].startVert;

if (vertNumSharp[vert] < 2) {
const glm::vec3 normal = vertFlatFace[vert] >= 0
? faceNormal_[vertFlatFace[vert]]
: vertNormal_[vert];
int lastProp = -1;
do {
current = NextHalfedge(halfedge_[current].pairedHalfedge);
ForVert(startEdge, [&](int current) {
const int thisTri = current / 3;
const int j = current - 3 * thisTri;
const int prop = oldTriProp[thisTri][j];
meshRelation_.triProperties[thisTri][j] = prop;
if (prop == lastProp) continue;
if (prop == lastProp) return;
lastProp = prop;
auto start = oldProperties.begin() + prop * oldNumProp;
std::copy(start, start + oldNumProp,
meshRelation_.properties.begin() + prop * numProp);
for (const int i : {0, 1, 2})
meshRelation_.properties[prop * numProp + normalIdx + i] =
normal[i];
} while (current != startEdge);
});
} else {
const glm::vec3 centerPos = vertPos_[vert];
// Length degree
std::vector<int> group;
// Length number of normals
std::vector<glm::vec3> normals;
int current = startEdge;
int prevFace = halfedge_[current].face;

do {
Expand All @@ -713,34 +712,38 @@ void Manifold::Impl::SetNormals(int normalIdx, float minSharpAngle) {
} while (current != startEdge);

const int endEdge = current;
glm::vec3 prevEdgeVec =
glm::normalize(vertPos_[halfedge_[current].endVert] - centerPos);

do {
current = NextHalfedge(halfedge_[current].pairedHalfedge);
const int face = halfedge_[current].face;

const float dihedral = glm::degrees(
glm::acos(glm::dot(faceNormal_[face], faceNormal_[prevFace])));
if (dihedral > minSharpAngle ||
triIsFlatFace[face] != triIsFlatFace[prevFace] ||
(triIsFlatFace[face] && triIsFlatFace[prevFace] &&
!meshRelation_.triRef[face].SameFace(
meshRelation_.triRef[prevFace]))) {
normals.push_back(glm::vec3(0));
}
group.push_back(normals.size() - 1);

const glm::vec3 edgeVec =
glm::normalize(vertPos_[halfedge_[current].endVert] - centerPos);
float dot = glm::dot(prevEdgeVec, edgeVec);
const float phi =
dot >= 1 ? 0 : (dot <= -1 ? glm::pi<float>() : glm::acos(dot));
normals.back() += faceNormal_[face] * phi;

prevFace = face;
prevEdgeVec = edgeVec;
} while (current != endEdge);
struct FaceEdge {
int face;
glm::vec3 edgeVec;
};

ForVert<FaceEdge>(
endEdge,
[this, centerPos](int current) {
return FaceEdge(
{halfedge_[current].face,
glm::normalize(vertPos_[halfedge_[current].endVert] -
centerPos)});
},
[this, &triIsFlatFace, &normals, &group, minSharpAngle](
int current, const FaceEdge& here, const FaceEdge& next) {
const float dihedral = glm::degrees(glm::acos(
glm::dot(faceNormal_[here.face], faceNormal_[next.face])));
if (dihedral > minSharpAngle ||
triIsFlatFace[here.face] != triIsFlatFace[next.face] ||
(triIsFlatFace[here.face] && triIsFlatFace[next.face] &&
!meshRelation_.triRef[here.face].SameFace(
meshRelation_.triRef[next.face]))) {
normals.push_back(glm::vec3(0));
}
group.push_back(normals.size() - 1);
float dot = glm::dot(here.edgeVec, next.edgeVec);
const float phi =
dot >= 1 ? 0
: (dot <= -1 ? glm::pi<float>() : glm::acos(dot));
normals.back() += faceNormal_[next.face] * phi;
});

for (auto& normal : normals) {
normal = glm::normalize(normal);
Expand All @@ -750,10 +753,9 @@ void Manifold::Impl::SetNormals(int normalIdx, float minSharpAngle) {
int lastProp = -1;
int newProp = -1;
int idx = 0;
do {
current = NextHalfedge(halfedge_[current].pairedHalfedge);
const int thisTri = current / 3;
const int j = current - 3 * thisTri;
ForVert(endEdge, [&](int current1) {
const int thisTri = current1 / 3;
const int j = current1 - 3 * thisTri;
const int prop = oldTriProp[thisTri][j];
auto start = oldProperties.begin() + prop * oldNumProp;

Expand All @@ -780,7 +782,7 @@ void Manifold::Impl::SetNormals(int normalIdx, float minSharpAngle) {

meshRelation_.triProperties[thisTri][j] = newProp;
++idx;
} while (current != endEdge);
});
}
}
}
Expand Down Expand Up @@ -855,11 +857,9 @@ void Manifold::Impl::CreateTangents(int normalIdx) {
}
});
} else { // Sharpen vertex uniformly
int current = first;
do {
ForVert(first, [this](int current) {
halfedgeTangent_[current] = glm::vec4(0);
current = NextHalfedge(halfedge_[current].pairedHalfedge);
} while (current != first);
});
}
}
}
Expand Down Expand Up @@ -947,18 +947,17 @@ void Manifold::Impl::CreateTangents(std::vector<Smoothness> sharpenedEdges) {
tangent[second] = CircularTangent(
-newTangent, vertPos_[halfedge_[second].endVert] - pos);

auto SmoothHalf = [&](int first, int last, float smoothness) {
int current = NextHalfedge(halfedge_[first].pairedHalfedge);
while (current != last) {
tangent[current] = smoothness * tangent[current];
current = NextHalfedge(halfedge_[current].pairedHalfedge);
}
};

SmoothHalf(first, second,
(vert[0].second.smoothness + vert[1].first.smoothness) / 2);
SmoothHalf(second, first,
(vert[1].second.smoothness + vert[0].first.smoothness) / 2);
float smoothness =
(vert[0].second.smoothness + vert[1].first.smoothness) / 2;
ForVert(
first, [&tangent, &smoothness, &vert, first, second](int current) {
if (current == second) {
smoothness =
(vert[1].second.smoothness + vert[0].first.smoothness) / 2;
} else if (current != first) {
tangent[current] = smoothness * tangent[current];
}
});
} else { // Sharpen vertex uniformly
float smoothness = 0;
for (const Pair& pair : vert) {
Expand All @@ -967,12 +966,9 @@ void Manifold::Impl::CreateTangents(std::vector<Smoothness> sharpenedEdges) {
}
smoothness /= 2 * vert.size();

const int start = vert[0].first.halfedge;
int current = start;
do {
ForVert(vert[0].first.halfedge, [&tangent, smoothness](int current) {
tangent[current] = smoothness * tangent[current];
current = NextHalfedge(halfedge_[current].pairedHalfedge);
} while (current != start);
});
}
}
}
Expand Down

0 comments on commit 32eefe9

Please sign in to comment.