TEveUtil.cxx

Go to the documentation of this file.
00001 // @(#)root/eve:$Id: TEveUtil.cxx 36373 2010-10-19 17:43:35Z 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 "TEveUtil.h"
00013 #include "TEveElement.h"
00014 #include "TEveManager.h"
00015 
00016 #include "TError.h"
00017 #include "TGeoManager.h"
00018 #include "TGeoMatrix.h"
00019 #include "TClass.h"
00020 #include "TMath.h"
00021 
00022 #include "TStyle.h"
00023 #include "TColor.h"
00024 
00025 #include "TROOT.h"
00026 #include "TInterpreter.h"
00027 #include "TSystem.h"
00028 
00029 #include "TGClient.h"
00030 #include "TGMimeTypes.h"
00031 
00032 #include "Riostream.h"
00033 
00034 #include <list>
00035 #include <algorithm>
00036 #include <string>
00037 
00038 //==============================================================================
00039 // TEveUtil
00040 //==============================================================================
00041 
00042 //______________________________________________________________________________
00043 //
00044 // Standard utility functions for Eve.
00045 
00046 ClassImp(TEveUtil);
00047 
00048 TObjArray* TEveUtil::fgDefaultColors = 0;
00049 
00050 //______________________________________________________________________________
00051 void TEveUtil::SetupEnvironment()
00052 {
00053    // Setup Include and Macro paths.
00054    // Since inclusion into ROOT this does nothing but could
00055    // potentially be reactivated if some common macros are established
00056    // and shipped with binary ROOT (in macros/eve). For example, these
00057    // might be used to spawn specific GUI / GL configurations.
00058 
00059    static const TEveException eh("TEveUtil::SetupEnvironment");
00060    static Bool_t setupDone = kFALSE;
00061 
00062    if (setupDone) {
00063       Info(eh.Data(), "has already been run.");
00064       return;
00065    }
00066 
00067    // Old initialization for ALICE.
00068    // Left as an example.
00069    /*
00070    // Check if REVESYS exists, try fallback to $ALICE_ROOT/EVE.
00071    if(gSystem->Getenv("REVESYS") == 0) {
00072       if(gSystem->Getenv("ALICE_ROOT") != 0) {
00073          Info(eh.Data(), "setting REVESYS from ALICE_ROOT.");
00074          gSystem->Setenv("REVESYS", Form("%s/EVE", gSystem->Getenv("ALICE_ROOT")));
00075       } else {
00076          Error(eh.Data(), "REVESYS not defined, neither is ALICE_ROOT.");
00077          gSystem->Exit(1);
00078       }
00079    }
00080    if(gSystem->AccessPathName(gSystem->Getenv("REVESYS")) == kTRUE) {
00081       Error(eh.Data(), "REVESYS '%s' does not exist.", gSystem->Getenv("REVESYS"));
00082       gSystem->Exit(1);
00083    }
00084 
00085    TString macPath(gROOT->GetMacroPath());
00086    macPath += Form(":%s/macros", gSystem->Getenv("REVESYS"));
00087    gInterpreter->AddIncludePath(gSystem->Getenv("REVESYS"));
00088    if(gSystem->Getenv("ALICE_ROOT") != 0) {
00089       macPath += Form(":%s/alice-macros", gSystem->Getenv("REVESYS"));
00090       gInterpreter->AddIncludePath(Form("%s/include", gSystem->Getenv("ALICE_ROOT")));
00091       gInterpreter->AddIncludePath(gSystem->Getenv("ALICE_ROOT"));
00092    }
00093    gROOT->SetMacroPath(macPath);
00094    */
00095 }
00096 
00097 //______________________________________________________________________________
00098 void TEveUtil::SetupGUI()
00099 {
00100    // Setup icon pictures and mime-types.
00101 
00102    TEveElement::fgRnrIcons[0] = gClient->GetPicture("eve_rnr00_t.xpm");
00103    TEveElement::fgRnrIcons[1] = gClient->GetPicture("eve_rnr01_t.xpm");
00104    TEveElement::fgRnrIcons[2] = gClient->GetPicture("eve_rnr10_t.xpm");
00105    TEveElement::fgRnrIcons[3] = gClient->GetPicture("eve_rnr11_t.xpm");
00106 
00107    TEveElement::fgListTreeIcons[0] = gClient->GetPicture("folder_t.xpm");
00108    TEveElement::fgListTreeIcons[1] = gClient->GetPicture("eve_viewer.xpm");
00109    TEveElement::fgListTreeIcons[2] = gClient->GetPicture("eve_scene.xpm");
00110    TEveElement::fgListTreeIcons[3] = gClient->GetPicture("eve_pointset.xpm");
00111    TEveElement::fgListTreeIcons[4] = gClient->GetPicture("eve_track.xpm");
00112    TEveElement::fgListTreeIcons[5] = gClient->GetPicture("eve_text.gif");
00113    TEveElement::fgListTreeIcons[6] = gClient->GetPicture("eve_axes.xpm");
00114    TEveElement::fgListTreeIcons[7] = gClient->GetPicture("ofolder_t.xpm");
00115    TEveElement::fgListTreeIcons[8] = gClient->GetPicture("eve_line.xpm");
00116 
00117    gClient->GetMimeTypeList()->AddType("root/tmacro", "TEveMacro",
00118                                        "tmacro_s.xpm", "tmacro_t.xpm", "");
00119 }
00120 
00121 /******************************************************************************/
00122 
00123 namespace
00124 {
00125 //______________________________________________________________________________
00126 void ChompTailAndDir(TString& s, char c='.')
00127 {
00128    // Remove last part of string 's', starting from the last
00129    // occurrence of character 'c'.
00130    // Remove directory part -- everything until the last '/'.
00131 
00132    Ssiz_t p = s.Last(c);
00133    if (p != kNPOS)
00134       s.Remove(p);
00135 
00136    Ssiz_t ls = s.Last('/');
00137    if (ls != kNPOS)
00138       s.Remove(0, ls + 1);
00139 }
00140 }
00141 
00142 //______________________________________________________________________________
00143 Bool_t TEveUtil::CheckMacro(const char* mac)
00144 {
00145    // Checks if macro 'mac' is loaded.
00146 
00147    // Axel's advice; now sth seems slow, using old method below for test.
00148    // return gROOT->GetInterpreter()->IsLoaded(mac);
00149 
00150    // Previous version expected function with same name and used ROOT's
00151    // list of global functions.
00152 
00153    TString foo(mac); ChompTailAndDir(foo);
00154    if (gROOT->GetGlobalFunction(foo.Data(), 0, kFALSE) != 0)
00155       return kTRUE;
00156    else
00157       return (gROOT->GetGlobalFunction(foo.Data(), 0, kTRUE) != 0);
00158 }
00159 
00160 //______________________________________________________________________________
00161 void TEveUtil::AssertMacro(const char* mac)
00162 {
00163    // Load and execute macro 'mac' if it has not been loaded yet.
00164 
00165    if( CheckMacro(mac) == kFALSE) {
00166       gROOT->Macro(mac);
00167    }
00168 }
00169 
00170 //______________________________________________________________________________
00171 void TEveUtil::Macro(const char* mac)
00172 {
00173    // Execute macro 'mac'. Do not reload the macro.
00174 
00175    if (CheckMacro(mac) == kFALSE) {
00176       gROOT->LoadMacro(mac);
00177    }
00178    TString foo(mac); ChompTailAndDir(foo); foo += "()";
00179    gROOT->ProcessLine(foo.Data());
00180 }
00181 
00182 //______________________________________________________________________________
00183 void TEveUtil::LoadMacro(const char* mac)
00184 {
00185    // Makes sure that macro 'mac' is loaded, but do not reload it.
00186 
00187    if (CheckMacro(mac) == kFALSE) {
00188       gROOT->LoadMacro(mac);
00189    }
00190 }
00191 
00192 /******************************************************************************/
00193 // Color management
00194 /******************************************************************************/
00195 
00196 //______________________________________________________________________________
00197 void TEveUtil::ColorFromIdx(Color_t ci, UChar_t col[4], Bool_t alpha)
00198 {
00199    // Fill col with RGBA values corresponding to index ci. If alpha
00200    // is true, set alpha component of col to 255.
00201    // ROOT's indexed color palette does not support transparency.
00202 
00203    TColor* c = gROOT->GetColor(ci);
00204    if (c)
00205    {
00206       col[0] = (UChar_t)(255*c->GetRed());
00207       col[1] = (UChar_t)(255*c->GetGreen());
00208       col[2] = (UChar_t)(255*c->GetBlue());
00209       if (alpha) col[3] = 255;
00210    }
00211    else
00212    {
00213       // Set to magenta.
00214       col[0] = 255; col[1] = 0; col[2] = 255;
00215       if (alpha) col[3] = 255;
00216       return;
00217    }
00218 }
00219 
00220 //______________________________________________________________________________
00221 void TEveUtil::ColorFromIdx(Color_t ci, UChar_t col[4], Char_t transparency)
00222 {
00223    // Fill col with RGBA values corresponding to index ci and transparency.
00224    // ROOT's indexed color palette does not support transparency.
00225 
00226    UChar_t alpha = (255*(100 - transparency))/100;
00227 
00228    TColor* c = gROOT->GetColor(ci);
00229    if (c)
00230    {
00231       col[0] = (UChar_t)(255*c->GetRed());
00232       col[1] = (UChar_t)(255*c->GetGreen());
00233       col[2] = (UChar_t)(255*c->GetBlue());
00234       col[3] = alpha;
00235    }
00236    else
00237    {
00238       // Set to magenta.
00239       col[0] = 255; col[1] = 0; col[2] = 255; col[3] = alpha;
00240       return;
00241    }
00242 }
00243 
00244 //______________________________________________________________________________
00245 void TEveUtil::ColorFromIdx(Float_t f1, Color_t c1, Float_t f2, Color_t c2,
00246                             UChar_t col[4], Bool_t alpha)
00247 {
00248    // Fill col with weighted RGBA values corresponding to
00249    // color-indices c1 and c2. If alpha is true, set alpha component
00250    // of col to 255.
00251 
00252    TColor* t1 = gROOT->GetColor(c1);
00253    TColor* t2 = gROOT->GetColor(c2);
00254    if(t1 && t2) {
00255       col[0] = (UChar_t)(255*(f1*t1->GetRed()   + f2*t2->GetRed()));
00256       col[1] = (UChar_t)(255*(f1*t1->GetGreen() + f2*t2->GetGreen()));
00257       col[2] = (UChar_t)(255*(f1*t1->GetBlue()  + f2*t2->GetBlue()));
00258       if (alpha) col[3] = 255;
00259    }
00260 }
00261 
00262 //______________________________________________________________________________
00263 Color_t* TEveUtil::FindColorVar(TObject* obj, const char* varname)
00264 {
00265    // Find address of Color_t data-member with name varname in object
00266    // obj.
00267    //
00268    // This is used to access color information for TGListTreeItem
00269    // coloration from visualization macros that wrap TObjects into
00270    // TEveElementObjectPtr instances.
00271 
00272    static const TEveException eh("TEveUtil::FindColorVar");
00273 
00274    Int_t off = obj->IsA()->GetDataMemberOffset(varname);
00275    if(off == 0)
00276       throw(eh + "could not find member '" + varname + "' in class " + obj->IsA()->GetName() + ".");
00277    return (Color_t*) (((char*)obj) + off);
00278 }
00279 
00280 //______________________________________________________________________________
00281 void TEveUtil::SetColorBrightness(Float_t value, Bool_t full_redraw)
00282 {
00283    // Tweak all ROOT colors to become brighter (if value > 0) or
00284    // darker (value < 0). Reasonable values for the value argument are
00285    // from -2.5 to 2.5 (error will be printed otherwise).
00286    // If value is zero, the original colors are restored.
00287    //
00288    // You should call TEveManager::FullRedraw3D() afterwards or set
00289    // the argument full_redraw to true (default is false).
00290 
00291    if (value < -2.5 || value > 2.5)
00292    {
00293       Error("TEveUtil::SetColorBrightness", "value '%f' out of range [-0.5, 0.5].", value);
00294       return;
00295    }
00296 
00297    TObjArray   *colors = (TObjArray*) gROOT->GetListOfColors();
00298 
00299    if (fgDefaultColors == 0)
00300    {
00301       const Int_t n_col = colors->GetEntriesFast();
00302       fgDefaultColors = new TObjArray(n_col);
00303       for (Int_t i = 0; i < n_col; ++i)
00304       {
00305          TColor* c = (TColor*) colors->At(i);
00306          if (c)
00307             fgDefaultColors->AddAt(new TColor(*c), i);
00308       }
00309    }
00310 
00311    const Int_t n_col = fgDefaultColors->GetEntriesFast();
00312    for (Int_t i = 0; i < n_col; ++i)
00313    {
00314       TColor* cdef = (TColor*) fgDefaultColors->At(i);
00315       if (cdef)
00316       {
00317          TColor* croot = (TColor*)  colors->At(i);
00318          if (croot == 0)
00319          {
00320             croot = new TColor(*cdef);
00321             colors->AddAt(croot, i);
00322          }
00323          else
00324          {
00325             cdef->Copy(*croot);
00326          }
00327 
00328          Float_t r, g, b;
00329          croot->GetRGB(r, g, b);
00330          r = TMath::Power( r, (2.5 - value)/2.5);
00331          g = TMath::Power(g, (2.5 - value)/2.5);
00332          b = TMath::Power(b, (2.5 - value)/2.5);
00333 
00334          r = TMath::Min(r, 1.0f);
00335          g = TMath::Min(g, 1.0f);
00336          b = TMath::Min(b, 1.0f);
00337 
00338          croot->SetRGB(r, g, b);
00339       }
00340       else
00341       {
00342          delete colors->RemoveAt(i);
00343       }
00344    }
00345 
00346    if (full_redraw && gEve != 0)
00347       gEve->FullRedraw3D();
00348 }
00349 
00350 /******************************************************************************/
00351 // Math utilities
00352 /******************************************************************************/
00353 
00354 //______________________________________________________________________________
00355 Bool_t TEveUtil::IsU1IntervalContainedByMinMax(Float_t minM, Float_t maxM,
00356                                                Float_t minQ, Float_t maxQ)
00357 {
00358    // Return true if interval Q is contained within interval M for U1 variables.
00359    // It is assumed that all values are within the [-2pi, 2pi] interval and
00360    // minM <= maxM & minQ <= maxQ.
00361 
00362    using namespace TMath;
00363 
00364    if (maxQ < minM)
00365    {
00366       minQ += TwoPi(); maxQ += TwoPi();
00367    }
00368    else if (minQ > maxM)
00369    {
00370       minQ -= TwoPi(); maxQ -= TwoPi();
00371    }
00372    return minQ >= minM && maxQ <= maxM;
00373 }
00374 
00375 //______________________________________________________________________________
00376 Bool_t TEveUtil::IsU1IntervalOverlappingByMinMax(Float_t minM, Float_t maxM,
00377                                                  Float_t minQ, Float_t maxQ)
00378 {
00379    // Return true if interval Q is overlapping within interval M for U1 variables.
00380    // It is assumed that all values are within the [-2pi, 2pi] interval and
00381    // minM <= maxM & minQ <= maxQ.
00382 
00383    using namespace TMath;
00384 
00385    if (maxQ < minM)
00386    {
00387       minQ += TwoPi(); maxQ += TwoPi();
00388    }
00389    else if (minQ > maxM)
00390    {
00391       minQ -= TwoPi(); maxQ -= TwoPi();
00392    }
00393    return maxQ >= minM && minQ <= maxM;
00394 }
00395 
00396 //______________________________________________________________________________
00397 Float_t TEveUtil::GetFraction(Float_t minM, Float_t maxM, Float_t minQ, Float_t maxQ)
00398 {
00399    // Get fraction of interval [minQ, maxQ] in [minM, maxM]
00400 
00401    if (minQ>=minM && maxQ<=maxM)
00402       return 1;
00403 
00404    else if (minQ<minM && maxQ>maxM)
00405       return (maxM-minM)/(maxQ-minQ);
00406 
00407    else if (minQ>=minM && maxQ>maxM)
00408       return (maxM-minQ)/(maxQ-minQ);
00409 
00410    else if (minQ<minM && maxQ<=maxM)
00411       return (maxQ-minM)/(maxQ-minQ);
00412 
00413    return 0;
00414 }
00415 
00416 /******************************************************************************/
00417 // TEveException
00418 /******************************************************************************/
00419 
00420 //______________________________________________________________________________
00421 //
00422 // Exception class thrown by TEve classes and macros.
00423 
00424 ClassImp(TEveException);
00425 
00426 //______________________________________________________________________________
00427 bool operator==(const TString& t, const std::string& s)
00428 { return (s == t.Data()); }
00429 
00430 bool operator==(const std::string&  s, const TString& t)
00431 { return (s == t.Data()); }
00432 
00433 // Exc
00434 
00435 TEveException::TEveException(const std::string& s) : TString(s.c_str())
00436 {
00437    // Constructor.
00438 }
00439 
00440 // Exc + ops
00441 
00442 TEveException operator+(const TEveException &s1, const std::string &s2)
00443 { TEveException r(s1); r += s2; return r; }
00444 
00445 TEveException operator+(const TEveException &s1, const TString &s2)
00446 { TEveException r(s1); r += s2; return r; }
00447 
00448 TEveException operator+(const TEveException &s1,  const char *s2)
00449 { TEveException r(s1); r += s2; return r; }
00450 
00451 
00452 /******************************************************************************/
00453 // TEvePadHolder
00454 /******************************************************************************/
00455 
00456 //______________________________________________________________________________
00457 //
00458 // Exception safe wrapper for setting gPad.
00459 // Optionally calls gPad->Modified()/Update() in destructor.
00460 
00461 ClassImp(TEvePadHolder);
00462 
00463 //______________________________________________________________________________
00464 TEvePadHolder::TEvePadHolder(Bool_t modify_update_p, TVirtualPad* new_pad, Int_t subpad) :
00465    fOldPad        (gPad),
00466    fModifyUpdateP (modify_update_p)
00467 {
00468    // Constructor.
00469 
00470    if (new_pad != 0)
00471       new_pad->cd(subpad);
00472    else
00473       gPad = 0;
00474 }
00475 
00476 //______________________________________________________________________________
00477 TEvePadHolder::~TEvePadHolder()
00478 {
00479    // Destructor.
00480 
00481    if (fModifyUpdateP && gPad != 0) {
00482       gPad->Modified();
00483       gPad->Update();
00484    }
00485    gPad = fOldPad;
00486 }
00487 
00488 
00489 /******************************************************************************/
00490 // TEveGeoManagerHolder
00491 /******************************************************************************/
00492 
00493 //______________________________________________________________________________
00494 //
00495 // Exception safe wrapper for setting gGeoManager.
00496 // Functionality to lock-unlock via setting of a static lock in
00497 // TGeoManager should be added (new feature of TGeoManager).
00498 
00499 ClassImp(TEveGeoManagerHolder);
00500 
00501 //______________________________________________________________________________
00502 TEveGeoManagerHolder::TEveGeoManagerHolder(TGeoManager* new_gmgr, Int_t n_seg) :
00503    fManager   (gGeoManager),
00504    fNSegments (0)
00505 {
00506    // Constructor.
00507    // If n_seg is specified and larger than 2, the new geo-manager's
00508    // NSegments is set to this value.
00509 
00510    gGeoManager = new_gmgr;
00511    if (gGeoManager)
00512    {
00513       gGeoIdentity = (TGeoIdentity*) gGeoManager->GetListOfMatrices()->At(0);
00514       if (n_seg > 2)
00515       {
00516          fNSegments = gGeoManager->GetNsegments();
00517          gGeoManager->SetNsegments(n_seg);
00518       }
00519    }
00520    else
00521    {
00522       gGeoIdentity = 0;
00523    }
00524 }
00525 
00526 //______________________________________________________________________________
00527 TEveGeoManagerHolder::~TEveGeoManagerHolder()
00528 {
00529    // Destructor.
00530 
00531    if (gGeoManager && fNSegments > 2)
00532    {
00533       gGeoManager->SetNsegments(fNSegments);
00534    }
00535    gGeoManager = fManager;
00536    if (gGeoManager)
00537    {
00538       gGeoIdentity = (TGeoIdentity*) gGeoManager->GetListOfMatrices()->At(0);
00539    }
00540    else
00541    {
00542       gGeoIdentity = 0;
00543    }
00544 }
00545 
00546 
00547 /******************************************************************************/
00548 // TEveRefCnt
00549 /******************************************************************************/
00550 
00551 //______________________________________________________________________________
00552 //
00553 // Base-class for reference-counted objects.
00554 // By default the object is destroyed when zero referece-count is reached.
00555 
00556 ClassImp(TEveRefCnt);
00557 
00558 
00559 /******************************************************************************/
00560 // TEveRefBackPtr
00561 /******************************************************************************/
00562 
00563 //______________________________________________________________________________
00564 //
00565 // Base-class for reference-counted objects with reverse references to
00566 // TEveElement objects.
00567 
00568 ClassImp(TEveRefBackPtr);
00569 
00570 //______________________________________________________________________________
00571 TEveRefBackPtr::TEveRefBackPtr() :
00572    TEveRefCnt(),
00573    fBackRefs()
00574 {
00575    // Default constructor.
00576 }
00577 
00578 //______________________________________________________________________________
00579 TEveRefBackPtr::~TEveRefBackPtr()
00580 {
00581    // Destructor. Noop, should complain if back-ref list is not empty.
00582 
00583    // !!! Complain if list not empty.
00584 }
00585 
00586 //______________________________________________________________________________
00587 TEveRefBackPtr::TEveRefBackPtr(const TEveRefBackPtr&) :
00588    TEveRefCnt(),
00589    fBackRefs()
00590 {
00591    // Copy constructor. New copy starts with zero reference count and
00592    // empty back-reference list.
00593 }
00594 
00595 //______________________________________________________________________________
00596 TEveRefBackPtr& TEveRefBackPtr::operator=(const TEveRefBackPtr&)
00597 {
00598    // Assignment operator. Reference count and back-reference
00599    // information is not assigned as these object hold pointers to a
00600    // specific object.
00601 
00602    return *this;
00603 }
00604 
00605 /******************************************************************************/
00606 
00607 //______________________________________________________________________________
00608 void TEveRefBackPtr::IncRefCount(TEveElement* re)
00609 {
00610    // Increase reference cound and add re to the list of back-references.
00611 
00612    TEveRefCnt::IncRefCount();
00613    ++fBackRefs[re];
00614 }
00615 
00616 //______________________________________________________________________________
00617 void TEveRefBackPtr::DecRefCount(TEveElement* re)
00618 {
00619    // Decrease reference cound and remove re from the list of back-references.
00620 
00621    static const TEveException eh("TEveRefBackPtr::DecRefCount ");
00622 
00623    RefMap_i i = fBackRefs.find(re);
00624    if (i != fBackRefs.end()) {
00625       if (--(i->second) <= 0)
00626          fBackRefs.erase(i);
00627       TEveRefCnt::DecRefCount();
00628    } else {
00629       Warning(eh, "render element '%s' not found in back-refs.",
00630                   re->GetObject(eh)->GetName());
00631    }
00632 }
00633 
00634 /******************************************************************************/
00635 
00636 //______________________________________________________________________________
00637 void TEveRefBackPtr::StampBackPtrElements(UChar_t stamps)
00638 {
00639    // Add givem stamps to elements in the list of reverse references.
00640 
00641    RefMap_i i = fBackRefs.begin();
00642    while (i != fBackRefs.end())
00643    {
00644       i->first->AddStamp(stamps);
00645       ++i;
00646    }
00647 }

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