Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TGLBoxPainter.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Timur Pocheptsov 31/08/2006
3
4/*************************************************************************
5 * Copyright (C) 1995-2006, 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#include <cctype>
12
13#include "KeySymbols.h"
14#include "TVirtualX.h"
15#include "Buttons.h"
16#include "TString.h"
17#include "TROOT.h"
18#include "TMath.h"
19#include "TColor.h"
20#include "TH3.h"
21#include "TVirtualMutex.h"
22
23#include "TPolyMarker3D.h"
24#include "TGLPlotCamera.h"
25#include "TGLBoxPainter.h"
26#include "TGLIncludes.h"
27
28/** \class TGLBoxPainter
29\ingroup opengl
30Paints TH3 histograms by rendering variable-sized boxes matching the
31bin contents.
32*/
33
34
35////////////////////////////////////////////////////////////////////////////////
36/// Normal constructor.
37
39 : TGLPlotPainter(hist, cam, coord, kTRUE, kTRUE, kTRUE),
40 fXOZSlice("XOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOZ),
41 fYOZSlice("YOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kYOZ),
42 fXOYSlice("XOY", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOY),
43 fType(kBox),
44 fPolymarker(nullptr)
45{
46}
47
48
49////////////////////////////////////////////////////////////////////////////////
50/// Normal constructor.
51
54 : TGLPlotPainter(hist, cam, coord, kFALSE, kFALSE, kFALSE),
55 fXOZSlice("XOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOZ),
56 fYOZSlice("YOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kYOZ),
57 fXOYSlice("XOY", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOY),
58 fType(kBox),
59 fPolymarker(pm)
60{
61}
62
63////////////////////////////////////////////////////////////////////////////////
64///Show box info (i, j, k, binContent).
65
67{
68 fPlotInfo = "";
69
70 if (fSelectedPart) {
72 if (fHist->Class())
73 fPlotInfo += fHist->Class()->GetName();
74 fPlotInfo += "::";
75 fPlotInfo += fHist->GetName();
76 } else if (!fHighColor){
77 const Int_t arr2Dsize = fCoord->GetNYBins() * fCoord->GetNZBins();
78 const Int_t binI = (fSelectedPart - fSelectionBase) / arr2Dsize + fCoord->GetFirstXBin();
79 const Int_t binJ = (fSelectedPart - fSelectionBase) % arr2Dsize / fCoord->GetNZBins() + fCoord->GetFirstYBin();
80 const Int_t binK = (fSelectedPart - fSelectionBase) % arr2Dsize % fCoord->GetNZBins() + fCoord->GetFirstZBin();
81
82 fPlotInfo.Form("(binx = %d; biny = %d; binz = %d; binc = %f)", binI, binJ, binK,
83 fHist->GetBinContent(binI, binJ, binK));
84 } else
85 fPlotInfo = "Switch to true color mode to get correct info";
86 }
87
88 return (Char_t *)fPlotInfo.Data();
89}
90
91////////////////////////////////////////////////////////////////////////////////
92///Set ranges, find min and max bin content.
93
95{
96 fCoord->SetZLog(kFALSE);
97 fCoord->SetYLog(kFALSE);
98 fCoord->SetXLog(kFALSE);
99
100 if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))//kFALSE == drawErrors, kTRUE == zAsBins
101 return kFALSE;
102
103 fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
104 if(fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());
105
106 fMinMaxVal.second = fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin(), fCoord->GetFirstZBin());
107 fMinMaxVal.first = fMinMaxVal.second;
108 //Bad. You can up-date some bin value and get wrong picture.
109 for (Int_t ir = fCoord->GetFirstXBin(); ir <= fCoord->GetLastXBin(); ++ir) {
110 for (Int_t jr = fCoord->GetFirstYBin(); jr <= fCoord->GetLastYBin(); ++jr) {
111 for (Int_t kr = fCoord->GetFirstZBin(); kr <= fCoord->GetLastZBin(); ++kr) {
112 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, fHist->GetBinContent(ir, jr, kr));
113 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, fHist->GetBinContent(ir, jr, kr));
114 }
115 }
116 }
117
118 fXOYSlice.SetMinMax(fMinMaxVal);
119 fXOZSlice.SetMinMax(fMinMaxVal);
120 fYOZSlice.SetMinMax(fMinMaxVal);
121
122 if (fPolymarker) {
123 const Double_t xScale = fCoord->GetXScale();
124 const Double_t yScale = fCoord->GetYScale();
125 const Double_t zScale = fCoord->GetZScale();
126
127 fPMPoints.assign(fPolymarker->GetP(), fPolymarker->GetP() + fPolymarker->GetN() * 3);
128 for (unsigned i = 0; i < fPMPoints.size(); i += 3) {
129 fPMPoints[i] *= xScale;
130 fPMPoints[i + 1] *= yScale;
131 fPMPoints[i + 2] *= zScale;
132 }
133 }
134
135 if (fCoord->Modified()) {
137 fXOZSectionPos = fBackBox.Get3DBox()[0].Y();
138 fYOZSectionPos = fBackBox.Get3DBox()[0].X();
139 fXOYSectionPos = fBackBox.Get3DBox()[0].Z();
140 fCoord->ResetModified();
141 }
142
143 return kTRUE;
144}
145
146////////////////////////////////////////////////////////////////////////////////
147/// User clicks right mouse button (in a pad).
148
150{
151 fMousePosition.fX = px;
152 fMousePosition.fY = fCamera->GetHeight() - py;
153 fCamera->StartPan(px, py);
154 fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
155}
156
157////////////////////////////////////////////////////////////////////////////////
158/// User's moving mouse cursor, with middle mouse button pressed (for pad).
159/// Calculate 3d shift related to 2d mouse movement.
160
162{
163 if (fSelectedPart >= fSelectionBase) {//Pan camera.
166
167 fCamera->SetCamera();
168 fCamera->Apply(fPadPhi, fPadTheta);
169 fCamera->Pan(px, py);
170
173 } else if (fSelectedPart > 0) {
174 //Convert py into bottom-top orientation.
175 //Possibly, move box here
176 py = fCamera->GetHeight() - py;
179
180 fCamera->SetCamera();
181 fCamera->Apply(fPadPhi, fPadTheta);
182
183
184 if (!fHighColor) {
185 if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis))
186 fBoxCut.MoveBox(px, py, fSelectedPart);
187 else
188 MoveSection(px, py);
189 } else {
190 MoveSection(px, py);
191 }
192
195 }
196
197 fMousePosition.fX = px, fMousePosition.fY = py;
199}
200
201////////////////////////////////////////////////////////////////////////////////
202/// Box1 == spheres.
203
205{
206 using std::isdigit;
207
208 const Ssiz_t boxPos = option.Index("box");//"box" _already_ _exists_ in a string.
209 if (boxPos + 3 < option.Length() && isdigit(option[boxPos + 3]))
210 option[boxPos + 3] - '0' == 1 ? fType = kBox1 : fType = kBox;
211 else
212 fType = kBox;
213 option.Index("z") == kNPOS ? fDrawPalette = kFALSE : fDrawPalette = kTRUE;
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Remove sections.
218
220{
221 if (event == kButton1Double && (HasSections() || fBoxCut.IsActive())) {
222 fXOZSectionPos = fBackBox.Get3DBox()[0].Y();
223 fYOZSectionPos = fBackBox.Get3DBox()[0].X();
224 fXOYSectionPos = fBackBox.Get3DBox()[0].Z();
225 if (fBoxCut.IsActive())
226 fBoxCut.TurnOnOff();
227 if (!gVirtualX->IsCmdThread())
228 gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%zx)->Paint()", (size_t)this));
229 else
230 Paint();
231 } else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
232 if (fHighColor)
233 Info("ProcessEvent", "Switch to true color mode to use box cut");
234 else {
235 fBoxCut.TurnOnOff();
237 }
238 }
239}
240
241////////////////////////////////////////////////////////////////////////////////
242/// Initialize some gl state variables.
243
245{
246 glEnable(GL_DEPTH_TEST);
247 glEnable(GL_LIGHTING);
248 glEnable(GL_LIGHT0);
249 //For box option back polygons are culled (but not for dynamic profiles).
250 glEnable(GL_CULL_FACE);
251 glCullFace(GL_BACK);
252
253 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
254}
255
256////////////////////////////////////////////////////////////////////////////////
257///Return back some gl state variables.
258
260{
261 glDisable(GL_DEPTH_TEST);
262 glDisable(GL_LIGHTING);
263 glDisable(GL_LIGHT0);
264 glDisable(GL_CULL_FACE);
265 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
266}
267
268namespace {
269
270 /////////////////////////////////////////////////////////////////////////////
271 ///
272
273 void DrawMinusSigns(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
274 Double_t zMin, Double_t zMax, Int_t fp, Bool_t onSphere, Bool_t transp)
275 {
276 const TGLDisableGuard depthTest(GL_DEPTH_TEST);
277 const TGLDisableGuard cullFace(GL_CULL_FACE);
278
279 const Double_t ratio = onSphere ? 0.4 : 0.15;
280 const Double_t leftX = xMin + ratio * (xMax - xMin), rightX = xMax - ratio * (xMax - xMin);
281 const Double_t leftY = yMin + ratio * (yMax - yMin), rightY = yMax - ratio * (yMax - yMin);
282 const Double_t lowZ = zMin / 2. + zMax / 2. - 0.1 * (zMax - zMin);
283 const Double_t upZ = zMin / 2. + zMax / 2. + 0.1 * (zMax - zMin);
284
285
286 const Double_t minusVerts[][3] = {{xMin, leftY, lowZ}, {xMin, leftY, upZ}, {xMin, rightY, upZ}, {xMin, rightY, lowZ},
287 {leftX, yMin, lowZ}, {rightX, yMin, lowZ}, {rightX, yMin, upZ}, {leftX, yMin, upZ},
288 {xMax, leftY, lowZ}, {xMax, rightY, lowZ}, {xMax, rightY, upZ}, {xMax, leftY, upZ},
289 {rightX, yMax, lowZ}, {leftX, yMax, lowZ}, {leftX, yMax, upZ}, {rightX, yMax, upZ}};
290 const Int_t minusQuads[][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15}};
291
292
293 TGLDisableGuard light(GL_LIGHTING);
294 glColor3d(1., 0., 0.);
295
296 const Int_t frontPlanes[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0}};//Code duplication again :(
297 const Int_t *verts = minusQuads[frontPlanes[fp][0]];
298
299 glBegin(GL_POLYGON);
300 glVertex3dv(minusVerts[verts[0]]);
301 glVertex3dv(minusVerts[verts[1]]);
302 glVertex3dv(minusVerts[verts[2]]);
303 glVertex3dv(minusVerts[verts[3]]);
304 glEnd();
305
306 verts = minusQuads[frontPlanes[fp][1]];
307
308 glBegin(GL_POLYGON);
309 glVertex3dv(minusVerts[verts[0]]);
310 glVertex3dv(minusVerts[verts[1]]);
311 glVertex3dv(minusVerts[verts[2]]);
312 glVertex3dv(minusVerts[verts[3]]);
313 glEnd();
314
315 const Float_t nullEmission[] = {0.f, 0.f, 0.f, 1.f};
316 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, nullEmission);
317 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, nullEmission);
318
319 glColor4d(0., 0., 0., 0.25);
320 glPolygonMode(GL_FRONT, GL_LINE);
321
322 if (!transp) {
323 glEnable(GL_BLEND);
324 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
325 }
326
327 glEnable(GL_LINE_SMOOTH);
328 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
329
330 verts = minusQuads[frontPlanes[fp][0]];
331
332 glBegin(GL_POLYGON);
333 glVertex3dv(minusVerts[verts[0]]);
334 glVertex3dv(minusVerts[verts[1]]);
335 glVertex3dv(minusVerts[verts[2]]);
336 glVertex3dv(minusVerts[verts[3]]);
337 glEnd();
338
339 verts = minusQuads[frontPlanes[fp][1]];
340
341 glBegin(GL_POLYGON);
342 glVertex3dv(minusVerts[verts[0]]);
343 glVertex3dv(minusVerts[verts[1]]);
344 glVertex3dv(minusVerts[verts[2]]);
345 glVertex3dv(minusVerts[verts[3]]);
346 glEnd();
347
348 glPolygonMode(GL_FRONT, GL_FILL);
349
350 if (!transp)
351 glDisable(GL_BLEND);
352 }
353
354}
355
356////////////////////////////////////////////////////////////////////////////////
357
359{
360 if (fPolymarker)
361 return DrawCloud();
362
363 // Draw set of boxes (spheres)
364
365 //Shift plot to point of origin.
366 const Rgl::PlotTranslation trGuard(this);
367
369 glDisable(GL_CULL_FACE);
370 DrawSections();
371 glEnable(GL_CULL_FACE);
372
373 if (!fSelectionPass) {
374 glEnable(GL_POLYGON_OFFSET_FILL);//[0
375 glPolygonOffset(1.f, 1.f);
376 SetPlotColor();
377 if (HasSections()) {
378 //Boxes are semi-transparent if we have any sections.
379 glEnable(GL_BLEND);//[1
380 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
381 }
382 }
383
384 //Using front point, find the correct order to draw boxes from
385 //back to front/from bottom to top (it's important only for semi-transparent boxes).
386 const Int_t frontPoint = fBackBox.GetFrontPoint();
387 Int_t irInit = fCoord->GetFirstXBin(), iInit = 0;
388 const Int_t nX = fCoord->GetNXBins();
389 Int_t jrInit = fCoord->GetFirstYBin(), jInit = 0;
390 const Int_t nY = fCoord->GetNYBins();
391 Int_t krInit = fCoord->GetFirstZBin(), kInit = 0;
392 const Int_t nZ = fCoord->GetNZBins();
393
394 const Int_t addI = frontPoint == 2 || frontPoint == 1 ? 1 : (iInit = nX - 1, irInit = fCoord->GetLastXBin(), -1);
395 const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? 1 : (jInit = nY - 1, jrInit = fCoord->GetLastYBin(), -1);
396 const Int_t addK = fBackBox.Get2DBox()[frontPoint + 4].Y() < fBackBox.Get2DBox()[frontPoint].Y() ? 1
397 : (kInit = nZ - 1, krInit = fCoord->GetLastZBin(),-1);
398 const Double_t xScale = fCoord->GetXScale();
399 const Double_t yScale = fCoord->GetYScale();
400 const Double_t zScale = fCoord->GetZScale();
401 const TAxis *xA = fXAxis;
402 const TAxis *yA = fYAxis;
403 const TAxis *zA = fZAxis;
404
407
408 Double_t maxContent = TMath::Max(TMath::Abs(fMinMaxVal.first), TMath::Abs(fMinMaxVal.second));
409 if(!maxContent)//bad, find better way to check zero.
410 maxContent = 1.;
411
412 Double_t wmin = TMath::Max(fHist->GetMinimum(),0.);
413 Double_t wmax = TMath::Max(TMath::Abs(fHist->GetMaximum()),
414 TMath::Abs(fHist->GetMinimum()));
415 Double_t binContent;
416
417 for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
418 for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
419 for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
420 binContent = fHist->GetBinContent(ir, jr, kr);
421 if (binContent < wmin) continue;
422 if (binContent > wmax) binContent = wmax;
423
424 const Double_t w = TMath::Power(TMath::Abs(binContent-wmin) / (wmax-wmin),1./3.);
425 if (!w)
426 continue;
427
428 const Double_t xMin = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 - w * xA->GetBinWidth(ir) / 2);
429 const Double_t xMax = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 + w * xA->GetBinWidth(ir) / 2);
430 const Double_t yMin = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 - w * yA->GetBinWidth(jr) / 2);
431 const Double_t yMax = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 + w * yA->GetBinWidth(jr) / 2);
432 const Double_t zMin = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 - w * zA->GetBinWidth(kr) / 2);
433 const Double_t zMax = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 + w * zA->GetBinWidth(kr) / 2);
434
435 if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
436 continue;
437
438 const Int_t binID = fSelectionBase + i * fCoord->GetNZBins() * fCoord->GetNYBins() + j * fCoord->GetNZBins() + k;
439
442 else if(!fHighColor && fSelectedPart == binID)
443 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
444
445 if (fType == kBox) {
446 Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
447 } else {
448 Rgl::DrawSphere(&fQuadric, xMin, xMax, yMin, yMax, zMin, zMax);
449 }
450
451 if (binContent < 0. && !fSelectionPass)
452 DrawMinusSigns(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint, fType != kBox, HasSections());
453
454 if (!fSelectionPass && !fHighColor && fSelectedPart == binID)
455 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
456 }
457 }
458 }
459
460 if (fBoxCut.IsActive())
462
463 if (!fSelectionPass && fType != kBox1) {
464 glDisable(GL_POLYGON_OFFSET_FILL);//0]
465 TGLDisableGuard lightGuard(GL_LIGHTING);//[2 - 2]
466 glColor4d(0., 0., 0., 0.25);
467 glPolygonMode(GL_FRONT, GL_LINE);//[3
468
469 const TGLEnableGuard blendGuard(GL_BLEND);//[4-4] + 1]
470 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
471 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);//[5-5]
472 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
473
474 for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
475 for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
476 for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
477 binContent = fHist->GetBinContent(ir, jr, kr);
478 if (binContent < wmin) continue;
479 if (binContent > wmax) binContent = wmax;
480 const Double_t w = TMath::Power(TMath::Abs(binContent-wmin) / (wmax-wmin),1./3.);
481 if (!w)
482 continue;
483
484 const Double_t xMin = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 - w * xA->GetBinWidth(ir) / 2);
485 const Double_t xMax = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 + w * xA->GetBinWidth(ir) / 2);
486 const Double_t yMin = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 - w * yA->GetBinWidth(jr) / 2);
487 const Double_t yMax = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 + w * yA->GetBinWidth(jr) / 2);
488 const Double_t zMin = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 - w * zA->GetBinWidth(kr) / 2);
489 const Double_t zMax = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 + w * zA->GetBinWidth(kr) / 2);
490
491 if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
492 continue;
493
494 Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
495 }
496 }
497 }
498
499 glPolygonMode(GL_FRONT, GL_FILL);//3]
500 }
501
503 DrawPalette();
504}
505
506////////////////////////////////////////////////////////////////////////////////
507///Draw a frame and a polymarker inside.
508
510{
511 //Shift plot to the point of origin.
512 const Rgl::PlotTranslation trGuard(this);
513
514 //Frame.
516
518 glColor3fv(fPhysicalShapeColor);
519
520 glDisable(GL_LIGHTING);
521
522 const TGLVertex3 *bb = fBackBox.Get3DBox();
523 const Double_t dX = (bb[1].X() - bb[0].X()) / 40.;
524 const Double_t dY = (bb[3].Y() - bb[0].Y()) / 40.;
525 const Double_t dZ = (bb[4].Z() - bb[0].Z()) / 40.;
526 //Now, draw the cloud of points (polymarker) inside the frame.
528
529 glEnable(GL_LIGHTING);
530}
531
532////////////////////////////////////////////////////////////////////////////////
533/// Set boxes color.
534
536{
537 Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.05f};
538
540 diffColor[0] = fPhysicalShapeColor[0];
541 diffColor[1] = fPhysicalShapeColor[1];
542 diffColor[2] = fPhysicalShapeColor[2];
543 } else {
544 if (fHist->GetFillColor() != kWhite)
545 if (const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
546 c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
547 }
548
549 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
550 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
551 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
552 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
553}
554
555////////////////////////////////////////////////////////////////////////////////
556/// Draw XOZ parallel section.
557
559{
560 if (fSelectionPass)
561 return;
562 fXOZSlice.DrawSlice(fXOZSectionPos / fCoord->GetYScale());
563}
564
565////////////////////////////////////////////////////////////////////////////////
566/// Draw YOZ parallel section.
567
569{
570 if (fSelectionPass)
571 return;
572 fYOZSlice.DrawSlice(fYOZSectionPos / fCoord->GetXScale());
573}
574
575////////////////////////////////////////////////////////////////////////////////
576/// Draw XOY parallel section.
577
579{
580 if (fSelectionPass)
581 return;
582 fXOYSlice.DrawSlice(fXOYSectionPos / fCoord->GetZScale());
583}
584
585////////////////////////////////////////////////////////////////////////////////
586/// Check, if any section exists.
587
589{
590 return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos> fBackBox.Get3DBox()[0].X() ||
591 fXOYSectionPos > fBackBox.Get3DBox()[0].Z();
592}
593
594////////////////////////////////////////////////////////////////////////////////
595///Draw. Palette.
596///Originally, fCamera was never null.
597///It can be a null now because of gl-viewer.
598
600{
601 if (!fCamera) {
602 //Thank you, gl-viewer!
603 return;
604 }
605
606 const TGLLevelPalette * palette = nullptr;
607 const TGLVertex3 *frame = fBackBox.Get3DBox();
608
609 if (fXOZSectionPos > frame[0].Y())
610 palette = &fXOZSlice.GetPalette();
611 else if (fYOZSectionPos > frame[0].X())
612 palette = &fYOZSlice.GetPalette();
613 else if (fXOYSectionPos > frame[0].Z())
614 palette = &fXOYSlice.GetPalette();
615
616 if (!palette || !palette->GetPaletteSize()) {
617 return;
618 }
619
620 Rgl::DrawPalette(fCamera, *palette);
621
622 glFinish();
623
624 fCamera->SetCamera();
625 fCamera->Apply(fPadPhi, fPadTheta);
626}
627
628////////////////////////////////////////////////////////////////////////////////
629///Draw. Palette. Axis.
630
632{
633 if (HasSections()) {
634 gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
635 Rgl::DrawPaletteAxis(fCamera, fMinMaxVal, fCoord->GetCoordType() == kGLCartesian ? fCoord->GetZLog() : kFALSE);
636 }
637}
@ kKeyPress
Definition Buttons.h:20
@ kButton1Double
Definition Buttons.h:24
@ kKey_C
Definition KeySymbols.h:128
@ kKey_c
Definition KeySymbols.h:160
#define c(i)
Definition RSha256.hxx:101
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
int Ssiz_t
String size (currently int).
Definition RtypesCore.h:81
char Char_t
Character 1 byte (char).
Definition RtypesCore.h:51
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
float Float_t
Float 4 bytes (float).
Definition RtypesCore.h:71
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
@ kWhite
Definition Rtypes.h:66
#define X(type, name)
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
@ kGLCartesian
Definition TGLUtil.h:44
#define gROOT
Definition TROOT.h:417
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2496
#define gVirtualX
Definition TVirtualX.h:375
Class to manage histogram axis.
Definition TAxis.h:32
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:522
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:546
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:532
const TPolyMarker3D * fPolymarker
void DrawPlot() const override
TGLTH3Slice fYOZSlice
Bool_t HasSections() const
Check, if any section exists.
void DrawSectionYOZ() const override
Draw YOZ parallel section.
Bool_t InitGeometry() override
Set ranges, find min and max bin content.
void Pan(Int_t px, Int_t py) override
User's moving mouse cursor, with middle mouse button pressed (for pad).
TGLTH3Slice fXOZSlice
void DeInitGL() const override
Return back some gl state variables.
void AddOption(const TString &stringOption) override
Box1 == spheres.
void DrawSectionXOZ() const override
Draw XOZ parallel section.
void InitGL() const override
Initialize some gl state variables.
TGLQuadric fQuadric
void StartPan(Int_t px, Int_t py) override
User clicks right mouse button (in a pad).
std::vector< Double_t > fPMPoints
TString fPlotInfo
Rgl::Range_t fMinMaxVal
void DrawPaletteAxis() const override
Draw. Palette. Axis.
void SetPlotColor() const
Set boxes color.
TGLBoxPainter(const TGLBoxPainter &)
void DrawCloud() const
Draw a frame and a polymarker inside.
void DrawSectionXOY() const override
Draw XOY parallel section.
void ProcessEvent(Int_t event, Int_t px, Int_t py) override
Remove sections.
TGLTH3Slice fXOYSlice
void DrawPalette() const
Draw.
char * GetPlotInfo(Int_t px, Int_t py) override
Show box info (i, j, k, binContent).
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition TGLUtil.cxx:4253
Camera for TGLPlotPainter and sub-classes.
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
void DrawSections() const
Draw sections (if any).
const Float_t * fPhysicalShapeColor
TGLPlotPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord, Bool_t xoySelectable, Bool_t xozSelectable, Bool_t yozSelectable)
TGLPlotPainter's ctor.
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
A slice of a TH3.
static void RenderPolyMarkers(const TAttMarker &marker, Char_t transp, Float_t *p, Int_t n, Int_t pick_radius=0, Bool_t selection=kFALSE, Bool_t sec_selection=kFALSE)
Render polymarkers at points specified by p-array.
Definition TGLUtil.cxx:1971
3 component (x/y/z) vertex class.
Definition TGLUtil.h:84
Double_t X() const
Definition TGLUtil.h:119
Double_t Z() const
Definition TGLUtil.h:123
Double_t Y() const
Definition TGLUtil.h:121
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
The 3-D histogram classes derived from the 1-D histogram classes.
Definition TH3.h:45
A 3D polymarker.
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:660
const Float_t gNullEmission[]
Definition TGLUtil.cxx:2846
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition TGLUtil.cxx:2890
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:3006
void DrawSphere(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax)
Cylinder for lego3.
Definition TGLUtil.cxx:3274
const Float_t gOrangeEmission[]
Definition TGLUtil.cxx:2843
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:732
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122