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(0),
53 fPhysicalShapeColor(0),
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(0),
86 fPhysicalShapeColor(0),
87 fPadPhi(45.),
88 fPadTheta(0.),
89 fHist(0),
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(0),
119 fPhysicalShapeColor(0),
120 fPadPhi(45.),
121 fPadTheta(0.),
122 fHist(0),
123 fXAxis(0),
124 fYAxis(0),
125 fZAxis(0),
126 fCoord(0),
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{
234 using namespace std;
235
237
238 FILE *output = fopen(gVirtualPS->GetName(), "a");
239 if (!output) {
240 Error("TGLPlotPainter::PrintPlot", "Could not (re)open ps file for GL output");
241 //As soon as we started embedded ps, we have to close it before exiting.
243 return;
244 }
245
246 Int_t gl2psFormat = GL2PS_EPS;
247 Int_t gl2psSort = GL2PS_BSP_SORT;
248 Int_t buffsize = 0;
249 Int_t state = GL2PS_OVERFLOW;
250 GLint gl2psoption = GL2PS_USE_CURRENT_VIEWPORT |
251 GL2PS_SILENT |
252 GL2PS_BEST_ROOT |
253 GL2PS_OCCLUSION_CULL |
254 0;
255
256 while (state == GL2PS_OVERFLOW) {
257 buffsize += 1024*1024;
258 gl2psBeginPage ("ROOT Scene Graph", "ROOT", NULL,
259 gl2psFormat, gl2psSort, gl2psoption,
260 GL_RGBA, 0, NULL,0, 0, 0,
261 buffsize, output, NULL);
262 DrawPlot();
263 state = gl2psEndPage();
264 }
265
266 fclose(output);
268 glFlush();
269}
270
271////////////////////////////////////////////////////////////////////////////////
272///Read color buffer content to find selected object
273
275{
276 if (fUpdateSelection) {
277 //Save projection and modelview matrix, used by glpad.
278 glMatrixMode(GL_PROJECTION);//[1
279 glPushMatrix();
280 glMatrixMode(GL_MODELVIEW);//[2
281 glPushMatrix();
282
285
286 glDepthMask(GL_TRUE);
287 glClearColor(0.f, 0.f, 0.f, 0.f);
288 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
289
291 DrawPlot();
292
293 glFinish();
294 //fSelection.ReadColorBuffer(fCamera->GetWidth(), fCamera->GetHeight());
295
299
300 glDepthMask(GL_FALSE);
301 glDisable(GL_DEPTH_TEST);
302
303 //Restore projection and modelview matrices.
304 glMatrixMode(GL_PROJECTION);//1]
305 glPopMatrix();
306 glMatrixMode(GL_MODELVIEW);//2]
307 glPopMatrix();
308 }
309
310 px -= Int_t(gPad->GetXlowNDC() * gPad->GetWw());
311 py -= Int_t(gPad->GetWh() - gPad->YtoAbsPixel(gPad->GetY1()));
312
313 //Pixel coords can be affected by scaling factor on retina displays.
316
317 if (scale > 1.f) {
318 px *= scale;
319 py *= scale;
320 }
321
322 //py = fCamera->GetHeight() - py;
323 //Y is a number of a row, x - column.
324 std::swap(px, py);
326
327 if (newSelected != fSelectedPart) {
328 //New object was selected (or surface deselected) - re-paint.
329 fSelectedPart = newSelected;
330 gPad->Update();
331 }
332
333 return fSelectedPart ? kTRUE : kFALSE;
334}
335
336////////////////////////////////////////////////////////////////////////////////
337///Used in a pad.
338
340{
341 fPadColor = c;
342}
343
344////////////////////////////////////////////////////////////////////////////////
345///Set plot's back box color.
346
348{
350}
351
352////////////////////////////////////////////////////////////////////////////////
353///Selection must be updated.
354
356{
358}
359
360////////////////////////////////////////////////////////////////////////////////
361///Get pad color.
362
364{
365 return fPadColor;
366}
367
368////////////////////////////////////////////////////////////////////////////////
369///Create dynamic profile using selected plane
370
372{
373 //Coordinates are expected to be fixed for retina!
374
375 const TGLVertex3 *frame = fBackBox.Get3DBox();
376 const Int_t frontPoint = fBackBox.GetFrontPoint();
377
378 if (fSelectedPart == 1) {
379 fXOYSectionPos = frame[0].Z();
380 fSelectedPart = 6;
381 } else if (fSelectedPart == 2) {
382 if (frontPoint == 2) {
383 fXOZSectionPos = frame[0].Y();
384 fSelectedPart = 4;
385 } else if (!frontPoint) {
386 fXOZSectionPos = frame[2].Y();
387 fSelectedPart = 4;
388 } else if (frontPoint == 1) {
389 fYOZSectionPos = frame[0].X();
390 fSelectedPart = 5;
391 } else if (frontPoint == 3) {
392 fYOZSectionPos = frame[1].X();
393 fSelectedPart = 5;
394 }
395 } else if (fSelectedPart == 3) {
396 if (frontPoint == 2) {
397 fYOZSectionPos = frame[0].X();
398 fSelectedPart = 5;
399 } else if (!frontPoint) {
400 fYOZSectionPos = frame[1].X();
401 fSelectedPart = 5;
402 } else if (frontPoint == 1) {
403 fXOZSectionPos = frame[2].Y();
404 fSelectedPart = 4;
405 } else if (frontPoint == 3) {
406 fXOZSectionPos = frame[0].Y();
407 fSelectedPart = 4;
408 }
409 }
410
411 Double_t mv[16] = {0.};
412 glGetDoublev(GL_MODELVIEW_MATRIX, mv);
413 Double_t pr[16] = {0.};
414 glGetDoublev(GL_PROJECTION_MATRIX, pr);
415 Int_t vp[4] = {0};
416 glGetIntegerv(GL_VIEWPORT, vp);
417 Double_t winVertex[3] = {0.};
418
419 if (fSelectedPart == 6)
420 gluProject(0., 0., fXOYSectionPos, mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
421 else
422 gluProject(fSelectedPart == 5 ? fYOZSectionPos : 0.,
423 fSelectedPart == 4 ? fXOZSectionPos : 0.,
424 0., mv, pr, vp,
425 &winVertex[0], &winVertex[1], &winVertex[2]);
426 winVertex[0] += px - fMousePosition.fX;
427 winVertex[1] += py - fMousePosition.fY;
428 Double_t newPoint[3] = {0.};
429 gluUnProject(winVertex[0], winVertex[1], winVertex[2], mv, pr, vp,
430 newPoint, newPoint + 1, newPoint + 2);
431
432 if (fSelectedPart == 4)
433 fXOZSectionPos = newPoint[1];
434 else if (fSelectedPart == 5)
435 fYOZSectionPos = newPoint[0];
436 else
437 fXOYSectionPos = newPoint[2];
438}
439
440////////////////////////////////////////////////////////////////////////////////
441///Draw sections (if any).
442
444{
445 const TGLVertex3 *frame = fBackBox.Get3DBox();
446
447 if (fXOZSectionPos > frame[0].Y()) {
448 if (fXOZSectionPos > frame[2].Y())
449 fXOZSectionPos = frame[2].Y();
450 const TGLVertex3 v1(frame[0].X(), fXOZSectionPos, frame[0].Z());
451 const TGLVertex3 v2(frame[4].X(), fXOZSectionPos, frame[4].Z());
452 const TGLVertex3 v3(frame[5].X(), fXOZSectionPos, frame[5].Z());
453 const TGLVertex3 v4(frame[1].X(), fXOZSectionPos, frame[1].Z());
454
455 if (fSelectionPass)
457 else if (fSelectedPart == 4)
458 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
459
460 glEnable(GL_POLYGON_OFFSET_FILL);
461 glPolygonOffset(1.f, 1.f);
462 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 1., 0.));
463 glDisable(GL_POLYGON_OFFSET_FILL);
464 //Zlevels here.
465 if (!fSelectionPass) {
466 if (fSelectedPart == 4)
467 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
468 const TGLDisableGuard lightGuard(GL_LIGHTING);
469 const TGLEnableGuard blendGuard(GL_BLEND);
470 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
471 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
472 glDepthMask(GL_FALSE);
474 //Draw z-levels
475 const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);//[1-1]
476 const UShort_t stipple = 0x5555;
477 glLineStipple(1, stipple);
478
479 glColor3d(0., 0., 0.);
480 glBegin(GL_LINES);
481 for (UInt_t i = 0; i < fZLevels.size(); ++i) {
482 glVertex3d(fBackBox.Get3DBox()[1].X(), fXOZSectionPos, fZLevels[i]);
483 glVertex3d(fBackBox.Get3DBox()[0].X(), fXOZSectionPos, fZLevels[i]);
484 }
485 glEnd();
486 glDepthMask(GL_TRUE);
487 }
488 }
489
490 if (fYOZSectionPos > frame[0].X()) {
491 if (fYOZSectionPos > frame[1].X())
492 fYOZSectionPos = frame[1].X();
493 TGLVertex3 v1(fYOZSectionPos, frame[0].Y(), frame[0].Z());
494 TGLVertex3 v2(fYOZSectionPos, frame[3].Y(), frame[3].Z());
495 TGLVertex3 v3(fYOZSectionPos, frame[7].Y(), frame[7].Z());
496 TGLVertex3 v4(fYOZSectionPos, frame[4].Y(), frame[4].Z());
497
498 if (fSelectionPass) {
500 } else if (fSelectedPart == 5)
501 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
502
503 glEnable(GL_POLYGON_OFFSET_FILL);
504 glPolygonOffset(1.f, 1.f);
505 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(1., 0., 0.));
506 glDisable(GL_POLYGON_OFFSET_FILL);
507
508 if (!fSelectionPass) {
509 if (fSelectedPart == 5)
510 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
511 const TGLDisableGuard lightHuard(GL_LIGHTING);
512 const TGLEnableGuard blendGuard(GL_BLEND);
513 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
514 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
515 glDepthMask(GL_FALSE);
517 //Draw z-levels
518 const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);//[1-1]
519 glLineStipple(1, 0x5555);
520
521 glColor3d(0., 0., 0.);
522 glBegin(GL_LINES);
523 for (UInt_t i = 0; i < fZLevels.size(); ++i) {
524 glVertex3d(fYOZSectionPos, fBackBox.Get3DBox()[3].Y(), fZLevels[i]);
525 glVertex3d(fYOZSectionPos, fBackBox.Get3DBox()[0].Y(), fZLevels[i]);
526 }
527 glEnd();
528 glDepthMask(GL_TRUE);
529 }
530 }
531
532 if (fXOYSectionPos > frame[0].Z()) {
533 if (fXOYSectionPos > frame[4].Z())
534 fXOYSectionPos = frame[4].Z();
535 TGLVertex3 v1(frame[0].X(), frame[0].Y(), fXOYSectionPos);
536 TGLVertex3 v2(frame[1].X(), frame[1].Y(), fXOYSectionPos);
537 TGLVertex3 v3(frame[2].X(), frame[2].Y(), fXOYSectionPos);
538 TGLVertex3 v4(frame[3].X(), frame[3].Y(), fXOYSectionPos);
539
540 if (fSelectionPass) {
542 } else if (fSelectedPart == 6)
543 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gBlueEmission);
544
545 glEnable(GL_POLYGON_OFFSET_FILL);
546 glPolygonOffset(1.f, 1.f);
547 //if (fSelectionPass || fSelectedPart == 6)
548 Rgl::DrawQuadFilled(v1, v2, v3, v4, TGLVector3(0., 0., 1.));
549 glDisable(GL_POLYGON_OFFSET_FILL);
550
551 if (!fSelectionPass) {
552 if (fSelectedPart == 6)
553 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
554 const TGLDisableGuard lightGuard(GL_LIGHTING);
555 const TGLEnableGuard blendGuard(GL_BLEND);
556 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
557 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
558 glDepthMask(GL_FALSE);
560 glDepthMask(GL_TRUE);
561 }
562 }
563}
564
565////////////////////////////////////////////////////////////////////////////////
566
568{
569/*
570 // Clear buffer.
571 Float_t rgb[3] = {1.f, 1.f, 1.f};
572 if (const TColor *color = GetPadColor())
573 color->GetRGB(rgb[0], rgb[1], rgb[2]);
574 glClearColor(rgb[0], rgb[1], rgb[2], 1.);
575 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
576 */
577}
578
579////////////////////////////////////////////////////////////////////////////////
580///Draw. Palette. Axis.
581
583{
584}
585
586////////////////////////////////////////////////////////////////////////////////
587
589{
590 glMatrixMode(GL_MODELVIEW);
591 glPushMatrix();
592}
593
594////////////////////////////////////////////////////////////////////////////////
595
597{
598 glMatrixMode(GL_PROJECTION);
599 glPushMatrix();
600}
601
602////////////////////////////////////////////////////////////////////////////////
603
605{
606 glMatrixMode(GL_MODELVIEW);
607 glPopMatrix();
608}
609
610////////////////////////////////////////////////////////////////////////////////
611
613{
614 glMatrixMode(GL_PROJECTION);
615 glPopMatrix();
616}
617
618/** \class TGLPlotCoordinates
619\ingroup opengl
620Helper class for plot-painters holding information about axis
621ranges, numbers of bins and flags if certain axis is logarithmic.
622*/
623
625
626////////////////////////////////////////////////////////////////////////////////
627///Constructor.
628
630 : fCoordType(kGLCartesian),
631 fXScale(1.),
632 fYScale(1.),
633 fZScale(1.),
634 fXLog(kFALSE),
635 fYLog(kFALSE),
636 fZLog(kFALSE),
637 fModified(kFALSE),
638 fFactor(1.)
639{
640}
641
642////////////////////////////////////////////////////////////////////////////////
643///Destructor.
644
646{
647}
648
649////////////////////////////////////////////////////////////////////////////////
650///If coord type was changed, plot must reset sections (if any),
651///set fModified.
652
654{
655 if (fCoordType != type) {
658 }
659}
660
661////////////////////////////////////////////////////////////////////////////////
662/// Get coordinates type.
663
665{
666 return fCoordType;
667}
668
669////////////////////////////////////////////////////////////////////////////////
670///If log changed, sections must be reset,
671///set fModified.
672
674{
675 if (fXLog != xLog) {
676 fXLog = xLog;
678 }
679}
680
681////////////////////////////////////////////////////////////////////////////////
682/// Get X log.
683
685{
686 return fXLog;
687}
688
689////////////////////////////////////////////////////////////////////////////////
690///If log changed, sections must be reset,
691///set fModified.
692
694{
695 if (fYLog != yLog) {
696 fYLog = yLog;
698 }
699}
700
701////////////////////////////////////////////////////////////////////////////////
702/// Get Y log.
703
705{
706 return fYLog;
707}
708
709////////////////////////////////////////////////////////////////////////////////
710///If log changed, sections must be reset,
711///set fModified.
712
714{
715 if (fZLog != zLog) {
716 fZLog = zLog;
718 }
719}
720
721////////////////////////////////////////////////////////////////////////////////
722/// Get Z log.
723
725{
726 return fZLog;
727}
728
729////////////////////////////////////////////////////////////////////////////////
730/// Reset modified.
731
733{
734 fModified = !fModified;//kFALSE;
735}
736
737////////////////////////////////////////////////////////////////////////////////
738/// Modified.
739
741{
742 return fModified;
743}
744
745////////////////////////////////////////////////////////////////////////////////
746///Set bin ranges, ranges.
747
749{
750 switch (fCoordType) {
751 case kGLPolar:
752 return SetRangesPolar(hist);
753 case kGLCylindrical:
754 return SetRangesCylindrical(hist);
755 case kGLSpherical:
756 return SetRangesSpherical(hist);
757 case kGLCartesian:
758 default:
759 return SetRangesCartesian(hist, errors, zBins);
760 }
761}
762
763////////////////////////////////////////////////////////////////////////////////
764///Number of X bins.
765
767{
768 return fXBins.second - fXBins.first + 1;
769}
770
771////////////////////////////////////////////////////////////////////////////////
772///Number of Y bins.
773
775{
776 return fYBins.second - fYBins.first + 1;
777}
778
779////////////////////////////////////////////////////////////////////////////////
780///Number of Z bins.
781
783{
784 return fZBins.second - fZBins.first + 1;
785}
786
787////////////////////////////////////////////////////////////////////////////////
788///X bins range.
789
791{
792 return fXBins;
793}
794
795////////////////////////////////////////////////////////////////////////////////
796///Y bins range.
797
799{
800 return fYBins;
801}
802
803////////////////////////////////////////////////////////////////////////////////
804///Z bins range.
805
807{
808 return fZBins;
809}
810
811////////////////////////////////////////////////////////////////////////////////
812///X range.
813
815{
816 return fXRange;
817}
818
819////////////////////////////////////////////////////////////////////////////////
820///X length.
821
823{
824 return fXRange.second - fXRange.first;
825}
826
827////////////////////////////////////////////////////////////////////////////////
828///Y range.
829
831{
832 return fYRange;
833}
834
835////////////////////////////////////////////////////////////////////////////////
836///Y length.
837
839{
840 return fYRange.second - fYRange.first;
841}
842
843
844////////////////////////////////////////////////////////////////////////////////
845///Z range.
846
848{
849 return fZRange;
850}
851
852////////////////////////////////////////////////////////////////////////////////
853///Z length.
854
856{
857 return fZRange.second - fZRange.first;
858}
859
860
861////////////////////////////////////////////////////////////////////////////////
862///Scaled range.
863
865{
866 return fXRangeScaled;
867}
868
869////////////////////////////////////////////////////////////////////////////////
870///Scaled range.
871
873{
874 return fYRangeScaled;
875}
876
877////////////////////////////////////////////////////////////////////////////////
878///Scaled range.
879
881{
882 return fZRangeScaled;
883}
884
885////////////////////////////////////////////////////////////////////////////////
886/// Get factor.
887
889{
890 return fFactor;
891}
892
893namespace {
894
895Bool_t FindAxisRange(const TAxis *axis, Bool_t log, Rgl::BinRange_t &bins, Rgl::Range_t &range);
896Bool_t FindAxisRange(const TH1 *hist, Bool_t logZ, const Rgl::BinRange_t &xBins,
897 const Rgl::BinRange_t &yBins, Rgl::Range_t &zRange,
898 Double_t &factor, Bool_t errors);
899
900Bool_t FindAxisRange(TH2Poly *hist, Bool_t zLog, Rgl::Range_t &zRange);
901
902}
903
904////////////////////////////////////////////////////////////////////////////////
905///Set bin ranges, ranges, etc.
906
908{
909 Rgl::BinRange_t xBins;
910 Rgl::Range_t xRange;
911 if (!FindAxisRange(hist->GetXaxis(), fXLog, xBins, xRange)) {
912 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set X axis to log scale");
913 return kFALSE;
914 }
915
916 Rgl::BinRange_t yBins;
917 Rgl::Range_t yRange;
918 if (!FindAxisRange(hist->GetYaxis(), fYLog, yBins, yRange)) {
919 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set Y axis to log scale");
920 return kFALSE;
921 }
922
923 Rgl::BinRange_t zBins;
924 Rgl::Range_t zRange;
925 Double_t factor = 1.;
926
927 if (zAsBins) {
928 if (!FindAxisRange(hist->GetZaxis(), fZLog, zBins, zRange)) {
929 Error("TGLPlotCoordinates::SetRangesCartesian", "Cannot set Z axis to log scale");
930 return kFALSE;
931 }
932 } else if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, errors)) {
933 Error("TGLPlotCoordinates::SetRangesCartesian",
934 "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
935 return kFALSE;
936 }
937
938 //Finds the maximum dimension and adjust scale coefficients
939 const Double_t x = xRange.second - xRange.first;
940 const Double_t y = yRange.second - yRange.first;
941 const Double_t z = zRange.second - zRange.first;
942
943 if (!x || !y || !z) {
944 Error("TGLPlotCoordinates::SetRangesCartesian", "Zero axis range.");
945 return kFALSE;
946 }
947
948 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
949 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
950 {
952 }
953
954 fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
955 fFactor = factor;
956 /*
957 const Double_t maxDim = TMath::Max(TMath::Max(x, y), z);
958 fXScale = maxDim / x;
959 fYScale = maxDim / y;
960 fZScale = maxDim / z;
961 */
962 fXScale = 1. / x;
963 fYScale = 1. / y;
964 fZScale = 1. / z;
965
966 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
967 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
968 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
969
970 return kTRUE;
971}
972
973//
974////////////////////////////////////////////////////////////////////////////////
975///Set bin ranges, ranges, etc.
976
978{
979 Rgl::BinRange_t xBins;
980 Rgl::Range_t xRange;
981 FindAxisRange(hist->GetXaxis(), kFALSE, xBins, xRange);//kFALSE == never logarithmic.
982
983 Rgl::BinRange_t yBins;
984 Rgl::Range_t yRange;
985 FindAxisRange(hist->GetYaxis(), kFALSE, yBins, yRange);//kFALSE == never logarithmic.
986
987 Rgl::BinRange_t zBins;
988 Rgl::Range_t zRange;
989 Double_t factor = 1.;
990
991 if (!FindAxisRange(hist, fZLog, zRange))
992 return kFALSE;
993
994 //Finds the maximum dimension and adjust scale coefficients
995 const Double_t x = xRange.second - xRange.first;
996 const Double_t y = yRange.second - yRange.first;
997 const Double_t z = zRange.second - zRange.first;
998
999 if (!x || !y || !z) {
1000 Error("TGLPlotCoordinates::SetRanges", "Zero axis range.");
1001 return kFALSE;
1002 }
1003
1004 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
1005 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
1006 {
1007 fModified = kTRUE;
1008 }
1009
1010 fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
1011 fFactor = factor;
1012
1015 fZScale = 1. / z;
1016
1017 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
1018 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
1019 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
1020
1021 return kTRUE;
1022}
1023//
1024
1025////////////////////////////////////////////////////////////////////////////////
1026///Set bin ranges, ranges, etc.
1027
1028Bool_t TGLPlotCoordinates::SetRanges(const TAxis *xAxis, const TAxis *yAxis, const TAxis *zAxis)
1029{
1030 Rgl::BinRange_t xBins;
1031 Rgl::Range_t xRange;
1032
1033 FindAxisRange(xAxis, kFALSE, xBins, xRange);
1034
1035 Rgl::BinRange_t yBins;
1036 Rgl::Range_t yRange;
1037
1038 FindAxisRange(yAxis, kFALSE, yBins, yRange);
1039
1040 Rgl::BinRange_t zBins;
1041 Rgl::Range_t zRange;
1042 Double_t factor = 1.;
1043
1044 FindAxisRange(zAxis, kFALSE, zBins, zRange);
1045
1046 //Finds the maximum dimension and adjust scale coefficients
1047 const Double_t x = xRange.second - xRange.first;
1048 const Double_t y = yRange.second - yRange.first;
1049 const Double_t z = zRange.second - zRange.first;
1050
1051 if (!x || !y || !z) {
1052 Error("TGLPlotCoordinates::SetRangesCartesian", "Zero axis range.");
1053 return kFALSE;
1054 }
1055
1056 if (xRange != fXRange || yRange != fYRange || zRange != fZRange ||
1057 xBins != fXBins || yBins != fYBins || zBins != fZBins || fFactor != factor)
1058 {
1059 fModified = kTRUE;
1060 }
1061
1062 fXRange = xRange, fXBins = xBins, fYRange = yRange, fYBins = yBins, fZRange = zRange, fZBins = zBins;
1063 fFactor = factor;
1064
1065/* const Double_t maxDim = TMath::Max(TMath::Max(x, y), z);
1066 fXScale = maxDim / x;
1067 fYScale = maxDim / y;
1068 fZScale = maxDim / z;*/
1069
1070 fXScale = 1. / x;
1071 fYScale = 1. / y;
1072 fZScale = 1. / z;
1073
1074 fXRangeScaled.first = fXRange.first * fXScale, fXRangeScaled.second = fXRange.second * fXScale;
1075 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
1076 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
1077
1078 return kTRUE;
1079}
1080
1081////////////////////////////////////////////////////////////////////////////////
1082///Set bin ranges, ranges, etc.
1083
1085{
1086 Rgl::BinRange_t xBins;
1087 Rgl::Range_t phiRange;
1088 const TAxis *xAxis = hist->GetXaxis();
1089 FindAxisRange(xAxis, kFALSE, xBins, phiRange);
1090 if (xBins.second - xBins.first + 1 > 360) {
1091 Error("TGLPlotCoordinates::SetRangesPolar", "To many PHI sectors");
1092 return kFALSE;
1093 }
1094
1095 Rgl::BinRange_t yBins;
1096 Rgl::Range_t roRange;
1097 const TAxis *yAxis = hist->GetYaxis();
1098 FindAxisRange(yAxis, kFALSE, yBins, roRange);
1099
1100 Rgl::Range_t zRange;
1101 Double_t factor = 1.;
1102 if (!FindAxisRange(hist, fZLog, xBins, yBins, zRange, factor, kFALSE))
1103 {
1104 Error("TGLPlotCoordinates::SetRangesPolar",
1105 "Log scale is requested for Z, but maximum less or equal 0. (%f)", zRange.second);
1106 return kFALSE;
1107 }
1108
1109 const Double_t z = zRange.second - zRange.first;
1110 if (!z || !(phiRange.second - phiRange.first) || !(roRange.second - roRange.first)) {
1111 Error("TGLPlotCoordinates::SetRangesPolar", "Zero axis range.");
1112 return kFALSE;
1113 }
1114
1115 if (phiRange != fXRange || roRange != fYRange || zRange != fZRange ||
1116 xBins != fXBins || yBins != fYBins || fFactor != factor)
1117 {
1118 fModified = kTRUE;
1119 fXRange = phiRange, fXBins = xBins;
1120 fYRange = roRange, fYBins = yBins;
1121 fZRange = zRange;
1122 fFactor = factor;
1123 }
1124
1125 //const Double_t maxDim = TMath::Max(2., z);
1126 fXScale = 0.5;//maxDim / 2.;
1127 fYScale = 0.5;//maxDim / 2.;
1128 fZScale = 1. / z;//maxDim / z;
1129 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
1130 fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
1131 fZRangeScaled.first = fZRange.first * fZScale, fZRangeScaled.second = fZRange.second * fZScale;
1132
1133 return kTRUE;
1134}
1135
1136////////////////////////////////////////////////////////////////////////////////
1137/// Set ranges cylindrical.
1138
1140{
1141 Rgl::BinRange_t xBins, yBins;
1142 Rgl::Range_t angleRange, heightRange, radiusRange;
1143 const TAxis *xAxis = hist->GetXaxis();
1144 const TAxis *yAxis = hist->GetYaxis();
1145 Double_t factor = 1.;
1146
1147 FindAxisRange(xAxis, kFALSE, xBins, angleRange);
1148 if (xBins.second - xBins.first + 1 > 360) {
1149 Error("TGLPlotCoordinates::SetRangesCylindrical", "To many PHI sectors");
1150 return kFALSE;
1151 }
1152 if (!FindAxisRange(yAxis, fYLog, yBins, heightRange)) {
1153 Error("TGLPlotCoordinates::SetRangesCylindrical", "Cannot set Y axis to log scale");
1154 return kFALSE;
1155 }
1156 FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
1157
1158 const Double_t x = angleRange.second - angleRange.first;
1159 const Double_t y = heightRange.second - heightRange.first;
1160 const Double_t z = radiusRange.second - radiusRange.first;
1161
1162 if (!x || !y || !z) {
1163 Error("TGLPlotCoordinates::SetRangesCylindrical", "Zero axis range.");
1164 return kFALSE;
1165 }
1166
1167 if (angleRange != fXRange || heightRange != fYRange ||
1168 radiusRange != fZRange || xBins != fXBins ||
1169 yBins != fYBins || fFactor != factor)
1170 {
1171 fModified = kTRUE;
1172 fXRange = angleRange, fXBins = xBins;
1173 fYRange = heightRange, fYBins = yBins;
1174 fZRange = radiusRange;
1175 fFactor = factor;
1176 }
1177
1178 // const Double_t maxDim = TMath::Max(2., y);
1179 fXScale = 0.5;//maxDim / 2.;
1180 fYScale = 1. / y;//maxDim / y;
1181 fZScale = 0.5;//maxDim / 2.;
1182 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
1183 fYRangeScaled.first = fYRange.first * fYScale, fYRangeScaled.second = fYRange.second * fYScale;
1184 fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
1185
1186 return kTRUE;
1187}
1188
1189////////////////////////////////////////////////////////////////////////////////
1190/// Set ranges spherical.
1191
1193{
1194 Rgl::BinRange_t xBins;
1195 Rgl::Range_t phiRange;
1196 FindAxisRange(hist->GetXaxis(), kFALSE, xBins, phiRange);
1197 if (xBins.second - xBins.first + 1 > 360) {
1198 Error("TGLPlotCoordinates::SetRangesSpherical", "To many PHI sectors");
1199 return kFALSE;
1200 }
1201
1202 Rgl::BinRange_t yBins;
1203 Rgl::Range_t thetaRange;
1204 FindAxisRange(hist->GetYaxis(), kFALSE, yBins, thetaRange);
1205 if (yBins.second - yBins.first + 1 > 180) {
1206 Error("TGLPlotCoordinates::SetRangesSpherical", "To many THETA sectors");
1207 return kFALSE;
1208 }
1209
1210 Rgl::Range_t radiusRange;
1211 Double_t factor = 1.;
1212 FindAxisRange(hist, kFALSE, xBins, yBins, radiusRange, factor, kFALSE);
1213
1214 if (xBins != fXBins || yBins != fYBins ||
1215 phiRange != fXRange || thetaRange != fYRange ||
1216 radiusRange != fZRange || fFactor != factor)
1217 {
1218 fModified = kTRUE;
1219 fXBins = xBins;
1220 fYBins = yBins;
1221 fXRange = phiRange;
1222 fYRange = thetaRange,
1223 fZRange = radiusRange;
1224 fFactor = factor;
1225 }
1226
1227 fXScale = 0.5;
1228 fYScale = 0.5;
1229 fZScale = 0.5;
1230 fXRangeScaled.first = -fXScale, fXRangeScaled.second = fXScale;
1231 fYRangeScaled.first = -fYScale, fYRangeScaled.second = fYScale;
1232 fZRangeScaled.first = -fZScale, fZRangeScaled.second = fZScale;
1233
1234 return kTRUE;
1235}
1236
1237namespace {
1238
1239////////////////////////////////////////////////////////////////////////////////
1240/// Find minimal bin width.
1241
1242Double_t FindMinBinWidth(const TAxis *axis)
1243{
1244 Int_t currBin = axis->GetFirst();
1245 Double_t width = axis->GetBinWidth(currBin);
1246
1247 if (!axis->IsVariableBinSize())//equal bins
1248 return width;
1249
1250 ++currBin;
1251 //variable size bins
1252 for (const Int_t lastBin = axis->GetLast(); currBin <= lastBin; ++currBin)
1253 width = TMath::Min(width, axis->GetBinWidth(currBin));
1254
1255 return width;
1256}
1257
1258////////////////////////////////////////////////////////////////////////////////
1259///"Generic" function, can be used for X/Y/Z axis.
1260///[low edge of first ..... up edge of last]
1261///If log is true, at least up edge of last MUST be positive or function fails (1).
1262///If log is true and low edge is negative, try to find bin with positive low edge, bin number
1263///must be less or equal to last (2). If no such bin, function fails.
1264///When looking for a such bin, I'm trying to find value which is 0.01 of
1265///MINIMUM bin width (3) (if bins are equidimensional, first's bin width is OK).
1266///But even such lookup can fail, so, it's a stupid idea to have negative ranges
1267///and logarithmic scale :)
1268
1269Bool_t FindAxisRange(const TAxis *axis, Bool_t log, Rgl::BinRange_t &bins, Rgl::Range_t &range)
1270{
1271 bins.first = axis->GetFirst(), bins.second = axis->GetLast();
1272 range.first = axis->GetBinLowEdge(bins.first), range.second = axis->GetBinUpEdge(bins.second);
1273
1274 if (log) {
1275 if (range.second <= 0.)
1276 return kFALSE;//(1)
1277
1278 range.second = TMath::Log10(range.second);
1279
1280 if (range.first <= 0.) {//(2)
1281 Int_t bin = axis->FindFixBin(FindMinBinWidth(axis) * 0.01);//(3)
1282 //Overflow or something stupid.
1283 if (bin > bins.second)
1284 return kFALSE;
1285
1286 if (axis->GetBinLowEdge(bin) <= 0.) {
1287 ++bin;
1288 if (bin > bins.second)//Again, something stupid.
1289 return kFALSE;
1290 }
1291
1292 bins.first = bin;
1293 range.first = axis->GetBinLowEdge(bin);
1294 }
1295
1296 range.first = TMath::Log10(range.first);
1297 }
1298
1299 return kTRUE;
1300}
1301
1302////////////////////////////////////////////////////////////////////////////////
1303///First, look through hist to find minimum and maximum values.
1304
1305Bool_t FindAxisRange(const TH1 *hist, Bool_t logZ, const Rgl::BinRange_t &xBins,
1306 const Rgl::BinRange_t &yBins, Rgl::Range_t &zRange,
1307 Double_t &factor, Bool_t errors)
1308{
1309 const Bool_t minimum = hist->GetMinimumStored() != -1111;
1310 const Bool_t maximum = hist->GetMaximumStored() != -1111;
1311 const Double_t margin = gStyle->GetHistTopMargin();
1312
1313 zRange.second = hist->GetBinContent(hist->GetBin(xBins.first, yBins.first)), zRange.first = zRange.second;
1314 Double_t summ = 0.;
1315
1316 for (Int_t i = xBins.first; i <= xBins.second; ++i) {
1317 for (Int_t j = yBins.first; j <= yBins.second; ++j) {
1318 Double_t val = hist->GetBinContent(hist->GetBin(i, j));
1319 if (val > 0. && errors)
1320 val = TMath::Max(val, val + hist->GetCellError(i, j));
1321 zRange.second = TMath::Max(val, zRange.second);
1322 zRange.first = TMath::Min(val, zRange.first);
1323 summ += val;
1324 }
1325 }
1326
1327 if (hist->GetMaximumStored() != -1111)
1328 zRange.second = hist->GetMaximumStored();
1329 if (hist->GetMinimumStored() != -1111)
1330 zRange.first = hist->GetMinimumStored();
1331
1332 if (logZ && zRange.second <= 0.)
1333 return kFALSE;//cannot setup logarithmic scale
1334
1335 if (zRange.first >= zRange.second)
1336 zRange.first = 0.001 * zRange.second;
1337
1338 factor = hist->GetNormFactor() > 0. ? hist->GetNormFactor() : summ;
1339 if (summ) factor /= summ;
1340 if (!factor) factor = 1.;
1341 if (factor < 0.)
1342 Warning("TGLPlotPainter::ExtractAxisZInfo",
1343 "Negative factor, negative ranges - possible incorrect behavior");
1344
1345 zRange.second *= factor;
1346 zRange.first *= factor;
1347
1348 if (logZ) {
1349 if (zRange.first <= 0.)
1350 zRange.first = TMath::Min(1., 0.001 * zRange.second);
1351 zRange.first = TMath::Log10(zRange.first);
1352 if (!minimum)
1353 zRange.first += TMath::Log10(0.5);
1354 zRange.second = TMath::Log10(zRange.second);
1355 if (!maximum)
1356 zRange.second += TMath::Log10(2*(0.9/0.95));//This magic numbers are from THistPainter.
1357 return kTRUE;
1358 }
1359
1360 if (!maximum)
1361 zRange.second += margin * (zRange.second - zRange.first);
1362 if (!minimum) {
1364 zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
1365 else
1366 zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
1367 zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
1368 }
1369
1370 return kTRUE;
1371}
1372
1373////////////////////////////////////////////////////////////////////////////////
1374///First, look through hist to find minimum and maximum values.
1375
1376Bool_t FindAxisRange(TH2Poly *hist, Bool_t logZ, Rgl::Range_t &zRange)
1377{
1378 TList *bins = hist->GetBins();
1379 if (!bins || !bins->GetEntries()) {
1380 Error("FindAxisRange", "TH2Poly returned empty list of bins");
1381 return kFALSE;
1382 }
1383
1384 zRange.first = hist->GetMinimum();
1385 zRange.second = hist->GetMaximum();
1386
1387 if (zRange.first >= zRange.second)
1388 zRange.first = 0.001 * zRange.second;
1389
1390 if (logZ) {
1391 if (zRange.second < 1e-20) {
1392 Error("FindAxisRange", "Failed to switch Z axis to logarithmic scale");
1393 return kFALSE;
1394 }
1395
1396 if (zRange.first <= 0.)
1397 zRange.first = TMath::Min(1., 0.001 * zRange.second);
1398
1399 zRange.first = TMath::Log10(zRange.first);
1400 zRange.first += TMath::Log10(0.5);
1401 zRange.second = TMath::Log10(zRange.second);
1402 zRange.second += TMath::Log10(2 * (0.9 / 0.95));//These magic numbers come from THistPainter.
1403
1404 return kTRUE;
1405 }
1406
1407 const Double_t margin = gStyle->GetHistTopMargin();
1408 zRange.second += margin * (zRange.second - zRange.first);
1410 zRange.first >= 0 ? zRange.first = 0. : zRange.first -= margin * (zRange.second - zRange.first);
1411 else
1412 zRange.first >= 0 && zRange.first - margin * (zRange.second - zRange.first) <= 0 ?
1413 zRange.first = 0 : zRange.first -= margin * (zRange.second - zRange.first);
1414
1415 return kTRUE;
1416}
1417
1418}
1419
1420/** \class TGLBoxCut
1421\ingroup opengl
1422Used by plot-painters to determine the area of the plot that is cut away.
1423*/
1424
1426
1427////////////////////////////////////////////////////////////////////////////////
1428///Constructor.
1429
1431 : fXLength(0.),
1432 fYLength(0.),
1433 fZLength(0.),
1434 fPlotBox(box),
1435 fActive(kFALSE),
1436 fFactor(1.)
1437{
1438}
1439
1440////////////////////////////////////////////////////////////////////////////////
1441///Destructor.
1442
1444{
1445}
1446
1447////////////////////////////////////////////////////////////////////////////////
1448///Turn the box cut on/off.
1449///If it's on, it will be placed in front point of a plot.
1450
1452{
1453 fActive = !fActive;
1454
1455 if (fActive) {
1457 }
1458}
1459
1460////////////////////////////////////////////////////////////////////////////////
1461///Turn the box cut on/off.
1462
1464{
1465 if (a == fActive)
1466 return;
1467 TurnOnOff();
1468}
1469
1470////////////////////////////////////////////////////////////////////////////////
1471///Set geometry using plot's back box.
1472
1474{
1475 const Int_t frontPoint = fPlotBox->GetFrontPoint();
1476 const TGLVertex3 *box = fPlotBox->Get3DBox();
1477 const TGLVertex3 center((box[0].X() + box[1].X()) / 2, (box[0].Y() + box[2].Y()) / 2,
1478 (box[0].Z() + box[4].Z()) / 2);
1479 fXLength = fFactor * (box[1].X() - box[0].X());
1480 fYLength = fFactor * (box[2].Y() - box[0].Y());
1481 fZLength = fFactor * (box[4].Z() - box[0].Z());
1482
1483 switch(frontPoint){
1484 case 0:
1485 fCenter.X() = box[0].X();
1486 fCenter.Y() = box[0].Y();
1487 break;
1488 case 1:
1489 fCenter.X() = box[1].X();
1490 fCenter.Y() = box[0].Y();
1491 break;
1492 case 2:
1493 fCenter.X() = box[2].X();
1494 fCenter.Y() = box[2].Y();
1495 break;
1496 case 3:
1497 fCenter.X() = box[0].X();
1498 fCenter.Y() = box[2].Y();
1499 break;
1500 }
1501
1502 fCenter.Z() = box[0].Z() * 0.5 + box[4].Z() * 0.5;
1503 AdjustBox();
1504}
1505
1506////////////////////////////////////////////////////////////////////////////////
1507///Draw cut as a semi-transparent box.
1508
1509void TGLBoxCut::DrawBox(Bool_t selectionPass, Int_t selected)const
1510{
1511 if (!selectionPass) {
1512 glDisable(GL_LIGHTING);
1513 glLineWidth(3.f);
1514
1515 selected == TGLPlotPainter::kXAxis ? glColor3d(1., 1., 0.) : glColor3d(1., 0., 0.);
1516 glBegin(GL_LINES);
1517 glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1518 glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1519 glEnd();
1520
1521 selected == TGLPlotPainter::kYAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 1., 0.);
1522 glBegin(GL_LINES);
1523 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
1524 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
1525 glEnd();
1526
1527 selected == TGLPlotPainter::kZAxis ? glColor3d(1., 1., 0.) : glColor3d(0., 0., 1.);
1528 glBegin(GL_LINES);
1529 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
1530 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
1531 glEnd();
1532
1533 glLineWidth(1.f);
1534 glEnable(GL_LIGHTING);
1535
1536 GLboolean oldBlendState = kFALSE;
1537 glGetBooleanv(GL_BLEND, &oldBlendState);
1538
1539 if (!oldBlendState)
1540 glEnable(GL_BLEND);
1541
1542 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1543
1544
1545 const Float_t diffuseColor[] = {0.f, 0.f, 1.f, 0.1f};
1546 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseColor);
1547
1548 Rgl::DrawBoxFront(fXRange.first, fXRange.second, fYRange.first, fYRange.second,
1549 fZRange.first, fZRange.second, fPlotBox->GetFrontPoint());
1550
1551 if (!oldBlendState)
1552 glDisable(GL_BLEND);
1553 } else {
1554 glLineWidth(5.f);
1556 glBegin(GL_LINES);
1557 glVertex3d(fXRange.first, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1558 glVertex3d(fXRange.second, (fYRange.first + fYRange.second) / 2, (fZRange.first + fZRange.second) / 2);
1559 glEnd();
1560
1562 glBegin(GL_LINES);
1563 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.first, (fZRange.first + fZRange.second) / 2);
1564 glVertex3d((fXRange.first + fXRange.second) / 2, fYRange.second, (fZRange.first + fZRange.second) / 2);
1565 glEnd();
1566
1568 glBegin(GL_LINES);
1569 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.first);
1570 glVertex3d((fXRange.first + fXRange.second) / 2, (fYRange.first + fYRange.second) / 2, fZRange.second);
1571 glEnd();
1572 glLineWidth(1.f);
1573 }
1574}
1575
1576////////////////////////////////////////////////////////////////////////////////
1577///Start cut's movement
1578
1580{
1581 fMousePos.fX = px;
1582 fMousePos.fY = py;
1583}
1584
1585////////////////////////////////////////////////////////////////////////////////
1586///Move box cut along selected direction.
1587
1589{
1590 Double_t mv[16] = {0.};
1591 glGetDoublev(GL_MODELVIEW_MATRIX, mv);
1592 Double_t pr[16] = {0.};
1593 glGetDoublev(GL_PROJECTION_MATRIX, pr);
1594 Int_t vp[4] = {0};
1595 glGetIntegerv(GL_VIEWPORT, vp);
1596 Double_t winVertex[3] = {0.};
1597
1598 switch(axisID){
1600 gluProject(fCenter.X(), 0., 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1601 break;
1603 gluProject(0., fCenter.Y(), 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1604 break;
1606 gluProject(0., 0., fCenter.Z(), mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1607 break;
1608 }
1609
1610 winVertex[0] += px - fMousePos.fX;
1611 winVertex[1] += py - fMousePos.fY;
1612 Double_t newPoint[3] = {0.};
1613 gluUnProject(winVertex[0], winVertex[1], winVertex[2], mv, pr, vp,
1614 newPoint, newPoint + 1, newPoint + 2);
1615
1616 const TGLVertex3 *box = fPlotBox->Get3DBox();
1617
1618 switch(axisID){
1620 if (newPoint[0] >= box[1].X() + 0.4 * fXLength)
1621 break;
1622 if (newPoint[0] <= box[0].X() - 0.4 * fXLength)
1623 break;
1624 fCenter.X() = newPoint[0];
1625 break;
1627 if (newPoint[1] >= box[2].Y() + 0.4 * fYLength)
1628 break;
1629 if (newPoint[1] <= box[0].Y() - 0.4 * fYLength)
1630 break;
1631 fCenter.Y() = newPoint[1];
1632 break;
1634 if (newPoint[2] >= box[4].Z() + 0.4 * fZLength)
1635 break;
1636 if (newPoint[2] <= box[0].Z() - 0.4 * fZLength)
1637 break;
1638 fCenter.Z() = newPoint[2];
1639 break;
1640 }
1641
1642 fMousePos.fX = px;
1643 fMousePos.fY = py;
1644
1645 AdjustBox();
1646}
1647
1648////////////////////////////////////////////////////////////////////////////////
1649///Box cut is limited by plot's sizes.
1650
1652{
1653 const TGLVertex3 *box = fPlotBox->Get3DBox();
1654
1655 fXRange.first = fCenter.X() - fXLength / 2.;
1656 fXRange.second = fCenter.X() + fXLength / 2.;
1657 fYRange.first = fCenter.Y() - fYLength / 2.;
1658 fYRange.second = fCenter.Y() + fYLength / 2.;
1659 fZRange.first = fCenter.Z() - fZLength / 2.;
1660 fZRange.second = fCenter.Z() + fZLength / 2.;
1661
1662 fXRange.first = TMath::Max(fXRange.first, box[0].X());
1663 fXRange.first = TMath::Min(fXRange.first, box[1].X());
1664 fXRange.second = TMath::Min(fXRange.second, box[1].X());
1665 fXRange.second = TMath::Max(fXRange.second, box[0].X());
1666
1667 fYRange.first = TMath::Max(fYRange.first, box[0].Y());
1668 fYRange.first = TMath::Min(fYRange.first, box[2].Y());
1669 fYRange.second = TMath::Min(fYRange.second, box[2].Y());
1670 fYRange.second = TMath::Max(fYRange.second, box[0].Y());
1671
1672 fZRange.first = TMath::Max(fZRange.first, box[0].Z());
1673 fZRange.first = TMath::Min(fZRange.first, box[4].Z());
1674 fZRange.second = TMath::Min(fZRange.second, box[4].Z());
1675 fZRange.second = TMath::Max(fZRange.second, box[0].Z());
1676}
1677
1678////////////////////////////////////////////////////////////////////////////////
1679///Check, if box defined by xmin/xmax etc. is in cut.
1680
1682 Double_t zMin, Double_t zMax)const
1683{
1684 if (((xMin >= fXRange.first && xMin < fXRange.second) || (xMax > fXRange.first && xMax <= fXRange.second)) &&
1685 ((yMin >= fYRange.first && yMin < fYRange.second) || (yMax > fYRange.first && yMax <= fYRange.second)) &&
1686 ((zMin >= fZRange.first && zMin < fZRange.second) || (zMax > fZRange.first && zMax <= fZRange.second)))
1687 return kTRUE;
1688 return kFALSE;
1689}
1690
1691
1692/** \class TGLTH3Slice
1693\ingroup opengl
1694A slice of a TH3.
1695*/
1696
1698
1699////////////////////////////////////////////////////////////////////////////////
1700/// Constructor.
1701
1703 const TGLPlotBox *box, ESliceAxis axis)
1704 : TNamed(name, name),
1705 fAxisType(axis),
1706 fAxis(0),
1707 fCoord(coord),
1708 fBox(box),
1709 fSliceWidth(1),
1710 fHist(hist),
1711 fF3(0)
1712{
1714}
1715
1716////////////////////////////////////////////////////////////////////////////////
1717/// Constructor.
1718
1719TGLTH3Slice::TGLTH3Slice(const TString &name, const TH3 *hist, const TF3 *fun, const TGLPlotCoordinates *coord,
1720 const TGLPlotBox *box, ESliceAxis axis)
1721 : TNamed(name, name),
1722 fAxisType(axis),
1723 fAxis(0),
1724 fCoord(coord),
1725 fBox(box),
1726 fSliceWidth(1),
1727 fHist(hist),
1728 fF3(fun)
1729{
1731}
1732
1733////////////////////////////////////////////////////////////////////////////////
1734/// Set Slice width.
1735
1737{
1738 if (width <= 0)
1739 return;
1740
1741 if (fAxis->GetLast() - fAxis->GetFirst() + 1 <= width)
1742 fSliceWidth = fAxis->GetLast() - fAxis->GetFirst() + 1;
1743 else
1745}
1746
1747////////////////////////////////////////////////////////////////////////////////
1748/// Draw slice.
1749
1751{
1752 Int_t bin = 0;
1753 for (Int_t i = fAxis->GetFirst(), e = fAxis->GetLast(); i <= e; ++i) {
1754 if (pos >= fAxis->GetBinLowEdge(i) && pos <= fAxis->GetBinUpEdge(i)) {
1755 bin = i;
1756 break;
1757 }
1758 }
1759
1760 if (bin) {
1761 Int_t low = 1, up = 2;
1762 if (bin - fSliceWidth + 1 >= fAxis->GetFirst()) {
1763 low = bin - fSliceWidth + 1;
1764 up = bin + 1;
1765 } else {
1766 low = fAxis->GetFirst();
1767 up = bin + (fSliceWidth - (bin - fAxis->GetFirst() + 1)) + 1;
1768 }
1769
1770 if (!fF3)
1771 FindMinMax(low, up);
1772
1773 if (!PreparePalette())
1774 return;
1775
1776 PrepareTexCoords(pos, low, up);
1777
1778 fPalette.EnableTexture(GL_REPLACE);
1779 const TGLDisableGuard lightGuard(GL_LIGHTING);
1780 DrawSliceTextured(pos);
1782 //highlight bins in a slice.
1783 //DrawSliceFrame(low, up);
1784 }
1785}
1786
1787////////////////////////////////////////////////////////////////////////////////
1788/// Find minimum and maximum for slice.
1789
1790void TGLTH3Slice::FindMinMax(Int_t /*low*/, Int_t /*up*/)const
1791{
1792 /* fMinMax.first = 0.;
1793
1794 switch (fAxisType) {
1795 case kXOZ:
1796 for (Int_t level = low; level < up; ++ level)
1797 fMinMax.first += fHist->GetBinContent(fCoord->GetFirstXBin(), level, fCoord->GetFirstZBin());
1798 fMinMax.second = fMinMax.first;
1799 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1800 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1801 Double_t val = 0.;
1802 for (Int_t level = low; level < up; ++ level)
1803 val += fHist->GetBinContent(i, level, j);
1804 fMinMax.second = TMath::Max(fMinMax.second, val);
1805 fMinMax.first = TMath::Min(fMinMax.first, val);
1806 }
1807 }
1808 break;
1809 case kYOZ:
1810 for (Int_t level = low; level < up; ++ level)
1811 fMinMax.first += fHist->GetBinContent(level, fCoord->GetFirstYBin(), fCoord->GetFirstZBin());
1812 fMinMax.second = fMinMax.first;
1813 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1814 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i <= ei; ++i, ++it) {
1815 Double_t val = 0.;
1816 for (Int_t level = low; level < up; ++ level)
1817 val += fHist->GetBinContent(level, i, j);
1818 fMinMax.second = TMath::Max(fMinMax.second, val);
1819 fMinMax.first = TMath::Min(fMinMax.first, val);
1820 }
1821 }
1822 break;
1823 case kXOY:
1824 for (Int_t level = low; level < up; ++ level)
1825 fMinMax.first += fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin(), level);
1826 fMinMax.second = fMinMax.first;
1827 for (Int_t i = fCoord->GetFirstXBin(), ir = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++ir) {
1828 for (Int_t j = fCoord->GetFirstYBin(), jr = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jr) {
1829 Double_t val = 0.;
1830 for (Int_t level = low; level < up; ++ level)
1831 val += fHist->GetBinContent(i, j, level);
1832 fMinMax.second = TMath::Max(fMinMax.second, val);
1833 fMinMax.first = TMath::Min(fMinMax.first, val);
1834 }
1835 }
1836 break;
1837 }*/
1838}
1839
1840////////////////////////////////////////////////////////////////////////////////
1841///Initialize color palette.
1842
1844{
1845 UInt_t paletteSize = ((TH1 *)fHist)->GetContour();
1846 if (!paletteSize && !(paletteSize = gStyle->GetNumberContours()))
1847 paletteSize = 20;
1848
1849 return fPalette.GeneratePalette(paletteSize, fMinMax);
1850}
1851
1852////////////////////////////////////////////////////////////////////////////////
1853/// Prepare TexCoords.
1854
1856{
1857 switch (fAxisType) {
1858 case kXOZ:
1859 fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNZBins());
1860 fTexCoords.SetRowLen(fCoord->GetNXBins());
1861 if (!fF3) {
1862
1863 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1864 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1865 Double_t val = 0.;
1866 for (Int_t level = low; level < up; ++ level)
1867 val += fHist->GetBinContent(i, level, j);
1868 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1869 }
1870 }
1871 } else {
1872 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1873 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1875 if (val > fMinMax.second)
1876 val = fMinMax.second;
1877 else if (val < fMinMax.first)
1878 val = fMinMax.first;
1879 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1880 }
1881 }
1882 }
1883 break;
1884 case kYOZ:
1885 fTexCoords.resize(fCoord->GetNYBins() * fCoord->GetNZBins());
1886 fTexCoords.SetRowLen(fCoord->GetNYBins());
1887 if (!fF3) {
1888 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1889 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i <= ei; ++i, ++it) {
1890 Double_t val = 0.;
1891 for (Int_t level = low; level < up; ++ level)
1892 val += fHist->GetBinContent(level, i, j);
1893 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1894 }
1895 }
1896 } else {
1897 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
1898 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1900 if (val > fMinMax.second)
1901 val = fMinMax.second;
1902 else if (val < fMinMax.first)
1903 val = fMinMax.first;
1904 fTexCoords[jt][it] = fPalette.GetTexCoord(val);
1905 }
1906 }
1907 }
1908 break;
1909 case kXOY:
1910 fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNYBins());
1911 fTexCoords.SetRowLen(fCoord->GetNYBins());
1912 if (!fF3) {
1913 for (Int_t i = fCoord->GetFirstXBin(), ir = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++ir) {
1914 for (Int_t j = fCoord->GetFirstYBin(), jr = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jr) {
1915 Double_t val = 0.;
1916 for (Int_t level = low; level < up; ++ level)
1917 val += fHist->GetBinContent(i, j, level);
1918 fTexCoords[ir][jr] = fPalette.GetTexCoord(val);
1919 }
1920 }
1921 } else {
1922 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
1923 for (Int_t j = fCoord->GetFirstYBin(), jt = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jt) {
1925 if (val > fMinMax.second)
1926 val = fMinMax.second;
1927 else if (val < fMinMax.first)
1928 val = fMinMax.first;
1929 fTexCoords[it][jt] = fPalette.GetTexCoord(val);
1930 }
1931 }
1932
1933 }
1934 break;
1935 }
1936}
1937
1938////////////////////////////////////////////////////////////////////////////////
1939/// Draw slice textured.
1940
1942{
1943 const Double_t xScale = fCoord->GetXScale();
1944 const Double_t yScale = fCoord->GetYScale();
1945 const Double_t zScale = fCoord->GetZScale();
1946 const TAxis *xA = fHist->GetXaxis();
1947 const TAxis *yA = fHist->GetYaxis();
1948 const TAxis *zA = fHist->GetZaxis();
1949
1950 switch (fAxisType) {
1951 case kXOZ:
1952 pos *= yScale;
1953 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
1954 for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i < ei; ++i, ++it) {
1955 const Double_t xMin = xA->GetBinCenter(i) * xScale;
1956 const Double_t xMax = xA->GetBinCenter(i + 1) * xScale;
1957 const Double_t zMin = zA->GetBinCenter(j) * zScale;
1958 const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
1959 glBegin(GL_POLYGON);
1960 glTexCoord1d(fTexCoords[jt][it]);
1961 glVertex3d(xMin, pos, zMin);
1962 glTexCoord1d(fTexCoords[jt + 1][it]);
1963 glVertex3d(xMin, pos, zMax);
1964 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
1965 glVertex3d(xMax, pos, zMax);
1966 glTexCoord1d(fTexCoords[jt][it + 1]);
1967 glVertex3d(xMax, pos, zMin);
1968 glEnd();
1969 }
1970 }
1971 break;
1972 case kYOZ:
1973 pos *= xScale;
1974 for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
1975 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
1976 const Double_t yMin = yA->GetBinCenter(i) * yScale;
1977 const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
1978 const Double_t zMin = zA->GetBinCenter(j) * zScale;
1979 const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
1980 glBegin(GL_POLYGON);
1981 glTexCoord1d(fTexCoords[jt][it]);
1982 glVertex3d(pos, yMin, zMin);
1983 glTexCoord1d(fTexCoords[jt][it + 1]);
1984 glVertex3d(pos, yMax, zMin);
1985 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
1986 glVertex3d(pos, yMax, zMax);
1987 glTexCoord1d(fTexCoords[jt + 1][it]);
1988 glVertex3d(pos, yMin, zMax);
1989 glEnd();
1990 }
1991 }
1992 break;
1993 case kXOY:
1994 pos *= zScale;
1995 for (Int_t j = fCoord->GetFirstXBin(), jt = 0, ej = fCoord->GetLastXBin(); j < ej; ++j, ++jt) {
1996 for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
1997 const Double_t xMin = xA->GetBinCenter(j) * xScale;
1998 const Double_t xMax = xA->GetBinCenter(j + 1) * xScale;
1999 const Double_t yMin = yA->GetBinCenter(i) * yScale;
2000 const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
2001 glBegin(GL_POLYGON);
2002 glTexCoord1d(fTexCoords[jt + 1][it]);
2003 glVertex3d(xMax, yMin, pos);
2004 glTexCoord1d(fTexCoords[jt + 1][it + 1]);
2005 glVertex3d(xMax, yMax, pos);
2006 glTexCoord1d(fTexCoords[jt][it + 1]);
2007 glVertex3d(xMin, yMax, pos);
2008 glTexCoord1d(fTexCoords[jt][it]);
2009 glVertex3d(xMin, yMin, pos);
2010 glEnd();
2011 }
2012 }
2013 break;
2014 }
2015}
2016
2017namespace {
2018
2019////////////////////////////////////////////////////////////////////////////////
2020
2021void DrawBoxOutline(Double_t xMin, Double_t xMax, Double_t yMin,
2022 Double_t yMax, Double_t zMin, Double_t zMax)
2023{
2024 glBegin(GL_LINE_LOOP);
2025 glVertex3d(xMin, yMin, zMin);
2026 glVertex3d(xMax, yMin, zMin);
2027 glVertex3d(xMax, yMax, zMin);
2028 glVertex3d(xMin, yMax, zMin);
2029 glEnd();
2030
2031 glBegin(GL_LINE_LOOP);
2032 glVertex3d(xMin, yMin, zMax);
2033 glVertex3d(xMax, yMin, zMax);
2034 glVertex3d(xMax, yMax, zMax);
2035 glVertex3d(xMin, yMax, zMax);
2036 glEnd();
2037
2038 glBegin(GL_LINES);
2039 glVertex3d(xMin, yMin, zMin);
2040 glVertex3d(xMin, yMin, zMax);
2041 glVertex3d(xMax, yMin, zMin);
2042 glVertex3d(xMax, yMin, zMax);
2043 glVertex3d(xMax, yMax, zMin);
2044 glVertex3d(xMax, yMax, zMax);
2045 glVertex3d(xMin, yMax, zMin);
2046 glVertex3d(xMin, yMax, zMax);
2047 glEnd();
2048}
2049
2050}
2051
2052////////////////////////////////////////////////////////////////////////////////
2053/// Draw slice frame.
2054
2056{
2057 glColor3d(1., 0., 0.);
2058 const TGLVertex3 *box = fBox->Get3DBox();
2059
2060 switch (fAxisType) {
2061 case kXOZ:
2062 DrawBoxOutline(box[0].X(), box[1].X(),
2064 fAxis->GetBinUpEdge(up - 1) * fCoord->GetYScale(),
2065 box[0].Z(), box[4].Z());
2066 break;
2067 case kYOZ:
2068 DrawBoxOutline(fAxis->GetBinLowEdge(low) * fCoord->GetXScale(),
2069 fAxis->GetBinUpEdge(up - 1) * fCoord->GetXScale(),
2070 box[0].Y(), box[2].Y(),
2071 box[0].Z(), box[4].Z());
2072 break;
2073 case kXOY:
2074 DrawBoxOutline(box[0].X(), box[1].X(),
2075 box[0].Y(), box[2].Y(),
2077 fAxis->GetBinUpEdge(up - 1) * fCoord->GetZScale());
2078 break;
2079 }
2080}
2081
2082namespace Rgl {
2083
2084////////////////////////////////////////////////////////////////////////////////
2085
2087 : fPainter(painter)
2088{
2090 const Double_t center[] = {(box[0].X() + box[1].X()) / 2,
2091 (box[0].Y() + box[2].Y()) / 2,
2092 (box[0].Z() + box[4].Z()) / 2};
2093
2095 glTranslated(-center[0], -center[1], -center[2]);
2096}
2097
2098////////////////////////////////////////////////////////////////////////////////
2099
2101{
2103}
2104
2105namespace
2106{
2107
2108const Double_t lr = 0.85;
2109const Double_t rr = 0.9;
2110
2111}
2112
2113////////////////////////////////////////////////////////////////////////////////
2114///Draw. Palette.
2115
2116void DrawPalette(const TGLPlotCamera * camera, const TGLLevelPalette & palette)
2117{
2118 const TGLDisableGuard light(GL_LIGHTING);
2119 const TGLDisableGuard depth(GL_DEPTH_TEST);
2120 const TGLEnableGuard blend(GL_BLEND);
2121
2122 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2123
2124 glMatrixMode(GL_PROJECTION);
2125 glLoadIdentity();
2126 glOrtho(0, camera->GetWidth(), 0, camera->GetHeight(), -1., 1.);
2127
2128 glMatrixMode(GL_MODELVIEW);
2129 glLoadIdentity();
2130
2131 const Double_t leftX = camera->GetWidth() * lr;
2132 const Double_t rightX = camera->GetWidth() * rr;
2133 const Double_t margin = 0.1 * camera->GetHeight();
2134 const Double_t h = (camera->GetHeight() * 0.8) / palette.GetPaletteSize();
2135
2136 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2137 glBegin(GL_POLYGON);
2138 const UChar_t * color = palette.GetColour(i);
2139 glColor4ub(color[0], color[1], color[2], 150);
2140 glVertex2d(leftX, margin + i * h);
2141 glVertex2d(rightX, margin + i * h);
2142 glVertex2d(rightX, margin + (i + 1) * h);
2143 glVertex2d(leftX, margin + (i + 1) * h);
2144 glEnd();
2145 }
2146
2147 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
2148 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
2149 glColor4d(0., 0., 0., 0.5);
2150
2151 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2152 glBegin(GL_LINE_LOOP);
2153 glVertex2d(leftX, margin + i * h);
2154 glVertex2d(rightX, margin + i * h);
2155 glVertex2d(rightX, margin + (i + 1) * h);
2156 glVertex2d(leftX, margin + (i + 1) * h);
2157 glEnd();
2158 }
2159
2160}
2161
2162////////////////////////////////////////////////////////////////////////////////
2163///Draw. Palette.
2164
2165void DrawPalette(const TGLPlotCamera * camera, const TGLLevelPalette & palette,
2166 const std::vector<Double_t> & levels)
2167{
2168 const TGLDisableGuard light(GL_LIGHTING);
2169 const TGLDisableGuard depth(GL_DEPTH_TEST);
2170 const TGLEnableGuard blend(GL_BLEND);
2171
2172 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2173
2174 glMatrixMode(GL_PROJECTION);
2175 glLoadIdentity();
2176 glOrtho(0, camera->GetWidth(), 0, camera->GetHeight(), -1., 1.);
2177
2178 glMatrixMode(GL_MODELVIEW);
2179 glLoadIdentity();
2180
2181 const Double_t leftX = camera->GetWidth() * lr;
2182 const Double_t rightX = camera->GetWidth() * rr;
2183 const Double_t margin = 0.1 * camera->GetHeight();
2184 const Double_t h = (camera->GetHeight() * 0.8);
2185 const Double_t range = levels.back() - levels.front();
2186
2187 const UChar_t opacity = 200;
2188
2189 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2190 const Double_t yMin = margin + (levels[i] - levels.front()) / range * h;
2191 const Double_t yMax = margin + (levels[i + 1] - levels.front()) / range * h;
2192 glBegin(GL_POLYGON);
2193 const UChar_t * color = palette.GetColour(i);
2194 glColor4ub(color[0], color[1], color[2], opacity);
2195 glVertex2d(leftX, yMin);
2196 glVertex2d(rightX, yMin);
2197 glVertex2d(rightX, yMax);
2198 glVertex2d(leftX, yMax);
2199 glEnd();
2200 }
2201
2202 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
2203 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
2204 glColor4d(0., 0., 0., 0.5);
2205
2206 for (Int_t i = 0, e = palette.GetPaletteSize(); i < e; ++i) {
2207 const Double_t yMin = (levels[i] - levels.front()) / range * h;
2208 const Double_t yMax = (levels[i + 1] - levels.front()) / range * h;
2209
2210 glBegin(GL_LINE_LOOP);
2211 glVertex2d(leftX, margin + yMin);
2212 glVertex2d(rightX, margin + yMin);
2213 glVertex2d(rightX, margin + yMax);
2214 glVertex2d(leftX, margin + yMax);
2215 glEnd();
2216 }
2217
2218}
2219
2220////////////////////////////////////////////////////////////////////////////////
2221
2222void DrawPaletteAxis(const TGLPlotCamera * camera, const Range_t & minMax, Bool_t logZ)
2223{
2224 UInt_t pixelW = camera->GetWidth();
2225 UInt_t pixelH = camera->GetHeight();
2226
2229 if (scale > 1.) {
2230 pixelW = UInt_t(pixelW / scale);
2231 pixelH = UInt_t(pixelH / scale);
2232 }
2233
2234 const Double_t x = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw() + rr * pixelW));
2235 const Double_t yMin = gPad->AbsPixeltoY(Int_t(gPad->GetWh() - (pixelH * 0.1
2236 + gPad->GetYlowNDC() * gPad->GetWh())));
2237 const Double_t yMax = gPad->AbsPixeltoY(Int_t(gPad->GetWh() - (pixelH * 0.9
2238 + gPad->GetYlowNDC() * gPad->GetWh())));
2239
2240 Double_t zMin = minMax.first;
2241 Double_t zMax = minMax.second;
2242
2243 if (logZ) {
2244 zMin = TMath::Power(10, zMin);
2245 zMax = TMath::Power(10, zMax);
2246 }
2247
2248 //Now, some stupid magic, to force ROOT's painting machine work as I want, not as it wants.
2249 const Bool_t logX = gPad->GetLogx();
2250 gPad->SetLogx(kFALSE);
2251 const Bool_t logY = gPad->GetLogy();
2252 gPad->SetLogy(kFALSE);
2253
2254 TGaxis axisPainter(x, yMin, x, yMax, zMin, zMax, 510, logZ ? "G" : "");
2255 axisPainter.Paint();
2256
2257 gPad->SetLogx(logX);
2258 gPad->SetLogy(logY);
2259}
2260
2261//Constant for TGLH2PolyPainter.
2263
2264}
2265
#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:19
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:75
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
TAxis * GetZaxis()
Definition TH1.h:324
virtual Double_t GetMinimumStored() const
Definition TH1.h:291
virtual Double_t GetNormFactor() const
Definition TH1.h:299
TAxis * GetXaxis()
Definition TH1.h:322
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:4932
TAxis * GetYaxis()
Definition TH1.h:323
virtual Double_t GetCellError(Int_t binx, Int_t biny) const
Definition TH1.h:431
virtual Double_t GetMaximumStored() const
Definition TH1.h:287
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5032
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:975
Double_t GetMaximum() const
Returns the maximum value of the histogram.
Definition TH2Poly.cxx:927
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:97
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
Definition first.py:1
static void output()