Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
39REveProjectionManager::REveProjectionManager(REveProjection::EPType_e type):
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 box and mark scenes
184/// containing element root or its children as requiring a repaint.
185
187{
188 for (auto &d: fDependentEls) {
189 TAttBBox* bbox = dynamic_cast<TAttBBox *>(d);
190 if (bbox)
191 bbox->ComputeBBox();
192 }
193
194 static int warn_count = 0;
195 if (++warn_count <= 5)
196 Warning("REveProjectionManager::UpdateDependentElsAndScenes",
197 "Figure out if scene stamping is still needed.");
198 /*
199 List_t scenes;
200 root->CollectScenes(scenes);
201 if (root == this)
202 for (auto &n : fNieces)
203 n->CollectScenes(scenes);
204
205 REX::gEve->ScenesChanged(scenes);
206 */
207}
208
209////////////////////////////////////////////////////////////////////////////////
210/// If el is REveProjectable add projected instance else add plain
211/// REveElementList to parent. Call the same function on el's
212/// children.
213///
214/// Returns the projected replica of el. Can be 0, if el and none of
215/// its children are projectable.
216
218 REveElement* parent)
219{
220 static const REveException eh("REveProjectionManager::ImportElementsRecurse ");
221
222 REveElement *new_el = nullptr;
223
224 if (ShouldImport(el))
225 {
226 REveProjected *new_pr = nullptr;
227 REveProjectable *pble = dynamic_cast<REveProjectable*>(el);
228 if (pble)
229 {
230 new_el = (REveElement*) pble->ProjectedClass(fProjection)->New();
231 new_pr = dynamic_cast<REveProjected*>(new_el);
232 new_pr->SetProjection(this, pble);
233 new_pr->SetDepth(fCurrentDepth);
234 }
235 else
236 {
237 new_el = new REveElement;
238 }
239 new_el->SetName (Form("%s [P]", el->GetCName()));
240 new_el->SetTitle(Form("Projected replica.\n%s", el->GetCTitle()));
241 new_el->SetRnrSelf (el->GetRnrSelf());
242 new_el->SetRnrChildren (el->GetRnrChildren());
243 new_el->SetPickable (el->IsPickable());
244
245 parent->AddElement(new_el);
246
247 REveCompound *cmpnd = dynamic_cast<REveCompound*>(el);
248 REveCompound *cmpnd_pr = dynamic_cast<REveCompound*>(new_el);
249 for (auto &c: el->RefChildren()) {
250 REveElement *child_pr = ImportElementsRecurse(c, new_el);
251 if (cmpnd && c->GetCompound() == cmpnd)
252 child_pr->SetCompound(cmpnd_pr);
253 }
254 }
255
256 return new_el;
257}
258
259////////////////////////////////////////////////////////////////////////////////
260/// Recursively import elements and apply projection to the newly
261/// imported objects.
262///
263/// If ext_list is not 0 the new element is also added to the list.
264/// This simplifies construction of complex views where projected
265/// elements are distributed into several scenes for optimization of
266/// updates and rendering.
267///
268/// Returns the projected replica of el. Can be 0, if el and none of
269/// its children are projectable.
270
272 REveElement* ext_list)
273{
274 REveElement* new_el = ImportElementsRecurse(el, ext_list ? ext_list : this);
275 if (new_el)
276 {
277 AssertBBox();
281
283
284 if (ext_list)
285 AddNiece(new_el);
286 }
287 return new_el;
288}
289
290////////////////////////////////////////////////////////////////////////////////
291/// Recursively import elements and apply projection to the newly
292/// imported objects.
293///
294/// The proj_parent argument should be a projected replica of parent
295/// of element 'el'. This allows to insert projected children of
296/// a given element when they are added after the projection has
297/// been already performed on the parent.
298/// This is called from REveElement::ProjectChild().
299///
300/// Returns the projected replica of el. Can be 0, if el and none of
301/// its children are projectable.
302
304 REveElement* proj_parent)
305{
306 REveElement* new_el = ImportElementsRecurse(el, proj_parent);
307 if (new_el)
308 {
309 AssertBBox();
313
315 }
316 return new_el;
317}
318
319////////////////////////////////////////////////////////////////////////////////
320/// Recursively import children elements of el and apply projection
321/// to the newly imported objects.
322///
323/// The proj_parent argument should be a projected replica of
324/// element 'el'. This allows to insert projected children of
325/// a given element when they are added after the projection has
326/// been already performed on the parent.
327/// This is called from REveElement::ProjectChild().
328///
329/// Returns the projected replica of el. Can be 0, if el and none of
330/// its children are projectable.
331
333{
334 List_t new_els;
335 for (auto &c: el->RefChildren()) {
336 auto new_el = ImportElementsRecurse(c, proj_parent);
337 if (new_el)
338 new_els.push_back(new_el);
339 }
340
341 if (!new_els.empty())
342 {
343 AssertBBox();
344 for (auto &nel: new_els)
348
349 UpdateDependentElsAndScenes(proj_parent);
350 }
351 return (Int_t) new_els.size();
352}
353
354////////////////////////////////////////////////////////////////////////////////
355/// Project el (via REveProjected::UpdateProjection()) and recurse
356/// through el's children.
357/// Bounding-box is updated along the recursion.
358
360{
361 REveProjected* pted = dynamic_cast<REveProjected*>(el);
362 if (pted)
363 {
364 pted->UpdateProjection();
365 TAttBBox* bb = dynamic_cast<TAttBBox*>(pted);
366 if (bb)
367 {
368 Float_t* b = bb->AssertBBox();
369 BBoxCheckPoint(b[0], b[2], b[4]);
370 BBoxCheckPoint(b[1], b[3], b[5]);
371 }
372 el->StampObjProps();
373 }
374
375 for (auto &c : el->RefChildren()) ProjectChildrenRecurse(c);
376}
377
378////////////////////////////////////////////////////////////////////////////////
379/// Project all children recursively, update bounding-box and notify
380/// EveManger about the scenes that have been changed.
381
383{
384 BBoxInit();
385
386 for (auto &c : fChildren) ProjectChildrenRecurse(c);
387
388 for (auto &n : fNieces) ProjectChildrenRecurse(n);
389
392
394}
395
396////////////////////////////////////////////////////////////////////////////////
397/// Virtual from TAttBBox; fill bounding-box information.
398///
399/// The bounding-box information is kept coherent during addition of
400/// projected elements and projection parameter updates. This is
401/// called only in case the manager has not been populated at all.
402
404{
405 static const REveException eH("REveProjectionManager::ComputeBBox ");
406
407 if ( ! HasChildren() && ! HasNieces())
408 {
409 BBoxZero();
410 return;
411 }
412
413 BBoxInit();
414}
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
const Bool_t kFALSE
Definition RtypesCore.h:92
const Bool_t kTRUE
Definition RtypesCore.h:91
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:231
int type
Definition TGX11.cxx:121
char * Form(const char *fmt,...)
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
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.
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)
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:4955
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4851
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16