Logo ROOT   6.21/01
Reference Guide
REveProjectionManager.cxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2019, 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 
13 #include <ROOT/REveManager.hxx>
15 #include <ROOT/REveCompound.hxx>
16 
17 #include "TBuffer3D.h"
18 #include "TBuffer3DTypes.h"
19 
20 #include "TClass.h"
21 
22 #include <list>
23 
24 /** \class REveProjectionManager
25 \ingroup REve
26 Manager class for steering of projections and managing projected objects.
27 
28 Recursively projects REveElement's and draws axis in the projected
29 scene. It enables to interactively set REveProjection parameters
30 and updates projected scene accordingly.
31 */
32 
33 using namespace ROOT::Experimental;
34 namespace REX = ROOT::Experimental;
35 
36 ////////////////////////////////////////////////////////////////////////////////
37 /// Constructor.
38 
40  REveElement("REveProjectionManager","")
41 {
42  for (Int_t i = 0; i < REveProjection::kPT_End; ++i)
43  fProjections[i] = nullptr;
44 
47 }
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 /// Destructor.
51 /// Destroys also dependent elements.
52 
54 {
55  for (Int_t i = 0; i < REveProjection::kPT_End; ++i) {
56  delete fProjections[i];
57  }
58  while ( ! fDependentEls.empty()) {
59  fDependentEls.front()->Destroy();
60  }
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// Add el as dependent element.
65 
67 {
68  fDependentEls.push_back(el);
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 /// Remove el as dependent element.
73 
75 {
76  fDependentEls.remove(el);
77 }
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// Updates name to have consistent information with projection.
81 
83 {
84  if (fProjection->Is2D())
85  SetName(Form ("%s (%3.1f)", fProjection->GetName(), fProjection->GetDistortion()*1000));
86  else
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Set projection type and distortion.
92 
94 {
95  static const REveException eH("REveProjectionManager::SetProjection ");
96 
97  if (fProjections[type] == 0)
98  {
99  switch (type)
100  {
102  {
104  break;
105  }
107  {
109  break;
110  }
112  {
114  break;
115  }
116  default:
117  throw eH + "projection type not valid.";
118  break;
119  }
120  }
121 
123  {
124  throw eH + "switching between 2D and 3D projections not implemented.";
125  }
126 
129  UpdateName();
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 /// Set projection center and rebuild projected scene.
134 
136 {
137  fCenter.Set(x, y, z);
139  ProjectChildren();
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 /// Returns true if element el should be imported.
144 ///
145 /// Behaviour depends on the value of the fImportEmpty member:
146 /// false - el or any of its children must be projectable (default);
147 /// true - always import.
148 
150 {
151  if (fImportEmpty)
152  return kTRUE;
153 
154  if (el->IsA()->InheritsFrom(TClass::GetClass<REveProjectable>()))
155  return kTRUE;
156  for (auto &c: el->RefChildren())
157  if (ShouldImport(c))
158  return kTRUE;
159  return kFALSE;
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 /// Update dependent elements' bounding box and mark scenes
164 /// containing element root or its children as requiring a repaint.
165 
167 {
168  for (auto &d: fDependentEls) {
169  TAttBBox* bbox = dynamic_cast<TAttBBox *>(d);
170  if (bbox)
171  bbox->ComputeBBox();
172  }
173 
174  static int warn_count = 0;
175  if (++warn_count <= 5)
176  Warning("REveProjectionManager::UpdateDependentElsAndScenes",
177  "Figure out if scene stamping is still needed.");
178  /*
179  List_t scenes;
180  root->CollectScenes(scenes);
181  if (root == this)
182  for (auto &n : fNieces)
183  n->CollectScenes(scenes);
184 
185  REX::gEve->ScenesChanged(scenes);
186  */
187 }
188 
189 ////////////////////////////////////////////////////////////////////////////////
190 /// If el is REveProjectable add projected instance else add plain
191 /// REveElementList to parent. Call the same function on el's
192 /// children.
193 ///
194 /// Returns the projected replica of el. Can be 0, if el and none of
195 /// its children are projectable.
196 
198  REveElement* parent)
199 {
200  static const REveException eh("REveProjectionManager::ImportElementsRecurse ");
201 
202  REveElement *new_el = nullptr;
203 
204  if (ShouldImport(el))
205  {
206  REveProjected *new_pr = nullptr;
207  REveProjectable *pble = dynamic_cast<REveProjectable*>(el);
208  if (pble)
209  {
210  new_el = (REveElement*) pble->ProjectedClass(fProjection)->New();
211  new_pr = dynamic_cast<REveProjected*>(new_el);
212  new_pr->SetProjection(this, pble);
213  new_pr->SetDepth(fCurrentDepth);
214  }
215  else
216  {
217  new_el = new REveElement;
218  }
219  new_el->SetName (Form("%s [P]", el->GetCName()));
220  new_el->SetTitle(Form("Projected replica.\n%s", el->GetCTitle()));
221  new_el->SetRnrSelf (el->GetRnrSelf());
222  new_el->SetRnrChildren (el->GetRnrChildren());
223  new_el->SetPickable (el->IsPickable());
224 
225  parent->AddElement(new_el);
226 
227  REveCompound *cmpnd = dynamic_cast<REveCompound*>(el);
228  REveCompound *cmpnd_pr = dynamic_cast<REveCompound*>(new_el);
229  for (auto &c: el->RefChildren()) {
230  REveElement *child_pr = ImportElementsRecurse(c, new_el);
231  if (cmpnd && c->GetCompound() == cmpnd)
232  child_pr->SetCompound(cmpnd_pr);
233  }
234  }
235 
236  return new_el;
237 }
238 
239 ////////////////////////////////////////////////////////////////////////////////
240 /// Recursively import elements and apply projection to the newly
241 /// imported objects.
242 ///
243 /// If ext_list is not 0 the new element is also added to the list.
244 /// This simplifies construction of complex views where projected
245 /// elements are distributed into several scenes for optimization of
246 /// updates and rendering.
247 ///
248 /// Returns the projected replica of el. Can be 0, if el and none of
249 /// its children are projectable.
250 
252  REveElement* ext_list)
253 {
254  REveElement* new_el = ImportElementsRecurse(el, ext_list ? ext_list : this);
255  if (new_el)
256  {
257  AssertBBox();
258  ProjectChildrenRecurse(new_el);
259  AssertBBoxExtents(0.1);
260  StampTransBBox();
261 
263 
264  if (ext_list)
265  AddNiece(new_el);
266  }
267  return new_el;
268 }
269 
270 ////////////////////////////////////////////////////////////////////////////////
271 /// Recursively import elements and apply projection to the newly
272 /// imported objects.
273 ///
274 /// The proj_parent argument should be a projected replica of parent
275 /// of element 'el'. This allows to insert projected children of
276 /// a given element when they are added after the projection has
277 /// been already performed on the parent.
278 /// This is called from REveElement::ProjectChild().
279 ///
280 /// Returns the projected replica of el. Can be 0, if el and none of
281 /// its children are projectable.
282 
284  REveElement* proj_parent)
285 {
286  REveElement* new_el = ImportElementsRecurse(el, proj_parent);
287  if (new_el)
288  {
289  AssertBBox();
290  ProjectChildrenRecurse(new_el);
291  AssertBBoxExtents(0.1);
292  StampTransBBox();
293 
295  }
296  return new_el;
297 }
298 
299 ////////////////////////////////////////////////////////////////////////////////
300 /// Recursively import children elements of el and apply projection
301 /// to the newly imported objects.
302 ///
303 /// The proj_parent argument should be a projected replica of
304 /// element 'el'. This allows to insert projected children of
305 /// a given element when they are added after the projection has
306 /// been already performed on the parent.
307 /// This is called from REveElement::ProjectChild().
308 ///
309 /// Returns the projected replica of el. Can be 0, if el and none of
310 /// its children are projectable.
311 
313 {
314  List_t new_els;
315  for (auto &c: el->RefChildren()) {
316  auto new_el = ImportElementsRecurse(c, proj_parent);
317  if (new_el)
318  new_els.push_back(new_el);
319  }
320 
321  if (!new_els.empty())
322  {
323  AssertBBox();
324  for (auto &nel: new_els)
326  AssertBBoxExtents(0.1);
327  StampTransBBox();
328 
329  UpdateDependentElsAndScenes(proj_parent);
330  }
331  return (Int_t) new_els.size();
332 }
333 
334 ////////////////////////////////////////////////////////////////////////////////
335 /// Project el (via REveProjected::UpdateProjection()) and recurse
336 /// through el's children.
337 /// Bounding-box is updated along the recursion.
338 
340 {
341  REveProjected* pted = dynamic_cast<REveProjected*>(el);
342  if (pted)
343  {
344  pted->UpdateProjection();
345  TAttBBox* bb = dynamic_cast<TAttBBox*>(pted);
346  if (bb)
347  {
348  Float_t* b = bb->AssertBBox();
349  BBoxCheckPoint(b[0], b[2], b[4]);
350  BBoxCheckPoint(b[1], b[3], b[5]);
351  }
352  el->StampObjProps();
353  }
354 
355  for (auto &c : el->RefChildren()) ProjectChildrenRecurse(c);
356 }
357 
358 ////////////////////////////////////////////////////////////////////////////////
359 /// Project all children recursively, update bounding-box and notify
360 /// EveManger about the scenes that have been changed.
361 
363 {
364  BBoxInit();
365 
366  for (auto &c : fChildren) ProjectChildrenRecurse(c);
367 
368  for (auto &n : fNieces) ProjectChildrenRecurse(n);
369 
370  AssertBBoxExtents(0.1);
371  StampTransBBox();
372 
374 }
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 /// Virtual from TAttBBox; fill bounding-box information.
378 ///
379 /// The bounding-box information is kept coherent during addition of
380 /// projected elements and projection parameter updates. This is
381 /// called only in case the manager has not been populated at all.
382 
384 {
385  static const REveException eH("REveProjectionManager::ComputeBBox ");
386 
387  if ( ! HasChildren() && ! HasNieces())
388  {
389  BBoxZero();
390  return;
391  }
392 
393  BBoxInit();
394 }
virtual void UpdateDependentElsAndScenes(REveElement *root)
Update dependent elements&#39; bounding box and mark scenes containing element root or its children as re...
virtual Int_t SubImportChildren(REveElement *el, REveElement *proj_parent)
Recursively import children elements of el and apply projection to the newly imported objects...
void SetName(const std::string &name)
Set name of an element.
virtual void SetProjection(REveProjectionManager *mng, REveProjectable *model)
Sets projection manager and reference in the projectable object.
float Float_t
Definition: RtypesCore.h:53
TClass * IsA() const
Return class for this element.
virtual Bool_t SetRnrChildren(Bool_t rnr)
Set render state of this element&#39;s children, i.e.
virtual void UpdateName()
Updates name to have consistent information with projection.
const char * GetCTitle() const
virtual Bool_t GetRnrSelf() const
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void ComputeBBox() override
Virtual from TAttBBox; fill bounding-box information.
void SetProjection(REveProjection::EPType_e type)
Set projection type and distortion.
void AddDependent(REveElement *el)
Add el as dependent element.
virtual void ProjectChildrenRecurse(REveElement *el)
Project el (via REveProjected::UpdateProjection()) and recurse through el&#39;s children.
const char * GetCName() const
virtual REveElement * SubImportElements(REveElement *el, REveElement *proj_parent)
Recursively import elements and apply projection to the newly imported objects.
bool HasNieces() const override
void SetTitle(const std::string &title)
Set title of an element.
void BBoxCheckPoint(Float_t x, Float_t y, Float_t z)
Definition: TAttBBox.h:58
Double_t x[n]
Definition: legend1.C:17
REveProjectionManager(const REveProjectionManager &)=delete
virtual Bool_t ShouldImport(REveElement *el)
Returns true if element el should be imported.
virtual void AddElement(REveElement *el)
Add el to the list of children.
virtual Bool_t GetRnrChildren() const
virtual void ComputeBBox()=0
void SetCompound(REveCompound *c)
std::list< REveElement * > List_t
Definition: REveElement.hxx:77
REveElement(const std::string &name="", const std::string &title="")
Default constructor.
Definition: REveElement.cxx:51
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
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4753
void Warning(const char *location, const char *msgfmt,...)
const Bool_t kFALSE
Definition: RtypesCore.h:88
#define d(i)
Definition: RSha256.hxx:102
virtual void SetCenter(REveVector &v)
void SetCenter(Float_t x, Float_t y, Float_t z)
Set projection center and rebuild projected scene.
int type
Definition: TGX11.cxx:120
Double_t y[n]
Definition: legend1.C:17
void RemoveDependent(REveElement *el)
Remove el as dependent element.
virtual REveElement * ImportElements(REveElement *el, REveElement *ext_list=nullptr)
Recursively import elements and apply projection to the newly imported objects.
virtual Bool_t SetRnrSelf(Bool_t rnr)
Set render state of this element, i.e.
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
virtual Bool_t Is2D() const =0
virtual void ProjectChildren()
Project all children recursively, update bounding-box and notify EveManger about the scenes that have...
Float_t * AssertBBox()
Definition: TAttBBox.h:45
virtual void SetDepth(Float_t d)
Set depth coordinate for the element.
REveProjection * fProjections[REveProjection::kPT_End]
Helper for management of bounding-box information.
Definition: TAttBBox.h:17
virtual REveElement * ImportElementsRecurse(REveElement *el, REveElement *parent)
If el is REveProjectable add projected instance else add plain REveElementList to parent...
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
virtual void AddNiece(REveElement *el)
#define c(i)
Definition: RSha256.hxx:101
void Set(const Float_t *v)
Definition: REveVector.hxx:80
const Bool_t kTRUE
Definition: RtypesCore.h:87
const Int_t n
Definition: legend1.C:16
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
REveException Exception-type thrown by Eve classes.
Definition: REveTypes.hxx:40
virtual TClass * ProjectedClass(const REveProjection *p) const =0
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4857