]> OCCT Git - occt-copy.git/commitdiff
Fix for issue #27665 CR0_670_FS_27665
authornbv <nbv@opencascade.com>
Mon, 11 Jul 2016 13:09:45 +0000 (16:09 +0300)
committernbv <nbv@opencascade.com>
Fri, 22 Jul 2016 07:20:44 +0000 (10:20 +0300)
src/Extrema/Extrema.cdl
src/Extrema/Extrema_GExtCC.cdl
src/Extrema/Extrema_GExtCC.gxx
src/Extrema/Extrema_UBTFilterCCPoints.hxx [new file with mode: 0644]
src/Extrema/FILES

index f0137906e4876535bbad3bf0c0113e235773cef3..1ce2c92e9620618b24ae8894ff0a298919cf8dbc 100644 (file)
@@ -133,6 +133,8 @@ is
     generic class GExtCC2d, CCache2d, ECC2d;
     generic class GLocateExtCC2d, LCCache2d, ELCC2d, LocECC2d;
     
+    imported UBTFilterCCPoints;
+    
     --  Curve-Surface:                                  
     class ExtCS;
 
index 038797f96120359668ba5dc7f8149d641b655e17..8a0ca2aeaad02fee6766df3f2bf0ce8f6052c96f 100644 (file)
@@ -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;
index 27c5eae14a3cd438bae1f81bc50bfcb41a122d06..5d4b3a4ef8e44722f9e06b0311f4c8839f63a849 100644 (file)
 #include <Extrema_ExtPElC.hxx>
 #include <Standard_NullObject.hxx>
 
+#include <NCollection_UBTreeFiller.hxx>
+#include <Bnd_Box.hxx>
+#include <BndLib_Add3dCurve.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+
+typedef NCollection_UBTreeFiller<Handle(Extrema_CCache), Bnd_Box> UBTreeFiller;
+typedef NCollection_UBTree<Handle(Extrema_CCache), Bnd_Box> 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 (file)
index 0000000..ce59dcf
--- /dev/null
@@ -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 <NCollection_CellFilter.hxx>
+
+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_CCPointsInspector> Extrema_UBTFilterCCPoints;
+
+#endif //_Extrema_UBTFilterCCPoints_HeaderFile
index 9aa286ee6d4bad7fab4f069a5327613f65aad9f7..29bc1cba57c5f7ef4fd6834f1b8b49c133145e1f 100644 (file)
@@ -1 +1,2 @@
 Extrema_HUBTreeOfSphere.hxx
+Extrema_UBTFilterCCPoints.hxx
\ No newline at end of file