Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLLegoPainter.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Timur Pocheptsov 14/06/2006
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, 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 <algorithm>
12#include <cctype>
13
14#include "KeySymbols.h"
15#include "TVirtualX.h"
16#include "Buttons.h"
17#include "TString.h"
18#include "TColor.h"
19#include "TROOT.h"
20#include "TStyle.h"
21#include "TAxis.h"
22#include "TMath.h"
23#include "TH1.h"
24
25#include "TGLLegoPainter.h"
26#include "TGLPlotCamera.h"
27#include "TGLIncludes.h"
28
29/** \class TGLLegoPainter
30\ingroup opengl
31Plot-painter implementing LEGO rendering of TH2 histograms in
32cartesian, polar, cylindrical and spherical coordinates.
33*/
34
35
36////////////////////////////////////////////////////////////////////////////////
37///Ctor.
38
41 fLegoType(kColorSimple),
42 fMinZ(0.),
43 fDrawErrors(kFALSE)
44{
45}
46
47////////////////////////////////////////////////////////////////////////////////
48///Obtain bin's info (i, j, value).
49
51{
52 fBinInfo = "";
53
54 if (fSelectedPart) {
56 if (fHist->Class())
57 fBinInfo += fHist->Class()->GetName();
58 fBinInfo += "::";
60 } else if (!fHighColor) {
63 fBinInfo.Form("(binx = %d; biny = %d; binc = %f)", binI, binJ,
65 } else
66 fBinInfo = "Switch to true-color mode to obtain correct info";
67 }
68
69 return (Char_t *)fBinInfo.Data();
70}
71
72////////////////////////////////////////////////////////////////////////////////
73///Select method.
74
76{
78 switch (fCoord->GetCoordType()) {
79 case kGLCartesian:
80 ret = InitGeometryCartesian(); break;
81 case kGLPolar:
82 ret = InitGeometryPolar(); break;
83 case kGLCylindrical:
85 case kGLSpherical:
86 ret = InitGeometrySpherical(); break;
87 default:
88 return kFALSE;
89 }
91 return ret;
92}
93
94////////////////////////////////////////////////////////////////////////////////
95///Geometry for lego in cartesian coords.
96
98{
100 return kFALSE;
101
103
104 //Find bin edges
105 const Int_t nX = fCoord->GetNXBins();
107 const TGLVertex3 *frame = fBackBox.Get3DBox();
108 fXEdges.resize(nX);
109
110 if (fCoord->GetXLog()) {
111 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
114 fXEdges[i].first = TMath::Log10(low) * fCoord->GetXScale();
115 fXEdges[i].second = TMath::Log10(low + xWidth * barWidth) * fCoord->GetXScale();
116 if (fXEdges[i].second > frame[1].X())
117 fXEdges[i].second = frame[1].X();
118 if (fXEdges[i].first < frame[0].X())
119 fXEdges[i].first = frame[0].X();
120 if (fXEdges[i].second < frame[0].X())
121 fXEdges[i].second = frame[0].X();
122 }
123 } else {
124 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
127 fXEdges[i].second = fXEdges[i].first + xWidth * barWidth * fCoord->GetXScale();
128 if (fXEdges[i].second > frame[1].X())
129 fXEdges[i].second = frame[1].X();
130 if (fXEdges[i].first < frame[0].X())
131 fXEdges[i].first = frame[0].X();
132 if (fXEdges[i].second < frame[0].X())
133 fXEdges[i].second = frame[0].X();
134 }
135 }
136
137 const Int_t nY = fCoord->GetNYBins();
138 fYEdges.resize(nY);
139
140 if (fCoord->GetYLog()) {
141 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
144 fYEdges[j].first = TMath::Log10(low) * fCoord->GetYScale();
145 fYEdges[j].second = TMath::Log10(low + yWidth * barWidth) * fCoord->GetYScale();
146 if (fYEdges[j].second > frame[2].Y())
147 fYEdges[j].second = frame[2].Y();
148 if (fYEdges[j].first < frame[0].Y())
149 fYEdges[j].first = frame[0].Y();
150 if (fYEdges[j].second < frame[0].Y())
151 fYEdges[j].second = frame[0].Y();
152 }
153 } else {
154 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
157 fYEdges[j].second = fYEdges[j].first + yWidth * barWidth * fCoord->GetYScale();
158 if (fYEdges[j].second > frame[2].Y())
159 fYEdges[j].second = frame[2].Y();
160 if (fYEdges[j].first < frame[0].Y())
161 fYEdges[j].first = frame[0].Y();
162 if (fYEdges[j].second < frame[0].Y())
163 fYEdges[j].second = frame[0].Y();
164 }
165 }
166
167 fMinZ = frame[0].Z();
168 if (fMinZ < 0.)
169 frame[4].Z() > 0. ? fMinZ = 0. : fMinZ = frame[4].Z();
170
171 if (fCoord->Modified()) {
173 fXOZSectionPos = frame[0].Y();
174 fYOZSectionPos = frame[0].X();
175 fXOYSectionPos = frame[0].Z();
178 }
179
181 fMinMaxVal.second = fMinMaxVal.first;
182
183 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
184 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
185 Double_t val = fHist->GetBinContent(i, j);
186 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
187 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
188 }
189 }
190
191 ClampZ(fMinMaxVal.first);
192 ClampZ(fMinMaxVal.second);
193
194 return kTRUE;
195}
196
197////////////////////////////////////////////////////////////////////////////////
198///Geometry for lego in polar coords.
199
201{
203 return kFALSE;
204
206
207 if (fCoord->Modified()) {
210 }
211
212 const Int_t nY = fCoord->GetNYBins();//yBins.second - yBins.first + 1;
213 fYEdges.resize(nY);
214
215 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
216 fYEdges[j].first = ((fYAxis->GetBinLowEdge(jr)) - fCoord->GetYRange().first) /
218 fYEdges[j].second = ((fYAxis->GetBinUpEdge(jr)) - fCoord->GetYRange().first) /
220 }
221
222 const Int_t nX = fCoord->GetNXBins();
223 fCosSinTableX.resize(nX + 1);
225 const Double_t phiLow = fXAxis->GetXmin();
226 Double_t angle = 0;
227 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
229 fCosSinTableX[i].first = TMath::Cos(angle);
230 fCosSinTableX[i].second = TMath::Sin(angle);
231 }
234 fCosSinTableX[nX].second = TMath::Sin(angle);
235
236 fMinZ = fBackBox.Get3DBox()[0].Z();
237 if (fMinZ < 0.)
238 fBackBox.Get3DBox()[4].Z() > 0. ? fMinZ = 0. : fMinZ = fBackBox.Get3DBox()[4].Z();
239
241 fMinMaxVal.second = fMinMaxVal.first;
242
243 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
244 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
245 Double_t val = fHist->GetBinContent(i, j);
246 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
247 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
248 }
249 }
250
251 ClampZ(fMinMaxVal.first);
252 ClampZ(fMinMaxVal.second);
253
254 return kTRUE;
255}
256
257////////////////////////////////////////////////////////////////////////////////
258///Geometry for lego in cylindrical coords.
259
261{
263 return kFALSE;
264
266
267 const Int_t nY = fCoord->GetNYBins();
268 fYEdges.resize(nY);
269
270 if (fCoord->GetYLog()) {
271 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
274 }
275 } else {
276 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
278 fYEdges[j].second = fYAxis->GetBinUpEdge(jr) * fCoord->GetYScale();
279 }
280 }
281
282 const Int_t nX = fCoord->GetNXBins();
283 fCosSinTableX.resize(nX + 1);
285 const Double_t phiLow = fXAxis->GetXmin();
286 Double_t angle = 0.;
287 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
289 fCosSinTableX[i].first = TMath::Cos(angle);
290 fCosSinTableX[i].second = TMath::Sin(angle);
291 }
294 fCosSinTableX[nX].second = TMath::Sin(angle);
295
296 if (fCoord->Modified()) {
299 }
300
301 fMinZ = fCoord->GetZRange().first;
302 if (fMinZ < 0.)
303 fCoord->GetZRange().second > 0. ? fMinZ = 0. : fMinZ = fCoord->GetZRange().second;
304
305
307 fMinMaxVal.second = fMinMaxVal.first;
308
309 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
310 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
311 Double_t val = fHist->GetBinContent(i, j);
312 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
313 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
314 }
315 }
316
317 return kTRUE;
318}
319
320////////////////////////////////////////////////////////////////////////////////
321///Geometry for lego in spherical coords.
322
324{
326 return kFALSE;
327
329
330 const Int_t nY = fCoord->GetNYBins();
331 fCosSinTableY.resize(nY + 1);
333 const Double_t thetaLow = fYAxis->GetXmin();
334 Double_t angle = 0.;
335 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
338 fCosSinTableY[j].second = TMath::Sin(angle);
339 }
342 fCosSinTableY[nY].second = TMath::Sin(angle);
343
344 const Int_t nX = fCoord->GetNXBins();
345 fCosSinTableX.resize(nX + 1);
347 const Double_t phiLow = fXAxis->GetXmin();
348
349 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
351 fCosSinTableX[i].first = TMath::Cos(angle);
352 fCosSinTableX[i].second = TMath::Sin(angle);
353 }
354
357 fCosSinTableX[nX].second = TMath::Sin(angle);
358
359 fMinZ = fCoord->GetZRange().first;
360 if (fMinZ < 0.)
361 fCoord->GetZRange().second > 0. ? fMinZ = 0. : fMinZ = fCoord->GetZRange().second;
362
364 fMinMaxVal.second = fMinMaxVal.first;
365
366 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
367 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
368 Double_t val = fHist->GetBinContent(i, j);
369 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
370 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
371 }
372 }
373
374
375 return kTRUE;
376}
377
378////////////////////////////////////////////////////////////////////////////////
379///User clicks on a lego with middle mouse button (middle for pad).
380
382{
383 fMousePosition.fX = px;
385 fCamera->StartPan(px, py);
386 fBoxCut.StartMovement(px, py);
387}
388
389////////////////////////////////////////////////////////////////////////////////
390///Move lego or section.
391
393{
397
400 fCamera->Pan(px, py);
401
404 } else if (fSelectedPart > 0) {
405 //Convert py into bottom-top orientation.
406 py = fCamera->GetHeight() - py;
407
410
413
414 if (!fHighColor) {
417 else
418 MoveSection(px, py);
419 } else
420 MoveSection(px, py);
421
424 }
425
428}
429
430////////////////////////////////////////////////////////////////////////////////
431///Parse additional options.
432
434{
435 const Ssiz_t legoPos = option.Index("lego");//"lego" _already_ _exists_ in a string.
436 if (legoPos + 4 < option.Length() && isdigit(option[legoPos + 4])) {
437 switch (option[legoPos + 4] - '0') {
438 case 1:
440 break;
441 case 2:
443 break;
444 case 3:
446 break;
447 default:
449 break;
450 }
451 } else
453 //check 'e' option
454 Ssiz_t ePos = option.Index("e");
455 if (ePos == legoPos + 1)
456 ePos = option.Index("e", legoPos + 4);
458
459 option.Index("z") == kNPOS ? fDrawPalette = kFALSE : fDrawPalette = kTRUE;
460}
461
462////////////////////////////////////////////////////////////////////////////////
463///Initialize some gl state variables.
464
466{
470 //For lego, back polygons are culled (but not for sections).
473
475}
476
477////////////////////////////////////////////////////////////////////////////////
478///Return some gl states to original values.
479
488
489////////////////////////////////////////////////////////////////////////////////
490///Select method corresponding to coordinate system.
491
493{
494 //Shift plot to point of origin.
495 const Rgl::PlotTranslation trGuard(this);
496
497 switch (fCoord->GetCoordType()) {
498 case kGLCartesian:
499 return DrawLegoCartesian();
500 case kGLPolar:
501 return DrawLegoPolar();
502 case kGLCylindrical:
503 return DrawLegoCylindrical();
504 case kGLSpherical:
505 return DrawLegoSpherical();
506 default:;
507 }
508}
509
510////////////////////////////////////////////////////////////////////////////////
511///Lego in cartesian system.
512
514{
515 if (fCoord->GetCoordType() == kGLCartesian) {
518 DrawSections();
519 }
520
521 //const TGLDisableGuard depthTest(GL_DEPTH_TEST); //[0-0]
522
523 if (!fSelectionPass) {
525 glPolygonOffset(1.f, 1.f);
526 SetLegoColor();
527 if (fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos> fBackBox.Get3DBox()[0].X()) {
528 //Lego is semi-transparent if we have any sections.
529 glEnable(GL_BLEND);//[1
531 }
532 }
533
534 //Using front point, find the correct order to draw bars from
535 //back to front (it's important only for semi-transparent lego).
536 //Only in cartesian.
537 const Int_t nX = fXEdges.size();
538 const Int_t nY = fYEdges.size();
541 const Int_t addI = frontPoint == 2 || frontPoint == 1 ? 1 : (iInit = nX - 1, irInit = fCoord->GetLastXBin(), -1);
542 const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? 1 : (jInit = nY - 1, jrInit = fCoord->GetLastYBin(), -1);
543
545 if (!PreparePalette()) {
548 } else
550 }
551
554
555 for(Int_t i = iInit, ir = irInit; addI > 0 ? i < nX : i >= 0; i += addI, ir += addI) {
556 for(Int_t j = jInit, jr = jrInit; addJ > 0 ? j < nY : j >= 0; j += addJ, jr += addJ) {
558 if (!ClampZ(zMax))
559 continue;
560
561 const Int_t binID = fSelectionBase + i * fCoord->GetNYBins() + j;
562
565 else if(!fHighColor && fSelectedPart == binID)
567
568 if (fLegoType == kCylindricBars) {
569 Rgl::DrawCylinder(&fQuadric, fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
570 fYEdges[j].second, fMinZ, zMax);
571 } else if (fLegoType == kColorLevel && !fSelectionPass) {
572 Rgl::DrawBoxFrontTextured(fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
575 } else {
576 Rgl::DrawBoxFront(fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
577 fYEdges[j].second, fMinZ, zMax, frontPoint);
578 }
579
582 }
583 }
584
587
588 //Draw outlines for non-cylindrical bars.
589 if (!fSelectionPass) {
591 const TGLDisableGuard lightGuard(GL_LIGHTING);//[2 - 2]
592 if (fXOZSectionPos <= fBackBox.Get3DBox()[0].Y() && fYOZSectionPos <= fBackBox.Get3DBox()[0].X())
593 glColor3d(0., 0., 0.);
594 else
595 glColor4d(0., 0., 0., 0.4);
597
598 const TGLEnableGuard blendGuard(GL_BLEND);//[4-4] + 1]
602
603 for(Int_t i = iInit, ir = irInit; addI > 0 ? i < nX : i >= 0; i += addI, ir += addI) {
604 for(Int_t j = jInit, jr = jrInit; addJ > 0 ? j < nY : j >= 0; j += addJ, jr += addJ) {
606 if (!ClampZ(zMax))
607 continue;
608 if (fLegoType != kCylindricBars) {
609 Rgl::DrawBoxFront(fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
610 fYEdges[j].second, fMinZ, zMax, frontPoint);
611 }
612 if (fDrawErrors && zMax > 0.) {
615 Rgl::DrawError(fXEdges[i].first, fXEdges[i].second, fYEdges[j].first,
616 fYEdges[j].second, zMax, errorZMax);
617 }
618 }
619 }
620
622 }
623
625 DrawPalette();
626}
627
628////////////////////////////////////////////////////////////////////////////////
629///Lego in polar system.
630
632{
633 const Int_t nX = fCosSinTableX.size() - 1;
634 const Int_t nY = fYEdges.size();
635
636 if (!fSelectionPass) {
637 SetLegoColor();
639 glPolygonOffset(1.f, 1.f);
640 }
641
642 Double_t points[4][2] = {};
643
645 if (!PreparePalette()) {
648 } else
650 }
651
654
655 for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
656 for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
658 if (!ClampZ(zMax))
659 continue;
660 points[0][0] = fYEdges[j].first * fCosSinTableX[i].first;
661 points[0][1] = fYEdges[j].first * fCosSinTableX[i].second;
662 points[1][0] = fYEdges[j].second * fCosSinTableX[i].first;
663 points[1][1] = fYEdges[j].second * fCosSinTableX[i].second;
664 points[2][0] = fYEdges[j].second * fCosSinTableX[i + 1].first;
665 points[2][1] = fYEdges[j].second * fCosSinTableX[i + 1].second;
666 points[3][0] = fYEdges[j].first * fCosSinTableX[i + 1].first;
667 points[3][1] = fYEdges[j].first * fCosSinTableX[i + 1].second;
668
669 const Int_t binID = fSelectionBase + i * fCoord->GetNYBins() + j;
670
673 else if(!fHighColor && fSelectedPart == binID)
675
679 else
681
684 }
685 }
686
689
690 //Draw outlines.
691 if (!fSelectionPass) {
694 glColor3d(0., 0., 0.);
700
701 for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
702 for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
704 if (!ClampZ(zMax))
705 continue;
706 points[0][0] = fYEdges[j].first * fCosSinTableX[i].first;
707 points[0][1] = fYEdges[j].first * fCosSinTableX[i].second;
708 points[1][0] = fYEdges[j].second * fCosSinTableX[i].first;
709 points[1][1] = fYEdges[j].second * fCosSinTableX[i].second;
710 points[2][0] = fYEdges[j].second * fCosSinTableX[i + 1].first;
711 points[2][1] = fYEdges[j].second * fCosSinTableX[i + 1].second;
712 points[3][0] = fYEdges[j].first * fCosSinTableX[i + 1].first;
713 points[3][1] = fYEdges[j].first * fCosSinTableX[i + 1].second;
715 }
716 }
717
719 }
720
722 DrawPalette();
723}
724
725////////////////////////////////////////////////////////////////////////////////
726///Lego in cylindrical system.
727
729{
730 const Int_t nX = fCosSinTableX.size() - 1;
731 const Int_t nY = fYEdges.size();
733 if (legoR > 1. || legoR < 0.)
734 legoR = 0.5;
735 const Double_t rRange = fCoord->GetZLength();
736
737 if (!fSelectionPass) {
738 SetLegoColor();
740 glPolygonOffset(1.f, 1.f);
741 }
742
743 Double_t points[4][2] = {};
744 const Double_t sc = (1 - legoR) * fCoord->GetXScale();
745 legoR *= fCoord->GetXScale();
746
748 if (!PreparePalette()) {
751 } else
753 }
754
757
758 for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
759 for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
760 Double_t zMin = legoR + (fMinZ - fCoord->GetZRange().first) / rRange * sc;
762 if (zMin > zMax)
763 std::swap(zMin, zMax);
764
765 points[0][0] = fCosSinTableX[i].first * zMin;
766 points[0][1] = fCosSinTableX[i].second * zMin;
767 points[1][0] = fCosSinTableX[i].first * zMax;
768 points[1][1] = fCosSinTableX[i].second * zMax;
769 points[2][0] = fCosSinTableX[i + 1].first * zMax;
770 points[2][1] = fCosSinTableX[i + 1].second * zMax;
771 points[3][0] = fCosSinTableX[i + 1].first * zMin;
772 points[3][1] = fCosSinTableX[i + 1].second * zMin;
773
774 const Int_t binID = fSelectionBase + i * fCoord->GetNYBins() + j;
775
778 else if(!fHighColor && fSelectedPart == binID)
780
784 }else
785 Rgl::DrawTrapezoid(points, fYEdges[j].first, fYEdges[j].second);
786
789 }
790 }
791
794
795 //Draw outlines.
796 if (!fSelectionPass) {
799 glColor3d(0., 0., 0.);
801
806
807 for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
808 for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
809 Double_t zMin = legoR + (fMinZ - fCoord->GetZRange().first) / rRange * sc;
811 if (zMin > zMax)
812 std::swap(zMin, zMax);
813
814 points[0][0] = fCosSinTableX[i].first * zMin;
815 points[0][1] = fCosSinTableX[i].second * zMin;
816 points[1][0] = fCosSinTableX[i].first * zMax;
817 points[1][1] = fCosSinTableX[i].second * zMax;
818 points[2][0] = fCosSinTableX[i + 1].first * zMax;
819 points[2][1] = fCosSinTableX[i + 1].second * zMax;
820 points[3][0] = fCosSinTableX[i + 1].first * zMin;
821 points[3][1] = fCosSinTableX[i + 1].second * zMin;
822 Rgl::DrawTrapezoid(points, fYEdges[j].first, fYEdges[j].second);
823 }
824 }
825
827 }
828
830 DrawPalette();
831}
832
833////////////////////////////////////////////////////////////////////////////////
834///Lego in spherical system.
835
837{
838 const Int_t nX = fCosSinTableX.size() - 1;
839 const Int_t nY = fCosSinTableY.size() - 1;
840 const Double_t rRange = fCoord->GetZLength();
842 if (legoR > 1. || legoR < 0.)
843 legoR = 0.5;
844
845 if (!fSelectionPass) {
846 SetLegoColor();
848 glPolygonOffset(1.f, 1.f);
849 }
850
851 Double_t points[8][3] = {};
852 const Double_t sc = 1 - legoR;
853
855 if (!PreparePalette()) {
858 } else
860 }
861
864
865 for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
866 for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
867 Double_t zMin = legoR + (fMinZ - fCoord->GetZRange().first) / rRange * sc;
869 if (zMin > zMax)
870 std::swap(zMin, zMax);
871
872 points[4][0] = zMin * fCosSinTableY[j].second * fCosSinTableX[i].first;
873 points[4][1] = zMin * fCosSinTableY[j].second * fCosSinTableX[i].second;
874 points[4][2] = zMin * fCosSinTableY[j].first;
875 points[5][0] = zMin * fCosSinTableY[j].second * fCosSinTableX[i + 1].first;
876 points[5][1] = zMin * fCosSinTableY[j].second * fCosSinTableX[i + 1].second;
877 points[5][2] = zMin * fCosSinTableY[j].first;
878 points[6][0] = zMax * fCosSinTableY[j].second * fCosSinTableX[i + 1].first;
879 points[6][1] = zMax * fCosSinTableY[j].second * fCosSinTableX[i + 1].second;
880 points[6][2] = zMax * fCosSinTableY[j].first;
881 points[7][0] = zMax * fCosSinTableY[j].second * fCosSinTableX[i].first;
882 points[7][1] = zMax * fCosSinTableY[j].second * fCosSinTableX[i].second;
883 points[7][2] = zMax * fCosSinTableY[j].first;
884 points[0][0] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i].first;
885 points[0][1] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i].second;
886 points[0][2] = zMin * fCosSinTableY[j + 1].first;
887 points[1][0] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].first;
888 points[1][1] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].second;
889 points[1][2] = zMin * fCosSinTableY[j + 1].first;
890 points[2][0] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].first;
891 points[2][1] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].second;
892 points[2][2] = zMax * fCosSinTableY[j + 1].first;
893 points[3][0] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i].first;
894 points[3][1] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i].second;
895 points[3][2] = zMax * fCosSinTableY[j + 1].first;
896
897 const Int_t binID = fSelectionBase + i * fCoord->GetNYBins() + j;
898
901 else if(!fHighColor && fSelectedPart == binID)
906 else
908
911 }
912 }
913
916
917 //Draw outlines.
918 if (!fSelectionPass) {
921 glColor3d(0., 0., 0.);
927
928 for(Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
929 for(Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
930 Double_t zMin = legoR + (fMinZ - fCoord->GetZRange().first) / rRange * sc;
932 if (zMin > zMax)
933 std::swap(zMin, zMax);
934
935 points[4][0] = zMin * fCosSinTableY[j].second * fCosSinTableX[i].first;
936 points[4][1] = zMin * fCosSinTableY[j].second * fCosSinTableX[i].second;
937 points[4][2] = zMin * fCosSinTableY[j].first;
938 points[5][0] = zMin * fCosSinTableY[j].second * fCosSinTableX[i + 1].first;
939 points[5][1] = zMin * fCosSinTableY[j].second * fCosSinTableX[i + 1].second;
940 points[5][2] = zMin * fCosSinTableY[j].first;
941 points[6][0] = zMax * fCosSinTableY[j].second * fCosSinTableX[i + 1].first;
942 points[6][1] = zMax * fCosSinTableY[j].second * fCosSinTableX[i + 1].second;
943 points[6][2] = zMax * fCosSinTableY[j].first;
944 points[7][0] = zMax * fCosSinTableY[j].second * fCosSinTableX[i].first;
945 points[7][1] = zMax * fCosSinTableY[j].second * fCosSinTableX[i].second;
946 points[7][2] = zMax * fCosSinTableY[j].first;
947 points[0][0] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i].first;
948 points[0][1] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i].second;
949 points[0][2] = zMin * fCosSinTableY[j + 1].first;
950 points[1][0] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].first;
951 points[1][1] = zMin * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].second;
952 points[1][2] = zMin * fCosSinTableY[j + 1].first;
953 points[2][0] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].first;
954 points[2][1] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i + 1].second;
955 points[2][2] = zMax * fCosSinTableY[j + 1].first;
956 points[3][0] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i].first;
957 points[3][1] = zMax * fCosSinTableY[j + 1].second * fCosSinTableX[i].second;
958 points[3][2] = zMax * fCosSinTableY[j + 1].first;
960 }
961 }
962
964 }
965
967 DrawPalette();
968}
969
970////////////////////////////////////////////////////////////////////////////////
971///Set lego's color.
972
974{
975 Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.15f};
976
978 if (const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
979 c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
980
982 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
985}
986
987////////////////////////////////////////////////////////////////////////////////
988///XOZ plane parallel section.
989
991{
992 Int_t binY = -1;
993
994 for (Int_t i = 0, e = fYEdges.size(); i < e; ++i) {
995 if (fYEdges[i].first <= fXOZSectionPos && fXOZSectionPos <= fYEdges[i].second) {
996 binY = i;
997 break;
998 }
999 }
1000
1001 if (binY >= 0) {
1002 binY += fCoord->GetFirstYBin();
1003 glColor3d(1., 0., 0.);
1004 glLineWidth(3.f);
1005 //Draw 2d hist on the profile's plane.
1006 for (UInt_t i = 0, ir = fCoord->GetFirstXBin(), e = fXEdges.size(); i < e; ++i, ++ir) {
1008 if (!ClampZ(zMax))
1009 continue;
1010
1011 glBegin(GL_LINE_LOOP);
1016 glEnd();
1017 }
1018
1019 glLineWidth(1.f);
1020 }
1021}
1022
1023////////////////////////////////////////////////////////////////////////////////
1024///YOZ plane parallel section.
1025
1027{
1028 Int_t binX = -1;
1029
1030 for (Int_t i = 0, e = fXEdges.size(); i < e; ++i) {
1031 if (fXEdges[i].first <= fYOZSectionPos && fYOZSectionPos <= fXEdges[i].second) {
1032 binX = i;
1033 break;
1034 }
1035 }
1036
1037 if (binX >= 0) {
1038 binX += fCoord->GetFirstXBin();//fBinsX.first;
1039 glColor3d(1., 0., 0.);
1040 glLineWidth(3.f);
1041 //Draw 2d hist on the profile's plane.
1042 for (UInt_t i = 0, ir = fCoord->GetFirstYBin(), e = fYEdges.size(); i < e; ++i, ++ir) {
1044 if (!ClampZ(zMax))
1045 continue;
1046
1047 glBegin(GL_LINE_LOOP);
1052 glEnd();
1053 }
1054
1055 glLineWidth(1.f);
1056 }
1057}
1058
1059////////////////////////////////////////////////////////////////////////////////
1060///Empty. No such sections for lego.
1061
1063{
1064}
1065
1066////////////////////////////////////////////////////////////////////////////////
1067///Remove all sections and repaint.
1068
1070{
1071 const TGLVertex3 *frame = fBackBox.Get3DBox();
1072 if (event == kButton1Double && (fXOZSectionPos > frame[0].Y() || fYOZSectionPos > frame[0].X())) {
1073 fXOZSectionPos = frame[0].Y();
1074 fYOZSectionPos = frame[0].X();
1075 if (fBoxCut.IsActive())
1077 //gGLManager->PaintSingleObject(this);
1078 if (!gVirtualX->IsCmdThread())
1079 gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%zx)->Paint()", (size_t)this));
1080 else
1081 Paint();
1082 } else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
1083 Info("ProcessEvent", "Box cut does not exist for lego");
1084 }
1085}
1086
1087////////////////////////////////////////////////////////////////////////////////
1088///Clamp z value.
1089
1091{
1092 if (fCoord->GetZLog())
1093 if (zVal <= 0.)
1094 return kFALSE;
1095 else
1097 else
1098 zVal *= fCoord->GetZScale();
1099
1100 const TGLVertex3 *frame = fBackBox.Get3DBox();
1101
1102 if (zVal > frame[4].Z())
1103 zVal = frame[4].Z();
1104 else if (zVal < frame[0].Z())
1105 zVal = frame[0].Z();
1106
1107 return kTRUE;
1108}
1109
1110////////////////////////////////////////////////////////////////////////////////
1111///Initialize color palette.
1112
1114{
1115 if(fMinMaxVal.first == fMinMaxVal.second)
1116 return kFALSE;//must be std::abs(fMinMaxVal.second - fMinMaxVal.first) < ...
1117
1118 //User-defined contours are disabled, to be fixed in a future.
1121
1123 if (!paletteSize)
1124 paletteSize = 20;
1125
1127}
1128
1129////////////////////////////////////////////////////////////////////////////////
1130///Draw. Palette.
1131///Originally, fCamera was never null.
1132///It can be a null now because of gl-viewer.
1133
1135{
1136 if (!fCamera) {
1137 //Thank you, gl-viewer!
1138 return;
1139 }
1140
1142
1143 glFinish();
1144
1145 fCamera->SetCamera();
1147}
1148
1149////////////////////////////////////////////////////////////////////////////////
1150///Draw. Palette. Axis.
1151
1153{
1154 gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
1156}
@ 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
#define e(i)
Definition RSha256.hxx:103
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
@ kWhite
Definition Rtypes.h:66
#define X(type, name)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
@ kGLSpherical
Definition TGLUtil.h:47
@ kGLCylindrical
Definition TGLUtil.h:46
@ kGLPolar
Definition TGLUtil.h:45
@ kGLCartesian
Definition TGLUtil.h:44
Option_t Option_t option
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
#define gROOT
Definition TROOT.h:411
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define gVirtualX
Definition TVirtualX.h:337
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:31
Double_t GetXmax() const
Definition TAxis.h:142
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:521
Double_t GetXmin() const
Definition TAxis.h:141
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:545
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:531
The color creation and management class.
Definition TColor.h:22
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1926
void MoveBox(Int_t px, Int_t py, Int_t axisID)
Move box cut along selected direction.
void TurnOnOff()
Turn the box cut on/off.
void StartMovement(Int_t px, Int_t py)
Start cut's movement.
Bool_t IsActive() const
Bool_t InitGeometryCartesian()
Geometry for lego in cartesian coords.
Bool_t PreparePalette() const
Initialize color palette.
void DrawSectionXOZ() const override
XOZ plane parallel section.
void DrawSectionXOY() const override
Empty. No such sections for lego.
void DrawLegoSpherical() const
Lego in spherical system.
std::vector< Rgl::Range_t > fXEdges
void StartPan(Int_t px, Int_t py) override
User clicks on a lego with middle mouse button (middle for pad).
Bool_t InitGeometryCylindrical()
Geometry for lego in cylindrical coords.
void AddOption(const TString &stringOption) override
Parse additional options.
TGLLevelPalette fPalette
void InitGL() const override
Initialize some gl state variables.
char * GetPlotInfo(Int_t px, Int_t py) override
Obtain bin's info (i, j, value).
void DrawLegoPolar() const
Lego in polar system.
void DrawSectionYOZ() const override
YOZ plane parallel section.
void Pan(Int_t px, Int_t py) override
Move lego or section.
Bool_t ClampZ(Double_t &zVal) const
Clamp z value.
Bool_t InitGeometrySpherical()
Geometry for lego in spherical coords.
void DrawPlot() const override
Select method corresponding to coordinate system.
TGLQuadric fQuadric
TGLLegoPainter(const TGLLegoPainter &)
void DrawPalette() const
Draw.
void DrawLegoCartesian() const
Lego in cartesian system.
void SetLegoColor() const
Set lego's color.
std::vector< Rgl::Range_t > fYEdges
std::vector< CosSin_t > fCosSinTableX
Rgl::Range_t fMinMaxVal
void DeInitGL() const override
Return some gl states to original values.
void DrawLegoCylindrical() const
Lego in cylindrical system.
std::vector< CosSin_t > fCosSinTableY
Bool_t InitGeometryPolar()
Geometry for lego in polar coords.
void ProcessEvent(Int_t event, Int_t px, Int_t py) override
Remove all sections and repaint.
ELegoType fLegoType
Bool_t InitGeometry() override
Select method.
void DrawPaletteAxis() const override
Draw. Palette. Axis.
void DisableTexture() const
Disable 1D texture.
Definition TGLUtil.cxx:4244
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition TGLUtil.cxx:4261
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition TGLUtil.cxx:4160
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition TGLUtil.cxx:4225
void SetPlotBox(const Rgl::Range_t &xRange, const Rgl::Range_t &yRange, const Rgl::Range_t &zRange)
Set up a frame box.
const TGLVertex3 * Get3DBox() const
Get 3D box.
void DrawBox(Int_t selectedPart, Bool_t selectionPass, const std::vector< Double_t > &zLevels, Bool_t highColor) const
Draw back box for a plot.
Int_t GetFrontPoint() const
The nearest point.
Camera for TGLPlotPainter and sub-classes.
void StartPan(Int_t px, Int_t py)
User clicks somewhere (px, py).
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
void SetCamera() const
Viewport and projection.
void Pan(Int_t px, Int_t py)
Pan camera.
Int_t GetHeight() const
viewport[3]
void SetViewVolume(const TGLVertex3 *box)
'box' is the TGLPlotPainter's back box's coordinates.
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
Double_t GetZLength() const
Z length.
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.
Bool_t GetXLog() const
Get X log.
Int_t GetFirstXBin() const
Int_t GetFirstYBin() const
const Rgl::Range_t & GetZRange() const
Z range.
const Rgl::Range_t & GetYRangeScaled() const
Scaled range.
void ResetModified()
Reset modified.
Bool_t GetYLog() const
Get Y log.
Bool_t GetZLog() const
Get Z log.
Bool_t Modified() const
Modified.
Double_t GetXScale() const
Double_t GetZScale() const
Int_t GetNXBins() const
Number of X bins.
const Rgl::Range_t & GetZRangeScaled() const
Scaled range.
const Rgl::Range_t & GetYRange() const
Y range.
Int_t GetLastYBin() const
Int_t GetNYBins() const
Number of Y bins.
Int_t GetLastXBin() const
EGLCoordType GetCoordType() const
Get coordinates type.
Double_t GetYLength() const
Y length.
Double_t GetFactor() const
Get factor.
Base class for plot-painters that provide GL rendering of various 2D and 3D histograms,...
void DrawSections() const
Draw sections (if any).
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
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
virtual Float_t GetBarWidth() const
Definition TH1.h:502
virtual Float_t GetBarOffset() const
Definition TH1.h:501
static TClass * Class()
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9101
@ kUserContour
User specified contour levels.
Definition TH1.h:405
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5076
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
void ResetBit(UInt_t f)
Definition TObject.h:201
SCoord_t fY
Definition TPoint.h:36
SCoord_t fX
Definition TPoint.h:35
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:384
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2362
Float_t GetLegoInnerR() const
Definition TStyle.h:242
Int_t GetNumberContours() const
Definition TStyle.h:243
void DrawTrapezoid(const Double_t ver[][2], Double_t zMin, Double_t zMax, Bool_t color=kTRUE)
Definition TGLUtil.cxx:3347
void DrawTrapezoidTextured(const Double_t ver[][2], Double_t zMin, Double_t zMax, Double_t tMin, Double_t tMax)
In polar coordinates, box became trapezoid.
Definition TGLUtil.cxx:3417
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 SetZLevels(TAxis *zAxis, Double_t zMin, Double_t zMax, Double_t zScale, std::vector< Double_t > &zLevels)
Definition TGLUtil.cxx:3819
void DrawPalette(const TGLPlotCamera *camera, const TGLLevelPalette &palette)
Draw. Palette.
void DrawPaletteAxis(const TGLPlotCamera *camera, const Range_t &minMax, Bool_t logZ)
void DrawTrapezoidTextured2(const Double_t ver[][2], Double_t zMin, Double_t zMax, Double_t tMin, Double_t tMax)
In polar coordinates, box became trapezoid.
Definition TGLUtil.cxx:3494
void DrawCylinder(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:3243
void DrawError(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax)
Definition TGLUtil.cxx:3297
std::pair< Double_t, Double_t > Range_t
Definition TGLUtil.h:1202
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 DrawBoxFrontTextured(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax, Double_t tMin, Double_t tMax, Int_t front)
Draws lego's bar as a 3d box LULULULU.
Definition TGLUtil.cxx:3133
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:251
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
constexpr Double_t Pi()
Definition TMath.h:40
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:599
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:773
constexpr Double_t TwoPi()
Definition TMath.h:47