mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-29 14:00:49 +03:00
0031757: Visualization - Prebuild BVH for Select3D_SensitiveEntity in separate threads
(cherry picked from commit bb598fe0216163889af6aa054ec8081eb1cfd384)
This commit is contained in:
@@ -2,6 +2,8 @@ SelectMgr_AndFilter.cxx
|
|||||||
SelectMgr_AndFilter.hxx
|
SelectMgr_AndFilter.hxx
|
||||||
SelectMgr_BaseFrustum.cxx
|
SelectMgr_BaseFrustum.cxx
|
||||||
SelectMgr_BaseFrustum.hxx
|
SelectMgr_BaseFrustum.hxx
|
||||||
|
SelectMgr_BVHThreadPool.cxx
|
||||||
|
SelectMgr_BVHThreadPool.hxx
|
||||||
SelectMgr_CompositionFilter.cxx
|
SelectMgr_CompositionFilter.cxx
|
||||||
SelectMgr_CompositionFilter.hxx
|
SelectMgr_CompositionFilter.hxx
|
||||||
SelectMgr_CompositionFilter.lxx
|
SelectMgr_CompositionFilter.lxx
|
||||||
|
157
src/SelectMgr/SelectMgr_BVHThreadPool.cxx
Normal file
157
src/SelectMgr/SelectMgr_BVHThreadPool.cxx
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#include <SelectMgr_BVHThreadPool.hxx>
|
||||||
|
#include <OSD_Parallel.hxx>
|
||||||
|
|
||||||
|
IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_BVHThreadPool, Standard_Transient)
|
||||||
|
|
||||||
|
//==================================================
|
||||||
|
// Function: SelectMgr_BVHThreadPool
|
||||||
|
// Purpose :
|
||||||
|
//==================================================
|
||||||
|
SelectMgr_BVHThreadPool::SelectMgr_BVHThreadPool (Standard_Integer theNbThreads)
|
||||||
|
: myToStopBVHThread(Standard_False),
|
||||||
|
myWakeEvent(Standard_False),
|
||||||
|
myIdleEvent(Standard_True),
|
||||||
|
myIsStarted(Standard_False)
|
||||||
|
{
|
||||||
|
Standard_Integer aBVHThreadsNum = theNbThreads > 0 ? theNbThreads : OSD_Parallel::NbLogicalProcessors() > 1 ? OSD_Parallel::NbLogicalProcessors() - 1 : 1;
|
||||||
|
myBVHThreads = NCollection_Array1<OSD_Thread>(1, aBVHThreadsNum);
|
||||||
|
myBVHBuildData = NCollection_Array1<BVHBuild_Data>(1, aBVHThreadsNum);
|
||||||
|
|
||||||
|
for (Standard_Integer i = myBVHThreads.Lower(); i <= myBVHThreads.Upper(); ++i)
|
||||||
|
{
|
||||||
|
myBVHThreads.ChangeValue(i).SetFunction (buildBVHThreadFunc);
|
||||||
|
myBVHThreads.ChangeValue(i).SetPriority (THREAD_PRIORITY_BELOW_NORMAL);
|
||||||
|
myBVHBuildData.ChangeValue(i).Pool = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================
|
||||||
|
// Function: ~SelectMgr_BVHThreadPool
|
||||||
|
// Purpose :
|
||||||
|
//==================================================
|
||||||
|
SelectMgr_BVHThreadPool::~SelectMgr_BVHThreadPool()
|
||||||
|
{
|
||||||
|
StopThreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================
|
||||||
|
// Function: StopThreads
|
||||||
|
// Purpose :
|
||||||
|
//==================================================
|
||||||
|
void SelectMgr_BVHThreadPool::StopThreads()
|
||||||
|
{
|
||||||
|
if (!myIsStarted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
myToStopBVHThread = Standard_True;
|
||||||
|
myWakeEvent.Set();
|
||||||
|
for (Standard_Integer i = myBVHThreads.Lower(); i <= myBVHThreads.Upper(); ++i)
|
||||||
|
{
|
||||||
|
myBVHThreads.ChangeValue(i).Wait();
|
||||||
|
}
|
||||||
|
myToStopBVHThread = Standard_False;
|
||||||
|
myIsStarted = Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================
|
||||||
|
// Function: WaitThreads
|
||||||
|
// Purpose :
|
||||||
|
//==================================================
|
||||||
|
void SelectMgr_BVHThreadPool::WaitThreads()
|
||||||
|
{
|
||||||
|
myIdleEvent.Wait();
|
||||||
|
|
||||||
|
LockBVHBuildMutex();
|
||||||
|
UnlockBVHBuildMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : BuildBVH
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void SelectMgr_BVHThreadPool::BuildBVH (const Handle(Select3D_SensitiveEntity)& theEntity)
|
||||||
|
{
|
||||||
|
myBVHListMutex.Lock();
|
||||||
|
myBVHToBuildList.Append (theEntity);
|
||||||
|
myWakeEvent.Set();
|
||||||
|
myIdleEvent.Reset();
|
||||||
|
myBVHListMutex.Unlock();
|
||||||
|
|
||||||
|
if (!myIsStarted)
|
||||||
|
{
|
||||||
|
myIsStarted = Standard_True;
|
||||||
|
for (Standard_Integer i = myBVHThreads.Lower(); i <= myBVHThreads.Upper(); ++i)
|
||||||
|
{
|
||||||
|
myBVHThreads.ChangeValue(i).Run((Standard_Address)(&myBVHBuildData.ChangeValue(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : buildBVHThreadFunc
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
Standard_Address SelectMgr_BVHThreadPool::buildBVHThreadFunc (Standard_Address data)
|
||||||
|
{
|
||||||
|
BVHBuild_Data* aData = reinterpret_cast<BVHBuild_Data*> (data);
|
||||||
|
SelectMgr_BVHThreadPool* aPool = aData->Pool;
|
||||||
|
Standard_Mutex& aBVHBuildMutex = aData->Mutex;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
aPool->myWakeEvent.Wait();
|
||||||
|
|
||||||
|
if (aPool->myToStopBVHThread)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
aPool->myBVHListMutex.Lock();
|
||||||
|
if (aPool->myBVHToBuildList.IsEmpty())
|
||||||
|
{
|
||||||
|
aPool->myWakeEvent.Reset();
|
||||||
|
aPool->myIdleEvent.Set();
|
||||||
|
aPool->myBVHListMutex.Unlock();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Handle(Select3D_SensitiveEntity) anEntity = aPool->myBVHToBuildList.First();
|
||||||
|
aPool->myBVHToBuildList.RemoveFirst();
|
||||||
|
|
||||||
|
aBVHBuildMutex.Lock();
|
||||||
|
aPool->myBVHListMutex.Unlock();
|
||||||
|
|
||||||
|
if (!anEntity.IsNull())
|
||||||
|
{
|
||||||
|
anEntity->BVH();
|
||||||
|
}
|
||||||
|
aBVHBuildMutex.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Standard_Address)(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : LockBVHBuildMutex
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void SelectMgr_BVHThreadPool::LockBVHBuildMutex()
|
||||||
|
{
|
||||||
|
for (Standard_Integer i = myBVHBuildData.Lower(); i <= myBVHBuildData.Upper(); ++i)
|
||||||
|
{
|
||||||
|
myBVHBuildData.ChangeValue(i).Mutex.Lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : UnlockBVHBuildMutex
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void SelectMgr_BVHThreadPool::UnlockBVHBuildMutex()
|
||||||
|
{
|
||||||
|
for (Standard_Integer i = myBVHBuildData.Lower(); i <= myBVHBuildData.Upper(); ++i)
|
||||||
|
{
|
||||||
|
myBVHBuildData.ChangeValue(i).Mutex.Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
60
src/SelectMgr/SelectMgr_BVHThreadPool.hxx
Normal file
60
src/SelectMgr/SelectMgr_BVHThreadPool.hxx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#ifndef _SelectMgr_BVHThreadPool_HeaderFile
|
||||||
|
#define _SelectMgr_BVHThreadPool_HeaderFile
|
||||||
|
|
||||||
|
#include <Standard_Transient.hxx>
|
||||||
|
#include <OSD_Thread.hxx>
|
||||||
|
#include <Standard_Mutex.hxx>
|
||||||
|
#include <Select3D_SensitiveEntity.hxx>
|
||||||
|
#include <Standard_Condition.hxx>
|
||||||
|
|
||||||
|
//! Class defining a thread pool for building BVH for Select3D_SensitiveEntity in multi-threaded mode.
|
||||||
|
class SelectMgr_BVHThreadPool : public Standard_Transient
|
||||||
|
{
|
||||||
|
DEFINE_STANDARD_RTTIEXT(SelectMgr_BVHThreadPool, Standard_Transient)
|
||||||
|
public:
|
||||||
|
//! Main constructor
|
||||||
|
Standard_EXPORT SelectMgr_BVHThreadPool (Standard_Integer theNbThreads);
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
Standard_EXPORT virtual ~SelectMgr_BVHThreadPool();
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Queue a sensitive entity to build its BVH
|
||||||
|
Standard_EXPORT void BuildBVH (const Handle(Select3D_SensitiveEntity)& theEntity);
|
||||||
|
|
||||||
|
//! Lock mutexes for building BVH
|
||||||
|
Standard_EXPORT void LockBVHBuildMutex();
|
||||||
|
|
||||||
|
//! Unlock mutexes for building BVH
|
||||||
|
Standard_EXPORT void UnlockBVHBuildMutex();
|
||||||
|
|
||||||
|
//! Stops threads
|
||||||
|
Standard_EXPORT void StopThreads();
|
||||||
|
|
||||||
|
//! Waits for all threads finish their jobs
|
||||||
|
Standard_EXPORT void WaitThreads();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Thread function, accept address of BVHBuild_Data struct as parameter
|
||||||
|
static Standard_Address buildBVHThreadFunc (Standard_Address data);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Structure that will be passed to a separate thread
|
||||||
|
struct BVHBuild_Data
|
||||||
|
{
|
||||||
|
SelectMgr_BVHThreadPool* Pool;
|
||||||
|
Standard_Mutex Mutex;
|
||||||
|
};
|
||||||
|
NCollection_List<Handle(Select3D_SensitiveEntity)> myBVHToBuildList; //!< list of queued sensitive entities
|
||||||
|
NCollection_Array1<OSD_Thread> myBVHThreads; //!< threads to build BVH
|
||||||
|
Standard_Boolean myToStopBVHThread; //!< flag to stop BVH threads
|
||||||
|
Standard_Mutex myBVHListMutex; //!< mutex for interaction with myBVHToBuildList
|
||||||
|
NCollection_Array1<BVHBuild_Data> myBVHBuildData; //!< list of mutexes for building BVH
|
||||||
|
Standard_Condition myWakeEvent; //!< raises when any sensitive is added to the BVH list
|
||||||
|
Standard_Condition myIdleEvent; //!< raises when BVH list become empty
|
||||||
|
Standard_Boolean myIsStarted; //!< indicates that threads are running
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@@ -484,6 +484,16 @@ void SelectMgr_SelectionManager::loadMode (const Handle(SelectMgr_SelectableObje
|
|||||||
theObject->AddSelection (aNewSel, theMode);
|
theObject->AddSelection (aNewSel, theMode);
|
||||||
aNewSel->UpdateBVHStatus (SelectMgr_TBU_Remove);
|
aNewSel->UpdateBVHStatus (SelectMgr_TBU_Remove);
|
||||||
aNewSel->SetSelectionState (SelectMgr_SOS_Deactivated);
|
aNewSel->SetSelectionState (SelectMgr_SOS_Deactivated);
|
||||||
|
|
||||||
|
if (mySelector->ToPrebuildBVH())
|
||||||
|
{
|
||||||
|
NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator anIter(aNewSel->Entities());
|
||||||
|
for (; anIter.More(); anIter.Next())
|
||||||
|
{
|
||||||
|
const Handle(Select3D_SensitiveEntity)& anEntity = anIter.Value()->BaseSensitive();
|
||||||
|
mySelector->QueueBVHBuild(anEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -496,6 +506,16 @@ void SelectMgr_SelectionManager::loadMode (const Handle(SelectMgr_SelectableObje
|
|||||||
mySelector->AddSelectionToObject (theObject, aNewSel);
|
mySelector->AddSelectionToObject (theObject, aNewSel);
|
||||||
aNewSel->UpdateBVHStatus (SelectMgr_TBU_None);
|
aNewSel->UpdateBVHStatus (SelectMgr_TBU_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mySelector->ToPrebuildBVH())
|
||||||
|
{
|
||||||
|
NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator anIter(aNewSel->Entities());
|
||||||
|
for (; anIter.More(); anIter.Next())
|
||||||
|
{
|
||||||
|
const Handle(Select3D_SensitiveEntity)& anEntity = anIter.Value()->BaseSensitive();
|
||||||
|
mySelector->QueueBVHBuild(anEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@@ -125,7 +125,8 @@ myToUpdateTolerance (Standard_True),
|
|||||||
myCameraScale (1.0),
|
myCameraScale (1.0),
|
||||||
myCurRank (0),
|
myCurRank (0),
|
||||||
myIsLeftChildQueuedFirst (Standard_False),
|
myIsLeftChildQueuedFirst (Standard_False),
|
||||||
myEntityIdx (0)
|
myEntityIdx (0),
|
||||||
|
myToPrebuildBVH (Standard_False)
|
||||||
{
|
{
|
||||||
myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
|
myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
|
||||||
}
|
}
|
||||||
@@ -543,6 +544,11 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
void SelectMgr_ViewerSelector::TraverseSensitives()
|
void SelectMgr_ViewerSelector::TraverseSensitives()
|
||||||
{
|
{
|
||||||
|
if (myToPrebuildBVH)
|
||||||
|
{
|
||||||
|
myBVHThreadPool->LockBVHBuildMutex();
|
||||||
|
}
|
||||||
|
|
||||||
mystored.Clear();
|
mystored.Clear();
|
||||||
|
|
||||||
Standard_Integer aWidth;
|
Standard_Integer aWidth;
|
||||||
@@ -679,6 +685,11 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
|
|||||||
}
|
}
|
||||||
|
|
||||||
SortResult();
|
SortResult();
|
||||||
|
|
||||||
|
if (myToPrebuildBVH)
|
||||||
|
{
|
||||||
|
myBVHThreadPool->UnlockBVHBuildMutex();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================
|
//==================================================
|
||||||
@@ -1046,3 +1057,32 @@ void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean the
|
|||||||
{
|
{
|
||||||
mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);
|
mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : SetToPrebuildBVH
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void SelectMgr_ViewerSelector::SetToPrebuildBVH (Standard_Boolean theToPrebuild, Standard_Integer theThreadsNum)
|
||||||
|
{
|
||||||
|
if (!theToPrebuild && !myBVHThreadPool.IsNull())
|
||||||
|
{
|
||||||
|
myBVHThreadPool->StopThreads();
|
||||||
|
}
|
||||||
|
else if (theToPrebuild)
|
||||||
|
{
|
||||||
|
myBVHThreadPool = new SelectMgr_BVHThreadPool (theThreadsNum);
|
||||||
|
}
|
||||||
|
myToPrebuildBVH = theToPrebuild;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : QueueBVHBuild
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void SelectMgr_ViewerSelector::QueueBVHBuild (const Handle(Select3D_SensitiveEntity)& theEntity)
|
||||||
|
{
|
||||||
|
if (myToPrebuildBVH)
|
||||||
|
{
|
||||||
|
myBVHThreadPool->BuildBVH (theEntity);
|
||||||
|
}
|
||||||
|
}
|
@@ -31,6 +31,7 @@
|
|||||||
#include <SelectMgr_StateOfSelection.hxx>
|
#include <SelectMgr_StateOfSelection.hxx>
|
||||||
#include <SelectMgr_ToleranceMap.hxx>
|
#include <SelectMgr_ToleranceMap.hxx>
|
||||||
#include <Standard_OStream.hxx>
|
#include <Standard_OStream.hxx>
|
||||||
|
#include <SelectMgr_BVHThreadPool.hxx>
|
||||||
|
|
||||||
class SelectMgr_SelectionManager;
|
class SelectMgr_SelectionManager;
|
||||||
class SelectMgr_SensitiveEntitySet;
|
class SelectMgr_SensitiveEntitySet;
|
||||||
@@ -245,6 +246,20 @@ public:
|
|||||||
Standard_DEPRECATED("Deprecated method DetectedEntity() should be replaced by DetectedEntity(int)")
|
Standard_DEPRECATED("Deprecated method DetectedEntity() should be replaced by DetectedEntity(int)")
|
||||||
Standard_EXPORT const Handle(Select3D_SensitiveEntity)& DetectedEntity() const;
|
Standard_EXPORT const Handle(Select3D_SensitiveEntity)& DetectedEntity() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Enables/disables building BVH for sensitives in separate threads
|
||||||
|
Standard_EXPORT void SetToPrebuildBVH(Standard_Boolean theToPrebuild, Standard_Integer theThreadsNum = -1);
|
||||||
|
|
||||||
|
//! Queue a sensitive entity to build its BVH
|
||||||
|
Standard_EXPORT void QueueBVHBuild(const Handle(Select3D_SensitiveEntity)& theEntity);
|
||||||
|
|
||||||
|
//! Returns TRUE if building BVH for sensitives in separate threads is enabled
|
||||||
|
Standard_Boolean ToPrebuildBVH()
|
||||||
|
{
|
||||||
|
return myToPrebuildBVH;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Standard_EXPORT SelectMgr_ViewerSelector();
|
Standard_EXPORT SelectMgr_ViewerSelector();
|
||||||
@@ -336,6 +351,9 @@ protected:
|
|||||||
gp_Dir myCameraDir;
|
gp_Dir myCameraDir;
|
||||||
Standard_Real myCameraScale;
|
Standard_Real myCameraScale;
|
||||||
|
|
||||||
|
Standard_Boolean myToPrebuildBVH;
|
||||||
|
Handle(SelectMgr_BVHThreadPool) myBVHThreadPool;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Handle(TColStd_HArray1OfInteger) myIndexes;
|
Handle(TColStd_HArray1OfInteger) myIndexes;
|
||||||
|
Reference in New Issue
Block a user