0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / Graphic3d / Graphic3d_ClipPlane.hxx
1 // Created on: 2013-07-12
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _Graphic3d_ClipPlane_HeaderFile
17 #define _Graphic3d_ClipPlane_HeaderFile
18
19 #include <Aspect_HatchStyle.hxx>
20 #include <gp_Pln.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>
29
30 //! Clipping state.
31 enum Graphic3d_ClipState
32 {
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
36 };
37
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
42 {
43   DEFINE_STANDARD_RTTIEXT(Graphic3d_ClipPlane,Standard_Transient)
44 public:
45
46   //! Type defining XYZW (ABCD) plane equation - left for compatibility with old code using Graphic3d_ClipPlane::Equation type.
47   typedef Graphic3d_Vec4d Equation;
48
49 public:
50
51   //! Default constructor.
52   //! Initializes clip plane container with the following properties:
53   //! - Equation (0.0, 0.0, 1.0, 0)
54   //! - IsOn (True),
55   //! - IsCapping (False),
56   //! - Material (Graphic3d_NOM_DEFAULT),
57   //! - Texture (NULL),
58   //! - HatchStyle (Aspect_HS_HORIZONTAL),
59   //! - IsHatchOn (False)
60   Standard_EXPORT Graphic3d_ClipPlane();
61
62   //! Copy constructor.
63   //! @param theOther [in] the copied plane.
64   Standard_EXPORT Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther);
65
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);
70
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);
75
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);
80
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);
85
86   //! Get 4-component equation vector for clipping plane.
87   //! @return clipping plane equation vector.
88   const Graphic3d_Vec4d& GetEquation() const { return myEquation; }
89
90   //! Get 4-component equation vector for clipping plane.
91   //! @return clipping plane equation vector.
92   const Graphic3d_Vec4d& ReversedEquation() const { return myEquationRev; }
93
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
97   {
98     return myIsOn;
99   }
100
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);
105
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);
112
113   //! Check state of capping surface rendering.
114   //! @return true (turned on) or false depending on the state.
115   Standard_Boolean IsCapping() const
116   {
117     return myIsCapping;
118   }
119
120   //! Get geometrical definition.
121   //! @return geometrical definition of clipping plane
122   const gp_Pln& ToPlane() const { return myPlane; }
123
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;
129
130 public:
131
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).
136   //!
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).
142   //!
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(); }
146
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; }
152
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.
155
156   const Handle(Graphic3d_ClipPlane)& ChainNextPlane() const { return myNextInChain; }
157
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; }
161
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);
166
167 public: // @name user-defined graphical attributes
168
169   //! Return color for rendering capping surface.
170   Quantity_Color CappingColor() const { return myAspect->FrontMaterial().MaterialType() == Graphic3d_MATERIAL_ASPECT ? myAspect->FrontMaterial().Color() : myAspect->InteriorColor(); }
171
172   //! Set color for rendering capping surface.
173   Standard_EXPORT void SetCappingColor (const Quantity_Color& theColor);
174
175   //! Set material for rendering capping surface.
176   //! @param theMat [in] the material.
177   Standard_EXPORT void SetCappingMaterial (const Graphic3d_MaterialAspect& theMat);
178
179   //! @return capping material.
180   const Graphic3d_MaterialAspect& CappingMaterial() const { return myAspect->FrontMaterial(); }
181
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);
185
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)(); }
190
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);
194
195   //! @return hatching style.
196   Aspect_HatchStyle CappingHatch() const { return (Aspect_HatchStyle)myAspect->HatchStyle()->HatchType(); }
197
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);
201
202   //! @return hatching style.
203   const Handle(Graphic3d_HatchStyle)& CappingCustomHatch() const { return myAspect->HatchStyle(); }
204
205   //! Turn on hatching.
206   Standard_EXPORT void SetCappingHatchOn();
207
208   //! Turn off hatching.
209   Standard_EXPORT void SetCappingHatchOff();
210
211   //! @return True if hatching mask is turned on.
212   Standard_Boolean IsHatchOn() const { return myAspect->InteriorStyle() == Aspect_IS_HATCH; }
213
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
222   {
223     return myId;
224   }
225
226 public:
227
228   //! Return capping aspect.
229   //! @return capping surface rendering aspect.
230   const Handle(Graphic3d_AspectFillArea3d)& CappingAspect() const { return myAspect; }
231
232   //! Assign capping aspect.
233   Standard_EXPORT void SetCappingAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect);
234
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; }
238
239   //! Set flag for controlling the source of capping plane material.
240   void SetUseObjectMaterial (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectMaterial); }
241
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; }
245
246   //! Set flag for controlling the source of capping plane texture.
247   void SetUseObjectTexture (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectTexture); }
248
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; }
252
253   //! Set flag for controlling the source of capping plane shader program.
254   void SetUseObjectShader(bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectShader); }
255
256   //! Return true if some fill area aspect properties should be taken from object.
257   bool ToUseObjectProperties() const { return myFlags != Graphic3d_CappingFlags_None; }
258
259 public:
260
261   //! Check if the given point is outside / inside / on section.
262   Graphic3d_ClipState ProbePoint (const Graphic3d_Vec4d& thePoint) const
263   {
264     Graphic3d_ClipState aState = Graphic3d_ClipState_Out;
265     for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
266     {
267       Graphic3d_ClipState aPlnState = aPlaneIter->ProbePointHalfspace (thePoint);
268       if (aPlnState == Graphic3d_ClipState_In)
269       {
270         return Graphic3d_ClipState_In;
271       }
272       else if (aPlnState != Graphic3d_ClipState_Out)
273       {
274         aState = Graphic3d_ClipState_On;
275       }
276     }
277     return aState;
278   }
279
280   //! Check if the given bounding box is fully outside / fully inside.
281   Graphic3d_ClipState ProbeBox (const Graphic3d_BndBox3d& theBox) const
282   {
283     Graphic3d_ClipState aState = Graphic3d_ClipState_Out;
284     for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
285     {
286       if (aPlaneIter->IsBoxFullInHalfspace (theBox))
287       {
288         // within union operation, if box is entirely inside at least one half-space, others can be ignored
289         return Graphic3d_ClipState_In;
290       }
291       else if (!aPlaneIter->IsBoxFullOutHalfspace (theBox))
292       {
293         // if at least one full out test fail, clipping state is inconclusive (partially clipped)
294         aState = Graphic3d_ClipState_On;
295       }
296     }
297     return aState;
298   }
299
300   //! Check if the given bounding box is In and touch the clipping planes
301   Standard_Boolean ProbeBoxTouch (const Graphic3d_BndBox3d& theBox) const
302   {
303     for (const Graphic3d_ClipPlane* aPlaneIter = this; aPlaneIter != NULL; aPlaneIter = aPlaneIter->myNextInChain.get())
304     {
305       if (aPlaneIter->IsBoxFullInHalfspace (theBox))
306       {
307         // within union operation, if box is entirely inside at least one half-space, others can be ignored
308         return Standard_False;
309       }
310       else if (!aPlaneIter->IsBoxFullOutHalfspace (theBox))
311       {
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)
314         {
315           return Standard_True;
316         }
317       }
318     }
319     return Standard_False;
320   }
321
322 public:
323
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
326   {
327     const Standard_Real aVal = myEquation.Dot (thePoint);
328     return aVal < 0.0
329          ? Graphic3d_ClipState_Out
330          : (aVal == 0.0
331           ? Graphic3d_ClipState_On
332           : Graphic3d_ClipState_In);
333   }
334
335   //! Check if the given bounding box is fully outside / fully inside the half-space.
336   Graphic3d_ClipState ProbeBoxHalfspace (const Graphic3d_BndBox3d& theBox) const
337   {
338     if (IsBoxFullOutHalfspace (theBox))
339     {
340       return Graphic3d_ClipState_Out;
341     }
342     return IsBoxFullInHalfspace (theBox)
343          ? Graphic3d_ClipState_In
344          : Graphic3d_ClipState_On;
345   }
346
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; }
349
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
352   {
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(),
356                                    1.0);
357     return IsPointOutHalfspace (aMaxPnt);
358   }
359
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
362   {
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(),
366                                    1.0);
367     return ProbePointHalfspace (aMaxPnt);
368   }
369
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
372   {
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(),
376                                    1.0);
377     return !IsPointOutHalfspace (aMinPnt);
378   }
379
380   //! Dumps the content of me into the stream
381   Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
382
383 public: // @name modification counters
384
385   //! @return modification counter for equation.
386   unsigned int MCountEquation() const
387   {
388     return myEquationMod;
389   }
390
391   //! @return modification counter for aspect.
392   unsigned int MCountAspect() const
393   {
394     return myAspectMod;
395   }
396
397 private:
398
399   //! Generate unique object id for OpenGL graphic resource manager.
400   void makeId();
401
402   //! Set capping flag.
403   Standard_EXPORT void setCappingFlag (bool theToUse, int theFlag);
404
405   //! Update chain length in backward direction.
406   void updateChainLen();
407
408   //! Update inversed plane definition from main plane.
409   void updateInversedPlane()
410   {
411     gp_Pln aPlane = myPlane;
412     aPlane.SetAxis (aPlane.Axis().Reversed());
413     aPlane.Coefficients (myEquationRev[0], myEquationRev[1], myEquationRev[2], myEquationRev[3]);
414   }
415
416 private:
417
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
431
432 };
433
434 DEFINE_STANDARD_HANDLE (Graphic3d_ClipPlane, Standard_Transient)
435
436 #endif