From: asuraven Date: Wed, 18 Aug 2021 17:23:07 +0000 (+0300) Subject: 0032539: Modeling Algorithms - Parallelize BRepExtrema_DistShapeShape algorithm X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FCR32539_1;p=occt-copy.git 0032539: Modeling Algorithms - Parallelize BRepExtrema_DistShapeShape algorithm --- diff --git a/src/BRepCheck/BRepCheck_Analyzer.cxx b/src/BRepCheck/BRepCheck_Analyzer.cxx index 1e777665ce..3be4b24cfb 100644 --- a/src/BRepCheck/BRepCheck_Analyzer.cxx +++ b/src/BRepCheck/BRepCheck_Analyzer.cxx @@ -434,7 +434,7 @@ void BRepCheck_Analyzer::Perform (Standard_Boolean theIsParallel) aNbTasks = (Standard_Integer)Ceiling ((double)aMapSize / aTaskSize); } - NCollection_Array1< NCollection_Array1 > aArrayOfArray (0, aNbTasks - 1); + NCollection_Array1< NCollection_Array1 > 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); } //======================================================================= diff --git a/src/BRepExtrema/BRepExtrema_DistShapeShape.cxx b/src/BRepExtrema/BRepExtrema_DistShapeShape.cxx index b31ea7a783..4e062d8b84 100644 --- a/src/BRepExtrema/BRepExtrema_DistShapeShape.cxx +++ b/src/BRepExtrema/BRepExtrema_DistShapeShape.cxx @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include @@ -56,13 +58,13 @@ namespace } static void BoxCalculation(const TopTools_IndexedMapOfShape& Map, - Bnd_SeqOfBox& SBox) + std::vector& 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* theSolutionsShape1, + std::vector* theSolutionsShape2, + const TopTools_IndexedMapOfShape* theMap1, + const TopTools_IndexedMapOfShape* theMap2, + const std::vector* theLBox1, + const std::vector* 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* mySolutionsShape1; + std::vector* mySolutionsShape2; + const TopTools_IndexedMapOfShape* myMap1; + const TopTools_IndexedMapOfShape* myMap2; + const std::vector* myLBox1; + const std::vector* 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& aSeq1 = aDistTool.Seq1Value(); + const std::vector& 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& aSeq1 = aDistTool.Seq1Value(); + const std::vector& 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& theLBox1, + const std::vector& theLBox2, + const Message_ProgressRange& theRange) { - NCollection_Vector 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& aSeq1 = aDistTool.Seq1Value(); + const std::vector& 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& aSeq1 = aDistTool.Seq1Value(); + const std::vector& 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 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* theArray, + std::vector* theSolutionsShape1, + std::vector* theSolutionsShape2, + const TopTools_IndexedMapOfShape* theMap1, + const TopTools_IndexedMapOfShape* theMap2, + const std::vector* theLBox1, + const std::vector* 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* mySolutionsShape1; + std::vector* mySolutionsShape2; + const NCollection_Array1* myArray; + const TopTools_IndexedMapOfShape* myMap1; + const TopTools_IndexedMapOfShape* myMap2; + const std::vector* myLBox1; + const std::vector* 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& aSeq1 = aDistTool.Seq1Value(); + const std::vector& 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& aSeq1 = aDistTool.Seq1Value(); + const std::vector& 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::Iterator aPairIter (aPairList); - aPairIter.More(); aPairIter.Next()) +//======================================================================= +//struct : DistancePairTask +//purpose : +//======================================================================= +struct DistancePairTask +{ + DistancePairTask(Standard_Integer theFirtsIndex, + Standard_Integer theLastIndex, + NCollection_Vector* thePairList, + const TopTools_IndexedMapOfShape* theMap1, + const TopTools_IndexedMapOfShape* theMap2, + const std::vector* theLBox1, + const std::vector* 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* myPairList; + const TopTools_IndexedMapOfShape* myMap1; + const TopTools_IndexedMapOfShape* myMap2; + const std::vector* myLBox1; + const std::vector* 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& theLBox1, + const std::vector& theLBox2, + const Message_ProgressRange& theRange) +{ + NCollection_Vector 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 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::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& aSeq1 = aDistTool.Seq1Value(); + const std::vector& 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& aSeq1 = aDistTool.Seq1Value(); + const std::vector& 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 > 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 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* 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 mySolutionsShape; + const TopoDS_Shape* myShape; + const NCollection_Array1* 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 > 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 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::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< #include #include +#include #include +#include + //! This class provides tools to compute minimum distance
//! between two Shapes (Compound,CompSolid, Solid, Shell, Face, Wire, Edge, Vertex).
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
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.
//! Returns IsDone status.
//! 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.
Standard_Boolean IsDone() const { @@ -76,7 +82,7 @@ class BRepExtrema_DistShapeShape //! Returns the number of solutions satisfying the minimum distance.
Standard_Integer NbSolution() const { - return mySolutionsShape1.Length(); + return (Standard_Integer) mySolutionsShape1.size(); } //! Returns the value of the minimum distance.
Standard_EXPORT Standard_Real Value() const; @@ -89,12 +95,12 @@ class BRepExtrema_DistShapeShape //! Returns the Point corresponding to the th solution on the first Shape
const gp_Pnt & PointOnShape1(const Standard_Integer N) const { - return mySolutionsShape1.Value(N).Point(); + return mySolutionsShape1[N].Point(); } //! Returns the Point corresponding to the th solution on the second Shape
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:
//! IsVertex => the Nth solution on the first shape is a Vertex
@@ -103,7 +109,7 @@ class BRepExtrema_DistShapeShape //! the corresponding support is obtained by the method SupportOnShape1
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:
//! IsVertex => the Nth solution on the second shape is a Vertex
@@ -112,7 +118,7 @@ class BRepExtrema_DistShapeShape //! the corresponding support is obtained by the method SupportOnShape2
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.
//! This support can be a Vertex, an Edge or a Face.
@@ -150,20 +156,37 @@ private: //! computes the minimum distance between two maps of shapes (Face,Edge,Vertex)
Standard_EXPORT void DistanceMapMap(const TopTools_IndexedMapOfShape& Map1, const TopTools_IndexedMapOfShape& Map2, - const Bnd_SeqOfBox& LBox1, - const Bnd_SeqOfBox& LBox2, + const std::vector& LBox1, + const std::vector& LBox2, const Message_ProgressRange& theRange); + void DistanceVertVert(const TopTools_IndexedMapOfShape& theMap1, + const TopTools_IndexedMapOfShape& theMap2, + const std::vector& theLBox1, + const std::vector& 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 mySolutionsShape1; + std::vector 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 myBV1; + std::vector myBV2; + std::vector myBE1; + std::vector myBE2; + std::vector myBF1; + std::vector myBF2; + + Standard_Boolean myIsBreak; + mutable Handle(Standard_HMutex) myMutex; }; #endif diff --git a/src/BRepExtrema/BRepExtrema_DistanceSS.cxx b/src/BRepExtrema/BRepExtrema_DistanceSS.cxx index 61773dd806..0ae065e5d6 100644 --- a/src/BRepExtrema/BRepExtrema_DistanceSS.cxx +++ b/src/BRepExtrema/BRepExtrema_DistanceSS.cxx @@ -62,12 +62,11 @@ //------------------------------------------------------------------------------ // function: TRI_SOLUTION //------------------------------------------------------------------------------ -static Standard_Boolean TRI_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol, const gp_Pnt& Pt) +static Standard_Boolean TRI_SOLUTION (std::vector& 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& SeqSol1, + const std::vector& SeqSol2, const Standard_Real DstRef, const Standard_Real Eps, - BRepExtrema_SeqOfSolution& seqSol1, - BRepExtrema_SeqOfSolution& seqSol2) + std::vector& seqSol1, + std::vector& 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& SeqSol1, + std::vector& 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 SeqSolution1; + std::vector SeqSolution2; PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps); - BRepExtrema_SeqOfSolution seqSol1; - BRepExtrema_SeqOfSolution seqSol2; + std::vector seqSol1; + std::vector 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 SeqSolution1; + std::vector 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 seqSol1; + std::vector 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 SeqSolution1; + std::vector 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 seqSol1; + std::vector 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); } } } diff --git a/src/BRepExtrema/BRepExtrema_DistanceSS.hxx b/src/BRepExtrema/BRepExtrema_DistanceSS.hxx index 1f7e6fc9e4..2b96597f92 100644 --- a/src/BRepExtrema/BRepExtrema_DistanceSS.hxx +++ b/src/BRepExtrema/BRepExtrema_DistanceSS.hxx @@ -20,6 +20,8 @@ #include #include +#include + 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
- const BRepExtrema_SeqOfSolution& Seq1Value() const + const std::vector& Seq1Value() const { return SeqSolShape1; } //! returns the list of solutions on the second shape
- const BRepExtrema_SeqOfSolution& Seq2Value() const + const std::vector& Seq2Value() const { return SeqSolShape2; } @@ -124,8 +126,8 @@ class BRepExtrema_DistanceSS //! computes the minimum distance between two faces
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 SeqSolShape1; + std::vector SeqSolShape2; Standard_Real myDstRef; Standard_Boolean myModif; Standard_Real myEps; diff --git a/src/BRepTest/BRepTest_ExtremaCommands.cxx b/src/BRepTest/BRepTest_ExtremaCommands.cxx index 0fa44321d1..7309769fab 100644 --- a/src/BRepTest/BRepTest_ExtremaCommands.cxx +++ b/src/BRepTest/BRepTest_ExtremaCommands.cxx @@ -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);