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