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).
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
{
{
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];
}
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)