Logo ROOT  
Reference Guide
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 "TClass.h"
9#include "TColor.h"
10#include "TStyle.h"
11#include "TH3.h"
12#include "TF1.h"
13
14#include "TGLVoxelPainter.h"
15#include "TGLPlotCamera.h"
16#include "TGLIncludes.h"
17
18/** \class TGLVoxelPainter
19\ingroup opengl
20Paint TH3 histograms as "voxels" - colored boxes, transparent if transfer function was specified.
21*/
22
24
25////////////////////////////////////////////////////////////////////////////////
26/// Constructor.
27///This plot always needs a palette.
28
30 : TGLPlotPainter(hist, cam, coord, kFALSE, kFALSE, kFALSE),
31 fTransferFunc(0)
32{
34}
35
36
37////////////////////////////////////////////////////////////////////////////////
38///Show box info (i, j, k, binContent).
39
41{
42 fPlotInfo = "";
43
44 if (fSelectedPart) {
46 if (fHist->Class())
47 fPlotInfo += fHist->Class()->GetName();
48 fPlotInfo += "::";
50 } else if (!fHighColor){
51 const Int_t arr2Dsize = fCoord->GetNYBins() * fCoord->GetNZBins();
52 const Int_t binI = (fSelectedPart - fSelectionBase) / arr2Dsize + fCoord->GetFirstXBin();
53 const Int_t binJ = (fSelectedPart - fSelectionBase) % arr2Dsize / fCoord->GetNZBins() + fCoord->GetFirstYBin();
54 const Int_t binK = (fSelectedPart - fSelectionBase) % arr2Dsize % fCoord->GetNZBins() + fCoord->GetFirstZBin();
55
56 fPlotInfo.Form("(binx = %d; biny = %d; binz = %d; binc = %f)", binI, binJ, binK,
57 fHist->GetBinContent(binI, binJ, binK));
58 } else
59 fPlotInfo = "Switch to true color mode to get correct info";
60 }
61
62 return (Char_t *)fPlotInfo.Data();
63}
64
65
66////////////////////////////////////////////////////////////////////////////////
67///Set ranges, find min and max bin content.
68
70{
74
75 if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))//kFALSE == drawErrors, kTRUE == zAsBins
76 return kFALSE;
77
80
82 fMinMaxVal.first = fMinMaxVal.second;
83 //Bad. You can up-date some bin value and get wrong picture.
84 for (Int_t ir = fCoord->GetFirstXBin(); ir <= fCoord->GetLastXBin(); ++ir) {
85 for (Int_t jr = fCoord->GetFirstYBin(); jr <= fCoord->GetLastYBin(); ++jr) {
86 for (Int_t kr = fCoord->GetFirstZBin(); kr <= fCoord->GetLastZBin(); ++kr) {
87 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, fHist->GetBinContent(ir, jr, kr));
88 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, fHist->GetBinContent(ir, jr, kr));
89 }
90 }
91 }
92
93 if (fCoord->Modified()) {
99 }
100
101 const TList *funcList = fHist->GetListOfFunctions();
102 fTransferFunc = dynamic_cast<TF1*>(funcList->FindObject("TransferFunction"));
103
104 return kTRUE;
105}
106
107
108////////////////////////////////////////////////////////////////////////////////
109/// User clicks right mouse button (in a pad).
110
112{
113 fMousePosition.fX = px;
115 fCamera->StartPan(px, py);
117}
118
119
120////////////////////////////////////////////////////////////////////////////////
121/// User's moving mouse cursor, with middle mouse button pressed (for pad).
122/// Calculate 3d shift related to 2d mouse movement.
123
125{
126 // User's moving mouse cursor, with middle mouse button pressed (for pad).
127 // Calculate 3d shift related to 2d mouse movement.
128 if (fSelectedPart >= fSelectionBase) {//Pan camera.
131
134 fCamera->Pan(px, py);
135
138 } else if (fSelectedPart > 0) {
139 //Convert py into bottom-top orientation.
140 //Possibly, move box here
141 py = fCamera->GetHeight() - py;
144
147
148
149 if (!fHighColor) {
152 else
153 MoveSection(px, py);
154 } else {
155 MoveSection(px, py);
156 }
157
160 }
161
164}
165
166
167////////////////////////////////////////////////////////////////////////////////
168/// "z" draw palette or not.
169
171{
172 option.Index("z") == kNPOS ? fDrawPalette = kFALSE : fDrawPalette = kTRUE;
173
174}
175
176////////////////////////////////////////////////////////////////////////////////
177/// Remove sections, switch on/off box cut.
178
180{
181 if (event == kButton1Double && fBoxCut.IsActive()) {
182 if (fBoxCut.IsActive())
184 if (!gVirtualX->IsCmdThread())
185 gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%lx)->Paint()", ULong_t(this)));
186 else
187 Paint();
188 } else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
189 if (fHighColor)
190 Info("ProcessEvent", "Switch to true color mode to use box cut");
191 else {
194 }
195 }
196}
197
198////////////////////////////////////////////////////////////////////////////////
199/// Initialize some gl state variables.
200
202{
203 glEnable(GL_DEPTH_TEST);
204 glEnable(GL_LIGHTING);
205 glEnable(GL_LIGHT0);
206
207 glEnable(GL_CULL_FACE);
208 glCullFace(GL_BACK);
209
210 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
211}
212
213////////////////////////////////////////////////////////////////////////////////
214/// Return back some gl state variables.
215
217{
218 glDisable(GL_DEPTH_TEST);
219 glDisable(GL_LIGHTING);
220 glDisable(GL_LIGHT0);
221 glDisable(GL_CULL_FACE);
222 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
223}
224
225////////////////////////////////////////////////////////////////////////////////
226/// Draw "voxels".
227
229{
230 //Shift plot to point of origin.
231 const Rgl::PlotTranslation trGuard(this);
232
233 if (!fSelectionPass)
235
237
238 TGLDisableGuard depthTest(GL_DEPTH_TEST);
239
240 if (!fSelectionPass) {
241 glEnable(GL_BLEND);//[1
242 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
243 }
244
245 //Using front point, find the correct order to draw boxes from
246 //back to front/from bottom to top (it's important only for semi-transparent boxes).
247 const Int_t frontPoint = fBackBox.GetFrontPoint();
248 Int_t irInit = fCoord->GetFirstXBin(), iInit = 0;
249 const Int_t nX = fCoord->GetNXBins();
250 Int_t jrInit = fCoord->GetFirstYBin(), jInit = 0;
251 const Int_t nY = fCoord->GetNYBins();
252 Int_t krInit = fCoord->GetFirstZBin(), kInit = 0;
253 const Int_t nZ = fCoord->GetNZBins();
254
255 const Int_t addI = frontPoint == 2 || frontPoint == 1 ? 1 : (iInit = nX - 1, irInit = fCoord->GetLastXBin(), -1);
256 const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? 1 : (jInit = nY - 1, jrInit = fCoord->GetLastYBin(), -1);
257 const Int_t addK = fBackBox.Get2DBox()[frontPoint + 4].Y() > fBackBox.Get2DBox()[frontPoint].Y() ? 1
258 : (kInit = nZ - 1, krInit = fCoord->GetLastZBin(),-1);
259 const Double_t xScale = fCoord->GetXScale();
260 const Double_t yScale = fCoord->GetYScale();
261 const Double_t zScale = fCoord->GetZScale();
262 const TAxis *xA = fXAxis;
263 const TAxis *yA = fYAxis;
264 const TAxis *zA = fZAxis;
265
268
269 Double_t maxContent = TMath::Max(TMath::Abs(fMinMaxVal.first), TMath::Abs(fMinMaxVal.second));
270 if(!maxContent)//bad, find better way to check zero.
271 maxContent = 1.;
272
273 Float_t rgba[4] = {};
274
275 Double_t wmin = TMath::Max(fHist->GetMinimum(),0.);
278 Double_t binContent;
279
280 for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
281 for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
282 for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
283 const Double_t xMin = xScale * xA->GetBinLowEdge(ir);
284 const Double_t xMax = xScale * xA->GetBinUpEdge(ir);
285 const Double_t yMin = yScale * yA->GetBinLowEdge(jr);
286 const Double_t yMax = yScale * yA->GetBinUpEdge(jr);
287 const Double_t zMin = zScale * zA->GetBinLowEdge(kr);
288 const Double_t zMax = zScale * zA->GetBinUpEdge(kr);
289
290 if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
291 continue;
292
293 binContent = fHist->GetBinContent(ir, jr, kr);
294 if (binContent < wmin) continue;
295 if (binContent > wmax) binContent = wmax;
296
297 FindVoxelColor(binContent, rgba);
298
299 if (rgba[3] < 0.01f)
300 continue;
301
302 if (!fSelectionPass)
303 SetVoxelColor(rgba);
304
305 const Int_t binID = fSelectionBase + i * fCoord->GetNZBins() * fCoord->GetNYBins() + j * fCoord->GetNZBins() + k;
306
309 else if(!fHighColor && fSelectedPart == binID)
310 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
311
312 Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
313
314 if (!fSelectionPass && !fHighColor && fSelectedPart == binID)
315 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
316 }
317 }
318 }
319
320 if (fBoxCut.IsActive())
322
323 if (!fSelectionPass) {
324 if (fDrawPalette)
325 DrawPalette();
326 glDisable(GL_BLEND);//1]
327 }
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Noop.
332
334{
335}
336
337////////////////////////////////////////////////////////////////////////////////
338/// Noop.
339
341{
342}
343
344
345////////////////////////////////////////////////////////////////////////////////
346/// Noop.
347
349{
350}
351
352////////////////////////////////////////////////////////////////////////////////
353///Draw. Palette.
354
356{
358 return;
359
362 else
364
365 glFinish();
366
369}
370
371////////////////////////////////////////////////////////////////////////////////
372///Draw. Palette. Axis.
373
375{
376 if (fCamera) {
377 gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
379 }
380}
381
382////////////////////////////////////////////////////////////////////////////////
383///Generate palette.
384
386{
387 if(fMinMaxVal.first == fMinMaxVal.second)
388 return;//must be std::abs(fMinMaxVal.second - fMinMaxVal.first) < ...
389
390 fLevels.clear();
391 UInt_t paletteSize = 0;
392
394 if (const UInt_t trySize = fHist->GetContour()) {
395 fLevels.reserve(trySize);
396
397 for (UInt_t i = 0; i < trySize; ++i) {
398 const Double_t level = fHist->GetContourLevel(Int_t(i));
399 if (level <= fMinMaxVal.first || level >= fMinMaxVal.second)
400 continue;
401 fLevels.push_back(level);
402 }
403 //sort levels
404 if (fLevels.size()) {
405 std::sort(fLevels.begin(), fLevels.end());
406 fLevels.push_back(fMinMaxVal.second);
407 fLevels.insert(fLevels.begin(), fMinMaxVal.first);
409 paletteSize = fLevels.size() - 1;
410 }
411 }
412
413 if (!paletteSize)
415 }
416
417 if (!paletteSize && !(paletteSize = gStyle->GetNumberContours()))
418 paletteSize = 20;
419
420 fPalette.GeneratePalette(paletteSize, fMinMaxVal);
421}
422
423////////////////////////////////////////////////////////////////////////////////
424/// Find box color.
425
427{
428 const UChar_t * tc = fPalette.GetColour(binContent);
429 rgba[3] = 0.06f; //Just a constant transparency.
430
431
432 if (fTransferFunc) {
433 rgba[3] = fTransferFunc->Eval(binContent);
434 }
435
436 rgba[0] = tc[0] / 255.f;
437 rgba[1] = tc[1] / 255.f;
438 rgba[2] = tc[2] / 255.f;
439}
440
441
442////////////////////////////////////////////////////////////////////////////////
443/// Set box color.
444
445void TGLVoxelPainter::SetVoxelColor(const Float_t *diffColor)const
446{
447 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
448 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
449 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
450 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
451}
@ 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
const Ssiz_t kNPOS
Definition: RtypesCore.h:113
int Int_t
Definition: RtypesCore.h:43
unsigned char UChar_t
Definition: RtypesCore.h:36
char Char_t
Definition: RtypesCore.h:31
const Bool_t kFALSE
Definition: RtypesCore.h:90
unsigned long ULong_t
Definition: RtypesCore.h:53
double Double_t
Definition: RtypesCore.h:57
float Float_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:89
#define ClassImp(name)
Definition: Rtypes.h:361
void Info(const char *location, const char *msgfmt,...)
#define gROOT
Definition: TROOT.h:406
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:410
#define gVirtualX
Definition: TVirtualX.h:338
Class to manage histogram axis.
Definition: TAxis.h:30
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:515
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:525
1-Dim function class
Definition: TF1.h:210
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:1432
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:4292
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition: TGLUtil.cxx:4255
void SetContours(const std::vector< Double_t > *contours)
Clear :)
Definition: TGLUtil.cxx:4219
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition: TGLUtil.cxx:4162
void SetPlotBox(const Rgl::Range_t &xRange, const Rgl::Range_t &yRange, const Rgl::Range_t &zRange)
Set up a frame box.
Definition: TGLPlotBox.cxx:198
const TGLVertex3 * Get3DBox() const
Get 3D box.
Definition: TGLPlotBox.cxx:303
const TGLVertex3 * Get2DBox() const
Get 2D box.
Definition: TGLPlotBox.cxx:312
void DrawBox(Int_t selectedPart, Bool_t selectionPass, const std::vector< Double_t > &zLevels, Bool_t highColor) const
Draw back box for a plot.
Definition: TGLPlotBox.cxx:184
Int_t GetFrontPoint() const
The nearest point.
Definition: TGLPlotBox.cxx:294
Camera for TGLPlotPainter and sub-classes.
Definition: TGLPlotCamera.h:22
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,...
Double_t fPadTheta
std::vector< Double_t > fZLevels
Double_t fXOYSectionPos
void RestoreModelviewMatrix() const
Double_t fXOZSectionPos
TGLBoxCut fBoxCut
virtual void Paint()
Draw lego/surf/whatever you can.
TGLPlotCoordinates * fCoord
TGLPlotBox fBackBox
void SaveProjectionMatrix() const
void SaveModelviewMatrix() const
void MoveSection(Int_t px, Int_t py)
Create dynamic profile using selected plane.
Bool_t fUpdateSelection
TGLPlotCamera * fCamera
void RestoreProjectionMatrix() const
Double_t fYOZSectionPos
Double_t X() const
Definition: TGLUtil.h:118
Double_t Z() const
Definition: TGLUtil.h:122
Double_t Y() const
Definition: TGLUtil.h:120
Paint TH3 histograms as "voxels" - colored boxes, transparent if transfer function was specified.
void DrawPaletteAxis() const
Draw. Palette. Axis.
void DeInitGL() const
Return back some gl state variables.
void DrawSectionXOY() const
Noop.
void DrawSectionYOZ() const
Noop.
void SetVoxelColor(const Float_t *rgba) const
Set box color.
void InitGL() const
Initialize some gl state variables.
Rgl::Range_t fMinMaxVal
void PreparePalette() const
Generate palette.
TGLVoxelPainter(const TGLVoxelPainter &)
void DrawPalette() const
Draw. Palette.
void AddOption(const TString &stringOption)
"z" draw palette or not.
void DrawSectionXOZ() const
Noop.
void ProcessEvent(Int_t event, Int_t px, Int_t py)
Remove sections, switch on/off box cut.
void Pan(Int_t px, Int_t py)
User's moving mouse cursor, with middle mouse button pressed (for pad).
Bool_t InitGeometry()
Set ranges, find min and max bin content.
TGLLevelPalette fPalette
void DrawPlot() const
Draw "voxels".
void FindVoxelColor(Double_t binContent, Float_t *rgba) const
Find box color.
void StartPan(Int_t px, Int_t py)
User clicks right mouse button (in a pad).
char * GetPlotInfo(Int_t px, Int_t py)
Show box info (i, j, k, binContent).
std::vector< Double_t > fLevels
The TH1 histogram class.
Definition: TH1.h:56
@ kUserContour
user specified contour levels
Definition: TH1.h:161
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:8006
TList * GetListOfFunctions() const
Definition: TH1.h:239
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4907
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition: TH1.cxx:7894
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:8091
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7875
A doubly linked list.
Definition: TList.h:44
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
void ResetBit(UInt_t f)
Definition: TObject.h:186
SCoord_t fY
Definition: TPoint.h:36
SCoord_t fX
Definition: TPoint.h:35
Basic string class.
Definition: TString.h:131
const char * Data() const
Definition: TString.h:364
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Int_t GetNumberContours() const
Definition: TStyle.h:230
const Float_t gNullEmission[]
Definition: TGLUtil.cxx:2848
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2892
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:3008
const Float_t gOrangeEmission[]
Definition: TGLUtil.cxx:2845
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
Short_t Abs(Short_t d)
Definition: TMathBase.h:120