Logo ROOT  
Reference Guide
TGLSurfacePainter.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
12#include <algorithm>
13#include <cstdlib>
14#include <cctype>
15
16#include "KeySymbols.h"
17#include "TVirtualX.h"
18#include "Buttons.h"
19#include "TString.h"
20#include "TStyle.h"
21#include "TGaxis.h"
22#include "TColor.h"
23#include "TROOT.h"
24#include "TMath.h"
25#include "TAxis.h"
26#include "TH1.h"
27#include "TRandom.h"
28
29#include "TGLSurfacePainter.h"
30#include "TGLPlotCamera.h"
31#include "TGLIncludes.h"
32
33/** \class TGLSurfacePainter
34\ingroup opengl
35Implements painting of TH2 with "SURF" option.
36*/
37
39
41
42////////////////////////////////////////////////////////////////////////////////
43/// Constructor.
44
46{
47 fRGBA[0] = rhs.fRGBA[0], fRGBA[1] = rhs.fRGBA[1], fRGBA[2] = rhs.fRGBA[2], fRGBA[3] = rhs.fRGBA[3];
48 fVertices.swap(rhs.fVertices);
49}
50
51////////////////////////////////////////////////////////////////////////////////
52/// Constructor.
53
55 : TGLPlotPainter(hist, camera, coord, kTRUE, kTRUE, kTRUE),
56 fType(kSurf),
59{
60}
61
62////////////////////////////////////////////////////////////////////////////////
63///Coords for point on surface under cursor.
64
66{
67 static char null[] = { "" };
68 if (fSelectedPart) {
69 if (fHighColor)
70 return fSelectedPart < fSelectionBase ? (char *)"TF2" : (char *)"Switch to true-color mode to obtain correct info";
71 return fSelectedPart < fSelectionBase ? (char *)"TF2" : WindowPointTo3DPoint(px, py);
72 }
73 return null;
74}
75
76////////////////////////////////////////////////////////////////////////////////
77///Set mesh, normals.
78
80{
81 Bool_t ret = kFALSE;
82 switch (fCoord->GetCoordType()) {
83 case kGLCartesian:
84 ret = InitGeometryCartesian(); break;
85 case kGLPolar:
86 ret = InitGeometryPolar(); break;
87 case kGLCylindrical:
88 ret = InitGeometryCylindrical(); break;
89 case kGLSpherical:
90 ret = InitGeometrySpherical(); break;
91 default:
92 return kFALSE;
93 }
95 return ret;
96}
97
98////////////////////////////////////////////////////////////////////////////////
99///User clicks right mouse button (in a pad).
100
102{
103 fMousePosition.fX = px;
105 fCamera->StartPan(px, py);
107}
108
109////////////////////////////////////////////////////////////////////////////////
110///User's moving mouse cursor, with middle mouse button pressed (for pad).
111///Calculate 3d shift related to 2d mouse movement.
112
114{
115 if (fSelectedPart >= fSelectionBase) {//Pan camera.
118
121 fCamera->Pan(px, py);
122
125 } else if (fSelectedPart > 0) {
126 //Convert py into bottom-top orientation.
127 py = fCamera->GetHeight() - py;
128
131
134
135
136 if (!fHighColor) {
139 else
140 MoveSection(px, py);
141 }
142 else
143 MoveSection(px, py);
144
147 }
148
151}
152
153////////////////////////////////////////////////////////////////////////////////
154///Additional options for surfaces.
155
157{
158 using namespace std;
159 const Ssiz_t surfPos = option.Index("surf");//"surf" _already_ _exists_ in a string.
160 if (surfPos + 4 < option.Length() && isdigit(option[surfPos + 4])) {
161 switch (option[surfPos + 4] - '0') {
162 case 1:
163 fType = kSurf1;
164 break;
165 case 2:
166 fType = kSurf2;
167 break;
168 case 3:
169 fType = kSurf3;
171 break;
172 case 4:
173 fType = kSurf4;
174 break;
175 case 5:
177 fType = kSurf3;
178 else
179 fType = kSurf5;
180 break;
181 default:
182 fType = kSurf;
183 }
184 } else
185 fType = kSurf;
186
187 option.Index("z") == kNPOS ? fDrawPalette = kFALSE : fDrawPalette = kTRUE;
188}
189
190////////////////////////////////////////////////////////////////////////////////
191///Remove all profiles/sections.
192
194{
195 const TGLVertex3 *frame = fBackBox.Get3DBox();
196 if (py == kKey_P || py == kKey_p) {
197
198 if (HasSections()) {
203 fXOZSectionPos = frame[0].Y();
204 fYOZSectionPos = frame[0].X();
205 fXOYSectionPos = frame[0].Z();
207 }
208 } else if (event == kButton1Double && (HasSections() || HasProjections() || fBoxCut.IsActive())) {
209 fXOZSectionPos = frame[0].Y();
210 fYOZSectionPos = frame[0].X();
211 fXOYSectionPos = frame[0].Z();
212 fXOZProj.clear();
213 fYOZProj.clear();
214 fXOYProj.clear();
215 if (fBoxCut.IsActive())
217 if (!gVirtualX->IsCmdThread())
218 gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%zx)->Paint()", (size_t)this));
219 else
220 Paint();
221 } else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
222 if (fHighColor)
223 Info("ProcessEvent", "Switch to true color to use box cut");
224 else {
227 }
228 }
229}
230
231////////////////////////////////////////////////////////////////////////////////
232///Initialize some OpenGL state variables.
233
235{
236 glEnable(GL_LIGHTING);
237 glEnable(GL_LIGHT0);
238 glEnable(GL_DEPTH_TEST);
239 glDisable(GL_CULL_FACE);
240 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
241}
242
243////////////////////////////////////////////////////////////////////////////////
244///Initialize some OpenGL state variables.
245
247{
248 glDisable(GL_LIGHTING);
249 glDisable(GL_LIGHT0);
250 glDisable(GL_DEPTH_TEST);
251 glDisable(GL_CULL_FACE);
252 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
253}
254
255
256////////////////////////////////////////////////////////////////////////////////
257///One normal per vertex;
258///this normal is average of
259///neighbouring triangles normals.
260
262{
263 const Int_t nX = fCoord->GetNXBins();
264 const Int_t nY = fCoord->GetNYBins();
265
266 fFaceNormals.resize((nX + 1) * (nY + 1));
267 fFaceNormals.assign(fFaceNormals.size(), std::pair<TGLVector3, TGLVector3>());
268 fFaceNormals.SetRowLen(nY + 1);
269
270
271 //first, calculate normal for each triangle face
272 for (Int_t i = 0; i < nX - 1; ++i) {
273 for (Int_t j = 0; j < nY - 1; ++j) {
274 //first "bottom-left" triangle
275 TMath::Normal2Plane(fMesh[i][j + 1].CArr(), fMesh[i][j].CArr(), fMesh[i + 1][j].CArr(),
276 fFaceNormals[i + 1][j + 1].first.Arr());
277 //second "top-right" triangle
278 TMath::Normal2Plane(fMesh[i + 1][j].CArr(), fMesh[i + 1][j + 1].CArr(), fMesh[i][j + 1].CArr(),
279 fFaceNormals[i + 1][j + 1].second.Arr());
280 }
281 }
282
283 fAverageNormals.resize(nX * nY);
284 fAverageNormals.SetRowLen(nY);
285
287 //second, calculate average normal for each vertex
288 for (Int_t i = 0; i < nX; ++i) {
289 for (Int_t j = 0; j < nY; ++j) {
290 TGLVector3 &norm = fAverageNormals[i][j];
291
292 norm += fFaceNormals[i][j].second;
293 norm += fFaceNormals[i][j + 1].first;
294 norm += fFaceNormals[i][j + 1].second;
295 norm += fFaceNormals[i + 1][j].first;
296 norm += fFaceNormals[i + 1][j].second;
297 norm += fFaceNormals[i + 1][j + 1].first;
298
299 if (!norm.X() && !norm.Y() && !norm.Z())
300 continue;
301
302 norm.Normalise();
303 }
304 }
305}
306
307////////////////////////////////////////////////////////////////////////////////
308///Set color for surface.
309
311{
312 Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.35f};
313
314 if (fHist->GetFillColor() != kWhite && fType != kSurf1 && fType != kSurf2 && fType != kSurf5)
315 if (const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
316 c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
317
318 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
319 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
320 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
321 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
322}
323
324////////////////////////////////////////////////////////////////////////////////
325///Draw surf/surf1/surf2/surf4
326
328{
329 //Shift plot to point of origin.
330 const Rgl::PlotTranslation trGuard(this);
331
332 if (fCoord->GetCoordType() == kGLCartesian) {
334 DrawSections();
335 if (!fSelectionPass)
337 }
338
339 if (!fSelectionPass) {
341 glEnable(GL_POLYGON_OFFSET_FILL);
342 glPolygonOffset(1.f, 1.f);
343
344 if (HasSections() || HasProjections())
345 {
346 //Surface is semi-transparent during dynamic profiling
347 glEnable(GL_BLEND);
348 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
349 }
350
351 }
352
353 if (Textured() && !fSelectionPass) {
354 if (!PreparePalette()) {
355 fType = kSurf;
357 }
358 else if (fType != kSurf3)
359 fPalette.EnableTexture(GL_MODULATE);
360 }
361
362 const Int_t nX = fCoord->GetNXBins();
363 const Int_t nY = fCoord->GetNYBins();
364 const Int_t frontPoint = fBackBox.GetFrontPoint();
365 Int_t i = 0, firstJ = 0;
366 const Int_t addI = frontPoint == 2 || frontPoint == 1 ? i = 0, 1 : (i = nX - 2, -1);
367 const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? firstJ = 0, 1 : (firstJ = nY - 2, -1);
368
371
372 for (; addI > 0 ? i < nX - 1 : i >= 0; i += addI) {
373 for (Int_t j = firstJ; addJ > 0 ? j < nY - 1 : j >= 0; j += addJ) {
374 Int_t triNumber = 2 * i * (nY - 1) + j * 2 + fSelectionBase;
375
376 Double_t xMin = TMath::Min(TMath::Min(fMesh[i][j + 1].X(), fMesh[i][j].X()), fMesh[i + 1][j].X());
377 Double_t xMax = TMath::Max(TMath::Max(fMesh[i][j + 1].X(), fMesh[i][j].X()), fMesh[i + 1][j].X());
378 Double_t yMin = TMath::Min(TMath::Min(fMesh[i][j + 1].Y(), fMesh[i][j].Y()), fMesh[i + 1][j].Y());
379 Double_t yMax = TMath::Max(TMath::Max(fMesh[i][j + 1].Y(), fMesh[i][j].Y()), fMesh[i + 1][j].Y());
380 Double_t zMin = TMath::Min(TMath::Min(fMesh[i][j + 1].Z(), fMesh[i][j].Z()), fMesh[i + 1][j].Z());
381 Double_t zMax = TMath::Max(TMath::Max(fMesh[i][j + 1].Z(), fMesh[i][j].Z()), fMesh[i + 1][j].Z());
382
383 if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
384 continue;
385
387 Rgl::ObjectIDToColor(triNumber, kFALSE);
388
389 if ((fType == kSurf1 || fType == kSurf2 || fType == kSurf5) && !fSelectionPass)
390 Rgl::DrawFaceTextured(fMesh[i][j + 1], fMesh[i][j], fMesh[i + 1][j],
391 fTexMap[i][j + 1], fTexMap[i][j], fTexMap[i + 1][j],
392 fAverageNormals[i][j + 1], fAverageNormals[i][j],
393 fAverageNormals[i + 1][j]);
394 else
395 Rgl::DrawSmoothFace(fMesh[i][j + 1], fMesh[i][j], fMesh[i + 1][j],
396 fAverageNormals[i][j + 1], fAverageNormals[i][j],
397 fAverageNormals[i + 1][j]);
398
399 ++triNumber;
400
402 Rgl::ObjectIDToColor(triNumber, kFALSE);
403
404 if ((fType == kSurf1 || fType == kSurf2 || fType == kSurf5) && !fSelectionPass)
405 Rgl::DrawFaceTextured(fMesh[i + 1][j], fMesh[i + 1][j + 1], fMesh[i][j + 1],
406 fTexMap[i + 1][j], fTexMap[i + 1][j + 1], fTexMap[i][j + 1],
407 fAverageNormals[i + 1][j], fAverageNormals[i + 1][j + 1],
408 fAverageNormals[i][j + 1]);
409 else
410 Rgl::DrawSmoothFace(fMesh[i + 1][j], fMesh[i + 1][j + 1], fMesh[i][j + 1],
411 fAverageNormals[i + 1][j], fAverageNormals[i + 1][j + 1],
412 fAverageNormals[i][j + 1]);
413 }
414 }
415
416 if (!fSelectionPass)
417 glDisable(GL_POLYGON_OFFSET_FILL);
418
419 if (fBoxCut.IsActive())
421
422 if (fType != kSurf3 && Textured() && !fSelectionPass)
424
425 //Draw outlines here
426 if (!fSelectionPass) {
427 const TGLEnableGuard blendGuard(GL_BLEND);
428
429 if (fType == kSurf || fType == kSurf1 || fType == kSurf3) {
430 const TGLDisableGuard lightGuard(GL_LIGHTING);
431 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
432
433 glDepthMask(GL_FALSE);
434
435 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
436 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
437
438 glColor4d(0., 0., 0., 0.5);
439
440 for (i = 0; i < nX - 1; ++i) {
441 for (Int_t j = 0; j < nY - 1; ++j) {
442 Rgl::DrawQuadOutline(fMesh[i][j + 1], fMesh[i][j], fMesh[i + 1][j], fMesh[i + 1][j + 1]);
443 }
444 }
445
446 glDepthMask(GL_TRUE);
447 }
448 }
449
450 if (fType == kSurf3 && !fSelectionPass) {
451 fPalette.EnableTexture(GL_MODULATE);
452 const TGLEnableGuard blend(GL_BLEND);
453 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
456 }
457
458 if (!fSelectionPass && fSelectedPart > 6) {
459 //Draw red outline for surface.
460 const TGLDisableGuard lightGuard(GL_LIGHTING);
461 const TGLEnableGuard blendGuard(GL_BLEND);
462 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
463 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
464 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
465 glLineWidth(3.f);
466
467 glColor4d(1.f, 0.f, 0.4f, 0.6f);
468 glBegin(GL_LINE_STRIP);
469 for (i = 0; i < nX; ++i)
470 glVertex3dv(fMesh[i][0].CArr());
471 for (Int_t j = 0; j < nY; ++j)
472 glVertex3dv(fMesh[nX - 1][j].CArr());
473 for (i = nX - 1; i >= 0; --i)
474 glVertex3dv(fMesh[i][nY - 1].CArr());
475 for (Int_t j = nY - 1; j >= 0; --j)
476 glVertex3dv(fMesh[0][j].CArr());
477 glEnd();
478 glLineWidth(1.f);
479 }
480
482 DrawPalette();
483}
484
485////////////////////////////////////////////////////////////////////////////////
486///Find bin ranges for X and Y axes,
487///axes ranges for X, Y and Z.
488///Function returns false, if logarithmic scale for
489///some axis was requested, but we cannot
490///find correct range.
491
493{
494 if (!fCoord->SetRanges(fHist, kFALSE, kFALSE)) //the second arg must be drawErrors, the third is always kFALSE.
495 return kFALSE;
496
498 //Set surface's mesh
499 //Calculates table of X and Y for lego (Z is obtained during drawing) or
500 //calculate mesh of triangles with vertices in the centres of bins
501 const Int_t nX = fCoord->GetNXBins();
502 const Int_t nY = fCoord->GetNYBins();
503
504 fMesh.resize(nX * nY);
505 fMesh.SetRowLen(nY);
506
507 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
508 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
510 : fMesh[i][j].X() = fXAxis->GetBinCenter(ir) * fCoord->GetXScale();
512 : fMesh[i][j].Y() = fYAxis->GetBinCenter(jr) * fCoord->GetYScale();
513
514 Double_t z = fHist->GetBinContent(ir, jr);
515 ClampZ(z);
516 fMesh[i][j].Z() = z;
517 }
518 }
519
520 if (Textured()) {
522 fMinMaxVal.second = fMinMaxVal.first;
523
524 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
525 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
526 const Double_t val = fHist->GetBinContent(i, j);
527 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
528 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
529 }
530 }
531
532 ClampZ(fMinMaxVal.first);
533 ClampZ(fMinMaxVal.second);
534
536 }
537
538 SetNormals();
539
540 if (fCoord->Modified()) {
542 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
548 }
549
550 return kTRUE;
551}
552
553////////////////////////////////////////////////////////////////////////////////
554///Find bin ranges for X and Y axes,
555///axes ranges for X, Y and Z.
556///Function returns false, if logarithmic scale for
557///some axis was requested, but we cannot
558///find correct range.
559
561{
563 return kFALSE;
564
566
567 if (fCoord->Modified()) {
569 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
574 }
575
576 const Int_t nY = fCoord->GetNYBins();
577 const Int_t nX = fCoord->GetNXBins();
578
579 fMesh.resize(nX * nY);
580 fMesh.SetRowLen(nY);
581
582 const Double_t fullAngle = fXAxis->GetBinCenter(fXAxis->GetNbins()) - fXAxis->GetBinCenter(1);
583 const Double_t phiLow = fXAxis->GetBinCenter(1);
585
586 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
587 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
588 const Double_t angle = (fXAxis->GetBinCenter(ir) - phiLow) / fullAngle * TMath::TwoPi();
589 const Double_t radius = ((fYAxis->GetBinCenter(jr)) - fYAxis->GetBinCenter(1)) /
590 rRange * fCoord->GetYScale();
591 fMesh[i][j].X() = radius * TMath::Cos(angle);
592 fMesh[i][j].Y() = radius * TMath::Sin(angle);
593 Double_t z = fHist->GetBinContent(ir, jr);
594 ClampZ(z);
595 fMesh[i][j].Z() = z;
596 }
597 }
598
599 SetNormals();
600
601 if (Textured()) {
603 fMinMaxVal.second = fMinMaxVal.first;
604
605 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
606 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
607 const Double_t val = fHist->GetBinContent(i, j);
608 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
609 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
610 }
611 }
612
614 }
615
616
617 return kTRUE;
618}
619
620////////////////////////////////////////////////////////////////////////////////
621///Find bin ranges for X and Y axes,
622///axes ranges for X, Y and Z.
623///Function returns false, if logarithmic scale for
624///some axis was requested, but we cannot
625///find correct range.
626
628{
630 return kFALSE;
631
633
634 if (fCoord->Modified()) {
636 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
641 }
642
643 const Int_t nY = fCoord->GetNYBins();
644 const Int_t nX = fCoord->GetNXBins();
645 fMesh.resize(nX * nY);
646 fMesh.SetRowLen(nY);
647
648 Double_t legoR = gStyle->GetLegoInnerR();
649 if (legoR > 1. || legoR < 0.)
650 legoR = 0.5;
651 const Double_t rRange = fCoord->GetZLength();
652 const Double_t sc = (1 - legoR) * fCoord->GetXScale();
653 legoR *= fCoord->GetXScale();
654
655 const Double_t fullAngle = fXAxis->GetBinCenter(fXAxis->GetNbins()) - fXAxis->GetBinCenter(1);
656 const Double_t phiLow = fXAxis->GetBinCenter(1);
657 Double_t angle = 0.;
658
659 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
660 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
661 angle = (fXAxis->GetBinLowEdge(ir) - phiLow) / fullAngle * TMath::TwoPi();
662 Double_t r = fType != kSurf5 ? legoR + (fHist->GetBinContent(ir, jr) - fCoord->GetZRange().first) / rRange * sc : legoR;
663 fMesh[i][j].X() = r * TMath::Cos(angle);
664 fMesh[i][j].Y() = fCoord->GetYLog() ?
666 :
668 fMesh[i][j].Z() = r * TMath::Sin(angle);
669 }
670 }
671
672 if (Textured()) {
674 fMinMaxVal.second = fMinMaxVal.first;
675
676 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
677 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
678 const Double_t val = fHist->GetBinContent(i, j);
679 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
680 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
681 }
682 }
683
685 }
686
687
688 SetNormals();
689
690 return kTRUE;
691}
692
693////////////////////////////////////////////////////////////////////////////////
694///Find bin ranges for X and Y axes,
695///axes ranges for X, Y and Z.
696///Function returns false, if logarithmic scale for
697///some axis was requested, but we cannot
698///find correct range.
699
701{
703 return kFALSE;
704
706
707 if (fCoord->Modified()) {
709 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
714 }
715
716 const Int_t nY = fCoord->GetNYBins();
717 const Int_t nX = fCoord->GetNXBins();
718 fMesh.resize(nX * nY);
719 fMesh.SetRowLen(nY);
720
721 Double_t legoR = gStyle->GetLegoInnerR();
722 if (legoR > 1. || legoR < 0.)
723 legoR = 0.5;
724 const Double_t rRange = fCoord->GetZLength();
725 const Double_t sc = (1 - legoR) * fCoord->GetXScale();
726 legoR *= fCoord->GetXScale();
727
728 //0 <= theta <= 2 * pi
729 const Double_t fullTheta = fXAxis->GetBinCenter(fXAxis->GetNbins()) - fXAxis->GetBinCenter(1);
730 const Double_t thetaLow = fXAxis->GetBinCenter(1);
731 //0 <= phi <= pi
732 const Double_t fullPhi = fYAxis->GetBinCenter(fYAxis->GetNbins()) - fYAxis->GetBinCenter(1);
733 const Double_t phiLow = fYAxis->GetBinCenter(1);
734
735 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
736
737 const Double_t theta = (fXAxis->GetBinCenter(ir) - thetaLow) / fullTheta * TMath::TwoPi();
738
739 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
740
741 const Double_t phi = (fYAxis->GetBinCenter(jr) - phiLow) / fullPhi * TMath::Pi();
742 const Double_t r = fType != kSurf5 ? legoR + (fHist->GetBinContent(ir, jr) - fCoord->GetZRange().first) / rRange * sc
743 : legoR;
744
745 fMesh[i][j].X() = r * TMath::Sin(phi) * TMath::Cos(theta);
746 fMesh[i][j].Y() = r * TMath::Sin(phi) * TMath::Sin(theta);
747 fMesh[i][j].Z() = r * TMath::Cos(phi);
748 }
749 }
750
751 if (Textured()) {
753 fMinMaxVal.second = fMinMaxVal.first;
754
755 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
756 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
757 const Double_t val = fHist->GetBinContent(i, j);
758 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
759 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
760 }
761 }
762
764 }
765
766
767 SetNormals();
768
769 return kTRUE;
770}
771
772////////////////////////////////////////////////////////////////////////////////
773/// Draw projections.
774
776{
777 const TGLDisableGuard lightGuard(GL_LIGHTING);
778 const TGLEnableGuard blendGuard(GL_BLEND);
779 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
780 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
781 glDepthMask(GL_FALSE);
782 glLineWidth(3.f);
783
784 typedef std::list<Projection_t>::const_iterator CLI_t;
785 for (CLI_t begin = fXOZProj.begin(), end = fXOZProj.end(); begin != end; ++begin) {
786 const Projection_t &proj = *begin;
787 glColor4ub(proj.fRGBA[0], proj.fRGBA[1], proj.fRGBA[2], proj.fRGBA[3]);
788
789 for(UInt_t i = 0, e = proj.fVertices.size() / 3; i < e; ++i) {
790 glBegin(GL_LINE_STRIP);
791 glVertex3dv(proj.fVertices[i * 3].CArr());
792 glVertex3dv(proj.fVertices[i * 3 + 1].CArr());
793 glVertex3dv(proj.fVertices[i * 3 + 2].CArr());
794 glEnd();
795 }
796 const Double_t y = fBackBox.GetFrontPoint() == 2 || fBackBox.GetFrontPoint() == 3 ? fBackBox.Get3DBox()[0].Y() : fBackBox.Get3DBox()[2].Y();
797 for(UInt_t i = 0, e = proj.fVertices.size() / 3; i < e; ++i) {
798 glBegin(GL_LINE_STRIP);
799 const TGLVertex3 &v1 = proj.fVertices[i * 3];
800 glVertex3d(v1.X(), y, v1.Z());
801 const TGLVertex3 &v2 = proj.fVertices[i * 3 + 1];
802 glVertex3d(v2.X(), y, v2.Z());
803 const TGLVertex3 &v3 = proj.fVertices[i * 3 + 2];
804 glVertex3d(v3.X(), y, v3.Z());
805 glEnd();
806 }
807 }
808
809 for (CLI_t begin = fYOZProj.begin(), end = fYOZProj.end(); begin != end; ++begin) {
810 const Projection_t &proj = *begin;
811 glColor4ub(proj.fRGBA[0], proj.fRGBA[1], proj.fRGBA[2], proj.fRGBA[3]);
812
813 for(UInt_t i = 0, e = proj.fVertices.size() / 3; i < e; ++i) {
814 glBegin(GL_LINE_STRIP);
815 glVertex3dv(proj.fVertices[i * 3].CArr());
816 glVertex3dv(proj.fVertices[i * 3 + 1].CArr());
817 glVertex3dv(proj.fVertices[i * 3 + 2].CArr());
818 glEnd();
819 }
820
821 const Double_t x = fBackBox.GetFrontPoint() == 2 || fBackBox.GetFrontPoint() == 1 ? fBackBox.Get3DBox()[0].X() : fBackBox.Get3DBox()[2].X();
822 for(UInt_t i = 0, e = proj.fVertices.size() / 3; i < e; ++i) {
823 glBegin(GL_LINE_STRIP);
824 const TGLVertex3 &v1 = proj.fVertices[i * 3];
825 glVertex3d(x, v1.Y(), v1.Z());
826 const TGLVertex3 &v2 = proj.fVertices[i * 3 + 1];
827 glVertex3d(x, v2.Y(), v2.Z());
828 const TGLVertex3 &v3 = proj.fVertices[i * 3 + 2];
829 glVertex3d(x, v3.Y(), v3.Z());
830 glEnd();
831 }
832 }
833
834 for (CLI_t begin = fXOYProj.begin(), end = fXOYProj.end(); begin != end; ++begin) {
835 const Projection_t &proj = *begin;
836 glColor4ub(proj.fRGBA[0], proj.fRGBA[1], proj.fRGBA[2], proj.fRGBA[3]);
837
838 for(UInt_t i = 0, e = proj.fVertices.size() / 2; i < e; ++i) {
839 glBegin(GL_LINES);
840 glVertex3dv(proj.fVertices[i * 2].CArr());
841 glVertex3dv(proj.fVertices[i * 2 + 1].CArr());
842 glEnd();
843 }
844
845
846 for(UInt_t i = 0, e = proj.fVertices.size() / 2; i < e; ++i) {
847 glBegin(GL_LINES);
848 const TGLVertex3 &v1 = proj.fVertices[i * 2];
849 glVertex3d(v1.X(), v1.Y(), fBackBox.Get3DBox()[0].Z());
850 const TGLVertex3 &v2 = proj.fVertices[i * 2 + 1];
851 glVertex3d(v2.X(), v2.Y(), fBackBox.Get3DBox()[0].Z());
852 glEnd();
853 }
854
855 }
856
857 glDepthMask(GL_TRUE);
858 glLineWidth(1.f);
859}
860
861////////////////////////////////////////////////////////////////////////////////
862/// Draw section X.
863
865{
866 using namespace std;
867 //XOZ parallel section.
868 Int_t binY = -1;
869 for (Int_t j = 0, e = fCoord->GetNYBins() - 1; j < e; ++j) {
870 if (fMesh[0][j].Y() <= fXOZSectionPos && fXOZSectionPos <= fMesh[0][j + 1].Y()) {
871 binY = j;
872 break;
873 }
874 }
875
876 if (binY >= 0) {
877 //Draw 2d curve on the profile's plane.
878 const TGLPlane profilePlane(0., 1., 0., -fXOZSectionPos);
879
880 if (!fSectionPass) {
881 glColor3d(1., 0., 0.);
882 glLineWidth(3.f);
883
884 for (Int_t i = 0, e = fCoord->GetNXBins() - 1; i < e; ++i) {
885 glBegin(GL_LINE_STRIP);
886 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[i + 1][binY], fMesh[i + 1][binY + 1]), kFALSE).second.CArr());
887 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[i + 1][binY], fMesh[i][binY + 1]), kFALSE).second.CArr());
888 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[i][binY], fMesh[i][binY + 1]), kFALSE).second.CArr());
889 glEnd();
890 }
891 glLineWidth(1.f);
892 } else {
893 fProj.fVertices.clear();
894 for (Int_t i = 0, e = fCoord->GetNXBins() - 1; i < e; ++i) {
895 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[i + 1][binY], fMesh[i + 1][binY + 1]), kFALSE).second);
896 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[i + 1][binY], fMesh[i][binY + 1]), kFALSE).second);
897 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[i][binY], fMesh[i][binY + 1]), kFALSE).second);
898 }
899 if (fProj.fVertices.size()) {
900 fProj.fRGBA[0] = (UChar_t) (50 + fgRandom->Integer(206));
901 fProj.fRGBA[1] = (UChar_t) fgRandom->Integer(150);
902 fProj.fRGBA[2] = (UChar_t) fgRandom->Integer(150);
903 fProj.fRGBA[3] = 150;
904 static Projection_t dummy;
905 fXOZProj.push_back(dummy);
906 fXOZProj.back().Swap(fProj);
907 }
908 }
909 }
910}
911
912////////////////////////////////////////////////////////////////////////////////
913/// Draw section Y.
914
916{
917 using namespace std;
918 //YOZ parallel section.
919 Int_t binX = -1;
920 for (Int_t i = 0, e = fCoord->GetNXBins() - 1; i < e; ++i) {
921 if (fMesh[i][0].X() <= fYOZSectionPos && fYOZSectionPos <= fMesh[i + 1][0].X()) {
922 binX = i;
923 break;
924 }
925 }
926
927 if (binX >= 0) {
928 //Draw 2d curve on the profile's plane.
929 const TGLPlane profilePlane(1., 0., 0., -fYOZSectionPos);
930
931 if (!fSectionPass) {
932 glColor3d(1., 0., 0.);
933 glLineWidth(3.f);
934 for (Int_t j = 0, e = fCoord->GetNYBins() - 1; j < e; ++j) {
935 glBegin(GL_LINE_STRIP);
936 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[binX][j + 1], fMesh[binX + 1][j + 1]), kFALSE).second.CArr());
937 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[binX][j + 1], fMesh[binX + 1][j]), kFALSE).second.CArr());
938 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[binX][j], fMesh[binX + 1][j]), kFALSE).second.CArr());
939 glEnd();
940 }
941 glLineWidth(1.f);
942 } else {
943 fProj.fVertices.clear();
944 for (Int_t j = 0, e = fCoord->GetNYBins() - 1; j < e; ++j) {
945 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[binX][j + 1], fMesh[binX + 1][j + 1]), kFALSE).second);
946 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[binX][j + 1], fMesh[binX + 1][j]), kFALSE).second);
947 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[binX][j], fMesh[binX + 1][j]), kFALSE).second);
948 }
949 if (fProj.fVertices.size()) {
950 fProj.fRGBA[0] = (UChar_t) (50 + fgRandom->Integer(206));
951 fProj.fRGBA[1] = (UChar_t) fgRandom->Integer(150);
952 fProj.fRGBA[2] = (UChar_t) fgRandom->Integer(150);
953 fProj.fRGBA[3] = 150;
954 static Projection_t dummy;
955 fYOZProj.push_back(dummy);
956 fYOZProj.back().Swap(fProj);
957 }
958 }
959
960 }
961}
962
963////////////////////////////////////////////////////////////////////////////////
964/// Draw section Z.
965
967{
968 using namespace std;
969 //XOY parallel section.
970 const Int_t nX = fCoord->GetNXBins();
971 const Int_t nY = fCoord->GetNYBins();
972 const TGLPlane profilePlane(0., 0., 1., -fXOYSectionPos);
973 TGLVertex3 intersection[2];
974
975
976 if (fSectionPass)
977 fProj.fVertices.clear();
978 else {
979 glColor3d(1., 0., 0.);
980 glLineWidth(3.f);
981 }
982
983 for (Int_t i = 0; i < nX - 1; ++i) {
984 for (Int_t j = 0; j < nY - 1; ++j) {
985 const TGLVertex3 &v1 = fMesh[i + 1][j], &v2 = fMesh[i][j], &v3 = fMesh[i][j + 1], &v4 = fMesh[i + 1][j + 1];
986 Double_t zMin = TMath::Min(TMath::Min(v1.Z(), v2.Z()), v3.Z());
987 Double_t zMax = TMath::Max(TMath::Max(v1.Z(), v2.Z()), v3.Z());
988
989 if (zMin < fXOYSectionPos && zMax > fXOYSectionPos) {
990 Int_t np = 0;
991 if ((v1.Z() > fXOYSectionPos && v2.Z() < fXOYSectionPos) || (v2.Z() > fXOYSectionPos && v1.Z() < fXOYSectionPos)) {
992 TGLLine3 line(v1, v2);
993 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
994 }
995 if ((v2.Z() > fXOYSectionPos && v3.Z() < fXOYSectionPos) || (v3.Z() > fXOYSectionPos && v2.Z() < fXOYSectionPos)) {
996 TGLLine3 line(v2, v3);
997 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
998 }
999 if ((np < 2 && v1.Z() > fXOYSectionPos && v3.Z() < fXOYSectionPos) || (v3.Z() > fXOYSectionPos && v1.Z() < fXOYSectionPos)) {
1000 TGLLine3 line(v1, v3);
1001 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
1002 }
1003 if (np > 1) {
1004 if (!fSectionPass) {
1005 glBegin(GL_LINES);
1006 glVertex3dv(intersection[0].CArr());
1007 glVertex3dv(intersection[1].CArr());
1008 glEnd();
1009 } else {
1010 fProj.fVertices.push_back(intersection[0]);
1011 fProj.fVertices.push_back(intersection[1]);
1012 }
1013 }
1014 }
1015 zMin = TMath::Min(v4.Z(), zMin);
1016 zMax = TMath::Max(v4.Z(), zMax);
1017 if (zMin < fXOYSectionPos && zMax > fXOYSectionPos) {
1018 Int_t np = 0;
1019 if ((v3.Z() > fXOYSectionPos && v4.Z() < fXOYSectionPos) || (v4.Z() > fXOYSectionPos && v3.Z() < fXOYSectionPos)) {
1020 TGLLine3 line(v3, v4);
1021 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
1022 }
1023 if ((v4.Z() > fXOYSectionPos && v1.Z() < fXOYSectionPos) || (v1.Z() > fXOYSectionPos && v4.Z() < fXOYSectionPos)) {
1024 TGLLine3 line(v4, v1);
1025 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
1026 }
1027 if ((np < 2 && v3.Z() > fXOYSectionPos && v1.Z() < fXOYSectionPos) || (v1.Z() > fXOYSectionPos && v3.Z() < fXOYSectionPos)) {
1028 TGLLine3 line(v3, v1);
1029 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
1030 }
1031 if (np > 1) {
1032 if (!fSectionPass) {
1033 glBegin(GL_LINES);
1034 glVertex3dv(intersection[0].CArr());
1035 glVertex3dv(intersection[1].CArr());
1036 glEnd();
1037 } else {
1038 fProj.fVertices.push_back(intersection[0]);
1039 fProj.fVertices.push_back(intersection[1]);
1040 }
1041 }
1042 }
1043 }
1044 }
1045
1046 if (fSectionPass && fProj.fVertices.size()) {
1047 fProj.fRGBA[0] = (UChar_t) fgRandom->Integer(150);
1048 fProj.fRGBA[1] = (UChar_t) fgRandom->Integer(150);
1049 fProj.fRGBA[2] = (UChar_t) (50 + fgRandom->Integer(206));
1050 fProj.fRGBA[3] = 150;
1051 static Projection_t dummy;
1052 fXOYProj.push_back(dummy);
1053 fXOYProj.back().Swap(fProj);
1054 }
1055
1056 if (!fSectionPass)
1057 glLineWidth(1.f);
1058}
1059
1060////////////////////////////////////////////////////////////////////////////////
1061///Clamp z value.
1062
1064{
1065 const TGLVertex3 *frame = fBackBox.Get3DBox();
1066
1067 if (fCoord->GetZLog())
1068 if (zVal <= 0.)
1069 zVal = frame[0].Z();
1070 else
1071 zVal = TMath::Log10(zVal) * fCoord->GetZScale();
1072 else
1073 zVal *= fCoord->GetZScale();
1074
1075 if (zVal > frame[4].Z())
1076 zVal = frame[4].Z();
1077 else if (zVal < frame[0].Z())
1078 zVal = frame[0].Z();
1079}
1080
1081////////////////////////////////////////////////////////////////////////////////
1082///Find 3d coords using mouse cursor coords.
1083
1085{
1086 py = fCamera->GetHeight() - py;
1087
1088 const Int_t nY = fCoord->GetNYBins() - 1;
1089 Int_t selected = fSelectedPart - (fSelectionBase - 1);
1090 Int_t k = selected / 2;
1091 Int_t i = k / nY;
1092 Int_t j = k % nY;
1093
1094 const Bool_t odd = selected & 1;
1095 const TGLVertex3 &v1 = odd ? fMesh[i][j + 1] : fMesh[i + 1][j];
1096 const TGLVertex3 &v2 = odd ? fMesh[i + 1][j + 1] : fMesh[i][j];
1097 const TGLVertex3 &v3 = odd ? fMesh[i + 1][j] : fMesh[i][j + 1];
1098
1099 TGLVertex3 winV1, winV2, winV3;
1100
1101 Double_t mvMatrix[16] = {0.};
1102 glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix);
1103 Double_t prMatrix[16] = {0.};
1104 glGetDoublev(GL_PROJECTION_MATRIX, prMatrix);
1105 Int_t viewport[4] = {0};
1106 glGetIntegerv(GL_VIEWPORT, viewport);
1107
1108 gluProject(v1.X(), v1.Y(), v1.Z(), mvMatrix, prMatrix, viewport, &winV1.X(), &winV1.Y(), &winV1.Z());
1109 gluProject(v2.X(), v2.Y(), v2.Z(), mvMatrix, prMatrix, viewport, &winV2.X(), &winV2.Y(), &winV2.Z());
1110 gluProject(v3.X(), v3.Y(), v3.Z(), mvMatrix, prMatrix, viewport, &winV3.X(), &winV3.Y(), &winV3.Z());
1111
1112 Double_t planeABCD[4] = {0.};
1113 TMath::Normal2Plane(winV1.CArr(), winV2.CArr(), winV3.CArr(), planeABCD);
1114 planeABCD[3] = - winV1.X() * planeABCD[0] - winV1.Y() * planeABCD[1] - winV1.Z() * planeABCD[2];
1115 Double_t pz = (-planeABCD[3] - planeABCD[0] * px - planeABCD[1] * py) / planeABCD[2];
1116 Double_t rez[3] = {0.};
1117
1118 gluUnProject(px, py, pz, mvMatrix, prMatrix, viewport, rez, rez + 1, rez + 2);
1119
1120 fObjectInfo.Form("(x == %f, y == %f, z == %f)",
1121 rez[0] / fCoord->GetXScale(),
1122 rez[1] / fCoord->GetYScale(),
1123 rez[2] / fCoord->GetZScale());
1124
1125 return (char *)fObjectInfo.Data();
1126}
1127
1128////////////////////////////////////////////////////////////////////////////////
1129///Generate palette.
1130
1132{
1133 if (!fUpdateTexMap)
1134 return kTRUE;
1135
1136 if(fMinMaxVal.first == fMinMaxVal.second)
1137 return kFALSE;//must be std::abs(fMinMaxVal.second - fMinMaxVal.first) < ...
1138
1139 //User-defined contours are disabled. To be fixed.
1142
1143 UInt_t paletteSize = gStyle->GetNumberContours();
1144 if (!paletteSize)
1145 paletteSize = 20;
1146
1147 Bool_t rez = fPalette.GeneratePalette(paletteSize, fMinMaxVal);
1148
1149 if (rez && fUpdateTexMap) {
1150 GenTexMap();
1152 }
1153
1154 return rez;
1155}
1156
1157////////////////////////////////////////////////////////////////////////////////
1158///Find texture coordinates.
1159
1161{
1162 const Int_t nX = fCoord->GetNXBins();
1163 const Int_t nY = fCoord->GetNYBins();
1164
1165 fTexMap.resize(nX * nY);
1166 fTexMap.SetRowLen(nY);
1167
1168 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
1169 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
1170 Double_t z = fHist->GetBinContent(ir, jr);
1172 ClampZ(z);
1173 fTexMap[i][j] = fPalette.GetTexCoord(z);
1174 }
1175 }
1176}
1177
1178////////////////////////////////////////////////////////////////////////////////
1179///Draw flat textured surface.
1180
1182{
1183 static const Float_t whiteDiffuse[] = {0.8f, 0.8f, 0.8f, 0.65f};
1184 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, whiteDiffuse);
1185 for (Int_t i = 0, ei = fCoord->GetNXBins() - 1; i < ei; ++i) {
1186 for (Int_t j = 0, ej = fCoord->GetNYBins() - 1; j < ej; ++j) {
1187 Rgl::DrawFaceTextured(fMesh[i][j + 1], fMesh[i][j], fMesh[i + 1][j],
1188 fTexMap[i][j + 1], fTexMap[i][j], fTexMap[i + 1][j],
1189 fBackBox.Get3DBox()[4].Z(), TGLVector3(0., 0., 1.));
1190 Rgl::DrawFaceTextured(fMesh[i + 1][j], fMesh[i + 1][j + 1], fMesh[i][j + 1],
1191 fTexMap[i + 1][j], fTexMap[i + 1][j + 1], fTexMap[i][j + 1],
1192 fBackBox.Get3DBox()[4].Z(), TGLVector3(0., 0., 1.));
1193 }
1194 }
1195}
1196
1197////////////////////////////////////////////////////////////////////////////////
1198///Checks, if surf requires texture.
1199
1201{
1202 switch (fType) {
1203 case kSurf1:
1204 case kSurf2:
1205 case kSurf3:
1206 case kSurf5:
1207 return kTRUE;
1208 default:;
1209 }
1210
1211 return kFALSE;
1212}
1213
1214////////////////////////////////////////////////////////////////////////////////
1215///Any section exists.
1216
1218{
1219 return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos > fBackBox.Get3DBox()[0].X() ||
1221}
1222
1223////////////////////////////////////////////////////////////////////////////////
1224///Any projection exists.
1225
1227{
1228 return fXOZProj.size() || fYOZProj.size() || fXOYProj.size();
1229}
1230
1231////////////////////////////////////////////////////////////////////////////////
1232///Draw. Palette.
1233///Originally, fCamera was never null.
1234///It can be a null now because of gl-viewer.
1235
1237{
1238 if (!fCamera) {
1239 //Thank you, gl-viewer!
1240 return;
1241 }
1242
1244
1245 glFinish();
1246
1247 fCamera->SetCamera();
1249}
1250
1251////////////////////////////////////////////////////////////////////////////////
1252///Draw. Palette. Axis.
1253
1255{
1256 gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
1258}
@ kKeyPress
Definition: Buttons.h:20
@ kButton1Double
Definition: Buttons.h:24
#define GL_TRUE
Definition: GL_glu.h:262
#define GL_LINE_STRIP
Definition: GL_glu.h:286
#define GL_LINES
Definition: GL_glu.h:284
#define GL_FALSE
Definition: GL_glu.h:261
@ kKey_P
Definition: KeySymbols.h:141
@ kKey_C
Definition: KeySymbols.h:128
@ kKey_p
Definition: KeySymbols.h:173
@ kKey_c
Definition: KeySymbols.h:160
ROOT::R::TRInterface & r
Definition: Object.C:4
#define c(i)
Definition: RSha256.hxx:101
#define e(i)
Definition: RSha256.hxx:103
const Ssiz_t kNPOS
Definition: RtypesCore.h:124
int Int_t
Definition: RtypesCore.h:45
unsigned char UChar_t
Definition: RtypesCore.h:38
int Ssiz_t
Definition: RtypesCore.h:67
unsigned int UInt_t
Definition: RtypesCore.h:46
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
double Double_t
Definition: RtypesCore.h:59
float Float_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
@ kWhite
Definition: Rtypes.h:65
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition: TError.cxx:220
std::pair< Bool_t, TGLLine3 > Intersection(const TGLPlane &p1, const TGLPlane &p2)
Find 3D line interestion of this plane with 'other'.
Definition: TGLUtil.cxx:516
@ kGLSpherical
Definition: TGLUtil.h:47
@ kGLCylindrical
Definition: TGLUtil.h:46
@ kGLPolar
Definition: TGLUtil.h:45
@ kGLCartesian
Definition: TGLUtil.h:44
#define gROOT
Definition: TROOT.h:404
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:412
#define gVirtualX
Definition: TVirtualX.h:338
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:478
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:518
Int_t GetNbins() const
Definition: TAxis.h:121
The color creation and management class.
Definition: TColor.h:19
void MoveBox(Int_t px, Int_t py, Int_t axisID)
Move box cut along selected direction.
Bool_t IsInCut(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax) const
Check, if box defined by xmin/xmax etc. is in cut.
void DrawBox(Bool_t selectionPass, Int_t selected) const
Draw cut as a semi-transparent box.
void TurnOnOff()
Turn the box cut on/off.
void StartMovement(Int_t px, Int_t py)
Start cut's movement.
Bool_t IsActive() const
void DisableTexture() const
Disable 1D texture.
Definition: TGLUtil.cxx:4245
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition: TGLUtil.cxx:4262
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition: TGLUtil.cxx:4161
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition: TGLUtil.cxx:4226
3D space, fixed length, line class, with direction / length 'vector', passing through point 'vertex'.
Definition: TGLUtil.h:387
3D plane class - of format Ax + By + Cz + D = 0
Definition: TGLUtil.h:525
void SetPlotBox(const Rgl::Range_t &xRange, const Rgl::Range_t &yRange, const Rgl::Range_t &zRange)
Set up a frame box.
Definition: TGLPlotBox.cxx:198
const TGLVertex3 * Get3DBox() const
Get 3D box.
Definition: TGLPlotBox.cxx:303
void DrawBox(Int_t selectedPart, Bool_t selectionPass, const std::vector< Double_t > &zLevels, Bool_t highColor) const
Draw back box for a plot.
Definition: TGLPlotBox.cxx:184
Int_t GetFrontPoint() const
The nearest point.
Definition: TGLPlotBox.cxx:294
Camera for TGLPlotPainter and sub-classes.
Definition: TGLPlotCamera.h:22
void StartPan(Int_t px, Int_t py)
User clicks somewhere (px, py).
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
void SetCamera() const
Viewport and projection.
void Pan(Int_t px, Int_t py)
Pan camera.
Int_t GetHeight() const
viewport[3]
void SetViewVolume(const TGLVertex3 *box)
'box' is the TGLPlotPainter's back box's coordinates.
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
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 SetCoordType(EGLCoordType type)
If coord type was changed, plot must reset sections (if any), set fModified.
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.
Int_t GetLastYBin() const
Int_t GetNYBins() const
Number of Y bins.
Int_t GetLastXBin() const
EGLCoordType GetCoordType() const
Get coordinates type.
Base class for plot-painters that provide GL rendering of various 2D and 3D histograms,...
void DrawSections() const
Draw sections (if any).
Double_t fPadTheta
std::vector< Double_t > fZLevels
Double_t fXOYSectionPos
void RestoreModelviewMatrix() const
Double_t fXOZSectionPos
TGLBoxCut fBoxCut
virtual void Paint()
Draw lego/surf/whatever you can.
TGLPlotCoordinates * fCoord
TGLPlotBox fBackBox
void SaveProjectionMatrix() const
void SaveModelviewMatrix() const
void MoveSection(Int_t px, Int_t py)
Create dynamic profile using selected plane.
Bool_t fUpdateSelection
TGLPlotCamera * fCamera
void RestoreProjectionMatrix() const
Double_t fYOZSectionPos
Implements painting of TH2 with "SURF" option.
char * WindowPointTo3DPoint(Int_t px, Int_t py) const
Find 3d coords using mouse cursor coords.
void DrawPlot() const
Draw surf/surf1/surf2/surf4.
TGLLevelPalette fPalette
TGL2DArray< Double_t > fTexMap
Bool_t InitGeometryPolar()
Find bin ranges for X and Y axes, axes ranges for X, Y and Z.
void DrawSectionXOY() const
Draw section Z.
void DeInitGL() const
Initialize some OpenGL state variables.
void DrawProjections() const
Draw projections.
Bool_t HasProjections() const
Any projection exists.
Bool_t Textured() const
Checks, if surf requires texture.
std::list< Projection_t > fXOYProj
Bool_t InitGeometry()
Set mesh, normals.
void DrawPalette() const
Draw.
TGL2DArray< TGLVector3 > fAverageNormals
void StartPan(Int_t px, Int_t py)
User clicks right mouse button (in a pad).
void SetSurfaceColor() const
Set color for surface.
char * GetPlotInfo(Int_t px, Int_t py)
Coords for point on surface under cursor.
TGL2DArray< std::pair< TGLVector3, TGLVector3 > > fFaceNormals
void DrawContoursProjection() const
Draw flat textured surface.
void InitGL() const
Initialize some OpenGL state variables.
std::list< Projection_t > fXOZProj
void ProcessEvent(Int_t event, Int_t px, Int_t py)
Remove all profiles/sections.
void DrawSectionYOZ() const
Draw section Y.
Bool_t InitGeometrySpherical()
Find bin ranges for X and Y axes, axes ranges for X, Y and Z.
void AddOption(const TString &stringOption)
Additional options for surfaces.
TGLSurfacePainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
Constructor.
void ClampZ(Double_t &zVal) const
Clamp z value.
TGL2DArray< TGLVertex3 > fMesh
Bool_t InitGeometryCartesian()
Find bin ranges for X and Y axes, axes ranges for X, Y and Z.
Bool_t PreparePalette() const
Generate palette.
void Pan(Int_t px, Int_t py)
User's moving mouse cursor, with middle mouse button pressed (for pad).
static TRandom * fgRandom
void GenTexMap() const
Find texture coordinates.
void DrawSectionXOZ() const
Draw section X.
void SetNormals()
One normal per vertex; this normal is average of neighbouring triangles normals.
Bool_t InitGeometryCylindrical()
Find bin ranges for X and Y axes, axes ranges for X, Y and Z.
std::list< Projection_t > fYOZProj
void DrawPaletteAxis() const
Draw. Palette. Axis.
Bool_t HasSections() const
Any section exists.
Rgl::Range_t fMinMaxVal
3 component (x/y/z) vector class.
Definition: TGLUtil.h:248
void Normalise()
Definition: TGLUtil.h:304
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
const Double_t * CArr() const
Definition: TGLUtil.h:126
TH1 is the base class of all histogram classes in ROOT.
Definition: TH1.h:58
@ kUserContour
User specified contour levels.
Definition: TH1.h:165
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4994
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
void ResetBit(UInt_t f)
Definition: TObject.h:186
SCoord_t fY
Definition: TPoint.h:36
SCoord_t fX
Definition: TPoint.h:35
This is the base class for the ROOT Random number generators.
Definition: TRandom.h:27
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition: TRandom.cxx:360
Basic string class.
Definition: TString.h:136
Ssiz_t Length() const
Definition: TString.h:410
const char * Data() const
Definition: TString.h:369
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2314
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:639
Float_t GetLegoInnerR() const
Definition: TStyle.h:231
Int_t GetNumberContours() const
Definition: TStyle.h:232
TLine * line
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
void DrawFaceTextured(const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, Double_t t1, Double_t t2, Double_t t3, const TGLVector3 &norm1, const TGLVector3 &norm2, const TGLVector3 &norm3)
Draw textured triangle.
Definition: TGLUtil.cxx:3836
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2891
void SetZLevels(TAxis *zAxis, Double_t zMin, Double_t zMax, Double_t zScale, std::vector< Double_t > &zLevels)
Definition: TGLUtil.cxx:3820
void DrawPalette(const TGLPlotCamera *camera, const TGLLevelPalette &palette)
Draw. Palette.
void DrawPaletteAxis(const TGLPlotCamera *camera, const Range_t &minMax, Bool_t logZ)
void DrawQuadOutline(const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVertex3 &v4)
Draw quad outline.
Definition: TGLUtil.cxx:2939
void DrawSmoothFace(const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVector3 &norm1, const TGLVector3 &norm2, const TGLVector3 &norm3)
Draws triangle face, each vertex has its own averaged normal.
Definition: TGLUtil.cxx:2983
static constexpr double second
null_t< F > null()
T * Normal2Plane(const T v1[3], const T v2[3], const T v3[3], T normal[3])
Calculate a normal vector of a plane.
Definition: TMath.h:1189
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:208
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:176
Double_t Cos(Double_t)
Definition: TMath.h:643
constexpr Double_t Pi()
Definition: TMath.h:37
Double_t Sin(Double_t)
Definition: TMath.h:639
Double_t Log10(Double_t x)
Definition: TMath.h:764
constexpr Double_t TwoPi()
Definition: TMath.h:44
Definition: first.py:1
void Swap(Projection_t &rhs)
Constructor.
std::vector< TGLVertex3 > fVertices
REAL * vertex
Definition: triangle.c:513