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

Potential boolean bug #970

Open
pca006132 opened this issue Oct 1, 2024 · 3 comments
Open

Potential boolean bug #970

pca006132 opened this issue Oct 1, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@pca006132
Copy link
Collaborator

See #666 (comment)

Just to remind us not to forget about this after finishing v3.0 release.

@pca006132 pca006132 added the bug Something isn't working label Oct 1, 2024
@elalish
Copy link
Owner

elalish commented Oct 1, 2024

Yeah, I feel like we could use an approximate IsOverlapping function that we can run in debug mode after each Boolean so we can figure out where the problem first occurs, and dump out a test case of those meshes.

@pca006132
Copy link
Collaborator Author

For the record: We now check for self-intersection in

bool Manifold::Impl::IsSelfIntersecting() const {
and has a simple fuzzer in https://github.com/elalish/manifold/blob/master/test/manifold_fuzz.cpp that can fuzz this quickly.

@pca006132
Copy link
Collaborator Author

pca006132 commented Jan 26, 2025

It seems that this may be related to the mesh simplification pass. For

TEST(BooleanComplex, DISABLED_OffsetSelfIntersect) {
const bool intermediateChecks = ManifoldParams().intermediateChecks;
ManifoldParams().intermediateChecks = true;
std::string file = __FILE__;
std::string dir = file.substr(0, file.rfind('/'));
Manifold a, b;
std::ifstream f;
f.open(dir + "/models/Offset3.obj");
a = Manifold::ImportMeshGL64(f);
f.close();
f.open(dir + "/models/Offset4.obj");
b = Manifold::ImportMeshGL64(f);
f.close();
Manifold result = a + b;
EXPECT_EQ(result.Status(), Manifold::Error::NoError);
ManifoldParams().intermediateChecks = intermediateChecks;
}

The result is not self-intersecting (doesn't even require epsilon-valid!) if we disable the mesh simplification pass, the part that flags redundant edges for collapsing. I think this suggests that the redundant edge removal may produce self-intersection.

However, disabling mesh simplification doesn't fix all the test cases. For example, the following case is still failing:

TEST(Boolean, DISABLED_SimpleCubeRegression) {
ManifoldParams().intermediateChecks = true;
ManifoldParams().processOverlaps = false;
Manifold result =
Manifold::Cube().Rotate(-0.10000000000000001, 0.10000000000000001, -1.) +
Manifold::Cube() -
Manifold::Cube().Rotate(-0.10000000000000001, -0.10000000000066571, -1.);
EXPECT_EQ(result.Status(), Manifold::Error::NoError);
ManifoldParams().intermediateChecks = false;
ManifoldParams().processOverlaps = true;
}

Probably two issues at play here.


Also, about the edge flagging code, why don't we do the following, which updates ref1 to make sure ref1 never points to the same triangle as ref0? The old code will not flag more edges, but it may flag less.

  bool operator()(int edge) const {
    if (halfedge[edge].pairedHalfedge < 0) return false;
    // Flag redundant edges - those where the startVert is surrounded by only
    // two original triangles.
    const TriRef ref0 = triRef[edge / 3];
    int current = NextHalfedge(halfedge[edge].pairedHalfedge);
    TriRef ref1 = triRef[current / 3];
    bool ref1Updated = !ref0.SameFace(ref1);
    while (current != edge) {
      current = NextHalfedge(halfedge[current].pairedHalfedge);
      int tri = current / 3;
      const TriRef ref = triRef[tri];
      if (!ref.SameFace(ref0) && !ref.SameFace(ref1)) {
        if (!ref1Updated) {
          ref1 = ref;
          ref1Updated = true;
        } else {
          return false;
        }
      }
    }
    return true;
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants