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