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 }
117 {
119 break;
120 }
122 {
124 break;
125 }
127 {
129 break;
130 }
132 {
134 break;
135 }
136 default:
137 throw eH + "projection type not valid.";
138 break;
139 }
140 }
141
143 {
144 throw eH + "switching between 2D and 3D projections not implemented.";
145 }
146
149 UpdateName();
150}
151
152////////////////////////////////////////////////////////////////////////////////
153/// Set projection center and rebuild projected scene.
154
156{
157 fCenter.Set(x, y, z);
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// Returns true if element el should be imported.
164///
165/// Behaviour depends on the value of the fImportEmpty member:
166/// false - el or any of its children must be projectable (default);
167/// true - always import.
168
170{
171 if (fImportEmpty)
172 return kTRUE;
173
174 if (el->IsA()->InheritsFrom(TClass::GetClass<REveProjectable>()))
175 return kTRUE;
176 for (auto &c: el->RefChildren())
177 if (ShouldImport(c))
178 return kTRUE;
179 return kFALSE;
180}
181
182////////////////////////////////////////////////////////////////////////////////
183/// Update dependent elements' bounding boxes.
184
186{
187 for (auto &d: fDependentEls) {
188 TAttBBox* bbox = dynamic_cast<TAttBBox *>(d);
189 if (bbox)
190 bbox->ComputeBBox();
191 }
192}
193
194////////////////////////////////////////////////////////////////////////////////
195/// If el is REveProjectable add projected instance else add plain
196/// REveElementList to parent. Call the same function on el's
197/// children.
198///
199/// Returns the projected replica of el. Can be 0, if el and none of
200/// its children are projectable.
201
203 REveElement* parent)
204{
205 static const REveException eh("REveProjectionManager::ImportElementsRecurse ");
206
207 REveElement *new_el = nullptr;
208
209 if (ShouldImport(el))
210 {
211 REveProjected *new_pr = nullptr;
212 REveProjectable *pble = dynamic_cast<REveProjectable*>(el);
213 if (pble)
214 {
215 new_el = (REveElement*) pble->ProjectedClass(fProjection)->New();
216 new_pr = dynamic_cast<REveProjected*>(new_el);
217 new_pr->SetProjection(this, pble);
218 new_pr->SetDepth(fCurrentDepth);
219 }
220 else
221 {
222 new_el = new REveElement;
223 }
224 new_el->SetName (Form("%s [P]", el->GetCName()));
225 new_el->SetTitle(Form("Projected replica.\n%s", el->GetCTitle()));
226 new_el->SetRnrSelf (el->GetRnrSelf());
227 new_el->SetRnrChildren (el->GetRnrChildren());
228 new_el->SetPickable (el->IsPickable());
229
230 parent->AddElement(new_el);
231
232 REveCompound *cmpnd = dynamic_cast<REveCompound*>(el);
233 REveCompound *cmpnd_pr = dynamic_cast<REveCompound*>(new_el);
234 for (auto &c: el->RefChildren()) {
235 REveElement *child_pr = ImportElementsRecurse(c, new_el);
236 if (cmpnd && c->GetCompound() == cmpnd)
237 child_pr->SetCompound(cmpnd_pr);
238 }
239 }
240
241 return new_el;
242}
243
244////////////////////////////////////////////////////////////////////////////////
245/// Recursively import elements and apply projection to the newly
246/// imported objects.
247///
248/// If ext_list is not 0 the new element is also added to the list.
249/// This simplifies construction of complex views where projected
250/// elements are distributed into several scenes for optimization of
251/// updates and rendering.
252///
253/// Returns the projected replica of el. Can be 0, if el and none of
254/// its children are projectable.
255
257 REveElement* ext_list)
258{
259 REveElement* new_el = ImportElementsRecurse(el, ext_list ? ext_list : this);
260 if (new_el)
261 {
262 AssertBBox();
266
268
269 if (ext_list)
270 AddNiece(new_el);
271 }
272 return new_el;
273}
274
275////////////////////////////////////////////////////////////////////////////////
276/// Recursively import elements and apply projection to the newly
277/// imported objects.
278///
279/// The proj_parent argument should be a projected replica of parent
280/// of element 'el'. This allows to insert projected children of
281/// a given element when they are added after the projection has
282/// been already performed on the parent.
283/// This is called from REveElement::ProjectChild().
284///
285/// Returns the projected replica of el. Can be 0, if el and none of
286/// its children are projectable.
287
289 REveElement* proj_parent)
290{
291 REveElement* new_el = ImportElementsRecurse(el, proj_parent);
292 if (new_el)
293 {
294 AssertBBox();
298
300 }
301 return new_el;
302}
303
304////////////////////////////////////////////////////////////////////////////////
305/// Recursively import children elements of el and apply projection
306/// to the newly imported objects.
307///
308/// The proj_parent argument should be a projected replica of
309/// element 'el'. This allows to insert projected children of
310/// a given element when they are added after the projection has
311/// been already performed on the parent.
312/// This is called from REveElement::ProjectChild().
313///
314/// Returns the projected replica of el. Can be 0, if el and none of
315/// its children are projectable.
316
318{
319 List_t new_els;
320 for (auto &c: el->RefChildren()) {
321 auto new_el = ImportElementsRecurse(c, proj_parent);
322 if (new_el)
323 new_els.push_back(new_el);
324 }
325
326 if (!new_els.empty())
327 {
328 AssertBBox();
329 for (auto &nel: new_els)
333
334 UpdateDependentElements(proj_parent);
335 }
336 return (Int_t) new_els.size();
337}
338
339////////////////////////////////////////////////////////////////////////////////
340/// Project el (via REveProjected::UpdateProjection()) and recurse
341/// through el's children.
342/// Bounding-box is updated along the recursion.
343
345{
346 REveProjected* pted = dynamic_cast<REveProjected*>(el);
347 if (pted)
348 {
349 pted->UpdateProjection();
350 TAttBBox* bb = dynamic_cast<TAttBBox*>(pted);
351 if (bb)
352 {
353 Float_t* b = bb->AssertBBox();
354 BBoxCheckPoint(b[0], b[2], b[4]);
355 BBoxCheckPoint(b[1], b[3], b[5]);
356 }
357 el->StampObjProps();
358 }
359
360 for (auto &c : el->RefChildren()) ProjectChildrenRecurse(c);
361}
362
363////////////////////////////////////////////////////////////////////////////////
364/// Project all children recursively, update bounding-box and notify
365/// EveManger about the scenes that have been changed.
366
368{
369 BBoxInit();
370
371 for (auto &c : fChildren) ProjectChildrenRecurse(c);
372
373 for (auto &n : fNieces) ProjectChildrenRecurse(n);
374
377
379}
380
381////////////////////////////////////////////////////////////////////////////////
382/// Virtual from TAttBBox; fill bounding-box information.
383///
384/// The bounding-box information is kept coherent during addition of
385/// projected elements and projection parameter updates. This is
386/// called only in case the manager has not been populated at all.
387
389{
390 static const REveException eH("REveProjectionManager::ComputeBBox ");
391
392 if ( ! HasChildren() && ! HasNieces())
393 {
394 BBoxZero();
395 return;
396 }
397
398 BBoxInit();
399}
#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:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
float Float_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:100
int type
Definition: TGX11.cxx:121
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:62
REveElement(const std::string &name="", const std::string &title="")
Default constructor.
Definition: REveElement.cxx:50
void SetName(const std::string &name)
Set name of an element.
REveException Exception-type thrown by Eve classes.
Definition: REveTypes.hxx:41
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.
virtual void UpdateDependentElements(REveElement *root)
Update dependent elements' bounding boxes.
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.
REveProjectionManager(const REveProjectionManager &)=delete
virtual REveElement * SubImportElements(REveElement *el, REveElement *proj_parent)
Recursively import elements and apply projection to the newly imported objects.
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.
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:4971
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4867
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16