ROOT logo
// @(#)root/gl:$Id: TGLScene.cxx 28197 2009-04-14 13:59:27Z matevz $
// Author:  Matevz Tadel, Feb 2007
// Author:  Richard Maunder  25/05/2005
// Parts taken from original TGLRender by Timur Pocheptsov

/*************************************************************************
 * Copyright (C) 1995-2004, 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 "TGLScene.h"
#include "TGLRnrCtx.h"
#include "TGLObject.h"
#include "TGLSelectRecord.h"
#include "TGLLogicalShape.h"
#include "TGLPhysicalShape.h"
#include "TGLCamera.h"
#include "TGLContext.h"
#include "TGLIncludes.h"

#include <TColor.h>
#include <TROOT.h>
#include <TClass.h>

#include <algorithm>

//==============================================================================
// TGLScene::TSceneInfo
//==============================================================================

//______________________________________________________________________
//
// Extend TGLSceneInfo for needs of TGLScene:
//
// 1. DrawElement vectors for opaque/transparent shapes which cache
// physicals that pass the clip tests (frustum and additional
// clip-object);
//
// 2. Statistics / debug information
//

//______________________________________________________________________________
TGLScene::TSceneInfo::TSceneInfo(TGLViewerBase* view, TGLScene* scene) :
   TGLSceneInfo (view, scene),
   fMinorStamp  (0),
   fOpaqueCnt   (0),
   fTranspCnt   (0),
   fAsPixelCnt  (0)
{
   // Constructor.
}

//______________________________________________________________________________
TGLScene::TSceneInfo::~TSceneInfo()
{
   // Destructor.
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::ClearDrawElementVec(DrawElementVec_t& vec,
                                               Int_t maxSize)
{
   // Clear given vec and if it grew too large compared to the size of
   // shape-of-interest also resize it.

   if (vec.capacity() > (size_t) maxSize) {
      DrawElementVec_t foo;
      foo.reserve((size_t) maxSize);
      vec.swap(foo);
   } else {
      vec.clear();
   }
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::ClearDrawElementPtrVec(DrawElementPtrVec_t& vec,
                                                  Int_t maxSize)
{
   // Clear given vec and if it grew too large compared to the size of
   // shape-of-interest also resize it.

   if (vec.capacity() > (size_t) maxSize) {
      DrawElementPtrVec_t foo;
      foo.reserve((size_t) maxSize);
      vec.swap(foo);
   } else {
      vec.clear();
   }
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::ClearAfterRebuild()
{
   // Clear DrawElementVector fVisibleElement and optionally resize it
   // so that it doesn't take more space then required by all the
   // elements in the scene's draw-list.

   Int_t maxSize = (Int_t) fShapesOfInterest.size();

   ClearDrawElementVec(fVisibleElements, maxSize);
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::ClearAfterUpdate()
{
   // Clear DrawElementPtrVectors and optionally resize them so that
   // they don't take more space then required by all the elements in
   // the scene's draw-list.

   Int_t maxSize = (Int_t) fShapesOfInterest.size();

   ClearDrawElementPtrVec(fOpaqueElements, maxSize);
   ClearDrawElementPtrVec(fTranspElements, maxSize);
   ClearDrawElementPtrVec(fSelOpaqueElements, maxSize);
   ClearDrawElementPtrVec(fSelTranspElements, maxSize);

   fMinorStamp = 0;
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::Lodify(TGLRnrCtx& ctx)
{
   // Quantize LODs for gice render-context.

   for (DrawElementVec_i i = fVisibleElements.begin(); i != fVisibleElements.end(); ++i)
      i->fPhysical->QuantizeShapeLOD(i->fPixelLOD, ctx.CombiLOD(), i->fFinalLOD);
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::PreDraw()
{
   // Prepare for drawing - fill DrawElementPtrVectors from the
   // contents of fVisibleElements if there was some change.

   if (fMinorStamp < fScene->GetMinorStamp())
   {
      fOpaqueElements.clear();
      fTranspElements.clear();
      fSelOpaqueElements.clear();
      fSelTranspElements.clear();

      for (DrawElementVec_i i = fVisibleElements.begin(); i != fVisibleElements.end(); ++i)
      {
         if (i->fPhysical->IsSelected())
         {
            if (i->fPhysical->IsTransparent())
               fSelTranspElements.push_back(&*i);
            else
               fSelOpaqueElements.push_back(&*i);
         } else {
            if (i->fPhysical->IsTransparent())
               fTranspElements.push_back(&*i);
            else
               fOpaqueElements.push_back(&*i);
         }
      }
      fMinorStamp = fScene->GetMinorStamp();
   }
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::PostDraw()
{
   // Clean-up after drawing, nothing to be done here.
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::ResetDrawStats()
{
   // Reset draw statistics.

   fOpaqueCnt  = 0;
   fTranspCnt  = 0;
   fAsPixelCnt = 0;
   fByShapeCnt.clear();
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::UpdateDrawStats(const TGLPhysicalShape& shape,
                                           Short_t lod)
{
   // Update draw stats, for newly drawn 'shape'

   // Update opaque/transparent draw count
   if (shape.IsTransparent()) {
      ++fTranspCnt;
   } else {
      ++fOpaqueCnt;
   }

   if (lod == TGLRnrCtx::kLODPixel) {
      ++fAsPixelCnt;
   }

   // By type only done at higher debug level.
   if (gDebug>3) {
      // Update the stats
      TClass* logIsA = shape.GetLogical()->IsA();
      std::map<TClass*, UInt_t>::iterator it = fByShapeCnt.find(logIsA);
      if (it == fByShapeCnt.end()) {
         //do not need to check insert(.....).second, because it was stats.end() before
         it = fByShapeCnt.insert(std::make_pair(logIsA, 0u)).first;
      }

      it->second++;
   }
}

//______________________________________________________________________________
void TGLScene::TSceneInfo::DumpDrawStats()
{
   // Output draw stats to Info stream.

   if (gDebug>2)
   {
      TString out;
      // Draw/container counts
      out += Form("Drew scene (%s / %i LOD) - %i (Op %i Trans %i) %i pixel\n",
                  TGLRnrCtx::StyleName(LastStyle()), LastLOD(),
                  fOpaqueCnt + fTranspCnt, fOpaqueCnt, fTranspCnt, fAsPixelCnt);
      out += Form("\tInner phys nums: physicals=%d, of_interest=%d, visible=%d, op=%d, trans=%d",
                  ((TGLScene*)fScene)->GetMaxPhysicalID(),
                  fShapesOfInterest.size(), fVisibleElements.size(),
                  fOpaqueElements.size(), fTranspElements.size());

      // By shape type counts
      if (gDebug>3)
      {
         out += "\n\tStatistics by shape:\n";
         std::map<TClass*, UInt_t>::const_iterator it = fByShapeCnt.begin();
         while (it != fByShapeCnt.end()) {
            out += Form("\t%-20s  %u\n", it->first->GetName(), it->second);
            it++;
         }
      }
      Info("TGLScene::DumpDrawStats()", out.Data());
   }
}


//==============================================================================
// TGLScene
//==============================================================================

//______________________________________________________________________________
//
// TGLScene provides managememnt and rendering of ROOT's default 3D
// object representation as logical and physical shapes.
//
// A GL scene is the container for all the viewable objects (shapes)
// loaded into the viewer. It consists of two main stl::maps containing
// the TGLLogicalShape and TGLPhysicalShape collections, and interface
// functions enabling viewers to manage objects in these. The physical
// shapes defined the placement of copies of the logical shapes - see
// TGLLogicalShape/TGLPhysicalShape for more information on relationship
//
// The scene can be drawn by owning viewer, passing camera, draw style
// & quality (LOD), clipping etc - see Draw(). The scene can also be
// drawn for selection in similar fashion - see Select(). The scene
// keeps track of a single selected physical - which can be modified by
// viewers.
//
// The scene maintains a lazy calculated bounding box for the total
// scene extents, axis aligned round TGLPhysicalShape shapes.
//
// Currently a scene is owned exclusively by one viewer - however it is
// intended that it could easily be shared by multiple viewers - for
// efficiency and syncronisation reasons. Hence viewer variant objects
// camera, clips etc being owned by viewer and passed at draw/select

ClassImp(TGLScene);

//______________________________________________________________________________
TGLScene::TGLScene() :
   TGLSceneBase(),
   fGLCtxIdentity(0),
   fInSmartRefresh(kFALSE)
{}

//______________________________________________________________________________
TGLScene::~TGLScene()
{
   // Destroy scene objects
   TakeLock(kModifyLock);
   ReleaseGLCtxIdentity();
   DestroyPhysicals(kTRUE); // including modified
   DestroyLogicals();
   if (fGLCtxIdentity)
      fGLCtxIdentity->ReleaseClient();
   ReleaseLock(kModifyLock);
}

/**************************************************************************/
// GLCtxIdentity
/**************************************************************************/

//______________________________________________________________________________
void TGLScene::ReleaseGLCtxIdentity()
{
   // Release all GL resources for current context identity.
   // Requires iteration over all logical shapes.

   if (fGLCtxIdentity == 0) return;

   if (fGLCtxIdentity->IsValid())
   {
      // Purge logical's DLs
      LogicalShapeMapIt_t lit = fLogicalShapes.begin();
      while (lit != fLogicalShapes.end()) {
         lit->second->DLCachePurge();
         ++lit;
      }
   }
   else
   {
      // Drop logical's DLs
      LogicalShapeMapIt_t lit = fLogicalShapes.begin();
      while (lit != fLogicalShapes.end()) {
         lit->second->DLCacheDrop();
         ++lit;
      }
   }
   fGLCtxIdentity->ReleaseClient();
   fGLCtxIdentity = 0;
}

/**************************************************************************/
// SceneInfo management
/**************************************************************************/


//______________________________________________________________________________
TGLScene::TSceneInfo* TGLScene::CreateSceneInfo(TGLViewerBase* view)
{
   // Create a scene-info instance appropriate for this scene class.
   // Here we instantiate the inner class TSceneInfo that includes
   // camera/clipping specific draw-list containers.

   return new TSceneInfo(view, this);
}

//______________________________________________________________________________
inline Bool_t TGLScene::ComparePhysicalVolumes(const TGLPhysicalShape* shape1,
                                               const TGLPhysicalShape* shape2)
{
   // Compare 'shape1' and 'shape2' bounding box volumes - return kTRUE if
   // 'shape1' bigger than 'shape2'.

   return (shape1->BoundingBox().Volume() > shape2->BoundingBox().Volume());
}

//______________________________________________________________________________
inline Bool_t TGLScene::ComparePhysicalDiagonals(const TGLPhysicalShape* shape1,
                                                 const TGLPhysicalShape* shape2)
{
   // Compare 'shape1' and 'shape2' bounding box volumes - return kTRUE if
   // 'shape1' bigger than 'shape2'.

   return (shape1->BoundingBox().Diagonal() > shape2->BoundingBox().Diagonal());
}

//______________________________________________________________________________
void TGLScene::RebuildSceneInfo(TGLRnrCtx& rnrCtx)
{
   // Major change in scene, need to rebuild all-element draw-vector and
   // sort it.
   //
   // Sort the TGLPhysical draw list by shape bounding box diagonal, from
   // large to small. This makes dropout of shapes with time limited
   // Draw() calls must less noticable. As this does not use projected
   // size it only needs to be done after a scene content change - not
   // everytime scene drawn (potential camera/projection change).

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   if (sinfo == 0 || sinfo->GetScene() != this) {
      Error("TGLScene::RebuildSceneInfo", "Scene mismatch.");
      return;
   }

   TGLSceneBase::RebuildSceneInfo(rnrCtx);

   if (sinfo->fShapesOfInterest.capacity() > fPhysicalShapes.size()) {
      ShapeVec_t foo;
      foo.reserve(fPhysicalShapes.size());
      sinfo->fShapesOfInterest.swap(foo);
   } else {
      sinfo->fShapesOfInterest.clear();
   }

   PhysicalShapeMapIt_t pit = fPhysicalShapes.begin();
   while (pit != fPhysicalShapes.end())
   {
      TGLPhysicalShape      * pshp = pit->second;
      const TGLLogicalShape * lshp = pshp->GetLogical();
      if (rnrCtx.GetCamera()->OfInterest(pshp->BoundingBox(),
                                         lshp->IgnoreSizeForOfInterest()))
      {
         sinfo->fShapesOfInterest.push_back(pshp);
      }
      ++pit;
   }

   std::sort(sinfo->fShapesOfInterest.begin(), sinfo->fShapesOfInterest.end(),
             TGLScene::ComparePhysicalDiagonals);

   sinfo->ClearAfterRebuild();
}

//______________________________________________________________________________
void TGLScene::UpdateSceneInfo(TGLRnrCtx& rnrCtx)
{
   // Fill scene-info with information needed for rendering, take into
   // account the render-context (viewer state, camera, clipping).
   // Here we have to iterate over all the physical shapes and select
   // the visible ones. While at it, opaque and transparent shapes are
   // divided into two groups.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   if (sinfo == 0 || sinfo->GetScene() != this) {
      Error("TGLScene::UpdateSceneInfo", "Scene mismatch.");
      return;
   }

   // Clean-up/reset, update of transformation matrices and clipping
   // planes done in base-class.
   TGLSceneBase::UpdateSceneInfo(rnrCtx);

   if (!sinfo->IsVisible())
      return;

   sinfo->fVisibleElements.clear();

   // Check individual physicals, build DrawElementList.

   Int_t  checkCount = 0;
   Bool_t timerp     = rnrCtx.IsStopwatchRunning();
   sinfo->ResetUpdateTimeouted();

   for (ShapeVec_i phys=sinfo->fShapesOfInterest.begin();
        phys!=sinfo->fShapesOfInterest.end();
        ++phys, ++checkCount)
   {
      const TGLPhysicalShape * drawShape = *phys;

      // TODO: Do small skipping first? Probably cheaper than frustum check
      // Profile relative costs? The frustum check could be done implictly
      // from the LOD as we project all 8 verticies of the BB onto viewport

      // Work out if we need to draw this shape - assume we do first
      Bool_t drawNeeded = kTRUE;

      // Draw test against passed clipping planes.
      // Do before camera clipping on assumption clip planes remove
      // more objects.
      if (sinfo->ClipMode() == TGLSceneInfo::kClipOutside)
      {
         // Draw not needed if outside any of the planes.
         std::vector<TGLPlane>::iterator pi = sinfo->ClipPlanes().begin();
         while (pi != sinfo->ClipPlanes().end())
         {
            if (drawShape->BoundingBox().Overlap(*pi) == kOutside)
            {
               drawNeeded = kFALSE;
               break;
            }
            ++pi;
         }
      }
      else if (sinfo->ClipMode() == TGLSceneInfo::kClipInside)
      {
         // Draw not needed if inside all the planes.
         std::vector<TGLPlane>::iterator pi = sinfo->ClipPlanes().begin();
         size_t cnt = 0;
         while (pi != sinfo->ClipPlanes().end())
         {
            EOverlap ovlp = drawShape->BoundingBox().Overlap(*pi);
            if (ovlp == kOutside)
               break;
            else if (ovlp == kInside)
               ++cnt;
            ++pi;
         }
         if (cnt == sinfo->ClipPlanes().size())
            drawNeeded = kFALSE;
      }

      // Test against camera frustum planes (here mode is Outside
      // implicitly).
      if (drawNeeded)
      {
         std::vector<TGLPlane>::iterator pi = sinfo->FrustumPlanes().begin();
         while (pi != sinfo->FrustumPlanes().end())
         {
            if (drawShape->BoundingBox().Overlap(*pi) == kOutside)
            {
               drawNeeded = kFALSE;
               break;
            }
            ++pi;
         }
      }

      // Draw? Then calculate lod and store ...
      if (drawNeeded)
      {
         DrawElement_t de(drawShape);
         drawShape->CalculateShapeLOD(rnrCtx, de.fPixelSize, de.fPixelLOD);
         sinfo->fVisibleElements.push_back(de);
      }

      // Terminate the traversal if over scene rendering limit.
      // Only test every 5000 objects as this is somewhat costly.
      if (timerp && (checkCount % 5000) == 0 && rnrCtx.HasStopwatchTimedOut())
      {
         sinfo->UpdateTimeouted();
         if (rnrCtx.ViewerLOD() == TGLRnrCtx::kLODHigh)
            Warning("TGLScene::UpdateSceneInfo",
                    "Timeout reached, not all elements processed.");
         break;
      }
   }

   sinfo->ClearAfterUpdate();

   // !!! MT Transparents should be sorted by their eye z-coordinate.
   // Need combined matrices in scene-info to do this.
   // Even more ... should z-sort contributions from ALL scenes!
}

//______________________________________________________________________________
void TGLScene::LodifySceneInfo(TGLRnrCtx& rnrCtx)
{
   // Setup LOD-dependant values in scene-info.
   // We have to perform LOD quantization for all draw-elements.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   if (sinfo == 0 || sinfo->GetScene() != this) {
      Error("TGLScene::LodifySceneInfo", "Scene mismatch.");
      return;
   }

   TGLSceneBase::LodifySceneInfo(rnrCtx);

   sinfo->Lodify(rnrCtx);
}


/**************************************************************************/
// Rendering
/**************************************************************************/

//______________________________________________________________________________
void TGLScene::PreDraw(TGLRnrCtx& rnrCtx)
{
   // Initialize rendering.
   // Pass to base-class where most work is done.
   // Check if GL-ctx is shared with the previous one; if not
   // wipe display-lists of all logicals.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   if (sinfo == 0 || sinfo->GetScene() != this) {
      TGLSceneInfo* si = rnrCtx.GetSceneInfo();
      Error("TGLScene::PreDraw", Form("SceneInfo mismatch (0x%lx, '%s').",
                                      si, si ? si->IsA()->GetName() : "<>"));
      return;
   }

   // Setup ctx, check if Update/Lodify needed.
   TGLSceneBase::PreDraw(rnrCtx);

   TGLContextIdentity* cid = rnrCtx.GetGLCtxIdentity();
   if (cid != fGLCtxIdentity)
   {
      ReleaseGLCtxIdentity();
      fGLCtxIdentity = cid;
      fGLCtxIdentity->AddClientRef();
   }

   sinfo->PreDraw();

   // Reset-scene-info counters.
   sinfo->ResetDrawStats();
}

//______________________________________________________________________________
void TGLScene::RenderOpaque(TGLRnrCtx& rnrCtx)
{
   // Render opaque elements.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   if (!sinfo->fOpaqueElements.empty())
       RenderAllPasses(rnrCtx, sinfo->fOpaqueElements, kTRUE);
}

//______________________________________________________________________________
void TGLScene::RenderTransp(TGLRnrCtx& rnrCtx)
{
   // Render transparent elements.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   if (!sinfo->fTranspElements.empty())
       RenderAllPasses(rnrCtx, sinfo->fTranspElements, kTRUE);
}

//______________________________________________________________________________
void TGLScene::RenderSelOpaque(TGLRnrCtx& rnrCtx)
{
   // Render selected opaque elements.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   if (!sinfo->fSelOpaqueElements.empty())
       RenderAllPasses(rnrCtx, sinfo->fSelOpaqueElements, kFALSE);
}

//______________________________________________________________________________
void TGLScene::RenderSelTransp(TGLRnrCtx& rnrCtx)
{
   // Render selected transparent elements.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   if (!sinfo->fSelTranspElements.empty())
       RenderAllPasses(rnrCtx, sinfo->fSelTranspElements, kFALSE);
}

//______________________________________________________________________________
void TGLScene::PostDraw(TGLRnrCtx& rnrCtx)
{
   // Called after the rendering is finished.
   // In debug mode draw statistcs is dumped.
   // Parent's PostDraw is called for GL cleanup.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());

   if (gDebug)
      sinfo->DumpDrawStats();

   sinfo->PostDraw();

   TGLSceneBase::PostDraw(rnrCtx);
}

//______________________________________________________________________________
void TGLScene::RenderAllPasses(TGLRnrCtx&           rnrCtx,
                               DrawElementPtrVec_t& elVec,
                               Bool_t               check_timeout)
{
   // Do full rendering of scene.
   //
   // First draw the opaques, then the transparents. For each we do
   // the number of passes required by draw mode and clipping setup.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   assert(sinfo != 0);

   Short_t sceneStyle = rnrCtx.SceneStyle();

   // Setup GL for current draw style - fill, wireframe, outline
   Int_t        reqPasses  = 1; // default

   Short_t      rnrPass[2];
   rnrPass[0] = rnrPass[1] = TGLRnrCtx::kPassUndef;

   switch (sceneStyle)
   {
      case TGLRnrCtx::kFill:
      case TGLRnrCtx::kOutline:
      {
         glEnable(GL_LIGHTING);
         if (sinfo->ShouldClip()) {
            // Clip object - two sided lighting, two side polygons, don't cull (BACK) faces
            glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
            glDisable(GL_CULL_FACE);
         }
         // No clip - default single side lighting,
         // front polygons, cull (BACK) faces ok
         if (sceneStyle == TGLRnrCtx::kOutline) {
            reqPasses = 2;   // Outline needs two full draws
            rnrPass[0] = TGLRnrCtx::kPassOutlineFill;
            rnrPass[1] = TGLRnrCtx::kPassOutlineLine;
         } else {
            rnrPass[0] = TGLRnrCtx::kPassFill;
         }
         break;
      }
      case TGLRnrCtx::kWireFrame:
      {
         rnrPass[0] = TGLRnrCtx::kPassWireFrame;
         glDisable(GL_LIGHTING);
         glDisable(GL_CULL_FACE);
         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
         break;
      }
      default:
      {
         assert(kFALSE);
      }
   }

   for (Int_t i = 0; i < reqPasses; ++i)
   {
      // For outline two full draws (fill + wireframe) required.
      // Do it this way to avoid costly GL state swaps on per drawable basis

      Short_t pass = rnrPass[i];
      rnrCtx.SetDrawPass(pass);

      if (pass == TGLRnrCtx::kPassOutlineFill)
      {
         // First pass - filled polygons
         glEnable(GL_POLYGON_OFFSET_FILL);
         glPolygonOffset(0.5f, 0.5f);
      }
      else if (pass == TGLRnrCtx::kPassOutlineLine)
      {
         // Second pass - outline (wireframe)
         glDisable(GL_POLYGON_OFFSET_FILL);
         glDisable(GL_LIGHTING);

         // We are only showing back faces with clipping as a
         // better solution than completely invisible faces.
         // *Could* cull back faces and only outline on front like this:
         //    glEnable(GL_CULL_FACE);
         //    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
         // However this means clipped back edges not shown - so do inside and out....
         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      }

      // If no clip object no plane sets to extract/pass
      if ( ! sinfo->ShouldClip())
      {
         RenderElements(rnrCtx, elVec, check_timeout);
      }
      else
      {
         // Get the clip plane set from the clipping object
         TGLPlaneSet_t & planeSet = sinfo->ClipPlanes();

         if (gDebug > 3)
         {
            Info("TGLScene::RenderAllPasses()",
                 "%d active clip planes", planeSet.size());
         }
         // Limit to smaller of plane set size or GL implementation plane support
         Int_t maxGLPlanes;
         glGetIntegerv(GL_MAX_CLIP_PLANES, &maxGLPlanes);
         UInt_t maxPlanes = maxGLPlanes;
         UInt_t planeInd;
         if (planeSet.size() < maxPlanes) {
            maxPlanes = planeSet.size();
         }

         if (sinfo->ClipMode() == TGLSceneInfo::kClipOutside)
         {
            // Clip away scene outside of the clip object.
            // Load all clip planes (up to max) at once.
            for (UInt_t ii=0; ii<maxPlanes; ii++) {
               glClipPlane(GL_CLIP_PLANE0+ii, planeSet[ii].CArr());
               glEnable(GL_CLIP_PLANE0+ii);
            }

            // Draw scene once with full time slot, physicals have been
            // clipped during UpdateSceneInfo, so no need to repeat that.
            RenderElements(rnrCtx, elVec, check_timeout);
         }
         else
         {
            // Clip away scene inside of the clip object.
            // This requires number-of-clip-planes passes and can not
            // be entirely pre-computed (non-relevant planes are removed).
            std::vector<TGLPlane> activePlanes;
            for (planeInd=0; planeInd<maxPlanes; planeInd++)
            {
               activePlanes.push_back(planeSet[planeInd]);
               TGLPlane& p = activePlanes.back();
               p.Negate();
               glClipPlane(GL_CLIP_PLANE0+planeInd, p.CArr());
               glEnable(GL_CLIP_PLANE0+planeInd);

               // Draw scene with active planes, allocating fraction of time
               // for total planes.
               RenderElements(rnrCtx, elVec, check_timeout, &activePlanes);

               p.Negate();
               glClipPlane(GL_CLIP_PLANE0+planeInd, p.CArr());
            }
         }
         // Ensure all clip planes turned off again
         for (planeInd=0; planeInd<maxPlanes; planeInd++) {
            glDisable(GL_CLIP_PLANE0+planeInd);
         }
      }
   } // end for reqPasses

   // Reset gl modes to defaults
   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
   glEnable(GL_CULL_FACE);
   glEnable(GL_LIGHTING);
}

//______________________________________________________________________________
void TGLScene::RenderElements(TGLRnrCtx&           rnrCtx,
                              DrawElementPtrVec_t& elVec,
                              Bool_t               check_timeout,
                              const TGLPlaneSet_t* clipPlanes)
{
   // Render DrawElements in elementVec with given timeout.
   // If clipPlanes is non-zero, test each element against its
   // clipping planes.

   TSceneInfo* sinfo = dynamic_cast<TSceneInfo*>(rnrCtx.GetSceneInfo());
   assert(sinfo != 0);

   Int_t drawCount = 0;

   for (DrawElementPtrVec_i i = elVec.begin(); i != elVec.end(); ++i)
   {
      const TGLPhysicalShape * drawShape = (*i)->fPhysical;

      Bool_t drawNeeded = kTRUE;

      // If clipping planes are passed as argument, we test against them.
      if (clipPlanes && IsOutside(drawShape->BoundingBox(), *clipPlanes))
         drawNeeded = kFALSE;

      // Draw?
      if (drawNeeded)
      {
         rnrCtx.SetShapeLOD((*i)->fFinalLOD);
         glPushName(drawShape->ID());
         drawShape->Draw(rnrCtx);
         glPopName();
         ++drawCount;
         sinfo->UpdateDrawStats(*drawShape, rnrCtx.ShapeLOD());
      }

      // Terminate the draw if over opaque fraction timeout.
      // Only test every 2000 objects as this is somewhat costly.
      if (check_timeout && (drawCount % 2000) == 0 &&
          rnrCtx.HasStopwatchTimedOut())
      {
         if (rnrCtx.ViewerLOD() == TGLRnrCtx::kLODHigh)
             Warning("TGLScene::RenderElements",
                     "Timeout reached, not all elements rendered.");
         break;
      }
   }
}


/**************************************************************************/
// Selection
/**************************************************************************/

//______________________________________________________________________________
Bool_t TGLScene::ResolveSelectRecord(TGLSelectRecord& rec, Int_t curIdx)
{
   // Process selection record rec.
   // 'curIdx' is the item position where the scene should start
   // its processing.
   // Return TRUE if an object has been identified or FALSE otherwise.
   // The scene-info member of the record is already set by the caller.

   if (curIdx >= rec.GetN())
      return kFALSE;

   TGLPhysicalShape* pshp = FindPhysical(rec.GetItem(curIdx));
   if (pshp)
   {
      rec.SetTransparent(pshp->IsTransparent());
      rec.SetPhysShape(pshp);
      rec.SetObject(pshp->GetLogical()->GetExternal());
      rec.SetSpecific(0);
      return kTRUE;
   }
   return kFALSE;
}


/**************************************************************************/
// Bounding-box
/**************************************************************************/

//______________________________________________________________________________
void TGLScene::CalcBoundingBox() const
{
   // Encapsulates all physical shapes bounding box with axes aligned box.
   // Validity checked in the base-class.

   Double_t xMin, xMax, yMin, yMax, zMin, zMax;
   xMin = xMax = yMin = yMax = zMin = zMax = 0.0;
   PhysicalShapeMapCIt_t physicalShapeIt = fPhysicalShapes.begin();
   const TGLPhysicalShape * physicalShape;
   while (physicalShapeIt != fPhysicalShapes.end())
   {
      physicalShape = physicalShapeIt->second;
      if (!physicalShape)
      {
         assert(kFALSE);
         continue;
      }
      TGLBoundingBox box = physicalShape->BoundingBox();
      if (physicalShapeIt == fPhysicalShapes.begin()) {
         xMin = box.XMin(); xMax = box.XMax();
         yMin = box.YMin(); yMax = box.YMax();
         zMin = box.ZMin(); zMax = box.ZMax();
      } else {
         if (box.XMin() < xMin) { xMin = box.XMin(); }
         if (box.XMax() > xMax) { xMax = box.XMax(); }
         if (box.YMin() < yMin) { yMin = box.YMin(); }
         if (box.YMax() > yMax) { yMax = box.YMax(); }
         if (box.ZMin() < zMin) { zMin = box.ZMin(); }
         if (box.ZMax() > zMax) { zMax = box.ZMax(); }
      }
      ++physicalShapeIt;
   }
   fBoundingBox.SetAligned(TGLVertex3(xMin,yMin,zMin), TGLVertex3(xMax,yMax,zMax));
   fBoundingBoxValid = kTRUE;
}

/**************************************************************************/
// Logical shapes
/**************************************************************************/

//______________________________________________________________________________
void TGLScene::AdoptLogical(TGLLogicalShape& shape)
{
   // Adopt dynamically created logical 'shape' - add to internal map
   // and take responsibility for deleting.

   if (fLock != kModifyLock) {
      Error("TGLScene::AdoptLogical", "expected ModifyLock");
      return;
   }

   shape.fScene = this;
   fLogicalShapes.insert(LogicalShapeMapValueType_t(shape.ID(), &shape));
}

//______________________________________________________________________________
Bool_t TGLScene::DestroyLogical(TObject* logid, Bool_t mustFind)
{
   // Destroy logical shape defined by unique 'ID'.
   // Returns kTRUE if found/destroyed - kFALSE otherwise.
   //
   // If mustFind is true, an error is reported if the logical is not
   // found.

   if (fLock != kModifyLock) {
      Error("TGLScene::DestroyLogical", "expected ModifyLock");
      return kFALSE;
   }

   LogicalShapeMapIt_t lit = fLogicalShapes.find(logid);

   if (lit == fLogicalShapes.end()) {
      if (mustFind)
         Error("TGLScene::DestroyLogical", "logical not found in map.");
      return kFALSE;
   }

   TGLLogicalShape * logical = lit->second;
   UInt_t phid;
   while ((phid = logical->UnrefFirstPhysical()) != 0)
   {
      PhysicalShapeMapIt_t pit = fPhysicalShapes.find(phid);
      if (pit != fPhysicalShapes.end())
         DestroyPhysicalInternal(pit);
      else
         Warning("TGLScene::DestroyLogical", "an attached physical not found in map.");
   }
   assert(logical->Ref() == 0);
   fLogicalShapes.erase(lit);
   delete logical;
   InvalidateBoundingBox();
   IncTimeStamp();
   return kTRUE;
}

//______________________________________________________________________________
Int_t TGLScene::DestroyLogicals()
{
   // Destroy all logical shapes in scene.
   // Return number of destroyed logicals.

   if (fLock != kModifyLock) {
      Error("TGLScene::DestroyLogicals", "expected ModifyLock");
      return 0;
   }

   Int_t count = 0;
   LogicalShapeMapIt_t logicalShapeIt = fLogicalShapes.begin();
   const TGLLogicalShape * logicalShape;
   while (logicalShapeIt != fLogicalShapes.end()) {
      logicalShape = logicalShapeIt->second;
      if (logicalShape) {
         if (logicalShape->Ref() == 0) {
            fLogicalShapes.erase(logicalShapeIt++);
            delete logicalShape;
            ++count;
            continue;
         } else {
            assert(kFALSE);
         }
      } else {
         assert(kFALSE);
      }
      ++logicalShapeIt;
   }

   return count;
}

//______________________________________________________________________________
TGLLogicalShape * TGLScene::FindLogical(TObject* logid) const
{
   // Find and return logical shape identified by unqiue logid.
   // Returns 0 if not found.

   LogicalShapeMapCIt_t lit = fLogicalShapes.find(logid);
   if (lit != fLogicalShapes.end()) {
      return lit->second;
   } else {
      if (fInSmartRefresh)
         return FindLogicalSmartRefresh(logid);
      else
         return 0;
   }
}


/**************************************************************************/
// Physical shapes
/**************************************************************************/

//______________________________________________________________________________
void TGLScene::AdoptPhysical(TGLPhysicalShape & shape)
{
   // Adopt dynamically created physical 'shape' - add to internal map and take
   // responsibility for deleting
   if (fLock != kModifyLock) {
      Error("TGLScene::AdoptPhysical", "expected ModifyLock");
      return;
   }
   // TODO: Very inefficient check - disable
   assert(fPhysicalShapes.find(shape.ID()) == fPhysicalShapes.end());

   fPhysicalShapes.insert(PhysicalShapeMapValueType_t(shape.ID(), &shape));

   InvalidateBoundingBox();
   IncTimeStamp();
}

//______________________________________________________________________________
void TGLScene::DestroyPhysicalInternal(PhysicalShapeMapIt_t pit)
{
   // Virtual function to destroy a physical. Sub-classes might have
   // special checks to perform.
   // Caller should also invalidate the draw-list.

   delete pit->second;
   fPhysicalShapes.erase(pit);
}

//______________________________________________________________________________
Bool_t TGLScene::DestroyPhysical(UInt_t phid)
{
   // Destroy physical shape defined by unique 'ID'.
   // Returns kTRUE if found/destroyed - kFALSE otherwise.

   if (fLock != kModifyLock) {
      Error("TGLScene::DestroyPhysical", "expected ModifyLock.");
      return kFALSE;
   }

   PhysicalShapeMapIt_t pit = fPhysicalShapes.find(phid);

   if (pit == fPhysicalShapes.end()) {
      Error("TGLScene::DestroyPhysical::UpdatePhysical", "physical not found.");
      return kFALSE;
   }

   DestroyPhysicalInternal(pit);

   InvalidateBoundingBox();

   return kTRUE;
}

//______________________________________________________________________________
Int_t TGLScene::DestroyPhysicals(Bool_t incModified, const TGLCamera* camera)
{
   // Destroy physical shapes that are no longer of interest to camera.
   // If 'incModified' is true also the modified ones are deleted.
   // Return count of number destroyed.

   // !!! MT this whole concept is strange. Why should i keep
   // physicals that are modified? There is no working update
   // mechanism so they'll be wiped on pad-update.
   // Maybe should rename the method, or what?

   if (fLock != kModifyLock) {
      Error("TGLScene::DestroyPhysicals", "expected ModifyLock");
      return 0;
   }

   Int_t count = 0;
   PhysicalShapeMapIt_t pit = fPhysicalShapes.begin();
   while (pit != fPhysicalShapes.end())
   {
      const TGLPhysicalShape * physical = pit->second;
      if (physical) {
         // If modified options allow this physical to be destoyed
         if (incModified || (!incModified && !physical->IsModified())) {
            // and no camera is passed, or it is no longer of interest
            // to camera
            Bool_t ignoreSize = physical->GetLogical()->IgnoreSizeForOfInterest();
            if (!camera || (camera && !camera->OfInterest(physical->BoundingBox(), ignoreSize)))
            {
               DestroyPhysicalInternal(pit++);
               ++count;
               continue; // Incremented the iterator during erase()
            }
         }
      } else {
         assert(kFALSE);
      }
      ++pit;
   }

   if (count > 0) {
      InvalidateBoundingBox();
      IncTimeStamp();
   }

   return count;
}

//______________________________________________________________________________
TGLPhysicalShape* TGLScene::FindPhysical(UInt_t phid) const
{
   // Find and return physical shape identified by unqiue 'ID'.
   // Returns 0 if not found.

   PhysicalShapeMapCIt_t pit = fPhysicalShapes.find(phid);
   return (pit != fPhysicalShapes.end()) ? pit->second : 0;
}

//______________________________________________________________________________
UInt_t TGLScene::GetMaxPhysicalID()
{
   // Returns the maximum used physical id.
   // Returns 0 if empty.

   if (fPhysicalShapes.empty()) return 0;
   return (--fPhysicalShapes.end())->first;
}


/**************************************************************************/
// Update methods
/**************************************************************************/

//______________________________________________________________________________
Bool_t TGLScene::BeginUpdate()
{
   // Put scene in update mode, return true if lock acquired.

   Bool_t ok = TakeLock(kModifyLock);
   return ok;
}

//______________________________________________________________________________
void TGLScene::EndUpdate(Bool_t minorChange, Bool_t sceneChanged, Bool_t updateViewers)
{
   // Exit scene update mode.
   //
   // If sceneChanged is true (default), the scene timestamp is
   // increased and basic draw-lists etc will be rebuild on next draw
   // request. If you only changed colors or some other visual
   // parameters that do not affect object bounding-box or
   // transformation matrix, you can set it to false.
   //
   // If updateViewers is true (default), the viewers using this scene
   // will be tagged as changed. If sceneChanged is true the
   // updateViewers should be true as well, unless you take care of
   // the viewers elsewhere or in some other way.

   if (minorChange)
      IncMinorStamp();

   if (sceneChanged)
      IncTimeStamp();

   ReleaseLock(kModifyLock);

   if (updateViewers)
      TagViewersChanged();
}

//______________________________________________________________________________
void TGLScene::UpdateLogical(TObject* logid)
{
   // Drop display-lists for the logical (assume TGLObject/direct rendering).
   // Re-calculate the bounding box (also for all physicals).

   if (fLock != kModifyLock) {
      Error("TGLScene::UpdateLogical", "expected ModifyLock");
      return;
   }

   TGLLogicalShape* log = FindLogical(logid);

   if (log == 0) {
      Error("TGLScene::UpdateLogical", "logical not found");
      return;
   }

   log->DLCacheClear();
   log->UpdateBoundingBox();
}

//______________________________________________________________________________
void TGLScene::UpdatePhysical(UInt_t phid, Double_t* trans, UChar_t* col)
{
   // Reposition/recolor physical shape.

   if (fLock != kModifyLock) {
      Error("TGLScene::UpdatePhysical", "expected ModifyLock");
      return;
   }

   TGLPhysicalShape* phys = FindPhysical(phid);

   if (phys == 0) {
      Error("TGLScene::UpdatePhysical", "physical not found");
      return;
   }

   if (trans)  phys->SetTransform(trans);
   if (col)    phys->SetDiffuseColor(col);
}

//______________________________________________________________________________
void TGLScene::UpdatePhysical(UInt_t phid, Double_t* trans, Color_t cidx, UChar_t transp)
{
   // Reposition/recolor physical shape.

   if (fLock != kModifyLock) {
      Error("TGLScene::UpdatePhysical", "expected ModifyLock");
      return;
   }

   TGLPhysicalShape* phys = FindPhysical(phid);

   if (phys == 0) {
      Error("TGLScene::UpdatePhysical", "physical not found");
      return;
   }

   if (trans)
      phys->SetTransform(trans);
   if (cidx >= 0) {
      Float_t rgba[4];
      RGBAFromColorIdx(rgba, cidx, transp);
      phys->SetDiffuseColor(rgba);
   }
}

//______________________________________________________________________________
void TGLScene::UpdatePhysioLogical(TObject* logid, Double_t* trans, UChar_t* col)
{
   // Reposition/recolor physical for given logical (assume TGLObject and
   // a single physical).

   if (fLock != kModifyLock) {
      Error("TGLScene::UpdatePhysioLogical", "expected ModifyLock");
      return;
   }

   TGLLogicalShape* log = FindLogical(logid);

   if (log == 0) {
      Error("TGLScene::UpdatePhysioLogical", "logical not found");
      return;
   }

   if (log->Ref() != 1) {
      Warning("TGLScene::UpdatePhysioLogical", "expecting a single physical (%d).", log->Ref());
   }

   TGLPhysicalShape* phys = log->fFirstPhysical;
   if (trans)  phys->SetTransform(trans);
   if (col)    phys->SetDiffuseColor(col);
}

//______________________________________________________________________________
void TGLScene::UpdatePhysioLogical(TObject* logid, Double_t* trans, Color_t cidx, UChar_t transp)
{
   // Reposition/recolor physical for given logical (assume TGLObject and
   // a single physical).

   if (fLock != kModifyLock) {
      Error("TGLScene::UpdatePhysioLogical", "expected ModifyLock");
      return;
   }

   TGLLogicalShape* log = FindLogical(logid);

   if (log == 0) {
      Error("TGLScene::UpdatePhysioLogical", "logical not found");
      return;
   }

   if (log->Ref() != 1) {
      Warning("TGLScene::UpdatePhysioLogical", "expecting a single physical (%d).", log->Ref());
   }

   TGLPhysicalShape* phys = log->fFirstPhysical;
   if (trans)
      phys->SetTransform(trans);
   if (cidx >= 0) {
      Float_t rgba[4];
      RGBAFromColorIdx(rgba, cidx, transp);
      phys->SetDiffuseColor(rgba);
   }
}


/**************************************************************************/
// Smart refresh
/**************************************************************************/

//______________________________________________________________________________
UInt_t TGLScene::BeginSmartRefresh()
{
   // Moves logicals that support smart-refresh to intermediate cache.
   // Destroys the others and returns the number of destroyed ones.

   fSmartRefreshCache.swap(fLogicalShapes);
   // Remove all logicals that don't survive a refresh.
   UInt_t count = 0;
   LogicalShapeMapIt_t i = fSmartRefreshCache.begin();
   while (i != fSmartRefreshCache.end()) {
      if (i->second->KeepDuringSmartRefresh() == kFALSE) {
         LogicalShapeMapIt_t j = i++;
         delete j->second;
         fSmartRefreshCache.erase(j);
         ++count;
      } else {
         ++i;
      }
   }
   fInSmartRefresh = kTRUE;
   return count;
}

//______________________________________________________________________________
void TGLScene::EndSmartRefresh()
{
   // Wipes logicals in refresh-cache.

   fInSmartRefresh = kFALSE;

   LogicalShapeMapIt_t i = fSmartRefreshCache.begin();
   while (i != fSmartRefreshCache.end()) {
      delete i->second;
      ++i;
   }
   fSmartRefreshCache.clear();
}

//______________________________________________________________________________
TGLLogicalShape * TGLScene::FindLogicalSmartRefresh(TObject* ID) const
{
   // Find and return logical shape identified by unqiue 'ID' in refresh-cache.
   // Returns 0 if not found.

   LogicalShapeMapIt_t it = fSmartRefreshCache.find(ID);
   if (it != fSmartRefreshCache.end())
   {
      TGLLogicalShape* l_shape = it->second;
      fSmartRefreshCache.erase(it);
      if (l_shape->IsA() != TGLObject::GetGLRenderer(ID->IsA()))
      {
         Warning("TGLScene::FindLogicalSmartRefresh", "Wrong renderer-type found in cache.");
         delete l_shape;
         return 0;
      }
      // printf("TGLScene::SmartRefresh found cached: %p '%s' [%s] for %p\n",
      //    l_shape, l_shape->GetExternal()->GetName(),
      //    l_shape->GetExternal()->IsA()->GetName(), (void*) ID);
      LogicalShapeMap_t* lsm = const_cast<LogicalShapeMap_t*>(&fLogicalShapes);
      lsm->insert(LogicalShapeMapValueType_t(l_shape->ID(), l_shape));
      l_shape->DLCacheClear();
      l_shape->UpdateBoundingBox();
      return l_shape;
   } else {
      return 0;
   }
}


/**************************************************************************/
// Helpers
/**************************************************************************/

//______________________________________________________________________________
UInt_t TGLScene::SizeOfScene() const
{
   // Return memory cost of scene.
   // Warning: NOT CORRECT at present - doesn't correctly calculate size.
   // of logical shapes with dynamic internal contents.

   UInt_t size = sizeof(this);

   printf("Size: Scene Only %u\n", size);

   LogicalShapeMapCIt_t logicalShapeIt = fLogicalShapes.begin();
   const TGLLogicalShape * logicalShape;
   while (logicalShapeIt != fLogicalShapes.end()) {
      logicalShape = logicalShapeIt->second;
      size += sizeof(*logicalShape);
      ++logicalShapeIt;
   }

   printf("Size: Scene + Logical Shapes %u\n", size);

   PhysicalShapeMapCIt_t physicalShapeIt = fPhysicalShapes.begin();
   const TGLPhysicalShape * physicalShape;
   while (physicalShapeIt != fPhysicalShapes.end()) {
      physicalShape = physicalShapeIt->second;
      size += sizeof(*physicalShape);
      ++physicalShapeIt;
   }

   printf("Size: Scene + Logical Shapes + Physical Shapes %u\n", size);

   return size;
}

//______________________________________________________________________________
void TGLScene::DumpMapSizes() const
{
   // Print sizes of logical nad physical-shape maps.

   printf("Scene: %u Logicals / %u Physicals\n",
          (UInt_t) fLogicalShapes.size(), (UInt_t) fPhysicalShapes.size());
}

//______________________________________________________________________________
void TGLScene::RGBAFromColorIdx(Float_t rgba[4], Color_t ci, Char_t transp)
{
   // Fill rgba color from ROOT color-index ci and transparency (0->100).

   TColor* c = gROOT->GetColor(ci);
   if(c)   c->GetRGB(rgba[0], rgba[1], rgba[2]);
   else    rgba[0] = rgba[1] = rgba[2] = 0.5;
   rgba[3] = 1.0f - transp/100.0f;
}

//______________________________________________________________________________
Bool_t TGLScene::IsOutside(const TGLBoundingBox & box,
                           const TGLPlaneSet_t  & planes)
{
   // Check if box is outside of all planes.

   for (TGLPlaneSet_ci p=planes.begin(); p!=planes.end(); ++p)
      if (box.Overlap(*p) == kOutside)
         return kTRUE;
   return kFALSE;
}
 TGLScene.cxx:1
 TGLScene.cxx:2
 TGLScene.cxx:3
 TGLScene.cxx:4
 TGLScene.cxx:5
 TGLScene.cxx:6
 TGLScene.cxx:7
 TGLScene.cxx:8
 TGLScene.cxx:9
 TGLScene.cxx:10
 TGLScene.cxx:11
 TGLScene.cxx:12
 TGLScene.cxx:13
 TGLScene.cxx:14
 TGLScene.cxx:15
 TGLScene.cxx:16
 TGLScene.cxx:17
 TGLScene.cxx:18
 TGLScene.cxx:19
 TGLScene.cxx:20
 TGLScene.cxx:21
 TGLScene.cxx:22
 TGLScene.cxx:23
 TGLScene.cxx:24
 TGLScene.cxx:25
 TGLScene.cxx:26
 TGLScene.cxx:27
 TGLScene.cxx:28
 TGLScene.cxx:29
 TGLScene.cxx:30
 TGLScene.cxx:31
 TGLScene.cxx:32
 TGLScene.cxx:33
 TGLScene.cxx:34
 TGLScene.cxx:35
 TGLScene.cxx:36
 TGLScene.cxx:37
 TGLScene.cxx:38
 TGLScene.cxx:39
 TGLScene.cxx:40
 TGLScene.cxx:41
 TGLScene.cxx:42
 TGLScene.cxx:43
 TGLScene.cxx:44
 TGLScene.cxx:45
 TGLScene.cxx:46
 TGLScene.cxx:47
 TGLScene.cxx:48
 TGLScene.cxx:49
 TGLScene.cxx:50
 TGLScene.cxx:51
 TGLScene.cxx:52
 TGLScene.cxx:53
 TGLScene.cxx:54
 TGLScene.cxx:55
 TGLScene.cxx:56
 TGLScene.cxx:57
 TGLScene.cxx:58
 TGLScene.cxx:59
 TGLScene.cxx:60
 TGLScene.cxx:61
 TGLScene.cxx:62
 TGLScene.cxx:63
 TGLScene.cxx:64
 TGLScene.cxx:65
 TGLScene.cxx:66
 TGLScene.cxx:67
 TGLScene.cxx:68
 TGLScene.cxx:69
 TGLScene.cxx:70
 TGLScene.cxx:71
 TGLScene.cxx:72
 TGLScene.cxx:73
 TGLScene.cxx:74
 TGLScene.cxx:75
 TGLScene.cxx:76
 TGLScene.cxx:77
 TGLScene.cxx:78
 TGLScene.cxx:79
 TGLScene.cxx:80
 TGLScene.cxx:81
 TGLScene.cxx:82
 TGLScene.cxx:83
 TGLScene.cxx:84
 TGLScene.cxx:85
 TGLScene.cxx:86
 TGLScene.cxx:87
 TGLScene.cxx:88
 TGLScene.cxx:89
 TGLScene.cxx:90
 TGLScene.cxx:91
 TGLScene.cxx:92
 TGLScene.cxx:93
 TGLScene.cxx:94
 TGLScene.cxx:95
 TGLScene.cxx:96
 TGLScene.cxx:97
 TGLScene.cxx:98
 TGLScene.cxx:99
 TGLScene.cxx:100
 TGLScene.cxx:101
 TGLScene.cxx:102
 TGLScene.cxx:103
 TGLScene.cxx:104
 TGLScene.cxx:105
 TGLScene.cxx:106
 TGLScene.cxx:107
 TGLScene.cxx:108
 TGLScene.cxx:109
 TGLScene.cxx:110
 TGLScene.cxx:111
 TGLScene.cxx:112
 TGLScene.cxx:113
 TGLScene.cxx:114
 TGLScene.cxx:115
 TGLScene.cxx:116
 TGLScene.cxx:117
 TGLScene.cxx:118
 TGLScene.cxx:119
 TGLScene.cxx:120
 TGLScene.cxx:121
 TGLScene.cxx:122
 TGLScene.cxx:123
 TGLScene.cxx:124
 TGLScene.cxx:125
 TGLScene.cxx:126
 TGLScene.cxx:127
 TGLScene.cxx:128
 TGLScene.cxx:129
 TGLScene.cxx:130
 TGLScene.cxx:131
 TGLScene.cxx:132
 TGLScene.cxx:133
 TGLScene.cxx:134
 TGLScene.cxx:135
 TGLScene.cxx:136
 TGLScene.cxx:137
 TGLScene.cxx:138
 TGLScene.cxx:139
 TGLScene.cxx:140
 TGLScene.cxx:141
 TGLScene.cxx:142
 TGLScene.cxx:143
 TGLScene.cxx:144
 TGLScene.cxx:145
 TGLScene.cxx:146
 TGLScene.cxx:147
 TGLScene.cxx:148
 TGLScene.cxx:149
 TGLScene.cxx:150
 TGLScene.cxx:151
 TGLScene.cxx:152
 TGLScene.cxx:153
 TGLScene.cxx:154
 TGLScene.cxx:155
 TGLScene.cxx:156
 TGLScene.cxx:157
 TGLScene.cxx:158
 TGLScene.cxx:159
 TGLScene.cxx:160
 TGLScene.cxx:161
 TGLScene.cxx:162
 TGLScene.cxx:163
 TGLScene.cxx:164
 TGLScene.cxx:165
 TGLScene.cxx:166
 TGLScene.cxx:167
 TGLScene.cxx:168
 TGLScene.cxx:169
 TGLScene.cxx:170
 TGLScene.cxx:171
 TGLScene.cxx:172
 TGLScene.cxx:173
 TGLScene.cxx:174
 TGLScene.cxx:175
 TGLScene.cxx:176
 TGLScene.cxx:177
 TGLScene.cxx:178
 TGLScene.cxx:179
 TGLScene.cxx:180
 TGLScene.cxx:181
 TGLScene.cxx:182
 TGLScene.cxx:183
 TGLScene.cxx:184
 TGLScene.cxx:185
 TGLScene.cxx:186
 TGLScene.cxx:187
 TGLScene.cxx:188
 TGLScene.cxx:189
 TGLScene.cxx:190
 TGLScene.cxx:191
 TGLScene.cxx:192
 TGLScene.cxx:193
 TGLScene.cxx:194
 TGLScene.cxx:195
 TGLScene.cxx:196
 TGLScene.cxx:197
 TGLScene.cxx:198
 TGLScene.cxx:199
 TGLScene.cxx:200
 TGLScene.cxx:201
 TGLScene.cxx:202
 TGLScene.cxx:203
 TGLScene.cxx:204
 TGLScene.cxx:205
 TGLScene.cxx:206
 TGLScene.cxx:207
 TGLScene.cxx:208
 TGLScene.cxx:209
 TGLScene.cxx:210
 TGLScene.cxx:211
 TGLScene.cxx:212
 TGLScene.cxx:213
 TGLScene.cxx:214
 TGLScene.cxx:215
 TGLScene.cxx:216
 TGLScene.cxx:217
 TGLScene.cxx:218
 TGLScene.cxx:219
 TGLScene.cxx:220
 TGLScene.cxx:221
 TGLScene.cxx:222
 TGLScene.cxx:223
 TGLScene.cxx:224
 TGLScene.cxx:225
 TGLScene.cxx:226
 TGLScene.cxx:227
 TGLScene.cxx:228
 TGLScene.cxx:229
 TGLScene.cxx:230
 TGLScene.cxx:231
 TGLScene.cxx:232
 TGLScene.cxx:233
 TGLScene.cxx:234
 TGLScene.cxx:235
 TGLScene.cxx:236
 TGLScene.cxx:237
 TGLScene.cxx:238
 TGLScene.cxx:239
 TGLScene.cxx:240
 TGLScene.cxx:241
 TGLScene.cxx:242
 TGLScene.cxx:243
 TGLScene.cxx:244
 TGLScene.cxx:245
 TGLScene.cxx:246
 TGLScene.cxx:247
 TGLScene.cxx:248
 TGLScene.cxx:249
 TGLScene.cxx:250
 TGLScene.cxx:251
 TGLScene.cxx:252
 TGLScene.cxx:253
 TGLScene.cxx:254
 TGLScene.cxx:255
 TGLScene.cxx:256
 TGLScene.cxx:257
 TGLScene.cxx:258
 TGLScene.cxx:259
 TGLScene.cxx:260
 TGLScene.cxx:261
 TGLScene.cxx:262
 TGLScene.cxx:263
 TGLScene.cxx:264
 TGLScene.cxx:265
 TGLScene.cxx:266
 TGLScene.cxx:267
 TGLScene.cxx:268
 TGLScene.cxx:269
 TGLScene.cxx:270
 TGLScene.cxx:271
 TGLScene.cxx:272
 TGLScene.cxx:273
 TGLScene.cxx:274
 TGLScene.cxx:275
 TGLScene.cxx:276
 TGLScene.cxx:277
 TGLScene.cxx:278
 TGLScene.cxx:279
 TGLScene.cxx:280
 TGLScene.cxx:281
 TGLScene.cxx:282
 TGLScene.cxx:283
 TGLScene.cxx:284
 TGLScene.cxx:285
 TGLScene.cxx:286
 TGLScene.cxx:287
 TGLScene.cxx:288
 TGLScene.cxx:289
 TGLScene.cxx:290
 TGLScene.cxx:291
 TGLScene.cxx:292
 TGLScene.cxx:293
 TGLScene.cxx:294
 TGLScene.cxx:295
 TGLScene.cxx:296
 TGLScene.cxx:297
 TGLScene.cxx:298
 TGLScene.cxx:299
 TGLScene.cxx:300
 TGLScene.cxx:301
 TGLScene.cxx:302
 TGLScene.cxx:303
 TGLScene.cxx:304
 TGLScene.cxx:305
 TGLScene.cxx:306
 TGLScene.cxx:307
 TGLScene.cxx:308
 TGLScene.cxx:309
 TGLScene.cxx:310
 TGLScene.cxx:311
 TGLScene.cxx:312
 TGLScene.cxx:313
 TGLScene.cxx:314
 TGLScene.cxx:315
 TGLScene.cxx:316
 TGLScene.cxx:317
 TGLScene.cxx:318
 TGLScene.cxx:319
 TGLScene.cxx:320
 TGLScene.cxx:321
 TGLScene.cxx:322
 TGLScene.cxx:323
 TGLScene.cxx:324
 TGLScene.cxx:325
 TGLScene.cxx:326
 TGLScene.cxx:327
 TGLScene.cxx:328
 TGLScene.cxx:329
 TGLScene.cxx:330
 TGLScene.cxx:331
 TGLScene.cxx:332
 TGLScene.cxx:333
 TGLScene.cxx:334
 TGLScene.cxx:335
 TGLScene.cxx:336
 TGLScene.cxx:337
 TGLScene.cxx:338
 TGLScene.cxx:339
 TGLScene.cxx:340
 TGLScene.cxx:341
 TGLScene.cxx:342
 TGLScene.cxx:343
 TGLScene.cxx:344
 TGLScene.cxx:345
 TGLScene.cxx:346
 TGLScene.cxx:347
 TGLScene.cxx:348
 TGLScene.cxx:349
 TGLScene.cxx:350
 TGLScene.cxx:351
 TGLScene.cxx:352
 TGLScene.cxx:353
 TGLScene.cxx:354
 TGLScene.cxx:355
 TGLScene.cxx:356
 TGLScene.cxx:357
 TGLScene.cxx:358
 TGLScene.cxx:359
 TGLScene.cxx:360
 TGLScene.cxx:361
 TGLScene.cxx:362
 TGLScene.cxx:363
 TGLScene.cxx:364
 TGLScene.cxx:365
 TGLScene.cxx:366
 TGLScene.cxx:367
 TGLScene.cxx:368
 TGLScene.cxx:369
 TGLScene.cxx:370
 TGLScene.cxx:371
 TGLScene.cxx:372
 TGLScene.cxx:373
 TGLScene.cxx:374
 TGLScene.cxx:375
 TGLScene.cxx:376
 TGLScene.cxx:377
 TGLScene.cxx:378
 TGLScene.cxx:379
 TGLScene.cxx:380
 TGLScene.cxx:381
 TGLScene.cxx:382
 TGLScene.cxx:383
 TGLScene.cxx:384
 TGLScene.cxx:385
 TGLScene.cxx:386
 TGLScene.cxx:387
 TGLScene.cxx:388
 TGLScene.cxx:389
 TGLScene.cxx:390
 TGLScene.cxx:391
 TGLScene.cxx:392
 TGLScene.cxx:393
 TGLScene.cxx:394
 TGLScene.cxx:395
 TGLScene.cxx:396
 TGLScene.cxx:397
 TGLScene.cxx:398
 TGLScene.cxx:399
 TGLScene.cxx:400
 TGLScene.cxx:401
 TGLScene.cxx:402
 TGLScene.cxx:403
 TGLScene.cxx:404
 TGLScene.cxx:405
 TGLScene.cxx:406
 TGLScene.cxx:407
 TGLScene.cxx:408
 TGLScene.cxx:409
 TGLScene.cxx:410
 TGLScene.cxx:411
 TGLScene.cxx:412
 TGLScene.cxx:413
 TGLScene.cxx:414
 TGLScene.cxx:415
 TGLScene.cxx:416
 TGLScene.cxx:417
 TGLScene.cxx:418
 TGLScene.cxx:419
 TGLScene.cxx:420
 TGLScene.cxx:421
 TGLScene.cxx:422
 TGLScene.cxx:423
 TGLScene.cxx:424
 TGLScene.cxx:425
 TGLScene.cxx:426
 TGLScene.cxx:427
 TGLScene.cxx:428
 TGLScene.cxx:429
 TGLScene.cxx:430
 TGLScene.cxx:431
 TGLScene.cxx:432
 TGLScene.cxx:433
 TGLScene.cxx:434
 TGLScene.cxx:435
 TGLScene.cxx:436
 TGLScene.cxx:437
 TGLScene.cxx:438
 TGLScene.cxx:439
 TGLScene.cxx:440
 TGLScene.cxx:441
 TGLScene.cxx:442
 TGLScene.cxx:443
 TGLScene.cxx:444
 TGLScene.cxx:445
 TGLScene.cxx:446
 TGLScene.cxx:447
 TGLScene.cxx:448
 TGLScene.cxx:449
 TGLScene.cxx:450
 TGLScene.cxx:451
 TGLScene.cxx:452
 TGLScene.cxx:453
 TGLScene.cxx:454
 TGLScene.cxx:455
 TGLScene.cxx:456
 TGLScene.cxx:457
 TGLScene.cxx:458
 TGLScene.cxx:459
 TGLScene.cxx:460
 TGLScene.cxx:461
 TGLScene.cxx:462
 TGLScene.cxx:463
 TGLScene.cxx:464
 TGLScene.cxx:465
 TGLScene.cxx:466
 TGLScene.cxx:467
 TGLScene.cxx:468
 TGLScene.cxx:469
 TGLScene.cxx:470
 TGLScene.cxx:471
 TGLScene.cxx:472
 TGLScene.cxx:473
 TGLScene.cxx:474
 TGLScene.cxx:475
 TGLScene.cxx:476
 TGLScene.cxx:477
 TGLScene.cxx:478
 TGLScene.cxx:479
 TGLScene.cxx:480
 TGLScene.cxx:481
 TGLScene.cxx:482
 TGLScene.cxx:483
 TGLScene.cxx:484
 TGLScene.cxx:485
 TGLScene.cxx:486
 TGLScene.cxx:487
 TGLScene.cxx:488
 TGLScene.cxx:489
 TGLScene.cxx:490
 TGLScene.cxx:491
 TGLScene.cxx:492
 TGLScene.cxx:493
 TGLScene.cxx:494
 TGLScene.cxx:495
 TGLScene.cxx:496
 TGLScene.cxx:497
 TGLScene.cxx:498
 TGLScene.cxx:499
 TGLScene.cxx:500
 TGLScene.cxx:501
 TGLScene.cxx:502
 TGLScene.cxx:503
 TGLScene.cxx:504
 TGLScene.cxx:505
 TGLScene.cxx:506
 TGLScene.cxx:507
 TGLScene.cxx:508
 TGLScene.cxx:509
 TGLScene.cxx:510
 TGLScene.cxx:511
 TGLScene.cxx:512
 TGLScene.cxx:513
 TGLScene.cxx:514
 TGLScene.cxx:515
 TGLScene.cxx:516
 TGLScene.cxx:517
 TGLScene.cxx:518
 TGLScene.cxx:519
 TGLScene.cxx:520
 TGLScene.cxx:521
 TGLScene.cxx:522
 TGLScene.cxx:523
 TGLScene.cxx:524
 TGLScene.cxx:525
 TGLScene.cxx:526
 TGLScene.cxx:527
 TGLScene.cxx:528
 TGLScene.cxx:529
 TGLScene.cxx:530
 TGLScene.cxx:531
 TGLScene.cxx:532
 TGLScene.cxx:533
 TGLScene.cxx:534
 TGLScene.cxx:535
 TGLScene.cxx:536
 TGLScene.cxx:537
 TGLScene.cxx:538
 TGLScene.cxx:539
 TGLScene.cxx:540
 TGLScene.cxx:541
 TGLScene.cxx:542
 TGLScene.cxx:543
 TGLScene.cxx:544
 TGLScene.cxx:545
 TGLScene.cxx:546
 TGLScene.cxx:547
 TGLScene.cxx:548
 TGLScene.cxx:549
 TGLScene.cxx:550
 TGLScene.cxx:551
 TGLScene.cxx:552
 TGLScene.cxx:553
 TGLScene.cxx:554
 TGLScene.cxx:555
 TGLScene.cxx:556
 TGLScene.cxx:557
 TGLScene.cxx:558
 TGLScene.cxx:559
 TGLScene.cxx:560
 TGLScene.cxx:561
 TGLScene.cxx:562
 TGLScene.cxx:563
 TGLScene.cxx:564
 TGLScene.cxx:565
 TGLScene.cxx:566
 TGLScene.cxx:567
 TGLScene.cxx:568
 TGLScene.cxx:569
 TGLScene.cxx:570
 TGLScene.cxx:571
 TGLScene.cxx:572
 TGLScene.cxx:573
 TGLScene.cxx:574
 TGLScene.cxx:575
 TGLScene.cxx:576
 TGLScene.cxx:577
 TGLScene.cxx:578
 TGLScene.cxx:579
 TGLScene.cxx:580
 TGLScene.cxx:581
 TGLScene.cxx:582
 TGLScene.cxx:583
 TGLScene.cxx:584
 TGLScene.cxx:585
 TGLScene.cxx:586
 TGLScene.cxx:587
 TGLScene.cxx:588
 TGLScene.cxx:589
 TGLScene.cxx:590
 TGLScene.cxx:591
 TGLScene.cxx:592
 TGLScene.cxx:593
 TGLScene.cxx:594
 TGLScene.cxx:595
 TGLScene.cxx:596
 TGLScene.cxx:597
 TGLScene.cxx:598
 TGLScene.cxx:599
 TGLScene.cxx:600
 TGLScene.cxx:601
 TGLScene.cxx:602
 TGLScene.cxx:603
 TGLScene.cxx:604
 TGLScene.cxx:605
 TGLScene.cxx:606
 TGLScene.cxx:607
 TGLScene.cxx:608
 TGLScene.cxx:609
 TGLScene.cxx:610
 TGLScene.cxx:611
 TGLScene.cxx:612
 TGLScene.cxx:613
 TGLScene.cxx:614
 TGLScene.cxx:615
 TGLScene.cxx:616
 TGLScene.cxx:617
 TGLScene.cxx:618
 TGLScene.cxx:619
 TGLScene.cxx:620
 TGLScene.cxx:621
 TGLScene.cxx:622
 TGLScene.cxx:623
 TGLScene.cxx:624
 TGLScene.cxx:625
 TGLScene.cxx:626
 TGLScene.cxx:627
 TGLScene.cxx:628
 TGLScene.cxx:629
 TGLScene.cxx:630
 TGLScene.cxx:631
 TGLScene.cxx:632
 TGLScene.cxx:633
 TGLScene.cxx:634
 TGLScene.cxx:635
 TGLScene.cxx:636
 TGLScene.cxx:637
 TGLScene.cxx:638
 TGLScene.cxx:639
 TGLScene.cxx:640
 TGLScene.cxx:641
 TGLScene.cxx:642
 TGLScene.cxx:643
 TGLScene.cxx:644
 TGLScene.cxx:645
 TGLScene.cxx:646
 TGLScene.cxx:647
 TGLScene.cxx:648
 TGLScene.cxx:649
 TGLScene.cxx:650
 TGLScene.cxx:651
 TGLScene.cxx:652
 TGLScene.cxx:653
 TGLScene.cxx:654
 TGLScene.cxx:655
 TGLScene.cxx:656
 TGLScene.cxx:657
 TGLScene.cxx:658
 TGLScene.cxx:659
 TGLScene.cxx:660
 TGLScene.cxx:661
 TGLScene.cxx:662
 TGLScene.cxx:663
 TGLScene.cxx:664
 TGLScene.cxx:665
 TGLScene.cxx:666
 TGLScene.cxx:667
 TGLScene.cxx:668
 TGLScene.cxx:669
 TGLScene.cxx:670
 TGLScene.cxx:671
 TGLScene.cxx:672
 TGLScene.cxx:673
 TGLScene.cxx:674
 TGLScene.cxx:675
 TGLScene.cxx:676
 TGLScene.cxx:677
 TGLScene.cxx:678
 TGLScene.cxx:679
 TGLScene.cxx:680
 TGLScene.cxx:681
 TGLScene.cxx:682
 TGLScene.cxx:683
 TGLScene.cxx:684
 TGLScene.cxx:685
 TGLScene.cxx:686
 TGLScene.cxx:687
 TGLScene.cxx:688
 TGLScene.cxx:689
 TGLScene.cxx:690
 TGLScene.cxx:691
 TGLScene.cxx:692
 TGLScene.cxx:693
 TGLScene.cxx:694
 TGLScene.cxx:695
 TGLScene.cxx:696
 TGLScene.cxx:697
 TGLScene.cxx:698
 TGLScene.cxx:699
 TGLScene.cxx:700
 TGLScene.cxx:701
 TGLScene.cxx:702
 TGLScene.cxx:703
 TGLScene.cxx:704
 TGLScene.cxx:705
 TGLScene.cxx:706
 TGLScene.cxx:707
 TGLScene.cxx:708
 TGLScene.cxx:709
 TGLScene.cxx:710
 TGLScene.cxx:711
 TGLScene.cxx:712
 TGLScene.cxx:713
 TGLScene.cxx:714
 TGLScene.cxx:715
 TGLScene.cxx:716
 TGLScene.cxx:717
 TGLScene.cxx:718
 TGLScene.cxx:719
 TGLScene.cxx:720
 TGLScene.cxx:721
 TGLScene.cxx:722
 TGLScene.cxx:723
 TGLScene.cxx:724
 TGLScene.cxx:725
 TGLScene.cxx:726
 TGLScene.cxx:727
 TGLScene.cxx:728
 TGLScene.cxx:729
 TGLScene.cxx:730
 TGLScene.cxx:731
 TGLScene.cxx:732
 TGLScene.cxx:733
 TGLScene.cxx:734
 TGLScene.cxx:735
 TGLScene.cxx:736
 TGLScene.cxx:737
 TGLScene.cxx:738
 TGLScene.cxx:739
 TGLScene.cxx:740
 TGLScene.cxx:741
 TGLScene.cxx:742
 TGLScene.cxx:743
 TGLScene.cxx:744
 TGLScene.cxx:745
 TGLScene.cxx:746
 TGLScene.cxx:747
 TGLScene.cxx:748
 TGLScene.cxx:749
 TGLScene.cxx:750
 TGLScene.cxx:751
 TGLScene.cxx:752
 TGLScene.cxx:753
 TGLScene.cxx:754
 TGLScene.cxx:755
 TGLScene.cxx:756
 TGLScene.cxx:757
 TGLScene.cxx:758
 TGLScene.cxx:759
 TGLScene.cxx:760
 TGLScene.cxx:761
 TGLScene.cxx:762
 TGLScene.cxx:763
 TGLScene.cxx:764
 TGLScene.cxx:765
 TGLScene.cxx:766
 TGLScene.cxx:767
 TGLScene.cxx:768
 TGLScene.cxx:769
 TGLScene.cxx:770
 TGLScene.cxx:771
 TGLScene.cxx:772
 TGLScene.cxx:773
 TGLScene.cxx:774
 TGLScene.cxx:775
 TGLScene.cxx:776
 TGLScene.cxx:777
 TGLScene.cxx:778
 TGLScene.cxx:779
 TGLScene.cxx:780
 TGLScene.cxx:781
 TGLScene.cxx:782
 TGLScene.cxx:783
 TGLScene.cxx:784
 TGLScene.cxx:785
 TGLScene.cxx:786
 TGLScene.cxx:787
 TGLScene.cxx:788
 TGLScene.cxx:789
 TGLScene.cxx:790
 TGLScene.cxx:791
 TGLScene.cxx:792
 TGLScene.cxx:793
 TGLScene.cxx:794
 TGLScene.cxx:795
 TGLScene.cxx:796
 TGLScene.cxx:797
 TGLScene.cxx:798
 TGLScene.cxx:799
 TGLScene.cxx:800
 TGLScene.cxx:801
 TGLScene.cxx:802
 TGLScene.cxx:803
 TGLScene.cxx:804
 TGLScene.cxx:805
 TGLScene.cxx:806
 TGLScene.cxx:807
 TGLScene.cxx:808
 TGLScene.cxx:809
 TGLScene.cxx:810
 TGLScene.cxx:811
 TGLScene.cxx:812
 TGLScene.cxx:813
 TGLScene.cxx:814
 TGLScene.cxx:815
 TGLScene.cxx:816
 TGLScene.cxx:817
 TGLScene.cxx:818
 TGLScene.cxx:819
 TGLScene.cxx:820
 TGLScene.cxx:821
 TGLScene.cxx:822
 TGLScene.cxx:823
 TGLScene.cxx:824
 TGLScene.cxx:825
 TGLScene.cxx:826
 TGLScene.cxx:827
 TGLScene.cxx:828
 TGLScene.cxx:829
 TGLScene.cxx:830
 TGLScene.cxx:831
 TGLScene.cxx:832
 TGLScene.cxx:833
 TGLScene.cxx:834
 TGLScene.cxx:835
 TGLScene.cxx:836
 TGLScene.cxx:837
 TGLScene.cxx:838
 TGLScene.cxx:839
 TGLScene.cxx:840
 TGLScene.cxx:841
 TGLScene.cxx:842
 TGLScene.cxx:843
 TGLScene.cxx:844
 TGLScene.cxx:845
 TGLScene.cxx:846
 TGLScene.cxx:847
 TGLScene.cxx:848
 TGLScene.cxx:849
 TGLScene.cxx:850
 TGLScene.cxx:851
 TGLScene.cxx:852
 TGLScene.cxx:853
 TGLScene.cxx:854
 TGLScene.cxx:855
 TGLScene.cxx:856
 TGLScene.cxx:857
 TGLScene.cxx:858
 TGLScene.cxx:859
 TGLScene.cxx:860
 TGLScene.cxx:861
 TGLScene.cxx:862
 TGLScene.cxx:863
 TGLScene.cxx:864
 TGLScene.cxx:865
 TGLScene.cxx:866
 TGLScene.cxx:867
 TGLScene.cxx:868
 TGLScene.cxx:869
 TGLScene.cxx:870
 TGLScene.cxx:871
 TGLScene.cxx:872
 TGLScene.cxx:873
 TGLScene.cxx:874
 TGLScene.cxx:875
 TGLScene.cxx:876
 TGLScene.cxx:877
 TGLScene.cxx:878
 TGLScene.cxx:879
 TGLScene.cxx:880
 TGLScene.cxx:881
 TGLScene.cxx:882
 TGLScene.cxx:883
 TGLScene.cxx:884
 TGLScene.cxx:885
 TGLScene.cxx:886
 TGLScene.cxx:887
 TGLScene.cxx:888
 TGLScene.cxx:889
 TGLScene.cxx:890
 TGLScene.cxx:891
 TGLScene.cxx:892
 TGLScene.cxx:893
 TGLScene.cxx:894
 TGLScene.cxx:895
 TGLScene.cxx:896
 TGLScene.cxx:897
 TGLScene.cxx:898
 TGLScene.cxx:899
 TGLScene.cxx:900
 TGLScene.cxx:901
 TGLScene.cxx:902
 TGLScene.cxx:903
 TGLScene.cxx:904
 TGLScene.cxx:905
 TGLScene.cxx:906
 TGLScene.cxx:907
 TGLScene.cxx:908
 TGLScene.cxx:909
 TGLScene.cxx:910
 TGLScene.cxx:911
 TGLScene.cxx:912
 TGLScene.cxx:913
 TGLScene.cxx:914
 TGLScene.cxx:915
 TGLScene.cxx:916
 TGLScene.cxx:917
 TGLScene.cxx:918
 TGLScene.cxx:919
 TGLScene.cxx:920
 TGLScene.cxx:921
 TGLScene.cxx:922
 TGLScene.cxx:923
 TGLScene.cxx:924
 TGLScene.cxx:925
 TGLScene.cxx:926
 TGLScene.cxx:927
 TGLScene.cxx:928
 TGLScene.cxx:929
 TGLScene.cxx:930
 TGLScene.cxx:931
 TGLScene.cxx:932
 TGLScene.cxx:933
 TGLScene.cxx:934
 TGLScene.cxx:935
 TGLScene.cxx:936
 TGLScene.cxx:937
 TGLScene.cxx:938
 TGLScene.cxx:939
 TGLScene.cxx:940
 TGLScene.cxx:941
 TGLScene.cxx:942
 TGLScene.cxx:943
 TGLScene.cxx:944
 TGLScene.cxx:945
 TGLScene.cxx:946
 TGLScene.cxx:947
 TGLScene.cxx:948
 TGLScene.cxx:949
 TGLScene.cxx:950
 TGLScene.cxx:951
 TGLScene.cxx:952
 TGLScene.cxx:953
 TGLScene.cxx:954
 TGLScene.cxx:955
 TGLScene.cxx:956
 TGLScene.cxx:957
 TGLScene.cxx:958
 TGLScene.cxx:959
 TGLScene.cxx:960
 TGLScene.cxx:961
 TGLScene.cxx:962
 TGLScene.cxx:963
 TGLScene.cxx:964
 TGLScene.cxx:965
 TGLScene.cxx:966
 TGLScene.cxx:967
 TGLScene.cxx:968
 TGLScene.cxx:969
 TGLScene.cxx:970
 TGLScene.cxx:971
 TGLScene.cxx:972
 TGLScene.cxx:973
 TGLScene.cxx:974
 TGLScene.cxx:975
 TGLScene.cxx:976
 TGLScene.cxx:977
 TGLScene.cxx:978
 TGLScene.cxx:979
 TGLScene.cxx:980
 TGLScene.cxx:981
 TGLScene.cxx:982
 TGLScene.cxx:983
 TGLScene.cxx:984
 TGLScene.cxx:985
 TGLScene.cxx:986
 TGLScene.cxx:987
 TGLScene.cxx:988
 TGLScene.cxx:989
 TGLScene.cxx:990
 TGLScene.cxx:991
 TGLScene.cxx:992
 TGLScene.cxx:993
 TGLScene.cxx:994
 TGLScene.cxx:995
 TGLScene.cxx:996
 TGLScene.cxx:997
 TGLScene.cxx:998
 TGLScene.cxx:999
 TGLScene.cxx:1000
 TGLScene.cxx:1001
 TGLScene.cxx:1002
 TGLScene.cxx:1003
 TGLScene.cxx:1004
 TGLScene.cxx:1005
 TGLScene.cxx:1006
 TGLScene.cxx:1007
 TGLScene.cxx:1008
 TGLScene.cxx:1009
 TGLScene.cxx:1010
 TGLScene.cxx:1011
 TGLScene.cxx:1012
 TGLScene.cxx:1013
 TGLScene.cxx:1014
 TGLScene.cxx:1015
 TGLScene.cxx:1016
 TGLScene.cxx:1017
 TGLScene.cxx:1018
 TGLScene.cxx:1019
 TGLScene.cxx:1020
 TGLScene.cxx:1021
 TGLScene.cxx:1022
 TGLScene.cxx:1023
 TGLScene.cxx:1024
 TGLScene.cxx:1025
 TGLScene.cxx:1026
 TGLScene.cxx:1027
 TGLScene.cxx:1028
 TGLScene.cxx:1029
 TGLScene.cxx:1030
 TGLScene.cxx:1031
 TGLScene.cxx:1032
 TGLScene.cxx:1033
 TGLScene.cxx:1034
 TGLScene.cxx:1035
 TGLScene.cxx:1036
 TGLScene.cxx:1037
 TGLScene.cxx:1038
 TGLScene.cxx:1039
 TGLScene.cxx:1040
 TGLScene.cxx:1041
 TGLScene.cxx:1042
 TGLScene.cxx:1043
 TGLScene.cxx:1044
 TGLScene.cxx:1045
 TGLScene.cxx:1046
 TGLScene.cxx:1047
 TGLScene.cxx:1048
 TGLScene.cxx:1049
 TGLScene.cxx:1050
 TGLScene.cxx:1051
 TGLScene.cxx:1052
 TGLScene.cxx:1053
 TGLScene.cxx:1054
 TGLScene.cxx:1055
 TGLScene.cxx:1056
 TGLScene.cxx:1057
 TGLScene.cxx:1058
 TGLScene.cxx:1059
 TGLScene.cxx:1060
 TGLScene.cxx:1061
 TGLScene.cxx:1062
 TGLScene.cxx:1063
 TGLScene.cxx:1064
 TGLScene.cxx:1065
 TGLScene.cxx:1066
 TGLScene.cxx:1067
 TGLScene.cxx:1068
 TGLScene.cxx:1069
 TGLScene.cxx:1070
 TGLScene.cxx:1071
 TGLScene.cxx:1072
 TGLScene.cxx:1073
 TGLScene.cxx:1074
 TGLScene.cxx:1075
 TGLScene.cxx:1076
 TGLScene.cxx:1077
 TGLScene.cxx:1078
 TGLScene.cxx:1079
 TGLScene.cxx:1080
 TGLScene.cxx:1081
 TGLScene.cxx:1082
 TGLScene.cxx:1083
 TGLScene.cxx:1084
 TGLScene.cxx:1085
 TGLScene.cxx:1086
 TGLScene.cxx:1087
 TGLScene.cxx:1088
 TGLScene.cxx:1089
 TGLScene.cxx:1090
 TGLScene.cxx:1091
 TGLScene.cxx:1092
 TGLScene.cxx:1093
 TGLScene.cxx:1094
 TGLScene.cxx:1095
 TGLScene.cxx:1096
 TGLScene.cxx:1097
 TGLScene.cxx:1098
 TGLScene.cxx:1099
 TGLScene.cxx:1100
 TGLScene.cxx:1101
 TGLScene.cxx:1102
 TGLScene.cxx:1103
 TGLScene.cxx:1104
 TGLScene.cxx:1105
 TGLScene.cxx:1106
 TGLScene.cxx:1107
 TGLScene.cxx:1108
 TGLScene.cxx:1109
 TGLScene.cxx:1110
 TGLScene.cxx:1111
 TGLScene.cxx:1112
 TGLScene.cxx:1113
 TGLScene.cxx:1114
 TGLScene.cxx:1115
 TGLScene.cxx:1116
 TGLScene.cxx:1117
 TGLScene.cxx:1118
 TGLScene.cxx:1119
 TGLScene.cxx:1120
 TGLScene.cxx:1121
 TGLScene.cxx:1122
 TGLScene.cxx:1123
 TGLScene.cxx:1124
 TGLScene.cxx:1125
 TGLScene.cxx:1126
 TGLScene.cxx:1127
 TGLScene.cxx:1128
 TGLScene.cxx:1129
 TGLScene.cxx:1130
 TGLScene.cxx:1131
 TGLScene.cxx:1132
 TGLScene.cxx:1133
 TGLScene.cxx:1134
 TGLScene.cxx:1135
 TGLScene.cxx:1136
 TGLScene.cxx:1137
 TGLScene.cxx:1138
 TGLScene.cxx:1139
 TGLScene.cxx:1140
 TGLScene.cxx:1141
 TGLScene.cxx:1142
 TGLScene.cxx:1143
 TGLScene.cxx:1144
 TGLScene.cxx:1145
 TGLScene.cxx:1146
 TGLScene.cxx:1147
 TGLScene.cxx:1148
 TGLScene.cxx:1149
 TGLScene.cxx:1150
 TGLScene.cxx:1151
 TGLScene.cxx:1152
 TGLScene.cxx:1153
 TGLScene.cxx:1154
 TGLScene.cxx:1155
 TGLScene.cxx:1156
 TGLScene.cxx:1157
 TGLScene.cxx:1158
 TGLScene.cxx:1159
 TGLScene.cxx:1160
 TGLScene.cxx:1161
 TGLScene.cxx:1162
 TGLScene.cxx:1163
 TGLScene.cxx:1164
 TGLScene.cxx:1165
 TGLScene.cxx:1166
 TGLScene.cxx:1167
 TGLScene.cxx:1168
 TGLScene.cxx:1169
 TGLScene.cxx:1170
 TGLScene.cxx:1171
 TGLScene.cxx:1172
 TGLScene.cxx:1173
 TGLScene.cxx:1174
 TGLScene.cxx:1175
 TGLScene.cxx:1176
 TGLScene.cxx:1177
 TGLScene.cxx:1178
 TGLScene.cxx:1179
 TGLScene.cxx:1180
 TGLScene.cxx:1181
 TGLScene.cxx:1182
 TGLScene.cxx:1183
 TGLScene.cxx:1184
 TGLScene.cxx:1185
 TGLScene.cxx:1186
 TGLScene.cxx:1187
 TGLScene.cxx:1188
 TGLScene.cxx:1189
 TGLScene.cxx:1190
 TGLScene.cxx:1191
 TGLScene.cxx:1192
 TGLScene.cxx:1193
 TGLScene.cxx:1194
 TGLScene.cxx:1195
 TGLScene.cxx:1196
 TGLScene.cxx:1197
 TGLScene.cxx:1198
 TGLScene.cxx:1199
 TGLScene.cxx:1200
 TGLScene.cxx:1201
 TGLScene.cxx:1202
 TGLScene.cxx:1203
 TGLScene.cxx:1204
 TGLScene.cxx:1205
 TGLScene.cxx:1206
 TGLScene.cxx:1207
 TGLScene.cxx:1208
 TGLScene.cxx:1209
 TGLScene.cxx:1210
 TGLScene.cxx:1211
 TGLScene.cxx:1212
 TGLScene.cxx:1213
 TGLScene.cxx:1214
 TGLScene.cxx:1215
 TGLScene.cxx:1216
 TGLScene.cxx:1217
 TGLScene.cxx:1218
 TGLScene.cxx:1219
 TGLScene.cxx:1220
 TGLScene.cxx:1221
 TGLScene.cxx:1222
 TGLScene.cxx:1223
 TGLScene.cxx:1224
 TGLScene.cxx:1225
 TGLScene.cxx:1226
 TGLScene.cxx:1227
 TGLScene.cxx:1228
 TGLScene.cxx:1229
 TGLScene.cxx:1230
 TGLScene.cxx:1231
 TGLScene.cxx:1232
 TGLScene.cxx:1233
 TGLScene.cxx:1234
 TGLScene.cxx:1235
 TGLScene.cxx:1236
 TGLScene.cxx:1237
 TGLScene.cxx:1238
 TGLScene.cxx:1239
 TGLScene.cxx:1240
 TGLScene.cxx:1241
 TGLScene.cxx:1242
 TGLScene.cxx:1243
 TGLScene.cxx:1244
 TGLScene.cxx:1245
 TGLScene.cxx:1246
 TGLScene.cxx:1247
 TGLScene.cxx:1248
 TGLScene.cxx:1249
 TGLScene.cxx:1250
 TGLScene.cxx:1251
 TGLScene.cxx:1252
 TGLScene.cxx:1253
 TGLScene.cxx:1254
 TGLScene.cxx:1255
 TGLScene.cxx:1256
 TGLScene.cxx:1257
 TGLScene.cxx:1258
 TGLScene.cxx:1259
 TGLScene.cxx:1260
 TGLScene.cxx:1261
 TGLScene.cxx:1262
 TGLScene.cxx:1263
 TGLScene.cxx:1264
 TGLScene.cxx:1265
 TGLScene.cxx:1266
 TGLScene.cxx:1267
 TGLScene.cxx:1268
 TGLScene.cxx:1269
 TGLScene.cxx:1270
 TGLScene.cxx:1271
 TGLScene.cxx:1272
 TGLScene.cxx:1273
 TGLScene.cxx:1274
 TGLScene.cxx:1275
 TGLScene.cxx:1276
 TGLScene.cxx:1277
 TGLScene.cxx:1278
 TGLScene.cxx:1279
 TGLScene.cxx:1280
 TGLScene.cxx:1281
 TGLScene.cxx:1282
 TGLScene.cxx:1283
 TGLScene.cxx:1284
 TGLScene.cxx:1285
 TGLScene.cxx:1286
 TGLScene.cxx:1287
 TGLScene.cxx:1288
 TGLScene.cxx:1289
 TGLScene.cxx:1290
 TGLScene.cxx:1291
 TGLScene.cxx:1292
 TGLScene.cxx:1293
 TGLScene.cxx:1294
 TGLScene.cxx:1295
 TGLScene.cxx:1296
 TGLScene.cxx:1297
 TGLScene.cxx:1298
 TGLScene.cxx:1299
 TGLScene.cxx:1300
 TGLScene.cxx:1301
 TGLScene.cxx:1302
 TGLScene.cxx:1303
 TGLScene.cxx:1304
 TGLScene.cxx:1305
 TGLScene.cxx:1306
 TGLScene.cxx:1307
 TGLScene.cxx:1308
 TGLScene.cxx:1309
 TGLScene.cxx:1310
 TGLScene.cxx:1311
 TGLScene.cxx:1312
 TGLScene.cxx:1313
 TGLScene.cxx:1314
 TGLScene.cxx:1315
 TGLScene.cxx:1316
 TGLScene.cxx:1317
 TGLScene.cxx:1318
 TGLScene.cxx:1319
 TGLScene.cxx:1320
 TGLScene.cxx:1321
 TGLScene.cxx:1322
 TGLScene.cxx:1323
 TGLScene.cxx:1324
 TGLScene.cxx:1325
 TGLScene.cxx:1326
 TGLScene.cxx:1327
 TGLScene.cxx:1328
 TGLScene.cxx:1329
 TGLScene.cxx:1330
 TGLScene.cxx:1331
 TGLScene.cxx:1332
 TGLScene.cxx:1333
 TGLScene.cxx:1334
 TGLScene.cxx:1335
 TGLScene.cxx:1336
 TGLScene.cxx:1337
 TGLScene.cxx:1338
 TGLScene.cxx:1339
 TGLScene.cxx:1340
 TGLScene.cxx:1341
 TGLScene.cxx:1342
 TGLScene.cxx:1343
 TGLScene.cxx:1344
 TGLScene.cxx:1345
 TGLScene.cxx:1346
 TGLScene.cxx:1347
 TGLScene.cxx:1348
 TGLScene.cxx:1349
 TGLScene.cxx:1350
 TGLScene.cxx:1351
 TGLScene.cxx:1352
 TGLScene.cxx:1353
 TGLScene.cxx:1354
 TGLScene.cxx:1355
 TGLScene.cxx:1356
 TGLScene.cxx:1357
 TGLScene.cxx:1358
 TGLScene.cxx:1359
 TGLScene.cxx:1360
 TGLScene.cxx:1361
 TGLScene.cxx:1362
 TGLScene.cxx:1363
 TGLScene.cxx:1364
 TGLScene.cxx:1365
 TGLScene.cxx:1366
 TGLScene.cxx:1367
 TGLScene.cxx:1368
 TGLScene.cxx:1369
 TGLScene.cxx:1370
 TGLScene.cxx:1371
 TGLScene.cxx:1372
 TGLScene.cxx:1373
 TGLScene.cxx:1374
 TGLScene.cxx:1375
 TGLScene.cxx:1376
 TGLScene.cxx:1377
 TGLScene.cxx:1378
 TGLScene.cxx:1379
 TGLScene.cxx:1380
 TGLScene.cxx:1381
 TGLScene.cxx:1382
 TGLScene.cxx:1383
 TGLScene.cxx:1384
 TGLScene.cxx:1385
 TGLScene.cxx:1386
 TGLScene.cxx:1387
 TGLScene.cxx:1388
 TGLScene.cxx:1389
 TGLScene.cxx:1390
 TGLScene.cxx:1391
 TGLScene.cxx:1392
 TGLScene.cxx:1393
 TGLScene.cxx:1394
 TGLScene.cxx:1395
 TGLScene.cxx:1396
 TGLScene.cxx:1397
 TGLScene.cxx:1398
 TGLScene.cxx:1399
 TGLScene.cxx:1400
 TGLScene.cxx:1401
 TGLScene.cxx:1402
 TGLScene.cxx:1403
 TGLScene.cxx:1404
 TGLScene.cxx:1405
 TGLScene.cxx:1406
 TGLScene.cxx:1407
 TGLScene.cxx:1408
 TGLScene.cxx:1409
 TGLScene.cxx:1410
 TGLScene.cxx:1411
 TGLScene.cxx:1412
 TGLScene.cxx:1413
 TGLScene.cxx:1414
 TGLScene.cxx:1415
 TGLScene.cxx:1416
 TGLScene.cxx:1417
 TGLScene.cxx:1418
 TGLScene.cxx:1419
 TGLScene.cxx:1420
 TGLScene.cxx:1421
 TGLScene.cxx:1422
 TGLScene.cxx:1423
 TGLScene.cxx:1424
 TGLScene.cxx:1425
 TGLScene.cxx:1426
 TGLScene.cxx:1427
 TGLScene.cxx:1428
 TGLScene.cxx:1429
 TGLScene.cxx:1430
 TGLScene.cxx:1431
 TGLScene.cxx:1432
 TGLScene.cxx:1433
 TGLScene.cxx:1434
 TGLScene.cxx:1435
 TGLScene.cxx:1436
 TGLScene.cxx:1437
 TGLScene.cxx:1438
 TGLScene.cxx:1439
 TGLScene.cxx:1440
 TGLScene.cxx:1441
 TGLScene.cxx:1442
 TGLScene.cxx:1443
 TGLScene.cxx:1444
 TGLScene.cxx:1445
 TGLScene.cxx:1446
 TGLScene.cxx:1447
 TGLScene.cxx:1448
 TGLScene.cxx:1449
 TGLScene.cxx:1450
 TGLScene.cxx:1451
 TGLScene.cxx:1452
 TGLScene.cxx:1453
 TGLScene.cxx:1454
 TGLScene.cxx:1455
 TGLScene.cxx:1456
 TGLScene.cxx:1457
 TGLScene.cxx:1458
 TGLScene.cxx:1459
 TGLScene.cxx:1460
 TGLScene.cxx:1461
 TGLScene.cxx:1462
 TGLScene.cxx:1463
 TGLScene.cxx:1464
 TGLScene.cxx:1465
 TGLScene.cxx:1466
 TGLScene.cxx:1467
 TGLScene.cxx:1468
 TGLScene.cxx:1469
 TGLScene.cxx:1470
 TGLScene.cxx:1471
 TGLScene.cxx:1472
 TGLScene.cxx:1473
 TGLScene.cxx:1474
 TGLScene.cxx:1475
 TGLScene.cxx:1476