CMS 3D CMS Logo

TEveEllipsoidGL.cc
Go to the documentation of this file.
2 
3 #include "TEveProjections.h" // AMT missing getter for projection center / beam-spot
4 
7 #include "TEveProjectionManager.h"
8 
9 #include "TMath.h"
10 
11 #include "TGLRnrCtx.h"
12 
13 #include "TMatrixDEigen.h"
14 #include "TMatrixDSym.h"
15 
16 #include "TDecompSVD.h"
17 #include "TGLIncludes.h"
18 
19 //==============================================================================
20 // TEveEllipsoidGL
21 //==============================================================================
22 
23 //______________________________________________________________________________
24 // OpenGL renderer class for TEveEllipsoid.
25 //
26 
27 //______________________________________________________________________________
28 TEveEllipsoidGL::TEveEllipsoidGL() : TGLObject(), fE(nullptr) {
29  // Constructor.
30 
31  // fDLCache = kFALSE; // Disable display list.
32 }
33 
34 //______________________________________________________________________________
35 Bool_t TEveEllipsoidGL::SetModel(TObject* obj, const Option_t* /*opt*/) {
36  // Set model object.
37 
38  fE = SetModelDynCast<TEveEllipsoid>(obj);
39  return kTRUE;
40 }
41 
42 //______________________________________________________________________________
44  // Set bounding box.
45  ((TEveEllipsoid*)fExternalObj)->ComputeBBox();
46  SetAxisAlignedBBox(((TEveEllipsoid*)fExternalObj)->AssertBBox());
47 }
48 
49 namespace {
50  GLUquadric* quad = nullptr; // !!!! AMT check why TGLQuadric crashes on mac
51 }
52 
53 //______________________________________________________________________________
54 void TEveEllipsoidGL::DirectDraw(TGLRnrCtx& /*rnrCtx*/) const {
55  // Render with OpenGL.
56 
57  // printf("TEveEllipsoidGL::DirectDraw LOD %s\n", fE->GetName());
58 
59  glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT | GL_LIGHTING_BIT);
60  glEnable(GL_NORMALIZE);
61  if (!quad)
62  quad = gluNewQuadric();
63 
64  glPushMatrix();
65 
66  TMatrixDSym xxx(3);
67  for (int i = 0; i < 3; i++)
68  for (int j = 0; j < 3; j++) {
69  xxx(i, j) = fE->RefEMtx()(i + 1, j + 1);
70  }
71  TMatrixDEigen eig(xxx);
72 
73  // rewrite for multmatrix ....
74  TEveTrans x;
75  for (int i = 0; i < 3; i++)
76  for (int j = 0; j < 3; j++) {
77  x(i + 1, j + 1) = eig.GetEigenVectors()(i, j);
78  }
79 
80  TVector3 a = x.GetBaseVec(1);
81  TVector3 c = a.Cross(x.GetBaseVec(2));
82  x.SetBaseVec(3, c);
83 
84  glTranslatef(fE->RefPos()[0], fE->RefPos()[1], fE->RefPos()[2]);
85  glMultMatrixd(x.Array());
86  glScalef(fE->RefExtent3D()[0], fE->RefExtent3D()[1], fE->RefExtent3D()[2]);
87  gluSphere(quad, 1., 30, 30);
88 
89  glPopMatrix();
90  glPopAttrib();
91 
92  // gluDeleteQuadric(quad);
93 }
94 
95 //==============================================================================
96 // TEveEllipsoidProjectedGL
97 //==============================================================================
98 
99 //______________________________________________________________________________
100 // OpenGL renderer class for TEveEllipsoidProjected.
101 //
102 
103 //______________________________________________________________________________
105  // Constructor.
106 
107  // fDLCache = kFALSE; // Disable display list.
108  fMultiColor = kTRUE;
109 }
110 
111 //______________________________________________________________________________
112 Bool_t TEveEllipsoidProjectedGL::SetModel(TObject* obj, const Option_t* /*opt*/) {
113  // Set model object.
114 
115  fM = SetModelDynCast<TEveEllipsoidProjected>(obj);
116  fE = dynamic_cast<TEveEllipsoid*>(fM->GetProjectable());
117  return fE != nullptr;
118 }
119 
120 //______________________________________________________________________________
122  // Set bounding box.
123 
124  SetAxisAlignedBBox(((TEveEllipsoidProjected*)fExternalObj)->AssertBBox());
125 }
126 
127 //______________________________________________________________________________
128 void TEveEllipsoidProjectedGL::DirectDraw(TGLRnrCtx& rnrCtx) const {
129  // Render with OpenGL.
130 
131  TEveProjection* proj = fM->GetManager()->GetProjection();
132 
133  glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT | GL_LINE_BIT | GL_POINT_BIT);
134  glDisable(GL_LIGHTING);
135  glDisable(GL_CULL_FACE);
136 
137  glPushMatrix();
138  if (proj->GetType() == TEveProjection::kPT_RPhi)
139  DrawRhoPhi();
140  else
141  DrawRhoZ();
142 
143  glPopMatrix();
144  glPopAttrib();
145 }
146 
147 //______________________________________________________________________________
149  float phiStart, float phiEnd, float phiStep, TEveVector& v0, TEveVector& v1, TEveVector& v2) const {
150  TEveProjection* proj = fM->GetManager()->GetProjection();
151  float phi = phiStart;
152  while (phi < phiEnd) {
153  TEveVector v = v0 + v1 * ((float)cos(phi)) + v2 * ((float)sin(phi));
154  proj->ProjectVector(v, fM->fDepth);
155  glVertex3fv(v.Arr());
156 
157  phi += phiStep;
158  }
159  TEveVector v = v0 + v1 * ((float)cos(phiEnd)) + v2 * ((float)sin(phiEnd));
160  proj->ProjectVector(v, fM->fDepth);
161  glVertex3fv(v.Arr());
162 }
163 
164 //-------------------------------------------------------------------------------
166  // printf("TEveEllipsoidProjectedGL::DirectDraw [%s ]\n", fE->GetName() );
167 
168  TMatrixDSym xxx(3);
169  for (int i = 0; i < 2; i++)
170  for (int j = 0; j < 2; j++) {
171  xxx(i, j) = fE->RefEMtx()(i + 1, j + 1);
172  }
173 
174  TMatrixDEigen eig(xxx);
175  TVectorD xxxEig(eig.GetEigenValuesRe());
176 
177  // Projection supports only floats :(
178  TEveVector v0(fE->RefPos()[0], fE->RefPos()[1], 0);
179  TEveVector v1(eig.GetEigenVectors()(0, 0), eig.GetEigenVectors()(0, 1), 0);
180  v1 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[0]));
181  TEveVector v2(eig.GetEigenVectors()(1, 0), eig.GetEigenVectors()(1, 1), 0);
182  v2 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[1]));
183 
184  TEveProjection* proj = fM->GetManager()->GetProjection();
185 
186  // fill
187  glBegin(GL_POLYGON);
188  drawArch(0, TMath::TwoPi(), TMath::TwoPi() / 20, v0, v1, v2);
189  glEnd();
190 
191  // frame
192  TGLUtil::LineWidth(fE->fLineWidth);
193  TGLUtil::Color(fE->fLineColor);
194 
195  glBegin(GL_LINE_LOOP);
196  drawArch(0, TMath::TwoPi(), TMath::TwoPi() / 20, v0, v1, v2);
197  glEnd();
198 
199  glBegin(GL_LINES);
200  {
201  // glColor3f(1, 0, 0);
202  TEveVector p1 = v0 - v1;
203  TEveVector p2 = v0 + v1;
204  proj->ProjectVector(p1, fM->fDepth);
205  proj->ProjectVector(p2, fM->fDepth);
206  glVertex3fv(p1.Arr());
207  glVertex3fv(p2.Arr());
208  }
209  {
210  // glColor3f(0, 1, 0);
211  TEveVector p1 = v0 - v2;
212  TEveVector p2 = v0 + v2;
213  proj->ProjectVector(p1, fM->fDepth);
214  proj->ProjectVector(p2, fM->fDepth);
215  glVertex3fv(p1.Arr());
216  glVertex3fv(p2.Arr());
217  }
218  glEnd();
219 }
220 
221 //--------------------------------------------------------------------
223  // printf("TEveEllipsoidProjectedGL::DirectDraw [%s ]\n", fE->GetTitle() );
224 
225  TEveVector v0(fE->RefPos()[0], fE->RefPos()[1], fE->RefPos()[2]);
226 
227  TMatrixDSym xxx(3);
228  xxx(0, 0) = 1;
229  for (int i = 1; i < 3; i++)
230  for (int j = 1; j < 3; j++) {
231  xxx(i, j) = fE->RefEMtx()(i + 1, j + 1);
232  }
233  TMatrixDEigen eig(xxx);
234  TVectorD xxxEig(eig.GetEigenValuesRe());
235 
236  TEveVector v1(0, eig.GetEigenVectors()(1, 2), eig.GetEigenVectors()(2, 2));
237  v1 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[2]));
238 
239  TEveVector v2(0, eig.GetEigenVectors()(1, 1), eig.GetEigenVectors()(2, 1));
240  v2 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[1]));
241  if (v1[1] * v2[2] > v1[2] * v2[1])
242  v2 *= -1;
243 
244  TEveProjection* proj = fM->GetManager()->GetProjection();
245 
246  // ellipse intersection with projection center
247  bool splitted = false;
248  int N = 20;
249  double phiStep = TMath::TwoPi() / N;
250 
251  // projection center can be moved in beam-spot
252  float bs = 0;
253  if (proj->GetDisplaceOrigin())
254  bs = proj->RefCenter()[1];
255 
256  float da = v2[1] * v2[1] + v1[1] * v1[1];
257  float db = 2 * v1[1] * (v0[1] - bs);
258  float dc = (v0[1] - bs) * (v0[1] - bs) - v2[1] * v2[1];
259  float disc = (db * db - 4 * da * dc);
260 
261  if (disc > 0) {
262  disc = sqrt(disc);
263  float cosS1 = (-db + disc) / (2 * da);
264  float cosS2 = (-db - disc) / (2 * da);
265  if (TMath::Abs(cosS1) < 1) {
266  splitted = true;
267  // printf("splitted \n");
268 
269  double phi1 = acos(cosS1);
270  double phi2 = acos(cosS2);
271  TEveVector ps1 = v0 + v1 * ((float)cos(phi1)) + v2 * ((float)sin(phi1));
272  TEveVector ps2 = v0 + v1 * ((float)cos(phi2)) + v2 * ((float)sin(phi2));
273 
274  // acos has values [0, Pi] , check the symetry over x axis (mirroring)
275  if (TMath::Abs(ps1[1] - bs) > 1e-5)
276  phi1 = TMath::TwoPi() - phi1;
277 
278  if (TMath::Abs(ps2[1] - bs) > 1e-5)
279  phi2 = TMath::TwoPi() - phi2;
280 
281  int N = 20;
282  double phiStep = TMath::TwoPi() / N;
283  double phiOffset = phiStep * 0.1;
284  double phiMin = TMath::Min(phi1, phi2);
285  double phiMax = TMath::Max(phi1, phi2);
286  // printf(" %f %f \n",phi1*TMath::RadToDeg(), phi2*TMath::RadToDeg() );
287 
288  // fill
289  // upper clothing
290  glBegin(GL_POLYGON);
291  drawArch(phiMin + phiOffset, phiMax - phiOffset, phiStep, v0, v1, v2);
292  glEnd();
293  // bottom clothing
294  glBegin(GL_POLYGON);
295  drawArch(phiMax + phiOffset, phiMax + TMath::TwoPi() - (phiMax - phiMin) - phiOffset, phiStep, v0, v1, v2);
296  glEnd();
297 
298  // frame
299  TGLUtil::LineWidth(fE->fLineWidth);
300  TGLUtil::Color(fE->fLineColor);
301  // upper clothing
302  glBegin(GL_LINE_LOOP);
303  drawArch(phiMin + phiOffset, phiMax - phiOffset, phiStep, v0, v1, v2);
304  glEnd();
305  // bottom clothing
306  glBegin(GL_LINE_LOOP);
307  drawArch(phiMax + phiOffset, phiMax + TMath::TwoPi() - (phiMax - phiMin) - phiOffset, phiStep, v0, v1, v2);
308  glEnd();
309  }
310  }
311 
312  if (!splitted) {
313  glBegin(GL_POLYGON);
314  drawArch(0, TMath::TwoPi(), phiStep, v0, v1, v2);
315  glEnd();
316  TGLUtil::LineWidth(fE->fLineWidth);
317  TGLUtil::Color(fE->fLineColor);
318  glBegin(GL_LINE_LOOP);
319  drawArch(0, TMath::TwoPi(), phiStep, v0, v1, v2);
320  glEnd();
321  }
322 
323  drawRhoZAxis(v0, v2);
324  drawRhoZAxis(v0, v1);
325 }
326 
327 //______________________________________________________________________________
328 void TEveEllipsoidProjectedGL::drawRhoZAxis(TEveVector& v0, TEveVector& v2) const {
329  glBegin(GL_LINES);
330  TEveProjection* proj = fM->GetManager()->GetProjection();
331 
332  float bs = 0;
333  if (proj->GetDisplaceOrigin())
334  bs = proj->RefCenter()[1];
335 
336  float off = (v2[1] > v0[1]) ? 0.01 : -0.01;
337  TEveVector alu = v0 + v2;
338  proj->ProjectVector(alu, fM->fDepth);
339  glVertex3fv(alu.Arr());
340 
341  if (TMath::Abs(v0[1] / v2[1]) < 1) {
342  alu = v0 - ((float)((1 - off) * (v0[1] - bs) / v2[1])) * v2;
343  proj->ProjectVector(alu, fM->fDepth);
344  glVertex3fv(alu.Arr());
345 
346  //============================
347 
348  alu = v0 - ((float)((1 + off) * (v0[1] - bs) / v2[1])) * v2;
349  proj->ProjectVector(alu, fM->fDepth);
350  glVertex3fv(alu.Arr());
351  }
352 
353  alu = v0 - v2;
354  proj->ProjectVector(alu, fM->fDepth);
355  glVertex3fv(alu.Arr());
356 
357  glEnd();
358 }
const double TwoPi
TEveVector & RefPos()
Definition: TEveEllipsoid.h:36
void drawArch(float pStart, float pEnd, float phiStep, TEveVector &v0, TEveVector &v1, TEveVector &v2) const
TEveEllipsoid * fE
Bool_t SetModel(TObject *obj, const Option_t *opt=nullptr) override
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
void DirectDraw(TGLRnrCtx &rnrCtx) const override
T sqrt(T t)
Definition: SSEVec.h:23
TEveTrans & RefEMtx()
Definition: TEveEllipsoid.h:38
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
TEveVector & RefExtent3D()
Definition: TEveEllipsoid.h:37
#define N
Definition: blowfish.cc:9
void DirectDraw(TGLRnrCtx &rnrCtx) const override
TEveEllipsoidProjected * fM
double a
Definition: hdecay.h:121
void SetBBox() override
void drawRhoZAxis(TEveVector &v, TEveVector &) const
Bool_t SetModel(TObject *obj, const Option_t *opt=nullptr) override