-
Notifications
You must be signed in to change notification settings - Fork 101
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
Add Offset #668
Add Offset #668
Conversation
As @zalo also found, this is basically a fuzz test for the Boolean due to using so many coplanar objects. The outset looks reasonable: but it has a terrible genus, and the inset makes it clearer what is going wrong internally: Most of these shards are due to bad symbolic perturbation (I think). Then there's lots of trouble with CW triangulation, due to self-intersecting polygons - I have a hunch about this problem too. And of course it's highly order-dependent and not infrequently seg-faults, which is the worst part. Since Anyway, even if this doesn't eventually become our API, it's serving as a good test case. |
Nice! The inset parameter makes a lot of sense; I feel silly for not including it. Do you notice any seams/artifacts between the extruded triangles and the low-resolution spheres? If so, I feel like it might be worth rotating the spheres/cylinders so they have at least one vertex aligned with the adjacent extruding triangle 🤔 Also, I wonder at the speed difference between hulling two spheres and unioning two spheres and a cylinder… I’ll look at the implementation more carefully tomorrow when I’m on a real PC again 😄 |
Yes, there are little dimples - I'm considering tweaking the precision to see if I can just decimate them out. Our spheres are tessellated octahedra, which I think already have the nicely aligned verts you're thinking of. I don't think it's worth rotating though, since having only one vert aligned isn't much better than none. The idea with unioning these separately is that with the hulls you're effectively unioning the same sphere 6 times (since that vert is part of 6 triangles), where I'm just doing it once. Plus, unioning shapes with identical faces is the slowest part, since you get lots of collisions to check. Still, I'm curious how much difference it makes in practice; would love to see some comparisons! |
I added just the Naive NonConvex-Convex method to your branch as a point of comparison:
Seems like it's twice as slow, but it returns the correct Genus 🤔
Ah, just saw your reply! The hulling method gets around this by just sweeping the same low-res sphere everywhere, but of course, that's where all of the slowness comes from. Perhaps the hull method can be sped up by sweeping just a few vertices of the sphere on triangle faces, but the whole thing on convexEdges/Points? Perhaps duplicate vertices/faces can be added to a hashmap and checked for in O(1)? |
Yeah, you get the right genus because you aren't unioning barely-touching extrusions like I am. I'm going to focus on fixing the Boolean problems this has revealed. |
If you'd like some mesh inspiration from OpenCascade's Offset Operation: It's kind of unfair given the amount of code OpenCascade needs to achieve this (and they don’t even try to handle self intersections), but look at that topology! 😄 EDIT: The key insight in OpenCascade is that every "Face" can be reduced to a boundary polygon in some 2D UV space, where it can be delaunay triangulated and lifted back to the 3D space. This means that it's trivial to ensure vertices are sewn together if they share the same boundary polygon edges. If the final destinations of the extruded triangle vertices are kept track of, then it might be straight-forward to construct these boundaries... |
Nice work! I have less capacity currently as I am working on a new openscad interpreter (https://github.com/pca006132/sscad). It is basically a minimal implementation of openscad's script, with cleaner code, less dependencies and hopefully faster speed. The goal is to use it in manifoldcad, python (maybe @wrongbad will be interested), and eventually as experimental alternative code backend for openscad. I want to get something working before next year, so I am pretty busy with it. Will have a look at offset and minkowski later after I get something running. |
Closing in favor of #666. |
edge.y *= -1; | ||
batch[edgeOffset + idx] = | ||
cylinder.Scale({1, 1, length}) | ||
.Transform(RotateUp(edge)) |
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.
@starseeker This might help you.
Inspired by and related to #666, this is an Offset function, so a Minkowski only with a sphere (positive or negative). I used convexity to apply fewer edge and vert Booleans.