From f14190252ba1e65bd89ad46ea7e9c304251d8a4d Mon Sep 17 00:00:00 2001 From: emv Date: Thu, 23 May 2013 11:55:08 +0400 Subject: [PATCH] 0023933: Self intersection reported after Fuse operation. Additional check has been added in IntTools_BeanFaceIntersector::FastComputeExactIntersection() to prevent creating an Edge/Face intersection for the case when edge lies on the surface of the face, but not on the face itself. Adding test case for this fix --- src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx | 7 + src/BOPTest/BOPTest_CheckCommands.cxx | 7 + src/IntTools/IntTools_BeanFaceIntersector.cxx | 272 +++++++++--------- tests/bugs/modalg_5/bug23933 | 24 ++ 4 files changed, 169 insertions(+), 141 deletions(-) create mode 100755 tests/bugs/modalg_5/bug23933 diff --git a/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx b/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx index 87a55ca1cc..65cc142370 100644 --- a/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx +++ b/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx @@ -348,6 +348,13 @@ void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences() continue; } // + if (aTypeInt == 4) { + BOPDS_InterfEF& aEF=aEFs(i); + if (aEF.CommonPart().Type()==TopAbs_SHAPE) { + continue; + } + } + // const TopoDS_Shape& aS1 = theDS->Shape(nI1); const TopoDS_Shape& aS2 = theDS->Shape(nI2); // diff --git a/src/BOPTest/BOPTest_CheckCommands.cxx b/src/BOPTest/BOPTest_CheckCommands.cxx index 0cb752999b..3bd59f7e68 100644 --- a/src/BOPTest/BOPTest_CheckCommands.cxx +++ b/src/BOPTest/BOPTest_CheckCommands.cxx @@ -133,6 +133,13 @@ Standard_Integer bopcheck (Draw_Interpretor& di, Standard_Integer n, const char continue; } // + if (aTypeInt == 4) { + BOPDS_InterfEF& aEF=aEFs(i); + if (aEF.CommonPart().Type()==TopAbs_SHAPE) { + continue; + } + } + // const TopoDS_Shape& aS1 = theDS->Shape(nI1); const TopoDS_Shape& aS2 = theDS->Shape(nI2); // diff --git a/src/IntTools/IntTools_BeanFaceIntersector.cxx b/src/IntTools/IntTools_BeanFaceIntersector.cxx index 460144cdd3..8023599b10 100755 --- a/src/IntTools/IntTools_BeanFaceIntersector.cxx +++ b/src/IntTools/IntTools_BeanFaceIntersector.cxx @@ -62,6 +62,7 @@ #include #include #include +#include static Standard_Boolean AdjustPeriodic(const Standard_Real U, const Standard_Real UFirst, @@ -742,9 +743,8 @@ Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection() if(aCT==GeomAbs_Line) { if((surfPlane.Distance(myCurve.Value(myFirstParameter)) < myCriteria) && - (surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) { - myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2); - aresult = 1; + (surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) { + aresult = 1; } } else { // else 1 @@ -752,78 +752,77 @@ Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection() switch(aCT) { case GeomAbs_Circle: { - aDir = myCurve.Circle().Axis().Direction(); - break; + aDir = myCurve.Circle().Axis().Direction(); + break; } - case GeomAbs_Ellipse: { - aDir = myCurve.Ellipse().Axis().Direction(); - break; + case GeomAbs_Ellipse: { + aDir = myCurve.Ellipse().Axis().Direction(); + break; } - case GeomAbs_Hyperbola: { - aDir = myCurve.Hyperbola().Axis().Direction(); - break; + case GeomAbs_Hyperbola: { + aDir = myCurve.Hyperbola().Axis().Direction(); + break; } - case GeomAbs_Parabola: { - aDir = myCurve.Parabola().Axis().Direction(); - break; + case GeomAbs_Parabola: { + aDir = myCurve.Parabola().Axis().Direction(); + break; } - default: { - return aresult; + default: { + return aresult; } } // Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction()); if(anAngle < Precision::Angular()) { - Standard_Boolean insertRange = Standard_False; - - switch(aCT) { - case GeomAbs_Circle: { - Standard_Real adist = - surfPlane.Distance(myCurve.Circle().Location()) + - myCurve.Circle().Radius() * Precision::Angular(); - - if(adist < myCriteria) { - insertRange = Standard_True; - } - break; - } - case GeomAbs_Ellipse: { - Standard_Real adist = - surfPlane.Distance(myCurve.Ellipse().Location()) + - myCurve.Ellipse().MajorRadius() * Precision::Angular(); - - if(adist < myCriteria) { - insertRange = Standard_True; - } - break; - } - case GeomAbs_Hyperbola: - case GeomAbs_Parabola: { - Standard_Real aMaxPar = - (Abs(myFirstParameter) > Abs(myLastParameter)) ? - Abs(myFirstParameter) : Abs(myLastParameter); - - gp_Pnt aLoc = (aCT == GeomAbs_Parabola) ? - myCurve.Parabola().Location() : - myCurve.Hyperbola().Location(); - Standard_Real adist = aLoc.Distance(myCurve.Value(aMaxPar)); - adist = surfPlane.Distance(aLoc) + adist * Precision::Angular(); - - if(adist < myCriteria) { - insertRange = Standard_True; - } - break; - } - default: { - break; - } - } - // - if(insertRange) { - myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2); - aresult = 1; - } + Standard_Boolean insertRange = Standard_False; + + switch(aCT) { + case GeomAbs_Circle: { + Standard_Real adist = + surfPlane.Distance(myCurve.Circle().Location()) + + myCurve.Circle().Radius() * Precision::Angular(); + + if(adist < myCriteria) { + insertRange = Standard_True; + } + break; + } + case GeomAbs_Ellipse: { + Standard_Real adist = + surfPlane.Distance(myCurve.Ellipse().Location()) + + myCurve.Ellipse().MajorRadius() * Precision::Angular(); + + if(adist < myCriteria) { + insertRange = Standard_True; + } + break; + } + case GeomAbs_Hyperbola: + case GeomAbs_Parabola: { + Standard_Real aMaxPar = + (Abs(myFirstParameter) > Abs(myLastParameter)) ? + Abs(myFirstParameter) : Abs(myLastParameter); + + gp_Pnt aLoc = (aCT == GeomAbs_Parabola) ? + myCurve.Parabola().Location() : + myCurve.Hyperbola().Location(); + Standard_Real adist = aLoc.Distance(myCurve.Value(aMaxPar)); + adist = surfPlane.Distance(aLoc) + adist * Precision::Angular(); + + if(adist < myCriteria) { + insertRange = Standard_True; + } + break; + } + default: { + break; + } + } + // + if(insertRange) { + aresult = 1; + } }//if(anAngle < Precision::Angular()) { }//else { // else 1 }// if(aST==GeomAbs_Plane) { @@ -838,28 +837,27 @@ Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection() Standard_Real anAngle = aDir1.Angle(aDir2); if(anAngle < Precision::Angular()) { - gp_Pnt aLoc = aCircle.Location(); - gp_Lin anCylAxis(aCylinder.Axis()); - Standard_Real alocdist = anCylAxis.Distance(aLoc); - Standard_Real adist = alocdist; - Standard_Real adiff = aCircle.Radius() - aCylinder.Radius(); - adist += Abs(adiff); - - if(adist < myCriteria) { - Standard_Real acylradius = aCylinder.Radius(); - Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular()); - Standard_Real aprojectedradius = atmpvalue; - aprojectedradius = - sqrt((aCircle.Radius() * aCircle.Radius()) - - (aprojectedradius * aprojectedradius)); - adiff = aprojectedradius - acylradius; - adist = alocdist + Abs(adiff); - - if(adist < myCriteria) { // Abs is important function here - myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2); - aresult = 1; - } - } + gp_Pnt aLoc = aCircle.Location(); + gp_Lin anCylAxis(aCylinder.Axis()); + Standard_Real alocdist = anCylAxis.Distance(aLoc); + Standard_Real adist = alocdist; + Standard_Real adiff = aCircle.Radius() - aCylinder.Radius(); + adist += Abs(adiff); + + if(adist < myCriteria) { + Standard_Real acylradius = aCylinder.Radius(); + Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular()); + Standard_Real aprojectedradius = atmpvalue; + aprojectedradius = + sqrt((aCircle.Radius() * aCircle.Radius()) + - (aprojectedradius * aprojectedradius)); + adiff = aprojectedradius - acylradius; + adist = alocdist + Abs(adiff); + + if(adist < myCriteria) { // Abs is important function here + aresult = 1; + } + } } }// if(aST==GeomAbs_Cylinder) @@ -868,18 +866,17 @@ Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection() IntAna_QuadQuadGeo anInter(aCirclePln, mySurface.Sphere()); if(anInter.IsDone()) { - if(anInter.TypeInter() == IntAna_Circle) { - gp_Circ aCircleToCompare = anInter.Circle(1); - Standard_Real adist = - aCircleToCompare.Location().Distance(aCircle.Location()); - Standard_Real adiff = aCircle.Radius() - aCircleToCompare.Radius(); - adist += Abs(adiff); - - if(adist < myCriteria) { - myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2); - aresult = 1; - } - } + if(anInter.TypeInter() == IntAna_Circle) { + gp_Circ aCircleToCompare = anInter.Circle(1); + Standard_Real adist = + aCircleToCompare.Location().Distance(aCircle.Location()); + Standard_Real adiff = aCircle.Radius() - aCircleToCompare.Radius(); + adist += Abs(adiff); + + if(adist < myCriteria) { + aresult = 1; + } + } } }// if(aST==GeomAbs_Sphere) { }// if(aCT==GeomAbs_Circle) { @@ -905,60 +902,53 @@ Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection() // aCos=aDirC.Dot(aDirL); if(aCos >= 0.) { - aAng2 = 2.*(1. - aCos); + aAng2 = 2.*(1. - aCos); } else { - aAng2 = 2.*(1. + aCos); + aAng2 = 2.*(1. + aCos); } // if(aAng2<=aTolang2) {// IsParallel = Standard_True; - Standard_Boolean bFlag; - Standard_Integer i; - Standard_Real aD; - gp_Pnt aPL[2]; - gp_Lin aLC(aAx1C); - // - aPL[0]=myCurve.Value(myFirstParameter); - aPL[1]=myCurve.Value(myLastParameter); - // - for (i=0; i<2; ++i) { - aD=aLC.Distance(aPL[i]); - aD=fabs(aD-aRC); - bFlag=(aD > myCriteria); - if (bFlag) { - break; - } - } - //modified by NIZHNY-EMV Fri Apr 20 08:45:29 2012 + Standard_Boolean bFlag; + Standard_Integer i; + Standard_Real aD; + gp_Pnt aPL[2]; + gp_Lin aLC(aAx1C); // - if (!bFlag) { - Standard_Real U, V, aTm; - gp_Pnt aPm; - gp_Pnt2d aP2d; - // - aTm = IntTools_Tools::IntermediatePoint(myFirstParameter, myLastParameter); - aPm = myCurve.Value(aTm); - ElSLib::Parameters(aCyl, aPm, U, V); - aP2d.SetCoord(U,V); - // - bFlag = !(myContext->IsPointInOnFace(mySurface.Face(), aP2d)); - } - // - if (!bFlag){ - myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2); - aresult = 1; - return aresult; - } - else { - aresult = 2; - return aresult; + aPL[0]=myCurve.Value(myFirstParameter); + aPL[1]=myCurve.Value(myLastParameter); + // + for (i=0; i<2; ++i) { + aD=aLC.Distance(aPL[i]); + aD=fabs(aD-aRC); + bFlag=(aD > myCriteria); + if (bFlag) { + break; + } } - //modified by NIZHNY-EMV Fri Apr 20 08:45:32 2012 + if (!bFlag){ + aresult = 1; + } } }//if(aCT==GeomAbs_Line) { } //modified by NIZNHY-PKV Thu Mar 01 11:54:06 2012t + // + //modified by NIZHNY-EMV Fri May 17 09:48:49 2013 + if (aresult==1) { + IntTools_Range aRange(myFirstParameter, myLastParameter); + const TopoDS_Face& aF = mySurface.Face(); + const TopoDS_Edge& aE = myCurve.Edge(); + // + if (BOPTools_AlgoTools::IsBlockInOnFace(aRange, aF, aE, myContext)) { + myRangeManager.InsertRange(aRange, 2); + } else { + aresult=2; + } + } + //modified by NIZHNY-EMV Fri May 17 09:48:53 2013 + // return aresult; } diff --git a/tests/bugs/modalg_5/bug23933 b/tests/bugs/modalg_5/bug23933 new file mode 100755 index 0000000000..9248daf618 --- /dev/null +++ b/tests/bugs/modalg_5/bug23933 @@ -0,0 +1,24 @@ +puts "============" +puts "OCC23933" +puts "============" +puts "" +###################################################### +# Self intersection reported after Fuse operation +###################################################### + +restore [locate_data_file bug23933_a.brep] a +restore [locate_data_file bug23933_b.brep] b + +checkshape a +checkshape b +bopargcheck a b -F + +if { [catch {bfuse result a b} catch_result] } { + puts "Faulty OCC697" +} + +checkshape result +bopargcheck result + +set square 246487 +set 3dviewer 1 -- 2.20.1