TGLLegoPainter.cxx

Go to the documentation of this file.
00001 // @(#)root/gl:$Id: TGLLegoPainter.cxx 36431 2010-10-27 10:16:50Z couet $
00002 // Author:  Timur Pocheptsov  14/06/2006
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 #include <algorithm>
00012 #include <cctype>
00013 
00014 #include "KeySymbols.h"
00015 #include "TVirtualX.h"
00016 #include "Buttons.h"
00017 #include "TString.h"
00018 #include "TColor.h"
00019 #include "TROOT.h"
00020 #include "TClass.h"
00021 #include "TStyle.h"
00022 #include "TAxis.h"
00023 #include "TMath.h"
00024 #include "TH1.h"
00025 
00026 #include "TGLLegoPainter.h"
00027 #include "TGLPlotCamera.h"
00028 #include "TGLIncludes.h"
00029 
00030 //______________________________________________________________________________
00031 //
00032 // Plot-painter implementing LEGO rendering of TH2 histograms in
00033 // cartesian, polar, cylindrical and spherical coordinates.
00034 
00035 ClassImp(TGLLegoPainter)
00036 
00037 //______________________________________________________________________________
00038 TGLLegoPainter::TGLLegoPainter(TH1 *hist, TGLPlotCamera *cam, TGLPlotCoordinates *coord)
00039                   : TGLPlotPainter(hist, cam, coord, kFALSE, kTRUE, kTRUE),
00040                     fLegoType(kColorSimple),
00041                     fMinZ(0.),
00042                     fDrawErrors(kFALSE)
00043 {
00044    //Ctor.
00045 }
00046 
00047 //______________________________________________________________________________
00048 char *TGLLegoPainter::GetPlotInfo(Int_t /*px*/, Int_t /*py*/)
00049 {
00050    //Obtain bin's info (i, j, value).
00051    fBinInfo = "";
00052 
00053    if (fSelectedPart) {
00054       if (fSelectedPart < fSelectionBase) {
00055          if (fHist->Class())
00056             fBinInfo += fHist->Class()->GetName();
00057          fBinInfo += "::";
00058          fBinInfo += fHist->GetName();
00059       } else if (!fHighColor) {
00060          const Int_t binI = (fSelectedPart - fSelectionBase) / fCoord->GetNYBins() + fCoord->GetFirstXBin();
00061          const Int_t binJ = (fSelectedPart - fSelectionBase) % fCoord->GetNYBins() + fCoord->GetFirstYBin();
00062          fBinInfo.Form("(binx = %d; biny = %d; binc = %f)", binI, binJ,
00063                        fHist->GetBinContent(binI, binJ));
00064       } else
00065          fBinInfo = "Switch to true-color mode to obtain correct info";
00066    }
00067 
00068    return (Char_t *)fBinInfo.Data();
00069 }
00070 
00071 //______________________________________________________________________________
00072 Bool_t TGLLegoPainter::InitGeometry()
00073 {
00074    //Select method.
00075 
00076    Bool_t ret = kFALSE;
00077    switch (fCoord->GetCoordType()) {
00078    case kGLCartesian:
00079       ret = InitGeometryCartesian(); break;
00080    case kGLPolar:
00081       ret = InitGeometryPolar(); break;
00082    case kGLCylindrical:
00083       ret = InitGeometryCylindrical(); break;
00084    case kGLSpherical:
00085       ret = InitGeometrySpherical(); break;
00086    default:
00087       return kFALSE;
00088    }
00089    if (ret && fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());
00090    return ret;
00091 }
00092 
00093 //______________________________________________________________________________
00094 Bool_t TGLLegoPainter::InitGeometryCartesian()
00095 {
00096    //Geometry for lego in cartesian coords.
00097    if (!fCoord->SetRanges(fHist, fDrawErrors, kFALSE))
00098       return kFALSE;
00099 
00100    fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
00101 
00102    //Find bin edges
00103    const Int_t nX = fCoord->GetNXBins();
00104    const Double_t barWidth = fHist->GetBarWidth(), barOffset = fHist->GetBarOffset();
00105    const TGLVertex3 *frame = fBackBox.Get3DBox();
00106    fXEdges.resize(nX);
00107 
00108    if (fCoord->GetXLog()) {
00109       for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00110          const Double_t xWidth = fXAxis->GetBinWidth(ir);
00111          Double_t low = fXAxis->GetBinLowEdge(ir) + xWidth * barOffset;
00112          fXEdges[i].first  = TMath::Log10(low) * fCoord->GetXScale();
00113          fXEdges[i].second = TMath::Log10(low + xWidth * barWidth) * fCoord->GetXScale();
00114          if (fXEdges[i].second > frame[1].X())
00115             fXEdges[i].second = frame[1].X();
00116          if (fXEdges[i].first < frame[0].X())
00117             fXEdges[i].first = frame[0].X();
00118          if (fXEdges[i].second < frame[0].X())
00119             fXEdges[i].second = frame[0].X();
00120       }
00121    } else {
00122       for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00123          const Double_t xWidth = fXAxis->GetBinWidth(ir);
00124          fXEdges[i].first  = (fXAxis->GetBinLowEdge(ir) + xWidth * barOffset) * fCoord->GetXScale();
00125          fXEdges[i].second = fXEdges[i].first + xWidth * barWidth * fCoord->GetXScale();
00126          if (fXEdges[i].second > frame[1].X())
00127             fXEdges[i].second = frame[1].X();
00128          if (fXEdges[i].first < frame[0].X())
00129             fXEdges[i].first = frame[0].X();
00130          if (fXEdges[i].second < frame[0].X())
00131             fXEdges[i].second = frame[0].X();
00132       }
00133    }
00134 
00135    const Int_t nY = fCoord->GetNYBins();
00136    fYEdges.resize(nY);
00137 
00138    if (fCoord->GetYLog()) {
00139       for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00140          const Double_t yWidth = fYAxis->GetBinWidth(jr);
00141          Double_t low = fYAxis->GetBinLowEdge(jr) + yWidth * barOffset;
00142          fYEdges[j].first  = TMath::Log10(low) * fCoord->GetYScale();
00143          fYEdges[j].second = TMath::Log10(low + yWidth * barWidth) * fCoord->GetYScale();
00144          if (fYEdges[j].second > frame[2].Y())
00145             fYEdges[j].second = frame[2].Y();
00146          if (fYEdges[j].first < frame[0].Y())
00147             fYEdges[j].first = frame[0].Y();
00148          if (fYEdges[j].second < frame[0].Y())
00149             fYEdges[j].second = frame[0].Y();
00150       }
00151    } else {
00152       for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00153          const Double_t yWidth = fYAxis->GetBinWidth(jr);
00154          fYEdges[j].first  = (fYAxis->GetBinLowEdge(jr) + yWidth * barOffset) * fCoord->GetYScale();
00155          fYEdges[j].second = fYEdges[j].first + yWidth * barWidth * fCoord->GetYScale();
00156          if (fYEdges[j].second > frame[2].Y())
00157             fYEdges[j].second = frame[2].Y();
00158          if (fYEdges[j].first < frame[0].Y())
00159             fYEdges[j].first = frame[0].Y();
00160          if (fYEdges[j].second < frame[0].Y())
00161             fYEdges[j].second = frame[0].Y();
00162       }
00163    }
00164 
00165    fMinZ = frame[0].Z();
00166    if (fMinZ < 0.)
00167       frame[4].Z() > 0. ? fMinZ = 0. : fMinZ = frame[4].Z();
00168 
00169    if (fCoord->Modified()) {
00170       fUpdateSelection = kTRUE;
00171       fXOZSectionPos = frame[0].Y();
00172       fYOZSectionPos = frame[0].X();
00173       fXOYSectionPos = frame[0].Z();
00174       fCoord->ResetModified();
00175       Rgl::SetZLevels(fZAxis, fCoord->GetZRange().first, fCoord->GetZRange().second, fCoord->GetZScale(), fZLevels);
00176    }
00177 
00178    fMinMaxVal.first  = fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin());
00179    fMinMaxVal.second = fMinMaxVal.first;
00180 
00181    for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
00182       for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
00183          Double_t val = fHist->GetBinContent(i, j);
00184          fMinMaxVal.first  = TMath::Min(fMinMaxVal.first, val);
00185          fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
00186       }
00187    }
00188 
00189    ClampZ(fMinMaxVal.first);
00190    ClampZ(fMinMaxVal.second);
00191 
00192    return kTRUE;
00193 }
00194 
00195 //______________________________________________________________________________
00196 Bool_t TGLLegoPainter::InitGeometryPolar()
00197 {
00198    //Geometry for lego in polar coords.
00199    if (!fCoord->SetRanges(fHist, kFALSE, kFALSE))
00200       return kFALSE;
00201 
00202    fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
00203 
00204    if (fCoord->Modified()) {
00205       fUpdateSelection = kTRUE;
00206       fCoord->ResetModified();
00207    }
00208 
00209    const Int_t nY = fCoord->GetNYBins();//yBins.second - yBins.first + 1;
00210    fYEdges.resize(nY);
00211 
00212    for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00213       fYEdges[j].first = ((fYAxis->GetBinLowEdge(jr)) - fCoord->GetYRange().first) /
00214                            fCoord->GetYLength() * fCoord->GetYScale();
00215       fYEdges[j].second = ((fYAxis->GetBinUpEdge(jr)) - fCoord->GetYRange().first) /
00216                            fCoord->GetYLength() * fCoord->GetYScale();
00217    }
00218 
00219    const Int_t nX = fCoord->GetNXBins();
00220    fCosSinTableX.resize(nX + 1);
00221    const Double_t fullAngle = fXAxis->GetXmax() - fXAxis->GetXmin();
00222    const Double_t phiLow = fXAxis->GetXmin();
00223    Double_t angle = 0;
00224    for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00225       angle = (fXAxis->GetBinLowEdge(ir) - phiLow) / fullAngle * TMath::TwoPi();
00226       fCosSinTableX[i].first  = TMath::Cos(angle);
00227       fCosSinTableX[i].second = TMath::Sin(angle);
00228    }
00229    angle = (fXAxis->GetBinUpEdge(fCoord->GetLastXBin()) - phiLow) / fullAngle * TMath::TwoPi();
00230    fCosSinTableX[nX].first  = TMath::Cos(angle);
00231    fCosSinTableX[nX].second = TMath::Sin(angle);
00232 
00233    fMinZ = fBackBox.Get3DBox()[0].Z();
00234    if (fMinZ < 0.)
00235       fBackBox.Get3DBox()[4].Z() > 0. ? fMinZ = 0. : fMinZ = fBackBox.Get3DBox()[4].Z();
00236 
00237    fMinMaxVal.first  = fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin());
00238    fMinMaxVal.second = fMinMaxVal.first;
00239 
00240    for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
00241       for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
00242          Double_t val = fHist->GetBinContent(i, j);
00243          fMinMaxVal.first  = TMath::Min(fMinMaxVal.first, val);
00244          fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
00245       }
00246    }
00247 
00248    ClampZ(fMinMaxVal.first);
00249    ClampZ(fMinMaxVal.second);
00250 
00251    return kTRUE;
00252 }
00253 
00254 //______________________________________________________________________________
00255 Bool_t TGLLegoPainter::InitGeometryCylindrical()
00256 {
00257    //Geometry for lego in cylindrical coords.
00258    if (!fCoord->SetRanges(fHist, kFALSE, kFALSE))
00259       return kFALSE;
00260 
00261    fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
00262 
00263    const Int_t nY = fCoord->GetNYBins();
00264    fYEdges.resize(nY);
00265 
00266    if (fCoord->GetYLog()) {
00267       for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00268          fYEdges[j].first  = TMath::Log10(fYAxis->GetBinLowEdge(jr)) * fCoord->GetYScale();
00269          fYEdges[j].second = TMath::Log10(fYAxis->GetBinUpEdge(jr))  * fCoord->GetYScale();
00270       }
00271    } else {
00272       for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00273          fYEdges[j].first  = fYAxis->GetBinLowEdge(jr) * fCoord->GetYScale();
00274          fYEdges[j].second = fYAxis->GetBinUpEdge(jr)  * fCoord->GetYScale();
00275       }
00276    }
00277 
00278    const Int_t nX = fCoord->GetNXBins();
00279    fCosSinTableX.resize(nX + 1);
00280    const Double_t fullAngle = fXAxis->GetXmax() - fXAxis->GetXmin();
00281    const Double_t phiLow    = fXAxis->GetXmin();
00282    Double_t angle = 0.;
00283    for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00284       angle = (fXAxis->GetBinLowEdge(ir) - phiLow) / fullAngle * TMath::TwoPi();
00285       fCosSinTableX[i].first  = TMath::Cos(angle);
00286       fCosSinTableX[i].second = TMath::Sin(angle);
00287    }
00288    angle = (fXAxis->GetBinUpEdge(fCoord->GetLastXBin()) - phiLow) / fullAngle * TMath::TwoPi();
00289    fCosSinTableX[nX].first  = TMath::Cos(angle);
00290    fCosSinTableX[nX].second = TMath::Sin(angle);
00291 
00292    if (fCoord->Modified()) {
00293       fUpdateSelection = kTRUE;
00294       fCoord->ResetModified();
00295    }
00296 
00297    fMinZ = fCoord->GetZRange().first;
00298    if (fMinZ < 0.)
00299       fCoord->GetZRange().second > 0. ? fMinZ = 0. : fMinZ = fCoord->GetZRange().second;
00300 
00301 
00302    fMinMaxVal.first  = fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin());
00303    fMinMaxVal.second = fMinMaxVal.first;
00304 
00305    for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
00306       for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
00307          Double_t val = fHist->GetBinContent(i, j);
00308          fMinMaxVal.first  = TMath::Min(fMinMaxVal.first, val);
00309          fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
00310       }
00311    }
00312 
00313    return kTRUE;
00314 }
00315 
00316 //______________________________________________________________________________
00317 Bool_t TGLLegoPainter::InitGeometrySpherical()
00318 {
00319    //Geometry for lego in spherical coords.
00320    if (!fCoord->SetRanges(fHist, kFALSE, kFALSE))
00321       return kFALSE;
00322 
00323    fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
00324 
00325    const Int_t nY = fCoord->GetNYBins();
00326    fCosSinTableY.resize(nY + 1);
00327    const Double_t fullTheta = fYAxis->GetXmax() - fYAxis->GetXmin();
00328    const Double_t thetaLow  = fYAxis->GetXmin();
00329    Double_t angle = 0.;
00330    for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00331       angle = (fYAxis->GetBinLowEdge(jr) - thetaLow) / fullTheta * TMath::Pi();
00332       fCosSinTableY[j].first = TMath::Cos(angle);
00333       fCosSinTableY[j].second = TMath::Sin(angle);
00334    }
00335    angle = (fYAxis->GetBinUpEdge(fCoord->GetLastYBin()) - thetaLow) / fullTheta * TMath::Pi();
00336    fCosSinTableY[nY].first = TMath::Cos(angle);
00337    fCosSinTableY[nY].second = TMath::Sin(angle);
00338 
00339    const Int_t nX = fCoord->GetNXBins();
00340    fCosSinTableX.resize(nX + 1);
00341    const Double_t fullPhi = fXAxis->GetXmax() - fXAxis->GetXmin();
00342    const Double_t phiLow  = fXAxis->GetXmin();
00343 
00344    for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00345       angle = (fXAxis->GetBinLowEdge(ir) - phiLow) / fullPhi * TMath::TwoPi();
00346       fCosSinTableX[i].first  = TMath::Cos(angle);
00347       fCosSinTableX[i].second = TMath::Sin(angle);
00348    }
00349 
00350    angle = (fXAxis->GetBinUpEdge(fCoord->GetLastXBin()) - phiLow) / fullPhi * TMath::TwoPi();
00351    fCosSinTableX[nX].first  = TMath::Cos(angle);
00352    fCosSinTableX[nX].second = TMath::Sin(angle);
00353 
00354    fMinZ = fCoord->GetZRange().first;
00355    if (fMinZ < 0.)
00356       fCoord->GetZRange().second > 0. ? fMinZ = 0. : fMinZ = fCoord->GetZRange().second;
00357 
00358    fMinMaxVal.first  = fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin());
00359    fMinMaxVal.second = fMinMaxVal.first;
00360 
00361    for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
00362       for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
00363          Double_t val = fHist->GetBinContent(i, j);
00364          fMinMaxVal.first  = TMath::Min(fMinMaxVal.first, val);
00365          fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
00366       }
00367    }
00368 
00369 
00370    return kTRUE;
00371 }
00372 
00373 //______________________________________________________________________________
00374 void TGLLegoPainter::StartPan(Int_t px, Int_t py)
00375 {
00376    //User clicks on a lego with middle mouse button (middle for pad).
00377    fMousePosition.fX = px;
00378    fMousePosition.fY = fCamera->GetHeight() - py;
00379    fCamera->StartPan(px, py);
00380    fBoxCut.StartMovement(px, py);
00381 }
00382 
00383 //______________________________________________________________________________
00384 void TGLLegoPainter::Pan(Int_t px, Int_t py)
00385 {
00386    //Move lego or section.
00387    if (fSelectedPart >= fSelectionBase || fSelectedPart == 1) {
00388       SaveModelviewMatrix();
00389       SaveProjectionMatrix();
00390 
00391       fCamera->SetCamera();
00392       fCamera->Apply(fPadPhi, fPadTheta);
00393       fCamera->Pan(px, py);
00394 
00395       RestoreProjectionMatrix();
00396       RestoreModelviewMatrix();
00397    } else if (fSelectedPart > 0) {
00398       //Convert py into bottom-top orientation.
00399       py = fCamera->GetHeight() - py;
00400 
00401       SaveModelviewMatrix();
00402       SaveProjectionMatrix();
00403 
00404       fCamera->SetCamera();
00405       fCamera->Apply(fPadPhi, fPadTheta);
00406 
00407       if (!fHighColor) {
00408          if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis))
00409             fBoxCut.MoveBox(px, py, fSelectedPart);
00410          else
00411             MoveSection(px, py);
00412       } else
00413          MoveSection(px, py);
00414 
00415       RestoreProjectionMatrix();
00416       RestoreModelviewMatrix();
00417    }
00418 
00419    fMousePosition.fX = px, fMousePosition.fY = py;
00420    fUpdateSelection = kTRUE;
00421 }
00422 
00423 //______________________________________________________________________________
00424 void TGLLegoPainter::AddOption(const TString &option)
00425 {
00426    //Parse additional options.
00427    using namespace std;
00428    const Ssiz_t legoPos = option.Index("lego");//"lego" _already_ _exists_ in a string.
00429    if (legoPos + 4 < option.Length() && isdigit(option[legoPos + 4])) {
00430       switch (option[legoPos + 4] - '0') {
00431       case 1:
00432          fLegoType = kColorSimple;
00433          break;
00434       case 2:
00435          fLegoType = kColorLevel;
00436          break;
00437       case 3:
00438          fLegoType = kCylindricBars;
00439          break;
00440       default:
00441          fLegoType = kColorSimple;
00442          break;
00443       }
00444    } else
00445       fLegoType = kColorSimple;
00446    //check 'e' option
00447    Ssiz_t ePos = option.Index("e");
00448    if (ePos == legoPos + 1)
00449       ePos = option.Index("e", legoPos + 4);
00450    fDrawErrors = ePos != kNPOS ? kTRUE : kFALSE;
00451 
00452    option.Index("z") == kNPOS ? fDrawPalette = kFALSE : fDrawPalette = kTRUE;
00453 }
00454 
00455 //______________________________________________________________________________
00456 void TGLLegoPainter::InitGL()const
00457 {
00458    //Initialize some gl state variables.
00459    glEnable(GL_DEPTH_TEST);
00460    glEnable(GL_LIGHTING);
00461    glEnable(GL_LIGHT0);
00462    //For lego, back polygons are culled (but not for sections).
00463    glEnable(GL_CULL_FACE);
00464    glCullFace(GL_BACK);
00465 
00466    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00467 }
00468 
00469 //______________________________________________________________________________
00470 void TGLLegoPainter::DeInitGL()const
00471 {
00472    //Return some gl states to original values.
00473    glDisable(GL_DEPTH_TEST);
00474    glDisable(GL_LIGHTING);
00475    glDisable(GL_LIGHT0);
00476    glDisable(GL_CULL_FACE);
00477    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
00478 }
00479 
00480 //______________________________________________________________________________
00481 void TGLLegoPainter::DrawPlot()const
00482 {
00483    //Select method corresponding to coordinate system.
00484 
00485    //Shift plot to point of origin.
00486    const Rgl::PlotTranslation trGuard(this);
00487 
00488    switch (fCoord->GetCoordType()) {
00489    case kGLCartesian:
00490       return DrawLegoCartesian();
00491    case kGLPolar:
00492       return DrawLegoPolar();
00493    case kGLCylindrical:
00494       return DrawLegoCylindrical();
00495    case kGLSpherical:
00496       return DrawLegoSpherical();
00497    default:;
00498    }
00499 }
00500 
00501 //______________________________________________________________________________
00502 void TGLLegoPainter::DrawLegoCartesian()const
00503 {
00504    //Lego in cartesian system.
00505    if (fCoord->GetCoordType() == kGLCartesian) {
00506       fBackBox.DrawBox(fSelectedPart, fSelectionPass, fZLevels, fHighColor);
00507       const TGLDisableGuard cullGuard(GL_CULL_FACE);
00508       DrawSections();
00509    }
00510 
00511    //const TGLDisableGuard depthTest(GL_DEPTH_TEST); //[0-0]
00512 
00513    if (!fSelectionPass) {
00514       glEnable(GL_POLYGON_OFFSET_FILL);//[0
00515       glPolygonOffset(1.f, 1.f);
00516       SetLegoColor();
00517       if (fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos> fBackBox.Get3DBox()[0].X()) {
00518          //Lego is semi-transparent if we have any sections.
00519          glEnable(GL_BLEND);//[1
00520          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00521       }
00522    }
00523 
00524    //Using front point, find the correct order to draw bars from
00525    //back to front (it's important only for semi-transparent lego).
00526    //Only in cartesian.
00527    const Int_t nX = fXEdges.size();
00528    const Int_t nY = fYEdges.size();
00529    const Int_t frontPoint = fBackBox.GetFrontPoint();
00530    Int_t iInit = 0, jInit = 0, irInit = fCoord->GetFirstXBin(), jrInit = fCoord->GetFirstYBin();
00531    const Int_t addI = frontPoint == 2 || frontPoint == 1 ? 1 : (iInit = nX - 1, irInit = fCoord->GetLastXBin(), -1);
00532    const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? 1 : (jInit = nY - 1, jrInit = fCoord->GetLastYBin(), -1);
00533 
00534    if (fLegoType == kColorLevel && !fSelectionPass) {
00535       if (!PreparePalette()) {
00536          fLegoType = kColorSimple;
00537          fDrawPalette = kFALSE;
00538       } else
00539          fPalette.EnableTexture(GL_MODULATE);
00540    }
00541 
00542    if (fSelectionPass && fHighColor)
00543       Rgl::ObjectIDToColor(fSelectionBase, kTRUE);
00544 
00545    for(Int_t i = iInit, ir = irInit; addI > 0 ? i < nX : i >= 0; i += addI, ir += addI) {
00546       for(Int_t j = jInit, jr = jrInit; addJ > 0 ? j < nY : j >= 0; j += addJ, jr += addJ) {
00547          Double_t zMax = fHist->GetCellContent(ir, jr) * fCoord->GetFactor();
00548          if (!ClampZ(zMax))
00549             continue;
00550 
00551          const Int_t binID = fSelectionBase + i * fCoord->GetNYBins() + j;
00552 
00553          if (fSelectionPass && !fHighColor)
00554             Rgl::ObjectIDToColor(binID, kFALSE);
00555          else if(!fHighColor && fSelectedPart == binID)
00556             glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
00557 
00558          if (fLegoType == kCylindricBars) {
00559             Rgl::DrawCylinder(&fQuadric, fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
00560                               fYEdges[j].second, fMinZ, zMax);
00561          } else if (fLegoType == kColorLevel && !fSelectionPass) {
00562             Rgl::DrawBoxFrontTextured(fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
00563                                       fYEdges[j].second, fMinZ, zMax, fPalette.GetTexCoord(fMinZ),
00564                                       fPalette.GetTexCoord(zMax), frontPoint);
00565          } else {
00566             Rgl::DrawBoxFront(fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
00567                               fYEdges[j].second, fMinZ, zMax, frontPoint);
00568          }
00569 
00570          if (!fHighColor && !fSelectionPass && fSelectedPart == binID)
00571             glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
00572       }
00573    }
00574 
00575    if (fLegoType == kColorLevel && !fSelectionPass)
00576       fPalette.DisableTexture();
00577 
00578    //Draw outlines for non-cylindrical bars.
00579    if (!fSelectionPass) {
00580       glDisable(GL_POLYGON_OFFSET_FILL);//0]
00581       const TGLDisableGuard lightGuard(GL_LIGHTING);//[2 - 2]
00582       if (fXOZSectionPos <= fBackBox.Get3DBox()[0].Y() && fYOZSectionPos <= fBackBox.Get3DBox()[0].X())
00583          glColor3d(0., 0., 0.);
00584       else
00585          glColor4d(0., 0., 0., 0.4);
00586       glPolygonMode(GL_FRONT, GL_LINE);//[3
00587 
00588       const TGLEnableGuard blendGuard(GL_BLEND);//[4-4] + 1]
00589       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00590       const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);//[5-5]
00591       glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00592 
00593       for(Int_t i = iInit, ir = irInit; addI > 0 ? i < nX : i >= 0; i += addI, ir += addI) {
00594          for(Int_t j = jInit, jr = jrInit; addJ > 0 ? j < nY : j >= 0; j += addJ, jr += addJ) {
00595             Double_t zMax = fHist->GetCellContent(ir, jr) * fCoord->GetFactor();
00596             if (!ClampZ(zMax))
00597                continue;
00598             if (fLegoType != kCylindricBars) {
00599                Rgl::DrawBoxFront(fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
00600                                  fYEdges[j].second, fMinZ, zMax, frontPoint);
00601             }
00602             if (fDrawErrors && zMax > 0.) {
00603                Double_t errorZMax = (fHist->GetCellContent(ir, jr) + fHist->GetCellError(ir, jr)) * fCoord->GetFactor();
00604                ClampZ(errorZMax);
00605                Rgl::DrawError(fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
00606                               fYEdges[j].second, zMax, errorZMax);
00607             }
00608          }
00609       }
00610 
00611       glPolygonMode(GL_FRONT, GL_FILL);//3]
00612    }
00613 
00614    if(!fSelectionPass && fDrawPalette)
00615       DrawPalette();
00616 }
00617 
00618 //______________________________________________________________________________
00619 void TGLLegoPainter::DrawLegoPolar()const
00620 {
00621    //Lego in polar system.
00622    const Int_t nX = fCosSinTableX.size() - 1;
00623    const Int_t nY = fYEdges.size();
00624 
00625    if (!fSelectionPass) {
00626       SetLegoColor();
00627       glEnable(GL_POLYGON_OFFSET_FILL);
00628       glPolygonOffset(1.f, 1.f);
00629    }
00630 
00631    Double_t points[4][2] = {};
00632 
00633    if (fLegoType == kColorLevel && !fSelectionPass) {
00634       if (!PreparePalette()) {
00635          fLegoType = kColorSimple;
00636          fDrawPalette = kFALSE;
00637       } else
00638          fPalette.EnableTexture(GL_MODULATE);
00639    }
00640 
00641    if (fHighColor && fSelectionPass)
00642       Rgl::ObjectIDToColor(fSelectionBase, kTRUE);
00643 
00644    for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00645       for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00646          Double_t zMax = fHist->GetCellContent(ir, jr);
00647          if (!ClampZ(zMax))
00648             continue;
00649          points[0][0] = fYEdges[j].first  * fCosSinTableX[i].first;
00650          points[0][1] = fYEdges[j].first  * fCosSinTableX[i].second;
00651          points[1][0] = fYEdges[j].second * fCosSinTableX[i].first;
00652          points[1][1] = fYEdges[j].second * fCosSinTableX[i].second;
00653          points[2][0] = fYEdges[j].second * fCosSinTableX[i + 1].first;
00654          points[2][1] = fYEdges[j].second * fCosSinTableX[i + 1].second;
00655          points[3][0] = fYEdges[j].first  * fCosSinTableX[i + 1].first;
00656          points[3][1] = fYEdges[j].first  * fCosSinTableX[i + 1].second;
00657 
00658          const Int_t binID = fSelectionBase + i * fCoord->GetNYBins() + j;
00659 
00660          if (!fHighColor && fSelectionPass)
00661             Rgl::ObjectIDToColor(binID, kFALSE);
00662          else if(!fHighColor && fSelectedPart == binID)
00663             glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
00664 
00665          if (fLegoType == kColorLevel && !fSelectionPass)
00666             Rgl::DrawTrapezoidTextured(points, fMinZ, zMax, fPalette.GetTexCoord(fMinZ),
00667                                        fPalette.GetTexCoord(zMax));
00668          else
00669             Rgl::DrawTrapezoid(points, fMinZ, zMax);
00670 
00671          if (!fHighColor && !fSelectionPass && fSelectedPart == binID)
00672             glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
00673       }
00674    }
00675 
00676    if (fLegoType == kColorLevel && !fSelectionPass)
00677       fPalette.DisableTexture();
00678 
00679    //Draw otulines.
00680    if (!fSelectionPass) {
00681       glDisable(GL_POLYGON_OFFSET_FILL);//0]
00682       const TGLDisableGuard lightGuard(GL_LIGHTING);//[2-2]
00683       glColor3d(0., 0., 0.);
00684       glPolygonMode(GL_FRONT, GL_LINE);//[3
00685       const TGLEnableGuard blendGuard(GL_BLEND);
00686       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00687       const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
00688       glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00689 
00690       for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00691          for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00692             Double_t zMax = fHist->GetCellContent(ir, jr);
00693             if (!ClampZ(zMax))
00694                continue;
00695             points[0][0] = fYEdges[j].first  * fCosSinTableX[i].first;
00696             points[0][1] = fYEdges[j].first  * fCosSinTableX[i].second;
00697             points[1][0] = fYEdges[j].second * fCosSinTableX[i].first;
00698             points[1][1] = fYEdges[j].second * fCosSinTableX[i].second;
00699             points[2][0] = fYEdges[j].second * fCosSinTableX[i + 1].first;
00700             points[2][1] = fYEdges[j].second * fCosSinTableX[i + 1].second;
00701             points[3][0] = fYEdges[j].first  * fCosSinTableX[i + 1].first;
00702             points[3][1] = fYEdges[j].first  * fCosSinTableX[i + 1].second;
00703             Rgl::DrawTrapezoid(points, fMinZ, zMax, kFALSE);
00704          }
00705       }
00706 
00707       glPolygonMode(GL_FRONT, GL_FILL);//3]
00708    }
00709 
00710    if(!fSelectionPass && fDrawPalette)
00711       DrawPalette();
00712 }
00713 
00714 //______________________________________________________________________________
00715 void TGLLegoPainter::DrawLegoCylindrical()const
00716 {
00717    //Lego in cylindrical system.
00718    const Int_t nX = fCosSinTableX.size() - 1;
00719    const Int_t nY = fYEdges.size();
00720    Double_t legoR = gStyle->GetLegoInnerR();
00721    if (legoR > 1. || legoR < 0.)
00722       legoR = 0.5;
00723    const Double_t rRange = fCoord->GetZLength();
00724 
00725    if (!fSelectionPass) {
00726       SetLegoColor();
00727       glEnable(GL_POLYGON_OFFSET_FILL);
00728       glPolygonOffset(1.f, 1.f);
00729    }
00730 
00731    Double_t points[4][2] = {};
00732    const Double_t sc = (1 - legoR) * fCoord->GetXScale();
00733    legoR *= fCoord->GetXScale();
00734 
00735    if (fLegoType == kColorLevel && !fSelectionPass) {
00736       if (!PreparePalette()) {
00737          fLegoType = kColorSimple;
00738          fDrawPalette = kFALSE;
00739       } else
00740          fPalette.EnableTexture(GL_MODULATE);
00741    }
00742 
00743    if (fHighColor && fSelectionPass)
00744       Rgl::ObjectIDToColor(fSelectionBase, kTRUE);
00745 
00746    for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00747       for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00748          Double_t zMin = legoR + (fMinZ - fCoord->GetZRange().first) / rRange * sc;
00749          Double_t zMax = legoR + (fHist->GetCellContent(ir, jr) - fCoord->GetZRange().first) / rRange * sc;
00750          if (zMin > zMax)
00751             std::swap(zMin, zMax);
00752 
00753          points[0][0] = fCosSinTableX[i].first * zMin;
00754          points[0][1] = fCosSinTableX[i].second * zMin;
00755          points[1][0] = fCosSinTableX[i].first * zMax;
00756          points[1][1] = fCosSinTableX[i].second * zMax;
00757          points[2][0] = fCosSinTableX[i + 1].first * zMax;
00758          points[2][1] = fCosSinTableX[i + 1].second * zMax;
00759          points[3][0] = fCosSinTableX[i + 1].first * zMin;
00760          points[3][1] = fCosSinTableX[i + 1].second * zMin;
00761 
00762          const Int_t binID = fSelectionBase + i * fCoord->GetNYBins() + j;
00763 
00764          if (fSelectionPass && !fHighColor)
00765             Rgl::ObjectIDToColor(binID, kFALSE);
00766          else if(!fHighColor && fSelectedPart == binID)
00767             glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
00768 
00769          if (fLegoType == kColorLevel && !fSelectionPass){
00770             Rgl::DrawTrapezoidTextured2(points, fYEdges[j].first, fYEdges[j].second,
00771                                         fPalette.GetTexCoord(fMinZ), fPalette.GetTexCoord(fHist->GetCellContent(ir, jr)));
00772          }else
00773             Rgl::DrawTrapezoid(points, fYEdges[j].first, fYEdges[j].second);
00774 
00775          if(!fSelectionPass && !fHighColor && fSelectedPart == binID)
00776             glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
00777       }
00778    }
00779 
00780    if (fLegoType == kColorLevel && !fSelectionPass)
00781       fPalette.DisableTexture();
00782 
00783    //Draw otulines.
00784    if (!fSelectionPass) {
00785       glDisable(GL_POLYGON_OFFSET_FILL);//0]
00786       const TGLDisableGuard lightGuard(GL_LIGHTING);//[2-2]
00787       glColor3d(0., 0., 0.);
00788       glPolygonMode(GL_FRONT, GL_LINE);//[3
00789 
00790       const TGLEnableGuard blendGuard(GL_BLEND);
00791       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00792       const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
00793       glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00794 
00795       for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00796          for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00797             Double_t zMin = legoR + (fMinZ - fCoord->GetZRange().first) / rRange * sc;
00798             Double_t zMax = legoR + (fHist->GetCellContent(ir, jr) - fCoord->GetZRange().first) / rRange * sc;
00799             if (zMin > zMax)
00800                std::swap(zMin, zMax);
00801 
00802             points[0][0] = fCosSinTableX[i].first * zMin;
00803             points[0][1] = fCosSinTableX[i].second * zMin;
00804             points[1][0] = fCosSinTableX[i].first * zMax;
00805             points[1][1] = fCosSinTableX[i].second * zMax;
00806             points[2][0] = fCosSinTableX[i + 1].first * zMax;
00807             points[2][1] = fCosSinTableX[i + 1].second * zMax;
00808             points[3][0] = fCosSinTableX[i + 1].first * zMin;
00809             points[3][1] = fCosSinTableX[i + 1].second * zMin;
00810             Rgl::DrawTrapezoid(points, fYEdges[j].first, fYEdges[j].second);
00811          }
00812       }
00813 
00814       glPolygonMode(GL_FRONT, GL_FILL);//3]
00815    }
00816 
00817    if(!fSelectionPass && fDrawPalette)
00818       DrawPalette();
00819 }
00820 
00821 //______________________________________________________________________________
00822 void TGLLegoPainter::DrawLegoSpherical()const
00823 {
00824    //Lego in spherical system.
00825    const Int_t nX = fCosSinTableX.size() - 1;
00826    const Int_t nY = fCosSinTableY.size() - 1;
00827    const Double_t rRange = fCoord->GetZLength();
00828    Double_t legoR = gStyle->GetLegoInnerR();
00829    if (legoR > 1. || legoR < 0.)
00830       legoR = 0.5;
00831 
00832    if (!fSelectionPass) {
00833       SetLegoColor();
00834       glEnable(GL_POLYGON_OFFSET_FILL);
00835       glPolygonOffset(1.f, 1.f);
00836    }
00837 
00838    Double_t points[8][3] = {};
00839    const Double_t sc = 1 - legoR;
00840 
00841    if (fLegoType == kColorLevel && !fSelectionPass) {
00842       if (!PreparePalette()) {
00843          fLegoType = kColorSimple;
00844          fDrawPalette = kFALSE;
00845       } else
00846          fPalette.EnableTexture(GL_MODULATE);
00847    }
00848 
00849    if (fSelectionPass && fHighColor)
00850       Rgl::ObjectIDToColor(fSelectionBase, kTRUE);
00851 
00852    for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00853       for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00854          Double_t zMin = legoR + (fMinZ - fCoord->GetZRange().first) / rRange * sc;
00855          Double_t zMax = legoR + (fHist->GetCellContent(ir, jr) - fCoord->GetZRange().first) / rRange * sc;
00856          if (zMin > zMax)
00857             std::swap(zMin, zMax);
00858 
00859          points[4][0] = zMin * fCosSinTableY[j].second * fCosSinTableX[i].first;
00860          points[4][1] = zMin * fCosSinTableY[j].second * fCosSinTableX[i].second;
00861          points[4][2] = zMin * fCosSinTableY[j].first;
00862          points[5][0] = zMin * fCosSinTableY[j].second * fCosSinTableX[i + 1].first;
00863          points[5][1] = zMin * fCosSinTableY[j].second * fCosSinTableX[i + 1].second;
00864          points[5][2] = zMin * fCosSinTableY[j].first;
00865          points[6][0] = zMax * fCosSinTableY[j].second * fCosSinTableX[i + 1].first;
00866          points[6][1] = zMax * fCosSinTableY[j].second * fCosSinTableX[i + 1].second;
00867          points[6][2] = zMax * fCosSinTableY[j].first;
00868          points[7][0] = zMax * fCosSinTableY[j].second * fCosSinTableX[i].first;
00869          points[7][1] = zMax * fCosSinTableY[j].second * fCosSinTableX[i].second;
00870          points[7][2] = zMax * fCosSinTableY[j].first;
00871          points[0][0] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i].first;
00872          points[0][1] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i].second;
00873          points[0][2] = zMin * fCosSinTableY[j + 1].first;
00874          points[1][0] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].first;
00875          points[1][1] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].second;
00876          points[1][2] = zMin * fCosSinTableY[j + 1].first;
00877          points[2][0] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].first;
00878          points[2][1] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].second;
00879          points[2][2] = zMax * fCosSinTableY[j + 1].first;
00880          points[3][0] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i].first;
00881          points[3][1] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i].second;
00882          points[3][2] = zMax * fCosSinTableY[j + 1].first;
00883 
00884          const Int_t binID = fSelectionBase + i * fCoord->GetNYBins() + j;
00885 
00886          if (fSelectionPass && !fHighColor)
00887             Rgl::ObjectIDToColor(binID, kFALSE);
00888          else if(!fHighColor && fSelectedPart == binID)
00889             glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
00890          if (fLegoType == kColorLevel && !fSelectionPass)
00891             Rgl::DrawTrapezoidTextured(points, fPalette.GetTexCoord(fMinZ),
00892                                        fPalette.GetTexCoord(fHist->GetCellContent(ir, jr)));
00893          else
00894             Rgl::DrawTrapezoid(points);
00895 
00896          if(!fHighColor && fSelectedPart == binID)
00897             glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
00898       }
00899    }
00900 
00901    if (fLegoType == kColorLevel && !fSelectionPass)
00902       fPalette.DisableTexture();
00903 
00904    //Draw otulines.
00905    if (!fSelectionPass) {
00906       glDisable(GL_POLYGON_OFFSET_FILL);//0]
00907       const TGLDisableGuard lightGuard(GL_LIGHTING);//[2-2]
00908       glColor3d(0., 0., 0.);
00909       glPolygonMode(GL_FRONT, GL_LINE);//[3
00910       const TGLEnableGuard blendGuard(GL_BLEND);
00911       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00912       const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
00913       glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00914 
00915       for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
00916          for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
00917             Double_t zMin = legoR + (fMinZ - fCoord->GetZRange().first) / rRange * sc;
00918             Double_t zMax = legoR + (fHist->GetCellContent(ir, jr) - fCoord->GetZRange().first) / rRange * sc;
00919             if (zMin > zMax)
00920                std::swap(zMin, zMax);
00921 
00922             points[4][0] = zMin * fCosSinTableY[j].second * fCosSinTableX[i].first;
00923             points[4][1] = zMin * fCosSinTableY[j].second * fCosSinTableX[i].second;
00924             points[4][2] = zMin * fCosSinTableY[j].first;
00925             points[5][0] = zMin * fCosSinTableY[j].second * fCosSinTableX[i + 1].first;
00926             points[5][1] = zMin * fCosSinTableY[j].second * fCosSinTableX[i + 1].second;
00927             points[5][2] = zMin * fCosSinTableY[j].first;
00928             points[6][0] = zMax * fCosSinTableY[j].second * fCosSinTableX[i + 1].first;
00929             points[6][1] = zMax * fCosSinTableY[j].second * fCosSinTableX[i + 1].second;
00930             points[6][2] = zMax * fCosSinTableY[j].first;
00931             points[7][0] = zMax * fCosSinTableY[j].second * fCosSinTableX[i].first;
00932             points[7][1] = zMax * fCosSinTableY[j].second * fCosSinTableX[i].second;
00933             points[7][2] = zMax * fCosSinTableY[j].first;
00934             points[0][0] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i].first;
00935             points[0][1] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i].second;
00936             points[0][2] = zMin * fCosSinTableY[j + 1].first;
00937             points[1][0] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].first;
00938             points[1][1] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].second;
00939             points[1][2] = zMin * fCosSinTableY[j + 1].first;
00940             points[2][0] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].first;
00941             points[2][1] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].second;
00942             points[2][2] = zMax * fCosSinTableY[j + 1].first;
00943             points[3][0] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i].first;
00944             points[3][1] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i].second;
00945             points[3][2] = zMax * fCosSinTableY[j + 1].first;
00946             Rgl::DrawTrapezoid(points);
00947          }
00948       }
00949 
00950       glPolygonMode(GL_FRONT, GL_FILL);//3]
00951    }
00952 
00953    if(!fSelectionPass && fDrawPalette)
00954       DrawPalette();
00955 }
00956 
00957 //______________________________________________________________________________
00958 void TGLLegoPainter::SetLegoColor()const
00959 {
00960    //Set lego's color.
00961    Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.15f};
00962 
00963    if (fLegoType != kColorLevel && fHist->GetFillColor() != kWhite)
00964       if (const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
00965          c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
00966 
00967    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
00968    const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
00969    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
00970    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
00971 }
00972 
00973 //______________________________________________________________________________
00974 void TGLLegoPainter::DrawSectionXOZ()const
00975 {
00976    //XOZ plane parallel section.
00977    Int_t binY = -1;
00978 
00979    for (Int_t i = 0, e = fYEdges.size(); i < e; ++i) {
00980       if (fYEdges[i].first <= fXOZSectionPos && fXOZSectionPos <= fYEdges[i].second) {
00981          binY = i;
00982          break;
00983       }
00984    }
00985 
00986    if (binY >= 0) {
00987       binY += fCoord->GetFirstYBin();
00988       glColor3d(1., 0., 0.);
00989       glLineWidth(3.f);
00990       //Draw 2d hist on the profile's plane.
00991       for (UInt_t i = 0, ir = fCoord->GetFirstXBin(), e = fXEdges.size(); i < e; ++i, ++ir) {
00992          Double_t zMax = fHist->GetBinContent(Int_t(ir), binY);
00993          if (!ClampZ(zMax))
00994             continue;
00995 
00996          glBegin(GL_LINE_LOOP);
00997          glVertex3d(fXEdges[i].first,  fXOZSectionPos, fMinZ);
00998          glVertex3d(fXEdges[i].first,  fXOZSectionPos, zMax);
00999          glVertex3d(fXEdges[i].second, fXOZSectionPos, zMax);
01000          glVertex3d(fXEdges[i].second, fXOZSectionPos, fMinZ);
01001          glEnd();
01002       }
01003 
01004       glLineWidth(1.f);
01005    }
01006 }
01007 
01008 //______________________________________________________________________________
01009 void TGLLegoPainter::DrawSectionYOZ()const
01010 {
01011    //YOZ plane parallel section.
01012    Int_t binX = -1;
01013 
01014    for (Int_t i = 0, e = fXEdges.size(); i < e; ++i) {
01015       if (fXEdges[i].first <= fYOZSectionPos && fYOZSectionPos <= fXEdges[i].second) {
01016          binX = i;
01017          break;
01018       }
01019    }
01020 
01021    if (binX >= 0) {
01022       binX += fCoord->GetFirstXBin();//fBinsX.first;
01023       glColor3d(1., 0., 0.);
01024       glLineWidth(3.f);
01025       //Draw 2d hist on the profile's plane.
01026       for (UInt_t i = 0, ir = fCoord->GetFirstYBin(), e = fYEdges.size(); i < e; ++i, ++ir) {
01027          Double_t zMax = fHist->GetBinContent(binX, ir);
01028          if (!ClampZ(zMax))
01029             continue;
01030 
01031          glBegin(GL_LINE_LOOP);
01032          glVertex3d(fYOZSectionPos, fYEdges[i].first,  fMinZ);
01033          glVertex3d(fYOZSectionPos, fYEdges[i].first,   zMax);
01034          glVertex3d(fYOZSectionPos, fYEdges[i].second,  zMax);
01035          glVertex3d(fYOZSectionPos, fYEdges[i].second, fMinZ);
01036          glEnd();
01037       }
01038 
01039       glLineWidth(1.f);
01040    }
01041 }
01042 
01043 //______________________________________________________________________________
01044 void TGLLegoPainter::DrawSectionXOY()const
01045 {
01046    //Empty. No such sections for lego.
01047 }
01048 
01049 //______________________________________________________________________________
01050 void TGLLegoPainter::ProcessEvent(Int_t event, Int_t /*px*/, Int_t py)
01051 {
01052    //Remove all sections and repaint.
01053    const TGLVertex3 *frame = fBackBox.Get3DBox();
01054    if (event == kButton1Double && (fXOZSectionPos > frame[0].Y() || fYOZSectionPos > frame[0].X())) {
01055       fXOZSectionPos = frame[0].Y();
01056       fYOZSectionPos = frame[0].X();
01057       if (fBoxCut.IsActive())
01058          fBoxCut.TurnOnOff();
01059       //gGLManager->PaintSingleObject(this);
01060       if (!gVirtualX->IsCmdThread())
01061          gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%lx)->Paint()", (ULong_t)this));
01062       else
01063          Paint();
01064    } else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
01065       Info("ProcessEvent", "Box cut does not exist for lego");
01066    }
01067 }
01068 
01069 //______________________________________________________________________________
01070 Bool_t TGLLegoPainter::ClampZ(Double_t &zVal)const
01071 {
01072    //Clamp z value.
01073    if (fCoord->GetZLog())
01074       if (zVal <= 0.)
01075          return kFALSE;
01076       else
01077          zVal = TMath::Log10(zVal) * fCoord->GetZScale();
01078    else
01079       zVal *= fCoord->GetZScale();
01080 
01081    const TGLVertex3 *frame = fBackBox.Get3DBox();
01082 
01083    if (zVal > frame[4].Z())
01084       zVal = frame[4].Z();
01085    else if (zVal < frame[0].Z())
01086       zVal = frame[0].Z();
01087 
01088    return kTRUE;
01089 }
01090 
01091 //______________________________________________________________________________
01092 Bool_t TGLLegoPainter::PreparePalette()const
01093 {
01094    //Initialize color palette.
01095    if(fMinMaxVal.first == fMinMaxVal.second)
01096       return kFALSE;//must be std::abs(fMinMaxVal.second - fMinMaxVal.first) < ...
01097 
01098    //User-defined contours are disabled, to be fixed in a future.
01099    if (fHist->TestBit(TH1::kUserContour))
01100       fHist->ResetBit(TH1::kUserContour);
01101 
01102    UInt_t paletteSize = gStyle->GetNumberContours();
01103    if (!paletteSize)
01104       paletteSize = 20;
01105 
01106    return fPalette.GeneratePalette(paletteSize, Rgl::Range_t(fMinZ, fMinMaxVal.second));
01107 }
01108 
01109 //______________________________________________________________________________
01110 void TGLLegoPainter::DrawPalette()const
01111 {
01112    //Draw. Palette.
01113    //Originally, fCamera was never null.
01114    //It can be a null now because of gl-viewer.
01115    if (!fCamera) {
01116       //Thank you, gl-viewer!
01117       return;
01118    }
01119 
01120    Rgl::DrawPalette(fCamera, fPalette);
01121 
01122    glFinish();
01123 
01124    fCamera->SetCamera();
01125    fCamera->Apply(fPadPhi, fPadTheta);
01126 }
01127 
01128 //______________________________________________________________________________
01129 void TGLLegoPainter::DrawPaletteAxis()const
01130 {
01131    //Draw. Palette. Axis.
01132    gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
01133    Rgl::DrawPaletteAxis(fCamera, fMinMaxVal, fCoord->GetCoordType() == kGLCartesian ? fCoord->GetZLog() : kFALSE);
01134 }

Generated on Tue Jul 5 14:18:07 2011 for ROOT_528-00b_version by  doxygen 1.5.1