1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

0030695: Visualization - selection by box should use clipping planes set for viewer - moving check on touching the clipping plane in selection only.

This commit is contained in:
nds
2019-08-07 09:42:33 +03:00
committed by bugmaster
parent 87bda9d805
commit 8996b4490a
4 changed files with 150 additions and 9 deletions

View File

@@ -291,6 +291,28 @@ public:
return aState;
}
//! Check if the given bounding box is In and touch the clipping planes
Standard_Boolean ProbeBoxTouch (const Graphic3d_BndBox3d& theBox) const
{
for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
{
if (aPlaneIter->IsBoxFullInHalfspace (theBox))
{
// within union operation, if box is entirely inside at least one half-space, others can be ignored
return Standard_False;
}
else if (!aPlaneIter->IsBoxFullOutHalfspace (theBox))
{
// the box is not fully out, and not fully in, check is it on (but not intersect)
if (ProbeBoxMaxPointHalfspace (theBox) != Graphic3d_ClipState_Out)
{
return Standard_True;
}
}
}
return Standard_False;
}
public:
//! Check if the given point is outside of the half-space (e.g. should be discarded by clipping plane).
@@ -329,6 +351,16 @@ public:
return IsPointOutHalfspace (aMaxPnt);
}
//! Check if the given bounding box is fully outside of the half-space (e.g. should be discarded by clipping plane).
Graphic3d_ClipState ProbeBoxMaxPointHalfspace (const Graphic3d_BndBox3d& theBox) const
{
const Graphic3d_Vec4d aMaxPnt (myEquation.x() > 0.0 ? theBox.CornerMax().x() : theBox.CornerMin().x(),
myEquation.y() > 0.0 ? theBox.CornerMax().y() : theBox.CornerMin().y(),
myEquation.z() > 0.0 ? theBox.CornerMax().z() : theBox.CornerMin().z(),
1.0);
return ProbePointHalfspace (aMaxPnt);
}
//! Check if the given bounding box is fully inside (or touches from inside) the half-space (e.g. NOT discarded by clipping plane).
bool IsBoxFullInHalfspace (const Graphic3d_BndBox3d& theBox) const
{

View File

@@ -378,6 +378,30 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
aMgr.SetViewClipping (theMgr.ViewClipping(), theObject->ClipPlanes());
}
if (!theMgr.ViewClipping().IsNull() &&
theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
{
Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (0), aSensitivesTree->MaxPoint (0));
// If box selection is active, and the whole sensitive tree is out of the clip planes
// selection is empty for this object
const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
{
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
if (!aPlane->IsOn())
{
continue;
}
Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
if (aState == Graphic3d_ClipState_Out) // do not process only whole trees, next check on the tree node
{
return;
}
}
}
const Standard_Integer aFirstStored = mystored.Extent() + 1;
Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
@@ -419,17 +443,51 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
}
else
{
Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
bool aClipped = false;
if (!theMgr.ViewClipping().IsNull() &&
theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
{
const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
if (aSensitive->IsActiveForSelection())
Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (aNode), aSensitivesTree->MaxPoint (aNode));
// If box selection is active, and the whole sensitive tree is out of the clip planes
// selection is empty for this object
const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
{
const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
if (!aPlane->IsOn())
{
continue;
}
Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
if (aState == Graphic3d_ClipState_Out)
{
aClipped = true;
break;
}
if (aState == Graphic3d_ClipState_On && !mySelectingVolumeMgr.IsOverlapAllowed()) // partially clipped
{
if (aPlane->ProbeBoxTouch (aBBox))
continue;
aClipped = true;
break;
}
}
}
if (!aClipped)
{
Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
{
const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
if (aSensitive->IsActiveForSelection())
{
const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
}
}
}
if (aHead < 0)

View File

@@ -160,6 +160,8 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
mySelectingVolumeMgr.BuildSelectingVolume (aMinMousePos,
aMaxMousePos);
mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)());
TraverseSensitives();
}
@@ -178,6 +180,8 @@ void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
mySelectingVolumeMgr.BuildSelectingVolume (thePolyline);
mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)());
TraverseSensitives();
}