Replies: 7 comments 2 replies
-
Hi, Yes, the algorithm works mostly as described in your outline:
Everything is done in arbitrary precision. I have two kernels for that, one based on arithmetic expansions (shipped with geogram), but it is a bit slow, and can reach its precision limits with complicated inputs, so I developped a more efficient / more general one based on multi-precision Geogramplus, marketed by the Tessael company. (I'm currently writing an article about the algorithm, will post it on arXiv when it is ready). I think that what you suggest is possible, it is mostly a modification in the MeshSurfaceIntersection::classify() function: suppose you have a set of closed surfaces, a boolean expression |
Beta Was this translation helpful? Give feedback.
-
Everything will become clearer with the article and the figures (it is the type of things that are well explained with a couple of drawings). I also have a powerpoint presentation here that explains some generalities (but it does not have explanations on |
Beta Was this translation helpful? Give feedback.
-
It seems to me that the operand inclusion bits include all the information to perform my alternative operations. Right now, the only defined operations are (and, or, xor, diff) which correspond to and: AinB,BinA (where - means to flip the normal direction) My desire is to be able to handle operations like (where A is watertight and B is not) A,BinA One immediate challenge is one of nomenclature / symbology. Currently, the following syntax is accepted for BooleanExpression:
What symbols should be used for my 'new' operations? !@#$%<>?:;\ / Although an expression parser for traditional Boolean ops is pretty concise, I'm afraid that handling all the permutations of my possible operations will lead to a hot mess of a syntax (handled bidirectionally, that is 8 new symbols, yuck). Instead, I would propose that we use a more abstract syntax based on the in/out operator.
Which would allow us to write things like A, BinA as A+(B<A) I believe that all possible operations could actually be defined using just +,<,> Upon further thought, we will also need a symbol to flip the orientation of a surface. Although unary - fits the bill, I think it would be too confusing with the appropriately defined difference operator. I would propose something like / to flip the orientation. So my revised minimal set of operations would be +, /, <, > |
Beta Was this translation helpful? Give feedback.
-
you got it right, the "low-level" API can do more general n-ary boolean operation than what is exposed in the "high-level" API (union, intersection, difference, with two meshes only), and it works exactly as you have guessed. To test the functions, I have a simplified openSCAD clone here. It has a CSG API that implements (most of) OpenSCAD's operations. For now, to evaluate an OpenSCAD expression, I simply apply the CSG operations in the order I read them from the files. Once it fully works (I still have a few glitches to fix), I plan to implement some tree transformations, then it will use the more general boolean ops that fully use the boolean operation parser. It uses a bit n-ary operations, for union (but union does not use about what you want to do that is, if I understood well, get the part of a possibly open surface that falls into a region defined by a general boolean operation combining several closed surface, my intuition is that the current version of
Now in your case, you have your set of closed surfaces and the additional open surface. The idea is to proceed as follows:
Now can we do the same without writing a new |
Beta Was this translation helpful? Give feedback.
-
Thanks again for the helpful response. I have tested a little with a mix of thick and thin surfaces. So far, it gave promising results -- but I wasn't able to explain or understand those results. Without any changes to Geogram, what do you expect to have happen with open surfaces? Apparently all surfaces are duplicated to form the outside and inside skins. If there are border edges, they are stitched together to construct a thin volume. A boolean operation is performed. What happens with an intentionally open (thin, flat) mesh? What happens with an unintentionally open (say a sphere with a small hole in it) mesh? It may be that I can achieve what I need with no modifications -- or at least enough to keep moving forward for a while. |
Beta Was this translation helpful? Give feedback.
-
I need to return to this issue and to make progress. You had previously mentioned an article that was in the works that would help someone like me figure out how to make some of these changes. Has that paper been made available yet? What do you think is the best way to proceed? Is it better for you to give me some help, guiding me along the way? Or is it better for me to file and Issue report with clearly stated requirements and let you and your team work on it without me? I am very thankful for your time and effort that you provide so generously -- I do not want to be a burden. At the same time, I need to come to a way to make steady progress on my problem. |
Beta Was this translation helpful? Give feedback.
-
I've been studying the code quite diligently and am slowly gaining some understanding. It seems that for non-manifold surfaces, the inner and outer shell get merged together. This is mentioned here, but I see this happen for large holes and for intentionally planar objects. I don't necessarily see this as a problem, but we need to handle it properly in classify() (actually tentatively_classify_component_vertex_fast()). Right now, classification gives erratic results when the classifier is non-manifold. This is unsurprising because a point can't actually be inside or outside a non-watertight thing. In the extreme, think of the thing as a flat plane -- in 3D, you can't be inside or outside a plane. I propose that we either detect non-manifold shapes (perhaps test for number of shells != 2) or let the user identify an object as non-manifold when it is input. When classifying A in B, for non-manifold B, I propose we always return false (or true, but consistency is the key). We might want to pair this with returning true for B in B, but I'm not sure. |
Beta Was this translation helpful? Give feedback.
-
I have a CSG engine in my program that was developed long before modern ideas of robustness were developed. My code mostly works, but will not suffice for some planned growth. I am considering switching to Geogram as a replacement. This is attractive because it seems that Geogram's approach to CSG is very similar to the one I currently use. This is important because I also use these routines in some non-conventional ways -- and I will need to modify Geogram to behave similarly.
My program (and as I understand Geogram too) approaches CSG operations with the following steps.
Sometimes I need to perform Boolean operations where one of my two meshes is open (i.e. it does not enclose a watertight volume). This is not a bad or sloppy surface that is accidentally non-watertight. Instead, this is on purpose -- For example, one mesh is a sphere and the second mesh represents a thin surface. I will always know when I'm dealing with a thin surface, so I can follow a different code path (I don't need Geogram to auto detect this).
The first important difference is in classification -- since one surface is thin, it has no inside and outside, so it can not be used to classify triangles on the other surface. If we were operating on (A,C) where C is a thin surface, the end result of classification would be (A, CinA, CoutA).
There are different operations I might want to perform when doing this intersection -- sometimes I want to keep (A,CinA) or (A,CoutA), or just (CinA) or just (CoutA).
Somewhat similarly, there are times when I want to intersect two meshes (one or both may or may not be open or closed) and I wish to perform steps 1,2,3 -- but then I want to keep all of A or all of B. I.e. I want to 'impress' the intersection line of mesh B on A (and re-triangulate A to satisfy this intersection curve), but then only keep triangles from A.
From poking around a little, the Geogram API is set up for traditional Boolean operations, and it looks like all the pieces I need exist, but I'm not sure how to achieve what I need.
How would I go about achieving these goals with Geogram?
Beta Was this translation helpful? Give feedback.
All reactions