#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>
}
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);
}
}
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();
}
}
}
myIsInitS1 (Standard_False),
myIsInitS2 (Standard_False),
myFlag (Extrema_ExtFlag_MINMAX),
- myAlgo (Extrema_ExtAlgo_Grad)
+ myAlgo (Extrema_ExtAlgo_Grad),
+ myIsBreak(Standard_False),
+ myMutex(NULL)
{
//
}
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),
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);
}
//=======================================================================
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),
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);
}
//=======================================================================
}
//=======================================================================
-//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)
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;
{
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);
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);
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());
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)
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();
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();
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");
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");
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");
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 ");
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;
+ }
+}
+
//------------------------------------------------------------------------------
// 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;
//------------------------------------------------------------------------------
// 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]);
+ }
}
}
// 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)
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);
}
}
}
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);
}
}
}
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())
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);
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
}
}
}
- 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;
}
}
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);
}
}
}
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);
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);
}
}
}
}
}
- 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());
}
}
}
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);
}
}
}
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);
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);
}
}
}
}
}
- 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());
}
}
}
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);
}
}
}