0022815: Missing delete operator for placement new
[occt.git] / src / NIS / NIS_Drawer.hxx
1 // File:      NIS_Drawer.hxx
2 // Created:   06.07.07 21:10
3 // Author:    Alexander GRIGORIEV
4 // Copyright: Open Cascade 2007
5
6
7 #ifndef NIS_Drawer_HeaderFile
8 #define NIS_Drawer_HeaderFile
9
10 #include <Standard_Transient.hxx>
11 #include <NCollection_List.hxx>
12 #include <TColStd_PackedMapOfInteger.hxx>
13 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
14 #include <NIS_DrawList.hxx>
15 #include <Bnd_B3f.hxx>
16
17 #ifdef WNT
18 #pragma warning (push)
19 // Disable warning 4480: nonstandard extension used: specifying underlying type for enum 'enum'
20 #pragma warning (disable:4480)
21 #endif
22
23 class Handle_NIS_InteractiveObject;
24 class Handle_NIS_View;
25 class Handle_NIS_Drawer;
26 class NIS_InteractiveContext;
27 class NIS_View;
28 template <class A> class NCollection_Vector;
29
30 /**
31  * Abstract Drawer type.
32  * Drawer provides the immediate OpenGL drawing for every NIS_InteractiveObject
33  * maneged by the given Drawer instance. Each Drawer instance has reciprocal
34  * link with a number of NIS_InteractiveObject instances of the same
35  * (corresponding to Drawer) type. The idea is to group the drawing for all
36  * referred interactive objects using the same pre- and post-treatment like
37  * color setting, matrix, polygon offset, line thickness and what not.
38  *
39  * @section nis_drawer_visualprop Visual properties of Drawer
40  * Normally visual properties of any NIS_InteractiveObject are stored in its
41  * Drawer instance, but not in an object. For example, if an interactive object
42  * has method SetColor() then the color is stored in the corresponding Drawer
43  * rather than in the interactive object itself. This scheme avoid useless
44  * duplication when a lot of objects have similar properties like color. Please
45  * see @see nis_interactiveobject_drawer to learn how this mechanism
46  * works from the side of NIS_InteractiveObject.
47  *
48  * @section nis_drawer_drawing Drawing
49  * There are 3 virtual methods to implement OpenGL drawing in this API. They
50  * define the drawing cycle that consists of filling the internal OpenGL draw
51  * list with commands. This drawing cycle is triggered when the corresponding
52  * internal instance of NIS_DrawList has 'IsUpdated' flag (you can set this
53  * flag by means of public methods NIS_Drawer::SetUpdated()). 
54  * <ul>
55  * <li><b>BeforeDraw()</b> : contains all OpenGL commands that define the
56  *     common set of visual properties for all managed interactive objects.
57  *     This method is called once in the beginning of drawing cycle for the
58  *     Drawer instance</li>
59  * <li><b>Draw()</b> : all OpenGL commands that are specific to a given
60  *     interactive object, usually definition of vertices, triangles, lines,
61  *     or their arrays.</li>
62  * <li><b>AfterDraw()</b> : commands that revert the status of OpenGL context
63  *     to the state before execution of BeforeDraw(). This method is called
64  *     once in the end of drawing cycle.</li>
65  * </ul>
66  * Each of these methods receives NIS_DrawList and DrawType, both identify the
67  * OpenGL draw list that should be filled with commands. Based on DrawType
68  * you will be able to define different presentation - the most important case
69  * is how hilighted (selected) interactive object is presented.
70  * <p>
71  * For advanced purposes you also can redefine the virtual method redraw(), it
72  * is dedicated to higher-level management of draw lists and ordering of
73  * their update when necessary.  
74  *
75  * @section nis_drawer_distinction Distinction of Drawer instances 
76  * Every Drawer should define which interactive objects it may manage and
77  * which - may not. The same idea could be shaped alternatively: every
78  * interactive object should understand to what Drawer it can attach itself.
79  * This question is answerd by special virtual method IsEqual() that compares
80  * two Drawers of the same type. <b>Two instances of Drawer are equal if they
81  * have the same set of visual properties that are implemented in BeforeDraw().
82  * </b> The method IsEqual() is the core of Drawer architecture and it must
83  * be implemented very carefully for any new type. Particularly, for any
84  * derived class the method IsEqual() should first call the same method of
85  * its superclass.
86  * <p>
87  * For the optimal efficiency of OpenGL drawing it is better to keep the size
88  * of draw list (i.e., the number of interactive objects in a Drawer instance)
89  * not too small and not too big. The latter limitation is entered by the
90  * protected field myObjPerDrawer. It is used in method IsEqual() of the base
91  * Drawer class: two Drawers are not equal if they are initialized on objects
92  * that have too different IDs -- even if all visual properties of these two
93  * Drawer instances coincide.
94  * <p>
95  * @section nis_drawer_cloning Cloning Drawer instances
96  * It is possible to clone a Drawer instance with the viryual method Assign().
97  * This method copies all visual properties and other important data from the
98  * Drawer provided as parameter. Method Clone() also should be very carefully
99  * implemented for any new Drawer type, to make sure that all necessary data
100  * fields and structures are properly copied.
101  */
102
103 class NIS_Drawer : public Standard_Transient
104 {
105  public:
106 #if defined(WNT) && (_MSC_VER >= 1400)
107   enum DrawType : unsigned int {
108 #else
109   enum DrawType {
110 #endif
111     Draw_Normal         = 0,
112     Draw_Top            = 1,
113     Draw_Transparent    = 2,
114     Draw_Hilighted      = 3,
115     Draw_DynHilighted   = 4
116   };
117
118  public:
119   // ---------- PUBLIC METHODS ----------
120
121
122   /**
123    * Empty constructor.
124    */
125   inline NIS_Drawer ()
126    : myTransparency     (0.f),
127      myIniId            (0),
128      myObjPerDrawer     (1024),
129      myCtx              (0L)
130    {}
131
132   /**
133    * Destructor.
134    */
135   Standard_EXPORT virtual ~NIS_Drawer ();
136
137   /**
138    * Query the Interactive Context.
139    */
140   inline NIS_InteractiveContext * GetContext () const
141   { return myCtx; }
142
143   /**
144    * Copy the relevant information from another instance of Drawer.
145    * raises exception if theOther has incompatible type (test IsKind).
146    */
147   Standard_EXPORT virtual void  Assign  (const Handle_NIS_Drawer& theOther);
148
149   /**
150    * Create a3D bounding box of drawn objects.
151    * @param pView
152    *   In not NULL, only objects visible in this view are taken.
153    */
154   Standard_EXPORT virtual const Bnd_B3f&
155                                 GetBox  (const NIS_View * pView = 0L) const;
156
157   /**
158    * Mark all draw lists for update
159    */
160   Standard_EXPORT void          SetUpdated (const DrawType theType) const;
161
162   Standard_EXPORT void          SetUpdated (const DrawType theType1,
163                                             const DrawType theType2) const;
164
165   Standard_EXPORT void          SetUpdated (const DrawType theType1,
166                                             const DrawType theType2,
167                                             const DrawType theType3) const;
168
169   Standard_EXPORT void          SetUpdated (const DrawType theType1,
170                                             const DrawType theType2,
171                                             const DrawType theType3,
172                                             const DrawType theType4) const;
173
174   /**
175    * Switch on/off the dynamic hilight of the given object in the
176    * given view.
177    * @param isHilighted
178    *   True if the object should be hilighted, False - if not hilighted
179    * @param theObj
180    *   Object instance that should be hilighted or unhilighted.
181    * @param theView
182    *   View where the status of object must be changed. If NULL, the object
183    *   is hilighted/unhilighted in all views.
184    */
185   Standard_EXPORT void          SetDynamicHilighted
186                                    (const Standard_Boolean      isHilighted,
187                                     const Handle_NIS_InteractiveObject& theObj,
188                                     const Handle_NIS_View&      theView = 0L);
189
190   /**
191    * Hash value, for Map interface.
192    */ 
193   Standard_EXPORT virtual Standard_Integer
194                                 HashCode(const Standard_Integer theN) const;
195
196   /**
197    * Matching two instances, for Map interface.
198    */
199   Standard_EXPORT virtual Standard_Boolean
200                                 IsEqual (const Handle_NIS_Drawer& theOth) const;
201
202   /**
203    * Obtain the iterator of IDs of associated objects.
204    */
205   inline TColStd_MapIteratorOfPackedMapOfInteger
206                                 ObjectIterator   () const
207   { return TColStd_MapIteratorOfPackedMapOfInteger (myMapID); }
208
209   /**
210    * Query associated draw lists.
211    */
212   inline NCollection_List<NIS_DrawList *>
213                                 GetLists() const
214   { return myLists; }
215  
216 protected:
217   /**
218    * Called to add draw list IDs to ex-list Ids of view. These draw lists are
219    * eventually released in the callback function, before anything is displayed
220    */
221   Standard_EXPORT void UpdateExListId   (const Handle_NIS_View& theView) const;
222
223   // ---------- PROTECTED METHODS ----------
224
225   /**
226    * Called before execution of Draw(), once per group of interactive objects.
227    */
228   Standard_EXPORT virtual void  BeforeDraw
229                                         (const DrawType         theType,
230                                          const NIS_DrawList&    theDrawList );
231
232   /**
233    * Called after execution of Draw(), once per group of interactive objects.
234    */
235   Standard_EXPORT virtual void  AfterDraw
236                                         (const DrawType         theType,
237                                          const NIS_DrawList&    theDrawList);
238
239   /**
240    * Main function: display the given interactive object in the given view.
241    */
242   Standard_EXPORT virtual void  Draw    (const Handle_NIS_InteractiveObject&,
243                                          const DrawType         theType,
244                                          const NIS_DrawList&    theDrawList)= 0;
245
246   Standard_EXPORT virtual void  redraw  (const DrawType         theType,
247                                          const Handle_NIS_View& theView);
248
249   Standard_EXPORT void  addObject       (const NIS_InteractiveObject * theObj,
250                                          const Standard_Boolean isShareList,
251                                          const Standard_Boolean isUpVws);
252
253   Standard_EXPORT void  removeObject    (const NIS_InteractiveObject * theObj,
254                                          const Standard_Boolean        isUpVws);
255
256   Standard_EXPORT virtual NIS_DrawList*
257                         createDefaultList (const Handle_NIS_View&) const;
258
259  protected:
260   //! Get the number of interactive objects in this drawer
261   inline Standard_Integer      NObjects() const
262   { return myMapID.Extent(); }
263
264  private:
265   // ---------- PRIVATE (PROHIBITED) METHODS ----------
266
267   NIS_Drawer             (const NIS_Drawer& theOther);
268   NIS_Drawer& operator = (const NIS_Drawer& theOther);
269
270   // ---------- PRIVATE METHODS ----------
271   void                  prepareList (const NIS_Drawer::DrawType theType,
272                                      const NIS_DrawList&        theDrawLst,
273                                      const TColStd_PackedMapOfInteger& mapObj);
274
275  protected:
276 // ---------- PROTECTED FIELDS ----------  
277   NCollection_List<NIS_DrawList*>       myLists;
278   Standard_ShortReal                    myTransparency;  
279   //! ID of the initializing InteractiveObject. It is never changed, can be
280   //! used to compute hash code of the Drawer instance.
281   Standard_Integer                      myIniId;
282   //! Maximal range of IDs of objects in one drawer. Limits the size of
283   //! draw lists. Can be initialized only in constructor (default 1024). It is
284   //! strictly prohibited to change this value outside the constructor.
285   Standard_Integer                      myObjPerDrawer;
286
287  private:
288   // ---------- PRIVATE FIELDS ----------
289
290   NIS_InteractiveContext                * myCtx;
291   TColStd_PackedMapOfInteger            myMapID;
292   Bnd_B3f                               myBox;
293
294   friend class NIS_InteractiveContext;
295   friend class NIS_InteractiveObject;
296   friend class NIS_View;
297
298  public:
299 // Declaration of CASCADE RTTI
300 DEFINE_STANDARD_RTTI (NIS_Drawer)
301 };
302
303 // Definition of HANDLE object using Standard_DefineHandle.hxx
304 DEFINE_STANDARD_HANDLE (NIS_Drawer, Standard_Transient)
305
306 //=======================================================================
307 //function : HashCode
308 //purpose  : 
309 //=======================================================================
310
311 inline Standard_Integer HashCode (const Handle_NIS_Drawer& theDrawer,
312                                   const Standard_Integer   theN)
313 { return theDrawer.IsNull() ? 0 : theDrawer->HashCode (theN); }
314
315 //=======================================================================
316 //function : IsEqual
317 //purpose  : 
318 //=======================================================================
319
320 inline Standard_Boolean IsEqual  (const Handle_NIS_Drawer& theDrawer1,
321                                   const Handle_NIS_Drawer& theDrawer2)
322 { return theDrawer1.IsNull()? Standard_False: theDrawer1->IsEqual(theDrawer2); }
323
324 #ifdef WNT
325 #pragma warning (pop)
326 #endif
327
328 #endif