1 // Created on: 2013-07-12
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #ifndef _Graphic3d_ClipPlane_HeaderFile
17 #define _Graphic3d_ClipPlane_HeaderFile
19 #include <Aspect_HatchStyle.hxx>
21 #include <Graphic3d_AspectFillArea3d.hxx>
22 #include <Graphic3d_BndBox3d.hxx>
23 #include <Graphic3d_CappingFlags.hxx>
24 #include <Graphic3d_TextureMap.hxx>
25 #include <NCollection_Vec4.hxx>
26 #include <Standard_Macro.hxx>
27 #include <Standard_TypeDef.hxx>
28 #include <Standard_Transient.hxx>
31 enum Graphic3d_ClipState
33 Graphic3d_ClipState_Out, //!< fully outside (clipped) - should be discarded
34 Graphic3d_ClipState_In, //!< fully inside (NOT clipped) - should NOT be discarded
35 Graphic3d_ClipState_On, //!< on (not clipped / partially clipped) - should NOT be discarded
38 //! Container for properties describing either a Clipping halfspace (single Clipping Plane),
39 //! or a chain of Clipping Planes defining logical AND (conjunction) operation.
40 //! The plane equation is specified in "world" coordinate system.
41 class Graphic3d_ClipPlane : public Standard_Transient
43 DEFINE_STANDARD_RTTIEXT(Graphic3d_ClipPlane,Standard_Transient)
46 //! Type defining XYZW (ABCD) plane equation - left for compatibility with old code using Graphic3d_ClipPlane::Equation type.
47 typedef Graphic3d_Vec4d Equation;
51 //! Default constructor.
52 //! Initializes clip plane container with the following properties:
53 //! - Equation (0.0, 0.0, 1.0, 0)
55 //! - IsCapping (False),
56 //! - Material (Graphic3d_NOM_DEFAULT),
58 //! - HatchStyle (Aspect_HS_HORIZONTAL),
59 //! - IsHatchOn (False)
60 Standard_EXPORT Graphic3d_ClipPlane();
63 //! @param theOther [in] the copied plane.
64 Standard_EXPORT Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther);
66 //! Construct clip plane for the passed equation.
67 //! By default the plane is on, capping is turned off.
68 //! @param theEquation [in] the plane equation.
69 Standard_EXPORT Graphic3d_ClipPlane (const Graphic3d_Vec4d& theEquation);
71 //! Construct clip plane from the passed geometrical definition.
72 //! By default the plane is on, capping is turned off.
73 //! @param thePlane [in] the plane.
74 Standard_EXPORT Graphic3d_ClipPlane (const gp_Pln& thePlane);
76 //! Set plane equation by its geometrical definition.
77 //! The equation is specified in "world" coordinate system.
78 //! @param thePlane [in] the plane.
79 Standard_EXPORT void SetEquation (const gp_Pln& thePlane);
81 //! Set 4-component equation vector for clipping plane.
82 //! The equation is specified in "world" coordinate system.
83 //! @param theEquation [in] the XYZW (or "ABCD") equation vector.
84 Standard_EXPORT void SetEquation (const Graphic3d_Vec4d& theEquation);
86 //! Get 4-component equation vector for clipping plane.
87 //! @return clipping plane equation vector.
88 const Graphic3d_Vec4d& GetEquation() const { return myEquation; }
90 //! Get 4-component equation vector for clipping plane.
91 //! @return clipping plane equation vector.
92 const Graphic3d_Vec4d& ReversedEquation() const { return myEquationRev; }
94 //! Check that the clipping plane is turned on.
95 //! @return boolean flag indicating whether the plane is in on or off state.
96 Standard_Boolean IsOn() const
101 //! Change state of the clipping plane.
102 //! @param theIsOn [in] the flag specifying whether the graphic driver
103 //! clipping by this plane should be turned on or off.
104 Standard_EXPORT void SetOn(const Standard_Boolean theIsOn);
106 //! Change state of capping surface rendering.
107 //! @param theIsOn [in] the flag specifying whether the graphic driver should
108 //! perform rendering of capping surface produced by this plane. The graphic
109 //! driver produces this surface for convex graphics by means of stencil-test
110 //! and multi-pass rendering.
111 Standard_EXPORT void SetCapping(const Standard_Boolean theIsOn);
113 //! Check state of capping surface rendering.
114 //! @return true (turned on) or false depending on the state.
115 Standard_Boolean IsCapping() const
120 //! Get geometrical definition.
121 //! @return geometrical definition of clipping plane
122 const gp_Pln& ToPlane() const { return myPlane; }
124 //! Clone plane. Virtual method to simplify copying procedure if plane
125 //! class is redefined at application level to add specific fields to it
126 //! e.g. id, name, etc.
127 //! @return new instance of clipping plane with same properties and attributes.
128 Standard_EXPORT virtual Handle(Graphic3d_ClipPlane) Clone() const;
132 //! Return TRUE if this item defines a conjunction (logical AND) between a set of Planes.
133 //! Graphic3d_ClipPlane item defines either a Clipping halfspace (single Clipping Plane)
134 //! or a Clipping volume defined by a logical AND (conjunction) operation between a set of Planes defined as a Chain
135 //! (so that the volume cuts a space only in case if check fails for ALL Planes in the Chain).
137 //! Note that Graphic3d_ClipPlane item cannot:
138 //! - Define a Chain with logical OR (disjunction) operation;
139 //! this should be done through Graphic3d_SequenceOfHClipPlane.
140 //! - Define nested Chains.
141 //! - Disable Chain items; only entire Chain can be disabled (by disabled a head of Chain).
143 //! The head of a Chain defines all visual properties of the Chain,
144 //! so that Graphic3d_ClipPlane of next items in a Chain merely defines only geometrical definition of the plane.
145 Standard_Boolean IsChain() const { return !myNextInChain.IsNull(); }
147 //! Return the previous plane in a Chain of Planes defining logical AND operation,
148 //! or NULL if there is no Chain or it is a first element in Chain.
149 //! When clipping is defined by a Chain of Planes,
150 //! it cuts a space only in case if check fails for all Planes in Chain.
151 Handle(Graphic3d_ClipPlane) ChainPreviousPlane() const { return myPrevInChain; }
153 //! Return the next plane in a Chain of Planes defining logical AND operation,
154 //! or NULL if there is no chain or it is a last element in chain.
156 const Handle(Graphic3d_ClipPlane)& ChainNextPlane() const { return myNextInChain; }
158 //! Return the number of chains in forward direction (including this item, so it is always >= 1).
159 //! For a head of Chain - returns the length of entire Chain.
160 Standard_Integer NbChainNextPlanes() const { return myChainLenFwd; }
162 //! Set the next plane in a Chain of Planes.
163 //! This operation also updates relationship between chains (Previous/Next items),
164 //! so that the previously set Next plane is cut off.
165 Standard_EXPORT void SetChainNextPlane (const Handle(Graphic3d_ClipPlane)& thePlane);
167 public: // @name user-defined graphical attributes
169 //! Return color for rendering capping surface.
170 Quantity_Color CappingColor() const { return myAspect->FrontMaterial().MaterialType() == Graphic3d_MATERIAL_ASPECT ? myAspect->FrontMaterial().Color() : myAspect->InteriorColor(); }
172 //! Set color for rendering capping surface.
173 Standard_EXPORT void SetCappingColor (const Quantity_Color& theColor);
175 //! Set material for rendering capping surface.
176 //! @param theMat [in] the material.
177 Standard_EXPORT void SetCappingMaterial (const Graphic3d_MaterialAspect& theMat);
179 //! @return capping material.
180 const Graphic3d_MaterialAspect& CappingMaterial() const { return myAspect->FrontMaterial(); }
182 //! Set texture to be applied on capping surface.
183 //! @param theTexture [in] the texture.
184 Standard_EXPORT void SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture);
186 //! @return capping texture map.
187 Handle(Graphic3d_TextureMap) CappingTexture() const { return !myAspect->TextureSet().IsNull() && !myAspect->TextureSet()->IsEmpty()
188 ? myAspect->TextureSet()->First()
189 : Handle(Graphic3d_TextureMap)(); }
191 //! Set hatch style (stipple) and turn hatching on.
192 //! @param theStyle [in] the hatch style.
193 Standard_EXPORT void SetCappingHatch (const Aspect_HatchStyle theStyle);
195 //! @return hatching style.
196 Aspect_HatchStyle CappingHatch() const { return (Aspect_HatchStyle)myAspect->HatchStyle()->HatchType(); }
198 //! Set custom hatch style (stipple) and turn hatching on.
199 //! @param theStyle [in] the hatch pattern.
200 Standard_EXPORT void SetCappingCustomHatch (const Handle(Graphic3d_HatchStyle)& theStyle);
202 //! @return hatching style.
203 const Handle(Graphic3d_HatchStyle)& CappingCustomHatch() const { return myAspect->HatchStyle(); }
205 //! Turn on hatching.
206 Standard_EXPORT void SetCappingHatchOn();
208 //! Turn off hatching.
209 Standard_EXPORT void SetCappingHatchOff();
211 //! @return True if hatching mask is turned on.
212 Standard_Boolean IsHatchOn() const { return myAspect->InteriorStyle() == Aspect_IS_HATCH; }
214 //! This ID is used for managing associated resources in graphical driver.
215 //! The clip plane can be assigned within a range of IO which can be
216 //! displayed in separate OpenGl contexts. For each of the context an associated
217 //! OpenGl resource for graphical aspects should be created and kept.
218 //! The resources are stored in graphical driver for each of individual groups
219 //! of shared context under the clip plane identifier.
220 //! @return clip plane resource identifier string.
221 const TCollection_AsciiString& GetId() const
228 //! Return capping aspect.
229 //! @return capping surface rendering aspect.
230 const Handle(Graphic3d_AspectFillArea3d)& CappingAspect() const { return myAspect; }
232 //! Assign capping aspect.
233 Standard_EXPORT void SetCappingAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect);
235 //! Flag indicating whether material for capping plane should be taken from object.
236 //! Default value: FALSE (use dedicated capping plane material).
237 bool ToUseObjectMaterial() const { return (myFlags & Graphic3d_CappingFlags_ObjectMaterial) != 0; }
239 //! Set flag for controlling the source of capping plane material.
240 void SetUseObjectMaterial (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectMaterial); }
242 //! Flag indicating whether texture for capping plane should be taken from object.
243 //! Default value: FALSE.
244 bool ToUseObjectTexture() const { return (myFlags & Graphic3d_CappingFlags_ObjectTexture) != 0; }
246 //! Set flag for controlling the source of capping plane texture.
247 void SetUseObjectTexture (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectTexture); }
249 //! Flag indicating whether shader program for capping plane should be taken from object.
250 //! Default value: FALSE.
251 bool ToUseObjectShader() const { return (myFlags & Graphic3d_CappingFlags_ObjectShader) != 0; }
253 //! Set flag for controlling the source of capping plane shader program.
254 void SetUseObjectShader(bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectShader); }
256 //! Return true if some fill area aspect properties should be taken from object.
257 bool ToUseObjectProperties() const { return myFlags != Graphic3d_CappingFlags_None; }
261 //! Check if the given point is outside / inside / on section.
262 Graphic3d_ClipState ProbePoint (const Graphic3d_Vec4d& thePoint) const
264 Graphic3d_ClipState aState = Graphic3d_ClipState_Out;
265 for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
267 Graphic3d_ClipState aPlnState = aPlaneIter->ProbePointHalfspace (thePoint);
268 if (aPlnState == Graphic3d_ClipState_In)
270 return Graphic3d_ClipState_In;
272 else if (aPlnState != Graphic3d_ClipState_Out)
274 aState = Graphic3d_ClipState_On;
280 //! Check if the given bounding box is fully outside / fully inside.
281 Graphic3d_ClipState ProbeBox (const Graphic3d_BndBox3d& theBox) const
283 Graphic3d_ClipState aState = Graphic3d_ClipState_Out;
284 for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
286 if (aPlaneIter->IsBoxFullInHalfspace (theBox))
288 // within union operation, if box is entirely inside at least one half-space, others can be ignored
289 return Graphic3d_ClipState_In;
291 else if (!aPlaneIter->IsBoxFullOutHalfspace (theBox))
293 // if at least one full out test fail, clipping state is inconclusive (partially clipped)
294 aState = Graphic3d_ClipState_On;
300 //! Check if the given bounding box is In and touch the clipping planes
301 Standard_Boolean ProbeBoxTouch (const Graphic3d_BndBox3d& theBox) const
303 for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
305 if (aPlaneIter->IsBoxFullInHalfspace (theBox))
307 // within union operation, if box is entirely inside at least one half-space, others can be ignored
308 return Standard_False;
310 else if (!aPlaneIter->IsBoxFullOutHalfspace (theBox))
312 // the box is not fully out, and not fully in, check is it on (but not intersect)
313 if (ProbeBoxMaxPointHalfspace (theBox) != Graphic3d_ClipState_Out)
315 return Standard_True;
319 return Standard_False;
324 //! Check if the given point is outside of the half-space (e.g. should be discarded by clipping plane).
325 Graphic3d_ClipState ProbePointHalfspace (const Graphic3d_Vec4d& thePoint) const
327 const Standard_Real aVal = myEquation.Dot (thePoint);
329 ? Graphic3d_ClipState_Out
331 ? Graphic3d_ClipState_On
332 : Graphic3d_ClipState_In);
335 //! Check if the given bounding box is fully outside / fully inside the half-space.
336 Graphic3d_ClipState ProbeBoxHalfspace (const Graphic3d_BndBox3d& theBox) const
338 if (IsBoxFullOutHalfspace (theBox))
340 return Graphic3d_ClipState_Out;
342 return IsBoxFullInHalfspace (theBox)
343 ? Graphic3d_ClipState_In
344 : Graphic3d_ClipState_On;
347 //! Check if the given point is outside of the half-space (e.g. should be discarded by clipping plane).
348 bool IsPointOutHalfspace (const Graphic3d_Vec4d& thePoint) const { return ProbePointHalfspace (thePoint) == Graphic3d_ClipState_Out; }
350 //! Check if the given bounding box is fully outside of the half-space (e.g. should be discarded by clipping plane).
351 bool IsBoxFullOutHalfspace (const Graphic3d_BndBox3d& theBox) const
353 const Graphic3d_Vec4d aMaxPnt (myEquation.x() > 0.0 ? theBox.CornerMax().x() : theBox.CornerMin().x(),
354 myEquation.y() > 0.0 ? theBox.CornerMax().y() : theBox.CornerMin().y(),
355 myEquation.z() > 0.0 ? theBox.CornerMax().z() : theBox.CornerMin().z(),
357 return IsPointOutHalfspace (aMaxPnt);
360 //! Check if the given bounding box is fully outside of the half-space (e.g. should be discarded by clipping plane).
361 Graphic3d_ClipState ProbeBoxMaxPointHalfspace (const Graphic3d_BndBox3d& theBox) const
363 const Graphic3d_Vec4d aMaxPnt (myEquation.x() > 0.0 ? theBox.CornerMax().x() : theBox.CornerMin().x(),
364 myEquation.y() > 0.0 ? theBox.CornerMax().y() : theBox.CornerMin().y(),
365 myEquation.z() > 0.0 ? theBox.CornerMax().z() : theBox.CornerMin().z(),
367 return ProbePointHalfspace (aMaxPnt);
370 //! Check if the given bounding box is fully inside (or touches from inside) the half-space (e.g. NOT discarded by clipping plane).
371 bool IsBoxFullInHalfspace (const Graphic3d_BndBox3d& theBox) const
373 const Graphic3d_Vec4d aMinPnt (myEquation.x() > 0.0 ? theBox.CornerMin().x() : theBox.CornerMax().x(),
374 myEquation.y() > 0.0 ? theBox.CornerMin().y() : theBox.CornerMax().y(),
375 myEquation.z() > 0.0 ? theBox.CornerMin().z() : theBox.CornerMax().z(),
377 return !IsPointOutHalfspace (aMinPnt);
380 //! Dumps the content of me into the stream
381 Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
383 public: // @name modification counters
385 //! @return modification counter for equation.
386 unsigned int MCountEquation() const
388 return myEquationMod;
391 //! @return modification counter for aspect.
392 unsigned int MCountAspect() const
399 //! Generate unique object id for OpenGL graphic resource manager.
402 //! Set capping flag.
403 Standard_EXPORT void setCappingFlag (bool theToUse, int theFlag);
405 //! Update chain length in backward direction.
406 void updateChainLen();
408 //! Update inversed plane definition from main plane.
409 void updateInversedPlane()
411 gp_Pln aPlane = myPlane;
412 aPlane.SetAxis (aPlane.Axis().Reversed());
413 aPlane.Coefficients (myEquationRev[0], myEquationRev[1], myEquationRev[2], myEquationRev[3]);
418 Handle(Graphic3d_AspectFillArea3d) myAspect; //!< fill area aspect
419 Handle(Graphic3d_ClipPlane) myNextInChain; //!< next plane in a chain of planes defining logical AND operation
420 Graphic3d_ClipPlane* myPrevInChain; //!< previous plane in a chain of planes defining logical AND operation
421 TCollection_AsciiString myId; //!< resource id
422 gp_Pln myPlane; //!< plane definition
423 Graphic3d_Vec4d myEquation; //!< plane equation vector
424 Graphic3d_Vec4d myEquationRev; //!< reversed plane equation
425 Standard_Integer myChainLenFwd; //!< chain length in forward direction (including this item)
426 unsigned int myFlags; //!< capping flags
427 unsigned int myEquationMod; //!< modification counter for equation
428 unsigned int myAspectMod; //!< modification counter of aspect
429 Standard_Boolean myIsOn; //!< state of the clipping plane
430 Standard_Boolean myIsCapping; //!< state of graphic driver capping
434 DEFINE_STANDARD_HANDLE (Graphic3d_ClipPlane, Standard_Transient)