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