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