Skip to content

Commit

Permalink
[PATCH] 0031462: Modeling Algorithms - BOP result depends on the argu…
Browse files Browse the repository at this point in the history
…ments order

Eliminate numerical instability by ensuring that the tolerance of intersection entities is slightly grater than the actual distance to the shapes creating the entity.

Original commit url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commit;h=3f7e5e99d565e35f600da5f089b0fc7a3851fbde
  • Loading branch information
emv authored and tpaviot committed Sep 17, 2020
1 parent bf870b8 commit 7c693ca
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 24 deletions.
27 changes: 26 additions & 1 deletion src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,14 @@ void BOPAlgo_PaveFiller::IntersectVE
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()) {
Expand All @@ -233,6 +241,9 @@ void BOPAlgo_PaveFiller::IntersectVE
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) {
Expand Down Expand Up @@ -287,7 +298,21 @@ void BOPAlgo_PaveFiller::IntersectVE
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);
Expand Down
7 changes: 4 additions & 3 deletions src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2414,7 +2414,7 @@ void BOPAlgo_PaveFiller::PutPaveOnCurve
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));
Expand Down Expand Up @@ -2459,7 +2459,8 @@ void BOPAlgo_PaveFiller::PutPaveOnCurve
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)) {
Expand Down Expand Up @@ -2831,7 +2832,7 @@ void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)

if (aDistVP > aTolV)
{
Standard_Integer nVn = UpdateVertex(nV, aDistVP);
Standard_Integer nVn = UpdateVertex(nV, aDistVP + BOPTools_AlgoTools::DTolerance());
if (nVn != nV)
{
aPave.SetIndex(nVn);
Expand Down
2 changes: 1 addition & 1 deletion src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ void UpdateVertices(const TopoDS_Edge& aE,
aD2=aP3D.SquareDistance(aP3Dx);
if (aD2>aTolV2) {
aD=sqrt(aD2);
aBB.UpdateVertex(aV[j], aD);
aBB.UpdateVertex(aV[j], aD + BOPTools_AlgoTools::DTolerance());
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/BOPTools/BOPTools_AlgoTools.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1636,7 +1636,7 @@ void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
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);
Expand Down
9 changes: 9 additions & 0 deletions src/BOPTools/BOPTools_AlgoTools.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ public:

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>.
Expand Down
2 changes: 1 addition & 1 deletion src/BOPTools/BOPTools_AlgoTools_1.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
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();
Expand Down
17 changes: 8 additions & 9 deletions src/BOPTools/BOPTools_AlgoTools_2.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void BOPTools_AlgoTools::UpdateVertex
(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);
Expand All @@ -54,7 +54,7 @@ void BOPTools_AlgoTools::UpdateVertex

if (aNewTol>aTolVF) {
BRep_Builder BB;
BB.UpdateVertex (aVF, aNewTol+aDTol);
BB.UpdateVertex (aVF, aNewTol + BOPTools_AlgoTools::DTolerance());
}
}

Expand All @@ -66,7 +66,7 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
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);
Expand All @@ -77,7 +77,7 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
BB.UpdateVertex (aV, aDist+aDTol);
BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance());
}
}
//
Expand All @@ -89,7 +89,7 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
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);
Expand All @@ -100,7 +100,7 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
BB.UpdateVertex (aV, aDist+aDTol);
BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance());
}
}
//=======================================================================
Expand Down Expand Up @@ -265,16 +265,15 @@ void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
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);
Expand Down
44 changes: 44 additions & 0 deletions tests/bugs/modalg_7/bug31462
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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
9 changes: 1 addition & 8 deletions tests/evolved/voluved/HMC008
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ puts "=========="

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

Expand Down Expand Up @@ -219,7 +212,7 @@ if {[regexp "Faulties" [bopargcheck result]]} {
# 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
Expand Down

0 comments on commit 7c693ca

Please sign in to comment.