CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/Fireworks/Vertices/src/TEveEllipsoidGL.cc

Go to the documentation of this file.
00001 #include "Fireworks/Vertices/interface/TEveEllipsoidGL.h"
00002 
00003 #define protected public  
00004 #include "TEveProjections.h" // AMT missing getter for projection center / beam-spot
00005 #undef protected
00006 
00007 #include "Fireworks/Vertices/interface/TEveEllipsoidGL.h"
00008 #include "Fireworks/Vertices/interface/TEveEllipsoid.h"
00009 #include "TEveProjectionManager.h"
00010 
00011 #include "TMath.h"
00012 
00013 #include "TGLRnrCtx.h"
00014 
00015 #include "TMatrixDEigen.h"
00016 #include "TMatrixDSym.h"
00017 
00018 #include "TDecompSVD.h"
00019 #include "TGLIncludes.h"
00020 
00021 //==============================================================================
00022 // TEveEllipsoidGL
00023 //==============================================================================
00024 
00025 //______________________________________________________________________________
00026 // OpenGL renderer class for TEveEllipsoid.
00027 //
00028 
00029 
00030 
00031 //______________________________________________________________________________
00032 TEveEllipsoidGL::TEveEllipsoidGL() :
00033    TGLObject(), fE(0)
00034 {
00035    // Constructor.
00036 
00037    // fDLCache = kFALSE; // Disable display list.
00038 }
00039 
00040 //______________________________________________________________________________
00041 Bool_t TEveEllipsoidGL::SetModel(TObject* obj, const Option_t* /*opt*/)
00042 {
00043    // Set model object.
00044 
00045    fE = SetModelDynCast<TEveEllipsoid>(obj);
00046    return kTRUE;
00047 }
00048 
00049 //______________________________________________________________________________
00050 void TEveEllipsoidGL::SetBBox()
00051 {
00052    // Set bounding box.
00053    ( (TEveEllipsoid*)fExternalObj)->ComputeBBox();
00054    SetAxisAlignedBBox(((TEveEllipsoid*)fExternalObj)->AssertBBox());
00055 }
00056 
00057 namespace {
00058 GLUquadric* quad = 0; // !!!! AMT check why TGLQuadric crashes on mac
00059 }
00060 
00061 //______________________________________________________________________________
00062 void TEveEllipsoidGL::DirectDraw(TGLRnrCtx& /*rnrCtx*/) const
00063 {
00064    // Render with OpenGL.
00065 
00066    // printf("TEveEllipsoidGL::DirectDraw LOD %s\n", fE->GetName());
00067 
00068    glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT | GL_LIGHTING_BIT);
00069    glEnable(GL_NORMALIZE );
00070    if(!quad)
00071       quad = gluNewQuadric();
00072 
00073    glPushMatrix();
00074 
00075    TMatrixDSym xxx(3);
00076    for(int i=0;i<3;i++)
00077       for(int j=0;j<3;j++)
00078       {
00079          xxx(i,j) = fE->RefEMtx()(i+1,j+1);
00080       }
00081    TMatrixDEigen eig(xxx);
00082 
00083 
00084    // rewrite for multmatrix ....
00085    TEveTrans x;
00086    for(int i=0;i<3;i++)
00087       for(int j=0;j<3;j++)
00088       {
00089          x(i+1, j+1) =  eig.GetEigenVectors()(i,j);
00090       }
00091 
00092    TVector3 a =  x.GetBaseVec(1);
00093    TVector3 c = a.Cross(x.GetBaseVec(2));
00094    x.SetBaseVec(3, c);
00095 
00096    glTranslatef(fE->RefPos()[0], fE->RefPos()[1], fE->RefPos()[2]);
00097    glMultMatrixd(x.Array());
00098    glScalef(fE->RefExtent3D()[0] , fE->RefExtent3D()[1], fE->RefExtent3D()[2]);
00099    gluSphere(quad,1. , 30, 30);
00100 
00101    glPopMatrix();
00102    glPopAttrib();
00103 
00104 
00105    // gluDeleteQuadric(quad);
00106 }
00107 
00108 
00109 //==============================================================================
00110 // TEveEllipsoidProjectedGL
00111 //==============================================================================
00112 
00113 //______________________________________________________________________________
00114 // OpenGL renderer class for TEveEllipsoidProjected.
00115 //
00116 
00117 
00118 
00119 //______________________________________________________________________________
00120 TEveEllipsoidProjectedGL::TEveEllipsoidProjectedGL() :
00121    fM(0)
00122 {
00123    // Constructor.
00124 
00125    // fDLCache = kFALSE; // Disable display list.
00126    fMultiColor = kTRUE;
00127 }
00128 
00129 //______________________________________________________________________________
00130 Bool_t TEveEllipsoidProjectedGL::SetModel(TObject* obj, const Option_t* /*opt*/)
00131 {
00132    // Set model object.
00133 
00134    fM = SetModelDynCast<TEveEllipsoidProjected>(obj);
00135    fE = dynamic_cast<TEveEllipsoid*>(fM->GetProjectable());
00136    return fE != 0;
00137 }
00138 
00139 //______________________________________________________________________________
00140 void TEveEllipsoidProjectedGL::SetBBox()
00141 {
00142    // Set bounding box.
00143 
00144    SetAxisAlignedBBox(((TEveEllipsoidProjected*)fExternalObj)->AssertBBox());
00145 }
00146 
00147 //______________________________________________________________________________
00148 void TEveEllipsoidProjectedGL::DirectDraw(TGLRnrCtx& rnrCtx) const
00149 {
00150    // Render with OpenGL.
00151  
00152    TEveProjection *proj = fM->GetManager()->GetProjection();
00153    
00154    
00155    glPushAttrib(GL_ENABLE_BIT| GL_POLYGON_BIT | GL_LINE_BIT | GL_POINT_BIT);
00156    glDisable(GL_LIGHTING);
00157    glDisable(GL_CULL_FACE);
00158 
00159    glPushMatrix();
00160    if ( proj->GetType() == TEveProjection::kPT_RPhi)
00161       DrawRhoPhi();
00162    else
00163       DrawRhoZ();
00164 
00165    glPopMatrix();
00166    glPopAttrib();  
00167 }
00168 
00169 //-------------------------------------------------------------------------------
00170 
00171 void TEveEllipsoidProjectedGL::drawArch(float phiStart, float phiEnd, float phiStep, TEveVector& v0,  TEveVector& v1, TEveVector& v2) const
00172 {
00173    TEveProjection *proj = fM->GetManager()->GetProjection();
00174    float phi = phiStart;
00175    while (phi < phiEnd ) {
00176       TEveVector v = v0 + v1*((float)cos(phi)) + v2*((float)sin(phi));
00177       proj->ProjectVector(v, fM->fDepth);
00178       glVertex3fv(v.Arr());
00179       
00180       phi += phiStep;
00181    }
00182    TEveVector v = v0 + v1*((float)cos(phiEnd)) + v2*((float)sin(phiEnd));
00183    proj->ProjectVector(v, fM->fDepth);
00184    glVertex3fv(v.Arr());   
00185 }
00186 
00187  //-------------------------------------------------------------------------------
00188 void TEveEllipsoidProjectedGL::DrawRhoPhi() const
00189 {
00190    // printf("TEveEllipsoidProjectedGL::DirectDraw [%s ]\n", fE->GetName() );
00191 
00192    TMatrixDSym xxx(3);
00193    for(int i=0;i<2;i++)
00194       for(int j=0;j<2;j++)
00195       {
00196          xxx(i,j) = fE->RefEMtx()(i+1,j+1);
00197       }
00198    
00199    TMatrixDEigen eig(xxx);
00200    TVectorD xxxEig ( eig.GetEigenValuesRe());
00201 
00202  
00203    // Projection supports only floats  :(
00204    TEveVector v0(fE->RefPos()[0], fE->RefPos()[1], 0);
00205    TEveVector v1(eig.GetEigenVectors()(0, 0) , eig.GetEigenVectors()(0, 1), 0 );
00206    v1 *= fE->fEScale *  sqrt(TMath::Abs(xxxEig[0]));
00207    TEveVector v2(eig.GetEigenVectors()(1, 0) , eig.GetEigenVectors()(1, 1), 0 );
00208    v2 *= fE->fEScale *  sqrt(TMath::Abs(xxxEig[1]));
00209    
00210    TEveProjection *proj = fM->GetManager()->GetProjection();
00211       
00212   // fill
00213    glBegin(GL_POLYGON);   
00214    drawArch(0, TMath::TwoPi(),  TMath::TwoPi()/20, v0, v1, v2);
00215    glEnd();
00216    
00217    // frame
00218    TGLUtil::LineWidth(fE->fLineWidth);
00219    TGLUtil::Color(fE->fLineColor);
00220    
00221    glBegin(GL_LINE_LOOP);   
00222    drawArch(0, TMath::TwoPi(),  TMath::TwoPi()/20, v0, v1, v2);
00223    glEnd();
00224    
00225    glBegin(GL_LINES);
00226    {
00227       // glColor3f(1, 0, 0);
00228       TEveVector p1 = v0 - v1;
00229       TEveVector p2 = v0 + v1;
00230       proj->ProjectVector(p1, fM->fDepth);
00231       proj->ProjectVector(p2, fM->fDepth);
00232       glVertex3fv(p1.Arr());
00233       glVertex3fv(p2.Arr());
00234    }
00235    {
00236       //  glColor3f(0, 1, 0);
00237       TEveVector p1 = v0 - v2;
00238       TEveVector p2 = v0 + v2;
00239       proj->ProjectVector(p1, fM->fDepth);
00240       proj->ProjectVector(p2, fM->fDepth);
00241       glVertex3fv(p1.Arr());
00242       glVertex3fv(p2.Arr());
00243    }
00244    glEnd();
00245    
00246    
00247    
00248 }
00249 
00250 //--------------------------------------------------------------------
00251 void TEveEllipsoidProjectedGL::DrawRhoZ() const
00252 {
00253    // printf("TEveEllipsoidProjectedGL::DirectDraw [%s ]\n", fE->GetTitle() );
00254  
00255    TEveVector v0(fE->RefPos()[0], fE->RefPos()[1], fE->RefPos()[2]);
00256    
00257    TMatrixDSym xxx(3);
00258    xxx(0, 0) = 1;
00259    for(int i=1;i<3;i++)
00260       for(int j=1;j<3;j++)
00261       {
00262          xxx(i,j) = fE->RefEMtx()(i+1,j+1);
00263       }   
00264    TMatrixDEigen eig(xxx);
00265    TVectorD xxxEig ( eig.GetEigenValuesRe());
00266 
00267 
00268    TEveVector v1(0, eig.GetEigenVectors()(1, 2), eig.GetEigenVectors()(2, 2));
00269    v1 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[2]));
00270 
00271    TEveVector v2(0, eig.GetEigenVectors()(1, 1), eig.GetEigenVectors()(2, 1));
00272    v2 *= fE->fEScale * sqrt(TMath::Abs(xxxEig[1]));
00273    if (v1[1]*v2[2] > v1[2]*v2[1])
00274       v2 *= -1;
00275 
00276    
00277    TEveProjection *proj = fM->GetManager()->GetProjection();
00278    
00279    // ellipse intersection with projection center
00280    bool splitted = false;
00281    int N = 20;
00282    double phiStep = TMath::TwoPi()/N;
00283    
00284    // projection center can be moved in beam-spot 
00285    float bs = 0;
00286    if (proj->GetDisplaceOrigin())
00287       bs = proj->fCenter[1];
00288 
00289    float da = v2[1]*v2[1] + v1[1]*v1[1];
00290    float db = 2 * v1[1] * (v0[1]-bs);
00291    float dc = (v0[1]-bs)*(v0[1]-bs) - v2[1]*v2[1];
00292    float disc = (db*db -4*da*dc);
00293    
00294    if ( disc > 0) {
00295       disc = sqrt(disc);
00296       float cosS1 = ( -db + disc)/(2 * da);
00297       float cosS2 = ( -db - disc)/(2 * da);
00298       if (TMath::Abs(cosS1) < 1) {
00299          splitted = true;
00300          // printf("splitted \n");
00301 
00302          double phi1 = acos(cosS1);
00303          double phi2 = acos(cosS2);
00304          TEveVector ps1 = v0 + v1*((float)cos(phi1)) + v2*((float)sin(phi1));
00305          TEveVector ps2 = v0 + v1*((float)cos(phi2)) + v2*((float)sin(phi2));
00306          
00307         
00308 
00309          // acos has values [0, Pi] , check the symetry over x axis (mirroring)
00310          if (TMath::Abs(ps1[1] - bs) > 1e-5)
00311             phi1 = TMath::TwoPi() -phi1;
00312       
00313          if (TMath::Abs(ps2[1] - bs) > 1e-5) 
00314             phi2 = TMath::TwoPi() -phi2;         
00315          
00316          int N = 20;
00317          double phiStep = TMath::TwoPi()/N;
00318          double phiOffset = phiStep*0.1;
00319          double phiMin = TMath::Min(phi1, phi2);
00320          double phiMax = TMath::Max(phi1, phi2);         
00321          // printf(" %f %f \n",phi1*TMath::RadToDeg(), phi2*TMath::RadToDeg() );
00322 
00323          // fill
00324          // upper clothing
00325          glBegin(GL_POLYGON);
00326          drawArch(phiMin + phiOffset, phiMax - phiOffset, phiStep, v0, v1, v2);
00327          glEnd();
00328          // bottom clothing
00329          glBegin(GL_POLYGON);
00330          drawArch(phiMax + phiOffset, phiMax + TMath::TwoPi() - (phiMax -phiMin) - phiOffset, phiStep, v0, v1, v2);
00331          glEnd();
00332          
00333          // frame
00334          TGLUtil::LineWidth(fE->fLineWidth);
00335          TGLUtil::Color(fE->fLineColor);
00336          // upper clothing
00337          glBegin(GL_LINE_LOOP);
00338          drawArch(phiMin + phiOffset, phiMax - phiOffset, phiStep, v0, v1, v2);
00339          glEnd();
00340          // bottom clothing
00341          glBegin(GL_LINE_LOOP);
00342          drawArch(phiMax + phiOffset, phiMax + TMath::TwoPi() - (phiMax -phiMin) - phiOffset, phiStep, v0, v1, v2);
00343          glEnd();
00344          
00345       }
00346    }
00347    
00348    
00349    if (!splitted) {
00350        glBegin(GL_POLYGON);
00351       drawArch(0, TMath::TwoPi(), phiStep, v0, v1, v2);
00352       glEnd();
00353       TGLUtil::LineWidth(fE->fLineWidth);
00354       TGLUtil::Color(fE->fLineColor);
00355       glBegin(GL_LINE_LOOP);
00356       drawArch(0, TMath::TwoPi(), phiStep, v0, v1, v2);
00357       glEnd();  
00358    }
00359    
00360    drawRhoZAxis(v0, v2);
00361    drawRhoZAxis(v0, v1);
00362 }
00363 //______________________________________________________________________________
00364 void TEveEllipsoidProjectedGL::drawRhoZAxis(TEveVector& v0, TEveVector& v2) const
00365 {
00366    glBegin(GL_LINES);
00367    TEveProjection* proj =   fM->GetManager()->GetProjection();
00368    
00369    float bs = 0;
00370    if (proj->GetDisplaceOrigin())
00371       bs = proj->fCenter[1];
00372    
00373    float off = (v2[1] > v0[1] ) ? 0.01 : -0.01;
00374    TEveVector alu = v0 + v2;
00375    proj->ProjectVector(alu, fM->fDepth);
00376    glVertex3fv(alu.Arr());   
00377    
00378    if (TMath::Abs(v0[1]/v2[1]) < 1 )
00379    {
00380       alu = v0 - ((float) ((1-off) *(v0[1]-bs)/v2[1])) * v2;
00381       proj->ProjectVector(alu, fM->fDepth);
00382       glVertex3fv(alu.Arr());   
00383       
00384       //============================
00385       
00386       alu = v0 - ((float) ((1+off) * (v0[1]-bs)/v2[1])) * v2;
00387       proj->ProjectVector(alu, fM->fDepth);
00388       glVertex3fv(alu.Arr());  
00389    }
00390    
00391    alu = v0 - v2;
00392    proj->ProjectVector(alu, fM->fDepth);
00393    glVertex3fv(alu.Arr());   
00394    
00395    glEnd();
00396 }