BRepAlgoAPI_Common - Finding the problem

Hello,
I´m currently facing some problems BRepAlgoAPI_Common algorithm when calculating the common between a box (solid) and a face (form of a cylinder). The ErrorStatus is 0 and the HasGenerated-Function return false. I have visualised the both shapes and the definetly intesect. Also check the orientation and so on... no problem. Has someone an idea to find out whats wrong???

Here a sample: http://rapidshare.com/files/270905274/TestShape.opn.html

Denis Teissandier's picture

You can try :
yourSolid.Orientation(TopAbs_REVERSED);
or yourSolid.Orientation(TopAbs_FORWARD);

Then apply BRepAlgoAPI_Common algorithm again.

the results shoud be different.

regards,

Denis

StefanKunze's picture

As I wrote... I checked that - changing the orientation still produces the same error.

StefanKunze's picture

Also checked the shapes with BRepCheck_Analyzer.
Hmmm I can´t see the problem... i´m sure it´s something simple.

Denis Teissandier's picture

If I understand you are trying to compute an intersection between a solid and a face (form of a cylinder).

Do you try to analyse the result of the method : SectionEdges() ?

Do you try to build a solid with your face and calculate again the intersection ?

Denis

StefanKunze's picture

Ok... at first - thanks for the tips.

As you suggested I make a solid from the form of the cylinder... the result is still the same.
SectionEdges() give me a list without elements (also when I create a solid of my shape/ cylinder)... which is regarding the visualisation impossible.

Not sure why why SectionEdges has no results... someone an idea??? The lower face of the cylinder lies in the same plane as one face of my cube - could this cause the wrong result???

StefanKunze's picture

Ok after some hours of try and error I figured out the problem and solved it. I´m trying to describe it:
I´m using two polygones (wires) to define the face. The polygones are always closed - meaning the first and the last point have the same coordinates. When building a face with such polygones BRepAlgoAPI_Common fails. To solve the problem simply leave out the last point and set the close-flag of BRepBuilderAPI_MakePolygon-object. In my eyes there is no different - but it seems to be handled different internally.

StefanKunze's picture

OK.... I was too optimistic - still have the problem under some cirumstances. Checked everything and now I have no more ideas what could be wrong. The hasGenerated - method returns false but the ErrorStatus said its all fine. Switch the orientation - same or wrong result. I will be thankful for any tip?!?!?

Here a sample file: 1 Solid and 1 face - calculate the common part results in nothing:
http://rapidshare.com/files/274665488/Sample.opn.html

Thanks in advance.. Stefan

StefanKunze's picture

Ok after some try and errors I figured out that the problem occurs when one side of the intersectionFace is tangency to on face of the solid. Has someone an idea of a wolkaround!?!?

Fotis Sioutis's picture

Can you post a .brep file ? I also have some strange cases with tangencies on cylinders and cubes , but my problem is with filleting.

Thanks

StefanKunze's picture
Fotis Sioutis's picture

I really don't know if the following will help , but here is how i solved your issue.

At first the shape created from the cylinder looks wrong with occ visualization, which usually shows an underlying issue ....

In order to have a valid result with your shape i had to apply C0 SurfaceContinuity and C1 CurveContinuity using ShapeProcessAPI_ApplySequence and providing the necesarry operators.This option splits the closed polygonal edge in distinct edges , which i am not so sure if this is right for your app.After applying the above the shape visualizes OK.Also afterwards Common opeation works without issues.

StefanKunze's picture

At first.... THX for the help. Before using ShapeProcessAPI_ApplySequence I will try to solve the underlying issue for the cylinder - maybe the problem solves itself.

The cuttet "cylinder" is created by defining two polygons (wires). With this functionality I create the resulting surface:

TopoDS_Face lFace;
Handle_Geom_BSplineCurve lFirstCurve,lSecondCurve;

BRepAdaptor_CompCurve lWireAdaptorOne(pFirstWire, Standard_False);
Handle_BRepAdaptor_HCompCurve lFirstCompCurve = new BRepAdaptor_HCompCurve(lWireAdaptorOne);
Approx_Curve3d lFirstApproxedCurve(lFirstCompCurve,TOLERANCE_3D_DISCRETISATION,GeomAbs_C0, NUMBER_OF_DISCRETIZATION_POINTS, MAXIMAL_DEGREE);
lFirstCurve = lFirstApproxedCurve.Curve();

BRepAdaptor_CompCurve lWireAdaptorTwo(pSecondWire, Standard_False );
Handle_BRepAdaptor_HCompCurve lSecondCompCurve = new BRepAdaptor_HCompCurve(lWireAdaptorTwo);
Approx_Curve3d lSecondApproxedCurve(lSecondCompCurve, TOLERANCE_3D_DISCRETISATION, GeomAbs_C0, NUMBER_OF_DISCRETIZATION_POINTS,MAXIMAL_DEGREE);
lSecondCurve = lSecondApproxedCurve.Curve();

lFace = BRepBuilderAPI_MakeFace(GeomFill::Surface(lFirstCurve, lSecondCurve));

Its working and the result seems to be ok for me.... do I miss something???
Best regards - Stefan

StefanKunze's picture

Hmm sorry for being such a pain... but could you provide the code how to make us of ShapeProcessAPI_ApplySequence please. I didn´t find any examples and my try and errors results in nothing.
Best regards - Stefan

Fotis Sioutis's picture

Try to use ShapeUpgrade_ShapeDivideContinuity.Its API is not so difficult (in case you may need some help check ShapeProcess_OperLibrary.cpp : splitcontinuity function).This part of code is used also from the higher level ShapeProcessAPI_ApplySequence which is used in order to apply a series of fixes-modifications to a shape.

Fotis

StefanKunze's picture

At first.... Thanks for the help Fotis!!!
Unfortunatly the modifications of the continuity doesn´t work for all my problematic cases. Here the code I used and a sample in which the BRepAlgoAPI_Common fails either.

Code:
ShapeUpgrade_ShapeDivideContinuity lShapeDivideContinuity;
lShapeDivideContinuity.Init(pFirstShape);
lShapeDivideContinuity.SetBoundaryCriterion(GeomAbs_Shape::GeomAbs_C1);
lShapeDivideContinuity.SetSurfaceCriterion(GeomAbs_Shape::GeomAbs_C0);
lShapeDivideContinuity.Perform();
lFirstInputShape = lShapeDivideContinuity.Result();

lShapeDivideContinuity.Init(pSecondShape);
lShapeDivideContinuity.SetBoundaryCriterion(GeomAbs_Shape::GeomAbs_C1);
lShapeDivideContinuity.SetSurfaceCriterion(GeomAbs_Shape::GeomAbs_C0);
lShapeDivideContinuity.Perform();
lSecondInputShape = lShapeDivideContinuity.Result();

BRepAlgoAPI_Common lCommon(lFirstInputShape,lSecondInputShape);

Sample:
http://rapidshare.com/files/278020411/CommonSample.brep.html

Best regards - Stefan

StefanKunze's picture

OK. Found the reason for the problem - didn´t set the correct continuity for the Approx_Curve3d-object.
Thanks Stefan

StefanKunze's picture

Ok... this BRepAlgoAPI_Common Class can really be paiiiiiinnfull... arg. I´ve check everthing basic wires, orientation, created solids, correct surface and boundary continuity etc. Unfortunately I get no result because HasGenerated is never true. Has someone an idea what else could be wrong??? Here a sample:
http://rapidshare.com/files/286468777/CommonProblem.brep.html

Any kind of tip or help is welcome.
Thanks in advance - Stefan

Fotis Sioutis's picture

Hello Stefan

Your beam (solid one) has problems(on the filleted faces of your beam there are free boundaries ) which in turn, they do not allow the BRepAlgoAPI_Common to work properly.After reconstructing the offending faces and recreating a valid solid BRepAlgoAPI_Common works like a charm.

Greets

Fotis

StefanKunze's picture

Could you please tell me how you reconstructed the offending faces. I didn´t get it worked. :(
Best regards - Stefan

jelle's picture

Sharing your curiosity! This is an illuminating thread...

Fotis Sioutis's picture

You free boundary edges can be checked using ShapeAnalysis_FreeBounds.(Propably you have already found that...).The reconstruction of the front and back faces from the beam has been accomplished using the following steps :

1)remove from the shell the front and back face (found with ShapeAnalysis).
2)using the remaining free edges, created two wires on each side with BRepBuilderAPI_MakeWire.
3)using the two wires on each side created the faces with BRepBuilderAPI_MakeFace.
4)Added the created faces on the shell with BRep_Builder::MakeShell
5)created a solid from the closed shell with BRep_Builder::MakeSolid

Writing this i see no reason also why it should not work only by sewing your shell properly and create a solid from it.(With BRepBuilderAPI_Sewing or ShHealOper_Sewing) (be careful you must apply a relatively big tolerance value in order to cover your gap).The above method i cannot test now since i am at home without access to a dev. environment, but i can give it a try tomorrow and post my results.

Fotis

StefanKunze's picture

Yeah I use BRepBuilderAPI_Sewing (and also tried it with BRepOffsetAPI_Sewing) to sew the single face to a solid - maybe the tolerance is to low - I will check that. Tommorow I will check your algorithm - hope it works.

Big Thanks - Stefan

Fotis Sioutis's picture

1)Sewing with a tolerance of 0.1 has succesfully closed your gaps.
2)Using the resulted water-tight shell i created a TopoDS_Solid.
3)BRepOffsetAPI_Sewing works fine with the above solid.

I hope i was of some help

Fotis

StefanKunze's picture

Ok I set the tolerance to 1 but it still doesn´t work. Depending on the shell I get a standard construction error or HasGenerated not becomes true.

After sewing the single faces to a solid - using BRepBuilderAPI_Sewing I used ShapeAnalyse_FreeBoundaries to find free boundaries. The resulting compound is empty - so I quess my solid is valid. Hmmm.... I´m using OCC v6.3 - is it possible that you are using version 6.3.1???

Fotis Sioutis's picture

Ok it seems you have overcome your sewing issue since there are no free boundaries reported.

It is very important also to create a solid from your shell.In my case it is done as following :

BRepCheck_Shell chkShell(TopoDS::Shell(aShapeShell));
if(chkShell.Closed() == BRepCheck_NotClosed) return 0;

TopoDS_Solid Sol;
B.MakeSolid(Sol);
B.Add(Sol, aShapeShell);
BRepClass3d_SolidClassifier SC (Sol);
SC.PerformInfinitePoint(Precision::Confusion());
if (SC.State() == TopAbs_IN) {
B.MakeSolid(Sol);
B.Add(Sol, aShapeShell.Reversed());
}

aShape = Sol;

Having a watertight shell(your case) is a diferent case than having a topologically correct solid.

Fotis

StefanKunze's picture

I`m sure I do so... here the function creating a solid from the single faces:

TopoDS_Solid SewShapeToSolid(TopoDS_Shape pShape)
{
// error check
if (pShape.IsNull())
return NULL;

BRep_Builder lBuilder;
BRepBuilderAPI_Sewing lFaceSewer;
TopoDS_Shell lSewedShell;
TopoDS_Solid lSolid, lResult;

// make solids
lBuilder.MakeSolid(lSolid);
lBuilder.MakeSolid(lResult);

// explore all faces from source and add it to the target
for (TopExp_Explorer lExplorer(pShape,TopAbs_ShapeEnum::TopAbs_FACE); lExplorer.More(); lExplorer.Next())
lFaceSewer.Add(TopoDS::Face(lExplorer.Current()));

// perform
lFaceSewer.SetTolerance(1.000);
lFaceSewer.Perform();

// check
lSewedShell= TopoDS::Shell(lFaceSewer.SewedShape());
if(lSewedShell.Closed() == Standard_False)
return NULL;

lBuilder.Add(lSolid, lSewedShell);

BRepClass3d_SolidClassifier SC (lSolid);
SC.PerformInfinitePoint(Precision::Confusion());
if (SC.State() == TopAbs_IN)
lBuilder.Add(lResult, lSolid.Reversed());
else
lBuilder.Add(lResult, lSolid);

return lResult;

}

Here again the file http://rapidshare.com/files/287693855/Common.brep.html
Thank for sharing your thoughts!!!

Fotis Sioutis's picture

1)The new shape you posted is different than the previous.The exact algo i proposed is working with http://rapidshare.com/files/286468777/CommonProblem.brep.html

2)Your new shape needs two things :
a)The solid beam has cn continuity and this is something most high level occ algos do not like so much, so it needed the above proposed method to limit it.

b)The shell part contains faces which they are not sewed ! Applying sewing to the shell is needed

After the above also this case works properly

Fotis

StefanKunze's picture

Yeahh - that did the trick. THANK U VERY MUCH....
A strange behaviour I registered - when I put a simple plane into my function sewing all available faces to a shell - the algorithm crashes too.