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