return (theLeft.Distance < theRight.Distance);
}
}
+//=======================================================================
+//struct : VertexTask
+//purpose :
+//=======================================================================
+struct VertexTask
+{
+ VertexTask(Standard_Integer theFirtsIndex,
+ Standard_Integer theLastIndex,
+ BRepExtrema_SeqOfSolution* theSolutionsShape1,
+ BRepExtrema_SeqOfSolution* theSolutionsShape2,
+ const TopTools_IndexedMapOfShape* theMap1,
+ const TopTools_IndexedMapOfShape* theMap2,
+ const Bnd_SeqOfBox* theLBox1,
+ const Bnd_SeqOfBox* 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;
+ BRepExtrema_SeqOfSolution* mySolutionsShape1;
+ BRepExtrema_SeqOfSolution* mySolutionsShape2;
+ const TopTools_IndexedMapOfShape* myMap1;
+ const TopTools_IndexedMapOfShape* myMap2;
+ const Bnd_SeqOfBox* myLBox1;
+ const Bnd_SeqOfBox* 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);
+
+ 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->Value(anIdx1);
+ const Bnd_Box& aBox2 = theTask.myLBox2->Value(anIdx2);
+ if (aBox1.IsVoid()
+ || aBox2.IsVoid())
+ {
+ continue;
+ }
+ const TopoDS_Shape& aShape1 = theTask.myMap1->FindKey(anIdx1);
+ const TopoDS_Shape& aShape2 = theTask.myMap2->FindKey(anIdx2);
+
+ Standard_Real aDistRef(0);
+ {
+ Standard_Mutex::Sentry aLock(theTask.myMutex.get());
+ aDistRef = *theTask.myDistRef;
+ }
+ 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();
+
+ BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
+ BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
+
+ theTask.mySolutionsShape1->Append(aSeq1);
+ theTask.mySolutionsShape2->Append(aSeq2);
+
+ *theTask.myDistRef = aDistTool.DistValue();
+ }
+ else if (fabs(aDistTool.DistValue() - *theTask.myDistRef) < theTask.myEps)
+ {
+ BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
+ BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
+
+ theTask.mySolutionsShape1->Append(aSeq1);
+ theTask.mySolutionsShape2->Append(aSeq2);
+
+ if (*theTask.myDistRef > aDistTool.DistValue())
+ {
+ *theTask.myDistRef = aDistTool.DistValue();
+ }
+ }
+ }
+ }
+ }
+ }
+};
//=======================================================================
//function : DistanceMapMap
//purpose :
const Bnd_SeqOfBox& theLBox2,
const Message_ProgressRange& theRange)
{
- NCollection_Vector<BRepExtrema_CheckPair> aPairList;
const Standard_Integer aCount1 = theMap1.Extent();
const Standard_Integer aCount2 = theMap2.Extent();
- Message_ProgressScope aScope(theRange, 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.Value(anIdx1);
+ const Bnd_Box& aBox2 = theLBox2.Value(anIdx2);
+ 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();
+
+ BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
+ BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
+
+ mySolutionsShape1.Append(aSeq1);
+ mySolutionsShape2.Append(aSeq2);
+
+ myDistRef = aDistTool.DistValue();
+ }
+ else if (fabs(aDistTool.DistValue() - myDistRef) < myEps)
+ {
+ BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
+ BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
+
+ mySolutionsShape1.Append(aSeq1);
+ mySolutionsShape2.Append(aSeq2);
+
+ if (myDistRef > aDistTool.DistValue())
+ {
+ myDistRef = aDistTool.DistValue();
+ }
+ }
+ }
+ }
+ }
+ }
+ else
{
- aScope.Next();
- if (!aScope.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)
+ {
+ VertexTask aTask(aFirstIndex, aFirstIndex + aTaskSize,
+ &mySolutionsShape1, &mySolutionsShape2,
+ &theMap1, &theMap2, &theLBox1, &theLBox2,
+ aDistScope.Next(), &myIsBreak, &myDistRef,
+ myEps, myMutex);
+ aTaskArray.SetValue(anI, aTask);
+ }
+ 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,
+ BRepExtrema_SeqOfSolution* theSolutionsShape1,
+ BRepExtrema_SeqOfSolution* theSolutionsShape2,
+ const TopTools_IndexedMapOfShape* theMap1,
+ const TopTools_IndexedMapOfShape* theMap2,
+ const Bnd_SeqOfBox* theLBox1,
+ const Bnd_SeqOfBox* 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;
+ }
+
+ BRepExtrema_SeqOfSolution* mySolutionsShape1;
+ BRepExtrema_SeqOfSolution* mySolutionsShape2;
+ const NCollection_Array1<BRepExtrema_CheckPair>* myArray;
+ const TopTools_IndexedMapOfShape* myMap1;
+ const TopTools_IndexedMapOfShape* myMap2;
+ const Bnd_SeqOfBox* myLBox1;
+ const Bnd_SeqOfBox* 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 TopoDS_Shape& aShape1 = theMap1.FindKey(anIdx1);
- const TopoDS_Shape& aShape2 = theMap2.FindKey(anIdx1);
- BRepExtrema_DistanceSS aDistTool(aShape1, aShape2, aBox1, aBox2, myDistRef, myEps);
+ const BRepExtrema_CheckPair& aPair = theTask.myArray->Value(i);
+ {
+ 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->Value(aPair.Index1);
+ const Bnd_Box& aBox2 = theTask.myLBox2->Value(aPair.Index2);
+
+ 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())
{
- if (aDistTool.DistValue() < myDistRef - myEps)
+ Standard_Mutex::Sentry aLock(theTask.myMutex.get());
+ if (aDistTool.DistValue() < *theTask.myDistRef - anEps)
{
- mySolutionsShape1.Clear();
- mySolutionsShape2.Clear();
+ theTask.mySolutionsShape1->Clear();
+ theTask.mySolutionsShape2->Clear();
BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
- mySolutionsShape1.Append(aSeq1);
- mySolutionsShape2.Append(aSeq2);
+ theTask.mySolutionsShape1->Append(aSeq1);
+ theTask.mySolutionsShape2->Append(aSeq2);
- myDistRef = aDistTool.DistValue();
+ *theTask.myDistRef = aDistTool.DistValue();
}
- else if (fabs(aDistTool.DistValue() - myDistRef) < myEps)
+ else if (fabs(aDistTool.DistValue() - *theTask.myDistRef) < anEps)
{
BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
- mySolutionsShape1.Append(aSeq1);
- mySolutionsShape2.Append(aSeq2);
+ theTask.mySolutionsShape1->Append(aSeq1);
+ theTask.mySolutionsShape2->Append(aSeq2);
- if (myDistRef > aDistTool.DistValue())
+ if (*theTask.myDistRef > aDistTool.DistValue())
{
- myDistRef = aDistTool.DistValue();
+ *theTask.myDistRef = aDistTool.DistValue();
}
}
}
}
}
-}
+};
//=======================================================================
//function : DistanceMapMap
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())
+ if (myMutex.IsNull())
{
- aDistScope.Next();
- if (!aDistScope.More())
+ Message_ProgressScope aDistScope(aDistRange, NULL, aPairList.Size());
+ for (NCollection_Vector<BRepExtrema_CheckPair>::Iterator aPairIter(aPairList);
+ aPairIter.More(); aPairIter.Next())
{
- throw StdFail_NotDone();
- }
- const BRepExtrema_CheckPair& aPair = aPairIter.Value();
- if (aPair.Distance > myDistRef + myEps)
- {
- break; // early search termination
- }
+ aDistScope.Next();
+ if (!aDistScope.More())
+ {
+ throw StdFail_NotDone();
+ }
+ const BRepExtrema_CheckPair& aPair = aPairIter.Value();
+ if (aPair.Distance > myDistRef + myEps)
+ {
+ break; // early search termination
+ }
- const Bnd_Box& aBox1 = theLBox1.Value (aPair.Index1);
- const Bnd_Box& aBox2 = theLBox2.Value (aPair.Index2);
+ const Bnd_Box& aBox1 = theLBox1.Value(aPair.Index1);
+ const Bnd_Box& aBox2 = theLBox2.Value(aPair.Index2);
- const TopoDS_Shape& aShape1 = theMap1 (aPair.Index1);
- const TopoDS_Shape& aShape2 = theMap2 (aPair.Index2);
+ const TopoDS_Shape& aShape1 = theMap1(aPair.Index1);
+ const TopoDS_Shape& aShape2 = theMap2(aPair.Index2);
- BRepExtrema_DistanceSS aDistTool (aShape1, aShape2, aBox1, aBox2, myDistRef, myEps);
- if (aDistTool.IsDone())
- {
- if (aDistTool.DistValue() < myDistRef - myEps)
+ BRepExtrema_DistanceSS aDistTool(aShape1, aShape2, aBox1, aBox2, myDistRef, myEps);
+ if (aDistTool.IsDone())
{
- mySolutionsShape1.Clear();
- mySolutionsShape2.Clear();
+ if (aDistTool.DistValue() < myDistRef - myEps)
+ {
+ mySolutionsShape1.Clear();
+ mySolutionsShape2.Clear();
+
+ BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
+ BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
+
+ mySolutionsShape1.Append(aSeq1);
+ mySolutionsShape2.Append(aSeq2);
- BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
- BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
+ myDistRef = aDistTool.DistValue();
+ }
+ else if (fabs(aDistTool.DistValue() - myDistRef) < myEps)
+ {
+ BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
+ BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
- mySolutionsShape1.Append (aSeq1);
- mySolutionsShape2.Append (aSeq2);
+ mySolutionsShape1.Append(aSeq1);
+ mySolutionsShape2.Append(aSeq2);
- myDistRef = aDistTool.DistValue();
+ if (myDistRef > aDistTool.DistValue())
+ {
+ myDistRef = aDistTool.DistValue();
+ }
+ }
}
- else if (fabs (aDistTool.DistValue() - myDistRef) < myEps)
+ }
+ }
+ 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)
{
- BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
- BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
-
- mySolutionsShape1.Append (aSeq1);
- mySolutionsShape2.Append (aSeq2);
+ aTaskSize = aMinTaskSize;
+ aNbTasks = (Standard_Integer) Ceiling((double) aMapSize / aTaskSize);
+ }
- if (myDistRef > aDistTool.DistValue())
+ 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)
{
- myDistRef = aDistTool.DistValue();
+ 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_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();
}
}
}
myIsInitS2 (Standard_False),
myFlag (Extrema_ExtFlag_MINMAX),
myAlgo (Extrema_ExtAlgo_Grad),
- myIsBreak(Standard_False)
+ myIsBreak(Standard_False),
+ myMutex(NULL)
{
//
}
myIsInitS2 (Standard_False),
myFlag (F),
myAlgo (A),
- myIsBreak(Standard_False)
+ myIsBreak(Standard_False),
+ myMutex(NULL)
{
LoadS1(Shape1);
LoadS2(Shape2);
myIsInitS2 (Standard_False),
myFlag (F),
myAlgo (A),
- myIsBreak(Standard_False)
+ myIsBreak(Standard_False),
+ myMutex(NULL)
{
LoadS1(Shape1);
LoadS2(Shape2);
{
if (!aScope.More())
{
- Standard_Atomic_CompareAndSwap((int*) theTask.myIsBreak, Standard_False, Standard_True);
+ Standard_Atomic_CompareAndSwap((int*) *theTask.myIsBreak, Standard_False, Standard_True);
}
Message_ProgressRange aRange = aScope.Next();
-
- if (!theTask.myIsBreak)
+ if (*theTask.myIsBreak || *theTask.myIsDone)
{
break;
}
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);
+ 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.Append(aSolElem);
break;
}
NCollection_Array1<TreatmentTask> aTaskArray(0, aNbTasks - 1);
- Message_ProgressScope aRange(theRange, "Solid treatment", aNbTasks);
+ Message_ProgressScope aScope(theRange, "Solid treatment", aNbTasks);
for (Standard_Integer anI = 0; anI < aTaskArray.Size(); ++anI)
{
- TreatmentTask aTask(&theShape, &anArrayOfArray[anI], aRange.Next(), &myIsBreak, &myInnerSol, &myIsDone);
+ TreatmentTask aTask(&theShape, &anArrayOfArray[anI], aScope.Next(), &myIsBreak, &myInnerSol, &myIsDone);
aTaskArray.SetValue(anI, aTask);
}
if (myInnerSol)
{
myDistRef = 0.;
+ if (aTaskArray.Size())
+ {
+ mySolutionsShape1.Append(aTaskArray[0].mySolutionsShape);
+ mySolutionsShape2.Append(aTaskArray[0].mySolutionsShape);
+ }
}
- for (Standard_Integer anI = 0; anI < aTaskArray.Size(); ++anI)
- {
- mySolutionsShape1.Append(aTaskArray[anI].mySolutionsShape);
- mySolutionsShape2.Append(aTaskArray[anI].mySolutionsShape);
- }
}
//=======================================================================
//function : SolidTreatment
Standard_Boolean BRepExtrema_DistShapeShape::Perform(const Message_ProgressRange& theRange,
const Standard_Boolean theIsMultiThread)
{
+ CheckAndSetMutex(theIsMultiThread);
+
myIsDone = Standard_False;
myInnerSol = Standard_False;
myIsBreak = Standard_False;
{
SolidTreatment(myShape1, myMapV2, aRootScope.Next(), theIsMultiThread);
}
-
- if (anIsSolid2 && (!myInnerSol))
- {
+
+ if (anIsSolid2 && (!myInnerSol))
+ {
SolidTreatment(myShape2, myMapV1, aRootScope.Next(), theIsMultiThread);
}
- if (!myInnerSol)
- {
- if (!myIsInitS1) // rebuild cached data for 1st shape
+ if (!myInnerSol)
{
- myBV1.Clear();
- myBE1.Clear();
- myBF1.Clear();
+ if (!myIsInitS1) // rebuild cached data for 1st shape
+ {
+ myBV1.Clear();
+ myBE1.Clear();
+ myBF1.Clear();
- BoxCalculation (myMapV1, myBV1);
- BoxCalculation (myMapE1, myBE1);
- BoxCalculation (myMapF1, myBF1);
+ BoxCalculation (myMapV1, myBV1);
+ BoxCalculation (myMapE1, myBE1);
+ BoxCalculation (myMapF1, myBF1);
- myIsInitS1 = Standard_True;
- }
+ myIsInitS1 = Standard_True;
+ }
- if (!myIsInitS2) // rebuild cached data for 2nd shape
- {
- myBV2.Clear();
- myBE2.Clear();
- myBF2.Clear();
+ if (!myIsInitS2) // rebuild cached data for 2nd shape
+ {
+ myBV2.Clear();
+ myBE2.Clear();
+ myBF2.Clear();
- BoxCalculation (myMapV2, myBV2);
- BoxCalculation (myMapE2, myBE2);
- BoxCalculation (myMapF2, myBF2);
+ BoxCalculation (myMapV2, myBV2);
+ BoxCalculation (myMapE2, myBE2);
+ BoxCalculation (myMapF2, myBF2);
- myIsInitS2 = Standard_True;
- }
+ myIsInitS2 = Standard_True;
+ }
- if (myMapV1.Extent() && myMapV2.Extent())
- {
- TopoDS_Vertex V1 = TopoDS::Vertex(myMapV1(1));
- TopoDS_Vertex V2 = TopoDS::Vertex(myMapV2(1));
- myDistRef = DistanceInitiale(V1, V2);
- }
- else
- myDistRef= 1.e30; //szv:!!!
-
- 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());
- DistanceMapMap (myMapF1, myMapV2, myBF1, myBV2, aRootScope.Next());
- DistanceMapMap (myMapE1, myMapE2, myBE1, myBE2, aRootScope.Next());
- DistanceMapMap (myMapE1, myMapF2, myBE1, myBF2, aRootScope.Next());
- DistanceMapMap (myMapF1, myMapE2, myBF1, myBE2, aRootScope.Next());
-
- if (fabs (myDistRef) > myEps)
- {
- 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)
+ if (myMapV1.Extent() && myMapV2.Extent())
{
- mySolutionsShape1.Remove(i);
- mySolutionsShape2.Remove(i);
+ TopoDS_Vertex V1 = TopoDS::Vertex(myMapV1(1));
+ TopoDS_Vertex V2 = TopoDS::Vertex(myMapV2(1));
+ myDistRef = DistanceInitiale(V1, V2);
}
- // Modified by Sergey KHROMOV - Tue Mar 6 11:55:04 2001 End
- myIsDone = ( mySolutionsShape1.Length() > 0 );
- }
+ else
+ myDistRef= 1.e30; //szv:!!!
+
+ 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());
+ DistanceMapMap (myMapF1, myMapV2, myBF1, myBV2, aRootScope.Next());
+ DistanceMapMap (myMapE1, myMapE2, myBE1, myBE2, aRootScope.Next());
+ DistanceMapMap (myMapE1, myMapF2, myBE1, myBF2, aRootScope.Next());
+ DistanceMapMap (myMapF1, myMapE2, myBF1, myBE2, aRootScope.Next());
+
+ if (fabs (myDistRef) > myEps)
+ {
+ 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)
+ {
+ mySolutionsShape1.Remove(i);
+ mySolutionsShape2.Remove(i);
+ }
+ // Modified by Sergey KHROMOV - Tue Mar 6 11:55:04 2001 End
+ myIsDone = ( mySolutionsShape1.Length() > 0 );
+ }
}
catch (StdFail_NotDone)
{
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;
+ }
+}
+