Eliminate numerical instability by ensuring that the tolerance of intersection entities is slightly grater than the actual distance to the shapes creating the entity.
const Handle(BOPDS_PaveBlock)& aPB = theVEPairs.FindKey(i);
Standard_Integer nE = aPB->OriginalEdge();
//
+ TColStd_MapOfInteger aMVPB;
+ const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE);
+ for (BOPDS_ListOfPaveBlock::Iterator itPB (aLPB); itPB.More(); itPB.Next())
+ {
+ aMVPB.Add (itPB.Value()->Pave1().Index());
+ aMVPB.Add (itPB.Value()->Pave2().Index());
+ }
+
const TColStd_ListOfInteger& aLV = theVEPairs(i);
TColStd_ListIteratorOfListOfInteger aItLV(aLV);
for (; aItLV.More(); aItLV.Next()) {
Standard_Integer nVSD = nV;
myDS->HasShapeSD(nV, nVSD);
//
+ if (aMVPB.Contains (nVSD))
+ continue;
+
BOPDS_Pair aPair(nVSD, nE);
TColStd_ListOfInteger* pLI = aDMVSD.ChangeSeek(aPair);
if (pLI) {
Standard_Integer nVx = UpdateVertex(nV, aTolVNew);
// 2. Create new pave and add it as extra pave to pave block
// for further splitting of the edge
- const Handle(BOPDS_PaveBlock)& aPB = aVESolver.PaveBlock();
+ const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE);
+ // Find the appropriate one
+ Handle(BOPDS_PaveBlock) aPB;
+ BOPDS_ListOfPaveBlock::Iterator itPB (aLPB);
+ for (; itPB.More(); itPB.Next())
+ {
+ aPB = itPB.Value();
+ Standard_Real aT1, aT2;
+ aPB->Range (aT1, aT2);
+ if (aT > aT1 && aT < aT2)
+ break;
+ }
+ if (!itPB.More())
+ continue;
+
BOPDS_Pave aPave;
aPave.SetIndex(nVx);
aPave.SetParameter(aT);
Standard_Integer nVUsed;
Standard_Real aPTol, aDTol;
//
- aDTol = 1.e-12;
+ aDTol = BOPTools_AlgoTools::DTolerance();
//
GeomAdaptor_Curve aGAC(aIC.Curve());
aPTol = aGAC.Resolution(Max(aTolR3D, aTolV));
aTolV = BRep_Tool::Tolerance(aV);
gp_Pnt aP2 = BRep_Tool::Pnt(aV);
Standard_Real aDist = aP1.Distance(aP2);
- if (aDist > aTolV) {
+ if (aTolV < aDist + aDTol)
+ {
BRep_Builder().UpdateVertex(aV, aDist + aDTol);
//
if (!aMVTol.IsBound(nV)) {
if (aDistVP > aTolV)
{
- Standard_Integer nVn = UpdateVertex(nV, aDistVP);
+ Standard_Integer nVn = UpdateVertex(nV, aDistVP + BOPTools_AlgoTools::DTolerance());
if (nVn != nV)
{
aPave.SetIndex(nVn);
aD2=aP3D.SquareDistance(aP3Dx);
if (aD2>aTolV2) {
aD=sqrt(aD2);
- aBB.UpdateVertex(aV[j], aD);
+ aBB.UpdateVertex(aV[j], aD + BOPTools_AlgoTools::DTolerance());
}
}
}
TopoDS_Edge& theE)
{
BRep_Builder aBB;
- Standard_Real aNeedTol = theTolR3D + 1e-12;
+ Standard_Real aNeedTol = theTolR3D + BOPTools_AlgoTools::DTolerance();
//
aBB.UpdateVertex(theV1, aNeedTol);
aBB.UpdateVertex(theV2, aNeedTol);
DEFINE_STANDARD_ALLOC
+public: //! @name Constants
+
+ //! Additional tolerance (delta tolerance) is used in Boolean Operations
+ //! to ensure that the tolerance of new/old entities obtained
+ //! by intersection of two shapes is slightly bigger than the actual
+ //! distances to these shapes. It helps to avoid numerical instability
+ //! which may occur when comparing distances and tolerances.
+ static Standard_Real DTolerance() { return 1.e-12; }
+
public: //! @name Intersection of the vertices
//! Intersects the vertex <theV1> with the point <theP> with tolerance <theTolP>.
Standard_Boolean SameRange = TE->SameRange();
Standard_Real First = myHCurve->FirstParameter();
Standard_Real Last = myHCurve->LastParameter();
- Standard_Real Delta =1.e-12;
+ Standard_Real Delta = BOPTools_AlgoTools::DTolerance();
Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
const TopLoc_Location& Floc = S.Location();
(const TopoDS_Vertex& aVF,
const TopoDS_Vertex& aNewVertex)
{
- Standard_Real aTolVF, aTolNewVertex, aDist, aDTol=1.e-12, aNewTol;
+ Standard_Real aTolVF, aTolNewVertex, aDist, aNewTol;
//
gp_Pnt aPVF=BRep_Tool::Pnt(aVF);
gp_Pnt aPNewVertex=BRep_Tool::Pnt(aNewVertex);
if (aNewTol>aTolVF) {
BRep_Builder BB;
- BB.UpdateVertex (aVF, aNewTol+aDTol);
+ BB.UpdateVertex (aVF, aNewTol + BOPTools_AlgoTools::DTolerance());
}
}
const Standard_Real aT,
const TopoDS_Vertex& aV)
{
- Standard_Real aTolV, aDist, aDTol=1.e-12, aFirst, aLast;
+ Standard_Real aTolV, aDist, aFirst, aLast;
gp_Pnt aPc;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
- BB.UpdateVertex (aV, aDist+aDTol);
+ BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance());
}
}
//
const Standard_Real aT,
const TopoDS_Vertex& aV)
{
- Standard_Real aTolV, aDist, aDTol=1.e-12;
+ Standard_Real aTolV, aDist;
gp_Pnt aPc;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
- BB.UpdateVertex (aV, aDist+aDTol);
+ BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance());
}
}
//=======================================================================
const TopoDS_Face& aF1,
TopoDS_Vertex& aNewVertex)
{
- Standard_Real aTol1, aTol2, aMaxTol, delta=1.e-12;
+ Standard_Real aTol1, aTol2, aMaxTol;
gp_Pnt aPnt;
PointOnEdge (aE1, aParm1, aPnt);
aTol1=BRep_Tool::Tolerance(aE1);
aTol2=BRep_Tool::Tolerance(aF1);
//
- //aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
- aMaxTol=aTol1+aTol2+delta;
+ aMaxTol = aTol1 + aTol2 + BOPTools_AlgoTools::DTolerance();
//
BRep_Builder aBB;
aBB.MakeVertex (aNewVertex, aPnt, aMaxTol);
--- /dev/null
+puts "========"
+puts "0031462: Modeling Algorithms - BOP result depends on the arguments order"
+puts "========"
+puts ""
+
+restore [locate_data_file bug31462_obj.brep] s1
+restore [locate_data_file bug31462_tools.brep] s2
+
+tcopy s1 obj
+tcopy s2 sx
+bclearobjects
+bcleartools
+baddobjects obj
+eval baddtools [explode sx]
+bfillds
+bsplit result1
+
+checkshape result1
+if {![regexp "This shape seems to be OK" [bopcheck result1]]} {
+ puts "Error: self-interfering result"
+}
+
+checknbshapes result1 -wire 19 -face 18 -shell 3 -solid 2
+checkprops result1 -s 103.955 -v 38.7982
+
+tcopy s1 obj
+tcopy s2 sx
+bclearobjects
+bcleartools
+baddobjects obj
+explode sx
+baddtools sx_4 sx_5 sx_6 sx_3 sx_2 sx_1
+bfillds
+bsplit result2
+
+checkshape result2
+if {![regexp "This shape seems to be OK" [bopcheck result2]]} {
+ puts "Error: self-interfering result"
+}
+
+checknbshapes result2 -ref [nbshapes result1]
+checkprops result2 -equal result1
+
+checkview -display result1 -2d -path ${imagedir}/${test_image}.png
cpulimit 100
-puts "TODO OCC30438 ALL: Error : The area of result shape is"
-puts "TODO OCC30438 ALL: Error : The volume of result shape is"
-puts "TODO OCC30438 ALL: Error : is WRONG because number of SHELL"
-puts "TODO OCC30438 ALL: Error : is WRONG because number of SOLID"
-puts "TODO OCC30438 ALL: Error: bopargcheck has found some faulties in result"
-
-
restore [locate_data_file bug29523_cut_extrudewire07.brep] sw
restore [locate_data_file bug29523_cut_toolwire07.brep] tw
# the dimensions of the shape "result" are about 1.0e+5.
# So, this tolerance seems to be OK.
-checkmaxtol result -ref 18.634531507134731
+checkmaxtol result -ref 1.7319951447770465
smallview
don result sw tw