jimy-byerley / pymadcad

Simple yet powerful CAD (Computer Aided Design) library, written with Python.
https://madcad.netlify.app/
GNU Lesser General Public License v3.0
208 stars 16 forks source link

Problems with using booleans(Intersection) #2

Closed hit-the-luke closed 3 years ago

hit-the-luke commented 3 years ago

Hi,

I just installed pymadcad and going my first steps and I cant figure out how the boolean functions are supposed to work. The closest I have come to my expected result was with the following code:

  m1 = madcad.brick(width=madcad.vec3(2))
  m2 = m1.transform(madcad.vec3(1, -0.5, 1))
  print(m1)
  print(m2)
  m3 = madcad.boolean.intersectwith(m1, m2)
  print(madcad.Mesh(m3))

Am I using it wrong?

the corresponding output was the following:

Mesh(
  points= [dvec3(            1,           -1,           -1 ),
                      ...
           dvec3(           -1,            1,           -1 )],
  faces=  [(0, 1, 2),
           ...,
           (4, 0, 3),
           (4, 3, 7)],
  tracks= [0,
           0,
           1,
             ...
           5,
           5],
  groups= [None,
           None,
           None,
           None,
           None,
           None],
  options= {})
Mesh(
  points= [dvec3(            2,         -1.5,            0 ),
           dvec3(            2,         -1.5,            2 ),
           dvec3(            0,         -1.5,            2 ),
           dvec3(            0,         -1.5,            0 ),
           dvec3(            2,          0.5,            0 ),
           dvec3(            2,          0.5,            2 ),
           dvec3(            0,          0.5,            2 ),
           dvec3(            0,          0.5,            0 )],
  faces=  [(0, 1, 2),
           (0, 2, 3),
           ...
           (4, 3, 7)],
  tracks= [0,
           0,
           1,
           ...
           5,
           5],
  groups= [None,
           None,
           None,
           None,
           None,
           None],
  options= {})
Mesh(
  points= [((8, 9), 9),
           ((10, 9), 10),
           ((15, 13), 2),
           ((10, 13), 10),
           ((15, 17), 2),
           ((8, 17), 8)],
  faces=  [],
  tracks= [],
  groups= [],
  options= {})

Thanks a lot for in advance and for doing this project in general. It sounds really promising

Lukas

jimy-byerley commented 3 years ago

Hello

well there is definitely a bug in that case, but maybe that's not the only issue you were facing ? intersectwith(m1, m2) is just modifying the mesh m1 by intersecting its content with the mesh m2. It returns the intersection edges :)

what this code actually does

So executing the following code,

edges = madcad.boolean.intersectwith(m1, m2)
print('edges:', edges)
madcad.show([m1, m2], options={'display_wire':True})

you get output

edges: [((8, 9), 9), ((10, 9), 10), ((15, 13), 2), ((10, 13), 10), ((15, 17), 2), ((8, 17), 8)]

and the display: image

the bug

It doesn't happen using intersectwith, but with the next step: boolean.boolean() (or any of difference, union, intersection). Looking closer at the edges, you can notice that an edge of m1 gets exactly on one edge of m2 image

This is a case where somethimes the current implementation of the boolean algorithm fails, causing the following code to fail:

m1 = brick(width=vec3(2))
m2 = m1.transform(vec3(1, -0.5, 1))
m3 = boolean.difference(m1, m2)
madcad.show([m3], options={'display_wire':True})

(it runs into an infinite loop, thus never return)

The current sad workarround is to slightly move one of the meshes, to make the edge not intersecting:

m2 = m1.transform(vec3(1, -0.5, 1.001))

image

Well I have to make a fix for that ;)

hit-the-luke commented 3 years ago

Thank you very much for the quick Answer!! I could reproduce your solution. I am interested where you found the Algorithm you are referring to (syandana). I tried to have a look for it on the web, but google left me hanging there...

jimy-byerley commented 3 years ago

You're welcome !

I tried to have a look for it on the web, but google left me hanging there...

Oh that's ... because I created that algorithm ;) It's slightly different that usual O(n**2) algorithms because it's using spatial hashing and few other techniques.

I'm planning to put de detail in the 'algorithms' section of the documentation, but I didn't had time yet. I'm mostly busy with with a software I develop on top of pymadcad

jimy-byerley commented 3 years ago

I worked hard the two last days to fix all the known bugs of the boolean operations:

so everything should work fine now with the repo version Those fixes will be in the next release :)