From 24def445c3bd603ecd1ffb17442539a040f45fe0 Mon Sep 17 00:00:00 2001 From: pkv Date: Fri, 19 Oct 2012 18:22:12 +0400 Subject: [PATCH] 0023470: Boolean Fuse between two edges fails --- src/IntTools/IntTools_BeanBeanIntersector.cxx | 271 +++++++++++++++++- tests/bugs/modalg/bug23470 | 25 ++ tests/bugs/modalg/end | 99 +++++-- 3 files changed, 363 insertions(+), 32 deletions(-) create mode 100755 tests/bugs/modalg/bug23470 diff --git a/src/IntTools/IntTools_BeanBeanIntersector.cxx b/src/IntTools/IntTools_BeanBeanIntersector.cxx index df643e1e08..9a99bc0106 100755 --- a/src/IntTools/IntTools_BeanBeanIntersector.cxx +++ b/src/IntTools/IntTools_BeanBeanIntersector.cxx @@ -38,14 +38,27 @@ #include #include -static void LocalPrepareArgs(BRepAdaptor_Curve& theCurve, - const Standard_Real theFirstParameter, - const Standard_Real theLastParameter, - Standard_Real& theDeflection, - IntTools_CArray1OfReal& theArgs); +static + void LocalPrepareArgs(BRepAdaptor_Curve& theCurve, + const Standard_Real theFirstParameter, + const Standard_Real theLastParameter, + Standard_Real& theDeflection, + IntTools_CArray1OfReal& theArgs); + +static + Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter, + IntTools_MarkedRangeSet& theMarkedRange); +static + Standard_Integer CheckCoincidence(const Standard_Real aT11, + const Standard_Real aT12, + const Handle(Geom_Curve)& aC1, + const Standard_Real aT21, + const Standard_Real aT22, + const Handle(Geom_Curve)& aC2, + const Standard_Real aCriteria, + const Standard_Real aCurveResolution1, + GeomAPI_ProjectPointOnCurve& aProjector); -static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter, - IntTools_MarkedRangeSet& theMarkedRange); // ================================================================================== // function: IntTools_BeanBeanIntersector @@ -456,12 +469,30 @@ Standard_Boolean IntTools_BeanBeanIntersector::FastComputeIntersection() newparfound = Standard_False; } } - + // if(!newparfound) { break; } }// for(i = 0; i < 2; i++) { } // if(aCT1==GeomAbs_Circle) + //modified by NIZNHY-PKV Mon Oct 08 14:08:19 2012f + if (aCT1==GeomAbs_BSplineCurve || aCT1==GeomAbs_BezierCurve) { + Standard_Integer iFlag; + // + iFlag=CheckCoincidence(myFirstParameter1, + myLastParameter1, + myTrsfCurve1, + myFirstParameter2, + myLastParameter2, + myTrsfCurve2, + myCriteria, + myCurveResolution1, + myProjector); + if (!iFlag) { + aresult=!aresult; + } + } + //modified by NIZNHY-PKV Mon Oct 08 14:08:23 2012t return aresult; } // ================================================================================== @@ -469,7 +500,7 @@ Standard_Boolean IntTools_BeanBeanIntersector::FastComputeIntersection() // purpose: // ================================================================================== Standard_Real IntTools_BeanBeanIntersector::Distance(const Standard_Real theArg, - Standard_Real& theArgOnOtherBean) + Standard_Real& theArgOnOtherBean) { Standard_Real aDistance; Standard_Integer aNbPoints; @@ -478,11 +509,8 @@ Standard_Real IntTools_BeanBeanIntersector::Distance(const Standard_Real theArg, aDistance=RealLast(); // aPoint=myCurve1.Value(theArg); - //modified by NIZNHY-PKV Thu Jul 01 12:20:52 2010f myProjector.Init(myTrsfCurve2, myFirstParameter2, myLastParameter2); myProjector.Perform(aPoint); - //myProjector.Init(aPoint, myTrsfCurve2, myFirstParameter2, myLastParameter2); - //modified by NIZNHY-PKV Thu Jul 01 12:21:05 2010t // aNbPoints=myProjector.NbPoints(); if(aNbPoints > 0) { @@ -1125,7 +1153,6 @@ static void LocalPrepareArgs(BRepAdaptor_Curve& theCurve, IntTools::PrepareArgs(theCurve, theLastParameter, theFirstParameter, aDiscretization, aRelativeDeflection, theArgs); } } - // --------------------------------------------------------------------------------- // static function: SetEmptyResultRange // purpose: @@ -1149,4 +1176,222 @@ static Standard_Boolean SetEmptyResultRange(const Standard_Real theParamete return add; } +//modified by NIZNHY-PKV Fri Oct 12 09:34:10 2012f +static + Standard_Integer DistPC(const Standard_Real aT1, + const Handle(Geom_Curve)& aC1, + const Standard_Real aCriteria, + GeomAPI_ProjectPointOnCurve& aProjector, + Standard_Real& aD, + Standard_Real& aT2); + +static + Standard_Integer DistPC(const Standard_Real aT1, + const Handle(Geom_Curve)& aC1, + const Standard_Real aCriteria, + GeomAPI_ProjectPointOnCurve& aProjector, + Standard_Real& aD, + Standard_Real& aT2, + Standard_Real& aDmax, + Standard_Real& aTmax); + +static + Standard_Integer FindMaxDistPC(const Standard_Real aT1A, + const Standard_Real aT1B, + const Handle(Geom_Curve)& aC1, + const Standard_Real aCriteria, + const Standard_Real aEps1, + GeomAPI_ProjectPointOnCurve& aProjector, + Standard_Real& aDmax, + Standard_Real& aT1max); + +//======================================================================= +//function : CheckCoincidence +//purpose : +//======================================================================= +Standard_Integer CheckCoincidence(const Standard_Real aT11, + const Standard_Real aT12, + const Handle(Geom_Curve)& aC1, + const Standard_Real aT21, + const Standard_Real aT22, + const Handle(Geom_Curve)& aC2, + const Standard_Real aCriteria, + const Standard_Real aEps1, + GeomAPI_ProjectPointOnCurve& aProjector) +{ + Standard_Integer iErr, aNb1, i, aNbX; + Standard_Real dT1, aT1, aT2, aD, aDmax, aTmin, aTmax; + Standard_Real aT1A, aT1B, aD1max,aT1max; + // + iErr=0; // the patches are coincided + // + // + aProjector.Init(aC2, aT21, aT22); + // + aDmax=-1.; + // + // 1. Express evaluation + // + aNb1=10; // Number of intervals on the curve #1 + dT1=(aT12-aT11)/aNb1; + for (i=1; iaCriteria) { + iErr=2; // the distance is too big + return iErr; + } + } + // + // 2. Deep evaluation + aD1max=aDmax; + // + aNbX=aNb1-1; + for (i=1; iaYL) { + aA=aXL; + aXL=aXP; + aYL=aYP; + aXP=aA+(aB-aA)*aGS; + iErr=DistPC(aXP, aC1, aCriteria, aProjector, aYP, aT2P, aDmax, aT1max); + if(iErr){ + return iErr; + } + } + else { + aB=aXP; + aXP=aXL; + aYP=aYL; + aXL=aB-(aB-aA)*aGS; + iErr=DistPC(aXL, aC1, aCriteria, aProjector, aYL, aT2L, aDmax, aT1max); + if(iErr){ + return iErr; + } + } + // + if ((aB-aA)aDmax) { + aDmax=aD; + aTmax=aT2; + } + // + return iErr; +} +//======================================================================= +//function : DistPC +//purpose : +//======================================================================= +Standard_Integer DistPC(const Standard_Real aT1, + const Handle(Geom_Curve)& aC1, + const Standard_Real aCriteria, + GeomAPI_ProjectPointOnCurve& aProjector, + Standard_Real& aD, + Standard_Real& aT2) +{ + Standard_Integer iErr, aNbP2; + gp_Pnt aP1; + // + iErr=0; + aC1->D0(aT1, aP1); + // + aProjector.Perform(aP1); + aNbP2=aProjector.NbPoints(); + if (!aNbP2) { + iErr=1;// the point from aC1 can not be projected on aC2 + return iErr; + } + // + aD=aProjector.LowerDistance(); + aT2=aProjector.LowerDistanceParameter(); + if (aD>aCriteria) { + iErr=2;// the distance is too big + } + // + return iErr; +} +//modified by NIZNHY-PKV Fri Oct 12 09:34:12 2012t diff --git a/tests/bugs/modalg/bug23470 b/tests/bugs/modalg/bug23470 new file mode 100755 index 0000000000..2f3682b0c9 --- /dev/null +++ b/tests/bugs/modalg/bug23470 @@ -0,0 +1,25 @@ +puts "============" +puts "CR23470" +puts "============" +puts "" +########################################################################################################## +# Boolean Fuse between two edges fails +########################################################################################################## + +restore [locate_data_file bug23470_qe.brep] qe +explode qe +bop qe_1 qe_2 +bopfuse result +set nb_info [nbshapes result] + +set nb_v_good 2 +set nb_e_good 1 +set nb_w_good 1 +set nb_shape_good 5 + +set length 48.4459 +set command bopfuse + +set 2dviewer 1 + + diff --git a/tests/bugs/modalg/end b/tests/bugs/modalg/end index ce77fef5ac..215479c5ae 100755 --- a/tests/bugs/modalg/end +++ b/tests/bugs/modalg/end @@ -31,27 +31,88 @@ if { [isdraw result] } { if { ($mass != 0 && [expr 1.*abs($mass - $m)/$mass] > 0.01) || ($mass == 0 && $m != 0) } { puts "Error : The $prop of result shape is $m" } - - if { [info exists nbsh_v ] } { - set arr_v [explode result v] - set nb_v [ llength $arr_v ] - if { $nb_v != $nbsh_v } { - puts "Error : Result shape is WRONG because it must contain $nbsh_v vertexes instead of $nb_v" - } else { - puts "Result shape contains $nb_v vertexes" - } - - } + + if { [info exists nb_v_good] } { + regexp {VERTEX +: +([-0-9.+eE]+)} $nb_info full nb_v + if { ${nb_v} != ${nb_v_good} } { + puts "Error : Result shape is WRONG because it must contains ${nb_v_good} vertexes instead of ${nb_v}" + } else { + puts "Result shape contains ${nb_v} vertexes" + } + } - if { [info exists nbsh_e ] } { - set arr_e [explode result e] - set nb_e [ llength $arr_e ] - if { $nb_e != $nbsh_e } { - puts "Error : Result shape is WRONG because it must contain $nbsh_e edges instead of $nb_e" + if { [info exists nb_e_good] } { + regexp {EDGE +: +([-0-9.+eE]+)} $nb_info full nb_e + if { ${nb_e} != ${nb_e_good} } { + puts "Error : Result shape is WRONG because it must contains ${nb_e_good} edges instead of ${nb_e}" } else { - puts "Result shape contains $nb_e edges" - } - } + puts "Result shape contains ${nb_e} edges" + } + } + + if { [info exists nb_w_good] } { + regexp {WIRE +: +([-0-9.+eE]+)} $nb_info full nb_w + if { ${nb_w} != ${nb_w_good} } { + puts "Error : Result shape is WRONG because it must contains ${nb_w_good} wires instead of ${nb_w}" + } else { + puts "Result shape contains ${nb_w} wires" + } + } + + if { [info exists nb_f_good] } { + regexp {FACE +: +([-0-9.+eE]+)} $nb_info full nb_f + if { ${nb_f} != ${nb_f_good} } { + puts "Error : Result shape is WRONG because it must contains ${nb_f_good} faces instead of ${nb_f}" + } else { + puts "Result shape contains ${nb_f} faces" + } + } + + if { [info exists nb_sh_good] } { + regexp {SHELL +: +([-0-9.+eE]+)} $nb_info full nb_sh + if { ${nb_sh} != ${nb_sh_good} } { + puts "Error : Result shape is WRONG because it must contains ${nb_sh_good} shells instead of ${nb_sh}" + } else { + puts "Result shape contains ${nb_sh} shells" + } + } + + if { [info exists nb_sol_good] } { + regexp {SOLID +: +([-0-9.+eE]+)} $nb_info full nb_sol + if { ${nb_sol} != ${nb_sol_good} } { + puts "Error : Result shape is WRONG because it must contains ${nb_sol_good} solids instead of ${nb_sol}" + } else { + puts "Result shape contains ${nb_sol} solids" + } + } + + if { [info exists nb_compsol_good] } { + regexp {COMPSOLID +: +([-0-9.+eE]+)} $nb_info full nb_compsol + if { ${nb_compsol} != ${nb_compsol_good} } { + puts "Error : Result shape is WRONG because it must contains ${nb_compsol_good} compsolids instead of ${nb_compsol}" + } else { + puts "Result shape contains ${nb_compsol} compsolids" + } + } + + if { [info exists nb_compound_good] } { + regexp {COMPOUND +: +([-0-9.+eE]+)} $nb_info full nb_compound + if { ${nb_compound} != ${nb_compound_good} } { + puts "Error : Result shape is WRONG because it must contains ${nb_compound_good} compounds instead of ${nb_compound}" + } else { + puts "Result shape contains ${nb_compound} compounds" + } + } + + if { [info exists nb_shape_good] } { + regexp {SHAPE +: +([-0-9.+eE]+)} $nb_info full nb_shape + if { ${nb_shape} != ${nb_shape_good} } { + puts "Error : Result shape is WRONG because it must contains ${nb_shape_good} shapes instead of ${nb_shape}" + } else { + puts "Result shape contains ${nb_shape} shapes" + } + } + } else { if { $m != 0 } { puts "Error : The $command is not valid. The $prop is $m"