mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0030058: Visualization, Select3D_SensitivePrimitiveArray - the selection is not fast enough
Select3D_SensitiveSet::Matches() has been improved to check if BVH node is fully included by selection volume and pass this information to overlapsElement()/elementIsInside() interfaces to avoid expensive partial overlapping checks for individual elements. Select3D_SensitivePrimitiveArray implements this new interface to improve partial overlapping performance. Select3D_SensitivePrimitiveArray::Matches() now handles rectangle selection for sub-elements when Elements map is defined. Added missing const to SelectMgr_BaseFrustum::Overlaps() methods. AIS_PointCloud has been extended with new selection mode for collecting selected nodes Draw Harness command vdrawparray has been extended with an option -shape allowing to create a triangulation from tessellated shape.
This commit is contained in:
@@ -259,12 +259,12 @@ void Select3D_InteriorSensitivePointSet::Swap (const Standard_Integer theIdx1,
|
||||
|
||||
// =======================================================================
|
||||
// function : overlapsElement
|
||||
// purpose : Checks whether the planar convex polygon with index theIdx
|
||||
// in myPlanarPolygons overlaps the current selecting volume
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Select3D_InteriorSensitivePointSet::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Boolean Select3D_InteriorSensitivePointSet::overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult)
|
||||
Standard_Boolean )
|
||||
{
|
||||
Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theElemIdx);
|
||||
const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (aPolygIdx);
|
||||
@@ -278,10 +278,11 @@ Standard_Boolean Select3D_InteriorSensitivePointSet::overlapsElement (SelectBasi
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Select3D_InteriorSensitivePointSet::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx)
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside)
|
||||
{
|
||||
SelectBasics_PickResult aDummy;
|
||||
return overlapsElement (theMgr, theElemIdx, aDummy);
|
||||
return overlapsElement (aDummy, theMgr, theElemIdx, theIsFullInside);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -76,13 +76,15 @@ protected:
|
||||
|
||||
//! Checks whether the planar convex polygon with index theIdx
|
||||
//! in myPlanarPolygons overlaps the current selecting volume
|
||||
Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Checks whether the entity with index theIdx is inside the current selecting volume
|
||||
Standard_EXPORT virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx) Standard_OVERRIDE;
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Calculates distance from the 3d projection of used-picked
|
||||
//! screen point to center of the geometry
|
||||
|
@@ -326,9 +326,10 @@ Standard_Integer Select3D_SensitiveGroup::Size() const
|
||||
// purpose : Checks whether the entity with index theIdx overlaps the
|
||||
// current selecting volume
|
||||
// =======================================================================
|
||||
Standard_Boolean Select3D_SensitiveGroup::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Boolean Select3D_SensitiveGroup::overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult)
|
||||
Standard_Boolean )
|
||||
{
|
||||
const Standard_Integer aSensitiveIdx = myBVHPrimIndexes.Value (theElemIdx);
|
||||
if (myEntities.FindKey (aSensitiveIdx)->Matches (theMgr, thePickResult))
|
||||
@@ -344,10 +345,11 @@ Standard_Boolean Select3D_SensitiveGroup::overlapsElement (SelectBasics_Selectin
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Select3D_SensitiveGroup::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx)
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside)
|
||||
{
|
||||
SelectBasics_PickResult aDummy;
|
||||
return overlapsElement(theMgr, theElemIdx, aDummy);
|
||||
return overlapsElement (aDummy, theMgr, theElemIdx, theIsFullInside);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -146,13 +146,15 @@ public:
|
||||
private:
|
||||
|
||||
//! Checks whether the entity with index theIdx overlaps the current selecting volume
|
||||
virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Checks whether the entity with index theIdx is inside the current selecting volume
|
||||
virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx) Standard_OVERRIDE;
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
|
||||
virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
|
||||
|
@@ -220,17 +220,23 @@ void Select3D_SensitivePoly::Swap (const Standard_Integer theIdx1,
|
||||
// theIdx overlaps the current selecting
|
||||
// volume
|
||||
//==================================================
|
||||
Standard_Boolean Select3D_SensitivePoly::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Boolean Select3D_SensitivePoly::overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult)
|
||||
Standard_Boolean theIsFullInside)
|
||||
{
|
||||
if (mySegmentIndexes.IsNull())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
else if (theIsFullInside)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
|
||||
gp_Pnt aPnt1 = myPolyg.Pnt3d (aSegmentIdx);
|
||||
gp_Pnt aPnt2 = myPolyg.Pnt3d (aSegmentIdx + 1);
|
||||
|
||||
return theMgr.Overlaps (aPnt1, aPnt2, thePickResult);
|
||||
}
|
||||
|
||||
@@ -239,10 +245,15 @@ Standard_Boolean Select3D_SensitivePoly::overlapsElement (SelectBasics_Selecting
|
||||
// Purpose :
|
||||
//==================================================
|
||||
Standard_Boolean Select3D_SensitivePoly::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx)
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside)
|
||||
{
|
||||
const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
|
||||
if (theIsFullInside)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
|
||||
return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0))
|
||||
&& theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1));
|
||||
}
|
||||
|
@@ -95,13 +95,15 @@ public:
|
||||
private:
|
||||
|
||||
//! Checks whether the segment with index theIdx overlaps the current selecting volume
|
||||
virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Checks whether the entity with index theIdx is inside the current selecting volume
|
||||
virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx) Standard_OVERRIDE;
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Calculates distance from the 3d projection of used-picked screen point
|
||||
//! to center of the geometry
|
||||
|
@@ -908,7 +908,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::Matches (SelectBasics_Selecti
|
||||
|| theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Point
|
||||
|| !toDetectRange)
|
||||
{
|
||||
if (!Select3D_SensitiveSet::Matches (theMgr, thePickResult))
|
||||
if (!matches (theMgr, thePickResult, toDetectRange))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -929,35 +929,22 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::Matches (SelectBasics_Selecti
|
||||
}
|
||||
|
||||
SelectBasics_PickResult aPickResult;
|
||||
bool isFailed = false;
|
||||
const bool toMatchAll = !theMgr.IsOverlapAllowed();
|
||||
bool hasResults = false;
|
||||
for (Standard_Integer aGroupIter = 0; aGroupIter < myBvhIndices.NbElements; ++aGroupIter)
|
||||
{
|
||||
const Standard_Integer anElemIdx = myBvhIndices.Index (aGroupIter);
|
||||
Handle(Select3D_SensitivePrimitiveArray)& aChild = myGroups->ChangeValue (anElemIdx);
|
||||
const bool isMatched = aChild->Matches (theMgr, aPickResult);
|
||||
if (!myDetectedElemMap.IsNull())
|
||||
if (aChild->Matches (theMgr, aPickResult))
|
||||
{
|
||||
myDetectedElemMap->ChangeMap().Unite (aChild->myDetectedElemMap->Map());
|
||||
}
|
||||
if (!myDetectedNodeMap.IsNull())
|
||||
{
|
||||
myDetectedNodeMap->ChangeMap().Unite (aChild->myDetectedNodeMap->Map());
|
||||
}
|
||||
|
||||
if (!isMatched)
|
||||
{
|
||||
if (toMatchAll)
|
||||
hasResults = true;
|
||||
if (!myDetectedElemMap.IsNull())
|
||||
{
|
||||
isFailed = true;
|
||||
if (!toDetectRange)
|
||||
{
|
||||
break;
|
||||
}
|
||||
myDetectedElemMap->ChangeMap().Unite (aChild->myDetectedElemMap->Map());
|
||||
}
|
||||
if (!myDetectedNodeMap.IsNull())
|
||||
{
|
||||
myDetectedNodeMap->ChangeMap().Unite (aChild->myDetectedNodeMap->Map());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thePickResult.Depth() > aPickResult.Depth())
|
||||
{
|
||||
myDetectedIdx = aGroupIter;
|
||||
@@ -965,7 +952,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::Matches (SelectBasics_Selecti
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isFailed)
|
||||
if (!hasResults)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -977,19 +964,15 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::Matches (SelectBasics_Selecti
|
||||
// function : overlapsElement
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Select3D_SensitivePrimitiveArray::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Boolean Select3D_SensitivePrimitiveArray::overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult)
|
||||
Standard_Boolean theIsFullInside)
|
||||
{
|
||||
const Standard_Integer anElemIdx = myBvhIndices.Index (theElemIdx);
|
||||
if (!myGroups.IsNull())
|
||||
{
|
||||
if (myGroups->Value (anElemIdx)->Matches (theMgr, thePickResult))
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
return myGroups->Value (anElemIdx)->Matches (theMgr, thePickResult);
|
||||
}
|
||||
|
||||
const Standard_Integer aPatchSize = myBvhIndices.PatchSize (theElemIdx);
|
||||
@@ -1019,7 +1002,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::overlapsElement (SelectBasics
|
||||
if (myToDetectNode
|
||||
|| myToDetectElem)
|
||||
{
|
||||
if (theMgr.Overlaps (aPoint, aPickResult))
|
||||
if (theIsFullInside || theMgr.Overlaps (aPoint, aPickResult))
|
||||
{
|
||||
if (aPickResult.Depth() <= myMinDepthNode)
|
||||
{
|
||||
@@ -1068,7 +1051,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::overlapsElement (SelectBasics
|
||||
|
||||
if (myToDetectElem)
|
||||
{
|
||||
if (theMgr.Overlaps (aPnts[0], aPnts[1], aPnts[2], Select3D_TOS_INTERIOR, aPickResult))
|
||||
if (theIsFullInside || theMgr.Overlaps (aPnts[0], aPnts[1], aPnts[2], Select3D_TOS_INTERIOR, aPickResult))
|
||||
{
|
||||
if (aPickResult.Depth() <= myMinDepthElem)
|
||||
{
|
||||
@@ -1087,7 +1070,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::overlapsElement (SelectBasics
|
||||
{
|
||||
for (int aNodeIter = 0; aNodeIter < 3; ++aNodeIter)
|
||||
{
|
||||
if (theMgr.Overlaps (aPnts[aNodeIter], aPickResult))
|
||||
if (theIsFullInside || theMgr.Overlaps (aPnts[aNodeIter], aPickResult))
|
||||
{
|
||||
if (aPickResult.Depth() <= myMinDepthNode)
|
||||
{
|
||||
@@ -1109,7 +1092,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::overlapsElement (SelectBasics
|
||||
{
|
||||
int aNode1 = aNodeIter == 0 ? 2 : (aNodeIter - 1);
|
||||
int aNode2 = aNodeIter;
|
||||
if (theMgr.Overlaps (aPnts[aNode1], aPnts[aNode2], aPickResult))
|
||||
if (theIsFullInside || theMgr.Overlaps (aPnts[aNode1], aPnts[aNode2], aPickResult))
|
||||
{
|
||||
if (aPickResult.Depth() <= myMinDepthEdge)
|
||||
{
|
||||
@@ -1148,13 +1131,14 @@ Standard_Real Select3D_SensitivePrimitiveArray::distanceToCOG (SelectBasics_Sele
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Select3D_SensitivePrimitiveArray::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx)
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside)
|
||||
{
|
||||
const Standard_Integer anElemIdx = myBvhIndices.Index (theElemIdx);
|
||||
if (!myGroups.IsNull())
|
||||
{
|
||||
SelectBasics_PickResult aDummy;
|
||||
return overlapsElement (theMgr, theElemIdx, aDummy);
|
||||
return myGroups->Value (anElemIdx)->Matches (theMgr, aDummy);
|
||||
}
|
||||
|
||||
const Standard_Integer aPatchSize = myBvhIndices.PatchSize (theElemIdx);
|
||||
@@ -1177,7 +1161,7 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::elementIsInside (SelectBasics
|
||||
{
|
||||
aPoint = vecToPnt (getPosVec2 (aPointIndex));
|
||||
}
|
||||
if (!theMgr.Overlaps (aPoint))
|
||||
if (!theIsFullInside && !theMgr.Overlaps (aPoint))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -1218,9 +1202,9 @@ Standard_Boolean Select3D_SensitivePrimitiveArray::elementIsInside (SelectBasics
|
||||
aPnts[2] = vecToPnt (getPosVec2 (aTriNodes[2]));
|
||||
}
|
||||
|
||||
if (!theMgr.Overlaps (aPnts[0])
|
||||
|| !theMgr.Overlaps (aPnts[1])
|
||||
|| !theMgr.Overlaps (aPnts[2]))
|
||||
if (!theIsFullInside && ( !theMgr.Overlaps (aPnts[0])
|
||||
|| !theMgr.Overlaps (aPnts[1])
|
||||
|| !theMgr.Overlaps (aPnts[2])))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
@@ -278,16 +278,18 @@ protected:
|
||||
}
|
||||
|
||||
//! Checks whether the element with index theIdx overlaps the current selecting volume
|
||||
Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
|
||||
Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
|
||||
|
||||
//! Checks whether the entity with index theIdx is inside the current selecting volume
|
||||
Standard_EXPORT virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx) Standard_OVERRIDE;
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
|
@@ -65,14 +65,26 @@ void Select3D_SensitiveSet::BVH()
|
||||
myContent.GetBVH();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
//! This structure describes the node in BVH
|
||||
struct NodeInStack
|
||||
{
|
||||
NodeInStack (Standard_Integer theId = 0,
|
||||
Standard_Boolean theIsFullInside = false) : Id (theId), IsFullInside (theIsFullInside) {}
|
||||
|
||||
Standard_Integer Id; //!< node identifier
|
||||
Standard_Boolean IsFullInside; //!< if the node is completely inside the current selection volume
|
||||
};
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Matches
|
||||
// purpose : Checks whether one or more entities of the set overlap
|
||||
// current selecting volume. Implements the traverse of BVH
|
||||
// tree built for the set
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean Select3D_SensitiveSet::Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult)
|
||||
Standard_Boolean Select3D_SensitiveSet::matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult,
|
||||
Standard_Boolean theToCheckAllInside)
|
||||
{
|
||||
myDetectedIdx = -1;
|
||||
const BVH_Tree<Standard_Real, 3, BVH_BinaryTree>* aBVH = myContent.GetBVH().get();
|
||||
@@ -82,50 +94,58 @@ Standard_Boolean Select3D_SensitiveSet::Matches (SelectBasics_SelectingVolumeMan
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
|
||||
Standard_Integer aNode = 0;
|
||||
NodeInStack aStack[BVH_Constants_MaxTreeDepth];
|
||||
NodeInStack aNode;
|
||||
|
||||
Standard_Integer aHead = -1;
|
||||
|
||||
Standard_Integer aMatchesNb = -1;
|
||||
SelectBasics_PickResult aPickResult;
|
||||
const bool toCheckFullInside = (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Point);
|
||||
for (;;)
|
||||
{
|
||||
const BVH_Vec4i& aData = aBVH->NodeInfoBuffer()[aNode];
|
||||
const BVH_Vec4i& aData = aBVH->NodeInfoBuffer()[aNode.Id];
|
||||
|
||||
if (aData.x() == 0) // is inner node
|
||||
{
|
||||
const Standard_Integer aLftIdx = aData.y();
|
||||
const Standard_Integer aRghIdx = aData.z();
|
||||
NodeInStack aLeft (aData.y(), toCheckFullInside), aRight(aData.z(), toCheckFullInside);
|
||||
Standard_Boolean toCheckLft = Standard_True, toCheckRgh = Standard_True;
|
||||
if (!aNode.IsFullInside)
|
||||
{
|
||||
toCheckLft = theMgr.Overlaps (aBVH->MinPoint (aLeft.Id), aBVH->MaxPoint (aLeft.Id), toCheckFullInside ? &aLeft.IsFullInside : NULL);
|
||||
if (!toCheckLft)
|
||||
{
|
||||
aLeft.IsFullInside = Standard_False;
|
||||
}
|
||||
|
||||
Standard_Boolean isLftInside = Standard_True;
|
||||
Standard_Boolean isRghInside = Standard_True;
|
||||
|
||||
Standard_Boolean toCheckLft = theMgr.Overlaps (aBVH->MinPoint (aLftIdx),
|
||||
aBVH->MaxPoint (aLftIdx),
|
||||
theMgr.IsOverlapAllowed() ? NULL : &isLftInside);
|
||||
|
||||
Standard_Boolean toCheckRgh = theMgr.Overlaps (aBVH->MinPoint (aRghIdx),
|
||||
aBVH->MaxPoint (aRghIdx),
|
||||
theMgr.IsOverlapAllowed() ? NULL : &isRghInside);
|
||||
toCheckRgh = theMgr.Overlaps (aBVH->MinPoint (aRight.Id), aBVH->MaxPoint (aRight.Id), toCheckFullInside ? &aRight.IsFullInside : NULL);
|
||||
if (!toCheckRgh)
|
||||
{
|
||||
aRight.IsFullInside = Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
if (!theMgr.IsOverlapAllowed()) // inclusion test
|
||||
{
|
||||
if (!toCheckLft || !toCheckRgh)
|
||||
if (!theToCheckAllInside)
|
||||
{
|
||||
return Standard_False; // no inclusion
|
||||
}
|
||||
if (!toCheckLft || !toCheckRgh)
|
||||
{
|
||||
return Standard_False; // no inclusion
|
||||
}
|
||||
|
||||
toCheckLft &= !isLftInside;
|
||||
toCheckRgh &= !isRghInside;
|
||||
// skip extra checks
|
||||
toCheckLft &= !aLeft.IsFullInside;
|
||||
toCheckRgh &= !aRight.IsFullInside;
|
||||
}
|
||||
}
|
||||
|
||||
if (toCheckLft || toCheckRgh)
|
||||
{
|
||||
aNode = toCheckLft ? aLftIdx : aRghIdx;
|
||||
|
||||
aNode = toCheckLft ? aLeft : aRight;
|
||||
if (toCheckLft && toCheckRgh)
|
||||
{
|
||||
aStack[++aHead] = aRghIdx;
|
||||
aStack[++aHead] = aRight;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -142,14 +162,18 @@ Standard_Boolean Select3D_SensitiveSet::Matches (SelectBasics_SelectingVolumeMan
|
||||
{
|
||||
if (!theMgr.IsOverlapAllowed()) // inclusion test
|
||||
{
|
||||
if (!elementIsInside (theMgr, anElemIdx))
|
||||
if (!elementIsInside (theMgr, anElemIdx, aNode.IsFullInside))
|
||||
{
|
||||
if (theToCheckAllInside)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
else // overlap test
|
||||
{
|
||||
if (!overlapsElement (theMgr, anElemIdx, aPickResult))
|
||||
if (!overlapsElement (aPickResult, theMgr, anElemIdx, aNode.IsFullInside))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -159,9 +183,8 @@ Standard_Boolean Select3D_SensitiveSet::Matches (SelectBasics_SelectingVolumeMan
|
||||
thePickResult = aPickResult;
|
||||
myDetectedIdx = anElemIdx;
|
||||
}
|
||||
|
||||
++aMatchesNb;
|
||||
}
|
||||
++aMatchesNb;
|
||||
}
|
||||
|
||||
if (aHead < 0)
|
||||
@@ -176,7 +199,8 @@ Standard_Boolean Select3D_SensitiveSet::Matches (SelectBasics_SelectingVolumeMan
|
||||
thePickResult.SetDistToGeomCenter(distanceToCOG(theMgr));
|
||||
}
|
||||
|
||||
return !theMgr.IsOverlapAllowed() || aMatchesNb != -1;
|
||||
return aMatchesNb != -1
|
||||
|| (!theToCheckAllInside && !theMgr.IsOverlapAllowed());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -64,8 +64,11 @@ public:
|
||||
|
||||
//! Checks whether one or more entities of the set overlap current selecting volume.
|
||||
//! Implements the traverse of BVH tree built for the set
|
||||
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
|
||||
virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE
|
||||
{
|
||||
return matches (theMgr, thePickResult, false);
|
||||
}
|
||||
|
||||
//! Builds BVH tree for sensitive set.
|
||||
//! Must be called manually to build BVH tree for any sensitive set
|
||||
@@ -96,15 +99,36 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
//! Checks whether the entity with index theIdx overlaps the current selecting volume.
|
||||
//! @param theMatchDepth set to the current minimum depth by Select3D_SensitiveSet; should be set to the new depth when overlapping is detected
|
||||
virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult) = 0;
|
||||
//! Checks whether one or more entities of the set overlap current selecting volume.
|
||||
//! Implements the traverse of BVH tree built for the set
|
||||
//! @param theMgr selection manager
|
||||
//! @param thePickResult picking result (for picking by ray)
|
||||
//! @param theToCheckAllInside flag indicating that even with SelectMgr_SelectingVolumeManager::IsOverlapAllowed() returning FALSE
|
||||
//! the method will return TRUE if at least one sub-element is fully inside selection volume ::elementIsInside();
|
||||
//! this is useful for entities allowing local selection of sub-elements using single Owner object.
|
||||
Standard_EXPORT Standard_Boolean matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult,
|
||||
Standard_Boolean theToCheckAllInside);
|
||||
|
||||
//! Checks whether the entity with index theIdx is inside the current selecting volume
|
||||
//! Checks whether the entity with index theIdx (partially) overlaps the current selecting volume.
|
||||
//! @param thePickResult [OUT] picking result, should update minimum depth
|
||||
//! @param theMgr [IN] selection manager
|
||||
//! @param theElemIdx [IN] element index within BVH tree to check
|
||||
//! @param theIsFullInside [IN] when TRUE indicates that entire BVH node is already inside selection volume (in case of rectangle selection);
|
||||
//! in this case algorithm might skip checking the element and just register it as detected
|
||||
virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside) = 0;
|
||||
|
||||
//! Checks whether the entity with index theIdx is (fully) inside the current selecting volume
|
||||
//! @param theMgr [IN] selection manager
|
||||
//! @param theElemIdx [IN] element index within BVH tree to check
|
||||
//! @param theIsFullInside [IN] when TRUE indicates that entire BVH node is already inside selection volume (in case of rectangle selection);
|
||||
//! in this case algorithm might skip checking the element and just register it as detected
|
||||
virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx) = 0;
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside) = 0;
|
||||
|
||||
//! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
|
||||
virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) = 0;
|
||||
|
@@ -259,12 +259,17 @@ void Select3D_SensitiveTriangulation::Swap (const Standard_Integer theIdx1,
|
||||
// purpose : Checks whether the element with index theIdx overlaps the
|
||||
// current selecting volume
|
||||
//=======================================================================
|
||||
Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult)
|
||||
Standard_Boolean theIsFullInside)
|
||||
{
|
||||
const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
|
||||
if (theIsFullInside)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
const Standard_Integer aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
|
||||
if (mySensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
Standard_Integer aSegmStartIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 1);
|
||||
@@ -296,10 +301,15 @@ Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_
|
||||
// Purpose :
|
||||
//==================================================
|
||||
Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx)
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside)
|
||||
{
|
||||
const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
|
||||
if (theIsFullInside)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
const Standard_Integer aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
|
||||
if (mySensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
const gp_Pnt& aSegmPnt1 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 1));
|
||||
|
@@ -102,16 +102,18 @@ protected:
|
||||
private:
|
||||
|
||||
//! Checks whether the element with index theIdx overlaps the current selecting volume
|
||||
virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
|
||||
virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
|
||||
|
||||
//! Checks whether the entity with index theIdx is inside the current selecting volume
|
||||
virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx) Standard_OVERRIDE;
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
|
@@ -112,9 +112,10 @@ void Select3D_SensitiveWire::Swap (const Standard_Integer theIdx1,
|
||||
// purpose : Checks whether the entity with index theIdx overlaps the
|
||||
// current selecting volume
|
||||
// =======================================================================
|
||||
Standard_Boolean Select3D_SensitiveWire::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Boolean Select3D_SensitiveWire::overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult)
|
||||
Standard_Boolean )
|
||||
{
|
||||
const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theElemIdx);
|
||||
const Handle(SelectBasics_SensitiveEntity)& aSeg = myEntities.Value (aSensitiveIdx);
|
||||
@@ -126,7 +127,8 @@ Standard_Boolean Select3D_SensitiveWire::overlapsElement (SelectBasics_Selecting
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Select3D_SensitiveWire::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx)
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean )
|
||||
{
|
||||
SelectBasics_PickResult aMatchResult;
|
||||
return myEntities.Value (myEntityIndexes.Value (theElemIdx))->Matches (theMgr, aMatchResult);
|
||||
|
@@ -73,13 +73,15 @@ public:
|
||||
protected:
|
||||
|
||||
//! Checks whether the entity with index theIdx overlaps the current selecting volume
|
||||
Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult,
|
||||
SelectBasics_SelectingVolumeManager& theMgr,
|
||||
Standard_Integer theElemIdx,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Checks whether the entity with index theIdx is inside the current selecting volume
|
||||
Standard_EXPORT virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
const Standard_Integer theElemIdx) Standard_OVERRIDE;
|
||||
Standard_Integer theElemIdx,
|
||||
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
||||
|
||||
//! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
|
||||
Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
|
||||
|
Reference in New Issue
Block a user