Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLVoxelPainter.cxx
Go to the documentation of this file.
1#include <algorithm>
2
3#include "KeySymbols.h"
4#include "TVirtualX.h"
5#include "Buttons.h"
6#include "TString.h"
7#include "TROOT.h"
8#include "TList.h"
9#include "TStyle.h"
10#include "TH3.h"
11#include "TF1.h"
12
13#include "TGLVoxelPainter.h"
14#include "TGLPlotCamera.h"
15#include "TGLIncludes.h"
16
17/** \class TGLVoxelPainter
18\ingroup opengl
19Paint TH3 histograms as "voxels" - colored boxes, transparent if transfer function was specified.
20*/
21
23
24////////////////////////////////////////////////////////////////////////////////
25/// Constructor.
26///This plot always needs a palette.
27
29 : TGLPlotPainter(hist, cam, coord, kFALSE, kFALSE, kFALSE),
30 fTransferFunc(nullptr)
31{
33}
34
35
36////////////////////////////////////////////////////////////////////////////////
37///Show box info (i, j, k, binContent).
38
40{
41 fPlotInfo = "";
42
43 if (fSelectedPart) {
45 if (fHist->Class())
47 fPlotInfo += "::";
49 } else if (!fHighColor){
50 const Int_t arr2Dsize = fCoord->GetNYBins() * fCoord->GetNZBins();
51 const Int_t binI = (fSelectedPart - fSelectionBase) / arr2Dsize + fCoord->GetFirstXBin();
52 const Int_t binJ = (fSelectedPart - fSelectionBase) % arr2Dsize / fCoord->GetNZBins() + fCoord->GetFirstYBin();
53 const Int_t binK = (fSelectedPart - fSelectionBase) % arr2Dsize % fCoord->GetNZBins() + fCoord->GetFirstZBin();
54
55 fPlotInfo.Form("(binx = %d; biny = %d; binz = %d; binc = %f)", binI, binJ, binK,
56 fHist->GetBinContent(binI, binJ, binK));
57 } else
58 fPlotInfo = "Switch to true color mode to get correct info";
59 }
60
61 return (Char_t *)fPlotInfo.Data();
62}
63
64
65////////////////////////////////////////////////////////////////////////////////
66///Set ranges, find min and max bin content.
67
69{
73
74 if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))//kFALSE == drawErrors, kTRUE == zAsBins
75 return kFALSE;
76
79
81 fMinMaxVal.first = fMinMaxVal.second;
82 //Bad. You can up-date some bin value and get wrong picture.
83 for (Int_t ir = fCoord->GetFirstXBin(); ir <= fCoord->GetLastXBin(); ++ir) {
84 for (Int_t jr = fCoord->GetFirstYBin(); jr <= fCoord->GetLastYBin(); ++jr) {
85 for (Int_t kr = fCoord->GetFirstZBin(); kr <= fCoord->GetLastZBin(); ++kr) {
86 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, fHist->GetBinContent(ir, jr, kr));
87 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, fHist->GetBinContent(ir, jr, kr));
88 }
89 }
90 }
91
92 if (fCoord->Modified()) {
98 }
99
100 const TList *funcList = fHist->GetListOfFunctions();
101 fTransferFunc = dynamic_cast<TF1*>(funcList->FindObject("TransferFunction"));
102
103 return kTRUE;
104}
105
106
107////////////////////////////////////////////////////////////////////////////////
108/// User clicks right mouse button (in a pad).
109
111{
112 fMousePosition.fX = px;
114 fCamera->StartPan(px, py);
116}
117
118
119////////////////////////////////////////////////////////////////////////////////
120/// User's moving mouse cursor, with middle mouse button pressed (for pad).
121/// Calculate 3d shift related to 2d mouse movement.
122
124{
125 // User's moving mouse cursor, with middle mouse button pressed (for pad).
126 // Calculate 3d shift related to 2d mouse movement.
127 if (fSelectedPart >= fSelectionBase) {//Pan camera.
130
133 fCamera->Pan(px, py);
134
137 } else if (fSelectedPart > 0) {
138 //Convert py into bottom-top orientation.
139 //Possibly, move box here
140 py = fCamera->GetHeight() - py;
143
146
147
148 if (!fHighColor) {
151 else
152 MoveSection(px, py);
153 } else {
154 MoveSection(px, py);
155 }
156
159 }
160
163}
164
165
166////////////////////////////////////////////////////////////////////////////////
167/// "z" draw palette or not.
168
170{
171 option.Index("z") == kNPOS ? fDrawPalette = kFALSE : fDrawPalette = kTRUE;
172
173}
174
175////////////////////////////////////////////////////////////////////////////////
176/// Remove sections, switch on/off box cut.
177
179{
180 if (event == kButton1Double && fBoxCut.IsActive()) {
181 if (fBoxCut.IsActive())
183 if (!gVirtualX->IsCmdThread())
184 gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%zx)->Paint()", (size_t)this));
185 else
186 Paint();
187 } else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
188 if (fHighColor)
189 Info("ProcessEvent", "Switch to true color mode to use box cut");
190 else {
193 }
194 }
195}
196
197////////////////////////////////////////////////////////////////////////////////
198/// Initialize some gl state variables.
199
201{
202 glEnable(GL_DEPTH_TEST);
203 glEnable(GL_LIGHTING);
204 glEnable(GL_LIGHT0);
205
206 glEnable(GL_CULL_FACE);
207 glCullFace(GL_BACK);
208
209 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
210}
211
212////////////////////////////////////////////////////////////////////////////////
213/// Return back some gl state variables.
214
216{
217 glDisable(GL_DEPTH_TEST);
218 glDisable(GL_LIGHTING);
219 glDisable(GL_LIGHT0);
220 glDisable(GL_CULL_FACE);
221 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
222}
223
224////////////////////////////////////////////////////////////////////////////////
225/// Draw "voxels".
226
228{
229 //Shift plot to point of origin.
230 const Rgl::PlotTranslation trGuard(this);
231
232 if (!fSelectionPass)
234
236
237 TGLDisableGuard depthTest(GL_DEPTH_TEST);
238
239 if (!fSelectionPass) {
240 glEnable(GL_BLEND);//[1
241 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
242 }
243
244 //Using front point, find the correct order to draw boxes from
245 //back to front/from bottom to top (it's important only for semi-transparent boxes).
246 const Int_t frontPoint = fBackBox.GetFrontPoint();
247 Int_t irInit = fCoord->GetFirstXBin(), iInit = 0;
248 const Int_t nX = fCoord->GetNXBins();
249 Int_t jrInit = fCoord->GetFirstYBin(), jInit = 0;
250 const Int_t nY = fCoord->GetNYBins();
251 Int_t krInit = fCoord->GetFirstZBin(), kInit = 0;
252 const Int_t nZ = fCoord->GetNZBins();
253
254 const Int_t addI = frontPoint == 2 || frontPoint == 1 ? 1 : (iInit = nX - 1, irInit = fCoord->GetLastXBin(), -1);
255 const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? 1 : (jInit = nY - 1, jrInit = fCoord->GetLastYBin(), -1);
256 const Int_t addK = fBackBox.Get2DBox()[frontPoint + 4].Y() > fBackBox.Get2DBox()[frontPoint].Y() ? 1
257 : (kInit = nZ - 1, krInit = fCoord->GetLastZBin(),-1);
258 const Double_t xScale = fCoord->GetXScale();
259 const Double_t yScale = fCoord->GetYScale();
260 const Double_t zScale = fCoord->GetZScale();
261 const TAxis *xA = fXAxis;
262 const TAxis *yA = fYAxis;
263 const TAxis *zA = fZAxis;
264
267
268 Double_t maxContent = TMath::Max(TMath::Abs(fMinMaxVal.first), TMath::Abs(fMinMaxVal.second));
269 if(!maxContent)//bad, find better way to check zero.
270 maxContent = 1.;
271
272 Float_t rgba[4] = {};
273
277 Double_t binContent;
278
279 for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
280 for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
281 for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
282 const Double_t xMin = xScale * xA->GetBinLowEdge(ir);
283 const Double_t xMax = xScale * xA->GetBinUpEdge(ir);
284 const Double_t yMin = yScale * yA->GetBinLowEdge(jr);
285 const Double_t yMax = yScale * yA->GetBinUpEdge(jr);
286 const Double_t zMin = zScale * zA->GetBinLowEdge(kr);
287 const Double_t zMax = zScale * zA->GetBinUpEdge(kr);
288
289 if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
290 continue;
291
292 binContent = fHist->GetBinContent(ir, jr, kr);
293 if (binContent < wmin) continue;
294 if (binContent > wmax) binContent = wmax;
295
296 FindVoxelColor(binContent, rgba);
297
298 if (rgba[3] < 0.01f)
299 continue;
300
301 if (!fSelectionPass)
302 SetVoxelColor(rgba);
303
304 const Int_t binID = fSelectionBase + i * fCoord->GetNZBins() * fCoord->GetNYBins() + j * fCoord->GetNZBins() + k;
305
308 else if(!fHighColor && fSelectedPart == binID)
309 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
310
311 Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
312
313 if (!fSelectionPass && !fHighColor && fSelectedPart == binID)
314 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
315 }
316 }
317 }
318
319 if (fBoxCut.IsActive())
321
322 if (!fSelectionPass) {
323 if (fDrawPalette)
324 DrawPalette();
325 glDisable(GL_BLEND);//1]
326 }
327}
328
329////////////////////////////////////////////////////////////////////////////////
330/// Noop.
331
333{
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// Noop.
338
340{
341}
342
343
344////////////////////////////////////////////////////////////////////////////////
345/// Noop.
346
348{
349}
350
351////////////////////////////////////////////////////////////////////////////////
352///Draw. Palette.
353
355{
357 return;
358
361 else
363
364 glFinish();
365
368}
369
370////////////////////////////////////////////////////////////////////////////////
371///Draw. Palette. Axis.
372
374{
375 if (fCamera) {
376 gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
378 }
379}
380
381////////////////////////////////////////////////////////////////////////////////
382///Generate palette.
383
385{
386 if(fMinMaxVal.first == fMinMaxVal.second)
387 return;//must be std::abs(fMinMaxVal.second - fMinMaxVal.first) < ...
388
389 fLevels.clear();
390 UInt_t paletteSize = 0;
391
393 if (const UInt_t trySize = fHist->GetContour()) {
394 fLevels.reserve(trySize);
395
396 for (UInt_t i = 0; i < trySize; ++i) {
397 const Double_t level = fHist->GetContourLevel(Int_t(i));
398 if (level <= fMinMaxVal.first || level >= fMinMaxVal.second)
399 continue;
400 fLevels.push_back(level);
401 }
402 //sort levels
403 if (!fLevels.empty()) {
404 std::sort(fLevels.begin(), fLevels.end());
405 fLevels.push_back(fMinMaxVal.second);
406 fLevels.insert(fLevels.begin(), fMinMaxVal.first);
408 paletteSize = fLevels.size() - 1;
409 }
410 }
411
412 if (!paletteSize)
414 }
415
416 if (!paletteSize && !(paletteSize = gStyle->GetNumberContours()))
417 paletteSize = 20;
418
419 fPalette.GeneratePalette(paletteSize, fMinMaxVal);
420}
421
422////////////////////////////////////////////////////////////////////////////////
423/// Find box color.
424
426{
427 const UChar_t * tc = fPalette.GetColour(binContent);
428 rgba[3] = 0.06f; //Just a constant transparency.
429
430
431 if (fTransferFunc) {
432 rgba[3] = fTransferFunc->Eval(binContent);
433 }
434
435 rgba[0] = tc[0] / 255.f;
436 rgba[1] = tc[1] / 255.f;
437 rgba[2] = tc[2] / 255.f;
438}
439
440
441////////////////////////////////////////////////////////////////////////////////
442/// Set box color.
443
444void TGLVoxelPainter::SetVoxelColor(const Float_t *diffColor)const
445{
446 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
447 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
448 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
449 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
450}
@ kKeyPress
Definition Buttons.h:20
@ kButton1Double
Definition Buttons.h:24
#define GL_TRUE
Definition GL_glu.h:262
#define GL_FALSE
Definition GL_glu.h:261
@ kKey_C
Definition KeySymbols.h:128
@ kKey_c
Definition KeySymbols.h:160
int Int_t
Definition RtypesCore.h:45
unsigned char UChar_t
Definition RtypesCore.h:38
char Char_t
Definition RtypesCore.h:37
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
#define ClassImp(name)
Definition Rtypes.h:377
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t wmin
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t wmax
#define gROOT
Definition TROOT.h:406
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
R__EXTERN TStyle * gStyle
Definition TStyle.h:433
#define gVirtualX
Definition TVirtualX.h:337
Class to manage histogram axis.
Definition TAxis.h:31
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:518
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:528
1-Dim function class
Definition TF1.h:233
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition TF1.cxx:1441
void MoveBox(Int_t px, Int_t py, Int_t axisID)
Move box cut along selected direction.
Bool_t IsInCut(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax) const
Check, if box defined by xmin/xmax etc. is in cut.
void DrawBox(Bool_t selectionPass, Int_t selected) const
Draw cut as a semi-transparent box.
void TurnOnOff()
Turn the box cut on/off.
void StartMovement(Int_t px, Int_t py)
Start cut's movement.
Bool_t IsActive() const
const UChar_t * GetColour(Double_t z) const
Get color.
Definition TGLUtil.cxx:4300
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition TGLUtil.cxx:4263
void SetContours(const std::vector< Double_t > *contours)
Clear :)
Definition TGLUtil.cxx:4227
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition TGLUtil.cxx:4170
void SetPlotBox(const Rgl::Range_t &xRange, const Rgl::Range_t &yRange, const Rgl::Range_t &zRange)
Set up a frame box.
const TGLVertex3 * Get3DBox() const
Get 3D box.
const TGLVertex3 * Get2DBox() const
Get 2D box.
void DrawBox(Int_t selectedPart, Bool_t selectionPass, const std::vector< Double_t > &zLevels, Bool_t highColor) const
Draw back box for a plot.
Int_t GetFrontPoint() const
The nearest point.
Camera for TGLPlotPainter and sub-classes.
void StartPan(Int_t px, Int_t py)
User clicks somewhere (px, py).
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
void SetCamera() const
Viewport and projection.
void Pan(Int_t px, Int_t py)
Pan camera.
Int_t GetHeight() const
viewport[3]
void SetViewVolume(const TGLVertex3 *box)
'box' is the TGLPlotPainter's back box's coordinates.
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
void SetXLog(Bool_t xLog)
If log changed, sections must be reset, set fModified.
Bool_t SetRanges(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges.
Double_t GetYScale() const
const Rgl::Range_t & GetXRangeScaled() const
Scaled range.
Int_t GetFirstXBin() const
Int_t GetFirstYBin() const
const Rgl::Range_t & GetYRangeScaled() const
Scaled range.
void ResetModified()
Reset modified.
Bool_t Modified() const
Modified.
Double_t GetXScale() const
Double_t GetZScale() const
Int_t GetLastZBin() const
Int_t GetNXBins() const
Number of X bins.
Int_t GetFirstZBin() const
const Rgl::Range_t & GetZRangeScaled() const
Scaled range.
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.
Int_t GetLastYBin() const
Int_t GetNYBins() const
Number of Y bins.
Int_t GetLastXBin() const
Int_t GetNZBins() const
Number of Z bins.
Base class for plot-painters that provide GL rendering of various 2D and 3D histograms,...
std::vector< Double_t > fZLevels
Double_t fXOYSectionPos
void RestoreModelviewMatrix() const
Double_t fXOZSectionPos
TGLPlotCoordinates * fCoord
void Paint() override
Draw lego/surf/whatever you can.
TGLPlotBox fBackBox
void SaveProjectionMatrix() const
void SaveModelviewMatrix() const
void MoveSection(Int_t px, Int_t py)
Create dynamic profile using selected plane.
TGLPlotCamera * fCamera
void RestoreProjectionMatrix() const
Double_t fYOZSectionPos
Double_t X() const
Definition TGLUtil.h:119
Double_t Z() const
Definition TGLUtil.h:123
Double_t Y() const
Definition TGLUtil.h:121
Paint TH3 histograms as "voxels" - colored boxes, transparent if transfer function was specified.
void DrawPlot() const override
Draw "voxels".
void SetVoxelColor(const Float_t *rgba) const
Set box color.
void DrawSectionXOZ() const override
Noop.
void ProcessEvent(Int_t event, Int_t px, Int_t py) override
Remove sections, switch on/off box cut.
void Pan(Int_t px, Int_t py) override
User's moving mouse cursor, with middle mouse button pressed (for pad).
void AddOption(const TString &stringOption) override
"z" draw palette or not.
Rgl::Range_t fMinMaxVal
void PreparePalette() const
Generate palette.
void DrawPalette() const
Draw. Palette.
TGLVoxelPainter(const TGLVoxelPainter &)=delete
void DeInitGL() const override
Return back some gl state variables.
void InitGL() const override
Initialize some gl state variables.
void DrawSectionYOZ() const override
Noop.
char * GetPlotInfo(Int_t px, Int_t py) override
Show box info (i, j, k, binContent).
Bool_t InitGeometry() override
Set ranges, find min and max bin content.
TGLLevelPalette fPalette
void DrawPaletteAxis() const override
Draw. Palette. Axis.
void FindVoxelColor(Double_t binContent, Float_t *rgba) const
Find box color.
void StartPan(Int_t px, Int_t py) override
User clicks right mouse button (in a pad).
std::vector< Double_t > fLevels
void DrawSectionXOY() const override
Noop.
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
static TClass * Class()
@ kUserContour
User specified contour levels.
Definition TH1.h:166
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition TH1.cxx:8513
TList * GetListOfFunctions() const
Definition TH1.h:244
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5029
virtual Int_t GetContour(Double_t *levels=nullptr)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8379
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8398
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition TH1.cxx:8603
A doubly linked list.
Definition TList.h:38
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:576
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
void ResetBit(UInt_t f)
Definition TObject.h:198
SCoord_t fY
Definition TPoint.h:36
SCoord_t fX
Definition TPoint.h:35
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:376
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2356
Int_t GetNumberContours() const
Definition TStyle.h:239
const Float_t gNullEmission[]
Definition TGLUtil.cxx:2856
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition TGLUtil.cxx:2900
void DrawPalette(const TGLPlotCamera *camera, const TGLLevelPalette &palette)
Draw. Palette.
void DrawPaletteAxis(const TGLPlotCamera *camera, const Range_t &minMax, Bool_t logZ)
void DrawBoxFront(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax, Int_t fp)
Draws lego's bar as a 3d box.
Definition TGLUtil.cxx:3016
const Float_t gOrangeEmission[]
Definition TGLUtil.cxx:2853
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123