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
45
46////////////////////////////////////////////////////////////////////////////////
47///TGLPlotPainter's ctor.
48
51 : fPadColor(nullptr),
52 fPhysicalShapeColor(nullptr),
53 fPadPhi(45.),
54 fPadTheta(0.),
55 fHist(hist),
56 fXAxis(hist->GetXaxis()),
57 fYAxis(hist->GetYaxis()),
58 fZAxis(hist->GetZaxis()),
59 fCoord(coord),
60 fCamera(camera),
61 fUpdateSelection(kTRUE),
62 fSelectionPass(kFALSE),
63 fSelectedPart(0),
64 fXOZSectionPos(0.),
65 fYOZSectionPos(0.),
66 fXOYSectionPos(0.),
67 fBackBox(xoy, xoz, yoz),
68 fBoxCut(&fBackBox),
69 fHighColor(kFALSE),
70 fSelectionBase(kTrueColorSelectionBase),
71 fDrawPalette(kFALSE),
72 fDrawAxes(kTRUE)
73{
74 if (gPad) {
75 fPadPhi = gPad->GetPhi();
76 fPadTheta = gPad->GetTheta();
77 }
78}
79
80////////////////////////////////////////////////////////////////////////////////
81///TGLPlotPainter's ctor.
82
84 : fPadColor(nullptr),
85 fPhysicalShapeColor(nullptr),
86 fPadPhi(45.),
87 fPadTheta(0.),
88 fHist(nullptr),
89 fXAxis(data->GetXAxis()),
90 fYAxis(data->GetYAxis()),
91 fZAxis(data->GetZAxis()),
92 fCoord(coord),
93 fCamera(camera),
94 fUpdateSelection(kTRUE),
95 fSelectionPass(kFALSE),
96 fSelectedPart(0),
97 fXOZSectionPos(0.),
98 fYOZSectionPos(0.),
99 fXOYSectionPos(0.),
100 fBackBox(kFALSE, kFALSE, kFALSE),
101 fBoxCut(&fBackBox),
102 fHighColor(kFALSE),
103 fSelectionBase(kTrueColorSelectionBase),
104 fDrawPalette(kFALSE),
105 fDrawAxes(kTRUE)
106{
107 if (gPad) {
108 fPadPhi = gPad->GetPhi();
109 fPadTheta = gPad->GetTheta();
110 }
111}
112
113////////////////////////////////////////////////////////////////////////////////
114///TGLPlotPainter's ctor.
115
117 : fPadColor(nullptr),
118 fPhysicalShapeColor(nullptr),
119 fPadPhi(45.),
120 fPadTheta(0.),
121 fHist(nullptr),
122 fXAxis(nullptr),
123 fYAxis(nullptr),
124 fZAxis(nullptr),
125 fCoord(nullptr),
126 fCamera(camera),
127 fUpdateSelection(kTRUE),
128 fSelectionPass(kFALSE),
129 fSelectedPart(0),
130 fXOZSectionPos(0.),
131 fYOZSectionPos(0.),
132 fXOYSectionPos(0.),
133 fBackBox(kFALSE, kFALSE, kFALSE),
134 fBoxCut(&fBackBox),
135 fHighColor(kFALSE),
136 fSelectionBase(kTrueColorSelectionBase),
137 fDrawPalette(kFALSE),
138 fDrawAxes(kTRUE)
139{
140 if (gPad) {
141 fPadPhi = gPad->GetPhi();
142 fPadTheta = gPad->GetTheta();
143 }
144}
145
146////////////////////////////////////////////////////////////////////////////////
147///Draw lego/surf/whatever you can.
148
150{
152
155
156 int vp[4] = {};
158
159 //GL pad painter does not use depth test,
160 //so, switch it on now.
161 glDepthMask(GL_TRUE);//[0
162 //
163 InitGL();
164 //Save material/light properties in a stack.
166
167 //Save projection and modelview matrix, used by glpad.
170
171 //glOrtho etc.
173 //
175 //Set light.
176 const Float_t pos[] = {0.f, 0.f, 0.f, 1.f};
178 //Set transformation - shift and rotate the scene.
181
182 if (gVirtualPS)
183 PrintPlot();
184
185 DrawPlot();
186 //Restore material properties from stack.
187 glPopAttrib();
188 //
189 DeInitGL();//Disable/enable, what concrete plot painter enabled/disabled
190
191 //Restore projection and modelview matrices.
194
195 glViewport(vp[0], vp[1], vp[2], vp[3]);
196 //GL pad painter does not use depth test, so,
197 //switch it off now.
199
201
202 Bool_t old = gPad->TestBit(TGraph::kClipFrame);
203 if (!old)
204 gPad->SetBit(TGraph::kClipFrame);
205
206 //Viewport on retina is bigger than real pixel coordinates in
207 //a pad, scale it back.
210 if (scale < 1.f)//Just ignore this.
211 scale = 1.f;
212
213 const Int_t viewport[] = {Int_t(fCamera->GetX() / scale),
214 Int_t(fCamera->GetY() / scale),
218 if (fDrawPalette)
220
221 if (!old)
222 gPad->ResetBit(TGraph::kClipFrame);
223 } else if(fDrawPalette)
225
226}
227
228////////////////////////////////////////////////////////////////////////////////
229/// Generate PS using gl2ps
230
232{
234
235 FILE *output = fopen(gVirtualPS->GetName(), "a");
236 if (!output) {
237 Error("TGLPlotPainter::PrintPlot", "Could not (re)open ps file for GL output");
238 //As soon as we started embedded ps, we have to close it before exiting.
240 return;
241 }
242
245 Int_t bufsize = 0;
246 Int_t state = GL2PS_OVERFLOW;
251 0;
252
253 while (state == GL2PS_OVERFLOW) {
254 bufsize += 1024*1024;
255 gl2psBeginPage ("ROOT Scene Graph", "ROOT", nullptr,
257 GL_RGBA, 0, nullptr,0, 0, 0,
258 bufsize, output, nullptr);
259 DrawPlot();
260 state = gl2psEndPage();
261 }
262
263 fclose(output);
265 glFlush();
266}
267
268////////////////////////////////////////////////////////////////////////////////
269///Read color buffer content to find selected object
270
272{
273 if (fUpdateSelection) {
274 //Save projection and modelview matrix, used by glpad.
276 glPushMatrix();
278 glPushMatrix();
279
282
284 glClearColor(0.f, 0.f, 0.f, 0.f);
286
288 DrawPlot();
289
290 glFinish();
291 //fSelection.ReadColorBuffer(fCamera->GetWidth(), fCamera->GetHeight());
292
296
299
300 //Restore projection and modelview matrices.
302 glPopMatrix();
304 glPopMatrix();
305 }
306
307 px -= Int_t(gPad->GetXlowNDC() * gPad->GetWw());
308 py -= Int_t(gPad->GetWh() - gPad->YtoAbsPixel(gPad->GetY1()));
309
310 //Pixel coords can be affected by scaling factor on retina displays.
313
314 if (scale > 1.f) {
315 px *= scale;
316 py *= scale;
317 }
318
319 //py = fCamera->GetHeight() - py;
320 //Y is a number of a row, x - column.
321 std::swap(px, py);
323
324 if (newSelected != fSelectedPart) {
325 //New object was selected (or surface deselected) - re-paint.
327 gPad->Update();
328 }
329
330 return fSelectedPart ? kTRUE : kFALSE;
331}
332
333////////////////////////////////////////////////////////////////////////////////
334///Used in a pad.
335
337{
338 fPadColor = c;
339}
340
341////////////////////////////////////////////////////////////////////////////////
342///Set plot's back box color.
343
348
349////////////////////////////////////////////////////////////////////////////////
350///Selection must be updated.
351
356
357////////////////////////////////////////////////////////////////////////////////
358///Get pad color.
359
361{
362 return fPadColor;
363}
364
365////////////////////////////////////////////////////////////////////////////////
366///Create dynamic profile using selected plane
367
369{
370 //Coordinates are expected to be fixed for retina!
371
372 const TGLVertex3 *frame = fBackBox.Get3DBox();
374
375 if (fSelectedPart == 1) {
376 fXOYSectionPos = frame[0].Z();
377 fSelectedPart = 6;
378 } else if (fSelectedPart == 2) {
379 if (frontPoint == 2) {
380 fXOZSectionPos = frame[0].Y();
381 fSelectedPart = 4;
382 } else if (!frontPoint) {
383 fXOZSectionPos = frame[2].Y();
384 fSelectedPart = 4;
385 } else if (frontPoint == 1) {
386 fYOZSectionPos = frame[0].X();
387 fSelectedPart = 5;
388 } else if (frontPoint == 3) {
389 fYOZSectionPos = frame[1].X();
390 fSelectedPart = 5;
391 }
392 } else if (fSelectedPart == 3) {
393 if (frontPoint == 2) {
394 fYOZSectionPos = frame[0].X();
395 fSelectedPart = 5;
396 } else if (!frontPoint) {
397 fYOZSectionPos = frame[1].X();
398 fSelectedPart = 5;
399 } else if (frontPoint == 1) {
400 fXOZSectionPos = frame[2].Y();
401 fSelectedPart = 4;
402 } else if (frontPoint == 3) {
403 fXOZSectionPos = frame[0].Y();
404 fSelectedPart = 4;
405 }
406 }
407
408 Double_t mv[16] = {0.};
410 Double_t pr[16] = {0.};
412 Int_t vp[4] = {0};
414 Double_t winVertex[3] = {0.};
415
416 if (fSelectedPart == 6)
417 gluProject(0., 0., fXOYSectionPos, mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
418 else
420 fSelectedPart == 4 ? fXOZSectionPos : 0.,
421 0., mv, pr, vp,
422 &winVertex[0], &winVertex[1], &winVertex[2]);
423 winVertex[0] += px - fMousePosition.fX;
424 winVertex[1] += py - fMousePosition.fY;
425 Double_t newPoint[3] = {0.};
427 newPoint, newPoint + 1, newPoint + 2);
428
429 if (fSelectedPart == 4)
431 else if (fSelectedPart == 5)
433 else
435}
436
437////////////////////////////////////////////////////////////////////////////////
438///Draw sections (if any).
439
441{
442 const TGLVertex3 *frame = fBackBox.Get3DBox();
443
444 if (fXOZSectionPos > frame[0].Y()) {
445 if (fXOZSectionPos > frame[2].Y())
446 fXOZSectionPos = frame[2].Y();
447 const TGLVertex3 v1(frame[0].X(), fXOZSectionPos, frame[0].Z());
448 const TGLVertex3 v2(frame[4].X(), fXOZSectionPos, frame[4].Z());
449 const TGLVertex3 v3(frame[5].X(), fXOZSectionPos, frame[5].Z());
450 const TGLVertex3 v4(frame[1].X(), fXOZSectionPos, frame[1].Z());
451
452 if (fSelectionPass)
454 else if (fSelectedPart == 4)
456
458 glPolygonOffset(1.f, 1.f);
459 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 1., 0.));
461 //Zlevels here.
462 if (!fSelectionPass) {
463 if (fSelectedPart == 4)
471 //Draw z-levels
473 const UShort_t stipple = 0x5555;
475
476 glColor3d(0., 0., 0.);
477 glBegin(GL_LINES);
478 for (UInt_t i = 0; i < fZLevels.size(); ++i) {
481 }
482 glEnd();
484 }
485 }
486
487 if (fYOZSectionPos > frame[0].X()) {
488 if (fYOZSectionPos > frame[1].X())
489 fYOZSectionPos = frame[1].X();
490 TGLVertex3 v1(fYOZSectionPos, frame[0].Y(), frame[0].Z());
491 TGLVertex3 v2(fYOZSectionPos, frame[3].Y(), frame[3].Z());
492 TGLVertex3 v3(fYOZSectionPos, frame[7].Y(), frame[7].Z());
493 TGLVertex3 v4(fYOZSectionPos, frame[4].Y(), frame[4].Z());
494
495 if (fSelectionPass) {
497 } else if (fSelectedPart == 5)
499
501 glPolygonOffset(1.f, 1.f);
502 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(1., 0., 0.));
504
505 if (!fSelectionPass) {
506 if (fSelectedPart == 5)
514 //Draw z-levels
516 glLineStipple(1, 0x5555);
517
518 glColor3d(0., 0., 0.);
519 glBegin(GL_LINES);
520 for (UInt_t i = 0; i < fZLevels.size(); ++i) {
523 }
524 glEnd();
526 }
527 }
528
529 if (fXOYSectionPos > frame[0].Z()) {
530 if (fXOYSectionPos > frame[4].Z())
531 fXOYSectionPos = frame[4].Z();
532 TGLVertex3 v1(frame[0].X(), frame[0].Y(), fXOYSectionPos);
533 TGLVertex3 v2(frame[1].X(), frame[1].Y(), fXOYSectionPos);
534 TGLVertex3 v3(frame[2].X(), frame[2].Y(), fXOYSectionPos);
535 TGLVertex3 v4(frame[3].X(), frame[3].Y(), fXOYSectionPos);
536
537 if (fSelectionPass) {
539 } else if (fSelectedPart == 6)
541
543 glPolygonOffset(1.f, 1.f);
544 //if (fSelectionPass || fSelectedPart == 6)
545 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 0., 1.));
547
548 if (!fSelectionPass) {
549 if (fSelectedPart == 6)
558 }
559 }
560}
561
562////////////////////////////////////////////////////////////////////////////////
563
565{
566/*
567 // Clear buffer.
568 Float_t rgb[3] = {1.f, 1.f, 1.f};
569 if (const TColor *color = GetPadColor())
570 color->GetRGB(rgb[0], rgb[1], rgb[2]);
571 glClearColor(rgb[0], rgb[1], rgb[2], 1.);
572 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
573 */
574}
575
576////////////////////////////////////////////////////////////////////////////////
577///Draw. Palette. Axis.
578
582
583////////////////////////////////////////////////////////////////////////////////
584
590
591////////////////////////////////////////////////////////////////////////////////
592
598
599////////////////////////////////////////////////////////////////////////////////
600
606
607////////////////////////////////////////////////////////////////////////////////
608
614
615/** \class TGLPlotCoordinates
616\ingroup opengl
617Helper class for plot-painters holding information about axis
618ranges, numbers of bins and flags if certain axis is logarithmic.
619*/
620
621
622////////////////////////////////////////////////////////////////////////////////
623///Constructor.
624
626 : fCoordType(kGLCartesian),
627 fXScale(1.),
628 fYScale(1.),
629 fZScale(1.),
630 fXLog(kFALSE),
631 fYLog(kFALSE),
632 fZLog(kFALSE),
633 fModified(kFALSE),
634 fFactor(1.)
635{
636}
637
638////////////////////////////////////////////////////////////////////////////////
639///Destructor.
640
644
645////////////////////////////////////////////////////////////////////////////////
646///If coord type was changed, plot must reset sections (if any),
647///set fModified.
648
656
657////////////////////////////////////////////////////////////////////////////////
658/// Get coordinates type.
659
664
665////////////////////////////////////////////////////////////////////////////////
666///If log changed, sections must be reset,
667///set fModified.
668
670{
671 if (fXLog != xLog) {
672 fXLog = xLog;
674 }
675}
676
677////////////////////////////////////////////////////////////////////////////////
678/// Get X log.
679
681{
682 return fXLog;
683}
684
685////////////////////////////////////////////////////////////////////////////////
686///If log changed, sections must be reset,
687///set fModified.
688
690{
691 if (fYLog != yLog) {
692 fYLog = yLog;
694 }
695}
696
697////////////////////////////////////////////////////////////////////////////////
698/// Get Y log.
699
701{
702 return fYLog;
703}
704
705////////////////////////////////////////////////////////////////////////////////
706///If log changed, sections must be reset,
707///set fModified.
708
710{
711 if (fZLog != zLog) {
712 fZLog = zLog;
714 }
715}
716
717////////////////////////////////////////////////////////////////////////////////
718/// Get Z log.
719
721{
722 return fZLog;
723}
724
725////////////////////////////////////////////////////////////////////////////////
726/// Reset modified.
727
729{
730 fModified = !fModified;//kFALSE;
731}
732
733////////////////////////////////////////////////////////////////////////////////
734/// Modified.
735
737{
738 return fModified;
739}
740
741////////////////////////////////////////////////////////////////////////////////
742///Set bin ranges, ranges.
743
745{
746 switch (fCoordType) {
747 case kGLPolar:
748 return SetRangesPolar(hist);
749 case kGLCylindrical:
750 return SetRangesCylindrical(hist);
751 case kGLSpherical:
752 return SetRangesSpherical(hist);
753 case kGLCartesian:
754 default:
755 return SetRangesCartesian(hist, errors, zBins);
756 }
757}
758
759////////////////////////////////////////////////////////////////////////////////
760///Number of X bins.
761
763{
764 return fXBins.second - fXBins.first + 1;
765}
766
767////////////////////////////////////////////////////////////////////////////////
768///Number of Y bins.
769
771{
772 return fYBins.second - fYBins.first + 1;
773}
774
775////////////////////////////////////////////////////////////////////////////////
776///Number of Z bins.
777
779{
780 return fZBins.second - fZBins.first + 1;
781}
782
783////////////////////////////////////////////////////////////////////////////////
784///X bins range.
785
787{
788 return fXBins;
789}
790
791////////////////////////////////////////////////////////////////////////////////
792///Y bins range.
793
795{
796 return fYBins;
797}
798
799////////////////////////////////////////////////////////////////////////////////
800///Z bins range.
801
803{
804 return fZBins;
805}
806
807////////////////////////////////////////////////////////////////////////////////
808///X range.
809
811{
812 return fXRange;
813}
814
815////////////////////////////////////////////////////////////////////////////////
816///X length.
817
819{
820 return fXRange.second - fXRange.first;
821}
822
823////////////////////////////////////////////////////////////////////////////////
824///Y range.
825
827{
828 return fYRange;
829}
830
831////////////////////////////////////////////////////////////////////////////////
832///Y length.
833
835{
836 return fYRange.second - fYRange.first;
837}
838
839
840////////////////////////////////////////////////////////////////////////////////
841///Z range.
842
844{
845 return fZRange;
846}
847
848////////////////////////////////////////////////////////////////////////////////
849///Z length.
850
852{
853 return fZRange.second - fZRange.first;
854}
855
856
857////////////////////////////////////////////////////////////////////////////////
858///Scaled range.
859
864
865////////////////////////////////////////////////////////////////////////////////
866///Scaled range.
867
872
873////////////////////////////////////////////////////////////////////////////////
874///Scaled range.
875
880
881////////////////////////////////////////////////////////////////////////////////
882/// Get factor.
883
885{
886 return fFactor;
887}
888
889namespace {
890
894 Double_t &factor, Bool_t errors);
895
897
898}
899
900////////////////////////////////////////////////////////////////////////////////
901///Set bin ranges, ranges, etc.
902
904{
907 if (!FindAxisRange(hist->GetXaxis(), fXLog, xBins, xRange)) {
908 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set X axis to log scale");
909 return kFALSE;
910 }
911
914 if (!FindAxisRange(hist->GetYaxis(), fYLog, yBins, yRange)) {
915 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set Y axis to log scale");
916 return kFALSE;
917 }
918
921 Double_t factor = 1.;
922
923 if (zAsBins) {
924 if (!FindAxisRange(hist->GetZaxis(), fZLog, zBins, zRange)) {
925 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set Z axis to log scale");
926 return kFALSE;
927 }
928 } else if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, errors)) {
929 Error("TGLPlotCoordinates::SetRangesCartesian",
930 "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
931 return kFALSE;
932 }
933
934 //Finds the maximum dimension and adjust scale coefficients
935 const Double_t x = xRange.second - xRange.first;
936 const Double_t y = yRange.second - yRange.first;
937 const Double_t z = zRange.second - zRange.first;
938
939 if (!x || !y || !z) {
940 Error("TGLPlotCoordinates::SetRangesCartesian", "Zero axis range.");
941 return kFALSE;
942 }
943
944 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
945 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
946 {
948 }
949
951 fFactor = factor;
952 /*
953 const Double_t maxDim = TMath::Max(TMath::Max(x, y), z);
954 fXScale = maxDim / x;
955 fYScale = maxDim / y;
956 fZScale = maxDim / z;
957 */
958 fXScale = 1. / x;
959 fYScale = 1. / y;
960 fZScale = 1. / z;
961
962 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
963 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
964 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
965
966 return kTRUE;
967}
968
969//
970////////////////////////////////////////////////////////////////////////////////
971///Set bin ranges, ranges, etc.
972
974{
977 FindAxisRange(hist->GetXaxis(), kFALSE, xBins, xRange);//kFALSE == never logarithmic.
978
981 FindAxisRange(hist->GetYaxis(), kFALSE, yBins, yRange);//kFALSE == never logarithmic.
982
985 Double_t factor = 1.;
986
987 if (!FindAxisRange(hist, fZLog, zRange))
988 return kFALSE;
989
990 //Finds the maximum dimension and adjust scale coefficients
991 const Double_t x = xRange.second - xRange.first;
992 const Double_t y = yRange.second - yRange.first;
993 const Double_t z = zRange.second - zRange.first;
994
995 if (!x || !y || !z) {
996 Error("TGLPlotCoordinates::SetRanges", "Zero axis range.");
997 return kFALSE;
998 }
999
1000 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
1001 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
1002 {
1003 fModified = kTRUE;
1004 }
1005
1007 fFactor = factor;
1008
1011 fZScale = 1. / z;
1012
1013 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
1014 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
1015 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
1016
1017 return kTRUE;
1018}
1019//
1020
1021////////////////////////////////////////////////////////////////////////////////
1022///Set bin ranges, ranges, etc.
1023
1025{
1028
1030
1033
1035
1038 Double_t factor = 1.;
1039
1041
1042 //Finds the maximum dimension and adjust scale coefficients
1043 const Double_t x = xRange.second - xRange.first;
1044 const Double_t y = yRange.second - yRange.first;
1045 const Double_t z = zRange.second - zRange.first;
1046
1047 if (!x || !y || !z) {
1048 Error("TGLPlotCoordinates::SetRangesCartesian", "Zero axis range.");
1049 return kFALSE;
1050 }
1051
1052 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
1053 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
1054 {
1055 fModified = kTRUE;
1056 }
1057
1059 fFactor = factor;
1060
1061/* const Double_t maxDim = TMath::Max(TMath::Max(x, y), z);
1062 fXScale = maxDim / x;
1063 fYScale = maxDim / y;
1064 fZScale = maxDim / z;*/
1065
1066 fXScale = 1. / x;
1067 fYScale = 1. / y;
1068 fZScale = 1. / z;
1069
1070 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
1071 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
1072 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
1073
1074 return kTRUE;
1075}
1076
1077////////////////////////////////////////////////////////////////////////////////
1078///Set bin ranges, ranges, etc.
1079
1081{
1084 const TAxis *xAxis = hist->GetXaxis();
1086 if (xBins.second - xBins.first + 1 > 360) {
1087 Error("TGLPlotCoordinates::SetRangesPolar", "To many PHI sectors");
1088 return kFALSE;
1089 }
1090
1093 const TAxis *yAxis = hist->GetYaxis();
1095
1097 Double_t factor = 1.;
1098 if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, kFALSE))
1099 {
1100 Error("TGLPlotCoordinates::SetRangesPolar",
1101 "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
1102 return kFALSE;
1103 }
1104
1105 const Double_t z = zRange.second - zRange.first;
1106 if (!z || !(phiRange.second - phiRange.first) || !(roRange.second - roRange.first)) {
1107 Error("TGLPlotCoordinates::SetRangesPolar", "Zero axis range.");
1108 return kFALSE;
1109 }
1110
1111 if (phiRange != fXRange || roRange != fYRange || zRange != fZRange ||
1112 xBins != fXBins || yBins != fYBins || fFactor != factor)
1113 {
1114 fModified = kTRUE;
1117 fZRange = zRange;
1118 fFactor = factor;
1119 }
1120
1121 //const Double_t maxDim = TMath::Max(2., z);
1122 fXScale = 0.5;//maxDim / 2.;
1123 fYScale = 0.5;//maxDim / 2.;
1124 fZScale = 1. / z;//maxDim / z;
1125 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
1126 fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
1127 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
1128
1129 return kTRUE;
1130}
1131
1132////////////////////////////////////////////////////////////////////////////////
1133/// Set ranges cylindrical.
1134
1136{
1139 const TAxis *xAxis = hist->GetXaxis();
1140 const TAxis *yAxis = hist->GetYaxis();
1141 Double_t factor = 1.;
1142
1144 if (xBins.second - xBins.first + 1 > 360) {
1145 Error("TGLPlotCoordinates::SetRangesCylindrical", "To many PHI sectors");
1146 return kFALSE;
1147 }
1149 Error("TGLPlotCoordinates::SetRangesCylindrical", "Cannot set Y axis to log scale");
1150 return kFALSE;
1151 }
1152 FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
1153
1154 const Double_t x = angleRange.second - angleRange.first;
1155 const Double_t y = heightRange.second - heightRange.first;
1156 const Double_t z = radiusRange.second - radiusRange.first;
1157
1158 if (!x || !y || !z) {
1159 Error("TGLPlotCoordinates::SetRangesCylindrical", "Zero axis range.");
1160 return kFALSE;
1161 }
1162
1163 if (angleRange != fXRange || heightRange != fYRange ||
1164 radiusRange != fZRange || xBins != fXBins ||
1165 yBins != fYBins || fFactor != factor)
1166 {
1167 fModified = kTRUE;
1171 fFactor = factor;
1172 }
1173
1174 // const Double_t maxDim = TMath::Max(2., y);
1175 fXScale = 0.5;//maxDim / 2.;
1176 fYScale = 1. / y;//maxDim / y;
1177 fZScale = 0.5;//maxDim / 2.;
1178 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
1179 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
1180 fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
1181
1182 return kTRUE;
1183}
1184
1185////////////////////////////////////////////////////////////////////////////////
1186/// Set ranges spherical.
1187
1189{
1193 if (xBins.second - xBins.first + 1 > 360) {
1194 Error("TGLPlotCoordinates::SetRangesSpherical", "To many PHI sectors");
1195 return kFALSE;
1196 }
1197
1201 if (yBins.second - yBins.first + 1 > 180) {
1202 Error("TGLPlotCoordinates::SetRangesSpherical", "To many THETA sectors");
1203 return kFALSE;
1204 }
1205
1207 Double_t factor = 1.;
1208 FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
1209
1210 if (xBins != fXBins || yBins != fYBins ||
1212 radiusRange != fZRange || fFactor != factor)
1213 {
1214 fModified = kTRUE;
1215 fXBins = xBins;
1216 fYBins = yBins;
1217 fXRange = phiRange;
1220 fFactor = factor;
1221 }
1222
1223 fXScale = 0.5;
1224 fYScale = 0.5;
1225 fZScale = 0.5;
1226 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
1227 fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
1228 fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
1229
1230 return kTRUE;
1231}
1232
1233namespace {
1234
1235////////////////////////////////////////////////////////////////////////////////
1236/// Find minimal bin width.
1237
1238Double_t FindMinBinWidth(const TAxis *axis)
1239{
1240 Int_t currBin = axis->GetFirst();
1242
1243 if (!axis->IsVariableBinSize())//equal bins
1244 return width;
1245
1246 ++currBin;
1247 //variable size bins
1248 for (const Int_t lastBin = axis->GetLast(); currBin <= lastBin; ++currBin)
1250
1251 return width;
1252}
1253
1254////////////////////////////////////////////////////////////////////////////////
1255///"Generic" function, can be used for X/Y/Z axis.
1256///[low edge of first ..... up edge of last]
1257///If log is true, at least up edge of last MUST be positive or function fails (1).
1258///If log is true and low edge is negative, try to find bin with positive low edge, bin number
1259///must be less or equal to last (2). If no such bin, function fails.
1260///When looking for a such bin, I'm trying to find value which is 0.01 of
1261///MINIMUM bin width (3) (if bins are equidimensional, first's bin width is OK).
1262///But even such lookup can fail, so, it's a stupid idea to have negative ranges
1263///and logarithmic scale :)
1264
1266{
1267 bins.first = axis->GetFirst(), bins.second = axis->GetLast();
1268 range.first = axis->GetBinLowEdge(bins.first), range.second = axis->GetBinUpEdge(bins.second);
1269
1270 if (log) {
1271 if (range.second <= 0.)
1272 return kFALSE;//(1)
1273
1274 range.second = TMath::Log10(range.second);
1275
1276 if (range.first <= 0.) {//(2)
1277 Int_t bin = axis->FindFixBin(FindMinBinWidth(axis) * 0.01);//(3)
1278 //Overflow or something stupid.
1279 if (bin > bins.second)
1280 return kFALSE;
1281
1282 if (axis->GetBinLowEdge(bin) <= 0.) {
1283 ++bin;
1284 if (bin > bins.second)//Again, something stupid.
1285 return kFALSE;
1286 }
1287
1288 bins.first = bin;
1289 range.first = axis->GetBinLowEdge(bin);
1290 }
1291
1292 range.first = TMath::Log10(range.first);
1293 }
1294
1295 return kTRUE;
1296}
1297
1298////////////////////////////////////////////////////////////////////////////////
1299///First, look through hist to find minimum and maximum values.
1300
1303 Double_t &factor, Bool_t errors)
1304{
1305 const Bool_t minimum = hist->GetMinimumStored() != -1111;
1306 const Bool_t maximum = hist->GetMaximumStored() != -1111;
1307 const Double_t margin = gStyle->GetHistTopMargin();
1308
1309 zRange.second = hist->GetBinContent(hist->GetBin(xBins.first, yBins.first)), zRange.first = zRange.second;
1310 Double_t summ = 0.;
1311
1312 for (Int_t i = xBins.first; i <= xBins.second; ++i) {
1313 for (Int_t j = yBins.first; j <= yBins.second; ++j) {
1314 Double_t val = hist->GetBinContent(hist->GetBin(i, j));
1315 if (val > 0. && errors)
1316 val = TMath::Max(val, val + hist->GetCellError(i, j));
1317 zRange.second = TMath::Max(val, zRange.second);
1318 zRange.first = TMath::Min(val, zRange.first);
1319 summ += val;
1320 }
1321 }
1322
1323 if (hist->GetMaximumStored() != -1111)
1324 zRange.second = hist->GetMaximumStored();
1325 if (hist->GetMinimumStored() != -1111)
1326 zRange.first = hist->GetMinimumStored();
1327
1328 if (logZ && zRange.second <= 0.)
1329 return kFALSE;//cannot setup logarithmic scale
1330
1331 if (zRange.first >= zRange.second)
1332 zRange.first = 0.001 * zRange.second;
1333
1334 factor = hist->GetNormFactor() > 0. ? hist->GetNormFactor() : summ;
1335 if (summ) factor /= summ;
1336 if (!factor) factor = 1.;
1337 if (factor < 0.)
1338 Warning("TGLPlotPainter::ExtractAxisZInfo",
1339 "Negative factor, negative ranges - possible incorrect behavior");
1340
1341 zRange.second *= factor;
1342 zRange.first *= factor;
1343
1344 if (logZ) {
1345 if (zRange.first <= 0.)
1346 zRange.first = TMath::Min(1., 0.001 * zRange.second);
1347 zRange.first = TMath::Log10(zRange.first);
1348 if (!minimum)
1349 zRange.first += TMath::Log10(0.5);
1350 zRange.second = TMath::Log10(zRange.second);
1351 if (!maximum)
1352 zRange.second += TMath::Log10(2*(0.9/0.95));//This magic numbers are from THistPainter.
1353 return kTRUE;
1354 }
1355
1356 if (!maximum)
1357 zRange.second += margin * (zRange.second - zRange.first);
1358 if (!minimum) {
1360 zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
1361 else
1362 zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
1363 zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
1364 }
1365
1366 return kTRUE;
1367}
1368
1369////////////////////////////////////////////////////////////////////////////////
1370///First, look through hist to find minimum and maximum values.
1371
1373{
1374 TList *bins = hist->GetBins();
1375 if (!bins || !bins->GetEntries()) {
1376 Error("FindAxisRange", "TH2Poly returned empty list of bins");
1377 return kFALSE;
1378 }
1379
1380 zRange.first = hist->GetMinimum();
1381 zRange.second = hist->GetMaximum();
1382
1383 if (zRange.first >= zRange.second)
1384 zRange.first = 0.001 * zRange.second;
1385
1386 if (logZ) {
1387 if (zRange.second < 1e-20) {
1388 Error("FindAxisRange", "Failed to switch Z axis to logarithmic scale");
1389 return kFALSE;
1390 }
1391
1392 if (zRange.first <= 0.)
1393 zRange.first = TMath::Min(1., 0.001 * zRange.second);
1394
1395 zRange.first = TMath::Log10(zRange.first);
1396 zRange.first += TMath::Log10(0.5);
1397 zRange.second = TMath::Log10(zRange.second);
1398 zRange.second += TMath::Log10(2 * (0.9 / 0.95));//These magic numbers come from THistPainter.
1399
1400 return kTRUE;
1401 }
1402
1403 const Double_t margin = gStyle->GetHistTopMargin();
1404 zRange.second += margin * (zRange.second - zRange.first);
1406 zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
1407 else
1408 zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
1409 zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
1410
1411 return kTRUE;
1412}
1413
1414}
1415
1416/** \class TGLBoxCut
1417\ingroup opengl
1418Used by plot-painters to determine the area of the plot that is cut away.
1419*/
1420
1421
1422////////////////////////////////////////////////////////////////////////////////
1423///Constructor.
1424
1426 : fXLength(0.),
1427 fYLength(0.),
1428 fZLength(0.),
1429 fPlotBox(box),
1430 fActive(kFALSE),
1431 fFactor(1.)
1432{
1433}
1434
1435////////////////////////////////////////////////////////////////////////////////
1436///Destructor.
1437
1441
1442////////////////////////////////////////////////////////////////////////////////
1443///Turn the box cut on/off.
1444///If it's on, it will be placed in front point of a plot.
1445
1447{
1448 fActive = !fActive;
1449
1450 if (fActive) {
1452 }
1453}
1454
1455////////////////////////////////////////////////////////////////////////////////
1456///Turn the box cut on/off.
1457
1459{
1460 if (a == fActive)
1461 return;
1462 TurnOnOff();
1463}
1464
1465////////////////////////////////////////////////////////////////////////////////
1466///Set geometry using plot's back box.
1467
1469{
1470 const Int_t frontPoint = fPlotBox->GetFrontPoint();
1471 const TGLVertex3 *box = fPlotBox->Get3DBox();
1472 const TGLVertex3 center((box[0].X() + box[1].X()) / 2, (box[0].Y() + box[2].Y()) / 2,
1473 (box[0].Z() + box[4].Z()) / 2);
1474 fXLength = fFactor * (box[1].X() - box[0].X());
1475 fYLength = fFactor * (box[2].Y() - box[0].Y());
1476 fZLength = fFactor * (box[4].Z() - box[0].Z());
1477
1478 switch(frontPoint){
1479 case 0:
1480 fCenter.X() = box[0].X();
1481 fCenter.Y() = box[0].Y();
1482 break;
1483 case 1:
1484 fCenter.X() = box[1].X();
1485 fCenter.Y() = box[0].Y();
1486 break;
1487 case 2:
1488 fCenter.X() = box[2].X();
1489 fCenter.Y() = box[2].Y();
1490 break;
1491 case 3:
1492 fCenter.X() = box[0].X();
1493 fCenter.Y() = box[2].Y();
1494 break;
1495 }
1496
1497 fCenter.Z() = box[0].Z() * 0.5 + box[4].Z() * 0.5;
1498 AdjustBox();
1499}
1500
1501////////////////////////////////////////////////////////////////////////////////
1502///Draw cut as a semi-transparent box.
1503
1505{
1506 if (!selectionPass) {
1508 glLineWidth(3.f);
1509
1510 selected == TGLPlotPainter::kXAxis ? glColor3d(1., 1., 0.) : glColor3d(1., 0., 0.);
1511 glBegin(GL_LINES);
1512 glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1513 glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1514 glEnd();
1515
1516 selected == TGLPlotPainter::kYAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 1., 0.);
1517 glBegin(GL_LINES);
1518 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
1519 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
1520 glEnd();
1521
1522 selected == TGLPlotPainter::kZAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 0., 1.);
1523 glBegin(GL_LINES);
1524 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
1525 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
1526 glEnd();
1527
1528 glLineWidth(1.f);
1530
1533
1534 if (!oldBlendState)
1536
1538
1539
1540 const Float_t diffuseColor[] = {0.f, 0.f, 1.f, 0.1f};
1542
1543 Rgl::DrawBoxFront(fXRange.first, fXRange.second, fYRange.first, fYRange.second,
1544 fZRange.first, fZRange.second, fPlotBox->GetFrontPoint());
1545
1546 if (!oldBlendState)
1548 } else {
1549 glLineWidth(5.f);
1551 glBegin(GL_LINES);
1552 glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1553 glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1554 glEnd();
1555
1557 glBegin(GL_LINES);
1558 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
1559 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
1560 glEnd();
1561
1563 glBegin(GL_LINES);
1564 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
1565 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
1566 glEnd();
1567 glLineWidth(1.f);
1568 }
1569}
1570
1571////////////////////////////////////////////////////////////////////////////////
1572///Start cut's movement
1573
1575{
1576 fMousePos.fX = px;
1577 fMousePos.fY = py;
1578}
1579
1580////////////////////////////////////////////////////////////////////////////////
1581///Move box cut along selected direction.
1582
1584{
1585 Double_t mv[16] = {0.};
1587 Double_t pr[16] = {0.};
1589 Int_t vp[4] = {0};
1591 Double_t winVertex[3] = {0.};
1592
1593 switch(axisID){
1595 gluProject(fCenter.X(), 0., 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1596 break;
1598 gluProject(0., fCenter.Y(), 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1599 break;
1601 gluProject(0., 0., fCenter.Z(), mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1602 break;
1603 }
1604
1605 winVertex[0] += px - fMousePos.fX;
1606 winVertex[1] += py - fMousePos.fY;
1607 Double_t newPoint[3] = {0.};
1608 gluUnProject(winVertex[0], winVertex[1], winVertex[2], mv, pr, vp,
1609 newPoint, newPoint + 1, newPoint + 2);
1610
1611 const TGLVertex3 *box = fPlotBox->Get3DBox();
1612
1613 switch(axisID){
1615 if (newPoint[0] >= box[1].X() + 0.4 * fXLength)
1616 break;
1617 if (newPoint[0] <= box[0].X() - 0.4 * fXLength)
1618 break;
1619 fCenter.X() = newPoint[0];
1620 break;
1622 if (newPoint[1] >= box[2].Y() + 0.4 * fYLength)
1623 break;
1624 if (newPoint[1] <= box[0].Y() - 0.4 * fYLength)
1625 break;
1626 fCenter.Y() = newPoint[1];
1627 break;
1629 if (newPoint[2] >= box[4].Z() + 0.4 * fZLength)
1630 break;
1631 if (newPoint[2] <= box[0].Z() - 0.4 * fZLength)
1632 break;
1633 fCenter.Z() = newPoint[2];
1634 break;
1635 }
1636
1637 fMousePos.fX = px;
1638 fMousePos.fY = py;
1639
1640 AdjustBox();
1641}
1642
1643////////////////////////////////////////////////////////////////////////////////
1644///Box cut is limited by plot's sizes.
1645
1647{
1648 const TGLVertex3 *box = fPlotBox->Get3DBox();
1649
1650 fXRange.first = fCenter.X() - fXLength / 2.;
1651 fXRange.second = fCenter.X() + fXLength / 2.;
1652 fYRange.first = fCenter.Y() - fYLength / 2.;
1653 fYRange.second = fCenter.Y() + fYLength / 2.;
1654 fZRange.first = fCenter.Z() - fZLength / 2.;
1655 fZRange.second = fCenter.Z() + fZLength / 2.;
1656
1657 fXRange.first = TMath::Max(fXRange.first, box[0].X());
1658 fXRange.first = TMath::Min(fXRange.first, box[1].X());
1659 fXRange.second = TMath::Min(fXRange.second, box[1].X());
1660 fXRange.second = TMath::Max(fXRange.second, box[0].X());
1661
1662 fYRange.first = TMath::Max(fYRange.first, box[0].Y());
1663 fYRange.first = TMath::Min(fYRange.first, box[2].Y());
1664 fYRange.second = TMath::Min(fYRange.second, box[2].Y());
1665 fYRange.second = TMath::Max(fYRange.second, box[0].Y());
1666
1667 fZRange.first = TMath::Max(fZRange.first, box[0].Z());
1668 fZRange.first = TMath::Min(fZRange.first, box[4].Z());
1669 fZRange.second = TMath::Min(fZRange.second, box[4].Z());
1670 fZRange.second = TMath::Max(fZRange.second, box[0].Z());
1671}
1672
1673////////////////////////////////////////////////////////////////////////////////
1674///Check, if box defined by xmin/xmax etc. is in cut.
1675
1677 Double_t zMin, Double_t zMax)const
1678{
1679 if (((xMin >= fXRange.first && xMin < fXRange.second) || (xMax > fXRange.first && xMax <= fXRange.second)) &&
1680 ((yMin >= fYRange.first && yMin < fYRange.second) || (yMax > fYRange.first && yMax <= fYRange.second)) &&
1681 ((zMin >= fZRange.first && zMin < fZRange.second) || (zMax > fZRange.first && zMax <= fZRange.second)))
1682 return kTRUE;
1683 return kFALSE;
1684}
1685
1686
1687/** \class TGLTH3Slice
1688\ingroup opengl
1689A slice of a TH3.
1690*/
1691
1692
1693////////////////////////////////////////////////////////////////////////////////
1694/// Constructor.
1695
1697 const TGLPlotBox *box, ESliceAxis axis)
1698 : TNamed(name, name),
1699 fAxisType(axis),
1700 fAxis(nullptr),
1701 fCoord(coord),
1702 fBox(box),
1703 fSliceWidth(1),
1704 fHist(hist),
1705 fF3(nullptr)
1706{
1707 fAxis = fAxisType == kXOZ ? fHist->GetYaxis() : fAxisType == kYOZ ? fHist->GetXaxis() : fHist->GetZaxis();
1708}
1709
1710////////////////////////////////////////////////////////////////////////////////
1711/// Constructor.
1712
1714 const TGLPlotBox *box, ESliceAxis axis)
1715 : TNamed(name, name),
1716 fAxisType(axis),
1717 fAxis(nullptr),
1718 fCoord(coord),
1719 fBox(box),
1720 fSliceWidth(1),
1721 fHist(hist),
1722 fF3(fun)
1723{
1724 fAxis = fAxisType == kXOZ ? fHist->GetYaxis() : fAxisType == kYOZ ? fHist->GetXaxis() : fHist->GetZaxis();
1725}
1726
1727////////////////////////////////////////////////////////////////////////////////
1728/// Set Slice width.
1729
1731{
1732 if (width <= 0)
1733 return;
1734
1735 if (fAxis->GetLast() - fAxis->GetFirst() + 1 <= width)
1736 fSliceWidth = fAxis->GetLast() - fAxis->GetFirst() + 1;
1737 else
1739}
1740
1741////////////////////////////////////////////////////////////////////////////////
1742/// Draw slice.
1743
1745{
1746 Int_t bin = 0;
1747 for (Int_t i = fAxis->GetFirst(), e = fAxis->GetLast(); i <= e; ++i) {
1748 if (pos >= fAxis->GetBinLowEdge(i) && pos <= fAxis->GetBinUpEdge(i)) {
1749 bin = i;
1750 break;
1751 }
1752 }
1753
1754 if (bin) {
1755 Int_t low = 1, up = 2;
1756 if (bin - fSliceWidth + 1 >= fAxis->GetFirst()) {
1757 low = bin - fSliceWidth + 1;
1758 up = bin + 1;
1759 } else {
1760 low = fAxis->GetFirst();
1761 up = bin + (fSliceWidth - (bin - fAxis->GetFirst() + 1)) + 1;
1762 }
1763
1764 if (!fF3)
1765 FindMinMax(low, up);
1766
1767 if (!PreparePalette())
1768 return;
1769
1770 PrepareTexCoords(pos, low, up);
1771
1774 DrawSliceTextured(pos);
1776 //highlight bins in a slice.
1777 //DrawSliceFrame(low, up);
1778 }
1779}
1780
1781////////////////////////////////////////////////////////////////////////////////
1782/// Find minimum and maximum for slice.
1783
1784void TGLTH3Slice::FindMinMax(Int_t /*low*/, Int_t /*up*/)const
1785{
1786 /* fMinMax.first = 0.;
1787
1788 switch (fAxisType) {
1789 case kXOZ:
1790 for (Int_t level = low; level < up; ++ level)
1791 fMinMax.first += fHist->GetBinContent(fCoord->GetFirstXBin(), level, fCoord->GetFirstZBin());
1792 fMinMax.second = fMinMax.first;
1793 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1794 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1795 Double_t val = 0.;
1796 for (Int_t level = low; level < up; ++ level)
1797 val += fHist->GetBinContent(i, level, j);
1798 fMinMax.second = TMath::Max(fMinMax.second, val);
1799 fMinMax.first = TMath::Min(fMinMax.first, val);
1800 }
1801 }
1802 break;
1803 case kYOZ:
1804 for (Int_t level = low; level < up; ++ level)
1805 fMinMax.first += fHist->GetBinContent(level, fCoord->GetFirstYBin(), fCoord->GetFirstZBin());
1806 fMinMax.second = fMinMax.first;
1807 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1808 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i <= ei; ++i, ++it) {
1809 Double_t val = 0.;
1810 for (Int_t level = low; level < up; ++ level)
1811 val += fHist->GetBinContent(level, i, j);
1812 fMinMax.second = TMath::Max(fMinMax.second, val);
1813 fMinMax.first = TMath::Min(fMinMax.first, val);
1814 }
1815 }
1816 break;
1817 case kXOY:
1818 for (Int_t level = low; level < up; ++ level)
1819 fMinMax.first += fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin(), level);
1820 fMinMax.second = fMinMax.first;
1821 for (Int_t i = fCoord->GetFirstXBin(), ir = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++ir) {
1822 for (Int_t j = fCoord->GetFirstYBin(), jr = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jr) {
1823 Double_t val = 0.;
1824 for (Int_t level = low; level < up; ++ level)
1825 val += fHist->GetBinContent(i, j, level);
1826 fMinMax.second = TMath::Max(fMinMax.second, val);
1827 fMinMax.first = TMath::Min(fMinMax.first, val);
1828 }
1829 }
1830 break;
1831 }*/
1832}
1833
1834////////////////////////////////////////////////////////////////////////////////
1835///Initialize color palette.
1836
1838{
1839 UInt_t paletteSize = ((TH1 *)fHist)->GetContour();
1841 paletteSize = 20;
1842
1844}
1845
1846////////////////////////////////////////////////////////////////////////////////
1847/// Prepare TexCoords.
1848
1850{
1851 switch (fAxisType) {
1852 case kXOZ:
1853 fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNZBins());
1854 fTexCoords.SetRowLen(fCoord->GetNXBins());
1855 if (!fF3) {
1856
1857 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1858 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1859 Double_t val = 0.;
1860 for (Int_t level = low; level < up; ++ level)
1861 val += fHist->GetBinContent(i, level, j);
1862 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1863 }
1864 }
1865 } else {
1866 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1867 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1868 Double_t val = fF3->Eval(fHist->GetXaxis()->GetBinCenter(i), pos, fHist->GetZaxis()->GetBinCenter(j));
1869 if (val > fMinMax.second)
1870 val = fMinMax.second;
1871 else if (val < fMinMax.first)
1872 val = fMinMax.first;
1873 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1874 }
1875 }
1876 }
1877 break;
1878 case kYOZ:
1879 fTexCoords.resize(fCoord->GetNYBins() * fCoord->GetNZBins());
1880 fTexCoords.SetRowLen(fCoord->GetNYBins());
1881 if (!fF3) {
1882 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1883 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i <= ei; ++i, ++it) {
1884 Double_t val = 0.;
1885 for (Int_t level = low; level < up; ++ level)
1886 val += fHist->GetBinContent(level, i, j);
1887 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1888 }
1889 }
1890 } else {
1891 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1892 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1893 Double_t val = fF3->Eval(pos, fHist->GetYaxis()->GetBinCenter(i), fHist->GetZaxis()->GetBinCenter(j));
1894 if (val > fMinMax.second)
1895 val = fMinMax.second;
1896 else if (val < fMinMax.first)
1897 val = fMinMax.first;
1898 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1899 }
1900 }
1901 }
1902 break;
1903 case kXOY:
1904 fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNYBins());
1905 fTexCoords.SetRowLen(fCoord->GetNYBins());
1906 if (!fF3) {
1907 for (Int_t i = fCoord->GetFirstXBin(), ir = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++ir) {
1908 for (Int_t j = fCoord->GetFirstYBin(), jr = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jr) {
1909 Double_t val = 0.;
1910 for (Int_t level = low; level < up; ++ level)
1911 val += fHist->GetBinContent(i, j, level);
1913 }
1914 }
1915 } else {
1916 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1917 for (Int_t j = fCoord->GetFirstYBin(), jt = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jt) {
1918 Double_t val = fF3->Eval(fHist->GetXaxis()->GetBinCenter(i), fHist->GetYaxis()->GetBinCenter(j), pos);
1919 if (val > fMinMax.second)
1920 val = fMinMax.second;
1921 else if (val < fMinMax.first)
1922 val = fMinMax.first;
1923 fTexCoords[it][jt] = fPalette.GetTexCoord(val);
1924 }
1925 }
1926
1927 }
1928 break;
1929 }
1930}
1931
1932////////////////////////////////////////////////////////////////////////////////
1933/// Draw slice textured.
1934
1936{
1937 const Double_t xScale = fCoord->GetXScale();
1938 const Double_t yScale = fCoord->GetYScale();
1939 const Double_t zScale = fCoord->GetZScale();
1940 const TAxis *xA = fHist->GetXaxis();
1941 const TAxis *yA = fHist->GetYaxis();
1942 const TAxis *zA = fHist->GetZaxis();
1943
1944 switch (fAxisType) {
1945 case kXOZ:
1946 pos *= yScale;
1947 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
1948 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i < ei; ++i, ++it) {
1949 const Double_t xMin = xA->GetBinCenter(i) * xScale;
1950 const Double_t xMax = xA->GetBinCenter(i + 1) * xScale;
1951 const Double_t zMin = zA->GetBinCenter(j) * zScale;
1952 const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
1955 glVertex3d(xMin, pos, zMin);
1956 glTexCoord1d(fTexCoords[jt + 1][it]);
1957 glVertex3d(xMin, pos, zMax);
1958 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
1959 glVertex3d(xMax, pos, zMax);
1960 glTexCoord1d(fTexCoords[jt][it + 1]);
1961 glVertex3d(xMax, pos, zMin);
1962 glEnd();
1963 }
1964 }
1965 break;
1966 case kYOZ:
1967 pos *= xScale;
1968 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
1969 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
1970 const Double_t yMin = yA->GetBinCenter(i) * yScale;
1971 const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
1972 const Double_t zMin = zA->GetBinCenter(j) * zScale;
1973 const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
1976 glVertex3d(pos, yMin, zMin);
1977 glTexCoord1d(fTexCoords[jt][it + 1]);
1978 glVertex3d(pos, yMax, zMin);
1979 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
1980 glVertex3d(pos, yMax, zMax);
1981 glTexCoord1d(fTexCoords[jt + 1][it]);
1982 glVertex3d(pos, yMin, zMax);
1983 glEnd();
1984 }
1985 }
1986 break;
1987 case kXOY:
1988 pos *= zScale;
1989 for (Int_t j = fCoord->GetFirstXBin(), jt = 0, ej = fCoord->GetLastXBin(); j < ej; ++j, ++jt) {
1990 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
1991 const Double_t xMin = xA->GetBinCenter(j) * xScale;
1992 const Double_t xMax = xA->GetBinCenter(j + 1) * xScale;
1993 const Double_t yMin = yA->GetBinCenter(i) * yScale;
1994 const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
1996 glTexCoord1d(fTexCoords[jt + 1][it]);
1997 glVertex3d(xMax, yMin, pos);
1998 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
1999 glVertex3d(xMax, yMax, pos);
2000 glTexCoord1d(fTexCoords[jt][it + 1]);
2001 glVertex3d(xMin, yMax, pos);
2003 glVertex3d(xMin, yMin, pos);
2004 glEnd();
2005 }
2006 }
2007 break;
2008 }
2009}
2010
2011namespace {
2012
2013////////////////////////////////////////////////////////////////////////////////
2014
2017{
2018 glBegin(GL_LINE_LOOP);
2023 glEnd();
2024
2025 glBegin(GL_LINE_LOOP);
2030 glEnd();
2031
2032 glBegin(GL_LINES);
2041 glEnd();
2042}
2043
2044}
2045
2046////////////////////////////////////////////////////////////////////////////////
2047/// Draw slice frame.
2048
2050{
2051 glColor3d(1., 0., 0.);
2052 const TGLVertex3 *box = fBox->Get3DBox();
2053
2054 switch (fAxisType) {
2055 case kXOZ:
2056 DrawBoxOutline(box[0].X(), box[1].X(),
2057 fAxis->GetBinLowEdge(low) * fCoord->GetYScale(),
2058 fAxis->GetBinUpEdge(up - 1) * fCoord->GetYScale(),
2059 box[0].Z(), box[4].Z());
2060 break;
2061 case kYOZ:
2062 DrawBoxOutline(fAxis->GetBinLowEdge(low) * fCoord->GetXScale(),
2063 fAxis->GetBinUpEdge(up - 1) * fCoord->GetXScale(),
2064 box[0].Y(), box[2].Y(),
2065 box[0].Z(), box[4].Z());
2066 break;
2067 case kXOY:
2068 DrawBoxOutline(box[0].X(), box[1].X(),
2069 box[0].Y(), box[2].Y(),
2070 fAxis->GetBinLowEdge(low) * fCoord->GetZScale(),
2071 fAxis->GetBinUpEdge(up - 1) * fCoord->GetZScale());
2072 break;
2073 }
2074}
2075
2076namespace Rgl {
2077
2078////////////////////////////////////////////////////////////////////////////////
2079
2081 : fPainter(painter)
2082{
2083 const TGLVertex3 *box = fPainter->fBackBox.Get3DBox();
2084 const Double_t center[] = {(box[0].X() + box[1].X()) / 2,
2085 (box[0].Y() + box[2].Y()) / 2,
2086 (box[0].Z() + box[4].Z()) / 2};
2087
2088 fPainter->SaveModelviewMatrix();
2089 glTranslated(-center[0], -center[1], -center[2]);
2090}
2091
2092////////////////////////////////////////////////////////////////////////////////
2093
2095{
2096 fPainter->RestoreModelviewMatrix();
2097}
2098
2099namespace
2100{
2101
2102const Double_t lr = 0.85;
2103const Double_t rr = 0.9;
2104
2105}
2106
2107////////////////////////////////////////////////////////////////////////////////
2108///Draw. Palette.
2109
2111{
2115
2117
2120 glOrtho(0, camera->GetWidth(), 0, camera->GetHeight(), -1., 1.);
2121
2124
2125 const Double_t leftX = camera->GetWidth() * lr;
2126 const Double_t rightX = camera->GetWidth() * rr;
2127 const Double_t margin = 0.1 * camera->GetHeight();
2128 const Double_t h = (camera->GetHeight() * 0.8) / palette.GetPaletteSize();
2129
2130 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2132 const UChar_t * color = palette.GetColour(i);
2133 glColor4ub(color[0], color[1], color[2], 150);
2134 glVertex2d(leftX, margin + i * h);
2135 glVertex2d(rightX, margin + i * h);
2136 glVertex2d(rightX, margin + (i + 1) * h);
2137 glVertex2d(leftX, margin + (i + 1) * h);
2138 glEnd();
2139 }
2140
2143 glColor4d(0., 0., 0., 0.5);
2144
2145 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2146 glBegin(GL_LINE_LOOP);
2147 glVertex2d(leftX, margin + i * h);
2148 glVertex2d(rightX, margin + i * h);
2149 glVertex2d(rightX, margin + (i + 1) * h);
2150 glVertex2d(leftX, margin + (i + 1) * h);
2151 glEnd();
2152 }
2153
2154}
2155
2156////////////////////////////////////////////////////////////////////////////////
2157///Draw. Palette.
2158
2160 const std::vector<Double_t> & levels)
2161{
2165
2167
2170 glOrtho(0, camera->GetWidth(), 0, camera->GetHeight(), -1., 1.);
2171
2174
2175 const Double_t leftX = camera->GetWidth() * lr;
2176 const Double_t rightX = camera->GetWidth() * rr;
2177 const Double_t margin = 0.1 * camera->GetHeight();
2178 const Double_t h = (camera->GetHeight() * 0.8);
2179 const Double_t range = levels.back() - levels.front();
2180
2181 const UChar_t opacity = 200;
2182
2183 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2184 const Double_t yMin = margin + (levels[i] - levels.front()) / range * h;
2185 const Double_t yMax = margin + (levels[i + 1] - levels.front()) / range * h;
2187 const UChar_t * color = palette.GetColour(i);
2188 glColor4ub(color[0], color[1], color[2], opacity);
2193 glEnd();
2194 }
2195
2198 glColor4d(0., 0., 0., 0.5);
2199
2200 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2201 const Double_t yMin = (levels[i] - levels.front()) / range * h;
2202 const Double_t yMax = (levels[i + 1] - levels.front()) / range * h;
2203
2204 glBegin(GL_LINE_LOOP);
2205 glVertex2d(leftX, margin + yMin);
2206 glVertex2d(rightX, margin + yMin);
2207 glVertex2d(rightX, margin + yMax);
2208 glVertex2d(leftX, margin + yMax);
2209 glEnd();
2210 }
2211
2212}
2213
2214////////////////////////////////////////////////////////////////////////////////
2215
2217{
2218 UInt_t pixelW = camera->GetWidth();
2219 UInt_t pixelH = camera->GetHeight();
2220
2223 if (scale > 1.) {
2226 }
2227
2228 const Double_t x = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw() + rr * pixelW));
2229 const Double_t yMin = gPad->AbsPixeltoY(Int_t(gPad->GetWh() - (pixelH * 0.1
2230 + gPad->GetYlowNDC() * gPad->GetWh())));
2231 const Double_t yMax = gPad->AbsPixeltoY(Int_t(gPad->GetWh() - (pixelH * 0.9
2232 + gPad->GetYlowNDC() * gPad->GetWh())));
2233
2234 Double_t zMin = minMax.first;
2235 Double_t zMax = minMax.second;
2236
2237 if (logZ) {
2238 zMin = TMath::Power(10, zMin);
2239 zMax = TMath::Power(10, zMax);
2240 }
2241
2242 //Now, some stupid magic, to force ROOT's painting machine work as I want, not as it wants.
2243 const Bool_t logX = gPad->GetLogx();
2244 gPad->SetLogx(kFALSE);
2245 const Bool_t logY = gPad->GetLogy();
2246 gPad->SetLogy(kFALSE);
2247
2248 TGaxis axisPainter(x, yMin, x, yMax, zMin, zMax, 510, logZ ? "G" : "");
2249 axisPainter.Paint();
2250
2251 gPad->SetLogx(logX);
2252 gPad->SetLogy(logY);
2253}
2254
2255//Constant for TGLH2PolyPainter.
2257
2258}
2259
#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
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:52
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
#define X(type, name)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
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:442
#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:32
Bool_t IsVariableBinSize() const
Definition TAxis.h:144
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:521
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x
Definition TAxis.cxx:421
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:472
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:545
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:531
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:461
virtual Int_t GetEntries() const
The color creation and management class.
Definition TColor.h:22
A 3-Dim function with parameters.
Definition TF3.h:28
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
void DisableTexture() const
Disable 1D texture.
Definition TGLUtil.cxx:4244
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition TGLUtil.cxx:4261
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition TGLUtil.cxx:4160
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition TGLUtil.cxx:4225
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.
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.
const Rgl::BinRange_t & GetXBins() const
X bins range.
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.
Int_t GetNXBins() const
Number of X bins.
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
const Rgl::Range_t & GetXRange() const
X range.
Int_t GetNYBins() const
Number of Y bins.
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:2825
void ReadColorBuffer(Int_t width, Int_t height)
Read color buffer.
Definition TGLUtil.cxx:2801
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:1573
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition TGLUtil.cxx:1843
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:26
@ kClipFrame
Clip to the frame boundary.
Definition TGraph.h:75
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
TAxis * GetZaxis()
Definition TH1.h:574
virtual Double_t GetMinimumStored() const
Definition TH1.h:538
virtual Double_t GetNormFactor() const
Definition TH1.h:546
TAxis * GetXaxis()
Definition TH1.h:572
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:4963
TAxis * GetYaxis()
Definition TH1.h:573
virtual Double_t GetCellError(Int_t binx, Int_t biny) const
Definition TH1.h:685
virtual Double_t GetMaximumStored() const
Definition TH1.h:534
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5063
2D Histogram with Polygonal Bins
Definition TH2Poly.h:66
TList * GetBins()
Returns the TList of all bins in the histogram.
Definition TH2Poly.h:100
Double_t GetMinimum() const
Returns the minimum value of the histogram.
Definition TH2Poly.cxx:962
Double_t GetMaximum() const
Returns the maximum value of the histogram.
Definition TH2Poly.cxx:914
The 3-D histogram classes derived from the 1-D histogram classes.
Definition TH3.h:40
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:49
SCoord_t fY
Definition TPoint.h:36
SCoord_t fX
Definition TPoint.h:35
Basic string class.
Definition TString.h:138
Bool_t GetHistMinimumZero() const
Definition TStyle.h:239
Double_t GetHistTopMargin() const
Definition TStyle.h:240
Int_t GetNumberContours() const
Definition TStyle.h:243
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:2952
const Float_t gNullEmission[]
Definition TGLUtil.cxx:2846
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition TGLUtil.cxx:2890
const Float_t gBlueEmission[]
Definition TGLUtil.cxx:2842
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:3006
const Double_t gH2PolyScaleXY
Int_t ColorToObjectID(const UChar_t *color, Bool_t highColor)
Definition TGLUtil.cxx:2916
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:3758
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:251
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:732
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:773
static void output()