// @(#)root/gl:$Id$
// Author:  Timur Pocheptsov  31/08/2006

/*************************************************************************
 * Copyright (C) 1995-2006, 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 <typeinfo>

#include "TVirtualGL.h"
#include "KeySymbols.h"
#include "TVirtualX.h"
#include "Buttons.h"
#include "TString.h"
#include "TROOT.h"
#include "TColor.h"
#include "TMath.h"
#include "TH3.h"
#include "TF3.h"

#include "TGLMarchingCubes.h"
#include "TGLPlotCamera.h"
#include "TGLTF3Painter.h"
#include "TGLIncludes.h"

//______________________________________________________________________________
//
// Plot-painter for TF3 functions.

ClassImp(TGLTF3Painter)

//______________________________________________________________________________
TGLTF3Painter::TGLTF3Painter(TF3 *fun, TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
                  : TGLPlotPainter(hist, camera, coord, kFALSE, kFALSE, kFALSE),
                    fStyle(kDefault),
                    fF3(fun),
                    fXOZSlice("XOZ", (TH3 *)hist, fun, coord, &fBackBox, TGLTH3Slice::kXOZ),
                    fYOZSlice("YOZ", (TH3 *)hist, fun, coord, &fBackBox, TGLTH3Slice::kYOZ),
                    fXOYSlice("XOY", (TH3 *)hist, fun, coord, &fBackBox, TGLTH3Slice::kXOY)
{
   // Constructor.
}

//______________________________________________________________________________
char *TGLTF3Painter::GetPlotInfo(Int_t /*px*/, Int_t /*py*/)
{
   //Coords for point on surface under cursor.
   static char mess[] = { "fun3" };
   return mess;
}

//______________________________________________________________________________
Bool_t TGLTF3Painter::InitGeometry()
{
   //Create mesh.
   fCoord->SetCoordType(kGLCartesian);

   if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))
      return kFALSE;

   fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
   if (fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());

   //Build mesh for TF3 surface
   fMesh.ClearMesh();

   Rgl::Mc::TMeshBuilder<TF3, Double_t> builder(kFALSE);//no averaged normals.
   //Set grid parameters.
   Rgl::Mc::TGridGeometry<Double_t> geom(fXAxis, fYAxis, fZAxis, fCoord->GetXScale(),
                                         fCoord->GetYScale(), fCoord->GetZScale(),
                                         Rgl::Mc::TGridGeometry<Double_t>::kBinEdge);

   builder.BuildMesh(fF3, geom, &fMesh, 0.2);

   if (fCoord->Modified()) {
      fUpdateSelection = kTRUE;
      const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
      fXOZSectionPos = vertex.Y();
      fYOZSectionPos = vertex.X();
      fXOYSectionPos = vertex.Z();
      fCoord->ResetModified();
   }

   return kTRUE;
}

//______________________________________________________________________________
void TGLTF3Painter::StartPan(Int_t px, Int_t py)
{
   //User clicks right mouse button (in a pad).
   fMousePosition.fX = px;
   fMousePosition.fY = fCamera->GetHeight() - py;
   fCamera->StartPan(px, py);
   fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
}

//______________________________________________________________________________
void TGLTF3Painter::Pan(Int_t px, Int_t py)
{
   //User's moving mouse cursor, with middle mouse button pressed (for pad).
   //Calculate 3d shift related to 2d mouse movement.
   //Slicing is disabled (since somebody has broken it).
   if (fSelectedPart >= fSelectionBase) {//Pan camera.
      SaveModelviewMatrix();
      SaveProjectionMatrix();

      fCamera->SetCamera();
      fCamera->Apply(fPadPhi, fPadTheta);
      fCamera->Pan(px, py);

      RestoreProjectionMatrix();
      RestoreModelviewMatrix();
   } else if (fSelectedPart > 0) {
      //Convert py into bottom-top orientation.
      //Possibly, move box here
      py = fCamera->GetHeight() - py;

      SaveModelviewMatrix();
      SaveProjectionMatrix();

      fCamera->SetCamera();
      fCamera->Apply(fPadPhi, fPadTheta);

      if (!fHighColor) {
         if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis)) {
            fBoxCut.MoveBox(px, py, fSelectedPart);
         } else {
            //MoveSection(px, py);
         }
      } else {
         //MoveSection(px, py);
      }

      RestoreProjectionMatrix();
      RestoreModelviewMatrix();
   }

   fMousePosition.fX = px, fMousePosition.fY = py;
   fUpdateSelection = kTRUE;
}

//______________________________________________________________________________
void TGLTF3Painter::AddOption(const TString &/*option*/)
{
   //No options for tf3
}

//______________________________________________________________________________
void TGLTF3Painter::ProcessEvent(Int_t event, Int_t /*px*/, Int_t py)
{
   //Change color sheme.
   if (event == kKeyPress) {
      if (py == kKey_s || py == kKey_S) {
         fStyle < kMaple2 ? fStyle = ETF3Style(fStyle + 1) : fStyle = kDefault;
      } else if (py == kKey_c || py == kKey_C) {
         if (fHighColor)
            Info("ProcessEvent", "Cut box does not work in high color, please, switch to true color");
         else {
            fBoxCut.TurnOnOff();
            fUpdateSelection = kTRUE;
         }
      }
   } else if (event == kButton1Double && (fBoxCut.IsActive() || HasSections())) {
      if (fBoxCut.IsActive())
         fBoxCut.TurnOnOff();
      const TGLVertex3 *frame = fBackBox.Get3DBox();
      fXOZSectionPos = frame[0].Y();
      fYOZSectionPos = frame[0].X();
      fXOYSectionPos = frame[0].Z();

      if (!gVirtualX->IsCmdThread())
         gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%lx)->Paint()", (ULong_t)this));
      else
         Paint();
   }
}

//______________________________________________________________________________
void TGLTF3Painter::InitGL() const
{
   //Initialize OpenGL state variables.
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glEnable(GL_DEPTH_TEST);
   glDisable(GL_CULL_FACE);
   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
}

//______________________________________________________________________________
void TGLTF3Painter::DeInitGL() const
{
   //Initialize OpenGL state variables.
   glDisable(GL_LIGHTING);
   glDisable(GL_LIGHT0);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_CULL_FACE);
   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
}

//______________________________________________________________________________
void TGLTF3Painter::DrawToSelectionBuffer() const
{
   //Draw triangles, no normals, no lighting.
   Rgl::ObjectIDToColor(fSelectionBase, fHighColor);

   if (!fBoxCut.IsActive())
      Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris);
   else
      Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris, fBoxCut);
}

//______________________________________________________________________________
void TGLTF3Painter::DrawDefaultPlot() const
{
   //Surface with material properties and lighting.
   if (HasSections()) {
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glDepthMask(GL_FALSE);
   }

   SetSurfaceColor();

   if (!fBoxCut.IsActive()) {
      Rgl::DrawMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris);
   } else {
      Rgl::DrawMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris, fBoxCut);
   }

   if (HasSections()) {
      glDisable(GL_BLEND);
      glDepthMask(GL_TRUE);
   }
}

//______________________________________________________________________________
void TGLTF3Painter::DrawMaplePlot() const
{
   //Colored surface, without lighting and
   //material properties.
   const TGLDisableGuard lightGuard(GL_LIGHTING);

   if (HasSections() && fStyle < kMaple2) {
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glDepthMask(GL_FALSE);
   }

   if (fStyle == kMaple1) {//Shaded polygons and outlines.
      glEnable(GL_POLYGON_OFFSET_FILL);//[1
      glPolygonOffset(1.f, 1.f);
   } else if (fStyle == kMaple2)//Colored outlines only.
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//[2

   if(!fBoxCut.IsActive())
      Rgl::DrawMapleMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris);
   else
      Rgl::DrawMapleMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris, fBoxCut);

   if (fStyle == kMaple1) {
      //Draw outlines.
      glDisable(GL_POLYGON_OFFSET_FILL);//1]
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//[3
      glColor4d(0., 0., 0., 0.25);

      if(!fBoxCut.IsActive())
         Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris);
      else
         Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris, fBoxCut);

      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);//[3
   } else if (fStyle == kMaple2)
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

   if (HasSections() && fStyle < kMaple2) {
      glDisable(GL_BLEND);
      glDepthMask(GL_TRUE);
   }
}

//______________________________________________________________________________
void TGLTF3Painter::DrawPlot() const
{
   //Draw mesh.

   //Shift plot to point of origin.
   const Rgl::PlotTranslation trGuard(this);

   fBackBox.DrawBox(fSelectedPart, fSelectionPass, fZLevels, fHighColor);
   DrawSections();

   if (fSelectionPass) {
      DrawToSelectionBuffer();
   } else if (fStyle == kDefault) {
      DrawDefaultPlot();
   } else {
      DrawMaplePlot();
   }

   if (fBoxCut.IsActive())
      fBoxCut.DrawBox(fSelectionPass, fSelectedPart);
}

//______________________________________________________________________________
void TGLTF3Painter::SetSurfaceColor() const
{
   //Set color for surface.
   Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.15f};

   if (fF3->GetFillColor() != kWhite)
      if (const TColor *c = gROOT->GetColor(fF3->GetFillColor()))
         c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);

   glMaterialfv(GL_BACK, GL_DIFFUSE, diffColor);
   diffColor[0] /= 2, diffColor[1] /= 2, diffColor[2] /= 2;
   glMaterialfv(GL_FRONT, GL_DIFFUSE, diffColor);
   const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
}

//______________________________________________________________________________
Bool_t TGLTF3Painter::HasSections() const
{
   //Any section exists.
   return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() ||
          fYOZSectionPos > fBackBox.Get3DBox()[0].X() ||
          fXOYSectionPos > fBackBox.Get3DBox()[0].Z();
}

//______________________________________________________________________________
void TGLTF3Painter::DrawSectionXOZ() const
{
   // Draw XOZ parallel section.
   if (fSelectionPass)
      return;
   fXOZSlice.DrawSlice(fXOZSectionPos / fCoord->GetYScale());
}

//______________________________________________________________________________
void TGLTF3Painter::DrawSectionYOZ() const
{
   // Draw YOZ parallel section.
   if (fSelectionPass)
      return;
   fYOZSlice.DrawSlice(fYOZSectionPos / fCoord->GetXScale());
}

//______________________________________________________________________________
void TGLTF3Painter::DrawSectionXOY() const
{
   // Draw XOY parallel section.
   if (fSelectionPass)
      return;
   fXOYSlice.DrawSlice(fXOYSectionPos / fCoord->GetZScale());
}


//______________________________________________________________________________
//
// "gliso" option for TH3.

ClassImp(TGLIsoPainter)

//______________________________________________________________________________
TGLIsoPainter::TGLIsoPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
                  : TGLPlotPainter(hist, camera, coord, kFALSE, kFALSE, kFALSE),
                    fXOZSlice("XOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOZ),
                    fYOZSlice("YOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kYOZ),
                    fXOYSlice("XOY", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOY),
                    fInit(kFALSE)
{
   //Constructor.
   if (hist->GetDimension() < 3)
      Error("TGLIsoPainter::TGLIsoPainter", "Wrong type of histogramm, must have 3 dimensions");
}

//______________________________________________________________________________
char *TGLIsoPainter::GetPlotInfo(Int_t /*px*/, Int_t /*py*/)
{
   //Return info for plot part under cursor.

   static char mess[] = { "iso" };
   return mess;
}

//______________________________________________________________________________
Bool_t TGLIsoPainter::InitGeometry()
{
   //Initializes meshes for 3d iso contours.
   if (fHist->GetDimension() < 3) {
      Error("TGLIsoPainter::TGLIsoPainter", "Wrong type of histogramm, must have 3 dimensions");
      return kFALSE;
   }

   //Create mesh.
   if (fInit)
      return kTRUE;

   //Only in cartesian.
   fCoord->SetCoordType(kGLCartesian);
   if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))
      return kFALSE;

   fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
   if (fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());

   //Move old meshes into the cache.
   if (!fIsos.empty())
      fCache.splice(fCache.begin(), fIsos);
   //Number of contours == number of iso surfaces.
   UInt_t nContours = fHist->GetContour();

   if (nContours > 1) {
      fColorLevels.resize(nContours);
      FindMinMax();

      if (fHist->TestBit(TH1::kUserContour)) {
         //There are user defined contours (iso-levels).
         for (UInt_t i = 0; i < nContours; ++i)
            fColorLevels[i] = fHist->GetContourLevelPad(i);
      } else {
         //Equidistant iso-surfaces.
         const Double_t isoStep = (fMinMax.second - fMinMax.first) / nContours;
         for (UInt_t i = 0; i < nContours; ++i)
            fColorLevels[i] = fMinMax.first + i * isoStep;
      }

      fPalette.GeneratePalette(nContours, fMinMax, kFALSE);
   } else {
      //Only one iso (ROOT's standard).
      fColorLevels.resize(nContours = 1);
      fColorLevels[0] = fHist->GetSumOfWeights() / (fHist->GetNbinsX() * fHist->GetNbinsY() * fHist->GetNbinsZ());
   }

   MeshIter_t firstMesh = fCache.begin();
   //Initialize meshes, trying to reuse mesh from
   //mesh cache.
   for (UInt_t i = 0; i < nContours; ++i) {
      if (firstMesh != fCache.end()) {
         //There is a mesh in a chache.
         SetMesh(*firstMesh, fColorLevels[i]);
         MeshIter_t next = firstMesh;
         ++next;
         fIsos.splice(fIsos.begin(), fCache, firstMesh);
         firstMesh = next;
      } else {
         //No meshes in a cache.
         //Create new one and _swap_ data (look at Mesh_t::Swap in a header)
         //between empty mesh in a list and this mesh
         //to avoid real copying.
         Mesh_t newMesh;
         SetMesh(newMesh, fColorLevels[i]);
         fIsos.push_back(fDummyMesh);
         fIsos.back().Swap(newMesh);
      }
   }

   if (fCoord->Modified()) {
      fUpdateSelection = kTRUE;
      fXOZSectionPos = fBackBox.Get3DBox()[0].Y();
      fYOZSectionPos = fBackBox.Get3DBox()[0].X();
      fXOYSectionPos = fBackBox.Get3DBox()[0].Z();
      fCoord->ResetModified();
   }

   //Avoid rebuilding the mesh.
   fInit = kTRUE;

   return kTRUE;

}

//______________________________________________________________________________
void TGLIsoPainter::StartPan(Int_t px, Int_t py)
{
   //User clicks right mouse button (in a pad).
   fMousePosition.fX = px;
   fMousePosition.fY = fCamera->GetHeight() - py;
   fCamera->StartPan(px, py);
   fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
}

//______________________________________________________________________________
void TGLIsoPainter::Pan(Int_t px, Int_t py)
{
   //User's moving mouse cursor, with middle mouse button pressed (for pad).
   //Calculate 3d shift related to 2d mouse movement.
   //User's moving mouse cursor, with middle mouse button pressed (for pad).
   //Calculate 3d shift related to 2d mouse movement.
   if (fSelectedPart >= fSelectionBase) {//Pan camera.
      SaveModelviewMatrix();
      SaveProjectionMatrix();

      fCamera->SetCamera();
      fCamera->Apply(fPadPhi, fPadTheta);
      fCamera->Pan(px, py);

      RestoreProjectionMatrix();
      RestoreModelviewMatrix();
   } else if (fSelectedPart > 0) {
      //Convert py into bottom-top orientation.
      //Possibly, move box here
      py = fCamera->GetHeight() - py;

      SaveModelviewMatrix();
      SaveProjectionMatrix();

      fCamera->SetCamera();
      fCamera->Apply(fPadPhi, fPadTheta);

      if (!fHighColor) {
         if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis)) {
            fBoxCut.MoveBox(px, py, fSelectedPart);
         } else {
            //MoveSection(px, py);
         }
      } else {
         //MoveSection(px, py);
      }

      RestoreProjectionMatrix();
      RestoreModelviewMatrix();

   }

   fMousePosition.fX = px, fMousePosition.fY = py;
   fUpdateSelection = kTRUE;
}

//______________________________________________________________________________
void TGLIsoPainter::AddOption(const TString &/*option*/)
{
   //No additional options for TGLIsoPainter.
}

//______________________________________________________________________________
void TGLIsoPainter::ProcessEvent(Int_t event, Int_t /*px*/, Int_t py)
{
   //Change color sheme.
   if (event == kKeyPress) {
      if (py == kKey_c || py == kKey_C) {
         if (fHighColor)
            Info("ProcessEvent", "Cut box does not work in high color, please, switch to true color");
         else {
            fBoxCut.TurnOnOff();
            fUpdateSelection = kTRUE;
         }
      }
   } else if (event == kButton1Double && (fBoxCut.IsActive() || HasSections())) {
      if (fBoxCut.IsActive())
         fBoxCut.TurnOnOff();
      const TGLVertex3 *frame = fBackBox.Get3DBox();
      fXOZSectionPos = frame[0].Y();
      fYOZSectionPos = frame[0].X();
      fXOYSectionPos = frame[0].Z();

      if (!gVirtualX->IsCmdThread())
         gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%lx)->Paint()", (ULong_t)this));
      else
         Paint();
   }
}

//______________________________________________________________________________
void TGLIsoPainter::InitGL() const
{
   //Initialize OpenGL state variables.
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glEnable(GL_DEPTH_TEST);
   glDisable(GL_CULL_FACE);
   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
}

//______________________________________________________________________________
void TGLIsoPainter::DeInitGL() const
{
   //Initialize OpenGL state variables.
   glDisable(GL_LIGHTING);
   glDisable(GL_LIGHT0);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_CULL_FACE);
   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
}

//______________________________________________________________________________
void TGLIsoPainter::DrawPlot() const
{
   //Draw mesh.

   //Shift plot to point of origin.
   const Rgl::PlotTranslation trGuard(this);


   fBackBox.DrawBox(fSelectedPart, fSelectionPass, fZLevels, fHighColor);
   DrawSections();

   if (fIsos.size() != fColorLevels.size()) {
      Error("TGLIsoPainter::DrawPlot", "Non-equal number of levels and isos");
      return;
   }

   if (!fSelectionPass && HasSections()) {
      //Surface is semi-transparent during dynamic profiling.
      //Having several complex nested surfaces, it's not easy
      //(possible?) to implement correct and _efficient_ transparency
      //drawing. So, artefacts are possbile.
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glDepthMask(GL_FALSE);
   }

   UInt_t colorInd = 0;
   ConstMeshIter_t iso = fIsos.begin();

   for (; iso != fIsos.end(); ++iso, ++colorInd)
      DrawMesh(*iso, colorInd);

   if (!fSelectionPass && HasSections()) {
      glDisable(GL_BLEND);
      glDepthMask(GL_TRUE);
   }

   if (fBoxCut.IsActive())
      fBoxCut.DrawBox(fSelectionPass, fSelectedPart);
}

//______________________________________________________________________________
void TGLIsoPainter::DrawSectionXOZ() const
{
   // Draw XOZ parallel section.
   if (fSelectionPass)
      return;
   fXOZSlice.DrawSlice(fXOZSectionPos / fCoord->GetYScale());
}

//______________________________________________________________________________
void TGLIsoPainter::DrawSectionYOZ() const
{
   // Draw YOZ parallel section.
   if (fSelectionPass)
      return;
   fYOZSlice.DrawSlice(fYOZSectionPos / fCoord->GetXScale());
}

//______________________________________________________________________________
void TGLIsoPainter::DrawSectionXOY() const
{
   // Draw XOY parallel section.
   if (fSelectionPass)
      return;
   fXOYSlice.DrawSlice(fXOYSectionPos / fCoord->GetZScale());
}

//______________________________________________________________________________
Bool_t TGLIsoPainter::HasSections() const
{
   //Any section exists.
   return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos > fBackBox.Get3DBox()[0].X() ||
          fXOYSectionPos > fBackBox.Get3DBox()[0].Z();
}

//______________________________________________________________________________
void TGLIsoPainter::SetSurfaceColor(Int_t ind) const
{
   //Set color for surface.
   Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.25f};

   if (fColorLevels.size() == 1) {
      if (fHist->GetFillColor() != kWhite)
         if (const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
            c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
   } else {
      const UChar_t *color = fPalette.GetColour(ind);
      diffColor[0] = color[0] / 255.;
      diffColor[1] = color[1] / 255.;
      diffColor[2] = color[2] / 255.;
   }

   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
   const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
   diffColor[0] /= 3.5, diffColor[1] /= 3.5, diffColor[2] /= 3.5;
   glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, diffColor);
   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 30.f);
}

//______________________________________________________________________________
void TGLIsoPainter::SetMesh(Mesh_t &m, Double_t isoValue)
{
   //Grid geometry.
   Rgl::Mc::TGridGeometry<Float_t> geom(fXAxis, fYAxis, fZAxis, fCoord->GetXScale(),
                                        fCoord->GetYScale(), fCoord->GetZScale());
   //Clear mesh if it was from cache.
   m.ClearMesh();
   //Select correct TMeshBuilder type.
   if (typeid(*fHist) == typeid(TH3C)) {
      Rgl::Mc::TMeshBuilder<TH3C, Float_t> builder(kTRUE);
      builder.BuildMesh(static_cast<TH3C *>(fHist), geom, &m, isoValue);
   } else if (typeid(*fHist) == typeid(TH3S)) {
      Rgl::Mc::TMeshBuilder<TH3S, Float_t> builder(kTRUE);
      builder.BuildMesh(static_cast<TH3S *>(fHist), geom, &m, isoValue);
   } else if (typeid(*fHist) == typeid(TH3I)) {
      Rgl::Mc::TMeshBuilder<TH3I, Float_t> builder(kTRUE);
      builder.BuildMesh(static_cast<TH3I *>(fHist), geom, &m, isoValue);
   } else if (typeid(*fHist) == typeid(TH3F)) {
      Rgl::Mc::TMeshBuilder<TH3F, Float_t> builder(kTRUE);
      builder.BuildMesh(static_cast<TH3F *>(fHist), geom, &m, isoValue);
   } else if (typeid(*fHist) == typeid(TH3D)) {
      Rgl::Mc::TMeshBuilder<TH3D, Float_t> builder(kTRUE);
      builder.BuildMesh(static_cast<TH3D *>(fHist), geom, &m, isoValue);
   }
}

//______________________________________________________________________________
void TGLIsoPainter::DrawMesh(const Mesh_t &m, Int_t level) const
{
   //Draw TF3 surface
   if (!fSelectionPass)
      SetSurfaceColor(level);

   if (!fBoxCut.IsActive()) {
      if (!fSelectionPass)
         Rgl::DrawMesh(m.fVerts, m.fNorms, m.fTris);
      else {
         Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
         Rgl::DrawMesh(m.fVerts, m.fTris);
      }
   } else {
      if (!fSelectionPass)
         Rgl::DrawMesh(m.fVerts, m.fNorms, m.fTris, fBoxCut);
      else {
         Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
         Rgl::DrawMesh(m.fVerts, m.fTris, fBoxCut);
      }
   }
}

//______________________________________________________________________________
void TGLIsoPainter::FindMinMax()
{
   //Find max/min bin contents for TH3.
   fMinMax.first  = fHist->GetBinContent(fXAxis->GetFirst(), fYAxis->GetFirst(), fZAxis->GetFirst());
   fMinMax.second = fMinMax.first;

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