}
for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
{
- const Bnd_Box& aBox1 = theLBox1[anIdx1];
- const Bnd_Box& aBox2 = theLBox2[anIdx2];
+ const Bnd_Box& aBox1 = theLBox1[anIdx1-1];
+ const Bnd_Box& aBox2 = theLBox2[anIdx2-1];
if (aBox1.IsVoid() || aBox2.IsVoid())
{
continue;
Message_ProgressScope aDistScope(theRange, NULL, aNbTasks);
for (Standard_Integer anI = 0; anI < aTaskArray.Size(); ++anI)
{
- VertexTask aTask(aFirstIndex, aFirstIndex + aTaskSize,
+ 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);
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
- }
+ //if (aPair.Distance > *theTask.myDistRef + anEps)
+ //{
+ // *theTask.myIsDone = Standard_True;
+ // break; // early search termination
+ //}
}
const Bnd_Box& aBox1 = theTask.myLBox1->at(aPair.Index1-1);
}
};
+//=======================================================================
+//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)
+ {
+ }
+
+ 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)
+ {
+ 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));
+ }
+ }
+ }
+ }
+};
+
//=======================================================================
//function : DistanceMapMap
//purpose :
const Message_ProgressRange& theRange)
{
NCollection_Vector<BRepExtrema_CheckPair> aPairList;
+ Message_ProgressScope aTwinScope(theRange, NULL, 2);
+
+
const Standard_Integer aCount1 = theMap1.Extent();
const Standard_Integer aCount2 = theMap2.Extent();
- Message_ProgressScope aTwinScope(theRange, NULL, 2);
+
+ if (myMutex.IsNull())
+ {
Message_ProgressRange aBoxRange(aTwinScope.Next());
- Message_ProgressScope aBoxScope(aBoxRange, NULL, aCount1);
+ Message_ProgressScope aBoxScope(aBoxRange, NULL, aCount1);
- for (Standard_Integer anIdx1 = 1; anIdx1 <= aCount1; ++anIdx1)
+ for (Standard_Integer anIdx1 = 1; anIdx1 <= aCount1; ++anIdx1)
+ {
+ aBoxScope.Next();
+ if (!aBoxScope.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 Standard_Real aDist = aBox1.Distance (aBox2);
+ if (aDist < myDistRef - myEps || fabs (aDist - myDistRef) < myEps)
+ {
+ aPairList.Append (BRepExtrema_CheckPair (anIdx1, anIdx2, aDist));
+ }
+ }
+ }
+ }
+ 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)
{
- throw StdFail_NotDone();
+ aTaskSize = aMinTaskSize;
+ aNbTasks = (Standard_Integer) Ceiling((double) aCount1 / aTaskSize);
}
- for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
+
+ 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)
{
- const Bnd_Box& aBox1 = theLBox1[anIdx1-1];
- const Bnd_Box& aBox2 = theLBox2[anIdx2-1];
- if (aBox1.IsVoid() || aBox2.IsVoid())
+ if (aCount1 < aFirstIndex + aTaskSize - 1)
{
- continue;
+ 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);
- const Standard_Real aDist = aBox1.Distance (aBox2);
- if (aDist < myDistRef - myEps || fabs (aDist - myDistRef) < myEps)
- {
- aPairList.Append (BRepExtrema_CheckPair (anIdx1, anIdx2, aDist));
- }
+ if (myIsBreak)
+ {
+ throw StdFail_NotDone();
}
}
- std::stable_sort(aPairList.begin(), aPairList.end(), BRepExtrema_CheckPair_Comparator);
- Message_ProgressRange aDistRange(aTwinScope.Next());
if (myMutex.IsNull())
{
+ std::stable_sort(aPairList.begin(), aPairList.end(), BRepExtrema_CheckPair_Comparator);
+ }
+
+ 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())
}
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)
{
else
myDistRef= 1.e30; //szv:!!!
- DistanceVertVert(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 (!myIsDone)
throw StdFail_NotDone("BRepExtrema_DistShapeShape::SupportOnShape1: There's no solution ");
- const BRepExtrema_SolutionElem &sol = mySolutionsShape1[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[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[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[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[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[N];
+ const BRepExtrema_SolutionElem &sol = mySolutionsShape2[N-1];
if (sol.SupportKind() != BRepExtrema_IsInFace)
throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnFaceS2:ParOnFaceS2 is impossible without FACE ");