BaseNode.hh 19.2 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
Jan Möbius's avatar
Jan Möbius committed
4
 *      Copyright (C) 2001-2010 by Computer Graphics Group, RWTH Aachen      *
Jan Möbius's avatar
Jan Möbius committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 *                           www.openflipper.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenFlipper.                                        *
 *                                                                           *
 *  OpenFlipper is free software: you can redistribute it and/or modify      *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenFlipper is distributed in the hope that it will be useful,           *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenFlipper. If not,                                  *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
37
 *   $Revision$                                                       *
Jan Möbius's avatar
Jan Möbius committed
38
39
40
41
 *   $Author$                                                      *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71



//=============================================================================
//
//  CLASS BaseNode
//
//=============================================================================


#ifndef ACG_BASE_NODE_HH
#define ACG_BASE_NODE_HH


//== INCLUDES =================================================================

// ACG
#include "../Math/VectorT.hh"
#include "../GL/GLState.hh"
#include "../Config/ACGDefines.hh"

// Qt
//#include <qgl.h>
#include <QMouseEvent>

// stdc++
#include <list>
#include <string>
#include <algorithm>
#include <iostream>
Jan Möbius's avatar
Jan Möbius committed
72
#include <ACG/Scenegraph/DrawModes.hh>
Jan Möbius's avatar
 
Jan Möbius committed
73
74
75
76
77
78
79
80
81
82
83
84
85


//== NAMESPACES ===============================================================


namespace ACG {
namespace SceneGraph {


//== CLASS DEFINITION =========================================================


/// What target to use for picking
86
enum PickTarget 
Jan Möbius's avatar
 
Jan Möbius committed
87
{
88
89
  /// picks faces (may not be implemented for all nodes)
  PICK_CELL,
Jan Möbius's avatar
 
Jan Möbius committed
90
91
92
93
94
95
96
  /// picks faces (should be implemented for all nodes)
  PICK_FACE,
  /// picks edges (may not be implemented for all nodes)
  PICK_EDGE,
  /// picks verices (may not be implemented for all nodes)
  PICK_VERTEX,
  /// pick any of the prior targets (should be implemented for all nodes)
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
97
98
99
100
101
  PICK_ANYTHING,

  /// picks only visible front edges (may not be implemented for all nodes)
  PICK_FRONT_EDGE,
  /// picks only visible front verices (may not be implemented for all nodes)
Henrik Zimmer's avatar
Henrik Zimmer committed
102
103
104
105
  PICK_FRONT_VERTEX,

  /// Pick spline curve or surface (picks u or u,v coords respectively)
  PICK_SPLINE
Jan Möbius's avatar
 
Jan Möbius committed
106
107
108
109
110
111
112
113
114
115
116
117
118
};


/// Convinience macro that sets up the BaseNode::className() function
#define ACG_CLASSNAME(_className) \
 virtual const std::string& className() const { \
  static std::string cname( #_className ); return cname; \
}


/** \class BaseNode BaseNode.hh <ACG/Scenegraph/BaseNode.hh>

    This is the base for all scenegraph nodes. All virtual functions
119
    should be reimplemented when inheriting from this class.  
Jan Möbius's avatar
 
Jan Möbius committed
120
121
**/

122
class ACGDLLEXPORT BaseNode 
Jan Möbius's avatar
 
Jan Möbius committed
123
124
125
126
127
128
129
130
131
{
public:


  /// Default constructor
  BaseNode(BaseNode* _parent=0, std::string _name="<unknown>");

  /// Put this node between _parent and _child
  BaseNode(BaseNode* _parent, BaseNode* _child, std::string _name="<unknown>");
132
 
Jan Möbius's avatar
 
Jan Möbius committed
133
134
135
  /// Destructor.
  virtual ~BaseNode();

136
137
138
139
140
141
142
143
  /** \brief Delete the whole subtree of this node
  *
  * This function will remove the whole subtree below this node.
  * All children in this nodes bubtree will be automatically removed from the tree
  * and their destructor is called.
  * The node itself will be removed from the list of its parents children.
  * Afterwards it will also call its own destructor.
  **/
Jan Möbius's avatar
 
Jan Möbius committed
144
145
146
147
148
149
150
151
152
153
  void delete_subtree();


  // --- basic interface ---

  /// Return class name (implemented by the ACG_CLASSNAME macro)
  virtual const std::string& className() const = 0;

  /** Return a list of available draw modes for this node: should be OR'ed
      from the items of the enum DrawModeIDs. */
Jan Möbius's avatar
Jan Möbius committed
154
  virtual DrawModes::DrawMode availableDrawModes() const { return DrawModes::NONE; }
Jan Möbius's avatar
 
Jan Möbius committed
155
156
157

  /** Compute the bounding box of this node and update the values
      _bbMin and _bbMax accordingly. Do not initialize _bbMin and
158
      _bbMax since they may already store values of previous nodes' 
Jan Möbius's avatar
 
Jan Möbius committed
159
160
      bounding box computation.
  */
161
  virtual void boundingBox(Vec3d& /* _bbMin */, Vec3d& /*_bbMax*/ ) {}
Jan Möbius's avatar
 
Jan Möbius committed
162
163
164
165

  /** This function is called when traversing the scene graph and
      arriving at this node. It can be used to store GL states that
      will be changed in order to restore then in the leave()
166
167
      function.  
      \see MaterialNode 
Jan Möbius's avatar
 
Jan Möbius committed
168
  */
Jan Möbius's avatar
Jan Möbius committed
169
  virtual void enter(GLState& /*_state */, DrawModes::DrawMode /*_drawMode*/ ) {}
Jan Möbius's avatar
 
Jan Möbius committed
170
171

  /** Draw this node using the draw modes _drawMode */
Jan Möbius's avatar
Jan Möbius committed
172
  virtual void draw(GLState& /* _state */, DrawModes::DrawMode /* _drawMode */)  {}
Jan Möbius's avatar
 
Jan Möbius committed
173
174

  /** The leave function is used to restore GL states the have been changed.
175
      This function must restore the status before enter() ! 
Jan Möbius's avatar
 
Jan Möbius committed
176
  */
Jan Möbius's avatar
Jan Möbius committed
177
  virtual void leave(GLState& /* _state */, DrawModes::DrawMode /* _drawMode */) {}
Jan Möbius's avatar
 
Jan Möbius committed
178

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
179
180
181
182
183
184
  /** This function is called when traversing the scene graph during picking
      and arriving at this node. It can be used to store GL states that
      will be changed in order to restore then in the leavePick()
      function. Its default implementation will call the enter() function.
  */
  virtual void enterPick(GLState& _state , PickTarget _target,
Jan Möbius's avatar
Jan Möbius committed
185
                         DrawModes::DrawMode _drawMode );
186
  
Jan Möbius's avatar
 
Jan Möbius committed
187
188
189
190
191
  /** Draw the node using the GL picking name stack. The node's ID
      will already be on the name stack, so only names identifing e.g. faces
      should be used ( by glLoadName() ).
  */
  virtual void pick(GLState& /* _state */, PickTarget /* _target */ ) {}
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
192
193
194
195
196
197

  /** The leavePick function is used to restore GL states the have been changed.
      This function must restore the status before enterPick() !
      Its default implementation will call the leave() function.
  */
  virtual void leavePick(GLState& _state, PickTarget _target,
Jan Möbius's avatar
Jan Möbius committed
198
                         DrawModes::DrawMode _drawMode );
199
  
Jan Möbius's avatar
 
Jan Möbius committed
200
201
202
203
  /** Enable or Disable picking for this node
   *  ( default: enabled )
   */
  void enablePicking(bool _enable) { pickingEnabled_ = _enable; };
204
205
  
  /** Check if picking is enabled for this node 
Jan Möbius's avatar
 
Jan Möbius committed
206
207
   */
  bool pickingEnabled() { return pickingEnabled_; };
208
  
Jan Möbius's avatar
 
Jan Möbius committed
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
  /// Handle mouse event (some interaction, e.g. modeling)
  virtual void mouseEvent(GLState& /* _state */, QMouseEvent* /* _event */ ) {}

  /// mark node for redrawn
  void setDirty (bool _dirty = true) { dirty_ = _dirty; }

  /// Check if node should be redrawn
  bool isDirty () const { return dirty_; }


  // --- iterators ---

  /// allows to iterate over children
  typedef std::list<BaseNode*>::const_iterator ConstChildIter;
  /// allows to iterate over children
  typedef std::list<BaseNode*>::iterator ChildIter;

  /// allows to reverse iterate over children
  typedef std::list<BaseNode*>::const_reverse_iterator ConstChildRIter;
  /// allows to reverse iterate over children
  typedef std::list<BaseNode*>::reverse_iterator ChildRIter;

  /// Returns: begin-iterator of children
  ChildIter childrenBegin() { return children_.begin(); }
  /// Same but \c cont
  ConstChildIter childrenBegin() const { return children_.begin(); }
  /// Returns: end-iterator of children
  ChildIter childrenEnd() { return children_.end(); }
  /// Same but \c const
  ConstChildIter childrenEnd() const { return children_.end(); }
239
  
Jan Möbius's avatar
 
Jan Möbius committed
240
241
242
243
244
245
246
247
248
249
250
251
  /// Returns: reverse begin-iterator of children
  ChildRIter childrenRBegin() { return children_.rbegin(); }
  /// Same but const
  ConstChildRIter childrenRBegin() const { return children_.rbegin(); }
  /// Returns: reverse end-iterator of children
  ChildRIter childrenREnd() { return children_.rend(); }
  /// Same but \c const
  ConstChildRIter childrenREnd() const { return children_.rend(); }




252
  
Jan Möbius's avatar
 
Jan Möbius committed
253
254
255
  // --- insert / remove ---

  /// Insert _node at the end of the list of children.
256
  void push_back(BaseNode* _node) 
Jan Möbius's avatar
 
Jan Möbius committed
257
258
259
260
261
262
263
264
265
266
267
  {
    if (_node)
    {
      children_.push_back(_node);
      _node->parent_=this;
    }
  }

  /** Remove child node at position _pos.
      This _pos \a must \a be \a reachable from childrenBegin().<br>
      This method has no effect if called with childrenEnd() as parameter.  */
268
  void remove(ChildIter _pos) 
Jan Möbius's avatar
 
Jan Möbius committed
269
270
271
  {
    if (_pos == childrenEnd()) return;
    //(*_pos)->parent_=0;
272
    children_.erase(_pos); 
Jan Möbius's avatar
 
Jan Möbius committed
273
274
275
276
277
278
279
280
281
282
283
  }

  /// number of children
  unsigned int nChildren() const { return children_.size(); }

  /** Find a specific node in the list of children.<br>
      This method is designed to convert a node pointer to an iterator
      that may be used e.g. for insert()'ing a new node at a distinct
      position.<br>
      Returns childrenEnd() if no appropriate node is found.
   */
284
  ChildIter find(BaseNode* _node) 
Jan Möbius's avatar
 
Jan Möbius committed
285
286
287
  {
    ChildIter i=std::find(children_.begin(),children_.end(),_node);
    return i;
288
  } 
Jan Möbius's avatar
 
Jan Möbius committed
289
290
291


  /** Find a node of a given name */
292
  
Jan Möbius's avatar
 
Jan Möbius committed
293
294
295
296
297
298
299
300
301
302
303
304
305
  BaseNode * find( const std::string & _name )
  {
    if ( name() == _name )
      return this;

    for ( BaseNode::ChildIter cIt = childrenBegin();
	  cIt != childrenEnd(); ++cIt )
    {
      BaseNode * n = (*cIt)->find( _name );
      if ( n ) return n;
    }

    return 0;
306
307
  } 
  
Jan Möbius's avatar
 
Jan Möbius committed
308

309
  /// Get the nodes parent node
Jan Möbius's avatar
 
Jan Möbius committed
310
  BaseNode* parent() { return parent_; }
311
312
313
314
315
316
  
  /** \brief Set the parent of this node.
  *
  * This function will remove this node from its original parents children, if the parent exists.
  * And will add it to the new parents children. 
  */
Jan Möbius's avatar
 
Jan Möbius committed
317
318
319
320
321
  void set_parent(BaseNode* _parent);


  // --- status info ---

322
  
Jan Möbius's avatar
 
Jan Möbius committed
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
  /// Status modi
  enum StatusMode
  {
    /// Draw node & children
    Active = 0x1,
    /// Hide this node, but draw children
    HideNode  = 0x2,
    /// Draw this node, but hide children
    HideChildren = 0x4,
    /// Hide this node and its children
    HideSubtree  = 0x8
  };
  /// Get node's status
  StatusMode status() const { return status_; }
  /// Set the status of this node.
  void set_status(StatusMode _s) { status_ = _s; }
  /// Hide Node: set status to HideNode
  void hide() { set_status(HideNode); }
  /// Show node: set status to Active
  void show() { set_status(Active); }
  /// Is node visible (status == Active)?
  bool visible() { return status_ == Active; }
  /// Is node not visible (status != Active)?
  bool hidden() { return status_ != Active; }


  /// Returns: name of node (needs not be unique)
  std::string name() const { return name_; }
351
  /// rename a node 
Jan Möbius's avatar
 
Jan Möbius committed
352
353
  void name(const std::string& _name) { name_ = _name; }

354
  
Jan Möbius's avatar
 
Jan Möbius committed
355
356
357
358
  /** Get unique ID of node. IDs are always positive and may be used
      e.g. for picking.
    */
  unsigned int id() const { return id_; }
359
  
Jan Möbius's avatar
 
Jan Möbius committed
360
361
362
363
364


  //--- draw mode ---

  /// Return the own draw modes of this node
Jan Möbius's avatar
Jan Möbius committed
365
  DrawModes::DrawMode drawMode() const { return drawMode_; }
366
  /** Set this node's own draw mode. It will be used for drawing instead of 
Jan Möbius's avatar
 
Jan Möbius committed
367
      the the global draw mode. */
Jan Möbius's avatar
Jan Möbius committed
368
  void drawMode(DrawModes::DrawMode _drawMode) { drawMode_ = _drawMode; }
Jan Möbius's avatar
 
Jan Möbius committed
369
370
371
372
373
374
375
376
377

  //--- traverse type ---

  /// Node traverse types
  enum TraverseMode
  {
    /// Execute action on node first and then on its children
    NodeFirst = 0x1,
    /// Execute action the children first and then on this node
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
378
379
380
    ChildrenFirst = 0x2,
    /// Draw node in second pass
    SecondPass = 0x4
Jan Möbius's avatar
 
Jan Möbius committed
381
382
383
  };

  /// Return how the node should be traversed
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
384
  unsigned int traverseMode () const { return traverseMode_; }
Jan Möbius's avatar
 
Jan Möbius committed
385
386

  /// Set traverse mode for node
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
387
  void setTraverseMode(unsigned int _mode) { traverseMode_ = _mode; }
388
389
390

  //===========================================================================
  /** @name Render pass controls
391
392
393
394
395
  *  The render pass controls are only used during multipass traversal. There
  *  are two types of multipass controls. One type controls if the enter and
  *  leave functions of the nodes are used (RenderStatusPass) or if the actual 
  *  draw function is called (RenderDrawPass). The bitmasks define if the functions
  *  are called by the traverse_multipass operation. The bitmask are initialized
396
397
  *  to run in the first path.\n
  *
398
  * @{ */
399
400
401
  //===========================================================================

public:
402
403
404
405
  
  /// Multipass pass bit mask type
  typedef unsigned int MultipassBitMask;
  
Jan Möbius's avatar
Jan Möbius committed
406
407
408
409
410
411
412
413
414
415
416
417
418
419

  /// This enum should be used to enable rendering of a node in different
  enum PASSES {
    NOPASS = 0,
    ALLPASSES = 1 << 0,
    PASS_1    = 1 << 1,
    PASS_2    = 1 << 2,
    PASS_3    = 1 << 3,
    PASS_4    = 1 << 4,
    PASS_5    = 1 << 5,
    PASS_6    = 1 << 6,
    PASS_7    = 1 << 7,
    PASS_8    = 1 << 8
  };
420
421
422
  
  /** \brief Get the current multipass settings for the nodes status functions
  *
Jan Möbius's avatar
Jan Möbius committed
423
424
  * Get a bitmask defining in which traverse pass the enter and leave nodes are used. Use
  * the PASSES enum above to control multipass rendering!
425
426
427
428
429
430
431
432
  *
  * @return Bitmask defining in which traverse pass the enter and leave nodes are used 
  */
  MultipassBitMask multipassStatus() const {return multipassStatus_;};
  
  
  /** \brief Set multipass settings for the nodes status functions
  *
Jan Möbius's avatar
Jan Möbius committed
433
434
435
  * Set a bitmask defining in which traverse pass the enter and leave nodes are used. Use
  * the PASSES enum above to control multipass rendering!
  *
436
437
438
439
440
441
442
443
444
  * Set to ALLPASSES if you want to render in all passes  
  *
  * @param _passStatus Bitmask defining in which traverse pass the enter and leave nodes are used 
  */
  void setMultipassStatus(const MultipassBitMask _passStatus) { multipassStatus_ = _passStatus; };
  
  /** \brief Set multipass status to traverse in a specific pass
  *
  * Change multipass setting for the nodes status functions. The node will
Jan Möbius's avatar
Jan Möbius committed
445
446
  * call its enter and leave functions in the given pass if its set active.
  * Use the PASSES enum above to control multipass rendering!
447
448
449
450
451
452
453
454
455
  *
  * @param _i Pass in which the node should be rendered
  * @param _active Activate or deactivate in this pass?
  */
  void multipassStatusSetActive(const unsigned int _i, bool _active);
 
  /** \brief Get multipass status to traverse in a specific pass
  *
  * Check multipass setting for the nodes status functions if they should
Jan Möbius's avatar
Jan Möbius committed
456
457
  * be called in the given render pass. 
  * Use the PASSES enum above to control multipass rendering!
458
459
460
461
462
463
464
465
466
467
  *
  * @param _i Check this pass if the nodes enter/leave functions are active
  */  
  bool multipassStatusActive(const unsigned int _i) const;  
  
  
  
  /** \brief Get the current multipass settings for the node
  *
  * Get a bitmask defining in which traverse path an action is applied to the node. (1-indexed)
Jan Möbius's avatar
Jan Möbius committed
468
  * Use the PASSES enum above to control multipass rendering!
469
470
471
472
473
474
475
476
477
478
  *
  * @return Bitmask defining in which traverse passes an action is applied to the node.
  */
  MultipassBitMask multipassNode() const {return multipassNode_;};  
  
  
  
  /** \brief Set multipass settings for the node
  *
  * Set a bitmask defining in which traverse path an action is applied to the node. (1-indexed)
Jan Möbius's avatar
Jan Möbius committed
479
480
  * Set to ALLPASSES if you want to render in all passes.
  * Use the PASSES enum above to control multipass rendering!
481
482
483
484
485
486
487
488
489
  *
  * @param _passNode Bitmask defining in which traverse passes an action is applied to the node.
  */
  void setMultipassNode(const MultipassBitMask _passNode) { multipassNode_ = _passNode; };  
  
  /** \brief Set Node status to traverse in a specific pass
  *
  * Change multipass setting for the node. An action will be
  * applied to this node in the given pass.
Jan Möbius's avatar
Jan Möbius committed
490
  * Use the PASSES enum above to control multipass rendering!
491
492
493
494
495
496
497
498
499
500
  *
  * @param _i      Pass in which the node should be rendered
  * @param _active Enable or disable node in this pass?
  */
  void multipassNodeSetActive(const unsigned int _i , bool _active);
  
  /** \brief Get Node status to traverse in a specific pass
  *
  * Check multipass setting for the node if an action will be
  * applied in the given pass.
Jan Möbius's avatar
Jan Möbius committed
501
  * Use the PASSES enum above to control multipass rendering!
502
503
504
505
  *
  * @param _i Check this pass if an action will be applied to the node.
  */  
  bool multipassNodeActive(const unsigned int _i) const;  
506
507
508

private:

509
510
511
512
513
514
515
516
517
518
519
  /** multi pass bit mask (1-indexed)
  * Defines in which multipass runs the enter and leave functions should be called.
  * (Only applies during multipass traversal!)
  */
  MultipassBitMask multipassStatus_;
  
  /** multi pass bit mask (1-indexed)
  * Defines in which multipass runs an action should be applied to the node.
  * (Only applies during multipass traversal!)
  */  
  MultipassBitMask multipassNode_;
520
521
522
523

  /** @} */

private:
Jan Möbius's avatar
 
Jan Möbius committed
524
525
526
527
528
529

  /// Copy constructor. Disabled.
  BaseNode(const BaseNode&);
  /// Assigment operator. Disabled.
  void operator=(const BaseNode&);

530
  
Jan Möbius's avatar
 
Jan Möbius committed
531
532
533
534
535
536
537
538
  /// pointer to parent node
  BaseNode* parent_;

  /// name of node
  std::string name_;

  /// node status()
  StatusMode status_;
539
  
Jan Möbius's avatar
 
Jan Möbius committed
540
  /// list of children
541
  std::list<BaseNode*> children_; 
Jan Möbius's avatar
 
Jan Möbius committed
542
543
544
545
546
547
548
549

  /// used to provide unique IDs to nodes
  static unsigned int last_id_used__;

  /// ID of node
  unsigned int id_;

  /// private draw mode
Jan Möbius's avatar
Jan Möbius committed
550
  DrawModes::DrawMode drawMode_;
551
  
Jan Möbius's avatar
 
Jan Möbius committed
552
553
554
555
556
557
558
559
560
  /** Flag indicating if picking should be done for this object
   * This flag has to be checked by your node if you implement picking
   */
  bool pickingEnabled_;

  /// Flag indicating that the node has to be redrawn
  bool dirty_;

  /// traverse mode
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
561
  unsigned int traverseMode_;
Jan Möbius's avatar
 
Jan Möbius committed
562
563
564
565
566
567
568
569
570
};


//=============================================================================
} // namespace SceneGraph
} // namespace ACG
//=============================================================================
#endif // ACG_BASE_NODE_HH defined
//=============================================================================