Logo ROOT   6.14/05
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),
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),
99  fSelectedPart(0),
100  fXOZSectionPos(0.),
101  fYOZSectionPos(0.),
102  fXOYSectionPos(0.),
104  fBoxCut(&fBackBox),
109 {
110  if (gPad) {
111  fPadPhi = gPad->GetPhi();
112  fPadTheta = gPad->GetTheta();
113  }
114 }
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 ///TGLPlotPainter's ctor.
118 
120  : fPadColor(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),
132  fSelectedPart(0),
133  fXOZSectionPos(0.),
134  fYOZSectionPos(0.),
135  fXOYSectionPos(0.),
137  fBoxCut(&fBackBox),
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 |
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 
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 
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 {
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 
2088 PlotTranslation::PlotTranslation(const TGLPlotPainter *painter)
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&#39;s back box.
for(Int_t i=0;i< n;i++)
Definition: legend1.C:18
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
void DrawBox(Bool_t selectionPass, Int_t selected) const
Draw cut as a semi-transparent box.
virtual Double_t GetMaximumStored() const
Definition: TH1.h:283
Double_t GetFactor() const
Get factor.
Int_t GetFrontPoint() const
The nearest point.
Definition: TGLPlotBox.cxx:294
void SetRowLen(Int_t len)
Definition: TGLUtil.h:1164
void RestoreModelviewMatrix() const
const Rgl::BinRange_t & GetZBins() const
Z bins range.
Camera for TGLPlotPainter and sub-classes.
Definition: TGLPlotCamera.h:21
Int_t GetFirstXBin() const
void ReadColorBuffer(Int_t width, Int_t height)
Read color buffer.
Definition: TGLUtil.cxx:2769
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 GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
Int_t GetNYBins() const
Number of Y bins.
void MoveBox(Int_t px, Int_t py, Int_t axisID)
Move box cut along selected direction.
Double_t fXLength
const Rgl::BinRange_t & GetYBins() const
Y bins range.
Int_t GetNumberContours() const
Definition: TStyle.h:228
const Float_t gNullEmission[]
Definition: TGLUtil.cxx:2814
Bool_t fActive
void PrintPlot() const
Generate PS using gl2ps.
float Float_t
Definition: RtypesCore.h:53
Bool_t GetZLog() const
Get Z log.
Double_t fFactor
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:504
void swap(TDirectoryEntry &e1, TDirectoryEntry &e2) noexcept
std::pair< Double_t, Double_t > Range_t
Definition: TGLUtil.h:1193
image html pict1_TGaxis_012 png width
Define new text attributes for the label number "labNum".
Definition: TGaxis.cxx:2551
Double_t GetHistTopMargin() const
Definition: TStyle.h:225
virtual Double_t GetMinimumStored() const
Definition: TH1.h:287
virtual Double_t GetNormFactor() const
Definition: TH1.h:295
R__EXTERN TStyle * gStyle
Definition: TStyle.h:406
const TF3 * fF3
Double_t GetYLength() const
Y length.
Double_t fYOZSectionPos
unsigned short UShort_t
Definition: RtypesCore.h:36
EGLCoordType GetCoordType() const
Get coordinates type.
Rgl::Range_t fXRange
void DrawSections() const
Draw sections (if any).
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4770
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition: TGLUtil.cxx:4221
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition: TGLUtil.cxx:4229
virtual Int_t GetEntries() const
Definition: TCollection.h:177
const TGLVertex3 * Get3DBox() const
Get 3D box.
Definition: TGLPlotBox.cxx:303
const Rgl::BinRange_t & GetXBins() const
X bins range.
SCoord_t fX
Definition: TPoint.h:35
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition: TGLUtil.cxx:1813
Double_t GetZLength() const
Z length.
const Rgl::Range_t & GetZRange() const
Z range.
SCoord_t fY
Definition: TPoint.h:36
void DrawSliceTextured(Double_t pos) const
Draw slice textured.
Bool_t PreparePalette() const
Initialize color palette.
Int_t GetNXBins() const
Number of X bins.
const Float_t gBlueEmission[]
Definition: TGLUtil.cxx:2810
Int_t GetWidth() const
viewport[2]
#define f(i)
Definition: RSha256.hxx:104
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:57
void TurnOnOff()
Turn the box cut on/off.
const UChar_t * GetColour(Double_t z) const
Get color.
Definition: TGLUtil.cxx:4258
Rgl::Range_t fZRangeScaled
Bool_t GetYLog() const
Get Y log.
void AdjustBox()
Box cut is limited by plot&#39;s sizes.
void DrawPalette(const TGLPlotCamera *camera, const TGLLevelPalette &palette)
Draw. Palette.
void DrawPaletteAxis(const TGLPlotCamera *camera, const Range_t &minMax, Bool_t logZ)
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH3.h:91
const TGLPlotCoordinates * fCoord
STL namespace.
void FindMinMax(Int_t sliceBegin, Int_t sliceEnd) const
Find minimum and maximum for slice.
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.
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
TPoint fMousePos
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:734
Bool_t SetRangesCartesian(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges, etc.
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:514
Rgl::BinRange_t fYBins
Int_t GetNZBins() const
Number of Z bins.
const Double_t gH2PolyScaleXY
virtual void SetFrameColor(const TColor *frameColor)
Set plot&#39;s back box color.
TGLBoxCut(const TGLPlotBox *plotBox)
Constructor.
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
Double_t x[n]
Definition: legend1.C:17
TGL2DArray< Double_t > fTexCoords
virtual ~TGLBoxCut()
Destructor.
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
3 component (x/y/z) vertex class.
Definition: TGLUtil.h:82
Double_t fXOZSectionPos
virtual void DrawPaletteAxis() const
Draw. Palette. Axis.
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition: TGLUtil.cxx:4193
Double_t Log10(Double_t x)
Definition: TMath.h:763
virtual Bool_t PlotSelected(Int_t px, Int_t py)
Read color buffer content to find selected object.
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
virtual void DrawSectionYOZ() const =0
void SetCamera() const
Viewport and projection.
Int_t GetFirstYBin() const
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:246
const TColor * GetPadColor() const
Get pad color.
Rgl::Range_t fXRange
Implementation of a box around a histogram/function for plot-painters.
Definition: TGLPlotBox.h:26
Bool_t SetRangesSpherical(const TH1 *hist)
Set ranges spherical.
void Error(const char *location, const char *msgfmt,...)
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:31
Int_t ColorToObjectID(const UChar_t *color, Bool_t highColor)
Definition: TGLUtil.cxx:2884
Rgl::BinRange_t fZBins
const UChar_t * GetPixelColor(Int_t px, Int_t py) const
Get pixel color.
Definition: TGLUtil.cxx:2793
Bool_t GetXLog() const
Get X log.
A doubly linked list.
Definition: TList.h:44
Bool_t SetRangesPolar(const TH1 *hist)
Set bin ranges, ranges, etc.
Double_t GetXLength() const
X length.
Double_t fPadTheta
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2858
const Rgl::Range_t & GetZRangeScaled() const
Scaled range.
TGLPlotCamera * fCamera
static void StartEmbeddedPS()
this function used by gl-in-pad
Definition: TGLOutput.cxx:137
void RestoreProjectionMatrix() const
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&#39;s bar as a 3d box.
Definition: TGLUtil.cxx:2974
Int_t GetLastYBin() const
void SetSliceWidth(Int_t width=1)
Set Slice width.
TList * GetBins()
Definition: TH2Poly.h:94
TGLPlotPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord, Bool_t xoySelectable, Bool_t xozSelectable, Bool_t yozSelectable)
TGLPlotPainter&#39;s ctor.
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
Class to manage histogram axis.
Definition: TAxis.h:30
EGLCoordType
Definition: TGLUtil.h:41
void DrawSliceFrame(Int_t low, Int_t up) const
Draw slice frame.
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition: TGLUtil.cxx:1543
auto * a
Definition: textangle.C:12
A 3-Dim function with parameters.
Definition: TF3.h:28
std::pair< Int_t, Int_t > BinRange_t
Definition: TGLUtil.h:1192
virtual void DrawSectionXOY() const =0
void SetPadColor(const TColor *color)
Used in a pad.
Rgl::Range_t fYRange
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:224
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
void ResetModified()
Reset modified.
TGLVertex3 fCenter
unsigned int UInt_t
Definition: RtypesCore.h:42
const Rgl::Range_t & GetXRange() const
X range.
void DrawSlice(Double_t pos) const
Draw slice.
Int_t FindFrontPoint() const
Convert 3d points into window coordinate system and find the nearest.
Definition: TGLPlotBox.cxx:245
void SetXLog(Bool_t xLog)
If log changed, sections must be reset, set fModified.
The axis painter class.
Definition: TGaxis.h:24
virtual void ClearBuffers() const
TAxis * GetYaxis()
Definition: TH1.h:316
EGLCoordType fCoordType
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.
Rgl::Range_t fZRange
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:4672
std::vector< Double_t > fZLevels
Rgl::Range_t fYRangeScaled
#define h(i)
Definition: RSha256.hxx:106
const Bool_t kFALSE
Definition: RtypesCore.h:88
void SetActive(Bool_t a)
Turn the box cut on/off.
const TColor * fPadColor
void PrepareTexCoords(Double_t pos, Int_t sliceBegin, Int_t sliceEnd) const
Prepare TexCoords.
Double_t Z() const
Definition: TGLUtil.h:122
Double_t GetYScale() 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:1336
const TAxis * fAxis
#define ClassImp(name)
Definition: Rtypes.h:359
double Double_t
Definition: RtypesCore.h:55
int type
Definition: TGX11.cxx:120
void SetFrameColor(const TColor *color)
Back box color.
Definition: TGLPlotBox.cxx:226
void SetCoordType(EGLCoordType type)
If coord type was changed, plot must reset sections (if any), set fModified.
Int_t GetY() const
viewport[1]
Bool_t Modified() const
Modified.
Rgl::Range_t fZRange
Double_t y[n]
Definition: legend1.C:17
void SaveProjectionMatrix() const
Double_t GetMinimum() const
Returns the minimum value of the histogram.
Definition: TH2Poly.cxx:859
The TH1 histogram class.
Definition: TH1.h:56
TGLPlotCoordinates()
Constructor.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
virtual void DrawSectionXOZ() const =0
#define R__LOCKGUARD(mutex)
The color creation and management class.
Definition: TColor.h:19
Int_t GetFirstZBin() const
Bool_t SetRanges(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges.
const Rgl::Range_t & GetYRange() const
Y range.
virtual void DeInitGL() const =0
void DisableTexture() const
Disable 1D texture.
Definition: TGLUtil.cxx:4212
const Rgl::Range_t & GetYRangeScaled() const
Scaled range.
Bool_t IsVariableBinSize() const
Definition: TAxis.h:136
Int_t GetLastXBin() const
TAxis * GetZaxis()
Definition: TH1.h:317
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:405
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
Double_t fXOYSectionPos
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:526
virtual void Paint(Option_t *chopt="")
Draw this axis with its current attributes.
Definition: TGaxis.cxx:935
Rgl::BinRange_t fXBins
const Float_t * fPhysicalShapeColor
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&#39;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:200
static void CloseEmbeddedPS()
this function used by gl-in-pad Restore the gVirtualPS output stream
Definition: TGLOutput.cxx:181
Double_t fYLength
Rgl::Range_t fXRangeScaled
const Rgl::Range_t & GetXRangeScaled() const
Scaled range.
R__EXTERN TVirtualPS * gVirtualPS
Definition: TVirtualPS.h:81
#define gPad
Definition: TVirtualPad.h:285
Bool_t SetRangesCylindrical(const TH1 *hist)
Set ranges cylindrical.
virtual void InitGL() const =0
#define c(i)
Definition: RSha256.hxx:101
TGLTH3Slice(const TString &sliceName, const TH3 *hist, const TGLPlotCoordinates *coord, const TGLPlotBox *box, ESliceAxis axis)
Constructor.
Rgl::Range_t fMinMax
const TH3 * fHist
unsigned char UChar_t
Definition: RtypesCore.h:34
Used by plot-painters to determine the area of the plot that is cut away.
Bool_t fUpdateSelection
Double_t fZLength
Int_t GetLastZBin() const
virtual Double_t GetCellError(Int_t binx, Int_t biny) const
Definition: TH1.h:421
Int_t GetHeight() const
viewport[3]
void SaveModelviewMatrix() const
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
Double_t Y() const
Definition: TGLUtil.h:120
virtual void Paint()
Draw lego/surf/whatever you can.
virtual void DrawPlot() const =0
virtual ~TGLPlotCoordinates()
Destructor.
const Bool_t kTRUE
Definition: RtypesCore.h:87
TGLBoxCut fBoxCut
void InvalidateSelection()
Selection must be updated.
Double_t GetZScale() const
Double_t GetMaximum() const
Returns the maximum value of the histogram.
Definition: TH2Poly.cxx:811
clip to the frame boundary
Definition: TGraph.h:70
Int_t GetX() const
viewport[0]
const TGLPlotBox *const fPlotBox
char name[80]
Definition: TGX11.cxx:109
double log(double)
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:315
Double_t GetXScale() const
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:66
const TGLVertex3 * Get2DBox() const
Get 2D box.
Definition: TGLPlotBox.cxx:312
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.
Rgl::Range_t fYRange
Double_t X() const
Definition: TGLUtil.h:118