Graphic3d_ClipPlane now can define a Chain of Planes (logical AND).
OpenGl_ShaderManager - added new GLSL sub-programs for clipping plane chains.
Bnd_Range::TrimFrom(), ::TrimTo() - added auxiliary methods for trimming the range.
SelectMgr_ViewClipRange now handles non-continuous clipping range.
Graphic3d_SequenceOfHClipPlane now aggregates NCollection_Sequence instead of inheritance.
OpenGl_CappingPlaneResource - triangulation has been adjusted to make front face following CCW order.
}
}
+ //! Trims the First value in range by the given lower limit.
+ //! Marks range as Void if the given Lower value is greater than range Max.
+ void TrimFrom (const Standard_Real theValLower)
+ {
+ if (!IsVoid())
+ {
+ myFirst = Max (myFirst, theValLower);
+ }
+ }
+
+ //! Trim the Last value in range by the given Upper limit.
+ //! Marks range as Void if the given Upper value is smaller than range Max.
+ void TrimTo (const Standard_Real theValUpper)
+ {
+ if (!IsVoid())
+ {
+ myLast = Min (myLast, theValUpper);
+ }
+ }
+
//! Returns True if the value is out of this range.
Standard_Boolean IsOut (Standard_Real theValue) const
{
Graphic3d_RenderingParams.hxx
Graphic3d_RenderTransparentMethod.hxx
Graphic3d_SequenceOfGroup.hxx
+Graphic3d_SequenceOfHClipPlane.cxx
Graphic3d_SequenceOfHClipPlane.hxx
Graphic3d_SequenceOfStructure.hxx
Graphic3d_ShaderAttribute.cxx
// =======================================================================
Graphic3d_ClipPlane::Graphic3d_ClipPlane()
: myAspect (defaultAspect()),
+ myPrevInChain(NULL),
myPlane (0.0, 0.0, 1.0, 0.0),
myEquation (0.0, 0.0, 1.0, 0.0),
+ myEquationRev(0.0, 0.0,-1.0, 0.0),
+ myChainLenFwd(1),
myFlags (Graphic3d_CappingFlags_None),
myEquationMod(0),
myAspectMod (0),
// function : Graphic3d_ClipPlane
// purpose :
// =======================================================================
-Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation)
+Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Graphic3d_Vec4d& theEquation)
: myAspect (defaultAspect()),
+ myPrevInChain(NULL),
myPlane (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.w()),
myEquation (theEquation),
+ myEquationRev(0.0, 0.0,-1.0, 0.0),
+ myChainLenFwd(1),
myFlags (Graphic3d_CappingFlags_None),
myEquationMod(0),
myAspectMod (0),
myIsCapping (Standard_False)
{
makeId();
+ updateInversedPlane();
}
// =======================================================================
Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther)
: Standard_Transient(theOther),
myAspect (defaultAspect()),
+ myPrevInChain(NULL),
myPlane (theOther.myPlane),
myEquation (theOther.myEquation),
+ myEquationRev(theOther.myEquationRev),
+ myChainLenFwd(1),
myFlags (theOther.myFlags),
myEquationMod(0),
myAspectMod (0),
// =======================================================================
Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
: myAspect (defaultAspect()),
+ myPrevInChain(NULL),
myPlane (thePlane),
+ myChainLenFwd(1),
myFlags (Graphic3d_CappingFlags_None),
myEquationMod(0),
myAspectMod (0),
myIsCapping (Standard_False)
{
thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
+ updateInversedPlane();
makeId();
}
// function : SetEquation
// purpose :
// =======================================================================
-void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation)
+void Graphic3d_ClipPlane::SetEquation (const Graphic3d_Vec4d& theEquation)
{
myPlane = gp_Pln (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.w());
myEquation = theEquation;
+ updateInversedPlane();
myEquationMod++;
}
void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
{
myPlane = thePlane;
- thePlane.Coefficients (myEquation[0],
- myEquation[1],
- myEquation[2],
- myEquation[3]);
+ thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
+ updateInversedPlane();
myEquationMod++;
}
// =======================================================================
void Graphic3d_ClipPlane::SetOn (const Standard_Boolean theIsOn)
{
+ if (myPrevInChain != NULL)
+ {
+ throw Standard_ProgramError ("Graphic3d_ClipPlane::SetOn() - undefined operation for a plane in Union");
+ }
myIsOn = theIsOn;
}
myId = TCollection_AsciiString ("Graphic3d_ClipPlane_") //DynamicType()->Name()
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_CLIP_PLANE_COUNTER));
}
+
+// =======================================================================
+// function : updateChainLen
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::updateChainLen()
+{
+ myChainLenFwd = !myNextInChain.IsNull() ? (myNextInChain->myChainLenFwd + 1) : 1;
+ if (myPrevInChain != NULL)
+ {
+ myPrevInChain->updateChainLen();
+ }
+}
+
+// =======================================================================
+// function : SetChainNextPlane
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::SetChainNextPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
+{
+ ++myEquationMod;
+ if (!myNextInChain.IsNull())
+ {
+ myNextInChain->myPrevInChain = NULL;
+ }
+ myNextInChain = thePlane;
+ if (!myNextInChain.IsNull())
+ {
+ myNextInChain->myPrevInChain = this;
+ }
+ updateChainLen();
+}
#include <Aspect_HatchStyle.hxx>
#include <gp_Pln.hxx>
#include <Graphic3d_AspectFillArea3d.hxx>
+#include <Graphic3d_BndBox3d.hxx>
#include <Graphic3d_CappingFlags.hxx>
#include <Graphic3d_TextureMap.hxx>
#include <NCollection_Vec4.hxx>
#include <Standard_TypeDef.hxx>
#include <Standard_Transient.hxx>
-//! Container for properties describing graphic driver clipping planes.
-//! It is up to application to create instances of this class and specify its
-//! properties. The instances are passed into graphic driver or other facilities
-//! that implement clipping features (e.g. selection).
-//! Depending on usage context the class can be used to specify:
-//! - Global clipping applied over the whole scene.
-//! - Object-level clipping applied for each particular object.
+//! Clipping state.
+enum Graphic3d_ClipState
+{
+ Graphic3d_ClipState_Out, //!< fully outside (clipped) - should be discarded
+ Graphic3d_ClipState_In, //!< fully inside (NOT clipped) - should NOT be discarded
+ Graphic3d_ClipState_On, //!< on (not clipped / partially clipped) - should NOT be discarded
+};
+
+//! Container for properties describing either a Clipping halfspace (single Clipping Plane),
+//! or a chain of Clipping Planes defining logical AND (conjunction) operation.
//! The plane equation is specified in "world" coordinate system.
-//! Please note that the set of planes can define convex clipping volume.
-//! Be aware that number of clip planes supported by OpenGl is implementation
-//! dependent: at least 6 planes are available. Thus, take into account
-//! number of clipping planes passed for rendering: the object planes plus
-//! the view defined ones.
class Graphic3d_ClipPlane : public Standard_Transient
{
+ DEFINE_STANDARD_RTTIEXT(Graphic3d_ClipPlane,Standard_Transient)
public:
- typedef NCollection_Vec4<Standard_Real> Equation;
+ //! Type defining XYZW (ABCD) plane equation - left for compatibility with old code using Graphic3d_ClipPlane::Equation type.
+ typedef Graphic3d_Vec4d Equation;
+
+public:
//! Default constructor.
//! Initializes clip plane container with the following properties:
//! Construct clip plane for the passed equation.
//! By default the plane is on, capping is turned off.
//! @param theEquation [in] the plane equation.
- Standard_EXPORT Graphic3d_ClipPlane (const Equation& theEquation);
+ Standard_EXPORT Graphic3d_ClipPlane (const Graphic3d_Vec4d& theEquation);
//! Construct clip plane from the passed geometrical definition.
//! By default the plane is on, capping is turned off.
//! Set 4-component equation vector for clipping plane.
//! The equation is specified in "world" coordinate system.
//! @param theEquation [in] the XYZW (or "ABCD") equation vector.
- Standard_EXPORT void SetEquation (const Equation& theEquation);
+ Standard_EXPORT void SetEquation (const Graphic3d_Vec4d& theEquation);
//! Get 4-component equation vector for clipping plane.
//! @return clipping plane equation vector.
- const Equation& GetEquation() const
- {
- return myEquation;
- }
+ const Graphic3d_Vec4d& GetEquation() const { return myEquation; }
+
+ //! Get 4-component equation vector for clipping plane.
+ //! @return clipping plane equation vector.
+ const Graphic3d_Vec4d& ReversedEquation() const { return myEquationRev; }
//! Check that the clipping plane is turned on.
//! @return boolean flag indicating whether the plane is in on or off state.
//! @return new instance of clipping plane with same properties and attributes.
Standard_EXPORT virtual Handle(Graphic3d_ClipPlane) Clone() const;
+public:
+
+ //! Return TRUE if this item defines a conjunction (logical AND) between a set of Planes.
+ //! Graphic3d_ClipPlane item defines either a Clipping halfspace (single Clipping Plane)
+ //! or a Clipping volume defined by a logical AND (conjunction) operation between a set of Planes defined as a Chain
+ //! (so that the volume cuts a space only in case if check fails for ALL Planes in the Chain).
+ //!
+ //! Note that Graphic3d_ClipPlane item cannot:
+ //! - Define a Chain with logical OR (disjunction) operation;
+ //! this should be done through Graphic3d_SequenceOfHClipPlane.
+ //! - Define nested Chains.
+ //! - Disable Chain items; only entire Chain can be disabled (by disabled a head of Chain).
+ //!
+ //! The head of a Chain defines all visual properties of the Chain,
+ //! so that Graphic3d_ClipPlane of next items in a Chain merely defines only geometrical definition of the plane.
+ Standard_Boolean IsChain() const { return !myNextInChain.IsNull(); }
+
+ //! Return the previous plane in a Chain of Planes defining logical AND operation,
+ //! or NULL if there is no Chain or it is a first element in Chain.
+ //! When clipping is defined by a Chain of Planes,
+ //! it cuts a space only in case if check fails for all Planes in Chain.
+ Handle(Graphic3d_ClipPlane) ChainPreviousPlane() const { return myPrevInChain; }
+
+ //! Return the next plane in a Chain of Planes defining logical AND operation,
+ //! or NULL if there is no chain or it is a last element in chain.
+
+ const Handle(Graphic3d_ClipPlane)& ChainNextPlane() const { return myNextInChain; }
+
+ //! Return the number of chains in forward direction (including this item, so it is always >= 1).
+ //! For a head of Chain - returns the length of entire Chain.
+ Standard_Integer NbChainNextPlanes() const { return myChainLenFwd; }
+
+ //! Set the next plane in a Chain of Planes.
+ //! This operation also updates relationship between chains (Previous/Next items),
+ //! so that the previously set Next plane is cut off.
+ Standard_EXPORT void SetChainNextPlane (const Handle(Graphic3d_ClipPlane)& thePlane);
+
public: // @name user-defined graphical attributes
//! Set material for rendering capping surface.
//! Return true if some fill area aspect properties should be taken from object.
bool ToUseObjectProperties() const { return myFlags != Graphic3d_CappingFlags_None; }
+public:
+
+ //! Check if the given point is outside / inside / on section.
+ Graphic3d_ClipState ProbePoint (const Graphic3d_Vec4d& thePoint) const
+ {
+ for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
+ {
+ Graphic3d_ClipState aPlnState = aPlaneIter->ProbePointHalfspace (thePoint);
+ if (aPlnState == Graphic3d_ClipState_On)
+ {
+ return Graphic3d_ClipState_On;
+ }
+ else if (aPlnState == Graphic3d_ClipState_Out
+ && aPlaneIter->myNextInChain.IsNull())
+ {
+ return Graphic3d_ClipState_Out;
+ }
+ }
+ return Graphic3d_ClipState_In;
+ }
+
+ //! Check if the given bounding box is fully outside / fully inside.
+ Graphic3d_ClipState ProbeBox (const Graphic3d_BndBox3d& theBox) const
+ {
+ Graphic3d_ClipState aPrevState = Graphic3d_ClipState_On;
+ for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
+ {
+ if (aPlaneIter->IsBoxFullOutHalfspace (theBox))
+ {
+ if (aPlaneIter->myNextInChain.IsNull())
+ {
+ return Graphic3d_ClipState_Out;
+ }
+ else if (aPrevState == Graphic3d_ClipState_In)
+ {
+ return Graphic3d_ClipState_On;
+ }
+ aPrevState = Graphic3d_ClipState_Out;
+ }
+ else if (aPlaneIter->IsBoxFullInHalfspace (theBox))
+ {
+ if (aPlaneIter->myNextInChain.IsNull())
+ {
+ return Graphic3d_ClipState_In;
+ }
+ else if (aPrevState == Graphic3d_ClipState_Out)
+ {
+ return Graphic3d_ClipState_On;
+ }
+ aPrevState = Graphic3d_ClipState_In;
+ }
+ else
+ {
+ return Graphic3d_ClipState_On;
+ }
+ }
+ return Graphic3d_ClipState_On;
+ }
+
+public:
+
+ //! Check if the given point is outside of the half-space (e.g. should be discarded by clipping plane).
+ Graphic3d_ClipState ProbePointHalfspace (const Graphic3d_Vec4d& thePoint) const
+ {
+ const Standard_Real aVal = myEquation.Dot (thePoint);
+ return aVal < 0.0
+ ? Graphic3d_ClipState_Out
+ : (aVal == 0.0
+ ? Graphic3d_ClipState_On
+ : Graphic3d_ClipState_In);
+ }
+
+ //! Check if the given bounding box is fully outside / fully inside the half-space.
+ Graphic3d_ClipState ProbeBoxHalfspace (const Graphic3d_BndBox3d& theBox) const
+ {
+ if (IsBoxFullOutHalfspace (theBox))
+ {
+ return Graphic3d_ClipState_Out;
+ }
+ return IsBoxFullInHalfspace (theBox)
+ ? Graphic3d_ClipState_In
+ : Graphic3d_ClipState_On;
+ }
+
+ //! Check if the given point is outside of the half-space (e.g. should be discarded by clipping plane).
+ bool IsPointOutHalfspace (const Graphic3d_Vec4d& thePoint) const { return ProbePointHalfspace (thePoint) == Graphic3d_ClipState_Out; }
+
+ //! Check if the given bounding box is fully outside of the half-space (e.g. should be discarded by clipping plane).
+ bool IsBoxFullOutHalfspace (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 IsPointOutHalfspace (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
+ {
+ const Graphic3d_Vec4d aMinPnt (myEquation.x() > 0.0 ? theBox.CornerMin().x() : theBox.CornerMax().x(),
+ myEquation.y() > 0.0 ? theBox.CornerMin().y() : theBox.CornerMax().y(),
+ myEquation.z() > 0.0 ? theBox.CornerMin().z() : theBox.CornerMax().z(),
+ 1.0);
+ return !IsPointOutHalfspace (aMinPnt);
+ }
+
public: // @name modification counters
//! @return modification counter for equation.
//! Set capping flag.
Standard_EXPORT void setCappingFlag (bool theToUse, int theFlag);
+ //! Update chain length in backward direction.
+ void updateChainLen();
+
+ //! Update inversed plane definition from main plane.
+ void updateInversedPlane()
+ {
+ gp_Pln aPlane = myPlane;
+ aPlane.SetAxis (aPlane.Axis().Reversed());
+ aPlane.Coefficients (myEquationRev[0], myEquationRev[1], myEquationRev[2], myEquationRev[3]);
+ }
+
private:
Handle(Graphic3d_AspectFillArea3d) myAspect; //!< fill area aspect
+ Handle(Graphic3d_ClipPlane) myNextInChain; //!< next plane in a chain of planes defining logical AND operation
+ Graphic3d_ClipPlane* myPrevInChain; //!< previous plane in a chain of planes defining logical AND operation
TCollection_AsciiString myId; //!< resource id
gp_Pln myPlane; //!< plane definition
- Equation myEquation; //!< plane equation vector
+ Graphic3d_Vec4d myEquation; //!< plane equation vector
+ Graphic3d_Vec4d myEquationRev; //!< reversed plane equation
+ Standard_Integer myChainLenFwd; //!< chain length in forward direction (including this item)
unsigned int myFlags; //!< capping flags
unsigned int myEquationMod; //!< modification counter for equation
unsigned int myAspectMod; //!< modification counter of aspect
Standard_Boolean myIsOn; //!< state of the clipping plane
Standard_Boolean myIsCapping; //!< state of graphic driver capping
-public:
-
- DEFINE_STANDARD_RTTIEXT(Graphic3d_ClipPlane,Standard_Transient)
};
DEFINE_STANDARD_HANDLE (Graphic3d_ClipPlane, Standard_Transient)
--- /dev/null
+// Copyright (c) 2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Graphic3d_SequenceOfHClipPlane.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_SequenceOfHClipPlane, Standard_Transient)
+
+// =======================================================================
+// function : Graphic3d_SequenceOfHClipPlane
+// purpose :
+// =======================================================================
+Graphic3d_SequenceOfHClipPlane::Graphic3d_SequenceOfHClipPlane()
+: myToOverrideGlobal (Standard_False)
+{
+ //
+}
+
+// =======================================================================
+// function : Append
+// purpose :
+// =======================================================================
+bool Graphic3d_SequenceOfHClipPlane::Append (const Handle(Graphic3d_ClipPlane)& theItem)
+{
+ for (NCollection_Sequence<Handle(Graphic3d_ClipPlane)>::Iterator anItemIter (myItems); anItemIter.More(); anItemIter.Next())
+ {
+ if (anItemIter.Value() == theItem)
+ {
+ return false;
+ }
+ }
+ myItems.Append (theItem);
+ return true;
+}
+
+// =======================================================================
+// function : Remove
+// purpose :
+// =======================================================================
+bool Graphic3d_SequenceOfHClipPlane::Remove (const Handle(Graphic3d_ClipPlane)& theItem)
+{
+ for (NCollection_Sequence<Handle(Graphic3d_ClipPlane)>::Iterator anItemIter (myItems); anItemIter.More(); anItemIter.Next())
+ {
+ if (anItemIter.Value() == theItem)
+ {
+ myItems.Remove (anItemIter);
+ return true;
+ }
+ }
+ return false;
+}
#define _Graphic3d_SequenceOfHClipPlane_HeaderFile
#include <NCollection_Sequence.hxx>
-#include <NCollection_Shared.hxx>
#include <Graphic3d_ClipPlane.hxx>
-//! Class defining the sequence of clipping planes.
-class Graphic3d_SequenceOfHClipPlane : public Standard_Transient, public NCollection_Sequence<Handle(Graphic3d_ClipPlane)>
+//! Class defines a Clipping Volume as a logical OR (disjunction) operation between Graphic3d_ClipPlane in sequence.
+//! Each Graphic3d_ClipPlane represents either a single Plane clipping a halfspace (direction is specified by normal),
+//! or a sub-chain of planes defining a logical AND (conjunction) operation.
+//! Therefore, this collection allows defining a Clipping Volume through the limited set of Boolean operations between clipping Planes.
+//!
+//! The Clipping Volume can be assigned either to entire View or to a specific Object;
+//! in the latter case property ToOverrideGlobal() will specify if Object planes should override (suppress) globally defined ones
+//! or extend their definition through logical OR (disjunction) operation.
+//!
+//! Note that defining (many) planes will lead to performance degradation, and Graphics Driver may limit
+//! the overall number of simultaneously active clipping planes - but at least 6 planes should be supported on all configurations.
+class Graphic3d_SequenceOfHClipPlane : public Standard_Transient
{
-DEFINE_STANDARD_RTTI_INLINE(Graphic3d_SequenceOfHClipPlane,Standard_Transient)
+ DEFINE_STANDARD_RTTIEXT(Graphic3d_SequenceOfHClipPlane, Standard_Transient)
+public:
+
+ //! Iterator through clipping planes.
+ class Iterator : public NCollection_Sequence<Handle(Graphic3d_ClipPlane)>::Iterator
+ {
+ public:
+ Iterator() {}
+ Iterator (const Graphic3d_SequenceOfHClipPlane& thePlanes) : NCollection_Sequence<Handle(Graphic3d_ClipPlane)>::Iterator (thePlanes.myItems) {}
+ Iterator (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) { Init (thePlanes); }
+
+ void Init (const Graphic3d_SequenceOfHClipPlane& thePlanes) { NCollection_Sequence<Handle(Graphic3d_ClipPlane)>::Iterator::Init (thePlanes.myItems); }
+ void Init (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
+ {
+ if (!thePlanes.IsNull())
+ {
+ NCollection_Sequence<Handle(Graphic3d_ClipPlane)>::Iterator::Init (thePlanes->myItems);
+ }
+ else
+ {
+ *this = Iterator();
+ }
+ }
+ };
+
public:
- DEFINE_STANDARD_ALLOC
- DEFINE_NCOLLECTION_ALLOC
//! Empty constructor.
- Graphic3d_SequenceOfHClipPlane() : myToOverrideGlobal (Standard_False) {}
+ Standard_EXPORT Graphic3d_SequenceOfHClipPlane();
//! Return true if local properties should override global properties.
Standard_Boolean ToOverrideGlobal() const { return myToOverrideGlobal; }
//! Setup flag defining if local properties should override global properties.
void SetOverrideGlobal (const Standard_Boolean theToOverride) { myToOverrideGlobal = theToOverride; }
-private:
+ //! Return TRUE if sequence is empty.
+ bool IsEmpty() const { return myItems.IsEmpty(); }
+
+ //! Return the number of items in sequence.
+ Standard_Integer Size() const { return myItems.Size(); }
+
+ //! Append a plane.
+ //! @return TRUE if new item has been added (FALSE if item already existed)
+ Standard_EXPORT bool Append (const Handle(Graphic3d_ClipPlane)& theItem);
+
+ //! Remove a plane.
+ //! @return TRUE if item has been found and removed
+ Standard_EXPORT bool Remove (const Handle(Graphic3d_ClipPlane)& theItem);
+
+ //! Remove a plane.
+ void Remove (Iterator& theItem) { myItems.Remove (theItem); }
+
+ //! Clear the items out.
+ void Clear()
+ {
+ myItems.Clear();
+ }
+
+ //! Return the first item in sequence.
+ const Handle(Graphic3d_ClipPlane)& First() const { return myItems.First(); }
+
+protected:
+ NCollection_Sequence<Handle(Graphic3d_ClipPlane)> myItems;
Standard_Boolean myToOverrideGlobal;
};
OpenGl_Caps.hxx
OpenGl_Clipping.cxx
OpenGl_Clipping.hxx
+OpenGl_ClippingIterator.hxx
OpenGl_Context.cxx
OpenGl_Context.hxx
OpenGl_Context_1.mm
#include <OpenGl_CappingAlgo.hxx>
+#include <OpenGl_ClippingIterator.hxx>
#include <OpenGl_Workspace.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_PrimitiveArray.hxx>
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
thePlane->Update (aContext, theAspectFace != NULL ? theAspectFace->Aspect() : Handle(Graphic3d_AspectFillArea3d)());
+ bool wasCullAllowed = theWorkspace->SetAllowFaceCulling (true);
const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace();
theWorkspace->SetAspectFace (thePlane->AspectFace());
aContext->ModelWorldState.Pop();
aContext->ApplyModelViewMatrix();
+ theWorkspace->SetAllowFaceCulling (wasCullAllowed);
theWorkspace->SetAspectFace (aFaceAspect);
}
//! Render capping for specific structure.
static void renderCappingForStructure (const Handle(OpenGl_Workspace)& theWorkspace,
const OpenGl_Structure& theStructure,
- const OpenGl_ClippingIterator& thePlaneIter,
+ const Handle(Graphic3d_ClipPlane)& theClipChain,
+ const Standard_Integer theSubPlaneIndex,
const Handle(OpenGl_CappingPlaneResource)& thePlane)
{
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
}
// enable only the rendering plane to generate stencil mask
- aContext->ChangeClipping().DisableAllExcept (aContext, thePlaneIter);
+ aContext->ChangeClipping().DisableAllExcept (theClipChain, theSubPlaneIndex);
aContext->ShaderManager()->UpdateClippingState();
glClear (GL_STENCIL_BUFFER_BIT);
theWorkspace->ApplyAspectFace();
// enable all clip plane except the rendered one
- aContext->ChangeClipping().EnableAllExcept (aContext, thePlaneIter);
+ aContext->ChangeClipping().EnableAllExcept (theClipChain, theSubPlaneIndex);
aContext->ShaderManager()->UpdateClippingState();
// render capping plane using the generated stencil mask
glEnable (GL_DEPTH_TEST);
}
- renderPlane (theWorkspace, thePlane, aRenderPlane->ToUseObjectProperties()
- ? aGroupIter.Value()->AspectFace()
- : NULL);
+ renderPlane (theWorkspace, thePlane,
+ aRenderPlane->ToUseObjectProperties() ? aGroupIter.Value()->AspectFace() : NULL);
// turn on the current plane to restore initial state
- aContext->ChangeClipping().SetEnabled (aContext, thePlaneIter, Standard_True);
+ aContext->ChangeClipping().ResetCappingFilter();
aContext->ShaderManager()->RevertClippingState();
aContext->ShaderManager()->RevertClippingState();
}
if (theStructure.InstancedStructure() != NULL)
{
- renderCappingForStructure (theWorkspace, *theStructure.InstancedStructure(), thePlaneIter, thePlane);
+ renderCappingForStructure (theWorkspace, *theStructure.InstancedStructure(), theClipChain, theSubPlaneIndex, thePlane);
}
}
}
for (OpenGl_ClippingIterator aCappingIt (aContext->Clipping()); aCappingIt.More(); aCappingIt.Next())
{
// get plane being rendered
- const Handle(Graphic3d_ClipPlane)& aRenderPlane = aCappingIt.Value();
- if (!aRenderPlane->IsCapping()
+ const Handle(Graphic3d_ClipPlane)& aClipChain = aCappingIt.Value();
+ if (!aClipChain->IsCapping()
|| aCappingIt.IsDisabled())
{
continue;
}
- // get resource for the plane
- const TCollection_AsciiString& aResId = aRenderPlane->GetId();
- Handle(OpenGl_CappingPlaneResource) aPlaneRes;
- if (!aContext->GetResource (aResId, aPlaneRes))
+ Standard_Integer aSubPlaneIndex = 1;
+ for (const Graphic3d_ClipPlane* aSubPlaneIter = aClipChain.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get(), ++aSubPlaneIndex)
{
- // share and register for release once the resource is no longer used
- aPlaneRes = new OpenGl_CappingPlaneResource (aRenderPlane);
- aContext->ShareResource (aResId, aPlaneRes);
- }
+ // get resource for the plane
+ const TCollection_AsciiString& aResId = aSubPlaneIter->GetId();
+ Handle(OpenGl_CappingPlaneResource) aPlaneRes;
+ if (!aContext->GetResource (aResId, aPlaneRes))
+ {
+ // share and register for release once the resource is no longer used
+ aPlaneRes = new OpenGl_CappingPlaneResource (aSubPlaneIter);
+ aContext->ShareResource (aResId, aPlaneRes);
+ }
- renderCappingForStructure (theWorkspace, theStructure, aCappingIt, aPlaneRes);
+ renderCappingForStructure (theWorkspace, theStructure, aClipChain, aSubPlaneIndex, aPlaneRes);
- // set delayed resource release
- aPlaneRes.Nullify();
- aContext->ReleaseResource (aResId, Standard_True);
+ // set delayed resource release
+ aPlaneRes.Nullify();
+ aContext->ReleaseResource (aResId, Standard_True);
+ }
}
// restore previous application state
//! - 4 floats, UV texture coordinates
static const GLfloat THE_CAPPING_PLN_VERTS[12 * (4 + 4 + 4)] =
{
- 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
- 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,
- -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
- -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
- 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
- 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
+ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f
};
static const OpenGl_Matrix OpenGl_IdentityMatrix =
#include <OpenGl_Clipping.hxx>
-#include <OpenGl_GlCore11.hxx>
-#include <OpenGl_Workspace.hxx>
-#include <OpenGl_Context.hxx>
+#include <OpenGl_ClippingIterator.hxx>
// =======================================================================
-// function : OpenGl_ClippingIterator
+// function : OpenGl_Clipping
// purpose :
// =======================================================================
-OpenGl_ClippingIterator::OpenGl_ClippingIterator (const OpenGl_Clipping& theClipping)
-: myDisabled (&theClipping.myDisabledPlanes),
- myCurrIndex (1)
-{
- if (!theClipping.myPlanesGlobal.IsNull())
- {
- myIter1.Init (*theClipping.myPlanesGlobal);
- }
- if (!theClipping.myPlanesLocal.IsNull())
- {
- myIter2.Init (*theClipping.myPlanesLocal);
- }
-}
-
-// =======================================================================
-// function : OpenGl_ClippingState
-// purpose :
-// =======================================================================
-OpenGl_Clipping::OpenGl_Clipping ()
-: myNbClipping (0),
+OpenGl_Clipping::OpenGl_Clipping()
+: myCappedSubPlane (0),
+ myNbClipping (0),
myNbCapping (0),
+ myNbChains (0),
myNbDisabled (0)
{}
// function : Init
// purpose :
// =======================================================================
-void OpenGl_Clipping::Init (const Standard_Integer )
+void OpenGl_Clipping::Init()
{
myPlanesGlobal.Nullify();
myPlanesLocal.Nullify();
myNbClipping = 0;
myNbCapping = 0;
+ myNbChains = 0;
myNbDisabled = 0;
+ myCappedSubPlane = 0;
+ myCappedChain.Nullify();
}
// =======================================================================
// function : Reset
// purpose :
// =======================================================================
-void OpenGl_Clipping::Reset (const Handle(OpenGl_Context)& theGlCtx,
- const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
+void OpenGl_Clipping::Reset (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
{
const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
- remove (theGlCtx, myPlanesLocal, aStartIndex);
- remove (theGlCtx, myPlanesGlobal, 1);
+ remove (myPlanesLocal, aStartIndex);
+ remove (myPlanesGlobal, 1);
myPlanesGlobal = thePlanes;
myPlanesLocal.Nullify();
- add (theGlCtx, thePlanes, 1);
+ add (thePlanes, 1);
myNbDisabled = 0;
+ myCappedSubPlane = 0;
+ myCappedChain.Nullify();
// Method ::add() implicitly extends myDisabledPlanes (NCollection_Vector::SetValue()),
// however we do not reset myDisabledPlanes and mySkipFilter beforehand to avoid redundant memory re-allocations.
// function : SetLocalPlanes
// purpose :
// =======================================================================
-void OpenGl_Clipping::SetLocalPlanes (const Handle(OpenGl_Context)& theGlCtx,
- const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
+void OpenGl_Clipping::SetLocalPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
{
const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
- remove (theGlCtx, myPlanesLocal, aStartIndex);
+ remove (myPlanesLocal, aStartIndex);
myPlanesLocal = thePlanes;
- add (theGlCtx, thePlanes, aStartIndex);
+ add (thePlanes, aStartIndex);
}
// =======================================================================
// function : add
// purpose :
// =======================================================================
-void OpenGl_Clipping::add (const Handle(OpenGl_Context)& ,
- const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+void OpenGl_Clipping::add (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
const Standard_Integer theStartIndex)
{
if (thePlanes.IsNull())
continue;
}
+ const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
+ myNbChains += 1;
if (aPlane->IsCapping())
{
- ++myNbCapping;
+ myNbCapping += aNbSubPlanes;
}
else
{
- ++myNbClipping;
+ myNbClipping += aNbSubPlanes;
}
}
}
// function : remove
// purpose :
// =======================================================================
-void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& ,
- const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+void OpenGl_Clipping::remove (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
const Standard_Integer theStartIndex)
{
if (thePlanes.IsNull())
continue;
}
+ const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
+ myNbChains -= 1;
if (aPlane->IsCapping())
{
- --myNbCapping;
+ myNbCapping -= aNbSubPlanes;
}
else
{
- --myNbClipping;
+ myNbClipping -= aNbSubPlanes;
}
}
}
// function : SetEnabled
// purpose :
// =======================================================================
-Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& ,
- const OpenGl_ClippingIterator& thePlane,
+Standard_Boolean OpenGl_Clipping::SetEnabled (const OpenGl_ClippingIterator& thePlane,
const Standard_Boolean theIsEnabled)
{
const Standard_Integer aPlaneIndex = thePlane.PlaneIndex();
}
isDisabled = !theIsEnabled;
+ const Standard_Integer aNbSubPlanes = thePlane.Value()->NbChainNextPlanes();
if (thePlane.Value()->IsCapping())
{
- myNbCapping += (theIsEnabled ? 1 : -1);
+ myNbCapping += (theIsEnabled ? aNbSubPlanes : -aNbSubPlanes);
}
else
{
- myNbClipping += (theIsEnabled ? 1 : -1);
+ myNbClipping += (theIsEnabled ? aNbSubPlanes : -aNbSubPlanes);
}
- myNbDisabled -= (theIsEnabled ? 1 : -1);
+ myNbChains += (theIsEnabled ? 1 : -1);
+ myNbDisabled += (theIsEnabled ? -aNbSubPlanes : aNbSubPlanes);
return Standard_True;
}
// function : RestoreDisabled
// purpose :
// =======================================================================
-void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& )
+void OpenGl_Clipping::RestoreDisabled()
{
if (myNbDisabled == 0)
{
isDisabled = Standard_False;
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
+ const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
+ myNbChains += 1;
if (aPlane->IsCapping())
{
- ++myNbCapping;
+ myNbCapping += aNbSubPlanes;
}
else
{
- ++myNbClipping;
+ myNbClipping += aNbSubPlanes;
}
}
}
// function : DisableGlobal
// purpose :
// =======================================================================
-void OpenGl_Clipping::DisableGlobal (const Handle(OpenGl_Context)& theGlCtx)
+void OpenGl_Clipping::DisableGlobal()
{
for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
{
return;
}
- SetEnabled (theGlCtx, aPlaneIter, Standard_False);
+ SetEnabled (aPlaneIter, Standard_False);
}
}
// function : DisableAllExcept
// purpose :
// =======================================================================
-void OpenGl_Clipping::DisableAllExcept (const Handle(OpenGl_Context)& theGlCtx,
- const OpenGl_ClippingIterator& thePlane)
+void OpenGl_Clipping::DisableAllExcept (const Handle(Graphic3d_ClipPlane)& theChain,
+ const Standard_Integer theSubPlaneIndex)
{
- for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
- {
- if (aPlaneIter.IsDisabled())
- {
- mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_True);
- continue;
- }
-
- const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() == thePlane.PlaneIndex());
- SetEnabled (theGlCtx, aPlaneIter, isOn);
- mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_False);
- }
+ myCappedChain = theChain;
+ myCappedSubPlane = theSubPlaneIndex;
}
// =======================================================================
// function : EnableAllExcept
// purpose :
// =======================================================================
-void OpenGl_Clipping::EnableAllExcept (const Handle(OpenGl_Context)& theGlCtx,
- const OpenGl_ClippingIterator& thePlane)
+void OpenGl_Clipping::EnableAllExcept (const Handle(Graphic3d_ClipPlane)& theChain,
+ const Standard_Integer theSubPlaneIndex)
{
- for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
- {
- if (mySkipFilter.Value (aPlaneIter.PlaneIndex()))
- {
- continue;
- }
+ myCappedChain = theChain;
+ myCappedSubPlane = -theSubPlaneIndex;
+}
- const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() != thePlane.PlaneIndex());
- SetEnabled (theGlCtx, aPlaneIter, isOn);
- }
+// =======================================================================
+// function : ResetCappingFilter
+// purpose :
+// =======================================================================
+void OpenGl_Clipping::ResetCappingFilter()
+{
+ myCappedChain.Nullify();
+ myCappedSubPlane = 0;
}
#include <NCollection_Vector.hxx>
#include <Standard_TypeDef.hxx>
-class OpenGl_Context;
class OpenGl_ClippingIterator;
//! This class contains logics related to tracking and modification of clipping plane
//! class.
class OpenGl_Clipping
{
+ friend class OpenGl_ClippingIterator;
public: //! @name general methods
//! Default constructor.
Standard_EXPORT OpenGl_Clipping();
//! Initialize.
- //! @param theMaxPlanes [in] number of clipping planes supported by OpenGl context.
- Standard_EXPORT void Init (const Standard_Integer theMaxPlanes);
+ Standard_EXPORT void Init();
//! Setup list of global (for entire view) clipping planes
//! and clears local plane list if it was not released before.
- Standard_EXPORT void Reset (const Handle(OpenGl_Context)& theGlCtx,
- const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes);
+ Standard_EXPORT void Reset (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes);
//! Setup list of local (for current object) clipping planes.
- Standard_EXPORT void SetLocalPlanes (const Handle(OpenGl_Context)& theGlCtx,
- const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes);
-
- //! @return true if there are enabled clipping planes (NOT capping)
- Standard_Boolean IsClippingOn() const { return myNbClipping > 0; }
+ Standard_EXPORT void SetLocalPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes);
//! @return true if there are enabled capping planes
Standard_Boolean IsCappingOn() const { return myNbCapping > 0; }
//! @return true if there are enabled clipping or capping planes
- Standard_Boolean IsClippingOrCappingOn() const { return (myNbClipping + myNbCapping) > 0; }
+ Standard_Boolean IsClippingOrCappingOn() const { return NbClippingOrCappingOn() > 0; }
//! @return number of enabled clipping + capping planes
- Standard_Integer NbClippingOrCappingOn() const { return myNbClipping + myNbCapping; }
+ Standard_Integer NbClippingOrCappingOn() const
+ {
+ if (IsCappingDisableAllExcept())
+ {
+ return 1; // all Chains are disabled - only single (sub) plane is active
+ }
+ return myNbClipping + myNbCapping
+ + (IsCappingEnableAllExcept() ? -1 : 0); // exclude 1 plane with Capping filter turned ON
+ }
+
+ //! Return TRUE if there are clipping chains in the list (defining more than 1 sub-plane)
+ Standard_Boolean HasClippingChains() const
+ {
+ if (IsCappingDisableAllExcept() // all chains are disabled - only single (sub) plane is active;
+ || myNbChains == (myNbClipping + myNbCapping)) // no sub-planes
+ {
+ return Standard_False;
+ }
+ return !IsCappingEnableAllExcept()
+ || myCappedChain->NbChainNextPlanes() == 1
+ || myNbChains > 1; // if capping filter ON - chains counter should be decremented
+ }
public: //! @name advanced method for disabling defined planes
Standard_Boolean HasDisabled() const { return myNbDisabled > 0; }
//! Disable plane temporarily.
- Standard_EXPORT Standard_Boolean SetEnabled (const Handle(OpenGl_Context)& theGlCtx,
- const OpenGl_ClippingIterator& thePlane,
+ Standard_EXPORT Standard_Boolean SetEnabled (const OpenGl_ClippingIterator& thePlane,
const Standard_Boolean theIsEnabled);
//! Temporarily disable all planes from the global (view) list, keep only local (object) list.
- Standard_EXPORT void DisableGlobal (const Handle(OpenGl_Context)& theGlCtx);
+ Standard_EXPORT void DisableGlobal();
//! Restore all temporarily disabled planes.
//! Does NOT affect constantly disabled planes Graphic3d_ClipPlane::IsOn().
- Standard_EXPORT void RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx);
+ Standard_EXPORT void RestoreDisabled();
+
+//! @name capping algorithm filter
+public:
+
+ //! Chain which is either temporary disabled or the only one enabled for Capping algorithm.
+ const Handle(Graphic3d_ClipPlane)& CappedChain() const { return myCappedChain; }
+
+ //! Sub-plane index within filtered Chain; positive number for DisableAllExcept and negative for EnableAllExcept.
+ Standard_Integer CappedSubPlane() const { return myCappedSubPlane; }
+
+ //! Return TRUE if capping algorithm is in state, when all clipping planes are temporarily disabled except currently processed one.
+ bool IsCappingFilterOn() const { return !myCappedChain.IsNull(); }
+
+ //! Return TRUE if capping algorithm is in state, when all clipping planes are temporarily disabled except currently processed one.
+ bool IsCappingDisableAllExcept() const { return myCappedSubPlane > 0; }
+
+ //! Return TRUE if capping algorithm is in state, when all clipping planes are enabled except currently rendered one.
+ bool IsCappingEnableAllExcept() const { return myCappedSubPlane < 0; }
- //! Temporarily disable all planes except specified one.
+ //! Temporarily disable all planes except specified one for Capping algorithm.
//! Does not affect already disabled planes.
- Standard_EXPORT void DisableAllExcept (const Handle(OpenGl_Context)& theGlCtx,
- const OpenGl_ClippingIterator& thePlane);
+ Standard_EXPORT void DisableAllExcept (const Handle(Graphic3d_ClipPlane)& theChain,
+ const Standard_Integer theSubPlaneIndex);
- //! Enable back planes disabled by ::DisableAllExcept().
+ //! Enable back planes disabled by ::DisableAllExcept() for Capping algorithm.
//! Keeps only specified plane enabled.
- Standard_EXPORT void EnableAllExcept (const Handle(OpenGl_Context)& theGlCtx,
- const OpenGl_ClippingIterator& thePlane);
+ Standard_EXPORT void EnableAllExcept (const Handle(Graphic3d_ClipPlane)& theChain,
+ const Standard_Integer theSubPlaneIndex);
+
+ //! Resets chain filter for Capping algorithm.
+ Standard_EXPORT void ResetCappingFilter();
protected: //! @name clipping state modification commands
//! Within FFP, method also temporarily resets ModelView matrix before calling glClipPlane().
//! Otherwise the method just redirects to addLazy().
//!
- //! @param theGlCtx [in] context to access the matrices
//! @param thePlanes [in/out] the list of planes to be added
//! The list then provides information on which planes were really added to clipping state.
//! This list then can be used to fall back to previous state.
- Standard_EXPORT void add (const Handle(OpenGl_Context)& theGlCtx,
- const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+ Standard_EXPORT void add (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
const Standard_Integer theStartIndex);
//! Remove the passed set of clipping planes from the context state.
//! @param thePlanes [in] the planes to remove from list.
- Standard_EXPORT void remove (const Handle(OpenGl_Context)& theGlCtx,
- const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+ Standard_EXPORT void remove (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
const Standard_Integer theStartIndex);
private:
Handle(Graphic3d_SequenceOfHClipPlane) myPlanesGlobal; //!< global clipping planes
Handle(Graphic3d_SequenceOfHClipPlane) myPlanesLocal; //!< object clipping planes
NCollection_Vector<Standard_Boolean> myDisabledPlanes; //!< ids of disabled planes
- NCollection_Vector<Standard_Boolean> mySkipFilter; //!< ids of planes that were disabled before calling ::DisableAllExcept()
+
+ Handle(Graphic3d_ClipPlane) myCappedChain; //!< chain which is either temporary disabled or the only one enabled for Capping algorithm
+ Standard_Integer myCappedSubPlane; //!< sub-plane index within filtered chain; positive number for DisableAllExcept and negative for EnableAllExcept
+
Standard_Integer myNbClipping; //!< number of enabled clipping-only planes (NOT capping)
Standard_Integer myNbCapping; //!< number of enabled capping planes
+ Standard_Integer myNbChains; //!< number of enabled chains
Standard_Integer myNbDisabled; //!< number of defined but disabled planes
private:
-
//! Copying allowed only within Handles
OpenGl_Clipping (const OpenGl_Clipping& );
OpenGl_Clipping& operator= (const OpenGl_Clipping& );
-
- friend class OpenGl_ClippingIterator;
-};
-
-//! The iterator through clipping planes.
-class OpenGl_ClippingIterator
-{
-public:
-
- //! Main constructor.
- Standard_EXPORT OpenGl_ClippingIterator(const OpenGl_Clipping& theClipping);
-
- //! Return true if iterator points to the valid clipping plane.
- bool More() const { return myIter1.More() || myIter2.More(); }
-
- //! Go to the next clipping plane.
- void Next()
- {
- ++myCurrIndex;
- if (myIter1.More())
- {
- myIter1.Next();
- }
- else
- {
- myIter2.Next();
- }
- }
-
- //! Return true if plane has been temporarily disabled
- //! either by Graphic3d_ClipPlane->IsOn() property or by temporary filter.
- bool IsDisabled() const { return myDisabled->Value (myCurrIndex) || !Value()->IsOn(); }
-
- //! Return the plane at current iterator position.
- const Handle(Graphic3d_ClipPlane)& Value() const
- {
- return myIter1.More()
- ? myIter1.Value()
- : myIter2.Value();
- }
-
- //! Return true if plane from the global (view) list.
- bool IsGlobal() const { return myIter1.More(); }
-
- //! Return the plane index.
- Standard_Integer PlaneIndex() const { return myCurrIndex; }
-
-private:
-
- Graphic3d_SequenceOfHClipPlane::Iterator myIter1;
- Graphic3d_SequenceOfHClipPlane::Iterator myIter2;
- const NCollection_Vector<Standard_Boolean>* myDisabled;
- Standard_Integer myCurrIndex;
-
};
#endif
--- /dev/null
+// Copyright (c) 2013-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef OpenGl_ClippingIterator_Header
+#define OpenGl_ClippingIterator_Header
+
+#include <OpenGl_Clipping.hxx>
+
+//! The iterator through clipping planes.
+class OpenGl_ClippingIterator
+{
+public:
+
+ //! Main constructor.
+ OpenGl_ClippingIterator(const OpenGl_Clipping& theClipping)
+ : myDisabled (&theClipping.myDisabledPlanes),
+ myCurrIndex (1)
+ {
+ myIter1.Init (theClipping.myPlanesGlobal);
+ myIter2.Init (theClipping.myPlanesLocal);
+ }
+
+ //! Return true if iterator points to the valid clipping plane.
+ bool More() const { return myIter1.More() || myIter2.More(); }
+
+ //! Go to the next clipping plane.
+ void Next()
+ {
+ ++myCurrIndex;
+ if (myIter1.More())
+ {
+ myIter1.Next();
+ }
+ else
+ {
+ myIter2.Next();
+ }
+ }
+
+ //! Return true if plane has been temporarily disabled either by Graphic3d_ClipPlane->IsOn() property or by temporary filter.
+ //! Beware that this method does NOT handle a Chain filter for Capping algorithm OpenGl_Clipping::CappedChain()!
+ bool IsDisabled() const { return myDisabled->Value (myCurrIndex) || !Value()->IsOn(); }
+
+ //! Return the plane at current iterator position.
+ const Handle(Graphic3d_ClipPlane)& Value() const
+ {
+ return myIter1.More()
+ ? myIter1.Value()
+ : myIter2.Value();
+ }
+
+ //! Return true if plane from the global (view) list.
+ bool IsGlobal() const { return myIter1.More(); }
+
+ //! Return the plane index.
+ Standard_Integer PlaneIndex() const { return myCurrIndex; }
+
+private:
+
+ Graphic3d_SequenceOfHClipPlane::Iterator myIter1;
+ Graphic3d_SequenceOfHClipPlane::Iterator myIter2;
+ const NCollection_Vector<Standard_Boolean>* myDisabled;
+ Standard_Integer myCurrIndex;
+
+};
+
+#endif // OpenGl_ClippingIterator_Header
glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
}
- myClippingState.Init (myMaxClipPlanes);
+ myClippingState.Init();
#if !defined(GL_ES_VERSION_2_0)
const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
// Setup aspects
- theWorkspace->SetAllowFaceCulling (myIsClosed);
+ theWorkspace->SetAllowFaceCulling (myIsClosed
+ && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn());
const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine();
const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace();
const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker();
OpenGl_PO_StippleLine = 0x020, //!< stipple line
OpenGl_PO_ClipPlanes1 = 0x040, //!< handle 1 clipping plane
OpenGl_PO_ClipPlanes2 = 0x080, //!< handle 2 clipping planes
+ //OpenGl_PO_ClipPlanes3 = OpenGl_PO_ClipPlanes1|OpenGl_PO_ClipPlanes2, //!< handle 3 clipping planes - not implemented
OpenGl_PO_ClipPlanesN = 0x100, //!< handle N clipping planes
- OpenGl_PO_AlphaTest = 0x200, //!< discard fragment by alpha test (defined by cutoff value)
- OpenGl_PO_WriteOit = 0x400, //!< write coverage buffer for Blended Order-Independent Transparency
- OpenGl_PO_NB = 0x800 //!< overall number of combinations
+ OpenGl_PO_ClipChains = 0x200, //!< handle chains of clipping planes
+ OpenGl_PO_AlphaTest = 0x400, //!< discard fragment by alpha test (defined by cutoff value)
+ OpenGl_PO_WriteOit = 0x800, //!< write coverage buffer for Blended Order-Independent Transparency
+ OpenGl_PO_NB = 0x1000 //!< overall number of combinations
};
//! Alias to programs array of predefined length
#include <OpenGl_AspectLine.hxx>
#include <OpenGl_AspectMarker.hxx>
#include <OpenGl_AspectText.hxx>
-#include <OpenGl_Clipping.hxx>
+#include <OpenGl_ClippingIterator.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ShaderProgram.hxx>
EOL" }"
EOL" }";
+//! Process chains of clipping planes in Fragment Shader.
+const char THE_FRAG_CLIP_CHAINS_N[] =
+EOL" for (int aPlaneIter = 0; aPlaneIter < occClipPlaneCount;)"
+EOL" {"
+EOL" vec4 aClipEquation = occClipPlaneEquations[aPlaneIter];"
+EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0)"
+EOL" {"
+EOL" if (occClipPlaneChains[aPlaneIter] == 1)"
+EOL" {"
+EOL" discard;"
+EOL" }"
+EOL" aPlaneIter += 1;"
+EOL" }"
+EOL" else"
+EOL" {"
+EOL" aPlaneIter += occClipPlaneChains[aPlaneIter];"
+EOL" }"
+EOL" }";
+
//! Process 1 clipping plane in Fragment Shader.
const char THE_FRAG_CLIP_PLANES_1[] =
EOL" vec4 aClipEquation0 = occClipPlaneEquations[0];"
EOL" discard;"
EOL" }";
+//! Process a chain of 2 clipping planes in Fragment Shader (3/4 section).
+const char THE_FRAG_CLIP_CHAINS_2[] =
+EOL" vec4 aClipEquation0 = occClipPlaneEquations[0];"
+EOL" vec4 aClipEquation1 = occClipPlaneEquations[1];"
+EOL" if (dot (aClipEquation0.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation0.w < 0.0"
+EOL" && dot (aClipEquation1.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation1.w < 0.0)"
+EOL" {"
+EOL" discard;"
+EOL" }";
+
#if !defined(GL_ES_VERSION_2_0)
static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
Standard_Integer aPlaneId = 0;
Standard_Boolean toRestoreModelView = Standard_False;
+ const Handle(Graphic3d_ClipPlane)& aCappedChain = myContext->Clipping().CappedChain();
for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next())
{
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
- if (aPlaneIter.IsDisabled())
+ if (aPlaneIter.IsDisabled()
+ || aPlane->IsChain()
+ || (aPlane == aCappedChain
+ && myContext->Clipping().IsCappingEnableAllExcept()))
{
continue;
}
}
const Standard_Integer aNbClipPlanesMax = theProgram->NbClipPlanesMax();
- const GLint aNbPlanes = Min (myContext->Clipping().NbClippingOrCappingOn(), aNbClipPlanesMax);
- theProgram->SetUniform (myContext,
- theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT),
- aNbPlanes);
+ const Standard_Integer aNbPlanes = Min (myContext->Clipping().NbClippingOrCappingOn(), aNbClipPlanesMax);
if (aNbPlanes < 1)
{
+ theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT), 0);
return;
}
if (myClipPlaneArray.Size() < aNbClipPlanesMax)
{
myClipPlaneArray.Resize (0, aNbClipPlanesMax - 1, false);
+ myClipChainArray.Resize (0, aNbClipPlanesMax - 1, false);
}
Standard_Integer aPlaneId = 0;
+ const Handle(Graphic3d_ClipPlane)& aCappedChain = myContext->Clipping().CappedChain();
for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next())
{
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
{
continue;
}
- else if (aPlaneId >= aNbClipPlanesMax)
+
+ if (myContext->Clipping().IsCappingDisableAllExcept())
{
- myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
- TCollection_AsciiString("Warning: clipping planes limit (") + aNbClipPlanesMax + ") has been exceeded.");
+ // enable only specific (sub) plane
+ if (aPlane != aCappedChain)
+ {
+ continue;
+ }
+
+ Standard_Integer aSubPlaneIndex = 1;
+ for (const Graphic3d_ClipPlane* aSubPlaneIter = aCappedChain.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get(), ++aSubPlaneIndex)
+ {
+ if (aSubPlaneIndex == myContext->Clipping().CappedSubPlane())
+ {
+ addClippingPlane (aPlaneId, *aSubPlaneIter, aSubPlaneIter->GetEquation(), 1);
+ break;
+ }
+ }
break;
}
+ else if (aPlane == aCappedChain) // && myContext->Clipping().IsCappingEnableAllExcept()
+ {
+ // enable sub-planes within processed Chain as reversed and ORed, excluding filtered plane
+ if (aPlaneId + aPlane->NbChainNextPlanes() - 1 > aNbClipPlanesMax)
+ {
+ myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString("Error: clipping planes limit (") + aNbClipPlanesMax + ") has been exceeded.");
+ break;
+ }
- const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
- OpenGl_Vec4& aPlaneEq = myClipPlaneArray.ChangeValue (aPlaneId);
- aPlaneEq.x() = float(anEquation.x());
- aPlaneEq.y() = float(anEquation.y());
- aPlaneEq.z() = float(anEquation.z());
- aPlaneEq.w() = float(anEquation.w());
- if (myHasLocalOrigin)
+ Standard_Integer aSubPlaneIndex = 1;
+ for (const Graphic3d_ClipPlane* aSubPlaneIter = aPlane.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get(), ++aSubPlaneIndex)
+ {
+ if (aSubPlaneIndex != -myContext->Clipping().CappedSubPlane())
+ {
+ addClippingPlane (aPlaneId, *aSubPlaneIter, aSubPlaneIter->ReversedEquation(), 1);
+ }
+ }
+ }
+ else
{
- const gp_XYZ aPos = aPlane->ToPlane().Position().Location().XYZ() - myLocalOrigin;
- const Standard_Real aD = -(anEquation.x() * aPos.X() + anEquation.y() * aPos.Y() + anEquation.z() * aPos.Z());
- aPlaneEq.w() = float(aD);
+ // normal case
+ if (aPlaneId + aPlane->NbChainNextPlanes() > aNbClipPlanesMax)
+ {
+ myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString("Error: clipping planes limit (") + aNbClipPlanesMax + ") has been exceeded.");
+ break;
+ }
+ for (const Graphic3d_ClipPlane* aSubPlaneIter = aPlane.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get())
+ {
+ addClippingPlane (aPlaneId, *aSubPlaneIter, aSubPlaneIter->GetEquation(), aSubPlaneIter->NbChainNextPlanes());
+ }
}
- ++aPlaneId;
}
+ theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT), aPlaneId);
theProgram->SetUniform (myContext, aLocEquations, aNbClipPlanesMax, &myClipPlaneArray.First());
+ theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_CHAINS), aNbClipPlanesMax, &myClipChainArray.First());
}
// =======================================================================
else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
{
aNbClipPlanes = 2;
- aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_2;
+ aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
+ ? THE_FRAG_CLIP_CHAINS_2
+ : THE_FRAG_CLIP_PLANES_2;
}
else
{
aNbClipPlanes = Graphic3d_ShaderProgram::THE_MAX_CLIP_PLANES_DEFAULT;
- aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
+ aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
+ ? THE_FRAG_CLIP_CHAINS_N
+ : THE_FRAG_CLIP_PLANES_N;
}
}
if ((theBits & OpenGl_PO_WriteOit) != 0)
else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
{
aNbClipPlanes = 2;
- aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_2;
+ aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
+ ? THE_FRAG_CLIP_CHAINS_2
+ : THE_FRAG_CLIP_PLANES_2;
}
else
{
aNbClipPlanes = Graphic3d_ShaderProgram::THE_MAX_CLIP_PLANES_DEFAULT;
- aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
+ aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
+ ? THE_FRAG_CLIP_CHAINS_N
+ : THE_FRAG_CLIP_PLANES_N;
}
}
if ((theBits & OpenGl_PO_WriteOit) != 0)
else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
{
aNbClipPlanes = 2;
- aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_2;
+ aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
+ ? THE_FRAG_CLIP_CHAINS_2
+ : THE_FRAG_CLIP_PLANES_2;
}
else
{
aNbClipPlanes = Graphic3d_ShaderProgram::THE_MAX_CLIP_PLANES_DEFAULT;
- aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
+ aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
+ ? THE_FRAG_CLIP_CHAINS_N
+ : THE_FRAG_CLIP_PLANES_N;
}
}
if ((theBits & OpenGl_PO_WriteOit) != 0)
if (aNbPlanes > 0)
{
aBits |= OpenGl_PO_ClipPlanesN;
+ if (myContext->Clipping().HasClippingChains())
+ {
+ aBits |= OpenGl_PO_ClipChains;
+ }
+
if (aNbPlanes == 1)
{
aBits |= OpenGl_PO_ClipPlanes1;
OpenGl_ShaderProgramFFP() {}
};
+protected:
+
+ //! Append clipping plane definition to temporary buffers.
+ void addClippingPlane (Standard_Integer& thePlaneId,
+ const Graphic3d_ClipPlane& thePlane,
+ const Graphic3d_Vec4d& theEq,
+ const Standard_Integer theChainFwd) const
+ {
+ myClipChainArray.SetValue (thePlaneId, theChainFwd);
+ OpenGl_Vec4& aPlaneEq = myClipPlaneArray.ChangeValue (thePlaneId);
+ aPlaneEq.x() = float(theEq.x());
+ aPlaneEq.y() = float(theEq.y());
+ aPlaneEq.z() = float(theEq.z());
+ aPlaneEq.w() = float(theEq.w());
+ if (myHasLocalOrigin)
+ {
+ const gp_XYZ aPos = thePlane.ToPlane().Position().Location().XYZ() - myLocalOrigin;
+ const Standard_Real aD = -(theEq.x() * aPos.X() + theEq.y() * aPos.Y() + theEq.z() * aPos.Z());
+ aPlaneEq.w() = float(aD);
+ }
+ ++thePlaneId;
+ }
+
protected:
Handle(OpenGl_ShaderProgramFFP) myFfpProgram;
mutable NCollection_Array1<OpenGl_ShaderLightParameters> myLightParamsArray;
mutable NCollection_Array1<OpenGl_Vec4> myClipPlaneArray;
mutable NCollection_Array1<OpenGl_Vec4d> myClipPlaneArrayFfp;
+ mutable NCollection_Array1<Standard_Integer> myClipChainArray;
private:
"occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
"occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
+ "occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS
"occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT
"occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
// OpenGL clip planes state
OpenGl_OCC_CLIP_PLANE_EQUATIONS,
+ OpenGl_OCC_CLIP_PLANE_CHAINS,
OpenGl_OCC_CLIP_PLANE_COUNT,
// OpenGL light state
Standard_Integer NbLightsMax() const { return myNbLightsMax; }
//! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES),
- //! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS).
+ //! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS) and occClipPlaneChains (OpenGl_OCC_CLIP_PLANE_CHAINS).
Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; }
//! Return the length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS),
#include <OpenGl_CappingAlgo.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_GlCore11.hxx>
+#include <OpenGl_ClippingIterator.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_View.hxx>
#include <OpenGl_Workspace.hxx>
-#include <Graphic3d_SequenceOfHClipPlane.hxx>
-
-
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Structure,Graphic3d_CStructure)
//! Auxiliary class for bounding box presentation
}
// Collect clipping planes of structure scope
- aCtx->ChangeClipping().SetLocalPlanes (aCtx, myClipPlanes);
+ aCtx->ChangeClipping().SetLocalPlanes (myClipPlanes);
// True if structure is fully clipped
bool isClipped = false;
if (!myClipPlanes.IsNull()
&& myClipPlanes->ToOverrideGlobal())
{
- aCtx->ChangeClipping().DisableGlobal (aCtx);
+ aCtx->ChangeClipping().DisableGlobal();
hasDisabled = aCtx->Clipping().HasDisabled();
}
else if (!myTrsfPers.IsNull())
}
// check for clipping
- const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
- if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space
+ if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
{
isClipped = true;
break;
}
}
- aCtx->ChangeClipping().DisableGlobal (aCtx);
+ aCtx->ChangeClipping().DisableGlobal();
hasDisabled = aCtx->Clipping().HasDisabled();
}
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
+ const Graphic3d_ClipState aBoxState = aPlane->ProbeBox (aBBox);
+ if (aBoxState == Graphic3d_ClipState_Out)
{
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
+ else if (aBoxState == Graphic3d_ClipState_In)
{
- aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt, Standard_False);
+ aCtx->ChangeClipping().SetEnabled (aPlaneIt, false);
hasDisabled = true;
}
}
if (hasDisabled)
{
// enable planes that were previously disabled
- aCtx->ChangeClipping().RestoreDisabled (aCtx);
+ aCtx->ChangeClipping().RestoreDisabled();
}
- aCtx->ChangeClipping().SetLocalPlanes (aCtx, Handle(Graphic3d_SequenceOfHClipPlane)());
+ aCtx->ChangeClipping().SetLocalPlanes (Handle(Graphic3d_SequenceOfHClipPlane)());
if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
|| hasDisabled)
{
const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext();
// Specify clipping planes in view transformation space
- aContext->ChangeClipping().Reset (aContext, myClipPlanes);
+ aContext->ChangeClipping().Reset (myClipPlanes);
if (!myClipPlanes.IsNull()
&& !myClipPlanes->IsEmpty())
{
// Apply restored view matrix.
aContext->ApplyWorldViewMatrix();
- aContext->ChangeClipping().Reset (aContext, Handle(Graphic3d_SequenceOfHClipPlane)());
+ aContext->ChangeClipping().Reset (Handle(Graphic3d_SequenceOfHClipPlane)());
if (!myClipPlanes.IsNull()
&& !myClipPlanes->IsEmpty())
{
{
if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
{
- // manage back face culling mode, disable culling when clipping is enabled
bool toSuppressBackFaces = myToAllowFaceCulling
&& myAspectFaceSet->Aspect()->ToSuppressBackFaces();
if (toSuppressBackFaces)
{
- if (myGlContext->Clipping().IsClippingOrCappingOn()
- || myAspectFaceSet->Aspect()->InteriorStyle() == Aspect_IS_HATCH)
- {
- toSuppressBackFaces = false;
- }
- }
- if (toSuppressBackFaces)
- {
- if (myAspectFaceSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Blend
+ if (myAspectFaceSet->Aspect()->InteriorStyle() == Aspect_IS_HATCH
+ || myAspectFaceSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Blend
|| myAspectFaceSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Mask
|| (myAspectFaceSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_BlendAuto
&& myAspectFaceSet->Aspect()->FrontMaterial().Transparency() != 0.0f))
//! @return true if depth writing is enabled.
Standard_Boolean& UseDepthWrite() { return myUseDepthWrite; }
- //! @return true if clipping algorithm enabled
+ //! @return true if frustum culling algorithm is enabled
Standard_EXPORT Standard_Boolean IsCullingEnabled() const;
//// RELATED TO STATUS ////
//! Allow or disallow face culling.
//! This call does NOT affect current state of back face culling;
//! ApplyAspectFace() should be called to update state.
- void SetAllowFaceCulling (bool theToAllow) { myToAllowFaceCulling = theToAllow; }
+ bool SetAllowFaceCulling (bool theToAllow)
+ {
+ const bool wasAllowed = myToAllowFaceCulling;
+ myToAllowFaceCulling = theToAllow;
+ return wasAllowed;
+ }
//! Return true if following structures should apply highlight color.
bool ToHighlight() const { return !myHighlightStyle.IsNull(); }
#include <Graphic3d_Buffer.hxx>
#include <Graphic3d_IndexBuffer.hxx>
#include <Graphic3d_TypeOfPrimitiveArray.hxx>
+#include <NCollection_Shared.hxx>
#include <Select3D_SensitiveSet.hxx>
#include <Select3D_BVHIndexBuffer.hxx>
#include <TColStd_HPackedMapOfInteger.hxx>
// {i, j, k} vectors and store them to corresponding class fields
cacheVertexProjections (this);
- myViewClipRange.Clear();
+ myViewClipRange.SetVoid();
myScale = 1.0;
}
// {i, j, k} vectors and store them to corresponding class fields
cacheVertexProjections (this);
- myViewClipRange.Clear();
+ myViewClipRange.SetVoid();
myScale = 1.0;
}
// purpose :
// =======================================================================
void SelectMgr_RectangularFrustum::computeClippingRange (const Graphic3d_SequenceOfHClipPlane& thePlanes,
- Standard_Real& theDepthMin,
- Standard_Real& theDepthMax)
+ SelectMgr_ViewClipRange& theRange)
{
- theDepthMax = DBL_MAX;
- theDepthMin = -DBL_MAX;
Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes); aPlaneIt.More(); aPlaneIt.Next())
{
const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
if (!aClipPlane->IsOn())
+ {
continue;
+ }
- gp_Pln aGeomPlane = aClipPlane->ToPlane();
+ Bnd_Range aSubRange (RealFirst(), RealLast());
+ for (const Graphic3d_ClipPlane* aSubPlaneIter = aClipPlane.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get())
+ {
+ const gp_Pln aGeomPlane = aSubPlaneIter->ToPlane();
+ aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
- aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
+ const gp_XYZ& aPlaneDirXYZ = aGeomPlane.Axis().Direction().XYZ();
+ Standard_Real aDotProduct = myViewRayDir.XYZ().Dot (aPlaneDirXYZ);
+ Standard_Real aDistance = -myNearPickedPnt.XYZ().Dot (aPlaneDirXYZ) - aPlaneD;
- const gp_XYZ& aPlaneDirXYZ = aGeomPlane.Axis().Direction().XYZ();
+ // check whether the pick line is parallel to clip plane
+ if (Abs (aDotProduct) < Precision::Angular())
+ {
+ // line lies below the plane and is not clipped, skip
+ continue;
+ }
- Standard_Real aDotProduct = myViewRayDir.XYZ ().Dot (aPlaneDirXYZ);
- Standard_Real aDistance = - myNearPickedPnt.XYZ ().Dot (aPlaneDirXYZ)
- - aPlaneD;
+ // compute distance to point of pick line intersection with the plane
+ const Standard_Real aParam = aDistance / aDotProduct;
- // check whether the pick line is parallel to clip plane
- if (Abs (aDotProduct) < Precision::Angular())
- {
- // line lies below the plane and is not clipped, skip
- continue;
- }
+ const gp_Pnt anIntersectionPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aParam;
+ Standard_Real aDistToPln = anIntersectionPnt.Distance (myNearPickedPnt);
+ if (aParam < 0.0)
+ {
+ // the plane is "behind" the ray
+ aDistToPln = -aDistToPln;
+ }
- // compute distance to point of pick line intersection with the plane
- const Standard_Real aParam = aDistance / aDotProduct;
- const gp_Pnt anIntersectionPt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aParam;
- Standard_Real aDistToPln = anIntersectionPt.Distance (myNearPickedPnt);
- if (aParam < 0.0)
- {
- // the plane is "behind" the ray
- aDistToPln = -aDistToPln;
+ // change depth limits for case of opposite and directed planes
+ if (!aClipPlane->IsChain())
+ {
+ if (aDotProduct < 0.0)
+ {
+ theRange.ChangeMain().Add (Bnd_Range (aDistToPln, RealLast()));
+ }
+ else
+ {
+ theRange.ChangeMain().Add (Bnd_Range (RealFirst(), aDistToPln));
+ }
+ }
+ else
+ {
+ if (aDotProduct < 0.0)
+ {
+ aSubRange.TrimFrom (aDistToPln);
+ }
+ else
+ {
+ aSubRange.TrimTo (aDistToPln);
+ }
+ }
}
- // change depth limits for case of opposite and directed planes
- if (aDotProduct < 0.0)
- {
- theDepthMax = Min (aDistToPln, theDepthMax);
- }
- else if (aDistToPln > theDepthMin)
+ if (!aSubRange.IsVoid()
+ && aClipPlane->IsChain())
{
- theDepthMin = Max (aDistToPln, theDepthMin);
+ theRange.AddSubRange (aSubRange);
}
}
}
Standard_Boolean SelectMgr_RectangularFrustum::IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
const Standard_Real theDepth)
{
- Standard_Real aMaxDepth, aMinDepth;
- computeClippingRange (thePlanes, aMinDepth, aMaxDepth);
-
- return (theDepth <= aMinDepth || theDepth >= aMaxDepth);
+ SelectMgr_ViewClipRange aRange;
+ computeClippingRange (thePlanes, aRange);
+ return aRange.IsClipped (theDepth);
}
// =======================================================================
if (thePlanes.IsNull()
|| thePlanes->IsEmpty())
{
- myViewClipRange.Clear();
+ myViewClipRange.SetVoid();
return;
}
- Standard_Real aMaxDepth, aMinDepth;
- computeClippingRange (*thePlanes, aMinDepth, aMaxDepth);
- myViewClipRange.Set (aMinDepth, aMaxDepth);
+ computeClippingRange (*thePlanes, myViewClipRange);
}
// =======================================================================
// =======================================================================
Standard_Boolean SelectMgr_RectangularFrustum::isViewClippingOk (const Standard_Real theDepth) const
{
- if (!myViewClipRange.IsValid()
- || !myIsViewClipEnabled)
- {
- return Standard_True;
- }
-
- return myViewClipRange.MaxDepth() > theDepth
- && myViewClipRange.MinDepth() < theDepth;
+ return !myIsViewClipEnabled
+ || !myViewClipRange.IsClipped (theDepth);
}
// =======================================================================
//! Computes valid depth range for the given clipping planes
Standard_EXPORT void computeClippingRange (const Graphic3d_SequenceOfHClipPlane& thePlanes,
- Standard_Real& theDepthMin,
- Standard_Real& theDepthMax);
+ SelectMgr_ViewClipRange& theRange);
//! Returns false if theDepth must be clipped by current view clip range
Standard_EXPORT Standard_Boolean isViewClippingOk (const Standard_Real theDepth) const;
#ifndef _SelectMgr_ViewClipRange_HeaderFile
#define _SelectMgr_ViewClipRange_HeaderFile
+#include <Bnd_Range.hxx>
#include <Standard_TypeDef.hxx>
//! Class for handling depth clipping range.
//! It is used to perform checks in case if global (for the whole view)
-//! clipping planes are defined inside of SelectMgr_RectangularFrustum
-//! class methods.
+//! clipping planes are defined inside of SelectMgr_RectangularFrustum class methods.
class SelectMgr_ViewClipRange
{
public:
- //! Creates new empty view clip range
+ //! Creates an empty clip range.
SelectMgr_ViewClipRange()
{
- Clear();
+ SetVoid();
}
- //! Sets boundaries and validates view clipping range
- void Set (const Standard_Real theDepthMin, const Standard_Real theDepthMax)
+ //! Check if the given depth is not within clipping range(s),
+ //! e.g. TRUE means depth is clipped.
+ Standard_Boolean IsClipped (const Standard_Real theDepth) const
{
- myMin = theDepthMin;
- myMax = theDepthMax;
- myIsValid = Standard_True;
+ for (size_t aRangeIter = 0; aRangeIter < myRanges.size(); ++aRangeIter)
+ {
+ if (!myRanges[aRangeIter].IsOut (theDepth))
+ {
+ return Standard_True;
+ }
+ }
+ return Standard_False;
}
- //! Returns true if clip range is set and depth of each matched
- //! primitive must be tested for satisfying the defined interval
- Standard_Boolean IsValid() const
+ //! Clears clipping range.
+ void SetVoid()
{
- return myIsValid;
+ myRanges.resize (1);
+ myRanges[0].SetVoid();
}
- //! Returns the upper bound of valid depth range
- Standard_Real MaxDepth() const
- {
- return myMax;
- }
+ //! Returns the main range.
+ Bnd_Range& ChangeMain() { return myRanges[0]; }
- //! Returns the lower bound of valid depth range
- Standard_Real MinDepth() const
- {
- return myMin;
- }
-
- //! Invalidates view clipping range
- void Clear()
- {
- myIsValid = Standard_False;
- }
+ //! Adds a sub-range.
+ void AddSubRange (const Bnd_Range& theRange) { myRanges.push_back (theRange); }
private:
- Standard_Real myMin; //!< Lower bound of valid depth range
- Standard_Real myMax; //!< Upper bound of valid depth range
- Standard_Boolean myIsValid; //!< The flag is set to true when range boundaries are set and depth check must be performed
+
+ std::vector<Bnd_Range> myRanges;
+
};
#endif // _SelectMgr_ViewClipRange_HeaderFile
continue;
}
- const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
- const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
- if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space
+ const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+ if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
{
return;
}
//! Parameters of clipping planes
#if defined(THE_MAX_CLIP_PLANES) && (THE_MAX_CLIP_PLANES > 0)
uniform vec4 occClipPlaneEquations[THE_MAX_CLIP_PLANES];
+uniform THE_PREC_ENUM int occClipPlaneChains[THE_MAX_CLIP_PLANES]; //! Indicating the number of planes in the Chain
uniform THE_PREC_ENUM int occClipPlaneCount; //!< Total number of clip planes
#endif
"//! Parameters of clipping planes\n"
"#if defined(THE_MAX_CLIP_PLANES) && (THE_MAX_CLIP_PLANES > 0)\n"
"uniform vec4 occClipPlaneEquations[THE_MAX_CLIP_PLANES];\n"
+ "uniform THE_PREC_ENUM int occClipPlaneChains[THE_MAX_CLIP_PLANES]; //! Indicating the number of planes in the Chain\n"
"uniform THE_PREC_ENUM int occClipPlaneCount; //!< Total number of clip planes\n"
"#endif\n";
for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
{
- const TCollection_AsciiString& aName = aPrsIter.CurrentName();
- Handle(AIS_InteractiveObject) aPrs = aPrsIter.Current();
+ const TCollection_AsciiString& aName = aPrsIter.CurrentName();
+ Handle(AIS_InteractiveObject) aPrs = aPrsIter.Current();
+ if (aPrs.IsNull())
+ {
+ return 1;
+ }
+
Handle(Prs3d_Drawer) aDrawer = aPrs->Attributes();
Handle(AIS_ColoredShape) aColoredPrs;
Standard_Boolean toDisplay = Standard_False;
{
aClipPlane->SetOn (toEnable);
}
- else if (aChangeArg == "-equation"
- || aChangeArg == "equation")
+ else if (aChangeArg.StartsWith ("-equation")
+ || aChangeArg.StartsWith ("equation"))
{
if (aNbChangeArgs < 5)
{
return 1;
}
- Standard_Real aCoeffA = Draw::Atof (aChangeArgs [1]);
- Standard_Real aCoeffB = Draw::Atof (aChangeArgs [2]);
- Standard_Real aCoeffC = Draw::Atof (aChangeArgs [3]);
- Standard_Real aCoeffD = Draw::Atof (aChangeArgs [4]);
- aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
+ Standard_Integer aSubIndex = 1;
+ Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
+ if (aPrefixLen < aChangeArg.Length())
+ {
+ TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
+ if (!aSubStr.IsIntegerValue()
+ || aSubStr.IntegerValue() <= 0)
+ {
+ std::cout << "Syntax error: unknown argument '" << aChangeArg << "'.\n";
+ return 1;
+ }
+ aSubIndex = aSubStr.IntegerValue();
+ }
+
+ Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
+ Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
+ Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
+ Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
+ Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
+ for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
+ {
+ if (aSubPln->ChainNextPlane().IsNull())
+ {
+ aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
+ }
+ aSubPln = aSubPln->ChainNextPlane();
+ }
+ aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
+ aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
anArgIter += 4;
}
+ else if ((aChangeArg == "-boxinterior"
+ || aChangeArg == "-boxint"
+ || aChangeArg == "-box")
+ && aNbChangeArgs >= 7)
+ {
+ Graphic3d_BndBox3d aBndBox;
+ aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
+ aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
+ anArgIter += 6;
+
+ Standard_Integer aNbSubPlanes = 6;
+ const Graphic3d_Vec3d aDirArray[6] =
+ {
+ Graphic3d_Vec3d (-1, 0, 0),
+ Graphic3d_Vec3d ( 1, 0, 0),
+ Graphic3d_Vec3d ( 0,-1, 0),
+ Graphic3d_Vec3d ( 0, 1, 0),
+ Graphic3d_Vec3d ( 0, 0,-1),
+ Graphic3d_Vec3d ( 0, 0, 1),
+ };
+ Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
+ for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
+ {
+ const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
+ const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
+ aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
+ if (aSubPlaneIter + 1 == aNbSubPlanes)
+ {
+ aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
+ }
+ else
+ {
+ aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
+ }
+ aSubPln = aSubPln->ChainNextPlane();
+ }
+ }
else if (aChangeArg == "-capping"
|| aChangeArg == "capping")
{
__FILE__,VHLRType,group);
theCommands.Add("vclipplane",
"vclipplane planeName [{0|1}]"
- "\n\t\t: [-equation A B C D]"
+ "\n\t\t: [-equation1 A B C D]"
+ "\n\t\t: [-equation2 A B C D]"
+ "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
"\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
"\n\t\t: [-maxPlanes]"
"\n\t\t: [-capping {0|1}]"
+puts "REQUIRED All: Error: clipping planes limit"
puts "==========="
-puts "OCC25052"
+puts "OCC25052: Visualization - activation of all Clipping Planes within driver limit leads to broken planes management"
puts "==========="
puts ""
-##########################################################################
-# Visualization - activation of all Clipping Planes within driver limit leads to broken planes management
-##########################################################################
set Image1 ${imagedir}/${casename}_1.png
set Image9 ${imagedir}/${casename}_9.png
--- /dev/null
+puts "========"
+puts "0029729: Visualization, Graphic3d_ClipPlane - add support of clipping plane chains"
+puts "========"
+
+vclear
+vclose ALL
+vinit View1
+
+set aCapParams "-capping 1 -color 0.5 0.5 0.5 -texname [locate_data_file images/hatch_1.png] -texscale 0.02 -0.02 -useObjMaterial 1"
+
+pload MODELING VISUALIZATION
+
+# create the geometry
+box b0sole 10 10 0 30 30 70
+box b0hole 20 20 -10 10 10 90
+bcut b0 b0sole b0hole
+box b1 40 20 0 10 30 70
+box b2 20 40 0 20 10 70
+box b3 0 40 0 20 10 70
+box b4 0 10 0 10 30 70
+box b5 0 0 0 30 10 70
+
+set aNbParts 6
+set aColors { RED YELLOW GREEN GRAY MAGENTA1 ORANGE }
+
+compound b0 b1 b2 b3 b4 b5 cc
+
+# create the viewer
+vclear
+vclose ALL
+vinit name=View1 w=512 h=512
+vviewparams -scale 4.66737 -proj 0.465292 -0.577133 0.671134 -up -0.46873 0.482524 0.739907 -at 15.807 37.1157 21.9799
+
+vpoint p0 0 0 0
+vzbufftrihedron
+
+puts "Display the geometry as dedicated objects"
+for { set aPartIter 0 } { $aPartIter < $aNbParts } { incr aPartIter } {
+ vdisplay -noupdate -dispMode 1 b${aPartIter}
+ set aColor [lindex $aColors $aPartIter]
+ vsetcolor -noupdate b${aPartIter} $aColor
+}
+
+puts "Display the geometry as sole object"
+vdisplay -noupdate -dispMode 1 cc
+for { set aPartIter 0 } { $aPartIter < $aNbParts } { incr aPartIter } {
+ set aColor [lindex $aColors $aPartIter]
+ vaspects -noupdate cc -subShapes b${aPartIter} -setColor $aColor
+}
+# show also connected interactive object
+vconnectto co -70 0 0 cc
+vsetdispmode co 1
+vsetlocation cc 70 0 0
+
+set aPln1Z 40
+set aPln2Y 15
+
+vremove -noupdate p1 p2 p3 pp1 pp2
+vpoint p1 0 0 1
+vpoint p2 1 0 1
+vpoint p3 0 1 1
+vplane pp1 p1 p2 p3
+vsetlocation -noupdate pp1 25 0 [expr $aPln1Z - 1]
+vremove -noupdate p1 p2 p3
+
+vpoint p1 0 1 0
+vpoint p2 1 1 0
+vpoint p3 0 1 1
+vplane pp2 p1 p2 p3
+vsetlocation -noupdate pp2 25 $aPln2Y 35
+vremove -noupdate p1 p2 p3
+verase pp1 pp2
+vfit
+vdisplay pp1 pp2
+
+vclipplane pln -set {*}$aCapParams -equation1 0 0 -1 40 -equation2 0 1 0 -15
+vdump $::imagedir/${::casename}_2.png
+
+vclipplane pln -set {*}$aCapParams -equation1 0 0 -1 40 -equation2 0 1 0 -15 -equation3 -1 0 0 5
+vdump $::imagedir/${::casename}_3.png
+
+vsettransparency b0 b1 b2 b3 b4 b5 0.5
+vdump $::imagedir/${::casename}_3transp.png
+
+vviewparams -scale 8.51584 -proj 0.284186 0.750426 0.59674 -up -0.228109 -0.55161 0.802305 -at 24.2647 23.8116 32.8743
+vclipplane pln -set {*}$aCapParams -boxint 25 25 25 55 55 55
+vsettransparency b0 b1 b2 b3 b4 b5 0
+vdump $::imagedir/${::casename}_6.png
+
+vsettransparency b0 b1 b2 b3 b4 b5 0.5
+vdump $::imagedir/${::casename}_6transp.png