mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
0026738: Make Boolean operations safely treating arguments when running with fuzzy option
When fuzzy option is in force prevent increasing tolerance of input shapes. Instead pass increased by fuzzy value the tolerances of sub-shapes everywhere where it is needed by intersection algorithms. The following changes in API have been made: - The methods SetFuzzyValue and FuzzyValue have been moved from the classes BOPAlgo_ArgumentAnalyzer, BOPAlgo_Builder, and BOPAlgo_PaveFiller to the base class BOPAlgo_Algo. - The public method BOPDS_DS::VerticesOnIn has been renamed to SubShapesOnIn, and the new output parameter theCommonPB has been added. - In BOPTools_AlgoTools, a new argument "theFuzzyValue" has been added in the methods ComputeVV and AreFacesSameDomain. - In IntTools_Context, a new argument "theFuzzyValue" has been added in the methods ComputeVE and ComputeVF. - The methods SetFuzzyValue and FuzzyValue have been added in the classes IntTools_EdgeEdge, IntTools_FaceFace. - In the class IntTools_EdgeFace, the methods SetTolE, SetTolF, TolE, TolF have been removed, and the methods SetFuzzyValue, FuzzyValue have been added. - The new argument "theTol" has been added in the method IntTools_WLineTool::DecompositionOfWLine. Some improvements in algorithms have been made during fighting with regressions: - Correct initialization of pave blocks for degenerated edges. - In BOPAlgo_PaveFiller::MakeBlocks(), filter out paves on intersection curve that were put on the curve accidentally due to wide range of E-F intersection vertex. - In the method IntTools_Tools::ComputeTolerance the margin added to the computed tolerance has been increased up to 0.001%. - The method BOPAlgo_PaveFiller::PutPaveOnCurve has been corrected in order to use the original vertex tolerance instead of the value increased during putting it on other curves. - The new method BOPDS_PaveBlock::RemoveExtPave has been added. - The vertex tolerance computation in BOPTools_AlgoTools::CorrectCurveOnSurface has been improved, taking into account intersection segments between p-curves (to avoid regression on "bugs modalg_6 bug22794"). - Improve IsExistingPaveBlock to make more stable catching of coincidence of common block with section curve (against regression "bugs modalg_4 bug697_2" on Linux). Test case for the bug has been added. The following test cases have been updated as improvements: boolean gdml_private ZH2 ZI7 ZJ7 boolean volumemaker C4 The test case bugs/modalg_4/pro19653 has been corrected to make it stable. See comment inside the script for details. The test case bugs/modalg_6/bug25880 has been corrected to suppress wrong bfuse commands. The test bugs/modalg_6/bug26954_3 has been corrected to compare the result with more precise reference value. The "faulty" TODO in boolean/volumemaker/A8 has been made actual for Linux as well. //Eliminate compilation error on Linux.
This commit is contained in:
@@ -922,7 +922,8 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
|
||||
Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
|
||||
(const TopoDS_Face& theF1,
|
||||
const TopoDS_Face& theF2,
|
||||
Handle(IntTools_Context)& theContext)
|
||||
Handle(IntTools_Context)& theContext,
|
||||
const Standard_Real theFuzz)
|
||||
{
|
||||
Standard_Boolean bFlag;
|
||||
Standard_Integer iErr;
|
||||
@@ -932,6 +933,7 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
|
||||
TopoDS_Face aF1, aF2;
|
||||
TopoDS_Edge aE1;
|
||||
TopExp_Explorer aExp;
|
||||
Standard_Real aFuzz1 = (theFuzz > Precision::Confusion() ? theFuzz : Precision::Confusion());
|
||||
//
|
||||
bFlag=Standard_False;
|
||||
//
|
||||
@@ -947,12 +949,14 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
|
||||
aE1=(*(TopoDS_Edge*)(&aExp.Current()));
|
||||
if (!BRep_Tool::Degenerated(aE1)) {
|
||||
Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
|
||||
aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
|
||||
if (aTolE > aTolF1) {
|
||||
aTolF1 = aTolE;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 2
|
||||
aTolF2=BRep_Tool::Tolerance(aF2);
|
||||
aTol = aTolF1 + aTolF2 + Precision::Confusion();
|
||||
aTol = aTolF1 + aTolF2 + aFuzz1;
|
||||
//
|
||||
iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
|
||||
theContext);
|
||||
@@ -1420,23 +1424,16 @@ void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
|
||||
const Standard_Real theTolR3D,
|
||||
TopoDS_Edge& theE)
|
||||
{
|
||||
Standard_Real aTolV;
|
||||
BRep_Builder aBB;
|
||||
Standard_Real aNeedTol = theTolR3D + 1e-12;
|
||||
//
|
||||
aBB.UpdateVertex(theV1, aNeedTol);
|
||||
aBB.UpdateVertex(theV2, aNeedTol);
|
||||
//
|
||||
BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2,
|
||||
theE);
|
||||
//
|
||||
aBB.UpdateEdge(theE, theTolR3D);
|
||||
//
|
||||
aTolV=BRep_Tool::Tolerance(theV1);
|
||||
if (aTolV<theTolR3D) {
|
||||
aBB.UpdateVertex(theV1, theTolR3D);
|
||||
}
|
||||
//
|
||||
aTolV=BRep_Tool::Tolerance(theV2);
|
||||
if (aTolV<theTolR3D) {
|
||||
aBB.UpdateVertex(theV2, theTolR3D);
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
// function: ComputeVV
|
||||
@@ -1467,14 +1464,16 @@ Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
|
||||
const TopoDS_Vertex& aV2)
|
||||
const TopoDS_Vertex& aV2,
|
||||
const Standard_Real aFuzz)
|
||||
{
|
||||
Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
|
||||
gp_Pnt aP1, aP2;
|
||||
Standard_Real aFuzz1 = (aFuzz > Precision::Confusion() ? aFuzz : Precision::Confusion());
|
||||
//
|
||||
aTolV1=BRep_Tool::Tolerance(aV1);
|
||||
aTolV2=BRep_Tool::Tolerance(aV2);
|
||||
aTolSum = aTolV1 + aTolV2 + Precision::Confusion();
|
||||
aTolSum=aTolV1+aTolV2+aFuzz1;
|
||||
aTolSum2=aTolSum*aTolSum;
|
||||
//
|
||||
aP1=BRep_Tool::Pnt(aV1);
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <TopAbs_State.hxx>
|
||||
#include <BOPCol_IndexedMapOfShape.hxx>
|
||||
#include <BOPCol_BaseAllocator.hxx>
|
||||
#include <Precision.hxx>
|
||||
class TopoDS_Vertex;
|
||||
class gp_Pnt;
|
||||
class IntTools_Curve;
|
||||
@@ -44,7 +45,6 @@ class IntTools_Range;
|
||||
class TopoDS_Shell;
|
||||
|
||||
|
||||
|
||||
class BOPTools_AlgoTools
|
||||
{
|
||||
public:
|
||||
@@ -54,7 +54,9 @@ public:
|
||||
|
||||
Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, const gp_Pnt& aP2, const Standard_Real aTolP2);
|
||||
|
||||
Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, const TopoDS_Vertex& aV2);
|
||||
Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1,
|
||||
const TopoDS_Vertex& aV2,
|
||||
const Standard_Real theFuzz = Precision::Confusion());
|
||||
|
||||
Standard_EXPORT static void MakeVertex (const BOPCol_ListOfShape& aLV, TopoDS_Vertex& aV);
|
||||
|
||||
@@ -79,7 +81,10 @@ public:
|
||||
|
||||
Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Edge& aE1, const TopoDS_Edge& aE2, Handle(IntTools_Context)& aContext);
|
||||
|
||||
Standard_EXPORT static Standard_Boolean AreFacesSameDomain (const TopoDS_Face& theF1, const TopoDS_Face& theF2, Handle(IntTools_Context)& theContext);
|
||||
Standard_EXPORT static Standard_Boolean AreFacesSameDomain (const TopoDS_Face& theF1,
|
||||
const TopoDS_Face& theF2,
|
||||
Handle(IntTools_Context)& theContext,
|
||||
const Standard_Real theFuzz = Precision::Confusion());
|
||||
|
||||
Standard_EXPORT static Standard_Boolean CheckSameGeom (const TopoDS_Face& theF1, const TopoDS_Face& theF2, Handle(IntTools_Context)& theContext);
|
||||
|
||||
@@ -299,26 +304,11 @@ public:
|
||||
Standard_EXPORT static Standard_Boolean ComputeTolerance (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, Standard_Real& theMaxDist, Standard_Real& theMaxPar);
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _BOPTools_AlgoTools_HeaderFile
|
||||
|
@@ -52,6 +52,7 @@
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <IntRes2d_Domain.hxx>
|
||||
#include <IntRes2d_IntersectionPoint.hxx>
|
||||
#include <IntRes2d_IntersectionSegment.hxx>
|
||||
#include <IntTools_Context.hxx>
|
||||
#include <IntTools_Curve.hxx>
|
||||
#include <IntTools_Range.hxx>
|
||||
@@ -74,22 +75,7 @@
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
static
|
||||
void CheckEdge (const TopoDS_Edge& E,
|
||||
const Standard_Real aMaxTol,
|
||||
@@ -126,13 +112,11 @@ static
|
||||
const BOPCol_IndexedMapOfShape& aMapToAvoid);
|
||||
|
||||
static
|
||||
Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
|
||||
const TopoDS_Face& aF,
|
||||
const GeomAdaptor_Surface& aS,
|
||||
const TopoDS_Edge& aE1,
|
||||
const TopoDS_Edge& aE2);
|
||||
|
||||
|
||||
Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
|
||||
const TopoDS_Face& theF,
|
||||
const Handle(Geom_Surface)& theS,
|
||||
const TopoDS_Edge& theE1,
|
||||
const TopoDS_Edge& theE2);
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPTools_CPC
|
||||
@@ -578,22 +562,17 @@ void CheckEdge (const TopoDS_Edge& Ed,
|
||||
void CorrectWires(const TopoDS_Face& aFx,
|
||||
const BOPCol_IndexedMapOfShape& aMapToAvoid)
|
||||
{
|
||||
Standard_Boolean bIsPeriodic;
|
||||
Standard_Integer i, aNbV;
|
||||
Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
|
||||
gp_Pnt aP, aPV;
|
||||
gp_Pnt2d aP2D;
|
||||
TopoDS_Face aF;
|
||||
TopoDS_Vertex aV11, aV12, aV21, aV22;;
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMVE;
|
||||
TopTools_ListIteratorOfListOfShape aIt, aIt1;
|
||||
//
|
||||
aF=aFx;
|
||||
aF.Orientation(TopAbs_FORWARD);
|
||||
const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
|
||||
GeomAdaptor_Surface aGAS (aS);
|
||||
//
|
||||
bIsPeriodic=(aGAS.IsUPeriodic() || aGAS.IsVPeriodic());
|
||||
//
|
||||
TopExp::MapShapesAndAncestors(aF,
|
||||
TopAbs_VERTEX,
|
||||
@@ -616,69 +595,60 @@ void CorrectWires(const TopoDS_Face& aFx,
|
||||
aT=BRep_Tool::Parameter(aV, aE);
|
||||
//
|
||||
aC2D->D0(aT, aP2D);
|
||||
aGAS.D0(aP2D.X(), aP2D.Y(), aP);
|
||||
aS->D0(aP2D.X(), aP2D.Y(), aP);
|
||||
aD2=aPV.SquareDistance(aP);
|
||||
if (aD2>aD2max) {
|
||||
aD2max=aD2;
|
||||
}
|
||||
//check self interference
|
||||
if (aNbV==2) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (bIsPeriodic) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
TopExp::Vertices(aE, aV11, aV12);
|
||||
}
|
||||
//
|
||||
//check wires on self interference by intersecting 2d curves of the edges
|
||||
aIt.Initialize(aLE);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Edge& aE1 = *(TopoDS_Edge*)&aIt.Value();
|
||||
//
|
||||
aIt1 = aIt;
|
||||
aIt1.Next();
|
||||
for (; aIt1.More(); aIt1.Next()) {
|
||||
const TopoDS_Edge& aE1=*(TopoDS_Edge*)(&aIt1.Value());
|
||||
for (aIt1.Next(); aIt1.More(); aIt1.Next()) {
|
||||
const TopoDS_Edge& aE2 = *(TopoDS_Edge*)&aIt1.Value();
|
||||
//
|
||||
//do not perform check for edges that have two common vertices
|
||||
TopExp::Vertices(aE1, aV21, aV22);
|
||||
if ((aV11.IsSame(aV21) && aV12.IsSame(aV22)) ||
|
||||
(aV12.IsSame(aV21) && aV11.IsSame(aV22))) {
|
||||
if (aE1.IsSame(aE2)) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
aD2=IntersectCurves2d(aPV, aF, aGAS, aE, aE1);
|
||||
if (aD2>aD2max) {
|
||||
aD2max=aD2;
|
||||
aD2 = IntersectCurves2d(aV, aF, aS, aE1, aE2);
|
||||
if (aD2 > aD2max) {
|
||||
aD2max = aD2;
|
||||
}
|
||||
}// for (; aIt1.More(); aIt1.Next()) {
|
||||
}// for (; aIt.More(); aIt.Next()) {
|
||||
}
|
||||
}
|
||||
//
|
||||
if (aD2max>aTol2) {
|
||||
aTol=sqrt(aD2max);
|
||||
aTol = 1.01 * sqrt(aD2max);
|
||||
UpdateShape(aV, aTol, aMapToAvoid);
|
||||
}
|
||||
}// for (i=1; i<=aNbV; ++i) {
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// Function : IntersectCurves2d
|
||||
// purpose : Intersect 2d curves of edges
|
||||
//=======================================================================
|
||||
Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
|
||||
const TopoDS_Face& aF,
|
||||
const GeomAdaptor_Surface& aGAS,
|
||||
const TopoDS_Edge& aE1,
|
||||
const TopoDS_Edge& aE2)
|
||||
Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
|
||||
const TopoDS_Face& theF,
|
||||
const Handle(Geom_Surface)& theS,
|
||||
const TopoDS_Edge& theE1,
|
||||
const TopoDS_Edge& theE2)
|
||||
{
|
||||
Standard_Real aDist, aD, aT11, aT12, aT21, aT22, aTol2d, aT1, aT2;
|
||||
Standard_Integer j, aNbPnt;
|
||||
Geom2dInt_GInter aInter;
|
||||
gp_Pnt aP;
|
||||
gp_Pnt2d aP2D;
|
||||
Standard_Real aT11, aT12, aT21, aT22, aTol2d, aMaxDist;
|
||||
Geom2dInt_GInter anInter;
|
||||
//
|
||||
aDist = 0.;
|
||||
aTol2d = 1.e-10;//Precision::Confusion();
|
||||
aMaxDist = 0.;
|
||||
aTol2d = 1.e-10;
|
||||
//
|
||||
const Handle(Geom2d_Curve)& aC2D1=
|
||||
BRep_Tool::CurveOnSurface(aE1, aF, aT11, aT12);
|
||||
BRep_Tool::CurveOnSurface(theE1, theF, aT11, aT12);
|
||||
const Handle(Geom2d_Curve)& aC2D2=
|
||||
BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
|
||||
BRep_Tool::CurveOnSurface(theE2, theF, aT21, aT22);
|
||||
//
|
||||
Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
|
||||
IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d,
|
||||
@@ -686,35 +656,68 @@ Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
|
||||
IntRes2d_Domain aDom2(aC2D2->Value(aT21), aT21, aTol2d,
|
||||
aC2D2->Value(aT22), aT22, aTol2d);
|
||||
//
|
||||
aInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
|
||||
if (aInter.IsDone()) {
|
||||
if (aInter.NbSegments()) {
|
||||
return aDist;
|
||||
anInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
|
||||
if (!anInter.IsDone()) {
|
||||
return aMaxDist;
|
||||
}
|
||||
//
|
||||
Standard_Real aT1, aT2, aTint1, aTint2, aHalfR1, aHalfR2, aDist;
|
||||
Standard_Integer i, aNb;
|
||||
gp_Pnt aP, aPV;
|
||||
gp_Pnt2d aP2d;
|
||||
NCollection_List<IntRes2d_IntersectionPoint> aLP;
|
||||
NCollection_List<IntRes2d_IntersectionPoint>::Iterator aItLP;
|
||||
//
|
||||
aPV = BRep_Tool::Pnt(theV);
|
||||
aT1 = BRep_Tool::Parameter(theV, theE1);
|
||||
aT2 = BRep_Tool::Parameter(theV, theE2);
|
||||
//
|
||||
aHalfR1 = (aT12 - aT11) / 2.;
|
||||
aHalfR2 = (aT22 - aT21) / 2.;
|
||||
//
|
||||
aDist = 0.;
|
||||
//
|
||||
aNb = anInter.NbSegments();
|
||||
for (i = 1; i <= aNb; ++i) {
|
||||
const IntRes2d_IntersectionSegment& aSeg = anInter.Segment(i);
|
||||
aLP.Append(aSeg.FirstPoint());
|
||||
aLP.Append(aSeg.LastPoint());
|
||||
}
|
||||
//
|
||||
aNb = anInter.NbPoints();
|
||||
for (i = 1; i <= aNb; ++i) {
|
||||
const IntRes2d_IntersectionPoint& aPnt = anInter.Point(i);
|
||||
aLP.Append(aPnt);
|
||||
}
|
||||
//
|
||||
aItLP.Initialize(aLP);
|
||||
for (; aItLP.More(); aItLP.Next()) {
|
||||
const IntRes2d_IntersectionPoint& aPnt = aItLP.Value();
|
||||
//
|
||||
aTint1 = aPnt.ParamOnFirst();
|
||||
aTint2 = aPnt.ParamOnSecond();
|
||||
//
|
||||
if ((aTint1 < aT11 || aTint1 > aT12) ||
|
||||
(aTint2 < aT21 || aTint2 > aT22)) {
|
||||
// out of range;
|
||||
continue;
|
||||
}
|
||||
aNbPnt = aInter.NbPoints();
|
||||
if (aNbPnt) {
|
||||
aDist = -Precision::Infinite();
|
||||
for (j = 1; j <= aNbPnt; ++j) {
|
||||
const IntRes2d_IntersectionPoint& aPoint = aInter.Point(j);
|
||||
//
|
||||
aT1 = aPoint.ParamOnFirst();
|
||||
aT2 = aPoint.ParamOnSecond();
|
||||
//
|
||||
if ((aT1 < aT11 || aT1 > aT12) ||
|
||||
(aT2 < aT21 || aT2 > aT22)) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
aP2D = aPoint.Value();
|
||||
aGAS.D0(aP2D.X(), aP2D.Y(), aP);
|
||||
aD=aPV.SquareDistance(aP);
|
||||
if (aD > aDist) {
|
||||
aDist = 1.01 * aD;
|
||||
}
|
||||
}
|
||||
//
|
||||
if (Abs(aTint1 - aT1) > aHalfR1 ||
|
||||
Abs(aTint2 - aT2) > aHalfR2) {
|
||||
// intersection on the other end of the closed edge
|
||||
continue;
|
||||
}
|
||||
//
|
||||
aP2d = aPnt.Value();
|
||||
theS->D0(aP2d.X(), aP2d.Y(), aP);
|
||||
aDist = aPV.SquareDistance(aP);
|
||||
if (aDist > aMaxDist) {
|
||||
aMaxDist = aDist;
|
||||
}
|
||||
}
|
||||
return aDist;
|
||||
//
|
||||
return aMaxDist;
|
||||
}
|
||||
//=======================================================================
|
||||
// Function : CorrectEdgeTolerance
|
||||
|
Reference in New Issue
Block a user