ROOT  6.06/09
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
43 Base class for plot-painters that provide GL rendering of various
44 2D 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 
156  fHighColor = kFALSE;
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.
175  fCamera->SetCamera();
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 
203  if (fCoord && fCoord->GetCoordType() == kGLCartesian && fDrawAxes) {
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)
222  DrawPaletteAxis();
223 
224  if (!old)
225  gPad->ResetBit(TGraph::kClipFrame);
226  } else if(fDrawPalette)
227  DrawPaletteAxis();
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 |
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 
286  fCamera->SetCamera();
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);
475  DrawSectionXOZ();
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);
518  DrawSectionYOZ();
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);
561  DrawSectionXOY();
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
622 Helper class for plot-painters holding information about axis
623 ranges, 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) {
658  fModified = kTRUE;
659  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;
679  fModified = kTRUE;
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;
699  fModified = kTRUE;
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;
719  fModified = kTRUE;
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 
895 namespace {
896 
897 Bool_t FindAxisRange(const TAxis *axis, Bool_t log, Rgl::BinRange_t &bins, Rgl::Range_t &range);
898 Bool_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 
902 Bool_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  {
953  fModified = kTRUE;
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 
1015  fXScale = Rgl::gH2PolyScaleXY / x;
1016  fYScale = Rgl::gH2PolyScaleXY / y;
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 
1030 Bool_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 
1239 namespace {
1240 
1241 ////////////////////////////////////////////////////////////////////////////////
1242 /// Find minimal bin width.
1243 
1244 Double_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 
1271 Bool_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 
1307 Bool_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) {
1365  if (gStyle->GetHistMinimumZero())
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 
1378 Bool_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);
1411  if (gStyle->GetHistMinimumZero())
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
1424 Used 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) {
1458  ResetBoxGeometry();
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 
1511 void 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 
1590 void TGLBoxCut::MoveBox(Int_t px, Int_t py, Int_t axisID)
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){
1601  case TGLPlotPainter::kXAxis :
1602  gluProject(fCenter.X(), 0., 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1603  break;
1604  case TGLPlotPainter::kYAxis :
1605  gluProject(0., fCenter.Y(), 0., mv, pr, vp, &winVertex[0], &winVertex[1], &winVertex[2]);
1606  break;
1607  case TGLPlotPainter::kZAxis :
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){
1621  case TGLPlotPainter::kXAxis :
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;
1628  case TGLPlotPainter::kYAxis :
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;
1635  case TGLPlotPainter::kZAxis :
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
1696 A slice of a TH3.
1697 */
1698 
1700 
1701 ////////////////////////////////////////////////////////////////////////////////
1702 /// Constructor.
1703 
1704 TGLTH3Slice::TGLTH3Slice(const TString &name, const TH3 *hist, const TGLPlotCoordinates *coord,
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 {
1715  fAxis = fAxisType == kXOZ ? fHist->GetYaxis() : fAxisType == kYOZ ? fHist->GetXaxis() : fHist->GetZaxis();
1716 }
1717 
1718 ////////////////////////////////////////////////////////////////////////////////
1719 /// Constructor.
1720 
1721 TGLTH3Slice::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
1746  fSliceWidth = width;
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 
1792 void 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) {
1876  Double_t val = fF3->Eval(fHist->GetXaxis()->GetBinCenter(i), pos, fHist->GetZaxis()->GetBinCenter(j));
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) {
1901  Double_t val = fF3->Eval(pos, fHist->GetYaxis()->GetBinCenter(i), fHist->GetZaxis()->GetBinCenter(j));
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) {
1926  Double_t val = fF3->Eval(fHist->GetXaxis()->GetBinCenter(i), fHist->GetYaxis()->GetBinCenter(j), pos);
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 
2019 namespace {
2020 
2021 ////////////////////////////////////////////////////////////////////////////////
2022 
2023 void 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(),
2065  fAxis->GetBinLowEdge(low) * fCoord->GetYScale(),
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(),
2078  fAxis->GetBinLowEdge(low) * fCoord->GetZScale(),
2079  fAxis->GetBinUpEdge(up - 1) * fCoord->GetZScale());
2080  break;
2081  }
2082 }
2083 
2084 namespace Rgl {
2085 
2086 ////////////////////////////////////////////////////////////////////////////////
2087 
2089  : fPainter(painter)
2090 {
2091  const TGLVertex3 *box = fPainter->fBackBox.Get3DBox();
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 
2107 namespace
2108 {
2109 
2110 const Double_t lr = 0.85;
2111 const Double_t rr = 0.9;
2112 
2113 }
2114 
2115 ////////////////////////////////////////////////////////////////////////////////
2116 ///Draw. Palette.
2117 
2118 void 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 
2167 void 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 
2224 void 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 
2230  const Float_t scale = TGLUtil::GetScreenScalingFactor();
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 
void ResetBoxGeometry()
Set geometry using plot's back box.
for(Int_t i=0;i< n;i++)
Definition: legend1.C:18
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:429
virtual Int_t GetEntries() const
Definition: TCollection.h:92
void SetRowLen(Int_t len)
Definition: TGLUtil.h:1168
Camera for TGLPlotPainter and sub-classes.
Definition: TGLPlotCamera.h:21
virtual void DrawPaletteAxis() const
Draw. Palette. Axis.
void ReadColorBuffer(Int_t width, Int_t height)
Read color buffer.
Definition: TGLUtil.cxx:2769
PlotTranslation(const TGLPlotPainter *painter)
void DrawQuadFilled(const TGLVertex3 &v0, const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVector3 &normal)
Draw quad face.
Definition: TGLUtil.cxx:2920
Int_t GetNXBins() const
Number of X bins.
const Rgl::Range_t & GetZRangeScaled() const
Scaled range.
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4629
void MoveBox(Int_t px, Int_t py, Int_t axisID)
Move box cut along selected direction.
const Double_t * v1
Definition: TArcBall.cxx:33
Bool_t PreparePalette() const
Initialize color palette.
Double_t GetXLength() const
X length.
const Float_t gNullEmission[]
Definition: TGLUtil.cxx:2814
float Float_t
Definition: RtypesCore.h:53
std::pair< Double_t, Double_t > Range_t
Definition: TGLUtil.h:1197
Int_t GetLastXBin() const
Int_t GetY() const
viewport[1]
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
const TF3 * fF3
Double_t fYOZSectionPos
unsigned short UShort_t
Definition: RtypesCore.h:36
GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, GLint viewport[4], GLint format, GLint sort, GLint options, GLint colormode, GLint colorsize, GL2PSrgba *colormap, GLint nr, GLint ng, GLint nb, GLint buffersize, FILE *stream, const char *filename)
Definition: gl2ps.cxx:5566
TH1 * h
Definition: legend2.C:5
const Rgl::BinRange_t & GetXBins() const
X bins range.
SCoord_t fX
Definition: TPoint.h:37
void swap(ROOT::THist< DIMENSIONS, PRECISION > &a, ROOT::THist< DIMENSIONS, PRECISION > &b) noexcept
Swap two histograms.
Definition: THist.h:196
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition: TGLUtil.cxx:1813
Int_t GetNumberContours() const
Definition: TStyle.h:249
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:489
const Rgl::Range_t & GetYRangeScaled() const
Scaled range.
SCoord_t fY
Definition: TPoint.h:38
Basic string class.
Definition: TString.h:137
const Float_t gBlueEmission[]
Definition: TGLUtil.cxx:2810
virtual Double_t GetNormFactor() const
Definition: TH1.h:300
Int_t GetWidth() const
viewport[2]
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
Int_t GetFirstZBin() const
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
void TurnOnOff()
Turn the box cut on/off.
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:511
void AdjustBox()
Box cut is limited by plot's sizes.
void DrawPalette(const TGLPlotCamera *camera, const TGLLevelPalette &palette)
Draw. Palette.
void DrawPaletteAxis(const TGLPlotCamera *camera, const Range_t &minMax, Bool_t logZ)
const TGLPlotCoordinates * fCoord
STL namespace.
const Rgl::BinRange_t & GetZBins() const
Z bins range.
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
A slice of a TH3.
Int_t FindFrontPoint() const
Convert 3d points into window coordinate system and find the nearest.
Definition: TGLPlotBox.cxx:244
Double_t GetZScale() const
Int_t GetFirstXBin() const
#define GL2PS_OCCLUSION_CULL
Definition: gl2ps.h:100
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:246
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:3726
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
Bool_t IsVariableBinSize() const
Definition: TAxis.h:140
Bool_t SetRangesCartesian(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges, etc.
const Double_t gH2PolyScaleXY
virtual void ClearBuffers() const
Double_t GetZLength() const
Z length.
virtual void SetFrameColor(const TColor *frameColor)
Set plot's back box color.
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition: TGLUtil.cxx:4193
Double_t GetMaximum() const
Returns the maximum value of the histogram.
Definition: TH2Poly.cxx:766
Double_t x[n]
Definition: legend1.C:17
TGL2DArray< Double_t > fTexCoords
void SaveProjectionMatrix() const
virtual ~TGLBoxCut()
Destructor.
void DisableTexture() const
Disable 1D texture.
Definition: TGLUtil.cxx:4212
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
3 component (x/y/z) vertex class.
Definition: TGLUtil.h:86
virtual Double_t GetMaximumStored() const
Definition: TH1.h:289
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
void DrawSlice(Double_t pos) const
Draw slice.
Double_t fXOZSectionPos
Double_t Log10(Double_t x)
Definition: TMath.h:529
virtual Bool_t PlotSelected(Int_t px, Int_t py)
Read color buffer content to find selected object.
virtual void DrawSectionYOZ() const =0
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:4535
const Rgl::Range_t & GetXRange() const
X range.
void SetYLog(Bool_t yLog)
If log changed, sections must be reset, set fModified.
TGLPlotBox fBackBox
ESliceAxis fAxisType
3 component (x/y/z) vector class.
Definition: TGLUtil.h:250
Implementation of a box around a histogram/function for plot-painters.
Definition: TGLPlotBox.h:30
Bool_t SetRangesSpherical(const TH1 *hist)
Set ranges spherical.
void Error(const char *location, const char *msgfmt,...)
Double_t GetXScale() const
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:35
GL2PSDLL_API GLint gl2psEndPage(void)
Definition: gl2ps.cxx:5733
Int_t GetNZBins() const
Number of Z bins.
Int_t ColorToObjectID(const UChar_t *color, Bool_t highColor)
Definition: TGLUtil.cxx:2884
A doubly linked list.
Definition: TList.h:47
Bool_t GetZLog() const
Get Z log.
Bool_t SetRangesPolar(const TH1 *hist)
Set bin ranges, ranges, etc.
Double_t fPadTheta
void RestoreProjectionMatrix() const
#define GL2PS_USE_CURRENT_VIEWPORT
Definition: gl2ps.h:105
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2858
const Rgl::BinRange_t & GetYBins() const
Y bins range.
TGLPlotCamera * fCamera
static void StartEmbeddedPS()
this function used by gl-in-pad
Definition: TGLOutput.cxx:136
const UChar_t * GetColour(Double_t z) const
Get color.
Definition: TGLUtil.cxx:4258
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:2974
#define GL2PS_BSP_SORT
Definition: gl2ps.h:81
Bool_t GetYLog() const
Get Y log.
void SetSliceWidth(Int_t width=1)
Set Slice width.
ClassImp(TGLPlotPainter) TGLPlotPainter
TGLPlotPainter's ctor.
TList * GetBins()
Definition: TH2Poly.h:97
TGLPlotPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord, Bool_t xoySelectable, Bool_t xozSelectable, Bool_t yozSelectable)
Class to manage histogram axis.
Definition: TAxis.h:36
EGLCoordType
Definition: TGLUtil.h:45
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition: TGLUtil.cxx:1543
void DrawBox(Bool_t selectionPass, Int_t selected) const
Draw cut as a semi-transparent box.
virtual Double_t GetMinimumStored() const
Definition: TH1.h:293
A 3-Dim function with parameters.
Definition: TF3.h:30
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition: TGLUtil.cxx:4229
Int_t GetLastZBin() const
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:499
std::pair< Int_t, Int_t > BinRange_t
Definition: TGLUtil.h:1196
virtual void DrawSectionXOY() const =0
void SetPadColor(const TColor *color)
Used in a pad.
void DrawSections() const
Draw sections (if any).
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
void ResetModified()
Reset modified.
unsigned int UInt_t
Definition: RtypesCore.h:42
void SaveModelviewMatrix() const
void SetXLog(Bool_t xLog)
If log changed, sections must be reset, set fModified.
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The axis painter class.
Definition: TGaxis.h:39
TAxis * GetYaxis()
Definition: TH1.h:320
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH3.h:95
Int_t GetX() const
viewport[0]
const TGLPlotBox * fBox
TGLLevelPalette fPalette
TGLSelectionBuffer fSelection
void Warning(const char *location, const char *msgfmt,...)
Base class for plot-painters that provide GL rendering of various 2D and 3D histograms, functions and parametric surfaces.
#define GL2PS_SILENT
Definition: gl2ps.h:98
std::vector< Double_t > fZLevels
const TGLVertex3 * Get2DBox() const
Get 2D box.
Definition: TGLPlotBox.cxx:311
void SetActive(Bool_t a)
Turn the box cut on/off.
#define blend
const TColor * fPadColor
void DrawSliceFrame(Int_t low, Int_t up) const
Draw slice frame.
void RestoreModelviewMatrix() const
void PrepareTexCoords(Double_t pos, Int_t sliceBegin, Int_t sliceEnd) const
Prepare TexCoords.
const TAxis * fAxis
double f(double x)
double Double_t
Definition: RtypesCore.h:55
int type
Definition: TGX11.cxx:120
void SetFrameColor(const TColor *color)
Back box color.
Definition: TGLPlotBox.cxx:225
void SetCoordType(EGLCoordType type)
If coord type was changed, plot must reset sections (if any), set fModified.
Int_t GetFirstYBin() const
Double_t y[n]
Definition: legend1.C:17
Int_t GetNYBins() const
Number of Y bins.
The TH1 histogram class.
Definition: TH1.h:80
virtual void DrawSectionXOZ() const =0
The color creation and management class.
Definition: TColor.h:23
Bool_t SetRanges(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges.
const TGLVertex3 * Get3DBox() const
Get 3D box.
Definition: TGLPlotBox.cxx:302
Double_t X() const
Definition: TGLUtil.h:122
virtual void DeInitGL() const =0
virtual Double_t GetCellError(Int_t binx, Int_t biny) const
Definition: TH1.h:424
Int_t GetFrontPoint() const
The nearest point.
Definition: TGLPlotBox.cxx:293
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition: TGLUtil.cxx:4221
#define name(a, b)
Definition: linkTestLib0.cpp:5
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:440
TAxis * GetZaxis()
Definition: TH1.h:321
Double_t GetYLength() const
Y length.
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:449
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.
#define GL2PS_BEST_ROOT
Definition: gl2ps.h:99
EGLCoordType GetCoordType() const
Get coordinates type.
Double_t Y() const
Definition: TGLUtil.h:124
Double_t GetFactor() const
Get factor.
Double_t fXOYSectionPos
const Rgl::Range_t & GetYRange() const
Y range.
void PrintPlot() const
Generate PS using gl2ps.
const UChar_t * GetPixelColor(Int_t px, Int_t py) const
Get pixel color.
Definition: TGLUtil.cxx:2793
virtual void Paint(Option_t *chopt="")
Draw this axis with its current attributes.
Definition: TGaxis.cxx:684
Double_t GetHistTopMargin() const
Definition: TStyle.h:247
const Rgl::Range_t & GetXRangeScaled() const
Scaled range.
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:390
Bool_t GetXLog() const
Get X log.
Double_t GetYScale() const
void SetZLog(Bool_t zLog)
If log changed, sections must be reset, set fModified.
const TGLPlotPainter * fPainter
void StartMovement(Int_t px, Int_t py)
Start cut's movement.
void MoveSection(Int_t px, Int_t py)
Create dynamic profile using selected plane.
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
static void CloseEmbeddedPS()
this function used by gl-in-pad Restore the gVirtualPS output stream
Definition: TGLOutput.cxx:180
Bool_t Modified() const
Modified.
Int_t GetLastYBin() const
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:1185
#define NULL
Definition: Rtypes.h:82
R__EXTERN TVirtualPS * gVirtualPS
Definition: TVirtualPS.h:91
#define gPad
Definition: TVirtualPad.h:288
void FindMinMax(Int_t sliceBegin, Int_t sliceEnd) const
Find minimum and maximum for slice.
Bool_t SetRangesCylindrical(const TH1 *hist)
Set ranges cylindrical.
virtual void InitGL() const =0
TGLTH3Slice(const TString &sliceName, const TH3 *hist, const TGLPlotCoordinates *coord, const TGLPlotBox *box, ESliceAxis axis)
Rgl::Range_t fMinMax
const TH3 * fHist
unsigned char UChar_t
Definition: RtypesCore.h:34
Double_t Z() const
Definition: TGLUtil.h:126
Used by plot-painters to determine the area of the plot that is cut away.
Bool_t fUpdateSelection
std::complex< float_v > Z
Definition: main.cpp:120
Double_t GetMinimum() const
Returns the minimum value of the histogram.
Definition: TH2Poly.cxx:814
static void output(int code)
Definition: gifencode.c:226
void DrawSliceTextured(Double_t pos) const
Draw slice textured.
const Bool_t kTRUE
Definition: Rtypes.h:91
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition: TGLUtil.cxx:4128
TGLPlotCoordinates * fCoord
virtual void Paint()
Draw lego/surf/whatever you can.
virtual void DrawPlot() const =0
virtual ~TGLPlotCoordinates()
Destructor.
#define GL2PS_OVERFLOW
Definition: gl2ps.h:90
void InvalidateSelection()
Selection must be updated.
void SetCamera() const
Viewport and projection.
const TColor * GetPadColor() const
Get pad color.
Int_t GetHeight() const
viewport[3]
TAxis * GetXaxis()
Definition: TH1.h:319
const Rgl::Range_t & GetZRange() const
Z range.
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:70
#define GL2PS_EPS
Definition: gl2ps.h:71