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