mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
0029729: Visualization, Graphic3d_ClipPlane - add support of clipping plane chains
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.
This commit is contained in:
parent
012264339e
commit
25c35042b6
@ -193,6 +193,26 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
//! 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
|
||||
{
|
||||
|
@ -83,6 +83,7 @@ Graphic3d_RenderingMode.hxx
|
||||
Graphic3d_RenderingParams.hxx
|
||||
Graphic3d_RenderTransparentMethod.hxx
|
||||
Graphic3d_SequenceOfGroup.hxx
|
||||
Graphic3d_SequenceOfHClipPlane.cxx
|
||||
Graphic3d_SequenceOfHClipPlane.hxx
|
||||
Graphic3d_SequenceOfStructure.hxx
|
||||
Graphic3d_ShaderAttribute.cxx
|
||||
|
@ -45,8 +45,11 @@ namespace
|
||||
// =======================================================================
|
||||
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),
|
||||
@ -60,10 +63,13 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane()
|
||||
// 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),
|
||||
@ -71,6 +77,7 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation)
|
||||
myIsCapping (Standard_False)
|
||||
{
|
||||
makeId();
|
||||
updateInversedPlane();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -80,8 +87,11 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation)
|
||||
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),
|
||||
@ -98,7 +108,9 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther)
|
||||
// =======================================================================
|
||||
Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
|
||||
: myAspect (defaultAspect()),
|
||||
myPrevInChain(NULL),
|
||||
myPlane (thePlane),
|
||||
myChainLenFwd(1),
|
||||
myFlags (Graphic3d_CappingFlags_None),
|
||||
myEquationMod(0),
|
||||
myAspectMod (0),
|
||||
@ -106,6 +118,7 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
|
||||
myIsCapping (Standard_False)
|
||||
{
|
||||
thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
|
||||
updateInversedPlane();
|
||||
makeId();
|
||||
}
|
||||
|
||||
@ -113,10 +126,11 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
|
||||
// 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++;
|
||||
}
|
||||
|
||||
@ -127,10 +141,8 @@ void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation)
|
||||
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++;
|
||||
}
|
||||
|
||||
@ -140,6 +152,10 @@ void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
|
||||
// =======================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
@ -276,3 +292,35 @@ void Graphic3d_ClipPlane::makeId()
|
||||
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();
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#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>
|
||||
@ -26,24 +27,26 @@
|
||||
#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:
|
||||
@ -63,7 +66,7 @@ public:
|
||||
//! 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.
|
||||
@ -78,14 +81,15 @@ public:
|
||||
//! 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.
|
||||
@ -123,6 +127,43 @@ public:
|
||||
//! @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.
|
||||
@ -209,6 +250,113 @@ public:
|
||||
//! 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.
|
||||
@ -231,21 +379,33 @@ private:
|
||||
//! 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)
|
||||
|
60
src/Graphic3d/Graphic3d_SequenceOfHClipPlane.cxx
Normal file
60
src/Graphic3d/Graphic3d_SequenceOfHClipPlane.cxx
Normal file
@ -0,0 +1,60 @@
|
||||
// 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;
|
||||
}
|
@ -17,19 +17,50 @@
|
||||
#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; }
|
||||
@ -37,8 +68,35 @@ public:
|
||||
//! 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;
|
||||
|
||||
};
|
||||
|
@ -77,6 +77,7 @@ OpenGl_Caps.cxx
|
||||
OpenGl_Caps.hxx
|
||||
OpenGl_Clipping.cxx
|
||||
OpenGl_Clipping.hxx
|
||||
OpenGl_ClippingIterator.hxx
|
||||
OpenGl_Context.cxx
|
||||
OpenGl_Context.hxx
|
||||
OpenGl_Context_1.mm
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include <OpenGl_CappingAlgo.hxx>
|
||||
|
||||
#include <OpenGl_ClippingIterator.hxx>
|
||||
#include <OpenGl_Workspace.hxx>
|
||||
#include <OpenGl_Context.hxx>
|
||||
#include <OpenGl_PrimitiveArray.hxx>
|
||||
@ -37,6 +38,7 @@ namespace
|
||||
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());
|
||||
|
||||
@ -50,13 +52,15 @@ namespace
|
||||
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();
|
||||
@ -69,7 +73,7 @@ namespace
|
||||
}
|
||||
|
||||
// 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);
|
||||
@ -112,7 +116,7 @@ namespace
|
||||
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
|
||||
@ -128,19 +132,18 @@ namespace
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,28 +184,32 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks
|
||||
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, aClipChain, aSubPlaneIndex, aPlaneRes);
|
||||
|
||||
// set delayed resource release
|
||||
aPlaneRes.Nullify();
|
||||
aContext->ReleaseResource (aResId, Standard_True);
|
||||
}
|
||||
|
||||
renderCappingForStructure (theWorkspace, theStructure, aCappingIt, aPlaneRes);
|
||||
|
||||
// set delayed resource release
|
||||
aPlaneRes.Nullify();
|
||||
aContext->ReleaseResource (aResId, Standard_True);
|
||||
}
|
||||
|
||||
// restore previous application state
|
||||
|
@ -29,21 +29,21 @@ namespace
|
||||
//! - 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 =
|
||||
|
@ -15,35 +15,17 @@
|
||||
|
||||
#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)
|
||||
{}
|
||||
|
||||
@ -51,32 +33,36 @@ OpenGl_Clipping::OpenGl_Clipping ()
|
||||
// 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.
|
||||
@ -88,23 +74,21 @@ void OpenGl_Clipping::Reset (const Handle(OpenGl_Context)& theGlCtx,
|
||||
// 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())
|
||||
@ -122,13 +106,15 @@ void OpenGl_Clipping::add (const Handle(OpenGl_Context)& ,
|
||||
continue;
|
||||
}
|
||||
|
||||
const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
|
||||
myNbChains += 1;
|
||||
if (aPlane->IsCapping())
|
||||
{
|
||||
++myNbCapping;
|
||||
myNbCapping += aNbSubPlanes;
|
||||
}
|
||||
else
|
||||
{
|
||||
++myNbClipping;
|
||||
myNbClipping += aNbSubPlanes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -137,8 +123,7 @@ void OpenGl_Clipping::add (const Handle(OpenGl_Context)& ,
|
||||
// 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())
|
||||
@ -156,13 +141,15 @@ void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& ,
|
||||
continue;
|
||||
}
|
||||
|
||||
const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
|
||||
myNbChains -= 1;
|
||||
if (aPlane->IsCapping())
|
||||
{
|
||||
--myNbCapping;
|
||||
myNbCapping -= aNbSubPlanes;
|
||||
}
|
||||
else
|
||||
{
|
||||
--myNbClipping;
|
||||
myNbClipping -= aNbSubPlanes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,8 +158,7 @@ void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& ,
|
||||
// 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();
|
||||
@ -183,15 +169,17 @@ Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& ,
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -199,7 +187,7 @@ Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& ,
|
||||
// function : RestoreDisabled
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& )
|
||||
void OpenGl_Clipping::RestoreDisabled()
|
||||
{
|
||||
if (myNbDisabled == 0)
|
||||
{
|
||||
@ -217,13 +205,15 @@ void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& )
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -232,7 +222,7 @@ void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& )
|
||||
// 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())
|
||||
{
|
||||
@ -242,7 +232,7 @@ void OpenGl_Clipping::DisableGlobal (const Handle(OpenGl_Context)& theGlCtx)
|
||||
return;
|
||||
}
|
||||
|
||||
SetEnabled (theGlCtx, aPlaneIter, Standard_False);
|
||||
SetEnabled (aPlaneIter, Standard_False);
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,38 +240,30 @@ void OpenGl_Clipping::DisableGlobal (const Handle(OpenGl_Context)& theGlCtx)
|
||||
// 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;
|
||||
}
|
||||
|
||||
const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() != thePlane.PlaneIndex());
|
||||
SetEnabled (theGlCtx, aPlaneIter, isOn);
|
||||
}
|
||||
myCappedChain = theChain;
|
||||
myCappedSubPlane = -theSubPlaneIndex;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ResetCappingFilter
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Clipping::ResetCappingFilter()
|
||||
{
|
||||
myCappedChain.Nullify();
|
||||
myCappedSubPlane = 0;
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
#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
|
||||
@ -30,35 +29,51 @@ class OpenGl_ClippingIterator;
|
||||
//! 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
|
||||
|
||||
@ -66,26 +81,46 @@ 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();
|
||||
|
||||
//! Temporarily disable all planes except specified one.
|
||||
//! @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 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
|
||||
|
||||
@ -98,18 +133,15 @@ 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:
|
||||
@ -117,70 +149,19 @@ 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
|
||||
|
77
src/OpenGl/OpenGl_ClippingIterator.hxx
Normal file
77
src/OpenGl/OpenGl_ClippingIterator.hxx
Normal file
@ -0,0 +1,77 @@
|
||||
// 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
|
@ -1465,7 +1465,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
|
||||
glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
|
||||
}
|
||||
|
||||
myClippingState.Init (myMaxClipPlanes);
|
||||
myClippingState.Init();
|
||||
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
|
||||
|
@ -396,7 +396,8 @@ void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
|
||||
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();
|
||||
|
@ -31,10 +31,12 @@ enum OpenGl_ProgramOptions
|
||||
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
|
||||
|
@ -20,7 +20,7 @@
|
||||
#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>
|
||||
@ -238,6 +238,25 @@ const char THE_FRAG_CLIP_PLANES_N[] =
|
||||
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];"
|
||||
@ -256,6 +275,16 @@ const char THE_FRAG_CLIP_PLANES_2[] =
|
||||
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 };
|
||||
@ -930,10 +959,14 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
|
||||
|
||||
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;
|
||||
}
|
||||
@ -995,21 +1028,21 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
|
||||
}
|
||||
|
||||
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();
|
||||
@ -1017,29 +1050,64 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
else if (aPlane == aCappedChain) // && myContext->Clipping().IsCappingEnableAllExcept()
|
||||
{
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
// 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());
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -1532,12 +1600,16 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
|
||||
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)
|
||||
@ -1895,12 +1967,16 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
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)
|
||||
@ -2054,12 +2130,16 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
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)
|
||||
|
@ -414,6 +414,11 @@ protected:
|
||||
if (aNbPlanes > 0)
|
||||
{
|
||||
aBits |= OpenGl_PO_ClipPlanesN;
|
||||
if (myContext->Clipping().HasClippingChains())
|
||||
{
|
||||
aBits |= OpenGl_PO_ClipChains;
|
||||
}
|
||||
|
||||
if (aNbPlanes == 1)
|
||||
{
|
||||
aBits |= OpenGl_PO_ClipPlanes1;
|
||||
@ -568,6 +573,29 @@ protected:
|
||||
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;
|
||||
@ -602,6 +630,7 @@ protected:
|
||||
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:
|
||||
|
||||
|
@ -56,6 +56,7 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
|
||||
"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
|
||||
|
@ -50,6 +50,7 @@ enum OpenGl_StateVariable
|
||||
|
||||
// OpenGL clip planes state
|
||||
OpenGl_OCC_CLIP_PLANE_EQUATIONS,
|
||||
OpenGl_OCC_CLIP_PLANE_CHAINS,
|
||||
OpenGl_OCC_CLIP_PLANE_COUNT,
|
||||
|
||||
// OpenGL light state
|
||||
@ -224,7 +225,7 @@ public:
|
||||
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),
|
||||
|
@ -16,6 +16,7 @@
|
||||
#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>
|
||||
@ -24,9 +25,6 @@
|
||||
#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
|
||||
@ -551,7 +549,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
|
||||
}
|
||||
|
||||
// Collect clipping planes of structure scope
|
||||
aCtx->ChangeClipping().SetLocalPlanes (aCtx, myClipPlanes);
|
||||
aCtx->ChangeClipping().SetLocalPlanes (myClipPlanes);
|
||||
|
||||
// True if structure is fully clipped
|
||||
bool isClipped = false;
|
||||
@ -562,7 +560,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
|
||||
if (!myClipPlanes.IsNull()
|
||||
&& myClipPlanes->ToOverrideGlobal())
|
||||
{
|
||||
aCtx->ChangeClipping().DisableGlobal (aCtx);
|
||||
aCtx->ChangeClipping().DisableGlobal();
|
||||
hasDisabled = aCtx->Clipping().HasDisabled();
|
||||
}
|
||||
else if (!myTrsfPers.IsNull())
|
||||
@ -583,9 +581,8 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
|
||||
}
|
||||
|
||||
// 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;
|
||||
@ -593,7 +590,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
|
||||
}
|
||||
}
|
||||
|
||||
aCtx->ChangeClipping().DisableGlobal (aCtx);
|
||||
aCtx->ChangeClipping().DisableGlobal();
|
||||
hasDisabled = aCtx->Clipping().HasDisabled();
|
||||
}
|
||||
|
||||
@ -610,26 +607,15 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -667,9 +653,9 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
|
||||
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)
|
||||
{
|
||||
|
@ -1205,7 +1205,7 @@ void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection,
|
||||
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())
|
||||
{
|
||||
@ -1218,7 +1218,7 @@ void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection,
|
||||
// Apply restored view matrix.
|
||||
aContext->ApplyWorldViewMatrix();
|
||||
|
||||
aContext->ChangeClipping().Reset (aContext, Handle(Graphic3d_SequenceOfHClipPlane)());
|
||||
aContext->ChangeClipping().Reset (Handle(Graphic3d_SequenceOfHClipPlane)());
|
||||
if (!myClipPlanes.IsNull()
|
||||
&& !myClipPlanes->IsEmpty())
|
||||
{
|
||||
|
@ -280,20 +280,12 @@ const OpenGl_AspectFace* OpenGl_Workspace::ApplyAspectFace()
|
||||
{
|
||||
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))
|
||||
|
@ -122,7 +122,7 @@ public:
|
||||
//! @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 ////
|
||||
@ -133,7 +133,12 @@ public:
|
||||
//! 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(); }
|
||||
|
@ -19,6 +19,7 @@
|
||||
#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>
|
||||
|
@ -276,7 +276,7 @@ void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d &thePoint)
|
||||
// {i, j, k} vectors and store them to corresponding class fields
|
||||
cacheVertexProjections (this);
|
||||
|
||||
myViewClipRange.Clear();
|
||||
myViewClipRange.SetVoid();
|
||||
|
||||
myScale = 1.0;
|
||||
}
|
||||
@ -306,7 +306,7 @@ void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d& theMinPnt,
|
||||
// {i, j, k} vectors and store them to corresponding class fields
|
||||
cacheVertexProjections (this);
|
||||
|
||||
myViewClipRange.Clear();
|
||||
myViewClipRange.SetVoid();
|
||||
|
||||
myScale = 1.0;
|
||||
}
|
||||
@ -645,53 +645,74 @@ gp_Pnt SelectMgr_RectangularFrustum::DetectedPoint (const Standard_Real theDepth
|
||||
// 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();
|
||||
|
||||
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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
Bnd_Range aSubRange (RealFirst(), RealLast());
|
||||
for (const Graphic3d_ClipPlane* aSubPlaneIter = aClipPlane.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get())
|
||||
{
|
||||
// the plane is "behind" the ray
|
||||
aDistToPln = -aDistToPln;
|
||||
const gp_Pln aGeomPlane = aSubPlaneIter->ToPlane();
|
||||
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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// compute distance to point of pick line intersection with the plane
|
||||
const Standard_Real aParam = aDistance / aDotProduct;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
if (!aSubRange.IsVoid()
|
||||
&& aClipPlane->IsChain())
|
||||
{
|
||||
theDepthMax = Min (aDistToPln, theDepthMax);
|
||||
}
|
||||
else if (aDistToPln > theDepthMin)
|
||||
{
|
||||
theDepthMin = Max (aDistToPln, theDepthMin);
|
||||
theRange.AddSubRange (aSubRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -704,10 +725,9 @@ void SelectMgr_RectangularFrustum::computeClippingRange (const Graphic3d_Sequenc
|
||||
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);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -719,13 +739,11 @@ void SelectMgr_RectangularFrustum::SetViewClipping (const Handle(Graphic3d_Seque
|
||||
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);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -734,14 +752,8 @@ void SelectMgr_RectangularFrustum::SetViewClipping (const Handle(Graphic3d_Seque
|
||||
// =======================================================================
|
||||
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);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@ -149,8 +149,7 @@ protected:
|
||||
|
||||
//! 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;
|
||||
|
@ -16,58 +16,52 @@
|
||||
#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
|
||||
|
@ -225,9 +225,8 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
|
||||
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;
|
||||
}
|
||||
|
@ -173,5 +173,6 @@ uniform float occAlphaCutoff; //!< alpha test cutoff value
|
||||
//! 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
|
||||
|
@ -176,5 +176,6 @@ static const char Shaders_Declarations_glsl[] =
|
||||
"//! 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";
|
||||
|
@ -2626,8 +2626,13 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
|
||||
|
||||
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;
|
||||
|
@ -8375,8 +8375,8 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
|
||||
{
|
||||
aClipPlane->SetOn (toEnable);
|
||||
}
|
||||
else if (aChangeArg == "-equation"
|
||||
|| aChangeArg == "equation")
|
||||
else if (aChangeArg.StartsWith ("-equation")
|
||||
|| aChangeArg.StartsWith ("equation"))
|
||||
{
|
||||
if (aNbChangeArgs < 5)
|
||||
{
|
||||
@ -8384,13 +8384,74 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
|
||||
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")
|
||||
{
|
||||
@ -12300,7 +12361,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
||||
__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}]"
|
||||
|
@ -1,10 +1,8 @@
|
||||
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
|
||||
|
91
tests/v3d/glsl/clipping1
Normal file
91
tests/v3d/glsl/clipping1
Normal file
@ -0,0 +1,91 @@
|
||||
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
|
Loading…
x
Reference in New Issue
Block a user