Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TEveProjectionAxesGL.cxx
Go to the documentation of this file.
1// @(#)root/eve:$Id$
2// Author: Alja Mrak-Tadel 2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2007, 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
13#include "TEveProjectionAxes.h"
15#include "THLimitsFinder.h"
16
17#include "TGLIncludes.h"
18#include "TGLRnrCtx.h"
19#include "TGLFontManager.h"
20#include "TGLCamera.h"
21
22#include "TMath.h"
23
24/** \class TEveProjectionAxesGL
25\ingroup TEve
26OpenGL renderer class for TEveProjectionAxes.
27*/
28
29
30////////////////////////////////////////////////////////////////////////////////
31/// Constructor.
32
34 TGLObject(),
35 fM(nullptr),
36 fProjection(nullptr)
37{
38 fDLCache = kFALSE; // Disable display list.
39}
40
41////////////////////////////////////////////////////////////////////////////////
42/// Set model object.
43/// Virtual from TGLObject.
44
46{
48 fAxisPainter.SetAttAxis(fM);
49 return fM->GetManager() ? kTRUE : kFALSE;
50}
51
52////////////////////////////////////////////////////////////////////////////////
53/// Fill the bounding-box data of the logical-shape.
54/// Virtual from TGLObject.
55
60
61////////////////////////////////////////////////////////////////////////////////
62/// Filter overlapping labels.
63
65{
66 TGLAxisPainter::LabVec_t &orig = fAxisPainter.RefLabVec();
67 if (orig.empty()) return;
68
69 Float_t center = fM->GetManager()->GetProjection()->GetProjectedCenter()[idx];
70
71 // Get index of label closest to the distortion center.
72 // Needed to keep symmetry around center.
73 Int_t minIdx = 0;
74 Int_t cnt = 0;
75 Float_t currD = 0;
76 Float_t minD = TMath::Abs(orig[0].first -center);
77 for (TGLAxisPainter::LabVec_t::iterator it = orig.begin(); it != orig.end(); ++it)
78 {
79 currD = TMath::Abs((*it).first - center);
80 if (minD > currD)
81 {
82 minD = currD;
83 minIdx = cnt;
84 }
85 cnt++;
86 }
87
88 // Minimum allowed distance 4* font size.
90 filtered.push_back(orig[minIdx]);
91 Int_t size = orig.size();
92 Float_t minDist = 4*fM->GetLabelSize()*ref;
93 Float_t pos = 0;
94
95 // Go from center to minimum.
96 if (minIdx > 0)
97 {
98 pos = orig[minIdx].first;
99 for (Int_t i=minIdx-1; i>=0; --i)
100 {
101 if (TMath::Abs(pos - orig[i].first) > minDist)
102 {
103 filtered.push_back(orig[i]);
104 pos = orig[i].first;
105 }
106 }
107 }
108
109 // Go from center to maximum.
110 if (minIdx < (size -1))
111 {
112 pos = orig[minIdx].first;
113 for (Int_t i=minIdx+1; i<size; ++i)
114 {
115 if (TMath::Abs(orig[i].first - pos) > minDist)
116 {
117 filtered.push_back(orig[i]);
118 pos = orig[i].first;
119 }
120 }
121 }
122
123 // Set labels list and text format.
124 if (filtered.size() >= 2)
125 {
126 if ( minIdx > 0 )
127 fAxisPainter.SetTextFormat(orig.front().second, orig.back().second, orig[minIdx].second - orig[minIdx-1].second);
128 else
129 fAxisPainter.SetTextFormat(orig.front().second, orig.back().second, orig[minIdx+1].second - orig[minIdx].second);
130
131 fAxisPainter.RefLabVec().swap(filtered);
132 }
133 else
134 {
135 fAxisPainter.SetTextFormat(orig.front().second, orig.back().second, orig.back().second - orig.front().second);
136 }
137}
138
139////////////////////////////////////////////////////////////////////////////////
140/// Build an array of tick-mark position-value pairs.
141
143{
144 fAxisPainter.RefLabVec().clear();
145 fAxisPainter.RefTMVec().clear();
146
147 // Get list of label position-value pairs.
148
149
150 // Minimum/maximum are defined at the front/back element of list.
151 fAxisPainter.RefTMVec().push_back(TGLAxisPainter::TM_t(p1, -1));
152
153 if (fM->GetLabMode() == TEveProjectionAxes::kValue)
154 {
155 SplitIntervalByVal(p1, p2, ax);
156 }
157 else if (fM->GetLabMode() == TEveProjectionAxes::kPosition)
158 {
159 SplitIntervalByPos(p1, p2, ax);
160 }
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Add tick-marks at equidistant position.
165
167{
168 // Limits.
169 Int_t n1a = TMath::FloorNint(fM->GetNdivisions() / 100);
170 Int_t n2a = fM->GetNdivisions() - n1a * 100;
171 Int_t bn1, bn2;
172 Double_t bw1, bw2; // bin with first second order
173 Double_t bl1=0, bh1=0, bl2=0, bh2=0; // bin low, high first second order
174 THLimitsFinder::Optimize(p1, p2, n1a, bl1, bh1, bn1, bw1);
175 THLimitsFinder::Optimize(bl1, bl1+bw1, n2a, bl2, bh2, bn2, bw2);
176
177 Int_t n1=TMath::CeilNint(p1/bw1);
178 Int_t n2=TMath::FloorNint(p2/bw1);
179
180 TGLAxisPainter::LabVec_t &labVec = fAxisPainter.RefLabVec();
181 TGLAxisPainter::TMVec_t &tmVec = fAxisPainter.RefTMVec();
182
183 Float_t p = n1*bw1;
184 Float_t pMinor = p;
185 for (Int_t l=n1; l<=n2; l++)
186 {
187 // Labels.
188 labVec.push_back( TGLAxisPainter::Lab_t(p , fProjection->GetValForScreenPos(ax, p)));
189
190 // Tick-marks.
191 tmVec.push_back(TGLAxisPainter::TM_t(p, 0));
192 pMinor = p+bw2;
193 for (Int_t i=1; i<bn2; i++)
194 {
195 if (pMinor > p2) break;
196 tmVec.push_back( TGLAxisPainter::TM_t(pMinor, 1));
197 pMinor += bw2;
198 }
199 p += bw1;
200 }
201
202 // Complete second order tick-marks.
203 pMinor = n1*bw1 -bw2;
204 while ( pMinor > p1)
205 {
206 tmVec.push_back(TGLAxisPainter::TM_t(pMinor, 1));
207 pMinor -=bw2;
208 }
209}
210
211////////////////////////////////////////////////////////////////////////////////
212/// Add tick-marks on fixed value step.
213
215{
216
217 TGLAxisPainter::LabVec_t &labVec = fAxisPainter.RefLabVec();
218 TGLAxisPainter::TMVec_t &tmVec = fAxisPainter.RefTMVec();
219
220 // Limits
221 Int_t n1a = TMath::FloorNint(fM->GetNdivisions() / 100);
222 Int_t n2a = fM->GetNdivisions() - n1a * 100;
223 Int_t bn1, bn2;
224 Double_t bw1, bw2; // bin width first / second order
225 Double_t bl1=0, bh1=0, bl2=0, bh2=0; // bin low, high first / second order
226 Float_t v1 = fProjection->GetValForScreenPos(ax, p1);
227 Float_t v2 = fProjection->GetValForScreenPos(ax, p2);
228 THLimitsFinder::Optimize(v1, v2, n1a, bl1, bh1, bn1, bw1);
229 THLimitsFinder::Optimize(bl1, bl1+bw1, n2a, bl2, bh2, bn2, bw2);
230
231 Float_t pFirst, pSecond; // position of first, second order of tick-marks
232 Float_t v = bl1;
233
234 // cache values here
235 TEveVector dirVec;
236 fProjection->SetDirectionalVector(ax, dirVec);
237 TEveVector oCenter;
238 fProjection->GetOrthogonalCenter(ax, oCenter);
239
240 // step
241 for (Int_t l=0; l<=bn1; l++)
242 {
243 // Labels.
244 pFirst = fProjection->GetScreenVal(ax, v);
245 labVec.push_back(TGLAxisPainter::Lab_t(pFirst , v));
246 tmVec.push_back(TGLAxisPainter::TM_t(pFirst, 0));
247
248 // Tick-marks.
249 for (Int_t k=1; k<bn2; k++)
250 {
251 pSecond = fProjection->GetScreenVal(ax, v+k*bw2, dirVec, oCenter);
252 if (pSecond > p2) break;
253 tmVec.push_back(TGLAxisPainter::TM_t(pSecond, 1));
254 }
255 v += bw1;
256 }
257
258 // Complete second order tick-marks.
259 v = bl1 -bw2;
260 while ( v > v1)
261 {
262 pSecond = fProjection->GetScreenVal(ax, v, dirVec, oCenter);
263 if (pSecond < p1) break;
264 tmVec.push_back(TGLAxisPainter::TM_t(pSecond, 1));
265 v -= bw2;
266 }
267}
268
269////////////////////////////////////////////////////////////////////////////////
270/// Get range from bounding box of projection manager and frustum size.
271
272void TEveProjectionAxesGL::GetRange(Int_t ax, Float_t frustMin, Float_t frustMax, Float_t& min, Float_t& max) const
273{
274 Float_t* bb = fM->fManager->GetBBox();
275 // enlarge bbox times 2
276 Float_t bbMin = bb[ax*2];
277 Float_t bbMax = bb[ax*2 + 1];
278 Float_t off = ( bb[ax*2 + 1] - bb[ax*2]) * 0.5;
279 bbMin -= off;
280 bbMax += off;
281
282
283 // minimum
284 if (frustMin > bbMin) {
285 min = frustMin;
286 min += (frustMax - frustMin) * 0.1;
287 }
288 else {
289 min = bbMin;
290 }
291
292 // maximum
293 if (frustMax < bbMax) {
294 max = frustMax;
295 max -= (frustMax - frustMin) * 0.1;
296 }
297 else {
298 max = bbMax;
299 }
300}
301
302////////////////////////////////////////////////////////////////////////////////
303/// Draw function for TEveProjectionAxesGL. Skips line-pass of outline mode.
304
306{
307 if (rnrCtx.IsDrawPassOutlineLine())
308 return;
309
310 TGLObject::Draw(rnrCtx);
311}
312
313////////////////////////////////////////////////////////////////////////////////
314/// Actual rendering code.
315/// Virtual from TGLLogicalShape.
316
318{
319 if (rnrCtx.Selection() || rnrCtx.Highlight() || fM->fManager->GetBBox() == nullptr) return;
320
321 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
322
323 glDisable(GL_LIGHTING);
324 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
325 glEnable(GL_COLOR_MATERIAL);
326 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
327 glDisable(GL_CULL_FACE);
328
329 // Draw on front-clipping plane.
330 Float_t old_depth_range[2];
331 glGetFloatv(GL_DEPTH_RANGE, old_depth_range);
332 glDepthRange(0, 0.001);
333
334 // Frustum size.
335 TGLCamera &camera = rnrCtx.RefCamera();
340
341 if (fM->fUseColorSet)
342 {
343 TGLUtil::Color(rnrCtx.ColorSet().Markup());
344 fAxisPainter.SetUseAxisColors(kFALSE);
345 }
346
347 fProjection = fM->GetManager()->GetProjection();
348 glDisable(GL_LIGHTING);
349 // Projection center and origin marker.
350 {
351 Float_t d = ((r-l) > (b-t)) ? (b-t) : (r-l);
352 d *= 0.02f;
353 if (fM->GetDrawCenter())
354 {
355 Float_t* c = fProjection->GetProjectedCenter();
357 glBegin(GL_LINES);
358 glVertex3f(c[0] + d, c[1], c[2]); glVertex3f(c[0] - d, c[1], c[2]);
359 glVertex3f(c[0], c[1] + d, c[2]); glVertex3f(c[0], c[1] - d, c[2]);
360 glVertex3f(c[0], c[1], c[2] + d); glVertex3f(c[0], c[1], c[2] - d);
361 glEnd();
362 }
363 if (fM->GetDrawOrigin())
364 {
365 TEveVector zero;
366 fProjection->ProjectVector(zero, 0);
368 glBegin(GL_LINES);
369 glVertex3f(zero[0] + d, zero[1], zero[2]); glVertex3f(zero[0] - d, zero[1], zero[2]);
370 glVertex3f(zero[0], zero[1] + d, zero[2]); glVertex3f(zero[0], zero[1] - d, zero[2]);
371 glVertex3f(zero[0], zero[1], zero[2] + d); glVertex3f(zero[0], zero[1], zero[2] - d);
372 glEnd();
373 }
374 }
375
376 //
377 // Axes.
378 try {
379 using namespace TMath;
380 GLint vp[4];
381 glGetIntegerv(GL_VIEWPORT, vp);
382 Float_t refLength = TMath::Sqrt((TMath::Power(vp[2]-vp[0], 2) + TMath::Power(vp[3]-vp[1], 2)));
383 Float_t tickLength = TMath::Sqrt((TMath::Power(r-l, 2) + TMath::Power(t-b, 2)));
384 fAxisPainter.SetFontMode(TGLFont::kPixmap);
385 fAxisPainter.SetLabelFont(rnrCtx, TGLFontManager::GetFontNameFromId(fM->GetLabelFont()), TMath::CeilNint(refLength*fM->GetLabelSize()), tickLength*fM->GetLabelSize());
386
387 Float_t min, max;
388 // X-axis.
389 if (fM->fAxesMode == TEveProjectionAxes::kAll ||
391 {
392 GetRange(0, l, r, min, max);
393 SplitInterval(min, max, 0);
394
396 fAxisPainter.RefTMVec().push_back(TGLAxisPainter::TM_t(max, -1));
397
398 fAxisPainter.RefDir().Set(1, 0, 0);
399 fAxisPainter.RefTMOff(0).Set(0, tickLength, 0);
400
401 // Bottom.
402 glPushMatrix();
403 glTranslatef( 0, b, 0);
405 fAxisPainter.RnrLabels();
406 fAxisPainter.RnrLines();
407 glPopMatrix();
408
409 // Top.
410 glPushMatrix();
411 glTranslatef( 0, t, 0);
413 fAxisPainter.RefTMOff(0).Negate();
414 fAxisPainter.RnrLabels();
415 fAxisPainter.RnrLines();
416 glPopMatrix();
417 }
418
419 // Y-axis.
420 if (fM->fAxesMode == TEveProjectionAxes::kAll ||
421 fM->fAxesMode == TEveProjectionAxes::kVertical)
422 {
423 GetRange(1, b, t, min, max);
424 SplitInterval(min, max, 1);
425
427 fAxisPainter.RefTMVec().push_back(TGLAxisPainter::TM_t(max, -1));
428
429 fAxisPainter.RefDir().Set(0, 1, 0);
430 fAxisPainter.RefTMOff(0).Set(tickLength, 0 , 0);
431
432 // Left.
433 glPushMatrix();
434 glTranslatef(l, 0, 0);
436 fAxisPainter.RnrLabels();
437 fAxisPainter.RnrLines();
438 glPopMatrix();
439
440 // Right.
441 glPushMatrix();
442 glTranslatef(r, 0, 0);
444 fAxisPainter.RefTMOff(0).Negate();
445 fAxisPainter.RnrLabels();
446 fAxisPainter.RnrLines();
447 glPopMatrix();
448 }
449 }
450 catch (TEveException& exc)
451 {
452 Warning("TEveProjectionAxesGL::DirectDraw", "caught exception: '%s'.", exc.Data());
453 }
454
455 glDepthRange(old_depth_range[0], old_depth_range[1]);
456
457 glPopAttrib();
458}
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
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
float Float_t
Float 4 bytes (float).
Definition RtypesCore.h:71
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char).
Definition RtypesCore.h:80
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
TEveVectorT< Float_t > TEveVector
Definition TEveVector.h:123
Exception class thrown by TEve classes and macros.
Definition TEveUtil.h:102
void Draw(TGLRnrCtx &rnrCtx) const override
Draw function for TEveProjectionAxesGL. Skips line-pass of outline mode.
void SplitIntervalByVal(Float_t min, Float_t max, Int_t axis) const
Add tick-marks on fixed value step.
void SplitIntervalByPos(Float_t min, Float_t max, Int_t axis) const
Add tick-marks at equidistant position.
TEveProjection * fProjection
void FilterOverlappingLabels(Int_t idx, Float_t ref) const
Filter overlapping labels.
void GetRange(Int_t ax, Float_t frustMin, Float_t frustMax, Float_t &start, Float_t &en) const
Get range from bounding box of projection manager and frustum size.
TEveProjectionAxes * fM
void DirectDraw(TGLRnrCtx &rnrCtx) const override
Actual rendering code.
void SetBBox() override
Fill the bounding-box data of the logical-shape.
Bool_t SetModel(TObject *obj, const Option_t *opt=nullptr) override
Set model object.
void SplitInterval(Float_t x1, Float_t x2, Int_t axis) const
Build an array of tick-mark position-value pairs.
Axes for non-linear projections.
std::pair< Float_t, Int_t > TM_t
std::vector< Lab_t > LabVec_t
std::vector< TM_t > TMVec_t
std::pair< Float_t, Float_t > Lab_t
Abstract base camera class - concrete classes for orthographic and perspective cameras derive from it...
Definition TGLCamera.h:44
const TGLPlane & FrustumPlane(EFrustumPlane plane) const
Definition TGLCamera.h:219
TGLColor & Markup()
Definition TGLUtil.h:854
static const char * GetFontNameFromId(Int_t)
Get font name from TAttAxis font id.
virtual void Draw(TGLRnrCtx &rnrCtx) const
Draw the GL drawable, using draw flags.
TObject * fExternalObj
! Also plays the role of ID.
Bool_t fDLCache
! use display list caching
TT * SetModelDynCast(TObject *obj)
Definition TGLObject.h:37
void SetAxisAlignedBBox(Float_t xmin, Float_t xmax, Float_t ymin, Float_t ymax, Float_t zmin, Float_t zmax)
Set axis-aligned bounding-box.
Definition TGLObject.cxx:85
Double_t D() const
Definition TGLUtil.h:556
The TGLRnrCtx class aggregates data for a given redering context as needed by various parts of the RO...
Definition TGLRnrCtx.h:41
TGLColorSet & ColorSet()
Return reference to current color-set (top of the stack).
TGLCamera & RefCamera()
Definition TGLRnrCtx.h:157
Bool_t IsDrawPassOutlineLine() const
Definition TGLRnrCtx.h:207
Bool_t Highlight() const
Definition TGLRnrCtx.h:218
Bool_t Selection() const
Definition TGLRnrCtx.h:222
static void Color(const TGLColor &color)
Set color from TGLColor.
Definition TGLUtil.cxx:1688
static Float_t LineWidth()
Get the line-width, taking the global scaling into account.
Definition TGLUtil.cxx:1934
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.
Mother of all ROOT objects.
Definition TObject.h:42
const char * Data() const
Definition TString.h:384
TMath.
Definition TMathBase.h:35
Int_t FloorNint(Double_t x)
Returns the nearest integer of TMath::Floor(x).
Definition TMath.h:697
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:732
Int_t CeilNint(Double_t x)
Returns the nearest integer of TMath::Ceil(x).
Definition TMath.h:685
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
TLine l
Definition textangle.C:4