TEveProjectionManager.cxx

Go to the documentation of this file.
00001 // @(#)root/eve:$Id: TEveProjectionManager.cxx 33037 2010-04-15 13:58:19Z matevz $
00002 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "TEveProjectionManager.h"
00013 #include "TEveManager.h"
00014 #include "TEveProjectionBases.h"
00015 #include "TEveCompound.h"
00016 
00017 #include "TBuffer3D.h"
00018 #include "TBuffer3DTypes.h"
00019 #include "TVirtualPad.h"
00020 #include "TVirtualViewer3D.h"
00021 
00022 #include "TClass.h"
00023 
00024 #include <list>
00025 
00026 //==============================================================================
00027 //==============================================================================
00028 // TEveProjectionManager
00029 //==============================================================================
00030 
00031 //______________________________________________________________________________
00032 //
00033 // Manager class for steering of projections and managing projected
00034 // objects.
00035 //
00036 // Recursively projects TEveElement's and draws axis in the projected
00037 // scene.  It enables to interactivly set TEveProjection parameters
00038 // and updates projected scene accordingly.
00039 
00040 ClassImp(TEveProjectionManager);
00041 
00042 //______________________________________________________________________________
00043 TEveProjectionManager::TEveProjectionManager(TEveProjection::EPType_e type):
00044    TEveElementList("TEveProjectionManager",""),
00045    TAttBBox(),
00046    fProjection  (0),
00047    fCurrentDepth(0),
00048    fImportEmpty (kFALSE)
00049 {
00050    // Constructor.
00051 
00052    for (Int_t i = 0; i < TEveProjection::kPT_End; ++i)
00053       fProjections[i] = 0;
00054 
00055    if (type != TEveProjection::kPT_Unknown)
00056       SetProjection(type);
00057 }
00058 
00059 //______________________________________________________________________________
00060 TEveProjectionManager::~TEveProjectionManager()
00061 {
00062    // Destructor.
00063    // Destroys also dependent elements.
00064 
00065    for (Int_t i = 0; i < TEveProjection::kPT_End; ++i)
00066    {
00067       delete fProjections[i];
00068    }
00069    while ( ! fDependentEls.empty())
00070    {
00071       fDependentEls.front()->Destroy();
00072    }
00073 }
00074 
00075 //______________________________________________________________________________
00076 void TEveProjectionManager::AddDependent(TEveElement* el)
00077 {
00078    // Add el as dependent element.
00079 
00080    fDependentEls.push_back(el);
00081 }
00082 
00083 //______________________________________________________________________________
00084 void TEveProjectionManager::RemoveDependent(TEveElement* el)
00085 {
00086    // Remove el as dependent element.
00087 
00088    fDependentEls.remove(el);
00089 }
00090 
00091 //______________________________________________________________________________
00092 void TEveProjectionManager::UpdateName()
00093 {
00094    // Updates name to have consitent information with prjection.
00095 
00096    if (fProjection->Is2D())
00097       SetName(Form ("%s (%3.1f)", fProjection->GetName(), fProjection->GetDistortion()*1000));
00098    else
00099       SetName(fProjection->GetName());
00100 }
00101 
00102 //______________________________________________________________________________
00103 void TEveProjectionManager::SetProjection(TEveProjection::EPType_e type)
00104 {
00105    // Set projection type and distortion.
00106 
00107    static const TEveException eH("TEveProjectionManager::SetProjection ");
00108 
00109    if (fProjections[type] == 0)
00110    {
00111       switch (type)
00112       {
00113          case TEveProjection::kPT_RPhi:
00114          {
00115             fProjections[type] = new TEveRPhiProjection();
00116             break;
00117          }
00118          case TEveProjection::kPT_RhoZ:
00119          {
00120             fProjections[type] = new TEveRhoZProjection();
00121             break;
00122          }
00123          case TEveProjection::kPT_3D:
00124          {
00125             fProjections[type] = new TEve3DProjection();
00126             break;
00127          }
00128          default:
00129             throw eH + "projection type not valid.";
00130             break;
00131       }
00132    }
00133 
00134    if (fProjection && fProjection->Is2D() != fProjections[type]->Is2D())
00135    {
00136       throw eH + "switching between 2D and 3D projections not implemented.";
00137    }
00138 
00139    fProjection = fProjections[type];
00140    fProjection->SetCenter(fCenter);
00141    UpdateName();
00142 }
00143 
00144 //______________________________________________________________________________
00145 void TEveProjectionManager::SetCenter(Float_t x, Float_t y, Float_t z)
00146 {
00147    // Set projection center and rebuild projected scene.
00148 
00149    fCenter.Set(x, y, z);
00150    fProjection->SetCenter(fCenter);
00151    ProjectChildren();
00152 }
00153 
00154 //______________________________________________________________________________
00155 Bool_t TEveProjectionManager::HandleElementPaste(TEveElement* el)
00156 {
00157    // React to element being pasted or dnd-ed.
00158    // Return true if redraw is needed (virtual method).
00159 
00160    List_t::size_type n_children  = fChildren.size();
00161    ImportElements(el);
00162    return n_children != fChildren.size();
00163 }
00164 
00165 //______________________________________________________________________________
00166 Bool_t TEveProjectionManager::ShouldImport(TEveElement* el)
00167 {
00168    // Returns true if element el should be imported.
00169    //
00170    // Behaviour depends on the value of the fImportEmpty member:
00171    //   false - el or any of its children must be projectable (default);
00172    //   true  - always import.
00173 
00174    if (fImportEmpty)
00175       return kTRUE;
00176 
00177    if (el->IsA() != TEveElementList::Class() && el->IsA()->InheritsFrom(TEveProjectable::Class()))
00178       return kTRUE;
00179    for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i)
00180       if (ShouldImport(*i))
00181          return kTRUE;
00182    return kFALSE;
00183 }
00184 
00185 //______________________________________________________________________________
00186 void TEveProjectionManager::UpdateDependentElsAndScenes(TEveElement* root)
00187 {
00188    // Update dependent elements' bounding box and mark scenes
00189    // containing element root or its children as requiring a repaint.
00190 
00191    for (List_i i=fDependentEls.begin(); i!=fDependentEls.end(); ++i)
00192    {
00193       TAttBBox* bbox = dynamic_cast<TAttBBox*>(*i);
00194       if (bbox)
00195          bbox->ComputeBBox();
00196    }
00197 
00198    List_t scenes;
00199    root->CollectSceneParentsFromChildren(scenes, 0);
00200    gEve->ScenesChanged(scenes);
00201 }
00202 
00203 //______________________________________________________________________________
00204 TEveElement* TEveProjectionManager::ImportElementsRecurse(TEveElement* el,
00205                                                           TEveElement* parent)
00206 {
00207    // If el is TEveProjectable add projected instance else add plain
00208    // TEveElementList to parent. Call the same function on el's
00209    // children.
00210    //
00211    // Returns the projected replica of el. Can be 0, if el and none of
00212    // its children are projectable.
00213 
00214    static const TEveException eh("TEveProjectionManager::ImportElementsRecurse ");
00215 
00216    TEveElement *new_el = 0;
00217 
00218    if (ShouldImport(el))
00219    {
00220       TEveProjected   *new_pr = 0;
00221       TEveProjectable *pble   = dynamic_cast<TEveProjectable*>(el);
00222       if (pble)
00223       {
00224          new_el = (TEveElement*) pble->ProjectedClass(fProjection)->New();
00225          new_pr = dynamic_cast<TEveProjected*>(new_el);
00226          new_pr->SetProjection(this, pble);
00227          new_pr->SetDepth(fCurrentDepth);
00228       }
00229       else
00230       {
00231          new_el = new TEveElementList;
00232       }
00233       new_el->SetElementName (Form("%s [P]", el->GetElementName()));
00234       new_el->SetElementTitle(Form("Projected replica.\n%s", el->GetElementTitle()));
00235       new_el->SetRnrSelf     (el->GetRnrSelf());
00236       new_el->SetRnrChildren (el->GetRnrChildren());
00237       new_el->SetPickable    (el->IsPickable());
00238       parent->AddElement(new_el);
00239 
00240       TEveCompound *cmpnd    = dynamic_cast<TEveCompound*>(el);
00241       TEveCompound *cmpnd_pr = dynamic_cast<TEveCompound*>(new_el);
00242       for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i)
00243       {
00244          TEveElement* child_pr = ImportElementsRecurse(*i, new_el);
00245          if (cmpnd && (*i)->GetCompound() == cmpnd)
00246             child_pr->SetCompound(cmpnd_pr);
00247       }
00248    }
00249 
00250    return new_el;
00251 }
00252 
00253 //______________________________________________________________________________
00254 TEveElement* TEveProjectionManager::ImportElements(TEveElement* el,
00255                                                    TEveElement* ext_list)
00256 {
00257    // Recursively import elements and apply projection to the newly
00258    // imported objects.
00259    //
00260    // If ext_list is not 0 the new element is also added to the list.
00261    // This simplifies construction of complex views where projected
00262    // elements are distributed into several scenes for optimization of
00263    // updates and rendering.
00264    //
00265    // Returns the projected replica of el. Can be 0, if el and none of
00266    // its children are projectable.
00267 
00268    TEveElement* new_el = ImportElementsRecurse(el, this);
00269    if (new_el)
00270    {
00271       AssertBBox();
00272       ProjectChildrenRecurse(new_el);
00273       AssertBBoxExtents(0.1);
00274       StampTransBBox();
00275 
00276       UpdateDependentElsAndScenes(new_el);
00277 
00278       if (ext_list)
00279          ext_list->AddElement(new_el);
00280    }
00281    return new_el;
00282 }
00283 
00284 //______________________________________________________________________________
00285 TEveElement* TEveProjectionManager::SubImportElements(TEveElement* el,
00286                                                       TEveElement* proj_parent)
00287 {
00288    // Recursively import elements and apply projection to the newly
00289    // imported objects.
00290    //
00291    // The proj_parent argument should be a projected replica of parent
00292    // of element 'el'. This allows to insert projected children of
00293    // a given element when they are added after the projection has
00294    // been already performed on the parent.
00295    // This is called from TEveElement::ProjectChild().
00296    //
00297    // Returns the projected replica of el. Can be 0, if el and none of
00298    // its children are projectable.
00299 
00300    TEveElement* new_el = ImportElementsRecurse(el, proj_parent);
00301    if (new_el)
00302    {
00303       AssertBBox();
00304       ProjectChildrenRecurse(new_el);
00305       AssertBBoxExtents(0.1);
00306       StampTransBBox();
00307 
00308       UpdateDependentElsAndScenes(new_el);
00309    }
00310    return new_el;
00311 }
00312 
00313 //______________________________________________________________________________
00314 Int_t TEveProjectionManager::SubImportChildren(TEveElement* el, TEveElement* proj_parent)
00315 {
00316    // Recursively import childer elements of el and apply projection
00317    // to the newly imported objects.
00318    //
00319    // The proj_parent argument should be a projected replica of
00320    // element 'el'. This allows to insert projected children of
00321    // a given element when they are added after the projection has
00322    // been already performed on the parent.
00323    // This is called from TEveElement::ProjectChild().
00324    //
00325    // Returns the projected replica of el. Can be 0, if el and none of
00326    // its children are projectable.
00327 
00328    List_t new_els;
00329    for (List_i i = el->BeginChildren(); i != el->EndChildren(); ++i)
00330    {
00331       TEveElement* new_el = ImportElementsRecurse(*i, proj_parent);
00332       if (new_el)
00333          new_els.push_back(new_el);
00334    }
00335 
00336    if ( ! new_els.empty())
00337    {
00338       AssertBBox();
00339       for (List_i i = new_els.begin(); i != new_els.end(); ++i)
00340       {
00341          ProjectChildrenRecurse(*i);
00342       }
00343       AssertBBoxExtents(0.1);
00344       StampTransBBox();
00345 
00346       UpdateDependentElsAndScenes(proj_parent);
00347    }
00348    return (Int_t) new_els.size();
00349 }
00350 
00351 //______________________________________________________________________________
00352 void TEveProjectionManager::ProjectChildrenRecurse(TEveElement* el)
00353 {
00354    // Project el (via TEveProjected::UpdateProjection()) and recurse
00355    // through el's children.
00356    // Bounding-box is updated along the recursion.
00357 
00358    TEveProjected* pted = dynamic_cast<TEveProjected*>(el);
00359    if (pted)
00360    {
00361       pted->UpdateProjection();
00362       TAttBBox* bb = dynamic_cast<TAttBBox*>(pted);
00363       if (bb)
00364       {
00365          Float_t* b = bb->AssertBBox();
00366          BBoxCheckPoint(b[0], b[2], b[4]);
00367          BBoxCheckPoint(b[1], b[3], b[5]);
00368       }
00369       el->ElementChanged(kFALSE);
00370    }
00371 
00372    for (List_i i=el->BeginChildren(); i!=el->EndChildren(); ++i)
00373       ProjectChildrenRecurse(*i);
00374 }
00375 
00376 //______________________________________________________________________________
00377 void TEveProjectionManager::ProjectChildren()
00378 {
00379    // Project all children recursively, update bounding-box and notify
00380    // TEveManger about the scenes that have been changed.
00381 
00382    BBoxInit();
00383    for (List_i i=BeginChildren(); i!=EndChildren(); ++i)
00384       ProjectChildrenRecurse(*i);
00385    AssertBBoxExtents(0.1);
00386    StampTransBBox();
00387 
00388    UpdateDependentElsAndScenes(this);
00389 }
00390 
00391 //______________________________________________________________________________
00392 void TEveProjectionManager::ComputeBBox()
00393 {
00394    // Virtual from TAttBBox; fill bounding-box information.
00395    //
00396    // The bounding-box information is kept coherent during addition of
00397    // projected elements and projection parameter updates. This is
00398    // called only in case the manager has not been populated at all.
00399 
00400    static const TEveException eH("TEveProjectionManager::ComputeBBox ");
00401 
00402    if (HasChildren() == kFALSE) {
00403       BBoxZero();
00404       return;
00405    }
00406 
00407    BBoxInit();
00408 }

Generated on Tue Jul 5 14:16:13 2011 for ROOT_528-00b_version by  doxygen 1.5.1