// @(#)root/x3d:$Id$
// Author: Rene Brun   05/09/99
/*************************************************************************
 * 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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TViewerX3D                                                           //
//                                                                      //
// C++ interface to the X3D viewer                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TViewerX3D.h"
#include "X3DBuffer.h"
#include "TVirtualPad.h"
#include "TView.h"
#include "TMath.h"
#include "TROOT.h"

#include "TRootHelpDialog.h"
#include "TGClient.h"
#include "TGCanvas.h"
#include "TGMenu.h"
#include "TGWidget.h"
#include "TGMsgBox.h"
#include "TVirtualX.h"

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

#include "HelpText.h"

#include <assert.h>

const char gHelpX3DViewer[] = "\
     PRESS \n\
     \tw\t--- wireframe mode\n\
     \te\t--- hidden line mode\n\
     \tr\t--- hidden surface mode\n\
     \tu\t--- move object down\n\
     \ti\t--- move object up\n\
     \to\t--- toggle controls style\n\
     \ts\t--- toggle stereo display\n\
     \td\t--- toggle blue stereo view\n\
     \tf\t--- toggle double buffer\n\
     \th\t--- move object right\n\
     \tj\t--- move object forward\n\
     \tk\t--- move object backward\n\
     \tl\t--- move object left\n\
     \tx a\t--- rotate about x\n\
     \ty b\t--- rotate about y\n\
     \tz c\t--- rotate about z\n\
     \t1 2 3\t--- autorotate about x\n\
     \t4 5 6\t--- autorotate about y\n\
     \t7 8 9\t--- autorotate about z\n\
     \t[ ] { }\t--- adjust focus\n\n\
     HOLD the left mouse button and MOVE mouse to ROTATE object\n\n\
";


extern "C" {
   Window_t x3d_main(Float_t *longitude, Float_t *latitude, Float_t *psi,
                     Option_t *option, Window_t parent);
   void     x3d_set_display(Display_t display);
   int      x3d_dispatch_event(Handle_t event);
   void     x3d_update();
   void     x3d_get_position(Float_t *longitude, Float_t *latitude, Float_t *psi);
   int      x3d_exec_command(int px, int py, char command);
   void     x3d_terminate();
}


// Canvas menu command ids
enum EX3DViewerCommands {
   kFileNewViewer,
   kFileSave,
   kFileSaveAs,
   kFilePrint,
   kFileCloseViewer,

   kHelpAbout,
   kHelpOnViewer
};

Bool_t TViewerX3D::fgCreated = kFALSE;


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TX3DContainer                                                        //
//                                                                      //
// Utility class used by TViewerX3D. The TX3DContainer is the frame     //
// embedded in the TGCanvas widget. The X3D graphics goes into this     //
// frame. This class is used to enable input events on this graphics    //
// frame and forward the events to X3D.                                 //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TX3DContainer : public TGCompositeFrame {
private:
   TViewerX3D  *fViewer;    // pointer back to viewer imp
public:
   TX3DContainer(TViewerX3D *c, Window_t id, const TGWindow *parent);

   Bool_t  HandleButton(Event_t *ev)
                  {  x3d_dispatch_event(gVirtualX->GetNativeEvent());
                     return fViewer->HandleContainerButton(ev); }
   Bool_t  HandleConfigureNotify(Event_t *ev)
                  {  TGFrame::HandleConfigureNotify(ev);
                     return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
   Bool_t  HandleKey(Event_t *)
                  {  return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
   Bool_t  HandleMotion(Event_t *)
                  {  return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
   Bool_t  HandleExpose(Event_t *)
                  {  return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
   Bool_t  HandleColormapChange(Event_t *)
                  {  return x3d_dispatch_event(gVirtualX->GetNativeEvent()); }
};


//______________________________________________________________________________
TX3DContainer::TX3DContainer(TViewerX3D *c, Window_t id, const TGWindow *p)
   : TGCompositeFrame(gClient, id, p)
{
   // Create a canvas container.

   fViewer = c;
}


ClassImp(TViewerX3D)


//______________________________________________________________________________
TViewerX3D::TViewerX3D(TVirtualPad *pad)
   : TVirtualViewer3D(),
     fCanvas(0), fContainer(0), fMenuBar(0), fFileMenu(0),
     fHelpMenu(0), fMenuBarLayout(0), fMenuBarItemLayout(0),
     fMenuBarHelpLayout(0), fCanvasLayout(0),
     fPad(pad), fBuildingScene(kFALSE), fPass(kSize)
{
   // Create ROOT X3D viewer.
   fMainFrame = new TX3DFrame(*this, gClient->GetRoot(), 800, 600);
   fOption = "x3d";
   fX3DWin = 0;
   fWidth  = 800;
   fHeight = 600;
   fXPos   = 0;
   fYPos   = 0;
   fTitle  = "x3d";
}


//______________________________________________________________________________
TViewerX3D::TViewerX3D(TVirtualPad *pad, Option_t *option, const char *title,
                       UInt_t width, UInt_t height)
   : TVirtualViewer3D(),
     fCanvas(0), fContainer(0), fMenuBar(0), fFileMenu(0),
     fHelpMenu(0), fMenuBarLayout(0), fMenuBarItemLayout(0),
     fMenuBarHelpLayout(0), fCanvasLayout(0),
     fPad(pad), fBuildingScene(kFALSE), fPass(kSize)
{
   // Create ROOT X3D viewer.
   fMainFrame = new TX3DFrame(*this, gClient->GetRoot(), 800, 600);
   fOption = option;
   fX3DWin = 0;
   fWidth  = width;
   fHeight = height;
   fXPos   = 0;
   fYPos   = 0;
   fTitle  = title;
}


//______________________________________________________________________________
TViewerX3D::TViewerX3D(TVirtualPad *pad, Option_t *option, const char *title,
                       Int_t x, Int_t y, UInt_t width, UInt_t height)
   : TVirtualViewer3D(),
     fCanvas(0), fContainer(0), fMenuBar(0), fFileMenu(0),
     fHelpMenu(0), fMenuBarLayout(0), fMenuBarItemLayout(0),
     fMenuBarHelpLayout(0), fCanvasLayout(0),
     fPad(pad), fBuildingScene(kFALSE), fPass(kSize)
{
   // Create ROOT X3D viewer.
   fMainFrame = new TX3DFrame(*this, gClient->GetRoot(), 800, 600);
   fOption = option;
   fX3DWin = 0;
   fWidth  = width;
   fHeight = height;
   fXPos   = x;
   fYPos   = y;
   fTitle  = title;
}


//______________________________________________________________________________
TViewerX3D::~TViewerX3D()
{
   // Delete ROOT X3D viewer.

   if (!fPad) return;

   if (fgCreated) {
      DeleteX3DWindow();
   }
   delete fCanvasLayout;
   delete fMenuBarHelpLayout;
   delete fMenuBarItemLayout;
   delete fMenuBarLayout;
   delete fHelpMenu;
   delete fFileMenu;
   delete fMenuBar;
   delete fContainer;
   delete fCanvas;
   delete fMainFrame;
   fgCreated = kFALSE;
}


//______________________________________________________________________________
void TViewerX3D::Close()
{
   // Close X3D Viewer
   assert(!fBuildingScene);
   fPad->ReleaseViewer3D();
   delete this;
}


//______________________________________________________________________________
void TViewerX3D::CreateViewer(const char *name)
{
   // Create the actual canvas.

   // Create menus
   fFileMenu = new TGPopupMenu(fMainFrame->GetClient()->GetRoot());
   fFileMenu->AddEntry("&New Viewer",         kFileNewViewer);
   fFileMenu->AddSeparator();
   fFileMenu->AddEntry("Save",                kFileSave);
   fFileMenu->AddEntry("Save As...",          kFileSaveAs);
   fFileMenu->AddSeparator();
   fFileMenu->AddEntry("&Print...",           kFilePrint);
   fFileMenu->AddSeparator();
   fFileMenu->AddEntry("&Close Viewer",       kFileCloseViewer);

   //fFileMenu->DefaultEntry(kFileNewViewer);
   fFileMenu->DisableEntry(kFileNewViewer);
   fFileMenu->DisableEntry(kFileSave);
   fFileMenu->DisableEntry(kFileSaveAs);
   fFileMenu->DisableEntry(kFilePrint);

   fHelpMenu = new TGPopupMenu(fMainFrame->GetClient()->GetRoot());
   fHelpMenu->AddEntry("&About ROOT...",           kHelpAbout);
   fHelpMenu->AddSeparator();
   fHelpMenu->AddEntry("Help On X3D Viewer...", kHelpOnViewer);

   // This main frame will process the menu commands
   fFileMenu->Associate(fMainFrame);
   fHelpMenu->Associate(fMainFrame);

   // Create menubar layout hints
   fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1);
   fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
   fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);

   // Create menubar
   fMenuBar = new TGMenuBar(fMainFrame, 1, 1, kHorizontalFrame);
   fMenuBar->AddPopup("&File",    fFileMenu,    fMenuBarItemLayout);
   fMenuBar->AddPopup("&Help",    fHelpMenu,    fMenuBarHelpLayout);

   fMainFrame->AddFrame(fMenuBar, fMenuBarLayout);

   // Create canvas and canvas container that will host the ROOT graphics
   fCanvas = new TGCanvas(fMainFrame, fMainFrame->GetWidth()+4, fMainFrame->GetHeight()+4,
                          kSunkenFrame | kDoubleBorder);
   InitX3DWindow();
   if (!fX3DWin) {
      fContainer    = 0;
      fCanvasLayout = 0;
      return;
   }
   fContainer = new TX3DContainer(this, fX3DWin, fCanvas->GetViewPort());
   fCanvas->SetContainer(fContainer);
   fCanvasLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
   fMainFrame->AddFrame(fCanvas, fCanvasLayout);

   // Misc

   fMainFrame->SetWindowName(name);
   fMainFrame->SetIconName(name);
   fMainFrame->SetClassHints("X3DViewer", "X3DViewer");

   fMainFrame->SetMWMHints(kMWMDecorAll, kMWMFuncAll, kMWMInputModeless);

   fMainFrame->MapSubwindows();

   // we need to use GetDefaultSize() to initialize the layout algorithm...
   fMainFrame->Resize(fMainFrame->GetDefaultSize());

   fMainFrame->MoveResize(fXPos, fYPos, fWidth, fHeight);
   fMainFrame->SetWMPosition(fXPos, fYPos);
   fgCreated = kTRUE;
}


//______________________________________________________________________________
void TViewerX3D::InitX3DWindow()
{
   // Setup geometry and initialize X3D.

   TView *view = fPad->GetView();
   if (!view) {
      Error("InitX3DWindow", "view is not set");
      return;
   }

   const Float_t kPI = Float_t (TMath::Pi());

   Float_t longitude_rad = ( 90 + view->GetLongitude()) * kPI/180.0;
   Float_t  latitude_rad = (-90 + view->GetLatitude() ) * kPI/180.0;
   Float_t       psi_rad = (      view->GetPsi()      ) * kPI/180.0;

   // Call 'x3d' package
   x3d_set_display(gVirtualX->GetDisplay());
   fX3DWin = (Window_t) x3d_main(&longitude_rad, &latitude_rad, &psi_rad,
   fOption.Data(), fCanvas->GetViewPort()->GetId());
}


//______________________________________________________________________________
void TViewerX3D::BeginScene()
{
   // The x3d viewer cannot rebuild a scene once created
   if (fgCreated) {
      return;
   }

   fBuildingScene = kTRUE;

   if (fPass == kSize) {
      gSize3D.numPoints = 0;
      gSize3D.numSegs   = 0;
      gSize3D.numPolys  = 0;
   }
}


//______________________________________________________________________________
void  TViewerX3D::EndScene()
{
   // The x3d viewer cannot rebuild a scene once created
   if (fgCreated) {
      return;
   }

   fBuildingScene = kFALSE;

   // Size pass done - and some points actually added
   if (gSize3D.numPoints != 0) {
      if (fPass == kSize) {
         // Allocate the X3D viewer buffer with sizes if any
         if (!AllocateX3DBuffer()) {
            Error("InitX3DWindow", "x3d buffer allocation failure");
            return;
         }

         // Enter draw pass and invoke another paint
         fPass = kDraw;
         fPad->Paint();
         fPass = kSize;
         CreateViewer(fTitle);
         Show();
      }
   } else {
      Int_t retval;
      new TGMsgBox(gClient->GetRoot(), gClient->GetRoot(),
                   "X3D Viewer", "Cannot display this content in the X3D viewer",
                   kMBIconExclamation, kMBOk, &retval);
      Close();
   }
}


//______________________________________________________________________________
Int_t TViewerX3D::AddObject(const TBuffer3D & buffer, Bool_t * addChildren)
{
   // The x3d viewer cannot rebuild a scene once created
   if (fgCreated) {
      if (addChildren) {
         *addChildren = kFALSE;
      }
      return TBuffer3D::kNone;
   }
   else if (addChildren) {
      *addChildren = kTRUE;
   }
   // Ensure we have the required sections
   UInt_t reqSections = TBuffer3D::kCore|TBuffer3D::kRawSizes;

   // Sizing does not require actual raw tesselation information
   if (fPass == kDraw) {
      reqSections |= TBuffer3D::kRaw;
   }

   if (!buffer.SectionsValid(reqSections)) {
      return reqSections;
   }

   if (buffer.Type() == TBuffer3DTypes::kMarker) {
      PaintPolyMarker(buffer);
      return TBuffer3D::kNone;
   }

   switch(fPass) {
      case(kSize): {
         gSize3D.numPoints += buffer.NbPnts();
         gSize3D.numSegs   += buffer.NbSegs();
         gSize3D.numPolys  += buffer.NbPols();
         break;
      }
      case (kDraw): {
         X3DBuffer *x3dBuff = new X3DBuffer;
         x3dBuff->numPoints = buffer.NbPnts();
         x3dBuff->numSegs   = buffer.NbSegs();
         x3dBuff->numPolys  = buffer.NbPols();
         x3dBuff->points    = new Float_t[3*buffer.NbPnts()];
         for (UInt_t i=0; i<3*buffer.NbPnts();i++)
            x3dBuff->points[i] = (Float_t)buffer.fPnts[i];
         x3dBuff->segs      = buffer.fSegs;
         x3dBuff->polys     = buffer.fPols;
         FillX3DBuffer(x3dBuff);
         delete [] x3dBuff->points;
         delete x3dBuff;
         break;
      }
      default: {
         assert(kFALSE);
         break;
      }
   }

   return TBuffer3D::kNone;
}


//______________________________________________________________________________
Int_t TViewerX3D::AddObject(UInt_t /* placedID */, const TBuffer3D & buffer, Bool_t * addChildren)
{
   // We don't support placed IDs - discard
   return AddObject(buffer,addChildren);
}


//______________________________________________________________________________
void TViewerX3D::PaintPolyMarker(const TBuffer3D & buffer) const
{
   // Paint 3D PolyMarker
   if (fgCreated) {
      return;
   }
   UInt_t mode;

   if (buffer.NbPnts() > 10000) mode = 1;     // One line marker    '-'
   else if (buffer.NbPnts() > 3000) mode = 2; // Two lines marker   '+'
   else mode = 3;                           // Three lines marker '*'

   switch(fPass) {
      case(kSize): {
         gSize3D.numPoints += 2*mode*buffer.NbPnts();
         gSize3D.numSegs   += mode*buffer.NbPnts();
         break;
      }
      case (kDraw): {
         X3DBuffer *x3dBuff = new X3DBuffer;
         x3dBuff->numPoints = 2*mode*buffer.NbPnts();
         x3dBuff->numSegs   = mode*buffer.NbPnts();
         x3dBuff->numPolys  = 0;
         x3dBuff->points    = new Float_t[3*x3dBuff->numPoints];
         x3dBuff->segs      = new Int_t[3*x3dBuff->numSegs];
         x3dBuff->polys     = 0;

         Double_t delta = 0.002;

         for (UInt_t i = 0; i < buffer.NbPnts(); i++) {
            for (UInt_t j = 0; j < mode; j++) {
               for (UInt_t k = 0; k < 2; k++) {
                  delta *= -1;
                  for (UInt_t n = 0; n < 3; n++) {
                     x3dBuff->points[mode*6*i+6*j+3*k+n] =
                     buffer.fPnts[3*i+n] * (1 + (j == n ? delta : 0));
                  }
               }
            }
         }

         for (Int_t i=0; i<x3dBuff->numSegs; i++) {
            x3dBuff->segs[3*i  ] = buffer.fSegs[0];
            x3dBuff->segs[3*i+1] = 2*i;
            x3dBuff->segs[3*i+2] = 2*i+1;
         }

         FillX3DBuffer(x3dBuff);
         delete [] x3dBuff->points;
         delete [] x3dBuff->segs;
         delete x3dBuff;
         break;
      }
   }
}


//______________________________________________________________________________
Int_t TViewerX3D::ExecCommand(Int_t px, Int_t py, char command)
{
// This function may be called from a script to animate an X3D picture
// px, py  mouse position
//command = 0       --- move to px,py
//        = w       --- wireframe mode
//        = e       --- hidden line mode
//        = r       --- hidden surface mode
//        = u       --- move object down
//        = i       --- move object up
//        = o       --- toggle controls style
//        = s       --- toggle stereo display
//        = d       --- toggle blue stereo view
//        = f       --- toggle double buffer
//        = h       --- move object right
//        = j       --- move object forward
//        = k       --- move object backward
//        = l       --- move object left
//        = x a     --- rotate about x
//        = y b     --- rotate about y
//        = z c     --- rotate about z
//        = 1 2 3   --- autorotate about x
//        = 4 5 6   --- autorotate about y
//        = 7 8 9   --- autorotate about z
//        = [ ] { } --- adjust focus
// Example:
/*
{
   gSystem->Load("libX3d");
   TCanvas *c1 = new TCanvas("c1");
   TFile *f = new TFile("hsimple.root");
   TTree *ntuple = (TTree*)f->Get("ntuple");
   ntuple->SetMarkerColor(kYellow);
   ntuple->Draw("px:py:pz");
   TViewerX3D *x3d = new TViewerX3D(c1,"");
   for (Int_t i=0;i<500;i++) {
      Int_t px = i%500;
      Int_t py = (2*i)%200;
      x3d->ExecCommand(px,py,0);  //rotate
      if (i%20 >10) x3d->ExecCommand(px,py,'j'); //zoom
      if (i%20 <10) x3d->ExecCommand(px,py,'k'); //unzoom
   }
}
*/

   return x3d_exec_command(px,py,command);
}


//______________________________________________________________________________
void TViewerX3D::GetPosition(Float_t &longitude, Float_t &latitude, Float_t &psi)
{
   // Get position
   x3d_get_position(&longitude, &latitude, &psi);
}

//______________________________________________________________________________
void TViewerX3D::DeleteX3DWindow()
{
   // Close X3D window.

   x3d_terminate();
}


//______________________________________________________________________________
void TViewerX3D::Update()
{
   // Update X3D viewer.

   x3d_update();
}


//______________________________________________________________________________
Bool_t TViewerX3D::ProcessFrameMessage(Long_t msg, Long_t parm1, Long_t)
{
   // Handle menu and other command generated by the user.

   TRootHelpDialog *hd;

   switch (GET_MSG(msg)) {

      case kC_COMMAND:

         switch (GET_SUBMSG(msg)) {

            case kCM_BUTTON:
            case kCM_MENU:

               switch (parm1) {
                  // Handle File menu items...
                  case kFileNewViewer:
                     if (fPad) fPad->GetViewer3D("x3d");
                     break;
                  case kFileSave:
                  case kFileSaveAs:
                  case kFilePrint:
                     break;
                  case kFileCloseViewer:
                     fMainFrame->SendCloseMessage();
                     break;

                  // Handle Help menu items...
                  case kHelpAbout:
                     {
                        char str[32];
                        snprintf(str,32, "About ROOT %s...", gROOT->GetVersion());
                        hd = new TRootHelpDialog(fMainFrame, str, 600, 400);
                        hd->SetText(gHelpAbout);
                        hd->Popup();
                     }
                     break;
                  case kHelpOnViewer:
                     hd = new TRootHelpDialog(fMainFrame, "Help on X3D Viewer...", 600, 400);
                     hd->SetText(gHelpX3DViewer);
                     hd->Popup();
                     break;
               }
            default:
               break;
         }
      default:
         break;
   }
   return kTRUE;
}


//______________________________________________________________________________
Bool_t TViewerX3D::HandleContainerButton(Event_t * /*ev */ )
{
   // After button release get current position and update associated pad.

   // Currently disabled as only drawing into one view at a time
   // Re-enalbe when multiple viewer implemented on pad
   /*if (ev->fType == kButtonRelease) {
      Float_t longitude_rad;
      Float_t latitude_rad;
      Float_t psi_rad;
      const Float_t kPI = Float_t (TMath::Pi());

      x3d_get_position(&longitude_rad, &latitude_rad, &psi_rad);

      Int_t irep;

      Float_t longitude_deg = longitude_rad * 180.0/kPI - 90;
      Float_t  latitude_deg = latitude_rad  * 180.0/kPI + 90;
      Float_t       psi_deg = psi_rad       * 180.0/kPI;

      fPad->GetView()->SetView(longitude_deg, latitude_deg, psi_deg, irep);

      fPad->SetPhi(-90 - longitude_deg);
      fPad->SetTheta(90 - latitude_deg);

      fPad->Modified(kTRUE);
      fPad->Update();
}*/
   return kTRUE;
}
 TViewerX3D.cxx:1
 TViewerX3D.cxx:2
 TViewerX3D.cxx:3
 TViewerX3D.cxx:4
 TViewerX3D.cxx:5
 TViewerX3D.cxx:6
 TViewerX3D.cxx:7
 TViewerX3D.cxx:8
 TViewerX3D.cxx:9
 TViewerX3D.cxx:10
 TViewerX3D.cxx:11
 TViewerX3D.cxx:12
 TViewerX3D.cxx:13
 TViewerX3D.cxx:14
 TViewerX3D.cxx:15
 TViewerX3D.cxx:16
 TViewerX3D.cxx:17
 TViewerX3D.cxx:18
 TViewerX3D.cxx:19
 TViewerX3D.cxx:20
 TViewerX3D.cxx:21
 TViewerX3D.cxx:22
 TViewerX3D.cxx:23
 TViewerX3D.cxx:24
 TViewerX3D.cxx:25
 TViewerX3D.cxx:26
 TViewerX3D.cxx:27
 TViewerX3D.cxx:28
 TViewerX3D.cxx:29
 TViewerX3D.cxx:30
 TViewerX3D.cxx:31
 TViewerX3D.cxx:32
 TViewerX3D.cxx:33
 TViewerX3D.cxx:34
 TViewerX3D.cxx:35
 TViewerX3D.cxx:36
 TViewerX3D.cxx:37
 TViewerX3D.cxx:38
 TViewerX3D.cxx:39
 TViewerX3D.cxx:40
 TViewerX3D.cxx:41
 TViewerX3D.cxx:42
 TViewerX3D.cxx:43
 TViewerX3D.cxx:44
 TViewerX3D.cxx:45
 TViewerX3D.cxx:46
 TViewerX3D.cxx:47
 TViewerX3D.cxx:48
 TViewerX3D.cxx:49
 TViewerX3D.cxx:50
 TViewerX3D.cxx:51
 TViewerX3D.cxx:52
 TViewerX3D.cxx:53
 TViewerX3D.cxx:54
 TViewerX3D.cxx:55
 TViewerX3D.cxx:56
 TViewerX3D.cxx:57
 TViewerX3D.cxx:58
 TViewerX3D.cxx:59
 TViewerX3D.cxx:60
 TViewerX3D.cxx:61
 TViewerX3D.cxx:62
 TViewerX3D.cxx:63
 TViewerX3D.cxx:64
 TViewerX3D.cxx:65
 TViewerX3D.cxx:66
 TViewerX3D.cxx:67
 TViewerX3D.cxx:68
 TViewerX3D.cxx:69
 TViewerX3D.cxx:70
 TViewerX3D.cxx:71
 TViewerX3D.cxx:72
 TViewerX3D.cxx:73
 TViewerX3D.cxx:74
 TViewerX3D.cxx:75
 TViewerX3D.cxx:76
 TViewerX3D.cxx:77
 TViewerX3D.cxx:78
 TViewerX3D.cxx:79
 TViewerX3D.cxx:80
 TViewerX3D.cxx:81
 TViewerX3D.cxx:82
 TViewerX3D.cxx:83
 TViewerX3D.cxx:84
 TViewerX3D.cxx:85
 TViewerX3D.cxx:86
 TViewerX3D.cxx:87
 TViewerX3D.cxx:88
 TViewerX3D.cxx:89
 TViewerX3D.cxx:90
 TViewerX3D.cxx:91
 TViewerX3D.cxx:92
 TViewerX3D.cxx:93
 TViewerX3D.cxx:94
 TViewerX3D.cxx:95
 TViewerX3D.cxx:96
 TViewerX3D.cxx:97
 TViewerX3D.cxx:98
 TViewerX3D.cxx:99
 TViewerX3D.cxx:100
 TViewerX3D.cxx:101
 TViewerX3D.cxx:102
 TViewerX3D.cxx:103
 TViewerX3D.cxx:104
 TViewerX3D.cxx:105
 TViewerX3D.cxx:106
 TViewerX3D.cxx:107
 TViewerX3D.cxx:108
 TViewerX3D.cxx:109
 TViewerX3D.cxx:110
 TViewerX3D.cxx:111
 TViewerX3D.cxx:112
 TViewerX3D.cxx:113
 TViewerX3D.cxx:114
 TViewerX3D.cxx:115
 TViewerX3D.cxx:116
 TViewerX3D.cxx:117
 TViewerX3D.cxx:118
 TViewerX3D.cxx:119
 TViewerX3D.cxx:120
 TViewerX3D.cxx:121
 TViewerX3D.cxx:122
 TViewerX3D.cxx:123
 TViewerX3D.cxx:124
 TViewerX3D.cxx:125
 TViewerX3D.cxx:126
 TViewerX3D.cxx:127
 TViewerX3D.cxx:128
 TViewerX3D.cxx:129
 TViewerX3D.cxx:130
 TViewerX3D.cxx:131
 TViewerX3D.cxx:132
 TViewerX3D.cxx:133
 TViewerX3D.cxx:134
 TViewerX3D.cxx:135
 TViewerX3D.cxx:136
 TViewerX3D.cxx:137
 TViewerX3D.cxx:138
 TViewerX3D.cxx:139
 TViewerX3D.cxx:140
 TViewerX3D.cxx:141
 TViewerX3D.cxx:142
 TViewerX3D.cxx:143
 TViewerX3D.cxx:144
 TViewerX3D.cxx:145
 TViewerX3D.cxx:146
 TViewerX3D.cxx:147
 TViewerX3D.cxx:148
 TViewerX3D.cxx:149
 TViewerX3D.cxx:150
 TViewerX3D.cxx:151
 TViewerX3D.cxx:152
 TViewerX3D.cxx:153
 TViewerX3D.cxx:154
 TViewerX3D.cxx:155
 TViewerX3D.cxx:156
 TViewerX3D.cxx:157
 TViewerX3D.cxx:158
 TViewerX3D.cxx:159
 TViewerX3D.cxx:160
 TViewerX3D.cxx:161
 TViewerX3D.cxx:162
 TViewerX3D.cxx:163
 TViewerX3D.cxx:164
 TViewerX3D.cxx:165
 TViewerX3D.cxx:166
 TViewerX3D.cxx:167
 TViewerX3D.cxx:168
 TViewerX3D.cxx:169
 TViewerX3D.cxx:170
 TViewerX3D.cxx:171
 TViewerX3D.cxx:172
 TViewerX3D.cxx:173
 TViewerX3D.cxx:174
 TViewerX3D.cxx:175
 TViewerX3D.cxx:176
 TViewerX3D.cxx:177
 TViewerX3D.cxx:178
 TViewerX3D.cxx:179
 TViewerX3D.cxx:180
 TViewerX3D.cxx:181
 TViewerX3D.cxx:182
 TViewerX3D.cxx:183
 TViewerX3D.cxx:184
 TViewerX3D.cxx:185
 TViewerX3D.cxx:186
 TViewerX3D.cxx:187
 TViewerX3D.cxx:188
 TViewerX3D.cxx:189
 TViewerX3D.cxx:190
 TViewerX3D.cxx:191
 TViewerX3D.cxx:192
 TViewerX3D.cxx:193
 TViewerX3D.cxx:194
 TViewerX3D.cxx:195
 TViewerX3D.cxx:196
 TViewerX3D.cxx:197
 TViewerX3D.cxx:198
 TViewerX3D.cxx:199
 TViewerX3D.cxx:200
 TViewerX3D.cxx:201
 TViewerX3D.cxx:202
 TViewerX3D.cxx:203
 TViewerX3D.cxx:204
 TViewerX3D.cxx:205
 TViewerX3D.cxx:206
 TViewerX3D.cxx:207
 TViewerX3D.cxx:208
 TViewerX3D.cxx:209
 TViewerX3D.cxx:210
 TViewerX3D.cxx:211
 TViewerX3D.cxx:212
 TViewerX3D.cxx:213
 TViewerX3D.cxx:214
 TViewerX3D.cxx:215
 TViewerX3D.cxx:216
 TViewerX3D.cxx:217
 TViewerX3D.cxx:218
 TViewerX3D.cxx:219
 TViewerX3D.cxx:220
 TViewerX3D.cxx:221
 TViewerX3D.cxx:222
 TViewerX3D.cxx:223
 TViewerX3D.cxx:224
 TViewerX3D.cxx:225
 TViewerX3D.cxx:226
 TViewerX3D.cxx:227
 TViewerX3D.cxx:228
 TViewerX3D.cxx:229
 TViewerX3D.cxx:230
 TViewerX3D.cxx:231
 TViewerX3D.cxx:232
 TViewerX3D.cxx:233
 TViewerX3D.cxx:234
 TViewerX3D.cxx:235
 TViewerX3D.cxx:236
 TViewerX3D.cxx:237
 TViewerX3D.cxx:238
 TViewerX3D.cxx:239
 TViewerX3D.cxx:240
 TViewerX3D.cxx:241
 TViewerX3D.cxx:242
 TViewerX3D.cxx:243
 TViewerX3D.cxx:244
 TViewerX3D.cxx:245
 TViewerX3D.cxx:246
 TViewerX3D.cxx:247
 TViewerX3D.cxx:248
 TViewerX3D.cxx:249
 TViewerX3D.cxx:250
 TViewerX3D.cxx:251
 TViewerX3D.cxx:252
 TViewerX3D.cxx:253
 TViewerX3D.cxx:254
 TViewerX3D.cxx:255
 TViewerX3D.cxx:256
 TViewerX3D.cxx:257
 TViewerX3D.cxx:258
 TViewerX3D.cxx:259
 TViewerX3D.cxx:260
 TViewerX3D.cxx:261
 TViewerX3D.cxx:262
 TViewerX3D.cxx:263
 TViewerX3D.cxx:264
 TViewerX3D.cxx:265
 TViewerX3D.cxx:266
 TViewerX3D.cxx:267
 TViewerX3D.cxx:268
 TViewerX3D.cxx:269
 TViewerX3D.cxx:270
 TViewerX3D.cxx:271
 TViewerX3D.cxx:272
 TViewerX3D.cxx:273
 TViewerX3D.cxx:274
 TViewerX3D.cxx:275
 TViewerX3D.cxx:276
 TViewerX3D.cxx:277
 TViewerX3D.cxx:278
 TViewerX3D.cxx:279
 TViewerX3D.cxx:280
 TViewerX3D.cxx:281
 TViewerX3D.cxx:282
 TViewerX3D.cxx:283
 TViewerX3D.cxx:284
 TViewerX3D.cxx:285
 TViewerX3D.cxx:286
 TViewerX3D.cxx:287
 TViewerX3D.cxx:288
 TViewerX3D.cxx:289
 TViewerX3D.cxx:290
 TViewerX3D.cxx:291
 TViewerX3D.cxx:292
 TViewerX3D.cxx:293
 TViewerX3D.cxx:294
 TViewerX3D.cxx:295
 TViewerX3D.cxx:296
 TViewerX3D.cxx:297
 TViewerX3D.cxx:298
 TViewerX3D.cxx:299
 TViewerX3D.cxx:300
 TViewerX3D.cxx:301
 TViewerX3D.cxx:302
 TViewerX3D.cxx:303
 TViewerX3D.cxx:304
 TViewerX3D.cxx:305
 TViewerX3D.cxx:306
 TViewerX3D.cxx:307
 TViewerX3D.cxx:308
 TViewerX3D.cxx:309
 TViewerX3D.cxx:310
 TViewerX3D.cxx:311
 TViewerX3D.cxx:312
 TViewerX3D.cxx:313
 TViewerX3D.cxx:314
 TViewerX3D.cxx:315
 TViewerX3D.cxx:316
 TViewerX3D.cxx:317
 TViewerX3D.cxx:318
 TViewerX3D.cxx:319
 TViewerX3D.cxx:320
 TViewerX3D.cxx:321
 TViewerX3D.cxx:322
 TViewerX3D.cxx:323
 TViewerX3D.cxx:324
 TViewerX3D.cxx:325
 TViewerX3D.cxx:326
 TViewerX3D.cxx:327
 TViewerX3D.cxx:328
 TViewerX3D.cxx:329
 TViewerX3D.cxx:330
 TViewerX3D.cxx:331
 TViewerX3D.cxx:332
 TViewerX3D.cxx:333
 TViewerX3D.cxx:334
 TViewerX3D.cxx:335
 TViewerX3D.cxx:336
 TViewerX3D.cxx:337
 TViewerX3D.cxx:338
 TViewerX3D.cxx:339
 TViewerX3D.cxx:340
 TViewerX3D.cxx:341
 TViewerX3D.cxx:342
 TViewerX3D.cxx:343
 TViewerX3D.cxx:344
 TViewerX3D.cxx:345
 TViewerX3D.cxx:346
 TViewerX3D.cxx:347
 TViewerX3D.cxx:348
 TViewerX3D.cxx:349
 TViewerX3D.cxx:350
 TViewerX3D.cxx:351
 TViewerX3D.cxx:352
 TViewerX3D.cxx:353
 TViewerX3D.cxx:354
 TViewerX3D.cxx:355
 TViewerX3D.cxx:356
 TViewerX3D.cxx:357
 TViewerX3D.cxx:358
 TViewerX3D.cxx:359
 TViewerX3D.cxx:360
 TViewerX3D.cxx:361
 TViewerX3D.cxx:362
 TViewerX3D.cxx:363
 TViewerX3D.cxx:364
 TViewerX3D.cxx:365
 TViewerX3D.cxx:366
 TViewerX3D.cxx:367
 TViewerX3D.cxx:368
 TViewerX3D.cxx:369
 TViewerX3D.cxx:370
 TViewerX3D.cxx:371
 TViewerX3D.cxx:372
 TViewerX3D.cxx:373
 TViewerX3D.cxx:374
 TViewerX3D.cxx:375
 TViewerX3D.cxx:376
 TViewerX3D.cxx:377
 TViewerX3D.cxx:378
 TViewerX3D.cxx:379
 TViewerX3D.cxx:380
 TViewerX3D.cxx:381
 TViewerX3D.cxx:382
 TViewerX3D.cxx:383
 TViewerX3D.cxx:384
 TViewerX3D.cxx:385
 TViewerX3D.cxx:386
 TViewerX3D.cxx:387
 TViewerX3D.cxx:388
 TViewerX3D.cxx:389
 TViewerX3D.cxx:390
 TViewerX3D.cxx:391
 TViewerX3D.cxx:392
 TViewerX3D.cxx:393
 TViewerX3D.cxx:394
 TViewerX3D.cxx:395
 TViewerX3D.cxx:396
 TViewerX3D.cxx:397
 TViewerX3D.cxx:398
 TViewerX3D.cxx:399
 TViewerX3D.cxx:400
 TViewerX3D.cxx:401
 TViewerX3D.cxx:402
 TViewerX3D.cxx:403
 TViewerX3D.cxx:404
 TViewerX3D.cxx:405
 TViewerX3D.cxx:406
 TViewerX3D.cxx:407
 TViewerX3D.cxx:408
 TViewerX3D.cxx:409
 TViewerX3D.cxx:410
 TViewerX3D.cxx:411
 TViewerX3D.cxx:412
 TViewerX3D.cxx:413
 TViewerX3D.cxx:414
 TViewerX3D.cxx:415
 TViewerX3D.cxx:416
 TViewerX3D.cxx:417
 TViewerX3D.cxx:418
 TViewerX3D.cxx:419
 TViewerX3D.cxx:420
 TViewerX3D.cxx:421
 TViewerX3D.cxx:422
 TViewerX3D.cxx:423
 TViewerX3D.cxx:424
 TViewerX3D.cxx:425
 TViewerX3D.cxx:426
 TViewerX3D.cxx:427
 TViewerX3D.cxx:428
 TViewerX3D.cxx:429
 TViewerX3D.cxx:430
 TViewerX3D.cxx:431
 TViewerX3D.cxx:432
 TViewerX3D.cxx:433
 TViewerX3D.cxx:434
 TViewerX3D.cxx:435
 TViewerX3D.cxx:436
 TViewerX3D.cxx:437
 TViewerX3D.cxx:438
 TViewerX3D.cxx:439
 TViewerX3D.cxx:440
 TViewerX3D.cxx:441
 TViewerX3D.cxx:442
 TViewerX3D.cxx:443
 TViewerX3D.cxx:444
 TViewerX3D.cxx:445
 TViewerX3D.cxx:446
 TViewerX3D.cxx:447
 TViewerX3D.cxx:448
 TViewerX3D.cxx:449
 TViewerX3D.cxx:450
 TViewerX3D.cxx:451
 TViewerX3D.cxx:452
 TViewerX3D.cxx:453
 TViewerX3D.cxx:454
 TViewerX3D.cxx:455
 TViewerX3D.cxx:456
 TViewerX3D.cxx:457
 TViewerX3D.cxx:458
 TViewerX3D.cxx:459
 TViewerX3D.cxx:460
 TViewerX3D.cxx:461
 TViewerX3D.cxx:462
 TViewerX3D.cxx:463
 TViewerX3D.cxx:464
 TViewerX3D.cxx:465
 TViewerX3D.cxx:466
 TViewerX3D.cxx:467
 TViewerX3D.cxx:468
 TViewerX3D.cxx:469
 TViewerX3D.cxx:470
 TViewerX3D.cxx:471
 TViewerX3D.cxx:472
 TViewerX3D.cxx:473
 TViewerX3D.cxx:474
 TViewerX3D.cxx:475
 TViewerX3D.cxx:476
 TViewerX3D.cxx:477
 TViewerX3D.cxx:478
 TViewerX3D.cxx:479
 TViewerX3D.cxx:480
 TViewerX3D.cxx:481
 TViewerX3D.cxx:482
 TViewerX3D.cxx:483
 TViewerX3D.cxx:484
 TViewerX3D.cxx:485
 TViewerX3D.cxx:486
 TViewerX3D.cxx:487
 TViewerX3D.cxx:488
 TViewerX3D.cxx:489
 TViewerX3D.cxx:490
 TViewerX3D.cxx:491
 TViewerX3D.cxx:492
 TViewerX3D.cxx:493
 TViewerX3D.cxx:494
 TViewerX3D.cxx:495
 TViewerX3D.cxx:496
 TViewerX3D.cxx:497
 TViewerX3D.cxx:498
 TViewerX3D.cxx:499
 TViewerX3D.cxx:500
 TViewerX3D.cxx:501
 TViewerX3D.cxx:502
 TViewerX3D.cxx:503
 TViewerX3D.cxx:504
 TViewerX3D.cxx:505
 TViewerX3D.cxx:506
 TViewerX3D.cxx:507
 TViewerX3D.cxx:508
 TViewerX3D.cxx:509
 TViewerX3D.cxx:510
 TViewerX3D.cxx:511
 TViewerX3D.cxx:512
 TViewerX3D.cxx:513
 TViewerX3D.cxx:514
 TViewerX3D.cxx:515
 TViewerX3D.cxx:516
 TViewerX3D.cxx:517
 TViewerX3D.cxx:518
 TViewerX3D.cxx:519
 TViewerX3D.cxx:520
 TViewerX3D.cxx:521
 TViewerX3D.cxx:522
 TViewerX3D.cxx:523
 TViewerX3D.cxx:524
 TViewerX3D.cxx:525
 TViewerX3D.cxx:526
 TViewerX3D.cxx:527
 TViewerX3D.cxx:528
 TViewerX3D.cxx:529
 TViewerX3D.cxx:530
 TViewerX3D.cxx:531
 TViewerX3D.cxx:532
 TViewerX3D.cxx:533
 TViewerX3D.cxx:534
 TViewerX3D.cxx:535
 TViewerX3D.cxx:536
 TViewerX3D.cxx:537
 TViewerX3D.cxx:538
 TViewerX3D.cxx:539
 TViewerX3D.cxx:540
 TViewerX3D.cxx:541
 TViewerX3D.cxx:542
 TViewerX3D.cxx:543
 TViewerX3D.cxx:544
 TViewerX3D.cxx:545
 TViewerX3D.cxx:546
 TViewerX3D.cxx:547
 TViewerX3D.cxx:548
 TViewerX3D.cxx:549
 TViewerX3D.cxx:550
 TViewerX3D.cxx:551
 TViewerX3D.cxx:552
 TViewerX3D.cxx:553
 TViewerX3D.cxx:554
 TViewerX3D.cxx:555
 TViewerX3D.cxx:556
 TViewerX3D.cxx:557
 TViewerX3D.cxx:558
 TViewerX3D.cxx:559
 TViewerX3D.cxx:560
 TViewerX3D.cxx:561
 TViewerX3D.cxx:562
 TViewerX3D.cxx:563
 TViewerX3D.cxx:564
 TViewerX3D.cxx:565
 TViewerX3D.cxx:566
 TViewerX3D.cxx:567
 TViewerX3D.cxx:568
 TViewerX3D.cxx:569
 TViewerX3D.cxx:570
 TViewerX3D.cxx:571
 TViewerX3D.cxx:572
 TViewerX3D.cxx:573
 TViewerX3D.cxx:574
 TViewerX3D.cxx:575
 TViewerX3D.cxx:576
 TViewerX3D.cxx:577
 TViewerX3D.cxx:578
 TViewerX3D.cxx:579
 TViewerX3D.cxx:580
 TViewerX3D.cxx:581
 TViewerX3D.cxx:582
 TViewerX3D.cxx:583
 TViewerX3D.cxx:584
 TViewerX3D.cxx:585
 TViewerX3D.cxx:586
 TViewerX3D.cxx:587
 TViewerX3D.cxx:588
 TViewerX3D.cxx:589
 TViewerX3D.cxx:590
 TViewerX3D.cxx:591
 TViewerX3D.cxx:592
 TViewerX3D.cxx:593
 TViewerX3D.cxx:594
 TViewerX3D.cxx:595
 TViewerX3D.cxx:596
 TViewerX3D.cxx:597
 TViewerX3D.cxx:598
 TViewerX3D.cxx:599
 TViewerX3D.cxx:600
 TViewerX3D.cxx:601
 TViewerX3D.cxx:602
 TViewerX3D.cxx:603
 TViewerX3D.cxx:604
 TViewerX3D.cxx:605
 TViewerX3D.cxx:606
 TViewerX3D.cxx:607
 TViewerX3D.cxx:608
 TViewerX3D.cxx:609
 TViewerX3D.cxx:610
 TViewerX3D.cxx:611
 TViewerX3D.cxx:612
 TViewerX3D.cxx:613
 TViewerX3D.cxx:614
 TViewerX3D.cxx:615
 TViewerX3D.cxx:616
 TViewerX3D.cxx:617
 TViewerX3D.cxx:618
 TViewerX3D.cxx:619
 TViewerX3D.cxx:620
 TViewerX3D.cxx:621
 TViewerX3D.cxx:622
 TViewerX3D.cxx:623
 TViewerX3D.cxx:624
 TViewerX3D.cxx:625
 TViewerX3D.cxx:626
 TViewerX3D.cxx:627
 TViewerX3D.cxx:628
 TViewerX3D.cxx:629
 TViewerX3D.cxx:630
 TViewerX3D.cxx:631
 TViewerX3D.cxx:632
 TViewerX3D.cxx:633
 TViewerX3D.cxx:634
 TViewerX3D.cxx:635
 TViewerX3D.cxx:636
 TViewerX3D.cxx:637
 TViewerX3D.cxx:638
 TViewerX3D.cxx:639
 TViewerX3D.cxx:640
 TViewerX3D.cxx:641
 TViewerX3D.cxx:642
 TViewerX3D.cxx:643
 TViewerX3D.cxx:644
 TViewerX3D.cxx:645
 TViewerX3D.cxx:646
 TViewerX3D.cxx:647
 TViewerX3D.cxx:648
 TViewerX3D.cxx:649
 TViewerX3D.cxx:650
 TViewerX3D.cxx:651
 TViewerX3D.cxx:652
 TViewerX3D.cxx:653
 TViewerX3D.cxx:654
 TViewerX3D.cxx:655
 TViewerX3D.cxx:656
 TViewerX3D.cxx:657
 TViewerX3D.cxx:658
 TViewerX3D.cxx:659
 TViewerX3D.cxx:660
 TViewerX3D.cxx:661
 TViewerX3D.cxx:662
 TViewerX3D.cxx:663
 TViewerX3D.cxx:664
 TViewerX3D.cxx:665
 TViewerX3D.cxx:666
 TViewerX3D.cxx:667
 TViewerX3D.cxx:668
 TViewerX3D.cxx:669
 TViewerX3D.cxx:670
 TViewerX3D.cxx:671
 TViewerX3D.cxx:672
 TViewerX3D.cxx:673
 TViewerX3D.cxx:674
 TViewerX3D.cxx:675
 TViewerX3D.cxx:676
 TViewerX3D.cxx:677
 TViewerX3D.cxx:678
 TViewerX3D.cxx:679