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