Logo ROOT   6.16/01
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 for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
276 for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
277// for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
278 for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
279 const Double_t xMin = xScale * xA->GetBinLowEdge(ir);
280 const Double_t xMax = xScale * xA->GetBinUpEdge(ir);
281 const Double_t yMin = yScale * yA->GetBinLowEdge(jr);
282 const Double_t yMax = yScale * yA->GetBinUpEdge(jr);
283 const Double_t zMin = zScale * zA->GetBinLowEdge(kr);
284 const Double_t zMax = zScale * zA->GetBinUpEdge(kr);
285
286 if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
287 continue;
288
289 FindVoxelColor(fHist->GetBinContent(ir, jr, kr), rgba);
290
291 if (rgba[3] < 0.01f)
292 continue;
293
294 if (!fSelectionPass)
295 SetVoxelColor(rgba);
296
297 const Int_t binID = fSelectionBase + i * fCoord->GetNZBins() * fCoord->GetNYBins() + j * fCoord->GetNZBins() + k;
298
301 else if(!fHighColor && fSelectedPart == binID)
302 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
303
304 Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
305
306 if (!fSelectionPass && !fHighColor && fSelectedPart == binID)
307 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
308 }
309 }
310 }
311
312 if (fBoxCut.IsActive())
314
315 if (!fSelectionPass) {
316 if (fDrawPalette)
317 DrawPalette();
318 glDisable(GL_BLEND);//1]
319 }
320}
321
322////////////////////////////////////////////////////////////////////////////////
323/// Noop.
324
326{
327}
328
329////////////////////////////////////////////////////////////////////////////////
330/// Noop.
331
333{
334}
335
336
337////////////////////////////////////////////////////////////////////////////////
338/// Noop.
339
341{
342}
343
344////////////////////////////////////////////////////////////////////////////////
345///Draw. Palette.
346
348{
350 return;
351
354 else
356
357 glFinish();
358
361}
362
363////////////////////////////////////////////////////////////////////////////////
364///Draw. Palette. Axis.
365
367{
368 if (fCamera) {
369 gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
371 }
372}
373
374////////////////////////////////////////////////////////////////////////////////
375///Generate palette.
376
378{
379 if(fMinMaxVal.first == fMinMaxVal.second)
380 return;//must be std::abs(fMinMaxVal.second - fMinMaxVal.first) < ...
381
382 fLevels.clear();
383 UInt_t paletteSize = 0;
384
386 if (const UInt_t trySize = fHist->GetContour()) {
387 fLevels.reserve(trySize);
388
389 for (UInt_t i = 0; i < trySize; ++i) {
390 const Double_t level = fHist->GetContourLevel(Int_t(i));
391 if (level <= fMinMaxVal.first || level >= fMinMaxVal.second)
392 continue;
393 fLevels.push_back(level);
394 }
395 //sort levels
396 if (fLevels.size()) {
397 std::sort(fLevels.begin(), fLevels.end());
398 fLevels.push_back(fMinMaxVal.second);
399 fLevels.insert(fLevels.begin(), fMinMaxVal.first);
401 paletteSize = fLevels.size() - 1;
402 }
403 }
404
405 if (!paletteSize)
407 }
408
409 if (!paletteSize && !(paletteSize = gStyle->GetNumberContours()))
410 paletteSize = 20;
411
412 fPalette.GeneratePalette(paletteSize, fMinMaxVal);
413}
414
415////////////////////////////////////////////////////////////////////////////////
416/// Find box color.
417
419{
420 const UChar_t * tc = fPalette.GetColour(binContent);
421 rgba[3] = 0.06f; //Just a constant transparency.
422
423
424 if (fTransferFunc) {
425 rgba[3] = fTransferFunc->Eval(binContent);
426 }
427
428 rgba[0] = tc[0] / 255.f;
429 rgba[1] = tc[1] / 255.f;
430 rgba[2] = tc[2] / 255.f;
431}
432
433
434////////////////////////////////////////////////////////////////////////////////
435/// Set box color.
436
437void TGLVoxelPainter::SetVoxelColor(const Float_t *diffColor)const
438{
439 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
440 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
441 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
442 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
443}
@ kKeyPress
Definition: Buttons.h:20
@ kButton1Double
Definition: Buttons.h:24
@ kKey_C
Definition: KeySymbols.h:128
@ kKey_c
Definition: KeySymbols.h:160
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
unsigned char UChar_t
Definition: RtypesCore.h:34
char Char_t
Definition: RtypesCore.h:29
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
void Info(const char *location, const char *msgfmt,...)
#define gROOT
Definition: TROOT.h:410
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:406
#define gVirtualX
Definition: TVirtualX.h:345
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:504
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:514
1-Dim function class
Definition: TF1.h:211
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:1424
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:4308
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition: TGLUtil.cxx:4271
void SetContours(const std::vector< Double_t > *contours)
Clear :)
Definition: TGLUtil.cxx:4235
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition: TGLUtil.cxx:4178
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
TList * GetListOfFunctions() const
Definition: TH1.h:239
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4790
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition: TH1.cxx:7760
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7741
A doubly linked list.
Definition: TList.h:44
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
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:172
void ResetBit(UInt_t f)
Definition: TObject.h:171
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:2264
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:228
const Float_t gNullEmission[]
Definition: TGLUtil.cxx:2864
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2908
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:3024
const Float_t gOrangeEmission[]
Definition: TGLUtil.cxx:2861
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