Cut operation usage

Dear all,

We develop 3D modeler that allows to hollow one shape by several shapes. The shapes are designed thanks to BRepPrimAPI (box, cylinder, sphere,...) and the cut performed thanks to BRepAlgoAPI_Cut

We encounter sometimes some issue during the cut operation, the resulting shape does not match what we expect.

For example, it can result several shapes in the compound shape while only one shape should be produced, or sometimes the cut operation may totally fail (BRepAlgoAPI_Cut::BuilderCanWork() or IsDone() return 'false')

We would like to be able to detect theses wrong cases in order to solve the issue before performing the cut operation: More user friendly than tell to the user that the "hollowing is impossible"...

The cut process is a loop on the hollowing shapes with successive cut between the previous resulting shape and the current hollowing shape.

We have noticed in particular that the order of the hollowing shapes seems to be decisive : When we get a wrong result shape, sometimes we just have to change the order of the hollowing shapes to get the good result shape.

Do someone have some advise to get more robust and professional this cut operation with OCC ? Is there some rules to follow to insure the success of the cut operation (cutting with cube before cutting with cylinder i.e.) ?

Thank you in advance for your help

Jc

Qr Qr's picture

Probably, the most instructive advice would be to register all encountered issues in the bugtracker here: https://tracker.dev.opencascade.org/

Few hints on using the Boolean tools of OpenCascade are as follows (I hope other experienced users will add something):

1. Assure that you maximize faces and edges after each Boolean operation. It is not done automatically, so after the series of cuts, you may end up with inadequate topology on your B-Reps. Many [redundant] topological constraints is a bad luck for Booleans: robustness of the algorithm clearly depends on the number of edges and faces. Few days ago there was a report on Boolean failure on highly faceted polyhedra (https://www.opencascade.com/content/brepalgoapicut-wrong-cut-result), which is an illustrative example (and misuse of the algorithm at the same time). You'd better use ShapeUpgrade_UnifySameDomain utility to prepare your operands for the subsequent operations.

2. Sometimes intersection check fails because of facets (triangulation) which sit in your model. This may happen because the bounding boxes are be built on triangulation (if it exists), and sometimes the triangulation is too coarse. You can do an experiment by running Booleans on operands without Poly_Triangulation inside your faces, and check if it improves anything in your test cases. Notice that without facets the Booleans will work slower, but we speak about precision, not about efficiency.

3. Make sure that the tolerances of your shapes are Ok, and your shapes are valid in terms of basic "checkshape" Draw command (do you use Draw?). Notice that Boolean algorithm uses its own checklist for assessing the shape quality, but it is generally enough to assure that basic "checkshape" holds. If your shapes are Ok both in terms of the tolerances and the "checkshape" command, then you have all arguments to register an issue in the bugtracker. Basically, the most tricky situation for any geometric modeling algorithm is then your shapes are not in "general position", i.e. you have a tangency or an overlapping situation.

Generally speaking, the Boolean algorithm of OpenCascade is not bad at all. Just note, please, that it is open source, and your contribution with use cases will help to improve it further.

Petr Matousek's picture

Hello Qr,

thank you for your interesting hints. Can you please explain in more detail what you mean by the "maximize faces and edges after each Boolean operation"? Just use the ShapeUpgrade_UnifySameDomain utility or is there something else to do? In my case after a quite long series of boolean operations (tens to hundreds) I usually end up with an invalid shape. So I am definitely interested.

Another question is related to the PolyTriangulation of the faces. How to strip it from the faces if it is already there?

To add some of my own experiences with the boolean operations - in my case the precision of the inputs is causing the problems mostly. If you can fix the inaccurracies of the input shapes before calling the boolean operations then definitely do it, it will help you a lot. Other way to go I was suggested is to use the fuzzy boolean operations. So far I am trying to but with no much success see https://www.opencascade.com/content/how-guess-fuzzy-value-boolean-operat...

Petr

Qr Qr's picture

Hi Petr. Yes, for maximization in OpenCascade there is only one tool which is ShapeUpgrade_UnifySameDomain. It is not a part of Booleans, so you have to run it explicitly. I don't think there is any other pre-processing step you should apply on valid shapes. For sure, if your shape is invalid, then it is first necessary to recover its integrity, which is sometimes a very challenging operation to perform. The major issue you may face is degradation of tolerances. I.e. after series of modeling operations the tolerances of your models could happen to be worse than initial ones. The Booleans in OpenCascade are sensitive to that. Inherent tolerances are used internally for classification and intersection, so for very big tolerances it can end up with strange results. Notice that fuzzy value is nothing but a trick to make Booleans use *your* tolerance, and not the tolerance of your shapes. So there is no magic.

To conclude, try to make your operands as perfect as you can: unite edges, faces, decrease tolerance, ensure integrity in terms of "checkshape". If this does not help, report an issue to the bugtracker, so the development team can analyze what goes wrong.

Addendum: to clean up facets, use BRepTools::Clean().

Petr Matousek's picture

Hi Qr, thank you for your answer. Just for clarification:

"Notice that fuzzy value is nothing but a trick to make Booleans use *your* tolerance, and not the tolerance of your shapes. So there is no magic."

Does it mean that in case I use the fuzzy boolean operations it does not matter what the tolerances at particular vertices, edges, ... are? So in such case it does not make any sense to decrease the tolerances after a series of boolean operations?

Except ShapeUpgrade_UnifySameDomain and decreasing tolerances (by ShapeFix_ShapeTolerance::SetTolerance ()?) is there any other fixing APIs I can use to improve the quality of the boolean inputs?

Qr Qr's picture

According to BOPAlgo_ArgumentAnalyzer::UpdateTolerances() method, a "fuzzy" value will be *added* to the tolerances of your argument shapes. So I would be very careful with this kind of functionality, since "tolerance" is nothing but another word for "inaccuracy". For me, passing additional "fuzzy" value is equivalent to reduction of formal accuracy of your models (even if they are very accurate geometrically). And, yes, it should have the same effect as just pre-configuring the original tolerances of your shapes. The only difference I see here, is that Booleans + "fuzzy" value will attempt to keep your arguments untouched, which is not the case if you prepare them manually. In your case, I guess, this does not make too much sense.

What's for ShapeFix_ShapeTolerance, I wonder if it does not break integrity of your models. The matter is that in a healing procedure it is normally not enough just to set a smaller tolerance. A tolerance is a kind of a "shield" covering singularities of your models (by "singularity" I mean a geometric region there point membership classification is hardly possible). The bigger tolerance you have, the less accurate your geometry is. The tricky point here is to heal the geometry locally, so that you can reduce the tolerances accordingly. This is not so easy, and there are many companies which make money on such healing. For me, ideal workflow is [again] as follows:

1. Make sure that your inputs are valid in terms of BRepCheck_Analyzer (see "checkshape" command in Draw).

2. Make sure that your tolerances are reasonably small (at least comparing to the bounding size of your model).

3. Run Booleans.

4. Run face maximization.

5. Return to the stage 1.

6. If properties 1 or 2 do not hold after Booleans invocation, register an issue in the bugtracker.

Many people use Booleans of OpenCascade and, personally, I am one of them. So far, I can say that the workflow given above works quite well.