#include <algorithm>
#include "TColor.h"
#include "TGLIncludes.h"
#include "TGLPlotBox.h"
ClassImp(TGLPlotBox)
const Int_t TGLPlotBox::fgFramePlanes[][4] =
   {
    {0, 4, 5, 1},
    {1, 5, 6, 2},
    {2, 6, 7, 3},
    {0, 3, 7, 4},
    {0, 1, 2, 3}
   };
const Double_t TGLPlotBox::fgNormals[][3] =
   {
    { 0., 1., 0.},
    {-1., 0., 0.},
    { 0.,-1., 0.},
    { 1., 0., 0.},
    { 0., 0., 1.}
   };
const Int_t TGLPlotBox::fgBackPairs[][2] =
   {
    {2, 1},
    {3, 2},
    {0, 3},
    {1, 0}
   };
TGLPlotBox::TGLPlotBox(Bool_t xoy, Bool_t xoz, Bool_t yoz)
               : fFrameColor(0),
                 fXOYSelectable(xoy),
                 fXOZSelectable(xoz),
                 fYOZSelectable(yoz),
                 fSelectablePairs(),
                 fFrontPoint(0)
{
   
   
   fSelectablePairs[0][0] = xoz;
   fSelectablePairs[0][1] = yoz;
   
   fSelectablePairs[1][0] = yoz;
   fSelectablePairs[1][1] = xoz;
   
   fSelectablePairs[2][0] = xoz;
   fSelectablePairs[2][1] = yoz;
   
   fSelectablePairs[3][0] = yoz;
   fSelectablePairs[3][1] = xoz;
}
TGLPlotBox::~TGLPlotBox()
{
   
}
void TGLPlotBox::DrawBox(Int_t selected, Bool_t selectionPass, const std::vector<Double_t> &zLevels,
                         Bool_t highColor)const
{
   
   using namespace Rgl;
   TGLDisableGuard depthTest(GL_DEPTH_TEST); 
   glDepthMask(GL_FALSE);
   if (!selectionPass) {
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
      glEnable(GL_LINE_SMOOTH);
   }
   
   Float_t backColor[] = {0.9f, 0.9f, 0.9f, 0.85f};
   if (fFrameColor)
      fFrameColor->GetRGB(backColor[0], backColor[1], backColor[2]);
   if (!selectionPass) {
      glMaterialfv(GL_FRONT, GL_DIFFUSE, backColor);
      if (selected == 1) {
         fXOYSelectable ?
                         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
                        :
                         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
      }
   } else
      ObjectIDToColor(1, highColor);
   DrawQuadFilled(f3DBox[0], f3DBox[1], f3DBox[2], f3DBox[3], TGLVector3(0., 0., 1.));
   if (!selectionPass) {
      if (selected == 1)
         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
      else if (selected == 2)
         fSelectablePairs[fFrontPoint][0] ?
            glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
           :glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
   } else
      ObjectIDToColor(2, highColor);
   DrawBackPlane(fgBackPairs[fFrontPoint][0], selectionPass, zLevels);
   if (!selectionPass) {
      if (selected == 2)
         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
      else if (selected == 3)
         fSelectablePairs[fFrontPoint][1] ?
            glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
           :glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
   } else
      ObjectIDToColor(3, highColor); 
   DrawBackPlane(fgBackPairs[fFrontPoint][1], selectionPass, zLevels);
   glDepthMask(GL_TRUE);
   if (!selectionPass) {
      if (selected == 3)
         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
      glDisable(GL_BLEND);
      glDisable(GL_LINE_SMOOTH);
   }
}
void TGLPlotBox::SetPlotBox(const Rgl::Range_t &x, const Rgl::Range_t &y, const Rgl::Range_t &z)
{
   
   f3DBox[0].Set(x.first,  y.first,  z.first);
   f3DBox[1].Set(x.second, y.first,  z.first);
   f3DBox[2].Set(x.second, y.second, z.first);
   f3DBox[3].Set(x.first,  y.second, z.first);
   f3DBox[4].Set(x.first,  y.first,  z.second);
   f3DBox[5].Set(x.second, y.first,  z.second);
   f3DBox[6].Set(x.second, y.second, z.second);
   f3DBox[7].Set(x.first,  y.second, z.second);
}
void TGLPlotBox::SetFrameColor(const TColor *color)
{
   
   fFrameColor = color;
}
namespace {
   bool Compare(const TGLVertex3 &v1, const TGLVertex3 &v2)
   {
      return v1.Z() < v2.Z();
   }
}
Int_t TGLPlotBox::FindFrontPoint()const
{
   
   
   Double_t mvMatrix[16] = {0.};
   glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix);
   Double_t prMatrix[16] = {0.};
   glGetDoublev(GL_PROJECTION_MATRIX, prMatrix);
   Int_t viewport[4] = {0};
   glGetIntegerv(GL_VIEWPORT, viewport);
   const Double_t zMin = f3DBox[0].Z();
   const Double_t zMax = f3DBox[4].Z();
   for (Int_t i = 0; i < 4; ++i) {
      gluProject(f3DBox[i].X(), f3DBox[i].Y(), zMin, mvMatrix, prMatrix, viewport,
                 &f2DBox[i].X(), &f2DBox[i].Y(), &f2DBox[i].Z());
      gluProject(f3DBox[i].X(), f3DBox[i].Y(), zMax, mvMatrix, prMatrix, viewport,
                 &f2DBox[i + 4].X(), &f2DBox[i + 4].Y(), &f2DBox[i + 4].Z());
   }
   return fFrontPoint = std::min_element(f2DBox, f2DBox + 4, Compare) - f2DBox;
}
Int_t TGLPlotBox::GetFrontPoint()const
{
   
   return fFrontPoint;
}
const TGLVertex3 *TGLPlotBox::Get3DBox()const
{
   
   return f3DBox;
}
const TGLVertex3 *TGLPlotBox::Get2DBox()const
{
   
   return f2DBox;
}
void TGLPlotBox::DrawBackPlane(Int_t plane, Bool_t selectionPass,
                               const std::vector<Double_t> &zLevels)const
{
   
   using namespace Rgl;
   const Int_t *vertInd = fgFramePlanes[plane];
   DrawQuadFilled(f3DBox[vertInd[0]], f3DBox[vertInd[1]], f3DBox[vertInd[2]],
                  f3DBox[vertInd[3]], fgNormals[plane]);
   
   if (!selectionPass) {
      const TGLDisableGuard lightGuard(GL_LIGHTING);
      glColor3d(0., 0., 0.);
      DrawQuadOutline(f3DBox[vertInd[0]], f3DBox[vertInd[1]],
                      f3DBox[vertInd[2]], f3DBox[vertInd[3]]);
      
      const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);
      const UShort_t stipple = 0x5555;
      glLineStipple(1, stipple);
      Double_t lineCaps[][4] =
      {
         {f3DBox[1].X(), f3DBox[0].Y(), f3DBox[0].X(), f3DBox[0].Y()},
         {f3DBox[1].X(), f3DBox[0].Y(), f3DBox[1].X(), f3DBox[2].Y()},
         {f3DBox[1].X(), f3DBox[2].Y(), f3DBox[0].X(), f3DBox[3].Y()},
         {f3DBox[0].X(), f3DBox[3].Y(), f3DBox[0].X(), f3DBox[0].Y()}
      };
      for (UInt_t i = 0; i < zLevels.size(); ++i) {
         glBegin(GL_LINES);
         glVertex3d(lineCaps[plane][0], lineCaps[plane][1], zLevels[i]);
         glVertex3d(lineCaps[plane][2], lineCaps[plane][3], zLevels[i]);
         glEnd();
      }
   }
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.