From 105d021c0167561764b3a9ab548ef61ed07938cf Mon Sep 17 00:00:00 2001 From: nbv Date: Mon, 11 Jul 2016 16:09:45 +0300 Subject: [PATCH] Fix for issue #27665 --- src/Extrema/Extrema.cdl | 2 + src/Extrema/Extrema_GExtCC.cdl | 10 +- src/Extrema/Extrema_GExtCC.gxx | 205 +++++++++++++++++----- src/Extrema/Extrema_UBTFilterCCPoints.hxx | 69 ++++++++ src/Extrema/FILES | 1 + 5 files changed, 237 insertions(+), 50 deletions(-) create mode 100644 src/Extrema/Extrema_UBTFilterCCPoints.hxx 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..5d4b3a4ef8 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 : @@ -395,18 +484,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 +937,58 @@ 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++) { + + // Size computed to have cell index inside of int32 value. + 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 -- 2.39.5