Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TEveElement.cxx
Go to the documentation of this file.
1 // @(#)root/eve:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TEveElement.h"
13 #include "TEveCompound.h"
14 #include "TEveTrans.h"
15 #include "TEveManager.h"
16 #include "TEveSelection.h"
17 #include "TEveProjectionBases.h"
18 #include "TEveProjectionManager.h"
19 
20 #include "TBuffer3D.h"
21 #include "TBuffer3DTypes.h"
22 #include "TVirtualPad.h"
23 #include "TVirtualViewer3D.h"
24 
25 #include "TGeoMatrix.h"
26 
27 #include "TClass.h"
28 #include "TPRegexp.h"
29 #include "TROOT.h"
30 #include "TColor.h"
31 #include "TEveBrowser.h"
32 #include "TGListTree.h"
33 #include "TGPicture.h"
34 
35 #include <algorithm>
36 
37 /** \class TEveElement::TEveListTreeInfo
38 \ingroup TEve
39 Structure holding information about TGListTree and TGListTreeItem
40 that represents given TEveElement. This needed because each element
41 can appear in several list-trees as well as several times in the
42 same list-tree.
43 */
44 
45 ClassImp(TEveElement::TEveListTreeInfo);
46 
47 /** \class TEveElement
48 \ingroup TEve
49 Base class for TEveUtil visualization elements, providing hierarchy
50 management, rendering control and list-tree item management.
51 */
52 
53 ClassImp(TEveElement);
54 
55 const TGPicture* TEveElement::fgRnrIcons[4] = { 0 };
56 const TGPicture* TEveElement::fgListTreeIcons[9] = { 0 };
57 
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Default constructor.
60 
61 TEveElement::TEveElement() :
62  fParents (),
63  fChildren (),
64  fCompound (0),
65  fVizModel (0),
66  fVizTag (),
67  fNumChildren (0),
68  fParentIgnoreCnt (0),
69  fTopItemCnt (0),
70  fDenyDestroy (0),
71  fDestroyOnZeroRefCnt (kTRUE),
72  fRnrSelf (kTRUE),
73  fRnrChildren (kTRUE),
74  fCanEditMainColor (kFALSE),
75  fCanEditMainTransparency(kFALSE),
76  fCanEditMainTrans (kFALSE),
77  fMainTransparency (0),
78  fMainColorPtr (0),
79  fMainTrans (0),
80  fItems (),
81  fSource (),
82  fUserData (0),
83  fPickable (kFALSE),
84  fSelected (kFALSE),
85  fHighlighted (kFALSE),
86  fImpliedSelected (0),
87  fImpliedHighlighted (0),
88  fCSCBits (0),
89  fChangeBits (0),
90  fDestructing (kNone)
91 {
92 }
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 /// Constructor.
96 
97 TEveElement::TEveElement(Color_t& main_color) :
98  fParents (),
99  fChildren (),
100  fCompound (0),
101  fVizModel (0),
102  fVizTag (),
103  fNumChildren (0),
104  fParentIgnoreCnt (0),
105  fTopItemCnt (0),
106  fDenyDestroy (0),
107  fDestroyOnZeroRefCnt (kTRUE),
108  fRnrSelf (kTRUE),
109  fRnrChildren (kTRUE),
110  fCanEditMainColor (kFALSE),
111  fCanEditMainTransparency(kFALSE),
112  fCanEditMainTrans (kFALSE),
113  fMainTransparency (0),
114  fMainColorPtr (&main_color),
115  fMainTrans (0),
116  fItems (),
117  fSource (),
118  fUserData (0),
119  fPickable (kFALSE),
120  fSelected (kFALSE),
121  fHighlighted (kFALSE),
122  fImpliedSelected (0),
123  fImpliedHighlighted (0),
124  fCSCBits (0),
125  fChangeBits (0),
126  fDestructing (kNone)
127 {
128 }
129 
130 ////////////////////////////////////////////////////////////////////////////////
131 /// Copy constructor. Does shallow copy.
132 /// For deep-cloning and children-cloning, see:
133 /// ~~~ {.cpp}
134 /// TEveElement* CloneElementRecurse(Int_t level)
135 /// void CloneChildrenRecurse(TEveElement* dest, Int_t level)
136 /// ~~~
137 /// 'TRef fSource' is copied but 'void* UserData' is NOT.
138 /// If the element is projectable, its projections are NOT copied.
139 ///
140 /// Not implemented for most sub-classes, let us know.
141 /// Note that sub-classes of TEveProjected are NOT and will NOT be copyable.
142 
143 TEveElement::TEveElement(const TEveElement& e) :
144  fParents (),
145  fChildren (),
146  fCompound (0),
147  fVizModel (0),
148  fVizTag (e.fVizTag),
149  fNumChildren (0),
150  fParentIgnoreCnt (0),
151  fTopItemCnt (0),
152  fDenyDestroy (0),
153  fDestroyOnZeroRefCnt (e.fDestroyOnZeroRefCnt),
154  fRnrSelf (e.fRnrSelf),
155  fRnrChildren (e.fRnrChildren),
156  fCanEditMainColor (e.fCanEditMainColor),
157  fCanEditMainTransparency(e.fCanEditMainTransparency),
158  fCanEditMainTrans (e.fCanEditMainTrans),
159  fMainTransparency (e.fMainTransparency),
160  fMainColorPtr (0),
161  fMainTrans (0),
162  fItems (),
163  fSource (e.fSource),
164  fUserData (0),
165  fPickable (e.fPickable),
166  fSelected (kFALSE),
167  fHighlighted (kFALSE),
168  fImpliedSelected (0),
169  fImpliedHighlighted (0),
170  fCSCBits (e.fCSCBits),
171  fChangeBits (0),
172  fDestructing (kNone)
173 {
174  SetVizModel(e.fVizModel);
175  if (e.fMainColorPtr)
176  fMainColorPtr = (Color_t*)((const char*) this + ((const char*) e.fMainColorPtr - (const char*) &e));
177  if (e.fMainTrans)
178  fMainTrans = new TEveTrans(*e.fMainTrans);
179 }
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 /// Destructor. Do not call this method directly, either call Destroy() or
183 /// Annihilate(). See also DestroyElements() and AnnihilateElements() if you
184 /// need to delete all children of an element.
185 
186 TEveElement::~TEveElement()
187 {
188  if (fDestructing != kAnnihilate)
189  {
190  fDestructing = kStandard;
191  RemoveElementsInternal();
192 
193  for (List_i p=fParents.begin(); p!=fParents.end(); ++p)
194  {
195  (*p)->RemoveElementLocal(this);
196  (*p)->fChildren.remove(this);
197  --((*p)->fNumChildren);
198  }
199  }
200 
201  fParents.clear();
202 
203  for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
204  i->fTree->DeleteItem(i->fItem);
205 
206  delete fMainTrans;
207 }
208 
209 ////////////////////////////////////////////////////////////////////////////////
210 /// Called before the element is deleted, thus offering the last chance
211 /// to detach from acquired resources and from the framework itself.
212 /// Here the request is just passed to TEveManager.
213 /// If you override it, make sure to call base-class version.
214 
215 void TEveElement::PreDeleteElement()
216 {
217  gEve->PreDeleteElement(this);
218 }
219 
220 ////////////////////////////////////////////////////////////////////////////////
221 /// Clone the element via copy constructor.
222 /// Should be implemented for all classes that require cloning support.
223 
224 TEveElement* TEveElement::CloneElement() const
225 {
226  return new TEveElement(*this);
227 }
228 
229 ////////////////////////////////////////////////////////////////////////////////
230 /// Clone elements and recurse 'level' deep over children.
231 /// - If level == 0, only the element itself is cloned (default).
232 /// - If level == -1, all the hierarchy is cloned.
233 
234 TEveElement* TEveElement::CloneElementRecurse(Int_t level) const
235 {
236  TEveElement* el = CloneElement();
237  if (level--)
238  {
239  CloneChildrenRecurse(el, level);
240  }
241  return el;
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 /// Clone children and attach them to the dest element.
246 /// If level == 0, only the direct descendants are cloned (default).
247 /// If level == -1, all the hierarchy is cloned.
248 
249 void TEveElement::CloneChildrenRecurse(TEveElement* dest, Int_t level) const
250 {
251  for (List_ci i=fChildren.begin(); i!=fChildren.end(); ++i)
252  {
253  dest->AddElement((*i)->CloneElementRecurse(level));
254  }
255 }
256 
257 
258 //==============================================================================
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 /// Virtual function for retrieving name of the element.
262 /// Here we attempt to cast the assigned object into TNamed and call
263 /// GetName() there.
264 
265 const char* TEveElement::GetElementName() const
266 {
267  static const TEveException eh("TEveElement::GetElementName ");
268 
269  TNamed* named = dynamic_cast<TNamed*>(GetObject(eh));
270  return named ? named->GetName() : "<no-name>";
271 }
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 /// Virtual function for retrieving title of the render-element.
275 /// Here we attempt to cast the assigned object into TNamed and call
276 /// GetTitle() there.
277 
278 const char* TEveElement::GetElementTitle() const
279 {
280  static const TEveException eh("TEveElement::GetElementTitle ");
281 
282  TNamed* named = dynamic_cast<TNamed*>(GetObject(eh));
283  return named ? named->GetTitle() : "<no-title>";
284 }
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 /// Virtual function for setting of name of an element.
288 /// Here we attempt to cast the assigned object into TNamed and call
289 /// SetName() there.
290 /// If you override this call NameTitleChanged() from there.
291 
292 void TEveElement::SetElementName(const char* name)
293 {
294  static const TEveException eh("TEveElement::SetElementName ");
295 
296  TNamed* named = dynamic_cast<TNamed*>(GetObject(eh));
297  if (named) {
298  named->SetName(name);
299  NameTitleChanged();
300  }
301 }
302 
303 ////////////////////////////////////////////////////////////////////////////////
304 /// Virtual function for setting of title of an element.
305 /// Here we attempt to cast the assigned object into TNamed and call
306 /// SetTitle() there.
307 /// If you override this call NameTitleChanged() from there.
308 
309 void TEveElement::SetElementTitle(const char* title)
310 {
311  static const TEveException eh("TEveElement::SetElementTitle ");
312 
313  TNamed* named = dynamic_cast<TNamed*>(GetObject(eh));
314  if (named) {
315  named->SetTitle(title);
316  NameTitleChanged();
317  }
318 }
319 
320 ////////////////////////////////////////////////////////////////////////////////
321 /// Virtual function for setting of name and title of render element.
322 /// Here we attempt to cast the assigned object into TNamed and call
323 /// SetNameTitle() there.
324 /// If you override this call NameTitleChanged() from there.
325 
326 void TEveElement::SetElementNameTitle(const char* name, const char* title)
327 {
328  static const TEveException eh("TEveElement::SetElementNameTitle ");
329 
330  TNamed* named = dynamic_cast<TNamed*>(GetObject(eh));
331  if (named) {
332  named->SetNameTitle(name, title);
333  NameTitleChanged();
334  }
335 }
336 
337 ////////////////////////////////////////////////////////////////////////////////
338 /// Virtual function called when a name or title of the element has
339 /// been changed.
340 /// If you override this, call also the version of your direct base-class.
341 
342 void TEveElement::NameTitleChanged()
343 {
344  // Nothing to do - list-tree-items take this info directly.
345 }
346 
347 //******************************************************************************
348 
349 ////////////////////////////////////////////////////////////////////////////////
350 /// Set visualization-parameter model element.
351 /// Calling of this function from outside of EVE should in principle
352 /// be avoided as it can lead to dis-synchronization of viz-tag and
353 /// viz-model.
354 
355 void TEveElement::SetVizModel(TEveElement* model)
356 {
357  if (fVizModel) {
358  --fParentIgnoreCnt;
359  fVizModel->RemoveElement(this);
360  }
361  fVizModel = model;
362  if (fVizModel) {
363  fVizModel->AddElement(this);
364  ++fParentIgnoreCnt;
365  }
366 }
367 
368 ////////////////////////////////////////////////////////////////////////////////
369 /// Find model element in VizDB that corresponds to previously
370 /// assigned fVizTag and set fVizModel accordingly.
371 /// If the tag is not found in VizDB, the old model-element is kept
372 /// and false is returned.
373 
374 Bool_t TEveElement::FindVizModel()
375 {
376  TEveElement* model = gEve->FindVizDBEntry(fVizTag);
377  if (model)
378  {
379  SetVizModel(model);
380  return kTRUE;
381  }
382  else
383  {
384  return kFALSE;
385  }
386 }
387 
388 ////////////////////////////////////////////////////////////////////////////////
389 /// Set the VizTag, find model-element from the VizDB and copy
390 /// visualization-parameters from it. If the model is not found and
391 /// fallback_tag is non-null, its search is attempted as well.
392 /// For example: ApplyVizTag("TPC Clusters", "Clusters");
393 ///
394 /// If the model-element can not be found a warning is printed and
395 /// false is returned.
396 
397 Bool_t TEveElement::ApplyVizTag(const TString& tag, const TString& fallback_tag)
398 {
399  SetVizTag(tag);
400  if (FindVizModel())
401  {
402  CopyVizParamsFromDB();
403  return kTRUE;
404  }
405  if ( ! fallback_tag.IsNull())
406  {
407  SetVizTag(fallback_tag);
408  if (FindVizModel())
409  {
410  CopyVizParamsFromDB();
411  return kTRUE;
412  }
413  }
414  Warning("TEveElement::ApplyVizTag", "entry for tag '%s' not found in VizDB.", tag.Data());
415  return kFALSE;
416 }
417 
418 ////////////////////////////////////////////////////////////////////////////////
419 /// Propagate visualization parameters to dependent elements.
420 ///
421 /// MainColor is propagated independently in SetMainColor().
422 /// In this case, as fMainColor is a pointer to Color_t, it should
423 /// be set in TProperClass::CopyVizParams().
424 ///
425 /// Render state is not propagated. Maybe it should be, at least optionally.
426 
427 void TEveElement::PropagateVizParamsToProjecteds()
428 {
429  TEveProjectable* pable = dynamic_cast<TEveProjectable*>(this);
430  if (pable && pable->HasProjecteds())
431  {
432  pable->PropagateVizParams();
433  }
434 }
435 
436 ////////////////////////////////////////////////////////////////////////////////
437 /// Propagate visualization parameters from element el (defaulting
438 /// to this) to all elements (children).
439 ///
440 /// The primary use of this is for model-elements from
441 /// visualization-parameter database.
442 
443 void TEveElement::PropagateVizParamsToElements(TEveElement* el)
444 {
445  if (el == 0)
446  el = this;
447 
448  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
449  {
450  (*i)->CopyVizParams(el);
451  }
452 }
453 
454 ////////////////////////////////////////////////////////////////////////////////
455 /// Copy visualization parameters from element el.
456 /// This method needs to be overriden by any class that introduces
457 /// new parameters.
458 /// Color is copied in sub-classes which define it.
459 /// See, for example, TEvePointSet::CopyVizParams(),
460 /// TEveLine::CopyVizParams() and TEveTrack::CopyVizParams().
461 
462 void TEveElement::CopyVizParams(const TEveElement* el)
463 {
464  fCanEditMainColor = el->fCanEditMainColor;
465  fCanEditMainTransparency = el->fCanEditMainTransparency;
466  fMainTransparency = el->fMainTransparency;
467 
468  AddStamp(kCBColorSelection | kCBObjProps);
469 }
470 
471 ////////////////////////////////////////////////////////////////////////////////
472 /// Copy visualization parameters from the model-element fVizModel.
473 /// A warning is printed if the model-element fVizModel is not set.
474 
475 void TEveElement::CopyVizParamsFromDB()
476 {
477  if (fVizModel)
478  {
479  CopyVizParams(fVizModel);
480  }
481  else
482  {
483  Warning("TEveElement::CopyVizParamsFromDB", "VizModel has not been set.");
484  }
485 }
486 
487 ////////////////////////////////////////////////////////////////////////////////
488 /// Save visualization parameters for this element with given tag.
489 ///
490 /// This function creates the instantiation code, calls virtual
491 /// WriteVizParams() and, at the end, writes out the code for
492 /// registration of the model into the VizDB.
493 
494 void TEveElement::SaveVizParams(std::ostream& out, const TString& tag, const TString& var)
495 {
496  static const TEveException eh("TEveElement::GetObject ");
497 
498  TString t = " ";
499  TString cls(GetObject(eh)->ClassName());
500 
501  out << "\n";
502 
503  TString intro = " TAG='" + tag + "', CLASS='" + cls + "'";
504  out << " //" << intro << "\n";
505  out << " //" << TString('-', intro.Length()) << "\n";
506  out << t << cls << "* " << var <<" = new " << cls << ";\n";
507 
508  WriteVizParams(out, var);
509 
510  out << t << "gEve->InsertVizDBEntry(\"" << tag << "\", "<< var <<");\n";
511 }
512 
513 ////////////////////////////////////////////////////////////////////////////////
514 /// Write-out visual parameters for this object.
515 /// This is a virtual function and all sub-classes are required to
516 /// first call the base-element version.
517 /// The name of the element pointer is 'x%03d', due to cint limitations.
518 /// Three spaces should be used for indentation, same as in
519 /// SavePrimitive() methods.
520 
521 void TEveElement::WriteVizParams(std::ostream& out, const TString& var)
522 {
523  TString t = " " + var + "->";
524 
525  out << t << "SetElementName(\"" << GetElementName() << "\");\n";
526  out << t << "SetElementTitle(\"" << GetElementTitle() << "\");\n";
527  out << t << "SetEditMainColor(" << fCanEditMainColor << ");\n";
528  out << t << "SetEditMainTransparency(" << fCanEditMainTransparency << ");\n";
529  out << t << "SetMainTransparency(" << fMainTransparency << ");\n";
530 }
531 
532 ////////////////////////////////////////////////////////////////////////////////
533 /// Set visual parameters for this object for given tag.
534 
535 void TEveElement::VizDB_Apply(const char* tag)
536 {
537  if (ApplyVizTag(tag))
538  {
539  PropagateVizParamsToProjecteds();
540  gEve->Redraw3D();
541  }
542 }
543 
544 ////////////////////////////////////////////////////////////////////////////////
545 /// Reset visual parameters for this object from VizDB.
546 /// The model object must be already set.
547 
548 void TEveElement::VizDB_Reapply()
549 {
550  if (fVizModel)
551  {
552  CopyVizParamsFromDB();
553  PropagateVizParamsToProjecteds();
554  gEve->Redraw3D();
555  }
556 }
557 
558 ////////////////////////////////////////////////////////////////////////////////
559 /// Copy visual parameters from this element to viz-db model.
560 /// If update is set, all clients of the model will be updated to
561 /// the new value.
562 /// A warning is printed if the model-element fVizModel is not set.
563 
564 void TEveElement::VizDB_UpdateModel(Bool_t update)
565 {
566  if (fVizModel)
567  {
568  fVizModel->CopyVizParams(this);
569  if (update)
570  {
571  fVizModel->PropagateVizParamsToElements(fVizModel);
572  gEve->Redraw3D();
573  }
574  }
575  else
576  {
577  Warning("VizDB_UpdateModel", "VizModel has not been set.");
578  }
579 }
580 
581 ////////////////////////////////////////////////////////////////////////////////
582 /// Create a replica of element and insert it into VizDB with given tag.
583 /// If replace is true an existing element with the same tag will be replaced.
584 /// If update is true, existing client of tag will be updated.
585 
586 void TEveElement::VizDB_Insert(const char* tag, Bool_t replace, Bool_t update)
587 {
588  static const TEveException eh("TEveElement::GetObject ");
589 
590  TClass* cls = GetObject(eh)->IsA();
591  TEveElement* el = reinterpret_cast<TEveElement*>(cls->New());
592  if (el == 0) {
593  Error("VizDB_Insert", "Creation of replica failed.");
594  return;
595  }
596  el->CopyVizParams(this);
597  Bool_t succ = gEve->InsertVizDBEntry(tag, el, replace, update);
598  if (succ && update)
599  gEve->Redraw3D();
600 }
601 
602 ////////////////////////////////////////////////////////////////////////////////
603 /// Returns the master element - that is:
604 /// - master of projectable, if this is a projected;
605 /// - master of compound, if fCompound is set;
606 /// - master of first compound parent, if kSCBTakeAnyParentAsMaster bit is set;
607 /// If non of the above is true, *this* is returned.
608 
609 TEveElement* TEveElement::GetMaster()
610 {
611  TEveProjected* proj = dynamic_cast<TEveProjected*>(this);
612  if (proj)
613  {
614  return dynamic_cast<TEveElement*>(proj->GetProjectable())->GetMaster();
615  }
616  if (fCompound)
617  {
618  return fCompound->GetMaster();
619  }
620  if (TestCSCBits(kCSCBTakeAnyParentAsMaster))
621  {
622  for (List_i i = fParents.begin(); i != fParents.end(); ++i)
623  if (dynamic_cast<TEveCompound*>(*i))
624  return (*i)->GetMaster();
625  }
626  return this;
627 }
628 
629 ////////////////////////////////////////////////////////////////////////////////
630 /// Add re into the list parents.
631 ///
632 /// Adding parent is subordinate to adding an element.
633 /// This is an internal function.
634 
635 void TEveElement::AddParent(TEveElement* re)
636 {
637  fParents.push_back(re);
638 }
639 
640 ////////////////////////////////////////////////////////////////////////////////
641 /// Remove re from the list of parents.
642 /// Removing parent is subordinate to removing an element.
643 /// This is an internal function.
644 
645 void TEveElement::RemoveParent(TEveElement* re)
646 {
647  static const TEveException eh("TEveElement::RemoveParent ");
648 
649  fParents.remove(re);
650  CheckReferenceCount(eh);
651 }
652 
653 /******************************************************************************/
654 
655 ////////////////////////////////////////////////////////////////////////////////
656 /// Check external references to this and eventually auto-destruct
657 /// the render-element.
658 
659 void TEveElement::CheckReferenceCount(const TEveException& eh)
660 {
661  if (fDestructing != kNone)
662  return;
663 
664  if (NumParents() <= fParentIgnoreCnt && fTopItemCnt <= 0 &&
665  fDestroyOnZeroRefCnt && fDenyDestroy <= 0)
666  {
667  if (gEve->GetUseOrphanage())
668  {
669  if (gDebug > 0)
670  Info(eh, "moving to orphanage '%s' on zero reference count.", GetElementName());
671 
672  PreDeleteElement();
673  gEve->GetOrphanage()->AddElement(this);
674  }
675  else
676  {
677  if (gDebug > 0)
678  Info(eh, "auto-destructing '%s' on zero reference count.", GetElementName());
679 
680  PreDeleteElement();
681  delete this;
682  }
683  }
684 }
685 
686 ////////////////////////////////////////////////////////////////////////////////
687 /// Collect all parents of class TEveScene. This is needed to
688 /// automatically detect which scenes need to be updated.
689 ///
690 /// Overriden in TEveScene to include itself and return.
691 
692 void TEveElement::CollectSceneParents(List_t& scenes)
693 {
694  for (List_i p=fParents.begin(); p!=fParents.end(); ++p)
695  (*p)->CollectSceneParents(scenes);
696 }
697 
698 ////////////////////////////////////////////////////////////////////////////////
699 /// Collect scene-parents from all children. This is needed to
700 /// automatically detect which scenes need to be updated during/after
701 /// a full sub-tree update.
702 /// Argument parent specifies parent in traversed hierarchy for which we can
703 /// skip the upwards search.
704 
705 void TEveElement::CollectSceneParentsFromChildren(List_t& scenes,
706  TEveElement* parent)
707 {
708  for (List_i p=fParents.begin(); p!=fParents.end(); ++p)
709  {
710  if (*p != parent) (*p)->CollectSceneParents(scenes);
711  }
712 
713  for (List_i c=fChildren.begin(); c!=fChildren.end(); ++c)
714  {
715  (*c)->CollectSceneParentsFromChildren(scenes, this);
716  }
717 }
718 
719 ////////////////////////////////////////////////////////////////////////////////
720 /// Populates parent with elements.
721 /// parent must be an already existing representation of *this*.
722 /// Returns number of inserted elements.
723 /// If parent already has children, it does nothing.
724 ///
725 /// Element can be inserted in a list-tree several times, thus we can not
726 /// search through fItems to get parent here.
727 /// Anyhow, it is probably known as it must have been selected by the user.
728 
729 void TEveElement::ExpandIntoListTree(TGListTree* ltree,
730  TGListTreeItem* parent)
731 {
732  if (parent->GetFirstChild() != 0)
733  return;
734  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
735  (*i)->AddIntoListTree(ltree, parent);
736  }
737 }
738 
739 ////////////////////////////////////////////////////////////////////////////////
740 /// Destroy sub-tree under item 'parent' in list-tree 'ltree'.
741 
742 void TEveElement::DestroyListSubTree(TGListTree* ltree,
743  TGListTreeItem* parent)
744 {
745  TGListTreeItem* i = parent->GetFirstChild();
746  while (i != 0)
747  {
748  TEveElement* re = (TEveElement*) i->GetUserData();
749  i = i->GetNextSibling();
750  re->RemoveFromListTree(ltree, parent);
751  }
752 }
753 
754 ////////////////////////////////////////////////////////////////////////////////
755 /// Add this element into ltree to an already existing item
756 /// parent_lti. Children, if any, are added as below the newly created item.
757 /// Returns the newly created list-tree-item.
758 
759 TGListTreeItem* TEveElement::AddIntoListTree(TGListTree* ltree,
760  TGListTreeItem* parent_lti)
761 {
762  static const TEveException eh("TEveElement::AddIntoListTree ");
763 
764  TGListTreeItem* item = new TEveListTreeItem(this);
765  ltree->AddItem(parent_lti, item);
766  fItems.insert(TEveListTreeInfo(ltree, item));
767 
768  if (parent_lti == 0)
769  ++fTopItemCnt;
770 
771  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
772  {
773  (*i)->AddIntoListTree(ltree, item);
774  }
775 
776  ltree->ClearViewPort();
777 
778  return item;
779 }
780 
781 ////////////////////////////////////////////////////////////////////////////////
782 /// Add this render element into ltree to all items belonging to
783 /// parent. Returns list-tree-item from the first register entry (but
784 /// we use a set for that so it can be anything).
785 
786 TGListTreeItem* TEveElement::AddIntoListTree(TGListTree* ltree,
787  TEveElement* parent)
788 {
789  TGListTreeItem* lti = 0;
790  if (parent == 0) {
791  lti = AddIntoListTree(ltree, (TGListTreeItem*) 0);
792  } else {
793  for (sLTI_ri i = parent->fItems.rbegin(); i != parent->fItems.rend(); ++i)
794  {
795  if (i->fTree == ltree)
796  lti = AddIntoListTree(ltree, i->fItem);
797  }
798  }
799  return lti;
800 }
801 
802 ////////////////////////////////////////////////////////////////////////////////
803 /// Add this render element into all list-trees and all items
804 /// belonging to parent. Returns list-tree-item from the first
805 /// register entry (but we use a set for that so it can be anything).
806 
807 TGListTreeItem* TEveElement::AddIntoListTrees(TEveElement* parent)
808 {
809  TGListTreeItem* lti = 0;
810  for (sLTI_ri i = parent->fItems.rbegin(); i != parent->fItems.rend(); ++i)
811  {
812  lti = AddIntoListTree(i->fTree, i->fItem);
813  }
814  return lti;
815 }
816 
817 ////////////////////////////////////////////////////////////////////////////////
818 /// Remove element from list-tree 'ltree' where its parent item is
819 /// 'parent_lti'.
820 /// Returns kTRUE if the item was found and removed, kFALSE
821 /// otherwise.
822 
823 Bool_t TEveElement::RemoveFromListTree(TGListTree* ltree,
824  TGListTreeItem* parent_lti)
825 {
826  static const TEveException eh("TEveElement::RemoveFromListTree ");
827 
828  sLTI_i i = FindItem(ltree, parent_lti);
829  if (i != fItems.end()) {
830  DestroyListSubTree(ltree, i->fItem);
831  ltree->DeleteItem(i->fItem);
832  ltree->ClearViewPort();
833  fItems.erase(i);
834  if (parent_lti == 0) {
835  --fTopItemCnt;
836  CheckReferenceCount(eh);
837  }
838  return kTRUE;
839  } else {
840  return kFALSE;
841  }
842 }
843 
844 ////////////////////////////////////////////////////////////////////////////////
845 /// Remove element from all list-trees where 'parent' is the
846 /// user-data of the parent list-tree-item.
847 
848 Int_t TEveElement::RemoveFromListTrees(TEveElement* parent)
849 {
850  static const TEveException eh("TEveElement::RemoveFromListTrees ");
851 
852  Int_t count = 0;
853 
854  sLTI_i i = fItems.begin();
855  while (i != fItems.end())
856  {
857  sLTI_i j = i++;
858  TGListTreeItem *plti = j->fItem->GetParent();
859  if ((plti != 0 && (TEveElement*) plti->GetUserData() == parent) ||
860  (plti == 0 && parent == 0))
861  {
862  DestroyListSubTree(j->fTree, j->fItem);
863  j->fTree->DeleteItem(j->fItem);
864  j->fTree->ClearViewPort();
865  fItems.erase(j);
866  if (parent == 0)
867  --fTopItemCnt;
868  ++count;
869  }
870  }
871 
872  if (parent == 0 && count > 0)
873  CheckReferenceCount(eh);
874 
875  return count;
876 }
877 
878 ////////////////////////////////////////////////////////////////////////////////
879 /// Find any list-tree-item of this element in list-tree 'ltree'.
880 /// Note that each element can be placed into the same list-tree on
881 /// several postions.
882 
883 TEveElement::sLTI_i TEveElement::FindItem(TGListTree* ltree)
884 {
885  for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
886  if (i->fTree == ltree)
887  return i;
888  return fItems.end();
889 }
890 
891 ////////////////////////////////////////////////////////////////////////////////
892 /// Find list-tree-item of this element with given parent
893 /// list-tree-item.
894 
895 TEveElement::sLTI_i TEveElement::FindItem(TGListTree* ltree,
896  TGListTreeItem* parent_lti)
897 {
898  for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
899  if (i->fTree == ltree && i->fItem->GetParent() == parent_lti)
900  return i;
901  return fItems.end();
902 }
903 
904 ////////////////////////////////////////////////////////////////////////////////
905 /// Find any list-tree-item of this element in list-tree 'ltree'.
906 /// Note that each element can be placed into the same list-tree on
907 /// several postions.
908 
909 TGListTreeItem* TEveElement::FindListTreeItem(TGListTree* ltree)
910 {
911  for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
912  if (i->fTree == ltree)
913  return i->fItem;
914  return 0;
915 }
916 
917 ////////////////////////////////////////////////////////////////////////////////
918 /// Find list-tree-item of this element with given parent
919 /// list-tree-item.
920 
921 TGListTreeItem* TEveElement::FindListTreeItem(TGListTree* ltree,
922  TGListTreeItem* parent_lti)
923 {
924  for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
925  if (i->fTree == ltree && i->fItem->GetParent() == parent_lti)
926  return i->fItem;
927  return 0;
928 }
929 
930 ////////////////////////////////////////////////////////////////////////////////
931 /// Get a TObject associated with this render-element.
932 /// Most cases uses double-inheritance from TEveElement and TObject
933 /// so we just do a dynamic cast here.
934 /// If some TEveElement descendant implements a different scheme,
935 /// this virtual method should be overriden accordingly.
936 
937 TObject* TEveElement::GetObject(const TEveException& eh) const
938 {
939  const TObject* obj = dynamic_cast<const TObject*>(this);
940  if (obj == 0)
941  throw(eh + "not a TObject.");
942  return const_cast<TObject*>(obj);
943 }
944 
945 ////////////////////////////////////////////////////////////////////////////////
946 /// Show GUI editor for this object.
947 /// This is forwarded to TEveManager::EditElement().
948 
949 void TEveElement::SpawnEditor()
950 {
951  gEve->EditElement(this);
952 }
953 
954 ////////////////////////////////////////////////////////////////////////////////
955 /// Export render-element to CINT with variable name var_name.
956 
957 void TEveElement::ExportToCINT(char* var_name)
958 {
959  const char* cname = IsA()->GetName();
960  gROOT->ProcessLine(TString::Format("%s* %s = (%s*)0x%lx;", cname, var_name, cname, (ULong_t)this));
961 }
962 
963 ////////////////////////////////////////////////////////////////////////////////
964 /// Call Dump() on source object.
965 /// Throws an exception if it is not set.
966 
967 void TEveElement::DumpSourceObject() const
968 {
969  static const TEveException eh("TEveElement::DumpSourceObject ");
970 
971  TObject *so = GetSourceObject();
972  if (!so)
973  throw eh + "source-object not set.";
974 
975  so->Dump();
976 }
977 
978 ////////////////////////////////////////////////////////////////////////////////
979 /// Call Print() on source object.
980 /// Throws an exception if it is not set.
981 
982 void TEveElement::PrintSourceObject() const
983 {
984  static const TEveException eh("TEveElement::PrintSourceObject ");
985 
986  TObject *so = GetSourceObject();
987  if (!so)
988  throw eh + "source-object not set.";
989 
990  so->Print();
991 }
992 
993 ////////////////////////////////////////////////////////////////////////////////
994 /// Export source object to CINT with given name for the variable.
995 /// Throws an exception if it is not set.
996 
997 void TEveElement::ExportSourceObjectToCINT(char* var_name) const
998 {
999  static const TEveException eh("TEveElement::ExportSourceObjectToCINT ");
1000 
1001  TObject *so = GetSourceObject();
1002  if (!so)
1003  throw eh + "source-object not set.";
1004 
1005  const char* cname = so->IsA()->GetName();
1006  gROOT->ProcessLine(TString::Format("%s* %s = (%s*)0x%lx;", cname, var_name, cname, (ULong_t)so));
1007 }
1008 
1009 ////////////////////////////////////////////////////////////////////////////////
1010 /// Paint self and/or children into currently active pad.
1011 
1012 void TEveElement::PadPaint(Option_t* option)
1013 {
1014  static const TEveException eh("TEveElement::PadPaint ");
1015 
1016  TObject* obj = 0;
1017  if (GetRnrSelf() && (obj = GetRenderObject(eh)))
1018  obj->Paint(option);
1019 
1020 
1021  if (GetRnrChildren()) {
1022  for (List_i i=BeginChildren(); i!=EndChildren(); ++i) {
1023  (*i)->PadPaint(option);
1024  }
1025  }
1026 }
1027 
1028 ////////////////////////////////////////////////////////////////////////////////
1029 /// Paint object -- a generic implementation for EVE elements.
1030 /// This supports direct rendering using a dedicated GL class.
1031 /// Override TObject::Paint() in sub-classes if different behaviour
1032 /// is required.
1033 
1034 void TEveElement::PaintStandard(TObject* id)
1035 {
1036  static const TEveException eh("TEveElement::PaintStandard ");
1037 
1038  TBuffer3D buff(TBuffer3DTypes::kGeneric);
1039 
1040  // Section kCore
1041  buff.fID = id;
1042  buff.fColor = GetMainColor();
1043  buff.fTransparency = GetMainTransparency();
1044  if (HasMainTrans()) RefMainTrans().SetBuffer3D(buff);
1045 
1046  buff.SetSectionsValid(TBuffer3D::kCore);
1047 
1048  Int_t reqSections = gPad->GetViewer3D()->AddObject(buff);
1049  if (reqSections != TBuffer3D::kNone)
1050  {
1051  Warning(eh, "IsA='%s'. Viewer3D requires more sections (%d). Only direct-rendering supported.",
1052  id->ClassName(), reqSections);
1053  }
1054 }
1055 
1056 ////////////////////////////////////////////////////////////////////////////////
1057 /// Set render state of this element, i.e. if it will be published
1058 /// on next scene update pass.
1059 /// Returns true if the state has changed.
1060 
1061 Bool_t TEveElement::SetRnrSelf(Bool_t rnr)
1062 {
1063  if (SingleRnrState())
1064  {
1065  return SetRnrState(rnr);
1066  }
1067 
1068  if (rnr != fRnrSelf)
1069  {
1070  fRnrSelf = rnr;
1071  StampVisibility();
1072  PropagateRnrStateToProjecteds();
1073  return kTRUE;
1074  }
1075  return kFALSE;
1076 }
1077 
1078 ////////////////////////////////////////////////////////////////////////////////
1079 /// Set render state of this element's children, i.e. if they will
1080 /// be published on next scene update pass.
1081 /// Returns true if the state has changed.
1082 
1083 Bool_t TEveElement::SetRnrChildren(Bool_t rnr)
1084 {
1085  if (SingleRnrState())
1086  {
1087  return SetRnrState(rnr);
1088  }
1089 
1090  if (rnr != fRnrChildren)
1091  {
1092  fRnrChildren = rnr;
1093  StampVisibility();
1094  PropagateRnrStateToProjecteds();
1095  return kTRUE;
1096  }
1097  return kFALSE;
1098 }
1099 
1100 ////////////////////////////////////////////////////////////////////////////////
1101 /// Set state for rendering of this element and its children.
1102 /// Returns true if the state has changed.
1103 
1104 Bool_t TEveElement::SetRnrSelfChildren(Bool_t rnr_self, Bool_t rnr_children)
1105 {
1106  if (SingleRnrState())
1107  {
1108  return SetRnrState(rnr_self);
1109  }
1110 
1111  if (fRnrSelf != rnr_self || fRnrChildren != rnr_children)
1112  {
1113  fRnrSelf = rnr_self;
1114  fRnrChildren = rnr_children;
1115  StampVisibility();
1116  PropagateRnrStateToProjecteds();
1117  return kTRUE;
1118  }
1119  return kFALSE;
1120 }
1121 
1122 ////////////////////////////////////////////////////////////////////////////////
1123 /// Set render state of this element and of its children to the same
1124 /// value.
1125 /// Returns true if the state has changed.
1126 
1127 Bool_t TEveElement::SetRnrState(Bool_t rnr)
1128 {
1129  if (fRnrSelf != rnr || fRnrChildren != rnr)
1130  {
1131  fRnrSelf = fRnrChildren = rnr;
1132  StampVisibility();
1133  PropagateRnrStateToProjecteds();
1134  return kTRUE;
1135  }
1136  return kFALSE;
1137 }
1138 
1139 ////////////////////////////////////////////////////////////////////////////////
1140 /// Propagate render state to the projected replicas of this element.
1141 /// Maybe this should be optional on gEve/element level.
1142 
1143 void TEveElement::PropagateRnrStateToProjecteds()
1144 {
1145  TEveProjectable *pable = dynamic_cast<TEveProjectable*>(this);
1146  if (pable && pable->HasProjecteds())
1147  {
1148  pable->PropagateRenderState(fRnrSelf, fRnrChildren);
1149  }
1150 }
1151 
1152 ////////////////////////////////////////////////////////////////////////////////
1153 /// Set main color of the element.
1154 ///
1155 ///
1156 /// List-tree-items are updated.
1157 
1158 void TEveElement::SetMainColor(Color_t color)
1159 {
1160  Color_t old_color = GetMainColor();
1161 
1162  if (fMainColorPtr)
1163  {
1164  *fMainColorPtr = color;
1165  StampColorSelection();
1166  }
1167 
1168  PropagateMainColorToProjecteds(color, old_color);
1169 }
1170 
1171 ////////////////////////////////////////////////////////////////////////////////
1172 /// Convert pixel to Color_t and call SetMainColor().
1173 
1174 void TEveElement::SetMainColorPixel(Pixel_t pixel)
1175 {
1176  SetMainColor(TColor::GetColor(pixel));
1177 }
1178 
1179 ////////////////////////////////////////////////////////////////////////////////
1180 /// Convert RGB values to Color_t and call SetMainColor.
1181 
1182 void TEveElement::SetMainColorRGB(UChar_t r, UChar_t g, UChar_t b)
1183 {
1184  SetMainColor(TColor::GetColor(r, g, b));
1185 }
1186 
1187 ////////////////////////////////////////////////////////////////////////////////
1188 /// Convert RGB values to Color_t and call SetMainColor.
1189 
1190 void TEveElement::SetMainColorRGB(Float_t r, Float_t g, Float_t b)
1191 {
1192  SetMainColor(TColor::GetColor(r, g, b));
1193 }
1194 
1195 ////////////////////////////////////////////////////////////////////////////////
1196 /// Propagate color to projected elements.
1197 
1198 void TEveElement::PropagateMainColorToProjecteds(Color_t color, Color_t old_color)
1199 {
1200  TEveProjectable* pable = dynamic_cast<TEveProjectable*>(this);
1201  if (pable && pable->HasProjecteds())
1202  {
1203  pable->PropagateMainColor(color, old_color);
1204  }
1205 }
1206 
1207 ////////////////////////////////////////////////////////////////////////////////
1208 /// Set main-transparency.
1209 /// Transparency is clamped to [0, 100].
1210 
1211 void TEveElement::SetMainTransparency(Char_t t)
1212 {
1213  Char_t old_t = GetMainTransparency();
1214 
1215  if (t > 100) t = 100;
1216  fMainTransparency = t;
1217  StampColorSelection();
1218 
1219  PropagateMainTransparencyToProjecteds(t, old_t);
1220 }
1221 
1222 ////////////////////////////////////////////////////////////////////////////////
1223 /// Set main-transparency via float alpha variable.
1224 /// Value of alpha is clamped t0 [0, 1].
1225 
1226 void TEveElement::SetMainAlpha(Float_t alpha)
1227 {
1228  if (alpha < 0) alpha = 0;
1229  if (alpha > 1) alpha = 1;
1230  SetMainTransparency((Char_t) (100.0f*(1.0f - alpha)));
1231 }
1232 
1233 ////////////////////////////////////////////////////////////////////////////////
1234 /// Propagate transparency to projected elements.
1235 
1236 void TEveElement::PropagateMainTransparencyToProjecteds(Char_t t, Char_t old_t)
1237 {
1238  TEveProjectable* pable = dynamic_cast<TEveProjectable*>(this);
1239  if (pable && pable->HasProjecteds())
1240  {
1241  pable->PropagateMainTransparency(t, old_t);
1242  }
1243 }
1244 
1245 ////////////////////////////////////////////////////////////////////////////////
1246 /// Return pointer to main transformation. If 'create' flag is set (default)
1247 /// it is created if not yet existing.
1248 
1249 TEveTrans* TEveElement::PtrMainTrans(Bool_t create)
1250 {
1251  if (!fMainTrans && create)
1252  InitMainTrans();
1253 
1254  return fMainTrans;
1255 }
1256 
1257 ////////////////////////////////////////////////////////////////////////////////
1258 /// Return reference to main transformation. It is created if not yet
1259 /// existing.
1260 
1261 TEveTrans& TEveElement::RefMainTrans()
1262 {
1263  if (!fMainTrans)
1264  InitMainTrans();
1265 
1266  return *fMainTrans;
1267 }
1268 
1269 ////////////////////////////////////////////////////////////////////////////////
1270 /// Initialize the main transformation to identity matrix.
1271 /// If can_edit is true (default), the user will be able to edit the
1272 /// transformation parameters via TEveElementEditor.
1273 
1274 void TEveElement::InitMainTrans(Bool_t can_edit)
1275 {
1276  if (fMainTrans)
1277  fMainTrans->UnitTrans();
1278  else
1279  fMainTrans = new TEveTrans;
1280  fCanEditMainTrans = can_edit;
1281 }
1282 
1283 ////////////////////////////////////////////////////////////////////////////////
1284 /// Destroy the main transformation matrix, it will always be taken
1285 /// as identity. Editing of transformation parameters is disabled.
1286 
1287 void TEveElement::DestroyMainTrans()
1288 {
1289  delete fMainTrans;
1290  fMainTrans = 0;
1291  fCanEditMainTrans = kFALSE;
1292 }
1293 
1294 ////////////////////////////////////////////////////////////////////////////////
1295 /// Set transformation matrix from column-major array.
1296 
1297 void TEveElement::SetTransMatrix(Double_t* carr)
1298 {
1299  RefMainTrans().SetFrom(carr);
1300 }
1301 
1302 ////////////////////////////////////////////////////////////////////////////////
1303 /// Set transformation matrix from TGeo's matrix.
1304 
1305 void TEveElement::SetTransMatrix(const TGeoMatrix& mat)
1306 {
1307  RefMainTrans().SetFrom(mat);
1308 }
1309 
1310 ////////////////////////////////////////////////////////////////////////////////
1311 /// Check if el can be added to this element.
1312 ///
1313 /// In the base-class version we only make sure the new child is not
1314 /// equal to this.
1315 
1316 Bool_t TEveElement::AcceptElement(TEveElement* el)
1317 {
1318  return el != this;
1319 }
1320 
1321 ////////////////////////////////////////////////////////////////////////////////
1322 /// Add el to the list of children.
1323 
1324 void TEveElement::AddElement(TEveElement* el)
1325 {
1326  static const TEveException eh("TEveElement::AddElement ");
1327 
1328  if ( ! AcceptElement(el))
1329  throw(eh + Form("parent '%s' rejects '%s'.",
1330  GetElementName(), el->GetElementName()));
1331 
1332  el->AddParent(this);
1333  fChildren.push_back(el); ++fNumChildren;
1334  el->AddIntoListTrees(this);
1335  ElementChanged();
1336 }
1337 
1338 ////////////////////////////////////////////////////////////////////////////////
1339 /// Remove el from the list of children.
1340 
1341 void TEveElement::RemoveElement(TEveElement* el)
1342 {
1343  el->RemoveFromListTrees(this);
1344  RemoveElementLocal(el);
1345  el->RemoveParent(this);
1346  fChildren.remove(el); --fNumChildren;
1347  ElementChanged();
1348 }
1349 
1350 ////////////////////////////////////////////////////////////////////////////////
1351 /// Perform additional local removal of el.
1352 /// Called from RemoveElement() which does whole untangling.
1353 /// Put into special function as framework-related handling of
1354 /// element removal should really be common to all classes and
1355 /// clearing of local structures happens in between removal
1356 /// of list-tree-items and final removal.
1357 /// If you override this, you should also override
1358 /// RemoveElementsLocal().
1359 
1360 void TEveElement::RemoveElementLocal(TEveElement* /*el*/)
1361 {
1362 }
1363 
1364 ////////////////////////////////////////////////////////////////////////////////
1365 /// Remove all elements. This assumes removing of all elements can
1366 /// be done more efficiently then looping over them and removing one
1367 /// by one. This protected function performs the removal on the
1368 /// level of TEveElement.
1369 
1370 void TEveElement::RemoveElementsInternal()
1371 {
1372  for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
1373  {
1374  DestroyListSubTree(i->fTree, i->fItem);
1375  }
1376  RemoveElementsLocal();
1377  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
1378  {
1379  (*i)->RemoveParent(this);
1380  }
1381  fChildren.clear(); fNumChildren = 0;
1382 }
1383 
1384 ////////////////////////////////////////////////////////////////////////////////
1385 /// Remove all elements. This assumes removing of all elements can
1386 /// be done more efficiently then looping over them and removing
1387 /// them one by one.
1388 
1389 void TEveElement::RemoveElements()
1390 {
1391  if (HasChildren())
1392  {
1393  RemoveElementsInternal();
1394  ElementChanged();
1395  }
1396 }
1397 
1398 ////////////////////////////////////////////////////////////////////////////////
1399 /// Perform additional local removal of all elements.
1400 /// See comment to RemoveElementlocal(TEveElement*).
1401 
1402 void TEveElement::RemoveElementsLocal()
1403 {
1404 }
1405 
1406 ////////////////////////////////////////////////////////////////////////////////
1407 /// If this is a projectable, loop over all projected replicas and
1408 /// add the projected image of child 'el' there. This is supposed to
1409 /// be called after you add a child to a projectable after it has
1410 /// already been projected.
1411 /// You might also want to call RecheckImpliedSelections() on this
1412 /// element or 'el'.
1413 ///
1414 /// If 'same_depth' flag is true, the same depth as for parent object
1415 /// is used in every projection. Otherwise current depth of each
1416 /// relevant projection-manager is used.
1417 
1418 void TEveElement::ProjectChild(TEveElement* el, Bool_t same_depth)
1419 {
1420  TEveProjectable* pable = dynamic_cast<TEveProjectable*>(this);
1421  if (pable && HasChild(el))
1422  {
1423  for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i)
1424  {
1425  TEveProjectionManager *pmgr = (*i)->GetManager();
1426  Float_t cd = pmgr->GetCurrentDepth();
1427  if (same_depth) pmgr->SetCurrentDepth((*i)->GetDepth());
1428 
1429  pmgr->SubImportElements(el, (*i)->GetProjectedAsElement());
1430 
1431  if (same_depth) pmgr->SetCurrentDepth(cd);
1432  }
1433  }
1434 }
1435 
1436 ////////////////////////////////////////////////////////////////////////////////
1437 /// If this is a projectable, loop over all projected replicas and
1438 /// add the projected image of all children there. This is supposed
1439 /// to be called after you destroy all children and then add new
1440 /// ones after this element has already been projected.
1441 /// You might also want to call RecheckImpliedSelections() on this
1442 /// element.
1443 ///
1444 /// If 'same_depth' flag is true, the same depth as for the
1445 /// projected element is used in every projection. Otherwise current
1446 /// depth of each relevant projection-manager is used.
1447 
1448 void TEveElement::ProjectAllChildren(Bool_t same_depth)
1449 {
1450  TEveProjectable* pable = dynamic_cast<TEveProjectable*>(this);
1451  if (pable)
1452  {
1453  for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i)
1454  {
1455  TEveProjectionManager *pmgr = (*i)->GetManager();
1456  Float_t cd = pmgr->GetCurrentDepth();
1457  if (same_depth) pmgr->SetCurrentDepth((*i)->GetDepth());
1458 
1459  pmgr->SubImportChildren(this, (*i)->GetProjectedAsElement());
1460 
1461  if (same_depth) pmgr->SetCurrentDepth(cd);
1462  }
1463  }
1464 }
1465 
1466 ////////////////////////////////////////////////////////////////////////////////
1467 /// Check if element el is a child of this element.
1468 
1469 Bool_t TEveElement::HasChild(TEveElement* el)
1470 {
1471  return (std::find(fChildren.begin(), fChildren.end(), el) != fChildren.end());
1472 }
1473 
1474 ////////////////////////////////////////////////////////////////////////////////
1475 /// Find the first child with given name. If cls is specified (non
1476 /// 0), it is also checked.
1477 ///
1478 /// Returns 0 if not found.
1479 
1480 TEveElement* TEveElement::FindChild(const TString& name, const TClass* cls)
1481 {
1482  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
1483  {
1484  if (name.CompareTo((*i)->GetElementName()) == 0)
1485  {
1486  if (!cls || (cls && (*i)->IsA()->InheritsFrom(cls)))
1487  return *i;
1488  }
1489  }
1490  return 0;
1491 }
1492 
1493 ////////////////////////////////////////////////////////////////////////////////
1494 /// Find the first child whose name matches regexp. If cls is
1495 /// specified (non 0), it is also checked.
1496 ///
1497 /// Returns 0 if not found.
1498 
1499 TEveElement* TEveElement::FindChild(TPRegexp& regexp, const TClass* cls)
1500 {
1501  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
1502  {
1503  if (regexp.MatchB((*i)->GetElementName()))
1504  {
1505  if (!cls || (cls && (*i)->IsA()->InheritsFrom(cls)))
1506  return *i;
1507  }
1508  }
1509  return 0;
1510 }
1511 
1512 ////////////////////////////////////////////////////////////////////////////////
1513 /// Find all children with given name and append them to matches
1514 /// list. If class is specified (non 0), it is also checked.
1515 ///
1516 /// Returns number of elements added to the list.
1517 
1518 Int_t TEveElement::FindChildren(List_t& matches,
1519  const TString& name, const TClass* cls)
1520 {
1521  Int_t count = 0;
1522  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
1523  {
1524  if (name.CompareTo((*i)->GetElementName()) == 0)
1525  {
1526  if (!cls || (cls && (*i)->IsA()->InheritsFrom(cls)))
1527  {
1528  matches.push_back(*i);
1529  ++count;
1530  }
1531  }
1532  }
1533  return count;
1534 }
1535 
1536 ////////////////////////////////////////////////////////////////////////////////
1537 /// Find all children whose name matches regexp and append them to
1538 /// matches list.
1539 ///
1540 /// Returns number of elements added to the list.
1541 
1542 Int_t TEveElement::FindChildren(List_t& matches,
1543  TPRegexp& regexp, const TClass* cls)
1544 {
1545  Int_t count = 0;
1546  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
1547  {
1548  if (regexp.MatchB((*i)->GetElementName()))
1549  {
1550  if (!cls || (cls && (*i)->IsA()->InheritsFrom(cls)))
1551  {
1552  matches.push_back(*i);
1553  ++count;
1554  }
1555  }
1556  }
1557  return count;
1558 }
1559 
1560 ////////////////////////////////////////////////////////////////////////////////
1561 /// Returns the first child element or 0 if the list is empty.
1562 
1563 TEveElement* TEveElement::FirstChild() const
1564 {
1565  return HasChildren() ? fChildren.front() : 0;
1566 }
1567 
1568 ////////////////////////////////////////////////////////////////////////////////
1569 /// Returns the last child element or 0 if the list is empty.
1570 
1571 TEveElement* TEveElement::LastChild () const
1572 {
1573  return HasChildren() ? fChildren.back() : 0;
1574 }
1575 
1576 ////////////////////////////////////////////////////////////////////////////////
1577 /// Enable rendering of children and their list contents.
1578 /// Arguments control how to set self/child rendering.
1579 
1580 void TEveElement::EnableListElements(Bool_t rnr_self, Bool_t rnr_children)
1581 {
1582  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
1583  {
1584  (*i)->SetRnrSelf(rnr_self);
1585  (*i)->SetRnrChildren(rnr_children);
1586  }
1587 
1588  ElementChanged(kTRUE, kTRUE);
1589 }
1590 
1591 ////////////////////////////////////////////////////////////////////////////////
1592 /// Disable rendering of children and their list contents.
1593 /// Arguments control how to set self/child rendering.
1594 ///
1595 /// Same as above function, but default arguments are different. This
1596 /// is convenient for calls via context menu.
1597 
1598 void TEveElement::DisableListElements(Bool_t rnr_self, Bool_t rnr_children)
1599 {
1600  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
1601  {
1602  (*i)->SetRnrSelf(rnr_self);
1603  (*i)->SetRnrChildren(rnr_children);
1604  }
1605 
1606  ElementChanged(kTRUE, kTRUE);
1607 }
1608 
1609 ////////////////////////////////////////////////////////////////////////////////
1610 /// Protected member function called from TEveElement::Annihilate().
1611 
1612 void TEveElement::AnnihilateRecursively()
1613 {
1614  static const TEveException eh("TEveElement::AnnihilateRecursively ");
1615 
1616  // projected were already destroyed in TEveElement::Anihilate(), now only clear its list
1617  TEveProjectable* pable = dynamic_cast<TEveProjectable*>(this);
1618  if (pable && pable->HasProjecteds())
1619  {
1620  pable->ClearProjectedList();
1621  }
1622 
1623  // same as TEveElements::RemoveElementsInternal(), except parents are ignored
1624  for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
1625  {
1626  DestroyListSubTree(i->fTree, i->fItem);
1627  }
1628  RemoveElementsLocal();
1629  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
1630  {
1631  (*i)->AnnihilateRecursively();
1632  }
1633 
1634  fChildren.clear();
1635  fNumChildren = 0;
1636 
1637  fDestructing = kAnnihilate;
1638  PreDeleteElement();
1639 
1640  delete this;
1641 }
1642 
1643 ////////////////////////////////////////////////////////////////////////////////
1644 /// Optimized destruction without check of reference-count.
1645 /// Parents are not notified about child destruction.
1646 /// The method should only be used when an element does not have
1647 /// more than one parent -- otherwise an exception is thrown.
1648 
1649 void TEveElement::Annihilate()
1650 {
1651  static const TEveException eh("TEveElement::Annihilate ");
1652 
1653  if (fParents.size() > 1)
1654  {
1655  Warning(eh, "More than one parent for '%s': %d. Refusing to delete.",
1656  GetElementName(), (Int_t) fParents.size());
1657  return;
1658  }
1659 
1660  fDestructing = kAnnihilate;
1661 
1662  // recursive annihilation of projecteds
1663  TEveProjectable* pable = dynamic_cast<TEveProjectable*>(this);
1664  if (pable && pable->HasProjecteds())
1665  {
1666  pable->AnnihilateProjecteds();
1667  }
1668 
1669  // detach from the parent
1670  while (!fParents.empty())
1671  {
1672  fParents.front()->RemoveElement(this);
1673  }
1674 
1675  AnnihilateRecursively();
1676 
1677  gEve->Redraw3D();
1678 }
1679 
1680 ////////////////////////////////////////////////////////////////////////////////
1681 /// Annihilate elements.
1682 
1683 void TEveElement::AnnihilateElements()
1684 {
1685  while (!fChildren.empty())
1686  {
1687  TEveElement* c = fChildren.front();
1688  c->Annihilate();
1689  }
1690 
1691  fNumChildren = 0;
1692 }
1693 
1694 ////////////////////////////////////////////////////////////////////////////////
1695 /// Destroy this element. Throws an exception if deny-destroy is in force.
1696 /// This method should be called instead of a destructor.
1697 /// Note that an exception will be thrown if the element has been
1698 /// protected against destruction with IncDenyDestroy().
1699 
1700 void TEveElement::Destroy()
1701 {
1702  static const TEveException eh("TEveElement::Destroy ");
1703 
1704  if (fDenyDestroy > 0)
1705  throw eh + TString::Format("element '%s' (%s*) 0x%lx is protected against destruction.",
1706  GetElementName(), IsA()->GetName(), (ULong_t)this);
1707 
1708  PreDeleteElement();
1709  delete this;
1710  gEve->Redraw3D();
1711 }
1712 
1713 ////////////////////////////////////////////////////////////////////////////////
1714 /// Destroy this element. Prints a warning if deny-destroy is in force.
1715 
1716 void TEveElement::DestroyOrWarn()
1717 {
1718  static const TEveException eh("TEveElement::DestroyOrWarn ");
1719 
1720  try
1721  {
1722  Destroy();
1723  }
1724  catch (TEveException& exc)
1725  {
1726  Warning(eh, "%s", exc.Data());
1727  }
1728 }
1729 
1730 ////////////////////////////////////////////////////////////////////////////////
1731 /// Destroy all children of this element.
1732 
1733 void TEveElement::DestroyElements()
1734 {
1735  static const TEveException eh("TEveElement::DestroyElements ");
1736 
1737  while (HasChildren())
1738  {
1739  TEveElement* c = fChildren.front();
1740  if (c->fDenyDestroy <= 0)
1741  {
1742  try {
1743  c->Destroy();
1744  }
1745  catch (const TEveException &exc) {
1746  Warning(eh, "element destruction failed: '%s'.", exc.Data());
1747  RemoveElement(c);
1748  }
1749  }
1750  else
1751  {
1752  if (gDebug > 0)
1753  Info(eh, "element '%s' is protected agains destruction, removing locally.", c->GetElementName());
1754  RemoveElement(c);
1755  }
1756  }
1757 
1758  gEve->Redraw3D();
1759 }
1760 
1761 ////////////////////////////////////////////////////////////////////////////////
1762 /// Returns state of flag determining if the element will be
1763 /// destroyed when reference count reaches zero.
1764 /// This is true by default.
1765 
1766 Bool_t TEveElement::GetDestroyOnZeroRefCnt() const
1767 {
1768  return fDestroyOnZeroRefCnt;
1769 }
1770 
1771 ////////////////////////////////////////////////////////////////////////////////
1772 /// Sets the state of flag determining if the element will be
1773 /// destroyed when reference count reaches zero.
1774 /// This is true by default.
1775 
1776 void TEveElement::SetDestroyOnZeroRefCnt(Bool_t d)
1777 {
1778  fDestroyOnZeroRefCnt = d;
1779 }
1780 
1781 ////////////////////////////////////////////////////////////////////////////////
1782 /// Returns the number of times deny-destroy has been requested on
1783 /// the element.
1784 
1785 Int_t TEveElement::GetDenyDestroy() const
1786 {
1787  return fDenyDestroy;
1788 }
1789 
1790 ////////////////////////////////////////////////////////////////////////////////
1791 /// Increases the deny-destroy count of the element.
1792 /// Call this if you store an external pointer to the element.
1793 
1794 void TEveElement::IncDenyDestroy()
1795 {
1796  ++fDenyDestroy;
1797 }
1798 
1799 ////////////////////////////////////////////////////////////////////////////////
1800 /// Decreases the deny-destroy count of the element.
1801 /// Call this after releasing an external pointer to the element.
1802 
1803 void TEveElement::DecDenyDestroy()
1804 {
1805  if (--fDenyDestroy <= 0)
1806  CheckReferenceCount("TEveElement::DecDenyDestroy ");
1807 }
1808 
1809 ////////////////////////////////////////////////////////////////////////////////
1810 /// Get number of parents that should be ignored in doing
1811 /// reference-counting.
1812 ///
1813 /// For example, this is used when subscribing an element to a
1814 /// visualization-database model object.
1815 
1816 Int_t TEveElement::GetParentIgnoreCnt() const
1817 {
1818  return fParentIgnoreCnt;
1819 }
1820 
1821 ////////////////////////////////////////////////////////////////////////////////
1822 /// Increase number of parents ignored in reference-counting.
1823 
1824 void TEveElement::IncParentIgnoreCnt()
1825 {
1826  ++fParentIgnoreCnt;
1827 }
1828 
1829 ////////////////////////////////////////////////////////////////////////////////
1830 /// Decrease number of parents ignored in reference-counting.
1831 
1832 void TEveElement::DecParentIgnoreCnt()
1833 {
1834  if (--fParentIgnoreCnt <= 0)
1835  CheckReferenceCount("TEveElement::DecParentIgnoreCnt ");
1836 }
1837 
1838 ////////////////////////////////////////////////////////////////////////////////
1839 /// React to element being pasted or dnd-ed.
1840 /// Return true if redraw is needed.
1841 
1842 Bool_t TEveElement::HandleElementPaste(TEveElement* el)
1843 {
1844  gEve->AddElement(el, this);
1845  return kTRUE;
1846 }
1847 
1848 ////////////////////////////////////////////////////////////////////////////////
1849 /// Call this after an element has been changed so that the state
1850 /// can be propagated around the framework.
1851 
1852 void TEveElement::ElementChanged(Bool_t update_scenes, Bool_t redraw)
1853 {
1854  gEve->ElementChanged(this, update_scenes, redraw);
1855 }
1856 
1857 ////////////////////////////////////////////////////////////////////////////////
1858 /// Set pickable state on the element and all its children.
1859 
1860 void TEveElement::SetPickableRecursively(Bool_t p)
1861 {
1862  fPickable = p;
1863  for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
1864  {
1865  (*i)->SetPickableRecursively(p);
1866  }
1867 }
1868 
1869 ////////////////////////////////////////////////////////////////////////////////
1870 /// Returns element to be selected on click.
1871 /// If value is zero the selected object will follow rules in
1872 /// TEveSelection.
1873 
1874 TEveElement* TEveElement::ForwardSelection()
1875 {
1876  return 0;
1877 }
1878 
1879 ////////////////////////////////////////////////////////////////////////////////
1880 /// Returns element to be displayed in GUI editor on click.
1881 /// If value is zero the displayed object will follow rules in
1882 /// TEveSelection.
1883 
1884 TEveElement* TEveElement::ForwardEdit()
1885 {
1886  return 0;
1887 }
1888 
1889 ////////////////////////////////////////////////////////////////////////////////
1890 /// Set element's selection state. Stamp appropriately.
1891 
1892 void TEveElement::SelectElement(Bool_t state)
1893 {
1894  if (fSelected != state) {
1895  fSelected = state;
1896  if (!fSelected && fImpliedSelected == 0)
1897  UnSelected();
1898  fParentIgnoreCnt += (fSelected) ? 1 : -1;
1899  StampColorSelection();
1900  }
1901 }
1902 
1903 ////////////////////////////////////////////////////////////////////////////////
1904 /// Increase element's implied-selection count. Stamp appropriately.
1905 
1906 void TEveElement::IncImpliedSelected()
1907 {
1908  if (fImpliedSelected++ == 0)
1909  StampColorSelection();
1910 }
1911 
1912 ////////////////////////////////////////////////////////////////////////////////
1913 /// Decrease element's implied-selection count. Stamp appropriately.
1914 
1915 void TEveElement::DecImpliedSelected()
1916 {
1917  if (--fImpliedSelected == 0)
1918  {
1919  if (!fSelected)
1920  UnSelected();
1921  StampColorSelection();
1922  }
1923 }
1924 
1925 ////////////////////////////////////////////////////////////////////////////////
1926 /// Virtual function called when both fSelected is false and
1927 /// fImpliedSelected is 0.
1928 /// Nothing is done in this base-class version
1929 
1930 void TEveElement::UnSelected()
1931 {
1932 }
1933 
1934 ////////////////////////////////////////////////////////////////////////////////
1935 /// Set element's highlight state. Stamp appropriately.
1936 
1937 void TEveElement::HighlightElement(Bool_t state)
1938 {
1939  if (fHighlighted != state) {
1940  fHighlighted = state;
1941  if (!fHighlighted && fImpliedHighlighted == 0)
1942  UnHighlighted();
1943  fParentIgnoreCnt += (fHighlighted) ? 1 : -1;
1944  StampColorSelection();
1945  }
1946 }
1947 
1948 ////////////////////////////////////////////////////////////////////////////////
1949 /// Increase element's implied-highlight count. Stamp appropriately.
1950 
1951 void TEveElement::IncImpliedHighlighted()
1952 {
1953  if (fImpliedHighlighted++ == 0)
1954  StampColorSelection();
1955 }
1956 
1957 ////////////////////////////////////////////////////////////////////////////////
1958 /// Decrease element's implied-highlight count. Stamp appropriately.
1959 
1960 void TEveElement::DecImpliedHighlighted()
1961 {
1962  if (--fImpliedHighlighted == 0)
1963  {
1964  if (!fHighlighted)
1965  UnHighlighted();
1966  StampColorSelection();
1967  }
1968 }
1969 
1970 ////////////////////////////////////////////////////////////////////////////////
1971 /// Virtual function called when both fHighlighted is false and
1972 /// fImpliedHighlighted is 0.
1973 /// Nothing is done in this base-class version
1974 
1975 void TEveElement::UnHighlighted()
1976 {
1977 }
1978 
1979 ////////////////////////////////////////////////////////////////////////////////
1980 /// Populate set impSelSet with derived / dependant elements.
1981 ///
1982 /// If this is a TEveProjectable, the projected replicas are added
1983 /// to the set. Thus it does not have to be reimplemented for each
1984 /// sub-class of TEveProjected.
1985 ///
1986 /// Note that this also takes care of projections of TEveCompound
1987 /// class, which is also a projectable.
1988 
1989 void TEveElement::FillImpliedSelectedSet(Set_t& impSelSet)
1990 {
1991  TEveProjectable* p = dynamic_cast<TEveProjectable*>(this);
1992  if (p)
1993  {
1994  p->AddProjectedsToSet(impSelSet);
1995  }
1996 }
1997 
1998 ////////////////////////////////////////////////////////////////////////////////
1999 /// Get selection level, needed for rendering selection and
2000 /// highlight feedback.
2001 /// This should go to TAtt3D.
2002 
2003 UChar_t TEveElement::GetSelectedLevel() const
2004 {
2005  if (fSelected) return 1;
2006  if (fImpliedSelected > 0) return 2;
2007  if (fHighlighted) return 3;
2008  if (fImpliedHighlighted > 0) return 4;
2009  return 0;
2010 }
2011 
2012 ////////////////////////////////////////////////////////////////////////////////
2013 /// Call this if it is possible that implied-selection or highlight
2014 /// has changed for this element or for implied-selection this
2015 /// element is member of and you want to maintain consistent
2016 /// selection state.
2017 /// This can happen if you add elements into compounds in response
2018 /// to user-interaction.
2019 
2020 void TEveElement::RecheckImpliedSelections()
2021 {
2022  if (fSelected || fImpliedSelected)
2023  gEve->GetSelection()->RecheckImpliedSetForElement(this);
2024 
2025  if (fHighlighted || fImpliedHighlighted)
2026  gEve->GetHighlight()->RecheckImpliedSetForElement(this);
2027 }
2028 
2029 ////////////////////////////////////////////////////////////////////////////////
2030 /// Add (bitwise or) given stamps to fChangeBits.
2031 /// Register this element to gEve as stamped.
2032 /// This method is virtual so that sub-classes can add additional
2033 /// actions. The base-class method should still be called (or replicated).
2034 
2035 void TEveElement::AddStamp(UChar_t bits)
2036 {
2037  fChangeBits |= bits;
2038  if (fDestructing == kNone) gEve->ElementStamped(this);
2039 }
2040 
2041 ////////////////////////////////////////////////////////////////////////////////
2042 /// Returns pointer to first listtreeicon
2043 
2044 const TGPicture* TEveElement::GetListTreeIcon(Bool_t open)
2045 {
2046  // Need better solution for icon-loading/ids !!!!
2047  return fgListTreeIcons[open ? 7 : 0];
2048 }
2049 
2050 ////////////////////////////////////////////////////////////////////////////////
2051 /// Returns list-tree-item check-box picture appropriate for given
2052 /// rendering state.
2053 
2054 const TGPicture* TEveElement::GetListTreeCheckBoxIcon()
2055 {
2056  Int_t idx = 0;
2057  if (fRnrSelf) idx = 2;
2058  if (fRnrChildren ) idx++;
2059 
2060  return fgRnrIcons[idx];
2061 }
2062 
2063 ////////////////////////////////////////////////////////////////////////////////
2064 /// Convert Bool_t to string - kTRUE or kFALSE.
2065 /// Needed in WriteVizParams().
2066 
2067 const char* TEveElement::ToString(Bool_t b)
2068 {
2069  return b ? "kTRUE" : "kFALSE";
2070 }
2071 
2072 
2073 /** \class TEveElementList
2074 \ingroup TEve
2075 A list of TEveElements.
2076 
2077 Class of acceptable children can be limited by setting the
2078 fChildClass member.
2079 
2080 !!! should have two ctors (like in TEveElement), one with Color_t&
2081 and set fDoColor automatically, based on which ctor is called.
2082 */
2083 
2084 ClassImp(TEveElementList);
2085 
2086 ////////////////////////////////////////////////////////////////////////////////
2087 /// Constructor.
2088 
2089 TEveElementList::TEveElementList(const char* n, const char* t, Bool_t doColor, Bool_t doTransparency) :
2090  TEveElement(),
2091  TNamed(n, t),
2092  TEveProjectable(),
2093  fColor(0),
2094  fChildClass(0)
2095 {
2096  if (doColor) {
2097  fCanEditMainColor = kTRUE;
2098  SetMainColorPtr(&fColor);
2099  }
2100  if (doTransparency)
2101  {
2102  fCanEditMainTransparency = kTRUE;
2103  }
2104 }
2105 
2106 ////////////////////////////////////////////////////////////////////////////////
2107 /// Copy constructor.
2108 
2109 TEveElementList::TEveElementList(const TEveElementList& e) :
2110  TEveElement (e),
2111  TNamed (e),
2112  TEveProjectable(),
2113  fColor (e.fColor),
2114  fChildClass (e.fChildClass)
2115 {
2116 }
2117 
2118 ////////////////////////////////////////////////////////////////////////////////
2119 /// Clone the element via copy constructor.
2120 /// Virtual from TEveElement.
2121 
2122 TEveElementList* TEveElementList::CloneElement() const
2123 {
2124  return new TEveElementList(*this);
2125 }
2126 
2127 ////////////////////////////////////////////////////////////////////////////////
2128 /// Check if TEveElement el is inherited from fChildClass.
2129 /// Virtual from TEveElement.
2130 
2131 Bool_t TEveElementList::AcceptElement(TEveElement* el)
2132 {
2133  if (fChildClass && ! el->IsA()->InheritsFrom(fChildClass))
2134  return kFALSE;
2135  return kTRUE;
2136 }
2137 
2138 ////////////////////////////////////////////////////////////////////////////////
2139 /// Virtual from TEveProjectable, returns TEveCompoundProjected class.
2140 
2141 TClass* TEveElementList::ProjectedClass(const TEveProjection*) const
2142 {
2143  return TEveElementListProjected::Class();
2144 }
2145 
2146 /** \class TEveElementListProjected
2147 \ingroup TEve
2148 A projected element list -- required for proper propagation
2149 of render state to projected views.
2150 */
2151 
2152 ClassImp(TEveElementListProjected);
2153 
2154 ////////////////////////////////////////////////////////////////////////////////
2155 /// Constructor.
2156 
2157 TEveElementListProjected::TEveElementListProjected() :
2158  TEveElementList("TEveElementListProjected")
2159 {
2160 }
2161 
2162 ////////////////////////////////////////////////////////////////////////////////
2163 /// This is abstract method from base-class TEveProjected.
2164 /// No implementation.
2165 
2166 void TEveElementListProjected::UpdateProjection()
2167 {
2168 }