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

Object formed by extrusion is not solid #412

Closed
nrnrnr opened this issue Apr 12, 2022 · 4 comments · Fixed by #469
Closed

Object formed by extrusion is not solid #412

nrnrnr opened this issue Apr 12, 2022 · 4 comments · Fixed by #469

Comments

@nrnrnr
Copy link

nrnrnr commented Apr 12, 2022

I've defined objects using the following code (complete code in attachments):

test_shape :: ℝ -> SymbolicObj2
test_shape k =
    intersect
    [ implicit (shape k circle_diameter_bottom (twice circle_height))
                   ((-9, -5), (9, 10))
    , rectR 0 (-15, 0) (15, 25)
    ]

test_solid :: ℝ -> SymbolicObj3
test_solid k = extrudeR 0.0 (test_shape k) 7

When I render the two-dimensional test_shape as a PNG, it shows as a solid rectangle with a semicircular bite taken out of it, as expected. But when that shape is extruded into a solid and written as an STL, the resulting STL isn't solid; it's just a bunch of surfaces glued together.

The documentation for the Haskell API is a bit thin, so I'm not sure if there is a fault in the library or if I just don't understand the API. If it's an API misunderstanding, perhaps we can clear it up and I'll send you a PR with revised documentation?

Here is a zip file with the complete source code and the output STL

@sorki
Copy link
Contributor

sorki commented May 5, 2022

I've updated your code to work with most recent version and managed to reproduce the problem. I think it is a bug but it's not clear to me what is causing it.

Updated code and pics following:

module Main
where

import Prelude
import Graphics.Implicit
import Graphics.Implicit.Definitions

circle_diameter_bottom = 14.80 -- mm
circle_height = 9.86

root ::  ->  -> 
root n x = x ** (1/n)

shape n width height (V2 x y) =
    1 - root n ((x / half width) ** n + (y / half height) ** n)

half k = k / 2
twice k = 2 * k

test_shape ::  -> SymbolicObj2
test_shape k =
    intersect
    [ implicit
        (shape k circle_diameter_bottom (twice circle_height))
        (V2 (-9) (-5), V2 9 10)
    , rect (V2 (-15) 0) (V2 15 25)
    ]

test_solid ::  -> SymbolicObj3
test_solid k = extrude (test_shape k) 7

main :: IO ()
main = do
  writePNG2 0.5 "test.png" $ test_shape 2
  writeSVG 0.5 "test.svg" $ test_shape 2
  writeSTL 0.5 "test.stl" $ test_solid 2

test
test
test00

@nrnrnr
Copy link
Author

nrnrnr commented May 6, 2022

OK. Thanks for having a look. I'll sit tight.

@lepsa
Copy link
Contributor

lepsa commented Nov 14, 2022

The SVG not having lines for the top or sides is making me think that something is going wrong somewhere at the 2D level, and it might not be an extrusion issue. I'll have a bit of a poke around and see if I can find anything.

@lepsa
Copy link
Contributor

lepsa commented Nov 14, 2022

OK, so I have a finding, and some reasoning as to why we are seeing the missing edges, and a work around for now.

Background
The implicit shape function is trying to generate an infinite plane except for the curve in the middle. This can be seen by just rendering the implicit function with a large bounding box. It'll always draw more. The problem seems to lie in the bounding box for this infinite plane.

Workaround
Setting the bounding box to (pure (-infty), pure infty) allows the shape to properly render the intersection, showing the rest of the rectangle.

Thoughts
From some quick experiments, I think that this will happen whenever the bounding box for an infinite surface doesn't entirely contain the bounding boxes for finite surfaces. I suspect that this is because when the intersection of the boxes is taken, the new bounding box is inside what should be considered solid. The effect of this is that when the bounding box is reached for rendering, nothing more is done and an edge can't be drawn because the implicit functions haven't indicated that one should exist at that position.

As to why the 2D render is showing the bounding box as solid, while the SVG and 3D render aren't I suspect either a bug somewhere in the render for 2D STL or that STL itself is using the bounding box of the render as implicit edges and filling in the gaps. I haven't looked into if this is the case or not however.

Followup

  • We should have a look into the rendering code and check why the 2D STL and PNG is outputting a solid shape when SVG and 3D STL aren't.
  • We should have a look into if we can use the bounding box in rendering to act as a backup edge if the implicit function at the same location is still saying that we are inside the solid.
  • If we are happy with the work around for now, we should add a note to the docs about this caveat, and possibly a second version of the implicit function along the lines of implicitInfinite f = implicit f (pure (-infty), pure infty)

@julialongtin I'll probably need to pick your brains about the rendering code if I dig into this more, consider this a heads up.

image

lepsa added a commit to lepsa/ImplicitCAD that referenced this issue Nov 15, 2022
Bounding boxes now work as edges when using `implicit` defined surfaces.
This allows the use of infinite surface functions with a finite bounding
box to work with operations such as `intersect`.

Haskell-Things#412
lepsa added a commit to lepsa/ImplicitCAD that referenced this issue Nov 15, 2022
Bounding boxes now work as edges when using `implicit` defined surfaces.
This allows the use of infinite surface functions with a finite bounding
box to work with operations such as `intersect`.

Haskell-Things#412
lepsa added a commit to lepsa/ImplicitCAD that referenced this issue Nov 15, 2022
Bounding boxes now work as edges when using `implicit` defined surfaces.
This allows the use of infinite surface functions with a finite bounding
box to work with operations such as `intersect`.

Haskell-Things#412
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants