8000 update tolerance defaults by elalish · Pull Request #1007 · elalish/manifold · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

update tolerance defaults #1007

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

Merged
merged 6 commits into from
Oct 29, 2024
Merged

update tolerance defaults #1007

merged 6 commits into from
Oct 29, 2024

Conversation

elalish
Copy link
Owner
@elalish elalish commented Oct 22, 2024

Now input MeshGLs get a default tolerance of 1e-6 * scale, reflecting the uncertainty of their coordinates, and more closely aligning with the amount of default decimation we did before the update to double precision. The tolerance is likewise reduced for the floating point output of MeshGL.

@elalish elalish self-assigned this Oct 22, 2024
@elalish elalish requested a review from pca006132 October 22, 2024 21:43
@elalish
Copy link
Owner Author
elalish commented Oct 22, 2024

I believe this now also covers the TODO list from #997. However, in the process of adding the test, I found a serious problem with our simplification:
image
Basically lots of edges are being marked short and then being consecutively collapsed until far too large a change has been made. I'm going to have to think about how best to fix that.

@@ -206,7 +206,7 @@ void Manifold::Impl::SimplifyTopology() {
{
ZoneScopedN("CollapseShortEdge");
numFlagged = 0;
ShortEdge se{halfedge_, vertPos_, tolerance_};
ShortEdge se{halfedge_, vertPos_, epsilon_};
Copy link
Owner Author

Choose a reason for hiding this comment

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

This is my quick fix - seems to be working okay. I need to come back and think about this more deeply sometime, but I think this will be okay for v3.0 - it's pretty close to what we were doing before.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I think we just need to get the APIs correct for v3.0, detailed implementation can be done a bit later.


EXPECT_EQ(cylinder.NumTri(), 3996);
EXPECT_EQ(cylinder2.NumTri(), 3996);
EXPECT_EQ(cylinder3.NumTri(), 3996);
Copy link
Owner Author

Choose a reason for hiding this comment

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

This is kind of a stupid test right now - the high res cylinder bends too much, so CreateFaces gives up and doesn't allow any simplification at all. This was true before too - our SimplifyTopology is not a real decimator; it's considerably simpler. However, we should probably come back someday and turn it into a proper decimator.

Meanwhile, I'll update this test to something more useful before we merge this PR.

Copy link
Collaborator
@pca006132 pca006132 left a comment

Choose a reason for hiding this comment

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

Nice catch! I am sure there should be papers on fast mesh decimation, maybe we should look into that later?

out.tolerance =
std::max(out.tolerance,
static_cast<Precision>(std::numeric_limits<float>::epsilon() *
impl.bBox_.Scale()));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we perform simplification after this?

Copy link
Owner Author

Choose a reason for hiding this comment

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

Huh, that's an interesting idea. It feels kind of wrong because you'd have to pay the cost of an extra simplification check on every mesh output, as well as paying the cost of extra faces in all of the boolean operations up to that point. It would be much better to set tolerance to the right level earlier instead. I feel like we should design our API to push people toward that golden path.

* Returns the tolerance of this Manifold's vertices.
* Edges shorter than this tolerance value will be collapsed.
* Returns the tolerance value of this Manifold. Triangles that are coplanar
* within tolerance tend to be merged and edges shorter than tolerance tend to
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm thinking if this will be true later when we implement better simplification. Not sure how to express this properly, but the final result should be between dilation and erosion by epsilon?

@@ -206,7 +206,7 @@ void Manifold::Impl::SimplifyTopology() {
{
ZoneScopedN("CollapseShortEdge");
numFlagged = 0;
ShortEdge se{halfedge_, vertPos_, tolerance_};
ShortEdge se{halfedge_, vertPos_, epsilon_};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I think we just need to get the APIs correct for v3.0, detailed implementation can be done a bit later.

@starseeker
Copy link
Contributor
starseeker commented Oct 23, 2024

Nice catch! I am sure there should be papers on fast mesh decimation, maybe we should look into that later?

I doubt the code would be a good fit for Manifold as-is, but Alexis Naveros has done quite a bit of work on a liberally licensed mesh decimation implementation that might be a useful resource: https://github.com/BRL-CAD/mmesh/blob/main/src/meshdecimation.c (He tends to heavily optimize his codes for high performance, so there's a lot of logic in mmesh pertaining to that sort of optimization in addition to the decimation algorithms themselves.)

We're currently using an older version of that code as one of the BRL-CAD options for decimation (still need to update to that newer mmesh version - ah, the never ending TODO list...) and it does pretty well in my experience at decimating without "ruining" the mesh shape. I tried wiring up the OpenMesh decimation as an alternative and had problems with the output from it not being manifold, so that's at least one data point. It might be simpler overall to grab a paper and start fresh, but I figured I might as well raise awareness just in case.

@elalish
Copy link
Owner Author
elalish commented Oct 25, 2024

Well, this is irritating - finally got some time to work on this again and without any changes on my side, suddenly my Mac is giving me a pile of fatal error: 'cstdint' file not found - apparently it suddenly can't find its own standard library? WTF?

Since I couldn't think of anything else to do, I went ahead and upgraded OS 14 to OS 15 and did a big brew upgrade of all my dependencies and upped my compiler from clang 15 to clang 16. Still no luck - exactly the same errors. Has anyone seen this on a mac lately? I'm a bit at a loss as to how to tell it how to find its own STL.

@pca006132
Copy link
Collaborator

Did you try a clean build? This sounds really weird...

@elalish
Copy link
Owner Author
elalish commented Oct 26, 2024

No, plenty of clean builds have had no effect. This is what it looks like - does anyone see anything weird about the command? It fails the same way on any file (fatal for whatever STL lib is included):

[build] [ 16%] Building CXX object bindings/python/CMakeFiles/nanobind-static.dir/__/__/_deps/nanobind-src/src/implicit.cpp.o
[build] cd /Users/elalish/Code/manifold/build/bindings/python && /usr/bin/clang++ -DNB_COMPACT_ASSERTIONS -I/Users/elalish/Code/manifold/build/_deps/nanobind-src/ext/robin_map/include -I/opt/homebrew/opt/python@3.13/Frameworks/Python.framework/Versions/3.13/include/python3.13 -I/Users/elalish/Code/manifold/build/_deps/nanobind-src/include -isystem /Library/Developer/CommandLineTools/usr/include/c++/v1 -isystem /Library/Developer/CommandLineTools/usr/lib/clang/16/include -isystem /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/usr/include -isystem /Library/Developer/CommandLineTools/usr/include -O3 -DNDEBUG -std=c++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk -fPIC -fvisibility=hidden -fno-strict-aliasing -MD -MT bindings/python/CMakeFiles/nanobind-static.dir/__/__/_deps/nanobind-src/src/implicit.cpp.o -MF CMakeFiles/nanobind-static.dir/__/__/_deps/nanobind-src/src/implicit.cpp.o.d -o CMakeFiles/nanobind-static.dir/__/__/_deps/nanobind-src/src/implicit.cpp.o -c /Users/elalish/Code/manifold/build/_deps/nanobind-src/src/implicit.cpp
[build] In file included from /Users/elalish/Code/manifold/build/_deps/nanobind-src/src/trampoline.cpp:10:
[build] In file included from /Users/elalish/Code/manifold/build/_deps/nanobind-src/include/nanobind/trampoline.h:13:
[build] /Users/elalish/Code/manifold/build/_deps/nanobind-src/include/nanobind/nanobind.h:30:10: fatal error: 'cstdint' file not found

@pca006132
Copy link
Collaborator

By clean build, are you just trying ninja clean or did you remove the entire build directory?

@elalish
Copy link
Owner Author
elalish commented Oct 28, 2024

Removed the whole build directory. Very strange.

@pca006132
Copy link
Collaborator

is there an option to install libc++ (dev version)? sounds very weird

@elalish
Copy link
Owner Author
elalish commented Oct 28, 2024

I don't know - but I can't even build a simple C++ test project now. I think I got screwed by some background update. Super weird.

@pca006132
Copy link
Collaborator

Maybe try to use a docker environment for now?

@elalish
Copy link
Owner Author
elalish commented Oct 28, 2024

Yay, I managed to fix my build! My only guess is that somehow Clang's paths got messed up internally - I had to not only upgrade XCode and the command line tools, but actually build a C++ "hello world" program in XCode - which worked and somehow fixed the broken paths. Now my VSCode builds work too. So strange.


EXPECT_EQ(imperfect.NumTri(), 28);
EXPECT_EQ(imperfect2.NumTri(), 16); // TODO: should be 12
EXPECT_EQ(imperfect3.NumTri(), 22); // TODO: should be 12
Copy link
Owner Author

Choose a reason for hiding this comment

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

Our simplification is obviously failing here, but I don't think it's due to the tolerance work in this PR (e.g. no change with a larger value). I think I'll merge this for now and come back and work on our simplification later.

@elalish elalish merged commit d1a8de2 into master Oct 29, 2024
19 checks passed
@elalish elalish deleted the floatTolerance branch October 29, 2024 16:42
@pca006132
Copy link
Collaborator

I have been thinking about the mesh simplification thing. I think it is probably impossible to guarantee the result of applying several consecutive simplifications to be equivalent to the result of applying simplification once, considering the process is lossy. And this makes it hard to have guarantees on boolean results, e.g. simpilfy(simplify(A) & simplify(B)) can be very different from simplify(A & B)...

@elalish
Copy link
Owner Author
elalish commented Oct 31, 2024

Agreed that it's not exactly the same, but I think I feel okay as long as it's giving "good" results - along the lines of the volume and surface area are still close, or ideally some metric on maximum difference between the shapes (which we should probably implement someday). If you can find a situation where it's drifting way too much, please open a bug. It'll be helpful when I go through and overhaul the simplification.

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.

3 participants
0