Logo ROOT  
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
26Manager class for steering of projections and managing projected objects.
27
28Recursively projects REveElement's and draws axis in the projected
29scene. It enables to interactively set REveProjection parameters
30and updates projected scene accordingly.
31*/
32
33using namespace ROOT::Experimental;
34namespace 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);
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();
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();
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)
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
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}
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define c(i)
Definition: RSha256.hxx:101
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
void Warning(const char *location, const char *msgfmt,...)
int type
Definition: TGX11.cxx:120
char * Form(const char *fmt,...)
bool HasNieces() const override
virtual void AddNiece(REveElement *el)
TClass * IsA() const
Return class for this element.
const char * GetCTitle() const
void SetCompound(REveCompound *c)
const char * GetCName() const
virtual void AddElement(REveElement *el)
Add el to the list of children.
virtual Bool_t GetRnrSelf() const
virtual Bool_t SetRnrChildren(Bool_t rnr)
Set render state of this element's children, i.e.
void SetTitle(const std::string &title)
Set title of an element.
virtual Bool_t SetRnrSelf(Bool_t rnr)
Set render state of this element, i.e.
virtual Bool_t GetRnrChildren() const
std::list< REveElement * > List_t
Definition: REveElement.hxx:77
REveElement(const std::string &name="", const std::string &title="")
Default constructor.
Definition: REveElement.cxx:51
void SetName(const std::string &name)
Set name of an element.
REveException Exception-type thrown by Eve classes.
Definition: REveTypes.hxx:40
virtual TClass * ProjectedClass(const REveProjection *p) const =0
virtual void SetProjection(REveProjectionManager *mng, REveProjectable *model)
Sets projection manager and reference in the projectable object.
virtual void SetDepth(Float_t d)
Set depth coordinate for the element.
REveProjection * fProjections[REveProjection::kPT_End]
void AddDependent(REveElement *el)
Add el as dependent element.
virtual REveElement * ImportElements(REveElement *el, REveElement *ext_list=nullptr)
Recursively import elements and apply projection to the newly imported objects.
void SetProjection(REveProjection::EPType_e type)
Set projection type and distortion.
virtual REveElement * ImportElementsRecurse(REveElement *el, REveElement *parent)
If el is REveProjectable add projected instance else add plain REveElementList to parent.
void ComputeBBox() override
Virtual from TAttBBox; fill bounding-box information.
virtual REveElement * SubImportElements(REveElement *el, REveElement *proj_parent)
Recursively import elements and apply projection to the newly imported objects.
REveProjectionManager(const REveProjectionManager &)
virtual void UpdateName()
Updates name to have consistent information with projection.
void RemoveDependent(REveElement *el)
Remove el as dependent element.
virtual void ProjectChildren()
Project all children recursively, update bounding-box and notify EveManger about the scenes that have...
virtual void ProjectChildrenRecurse(REveElement *el)
Project el (via REveProjected::UpdateProjection()) and recurse through el's children.
virtual void UpdateDependentElsAndScenes(REveElement *root)
Update dependent elements' bounding box and mark scenes containing element root or its children as re...
void SetCenter(Float_t x, Float_t y, Float_t z)
Set projection center and rebuild projected scene.
virtual Bool_t ShouldImport(REveElement *el)
Returns true if element el should be imported.
virtual Int_t SubImportChildren(REveElement *el, REveElement *proj_parent)
Recursively import children elements of el and apply projection to the newly imported objects.
virtual void SetCenter(REveVector &v)
virtual Bool_t Is2D() const =0
void Set(const Float_t *v)
Definition: REveVector.hxx:80
Helper for management of bounding-box information.
Definition: TAttBBox.h:18
virtual void ComputeBBox()=0
void BBoxCheckPoint(Float_t x, Float_t y, Float_t z)
Definition: TAttBBox.h:58
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
void AssertBBoxExtents(Float_t epsilon=0.005)
Assert extents of all sides of the bounding-box are at least epsilon.
Definition: TAttBBox.cxx:62
Float_t * AssertBBox()
Definition: TAttBBox.h:45
void BBoxInit(Float_t infinity=1e6)
Dynamic Float_t[6] X(min,max), Y(min,max), Z(min,max)
Definition: TAttBBox.cxx:29
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4812
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4708
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16