jamesgregson / pyPolyCSG

A Polyhedral CSG library for Python
Other
17 stars 7 forks source link

Bug: RuntimeError: unidentifiable C++ exception #6

Open dbc opened 11 years ago

dbc commented 11 years ago

Simple test case iteratively subtracting a cylinder from a block fails with "unidentifiable C++ exception"

import pyPolyCSG as csg

#probe = 0.9 # works
#probe = 1.0 # works
probe = 1.1 # fails
#probe = 2.0 # fails

block = csg.box(6,2,4,True)
cyl = csg.cylinder(1,4,True)
cyl = cyl.translate(0,probe,0)

offset = 4
i = 0 # keep track of which iteration failed
while offset > -0.4:
    print i
    i += 1
    tool = cyl.translate(offset,0,0)
    block -= tool
    offset -= 0.5

traceback:

>>> ================================ RESTART ================================
>>> 
0
1
2
3
4

Traceback (most recent call last):
  File "****/bug01.py", line 18, in <module>
    block -= tool
RuntimeError: unidentifiable C++ exception

and in the terminal window running idle:

FACE LOOP ERROR: 0x2918e88-0x2919540 : 2
FACE LOOP ERROR: 0x2918fa0-0x2919338 : 2
FACE LOOP ERROR: 0x2918f00-0x2919108 : 2
FACE LOOP ERROR: 0x29193d8-0x2919568 : 2
FACE LOOP ERROR: 0x2918e60-0x29193b0 : -2
FACE LOOP ERROR: 0x2919108-0x29193b0 : 2
FACE LOOP ERROR: 0x2919518-0x2924a58 : -2
FACE LOOP ERROR: 0x29193d8-0x2919518 : -2
FACE LOOP ERROR: 0x29190e0-0x2924a58 : 2
FACE LOOP ERROR: 0x2918ed8-0x2919568 : -2
FACE LOOP ERROR: 0x2918f78-0x2924a30 : 2
FACE LOOP ERROR: 0x2918e60-0x29190e0 : 2
FACE LOOP ERROR: 0x2918f78-0x2919540 : -2
FACE LOOP ERROR: 0x2918f00-0x29194a0 : -2
FACE LOOP ERROR: 0x29191a8-0x29194a0 : 2
FACE LOOP ERROR: 0x2918ed8-0x2918fa0 : 2
FACE LOOP ERROR: 0x29191a8-0x2924a30 : -2
FACE LOOP ERROR: 0x2918e88-0x2919338 : -2

The "FACE LOOP" message seems to come from: carve/lib/intersect.cpp

There are 3 open bugs on Carve's issue tracker metioning 'FACE LOOP ERROR', and some Blender issues mentioning 'FACE LOOP ERROR'. These might be coming from an intersect operation leaving behind a degenerate mesh, causing problems for the next intersection operation. Or maybe not. I see Carve defines a Polyhedron::canonicalize() method which you are not yet exporting. I'm speculating that canonicalize() might be worth experimenting with.


Additional info: I speculate that this may be related to the cylinder having a flat bottom -- if I replace the cylinder with a sphere and try the same simulation, I can try many different sizes of sphere and step sizes and it all works fine.


Annnnnnd.... another update. Changing cylinder creation to:

cyl = csg.cylinder(1,4,True)
cyl = cyl.rotate(0,0,0.1)
cyl = cyl.translate(0,probe,0)

will make the tests pass. So rotation in Z works around what ever bug is showing up here. That kind of blows the flat-bottom theory out of the water.

jamesgregson commented 11 years ago

Hi Dave,

Thanks for your interest in the library! I'm on vacation for the next two weeks with limited Internet access and will look into your additions and bug reports when I'm back home.

Best regards,

James G.

On Wednesday, November 14, 2012, Dave Curtis wrote:

Simple test case iteratively subtracting a cylinder from a block fails with "unidentifiable C++ exception"

import pyPolyCSG as csg

probe = 0.9 # works

probe = 1.0 # works

probe = 1.1 # fails

probe = 2.0 # fails

block = csg.box(6,2,4,True) cyl = csg.cylinder(1,4,True) cyl = cyl.translate(0,probe,0)

offset = 4 i = 0 # keep track of which iteration failed while offset > -0.4: print i i += 1 tool = cyl.translate(offset,0,0) block -= tool offset -= 0.5

traceback:

================================ RESTART ================================

0 1 2 3 4

Traceback (most recent call last): File "****/bug01.py", line 18, in block -= tool RuntimeError: unidentifiable C++ exception

— Reply to this email directly or view it on GitHubhttps://github.com/jamesgregson/pyPolyCSG/issues/6.

rrix commented 11 years ago

Hi James, have you had any chance to take a look at these and similar issues? I am doing some intersections which carve should be able to handle, and CGAL is able to handle, but i am getting this error.

In my case, I am importing a pair of meshes which are taken from openscad code centered on the origin, and then trying to apply an intersection to them. They don't share any faces, and the models themselves are perfectly valid. Heck, even blender can use Carve to do these intersections. Not sure where to go with this from here, since I am relatively new to using Carve and your wrapper library

jamesgregson commented 11 years ago

Hi,

Without having the meshes/script to try out for myself I'm not able to comment on your specific case. Blender may be working around failures in Carve this by perturbing the models slightly (or using an alternate workaround), which my wrapper does not do.

The example that Dave posted generates lots of potentially degenerate cases: vertex-vertex collisions, coincident faces, etc. This is why rotating the cylinder (perturbing the geometry) allows the test to succeed, and a similar approach may work in your case. Carve -should- be able to handle this (without perturbation) but often does not. It also hasn't been updated in quite some time judging by the Google code site so I don't expect these issues to get resolved.

My plan to improve robustness is to use CGAL rather than Carve. However until very recently there was not much I could do about this because CGAL would not build properly under OS-X (my development machine) using the LLVM/CLANG compiler that was shipped with the Apple developer tools by default. This was due to a missing feature (spec-compliant rounding modes) in LLVM/CLANG that CGAL depends upon heavily for robust geometric predicates. As I understand it, CGAL now supports the default Apple compiler, so I hope to pick up where I had left off on implementing a CGAL backend to pyPolyCSG. I don't know when I will get a chance to finish this however.

James

rrix commented 11 years ago

What are the perfomance characteristics of CGAL versus Carve? We opted to use Carve (and thus this library) as opposed to CGAL because because the speed of CGAL's operations left much to be desired.

I can put together a minimal test case of two loaded meshes being intersected tonight. Jiggling the objects around didn't seem to have much affect, but if there is a simple way to push them in to working, I would love to know about it.

jamesgregson commented 11 years ago

CGAL seems to be -way- slower, but also way more reliable than Carve.

Speed/portability is the reason I originally went with Carve, hoping that it would live up to the robustness claims on the website. I will probably take a look at the blender source to see if there's something simple that can be done to get more reliable boolean ops without losing the speed advantage.

dbc commented 11 years ago

Sorry to post to a necro-thread, but since this is still open.... I have a friend with a lot of CGAL experience, so I could quiz him if you want more CGAL info. In general, yes, CGAL will go much slower, because the normal build method is to use their own rational arithmetic library instead of floating point. All numbers are represented exactly as rationals using arbitrarily long sums of integer fractions. Irrational numbers are forbidden, which includes pi, so there is no such thing as a curve in CGAL, only arbitrarily fine-grained polygons. I belive CGAL can be compiled to use floating point math, but then it suffers from some of the same issues as other CSG packages, as I understand it.