-
Notifications
You must be signed in to change notification settings - Fork 129
boolean debugging #1104
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 8000 occasionally send you account related emails.
Already on GitHub? Sign in to your account
boolean debugging #1104
Conversation
src/csg_tree.cpp
Outdated
#ifdef MANIFOLD_DEBUG | ||
if (impl.IsSelfIntersecting()) { | ||
dump_lock.lock(); | ||
std::cout << "self-intersection detected" << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably clean up these error messages later.
src/impl.cpp
Outdated
#endif | ||
< 8000 td class="blob-code blob-code-addition"> | ||
#ifdef MANIFOLD_EXPORT | ||
MeshGL64 ImportMeshGL64(std::istream& stream) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function imports the .obj
file. Note that this is a quick-and-dirty implementation that doesn't really support the actual specification, but good enough that it can parse our outputs. I do not plan to make it spec compliant, nor make the format stable, so this will probably keep internal to us.
test/boolean_complex_test.cpp
Outdated
@@ -1016,4 +1020,26 @@ TEST(BooleanComplex, SimpleOffset) { | |||
EXPECT_EQ(c.Status(), Manifold::Error::NoError); | |||
} | |||
|
|||
TEST(BooleanComplex, UnionDifferenceSelfIntersect) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a simple failure case, and a test case to exercise the parser as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the big question: does this successfully spit out the Boolean that leads to the first self-intersection in our problem Minkowski cases? If so, this will be super helpful. If not, we probably need to rethink it.
This seems to work for the |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1104 +/- ##
==========================================
- Coverage 91.87% 91.46% -0.41%
==========================================
Files 30 30
Lines 5885 5908 +23
==========================================
- Hits 5407 5404 -3
- Misses 478 504 +26 ☔ View full report in Codecov by Sentry. |
Here are the failures we have when intermediate checks are enabled (via a new
It now checks if the two operands are self-intersecting up to epsilon. |
The main issue is that the operands causing these issues are typically quite large, may require some randomized algorithm to reduce their sizes. |
Managed to obtain a smaller self-intersecting result case with openscad. The two operands are fine, but the result is not. Btw, I found that the problem with verbose output is that we also print running time and algorithm statistics with verbose enabled, and things are unreadable when run in multiple threads... Wonder if we should split that into some debug flag, as users should never use that verbose output (except during debugging). |
It seems that the offending pairs look like this by peforming decomposition: diff --git a/test/boolean_complex_test.cpp b/test/boolean_complex_test.cpp
index 2cef5f6..a16bd67 100644
--- a/test/boolean_complex_test.cpp
+++ b/test/boolean_complex_test.cpp
@@ -1045,7 +1045,7 @@ TEST(BooleanComplex, DISABLED_OffsetTriangulationFailure) {
ManifoldParams().intermediateChecks = intermediateChecks;
}
-TEST(BooleanComplex, DISABLED_OffsetSelfIntersect) {
+TEST(BooleanComplex, OffsetSelfIntersect) {
const bool intermediateChecks = ManifoldParams().intermediateChecks;
ManifoldParams().intermediateChecks = true;
std::string file = __FILE__;
@@ -1063,10 +1063,17 @@ TEST(BooleanComplex, DISABLED_OffsetSelfIntersect) {
std::cout << err.what() << std::endl;
FAIL();
}
- Manifold x(a);
- Manifold y(b);
- Manifold result = x + y;
- EXPECT_EQ(result.Status(), Manifold::Error::NoError);
+
+ auto xs = Manifold(a).Decompose();
+ auto ys = Manifold(b).Decompose();
+
+ for (const auto &x : xs) {
+ for (const auto &y : ys) {
+ Manifold result = x + y;
+ EXPECT_EQ(result.Status(), Manifold::Error::NoError);
+ }
+ }
+
ManifoldParams().intermediateChecks = intermediateChecks;
}
But for some reason after extracting the mesh, I cannot reproduce the issue. Perhaps this is related to rounding error or face normals? |
It can now be reproduced after allowing setting epsilon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks!
for (int i : {0, 1, 2}) tmp_y[i] = tri_y[i] + epsilon_ * faceNormal_[x]; | ||
if (DistanceTriangleTriangleSquared(tri_x, tmp_y) > 0.0) return true; | ||
for (int i : {0, 1, 2}) tmp_y[i] = tri_y[i] - epsilon_ * faceNormal_[x]; | ||
if (DistanceTriangleTriangleSquared(tri_x, tmp_y) > 0.0) return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I don't think this can be merged now, because the self-intersection check causes quite a few failures. Some are probably fine (epsilon-valid because they are just touching), but some are probably not. Use the verbose option to print the information, because it can be quite long.
@elalish maybe you should have a look and play with this.