Logo ROOT  
Reference Guide
TGLHistPainter.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Timur Pocheptsov 17/11/2005
3
4/*************************************************************************
5 * Copyright (C) 1995-2005, 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
12#include <stdexcept>
13#include <cstring>
14
15#include "TVirtualGL.h"
16#include "KeySymbols.h"
17#include "Buttons.h"
18#include "TH2Poly.h"
19#include "TClass.h"
20#include "TROOT.h"
21#include "TGL5D.h"
22#include "TMath.h"
23#include "TPad.h"
24#include "TH3.h"
25#include "TF3.h"
26
27#include "TGLSurfacePainter.h"
28#include "TGLTH3Composition.h"
29#include "TGLH2PolyPainter.h"
30#include "TGLVoxelPainter.h"
31#include "TGLHistPainter.h"
32#include "TGLLegoPainter.h"
33#include "TGLBoxPainter.h"
34#include "TGLTF3Painter.h"
35#include "TGLParametric.h"
36#include "TGL5DPainter.h"
37#include "TGLUtil.h"
38
40
41/** \class TGLHistPainter
42\ingroup opengl
43The histogram painter class using OpenGL.
44
45Histograms are, by default, drawn via the `THistPainter` class.
46`TGLHistPainter` allows to paint them using the OpenGL 3D graphics
47library. The plotting options provided by `TGLHistPainter` start with
48`GL` keyword.
49
50### General information: plot types and supported options
51
52The following types of plots are provided:
53
54#### Lego - (`TGLLegoPainter`)
55 The supported options are:
56
57 - `"GLLEGO" :` Draw a lego plot.
58 - `"GLLEGO2" :` Bins with color levels.
59 - `"GLLEGO3" :` Cylindrical bars.
60
61 Lego painter in cartesian supports logarithmic scales for X, Y, Z.
62 In polar only Z axis can be logarithmic, in cylindrical only Y (if you see
63 what it means).
64
65
66#### Surfaces (`TF2` and `TH2` with `"GLSURF"` options) - (`TGLSurfacePainter`)
67 The supported options are:
68
69 - `"GLSURF" :` Draw a surface.
70 - `"GLSURF1" :` Surface with color levels
71 - `"GLSURF2" :` The same as `"GLSURF1"` but without polygon outlines.
72 - `"GLSURF3" :` Color level projection on top of plot (works only in cartesian coordinate system).
73 - `"GLSURF4" :` Same as `"GLSURF"` but without polygon outlines.
74
75
76 The surface painting in cartesian coordinates supports logarithmic scales along X, Y, Z axis.
77 In polar coordinates only the Z axis can be logarithmic, in cylindrical coordinates only the Y axis.
78
79#### Additional options to `SURF` and `LEGO` - Coordinate systems:
80 The supported options are:
81
82 - `" " :` Default, cartesian coordinates system.
83 - `"POL" :` Polar coordinates system.
84 - `"CYL" :` Cylindrical coordinates system.
85 - `"SPH" :` Spherical coordinates system.
86
87
88#### `TH3` as boxes (spheres) - (`TGLBoxPainter`)
89 The supported options are:
90
91 - `"GLBOX" :` TH3 as a set of boxes, size of box is proportional to bin content.
92 - `"GLBOX1":` the same as "glbox", but spheres are drawn instead of boxes.
93
94
95#### `TH3` as iso-surface(s) - (`TGLIsoPainter`)
96 The supported option is:
97
98 - `"GLISO" :` TH3 is drawn using iso-surfaces.
99
100
101#### `TH3` as color boxes - (`TGLVoxelPainter`)
102 The supported option is:
103
104 - `"GLCOL" :` TH3 is drawn using semi-transparent colored boxes.
105 See `$ROOTSYS/tutorials/gl/glvox1.C`.
106
107
108#### `TF3` (implicit function) - (`TGLTF3Painter`)
109 The supported option is:
110
111 - `"GLTF3" :` Draw a `TF3`.
112
113
114#### Parametric surfaces - (`TGLParametricPlot`)
115 `$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric equations and
116 visualize the surface.
117
118
119### Interaction with the plots
120
121
122#### General information.
123
124 All the interactions are implemented via standard methods `DistancetoPrimitive` and
125 `ExecuteEvent`. That's why all the interactions with the OpenGL plots are possible i
126 only when the mouse cursor is in the plot's area (the plot's area is the part of a the pad
127 occupied by gl-produced picture). If the mouse cursor is not above gl-picture,
128 the standard pad interaction is performed.
129
130#### Selectable parts.
131
132 Different parts of the plot can be selected:
133
134 - *xoz, yoz, xoy back planes*:
135 When such a plane selected, it's highlighted in green if the dynamic slicing
136 by this plane is supported, and it's highlighted in red, if the dynamic slicing
137 is not supported.
138 -*The plot itself*:
139 On surfaces, the selected surface is outlined in red. (TF3 and ISO are not
140 outlined). On lego plots, the selected bin is highlihted. The bin number and content are displayed in pad's status
141 bar. In box plots, the box or sphere is highlighted and the bin info is displayed in pad's status bar.
142
143#### Rotation and zooming.
144
145 - *Rotation*:
146
147 When the plot is selected, it can be rotated by pressing and holding the left mouse button and move the cursor.
148 - *Zoom/Unzoom*:
149
150 Mouse wheel or `'j'`, `'J'`, `'k'`, `'K'` keys.
151
152
153#### Panning.
154
155 The selected plot can be moved in a pad's area by
156 pressing and holding the left mouse button and the shift key.
157
158### Box cut
159 Surface, iso, box, TF3 and parametric painters support box cut by pressing the `'c'` or
160 `'C'` key when the mouse cursor is in a plot's area. That will display a transparent box,
161 cutting away part of the surface (or boxes) in order to show internal part of plot.
162 This box can be moved inside the plot's area (the full size of the box is equal to the plot's
163 surrounding box) by selecting one of the box cut axes and pressing the left mouse button to move it.
164
165### Plot specific interactions (dynamic slicing etc.)
166 Currently, all gl-plots support some form of slicing.
167 When back plane is selected (and if it's highlighted in green)
168 you can press and hold left mouse button and shift key
169 and move this back plane inside plot's area, creating the slice.
170 During this "slicing" plot becomes semi-transparent. To remove all slices (and projected curves for surfaces)
171 - double click with left mouse button in a plot's area.
172
173 #### Surface with option `"GLSURF"`
174
175 The surface profile is displayed on the slicing plane.
176 The profile projection is drawn on the back plane
177 by pressing `'p'` or `'P'` key.
178
179 #### TF3
180
181 The contour plot is drawn on the slicing plane.
182 For `TF3` the color scheme can be changed by pressing `'s'` or `'S'`.
183
184 #### Box
185
186 The contour plot corresponding to slice plane position is drawn in real time.
187
188 #### Iso
189
190 Slicing is similar to `"GLBOX"` option.
191
192 #### Parametric plot
193
194 No slicing. Additional keys: `'s'` or `'S'` to change color scheme - about 20 color schemes supported
195 (`'s'` for "scheme"); `'l'` or `'L'` to increase number of polygons (`'l'` for "level" of details),
196 `'w'` or `'W'` to show outlines (`'w'` for "wireframe").
197*/
198
199////////////////////////////////////////////////////////////////////////////////
200/// ROOT does not use exceptions, so, if default painter's creation failed,
201/// fDefaultPainter is 0. In each function, which use it, I have to check the pointer first.
202
204 : fDefaultPainter(TVirtualHistPainter::HistPainter(hist)),
205 fEq(0),
206 fHist(hist),
207 fF3(0),
208 fStack(0),
209 fPlotType(kGLDefaultPlot)//THistPainter
210{
211}
212
213////////////////////////////////////////////////////////////////////////////////
214///This ctor creates gl-parametric plot's painter.
215
217 : fEq(equation),
218 fHist(0),
219 fF3(0),
220 fStack(0),
221 fPlotType(kGLParametricPlot)//THistPainter
222{
223 fGLPainter.reset(new TGLParametricPlot(equation, &fCamera));
224}
225
226////////////////////////////////////////////////////////////////////////////////
227///This ctor creates plot painter for TGL5DDataSet.
228
230 : fEq(0),
231 fHist(0),
232 fF3(0),
233 fStack(0),
234 fPlotType(kGL5D)//THistPainter
235{
236 fGLPainter.reset(new TGL5DPainter(data, &fCamera, &fCoord));
237}
238
239////////////////////////////////////////////////////////////////////////////////
240///This ctor creates plot painter for TGL5DDataSet.
241
243 : fEq(0),
244 fHist(data),
245 fF3(0),
246 fStack(0),
247 fPlotType(kGLTH3Composition)
248{
250}
251
252////////////////////////////////////////////////////////////////////////////////
253///Selects plot or axis.
254///9999 is the magic number, ROOT's classes use in DistancetoPrimitive.
255
257{
258 //[tp: return statement added.
259 //tp]
260
262 return fDefaultPainter.get() ? fDefaultPainter->DistancetoPrimitive(px, py) : 9999;
263 else {
264 //Adjust px and py - canvas can have several pads inside, so we need to convert
265 //the from canvas' system into pad's.
266
267 //Retina-related adjustments must be done inside!!!
268
269 py = gPad->GetWh() - py;
270
271 //One hist can be appended to several pads,
272 //the current pad should have valid OpenGL context.
273 const Int_t glContext = gPad->GetGLDevice();
274
275 if (glContext != -1) {
276 //Add "viewport" extraction here.
278
279 if (!gGLManager->PlotSelected(fGLPainter.get(), px, py))
280 gPad->SetSelected(gPad);
281 } else {
282 Error("DistancetoPrimitive",
283 "Attempt to use TGLHistPainter, while the current pad (gPad) does not support gl");
284 gPad->SetSelected(gPad);
285 }
286
287 return 0;
288 }
289}
290
291////////////////////////////////////////////////////////////////////////////////
292///Default implementation is OK
293///This function is called from a context menu
294///after right click on a plot's area. Opens window
295///("panel") with several controls.
296
298{
299 if (fDefaultPainter.get())
300 fDefaultPainter->DrawPanel();
301}
302
303////////////////////////////////////////////////////////////////////////////////
304///Execute event.
305///Events are: mouse events in a plot's area,
306///key presses (while mouse cursor is in plot's area).
307///"Event execution" means one of the following actions:
308/// 1. Rotation.
309/// 2. Panning.
310/// 3. Zoom changing.
311/// 4. Moving dynamic profile.
312/// 5. Plot specific events - for example, 's' or 'S' key press for TF3.
313
315{
316 if (fPlotType == kGLDefaultPlot) {
317 if(fDefaultPainter.get()) {
318 fDefaultPainter->ExecuteEvent(event, px, py);
319 }
320 } else {
321 //One hist can be appended to several pads,
322 //the current pad should have valid OpenGL context.
323 const Int_t glContext = gPad->GetGLDevice();
324
325 if (glContext == -1) {
326 Error("ExecuteEvent",
327 "Attempt to use TGLHistPainter, while the current pad (gPad) does not support gl");
328 return;
329 } else {
330 //Add viewport extraction here.
331 /*fGLDevice.SetGLDevice(glContext);
332 fGLPainter->SetGLDevice(&fGLDevice);*/
334 }
335
336 if (event != kKeyPress) {
337 //Adjust px and py - canvas can have several pads inside, so we need to convert
338 //the from canvas' system into pad's. If it was a key press event,
339 //px and py ARE NOT coordinates.
340 py -= Int_t((1 - gPad->GetHNDC() - gPad->GetYlowNDC()) * gPad->GetWh());
341 px -= Int_t(gPad->GetXlowNDC() * gPad->GetWw());
342
343 //We also have to take care of retina displays with a different viewports.
346 if (scale > 1) {
347 px *= scale;
348 py *= scale;
349 }
350 }
351
352 switch (event) {
353 case kButton1Double:
354 //Left double click removes dynamic sections, user created (if plot type supports sections).
355 fGLPainter->ProcessEvent(event, px, py);
356 break;
357 case kButton1Down:
358 //Left mouse down in a plot area starts rotation.
359 if (!fGLPainter->CutAxisSelected())
360 fCamera.StartRotation(px, py);
361 else
362 fGLPainter->StartPan(px, py);
363 //During rotation, usual TCanvas/TPad machinery (CopyPixmap/Flush/UpdateWindow/etc.)
364 //is skipped - I use "bit blasting" functions to copy picture directly onto window.
365 //gGLManager->MarkForDirectCopy(glContext, kTRUE);
366 break;
367 case kButton1Motion:
368 //Rotation invalidates "selection buffer"
369 // - (color-to-object map, previously read from gl-buffer).
370 fGLPainter->InvalidateSelection();
371 if (fGLPainter->CutAxisSelected())
372 gGLManager->PanObject(fGLPainter.get(), px, py);
373 else
374 fCamera.RotateCamera(px, py);
375 //Draw modified scene onto canvas' window.
376 //gGLManager->PaintSingleObject(fGLPainter.get());
377 gPad->Update();
378 break;
379 case kButton1Up:
380 case kButton2Up:
381 gGLManager->MarkForDirectCopy(glContext, kFALSE);
382 break;
383 case kMouseMotion:
384 gPad->SetCursor(kRotate);
385 break;
386 case 7://kButton1Down + shift modifier
387 //The current version of ROOT does not
388 //have enumerators for button events + key modifiers,
389 //so I use hardcoded literals. :(
390 //With left mouse button down and shift pressed
391 //we can move plot as the whole or move
392 //plot's parts - dynamic sections.
393 fGLPainter->StartPan(px, py);
394 gGLManager->MarkForDirectCopy(glContext, kTRUE);
395 break;
396 case 8://kButton1Motion + shift modifier
397 gGLManager->PanObject(fGLPainter.get(), px, py);
398 //gGLManager->PaintSingleObject(fGLPainter.get());
399 gPad->Update();
400 break;
401 case kKeyPress:
402 case 5:
403 case 6:
404 //5, 6 are mouse wheel events (see comment about literals above).
405 //'p'/'P' - specific events processed by TGLSurfacePainter,
406 //'s'/'S' - specific events processed by TGLTF3Painter,
407 //'c'/'C' - turn on/off box cut.
408 gGLManager->MarkForDirectCopy(glContext, kTRUE);
409 if (event == 6 || py == kKey_J || py == kKey_j) {
410 fCamera.ZoomIn();
411 fGLPainter->InvalidateSelection();
412 //gGLManager->PaintSingleObject(fGLPainter.get());
413 gPad->Update();
414 } else if (event == 5 || py == kKey_K || py == kKey_k) {
416 fGLPainter->InvalidateSelection();
417 //gGLManager->PaintSingleObject(fGLPainter.get());
418 gPad->Update();
419 } else if (py == kKey_p || py == kKey_P || py == kKey_S || py == kKey_s
420 || py == kKey_c || py == kKey_C || py == kKey_x || py == kKey_X
421 || py == kKey_y || py == kKey_Y || py == kKey_z || py == kKey_Z
422 || py == kKey_w || py == kKey_W || py == kKey_l || py == kKey_L
423 /*|| py == kKey_r || py == kKey_R*/)
424 {
425 fGLPainter->ProcessEvent(event, px, py);
426 //gGLManager->PaintSingleObject(fGLPainter.get());
427 gPad->Update();
428 }
429 gGLManager->MarkForDirectCopy(glContext, kFALSE);
430 break;
431 }
432 }
433}
434
435////////////////////////////////////////////////////////////////////////////////
436///Get contour list.
437///I do not use this function. Contours are implemented in
438///a completely different way by gl-painters.
439
441{
442 return fDefaultPainter.get() ? fDefaultPainter->GetContourList(contour) : 0;
443}
444
445////////////////////////////////////////////////////////////////////////////////
446///Overrides TObject::GetObjectInfo.
447///For lego info is: bin numbers (i, j), bin content.
448///For TF2 info is: x,y,z 3d surface-point for 2d screen-point under cursor
449///(this can work incorrectly now, because of wrong code in TF2).
450///For TF3 no info now.
451///For box info is: bin numbers (i, j, k), bin content.
452
454{
455 static char errMsg[] = { "TGLHistPainter::GetObjectInfo: Error in a hist painter\n" };
457 return fDefaultPainter.get() ? fDefaultPainter->GetObjectInfo(px, py)
458 : errMsg;
459 else {
462 if (scale > 1.f) {
463 px *= scale;
464 py *= scale;
465 }
466
467 return gGLManager->GetPlotInfo(fGLPainter.get(), px, py);
468 }
469}
470
471////////////////////////////////////////////////////////////////////////////////
472/// Get stack.
473
475{
476 return fStack;
477}
478
479////////////////////////////////////////////////////////////////////////////////
480///Returns kTRUE if the cell ix, iy is inside one of the graphical cuts.
481///I do not use this function anywhere, this is a "default implementation".
482
484{
486 return fDefaultPainter.get() ? fDefaultPainter->IsInside(x, y) : kFALSE;
487
488 return kFALSE;
489}
490
491////////////////////////////////////////////////////////////////////////////////
492///Returns kTRUE if the cell x, y is inside one of the graphical cuts.
493///I do not use this function anywhere, this is a "default implementation".
494
496{
498 return fDefaultPainter.get() ? fDefaultPainter->IsInside(x, y) : kFALSE;
499
500 return kFALSE;
501}
502
503////////////////////////////////////////////////////////////////////////////////
504///Paint statistics.
505///This does not work on windows.
506
508{
509 if (fDefaultPainter.get())
510 fDefaultPainter->PaintStat(dostat, fit);
511}
512
513////////////////////////////////////////////////////////////////////////////////
514/// Process message.
515
516void TGLHistPainter::ProcessMessage(const char *m, const TObject *o)
517{
518 if (!std::strcmp(m, "SetF3"))
519 fF3 = (TF3 *)o;
520
521 if (fDefaultPainter.get())
522 fDefaultPainter->ProcessMessage(m, o);
523}
524
525////////////////////////////////////////////////////////////////////////////////
526/// Set highlight mode
527
529{
530 if (fDefaultPainter.get())
531 fDefaultPainter->SetHighlight();
532}
533
534////////////////////////////////////////////////////////////////////////////////
535/// Set histogram.
536
538{
539 fHist = h;
540
541 if (fDefaultPainter.get())
542 fDefaultPainter->SetHistogram(h);
543}
544
545////////////////////////////////////////////////////////////////////////////////
546/// Set stack.
547
549{
550 fStack = s;
551
552 if (fDefaultPainter.get())
553 fDefaultPainter->SetStack(s);
554}
555
556////////////////////////////////////////////////////////////////////////////////
557/// Make cuts.
558
560{
562 return fDefaultPainter->MakeCuts(o);
563
564 return 0;
565}
566
567struct TGLHistPainter::PlotOption_t {
569 EGLCoordType fCoordType;
570 Bool_t fBackBox;
571 Bool_t fFrontBox;
572 Bool_t fDrawAxes;
573 Bool_t fLogX;
574 Bool_t fLogY;
575 Bool_t fLogZ;
576};
577
578////////////////////////////////////////////////////////////////////////////////
579///Final-overrider for TObject::Paint.
580
582{
583 TString option(o);
584 option.ToLower();
585
586 const Ssiz_t glPos = option.Index("gl");
587 if (glPos != kNPOS)
588 option.Remove(glPos, 2);
590 gPad->SetCopyGLDevice(kFALSE);
591 if (fDefaultPainter.get())
592 fDefaultPainter->Paint(o);//option.Data());
593 return;
594 }
595
597 CreatePainter(ParsePaintOption(option), option);
598
599 if (fPlotType == kGLDefaultPlot) {
600 //In case of default plot pad
601 //should not copy gl-buffer (it will be simply black)
602
603 //[tp: code was commented.
604 //gPad->SetCopyGLDevice(kFALSE);
605 //tp]
606
607 if (fDefaultPainter.get())
608 fDefaultPainter->Paint(option.Data());
609 } else {
610 Int_t glContext = gPad->GetGLDevice();
611
612 if (glContext != -1) {
613 //With gl-plot, pad should copy
614 //gl-buffer into the final pad/canvas pixmap/DIB.
615 //fGLDevice.SetGLDevice(glContext);
616
617 //[tp: code commented.
618 //gPad->SetCopyGLDevice(kTRUE);
619 //tp]
620 //fGLPainter->SetGLDevice(&fGLDevice);
621 //Add viewport extraction here.
623 if (gPad->GetFrameFillColor() != kWhite)
624 fGLPainter->SetFrameColor(gROOT->GetColor(gPad->GetFrameFillColor()));
625 fGLPainter->SetPadColor(gROOT->GetColor(gPad->GetFillColor()));
626 if (fGLPainter->InitGeometry())
627 gGLManager->PaintSingleObject(fGLPainter.get());
628 }
629 }
630}
631
632namespace {
633
634Bool_t FindAndRemoveOption(TString &options, const char *toFind)
635{
636 const UInt_t len = std::strlen(toFind);
637 const Ssiz_t index = options.Index(toFind);
638
639 if (index != kNPOS) {
640 options.Remove(index, len);
641 return kTRUE;
642 }
643
644 return kFALSE;
645}
646
647}
648
649////////////////////////////////////////////////////////////////////////////////
650///In principle, we can have several conflicting options: "lego surf pol sph", surfbb: surf, fb, bb.
651///but only one will be selected, which one - depends on parsing order in this function.
652
653TGLHistPainter::PlotOption_t
655{
656 TString options(o);
657
658 PlotOption_t parsedOption = {kGLDefaultPlot, kGLCartesian,
659 kTRUE, kTRUE, kTRUE, //Show back box, show front box, show axes.
660 Bool_t(gPad->GetLogx()), Bool_t(gPad->GetLogy()),
661 Bool_t(gPad->GetLogz())};
662
663 //Check coordinate system type.
664 if (FindAndRemoveOption(options, "pol"))
665 parsedOption.fCoordType = kGLPolar;
666 if (FindAndRemoveOption(options, "cyl"))
667 parsedOption.fCoordType = kGLCylindrical;
668 if (FindAndRemoveOption(options, "sph"))
669 parsedOption.fCoordType = kGLSpherical;
670
671 //Define plot type.
672 if (FindAndRemoveOption(options, "lego"))
673 fStack ? parsedOption.fPlotType = kGLStackPlot : parsedOption.fPlotType = kGLLegoPlot;
674 if (FindAndRemoveOption(options, "surf"))
675 parsedOption.fPlotType = kGLSurfacePlot;
676 if (FindAndRemoveOption(options, "tf3"))
677 parsedOption.fPlotType = kGLTF3Plot;
678 if (FindAndRemoveOption(options, "box"))
679 parsedOption.fPlotType = kGLBoxPlot;
680 if (FindAndRemoveOption(options, "iso"))
681 parsedOption.fPlotType = kGLIsoPlot;
682 if (FindAndRemoveOption(options, "col"))
683 parsedOption.fPlotType = kGLVoxel;
684
685 //Check BB and FB options.
686 if (FindAndRemoveOption(options, "bb"))
687 parsedOption.fBackBox = kFALSE;
688 if (FindAndRemoveOption(options, "fb"))
689 parsedOption.fFrontBox = kFALSE;
690
691 //Check A option.
692 if (FindAndRemoveOption(options, "a"))
693 parsedOption.fDrawAxes = kFALSE;
694
695 return parsedOption;
696}
697
698////////////////////////////////////////////////////////////////////////////////
699/// Create painter.
700
701void TGLHistPainter::CreatePainter(const PlotOption_t &option, const TString &addOption)
702{
703 if (option.fPlotType != fPlotType) {
705 fGLPainter.reset(0);
706 }
707
708 if (option.fPlotType == kGLLegoPlot) {
709 if (!fGLPainter.get()) {
710 if (dynamic_cast<TH2Poly*>(fHist))
712 else
714 }
715 } else if (option.fPlotType == kGLSurfacePlot) {
716 if (!fGLPainter.get())
718 } else if (option.fPlotType == kGLBoxPlot) {
719 if (!fGLPainter.get())
721 } else if (option.fPlotType == kGLTF3Plot) {
722 if (!fGLPainter.get())
724 } else if (option.fPlotType == kGLIsoPlot) {
725 if (!fGLPainter.get())
727 } else if (option.fPlotType == kGLVoxel) {
728 if (!fGLPainter.get())
730 }
731
732 if (fGLPainter.get()) {
733 fPlotType = option.fPlotType;
734 fCoord.SetXLog(gPad->GetLogx());
735 fCoord.SetYLog(gPad->GetLogy());
736 fCoord.SetZLog(gPad->GetLogz());
737 fCoord.SetCoordType(option.fCoordType);
738 fGLPainter->AddOption(addOption);
739
740 fGLPainter->SetDrawFrontBox(option.fFrontBox);
741 fGLPainter->SetDrawBackBox(option.fBackBox);
742 fGLPainter->SetDrawAxes(option.fDrawAxes);
743 } else
745}
746
747////////////////////////////////////////////////////////////////////////////////
748/// Set show projection.
749
750void TGLHistPainter::SetShowProjection(const char *option, Int_t nbins)
751{
752 if (fDefaultPainter.get()) fDefaultPainter->SetShowProjection(option, nbins);
753}
754
755////////////////////////////////////////////////////////////////////////////////
756
758{
759 if (!fGLPainter.get())
760 return;
761
762 TGLRect vp;
763 vp.Width() = Int_t(gPad->GetAbsWNDC() * gPad->GetWw());
764 vp.Height() = Int_t(gPad->GetAbsHNDC() * gPad->GetWh());
765
766 vp.X() = Int_t(gPad->XtoAbsPixel(gPad->GetX1()));
767 vp.Y() = Int_t((gPad->GetWh() - gPad->YtoAbsPixel(gPad->GetY1())));
768
771
772 if (scale > 1.f) {
773 vp.X() = Int_t(vp.X() * scale);
774 vp.Y() = Int_t(vp.Y() * scale);
775
776 vp.Width() = Int_t(vp.Width() * scale);
777 vp.Height() = Int_t(vp.Height() * scale);
778 }
779
781 if (fCamera.ViewportChanged() && fGLPainter.get())
782 fGLPainter->InvalidateSelection();
783}
@ kMouseMotion
Definition: Buttons.h:23
@ kKeyPress
Definition: Buttons.h:20
@ kButton1Double
Definition: Buttons.h:24
@ kButton1Motion
Definition: Buttons.h:20
@ kButton1Up
Definition: Buttons.h:19
@ kButton2Up
Definition: Buttons.h:19
@ kButton1Down
Definition: Buttons.h:17
@ kKey_J
Definition: KeySymbols.h:135
@ kKey_W
Definition: KeySymbols.h:148
@ kKey_P
Definition: KeySymbols.h:141
@ kKey_Y
Definition: KeySymbols.h:150
@ kKey_L
Definition: KeySymbols.h:137
@ kKey_l
Definition: KeySymbols.h:169
@ kKey_C
Definition: KeySymbols.h:128
@ kKey_j
Definition: KeySymbols.h:167
@ kKey_x
Definition: KeySymbols.h:181
@ kKey_p
Definition: KeySymbols.h:173
@ kKey_Z
Definition: KeySymbols.h:151
@ kKey_y
Definition: KeySymbols.h:182
@ kKey_X
Definition: KeySymbols.h:149
@ kKey_S
Definition: KeySymbols.h:144
@ kKey_z
Definition: KeySymbols.h:183
@ kKey_s
Definition: KeySymbols.h:176
@ kKey_w
Definition: KeySymbols.h:180
@ kKey_c
Definition: KeySymbols.h:160
@ kKey_k
Definition: KeySymbols.h:168
@ kKey_K
Definition: KeySymbols.h:136
#define h(i)
Definition: RSha256.hxx:106
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
int Ssiz_t
Definition: RtypesCore.h:63
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:365
@ kWhite
Definition: Rtypes.h:63
EGLCoordType
Definition: TGLUtil.h:42
@ kGLSpherical
Definition: TGLUtil.h:46
@ kGLCylindrical
Definition: TGLUtil.h:45
@ kGLPolar
Definition: TGLUtil.h:44
@ kGLCartesian
Definition: TGLUtil.h:43
EGLPlotType
Definition: TGLUtil.h:50
@ kGLBoxPlot
Definition: TGLUtil.h:53
@ kGLTH3Composition
Definition: TGLUtil.h:59
@ kGLLegoPlot
Definition: TGLUtil.h:51
@ kGLIsoPlot
Definition: TGLUtil.h:57
@ kGLVoxel
Definition: TGLUtil.h:60
@ kGLSurfacePlot
Definition: TGLUtil.h:52
@ kGL5D
Definition: TGLUtil.h:58
@ kGLParametricPlot
Definition: TGLUtil.h:56
@ kGLTF3Plot
Definition: TGLUtil.h:54
@ kGLStackPlot
Definition: TGLUtil.h:55
@ kGLDefaultPlot
Definition: TGLUtil.h:61
#define gROOT
Definition: TROOT.h:415
#define gGLManager
Definition: TVirtualGL.h:162
#define gPad
Definition: TVirtualPad.h:286
@ kRotate
Definition: TVirtualX.h:46
1-Dim function class
Definition: TF1.h:211
A 3-Dim function with parameters.
Definition: TF3.h:28
TGL5DPainter implements "gl5d" option for TTree::Draw.
Definition: TGL5DPainter.h:32
Paints TH3 histograms by rendering variable-sized boxes matching the bin contents.
Definition: TGLBoxPainter.h:32
Paint TH2Poly.
The histogram painter class using OpenGL.
void DrawPanel()
Default implementation is OK This function is called from a context menu after right click on a plot'...
EGLPlotType fPlotType
TGLPlotCoordinates fCoord
PlotOption_t ParsePaintOption(const TString &option) const
In principle, we can have several conflicting options: "lego surf pol sph", surfbb: surf,...
void CreatePainter(const PlotOption_t &parsed, const TString &option)
Create painter.
char * GetObjectInfo(Int_t px, Int_t py) const
Overrides TObject::GetObjectInfo.
void SetHistogram(TH1 *hist)
Set histogram.
void SetStack(TList *stack)
Set stack.
Bool_t IsInside(Int_t x, Int_t y)
Returns kTRUE if the cell ix, iy is inside one of the graphical cuts.
void Paint(Option_t *option)
Final-overrider for TObject::Paint.
void PadToViewport(Bool_t selectionPass=kFALSE)
void ProcessMessage(const char *message, const TObject *obj)
Process message.
std::unique_ptr< TGLPlotPainter > fGLPainter
void PaintStat(Int_t dostat, TF1 *fit)
Paint statistics.
Int_t MakeCuts(char *cutsOpt)
Make cuts.
std::unique_ptr< TVirtualHistPainter > fDefaultPainter
void SetHighlight()
Set highlight mode.
TGLPlotCamera fCamera
void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute event.
TList * GetContourList(Double_t contour) const
Get contour list.
Int_t DistancetoPrimitive(Int_t px, Int_t py)
Selects plot or axis.
TList * GetStack() const
Get stack.
TGLHistPainter(TH1 *hist)
ROOT does not use exceptions, so, if default painter's creation failed, fDefaultPainter is 0.
void SetShowProjection(const char *option, Int_t nbins)
Set show projection.
"gliso" option for TH3.
Definition: TGLTF3Painter.h:85
Plot-painter implementing LEGO rendering of TH2 histograms in cartesian, polar, cylindrical and spher...
A parametric surface is a surface defined by a parametric equation, involving two parameters (u,...
Definition: TGLParametric.h:35
Bool_t ViewportChanged() const
Definition: TGLPlotCamera.h:53
void SetViewport(const TGLRect &vp)
Setup viewport, if it was changed, plus reset arcball.
void RotateCamera(Int_t px, Int_t py)
Mouse movement.
void ZoomIn()
Zoom in.
void ZoomOut()
Zoom out.
void StartRotation(Int_t px, Int_t py)
User clicks somewhere (px, py).
void SetXLog(Bool_t xLog)
If log changed, sections must be reset, set fModified.
void SetCoordType(EGLCoordType type)
If coord type was changed, plot must reset sections (if any), set fModified.
void ResetModified()
Reset modified.
void SetZLog(Bool_t zLog)
If log changed, sections must be reset, set fModified.
void SetYLog(Bool_t yLog)
If log changed, sections must be reset, set fModified.
Viewport (pixel base) 2D rectangle class.
Definition: TGLUtil.h:421
Int_t Y() const
Definition: TGLUtil.h:447
Int_t Height() const
Definition: TGLUtil.h:451
Int_t Width() const
Definition: TGLUtil.h:449
Int_t X() const
Definition: TGLUtil.h:445
Implements painting of TH2 with "SURF" option.
Plot-painter for TF3 functions.
Definition: TGLTF3Painter.h:29
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition: TGLUtil.cxx:1577
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition: TGLUtil.cxx:1847
Paint TH3 histograms as "voxels" - colored boxes, transparent if transfer function was specified.
The TH1 histogram class.
Definition: TH1.h:56
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:66
A doubly linked list.
Definition: TList.h:44
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
Basic string class.
Definition: TString.h:131
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
const char * Data() const
Definition: TString.h:364
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Abstract interface to a histogram painter.
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
static constexpr double s
auto * m
Definition: textangle.C:8