]> OCCT Git - occt-copy.git/commitdiff
0032539: Modeling Algorithms - Parallelize BRepExtrema_DistShapeShape algorithm CR32539_1
authorasuraven <andrey.suravenkov@opencascade.com>
Wed, 18 Aug 2021 17:23:07 +0000 (20:23 +0300)
committerasuraven <andrey.suravenkov@opencascade.com>
Mon, 30 Aug 2021 13:05:17 +0000 (16:05 +0300)
src/BRepCheck/BRepCheck_Analyzer.cxx
src/BRepExtrema/BRepExtrema_DistShapeShape.cxx
src/BRepExtrema/BRepExtrema_DistShapeShape.hxx
src/BRepExtrema/BRepExtrema_DistanceSS.cxx
src/BRepExtrema/BRepExtrema_DistanceSS.hxx
src/BRepTest/BRepTest_ExtremaCommands.cxx

index 1e777665ce7d04ed977177f595bff465e4a891bc..3be4b24cfb95ff2408b13869f7be8047710bf3c1 100644 (file)
@@ -434,7 +434,7 @@ void BRepCheck_Analyzer::Perform (Standard_Boolean theIsParallel)
     aNbTasks = (Standard_Integer)Ceiling ((double)aMapSize / aTaskSize);
   }
 
-  NCollection_Array1< NCollection_Array1<TopoDS_Shape> > aArrayOfArray (0, aNbTasks - 1);
+  NCollection_Array1< NCollection_Array1<TopoDS_Shape> > anArrayOfArray (0, aNbTasks - 1);
   for (Standard_Integer anI = 1; anI <= aMapSize; ++anI)
   {
     Standard_Integer aVectIndex  = (anI-1) / aTaskSize;
@@ -447,13 +447,13 @@ void BRepCheck_Analyzer::Perform (Standard_Boolean theIsParallel)
       {
         aVectorSize = aTailSize;
       }
-      aArrayOfArray[aVectIndex].Resize (0, aVectorSize - 1, Standard_False);
+      anArrayOfArray[aVectIndex].Resize (0, aVectorSize - 1, Standard_False);
     }
-    aArrayOfArray[aVectIndex][aShapeIndex] = myMap.FindKey (anI);
+    anArrayOfArray[aVectIndex][aShapeIndex] = myMap.FindKey (anI);
   }
 
-  BRepCheck_ParallelAnalyzer aParallelAnalyzer (aArrayOfArray, myMap);
-  OSD_Parallel::For (0, aArrayOfArray.Size(), aParallelAnalyzer, !theIsParallel);
+  BRepCheck_ParallelAnalyzer aParallelAnalyzer (anArrayOfArray, myMap);
+  OSD_Parallel::For (0, anArrayOfArray.Size(), aParallelAnalyzer, !theIsParallel);
 }
 
 //=======================================================================
index b31ea7a783c596f39b885e9d0f73e97982c4fa33..4e062d8b84cfa79d45596f03b1513d292b4b8c9f 100644 (file)
@@ -36,6 +36,8 @@
 #include <BRep_Tool.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
 #include <NCollection_Vector.hxx>
+#include <OSD_Parallel.hxx>
+#include <Standard_Atomic.hxx>
 #include <StdFail_NotDone.hxx>
 
 #include <algorithm>
@@ -56,13 +58,13 @@ namespace
   }
 
   static void BoxCalculation(const TopTools_IndexedMapOfShape& Map,
-                             Bnd_SeqOfBox&                     SBox)
+                             std::vector<Bnd_Box>&             SBox)
   {
     for (Standard_Integer i = 1; i <= Map.Extent(); i++)
     {
       Bnd_Box box;
       BRepBndLib::Add(Map(i), box);
-      SBox.Append(box);
+      SBox.push_back(box);
     }
   }
 
@@ -103,102 +105,754 @@ namespace
     return (theLeft.Distance < theRight.Distance);
   }
 }
+//=======================================================================
+//struct   : VertexTask
+//purpose  : 
+//=======================================================================
+struct VertexTask
+{
+  VertexTask(Standard_Integer theFirtsIndex,
+             Standard_Integer theLastIndex,
+             std::vector<BRepExtrema_SolutionElem>* theSolutionsShape1,
+             std::vector<BRepExtrema_SolutionElem>* theSolutionsShape2,
+             const TopTools_IndexedMapOfShape* theMap1,
+             const TopTools_IndexedMapOfShape* theMap2,
+             const std::vector<Bnd_Box>* theLBox1,
+             const std::vector<Bnd_Box>* theLBox2,
+             const Message_ProgressRange theRange,
+             Standard_Boolean* theIsBreak,
+             Standard_Real* theDistRef,
+             Standard_Real theEps,
+             Handle(Standard_HMutex) theMutex)
+    : myFirtsIndex(theFirtsIndex),
+    myLastIndex(theLastIndex),    
+    mySolutionsShape1(theSolutionsShape1),
+    mySolutionsShape2(theSolutionsShape2),
+    myMap1(theMap1),
+    myMap2(theMap2),
+    myLBox1(theLBox1),
+    myLBox2(theLBox2),
+    myRange(theRange),
+    myIsBreak(theIsBreak),
+    myDistRef(theDistRef),
+    myEps(theEps),
+    myMutex(theMutex)
+  {
+  }
+
+  VertexTask()
+    : myFirtsIndex(0),
+    myLastIndex(0), 
+    mySolutionsShape1(NULL),
+    mySolutionsShape2(NULL),
+    myMap1(NULL),
+    myMap2(NULL),
+    myLBox1(NULL),
+    myLBox2(NULL),
+    myIsBreak(NULL),
+    myDistRef(NULL),
+    myEps(Precision::Confusion()),
+    myMutex(NULL)
+  {
+  }
+
+  VertexTask& VertexTask::operator =(const VertexTask& theCopy)
+  {
+    myFirtsIndex = theCopy.myFirtsIndex;
+    myLastIndex = theCopy.myLastIndex;
+    mySolutionsShape1 = theCopy.mySolutionsShape1;
+    mySolutionsShape2 = theCopy.mySolutionsShape2;
+    myMap1 = theCopy.myMap1;
+    myMap2 = theCopy.myMap2;
+    myLBox1 = theCopy.myLBox1;
+    myLBox2 = theCopy.myLBox2;
+    myRange = theCopy.myRange;
+    myIsBreak = theCopy.myIsBreak;
+    myDistRef = theCopy.myDistRef;
+    myEps = theCopy.myEps;
+    myMutex = theCopy.myMutex;
+    return *this;
+  }
+
+  Standard_Integer myFirtsIndex;
+  Standard_Integer myLastIndex;
+  std::vector<BRepExtrema_SolutionElem>* mySolutionsShape1;
+  std::vector<BRepExtrema_SolutionElem>* mySolutionsShape2;
+  const TopTools_IndexedMapOfShape* myMap1;
+  const TopTools_IndexedMapOfShape* myMap2;
+  const std::vector<Bnd_Box>* myLBox1;
+  const std::vector<Bnd_Box>* myLBox2;
+  Message_ProgressRange myRange;
+  Standard_Boolean* myIsBreak;
+  Standard_Real* myDistRef;
+  Standard_Real myEps;
+  Handle(Standard_HMutex) myMutex;
+};
+
+//=======================================================================
+//struct   : VertexFunctor
+//purpose  : 
+//=======================================================================
+struct VertexFunctor
+{
+  void operator() (VertexTask& theTask) const
+  {
+    const Standard_Integer aCount1 = theTask.myMap1->Extent();
+    const Standard_Integer aCount2 = theTask.myMap2->Extent();
+
+    Message_ProgressScope aScope(theTask.myRange, NULL, aCount1);
 
+    Standard_Real aDistRef(0);
+    {
+      Standard_Mutex::Sentry aLock(theTask.myMutex.get());
+      aDistRef = *theTask.myDistRef;
+    }
+
+    for (Standard_Integer anIdx1 = theTask.myFirtsIndex; anIdx1 <= theTask.myLastIndex; ++anIdx1)
+    {
+      if (!aScope.More())
+      {
+        Standard_Atomic_CompareAndSwap((int*) *theTask.myIsBreak, Standard_False, Standard_True);
+      }
+      aScope.Next();
+      if (*theTask.myIsBreak)
+      {
+        break;
+      }
+
+      for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
+      {
+        const Bnd_Box& aBox1 = theTask.myLBox1->at(anIdx1-1);
+        const Bnd_Box& aBox2 = theTask.myLBox2->at(anIdx2-1);
+        if (aBox1.IsVoid() || aBox2.IsVoid())
+        {
+          continue;
+        }
+        const TopoDS_Shape& aShape1 = theTask.myMap1->FindKey(anIdx1);
+        const TopoDS_Shape& aShape2 = theTask.myMap2->FindKey(anIdx2);
+
+        BRepExtrema_DistanceSS aDistTool(aShape1, aShape2, aBox1, aBox2, aDistRef, theTask.myEps);
+        if (aDistTool.IsDone())
+        {
+          Standard_Mutex::Sentry aLock(theTask.myMutex.get());
+          if (aDistTool.DistValue() < *theTask.myDistRef - theTask.myEps)
+          {
+            theTask.mySolutionsShape1->clear();
+            theTask.mySolutionsShape2->clear();
+
+            const std::vector<BRepExtrema_SolutionElem>& aSeq1 = aDistTool.Seq1Value();
+            const std::vector<BRepExtrema_SolutionElem>& aSeq2 = aDistTool.Seq2Value();
+
+            theTask.mySolutionsShape1->insert(theTask.mySolutionsShape1->end(), aSeq1.begin(), aSeq1.end());
+            theTask.mySolutionsShape2->insert(theTask.mySolutionsShape2->end(), aSeq2.begin(), aSeq2.end());
+
+            *theTask.myDistRef = aDistTool.DistValue();
+          }
+          else if (fabs(aDistTool.DistValue() - *theTask.myDistRef) < theTask.myEps)
+          {
+            const std::vector<BRepExtrema_SolutionElem>& aSeq1 = aDistTool.Seq1Value();
+            const std::vector<BRepExtrema_SolutionElem>& aSeq2 = aDistTool.Seq2Value();
+
+            theTask.mySolutionsShape1->insert(theTask.mySolutionsShape1->end(), aSeq1.begin(), aSeq1.end());
+            theTask.mySolutionsShape2->insert(theTask.mySolutionsShape2->end(), aSeq2.begin(), aSeq2.end());
+
+            if (*theTask.myDistRef > aDistTool.DistValue())
+            {
+              *theTask.myDistRef = aDistTool.DistValue();
+            }
+          }
+          aDistRef = *theTask.myDistRef;
+        }
+      }
+    }
+  }
+};
 //=======================================================================
 //function : DistanceMapMap
 //purpose  : 
 //=======================================================================
 
-void BRepExtrema_DistShapeShape::DistanceMapMap (const TopTools_IndexedMapOfShape& theMap1,
-                                                 const TopTools_IndexedMapOfShape& theMap2,
-                                                 const Bnd_SeqOfBox&               theLBox1,
-                                                 const Bnd_SeqOfBox&               theLBox2,
-                                                 const Message_ProgressRange&      theRange)
+void BRepExtrema_DistShapeShape::DistanceVertVert(const TopTools_IndexedMapOfShape& theMap1,
+                                                  const TopTools_IndexedMapOfShape& theMap2,
+                                                  const std::vector<Bnd_Box>& theLBox1,
+                                                  const std::vector<Bnd_Box>& theLBox2,
+                                                  const Message_ProgressRange& theRange)
 {
-  NCollection_Vector<BRepExtrema_CheckPair> aPairList;
   const Standard_Integer aCount1 = theMap1.Extent();
   const Standard_Integer aCount2 = theMap2.Extent();
 
-  Message_ProgressScope aTwinScope(theRange, NULL, 2);
-  Message_ProgressRange aBoxRange(aTwinScope.Next());
-  Message_ProgressScope aBoxScope(aBoxRange, NULL, aCount1);
+  if (myMutex.IsNull())
+  {
+    Message_ProgressScope aScope(theRange, NULL, aCount1);
 
-  for (Standard_Integer anIdx1 = 1; anIdx1 <= aCount1; ++anIdx1)
+    for (Standard_Integer anIdx1 = 1; anIdx1 <= aCount1; ++anIdx1)
+    {
+      aScope.Next();
+      if (!aScope.More())
+      {
+        throw StdFail_NotDone();
+      }
+      for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
+      {
+        const Bnd_Box& aBox1 = theLBox1[anIdx1-1];
+        const Bnd_Box& aBox2 = theLBox2[anIdx2-1];
+        if (aBox1.IsVoid() || aBox2.IsVoid())
+        {
+          continue;
+        }
+        const TopoDS_Shape& aShape1 = theMap1.FindKey(anIdx1);
+        const TopoDS_Shape& aShape2 = theMap2.FindKey(anIdx2);
+
+        BRepExtrema_DistanceSS aDistTool(aShape1, aShape2, aBox1, aBox2, myDistRef, myEps);
+        if (aDistTool.IsDone())
+        {
+          if (aDistTool.DistValue() < myDistRef - myEps)
+          {
+            mySolutionsShape1.clear();
+            mySolutionsShape2.clear();
+
+            const std::vector<BRepExtrema_SolutionElem>& aSeq1 = aDistTool.Seq1Value();
+            const std::vector<BRepExtrema_SolutionElem>& aSeq2 = aDistTool.Seq2Value();
+
+            mySolutionsShape1.insert(mySolutionsShape1.end(), aSeq1.begin(), aSeq1.end());
+            mySolutionsShape2.insert(mySolutionsShape2.end(), aSeq2.begin(), aSeq2.end());
+
+            myDistRef = aDistTool.DistValue();
+          }
+          else if (fabs(aDistTool.DistValue() - myDistRef) < myEps)
+          {
+            const std::vector<BRepExtrema_SolutionElem>& aSeq1 = aDistTool.Seq1Value();
+            const std::vector<BRepExtrema_SolutionElem>& aSeq2 = aDistTool.Seq2Value();
+
+            mySolutionsShape1.insert(mySolutionsShape1.end(), aSeq1.begin(), aSeq1.end());
+            mySolutionsShape2.insert(mySolutionsShape2.end(), aSeq2.begin(), aSeq2.end());
+
+            if (myDistRef > aDistTool.DistValue())
+            {
+              myDistRef = aDistTool.DistValue();
+            }
+          }
+        }
+      }
+    }
+  }
+  else
   {
-    aBoxScope.Next();
-    if (!aBoxScope.More())
+    const Standard_Integer aMinTaskSize = 10;
+    const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
+    const Standard_Integer aNbThreads = aThreadPool->NbThreads();
+    Standard_Integer aNbTasks = aNbThreads * 10;
+    Standard_Integer aTaskSize = (Standard_Integer) Ceiling((double) aCount1 / aNbTasks);
+    if (aTaskSize < aMinTaskSize)
+    {
+      aTaskSize = aMinTaskSize;
+      aNbTasks = (Standard_Integer) Ceiling((double) aCount1 / aTaskSize);
+    }
+
+    Standard_Integer aFirstIndex(1);
+    NCollection_Array1<VertexTask> aTaskArray(0, aNbTasks - 1);
+    Message_ProgressScope aDistScope(theRange, NULL, aNbTasks);
+    for (Standard_Integer anI = 0; anI < aTaskArray.Size(); ++anI)
+    {
+      if (aCount1 < aFirstIndex + aTaskSize - 1)
+      {
+        aTaskSize = aCount1 - aFirstIndex + 1;
+      }
+      VertexTask aTask(aFirstIndex, aFirstIndex + aTaskSize-1,
+                       &mySolutionsShape1, &mySolutionsShape2,
+                       &theMap1, &theMap2, &theLBox1, &theLBox2,
+                       aDistScope.Next(), &myIsBreak, &myDistRef,
+                       myEps, myMutex);
+      aTaskArray.SetValue(anI, aTask);
+      aFirstIndex += aTaskSize;
+    }
+    OSD_Parallel::ForEach(aTaskArray.begin(), aTaskArray.end(), VertexFunctor(), Standard_False);
+
+    if (myIsBreak)
     {
       throw StdFail_NotDone();
     }
-    for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
+  }
+}
+
+
+//=======================================================================
+//struct   : DistanceTask
+//purpose  : 
+//=======================================================================
+struct DistanceTask
+{
+  DistanceTask(const NCollection_Array1<BRepExtrema_CheckPair>* theArray,
+               std::vector<BRepExtrema_SolutionElem>* theSolutionsShape1,
+               std::vector<BRepExtrema_SolutionElem>* theSolutionsShape2,
+               const TopTools_IndexedMapOfShape* theMap1,
+               const TopTools_IndexedMapOfShape* theMap2,
+               const std::vector<Bnd_Box>* theLBox1,
+               const std::vector<Bnd_Box>* theLBox2,
+               const Message_ProgressRange theRange,
+               Standard_Boolean* theIsBreak,
+               Standard_Boolean* theIsDone,
+               Standard_Real* theDistRef,
+               Standard_Real theEps,
+               Handle(Standard_HMutex) theMutex)
+    : myArray(theArray),
+    mySolutionsShape1(theSolutionsShape1),
+    mySolutionsShape2(theSolutionsShape2),
+    myMap1(theMap1),
+    myMap2(theMap2),
+    myLBox1(theLBox1),
+    myLBox2(theLBox2),
+    myRange(theRange),
+    myIsBreak(theIsBreak),
+    myIsDone(theIsDone),
+    myDistRef(theDistRef),
+    myEps(theEps),
+    myMutex(theMutex)
+  {
+  }
+
+  DistanceTask()
+    : myArray(NULL),
+    mySolutionsShape1(NULL),
+    mySolutionsShape2(NULL),
+    myMap1(NULL),
+    myMap2(NULL),
+    myLBox1(NULL),
+    myLBox2(NULL),
+    myIsBreak(NULL),
+    myIsDone(NULL),
+    myDistRef(NULL),
+    myEps(Precision::Confusion()),
+    myMutex(NULL)
+  {
+  }
+
+  DistanceTask& DistanceTask::operator =(const DistanceTask& theCopy)
+  {
+    myArray = theCopy.myArray;
+    mySolutionsShape1 = theCopy.mySolutionsShape1;
+    mySolutionsShape2 = theCopy.mySolutionsShape2;
+    myMap1 = theCopy.myMap1;
+    myMap2 = theCopy.myMap2;
+    myLBox1 = theCopy.myLBox1;
+    myLBox2 = theCopy.myLBox2;
+    myRange = theCopy.myRange;
+    myIsBreak = theCopy.myIsBreak;
+    myIsDone = theCopy.myIsDone;
+    myDistRef = theCopy.myDistRef;
+    myEps = theCopy.myEps;
+    myMutex = theCopy.myMutex;
+    return *this;
+  }
+
+  std::vector<BRepExtrema_SolutionElem>* mySolutionsShape1;
+  std::vector<BRepExtrema_SolutionElem>* mySolutionsShape2;
+  const NCollection_Array1<BRepExtrema_CheckPair>* myArray;
+  const TopTools_IndexedMapOfShape* myMap1;
+  const TopTools_IndexedMapOfShape* myMap2;
+  const std::vector<Bnd_Box>* myLBox1;
+  const std::vector<Bnd_Box>* myLBox2;
+  Message_ProgressRange myRange;
+  Standard_Boolean* myIsBreak;
+  Standard_Boolean* myIsDone;
+  Standard_Real* myDistRef;
+  Standard_Real myEps;
+  Handle(Standard_HMutex) myMutex;
+};
+
+//=======================================================================
+//struct   : DistanceFunctor
+//purpose  : 
+//=======================================================================
+struct DistanceFunctor
+{
+  void operator() (DistanceTask& theTask) const
+  {
+    Message_ProgressScope aDistScope(theTask.myRange, NULL, theTask.myArray->Size());
+    Standard_Real& anEps = theTask.myEps;
+    for (Standard_Integer i = 0; i < theTask.myArray->Size(); i++)
     {
-      const Bnd_Box& aBox1 = theLBox1.Value (anIdx1);
-      const Bnd_Box& aBox2 = theLBox2.Value (anIdx2);
-      if (aBox1.IsVoid()
-       || aBox2.IsVoid())
+      if (!aDistScope.More())
       {
-        continue;
+        Standard_Atomic_CompareAndSwap((int*) *theTask.myIsBreak, Standard_False, Standard_True);
+      }
+      aDistScope.Next();
+      if (*theTask.myIsBreak || *theTask.myIsDone)
+      {
+        break;
       }
 
-      const Standard_Real aDist = aBox1.Distance (aBox2);
-      if (aDist < myDistRef - myEps || fabs (aDist - myDistRef) < myEps)
+      const BRepExtrema_CheckPair& aPair = theTask.myArray->Value(i);
       {
-        aPairList.Append (BRepExtrema_CheckPair (anIdx1, anIdx2, aDist));
+        Standard_Mutex::Sentry aLock(theTask.myMutex.get());
+        //if (aPair.Distance > *theTask.myDistRef + anEps)
+        //{
+        //  *theTask.myIsDone = Standard_True;
+        //  break; // early search termination
+        //}
+      }
+
+      const Bnd_Box& aBox1 = theTask.myLBox1->at(aPair.Index1-1);
+      const Bnd_Box& aBox2 = theTask.myLBox2->at(aPair.Index2-1);
+
+      const TopoDS_Shape& aShape1 = theTask.myMap1->FindKey(aPair.Index1);
+      const TopoDS_Shape& aShape2 = theTask.myMap2->FindKey(aPair.Index2);
+
+      BRepExtrema_DistanceSS aDistTool(aShape1, aShape2, aBox1, aBox2, *theTask.myDistRef, anEps);
+      if (aDistTool.IsDone())
+      {
+        Standard_Mutex::Sentry aLock(theTask.myMutex.get());
+        if (aDistTool.DistValue() < *theTask.myDistRef - anEps)
+        {
+          theTask.mySolutionsShape1->clear();
+          theTask.mySolutionsShape2->clear();
+
+          const std::vector<BRepExtrema_SolutionElem>& aSeq1 = aDistTool.Seq1Value();
+          const std::vector<BRepExtrema_SolutionElem>& aSeq2 = aDistTool.Seq2Value();
+
+          theTask.mySolutionsShape1->insert(theTask.mySolutionsShape1->end(), aSeq1.begin(), aSeq1.end());
+          theTask.mySolutionsShape2->insert(theTask.mySolutionsShape2->end(), aSeq2.begin(), aSeq2.end());
+
+          *theTask.myDistRef = aDistTool.DistValue();
+        }
+        else if (fabs(aDistTool.DistValue() - *theTask.myDistRef) < anEps)
+        {
+          const std::vector<BRepExtrema_SolutionElem>& aSeq1 = aDistTool.Seq1Value();
+          const std::vector<BRepExtrema_SolutionElem>& aSeq2 = aDistTool.Seq2Value();
+
+          theTask.mySolutionsShape1->insert(theTask.mySolutionsShape1->end(), aSeq1.begin(), aSeq1.end());
+          theTask.mySolutionsShape2->insert(theTask.mySolutionsShape2->end(), aSeq2.begin(), aSeq2.end());
+
+          if (*theTask.myDistRef > aDistTool.DistValue())
+          {
+            *theTask.myDistRef = aDistTool.DistValue();
+          }
+        }
       }
     }
   }
+};
 
-  std::stable_sort(aPairList.begin(), aPairList.end(), BRepExtrema_CheckPair_Comparator);
-  Message_ProgressRange aDistRange(aTwinScope.Next());
-  Message_ProgressScope aDistScope(aDistRange, NULL, aPairList.Size());
-  for (NCollection_Vector<BRepExtrema_CheckPair>::Iterator aPairIter (aPairList);
-       aPairIter.More(); aPairIter.Next())
+//=======================================================================
+//struct   : DistancePairTask
+//purpose  : 
+//=======================================================================
+struct DistancePairTask
+{
+  DistancePairTask(Standard_Integer theFirtsIndex,
+                   Standard_Integer theLastIndex,
+                   NCollection_Vector<BRepExtrema_CheckPair>* thePairList,
+                   const TopTools_IndexedMapOfShape* theMap1,
+                   const TopTools_IndexedMapOfShape* theMap2,
+                   const std::vector<Bnd_Box>* theLBox1,
+                   const std::vector<Bnd_Box>* theLBox2,
+                   const Message_ProgressRange theRange,
+                   Standard_Boolean* theIsBreak,
+                   Standard_Real theDistRef,
+                   Standard_Real theEps,
+                   Handle(Standard_HMutex) theMutex)
+    : myFirtsIndex(theFirtsIndex),
+    myLastIndex(theLastIndex),
+    myPairList(thePairList),
+    myMap1(theMap1),
+    myMap2(theMap2),
+    myLBox1(theLBox1),
+    myLBox2(theLBox2),
+    myRange(theRange),
+    myIsBreak(theIsBreak),
+    myDistRef(theDistRef),
+    myEps(theEps),
+    myMutex(theMutex)
   {
-    aDistScope.Next();
-    if (!aDistScope.More())
-    {
-      throw StdFail_NotDone();
-    }
-    const BRepExtrema_CheckPair& aPair = aPairIter.Value();
-    if (aPair.Distance > myDistRef + myEps)
+  }
+
+  DistancePairTask()
+    : myFirtsIndex(0),
+    myLastIndex(0), 
+    myPairList(NULL),
+    myMap1(NULL),
+    myMap2(NULL),
+    myLBox1(NULL),
+    myLBox2(NULL),
+    myIsBreak(NULL),
+    myDistRef(0),
+    myEps(Precision::Confusion()),
+    myMutex(NULL)
+  {
+  }
+
+  DistancePairTask& DistancePairTask::operator =(const DistancePairTask& theCopy)
+  {
+    myFirtsIndex = theCopy.myFirtsIndex;
+    myLastIndex = theCopy.myLastIndex;
+    myPairList = theCopy.myPairList;
+    myMap1 = theCopy.myMap1;
+    myMap2 = theCopy.myMap2;
+    myLBox1 = theCopy.myLBox1;
+    myLBox2 = theCopy.myLBox2;
+    myRange = theCopy.myRange;
+    myIsBreak = theCopy.myIsBreak;
+    myDistRef = theCopy.myDistRef;
+    myEps = theCopy.myEps;
+    myMutex = theCopy.myMutex;
+    return *this;
+  }
+
+  Standard_Integer myFirtsIndex;
+  Standard_Integer myLastIndex;
+  NCollection_Vector<BRepExtrema_CheckPair>* myPairList;
+  const TopTools_IndexedMapOfShape* myMap1;
+  const TopTools_IndexedMapOfShape* myMap2;
+  const std::vector<Bnd_Box>* myLBox1;
+  const std::vector<Bnd_Box>* myLBox2;
+  Message_ProgressRange myRange;
+  Standard_Boolean* myIsBreak;
+  Standard_Real myDistRef;
+  Standard_Real myEps;
+  Handle(Standard_HMutex) myMutex;
+};
+
+//=======================================================================
+//struct   : DistancePairFunctor
+//purpose  : 
+//=======================================================================
+struct DistancePairFunctor
+{
+  void operator() (DistancePairTask& theTask) const
+  {
+    const Standard_Integer aCount1 = theTask.myMap1->Extent();
+    const Standard_Integer aCount2 = theTask.myMap2->Extent();
+    Message_ProgressScope aScope(theTask.myRange, NULL, theTask.myLastIndex - theTask.myFirtsIndex);
+    Standard_Real anEpsDist = theTask.myDistRef - theTask.myEps;
+
+    for (Standard_Integer anIdx1 = theTask.myFirtsIndex; anIdx1 <= theTask.myLastIndex; ++anIdx1)
     {
-      break; // early search termination
+      if (!aScope.More())
+      {
+        Standard_Atomic_CompareAndSwap((int*) *theTask.myIsBreak, Standard_False, Standard_True);
+      }
+      aScope.Next();
+      if (*theTask.myIsBreak)
+      {
+        break;
+      }
+
+      for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
+      {
+        const Bnd_Box& aBox1 = theTask.myLBox1->at(anIdx1 - 1);
+        const Bnd_Box& aBox2 = theTask.myLBox2->at(anIdx2 - 1);
+        if (aBox1.IsVoid() || aBox2.IsVoid())
+        {
+          continue;
+        }
+
+        const Standard_Real aDist = aBox1.Distance(aBox2);
+        if (aDist < anEpsDist || fabs(aDist - theTask.myDistRef) < theTask.myEps)
+        {
+          Standard_Mutex::Sentry aLock(theTask.myMutex.get());
+          theTask.myPairList->Append(BRepExtrema_CheckPair(anIdx1, anIdx2, aDist));
+        }
+      }
     }
+  }
+};
 
-    const Bnd_Box& aBox1 = theLBox1.Value (aPair.Index1);
-    const Bnd_Box& aBox2 = theLBox2.Value (aPair.Index2);
+//=======================================================================
+//function : DistanceMapMap
+//purpose  : 
+//=======================================================================
 
-    const TopoDS_Shape& aShape1 = theMap1 (aPair.Index1);
-    const TopoDS_Shape& aShape2 = theMap2 (aPair.Index2);
+void BRepExtrema_DistShapeShape::DistanceMapMap (const TopTools_IndexedMapOfShape& theMap1,
+                                                 const TopTools_IndexedMapOfShape& theMap2,
+                                                 const std::vector<Bnd_Box>&       theLBox1,
+                                                 const std::vector<Bnd_Box>&       theLBox2,
+                                                 const Message_ProgressRange&      theRange)
+{
+  NCollection_Vector<BRepExtrema_CheckPair> aPairList;
+  Message_ProgressScope aTwinScope(theRange, NULL, 2);
 
-    BRepExtrema_DistanceSS aDistTool (aShape1, aShape2, aBox1, aBox2, myDistRef, myEps);
-    if (aDistTool.IsDone())
+
+  const Standard_Integer aCount1 = theMap1.Extent();
+  const Standard_Integer aCount2 = theMap2.Extent();
+
+
+  if (myMutex.IsNull())
+  {
+  Message_ProgressRange aBoxRange(aTwinScope.Next());
+    Message_ProgressScope aBoxScope(aBoxRange, NULL, aCount1);
+
+    for (Standard_Integer anIdx1 = 1; anIdx1 <= aCount1; ++anIdx1)
     {
-      if (aDistTool.DistValue() < myDistRef - myEps)
+      aBoxScope.Next();
+      if (!aBoxScope.More())
+      {
+        throw StdFail_NotDone();
+      }
+      for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
       {
-        mySolutionsShape1.Clear();
-        mySolutionsShape2.Clear();
+        const Bnd_Box& aBox1 = theLBox1[anIdx1-1];
+        const Bnd_Box& aBox2 = theLBox2[anIdx2-1];
+        if (aBox1.IsVoid() || aBox2.IsVoid())
+        {
+          continue;
+        }
 
-        BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
-        BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
+        const Standard_Real aDist = aBox1.Distance (aBox2);
+        if (aDist < myDistRef - myEps || fabs (aDist - myDistRef) < myEps)
+        {
+          aPairList.Append (BRepExtrema_CheckPair (anIdx1, anIdx2, aDist));
+        }
+      }
+    }
+  }
+  else
+  {
+    const Standard_Integer aMinTaskSize = 10;
+    const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
+    const Standard_Integer aNbThreads = aThreadPool->NbThreads();
+    Standard_Integer aNbTasks = aNbThreads * 10;
+    Standard_Integer aTaskSize = (Standard_Integer) Ceiling((double) aCount1 / aNbTasks);
+    if (aTaskSize < aMinTaskSize)
+    {
+      aTaskSize = aMinTaskSize;
+      aNbTasks = (Standard_Integer) Ceiling((double) aCount1 / aTaskSize);
+    }
 
-        mySolutionsShape1.Append (aSeq1);
-        mySolutionsShape2.Append (aSeq2);
+    Standard_Integer aFirstIndex(1);
+    NCollection_Array1<DistancePairTask> aTaskArray(0, aNbTasks - 1);
+    Message_ProgressRange aBoxRange(aTwinScope.Next());
+    Message_ProgressScope aDistScope(aBoxRange, NULL, aNbTasks);
+    for (Standard_Integer anI = 0; anI < aTaskArray.Size(); ++anI)
+    {
+      if (aCount1 < aFirstIndex + aTaskSize - 1)
+      {
+        aTaskSize = aCount1 - aFirstIndex + 1;
+      }
+      DistancePairTask aTask(aFirstIndex, aFirstIndex + aTaskSize-1,
+                             &aPairList, &theMap1, &theMap2, &theLBox1, &theLBox2,
+                             aDistScope.Next(), &myIsBreak, myDistRef, myEps, myMutex);
+      aTaskArray.SetValue(anI, aTask);
+      aFirstIndex += aTaskSize;
+    }
+    OSD_Parallel::ForEach(aTaskArray.begin(), aTaskArray.end(), DistancePairFunctor(), Standard_False);
+
+    if (myIsBreak)
+    {
+      throw StdFail_NotDone();
+    }
+  }
+
+  if (myMutex.IsNull())
+  {
+    std::stable_sort(aPairList.begin(), aPairList.end(), BRepExtrema_CheckPair_Comparator);
+  }
 
-        myDistRef = aDistTool.DistValue();
+  if (myMutex.IsNull())
+  {
+    Message_ProgressRange aDistRange(aTwinScope.Next());
+    Message_ProgressScope aDistScope(aDistRange, NULL, aPairList.Size());
+    for (NCollection_Vector<BRepExtrema_CheckPair>::Iterator aPairIter(aPairList);
+         aPairIter.More(); aPairIter.Next())
+    {
+      aDistScope.Next();
+      if (!aDistScope.More())
+      {
+        throw StdFail_NotDone();
       }
-      else if (fabs (aDistTool.DistValue() - myDistRef) < myEps)
+      const BRepExtrema_CheckPair& aPair = aPairIter.Value();
+      if (aPair.Distance > myDistRef + myEps)
       {
-        BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
-        BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
+        break; // early search termination
+      }
+
+      const Bnd_Box& aBox1 = theLBox1[aPair.Index1-1];
+      const Bnd_Box& aBox2 = theLBox2[aPair.Index2-1];
 
-        mySolutionsShape1.Append (aSeq1);
-        mySolutionsShape2.Append (aSeq2);
+      const TopoDS_Shape& aShape1 = theMap1(aPair.Index1);
+      const TopoDS_Shape& aShape2 = theMap2(aPair.Index2);
 
-        if (myDistRef > aDistTool.DistValue())
+      BRepExtrema_DistanceSS aDistTool(aShape1, aShape2, aBox1, aBox2, myDistRef, myEps);
+      if (aDistTool.IsDone())
+      {
+        if (aDistTool.DistValue() < myDistRef - myEps)
         {
+          mySolutionsShape1.clear();
+          mySolutionsShape2.clear();
+
+          const std::vector<BRepExtrema_SolutionElem>& aSeq1 = aDistTool.Seq1Value();
+          const std::vector<BRepExtrema_SolutionElem>& aSeq2 = aDistTool.Seq2Value();
+
+          mySolutionsShape1.insert(mySolutionsShape1.end(), aSeq1.begin(), aSeq1.end());
+          mySolutionsShape2.insert(mySolutionsShape2.end(), aSeq2.begin(), aSeq2.end());
+
           myDistRef = aDistTool.DistValue();
         }
+        else if (fabs(aDistTool.DistValue() - myDistRef) < myEps)
+        {
+          const std::vector<BRepExtrema_SolutionElem>& aSeq1 = aDistTool.Seq1Value();
+          const std::vector<BRepExtrema_SolutionElem>& aSeq2 = aDistTool.Seq2Value();
+
+          mySolutionsShape1.insert(mySolutionsShape1.end(), aSeq1.begin(), aSeq1.end());
+          mySolutionsShape2.insert(mySolutionsShape2.end(), aSeq2.begin(), aSeq2.end());
+
+          if (myDistRef > aDistTool.DistValue())
+          {
+            myDistRef = aDistTool.DistValue();
+          }
+        }
+      }
+    }
+  }
+  else
+  {
+    const Standard_Integer aMapSize = aPairList.Size();
+    if (aMapSize)
+    {
+      const Standard_Integer aMinTaskSize = 2;
+      const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
+      const Standard_Integer aNbThreads = aThreadPool->NbThreads();
+      Standard_Integer aNbTasks = aNbThreads * 10;
+      Standard_Integer aTaskSize = (Standard_Integer) Ceiling((double) aMapSize / aNbTasks);
+      if (aTaskSize < aMinTaskSize)
+      {
+        aTaskSize = aMinTaskSize;
+        aNbTasks = (Standard_Integer) Ceiling((double) aMapSize / aTaskSize);
+      }
+
+      NCollection_Array1< NCollection_Array1<BRepExtrema_CheckPair> > anArrayOfArray(0, aNbTasks - 1);
+      for (Standard_Integer anI = 0; anI < aMapSize; ++anI)
+      {
+        Standard_Integer aVectIndex = anI / aTaskSize;
+        Standard_Integer aShapeIndex = anI % aTaskSize;
+        if (aShapeIndex == 0)
+        {
+          Standard_Integer aVectorSize = aTaskSize;
+          Standard_Integer aTailSize = aMapSize - aVectIndex * aTaskSize;
+          if (aTailSize < aTaskSize)
+          {
+            aVectorSize = aTailSize;
+          }
+          anArrayOfArray[aVectIndex].Resize(0, aVectorSize - 1, Standard_False);
+        }
+        anArrayOfArray[aVectIndex][aShapeIndex] = aPairList(anI);
+      }
+
+      NCollection_Array1<DistanceTask> aTaskArray(0, aNbTasks - 1);
+      Message_ProgressRange aDistRange(aTwinScope.Next());
+      Message_ProgressScope aDistScope(aDistRange, NULL, aNbTasks);
+      for (Standard_Integer anI = 0; anI < aTaskArray.Size(); ++anI)
+      {
+        DistanceTask aTask(&anArrayOfArray[anI], &mySolutionsShape1, &mySolutionsShape2,
+                           &theMap1, &theMap2, &theLBox1, &theLBox2, aDistScope.Next(),
+                           &myIsBreak, &myIsDone, &myDistRef, myEps, myMutex);
+        aTaskArray.SetValue(anI, aTask);
+      }
+
+      OSD_Parallel::ForEach(aTaskArray.begin(), aTaskArray.end(), DistanceFunctor(), Standard_False);
+
+      if (myIsBreak)
+      {
+        throw StdFail_NotDone();
       }
     }
   }
@@ -217,7 +871,9 @@ BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape()
   myIsInitS1 (Standard_False),
   myIsInitS2 (Standard_False),
   myFlag (Extrema_ExtFlag_MINMAX),
-  myAlgo (Extrema_ExtAlgo_Grad)
+  myAlgo (Extrema_ExtAlgo_Grad),
+  myIsBreak(Standard_False),
+  myMutex(NULL)
 {
   //
 }
@@ -230,7 +886,8 @@ BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape
                                                        const TopoDS_Shape& Shape2,
                                                        const Extrema_ExtFlag F,
                                                        const Extrema_ExtAlgo A,
-                                                       const Message_ProgressRange& theRange)
+                                                       const Message_ProgressRange& theRange,
+                                                       const Standard_Boolean theIsMultiThread)
 : myDistRef (0.0),
   myIsDone (Standard_False),
   myInnerSol (Standard_False),
@@ -238,11 +895,13 @@ BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape
   myIsInitS1 (Standard_False),
   myIsInitS2 (Standard_False),
   myFlag (F),
-  myAlgo (A)
+  myAlgo (A),
+  myIsBreak(Standard_False),
+  myMutex(NULL)
 {
   LoadS1(Shape1);
   LoadS2(Shape2);
-  Perform(theRange);
+  Perform(theRange, theIsMultiThread);
 }
 
 //=======================================================================
@@ -255,7 +914,8 @@ BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape
                                                        const Standard_Real theDeflection,
                                                        const Extrema_ExtFlag F,
                                                        const Extrema_ExtAlgo A,
-                                                       const Message_ProgressRange& theRange)
+                                                       const Message_ProgressRange& theRange,
+                                                       const Standard_Boolean theIsMultiThread)
 : myDistRef (0.0),
   myIsDone (Standard_False),
   myInnerSol (Standard_False),
@@ -263,11 +923,13 @@ BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape
   myIsInitS1 (Standard_False),
   myIsInitS2 (Standard_False),
   myFlag (F),
-  myAlgo (A)
+  myAlgo (A),
+  myIsBreak(Standard_False),
+  myMutex(NULL)
 {
   LoadS1(Shape1);
   LoadS2(Shape2);
-  Perform(theRange);
+  Perform(theRange, theIsMultiThread);
 }
 
 //=======================================================================
@@ -295,24 +957,24 @@ void BRepExtrema_DistShapeShape::LoadS2 (const TopoDS_Shape& Shape2)
 }
 
 //=======================================================================
-//function : SolidTreatment
+//function : SolidTreatmentOne
 //purpose  : 
 //=======================================================================
-void BRepExtrema_DistShapeShape::SolidTreatment(const TopoDS_Shape& theShape,
-                                                const TopTools_IndexedMapOfShape& theMap,
-                                                const Message_ProgressRange& theRange)
+void BRepExtrema_DistShapeShape::SolidTreatmentOne(const TopoDS_Shape& theShape,
+                                                   const TopTools_IndexedMapOfShape& theVertexMap,
+                                                   const Message_ProgressRange& theRange)
 {
   BRepClass3d_SolidClassifier aClassifier(theShape);
   const Standard_Real aTolerance = 0.001;
-  Message_ProgressScope aScope(theRange, NULL, theMap.Extent());
-  for (Standard_Integer i = 1; i < theMap.Extent(); ++i)
+  Message_ProgressScope aScope(theRange, NULL, theVertexMap.Extent());
+  for (Standard_Integer i = 1; i < theVertexMap.Extent(); ++i)
   {
-    aScope.Next();
+    Message_ProgressRange aRange = aScope.Next();
     if (!aScope.More())
     {
       throw StdFail_NotDone();
     }
-    const TopoDS_Vertex& aVertex = TopoDS::Vertex(theMap(i));
+    const TopoDS_Vertex& aVertex = TopoDS::Vertex(theVertexMap(i));
     const gp_Pnt& aPnt = BRep_Tool::Pnt(aVertex);
     aClassifier.Perform(aPnt, aTolerance);
     if (aClassifier.State() == TopAbs_IN)
@@ -321,24 +983,202 @@ void BRepExtrema_DistShapeShape::SolidTreatment(const TopoDS_Shape& theShape,
       myDistRef = 0.;
       myIsDone = Standard_True;
       BRepExtrema_SolutionElem Sol(0, aPnt, BRepExtrema_IsVertex, aVertex);
-      mySolutionsShape1.Append(Sol);
-      mySolutionsShape2.Append(Sol);
+      mySolutionsShape1.push_back(Sol);
+      mySolutionsShape2.push_back(Sol);
       break;
     }
   }
 }
 
+//=======================================================================
+//struct   : TreatmentTask
+//purpose  : 
+//=======================================================================
+struct TreatmentTask
+{
+  TreatmentTask(const TopoDS_Shape* theShape,
+                const NCollection_Array1<TopoDS_Shape>* theArray,
+                const Message_ProgressRange theRange,
+                Standard_Boolean*  theIsBreak,
+                Standard_Boolean* theInnerSol,
+                Standard_Boolean* theIsDone)
+: myShape(theShape),
+  myArray(theArray), 
+  myRange(theRange),
+  myIsBreak(theIsBreak),
+  myInnerSol(theInnerSol),
+  myIsDone(theIsDone)
+  {
+  }
+
+  TreatmentTask()
+: myShape(NULL),
+  myArray(NULL),
+  myIsBreak(NULL),
+  myInnerSol(NULL),
+  myIsDone(NULL)
+  {
+  }
+
+  TreatmentTask& TreatmentTask::operator =(const TreatmentTask& theCopy)
+  {
+    myShape = theCopy.myShape;
+    myArray = theCopy.myArray;
+    myRange = theCopy.myRange;
+    myIsBreak  = theCopy.myIsBreak;
+    myInnerSol = theCopy.myInnerSol;
+    myIsDone   = theCopy.myIsDone;
+    return *this;
+  }
+
+  std::vector<BRepExtrema_SolutionElem> mySolutionsShape;
+  const TopoDS_Shape* myShape;
+  const NCollection_Array1<TopoDS_Shape>* myArray;
+  Message_ProgressRange myRange;
+  Standard_Boolean* myIsBreak;
+  Standard_Boolean* myInnerSol;
+  Standard_Boolean* myIsDone;
+};
+
+//=======================================================================
+//struct   : TreatmentFunctor
+//purpose  : 
+//=======================================================================
+struct TreatmentFunctor
+{
+  void operator() (TreatmentTask& theTask) const
+  {
+    const Standard_Real aTolerance = 0.001;
+    Message_ProgressScope aScope(theTask.myRange, NULL, theTask.myArray->Size());
+    BRepClass3d_SolidClassifier aClassifier(*theTask.myShape);
+
+    for (Standard_Integer i = 0; i < theTask.myArray->Size(); i++)
+    {
+      if (!aScope.More())
+      {
+        Standard_Atomic_CompareAndSwap((int*) *theTask.myIsBreak, Standard_False, Standard_True);
+      }
+      Message_ProgressRange aRange = aScope.Next();
+      if (*theTask.myIsBreak || *theTask.myIsDone)
+      {
+        break;
+      }
+
+      const TopoDS_Vertex& aVertex = TopoDS::Vertex(theTask.myArray->Value(i));
+      const gp_Pnt& aPnt = BRep_Tool::Pnt(aVertex);
+      aClassifier.Perform(aPnt, aTolerance);
+      if (aClassifier.State() == TopAbs_IN)
+      {
+        Standard_Atomic_CompareAndSwap((int*) *theTask.myInnerSol, Standard_False, Standard_True);
+        Standard_Atomic_CompareAndSwap((int*) *theTask.myIsDone, Standard_False, Standard_True);
+        BRepExtrema_SolutionElem aSolElem(0, aPnt, BRepExtrema_IsVertex, aVertex);
+        theTask.mySolutionsShape.push_back(aSolElem);
+        break;
+      }
+    }
+  }
+};
+
+//=======================================================================
+//function : SolidTreatmentMulty
+//purpose  : 
+//=======================================================================
+void BRepExtrema_DistShapeShape::SolidTreatmentMulty(const TopoDS_Shape& theShape,
+                                                     const TopTools_IndexedMapOfShape& theVertexMap,
+                                                     const Message_ProgressRange& theRange)
+{
+  const Standard_Integer aMapSize = theVertexMap.Extent();
+  const Standard_Integer aMinTaskSize = 3;
+  const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
+  const Standard_Integer aNbThreads = aThreadPool->NbThreads();
+  Standard_Integer aNbTasks = aNbThreads * 10;
+  Standard_Integer aTaskSize = (Standard_Integer) Ceiling((double) aMapSize / aNbTasks);
+  if (aTaskSize < aMinTaskSize)
+  {
+    aTaskSize = aMinTaskSize;
+    aNbTasks = (Standard_Integer) Ceiling((double) aMapSize / aTaskSize);
+  }
+
+  NCollection_Array1< NCollection_Array1<TopoDS_Shape> > anArrayOfArray(0, aNbTasks - 1);
+  for (Standard_Integer anI = 1; anI <= aMapSize; ++anI)
+  {
+    Standard_Integer aVectIndex  = (anI - 1) / aTaskSize;
+    Standard_Integer aShapeIndex = (anI - 1) % aTaskSize;
+    if (aShapeIndex == 0)
+    {
+      Standard_Integer aVectorSize = aTaskSize;
+      Standard_Integer aTailSize = aMapSize - aVectIndex * aTaskSize;
+      if (aTailSize < aTaskSize)
+      {
+        aVectorSize = aTailSize;
+      }
+      anArrayOfArray[aVectIndex].Resize(0, aVectorSize - 1, Standard_False);
+    }
+    anArrayOfArray[aVectIndex][aShapeIndex] = theVertexMap(anI);
+  }
+
+  NCollection_Array1<TreatmentTask> aTaskArray(0, aNbTasks - 1);
+  Message_ProgressScope aScope(theRange, "Solid treatment", aNbTasks);
+  for (Standard_Integer anI = 0; anI < aTaskArray.Size(); ++anI)
+  {
+    TreatmentTask aTask(&theShape, &anArrayOfArray[anI], aScope.Next(), &myIsBreak, &myInnerSol, &myIsDone);
+    aTaskArray.SetValue(anI, aTask);
+  }
+
+  OSD_Parallel::ForEach(aTaskArray.begin(), aTaskArray.end(), TreatmentFunctor(), Standard_False);
+
+  if (myIsBreak)
+  {
+    throw StdFail_NotDone();
+  }
+
+  if (myInnerSol)
+  {
+    myDistRef = 0.;
+    if (aTaskArray.Size())
+    {
+      mySolutionsShape1.push_back(aTaskArray[0].mySolutionsShape[0]);
+      mySolutionsShape2.push_back(aTaskArray[0].mySolutionsShape[0]);
+    }
+  }
+
+}
+//=======================================================================
+//function : SolidTreatment
+//purpose  : 
+//=======================================================================
+void BRepExtrema_DistShapeShape::SolidTreatment(const TopoDS_Shape& theShape,
+                                                const TopTools_IndexedMapOfShape& theVertexMap,
+                                                const Message_ProgressRange& theRange,
+                                                const Standard_Boolean theIsMultiThread)
+{
+  if (theIsMultiThread)
+  {
+    SolidTreatmentMulty(theShape, theVertexMap, theRange);
+  }
+  else
+  {
+    SolidTreatmentOne(theShape, theVertexMap, theRange);
+  }
+}
+
+
+
 //=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean BRepExtrema_DistShapeShape::Perform(const Message_ProgressRange& theRange)
+Standard_Boolean BRepExtrema_DistShapeShape::Perform(const Message_ProgressRange& theRange,
+                                                     const Standard_Boolean theIsMultiThread)
 {
-  myIsDone=Standard_False;
-  myInnerSol=Standard_False;
-  mySolutionsShape1.Clear();
-  mySolutionsShape2.Clear();
+  CheckAndSetMutex(theIsMultiThread);
+
+  myIsDone   = Standard_False;
+  myInnerSol = Standard_False;
+  myIsBreak  = Standard_False;
+  mySolutionsShape1.clear();
+  mySolutionsShape2.clear();
 
   if ( myShape1.IsNull() || myShape2.IsNull() )
     return Standard_False;
@@ -356,21 +1196,21 @@ Standard_Boolean BRepExtrema_DistShapeShape::Perform(const Message_ProgressRange
   {
     if (anIsSolid1)
     {
-      SolidTreatment(myShape1, myMapV2, aRootScope.Next());
+      SolidTreatment(myShape1, myMapV2, aRootScope.Next(), theIsMultiThread);
     }
   
     if (anIsSolid2 && (!myInnerSol))
     {
-      SolidTreatment(myShape2, myMapV1, aRootScope.Next());
+      SolidTreatment(myShape2, myMapV1, aRootScope.Next(), theIsMultiThread);
     }
 
     if (!myInnerSol)
     {
       if (!myIsInitS1) // rebuild cached data for 1st shape
       {
-        myBV1.Clear();
-        myBE1.Clear();
-        myBF1.Clear();
+        myBV1.clear();
+        myBE1.clear();
+        myBF1.clear();
 
         BoxCalculation (myMapV1, myBV1);
         BoxCalculation (myMapE1, myBE1);
@@ -381,9 +1221,9 @@ Standard_Boolean BRepExtrema_DistShapeShape::Perform(const Message_ProgressRange
 
       if (!myIsInitS2) // rebuild cached data for 2nd shape
       {
-        myBV2.Clear();
-        myBE2.Clear();
-        myBF2.Clear();
+        myBV2.clear();
+        myBE2.clear();
+        myBF2.clear();
 
         BoxCalculation (myMapV2, myBV2);
         BoxCalculation (myMapE2, myBE2);
@@ -401,7 +1241,7 @@ Standard_Boolean BRepExtrema_DistShapeShape::Perform(const Message_ProgressRange
       else
         myDistRef= 1.e30; //szv:!!!
 
-      DistanceMapMap (myMapV1, myMapV2, myBV1, myBV2, aRootScope.Next());
+      DistanceVertVert (myMapV1, myMapV2, myBV1, myBV2, aRootScope.Next());
       DistanceMapMap (myMapV1, myMapE2, myBV1, myBE2, aRootScope.Next());
       DistanceMapMap (myMapE1, myMapV2, myBE1, myBV2, aRootScope.Next());
       DistanceMapMap (myMapV1, myMapF2, myBV1, myBF2, aRootScope.Next());
@@ -412,19 +1252,22 @@ Standard_Boolean BRepExtrema_DistShapeShape::Perform(const Message_ProgressRange
 
       if (fabs (myDistRef) > myEps)
       {
-        DistanceMapMap (myMapF1, myMapF2, myBF1, myBF2, aRootScope.Next());
+          DistanceMapMap (myMapF1, myMapF2, myBF1, myBF2, aRootScope.Next());
       }
     
-      //  Modified by Sergey KHROMOV - Tue Mar  6 11:55:03 2001 Begin
-      Standard_Integer i = 1;
-      for (; i <= mySolutionsShape1.Length(); i++)
-        if (mySolutionsShape1.Value(i).Dist() > myDistRef + myEps)
+      for (std::vector<BRepExtrema_SolutionElem>::iterator it = mySolutionsShape1.begin();
+           it != mySolutionsShape1.end(); )
+      {
+        if ((*it).Dist() > myDistRef + myEps)
         {
-          mySolutionsShape1.Remove(i);
-          mySolutionsShape2.Remove(i);
+          it = mySolutionsShape1.erase(it);
         }
-      //  Modified by Sergey KHROMOV - Tue Mar  6 11:55:04 2001 End
-      myIsDone = ( mySolutionsShape1.Length() > 0 );
+        else
+        {
+          ++it;
+        }
+      }
+      myIsDone = ( mySolutionsShape1.size() > 0 );
     }
   }
   catch (StdFail_NotDone)
@@ -458,7 +1301,7 @@ TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape1(const Standard_Integer
   if (!myIsDone)
     throw StdFail_NotDone("BRepExtrema_DistShapeShape::SupportOnShape1: There's no solution ");
 
-  const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
+  const BRepExtrema_SolutionElem &sol = mySolutionsShape1[N-1];
   switch (sol.SupportKind())
   {
     case BRepExtrema_IsVertex : return sol.Vertex();
@@ -478,7 +1321,7 @@ TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape2(const Standard_Integer
   if (!myIsDone)
     throw StdFail_NotDone("BRepExtrema_DistShapeShape::SupportOnShape2: There's no solution ");
 
-  const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
+  const BRepExtrema_SolutionElem &sol = mySolutionsShape2[N-1];
   switch (sol.SupportKind())
   {
     case BRepExtrema_IsVertex : return sol.Vertex();
@@ -498,7 +1341,7 @@ void BRepExtrema_DistShapeShape::ParOnEdgeS1(const Standard_Integer N, Standard_
   if (!myIsDone)
     throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnEdgeS1: There's no solution");
 
-  const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
+  const BRepExtrema_SolutionElem &sol = mySolutionsShape1[N-1];
   if (sol.SupportKind() != BRepExtrema_IsOnEdge)
     throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnEdgeS1: ParOnEdgeS1 is impossible without EDGE");
 
@@ -515,7 +1358,7 @@ void BRepExtrema_DistShapeShape::ParOnEdgeS2(const Standard_Integer N,  Standard
   if (!myIsDone)
     throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnEdgeS2: There's no solution");
 
-  const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
+  const BRepExtrema_SolutionElem &sol = mySolutionsShape2[N-1];
   if (sol.SupportKind() != BRepExtrema_IsOnEdge)
     throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnEdgeS2: ParOnEdgeS2 is impossible without EDGE");
  
@@ -532,7 +1375,7 @@ void BRepExtrema_DistShapeShape::ParOnFaceS1(const Standard_Integer N,  Standard
   if (!myIsDone)
     throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnFaceS1: There's no solution");
 
-  const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
+  const BRepExtrema_SolutionElem &sol = mySolutionsShape1[N-1];
   if (sol.SupportKind() != BRepExtrema_IsInFace)
     throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnFaceS1: ParOnFaceS1 is impossible without FACE");
   
@@ -549,7 +1392,7 @@ void BRepExtrema_DistShapeShape::ParOnFaceS2(const Standard_Integer N,  Standard
   if (!myIsDone)
     throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnFaceS2: There's no solution");
 
-  const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
+  const BRepExtrema_SolutionElem &sol = mySolutionsShape2[N-1];
   if (sol.SupportKind() != BRepExtrema_IsInFace)
     throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnFaceS2:ParOnFaceS2 is impossible without FACE ");
   
@@ -608,3 +1451,20 @@ void BRepExtrema_DistShapeShape::Dump(Standard_OStream& o) const
     o<<std::endl;
   } 
 }
+
+//=======================================================================
+//function : CheckAndSetMutex
+//purpose  : 
+//=======================================================================
+void BRepExtrema_DistShapeShape::CheckAndSetMutex(const Standard_Boolean theIsMultiThread)
+{
+  if (theIsMultiThread && myMutex.IsNull())
+  {
+    myMutex.reset(new Standard_HMutex());
+  }
+  else
+  {
+    myMutex = NULL;
+  }
+}
+
index 182ea6adfb3088a519f3a4cbe1aa9485a6ed6862..6ea8f39f5b97768baa380da7ca6c505345541ca2 100644 (file)
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <Standard_OStream.hxx>
 #include <Standard_DefineAlloc.hxx>
+#include <Standard_Mutex.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 
+#include <vector>
+
 //! This class  provides tools to compute minimum distance <br>
 //! between two Shapes (Compound,CompSolid, Solid, Shell, Face, Wire, Edge, Vertex). <br>
 class BRepExtrema_DistShapeShape
@@ -44,14 +47,16 @@ class BRepExtrema_DistShapeShape
                                              const TopoDS_Shape& Shape2,
                                              const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX,
                                              const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad,
-                                             const Message_ProgressRange& theRange = Message_ProgressRange());
+                                             const Message_ProgressRange& theRange = Message_ProgressRange(),
+                                             const Standard_Boolean theIsMultiThread = Standard_False);
   //! create tool and load both shapes into it <br>
   Standard_EXPORT BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
                                              const TopoDS_Shape& Shape2,
                                              const Standard_Real theDeflection,
                                              const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX,
                                              const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad,
-                                             const Message_ProgressRange& theRange = Message_ProgressRange());
+                                             const Message_ProgressRange& theRange = Message_ProgressRange(),
+                                             const Standard_Boolean theIsMultiThread = Standard_False);
   
   void SetDeflection(const Standard_Real theDeflection)
   {
@@ -67,7 +72,8 @@ class BRepExtrema_DistShapeShape
   //!          from the minimum one. <br>
   //!          Returns IsDone status. <br>
   //! theProgress - progress indicator of algorithm
-  Standard_EXPORT Standard_Boolean Perform(const Message_ProgressRange& theRange = Message_ProgressRange());
+  Standard_EXPORT Standard_Boolean Perform(const Message_ProgressRange& theRange = Message_ProgressRange(),
+                                           const Standard_Boolean theIsMultiThread = Standard_False);
   //! True if the minimum distance is found. <br>
   Standard_Boolean IsDone() const
   { 
@@ -76,7 +82,7 @@ class BRepExtrema_DistShapeShape
   //! Returns the number of solutions satisfying the minimum distance. <br>
   Standard_Integer NbSolution() const
   { 
-    return mySolutionsShape1.Length();
+    return (Standard_Integer) mySolutionsShape1.size();
   }
   //! Returns the value of the minimum distance. <br>
   Standard_EXPORT Standard_Real Value() const;
@@ -89,12 +95,12 @@ class BRepExtrema_DistShapeShape
   //! Returns the Point corresponding to the <N>th solution on the first Shape <br>
   const gp_Pnt & PointOnShape1(const Standard_Integer N) const
   { 
-    return mySolutionsShape1.Value(N).Point();
+    return mySolutionsShape1[N].Point();
   }
   //! Returns the Point corresponding to the <N>th solution on the second Shape <br>
   const gp_Pnt & PointOnShape2(const Standard_Integer N) const
   { 
-    return mySolutionsShape2.Value(N).Point();
+    return mySolutionsShape2[N].Point();
   }
   //! gives the type of the support where the Nth solution on the first shape is situated: <br>
   //!   IsVertex => the Nth solution on the first shape is a Vertex <br>
@@ -103,7 +109,7 @@ class BRepExtrema_DistShapeShape
   //! the corresponding support is obtained by the method SupportOnShape1 <br>
   BRepExtrema_SupportType SupportTypeShape1(const Standard_Integer N) const
   { 
-    return mySolutionsShape1.Value(N).SupportKind();
+    return mySolutionsShape1[N].SupportKind();
   }
   //! gives the type of the support where the Nth solution on the second shape is situated: <br>
   //!   IsVertex => the Nth solution on the second shape is a Vertex <br>
@@ -112,7 +118,7 @@ class BRepExtrema_DistShapeShape
   //! the corresponding support is obtained by the method SupportOnShape2 <br>
   BRepExtrema_SupportType SupportTypeShape2(const Standard_Integer N) const
   { 
-    return mySolutionsShape2.Value(N).SupportKind();
+    return mySolutionsShape2[N].SupportKind();
   }
   //! gives the support where the Nth solution on the first shape is situated. <br>
   //! This support can be a Vertex, an Edge or a Face. <br>
@@ -150,20 +156,37 @@ private:
   //! computes the minimum distance between two maps of shapes (Face,Edge,Vertex) <br>
   Standard_EXPORT void DistanceMapMap(const TopTools_IndexedMapOfShape& Map1,
                                       const TopTools_IndexedMapOfShape& Map2,
-                                      const Bnd_SeqOfBox&               LBox1,
-                                      const Bnd_SeqOfBox&               LBox2,
+                                      const std::vector<Bnd_Box>&       LBox1,
+                                      const std::vector<Bnd_Box>&       LBox2,
                                       const Message_ProgressRange&      theRange);
 
+  void DistanceVertVert(const TopTools_IndexedMapOfShape& theMap1,
+                        const TopTools_IndexedMapOfShape& theMap2,
+                        const std::vector<Bnd_Box>&       theLBox1,
+                        const std::vector<Bnd_Box>&       theLBox2,
+                        const Message_ProgressRange&      theRange);
+
   void SolidTreatment(const TopoDS_Shape& theShape,
                       const TopTools_IndexedMapOfShape& theMap,
-                      const Message_ProgressRange& theRange);
+                      const Message_ProgressRange& theRange,
+                      const Standard_Boolean theIsMultiThread);
+
+  void SolidTreatmentOne(const TopoDS_Shape& theShape,
+                         const TopTools_IndexedMapOfShape& theVertexMap,
+                         const Message_ProgressRange& theRange);
+
+  void SolidTreatmentMulty(const TopoDS_Shape& theShape,
+                           const TopTools_IndexedMapOfShape& theVertexMap,
+                           const Message_ProgressRange& theRange);
+
+  void CheckAndSetMutex(const Standard_Boolean theIsMultiThread);
 
 private:
 
   Standard_Real myDistRef;
   Standard_Boolean myIsDone;
-  BRepExtrema_SeqOfSolution mySolutionsShape1;
-  BRepExtrema_SeqOfSolution mySolutionsShape2;
+  std::vector<BRepExtrema_SolutionElem> mySolutionsShape1;
+  std::vector<BRepExtrema_SolutionElem> mySolutionsShape2;
   Standard_Boolean myInnerSol;
   Standard_Real myEps;
   TopoDS_Shape myShape1;
@@ -178,12 +201,15 @@ private:
   Standard_Boolean myIsInitS2;
   Extrema_ExtFlag myFlag;
   Extrema_ExtAlgo myAlgo;
-  Bnd_SeqOfBox myBV1;
-  Bnd_SeqOfBox myBV2;
-  Bnd_SeqOfBox myBE1;
-  Bnd_SeqOfBox myBE2;
-  Bnd_SeqOfBox myBF1;
-  Bnd_SeqOfBox myBF2;
+  std::vector<Bnd_Box> myBV1;
+  std::vector<Bnd_Box> myBV2;
+  std::vector<Bnd_Box> myBE1;
+  std::vector<Bnd_Box> myBE2;
+  std::vector<Bnd_Box> myBF1;
+  std::vector<Bnd_Box> myBF2;
+
+  Standard_Boolean myIsBreak;
+  mutable Handle(Standard_HMutex) myMutex;
 };
 
 #endif
index 61773dd80697ef634429d631194191cc6f58b3c3..0ae065e5d6f094f861f1433bcd33b01130bdc3a0 100644 (file)
 //------------------------------------------------------------------------------
 // function: TRI_SOLUTION
 //------------------------------------------------------------------------------
-static Standard_Boolean TRI_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol, const gp_Pnt& Pt)
+static Standard_Boolean TRI_SOLUTION (std::vector<BRepExtrema_SolutionElem>& SeqSol, const gp_Pnt& Pt)
 {
-  const Standard_Integer Nbsol = SeqSol.Length();
-  for (Standard_Integer i = 1; i <= Nbsol; i++)
+  for (size_t i = 0; i < SeqSol.size(); i++)
   {
-    const Standard_Real dst = SeqSol.Value(i).Point().Distance(Pt);
+    const Standard_Real dst = SeqSol[i].Point().Distance(Pt);
     if (dst <= Precision::Confusion()) return Standard_False;
   }
   return Standard_True;
@@ -76,22 +75,21 @@ static Standard_Boolean TRI_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol, c
 //------------------------------------------------------------------------------
 // function: MIN_SOLUTION
 //------------------------------------------------------------------------------
-static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
-                          const BRepExtrema_SeqOfSolution& SeqSol2,
+static void MIN_SOLUTION (const std::vector<BRepExtrema_SolutionElem>& SeqSol1,
+                          const std::vector<BRepExtrema_SolutionElem>& SeqSol2,
                           const Standard_Real DstRef,
                           const Standard_Real Eps,
-                          BRepExtrema_SeqOfSolution& seqSol1,
-                          BRepExtrema_SeqOfSolution& seqSol2)
+                          std::vector<BRepExtrema_SolutionElem>& seqSol1,
+                          std::vector<BRepExtrema_SolutionElem>& seqSol2)
 {
-  const Standard_Integer nbSol = SeqSol1.Length();
-  for (Standard_Integer i = 1; i <= nbSol; i++)
+  for (size_t i = 0; i < SeqSol1.size(); i++)
   {
-    const Standard_Real dst1 = SeqSol1.Value(i).Dist();
+    const Standard_Real dst1 = SeqSol1[i].Dist();
     if (fabs(dst1 - DstRef) < Eps)
-       {         
-      seqSol1.Append(SeqSol1.Value(i));
-      seqSol2.Append(SeqSol2.Value(i));
-       }
+         {       
+      seqSol1.push_back(SeqSol1[i]);
+      seqSol2.push_back(SeqSol2[i]);
+         }
   }
 }
 
@@ -392,8 +390,8 @@ static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
 // static function: PERFORM_C0
 //------------------------------------------------------------------------------
 static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
-                       BRepExtrema_SeqOfSolution& SeqSol1,
-                       BRepExtrema_SeqOfSolution& SeqSol2,
+                       std::vector<BRepExtrema_SolutionElem>& SeqSol1,
+                       std::vector<BRepExtrema_SolutionElem>& SeqSol2,
                        const Standard_Real DstRef,
                        Standard_Real& mDstRef,
                        const Standard_Real Eps)
@@ -479,8 +477,8 @@ static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
                       mDstRef=Dstmin;
                     const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
                     const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,Eother,t);
-                    SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
-                    SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
+                    SeqSol1.push_back(iE == 0 ? Sol1 : Sol2);
+                    SeqSol2.push_back(iE == 0 ? Sol2 : Sol1);
                   }
                 }
               }
@@ -497,8 +495,8 @@ static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
               mDstRef=Dst;
             const BRepExtrema_SolutionElem Sol1(Dst,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
             const BRepExtrema_SolutionElem Sol2(Dst,aPntOther,BRepExtrema_IsOnEdge,Eother,aParameterOther);
-            SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
-            SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
+            SeqSol1.push_back(iE == 0 ? Sol1 : Sol2);
+            SeqSol2.push_back(iE == 0 ? Sol2 : Sol1);
           }              
         }
       }
@@ -511,8 +509,8 @@ static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
 void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
                                      const Bnd_Box& B1, const Bnd_Box& B2)
 {
-  SeqSolShape1.Clear();
-  SeqSolShape2.Clear();
+  SeqSolShape1.clear();
+  SeqSolShape2.clear();
   myModif=Standard_False;
 
   switch (S1.ShapeType())
@@ -641,8 +639,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Verte
     myModif=Standard_True;
     const BRepExtrema_SolutionElem Sol1(Dst,P1,BRepExtrema_IsVertex,S1);
     const BRepExtrema_SolutionElem Sol2(Dst,P2,BRepExtrema_IsVertex,S2);
-    SeqSolShape1.Append(Sol1);
-    SeqSolShape2.Append(Sol2);
+    SeqSolShape1.push_back(Sol1);
+    SeqSolShape2.push_back(Sol2);
   }
 }
 
@@ -695,8 +693,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge&
                 myModif=Standard_True;
                 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
                 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,S2,t);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);
+                SeqSolShape1.push_back(Sol1);
+                SeqSolShape2.push_back(Sol2);
               }
             }
           }
@@ -753,8 +751,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1,const TopoDS_Vertex&
                 myModif=Standard_True;
                 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsOnEdge,S1,t);
                 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);
+                SeqSolShape1.push_back(Sol1);
+                SeqSolShape2.push_back(Sol2);
               }
             }
           }
@@ -811,8 +809,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face&
                 myModif=Standard_True;
                 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
                 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsInFace,S2,U,V);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);               
+                SeqSolShape1.push_back(Sol1);
+                SeqSolShape2.push_back(Sol2);
               }
             }
           }
@@ -867,8 +865,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex&
                 myModif=Standard_True;
                 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsInFace,S1,U,V);
                 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);               
+                SeqSolShape1.push_back(Sol1);
+                SeqSolShape2.push_back(Sol2);
               }
             }
           }
@@ -932,8 +930,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S
                 myModif=Standard_True;
                 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
                 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsOnEdge,S2,t2);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);
+                SeqSolShape1.push_back(Sol1);
+                SeqSolShape2.push_back(Sol2);
               }
             }
           }
@@ -941,21 +939,21 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S
       }
     }
 
-    BRepExtrema_SeqOfSolution SeqSolution1;
-    BRepExtrema_SeqOfSolution SeqSolution2;
+    std::vector<BRepExtrema_SolutionElem> SeqSolution1;
+    std::vector<BRepExtrema_SolutionElem> SeqSolution2;
 
     PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
      
-    BRepExtrema_SeqOfSolution seqSol1;
-    BRepExtrema_SeqOfSolution seqSol2;
+    std::vector<BRepExtrema_SolutionElem> seqSol1;
+    std::vector<BRepExtrema_SolutionElem> seqSol2;
        
-    if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
+    if (SeqSolution1.size() > 0 && SeqSolution2.size() > 0)
       MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
      
-    if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
+    if (!seqSol1.empty() && !seqSol2.empty())
     {
-      SeqSolShape1.Append(seqSol1);
-      SeqSolShape2.Append(seqSol2);    
+      SeqSolShape1.insert(SeqSolShape1.end(), seqSol1.begin(), seqSol1.end());
+      SeqSolShape2.insert(SeqSolShape2.end(), seqSol2.begin(), seqSol2.end());
       myModif = Standard_True;
     }
   }
@@ -1019,8 +1017,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
                   myModif=Standard_True;
                   const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
                   const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U,V);
-                  SeqSolShape1.Append(Sol1);
-                  SeqSolShape2.Append(Sol2);             
+                  SeqSolShape1.push_back(Sol1);
+                  SeqSolShape2.push_back(Sol2);                  
                 }
               }
             }
@@ -1033,8 +1031,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
     Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S1, aFirst, aLast);
     if (pCurv->Continuity() == GeomAbs_C0)
     {
-      BRepExtrema_SeqOfSolution SeqSolution1;
-      BRepExtrema_SeqOfSolution SeqSolution2;
+      std::vector<BRepExtrema_SolutionElem> SeqSolution1;
+      std::vector<BRepExtrema_SolutionElem> SeqSolution2;
 
       GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
       const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
@@ -1085,8 +1083,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
                   myModif=Standard_True;
                   const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,S1,aParameter);
                   const BRepExtrema_SolutionElem Sol2(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S2,U,V);
-                  SeqSolution1.Append(Sol1);
-                  SeqSolution2.Append(Sol2);
+                  SeqSolution1.push_back(Sol1);
+                  SeqSolution2.push_back(Sol2);
                 }
               }
             }
@@ -1094,15 +1092,15 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
         }
       }
 
-      BRepExtrema_SeqOfSolution seqSol1;
-      BRepExtrema_SeqOfSolution seqSol2;
-      if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
+      std::vector<BRepExtrema_SolutionElem> seqSol1;
+      std::vector<BRepExtrema_SolutionElem> seqSol2;
+      if (SeqSolution1.size() > 0 && SeqSolution2.size() > 0)
         MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
            
-      if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
+      if (!seqSol1.empty() && !seqSol2.empty())
       {
-        SeqSolShape1.Append(seqSol1);
-        SeqSolShape2.Append(seqSol2);
+        SeqSolShape1.insert(SeqSolShape1.end(), seqSol1.begin(), seqSol1.end());
+        SeqSolShape2.insert(SeqSolShape2.end(), seqSol2.begin(), seqSol2.end());
       }
     }
   }
@@ -1164,8 +1162,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
                   myModif=Standard_True;
                   const BRepExtrema_SolutionElem Sol2(Dstmin,Pt1,BRepExtrema_IsOnEdge,S2,t1);
                   const BRepExtrema_SolutionElem Sol1(Dstmin,Pt2,BRepExtrema_IsInFace,S1,U,V);
-                  SeqSolShape1.Append(Sol1);
-                  SeqSolShape2.Append(Sol2);             
+                  SeqSolShape1.push_back(Sol1);
+                  SeqSolShape2.push_back(Sol2);
                 }
               }
             }
@@ -1178,8 +1176,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
     Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S2, aFirst, aLast);
     if (pCurv->Continuity() == GeomAbs_C0)
     {
-      BRepExtrema_SeqOfSolution SeqSolution1;
-      BRepExtrema_SeqOfSolution SeqSolution2;
+      std::vector<BRepExtrema_SolutionElem> SeqSolution1;
+      std::vector<BRepExtrema_SolutionElem> SeqSolution2;
 
       GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
       const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
@@ -1230,8 +1228,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
                   myModif=Standard_True;
                   const BRepExtrema_SolutionElem Sol2(Dstmin,aPnt,BRepExtrema_IsOnEdge,S2,aParameter);
                   const BRepExtrema_SolutionElem Sol1(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S1,U,V);
-                  SeqSolution1.Append(Sol1);
-                  SeqSolution2.Append(Sol2);
+                  SeqSolution1.push_back(Sol1);
+                  SeqSolution2.push_back(Sol2);
                 }
               }
             }
@@ -1239,15 +1237,15 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
         }
       }
 
-      BRepExtrema_SeqOfSolution seqSol1;
-      BRepExtrema_SeqOfSolution seqSol2;
-      if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
+      std::vector<BRepExtrema_SolutionElem> seqSol1;
+      std::vector<BRepExtrema_SolutionElem> seqSol2;
+      if (SeqSolution1.size() > 0 && SeqSolution2.size() > 0)
         MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
            
-      if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
+      if (!seqSol1.empty() && !seqSol2.empty())
       {
-        SeqSolShape1.Append(seqSol1);
-        SeqSolShape2.Append(seqSol2);
+        SeqSolShape1.insert(SeqSolShape1.end(), seqSol1.begin(), seqSol1.end());
+        SeqSolShape2.insert(SeqSolShape2.end(), seqSol2.begin(), seqSol2.end());
       }
     }
   }
@@ -1309,8 +1307,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S
                   myModif=Standard_True;
                   const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsInFace,S1,U1,V1);
                   const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U2,V2);
-                  SeqSolShape1.Append(Sol1);
-                  SeqSolShape2.Append(Sol2);
+                  SeqSolShape1.push_back(Sol1);
+                  SeqSolShape2.push_back(Sol2);
                 }
               }
             }
index 1f7e6fc9e424ed5b55aadbd18fb056bd57062e5f..2b96597f92c05d61fcd0e5f5aaff7ded58525668 100644 (file)
@@ -20,6 +20,8 @@
 #include <Precision.hxx>
 #include <Standard_DefineAlloc.hxx>
 
+#include <vector>
+
 class TopoDS_Shape;
 class Bnd_Box;
 class TopoDS_Vertex;
@@ -69,12 +71,12 @@ class BRepExtrema_DistanceSS
     return myDstRef;
   }
   //! returns the list of solutions on the first shape <br>
-  const BRepExtrema_SeqOfSolution& Seq1Value() const
+  const std::vector<BRepExtrema_SolutionElem>& Seq1Value() const
   {
     return SeqSolShape1;
   }
   //! returns the list of solutions on the second shape <br>
-  const BRepExtrema_SeqOfSolution& Seq2Value() const
+  const std::vector<BRepExtrema_SolutionElem>& Seq2Value() const
   {
     return SeqSolShape2;
   }
@@ -124,8 +126,8 @@ class BRepExtrema_DistanceSS
   //! computes the minimum distance between two faces <br>
   void Perform(const TopoDS_Face& S1,const TopoDS_Face& S2,const Bnd_Box& B1,const Bnd_Box& B2);
 
-  BRepExtrema_SeqOfSolution SeqSolShape1;
-  BRepExtrema_SeqOfSolution SeqSolShape2;
+  std::vector<BRepExtrema_SolutionElem> SeqSolShape1;
+  std::vector<BRepExtrema_SolutionElem> SeqSolShape2;
   Standard_Real myDstRef;
   Standard_Boolean myModif;
   Standard_Real myEps;
index 0fa44321d1a1a1b80456a58e1286fedd08955a1b..7309769fab5c19a77de47ac6fd0a4e33a872a414 100644 (file)
@@ -64,19 +64,39 @@ static Standard_Integer distance (Draw_Interpretor& di,
 
 static Standard_Integer distmini(Draw_Interpretor& di, Standard_Integer n, const char** a)
 {
-  if (n != 4 && n != 5 )
+  if (n < 4 || n > 6)
+  {
     return 1;
+  }
 
   const char *ns1 = (a[2]), *ns2 = (a[3]), *ns0 = (a[1]);
   TopoDS_Shape S1(DBRep::Get(ns1)), S2(DBRep::Get(ns2));
 
   Standard_Real aDeflection = Precision::Confusion();
-  if (n == 5)
+  if (n >= 5 && strncmp(a[4], "-", 1))
+  {
     aDeflection = Draw::Atof(a[4]);
+  }
+
+  Standard_Boolean anIsMultiThread = Standard_False;
+  for (Standard_Integer anAI = 4; anAI < n; anAI++)
+  {
+    TCollection_AsciiString anArg(a[anAI]);
+    anArg.LowerCase();
+    if (anArg == "-parallel")
+    {
+      anIsMultiThread = Standard_True;
+    }
+    else
+    {
+      di << "Syntax error at '" << anArg << "'";
+      return 1;
+    }
+  }
 
   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
   BRepExtrema_DistShapeShape dst(S1 ,S2, aDeflection, Extrema_ExtFlag_MINMAX,
-                                 Extrema_ExtAlgo_Grad, aProgress->Start());
+                                 Extrema_ExtAlgo_Grad, aProgress->Start(), anIsMultiThread);
 
   if (dst.IsDone()) 
   { 
@@ -97,7 +117,7 @@ static Standard_Integer distmini(Draw_Interpretor& di, Standard_Integer n, const
     Draw::Set(tempd,dst.Value());
     di << named << " ";
 
-    for (Standard_Integer i1 = 1; i1<= dst.NbSolution(); i1++)
+    for (Standard_Integer i1 = 0; i1 < dst.NbSolution(); i1++)
     {
       gp_Pnt P1,P2;
       P1 = (dst.PointOnShape1(i1));
@@ -106,7 +126,7 @@ static Standard_Integer distmini(Draw_Interpretor& di, Standard_Integer n, const
       {
         TopoDS_Vertex V =BRepLib_MakeVertex(P1);
         char namev[100];
-        if (i1==1
+        if (i1==0
           Sprintf(namev, "%s" ,ns0);
         else
           Sprintf(namev, "%s%d" ,ns0,i1);
@@ -118,7 +138,7 @@ static Standard_Integer distmini(Draw_Interpretor& di, Standard_Integer n, const
       {
         char name[100];
         TopoDS_Edge E = BRepLib_MakeEdge (P1, P2);
-        if (i1==1)
+        if (i1==0)
         {
           Sprintf(name,"%s",ns0);
         }
@@ -412,7 +432,10 @@ void BRepTest::ExtremaCommands (Draw_Interpretor& theCommands)
                    aGroup);
 
   theCommands.Add ("distmini",
-                   "distmini name Shape1 Shape2 [deflection]",
+                   "distmini name Shape1 Shape2 [deflection] [-parallel]",
+                   "\n\t\t: Searches minimal distance between two shapes."
+                   "\n\t\t: The option is:"
+                   "\n\t\t:   -parallel : calculate distance in multithreaded mode"
                    __FILE__,
                    distmini,
                    aGroup);