47 ClassImp(TGLPlotPainter);
 
   52 TGLPlotPainter::TGLPlotPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord,
 
   53                                Bool_t xoy, Bool_t xoz, Bool_t yoz)
 
   55                     fPhysicalShapeColor(0),
 
   59                     fXAxis(hist->GetXaxis()),
 
   60                     fYAxis(hist->GetYaxis()),
 
   61                     fZAxis(hist->GetZaxis()),
 
   64                     fUpdateSelection(kTRUE),
 
   65                     fSelectionPass(kFALSE),
 
   70                     fBackBox(xoy, xoz, yoz),
 
   73                     fSelectionBase(kTrueColorSelectionBase),
 
   78       fPadPhi   = gPad->GetPhi();
 
   79       fPadTheta = gPad->GetTheta();
 
   86 TGLPlotPainter::TGLPlotPainter(TGL5DDataSet *data, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
 
   88                     fPhysicalShapeColor(0),
 
   92                     fXAxis(data->GetXAxis()),
 
   93                     fYAxis(data->GetYAxis()),
 
   94                     fZAxis(data->GetZAxis()),
 
   97                     fUpdateSelection(kTRUE),
 
   98                     fSelectionPass(kFALSE),
 
  103                     fBackBox(kFALSE, kFALSE, kFALSE),
 
  106                     fSelectionBase(kTrueColorSelectionBase),
 
  107                     fDrawPalette(kFALSE),
 
  111       fPadPhi   = gPad->GetPhi();
 
  112       fPadTheta = gPad->GetTheta();
 
  119 TGLPlotPainter::TGLPlotPainter(TGLPlotCamera *camera)
 
  121                     fPhysicalShapeColor(0),
 
  130                     fUpdateSelection(kTRUE),
 
  131                     fSelectionPass(kFALSE),
 
  136                     fBackBox(kFALSE, kFALSE, kFALSE),
 
  139                     fSelectionBase(kTrueColorSelectionBase),
 
  140                     fDrawPalette(kFALSE),
 
  144       fPadPhi   = gPad->GetPhi();
 
  145       fPadTheta = gPad->GetTheta();
 
  152 void TGLPlotPainter::Paint()
 
  154    R__LOCKGUARD(gROOTMutex);
 
  157    fSelectionBase = fHighColor ? kHighColorSelectionBase : kTrueColorSelectionBase;
 
  160    glGetIntegerv(GL_VIEWPORT, vp);
 
  164    glDepthMask(GL_TRUE);
 
  168    glPushAttrib(GL_LIGHTING_BIT);
 
  171    SaveProjectionMatrix();
 
  172    SaveModelviewMatrix();
 
  175    fCamera->SetCamera();
 
  177    glClear(GL_DEPTH_BUFFER_BIT);
 
  179    const Float_t pos[] = {0.f, 0.f, 0.f, 1.f};
 
  180    glLightfv(GL_LIGHT0, GL_POSITION, pos);
 
  182    fCamera->Apply(fPadPhi, fPadTheta);
 
  183    fBackBox.FindFrontPoint();
 
  195    RestoreProjectionMatrix();
 
  196    RestoreModelviewMatrix();
 
  198    glViewport(vp[0], vp[1], vp[2], vp[3]);
 
  201    glDepthMask(GL_FALSE);
 
  203    if (fCoord && fCoord->GetCoordType() == kGLCartesian && fDrawAxes) {
 
  205       Bool_t old = gPad->TestBit(TGraph::kClipFrame);
 
  207          gPad->SetBit(TGraph::kClipFrame);
 
  211       TGLUtil::InitializeIfNeeded();
 
  212       Float_t scale = TGLUtil::GetScreenScalingFactor();
 
  216       const Int_t viewport[] = {Int_t(fCamera->GetX() / scale),
 
  217                                 Int_t(fCamera->GetY() / scale),
 
  218                                 Int_t(fCamera->GetWidth() / scale),
 
  219                                 Int_t(fCamera->GetHeight() / scale)};
 
  220       Rgl::DrawAxes(fBackBox.GetFrontPoint(), viewport, fBackBox.Get2DBox(), fCoord, fXAxis, fYAxis, fZAxis);
 
  225          gPad->ResetBit(TGraph::kClipFrame);
 
  226    } 
else if(fDrawPalette)
 
  234 void TGLPlotPainter::PrintPlot()
const 
  238    TGLOutput::StartEmbeddedPS();
 
  240    FILE *output = fopen(gVirtualPS->GetName(), 
"a");
 
  242       Error(
"TGLPlotPainter::PrintPlot", 
"Could not (re)open ps file for GL output");
 
  244       TGLOutput::CloseEmbeddedPS();
 
  248    Int_t gl2psFormat = GL2PS_EPS;
 
  249    Int_t gl2psSort   = GL2PS_BSP_SORT;
 
  251    Int_t state       = GL2PS_OVERFLOW;
 
  252    GLint gl2psoption = GL2PS_USE_CURRENT_VIEWPORT |
 
  255                        GL2PS_OCCLUSION_CULL       |
 
  258    while (state == GL2PS_OVERFLOW) {
 
  259       buffsize += 1024*1024;
 
  260       gl2psBeginPage (
"ROOT Scene Graph", 
"ROOT", NULL,
 
  261                       gl2psFormat, gl2psSort, gl2psoption,
 
  262                       GL_RGBA, 0, NULL,0, 0, 0,
 
  263                       buffsize, output, NULL);
 
  265       state = gl2psEndPage();
 
  269    TGLOutput::CloseEmbeddedPS();
 
  276 Bool_t TGLPlotPainter::PlotSelected(Int_t px, Int_t py)
 
  278    if (fUpdateSelection) {
 
  280       glMatrixMode(GL_PROJECTION);
 
  282       glMatrixMode(GL_MODELVIEW);
 
  285       fSelectionPass = kTRUE;
 
  286       fCamera->SetCamera();
 
  288       glDepthMask(GL_TRUE);
 
  289       glClearColor(0.f, 0.f, 0.f, 0.f);
 
  290       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
  292       fCamera->Apply(fPadPhi, fPadTheta);
 
  298       fSelection.ReadColorBuffer(fCamera->GetX(), fCamera->GetY(), fCamera->GetWidth(), fCamera->GetHeight());
 
  299       fSelectionPass   = kFALSE;
 
  300       fUpdateSelection = kFALSE;
 
  302       glDepthMask(GL_FALSE);
 
  303       glDisable(GL_DEPTH_TEST);
 
  306       glMatrixMode(GL_PROJECTION);
 
  308       glMatrixMode(GL_MODELVIEW);
 
  312    px -= Int_t(gPad->GetXlowNDC() * gPad->GetWw());
 
  313    py -= Int_t(gPad->GetWh() - gPad->YtoAbsPixel(gPad->GetY1()));
 
  316    TGLUtil::InitializeIfNeeded();
 
  317    const Float_t scale = TGLUtil::GetScreenScalingFactor();
 
  327    Int_t newSelected(Rgl::ColorToObjectID(fSelection.GetPixelColor(px, py), fHighColor));
 
  329    if (newSelected != fSelectedPart) {
 
  331       fSelectedPart = newSelected;
 
  335    return fSelectedPart ? kTRUE : kFALSE;
 
  341 void TGLPlotPainter::SetPadColor(
const TColor *c)
 
  349 void TGLPlotPainter::SetFrameColor(
const TColor *c)
 
  351    fBackBox.SetFrameColor(c);
 
  357 void TGLPlotPainter::InvalidateSelection()
 
  359    fUpdateSelection = kTRUE;
 
  365 const TColor *TGLPlotPainter::GetPadColor()
const 
  373 void TGLPlotPainter::MoveSection(Int_t px, Int_t py)
 
  377    const TGLVertex3 *frame = fBackBox.Get3DBox();
 
  378    const Int_t frontPoint  = fBackBox.GetFrontPoint();
 
  380    if (fSelectedPart == 1) {
 
  381       fXOYSectionPos = frame[0].Z();
 
  383    } 
else if (fSelectedPart == 2) {
 
  384       if (frontPoint == 2) {
 
  385          fXOZSectionPos = frame[0].Y();
 
  387       } 
else if (!frontPoint) {
 
  388          fXOZSectionPos = frame[2].Y();
 
  390       } 
else if (frontPoint == 1) {
 
  391          fYOZSectionPos = frame[0].X();
 
  393       } 
else if (frontPoint == 3) {
 
  394          fYOZSectionPos = frame[1].X();
 
  397    } 
else if (fSelectedPart == 3) {
 
  398       if (frontPoint == 2) {
 
  399          fYOZSectionPos = frame[0].X();
 
  401       } 
else if (!frontPoint) {
 
  402          fYOZSectionPos = frame[1].X();
 
  404       } 
else if (frontPoint == 1) {
 
  405          fXOZSectionPos = frame[2].Y();
 
  407       } 
else if (frontPoint == 3) {
 
  408          fXOZSectionPos = frame[0].Y();
 
  413    Double_t mv[16] = {0.};
 
  414    glGetDoublev(GL_MODELVIEW_MATRIX, mv);
 
  415    Double_t pr[16] = {0.};
 
  416    glGetDoublev(GL_PROJECTION_MATRIX, pr);
 
  418    glGetIntegerv(GL_VIEWPORT, vp);
 
  419    Double_t winVertex[3] = {0.};
 
  421    if (fSelectedPart == 6)
 
  422       gluProject(0., 0., fXOYSectionPos, mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
 
  424       gluProject(fSelectedPart == 5 ? fYOZSectionPos : 0.,
 
  425                  fSelectedPart == 4 ? fXOZSectionPos : 0.,
 
  427                  &winVertex[0], &winVertex[1], &winVertex[2]);
 
  428    winVertex[0] += px - fMousePosition.fX;
 
  429    winVertex[1] += py - fMousePosition.fY;
 
  430    Double_t newPoint[3] = {0.};
 
  431    gluUnProject(winVertex[0], winVertex[1], winVertex[2], mv, pr, vp,
 
  432                 newPoint, newPoint + 1, newPoint + 2);
 
  434    if (fSelectedPart == 4)
 
  435       fXOZSectionPos = newPoint[1];
 
  436    else if (fSelectedPart == 5)
 
  437       fYOZSectionPos = newPoint[0];
 
  439       fXOYSectionPos = newPoint[2];
 
  445 void TGLPlotPainter::DrawSections()
const 
  447    const TGLVertex3 *frame = fBackBox.Get3DBox();
 
  449    if (fXOZSectionPos > frame[0].Y()) {
 
  450       if (fXOZSectionPos > frame[2].Y())
 
  451          fXOZSectionPos = frame[2].Y();
 
  452       const TGLVertex3 v1(frame[0].X(), fXOZSectionPos, frame[0].Z());
 
  453       const TGLVertex3 v2(frame[4].X(), fXOZSectionPos, frame[4].Z());
 
  454       const TGLVertex3 v3(frame[5].X(), fXOZSectionPos, frame[5].Z());
 
  455       const TGLVertex3 v4(frame[1].X(), fXOZSectionPos, frame[1].Z());
 
  458          Rgl::ObjectIDToColor(4, fHighColor);
 
  459       else if (fSelectedPart == 4)
 
  460          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
 
  462       glEnable(GL_POLYGON_OFFSET_FILL);
 
  463       glPolygonOffset(1.f, 1.f);
 
  464       Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 1., 0.));
 
  465       glDisable(GL_POLYGON_OFFSET_FILL);
 
  467       if (!fSelectionPass) {
 
  468          if (fSelectedPart == 4)
 
  469             glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
 
  470          const TGLDisableGuard lightGuard(GL_LIGHTING);
 
  471          const TGLEnableGuard  blendGuard(GL_BLEND);
 
  472          const TGLEnableGuard  lineSmooth(GL_LINE_SMOOTH);
 
  473          glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
 
  474          glDepthMask(GL_FALSE);
 
  477          const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);
 
  478          const UShort_t stipple = 0x5555;
 
  479          glLineStipple(1, stipple);
 
  481          glColor3d(0., 0., 0.);
 
  483          for (UInt_t i = 0; i < fZLevels.size(); ++i) {
 
  484             glVertex3d(fBackBox.Get3DBox()[1].X(), fXOZSectionPos, fZLevels[i]);
 
  485             glVertex3d(fBackBox.Get3DBox()[0].X(), fXOZSectionPos, fZLevels[i]);
 
  488          glDepthMask(GL_TRUE);
 
  492    if (fYOZSectionPos > frame[0].X()) {
 
  493       if (fYOZSectionPos > frame[1].X())
 
  494          fYOZSectionPos = frame[1].X();
 
  495       TGLVertex3 v1(fYOZSectionPos, frame[0].Y(), frame[0].Z());
 
  496       TGLVertex3 v2(fYOZSectionPos, frame[3].Y(), frame[3].Z());
 
  497       TGLVertex3 v3(fYOZSectionPos, frame[7].Y(), frame[7].Z());
 
  498       TGLVertex3 v4(fYOZSectionPos, frame[4].Y(), frame[4].Z());
 
  500       if (fSelectionPass) {
 
  501          Rgl::ObjectIDToColor(5, fHighColor);
 
  502       } 
else if (fSelectedPart == 5)
 
  503          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
 
  505       glEnable(GL_POLYGON_OFFSET_FILL);
 
  506       glPolygonOffset(1.f, 1.f);
 
  507       Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(1., 0., 0.));
 
  508       glDisable(GL_POLYGON_OFFSET_FILL);
 
  510       if (!fSelectionPass) {
 
  511          if (fSelectedPart == 5)
 
  512             glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
 
  513          const TGLDisableGuard lightHuard(GL_LIGHTING);
 
  514          const TGLEnableGuard blendGuard(GL_BLEND);
 
  515          const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
 
  516          glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
 
  517          glDepthMask(GL_FALSE);
 
  520          const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);
 
  521          glLineStipple(1, 0x5555);
 
  523          glColor3d(0., 0., 0.);
 
  525          for (UInt_t i = 0; i < fZLevels.size(); ++i) {
 
  526             glVertex3d(fYOZSectionPos, fBackBox.Get3DBox()[3].Y(), fZLevels[i]);
 
  527             glVertex3d(fYOZSectionPos, fBackBox.Get3DBox()[0].Y(), fZLevels[i]);
 
  530          glDepthMask(GL_TRUE);
 
  534    if (fXOYSectionPos > frame[0].Z()) {
 
  535       if (fXOYSectionPos > frame[4].Z())
 
  536          fXOYSectionPos = frame[4].Z();
 
  537       TGLVertex3 v1(frame[0].X(), frame[0].Y(), fXOYSectionPos);
 
  538       TGLVertex3 v2(frame[1].X(), frame[1].Y(), fXOYSectionPos);
 
  539       TGLVertex3 v3(frame[2].X(), frame[2].Y(), fXOYSectionPos);
 
  540       TGLVertex3 v4(frame[3].X(), frame[3].Y(), fXOYSectionPos);
 
  542       if (fSelectionPass) {
 
  543          Rgl::ObjectIDToColor(6, fHighColor);
 
  544       } 
else if (fSelectedPart == 6)
 
  545          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
 
  547       glEnable(GL_POLYGON_OFFSET_FILL);
 
  548       glPolygonOffset(1.f, 1.f);
 
  550       Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 0., 1.));
 
  551       glDisable(GL_POLYGON_OFFSET_FILL);
 
  553       if (!fSelectionPass) {
 
  554          if (fSelectedPart == 6)
 
  555             glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
 
  556          const TGLDisableGuard lightGuard(GL_LIGHTING);
 
  557          const TGLEnableGuard blendGuard(GL_BLEND);
 
  558          const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
 
  559          glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
 
  560          glDepthMask(GL_FALSE);
 
  562          glDepthMask(GL_TRUE);
 
  569 void TGLPlotPainter::ClearBuffers()
const 
  584 void TGLPlotPainter::DrawPaletteAxis()
const 
  590 void TGLPlotPainter::SaveModelviewMatrix()
const 
  592    glMatrixMode(GL_MODELVIEW);
 
  598 void TGLPlotPainter::SaveProjectionMatrix()
const 
  600    glMatrixMode(GL_PROJECTION);
 
  606 void TGLPlotPainter::RestoreModelviewMatrix()
const 
  608    glMatrixMode(GL_MODELVIEW);
 
  614 void TGLPlotPainter::RestoreProjectionMatrix()
const 
  616    glMatrixMode(GL_PROJECTION);
 
  626 ClassImp(TGLPlotCoordinates);
 
  631 TGLPlotCoordinates::TGLPlotCoordinates()
 
  632                         : fCoordType(kGLCartesian),
 
  647 TGLPlotCoordinates::~TGLPlotCoordinates()
 
  655 void TGLPlotCoordinates::SetCoordType(EGLCoordType type)
 
  657    if (fCoordType != type) {
 
  666 EGLCoordType TGLPlotCoordinates::GetCoordType()
const 
  675 void TGLPlotCoordinates::SetXLog(Bool_t xLog)
 
  686 Bool_t TGLPlotCoordinates::GetXLog()
const 
  695 void TGLPlotCoordinates::SetYLog(Bool_t yLog)
 
  706 Bool_t TGLPlotCoordinates::GetYLog()
const 
  715 void TGLPlotCoordinates::SetZLog(Bool_t zLog)
 
  726 Bool_t TGLPlotCoordinates::GetZLog()
const 
  734 void TGLPlotCoordinates::ResetModified()
 
  736    fModified = !fModified;
 
  742 Bool_t TGLPlotCoordinates::Modified()
const 
  750 Bool_t TGLPlotCoordinates::SetRanges(
const TH1 *hist, Bool_t errors, Bool_t zBins)
 
  752    switch (fCoordType) {
 
  754       return SetRangesPolar(hist);
 
  756       return SetRangesCylindrical(hist);
 
  758       return SetRangesSpherical(hist);
 
  761       return SetRangesCartesian(hist, errors, zBins);
 
  768 Int_t TGLPlotCoordinates::GetNXBins()
const 
  770    return fXBins.second - fXBins.first + 1;
 
  776 Int_t TGLPlotCoordinates::GetNYBins()
const 
  778    return fYBins.second - fYBins.first + 1;
 
  784 Int_t TGLPlotCoordinates::GetNZBins()
const 
  786    return fZBins.second - fZBins.first + 1;
 
  792 const Rgl::BinRange_t &TGLPlotCoordinates::GetXBins()
const 
  800 const Rgl::BinRange_t &TGLPlotCoordinates::GetYBins()
const 
  808 const Rgl::BinRange_t &TGLPlotCoordinates::GetZBins()
const 
  816 const Rgl::Range_t &TGLPlotCoordinates::GetXRange()
const 
  824 Double_t TGLPlotCoordinates::GetXLength()
const 
  826    return fXRange.second - fXRange.first;
 
  832 const Rgl::Range_t &TGLPlotCoordinates::GetYRange()
const 
  840 Double_t TGLPlotCoordinates::GetYLength()
const 
  842    return fYRange.second - fYRange.first;
 
  849 const Rgl::Range_t &TGLPlotCoordinates::GetZRange()
const 
  857 Double_t TGLPlotCoordinates::GetZLength()
const 
  859    return fZRange.second - fZRange.first;
 
  866 const Rgl::Range_t &TGLPlotCoordinates::GetXRangeScaled()
const 
  868    return fXRangeScaled;
 
  874 const Rgl::Range_t &TGLPlotCoordinates::GetYRangeScaled()
const 
  876    return fYRangeScaled;
 
  882 const Rgl::Range_t &TGLPlotCoordinates::GetZRangeScaled()
const 
  884    return fZRangeScaled;
 
  890 Double_t TGLPlotCoordinates::GetFactor()
const 
  897 Bool_t FindAxisRange(
const TAxis *axis, Bool_t log, Rgl::BinRange_t &bins, Rgl::Range_t &range);
 
  898 Bool_t FindAxisRange(
const TH1 *hist, Bool_t logZ, 
const Rgl::BinRange_t &xBins,
 
  899                      const Rgl::BinRange_t &yBins, Rgl::Range_t &zRange,
 
  900                      Double_t &factor, Bool_t errors);
 
  902 Bool_t FindAxisRange(TH2Poly *hist, Bool_t zLog, Rgl::Range_t &zRange);
 
  909 Bool_t TGLPlotCoordinates::SetRangesCartesian(
const TH1 *hist, Bool_t errors, Bool_t zAsBins)
 
  911    Rgl::BinRange_t xBins;
 
  913    if (!FindAxisRange(hist->GetXaxis(), fXLog, xBins, xRange)) {
 
  914       Error(
"TGLPlotCoordinates::SetRangesCartesian", 
"Cannot set X axis to log scale");
 
  918    Rgl::BinRange_t yBins;
 
  920    if (!FindAxisRange(hist->GetYaxis(), fYLog, yBins, yRange)) {
 
  921       Error(
"TGLPlotCoordinates::SetRangesCartesian", 
"Cannot set Y axis to log scale");
 
  925    Rgl::BinRange_t zBins;
 
  927    Double_t factor = 1.;
 
  930       if (!FindAxisRange(hist->GetZaxis(), fZLog, zBins, zRange)) {
 
  931          Error(
"TGLPlotCoordinates::SetRangesCartesian", 
"Cannot set Z axis to log scale");
 
  934    } 
else if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, errors)) {
 
  935       Error(
"TGLPlotCoordinates::SetRangesCartesian",
 
  936             "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
 
  941    const Double_t x = xRange.second - xRange.first;
 
  942    const Double_t y = yRange.second - yRange.first;
 
  943    const Double_t z = zRange.second - zRange.first;
 
  945    if (!x || !y || !z) {
 
  946       Error(
"TGLPlotCoordinates::SetRangesCartesian", 
"Zero axis range.");
 
  950    if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
 
  951        xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
 
  956    fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
 
  968    fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
 
  969    fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
 
  970    fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
 
  979 Bool_t TGLPlotCoordinates::SetRanges(TH2Poly *hist)
 
  981    Rgl::BinRange_t xBins;
 
  983    FindAxisRange(hist->GetXaxis(), kFALSE, xBins, xRange);
 
  985    Rgl::BinRange_t yBins;
 
  987    FindAxisRange(hist->GetYaxis(), kFALSE, yBins, yRange);
 
  989    Rgl::BinRange_t zBins;
 
  991    Double_t factor = 1.;
 
  993    if (!FindAxisRange(hist, fZLog, zRange))
 
  997    const Double_t x = xRange.second - xRange.first;
 
  998    const Double_t y = yRange.second - yRange.first;
 
  999    const Double_t z = zRange.second - zRange.first;
 
 1001    if (!x || !y || !z) {
 
 1002       Error(
"TGLPlotCoordinates::SetRanges", 
"Zero axis range.");
 
 1006    if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
 
 1007        xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
 
 1012    fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
 
 1015    fXScale = Rgl::gH2PolyScaleXY / x;
 
 1016    fYScale = Rgl::gH2PolyScaleXY / y;
 
 1019    fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
 
 1020    fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
 
 1021    fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
 
 1030 Bool_t TGLPlotCoordinates::SetRanges(
const TAxis *xAxis, 
const TAxis *yAxis, 
const TAxis *zAxis)
 
 1032    Rgl::BinRange_t xBins;
 
 1033    Rgl::Range_t    xRange;
 
 1035    FindAxisRange(xAxis, kFALSE, xBins, xRange);
 
 1037    Rgl::BinRange_t yBins;
 
 1038    Rgl::Range_t    yRange;
 
 1040    FindAxisRange(yAxis, kFALSE, yBins, yRange);
 
 1042    Rgl::BinRange_t zBins;
 
 1043    Rgl::Range_t zRange;
 
 1044    Double_t factor = 1.;
 
 1046    FindAxisRange(zAxis, kFALSE, zBins, zRange);
 
 1049    const Double_t x = xRange.second - xRange.first;
 
 1050    const Double_t y = yRange.second - yRange.first;
 
 1051    const Double_t z = zRange.second - zRange.first;
 
 1053    if (!x || !y || !z) {
 
 1054       Error(
"TGLPlotCoordinates::SetRangesCartesian", 
"Zero axis range.");
 
 1058    if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
 
 1059        xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
 
 1064    fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
 
 1076    fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
 
 1077    fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
 
 1078    fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
 
 1086 Bool_t TGLPlotCoordinates::SetRangesPolar(
const TH1 *hist)
 
 1088    Rgl::BinRange_t xBins;
 
 1089    Rgl::Range_t phiRange;
 
 1090    const TAxis *xAxis = hist->GetXaxis();
 
 1091    FindAxisRange(xAxis, kFALSE, xBins, phiRange);
 
 1092    if (xBins.second - xBins.first + 1 > 360) {
 
 1093       Error(
"TGLPlotCoordinates::SetRangesPolar", 
"To many PHI sectors");
 
 1097    Rgl::BinRange_t yBins;
 
 1098    Rgl::Range_t roRange;
 
 1099    const TAxis *yAxis = hist->GetYaxis();
 
 1100    FindAxisRange(yAxis, kFALSE, yBins, roRange);
 
 1102    Rgl::Range_t zRange;
 
 1103    Double_t factor = 1.;
 
 1104    if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, kFALSE))
 
 1106       Error(
"TGLPlotCoordinates::SetRangesPolar",
 
 1107             "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
 
 1111    const Double_t z = zRange.second - zRange.first;
 
 1112    if (!z || !(phiRange.second - phiRange.first) || !(roRange.second - roRange.first)) {
 
 1113       Error(
"TGLPlotCoordinates::SetRangesPolar", 
"Zero axis range.");
 
 1117    if (phiRange != fXRange || roRange != fYRange || zRange != fZRange ||
 
 1118        xBins != fXBins || yBins != fYBins || fFactor != factor)
 
 1121       fXRange = phiRange, fXBins = xBins;
 
 1122       fYRange = roRange,  fYBins = yBins;
 
 1131    fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
 
 1132    fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
 
 1133    fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
 
 1141 Bool_t TGLPlotCoordinates::SetRangesCylindrical(
const TH1 *hist)
 
 1143    Rgl::BinRange_t xBins, yBins;
 
 1144    Rgl::Range_t angleRange, heightRange, radiusRange;
 
 1145    const TAxis *xAxis = hist->GetXaxis();
 
 1146    const TAxis *yAxis = hist->GetYaxis();
 
 1147    Double_t factor = 1.;
 
 1149    FindAxisRange(xAxis, kFALSE, xBins, angleRange);
 
 1150    if (xBins.second - xBins.first + 1 > 360) {
 
 1151       Error(
"TGLPlotCoordinates::SetRangesCylindrical", 
"To many PHI sectors");
 
 1154    if (!FindAxisRange(yAxis, fYLog, yBins, heightRange)) {
 
 1155       Error(
"TGLPlotCoordinates::SetRangesCylindrical", 
"Cannot set Y axis to log scale");
 
 1158    FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
 
 1160    const Double_t x = angleRange.second  - angleRange.first;
 
 1161    const Double_t y = heightRange.second - heightRange.first;
 
 1162    const Double_t z = radiusRange.second - radiusRange.first;
 
 1164    if (!x || !y || !z) {
 
 1165       Error(
"TGLPlotCoordinates::SetRangesCylindrical", 
"Zero axis range.");
 
 1169    if (angleRange != fXRange  || heightRange != fYRange ||
 
 1170        radiusRange != fZRange || xBins != fXBins ||
 
 1171        yBins != fYBins || fFactor != factor)
 
 1174       fXRange = angleRange,  fXBins = xBins;
 
 1175       fYRange = heightRange, fYBins = yBins;
 
 1176       fZRange = radiusRange;
 
 1184    fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
 
 1185    fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
 
 1186    fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
 
 1194 Bool_t TGLPlotCoordinates::SetRangesSpherical(
const TH1 *hist)
 
 1196    Rgl::BinRange_t xBins;
 
 1197    Rgl::Range_t phiRange;
 
 1198    FindAxisRange(hist->GetXaxis(), kFALSE, xBins, phiRange);
 
 1199    if (xBins.second - xBins.first + 1 > 360) {
 
 1200       Error(
"TGLPlotCoordinates::SetRangesSpherical", 
"To many PHI sectors");
 
 1204    Rgl::BinRange_t yBins;
 
 1205    Rgl::Range_t thetaRange;
 
 1206    FindAxisRange(hist->GetYaxis(), kFALSE, yBins, thetaRange);
 
 1207    if (yBins.second - yBins.first + 1 > 180) {
 
 1208       Error(
"TGLPlotCoordinates::SetRangesSpherical", 
"To many THETA sectors");
 
 1212    Rgl::Range_t radiusRange;
 
 1213    Double_t factor = 1.;
 
 1214    FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
 
 1216    if (xBins != fXBins || yBins != fYBins ||
 
 1217        phiRange != fXRange || thetaRange != fYRange ||
 
 1218        radiusRange != fZRange || fFactor != factor)
 
 1224       fYRange   = thetaRange,
 
 1225       fZRange   = radiusRange;
 
 1232    fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
 
 1233    fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
 
 1234    fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
 
 1244 Double_t FindMinBinWidth(
const TAxis *axis)
 
 1246    Int_t currBin = axis->GetFirst();
 
 1247    Double_t width = axis->GetBinWidth(currBin);
 
 1249    if (!axis->IsVariableBinSize())
 
 1254    for (
const Int_t lastBin = axis->GetLast(); currBin <= lastBin; ++currBin)
 
 1255       width = TMath::Min(width, axis->GetBinWidth(currBin));
 
 1271 Bool_t FindAxisRange(
const TAxis *axis, Bool_t log, Rgl::BinRange_t &bins, Rgl::Range_t &range)
 
 1273    bins.first = axis->GetFirst(), bins.second = axis->GetLast();
 
 1274    range.first = axis->GetBinLowEdge(bins.first), range.second = axis->GetBinUpEdge(bins.second);
 
 1277       if (range.second <= 0.)
 
 1280       range.second = TMath::Log10(range.second);
 
 1282       if (range.first <= 0.) {
 
 1283          Int_t bin = axis->FindFixBin(FindMinBinWidth(axis) * 0.01);
 
 1285          if (bin > bins.second)
 
 1288          if (axis->GetBinLowEdge(bin) <= 0.) {
 
 1290             if (bin > bins.second)
 
 1295          range.first = axis->GetBinLowEdge(bin);
 
 1298       range.first = TMath::Log10(range.first);
 
 1307 Bool_t FindAxisRange(
const TH1 *hist, Bool_t logZ, 
const Rgl::BinRange_t &xBins,
 
 1308                      const Rgl::BinRange_t &yBins, Rgl::Range_t &zRange,
 
 1309                      Double_t &factor, Bool_t errors)
 
 1311    const Bool_t minimum = hist->GetMinimumStored() != -1111;
 
 1312    const Bool_t maximum = hist->GetMaximumStored() != -1111;
 
 1313    const Double_t margin = gStyle->GetHistTopMargin();
 
 1315    zRange.second = hist->GetBinContent(hist->GetBin(xBins.first, yBins.first)), zRange.first = zRange.second;
 
 1318    for (Int_t i = xBins.first; i <= xBins.second; ++i) {
 
 1319       for (Int_t j = yBins.first; j <= yBins.second; ++j) {
 
 1320          Double_t val = hist->GetBinContent(hist->GetBin(i, j));
 
 1321          if (val > 0. && errors)
 
 1322             val = TMath::Max(val, val + hist->GetCellError(i, j));
 
 1323          zRange.second = TMath::Max(val, zRange.second);
 
 1324          zRange.first = TMath::Min(val, zRange.first);
 
 1329    if (hist->GetMaximumStored() != -1111)
 
 1330       zRange.second = hist->GetMaximumStored();
 
 1331    if (hist->GetMinimumStored() != -1111)
 
 1332       zRange.first = hist->GetMinimumStored();
 
 1334    if (logZ && zRange.second <= 0.)
 
 1337    if (zRange.first >= zRange.second)
 
 1338       zRange.first = 0.001 * zRange.second;
 
 1340    factor = hist->GetNormFactor() > 0. ? hist->GetNormFactor() : summ;
 
 1341    if (summ) factor /= summ;
 
 1342    if (!factor) factor = 1.;
 
 1344       Warning(
"TGLPlotPainter::ExtractAxisZInfo",
 
 1345               "Negative factor, negative ranges - possible incorrect behavior");
 
 1347    zRange.second *= factor;
 
 1348    zRange.first  *= factor;
 
 1351       if (zRange.first <= 0.)
 
 1352          zRange.first = TMath::Min(1., 0.001 * zRange.second);
 
 1353       zRange.first = TMath::Log10(zRange.first);
 
 1355          zRange.first += TMath::Log10(0.5);
 
 1356       zRange.second = TMath::Log10(zRange.second);
 
 1358          zRange.second += TMath::Log10(2*(0.9/0.95));
 
 1363       zRange.second += margin * (zRange.second - zRange.first);
 
 1365       if (gStyle->GetHistMinimumZero())
 
 1366          zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
 
 1368          zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
 
 1369                zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
 
 1378 Bool_t FindAxisRange(TH2Poly *hist, Bool_t logZ, Rgl::Range_t &zRange)
 
 1380    TList *bins = hist->GetBins();
 
 1381    if (!bins || !bins->GetEntries()) {
 
 1382       Error(
"FindAxisRange", 
"TH2Poly returned empty list of bins");
 
 1386    zRange.first  = hist->GetMinimum();
 
 1387    zRange.second = hist->GetMaximum();
 
 1389    if (zRange.first >= zRange.second)
 
 1390       zRange.first = 0.001 * zRange.second;
 
 1393       if (zRange.second < 1e-20) {
 
 1394          Error(
"FindAxisRange", 
"Failed to switch Z axis to logarithmic scale");
 
 1398       if (zRange.first <= 0.)
 
 1399          zRange.first = TMath::Min(1., 0.001 * zRange.second);
 
 1401       zRange.first  = TMath::Log10(zRange.first);
 
 1402       zRange.first += TMath::Log10(0.5);
 
 1403       zRange.second = TMath::Log10(zRange.second);
 
 1404       zRange.second += TMath::Log10(2 * (0.9 / 0.95));
 
 1409    const Double_t margin = gStyle->GetHistTopMargin();
 
 1410    zRange.second += margin * (zRange.second - zRange.first);
 
 1411    if (gStyle->GetHistMinimumZero())
 
 1412       zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
 
 1414       zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
 
 1415          zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
 
 1427 ClassImp(TGLBoxCut);
 
 1432 TGLBoxCut::TGLBoxCut(
const TGLPlotBox *box)
 
 1445 TGLBoxCut::~TGLBoxCut()
 
 1453 void TGLBoxCut::TurnOnOff()
 
 1465 void TGLBoxCut::SetActive(Bool_t a)
 
 1475 void TGLBoxCut::ResetBoxGeometry()
 
 1477    const Int_t frontPoint = fPlotBox->GetFrontPoint();
 
 1478    const TGLVertex3 *box = fPlotBox->Get3DBox();
 
 1479    const TGLVertex3 center((box[0].X() + box[1].X()) / 2, (box[0].Y() + box[2].Y()) / 2,
 
 1480                            (box[0].Z() + box[4].Z()) / 2);
 
 1481    fXLength = fFactor * (box[1].X() - box[0].X());
 
 1482    fYLength = fFactor * (box[2].Y() - box[0].Y());
 
 1483    fZLength = fFactor * (box[4].Z() - box[0].Z());
 
 1487       fCenter.X() = box[0].X();
 
 1488       fCenter.Y() = box[0].Y();
 
 1491       fCenter.X() = box[1].X();
 
 1492       fCenter.Y() = box[0].Y();
 
 1495       fCenter.X() = box[2].X();
 
 1496       fCenter.Y() = box[2].Y();
 
 1499       fCenter.X() = box[0].X();
 
 1500       fCenter.Y() = box[2].Y();
 
 1504    fCenter.Z() = box[0].Z() * 0.5 + box[4].Z() * 0.5;
 
 1511 void TGLBoxCut::DrawBox(Bool_t selectionPass, Int_t selected)
const 
 1513    if (!selectionPass) {
 
 1514       glDisable(GL_LIGHTING);
 
 1517       selected == TGLPlotPainter::kXAxis ? glColor3d(1., 1., 0.) : glColor3d(1., 0., 0.);
 
 1519       glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
 
 1520       glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
 
 1523       selected == TGLPlotPainter::kYAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 1., 0.);
 
 1525       glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
 
 1526       glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
 
 1529       selected == TGLPlotPainter::kZAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 0., 1.);
 
 1531       glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
 
 1532       glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
 
 1536       glEnable(GL_LIGHTING);
 
 1538       GLboolean oldBlendState = kFALSE;
 
 1539       glGetBooleanv(GL_BLEND, &oldBlendState);
 
 1544       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 1547       const Float_t diffuseColor[] = {0.f, 0.f, 1.f, 0.1f};
 
 1548       glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseColor);
 
 1550       Rgl::DrawBoxFront(fXRange.first, fXRange.second, fYRange.first, fYRange.second,
 
 1551                         fZRange.first, fZRange.second, fPlotBox->GetFrontPoint());
 
 1554          glDisable(GL_BLEND);
 
 1557       Rgl::ObjectIDToColor(TGLPlotPainter::kXAxis, kFALSE);
 
 1559       glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
 
 1560       glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
 
 1563       Rgl::ObjectIDToColor(TGLPlotPainter::kYAxis, kFALSE);
 
 1565       glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
 
 1566       glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
 
 1569       Rgl::ObjectIDToColor(TGLPlotPainter::kZAxis, kFALSE);
 
 1571       glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
 
 1572       glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
 
 1581 void TGLBoxCut::StartMovement(Int_t px, Int_t py)
 
 1590 void TGLBoxCut::MoveBox(Int_t px, Int_t py, Int_t axisID)
 
 1592    Double_t mv[16] = {0.};
 
 1593    glGetDoublev(GL_MODELVIEW_MATRIX, mv);
 
 1594    Double_t pr[16] = {0.};
 
 1595    glGetDoublev(GL_PROJECTION_MATRIX, pr);
 
 1597    glGetIntegerv(GL_VIEWPORT, vp);
 
 1598    Double_t winVertex[3] = {0.};
 
 1601    case TGLPlotPainter::kXAxis :
 
 1602       gluProject(fCenter.X(), 0., 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
 
 1604    case TGLPlotPainter::kYAxis :
 
 1605       gluProject(0., fCenter.Y(), 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
 
 1607    case TGLPlotPainter::kZAxis :
 
 1608       gluProject(0., 0., fCenter.Z(), mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
 
 1612    winVertex[0] += px - fMousePos.fX;
 
 1613    winVertex[1] += py - fMousePos.fY;
 
 1614    Double_t newPoint[3] = {0.};
 
 1615    gluUnProject(winVertex[0], winVertex[1], winVertex[2], mv, pr, vp,
 
 1616                 newPoint, newPoint + 1, newPoint + 2);
 
 1618    const TGLVertex3 *box = fPlotBox->Get3DBox();
 
 1621    case TGLPlotPainter::kXAxis :
 
 1622       if (newPoint[0] >= box[1].X() + 0.4 * fXLength)
 
 1624       if (newPoint[0] <= box[0].X() - 0.4 * fXLength)
 
 1626       fCenter.X() = newPoint[0];
 
 1628    case TGLPlotPainter::kYAxis :
 
 1629       if (newPoint[1] >= box[2].Y() + 0.4 * fYLength)
 
 1631       if (newPoint[1] <= box[0].Y() - 0.4 * fYLength)
 
 1633       fCenter.Y() = newPoint[1];
 
 1635    case TGLPlotPainter::kZAxis :
 
 1636       if (newPoint[2] >= box[4].Z() + 0.4 * fZLength)
 
 1638       if (newPoint[2] <= box[0].Z() - 0.4 * fZLength)
 
 1640       fCenter.Z() = newPoint[2];
 
 1653 void TGLBoxCut::AdjustBox()
 
 1655    const TGLVertex3 *box = fPlotBox->Get3DBox();
 
 1657    fXRange.first  = fCenter.X() - fXLength / 2.;
 
 1658    fXRange.second = fCenter.X() + fXLength / 2.;
 
 1659    fYRange.first  = fCenter.Y() - fYLength / 2.;
 
 1660    fYRange.second = fCenter.Y() + fYLength / 2.;
 
 1661    fZRange.first  = fCenter.Z() - fZLength / 2.;
 
 1662    fZRange.second = fCenter.Z() + fZLength / 2.;
 
 1664    fXRange.first  = TMath::Max(fXRange.first,  box[0].X());
 
 1665    fXRange.first  = TMath::Min(fXRange.first,  box[1].X());
 
 1666    fXRange.second = TMath::Min(fXRange.second, box[1].X());
 
 1667    fXRange.second = TMath::Max(fXRange.second, box[0].X());
 
 1669    fYRange.first  = TMath::Max(fYRange.first,  box[0].Y());
 
 1670    fYRange.first  = TMath::Min(fYRange.first,  box[2].Y());
 
 1671    fYRange.second = TMath::Min(fYRange.second, box[2].Y());
 
 1672    fYRange.second = TMath::Max(fYRange.second, box[0].Y());
 
 1674    fZRange.first  = TMath::Max(fZRange.first,  box[0].Z());
 
 1675    fZRange.first  = TMath::Min(fZRange.first,  box[4].Z());
 
 1676    fZRange.second = TMath::Min(fZRange.second, box[4].Z());
 
 1677    fZRange.second = TMath::Max(fZRange.second, box[0].Z());
 
 1683 Bool_t TGLBoxCut::IsInCut(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
 
 1684                           Double_t zMin, Double_t zMax)
const 
 1686    if (((xMin >= fXRange.first && xMin < fXRange.second) || (xMax > fXRange.first && xMax <= fXRange.second)) &&
 
 1687        ((yMin >= fYRange.first && yMin < fYRange.second) || (yMax > fYRange.first && yMax <= fYRange.second)) &&
 
 1688        ((zMin >= fZRange.first && zMin < fZRange.second) || (zMax > fZRange.first && zMax <= fZRange.second)))
 
 1699 ClassImp(TGLTH3Slice);
 
 1704 TGLTH3Slice::TGLTH3Slice(
const TString &name, 
const TH3 *hist, 
const TGLPlotCoordinates *coord,
 
 1705                          const TGLPlotBox *box, ESliceAxis axis)
 
 1706                : TNamed(name, name),
 
 1715    fAxis = fAxisType == kXOZ ? fHist->GetYaxis() : fAxisType == kYOZ ? fHist->GetXaxis() : fHist->GetZaxis();
 
 1721 TGLTH3Slice::TGLTH3Slice(
const TString &name, 
const TH3 *hist, 
const TF3 *fun, 
const TGLPlotCoordinates *coord,
 
 1722                          const TGLPlotBox *box, ESliceAxis axis)
 
 1723                : TNamed(name, name),
 
 1732    fAxis = fAxisType == kXOZ ? fHist->GetYaxis() : fAxisType == kYOZ ? fHist->GetXaxis() : fHist->GetZaxis();
 
 1738 void TGLTH3Slice::SetSliceWidth(Int_t width)
 
 1743    if (fAxis->GetLast() - fAxis->GetFirst() + 1 <= width)
 
 1744       fSliceWidth = fAxis->GetLast() - fAxis->GetFirst() + 1;
 
 1746       fSliceWidth = width;
 
 1752 void TGLTH3Slice::DrawSlice(Double_t pos)
const 
 1755    for (Int_t i = fAxis->GetFirst(), e = fAxis->GetLast(); i <= e; ++i) {
 
 1756       if (pos >= fAxis->GetBinLowEdge(i) && pos <= fAxis->GetBinUpEdge(i)) {
 
 1763       Int_t low = 1, up = 2;
 
 1764       if (bin - fSliceWidth + 1 >= fAxis->GetFirst()) {
 
 1765          low = bin - fSliceWidth + 1;
 
 1768          low = fAxis->GetFirst();
 
 1769          up  = bin + (fSliceWidth - (bin - fAxis->GetFirst() + 1)) + 1;
 
 1773          FindMinMax(low, up);
 
 1775       if (!PreparePalette())
 
 1778       PrepareTexCoords(pos, low, up);
 
 1780       fPalette.EnableTexture(GL_REPLACE);
 
 1781       const TGLDisableGuard lightGuard(GL_LIGHTING);
 
 1782       DrawSliceTextured(pos);
 
 1783       fPalette.DisableTexture();
 
 1792 void TGLTH3Slice::FindMinMax(Int_t , Int_t )
const 
 1845 Bool_t TGLTH3Slice::PreparePalette()
const 
 1847    UInt_t paletteSize = ((TH1 *)fHist)->GetContour();
 
 1848    if (!paletteSize && !(paletteSize = gStyle->GetNumberContours()))
 
 1851    return fPalette.GeneratePalette(paletteSize, fMinMax);
 
 1857 void TGLTH3Slice::PrepareTexCoords(Double_t pos, Int_t low, Int_t up)
const 
 1859    switch (fAxisType) {
 
 1861       fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNZBins());
 
 1862       fTexCoords.SetRowLen(fCoord->GetNXBins());
 
 1865          for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
 
 1866             for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
 
 1868                for (Int_t level = low; level < up; ++ level)
 
 1869                   val += fHist->GetBinContent(i, level, j);
 
 1870                fTexCoords[jt][it] = fPalette.GetTexCoord(val);
 
 1874          for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
 
 1875             for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
 
 1876                Double_t val = fF3->Eval(fHist->GetXaxis()->GetBinCenter(i), pos, fHist->GetZaxis()->GetBinCenter(j));
 
 1877                if (val > fMinMax.second)
 
 1878                   val = fMinMax.second;
 
 1879                else if (val < fMinMax.first)
 
 1880                   val = fMinMax.first;
 
 1881                fTexCoords[jt][it] = fPalette.GetTexCoord(val);
 
 1887       fTexCoords.resize(fCoord->GetNYBins() * fCoord->GetNZBins());
 
 1888       fTexCoords.SetRowLen(fCoord->GetNYBins());
 
 1890          for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
 
 1891             for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i <= ei; ++i, ++it) {
 
 1893                for (Int_t level = low; level < up; ++ level)
 
 1894                   val += fHist->GetBinContent(level, i, j);
 
 1895                fTexCoords[jt][it] = fPalette.GetTexCoord(val);
 
 1899          for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
 
 1900             for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
 
 1901                Double_t val = fF3->Eval(pos, fHist->GetYaxis()->GetBinCenter(i), fHist->GetZaxis()->GetBinCenter(j));
 
 1902                if (val > fMinMax.second)
 
 1903                   val = fMinMax.second;
 
 1904                else if (val < fMinMax.first)
 
 1905                   val = fMinMax.first;
 
 1906                fTexCoords[jt][it] = fPalette.GetTexCoord(val);
 
 1912       fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNYBins());
 
 1913       fTexCoords.SetRowLen(fCoord->GetNYBins());
 
 1915          for (Int_t i = fCoord->GetFirstXBin(), ir = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++ir) {
 
 1916             for (Int_t j = fCoord->GetFirstYBin(), jr = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jr) {
 
 1918                for (Int_t level = low; level < up; ++ level)
 
 1919                   val += fHist->GetBinContent(i, j, level);
 
 1920                fTexCoords[ir][jr] = fPalette.GetTexCoord(val);
 
 1924          for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
 
 1925             for (Int_t j = fCoord->GetFirstYBin(), jt = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jt) {
 
 1926                Double_t val = fF3->Eval(fHist->GetXaxis()->GetBinCenter(i), fHist->GetYaxis()->GetBinCenter(j), pos);
 
 1927                if (val > fMinMax.second)
 
 1928                   val = fMinMax.second;
 
 1929                else if (val < fMinMax.first)
 
 1930                   val = fMinMax.first;
 
 1931                fTexCoords[it][jt] = fPalette.GetTexCoord(val);
 
 1943 void TGLTH3Slice::DrawSliceTextured(Double_t pos)
const 
 1945    const Double_t xScale = fCoord->GetXScale();
 
 1946    const Double_t yScale = fCoord->GetYScale();
 
 1947    const Double_t zScale = fCoord->GetZScale();
 
 1948    const TAxis *xA = fHist->GetXaxis();
 
 1949    const TAxis *yA = fHist->GetYaxis();
 
 1950    const TAxis *zA = fHist->GetZaxis();
 
 1952    switch (fAxisType) {
 
 1955       for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
 
 1956          for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i < ei; ++i, ++it) {
 
 1957             const Double_t xMin = xA->GetBinCenter(i) * xScale;
 
 1958             const Double_t xMax = xA->GetBinCenter(i + 1) * xScale;
 
 1959             const Double_t zMin = zA->GetBinCenter(j) * zScale;
 
 1960             const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
 
 1961             glBegin(GL_POLYGON);
 
 1962             glTexCoord1d(fTexCoords[jt][it]);
 
 1963             glVertex3d(xMin, pos, zMin);
 
 1964             glTexCoord1d(fTexCoords[jt + 1][it]);
 
 1965             glVertex3d(xMin, pos, zMax);
 
 1966             glTexCoord1d(fTexCoords[jt + 1][it + 1]);
 
 1967             glVertex3d(xMax, pos, zMax);
 
 1968             glTexCoord1d(fTexCoords[jt][it + 1]);
 
 1969             glVertex3d(xMax, pos, zMin);
 
 1976       for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
 
 1977          for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
 
 1978             const Double_t yMin = yA->GetBinCenter(i) * yScale;
 
 1979             const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
 
 1980             const Double_t zMin = zA->GetBinCenter(j) * zScale;
 
 1981             const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
 
 1982             glBegin(GL_POLYGON);
 
 1983             glTexCoord1d(fTexCoords[jt][it]);
 
 1984             glVertex3d(pos, yMin, zMin);
 
 1985             glTexCoord1d(fTexCoords[jt][it + 1]);
 
 1986             glVertex3d(pos, yMax, zMin);
 
 1987             glTexCoord1d(fTexCoords[jt + 1][it + 1]);
 
 1988             glVertex3d(pos, yMax, zMax);
 
 1989             glTexCoord1d(fTexCoords[jt + 1][it]);
 
 1990             glVertex3d(pos, yMin, zMax);
 
 1997       for (Int_t j = fCoord->GetFirstXBin(), jt = 0, ej = fCoord->GetLastXBin(); j < ej; ++j, ++jt) {
 
 1998          for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
 
 1999             const Double_t xMin = xA->GetBinCenter(j) * xScale;
 
 2000             const Double_t xMax = xA->GetBinCenter(j + 1) * xScale;
 
 2001             const Double_t yMin = yA->GetBinCenter(i) * yScale;
 
 2002             const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
 
 2003             glBegin(GL_POLYGON);
 
 2004             glTexCoord1d(fTexCoords[jt + 1][it]);
 
 2005             glVertex3d(xMax, yMin, pos);
 
 2006             glTexCoord1d(fTexCoords[jt + 1][it + 1]);
 
 2007             glVertex3d(xMax, yMax, pos);
 
 2008             glTexCoord1d(fTexCoords[jt][it + 1]);
 
 2009             glVertex3d(xMin, yMax, pos);
 
 2010             glTexCoord1d(fTexCoords[jt][it]);
 
 2011             glVertex3d(xMin, yMin, pos);
 
 2023 void DrawBoxOutline(Double_t xMin, Double_t xMax, Double_t yMin,
 
 2024                     Double_t yMax, Double_t zMin, Double_t zMax)
 
 2026    glBegin(GL_LINE_LOOP);
 
 2027    glVertex3d(xMin, yMin, zMin);
 
 2028    glVertex3d(xMax, yMin, zMin);
 
 2029    glVertex3d(xMax, yMax, zMin);
 
 2030    glVertex3d(xMin, yMax, zMin);
 
 2033    glBegin(GL_LINE_LOOP);
 
 2034    glVertex3d(xMin, yMin, zMax);
 
 2035    glVertex3d(xMax, yMin, zMax);
 
 2036    glVertex3d(xMax, yMax, zMax);
 
 2037    glVertex3d(xMin, yMax, zMax);
 
 2041    glVertex3d(xMin, yMin, zMin);
 
 2042    glVertex3d(xMin, yMin, zMax);
 
 2043    glVertex3d(xMax, yMin, zMin);
 
 2044    glVertex3d(xMax, yMin, zMax);
 
 2045    glVertex3d(xMax, yMax, zMin);
 
 2046    glVertex3d(xMax, yMax, zMax);
 
 2047    glVertex3d(xMin, yMax, zMin);
 
 2048    glVertex3d(xMin, yMax, zMax);
 
 2057 void TGLTH3Slice::DrawSliceFrame(Int_t low, Int_t up)
const 
 2059    glColor3d(1., 0., 0.);
 
 2060    const TGLVertex3 *box = fBox->Get3DBox();
 
 2062    switch (fAxisType) {
 
 2064       DrawBoxOutline(box[0].X(), box[1].X(),
 
 2065                      fAxis->GetBinLowEdge(low) * fCoord->GetYScale(),
 
 2066                      fAxis->GetBinUpEdge(up - 1) * fCoord->GetYScale(),
 
 2067                      box[0].Z(), box[4].Z());
 
 2070       DrawBoxOutline(fAxis->GetBinLowEdge(low) * fCoord->GetXScale(),
 
 2071                      fAxis->GetBinUpEdge(up - 1) * fCoord->GetXScale(),
 
 2072                      box[0].Y(), box[2].Y(),
 
 2073                      box[0].Z(), box[4].Z());
 
 2076       DrawBoxOutline(box[0].X(), box[1].X(),
 
 2077                      box[0].Y(), box[2].Y(),
 
 2078                      fAxis->GetBinLowEdge(low) * fCoord->GetZScale(),
 
 2079                      fAxis->GetBinUpEdge(up - 1) * fCoord->GetZScale());
 
 2088 PlotTranslation::PlotTranslation(
const TGLPlotPainter *painter)
 
 2091    const TGLVertex3 *box = fPainter->fBackBox.Get3DBox();
 
 2092    const Double_t center[] = {(box[0].X() + box[1].X()) / 2,
 
 2093                               (box[0].Y() + box[2].Y()) / 2,
 
 2094                               (box[0].Z() + box[4].Z()) / 2};
 
 2096    fPainter->SaveModelviewMatrix();
 
 2097    glTranslated(-center[0], -center[1], -center[2]);
 
 2102 PlotTranslation::~PlotTranslation()
 
 2104    fPainter->RestoreModelviewMatrix();
 
 2110 const Double_t lr = 0.85;
 
 2111 const Double_t rr = 0.9;
 
 2118 void DrawPalette(
const TGLPlotCamera * camera, 
const TGLLevelPalette & palette)
 
 2120    const TGLDisableGuard light(GL_LIGHTING);
 
 2121    const TGLDisableGuard depth(GL_DEPTH_TEST);
 
 2122    const TGLEnableGuard blend(GL_BLEND);
 
 2124    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 2126    glMatrixMode(GL_PROJECTION);
 
 2128    glOrtho(0, camera->GetWidth(), 0, camera->GetHeight(), -1., 1.);
 
 2130    glMatrixMode(GL_MODELVIEW);
 
 2133    const Double_t leftX = camera->GetWidth() * lr;
 
 2134    const Double_t rightX = camera->GetWidth() * rr;
 
 2135    const Double_t margin = 0.1 * camera->GetHeight();
 
 2136    const Double_t h = (camera->GetHeight() * 0.8) / palette.GetPaletteSize();
 
 2138    for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
 
 2139       glBegin(GL_POLYGON);
 
 2140       const UChar_t * color = palette.GetColour(i);
 
 2141       glColor4ub(color[0], color[1], color[2], 150);
 
 2142       glVertex2d(leftX, margin + i * h);
 
 2143       glVertex2d(rightX, margin + i * h);
 
 2144       glVertex2d(rightX, margin + (i + 1) * h);
 
 2145       glVertex2d(leftX, margin + (i + 1) * h);
 
 2149    const TGLEnableGuard  smoothGuard(GL_LINE_SMOOTH);
 
 2150    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
 
 2151    glColor4d(0., 0., 0., 0.5);
 
 2153    for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
 
 2154       glBegin(GL_LINE_LOOP);
 
 2155       glVertex2d(leftX, margin + i * h);
 
 2156       glVertex2d(rightX, margin + i * h);
 
 2157       glVertex2d(rightX, margin + (i + 1) * h);
 
 2158       glVertex2d(leftX, margin + (i + 1) * h);
 
 2167 void DrawPalette(
const TGLPlotCamera * camera, 
const TGLLevelPalette & palette,
 
 2168                  const std::vector<Double_t> & levels)
 
 2170    const TGLDisableGuard light(GL_LIGHTING);
 
 2171    const TGLDisableGuard depth(GL_DEPTH_TEST);
 
 2172    const TGLEnableGuard blend(GL_BLEND);
 
 2174    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 2176    glMatrixMode(GL_PROJECTION);
 
 2178    glOrtho(0, camera->GetWidth(), 0, camera->GetHeight(), -1., 1.);
 
 2180    glMatrixMode(GL_MODELVIEW);
 
 2183    const Double_t leftX = camera->GetWidth() * lr;
 
 2184    const Double_t rightX = camera->GetWidth() * rr;
 
 2185    const Double_t margin = 0.1 * camera->GetHeight();
 
 2186    const Double_t h = (camera->GetHeight() * 0.8);
 
 2187    const Double_t range = levels.back() - levels.front();
 
 2189    const UChar_t opacity = 200;
 
 2191    for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
 
 2192       const Double_t yMin = margin + (levels[i] - levels.front()) / range * h;
 
 2193       const Double_t yMax = margin + (levels[i + 1] - levels.front()) / range * h;
 
 2194       glBegin(GL_POLYGON);
 
 2195       const UChar_t * color = palette.GetColour(i);
 
 2196       glColor4ub(color[0], color[1], color[2], opacity);
 
 2197       glVertex2d(leftX, yMin);
 
 2198       glVertex2d(rightX, yMin);
 
 2199       glVertex2d(rightX, yMax);
 
 2200       glVertex2d(leftX, yMax);
 
 2204    const TGLEnableGuard  smoothGuard(GL_LINE_SMOOTH);
 
 2205    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
 
 2206    glColor4d(0., 0., 0., 0.5);
 
 2208    for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
 
 2209       const Double_t yMin = (levels[i] - levels.front()) / range * h;
 
 2210       const Double_t yMax = (levels[i + 1] - levels.front()) / range * h;
 
 2212       glBegin(GL_LINE_LOOP);
 
 2213       glVertex2d(leftX, margin + yMin);
 
 2214       glVertex2d(rightX, margin + yMin);
 
 2215       glVertex2d(rightX, margin + yMax);
 
 2216       glVertex2d(leftX, margin + yMax);
 
 2224 void DrawPaletteAxis(
const TGLPlotCamera * camera, 
const Range_t & minMax, Bool_t logZ)
 
 2226    UInt_t pixelW = camera->GetWidth();
 
 2227    UInt_t pixelH = camera->GetHeight();
 
 2229    TGLUtil::InitializeIfNeeded();
 
 2230    const Float_t scale = TGLUtil::GetScreenScalingFactor();
 
 2232       pixelW = UInt_t(pixelW / scale);
 
 2233       pixelH = UInt_t(pixelH / scale);
 
 2236    const Double_t x = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw() + rr * pixelW));
 
 2237    const Double_t yMin = gPad->AbsPixeltoY(Int_t(gPad->GetWh() - (pixelH * 0.1
 
 2238                                            + gPad->GetYlowNDC() * gPad->GetWh())));
 
 2239    const Double_t yMax = gPad->AbsPixeltoY(Int_t(gPad->GetWh() - (pixelH * 0.9
 
 2240                                            + gPad->GetYlowNDC() * gPad->GetWh())));
 
 2242    Double_t zMin = minMax.first;
 
 2243    Double_t zMax = minMax.second;
 
 2246       zMin = TMath::Power(10, zMin);
 
 2247       zMax = TMath::Power(10, zMax);
 
 2251    const Bool_t logX = gPad->GetLogx();
 
 2252    gPad->SetLogx(kFALSE);
 
 2253    const Bool_t logY = gPad->GetLogy();
 
 2254    gPad->SetLogy(kFALSE);
 
 2256    TGaxis axisPainter(x, yMin, x, yMax, zMin, zMax, 510, logZ ? 
"G" : 
"");
 
 2257    axisPainter.Paint();
 
 2259    gPad->SetLogx(logX);
 
 2260    gPad->SetLogy(logY);
 
 2264 const Double_t gH2PolyScaleXY = 1.2;