00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00033
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
00045 }
00046
00047
00048 char *TGLLegoPainter::GetPlotInfo(Int_t , Int_t )
00049 {
00050
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
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
00097 if (!fCoord->SetRanges(fHist, fDrawErrors, kFALSE))
00098 return kFALSE;
00099
00100 fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
00101
00102
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
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();
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
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
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
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
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
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
00427 using namespace std;
00428 const Ssiz_t legoPos = option.Index("lego");
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
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
00459 glEnable(GL_DEPTH_TEST);
00460 glEnable(GL_LIGHTING);
00461 glEnable(GL_LIGHT0);
00462
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
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
00484
00485
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
00505 if (fCoord->GetCoordType() == kGLCartesian) {
00506 fBackBox.DrawBox(fSelectedPart, fSelectionPass, fZLevels, fHighColor);
00507 const TGLDisableGuard cullGuard(GL_CULL_FACE);
00508 DrawSections();
00509 }
00510
00511
00512
00513 if (!fSelectionPass) {
00514 glEnable(GL_POLYGON_OFFSET_FILL);
00515 glPolygonOffset(1.f, 1.f);
00516 SetLegoColor();
00517 if (fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos> fBackBox.Get3DBox()[0].X()) {
00518
00519 glEnable(GL_BLEND);
00520 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00521 }
00522 }
00523
00524
00525
00526
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
00579 if (!fSelectionPass) {
00580 glDisable(GL_POLYGON_OFFSET_FILL);
00581 const TGLDisableGuard lightGuard(GL_LIGHTING);
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);
00587
00588 const TGLEnableGuard blendGuard(GL_BLEND);
00589 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00590 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
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);
00612 }
00613
00614 if(!fSelectionPass && fDrawPalette)
00615 DrawPalette();
00616 }
00617
00618
00619 void TGLLegoPainter::DrawLegoPolar()const
00620 {
00621
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
00680 if (!fSelectionPass) {
00681 glDisable(GL_POLYGON_OFFSET_FILL);
00682 const TGLDisableGuard lightGuard(GL_LIGHTING);
00683 glColor3d(0., 0., 0.);
00684 glPolygonMode(GL_FRONT, GL_LINE);
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);
00708 }
00709
00710 if(!fSelectionPass && fDrawPalette)
00711 DrawPalette();
00712 }
00713
00714
00715 void TGLLegoPainter::DrawLegoCylindrical()const
00716 {
00717
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
00784 if (!fSelectionPass) {
00785 glDisable(GL_POLYGON_OFFSET_FILL);
00786 const TGLDisableGuard lightGuard(GL_LIGHTING);
00787 glColor3d(0., 0., 0.);
00788 glPolygonMode(GL_FRONT, GL_LINE);
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);
00815 }
00816
00817 if(!fSelectionPass && fDrawPalette)
00818 DrawPalette();
00819 }
00820
00821
00822 void TGLLegoPainter::DrawLegoSpherical()const
00823 {
00824
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
00905 if (!fSelectionPass) {
00906 glDisable(GL_POLYGON_OFFSET_FILL);
00907 const TGLDisableGuard lightGuard(GL_LIGHTING);
00908 glColor3d(0., 0., 0.);
00909 glPolygonMode(GL_FRONT, GL_LINE);
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);
00951 }
00952
00953 if(!fSelectionPass && fDrawPalette)
00954 DrawPalette();
00955 }
00956
00957
00958 void TGLLegoPainter::SetLegoColor()const
00959 {
00960
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
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
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
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();
01023 glColor3d(1., 0., 0.);
01024 glLineWidth(3.f);
01025
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
01047 }
01048
01049
01050 void TGLLegoPainter::ProcessEvent(Int_t event, Int_t , Int_t py)
01051 {
01052
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
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
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
01095 if(fMinMaxVal.first == fMinMaxVal.second)
01096 return kFALSE;
01097
01098
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
01113
01114
01115 if (!fCamera) {
01116
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
01132 gVirtualX->SetDrawMode(TVirtualX::kCopy);
01133 Rgl::DrawPaletteAxis(fCamera, fMinMaxVal, fCoord->GetCoordType() == kGLCartesian ? fCoord->GetZLog() : kFALSE);
01134 }