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 face removal (#1191) #1192

Merged
merged 10 commits into from
Mar 15, 2025
Merged

Fix face removal (#1191) #1192

merged 10 commits into from
Mar 15, 2025

Conversation

pca006132
Copy link
Collaborator

Closes #1191.

The bulk of the code is handling removed faces. Instead of letting them sit in the vector, I remove them and reorder properties dependent on this. This avoids the need to make other functions accept removed halfedges.

While writing this, something that comes to my mind is that we are not really trying our best to handle cases that are not 2-manifold. The current matching method may produce pairs that cross-cross together. I think one way to handle this is to sort the duplicated halfedges according to the face normals, so we will not produce any criss-crossing pairs. Probably for another issue, though.

@pca006132 pca006132 requested a review from elalish March 14, 2025 12:34
Copy link

codecov bot commented Mar 14, 2025

Codecov Report

Attention: Patch coverage is 86.95652% with 3 lines in your changes missing coverage. Please review.

Project coverage is 92.09%. Comparing base (fab833e) to head (82abc27).
Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
src/face_op.cpp 33.33% 2 Missing ⚠️
src/impl.cpp 94.73% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1192      +/-   ##
==========================================
- Coverage   92.21%   92.09%   -0.13%     
==========================================
  Files          31       31              
  Lines        5959     5982      +23     
==========================================
+ Hits         5495     5509      +14     
- Misses        464      473       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pca006132 pca006132 changed the title Fix edge removal (#1191) Fix face removal (#1191) Mar 14, 2025
Copy link
Owner

@elalish elalish left a comment

Choose a reason for hiding this comment

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

Thanks for digging into this!

src/impl.cpp Outdated
#endif

if (!removedHalfedges.empty()) {
// Remove the marked halfedges
Copy link
Owner

Choose a reason for hiding this comment

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

Okay, so the logic I had been using was that I could mark any halfedge as removed by setting it to -1 and any vertex by setting it to NAN, then Finish() would take care of actually removing them because that's where the vectors get sorted and reindexed anyway. I was figuring that's an expensive step, so better to do it once. This bug sounds like I messed that up somewhere.

Still, isn't this big chunk of new code a lot like Finish? Is there a way we can share it? Or a way we can organize things so that removals are still lazy, but safer?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah make sense, I just added the checks elsewhere and keep the removed halfedges in-place.

@pca006132
Copy link
Collaborator Author

Weird, I can't reproduce the failure.

@pca006132
Copy link
Collaborator Author

OK some uninitialized memory stuff. Here we go again.

src/impl.cpp Outdated
if (h0.startVert != h1.endVert || h0.endVert != h1.startVert) break;
if (halfedge_[NextHalfedge(pair0)].endVert ==
halfedge_[NextHalfedge(pair1)].endVert) {
h0 = {-1, -1, -1};
h1 = {-1, -1, -1};
h0.pairedHalfedge = h1.pairedHalfedge = -2;
Copy link
Owner

Choose a reason for hiding this comment

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

perhaps we should start using named constants?

@@ -42,7 +42,7 @@ TEST(SDF, SphereShell) {
},
{vec3(-1.1), vec3(1.1)}, 0.01, 0, 0.0001);

EXPECT_NEAR(sphere.Genus(), 11500, 1000);
EXPECT_NEAR(sphere.Genus(), 14235, 1000);
Copy link
Owner

Choose a reason for hiding this comment

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

Does this still look good, or look better? I recall working to remove little bits of infinitely thin geometry on this one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't see infinitely thin stuff, but I see something that looks like self-intersection:

image

This is probably related to the other thing I mentioned, as there are many non-2-manifold edges here.

Copy link
Owner

Choose a reason for hiding this comment

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

Ah, right - I think my slick pre-edge collapse thing in the SDF can create even manifold edges. We should probably look at that again and see if there's a better way. I believe without that it's all guaranteed 2-manifold.

@pca006132 pca006132 merged commit 4edd442 into master Mar 15, 2025
27 checks passed
@pca006132 pca006132 deleted the fix-edge-removal branch March 15, 2025 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

regression on meshgl with touching faces
2 participants