mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0027816: Visualization - provide an API for overriding clipping planes list
Graphic3d_SequenceOfHClipPlane now inherits Standard_Transient. PrsMgr_PresentableObject, Graphic3d_Structure, Graphic3d_CStructure, V3d_View, OpenGl_View now manages the plane list by Handle. The getters ::GetClipPlanes() has been removed, setters taking non-handle ::SetClipPlanes() has been marked deprecated. OpenGl_Structure::Render() and SelectMgr_ViewerSelector::checkOverlap() now disable global (view) clipping planes for objects with flags Graphic3d_TMF_TriedronPers and Graphic3d_TMF_2d or with new flag Graphic3d_SequenceOfHClipPlane::ToOverrideGlobal(). OpenGl_Clipping now implements interface for managing clipping planes without copying the sequences. The filtering of duplicates is no more performed by OpenGl_Clipping - application is responsible to not do this. OpenGl_Clipping tries avoiding unnecessary allocations for managing list of active planes. MFC sample has been updated to use V3d_View::ClipPlanes() method.
This commit is contained in:
@@ -517,84 +517,67 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
|
||||
if (myHighlightColor)
|
||||
theWorkspace->HighlightColor = myHighlightColor;
|
||||
|
||||
// Set up plane equations for non-structure transformed global model-view matrix
|
||||
// List of planes to be applied to context state
|
||||
Handle(NCollection_Shared<Graphic3d_SequenceOfHClipPlane>) aUserPlanes, aDisabledPlanes;
|
||||
|
||||
// Collect clipping planes of structure scope
|
||||
if (!myClipPlanes.IsEmpty())
|
||||
{
|
||||
for (Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes); aClippingIter.More(); aClippingIter.Next())
|
||||
{
|
||||
const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value();
|
||||
if (!aClipPlane->IsOn())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aUserPlanes.IsNull())
|
||||
{
|
||||
aUserPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>();
|
||||
}
|
||||
aUserPlanes->Append (aClipPlane);
|
||||
}
|
||||
}
|
||||
if (!aUserPlanes.IsNull())
|
||||
{
|
||||
// add planes at loaded view matrix state
|
||||
aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes);
|
||||
|
||||
// Set OCCT state uniform variables
|
||||
aCtx->ShaderManager()->UpdateClippingState();
|
||||
}
|
||||
aCtx->ChangeClipping().SetLocalPlanes (aCtx, myClipPlanes);
|
||||
|
||||
// True if structure is fully clipped
|
||||
bool isClipped = false;
|
||||
|
||||
// Set of clipping planes that do not intersect the structure,
|
||||
// and thus can be disabled to improve rendering performance
|
||||
const Graphic3d_BndBox4f& aBBox = BoundingBox();
|
||||
if (!aCtx->Clipping().Planes().IsEmpty() && aBBox.IsValid() && TransformPersistence.Flags == Graphic3d_TMF_None)
|
||||
bool hasDisabled = false;
|
||||
if (aCtx->Clipping().IsClippingOrCappingOn())
|
||||
{
|
||||
for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aCtx->Clipping().Planes()); aPlaneIt.More(); aPlaneIt.Next())
|
||||
const Graphic3d_BndBox4f& aBBox = BoundingBox();
|
||||
if (TransformPersistence.Flags == Graphic3d_TMF_TriedronPers
|
||||
|| TransformPersistence.Flags == Graphic3d_TMF_2d
|
||||
|| (!myClipPlanes.IsNull() && myClipPlanes->ToOverrideGlobal()))
|
||||
{
|
||||
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
|
||||
if (!aPlane->IsOn())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
aCtx->ChangeClipping().DisableGlobal (aCtx);
|
||||
hasDisabled = aCtx->Clipping().HasDisabled();
|
||||
}
|
||||
|
||||
// check for clipping
|
||||
const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
|
||||
const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(),
|
||||
aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(),
|
||||
aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(),
|
||||
1.0);
|
||||
if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space
|
||||
// Set of clipping planes that do not intersect the structure,
|
||||
// and thus can be disabled to improve rendering performance
|
||||
if (aBBox.IsValid()
|
||||
&& TransformPersistence.Flags == Graphic3d_TMF_None)
|
||||
{
|
||||
for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More(); aPlaneIt.Next())
|
||||
{
|
||||
isClipped = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// check for no intersection (e.g. object is "entirely not clipped")
|
||||
const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(),
|
||||
aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(),
|
||||
aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(),
|
||||
1.0);
|
||||
if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space
|
||||
{
|
||||
aCtx->ChangeClipping().SetEnabled (aCtx, aPlane, Standard_False);
|
||||
if (aDisabledPlanes.IsNull())
|
||||
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
|
||||
if (!aPlane->IsOn())
|
||||
{
|
||||
aDisabledPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>();
|
||||
if (aUserPlanes.IsNull())
|
||||
{
|
||||
aCtx->ShaderManager()->UpdateClippingState();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for clipping
|
||||
const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
|
||||
const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(),
|
||||
aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(),
|
||||
aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(),
|
||||
1.0);
|
||||
if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space
|
||||
{
|
||||
isClipped = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// check for no intersection (e.g. object is "entirely not clipped")
|
||||
const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(),
|
||||
aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(),
|
||||
aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(),
|
||||
1.0);
|
||||
if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space
|
||||
{
|
||||
aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt, Standard_False);
|
||||
hasDisabled = true;
|
||||
}
|
||||
aDisabledPlanes->Append (aPlane);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
|
||||
|| hasDisabled)
|
||||
{
|
||||
// Set OCCT state uniform variables
|
||||
aCtx->ShaderManager()->UpdateClippingState();
|
||||
}
|
||||
}
|
||||
|
||||
// Render groups
|
||||
@@ -618,22 +601,15 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
|
||||
}
|
||||
|
||||
// Revert structure clippings
|
||||
if (!aDisabledPlanes.IsNull())
|
||||
if (hasDisabled)
|
||||
{
|
||||
// enable planes that were previously disabled
|
||||
for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aDisabledPlanes); aPlaneIt.More(); aPlaneIt.Next())
|
||||
{
|
||||
aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt.Value(), Standard_True);
|
||||
}
|
||||
if (aUserPlanes.IsNull())
|
||||
{
|
||||
aCtx->ShaderManager()->RevertClippingState();
|
||||
}
|
||||
aCtx->ChangeClipping().RestoreDisabled (aCtx);
|
||||
}
|
||||
if (!aUserPlanes.IsNull())
|
||||
aCtx->ChangeClipping().SetLocalPlanes (aCtx, Handle(Graphic3d_SequenceOfHClipPlane)());
|
||||
if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
|
||||
|| hasDisabled)
|
||||
{
|
||||
aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes);
|
||||
|
||||
// Set OCCT state uniform variables
|
||||
aCtx->ShaderManager()->RevertClippingState();
|
||||
}
|
||||
|
Reference in New Issue
Block a user