Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLPlotPainter.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Timur Pocheptsov 14/06/2006
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11#include <cstdio>
12
13#include "TVirtualPad.h"
14#include "TVirtualPS.h"
15#include "TGaxis.h"
16#include "TGraph.h"
17#include "TStyle.h"
18#include "TError.h"
19#include "TColor.h"
20#include "TAxis.h"
21#include "TMath.h"
22#include "TList.h"
23#include "TH2Poly.h"
24#include "TH1.h"
25#include "TH3.h"
26#include "TF3.h"
27#include "TROOT.h"
28#include "TVirtualMutex.h"
29
30#include "TGLPlotPainter.h"
31#include "TGLPlotCamera.h"
32#include "TGLIncludes.h"
33#include "TGLAdapter.h"
34#include "TGLOutput.h"
35#include "TGLUtil.h"
36#include "TGL5D.h"
37#include "gl2ps.h"
38
39/** \class TGLPlotPainter
40\ingroup opengl
41Base class for plot-painters that provide GL rendering of various
422D and 3D histograms, functions and parametric surfaces.
43*/
44
46
47////////////////////////////////////////////////////////////////////////////////
48///TGLPlotPainter's ctor.
49
51 Bool_t xoy, Bool_t xoz, Bool_t yoz)
52 : fPadColor(nullptr),
53 fPhysicalShapeColor(nullptr),
54 fPadPhi(45.),
55 fPadTheta(0.),
56 fHist(hist),
57 fXAxis(hist->GetXaxis()),
58 fYAxis(hist->GetYaxis()),
59 fZAxis(hist->GetZaxis()),
60 fCoord(coord),
61 fCamera(camera),
62 fUpdateSelection(kTRUE),
63 fSelectionPass(kFALSE),
64 fSelectedPart(0),
65 fXOZSectionPos(0.),
66 fYOZSectionPos(0.),
67 fXOYSectionPos(0.),
68 fBackBox(xoy, xoz, yoz),
69 fBoxCut(&fBackBox),
70 fHighColor(kFALSE),
71 fSelectionBase(kTrueColorSelectionBase),
72 fDrawPalette(kFALSE),
73 fDrawAxes(kTRUE)
74{
75 if (gPad) {
76 fPadPhi = gPad->GetPhi();
77 fPadTheta = gPad->GetTheta();
78 }
79}
80
81////////////////////////////////////////////////////////////////////////////////
82///TGLPlotPainter's ctor.
83
85 : fPadColor(nullptr),
86 fPhysicalShapeColor(nullptr),
87 fPadPhi(45.),
88 fPadTheta(0.),
89 fHist(nullptr),
90 fXAxis(data->GetXAxis()),
91 fYAxis(data->GetYAxis()),
92 fZAxis(data->GetZAxis()),
93 fCoord(coord),
94 fCamera(camera),
95 fUpdateSelection(kTRUE),
96 fSelectionPass(kFALSE),
97 fSelectedPart(0),
98 fXOZSectionPos(0.),
99 fYOZSectionPos(0.),
100 fXOYSectionPos(0.),
101 fBackBox(kFALSE, kFALSE, kFALSE),
102 fBoxCut(&fBackBox),
103 fHighColor(kFALSE),
104 fSelectionBase(kTrueColorSelectionBase),
105 fDrawPalette(kFALSE),
106 fDrawAxes(kTRUE)
107{
108 if (gPad) {
109 fPadPhi = gPad->GetPhi();
110 fPadTheta = gPad->GetTheta();
111 }
112}
113
114////////////////////////////////////////////////////////////////////////////////
115///TGLPlotPainter's ctor.
116
118 : fPadColor(nullptr),
119 fPhysicalShapeColor(nullptr),
120 fPadPhi(45.),
121 fPadTheta(0.),
122 fHist(nullptr),
123 fXAxis(nullptr),
124 fYAxis(nullptr),
125 fZAxis(nullptr),
126 fCoord(nullptr),
127 fCamera(camera),
128 fUpdateSelection(kTRUE),
129 fSelectionPass(kFALSE),
130 fSelectedPart(0),
131 fXOZSectionPos(0.),
132 fYOZSectionPos(0.),
133 fXOYSectionPos(0.),
134 fBackBox(kFALSE, kFALSE, kFALSE),
135 fBoxCut(&fBackBox),
136 fHighColor(kFALSE),
137 fSelectionBase(kTrueColorSelectionBase),
138 fDrawPalette(kFALSE),
139 fDrawAxes(kTRUE)
140{
141 if (gPad) {
142 fPadPhi = gPad->GetPhi();
143 fPadTheta = gPad->GetTheta();
144 }
145}
146
147////////////////////////////////////////////////////////////////////////////////
148///Draw lego/surf/whatever you can.
149
151{
153
156
157 int vp[4] = {};
158 glGetIntegerv(GL_VIEWPORT, vp);
159
160 //GL pad painter does not use depth test,
161 //so, switch it on now.
162 glDepthMask(GL_TRUE);//[0
163 //
164 InitGL();
165 //Save material/light properties in a stack.
166 glPushAttrib(GL_LIGHTING_BIT);
167
168 //Save projection and modelview matrix, used by glpad.
171
172 //glOrtho etc.
174 //
175 glClear(GL_DEPTH_BUFFER_BIT);
176 //Set light.
177 const Float_t pos[] = {0.f, 0.f, 0.f, 1.f};
178 glLightfv(GL_LIGHT0, GL_POSITION, pos);
179 //Set transformation - shift and rotate the scene.
182
183 if (gVirtualPS)
184 PrintPlot();
185
186 DrawPlot();
187 //Restore material properties from stack.
188 glPopAttrib();
189 //
190 DeInitGL();//Disable/enable, what concrete plot painter enabled/disabled
191
192 //Restore projection and modelview matrices.
195
196 glViewport(vp[0], vp[1], vp[2], vp[3]);
197 //GL pad painter does not use depth test, so,
198 //switch it off now.
199 glDepthMask(GL_FALSE);//0]
200
202
203 Bool_t old = gPad->TestBit(TGraph::kClipFrame);
204 if (!old)
205 gPad->SetBit(TGraph::kClipFrame);
206
207 //Viewport on retina is bigger than real pixel coordinates in
208 //a pad, scale it back.
211 if (scale < 1.f)//Just ignore this.
212 scale = 1.f;
213
214 const Int_t viewport[] = {Int_t(fCamera->GetX() / scale),
215 Int_t(fCamera->GetY() / scale),
216 Int_t(fCamera->GetWidth() / scale),
217 Int_t(fCamera->GetHeight() / scale)};
219 if (fDrawPalette)
221
222 if (!old)
223 gPad->ResetBit(TGraph::kClipFrame);
224 } else if(fDrawPalette)
226
227}
228
229////////////////////////////////////////////////////////////////////////////////
230/// Generate PS using gl2ps
231
233{
235
236 FILE *output = fopen(gVirtualPS->GetName(), "a");
237 if (!output) {
238 Error("TGLPlotPainter::PrintPlot", "Could not (re)open ps file for GL output");
239 //As soon as we started embedded ps, we have to close it before exiting.
241 return;
242 }
243
244 Int_t gl2psFormat = GL2PS_EPS;
245 Int_t gl2psSort = GL2PS_BSP_SORT;
246 Int_t buffsize = 0;
247 Int_t state = GL2PS_OVERFLOW;
248 GLint gl2psoption = GL2PS_USE_CURRENT_VIEWPORT |
249 GL2PS_SILENT |
250 GL2PS_BEST_ROOT |
251 GL2PS_OCCLUSION_CULL |
252 0;
253
254 while (state == GL2PS_OVERFLOW) {
255 buffsize += 1024*1024;
256 gl2psBeginPage ("ROOT Scene Graph", "ROOT", nullptr,
257 gl2psFormat, gl2psSort, gl2psoption,
258 GL_RGBA, 0, nullptr,0, 0, 0,
259 buffsize, output, nullptr);
260 DrawPlot();
261 state = gl2psEndPage();
262 }
263
264 fclose(output);
266 glFlush();
267}
268
269////////////////////////////////////////////////////////////////////////////////
270///Read color buffer content to find selected object
271
273{
274 if (fUpdateSelection) {
275 //Save projection and modelview matrix, used by glpad.
276 glMatrixMode(GL_PROJECTION);//[1
277 glPushMatrix();
278 glMatrixMode(GL_MODELVIEW);//[2
279 glPushMatrix();
280
283
284 glDepthMask(GL_TRUE);
285 glClearColor(0.f, 0.f, 0.f, 0.f);
286 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
287
289 DrawPlot();
290
291 glFinish();
292 //fSelection.ReadColorBuffer(fCamera->GetWidth(), fCamera->GetHeight());
293
297
298 glDepthMask(GL_FALSE);
299 glDisable(GL_DEPTH_TEST);
300
301 //Restore projection and modelview matrices.
302 glMatrixMode(GL_PROJECTION);//1]
303 glPopMatrix();
304 glMatrixMode(GL_MODELVIEW);//2]
305 glPopMatrix();
306 }
307
308 px -= Int_t(gPad->GetXlowNDC() * gPad->GetWw());
309 py -= Int_t(gPad->GetWh() - gPad->YtoAbsPixel(gPad->GetY1()));
310
311 //Pixel coords can be affected by scaling factor on retina displays.
314
315 if (scale > 1.f) {
316 px *= scale;
317 py *= scale;
318 }
319
320 //py = fCamera->GetHeight() - py;
321 //Y is a number of a row, x - column.
322 std::swap(px, py);
324
325 if (newSelected != fSelectedPart) {
326 //New object was selected (or surface deselected) - re-paint.
327 fSelectedPart = newSelected;
328 gPad->Update();
329 }
330
331 return fSelectedPart ? kTRUE : kFALSE;
332}
333
334////////////////////////////////////////////////////////////////////////////////
335///Used in a pad.
336
338{
339 fPadColor = c;
340}
341
342////////////////////////////////////////////////////////////////////////////////
343///Set plot's back box color.
344
346{
348}
349
350////////////////////////////////////////////////////////////////////////////////
351///Selection must be updated.
352
354{
356}
357
358////////////////////////////////////////////////////////////////////////////////
359///Get pad color.
360
362{
363 return fPadColor;
364}
365
366////////////////////////////////////////////////////////////////////////////////
367///Create dynamic profile using selected plane
368
370{
371 //Coordinates are expected to be fixed for retina!
372
373 const TGLVertex3 *frame = fBackBox.Get3DBox();
374 const Int_t frontPoint = fBackBox.GetFrontPoint();
375
376 if (fSelectedPart == 1) {
377 fXOYSectionPos = frame[0].Z();
378 fSelectedPart = 6;
379 } else if (fSelectedPart == 2) {
380 if (frontPoint == 2) {
381 fXOZSectionPos = frame[0].Y();
382 fSelectedPart = 4;
383 } else if (!frontPoint) {
384 fXOZSectionPos = frame[2].Y();
385 fSelectedPart = 4;
386 } else if (frontPoint == 1) {
387 fYOZSectionPos = frame[0].X();
388 fSelectedPart = 5;
389 } else if (frontPoint == 3) {
390 fYOZSectionPos = frame[1].X();
391 fSelectedPart = 5;
392 }
393 } else if (fSelectedPart == 3) {
394 if (frontPoint == 2) {
395 fYOZSectionPos = frame[0].X();
396 fSelectedPart = 5;
397 } else if (!frontPoint) {
398 fYOZSectionPos = frame[1].X();
399 fSelectedPart = 5;
400 } else if (frontPoint == 1) {
401 fXOZSectionPos = frame[2].Y();
402 fSelectedPart = 4;
403 } else if (frontPoint == 3) {
404 fXOZSectionPos = frame[0].Y();
405 fSelectedPart = 4;
406 }
407 }
408
409 Double_t mv[16] = {0.};
410 glGetDoublev(GL_MODELVIEW_MATRIX, mv);
411 Double_t pr[16] = {0.};
412 glGetDoublev(GL_PROJECTION_MATRIX, pr);
413 Int_t vp[4] = {0};
414 glGetIntegerv(GL_VIEWPORT, vp);
415 Double_t winVertex[3] = {0.};
416
417 if (fSelectedPart == 6)
418 gluProject(0., 0., fXOYSectionPos, mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
419 else
420 gluProject(fSelectedPart == 5 ? fYOZSectionPos : 0.,
421 fSelectedPart == 4 ? fXOZSectionPos : 0.,
422 0., mv, pr, vp,
423 &winVertex[0], &winVertex[1], &winVertex[2]);
424 winVertex[0] += px - fMousePosition.fX;
425 winVertex[1] += py - fMousePosition.fY;
426 Double_t newPoint[3] = {0.};
427 gluUnProject(winVertex[0], winVertex[1], winVertex[2], mv, pr, vp,
428 newPoint, newPoint + 1, newPoint + 2);
429
430 if (fSelectedPart == 4)
431 fXOZSectionPos = newPoint[1];
432 else if (fSelectedPart == 5)
433 fYOZSectionPos = newPoint[0];
434 else
435 fXOYSectionPos = newPoint[2];
436}
437
438////////////////////////////////////////////////////////////////////////////////
439///Draw sections (if any).
440
442{
443 const TGLVertex3 *frame = fBackBox.Get3DBox();
444
445 if (fXOZSectionPos > frame[0].Y()) {
446 if (fXOZSectionPos > frame[2].Y())
447 fXOZSectionPos = frame[2].Y();
448 const TGLVertex3 v1(frame[0].X(), fXOZSectionPos, frame[0].Z());
449 const TGLVertex3 v2(frame[4].X(), fXOZSectionPos, frame[4].Z());
450 const TGLVertex3 v3(frame[5].X(), fXOZSectionPos, frame[5].Z());
451 const TGLVertex3 v4(frame[1].X(), fXOZSectionPos, frame[1].Z());
452
453 if (fSelectionPass)
455 else if (fSelectedPart == 4)
456 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
457
458 glEnable(GL_POLYGON_OFFSET_FILL);
459 glPolygonOffset(1.f, 1.f);
460 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 1., 0.));
461 glDisable(GL_POLYGON_OFFSET_FILL);
462 //Zlevels here.
463 if (!fSelectionPass) {
464 if (fSelectedPart == 4)
465 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
466 const TGLDisableGuard lightGuard(GL_LIGHTING);
467 const TGLEnableGuard blendGuard(GL_BLEND);
468 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
469 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
470 glDepthMask(GL_FALSE);
472 //Draw z-levels
473 const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);//[1-1]
474 const UShort_t stipple = 0x5555;
475 glLineStipple(1, stipple);
476
477 glColor3d(0., 0., 0.);
478 glBegin(GL_LINES);
479 for (UInt_t i = 0; i < fZLevels.size(); ++i) {
480 glVertex3d(fBackBox.Get3DBox()[1].X(), fXOZSectionPos, fZLevels[i]);
481 glVertex3d(fBackBox.Get3DBox()[0].X(), fXOZSectionPos, fZLevels[i]);
482 }
483 glEnd();
484 glDepthMask(GL_TRUE);
485 }
486 }
487
488 if (fYOZSectionPos > frame[0].X()) {
489 if (fYOZSectionPos > frame[1].X())
490 fYOZSectionPos = frame[1].X();
491 TGLVertex3 v1(fYOZSectionPos, frame[0].Y(), frame[0].Z());
492 TGLVertex3 v2(fYOZSectionPos, frame[3].Y(), frame[3].Z());
493 TGLVertex3 v3(fYOZSectionPos, frame[7].Y(), frame[7].Z());
494 TGLVertex3 v4(fYOZSectionPos, frame[4].Y(), frame[4].Z());
495
496 if (fSelectionPass) {
498 } else if (fSelectedPart == 5)
499 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
500
501 glEnable(GL_POLYGON_OFFSET_FILL);
502 glPolygonOffset(1.f, 1.f);
503 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(1., 0., 0.));
504 glDisable(GL_POLYGON_OFFSET_FILL);
505
506 if (!fSelectionPass) {
507 if (fSelectedPart == 5)
508 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
509 const TGLDisableGuard lightHuard(GL_LIGHTING);
510 const TGLEnableGuard blendGuard(GL_BLEND);
511 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
512 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
513 glDepthMask(GL_FALSE);
515 //Draw z-levels
516 const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);//[1-1]
517 glLineStipple(1, 0x5555);
518
519 glColor3d(0., 0., 0.);
520 glBegin(GL_LINES);
521 for (UInt_t i = 0; i < fZLevels.size(); ++i) {
522 glVertex3d(fYOZSectionPos, fBackBox.Get3DBox()[3].Y(), fZLevels[i]);
523 glVertex3d(fYOZSectionPos, fBackBox.Get3DBox()[0].Y(), fZLevels[i]);
524 }
525 glEnd();
526 glDepthMask(GL_TRUE);
527 }
528 }
529
530 if (fXOYSectionPos > frame[0].Z()) {
531 if (fXOYSectionPos > frame[4].Z())
532 fXOYSectionPos = frame[4].Z();
533 TGLVertex3 v1(frame[0].X(), frame[0].Y(), fXOYSectionPos);
534 TGLVertex3 v2(frame[1].X(), frame[1].Y(), fXOYSectionPos);
535 TGLVertex3 v3(frame[2].X(), frame[2].Y(), fXOYSectionPos);
536 TGLVertex3 v4(frame[3].X(), frame[3].Y(), fXOYSectionPos);
537
538 if (fSelectionPass) {
540 } else if (fSelectedPart == 6)
541 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
542
543 glEnable(GL_POLYGON_OFFSET_FILL);
544 glPolygonOffset(1.f, 1.f);
545 //if (fSelectionPass || fSelectedPart == 6)
546 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 0., 1.));
547 glDisable(GL_POLYGON_OFFSET_FILL);
548
549 if (!fSelectionPass) {
550 if (fSelectedPart == 6)
551 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
552 const TGLDisableGuard lightGuard(GL_LIGHTING);
553 const TGLEnableGuard blendGuard(GL_BLEND);
554 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
555 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
556 glDepthMask(GL_FALSE);
558 glDepthMask(GL_TRUE);
559 }
560 }
561}
562
563////////////////////////////////////////////////////////////////////////////////
564
566{
567/*
568 // Clear buffer.
569 Float_t rgb[3] = {1.f, 1.f, 1.f};
570 if (const TColor *color = GetPadColor())
571 color->GetRGB(rgb[0], rgb[1], rgb[2]);
572 glClearColor(rgb[0], rgb[1], rgb[2], 1.);
573 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
574 */
575}
576
577////////////////////////////////////////////////////////////////////////////////
578///Draw. Palette. Axis.
579
581{
582}
583
584////////////////////////////////////////////////////////////////////////////////
585
587{
588 glMatrixMode(GL_MODELVIEW);
589 glPushMatrix();
590}
591
592////////////////////////////////////////////////////////////////////////////////
593
595{
596 glMatrixMode(GL_PROJECTION);
597 glPushMatrix();
598}
599
600////////////////////////////////////////////////////////////////////////////////
601
603{
604 glMatrixMode(GL_MODELVIEW);
605 glPopMatrix();
606}
607
608////////////////////////////////////////////////////////////////////////////////
609
611{
612 glMatrixMode(GL_PROJECTION);
613 glPopMatrix();
614}
615
616/** \class TGLPlotCoordinates
617\ingroup opengl
618Helper class for plot-painters holding information about axis
619ranges, numbers of bins and flags if certain axis is logarithmic.
620*/
621
623
624////////////////////////////////////////////////////////////////////////////////
625///Constructor.
626
628 : fCoordType(kGLCartesian),
629 fXScale(1.),
630 fYScale(1.),
631 fZScale(1.),
632 fXLog(kFALSE),
633 fYLog(kFALSE),
634 fZLog(kFALSE),
635 fModified(kFALSE),
636 fFactor(1.)
637{
638}
639
640////////////////////////////////////////////////////////////////////////////////
641///Destructor.
642
644{
645}
646
647////////////////////////////////////////////////////////////////////////////////
648///If coord type was changed, plot must reset sections (if any),
649///set fModified.
650
652{
653 if (fCoordType != type) {
656 }
657}
658
659////////////////////////////////////////////////////////////////////////////////
660/// Get coordinates type.
661
663{
664 return fCoordType;
665}
666
667////////////////////////////////////////////////////////////////////////////////
668///If log changed, sections must be reset,
669///set fModified.
670
672{
673 if (fXLog != xLog) {
674 fXLog = xLog;
676 }
677}
678
679////////////////////////////////////////////////////////////////////////////////
680/// Get X log.
681
683{
684 return fXLog;
685}
686
687////////////////////////////////////////////////////////////////////////////////
688///If log changed, sections must be reset,
689///set fModified.
690
692{
693 if (fYLog != yLog) {
694 fYLog = yLog;
696 }
697}
698
699////////////////////////////////////////////////////////////////////////////////
700/// Get Y log.
701
703{
704 return fYLog;
705}
706
707////////////////////////////////////////////////////////////////////////////////
708///If log changed, sections must be reset,
709///set fModified.
710
712{
713 if (fZLog != zLog) {
714 fZLog = zLog;
716 }
717}
718
719////////////////////////////////////////////////////////////////////////////////
720/// Get Z log.
721
723{
724 return fZLog;
725}
726
727////////////////////////////////////////////////////////////////////////////////
728/// Reset modified.
729
731{
732 fModified = !fModified;//kFALSE;
733}
734
735////////////////////////////////////////////////////////////////////////////////
736/// Modified.
737
739{
740 return fModified;
741}
742
743////////////////////////////////////////////////////////////////////////////////
744///Set bin ranges, ranges.
745
747{
748 switch (fCoordType) {
749 case kGLPolar:
750 return SetRangesPolar(hist);
751 case kGLCylindrical:
752 return SetRangesCylindrical(hist);
753 case kGLSpherical:
754 return SetRangesSpherical(hist);
755 case kGLCartesian:
756 default:
757 return SetRangesCartesian(hist, errors, zBins);
758 }
759}
760
761////////////////////////////////////////////////////////////////////////////////
762///Number of X bins.
763
765{
766 return fXBins.second - fXBins.first + 1;
767}
768
769////////////////////////////////////////////////////////////////////////////////
770///Number of Y bins.
771
773{
774 return fYBins.second - fYBins.first + 1;
775}
776
777////////////////////////////////////////////////////////////////////////////////
778///Number of Z bins.
779
781{
782 return fZBins.second - fZBins.first + 1;
783}
784
785////////////////////////////////////////////////////////////////////////////////
786///X bins range.
787
789{
790 return fXBins;
791}
792
793////////////////////////////////////////////////////////////////////////////////
794///Y bins range.
795
797{
798 return fYBins;
799}
800
801////////////////////////////////////////////////////////////////////////////////
802///Z bins range.
803
805{
806 return fZBins;
807}
808
809////////////////////////////////////////////////////////////////////////////////
810///X range.
811
813{
814 return fXRange;
815}
816
817////////////////////////////////////////////////////////////////////////////////
818///X length.
819
821{
822 return fXRange.second - fXRange.first;
823}
824
825////////////////////////////////////////////////////////////////////////////////
826///Y range.
827
829{
830 return fYRange;
831}
832
833////////////////////////////////////////////////////////////////////////////////
834///Y length.
835
837{
838 return fYRange.second - fYRange.first;
839}
840
841
842////////////////////////////////////////////////////////////////////////////////
843///Z range.
844
846{
847 return fZRange;
848}
849
850////////////////////////////////////////////////////////////////////////////////
851///Z length.
852
854{
855 return fZRange.second - fZRange.first;
856}
857
858
859////////////////////////////////////////////////////////////////////////////////
860///Scaled range.
861
863{
864 return fXRangeScaled;
865}
866
867////////////////////////////////////////////////////////////////////////////////
868///Scaled range.
869
871{
872 return fYRangeScaled;
873}
874
875////////////////////////////////////////////////////////////////////////////////
876///Scaled range.
877
879{
880 return fZRangeScaled;
881}
882
883////////////////////////////////////////////////////////////////////////////////
884/// Get factor.
885
887{
888 return fFactor;
889}
890
891namespace {
892
893Bool_t FindAxisRange(const TAxis *axis, Bool_t log, Rgl::BinRange_t &bins, Rgl::Range_t &range);
894Bool_t FindAxisRange(const TH1 *hist, Bool_t logZ, const Rgl::BinRange_t &xBins,
895 const Rgl::BinRange_t &yBins, Rgl::Range_t &zRange,
896 Double_t &factor, Bool_t errors);
897
898Bool_t FindAxisRange(TH2Poly *hist, Bool_t zLog, Rgl::Range_t &zRange);
899
900}
901
902////////////////////////////////////////////////////////////////////////////////
903///Set bin ranges, ranges, etc.
904
906{
907 Rgl::BinRange_t xBins;
908 Rgl::Range_t xRange;
909 if (!FindAxisRange(hist->GetXaxis(), fXLog, xBins, xRange)) {
910 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set X axis to log scale");
911 return kFALSE;
912 }
913
914 Rgl::BinRange_t yBins;
915 Rgl::Range_t yRange;
916 if (!FindAxisRange(hist->GetYaxis(), fYLog, yBins, yRange)) {
917 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set Y axis to log scale");
918 return kFALSE;
919 }
920
921 Rgl::BinRange_t zBins;
922 Rgl::Range_t zRange;
923 Double_t factor = 1.;
924
925 if (zAsBins) {
926 if (!FindAxisRange(hist->GetZaxis(), fZLog, zBins, zRange)) {
927 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set Z axis to log scale");
928 return kFALSE;
929 }
930 } else if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, errors)) {
931 Error("TGLPlotCoordinates::SetRangesCartesian",
932 "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
933 return kFALSE;
934 }
935
936 //Finds the maximum dimension and adjust scale coefficients
937 const Double_t x = xRange.second - xRange.first;
938 const Double_t y = yRange.second - yRange.first;
939 const Double_t z = zRange.second - zRange.first;
940
941 if (!x || !y || !z) {
942 Error("TGLPlotCoordinates::SetRangesCartesian", "Zero axis range.");
943 return kFALSE;
944 }
945
946 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
947 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
948 {
950 }
951
952 fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
953 fFactor = factor;
954 /*
955 const Double_t maxDim = TMath::Max(TMath::Max(x, y), z);
956 fXScale = maxDim / x;
957 fYScale = maxDim / y;
958 fZScale = maxDim / z;
959 */
960 fXScale = 1. / x;
961 fYScale = 1. / y;
962 fZScale = 1. / z;
963
964 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
965 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
966 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
967
968 return kTRUE;
969}
970
971//
972////////////////////////////////////////////////////////////////////////////////
973///Set bin ranges, ranges, etc.
974
976{
977 Rgl::BinRange_t xBins;
978 Rgl::Range_t xRange;
979 FindAxisRange(hist->GetXaxis(), kFALSE, xBins, xRange);//kFALSE == never logarithmic.
980
981 Rgl::BinRange_t yBins;
982 Rgl::Range_t yRange;
983 FindAxisRange(hist->GetYaxis(), kFALSE, yBins, yRange);//kFALSE == never logarithmic.
984
985 Rgl::BinRange_t zBins;
986 Rgl::Range_t zRange;
987 Double_t factor = 1.;
988
989 if (!FindAxisRange(hist, fZLog, zRange))
990 return kFALSE;
991
992 //Finds the maximum dimension and adjust scale coefficients
993 const Double_t x = xRange.second - xRange.first;
994 const Double_t y = yRange.second - yRange.first;
995 const Double_t z = zRange.second - zRange.first;
996
997 if (!x || !y || !z) {
998 Error("TGLPlotCoordinates::SetRanges", "Zero axis range.");
999 return kFALSE;
1000 }
1001
1002 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
1003 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
1004 {
1005 fModified = kTRUE;
1006 }
1007
1008 fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
1009 fFactor = factor;
1010
1013 fZScale = 1. / z;
1014
1015 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
1016 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
1017 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
1018
1019 return kTRUE;
1020}
1021//
1022
1023////////////////////////////////////////////////////////////////////////////////
1024///Set bin ranges, ranges, etc.
1025
1026Bool_t TGLPlotCoordinates::SetRanges(const TAxis *xAxis, const TAxis *yAxis, const TAxis *zAxis)
1027{
1028 Rgl::BinRange_t xBins;
1029 Rgl::Range_t xRange;
1030
1031 FindAxisRange(xAxis, kFALSE, xBins, xRange);
1032
1033 Rgl::BinRange_t yBins;
1034 Rgl::Range_t yRange;
1035
1036 FindAxisRange(yAxis, kFALSE, yBins, yRange);
1037
1038 Rgl::BinRange_t zBins;
1039 Rgl::Range_t zRange;
1040 Double_t factor = 1.;
1041
1042 FindAxisRange(zAxis, kFALSE, zBins, zRange);
1043
1044 //Finds the maximum dimension and adjust scale coefficients
1045 const Double_t x = xRange.second - xRange.first;
1046 const Double_t y = yRange.second - yRange.first;
1047 const Double_t z = zRange.second - zRange.first;
1048
1049 if (!x || !y || !z) {
1050 Error("TGLPlotCoordinates::SetRangesCartesian", "Zero axis range.");
1051 return kFALSE;
1052 }
1053
1054 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
1055 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
1056 {
1057 fModified = kTRUE;
1058 }
1059
1060 fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
1061 fFactor = factor;
1062
1063/* const Double_t maxDim = TMath::Max(TMath::Max(x, y), z);
1064 fXScale = maxDim / x;
1065 fYScale = maxDim / y;
1066 fZScale = maxDim / z;*/
1067
1068 fXScale = 1. / x;
1069 fYScale = 1. / y;
1070 fZScale = 1. / z;
1071
1072 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
1073 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
1074 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
1075
1076 return kTRUE;
1077}
1078
1079////////////////////////////////////////////////////////////////////////////////
1080///Set bin ranges, ranges, etc.
1081
1083{
1084 Rgl::BinRange_t xBins;
1085 Rgl::Range_t phiRange;
1086 const TAxis *xAxis = hist->GetXaxis();
1087 FindAxisRange(xAxis, kFALSE, xBins, phiRange);
1088 if (xBins.second - xBins.first + 1 > 360) {
1089 Error("TGLPlotCoordinates::SetRangesPolar", "To many PHI sectors");
1090 return kFALSE;
1091 }
1092
1093 Rgl::BinRange_t yBins;
1094 Rgl::Range_t roRange;
1095 const TAxis *yAxis = hist->GetYaxis();
1096 FindAxisRange(yAxis, kFALSE, yBins, roRange);
1097
1098 Rgl::Range_t zRange;
1099 Double_t factor = 1.;
1100 if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, kFALSE))
1101 {
1102 Error("TGLPlotCoordinates::SetRangesPolar",
1103 "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
1104 return kFALSE;
1105 }
1106
1107 const Double_t z = zRange.second - zRange.first;
1108 if (!z || !(phiRange.second - phiRange.first) || !(roRange.second - roRange.first)) {
1109 Error("TGLPlotCoordinates::SetRangesPolar", "Zero axis range.");
1110 return kFALSE;
1111 }
1112
1113 if (phiRange != fXRange || roRange != fYRange || zRange != fZRange ||
1114 xBins != fXBins || yBins != fYBins || fFactor != factor)
1115 {
1116 fModified = kTRUE;
1117 fXRange = phiRange, fXBins = xBins;
1118 fYRange = roRange, fYBins = yBins;
1119 fZRange = zRange;
1120 fFactor = factor;
1121 }
1122
1123 //const Double_t maxDim = TMath::Max(2., z);
1124 fXScale = 0.5;//maxDim / 2.;
1125 fYScale = 0.5;//maxDim / 2.;
1126 fZScale = 1. / z;//maxDim / z;
1127 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
1128 fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
1129 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
1130
1131 return kTRUE;
1132}
1133
1134////////////////////////////////////////////////////////////////////////////////
1135/// Set ranges cylindrical.
1136
1138{
1139 Rgl::BinRange_t xBins, yBins;
1140 Rgl::Range_t angleRange, heightRange, radiusRange;
1141 const TAxis *xAxis = hist->GetXaxis();
1142 const TAxis *yAxis = hist->GetYaxis();
1143 Double_t factor = 1.;
1144
1145 FindAxisRange(xAxis, kFALSE, xBins, angleRange);
1146 if (xBins.second - xBins.first + 1 > 360) {
1147 Error("TGLPlotCoordinates::SetRangesCylindrical", "To many PHI sectors");
1148 return kFALSE;
1149 }
1150 if (!FindAxisRange(yAxis, fYLog, yBins, heightRange)) {
1151 Error("TGLPlotCoordinates::SetRangesCylindrical", "Cannot set Y axis to log scale");
1152 return kFALSE;
1153 }
1154 FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
1155
1156 const Double_t x = angleRange.second - angleRange.first;
1157 const Double_t y = heightRange.second - heightRange.first;
1158 const Double_t z = radiusRange.second - radiusRange.first;
1159
1160 if (!x || !y || !z) {
1161 Error("TGLPlotCoordinates::SetRangesCylindrical", "Zero axis range.");
1162 return kFALSE;
1163 }
1164
1165 if (angleRange != fXRange || heightRange != fYRange ||
1166 radiusRange != fZRange || xBins != fXBins ||
1167 yBins != fYBins || fFactor != factor)
1168 {
1169 fModified = kTRUE;
1170 fXRange = angleRange, fXBins = xBins;
1171 fYRange = heightRange, fYBins = yBins;
1172 fZRange = radiusRange;
1173 fFactor = factor;
1174 }
1175
1176 // const Double_t maxDim = TMath::Max(2., y);
1177 fXScale = 0.5;//maxDim / 2.;
1178 fYScale = 1. / y;//maxDim / y;
1179 fZScale = 0.5;//maxDim / 2.;
1180 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
1181 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
1182 fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
1183
1184 return kTRUE;
1185}
1186
1187////////////////////////////////////////////////////////////////////////////////
1188/// Set ranges spherical.
1189
1191{
1192 Rgl::BinRange_t xBins;
1193 Rgl::Range_t phiRange;
1194 FindAxisRange(hist->GetXaxis(), kFALSE, xBins, phiRange);
1195 if (xBins.second - xBins.first + 1 > 360) {
1196 Error("TGLPlotCoordinates::SetRangesSpherical", "To many PHI sectors");
1197 return kFALSE;
1198 }
1199
1200 Rgl::BinRange_t yBins;
1201 Rgl::Range_t thetaRange;
1202 FindAxisRange(hist->GetYaxis(), kFALSE, yBins, thetaRange);
1203 if (yBins.second - yBins.first + 1 > 180) {
1204 Error("TGLPlotCoordinates::SetRangesSpherical", "To many THETA sectors");
1205 return kFALSE;
1206 }
1207
1208 Rgl::Range_t radiusRange;
1209 Double_t factor = 1.;
1210 FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
1211
1212 if (xBins != fXBins || yBins != fYBins ||
1213 phiRange != fXRange || thetaRange != fYRange ||
1214 radiusRange != fZRange || fFactor != factor)
1215 {
1216 fModified = kTRUE;
1217 fXBins = xBins;
1218 fYBins = yBins;
1219 fXRange = phiRange;
1220 fYRange = thetaRange,
1221 fZRange = radiusRange;
1222 fFactor = factor;
1223 }
1224
1225 fXScale = 0.5;
1226 fYScale = 0.5;
1227 fZScale = 0.5;
1228 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
1229 fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
1230 fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
1231
1232 return kTRUE;
1233}
1234
1235namespace {
1236
1237////////////////////////////////////////////////////////////////////////////////
1238/// Find minimal bin width.
1239
1240Double_t FindMinBinWidth(const TAxis *axis)
1241{
1242 Int_t currBin = axis->GetFirst();
1243 Double_t width = axis->GetBinWidth(currBin);
1244
1245 if (!axis->IsVariableBinSize())//equal bins
1246 return width;
1247
1248 ++currBin;
1249 //variable size bins
1250 for (const Int_t lastBin = axis->GetLast(); currBin <= lastBin; ++currBin)
1251 width = TMath::Min(width, axis->GetBinWidth(currBin));
1252
1253 return width;
1254}
1255
1256////////////////////////////////////////////////////////////////////////////////
1257///"Generic" function, can be used for X/Y/Z axis.
1258///[low edge of first ..... up edge of last]
1259///If log is true, at least up edge of last MUST be positive or function fails (1).
1260///If log is true and low edge is negative, try to find bin with positive low edge, bin number
1261///must be less or equal to last (2). If no such bin, function fails.
1262///When looking for a such bin, I'm trying to find value which is 0.01 of
1263///MINIMUM bin width (3) (if bins are equidimensional, first's bin width is OK).
1264///But even such lookup can fail, so, it's a stupid idea to have negative ranges
1265///and logarithmic scale :)
1266
1267Bool_t FindAxisRange(const TAxis *axis, Bool_t log, Rgl::BinRange_t &bins, Rgl::Range_t &range)
1268{
1269 bins.first = axis->GetFirst(), bins.second = axis->GetLast();
1270 range.first = axis->GetBinLowEdge(bins.first), range.second = axis->GetBinUpEdge(bins.second);
1271
1272 if (log) {
1273 if (range.second <= 0.)
1274 return kFALSE;//(1)
1275
1276 range.second = TMath::Log10(range.second);
1277
1278 if (range.first <= 0.) {//(2)
1279 Int_t bin = axis->FindFixBin(FindMinBinWidth(axis) * 0.01);//(3)
1280 //Overflow or something stupid.
1281 if (bin > bins.second)
1282 return kFALSE;
1283
1284 if (axis->GetBinLowEdge(bin) <= 0.) {
1285 ++bin;
1286 if (bin > bins.second)//Again, something stupid.
1287 return kFALSE;
1288 }
1289
1290 bins.first = bin;
1291 range.first = axis->GetBinLowEdge(bin);
1292 }
1293
1294 range.first = TMath::Log10(range.first);
1295 }
1296
1297 return kTRUE;
1298}
1299
1300////////////////////////////////////////////////////////////////////////////////
1301///First, look through hist to find minimum and maximum values.
1302
1303Bool_t FindAxisRange(const TH1 *hist, Bool_t logZ, const Rgl::BinRange_t &xBins,
1304 const Rgl::BinRange_t &yBins, Rgl::Range_t &zRange,
1305 Double_t &factor, Bool_t errors)
1306{
1307 const Bool_t minimum = hist->GetMinimumStored() != -1111;
1308 const Bool_t maximum = hist->GetMaximumStored() != -1111;
1309 const Double_t margin = gStyle->GetHistTopMargin();
1310
1311 zRange.second = hist->GetBinContent(hist->GetBin(xBins.first, yBins.first)), zRange.first = zRange.second;
1312 Double_t summ = 0.;
1313
1314 for (Int_t i = xBins.first; i <= xBins.second; ++i) {
1315 for (Int_t j = yBins.first; j <= yBins.second; ++j) {
1316 Double_t val = hist->GetBinContent(hist->GetBin(i, j));
1317 if (val > 0. && errors)
1318 val = TMath::Max(val, val + hist->GetCellError(i, j));
1319 zRange.second = TMath::Max(val, zRange.second);
1320 zRange.first = TMath::Min(val, zRange.first);
1321 summ += val;
1322 }
1323 }
1324
1325 if (hist->GetMaximumStored() != -1111)
1326 zRange.second = hist->GetMaximumStored();
1327 if (hist->GetMinimumStored() != -1111)
1328 zRange.first = hist->GetMinimumStored();
1329
1330 if (logZ && zRange.second <= 0.)
1331 return kFALSE;//cannot setup logarithmic scale
1332
1333 if (zRange.first >= zRange.second)
1334 zRange.first = 0.001 * zRange.second;
1335
1336 factor = hist->GetNormFactor() > 0. ? hist->GetNormFactor() : summ;
1337 if (summ) factor /= summ;
1338 if (!factor) factor = 1.;
1339 if (factor < 0.)
1340 Warning("TGLPlotPainter::ExtractAxisZInfo",
1341 "Negative factor, negative ranges - possible incorrect behavior");
1342
1343 zRange.second *= factor;
1344 zRange.first *= factor;
1345
1346 if (logZ) {
1347 if (zRange.first <= 0.)
1348 zRange.first = TMath::Min(1., 0.001 * zRange.second);
1349 zRange.first = TMath::Log10(zRange.first);
1350 if (!minimum)
1351 zRange.first += TMath::Log10(0.5);
1352 zRange.second = TMath::Log10(zRange.second);
1353 if (!maximum)
1354 zRange.second += TMath::Log10(2*(0.9/0.95));//This magic numbers are from THistPainter.
1355 return kTRUE;
1356 }
1357
1358 if (!maximum)
1359 zRange.second += margin * (zRange.second - zRange.first);
1360 if (!minimum) {
1362 zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
1363 else
1364 zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
1365 zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
1366 }
1367
1368 return kTRUE;
1369}
1370
1371////////////////////////////////////////////////////////////////////////////////
1372///First, look through hist to find minimum and maximum values.
1373
1374Bool_t FindAxisRange(TH2Poly *hist, Bool_t logZ, Rgl::Range_t &zRange)
1375{
1376 TList *bins = hist->GetBins();
1377 if (!bins || !bins->GetEntries()) {
1378 Error("FindAxisRange", "TH2Poly returned empty list of bins");
1379 return kFALSE;
1380 }
1381
1382 zRange.first = hist->GetMinimum();
1383 zRange.second = hist->GetMaximum();
1384
1385 if (zRange.first >= zRange.second)
1386 zRange.first = 0.001 * zRange.second;
1387
1388 if (logZ) {
1389 if (zRange.second < 1e-20) {
1390 Error("FindAxisRange", "Failed to switch Z axis to logarithmic scale");
1391 return kFALSE;
1392 }
1393
1394 if (zRange.first <= 0.)
1395 zRange.first = TMath::Min(1., 0.001 * zRange.second);
1396
1397 zRange.first = TMath::Log10(zRange.first);
1398 zRange.first += TMath::Log10(0.5);
1399 zRange.second = TMath::Log10(zRange.second);
1400 zRange.second += TMath::Log10(2 * (0.9 / 0.95));//These magic numbers come from THistPainter.
1401
1402 return kTRUE;
1403 }
1404
1405 const Double_t margin = gStyle->GetHistTopMargin();
1406 zRange.second += margin * (zRange.second - zRange.first);
1408 zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
1409 else
1410 zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
1411 zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
1412
1413 return kTRUE;
1414}
1415
1416}
1417
1418/** \class TGLBoxCut
1419\ingroup opengl
1420Used by plot-painters to determine the area of the plot that is cut away.
1421*/
1422
1424
1425////////////////////////////////////////////////////////////////////////////////
1426///Constructor.
1427
1429 : fXLength(0.),
1430 fYLength(0.),
1431 fZLength(0.),
1432 fPlotBox(box),
1433 fActive(kFALSE),
1434 fFactor(1.)
1435{
1436}
1437
1438////////////////////////////////////////////////////////////////////////////////
1439///Destructor.
1440
1442{
1443}
1444
1445////////////////////////////////////////////////////////////////////////////////
1446///Turn the box cut on/off.
1447///If it's on, it will be placed in front point of a plot.
1448
1450{
1451 fActive = !fActive;
1452
1453 if (fActive) {
1455 }
1456}
1457
1458////////////////////////////////////////////////////////////////////////////////
1459///Turn the box cut on/off.
1460
1462{
1463 if (a == fActive)
1464 return;
1465 TurnOnOff();
1466}
1467
1468////////////////////////////////////////////////////////////////////////////////
1469///Set geometry using plot's back box.
1470
1472{
1473 const Int_t frontPoint = fPlotBox->GetFrontPoint();
1474 const TGLVertex3 *box = fPlotBox->Get3DBox();
1475 const TGLVertex3 center((box[0].X() + box[1].X()) / 2, (box[0].Y() + box[2].Y()) / 2,
1476 (box[0].Z() + box[4].Z()) / 2);
1477 fXLength = fFactor * (box[1].X() - box[0].X());
1478 fYLength = fFactor * (box[2].Y() - box[0].Y());
1479 fZLength = fFactor * (box[4].Z() - box[0].Z());
1480
1481 switch(frontPoint){
1482 case 0:
1483 fCenter.X() = box[0].X();
1484 fCenter.Y() = box[0].Y();
1485 break;
1486 case 1:
1487 fCenter.X() = box[1].X();
1488 fCenter.Y() = box[0].Y();
1489 break;
1490 case 2:
1491 fCenter.X() = box[2].X();
1492 fCenter.Y() = box[2].Y();
1493 break;
1494 case 3:
1495 fCenter.X() = box[0].X();
1496 fCenter.Y() = box[2].Y();
1497 break;
1498 }
1499
1500 fCenter.Z() = box[0].Z() * 0.5 + box[4].Z() * 0.5;
1501 AdjustBox();
1502}
1503
1504////////////////////////////////////////////////////////////////////////////////
1505///Draw cut as a semi-transparent box.
1506
1507void TGLBoxCut::DrawBox(Bool_t selectionPass, Int_t selected)const
1508{
1509 if (!selectionPass) {
1510 glDisable(GL_LIGHTING);
1511 glLineWidth(3.f);
1512
1513 selected == TGLPlotPainter::kXAxis ? glColor3d(1., 1., 0.) : glColor3d(1., 0., 0.);
1514 glBegin(GL_LINES);
1515 glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1516 glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1517 glEnd();
1518
1519 selected == TGLPlotPainter::kYAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 1., 0.);
1520 glBegin(GL_LINES);
1521 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
1522 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
1523 glEnd();
1524
1525 selected == TGLPlotPainter::kZAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 0., 1.);
1526 glBegin(GL_LINES);
1527 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
1528 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
1529 glEnd();
1530
1531 glLineWidth(1.f);
1532 glEnable(GL_LIGHTING);
1533
1534 GLboolean oldBlendState = kFALSE;
1535 glGetBooleanv(GL_BLEND, &oldBlendState);
1536
1537 if (!oldBlendState)
1538 glEnable(GL_BLEND);
1539
1540 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1541
1542
1543 const Float_t diffuseColor[] = {0.f, 0.f, 1.f, 0.1f};
1544 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseColor);
1545
1546 Rgl::DrawBoxFront(fXRange.first, fXRange.second, fYRange.first, fYRange.second,
1547 fZRange.first, fZRange.second, fPlotBox->GetFrontPoint());
1548
1549 if (!oldBlendState)
1550 glDisable(GL_BLEND);
1551 } else {
1552 glLineWidth(5.f);
1554 glBegin(GL_LINES);
1555 glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1556 glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1557 glEnd();
1558
1560 glBegin(GL_LINES);
1561 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
1562 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
1563 glEnd();
1564
1566 glBegin(GL_LINES);
1567 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
1568 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
1569 glEnd();
1570 glLineWidth(1.f);
1571 }
1572}
1573
1574////////////////////////////////////////////////////////////////////////////////
1575///Start cut's movement
1576
1578{
1579 fMousePos.fX = px;
1580 fMousePos.fY = py;
1581}
1582
1583////////////////////////////////////////////////////////////////////////////////
1584///Move box cut along selected direction.
1585
1587{
1588 Double_t mv[16] = {0.};
1589 glGetDoublev(GL_MODELVIEW_MATRIX, mv);
1590 Double_t pr[16] = {0.};
1591 glGetDoublev(GL_PROJECTION_MATRIX, pr);
1592 Int_t vp[4] = {0};
1593 glGetIntegerv(GL_VIEWPORT, vp);
1594 Double_t winVertex[3] = {0.};
1595
1596 switch(axisID){
1598 gluProject(fCenter.X(), 0., 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1599 break;
1601 gluProject(0., fCenter.Y(), 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1602 break;
1604 gluProject(0., 0., fCenter.Z(), mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1605 break;
1606 }
1607
1608 winVertex[0] += px - fMousePos.fX;
1609 winVertex[1] += py - fMousePos.fY;
1610 Double_t newPoint[3] = {0.};
1611 gluUnProject(winVertex[0], winVertex[1], winVertex[2], mv, pr, vp,
1612 newPoint, newPoint + 1, newPoint + 2);
1613
1614 const TGLVertex3 *box = fPlotBox->Get3DBox();
1615
1616 switch(axisID){
1618 if (newPoint[0] >= box[1].X() + 0.4 * fXLength)
1619 break;
1620 if (newPoint[0] <= box[0].X() - 0.4 * fXLength)
1621 break;
1622 fCenter.X() = newPoint[0];
1623 break;
1625 if (newPoint[1] >= box[2].Y() + 0.4 * fYLength)
1626 break;
1627 if (newPoint[1] <= box[0].Y() - 0.4 * fYLength)
1628 break;
1629 fCenter.Y() = newPoint[1];
1630 break;
1632 if (newPoint[2] >= box[4].Z() + 0.4 * fZLength)
1633 break;
1634 if (newPoint[2] <= box[0].Z() - 0.4 * fZLength)
1635 break;
1636 fCenter.Z() = newPoint[2];
1637 break;
1638 }
1639
1640 fMousePos.fX = px;
1641 fMousePos.fY = py;
1642
1643 AdjustBox();
1644}
1645
1646////////////////////////////////////////////////////////////////////////////////
1647///Box cut is limited by plot's sizes.
1648
1650{
1651 const TGLVertex3 *box = fPlotBox->Get3DBox();
1652
1653 fXRange.first = fCenter.X() - fXLength / 2.;
1654 fXRange.second = fCenter.X() + fXLength / 2.;
1655 fYRange.first = fCenter.Y() - fYLength / 2.;
1656 fYRange.second = fCenter.Y() + fYLength / 2.;
1657 fZRange.first = fCenter.Z() - fZLength / 2.;
1658 fZRange.second = fCenter.Z() + fZLength / 2.;
1659
1660 fXRange.first = TMath::Max(fXRange.first, box[0].X());
1661 fXRange.first = TMath::Min(fXRange.first, box[1].X());
1662 fXRange.second = TMath::Min(fXRange.second, box[1].X());
1663 fXRange.second = TMath::Max(fXRange.second, box[0].X());
1664
1665 fYRange.first = TMath::Max(fYRange.first, box[0].Y());
1666 fYRange.first = TMath::Min(fYRange.first, box[2].Y());
1667 fYRange.second = TMath::Min(fYRange.second, box[2].Y());
1668 fYRange.second = TMath::Max(fYRange.second, box[0].Y());
1669
1670 fZRange.first = TMath::Max(fZRange.first, box[0].Z());
1671 fZRange.first = TMath::Min(fZRange.first, box[4].Z());
1672 fZRange.second = TMath::Min(fZRange.second, box[4].Z());
1673 fZRange.second = TMath::Max(fZRange.second, box[0].Z());
1674}
1675
1676////////////////////////////////////////////////////////////////////////////////
1677///Check, if box defined by xmin/xmax etc. is in cut.
1678
1680 Double_t zMin, Double_t zMax)const
1681{
1682 if (((xMin >= fXRange.first && xMin < fXRange.second) || (xMax > fXRange.first && xMax <= fXRange.second)) &&
1683 ((yMin >= fYRange.first && yMin < fYRange.second) || (yMax > fYRange.first && yMax <= fYRange.second)) &&
1684 ((zMin >= fZRange.first && zMin < fZRange.second) || (zMax > fZRange.first && zMax <= fZRange.second)))
1685 return kTRUE;
1686 return kFALSE;
1687}
1688
1689
1690/** \class TGLTH3Slice
1691\ingroup opengl
1692A slice of a TH3.
1693*/
1694
1696
1697////////////////////////////////////////////////////////////////////////////////
1698/// Constructor.
1699
1701 const TGLPlotBox *box, ESliceAxis axis)
1702 : TNamed(name, name),
1703 fAxisType(axis),
1704 fAxis(nullptr),
1705 fCoord(coord),
1706 fBox(box),
1707 fSliceWidth(1),
1708 fHist(hist),
1709 fF3(nullptr)
1710{
1712}
1713
1714////////////////////////////////////////////////////////////////////////////////
1715/// Constructor.
1716
1717TGLTH3Slice::TGLTH3Slice(const TString &name, const TH3 *hist, const TF3 *fun, const TGLPlotCoordinates *coord,
1718 const TGLPlotBox *box, ESliceAxis axis)
1719 : TNamed(name, name),
1720 fAxisType(axis),
1721 fAxis(nullptr),
1722 fCoord(coord),
1723 fBox(box),
1724 fSliceWidth(1),
1725 fHist(hist),
1726 fF3(fun)
1727{
1729}
1730
1731////////////////////////////////////////////////////////////////////////////////
1732/// Set Slice width.
1733
1735{
1736 if (width <= 0)
1737 return;
1738
1739 if (fAxis->GetLast() - fAxis->GetFirst() + 1 <= width)
1740 fSliceWidth = fAxis->GetLast() - fAxis->GetFirst() + 1;
1741 else
1743}
1744
1745////////////////////////////////////////////////////////////////////////////////
1746/// Draw slice.
1747
1749{
1750 Int_t bin = 0;
1751 for (Int_t i = fAxis->GetFirst(), e = fAxis->GetLast(); i <= e; ++i) {
1752 if (pos >= fAxis->GetBinLowEdge(i) && pos <= fAxis->GetBinUpEdge(i)) {
1753 bin = i;
1754 break;
1755 }
1756 }
1757
1758 if (bin) {
1759 Int_t low = 1, up = 2;
1760 if (bin - fSliceWidth + 1 >= fAxis->GetFirst()) {
1761 low = bin - fSliceWidth + 1;
1762 up = bin + 1;
1763 } else {
1764 low = fAxis->GetFirst();
1765 up = bin + (fSliceWidth - (bin - fAxis->GetFirst() + 1)) + 1;
1766 }
1767
1768 if (!fF3)
1769 FindMinMax(low, up);
1770
1771 if (!PreparePalette())
1772 return;
1773
1774 PrepareTexCoords(pos, low, up);
1775
1776 fPalette.EnableTexture(GL_REPLACE);
1777 const TGLDisableGuard lightGuard(GL_LIGHTING);
1778 DrawSliceTextured(pos);
1780 //highlight bins in a slice.
1781 //DrawSliceFrame(low, up);
1782 }
1783}
1784
1785////////////////////////////////////////////////////////////////////////////////
1786/// Find minimum and maximum for slice.
1787
1788void TGLTH3Slice::FindMinMax(Int_t /*low*/, Int_t /*up*/)const
1789{
1790 /* fMinMax.first = 0.;
1791
1792 switch (fAxisType) {
1793 case kXOZ:
1794 for (Int_t level = low; level < up; ++ level)
1795 fMinMax.first += fHist->GetBinContent(fCoord->GetFirstXBin(), level, fCoord->GetFirstZBin());
1796 fMinMax.second = fMinMax.first;
1797 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1798 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1799 Double_t val = 0.;
1800 for (Int_t level = low; level < up; ++ level)
1801 val += fHist->GetBinContent(i, level, j);
1802 fMinMax.second = TMath::Max(fMinMax.second, val);
1803 fMinMax.first = TMath::Min(fMinMax.first, val);
1804 }
1805 }
1806 break;
1807 case kYOZ:
1808 for (Int_t level = low; level < up; ++ level)
1809 fMinMax.first += fHist->GetBinContent(level, fCoord->GetFirstYBin(), fCoord->GetFirstZBin());
1810 fMinMax.second = fMinMax.first;
1811 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1812 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i <= ei; ++i, ++it) {
1813 Double_t val = 0.;
1814 for (Int_t level = low; level < up; ++ level)
1815 val += fHist->GetBinContent(level, i, j);
1816 fMinMax.second = TMath::Max(fMinMax.second, val);
1817 fMinMax.first = TMath::Min(fMinMax.first, val);
1818 }
1819 }
1820 break;
1821 case kXOY:
1822 for (Int_t level = low; level < up; ++ level)
1823 fMinMax.first += fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin(), level);
1824 fMinMax.second = fMinMax.first;
1825 for (Int_t i = fCoord->GetFirstXBin(), ir = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++ir) {
1826 for (Int_t j = fCoord->GetFirstYBin(), jr = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jr) {
1827 Double_t val = 0.;
1828 for (Int_t level = low; level < up; ++ level)
1829 val += fHist->GetBinContent(i, j, level);
1830 fMinMax.second = TMath::Max(fMinMax.second, val);
1831 fMinMax.first = TMath::Min(fMinMax.first, val);
1832 }
1833 }
1834 break;
1835 }*/
1836}
1837
1838////////////////////////////////////////////////////////////////////////////////
1839///Initialize color palette.
1840
1842{
1843 UInt_t paletteSize = ((TH1 *)fHist)->GetContour();
1844 if (!paletteSize && !(paletteSize = gStyle->GetNumberContours()))
1845 paletteSize = 20;
1846
1847 return fPalette.GeneratePalette(paletteSize, fMinMax);
1848}
1849
1850////////////////////////////////////////////////////////////////////////////////
1851/// Prepare TexCoords.
1852
1854{
1855 switch (fAxisType) {
1856 case kXOZ:
1857 fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNZBins());
1858 fTexCoords.SetRowLen(fCoord->GetNXBins());
1859 if (!fF3) {
1860
1861 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1862 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1863 Double_t val = 0.;
1864 for (Int_t level = low; level < up; ++ level)
1865 val += fHist->GetBinContent(i, level, j);
1866 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1867 }
1868 }
1869 } else {
1870 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1871 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1873 if (val > fMinMax.second)
1874 val = fMinMax.second;
1875 else if (val < fMinMax.first)
1876 val = fMinMax.first;
1877 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1878 }
1879 }
1880 }
1881 break;
1882 case kYOZ:
1883 fTexCoords.resize(fCoord->GetNYBins() * fCoord->GetNZBins());
1884 fTexCoords.SetRowLen(fCoord->GetNYBins());
1885 if (!fF3) {
1886 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1887 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i <= ei; ++i, ++it) {
1888 Double_t val = 0.;
1889 for (Int_t level = low; level < up; ++ level)
1890 val += fHist->GetBinContent(level, i, j);
1891 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1892 }
1893 }
1894 } else {
1895 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1896 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1898 if (val > fMinMax.second)
1899 val = fMinMax.second;
1900 else if (val < fMinMax.first)
1901 val = fMinMax.first;
1902 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1903 }
1904 }
1905 }
1906 break;
1907 case kXOY:
1908 fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNYBins());
1909 fTexCoords.SetRowLen(fCoord->GetNYBins());
1910 if (!fF3) {
1911 for (Int_t i = fCoord->GetFirstXBin(), ir = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++ir) {
1912 for (Int_t j = fCoord->GetFirstYBin(), jr = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jr) {
1913 Double_t val = 0.;
1914 for (Int_t level = low; level < up; ++ level)
1915 val += fHist->GetBinContent(i, j, level);
1916 fTexCoords[ir][jr] = fPalette.GetTexCoord(val);
1917 }
1918 }
1919 } else {
1920 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1921 for (Int_t j = fCoord->GetFirstYBin(), jt = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jt) {
1923 if (val > fMinMax.second)
1924 val = fMinMax.second;
1925 else if (val < fMinMax.first)
1926 val = fMinMax.first;
1927 fTexCoords[it][jt] = fPalette.GetTexCoord(val);
1928 }
1929 }
1930
1931 }
1932 break;
1933 }
1934}
1935
1936////////////////////////////////////////////////////////////////////////////////
1937/// Draw slice textured.
1938
1940{
1941 const Double_t xScale = fCoord->GetXScale();
1942 const Double_t yScale = fCoord->GetYScale();
1943 const Double_t zScale = fCoord->GetZScale();
1944 const TAxis *xA = fHist->GetXaxis();
1945 const TAxis *yA = fHist->GetYaxis();
1946 const TAxis *zA = fHist->GetZaxis();
1947
1948 switch (fAxisType) {
1949 case kXOZ:
1950 pos *= yScale;
1951 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
1952 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i < ei; ++i, ++it) {
1953 const Double_t xMin = xA->GetBinCenter(i) * xScale;
1954 const Double_t xMax = xA->GetBinCenter(i + 1) * xScale;
1955 const Double_t zMin = zA->GetBinCenter(j) * zScale;
1956 const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
1957 glBegin(GL_POLYGON);
1958 glTexCoord1d(fTexCoords[jt][it]);
1959 glVertex3d(xMin, pos, zMin);
1960 glTexCoord1d(fTexCoords[jt + 1][it]);
1961 glVertex3d(xMin, pos, zMax);
1962 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
1963 glVertex3d(xMax, pos, zMax);
1964 glTexCoord1d(fTexCoords[jt][it + 1]);
1965 glVertex3d(xMax, pos, zMin);
1966 glEnd();
1967 }
1968 }
1969 break;
1970 case kYOZ:
1971 pos *= xScale;
1972 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
1973 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
1974 const Double_t yMin = yA->GetBinCenter(i) * yScale;
1975 const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
1976 const Double_t zMin = zA->GetBinCenter(j) * zScale;
1977 const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
1978 glBegin(GL_POLYGON);
1979 glTexCoord1d(fTexCoords[jt][it]);
1980 glVertex3d(pos, yMin, zMin);
1981 glTexCoord1d(fTexCoords[jt][it + 1]);
1982 glVertex3d(pos, yMax, zMin);
1983 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
1984 glVertex3d(pos, yMax, zMax);
1985 glTexCoord1d(fTexCoords[jt + 1][it]);
1986 glVertex3d(pos, yMin, zMax);
1987 glEnd();
1988 }
1989 }
1990 break;
1991 case kXOY:
1992 pos *= zScale;
1993 for (Int_t j = fCoord->GetFirstXBin(), jt = 0, ej = fCoord->GetLastXBin(); j < ej; ++j, ++jt) {
1994 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
1995 const Double_t xMin = xA->GetBinCenter(j) * xScale;
1996 const Double_t xMax = xA->GetBinCenter(j + 1) * xScale;
1997 const Double_t yMin = yA->GetBinCenter(i) * yScale;
1998 const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
1999 glBegin(GL_POLYGON);
2000 glTexCoord1d(fTexCoords[jt + 1][it]);
2001 glVertex3d(xMax, yMin, pos);
2002 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
2003 glVertex3d(xMax, yMax, pos);
2004 glTexCoord1d(fTexCoords[jt][it + 1]);
2005 glVertex3d(xMin, yMax, pos);
2006 glTexCoord1d(fTexCoords[jt][it]);
2007 glVertex3d(xMin, yMin, pos);
2008 glEnd();
2009 }
2010 }
2011 break;
2012 }
2013}
2014
2015namespace {
2016
2017////////////////////////////////////////////////////////////////////////////////
2018
2019void DrawBoxOutline(Double_t xMin, Double_t xMax, Double_t yMin,
2020 Double_t yMax, Double_t zMin, Double_t zMax)
2021{
2022 glBegin(GL_LINE_LOOP);
2023 glVertex3d(xMin, yMin, zMin);
2024 glVertex3d(xMax, yMin, zMin);
2025 glVertex3d(xMax, yMax, zMin);
2026 glVertex3d(xMin, yMax, zMin);
2027 glEnd();
2028
2029 glBegin(GL_LINE_LOOP);
2030 glVertex3d(xMin, yMin, zMax);
2031 glVertex3d(xMax, yMin, zMax);
2032 glVertex3d(xMax, yMax, zMax);
2033 glVertex3d(xMin, yMax, zMax);
2034 glEnd();
2035
2036 glBegin(GL_LINES);
2037 glVertex3d(xMin, yMin, zMin);
2038 glVertex3d(xMin, yMin, zMax);
2039 glVertex3d(xMax, yMin, zMin);
2040 glVertex3d(xMax, yMin, zMax);
2041 glVertex3d(xMax, yMax, zMin);
2042 glVertex3d(xMax, yMax, zMax);
2043 glVertex3d(xMin, yMax, zMin);
2044 glVertex3d(xMin, yMax, zMax);
2045 glEnd();
2046}
2047
2048}
2049
2050////////////////////////////////////////////////////////////////////////////////
2051/// Draw slice frame.
2052
2054{
2055 glColor3d(1., 0., 0.);
2056 const TGLVertex3 *box = fBox->Get3DBox();
2057
2058 switch (fAxisType) {
2059 case kXOZ:
2060 DrawBoxOutline(box[0].X(), box[1].X(),
2062 fAxis->GetBinUpEdge(up - 1) * fCoord->GetYScale(),
2063 box[0].Z(), box[4].Z());
2064 break;
2065 case kYOZ:
2066 DrawBoxOutline(fAxis->GetBinLowEdge(low) * fCoord->GetXScale(),
2067 fAxis->GetBinUpEdge(up - 1) * fCoord->GetXScale(),
2068 box[0].Y(), box[2].Y(),
2069 box[0].Z(), box[4].Z());
2070 break;
2071 case kXOY:
2072 DrawBoxOutline(box[0].X(), box[1].X(),
2073 box[0].Y(), box[2].Y(),
2075 fAxis->GetBinUpEdge(up - 1) * fCoord->GetZScale());
2076 break;
2077 }
2078}
2079
2080namespace Rgl {
2081
2082////////////////////////////////////////////////////////////////////////////////
2083
2085 : fPainter(painter)
2086{
2088 const Double_t center[] = {(box[0].X() + box[1].X()) / 2,
2089 (box[0].Y() + box[2].Y()) / 2,
2090 (box[0].Z() + box[4].Z()) / 2};
2091
2093 glTranslated(-center[0], -center[1], -center[2]);
2094}
2095
2096////////////////////////////////////////////////////////////////////////////////
2097
2099{
2101}
2102
2103namespace
2104{
2105
2106const Double_t lr = 0.85;
2107const Double_t rr = 0.9;
2108
2109}
2110
2111////////////////////////////////////////////////////////////////////////////////
2112///Draw. Palette.
2113
2114void DrawPalette(const TGLPlotCamera * camera, const TGLLevelPalette & palette)
2115{
2116 const TGLDisableGuard light(GL_LIGHTING);
2117 const TGLDisableGuard depth(GL_DEPTH_TEST);
2118 const TGLEnableGuard blend(GL_BLEND);
2119
2120 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2121
2122 glMatrixMode(GL_PROJECTION);
2123 glLoadIdentity();
2124 glOrtho(0, camera->GetWidth(), 0, camera->GetHeight(), -1., 1.);
2125
2126 glMatrixMode(GL_MODELVIEW);
2127 glLoadIdentity();
2128
2129 const Double_t leftX = camera->GetWidth() * lr;
2130 const Double_t rightX = camera->GetWidth() * rr;
2131 const Double_t margin = 0.1 * camera->GetHeight();
2132 const Double_t h = (camera->GetHeight() * 0.8) / palette.GetPaletteSize();
2133
2134 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2135 glBegin(GL_POLYGON);
2136 const UChar_t * color = palette.GetColour(i);
2137 glColor4ub(color[0], color[1], color[2], 150);
2138 glVertex2d(leftX, margin + i * h);
2139 glVertex2d(rightX, margin + i * h);
2140 glVertex2d(rightX, margin + (i + 1) * h);
2141 glVertex2d(leftX, margin + (i + 1) * h);
2142 glEnd();
2143 }
2144
2145 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
2146 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
2147 glColor4d(0., 0., 0., 0.5);
2148
2149 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2150 glBegin(GL_LINE_LOOP);
2151 glVertex2d(leftX, margin + i * h);
2152 glVertex2d(rightX, margin + i * h);
2153 glVertex2d(rightX, margin + (i + 1) * h);
2154 glVertex2d(leftX, margin + (i + 1) * h);
2155 glEnd();
2156 }
2157
2158}
2159
2160////////////////////////////////////////////////////////////////////////////////
2161///Draw. Palette.
2162
2163void DrawPalette(const TGLPlotCamera * camera, const TGLLevelPalette & palette,
2164 const std::vector<Double_t> & levels)
2165{
2166 const TGLDisableGuard light(GL_LIGHTING);
2167 const TGLDisableGuard depth(GL_DEPTH_TEST);
2168 const TGLEnableGuard blend(GL_BLEND);
2169
2170 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2171
2172 glMatrixMode(GL_PROJECTION);
2173 glLoadIdentity();
2174 glOrtho(0, camera->GetWidth(), 0, camera->GetHeight(), -1., 1.);
2175
2176 glMatrixMode(GL_MODELVIEW);
2177 glLoadIdentity();
2178
2179 const Double_t leftX = camera->GetWidth() * lr;
2180 const Double_t rightX = camera->GetWidth() * rr;
2181 const Double_t margin = 0.1 * camera->GetHeight();
2182 const Double_t h = (camera->GetHeight() * 0.8);
2183 const Double_t range = levels.back() - levels.front();
2184
2185 const UChar_t opacity = 200;
2186
2187 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2188 const Double_t yMin = margin + (levels[i] - levels.front()) / range * h;
2189 const Double_t yMax = margin + (levels[i + 1] - levels.front()) / range * h;
2190 glBegin(GL_POLYGON);
2191 const UChar_t * color = palette.GetColour(i);
2192 glColor4ub(color[0], color[1], color[2], opacity);
2193 glVertex2d(leftX, yMin);
2194 glVertex2d(rightX, yMin);
2195 glVertex2d(rightX, yMax);
2196 glVertex2d(leftX, yMax);
2197 glEnd();
2198 }
2199
2200 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
2201 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
2202 glColor4d(0., 0., 0., 0.5);
2203
2204 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2205 const Double_t yMin = (levels[i] - levels.front()) / range * h;
2206 const Double_t yMax = (levels[i + 1] - levels.front()) / range * h;
2207
2208 glBegin(GL_LINE_LOOP);
2209 glVertex2d(leftX, margin + yMin);
2210 glVertex2d(rightX, margin + yMin);
2211 glVertex2d(rightX, margin + yMax);
2212 glVertex2d(leftX, margin + yMax);
2213 glEnd();
2214 }
2215
2216}
2217
2218////////////////////////////////////////////////////////////////////////////////
2219
2220void DrawPaletteAxis(const TGLPlotCamera * camera, const Range_t & minMax, Bool_t logZ)
2221{
2222 UInt_t pixelW = camera->GetWidth();
2223 UInt_t pixelH = camera->GetHeight();
2224
2227 if (scale > 1.) {
2228 pixelW = UInt_t(pixelW / scale);
2229 pixelH = UInt_t(pixelH / scale);
2230 }
2231
2232 const Double_t x = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw() + rr * pixelW));
2233 const Double_t yMin = gPad->AbsPixeltoY(Int_t(gPad->GetWh() - (pixelH * 0.1
2234 + gPad->GetYlowNDC() * gPad->GetWh())));
2235 const Double_t yMax = gPad->AbsPixeltoY(Int_t(gPad->GetWh() - (pixelH * 0.9
2236 + gPad->GetYlowNDC() * gPad->GetWh())));
2237
2238 Double_t zMin = minMax.first;
2239 Double_t zMax = minMax.second;
2240
2241 if (logZ) {
2242 zMin = TMath::Power(10, zMin);
2243 zMax = TMath::Power(10, zMax);
2244 }
2245
2246 //Now, some stupid magic, to force ROOT's painting machine work as I want, not as it wants.
2247 const Bool_t logX = gPad->GetLogx();
2248 gPad->SetLogx(kFALSE);
2249 const Bool_t logY = gPad->GetLogy();
2250 gPad->SetLogy(kFALSE);
2251
2252 TGaxis axisPainter(x, yMin, x, yMax, zMin, zMax, 510, logZ ? "G" : "");
2253 axisPainter.Paint();
2254
2255 gPad->SetLogx(logX);
2256 gPad->SetLogy(logY);
2257}
2258
2259//Constant for TGLH2PolyPainter.
2261
2262}
2263
#define GL_TRUE
Definition GL_glu.h:262
#define GL_LINES
Definition GL_glu.h:284
unsigned char GLboolean
Definition GL_glu.h:267
#define GL_FALSE
Definition GL_glu.h:261
#define GL_POLYGON
Definition GL_glu.h:292
#define GL_LINE_LOOP
Definition GL_glu.h:285
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
bool Bool_t
Definition RtypesCore.h:63
unsigned short UShort_t
Definition RtypesCore.h:40
int Int_t
Definition RtypesCore.h:45
unsigned char UChar_t
Definition RtypesCore.h:38
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:377
#define X(type, name)
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
EGLCoordType
Definition TGLUtil.h:43
@ kGLSpherical
Definition TGLUtil.h:47
@ kGLCylindrical
Definition TGLUtil.h:46
@ kGLPolar
Definition TGLUtil.h:45
@ kGLCartesian
Definition TGLUtil.h:44
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
R__EXTERN TStyle * gStyle
Definition TStyle.h:433
#define R__LOCKGUARD(mutex)
R__EXTERN TVirtualPS * gVirtualPS
Definition TVirtualPS.h:81
#define gPad
const TGLPlotPainter * fPainter
PlotTranslation(const TGLPlotPainter *painter)
Class to manage histogram axis.
Definition TAxis.h:31
Bool_t IsVariableBinSize() const
Definition TAxis.h:142
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:518
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:419
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:469
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:540
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:528
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:458
virtual Int_t GetEntries() const
The color creation and management class.
Definition TColor.h:21
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition TF1.cxx:1441
A 3-Dim function with parameters.
Definition TF3.h:28
Used by plot-painters to determine the area of the plot that is cut away.
void MoveBox(Int_t px, Int_t py, Int_t axisID)
Move box cut along selected direction.
void AdjustBox()
Box cut is limited by plot's sizes.
Bool_t IsInCut(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax) const
Check, if box defined by xmin/xmax etc. is in cut.
Double_t fYLength
Rgl::Range_t fYRange
void DrawBox(Bool_t selectionPass, Int_t selected) const
Draw cut as a semi-transparent box.
void TurnOnOff()
Turn the box cut on/off.
Double_t fXLength
TPoint fMousePos
Bool_t fActive
const TGLPlotBox *const fPlotBox
void StartMovement(Int_t px, Int_t py)
Start cut's movement.
TGLVertex3 fCenter
Double_t fFactor
Double_t fZLength
Rgl::Range_t fZRange
virtual ~TGLBoxCut()
Destructor.
void SetActive(Bool_t a)
Turn the box cut on/off.
void ResetBoxGeometry()
Set geometry using plot's back box.
TGLBoxCut(const TGLPlotBox *plotBox)
Constructor.
Rgl::Range_t fXRange
const UChar_t * GetColour(Double_t z) const
Get color.
Definition TGLUtil.cxx:4300
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition TGLUtil.cxx:4263
void DisableTexture() const
Disable 1D texture.
Definition TGLUtil.cxx:4254
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition TGLUtil.cxx:4271
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition TGLUtil.cxx:4170
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition TGLUtil.cxx:4235
static void CloseEmbeddedPS()
this function used by gl-in-pad Restore the gVirtualPS output stream
static void StartEmbeddedPS()
this function used by gl-in-pad
Implementation of a box around a histogram/function for plot-painters.
Definition TGLPlotBox.h:26
Int_t FindFrontPoint() const
Convert 3d points into window coordinate system and find the nearest.
const TGLVertex3 * Get3DBox() const
Get 3D box.
const TGLVertex3 * Get2DBox() const
Get 2D box.
void SetFrameColor(const TColor *color)
Back box color.
Int_t GetFrontPoint() const
The nearest point.
Camera for TGLPlotPainter and sub-classes.
Int_t GetY() const
viewport[1]
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
Int_t GetX() const
viewport[0]
void SetCamera() const
Viewport and projection.
Int_t GetWidth() const
viewport[2]
Int_t GetHeight() const
viewport[3]
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
Double_t GetZLength() const
Z length.
void SetXLog(Bool_t xLog)
If log changed, sections must be reset, set fModified.
Bool_t SetRanges(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges.
Double_t GetYScale() const
const Rgl::Range_t & GetXRangeScaled() const
Scaled range.
Rgl::BinRange_t fZBins
const Rgl::BinRange_t & GetZBins() const
Z bins range.
Rgl::Range_t fZRangeScaled
Bool_t GetXLog() const
Get X log.
Int_t GetFirstXBin() const
const Rgl::BinRange_t & GetXBins() const
X bins range.
Int_t GetFirstYBin() const
const Rgl::Range_t & GetZRange() const
Z range.
virtual ~TGLPlotCoordinates()
Destructor.
EGLCoordType fCoordType
Bool_t SetRangesPolar(const TH1 *hist)
Set bin ranges, ranges, etc.
const Rgl::Range_t & GetYRangeScaled() const
Scaled range.
Bool_t SetRangesCartesian(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges, etc.
void SetCoordType(EGLCoordType type)
If coord type was changed, plot must reset sections (if any), set fModified.
void ResetModified()
Reset modified.
TGLPlotCoordinates()
Constructor.
Bool_t SetRangesCylindrical(const TH1 *hist)
Set ranges cylindrical.
Bool_t GetYLog() const
Get Y log.
Bool_t GetZLog() const
Get Z log.
Bool_t Modified() const
Modified.
Double_t GetXScale() const
Double_t GetZScale() const
Int_t GetLastZBin() const
Int_t GetNXBins() const
Number of X bins.
Int_t GetFirstZBin() const
const Rgl::Range_t & GetZRangeScaled() const
Scaled range.
const Rgl::Range_t & GetYRange() const
Y range.
Rgl::BinRange_t fXBins
Double_t GetXLength() const
X length.
void SetZLog(Bool_t zLog)
If log changed, sections must be reset, set fModified.
void SetYLog(Bool_t yLog)
If log changed, sections must be reset, set fModified.
Bool_t SetRangesSpherical(const TH1 *hist)
Set ranges spherical.
Rgl::BinRange_t fYBins
Int_t GetLastYBin() const
const Rgl::Range_t & GetXRange() const
X range.
Int_t GetNYBins() const
Number of Y bins.
Int_t GetLastXBin() const
Rgl::Range_t fYRangeScaled
EGLCoordType GetCoordType() const
Get coordinates type.
Rgl::Range_t fXRangeScaled
const Rgl::BinRange_t & GetYBins() const
Y bins range.
Int_t GetNZBins() const
Number of Z bins.
Double_t GetYLength() const
Y length.
Double_t GetFactor() const
Get factor.
Base class for plot-painters that provide GL rendering of various 2D and 3D histograms,...
void InvalidateSelection()
Selection must be updated.
void DrawSections() const
Draw sections (if any).
TGLPlotPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord, Bool_t xoySelectable, Bool_t xozSelectable, Bool_t yozSelectable)
TGLPlotPainter's ctor.
std::vector< Double_t > fZLevels
virtual void SetFrameColor(const TColor *frameColor)
Set plot's back box color.
TGLSelectionBuffer fSelection
Double_t fXOYSectionPos
void RestoreModelviewMatrix() const
virtual void DrawPaletteAxis() const
Draw. Palette. Axis.
const TColor * fPadColor
void SetPadColor(const TColor *color)
Used in a pad.
const TColor * GetPadColor() const
Get pad color.
Double_t fXOZSectionPos
virtual void DrawPlot() const =0
void PrintPlot() const
Generate PS using gl2ps.
virtual void InitGL() const =0
TGLPlotCoordinates * fCoord
void Paint() override
Draw lego/surf/whatever you can.
virtual void DrawSectionXOY() const =0
TGLPlotBox fBackBox
Bool_t PlotSelected(Int_t px, Int_t py) override
Read color buffer content to find selected object.
void SaveProjectionMatrix() const
virtual void DrawSectionYOZ() const =0
void SaveModelviewMatrix() const
void MoveSection(Int_t px, Int_t py)
Create dynamic profile using selected plane.
TGLPlotCamera * fCamera
virtual void DeInitGL() const =0
void RestoreProjectionMatrix() const
virtual void ClearBuffers() const
Double_t fYOZSectionPos
virtual void DrawSectionXOZ() const =0
const UChar_t * GetPixelColor(Int_t px, Int_t py) const
Get pixel color.
Definition TGLUtil.cxx:2835
void ReadColorBuffer(Int_t width, Int_t height)
Read color buffer.
Definition TGLUtil.cxx:2811
A slice of a TH3.
void FindMinMax(Int_t sliceBegin, Int_t sliceEnd) const
Find minimum and maximum for slice.
Rgl::Range_t fMinMax
void DrawSliceFrame(Int_t low, Int_t up) const
Draw slice frame.
const TH3 * fHist
Bool_t PreparePalette() const
Initialize color palette.
const TAxis * fAxis
ESliceAxis fAxisType
const TGLPlotCoordinates * fCoord
void PrepareTexCoords(Double_t pos, Int_t sliceBegin, Int_t sliceEnd) const
Prepare TexCoords.
void DrawSlice(Double_t pos) const
Draw slice.
TGLLevelPalette fPalette
TGLTH3Slice(const TString &sliceName, const TH3 *hist, const TGLPlotCoordinates *coord, const TGLPlotBox *box, ESliceAxis axis)
Constructor.
void SetSliceWidth(Int_t width=1)
Set Slice width.
const TGLPlotBox * fBox
void DrawSliceTextured(Double_t pos) const
Draw slice textured.
const TF3 * fF3
TGL2DArray< Double_t > fTexCoords
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition TGLUtil.cxx:1582
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition TGLUtil.cxx:1852
3 component (x/y/z) vector class.
Definition TGLUtil.h:248
3 component (x/y/z) vertex class.
Definition TGLUtil.h:84
Double_t X() const
Definition TGLUtil.h:119
Double_t Z() const
Definition TGLUtil.h:123
Double_t Y() const
Definition TGLUtil.h:121
The axis painter class.
Definition TGaxis.h:24
void Paint(Option_t *chopt="") override
Draw this axis with its current attributes.
Definition TGaxis.cxx:986
@ kClipFrame
Clip to the frame boundary.
Definition TGraph.h:76
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
TAxis * GetZaxis()
Definition TH1.h:326
virtual Double_t GetMinimumStored() const
Definition TH1.h:293
virtual Double_t GetNormFactor() const
Definition TH1.h:301
TAxis * GetXaxis()
Definition TH1.h:324
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
Definition TH1.cxx:4929
TAxis * GetYaxis()
Definition TH1.h:325
virtual Double_t GetCellError(Int_t binx, Int_t biny) const
Definition TH1.h:434
virtual Double_t GetMaximumStored() const
Definition TH1.h:289
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5029
2D Histogram with Polygonal Bins
Definition TH2Poly.h:66
TList * GetBins()
Returns the TList of all bins in the histogram.
Definition TH2Poly.h:101
Double_t GetMinimum() const
Returns the minimum value of the histogram.
Definition TH2Poly.cxx:964
Double_t GetMaximum() const
Returns the maximum value of the histogram.
Definition TH2Poly.cxx:916
The 3-D histogram classes derived from the 1-D histogram classes.
Definition TH3.h:31
Double_t GetBinContent(Int_t binx, Int_t biny, Int_t binz) const override
Definition TH3.h:101
A doubly linked list.
Definition TList.h:38
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
SCoord_t fY
Definition TPoint.h:36
SCoord_t fX
Definition TPoint.h:35
Basic string class.
Definition TString.h:139
Bool_t GetHistMinimumZero() const
Definition TStyle.h:235
Double_t GetHistTopMargin() const
Definition TStyle.h:236
Int_t GetNumberContours() const
Definition TStyle.h:239
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
void DrawQuadFilled(const TGLVertex3 &v0, const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVector3 &normal)
Draw quad face.
Definition TGLUtil.cxx:2962
const Float_t gNullEmission[]
Definition TGLUtil.cxx:2856
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition TGLUtil.cxx:2900
const Float_t gBlueEmission[]
Definition TGLUtil.cxx:2852
void DrawPalette(const TGLPlotCamera *camera, const TGLLevelPalette &palette)
Draw. Palette.
void DrawPaletteAxis(const TGLPlotCamera *camera, const Range_t &minMax, Bool_t logZ)
std::pair< Int_t, Int_t > BinRange_t
Definition TGLUtil.h:1201
std::pair< Double_t, Double_t > Range_t
Definition TGLUtil.h:1202
void DrawBoxFront(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax, Int_t fp)
Draws lego's bar as a 3d box.
Definition TGLUtil.cxx:3016
const Double_t gH2PolyScaleXY
Int_t ColorToObjectID(const UChar_t *color, Bool_t highColor)
Definition TGLUtil.cxx:2926
void DrawAxes(Int_t frontPoint, const Int_t *viewport, const TGLVertex3 *box2D, const TGLPlotCoordinates *plotCoord, TAxis *xAxis, TAxis *yAxis, TAxis *zAxis)
Using front point, find, where to draw axes and which labels to use for them gVirtualX->SelectWindow(...
Definition TGLUtil.cxx:3768
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:721
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:762
static void output()