Logo ROOT   6.10/09
Reference Guide
TEveProjectionManager.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 "TEveProjectionManager.h"
13 #include "TEveManager.h"
14 #include "TEveProjectionBases.h"
15 #include "TEveCompound.h"
16 
17 #include "TBuffer3D.h"
18 #include "TBuffer3DTypes.h"
19 #include "TVirtualPad.h"
20 #include "TVirtualViewer3D.h"
21 
22 #include "TClass.h"
23 
24 #include <list>
25 
26 /** \class TEveProjectionManager
27 \ingroup TEve
28 Manager class for steering of projections and managing projected objects.
29 
30 Recursively projects TEveElement's and draws axis in the projected
31 scene. It enables to interactively set TEveProjection parameters
32 and updates projected scene accordingly.
33 */
34 
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Constructor.
39 
41  TEveElementList("TEveProjectionManager",""),
42  TAttBBox(),
43  fProjection (0),
44  fCurrentDepth(0),
45  fImportEmpty (kFALSE)
46 {
47  for (Int_t i = 0; i < TEveProjection::kPT_End; ++i)
48  fProjections[i] = 0;
49 
50  if (type != TEveProjection::kPT_Unknown)
51  SetProjection(type);
52 }
53 
54 ////////////////////////////////////////////////////////////////////////////////
55 /// Destructor.
56 /// Destroys also dependent elements.
57 
59 {
60  for (Int_t i = 0; i < TEveProjection::kPT_End; ++i)
61  {
62  delete fProjections[i];
63  }
64  while ( ! fDependentEls.empty())
65  {
66  fDependentEls.front()->Destroy();
67  }
68 }
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Add el as dependent element.
72 
74 {
75  fDependentEls.push_back(el);
76 }
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// Remove el as dependent element.
80 
82 {
83  fDependentEls.remove(el);
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// Updates name to have consistent information with projection.
88 
90 {
91  if (fProjection->Is2D())
92  SetName(Form ("%s (%3.1f)", fProjection->GetName(), fProjection->GetDistortion()*1000));
93  else
95 }
96 
97 ////////////////////////////////////////////////////////////////////////////////
98 /// Set projection type and distortion.
99 
101 {
102  static const TEveException eH("TEveProjectionManager::SetProjection ");
103 
104  if (fProjections[type] == 0)
105  {
106  switch (type)
107  {
109  {
111  break;
112  }
114  {
116  break;
117  }
119  {
121  break;
122  }
123  default:
124  throw eH + "projection type not valid.";
125  break;
126  }
127  }
128 
130  {
131  throw eH + "switching between 2D and 3D projections not implemented.";
132  }
133 
136  UpdateName();
137 }
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Set projection center and rebuild projected scene.
141 
143 {
144  fCenter.Set(x, y, z);
146  ProjectChildren();
147 }
148 
149 ////////////////////////////////////////////////////////////////////////////////
150 /// React to element being pasted or dnd-ed.
151 /// Return true if redraw is needed (virtual method).
152 
154 {
155  List_t::size_type n_children = fChildren.size();
156  ImportElements(el);
157  return n_children != fChildren.size();
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// Returns true if element el should be imported.
162 ///
163 /// Behaviour depends on the value of the fImportEmpty member:
164 /// false - el or any of its children must be projectable (default);
165 /// true - always import.
166 
168 {
169  if (fImportEmpty)
170  return kTRUE;
171 
172  if (el->IsA() != TEveElementList::Class() && el->IsA()->InheritsFrom(TEveProjectable::Class()))
173  return kTRUE;
174  for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i)
175  if (ShouldImport(*i))
176  return kTRUE;
177  return kFALSE;
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 /// Update dependent elements' bounding box and mark scenes
182 /// containing element root or its children as requiring a repaint.
183 
185 {
186  for (List_i i=fDependentEls.begin(); i!=fDependentEls.end(); ++i)
187  {
188  TAttBBox* bbox = dynamic_cast<TAttBBox*>(*i);
189  if (bbox)
190  bbox->ComputeBBox();
191  }
192 
193  List_t scenes;
194  root->CollectSceneParentsFromChildren(scenes, 0);
195  gEve->ScenesChanged(scenes);
196 }
197 
198 ////////////////////////////////////////////////////////////////////////////////
199 /// If el is TEveProjectable add projected instance else add plain
200 /// TEveElementList to parent. Call the same function on el's
201 /// children.
202 ///
203 /// Returns the projected replica of el. Can be 0, if el and none of
204 /// its children are projectable.
205 
207  TEveElement* parent)
208 {
209  static const TEveException eh("TEveProjectionManager::ImportElementsRecurse ");
210 
211  TEveElement *new_el = 0;
212 
213  if (ShouldImport(el))
214  {
215  TEveProjected *new_pr = 0;
216  TEveProjectable *pble = dynamic_cast<TEveProjectable*>(el);
217  if (pble)
218  {
219  new_el = (TEveElement*) pble->ProjectedClass(fProjection)->New();
220  new_pr = dynamic_cast<TEveProjected*>(new_el);
221  new_pr->SetProjection(this, pble);
222  new_pr->SetDepth(fCurrentDepth);
223  }
224  else
225  {
226  new_el = new TEveElementList;
227  }
228  new_el->SetElementName (Form("%s [P]", el->GetElementName()));
229  new_el->SetElementTitle(Form("Projected replica.\n%s", el->GetElementTitle()));
230  new_el->SetRnrSelf (el->GetRnrSelf());
231  new_el->SetRnrChildren (el->GetRnrChildren());
232  new_el->SetPickable (el->IsPickable());
233  parent->AddElement(new_el);
234 
235  TEveCompound *cmpnd = dynamic_cast<TEveCompound*>(el);
236  TEveCompound *cmpnd_pr = dynamic_cast<TEveCompound*>(new_el);
237  for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i)
238  {
239  TEveElement* child_pr = ImportElementsRecurse(*i, new_el);
240  if (cmpnd && (*i)->GetCompound() == cmpnd)
241  child_pr->SetCompound(cmpnd_pr);
242  }
243  }
244 
245  return new_el;
246 }
247 
248 ////////////////////////////////////////////////////////////////////////////////
249 /// Recursively import elements and apply projection to the newly
250 /// imported objects.
251 ///
252 /// If ext_list is not 0 the new element is also added to the list.
253 /// This simplifies construction of complex views where projected
254 /// elements are distributed into several scenes for optimization of
255 /// updates and rendering.
256 ///
257 /// Returns the projected replica of el. Can be 0, if el and none of
258 /// its children are projectable.
259 
261  TEveElement* ext_list)
262 {
263  TEveElement* new_el = ImportElementsRecurse(el, this);
264  if (new_el)
265  {
266  AssertBBox();
267  ProjectChildrenRecurse(new_el);
268  AssertBBoxExtents(0.1);
269  StampTransBBox();
270 
272 
273  if (ext_list)
274  ext_list->AddElement(new_el);
275  }
276  return new_el;
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Recursively import elements and apply projection to the newly
281 /// imported objects.
282 ///
283 /// The proj_parent argument should be a projected replica of parent
284 /// of element 'el'. This allows to insert projected children of
285 /// a given element when they are added after the projection has
286 /// been already performed on the parent.
287 /// This is called from TEveElement::ProjectChild().
288 ///
289 /// Returns the projected replica of el. Can be 0, if el and none of
290 /// its children are projectable.
291 
293  TEveElement* proj_parent)
294 {
295  TEveElement* new_el = ImportElementsRecurse(el, proj_parent);
296  if (new_el)
297  {
298  AssertBBox();
299  ProjectChildrenRecurse(new_el);
300  AssertBBoxExtents(0.1);
301  StampTransBBox();
302 
304  }
305  return new_el;
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 /// Recursively import children elements of el and apply projection
310 /// to the newly imported objects.
311 ///
312 /// The proj_parent argument should be a projected replica of
313 /// element 'el'. This allows to insert projected children of
314 /// a given element when they are added after the projection has
315 /// been already performed on the parent.
316 /// This is called from TEveElement::ProjectChild().
317 ///
318 /// Returns the projected replica of el. Can be 0, if el and none of
319 /// its children are projectable.
320 
322 {
323  List_t new_els;
324  for (List_i i = el->BeginChildren(); i != el->EndChildren(); ++i)
325  {
326  TEveElement* new_el = ImportElementsRecurse(*i, proj_parent);
327  if (new_el)
328  new_els.push_back(new_el);
329  }
330 
331  if ( ! new_els.empty())
332  {
333  AssertBBox();
334  for (List_i i = new_els.begin(); i != new_els.end(); ++i)
335  {
337  }
338  AssertBBoxExtents(0.1);
339  StampTransBBox();
340 
341  UpdateDependentElsAndScenes(proj_parent);
342  }
343  return (Int_t) new_els.size();
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Project el (via TEveProjected::UpdateProjection()) and recurse
348 /// through el's children.
349 /// Bounding-box is updated along the recursion.
350 
352 {
353  TEveProjected* pted = dynamic_cast<TEveProjected*>(el);
354  if (pted)
355  {
356  pted->UpdateProjection();
357  TAttBBox* bb = dynamic_cast<TAttBBox*>(pted);
358  if (bb)
359  {
360  Float_t* b = bb->AssertBBox();
361  BBoxCheckPoint(b[0], b[2], b[4]);
362  BBoxCheckPoint(b[1], b[3], b[5]);
363  }
364  el->ElementChanged(kFALSE);
365  }
366 
367  for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i)
369 }
370 
371 ////////////////////////////////////////////////////////////////////////////////
372 /// Project all children recursively, update bounding-box and notify
373 /// TEveManger about the scenes that have been changed.
374 
376 {
377  BBoxInit();
378  for (List_i i=BeginChildren(); i!=EndChildren(); ++i)
380  AssertBBoxExtents(0.1);
381  StampTransBBox();
382 
384 }
385 
386 ////////////////////////////////////////////////////////////////////////////////
387 /// Virtual from TAttBBox; fill bounding-box information.
388 ///
389 /// The bounding-box information is kept coherent during addition of
390 /// projected elements and projection parameter updates. This is
391 /// called only in case the manager has not been populated at all.
392 
394 {
395  static const TEveException eH("TEveProjectionManager::ComputeBBox ");
396 
397  if (HasChildren() == kFALSE) {
398  BBoxZero();
399  return;
400  }
401 
402  BBoxInit();
403 }
Abstract base class for classes that hold results of a non-linear projection transformation.
virtual void SetElementName(const char *name)
Virtual function for setting of name of an element.
List_i EndChildren()
Definition: TEveElement.h:165
virtual void CollectSceneParentsFromChildren(List_t &scenes, TEveElement *parent)
Collect scene-parents from all children.
void Set(const Float_t *v)
Definition: TEveVector.h:59
float Float_t
Definition: RtypesCore.h:53
List_t fChildren
Definition: TEveElement.h:79
virtual ~TEveProjectionManager()
Destructor.
void SetCenter(Float_t x, Float_t y, Float_t z)
Set projection center and rebuild projected scene.
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
virtual Int_t SubImportChildren(TEveElement *el, TEveElement *proj_parent)
Recursively import children elements of el and apply projection to the newly imported objects...
virtual TEveElement * ImportElementsRecurse(TEveElement *el, TEveElement *parent)
If el is TEveProjectable add projected instance else add plain TEveElementList to parent...
void SetPickable(Bool_t p)
Definition: TEveElement.h:340
Bool_t HasChildren() const
Definition: TEveElement.h:169
virtual Bool_t Is2D() const =0
3D scaling projection.
void RemoveDependent(TEveElement *el)
Remove el as dependent element.
List_t::iterator List_i
Definition: TEveElement.h:70
virtual void ProjectChildren()
Project all children recursively, update bounding-box and notify TEveManger about the scenes that hav...
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual void SetProjection(TEveProjectionManager *mng, TEveProjectable *model)
Sets projection manager and reference in the projectable object.
virtual Bool_t HandleElementPaste(TEveElement *el)
React to element being pasted or dnd-ed.
virtual Bool_t GetRnrSelf() const
Definition: TEveElement.h:254
TEveElementList(const char *n="TEveElementList", const char *t="", Bool_t doColor=kFALSE, Bool_t doTransparency=kFALSE)
Constructor.
TEveProjection * fProjections[TEveProjection::kPT_End]
A list of TEveElements.
Definition: TEveElement.h:459
Description of TEveCompound.
Definition: TEveCompound.h:23
void BBoxCheckPoint(Float_t x, Float_t y, Float_t z)
Definition: TAttBBox.h:58
Double_t x[n]
Definition: legend1.C:17
void AddDependent(TEveElement *el)
Add el as dependent element.
virtual void ElementChanged(Bool_t update_scenes=kTRUE, Bool_t redraw=kFALSE)
Call this after an element has been changed so that the state can be propagated around the framework...
virtual TEveElement * ImportElements(TEveElement *el, TEveElement *ext_list=0)
Recursively import elements and apply projection to the newly imported objects.
void Class()
Definition: Class.C:29
Float_t GetDistortion() const
XY projection with distortion around given center.
void SetCompound(TEveCompound *c)
Definition: TEveElement.h:147
virtual void SetElementTitle(const char *title)
Virtual function for setting of title of an element.
Manager class for steering of projections and managing projected objects.
virtual Bool_t ShouldImport(TEveElement *el)
Returns true if element el should be imported.
virtual void SetDepth(Float_t d)
Set depth coordinate for the element.
void ScenesChanged(TEveElement::List_t &scenes)
Mark all scenes from the given list as changed.
virtual void ComputeBBox()=0
Abstract base-class for non-linear projectable objects.
virtual TClass * ProjectedClass(const TEveProjection *p) const =0
const Char_t * GetName() const
Bool_t IsPickable() const
Definition: TEveElement.h:339
R__EXTERN TEveManager * gEve
Definition: TEveManager.h:243
TEveProjectionManager(const TEveProjectionManager &)
virtual Bool_t GetRnrChildren() const
Definition: TEveElement.h:255
char * Form(const char *fmt,...)
void BBoxZero(Float_t epsilon=0, Float_t x=0, Float_t y=0, Float_t z=0)
Create cube of volume (2*epsilon)^3 at (x,y,z).
Definition: TAttBBox.cxx:42
virtual Bool_t SetRnrSelf(Bool_t rnr)
Set render state of this element, i.e.
virtual void AddElement(TEveElement *el)
Add el to the list of children.
virtual const char * GetElementName() const
Virtual function for retrieving name of the element.
const Bool_t kFALSE
Definition: RtypesCore.h:92
void StampTransBBox()
Definition: TEveElement.h:396
TEveProjection * fProjection
std::list< TEveElement * > List_t
Definition: TEveElement.h:69
#define ClassImp(name)
Definition: Rtypes.h:336
virtual const char * GetElementTitle() const
Virtual function for retrieving title of the render-element.
virtual void SetCenter(TEveVector &v)
virtual void UpdateProjection()=0
int type
Definition: TGX11.cxx:120
virtual Bool_t SetRnrChildren(Bool_t rnr)
Set render state of this element&#39;s children, i.e.
Double_t y[n]
Definition: legend1.C:17
virtual void UpdateDependentElsAndScenes(TEveElement *root)
Update dependent elements&#39; bounding box and mark scenes containing element root or its children as re...
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
void SetProjection(TEveProjection::EPType_e type)
Set projection type and distortion.
virtual void ProjectChildrenRecurse(TEveElement *el)
Project el (via TEveProjected::UpdateProjection()) and recurse through el&#39;s children.
Float_t * AssertBBox()
Definition: TAttBBox.h:45
Helper for management of bounding-box information.
Definition: TAttBBox.h:17
List_i BeginChildren()
Definition: TEveElement.h:164
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
Exception class thrown by TEve classes and macros.
Definition: TEveUtil.h:102
virtual void ComputeBBox()
Virtual from TAttBBox; fill bounding-box information.
virtual void UpdateName()
Updates name to have consistent information with projection.
TEveCompound * GetCompound()
Definition: TEveElement.h:146
virtual TEveElement * SubImportElements(TEveElement *el, TEveElement *proj_parent)
Recursively import elements and apply projection to the newly imported objects.
const Bool_t kTRUE
Definition: RtypesCore.h:91
Base class for TEveUtil visualization elements, providing hierarchy management, rendering control and...
Definition: TEveElement.h:33
void BBoxInit(Float_t infinity=1e6)
Dynamic Float_t[6] X(min,max), Y(min,max), Z(min,max)
Definition: TAttBBox.cxx:29
void AssertBBoxExtents(Float_t epsilon=0.005)
Assert extents of all sides of the bounding-box are at least epsilon.
Definition: TAttBBox.cxx:62
Transformation from 3D to 2D.
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4706