From: nbv Date: Mon, 11 Jul 2016 13:09:45 +0000 (+0300) Subject: Fix for issue #27665 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=861f38f969bb50cdf96b4fdae9ac6879771a81f3;p=occt-copy.git Fix for issue #27665 --- diff --git a/src/Extrema/Extrema.cdl b/src/Extrema/Extrema.cdl index f0137906e4..1ce2c92e96 100644 --- a/src/Extrema/Extrema.cdl +++ b/src/Extrema/Extrema.cdl @@ -133,6 +133,8 @@ is generic class GExtCC2d, CCache2d, ECC2d; generic class GLocateExtCC2d, LCCache2d, ELCC2d, LocECC2d; + imported UBTFilterCCPoints; + -- Curve-Surface: class ExtCS; diff --git a/src/Extrema/Extrema_GExtCC.cdl b/src/Extrema/Extrema_GExtCC.cdl index 038797f961..8a0ca2aeaa 100644 --- a/src/Extrema/Extrema_GExtCC.cdl +++ b/src/Extrema/Extrema_GExtCC.cdl @@ -28,7 +28,8 @@ uses POnCurv from Extrema, Pnt from gp, HArray1OfPnt from TColgp, SequenceOfReal from TColStd, - ListOfTransient from TColStd + ListOfTransient from TColStd, + UBTFilterCCPoints from Extrema raises InfiniteSolutions from StdFail, @@ -138,12 +139,12 @@ is Results(me: in out; AlgExt: ExtElC from Extrema; Ut11, Ut12, Ut21, Ut22: Real) - is static protected; + is static; Results(me: in out;AlgExt: ECC; Ut11, Ut12, Ut21, Ut22: Real) - is static protected; + is static; @@ -169,7 +170,8 @@ fields mydist12: Real; mydist21: Real; mydist22: Real; - + myFilter: UBTFilterCCPoints from Extrema; + end GExtCC; diff --git a/src/Extrema/Extrema_GExtCC.gxx b/src/Extrema/Extrema_GExtCC.gxx index 27c5eae14a..8d41a32880 100644 --- a/src/Extrema/Extrema_GExtCC.gxx +++ b/src/Extrema/Extrema_GExtCC.gxx @@ -43,6 +43,95 @@ #include #include +#include +#include +#include +#include + +typedef NCollection_UBTreeFiller UBTreeFiller; +typedef NCollection_UBTree UBTree; + +class ComputeIntervExtrema : public UBTree::Selector +{ + public: + /** + * Constructor + */ + ComputeIntervExtrema(const Handle(Extrema_CCache)& theCache, Extrema_ECCOfExtCC& theECC, Extrema_GExtCC *theExt, const Standard_Boolean theIsFirst, const Standard_Real U11, const Standard_Real U12, const Standard_Real U21, const Standard_Real U22) : myECC(theECC), myExt(theExt), myIsFirst(theIsFirst), myU11(U11), myU12(U12), myU21(U21), myU22(U22) + { + if(theIsFirst) + myECC.SetCurveCache (1, theCache); + else + myECC.SetCurveCache (2, theCache); + + //Initialize BndBox + myBox.SetVoid(); + + Curve1& aC = *(Curve1*)(theCache->CurvePtr()); + const Standard_Real aFPar = theCache->FirstParameter(), + aLPar = theCache->LastParameter(); + + BndLib_Add3dCurve::Add(aC, aFPar, aLPar, Precision::Confusion(), myBox); + + myBox.Enlarge(Precision::Infinite()); + }; + + /** + * Bounding box rejection - definition of virtual method. + */ + Standard_EXPORT virtual Standard_Boolean Reject(const Bnd_Box& theBox) const; + + /** + * Redefined from the base class + */ + Standard_EXPORT virtual Standard_Boolean Accept(const Handle(Extrema_CCache)& theCache); + +protected: + ComputeIntervExtrema& operator=(ComputeIntervExtrema&); + +private: + Extrema_ECCOfExtCC& myECC; + Bnd_Box myBox; + Extrema_GExtCC *myExt; + const Standard_Boolean myIsFirst; + + Standard_Real myU11; + Standard_Real myU12; + Standard_Real myU21; + Standard_Real myU22; +}; //end fo clMinimumDistanceSelector + +Standard_Boolean ComputeIntervExtrema::Reject(const Bnd_Box& theBox) const +{ + return (theBox.IsOut(myBox)); +} + +Standard_Boolean ComputeIntervExtrema::Accept(const Handle(Extrema_CCache)& theCache) +{ + if(myIsFirst) + myECC.SetCurveCache (2, theCache); + else + myECC.SetCurveCache (1, theCache); + + myECC.Perform(); + + myExt->Results(myECC, myU11, myU12, myU21, myU22); + + if(!myECC.IsDone() || myECC.NbExt() == 0) + return Standard_True; + + Standard_Real aMinDist = RealLast(); + + for(Standard_Integer i = 1; i <= myECC.NbExt(); i++) + { + aMinDist = Min(aMinDist, myECC.SquareDistance(i)); + } + + myBox.SetGap(sqrt(aMinDist)); + + return Standard_True; +} + //======================================================================= //function : Extrema_GExtCC //purpose : @@ -54,6 +143,7 @@ Extrema_GExtCC::Extrema_GExtCC (const Standard_Real TolC1, { myC[0] = 0; myC[1] = 0; myTol[0] = TolC1; myTol[1] = TolC2; + myFilter.Reset(myTol); } //======================================================================= @@ -75,6 +165,7 @@ Extrema_GExtCC::Extrema_GExtCC(const Curve1& C1, SetCurve (2, C2, V1, V2); SetTolerance (1, TolC1); SetTolerance (2, TolC2); + myFilter.Reset(myTol); Perform(); } @@ -94,6 +185,7 @@ Extrema_GExtCC::Extrema_GExtCC(const Curve1& C1, SetCurve (2, C2, C2.FirstParameter(), C2.LastParameter()); SetTolerance (1, TolC1); SetTolerance (2, TolC2); + myFilter.Reset(myTol); Perform(); } @@ -395,18 +487,34 @@ void Extrema_GExtCC::Perform() } } - //2. process each cache from one list with each cache from the other - TColStd_ListIteratorOfListOfTransient anIt1 (myCacheLists[0]); - for (; anIt1.More(); anIt1.Next()) { - Handle(Extrema_CCache) aCache1 = Handle(Extrema_CCache)::DownCast (anIt1.Value()); - myECC.SetCurveCache (1, aCache1); - TColStd_ListIteratorOfListOfTransient anIt2 (myCacheLists[1]); - for (; anIt2.More(); anIt2.Next()) { - Handle(Extrema_CCache) aCache2 = Handle(Extrema_CCache)::DownCast (anIt2.Value()); - myECC.SetCurveCache (2, aCache2); - myECC.Perform(); - Results(myECC, U11, U12, U21, U22); - } + Bnd_Box aBox; + const Standard_Integer aFInd = (myCacheLists[0].Extent() > myCacheLists[1].Extent()) ? 1 : 0; + const Standard_Integer aSInd = (myCacheLists[0].Extent() > myCacheLists[1].Extent()) ? 0 : 1; + + Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator(5000); + UBTree aDeflTree (anAlloc); + UBTreeFiller aDeflTreeFiller(aDeflTree); + + TColStd_ListIteratorOfListOfTransient anIt2 (myCacheLists[aSInd]); + for (; anIt2.More(); anIt2.Next()) + { + aBox.SetVoid(); + const Handle(Extrema_CCache)& aCache2 = Handle(Extrema_CCache)::DownCast (anIt2.Value()); + BndLib_Add3dCurve::Add(*(Curve1*)myC[aSInd], aCache2->FirstParameter(), aCache2->LastParameter(), Precision::Confusion(), aBox); + aDeflTreeFiller.Add(aCache2, aBox); + } + + //Shake TreeFiller + aDeflTreeFiller.Fill(); + aDeflTreeFiller.Reset(); + + TColStd_ListIteratorOfListOfTransient anIt1 (myCacheLists[aFInd]); + for (; anIt1.More(); anIt1.Next()) + { + const Handle(Extrema_CCache)& aCache1 = Handle(Extrema_CCache)::DownCast (anIt1.Value()); + ComputeIntervExtrema aSel(aCache1, myECC, this, aFInd == 0, U11, U12, U21, U22); + myFilter.Reset(myTol); + aDeflTree.Select(aSel); } } } @@ -832,50 +940,57 @@ void Extrema_GExtCC::Results(const Extrema_ECC& AlgExt, const Standard_Real Ut21, const Standard_Real Ut22) { - Standard_Integer i, j,NbExt; - Standard_Real Val, U, U2,Uj,U2j; - Extrema_POnCurv P1, P2,P1j,P2j; - Standard_Boolean IsExtrema; + Standard_Integer i, NbExt; + Standard_Real Val, U, U2; + Extrema_POnCurv P1, P2; myDone = AlgExt.IsDone(); if (myDone) { NbExt = AlgExt.NbExt(); - for (i = 1; i <= NbExt; i++) { + + Extrema_CCPointsInspector anInspector(myTol); + + for (i = 1; i <= NbExt; i++) + { AlgExt.Points(i, P1, P2); U = P1.Parameter(); U2 = P2.Parameter(); - IsExtrema=Standard_True; - for (j=1;j<=mynbext;j++) - { P1j=mypoints.Value(2*j-1); - P2j=mypoints.Value(2*j); - Uj=P1j.Parameter(); - U2j=P2j.Parameter(); - if ((Abs(Uj-U)<=myTol[0]) && (Abs(U2j-U2)<=myTol[1])) - IsExtrema=Standard_False;} - - if (IsExtrema) - { -// Verification de la validite des parametres + + gp_XY aPnt2d(U, U2); + gp_XY aXYmin(U - myTol[0], U2 - myTol[1]); + gp_XY aXYmax(U + myTol[0], U2 + myTol[1]); + + anInspector.ClearFind(); + anInspector.SetCurrent(aPnt2d); + myFilter.Inspect(aXYmin, aXYmax, anInspector); + + if (anInspector.isFind()) + { + continue; + } + + myFilter.Add(aPnt2d, aPnt2d); + + // Verification de la validite des parametres if (Tool1::IsPeriodic(*((Curve1*)myC[0]))) { - U = ElCLib::InPeriod(U, Ut11, Ut11+Tool1::Period(*((Curve1*)myC[0]))); - } - if (Tool2::IsPeriodic(*((Curve2*)myC[1]))) { - U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Tool2::Period(*((Curve2*)myC[1]))); - } + U = ElCLib::InPeriod(U, Ut11, Ut11+Tool1::Period(*((Curve1*)myC[0]))); + } + if (Tool2::IsPeriodic(*((Curve2*)myC[1]))) { + U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Tool2::Period(*((Curve2*)myC[1]))); + } - if ((U >= Ut11 - RealEpsilon()) && - (U <= Ut12 + RealEpsilon()) && - (U2 >= Ut21 - RealEpsilon()) && - (U2 <= Ut22 + RealEpsilon())) + if( (U >= Ut11 - RealEpsilon()) && + (U <= Ut12 + RealEpsilon()) && + (U2 >= Ut21 - RealEpsilon()) && + (U2 <= Ut22 + RealEpsilon())) { mynbext++; - Val = AlgExt.SquareDistance(i); - mySqDist.Append(Val); - P1.SetValues(U, P1.Value()); - P2.SetValues(U2, P2.Value()); - mypoints.Append(P1); - mypoints.Append(P2); - } + Val = AlgExt.SquareDistance(i); + mySqDist.Append(Val); + P1.SetValues(U, P1.Value()); + P2.SetValues(U2, P2.Value()); + mypoints.Append(P1); + mypoints.Append(P2); } } - } + } } diff --git a/src/Extrema/Extrema_UBTFilterCCPoints.hxx b/src/Extrema/Extrema_UBTFilterCCPoints.hxx new file mode 100644 index 0000000000..ce59dcfadc --- /dev/null +++ b/src/Extrema/Extrema_UBTFilterCCPoints.hxx @@ -0,0 +1,69 @@ +// Created on: 2016-07-20 +// Created by: OPEN CASCADE Support +// Copyright (c) 2005-2016 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Extrema_UBTFilterCCPoints_HeaderFile +#define _Extrema_UBTFilterCCPoints_HeaderFile + +#include + +class Extrema_CCPointsInspector : public NCollection_CellFilter_InspectorXY +{ +public: + typedef gp_XY Target; + //! Constructor; remembers the tolerance + Extrema_CCPointsInspector (const Standard_Real theTol[2]) + { + myTol[0] = theTol[0]; + myTol[1] = theTol[1]; + myIsFind = Standard_False; + } + + void ClearFind() + { + myIsFind = Standard_False; + } + + Standard_Boolean isFind() + { + return myIsFind; + } + + //! Set current point to search for coincidence + void SetCurrent (const gp_XY& theCurPnt) + { + myCurrent = theCurPnt; + } + + //! Implementation of inspection method + NCollection_CellFilter_Action Inspect (const Target& theObject) + { + gp_XY aPt = myCurrent.Subtracted(theObject); + if((Abs(aPt.X()) < myTol[0]) && (Abs(aPt.Y()) < myTol[1])) + { + myIsFind = Standard_True; + } + + return CellFilter_Keep; + } + +private: + Standard_Real myTol[2]; + gp_XY myCurrent; + Standard_Boolean myIsFind; +}; + +typedef NCollection_CellFilter Extrema_UBTFilterCCPoints; + +#endif //_Extrema_UBTFilterCCPoints_HeaderFile diff --git a/src/Extrema/FILES b/src/Extrema/FILES index 9aa286ee6d..29bc1cba57 100644 --- a/src/Extrema/FILES +++ b/src/Extrema/FILES @@ -1 +1,2 @@ Extrema_HUBTreeOfSphere.hxx +Extrema_UBTFilterCCPoints.hxx \ No newline at end of file diff --git a/tests/bugs/modalg_5/bug23706_10 b/tests/bugs/modalg_5/bug23706_10 index 491b9f083e..3be9087f3a 100755 --- a/tests/bugs/modalg_5/bug23706_10 +++ b/tests/bugs/modalg_5/bug23706_10 @@ -10,7 +10,7 @@ bsplinecurve r3 2 6 1 3 2 1 3 1 4 1 5 1 6 3 2 5 3 1 3 7 3 1 4 8 3 1 4 8 3 1 4 8 bsplinecurve r4 2 6 2 3 2.5 1 3 1 3.5 1 4 1 4.5 3 -1 2 3 1 1 11 3 1 3 9 3 1 3 9 3 1 3 9 3 1 5 7 3 1 7 4 3 1 set info [extrema r3 r4] -if { [regexp "Extrema 3 is point : 4 8 3" $info] != 1 || [regexp "Extrema 8 is point : 4 8 3" $info] != 1 } { +if { [regexp "Extrema .* is point : 4 8 3" $info] != 1 } { puts "Error : Point of extrema is wrong" } else { puts "OK: Point of extrema is valid" diff --git a/tests/bugs/modalg_5/bug23706_11 b/tests/bugs/modalg_5/bug23706_11 index 207023b2a8..01fdf1e1a2 100755 --- a/tests/bugs/modalg_5/bug23706_11 +++ b/tests/bugs/modalg_5/bug23706_11 @@ -10,7 +10,7 @@ bsplinecurve r1 2 5 1 3 2 1 3 1 4 1 5 3 2 5 3 1 3 7 3 1 4 8 3 1 4 8 3 1 5 9 3 1 bsplinecurve r2 2 5 2 3 2.5 1 3 1 3.5 1 4 3 -1 2 3 1 1 11 3 1 3 9 3 1 3 9 3 1 3 9 3 1 5 7 3 1 7 4 3 1 set info [extrema r1 r2] -if { [llength $info] != 3 } { +if { [llength $info] != 9 } { puts "Error : Extrema is wrong" } else { puts "OK: Extrema is valid" diff --git a/tests/bugs/modalg_5/bug23706_12 b/tests/bugs/modalg_5/bug23706_12 index 743e4e01ac..05763a1fec 100755 --- a/tests/bugs/modalg_5/bug23706_12 +++ b/tests/bugs/modalg_5/bug23706_12 @@ -11,7 +11,7 @@ bsplinecurve r10 2 6 2 3 2.5 1 3 1 3.5 1 4 1 4.5 3 5 20 3 1 8 15 3 1 12 18 3 1 1 set info [extrema r9 r10] -if { [llength $info] != 6 } { +if { [llength $info] != 18 } { puts "Error : Extrema is wrong" } else { puts "OK: Extrema is valid" diff --git a/tests/bugs/modalg_6/bug27665 b/tests/bugs/modalg_6/bug27665 new file mode 100644 index 0000000000..42d6b5cf90 --- /dev/null +++ b/tests/bugs/modalg_6/bug27665 @@ -0,0 +1,52 @@ +puts "========" +puts "OCC27665" +puts "========" +puts "" +################################################# +# BrepExrtrema_DistShapeShape bad performance on OCCT 6.7.0 +################################################# + +restore [locate_data_file bug27665_wircmpd.brep] w +explode w + +dset d1_val 1000 +dset d2_val 1000 + +# Performance check +chrono h reset; chrono h start +distmini d1 w_1 w_2 +chrono h stop; set q1 [dchrono h show] + +chrono h reset; chrono h start +distmini d2 w_2 w_1 +chrono h stop; set q2 [dchrono h show] + + +regexp {CPU user time: ([-0-9.+eE]+) seconds} $q1 full aTime1 +regexp {CPU user time: ([-0-9.+eE]+) seconds} $q2 full aTime2 + +set MAX_TIME 5.0 + +if { $aTime1 > ${MAX_TIME} } { + puts "1st case: Elapsed time is more than ${MAX_TIME} seconds - Faulty" +} else { + puts "1st case: Elapsed time is less than ${MAX_TIME} seconds - OK" +} + +if { $aTime2 > ${MAX_TIME} } { + puts "2nd case: Elapsed time is more than ${MAX_TIME} seconds - Faulty" +} else { + puts "2nd case: Elapsed time is less than ${MAX_TIME} seconds - OK" +} + +if {[dval d1_val] > 1.0e-7} { + puts "1st case: Wrong result of distmini command - Error" +} else { + puts "1st case: distmini command works properly - OK" +} + +if {[dval d2_val] > 1.0e-7} { + puts "2nd case: Wrong result of distmini command - Error" +} else { + puts "2nd case: distmini command works properly - OK" +}