mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +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:
@@ -233,6 +233,31 @@ public:
|
||||
return aState;
|
||||
}
|
||||
|
||||
//! Check if the given bounding box is In and touch the clipping planes
|
||||
Standard_Boolean ProbeBoxTouch (const Graphic3d_BndBox3d& theBox) const
|
||||
{
|
||||
Graphic3d_ClipState aState = Graphic3d_ClipState_Out;
|
||||
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;
|
||||
}
|
||||
// if at least one full out test fail, clipping state is inconclusive (partially clipped)
|
||||
aState = Graphic3d_ClipState_On;
|
||||
}
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Check if the given point is outside of the half-space (e.g. should be discarded by clipping plane).
|
||||
@@ -271,6 +296,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
|
||||
{
|
||||
|
@@ -435,7 +435,36 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
|
||||
{
|
||||
return;
|
||||
}
|
||||
// in case of Box/Polyline selection - keep only Owners having all Entities detected
|
||||
if (!theMgr.ViewClipping().IsNull() &&
|
||||
theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
|
||||
//&& theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Polyline))
|
||||
{
|
||||
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;
|
||||
}
|
||||
//if (aState == Graphic3d_ClipState_On && !mySelectingVolumeMgr.IsOverlapAllowed()) // partially clipped
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
const Standard_Integer aFirstStored = mystored.Extent() + 1;
|
||||
|
||||
Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
|
||||
@@ -479,17 +508,52 @@ 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)
|
||||
//&& theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Polyline))
|
||||
{
|
||||
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(SelectBasics_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(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
|
||||
SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
|
||||
computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
|
||||
checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aHead < 0)
|
||||
|
@@ -175,6 +175,8 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
|
||||
mySelectingVolumeMgr.BuildSelectingVolume (aMinMousePos,
|
||||
aMaxMousePos);
|
||||
|
||||
mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes());
|
||||
|
||||
TraverseSensitives();
|
||||
}
|
||||
|
||||
@@ -193,6 +195,8 @@ void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
|
||||
mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
|
||||
mySelectingVolumeMgr.BuildSelectingVolume (thePolyline);
|
||||
|
||||
mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes());
|
||||
|
||||
TraverseSensitives();
|
||||
}
|
||||
|
||||
|
36
tests/bugs/vis/bug30695
Normal file
36
tests/bugs/vis/bug30695
Normal file
@@ -0,0 +1,36 @@
|
||||
puts "============="
|
||||
puts "0030695: Visualization - selection by box should use clipping planes set for viewer"
|
||||
puts "============="
|
||||
|
||||
pload ALL
|
||||
vinit View1
|
||||
|
||||
box b 10 10 10
|
||||
vdisplay b
|
||||
|
||||
box b1 -5 0 0 2 2 2
|
||||
vdisplay b1
|
||||
|
||||
box b2 13 0 0 2 2 2
|
||||
vdisplay b2
|
||||
|
||||
box b3 16 0 0 2 2 2
|
||||
vdisplay b3
|
||||
|
||||
vsetdispmode 1
|
||||
|
||||
vtop
|
||||
vfit
|
||||
vzoom 0.5
|
||||
vselect 40 100 370 300
|
||||
vnbselected
|
||||
|
||||
vclipplane create pln
|
||||
vclipplane set pln view Driver1/Viewer1/View1
|
||||
vclipplane change pln equation -1 0 0 5
|
||||
|
||||
vselect 40 100 370 300
|
||||
vnbselected
|
||||
|
||||
vselect 40 100 370 300 -allowoverlap 1
|
||||
vnbselected
|
Reference in New Issue
Block a user