mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-16 10:08:36 +03:00
0031757: Visualization - Prebuild BVH for Select3D_SensitiveEntity in separate threads
- Added a new mode in SelectMgr_ViewerSelector for computing BVH for Select3D_SensitiveEntity in background which can be activated via method SelectMgr_ViewerSelector::SetToPrebuildBVH(). Default behavior has not been changed. - New class SelectMgr_BVHThreadPool manages background processing of BVH building queue. - Added Select3D_SensitiveEntity::ToBuildBVH() method that checks if BVH (if it used) is in invalidated state. Defined this method for all standard classes inherited from Select3D_SensitiveEntity.
This commit is contained in:
parent
ee3280a94f
commit
6a2fb7a1d1
@ -518,8 +518,6 @@ void AIS_ColoredShape::ComputeSelection (const Handle(SelectMgr_Selection)& theS
|
|||||||
const Handle(SelectMgr_EntityOwner)& anOwner = aSelEntIter.Value()->BaseSensitive()->OwnerId();
|
const Handle(SelectMgr_EntityOwner)& anOwner = aSelEntIter.Value()->BaseSensitive()->OwnerId();
|
||||||
anOwner->SetSelectable (aThis);
|
anOwner->SetSelectable (aThis);
|
||||||
}
|
}
|
||||||
|
|
||||||
StdSelect_BRepSelectionTool::PreBuildBVH (theSelection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@ -42,6 +42,8 @@ public:
|
|||||||
|
|
||||||
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE { return Standard_False; }
|
||||||
|
|
||||||
Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
|
Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
|
||||||
|
|
||||||
Standard_EXPORT virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE;
|
Standard_EXPORT virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE;
|
||||||
|
@ -652,8 +652,6 @@ void MeshVS_Mesh::ComputeSelection (const Handle(SelectMgr_Selection)& theSelect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StdSelect_BRepSelectionTool::PreBuildBVH (theSelection);
|
|
||||||
|
|
||||||
if (toShowComputeSelectionTime)
|
if (toShowComputeSelectionTime)
|
||||||
{
|
{
|
||||||
Standard_Real sec, cpu;
|
Standard_Real sec, cpu;
|
||||||
|
@ -70,6 +70,9 @@ public:
|
|||||||
//! transformation is set, it will be applied
|
//! transformation is set, it will be applied
|
||||||
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
|
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Returns TRUE if BVH tree is in invalidated state
|
||||||
|
virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE { return Standard_False; }
|
||||||
|
|
||||||
//! Dumps the content of me into the stream
|
//! Dumps the content of me into the stream
|
||||||
Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
|
Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
|
||||||
|
|
||||||
|
@ -191,6 +191,20 @@ void Select3D_SensitiveCircle::BVH()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// function : ToBuildBVH
|
||||||
|
// purpose :
|
||||||
|
//=======================================================================
|
||||||
|
Standard_Boolean Select3D_SensitiveCircle::ToBuildBVH() const
|
||||||
|
{
|
||||||
|
if (mySensType != Select3D_TOS_BOUNDARY)
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Select3D_SensitivePoly::ToBuildBVH();
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// function : Matches
|
// function : Matches
|
||||||
// purpose : Checks whether the circle overlaps current selecting volume
|
// purpose : Checks whether the circle overlaps current selecting volume
|
||||||
|
@ -81,6 +81,9 @@ public:
|
|||||||
//! Builds BVH tree for a circle's edge segments if needed
|
//! Builds BVH tree for a circle's edge segments if needed
|
||||||
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Returns TRUE if BVH tree is in invalidated state
|
||||||
|
Standard_EXPORT virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! Calculates distance from the 3d projection of used-picked screen point
|
//! Calculates distance from the 3d projection of used-picked screen point
|
||||||
|
@ -81,6 +81,9 @@ public:
|
|||||||
//! Builds BVH tree for a sensitive if needed
|
//! Builds BVH tree for a sensitive if needed
|
||||||
virtual void BVH() {}
|
virtual void BVH() {}
|
||||||
|
|
||||||
|
//! Returns TRUE if BVH tree is in invalidated state
|
||||||
|
virtual Standard_Boolean ToBuildBVH() const { return Standard_True; }
|
||||||
|
|
||||||
//! Clears up all resources and memory
|
//! Clears up all resources and memory
|
||||||
virtual void Clear() { Set (Handle(SelectMgr_EntityOwner)()); }
|
virtual void Clear() { Set (Handle(SelectMgr_EntityOwner)()); }
|
||||||
|
|
||||||
|
@ -70,6 +70,9 @@ public:
|
|||||||
//! Builds BVH tree for the face
|
//! Builds BVH tree for the face
|
||||||
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Returns TRUE if BVH tree is in invalidated state
|
||||||
|
virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE { return myFacePoints->ToBuildBVH(); }
|
||||||
|
|
||||||
//! Returns the amount of sub-entities (points or planar convex polygons)
|
//! Returns the amount of sub-entities (points or planar convex polygons)
|
||||||
Standard_EXPORT virtual Standard_Integer NbSubElements() const Standard_OVERRIDE;
|
Standard_EXPORT virtual Standard_Integer NbSubElements() const Standard_OVERRIDE;
|
||||||
|
|
||||||
|
@ -50,6 +50,9 @@ public:
|
|||||||
//! transformation is set, it will be applied
|
//! transformation is set, it will be applied
|
||||||
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
|
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Returns TRUE if BVH tree is in invalidated state
|
||||||
|
virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE { return Standard_False; }
|
||||||
|
|
||||||
//! Dumps the content of me into the stream
|
//! Dumps the content of me into the stream
|
||||||
Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
|
Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
|
||||||
|
|
||||||
|
@ -62,6 +62,9 @@ public:
|
|||||||
//! transformation is set, it will be applied
|
//! transformation is set, it will be applied
|
||||||
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
|
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Returns TRUE if BVH tree is in invalidated state
|
||||||
|
virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE { return Standard_False; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! changes the start Point of the Segment;
|
//! changes the start Point of the Segment;
|
||||||
|
@ -75,6 +75,9 @@ public:
|
|||||||
//! but element by element
|
//! but element by element
|
||||||
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Returns TRUE if BVH tree is in invalidated state
|
||||||
|
virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE { return myContent.IsDirty(); }
|
||||||
|
|
||||||
//! Sets the method (builder) used to construct BVH.
|
//! Sets the method (builder) used to construct BVH.
|
||||||
void SetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder) { myContent.SetBuilder (theBuilder); }
|
void SetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder) { myContent.SetBuilder (theBuilder); }
|
||||||
|
|
||||||
|
@ -62,6 +62,9 @@ public:
|
|||||||
//! will be applied
|
//! will be applied
|
||||||
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
|
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Returns TRUE if BVH tree is in invalidated state
|
||||||
|
virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE { return Standard_False; }
|
||||||
|
|
||||||
//! Returns the amount of points
|
//! Returns the amount of points
|
||||||
virtual Standard_Integer NbSubElements() const Standard_OVERRIDE { return 3; }
|
virtual Standard_Integer NbSubElements() const Standard_OVERRIDE { return 3; }
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@ SelectMgr_AndOrFilter.cxx
|
|||||||
SelectMgr_AndOrFilter.hxx
|
SelectMgr_AndOrFilter.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
|
||||||
|
180
src/SelectMgr/SelectMgr_BVHThreadPool.cxx
Normal file
180
src/SelectMgr/SelectMgr_BVHThreadPool.cxx
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
// Copyright (c) 2020 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#include <SelectMgr_BVHThreadPool.hxx>
|
||||||
|
#include <Message.hxx>
|
||||||
|
#include <OSD.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 = Max (1, theNbThreads);
|
||||||
|
myBVHThreads.Resize (1, aBVHThreadsNum, Standard_False);
|
||||||
|
|
||||||
|
Standard_Boolean toCatchFpe = OSD::ToCatchFloatingSignals();
|
||||||
|
|
||||||
|
for (Standard_Integer i = myBVHThreads.Lower(); i <= myBVHThreads.Upper(); ++i)
|
||||||
|
{
|
||||||
|
BVHThread& aThread = myBVHThreads.ChangeValue(i);
|
||||||
|
aThread.SetFunction (&BVHThread::runThread);
|
||||||
|
aThread.myPool = this;
|
||||||
|
aThread.myToCatchFpe = toCatchFpe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
Sentry aSentry (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : AddEntity
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void SelectMgr_BVHThreadPool::AddEntity (const Handle(Select3D_SensitiveEntity)& theEntity)
|
||||||
|
{
|
||||||
|
if (!theEntity->ToBuildBVH())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Standard_Mutex::Sentry aSentry (myBVHListMutex);
|
||||||
|
myBVHToBuildList.Append (theEntity);
|
||||||
|
myWakeEvent.Set();
|
||||||
|
myIdleEvent.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!myIsStarted)
|
||||||
|
{
|
||||||
|
myIsStarted = Standard_True;
|
||||||
|
for (Standard_Integer i = myBVHThreads.Lower(); i <= myBVHThreads.Upper(); ++i)
|
||||||
|
{
|
||||||
|
myBVHThreads.ChangeValue(i).Run ((Standard_Address) (&myBVHThreads.ChangeValue(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : performThread
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void SelectMgr_BVHThreadPool::BVHThread::performThread()
|
||||||
|
{
|
||||||
|
OSD::SetThreadLocalSignal (OSD::SignalMode(), myToCatchFpe);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
myPool->myWakeEvent.Wait();
|
||||||
|
|
||||||
|
if (myPool->myToStopBVHThread)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
myPool->myBVHListMutex.Lock();
|
||||||
|
if (myPool->myBVHToBuildList.IsEmpty())
|
||||||
|
{
|
||||||
|
myPool->myWakeEvent.Reset();
|
||||||
|
myPool->myIdleEvent.Set();
|
||||||
|
myPool->myBVHListMutex.Unlock();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Handle(Select3D_SensitiveEntity) anEntity = myPool->myBVHToBuildList.First();
|
||||||
|
myPool->myBVHToBuildList.RemoveFirst();
|
||||||
|
|
||||||
|
Standard_Mutex::Sentry anEntry (myMutex);
|
||||||
|
myPool->myBVHListMutex.Unlock();
|
||||||
|
|
||||||
|
if (!anEntity.IsNull())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
anEntity->BVH();
|
||||||
|
}
|
||||||
|
catch (Standard_Failure const& aFailure)
|
||||||
|
{
|
||||||
|
TCollection_AsciiString aMsg = TCollection_AsciiString (aFailure.DynamicType()->Name())
|
||||||
|
+ ": " + aFailure.GetMessageString();
|
||||||
|
Message::DefaultMessenger()->SendFail (aMsg);
|
||||||
|
}
|
||||||
|
catch (std::exception& anStdException)
|
||||||
|
{
|
||||||
|
TCollection_AsciiString aMsg = TCollection_AsciiString (typeid(anStdException).name())
|
||||||
|
+ ": " + anStdException.what();
|
||||||
|
Message::DefaultMessenger()->SendFail (aMsg);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
Message::DefaultMessenger()->SendFail ("Error: Unknown exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : runThread
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Address SelectMgr_BVHThreadPool::BVHThread::runThread (Standard_Address theTask)
|
||||||
|
{
|
||||||
|
BVHThread* aThread = static_cast<BVHThread*>(theTask);
|
||||||
|
aThread->performThread();
|
||||||
|
return NULL;
|
||||||
|
}
|
165
src/SelectMgr/SelectMgr_BVHThreadPool.hxx
Normal file
165
src/SelectMgr/SelectMgr_BVHThreadPool.hxx
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
// Copyright (c) 2020 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#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>
|
||||||
|
#include <Message_Messenger.hxx>
|
||||||
|
|
||||||
|
//! Class defining a thread pool for building BVH for the list of Select3D_SensitiveEntity within background thread(s).
|
||||||
|
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:
|
||||||
|
|
||||||
|
//! Thread with back reference to thread pool and thread mutex in it.
|
||||||
|
class BVHThread : public OSD_Thread
|
||||||
|
{
|
||||||
|
friend class SelectMgr_BVHThreadPool;
|
||||||
|
public:
|
||||||
|
|
||||||
|
BVHThread()
|
||||||
|
: OSD_Thread(),
|
||||||
|
myToCatchFpe (Standard_False)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns mutex used for BVH building
|
||||||
|
Standard_Mutex& BVHMutex()
|
||||||
|
{
|
||||||
|
return myMutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Assignment operator.
|
||||||
|
BVHThread& operator= (const BVHThread& theCopy)
|
||||||
|
{
|
||||||
|
Assign (theCopy);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Assignment operator.
|
||||||
|
void Assign (const BVHThread& theCopy)
|
||||||
|
{
|
||||||
|
OSD_Thread::Assign (theCopy);
|
||||||
|
myPool = theCopy.myPool;
|
||||||
|
myToCatchFpe = theCopy.myToCatchFpe;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Method is executed in the context of thread.
|
||||||
|
void performThread();
|
||||||
|
|
||||||
|
//! Method is executed in the context of thread.
|
||||||
|
static Standard_Address runThread (Standard_Address theTask);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SelectMgr_BVHThreadPool* myPool;
|
||||||
|
Standard_Mutex myMutex;
|
||||||
|
bool myToCatchFpe;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Queue a sensitive entity to build its BVH
|
||||||
|
Standard_EXPORT void AddEntity (const Handle(Select3D_SensitiveEntity)& theEntity);
|
||||||
|
|
||||||
|
//! Stops threads
|
||||||
|
Standard_EXPORT void StopThreads();
|
||||||
|
|
||||||
|
//! Waits for all threads finish their jobs
|
||||||
|
Standard_EXPORT void WaitThreads();
|
||||||
|
|
||||||
|
//! Returns array of threads
|
||||||
|
NCollection_Array1<BVHThread>& Threads()
|
||||||
|
{
|
||||||
|
return myBVHThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Class providing a simple interface to mutexes for list of BVHThread
|
||||||
|
class Sentry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructor - initializes the sentry object and locks list of mutexes immediately
|
||||||
|
Sentry (const Handle(SelectMgr_BVHThreadPool)& thePool)
|
||||||
|
: myPool (thePool)
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destructor - unlocks list of mutexes if already locked.
|
||||||
|
~Sentry()
|
||||||
|
{
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Lock list of mutexes
|
||||||
|
void Lock()
|
||||||
|
{
|
||||||
|
if (!myPool.IsNull())
|
||||||
|
{
|
||||||
|
for (Standard_Integer i = myPool->Threads().Lower(); i <= myPool->Threads().Upper(); ++i)
|
||||||
|
{
|
||||||
|
myPool->Threads().ChangeValue(i).BVHMutex().Lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Unlock list of mutexes
|
||||||
|
void Unlock()
|
||||||
|
{
|
||||||
|
if (!myPool.IsNull())
|
||||||
|
{
|
||||||
|
for (Standard_Integer i = myPool->Threads().Lower(); i <= myPool->Threads().Upper(); ++i)
|
||||||
|
{
|
||||||
|
myPool->Threads().ChangeValue(i).BVHMutex().Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! This method should not be called (prohibited).
|
||||||
|
Sentry (const Sentry &);
|
||||||
|
//! This method should not be called (prohibited).
|
||||||
|
Sentry& operator = (const Sentry &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Handle(SelectMgr_BVHThreadPool) myPool;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
NCollection_List<Handle(Select3D_SensitiveEntity)> myBVHToBuildList; //!< list of queued sensitive entities
|
||||||
|
NCollection_Array1<BVHThread> myBVHThreads; //!< threads to build BVH
|
||||||
|
Standard_Boolean myToStopBVHThread; //!< flag to stop BVH threads
|
||||||
|
Standard_Mutex myBVHListMutex; //!< mutex for interaction with myBVHToBuildList
|
||||||
|
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
|
@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
#include <SelectMgr_SelectionManager.hxx>
|
#include <SelectMgr_SelectionManager.hxx>
|
||||||
|
|
||||||
|
#include <Select3D_SensitiveGroup.hxx>
|
||||||
#include <SelectMgr_SelectableObject.hxx>
|
#include <SelectMgr_SelectableObject.hxx>
|
||||||
#include <SelectMgr_Selection.hxx>
|
#include <SelectMgr_Selection.hxx>
|
||||||
|
#include <StdSelect_BRepSelectionTool.hxx>
|
||||||
#include <TCollection_AsciiString.hxx>
|
#include <TCollection_AsciiString.hxx>
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SelectionManager,Standard_Transient)
|
IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SelectionManager,Standard_Transient)
|
||||||
@ -484,6 +486,8 @@ 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);
|
||||||
|
|
||||||
|
buildBVH (aNewSel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -496,6 +500,37 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildBVH (aNewSel);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================
|
||||||
|
// Function: buildBVH
|
||||||
|
// Purpose : Private Method
|
||||||
|
//==================================================
|
||||||
|
void SelectMgr_SelectionManager::buildBVH (const Handle(SelectMgr_Selection)& theSelection)
|
||||||
|
{
|
||||||
|
if (mySelector->ToPrebuildBVH())
|
||||||
|
{
|
||||||
|
for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator anIter (theSelection->Entities()); anIter.More(); anIter.Next())
|
||||||
|
{
|
||||||
|
const Handle(Select3D_SensitiveEntity)& anEntity = anIter.Value()->BaseSensitive();
|
||||||
|
mySelector->QueueBVHBuild (anEntity);
|
||||||
|
|
||||||
|
if (Handle(Select3D_SensitiveGroup) aGroup = Handle(Select3D_SensitiveGroup)::DownCast (anEntity))
|
||||||
|
{
|
||||||
|
for (Select3D_IndexedMapOfEntity::Iterator aSubEntitiesIter (aGroup->Entities()); aSubEntitiesIter.More(); aSubEntitiesIter.Next())
|
||||||
|
{
|
||||||
|
const Handle(Select3D_SensitiveEntity)& aSubEntity = aSubEntitiesIter.Value();
|
||||||
|
mySelector->QueueBVHBuild (aSubEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StdSelect_BRepSelectionTool::PreBuildBVH (theSelection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@ -117,6 +117,10 @@ private:
|
|||||||
Standard_EXPORT void loadMode (const Handle(SelectMgr_SelectableObject)& theObject,
|
Standard_EXPORT void loadMode (const Handle(SelectMgr_SelectableObject)& theObject,
|
||||||
const Standard_Integer theMode);
|
const Standard_Integer theMode);
|
||||||
|
|
||||||
|
//! In multi-thread mode queues sensitive entities to build its BVH in separate threads.
|
||||||
|
//! Otherwise, builds BVH for heavyweight entities immediately.
|
||||||
|
Standard_EXPORT void buildBVH (const Handle(SelectMgr_Selection)& theSelection);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Handle(SelectMgr_ViewerSelector) mySelector;
|
Handle(SelectMgr_ViewerSelector) mySelector;
|
||||||
|
@ -137,6 +137,7 @@ SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
|
|||||||
preferclosest(Standard_True),
|
preferclosest(Standard_True),
|
||||||
myToUpdateTolerance (Standard_True),
|
myToUpdateTolerance (Standard_True),
|
||||||
myCameraScale (1.0),
|
myCameraScale (1.0),
|
||||||
|
myToPrebuildBVH (Standard_False),
|
||||||
myCurRank (0),
|
myCurRank (0),
|
||||||
myIsLeftChildQueuedFirst (Standard_False),
|
myIsLeftChildQueuedFirst (Standard_False),
|
||||||
myEntityIdx (0)
|
myEntityIdx (0)
|
||||||
@ -579,6 +580,8 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
void SelectMgr_ViewerSelector::TraverseSensitives()
|
void SelectMgr_ViewerSelector::TraverseSensitives()
|
||||||
{
|
{
|
||||||
|
SelectMgr_BVHThreadPool::Sentry aSentry (myBVHThreadPool);
|
||||||
|
|
||||||
mystored.Clear();
|
mystored.Clear();
|
||||||
|
|
||||||
Standard_Integer aWidth;
|
Standard_Integer aWidth;
|
||||||
@ -1122,3 +1125,44 @@ void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_
|
|||||||
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myEntityIdx)
|
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myEntityIdx)
|
||||||
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent())
|
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : SetToPrebuildBVH
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void SelectMgr_ViewerSelector::SetToPrebuildBVH (Standard_Boolean theToPrebuild, Standard_Integer theThreadsNum)
|
||||||
|
{
|
||||||
|
if (!theToPrebuild && !myBVHThreadPool.IsNull())
|
||||||
|
{
|
||||||
|
myBVHThreadPool.Nullify();
|
||||||
|
}
|
||||||
|
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->AddEntity (theEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : WaitForBVHBuild
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void SelectMgr_ViewerSelector::WaitForBVHBuild()
|
||||||
|
{
|
||||||
|
if (myToPrebuildBVH)
|
||||||
|
{
|
||||||
|
myBVHThreadPool->WaitThreads();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
@ -260,6 +261,23 @@ 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);
|
||||||
|
|
||||||
|
//! Queues a sensitive entity to build its BVH
|
||||||
|
Standard_EXPORT void QueueBVHBuild(const Handle(Select3D_SensitiveEntity)& theEntity);
|
||||||
|
|
||||||
|
//! Waits BVH threads finished building
|
||||||
|
Standard_EXPORT void WaitForBVHBuild();
|
||||||
|
|
||||||
|
//! Returns TRUE if building BVH for sensitives in separate threads is enabled
|
||||||
|
Standard_Boolean ToPrebuildBVH() const
|
||||||
|
{
|
||||||
|
return myToPrebuildBVH;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Standard_EXPORT SelectMgr_ViewerSelector();
|
Standard_EXPORT SelectMgr_ViewerSelector();
|
||||||
@ -351,6 +369,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;
|
||||||
|
@ -192,8 +192,6 @@ void StdSelect_BRepSelectionTool::Load (const Handle(SelectMgr_Selection)& theSe
|
|||||||
const Handle(SelectMgr_EntityOwner)& anOwner = aSelEntIter.Value()->BaseSensitive()->OwnerId();
|
const Handle(SelectMgr_EntityOwner)& anOwner = aSelEntIter.Value()->BaseSensitive()->OwnerId();
|
||||||
anOwner->SetSelectable (theSelectableObj);
|
anOwner->SetSelectable (theSelectableObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
PreBuildBVH (theSelection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================
|
//==================================================
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
#include <NCollection_LocalArray.hxx>
|
#include <NCollection_LocalArray.hxx>
|
||||||
#include <NCollection_Vector.hxx>
|
#include <NCollection_Vector.hxx>
|
||||||
#include <OSD.hxx>
|
#include <OSD.hxx>
|
||||||
|
#include <OSD_Parallel.hxx>
|
||||||
#include <OSD_Timer.hxx>
|
#include <OSD_Timer.hxx>
|
||||||
#include <OpenGl_GraphicDriver.hxx>
|
#include <OpenGl_GraphicDriver.hxx>
|
||||||
#include <Prs3d_ShadingAspect.hxx>
|
#include <Prs3d_ShadingAspect.hxx>
|
||||||
@ -13982,6 +13983,83 @@ static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, con
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===============================================================================================
|
||||||
|
//function : VBVHPrebuid
|
||||||
|
//purpose :
|
||||||
|
//===============================================================================================
|
||||||
|
static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
|
||||||
|
{
|
||||||
|
const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
|
||||||
|
if (aCtx.IsNull())
|
||||||
|
{
|
||||||
|
Message::SendFail ("Error: no active viewer");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theNbArgs < 2)
|
||||||
|
{
|
||||||
|
Message::SendFail ("Error: command syntax is incorrect, see help");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Integer toEnable = -1;
|
||||||
|
Standard_Integer aThreadsNb = -1;
|
||||||
|
Standard_Boolean toWait = Standard_False;
|
||||||
|
|
||||||
|
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
||||||
|
{
|
||||||
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
||||||
|
anArg.LowerCase();
|
||||||
|
|
||||||
|
if (anArg == "-nbthreads"
|
||||||
|
&& anArgIter + 1 < theNbArgs)
|
||||||
|
{
|
||||||
|
aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
|
||||||
|
if (aThreadsNb < 1)
|
||||||
|
{
|
||||||
|
aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (anArg == "-wait")
|
||||||
|
{
|
||||||
|
toWait = Standard_True;
|
||||||
|
}
|
||||||
|
else if (toEnable == -1)
|
||||||
|
{
|
||||||
|
Standard_Boolean toEnableValue = Standard_True;
|
||||||
|
if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
|
||||||
|
{
|
||||||
|
toEnable = toEnableValue ? 1 : 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aThreadsNb == -1)
|
||||||
|
{
|
||||||
|
aThreadsNb = 1;
|
||||||
|
}
|
||||||
|
if (toEnable != -1)
|
||||||
|
{
|
||||||
|
aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
|
||||||
|
}
|
||||||
|
if (toWait)
|
||||||
|
{
|
||||||
|
aCtx->MainSelector()->WaitForBVHBuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : ViewerCommands
|
//function : ViewerCommands
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -14887,4 +14965,10 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
|||||||
theCommands.Add("vcolordiff" ,
|
theCommands.Add("vcolordiff" ,
|
||||||
"vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
|
"vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
|
||||||
__FILE__,VColorDiff,group);
|
__FILE__,VColorDiff,group);
|
||||||
|
theCommands.Add("vselbvhbuild",
|
||||||
|
"vselbvhbuild [{0|1}] [-nbThreads value] [-wait]"
|
||||||
|
"\n\t\t: Turns on/off prebuilding of BVH within background thread(s)"
|
||||||
|
"\n\t\t: -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1)"
|
||||||
|
"\n\t\t: -wait waits for building all of BVH",
|
||||||
|
__FILE__,VSelBvhBuild,group);
|
||||||
}
|
}
|
||||||
|
14
tests/v3d/mesh/C1
Normal file
14
tests/v3d/mesh/C1
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "OCC31757: Visualization - Prebuild BVH for Select3D_SensitiveEntity in separate threads"
|
||||||
|
puts "========"
|
||||||
|
|
||||||
|
vclear
|
||||||
|
set aShape [locate_data_file occ/Motor-c.brep]
|
||||||
|
restore $aShape s
|
||||||
|
vdisplay s
|
||||||
|
vfit
|
||||||
|
vselbvhbuild 1 -nbThreads 1
|
||||||
|
vselmode s FACE 1
|
||||||
|
vselbvhbuild -wait
|
||||||
|
vselect 0 0 512 512
|
||||||
|
vdump $imagedir/${test_image}.png
|
Loading…
x
Reference in New Issue
Block a user