// @(#)root/eve:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TEveUtil.h"
#include "TEveElement.h"
#include "TEveManager.h"

#include "TError.h"
#include "TGeoManager.h"
#include "TGeoMatrix.h"
#include "TClass.h"
#include "TMath.h"

#include "TStyle.h"
#include "TColor.h"

#include "TROOT.h"
#include "TInterpreter.h"
#include "TSystem.h"

#include "TGClient.h"
#include "TGMimeTypes.h"

#include "Riostream.h"

#include <list>
#include <algorithm>
#include <string>

//==============================================================================
// TEveUtil
//==============================================================================

//______________________________________________________________________________
//
// Standard utility functions for Eve.

ClassImp(TEveUtil);

TObjArray* TEveUtil::fgDefaultColors = 0;

//______________________________________________________________________________
void TEveUtil::SetupEnvironment()
{
   // Setup Include and Macro paths.
   // Since inclusion into ROOT this does nothing but could
   // potentially be reactivated if some common macros are established
   // and shipped with binary ROOT (in macros/eve). For example, these
   // might be used to spawn specific GUI / GL configurations.

   static const TEveException eh("TEveUtil::SetupEnvironment");
   static Bool_t setupDone = kFALSE;

   if (setupDone) {
      Info(eh.Data(), "has already been run.");
      return;
   }

   // Old initialization for ALICE.
   // Left as an example.
   /*
   // Check if REVESYS exists, try fallback to $ALICE_ROOT/EVE.
   if(gSystem->Getenv("REVESYS") == 0) {
      if(gSystem->Getenv("ALICE_ROOT") != 0) {
         Info(eh.Data(), "setting REVESYS from ALICE_ROOT.");
         gSystem->Setenv("REVESYS", Form("%s/EVE", gSystem->Getenv("ALICE_ROOT")));
      } else {
         Error(eh.Data(), "REVESYS not defined, neither is ALICE_ROOT.");
         gSystem->Exit(1);
      }
   }
   if(gSystem->AccessPathName(gSystem->Getenv("REVESYS")) == kTRUE) {
      Error(eh.Data(), "REVESYS '%s' does not exist.", gSystem->Getenv("REVESYS"));
      gSystem->Exit(1);
   }

   TString macPath(gROOT->GetMacroPath());
   macPath += Form(":%s/macros", gSystem->Getenv("REVESYS"));
   gInterpreter->AddIncludePath(gSystem->Getenv("REVESYS"));
   if(gSystem->Getenv("ALICE_ROOT") != 0) {
      macPath += Form(":%s/alice-macros", gSystem->Getenv("REVESYS"));
      gInterpreter->AddIncludePath(Form("%s/include", gSystem->Getenv("ALICE_ROOT")));
      gInterpreter->AddIncludePath(gSystem->Getenv("ALICE_ROOT"));
   }
   gROOT->SetMacroPath(macPath);
   */
}

//______________________________________________________________________________
void TEveUtil::SetupGUI()
{
   // Setup icon pictures and mime-types.

   TEveElement::fgRnrIcons[0] = gClient->GetPicture("eve_rnr00_t.xpm");
   TEveElement::fgRnrIcons[1] = gClient->GetPicture("eve_rnr01_t.xpm");
   TEveElement::fgRnrIcons[2] = gClient->GetPicture("eve_rnr10_t.xpm");
   TEveElement::fgRnrIcons[3] = gClient->GetPicture("eve_rnr11_t.xpm");

   TEveElement::fgListTreeIcons[0] = gClient->GetPicture("folder_t.xpm");
   TEveElement::fgListTreeIcons[1] = gClient->GetPicture("eve_viewer.xpm");
   TEveElement::fgListTreeIcons[2] = gClient->GetPicture("eve_scene.xpm");
   TEveElement::fgListTreeIcons[3] = gClient->GetPicture("eve_pointset.xpm");
   TEveElement::fgListTreeIcons[4] = gClient->GetPicture("eve_track.xpm");
   TEveElement::fgListTreeIcons[5] = gClient->GetPicture("eve_text.gif");
   TEveElement::fgListTreeIcons[6] = gClient->GetPicture("eve_axes.xpm");
   TEveElement::fgListTreeIcons[7] = gClient->GetPicture("ofolder_t.xpm");
   TEveElement::fgListTreeIcons[8] = gClient->GetPicture("eve_line.xpm");

   gClient->GetMimeTypeList()->AddType("root/tmacro", "TEveMacro",
                                       "tmacro_s.xpm", "tmacro_t.xpm", "");
}

/******************************************************************************/

namespace
{
//______________________________________________________________________________
void ChompTailAndDir(TString& s, char c='.')
{
   // Remove last part of string 's', starting from the last
   // occurrence of character 'c'.
   // Remove directory part -- everything until the last '/'.

   Ssiz_t p = s.Last(c);
   if (p != kNPOS)
      s.Remove(p);

   Ssiz_t ls = s.Last('/');
   if (ls != kNPOS)
      s.Remove(0, ls + 1);
}
}

//______________________________________________________________________________
Bool_t TEveUtil::CheckMacro(const char* mac)
{
   // Checks if macro 'mac' is loaded.

   // Axel's advice; now sth seems slow, using old method below for test.
   // return gROOT->GetInterpreter()->IsLoaded(mac);

   // Previous version expected function with same name and used ROOT's
   // list of global functions.

   TString foo(mac); ChompTailAndDir(foo);
   if (gROOT->GetGlobalFunction(foo.Data(), 0, kFALSE) != 0)
      return kTRUE;
   else
      return (gROOT->GetGlobalFunction(foo.Data(), 0, kTRUE) != 0);
}

//______________________________________________________________________________
void TEveUtil::AssertMacro(const char* mac)
{
   // Load and execute macro 'mac' if it has not been loaded yet.

   if( CheckMacro(mac) == kFALSE) {
      gROOT->Macro(mac);
   }
}

//______________________________________________________________________________
void TEveUtil::Macro(const char* mac)
{
   // Execute macro 'mac'. Do not reload the macro.

   if (CheckMacro(mac) == kFALSE) {
      gROOT->LoadMacro(mac);
   }
   TString foo(mac); ChompTailAndDir(foo); foo += "()";
   gROOT->ProcessLine(foo.Data());
}

//______________________________________________________________________________
void TEveUtil::LoadMacro(const char* mac)
{
   // Makes sure that macro 'mac' is loaded, but do not reload it.

   if (CheckMacro(mac) == kFALSE) {
      gROOT->LoadMacro(mac);
   }
}

/******************************************************************************/
// Color management
/******************************************************************************/

//______________________________________________________________________________
void TEveUtil::ColorFromIdx(Color_t ci, UChar_t col[4], Bool_t alpha)
{
   // Fill col with RGBA values corresponding to index ci. If alpha
   // is true, set alpha component of col to 255.
   // ROOT's indexed color palette does not support transparency.

   TColor* c = gROOT->GetColor(ci);
   if (c)
   {
      col[0] = (UChar_t)(255*c->GetRed());
      col[1] = (UChar_t)(255*c->GetGreen());
      col[2] = (UChar_t)(255*c->GetBlue());
      if (alpha) col[3] = 255;
   }
   else
   {
      // Set to magenta.
      col[0] = 255; col[1] = 0; col[2] = 255;
      if (alpha) col[3] = 255;
      return;
   }
}

//______________________________________________________________________________
void TEveUtil::ColorFromIdx(Color_t ci, UChar_t col[4], Char_t transparency)
{
   // Fill col with RGBA values corresponding to index ci and transparency.
   // ROOT's indexed color palette does not support transparency.

   UChar_t alpha = (255*(100 - transparency))/100;

   TColor* c = gROOT->GetColor(ci);
   if (c)
   {
      col[0] = (UChar_t)(255*c->GetRed());
      col[1] = (UChar_t)(255*c->GetGreen());
      col[2] = (UChar_t)(255*c->GetBlue());
      col[3] = alpha;
   }
   else
   {
      // Set to magenta.
      col[0] = 255; col[1] = 0; col[2] = 255; col[3] = alpha;
      return;
   }
}

//______________________________________________________________________________
void TEveUtil::ColorFromIdx(Float_t f1, Color_t c1, Float_t f2, Color_t c2,
			    UChar_t col[4], Bool_t alpha)
{
   // Fill col with weighted RGBA values corresponding to
   // color-indices c1 and c2. If alpha is true, set alpha component
   // of col to 255.

   TColor* t1 = gROOT->GetColor(c1);
   TColor* t2 = gROOT->GetColor(c2);
   if(t1 && t2) {
      col[0] = (UChar_t)(255*(f1*t1->GetRed()   + f2*t2->GetRed()));
      col[1] = (UChar_t)(255*(f1*t1->GetGreen() + f2*t2->GetGreen()));
      col[2] = (UChar_t)(255*(f1*t1->GetBlue()  + f2*t2->GetBlue()));
      if (alpha) col[3] = 255;
   }
}

//______________________________________________________________________________
Color_t* TEveUtil::FindColorVar(TObject* obj, const char* varname)
{
   // Find address of Color_t data-member with name varname in object
   // obj.
   //
   // This is used to access color information for TGListTreeItem
   // coloration from visualization macros that wrap TObjects into
   // TEveElementObjectPtr instances.

   static const TEveException eh("TEveUtil::FindColorVar");

   Int_t off = obj->IsA()->GetDataMemberOffset(varname);
   if(off == 0)
      throw(eh + "could not find member '" + varname + "' in class " + obj->IsA()->GetName() + ".");
   return (Color_t*) (((char*)obj) + off);
}

//______________________________________________________________________________
void TEveUtil::SetColorBrightness(Float_t value, Bool_t full_redraw)
{
   // Tweak all ROOT colors to become brighter (if value > 0) or
   // darker (value < 0). Reasonable values for the value argument are
   // from -2.5 to 2.5 (error will be printed otherwise).
   // If value is zero, the original colors are restored.
   //
   // You should call TEveManager::FullRedraw3D() afterwards or set
   // the argument full_redraw to true (default is false).

   if (value < -2.5 || value > 2.5)
   {
      Error("TEveUtil::SetColorBrightness", "value '%f' out of range [-0.5, 0.5].", value);
      return;
   }

   TObjArray   *colors = (TObjArray*) gROOT->GetListOfColors();

   if (fgDefaultColors == 0)
   {
      const Int_t n_col = colors->GetEntriesFast();
      fgDefaultColors = new TObjArray(n_col);
      for (Int_t i = 0; i < n_col; ++i)
      {
         TColor* c = (TColor*) colors->At(i);
         if (c)
            fgDefaultColors->AddAt(new TColor(*c), i);
      }
   }

   const Int_t n_col = fgDefaultColors->GetEntriesFast();
   for (Int_t i = 0; i < n_col; ++i)
   {
      TColor* cdef = (TColor*) fgDefaultColors->At(i);
      if (cdef)
      {
         TColor* croot = (TColor*)  colors->At(i);
         if (croot == 0)
         {
            croot = new TColor(*cdef);
            colors->AddAt(croot, i);
         }
         else
         {
            cdef->Copy(*croot);
         }

         Float_t r, g, b;
         croot->GetRGB(r, g, b);
         r = TMath::Power( r, (2.5 - value)/2.5);
         g = TMath::Power(g, (2.5 - value)/2.5);
         b = TMath::Power(b, (2.5 - value)/2.5);

         r = TMath::Min(r, 1.0f);
         g = TMath::Min(g, 1.0f);
         b = TMath::Min(b, 1.0f);

         croot->SetRGB(r, g, b);
      }
      else
      {
         delete colors->RemoveAt(i);
      }
   }

   if (full_redraw && gEve != 0)
      gEve->FullRedraw3D();
}

/******************************************************************************/
// Math utilities
/******************************************************************************/

//______________________________________________________________________________
Bool_t TEveUtil::IsU1IntervalContainedByMinMax(Float_t minM, Float_t maxM,
                                               Float_t minQ, Float_t maxQ)
{
   // Return true if interval Q is contained within interval M for U1 variables.
   // It is assumed that all values are within the [-2pi, 2pi] interval and
   // minM <= maxM & minQ <= maxQ.

   using namespace TMath;

   if (maxQ < minM)
   {
      minQ += TwoPi(); maxQ += TwoPi();
   }
   else if (minQ > maxM)
   {
      minQ -= TwoPi(); maxQ -= TwoPi();
   }
   return minQ >= minM && maxQ <= maxM;
}

//______________________________________________________________________________
Bool_t TEveUtil::IsU1IntervalOverlappingByMinMax(Float_t minM, Float_t maxM,
                                                 Float_t minQ, Float_t maxQ)
{
   // Return true if interval Q is overlapping within interval M for U1 variables.
   // It is assumed that all values are within the [-2pi, 2pi] interval and
   // minM <= maxM & minQ <= maxQ.

   using namespace TMath;

   if (maxQ < minM)
   {
      minQ += TwoPi(); maxQ += TwoPi();
   }
   else if (minQ > maxM)
   {
      minQ -= TwoPi(); maxQ -= TwoPi();
   }
   return maxQ >= minM && minQ <= maxM;
}

//______________________________________________________________________________
Float_t TEveUtil::GetFraction(Float_t minM, Float_t maxM, Float_t minQ, Float_t maxQ)
{
   // Get fraction of interval [minQ, maxQ] in [minM, maxM]

   if (minQ>=minM && maxQ<=maxM)
      return 1;

   else if (minQ<minM && maxQ>maxM)
      return (maxM-minM)/(maxQ-minQ);

   else if (minQ>=minM && maxQ>maxM)
      return (maxM-minQ)/(maxQ-minQ);

   else if (minQ<minM && maxQ<=maxM)
      return (maxQ-minM)/(maxQ-minQ);

   return 0;
}

/******************************************************************************/
// TEveException
/******************************************************************************/

//______________________________________________________________________________
//
// Exception class thrown by TEve classes and macros.

ClassImp(TEveException);

//______________________________________________________________________________
bool operator==(const TString& t, const std::string& s)
{ return (s == t.Data()); }

bool operator==(const std::string&  s, const TString& t)
{ return (s == t.Data()); }

// Exc

TEveException::TEveException(const std::string& s) : TString(s.c_str())
{
   // Constructor.
}

// Exc + ops

TEveException operator+(const TEveException &s1, const std::string &s2)
{ TEveException r(s1); r += s2; return r; }

TEveException operator+(const TEveException &s1, const TString &s2)
{ TEveException r(s1); r += s2; return r; }

TEveException operator+(const TEveException &s1,  const char *s2)
{ TEveException r(s1); r += s2; return r; }


/******************************************************************************/
// TEvePadHolder
/******************************************************************************/

//______________________________________________________________________________
//
// Exception safe wrapper for setting gPad.
// Optionally calls gPad->Modified()/Update() in destructor.

ClassImp(TEvePadHolder);

//______________________________________________________________________________
TEvePadHolder::TEvePadHolder(Bool_t modify_update_p, TVirtualPad* new_pad, Int_t subpad) :
   fOldPad        (gPad),
   fModifyUpdateP (modify_update_p)
{
   // Constructor.

   if (new_pad != 0)
      new_pad->cd(subpad);
   else
      gPad = 0;
}

//______________________________________________________________________________
TEvePadHolder::~TEvePadHolder()
{
   // Destructor.

   if (fModifyUpdateP && gPad != 0) {
      gPad->Modified();
      gPad->Update();
   }
   gPad = fOldPad;
}


/******************************************************************************/
// TEveGeoManagerHolder
/******************************************************************************/

//______________________________________________________________________________
//
// Exception safe wrapper for setting gGeoManager.
// Functionality to lock-unlock via setting of a static lock in
// TGeoManager should be added (new feature of TGeoManager).

ClassImp(TEveGeoManagerHolder);

//______________________________________________________________________________
TEveGeoManagerHolder::TEveGeoManagerHolder(TGeoManager* new_gmgr, Int_t n_seg) :
   fManager   (gGeoManager),
   fNSegments (0)
{
   // Constructor.
   // If n_seg is specified and larger than 2, the new geo-manager's
   // NSegments is set to this value.

   gGeoManager = new_gmgr;
   if (gGeoManager)
   {
      gGeoIdentity = (TGeoIdentity*) gGeoManager->GetListOfMatrices()->At(0);
      if (n_seg > 2)
      {
         fNSegments = gGeoManager->GetNsegments();
         gGeoManager->SetNsegments(n_seg);
      }
   }
   else
   {
      gGeoIdentity = 0;
   }
}

//______________________________________________________________________________
TEveGeoManagerHolder::~TEveGeoManagerHolder()
{
   // Destructor.

   if (gGeoManager && fNSegments > 2)
   {
      gGeoManager->SetNsegments(fNSegments);
   }
   gGeoManager = fManager;
   if (gGeoManager)
   {
      gGeoIdentity = (TGeoIdentity*) gGeoManager->GetListOfMatrices()->At(0);
   }
   else
   {
      gGeoIdentity = 0;
   }
}


/******************************************************************************/
// TEveRefCnt
/******************************************************************************/

//______________________________________________________________________________
//
// Base-class for reference-counted objects.
// By default the object is destroyed when zero referece-count is reached.

ClassImp(TEveRefCnt);


/******************************************************************************/
// TEveRefBackPtr
/******************************************************************************/

//______________________________________________________________________________
//
// Base-class for reference-counted objects with reverse references to
// TEveElement objects.

ClassImp(TEveRefBackPtr);

//______________________________________________________________________________
TEveRefBackPtr::TEveRefBackPtr() :
   TEveRefCnt(),
   fBackRefs()
{
   // Default constructor.
}

//______________________________________________________________________________
TEveRefBackPtr::~TEveRefBackPtr()
{
   // Destructor. Noop, should complain if back-ref list is not empty.

   // !!! Complain if list not empty.
}

//______________________________________________________________________________
TEveRefBackPtr::TEveRefBackPtr(const TEveRefBackPtr&) :
   TEveRefCnt(),
   fBackRefs()
{
   // Copy constructor. New copy starts with zero reference count and
   // empty back-reference list.
}

//______________________________________________________________________________
TEveRefBackPtr& TEveRefBackPtr::operator=(const TEveRefBackPtr&)
{
   // Assignment operator. Reference count and back-reference
   // information is not assigned as these object hold pointers to a
   // specific object.

   return *this;
}

/******************************************************************************/

//______________________________________________________________________________
void TEveRefBackPtr::IncRefCount(TEveElement* re)
{
   // Increase reference cound and add re to the list of back-references.

   TEveRefCnt::IncRefCount();
   ++fBackRefs[re];
}

//______________________________________________________________________________
void TEveRefBackPtr::DecRefCount(TEveElement* re)
{
   // Decrease reference cound and remove re from the list of back-references.

   static const TEveException eh("TEveRefBackPtr::DecRefCount ");

   RefMap_i i = fBackRefs.find(re);
   if (i != fBackRefs.end()) {
      if (--(i->second) <= 0)
         fBackRefs.erase(i);
      TEveRefCnt::DecRefCount();
   } else {
      Warning(eh, "render element '%s' not found in back-refs.",
                  re->GetObject(eh)->GetName());
   }
}

/******************************************************************************/

//______________________________________________________________________________
void TEveRefBackPtr::StampBackPtrElements(UChar_t stamps)
{
   // Add givem stamps to elements in the list of reverse references.

   RefMap_i i = fBackRefs.begin();
   while (i != fBackRefs.end())
   {
      i->first->AddStamp(stamps);
      ++i;
   }
}
 TEveUtil.cxx:1
 TEveUtil.cxx:2
 TEveUtil.cxx:3
 TEveUtil.cxx:4
 TEveUtil.cxx:5
 TEveUtil.cxx:6
 TEveUtil.cxx:7
 TEveUtil.cxx:8
 TEveUtil.cxx:9
 TEveUtil.cxx:10
 TEveUtil.cxx:11
 TEveUtil.cxx:12
 TEveUtil.cxx:13
 TEveUtil.cxx:14
 TEveUtil.cxx:15
 TEveUtil.cxx:16
 TEveUtil.cxx:17
 TEveUtil.cxx:18
 TEveUtil.cxx:19
 TEveUtil.cxx:20
 TEveUtil.cxx:21
 TEveUtil.cxx:22
 TEveUtil.cxx:23
 TEveUtil.cxx:24
 TEveUtil.cxx:25
 TEveUtil.cxx:26
 TEveUtil.cxx:27
 TEveUtil.cxx:28
 TEveUtil.cxx:29
 TEveUtil.cxx:30
 TEveUtil.cxx:31
 TEveUtil.cxx:32
 TEveUtil.cxx:33
 TEveUtil.cxx:34
 TEveUtil.cxx:35
 TEveUtil.cxx:36
 TEveUtil.cxx:37
 TEveUtil.cxx:38
 TEveUtil.cxx:39
 TEveUtil.cxx:40
 TEveUtil.cxx:41
 TEveUtil.cxx:42
 TEveUtil.cxx:43
 TEveUtil.cxx:44
 TEveUtil.cxx:45
 TEveUtil.cxx:46
 TEveUtil.cxx:47
 TEveUtil.cxx:48
 TEveUtil.cxx:49
 TEveUtil.cxx:50
 TEveUtil.cxx:51
 TEveUtil.cxx:52
 TEveUtil.cxx:53
 TEveUtil.cxx:54
 TEveUtil.cxx:55
 TEveUtil.cxx:56
 TEveUtil.cxx:57
 TEveUtil.cxx:58
 TEveUtil.cxx:59
 TEveUtil.cxx:60
 TEveUtil.cxx:61
 TEveUtil.cxx:62
 TEveUtil.cxx:63
 TEveUtil.cxx:64
 TEveUtil.cxx:65
 TEveUtil.cxx:66
 TEveUtil.cxx:67
 TEveUtil.cxx:68
 TEveUtil.cxx:69
 TEveUtil.cxx:70
 TEveUtil.cxx:71
 TEveUtil.cxx:72
 TEveUtil.cxx:73
 TEveUtil.cxx:74
 TEveUtil.cxx:75
 TEveUtil.cxx:76
 TEveUtil.cxx:77
 TEveUtil.cxx:78
 TEveUtil.cxx:79
 TEveUtil.cxx:80
 TEveUtil.cxx:81
 TEveUtil.cxx:82
 TEveUtil.cxx:83
 TEveUtil.cxx:84
 TEveUtil.cxx:85
 TEveUtil.cxx:86
 TEveUtil.cxx:87
 TEveUtil.cxx:88
 TEveUtil.cxx:89
 TEveUtil.cxx:90
 TEveUtil.cxx:91
 TEveUtil.cxx:92
 TEveUtil.cxx:93
 TEveUtil.cxx:94
 TEveUtil.cxx:95
 TEveUtil.cxx:96
 TEveUtil.cxx:97
 TEveUtil.cxx:98
 TEveUtil.cxx:99
 TEveUtil.cxx:100
 TEveUtil.cxx:101
 TEveUtil.cxx:102
 TEveUtil.cxx:103
 TEveUtil.cxx:104
 TEveUtil.cxx:105
 TEveUtil.cxx:106
 TEveUtil.cxx:107
 TEveUtil.cxx:108
 TEveUtil.cxx:109
 TEveUtil.cxx:110
 TEveUtil.cxx:111
 TEveUtil.cxx:112
 TEveUtil.cxx:113
 TEveUtil.cxx:114
 TEveUtil.cxx:115
 TEveUtil.cxx:116
 TEveUtil.cxx:117
 TEveUtil.cxx:118
 TEveUtil.cxx:119
 TEveUtil.cxx:120
 TEveUtil.cxx:121
 TEveUtil.cxx:122
 TEveUtil.cxx:123
 TEveUtil.cxx:124
 TEveUtil.cxx:125
 TEveUtil.cxx:126
 TEveUtil.cxx:127
 TEveUtil.cxx:128
 TEveUtil.cxx:129
 TEveUtil.cxx:130
 TEveUtil.cxx:131
 TEveUtil.cxx:132
 TEveUtil.cxx:133
 TEveUtil.cxx:134
 TEveUtil.cxx:135
 TEveUtil.cxx:136
 TEveUtil.cxx:137
 TEveUtil.cxx:138
 TEveUtil.cxx:139
 TEveUtil.cxx:140
 TEveUtil.cxx:141
 TEveUtil.cxx:142
 TEveUtil.cxx:143
 TEveUtil.cxx:144
 TEveUtil.cxx:145
 TEveUtil.cxx:146
 TEveUtil.cxx:147
 TEveUtil.cxx:148
 TEveUtil.cxx:149
 TEveUtil.cxx:150
 TEveUtil.cxx:151
 TEveUtil.cxx:152
 TEveUtil.cxx:153
 TEveUtil.cxx:154
 TEveUtil.cxx:155
 TEveUtil.cxx:156
 TEveUtil.cxx:157
 TEveUtil.cxx:158
 TEveUtil.cxx:159
 TEveUtil.cxx:160
 TEveUtil.cxx:161
 TEveUtil.cxx:162
 TEveUtil.cxx:163
 TEveUtil.cxx:164
 TEveUtil.cxx:165
 TEveUtil.cxx:166
 TEveUtil.cxx:167
 TEveUtil.cxx:168
 TEveUtil.cxx:169
 TEveUtil.cxx:170
 TEveUtil.cxx:171
 TEveUtil.cxx:172
 TEveUtil.cxx:173
 TEveUtil.cxx:174
 TEveUtil.cxx:175
 TEveUtil.cxx:176
 TEveUtil.cxx:177
 TEveUtil.cxx:178
 TEveUtil.cxx:179
 TEveUtil.cxx:180
 TEveUtil.cxx:181
 TEveUtil.cxx:182
 TEveUtil.cxx:183
 TEveUtil.cxx:184
 TEveUtil.cxx:185
 TEveUtil.cxx:186
 TEveUtil.cxx:187
 TEveUtil.cxx:188
 TEveUtil.cxx:189
 TEveUtil.cxx:190
 TEveUtil.cxx:191
 TEveUtil.cxx:192
 TEveUtil.cxx:193
 TEveUtil.cxx:194
 TEveUtil.cxx:195
 TEveUtil.cxx:196
 TEveUtil.cxx:197
 TEveUtil.cxx:198
 TEveUtil.cxx:199
 TEveUtil.cxx:200
 TEveUtil.cxx:201
 TEveUtil.cxx:202
 TEveUtil.cxx:203
 TEveUtil.cxx:204
 TEveUtil.cxx:205
 TEveUtil.cxx:206
 TEveUtil.cxx:207
 TEveUtil.cxx:208
 TEveUtil.cxx:209
 TEveUtil.cxx:210
 TEveUtil.cxx:211
 TEveUtil.cxx:212
 TEveUtil.cxx:213
 TEveUtil.cxx:214
 TEveUtil.cxx:215
 TEveUtil.cxx:216
 TEveUtil.cxx:217
 TEveUtil.cxx:218
 TEveUtil.cxx:219
 TEveUtil.cxx:220
 TEveUtil.cxx:221
 TEveUtil.cxx:222
 TEveUtil.cxx:223
 TEveUtil.cxx:224
 TEveUtil.cxx:225
 TEveUtil.cxx:226
 TEveUtil.cxx:227
 TEveUtil.cxx:228
 TEveUtil.cxx:229
 TEveUtil.cxx:230
 TEveUtil.cxx:231
 TEveUtil.cxx:232
 TEveUtil.cxx:233
 TEveUtil.cxx:234
 TEveUtil.cxx:235
 TEveUtil.cxx:236
 TEveUtil.cxx:237
 TEveUtil.cxx:238
 TEveUtil.cxx:239
 TEveUtil.cxx:240
 TEveUtil.cxx:241
 TEveUtil.cxx:242
 TEveUtil.cxx:243
 TEveUtil.cxx:244
 TEveUtil.cxx:245
 TEveUtil.cxx:246
 TEveUtil.cxx:247
 TEveUtil.cxx:248
 TEveUtil.cxx:249
 TEveUtil.cxx:250
 TEveUtil.cxx:251
 TEveUtil.cxx:252
 TEveUtil.cxx:253
 TEveUtil.cxx:254
 TEveUtil.cxx:255
 TEveUtil.cxx:256
 TEveUtil.cxx:257
 TEveUtil.cxx:258
 TEveUtil.cxx:259
 TEveUtil.cxx:260
 TEveUtil.cxx:261
 TEveUtil.cxx:262
 TEveUtil.cxx:263
 TEveUtil.cxx:264
 TEveUtil.cxx:265
 TEveUtil.cxx:266
 TEveUtil.cxx:267
 TEveUtil.cxx:268
 TEveUtil.cxx:269
 TEveUtil.cxx:270
 TEveUtil.cxx:271
 TEveUtil.cxx:272
 TEveUtil.cxx:273
 TEveUtil.cxx:274
 TEveUtil.cxx:275
 TEveUtil.cxx:276
 TEveUtil.cxx:277
 TEveUtil.cxx:278
 TEveUtil.cxx:279
 TEveUtil.cxx:280
 TEveUtil.cxx:281
 TEveUtil.cxx:282
 TEveUtil.cxx:283
 TEveUtil.cxx:284
 TEveUtil.cxx:285
 TEveUtil.cxx:286
 TEveUtil.cxx:287
 TEveUtil.cxx:288
 TEveUtil.cxx:289
 TEveUtil.cxx:290
 TEveUtil.cxx:291
 TEveUtil.cxx:292
 TEveUtil.cxx:293
 TEveUtil.cxx:294
 TEveUtil.cxx:295
 TEveUtil.cxx:296
 TEveUtil.cxx:297
 TEveUtil.cxx:298
 TEveUtil.cxx:299
 TEveUtil.cxx:300
 TEveUtil.cxx:301
 TEveUtil.cxx:302
 TEveUtil.cxx:303
 TEveUtil.cxx:304
 TEveUtil.cxx:305
 TEveUtil.cxx:306
 TEveUtil.cxx:307
 TEveUtil.cxx:308
 TEveUtil.cxx:309
 TEveUtil.cxx:310
 TEveUtil.cxx:311
 TEveUtil.cxx:312
 TEveUtil.cxx:313
 TEveUtil.cxx:314
 TEveUtil.cxx:315
 TEveUtil.cxx:316
 TEveUtil.cxx:317
 TEveUtil.cxx:318
 TEveUtil.cxx:319
 TEveUtil.cxx:320
 TEveUtil.cxx:321
 TEveUtil.cxx:322
 TEveUtil.cxx:323
 TEveUtil.cxx:324
 TEveUtil.cxx:325
 TEveUtil.cxx:326
 TEveUtil.cxx:327
 TEveUtil.cxx:328
 TEveUtil.cxx:329
 TEveUtil.cxx:330
 TEveUtil.cxx:331
 TEveUtil.cxx:332
 TEveUtil.cxx:333
 TEveUtil.cxx:334
 TEveUtil.cxx:335
 TEveUtil.cxx:336
 TEveUtil.cxx:337
 TEveUtil.cxx:338
 TEveUtil.cxx:339
 TEveUtil.cxx:340
 TEveUtil.cxx:341
 TEveUtil.cxx:342
 TEveUtil.cxx:343
 TEveUtil.cxx:344
 TEveUtil.cxx:345
 TEveUtil.cxx:346
 TEveUtil.cxx:347
 TEveUtil.cxx:348
 TEveUtil.cxx:349
 TEveUtil.cxx:350
 TEveUtil.cxx:351
 TEveUtil.cxx:352
 TEveUtil.cxx:353
 TEveUtil.cxx:354
 TEveUtil.cxx:355
 TEveUtil.cxx:356
 TEveUtil.cxx:357
 TEveUtil.cxx:358
 TEveUtil.cxx:359
 TEveUtil.cxx:360
 TEveUtil.cxx:361
 TEveUtil.cxx:362
 TEveUtil.cxx:363
 TEveUtil.cxx:364
 TEveUtil.cxx:365
 TEveUtil.cxx:366
 TEveUtil.cxx:367
 TEveUtil.cxx:368
 TEveUtil.cxx:369
 TEveUtil.cxx:370
 TEveUtil.cxx:371
 TEveUtil.cxx:372
 TEveUtil.cxx:373
 TEveUtil.cxx:374
 TEveUtil.cxx:375
 TEveUtil.cxx:376
 TEveUtil.cxx:377
 TEveUtil.cxx:378
 TEveUtil.cxx:379
 TEveUtil.cxx:380
 TEveUtil.cxx:381
 TEveUtil.cxx:382
 TEveUtil.cxx:383
 TEveUtil.cxx:384
 TEveUtil.cxx:385
 TEveUtil.cxx:386
 TEveUtil.cxx:387
 TEveUtil.cxx:388
 TEveUtil.cxx:389
 TEveUtil.cxx:390
 TEveUtil.cxx:391
 TEveUtil.cxx:392
 TEveUtil.cxx:393
 TEveUtil.cxx:394
 TEveUtil.cxx:395
 TEveUtil.cxx:396
 TEveUtil.cxx:397
 TEveUtil.cxx:398
 TEveUtil.cxx:399
 TEveUtil.cxx:400
 TEveUtil.cxx:401
 TEveUtil.cxx:402
 TEveUtil.cxx:403
 TEveUtil.cxx:404
 TEveUtil.cxx:405
 TEveUtil.cxx:406
 TEveUtil.cxx:407
 TEveUtil.cxx:408
 TEveUtil.cxx:409
 TEveUtil.cxx:410
 TEveUtil.cxx:411
 TEveUtil.cxx:412
 TEveUtil.cxx:413
 TEveUtil.cxx:414
 TEveUtil.cxx:415
 TEveUtil.cxx:416
 TEveUtil.cxx:417
 TEveUtil.cxx:418
 TEveUtil.cxx:419
 TEveUtil.cxx:420
 TEveUtil.cxx:421
 TEveUtil.cxx:422
 TEveUtil.cxx:423
 TEveUtil.cxx:424
 TEveUtil.cxx:425
 TEveUtil.cxx:426
 TEveUtil.cxx:427
 TEveUtil.cxx:428
 TEveUtil.cxx:429
 TEveUtil.cxx:430
 TEveUtil.cxx:431
 TEveUtil.cxx:432
 TEveUtil.cxx:433
 TEveUtil.cxx:434
 TEveUtil.cxx:435
 TEveUtil.cxx:436
 TEveUtil.cxx:437
 TEveUtil.cxx:438
 TEveUtil.cxx:439
 TEveUtil.cxx:440
 TEveUtil.cxx:441
 TEveUtil.cxx:442
 TEveUtil.cxx:443
 TEveUtil.cxx:444
 TEveUtil.cxx:445
 TEveUtil.cxx:446
 TEveUtil.cxx:447
 TEveUtil.cxx:448
 TEveUtil.cxx:449
 TEveUtil.cxx:450
 TEveUtil.cxx:451
 TEveUtil.cxx:452
 TEveUtil.cxx:453
 TEveUtil.cxx:454
 TEveUtil.cxx:455
 TEveUtil.cxx:456
 TEveUtil.cxx:457
 TEveUtil.cxx:458
 TEveUtil.cxx:459
 TEveUtil.cxx:460
 TEveUtil.cxx:461
 TEveUtil.cxx:462
 TEveUtil.cxx:463
 TEveUtil.cxx:464
 TEveUtil.cxx:465
 TEveUtil.cxx:466
 TEveUtil.cxx:467
 TEveUtil.cxx:468
 TEveUtil.cxx:469
 TEveUtil.cxx:470
 TEveUtil.cxx:471
 TEveUtil.cxx:472
 TEveUtil.cxx:473
 TEveUtil.cxx:474
 TEveUtil.cxx:475
 TEveUtil.cxx:476
 TEveUtil.cxx:477
 TEveUtil.cxx:478
 TEveUtil.cxx:479
 TEveUtil.cxx:480
 TEveUtil.cxx:481
 TEveUtil.cxx:482
 TEveUtil.cxx:483
 TEveUtil.cxx:484
 TEveUtil.cxx:485
 TEveUtil.cxx:486
 TEveUtil.cxx:487
 TEveUtil.cxx:488
 TEveUtil.cxx:489
 TEveUtil.cxx:490
 TEveUtil.cxx:491
 TEveUtil.cxx:492
 TEveUtil.cxx:493
 TEveUtil.cxx:494
 TEveUtil.cxx:495
 TEveUtil.cxx:496
 TEveUtil.cxx:497
 TEveUtil.cxx:498
 TEveUtil.cxx:499
 TEveUtil.cxx:500
 TEveUtil.cxx:501
 TEveUtil.cxx:502
 TEveUtil.cxx:503
 TEveUtil.cxx:504
 TEveUtil.cxx:505
 TEveUtil.cxx:506
 TEveUtil.cxx:507
 TEveUtil.cxx:508
 TEveUtil.cxx:509
 TEveUtil.cxx:510
 TEveUtil.cxx:511
 TEveUtil.cxx:512
 TEveUtil.cxx:513
 TEveUtil.cxx:514
 TEveUtil.cxx:515
 TEveUtil.cxx:516
 TEveUtil.cxx:517
 TEveUtil.cxx:518
 TEveUtil.cxx:519
 TEveUtil.cxx:520
 TEveUtil.cxx:521
 TEveUtil.cxx:522
 TEveUtil.cxx:523
 TEveUtil.cxx:524
 TEveUtil.cxx:525
 TEveUtil.cxx:526
 TEveUtil.cxx:527
 TEveUtil.cxx:528
 TEveUtil.cxx:529
 TEveUtil.cxx:530
 TEveUtil.cxx:531
 TEveUtil.cxx:532
 TEveUtil.cxx:533
 TEveUtil.cxx:534
 TEveUtil.cxx:535
 TEveUtil.cxx:536
 TEveUtil.cxx:537
 TEveUtil.cxx:538
 TEveUtil.cxx:539
 TEveUtil.cxx:540
 TEveUtil.cxx:541
 TEveUtil.cxx:542
 TEveUtil.cxx:543
 TEveUtil.cxx:544
 TEveUtil.cxx:545
 TEveUtil.cxx:546
 TEveUtil.cxx:547
 TEveUtil.cxx:548
 TEveUtil.cxx:549
 TEveUtil.cxx:550
 TEveUtil.cxx:551
 TEveUtil.cxx:552
 TEveUtil.cxx:553
 TEveUtil.cxx:554
 TEveUtil.cxx:555
 TEveUtil.cxx:556
 TEveUtil.cxx:557
 TEveUtil.cxx:558
 TEveUtil.cxx:559
 TEveUtil.cxx:560
 TEveUtil.cxx:561
 TEveUtil.cxx:562
 TEveUtil.cxx:563
 TEveUtil.cxx:564
 TEveUtil.cxx:565
 TEveUtil.cxx:566
 TEveUtil.cxx:567
 TEveUtil.cxx:568
 TEveUtil.cxx:569
 TEveUtil.cxx:570
 TEveUtil.cxx:571
 TEveUtil.cxx:572
 TEveUtil.cxx:573
 TEveUtil.cxx:574
 TEveUtil.cxx:575
 TEveUtil.cxx:576
 TEveUtil.cxx:577
 TEveUtil.cxx:578
 TEveUtil.cxx:579
 TEveUtil.cxx:580
 TEveUtil.cxx:581
 TEveUtil.cxx:582
 TEveUtil.cxx:583
 TEveUtil.cxx:584
 TEveUtil.cxx:585
 TEveUtil.cxx:586
 TEveUtil.cxx:587
 TEveUtil.cxx:588
 TEveUtil.cxx:589
 TEveUtil.cxx:590
 TEveUtil.cxx:591
 TEveUtil.cxx:592
 TEveUtil.cxx:593
 TEveUtil.cxx:594
 TEveUtil.cxx:595
 TEveUtil.cxx:596
 TEveUtil.cxx:597
 TEveUtil.cxx:598
 TEveUtil.cxx:599
 TEveUtil.cxx:600
 TEveUtil.cxx:601
 TEveUtil.cxx:602
 TEveUtil.cxx:603
 TEveUtil.cxx:604
 TEveUtil.cxx:605
 TEveUtil.cxx:606
 TEveUtil.cxx:607
 TEveUtil.cxx:608
 TEveUtil.cxx:609
 TEveUtil.cxx:610
 TEveUtil.cxx:611
 TEveUtil.cxx:612
 TEveUtil.cxx:613
 TEveUtil.cxx:614
 TEveUtil.cxx:615
 TEveUtil.cxx:616
 TEveUtil.cxx:617
 TEveUtil.cxx:618
 TEveUtil.cxx:619
 TEveUtil.cxx:620
 TEveUtil.cxx:621
 TEveUtil.cxx:622
 TEveUtil.cxx:623
 TEveUtil.cxx:624
 TEveUtil.cxx:625
 TEveUtil.cxx:626
 TEveUtil.cxx:627
 TEveUtil.cxx:628
 TEveUtil.cxx:629
 TEveUtil.cxx:630
 TEveUtil.cxx:631
 TEveUtil.cxx:632
 TEveUtil.cxx:633
 TEveUtil.cxx:634
 TEveUtil.cxx:635
 TEveUtil.cxx:636
 TEveUtil.cxx:637
 TEveUtil.cxx:638
 TEveUtil.cxx:639
 TEveUtil.cxx:640
 TEveUtil.cxx:641
 TEveUtil.cxx:642
 TEveUtil.cxx:643
 TEveUtil.cxx:644
 TEveUtil.cxx:645
 TEveUtil.cxx:646
 TEveUtil.cxx:647