00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "Riostream.h"
00012 #include <cstdio>
00013
00014 #include "TVirtualPad.h"
00015 #include "TVirtualPS.h"
00016 #include "TVirtualX.h"
00017 #include "TGaxis.h"
00018 #include "TGraph.h"
00019 #include "TStyle.h"
00020 #include "TError.h"
00021 #include "TColor.h"
00022 #include "TAxis.h"
00023 #include "TMath.h"
00024 #include "TList.h"
00025 #include "TH2Poly.h"
00026 #include "TH1.h"
00027 #include "TH3.h"
00028 #include "TF3.h"
00029
00030 #include "TGLPlotPainter.h"
00031 #include "TGLPlotCamera.h"
00032 #include "TGLIncludes.h"
00033 #include "TGLAdapter.h"
00034 #include "TGLOutput.h"
00035 #include "TGL5D.h"
00036 #include "gl2ps.h"
00037
00038
00039
00040
00041
00042
00043 ClassImp(TGLPlotPainter)
00044
00045
00046 TGLPlotPainter::TGLPlotPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord,
00047 Bool_t xoy, Bool_t xoz, Bool_t yoz)
00048 : fPadColor(0),
00049 fPadPhi(45.),
00050 fPadTheta(0.),
00051 fHist(hist),
00052 fXAxis(hist->GetXaxis()),
00053 fYAxis(hist->GetYaxis()),
00054 fZAxis(hist->GetZaxis()),
00055 fCoord(coord),
00056 fCamera(camera),
00057 fUpdateSelection(kTRUE),
00058 fSelectionPass(kFALSE),
00059 fSelectedPart(0),
00060 fXOZSectionPos(0.),
00061 fYOZSectionPos(0.),
00062 fXOYSectionPos(0.),
00063 fBackBox(xoy, xoz, yoz),
00064 fBoxCut(&fBackBox),
00065 fHighColor(kFALSE),
00066 fSelectionBase(kTrueColorSelectionBase),
00067 fDrawPalette(kFALSE)
00068 {
00069
00070 if (gPad) {
00071 fPadPhi = gPad->GetPhi();
00072 fPadTheta = gPad->GetTheta();
00073 }
00074 }
00075
00076
00077 TGLPlotPainter::TGLPlotPainter(TGL5DDataSet *data, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
00078 : fPadColor(0),
00079 fPadPhi(45.),
00080 fPadTheta(0.),
00081 fHist(0),
00082 fXAxis(data->GetXAxis()),
00083 fYAxis(data->GetYAxis()),
00084 fZAxis(data->GetZAxis()),
00085 fCoord(coord),
00086 fCamera(camera),
00087 fUpdateSelection(kTRUE),
00088 fSelectionPass(kFALSE),
00089 fSelectedPart(0),
00090 fXOZSectionPos(0.),
00091 fYOZSectionPos(0.),
00092 fXOYSectionPos(0.),
00093 fBackBox(kFALSE, kFALSE, kFALSE),
00094 fBoxCut(&fBackBox),
00095 fHighColor(kFALSE),
00096 fSelectionBase(kTrueColorSelectionBase),
00097 fDrawPalette(kFALSE)
00098 {
00099
00100 if (gPad) {
00101 fPadPhi = gPad->GetPhi();
00102 fPadTheta = gPad->GetTheta();
00103 }
00104 }
00105
00106
00107 TGLPlotPainter::TGLPlotPainter(TGLPlotCamera *camera)
00108 : fPadColor(0),
00109 fPadPhi(45.),
00110 fPadTheta(0.),
00111 fHist(0),
00112 fXAxis(0),
00113 fYAxis(0),
00114 fZAxis(0),
00115 fCoord(0),
00116 fCamera(camera),
00117 fUpdateSelection(kTRUE),
00118 fSelectionPass(kFALSE),
00119 fSelectedPart(0),
00120 fXOZSectionPos(0.),
00121 fYOZSectionPos(0.),
00122 fXOYSectionPos(0.),
00123 fBackBox(kFALSE, kFALSE, kFALSE),
00124 fBoxCut(&fBackBox),
00125 fHighColor(kFALSE),
00126 fSelectionBase(kTrueColorSelectionBase),
00127 fDrawPalette(kFALSE)
00128 {
00129
00130 if (gPad) {
00131 fPadPhi = gPad->GetPhi();
00132 fPadTheta = gPad->GetTheta();
00133 }
00134 }
00135
00136
00137 void TGLPlotPainter::Paint()
00138 {
00139
00140 fHighColor = kFALSE;
00141 fSelectionBase = fHighColor ? kHighColorSelectionBase : kTrueColorSelectionBase;
00142
00143 int vp[4] = {};
00144 glGetIntegerv(GL_VIEWPORT, vp);
00145
00146
00147
00148 glDepthMask(GL_TRUE);
00149
00150 InitGL();
00151
00152 glPushAttrib(GL_LIGHTING_BIT);
00153
00154
00155 SaveProjectionMatrix();
00156 SaveModelviewMatrix();
00157
00158
00159 fCamera->SetCamera();
00160
00161 glClear(GL_DEPTH_BUFFER_BIT);
00162
00163
00164
00165
00166
00167
00168 const Float_t pos[] = {0.f, 0.f, 0.f, 1.f};
00169 glLightfv(GL_LIGHT0, GL_POSITION, pos);
00170
00171 fCamera->Apply(fPadPhi, fPadTheta);
00172 fBackBox.FindFrontPoint();
00173
00174 if (gVirtualPS)
00175 PrintPlot();
00176
00177
00178
00179 DrawPlot();
00180
00181 glPopAttrib();
00182
00183 DeInitGL();
00184
00185
00186 RestoreProjectionMatrix();
00187 RestoreModelviewMatrix();
00188
00189 glViewport(vp[0], vp[1], vp[2], vp[3]);
00190
00191
00192 glDepthMask(GL_FALSE);
00193
00194 if (fCoord && fCoord->GetCoordType() == kGLCartesian) {
00195
00196 Bool_t old = gPad->TestBit(TGraph::kClipFrame);
00197 if (!old)
00198 gPad->SetBit(TGraph::kClipFrame);
00199 const Int_t viewport[] = {fCamera->GetX(), fCamera->GetY(), fCamera->GetWidth(), fCamera->GetHeight()};
00200 Rgl::DrawAxes(fBackBox.GetFrontPoint(), viewport, fBackBox.Get2DBox(), fCoord, fXAxis, fYAxis, fZAxis);
00201 if (fDrawPalette)
00202 DrawPaletteAxis();
00203
00204 if (!old)
00205 gPad->ResetBit(TGraph::kClipFrame);
00206 } else if(fDrawPalette)
00207 DrawPaletteAxis();
00208
00209 }
00210
00211
00212 void TGLPlotPainter::PrintPlot()const
00213 {
00214
00215 using namespace std;
00216
00217 TGLOutput::StartEmbeddedPS();
00218
00219 FILE *output = fopen(gVirtualPS->GetName(), "a");
00220 if (!output) {
00221 Error("TGLPlotPainter::PrintPlot", "Could not (re)open ps file for GL output");
00222
00223 TGLOutput::CloseEmbeddedPS();
00224 return;
00225 }
00226
00227 Int_t gl2psFormat = GL2PS_EPS;
00228 Int_t gl2psSort = GL2PS_BSP_SORT;
00229 Int_t buffsize = 0;
00230 Int_t state = GL2PS_OVERFLOW;
00231 GLint gl2psoption = GL2PS_USE_CURRENT_VIEWPORT |
00232 GL2PS_SILENT |
00233 GL2PS_BEST_ROOT |
00234 GL2PS_OCCLUSION_CULL |
00235 0;
00236
00237 while (state == GL2PS_OVERFLOW) {
00238 buffsize += 1024*1024;
00239 gl2psBeginPage ("ROOT Scene Graph", "ROOT", NULL,
00240 gl2psFormat, gl2psSort, gl2psoption,
00241 GL_RGBA, 0, NULL,0, 0, 0,
00242 buffsize, output, NULL);
00243 DrawPlot();
00244 state = gl2psEndPage();
00245 }
00246
00247 fclose(output);
00248 TGLOutput::CloseEmbeddedPS();
00249 glFlush();
00250 }
00251
00252
00253 Bool_t TGLPlotPainter::PlotSelected(Int_t px, Int_t py)
00254 {
00255
00256 if (fUpdateSelection) {
00257
00258 glMatrixMode(GL_PROJECTION);
00259 glPushMatrix();
00260 glMatrixMode(GL_MODELVIEW);
00261 glPushMatrix();
00262
00263 fSelectionPass = kTRUE;
00264 fCamera->SetCamera();
00265
00266 glDepthMask(GL_TRUE);
00267 glClearColor(0.f, 0.f, 0.f, 0.f);
00268 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00269
00270 fCamera->Apply(fPadPhi, fPadTheta);
00271 DrawPlot();
00272
00273 glFinish();
00274
00275 fSelection.ReadColorBuffer(fCamera->GetX(), fCamera->GetY(), fCamera->GetWidth(), fCamera->GetHeight());
00276 fSelectionPass = kFALSE;
00277 fUpdateSelection = kFALSE;
00278
00279 glDepthMask(GL_FALSE);
00280 glDisable(GL_DEPTH_TEST);
00281
00282
00283 glMatrixMode(GL_PROJECTION);
00284 glPopMatrix();
00285 glMatrixMode(GL_MODELVIEW);
00286 glPopMatrix();
00287 }
00288
00289
00290 px -= Int_t(gPad->GetXlowNDC() * gPad->GetWw());
00291 py -= Int_t(gPad->GetWh() - gPad->YtoAbsPixel(gPad->GetY1()));
00292
00293
00294 std::swap(px, py);
00295 Int_t newSelected(Rgl::ColorToObjectID(fSelection.GetPixelColor(px, py), fHighColor));
00296
00297 if (newSelected != fSelectedPart) {
00298
00299 fSelectedPart = newSelected;
00300 gPad->Update();
00301 }
00302
00303 return fSelectedPart ? kTRUE : kFALSE;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 void TGLPlotPainter::SetPadColor(const TColor *c)
00316 {
00317
00318 fPadColor = c;
00319 }
00320
00321
00322 void TGLPlotPainter::SetFrameColor(const TColor *c)
00323 {
00324
00325 fBackBox.SetFrameColor(c);
00326 }
00327
00328
00329 void TGLPlotPainter::InvalidateSelection()
00330 {
00331
00332 fUpdateSelection = kTRUE;
00333 }
00334
00335
00336 const TColor *TGLPlotPainter::GetPadColor()const
00337 {
00338
00339 return fPadColor;
00340 }
00341
00342
00343 void TGLPlotPainter::MoveSection(Int_t px, Int_t py)
00344 {
00345
00346 const TGLVertex3 *frame = fBackBox.Get3DBox();
00347 const Int_t frontPoint = fBackBox.GetFrontPoint();
00348
00349 if (fSelectedPart == 1) {
00350 fXOYSectionPos = frame[0].Z();
00351 fSelectedPart = 6;
00352 } else if (fSelectedPart == 2) {
00353 if (frontPoint == 2) {
00354 fXOZSectionPos = frame[0].Y();
00355 fSelectedPart = 4;
00356 } else if (!frontPoint) {
00357 fXOZSectionPos = frame[2].Y();
00358 fSelectedPart = 4;
00359 } else if (frontPoint == 1) {
00360 fYOZSectionPos = frame[0].X();
00361 fSelectedPart = 5;
00362 } else if (frontPoint == 3) {
00363 fYOZSectionPos = frame[1].X();
00364 fSelectedPart = 5;
00365 }
00366 } else if (fSelectedPart == 3) {
00367 if (frontPoint == 2) {
00368 fYOZSectionPos = frame[0].X();
00369 fSelectedPart = 5;
00370 } else if (!frontPoint) {
00371 fYOZSectionPos = frame[1].X();
00372 fSelectedPart = 5;
00373 } else if (frontPoint == 1) {
00374 fXOZSectionPos = frame[2].Y();
00375 fSelectedPart = 4;
00376 } else if (frontPoint == 3) {
00377 fXOZSectionPos = frame[0].Y();
00378 fSelectedPart = 4;
00379 }
00380 }
00381
00382 Double_t mv[16] = {0.};
00383 glGetDoublev(GL_MODELVIEW_MATRIX, mv);
00384 Double_t pr[16] = {0.};
00385 glGetDoublev(GL_PROJECTION_MATRIX, pr);
00386 Int_t vp[4] = {0};
00387 glGetIntegerv(GL_VIEWPORT, vp);
00388 Double_t winVertex[3] = {0.};
00389
00390 if (fSelectedPart == 6)
00391 gluProject(0., 0., fXOYSectionPos, mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
00392 else
00393 gluProject(fSelectedPart == 5 ? fYOZSectionPos : 0.,
00394 fSelectedPart == 4 ? fXOZSectionPos : 0.,
00395 0., mv, pr, vp,
00396 &winVertex[0], &winVertex[1], &winVertex[2]);
00397 winVertex[0] += px - fMousePosition.fX;
00398 winVertex[1] += py - fMousePosition.fY;
00399 Double_t newPoint[3] = {0.};
00400 gluUnProject(winVertex[0], winVertex[1], winVertex[2], mv, pr, vp,
00401 newPoint, newPoint + 1, newPoint + 2);
00402
00403 if (fSelectedPart == 4)
00404 fXOZSectionPos = newPoint[1];
00405 else if (fSelectedPart == 5)
00406 fYOZSectionPos = newPoint[0];
00407 else
00408 fXOYSectionPos = newPoint[2];
00409 }
00410
00411
00412 void TGLPlotPainter::DrawSections()const
00413 {
00414
00415 const TGLVertex3 *frame = fBackBox.Get3DBox();
00416
00417 if (fXOZSectionPos > frame[0].Y()) {
00418 if (fXOZSectionPos > frame[2].Y())
00419 fXOZSectionPos = frame[2].Y();
00420 const TGLVertex3 v1(frame[0].X(), fXOZSectionPos, frame[0].Z());
00421 const TGLVertex3 v2(frame[4].X(), fXOZSectionPos, frame[4].Z());
00422 const TGLVertex3 v3(frame[5].X(), fXOZSectionPos, frame[5].Z());
00423 const TGLVertex3 v4(frame[1].X(), fXOZSectionPos, frame[1].Z());
00424
00425 if (fSelectionPass)
00426 Rgl::ObjectIDToColor(4, fHighColor);
00427 else if (fSelectedPart == 4)
00428 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
00429
00430 glEnable(GL_POLYGON_OFFSET_FILL);
00431 glPolygonOffset(1.f, 1.f);
00432 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 1., 0.));
00433 glDisable(GL_POLYGON_OFFSET_FILL);
00434
00435 if (!fSelectionPass) {
00436 if (fSelectedPart == 4)
00437 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
00438 const TGLDisableGuard lightGuard(GL_LIGHTING);
00439 const TGLEnableGuard blendGuard(GL_BLEND);
00440 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
00441 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00442 glDepthMask(GL_FALSE);
00443 DrawSectionXOZ();
00444
00445 const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);
00446 const UShort_t stipple = 0x5555;
00447 glLineStipple(1, stipple);
00448
00449 glColor3d(0., 0., 0.);
00450 glBegin(GL_LINES);
00451 for (UInt_t i = 0; i < fZLevels.size(); ++i) {
00452 glVertex3d(fBackBox.Get3DBox()[1].X(), fXOZSectionPos, fZLevels[i]);
00453 glVertex3d(fBackBox.Get3DBox()[0].X(), fXOZSectionPos, fZLevels[i]);
00454 }
00455 glEnd();
00456 glDepthMask(GL_TRUE);
00457 }
00458 }
00459
00460 if (fYOZSectionPos > frame[0].X()) {
00461 if (fYOZSectionPos > frame[1].X())
00462 fYOZSectionPos = frame[1].X();
00463 TGLVertex3 v1(fYOZSectionPos, frame[0].Y(), frame[0].Z());
00464 TGLVertex3 v2(fYOZSectionPos, frame[3].Y(), frame[3].Z());
00465 TGLVertex3 v3(fYOZSectionPos, frame[7].Y(), frame[7].Z());
00466 TGLVertex3 v4(fYOZSectionPos, frame[4].Y(), frame[4].Z());
00467
00468 if (fSelectionPass) {
00469 Rgl::ObjectIDToColor(5, fHighColor);
00470 } else if (fSelectedPart == 5)
00471 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
00472
00473 glEnable(GL_POLYGON_OFFSET_FILL);
00474 glPolygonOffset(1.f, 1.f);
00475 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(1., 0., 0.));
00476 glDisable(GL_POLYGON_OFFSET_FILL);
00477
00478 if (!fSelectionPass) {
00479 if (fSelectedPart == 5)
00480 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
00481 const TGLDisableGuard lightHuard(GL_LIGHTING);
00482 const TGLEnableGuard blendGuard(GL_BLEND);
00483 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
00484 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00485 glDepthMask(GL_FALSE);
00486 DrawSectionYOZ();
00487
00488 const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);
00489 glLineStipple(1, 0x5555);
00490
00491 glColor3d(0., 0., 0.);
00492 glBegin(GL_LINES);
00493 for (UInt_t i = 0; i < fZLevels.size(); ++i) {
00494 glVertex3d(fYOZSectionPos, fBackBox.Get3DBox()[3].Y(), fZLevels[i]);
00495 glVertex3d(fYOZSectionPos, fBackBox.Get3DBox()[0].Y(), fZLevels[i]);
00496 }
00497 glEnd();
00498 glDepthMask(GL_TRUE);
00499 }
00500 }
00501
00502 if (fXOYSectionPos > frame[0].Z()) {
00503 if (fXOYSectionPos > frame[4].Z())
00504 fXOYSectionPos = frame[4].Z();
00505 TGLVertex3 v1(frame[0].X(), frame[0].Y(), fXOYSectionPos);
00506 TGLVertex3 v2(frame[1].X(), frame[1].Y(), fXOYSectionPos);
00507 TGLVertex3 v3(frame[2].X(), frame[2].Y(), fXOYSectionPos);
00508 TGLVertex3 v4(frame[3].X(), frame[3].Y(), fXOYSectionPos);
00509
00510 if (fSelectionPass) {
00511 Rgl::ObjectIDToColor(6, fHighColor);
00512 } else if (fSelectedPart == 6)
00513 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
00514
00515 glEnable(GL_POLYGON_OFFSET_FILL);
00516 glPolygonOffset(1.f, 1.f);
00517
00518 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 0., 1.));
00519 glDisable(GL_POLYGON_OFFSET_FILL);
00520
00521 if (!fSelectionPass) {
00522 if (fSelectedPart == 6)
00523 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
00524 const TGLDisableGuard lightGuard(GL_LIGHTING);
00525 const TGLEnableGuard blendGuard(GL_BLEND);
00526 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
00527 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00528 glDepthMask(GL_FALSE);
00529 DrawSectionXOY();
00530 glDepthMask(GL_TRUE);
00531 }
00532 }
00533 }
00534
00535
00536 void TGLPlotPainter::ClearBuffers()const
00537 {
00538
00539
00540
00541
00542
00543
00544
00545
00546 }
00547
00548
00549 void TGLPlotPainter::DrawPaletteAxis()const
00550 {
00551
00552 }
00553
00554
00555 void TGLPlotPainter::SaveModelviewMatrix()const
00556 {
00557 glMatrixMode(GL_MODELVIEW);
00558 glPushMatrix();
00559 }
00560
00561
00562 void TGLPlotPainter::SaveProjectionMatrix()const
00563 {
00564 glMatrixMode(GL_PROJECTION);
00565 glPushMatrix();
00566 }
00567
00568
00569 void TGLPlotPainter::RestoreModelviewMatrix()const
00570 {
00571 glMatrixMode(GL_MODELVIEW);
00572 glPopMatrix();
00573 }
00574
00575
00576 void TGLPlotPainter::RestoreProjectionMatrix()const
00577 {
00578 glMatrixMode(GL_PROJECTION);
00579 glPopMatrix();
00580 }
00581
00582
00583
00584
00585
00586
00587 ClassImp(TGLPlotCoordinates)
00588
00589
00590 TGLPlotCoordinates::TGLPlotCoordinates()
00591 : fCoordType(kGLCartesian),
00592 fXScale(1.),
00593 fYScale(1.),
00594 fZScale(1.),
00595 fXLog(kFALSE),
00596 fYLog(kFALSE),
00597 fZLog(kFALSE),
00598 fModified(kFALSE),
00599 fFactor(1.)
00600 {
00601
00602 }
00603
00604
00605 TGLPlotCoordinates::~TGLPlotCoordinates()
00606 {
00607
00608 }
00609
00610
00611 void TGLPlotCoordinates::SetCoordType(EGLCoordType type)
00612 {
00613
00614
00615 if (fCoordType != type) {
00616 fModified = kTRUE;
00617 fCoordType = type;
00618 }
00619 }
00620
00621
00622 EGLCoordType TGLPlotCoordinates::GetCoordType()const
00623 {
00624
00625
00626 return fCoordType;
00627 }
00628
00629
00630 void TGLPlotCoordinates::SetXLog(Bool_t xLog)
00631 {
00632
00633
00634 if (fXLog != xLog) {
00635 fXLog = xLog;
00636 fModified = kTRUE;
00637 }
00638 }
00639
00640
00641 Bool_t TGLPlotCoordinates::GetXLog()const
00642 {
00643
00644
00645 return fXLog;
00646 }
00647
00648
00649 void TGLPlotCoordinates::SetYLog(Bool_t yLog)
00650 {
00651
00652
00653 if (fYLog != yLog) {
00654 fYLog = yLog;
00655 fModified = kTRUE;
00656 }
00657 }
00658
00659
00660 Bool_t TGLPlotCoordinates::GetYLog()const
00661 {
00662
00663
00664 return fYLog;
00665 }
00666
00667
00668 void TGLPlotCoordinates::SetZLog(Bool_t zLog)
00669 {
00670
00671
00672 if (fZLog != zLog) {
00673 fZLog = zLog;
00674 fModified = kTRUE;
00675 }
00676 }
00677
00678
00679 Bool_t TGLPlotCoordinates::GetZLog()const
00680 {
00681
00682
00683 return fZLog;
00684 }
00685
00686
00687 void TGLPlotCoordinates::ResetModified()
00688 {
00689
00690
00691 fModified = !fModified;
00692 }
00693
00694
00695 Bool_t TGLPlotCoordinates::Modified()const
00696 {
00697
00698
00699 return fModified;
00700 }
00701
00702
00703 Bool_t TGLPlotCoordinates::SetRanges(const TH1 *hist, Bool_t errors, Bool_t zBins)
00704 {
00705
00706 switch (fCoordType) {
00707 case kGLPolar:
00708 return SetRangesPolar(hist);
00709 case kGLCylindrical:
00710 return SetRangesCylindrical(hist);
00711 case kGLSpherical:
00712 return SetRangesSpherical(hist);
00713 case kGLCartesian:
00714 default:
00715 return SetRangesCartesian(hist, errors, zBins);
00716 }
00717 }
00718
00719
00720 Int_t TGLPlotCoordinates::GetNXBins()const
00721 {
00722
00723 return fXBins.second - fXBins.first + 1;
00724 }
00725
00726
00727 Int_t TGLPlotCoordinates::GetNYBins()const
00728 {
00729
00730 return fYBins.second - fYBins.first + 1;
00731 }
00732
00733
00734 Int_t TGLPlotCoordinates::GetNZBins()const
00735 {
00736
00737 return fZBins.second - fZBins.first + 1;
00738 }
00739
00740
00741 const Rgl::BinRange_t &TGLPlotCoordinates::GetXBins()const
00742 {
00743
00744 return fXBins;
00745 }
00746
00747
00748 const Rgl::BinRange_t &TGLPlotCoordinates::GetYBins()const
00749 {
00750
00751 return fYBins;
00752 }
00753
00754
00755 const Rgl::BinRange_t &TGLPlotCoordinates::GetZBins()const
00756 {
00757
00758 return fZBins;
00759 }
00760
00761
00762 const Rgl::Range_t &TGLPlotCoordinates::GetXRange()const
00763 {
00764
00765 return fXRange;
00766 }
00767
00768
00769 Double_t TGLPlotCoordinates::GetXLength()const
00770 {
00771
00772 return fXRange.second - fXRange.first;
00773 }
00774
00775
00776 const Rgl::Range_t &TGLPlotCoordinates::GetYRange()const
00777 {
00778
00779 return fYRange;
00780 }
00781
00782
00783 Double_t TGLPlotCoordinates::GetYLength()const
00784 {
00785
00786 return fYRange.second - fYRange.first;
00787 }
00788
00789
00790
00791 const Rgl::Range_t &TGLPlotCoordinates::GetZRange()const
00792 {
00793
00794 return fZRange;
00795 }
00796
00797
00798 Double_t TGLPlotCoordinates::GetZLength()const
00799 {
00800
00801 return fZRange.second - fZRange.first;
00802 }
00803
00804
00805
00806 const Rgl::Range_t &TGLPlotCoordinates::GetXRangeScaled()const
00807 {
00808
00809 return fXRangeScaled;
00810 }
00811
00812
00813 const Rgl::Range_t &TGLPlotCoordinates::GetYRangeScaled()const
00814 {
00815
00816 return fYRangeScaled;
00817 }
00818
00819
00820 const Rgl::Range_t &TGLPlotCoordinates::GetZRangeScaled()const
00821 {
00822
00823 return fZRangeScaled;
00824 }
00825
00826
00827 Double_t TGLPlotCoordinates::GetFactor()const
00828 {
00829
00830
00831 return fFactor;
00832 }
00833
00834 namespace {
00835
00836 Bool_t FindAxisRange(const TAxis *axis, Bool_t log, Rgl::BinRange_t &bins, Rgl::Range_t &range);
00837 Bool_t FindAxisRange(const TH1 *hist, Bool_t logZ, const Rgl::BinRange_t &xBins,
00838 const Rgl::BinRange_t &yBins, Rgl::Range_t &zRange,
00839 Double_t &factor, Bool_t errors);
00840
00841 Bool_t FindAxisRange(TH2Poly *hist, Bool_t zLog, Rgl::Range_t &zRange);
00842
00843 }
00844
00845
00846 Bool_t TGLPlotCoordinates::SetRangesCartesian(const TH1 *hist, Bool_t errors, Bool_t zAsBins)
00847 {
00848
00849 Rgl::BinRange_t xBins;
00850 Rgl::Range_t xRange;
00851 if (!FindAxisRange(hist->GetXaxis(), fXLog, xBins, xRange)) {
00852 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set X axis to log scale");
00853 return kFALSE;
00854 }
00855
00856 Rgl::BinRange_t yBins;
00857 Rgl::Range_t yRange;
00858 if (!FindAxisRange(hist->GetYaxis(), fYLog, yBins, yRange)) {
00859 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set Y axis to log scale");
00860 return kFALSE;
00861 }
00862
00863 Rgl::BinRange_t zBins;
00864 Rgl::Range_t zRange;
00865 Double_t factor = 1.;
00866
00867 if (zAsBins) {
00868 if (!FindAxisRange(hist->GetZaxis(), fZLog, zBins, zRange)) {
00869 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set Z axis to log scale");
00870 return kFALSE;
00871 }
00872 } else if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, errors)) {
00873 Error("TGLPlotCoordinates::SetRangesCartesian",
00874 "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
00875 return kFALSE;
00876 }
00877
00878
00879 const Double_t x = xRange.second - xRange.first;
00880 const Double_t y = yRange.second - yRange.first;
00881 const Double_t z = zRange.second - zRange.first;
00882
00883 if (!x || !y || !z) {
00884 Error("TGLPlotCoordinates::SetRangesCartesian", "Zero axis range.");
00885 return kFALSE;
00886 }
00887
00888 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
00889 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
00890 {
00891 fModified = kTRUE;
00892 }
00893
00894 fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
00895 fFactor = factor;
00896
00897
00898
00899
00900
00901
00902 fXScale = 1. / x;
00903 fYScale = 1. / y;
00904 fZScale = 1. / z;
00905
00906 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
00907 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
00908 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
00909
00910 return kTRUE;
00911 }
00912
00913
00914
00915 Bool_t TGLPlotCoordinates::SetRanges(TH2Poly *hist)
00916 {
00917
00918 Rgl::BinRange_t xBins;
00919 Rgl::Range_t xRange;
00920 FindAxisRange(hist->GetXaxis(), kFALSE, xBins, xRange);
00921
00922 Rgl::BinRange_t yBins;
00923 Rgl::Range_t yRange;
00924 FindAxisRange(hist->GetYaxis(), kFALSE, yBins, yRange);
00925
00926 Rgl::BinRange_t zBins;
00927 Rgl::Range_t zRange;
00928 Double_t factor = 1.;
00929
00930 if (!FindAxisRange(hist, fZLog, zRange))
00931 return kFALSE;
00932
00933
00934 const Double_t x = xRange.second - xRange.first;
00935 const Double_t y = yRange.second - yRange.first;
00936 const Double_t z = zRange.second - zRange.first;
00937
00938 if (!x || !y || !z) {
00939 Error("TGLPlotCoordinates::SetRanges", "Zero axis range.");
00940 return kFALSE;
00941 }
00942
00943 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
00944 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
00945 {
00946 fModified = kTRUE;
00947 }
00948
00949 fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
00950 fFactor = factor;
00951
00952 fXScale = Rgl::gH2PolyScaleXY / x;
00953 fYScale = Rgl::gH2PolyScaleXY / y;
00954 fZScale = 1. / z;
00955
00956 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
00957 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
00958 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
00959
00960 return kTRUE;
00961 }
00962
00963
00964
00965 Bool_t TGLPlotCoordinates::SetRanges(const TAxis *xAxis, const TAxis *yAxis, const TAxis *zAxis)
00966 {
00967
00968 Rgl::BinRange_t xBins;
00969 Rgl::Range_t xRange;
00970
00971 FindAxisRange(xAxis, kFALSE, xBins, xRange);
00972
00973 Rgl::BinRange_t yBins;
00974 Rgl::Range_t yRange;
00975
00976 FindAxisRange(yAxis, kFALSE, yBins, yRange);
00977
00978 Rgl::BinRange_t zBins;
00979 Rgl::Range_t zRange;
00980 Double_t factor = 1.;
00981
00982 FindAxisRange(zAxis, kFALSE, zBins, zRange);
00983
00984
00985 const Double_t x = xRange.second - xRange.first;
00986 const Double_t y = yRange.second - yRange.first;
00987 const Double_t z = zRange.second - zRange.first;
00988
00989 if (!x || !y || !z) {
00990 Error("TGLPlotCoordinates::SetRangesCartesian", "Zero axis range.");
00991 return kFALSE;
00992 }
00993
00994 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
00995 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
00996 {
00997 fModified = kTRUE;
00998 }
00999
01000 fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
01001 fFactor = factor;
01002
01003
01004
01005
01006
01007
01008 fXScale = 1. / x;
01009 fYScale = 1. / y;
01010 fZScale = 1. / z;
01011
01012 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
01013 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
01014 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
01015
01016 return kTRUE;
01017 }
01018
01019
01020 Bool_t TGLPlotCoordinates::SetRangesPolar(const TH1 *hist)
01021 {
01022
01023 Rgl::BinRange_t xBins;
01024 Rgl::Range_t phiRange;
01025 const TAxis *xAxis = hist->GetXaxis();
01026 FindAxisRange(xAxis, kFALSE, xBins, phiRange);
01027 if (xBins.second - xBins.first + 1 > 360) {
01028 Error("TGLPlotCoordinates::SetRangesPolar", "To many PHI sectors");
01029 return kFALSE;
01030 }
01031
01032 Rgl::BinRange_t yBins;
01033 Rgl::Range_t roRange;
01034 const TAxis *yAxis = hist->GetYaxis();
01035 FindAxisRange(yAxis, kFALSE, yBins, roRange);
01036
01037 Rgl::Range_t zRange;
01038 Double_t factor = 1.;
01039 if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, kFALSE))
01040 {
01041 Error("TGLPlotCoordinates::SetRangesPolar",
01042 "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
01043 return kFALSE;
01044 }
01045
01046 const Double_t z = zRange.second - zRange.first;
01047 if (!z || !(phiRange.second - phiRange.first) || !(roRange.second - roRange.first)) {
01048 Error("TGLPlotCoordinates::SetRangesPolar", "Zero axis range.");
01049 return kFALSE;
01050 }
01051
01052 if (phiRange != fXRange || roRange != fYRange || zRange != fZRange ||
01053 xBins != fXBins || yBins != fYBins || fFactor != factor)
01054 {
01055 fModified = kTRUE;
01056 fXRange = phiRange, fXBins = xBins;
01057 fYRange = roRange, fYBins = yBins;
01058 fZRange = zRange;
01059 fFactor = factor;
01060 }
01061
01062
01063 fXScale = 0.5;
01064 fYScale = 0.5;
01065 fZScale = 1. / z;
01066 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
01067 fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
01068 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
01069
01070 return kTRUE;
01071 }
01072
01073
01074 Bool_t TGLPlotCoordinates::SetRangesCylindrical(const TH1 *hist)
01075 {
01076
01077
01078 Rgl::BinRange_t xBins, yBins;
01079 Rgl::Range_t angleRange, heightRange, radiusRange;
01080 const TAxis *xAxis = hist->GetXaxis();
01081 const TAxis *yAxis = hist->GetYaxis();
01082 Double_t factor = 1.;
01083
01084 FindAxisRange(xAxis, kFALSE, xBins, angleRange);
01085 if (xBins.second - xBins.first + 1 > 360) {
01086 Error("TGLPlotCoordinates::SetRangesCylindrical", "To many PHI sectors");
01087 return kFALSE;
01088 }
01089 if (!FindAxisRange(yAxis, fYLog, yBins, heightRange)) {
01090 Error("TGLPlotCoordinates::SetRangesCylindrical", "Cannot set Y axis to log scale");
01091 return kFALSE;
01092 }
01093 FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
01094
01095 const Double_t x = angleRange.second - angleRange.first;
01096 const Double_t y = heightRange.second - heightRange.first;
01097 const Double_t z = radiusRange.second - radiusRange.first;
01098
01099 if (!x || !y || !z) {
01100 Error("TGLPlotCoordinates::SetRangesCylindrical", "Zero axis range.");
01101 return kFALSE;
01102 }
01103
01104 if (angleRange != fXRange || heightRange != fYRange ||
01105 radiusRange != fZRange || xBins != fXBins ||
01106 yBins != fYBins || fFactor != factor)
01107 {
01108 fModified = kTRUE;
01109 fXRange = angleRange, fXBins = xBins;
01110 fYRange = heightRange, fYBins = yBins;
01111 fZRange = radiusRange;
01112 fFactor = factor;
01113 }
01114
01115
01116 fXScale = 0.5;
01117 fYScale = 1. / y;
01118 fZScale = 0.5;
01119 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
01120 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
01121 fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
01122
01123 return kTRUE;
01124 }
01125
01126
01127 Bool_t TGLPlotCoordinates::SetRangesSpherical(const TH1 *hist)
01128 {
01129
01130
01131 Rgl::BinRange_t xBins;
01132 Rgl::Range_t phiRange;
01133 FindAxisRange(hist->GetXaxis(), kFALSE, xBins, phiRange);
01134 if (xBins.second - xBins.first + 1 > 360) {
01135 Error("TGLPlotCoordinates::SetRangesSpherical", "To many PHI sectors");
01136 return kFALSE;
01137 }
01138
01139 Rgl::BinRange_t yBins;
01140 Rgl::Range_t thetaRange;
01141 FindAxisRange(hist->GetYaxis(), kFALSE, yBins, thetaRange);
01142 if (yBins.second - yBins.first + 1 > 180) {
01143 Error("TGLPlotCoordinates::SetRangesSpherical", "To many THETA sectors");
01144 return kFALSE;
01145 }
01146
01147 Rgl::Range_t radiusRange;
01148 Double_t factor = 1.;
01149 FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
01150
01151 if (xBins != fXBins || yBins != fYBins ||
01152 phiRange != fXRange || thetaRange != fYRange ||
01153 radiusRange != fZRange || fFactor != factor)
01154 {
01155 fModified = kTRUE;
01156 fXBins = xBins;
01157 fYBins = yBins;
01158 fXRange = phiRange;
01159 fYRange = thetaRange,
01160 fZRange = radiusRange;
01161 fFactor = factor;
01162 }
01163
01164 fXScale = 0.5;
01165 fYScale = 0.5;
01166 fZScale = 0.5;
01167 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
01168 fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
01169 fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
01170
01171 return kTRUE;
01172 }
01173
01174 namespace {
01175
01176
01177 Double_t FindMinBinWidth(const TAxis *axis)
01178 {
01179
01180
01181 Int_t currBin = axis->GetFirst();
01182 Double_t width = axis->GetBinWidth(currBin);
01183
01184 if (!axis->IsVariableBinSize())
01185 return width;
01186
01187 ++currBin;
01188
01189 for (const Int_t lastBin = axis->GetLast(); currBin <= lastBin; ++currBin)
01190 width = TMath::Min(width, axis->GetBinWidth(currBin));
01191
01192 return width;
01193 }
01194
01195
01196 Bool_t FindAxisRange(const TAxis *axis, Bool_t log, Rgl::BinRange_t &bins, Rgl::Range_t &range)
01197 {
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 bins.first = axis->GetFirst(), bins.second = axis->GetLast();
01209 range.first = axis->GetBinLowEdge(bins.first), range.second = axis->GetBinUpEdge(bins.second);
01210
01211 if (log) {
01212 if (range.second <= 0.)
01213 return kFALSE;
01214
01215 range.second = TMath::Log10(range.second);
01216
01217 if (range.first <= 0.) {
01218 Int_t bin = axis->FindFixBin(FindMinBinWidth(axis) * 0.01);
01219
01220 if (bin > bins.second)
01221 return kFALSE;
01222
01223 if (axis->GetBinLowEdge(bin) <= 0.) {
01224 ++bin;
01225 if (bin > bins.second)
01226 return kFALSE;
01227 }
01228
01229 bins.first = bin;
01230 range.first = axis->GetBinLowEdge(bin);
01231 }
01232
01233 range.first = TMath::Log10(range.first);
01234 }
01235
01236 return kTRUE;
01237 }
01238
01239
01240 Bool_t FindAxisRange(const TH1 *hist, Bool_t logZ, const Rgl::BinRange_t &xBins,
01241 const Rgl::BinRange_t &yBins, Rgl::Range_t &zRange,
01242 Double_t &factor, Bool_t errors)
01243 {
01244
01245 const Bool_t minimum = hist->GetMinimumStored() != -1111;
01246 const Bool_t maximum = hist->GetMaximumStored() != -1111;
01247 const Double_t margin = gStyle->GetHistTopMargin();
01248
01249 zRange.second = hist->GetCellContent(xBins.first, yBins.first), zRange.first = zRange.second;
01250 Double_t summ = 0.;
01251
01252 for (Int_t i = xBins.first; i <= xBins.second; ++i) {
01253 for (Int_t j = yBins.first; j <= yBins.second; ++j) {
01254 Double_t val = hist->GetCellContent(i, j);
01255 if (val > 0. && errors)
01256 val = TMath::Max(val, val + hist->GetCellError(i, j));
01257 zRange.second = TMath::Max(val, zRange.second);
01258 zRange.first = TMath::Min(val, zRange.first);
01259 summ += val;
01260 }
01261 }
01262
01263 if (hist->GetMaximumStored() != -1111)
01264 zRange.second = hist->GetMaximumStored();
01265 if (hist->GetMinimumStored() != -1111)
01266 zRange.first = hist->GetMinimumStored();
01267
01268 if (logZ && zRange.second <= 0.)
01269 return kFALSE;
01270
01271 if (zRange.first >= zRange.second)
01272 zRange.first = 0.001 * zRange.second;
01273
01274 factor = hist->GetNormFactor() > 0. ? hist->GetNormFactor() : summ;
01275 if (summ) factor /= summ;
01276 if (!factor) factor = 1.;
01277 if (factor < 0.)
01278 Warning("TGLPlotPainter::ExtractAxisZInfo",
01279 "Negative factor, negative ranges - possible incorrect behavior");
01280
01281 zRange.second *= factor;
01282 zRange.first *= factor;
01283
01284 if (logZ) {
01285 if (zRange.first <= 0.)
01286 zRange.first = TMath::Min(1., 0.001 * zRange.second);
01287 zRange.first = TMath::Log10(zRange.first);
01288 if (!minimum)
01289 zRange.first += TMath::Log10(0.5);
01290 zRange.second = TMath::Log10(zRange.second);
01291 if (!maximum)
01292 zRange.second += TMath::Log10(2*(0.9/0.95));
01293 return kTRUE;
01294 }
01295
01296 if (!maximum)
01297 zRange.second += margin * (zRange.second - zRange.first);
01298 if (!minimum) {
01299 if (gStyle->GetHistMinimumZero())
01300 zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
01301 else
01302 zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
01303 zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
01304 }
01305
01306 return kTRUE;
01307 }
01308
01309
01310 Bool_t FindAxisRange(TH2Poly *hist, Bool_t logZ, Rgl::Range_t &zRange)
01311 {
01312
01313 TList *bins = hist->GetBins();
01314 if (!bins || !bins->GetEntries()) {
01315 Error("FindAxisRange", "TH2Poly returned empty list of bins");
01316 return kFALSE;
01317 }
01318
01319 zRange.first = hist->GetMinimum();
01320 zRange.second = hist->GetMaximum();
01321
01322 if (zRange.first >= zRange.second)
01323 zRange.first = 0.001 * zRange.second;
01324
01325 if (logZ) {
01326 if (zRange.second < 1e-20) {
01327 Error("FindAxisRange", "Failed to switch Z axis to logarithmic scale");
01328 return kFALSE;
01329 }
01330
01331 if (zRange.first <= 0.)
01332 zRange.first = TMath::Min(1., 0.001 * zRange.second);
01333
01334 zRange.first = TMath::Log10(zRange.first);
01335 zRange.first += TMath::Log10(0.5);
01336 zRange.second = TMath::Log10(zRange.second);
01337 zRange.second += TMath::Log10(2 * (0.9 / 0.95));
01338
01339 return kTRUE;
01340 }
01341
01342 const Double_t margin = gStyle->GetHistTopMargin();
01343 zRange.second += margin * (zRange.second - zRange.first);
01344 if (gStyle->GetHistMinimumZero())
01345 zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
01346 else
01347 zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
01348 zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
01349
01350 return kTRUE;
01351 }
01352
01353 }
01354
01355
01356
01357
01358
01359
01360 ClassImp(TGLBoxCut)
01361
01362
01363 TGLBoxCut::TGLBoxCut(const TGLPlotBox *box)
01364 : fXLength(0.),
01365 fYLength(0.),
01366 fZLength(0.),
01367 fPlotBox(box),
01368 fActive(kFALSE),
01369 fFactor(1.)
01370 {
01371
01372 }
01373
01374
01375 TGLBoxCut::~TGLBoxCut()
01376 {
01377
01378 }
01379
01380
01381 void TGLBoxCut::TurnOnOff()
01382 {
01383
01384
01385 fActive = !fActive;
01386
01387 if (fActive) {
01388 ResetBoxGeometry();
01389 }
01390 }
01391
01392
01393 void TGLBoxCut::SetActive(Bool_t a)
01394 {
01395
01396 if (a == fActive)
01397 return;
01398 TurnOnOff();
01399 }
01400
01401
01402 void TGLBoxCut::ResetBoxGeometry()
01403 {
01404
01405
01406 const Int_t frontPoint = fPlotBox->GetFrontPoint();
01407 const TGLVertex3 *box = fPlotBox->Get3DBox();
01408 const TGLVertex3 center((box[0].X() + box[1].X()) / 2, (box[0].Y() + box[2].Y()) / 2,
01409 (box[0].Z() + box[4].Z()) / 2);
01410 fXLength = fFactor * (box[1].X() - box[0].X());
01411 fYLength = fFactor * (box[2].Y() - box[0].Y());
01412 fZLength = fFactor * (box[4].Z() - box[0].Z());
01413
01414 switch(frontPoint){
01415 case 0:
01416 fCenter.X() = box[0].X();
01417 fCenter.Y() = box[0].Y();
01418 break;
01419 case 1:
01420 fCenter.X() = box[1].X();
01421 fCenter.Y() = box[0].Y();
01422 break;
01423 case 2:
01424 fCenter.X() = box[2].X();
01425 fCenter.Y() = box[2].Y();
01426 break;
01427 case 3:
01428 fCenter.X() = box[0].X();
01429 fCenter.Y() = box[2].Y();
01430 break;
01431 }
01432
01433 fCenter.Z() = box[0].Z() * 0.5 + box[4].Z() * 0.5;
01434 AdjustBox();
01435 }
01436
01437
01438 void TGLBoxCut::DrawBox(Bool_t selectionPass, Int_t selected)const
01439 {
01440
01441 if (!selectionPass) {
01442 glDisable(GL_LIGHTING);
01443 glLineWidth(3.f);
01444
01445 selected == TGLPlotPainter::kXAxis ? glColor3d(1., 1., 0.) : glColor3d(1., 0., 0.);
01446 glBegin(GL_LINES);
01447 glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
01448 glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
01449 glEnd();
01450
01451 selected == TGLPlotPainter::kYAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 1., 0.);
01452 glBegin(GL_LINES);
01453 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
01454 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
01455 glEnd();
01456
01457 selected == TGLPlotPainter::kZAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 0., 1.);
01458 glBegin(GL_LINES);
01459 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
01460 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
01461 glEnd();
01462
01463 glLineWidth(1.f);
01464 glEnable(GL_LIGHTING);
01465
01466 GLboolean oldBlendState = kFALSE;
01467 glGetBooleanv(GL_BLEND, &oldBlendState);
01468
01469 if (!oldBlendState)
01470 glEnable(GL_BLEND);
01471
01472 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01473
01474
01475 const Float_t diffuseColor[] = {0.f, 0.f, 1.f, 0.1f};
01476 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseColor);
01477
01478 Rgl::DrawBoxFront(fXRange.first, fXRange.second, fYRange.first, fYRange.second,
01479 fZRange.first, fZRange.second, fPlotBox->GetFrontPoint());
01480
01481 if (!oldBlendState)
01482 glDisable(GL_BLEND);
01483 } else {
01484 glLineWidth(5.f);
01485 Rgl::ObjectIDToColor(TGLPlotPainter::kXAxis, kFALSE);
01486 glBegin(GL_LINES);
01487 glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
01488 glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
01489 glEnd();
01490
01491 Rgl::ObjectIDToColor(TGLPlotPainter::kYAxis, kFALSE);
01492 glBegin(GL_LINES);
01493 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
01494 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
01495 glEnd();
01496
01497 Rgl::ObjectIDToColor(TGLPlotPainter::kZAxis, kFALSE);
01498 glBegin(GL_LINES);
01499 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
01500 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
01501 glEnd();
01502 glLineWidth(1.f);
01503 }
01504 }
01505
01506
01507 void TGLBoxCut::StartMovement(Int_t px, Int_t py)
01508 {
01509
01510 fMousePos.fX = px;
01511 fMousePos.fY = py;
01512 }
01513
01514
01515 void TGLBoxCut::MoveBox(Int_t px, Int_t py, Int_t axisID)
01516 {
01517
01518 Double_t mv[16] = {0.};
01519 glGetDoublev(GL_MODELVIEW_MATRIX, mv);
01520 Double_t pr[16] = {0.};
01521 glGetDoublev(GL_PROJECTION_MATRIX, pr);
01522 Int_t vp[4] = {0};
01523 glGetIntegerv(GL_VIEWPORT, vp);
01524 Double_t winVertex[3] = {0.};
01525
01526 switch(axisID){
01527 case TGLPlotPainter::kXAxis :
01528 gluProject(fCenter.X(), 0., 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
01529 break;
01530 case TGLPlotPainter::kYAxis :
01531 gluProject(0., fCenter.Y(), 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
01532 break;
01533 case TGLPlotPainter::kZAxis :
01534 gluProject(0., 0., fCenter.Z(), mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
01535 break;
01536 }
01537
01538 winVertex[0] += px - fMousePos.fX;
01539 winVertex[1] += py - fMousePos.fY;
01540 Double_t newPoint[3] = {0.};
01541 gluUnProject(winVertex[0], winVertex[1], winVertex[2], mv, pr, vp,
01542 newPoint, newPoint + 1, newPoint + 2);
01543
01544 const TGLVertex3 *box = fPlotBox->Get3DBox();
01545
01546 switch(axisID){
01547 case TGLPlotPainter::kXAxis :
01548 if (newPoint[0] >= box[1].X() + 0.4 * fXLength)
01549 break;
01550 if (newPoint[0] <= box[0].X() - 0.4 * fXLength)
01551 break;
01552 fCenter.X() = newPoint[0];
01553 break;
01554 case TGLPlotPainter::kYAxis :
01555 if (newPoint[1] >= box[2].Y() + 0.4 * fYLength)
01556 break;
01557 if (newPoint[1] <= box[0].Y() - 0.4 * fYLength)
01558 break;
01559 fCenter.Y() = newPoint[1];
01560 break;
01561 case TGLPlotPainter::kZAxis :
01562 if (newPoint[2] >= box[4].Z() + 0.4 * fZLength)
01563 break;
01564 if (newPoint[2] <= box[0].Z() - 0.4 * fZLength)
01565 break;
01566 fCenter.Z() = newPoint[2];
01567 break;
01568 }
01569
01570 fMousePos.fX = px;
01571 fMousePos.fY = py;
01572
01573 AdjustBox();
01574 }
01575
01576
01577 void TGLBoxCut::AdjustBox()
01578 {
01579
01580 const TGLVertex3 *box = fPlotBox->Get3DBox();
01581
01582 fXRange.first = fCenter.X() - fXLength / 2.;
01583 fXRange.second = fCenter.X() + fXLength / 2.;
01584 fYRange.first = fCenter.Y() - fYLength / 2.;
01585 fYRange.second = fCenter.Y() + fYLength / 2.;
01586 fZRange.first = fCenter.Z() - fZLength / 2.;
01587 fZRange.second = fCenter.Z() + fZLength / 2.;
01588
01589 fXRange.first = TMath::Max(fXRange.first, box[0].X());
01590 fXRange.first = TMath::Min(fXRange.first, box[1].X());
01591 fXRange.second = TMath::Min(fXRange.second, box[1].X());
01592 fXRange.second = TMath::Max(fXRange.second, box[0].X());
01593
01594 fYRange.first = TMath::Max(fYRange.first, box[0].Y());
01595 fYRange.first = TMath::Min(fYRange.first, box[2].Y());
01596 fYRange.second = TMath::Min(fYRange.second, box[2].Y());
01597 fYRange.second = TMath::Max(fYRange.second, box[0].Y());
01598
01599 fZRange.first = TMath::Max(fZRange.first, box[0].Z());
01600 fZRange.first = TMath::Min(fZRange.first, box[4].Z());
01601 fZRange.second = TMath::Min(fZRange.second, box[4].Z());
01602 fZRange.second = TMath::Max(fZRange.second, box[0].Z());
01603 }
01604
01605
01606 Bool_t TGLBoxCut::IsInCut(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
01607 Double_t zMin, Double_t zMax)const
01608 {
01609
01610 if (((xMin >= fXRange.first && xMin < fXRange.second) || (xMax > fXRange.first && xMax <= fXRange.second)) &&
01611 ((yMin >= fYRange.first && yMin < fYRange.second) || (yMax > fYRange.first && yMax <= fYRange.second)) &&
01612 ((zMin >= fZRange.first && zMin < fZRange.second) || (zMax > fZRange.first && zMax <= fZRange.second)))
01613 return kTRUE;
01614 return kFALSE;
01615 }
01616
01617
01618
01619
01620
01621
01622 ClassImp(TGLTH3Slice)
01623
01624
01625 TGLTH3Slice::TGLTH3Slice(const TString &name, const TH3 *hist, const TGLPlotCoordinates *coord,
01626 const TGLPlotBox *box, ESliceAxis axis)
01627 : TNamed(name, name),
01628 fAxisType(axis),
01629 fAxis(0),
01630 fCoord(coord),
01631 fBox(box),
01632 fSliceWidth(1),
01633 fHist(hist),
01634 fF3(0)
01635 {
01636
01637 fAxis = fAxisType == kXOZ ? fHist->GetYaxis() : fAxisType == kYOZ ? fHist->GetXaxis() : fHist->GetZaxis();
01638 }
01639
01640
01641 TGLTH3Slice::TGLTH3Slice(const TString &name, const TH3 *hist, const TF3 *fun, const TGLPlotCoordinates *coord,
01642 const TGLPlotBox *box, ESliceAxis axis)
01643 : TNamed(name, name),
01644 fAxisType(axis),
01645 fAxis(0),
01646 fCoord(coord),
01647 fBox(box),
01648 fSliceWidth(1),
01649 fHist(hist),
01650 fF3(fun)
01651 {
01652
01653 fAxis = fAxisType == kXOZ ? fHist->GetYaxis() : fAxisType == kYOZ ? fHist->GetXaxis() : fHist->GetZaxis();
01654 }
01655
01656
01657 void TGLTH3Slice::SetSliceWidth(Int_t width)
01658 {
01659
01660
01661 if (width <= 0)
01662 return;
01663
01664 if (fAxis->GetLast() - fAxis->GetFirst() + 1 <= width)
01665 fSliceWidth = fAxis->GetLast() - fAxis->GetFirst() + 1;
01666 else
01667 fSliceWidth = width;
01668 }
01669
01670
01671 void TGLTH3Slice::DrawSlice(Double_t pos)const
01672 {
01673
01674 Int_t bin = 0;
01675 for (Int_t i = fAxis->GetFirst(), e = fAxis->GetLast(); i <= e; ++i) {
01676 if (pos >= fAxis->GetBinLowEdge(i) && pos <= fAxis->GetBinUpEdge(i)) {
01677 bin = i;
01678 break;
01679 }
01680 }
01681
01682 if (bin) {
01683 Int_t low = 1, up = 2;
01684 if (bin - fSliceWidth + 1 >= fAxis->GetFirst()) {
01685 low = bin - fSliceWidth + 1;
01686 up = bin + 1;
01687 } else {
01688 low = fAxis->GetFirst();
01689 up = bin + (fSliceWidth - (bin - fAxis->GetFirst() + 1)) + 1;
01690 }
01691
01692 if (!fF3)
01693 FindMinMax(low, up);
01694
01695 if (!PreparePalette())
01696 return;
01697
01698 PrepareTexCoords(pos, low, up);
01699
01700 fPalette.EnableTexture(GL_REPLACE);
01701 const TGLDisableGuard lightGuard(GL_LIGHTING);
01702 DrawSliceTextured(pos);
01703 fPalette.DisableTexture();
01704
01705
01706 }
01707 }
01708
01709
01710 void TGLTH3Slice::FindMinMax(Int_t , Int_t )const
01711 {
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759 }
01760
01761
01762 Bool_t TGLTH3Slice::PreparePalette()const
01763 {
01764
01765 UInt_t paletteSize = ((TH1 *)fHist)->GetContour();
01766 if (!paletteSize && !(paletteSize = gStyle->GetNumberContours()))
01767 paletteSize = 20;
01768
01769 return fPalette.GeneratePalette(paletteSize, fMinMax);
01770 }
01771
01772
01773 void TGLTH3Slice::PrepareTexCoords(Double_t pos, Int_t low, Int_t up)const
01774 {
01775
01776 switch (fAxisType) {
01777 case kXOZ:
01778 fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNZBins());
01779 fTexCoords.SetRowLen(fCoord->GetNXBins());
01780 if (!fF3) {
01781
01782 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
01783 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
01784 Double_t val = 0.;
01785 for (Int_t level = low; level < up; ++ level)
01786 val += fHist->GetBinContent(i, level, j);
01787 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
01788 }
01789 }
01790 } else {
01791 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
01792 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
01793 Double_t val = fF3->Eval(fHist->GetXaxis()->GetBinCenter(i), pos, fHist->GetZaxis()->GetBinCenter(j));
01794 if (val > fMinMax.second)
01795 val = fMinMax.second;
01796 else if (val < fMinMax.first)
01797 val = fMinMax.first;
01798 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
01799 }
01800 }
01801 }
01802 break;
01803 case kYOZ:
01804 fTexCoords.resize(fCoord->GetNYBins() * fCoord->GetNZBins());
01805 fTexCoords.SetRowLen(fCoord->GetNYBins());
01806 if (!fF3) {
01807 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
01808 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i <= ei; ++i, ++it) {
01809 Double_t val = 0.;
01810 for (Int_t level = low; level < up; ++ level)
01811 val += fHist->GetBinContent(level, i, j);
01812 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
01813 }
01814 }
01815 } else {
01816 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
01817 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
01818 Double_t val = fF3->Eval(pos, fHist->GetYaxis()->GetBinCenter(i), fHist->GetZaxis()->GetBinCenter(j));
01819 if (val > fMinMax.second)
01820 val = fMinMax.second;
01821 else if (val < fMinMax.first)
01822 val = fMinMax.first;
01823 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
01824 }
01825 }
01826 }
01827 break;
01828 case kXOY:
01829 fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNYBins());
01830 fTexCoords.SetRowLen(fCoord->GetNYBins());
01831 if (!fF3) {
01832 for (Int_t i = fCoord->GetFirstXBin(), ir = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++ir) {
01833 for (Int_t j = fCoord->GetFirstYBin(), jr = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jr) {
01834 Double_t val = 0.;
01835 for (Int_t level = low; level < up; ++ level)
01836 val += fHist->GetBinContent(i, j, level);
01837 fTexCoords[ir][jr] = fPalette.GetTexCoord(val);
01838 }
01839 }
01840 } else {
01841 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
01842 for (Int_t j = fCoord->GetFirstYBin(), jt = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jt) {
01843 Double_t val = fF3->Eval(fHist->GetXaxis()->GetBinCenter(i), fHist->GetYaxis()->GetBinCenter(j), pos);
01844 if (val > fMinMax.second)
01845 val = fMinMax.second;
01846 else if (val < fMinMax.first)
01847 val = fMinMax.first;
01848 fTexCoords[it][jt] = fPalette.GetTexCoord(val);
01849 }
01850 }
01851
01852 }
01853 break;
01854 }
01855 }
01856
01857
01858 void TGLTH3Slice::DrawSliceTextured(Double_t pos)const
01859 {
01860
01861
01862 const Double_t xScale = fCoord->GetXScale();
01863 const Double_t yScale = fCoord->GetYScale();
01864 const Double_t zScale = fCoord->GetZScale();
01865 const TAxis *xA = fHist->GetXaxis();
01866 const TAxis *yA = fHist->GetYaxis();
01867 const TAxis *zA = fHist->GetZaxis();
01868
01869 switch (fAxisType) {
01870 case kXOZ:
01871 pos *= yScale;
01872 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
01873 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i < ei; ++i, ++it) {
01874 const Double_t xMin = xA->GetBinCenter(i) * xScale;
01875 const Double_t xMax = xA->GetBinCenter(i + 1) * xScale;
01876 const Double_t zMin = zA->GetBinCenter(j) * zScale;
01877 const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
01878 glBegin(GL_POLYGON);
01879 glTexCoord1d(fTexCoords[jt][it]);
01880 glVertex3d(xMin, pos, zMin);
01881 glTexCoord1d(fTexCoords[jt + 1][it]);
01882 glVertex3d(xMin, pos, zMax);
01883 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
01884 glVertex3d(xMax, pos, zMax);
01885 glTexCoord1d(fTexCoords[jt][it + 1]);
01886 glVertex3d(xMax, pos, zMin);
01887 glEnd();
01888 }
01889 }
01890 break;
01891 case kYOZ:
01892 pos *= xScale;
01893 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
01894 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
01895 const Double_t yMin = yA->GetBinCenter(i) * yScale;
01896 const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
01897 const Double_t zMin = zA->GetBinCenter(j) * zScale;
01898 const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
01899 glBegin(GL_POLYGON);
01900 glTexCoord1d(fTexCoords[jt][it]);
01901 glVertex3d(pos, yMin, zMin);
01902 glTexCoord1d(fTexCoords[jt][it + 1]);
01903 glVertex3d(pos, yMax, zMin);
01904 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
01905 glVertex3d(pos, yMax, zMax);
01906 glTexCoord1d(fTexCoords[jt + 1][it]);
01907 glVertex3d(pos, yMin, zMax);
01908 glEnd();
01909 }
01910 }
01911 break;
01912 case kXOY:
01913 pos *= zScale;
01914 for (Int_t j = fCoord->GetFirstXBin(), jt = 0, ej = fCoord->GetLastXBin(); j < ej; ++j, ++jt) {
01915 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
01916 const Double_t xMin = xA->GetBinCenter(j) * xScale;
01917 const Double_t xMax = xA->GetBinCenter(j + 1) * xScale;
01918 const Double_t yMin = yA->GetBinCenter(i) * yScale;
01919 const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
01920 glBegin(GL_POLYGON);
01921 glTexCoord1d(fTexCoords[jt + 1][it]);
01922 glVertex3d(xMax, yMin, pos);
01923 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
01924 glVertex3d(xMax, yMax, pos);
01925 glTexCoord1d(fTexCoords[jt][it + 1]);
01926 glVertex3d(xMin, yMax, pos);
01927 glTexCoord1d(fTexCoords[jt][it]);
01928 glVertex3d(xMin, yMin, pos);
01929 glEnd();
01930 }
01931 }
01932 break;
01933 }
01934 }
01935
01936 namespace {
01937
01938
01939 void DrawBoxOutline(Double_t xMin, Double_t xMax, Double_t yMin,
01940 Double_t yMax, Double_t zMin, Double_t zMax)
01941 {
01942 glBegin(GL_LINE_LOOP);
01943 glVertex3d(xMin, yMin, zMin);
01944 glVertex3d(xMax, yMin, zMin);
01945 glVertex3d(xMax, yMax, zMin);
01946 glVertex3d(xMin, yMax, zMin);
01947 glEnd();
01948
01949 glBegin(GL_LINE_LOOP);
01950 glVertex3d(xMin, yMin, zMax);
01951 glVertex3d(xMax, yMin, zMax);
01952 glVertex3d(xMax, yMax, zMax);
01953 glVertex3d(xMin, yMax, zMax);
01954 glEnd();
01955
01956 glBegin(GL_LINES);
01957 glVertex3d(xMin, yMin, zMin);
01958 glVertex3d(xMin, yMin, zMax);
01959 glVertex3d(xMax, yMin, zMin);
01960 glVertex3d(xMax, yMin, zMax);
01961 glVertex3d(xMax, yMax, zMin);
01962 glVertex3d(xMax, yMax, zMax);
01963 glVertex3d(xMin, yMax, zMin);
01964 glVertex3d(xMin, yMax, zMax);
01965 glEnd();
01966 }
01967
01968 }
01969
01970
01971 void TGLTH3Slice::DrawSliceFrame(Int_t low, Int_t up)const
01972 {
01973
01974
01975 glColor3d(1., 0., 0.);
01976 const TGLVertex3 *box = fBox->Get3DBox();
01977
01978 switch (fAxisType) {
01979 case kXOZ:
01980 DrawBoxOutline(box[0].X(), box[1].X(),
01981 fAxis->GetBinLowEdge(low) * fCoord->GetYScale(),
01982 fAxis->GetBinUpEdge(up - 1) * fCoord->GetYScale(),
01983 box[0].Z(), box[4].Z());
01984 break;
01985 case kYOZ:
01986 DrawBoxOutline(fAxis->GetBinLowEdge(low) * fCoord->GetXScale(),
01987 fAxis->GetBinUpEdge(up - 1) * fCoord->GetXScale(),
01988 box[0].Y(), box[2].Y(),
01989 box[0].Z(), box[4].Z());
01990 break;
01991 case kXOY:
01992 DrawBoxOutline(box[0].X(), box[1].X(),
01993 box[0].Y(), box[2].Y(),
01994 fAxis->GetBinLowEdge(low) * fCoord->GetZScale(),
01995 fAxis->GetBinUpEdge(up - 1) * fCoord->GetZScale());
01996 break;
01997 }
01998 }
01999
02000 namespace Rgl {
02001
02002
02003 PlotTranslation::PlotTranslation(const TGLPlotPainter *painter)
02004 : fPainter(painter)
02005 {
02006 const TGLVertex3 *box = fPainter->fBackBox.Get3DBox();
02007 const Double_t center[] = {(box[0].X() + box[1].X()) / 2,
02008 (box[0].Y() + box[2].Y()) / 2,
02009 (box[0].Z() + box[4].Z()) / 2};
02010
02011 fPainter->SaveModelviewMatrix();
02012 glTranslated(-center[0], -center[1], -center[2]);
02013 }
02014
02015
02016 PlotTranslation::~PlotTranslation()
02017 {
02018 fPainter->RestoreModelviewMatrix();
02019 }
02020
02021 namespace
02022 {
02023
02024 const Double_t lr = 0.85;
02025 const Double_t rr = 0.9;
02026
02027 }
02028
02029
02030 void DrawPalette(const TGLPlotCamera * camera, const TGLLevelPalette & palette)
02031 {
02032
02033 const TGLDisableGuard light(GL_LIGHTING);
02034 const TGLDisableGuard depth(GL_DEPTH_TEST);
02035 const TGLEnableGuard blend(GL_BLEND);
02036
02037 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
02038
02039 glMatrixMode(GL_PROJECTION);
02040 glLoadIdentity();
02041 glOrtho(0, camera->GetWidth(), 0, camera->GetHeight(), -1., 1.);
02042
02043 glMatrixMode(GL_MODELVIEW);
02044 glLoadIdentity();
02045
02046 const Double_t leftX = camera->GetWidth() * lr;
02047 const Double_t rightX = camera->GetWidth() * rr;
02048 const Double_t margin = 0.1 * camera->GetHeight();
02049 const Double_t h = (camera->GetHeight() * 0.8) / palette.GetPaletteSize();
02050
02051 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
02052 glBegin(GL_POLYGON);
02053 const UChar_t * color = palette.GetColour(i);
02054 glColor4ub(color[0], color[1], color[2], 150);
02055 glVertex2d(leftX, margin + i * h);
02056 glVertex2d(rightX, margin + i * h);
02057 glVertex2d(rightX, margin + (i + 1) * h);
02058 glVertex2d(leftX, margin + (i + 1) * h);
02059 glEnd();
02060 }
02061
02062 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
02063 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
02064 glColor4d(0., 0., 0., 0.5);
02065
02066 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
02067 glBegin(GL_LINE_LOOP);
02068 glVertex2d(leftX, margin + i * h);
02069 glVertex2d(rightX, margin + i * h);
02070 glVertex2d(rightX, margin + (i + 1) * h);
02071 glVertex2d(leftX, margin + (i + 1) * h);
02072 glEnd();
02073 }
02074
02075 }
02076
02077
02078 void DrawPaletteAxis(const TGLPlotCamera * camera, const Range_t & minMax, Bool_t logZ)
02079 {
02080 const Double_t x = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw() + rr * camera->GetWidth()));
02081 const Double_t yMin = gPad->AbsPixeltoY(Int_t(camera->GetHeight() - camera->GetHeight() * 0.1
02082 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
02083 * gPad->GetWh() + camera->GetY()));
02084 const Double_t yMax = gPad->AbsPixeltoY(Int_t(camera->GetHeight() - camera->GetHeight() * 0.9
02085 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
02086 * gPad->GetWh() + camera->GetY()));
02087 Double_t zMin = minMax.first;
02088 Double_t zMax = minMax.second;
02089
02090 if (logZ) {
02091 zMin = TMath::Power(10, zMin);
02092 zMax = TMath::Power(10, zMax);
02093 }
02094
02095
02096 const Bool_t logX = gPad->GetLogx();
02097 gPad->SetLogx(kFALSE);
02098 const Bool_t logY = gPad->GetLogy();
02099 gPad->SetLogy(kFALSE);
02100
02101 TGaxis axisPainter(x, yMin, x, yMax, zMin, zMax, 510, logZ ? "G" : "");
02102 axisPainter.Paint();
02103
02104 gPad->SetLogx(logX);
02105 gPad->SetLogy(logY);
02106 }
02107
02108
02109 const Double_t gH2PolyScaleXY = 1.2;
02110
02111 }
02112