SelectMgr_AndFilter.hxx
SelectMgr_BaseFrustum.cxx
SelectMgr_BaseFrustum.hxx
+SelectMgr_BVHThreadPool.cxx
+SelectMgr_BVHThreadPool.hxx
SelectMgr_CompositionFilter.cxx
SelectMgr_CompositionFilter.hxx
SelectMgr_CompositionFilter.lxx
--- /dev/null
+#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();
+ }
+}
+
--- /dev/null
+#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
theObject->AddSelection (aNewSel, theMode);
aNewSel->UpdateBVHStatus (SelectMgr_TBU_Remove);
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;
mySelector->AddSelectionToObject (theObject, aNewSel);
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);
+ }
+ }
}
//=======================================================================
myCameraScale (1.0),
myCurRank (0),
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);
}
//=======================================================================
void SelectMgr_ViewerSelector::TraverseSensitives()
{
+ if (myToPrebuildBVH)
+ {
+ myBVHThreadPool->LockBVHBuildMutex();
+ }
+
mystored.Clear();
Standard_Integer aWidth;
}
SortResult();
+
+ if (myToPrebuildBVH)
+ {
+ myBVHThreadPool->UnlockBVHBuildMutex();
+ }
}
//==================================================
{
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);
+ }
+}
\ No newline at end of file
#include <SelectMgr_StateOfSelection.hxx>
#include <SelectMgr_ToleranceMap.hxx>
#include <Standard_OStream.hxx>
+#include <SelectMgr_BVHThreadPool.hxx>
class SelectMgr_SelectionManager;
class SelectMgr_SensitiveEntitySet;
Standard_DEPRECATED("Deprecated method DetectedEntity() should be replaced by DetectedEntity(int)")
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:
Standard_EXPORT SelectMgr_ViewerSelector();
gp_Dir myCameraDir;
Standard_Real myCameraScale;
+ Standard_Boolean myToPrebuildBVH;
+ Handle(SelectMgr_BVHThreadPool) myBVHThreadPool;
+
private:
Handle(TColStd_HArray1OfInteger) myIndexes;