// @(#)root/gl:$Id$
// Author:  Timur Pocheptsov  07/08/2009

#include <stdexcept>

#include "KeySymbols.h"
#include "TVirtualX.h"
#include "Buttons.h"
#include "TString.h"
#include "TError.h"
#include "TColor.h"
#include "TROOT.h"
#include "TMath.h"

#include "TGLTH3Composition.h"
#include "TGLIncludes.h"

//
//TGLTH3Composition.
//

ClassImp(TGLTH3Composition)

//______________________________________________________________________________
TGLTH3Composition::TGLTH3Composition()
{
   //I have to define it, since explicit copy ctor was declared.
}

namespace {

void CompareAxes(const TAxis *a1, const TAxis *a2, const TString &axisName);

}

//______________________________________________________________________________
void TGLTH3Composition::AddTH3(const TH3 *h, ETH3BinShape shape)
{
   //Add TH3 into collection. Throw if fHists is not empty
   //but ranges are not equal.
   const TAxis *xa = h->GetXaxis();
   const TAxis *ya = h->GetYaxis();
   const TAxis *za = h->GetZaxis();

   if (!fHists.size()) {
      //This is the first hist in a composition,
      //take its ranges and reset axes for the composition.
      fXaxis.Set(h->GetNbinsX(), xa->GetBinLowEdge(xa->GetFirst()), xa->GetBinUpEdge(xa->GetLast()));
      fYaxis.Set(h->GetNbinsY(), ya->GetBinLowEdge(ya->GetFirst()), ya->GetBinUpEdge(ya->GetLast()));
      fZaxis.Set(h->GetNbinsZ(), za->GetBinLowEdge(za->GetFirst()), za->GetBinUpEdge(za->GetLast()));
   } else {
      CompareAxes(xa, GetXaxis(), "X");
      CompareAxes(ya, GetYaxis(), "Y");
      CompareAxes(za, GetZaxis(), "Z");
   }

   fHists.push_back(TH3Pair_t(h, shape));
}

//______________________________________________________________________________
Int_t TGLTH3Composition::DistancetoPrimitive(Int_t px, Int_t py)
{
   //Check if "this" is under cursor.
   if (!fPainter.get())
      return 9999;

   return fPainter->DistancetoPrimitive(px, py);
}

//______________________________________________________________________________
void TGLTH3Composition::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   //Mouse and keyboard events.
   fPainter->ExecuteEvent(event, px, py);
}

//______________________________________________________________________________
char *TGLTH3Composition::GetObjectInfo(Int_t /*px*/, Int_t /*py*/) const
{
   //I cannot show bin content in a status bar -
   //since there can be several bins in one.
   static char message[] = "TH3 composition";
   return message;
}

//______________________________________________________________________________
void TGLTH3Composition::Paint(Option_t * /*option*/)
{
   //Paint a composition of 3d hists.
   if (!fHists.size())
      return;

   //create a painter.
   if (!fPainter.get())
      fPainter.reset(new TGLHistPainter(this));

   fPainter->Paint("dummy");
}

//
//TGLTH3CompositionPainter.
//

ClassImp(TGLTH3CompositionPainter)

//______________________________________________________________________________
TGLTH3CompositionPainter::TGLTH3CompositionPainter(TGLTH3Composition *data, TGLPlotCamera *cam,
                                                   TGLPlotCoordinates *coord)
                             : TGLPlotPainter(data, cam, coord, kFALSE, kFALSE, kFALSE),
                               fData(data)
{
   //Ctor.
}

//______________________________________________________________________________
char *TGLTH3CompositionPainter::GetPlotInfo(Int_t /*px*/, Int_t /*py*/)
{
   //Will be never called from TPad.
   static char message[] = "TH3 composition";
   return message;
}

//______________________________________________________________________________
Bool_t TGLTH3CompositionPainter::InitGeometry()
{
   if (!fData->fHists.size())
      return kFALSE;

   //Prepare plot painter.
   //Forget about log scale.
   fCoord->SetZLog(kFALSE);
   fCoord->SetYLog(kFALSE);
   fCoord->SetXLog(kFALSE);

   if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))//kFALSE == drawErrors, kTRUE == zAsBins
      return kFALSE;

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

   //Loop on hists.
   const TH3 *h = fData->fHists[0].first;
   fMinMaxVal.second  = h->GetBinContent(fCoord->GetFirstXBin(),
                                         fCoord->GetFirstYBin(),
                                         fCoord->GetFirstZBin());
   fMinMaxVal.first = fMinMaxVal.second;

   for (UInt_t hNum = 0, lastH = fData->fHists.size(); hNum < lastH; ++hNum) {
      h = fData->fHists[hNum].first;
      for (Int_t ir = fCoord->GetFirstXBin(); ir <= fCoord->GetLastXBin(); ++ir) {
         for (Int_t jr = fCoord->GetFirstYBin(); jr <= fCoord->GetLastYBin(); ++jr) {
            for (Int_t kr = fCoord->GetFirstZBin();  kr <= fCoord->GetLastZBin(); ++kr) {
               fMinMaxVal.second = TMath::Max(fMinMaxVal.second, h->GetBinContent(ir, jr, kr));
               fMinMaxVal.first = TMath::Min(fMinMaxVal.first, h->GetBinContent(ir, jr, kr));
            }
         }
      }
   }

   if (fCoord->Modified()) {
      fUpdateSelection = kTRUE;
      fCoord->ResetModified();
   }

   return kTRUE;
}

//______________________________________________________________________________
void TGLTH3CompositionPainter::StartPan(Int_t px, Int_t py)
{
   //Move plot or box cut.
   fMousePosition.fX = px;
   fMousePosition.fY = fCamera->GetHeight() - py;
   fCamera->StartPan(px, py);
   fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
}

//______________________________________________________________________________
void TGLTH3CompositionPainter::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.
   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);
      }

      RestoreProjectionMatrix();
      RestoreModelviewMatrix();
   }

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

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

//______________________________________________________________________________
void TGLTH3CompositionPainter::ProcessEvent(Int_t event, Int_t /*px*/, Int_t py)
{
   //Switch on/off box cut.
   if (event == kButton1Double && fBoxCut.IsActive()) {
      fBoxCut.TurnOnOff();
      if (!gVirtualX->IsCmdThread())
         gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%lx)->Paint()", (ULong_t)this));
      else
         Paint();
   } else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
      if (fHighColor)
         Info("ProcessEvent", "Switch to true color mode to use box cut");
      else {
         fBoxCut.TurnOnOff();
         fUpdateSelection = kTRUE;
      }
   }
}

//______________________________________________________________________________
void TGLTH3CompositionPainter::InitGL()const
{
   // Initialize some gl state variables.
   glEnable(GL_DEPTH_TEST);
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glEnable(GL_CULL_FACE);
   glCullFace(GL_BACK);

   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
}

//______________________________________________________________________________
void TGLTH3CompositionPainter::DeInitGL()const
{
   //Return back some gl state variables.
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_LIGHTING);
   glDisable(GL_LIGHT0);
   glDisable(GL_CULL_FACE);
   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
}

//______________________________________________________________________________
void TGLTH3CompositionPainter::DrawPlot()const
{
   //Draw composition of TH3s.

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

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

   if (!fSelectionPass) {
      glEnable(GL_POLYGON_OFFSET_FILL);//[0
      glPolygonOffset(1.f, 1.f);
   } else
      return;

   //Using front point, find the correct order to draw boxes from
   //back to front/from bottom to top (it's important only for semi-transparent boxes).
   const Int_t frontPoint = fBackBox.GetFrontPoint();
   Int_t irInit = fCoord->GetFirstXBin(), iInit = 0;
   const Int_t nX = fCoord->GetNXBins();
   Int_t jrInit = fCoord->GetFirstYBin(), jInit = 0;
   const Int_t nY = fCoord->GetNYBins();
   Int_t krInit = fCoord->GetFirstZBin(), kInit = 0;
   const Int_t nZ = fCoord->GetNZBins();

   const Int_t addI = frontPoint == 2 || frontPoint == 1 ? 1 : (iInit = nX - 1, irInit = fCoord->GetLastXBin(), -1);
   const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? 1 : (jInit = nY - 1, jrInit = fCoord->GetLastYBin(), -1);
   const Int_t addK = fBackBox.Get2DBox()[frontPoint + 4].Y() < fBackBox.Get2DBox()[frontPoint].Y() ? 1
                     : (kInit = nZ - 1, krInit = fCoord->GetLastZBin(),-1);
   const Double_t xScale = fCoord->GetXScale();
   const Double_t yScale = fCoord->GetYScale();
   const Double_t zScale = fCoord->GetZScale();
   const TAxis   *xA = fXAxis;
   const TAxis   *yA = fYAxis;
   const TAxis   *zA = fZAxis;

   Double_t maxContent = TMath::Max(TMath::Abs(fMinMaxVal.first), TMath::Abs(fMinMaxVal.second));
   if(!maxContent)//bad, find better way to check zero.
      maxContent = 1.;

   for (UInt_t hNum = 0; hNum < fData->fHists.size(); ++hNum) {
      const TH3 *h = fData->fHists[hNum].first;
      const TGLTH3Composition::ETH3BinShape shape = fData->fHists[hNum].second;
      SetColor(h->GetFillColor());

      for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
         for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
            for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
               const Double_t binContent = h->GetBinContent(ir, jr, kr);
               const Double_t w = TMath::Abs(binContent) / maxContent;
               if (!w)
                  continue;

               const Double_t xMin = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 - w * xA->GetBinWidth(ir) / 2);
               const Double_t xMax = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 + w * xA->GetBinWidth(ir) / 2);
               const Double_t yMin = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 - w * yA->GetBinWidth(jr) / 2);
               const Double_t yMax = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 + w * yA->GetBinWidth(jr) / 2);
               const Double_t zMin = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 - w * zA->GetBinWidth(kr) / 2);
               const Double_t zMax = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 + w * zA->GetBinWidth(kr) / 2);

               if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
                  continue;

               if (shape == TGLTH3Composition::kSphere)
                  Rgl::DrawSphere(&fQuadric, xMin, xMax, yMin, yMax, zMin, zMax);
               else
                  Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
            }
         }
      }
   }

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

   glDisable(GL_POLYGON_OFFSET_FILL);//0]
   const TGLDisableGuard lightGuard(GL_LIGHTING);//[2 - 2]
   glColor4d(0., 0., 0., 0.25);
   glPolygonMode(GL_FRONT, GL_LINE);//[3

   const TGLEnableGuard blendGuard(GL_BLEND);//[4-4] + 1]
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);//[5-5]
   glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);

   for (UInt_t hNum = 0; hNum < fData->fHists.size(); ++hNum) {
      if (fData->fHists[hNum].second == TGLTH3Composition::kSphere)
         continue;//No outlines for spherical bins.

      const TH3 *h = fData->fHists[hNum].first;

      for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
         for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
            for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
               const Double_t w = TMath::Abs(h->GetBinContent(ir, jr, kr)) / maxContent;
               if (!w)
                  continue;

               const Double_t xMin = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 - w * xA->GetBinWidth(ir) / 2);
               const Double_t xMax = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 + w * xA->GetBinWidth(ir) / 2);
               const Double_t yMin = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 - w * yA->GetBinWidth(jr) / 2);
               const Double_t yMax = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 + w * yA->GetBinWidth(jr) / 2);
               const Double_t zMin = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 - w * zA->GetBinWidth(kr) / 2);
               const Double_t zMax = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 + w * zA->GetBinWidth(kr) / 2);

               if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
                  continue;

               Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
            }
         }
      }
   }

   glPolygonMode(GL_FRONT, GL_FILL);//3]
}

//______________________________________________________________________________
void TGLTH3CompositionPainter::SetColor(Int_t color)const
{
   //Set material.
   Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.05f};

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

   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);
   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
}

namespace {

//______________________________________________________________________________
void AxisError(const TString & errorMsg)
{
   Error("TGLTH3Composition::AddTH3", "%s", errorMsg.Data());
   throw std::runtime_error(errorMsg.Data());
}

//______________________________________________________________________________
void CompareAxes(const TAxis *a1, const TAxis *a2, const TString &axisName)
{
   //Check number of bins.
   if (a1->GetNbins() != a2->GetNbins())
      AxisError("New hist has different number of bins along " + axisName);

   //Check bin ranges.
   const Int_t firstBin1 = a1->GetFirst(), lastBin1 = a1->GetLast();
   const Int_t firstBin2 = a2->GetFirst(), lastBin2 = a2->GetLast();

   if (firstBin1 != firstBin2)
      AxisError("New hist has different first bin along " + axisName);

   if (lastBin1 != lastBin2)
      AxisError("New hist has different last bin along " + axisName);

   const Double_t eps = 1e-7;//?????:((((
   //Check axes ranges.
   if (TMath::Abs(a1->GetBinLowEdge(firstBin1) - a2->GetBinLowEdge(firstBin2)) > eps)
      AxisError("New hist has different low edge along " + axisName);
   if (TMath::Abs(a1->GetBinUpEdge(lastBin1) - a2->GetBinUpEdge(lastBin2)) > eps)
      AxisError("New hist has different low edge along " + axisName);
}

}
 TGLTH3Composition.cxx:1
 TGLTH3Composition.cxx:2
 TGLTH3Composition.cxx:3
 TGLTH3Composition.cxx:4
 TGLTH3Composition.cxx:5
 TGLTH3Composition.cxx:6
 TGLTH3Composition.cxx:7
 TGLTH3Composition.cxx:8
 TGLTH3Composition.cxx:9
 TGLTH3Composition.cxx:10
 TGLTH3Composition.cxx:11
 TGLTH3Composition.cxx:12
 TGLTH3Composition.cxx:13
 TGLTH3Composition.cxx:14
 TGLTH3Composition.cxx:15
 TGLTH3Composition.cxx:16
 TGLTH3Composition.cxx:17
 TGLTH3Composition.cxx:18
 TGLTH3Composition.cxx:19
 TGLTH3Composition.cxx:20
 TGLTH3Composition.cxx:21
 TGLTH3Composition.cxx:22
 TGLTH3Composition.cxx:23
 TGLTH3Composition.cxx:24
 TGLTH3Composition.cxx:25
 TGLTH3Composition.cxx:26
 TGLTH3Composition.cxx:27
 TGLTH3Composition.cxx:28
 TGLTH3Composition.cxx:29
 TGLTH3Composition.cxx:30
 TGLTH3Composition.cxx:31
 TGLTH3Composition.cxx:32
 TGLTH3Composition.cxx:33
 TGLTH3Composition.cxx:34
 TGLTH3Composition.cxx:35
 TGLTH3Composition.cxx:36
 TGLTH3Composition.cxx:37
 TGLTH3Composition.cxx:38
 TGLTH3Composition.cxx:39
 TGLTH3Composition.cxx:40
 TGLTH3Composition.cxx:41
 TGLTH3Composition.cxx:42
 TGLTH3Composition.cxx:43
 TGLTH3Composition.cxx:44
 TGLTH3Composition.cxx:45
 TGLTH3Composition.cxx:46
 TGLTH3Composition.cxx:47
 TGLTH3Composition.cxx:48
 TGLTH3Composition.cxx:49
 TGLTH3Composition.cxx:50
 TGLTH3Composition.cxx:51
 TGLTH3Composition.cxx:52
 TGLTH3Composition.cxx:53
 TGLTH3Composition.cxx:54
 TGLTH3Composition.cxx:55
 TGLTH3Composition.cxx:56
 TGLTH3Composition.cxx:57
 TGLTH3Composition.cxx:58
 TGLTH3Composition.cxx:59
 TGLTH3Composition.cxx:60
 TGLTH3Composition.cxx:61
 TGLTH3Composition.cxx:62
 TGLTH3Composition.cxx:63
 TGLTH3Composition.cxx:64
 TGLTH3Composition.cxx:65
 TGLTH3Composition.cxx:66
 TGLTH3Composition.cxx:67
 TGLTH3Composition.cxx:68
 TGLTH3Composition.cxx:69
 TGLTH3Composition.cxx:70
 TGLTH3Composition.cxx:71
 TGLTH3Composition.cxx:72
 TGLTH3Composition.cxx:73
 TGLTH3Composition.cxx:74
 TGLTH3Composition.cxx:75
 TGLTH3Composition.cxx:76
 TGLTH3Composition.cxx:77
 TGLTH3Composition.cxx:78
 TGLTH3Composition.cxx:79
 TGLTH3Composition.cxx:80
 TGLTH3Composition.cxx:81
 TGLTH3Composition.cxx:82
 TGLTH3Composition.cxx:83
 TGLTH3Composition.cxx:84
 TGLTH3Composition.cxx:85
 TGLTH3Composition.cxx:86
 TGLTH3Composition.cxx:87
 TGLTH3Composition.cxx:88
 TGLTH3Composition.cxx:89
 TGLTH3Composition.cxx:90
 TGLTH3Composition.cxx:91
 TGLTH3Composition.cxx:92
 TGLTH3Composition.cxx:93
 TGLTH3Composition.cxx:94
 TGLTH3Composition.cxx:95
 TGLTH3Composition.cxx:96
 TGLTH3Composition.cxx:97
 TGLTH3Composition.cxx:98
 TGLTH3Composition.cxx:99
 TGLTH3Composition.cxx:100
 TGLTH3Composition.cxx:101
 TGLTH3Composition.cxx:102
 TGLTH3Composition.cxx:103
 TGLTH3Composition.cxx:104
 TGLTH3Composition.cxx:105
 TGLTH3Composition.cxx:106
 TGLTH3Composition.cxx:107
 TGLTH3Composition.cxx:108
 TGLTH3Composition.cxx:109
 TGLTH3Composition.cxx:110
 TGLTH3Composition.cxx:111
 TGLTH3Composition.cxx:112
 TGLTH3Composition.cxx:113
 TGLTH3Composition.cxx:114
 TGLTH3Composition.cxx:115
 TGLTH3Composition.cxx:116
 TGLTH3Composition.cxx:117
 TGLTH3Composition.cxx:118
 TGLTH3Composition.cxx:119
 TGLTH3Composition.cxx:120
 TGLTH3Composition.cxx:121
 TGLTH3Composition.cxx:122
 TGLTH3Composition.cxx:123
 TGLTH3Composition.cxx:124
 TGLTH3Composition.cxx:125
 TGLTH3Composition.cxx:126
 TGLTH3Composition.cxx:127
 TGLTH3Composition.cxx:128
 TGLTH3Composition.cxx:129
 TGLTH3Composition.cxx:130
 TGLTH3Composition.cxx:131
 TGLTH3Composition.cxx:132
 TGLTH3Composition.cxx:133
 TGLTH3Composition.cxx:134
 TGLTH3Composition.cxx:135
 TGLTH3Composition.cxx:136
 TGLTH3Composition.cxx:137
 TGLTH3Composition.cxx:138
 TGLTH3Composition.cxx:139
 TGLTH3Composition.cxx:140
 TGLTH3Composition.cxx:141
 TGLTH3Composition.cxx:142
 TGLTH3Composition.cxx:143
 TGLTH3Composition.cxx:144
 TGLTH3Composition.cxx:145
 TGLTH3Composition.cxx:146
 TGLTH3Composition.cxx:147
 TGLTH3Composition.cxx:148
 TGLTH3Composition.cxx:149
 TGLTH3Composition.cxx:150
 TGLTH3Composition.cxx:151
 TGLTH3Composition.cxx:152
 TGLTH3Composition.cxx:153
 TGLTH3Composition.cxx:154
 TGLTH3Composition.cxx:155
 TGLTH3Composition.cxx:156
 TGLTH3Composition.cxx:157
 TGLTH3Composition.cxx:158
 TGLTH3Composition.cxx:159
 TGLTH3Composition.cxx:160
 TGLTH3Composition.cxx:161
 TGLTH3Composition.cxx:162
 TGLTH3Composition.cxx:163
 TGLTH3Composition.cxx:164
 TGLTH3Composition.cxx:165
 TGLTH3Composition.cxx:166
 TGLTH3Composition.cxx:167
 TGLTH3Composition.cxx:168
 TGLTH3Composition.cxx:169
 TGLTH3Composition.cxx:170
 TGLTH3Composition.cxx:171
 TGLTH3Composition.cxx:172
 TGLTH3Composition.cxx:173
 TGLTH3Composition.cxx:174
 TGLTH3Composition.cxx:175
 TGLTH3Composition.cxx:176
 TGLTH3Composition.cxx:177
 TGLTH3Composition.cxx:178
 TGLTH3Composition.cxx:179
 TGLTH3Composition.cxx:180
 TGLTH3Composition.cxx:181
 TGLTH3Composition.cxx:182
 TGLTH3Composition.cxx:183
 TGLTH3Composition.cxx:184
 TGLTH3Composition.cxx:185
 TGLTH3Composition.cxx:186
 TGLTH3Composition.cxx:187
 TGLTH3Composition.cxx:188
 TGLTH3Composition.cxx:189
 TGLTH3Composition.cxx:190
 TGLTH3Composition.cxx:191
 TGLTH3Composition.cxx:192
 TGLTH3Composition.cxx:193
 TGLTH3Composition.cxx:194
 TGLTH3Composition.cxx:195
 TGLTH3Composition.cxx:196
 TGLTH3Composition.cxx:197
 TGLTH3Composition.cxx:198
 TGLTH3Composition.cxx:199
 TGLTH3Composition.cxx:200
 TGLTH3Composition.cxx:201
 TGLTH3Composition.cxx:202
 TGLTH3Composition.cxx:203
 TGLTH3Composition.cxx:204
 TGLTH3Composition.cxx:205
 TGLTH3Composition.cxx:206
 TGLTH3Composition.cxx:207
 TGLTH3Composition.cxx:208
 TGLTH3Composition.cxx:209
 TGLTH3Composition.cxx:210
 TGLTH3Composition.cxx:211
 TGLTH3Composition.cxx:212
 TGLTH3Composition.cxx:213
 TGLTH3Composition.cxx:214
 TGLTH3Composition.cxx:215
 TGLTH3Composition.cxx:216
 TGLTH3Composition.cxx:217
 TGLTH3Composition.cxx:218
 TGLTH3Composition.cxx:219
 TGLTH3Composition.cxx:220
 TGLTH3Composition.cxx:221
 TGLTH3Composition.cxx:222
 TGLTH3Composition.cxx:223
 TGLTH3Composition.cxx:224
 TGLTH3Composition.cxx:225
 TGLTH3Composition.cxx:226
 TGLTH3Composition.cxx:227
 TGLTH3Composition.cxx:228
 TGLTH3Composition.cxx:229
 TGLTH3Composition.cxx:230
 TGLTH3Composition.cxx:231
 TGLTH3Composition.cxx:232
 TGLTH3Composition.cxx:233
 TGLTH3Composition.cxx:234
 TGLTH3Composition.cxx:235
 TGLTH3Composition.cxx:236
 TGLTH3Composition.cxx:237
 TGLTH3Composition.cxx:238
 TGLTH3Composition.cxx:239
 TGLTH3Composition.cxx:240
 TGLTH3Composition.cxx:241
 TGLTH3Composition.cxx:242
 TGLTH3Composition.cxx:243
 TGLTH3Composition.cxx:244
 TGLTH3Composition.cxx:245
 TGLTH3Composition.cxx:246
 TGLTH3Composition.cxx:247
 TGLTH3Composition.cxx:248
 TGLTH3Composition.cxx:249
 TGLTH3Composition.cxx:250
 TGLTH3Composition.cxx:251
 TGLTH3Composition.cxx:252
 TGLTH3Composition.cxx:253
 TGLTH3Composition.cxx:254
 TGLTH3Composition.cxx:255
 TGLTH3Composition.cxx:256
 TGLTH3Composition.cxx:257
 TGLTH3Composition.cxx:258
 TGLTH3Composition.cxx:259
 TGLTH3Composition.cxx:260
 TGLTH3Composition.cxx:261
 TGLTH3Composition.cxx:262
 TGLTH3Composition.cxx:263
 TGLTH3Composition.cxx:264
 TGLTH3Composition.cxx:265
 TGLTH3Composition.cxx:266
 TGLTH3Composition.cxx:267
 TGLTH3Composition.cxx:268
 TGLTH3Composition.cxx:269
 TGLTH3Composition.cxx:270
 TGLTH3Composition.cxx:271
 TGLTH3Composition.cxx:272
 TGLTH3Composition.cxx:273
 TGLTH3Composition.cxx:274
 TGLTH3Composition.cxx:275
 TGLTH3Composition.cxx:276
 TGLTH3Composition.cxx:277
 TGLTH3Composition.cxx:278
 TGLTH3Composition.cxx:279
 TGLTH3Composition.cxx:280
 TGLTH3Composition.cxx:281
 TGLTH3Composition.cxx:282
 TGLTH3Composition.cxx:283
 TGLTH3Composition.cxx:284
 TGLTH3Composition.cxx:285
 TGLTH3Composition.cxx:286
 TGLTH3Composition.cxx:287
 TGLTH3Composition.cxx:288
 TGLTH3Composition.cxx:289
 TGLTH3Composition.cxx:290
 TGLTH3Composition.cxx:291
 TGLTH3Composition.cxx:292
 TGLTH3Composition.cxx:293
 TGLTH3Composition.cxx:294
 TGLTH3Composition.cxx:295
 TGLTH3Composition.cxx:296
 TGLTH3Composition.cxx:297
 TGLTH3Composition.cxx:298
 TGLTH3Composition.cxx:299
 TGLTH3Composition.cxx:300
 TGLTH3Composition.cxx:301
 TGLTH3Composition.cxx:302
 TGLTH3Composition.cxx:303
 TGLTH3Composition.cxx:304
 TGLTH3Composition.cxx:305
 TGLTH3Composition.cxx:306
 TGLTH3Composition.cxx:307
 TGLTH3Composition.cxx:308
 TGLTH3Composition.cxx:309
 TGLTH3Composition.cxx:310
 TGLTH3Composition.cxx:311
 TGLTH3Composition.cxx:312
 TGLTH3Composition.cxx:313
 TGLTH3Composition.cxx:314
 TGLTH3Composition.cxx:315
 TGLTH3Composition.cxx:316
 TGLTH3Composition.cxx:317
 TGLTH3Composition.cxx:318
 TGLTH3Composition.cxx:319
 TGLTH3Composition.cxx:320
 TGLTH3Composition.cxx:321
 TGLTH3Composition.cxx:322
 TGLTH3Composition.cxx:323
 TGLTH3Composition.cxx:324
 TGLTH3Composition.cxx:325
 TGLTH3Composition.cxx:326
 TGLTH3Composition.cxx:327
 TGLTH3Composition.cxx:328
 TGLTH3Composition.cxx:329
 TGLTH3Composition.cxx:330
 TGLTH3Composition.cxx:331
 TGLTH3Composition.cxx:332
 TGLTH3Composition.cxx:333
 TGLTH3Composition.cxx:334
 TGLTH3Composition.cxx:335
 TGLTH3Composition.cxx:336
 TGLTH3Composition.cxx:337
 TGLTH3Composition.cxx:338
 TGLTH3Composition.cxx:339
 TGLTH3Composition.cxx:340
 TGLTH3Composition.cxx:341
 TGLTH3Composition.cxx:342
 TGLTH3Composition.cxx:343
 TGLTH3Composition.cxx:344
 TGLTH3Composition.cxx:345
 TGLTH3Composition.cxx:346
 TGLTH3Composition.cxx:347
 TGLTH3Composition.cxx:348
 TGLTH3Composition.cxx:349
 TGLTH3Composition.cxx:350
 TGLTH3Composition.cxx:351
 TGLTH3Composition.cxx:352
 TGLTH3Composition.cxx:353
 TGLTH3Composition.cxx:354
 TGLTH3Composition.cxx:355
 TGLTH3Composition.cxx:356
 TGLTH3Composition.cxx:357
 TGLTH3Composition.cxx:358
 TGLTH3Composition.cxx:359
 TGLTH3Composition.cxx:360
 TGLTH3Composition.cxx:361
 TGLTH3Composition.cxx:362
 TGLTH3Composition.cxx:363
 TGLTH3Composition.cxx:364
 TGLTH3Composition.cxx:365
 TGLTH3Composition.cxx:366
 TGLTH3Composition.cxx:367
 TGLTH3Composition.cxx:368
 TGLTH3Composition.cxx:369
 TGLTH3Composition.cxx:370
 TGLTH3Composition.cxx:371
 TGLTH3Composition.cxx:372
 TGLTH3Composition.cxx:373
 TGLTH3Composition.cxx:374
 TGLTH3Composition.cxx:375
 TGLTH3Composition.cxx:376
 TGLTH3Composition.cxx:377
 TGLTH3Composition.cxx:378
 TGLTH3Composition.cxx:379
 TGLTH3Composition.cxx:380
 TGLTH3Composition.cxx:381
 TGLTH3Composition.cxx:382
 TGLTH3Composition.cxx:383
 TGLTH3Composition.cxx:384
 TGLTH3Composition.cxx:385
 TGLTH3Composition.cxx:386
 TGLTH3Composition.cxx:387
 TGLTH3Composition.cxx:388
 TGLTH3Composition.cxx:389
 TGLTH3Composition.cxx:390
 TGLTH3Composition.cxx:391
 TGLTH3Composition.cxx:392
 TGLTH3Composition.cxx:393
 TGLTH3Composition.cxx:394
 TGLTH3Composition.cxx:395
 TGLTH3Composition.cxx:396
 TGLTH3Composition.cxx:397
 TGLTH3Composition.cxx:398
 TGLTH3Composition.cxx:399
 TGLTH3Composition.cxx:400
 TGLTH3Composition.cxx:401
 TGLTH3Composition.cxx:402
 TGLTH3Composition.cxx:403
 TGLTH3Composition.cxx:404
 TGLTH3Composition.cxx:405
 TGLTH3Composition.cxx:406
 TGLTH3Composition.cxx:407
 TGLTH3Composition.cxx:408
 TGLTH3Composition.cxx:409
 TGLTH3Composition.cxx:410
 TGLTH3Composition.cxx:411
 TGLTH3Composition.cxx:412
 TGLTH3Composition.cxx:413
 TGLTH3Composition.cxx:414
 TGLTH3Composition.cxx:415
 TGLTH3Composition.cxx:416
 TGLTH3Composition.cxx:417
 TGLTH3Composition.cxx:418
 TGLTH3Composition.cxx:419
 TGLTH3Composition.cxx:420
 TGLTH3Composition.cxx:421
 TGLTH3Composition.cxx:422
 TGLTH3Composition.cxx:423
 TGLTH3Composition.cxx:424
 TGLTH3Composition.cxx:425
 TGLTH3Composition.cxx:426
 TGLTH3Composition.cxx:427
 TGLTH3Composition.cxx:428
 TGLTH3Composition.cxx:429
 TGLTH3Composition.cxx:430
 TGLTH3Composition.cxx:431
 TGLTH3Composition.cxx:432
 TGLTH3Composition.cxx:433
 TGLTH3Composition.cxx:434
 TGLTH3Composition.cxx:435