ROOT  6.06/09
Reference Guide
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 "TClass.h"
19 #include "TColor.h"
20 #include "TStyle.h"
21 #include "TH3.h"
22 #include "TVirtualMutex.h"
23 
24 #include "TPolyMarker3D.h"
25 #include "TGLPlotCamera.h"
26 #include "TGLBoxPainter.h"
27 #include "TGLIncludes.h"
28 
29 /** \class TGLBoxPainter
30 \ingroup opengl
31 Paints TH3 histograms by rendering variable-sized boxes matching the
32 bin contents.
33 */
34 
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Normal constructor.
39 
41  : TGLPlotPainter(hist, cam, coord, kTRUE, kTRUE, kTRUE),
42  fXOZSlice("XOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOZ),
43  fYOZSlice("YOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kYOZ),
44  fXOYSlice("XOY", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOY),
45  fType(kBox),
46  fPolymarker(0)
47 {
48 }
49 
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Normal constructor.
53 
55  TGLPlotCamera *cam, TGLPlotCoordinates *coord)
56  : TGLPlotPainter(hist, cam, coord, kFALSE, kFALSE, kFALSE),
57  fXOZSlice("XOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOZ),
58  fYOZSlice("YOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kYOZ),
59  fXOYSlice("XOY", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOY),
60  fType(kBox),
61  fPolymarker(pm)
62 {
63 }
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 ///Show box info (i, j, k, binContent).
67 
69 {
70  fPlotInfo = "";
71 
72  if (fSelectedPart) {
74  if (fHist->Class())
75  fPlotInfo += fHist->Class()->GetName();
76  fPlotInfo += "::";
77  fPlotInfo += fHist->GetName();
78  } else if (!fHighColor){
79  const Int_t arr2Dsize = fCoord->GetNYBins() * fCoord->GetNZBins();
80  const Int_t binI = (fSelectedPart - fSelectionBase) / arr2Dsize + fCoord->GetFirstXBin();
81  const Int_t binJ = (fSelectedPart - fSelectionBase) % arr2Dsize / fCoord->GetNZBins() + fCoord->GetFirstYBin();
82  const Int_t binK = (fSelectedPart - fSelectionBase) % arr2Dsize % fCoord->GetNZBins() + fCoord->GetFirstZBin();
83 
84  fPlotInfo.Form("(binx = %d; biny = %d; binz = %d; binc = %f)", binI, binJ, binK,
85  fHist->GetBinContent(binI, binJ, binK));
86  } else
87  fPlotInfo = "Switch to true color mode to get correct info";
88  }
89 
90  return (Char_t *)fPlotInfo.Data();
91 }
92 
93 ////////////////////////////////////////////////////////////////////////////////
94 ///Set ranges, find min and max bin content.
95 
97 {
101 
102  if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))//kFALSE == drawErrors, kTRUE == zAsBins
103  return kFALSE;
104 
107 
109  fMinMaxVal.first = fMinMaxVal.second;
110  //Bad. You can up-date some bin value and get wrong picture.
111  for (Int_t ir = fCoord->GetFirstXBin(); ir <= fCoord->GetLastXBin(); ++ir) {
112  for (Int_t jr = fCoord->GetFirstYBin(); jr <= fCoord->GetLastYBin(); ++jr) {
113  for (Int_t kr = fCoord->GetFirstZBin(); kr <= fCoord->GetLastZBin(); ++kr) {
114  fMinMaxVal.second = TMath::Max(fMinMaxVal.second, fHist->GetBinContent(ir, jr, kr));
115  fMinMaxVal.first = TMath::Min(fMinMaxVal.first, fHist->GetBinContent(ir, jr, kr));
116  }
117  }
118  }
119 
123 
124  if (fPolymarker) {
125  const Double_t xScale = fCoord->GetXScale();
126  const Double_t yScale = fCoord->GetYScale();
127  const Double_t zScale = fCoord->GetZScale();
128 
129  fPMPoints.assign(fPolymarker->GetP(), fPolymarker->GetP() + fPolymarker->GetN() * 3);
130  for (unsigned i = 0; i < fPMPoints.size(); i += 3) {
131  fPMPoints[i] *= xScale;
132  fPMPoints[i + 1] *= yScale;
133  fPMPoints[i + 2] *= zScale;
134  }
135  }
136 
137  if (fCoord->Modified()) {
143  }
144 
145  return kTRUE;
146 }
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 /// User clicks right mouse button (in a pad).
150 
152 {
153  fMousePosition.fX = px;
155  fCamera->StartPan(px, py);
156  fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
157 }
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 /// User's moving mouse cursor, with middle mouse button pressed (for pad).
161 /// Calculate 3d shift related to 2d mouse movement.
162 
164 {
165  if (fSelectedPart >= fSelectionBase) {//Pan camera.
168 
169  fCamera->SetCamera();
171  fCamera->Pan(px, py);
172 
175  } else if (fSelectedPart > 0) {
176  //Convert py into bottom-top orientation.
177  //Possibly, move box here
178  py = fCamera->GetHeight() - py;
181 
182  fCamera->SetCamera();
184 
185 
186  if (!fHighColor) {
188  fBoxCut.MoveBox(px, py, fSelectedPart);
189  else
190  MoveSection(px, py);
191  } else {
192  MoveSection(px, py);
193  }
194 
197  }
198 
199  fMousePosition.fX = px, fMousePosition.fY = py;
201 }
202 
203 ////////////////////////////////////////////////////////////////////////////////
204 /// Box1 == spheres.
205 
207 {
208  using namespace std;//isdigit must be in std. But ...
209 
210  const Ssiz_t boxPos = option.Index("box");//"box" _already_ _exists_ in a string.
211  if (boxPos + 3 < option.Length() && isdigit(option[boxPos + 3]))
212  option[boxPos + 3] - '0' == 1 ? fType = kBox1 : fType = kBox;
213  else
214  fType = kBox;
215  option.Index("z") == kNPOS ? fDrawPalette = kFALSE : fDrawPalette = kTRUE;
216 }
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// Remove sections.
220 
222 {
223  if (event == kButton1Double && (HasSections() || fBoxCut.IsActive())) {
227  if (fBoxCut.IsActive())
228  fBoxCut.TurnOnOff();
229  if (!gVirtualX->IsCmdThread())
230  gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%lx)->Paint()", (ULong_t)this));
231  else
232  Paint();
233  } else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
234  if (fHighColor)
235  Info("ProcessEvent", "Switch to true color mode to use box cut");
236  else {
237  fBoxCut.TurnOnOff();
239  }
240  }
241 }
242 
243 ////////////////////////////////////////////////////////////////////////////////
244 /// Initialize some gl state variables.
245 
247 {
248  glEnable(GL_DEPTH_TEST);
249  glEnable(GL_LIGHTING);
250  glEnable(GL_LIGHT0);
251  //For box option back polygons are culled (but not for dynamic profiles).
252  glEnable(GL_CULL_FACE);
253  glCullFace(GL_BACK);
254 
255  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
256 }
257 
258 ////////////////////////////////////////////////////////////////////////////////
259 ///Return back some gl state variables.
260 
262 {
263  glDisable(GL_DEPTH_TEST);
264  glDisable(GL_LIGHTING);
265  glDisable(GL_LIGHT0);
266  glDisable(GL_CULL_FACE);
267  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
268 }
269 
270 namespace {
271 
272  /////////////////////////////////////////////////////////////////////////////
273  ///
274 
275  void DrawMinusSigns(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax,
276  Double_t zMin, Double_t zMax, Int_t fp, Bool_t onSphere, Bool_t transp)
277  {
278  const TGLDisableGuard depthTest(GL_DEPTH_TEST);
279  const TGLDisableGuard cullFace(GL_CULL_FACE);
280 
281  const Double_t ratio = onSphere ? 0.4 : 0.15;
282  const Double_t leftX = xMin + ratio * (xMax - xMin), rightX = xMax - ratio * (xMax - xMin);
283  const Double_t leftY = yMin + ratio * (yMax - yMin), rightY = yMax - ratio * (yMax - yMin);
284  const Double_t lowZ = zMin / 2. + zMax / 2. - 0.1 * (zMax - zMin);
285  const Double_t upZ = zMin / 2. + zMax / 2. + 0.1 * (zMax - zMin);
286 
287 
288  const Double_t minusVerts[][3] = {{xMin, leftY, lowZ}, {xMin, leftY, upZ}, {xMin, rightY, upZ}, {xMin, rightY, lowZ},
289  {leftX, yMin, lowZ}, {rightX, yMin, lowZ}, {rightX, yMin, upZ}, {leftX, yMin, upZ},
290  {xMax, leftY, lowZ}, {xMax, rightY, lowZ}, {xMax, rightY, upZ}, {xMax, leftY, upZ},
291  {rightX, yMax, lowZ}, {leftX, yMax, lowZ}, {leftX, yMax, upZ}, {rightX, yMax, upZ}};
292  const Int_t minusQuads[][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15}};
293 
294 
295  TGLDisableGuard light(GL_LIGHTING);
296  glColor3d(1., 0., 0.);
297 
298  const Int_t frontPlanes[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0}};//Code duplication again :(
299  const Int_t *verts = minusQuads[frontPlanes[fp][0]];
300 
301  glBegin(GL_POLYGON);
302  glVertex3dv(minusVerts[verts[0]]);
303  glVertex3dv(minusVerts[verts[1]]);
304  glVertex3dv(minusVerts[verts[2]]);
305  glVertex3dv(minusVerts[verts[3]]);
306  glEnd();
307 
308  verts = minusQuads[frontPlanes[fp][1]];
309 
310  glBegin(GL_POLYGON);
311  glVertex3dv(minusVerts[verts[0]]);
312  glVertex3dv(minusVerts[verts[1]]);
313  glVertex3dv(minusVerts[verts[2]]);
314  glVertex3dv(minusVerts[verts[3]]);
315  glEnd();
316 
317  const Float_t nullEmission[] = {0.f, 0.f, 0.f, 1.f};
318  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, nullEmission);
319  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, nullEmission);
320 
321  glColor4d(0., 0., 0., 0.25);
322  glPolygonMode(GL_FRONT, GL_LINE);
323 
324  if (!transp) {
325  glEnable(GL_BLEND);
326  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
327  }
328 
329  glEnable(GL_LINE_SMOOTH);
330  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
331 
332  verts = minusQuads[frontPlanes[fp][0]];
333 
334  glBegin(GL_POLYGON);
335  glVertex3dv(minusVerts[verts[0]]);
336  glVertex3dv(minusVerts[verts[1]]);
337  glVertex3dv(minusVerts[verts[2]]);
338  glVertex3dv(minusVerts[verts[3]]);
339  glEnd();
340 
341  verts = minusQuads[frontPlanes[fp][1]];
342 
343  glBegin(GL_POLYGON);
344  glVertex3dv(minusVerts[verts[0]]);
345  glVertex3dv(minusVerts[verts[1]]);
346  glVertex3dv(minusVerts[verts[2]]);
347  glVertex3dv(minusVerts[verts[3]]);
348  glEnd();
349 
350  glPolygonMode(GL_FRONT, GL_FILL);
351 
352  if (!transp)
353  glDisable(GL_BLEND);
354  }
355 
356 }
357 
358 ////////////////////////////////////////////////////////////////////////////////
359 
361 {
362  if (fPolymarker)
363  return DrawCloud();
364 
365  // Draw set of boxes (spheres)
366 
367  //Shift plot to point of origin.
368  const Rgl::PlotTranslation trGuard(this);
369 
371  glDisable(GL_CULL_FACE);
372  DrawSections();
373  glEnable(GL_CULL_FACE);
374 
375  if (!fSelectionPass) {
376  glEnable(GL_POLYGON_OFFSET_FILL);//[0
377  glPolygonOffset(1.f, 1.f);
378  SetPlotColor();
379  if (HasSections()) {
380  //Boxes are semi-transparent if we have any sections.
381  glEnable(GL_BLEND);//[1
382  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
383  }
384  }
385 
386  //Using front point, find the correct order to draw boxes from
387  //back to front/from bottom to top (it's important only for semi-transparent boxes).
388  const Int_t frontPoint = fBackBox.GetFrontPoint();
389  Int_t irInit = fCoord->GetFirstXBin(), iInit = 0;
390  const Int_t nX = fCoord->GetNXBins();
391  Int_t jrInit = fCoord->GetFirstYBin(), jInit = 0;
392  const Int_t nY = fCoord->GetNYBins();
393  Int_t krInit = fCoord->GetFirstZBin(), kInit = 0;
394  const Int_t nZ = fCoord->GetNZBins();
395 
396  const Int_t addI = frontPoint == 2 || frontPoint == 1 ? 1 : (iInit = nX - 1, irInit = fCoord->GetLastXBin(), -1);
397  const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? 1 : (jInit = nY - 1, jrInit = fCoord->GetLastYBin(), -1);
398  const Int_t addK = fBackBox.Get2DBox()[frontPoint + 4].Y() < fBackBox.Get2DBox()[frontPoint].Y() ? 1
399  : (kInit = nZ - 1, krInit = fCoord->GetLastZBin(),-1);
400  const Double_t xScale = fCoord->GetXScale();
401  const Double_t yScale = fCoord->GetYScale();
402  const Double_t zScale = fCoord->GetZScale();
403  const TAxis *xA = fXAxis;
404  const TAxis *yA = fYAxis;
405  const TAxis *zA = fZAxis;
406 
407  if (fSelectionPass && fHighColor)
409 
410  Double_t maxContent = TMath::Max(TMath::Abs(fMinMaxVal.first), TMath::Abs(fMinMaxVal.second));
411  if(!maxContent)//bad, find better way to check zero.
412  maxContent = 1.;
413 
414  for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
415  for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
416  for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
417  const Double_t binContent = fHist->GetBinContent(ir, jr, kr);
418  const Double_t w = TMath::Abs(binContent) / maxContent;
419  if (!w)
420  continue;
421 
422  const Double_t xMin = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 - w * xA->GetBinWidth(ir) / 2);
423  const Double_t xMax = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 + w * xA->GetBinWidth(ir) / 2);
424  const Double_t yMin = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 - w * yA->GetBinWidth(jr) / 2);
425  const Double_t yMax = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 + w * yA->GetBinWidth(jr) / 2);
426  const Double_t zMin = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 - w * zA->GetBinWidth(kr) / 2);
427  const Double_t zMax = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 + w * zA->GetBinWidth(kr) / 2);
428 
429  if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
430  continue;
431 
432  const Int_t binID = fSelectionBase + i * fCoord->GetNZBins() * fCoord->GetNYBins() + j * fCoord->GetNZBins() + k;
433 
434  if (fSelectionPass && !fHighColor)
436  else if(!fHighColor && fSelectedPart == binID)
437  glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
438 
439  if (fType == kBox) {
440  Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
441  } else {
442  Rgl::DrawSphere(&fQuadric, xMin, xMax, yMin, yMax, zMin, zMax);
443  }
444 
445  if (binContent < 0. && !fSelectionPass)
446  DrawMinusSigns(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint, fType != kBox, HasSections());
447 
448  if (!fSelectionPass && !fHighColor && fSelectedPart == binID)
449  glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
450  }
451  }
452  }
453 
454  if (fBoxCut.IsActive())
456 
457  if (!fSelectionPass && fType != kBox1) {
458  glDisable(GL_POLYGON_OFFSET_FILL);//0]
459  TGLDisableGuard lightGuard(GL_LIGHTING);//[2 - 2]
460  glColor4d(0., 0., 0., 0.25);
461  glPolygonMode(GL_FRONT, GL_LINE);//[3
462 
463  const TGLEnableGuard blendGuard(GL_BLEND);//[4-4] + 1]
464  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
465  const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);//[5-5]
466  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
467 
468  for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
469  for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
470  for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
471  const Double_t w = TMath::Abs(fHist->GetBinContent(ir, jr, kr)) / maxContent;
472  if (!w)
473  continue;
474 
475  const Double_t xMin = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 - w * xA->GetBinWidth(ir) / 2);
476  const Double_t xMax = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 + w * xA->GetBinWidth(ir) / 2);
477  const Double_t yMin = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 - w * yA->GetBinWidth(jr) / 2);
478  const Double_t yMax = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 + w * yA->GetBinWidth(jr) / 2);
479  const Double_t zMin = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 - w * zA->GetBinWidth(kr) / 2);
480  const Double_t zMax = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 + w * zA->GetBinWidth(kr) / 2);
481 
482  if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
483  continue;
484 
485  Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
486  }
487  }
488  }
489 
490  glPolygonMode(GL_FRONT, GL_FILL);//3]
491  }
492 
494  DrawPalette();
495 }
496 
497 ////////////////////////////////////////////////////////////////////////////////
498 ///Draw a frame and a polymarker inside.
499 
501 {
502  //Shift plot to the point of origin.
503  const Rgl::PlotTranslation trGuard(this);
504 
505  //Frame.
507 
509  glColor3fv(fPhysicalShapeColor);
510 
511  glDisable(GL_LIGHTING);
512 
513  const TGLVertex3 *bb = fBackBox.Get3DBox();
514  const Double_t dX = (bb[1].X() - bb[0].X()) / 40.;
515  const Double_t dY = (bb[3].Y() - bb[0].Y()) / 40.;
516  const Double_t dZ = (bb[4].Z() - bb[0].Z()) / 40.;
517  //Now, draw the cloud of points (polymarker) inside the frame.
519 
520  glEnable(GL_LIGHTING);
521 }
522 
523 ////////////////////////////////////////////////////////////////////////////////
524 /// Set boxes color.
525 
527 {
528  Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.05f};
529 
530  if (fPhysicalShapeColor) {
531  diffColor[0] = fPhysicalShapeColor[0];
532  diffColor[1] = fPhysicalShapeColor[1];
533  diffColor[2] = fPhysicalShapeColor[2];
534  } else {
535  if (fHist->GetFillColor() != kWhite)
536  if (const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
537  c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
538  }
539 
540  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
541  const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
542  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
543  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
544 }
545 
546 ////////////////////////////////////////////////////////////////////////////////
547 /// Draw XOZ parallel section.
548 
550 {
551  if (fSelectionPass)
552  return;
554 }
555 
556 ////////////////////////////////////////////////////////////////////////////////
557 /// Draw YOZ parallel section.
558 
560 {
561  if (fSelectionPass)
562  return;
564 }
565 
566 ////////////////////////////////////////////////////////////////////////////////
567 /// Draw XOY parallel section.
568 
570 {
571  if (fSelectionPass)
572  return;
574 }
575 
576 ////////////////////////////////////////////////////////////////////////////////
577 /// Check, if any section exists.
578 
580 {
581  return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos> fBackBox.Get3DBox()[0].X() ||
583 }
584 
585 ////////////////////////////////////////////////////////////////////////////////
586 ///Draw. Palette.
587 ///Originally, fCamera was never null.
588 ///It can be a null now because of gl-viewer.
589 
591 {
592  if (!fCamera) {
593  //Thank you, gl-viewer!
594  return;
595  }
596 
597  const TGLLevelPalette * palette = 0;
598  const TGLVertex3 *frame = fBackBox.Get3DBox();
599 
600  if (fXOZSectionPos > frame[0].Y())
601  palette = &fXOZSlice.GetPalette();
602  else if (fYOZSectionPos > frame[0].X())
603  palette = &fYOZSlice.GetPalette();
604  else if (fXOYSectionPos > frame[0].Z())
605  palette = &fXOYSlice.GetPalette();
606 
607  if (!palette || !palette->GetPaletteSize()) {
608  return;
609  }
610 
611  Rgl::DrawPalette(fCamera, *palette);
612 
613  glFinish();
614 
615  fCamera->SetCamera();
617 }
618 
619 ////////////////////////////////////////////////////////////////////////////////
620 ///Draw. Palette. Axis.
621 
623 {
624  if (HasSections()) {
625  gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
627  }
628 }
EBoxType fType
Definition: TGLBoxPainter.h:51
Camera for TGLPlotPainter and sub-classes.
Definition: TGLPlotCamera.h:21
Definition: Buttons.h:29
Int_t GetNXBins() const
Number of X bins.
const Rgl::Range_t & GetZRangeScaled() const
Scaled range.
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4629
void MoveBox(Int_t px, Int_t py, Int_t axisID)
Move box cut along selected direction.
const TGLLevelPalette & GetPalette() const
Ssiz_t Length() const
Definition: TString.h:390
const Float_t gNullEmission[]
Definition: TGLUtil.cxx:2814
float Float_t
Definition: RtypesCore.h:53
TGLBoxPainter(const TGLBoxPainter &)
void StartPan(Int_t px, Int_t py)
User clicks right mouse button (in a pad).
Int_t GetLastXBin() const
Double_t fYOZSectionPos
void StartPan(Int_t px, Int_t py)
User clicks somewhere (px, py).
SCoord_t fX
Definition: TPoint.h:37
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:489
#define gROOT
Definition: TROOT.h:340
const Rgl::Range_t & GetYRangeScaled() const
Scaled range.
SCoord_t fY
Definition: TPoint.h:38
Basic string class.
Definition: TString.h:137
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
Int_t GetFirstZBin() const
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
void TurnOnOff()
Turn the box cut on/off.
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:511
TGLTH3Slice fXOZSlice
Definition: TGLBoxPainter.h:42
void DeInitGL() const
Return back some gl state variables.
void DrawPalette(const TGLPlotCamera *camera, const TGLLevelPalette &palette)
Draw. Palette.
void DrawPaletteAxis(const TGLPlotCamera *camera, const Range_t &minMax, Bool_t logZ)
void DrawPalette() const
Draw.
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:1941
STL namespace.
void SetMinMax(const Rgl::Range_t &newRange)
std::vector< Double_t > fPMPoints
Definition: TGLBoxPainter.h:59
A slice of a TH3.
Double_t GetZScale() const
Int_t GetFirstXBin() const
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Paints TH3 histograms by rendering variable-sized boxes matching the bin contents.
Definition: TGLBoxPainter.h:40
void DrawSectionXOY() const
Draw XOY parallel section.
const char * Data() const
Definition: TString.h:349
void SaveProjectionMatrix() const
void ProcessEvent(Int_t event, Int_t px, Int_t py)
Remove sections.
ClassImp(TGLBoxPainter) TGLBoxPainter
Normal constructor.
3 component (x/y/z) vertex class.
Definition: TGLUtil.h:86
void DrawSlice(Double_t pos) const
Draw slice.
Double_t fXOZSectionPos
Bool_t InitGeometry()
Set ranges, find min and max bin content.
void Info(const char *location, const char *msgfmt,...)
void SetYLog(Bool_t yLog)
If log changed, sections must be reset, set fModified.
TGLPlotBox fBackBox
void DrawSectionYOZ() const
Draw YOZ parallel section.
void AddOption(const TString &stringOption)
Box1 == spheres.
virtual Float_t * GetP() const
Definition: TPolyMarker3D.h:67
Double_t GetXScale() const
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
void SetViewVolume(const TGLVertex3 *box)
'box' is the TGLPlotPainter's back box's coordinates.
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:35
Int_t GetNZBins() const
Number of Z bins.
const TPolyMarker3D * fPolymarker
Definition: TGLBoxPainter.h:58
Definition: Rtypes.h:60
Bool_t HasSections() const
Check, if any section exists.
Bool_t GetZLog() const
Get Z log.
void DrawCloud() const
Draw a frame and a polymarker inside.
Double_t fPadTheta
void RestoreProjectionMatrix() const
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2858
TGLPlotCamera * fCamera
void DrawPlot() const
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:2974
Class to manage histogram axis.
Definition: TAxis.h:36
void DrawBox(Bool_t selectionPass, Int_t selected) const
Draw cut as a semi-transparent box.
Int_t GetLastZBin() const
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:499
void DrawSections() const
Draw sections (if any).
virtual Color_t GetFillColor() const
Definition: TAttFill.h:43
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
void ResetModified()
Reset modified.
void DrawPaletteAxis() const
Draw. Palette. Axis.
void Pan(Int_t px, Int_t py)
Pan camera.
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2321
char * Form(const char *fmt,...)
void SaveModelviewMatrix() const
void SetXLog(Bool_t xLog)
If log changed, sections must be reset, set fModified.
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
Base class for plot-painters that provide GL rendering of various 2D and 3D histograms, functions and parametric surfaces.
char * GetPlotInfo(Int_t px, Int_t py)
Show box info (i, j, k, binContent).
std::vector< Double_t > fZLevels
#define gVirtualX
Definition: TVirtualX.h:362
TString fPlotInfo
Definition: TGLBoxPainter.h:53
const TGLVertex3 * Get2DBox() const
Get 2D box.
Definition: TGLPlotBox.cxx:311
Bool_t IsActive() const
PyObject * fType
Rgl::Range_t fMinMaxVal
Definition: TGLBoxPainter.h:54
int Ssiz_t
Definition: RtypesCore.h:63
void RestoreModelviewMatrix() const
void Pan(Int_t px, Int_t py)
User's moving mouse cursor, with middle mouse button pressed (for pad).
double f(double x)
TGLTH3Slice fYOZSlice
Definition: TGLBoxPainter.h:43
double Double_t
Definition: RtypesCore.h:55
void DrawSectionXOZ() const
Draw XOZ parallel section.
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:183
TGLQuadric fQuadric
Definition: TGLBoxPainter.h:56
unsigned long ULong_t
Definition: RtypesCore.h:51
Int_t GetFirstYBin() const
Int_t GetNYBins() const
Number of Y bins.
The TH1 histogram class.
Definition: TH1.h:80
The color creation and management class.
Definition: TColor.h:23
Bool_t SetRanges(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges.
const TGLVertex3 * Get3DBox() const
Get 3D box.
Definition: TGLPlotBox.cxx:302
Double_t X() const
Definition: TGLUtil.h:122
Int_t GetFrontPoint() const
The nearest point.
Definition: TGLPlotBox.cxx:293
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition: TGLUtil.cxx:4221
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:3242
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.
EGLCoordType GetCoordType() const
Get coordinates type.
Double_t Y() const
Definition: TGLUtil.h:124
char Char_t
Definition: RtypesCore.h:29
Double_t fXOYSectionPos
A 3D polymarker.
Definition: TPolyMarker3D.h:40
const Rgl::Range_t & GetXRangeScaled() const
Scaled range.
const Float_t * fPhysicalShapeColor
void SetPlotColor() const
Set boxes color.
const Ssiz_t kNPOS
Definition: Rtypes.h:115
Double_t GetYScale() const
void SetZLog(Bool_t zLog)
If log changed, sections must be reset, set fModified.
void StartMovement(Int_t px, Int_t py)
Start cut's movement.
void MoveSection(Int_t px, Int_t py)
Create dynamic profile using selected plane.
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
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:197
Bool_t Modified() const
Modified.
Int_t GetLastYBin() const
virtual Int_t GetN() const
Definition: TPolyMarker3D.h:66
Double_t Z() const
Definition: TGLUtil.h:126
Bool_t fUpdateSelection
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
std::complex< float_v > Z
Definition: main.cpp:120
TGLTH3Slice fXOYSlice
Definition: TGLBoxPainter.h:44
const Bool_t kTRUE
Definition: Rtypes.h:91
TGLPlotCoordinates * fCoord
virtual void Paint()
Draw lego/surf/whatever you can.
const Float_t gOrangeEmission[]
Definition: TGLUtil.cxx:2811
TGLBoxCut fBoxCut
void SetCamera() const
Viewport and projection.
Int_t GetHeight() const
viewport[3]
void InitGL() const
Initialize some gl state variables.