Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 const Ssiz_t surfPos = option.Index("surf");//"surf" _already_ _exists_ in a string.
159 if (surfPos + 4 < option.Length() && isdigit(option[surfPos + 4])) {
160 switch (option[surfPos + 4] - '0') {
161 case 1:
162 fType = kSurf1;
163 break;
164 case 2:
165 fType = kSurf2;
166 break;
167 case 3:
168 fType = kSurf3;
170 break;
171 case 4:
172 fType = kSurf4;
173 break;
174 case 5:
176 fType = kSurf3;
177 else
178 fType = kSurf5;
179 break;
180 default:
181 fType = kSurf;
182 }
183 } else
184 fType = kSurf;
185
186 option.Index("z") == kNPOS ? fDrawPalette = kFALSE : fDrawPalette = kTRUE;
187}
188
189////////////////////////////////////////////////////////////////////////////////
190///Remove all profiles/sections.
191
193{
194 const TGLVertex3 *frame = fBackBox.Get3DBox();
195 if (py == kKey_P || py == kKey_p) {
196
197 if (HasSections()) {
202 fXOZSectionPos = frame[0].Y();
203 fYOZSectionPos = frame[0].X();
204 fXOYSectionPos = frame[0].Z();
206 }
207 } else if (event == kButton1Double && (HasSections() || HasProjections() || fBoxCut.IsActive())) {
208 fXOZSectionPos = frame[0].Y();
209 fYOZSectionPos = frame[0].X();
210 fXOYSectionPos = frame[0].Z();
211 fXOZProj.clear();
212 fYOZProj.clear();
213 fXOYProj.clear();
214 if (fBoxCut.IsActive())
216 if (!gVirtualX->IsCmdThread())
217 gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%zx)->Paint()", (size_t)this));
218 else
219 Paint();
220 } else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
221 if (fHighColor)
222 Info("ProcessEvent", "Switch to true color to use box cut");
223 else {
226 }
227 }
228}
229
230////////////////////////////////////////////////////////////////////////////////
231///Initialize some OpenGL state variables.
232
234{
235 glEnable(GL_LIGHTING);
236 glEnable(GL_LIGHT0);
237 glEnable(GL_DEPTH_TEST);
238 glDisable(GL_CULL_FACE);
239 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
240}
241
242////////////////////////////////////////////////////////////////////////////////
243///Initialize some OpenGL state variables.
244
246{
247 glDisable(GL_LIGHTING);
248 glDisable(GL_LIGHT0);
249 glDisable(GL_DEPTH_TEST);
250 glDisable(GL_CULL_FACE);
251 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
252}
253
254
255////////////////////////////////////////////////////////////////////////////////
256///One normal per vertex;
257///this normal is average of
258///neighbouring triangles normals.
259
261{
262 const Int_t nX = fCoord->GetNXBins();
263 const Int_t nY = fCoord->GetNYBins();
264
265 fFaceNormals.resize((nX + 1) * (nY + 1));
266 fFaceNormals.assign(fFaceNormals.size(), std::pair<TGLVector3, TGLVector3>());
267 fFaceNormals.SetRowLen(nY + 1);
268
269
270 //first, calculate normal for each triangle face
271 for (Int_t i = 0; i < nX - 1; ++i) {
272 for (Int_t j = 0; j < nY - 1; ++j) {
273 //first "bottom-left" triangle
274 TMath::Normal2Plane(fMesh[i][j + 1].CArr(), fMesh[i][j].CArr(), fMesh[i + 1][j].CArr(),
275 fFaceNormals[i + 1][j + 1].first.Arr());
276 //second "top-right" triangle
277 TMath::Normal2Plane(fMesh[i + 1][j].CArr(), fMesh[i + 1][j + 1].CArr(), fMesh[i][j + 1].CArr(),
278 fFaceNormals[i + 1][j + 1].second.Arr());
279 }
280 }
281
282 fAverageNormals.resize(nX * nY);
284
286 //second, calculate average normal for each vertex
287 for (Int_t i = 0; i < nX; ++i) {
288 for (Int_t j = 0; j < nY; ++j) {
289 TGLVector3 &norm = fAverageNormals[i][j];
290
291 norm += fFaceNormals[i][j].second;
292 norm += fFaceNormals[i][j + 1].first;
293 norm += fFaceNormals[i][j + 1].second;
294 norm += fFaceNormals[i + 1][j].first;
295 norm += fFaceNormals[i + 1][j].second;
296 norm += fFaceNormals[i + 1][j + 1].first;
297
298 if (!norm.X() && !norm.Y() && !norm.Z())
299 continue;
300
301 norm.Normalise();
302 }
303 }
304}
305
306////////////////////////////////////////////////////////////////////////////////
307///Set color for surface.
308
310{
311 Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.35f};
312
313 if (fHist->GetFillColor() != kWhite && fType != kSurf1 && fType != kSurf2 && fType != kSurf5)
314 if (const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
315 c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
316
317 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
318 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
319 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
320 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
321}
322
323////////////////////////////////////////////////////////////////////////////////
324///Draw surf/surf1/surf2/surf4
325
327{
328 //Shift plot to point of origin.
329 const Rgl::PlotTranslation trGuard(this);
330
331 if (fCoord->GetCoordType() == kGLCartesian) {
333 DrawSections();
334 if (!fSelectionPass)
336 }
337
338 if (!fSelectionPass) {
340 glEnable(GL_POLYGON_OFFSET_FILL);
341 glPolygonOffset(1.f, 1.f);
342
343 if (HasSections() || HasProjections())
344 {
345 //Surface is semi-transparent during dynamic profiling
346 glEnable(GL_BLEND);
347 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
348 }
349
350 }
351
352 if (Textured() && !fSelectionPass) {
353 if (!PreparePalette()) {
354 fType = kSurf;
356 }
357 else if (fType != kSurf3)
358 fPalette.EnableTexture(GL_MODULATE);
359 }
360
361 const Int_t nX = fCoord->GetNXBins();
362 const Int_t nY = fCoord->GetNYBins();
363 const Int_t frontPoint = fBackBox.GetFrontPoint();
364 Int_t i = 0, firstJ = 0;
365 const Int_t addI = frontPoint == 2 || frontPoint == 1 ? i = 0, 1 : (i = nX - 2, -1);
366 const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? firstJ = 0, 1 : (firstJ = nY - 2, -1);
367
370
371 for (; addI > 0 ? i < nX - 1 : i >= 0; i += addI) {
372 for (Int_t j = firstJ; addJ > 0 ? j < nY - 1 : j >= 0; j += addJ) {
373 Int_t triNumber = 2 * i * (nY - 1) + j * 2 + fSelectionBase;
374
375 Double_t xMin = TMath::Min(TMath::Min(fMesh[i][j + 1].X(), fMesh[i][j].X()), fMesh[i + 1][j].X());
376 Double_t xMax = TMath::Max(TMath::Max(fMesh[i][j + 1].X(), fMesh[i][j].X()), fMesh[i + 1][j].X());
377 Double_t yMin = TMath::Min(TMath::Min(fMesh[i][j + 1].Y(), fMesh[i][j].Y()), fMesh[i + 1][j].Y());
378 Double_t yMax = TMath::Max(TMath::Max(fMesh[i][j + 1].Y(), fMesh[i][j].Y()), fMesh[i + 1][j].Y());
379 Double_t zMin = TMath::Min(TMath::Min(fMesh[i][j + 1].Z(), fMesh[i][j].Z()), fMesh[i + 1][j].Z());
380 Double_t zMax = TMath::Max(TMath::Max(fMesh[i][j + 1].Z(), fMesh[i][j].Z()), fMesh[i + 1][j].Z());
381
382 if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
383 continue;
384
386 Rgl::ObjectIDToColor(triNumber, kFALSE);
387
388 if ((fType == kSurf1 || fType == kSurf2 || fType == kSurf5) && !fSelectionPass)
389 Rgl::DrawFaceTextured(fMesh[i][j + 1], fMesh[i][j], fMesh[i + 1][j],
390 fTexMap[i][j + 1], fTexMap[i][j], fTexMap[i + 1][j],
391 fAverageNormals[i][j + 1], fAverageNormals[i][j],
392 fAverageNormals[i + 1][j]);
393 else
394 Rgl::DrawSmoothFace(fMesh[i][j + 1], fMesh[i][j], fMesh[i + 1][j],
395 fAverageNormals[i][j + 1], fAverageNormals[i][j],
396 fAverageNormals[i + 1][j]);
397
398 ++triNumber;
399
401 Rgl::ObjectIDToColor(triNumber, kFALSE);
402
403 if ((fType == kSurf1 || fType == kSurf2 || fType == kSurf5) && !fSelectionPass)
404 Rgl::DrawFaceTextured(fMesh[i + 1][j], fMesh[i + 1][j + 1], fMesh[i][j + 1],
405 fTexMap[i + 1][j], fTexMap[i + 1][j + 1], fTexMap[i][j + 1],
406 fAverageNormals[i + 1][j], fAverageNormals[i + 1][j + 1],
407 fAverageNormals[i][j + 1]);
408 else
409 Rgl::DrawSmoothFace(fMesh[i + 1][j], fMesh[i + 1][j + 1], fMesh[i][j + 1],
410 fAverageNormals[i + 1][j], fAverageNormals[i + 1][j + 1],
411 fAverageNormals[i][j + 1]);
412 }
413 }
414
415 if (!fSelectionPass)
416 glDisable(GL_POLYGON_OFFSET_FILL);
417
418 if (fBoxCut.IsActive())
420
421 if (fType != kSurf3 && Textured() && !fSelectionPass)
423
424 //Draw outlines here
425 if (!fSelectionPass) {
426 const TGLEnableGuard blendGuard(GL_BLEND);
427
428 if (fType == kSurf || fType == kSurf1 || fType == kSurf3) {
429 const TGLDisableGuard lightGuard(GL_LIGHTING);
430 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
431
432 glDepthMask(GL_FALSE);
433
434 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
435 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
436
437 glColor4d(0., 0., 0., 0.5);
438
439 for (i = 0; i < nX - 1; ++i) {
440 for (Int_t j = 0; j < nY - 1; ++j) {
441 Rgl::DrawQuadOutline(fMesh[i][j + 1], fMesh[i][j], fMesh[i + 1][j], fMesh[i + 1][j + 1]);
442 }
443 }
444
445 glDepthMask(GL_TRUE);
446 }
447 }
448
449 if (fType == kSurf3 && !fSelectionPass) {
450 fPalette.EnableTexture(GL_MODULATE);
451 const TGLEnableGuard blend(GL_BLEND);
452 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
455 }
456
457 if (!fSelectionPass && fSelectedPart > 6) {
458 //Draw red outline for surface.
459 const TGLDisableGuard lightGuard(GL_LIGHTING);
460 const TGLEnableGuard blendGuard(GL_BLEND);
461 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
462 const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
463 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
464 glLineWidth(3.f);
465
466 glColor4d(1.f, 0.f, 0.4f, 0.6f);
467 glBegin(GL_LINE_STRIP);
468 for (i = 0; i < nX; ++i)
469 glVertex3dv(fMesh[i][0].CArr());
470 for (Int_t j = 0; j < nY; ++j)
471 glVertex3dv(fMesh[nX - 1][j].CArr());
472 for (i = nX - 1; i >= 0; --i)
473 glVertex3dv(fMesh[i][nY - 1].CArr());
474 for (Int_t j = nY - 1; j >= 0; --j)
475 glVertex3dv(fMesh[0][j].CArr());
476 glEnd();
477 glLineWidth(1.f);
478 }
479
481 DrawPalette();
482}
483
484////////////////////////////////////////////////////////////////////////////////
485///Find bin ranges for X and Y axes,
486///axes ranges for X, Y and Z.
487///Function returns false, if logarithmic scale for
488///some axis was requested, but we cannot
489///find correct range.
490
492{
493 if (!fCoord->SetRanges(fHist, kFALSE, kFALSE)) //the second arg must be drawErrors, the third is always kFALSE.
494 return kFALSE;
495
497 //Set surface's mesh
498 //Calculates table of X and Y for lego (Z is obtained during drawing) or
499 //calculate mesh of triangles with vertices in the centres of bins
500 const Int_t nX = fCoord->GetNXBins();
501 const Int_t nY = fCoord->GetNYBins();
502
503 fMesh.resize(nX * nY);
504 fMesh.SetRowLen(nY);
505
506 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
507 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
509 : fMesh[i][j].X() = fXAxis->GetBinCenter(ir) * fCoord->GetXScale();
511 : fMesh[i][j].Y() = fYAxis->GetBinCenter(jr) * fCoord->GetYScale();
512
513 Double_t z = fHist->GetBinContent(ir, jr);
514 ClampZ(z);
515 fMesh[i][j].Z() = z;
516 }
517 }
518
519 if (Textured()) {
521 fMinMaxVal.second = fMinMaxVal.first;
522
523 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
524 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
525 const Double_t val = fHist->GetBinContent(i, j);
526 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
527 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
528 }
529 }
530
531 ClampZ(fMinMaxVal.first);
532 ClampZ(fMinMaxVal.second);
533
535 }
536
537 SetNormals();
538
539 if (fCoord->Modified()) {
541 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
542 fXOZSectionPos = vertex.Y();
543 fYOZSectionPos = vertex.X();
544 fXOYSectionPos = vertex.Z();
547 }
548
549 return kTRUE;
550}
551
552////////////////////////////////////////////////////////////////////////////////
553///Find bin ranges for X and Y axes,
554///axes ranges for X, Y and Z.
555///Function returns false, if logarithmic scale for
556///some axis was requested, but we cannot
557///find correct range.
558
560{
562 return kFALSE;
563
565
566 if (fCoord->Modified()) {
568 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
569 fXOZSectionPos = vertex.Y();
570 fYOZSectionPos = vertex.X();
571 fXOYSectionPos = vertex.Z();
573 }
574
575 const Int_t nY = fCoord->GetNYBins();
576 const Int_t nX = fCoord->GetNXBins();
577
578 fMesh.resize(nX * nY);
579 fMesh.SetRowLen(nY);
580
581 const Double_t fullAngle = fXAxis->GetBinCenter(fXAxis->GetNbins()) - fXAxis->GetBinCenter(1);
582 const Double_t phiLow = fXAxis->GetBinCenter(1);
584
585 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
586 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
587 const Double_t angle = (fXAxis->GetBinCenter(ir) - phiLow) / fullAngle * TMath::TwoPi();
588 const Double_t radius = ((fYAxis->GetBinCenter(jr)) - fYAxis->GetBinCenter(1)) /
589 rRange * fCoord->GetYScale();
590 fMesh[i][j].X() = radius * TMath::Cos(angle);
591 fMesh[i][j].Y() = radius * TMath::Sin(angle);
592 Double_t z = fHist->GetBinContent(ir, jr);
593 ClampZ(z);
594 fMesh[i][j].Z() = z;
595 }
596 }
597
598 SetNormals();
599
600 if (Textured()) {
602 fMinMaxVal.second = fMinMaxVal.first;
603
604 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
605 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
606 const Double_t val = fHist->GetBinContent(i, j);
607 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
608 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
609 }
610 }
611
613 }
614
615
616 return kTRUE;
617}
618
619////////////////////////////////////////////////////////////////////////////////
620///Find bin ranges for X and Y axes,
621///axes ranges for X, Y and Z.
622///Function returns false, if logarithmic scale for
623///some axis was requested, but we cannot
624///find correct range.
625
627{
629 return kFALSE;
630
632
633 if (fCoord->Modified()) {
635 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
636 fXOZSectionPos = vertex.Y();
637 fYOZSectionPos = vertex.X();
638 fXOYSectionPos = vertex.Z();
640 }
641
642 const Int_t nY = fCoord->GetNYBins();
643 const Int_t nX = fCoord->GetNXBins();
644 fMesh.resize(nX * nY);
645 fMesh.SetRowLen(nY);
646
647 Double_t legoR = gStyle->GetLegoInnerR();
648 if (legoR > 1. || legoR < 0.)
649 legoR = 0.5;
650 const Double_t rRange = fCoord->GetZLength();
651 const Double_t sc = (1 - legoR) * fCoord->GetXScale();
652 legoR *= fCoord->GetXScale();
653
654 const Double_t fullAngle = fXAxis->GetBinCenter(fXAxis->GetNbins()) - fXAxis->GetBinCenter(1);
655 const Double_t phiLow = fXAxis->GetBinCenter(1);
656 Double_t angle = 0.;
657
658 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
659 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
660 angle = (fXAxis->GetBinLowEdge(ir) - phiLow) / fullAngle * TMath::TwoPi();
661 Double_t r = fType != kSurf5 ? legoR + (fHist->GetBinContent(ir, jr) - fCoord->GetZRange().first) / rRange * sc : legoR;
662 fMesh[i][j].X() = r * TMath::Cos(angle);
663 fMesh[i][j].Y() = fCoord->GetYLog() ?
665 :
667 fMesh[i][j].Z() = r * TMath::Sin(angle);
668 }
669 }
670
671 if (Textured()) {
673 fMinMaxVal.second = fMinMaxVal.first;
674
675 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
676 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
677 const Double_t val = fHist->GetBinContent(i, j);
678 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
679 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
680 }
681 }
682
684 }
685
686
687 SetNormals();
688
689 return kTRUE;
690}
691
692////////////////////////////////////////////////////////////////////////////////
693///Find bin ranges for X and Y axes,
694///axes ranges for X, Y and Z.
695///Function returns false, if logarithmic scale for
696///some axis was requested, but we cannot
697///find correct range.
698
700{
702 return kFALSE;
703
705
706 if (fCoord->Modified()) {
708 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
709 fXOZSectionPos = vertex.Y();
710 fYOZSectionPos = vertex.X();
711 fXOYSectionPos = vertex.Z();
713 }
714
715 const Int_t nY = fCoord->GetNYBins();
716 const Int_t nX = fCoord->GetNXBins();
717 fMesh.resize(nX * nY);
718 fMesh.SetRowLen(nY);
719
720 Double_t legoR = gStyle->GetLegoInnerR();
721 if (legoR > 1. || legoR < 0.)
722 legoR = 0.5;
723 const Double_t rRange = fCoord->GetZLength();
724 const Double_t sc = (1 - legoR) * fCoord->GetXScale();
725 legoR *= fCoord->GetXScale();
726
727 //0 <= theta <= 2 * pi
728 const Double_t fullTheta = fXAxis->GetBinCenter(fXAxis->GetNbins()) - fXAxis->GetBinCenter(1);
729 const Double_t thetaLow = fXAxis->GetBinCenter(1);
730 //0 <= phi <= pi
731 const Double_t fullPhi = fYAxis->GetBinCenter(fYAxis->GetNbins()) - fYAxis->GetBinCenter(1);
732 const Double_t phiLow = fYAxis->GetBinCenter(1);
733
734 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
735
736 const Double_t theta = (fXAxis->GetBinCenter(ir) - thetaLow) / fullTheta * TMath::TwoPi();
737
738 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
739
740 const Double_t phi = (fYAxis->GetBinCenter(jr) - phiLow) / fullPhi * TMath::Pi();
741 const Double_t r = fType != kSurf5 ? legoR + (fHist->GetBinContent(ir, jr) - fCoord->GetZRange().first) / rRange * sc
742 : legoR;
743
744 fMesh[i][j].X() = r * TMath::Sin(phi) * TMath::Cos(theta);
745 fMesh[i][j].Y() = r * TMath::Sin(phi) * TMath::Sin(theta);
746 fMesh[i][j].Z() = r * TMath::Cos(phi);
747 }
748 }
749
750 if (Textured()) {
752 fMinMaxVal.second = fMinMaxVal.first;
753
754 for (Int_t i = fCoord->GetFirstXBin(), e = fCoord->GetLastXBin(); i <= e; ++i) {
755 for (Int_t j = fCoord->GetFirstYBin(), e1 = fCoord->GetLastYBin(); j <= e1; ++j) {
756 const Double_t val = fHist->GetBinContent(i, j);
757 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, val);
758 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, val);
759 }
760 }
761
763 }
764
765
766 SetNormals();
767
768 return kTRUE;
769}
770
771////////////////////////////////////////////////////////////////////////////////
772/// Draw projections.
773
775{
776 const TGLDisableGuard lightGuard(GL_LIGHTING);
777 const TGLEnableGuard blendGuard(GL_BLEND);
778 const TGLEnableGuard lineSmooth(GL_LINE_SMOOTH);
779 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
780 glDepthMask(GL_FALSE);
781 glLineWidth(3.f);
782
783 typedef std::list<Projection_t>::const_iterator CLI_t;
784 for (CLI_t begin = fXOZProj.begin(), end = fXOZProj.end(); begin != end; ++begin) {
785 const Projection_t &proj = *begin;
786 glColor4ub(proj.fRGBA[0], proj.fRGBA[1], proj.fRGBA[2], proj.fRGBA[3]);
787
788 for(UInt_t i = 0, e = proj.fVertices.size() / 3; i < e; ++i) {
789 glBegin(GL_LINE_STRIP);
790 glVertex3dv(proj.fVertices[i * 3].CArr());
791 glVertex3dv(proj.fVertices[i * 3 + 1].CArr());
792 glVertex3dv(proj.fVertices[i * 3 + 2].CArr());
793 glEnd();
794 }
795 const Double_t y = fBackBox.GetFrontPoint() == 2 || fBackBox.GetFrontPoint() == 3 ? fBackBox.Get3DBox()[0].Y() : fBackBox.Get3DBox()[2].Y();
796 for(UInt_t i = 0, e = proj.fVertices.size() / 3; i < e; ++i) {
797 glBegin(GL_LINE_STRIP);
798 const TGLVertex3 &v1 = proj.fVertices[i * 3];
799 glVertex3d(v1.X(), y, v1.Z());
800 const TGLVertex3 &v2 = proj.fVertices[i * 3 + 1];
801 glVertex3d(v2.X(), y, v2.Z());
802 const TGLVertex3 &v3 = proj.fVertices[i * 3 + 2];
803 glVertex3d(v3.X(), y, v3.Z());
804 glEnd();
805 }
806 }
807
808 for (CLI_t begin = fYOZProj.begin(), end = fYOZProj.end(); begin != end; ++begin) {
809 const Projection_t &proj = *begin;
810 glColor4ub(proj.fRGBA[0], proj.fRGBA[1], proj.fRGBA[2], proj.fRGBA[3]);
811
812 for(UInt_t i = 0, e = proj.fVertices.size() / 3; i < e; ++i) {
813 glBegin(GL_LINE_STRIP);
814 glVertex3dv(proj.fVertices[i * 3].CArr());
815 glVertex3dv(proj.fVertices[i * 3 + 1].CArr());
816 glVertex3dv(proj.fVertices[i * 3 + 2].CArr());
817 glEnd();
818 }
819
820 const Double_t x = fBackBox.GetFrontPoint() == 2 || fBackBox.GetFrontPoint() == 1 ? fBackBox.Get3DBox()[0].X() : fBackBox.Get3DBox()[2].X();
821 for(UInt_t i = 0, e = proj.fVertices.size() / 3; i < e; ++i) {
822 glBegin(GL_LINE_STRIP);
823 const TGLVertex3 &v1 = proj.fVertices[i * 3];
824 glVertex3d(x, v1.Y(), v1.Z());
825 const TGLVertex3 &v2 = proj.fVertices[i * 3 + 1];
826 glVertex3d(x, v2.Y(), v2.Z());
827 const TGLVertex3 &v3 = proj.fVertices[i * 3 + 2];
828 glVertex3d(x, v3.Y(), v3.Z());
829 glEnd();
830 }
831 }
832
833 for (CLI_t begin = fXOYProj.begin(), end = fXOYProj.end(); begin != end; ++begin) {
834 const Projection_t &proj = *begin;
835 glColor4ub(proj.fRGBA[0], proj.fRGBA[1], proj.fRGBA[2], proj.fRGBA[3]);
836
837 for(UInt_t i = 0, e = proj.fVertices.size() / 2; i < e; ++i) {
838 glBegin(GL_LINES);
839 glVertex3dv(proj.fVertices[i * 2].CArr());
840 glVertex3dv(proj.fVertices[i * 2 + 1].CArr());
841 glEnd();
842 }
843
844
845 for(UInt_t i = 0, e = proj.fVertices.size() / 2; i < e; ++i) {
846 glBegin(GL_LINES);
847 const TGLVertex3 &v1 = proj.fVertices[i * 2];
848 glVertex3d(v1.X(), v1.Y(), fBackBox.Get3DBox()[0].Z());
849 const TGLVertex3 &v2 = proj.fVertices[i * 2 + 1];
850 glVertex3d(v2.X(), v2.Y(), fBackBox.Get3DBox()[0].Z());
851 glEnd();
852 }
853
854 }
855
856 glDepthMask(GL_TRUE);
857 glLineWidth(1.f);
858}
859
860////////////////////////////////////////////////////////////////////////////////
861/// Draw section X.
862
864{
865 //XOZ parallel section.
866 Int_t binY = -1;
867 for (Int_t j = 0, e = fCoord->GetNYBins() - 1; j < e; ++j) {
868 if (fMesh[0][j].Y() <= fXOZSectionPos && fXOZSectionPos <= fMesh[0][j + 1].Y()) {
869 binY = j;
870 break;
871 }
872 }
873
874 if (binY >= 0) {
875 //Draw 2d curve on the profile's plane.
876 const TGLPlane profilePlane(0., 1., 0., -fXOZSectionPos);
877
878 if (!fSectionPass) {
879 glColor3d(1., 0., 0.);
880 glLineWidth(3.f);
881
882 for (Int_t i = 0, e = fCoord->GetNXBins() - 1; i < e; ++i) {
883 glBegin(GL_LINE_STRIP);
884 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[i + 1][binY], fMesh[i + 1][binY + 1]), kFALSE).second.CArr());
885 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[i + 1][binY], fMesh[i][binY + 1]), kFALSE).second.CArr());
886 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[i][binY], fMesh[i][binY + 1]), kFALSE).second.CArr());
887 glEnd();
888 }
889 glLineWidth(1.f);
890 } else {
891 fProj.fVertices.clear();
892 for (Int_t i = 0, e = fCoord->GetNXBins() - 1; i < e; ++i) {
893 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[i + 1][binY], fMesh[i + 1][binY + 1]), kFALSE).second);
894 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[i + 1][binY], fMesh[i][binY + 1]), kFALSE).second);
895 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[i][binY], fMesh[i][binY + 1]), kFALSE).second);
896 }
897 if (!fProj.fVertices.empty()) {
898 fProj.fRGBA[0] = (UChar_t) (50 + fgRandom->Integer(206));
899 fProj.fRGBA[1] = (UChar_t) fgRandom->Integer(150);
900 fProj.fRGBA[2] = (UChar_t) fgRandom->Integer(150);
901 fProj.fRGBA[3] = 150;
902 static Projection_t dummy;
903 fXOZProj.push_back(dummy);
904 fXOZProj.back().Swap(fProj);
905 }
906 }
907 }
908}
909
910////////////////////////////////////////////////////////////////////////////////
911/// Draw section Y.
912
914{
915 //YOZ parallel section.
916 Int_t binX = -1;
917 for (Int_t i = 0, e = fCoord->GetNXBins() - 1; i < e; ++i) {
918 if (fMesh[i][0].X() <= fYOZSectionPos && fYOZSectionPos <= fMesh[i + 1][0].X()) {
919 binX = i;
920 break;
921 }
922 }
923
924 if (binX >= 0) {
925 //Draw 2d curve on the profile's plane.
926 const TGLPlane profilePlane(1., 0., 0., -fYOZSectionPos);
927
928 if (!fSectionPass) {
929 glColor3d(1., 0., 0.);
930 glLineWidth(3.f);
931 for (Int_t j = 0, e = fCoord->GetNYBins() - 1; j < e; ++j) {
932 glBegin(GL_LINE_STRIP);
933 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[binX][j + 1], fMesh[binX + 1][j + 1]), kFALSE).second.CArr());
934 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[binX][j + 1], fMesh[binX + 1][j]), kFALSE).second.CArr());
935 glVertex3dv(Intersection(profilePlane, TGLLine3(fMesh[binX][j], fMesh[binX + 1][j]), kFALSE).second.CArr());
936 glEnd();
937 }
938 glLineWidth(1.f);
939 } else {
940 fProj.fVertices.clear();
941 for (Int_t j = 0, e = fCoord->GetNYBins() - 1; j < e; ++j) {
942 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[binX][j + 1], fMesh[binX + 1][j + 1]), kFALSE).second);
943 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[binX][j + 1], fMesh[binX + 1][j]), kFALSE).second);
944 fProj.fVertices.push_back(Intersection(profilePlane, TGLLine3(fMesh[binX][j], fMesh[binX + 1][j]), kFALSE).second);
945 }
946 if (!fProj.fVertices.empty()) {
947 fProj.fRGBA[0] = (UChar_t) (50 + fgRandom->Integer(206));
948 fProj.fRGBA[1] = (UChar_t) fgRandom->Integer(150);
949 fProj.fRGBA[2] = (UChar_t) fgRandom->Integer(150);
950 fProj.fRGBA[3] = 150;
951 static Projection_t dummy;
952 fYOZProj.push_back(dummy);
953 fYOZProj.back().Swap(fProj);
954 }
955 }
956
957 }
958}
959
960////////////////////////////////////////////////////////////////////////////////
961/// Draw section Z.
962
964{
965 //XOY parallel section.
966 const Int_t nX = fCoord->GetNXBins();
967 const Int_t nY = fCoord->GetNYBins();
968 const TGLPlane profilePlane(0., 0., 1., -fXOYSectionPos);
969 TGLVertex3 intersection[2];
970
971
972 if (fSectionPass)
973 fProj.fVertices.clear();
974 else {
975 glColor3d(1., 0., 0.);
976 glLineWidth(3.f);
977 }
978
979 for (Int_t i = 0; i < nX - 1; ++i) {
980 for (Int_t j = 0; j < nY - 1; ++j) {
981 const TGLVertex3 &v1 = fMesh[i + 1][j], &v2 = fMesh[i][j], &v3 = fMesh[i][j + 1], &v4 = fMesh[i + 1][j + 1];
982 Double_t zMin = TMath::Min(TMath::Min(v1.Z(), v2.Z()), v3.Z());
983 Double_t zMax = TMath::Max(TMath::Max(v1.Z(), v2.Z()), v3.Z());
984
985 if (zMin < fXOYSectionPos && zMax > fXOYSectionPos) {
986 Int_t np = 0;
987 if ((v1.Z() > fXOYSectionPos && v2.Z() < fXOYSectionPos) || (v2.Z() > fXOYSectionPos && v1.Z() < fXOYSectionPos)) {
988 TGLLine3 line(v1, v2);
989 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
990 }
991 if ((v2.Z() > fXOYSectionPos && v3.Z() < fXOYSectionPos) || (v3.Z() > fXOYSectionPos && v2.Z() < fXOYSectionPos)) {
992 TGLLine3 line(v2, v3);
993 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
994 }
995 if ((np < 2 && v1.Z() > fXOYSectionPos && v3.Z() < fXOYSectionPos) || (v3.Z() > fXOYSectionPos && v1.Z() < fXOYSectionPos)) {
996 TGLLine3 line(v1, v3);
997 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
998 }
999 if (np > 1) {
1000 if (!fSectionPass) {
1001 glBegin(GL_LINES);
1002 glVertex3dv(intersection[0].CArr());
1003 glVertex3dv(intersection[1].CArr());
1004 glEnd();
1005 } else {
1006 fProj.fVertices.push_back(intersection[0]);
1007 fProj.fVertices.push_back(intersection[1]);
1008 }
1009 }
1010 }
1011 zMin = TMath::Min(v4.Z(), zMin);
1012 zMax = TMath::Max(v4.Z(), zMax);
1013 if (zMin < fXOYSectionPos && zMax > fXOYSectionPos) {
1014 Int_t np = 0;
1015 if ((v3.Z() > fXOYSectionPos && v4.Z() < fXOYSectionPos) || (v4.Z() > fXOYSectionPos && v3.Z() < fXOYSectionPos)) {
1016 TGLLine3 line(v3, v4);
1017 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
1018 }
1019 if ((v4.Z() > fXOYSectionPos && v1.Z() < fXOYSectionPos) || (v1.Z() > fXOYSectionPos && v4.Z() < fXOYSectionPos)) {
1020 TGLLine3 line(v4, v1);
1021 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
1022 }
1023 if ((np < 2 && v3.Z() > fXOYSectionPos && v1.Z() < fXOYSectionPos) || (v1.Z() > fXOYSectionPos && v3.Z() < fXOYSectionPos)) {
1024 TGLLine3 line(v3, v1);
1025 intersection[np++] = Intersection(profilePlane, line, kFALSE).second;
1026 }
1027 if (np > 1) {
1028 if (!fSectionPass) {
1029 glBegin(GL_LINES);
1030 glVertex3dv(intersection[0].CArr());
1031 glVertex3dv(intersection[1].CArr());
1032 glEnd();
1033 } else {
1034 fProj.fVertices.push_back(intersection[0]);
1035 fProj.fVertices.push_back(intersection[1]);
1036 }
1037 }
1038 }
1039 }
1040 }
1041
1042 if (fSectionPass && !fProj.fVertices.empty()) {
1043 fProj.fRGBA[0] = (UChar_t) fgRandom->Integer(150);
1044 fProj.fRGBA[1] = (UChar_t) fgRandom->Integer(150);
1045 fProj.fRGBA[2] = (UChar_t) (50 + fgRandom->Integer(206));
1046 fProj.fRGBA[3] = 150;
1047 static Projection_t dummy;
1048 fXOYProj.push_back(dummy);
1049 fXOYProj.back().Swap(fProj);
1050 }
1051
1052 if (!fSectionPass)
1053 glLineWidth(1.f);
1054}
1055
1056////////////////////////////////////////////////////////////////////////////////
1057///Clamp z value.
1058
1060{
1061 const TGLVertex3 *frame = fBackBox.Get3DBox();
1062
1063 if (fCoord->GetZLog())
1064 if (zVal <= 0.)
1065 zVal = frame[0].Z();
1066 else
1067 zVal = TMath::Log10(zVal) * fCoord->GetZScale();
1068 else
1069 zVal *= fCoord->GetZScale();
1070
1071 if (zVal > frame[4].Z())
1072 zVal = frame[4].Z();
1073 else if (zVal < frame[0].Z())
1074 zVal = frame[0].Z();
1075}
1076
1077////////////////////////////////////////////////////////////////////////////////
1078///Find 3d coords using mouse cursor coords.
1079
1081{
1082 py = fCamera->GetHeight() - py;
1083
1084 const Int_t nY = fCoord->GetNYBins() - 1;
1085 Int_t selected = fSelectedPart - (fSelectionBase - 1);
1086 Int_t k = selected / 2;
1087 Int_t i = k / nY;
1088 Int_t j = k % nY;
1089
1090 const Bool_t odd = selected & 1;
1091 const TGLVertex3 &v1 = odd ? fMesh[i][j + 1] : fMesh[i + 1][j];
1092 const TGLVertex3 &v2 = odd ? fMesh[i + 1][j + 1] : fMesh[i][j];
1093 const TGLVertex3 &v3 = odd ? fMesh[i + 1][j] : fMesh[i][j + 1];
1094
1095 TGLVertex3 winV1, winV2, winV3;
1096
1097 Double_t mvMatrix[16] = {0.};
1098 glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix);
1099 Double_t prMatrix[16] = {0.};
1100 glGetDoublev(GL_PROJECTION_MATRIX, prMatrix);
1101 Int_t viewport[4] = {0};
1102 glGetIntegerv(GL_VIEWPORT, viewport);
1103
1104 gluProject(v1.X(), v1.Y(), v1.Z(), mvMatrix, prMatrix, viewport, &winV1.X(), &winV1.Y(), &winV1.Z());
1105 gluProject(v2.X(), v2.Y(), v2.Z(), mvMatrix, prMatrix, viewport, &winV2.X(), &winV2.Y(), &winV2.Z());
1106 gluProject(v3.X(), v3.Y(), v3.Z(), mvMatrix, prMatrix, viewport, &winV3.X(), &winV3.Y(), &winV3.Z());
1107
1108 Double_t planeABCD[4] = {0.};
1109 TMath::Normal2Plane(winV1.CArr(), winV2.CArr(), winV3.CArr(), planeABCD);
1110 planeABCD[3] = - winV1.X() * planeABCD[0] - winV1.Y() * planeABCD[1] - winV1.Z() * planeABCD[2];
1111 Double_t pz = (-planeABCD[3] - planeABCD[0] * px - planeABCD[1] * py) / planeABCD[2];
1112 Double_t rez[3] = {0.};
1113
1114 gluUnProject(px, py, pz, mvMatrix, prMatrix, viewport, rez, rez + 1, rez + 2);
1115
1116 fObjectInfo.Form("(x == %f, y == %f, z == %f)",
1117 rez[0] / fCoord->GetXScale(),
1118 rez[1] / fCoord->GetYScale(),
1119 rez[2] / fCoord->GetZScale());
1120
1121 return (char *)fObjectInfo.Data();
1122}
1123
1124////////////////////////////////////////////////////////////////////////////////
1125///Generate palette.
1126
1128{
1129 if (!fUpdateTexMap)
1130 return kTRUE;
1131
1132 if(fMinMaxVal.first == fMinMaxVal.second)
1133 return kFALSE;//must be std::abs(fMinMaxVal.second - fMinMaxVal.first) < ...
1134
1135 //User-defined contours are disabled. To be fixed.
1138
1139 UInt_t paletteSize = gStyle->GetNumberContours();
1140 if (!paletteSize)
1141 paletteSize = 20;
1142
1143 Bool_t rez = fPalette.GeneratePalette(paletteSize, fMinMaxVal);
1144
1145 if (rez && fUpdateTexMap) {
1146 GenTexMap();
1148 }
1149
1150 return rez;
1151}
1152
1153////////////////////////////////////////////////////////////////////////////////
1154///Find texture coordinates.
1155
1157{
1158 const Int_t nX = fCoord->GetNXBins();
1159 const Int_t nY = fCoord->GetNYBins();
1160
1161 fTexMap.resize(nX * nY);
1162 fTexMap.SetRowLen(nY);
1163
1164 for (Int_t i = 0, ir = fCoord->GetFirstXBin(); i < nX; ++i, ++ir) {
1165 for (Int_t j = 0, jr = fCoord->GetFirstYBin(); j < nY; ++j, ++jr) {
1166 Double_t z = fHist->GetBinContent(ir, jr);
1168 ClampZ(z);
1169 fTexMap[i][j] = fPalette.GetTexCoord(z);
1170 }
1171 }
1172}
1173
1174////////////////////////////////////////////////////////////////////////////////
1175///Draw flat textured surface.
1176
1178{
1179 static const Float_t whiteDiffuse[] = {0.8f, 0.8f, 0.8f, 0.65f};
1180 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, whiteDiffuse);
1181 for (Int_t i = 0, ei = fCoord->GetNXBins() - 1; i < ei; ++i) {
1182 for (Int_t j = 0, ej = fCoord->GetNYBins() - 1; j < ej; ++j) {
1183 Rgl::DrawFaceTextured(fMesh[i][j + 1], fMesh[i][j], fMesh[i + 1][j],
1184 fTexMap[i][j + 1], fTexMap[i][j], fTexMap[i + 1][j],
1185 fBackBox.Get3DBox()[4].Z(), TGLVector3(0., 0., 1.));
1186 Rgl::DrawFaceTextured(fMesh[i + 1][j], fMesh[i + 1][j + 1], fMesh[i][j + 1],
1187 fTexMap[i + 1][j], fTexMap[i + 1][j + 1], fTexMap[i][j + 1],
1188 fBackBox.Get3DBox()[4].Z(), TGLVector3(0., 0., 1.));
1189 }
1190 }
1191}
1192
1193////////////////////////////////////////////////////////////////////////////////
1194///Checks, if surf requires texture.
1195
1197{
1198 switch (fType) {
1199 case kSurf1:
1200 case kSurf2:
1201 case kSurf3:
1202 case kSurf5:
1203 return kTRUE;
1204 default:;
1205 }
1206
1207 return kFALSE;
1208}
1209
1210////////////////////////////////////////////////////////////////////////////////
1211///Any section exists.
1212
1214{
1215 return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos > fBackBox.Get3DBox()[0].X() ||
1217}
1218
1219////////////////////////////////////////////////////////////////////////////////
1220///Any projection exists.
1221
1223{
1224 return !fXOZProj.empty() || !fYOZProj.empty() || !fXOYProj.empty();
1225}
1226
1227////////////////////////////////////////////////////////////////////////////////
1228///Draw. Palette.
1229///Originally, fCamera was never null.
1230///It can be a null now because of gl-viewer.
1231
1233{
1234 if (!fCamera) {
1235 //Thank you, gl-viewer!
1236 return;
1237 }
1238
1240
1241 glFinish();
1242
1243 fCamera->SetCamera();
1245}
1246
1247////////////////////////////////////////////////////////////////////////////////
1248///Draw. Palette. Axis.
1249
1251{
1252 gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
1254}
@ 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
#define c(i)
Definition RSha256.hxx:101
#define e(i)
Definition RSha256.hxx:103
unsigned char UChar_t
Definition RtypesCore.h:38
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:377
@ kWhite
Definition Rtypes.h:65
#define X(type, name)
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
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
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint angle
#define gROOT
Definition TROOT.h:406
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
R__EXTERN TStyle * gStyle
Definition TStyle.h:433
#define gVirtualX
Definition TVirtualX.h:337
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:125
The color creation and management class.
Definition TColor.h:21
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1839
void SetRowLen(Int_t len)
Definition TGLUtil.h:1173
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:4254
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition TGLUtil.cxx:4271
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition TGLUtil.cxx:4170
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition TGLUtil.cxx:4235
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.
const TGLVertex3 * Get3DBox() const
Get 3D box.
void DrawBox(Int_t selectedPart, Bool_t selectionPass, const std::vector< Double_t > &zLevels, Bool_t highColor) const
Draw back box for a plot.
Int_t GetFrontPoint() const
The nearest point.
Camera for TGLPlotPainter and sub-classes.
void StartPan(Int_t px, Int_t py)
User clicks somewhere (px, py).
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
void SetCamera() const
Viewport and projection.
void Pan(Int_t px, Int_t py)
Pan camera.
Int_t GetHeight() const
viewport[3]
void SetViewVolume(const TGLVertex3 *box)
'box' is the TGLPlotPainter's back box's coordinates.
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
Double_t GetZLength() const
Z length.
Bool_t SetRanges(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges.
Double_t GetYScale() const
const Rgl::Range_t & GetXRangeScaled() const
Scaled range.
Bool_t GetXLog() const
Get X log.
Int_t GetFirstXBin() const
Int_t GetFirstYBin() const
const Rgl::Range_t & GetZRange() const
Z range.
const Rgl::Range_t & GetYRangeScaled() const
Scaled range.
void 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).
std::vector< Double_t > fZLevels
Double_t fXOYSectionPos
void RestoreModelviewMatrix() const
Double_t fXOZSectionPos
TGLPlotCoordinates * fCoord
void Paint() override
Draw lego/surf/whatever you can.
TGLPlotBox fBackBox
void SaveProjectionMatrix() const
void SaveModelviewMatrix() const
void MoveSection(Int_t px, Int_t py)
Create dynamic profile using selected plane.
TGLPlotCamera * fCamera
void RestoreProjectionMatrix() const
Double_t fYOZSectionPos
Implements painting of TH2 with "SURF" option.
char * GetPlotInfo(Int_t px, Int_t py) override
Coords for point on surface under cursor.
char * WindowPointTo3DPoint(Int_t px, Int_t py) const
Find 3d coords using mouse cursor coords.
void Pan(Int_t px, Int_t py) override
User's moving mouse cursor, with middle mouse button pressed (for pad).
void InitGL() const override
Initialize some OpenGL state variables.
TGLLevelPalette fPalette
TGL2DArray< Double_t > fTexMap
void ProcessEvent(Int_t event, Int_t px, Int_t py) override
Remove all profiles/sections.
Bool_t InitGeometryPolar()
Find bin ranges for X and Y axes, axes ranges for X, Y and Z.
void AddOption(const TString &stringOption) override
Additional options for surfaces.
void DrawProjections() const
Draw projections.
Bool_t HasProjections() const
Any projection exists.
Bool_t Textured() const
Checks, if surf requires texture.
void DrawSectionXOY() const override
Draw section Z.
std::list< Projection_t > fXOYProj
void DrawPalette() const
Draw.
TGL2DArray< TGLVector3 > fAverageNormals
void SetSurfaceColor() const
Set color for surface.
void DrawPaletteAxis() const override
Draw. Palette. Axis.
void DrawSectionXOZ() const override
Draw section X.
void DrawPlot() const override
Draw surf/surf1/surf2/surf4.
void DeInitGL() const override
Initialize some OpenGL state variables.
void DrawSectionYOZ() const override
Draw section Y.
TGL2DArray< std::pair< TGLVector3, TGLVector3 > > fFaceNormals
void DrawContoursProjection() const
Draw flat textured surface.
std::list< Projection_t > fXOZProj
Bool_t InitGeometrySpherical()
Find bin ranges for X and Y axes, axes ranges for X, Y and Z.
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.
Bool_t InitGeometry() override
Set mesh, normals.
static TRandom * fgRandom
void GenTexMap() const
Find texture coordinates.
void SetNormals()
One normal per vertex; this normal is average of neighbouring triangles normals.
void StartPan(Int_t px, Int_t py) override
User clicks right mouse button (in a pad).
Bool_t InitGeometryCylindrical()
Find bin ranges for X and Y axes, axes ranges for X, Y and Z.
std::list< Projection_t > fYOZProj
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:59
@ kUserContour
User specified contour levels.
Definition TH1.h:166
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5029
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
void ResetBit(UInt_t f)
Definition TObject.h:198
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:361
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:376
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2356
Float_t GetLegoInnerR() const
Definition TStyle.h:238
Int_t GetNumberContours() const
Definition TStyle.h:239
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:3845
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition TGLUtil.cxx:2900
void SetZLevels(TAxis *zAxis, Double_t zMin, Double_t zMax, Double_t zScale, std::vector< Double_t > &zLevels)
Definition TGLUtil.cxx:3829
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:2948
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:2992
T * Normal2Plane(const T v1[3], const T v2[3], const T v3[3], T normal[3])
Calculates a normal vector of a plane.
Definition TMath.h:1212
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:594
constexpr Double_t Pi()
Definition TMath.h:37
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:588
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:762
constexpr Double_t TwoPi()
Definition TMath.h:44
void Swap(Projection_t &rhs)
Constructor.
std::vector< TGLVertex3 > fVertices