ROOT logo
#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"

namespace {

/*
Auxilary functions to draw iso-meshes.
*/
//______________________________________________________________________________
template<class V>
void DrawMesh(GLenum type, const std::vector<V> &vs, const std::vector<V> &ns, 
              const std::vector<UInt_t> &ts)
{
   //Surface with material and lighting.
   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_NORMAL_ARRAY);
   glVertexPointer(3, type, 0, &vs[0]);
   glNormalPointer(type, 0, &ns[0]);
   glDrawElements(GL_TRIANGLES, ts.size(), GL_UNSIGNED_INT, &ts[0]);
   glDisableClientState(GL_NORMAL_ARRAY);
   glDisableClientState(GL_VERTEX_ARRAY);
}

//______________________________________________________________________________
template<class V>
void DrawMesh(GLenum type, const std::vector<V> &vs, const std::vector<UInt_t> &ts)
{
   //Only vertices, no normal (no lighting and material).
   glEnableClientState(GL_VERTEX_ARRAY);
   glVertexPointer(3, type, 0, &vs[0]);
   glDrawElements(GL_TRIANGLES, ts.size(), GL_UNSIGNED_INT, &ts[0]);
   glDisableClientState(GL_VERTEX_ARRAY);
}

//______________________________________________________________________________
template<class V, class GLN, class GLV>
void DrawMesh(GLN normal3, GLV vertex3, const std::vector<V> &vs, 
              const std::vector<V> &ns, const std::vector<UInt_t> &ts, 
              const TGLBoxCut &box)
{
   //Mesh with cut.
   //Material and lighting are enabled.
   glBegin(GL_TRIANGLES);

   for (UInt_t i = 0, e = ts.size() / 3; i < e; ++i) {
      const UInt_t * t = &ts[i * 3];
      if (box.IsInCut(&vs[t[0] * 3]))
         continue;
      if (box.IsInCut(&vs[t[1] * 3]))
         continue;
      if (box.IsInCut(&vs[t[2] * 3]))
         continue;

      normal3(&ns[t[0] * 3]);
      vertex3(&vs[t[0] * 3]);
      
      normal3(&ns[t[1] * 3]);
      vertex3(&vs[t[1] * 3]);
      
      normal3(&ns[t[2] * 3]);
      vertex3(&vs[t[2] * 3]);
   }

   glEnd();
}

//______________________________________________________________________________
template<class V, class GLV>
void DrawMesh(GLV vertex3, const std::vector<V> &vs, const std::vector<UInt_t> &ts, 
              const TGLBoxCut &box)
{
   //Mesh with cut.
   //No material and lighting.
   glBegin(GL_TRIANGLES);

   for (UInt_t i = 0, e = ts.size() / 3; i < e; ++i) {
      const UInt_t * t = &ts[i * 3];
      if (box.IsInCut(&vs[t[0] * 3]))
         continue;
      if (box.IsInCut(&vs[t[1] * 3]))
         continue;
      if (box.IsInCut(&vs[t[2] * 3]))
         continue;

      vertex3(&vs[t[0] * 3]);
      vertex3(&vs[t[1] * 3]);
      vertex3(&vs[t[2] * 3]);
   }

   glEnd();
}

//______________________________________________________________________________
void GetColor(Double_t *rfColor, const Double_t *n)
{
   //GetColor generates a color from a given normal
   const Double_t x = n[0];
   const Double_t y = n[1];
   const Double_t z = n[2];
   rfColor[0] = (x > 0. ? x : 0.) + (y < 0. ? -0.5 * y : 0.) + (z < 0. ? -0.5 * z : 0.);
   rfColor[1] = (y > 0. ? y : 0.) + (z < 0. ? -0.5 * z : 0.) + (x < 0. ? -0.5 * x : 0.);
   rfColor[2] = (z > 0. ? z : 0.) + (x < 0. ? -0.5 * x : 0.) + (y < 0. ? -0.5 * y : 0.);
}

//______________________________________________________________________________
void DrawMapleMesh(const std::vector<Double_t> &vs, const std::vector<Double_t> &ns,
                   const std::vector<UInt_t> &ts)
{
   //Colored mesh with lighting disabled.
   Double_t color[] = {0., 0., 0., 0.15};

   glBegin(GL_TRIANGLES);

   for (UInt_t i = 0, e = ts.size() / 3; i < e; ++i) {
      const UInt_t *t = &ts[i * 3];
      const Double_t * n = &ns[t[0] * 3];
      //
      GetColor(color, n);
      glColor4dv(color);
      glVertex3dv(&vs[t[0] * 3]);
      //
      n = &ns[t[1] * 3];
      GetColor(color, n);
      glColor4dv(color);
      glVertex3dv(&vs[t[1] * 3]);
      //
      n = &ns[t[2] * 3];
      GetColor(color, n);
      glColor4dv(color);
      glVertex3dv(&vs[t[2] * 3]);
   }

   glEnd();
}

void DrawMapleMesh(const std::vector<Double_t> &vs, const std::vector<Double_t> &ns,
                   const std::vector<UInt_t> &ts, const TGLBoxCut & box)
{
   //Colored mesh with cut and disabled lighting.
   Double_t color[] = {0., 0., 0., 0.15};

   glBegin(GL_TRIANGLES);

   for (UInt_t i = 0, e = ts.size() / 3; i < e; ++i) {
      const UInt_t *t = &ts[i * 3];
      if (box.IsInCut(&vs[t[0] * 3]))
         continue;
      if (box.IsInCut(&vs[t[1] * 3]))
         continue;
      if (box.IsInCut(&vs[t[2] * 3]))
         continue;
      const Double_t * n = &ns[t[0] * 3];
      //
      GetColor(color, n);
      glColor4dv(color);
      glVertex3dv(&vs[t[0] * 3]);
      //
      n = &ns[t[1] * 3];
      GetColor(color, n);
      glColor4dv(color);
      glVertex3dv(&vs[t[1] * 3]);
      //
      n = &ns[t[2] * 3];
      GetColor(color, n);
      glColor4dv(color);
      glVertex3dv(&vs[t[2] * 3]);
   }

   glEnd();
}

}//Unnamed namespace.

//______________________________________________________________________________
//
// 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;
   geom.fMinX  = fXAxis->GetBinLowEdge(fXAxis->GetFirst());
   geom.fStepX = (fXAxis->GetBinUpEdge(fXAxis->GetLast()) - geom.fMinX) / (fHist->GetNbinsX());
   geom.fMinY  = fYAxis->GetBinLowEdge(fYAxis->GetFirst());
   geom.fStepY = (fYAxis->GetBinUpEdge(fYAxis->GetLast()) - geom.fMinY) / (fHist->GetNbinsY());
   geom.fMinZ  = fZAxis->GetBinLowEdge(fZAxis->GetFirst());
   geom.fStepZ = (fZAxis->GetBinUpEdge(fZAxis->GetLast()) - geom.fMinZ) / (fHist->GetNbinsZ());
   //Scale grid parameters.
   geom.fMinX *= fCoord->GetXScale(), geom.fStepX *= fCoord->GetXScale();
   geom.fMinY *= fCoord->GetYScale(), geom.fStepY *= fCoord->GetYScale();
   geom.fMinZ *= fCoord->GetZScale(), geom.fStepZ *= fCoord->GetZScale();

   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()", 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())
      DrawMesh(GL_DOUBLE, fMesh.fVerts, fMesh.fTris);
   else
      DrawMesh(&glVertex3dv, 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()) {
      DrawMesh(GL_DOUBLE, fMesh.fVerts, fMesh.fNorms, fMesh.fTris);
   } else {
      DrawMesh(&glNormal3dv, &glVertex3dv, 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())
      DrawMapleMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris);
   else
      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())
         DrawMesh(GL_DOUBLE, fMesh.fVerts, fMesh.fTris);
      else
         DrawMesh(&glVertex3dv, 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.
   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()", 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.
   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)
{
   Rgl::Mc::TGridGeometry<Float_t> geom;
   //Get grid parameters.
   geom.fMinX  = fXAxis->GetBinCenter(fXAxis->GetFirst());
   geom.fStepX = (fXAxis->GetBinCenter(fXAxis->GetLast()) - geom.fMinX) / (fHist->GetNbinsX() - 1);
   geom.fMinY  = fYAxis->GetBinCenter(fYAxis->GetFirst());
   geom.fStepY = (fYAxis->GetBinCenter(fYAxis->GetLast()) - geom.fMinY) / (fHist->GetNbinsY() - 1);
   geom.fMinZ  = fZAxis->GetBinCenter(fZAxis->GetFirst());
   geom.fStepZ = (fZAxis->GetBinCenter(fZAxis->GetLast()) - geom.fMinZ) / (fHist->GetNbinsZ() - 1);
   //Scale grid parameters.
   geom.fMinX *= fCoord->GetXScale(), geom.fStepX *= fCoord->GetXScale();
   geom.fMinY *= fCoord->GetYScale(), geom.fStepY *= fCoord->GetYScale();
   geom.fMinZ *= fCoord->GetZScale(), geom.fStepZ *= 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)
         ::DrawMesh(GL_FLOAT, m.fVerts, m.fNorms, m.fTris);
      else {
         Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
         ::DrawMesh(GL_FLOAT, m.fVerts, m.fTris);
      }
   } else {
      if (!fSelectionPass)
         ::DrawMesh(&glNormal3fv, &glVertex3fv, m.fVerts, m.fNorms, m.fTris, fBoxCut);
      else {
         Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
         ::DrawMesh(&glVertex3fv, 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
 TGLTF3Painter.cxx:761
 TGLTF3Painter.cxx:762
 TGLTF3Painter.cxx:763
 TGLTF3Painter.cxx:764
 TGLTF3Painter.cxx:765
 TGLTF3Painter.cxx:766
 TGLTF3Painter.cxx:767
 TGLTF3Painter.cxx:768
 TGLTF3Painter.cxx:769
 TGLTF3Painter.cxx:770
 TGLTF3Painter.cxx:771
 TGLTF3Painter.cxx:772
 TGLTF3Painter.cxx:773
 TGLTF3Painter.cxx:774
 TGLTF3Painter.cxx:775
 TGLTF3Painter.cxx:776
 TGLTF3Painter.cxx:777
 TGLTF3Painter.cxx:778
 TGLTF3Painter.cxx:779
 TGLTF3Painter.cxx:780
 TGLTF3Painter.cxx:781
 TGLTF3Painter.cxx:782
 TGLTF3Painter.cxx:783
 TGLTF3Painter.cxx:784
 TGLTF3Painter.cxx:785
 TGLTF3Painter.cxx:786
 TGLTF3Painter.cxx:787
 TGLTF3Painter.cxx:788
 TGLTF3Painter.cxx:789
 TGLTF3Painter.cxx:790
 TGLTF3Painter.cxx:791
 TGLTF3Painter.cxx:792
 TGLTF3Painter.cxx:793
 TGLTF3Painter.cxx:794
 TGLTF3Painter.cxx:795
 TGLTF3Painter.cxx:796
 TGLTF3Painter.cxx:797
 TGLTF3Painter.cxx:798
 TGLTF3Painter.cxx:799
 TGLTF3Painter.cxx:800
 TGLTF3Painter.cxx:801
 TGLTF3Painter.cxx:802
 TGLTF3Painter.cxx:803
 TGLTF3Painter.cxx:804
 TGLTF3Painter.cxx:805
 TGLTF3Painter.cxx:806
 TGLTF3Painter.cxx:807
 TGLTF3Painter.cxx:808
 TGLTF3Painter.cxx:809
 TGLTF3Painter.cxx:810
 TGLTF3Painter.cxx:811
 TGLTF3Painter.cxx:812
 TGLTF3Painter.cxx:813
 TGLTF3Painter.cxx:814
 TGLTF3Painter.cxx:815
 TGLTF3Painter.cxx:816
 TGLTF3Painter.cxx:817
 TGLTF3Painter.cxx:818
 TGLTF3Painter.cxx:819
 TGLTF3Painter.cxx:820
 TGLTF3Painter.cxx:821
 TGLTF3Painter.cxx:822
 TGLTF3Painter.cxx:823
 TGLTF3Painter.cxx:824
 TGLTF3Painter.cxx:825
 TGLTF3Painter.cxx:826
 TGLTF3Painter.cxx:827
 TGLTF3Painter.cxx:828
 TGLTF3Painter.cxx:829
 TGLTF3Painter.cxx:830
 TGLTF3Painter.cxx:831
 TGLTF3Painter.cxx:832
 TGLTF3Painter.cxx:833
 TGLTF3Painter.cxx:834
 TGLTF3Painter.cxx:835
 TGLTF3Painter.cxx:836
 TGLTF3Painter.cxx:837
 TGLTF3Painter.cxx:838
 TGLTF3Painter.cxx:839
 TGLTF3Painter.cxx:840
 TGLTF3Painter.cxx:841
 TGLTF3Painter.cxx:842
 TGLTF3Painter.cxx:843
 TGLTF3Painter.cxx:844
 TGLTF3Painter.cxx:845
 TGLTF3Painter.cxx:846
 TGLTF3Painter.cxx:847
 TGLTF3Painter.cxx:848
 TGLTF3Painter.cxx:849
 TGLTF3Painter.cxx:850
 TGLTF3Painter.cxx:851
 TGLTF3Painter.cxx:852
 TGLTF3Painter.cxx:853
 TGLTF3Painter.cxx:854
 TGLTF3Painter.cxx:855
 TGLTF3Painter.cxx:856
 TGLTF3Painter.cxx:857
 TGLTF3Painter.cxx:858
 TGLTF3Painter.cxx:859
 TGLTF3Painter.cxx:860
 TGLTF3Painter.cxx:861
 TGLTF3Painter.cxx:862
 TGLTF3Painter.cxx:863
 TGLTF3Painter.cxx:864
 TGLTF3Painter.cxx:865
 TGLTF3Painter.cxx:866
 TGLTF3Painter.cxx:867
 TGLTF3Painter.cxx:868
 TGLTF3Painter.cxx:869
 TGLTF3Painter.cxx:870
 TGLTF3Painter.cxx:871
 TGLTF3Painter.cxx:872
 TGLTF3Painter.cxx:873
 TGLTF3Painter.cxx:874
 TGLTF3Painter.cxx:875
 TGLTF3Painter.cxx:876
 TGLTF3Painter.cxx:877
 TGLTF3Painter.cxx:878
 TGLTF3Painter.cxx:879
 TGLTF3Painter.cxx:880
 TGLTF3Painter.cxx:881
 TGLTF3Painter.cxx:882
 TGLTF3Painter.cxx:883
 TGLTF3Painter.cxx:884
 TGLTF3Painter.cxx:885
 TGLTF3Painter.cxx:886
 TGLTF3Painter.cxx:887
 TGLTF3Painter.cxx:888
 TGLTF3Painter.cxx:889
 TGLTF3Painter.cxx:890
 TGLTF3Painter.cxx:891
 TGLTF3Painter.cxx:892
 TGLTF3Painter.cxx:893
 TGLTF3Painter.cxx:894
 TGLTF3Painter.cxx:895
 TGLTF3Painter.cxx:896
 TGLTF3Painter.cxx:897
 TGLTF3Painter.cxx:898
 TGLTF3Painter.cxx:899
 TGLTF3Painter.cxx:900
 TGLTF3Painter.cxx:901
 TGLTF3Painter.cxx:902
 TGLTF3Painter.cxx:903
 TGLTF3Painter.cxx:904
 TGLTF3Painter.cxx:905
 TGLTF3Painter.cxx:906
 TGLTF3Painter.cxx:907
 TGLTF3Painter.cxx:908
 TGLTF3Painter.cxx:909
 TGLTF3Painter.cxx:910
 TGLTF3Painter.cxx:911
 TGLTF3Painter.cxx:912
 TGLTF3Painter.cxx:913
 TGLTF3Painter.cxx:914
 TGLTF3Painter.cxx:915
 TGLTF3Painter.cxx:916
 TGLTF3Painter.cxx:917
 TGLTF3Painter.cxx:918
 TGLTF3Painter.cxx:919
 TGLTF3Painter.cxx:920
 TGLTF3Painter.cxx:921
 TGLTF3Painter.cxx:922
 TGLTF3Painter.cxx:923
 TGLTF3Painter.cxx:924
 TGLTF3Painter.cxx:925
 TGLTF3Painter.cxx:926
 TGLTF3Painter.cxx:927
 TGLTF3Painter.cxx:928