Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLUtil.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Richard Maunder 25/05/2005
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, 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 <cassert>
14#include <string>
15#include <map>
16#include <iostream>
17
18#include "THLimitsFinder.h"
19#include "TVirtualPad.h"
20#include "TVirtualX.h"
21#include "TStyle.h"
22#include "TGaxis.h"
23#include "TColor.h"
24#include "TError.h"
25#include "TAxis.h"
26#include "TMath.h"
27#include "TROOT.h"
28#include "TEnv.h"
29
30#include "TGLBoundingBox.h"
31#include "TGLCamera.h"
32#include "TGLPlotPainter.h"
33#include "TGLIncludes.h"
34#include "TGLQuadric.h"
35#include "TGLUtil.h"
36
37/** \class TGLVertex3
38\ingroup opengl
393 component (x/y/z) vertex class.
40
41This is part of collection of simple utility classes for GL only in
42TGLUtil.h/cxx. These provide const and non-const accessors Arr() &
43CArr() to a GL compatible internal field - so can be used directly
44with OpenGL C API calls - which TVector3 etc cannot (easily).
45They are not intended to be fully featured just provide minimum required.
46*/
47
48
49////////////////////////////////////////////////////////////////////////////////
50/// Construct a default (0.0, 0.0, 0.0) vertex
51
53{
54 Fill(0.0);
55}
56
57////////////////////////////////////////////////////////////////////////////////
58/// Construct a vertex with components (x,y,z)
59
64
65////////////////////////////////////////////////////////////////////////////////
66/// Construct a vertex with components (v[0], v[1], v[2])
67
69{
70 Set(v[0], v[1], v[2]);
71}
72
73////////////////////////////////////////////////////////////////////////////////
74/// Construct a vertex from 'other'
75
80
81////////////////////////////////////////////////////////////////////////////////
82/// Destroy vertex object
83
87
88////////////////////////////////////////////////////////////////////////////////
89/// Offset a vertex by vector 'shift'
90
92{
93 fVals[0] += shift[0];
94 fVals[1] += shift[1];
95 fVals[2] += shift[2];
96}
97
98////////////////////////////////////////////////////////////////////////////////
99/// Offset a vertex by components (xDelta, yDelta, zDelta)
100
102{
103 fVals[0] += xDelta;
104 fVals[1] += yDelta;
105 fVals[2] += zDelta;
106}
107
108////////////////////////////////////////////////////////////////////////////////
109
111{
112 fVals[0] = TMath::Min(fVals[0], other.fVals[0]);
113 fVals[1] = TMath::Min(fVals[1], other.fVals[1]);
114 fVals[2] = TMath::Min(fVals[2], other.fVals[2]);
115}
116
117////////////////////////////////////////////////////////////////////////////////
118
120{
121 fVals[0] = TMath::Max(fVals[0], other.fVals[0]);
122 fVals[1] = TMath::Max(fVals[1], other.fVals[1]);
123 fVals[2] = TMath::Max(fVals[2], other.fVals[2]);
124}
125
126////////////////////////////////////////////////////////////////////////////////
127/// Output vertex component values to std::cout
128
130{
131 std::cout << "(" << fVals[0] << "," << fVals[1] << "," << fVals[2] << ")" << std::endl;
132}
133
134/** \class TGLVector3
135\ingroup opengl
1363 component (x/y/z) vector class.
137
138This is part of collection of utility classes for GL in TGLUtil.h/cxx
139These provide const and non-const accessors Arr() / CArr() to a GL
140compatible internal field - so can be used directly with OpenGL C API
141calls. They are not intended to be fully featured just provide
142minimum required.
143*/
144
145
146////////////////////////////////////////////////////////////////////////////////
147/// Construct a vector with components (x,y,z)
148
153
154////////////////////////////////////////////////////////////////////////////////
155/// Construct a vector with components (src[0], src[1], src[2])
156
158 TGLVertex3(src[0], src[1], src[2])
159{
160}
161
162
163/** \class TGLLine3
164\ingroup opengl
1653D space, fixed length, line class, with direction / length 'vector',
166passing through point 'vertex'. Just wraps a TGLVector3 / TGLVertex3 pair.
167*/
168
169
170////////////////////////////////////////////////////////////////////////////////
171/// Construct 3D line running from 'start' to 'end'
172
173TGLLine3::TGLLine3(const TGLVertex3 & start, const TGLVertex3 & end) :
174 fVertex(start), fVector(end - start)
175{
176}
177
178////////////////////////////////////////////////////////////////////////////////
179/// Construct 3D line running from 'start', magnitude 'vect'
180
182 fVertex(start), fVector(vect)
183{
184}
185
186////////////////////////////////////////////////////////////////////////////////
187/// Set 3D line running from 'start' to 'end'
188
189void TGLLine3::Set(const TGLVertex3 & start, const TGLVertex3 & end)
190{
191 fVertex = start;
192 fVector = end - start;
193}
194
195////////////////////////////////////////////////////////////////////////////////
196/// Set 3D line running from start, magnitude 'vect'
197
198void TGLLine3::Set(const TGLVertex3 & start, const TGLVector3 & vect)
199{
200 fVertex = start;
201 fVector = vect;
202}
203
204////////////////////////////////////////////////////////////////////////////////
205/// Draw line in current basic GL color. Assume we are in the correct reference
206/// frame
207
208void TGLLine3::Draw() const
209{
210 glBegin(GL_LINE_LOOP);
212 glVertex3dv(End().CArr());
213 glEnd();
214}
215
216/** \class TGLRect
217\ingroup opengl
218Viewport (pixel base) 2D rectangle class.
219*/
220
221
222////////////////////////////////////////////////////////////////////////////////
223/// Construct empty rect object, corner (0,0), width/height 0
224
226 fX(0), fY(0), fWidth(0), fHeight(0)
227{
228}
229
230////////////////////////////////////////////////////////////////////////////////
231/// Construct rect object, corner (x,y), dimensions 'width', 'height'
232
234 fX(x), fY(y), fWidth(width), fHeight(height)
235{
236}
237
238////////////////////////////////////////////////////////////////////////////////
239/// Construct rect object, corner (x,y), dimensions 'width', 'height'
240
242 fX(x), fY(y), fWidth(width), fHeight(height)
243{
244}
245
246
247////////////////////////////////////////////////////////////////////////////////
248/// Destroy rect object
249
253
254////////////////////////////////////////////////////////////////////////////////
255/// Expand the rect to encompass point (x,y)
256
258{
259 Int_t delX = x - fX;
260 Int_t delY = y - fY;
261
262 if (delX > fWidth) {
263 fWidth = delX;
264 }
265 if (delY > fHeight) {
266 fHeight = delY;
267 }
268
269 if (delX < 0) {
270 fX = x;
271 fWidth += -delX;
272 }
273 if (delY < 0) {
274 fY = y;
275 fHeight += -delY;
276 }
277}
278
279////////////////////////////////////////////////////////////////////////////////
280/// Return the diagonal of the rectangle.
281
283{
284 const Double_t w = static_cast<Double_t>(fWidth);
285 const Double_t h = static_cast<Double_t>(fHeight);
286 return TMath::Nint(TMath::Sqrt(w*w + h*h));
287}
288
289////////////////////////////////////////////////////////////////////////////////
290/// Return overlap result (kInside, kOutside, kPartial) of this
291/// rect with 'other'
292
294{
295 using namespace Rgl;
296
297 if ((fX <= other.fX) && (fX + fWidth >= other.fX + other.fWidth) &&
298 (fY <= other.fY) && (fY + fHeight >= other.fY + other.fHeight))
299 {
300 return kInside;
301 }
302 else if ((fX >= other.fX + static_cast<Int_t>(other.fWidth)) ||
303 (fX + static_cast<Int_t>(fWidth) <= other.fX) ||
304 (fY >= other.fY + static_cast<Int_t>(other.fHeight)) ||
305 (fY + static_cast<Int_t>(fHeight) <= other.fY))
306 {
307 return kOutside;
308 }
309 else
310 {
311 return kPartial;
312 }
313}
314
315/** \class TGLPlane
316\ingroup opengl
3173D plane class - of format Ax + By + Cz + D = 0
318
319This is part of collection of simple utility classes for GL only in
320TGLUtil.h/cxx. These provide const and non-const accessors Arr() &
321CArr() to a GL compatible internal field - so can be used directly
322with OpenGL C API calls - which TVector3 etc cannot (easily).
323They are not intended to be fully featured just provide minimum
324required.
325*/
326
327
328////////////////////////////////////////////////////////////////////////////////
329/// Construct a default plane of x + y + z = 0
330
332{
333 Set(1.0, 1.0, 1.0, 0.0);
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// Construct plane from 'other'
338
340{
341 Set(other);
342}
343
344////////////////////////////////////////////////////////////////////////////////
345/// Construct plane with equation a.x + b.y + c.z + d = 0
346/// with optional normalisation
347
352
353////////////////////////////////////////////////////////////////////////////////
354/// Construct plane with equation eq[0].x + eq[1].y + eq[2].z + eq[3] = 0
355/// with optional normalisation
356
358{
359 Set(eq);
360}
361
362////////////////////////////////////////////////////////////////////////////////
363/// Construct plane passing through 3 supplied points
364/// with optional normalisation
365
367 const TGLVertex3 & p3)
368{
369 Set(p1, p2, p3);
370}
371
372////////////////////////////////////////////////////////////////////////////////
373/// Construct plane with supplied normal vector, passing through point
374/// with optional normalisation
375
377{
378 Set(v, p);
379}
380
381////////////////////////////////////////////////////////////////////////////////
382/// Assignment operator
383
385{
386 Set(src);
387 return *this;
388}
389
390////////////////////////////////////////////////////////////////////////////////
391/// Normalise the plane.
392
394{
395 Double_t mag = sqrt(fVals[0]*fVals[0] + fVals[1]*fVals[1] + fVals[2]*fVals[2]);
396
397 if (mag == 0.0 ) {
398 Error("TGLPlane::Normalise", "trying to normalise plane with zero magnitude normal");
399 return;
400 }
401 mag = 1.0 / mag;
402 fVals[0] *= mag;
403 fVals[1] *= mag;
404 fVals[2] *= mag;
405 fVals[3] *= mag;
406}
407
408////////////////////////////////////////////////////////////////////////////////
409/// Output plane equation to std::out
410
411void TGLPlane::Dump() const
412{
413 std::cout.precision(6);
414 std::cout << "Plane : " << fVals[0] << "x + " << fVals[1] << "y + " << fVals[2] << "z + " << fVals[3] << std::endl;
415}
416
417////////////////////////////////////////////////////////////////////////////////
418/// Assign from other.
419
421{
422 fVals[0] = other.fVals[0];
423 fVals[1] = other.fVals[1];
424 fVals[2] = other.fVals[2];
425 fVals[3] = other.fVals[3];
426}
427
428////////////////////////////////////////////////////////////////////////////////
429/// Set by values.
430
432{
433 fVals[0] = a;
434 fVals[1] = b;
435 fVals[2] = c;
436 fVals[3] = d;
437 Normalise();
438}
439
440////////////////////////////////////////////////////////////////////////////////
441/// Set by array values.
442
444{
445 fVals[0] = eq[0];
446 fVals[1] = eq[1];
447 fVals[2] = eq[2];
448 fVals[3] = eq[3];
449 Normalise();
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Set plane from a normal vector and in-plane point pair
454
455void TGLPlane::Set(const TGLVector3 & norm, const TGLVertex3 & point)
456{
457 fVals[0] = norm[0];
458 fVals[1] = norm[1];
459 fVals[2] = norm[2];
460 fVals[3] = -(fVals[0]*point[0] + fVals[1]*point[1] + fVals[2]*point[2]);
461 Normalise();
462}
463
464////////////////////////////////////////////////////////////////////////////////
465/// Set plane by three points.
466
467void TGLPlane::Set(const TGLVertex3 & p1, const TGLVertex3 & p2, const TGLVertex3 & p3)
468{
469 TGLVector3 norm = Cross(p2 - p1, p3 - p1);
470 Set(norm, p2);
471}
472
473////////////////////////////////////////////////////////////////////////////////
474/// Negate the plane.
475
477{
478 fVals[0] = -fVals[0];
479 fVals[1] = -fVals[1];
480 fVals[2] = -fVals[2];
481 fVals[3] = -fVals[3];
482}
483
484////////////////////////////////////////////////////////////////////////////////
485/// Distance from plane to vertex.
486
488{
489 return (fVals[0]*vertex[0] + fVals[1]*vertex[1] + fVals[2]*vertex[2] + fVals[3]);
490}
491
492////////////////////////////////////////////////////////////////////////////////
493/// Return nearest point on plane.
494
496{
497 TGLVector3 o = Norm() * (Dot(Norm(), TGLVector3(point[0], point[1], point[2])) + D() / Dot(Norm(), Norm()));
498 TGLVertex3 v = point - o;
499 return v;
500}
501
502// Some free functions for plane intersections
503
504////////////////////////////////////////////////////////////////////////////////
505/// Find 3D line interestion of this plane with 'other'. Returns a std::pair
506///
507/// first (Bool_t) second (TGLLine3)
508/// kTRUE - planes intersect intersection line between planes
509/// kFALSE - no intersect (parallel) undefined
510
511std::pair<Bool_t, TGLLine3> Intersection(const TGLPlane & p1, const TGLPlane & p2)
512{
513 TGLVector3 lineDir = Cross(p1.Norm(), p2.Norm());
514
515 if (lineDir.Mag() == 0.0) {
516 return std::make_pair(kFALSE, TGLLine3(TGLVertex3(0.0, 0.0, 0.0),
517 TGLVector3(0.0, 0.0, 0.0)));
518 }
519 TGLVertex3 linePoint = Cross((p1.Norm()*p2.D() - p2.Norm()*p1.D()), lineDir) /
521 return std::make_pair(kTRUE, TGLLine3(linePoint, lineDir));
522}
523
524////////////////////////////////////////////////////////////////////////////////
525
526std::pair<Bool_t, TGLVertex3> Intersection(const TGLPlane & p1, const TGLPlane & p2, const TGLPlane & p3)
527{
528 Double_t denom = Dot(p1.Norm(), Cross(p2.Norm(), p3.Norm()));
529 if (denom == 0.0) {
530 return std::make_pair(kFALSE, TGLVertex3(0.0, 0.0, 0.0));
531 }
532 TGLVector3 vect = ((Cross(p2.Norm(),p3.Norm())* -p1.D()) -
533 (Cross(p3.Norm(),p1.Norm())*p2.D()) -
534 (Cross(p1.Norm(),p2.Norm())*p3.D())) / denom;
535 TGLVertex3 interVert(vect.X(), vect.Y(), vect.Z());
536 return std::make_pair(kTRUE, interVert);
537}
538
539////////////////////////////////////////////////////////////////////////////////
540/// Find intersection of 3D space 'line' with this plane. If 'extend' is kTRUE
541/// then line extents can be extended (infinite length) to find intersection.
542/// If 'extend' is kFALSE the fixed extents of line is respected.
543///
544/// The return a std::pair
545///
546/// - first (Bool_t) second (TGLVertex3)
547/// - kTRUE - line/plane intersect intersection vertex on plane
548/// - kFALSE - no line/plane intersect undefined
549///
550/// If intersection is not found (first == kFALSE) & 'extend' was kTRUE (infinite line)
551/// this implies line and plane are parallel. If 'extend' was kFALSE, then
552/// either line parallel or insufficient length.
553
554std::pair<Bool_t, TGLVertex3> Intersection(const TGLPlane & plane, const TGLLine3 & line, Bool_t extend)
555{
556 Double_t denom = -(plane.A()*line.Vector().X() +
557 plane.B()*line.Vector().Y() +
558 plane.C()*line.Vector().Z());
559
560 if (denom == 0.0) {
561 return std::make_pair(kFALSE, TGLVertex3(0.0, 0.0, 0.0));
562 }
563
564 Double_t num = plane.A()*line.Start().X() + plane.B()*line.Start().Y() +
565 plane.C()*line.Start().Z() + plane.D();
566 Double_t factor = num/denom;
567
568 // If not extending (projecting) line is length from start enough to reach plane?
569 if (!extend && (factor < 0.0 || factor > 1.0)) {
570 return std::make_pair(kFALSE, TGLVertex3(0.0, 0.0, 0.0));
571 }
572
573 TGLVector3 toPlane = line.Vector() * factor;
574 return std::make_pair(kTRUE, line.Start() + toPlane);
575}
576
577/** \class TGLMatrix
578\ingroup opengl
57916 component (4x4) transform matrix - column MAJOR as per GL.
580Provides limited support for adjusting the translation, scale and
581rotation components.
582
583This is part of collection of simple utility classes for GL only in
584TGLUtil.h/cxx. These provide const and non-const accessors Arr() &
585CArr() to a GL compatible internal field - so can be used directly
586with OpenGL C API calls - which TVector3 etc cannot (easily).
587They are not intended to be fully featured just provide minimum
588required.
589*/
590
591
592////////////////////////////////////////////////////////////////////////////////
593/// Construct default identity matrix:
594///
595/// 1 0 0 0
596/// 0 1 0 0
597/// 0 0 1 0
598/// 0 0 0 1
599
604
605////////////////////////////////////////////////////////////////////////////////
606/// Construct matrix with translation components x,y,z:
607///
608/// 1 0 0 x
609/// 0 1 0 y
610/// 0 0 1 z
611/// 0 0 0 1
612
618
619////////////////////////////////////////////////////////////////////////////////
620/// Construct matrix with translation components x,y,z:
621///
622/// 1 0 0 translation.X()
623/// 0 1 0 translation.Y()
624/// 0 0 1 translation.Z()
625/// 0 0 0 1
626
632
633////////////////////////////////////////////////////////////////////////////////
634/// Construct matrix which when applied puts local origin at
635/// 'origin' and the local Z axis in direction 'z'. Both
636/// 'origin' and 'zAxisVec' are expressed in the parent frame
637
639{
640 SetIdentity();
641
643 zAxisInt.Normalise();
645
646 if (TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Y()) && TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Z())) {
647 arbAxis.Set(1.0, 0.0, 0.0);
648 } else if (TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.X()) && TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.Z())) {
649 arbAxis.Set(0.0, 1.0, 0.0);
650 } else {
651 arbAxis.Set(0.0, 0.0, 1.0);
652 }
653
655}
656
657////////////////////////////////////////////////////////////////////////////////
658/// Construct matrix which when applied puts local origin at
659/// 'origin' and the local Z axis in direction 'z'. Both
660/// 'origin' and 'zAxisVec' are expressed in the parent frame
661
667
668////////////////////////////////////////////////////////////////////////////////
669/// Construct matrix using the 16 Double_t 'vals' passed,
670/// ordering is maintained - i.e. should be column major
671/// as we are
672
674{
675 Set(vals);
676}
677
678////////////////////////////////////////////////////////////////////////////////
679/// Construct matrix from 'other'
680
682{
683 *this = other;
684}
685
686////////////////////////////////////////////////////////////////////////////////
687/// Destroy matrix object
688
692
693////////////////////////////////////////////////////////////////////////////////
694/// Multiply with matrix rhs on right.
695
697{
698 Double_t B[4];
699 Double_t* C = fVals;
700 for(int r=0; r<4; ++r, ++C)
701 {
702 const Double_t* T = rhs.fVals;
703 for(int c=0; c<4; ++c, T+=4)
704 B[c] = C[0]*T[0] + C[4]*T[1] + C[8]*T[2] + C[12]*T[3];
705 C[0] = B[0]; C[4] = B[1]; C[8] = B[2]; C[12] = B[3];
706 }
707}
708
709////////////////////////////////////////////////////////////////////////////////
710/// Multiply with matrix lhs on left.
711
713{
714 Double_t B[4];
715 Double_t* C = fVals;
716 for (int c=0; c<4; ++c, C+=4)
717 {
718 const Double_t* T = lhs.fVals;
719 for(int r=0; r<4; ++r, ++T)
720 B[r] = T[0]*C[0] + T[4]*C[1] + T[8]*C[2] + T[12]*C[3];
721 C[0] = B[0]; C[1] = B[1]; C[2] = B[2]; C[3] = B[3];
722 }
723}
724
725////////////////////////////////////////////////////////////////////////////////
726/// Set matrix which when applied puts local origin at
727/// 'origin' and the local Z axis in direction 'z'. Both
728/// 'origin' and 'z' are expressed in the parent frame
729
731{
733 zAxisInt.Normalise();
734
736 xAxisInt.Normalise();
738
739 fVals[0] = xAxisInt.X(); fVals[4] = yAxisInt.X(); fVals[8 ] = zAxisInt.X(); fVals[12] = origin.X();
740 fVals[1] = xAxisInt.Y(); fVals[5] = yAxisInt.Y(); fVals[9 ] = zAxisInt.Y(); fVals[13] = origin.Y();
741 fVals[2] = xAxisInt.Z(); fVals[6] = yAxisInt.Z(); fVals[10] = zAxisInt.Z(); fVals[14] = origin.Z();
742 fVals[3] = 0.0; fVals[7] = 0.0; fVals[11] = 0.0; fVals[15] = 1.0;
743}
744
745////////////////////////////////////////////////////////////////////////////////
746/// Set matrix using the 16 Double_t 'vals' passed,
747/// ordering is maintained - i.e. should be column major.
748
749void TGLMatrix::Set(const Double_t vals[16])
750{
751 for (UInt_t i=0; i < 16; i++) {
752 fVals[i] = vals[i];
753 }
754}
755
756////////////////////////////////////////////////////////////////////////////////
757/// Set matrix to identity.
758
760{
761 fVals[0] = 1.0; fVals[4] = 0.0; fVals[8 ] = 0.0; fVals[12] = 0.0;
762 fVals[1] = 0.0; fVals[5] = 1.0; fVals[9 ] = 0.0; fVals[13] = 0.0;
763 fVals[2] = 0.0; fVals[6] = 0.0; fVals[10] = 1.0; fVals[14] = 0.0;
764 fVals[3] = 0.0; fVals[7] = 0.0; fVals[11] = 0.0; fVals[15] = 1.0;
765}
766
767////////////////////////////////////////////////////////////////////////////////
768/// Set matrix translation components x,y,z.
769
774
775////////////////////////////////////////////////////////////////////////////////
776/// Set matrix translation components x,y,z.
777
779{
780 fVals[12] = translation[0];
781 fVals[13] = translation[1];
782 fVals[14] = translation[2];
783}
784
785////////////////////////////////////////////////////////////////////////////////
786/// Return the translation component of matrix.
787
789{
790 return TGLVector3(fVals[12], fVals[13], fVals[14]);
791}
792
793////////////////////////////////////////////////////////////////////////////////
794/// Shift matrix translation components by 'vect' in parent frame.
795
797{
798 fVals[12] += vect[0];
799 fVals[13] += vect[1];
800 fVals[14] += vect[2];
801}
802
803////////////////////////////////////////////////////////////////////////////////
804/// Translate in local frame.
805/// i1, i2 are axes indices: 1 ~ x, 2 ~ y, 3 ~ z.
806
808{
809 const Double_t *C = fVals + 4*--ai;
810 fVals[12] += amount*C[0]; fVals[13] += amount*C[1]; fVals[14] += amount*C[2];
811}
812
813////////////////////////////////////////////////////////////////////////////////
814/// Translate in local frame along all base vectors simultaneously.
815
817{
818 fVals[12] += x*fVals[0] + y*fVals[4] + z*fVals[8];
819 fVals[13] += x*fVals[1] + y*fVals[5] + z*fVals[9];
820 fVals[14] += x*fVals[2] + y*fVals[6] + z*fVals[10];
821}
822
823////////////////////////////////////////////////////////////////////////////////
824/// Set matrix axis scales to 'scale'. Note - this really sets
825/// the overall (total) scaling for each axis - it does NOT
826/// apply compounded scale on top of existing one
827
829{
831
832 // x
833 if (currentScale[0] != 0.0) {
834 fVals[0] *= scale[0]/currentScale[0];
835 fVals[1] *= scale[0]/currentScale[0];
836 fVals[2] *= scale[0]/currentScale[0];
837 } else {
838 Error("TGLMatrix::Scale()", "zero scale div by zero");
839 }
840 // y
841 if (currentScale[1] != 0.0) {
842 fVals[4] *= scale[1]/currentScale[1];
843 fVals[5] *= scale[1]/currentScale[1];
844 fVals[6] *= scale[1]/currentScale[1];
845 } else {
846 Error("TGLMatrix::Scale()", "zero scale div by zero");
847 }
848 // z
849 if (currentScale[2] != 0.0) {
850 fVals[8] *= scale[2]/currentScale[2];
851 fVals[9] *= scale[2]/currentScale[2];
852 fVals[10] *= scale[2]/currentScale[2];
853 } else {
854 Error("TGLMatrix::Scale()", "zero scale div by zero");
855 }
856}
857
858////////////////////////////////////////////////////////////////////////////////
859/// Update matrix so resulting transform has been rotated about 'pivot'
860/// (in parent frame), round vector 'axis', through 'angle' (radians)
861/// Equivalent to glRotate function, but with addition of translation
862/// and compounded on top of existing.
863
865{
866 TGLVector3 nAxis = axis;
867 nAxis.Normalise();
868 Double_t x = nAxis.X();
869 Double_t y = nAxis.Y();
870 Double_t z = nAxis.Z();
873
874 // Calculate local rotation, with pre-translation to local pivot origin
876 rotMat[ 0] = x*x*(1-c) + c; rotMat[ 4] = x*y*(1-c) - z*s; rotMat[ 8] = x*z*(1-c) + y*s; rotMat[12] = pivot[0];
877 rotMat[ 1] = y*x*(1-c) + z*s; rotMat[ 5] = y*y*(1-c) + c; rotMat[ 9] = y*z*(1-c) - x*s; rotMat[13] = pivot[1];
878 rotMat[ 2] = x*z*(1-c) - y*s; rotMat[ 6] = y*z*(1-c) + x*s; rotMat[10] = z*z*(1-c) + c; rotMat[14] = pivot[2];
879 rotMat[ 3] = 0.0; rotMat[ 7] = 0.0; rotMat[11] = 0.0; rotMat[15] = 1.0;
881
882 // TODO: Ugly - should use quaternions to avoid compound rounding errors and
883 // triple multiplication
884 *this = rotMat * localToWorld * (*this);
885}
886
887////////////////////////////////////////////////////////////////////////////////
888/// Rotate in local frame. Does optimised version of MultRight.
889/// i1, i2 are axes indices: 1 ~ x, 2 ~ y, 3 ~ z.
890
892{
893 if(i1 == i2) return;
894 const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
895 Double_t b1, b2;
896 Double_t* c = fVals;
897 --i1 <<= 2; --i2 <<= 2; // column major
898 for(int r=0; r<4; ++r, ++c) {
899 b1 = cos*c[i1] + sin*c[i2];
900 b2 = cos*c[i2] - sin*c[i1];
901 c[i1] = b1; c[i2] = b2;
902 }
903}
904
905////////////////////////////////////////////////////////////////////////////////
906/// Rotate in parent frame. Does optimised version of MultLeft.
907
909{
910 if(i1 == i2) return;
911
912 // Optimized version:
913 const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount);
914 Double_t b1, b2;
915 Double_t* C = fVals;
916 --i1; --i2;
917 for(int c=0; c<4; ++c, C+=4) {
918 b1 = cos*C[i1] - sin*C[i2];
919 b2 = cos*C[i2] + sin*C[i1];
920 C[i1] = b1; C[i2] = b2;
921 }
922}
923
924////////////////////////////////////////////////////////////////////////////////
925/// Transform passed 'vertex' by this matrix - converts local frame to parent
926
928{
930 for (UInt_t i = 0; i < 3; i++) {
931 vertex[i] = orig[0] * fVals[0+i] + orig[1] * fVals[4+i] +
932 orig[2] * fVals[8+i] + fVals[12+i];
933 }
934}
935
936////////////////////////////////////////////////////////////////////////////////
937/// Transpose the top left 3x3 matrix component along major diagonal
938/// Supported as currently incompatibility between TGeo and GL matrix
939/// layouts for this 3x3 only. To be resolved.
940
942{
943 // TODO: Move this fix to the TBuffer3D filling side and remove
944 //
945 // 0 4 8 12
946 // 1 5 9 13
947 // 2 6 10 14
948 // 3 7 11 15
949
950 Double_t temp = fVals[4];
951 fVals[4] = fVals[1];
952 fVals[1] = temp;
953 temp = fVals[8];
954 fVals[8] = fVals[2];
955 fVals[2] = temp;
956 temp = fVals[9];
957 fVals[9] = fVals[6];
958 fVals[6] = temp;
959}
960
961////////////////////////////////////////////////////////////////////////////////
962/// Invert the matrix, returns determinant.
963/// Copied from TMatrixFCramerInv.
964
966{
967 Double_t* M = fVals;
968
969 const Double_t det2_12_01 = M[1]*M[6] - M[5]*M[2];
970 const Double_t det2_12_02 = M[1]*M[10] - M[9]*M[2];
971 const Double_t det2_12_03 = M[1]*M[14] - M[13]*M[2];
972 const Double_t det2_12_13 = M[5]*M[14] - M[13]*M[6];
973 const Double_t det2_12_23 = M[9]*M[14] - M[13]*M[10];
974 const Double_t det2_12_12 = M[5]*M[10] - M[9]*M[6];
975 const Double_t det2_13_01 = M[1]*M[7] - M[5]*M[3];
976 const Double_t det2_13_02 = M[1]*M[11] - M[9]*M[3];
977 const Double_t det2_13_03 = M[1]*M[15] - M[13]*M[3];
978 const Double_t det2_13_12 = M[5]*M[11] - M[9]*M[7];
979 const Double_t det2_13_13 = M[5]*M[15] - M[13]*M[7];
980 const Double_t det2_13_23 = M[9]*M[15] - M[13]*M[11];
981 const Double_t det2_23_01 = M[2]*M[7] - M[6]*M[3];
982 const Double_t det2_23_02 = M[2]*M[11] - M[10]*M[3];
983 const Double_t det2_23_03 = M[2]*M[15] - M[14]*M[3];
984 const Double_t det2_23_12 = M[6]*M[11] - M[10]*M[7];
985 const Double_t det2_23_13 = M[6]*M[15] - M[14]*M[7];
986 const Double_t det2_23_23 = M[10]*M[15] - M[14]*M[11];
987
988
989 const Double_t det3_012_012 = M[0]*det2_12_12 - M[4]*det2_12_02 + M[8]*det2_12_01;
990 const Double_t det3_012_013 = M[0]*det2_12_13 - M[4]*det2_12_03 + M[12]*det2_12_01;
991 const Double_t det3_012_023 = M[0]*det2_12_23 - M[8]*det2_12_03 + M[12]*det2_12_02;
992 const Double_t det3_012_123 = M[4]*det2_12_23 - M[8]*det2_12_13 + M[12]*det2_12_12;
993 const Double_t det3_013_012 = M[0]*det2_13_12 - M[4]*det2_13_02 + M[8]*det2_13_01;
994 const Double_t det3_013_013 = M[0]*det2_13_13 - M[4]*det2_13_03 + M[12]*det2_13_01;
995 const Double_t det3_013_023 = M[0]*det2_13_23 - M[8]*det2_13_03 + M[12]*det2_13_02;
996 const Double_t det3_013_123 = M[4]*det2_13_23 - M[8]*det2_13_13 + M[12]*det2_13_12;
997 const Double_t det3_023_012 = M[0]*det2_23_12 - M[4]*det2_23_02 + M[8]*det2_23_01;
998 const Double_t det3_023_013 = M[0]*det2_23_13 - M[4]*det2_23_03 + M[12]*det2_23_01;
999 const Double_t det3_023_023 = M[0]*det2_23_23 - M[8]*det2_23_03 + M[12]*det2_23_02;
1000 const Double_t det3_023_123 = M[4]*det2_23_23 - M[8]*det2_23_13 + M[12]*det2_23_12;
1001 const Double_t det3_123_012 = M[1]*det2_23_12 - M[5]*det2_23_02 + M[9]*det2_23_01;
1002 const Double_t det3_123_013 = M[1]*det2_23_13 - M[5]*det2_23_03 + M[13]*det2_23_01;
1003 const Double_t det3_123_023 = M[1]*det2_23_23 - M[9]*det2_23_03 + M[13]*det2_23_02;
1004 const Double_t det3_123_123 = M[5]*det2_23_23 - M[9]*det2_23_13 + M[13]*det2_23_12;
1005
1006 const Double_t det = M[0]*det3_123_123 - M[4]*det3_123_023 +
1007 M[8]*det3_123_013 - M[12]*det3_123_012;
1008
1009 if(det == 0) {
1010 Warning("TGLMatrix::Invert", "matrix is singular.");
1011 return 0;
1012 }
1013
1014 const Double_t oneOverDet = 1.0/det;
1015 const Double_t mn1OverDet = - oneOverDet;
1016
1017 M[0] = det3_123_123 * oneOverDet;
1018 M[4] = det3_023_123 * mn1OverDet;
1019 M[8] = det3_013_123 * oneOverDet;
1020 M[12] = det3_012_123 * mn1OverDet;
1021
1022 M[1] = det3_123_023 * mn1OverDet;
1023 M[5] = det3_023_023 * oneOverDet;
1024 M[9] = det3_013_023 * mn1OverDet;
1025 M[13] = det3_012_023 * oneOverDet;
1026
1027 M[2] = det3_123_013 * oneOverDet;
1028 M[6] = det3_023_013 * mn1OverDet;
1029 M[10] = det3_013_013 * oneOverDet;
1030 M[14] = det3_012_013 * mn1OverDet;
1031
1032 M[3] = det3_123_012 * mn1OverDet;
1033 M[7] = det3_023_012 * oneOverDet;
1034 M[11] = det3_013_012 * mn1OverDet;
1035 M[15] = det3_012_012 * oneOverDet;
1036
1037 return det;
1038}
1039
1040////////////////////////////////////////////////////////////////////////////////
1041/// Multiply vector.
1042
1044{
1045 const Double_t* M = fVals;
1046 TGLVector3 r;
1047 r.X() = M[0]*v[0] + M[4]*v[1] + M[8]*v[2] + M[12]*w;
1048 r.Y() = M[1]*v[0] + M[5]*v[1] + M[9]*v[2] + M[13]*w;
1049 r.Z() = M[2]*v[0] + M[6]*v[1] + M[10]*v[2] + M[14]*w;
1050 return r;
1051}
1052
1053////////////////////////////////////////////////////////////////////////////////
1054/// Rotate vector. Translation is not applied.
1055
1057{
1058 const Double_t* M = fVals;
1059 TGLVector3 r;
1060 r.X() = M[0]*v[0] + M[4]*v[1] + M[8]*v[2];
1061 r.Y() = M[1]*v[0] + M[5]*v[1] + M[9]*v[2];
1062 r.Z() = M[2]*v[0] + M[6]*v[1] + M[10]*v[2];
1063 return r;
1064}
1065
1066////////////////////////////////////////////////////////////////////////////////
1067/// Multiply vector in-place.
1068
1070{
1071 const Double_t* M = fVals;
1072 Double_t r[3] = { v[0], v[1], v[2] };
1073 v.X() = M[0]*r[0] + M[4]*r[1] + M[8]*r[2] + M[12]*w;
1074 v.Y() = M[1]*r[0] + M[5]*r[1] + M[9]*r[2] + M[13]*w;
1075 v.Z() = M[2]*r[0] + M[6]*r[1] + M[10]*r[2] + M[14]*w;
1076}
1077
1078////////////////////////////////////////////////////////////////////////////////
1079/// Rotate vector in-place. Translation is not applied.
1080
1082{
1083 const Double_t* M = fVals;
1084 Double_t r[3] = { v[0], v[1], v[2] };
1085 v.X() = M[0]*r[0] + M[4]*r[1] + M[8]*r[2];
1086 v.Y() = M[1]*r[0] + M[5]*r[1] + M[9]*r[2];
1087 v.Z() = M[2]*r[0] + M[6]*r[1] + M[10]*r[2];
1088}
1089
1090////////////////////////////////////////////////////////////////////////////////
1091/// Get local axis scaling factors
1092
1094{
1095 TGLVector3 x(fVals[0], fVals[1], fVals[2]);
1096 TGLVector3 y(fVals[4], fVals[5], fVals[6]);
1097 TGLVector3 z(fVals[8], fVals[9], fVals[10]);
1098 return TGLVector3(x.Mag(), y.Mag(), z.Mag());
1099}
1100
1101////////////////////////////////////////////////////////////////////////////////
1102/// Return true if matrix is to be considered a scaling matrix
1103/// for rendering.
1104
1106{
1107 Double_t ss;
1108 ss = fVals[0]*fVals[0] + fVals[1]*fVals[1] + fVals[2]*fVals[2];
1109 if (ss < 0.8 || ss > 1.2) return kTRUE;
1110 ss = fVals[4]*fVals[4] + fVals[5]*fVals[5] + fVals[6]*fVals[6];
1111 if (ss < 0.8 || ss > 1.2) return kTRUE;
1112 ss = fVals[8]*fVals[8] + fVals[9]*fVals[9] + fVals[10]*fVals[10];
1113 if (ss < 0.8 || ss > 1.2) return kTRUE;
1114 return kFALSE;
1115}
1116
1117////////////////////////////////////////////////////////////////////////////////
1118/// Output 16 matrix components to std::cout
1119///
1120/// 0 4 8 12
1121/// 1 5 9 13
1122/// 2 6 10 14
1123/// 3 7 11 15
1124///
1125
1127{
1128 std::cout.precision(6);
1129 for (Int_t x = 0; x < 4; x++) {
1130 std::cout << "[ ";
1131 for (Int_t y = 0; y < 4; y++) {
1132 std::cout << fVals[y*4 + x] << " ";
1133 }
1134 std::cout << "]" << std::endl;
1135 }
1136}
1137
1138
1139/** \class TGLColor
1140\ingroup opengl
1141Class encapsulating color information in preferred GL format - an
1142array of four unsigned bytes.
1143Color index is also cached for easier interfacing with the
1144traditional ROOT graphics.
1145*/
1146
1147
1148////////////////////////////////////////////////////////////////////////////////
1149/// Default constructor. Color is initialized to black.
1150
1152{
1153 fRGBA[0] = fRGBA[1] = fRGBA[2] = 0;
1154 fRGBA[3] = 255;
1155 fIndex = -1;
1156}
1157
1158////////////////////////////////////////////////////////////////////////////////
1159/// Constructor from Int_t values.
1160
1162{
1163 SetColor(r, g, b, a);
1164}
1165
1166////////////////////////////////////////////////////////////////////////////////
1167/// Constructor from Float_t values.
1168
1173
1174////////////////////////////////////////////////////////////////////////////////
1175/// Constructor from color-index and transparency.
1176
1181
1182////////////////////////////////////////////////////////////////////////////////
1183/// copy constructor
1184
1186{
1187 fRGBA[0] = c.fRGBA[0];
1188 fRGBA[1] = c.fRGBA[1];
1189 fRGBA[2] = c.fRGBA[2];
1190 fRGBA[3] = c.fRGBA[3];
1191 fIndex = c.fIndex;
1192}
1193
1194////////////////////////////////////////////////////////////////////////////////
1195/// Assignment operator.
1196
1198{
1199 fRGBA[0] = c.fRGBA[0];
1200 fRGBA[1] = c.fRGBA[1];
1201 fRGBA[2] = c.fRGBA[2];
1202 fRGBA[3] = c.fRGBA[3];
1203 fIndex = c.fIndex;
1204 return *this;
1205}
1206
1207////////////////////////////////////////////////////////////////////////////////
1208/// Returns color-index representing the color.
1209
1211{
1212 if (fIndex == -1)
1213 fIndex = TColor::GetColor(fRGBA[0], fRGBA[1], fRGBA[2]);
1214 return fIndex;
1215}
1216
1217////////////////////////////////////////////////////////////////////////////////
1218/// Returns transparency value.
1219
1221{
1222 return TMath::Nint(100.0*(1.0 - fRGBA[3]/255.0));
1223}
1224
1225////////////////////////////////////////////////////////////////////////////////
1226/// Set color with Int_t values.
1227
1229{
1230 fRGBA[0] = r;
1231 fRGBA[1] = g;
1232 fRGBA[2] = b;
1233 fRGBA[3] = a;
1234 fIndex = -1;
1235}
1236
1237////////////////////////////////////////////////////////////////////////////////
1238/// Set color with Float_t values.
1239
1241{
1242 fRGBA[0] = (UChar_t)(255*r);
1243 fRGBA[1] = (UChar_t)(255*g);
1244 fRGBA[2] = (UChar_t)(255*b);
1245 fRGBA[3] = (UChar_t)(255*a);
1246 fIndex = -1;
1247}
1248
1249////////////////////////////////////////////////////////////////////////////////
1250/// Set color by color-index. Alpha is not changed.
1251/// If color_index is not valid, color is set to magenta.
1252
1254{
1256 if (c)
1257 {
1258 fRGBA[0] = (UChar_t)(255*c->GetRed());
1259 fRGBA[1] = (UChar_t)(255*c->GetGreen());
1260 fRGBA[2] = (UChar_t)(255*c->GetBlue());
1262 }
1263 else
1264 {
1265 // Set to magenta.
1266 fRGBA[0] = 255;
1267 fRGBA[1] = 0;
1268 fRGBA[2] = 255;
1269 fIndex = -1;
1270 }
1271}
1272
1273////////////////////////////////////////////////////////////////////////////////
1274/// Set color by color-index and alpha from the transparency.
1275/// If color_index is not valid, color is set to magenta.
1276
1278{
1279 UChar_t alpha = (255*(100 - transparency))/100;
1280
1282 if (c)
1283 {
1284 fRGBA[0] = (UChar_t)(255*c->GetRed());
1285 fRGBA[1] = (UChar_t)(255*c->GetGreen());
1286 fRGBA[2] = (UChar_t)(255*c->GetBlue());
1287 fRGBA[3] = alpha;
1289 }
1290 else
1291 {
1292 // Set to magenta.
1293 fRGBA[0] = 255;
1294 fRGBA[1] = 0;
1295 fRGBA[2] = 255;
1296 fRGBA[3] = alpha;
1297 fIndex = -1;
1298 return;
1299 }
1300}
1301
1302////////////////////////////////////////////////////////////////////////////////
1303/// Set alpha from the transparency.
1304
1306{
1307 fRGBA[3] = (255*(100 - transparency))/100;
1308}
1309
1310////////////////////////////////////////////////////////////////////////////////
1311/// Return string describing the color.
1312
1314{
1315 return TString::Format("rgba:%02hhx/%02hhx/%02hhx/%02hhx",
1316 fRGBA[0], fRGBA[1], fRGBA[2], fRGBA[3]);
1317}
1318
1319
1320/** \class TGLColorSet
1321\ingroup opengl
1322Class encapsulating a set of colors used throughout standard rendering.
1323*/
1324
1325
1326////////////////////////////////////////////////////////////////////////////////
1327/// Constructor. Sets default for dark background.
1328
1333
1334////////////////////////////////////////////////////////////////////////////////
1335/// Copy constructor
1336
1338{
1341 fOutline = s.fOutline;
1342 fMarkup = s.fMarkup;
1343 for (Int_t i = 0; i < 5; ++i)
1344 fSelection[i] = s.fSelection[i];
1345}
1346
1347////////////////////////////////////////////////////////////////////////////////
1348/// Assignment operator.
1349
1351{
1354 fOutline = s.fOutline;
1355 fMarkup = s.fMarkup;
1356 for (Int_t i = 0; i < 5; ++i)
1357 fSelection[i] = s.fSelection[i];
1358 return *this;
1359}
1360
1361////////////////////////////////////////////////////////////////////////////////
1362/// Set defaults for dark (black) background.
1363
1365{
1366 fBackground .SetColor(0, 0, 0);
1367 fForeground .SetColor(255, 255, 255);
1368 fOutline .SetColor(240, 255, 240);
1369 fMarkup .SetColor(200, 200, 200);
1370
1371 fSelection[0].SetColor( 0, 0, 0);
1372 fSelection[1].SetColor(255, 220, 220);
1373 fSelection[2].SetColor(255, 220, 220);
1374 fSelection[3].SetColor(200, 200, 255);
1375 fSelection[4].SetColor(200, 200, 255);
1376}
1377
1378////////////////////////////////////////////////////////////////////////////////
1379/// Set defaults for light (white) background.
1380
1382{
1383 fBackground .SetColor(255, 255, 255);
1384 fForeground .SetColor(0, 0, 0);
1385 fOutline .SetColor(0, 0, 0);
1386 fMarkup .SetColor(55, 55, 55);
1387
1388 fSelection[0].SetColor(0, 0, 0);
1389 fSelection[1].SetColor(200, 100, 100);
1390 fSelection[2].SetColor(200, 100, 100);
1391 fSelection[3].SetColor(100, 100, 200);
1392 fSelection[4].SetColor(100, 100, 200);
1393}
1394
1395
1396/** \class TGLUtil
1397\ingroup opengl
1398Wrapper class for various misc static functions - error checking, draw helpers etc.
1399*/
1400
1401
1403UInt_t TGLUtil::fgDrawQuality = fgDefaultDrawQuality;
1405
1410
1414
1417
1420
1421const UChar_t TGLUtil::fgRed[4] = { 230, 0, 0, 255 };
1422const UChar_t TGLUtil::fgGreen[4] = { 0, 230, 0, 255 };
1423const UChar_t TGLUtil::fgBlue[4] = { 0, 0, 230, 255 };
1424const UChar_t TGLUtil::fgYellow[4] = { 210, 210, 0, 255 };
1425const UChar_t TGLUtil::fgWhite[4] = { 255, 255, 255, 255 };
1426const UChar_t TGLUtil::fgGrey[4] = { 128, 128, 128, 100 };
1427
1428#ifndef CALLBACK
1429#define CALLBACK
1430#endif
1431
1432extern "C"
1433{
1434#if defined(__APPLE_CC__) && __APPLE_CC__ > 4000 && __APPLE_CC__ < 5450 && !defined(__INTEL_COMPILER)
1435 typedef GLvoid (*tessfuncptr_t)(...);
1436#elif defined(__linux__) || defined(__FreeBSD__) || defined( __OpenBSD__ ) || defined(__sun) || defined (__CYGWIN__) || defined (__APPLE__)
1437 typedef GLvoid (*tessfuncptr_t)();
1438#elif defined (WIN32)
1439 typedef GLvoid (CALLBACK *tessfuncptr_t)();
1440#else
1441 #error "Error - need to define type tessfuncptr_t for this platform/compiler"
1442#endif
1443}
1444
1445namespace
1446{
1447
1448class TGLTesselatorWrap
1449{
1450protected:
1451
1452public:
1453 GLUtesselator *fTess;
1454
1455 TGLTesselatorWrap(tessfuncptr_t vertex_func) : fTess(nullptr)
1456 {
1457 fTess = gluNewTess();
1458 if (!fTess)
1459 throw std::bad_alloc();
1460
1461#if defined(__GNUC__) && __GNUC__ >= 8
1462#pragma GCC diagnostic push
1463#pragma GCC diagnostic ignored "-Wcast-function-type"
1464#endif
1465
1469
1470#if defined(__GNUC__) && __GNUC__ >= 8
1471#pragma GCC diagnostic pop
1472#endif
1473
1474 }
1475
1476 virtual ~TGLTesselatorWrap()
1477 {
1478 if (fTess)
1479 gluDeleteTess(fTess);
1480 }
1481};
1482
1483}
1484
1485////////////////////////////////////////////////////////////////////////////////
1486/// Returns a tesselator for direct drawing when using 3-vertices with
1487/// single precision.
1488
1490{
1491
1492#if defined(__GNUC__) && __GNUC__ >= 8
1493#pragma GCC diagnostic push
1494#pragma GCC diagnostic ignored "-Wcast-function-type"
1495#endif
1496
1497 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex3fv);
1498
1499#if defined(__GNUC__) && __GNUC__ >= 8
1500#pragma GCC diagnostic pop
1501#endif
1502
1503 return singleton.fTess;
1504}
1505
1506////////////////////////////////////////////////////////////////////////////////
1507/// Returns a tesselator for direct drawing when using 4-vertices with
1508/// single precision.
1509
1511{
1512
1513#if defined(__GNUC__) && __GNUC__ >= 8
1514#pragma GCC diagnostic push
1515#pragma GCC diagnostic ignored "-Wcast-function-type"
1516#endif
1517
1518 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex4fv);
1519
1520#if defined(__GNUC__) && __GNUC__ >= 8
1521#pragma GCC diagnostic pop
1522#endif
1523
1524 return singleton.fTess;
1525}
1526
1527////////////////////////////////////////////////////////////////////////////////
1528/// Returns a tesselator for direct drawing when using 3-vertices with
1529/// double precision.
1530
1532{
1533
1534#if defined(__GNUC__) && __GNUC__ >= 8
1535#pragma GCC diagnostic push
1536#pragma GCC diagnostic ignored "-Wcast-function-type"
1537#endif
1538
1539 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex3dv);
1540
1541#if defined(__GNUC__) && __GNUC__ >= 8
1542#pragma GCC diagnostic pop
1543#endif
1544
1545 return singleton.fTess;
1546}
1547
1548////////////////////////////////////////////////////////////////////////////////
1549/// Returns a tesselator for direct drawing when using 4-vertices with
1550/// double precision.
1551
1553{
1554
1555#if defined(__GNUC__) && __GNUC__ >= 8
1556#pragma GCC diagnostic push
1557#pragma GCC diagnostic ignored "-Wcast-function-type"
1558#endif
1559
1560 static TGLTesselatorWrap singleton((tessfuncptr_t) glVertex4dv);
1561
1562#if defined(__GNUC__) && __GNUC__ >= 8
1563#pragma GCC diagnostic pop
1564#endif
1565
1566 return singleton.fTess;
1567}
1568
1569////////////////////////////////////////////////////////////////////////////////
1570/// Initialize globals that require other libraries to be initialized.
1571/// This is called from TGLWidget creation function.
1572
1574{
1575 static Bool_t init_done = kFALSE;
1576 if (init_done) return;
1577 init_done = kTRUE;
1578
1579 fgScreenScalingFactor = gVirtualX->GetOpenGLScalingFactor();
1580
1581 if (strcmp(gEnv->GetValue("OpenGL.PointLineScalingFactor", "native"), "native") == 0)
1582 {
1584 }
1585 else
1586 {
1587 fgPointLineScalingFactor = gEnv->GetValue("OpenGL.PointLineScalingFactor", 1.0);
1588 }
1589
1590 fgPickingRadius = TMath::Nint(gEnv->GetValue("OpenGL.PickingRadius", 3.0) * TMath::Sqrt(fgScreenScalingFactor));
1591}
1592
1593////////////////////////////////////////////////////////////////////////////////
1594///static: get draw quality
1595
1600
1601////////////////////////////////////////////////////////////////////////////////
1602///static: set draw quality
1603
1608
1609////////////////////////////////////////////////////////////////////////////////
1610///static: reset draw quality
1611
1616
1617////////////////////////////////////////////////////////////////////////////////
1618///static: get default draw quality
1619
1624
1625////////////////////////////////////////////////////////////////////////////////
1626///static: set default draw quality
1627
1632
1633////////////////////////////////////////////////////////////////////////////////
1634/// Check current GL error state, outputting details via ROOT
1635/// Error method if one
1636
1638{
1640 const GLubyte *errString;
1641
1642 if ((errCode = glGetError()) != GL_NO_ERROR) {
1644 if (loc) {
1645 Error(loc, "GL Error %s", (const char *)errString);
1646 } else {
1647 Error("TGLUtil::CheckError", "GL Error %s", (const char *)errString);
1648 }
1649 }
1650 return errCode;
1651}
1652
1653/******************************************************************************/
1654// Color wrapping functions
1655/******************************************************************************/
1656
1657////////////////////////////////////////////////////////////////////////////////
1658/// Prevent further color changes.
1659
1661{
1662 return ++fgColorLockCount;
1663}
1664
1665////////////////////////////////////////////////////////////////////////////////
1666/// Allow color changes.
1667
1669{
1670 if (fgColorLockCount)
1672 else
1673 Error("TGLUtil::UnlockColor", "fgColorLockCount already 0.");
1674 return fgColorLockCount;
1675}
1676
1677////////////////////////////////////////////////////////////////////////////////
1678/// Returns true if color lock-count is greater than 0.
1679
1681{
1682 return fgColorLockCount > 0;
1683}
1684
1685////////////////////////////////////////////////////////////////////////////////
1686/// Set color from TGLColor.
1687
1688void TGLUtil::Color(const TGLColor& color)
1689{
1690 if (fgColorLockCount == 0) glColor4ubv(color.CArr());
1691}
1692
1693////////////////////////////////////////////////////////////////////////////////
1694/// Set color from TGLColor and alpha value.
1695
1696void TGLUtil::ColorAlpha(const TGLColor& color, UChar_t alpha)
1697{
1698 if (fgColorLockCount == 0)
1699 {
1700 glColor4ub(color.GetRed(), color.GetGreen(), color.GetBlue(), alpha);
1701 }
1702}
1703
1704////////////////////////////////////////////////////////////////////////////////
1705/// Set color from TGLColor and alpha value.
1706
1707void TGLUtil::ColorAlpha(const TGLColor& color, Float_t alpha)
1708{
1709 if (fgColorLockCount == 0)
1710 {
1711 glColor4ub(color.GetRed(), color.GetGreen(), color.GetBlue(), (UChar_t)(255*alpha));
1712 }
1713}
1714
1715////////////////////////////////////////////////////////////////////////////////
1716/// Set color from color_index and GL-style alpha (default 1).
1717
1719{
1720 if (fgColorLockCount == 0) {
1721 if (color_index < 0)
1722 color_index = 1;
1724 if (c)
1725 glColor4f(c->GetRed(), c->GetGreen(), c->GetBlue(), alpha);
1726 }
1727}
1728
1729////////////////////////////////////////////////////////////////////////////////
1730/// Set color from color_index and ROOT-style transparency (default 0).
1731
1733{
1734 if (fgColorLockCount == 0) {
1735 if (color_index < 0)
1736 color_index = 1;
1738 if (c)
1739 glColor4f(c->GetRed(), c->GetGreen(), c->GetBlue(), 1.0f - 0.01f*transparency);
1740 }
1741}
1742
1743////////////////////////////////////////////////////////////////////////////////
1744/// Wrapper for glColor3ub.
1745
1747{
1748 if (fgColorLockCount == 0) glColor3ub(r, g, b);
1749}
1750
1751////////////////////////////////////////////////////////////////////////////////
1752/// Wrapper for glColor4ub.
1753
1755{
1756 if (fgColorLockCount == 0) glColor4ub(r, g, b, a);
1757}
1758
1759////////////////////////////////////////////////////////////////////////////////
1760/// Wrapper for glColor3ubv.
1761
1763{
1764 if (fgColorLockCount == 0) glColor3ubv(rgb);
1765}
1766
1767////////////////////////////////////////////////////////////////////////////////
1768/// Wrapper for glColor4ubv.
1769
1771{
1773}
1774
1775////////////////////////////////////////////////////////////////////////////////
1776/// Wrapper for glColor3f.
1777
1779{
1780 if (fgColorLockCount == 0) glColor3f(r, g, b);
1781}
1782
1783////////////////////////////////////////////////////////////////////////////////
1784/// Wrapper for glColor4f.
1785
1787{
1788 if (fgColorLockCount == 0) glColor4f(r, g, b, a);
1789}
1790
1791////////////////////////////////////////////////////////////////////////////////
1792/// Wrapper for glColor3fv.
1793
1795{
1796 if (fgColorLockCount == 0) glColor3fv(rgb);
1797}
1798
1799////////////////////////////////////////////////////////////////////////////////
1800/// Wrapper for glColor4fv.
1801
1803{
1804 if (fgColorLockCount == 0) glColor4fv(rgba);
1805}
1806
1807/******************************************************************************/
1808// Coordinate conversion and extra scaling (needed for osx retina)
1809/******************************************************************************/
1810
1811////////////////////////////////////////////////////////////////////////////////
1812/// Convert from point/screen coordinates to GL viewport coordinates.
1813
1815{
1816 if (fgScreenScalingFactor != 1.0)
1817 {
1820 }
1821}
1822
1823////////////////////////////////////////////////////////////////////////////////
1824/// Convert from point/screen coordinates to GL viewport coordinates.
1825
1836
1837////////////////////////////////////////////////////////////////////////////////
1838/// Returns scaling factor between screen points and GL viewport pixels.
1839/// This is what is returned by gVirtualX->GetOpenGLScalingFactor() but is
1840/// cached here to avoid a virtual function call as it is used quite often in
1841/// TGLPhysical shape when drawing the selection highlight.
1842
1847
1848////////////////////////////////////////////////////////////////////////////////
1849/// Return extra scaling factor for points and lines.
1850/// By default this is set to the same value as ScreenScalingFactor to keep
1851/// the same appearance. To override use rootrc entry, e.g.:
1852/// OpenGL.PointLineScalingFactor: 1.0
1853
1858
1859////////////////////////////////////////////////////////////////////////////////
1860/// Returns picking radius.
1861
1866
1867/******************************************************************************/
1868// Control for scaling of point-size and line-width.
1869/******************************************************************************/
1870
1871////////////////////////////////////////////////////////////////////////////////
1872/// Get global point-size scale.
1873
1878
1879////////////////////////////////////////////////////////////////////////////////
1880/// Set global point-size scale.
1881
1886
1887////////////////////////////////////////////////////////////////////////////////
1888/// Returns global line-width scale.
1889
1894
1895////////////////////////////////////////////////////////////////////////////////
1896/// Set global line-width scale.
1897
1902
1903////////////////////////////////////////////////////////////////////////////////
1904/// Set the point-size, taking the global scaling into account.
1905/// Wrapper for glPointSize.
1906
1912
1913////////////////////////////////////////////////////////////////////////////////
1914/// Set the line-width, taking the global scaling into account.
1915/// Wrapper for glLineWidth.
1916
1922
1923////////////////////////////////////////////////////////////////////////////////
1924/// Get the point-size, taking the global scaling into account.
1925
1927{
1928 return fgPointSize;
1929}
1930
1931////////////////////////////////////////////////////////////////////////////////
1932/// Get the line-width, taking the global scaling into account.
1933
1935{
1936 return fgLineWidth;
1937}
1938
1939/******************************************************************************/
1940// Rendering of polymarkers and lines from logical-shapes.
1941/******************************************************************************/
1942
1944{
1945 // Extend pick region for large point-sizes or line-widths.
1946
1948 glPushMatrix();
1949 Float_t pm[16];
1951 for (Int_t i=0; i<=12; i+=4) {
1952 pm[i] *= scale; pm[i+1] *= scale;
1953 }
1956}
1957
1959{
1960 // End extension of the pick region.
1961
1963 glPopMatrix();
1965}
1966
1967////////////////////////////////////////////////////////////////////////////////
1968/// Render polymarkers at points specified by p-array.
1969/// Supports point and cross-like styles.
1970
1972 Float_t* p, Int_t n,
1975{
1976 if (n == 0) return;
1977
1979
1982
1983 Int_t s = marker.GetMarkerStyle();
1984 if (s == 2 || s == 3 || s == 5 || s == 28)
1985 RenderCrosses(marker, p, n, sec_selection);
1986 else
1988
1989 glPopAttrib();
1990}
1991
1992////////////////////////////////////////////////////////////////////////////////
1993/// Render polymarkers at points specified by p-array.
1994/// Supports point and cross-like styles.
1995/// Color is set externally. Lighting is disabled externally.
1996
1997void TGLUtil::RenderPolyMarkers(const TAttMarker &marker, const std::vector<Double_t> &points,
1999{
2000 const Int_t s = marker.GetMarkerStyle();
2001 if (s == 2 || s == 3 || s == 5 || s == 28)
2002 RenderCrosses(marker, points, dX, dY, dZ);
2003 else
2004 RenderPoints(marker, points);
2005}
2006
2007////////////////////////////////////////////////////////////////////////////////
2008/// Render markers as circular or square points.
2009/// Color is never changed.
2010
2012 Float_t* op, Int_t n,
2015{
2016 Int_t style = marker.GetMarkerStyle();
2017 Float_t size = 5*marker.GetMarkerSize();
2018 if (style == 4 || style == 20 || style == 24)
2019 {
2021 if (style == 4 || style == 24) {
2025 }
2026 }
2027 else
2028 {
2030 if (style == 1) size = 1;
2031 else if (style == 6) size = 2;
2032 else if (style == 7) size = 3;
2033 }
2035
2036 // During selection extend picking region for large point-sizes.
2038 if (changePM)
2040
2041 Float_t* p = op;
2042 if (sec_selection)
2043 {
2044 glPushName(0);
2045 for (Int_t i=0; i<n; ++i, p+=3)
2046 {
2047 glLoadName(i);
2048 glBegin(GL_POINTS);
2049 glVertex3fv(p);
2050 glEnd();
2051 }
2052 glPopName();
2053 }
2054 else
2055 {
2057 glVertexPointer(3, GL_FLOAT, 0, p);
2059 { // Circumvent bug in ATI's linux drivers.
2060 Int_t nleft = n;
2061 Int_t ndone = 0;
2062 const Int_t maxChunk = 8192;
2063 while (nleft > maxChunk)
2064 {
2065 glDrawArrays(GL_POINTS, ndone, maxChunk);
2066 nleft -= maxChunk;
2067 ndone += maxChunk;
2068 }
2069 glDrawArrays(GL_POINTS, ndone, nleft);
2070 }
2072 }
2073
2074 if (changePM)
2076}
2077
2078////////////////////////////////////////////////////////////////////////////////
2079/// Render markers as circular or square points.
2080/// Color is never changed.
2081
2082void TGLUtil::RenderPoints(const TAttMarker& marker, const std::vector<Double_t> &points)
2083{
2084 const Int_t style = marker.GetMarkerStyle();
2085 Float_t size = 5 * marker.GetMarkerSize();
2086
2087 if (style == 4 || style == 20 || style == 24)
2088 {
2090 if (style == 4 || style == 24) {
2094 }
2095 }
2096 else
2097 {
2099 if (style == 1) size = 1;
2100 else if (style == 6) size = 2;
2101 else if (style == 7) size = 3;
2102 }
2103
2105
2106 glVertexPointer(3, GL_DOUBLE, 0, &points[0]);
2108
2109 // Circumvent bug in ATI's linux drivers.
2110 Int_t nleft = points.size() / 3;
2111 Int_t ndone = 0;
2112 const Int_t maxChunk = 8192;
2113 while (nleft > maxChunk)
2114 {
2115 glDrawArrays(GL_POINTS, ndone, maxChunk);
2116 nleft -= maxChunk;
2117 ndone += maxChunk;
2118 }
2119
2120 if (nleft > 0)
2121 glDrawArrays(GL_POINTS, ndone, nleft);
2122
2124 glPointSize(1.f);
2125}
2126
2127////////////////////////////////////////////////////////////////////////////////
2128/// Render markers as crosses.
2129/// Color is never changed.
2130
2132 Float_t* op, Int_t n,
2134{
2135 if (marker.GetMarkerStyle() == 28)
2136 {
2140 }
2141 else
2142 {
2145 }
2146
2147 // cross dim
2148 const Float_t d = 2*marker.GetMarkerSize();
2149 Float_t* p = op;
2150 if (sec_selection)
2151 {
2152 glPushName(0);
2153 for (Int_t i=0; i<n; ++i, p+=3)
2154 {
2155 glLoadName(i);
2156 glBegin(GL_LINES);
2157 glVertex3f(p[0]-d, p[1], p[2]); glVertex3f(p[0]+d, p[1], p[2]);
2158 glVertex3f(p[0], p[1]-d, p[2]); glVertex3f(p[0], p[1]+d, p[2]);
2159 glVertex3f(p[0], p[1], p[2]-d); glVertex3f(p[0], p[1], p[2]+d);
2160 glEnd();
2161 }
2162 glPopName();
2163 }
2164 else
2165 {
2166 glBegin(GL_LINES);
2167 for (Int_t i=0; i<n; ++i, p+=3)
2168 {
2169 glVertex3f(p[0]-d, p[1], p[2]); glVertex3f(p[0]+d, p[1], p[2]);
2170 glVertex3f(p[0], p[1]-d, p[2]); glVertex3f(p[0], p[1]+d, p[2]);
2171 glVertex3f(p[0], p[1], p[2]-d); glVertex3f(p[0], p[1], p[2]+d);
2172 }
2173 glEnd();
2174 }
2175
2176 // Anti-flickering -- when crosses get too small they
2177 // appear / disappear randomly.
2178 {
2181
2183 glVertexPointer(3, GL_FLOAT, 0, op);
2185 { // Circumvent bug in ATI's linux drivers.
2186 Int_t nleft = n;
2187 Int_t ndone = 0;
2188 const Int_t maxChunk = 8192;
2189 while (nleft > maxChunk)
2190 {
2191 glDrawArrays(GL_POINTS, ndone, maxChunk);
2192 nleft -= maxChunk;
2193 ndone += maxChunk;
2194 }
2195 glDrawArrays(GL_POINTS, ndone, nleft);
2196 }
2198 }
2199}
2200
2201////////////////////////////////////////////////////////////////////////////////
2202/// Render markers as crosses.
2203/// Color is never changed.
2204
2205void TGLUtil::RenderCrosses(const TAttMarker& marker, const std::vector<Double_t> &points,
2207{
2208 if (marker.GetMarkerStyle() == 28)
2209 {
2212 glLineWidth(2.f);
2213 }
2214 else
2215 {
2217 glLineWidth(1.f);
2218 }
2219
2220 typedef std::vector<Double_t>::size_type size_type;
2221
2222 glBegin(GL_LINES);
2223
2224 for (size_type i = 0; i < points.size(); i += 3) {
2225 const Double_t *p = &points[i];
2226 glVertex3f(p[0] - dX, p[1], p[2]); glVertex3f(p[0] + dX, p[1], p[2]);
2227 glVertex3f(p[0], p[1] - dY, p[2]); glVertex3f(p[0], p[1] + dY, p[2]);
2228 glVertex3f(p[0], p[1], p[2] - dZ); glVertex3f(p[0], p[1], p[2] + dZ);
2229 }
2230
2231 glEnd();
2232
2233 if (marker.GetMarkerStyle() == 28) {
2236 glLineWidth(1.f);
2237 }
2238}
2239
2240////////////////////////////////////////////////////////////////////////////////
2241/// Render poly-line as specified by the p-array.
2242
2244 Float_t* p, Int_t n,
2246{
2247 if (n == 0) return;
2248
2250
2251 Float_t* tp = p;
2252 glBegin(GL_LINE_STRIP);
2253 for (Int_t i=0; i<n; ++i, tp+=3)
2254 glVertex3fv(tp);
2255 glEnd();
2256
2258}
2259
2260////////////////////////////////////////////////////////////////////////////////
2261/// Setup drawing parameters according to passed TAttLine.
2262
2265{
2267
2269 TGLUtil::ColorTransparency(aline.GetLineColor(), transp);
2270 TGLUtil::LineWidth(aline.GetLineWidth());
2271 if (aline.GetLineStyle() > 1)
2272 {
2273 // Int_t fac = 1;
2274 UShort_t pat = 0xffff;
2275 switch (aline.GetLineStyle()) {
2276 case 2: pat = 0x3333; break;
2277 case 3: pat = 0x5555; break;
2278 case 4: pat = 0xf040; break;
2279 case 5: pat = 0xf4f4; break;
2280 case 6: pat = 0xf111; break;
2281 case 7: pat = 0xf0f0; break;
2282 case 8: pat = 0xff11; break;
2283 case 9: pat = 0x3fff; break;
2284 case 10: pat = 0x08ff; /* fac = 2; */ break;
2285 }
2286
2287 glLineStipple(1, pat);
2289 }
2290
2291 // During selection extend picking region for large line-widths.
2294}
2295
2296////////////////////////////////////////////////////////////////////////////////
2297/// Restore previous line drawing state.
2298
2306
2307/******************************************************************************/
2308// Rendering atoms used by TGLViewer / TGScene.
2309/******************************************************************************/
2310
2311////////////////////////////////////////////////////////////////////////////////
2312/// Set basic draw colors from 4 component 'rgba'
2313/// Used by other TGLUtil drawing routines
2314///
2315/// Sets basic (unlit) color - glColor
2316/// and also GL materials (see OpenGL docs) thus:
2317///
2318/// diffuse : rgba
2319/// ambient : 0.0 0.0 0.0 1.0
2320/// specular : 0.6 0.6 0.6 1.0
2321/// emission : rgba/4.0
2322/// shininess: 60.0
2323///
2324/// emission is set so objects with no lights (but lighting still enabled)
2325/// are partially visible
2326
2328{
2329
2330 // Util function to setup GL color for both unlit and lit material
2331 Float_t rgba[4] = {rgbai[0]/255.f, rgbai[1]/255.f, rgbai[2]/255.f, rgbai[3]/255.f};
2332 Float_t ambient[4] = {0.0, 0.0, 0.0, 1.0};
2333 Float_t specular[4] = {0.6, 0.6, 0.6, 1.0};
2334 Float_t emission[4] = {rgba[0]/4.f, rgba[1]/4.f, rgba[2]/4.f, rgba[3]};
2335
2342}
2343
2344////////////////////////////////////////////////////////////////////////////////
2345/// Draw sphere, centered on vertex 'position', with radius 'radius',
2346/// color 'rgba'
2347
2349 const UChar_t rgba[4])
2350{
2351 static TGLQuadric quad;
2353 glPushMatrix();
2354 glTranslated(position.X(), position.Y(), position.Z());
2356 glPopMatrix();
2357}
2358
2359////////////////////////////////////////////////////////////////////////////////
2360/// Draw thick line (tube) defined by 'line', with head at end shape
2361/// 'head' - box/arrow/none, (head) size 'size', color 'rgba'
2362
2364 const UChar_t rgba[4])
2365{
2366 DrawLine(line.Start(), line.Vector(), head, size, rgba);
2367}
2368
2369////////////////////////////////////////////////////////////////////////////////
2370/// Draw thick line (tube) running from 'start', length 'vector',
2371/// with head at end of shape 'head' - box/arrow/none,
2372/// (head) size 'size', color 'rgba'
2373
2374void TGLUtil::DrawLine(const TGLVertex3 & start, const TGLVector3 & vector,
2375 ELineHeadShape head, Double_t size, const UChar_t rgba[4])
2376{
2377 static TGLQuadric quad;
2378
2379 // Draw 3D line (tube) with optional head shape
2381 glPushMatrix();
2382 TGLMatrix local(start, vector);
2383 glMultMatrixd(local.CArr());
2384
2386 if (head == kLineHeadNone) {
2387 headHeight = 0.0;
2388 } else if (head == kLineHeadArrow) {
2389 headHeight = size*2.0;
2390 } else if (head == kLineHeadBox) {
2391 headHeight = size*1.4;
2392 }
2393
2394 // Line (tube) component
2395 gluCylinder(quad.Get(), 0.25*size, 0.25*size, vector.Mag() - headHeight, fgDrawQuality, 1);
2397 gluDisk(quad.Get(), 0.0, 0.25*size, fgDrawQuality, 1);
2398
2399 glTranslated(0.0, 0.0, vector.Mag() - headHeight); // Shift down local Z to end of line
2400
2401 if (head == kLineHeadNone) {
2402 // Cap end of line
2404 gluDisk(quad.Get(), 0.0, size/4.0, fgDrawQuality, 1);
2405 }
2406 else if (head == kLineHeadArrow) {
2407 // Arrow base / end line cap
2408 gluDisk(quad.Get(), 0.0, size, fgDrawQuality, 1);
2409 // Arrow cone
2411 gluCylinder(quad.Get(), size, 0.0, headHeight, fgDrawQuality, 1);
2412 } else if (head == kLineHeadBox) {
2413 // Box
2414 // TODO: Drawing box should be simpler - maybe make
2415 // a static helper which BB + others use.
2416 // Single face tesselation - ugly lighting
2418 TGLBoundingBox box(TGLVertex3(-size*.7, -size*.7, 0.0),
2419 TGLVertex3(size*.7, size*.7, headHeight));
2420 box.Draw(kTRUE);
2421 }
2422 glPopMatrix();
2423}
2424
2425////////////////////////////////////////////////////////////////////////////////
2426/// Draw ring, centered on 'center', lying on plane defined by 'center' & 'normal'
2427/// of outer radius 'radius', color 'rgba'
2428
2429void TGLUtil::DrawRing(const TGLVertex3 & center, const TGLVector3 & normal,
2430 Double_t radius, const UChar_t rgba[4])
2431{
2432 static TGLQuadric quad;
2433
2434 // Draw a ring, round vertex 'center', lying on plane defined by 'normal' vector
2435 // Radius defines the outer radius
2437
2439 Double_t width = radius*0.05;
2441
2442 // Shift into local system, looking down 'normal' vector, origin at center
2443 glPushMatrix();
2444 TGLMatrix local(center, normal);
2445 glMultMatrixd(local.CArr());
2446
2447 // Shift half width so rings centered over center vertex
2448 glTranslated(0.0, 0.0, -width/2.0);
2449
2450 // Inner and outer faces
2453
2454 // Top/bottom
2456 gluDisk(quad.Get(), inner, outer, fgDrawQuality, 1);
2457 glTranslated(0.0, 0.0, width);
2459 gluDisk(quad.Get(), inner, outer, fgDrawQuality, 1);
2460
2461 glPopMatrix();
2462}
2463
2464/**************************************************************************/
2465
2466////////////////////////////////////////////////////////////////////////////////
2467/// Draw a sphere- marker on world-coordinate 'pos' with pixel
2468/// radius 'radius'. Color argument is optional.
2469
2471 const TGLVertex3 & pos,
2473 const UChar_t * rgba)
2474{
2475 static const UChar_t defColor[4] = { 250, 110, 0, 255 }; // Orange
2476
2477 radius = camera.ViewportDeltaToWorld(pos, radius, radius).Mag();
2478 DrawSphere(pos, radius, rgba ? rgba : defColor);
2479
2480}
2481
2482////////////////////////////////////////////////////////////////////////////////
2483/// Draw simple xyz-axes for given bounding-box.
2484
2486 const TGLBoundingBox & bbox,
2489{
2490 if (axesType == kAxesNone)
2491 return;
2492
2493 static const UChar_t axesColors[][4] = {
2494 {128, 0, 0, 255}, // -ive X axis light red
2495 {255, 0, 0, 255}, // +ive X axis deep red
2496 { 0, 128, 0, 255}, // -ive Y axis light green
2497 { 0, 255, 0, 255}, // +ive Y axis deep green
2498 { 0, 0, 128, 255}, // -ive Z axis light blue
2499 { 0, 0, 255, 255} // +ive Z axis deep blue
2500 };
2501
2502 static const UChar_t xyz[][8] = {
2503 {0x44, 0x44, 0x28, 0x10, 0x10, 0x28, 0x44, 0x44},
2504 {0x10, 0x10, 0x10, 0x10, 0x10, 0x28, 0x44, 0x44},
2505 {0x7c, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x7c}
2506 };
2507
2508 // Axes draw at fixed screen size - back project to world
2509 TGLVector3 pixelVector = camera.ViewportDeltaToWorld(bbox.Center(), 1, 1);
2511
2512 // Find x/y/z min/max values
2513 TGLBoundingBox bb(bbox);
2515 Double_t min[3] = { bb.XMin(), bb.YMin(), bb.ZMin() };
2516 Double_t max[3] = { bb.XMax(), bb.YMax(), bb.ZMax() };
2517
2518 for (UInt_t i = 0; i < 3; i++) {
2519 TGLVertex3 start;
2520 TGLVector3 vector;
2521
2522 if (axesType == kAxesOrigin) {
2523 // Through origin axes
2524 start[(i+1)%3] = 0.0;
2525 start[(i+2)%3] = 0.0;
2526 } else {
2527 // Side axes
2528 start[(i+1)%3] = min[(i+1)%3];
2529 start[(i+2)%3] = min[(i+2)%3];
2530 }
2531 vector[(i+1)%3] = 0.0;
2532 vector[(i+2)%3] = 0.0;
2533
2534 // -ive axis?
2535 if (min[i] < 0.0) {
2536 // Runs from origin?
2537 if (max[i] > 0.0) {
2538 start[i] = 0.0;
2539 vector[i] = min[i];
2540 } else {
2541 start[i] = max[i];
2542 vector[i] = min[i] - max[i];
2543 }
2545 }
2546 // +ive axis?
2547 if (max[i] > 0.0) {
2548 // Runs from origin?
2549 if (min[i] < 0.0) {
2550 start[i] = 0.0;
2551 vector[i] = max[i];
2552 } else {
2553 start[i] = min[i];
2554 vector[i] = max[i] - min[i];
2555 }
2556 DrawLine(start, vector, kLineHeadNone, pixelSize*fgSimpleAxisWidthScale*2.5, axesColors[i*2 + 1]);
2557 }
2558 }
2559
2560 // Draw origin sphere(s)
2561 if (axesType == kAxesOrigin) {
2562 // Single white origin sphere at 0, 0, 0
2563 DrawSphere(TGLVertex3(0.0, 0.0, 0.0), pixelSize*2.0, fgWhite);
2564 } else {
2565 for (UInt_t j = 0; j < 3; j++) {
2566 if (min[j] <= 0.0 && max[j] >= 0.0) {
2568 zero[j] = 0.0;
2569 zero[(j+1)%3] = min[(j+1)%3];
2570 zero[(j+2)%3] = min[(j+2)%3];
2571 DrawSphere(zero, pixelSize*2.0, axesColors[j*2 + 1]);
2572 }
2573 }
2574 }
2575
2577
2578 // Labels
2579 Double_t padPixels = 25.0;
2580
2582 for (UInt_t k = 0; k < 3; k++) {
2583 SetDrawColors(axesColors[k*2+1]);
2585 if (axesType == kAxesOrigin) {
2586 minPos[(k+1)%3] = 0.0;
2587 minPos[(k+2)%3] = 0.0;
2588 } else {
2589 minPos[(k+1)%3] = min[(k+1)%3];
2590 minPos[(k+2)%3] = min[(k+2)%3];
2591 }
2592 maxPos = minPos;
2593 minPos[k] = min[k];
2594 maxPos[k] = max[k];
2595
2596 TGLVector3 axis = maxPos - minPos;
2597 TGLVector3 axisViewport = camera.WorldDeltaToViewport(minPos, axis);
2598
2599 // Skip drawing if viewport projection of axis very small - labels will overlap
2600 // Occurs with orthographic cameras
2601 if (axisViewport.Mag() < 1) {
2602 continue;
2603 }
2604
2605 minPos -= camera.ViewportDeltaToWorld(minPos, padPixels*axisViewport.X()/axisViewport.Mag(),
2607 axisViewport = camera.WorldDeltaToViewport(maxPos, -axis);
2608 maxPos -= camera.ViewportDeltaToWorld(maxPos, padPixels*axisViewport.X()/axisViewport.Mag(),
2610
2611 DrawNumber(Form("%.0f", labelScale * min[k]), minPos, kTRUE); // Min value
2612 DrawNumber(Form("%.0f", labelScale * max[k]), maxPos, kTRUE); // Max value
2613
2614 // Axis name beside max value
2616 camera.ViewportDeltaToWorld(maxPos, padPixels*axisViewport.X()/axisViewport.Mag(),
2618 glRasterPos3dv(namePos.CArr());
2619 glBitmap(8, 8, 0.0, 4.0, 0.0, 0.0, xyz[k]); // Axis Name
2620 }
2621}
2622
2623////////////////////////////////////////////////////////////////////////////////
2624/// Draw number in string 'num' via internal 8x8-pixel bitmap on
2625/// vertex 'pos'. If 'center' is true, the number is centered on 'pos'.
2626/// Only numbers, '.', '-' and ' ' are supported.
2627
2629 const TGLVertex3 & pos,
2630 Bool_t center)
2631{
2632 static const UChar_t digits[][8] = {
2633 {0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38},//0
2634 {0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x10, 0x10},//1
2635 {0x7c, 0x44, 0x20, 0x18, 0x04, 0x04, 0x44, 0x38},//2
2636 {0x38, 0x44, 0x04, 0x04, 0x18, 0x04, 0x44, 0x38},//3
2637 {0x04, 0x04, 0x04, 0x04, 0x7c, 0x44, 0x44, 0x44},//4
2638 {0x7c, 0x44, 0x04, 0x04, 0x7c, 0x40, 0x40, 0x7c},//5
2639 {0x7c, 0x44, 0x44, 0x44, 0x7c, 0x40, 0x40, 0x7c},//6
2640 {0x20, 0x20, 0x20, 0x10, 0x08, 0x04, 0x44, 0x7c},//7
2641 {0x38, 0x44, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38},//8
2642 {0x7c, 0x44, 0x04, 0x04, 0x7c, 0x44, 0x44, 0x7c},//9
2643 {0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},//.
2644 {0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00},//-
2645 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} //space
2646 };
2647
2648 Double_t xOffset = 0, yOffset = 0;
2649 if (center)
2650 {
2651 xOffset = 3.5 * num.Length();
2652 yOffset = 4.0;
2653 }
2654
2655 glRasterPos3dv(pos.CArr());
2656 for (Ssiz_t i = 0, e = num.Length(); i < e; ++i) {
2657 if (num[i] == '.') {
2658 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[10]);
2659 } else if (num[i] == '-') {
2660 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[11]);
2661 } else if (num[i] == ' ') {
2662 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[12]);
2663 } else if (num[i] >= '0' && num[i] <= '9') {
2664 glBitmap(8, 8, xOffset, yOffset, 7.0, 0.0, digits[num[i] - '0']);
2665 }
2666 }
2667}
2668
2669
2670/**************************************************************************/
2671/**************************************************************************/
2672
2673////////////////////////////////////////////////////////////////////////////////
2674/// Constructor - change state only if necessary.
2675
2677 fWhat(what)
2678{
2680 fFlip = (fState != state);
2681 if (fFlip)
2682 SetState(state);
2683}
2684
2685////////////////////////////////////////////////////////////////////////////////
2686/// Destructor - reset state if changed.
2687
2693
2694////////////////////////////////////////////////////////////////////////////////
2695
2697{
2698 if (s)
2699 glEnable(fWhat);
2700 else
2702}
2703
2704
2705////////////////////////////////////////////////////////////////////////////////
2706/// Constructor - change state only if necessary.
2707
2709 fWhat(what)
2710{
2711 fFlip = ! glIsEnabled(fWhat) && state;
2712 if (fFlip)
2713 glEnable(fWhat);
2714}
2715
2716////////////////////////////////////////////////////////////////////////////////
2717/// Destructor - reset state if changed.
2718
2724
2725
2726////////////////////////////////////////////////////////////////////////////////
2727
2729 fWhat(what), fState(0), fFlip(kFALSE), fFoo(foo)
2730 {
2732 fFlip = (fState != state);
2733 if (fFlip) fFoo(state);
2734 }
2735
2736////////////////////////////////////////////////////////////////////////////////
2737
2742
2743
2744////////////////////////////////////////////////////////////////////////////////
2745/// TGLEnableGuard constructor.
2746
2752
2753////////////////////////////////////////////////////////////////////////////////
2754/// TGLEnableGuard destructor.
2755
2760
2761////////////////////////////////////////////////////////////////////////////////
2762/// TGLDisableGuard constructor.
2763
2769
2770////////////////////////////////////////////////////////////////////////////////
2771/// TGLDisableGuard destructor.
2772
2777
2778/** \class TGLSelectionBuffer
2779\ingroup opengl
2780*/
2781
2782
2783////////////////////////////////////////////////////////////////////////////////
2784/// TGLSelectionBuffer constructor.
2785
2787 : fWidth(0), fHeight(0)
2788{
2789}
2790
2791////////////////////////////////////////////////////////////////////////////////
2792/// TGLSelectionBuffer destructor.
2793
2797
2798////////////////////////////////////////////////////////////////////////////////
2799/// Read color buffer.
2800
2802{
2803 fWidth = w;
2804 fHeight = h;
2805 fBuffer.resize(w * h * 4);
2808}
2809
2810////////////////////////////////////////////////////////////////////////////////
2811/// Read color buffer.
2812
2814{
2815 fWidth = w;
2816 fHeight = h;
2817 fBuffer.resize(w * h * 4);
2820}
2821
2822////////////////////////////////////////////////////////////////////////////////
2823/// Get pixel color.
2824
2826{
2827 if (px < 0)
2828 px = 0;
2829 if (py < 0)
2830 py = 0;
2831
2832 if (UInt_t(px * fWidth * 4 + py * 4) > fBuffer.size())
2833 return &fBuffer[0];
2834
2835 return &fBuffer[px * fWidth * 4 + py * 4];
2836}
2837
2838namespace Rgl {
2839
2840const Float_t gRedEmission[] = {1.f, 0.f, 0.f, 1.f};
2841const Float_t gGreenEmission[] = {0.f, 1.f, 0.f, 1.f};
2842const Float_t gBlueEmission[] = {0.f, 0.f, 1.f, 1.f};
2843const Float_t gOrangeEmission[] = {1.f, 0.4f, 0.f, 1.f};
2844const Float_t gWhiteEmission[] = {1.f, 1.f, 1.f, 1.f};
2845const Float_t gGrayEmission[] = {0.3f,0.3f, 0.3f,1.f};
2846const Float_t gNullEmission[] = {0.f, 0.f, 0.f, 1.f};
2847
2848namespace {
2849 struct RGB_t {
2850 Int_t fRGB[3];
2851 };
2852
2853 RGB_t gColorTriplets[] = {{{255, 0, 0}},
2854 {{0, 255, 0}},
2855 {{0, 0, 255}},
2856 {{255, 255, 0}},
2857 {{255, 0, 255}},
2858 {{0, 255, 255}},
2859 {{255, 255, 255}}};
2860
2861 Bool_t operator < (const RGB_t &lhs, const RGB_t &rhs)
2862 {
2863 if (lhs.fRGB[0] < rhs.fRGB[0])
2864 return kTRUE;
2865 else if (lhs.fRGB[0] > rhs.fRGB[0])
2866 return kFALSE;
2867 else if (lhs.fRGB[1] < rhs.fRGB[1])
2868 return kTRUE;
2869 else if (lhs.fRGB[1] > rhs.fRGB[1])
2870 return kFALSE;
2871 else if (lhs.fRGB[2] < rhs.fRGB[2])
2872 return kTRUE;
2873
2874 return kFALSE;
2875 }
2876
2877 typedef std::map<Int_t, RGB_t> ColorLookupTable_t;
2879
2881
2882 typedef std::map<RGB_t, Int_t> ObjectLookupTable_t;
2884
2886}
2887////////////////////////////////////////////////////////////////////////////////
2888///Object id encoded as rgb triplet.
2889
2891{
2892 if (!highColor)
2893 glColor3ub(objectID & 0xff, (objectID & 0xff00) >> 8, (objectID & 0xff0000) >> 16);
2894 else {
2895 if (gObjectIDToColor.empty()) {
2896 //Initialize lookup tables.
2897 for (Int_t i = 0, id = 1; i < Int_t(sizeof gColorTriplets / sizeof(RGB_t)); ++i, ++id)
2899 for (Int_t i = 0, id = 1; i < Int_t(sizeof gColorTriplets / sizeof(RGB_t)); ++i, ++id)
2901 }
2902
2904
2905 if (it != gObjectIDToColor.end())
2906 glColor3ub(it->second.fRGB[0], it->second.fRGB[1], it->second.fRGB[2]);
2907 else {
2908 Error("ObjectIDToColor", "No color for such object ID: %d", objectID);
2909 glColor3ub(0, 0, 0);
2910 }
2911 }
2912}
2913
2914////////////////////////////////////////////////////////////////////////////////
2915
2917{
2918 if (!highColor)
2919 return pixel[0] | (pixel[1] << 8) | (pixel[2] << 16);
2920 else {
2921 if (gObjectIDToColor.empty())
2922 return 0;
2923
2924 RGB_t triplet = {{pixel[0], pixel[1], pixel[2]}};
2925 OLTCI_t it = gColorToObjectID.find(triplet);
2926
2927 if (it != gColorToObjectID.end())
2928 return it->second;
2929 else
2930 return 0;
2931 }
2932}
2933
2934
2935////////////////////////////////////////////////////////////////////////////////
2936///Draw quad outline.
2937
2939 const TGLVertex3 &v3, const TGLVertex3 &v4)
2940{
2941 glBegin(GL_LINE_LOOP);
2942 glVertex3dv(v1.CArr());
2943 glVertex3dv(v2.CArr());
2944 glVertex3dv(v3.CArr());
2945 glVertex3dv(v4.CArr());
2946 glEnd();
2947}
2948
2949////////////////////////////////////////////////////////////////////////////////
2950///Draw quad face.
2951
2953 const TGLVertex3 &v3, const TGLVector3 &normal)
2954{
2956 glNormal3dv(normal.CArr());
2957 glVertex3dv(v0.CArr());
2958 glVertex3dv(v1.CArr());
2959 glVertex3dv(v2.CArr());
2960 glVertex3dv(v3.CArr());
2961 glEnd();
2962}
2963
2964////////////////////////////////////////////////////////////////////////////////
2965///Draw quad face.
2966
2967void DrawQuadFilled(const Double_t *v0, const Double_t *v1, const Double_t *v2, const Double_t *v3,
2968 const Double_t *normal)
2969{
2972 glVertex3dv(v0);
2973 glVertex3dv(v1);
2974 glVertex3dv(v2);
2975 glVertex3dv(v3);
2976 glEnd();
2977}
2978
2979////////////////////////////////////////////////////////////////////////////////
2980///Draws triangle face, each vertex has its own averaged normal
2981
2983 const TGLVector3 &norm1, const TGLVector3 &norm2, const TGLVector3 &norm3)
2984{
2986 glNormal3dv(norm1.CArr());
2987 glVertex3dv(v1.CArr());
2988 glNormal3dv(norm2.CArr());
2989 glVertex3dv(v2.CArr());
2990 glNormal3dv(norm3.CArr());
2991 glVertex3dv(v3.CArr());
2992 glEnd();
2993}
2994
2995const Int_t gBoxFrontQuads[][4] = {{0, 1, 2, 3}, {4, 0, 3, 5}, {4, 5, 6, 7}, {7, 6, 2, 1}};
2996const Double_t gBoxFrontNormals[][3] = {{-1., 0., 0.}, {0., -1., 0.}, {1., 0., 0.}, {0., 1., 0.}};
2997const Int_t gBoxFrontPlanes[][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0}};
2998
2999const Int_t gBoxBackQuads[][4] = {{7, 1, 2, 6}, {4, 7, 6, 5}, {0, 4, 5, 3}, {0, 3, 2, 1}};
3000const Double_t gBoxBackNormals[][3] = {{0., -1., 0.}, {-1., 0., 0.}, {0., 1., 0.}, {1., 0., 0.}};
3001const Int_t gBoxBackPlanes[][2] = {{0, 1}, {3, 0}, {2, 3}, {1, 2}};
3002
3003////////////////////////////////////////////////////////////////////////////////
3004///Draws lego's bar as a 3d box
3005
3008{
3009 if (zMax < zMin)
3010 std::swap(zMax, zMin);
3011
3012 //Bottom is always drawn.
3014 glNormal3d(0., 0., -1.);
3019 glEnd();
3020 //Draw two visible front planes.
3021 const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
3022 {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
3023 const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
3024
3027 glVertex3dv(box[verts[0]]);
3028 glVertex3dv(box[verts[1]]);
3029 glVertex3dv(box[verts[2]]);
3030 glVertex3dv(box[verts[3]]);
3031 glEnd();
3032
3034
3037 glVertex3dv(box[verts[0]]);
3038 glVertex3dv(box[verts[1]]);
3039 glVertex3dv(box[verts[2]]);
3040 glVertex3dv(box[verts[3]]);
3041 glEnd();
3042
3043 //Top is always drawn.
3045 glNormal3d(0., 0., 1.);
3050 glEnd();
3051}
3052
3053////////////////////////////////////////////////////////////////////////////////
3054///Draws lego's bar as a 3d box
3055
3058{
3059 if (zMax < zMin)
3060 std::swap(zMax, zMin);
3061
3062 //The order is: 1) two back planes, 2) bottom plane, 3) two front planes,
3063 //4) top.
3064
3065 //Bottom is always drawn.
3067 glNormal3d(0., 0., -1.);
3072 glEnd();
3073
3074 const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
3075 {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
3076
3077 //Draw two back planes.
3078 const Int_t *verts = gBoxBackQuads[gBoxBackPlanes[fp][0]];
3079
3082 glVertex3dv(box[verts[0]]);
3083 glVertex3dv(box[verts[1]]);
3084 glVertex3dv(box[verts[2]]);
3085 glVertex3dv(box[verts[3]]);
3086 glEnd();
3087
3089
3092 glVertex3dv(box[verts[0]]);
3093 glVertex3dv(box[verts[1]]);
3094 glVertex3dv(box[verts[2]]);
3095 glVertex3dv(box[verts[3]]);
3096 glEnd();
3097
3098 //Draw two visible front planes.
3100
3103 glVertex3dv(box[verts[0]]);
3104 glVertex3dv(box[verts[1]]);
3105 glVertex3dv(box[verts[2]]);
3106 glVertex3dv(box[verts[3]]);
3107 glEnd();
3108
3110
3113 glVertex3dv(box[verts[0]]);
3114 glVertex3dv(box[verts[1]]);
3115 glVertex3dv(box[verts[2]]);
3116 glVertex3dv(box[verts[3]]);
3117 glEnd();
3118
3119 //Top is always drawn.
3121 glNormal3d(0., 0., 1.);
3126 glEnd();
3127}
3128
3129////////////////////////////////////////////////////////////////////////////////
3130///Draws lego's bar as a 3d box
3131///LULULULU
3132
3136{
3137 if (zMax < zMin) {
3138 std::swap(zMax, zMin);
3139 std::swap(texMax, texMin);
3140 }
3141
3142 //Top and bottom are always drawn.
3144 glNormal3d(0., 0., 1.);
3150 glEnd();
3151
3154 glNormal3d(0., 0., -1.);
3159 glEnd();
3160 //Draw two visible front planes.
3161 const Double_t box[][3] = {{xMin, yMin, zMax}, {xMin, yMax, zMax}, {xMin, yMax, zMin}, {xMin, yMin, zMin},
3162 {xMax, yMin, zMax}, {xMax, yMin, zMin}, {xMax, yMax, zMin}, {xMax, yMax, zMax}};
3163
3165 const Int_t *verts = gBoxFrontQuads[gBoxFrontPlanes[fp][0]];
3166
3169 glTexCoord1d(tex[verts[0]]);
3170 glVertex3dv(box[verts[0]]);
3171 glTexCoord1d(tex[verts[1]]);
3172 glVertex3dv(box[verts[1]]);
3173 glTexCoord1d(tex[verts[2]]);
3174 glVertex3dv(box[verts[2]]);
3175 glTexCoord1d(tex[verts[3]]);
3176 glVertex3dv(box[verts[3]]);
3177 glEnd();
3178
3180
3183 glTexCoord1d(tex[verts[0]]);
3184 glVertex3dv(box[verts[0]]);
3185 glTexCoord1d(tex[verts[1]]);
3186 glVertex3dv(box[verts[1]]);
3187 glTexCoord1d(tex[verts[2]]);
3188 glVertex3dv(box[verts[2]]);
3189 glTexCoord1d(tex[verts[3]]);
3190 glVertex3dv(box[verts[3]]);
3191 glEnd();
3192}
3193
3194////////////////////////////////////////////////////////////////////////////////
3195
3197 const Double_t *rgba1, const Double_t *rgba2)
3198{
3199 assert(rgba1 != nullptr && "DrawBoxWithGradientFill, parameter 'rgba1' is null");
3200 assert(rgba2 != nullptr && "DrawBoxWithGradientFill, parameter 'rgba2' is null");
3201
3204 glVertex2d(x1, y1);
3205 glVertex2d(x2, y1);
3207 glVertex2d(x2, y2);
3208 glVertex2d(x1, y2);
3209 glEnd();
3210}
3211
3212////////////////////////////////////////////////////////////////////////////////
3213///TODO: is it possible to use GLdouble to avoid problems with Double_t/GLdouble if they
3214///are not the same type?
3215
3217 const Double_t *outer, const Double_t *outerRGBA)
3218{
3219 assert(nPoints != 0 &&
3220 "DrawQuadStripWithRadialGradientFill, invalid number of points");
3221 assert(inner != nullptr &&
3222 "DrawQuadStripWithRadialGradientFill, parameter 'inner' is null");
3223 assert(innerRGBA != nullptr &&
3224 "DrawQuadStripWithRadialGradientFill, parameter 'innerRGBA' is null");
3225 assert(outer != nullptr &&
3226 "DrawQuadStripWithRadialGradientFill, parameter 'outer' is null");
3227 assert(outerRGBA != nullptr &&
3228 "DrawQuadStripWithRadialGradientFill, parameter 'outerRGBA' is null");
3229
3231 for (UInt_t j = 0; j < nPoints; ++j) {
3233 glVertex2dv(inner + j * 2);
3235 glVertex2dv(outer + j * 2);
3236 }
3237 glEnd();
3238}
3239
3240////////////////////////////////////////////////////////////////////////////////
3241///Cylinder for lego3.
3242
3245{
3246 GLUquadric *quad = quadric->Get();
3247
3248 if (quad) {
3249 if (zMin > zMax)
3250 std::swap(zMin, zMax);
3251 const Double_t xCenter = xMin + (xMax - xMin) / 2;
3252 const Double_t yCenter = yMin + (yMax - yMin) / 2;
3253 const Double_t radius = TMath::Min((xMax - xMin) / 2, (yMax - yMin) / 2);
3254
3255 glPushMatrix();
3257 gluCylinder(quad, radius, radius, zMax - zMin, 40, 1);
3258 glPopMatrix();
3259 glPushMatrix();
3261 gluDisk(quad, 0., radius, 40, 1);
3262 glPopMatrix();
3263 glPushMatrix();
3265 glRotated(180., 0., 1., 0.);
3266 gluDisk(quad, 0., radius, 40, 1);
3267 glPopMatrix();
3268 }
3269}
3270
3271////////////////////////////////////////////////////////////////////////////////
3272///Cylinder for lego3.
3273
3276{
3277 GLUquadric *quad = quadric->Get();
3278
3279 if (quad) {
3280 const Double_t xCenter = xMin + (xMax - xMin) / 2;
3281 const Double_t yCenter = yMin + (yMax - yMin) / 2;
3282 const Double_t zCenter = zMin + (zMax - zMin) / 2;
3283
3284 const Double_t radius = TMath::Min((zMax - zMin) / 2,
3285 TMath::Min((xMax - xMin) / 2, (yMax - yMin) / 2));
3286
3287 glPushMatrix();
3289 gluSphere(quad, radius, 10, 10);
3290 glPopMatrix();
3291 }
3292}
3293
3294
3295////////////////////////////////////////////////////////////////////////////////
3296
3299{
3300 const Double_t xWid = xMax - xMin;
3301 const Double_t yWid = yMax - yMin;
3302
3303 glBegin(GL_LINES);
3304 glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMin);
3305 glVertex3d(xMin + xWid / 2, yMin + yWid / 2, zMax);
3306 glEnd();
3307
3308 glBegin(GL_LINES);
3309 glVertex3d(xMin + xWid / 2, yMin, zMin);
3310 glVertex3d(xMin + xWid / 2, yMax, zMin);
3311 glEnd();
3312
3313 glBegin(GL_LINES);
3314 glVertex3d(xMin, yMin + yWid / 2, zMin);
3315 glVertex3d(xMax, yMin + yWid / 2, zMin);
3316 glEnd();
3317}
3318
3320{
3321 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
3322 if (n > 0.) {
3323 normal[0] = v[0] / n;
3324 normal[1] = v[1] / n;
3325 normal[2] = 0.;
3326 } else {
3327 normal[0] = v[0];
3328 normal[1] = v[1];
3329 normal[2] = 0.;
3330 }
3331}
3332
3334{
3335 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1]);
3336 if (n > 0.) {
3337 normal[0] = -v[0] / n;
3338 normal[1] = -v[1] / n;
3339 normal[2] = 0.;
3340 } else {
3341 normal[0] = -v[0];
3342 normal[1] = -v[1];
3343 normal[2] = 0.;
3344 }
3345}
3346
3348{
3349 //In polar coordinates, box became trapezoid.
3350 //Four faces need normal calculations.
3351 if (zMin > zMax)
3352 std::swap(zMin, zMax);
3353 //top
3355 glNormal3d(0., 0., 1.);
3356 glVertex3d(ver[0][0], ver[0][1], zMax);
3357 glVertex3d(ver[1][0], ver[1][1], zMax);
3358 glVertex3d(ver[2][0], ver[2][1], zMax);
3359 glVertex3d(ver[3][0], ver[3][1], zMax);
3360 glEnd();
3361 //bottom
3363 glNormal3d(0., 0., -1.);
3364 glVertex3d(ver[0][0], ver[0][1], zMin);
3365 glVertex3d(ver[3][0], ver[3][1], zMin);
3366 glVertex3d(ver[2][0], ver[2][1], zMin);
3367 glVertex3d(ver[1][0], ver[1][1], zMin);
3368 glEnd();
3369 //
3370
3371 Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
3372 {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
3373 {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
3374 {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
3375 Double_t normal[3] = {0.};
3381 glEnd();
3382
3388 glEnd();
3389
3391 if (color) {
3394 }
3399 glEnd();
3400
3402 if (color) {
3405 }
3410 glEnd();
3411}
3412
3413////////////////////////////////////////////////////////////////////////////////
3414///In polar coordinates, box became trapezoid.
3415///Four faces need normal calculations.
3416
3419{
3420 if (zMin > zMax) {
3421 std::swap(zMin, zMax);
3422 std::swap(texMin, texMax);
3423 }
3424
3425 //top
3427 glNormal3d(0., 0., 1.);
3429 glVertex3d(ver[0][0], ver[0][1], zMax);
3430 glVertex3d(ver[1][0], ver[1][1], zMax);
3431 glVertex3d(ver[2][0], ver[2][1], zMax);
3432 glVertex3d(ver[3][0], ver[3][1], zMax);
3433 glEnd();
3434 //bottom
3436 glNormal3d(0., 0., -1.);
3438 glVertex3d(ver[0][0], ver[0][1], zMin);
3439 glVertex3d(ver[3][0], ver[3][1], zMin);
3440 glVertex3d(ver[2][0], ver[2][1], zMin);
3441 glVertex3d(ver[1][0], ver[1][1], zMin);
3442 glEnd();
3443 //
3444
3445 Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
3446 {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
3447 {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
3448 {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
3449 Double_t normal[3] = {0.};
3455 glEnd();
3456
3462 glEnd();
3463
3475 glEnd();
3476
3488 glEnd();
3489}
3490
3491////////////////////////////////////////////////////////////////////////////////
3492///In polar coordinates, box became trapezoid.
3493
3496{
3497 if (zMin > zMax)
3498 std::swap(zMin, zMax);
3499
3500 const Double_t trapezoid[][3] = {{ver[0][0], ver[0][1], zMin}, {ver[1][0], ver[1][1], zMin},
3501 {ver[2][0], ver[2][1], zMin}, {ver[3][0], ver[3][1], zMin},
3502 {ver[0][0], ver[0][1], zMax}, {ver[1][0], ver[1][1], zMax},
3503 {ver[2][0], ver[2][1], zMax}, {ver[3][0], ver[3][1], zMax}};
3505 //top
3507 glNormal3d(0., 0., 1.);
3512 glEnd();
3513 //bottom
3515 glNormal3d(0., 0., -1.);
3520 glEnd();
3521 //
3523 Double_t normal[3] = {};
3528 glEnd();
3529
3535 glEnd();
3536
3544 glEnd();
3545
3553 glEnd();
3554}
3555
3556////////////////////////////////////////////////////////////////////////////////
3557
3559{
3560 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
3561 if (n > 0.) {
3562 normal[0] = v[0] / n;
3563 normal[1] = v[1] / n;
3564 normal[2] = v[2] / n;
3565 } else {
3566 normal[0] = v[0];
3567 normal[1] = v[1];
3568 normal[2] = v[2];
3569 }
3570}
3571
3572////////////////////////////////////////////////////////////////////////////////
3573
3575{
3576 const Double_t n = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
3577 if (n > 0.) {
3578 normal[0] = -v[0] / n;
3579 normal[1] = -v[1] / n;
3580 normal[2] = -v[2] / n;
3581 } else {
3582 normal[0] = -v[0];
3583 normal[1] = -v[1];
3584 normal[2] = -v[2];
3585 }
3586}
3587
3588////////////////////////////////////////////////////////////////////////////////
3589
3591{
3592 Double_t normal[3] = {0.};
3593
3595 TMath::Normal2Plane(ver[1], ver[2], ver[3], normal);
3597 glVertex3dv(ver[0]);
3598 glVertex3dv(ver[1]);
3599 glVertex3dv(ver[2]);
3600 glVertex3dv(ver[3]);
3601 glEnd();
3602 //bottom
3604 TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
3606 glVertex3dv(ver[4]);
3607 glVertex3dv(ver[7]);
3608 glVertex3dv(ver[6]);
3609 glVertex3dv(ver[5]);
3610 glEnd();
3611 //
3612
3614 TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
3616 glVertex3dv(ver[0]);
3617 glVertex3dv(ver[3]);
3618 glVertex3dv(ver[7]);
3619 glVertex3dv(ver[4]);
3620 glEnd();
3621
3627 glEnd();
3628
3630 TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
3632 glVertex3dv(ver[5]);
3633 glVertex3dv(ver[6]);
3634 glVertex3dv(ver[2]);
3635 glVertex3dv(ver[1]);
3636 glEnd();
3637
3643 glEnd();
3644}
3645
3646////////////////////////////////////////////////////////////////////////////////
3647
3649{
3650 Double_t normal[3] = {};
3651 if (texMin > texMax)
3652 std::swap(texMin, texMax);
3653
3656 TMath::Normal2Plane(ver[0], ver[1], ver[2], normal);
3662 glEnd();
3664 TMath::Normal2Plane(ver[4], ver[7], ver[6], normal);
3670 glEnd();
3672 TMath::Normal2Plane(ver[0], ver[3], ver[7], normal);
3678 glEnd();
3684 glEnd();
3686 TMath::Normal2Plane(ver[5], ver[6], ver[2], normal);
3692 glEnd();
3698 glEnd();
3699}
3700
3701
3703 Double_t min, Double_t max, Bool_t log, Bool_t z = kFALSE)
3704{
3705 //Axes are drawn with help of TGaxis class
3706 std::string option;
3707 option.reserve(20);
3708
3709 if (xMin > xMax || z) option += "SDH=+";
3710 else option += "SDH=-";
3711
3712 if (log) option += 'G';
3713
3714 Int_t nDiv = axis->GetNdivisions();
3715
3716 if (nDiv < 0) {
3717 option += 'N';
3718 nDiv = -nDiv;
3719 }
3720
3722 axisPainter.SetLineWidth(1);
3723
3724 static const Double_t zero = 0.001;
3725
3726 if (TMath::Abs(xMax - xMin) >= zero || TMath::Abs(yMax - yMin) >= zero) {
3727 axisPainter.ImportAxisAttributes(axis);
3728 axisPainter.SetLabelOffset(axis->GetLabelOffset() + axis->GetTickLength());
3729
3730 if (log) {
3731 min = TMath::Power(10, min);
3732 max = TMath::Power(10, max);
3733 }
3734 //Option time display is required ?
3735 if (axis->GetTimeDisplay()) {
3736 option += 't';
3737
3738 if (!strlen(axis->GetTimeFormatOnly()))
3739 axisPainter.SetTimeFormat(axis->ChooseTimeFormat(max - min));
3740 else
3741 axisPainter.SetTimeFormat(axis->GetTimeFormat());
3742 }
3743
3744 axisPainter.SetOption(option.c_str());
3745 axisPainter.PaintAxis(xMin, yMin, xMax, yMax, min, max, nDiv, option.c_str());
3746 }
3747}
3748
3749const Int_t gFramePoints[][2] = {{3, 1}, {0, 2}, {1, 3}, {2, 0}};
3750//Each point has two "neighbouring axes" (left and right). Axes types are 1 (ordinata) and 0 (abscissa)
3751const Int_t gAxisType[][2] = {{1, 0}, {0, 1}, {1, 0}, {0, 1}};
3752
3753////////////////////////////////////////////////////////////////////////////////
3754///Using front point, find, where to draw axes and which labels to use for them
3755///gVirtualX->SelectWindow(gGLManager->GetVirtualXInd(fGLDevice));
3756///gVirtualX->SetDrawMode(TVirtualX::kCopy);//TCanvas by default sets in kInverse
3757
3760{
3761 const Int_t left = gFramePoints[fp][0];
3762 const Int_t right = gFramePoints[fp][1];
3763 const Double_t xLeft = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
3764 + box[left].X() - vp[0]));
3765 const Double_t yLeft = gPad->AbsPixeltoY(Int_t(vp[3] - box[left].Y()
3766 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3767 * gPad->GetWh() + vp[1]));
3768 const Double_t xMid = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
3769 + box[fp].X() - vp[0]));
3770 const Double_t yMid = gPad->AbsPixeltoY(Int_t(vp[3] - box[fp].Y()
3771 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3772 * gPad->GetWh() + vp[1]));
3773 const Double_t xRight = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC()
3774 * gPad->GetWw() + box[right].X() - vp[0]));
3775 const Double_t yRight = gPad->AbsPixeltoY(Int_t(vp[3] - box[right].Y()
3776 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3777 * gPad->GetWh() + vp[1]));
3778 const Double_t points[][2] = {{coord->GetXRange().first, coord->GetYRange().first },
3779 {coord->GetXRange().second, coord->GetYRange().first },
3780 {coord->GetXRange().second, coord->GetYRange().second},
3781 {coord->GetXRange().first, coord->GetYRange().second}};
3782 const Int_t leftType = gAxisType[fp][0];
3783 const Int_t rightType = gAxisType[fp][1];
3784 const Double_t leftLabel = points[left][leftType];
3785 const Double_t leftMidLabel = points[fp][leftType];
3787 const Double_t rightLabel = points[right][rightType];
3788
3789 if (xLeft - xMid || yLeft - yMid) {//To suppress error messages from TGaxis
3790 TAxis *axis = leftType ? yAxis : xAxis;
3791 if (leftLabel < leftMidLabel)
3793 leftType ? coord->GetYLog() : coord->GetXLog());
3794 else
3796 leftType ? coord->GetYLog() : coord->GetXLog());
3797 }
3798
3799 if (xRight - xMid || yRight - yMid) {//To suppress error messages from TGaxis
3800 TAxis *axis = rightType ? yAxis : xAxis;
3801
3804 rightType ? coord->GetYLog() : coord->GetXLog());
3805 else
3807 rightType ? coord->GetYLog() : coord->GetXLog());
3808 }
3809
3810 const Double_t xUp = gPad->AbsPixeltoX(Int_t(gPad->GetXlowNDC() * gPad->GetWw()
3811 + box[left + 4].X() - vp[0]));
3812 const Double_t yUp = gPad->AbsPixeltoY(Int_t(vp[3] - box[left + 4].Y()
3813 + (1 - gPad->GetHNDC() - gPad->GetYlowNDC())
3814 * gPad->GetWh() + vp[1]));
3815 Draw2DAxis(zAxis, xLeft, yLeft, xUp, yUp, coord->GetZRange().first,
3816 coord->GetZRange().second, coord->GetZLog(), kTRUE);
3817}
3818
3820 Double_t zScale, std::vector<Double_t> &zLevels)
3821{
3822 Int_t nDiv = zAxis->GetNdivisions() % 100;
3823 Int_t nBins = 0;
3824 Double_t binLow = 0., binHigh = 0., binWidth = 0.;
3825 THLimitsFinder::Optimize(zMin, zMax, nDiv, binLow, binHigh, nBins, binWidth, " ");
3826 zLevels.resize(nBins + 1);
3827
3828 for (Int_t i = 0; i < nBins + 1; ++i)
3829 zLevels[i] = (binLow + i * binWidth) * zScale;
3830}
3831
3832////////////////////////////////////////////////////////////////////////////////
3833///Draw textured triangle
3834
3837 const TGLVector3 &norm2, const TGLVector3 &norm3)
3838{
3840 glNormal3dv(norm1.CArr());
3842 glVertex3dv(v1.CArr());
3843 glNormal3dv(norm2.CArr());
3845 glVertex3dv(v2.CArr());
3846 glNormal3dv(norm3.CArr());
3848 glVertex3dv(v3.CArr());
3849 glEnd();
3850}
3851
3852////////////////////////////////////////////////////////////////////////////////
3853///Draw textured triangle on a plane
3854
3857 const TGLVector3 &normal)
3858{
3860 glNormal3dv(normal.CArr());
3862 glVertex3d(v1.X(), v1.Y(), z);
3864 glVertex3d(v2.X(), v2.Y(), z);
3866 glVertex3d(v3.X(), v3.Y(), z);
3867 glEnd();
3868}
3869
3870////////////////////////////////////////////////////////////////////////////////
3871///This function creates color for parametric surface's vertex,
3872///using its 'u' value.
3873///I've found it in one of Apple's Carbon tutorials , and it's based
3874///on Paul Bourke work. Very nice colors!!! :)
3875
3877{
3878 Float_t dv,vmid;
3879 //Float_t c[] = {1.f, 1.f, 1.f};
3880 Float_t c1[3] = {}, c2[3] = {}, c3[3] = {};
3881 Float_t ratio ;
3882 rgba[3] = 1.f;
3883
3884 if (v < vmin)
3885 v = vmin;
3886 if (v > vmax)
3887 v = vmax;
3888 dv = vmax - vmin;
3889
3890 switch (type) {
3891 case 0:
3892 rgba[0] = 1.f;
3893 rgba[1] = 1.f;
3894 rgba[2] = 1.f;
3895 break;
3896 case 1:
3897 if (v < (vmin + 0.25 * dv)) {
3898 rgba[0] = 0;
3899 rgba[1] = 4 * (v - vmin) / dv;
3900 rgba[2] = 1;
3901 } else if (v < (vmin + 0.5 * dv)) {
3902 rgba[0] = 0;
3903 rgba[1] = 1;
3904 rgba[2] = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
3905 } else if (v < (vmin + 0.75 * dv)) {
3906 rgba[0] = 4 * (v - vmin - 0.5 * dv) / dv;
3907 rgba[1] = 1;
3908 rgba[2] = 0;
3909 } else {
3910 rgba[0] = 1;
3911 rgba[1] = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
3912 rgba[2] = 0;
3913 }
3914 break;
3915 case 2:
3916 rgba[0] = (v - vmin) / dv;
3917 rgba[1] = 0;
3918 rgba[2] = (vmax - v) / dv;
3919 break;
3920 case 3:
3921 rgba[0] = (v - vmin) / dv;
3922 rgba[1] = rgba[0];
3923 rgba[2] = rgba[0];
3924 break;
3925 case 4:
3926 if (v < (vmin + dv / 6.0)) {
3927 rgba[0] = 1;
3928 rgba[1] = 6 * (v - vmin) / dv;
3929 rgba[2] = 0;
3930 } else if (v < (vmin + 2.0 * dv / 6.0)) {
3931 rgba[0] = 1 + 6 * (vmin + dv / 6.0 - v) / dv;
3932 rgba[1] = 1;
3933 rgba[2] = 0;
3934 } else if (v < (vmin + 3.0 * dv / 6.0)) {
3935 rgba[0] = 0;
3936 rgba[1] = 1;
3937 rgba[2] = 6 * (v - vmin - 2.0 * dv / 6.0) / dv;
3938 } else if (v < (vmin + 4.0 * dv / 6.0)) {
3939 rgba[0] = 0;
3940 rgba[1] = 1 + 6 * (vmin + 3.0 * dv / 6.0 - v) / dv;
3941 rgba[2] = 1;
3942 } else if (v < (vmin + 5.0 * dv / 6.0)) {
3943 rgba[0] = 6 * (v - vmin - 4.0 * dv / 6.0) / dv;
3944 rgba[1] = 0;
3945 rgba[2] = 1;
3946 } else {
3947 rgba[0] = 1;
3948 rgba[1] = 0;
3949 rgba[2] = 1 + 6 * (vmin + 5.0 * dv / 6.0 - v) / dv;
3950 }
3951 break;
3952 case 5:
3953 rgba[0] = (v - vmin) / (vmax - vmin);
3954 rgba[1] = 1;
3955 rgba[2] = 0;
3956 break;
3957 case 6:
3958 rgba[0] = (v - vmin) / (vmax - vmin);
3959 rgba[1] = (vmax - v) / (vmax - vmin);
3960 rgba[2] = rgba[0];
3961 break;
3962 case 7:
3963 if (v < (vmin + 0.25 * dv)) {
3964 rgba[0] = 0;
3965 rgba[1] = 4 * (v - vmin) / dv;
3966 rgba[2] = 1 - rgba[1];
3967 } else if (v < (vmin + 0.5 * dv)) {
3968 rgba[0] = 4 * (v - vmin - 0.25 * dv) / dv;
3969 rgba[1] = 1 - rgba[0];
3970 rgba[2] = 0;
3971 } else if (v < (vmin + 0.75 * dv)) {
3972 rgba[1] = 4 * (v - vmin - 0.5 * dv) / dv;
3973 rgba[0] = 1 - rgba[1];
3974 rgba[2] = 0;
3975 } else {
3976 rgba[0] = 0;
3977 rgba[2] = 4 * (v - vmin - 0.75 * dv) / dv;
3978 rgba[1] = 1 - rgba[2];
3979 }
3980 break;
3981 case 8:
3982 if (v < (vmin + 0.5 * dv)) {
3983 rgba[0] = 2 * (v - vmin) / dv;
3984 rgba[1] = rgba[0];
3985 rgba[2] = rgba[0];
3986 } else {
3987 rgba[0] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
3988 rgba[1] = rgba[0];
3989 rgba[2] = rgba[0];
3990 }
3991 break;
3992 case 9:
3993 if (v < (vmin + dv / 3)) {
3994 rgba[2] = 3 * (v - vmin) / dv;
3995 rgba[1] = 0;
3996 rgba[0] = 1 - rgba[2];
3997 } else if (v < (vmin + 2 * dv / 3)) {
3998 rgba[0] = 0;
3999 rgba[1] = 3 * (v - vmin - dv / 3) / dv;
4000 rgba[2] = 1;
4001 } else {
4002 rgba[0] = 3 * (v - vmin - 2 * dv / 3) / dv;
4003 rgba[1] = 1 - rgba[0];
4004 rgba[2] = 1;
4005 }
4006 break;
4007 case 10:
4008 if (v < (vmin + 0.2 * dv)) {
4009 rgba[0] = 0;
4010 rgba[1] = 5 * (v - vmin) / dv;
4011 rgba[2] = 1;
4012 } else if (v < (vmin + 0.4 * dv)) {
4013 rgba[0] = 0;
4014 rgba[1] = 1;
4015 rgba[2] = 1 + 5 * (vmin + 0.2 * dv - v) / dv;
4016 } else if (v < (vmin + 0.6 * dv)) {
4017 rgba[0] = 5 * (v - vmin - 0.4 * dv) / dv;
4018 rgba[1] = 1;
4019 rgba[2] = 0;
4020 } else if (v < (vmin + 0.8 * dv)) {
4021 rgba[0] = 1;
4022 rgba[1] = 1 - 5 * (v - vmin - 0.6 * dv) / dv;
4023 rgba[2] = 0;
4024 } else {
4025 rgba[0] = 1;
4026 rgba[1] = 5 * (v - vmin - 0.8 * dv) / dv;
4027 rgba[2] = 5 * (v - vmin - 0.8 * dv) / dv;
4028 }
4029 break;
4030 case 11:
4031 c1[0] = 200 / 255.0; c1[1] = 60 / 255.0; c1[2] = 0 / 255.0;
4032 c2[0] = 250 / 255.0; c2[1] = 160 / 255.0; c2[2] = 110 / 255.0;
4033 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / dv + c1[0];
4034 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / dv + c1[1];
4035 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / dv + c1[2];
4036 break;
4037 case 12:
4038 c1[0] = 55 / 255.0; c1[1] = 55 / 255.0; c1[2] = 45 / 255.0;
4039 c2[0] = 200 / 255.0; c2[1] = 60 / 255.0; c2[2] = 0 / 255.0;
4040 c3[0] = 250 / 255.0; c3[1] = 160 / 255.0; c3[2] = 110 / 255.0;
4041 ratio = 0.4;
4042 vmid = vmin + ratio * dv;
4043 if (v < vmid) {
4044 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
4045 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
4046 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
4047 } else {
4048 rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
4049 rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
4050 rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
4051 }
4052 break;
4053 case 13:
4054 c1[0] = 0 / 255.0; c1[1] = 255 / 255.0; c1[2] = 0 / 255.0;
4055 c2[0] = 255 / 255.0; c2[1] = 150 / 255.0; c2[2] = 0 / 255.0;
4056 c3[0] = 255 / 255.0; c3[1] = 250 / 255.0; c3[2] = 240 / 255.0;
4057 ratio = 0.3;
4058 vmid = vmin + ratio * dv;
4059 if (v < vmid) {
4060 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
4061 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
4062 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
4063 } else {
4064 rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
4065 rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
4066 rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
4067 }
4068 break;
4069 case 14:
4070 rgba[0] = 1;
4071 rgba[1] = 1 - (v - vmin) / dv;
4072 rgba[2] = 0;
4073 break;
4074 case 15:
4075 if (v < (vmin + 0.25 * dv)) {
4076 rgba[0] = 0;
4077 rgba[1] = 4 * (v - vmin) / dv;
4078 rgba[2] = 1;
4079 } else if (v < (vmin + 0.5 * dv)) {
4080 rgba[0] = 0;
4081 rgba[1] = 1;
4082 rgba[2] = 1 - 4 * (v - vmin - 0.25 * dv) / dv;
4083 } else if (v < (vmin + 0.75 * dv)) {
4084 rgba[0] = 4 * (v - vmin - 0.5 * dv) / dv;
4085 rgba[1] = 1;
4086 rgba[2] = 0;
4087 } else {
4088 rgba[0] = 1;
4089 rgba[1] = 1;
4090 rgba[2] = 4 * (v - vmin - 0.75 * dv) / dv;
4091 }
4092 break;
4093 case 16:
4094 if (v < (vmin + 0.5 * dv)) {
4095 rgba[0] = 0.0;
4096 rgba[1] = 2 * (v - vmin) / dv;
4097 rgba[2] = 1 - 2 * (v - vmin) / dv;
4098 } else {
4099 rgba[0] = 2 * (v - vmin - 0.5 * dv) / dv;
4100 rgba[1] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
4101 rgba[2] = 0.0;
4102 }
4103 break;
4104 case 17:
4105 if (v < (vmin + 0.5 * dv)) {
4106 rgba[0] = 1.0;
4107 rgba[1] = 1 - 2 * (v - vmin) / dv;
4108 rgba[2] = 2 * (v - vmin) / dv;
4109 } else {
4110 rgba[0] = 1 - 2 * (v - vmin - 0.5 * dv) / dv;
4111 rgba[1] = 2 * (v - vmin - 0.5 * dv) / dv;
4112 rgba[2] = 1.0;
4113 }
4114 break;
4115 case 18:
4116 rgba[0] = 0;
4117 rgba[1] = (v - vmin) / (vmax - vmin);
4118 rgba[2] = 1;
4119 break;
4120 case 19:
4121 rgba[0] = (v - vmin) / (vmax - vmin);
4122 rgba[1] = rgba[0];
4123 rgba[2] = 1;
4124 break;
4125 case 20:
4126 c1[0] = 0 / 255.0; c1[1] = 160 / 255.0; c1[2] = 0 / 255.0;
4127 c2[0] = 180 / 255.0; c2[1] = 220 / 255.0; c2[2] = 0 / 255.0;
4128 c3[0] = 250 / 255.0; c3[1] = 220 / 255.0; c3[2] = 170 / 255.0;
4129 ratio = 0.3;
4130 vmid = vmin + ratio * dv;
4131 if (v < vmid) {
4132 rgba[0] = (c2[0] - c1[0]) * (v - vmin) / (ratio*dv) + c1[0];
4133 rgba[1] = (c2[1] - c1[1]) * (v - vmin) / (ratio*dv) + c1[1];
4134 rgba[2] = (c2[2] - c1[2]) * (v - vmin) / (ratio*dv) + c1[2];
4135 } else {
4136 rgba[0] = (c3[0] - c2[0]) * (v - vmid) / ((1-ratio)*dv) + c2[0];
4137 rgba[1] = (c3[1] - c2[1]) * (v - vmid) / ((1-ratio)*dv) + c2[1];
4138 rgba[2] = (c3[2] - c2[2]) * (v - vmid) / ((1-ratio)*dv) + c2[2];
4139 }
4140 break;
4141 }
4142}
4143
4144}
4145
4146////////////////////////////////////////////////////////////////////////////////
4147///Ctor.
4148
4150 : fContours(nullptr),
4151 fPaletteSize(0),
4152 fTexture(0),
4153 fMaxPaletteSize(0)
4154{
4155}
4156
4157////////////////////////////////////////////////////////////////////////////////
4158///Try to find colors for palette.
4159
4161{
4162 if (!fMaxPaletteSize && check)
4164
4165 if (!(zRange.second - zRange.first))
4166 return kFALSE;
4167
4168 if (!paletteSize) {
4169 Error("TGLLevelPaletter::GeneratePalette",
4170 "Invalid palette size, must be a positive number");
4171 return kFALSE;
4172 }
4173
4175 Error("TGLLevelPalette::GeneratePalette",
4176 "Number of contours %d is too big for GL 1D texture, try to reduce it to %d",
4178 return kFALSE;
4179 }
4180
4181 UInt_t nearestPow2 = 2;
4182 while (nearestPow2 < paletteSize)
4183 nearestPow2 <<= 1;
4184
4185 fTexels.resize(4 * nearestPow2);
4187
4188 //Generate texels.
4190
4191 //Map color index into index in real palette.
4192
4193 for (UInt_t i = 0; i < paletteSize; ++i) {
4195 if (paletteInd > nColors - 1)
4196 paletteInd = nColors - 1;
4198
4199 if (const TColor *c = gROOT->GetColor(colorInd)) {
4200 Float_t rgb[3] = {};
4201 c->GetRGB(rgb[0], rgb[1], rgb[2]);
4202 fTexels[i * 4] = UChar_t(rgb[0] * 255);
4203 fTexels[i * 4 + 1] = UChar_t(rgb[1] * 255);
4204 fTexels[i * 4 + 2] = UChar_t(rgb[2] * 255);
4205 fTexels[i * 4 + 3] = 200;//alpha
4206 }
4207 }
4208
4209 fZRange = zRange;
4210
4211 return kTRUE;
4212}
4213
4214////////////////////////////////////////////////////////////////////////////////
4215///Clear :)
4216
4217void TGLLevelPalette::SetContours(const std::vector<Double_t> *cont)
4218{
4219 fContours = cont;
4220}
4221
4222////////////////////////////////////////////////////////////////////////////////
4223///Enable 1D texture
4224
4240
4241////////////////////////////////////////////////////////////////////////////////
4242///Disable 1D texture
4243
4249
4250////////////////////////////////////////////////////////////////////////////////
4251///Get. Palette. Size.
4252
4257
4258////////////////////////////////////////////////////////////////////////////////
4259///Get tex coordinate
4260
4262{
4263 if (!fContours) {
4264 if (z - fZRange.first < 0)
4265 z = fZRange.first;
4266 else if (fZRange.second < z)
4267 z = fZRange.second;
4268
4269 return (z - fZRange.first) / (fZRange.second - fZRange.first) * fPaletteSize / (fTexels.size() / 4);
4270 }
4271 /*
4272 //This part is wrong. To be fixed.
4273 std::vector<Double_t>::size_type i = 0, e = fContours->size();
4274
4275 if (!e)
4276 return 0.;
4277
4278 for (; i < e - 1; ++i) {
4279 if (z >= (*fContours)[i] && z <= (*fContours)[i + 1])
4280 return i / Double_t(fTexels.size() / 4);
4281 }
4282 */
4283
4284 return 1.;
4285}
4286
4287////////////////////////////////////////////////////////////////////////////////
4288///Get color.
4289
4291{
4292 if (z - fZRange.first < 0)
4293 z = fZRange.first;
4294 else if (fZRange.second < z)
4295 z = fZRange.second;
4296
4297 UInt_t ind = UInt_t((z - fZRange.first) / (fZRange.second - fZRange.first) * fPaletteSize);
4298 if (ind >= fPaletteSize)
4299 ind = fPaletteSize - 1;
4300
4301 return &fTexels[ind * 4];
4302}
4303
4304////////////////////////////////////////////////////////////////////////////////
4305///Get color.
4306
4308{
4309 return &fTexels[ind * 4];
4310}
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define g(i)
Definition RSha256.hxx:105
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:52
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Bool_t operator<(const TDatime &d1, const TDatime &d2)
Definition TDatime.h:106
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
std::pair< Bool_t, TGLLine3 > Intersection(const TGLPlane &p1, const TGLPlane &p2)
Find 3D line interestion of this plane with 'other'.
Definition TGLUtil.cxx:511
#define CALLBACK
Definition TGLUtil.cxx:1429
Double_t Dot(const TGLVector3 &v1, const TGLVector3 &v2)
Definition TGLUtil.h:317
TGLVector3 Cross(const TGLVector3 &v1, const TGLVector3 &v2)
Definition TGLUtil.h:323
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void pixel
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 const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char DrawLine
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
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 winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t style
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition TROOT.h:411
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
const_iterator end() const
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:37
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:41
virtual Float_t GetTickLength() const
Definition TAttAxis.h:46
Line Attributes class.
Definition TAttLine.h:20
Marker Attributes class.
Definition TAttMarker.h:20
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:33
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:32
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:34
Class to manage histogram axis.
Definition TAxis.h:32
virtual Bool_t GetTimeDisplay() const
Definition TAxis.h:133
const char * ChooseTimeFormat(Double_t axislength=0)
Choose a reasonable time format from the coordinates in the active pad and the number of divisions in...
Definition TAxis.cxx:126
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Definition TAxis.cxx:603
virtual const char * GetTimeFormat() const
Definition TAxis.h:134
The color creation and management class.
Definition TColor.h:22
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1926
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:490
Concrete class describing an orientated (free) or axis aligned box of 8 vertices.
TGLVertex3 Center() const
Abstract base camera class - concrete classes for orthographic and perspective cameras derive from it...
Definition TGLCamera.h:44
~TGLCapabilityEnabler()
Destructor - reset state if changed.
Definition TGLUtil.cxx:2719
TGLCapabilityEnabler(const TGLCapabilityEnabler &)
TGLCapabilitySwitch(const TGLCapabilitySwitch &)
void SetState(Bool_t s)
Definition TGLUtil.cxx:2696
~TGLCapabilitySwitch()
Destructor - reset state if changed.
Definition TGLUtil.cxx:2688
Class encapsulating a set of colors used throughout standard rendering.
Definition TGLUtil.h:836
TGLColor fSelection[5]
Definition TGLUtil.h:842
void StdLightBackground()
Set defaults for light (white) background.
Definition TGLUtil.cxx:1381
TGLColor fMarkup
Definition TGLUtil.h:841
TGLColorSet & operator=(const TGLColorSet &s)
Assignment operator.
Definition TGLUtil.cxx:1350
TGLColor fBackground
Definition TGLUtil.h:838
TGLColor fOutline
Definition TGLUtil.h:840
void StdDarkBackground()
Set defaults for dark (black) background.
Definition TGLUtil.cxx:1364
TGLColorSet()
Constructor. Sets default for dark background.
Definition TGLUtil.cxx:1329
TGLColor fForeground
Definition TGLUtil.h:839
Class encapsulating color information in preferred GL format - an array of four unsigned bytes.
Definition TGLUtil.h:785
void SetTransparency(Char_t transparency)
Set alpha from the transparency.
Definition TGLUtil.cxx:1305
const UChar_t * CArr() const
Definition TGLUtil.h:800
Char_t GetTransparency() const
Returns transparency value.
Definition TGLUtil.cxx:1220
void SetColor(Int_t r, Int_t g, Int_t b, Int_t a=255)
Set color with Int_t values.
Definition TGLUtil.cxx:1228
UChar_t GetBlue() const
Definition TGLUtil.h:804
UChar_t fRGBA[4]
Definition TGLUtil.h:787
TGLColor()
Default constructor. Color is initialized to black.
Definition TGLUtil.cxx:1151
UChar_t GetRed() const
Definition TGLUtil.h:802
TString AsString() const
Return string describing the color.
Definition TGLUtil.cxx:1313
TGLColor & operator=(const TGLColor &c)
Assignment operator.
Definition TGLUtil.cxx:1197
UChar_t GetGreen() const
Definition TGLUtil.h:803
Color_t GetColorIndex() const
Returns color-index representing the color.
Definition TGLUtil.cxx:1210
Short_t fIndex
Definition TGLUtil.h:788
~TGLDisableGuard()
TGLDisableGuard destructor.
Definition TGLUtil.cxx:2773
TGLDisableGuard(Int_t cap)
TGLDisableGuard constructor.
Definition TGLUtil.cxx:2764
~TGLEnableGuard()
TGLEnableGuard destructor.
Definition TGLUtil.cxx:2756
TGLEnableGuard(Int_t cap)
TGLEnableGuard constructor.
Definition TGLUtil.cxx:2747
void(* fFoo)(Float_t)
Definition TGLUtil.h:1107
TGLFloatHolder(const TGLFloatHolder &)=delete
Float_t fState
Definition TGLUtil.h:1105
const UChar_t * GetColour(Double_t z) const
Get color.
Definition TGLUtil.cxx:4290
const std::vector< Double_t > * fContours
Definition TGLUtil.h:1345
Int_t GetPaletteSize() const
Get. Palette. Size.
Definition TGLUtil.cxx:4253
void SetContours(const std::vector< Double_t > *contours)
Clear :)
Definition TGLUtil.cxx:4217
UInt_t fPaletteSize
Definition TGLUtil.h:1346
TGLLevelPalette()
Ctor.
Definition TGLUtil.cxx:4149
std::vector< UChar_t > fTexels
Definition TGLUtil.h:1344
void DisableTexture() const
Disable 1D texture.
Definition TGLUtil.cxx:4244
Double_t GetTexCoord(Double_t z) const
Get tex coordinate.
Definition TGLUtil.cxx:4261
Rgl::Range_t fZRange
Definition TGLUtil.h:1349
Bool_t GeneratePalette(UInt_t paletteSize, const Rgl::Range_t &zRange, Bool_t checkSize=kTRUE)
Try to find colors for palette.
Definition TGLUtil.cxx:4160
Int_t fMaxPaletteSize
Definition TGLUtil.h:1348
UInt_t fTexture
Definition TGLUtil.h:1347
void EnableTexture(Int_t mode) const
Enable 1D texture.
Definition TGLUtil.cxx:4225
3D space, fixed length, line class, with direction / length 'vector', passing through point 'vertex'.
Definition TGLUtil.h:387
TGLLine3(const TGLVertex3 &start, const TGLVertex3 &end)
Vector of line from fVertex.
Definition TGLUtil.cxx:173
const TGLVertex3 End() const
Definition TGLUtil.h:405
void Draw() const
Draw line in current basic GL color.
Definition TGLUtil.cxx:208
TGLVector3 fVector
Start vertex of line.
Definition TGLUtil.h:391
TGLVertex3 fVertex
Definition TGLUtil.h:390
void Set(const TGLVertex3 &start, const TGLVertex3 &end)
Set 3D line running from 'start' to 'end'.
Definition TGLUtil.cxx:189
16 component (4x4) transform matrix - column MAJOR as per GL.
Definition TGLUtil.h:598
void MultLeft(const TGLMatrix &lhs)
Multiply with matrix lhs on left.
Definition TGLUtil.cxx:712
TGLVector3 Multiply(const TGLVector3 &v, Double_t w=1) const
Multiply vector.
Definition TGLUtil.cxx:1043
void Scale(const TGLVector3 &scale)
Set matrix axis scales to 'scale'.
Definition TGLUtil.cxx:828
void RotateLF(Int_t i1, Int_t i2, Double_t amount)
Rotate in local frame.
Definition TGLUtil.cxx:891
Double_t Invert()
Invert the matrix, returns determinant.
Definition TGLUtil.cxx:965
void MoveLF(Int_t ai, Double_t amount)
Translate in local frame.
Definition TGLUtil.cxx:807
void SetIdentity()
Set matrix to identity.
Definition TGLUtil.cxx:759
void Transpose3x3()
Transpose the top left 3x3 matrix component along major diagonal Supported as currently incompatibili...
Definition TGLUtil.cxx:941
void RotatePF(Int_t i1, Int_t i2, Double_t amount)
Rotate in parent frame. Does optimised version of MultLeft.
Definition TGLUtil.cxx:908
void Move3LF(Double_t x, Double_t y, Double_t z)
Translate in local frame along all base vectors simultaneously.
Definition TGLUtil.cxx:816
void Rotate(const TGLVertex3 &pivot, const TGLVector3 &axis, Double_t angle)
Update matrix so resulting transform has been rotated about 'pivot' (in parent frame),...
Definition TGLUtil.cxx:864
virtual ~TGLMatrix()
Destroy matrix object.
Definition TGLUtil.cxx:689
TGLVector3 GetTranslation() const
Return the translation component of matrix.
Definition TGLUtil.cxx:788
Double_t fVals[16]
Definition TGLUtil.h:601
void RotateIP(TGLVector3 &v) const
Rotate vector in-place. Translation is not applied.
Definition TGLUtil.cxx:1081
Bool_t IsScalingForRender() const
Return true if matrix is to be considered a scaling matrix for rendering.
Definition TGLUtil.cxx:1105
void TransformVertex(TGLVertex3 &vertex) const
Transform passed 'vertex' by this matrix - converts local frame to parent.
Definition TGLUtil.cxx:927
TGLVector3 GetScale() const
Get local axis scaling factors.
Definition TGLUtil.cxx:1093
void MultRight(const TGLMatrix &rhs)
Multiply with matrix rhs on right.
Definition TGLUtil.cxx:696
void SetTranslation(Double_t x, Double_t y, Double_t z)
Set matrix translation components x,y,z.
Definition TGLUtil.cxx:770
void Set(const TGLVertex3 &origin, const TGLVector3 &zAxis, const TGLVector3 &xAxis=nullptr)
Set matrix which when applied puts local origin at 'origin' and the local Z axis in direction 'z'.
Definition TGLUtil.cxx:730
void MultiplyIP(TGLVector3 &v, Double_t w=1) const
Multiply vector in-place.
Definition TGLUtil.cxx:1069
void Translate(const TGLVector3 &vect)
Shift matrix translation components by 'vect' in parent frame.
Definition TGLUtil.cxx:796
void Dump() const
Output 16 matrix components to std::cout.
Definition TGLUtil.cxx:1126
TGLMatrix()
Construct default identity matrix:
Definition TGLUtil.cxx:600
3D plane class - of format Ax + By + Cz + D = 0
Definition TGLUtil.h:525
void Set(const TGLPlane &other)
Assign from other.
Definition TGLUtil.cxx:420
Double_t D() const
Definition TGLUtil.h:556
void Negate()
Negate the plane.
Definition TGLUtil.cxx:476
TGLVertex3 NearestOn(const TGLVertex3 &point) const
Return nearest point on plane.
Definition TGLUtil.cxx:495
TGLPlane & operator=(const TGLPlane &src)
Assignment operator.
Definition TGLUtil.cxx:384
void Normalise()
Normalise the plane.
Definition TGLUtil.cxx:393
TGLPlane()
Construct a default plane of x + y + z = 0.
Definition TGLUtil.cxx:331
Double_t DistanceTo(const TGLVertex3 &vertex) const
Distance from plane to vertex.
Definition TGLUtil.cxx:487
TGLVector3 Norm() const
Definition TGLUtil.h:558
void Dump() const
Output plane equation to std::out.
Definition TGLUtil.cxx:411
Double_t fVals[4]
Definition TGLUtil.h:528
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
Wrapper class for GLU quadric shape drawing object.
Definition TGLQuadric.h:28
Viewport (pixel base) 2D rectangle class.
Definition TGLUtil.h:422
Int_t fY
Definition TGLUtil.h:425
Int_t fWidth
Corner.
Definition TGLUtil.h:426
TGLRect()
Positive width/height.
Definition TGLUtil.cxx:225
Int_t Diagonal() const
Return the diagonal of the rectangle.
Definition TGLUtil.cxx:282
Rgl::EOverlap Overlap(const TGLRect &other) const
Return overlap result (kInside, kOutside, kPartial) of this rect with 'other'.
Definition TGLUtil.cxx:293
virtual ~TGLRect()
Destroy rect object.
Definition TGLUtil.cxx:250
Int_t fHeight
Definition TGLUtil.h:426
void Expand(Int_t x, Int_t y)
Expand the rect to encompass point (x,y)
Definition TGLUtil.cxx:257
Int_t fX
Definition TGLUtil.h:425
const UChar_t * GetPixelColor(Int_t px, Int_t py) const
Get pixel color.
Definition TGLUtil.cxx:2825
void ReadColorBuffer(Int_t width, Int_t height)
Read color buffer.
Definition TGLUtil.cxx:2801
virtual ~TGLSelectionBuffer()
TGLSelectionBuffer destructor.
Definition TGLUtil.cxx:2794
TGLSelectionBuffer()
TGLSelectionBuffer constructor.
Definition TGLUtil.cxx:2786
std::vector< UChar_t > fBuffer
Definition TGLUtil.h:1141
static void DrawSphere(const TGLVertex3 &position, Double_t radius, const UChar_t rgba[4])
Draw sphere, centered on vertex 'position', with radius 'radius', color 'rgba'.
Definition TGLUtil.cxx:2348
static void Color4ubv(const UChar_t *rgba)
Wrapper for glColor4ubv.
Definition TGLUtil.cxx:1770
static UInt_t GetDrawQuality()
static: get draw quality
Definition TGLUtil.cxx:1596
static Int_t fgPickingRadius
Definition TGLUtil.h:929
static const UChar_t fgWhite[4]
Definition TGLUtil.h:1425
static UInt_t fgDefaultDrawQuality
Definition TGLUtil.h:917
static void SetDrawQuality(UInt_t dq)
static: set draw quality
Definition TGLUtil.cxx:1604
static Float_t GetPointSizeScale()
Get global point-size scale.
Definition TGLUtil.cxx:1874
static void Color3f(Float_t r, Float_t g, Float_t b)
Wrapper for glColor3f.
Definition TGLUtil.cxx:1778
static Float_t fgPointSize
Definition TGLUtil.h:922
static Float_t fgLineWidth
Definition TGLUtil.h:923
static Float_t fgScreenScalingFactor
Definition TGLUtil.h:927
static void ResetDrawQuality()
static: reset draw quality
Definition TGLUtil.cxx:1612
static Float_t fgSimpleAxisWidthScale
Definition TGLUtil.h:931
static Float_t fgPointSizeScale
Definition TGLUtil.h:924
static Bool_t IsColorLocked()
Returns true if color lock-count is greater than 0.
Definition TGLUtil.cxx:1680
static void Color3fv(const Float_t *rgb)
Wrapper for glColor3fv.
Definition TGLUtil.cxx:1794
static void SetLineWidthScale(Float_t scale)
Set global line-width scale.
Definition TGLUtil.cxx:1898
static void SetSimpleAxisWidthScale(Float_t s)
Definition TGLUtil.cxx:1418
static UInt_t LockColor()
Prevent further color changes.
Definition TGLUtil.cxx:1660
static void Color4f(Float_t r, Float_t g, Float_t b, Float_t a)
Wrapper for glColor4f.
Definition TGLUtil.cxx:1786
static void SetDrawColors(const UChar_t rgba[4])
Set basic draw colors from 4 component 'rgba' Used by other TGLUtil drawing routines.
Definition TGLUtil.cxx:2327
static void ColorTransparency(Color_t color_index, Char_t transparency=0)
Set color from color_index and ROOT-style transparency (default 0).
Definition TGLUtil.cxx:1732
static void BeginAttLine(const TAttLine &aline, Char_t transp, Int_t pick_radius=0, Bool_t selection=kFALSE)
Setup drawing parameters according to passed TAttLine.
Definition TGLUtil.cxx:2263
static const UChar_t fgRed[4]
Definition TGLUtil.h:1421
static void RenderPolyLine(const TAttLine &aline, Char_t transp, Float_t *p, Int_t n, Int_t pick_radius=0, Bool_t selection=kFALSE)
Render poly-line as specified by the p-array.
Definition TGLUtil.cxx:2243
static UInt_t GetDefaultDrawQuality()
static: get default draw quality
Definition TGLUtil.cxx:1620
static void BeginExtendPickRegion(Float_t scale)
Definition TGLUtil.cxx:1943
static void InitializeIfNeeded()
Initialize globals that require other libraries to be initialized.
Definition TGLUtil.cxx:1573
ELineHeadShape
Definition TGLUtil.h:951
@ kLineHeadNone
Definition TGLUtil.h:951
@ kLineHeadBox
Definition TGLUtil.h:951
@ kLineHeadArrow
Definition TGLUtil.h:951
static Float_t GetLineWidthScale()
Returns global line-width scale.
Definition TGLUtil.cxx:1890
static Float_t fgPointLineScalingFactor
Definition TGLUtil.h:928
static UInt_t UnlockColor()
Allow color changes.
Definition TGLUtil.cxx:1668
static void EndAttLine(Int_t pick_radius=0, Bool_t selection=kFALSE)
Restore previous line drawing state.
Definition TGLUtil.cxx:2299
static void DrawLine(const TGLLine3 &line, ELineHeadShape head, Double_t size, const UChar_t rgba[4])
Draw thick line (tube) defined by 'line', with head at end shape 'head' - box/arrow/none,...
Definition TGLUtil.cxx:2363
static void Color(const TGLColor &color)
Set color from TGLColor.
Definition TGLUtil.cxx:1688
static void DrawReferenceMarker(const TGLCamera &camera, const TGLVertex3 &pos, Float_t radius=3, const UChar_t *rgba=nullptr)
Draw a sphere- marker on world-coordinate 'pos' with pixel radius 'radius'.
Definition TGLUtil.cxx:2470
static void DrawRing(const TGLVertex3 &center, const TGLVector3 &normal, Double_t radius, const UChar_t *rgba)
Draw ring, centered on 'center', lying on plane defined by 'center' & 'normal' of outer radius 'radiu...
Definition TGLUtil.cxx:2429
static void Color3ubv(const UChar_t *rgb)
Wrapper for glColor3ubv.
Definition TGLUtil.cxx:1762
static Int_t CheckError(const char *loc)
Check current GL error state, outputting details via ROOT Error method if one.
Definition TGLUtil.cxx:1637
static Float_t GetScreenScalingFactor()
Returns scaling factor between screen points and GL viewport pixels.
Definition TGLUtil.cxx:1843
static void ColorAlpha(const TGLColor &color, UChar_t alpha)
Set color from TGLColor and alpha value.
Definition TGLUtil.cxx:1696
static Int_t GetPickingRadius()
Returns picking radius.
Definition TGLUtil.cxx:1862
static void SetPointSizeScale(Float_t scale)
Set global point-size scale.
Definition TGLUtil.cxx:1882
static void Color4fv(const Float_t *rgba)
Wrapper for glColor4fv.
Definition TGLUtil.cxx:1802
static void Color3ub(UChar_t r, UChar_t g, UChar_t b)
Wrapper for glColor3ub.
Definition TGLUtil.cxx:1746
static UInt_t fgDrawQuality
Definition TGLUtil.h:918
static GLUtesselator * GetDrawTesselator4dv()
Returns a tesselator for direct drawing when using 4-vertices with double precision.
Definition TGLUtil.cxx:1552
static const UChar_t fgBlue[4]
Definition TGLUtil.h:1423
static const UChar_t fgGrey[4]
Definition TGLUtil.h:1426
@ kAxesNone
Definition TGLUtil.h:952
@ kAxesOrigin
Definition TGLUtil.h:952
static Float_t PointSize()
Get the point-size, taking the global scaling into account.
Definition TGLUtil.cxx:1926
static void EndExtendPickRegion()
Definition TGLUtil.cxx:1958
static GLUtesselator * GetDrawTesselator3dv()
Returns a tesselator for direct drawing when using 3-vertices with double precision.
Definition TGLUtil.cxx:1531
static GLUtesselator * GetDrawTesselator4fv()
Returns a tesselator for direct drawing when using 4-vertices with single precision.
Definition TGLUtil.cxx:1510
static Float_t fgSimpleAxisBBoxScale
Definition TGLUtil.h:932
static const UChar_t fgGreen[4]
Definition TGLUtil.h:1422
static UInt_t fgColorLockCount
Definition TGLUtil.h:920
static GLUtesselator * GetDrawTesselator3fv()
Returns a tesselator for direct drawing when using 3-vertices with single precision.
Definition TGLUtil.cxx:1489
static void DrawSimpleAxes(const TGLCamera &camera, const TGLBoundingBox &bbox, Int_t axesType, Float_t labelScale=1)
Draw simple xyz-axes for given bounding-box.
Definition TGLUtil.cxx:2485
static void SetSimpleAxisBBoxScale(Float_t s)
Definition TGLUtil.cxx:1419
static void SetDefaultDrawQuality(UInt_t dq)
static: set default draw quality
Definition TGLUtil.cxx:1628
static void PointToViewport(Int_t &x, Int_t &y)
Convert from point/screen coordinates to GL viewport coordinates.
Definition TGLUtil.cxx:1814
static void DrawNumber(const TString &num, const TGLVertex3 &pos, Bool_t center=kFALSE)
Draw number in string 'num' via internal 8x8-pixel bitmap on vertex 'pos'.
Definition TGLUtil.cxx:2628
static Float_t LineWidth()
Get the line-width, taking the global scaling into account.
Definition TGLUtil.cxx:1934
static Float_t fgLineWidthScale
Definition TGLUtil.h:925
static void RenderPolyMarkers(const TAttMarker &marker, Char_t transp, Float_t *p, Int_t n, Int_t pick_radius=0, Bool_t selection=kFALSE, Bool_t sec_selection=kFALSE)
Render polymarkers at points specified by p-array.
Definition TGLUtil.cxx:1971
static const UChar_t fgYellow[4]
Definition TGLUtil.h:1424
static void RenderPoints(const TAttMarker &marker, Float_t *p, Int_t n, Int_t pick_radius=0, Bool_t selection=kFALSE, Bool_t sec_selection=kFALSE)
Render markers as circular or square points.
Definition TGLUtil.cxx:2011
static Float_t GetPointLineScalingFactor()
Return extra scaling factor for points and lines.
Definition TGLUtil.cxx:1854
static void Color4ub(UChar_t r, UChar_t g, UChar_t b, UChar_t a)
Wrapper for glColor4ub.
Definition TGLUtil.cxx:1754
static void RenderCrosses(const TAttMarker &marker, Float_t *p, Int_t n, Bool_t sec_selection=kFALSE)
Render markers as crosses.
Definition TGLUtil.cxx:2131
3 component (x/y/z) vector class.
Definition TGLUtil.h:248
Double_t Mag() const
Definition TGLUtil.h:298
TGLVector3()=default
3 component (x/y/z) vertex class.
Definition TGLUtil.h:84
void Dump() const
Output vertex component values to std::cout.
Definition TGLUtil.cxx:129
void Minimum(const TGLVertex3 &other)
Definition TGLUtil.cxx:110
Double_t X() const
Definition TGLUtil.h:119
Double_t Z() const
Definition TGLUtil.h:123
Double_t fVals[3]
Definition TGLUtil.h:88
void Maximum(const TGLVertex3 &other)
Definition TGLUtil.cxx:119
void Fill(Double_t val)
Definition TGLUtil.h:204
void Set(Double_t x, Double_t y, Double_t z)
Definition TGLUtil.h:210
Double_t Y() const
Definition TGLUtil.h:121
TGLVertex3()
Construct a default (0.0, 0.0, 0.0) vertex.
Definition TGLUtil.cxx:52
void Shift(TGLVector3 &shift)
Offset a vertex by vector 'shift'.
Definition TGLUtil.cxx:91
const Double_t * CArr() const
Definition TGLUtil.h:126
~TGLVertex3()
Destroy vertex object.
Definition TGLUtil.cxx:84
The axis painter class.
Definition TGaxis.h:26
static void Optimize(Double_t A1, Double_t A2, Int_t nold, Double_t &BinLow, Double_t &BinHigh, Int_t &nbins, Double_t &BWID, Option_t *option="")
Static function to compute reasonable axis limits.
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition TStyle.cxx:1102
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition TStyle.cxx:1176
TLine * line
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
return c2
Definition legend2.C:14
return c3
Definition legend3.C:15
void DrawTrapezoid(const Double_t ver[][2], Double_t zMin, Double_t zMax, Bool_t color=kTRUE)
Definition TGLUtil.cxx:3347
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:3835
void DrawQuadStripWithRadialGradientFill(unsigned nPoints, const Double_t *inner, const Double_t *innerRGBA, const Double_t *outer, const Double_t *outerRGBA)
TODO: is it possible to use GLdouble to avoid problems with Double_t/GLdouble if they are not the sam...
Definition TGLUtil.cxx:3216
void DrawQuadFilled(const TGLVertex3 &v0, const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVector3 &normal)
Draw quad face.
Definition TGLUtil.cxx:2952
void DrawTrapezoidTextured(const Double_t ver[][2], Double_t zMin, Double_t zMax, Double_t tMin, Double_t tMax)
In polar coordinates, box became trapezoid.
Definition TGLUtil.cxx:3417
const Float_t gNullEmission[]
Definition TGLUtil.cxx:2846
const Int_t gFramePoints[][2]
Definition TGLUtil.cxx:3749
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition TGLUtil.cxx:2890
const Float_t gBlueEmission[]
Definition TGLUtil.cxx:2842
const Float_t gWhiteEmission[]
Definition TGLUtil.cxx:2844
void SetZLevels(TAxis *zAxis, Double_t zMin, Double_t zMax, Double_t zScale, std::vector< Double_t > &zLevels)
Definition TGLUtil.cxx:3819
void CylindricalNormalInv(const Double_t *v, Double_t *normal)
Definition TGLUtil.cxx:3333
void DrawTrapezoidTextured2(const Double_t ver[][2], Double_t zMin, Double_t zMax, Double_t tMin, Double_t tMax)
In polar coordinates, box became trapezoid.
Definition TGLUtil.cxx:3494
const Int_t gBoxFrontQuads[][4]
Definition TGLUtil.cxx:2995
const Float_t gGrayEmission[]
Definition TGLUtil.cxx:2845
void GetColor(Float_t v, Float_t vmin, Float_t vmax, Int_t type, Float_t *rgba)
This function creates color for parametric surface's vertex, using its 'u' value.
Definition TGLUtil.cxx:3876
const Int_t gBoxBackQuads[][4]
Definition TGLUtil.cxx:2999
void SphericalNormal(const Double_t *v, Double_t *normal)
Definition TGLUtil.cxx:3558
void DrawCylinder(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax)
Cylinder for lego3.
Definition TGLUtil.cxx:3243
const Int_t gAxisType[][2]
Definition TGLUtil.cxx:3751
void DrawError(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax)
Definition TGLUtil.cxx:3297
void SphericalNormalInv(const Double_t *v, Double_t *normal)
Definition TGLUtil.cxx:3574
const Float_t gRedEmission[]
Definition TGLUtil.cxx:2840
const Int_t gBoxBackPlanes[][2]
Definition TGLUtil.cxx:3001
void DrawTransparentBox(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax, Int_t fp)
Draws lego's bar as a 3d box.
Definition TGLUtil.cxx:3056
std::pair< Double_t, Double_t > Range_t
Definition TGLUtil.h:1202
void DrawBoxFront(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax, Int_t fp)
Draws lego's bar as a 3d box.
Definition TGLUtil.cxx:3006
const Double_t gBoxFrontNormals[][3]
Definition TGLUtil.cxx:2996
const Float_t gGreenEmission[]
Definition TGLUtil.cxx:2841
void CylindricalNormal(const Double_t *v, Double_t *normal)
Definition TGLUtil.cxx:3319
void DrawQuadOutline(const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVertex3 &v4)
Draw quad outline.
Definition TGLUtil.cxx:2938
void DrawBoxWithGradientFill(Double_t y1, Double_t y2, Double_t x1, Double_t x2, const Double_t *rgba1, const Double_t *rgba2)
Definition TGLUtil.cxx:3196
EOverlap
Definition TGLUtil.h:35
void DrawSphere(TGLQuadric *quadric, Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax)
Cylinder for lego3.
Definition TGLUtil.cxx:3274
void DrawBoxFrontTextured(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax, Double_t tMin, Double_t tMax, Int_t front)
Draws lego's bar as a 3d box LULULULU.
Definition TGLUtil.cxx:3133
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:2982
const Double_t gBoxBackNormals[][3]
Definition TGLUtil.cxx:3000
const Float_t gOrangeEmission[]
Definition TGLUtil.cxx:2843
void Draw2DAxis(TAxis *axis, Double_t xMin, Double_t yMin, Double_t xMax, Double_t yMax, Double_t min, Double_t max, Bool_t log, Bool_t z=kFALSE)
Definition TGLUtil.cxx:3702
Int_t ColorToObjectID(const UChar_t *color, Bool_t highColor)
Definition TGLUtil.cxx:2916
const Int_t gBoxFrontPlanes[][2]
Definition TGLUtil.cxx:2997
void DrawAxes(Int_t frontPoint, const Int_t *viewport, const TGLVertex3 *box2D, const TGLPlotCoordinates *plotCoord, TAxis *xAxis, TAxis *yAxis, TAxis *zAxis)
Using front point, find, where to draw axes and which labels to use for them gVirtualX->SelectWindow(...
Definition TGLUtil.cxx:3758
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:1299
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:704
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:251
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:732
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:599
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124
static const char * what
Definition stlLoader.cc:5
auto * t1
Definition textangle.C:20