TGLPlotBox.cxx

Go to the documentation of this file.
00001 // @(#)root/gl:$Id$
00002 // Author:  Timur Pocheptsov  31/08/2006
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include <algorithm>
00013 
00014 #include "TColor.h"
00015 
00016 #include "TGLIncludes.h"
00017 #include "TGLPlotBox.h"
00018 
00019 //______________________________________________________________________________
00020 //
00021 // Implementation of a box around a histogram/function for
00022 // plot-painters.
00023 
00024 ClassImp(TGLPlotBox)
00025 
00026 const Int_t TGLPlotBox::fgFramePlanes[][4] =
00027    {
00028     {0, 4, 5, 1},
00029     {1, 5, 6, 2},
00030     {2, 6, 7, 3},
00031     {0, 3, 7, 4},
00032     {0, 1, 2, 3}
00033    };
00034 const Double_t TGLPlotBox::fgNormals[][3] =
00035    {
00036     { 0., 1., 0.},
00037     {-1., 0., 0.},
00038     { 0.,-1., 0.},
00039     { 1., 0., 0.},
00040     { 0., 0., 1.}
00041    };
00042 const Int_t TGLPlotBox::fgBackPairs[][2] =
00043    {
00044     {2, 1},
00045     {3, 2},
00046     {0, 3},
00047     {1, 0}
00048    };
00049 
00050 //______________________________________________________________________________
00051 TGLPlotBox::TGLPlotBox(Bool_t xoy, Bool_t xoz, Bool_t yoz)
00052                : fFrameColor(0),
00053                  fXOYSelectable(xoy),
00054                  fXOZSelectable(xoz),
00055                  fYOZSelectable(yoz),
00056                  fSelectablePairs(),
00057                  fFrontPoint(0),
00058                  fRangeXU(1.),
00059                  fRangeYU(1.),
00060                  fRangeZU(1.)
00061 {
00062    // Constructor.
00063    //Front point is 0.
00064    fSelectablePairs[0][0] = xoz;
00065    fSelectablePairs[0][1] = yoz;
00066    //Front point is 1.
00067    fSelectablePairs[1][0] = yoz;
00068    fSelectablePairs[1][1] = xoz;
00069    //Front point is 2.
00070    fSelectablePairs[2][0] = xoz;
00071    fSelectablePairs[2][1] = yoz;
00072    //Front point is 3.
00073    fSelectablePairs[3][0] = yoz;
00074    fSelectablePairs[3][1] = xoz;
00075 }
00076 
00077 
00078 //______________________________________________________________________________
00079 TGLPlotBox::~TGLPlotBox()
00080 {
00081    // Empty dtor to suppress g++ warnings.
00082 }
00083 
00084 
00085 //______________________________________________________________________________
00086 void TGLPlotBox::DrawBox(Int_t selected, Bool_t selectionPass, const std::vector<Double_t> &zLevels,
00087                          Bool_t highColor)const
00088 {
00089    // Draw back box for a plot.
00090 
00091    using namespace Rgl;
00092    TGLDisableGuard depthTest(GL_DEPTH_TEST); //[0-0]
00093    glDepthMask(GL_FALSE);//[1
00094 
00095    if (!selectionPass) {
00096       glEnable(GL_BLEND);//[2
00097       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00098       glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00099       glEnable(GL_LINE_SMOOTH);//[3
00100    }
00101 
00102    //Back planes are partially transparent to make their color smoother.
00103    Float_t backColor[] = {0.9f, 0.9f, 0.9f, 0.85f};
00104    if (fFrameColor)
00105       fFrameColor->GetRGB(backColor[0], backColor[1], backColor[2]);
00106 
00107    if (!selectionPass) {
00108       glMaterialfv(GL_FRONT, GL_DIFFUSE, backColor);
00109       if (selected == 1) {
00110          fXOYSelectable ?
00111                          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
00112                         :
00113                          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
00114       }
00115    } else
00116       ObjectIDToColor(1, highColor);//Bottom plane, encoded as 1 in a selection buffer.
00117 
00118    DrawQuadFilled(f3DBox[0], f3DBox[1], f3DBox[2], f3DBox[3], TGLVector3(0., 0., 1.));
00119 
00120    if (!selectionPass) {
00121       if (selected == 1)
00122          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
00123       else if (selected == 2)
00124          fSelectablePairs[fFrontPoint][0] ?
00125             glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
00126            :glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
00127    } else
00128       ObjectIDToColor(2, highColor);//Left plane, encoded as 2 in a selection buffer.
00129 
00130    DrawBackPlane(fgBackPairs[fFrontPoint][0], selectionPass, zLevels);
00131 
00132    if (!selectionPass) {
00133       if (selected == 2)
00134          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
00135       else if (selected == 3)
00136          fSelectablePairs[fFrontPoint][1] ?
00137             glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
00138            :glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
00139    } else
00140       ObjectIDToColor(3, highColor); //Right plane, encoded as 3 in a selection buffer.
00141 
00142    DrawBackPlane(fgBackPairs[fFrontPoint][1], selectionPass, zLevels);
00143 
00144    glDepthMask(GL_TRUE);//1]
00145    if (!selectionPass) {
00146       if (selected == 3)
00147          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
00148       glDisable(GL_BLEND);//2]
00149       glDisable(GL_LINE_SMOOTH);//3]
00150    }
00151 }
00152 
00153 
00154 //______________________________________________________________________________
00155 void TGLPlotBox::SetPlotBox(const Rgl::Range_t &x, const Rgl::Range_t &y, const Rgl::Range_t &z)
00156 {
00157    // Set up a frame box.
00158 
00159    f3DBox[0].Set(x.first,  y.first,  z.first);
00160    f3DBox[1].Set(x.second, y.first,  z.first);
00161    f3DBox[2].Set(x.second, y.second, z.first);
00162    f3DBox[3].Set(x.first,  y.second, z.first);
00163    f3DBox[4].Set(x.first,  y.first,  z.second);
00164    f3DBox[5].Set(x.second, y.first,  z.second);
00165    f3DBox[6].Set(x.second, y.second, z.second);
00166    f3DBox[7].Set(x.first,  y.second, z.second);
00167 }
00168 
00169 //______________________________________________________________________________
00170 void TGLPlotBox::SetPlotBox(const Rgl::Range_t &x, Double_t xr, const Rgl::Range_t &y, Double_t yr,
00171                             const Rgl::Range_t &z, Double_t zr)
00172 {
00173    // Set up a frame box.
00174    fRangeXU = xr;
00175    fRangeYU = yr;
00176    fRangeZU = zr;
00177 
00178    SetPlotBox(x, y, z);
00179 }
00180 
00181 //______________________________________________________________________________
00182 void TGLPlotBox::SetFrameColor(const TColor *color)
00183 {
00184    // Back box color.
00185 
00186    fFrameColor = color;
00187 }
00188 
00189 namespace {
00190 
00191    bool Compare(const TGLVertex3 &v1, const TGLVertex3 &v2)
00192    {
00193       return v1.Z() < v2.Z();
00194    }
00195 
00196 }
00197 
00198 
00199 //______________________________________________________________________________
00200 Int_t TGLPlotBox::FindFrontPoint()const
00201 {
00202    // Convert 3d points into window coordinate system
00203    // and find the nearest.
00204 
00205    Double_t mvMatrix[16] = {0.};
00206    glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix);
00207    Double_t prMatrix[16] = {0.};
00208    glGetDoublev(GL_PROJECTION_MATRIX, prMatrix);
00209    Int_t viewport[4] = {0};
00210    glGetIntegerv(GL_VIEWPORT, viewport);
00211 
00212    const Double_t zMin = f3DBox[0].Z();
00213    const Double_t zMax = f3DBox[4].Z();
00214 
00215    const Double_t uBox[][2] = {{-fRangeXU / 2., -fRangeYU / 2.},
00216                                { fRangeXU / 2., -fRangeYU / 2.},
00217                                { fRangeXU / 2.,  fRangeYU / 2.},
00218                                {-fRangeXU / 2.,  fRangeYU / 2.}};
00219    //const Double_t uBox[][2] = {{-1., -1.}, {1., -1.}, {1., 1.}, {-1., 1.}};
00220 
00221 
00222    for (Int_t i = 0; i < 4; ++i) {
00223       gluProject(f3DBox[i].X(), f3DBox[i].Y(), zMin, mvMatrix, prMatrix, viewport,
00224                  &f2DBox[i].X(), &f2DBox[i].Y(), &f2DBox[i].Z());
00225       gluProject(f3DBox[i].X(), f3DBox[i].Y(), zMax, mvMatrix, prMatrix, viewport,
00226                  &f2DBox[i + 4].X(), &f2DBox[i + 4].Y(), &f2DBox[i + 4].Z());
00227 
00228       gluProject(uBox[i][0], uBox[i][1], -0.5, mvMatrix, prMatrix, viewport,
00229                  &f2DBoxU[i].X(), &f2DBoxU[i].Y(), &f2DBoxU[i].Z());
00230       gluProject(uBox[i][0], uBox[i][1], 0.5, mvMatrix, prMatrix, viewport,
00231                  &f2DBoxU[i + 4].X(), &f2DBoxU[i + 4].Y(), &f2DBoxU[i + 4].Z());
00232    }
00233 
00234    //return fFrontPoint = std::min_element(f2DBox, f2DBox + 4, Compare) - f2DBox;
00235    return fFrontPoint = std::min_element(f2DBoxU, f2DBoxU + 4, Compare) - f2DBoxU;
00236 }
00237 
00238 
00239 //______________________________________________________________________________
00240 Int_t TGLPlotBox::GetFrontPoint()const
00241 {
00242    // The nearest point.
00243 
00244    return fFrontPoint;
00245 }
00246 
00247 
00248 //______________________________________________________________________________
00249 const TGLVertex3 *TGLPlotBox::Get3DBox()const
00250 {
00251    // Get 3D box.
00252 
00253    return f3DBox;
00254 }
00255 
00256 
00257 //______________________________________________________________________________
00258 const TGLVertex3 *TGLPlotBox::Get2DBox()const
00259 {
00260    // Get 2D box.
00261 
00262 //   return f2DBox;
00263    return f2DBoxU;
00264 }
00265 
00266 
00267 //______________________________________________________________________________
00268 void TGLPlotBox::DrawBackPlane(Int_t plane, Bool_t selectionPass,
00269                                const std::vector<Double_t> &zLevels)const
00270 {
00271    //Draw back plane with number 'plane'
00272    using namespace Rgl;
00273    const Int_t *vertInd = fgFramePlanes[plane];
00274    DrawQuadFilled(f3DBox[vertInd[0]], f3DBox[vertInd[1]], f3DBox[vertInd[2]],
00275                   f3DBox[vertInd[3]], fgNormals[plane]);
00276    //Antialias back plane outline.
00277    if (!selectionPass) {
00278       const TGLDisableGuard lightGuard(GL_LIGHTING);
00279       glColor3d(0., 0., 0.);
00280       DrawQuadOutline(f3DBox[vertInd[0]], f3DBox[vertInd[1]],
00281                       f3DBox[vertInd[2]], f3DBox[vertInd[3]]);
00282       //draw grid.
00283       const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);//[1-1]
00284       const UShort_t stipple = 0x5555;
00285       glLineStipple(1, stipple);
00286 
00287       Double_t lineCaps[][4] =
00288       {
00289          {f3DBox[1].X(), f3DBox[0].Y(), f3DBox[0].X(), f3DBox[0].Y()},
00290          {f3DBox[1].X(), f3DBox[0].Y(), f3DBox[1].X(), f3DBox[2].Y()},
00291          {f3DBox[1].X(), f3DBox[2].Y(), f3DBox[0].X(), f3DBox[3].Y()},
00292          {f3DBox[0].X(), f3DBox[3].Y(), f3DBox[0].X(), f3DBox[0].Y()}
00293       };
00294 
00295       for (UInt_t i = 0; i < zLevels.size(); ++i) {
00296          glBegin(GL_LINES);
00297          glVertex3d(lineCaps[plane][0], lineCaps[plane][1], zLevels[i]);
00298          glVertex3d(lineCaps[plane][2], lineCaps[plane][3], zLevels[i]);
00299          glEnd();
00300       }
00301 
00302    }
00303 }

Generated on Tue Jul 5 14:18:08 2011 for ROOT_528-00b_version by  doxygen 1.5.1