ROOT logo
// @(#)root/gl:$Id: TGLPhysicalShape.cxx 28845 2009-06-08 13:53:44Z rdm $
// Author:  Richard Maunder  25/05/2005

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TGLPhysicalShape.h"
#include "TGLLogicalShape.h"
#include "TGLPShapeRef.h"
#include "TGLCamera.h"
#include "TGLRnrCtx.h"
#include "TGLIncludes.h"

#include "TGLScene.h"

#include "TColor.h"
#include "TROOT.h"

#include <cmath>

// For debug tracing
#include "TClass.h"
#include "TError.h"

/******************************************************************************/
// TGLPhysicalShape
/******************************************************************************/

//______________________________________________________________________________
//
// Concrete physical shape - a GL drawable. Physical shapes are the
// objects the user can actually see, select, move in the viewer. It is
// a placement of the associated local frame TGLLogicaShape into the
// world frame. The draw process is:
//
// Load attributes - material colors etc
// Load translation matrix - placement
// Load gl name (for selection)
// Call our associated logical shape Draw() to draw placed shape
//
// The physical shape supports translation, scaling and rotation,
// selection, color changes, and permitted modification flags etc.
// A physical shape cannot modify or be bound to another (or no)
// logical shape - hence const & handle. It can perform mutable
// reference counting on the logical to enable purging.
//
// Physical shape also maintains a list of references to it and
// provides notifications of change and destruction.
// See class TGLPShapeRef which needs to be sub-classes for real use.
//
// See base/src/TVirtualViewer3D for description of common external 3D
// viewer architecture and how external viewer clients use it.
//

ClassImp(TGLPhysicalShape)

//______________________________________________________________________________
TGLPhysicalShape::TGLPhysicalShape(UInt_t id, const TGLLogicalShape & logicalShape,
                                   const TGLMatrix & transform, Bool_t invertedWind,
                                   const Float_t rgba[4]) :
   fLogicalShape (&logicalShape),
   fNextPhysical (0),
   fFirstPSRef   (0),
   fID           (id),
   fTransform    (transform),
   fSelected     (0),
   fInvertedWind (invertedWind),
   fModified     (kFALSE),
   fManip        (kManipAll)
{
   // Construct a physical shape using arguments:
   //    ID             - unique drawable id.
   //    logicalShape   - bound logical shape
   //    transform      - transform for placement of logical drawing
   //    invertedWind   - use inverted face polygon winding?
   //    rgba           - basic four component (RGBA) diffuse color

   fLogicalShape->AddRef(this);
   UpdateBoundingBox();

   // Initialise color
   InitColor(rgba);
}

//______________________________________________________________________________
TGLPhysicalShape::TGLPhysicalShape(UInt_t id, const TGLLogicalShape & logicalShape,
                                   const Double_t * transform, Bool_t invertedWind,
                                   const Float_t rgba[4]) :
   fLogicalShape (&logicalShape),
   fNextPhysical (0),
   fFirstPSRef   (0),
   fID           (id),
   fTransform    (transform),
   fSelected     (0),
   fInvertedWind (invertedWind),
   fModified     (kFALSE),
   fManip        (kManipAll)
{
   // Construct a physical shape using arguments:
   //    id             - unique drawable id.
   //    logicalShape   - bound logical shape
   //    transform      - 16 Double_t component transform for placement of logical drawing
   //    invertedWind   - use inverted face polygon winding?
   //    rgba           - basic four component (RGBA) diffuse color

   fLogicalShape->AddRef(this);

   // Temporary hack - invert the 3x3 part of martix as TGeo sends this
   // in opp layout to shear/translation parts. Speak to Andrei about best place
   // to fix - probably when filling TBuffer3D - should always be OGL convention?
   fTransform.Transpose3x3();
   UpdateBoundingBox();

   // Initialise color
   InitColor(rgba);
}

//______________________________________________________________________________
TGLPhysicalShape::~TGLPhysicalShape()
{
   // Destroy the physical shape.

   // If destroyed from the logical shape itself the pointer has already
   // been cleared.
   if (fLogicalShape) fLogicalShape->SubRef(this);

   // Remove all references.
   while (fFirstPSRef) {
      fFirstPSRef->SetPShape(0);
   }
}

//______________________________________________________________________________
void TGLPhysicalShape::AddReference(TGLPShapeRef* ref)
{
   // Add reference ref.

   assert(ref != 0);

   ref->fNextPSRef = fFirstPSRef;
   fFirstPSRef = ref;
}

//______________________________________________________________________________
void TGLPhysicalShape::RemoveReference(TGLPShapeRef* ref)
{
   // Remove reference ref.

   assert(ref != 0);

   Bool_t found = kFALSE;
   if (fFirstPSRef == ref) {
      fFirstPSRef = ref->fNextPSRef;
      found = kTRUE;
   } else {
      TGLPShapeRef *shp1 = fFirstPSRef, *shp2;
      while ((shp2 = shp1->fNextPSRef) != 0) {
         if (shp2 == ref) {
            shp1->fNextPSRef = shp2->fNextPSRef;
            found = kTRUE;
            break;
         }
         shp1 = shp2;
      }
   }
   if (found) {
      ref->fNextPSRef = 0;
   } else {
      Error("TGLPhysicalShape::RemoveReference", "Attempt to un-ref an unregistered shape-ref.");
   }
}

//______________________________________________________________________________
void TGLPhysicalShape::Modified()
{
   // Call this after modifying the physical so that the information
   // can be propagated to the object referencing it.

   fModified = kTRUE;
   TGLPShapeRef * ref = fFirstPSRef;
   while (ref) {
      ref->PShapeModified();
      ref = ref->fNextPSRef;
   }
}

//______________________________________________________________________________
void TGLPhysicalShape::UpdateBoundingBox()
{
   // Update our internal bounding box (in global frame).

   fBoundingBox.Set(fLogicalShape->BoundingBox());
   fBoundingBox.Transform(fTransform);

   if (fLogicalShape->GetScene())
      fLogicalShape->GetScene()->InvalidateBoundingBox();
}

//______________________________________________________________________________
void TGLPhysicalShape::InitColor(const Float_t rgba[4])
{
   // Initialise the colors, using basic RGBA diffuse material color supplied

   // TODO: Make a color class
   fColor[0] = rgba[0];
   fColor[1] = rgba[1];
   fColor[2] = rgba[2];
   fColor[3] = rgba[3];

   fColor[4]  = fColor[5]  = fColor[6]  = 0.0f; //ambient
   fColor[8]  = fColor[9]  = fColor[10] = 0.7f; //specular
   fColor[12] = fColor[13] = fColor[14] = 0.0f; //emission
   fColor[7]  = fColor[11] = fColor[15] = 1.0f; //alpha
   fColor[16] = 60.0f;                          //shininess
}

//______________________________________________________________________________
void TGLPhysicalShape::SetColor(const Float_t color[17])
{
   // Set full color attributes - see OpenGL material documentation
   // for full description.
   // 0->3 diffuse, 4->7 ambient, 8->11 specular, 12->15 emission, 16 shininess

   // TODO: Make a color class
   for (UInt_t i = 0; i < 17; i++) {
      fColor[i] = color[i];
   }

   Modified();
}

//______________________________________________________________________________
void TGLPhysicalShape::SetColorOnFamily(const Float_t color[17])
{
   // Set full color attributes to all physicals sharing the same
   // logical with this object.

   TGLPhysicalShape* pshp = const_cast<TGLPhysicalShape*>(fLogicalShape->GetFirstPhysical());
   while (pshp)
   {
      pshp->SetColor(color);
      pshp = pshp->fNextPhysical;
   }
}

//______________________________________________________________________________
void TGLPhysicalShape::SetDiffuseColor(const Float_t rgba[4])
{
   // Set color from ROOT color index and transparency [0,100].

   for (Int_t i=0; i<4; ++i)
      fColor[i] = rgba[i];
   Modified();
}

//______________________________________________________________________________
void TGLPhysicalShape::SetDiffuseColor(const UChar_t rgba[4])
{
   // Set color from RGBA quadruplet.

   for (Int_t i=0; i<4; ++i)
      fColor[i] = rgba[i]/255.0f;
   Modified();
}

//______________________________________________________________________________
void TGLPhysicalShape::SetDiffuseColor(Color_t ci, UChar_t transparency)
{
   // Set color from standard ROOT representation, that is color index
   // + transparency in range [0, 100].

   if (ci < 0) ci = 1;
   TColor* c = gROOT->GetColor(ci);
   if (c) {
      fColor[0] = c->GetRed();
      fColor[1] = c->GetGreen();
      fColor[2] = c->GetBlue();
      fColor[3] = 1.0f - 0.01*transparency;
   }
   Modified();
}

//______________________________________________________________________________
void TGLPhysicalShape::SetupGLColors(TGLRnrCtx & rnrCtx, const Float_t* color) const
{
   // Setup colors - avoid setting things not required
   // for current draw flags.

   if (color == 0) color = fColor;

   switch (rnrCtx.DrawPass()) {
      case TGLRnrCtx::kPassWireFrame:
      {
         // Wireframe needs basic color only
         glColor4fv(color);
         break;
      }
      case TGLRnrCtx::kPassFill:
      case TGLRnrCtx::kPassOutlineFill:
      {
         // Both need material colors

         // Set back diffuse only for clipping where inner (back) faces
         // are shown. Don't set shinneness or specular as we want
         // back face to appear as 'flat' as possible as crude visual
         // approximation to proper capped clipped solid
         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
         glMaterialfv(GL_FRONT, GL_AMBIENT,  color + 4);
         glMaterialfv(GL_FRONT, GL_SPECULAR, color + 8);
         glMaterialfv(GL_FRONT, GL_EMISSION, color + 12);
         glMaterialf(GL_FRONT, GL_SHININESS, color[16]);
         // Some objects use point/line graphics. Material mode disabled.
         glColor4fv(color);
         break;
      }
      case TGLRnrCtx::kPassOutlineLine:
      {
         // Outline also needs grey wireframe but respecting
         // transparency of main diffuse color.
         TGLUtil::Color(rnrCtx.ColorSet().Outline(), 0.5f*color[3]);
         break;
      }
      default:
      {
         assert(kFALSE);
      }
   }
}

static const Float_t selColor[] =
{
   1,   1,   1,   1,     // base color
   0,   0,   0,   1,     // ambient
   0,   0,   0,   1,     // specular
   0.5, 0,   0,   1,     // emission
   0                     // shininess
};

//______________________________________________________________________________
void TGLPhysicalShape::Draw(TGLRnrCtx & rnrCtx) const
{
   // Draw physical shape, using LOD flags, potential from display list cache

   // Debug tracing
   if (gDebug > 4) {
      Info("TGLPhysicalShape::Draw", "this %d (class %s) LOD %d",
           this, IsA()->GetName(), rnrCtx.ShapeLOD());
   }

   // If LOD is pixel or less can draw pixel(point) directly, skipping
   // any logical call, caching etc.
   if (rnrCtx.ShapeLOD() == TGLRnrCtx::kLODPixel)
   {
      if (!rnrCtx.IsDrawPassOutlineLine())
      {
         glColor4fv(fColor);
         glBegin(GL_POINTS);
         glVertex3dv(&fTransform.CArr()[12]);
         glEnd();
      }
      return;
   }

   if (gDebug > 4) {
      Info("TGLPhysicalShape::Draw", "this %d (class %s) LOD %d",
           this, IsA()->GetName(), rnrCtx.ShapeLOD());
   }

   glPushMatrix();
   glMultMatrixd(fTransform.CArr());
   if (fInvertedWind)  glFrontFace(GL_CW);
   if (fSelected && !rnrCtx.Selection() && !rnrCtx.IsDrawPassOutlineLine())
   {
      const TGLRect& vp = rnrCtx.RefCamera().RefViewport();
      Int_t inner[4][2] = { { 0,-1}, { 1, 0}, { 0, 1}, {-1, 0} };
      Int_t outer[8][2] = { {-1,-1}, { 1,-1}, { 1, 1}, {-1, 1},
                            { 0,-2}, { 2, 0}, { 0, 2}, {-2, 0} };

      // TGLCapabilitySwitch bs(GL_BLEND, kTRUE), lss(GL_LINE_SMOOTH, kTRUE);

      rnrCtx.SetHighlight(kTRUE);
      rnrCtx.SetHighlightOutline(kTRUE);
      TGLUtil::LockColor();
      Int_t first_outer = (rnrCtx.CombiLOD() == TGLRnrCtx::kLODHigh) ? 0 : 4;
      for (int i = first_outer; i < 8; ++i)
      {
         glViewport(vp.X() + outer[i][0], vp.Y() + outer[i][1], vp.Width(), vp.Height());
         glColor4ubv(rnrCtx.ColorSet().Selection(fSelected).CArr());
         fLogicalShape->Draw(rnrCtx);
      }
      TGLUtil::UnlockColor();
      rnrCtx.SetHighlightOutline(kFALSE);

      SetupGLColors(rnrCtx);
      for (int i = 0; i < 4; ++i)
      {
         glViewport(vp.X() + inner[i][0], vp.Y() + inner[i][1], vp.Width(), vp.Height());
         glColor4fv(fColor);
         fLogicalShape->Draw(rnrCtx);
      }
      glViewport(vp.X(), vp.Y(), vp.Width(), vp.Height());
      rnrCtx.SetHighlight(kFALSE);

      SetupGLColors(rnrCtx);
      Float_t dr[2];
      glGetFloatv(GL_DEPTH_RANGE,dr);
      glDepthRange(dr[0], 0.5*dr[1]);
      fLogicalShape->Draw(rnrCtx);
      glDepthRange(dr[0], dr[1]);
   }
   else
   {
      SetupGLColors(rnrCtx);
      if (rnrCtx.IsDrawPassOutlineLine())
         TGLUtil::LockColor();
      fLogicalShape->Draw(rnrCtx);
      if (rnrCtx.IsDrawPassOutlineLine())
         TGLUtil::UnlockColor();
   }
   if (fInvertedWind)  glFrontFace(GL_CCW);
   glPopMatrix();
}

//______________________________________________________________________________
void TGLPhysicalShape::CalculateShapeLOD(TGLRnrCtx& rnrCtx, Float_t& pixSize, Short_t& shapeLOD) const
{
   // Calculate shape-lod, suitible for use under
   // projection defined by 'rnrCtx', taking account of which local
   // axes of the shape support LOD adjustment, and the global
   // 'sceneFlags' passed.
   //
   // Returned shapeLOD component is from 0 (kLODPixel - lowest
   // quality) to 100 (kLODHigh - highest quality).
   //
   // Scene flags are not used. LOD quantization is not done.  RnrCtx
   // is not modified as this is called via lodification stage of
   // rendering.

   TGLLogicalShape::ELODAxes lodAxes = fLogicalShape->SupportedLODAxes();

   if (lodAxes == TGLLogicalShape::kLODAxesNone)
   {  // Shape doesn't support LOD along any axes return special
      // unsupported LOD draw/cache flag.
      // TODO: Still ... could check for kLODPixel when very small,
      //    by using diagonal from bounding-box and some special camera foo.
      pixSize  = 100; // Make up something / irrelevant.
      shapeLOD = TGLRnrCtx::kLODHigh;
      return;
   }

   std::vector <Double_t> boxViewportDiags;
   const TGLBoundingBox & box        = BoundingBox();
   const TGLCamera      & camera     = rnrCtx.RefCamera();

   if (lodAxes == TGLLogicalShape::kLODAxesAll) {
      // Shape supports LOD along all axes - basis LOD hint on diagonal of viewport
      // projection rect round whole bounding box
      boxViewportDiags.push_back(camera.ViewportRect(box).Diagonal());
   } else if (lodAxes == (TGLLogicalShape::kLODAxesY | TGLLogicalShape::kLODAxesZ)) {
      // Shape supports LOD along Y/Z axes (not X). LOD hint based on longest
      // diagonal (largest rect) of either of the X axis end faces
      boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceLowX).Diagonal());
      boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceHighX).Diagonal());
   } else if (lodAxes == (TGLLogicalShape::kLODAxesX | TGLLogicalShape::kLODAxesZ)) {
      // Shape supports LOD along X/Z axes (not Y). See above for Y/Z
      boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceLowY).Diagonal());
      boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceHighY).Diagonal());
   } else if (lodAxes == (TGLLogicalShape::kLODAxesX | TGLLogicalShape::kLODAxesY)) {
      // Shape supports LOD along X/Y axes (not Z). See above for Y/Z
      boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceLowZ).Diagonal());
      boxViewportDiags.push_back(camera.ViewportRect(box, TGLBoundingBox::kFaceHighZ).Diagonal());
   } else {
      // Don't bother to implement LOD calc for shapes supporting LOD along single
      // axis only. Not needed at present + unlikely case - but could be done based
      // on longest of projection of 4 edges of BBox along LOD axis. However this would
      // probably be more costly than just using whole BB projection (as for all axes)
      Error("TGLPhysicalShape::CalcPhysicalLOD", "LOD calculation for single axis not implemented presently");
      shapeLOD = TGLRnrCtx::kLODMed;
      return;
   }

   // Find largest of the projected diagonals
   Double_t largestDiagonal = 0.0;
   for (UInt_t i = 0; i < boxViewportDiags.size(); i++) {
      if (boxViewportDiags[i] > largestDiagonal) {
         largestDiagonal = boxViewportDiags[i];
      }
   }
   pixSize = largestDiagonal;

   if (largestDiagonal <= 1.0) {
      shapeLOD = TGLRnrCtx::kLODPixel;
   } else {
      // TODO: Get real screen size - assuming 2000 pixel screen at present
      // Calculate a non-linear sizing hint for this shape based on diagonal.
      // Needs more experimenting with...
      UInt_t lodApp = static_cast<UInt_t>(std::pow(largestDiagonal,0.4) * 100.0 / std::pow(2000.0,0.4));
      if (lodApp > 1000) lodApp = 1000;
      shapeLOD = (Short_t) lodApp;
   }
}

//______________________________________________________________________________
void TGLPhysicalShape::QuantizeShapeLOD(Short_t shapeLOD, Short_t combiLOD, Short_t& quantLOD) const
{
   // Factor in scene/vierer LOD and Quantize ... forward to
   // logical shape.

   quantLOD = fLogicalShape->QuantizeShapeLOD(shapeLOD, combiLOD);
}

//______________________________________________________________________________
void TGLPhysicalShape::InvokeContextMenu(TContextMenu & menu, UInt_t x, UInt_t y) const
{
   // Request creation of context menu on shape, attached to 'menu' at screen position
   // 'x' 'y'

   // Just defer to our logical at present
   fLogicalShape->InvokeContextMenu(menu, x, y);
}
 TGLPhysicalShape.cxx:1
 TGLPhysicalShape.cxx:2
 TGLPhysicalShape.cxx:3
 TGLPhysicalShape.cxx:4
 TGLPhysicalShape.cxx:5
 TGLPhysicalShape.cxx:6
 TGLPhysicalShape.cxx:7
 TGLPhysicalShape.cxx:8
 TGLPhysicalShape.cxx:9
 TGLPhysicalShape.cxx:10
 TGLPhysicalShape.cxx:11
 TGLPhysicalShape.cxx:12
 TGLPhysicalShape.cxx:13
 TGLPhysicalShape.cxx:14
 TGLPhysicalShape.cxx:15
 TGLPhysicalShape.cxx:16
 TGLPhysicalShape.cxx:17
 TGLPhysicalShape.cxx:18
 TGLPhysicalShape.cxx:19
 TGLPhysicalShape.cxx:20
 TGLPhysicalShape.cxx:21
 TGLPhysicalShape.cxx:22
 TGLPhysicalShape.cxx:23
 TGLPhysicalShape.cxx:24
 TGLPhysicalShape.cxx:25
 TGLPhysicalShape.cxx:26
 TGLPhysicalShape.cxx:27
 TGLPhysicalShape.cxx:28
 TGLPhysicalShape.cxx:29
 TGLPhysicalShape.cxx:30
 TGLPhysicalShape.cxx:31
 TGLPhysicalShape.cxx:32
 TGLPhysicalShape.cxx:33
 TGLPhysicalShape.cxx:34
 TGLPhysicalShape.cxx:35
 TGLPhysicalShape.cxx:36
 TGLPhysicalShape.cxx:37
 TGLPhysicalShape.cxx:38
 TGLPhysicalShape.cxx:39
 TGLPhysicalShape.cxx:40
 TGLPhysicalShape.cxx:41
 TGLPhysicalShape.cxx:42
 TGLPhysicalShape.cxx:43
 TGLPhysicalShape.cxx:44
 TGLPhysicalShape.cxx:45
 TGLPhysicalShape.cxx:46
 TGLPhysicalShape.cxx:47
 TGLPhysicalShape.cxx:48
 TGLPhysicalShape.cxx:49
 TGLPhysicalShape.cxx:50
 TGLPhysicalShape.cxx:51
 TGLPhysicalShape.cxx:52
 TGLPhysicalShape.cxx:53
 TGLPhysicalShape.cxx:54
 TGLPhysicalShape.cxx:55
 TGLPhysicalShape.cxx:56
 TGLPhysicalShape.cxx:57
 TGLPhysicalShape.cxx:58
 TGLPhysicalShape.cxx:59
 TGLPhysicalShape.cxx:60
 TGLPhysicalShape.cxx:61
 TGLPhysicalShape.cxx:62
 TGLPhysicalShape.cxx:63
 TGLPhysicalShape.cxx:64
 TGLPhysicalShape.cxx:65
 TGLPhysicalShape.cxx:66
 TGLPhysicalShape.cxx:67
 TGLPhysicalShape.cxx:68
 TGLPhysicalShape.cxx:69
 TGLPhysicalShape.cxx:70
 TGLPhysicalShape.cxx:71
 TGLPhysicalShape.cxx:72
 TGLPhysicalShape.cxx:73
 TGLPhysicalShape.cxx:74
 TGLPhysicalShape.cxx:75
 TGLPhysicalShape.cxx:76
 TGLPhysicalShape.cxx:77
 TGLPhysicalShape.cxx:78
 TGLPhysicalShape.cxx:79
 TGLPhysicalShape.cxx:80
 TGLPhysicalShape.cxx:81
 TGLPhysicalShape.cxx:82
 TGLPhysicalShape.cxx:83
 TGLPhysicalShape.cxx:84
 TGLPhysicalShape.cxx:85
 TGLPhysicalShape.cxx:86
 TGLPhysicalShape.cxx:87
 TGLPhysicalShape.cxx:88
 TGLPhysicalShape.cxx:89
 TGLPhysicalShape.cxx:90
 TGLPhysicalShape.cxx:91
 TGLPhysicalShape.cxx:92
 TGLPhysicalShape.cxx:93
 TGLPhysicalShape.cxx:94
 TGLPhysicalShape.cxx:95
 TGLPhysicalShape.cxx:96
 TGLPhysicalShape.cxx:97
 TGLPhysicalShape.cxx:98
 TGLPhysicalShape.cxx:99
 TGLPhysicalShape.cxx:100
 TGLPhysicalShape.cxx:101
 TGLPhysicalShape.cxx:102
 TGLPhysicalShape.cxx:103
 TGLPhysicalShape.cxx:104
 TGLPhysicalShape.cxx:105
 TGLPhysicalShape.cxx:106
 TGLPhysicalShape.cxx:107
 TGLPhysicalShape.cxx:108
 TGLPhysicalShape.cxx:109
 TGLPhysicalShape.cxx:110
 TGLPhysicalShape.cxx:111
 TGLPhysicalShape.cxx:112
 TGLPhysicalShape.cxx:113
 TGLPhysicalShape.cxx:114
 TGLPhysicalShape.cxx:115
 TGLPhysicalShape.cxx:116
 TGLPhysicalShape.cxx:117
 TGLPhysicalShape.cxx:118
 TGLPhysicalShape.cxx:119
 TGLPhysicalShape.cxx:120
 TGLPhysicalShape.cxx:121
 TGLPhysicalShape.cxx:122
 TGLPhysicalShape.cxx:123
 TGLPhysicalShape.cxx:124
 TGLPhysicalShape.cxx:125
 TGLPhysicalShape.cxx:126
 TGLPhysicalShape.cxx:127
 TGLPhysicalShape.cxx:128
 TGLPhysicalShape.cxx:129
 TGLPhysicalShape.cxx:130
 TGLPhysicalShape.cxx:131
 TGLPhysicalShape.cxx:132
 TGLPhysicalShape.cxx:133
 TGLPhysicalShape.cxx:134
 TGLPhysicalShape.cxx:135
 TGLPhysicalShape.cxx:136
 TGLPhysicalShape.cxx:137
 TGLPhysicalShape.cxx:138
 TGLPhysicalShape.cxx:139
 TGLPhysicalShape.cxx:140
 TGLPhysicalShape.cxx:141
 TGLPhysicalShape.cxx:142
 TGLPhysicalShape.cxx:143
 TGLPhysicalShape.cxx:144
 TGLPhysicalShape.cxx:145
 TGLPhysicalShape.cxx:146
 TGLPhysicalShape.cxx:147
 TGLPhysicalShape.cxx:148
 TGLPhysicalShape.cxx:149
 TGLPhysicalShape.cxx:150
 TGLPhysicalShape.cxx:151
 TGLPhysicalShape.cxx:152
 TGLPhysicalShape.cxx:153
 TGLPhysicalShape.cxx:154
 TGLPhysicalShape.cxx:155
 TGLPhysicalShape.cxx:156
 TGLPhysicalShape.cxx:157
 TGLPhysicalShape.cxx:158
 TGLPhysicalShape.cxx:159
 TGLPhysicalShape.cxx:160
 TGLPhysicalShape.cxx:161
 TGLPhysicalShape.cxx:162
 TGLPhysicalShape.cxx:163
 TGLPhysicalShape.cxx:164
 TGLPhysicalShape.cxx:165
 TGLPhysicalShape.cxx:166
 TGLPhysicalShape.cxx:167
 TGLPhysicalShape.cxx:168
 TGLPhysicalShape.cxx:169
 TGLPhysicalShape.cxx:170
 TGLPhysicalShape.cxx:171
 TGLPhysicalShape.cxx:172
 TGLPhysicalShape.cxx:173
 TGLPhysicalShape.cxx:174
 TGLPhysicalShape.cxx:175
 TGLPhysicalShape.cxx:176
 TGLPhysicalShape.cxx:177
 TGLPhysicalShape.cxx:178
 TGLPhysicalShape.cxx:179
 TGLPhysicalShape.cxx:180
 TGLPhysicalShape.cxx:181
 TGLPhysicalShape.cxx:182
 TGLPhysicalShape.cxx:183
 TGLPhysicalShape.cxx:184
 TGLPhysicalShape.cxx:185
 TGLPhysicalShape.cxx:186
 TGLPhysicalShape.cxx:187
 TGLPhysicalShape.cxx:188
 TGLPhysicalShape.cxx:189
 TGLPhysicalShape.cxx:190
 TGLPhysicalShape.cxx:191
 TGLPhysicalShape.cxx:192
 TGLPhysicalShape.cxx:193
 TGLPhysicalShape.cxx:194
 TGLPhysicalShape.cxx:195
 TGLPhysicalShape.cxx:196
 TGLPhysicalShape.cxx:197
 TGLPhysicalShape.cxx:198
 TGLPhysicalShape.cxx:199
 TGLPhysicalShape.cxx:200
 TGLPhysicalShape.cxx:201
 TGLPhysicalShape.cxx:202
 TGLPhysicalShape.cxx:203
 TGLPhysicalShape.cxx:204
 TGLPhysicalShape.cxx:205
 TGLPhysicalShape.cxx:206
 TGLPhysicalShape.cxx:207
 TGLPhysicalShape.cxx:208
 TGLPhysicalShape.cxx:209
 TGLPhysicalShape.cxx:210
 TGLPhysicalShape.cxx:211
 TGLPhysicalShape.cxx:212
 TGLPhysicalShape.cxx:213
 TGLPhysicalShape.cxx:214
 TGLPhysicalShape.cxx:215
 TGLPhysicalShape.cxx:216
 TGLPhysicalShape.cxx:217
 TGLPhysicalShape.cxx:218
 TGLPhysicalShape.cxx:219
 TGLPhysicalShape.cxx:220
 TGLPhysicalShape.cxx:221
 TGLPhysicalShape.cxx:222
 TGLPhysicalShape.cxx:223
 TGLPhysicalShape.cxx:224
 TGLPhysicalShape.cxx:225
 TGLPhysicalShape.cxx:226
 TGLPhysicalShape.cxx:227
 TGLPhysicalShape.cxx:228
 TGLPhysicalShape.cxx:229
 TGLPhysicalShape.cxx:230
 TGLPhysicalShape.cxx:231
 TGLPhysicalShape.cxx:232
 TGLPhysicalShape.cxx:233
 TGLPhysicalShape.cxx:234
 TGLPhysicalShape.cxx:235
 TGLPhysicalShape.cxx:236
 TGLPhysicalShape.cxx:237
 TGLPhysicalShape.cxx:238
 TGLPhysicalShape.cxx:239
 TGLPhysicalShape.cxx:240
 TGLPhysicalShape.cxx:241
 TGLPhysicalShape.cxx:242
 TGLPhysicalShape.cxx:243
 TGLPhysicalShape.cxx:244
 TGLPhysicalShape.cxx:245
 TGLPhysicalShape.cxx:246
 TGLPhysicalShape.cxx:247
 TGLPhysicalShape.cxx:248
 TGLPhysicalShape.cxx:249
 TGLPhysicalShape.cxx:250
 TGLPhysicalShape.cxx:251
 TGLPhysicalShape.cxx:252
 TGLPhysicalShape.cxx:253
 TGLPhysicalShape.cxx:254
 TGLPhysicalShape.cxx:255
 TGLPhysicalShape.cxx:256
 TGLPhysicalShape.cxx:257
 TGLPhysicalShape.cxx:258
 TGLPhysicalShape.cxx:259
 TGLPhysicalShape.cxx:260
 TGLPhysicalShape.cxx:261
 TGLPhysicalShape.cxx:262
 TGLPhysicalShape.cxx:263
 TGLPhysicalShape.cxx:264
 TGLPhysicalShape.cxx:265
 TGLPhysicalShape.cxx:266
 TGLPhysicalShape.cxx:267
 TGLPhysicalShape.cxx:268
 TGLPhysicalShape.cxx:269
 TGLPhysicalShape.cxx:270
 TGLPhysicalShape.cxx:271
 TGLPhysicalShape.cxx:272
 TGLPhysicalShape.cxx:273
 TGLPhysicalShape.cxx:274
 TGLPhysicalShape.cxx:275
 TGLPhysicalShape.cxx:276
 TGLPhysicalShape.cxx:277
 TGLPhysicalShape.cxx:278
 TGLPhysicalShape.cxx:279
 TGLPhysicalShape.cxx:280
 TGLPhysicalShape.cxx:281
 TGLPhysicalShape.cxx:282
 TGLPhysicalShape.cxx:283
 TGLPhysicalShape.cxx:284
 TGLPhysicalShape.cxx:285
 TGLPhysicalShape.cxx:286
 TGLPhysicalShape.cxx:287
 TGLPhysicalShape.cxx:288
 TGLPhysicalShape.cxx:289
 TGLPhysicalShape.cxx:290
 TGLPhysicalShape.cxx:291
 TGLPhysicalShape.cxx:292
 TGLPhysicalShape.cxx:293
 TGLPhysicalShape.cxx:294
 TGLPhysicalShape.cxx:295
 TGLPhysicalShape.cxx:296
 TGLPhysicalShape.cxx:297
 TGLPhysicalShape.cxx:298
 TGLPhysicalShape.cxx:299
 TGLPhysicalShape.cxx:300
 TGLPhysicalShape.cxx:301
 TGLPhysicalShape.cxx:302
 TGLPhysicalShape.cxx:303
 TGLPhysicalShape.cxx:304
 TGLPhysicalShape.cxx:305
 TGLPhysicalShape.cxx:306
 TGLPhysicalShape.cxx:307
 TGLPhysicalShape.cxx:308
 TGLPhysicalShape.cxx:309
 TGLPhysicalShape.cxx:310
 TGLPhysicalShape.cxx:311
 TGLPhysicalShape.cxx:312
 TGLPhysicalShape.cxx:313
 TGLPhysicalShape.cxx:314
 TGLPhysicalShape.cxx:315
 TGLPhysicalShape.cxx:316
 TGLPhysicalShape.cxx:317
 TGLPhysicalShape.cxx:318
 TGLPhysicalShape.cxx:319
 TGLPhysicalShape.cxx:320
 TGLPhysicalShape.cxx:321
 TGLPhysicalShape.cxx:322
 TGLPhysicalShape.cxx:323
 TGLPhysicalShape.cxx:324
 TGLPhysicalShape.cxx:325
 TGLPhysicalShape.cxx:326
 TGLPhysicalShape.cxx:327
 TGLPhysicalShape.cxx:328
 TGLPhysicalShape.cxx:329
 TGLPhysicalShape.cxx:330
 TGLPhysicalShape.cxx:331
 TGLPhysicalShape.cxx:332
 TGLPhysicalShape.cxx:333
 TGLPhysicalShape.cxx:334
 TGLPhysicalShape.cxx:335
 TGLPhysicalShape.cxx:336
 TGLPhysicalShape.cxx:337
 TGLPhysicalShape.cxx:338
 TGLPhysicalShape.cxx:339
 TGLPhysicalShape.cxx:340
 TGLPhysicalShape.cxx:341
 TGLPhysicalShape.cxx:342
 TGLPhysicalShape.cxx:343
 TGLPhysicalShape.cxx:344
 TGLPhysicalShape.cxx:345
 TGLPhysicalShape.cxx:346
 TGLPhysicalShape.cxx:347
 TGLPhysicalShape.cxx:348
 TGLPhysicalShape.cxx:349
 TGLPhysicalShape.cxx:350
 TGLPhysicalShape.cxx:351
 TGLPhysicalShape.cxx:352
 TGLPhysicalShape.cxx:353
 TGLPhysicalShape.cxx:354
 TGLPhysicalShape.cxx:355
 TGLPhysicalShape.cxx:356
 TGLPhysicalShape.cxx:357
 TGLPhysicalShape.cxx:358
 TGLPhysicalShape.cxx:359
 TGLPhysicalShape.cxx:360
 TGLPhysicalShape.cxx:361
 TGLPhysicalShape.cxx:362
 TGLPhysicalShape.cxx:363
 TGLPhysicalShape.cxx:364
 TGLPhysicalShape.cxx:365
 TGLPhysicalShape.cxx:366
 TGLPhysicalShape.cxx:367
 TGLPhysicalShape.cxx:368
 TGLPhysicalShape.cxx:369
 TGLPhysicalShape.cxx:370
 TGLPhysicalShape.cxx:371
 TGLPhysicalShape.cxx:372
 TGLPhysicalShape.cxx:373
 TGLPhysicalShape.cxx:374
 TGLPhysicalShape.cxx:375
 TGLPhysicalShape.cxx:376
 TGLPhysicalShape.cxx:377
 TGLPhysicalShape.cxx:378
 TGLPhysicalShape.cxx:379
 TGLPhysicalShape.cxx:380
 TGLPhysicalShape.cxx:381
 TGLPhysicalShape.cxx:382
 TGLPhysicalShape.cxx:383
 TGLPhysicalShape.cxx:384
 TGLPhysicalShape.cxx:385
 TGLPhysicalShape.cxx:386
 TGLPhysicalShape.cxx:387
 TGLPhysicalShape.cxx:388
 TGLPhysicalShape.cxx:389
 TGLPhysicalShape.cxx:390
 TGLPhysicalShape.cxx:391
 TGLPhysicalShape.cxx:392
 TGLPhysicalShape.cxx:393
 TGLPhysicalShape.cxx:394
 TGLPhysicalShape.cxx:395
 TGLPhysicalShape.cxx:396
 TGLPhysicalShape.cxx:397
 TGLPhysicalShape.cxx:398
 TGLPhysicalShape.cxx:399
 TGLPhysicalShape.cxx:400
 TGLPhysicalShape.cxx:401
 TGLPhysicalShape.cxx:402
 TGLPhysicalShape.cxx:403
 TGLPhysicalShape.cxx:404
 TGLPhysicalShape.cxx:405
 TGLPhysicalShape.cxx:406
 TGLPhysicalShape.cxx:407
 TGLPhysicalShape.cxx:408
 TGLPhysicalShape.cxx:409
 TGLPhysicalShape.cxx:410
 TGLPhysicalShape.cxx:411
 TGLPhysicalShape.cxx:412
 TGLPhysicalShape.cxx:413
 TGLPhysicalShape.cxx:414
 TGLPhysicalShape.cxx:415
 TGLPhysicalShape.cxx:416
 TGLPhysicalShape.cxx:417
 TGLPhysicalShape.cxx:418
 TGLPhysicalShape.cxx:419
 TGLPhysicalShape.cxx:420
 TGLPhysicalShape.cxx:421
 TGLPhysicalShape.cxx:422
 TGLPhysicalShape.cxx:423
 TGLPhysicalShape.cxx:424
 TGLPhysicalShape.cxx:425
 TGLPhysicalShape.cxx:426
 TGLPhysicalShape.cxx:427
 TGLPhysicalShape.cxx:428
 TGLPhysicalShape.cxx:429
 TGLPhysicalShape.cxx:430
 TGLPhysicalShape.cxx:431
 TGLPhysicalShape.cxx:432
 TGLPhysicalShape.cxx:433
 TGLPhysicalShape.cxx:434
 TGLPhysicalShape.cxx:435
 TGLPhysicalShape.cxx:436
 TGLPhysicalShape.cxx:437
 TGLPhysicalShape.cxx:438
 TGLPhysicalShape.cxx:439
 TGLPhysicalShape.cxx:440
 TGLPhysicalShape.cxx:441
 TGLPhysicalShape.cxx:442
 TGLPhysicalShape.cxx:443
 TGLPhysicalShape.cxx:444
 TGLPhysicalShape.cxx:445
 TGLPhysicalShape.cxx:446
 TGLPhysicalShape.cxx:447
 TGLPhysicalShape.cxx:448
 TGLPhysicalShape.cxx:449
 TGLPhysicalShape.cxx:450
 TGLPhysicalShape.cxx:451
 TGLPhysicalShape.cxx:452
 TGLPhysicalShape.cxx:453
 TGLPhysicalShape.cxx:454
 TGLPhysicalShape.cxx:455
 TGLPhysicalShape.cxx:456
 TGLPhysicalShape.cxx:457
 TGLPhysicalShape.cxx:458
 TGLPhysicalShape.cxx:459
 TGLPhysicalShape.cxx:460
 TGLPhysicalShape.cxx:461
 TGLPhysicalShape.cxx:462
 TGLPhysicalShape.cxx:463
 TGLPhysicalShape.cxx:464
 TGLPhysicalShape.cxx:465
 TGLPhysicalShape.cxx:466
 TGLPhysicalShape.cxx:467
 TGLPhysicalShape.cxx:468
 TGLPhysicalShape.cxx:469
 TGLPhysicalShape.cxx:470
 TGLPhysicalShape.cxx:471
 TGLPhysicalShape.cxx:472
 TGLPhysicalShape.cxx:473
 TGLPhysicalShape.cxx:474
 TGLPhysicalShape.cxx:475
 TGLPhysicalShape.cxx:476
 TGLPhysicalShape.cxx:477
 TGLPhysicalShape.cxx:478
 TGLPhysicalShape.cxx:479
 TGLPhysicalShape.cxx:480
 TGLPhysicalShape.cxx:481
 TGLPhysicalShape.cxx:482
 TGLPhysicalShape.cxx:483
 TGLPhysicalShape.cxx:484
 TGLPhysicalShape.cxx:485
 TGLPhysicalShape.cxx:486
 TGLPhysicalShape.cxx:487
 TGLPhysicalShape.cxx:488
 TGLPhysicalShape.cxx:489
 TGLPhysicalShape.cxx:490
 TGLPhysicalShape.cxx:491
 TGLPhysicalShape.cxx:492
 TGLPhysicalShape.cxx:493
 TGLPhysicalShape.cxx:494
 TGLPhysicalShape.cxx:495
 TGLPhysicalShape.cxx:496
 TGLPhysicalShape.cxx:497
 TGLPhysicalShape.cxx:498
 TGLPhysicalShape.cxx:499
 TGLPhysicalShape.cxx:500
 TGLPhysicalShape.cxx:501
 TGLPhysicalShape.cxx:502
 TGLPhysicalShape.cxx:503
 TGLPhysicalShape.cxx:504
 TGLPhysicalShape.cxx:505
 TGLPhysicalShape.cxx:506
 TGLPhysicalShape.cxx:507
 TGLPhysicalShape.cxx:508
 TGLPhysicalShape.cxx:509
 TGLPhysicalShape.cxx:510
 TGLPhysicalShape.cxx:511
 TGLPhysicalShape.cxx:512
 TGLPhysicalShape.cxx:513
 TGLPhysicalShape.cxx:514
 TGLPhysicalShape.cxx:515
 TGLPhysicalShape.cxx:516
 TGLPhysicalShape.cxx:517
 TGLPhysicalShape.cxx:518
 TGLPhysicalShape.cxx:519
 TGLPhysicalShape.cxx:520
 TGLPhysicalShape.cxx:521
 TGLPhysicalShape.cxx:522
 TGLPhysicalShape.cxx:523
 TGLPhysicalShape.cxx:524
 TGLPhysicalShape.cxx:525