From $ROOTSYS/tutorials/gl/viewer3DLocal.C

//+ Demonstrates 3D viewer architecture TVirtualViewer3D and TBuffer3D in the local frame.
//
// Here each shape is described in a TBuffer3D class,
// with a suitible translation matrix to place each instance
// NOTE: to be executed via .x viewer3DLocal.C+
//
// NOTE: We don't implement raw tesselation of sphere - hence this will
// not appear in viewers which don't support directly (non-OpenGL)
// Shows that viewers can at least deal gracefully with these cases

// Our abstract base shape class.
// Author: Richard Maunder

// As we overload TObject::Paint which is called directly from compiled
// code, this script must also be compiled to work correctly.

//#if defined(__CINT__) && !defined(__MAKECINT__)
//{
//   gSystem->CompileMacro("viewer3DLocal.C");
//   viewer3DLocal();
//}
//#else

#include "TVirtualViewer3D.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"

#include "TObject.h"
#include "TVirtualPad.h"
#include "TAtt3D.h"

#include <vector>

class Shape : public TObject
{
public:
   Shape(Int_t color, Double_t x, Double_t y, Double_t z);
   ~Shape() {};
   virtual TBuffer3D & GetBuffer3D(UInt_t reqSections) = 0;

protected:
   Double_t fX, fY, fZ;    // Origin
   Int_t fColor;

   ClassDef(Shape,0);
};

ClassImp(Shape);

Shape::Shape(Int_t color, Double_t x, Double_t y, Double_t z) :
   fX(x), fY(y), fZ(z), fColor(color)
{}

class Sphere : public Shape
{
public:
   Sphere(Int_t color, Double_t x, Double_t y, Double_t z, Double_t radius);
   ~Sphere() {};

   virtual TBuffer3D & GetBuffer3D(UInt_t reqSections);

private:
   Double_t fRadius;

   ClassDef(Sphere,0);
};

ClassImp(Sphere);

Sphere::Sphere(Int_t color, Double_t x, Double_t y, Double_t z, Double_t radius) :
   Shape(color,x,y,z),
   fRadius(radius)
{}

TBuffer3D & Sphere::GetBuffer3D(UInt_t reqSections)
{
   static TBuffer3DSphere buffer;

   // Complete kCore section - this could be moved to Shape base class
   if (reqSections & TBuffer3D::kCore) {
      buffer.ClearSectionsValid();
      buffer.fID = this;
      buffer.fColor = fColor;       // Color index - see gROOT->GetColor()
      buffer.fTransparency = 0;     // Transparency 0 (opaque) - 100 (fully transparent)

      // Complete local/master transformation matrix - simple x/y/z
      // translation. Easiest way to set identity then override the
      // translation components
      buffer.SetLocalMasterIdentity();
      buffer.fLocalMaster[12] = fX;
      buffer.fLocalMaster[13] = fY;
      buffer.fLocalMaster[14] = fZ;
      buffer.fLocalFrame = kTRUE;  // Local frame

      buffer.fReflection = kFALSE;
      buffer.SetSectionsValid(TBuffer3D::kCore);
   }
   // Complete kBoundingBox section
   if (reqSections & TBuffer3D::kBoundingBox) {
      Double_t origin[3] = { 0.0, 0.0, 0.0 };
      Double_t halfLength[3] = { fRadius, fRadius, fRadius };
      buffer.SetAABoundingBox(origin, halfLength);
      buffer.SetSectionsValid(TBuffer3D::kBoundingBox);
   }
   // Complete kShapeSpecific section
   if (reqSections & TBuffer3D::kShapeSpecific) {
      buffer.fRadiusOuter = fRadius;
      buffer.fRadiusInner = 0.0;
      buffer.fThetaMin    = 0.0;
      buffer.fThetaMax    = 180.0;
      buffer.fPhiMin    = 0.0;
      buffer.fPhiMax    = 360.0;
      buffer.SetSectionsValid(TBuffer3D::kShapeSpecific);
   }
   // We don't implement raw tesselation of sphere - hence this will
   // not appear in viewers which don't support directly (non-OpenGL)
   // Complete kRawSizes section
   if (reqSections & TBuffer3D::kRawSizes) {
      //buffer.SetSectionsValid(TBuffer3D::kRawSizes);
   }
   // Complete kRaw section
   if (reqSections & TBuffer3D::kRaw) {
      //buffer.SetSectionsValid(TBuffer3D::kRaw);
   }

   return buffer;
}

class Box : public Shape
{
public:
   Box(Int_t color, Double_t x, Double_t y, Double_t z,
       Double_t dX, Double_t dY, Double_t dZ);
   ~Box() {};

   virtual TBuffer3D & GetBuffer3D(UInt_t reqSections);

private:
   Double_t fDX, fDY, fDZ; // Half lengths

   ClassDef(Box,0);
};

ClassImp(Box);

Box::Box(Int_t color, Double_t x, Double_t y, Double_t z,
         Double_t dX, Double_t dY, Double_t dZ) :
   Shape(color,x,y,z),
   fDX(dX), fDY(dY), fDZ(dZ)
{}

TBuffer3D & Box::GetBuffer3D(UInt_t reqSections)
{
   static TBuffer3D buffer(TBuffer3DTypes::kGeneric);

   // Complete kCore section - this could be moved to Shape base class
   if (reqSections & TBuffer3D::kCore) {
      buffer.ClearSectionsValid();
      buffer.fID = this;
      buffer.fColor = fColor;       // Color index - see gROOT->GetColor()
      buffer.fTransparency = 0;     // Transparency 0 (opaque) - 100 (fully transparent)

      // Complete local/master transformation matrix - simple x/y/z
      // translation. Easiest way to set identity then override the
      // translation components
      buffer.SetLocalMasterIdentity();
      buffer.fLocalMaster[12] = fX;
      buffer.fLocalMaster[13] = fY;
      buffer.fLocalMaster[14] = fZ;
      buffer.fLocalFrame = kTRUE;  // Local frame

      buffer.fReflection = kFALSE;
      buffer.SetSectionsValid(TBuffer3D::kCore);
   }
   // Complete kBoundingBox section
   if (reqSections & TBuffer3D::kBoundingBox) {
      Double_t origin[3] = { fX, fY, fZ };
      Double_t halfLength[3] =  { fDX, fDY, fDZ };
      buffer.SetAABoundingBox(origin, halfLength);
      buffer.SetSectionsValid(TBuffer3D::kBoundingBox);
   }
   // No kShapeSpecific section

   // Complete kRawSizes section
   if (reqSections & TBuffer3D::kRawSizes) {
      buffer.SetRawSizes(8, 3*8, 12, 3*12, 6, 6*6);
      buffer.SetSectionsValid(TBuffer3D::kRawSizes);
   }
   // Complete kRaw section
   if (reqSections & TBuffer3D::kRaw) {
      // Points (8)
      // 3 components: x,y,z
      buffer.fPnts[ 0] = fX - fDX; buffer.fPnts[ 1] = fY - fDY; buffer.fPnts[ 2] = fZ - fDZ; // 0
      buffer.fPnts[ 3] = fX + fDX; buffer.fPnts[ 4] = fY - fDY; buffer.fPnts[ 5] = fZ - fDZ; // 1
      buffer.fPnts[ 6] = fX + fDX; buffer.fPnts[ 7] = fY + fDY; buffer.fPnts[ 8] = fZ - fDZ; // 2
      buffer.fPnts[ 9] = fX - fDX; buffer.fPnts[10] = fY + fDY; buffer.fPnts[11] = fZ - fDZ; // 3
      buffer.fPnts[12] = fX - fDX; buffer.fPnts[13] = fY - fDY; buffer.fPnts[14] = fZ + fDZ; // 4
      buffer.fPnts[15] = fX + fDX; buffer.fPnts[16] = fY - fDY; buffer.fPnts[17] = fZ + fDZ; // 5
      buffer.fPnts[18] = fX + fDX; buffer.fPnts[19] = fY + fDY; buffer.fPnts[20] = fZ + fDZ; // 6
      buffer.fPnts[21] = fX - fDX; buffer.fPnts[22] = fY + fDY; buffer.fPnts[23] = fZ + fDZ; // 7

      // Segments (12)
      // 3 components: segment color(ignored), start point index, end point index
      // Indexes reference the above points
      buffer.fSegs[ 0] = fColor   ; buffer.fSegs[ 1] = 0   ; buffer.fSegs[ 2] = 1   ; // 0
      buffer.fSegs[ 3] = fColor   ; buffer.fSegs[ 4] = 1   ; buffer.fSegs[ 5] = 2   ; // 1
      buffer.fSegs[ 6] = fColor   ; buffer.fSegs[ 7] = 2   ; buffer.fSegs[ 8] = 3   ; // 2
      buffer.fSegs[ 9] = fColor   ; buffer.fSegs[10] = 3   ; buffer.fSegs[11] = 0   ; // 3
      buffer.fSegs[12] = fColor   ; buffer.fSegs[13] = 4   ; buffer.fSegs[14] = 5   ; // 4
      buffer.fSegs[15] = fColor   ; buffer.fSegs[16] = 5   ; buffer.fSegs[17] = 6   ; // 5
      buffer.fSegs[18] = fColor   ; buffer.fSegs[19] = 6   ; buffer.fSegs[20] = 7   ; // 6
      buffer.fSegs[21] = fColor   ; buffer.fSegs[22] = 7   ; buffer.fSegs[23] = 4   ; // 7
      buffer.fSegs[24] = fColor   ; buffer.fSegs[25] = 0   ; buffer.fSegs[26] = 4   ; // 8
      buffer.fSegs[27] = fColor   ; buffer.fSegs[28] = 1   ; buffer.fSegs[29] = 5   ; // 9
      buffer.fSegs[30] = fColor   ; buffer.fSegs[31] = 2   ; buffer.fSegs[32] = 6   ; // 10
      buffer.fSegs[33] = fColor   ; buffer.fSegs[34] = 3   ; buffer.fSegs[35] = 7   ; // 11

      // Polygons (6)
      // 5+ (2+n) components: polygon color (ignored), segment count(n=3+),
      // seg1, seg2 .... segn index
      // Segments indexes refer to the above 12 segments
      // Here n=4 - each polygon defines a rectangle - 4 sides.
      buffer.fPols[ 0] = fColor   ; buffer.fPols[ 1] = 4   ;  buffer.fPols[ 2] = 8  ; // 0
      buffer.fPols[ 3] = 4        ; buffer.fPols[ 4] = 9   ;  buffer.fPols[ 5] = 0  ;
      buffer.fPols[ 6] = fColor   ; buffer.fPols[ 7] = 4   ;  buffer.fPols[ 8] = 9  ; // 1
      buffer.fPols[ 9] = 5        ; buffer.fPols[10] = 10  ;  buffer.fPols[11] = 1  ;
      buffer.fPols[12] = fColor   ; buffer.fPols[13] = 4   ;  buffer.fPols[14] = 10  ; // 2
      buffer.fPols[15] = 6        ; buffer.fPols[16] = 11  ;  buffer.fPols[17] = 2  ;
      buffer.fPols[18] = fColor   ; buffer.fPols[19] = 4   ;  buffer.fPols[20] = 11 ; // 3
      buffer.fPols[21] = 7        ; buffer.fPols[22] = 8   ;  buffer.fPols[23] = 3 ;
      buffer.fPols[24] = fColor   ; buffer.fPols[25] = 4   ;  buffer.fPols[26] = 1  ; // 4
      buffer.fPols[27] = 2        ; buffer.fPols[28] = 3   ;  buffer.fPols[29] = 0  ;
      buffer.fPols[30] = fColor   ; buffer.fPols[31] = 4   ;  buffer.fPols[32] = 7  ; // 5
      buffer.fPols[33] = 6        ; buffer.fPols[34] = 5   ;  buffer.fPols[35] = 4  ;

      buffer.SetSectionsValid(TBuffer3D::kRaw);
  }

   return buffer;
}

class SBPyramid : public Shape
{
public:
   SBPyramid(Int_t color, Double_t d, Double_t y, Double_t z,
             Double_t dX, Double_t dY, Double_t dZ);
   ~SBPyramid() {};

   virtual TBuffer3D & GetBuffer3D(UInt_t reqSections);

private:
   Double_t fDX, fDY, fDZ; // Base half lengths dX,dY
                           // Pyr. height dZ

   ClassDef(SBPyramid,0);
};

ClassImp(SBPyramid);

SBPyramid::SBPyramid(Int_t color, Double_t x, Double_t y, Double_t z,
         Double_t dX, Double_t dY, Double_t dZ) :
   Shape(color,x,y,z),
   fDX(dX), fDY(dY), fDZ(dZ)
{}

TBuffer3D & SBPyramid::GetBuffer3D(UInt_t reqSections)
{
   static TBuffer3D buffer(TBuffer3DTypes::kGeneric);

   // Complete kCore section
   if (reqSections & TBuffer3D::kCore) {
      buffer.ClearSectionsValid();
      buffer.fID = this;
      buffer.fColor = fColor;       // Color index - see gROOT->GetColor()
      buffer.fTransparency = 0;     // Transparency 0 (opaque) - 100 (fully transparent)

      // Complete local/master transformation matrix - simple x/y/z
      // translation. Easiest way to set identity then override the
      // translation components
      buffer.SetLocalMasterIdentity();
      buffer.fLocalMaster[12] = fX;
      buffer.fLocalMaster[13] = fY;
      buffer.fLocalMaster[14] = fZ;
      buffer.fLocalFrame = kTRUE;  // Local frame

      buffer.fReflection = kFALSE;
      buffer.SetSectionsValid(TBuffer3D::kCore);
   }
   // Complete kBoundingBox section
   if (reqSections & TBuffer3D::kBoundingBox) {
      Double_t halfLength[3] =  { fDX, fDY, fDZ/2.0 };
      Double_t origin[3] = { fX , fY, fZ + halfLength[2]};
      buffer.SetAABoundingBox(origin, halfLength);
      buffer.SetSectionsValid(TBuffer3D::kBoundingBox);
   }
   // No kShapeSpecific section

   // Complete kRawSizes section
   if (reqSections & TBuffer3D::kRawSizes) {
      buffer.SetRawSizes(5, 3*5, 8, 3*8, 5, 6 + 4*5);
      buffer.SetSectionsValid(TBuffer3D::kRawSizes);
   }
   // Complete kRaw section
   if (reqSections & TBuffer3D::kRaw) {
      // Points (5)
      // 3 components: x,y,z
      buffer.fPnts[ 0] = fX - fDX; buffer.fPnts[ 1] = fY - fDY; buffer.fPnts[ 2] = fZ; // 0
      buffer.fPnts[ 3] = fX + fDX; buffer.fPnts[ 4] = fY - fDY; buffer.fPnts[ 5] = fZ; // 1
      buffer.fPnts[ 6] = fX + fDX; buffer.fPnts[ 7] = fY + fDY; buffer.fPnts[ 8] = fZ; // 2
      buffer.fPnts[ 9] = fX - fDX; buffer.fPnts[10] = fY + fDY; buffer.fPnts[11] = fZ; // 3
      buffer.fPnts[12] = fX;       buffer.fPnts[13] = fY      ; buffer.fPnts[14] = fZ + fDZ; // 4 (pyr top point)

      // Segments (8)
      // 3 components: segment color(ignored), start point index, end point index
      // Indexes reference the above points

      buffer.fSegs[ 0] = fColor   ; buffer.fSegs[ 1] = 0   ; buffer.fSegs[ 2] = 1   ; // 0 base
      buffer.fSegs[ 3] = fColor   ; buffer.fSegs[ 4] = 1   ; buffer.fSegs[ 5] = 2   ; // 1 base
      buffer.fSegs[ 6] = fColor   ; buffer.fSegs[ 7] = 2   ; buffer.fSegs[ 8] = 3   ; // 2 base
      buffer.fSegs[ 9] = fColor   ; buffer.fSegs[10] = 3   ; buffer.fSegs[11] = 0   ; // 3 base
      buffer.fSegs[12] = fColor   ; buffer.fSegs[13] = 0   ; buffer.fSegs[14] = 4   ; // 4 side
      buffer.fSegs[15] = fColor   ; buffer.fSegs[16] = 1   ; buffer.fSegs[17] = 4   ; // 5 side
      buffer.fSegs[18] = fColor   ; buffer.fSegs[19] = 2   ; buffer.fSegs[20] = 4   ; // 6 side
      buffer.fSegs[21] = fColor   ; buffer.fSegs[22] = 3   ; buffer.fSegs[23] = 4   ; // 7 side

      // Polygons (6)
      // 5+ (2+n) components: polygon color (ignored), segment count(n=3+),
      // seg1, seg2 .... segn index
      // Segments indexes refer to the above 12 segments
      // Here n=4 - each polygon defines a rectangle - 4 sides.
      buffer.fPols[ 0] = fColor  ; buffer.fPols[ 1] = 4   ;  buffer.fPols[ 2] = 0  ; // base
      buffer.fPols[ 3] = 1       ; buffer.fPols[ 4] = 2   ;  buffer.fPols[ 5] = 3  ;

      buffer.fPols[ 6] = fColor  ; buffer.fPols[ 7] = 3   ;  buffer.fPols[ 8] = 0  ; // side 0
      buffer.fPols[ 9] = 4       ; buffer.fPols[10] = 5   ;
      buffer.fPols[11] = fColor  ; buffer.fPols[12] = 3   ;  buffer.fPols[13] = 1  ; // side 1
      buffer.fPols[14] = 5       ; buffer.fPols[15] = 6   ;
      buffer.fPols[16] = fColor  ; buffer.fPols[17] = 3   ;  buffer.fPols[18] = 2  ; // side 2
      buffer.fPols[19] = 6       ; buffer.fPols[20] = 7   ;
      buffer.fPols[21] = fColor  ; buffer.fPols[22] = 3   ;  buffer.fPols[23] = 3  ; // side 3
      buffer.fPols[24] = 7       ; buffer.fPols[25] = 4   ;

      buffer.SetSectionsValid(TBuffer3D::kRaw);
  }

   return buffer;
}

class MyGeom : public TObject, public TAtt3D
{
public:
   MyGeom();
   ~MyGeom();

   void Draw(Option_t *option);
   void Paint(Option_t *option);

private:
   std::vector<Shape *> fShapes;

   ClassDef(MyGeom,0);
};

ClassImp(MyGeom);

MyGeom::MyGeom()
{
   // Create our simple geometry - sphere, couple of boxes
   // and a square base pyramid
   Shape * aShape;
   aShape = new Sphere(kYellow, 80.0, 60.0, 120.0, 10.0);
   fShapes.push_back(aShape);
   aShape = new Box(kRed, 0.0, 0.0, 0.0, 20.0, 20.0, 20.0);
   fShapes.push_back(aShape);
   aShape = new Box(kBlue, 50.0, 100.0, 200.0, 5.0, 10.0, 15.0);
   fShapes.push_back(aShape);
   aShape = new SBPyramid(kGreen, 20.0, 25.0, 45.0, 30.0, 30.0, 90.0);
   fShapes.push_back(aShape);
}

MyGeom::~MyGeom()
{
   // Clear out fShapes
}

void MyGeom::Draw(Option_t *option)
{
   TObject::Draw(option);

   // Ask pad to create 3D viewer of type 'option'
   gPad->GetViewer3D(option);
}

void MyGeom::Paint(Option_t * /*option*/)
{
   TVirtualViewer3D * viewer = gPad->GetViewer3D();

   // If MyGeom derives from TAtt3D then pad will recognise
   // that the object it is asking to paint is 3D, and open/close
   // the scene for us. If not Open/Close are required
   //viewer->BeginScene();

   // We are working in the master frame - so we don't bother
   // to ask the viewer if it prefers local. Viewer's must
   // always support master frame as minimum. c.f. with
   // viewer3DLocal.C
   std::vector<Shape *>::const_iterator ShapeIt = fShapes.begin();
   Shape * shape;
   while (ShapeIt != fShapes.end()) {
      shape = *ShapeIt;

      UInt_t reqSections = TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific;
      TBuffer3D & buffer = shape->GetBuffer3D(reqSections);
      reqSections = viewer->AddObject(buffer);

      if (reqSections != TBuffer3D::kNone) {
         shape->GetBuffer3D(reqSections);
         viewer->AddObject(buffer);
      }
      ShapeIt++;
   }
   // Not required as we are TAtt3D subclass
   //viewer->EndScene();
}

void viewer3DLocal()
{
   printf("\n\nviewer3DLocal: This frame demonstates local frame use of 3D viewer architecture.\n");
   printf("Creates sphere, two boxes and a square based pyramid, described in local frame.\n");
   printf("We do not implement raw tesselation of sphere - hence will not appear in viewers\n");
   printf("which do not support in natively (non-GL viewer).\n\n");

   MyGeom * myGeom = new MyGeom;
   myGeom->Draw("ogl");
}

//#endif
 viewer3DLocal.C:1
 viewer3DLocal.C:2
 viewer3DLocal.C:3
 viewer3DLocal.C:4
 viewer3DLocal.C:5
 viewer3DLocal.C:6
 viewer3DLocal.C:7
 viewer3DLocal.C:8
 viewer3DLocal.C:9
 viewer3DLocal.C:10
 viewer3DLocal.C:11
 viewer3DLocal.C:12
 viewer3DLocal.C:13
 viewer3DLocal.C:14
 viewer3DLocal.C:15
 viewer3DLocal.C:16
 viewer3DLocal.C:17
 viewer3DLocal.C:18
 viewer3DLocal.C:19
 viewer3DLocal.C:20
 viewer3DLocal.C:21
 viewer3DLocal.C:22
 viewer3DLocal.C:23
 viewer3DLocal.C:24
 viewer3DLocal.C:25
 viewer3DLocal.C:26
 viewer3DLocal.C:27
 viewer3DLocal.C:28
 viewer3DLocal.C:29
 viewer3DLocal.C:30
 viewer3DLocal.C:31
 viewer3DLocal.C:32
 viewer3DLocal.C:33
 viewer3DLocal.C:34
 viewer3DLocal.C:35
 viewer3DLocal.C:36
 viewer3DLocal.C:37
 viewer3DLocal.C:38
 viewer3DLocal.C:39
 viewer3DLocal.C:40
 viewer3DLocal.C:41
 viewer3DLocal.C:42
 viewer3DLocal.C:43
 viewer3DLocal.C:44
 viewer3DLocal.C:45
 viewer3DLocal.C:46
 viewer3DLocal.C:47
 viewer3DLocal.C:48
 viewer3DLocal.C:49
 viewer3DLocal.C:50
 viewer3DLocal.C:51
 viewer3DLocal.C:52
 viewer3DLocal.C:53
 viewer3DLocal.C:54
 viewer3DLocal.C:55
 viewer3DLocal.C:56
 viewer3DLocal.C:57
 viewer3DLocal.C:58
 viewer3DLocal.C:59
 viewer3DLocal.C:60
 viewer3DLocal.C:61
 viewer3DLocal.C:62
 viewer3DLocal.C:63
 viewer3DLocal.C:64
 viewer3DLocal.C:65
 viewer3DLocal.C:66
 viewer3DLocal.C:67
 viewer3DLocal.C:68
 viewer3DLocal.C:69
 viewer3DLocal.C:70
 viewer3DLocal.C:71
 viewer3DLocal.C:72
 viewer3DLocal.C:73
 viewer3DLocal.C:74
 viewer3DLocal.C:75
 viewer3DLocal.C:76
 viewer3DLocal.C:77
 viewer3DLocal.C:78
 viewer3DLocal.C:79
 viewer3DLocal.C:80
 viewer3DLocal.C:81
 viewer3DLocal.C:82
 viewer3DLocal.C:83
 viewer3DLocal.C:84
 viewer3DLocal.C:85
 viewer3DLocal.C:86
 viewer3DLocal.C:87
 viewer3DLocal.C:88
 viewer3DLocal.C:89
 viewer3DLocal.C:90
 viewer3DLocal.C:91
 viewer3DLocal.C:92
 viewer3DLocal.C:93
 viewer3DLocal.C:94
 viewer3DLocal.C:95
 viewer3DLocal.C:96
 viewer3DLocal.C:97
 viewer3DLocal.C:98
 viewer3DLocal.C:99
 viewer3DLocal.C:100
 viewer3DLocal.C:101
 viewer3DLocal.C:102
 viewer3DLocal.C:103
 viewer3DLocal.C:104
 viewer3DLocal.C:105
 viewer3DLocal.C:106
 viewer3DLocal.C:107
 viewer3DLocal.C:108
 viewer3DLocal.C:109
 viewer3DLocal.C:110
 viewer3DLocal.C:111
 viewer3DLocal.C:112
 viewer3DLocal.C:113
 viewer3DLocal.C:114
 viewer3DLocal.C:115
 viewer3DLocal.C:116
 viewer3DLocal.C:117
 viewer3DLocal.C:118
 viewer3DLocal.C:119
 viewer3DLocal.C:120
 viewer3DLocal.C:121
 viewer3DLocal.C:122
 viewer3DLocal.C:123
 viewer3DLocal.C:124
 viewer3DLocal.C:125
 viewer3DLocal.C:126
 viewer3DLocal.C:127
 viewer3DLocal.C:128
 viewer3DLocal.C:129
 viewer3DLocal.C:130
 viewer3DLocal.C:131
 viewer3DLocal.C:132
 viewer3DLocal.C:133
 viewer3DLocal.C:134
 viewer3DLocal.C:135
 viewer3DLocal.C:136
 viewer3DLocal.C:137
 viewer3DLocal.C:138
 viewer3DLocal.C:139
 viewer3DLocal.C:140
 viewer3DLocal.C:141
 viewer3DLocal.C:142
 viewer3DLocal.C:143
 viewer3DLocal.C:144
 viewer3DLocal.C:145
 viewer3DLocal.C:146
 viewer3DLocal.C:147
 viewer3DLocal.C:148
 viewer3DLocal.C:149
 viewer3DLocal.C:150
 viewer3DLocal.C:151
 viewer3DLocal.C:152
 viewer3DLocal.C:153
 viewer3DLocal.C:154
 viewer3DLocal.C:155
 viewer3DLocal.C:156
 viewer3DLocal.C:157
 viewer3DLocal.C:158
 viewer3DLocal.C:159
 viewer3DLocal.C:160
 viewer3DLocal.C:161
 viewer3DLocal.C:162
 viewer3DLocal.C:163
 viewer3DLocal.C:164
 viewer3DLocal.C:165
 viewer3DLocal.C:166
 viewer3DLocal.C:167
 viewer3DLocal.C:168
 viewer3DLocal.C:169
 viewer3DLocal.C:170
 viewer3DLocal.C:171
 viewer3DLocal.C:172
 viewer3DLocal.C:173
 viewer3DLocal.C:174
 viewer3DLocal.C:175
 viewer3DLocal.C:176
 viewer3DLocal.C:177
 viewer3DLocal.C:178
 viewer3DLocal.C:179
 viewer3DLocal.C:180
 viewer3DLocal.C:181
 viewer3DLocal.C:182
 viewer3DLocal.C:183
 viewer3DLocal.C:184
 viewer3DLocal.C:185
 viewer3DLocal.C:186
 viewer3DLocal.C:187
 viewer3DLocal.C:188
 viewer3DLocal.C:189
 viewer3DLocal.C:190
 viewer3DLocal.C:191
 viewer3DLocal.C:192
 viewer3DLocal.C:193
 viewer3DLocal.C:194
 viewer3DLocal.C:195
 viewer3DLocal.C:196
 viewer3DLocal.C:197
 viewer3DLocal.C:198
 viewer3DLocal.C:199
 viewer3DLocal.C:200
 viewer3DLocal.C:201
 viewer3DLocal.C:202
 viewer3DLocal.C:203
 viewer3DLocal.C:204
 viewer3DLocal.C:205
 viewer3DLocal.C:206
 viewer3DLocal.C:207
 viewer3DLocal.C:208
 viewer3DLocal.C:209
 viewer3DLocal.C:210
 viewer3DLocal.C:211
 viewer3DLocal.C:212
 viewer3DLocal.C:213
 viewer3DLocal.C:214
 viewer3DLocal.C:215
 viewer3DLocal.C:216
 viewer3DLocal.C:217
 viewer3DLocal.C:218
 viewer3DLocal.C:219
 viewer3DLocal.C:220
 viewer3DLocal.C:221
 viewer3DLocal.C:222
 viewer3DLocal.C:223
 viewer3DLocal.C:224
 viewer3DLocal.C:225
 viewer3DLocal.C:226
 viewer3DLocal.C:227
 viewer3DLocal.C:228
 viewer3DLocal.C:229
 viewer3DLocal.C:230
 viewer3DLocal.C:231
 viewer3DLocal.C:232
 viewer3DLocal.C:233
 viewer3DLocal.C:234
 viewer3DLocal.C:235
 viewer3DLocal.C:236
 viewer3DLocal.C:237
 viewer3DLocal.C:238
 viewer3DLocal.C:239
 viewer3DLocal.C:240
 viewer3DLocal.C:241
 viewer3DLocal.C:242
 viewer3DLocal.C:243
 viewer3DLocal.C:244
 viewer3DLocal.C:245
 viewer3DLocal.C:246
 viewer3DLocal.C:247
 viewer3DLocal.C:248
 viewer3DLocal.C:249
 viewer3DLocal.C:250
 viewer3DLocal.C:251
 viewer3DLocal.C:252
 viewer3DLocal.C:253
 viewer3DLocal.C:254
 viewer3DLocal.C:255
 viewer3DLocal.C:256
 viewer3DLocal.C:257
 viewer3DLocal.C:258
 viewer3DLocal.C:259
 viewer3DLocal.C:260
 viewer3DLocal.C:261
 viewer3DLocal.C:262
 viewer3DLocal.C:263
 viewer3DLocal.C:264
 viewer3DLocal.C:265
 viewer3DLocal.C:266
 viewer3DLocal.C:267
 viewer3DLocal.C:268
 viewer3DLocal.C:269
 viewer3DLocal.C:270
 viewer3DLocal.C:271
 viewer3DLocal.C:272
 viewer3DLocal.C:273
 viewer3DLocal.C:274
 viewer3DLocal.C:275
 viewer3DLocal.C:276
 viewer3DLocal.C:277
 viewer3DLocal.C:278
 viewer3DLocal.C:279
 viewer3DLocal.C:280
 viewer3DLocal.C:281
 viewer3DLocal.C:282
 viewer3DLocal.C:283
 viewer3DLocal.C:284
 viewer3DLocal.C:285
 viewer3DLocal.C:286
 viewer3DLocal.C:287
 viewer3DLocal.C:288
 viewer3DLocal.C:289
 viewer3DLocal.C:290
 viewer3DLocal.C:291
 viewer3DLocal.C:292
 viewer3DLocal.C:293
 viewer3DLocal.C:294
 viewer3DLocal.C:295
 viewer3DLocal.C:296
 viewer3DLocal.C:297
 viewer3DLocal.C:298
 viewer3DLocal.C:299
 viewer3DLocal.C:300
 viewer3DLocal.C:301
 viewer3DLocal.C:302
 viewer3DLocal.C:303
 viewer3DLocal.C:304
 viewer3DLocal.C:305
 viewer3DLocal.C:306
 viewer3DLocal.C:307
 viewer3DLocal.C:308
 viewer3DLocal.C:309
 viewer3DLocal.C:310
 viewer3DLocal.C:311
 viewer3DLocal.C:312
 viewer3DLocal.C:313
 viewer3DLocal.C:314
 viewer3DLocal.C:315
 viewer3DLocal.C:316
 viewer3DLocal.C:317
 viewer3DLocal.C:318
 viewer3DLocal.C:319
 viewer3DLocal.C:320
 viewer3DLocal.C:321
 viewer3DLocal.C:322
 viewer3DLocal.C:323
 viewer3DLocal.C:324
 viewer3DLocal.C:325
 viewer3DLocal.C:326
 viewer3DLocal.C:327
 viewer3DLocal.C:328
 viewer3DLocal.C:329
 viewer3DLocal.C:330
 viewer3DLocal.C:331
 viewer3DLocal.C:332
 viewer3DLocal.C:333
 viewer3DLocal.C:334
 viewer3DLocal.C:335
 viewer3DLocal.C:336
 viewer3DLocal.C:337
 viewer3DLocal.C:338
 viewer3DLocal.C:339
 viewer3DLocal.C:340
 viewer3DLocal.C:341
 viewer3DLocal.C:342
 viewer3DLocal.C:343
 viewer3DLocal.C:344
 viewer3DLocal.C:345
 viewer3DLocal.C:346
 viewer3DLocal.C:347
 viewer3DLocal.C:348
 viewer3DLocal.C:349
 viewer3DLocal.C:350
 viewer3DLocal.C:351
 viewer3DLocal.C:352
 viewer3DLocal.C:353
 viewer3DLocal.C:354
 viewer3DLocal.C:355
 viewer3DLocal.C:356
 viewer3DLocal.C:357
 viewer3DLocal.C:358
 viewer3DLocal.C:359
 viewer3DLocal.C:360
 viewer3DLocal.C:361
 viewer3DLocal.C:362
 viewer3DLocal.C:363
 viewer3DLocal.C:364
 viewer3DLocal.C:365
 viewer3DLocal.C:366
 viewer3DLocal.C:367
 viewer3DLocal.C:368
 viewer3DLocal.C:369
 viewer3DLocal.C:370
 viewer3DLocal.C:371
 viewer3DLocal.C:372
 viewer3DLocal.C:373
 viewer3DLocal.C:374
 viewer3DLocal.C:375
 viewer3DLocal.C:376
 viewer3DLocal.C:377
 viewer3DLocal.C:378
 viewer3DLocal.C:379
 viewer3DLocal.C:380
 viewer3DLocal.C:381
 viewer3DLocal.C:382
 viewer3DLocal.C:383
 viewer3DLocal.C:384
 viewer3DLocal.C:385
 viewer3DLocal.C:386
 viewer3DLocal.C:387
 viewer3DLocal.C:388
 viewer3DLocal.C:389
 viewer3DLocal.C:390
 viewer3DLocal.C:391
 viewer3DLocal.C:392
 viewer3DLocal.C:393
 viewer3DLocal.C:394
 viewer3DLocal.C:395
 viewer3DLocal.C:396
 viewer3DLocal.C:397
 viewer3DLocal.C:398
 viewer3DLocal.C:399
 viewer3DLocal.C:400
 viewer3DLocal.C:401
 viewer3DLocal.C:402
 viewer3DLocal.C:403
 viewer3DLocal.C:404
 viewer3DLocal.C:405
 viewer3DLocal.C:406
 viewer3DLocal.C:407
 viewer3DLocal.C:408
 viewer3DLocal.C:409
 viewer3DLocal.C:410
 viewer3DLocal.C:411
 viewer3DLocal.C:412
 viewer3DLocal.C:413
 viewer3DLocal.C:414
 viewer3DLocal.C:415
 viewer3DLocal.C:416
 viewer3DLocal.C:417
 viewer3DLocal.C:418
 viewer3DLocal.C:419
 viewer3DLocal.C:420
 viewer3DLocal.C:421
 viewer3DLocal.C:422
 viewer3DLocal.C:423
 viewer3DLocal.C:424
 viewer3DLocal.C:425
 viewer3DLocal.C:426
 viewer3DLocal.C:427
 viewer3DLocal.C:428
 viewer3DLocal.C:429
 viewer3DLocal.C:430
 viewer3DLocal.C:431
 viewer3DLocal.C:432
 viewer3DLocal.C:433
 viewer3DLocal.C:434
 viewer3DLocal.C:435
 viewer3DLocal.C:436
 viewer3DLocal.C:437
 viewer3DLocal.C:438