Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/OpenInventor/src/G4OpenInventorXtExaminerViewer.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /visualization/OpenInventor/src/G4OpenInventorXtExaminerViewer.cc (Version 11.3.0) and /visualization/OpenInventor/src/G4OpenInventorXtExaminerViewer.cc (Version 11.1.2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //                                                 26 //
 27 // Open Inventor Xt Extended Viewer - 30 Oct 2     27 // Open Inventor Xt Extended Viewer - 30 Oct 2012
 28 // Rastislav Ondrasek, Pierre-Luc Gagnon, Fred     28 // Rastislav Ondrasek, Pierre-Luc Gagnon, Frederick Jones TRIUMF
 29                                                    29 
 30 #include <stdio.h>                                 30 #include <stdio.h>
 31 #include <string.h>                                31 #include <string.h>
 32 #include <string>                                  32 #include <string>
 33 #include <sstream>                                 33 #include <sstream>
 34 #include <cmath>                                   34 #include <cmath>
 35 #include <iostream>                                35 #include <iostream>
 36 #include <iomanip>                                 36 #include <iomanip>
 37 #include <cstdio>                                  37 #include <cstdio>
 38 #include <algorithm> // For using sort on a ve     38 #include <algorithm> // For using sort on a vector
 39 #include <X11/keysym.h>                            39 #include <X11/keysym.h>
 40                                                    40 
 41 #include <Xm/Xm.h>                                 41 #include <Xm/Xm.h>
 42 #include <Xm/Text.h>                               42 #include <Xm/Text.h>
 43 #include <Xm/List.h>                               43 #include <Xm/List.h>
 44 #include <Xm/MessageB.h>                           44 #include <Xm/MessageB.h>
 45 #include <Xm/PushB.h>                              45 #include <Xm/PushB.h>
 46 #include <Xm/ToggleB.h>                            46 #include <Xm/ToggleB.h>
 47 #include <Xm/CascadeB.h>                           47 #include <Xm/CascadeB.h>
 48 #include <Xm/ArrowBG.h>                            48 #include <Xm/ArrowBG.h>
 49 #include <Xm/Form.h>                               49 #include <Xm/Form.h>
 50 #include <Xm/RowColumn.h>                          50 #include <Xm/RowColumn.h>
 51 #include <Xm/FileSB.h>                             51 #include <Xm/FileSB.h>
 52 #include <Xm/SelectioB.h>                          52 #include <Xm/SelectioB.h>
 53 #include <Xm/Protocols.h>                          53 #include <Xm/Protocols.h>
 54 #include <Xm/SeparatoG.h>                          54 #include <Xm/SeparatoG.h>
 55 #include <Xm/DialogS.h>                            55 #include <Xm/DialogS.h>  
 56 #include <Xm/PanedW.h>                             56 #include <Xm/PanedW.h>
 57 #include <Xm/LabelG.h>                             57 #include <Xm/LabelG.h>
 58 #include <Xm/Scale.h>                              58 #include <Xm/Scale.h>
 59 #include <Xm/DrawingA.h>                           59 #include <Xm/DrawingA.h>
 60                                                    60 
 61 #include <Inventor/Xt/SoXt.h>                      61 #include <Inventor/Xt/SoXt.h>
 62 //#include <Inventor/Xt/SoXtInternal.h>            62 //#include <Inventor/Xt/SoXtInternal.h>
 63 #include <Inventor/Xt/SoXtCursor.h>                63 #include <Inventor/Xt/SoXtCursor.h>
 64 #include <Inventor/events/SoKeyboardEvent.h>       64 #include <Inventor/events/SoKeyboardEvent.h>
 65 #include <Inventor/events/SoMouseButtonEvent.h     65 #include <Inventor/events/SoMouseButtonEvent.h>
 66 #include <Inventor/events/SoLocation2Event.h>      66 #include <Inventor/events/SoLocation2Event.h>
 67 #include <Inventor/nodes/SoSeparator.h>            67 #include <Inventor/nodes/SoSeparator.h>
 68 #include <Inventor/nodes/SoOrthographicCamera.     68 #include <Inventor/nodes/SoOrthographicCamera.h>
 69 #include <Inventor/nodes/SoPerspectiveCamera.h     69 #include <Inventor/nodes/SoPerspectiveCamera.h>
 70 // FWJ moved to header file                        70 // FWJ moved to header file
 71 //#include <Inventor/nodes/SoEventCallback.h>      71 //#include <Inventor/nodes/SoEventCallback.h>
 72 #include <Inventor/nodes/SoLineSet.h>              72 #include <Inventor/nodes/SoLineSet.h>
 73 #include <Inventor/nodes/SoMaterial.h>             73 #include <Inventor/nodes/SoMaterial.h>
 74 #include <Inventor/errors/SoDebugError.h>          74 #include <Inventor/errors/SoDebugError.h>
 75 #include <Inventor/SoPickedPoint.h>                75 #include <Inventor/SoPickedPoint.h>
 76 #include <Inventor/actions/SoWriteAction.h>        76 #include <Inventor/actions/SoWriteAction.h>
 77                                                    77 
 78 #include "G4OpenInventorXtExaminerViewer.hh"       78 #include "G4OpenInventorXtExaminerViewer.hh"
 79 #include "wheelmouse.h"  // To use mouse scrol     79 #include "wheelmouse.h"  // To use mouse scrolling in dialogs
 80 #include "SoXtInternal.h"                          80 #include "SoXtInternal.h"
 81 #include <Inventor/sensors/SoTimerSensor.h>        81 #include <Inventor/sensors/SoTimerSensor.h>   // Animation
 82 #include <Inventor/sensors/SoNodeSensor.h>         82 #include <Inventor/sensors/SoNodeSensor.h>    // Detect start of run
 83 #include "saveViewPt.h"                            83 #include "saveViewPt.h"
 84 #include "pickext.h"                               84 #include "pickext.h"
 85 #include "pickref.h"                               85 #include "pickref.h"
 86 #include "wireframe.h"                             86 #include "wireframe.h"
 87 //#include "console.h"                             87 //#include "console.h"
 88 //#include "favorites.h"                           88 //#include "favorites.h"
 89                                                    89 
 90 #include "Geant4_SoPolyhedron.h"                   90 #include "Geant4_SoPolyhedron.h"
 91 //#include "G4RunManager.hh"                       91 //#include "G4RunManager.hh"
 92 //#include "G4Run.hh"                              92 //#include "G4Run.hh"
 93 #include "G4TrajectoryPoint.hh"                    93 #include "G4TrajectoryPoint.hh"
 94 #include "G4AttHolder.hh"                          94 #include "G4AttHolder.hh"
 95 #include "G4AttCheck.hh"                           95 #include "G4AttCheck.hh"
 96                                                    96 
 97 #include <Inventor/nodes/SoCallback.h>             97 #include <Inventor/nodes/SoCallback.h>
 98 #include <Inventor/nodes/SoSwitch.h>               98 #include <Inventor/nodes/SoSwitch.h>
 99 #include <Inventor/nodes/SoScale.h>                99 #include <Inventor/nodes/SoScale.h>
100 #include <Inventor/nodes/SoTranslation.h>         100 #include <Inventor/nodes/SoTranslation.h>
101 #include <Inventor/actions/SoSearchAction.h>      101 #include <Inventor/actions/SoSearchAction.h>
102 #include <Inventor/actions/SoGetBoundingBoxAct    102 #include <Inventor/actions/SoGetBoundingBoxAction.h>
103                                                   103 
104 #include <Inventor/nodes/SoCoordinate3.h>         104 #include <Inventor/nodes/SoCoordinate3.h>
105 // For rendering distance during animation:       105 // For rendering distance during animation:
106 #include <Inventor/nodes/SoText2.h>               106 #include <Inventor/nodes/SoText2.h>
107 #include <Inventor/nodes/SoFont.h>                107 #include <Inventor/nodes/SoFont.h>
108 #include <Inventor/nodes/SoPointSet.h>            108 #include <Inventor/nodes/SoPointSet.h>
109 #include <Inventor/nodes/SoDrawStyle.h>           109 #include <Inventor/nodes/SoDrawStyle.h>
110 #include <Inventor/nodes/SoBaseColor.h>           110 #include <Inventor/nodes/SoBaseColor.h>
111                                                   111 
112 // For searching for nodes within kits:           112 // For searching for nodes within kits:
113 #include <Inventor/nodekits/SoBaseKit.h>          113 #include <Inventor/nodekits/SoBaseKit.h>
114                                                   114 
115 // FWJ                                            115 // FWJ
116 #include <Inventor/SbVec3f.h>                     116 #include <Inventor/SbVec3f.h>
117                                                   117 
118 G4OpenInventorXtExaminerViewer* G4OpenInventor    118 G4OpenInventorXtExaminerViewer* G4OpenInventorXtExaminerViewer::viewer = 0;
119                                                   119 
120 static const char* thisClassName = "G4OpenInve    120 static const char* thisClassName = "G4OpenInventorXtExaminerViewer";
121                                                   121  
122 #define MIN_SPEED  2.1        // Lower number     122 #define MIN_SPEED  2.1        // Lower number means faster
123 #define START_STEP 0.3                            123 #define START_STEP 0.3
124 #define SPEED_INDICATOR_STEP 0.045                124 #define SPEED_INDICATOR_STEP 0.045
125 #define MAX_SPEED_INDICATOR  0.81                 125 #define MAX_SPEED_INDICATOR  0.81
126 // Number of steps 90 degree rotation around a    126 // Number of steps 90 degree rotation around an element is split into
127 #define ROT_CNT 6                                 127 #define ROT_CNT 6
128                                                   128 
129 // Public constructor                             129 // Public constructor
130 G4OpenInventorXtExaminerViewer::G4OpenInventor    130 G4OpenInventorXtExaminerViewer::G4OpenInventorXtExaminerViewer(Widget parent,
131                 const char *name, SbBool embed    131                 const char *name, SbBool embed,
132     SoXtFullViewer::BuildFlag flag, SoXtViewer    132     SoXtFullViewer::BuildFlag flag, SoXtViewer::Type type) :
133    SoXtExaminerViewer(parent, name, embed, fla    133    SoXtExaminerViewer(parent, name, embed, flag, type, FALSE)
134 {                                                 134 {
135 // Tell GLWidget not to build just yet            135 // Tell GLWidget not to build just yet
136    this->constructor(TRUE);                       136    this->constructor(TRUE);
137 }                                                 137 }
138                                                   138 
139 // Protected constructor for classes deriving     139 // Protected constructor for classes deriving from this viewer.
140 G4OpenInventorXtExaminerViewer::G4OpenInventor    140 G4OpenInventorXtExaminerViewer::G4OpenInventorXtExaminerViewer(Widget parent,
141                 const char *name, SbBool embed    141                 const char *name, SbBool embed,
142                 SoXtFullViewer::BuildFlag flag    142                 SoXtFullViewer::BuildFlag flag, SoXtViewer::Type type,
143                 SbBool build) :                   143                 SbBool build) :
144    SoXtExaminerViewer(parent, name, embed, fla    144    SoXtExaminerViewer(parent, name, embed, flag, type, FALSE)
145 {                                                 145 {
146    this->constructor(build);                      146    this->constructor(build);
147 }                                                 147 }
148                                                   148 
149 // Called by all constructors to set up widget    149 // Called by all constructors to set up widgets and initialize member fields.
150 void G4OpenInventorXtExaminerViewer::construct    150 void G4OpenInventorXtExaminerViewer::constructor(const SbBool build)
151 {                                                 151 {
152    setClassName(thisClassName);                   152    setClassName(thisClassName);
153                                                   153 
154    hookBeamOn = new HookEventProcState(this);     154    hookBeamOn = new HookEventProcState(this);
155    this->newEvents = false;                       155    this->newEvents = false;
156                                                   156 
157    fileName = ".bookmarkFile"; // Default view    157    fileName = ".bookmarkFile"; // Default viewpoint file name
158    viewPtIdx = -1; // index of the most recent    158    viewPtIdx = -1; // index of the most recent viewpoint in viewPtList vector
159    animateSensor = new SoTimerSensor(             159    animateSensor = new SoTimerSensor(
160                        G4OpenInventorXtExamine    160                        G4OpenInventorXtExaminerViewer::animateSensorCB, this);
161    animateSensorRotation = new SoTimerSensor(     161    animateSensorRotation = new SoTimerSensor(
162                G4OpenInventorXtExaminerViewer:    162                G4OpenInventorXtExaminerViewer::animateSensorRotationCB, this);
163    animateBtwPtsPeriod = MIN_SPEED;               163    animateBtwPtsPeriod = MIN_SPEED;
164    currentState = GENERAL;                        164    currentState = GENERAL;
165    myCam = new SoPerspectiveCamera;               165    myCam = new SoPerspectiveCamera;
166    MAX_VP_IDX = 3;                                166    MAX_VP_IDX = 3;
167    MAX_VP_NAME = 35; // Max length of a viewpo    167    MAX_VP_NAME = 35; // Max length of a viewpoint name, padded with spaces
168    rotCnt = ROT_CNT; // For 90 degree rotation    168    rotCnt = ROT_CNT; // For 90 degree rotations
169    curViewPtName = new char[MAX_VP_NAME + 1];     169    curViewPtName = new char[MAX_VP_NAME + 1];
170    left_right = up_down = 0; // For movements     170    left_right = up_down = 0; // For movements around the beam during animation
171    speedStep = START_STEP; // For smoother ani    171    speedStep = START_STEP; // For smoother animation speed increase/decrease
172    rotUpVec = false; // Used during scene elem    172    rotUpVec = false; // Used during scene element rotations
173    step = 1;  //By default                        173    step = 1;  //By default
174    // Used for moving along the beam with the     174    // Used for moving along the beam with the
175    // mouse instead of rotating the view          175    // mouse instead of rotating the view
176    lshiftdown = rshiftdown = false;               176    lshiftdown = rshiftdown = false;
177    // Used for rotating the view with the came    177    // Used for rotating the view with the camera
178    // staying in place                            178    // staying in place
179    lctrldown = rctrldown = false;                 179    lctrldown = rctrldown = false;
180    // Used to send abbreviated output to the c    180    // Used to send abbreviated output to the console when
181    abbrOutputFlag = false;                        181    abbrOutputFlag = false;
182    pickRefPathFlag = false;                       182    pickRefPathFlag = false;
183    prevColorField = NULL;                         183    prevColorField = NULL;
184    warningFlag = false; // We come from the wa    184    warningFlag = false; // We come from the warning dialog
185    viewer = this;                                 185    viewer = this;
186    openFileDialog = newFileDialog = listsDialo    186    openFileDialog = newFileDialog = listsDialog = (Widget) NULL;
187    loadRefCoordsDialog = saveRefCoordsDialog =    187    loadRefCoordsDialog = saveRefCoordsDialog = NULL;
188    loadSceneGraphDialog = saveSceneGraphDialog    188    loadSceneGraphDialog = saveSceneGraphDialog = NULL;
189    myElementList = NULL;                          189    myElementList = NULL;
190    // FWJ default path look-ahead                 190    // FWJ default path look-ahead
191    pathLookahead = 5;                             191    pathLookahead = 5;
192                                                   192 
193    newSceneGraph = NULL;                          193    newSceneGraph = NULL;
194    zcoordSetFlag = false;                         194    zcoordSetFlag = false;
195                                                   195 
196    //////////////////////////SUPERIMPOSED SCEN    196    //////////////////////////SUPERIMPOSED SCENE//////////////////////////
197    searcher = NULL;                               197    searcher = NULL;
198    // Used in animation; progressively scaled     198    // Used in animation; progressively scaled for gradual speed change
199    maxSpeed = 0.0f;                               199    maxSpeed = 0.0f;
200                                                   200 
201    static const char * superimposed[] = {         201    static const char * superimposed[] = {
202       "#Inventor V2.1 ascii", "",                 202       "#Inventor V2.1 ascii", "",
203       "Separator ",                               203       "Separator ",
204       "{",                                        204       "{",
205       " MaterialBinding ",                        205       " MaterialBinding ",
206       " {",                                       206       " {",
207       "     value OVERALL",                       207       "     value OVERALL",
208       " }",                                       208       " }",
209       "   OrthographicCamera ",                   209       "   OrthographicCamera ",
210       " {",                                       210       " {",
211       "     height 1",                            211       "     height 1",
212       "   nearDistance 0",                        212       "   nearDistance 0",
213       "     farDistance 1",                       213       "     farDistance 1",
214       " }",                                       214       " }",
215       "   DEF soxt->callback Callback { }",       215       "   DEF soxt->callback Callback { }",
216       "   Separator ",                            216       "   Separator ",
217       " {",                                       217       " {",
218       "     DEF soxt->translation Translation     218       "     DEF soxt->translation Translation ",
219       "   {",                                     219       "   {",
220       "         translation 0 0 0",               220       "         translation 0 0 0",
221       "     }",                                   221       "     }",
222       "     DEF soxt->scale Scale ",              222       "     DEF soxt->scale Scale ",
223       "   {",                                     223       "   {",
224       "         scaleFactor 1 1 1",               224       "         scaleFactor 1 1 1",
225       "     }",                                   225       "     }",
226       "   DEF soxt->geometry Coordinate3 ",       226       "   DEF soxt->geometry Coordinate3 ",
227       "   {",                                     227       "   {",
228       "       point ",                            228       "       point ",
229       "     [",                                   229       "     [",
230       "         -0.81 -0.04 0,  -0.81 0   0,",    230       "         -0.81 -0.04 0,  -0.81 0   0,",
231       "           -0.81 0.04  0,  0     -0.04     231       "           -0.81 0.04  0,  0     -0.04   0,",
232       "           0       0     0,  0       0.    232       "           0       0     0,  0       0.04  0,",
233       "           0.81  -0.04   0,  0.81    0     233       "           0.81  -0.04   0,  0.81    0       0,",
234       "           0.81    0.04  0,",              234       "           0.81    0.04  0,",
235       "           0       0.02  0,", // idx 9     235       "           0       0.02  0,", // idx 9
236       "           0.81    0.02  0,  0.81  -0.0    236       "           0.81    0.02  0,  0.81  -0.02   0,",
237       "           0     -0.02   0,",              237       "           0     -0.02   0,",
238       "           0       0.01  0,", // idx 13    238       "           0       0.01  0,", // idx 13
239       "           0.4     0.01  0,  0.4   -0.0    239       "           0.4     0.01  0,  0.4   -0.01   0,",
240       "           0     -0.01   0",               240       "           0     -0.01   0",
241       "     ]",                                   241       "     ]",
242       "   }",                                     242       "   }",
243       // current speed indicator (outline)        243       // current speed indicator (outline)
244       "     DEF soxt->animSpeedOutlineSwitch S    244       "     DEF soxt->animSpeedOutlineSwitch Switch ",
245       "   {",                                     245       "   {",
246       "         whichChild -3",                   246       "         whichChild -3",
247       "         Material ",                       247       "         Material ",
248       "     {",                                   248       "     {",
249       "            emissiveColor 0 0 0",          249       "            emissiveColor 0 0 0",
250       "       }",                                 250       "       }",
251       "         IndexedFaceSet ",                 251       "         IndexedFaceSet ",
252       "     {",                                   252       "     {",
253       "           coordIndex ",                   253       "           coordIndex ",
254       "       [",                                 254       "       [",
255       "               12, 11, 10, 9, -1",         255       "               12, 11, 10, 9, -1",
256       "             ]",                           256       "             ]",
257       "         }",                               257       "         }",
258       "      }",                                  258       "      }",
259       // the coordinate system                    259       // the coordinate system
260       "     DEF soxt->axisSwitch Switch ",        260       "     DEF soxt->axisSwitch Switch ",
261       "   {",                                     261       "   {",
262       "         whichChild -3",                   262       "         whichChild -3",
263       "         BaseColor ",                      263       "         BaseColor ",
264       "     {",                                   264       "     {",
265       "             rgb 1 1 1",                   265       "             rgb 1 1 1",
266       "         }",                               266       "         }",
267       "         IndexedLineSet ",                 267       "         IndexedLineSet ",
268       "     {",                                   268       "     {",
269       "           coordIndex ",                   269       "           coordIndex ",
270       "       [",                                 270       "       [",
271       "               0, 2, -1,",                 271       "               0, 2, -1,",
272       "               3, 5, -1,",                 272       "               3, 5, -1,",
273       "               6, 8, -1,",                 273       "               6, 8, -1,",
274       "               1, 7, -1",                  274       "               1, 7, -1",
275       "             ]",                           275       "             ]",
276       "         }",                               276       "         }",
277       "     }",                                   277       "     }",
278       // current speed indicator                  278       // current speed indicator
279       "     DEF soxt->animSpeedSwitch Switch "    279       "     DEF soxt->animSpeedSwitch Switch ",
280       "   {",                                     280       "   {",
281       "         whichChild -3",                   281       "         whichChild -3",
282       "         Material ",                       282       "         Material ",
283       "     {",                                   283       "     {",
284       "           emissiveColor 0 1 0",           284       "           emissiveColor 0 1 0",
285       "         }",                               285       "         }",
286       "     IndexedFaceSet ",                     286       "     IndexedFaceSet ",
287       "     {",                                   287       "     {",
288       "         coordIndex ",                     288       "         coordIndex ",
289       "       [",                                 289       "       [",
290       "               16, 15, 14, 13, -1",        290       "               16, 15, 14, 13, -1",
291       "           ]",                             291       "           ]",
292       "         }",                               292       "         }",
293       "     }",                                   293       "     }",
294       "   }",                                     294       "   }",
295       // For displaying either z position (dur    295       // For displaying either z position (during animation) or current viewpoint name
296       " DEF soxt->curInfoSwitch Switch ",         296       " DEF soxt->curInfoSwitch Switch ",
297       " {",                                       297       " {",
298       "   whichChild -3",                         298       "   whichChild -3",
299       "     DEF soxt->curInfoTrans Translation    299       "     DEF soxt->curInfoTrans Translation ",
300       "   {",                                     300       "   {",
301       "         translation 10 20 30    ",        301       "         translation 10 20 30    ",
302       "   }",                                     302       "   }",
303       "     DEF soxt->curInfoFont Font ",         303       "     DEF soxt->curInfoFont Font ",
304       "   {",                                     304       "   {",
305       "         name defaultFont:Bold",           305       "         name defaultFont:Bold",
306       "         size 16",                         306       "         size 16",
307       "     }",                                   307       "     }",
308       "   DEF soxt->curInfoText Text2 ",          308       "   DEF soxt->curInfoText Text2 ",
309       "   {",                                     309       "   {",
310       "         string Hello",                    310       "         string Hello",
311       "     }",                                   311       "     }",
312       " }",                                       312       " }",
313       // Need to use different fields for mous    313       // Need to use different fields for mouseover
314       // because newlines are ignored when the    314       // because newlines are ignored when the scene is rendered
315       " Separator ",                              315       " Separator ",
316       " {",                                       316       " {",
317       "     DEF soxt->mouseOverTransLogName Tr    317       "     DEF soxt->mouseOverTransLogName Translation ",
318       "   {",                                     318       "   {",
319       "         translation 0 0 0    ",           319       "         translation 0 0 0    ",
320       "   }",                                     320       "   }",
321       "     DEF soxt->mouseOverFontLogName Fon    321       "     DEF soxt->mouseOverFontLogName Font ",
322       "   {",                                     322       "   {",
323       "         name defaultFont:Bold",           323       "         name defaultFont:Bold",
324       "         size 16",                         324       "         size 16",
325       "     }",                                   325       "     }",
326       "   DEF soxt->mouseOverTextLogName Text2    326       "   DEF soxt->mouseOverTextLogName Text2 { } ",
327       " }",                                       327       " }",
328       " Separator ",                              328       " Separator ",
329       " {",                                       329       " {",
330       "     DEF soxt->mouseOverTransSolid Tran    330       "     DEF soxt->mouseOverTransSolid Translation ",
331       "   {",                                     331       "   {",
332       "         translation 0 0 0    ",           332       "         translation 0 0 0    ",
333       "   }",                                     333       "   }",
334       "     DEF soxt->mouseOverFontSolid Font     334       "     DEF soxt->mouseOverFontSolid Font ",
335       "   {",                                     335       "   {",
336       "         name defaultFont:Bold",           336       "         name defaultFont:Bold",
337       "         size 16",                         337       "         size 16",
338       "     }",                                   338       "     }",
339       "   DEF soxt->mouseOverTextSolid Text2 {    339       "   DEF soxt->mouseOverTextSolid Text2 { } ",
340       " }",                                       340       " }",
341       " Separator ",                              341       " Separator ",
342       " {",                                       342       " {",
343       "     DEF soxt->mouseOverTransMaterial T    343       "     DEF soxt->mouseOverTransMaterial Translation ",
344       "   {",                                     344       "   {",
345       "         translation 0 0 0    ",           345       "         translation 0 0 0    ",
346       "   }",                                     346       "   }",
347       "     DEF soxt->mouseOverFontMaterial Fo    347       "     DEF soxt->mouseOverFontMaterial Font ",
348       "   {",                                     348       "   {",
349       "         name defaultFont:Bold",           349       "         name defaultFont:Bold",
350       "         size 16",                         350       "         size 16",
351       "     }",                                   351       "     }",
352       "   DEF soxt->mouseOverTextMaterial Text    352       "   DEF soxt->mouseOverTextMaterial Text2 { } ",
353       " }",                                       353       " }",
354       " Separator ",                              354       " Separator ",
355       " {",                                       355       " {",
356       "     DEF soxt->mouseOverTransZPos Trans    356       "     DEF soxt->mouseOverTransZPos Translation ",
357       "   {",                                     357       "   {",
358       "         translation 0 0 0    ",           358       "         translation 0 0 0    ",
359       "   }",                                     359       "   }",
360       "     DEF soxt->mouseOverFontZPos Font "    360       "     DEF soxt->mouseOverFontZPos Font ",
361       "   {",                                     361       "   {",
362       "         name defaultFont:Bold",           362       "         name defaultFont:Bold",
363       "         size 16",                         363       "         size 16",
364       "     }",                                   364       "     }",
365       "   DEF soxt->mouseOverTextZPos Text2 {     365       "   DEF soxt->mouseOverTextZPos Text2 { } ",
366       " }",                                       366       " }",
367       "}", NULL                                   367       "}", NULL
368    };                                             368    };
369                                                   369 
370    int i, bufsize;                                370    int i, bufsize;
371    for (i = bufsize = 0; superimposed[i]; i++)    371    for (i = bufsize = 0; superimposed[i]; i++)
372       bufsize += strlen(superimposed[i]) + 1;     372       bufsize += strlen(superimposed[i]) + 1;
373    char * buf = new char[bufsize + 1];            373    char * buf = new char[bufsize + 1];
374    for (i = bufsize = 0; superimposed[i]; i++)    374    for (i = bufsize = 0; superimposed[i]; i++) {
375       strcpy(buf + bufsize, superimposed[i]);     375       strcpy(buf + bufsize, superimposed[i]);
376       bufsize += strlen(superimposed[i]);         376       bufsize += strlen(superimposed[i]);
377       buf[bufsize] = '\n';                        377       buf[bufsize] = '\n';
378       bufsize++;                                  378       bufsize++;
379    }                                              379    }
380    SoInput * input = new SoInput;                 380    SoInput * input = new SoInput;
381    input->setBuffer(buf, bufsize);                381    input->setBuffer(buf, bufsize);
382    SbBool ok = SoDB::read(input, this->superim    382    SbBool ok = SoDB::read(input, this->superimposition);
383    (void)ok;   // FWJ added to avoid compiler     383    (void)ok;   // FWJ added to avoid compiler warning
384    assert(ok);                                    384    assert(ok);
385    delete input;                                  385    delete input;
386    delete[] buf;                                  386    delete[] buf;
387    this->superimposition->ref();                  387    this->superimposition->ref();
388                                                   388 
389    this->sscale = (SoScale *) this->getSuperim    389    this->sscale = (SoScale *) this->getSuperimpositionNode(
390                                  this->superim    390                                  this->superimposition, "soxt->scale");
391    this->stranslation = (SoTranslation *) this    391    this->stranslation = (SoTranslation *) this->getSuperimpositionNode(
392                                  this->superim    392                                  this->superimposition, "soxt->translation");
393    this->sgeometry = (SoCoordinate3 *) this->g    393    this->sgeometry = (SoCoordinate3 *) this->getSuperimpositionNode(
394                                  this->superim    394                                  this->superimposition, "soxt->geometry");
395    this->axisSwitch = (SoSwitch *) this->getSu    395    this->axisSwitch = (SoSwitch *) this->getSuperimpositionNode(
396                                  this->superim    396                                  this->superimposition, "soxt->axisSwitch");
397    this->animSpeedOutlineSwitch = (SoSwitch *)    397    this->animSpeedOutlineSwitch = (SoSwitch *) this->getSuperimpositionNode(
398                        this->superimposition,     398                        this->superimposition, "soxt->animSpeedOutlineSwitch");
399    this->animSpeedSwitch = (SoSwitch *) this->    399    this->animSpeedSwitch = (SoSwitch *) this->getSuperimpositionNode(
400                        this->superimposition,     400                        this->superimposition, "soxt->animSpeedSwitch");
401    this->curInfoSwitch = (SoSwitch *) this->ge    401    this->curInfoSwitch = (SoSwitch *) this->getSuperimpositionNode(
402                              this->superimposi    402                              this->superimposition, "soxt->curInfoSwitch");
403    this->curInfoTrans = (SoTranslation *) this    403    this->curInfoTrans = (SoTranslation *) this->getSuperimpositionNode(
404                              this->superimposi    404                              this->superimposition, "soxt->curInfoTrans");
405    this->curInfoFont = (SoFont *) this->getSup    405    this->curInfoFont = (SoFont *) this->getSuperimpositionNode(
406                              this->superimposi    406                              this->superimposition, "soxt->curInfoFont");
407    this->curInfoText = (SoText2 *) this->getSu    407    this->curInfoText = (SoText2 *) this->getSuperimpositionNode(
408                              this->superimposi    408                              this->superimposition, "soxt->curInfoText");
409    this->mouseOverTransLogName = (SoTranslatio    409    this->mouseOverTransLogName = (SoTranslation*)this->getSuperimpositionNode(
410                    this->superimposition, "sox    410                    this->superimposition, "soxt->mouseOverTransLogName");
411    this->mouseOverFontLogName = (SoFont *) thi    411    this->mouseOverFontLogName = (SoFont *) this->getSuperimpositionNode(
412                    this->superimposition, "sox    412                    this->superimposition, "soxt->mouseOverFontLogName");
413    this->mouseOverTextLogName = (SoText2 *) th    413    this->mouseOverTextLogName = (SoText2 *) this->getSuperimpositionNode(
414                    this->superimposition, "sox    414                    this->superimposition, "soxt->mouseOverTextLogName");
415    this->mouseOverTransSolid = (SoTranslation     415    this->mouseOverTransSolid = (SoTranslation *) this->getSuperimpositionNode(
416                    this->superimposition, "sox    416                    this->superimposition, "soxt->mouseOverTransSolid");
417    this->mouseOverFontSolid = (SoFont *) this-    417    this->mouseOverFontSolid = (SoFont *) this->getSuperimpositionNode(
418                    this->superimposition, "sox    418                    this->superimposition, "soxt->mouseOverFontSolid");
419    this->mouseOverTextSolid = (SoText2 *) this    419    this->mouseOverTextSolid = (SoText2 *) this->getSuperimpositionNode(
420                    this->superimposition, "sox    420                    this->superimposition, "soxt->mouseOverTextSolid");
421    this->mouseOverTransMaterial = (SoTranslati    421    this->mouseOverTransMaterial = (SoTranslation*)this->getSuperimpositionNode(
422                    this->superimposition, "sox    422                    this->superimposition, "soxt->mouseOverTransMaterial");
423    this->mouseOverFontMaterial = (SoFont *) th    423    this->mouseOverFontMaterial = (SoFont *) this->getSuperimpositionNode(
424                    this->superimposition, "sox    424                    this->superimposition, "soxt->mouseOverFontMaterial");
425    this->mouseOverTextMaterial = (SoText2 *) t    425    this->mouseOverTextMaterial = (SoText2 *) this->getSuperimpositionNode(
426                    this->superimposition, "sox    426                    this->superimposition, "soxt->mouseOverTextMaterial");
427    this->mouseOverTransZPos = (SoTranslation *    427    this->mouseOverTransZPos = (SoTranslation *) this->getSuperimpositionNode(
428                    this->superimposition, "sox    428                    this->superimposition, "soxt->mouseOverTransZPos");
429    this->mouseOverFontZPos = (SoFont *) this->    429    this->mouseOverFontZPos = (SoFont *) this->getSuperimpositionNode(
430                    this->superimposition, "sox    430                    this->superimposition, "soxt->mouseOverFontZPos");
431    this->mouseOverTextZPos = (SoText2 *) this-    431    this->mouseOverTextZPos = (SoText2 *) this->getSuperimpositionNode(
432                    this->superimposition, "sox    432                    this->superimposition, "soxt->mouseOverTextZPos");
433                                                   433 
434    SoCallback * cb = (SoCallback *) this->getS    434    SoCallback * cb = (SoCallback *) this->getSuperimpositionNode(
435                    this->superimposition, "sox    435                    this->superimposition, "soxt->callback");
436    cb->setCallback(superimpositionCB, this);      436    cb->setCallback(superimpositionCB, this);
437                                                   437 
438    this->addSuperimposition(this->superimposit    438    this->addSuperimposition(this->superimposition);
439    this->setSuperimpositionEnabled(this->super    439    this->setSuperimpositionEnabled(this->superimposition, FALSE);
440    axisSwitch->whichChild.setValue(SO_SWITCH_N    440    axisSwitch->whichChild.setValue(SO_SWITCH_NONE);
441    animSpeedOutlineSwitch->whichChild.setValue    441    animSpeedOutlineSwitch->whichChild.setValue(SO_SWITCH_NONE);
442    animSpeedSwitch->whichChild.setValue(SO_SWI    442    animSpeedSwitch->whichChild.setValue(SO_SWITCH_NONE);
443                                                   443 
444    /////////////////////\SUPERIMPOSED SCENE///    444    /////////////////////\SUPERIMPOSED SCENE///////////////////////////////////
445                                                   445 
446    // Build everything else like the parent vi    446    // Build everything else like the parent viewer does
447    if (build) {                                   447    if (build) {
448       Widget w = buildWidget(getParentWidget()    448       Widget w = buildWidget(getParentWidget());
449       setBaseWidget(w);                           449       setBaseWidget(w);
450                                                   450 
451       // Make this window a little bigger beca    451       // Make this window a little bigger because of the extra buttons
452       // FWJ but it is already set to 600x600     452       // FWJ but it is already set to 600x600 by vis/open
453       //      setSize(SbVec2s(500, 550));         453       //      setSize(SbVec2s(500, 550));
454    }                                              454    }
455                                                   455 
456 }                                                 456 }
457                                                   457 
458                                                   458 
459 // Static function that returns the pointer to    459 // Static function that returns the pointer to G4OpenInventorXtExaminerViewer
460 // FWJ DISABLED                                   460 // FWJ DISABLED
461 //G4OpenInventorXtExaminerViewer *G4OpenInvent    461 //G4OpenInventorXtExaminerViewer *G4OpenInventorXtExaminerViewer::getObject()
462 //{                                               462 //{
463 //   if (!viewer)                                 463 //   if (!viewer)
464 //      new G4OpenInventorXtExaminerViewer();     464 //      new G4OpenInventorXtExaminerViewer();
465 //   return viewer;                               465 //   return viewer;
466 //}                                               466 //}
467                                                   467 
468                                                   468 
469 // This method locates a named node in the sup    469 // This method locates a named node in the superimposed or original scene.
470 SoNode *                                          470 SoNode *
471 G4OpenInventorXtExaminerViewer::getSuperimposi    471 G4OpenInventorXtExaminerViewer::getSuperimpositionNode(SoNode *root,
472                                                   472                                                      const char * name)
473 {                                                 473 {
474    if (!this->searcher)                           474    if (!this->searcher)
475       this->searcher = new SoSearchAction;        475       this->searcher = new SoSearchAction;
476    searcher->reset();                             476    searcher->reset();
477    searcher->setName(SbName(name));               477    searcher->setName(SbName(name));
478    searcher->setInterest(SoSearchAction::FIRST    478    searcher->setInterest(SoSearchAction::FIRST);
479    searcher->setSearchingAll(TRUE);               479    searcher->setSearchingAll(TRUE);
480    searcher->apply(root);                         480    searcher->apply(root);
481    assert(searcher->getPath());                   481    assert(searcher->getPath());
482    return searcher->getPath()->getTail();         482    return searcher->getPath()->getTail();
483 }                                                 483 }
484                                                   484 
485                                                   485 
486 void G4OpenInventorXtExaminerViewer::superimpo    486 void G4OpenInventorXtExaminerViewer::superimpositionCB(void * closure,
487                                                   487                                                      SoAction * action)
488 {                                                 488 {
489    if (closure)                                   489    if (closure)
490       ((G4OpenInventorXtExaminerViewer*)closur    490       ((G4OpenInventorXtExaminerViewer*)closure)->superimpositionEvent(action);
491 }                                                 491 }
492                                                   492 
493                                                   493 
494 // Renders and positions speed indicator and l    494 // Renders and positions speed indicator and longitudinal
495 // distance/viewpoint name on the drawing canv    495 // distance/viewpoint name on the drawing canvas
496 void G4OpenInventorXtExaminerViewer::superimpo    496 void G4OpenInventorXtExaminerViewer::superimpositionEvent(SoAction * action)
497 {                                                 497 {
498                                                   498 
499    if (!action->isOfType(SoGLRenderAction::get    499    if (!action->isOfType(SoGLRenderAction::getClassTypeId()))
500       return;                                     500       return;
501    SbViewportRegion vpRegion =                    501    SbViewportRegion vpRegion =
502       ((SoGLRenderAction *) action)->getViewpo    502       ((SoGLRenderAction *) action)->getViewportRegion();
503    SbVec2s viewportSize = vpRegion.getViewport    503    SbVec2s viewportSize = vpRegion.getViewportSizePixels();
504                                                   504 
505    float aspect = float(viewportSize[0]) / flo    505    float aspect = float(viewportSize[0]) / float(viewportSize[1]);
506    float factorx = 1.0f / float(viewportSize[1    506    float factorx = 1.0f / float(viewportSize[1]) * 220.0f;
507    float factory = factorx;                       507    float factory = factorx;
508                                                   508 
509    if (aspect > 1.0f) {                           509    if (aspect > 1.0f) {
510       this->stranslation->translation.setValue    510       this->stranslation->translation.setValue(SbVec3f(0.0f, -0.4f, 0.0f));
511    } else {                                       511    } else {
512       this->stranslation->translation.setValue    512       this->stranslation->translation.setValue(
513                        SbVec3f(0.0f, -0.4f / a    513                        SbVec3f(0.0f, -0.4f / aspect, 0.0f));
514       factorx /= aspect;                          514       factorx /= aspect;
515       factory /= aspect;                          515       factory /= aspect;
516    }                                              516    }
517    if (viewportSize[0] > 500)                     517    if (viewportSize[0] > 500)
518       factorx *= 500.0f / 400.0f;                 518       factorx *= 500.0f / 400.0f;
519    else                                           519    else
520       factorx *= float(viewportSize[0]) / 400.    520       factorx *= float(viewportSize[0]) / 400.0f;
521    this->sscale->scaleFactor.setValue(SbVec3f(    521    this->sscale->scaleFactor.setValue(SbVec3f(factorx, factory, 1.0f));
522                                                   522 
523    float xInfo, yInfo, xMouseLogName, yMouseLo    523    float xInfo, yInfo, xMouseLogName, yMouseLogName, xMouseSolid, yMouseSolid,
524       xMouseMaterial, yMouseMaterial, xMouseZP    524       xMouseMaterial, yMouseMaterial, xMouseZPos, yMouseZPos;
525    xInfo = -.45;                                  525    xInfo = -.45;
526    yInfo = .45;                                   526    yInfo = .45;
527    xMouseLogName = 0.0;                           527    xMouseLogName = 0.0;
528    yMouseLogName = -.75;                          528    yMouseLogName = -.75;
529    xMouseSolid = 0.0;                             529    xMouseSolid = 0.0;
530    yMouseSolid = -.78;                            530    yMouseSolid = -.78;
531    xMouseMaterial = 0.0;                          531    xMouseMaterial = 0.0;
532    yMouseMaterial = -.81;                         532    yMouseMaterial = -.81;
533    xMouseZPos = 0.0;                              533    xMouseZPos = 0.0;
534    yMouseZPos = -.84;                             534    yMouseZPos = -.84;
535                                                   535 
536    if (aspect > 1.0f) {                           536    if (aspect > 1.0f) {
537       xInfo *= aspect;                            537       xInfo *= aspect;
538       xMouseSolid *= aspect;                      538       xMouseSolid *= aspect;
539       xMouseMaterial *= aspect;                   539       xMouseMaterial *= aspect;
540       this->curInfoTrans->translation.setValue    540       this->curInfoTrans->translation.setValue(SbVec3f(xInfo, yInfo, 0.0));
541       this->mouseOverTransLogName->translation    541       this->mouseOverTransLogName->translation.setValue(
542                         SbVec3f(xMouseLogName,    542                         SbVec3f(xMouseLogName, yMouseLogName, 0.0));
543       this->mouseOverTransSolid->translation.s    543       this->mouseOverTransSolid->translation.setValue(
544                         SbVec3f(xMouseSolid, y    544                         SbVec3f(xMouseSolid, yMouseSolid, 0.0));
545       this->mouseOverTransMaterial->translatio    545       this->mouseOverTransMaterial->translation.setValue(
546                         SbVec3f(xMouseMaterial    546                         SbVec3f(xMouseMaterial, yMouseMaterial, 0.0));
547       this->mouseOverTransZPos->translation.se    547       this->mouseOverTransZPos->translation.setValue(
548                         SbVec3f(xMouseZPos, yM    548                         SbVec3f(xMouseZPos, yMouseZPos, 0.0));
549    } else {                                       549    } else {
550       yInfo /= aspect;                            550       yInfo /= aspect;
551       yMouseSolid /= aspect;                      551       yMouseSolid /= aspect;
552       yMouseMaterial /= aspect;                   552       yMouseMaterial /= aspect;
553       this->curInfoTrans->translation.setValue    553       this->curInfoTrans->translation.setValue(SbVec3f(xInfo, yInfo, 0.0));
554       this->mouseOverTransLogName->translation    554       this->mouseOverTransLogName->translation.setValue(
555                         SbVec3f(xMouseLogName,    555                         SbVec3f(xMouseLogName, yMouseLogName, 0.0));
556       this->mouseOverTransSolid->translation.s    556       this->mouseOverTransSolid->translation.setValue(
557                         SbVec3f(xMouseSolid, y    557                         SbVec3f(xMouseSolid, yMouseSolid, 0.0));
558       this->mouseOverTransMaterial->translatio    558       this->mouseOverTransMaterial->translation.setValue(
559                         SbVec3f(xMouseMaterial    559                         SbVec3f(xMouseMaterial, yMouseMaterial, 0.0));
560       this->mouseOverTransZPos->translation.se    560       this->mouseOverTransZPos->translation.setValue(
561                         SbVec3f(xMouseZPos, yM    561                         SbVec3f(xMouseZPos, yMouseZPos, 0.0));
562    }                                              562    }
563                                                   563 
564    if (currentState == VIEWPOINT) { // Display    564    if (currentState == VIEWPOINT) { // Displaying viewpoint name
565       this->curInfoFont->size.setValue(15);       565       this->curInfoFont->size.setValue(15);
566       this->curInfoFont->name.setValue("defaul    566       this->curInfoFont->name.setValue("defaultFont:Italic");
567       this->curInfoText->string.setValue(SbStr    567       this->curInfoText->string.setValue(SbString(curViewPtName));
568    }                                              568    }
569    else if(currentState == GENERAL) { // Displ    569    else if(currentState == GENERAL) { // Displaying longitudinal distance
570       this->curInfoFont->size.setValue(16);       570       this->curInfoFont->size.setValue(16);
571       this->curInfoFont->name.setValue("defaul    571       this->curInfoFont->name.setValue("defaultFont:Bold");
572       this->curInfoText->string.setValue(SbStr    572       this->curInfoText->string.setValue(SbString(""));
573    }                                              573    }
574    else {                                         574    else {
575       if (refParticleIdx < (int) refParticleTr    575       if (refParticleIdx < (int) refParticleTrajectory.size() - 1) {
576          this->curInfoFont->size.setValue(16);    576          this->curInfoFont->size.setValue(16);
577          this->curInfoFont->name.setValue("def    577          this->curInfoFont->name.setValue("defaultFont:Bold");
578          char zPos[20];                           578          char zPos[20];
579          snprintf(zPos, sizeof zPos, "%7.2f [m    579          snprintf(zPos, sizeof zPos, "%7.2f [m]", refZPositions[refParticleIdx] / 1000);
580          this->curInfoText->string.setValue(Sb    580          this->curInfoText->string.setValue(SbString(zPos));
581       }                                           581       }
582    }                                              582    }
583 }                                                 583 }
584                                                   584 
585                                                   585 
586 G4OpenInventorXtExaminerViewer::~G4OpenInvento    586 G4OpenInventorXtExaminerViewer::~G4OpenInventorXtExaminerViewer()
587 {                                                 587 {
588    if (superimposition != NULL) {                 588    if (superimposition != NULL) {
589       removeSuperimposition(superimposition);     589       removeSuperimposition(superimposition);
590       superimposition->unref();                   590       superimposition->unref();
591       superimposition = NULL;                     591       superimposition = NULL;
592    }                                              592    }
593    if (animateSensor->isScheduled())              593    if (animateSensor->isScheduled())
594       animateSensor->unschedule();                594       animateSensor->unschedule();
595    delete animateSensor;                          595    delete animateSensor;
596    delete sceneChangeSensor;                      596    delete sceneChangeSensor;
597                                                   597 
598    delete[] curViewPtName;                        598    delete[] curViewPtName;
599    delete searcher;                               599    delete searcher;
600                                                   600 
601    viewer = 0;                                    601    viewer = 0;
602 }                                                 602 }
603                                                   603 
604                                                   604 
605 // Adds a menu bar and a few menu items to the    605 // Adds a menu bar and a few menu items to the viewer.
606 Widget G4OpenInventorXtExaminerViewer::buildWi    606 Widget G4OpenInventorXtExaminerViewer::buildWidget(Widget parent)
607 {                                                 607 {
608    Widget shell;                                  608    Widget shell;
609    Atom WM_DELETE_WINDOW;                         609    Atom WM_DELETE_WINDOW;
610                                                   610 
611    if (!parent)                                   611    if (!parent)
612       SoDebugError::post("G4OpenInventorXtExam    612       SoDebugError::post("G4OpenInventorXtExaminerViewer::buildWidget", "Error: Parent is null.");
613                                                   613 
614    Arg args[10];                                  614    Arg args[10];
615    XtSetArg(args[0], XmNtopAttachment, XmATTAC    615    XtSetArg(args[0], XmNtopAttachment, XmATTACH_FORM);
616    XtSetArg(args[1], XmNleftAttachment, XmATTA    616    XtSetArg(args[1], XmNleftAttachment, XmATTACH_FORM);
617    XtSetArg(args[2], XmNrightAttachment, XmATT    617    XtSetArg(args[2], XmNrightAttachment, XmATTACH_FORM);
618    XtSetArg(args[3], XmNbottomAttachment, XmAT    618    XtSetArg(args[3], XmNbottomAttachment, XmATTACH_FORM);
619    Widget form = XmCreateForm(parent, (char *)    619    Widget form = XmCreateForm(parent, (char *) "Form", args, 4);
620    XtManageChild(form);                           620    XtManageChild(form);
621                                                   621 
622    shell = XtParent(form);                        622    shell = XtParent(form);
623    WM_DELETE_WINDOW = XInternAtom(XtDisplay(pa    623    WM_DELETE_WINDOW = XInternAtom(XtDisplay(parent), "WM_DELETE_WINDOW",
624                                   False);         624                                   False);
625    XmAddWMProtocolCallback(shell, WM_DELETE_WI    625    XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW,
626                            (XtCallbackProc)clo    626                            (XtCallbackProc)closeMainWindowCB, this);
627                                                   627 
628    XtSetArg(args[0], XmNtopAttachment, XmATTAC    628    XtSetArg(args[0], XmNtopAttachment, XmATTACH_FORM);
629    XtSetArg(args[1], XmNleftAttachment, XmATTA    629    XtSetArg(args[1], XmNleftAttachment, XmATTACH_FORM);
630    XtSetArg(args[2], XmNrightAttachment, XmATT    630    XtSetArg(args[2], XmNrightAttachment, XmATTACH_FORM);
631    menuBar = XmCreateMenuBar(form, (char *) "M    631    menuBar = XmCreateMenuBar(form, (char *) "MenuBar", args, 3);
632    XtManageChild(menuBar);                        632    XtManageChild(menuBar);
633                                                   633 
634    fileMenu = addMenu("File");                    634    fileMenu = addMenu("File");
635    this->addButton(fileMenu, "Open Viewpoint F    635    this->addButton(fileMenu, "Open Viewpoint File...", openViewPtFileCB);
636    addButton(fileMenu, "New Viewpoint File", n    636    addButton(fileMenu, "New Viewpoint File", newViewPtFileCB);
637    addButton(fileMenu, "Load Ref. Coords", loa    637    addButton(fileMenu, "Load Ref. Coords", loadRefCoordsDialogCB);
638    addButton(fileMenu, "Save Ref. Coords", sav    638    addButton(fileMenu, "Save Ref. Coords", saveRefCoordsDialogCB);
639    addButton(fileMenu, "Load Scene Graph", loa    639    addButton(fileMenu, "Load Scene Graph", loadSceneGraphDialogCB);
640    addButton(fileMenu, "Save Scene Graph", sav    640    addButton(fileMenu, "Save Scene Graph", saveSceneGraphDialogCB);
641    XtManageChild(                                 641    XtManageChild(
642           XmCreateSeparatorGadget(fileMenu, (c    642           XmCreateSeparatorGadget(fileMenu, (char *) "Separator", NULL, 0));
643                                                   643 
644    Widget menu = addMenu("Tools");                644    Widget menu = addMenu("Tools");
645    addButton(menu, "Animate Ref. Particle", an    645    addButton(menu, "Animate Ref. Particle", animateRefParticleCB);
646    addButton(menu, "Go to start of Ref path",     646    addButton(menu, "Go to start of Ref path", gotoRefPathStartCB);
647    addButton(menu, "Invert Ref path", invertRe    647    addButton(menu, "Invert Ref path", invertRefPathCB);
648                                                   648 
649    Widget viewerBase = SoXtFullViewer::buildWi    649    Widget viewerBase = SoXtFullViewer::buildWidget(form);
650                                                   650 
651    XtSetArg(args[0], XmNtopAttachment, XmATTAC    651    XtSetArg(args[0], XmNtopAttachment, XmATTACH_WIDGET);
652    XtSetArg(args[1], XmNtopWidget, menuBar);      652    XtSetArg(args[1], XmNtopWidget, menuBar);
653    XtSetArg(args[2], XmNleftAttachment, XmATTA    653    XtSetArg(args[2], XmNleftAttachment, XmATTACH_FORM);
654    XtSetArg(args[3], XmNrightAttachment, XmATT    654    XtSetArg(args[3], XmNrightAttachment, XmATTACH_FORM);
655    XtSetArg(args[4], XmNbottomAttachment, XmAT    655    XtSetArg(args[4], XmNbottomAttachment, XmATTACH_FORM);
656    XtSetValues(viewerBase, args, 5);              656    XtSetValues(viewerBase, args, 5);
657                                                   657 
658    return viewerBase;                             658    return viewerBase;
659 }                                                 659 }
660                                                   660 
661                                                   661 
662 // Adds a new menu to menuBar                     662 // Adds a new menu to menuBar
663 Widget G4OpenInventorXtExaminerViewer::addMenu    663 Widget G4OpenInventorXtExaminerViewer::addMenu(std::string name)
664 {                                                 664 {
665    Arg args[1];                                   665    Arg args[1];
666    Widget menu = XmCreatePulldownMenu(menuBar,    666    Widget menu = XmCreatePulldownMenu(menuBar, (char *) name.c_str(), NULL, 0);
667                                                   667 
668    XtSetArg(args[0], XmNsubMenuId, menu);         668    XtSetArg(args[0], XmNsubMenuId, menu);
669    Widget w = XmCreateCascadeButton(menuBar, (    669    Widget w = XmCreateCascadeButton(menuBar, (char *) name.c_str(), args, 1);
670    XtManageChild(w);                              670    XtManageChild(w);
671                                                   671 
672    return menu;                                   672    return menu;
673 }                                                 673 }
674                                                   674 
675                                                   675 
676 // Adds a new button to menu                      676 // Adds a new button to menu
677 void G4OpenInventorXtExaminerViewer::addButton    677 void G4OpenInventorXtExaminerViewer::addButton(Widget menu, std::string name,
678                                              X    678                                              XtCallbackProc cb)
679 {                                                 679 {
680    Widget button = XmCreatePushButton(menu, (c    680    Widget button = XmCreatePushButton(menu, (char *) name.c_str(), NULL, 0);
681    XtManageChild(button);                         681    XtManageChild(button);
682    XtAddCallback(button, XmNactivateCallback,     682    XtAddCallback(button, XmNactivateCallback, cb, this);
683 }                                                 683 }
684                                                   684 
685                                                   685 
686 // Overloaded for saving of and browsing throu    686 // Overloaded for saving of and browsing through viewpoints.
687 void G4OpenInventorXtExaminerViewer::createVie    687 void G4OpenInventorXtExaminerViewer::createViewerButtons(Widget parent,
688                                                   688                                                        SbPList * buttonlist)
689 {                                                 689 {
690    int n;                                         690    int n;
691    Arg args[6];                                   691    Arg args[6];
692    Widget saveViewPtButton, abbrOutputButton,     692    Widget saveViewPtButton, abbrOutputButton, pickRefPathButton;
693    Widget switchWireFrameButton;                  693    Widget switchWireFrameButton;
694                                                   694 
695    // Create original buttons                     695    // Create original buttons
696    SoXtExaminerViewer::createViewerButtons(par    696    SoXtExaminerViewer::createViewerButtons(parent, buttonlist);
697                                                   697 
698    // Handle disappearing button caused by SoX    698    // Handle disappearing button caused by SoXtExaminerViewer::setCamera
699    Widget emptyButton = XtVaCreateManagedWidge    699    Widget emptyButton = XtVaCreateManagedWidget("", xmPushButtonWidgetClass,
700                                                   700                                                 parent, NULL);
701    buttonlist->append(emptyButton);               701    buttonlist->append(emptyButton);
702                                                   702 
703    // Left arrow that goes back one view point    703    // Left arrow that goes back one view point on click
704    n = 0;                                         704    n = 0;
705    XtSetArg(args[n], XmNtopPosition, 1);  n++;    705    XtSetArg(args[n], XmNtopPosition, 1);  n++;
706    XtSetArg(args[n], XmNbottomPosition, 2); n+    706    XtSetArg(args[n], XmNbottomPosition, 2); n++;
707    XtSetArg(args[n], XmNleftPosition, 0); n++;    707    XtSetArg(args[n], XmNleftPosition, 0); n++;
708    XtSetArg(args[n], XmNrightPosition, 1);  n+    708    XtSetArg(args[n], XmNrightPosition, 1);  n++;
709    XtSetArg(args[n], XmNarrowDirection, XmARRO    709    XtSetArg(args[n], XmNarrowDirection, XmARROW_LEFT);  n++;
710    XtSetArg(args[n], XmNsensitive, False);  n+    710    XtSetArg(args[n], XmNsensitive, False);  n++;
711    prevViewPtButton = XmCreateArrowButtonGadge    711    prevViewPtButton = XmCreateArrowButtonGadget(parent, (char *) "ArrowL",
712                                                   712                                                 args, n);
713    XtManageChild(prevViewPtButton);               713    XtManageChild(prevViewPtButton);
714    XtAddCallback(prevViewPtButton, XmNactivate    714    XtAddCallback(prevViewPtButton, XmNactivateCallback,
715                  G4OpenInventorXtExaminerViewe    715                  G4OpenInventorXtExaminerViewer::prevViewPtCB, this);
716    buttonlist->append(prevViewPtButton);          716    buttonlist->append(prevViewPtButton);
717                                                   717 
718    // Right arrow that goes forward one view p    718    // Right arrow that goes forward one view point on click
719    n = 0;                                         719    n = 0;
720    XtSetArg(args[n], XmNtopPosition, 1);  n++;    720    XtSetArg(args[n], XmNtopPosition, 1);  n++;
721    XtSetArg(args[n], XmNbottomPosition, 2); n+    721    XtSetArg(args[n], XmNbottomPosition, 2); n++;
722    XtSetArg(args[n], XmNleftPosition, 0); n++;    722    XtSetArg(args[n], XmNleftPosition, 0); n++;
723    XtSetArg(args[n], XmNrightPosition, 1);  n+    723    XtSetArg(args[n], XmNrightPosition, 1);  n++;
724    XtSetArg(args[n], XmNarrowDirection, XmARRO    724    XtSetArg(args[n], XmNarrowDirection, XmARROW_RIGHT); n++;
725    XtSetArg(args[n], XmNsensitive, False);  n+    725    XtSetArg(args[n], XmNsensitive, False);  n++;
726    nextViewPtButton = XmCreateArrowButtonGadge    726    nextViewPtButton = XmCreateArrowButtonGadget(parent, (char *) "ArrowR",
727                                                   727                                                 args, n);
728    XtManageChild(nextViewPtButton);               728    XtManageChild(nextViewPtButton);
729    XtAddCallback(nextViewPtButton, XmNactivate    729    XtAddCallback(nextViewPtButton, XmNactivateCallback,
730                  G4OpenInventorXtExaminerViewe    730                  G4OpenInventorXtExaminerViewer::nextViewPtCB, this);
731    buttonlist->append(nextViewPtButton);          731    buttonlist->append(nextViewPtButton);
732                                                   732 
733    // Save button for storing current camera p    733    // Save button for storing current camera parameters
734    saveViewPtButton = XtVaCreateManagedWidget(    734    saveViewPtButton = XtVaCreateManagedWidget("Save", xmPushButtonWidgetClass,
735                                                   735                                               parent, NULL);
736    XtAddCallback(saveViewPtButton, XmNactivate    736    XtAddCallback(saveViewPtButton, XmNactivateCallback,
737                  G4OpenInventorXtExaminerViewe    737                  G4OpenInventorXtExaminerViewer::saveViewPtCB, this);
738    Pixmap saveVP, saveVP_ins;                     738    Pixmap saveVP, saveVP_ins;
739    saveVP = SoXtInternal::createPixmapFromXpm(    739    saveVP = SoXtInternal::createPixmapFromXpm(saveViewPtButton,
740                                                   740                                               saveViewPt_xpm);
741    saveVP_ins = SoXtInternal::createPixmapFrom    741    saveVP_ins = SoXtInternal::createPixmapFromXpm(saveViewPtButton,
742                                                   742                                                   saveViewPt_xpm, TRUE);
743    XtVaSetValues(saveViewPtButton, XmNlabelTyp    743    XtVaSetValues(saveViewPtButton, XmNlabelType, XmPIXMAP, XmNlabelPixmap,
744                  saveVP, XmNselectPixmap, save    744                  saveVP, XmNselectPixmap, saveVP, XmNlabelInsensitivePixmap,
745                  saveVP_ins, XmNselectInsensit    745                  saveVP_ins, XmNselectInsensitivePixmap, saveVP_ins, NULL);
746    buttonlist->append(saveViewPtButton);          746    buttonlist->append(saveViewPtButton);
747                                                   747 
748    // Toggle button to get abbreviated output     748    // Toggle button to get abbreviated output
749    abbrOutputButton = XtVaCreateManagedWidget(    749    abbrOutputButton = XtVaCreateManagedWidget("Abbr",
750                                                   750                                               xmToggleButtonWidgetClass, parent, XmNindicatorOn, False, NULL);
751    XtAddCallback(abbrOutputButton, XmNdisarmCa    751    XtAddCallback(abbrOutputButton, XmNdisarmCallback, G4OpenInventorXtExaminerViewer::abbrOutputCB,
752                  this);                           752                  this);
753    Pixmap pickextxpm, pickextxpm_ins;             753    Pixmap pickextxpm, pickextxpm_ins;
754    pickextxpm = SoXtInternal::createPixmapFrom    754    pickextxpm = SoXtInternal::createPixmapFromXpm(abbrOutputButton,
755                                                   755                                                   pickext_xpm);
756    pickextxpm_ins = SoXtInternal::createPixmap    756    pickextxpm_ins = SoXtInternal::createPixmapFromXpm(abbrOutputButton,
757                                                   757                                                       pickext_xpm, TRUE);
758    XtVaSetValues(abbrOutputButton, XmNlabelTyp    758    XtVaSetValues(abbrOutputButton, XmNlabelType, XmPIXMAP, XmNlabelPixmap,
759                  pickextxpm, XmNselectPixmap,     759                  pickextxpm, XmNselectPixmap, pickextxpm, XmNlabelInsensitivePixmap,
760                  pickextxpm_ins, XmNselectInse    760                  pickextxpm_ins, XmNselectInsensitivePixmap, pickextxpm_ins, NULL);
761    //   Pixmap consolexpm, consolexpm_ins;        761    //   Pixmap consolexpm, consolexpm_ins;
762    // consolexpm = SoXtInternal::createPixmapF    762    // consolexpm = SoXtInternal::createPixmapFromXpm(abbrOutputButton,
763    //                                             763    //                                                console_xpm);
764    // consolexpm_ins = SoXtInternal::createPix    764    // consolexpm_ins = SoXtInternal::createPixmapFromXpm(abbrOutputButton,
765    //                                             765    //                                                    console_xpm, TRUE);
766    // XtVaSetValues(abbrOutputButton, XmNlabel    766    // XtVaSetValues(abbrOutputButton, XmNlabelType, XmPIXMAP, XmNlabelPixmap,
767    //               consolexpm, XmNselectPixma    767    //               consolexpm, XmNselectPixmap, consolexpm, XmNlabelInsensitivePixmap,
768    //               consolexpm_ins, XmNselectI    768    //               consolexpm_ins, XmNselectInsensitivePixmap, consolexpm_ins, NULL);
769    buttonlist->append(abbrOutputButton);          769    buttonlist->append(abbrOutputButton);
770                                                   770 
771    // Button for selecting the beam that will     771    // Button for selecting the beam that will act as reference path
772    pickRefPathButton = XtVaCreateManagedWidget    772    pickRefPathButton = XtVaCreateManagedWidget("Refpath", xmPushButtonWidgetClass,
773                                                   773                                                parent, NULL);
774    XtAddCallback(pickRefPathButton, XmNactivat    774    XtAddCallback(pickRefPathButton, XmNactivateCallback,
775                  G4OpenInventorXtExaminerViewe    775                  G4OpenInventorXtExaminerViewer::pickRefPathCB, this);
776    Pixmap pickrefxpm, pickrefxpm_ins;             776    Pixmap pickrefxpm, pickrefxpm_ins;
777    pickrefxpm = SoXtInternal::createPixmapFrom    777    pickrefxpm = SoXtInternal::createPixmapFromXpm(pickRefPathButton,
778                                                   778                                                     pickref_xpm);
779    pickrefxpm_ins = SoXtInternal::createPixmap    779    pickrefxpm_ins = SoXtInternal::createPixmapFromXpm(pickRefPathButton,
780                                                   780                                                         pickref_xpm, TRUE);
781    XtVaSetValues(pickRefPathButton, XmNlabelTy    781    XtVaSetValues(pickRefPathButton, XmNlabelType, XmPIXMAP, XmNlabelPixmap,
782        pickrefxpm, XmNselectPixmap, pickrefxpm    782        pickrefxpm, XmNselectPixmap, pickrefxpm, XmNlabelInsensitivePixmap,
783        pickrefxpm_ins, XmNselectInsensitivePix    783        pickrefxpm_ins, XmNselectInsensitivePixmap, pickrefxpm_ins, NULL);
784                                                   784 
785    buttonlist->append(pickRefPathButton);         785    buttonlist->append(pickRefPathButton);
786                                                   786 
787    // Toggle button for switching in and out o    787    // Toggle button for switching in and out of wireframe mode
788    switchWireFrameButton = XtVaCreateManagedWi    788    switchWireFrameButton = XtVaCreateManagedWidget("Wireframe",
789          xmToggleButtonWidgetClass, parent,  X    789          xmToggleButtonWidgetClass, parent,  XmNindicatorOn, False, NULL);
790    XtAddCallback(switchWireFrameButton, XmNval    790    XtAddCallback(switchWireFrameButton, XmNvalueChangedCallback,
791                  G4OpenInventorXtExaminerViewe    791                  G4OpenInventorXtExaminerViewer::switchWireFrameCB, this);
792    Pixmap wireframe, wireframe_ins;               792    Pixmap wireframe, wireframe_ins;
793    wireframe = SoXtInternal::createPixmapFromX    793    wireframe = SoXtInternal::createPixmapFromXpm(switchWireFrameButton,
794                                                   794                                                  wireframe_xpm);
795    wireframe_ins = SoXtInternal::createPixmapF    795    wireframe_ins = SoXtInternal::createPixmapFromXpm(switchWireFrameButton,
796                                                   796                                                      wireframe_xpm, TRUE);
797    XtVaSetValues(switchWireFrameButton, XmNlab    797    XtVaSetValues(switchWireFrameButton, XmNlabelType, XmPIXMAP, XmNlabelPixmap,
798               wireframe, XmNselectPixmap, wire    798               wireframe, XmNselectPixmap, wireframe, XmNlabelInsensitivePixmap,
799               wireframe_ins, XmNselectInsensit    799               wireframe_ins, XmNselectInsensitivePixmap, wireframe_ins, NULL);
800    buttonlist->append(switchWireFrameButton);     800    buttonlist->append(switchWireFrameButton);
801 }                                                 801 }
802                                                   802 
803                                                   803 
804 // Called right after buttons and widgets get     804 // Called right after buttons and widgets get realized.
805 // It sets the viewpoint last accessed.           805 // It sets the viewpoint last accessed.
806 void G4OpenInventorXtExaminerViewer::afterReal    806 void G4OpenInventorXtExaminerViewer::afterRealizeHook()
807 {                                                 807 {
808    SoXtExaminerViewer::afterRealizeHook();        808    SoXtExaminerViewer::afterRealizeHook();
809                                                   809 
810    // Default height is used when selecting an    810    // Default height is used when selecting and viewing scene elements
811    // FWJ Added defaultHeight for Ortho camera    811    // FWJ Added defaultHeight for Ortho camera
812    SoCamera *cam = getCamera();                   812    SoCamera *cam = getCamera();
813    if (cam) {                                     813    if (cam) {
814       if (cam->isOfType(SoPerspectiveCamera::g    814       if (cam->isOfType(SoPerspectiveCamera::getClassTypeId())) {
815          defaultHeightAngle =                     815          defaultHeightAngle =
816             ((SoPerspectiveCamera *) cam)->hei    816             ((SoPerspectiveCamera *) cam)->heightAngle.getValue();
817          toggleCameraType();                      817          toggleCameraType();
818          defaultHeight =                          818          defaultHeight =
819             ((SoOrthographicCamera *) cam)->he    819             ((SoOrthographicCamera *) cam)->height.getValue();
820          toggleCameraType();                      820          toggleCameraType();
821       } else {                                    821       } else {
822          defaultHeight =                          822          defaultHeight =
823             ((SoOrthographicCamera *) cam)->he    823             ((SoOrthographicCamera *) cam)->height.getValue();
824          toggleCameraType();                      824          toggleCameraType();
825          cam = getCamera();                       825          cam = getCamera();
826          if (cam->isOfType(SoPerspectiveCamera    826          if (cam->isOfType(SoPerspectiveCamera::getClassTypeId()))
827             defaultHeightAngle =                  827             defaultHeightAngle =
828                ((SoPerspectiveCamera *) cam)->    828                ((SoPerspectiveCamera *) cam)->heightAngle.getValue();
829          toggleCameraType();                      829          toggleCameraType();
830       }                                           830       }
831    }                                              831    }
832                                                   832 
833    // Open the default bookmark file              833    // Open the default bookmark file
834    fileIn.open(fileName.c_str());                 834    fileIn.open(fileName.c_str());
835    if (!fileIn.fail()) {                          835    if (!fileIn.fail()) {
836       if (!loadViewPts()) {                       836       if (!loadViewPts()) {
837          String dialogName = (char *) "Error L    837          String dialogName = (char *) "Error Loading File";
838          std::string msg = "Wrong or corrupted    838          std::string msg = "Wrong or corrupted input file.";
839          warningMsgDialog(msg, dialogName, NUL    839          warningMsgDialog(msg, dialogName, NULL);
840       } else {                                    840       } else {
841          // Opens a file without erasing it       841          // Opens a file without erasing it
842          fileOut.open(fileName.c_str(), std::i    842          fileOut.open(fileName.c_str(), std::ios::in);
843          fileOut.seekp(0, std::ios::end); // F    843          fileOut.seekp(0, std::ios::end); // For appending new data to the end
844          constructListsDialog(getParentWidget(    844          constructListsDialog(getParentWidget(), this, NULL); // Pop up listsDialog
845          if (viewPtList.size()) {                 845          if (viewPtList.size()) {
846             // FWJ disabled auto-selection of     846             // FWJ disabled auto-selection of first viewpoint.
847             // Initial view should be user-con    847             // Initial view should be user-controllable & not forced
848             //    setViewPt();                    848             //    setViewPt();
849             XtSetSensitive(nextViewPtButton, T    849             XtSetSensitive(nextViewPtButton, True);
850             XtSetSensitive(prevViewPtButton, T    850             XtSetSensitive(prevViewPtButton, True);
851          }                                        851          }
852       }                                           852       }
853       fileIn.close();                             853       fileIn.close();
854    } else {                                       854    } else {
855       // Creates a new default bookmark file      855       // Creates a new default bookmark file
856       fileOut.open(fileName.c_str());             856       fileOut.open(fileName.c_str());
857       constructListsDialog(getParentWidget(),     857       constructListsDialog(getParentWidget(), this, NULL); // Pop up listsDialog
858    }                                              858    }
859                                                   859 
860    fileIn.clear();                                860    fileIn.clear();
861                                                   861 
862    SoSeparator *root = (SoSeparator *) (getSce    862    SoSeparator *root = (SoSeparator *) (getSceneManager()->getSceneGraph());
863    if (root == NULL)                              863    if (root == NULL)
864       SoDebugError::post("G4OpenInventorXtExam    864       SoDebugError::post("G4OpenInventorXtExaminerViewer::afterRealizeHook", "Root is null.");
865    else {                                         865    else {
866       root->addChild(myCam); // For position/o    866       root->addChild(myCam); // For position/orientation calculation during animation
867    }                                              867    }
868                                                   868 
869    sceneChangeSensor = new SoNodeSensor;          869    sceneChangeSensor = new SoNodeSensor;
870    sceneChangeSensor->setFunction(sceneChangeC    870    sceneChangeSensor->setFunction(sceneChangeCB);
871    sceneChangeSensor->attach(root);               871    sceneChangeSensor->attach(root);
872    sceneChangeSensor->setData(this);              872    sceneChangeSensor->setData(this);
873                                                   873 
874    // Monitor mouseover events for displaying     874    // Monitor mouseover events for displaying the name of scene elements
875    // An SoEventCallback is needed instead of     875    // An SoEventCallback is needed instead of using the default processSoEvent
876    // because that last one does not provide u    876    // because that last one does not provide us with an SoPath to the object
877    // that was picked                             877    // that was picked
878    SoEventCallback *moCB = new SoEventCallback    878    SoEventCallback *moCB = new SoEventCallback;
879    moCB->addEventCallback(                        879    moCB->addEventCallback(
880                           SoLocation2Event::ge    880                           SoLocation2Event::getClassTypeId(),
881                           mouseoverCB, static_    881                           mouseoverCB, static_cast<void *>(this));
882    root->addChild(moCB);                          882    root->addChild(moCB);
883                                                   883 
884    // Override the default picking mechanism p    884    // Override the default picking mechanism present in G4OpenInventorViewer
885    // because we want abbreviated output when     885    // because we want abbreviated output when picking a trajectory
886    SoEventCallback *pickCB = new SoEventCallba    886    SoEventCallback *pickCB = new SoEventCallback;
887    pickCB->addEventCallback(                      887    pickCB->addEventCallback(
888                             SoMouseButtonEvent    888                             SoMouseButtonEvent::getClassTypeId(),
889                             pickingCB, static_    889                             pickingCB, static_cast<void *>(this));
890    root->addChild(pickCB);                        890    root->addChild(pickCB);
891                                                   891 
892 }                                                 892 }
893                                                   893 
894                                                   894 
895 // Rotates camera 90 degrees around a scene el    895 // Rotates camera 90 degrees around a scene element.
896 // Rotation is animated for smoothness.           896 // Rotation is animated for smoothness.
897 void G4OpenInventorXtExaminerViewer::rotateCam    897 void G4OpenInventorXtExaminerViewer::rotateCamera()
898 {                                                 898 {
899    SoCamera *cam = getCamera();                   899    SoCamera *cam = getCamera();
900                                                   900 
901    SbRotation rot(rotAxis, M_PI / (2 * ROT_CNT    901    SbRotation rot(rotAxis, M_PI / (2 * ROT_CNT));
902    rot.multVec(camDir, camDir);                   902    rot.multVec(camDir, camDir);
903    rot.multVec(camUpVec, camUpVec);               903    rot.multVec(camUpVec, camUpVec);
904                                                   904 
905    SbVec3f camPosNew = prevPt - (camDir*distan    905    SbVec3f camPosNew = prevPt - (camDir*distance);
906    cam->position = camPosNew;                     906    cam->position = camPosNew;
907    cam->pointAt(prevPt, camUpVec);                907    cam->pointAt(prevPt, camUpVec);
908    cam->focalDistance = (prevPt - camPosNew).l    908    cam->focalDistance = (prevPt - camPosNew).length();
909                                                   909 
910    rotCnt--;                                      910    rotCnt--;
911                                                   911 
912    if (animateSensorRotation->isScheduled()) {    912    if (animateSensorRotation->isScheduled()) {
913       animateSensorRotation->unschedule();        913       animateSensorRotation->unschedule();
914    }                                              914    }
915                                                   915 
916    animateSensorRotation->setBaseTime(SbTime::    916    animateSensorRotation->setBaseTime(SbTime::getTimeOfDay());
917    animateSensorRotation->setInterval(SbTime(0    917    animateSensorRotation->setInterval(SbTime(0.02));
918    animateSensorRotation->schedule();             918    animateSensorRotation->schedule();
919                                                   919 
920 }                                                 920 }
921                                                   921 
922                                                   922 
923 // Slides camera along the beamline.              923 // Slides camera along the beamline.
924 void G4OpenInventorXtExaminerViewer::moveCamer    924 void G4OpenInventorXtExaminerViewer::moveCamera(float dist, bool lookdown)
925 {                                                 925 {
926                                                   926 
927    SoCamera *cam = getCamera();                   927    SoCamera *cam = getCamera();
928    SbVec3f p1(0), p2(0); // The particle moves    928    SbVec3f p1(0), p2(0); // The particle moves from p1 to p2
929    SbVec3f particleDir;  // Direction vector f    929    SbVec3f particleDir;  // Direction vector from p1 to p2
930    SbVec3f camPosNew(0); // New position of th    930    SbVec3f camPosNew(0); // New position of the camera
931                                                   931 
932    if(refParticleTrajectory.size() == 0) {        932    if(refParticleTrajectory.size() == 0) {
933       //refParticleTrajectory hasn't been set     933       //refParticleTrajectory hasn't been set yet
934       if(dist)                                    934       if(dist)
935          distance = dist;                         935          distance = dist;
936       else                                        936       else
937          distance = (cam->position.getValue()     937          distance = (cam->position.getValue() - center).length();
938                                                   938 
939       cam->position.setValue(center + offsetFr    939       cam->position.setValue(center + offsetFromCenter*distance);
940       cam->focalDistance = (cam->position.getV    940       cam->focalDistance = (cam->position.getValue() - center).length();
941       cam->pointAt(center, upVector);             941       cam->pointAt(center, upVector);
942    }                                              942    }
943    else{                                          943    else{
944                                                   944 
945       // If we move forward past the last traj    945       // If we move forward past the last trajectory point,
946       // go back to the beginning                 946       // go back to the beginning
947       if (refParticleIdx >= (int) refParticleT    947       if (refParticleIdx >= (int) refParticleTrajectory.size() - 1) {
948          prevPt = refParticleTrajectory[refPar    948          prevPt = refParticleTrajectory[refParticleIdx - step];
949          dist = (prevPt - cam->position.getVal    949          dist = (prevPt - cam->position.getValue()).length();
950          refParticleIdx = 0;                      950          refParticleIdx = 0;
951       }                                           951       }
952       // If we move backward past the beginnin    952       // If we move backward past the beginning,
953       // go to the last trajectory point          953       // go to the last trajectory point
954       if (refParticleIdx < 0) {                   954       if (refParticleIdx < 0) {
955          prevPt = refParticleTrajectory[refPar    955          prevPt = refParticleTrajectory[refParticleIdx + step];
956          dist = (prevPt - cam->position.getVal    956          dist = (prevPt - cam->position.getValue()).length();
957          refParticleIdx = refParticleTrajector    957          refParticleIdx = refParticleTrajectory.size() - 2;
958       }                                           958       }
959                                                   959 
960       // Set start and end points                 960       // Set start and end points
961       p1 = refParticleTrajectory[refParticleId    961       p1 = refParticleTrajectory[refParticleIdx];
962       p2 = refParticleTrajectory[refParticleId    962       p2 = refParticleTrajectory[refParticleIdx + step];
963                                                   963 
964       // Get the direction from p1 to p2          964       // Get the direction from p1 to p2
965       particleDir = p2 - p1;                      965       particleDir = p2 - p1;
966       particleDir.normalize();                    966       particleDir.normalize();
967                                                   967 
968       if(prevParticleDir == SbVec3f(0,0,0)){      968       if(prevParticleDir == SbVec3f(0,0,0)){
969          // First time entering BEAMLINE mode,    969          // First time entering BEAMLINE mode, look at
970          // the element from the front, with c    970          // the element from the front, with camera upright
971          if(lookdown)                             971          if(lookdown)
972             camDir = SbVec3f(0,0,1);              972             camDir = SbVec3f(0,0,1);
973          else                                     973          else
974             camDir = SbVec3f(1,0,0);              974             camDir = SbVec3f(1,0,0);
975          camUpVec = SbVec3f(0,1,0);               975          camUpVec = SbVec3f(0,1,0);
976                                                   976 
977          // In case the start of the goes in a    977          // In case the start of the goes in a
978          // direction other than +z, rotate th    978          // direction other than +z, rotate the camera accordingly
979          SbRotation rot(SbVec3f(0,0,1), partic    979          SbRotation rot(SbVec3f(0,0,1), particleDir);
980          rot.multVec(camDir, camDir);             980          rot.multVec(camDir, camDir);
981          rot.multVec(camUpVec, camUpVec);         981          rot.multVec(camUpVec, camUpVec);
982                                                   982 
983       }                                           983       }
984       else if(particleDir != prevParticleDir)     984       else if(particleDir != prevParticleDir) {
985          // The beamline has changed direction    985          // The beamline has changed direction
986                                                   986 
987          SbRotation rot(prevParticleDir, parti    987          SbRotation rot(prevParticleDir, particleDir);
988          rot.multVec(camDir, camDir);             988          rot.multVec(camDir, camDir);
989          rot.multVec(camUpVec, camUpVec);         989          rot.multVec(camUpVec, camUpVec);
990                                                   990 
991       }                                           991       }
992                                                   992 
993       if (cam->isOfType(SoPerspectiveCamera::g    993       if (cam->isOfType(SoPerspectiveCamera::getClassTypeId())) {
994          if (!dist)                               994          if (!dist)
995             distance = (prevPt - cam->position    995             distance = (prevPt - cam->position.getValue()).length();
996          else                                     996          else
997             distance = dist;                      997             distance = dist;
998       }                                           998       }
999                                                   999 
1000       // FWJ distance not relevant -- use foc    1000       // FWJ distance not relevant -- use focalDistance
1001       // if (cam->isOfType(SoOrthographicCame    1001       // if (cam->isOfType(SoOrthographicCamera::getClassTypeId())) {
1002       //    if (!dist)                           1002       //    if (!dist)
1003       //       distance = (prevPt - cam->posi    1003       //       distance = (prevPt - cam->position.getValue()).length();
1004       //    else                                 1004       //    else
1005       //       distance = dist;                  1005       //       distance = dist;
1006       // }                                       1006       // }
1007                                                  1007 
1008                                                  1008 
1009       float x(0.),y(0.),z(0.);                   1009       float x(0.),y(0.),z(0.);
1010       prevPt.getValue(x,y,z);                    1010       prevPt.getValue(x,y,z);
1011                                                  1011 
1012                                                  1012 
1013       if (cam->isOfType(SoPerspectiveCamera::    1013       if (cam->isOfType(SoPerspectiveCamera::getClassTypeId())) {
1014          camPosNew = p2 - (camDir*distance);     1014          camPosNew = p2 - (camDir*distance);
1015       }                                          1015       }
1016       if (cam->isOfType(SoOrthographicCamera:    1016       if (cam->isOfType(SoOrthographicCamera::getClassTypeId())) {
1017          // FWJ maintain focal distance          1017          // FWJ maintain focal distance
1018          camPosNew = p2 - (camDir*cam->focalD    1018          camPosNew = p2 - (camDir*cam->focalDistance.getValue());
1019          //         camPosNew = p2 - (camDir)    1019          //         camPosNew = p2 - (camDir);
1020       }                                          1020       }
1021                                                  1021 
1022       cam->position = camPosNew;                 1022       cam->position = camPosNew;
1023       cam->pointAt(p2, camUpVec);                1023       cam->pointAt(p2, camUpVec);
1024       cam->focalDistance = (p2 - camPosNew).l    1024       cam->focalDistance = (p2 - camPosNew).length();
1025                                                  1025 
1026       p2.getValue(x,y,z);                        1026       p2.getValue(x,y,z);
1027       camPosNew.getValue(x,y,z);                 1027       camPosNew.getValue(x,y,z);
1028                                                  1028 
1029       prevParticleDir = particleDir;             1029       prevParticleDir = particleDir;
1030       prevPt = p1; // For accurate distance c    1030       prevPt = p1; // For accurate distance calculation
1031                                                  1031 
1032    }                                             1032    }
1033                                                  1033 
1034 }                                                1034 }
1035                                                  1035 
1036                                                  1036 
1037 void G4OpenInventorXtExaminerViewer::pickingC    1037 void G4OpenInventorXtExaminerViewer::pickingCB(void *aThis, 
1038                                                  1038                                                SoEventCallback *eventCB)
1039 {                                                1039 {
1040    SoHandleEventAction* action = eventCB->get    1040    SoHandleEventAction* action = eventCB->getAction();
1041    const SoPickedPoint *pp = action->getPicke    1041    const SoPickedPoint *pp = action->getPickedPoint();
1042    G4OpenInventorXtExaminerViewer* This = (G4    1042    G4OpenInventorXtExaminerViewer* This = (G4OpenInventorXtExaminerViewer*)aThis;
1043                                                  1043 
1044    if(pp != NULL) {                              1044    if(pp != NULL) {
1045                                                  1045 
1046       SoPath* path = pp->getPath();              1046       SoPath* path = pp->getPath();
1047       SoNode* node = ((SoFullPath*)path)->get    1047       SoNode* node = ((SoFullPath*)path)->getTail();
1048                                                  1048 
1049       if(node->getTypeId() == SoLineSet::getC    1049       if(node->getTypeId() == SoLineSet::getClassTypeId()){
1050                                                  1050 
1051          if(This->pickRefPathFlag){              1051          if(This->pickRefPathFlag){
1052             This->pickRefPathFlag = false;       1052             This->pickRefPathFlag = false;
1053             if(This->viewingBeforePickRef !=     1053             if(This->viewingBeforePickRef != This->isViewing())
1054                This->setViewing(This->viewing    1054                This->setViewing(This->viewingBeforePickRef);
1055             else                                 1055             else
1056                This->setComponentCursor(SoXtC    1056                This->setComponentCursor(SoXtCursor(SoXtCursor::DEFAULT));
1057                                                  1057 
1058             // The trajectory is a set of lin    1058             // The trajectory is a set of lines stored in a LineSet
1059             SoLineSet * trajectory = (SoLineS    1059             SoLineSet * trajectory = (SoLineSet *)node;
1060                                                  1060 
1061        // The set of all trajectories is stor    1061        // The set of all trajectories is stored in a Seperator group node
1062        // one level above the LineSet that wa    1062        // one level above the LineSet that was picked. The nodes under that
1063        // seperator are as follows (in this o    1063        // seperator are as follows (in this order): Material, LightModel,
1064        // ResetTransform, MatrixTransform, Co    1064        // ResetTransform, MatrixTransform, Coordinate3, DrawStyle, LineSet
1065             SoSeparator * grpNode =              1065             SoSeparator * grpNode = 
1066                (SoSeparator*)(((SoFullPath*)p    1066                (SoSeparator*)(((SoFullPath*)path)->getNodeFromTail(1));
1067                                                  1067 
1068    // The node that contains the coordinates     1068    // The node that contains the coordinates for the trajectory is a
1069    // Coordinate3 node which occurs before th    1069    // Coordinate3 node which occurs before the LineSet node.  We iterate
1070    // back through the nodes in the group unt    1070    // back through the nodes in the group until we find the Coordinate3 node
1071             int nodeIndex = grpNode->findChil    1071             int nodeIndex = grpNode->findChild(trajectory);
1072             SoNode * tmpNode;                    1072             SoNode * tmpNode;
1073             // FWJ needs initialization          1073             // FWJ needs initialization
1074             SoCoordinate3 * coords = 0;          1074             SoCoordinate3 * coords = 0;
1075             //            SoCoordinate3 * coo    1075             //            SoCoordinate3 * coords;
1076             // We allow only 100 iterations,     1076             // We allow only 100 iterations, in case the node isn't found
1077             // (should take only a few iterat    1077             // (should take only a few iterations)
1078             for(int i = 0; i < 100; ++i) {       1078             for(int i = 0; i < 100; ++i) {
1079                --nodeIndex;                      1079                --nodeIndex;
1080                                                  1080 
1081                tmpNode = grpNode->getChild(no    1081                tmpNode = grpNode->getChild(nodeIndex);
1082                if(tmpNode->getTypeId() == SoC    1082                if(tmpNode->getTypeId() == SoCoordinate3::getClassTypeId()){
1083                   //node found                   1083                   //node found
1084                   coords = (SoCoordinate3 *)t    1084                   coords = (SoCoordinate3 *)tmpNode;
1085                   break;                         1085                   break;
1086                }                                 1086                }
1087             }                                    1087             }
1088                                                  1088 
1089             if(coords == NULL){                  1089             if(coords == NULL){
1090                String dialogName = (char *) "    1090                String dialogName = (char *) "No coordinates";
1091                std::string msg = "Could not f    1091                std::string msg = "Could not find the coordinates node"
1092                   " for the picked trajectory    1092                   " for the picked trajectory."
1093                   " Reference trajectory not     1093                   " Reference trajectory not set";
1094                This->warningMsgDialog(msg, di    1094                This->warningMsgDialog(msg, dialogName, NULL);
1095                return;                           1095                return;
1096             }                                    1096             }
1097                                                  1097 
1098                                                  1098 
1099             if ((This->lshiftdown)  || (This-    1099             if ((This->lshiftdown)  || (This->rshiftdown))
1100                This->setReferencePath(traject    1100                This->setReferencePath(trajectory, coords, true);
1101             else                                 1101             else
1102                This->setReferencePath(traject    1102                This->setReferencePath(trajectory, coords, false);
1103                                                  1103 
1104             return;                              1104             return;
1105                                                  1105 
1106          }                                       1106          }
1107          else if(This->abbrOutputFlag) {         1107          else if(This->abbrOutputFlag) {
1108                                                  1108 
1109             G4AttHolder* attHolder = dynamic_    1109             G4AttHolder* attHolder = dynamic_cast<G4AttHolder*>(node);
1110             if(attHolder && attHolder->GetAtt    1110             if(attHolder && attHolder->GetAttDefs().size()) {
1111                                                  1111 
1112                std::string strTrajPoint = "G4    1112                std::string strTrajPoint = "G4TrajectoryPoint:";
1113                std::ostringstream oss;           1113                std::ostringstream oss;
1114                for (size_t i = 0; i < attHold    1114                for (size_t i = 0; i < attHolder->GetAttDefs().size(); ++i) {
1115                   G4cout << G4AttCheck(attHol    1115                   G4cout << G4AttCheck(attHolder->GetAttValues()[i],
1116                                        attHol    1116                                        attHolder->GetAttDefs()[i]);
1117                   oss << G4AttCheck(attHolder    1117                   oss << G4AttCheck(attHolder->GetAttValues()[i],
1118                                     attHolder    1118                                     attHolder->GetAttDefs()[i]);
1119                   if(oss.str().find(strTrajPo    1119                   if(oss.str().find(strTrajPoint) != std::string::npos) {
1120                                                  1120 
1121            // Last attribute displayed was a     1121            // Last attribute displayed was a trajectory point.  Since we
1122            // want abbreviated output, displa    1122            // want abbreviated output, display the last one and exit
1123            // (unless we're already at the la    1123            // (unless we're already at the last (and only) trajectory point)
1124                      if(i != attHolder->GetAt    1124                      if(i != attHolder->GetAttDefs().size()-1) {
1125                         G4cout << G4AttCheck(    1125                         G4cout << G4AttCheck(
1126               attHolder->GetAttValues()[attHo    1126               attHolder->GetAttValues()[attHolder->GetAttDefs().size()-1],
1127               attHolder->GetAttDefs()[attHold    1127               attHolder->GetAttDefs()[attHolder->GetAttDefs().size()-1]);
1128                      }                           1128                      }
1129                      break;                      1129                      break;
1130                   }                              1130                   }
1131                }                                 1131                }
1132             } else {                             1132             } else {
1133                G4String name((char*)node->get    1133                G4String name((char*)node->getName().getString());
1134                G4String cls((char*)node->getT    1134                G4String cls((char*)node->getTypeId().getName().getString());
1135                G4cout << "SoNode : " << node     1135                G4cout << "SoNode : " << node
1136                       << " SoType : " << cls     1136                       << " SoType : " << cls
1137                       << " name : " << name      1137                       << " name : " << name
1138                       << G4endl;                 1138                       << G4endl;
1139                G4cout << "No attributes attac    1139                G4cout << "No attributes attached." << G4endl;
1140             }                                    1140             }
1141                                                  1141 
1142             return;                              1142             return;
1143          }                                       1143          }
1144          else{                                   1144          else{
1145             //Go to default behavior             1145             //Go to default behavior
1146          }                                       1146          }
1147       }                                          1147       }
1148       else {                                     1148       else {
1149          //Go to default behavior                1149          //Go to default behavior
1150       }                                          1150       }
1151                                                  1151 
1152       // Default behavior in G4OpenInventorVi    1152       // Default behavior in G4OpenInventorViewer::SelectionCB
1153       G4AttHolder* attHolder = dynamic_cast<G    1153       G4AttHolder* attHolder = dynamic_cast<G4AttHolder*>(node);
1154       if(attHolder && attHolder->GetAttDefs()    1154       if(attHolder && attHolder->GetAttDefs().size()) {
1155          for (size_t i = 0; i < attHolder->Ge    1155          for (size_t i = 0; i < attHolder->GetAttDefs().size(); ++i) {
1156             G4cout << G4AttCheck(attHolder->G    1156             G4cout << G4AttCheck(attHolder->GetAttValues()[i],
1157                                  attHolder->G    1157                                  attHolder->GetAttDefs()[i]);
1158          }                                       1158          }
1159       } else {                                   1159       } else {
1160          G4String name((char*)node->getName()    1160          G4String name((char*)node->getName().getString());
1161          G4String cls((char*)node->getTypeId(    1161          G4String cls((char*)node->getTypeId().getName().getString());
1162          G4cout << "SoNode : " << node           1162          G4cout << "SoNode : " << node
1163                 << " SoType : " << cls           1163                 << " SoType : " << cls
1164                 << " name : " << name            1164                 << " name : " << name
1165                 << G4endl;                       1165                 << G4endl;
1166          G4cout << "No attributes attached."     1166          G4cout << "No attributes attached." << G4endl;
1167       }                                          1167       }
1168                                                  1168 
1169       //Suppress other event handlers            1169       //Suppress other event handlers
1170       eventCB->setHandled();                     1170       eventCB->setHandled();
1171    }                                             1171    }
1172 }                                                1172 }
1173                                                  1173 
1174                                                  1174 
1175 void G4OpenInventorXtExaminerViewer::mouseove    1175 void G4OpenInventorXtExaminerViewer::mouseoverCB(void *aThis, SoEventCallback *eventCB)
1176 {                                                1176 {
1177    SoHandleEventAction* action = eventCB->get    1177    SoHandleEventAction* action = eventCB->getAction();
1178    const SoPickedPoint* pp = action->getPicke    1178    const SoPickedPoint* pp = action->getPickedPoint();
1179    G4OpenInventorXtExaminerViewer* This = (G4    1179    G4OpenInventorXtExaminerViewer* This = (G4OpenInventorXtExaminerViewer*)aThis;
1180                                                  1180 
1181    if(!This->abbrOutputFlag)                     1181    if(!This->abbrOutputFlag)
1182       return;                                    1182       return;
1183                                                  1183 
1184    if(pp != NULL) {                              1184    if(pp != NULL) {
1185                                                  1185 
1186       const SbViewportRegion & viewportRegion    1186       const SbViewportRegion & viewportRegion = action->getViewportRegion();
1187                                                  1187 
1188       std::string sLogName;                      1188       std::string sLogName;
1189       float x,y,z;                               1189       float x,y,z;
1190       std::stringstream ssZPos;                  1190       std::stringstream ssZPos;
1191       std::stringstream ssSolids;                1191       std::stringstream ssSolids;
1192       std::stringstream ssMaterials;             1192       std::stringstream ssMaterials;
1193       SoPath * path = pp->getPath();             1193       SoPath * path = pp->getPath();
1194       SoNode* node = ((SoFullPath*)path)->get    1194       SoNode* node = ((SoFullPath*)path)->getTail();
1195                                                  1195 
1196       if(node->getTypeId() == Geant4_SoPolyhe    1196       if(node->getTypeId() == Geant4_SoPolyhedron::getClassTypeId()) {
1197                                                  1197 
1198          sLogName = "Logical Volume:  ";         1198          sLogName = "Logical Volume:  ";
1199          sLogName += ((Geant4_SoPolyhedron *)    1199          sLogName += ((Geant4_SoPolyhedron *)node)->getName().getString();
1200                                                  1200 
1201          SoGetBoundingBoxAction bAction(viewp    1201          SoGetBoundingBoxAction bAction(viewportRegion);
1202          bAction.apply((SoFullPath*)path);       1202          bAction.apply((SoFullPath*)path);
1203          SbBox3f bBox = bAction.getBoundingBo    1203          SbBox3f bBox = bAction.getBoundingBox();
1204          SbVec3f center = bBox.getCenter();      1204          SbVec3f center = bBox.getCenter();
1205          center.getValue(x,y,z);                 1205          center.getValue(x,y,z);
1206          ssZPos << "Pos:  " << x << "  " << y    1206          ssZPos << "Pos:  " << x << "  " << y << "  " << z;
1207                                                  1207 
1208          G4AttHolder* attHolder = dynamic_cas    1208          G4AttHolder* attHolder = dynamic_cast<G4AttHolder*>(node);
1209          if(attHolder && attHolder->GetAttDef    1209          if(attHolder && attHolder->GetAttDefs().size()) {
1210                                                  1210 
1211             std::vector<const std::map<G4Stri    1211             std::vector<const std::map<G4String,G4AttDef>*> vecDefs =
1212                attHolder->GetAttDefs();          1212                attHolder->GetAttDefs();
1213             std::vector<const std::vector<G4A    1213             std::vector<const std::vector<G4AttValue>*> vecVals =
1214                attHolder->GetAttValues();        1214                attHolder->GetAttValues();
1215             for (size_t i = 0; i < vecDefs.si    1215             for (size_t i = 0; i < vecDefs.size(); ++i) {
1216                const std::vector<G4AttValue>     1216                const std::vector<G4AttValue> * vals = vecVals[i];
1217                                                  1217 
1218                std::vector<G4AttValue>::const    1218                std::vector<G4AttValue>::const_iterator iValue;
1219                                                  1219 
1220                for (iValue = vals->begin(); i    1220                for (iValue = vals->begin(); iValue != vals->end(); ++iValue) {
1221                   const G4String& valueName =    1221                   const G4String& valueName = iValue->GetName();
1222                   const G4String& value = iVa    1222                   const G4String& value = iValue->GetValue();
1223                                                  1223 
1224                   if(valueName == "Solid") {     1224                   if(valueName == "Solid") {
1225                      if(ssSolids.str() == "")    1225                      if(ssSolids.str() == "")
1226                         ssSolids << "Solid Na    1226                         ssSolids << "Solid Name:  " << value;
1227                      else                        1227                      else
1228                         ssSolids << ", " << v    1228                         ssSolids << ", " << value;
1229                   }                              1229                   }
1230                                                  1230 
1231                   if(valueName == "Material")    1231                   if(valueName == "Material") {
1232                      if(ssMaterials.str() ==     1232                      if(ssMaterials.str() == "")
1233                         ssMaterials << "Mater    1233                         ssMaterials << "Material Name:  " << value;
1234                      else                        1234                      else
1235                         ssMaterials << ", " <    1235                         ssMaterials << ", " << value;
1236                   }                              1236                   }
1237                }                                 1237                }
1238             }                                    1238             }
1239          }                                       1239          }
1240       }                                          1240       }
1241       // FWJ Mouseover for trajectories          1241       // FWJ Mouseover for trajectories
1242       else if(node->getTypeId() == SoLineSet:    1242       else if(node->getTypeId() == SoLineSet::getClassTypeId()) {
1243          //         G4cout << "Trajectory!!!!    1243          //         G4cout << "Trajectory!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << G4endl;
1244          G4AttHolder* attHolder = dynamic_cas    1244          G4AttHolder* attHolder = dynamic_cast<G4AttHolder*>(node);
1245          if(attHolder && attHolder->GetAttDef    1245          if(attHolder && attHolder->GetAttDefs().size()) {
1246             std::string strTrajPoint = "G4Tra    1246             std::string strTrajPoint = "G4TrajectoryPoint:";
1247             std::ostringstream oss;              1247             std::ostringstream oss;
1248             G4String t1, t1Ch, t2, t3, t4;       1248             G4String t1, t1Ch, t2, t3, t4;
1249             for (size_t i = 0; i < attHolder-    1249             for (size_t i = 0; i < attHolder->GetAttDefs().size(); ++i) {
1250                //               G4cout << "Ge    1250                //               G4cout << "Getting index " << i << " from attHolder" << G4endl;
1251                // No, returns a vector!   G4A    1251                // No, returns a vector!   G4AttValue* attValue = attHolder->GetAttValues()[i];
1252                const std::vector<G4AttValue>*    1252                const std::vector<G4AttValue>* vals = attHolder->GetAttValues()[i];
1253                std::vector<G4AttValue>::const    1253                std::vector<G4AttValue>::const_iterator iValue;
1254                for (iValue = vals->begin(); i    1254                for (iValue = vals->begin(); iValue != vals->end(); ++iValue) {
1255                   const G4String& valueName =    1255                   const G4String& valueName = iValue->GetName();
1256                   const G4String& value = iVa    1256                   const G4String& value = iValue->GetValue();
1257                   // G4cout << "  valueName =    1257                   // G4cout << "  valueName = " << valueName << G4endl;
1258                   // G4cout << "  value = " <    1258                   // G4cout << "  value = " << value << G4endl;
1259                   // LINE 1                      1259                   // LINE 1
1260                   if (valueName == "PN") t1 =    1260                   if (valueName == "PN") t1 = value;
1261                   if (valueName == "Ch") {       1261                   if (valueName == "Ch") {
1262                      if (atof(value.c_str())     1262                      if (atof(value.c_str()) > 0)
1263                         t1Ch = "    +";          1263                         t1Ch = "    +";
1264                      else                        1264                      else
1265                         t1Ch = "    ";           1265                         t1Ch = "    ";
1266                      t1Ch += value;              1266                      t1Ch += value;
1267                   }                              1267                   }
1268                   if (valueName == "PDG") {      1268                   if (valueName == "PDG") {
1269                      t1 += "    ";               1269                      t1 += "    ";
1270                      t1 += value;                1270                      t1 += value;
1271                      t1 += t1Ch;                 1271                      t1 += t1Ch;
1272                      This->mouseOverTextLogNa    1272                      This->mouseOverTextLogName->string.setValue(t1);
1273                   }                              1273                   }
1274                   //                  G4cout     1274                   //                  G4cout << "  t1 = " << t1 << G4endl;
1275                   // LINE 2                      1275                   // LINE 2
1276                   if (valueName == "EventID")    1276                   if (valueName == "EventID") t2 = "Evt " + value;
1277                   if (valueName == "ID") t2 +    1277                   if (valueName == "ID") t2 += "    Trk " + value;
1278                   if (valueName == "PID") {      1278                   if (valueName == "PID") {
1279                      t2 += "    Prt " + value    1279                      t2 += "    Prt " + value;
1280                      This->mouseOverTextSolid    1280                      This->mouseOverTextSolid->string.setValue(t2);
1281                   }                              1281                   }
1282                   // LINE 3                      1282                   // LINE 3
1283                   if (valueName == "IKE") t3     1283                   if (valueName == "IKE") t3 = "KE " + value;
1284                   if (valueName == "IMom") {     1284                   if (valueName == "IMom") {
1285                      // Remove units             1285                      // Remove units
1286                      unsigned ipos = value.rf    1286                      unsigned ipos = value.rfind(" ");
1287                      G4String value1 = value;    1287                      G4String value1 = value;
1288                      value1.erase(ipos);         1288                      value1.erase(ipos);
1289                      t3 += "    P (" + value1    1289                      t3 += "    P (" + value1 + ")";
1290                   }                              1290                   }
1291                   if (valueName == "IMag") {     1291                   if (valueName == "IMag") {
1292                      t3 += " " + value + "/c"    1292                      t3 += " " + value + "/c";
1293                      //                     t    1293                      //                     t3 += " " + value;
1294                      This->mouseOverTextMater    1294                      This->mouseOverTextMaterial->string.setValue(t3);
1295                   }                              1295                   }
1296                   // LINE 4                      1296                   // LINE 4
1297                   if (valueName == "NTP") {      1297                   if (valueName == "NTP") {
1298                      std::ostringstream t4oss    1298                      std::ostringstream t4oss;
1299                      t4oss << "TrjPts " <<  v    1299                      t4oss << "TrjPts " <<  value;
1300                      t4oss << "    Pos " << p    1300                      t4oss << "    Pos " << pp->getPoint()[0] << " " << pp->getPoint()[1] <<
1301                         " " << pp->getPoint()    1301                         " " << pp->getPoint()[2];
1302                      This->mouseOverTextZPos-    1302                      This->mouseOverTextZPos->string.setValue(SbString(t4oss.str().c_str()));
1303                   }                              1303                   }
1304                }                                 1304                }
1305 //               G4cout << "  NOW CALLING G4A    1305 //               G4cout << "  NOW CALLING G4AttCheck" << G4endl;
1306 //                G4cout << G4AttCheck(attHol    1306 //                G4cout << G4AttCheck(attHolder->GetAttValues()[i],
1307 //                                     attHol    1307 //                                     attHolder->GetAttDefs()[i]);
1308 //                oss << G4AttCheck(attHolder    1308 //                oss << G4AttCheck(attHolder->GetAttValues()[i],
1309 //                                  attHolder    1309 //                                  attHolder->GetAttDefs()[i]);
1310 //                if(oss.str().find(strTrajPo    1310 //                if(oss.str().find(strTrajPoint) != std::string::npos) {
1311 //                   // Last attribute displa    1311 //                   // Last attribute displayed was a trajectory point.  Since we
1312 //                   // want abbreviated outp    1312 //                   // want abbreviated output, display the last one and exit
1313 //                   // (unless we're already    1313 //                   // (unless we're already at the last (and only) trajectory point)
1314 //                   if(i != attHolder->GetAt    1314 //                   if(i != attHolder->GetAttDefs().size()-1) {
1315 //                      G4cout << G4AttCheck(    1315 //                      G4cout << G4AttCheck(
1316 //                                               1316 //                                           attHolder->GetAttValues()[attHolder->GetAttDefs().size()-1],
1317 //                                               1317 //                                           attHolder->GetAttDefs()[attHolder->GetAttDefs().size()-1]);
1318 //                   }                           1318 //                   }
1319 //                   break;                      1319 //                   break;
1320 //                }                              1320 //                }
1321             }                                    1321             }
1322          }                                       1322          }
1323          This->setSuperimpositionEnabled(This    1323          This->setSuperimpositionEnabled(This->superimposition, TRUE);
1324          This->scheduleRedraw();                 1324          This->scheduleRedraw();
1325          eventCB->setHandled();                  1325          eventCB->setHandled();
1326          return;                                 1326          return;
1327       }                                          1327       }
1328                                                  1328 
1329       bool redraw = false;                       1329       bool redraw = false;
1330       if(std::string(This->mouseOverTextLogNa    1330       if(std::string(This->mouseOverTextLogName->string.getValues(0)->getString()) != sLogName) {
1331          This->mouseOverTextLogName->string.s    1331          This->mouseOverTextLogName->string.setValue(SbString(sLogName.c_str()));
1332          redraw = true;                          1332          redraw = true;
1333       }                                          1333       }
1334       if(std::string(This->mouseOverTextSolid    1334       if(std::string(This->mouseOverTextSolid->string.getValues(0)->getString()) != ssSolids.str()) {
1335          This->mouseOverTextSolid->string.set    1335          This->mouseOverTextSolid->string.setValue(SbString(ssSolids.str().c_str()));
1336          redraw = true;                          1336          redraw = true;
1337       }                                          1337       }
1338       if(std::string(This->mouseOverTextMater    1338       if(std::string(This->mouseOverTextMaterial->string.getValues(0)->getString()) != ssMaterials.str()){
1339          This->mouseOverTextMaterial->string.    1339          This->mouseOverTextMaterial->string.setValue(SbString(ssMaterials.str().c_str()));
1340          redraw = true;                          1340          redraw = true;
1341       }                                          1341       }
1342       if(std::string(This->mouseOverTextZPos-    1342       if(std::string(This->mouseOverTextZPos->string.getValues(0)->getString()) != ssZPos.str()) {
1343          This->mouseOverTextZPos->string.setV    1343          This->mouseOverTextZPos->string.setValue(SbString(ssZPos.str().c_str()));
1344          redraw = true;                          1344          redraw = true;
1345       }                                          1345       }
1346                                                  1346 
1347       if(redraw) {                               1347       if(redraw) {
1348          This->setSuperimpositionEnabled(This    1348          This->setSuperimpositionEnabled(This->superimposition, TRUE);
1349          This->scheduleRedraw();                 1349          This->scheduleRedraw();
1350       }                                          1350       }
1351                                                  1351 
1352       eventCB->setHandled();                     1352       eventCB->setHandled();
1353    }                                             1353    }
1354    else {                                        1354    else {
1355       if(std::string(This->mouseOverTextLogNa    1355       if(std::string(This->mouseOverTextLogName->string.getValues(0)->getString()) != "") {
1356          This->mouseOverTextLogName->string.s    1356          This->mouseOverTextLogName->string.setValue(SbString(""));
1357          This->scheduleRedraw();                 1357          This->scheduleRedraw();
1358       }                                          1358       }
1359       if(std::string(This->mouseOverTextSolid    1359       if(std::string(This->mouseOverTextSolid->string.getValues(0)->getString()) != "") {
1360          This->mouseOverTextSolid->string.set    1360          This->mouseOverTextSolid->string.setValue(SbString(""));
1361          This->scheduleRedraw();                 1361          This->scheduleRedraw();
1362       }                                          1362       }
1363       if(std::string(This->mouseOverTextMater    1363       if(std::string(This->mouseOverTextMaterial->string.getValues(0)->getString()) != "") {
1364          This->mouseOverTextMaterial->string.    1364          This->mouseOverTextMaterial->string.setValue(SbString(""));
1365          This->scheduleRedraw();                 1365          This->scheduleRedraw();
1366       }                                          1366       }
1367       if(std::string(This->mouseOverTextZPos-    1367       if(std::string(This->mouseOverTextZPos->string.getValues(0)->getString()) != "") {
1368          This->mouseOverTextZPos->string.setV    1368          This->mouseOverTextZPos->string.setValue(SbString(""));
1369          This->scheduleRedraw();                 1369          This->scheduleRedraw();
1370       }                                          1370       }
1371    }                                             1371    }
1372 }                                                1372 }
1373                                                  1373 
1374                                                  1374 
1375 SbBool G4OpenInventorXtExaminerViewer::proces    1375 SbBool G4OpenInventorXtExaminerViewer::processSoEvent(const SoEvent * const ev) {
1376    SoCamera *cam = getCamera();                  1376    SoCamera *cam = getCamera();
1377    const SoType type(ev->getTypeId());           1377    const SoType type(ev->getTypeId());
1378                                                  1378 
1379    if (type.isDerivedFrom(SoMouseButtonEvent:    1379    if (type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
1380       SoMouseButtonEvent * me = (SoMouseButto    1380       SoMouseButtonEvent * me = (SoMouseButtonEvent *) ev;
1381                                                  1381 
1382       if (currentState == ANIMATION || curren    1382       if (currentState == ANIMATION || currentState == REVERSED_ANIMATION
1383           || currentState == PAUSED_ANIMATION    1383           || currentState == PAUSED_ANIMATION) {
1384          switch (me->getButton()) {              1384          switch (me->getButton()) {
1385          case SoMouseButtonEvent::BUTTON4: //    1385          case SoMouseButtonEvent::BUTTON4: // Scroll wheel up
1386             if (me->getState() == SoButtonEve    1386             if (me->getState() == SoButtonEvent::DOWN) {
1387                if (cam->isOfType(SoPerspectiv    1387                if (cam->isOfType(SoPerspectiveCamera::getClassTypeId())) {
1388                   float hAngle =                 1388                   float hAngle =
1389                      ((SoPerspectiveCamera *)    1389                      ((SoPerspectiveCamera *) cam)->heightAngle.getValue();
1390                   ((SoPerspectiveCamera *) ca    1390                   ((SoPerspectiveCamera *) cam)->heightAngle = hAngle
1391                      + 0.01f;                    1391                      + 0.01f;
1392                   return TRUE;                   1392                   return TRUE;
1393                } else if (cam->isOfType(         1393                } else if (cam->isOfType(
1394                                         SoOrt    1394                                         SoOrthographicCamera::getClassTypeId())) {
1395                   float height =                 1395                   float height =
1396                      ((SoOrthographicCamera *    1396                      ((SoOrthographicCamera *) cam)->height.getValue();
1397                   ((SoOrthographicCamera *) c    1397                   ((SoOrthographicCamera *) cam)->height = height + 5;
1398                   return TRUE;                   1398                   return TRUE;
1399                }                                 1399                }
1400             }                                    1400             }
1401             break;                               1401             break;
1402          case SoMouseButtonEvent::BUTTON5: //    1402          case SoMouseButtonEvent::BUTTON5: // Scroll wheel down
1403             if (me->getState() == SoButtonEve    1403             if (me->getState() == SoButtonEvent::DOWN) {
1404                if (cam->isOfType(SoPerspectiv    1404                if (cam->isOfType(SoPerspectiveCamera::getClassTypeId())) {
1405                   float hAngle =                 1405                   float hAngle =
1406                      ((SoPerspectiveCamera *)    1406                      ((SoPerspectiveCamera *) cam)->heightAngle.getValue();
1407                   if (hAngle > 0.01)             1407                   if (hAngle > 0.01)
1408                      ((SoPerspectiveCamera *)    1408                      ((SoPerspectiveCamera *) cam)->heightAngle = hAngle
1409                         - 0.01f;                 1409                         - 0.01f;
1410                   return TRUE;                   1410                   return TRUE;
1411                } else if (cam->isOfType(         1411                } else if (cam->isOfType(
1412                                         SoOrt    1412                                         SoOrthographicCamera::getClassTypeId())) {
1413                   float height =                 1413                   float height =
1414                      ((SoOrthographicCamera *    1414                      ((SoOrthographicCamera *) cam)->height.getValue();
1415                   if (height > 5)                1415                   if (height > 5)
1416                      ((SoOrthographicCamera *    1416                      ((SoOrthographicCamera *) cam)->height = height - 5;
1417                   return TRUE;                   1417                   return TRUE;
1418                }                                 1418                }
1419             }                                    1419             }
1420             break;                               1420             break;
1421          default:                                1421          default:
1422             break;                               1422             break;
1423          }                                       1423          }
1424       }                                          1424       }
1425       if (currentState == GENERAL) {             1425       if (currentState == GENERAL) {
1426                                                  1426 
1427       }                                          1427       }
1428    }                                             1428    }
1429                                                  1429 
1430    if (type.isDerivedFrom(SoKeyboardEvent::ge    1430    if (type.isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
1431       SoKeyboardEvent * ke = (SoKeyboardEvent    1431       SoKeyboardEvent * ke = (SoKeyboardEvent *) ev;
1432                                                  1432 
1433       if (SoKeyboardEvent::isKeyPressEvent(ev    1433       if (SoKeyboardEvent::isKeyPressEvent(ev, ke->getKey())) {
1434          switch (ke->getKey()) {                 1434          switch (ke->getKey()) {
1435          case SoKeyboardEvent::LEFT_SHIFT:       1435          case SoKeyboardEvent::LEFT_SHIFT:
1436             this->lshiftdown = true;             1436             this->lshiftdown = true;
1437             return TRUE;                         1437             return TRUE;
1438          case SoKeyboardEvent::RIGHT_SHIFT:      1438          case SoKeyboardEvent::RIGHT_SHIFT:
1439             this->rshiftdown = true;             1439             this->rshiftdown = true;
1440             return TRUE;                         1440             return TRUE;
1441          case SoKeyboardEvent::LEFT_CONTROL:     1441          case SoKeyboardEvent::LEFT_CONTROL:
1442             this->lctrldown = true;              1442             this->lctrldown = true;
1443             return TRUE;                         1443             return TRUE;
1444          case SoKeyboardEvent::RIGHT_CONTROL:    1444          case SoKeyboardEvent::RIGHT_CONTROL:
1445             this->rctrldown = true;              1445             this->rctrldown = true;
1446             return TRUE;                         1446             return TRUE;
1447          case SoKeyboardEvent::SPACE:            1447          case SoKeyboardEvent::SPACE:
1448             if (currentState == ANIMATION        1448             if (currentState == ANIMATION
1449                 || currentState == REVERSED_A    1449                 || currentState == REVERSED_ANIMATION) {
1450                beforePausing = currentState;     1450                beforePausing = currentState;
1451                currentState = PAUSED_ANIMATIO    1451                currentState = PAUSED_ANIMATION;
1452                if (animateSensor->isScheduled    1452                if (animateSensor->isScheduled())
1453                   animateSensor->unschedule()    1453                   animateSensor->unschedule();
1454                return TRUE;                      1454                return TRUE;
1455             } else if (currentState == PAUSED    1455             } else if (currentState == PAUSED_ANIMATION) {
1456                if (maxSpeed) {                   1456                if (maxSpeed) {
1457                   if ((beforePausing == ANIMA    1457                   if ((beforePausing == ANIMATION
1458                        && refParticleIdx         1458                        && refParticleIdx
1459                        < (int) refParticleTra    1459                        < (int) refParticleTrajectory.size() - 1)
1460                       || (beforePausing == RE    1460                       || (beforePausing == REVERSED_ANIMATION
1461                           && refParticleIdx >    1461                           && refParticleIdx > 0)) {
1462                      currentState = beforePau    1462                      currentState = beforePausing;
1463                      animateRefParticle();       1463                      animateRefParticle();
1464                   }                              1464                   }
1465                }                                 1465                }
1466                return TRUE;                      1466                return TRUE;
1467             }                                    1467             }
1468             break;                               1468             break;
1469          case SoKeyboardEvent::ESCAPE:           1469          case SoKeyboardEvent::ESCAPE:
1470             if (currentState == ANIMATION        1470             if (currentState == ANIMATION
1471                 || currentState == REVERSED_A    1471                 || currentState == REVERSED_ANIMATION
1472                 || currentState == PAUSED_ANI    1472                 || currentState == PAUSED_ANIMATION) {
1473                                                  1473 
1474                if (animateSensor->isScheduled    1474                if (animateSensor->isScheduled())
1475                   animateSensor->unschedule()    1475                   animateSensor->unschedule();
1476                currentState = prevState;         1476                currentState = prevState;
1477                refParticleIdx = prevRefIdx;      1477                refParticleIdx = prevRefIdx;
1478                setSuperimpositionEnabled(supe    1478                setSuperimpositionEnabled(superimposition, FALSE);
1479                maxSpeed = 0.0f;                  1479                maxSpeed = 0.0f;
1480                step = 1;                         1480                step = 1;
1481                                                  1481 
1482                scheduleRedraw();                 1482                scheduleRedraw();
1483                if (currentState == VIEWPOINT)    1483                if (currentState == VIEWPOINT) {
1484                   setSuperimpositionEnabled(s    1484                   setSuperimpositionEnabled(superimposition, TRUE);
1485                   axisSwitch->whichChild.setV    1485                   axisSwitch->whichChild.setValue(SO_SWITCH_NONE);
1486                   animSpeedOutlineSwitch->whi    1486                   animSpeedOutlineSwitch->whichChild.setValue(
1487                                                  1487                                                               SO_SWITCH_NONE);
1488                   animSpeedSwitch->whichChild    1488                   animSpeedSwitch->whichChild.setValue(SO_SWITCH_NONE);
1489                                                  1489 
1490                   scheduleRedraw();              1490                   scheduleRedraw();
1491                }                                 1491                }
1492                restoreCamera();                  1492                restoreCamera();
1493                return TRUE;                      1493                return TRUE;
1494             }                                    1494             }
1495             break;                               1495             break;
1496          case SoKeyboardEvent::DELETE:           1496          case SoKeyboardEvent::DELETE:
1497             if (viewPtList.size()                1497             if (viewPtList.size()
1498                 && (currentState != ANIMATION    1498                 && (currentState != ANIMATION
1499                     && currentState != REVERS    1499                     && currentState != REVERSED_ANIMATION
1500                     && currentState != PAUSED    1500                     && currentState != PAUSED_ANIMATION)) {
1501                String dialogName = (char *) "    1501                String dialogName = (char *) "Delete Viewpoint";
1502                std::string msg = "Are you sur    1502                std::string msg = "Are you sure you want to delete current viewpoint?";
1503                warningMsgDialog(msg, dialogNa    1503                warningMsgDialog(msg, dialogName, deleteViewPtCB);
1504                return TRUE;                      1504                return TRUE;
1505             }                                    1505             }
1506             break;                               1506             break;
1507          case SoKeyboardEvent::LEFT_ARROW:       1507          case SoKeyboardEvent::LEFT_ARROW:
1508             switch (currentState) {              1508             switch (currentState) {
1509             case BEAMLINE:                       1509             case BEAMLINE:
1510                if ((this->lshiftdown) || (thi    1510                if ((this->lshiftdown) || (this->rshiftdown)){
1511                   refParticleIdx -= step;        1511                   refParticleIdx -= step;
1512                   moveCamera();                  1512                   moveCamera();
1513                }                                 1513                }
1514                else if ((this->lctrldown) ||     1514                else if ((this->lctrldown) || (this->rctrldown)){
1515                   if (SoXtExaminerViewer::isA    1515                   if (SoXtExaminerViewer::isAnimating())
1516                      stopAnimating();            1516                      stopAnimating();
1517                   prevState = currentState;      1517                   prevState = currentState;
1518                   currentState = ROTATING;       1518                   currentState = ROTATING;
1519                   animateBtwPtsPeriod = 0.08f    1519                   animateBtwPtsPeriod = 0.08f;
1520                                                  1520 
1521                   SbVec3f tmp = camDir;          1521                   SbVec3f tmp = camDir;
1522                   tmp.negate();                  1522                   tmp.negate();
1523                   rotAxis = tmp;                 1523                   rotAxis = tmp;
1524                                                  1524 
1525                   rotCnt = ROT_CNT;              1525                   rotCnt = ROT_CNT;
1526                   moveCamera(); // To make su    1526                   moveCamera(); // To make sure camera is perpendicular to the beamline
1527                                                  1527 
1528                   rotateCamera();                1528                   rotateCamera();
1529                }                                 1529                }
1530                else{                             1530                else{
1531                   if (SoXtExaminerViewer::isA    1531                   if (SoXtExaminerViewer::isAnimating())
1532                      stopAnimating();            1532                      stopAnimating();
1533                   prevState = currentState;      1533                   prevState = currentState;
1534                   currentState = ROTATING;       1534                   currentState = ROTATING;
1535                   animateBtwPtsPeriod = 0.08f    1535                   animateBtwPtsPeriod = 0.08f;
1536                                                  1536 
1537                   SbVec3f tmp = camUpVec;        1537                   SbVec3f tmp = camUpVec;
1538                   tmp.negate();                  1538                   tmp.negate();
1539                   rotAxis = tmp;                 1539                   rotAxis = tmp;
1540                                                  1540 
1541                   rotCnt = ROT_CNT;              1541                   rotCnt = ROT_CNT;
1542                   moveCamera(); // To make su    1542                   moveCamera(); // To make sure camera is perpendicular to the beamline
1543                                                  1543 
1544                   rotateCamera();                1544                   rotateCamera();
1545                                                  1545 
1546                }                                 1546                }
1547                return TRUE;                      1547                return TRUE;
1548                                                  1548 
1549             case ANIMATION:                      1549             case ANIMATION:
1550             case REVERSED_ANIMATION:             1550             case REVERSED_ANIMATION:
1551                left_right -= 1.5f;               1551                left_right -= 1.5f;
1552                return TRUE;                      1552                return TRUE;
1553             case PAUSED_ANIMATION:               1553             case PAUSED_ANIMATION:
1554                left_right -= 1.5f;               1554                left_right -= 1.5f;
1555                setStartingPtForAnimation();      1555                setStartingPtForAnimation();
1556                cam->position = myCam->positio    1556                cam->position = myCam->position;
1557                return TRUE;                      1557                return TRUE;
1558             case GENERAL:                        1558             case GENERAL:
1559             case VIEWPOINT:                      1559             case VIEWPOINT:
1560                if ((!this->lshiftdown) && (!t    1560                if ((!this->lshiftdown) && (!this->rshiftdown)) {
1561                   // Using this allows us to     1561                   // Using this allows us to look around without
1562                   // changing the camera para    1562                   // changing the camera parameters (camDir, camUpVec)
1563                   this->bottomWheelMotion(       1563                   this->bottomWheelMotion(
1564                                           thi    1564                                           this->getBottomWheelValue() + 0.1f);
1565                                                  1565 
1566                   return TRUE;                   1566                   return TRUE;
1567                }                                 1567                }
1568                break;                            1568                break;
1569             case ROTATING:                       1569             case ROTATING:
1570                // For this state, let the key    1570                // For this state, let the keyboard event
1571                // be handled by superclass       1571                // be handled by superclass
1572                break;                            1572                break;
1573             default:                             1573             default:
1574                SoDebugError::post("G4OpenInve    1574                SoDebugError::post("G4OpenInventorXtExaminerViewer::processSoEvent",
1575                                   "Unhandled     1575                                   "Unhandled viewer state");
1576                break;                            1576                break;
1577             }                                    1577             }
1578             break;                               1578             break;
1579                                                  1579 
1580          case SoKeyboardEvent::RIGHT_ARROW:      1580          case SoKeyboardEvent::RIGHT_ARROW:
1581             switch(currentState){                1581             switch(currentState){
1582             case BEAMLINE:                       1582             case BEAMLINE:
1583                if ((this->lshiftdown) || (thi    1583                if ((this->lshiftdown) || (this->rshiftdown)){
1584                   refParticleIdx += step;        1584                   refParticleIdx += step;
1585                   moveCamera();                  1585                   moveCamera();
1586                }                                 1586                }
1587                else if ((this->lctrldown) ||     1587                else if ((this->lctrldown) || (this->rctrldown)){
1588                   if (SoXtExaminerViewer::isA    1588                   if (SoXtExaminerViewer::isAnimating())
1589                      stopAnimating();            1589                      stopAnimating();
1590                   prevState = currentState;      1590                   prevState = currentState;
1591                   currentState = ROTATING;       1591                   currentState = ROTATING;
1592                   animateBtwPtsPeriod = 0.08f    1592                   animateBtwPtsPeriod = 0.08f;
1593                                                  1593 
1594                   rotAxis = camDir;              1594                   rotAxis = camDir;
1595                                                  1595 
1596                   rotCnt = ROT_CNT;              1596                   rotCnt = ROT_CNT;
1597                   moveCamera(); // To make su    1597                   moveCamera(); // To make sure camera is perpendicular to the beamline
1598                                                  1598 
1599                   rotateCamera();                1599                   rotateCamera();
1600                }                                 1600                }
1601                else{                             1601                else{
1602                   if (SoXtExaminerViewer::isA    1602                   if (SoXtExaminerViewer::isAnimating())
1603                      stopAnimating();            1603                      stopAnimating();
1604                   prevState = currentState;      1604                   prevState = currentState;
1605                   currentState = ROTATING;       1605                   currentState = ROTATING;
1606                   animateBtwPtsPeriod = 0.08f    1606                   animateBtwPtsPeriod = 0.08f;
1607                                                  1607 
1608                   rotAxis = camUpVec;            1608                   rotAxis = camUpVec;
1609                                                  1609 
1610                   rotCnt = ROT_CNT;              1610                   rotCnt = ROT_CNT;
1611                   moveCamera(); // To make su    1611                   moveCamera(); // To make sure camera is perpendicular to the beamline
1612                                                  1612 
1613                   rotateCamera();                1613                   rotateCamera();
1614                }                                 1614                }
1615                return TRUE;                      1615                return TRUE;
1616                                                  1616 
1617             case ANIMATION:                      1617             case ANIMATION:
1618             case REVERSED_ANIMATION:             1618             case REVERSED_ANIMATION:
1619                left_right += 1.5f;               1619                left_right += 1.5f;
1620                return TRUE;                      1620                return TRUE;
1621             case PAUSED_ANIMATION:               1621             case PAUSED_ANIMATION:
1622                left_right += 1.5f;               1622                left_right += 1.5f;
1623                setStartingPtForAnimation();      1623                setStartingPtForAnimation();
1624                cam->position = myCam->positio    1624                cam->position = myCam->position;
1625                return TRUE;                      1625                return TRUE;
1626             case GENERAL:                        1626             case GENERAL:
1627             case VIEWPOINT:                      1627             case VIEWPOINT:
1628                if ((!this->lshiftdown) && (!t    1628                if ((!this->lshiftdown) && (!this->rshiftdown)) {
1629                   // Using this allows us to     1629                   // Using this allows us to look around without
1630                   // changing the camera para    1630                   // changing the camera parameters (camDir, camUpVec)
1631                   this->bottomWheelMotion(       1631                   this->bottomWheelMotion(
1632                                           thi    1632                                           this->getBottomWheelValue() - 0.1f);
1633                   return TRUE;                   1633                   return TRUE;
1634                }                                 1634                }
1635                break;                            1635                break;
1636             case ROTATING:                       1636             case ROTATING:
1637                // For this state, let the key    1637                // For this state, let the keyboard event
1638                // be handled by superclass       1638                // be handled by superclass
1639                break;                            1639                break;
1640             default:                             1640             default:
1641                SoDebugError::post("G4OpenInve    1641                SoDebugError::post("G4OpenInventorXtExaminerViewer::processSoEvent",
1642                                   "Unhandled     1642                                   "Unhandled viewer state");
1643                break;                            1643                break;
1644             }                                    1644             }
1645             break;                               1645             break;
1646                                                  1646 
1647          case SoKeyboardEvent::DOWN_ARROW:       1647          case SoKeyboardEvent::DOWN_ARROW:
1648             switch(currentState){                1648             switch(currentState){
1649             case BEAMLINE:                       1649             case BEAMLINE:
1650                                                  1650 
1651                if ((this->lshiftdown) || (thi    1651                if ((this->lshiftdown) || (this->rshiftdown)){
1652                   refParticleIdx -= step;        1652                   refParticleIdx -= step;
1653                   moveCamera();                  1653                   moveCamera();
1654                }                                 1654                }
1655                else{                             1655                else{
1656                   if (SoXtExaminerViewer::isA    1656                   if (SoXtExaminerViewer::isAnimating())
1657                      stopAnimating();            1657                      stopAnimating();
1658                   prevState = currentState;      1658                   prevState = currentState;
1659                   currentState = ROTATING;       1659                   currentState = ROTATING;
1660                   animateBtwPtsPeriod = 0.08f    1660                   animateBtwPtsPeriod = 0.08f;
1661                                                  1661 
1662                   rotAxis = camDir.cross(camU    1662                   rotAxis = camDir.cross(camUpVec);
1663                                                  1663 
1664                   rotCnt = ROT_CNT;              1664                   rotCnt = ROT_CNT;
1665                   moveCamera(); // To make su    1665                   moveCamera(); // To make sure camera is perpendicular to the beamline
1666                                                  1666 
1667                   rotateCamera();                1667                   rotateCamera();
1668                                                  1668 
1669                }                                 1669                }
1670                return TRUE;                      1670                return TRUE;
1671                                                  1671 
1672             case ANIMATION:                      1672             case ANIMATION:
1673             case REVERSED_ANIMATION:             1673             case REVERSED_ANIMATION:
1674                up_down -= 1.5f;                  1674                up_down -= 1.5f;
1675                return TRUE;                      1675                return TRUE;
1676             case PAUSED_ANIMATION:               1676             case PAUSED_ANIMATION:
1677                up_down -= 1.5f;                  1677                up_down -= 1.5f;
1678                setStartingPtForAnimation();      1678                setStartingPtForAnimation();
1679                cam->position = myCam->positio    1679                cam->position = myCam->position;
1680                return TRUE;                      1680                return TRUE;
1681             case GENERAL:                        1681             case GENERAL:
1682             case VIEWPOINT:                      1682             case VIEWPOINT:
1683                // Using this allows us to loo    1683                // Using this allows us to look around without
1684                // changing the camera paramet    1684                // changing the camera parameters (camDir, camUpVec)
1685                if ((!this->lshiftdown) && (!t    1685                if ((!this->lshiftdown) && (!this->rshiftdown)) {
1686                   this->leftWheelMotion(this-    1686                   this->leftWheelMotion(this->getLeftWheelValue() - 0.1f);
1687                   return TRUE;                   1687                   return TRUE;
1688                }                                 1688                }
1689                break;                            1689                break;
1690             case ROTATING:                       1690             case ROTATING:
1691                // For this state, let the key    1691                // For this state, let the keyboard event
1692                // be handled by superclass       1692                // be handled by superclass
1693                break;                            1693                break;
1694             default:                             1694             default:
1695                SoDebugError::post("G4OpenInve    1695                SoDebugError::post("G4OpenInventorXtExaminerViewer::processSoEvent",
1696                                   "Unhandled     1696                                   "Unhandled viewer state");
1697                break;                            1697                break;
1698             }                                    1698             }
1699             break;                               1699             break;
1700                                                  1700 
1701          case SoKeyboardEvent::UP_ARROW:         1701          case SoKeyboardEvent::UP_ARROW:
1702             switch(currentState){                1702             switch(currentState){
1703             case BEAMLINE:                       1703             case BEAMLINE:
1704                if ((this->lshiftdown) || (thi    1704                if ((this->lshiftdown) || (this->rshiftdown)){
1705                   refParticleIdx -= step;        1705                   refParticleIdx -= step;
1706                   moveCamera();                  1706                   moveCamera();
1707                }                                 1707                }
1708                else{                             1708                else{
1709                   if (SoXtExaminerViewer::isA    1709                   if (SoXtExaminerViewer::isAnimating())
1710                      stopAnimating();            1710                      stopAnimating();
1711                   prevState = currentState;      1711                   prevState = currentState;
1712                   currentState = ROTATING;       1712                   currentState = ROTATING;
1713                   animateBtwPtsPeriod = 0.08f    1713                   animateBtwPtsPeriod = 0.08f;
1714                                                  1714 
1715                   rotAxis = camUpVec.cross(ca    1715                   rotAxis = camUpVec.cross(camDir);
1716                                                  1716 
1717                   rotCnt = ROT_CNT;              1717                   rotCnt = ROT_CNT;
1718                   moveCamera();                  1718                   moveCamera();
1719                                                  1719 
1720                   rotateCamera();                1720                   rotateCamera();
1721                                                  1721 
1722                                                  1722 
1723                }                                 1723                }
1724                return TRUE;                      1724                return TRUE;
1725             case ANIMATION:                      1725             case ANIMATION:
1726             case REVERSED_ANIMATION:             1726             case REVERSED_ANIMATION:
1727                up_down += 1.5f;                  1727                up_down += 1.5f;
1728                return TRUE;                      1728                return TRUE;
1729             case PAUSED_ANIMATION:               1729             case PAUSED_ANIMATION:
1730                up_down += 1.5f;                  1730                up_down += 1.5f;
1731                setStartingPtForAnimation();      1731                setStartingPtForAnimation();
1732                cam->position = myCam->positio    1732                cam->position = myCam->position;
1733                return TRUE;                      1733                return TRUE;
1734             case GENERAL:                        1734             case GENERAL:
1735             case VIEWPOINT:                      1735             case VIEWPOINT:
1736                // Using this allows us to loo    1736                // Using this allows us to look around without
1737                // changing the camera paramet    1737                // changing the camera parameters (camDir, camUpVec)
1738                if ((!this->lshiftdown) && (!t    1738                if ((!this->lshiftdown) && (!this->rshiftdown)) {
1739                   this->leftWheelMotion(this-    1739                   this->leftWheelMotion(this->getLeftWheelValue() + 0.1f);
1740                   return TRUE;                   1740                   return TRUE;
1741                }                                 1741                }
1742                break;                            1742                break;
1743             case ROTATING:                       1743             case ROTATING:
1744                // For this state, let the key    1744                // For this state, let the keyboard event
1745                // be handled by superclass       1745                // be handled by superclass
1746                break;                            1746                break;
1747             default:                             1747             default:
1748                SoDebugError::post("G4OpenInve    1748                SoDebugError::post("G4OpenInventorXtExaminerViewer::processSoEvent",
1749                                   "Unhandled     1749                                   "Unhandled viewer state");
1750                break;                            1750                break;
1751             }                                    1751             }
1752             break;                               1752             break;
1753                                                  1753 
1754          case SoKeyboardEvent::PAGE_UP:          1754          case SoKeyboardEvent::PAGE_UP:
1755             switch(currentState){                1755             switch(currentState){
1756             case BEAMLINE:                       1756             case BEAMLINE:
1757                if (step < (int) refParticleTr    1757                if (step < (int) refParticleTrajectory.size() / 5) // Magic number
1758                   step++;                        1758                   step++;
1759                return TRUE;                      1759                return TRUE;
1760             case ANIMATION:                      1760             case ANIMATION:
1761                incSpeed();                       1761                incSpeed();
1762                maxSpeed += SPEED_INDICATOR_ST    1762                maxSpeed += SPEED_INDICATOR_STEP;
1763                if (maxSpeed > 0.8)               1763                if (maxSpeed > 0.8)
1764                   maxSpeed = MAX_SPEED_INDICA    1764                   maxSpeed = MAX_SPEED_INDICATOR;
1765                scheduleRedraw();                 1765                scheduleRedraw();
1766                                                  1766 
1767                return TRUE;                      1767                return TRUE;
1768             case REVERSED_ANIMATION:             1768             case REVERSED_ANIMATION:
1769                if(!animateSensor->isScheduled    1769                if(!animateSensor->isScheduled()){
1770                   currentState = ANIMATION;      1770                   currentState = ANIMATION;
1771                   if (refParticleIdx             1771                   if (refParticleIdx
1772                       < (int) refParticleTraj    1772                       < (int) refParticleTrajectory.size() - 1) {
1773                      refParticleIdx++;           1773                      refParticleIdx++;
1774                      maxSpeed = SPEED_INDICAT    1774                      maxSpeed = SPEED_INDICATOR_STEP;
1775                      scheduleRedraw();           1775                      scheduleRedraw();
1776                      animateRefParticle();       1776                      animateRefParticle();
1777                   }                              1777                   }
1778                }                                 1778                }
1779                else{                             1779                else{
1780                   maxSpeed += SPEED_INDICATOR    1780                   maxSpeed += SPEED_INDICATOR_STEP;
1781                   decSpeed();                    1781                   decSpeed();
1782                   scheduleRedraw();              1782                   scheduleRedraw();
1783                }                                 1783                }
1784                return TRUE;                      1784                return TRUE;
1785             case PAUSED_ANIMATION:               1785             case PAUSED_ANIMATION:
1786                maxSpeed += SPEED_INDICATOR_ST    1786                maxSpeed += SPEED_INDICATOR_STEP;
1787                if (maxSpeed > 0.8)               1787                if (maxSpeed > 0.8)
1788                   maxSpeed = MAX_SPEED_INDICA    1788                   maxSpeed = MAX_SPEED_INDICATOR;
1789                                                  1789 
1790                if (beforePausing == ANIMATION    1790                if (beforePausing == ANIMATION) {
1791                   incSpeed();                    1791                   incSpeed();
1792                } else {                          1792                } else {
1793                   decSpeed();                    1793                   decSpeed();
1794                   if (animateBtwPtsPeriod >=     1794                   if (animateBtwPtsPeriod >= MIN_SPEED)
1795                      beforePausing = ANIMATIO    1795                      beforePausing = ANIMATION;
1796                }                                 1796                }
1797                                                  1797 
1798                scheduleRedraw();                 1798                scheduleRedraw();
1799                return TRUE;                      1799                return TRUE;
1800             default:  //fall through             1800             default:  //fall through
1801                break;                            1801                break;
1802             }                                    1802             }
1803             break;                               1803             break;
1804                                                  1804 
1805          case SoKeyboardEvent::PAGE_DOWN:        1805          case SoKeyboardEvent::PAGE_DOWN:
1806             switch(currentState){                1806             switch(currentState){
1807             case BEAMLINE:                       1807             case BEAMLINE:
1808                if (step > 1)                     1808                if (step > 1)
1809                   step--;                        1809                   step--;
1810                return TRUE;                      1810                return TRUE;
1811             case ANIMATION:                      1811             case ANIMATION:
1812                if(!animateSensor->isScheduled    1812                if(!animateSensor->isScheduled()){
1813                   currentState = REVERSED_ANI    1813                   currentState = REVERSED_ANIMATION;
1814                   if (refParticleIdx > 1) {      1814                   if (refParticleIdx > 1) {
1815                      refParticleIdx--;           1815                      refParticleIdx--;
1816                      maxSpeed = -SPEED_INDICA    1816                      maxSpeed = -SPEED_INDICATOR_STEP;
1817                      scheduleRedraw();           1817                      scheduleRedraw();
1818                      animateRefParticle();       1818                      animateRefParticle();
1819                   }                              1819                   }
1820                }                                 1820                }
1821                else{                             1821                else{
1822                   maxSpeed -= SPEED_INDICATOR    1822                   maxSpeed -= SPEED_INDICATOR_STEP;
1823                   decSpeed();                    1823                   decSpeed();
1824                   scheduleRedraw();              1824                   scheduleRedraw();
1825                }                                 1825                }
1826                return TRUE;                      1826                return TRUE;
1827             case REVERSED_ANIMATION:             1827             case REVERSED_ANIMATION:
1828                incSpeed();                       1828                incSpeed();
1829                maxSpeed -= SPEED_INDICATOR_ST    1829                maxSpeed -= SPEED_INDICATOR_STEP;
1830                if (maxSpeed < -0.8)              1830                if (maxSpeed < -0.8)
1831                   maxSpeed = -MAX_SPEED_INDIC    1831                   maxSpeed = -MAX_SPEED_INDICATOR;
1832                scheduleRedraw();                 1832                scheduleRedraw();
1833                return TRUE;                      1833                return TRUE;
1834             case PAUSED_ANIMATION:               1834             case PAUSED_ANIMATION:
1835                maxSpeed -= SPEED_INDICATOR_ST    1835                maxSpeed -= SPEED_INDICATOR_STEP;
1836                if (maxSpeed < -0.8)              1836                if (maxSpeed < -0.8)
1837                   maxSpeed = -MAX_SPEED_INDIC    1837                   maxSpeed = -MAX_SPEED_INDICATOR;
1838                if (beforePausing == REVERSED_    1838                if (beforePausing == REVERSED_ANIMATION) {
1839                   incSpeed();                    1839                   incSpeed();
1840                } else {                          1840                } else {
1841                   decSpeed();                    1841                   decSpeed();
1842                   if (animateBtwPtsPeriod >=     1842                   if (animateBtwPtsPeriod >= MIN_SPEED)
1843                      beforePausing = REVERSED    1843                      beforePausing = REVERSED_ANIMATION;
1844                }                                 1844                }
1845                scheduleRedraw();                 1845                scheduleRedraw();
1846                return TRUE;                      1846                return TRUE;
1847             default:                             1847             default:
1848                //fall through                    1848                //fall through
1849                break;                            1849                break;
1850             }                                    1850             }
1851             break;                               1851             break;
1852                                                  1852 
1853          case SoKeyboardEvent::E:                1853          case SoKeyboardEvent::E:
1854             this->escapeCallback(this->examin    1854             this->escapeCallback(this->examinerObject);
1855             break;                               1855             break;
1856                                                  1856 
1857          default:                                1857          default:
1858             break; // To get rid of compiler     1858             break; // To get rid of compiler warnings
1859          }                                       1859          }
1860       }                                          1860       }
1861       if (SoKeyboardEvent::isKeyReleaseEvent(    1861       if (SoKeyboardEvent::isKeyReleaseEvent(ev, ke->getKey())) {
1862          switch (ke->getKey()) {                 1862          switch (ke->getKey()) {
1863          case SoKeyboardEvent::LEFT_SHIFT:       1863          case SoKeyboardEvent::LEFT_SHIFT:
1864             this->lshiftdown = false;            1864             this->lshiftdown = false;
1865             return TRUE;                         1865             return TRUE;
1866          case SoKeyboardEvent::RIGHT_SHIFT:      1866          case SoKeyboardEvent::RIGHT_SHIFT:
1867             this->rshiftdown = false;            1867             this->rshiftdown = false;
1868             return TRUE;                         1868             return TRUE;
1869          case SoKeyboardEvent::LEFT_CONTROL:     1869          case SoKeyboardEvent::LEFT_CONTROL:
1870             this->lctrldown = false;             1870             this->lctrldown = false;
1871             return TRUE;                         1871             return TRUE;
1872          case SoKeyboardEvent::RIGHT_CONTROL:    1872          case SoKeyboardEvent::RIGHT_CONTROL:
1873             this->rctrldown = false;             1873             this->rctrldown = false;
1874             return TRUE;                         1874             return TRUE;
1875          default:                                1875          default:
1876             break;                               1876             break;
1877          }                                       1877          }
1878       }                                          1878       }
1879    }                                             1879    }
1880                                                  1880 
1881    if (currentState == ANIMATION || currentSt    1881    if (currentState == ANIMATION || currentState == REVERSED_ANIMATION
1882        || currentState == ROTATING)              1882        || currentState == ROTATING)
1883       return FALSE;                              1883       return FALSE;
1884    else                                          1884    else
1885       return SoXtExaminerViewer::processSoEve    1885       return SoXtExaminerViewer::processSoEvent(ev);
1886 }                                                1886 }
1887                                                  1887 
1888 // Called by hitting PageUp during animation.    1888 // Called by hitting PageUp during animation.
1889 void G4OpenInventorXtExaminerViewer::incSpeed    1889 void G4OpenInventorXtExaminerViewer::incSpeed() {
1890   if (std::ceil(animateBtwPtsPeriod * 100) >=    1890   if (std::ceil(animateBtwPtsPeriod * 100) >= 4) {
1891     if (speedStep > 0.08)                        1891     if (speedStep > 0.08)
1892       speedStep -= 0.02;                         1892       speedStep -= 0.02;
1893     else                                         1893     else
1894       speedStep = 0.02;                          1894       speedStep = 0.02;
1895     animateBtwPtsPeriod -= speedStep;            1895     animateBtwPtsPeriod -= speedStep;
1896   } else                                         1896   } else
1897     animateBtwPtsPeriod = 0.0;                   1897     animateBtwPtsPeriod = 0.0;
1898                                                  1898 
1899   if (currentState != PAUSED_ANIMATION) {        1899   if (currentState != PAUSED_ANIMATION) {
1900     int lastIdx = refParticleTrajectory.size(    1900     int lastIdx = refParticleTrajectory.size() - 1;
1901     if (refParticleIdx < lastIdx && !animateS    1901     if (refParticleIdx < lastIdx && !animateSensor->isScheduled())
1902       animateRefParticle();                      1902       animateRefParticle();
1903   }                                              1903   }
1904 }                                                1904 }
1905                                                  1905 
1906 // Called by hitting PageDown during animatio    1906 // Called by hitting PageDown during animation.
1907 void G4OpenInventorXtExaminerViewer::decSpeed    1907 void G4OpenInventorXtExaminerViewer::decSpeed() {
1908   animateBtwPtsPeriod += speedStep;              1908   animateBtwPtsPeriod += speedStep;
1909   if (animateBtwPtsPeriod < MIN_SPEED) {         1909   if (animateBtwPtsPeriod < MIN_SPEED) {
1910     if (std::floor(animateBtwPtsPeriod * 100)    1910     if (std::floor(animateBtwPtsPeriod * 100) == 12) { // Errors in double representation
1911       speedStep = 0.08;                          1911       speedStep = 0.08;
1912     } else if (animateBtwPtsPeriod > 0.12)       1912     } else if (animateBtwPtsPeriod > 0.12)
1913       speedStep += 0.02;                         1913       speedStep += 0.02;
1914   } else {                                       1914   } else {
1915     animateBtwPtsPeriod = MIN_SPEED;             1915     animateBtwPtsPeriod = MIN_SPEED;
1916     speedStep = START_STEP;                      1916     speedStep = START_STEP;
1917     maxSpeed = 0.0f;                             1917     maxSpeed = 0.0f;
1918     if (animateSensor->isScheduled())            1918     if (animateSensor->isScheduled())
1919       animateSensor->unschedule();               1919       animateSensor->unschedule();
1920   }                                              1920   }
1921 }                                                1921 }
1922                                                  1922 
1923 // Based on the user's interaction the speed     1923 // Based on the user's interaction the speed indicator bar needs to be adjusted.
1924 void G4OpenInventorXtExaminerViewer::updateSp    1924 void G4OpenInventorXtExaminerViewer::updateSpeedIndicator(void) {
1925   assert(this->sgeometry != NULL);               1925   assert(this->sgeometry != NULL);
1926                                                  1926 
1927   SbVec3f * points = this->sgeometry->point.s    1927   SbVec3f * points = this->sgeometry->point.startEditing();
1928                                                  1928 
1929   if (points[10][0] == 0.0f)                     1929   if (points[10][0] == 0.0f)
1930     this->animSpeedOutlineSwitch->whichChild.    1930     this->animSpeedOutlineSwitch->whichChild.setValue(SO_SWITCH_ALL);
1931   if (points[14][0] == 0.0f)                     1931   if (points[14][0] == 0.0f)
1932     this->animSpeedSwitch->whichChild.setValu    1932     this->animSpeedSwitch->whichChild.setValue(SO_SWITCH_ALL);
1933   points[10][0] = this->maxSpeed;                1933   points[10][0] = this->maxSpeed;
1934   points[11][0] = this->maxSpeed;                1934   points[11][0] = this->maxSpeed;
1935   points[14][0] = this->maxSpeed;                1935   points[14][0] = this->maxSpeed;
1936   points[15][0] = this->maxSpeed;                1936   points[15][0] = this->maxSpeed;
1937   this->sgeometry->point.finishEditing();        1937   this->sgeometry->point.finishEditing();
1938                                                  1938 
1939   if (this->maxSpeed == 0.0f) {                  1939   if (this->maxSpeed == 0.0f) {
1940     this->animSpeedOutlineSwitch->whichChild.    1940     this->animSpeedOutlineSwitch->whichChild.setValue(SO_SWITCH_NONE);
1941     this->animSpeedSwitch->whichChild.setValu    1941     this->animSpeedSwitch->whichChild.setValue(SO_SWITCH_NONE);
1942   }                                              1942   }
1943 }                                                1943 }
1944                                                  1944 
1945 void G4OpenInventorXtExaminerViewer::actualRe    1945 void G4OpenInventorXtExaminerViewer::actualRedraw(void) {
1946   switch (currentState) {                        1946   switch (currentState) {
1947   case ANIMATION:                                1947   case ANIMATION:
1948   case REVERSED_ANIMATION:                       1948   case REVERSED_ANIMATION:
1949   case PAUSED_ANIMATION:                         1949   case PAUSED_ANIMATION:
1950     updateSpeedIndicator();                      1950     updateSpeedIndicator();
1951     SoXtExaminerViewer::actualRedraw();          1951     SoXtExaminerViewer::actualRedraw();
1952     break;                                       1952     break;
1953   default:                                       1953   default:
1954     SoXtExaminerViewer::actualRedraw();          1954     SoXtExaminerViewer::actualRedraw();
1955     break;                                       1955     break;
1956   }                                              1956   }
1957 }                                                1957 }
1958                                                  1958 
1959 void G4OpenInventorXtExaminerViewer::setRefer    1959 void G4OpenInventorXtExaminerViewer::setReferencePath(SoLineSet *lineset, SoCoordinate3 *coords, bool append)
1960 {                                                1960 {
1961    // TODO:  Color the reference path            1961    // TODO:  Color the reference path
1962    // Disable the color stuff for now: change    1962    // Disable the color stuff for now: changes all trajectories
1963                                                  1963 
1964 // // We change the color of the trajectory t    1964 // // We change the color of the trajectory too, so we get its material
1965 //  nodeIndex = grpNode->findChild(trajectory    1965 //  nodeIndex = grpNode->findChild(trajectory);
1966 //  SoMaterial * mat;                            1966 //  SoMaterial * mat;
1967 //  for(int i = 0; i < 100; ++i){                1967 //  for(int i = 0; i < 100; ++i){
1968 //    --nodeIndex;                               1968 //    --nodeIndex;
1969 //                                               1969 //
1970 //    tmpNode = grpNode->getChild(nodeIndex);    1970 //    tmpNode = grpNode->getChild(nodeIndex);
1971 //    if(tmpNode->getTypeId() == SoMaterial::    1971 //    if(tmpNode->getTypeId() == SoMaterial::getClassTypeId()){
1972 //      //node found                             1972 //      //node found
1973 //      mat = (SoMaterial *)tmpNode;             1973 //      mat = (SoMaterial *)tmpNode;
1974 //                                               1974 //
1975 //      break;                                   1975 //      break;
1976 //    }                                          1976 //    }
1977 //  }                                            1977 //  }
1978 //                                               1978 //
1979 //                                               1979 //
1980 // // Restore default color for previously pi    1980 // // Restore default color for previously picked trajectory
1981 // // and set different color for current pic    1981 // // and set different color for current pick
1982 //  if(This->prevColorField)                     1982 //  if(This->prevColorField)
1983 //    ((SoMFColor *)This->prevColorField)->se    1983 //    ((SoMFColor *)This->prevColorField)->setValue(0.0, 1.0, 0.0);
1984 //  This->prevColorField = (void *)&mat->diff    1984 //  This->prevColorField = (void *)&mat->diffuseColor;
1985 //                                               1985 //
1986 //                                               1986 //
1987 //  if(mat->diffuseColor.isConnected())          1987 //  if(mat->diffuseColor.isConnected())
1988 //    std::cout << "connected" << std::endl;     1988 //    std::cout << "connected" << std::endl;
1989 //                                               1989 //
1990 //  mat->diffuseColor.setValue(41.0/255.0, 23    1990 //  mat->diffuseColor.setValue(41.0/255.0, 230.0/255.0, 230.0/255.0);
1991 //                                               1991 //
1992 //  std::cout << "R: " << mat->diffuseColor[0    1992 //  std::cout << "R: " << mat->diffuseColor[0][0] << " ";
1993 //  std::cout << "G: " << mat->diffuseColor[0    1993 //  std::cout << "G: " << mat->diffuseColor[0][1] << " ";
1994 //  std::cout << "B: " << mat->diffuseColor[0    1994 //  std::cout << "B: " << mat->diffuseColor[0][2] << std::endl;
1995                                                  1995 
1996    // The trajectory is composed of all the p    1996    // The trajectory is composed of all the polyline segments in the
1997    // multiple value field (SoMFInt32) numVer    1997    // multiple value field (SoMFInt32) numVertices.
1998    // For each of the numVertices.getNum()* p    1998    // For each of the numVertices.getNum()* polyline segments,
1999    // retrieve the points from the SoCoordina    1999    // retrieve the points from the SoCoordinate3 node
2000    SbVec3f refParticlePt;                        2000    SbVec3f refParticlePt;
2001                                                  2001 
2002    if(!append)                                   2002    if(!append)
2003       this->refParticleTrajectory.clear();       2003       this->refParticleTrajectory.clear();
2004                                                  2004 
2005    for(int i = 0; i < lineset->numVertices.ge    2005    for(int i = 0; i < lineset->numVertices.getNum(); ++i){
2006       for(int j = 0; j < lineset->numVertices    2006       for(int j = 0; j < lineset->numVertices[i]; ++j){
2007          refParticlePt = coords->point[j];       2007          refParticlePt = coords->point[j];
2008          this->refParticleTrajectory.push_bac    2008          this->refParticleTrajectory.push_back(refParticlePt);
2009       }                                          2009       }
2010    }                                             2010    }
2011    // Remove points that are too close to eac    2011    // Remove points that are too close to each other
2012    this->evenOutRefParticlePts();                2012    this->evenOutRefParticlePts();
2013    this->setReferencePathZPos();                 2013    this->setReferencePathZPos();
2014    this->sortElements();                         2014    this->sortElements();
2015 }                                                2015 }
2016                                                  2016 
2017                                                  2017 
2018 void G4OpenInventorXtExaminerViewer::setRefer    2018 void G4OpenInventorXtExaminerViewer::setReferencePathZPos()
2019 {                                                2019 {
2020    refZPositions.clear();                        2020    refZPositions.clear();
2021    refZPositions.push_back(0);                   2021    refZPositions.push_back(0);
2022    float dist;                                   2022    float dist;
2023    for(unsigned int i=0; i < this->refParticl    2023    for(unsigned int i=0; i < this->refParticleTrajectory.size() - 1; ++i){
2024       dist = (refParticleTrajectory[i] -         2024       dist = (refParticleTrajectory[i] - 
2025               refParticleTrajectory[i + 1]).l    2025               refParticleTrajectory[i + 1]).length();
2026       refZPositions.push_back(refZPositions[i    2026       refZPositions.push_back(refZPositions[i] + dist);
2027    }                                             2027    }
2028 }                                                2028 }
2029                                                  2029 
2030                                                  2030 
2031 void G4OpenInventorXtExaminerViewer::findAndS    2031 void G4OpenInventorXtExaminerViewer::findAndSetRefPath()
2032 {                                                2032 {
2033    SoSearchAction action;                        2033    SoSearchAction action;
2034    action.setType(SoLineSet::getClassTypeId()    2034    action.setType(SoLineSet::getClassTypeId(),false);
2035    action.setInterest(SoSearchAction::ALL);      2035    action.setInterest(SoSearchAction::ALL);
2036    action.apply(this->getSceneGraph());          2036    action.apply(this->getSceneGraph());
2037                                                  2037 
2038    SoPathList &pathList = action.getPaths();     2038    SoPathList &pathList = action.getPaths();
2039                                                  2039 
2040    if(pathList.getLength() != 0){                2040    if(pathList.getLength() != 0){
2041                                                  2041 
2042       SoCoordinate3 * coords = NULL;             2042       SoCoordinate3 * coords = NULL;
2043       std::vector<SoCoordinate3 *> coordvec;     2043       std::vector<SoCoordinate3 *> coordvec;
2044       std::vector<SoLineSet *> linevec;          2044       std::vector<SoLineSet *> linevec;
2045                                                  2045 
2046       bool refPathFound = false;                 2046       bool refPathFound = false;
2047       for(int i = 0; i < pathList.getLength()    2047       for(int i = 0; i < pathList.getLength(); ++i) {
2048          SoFullPath *path = (SoFullPath *)pat    2048          SoFullPath *path = (SoFullPath *)pathList[i];
2049                                                  2049 
2050          G4AttHolder* attHolder = dynamic_cas    2050          G4AttHolder* attHolder = dynamic_cast<G4AttHolder*>(path->getTail());
2051          for (size_t j = 0; j < attHolder->Ge    2051          for (size_t j = 0; j < attHolder->GetAttDefs().size(); ++j) {
2052             std::ostringstream oss;              2052             std::ostringstream oss;
2053             oss << G4AttCheck(attHolder->GetA    2053             oss << G4AttCheck(attHolder->GetAttValues()[j], attHolder->GetAttDefs()[j]);
2054                                                  2054 
2055             std::string findStr = "Type of tr    2055             std::string findStr = "Type of trajectory (Type): ";
2056             std::string compareValue = "REFER    2056             std::string compareValue = "REFERENCE";
2057             size_t idx = oss.str().find(findS    2057             size_t idx = oss.str().find(findStr);
2058                                                  2058 
2059             if(idx != std::string::npos) {       2059             if(idx != std::string::npos) {
2060                if(oss.str().substr(idx + find    2060                if(oss.str().substr(idx + findStr.size(), compareValue.size()) == compareValue) {
2061                   coords = this->getCoordsNod    2061                   coords = this->getCoordsNode(path);
2062                   if(coords != NULL){            2062                   if(coords != NULL){
2063                      refPathFound = true;        2063                      refPathFound = true;
2064                      coordvec.push_back(coord    2064                      coordvec.push_back(coords);
2065                      linevec.push_back((SoLin    2065                      linevec.push_back((SoLineSet *)path->getTail());
2066                   }                              2066                   }
2067                   break;                         2067                   break;
2068                }                                 2068                }
2069             }                                    2069             }
2070                                                  2070 
2071             findStr = "Track ID (ID): ";         2071             findStr = "Track ID (ID): ";
2072             idx = oss.str().find(findStr);       2072             idx = oss.str().find(findStr);
2073             if(idx != std::string::npos) {       2073             if(idx != std::string::npos) {
2074                //index all primary tracks        2074                //index all primary tracks
2075                std::string tmpstr = oss.str()    2075                std::string tmpstr = oss.str().substr(idx + findStr.size(),1);
2076                std::istringstream buffer(tmps    2076                std::istringstream buffer(tmpstr);
2077                int num;                          2077                int num;
2078                buffer >> num;                    2078                buffer >> num;
2079                if(num == 1) {                    2079                if(num == 1) {
2080                                                  2080 
2081                   // Check if next character     2081                   // Check if next character is a number, 
2082                   // in which case we don't h    2082                   // in which case we don't have Track ID 1
2083                   // FWJ attempt to fix Cover    2083                   // FWJ attempt to fix Coverity issue.
2084                   char nextChar = oss.str().a    2084                   char nextChar = oss.str().at(idx+findStr.size()+1);
2085                   // const char * nextChar =     2085                   // const char * nextChar = 
2086                   // oss.str().substr(idx + f    2086                   // oss.str().substr(idx + findStr.size() + 1,1).c_str();
2087                   if(std::isdigit(nextChar))     2087                   if(std::isdigit(nextChar))
2088                   // if(std::isdigit(nextChar    2088                   // if(std::isdigit(nextChar[0]))
2089                      break; //Not a primary t    2089                      break; //Not a primary track, continue with next track
2090                                                  2090 
2091                   coords = this->getCoordsNod    2091                   coords = this->getCoordsNode(path);
2092                   if(coords != NULL){            2092                   if(coords != NULL){
2093                      coordvec.push_back(coord    2093                      coordvec.push_back(coords);
2094                      linevec.push_back((SoLin    2094                      linevec.push_back((SoLineSet *)path->getTail());
2095                      break; //Found coords no    2095                      break; //Found coords node, continue with next track
2096                   }                              2096                   }
2097                }                                 2097                }
2098                else                              2098                else
2099                   break;  //Not a primary tra    2099                   break;  //Not a primary track, continue with next track
2100             }                                    2100             }
2101             else{                                2101             else{
2102                //Not a Track ID attribute, fa    2102                //Not a Track ID attribute, fall through
2103             }                                    2103             }
2104          }                                       2104          }
2105                                                  2105 
2106          if(refPathFound)                        2106          if(refPathFound)
2107             break;                               2107             break;
2108       }                                          2108       }
2109                                                  2109 
2110       if(coordvec.empty())                       2110       if(coordvec.empty())
2111          return;    //No track with a Coordin    2111          return;    //No track with a Coordinate3 node found
2112                                                  2112 
2113       if(refPathFound){                          2113       if(refPathFound){
2114          //set ref path to last traj, coord i    2114          //set ref path to last traj, coord in the vecs
2115          this->setReferencePath(linevec.back(    2115          this->setReferencePath(linevec.back(), coordvec.back());
2116          return;                                 2116          return;
2117       }                                          2117       }
2118       //else                                     2118       //else
2119                                                  2119 
2120       int longestIdx = 0;                        2120       int longestIdx = 0;
2121       float longestLength = 0.0;                 2121       float longestLength = 0.0;
2122       // For all paths                           2122       // For all paths
2123       for(unsigned int i=0;i < linevec.size()    2123       for(unsigned int i=0;i < linevec.size(); ++i){
2124                                                  2124 
2125          //First generate a vector with all t    2125          //First generate a vector with all the points in this lineset
2126          std::vector<SbVec3f> trajectory;        2126          std::vector<SbVec3f> trajectory;
2127          // For all lines in the i path          2127          // For all lines in the i path
2128          for(int j=0; j < linevec[i]->numVert    2128          for(int j=0; j < linevec[i]->numVertices.getNum(); ++j){
2129             // For all points in line j          2129             // For all points in line j
2130             for(int k=0; k < linevec[i]->numV    2130             for(int k=0; k < linevec[i]->numVertices[j]; ++k){
2131                trajectory.push_back(coordvec[    2131                trajectory.push_back(coordvec[i]->point[k]);
2132             }                                    2132             }
2133          }                                       2133          }
2134                                                  2134 
2135          // Then calculate the total length      2135          // Then calculate the total length
2136          float tmpLength=0.0;                    2136          float tmpLength=0.0;
2137          for(unsigned int j=0; j < trajectory    2137          for(unsigned int j=0; j < trajectory.size() - 1; ++j){
2138             tmpLength += (trajectory[j] - tra    2138             tmpLength += (trajectory[j] - trajectory[j + 1]).length();
2139          }                                       2139          }
2140                                                  2140 
2141          if(tmpLength > longestLength){          2141          if(tmpLength > longestLength){
2142             longestIdx = i;                      2142             longestIdx = i;
2143             longestLength = tmpLength;           2143             longestLength = tmpLength;
2144          }                                       2144          }
2145       }                                          2145       }
2146                                                  2146 
2147       // Set the longest path as the referenc    2147       // Set the longest path as the reference path
2148       this->setReferencePath(linevec[longestI    2148       this->setReferencePath(linevec[longestIdx], coordvec[longestIdx]);
2149    }                                             2149    }
2150 }                                                2150 }
2151                                                  2151 
2152                                                  2152 
2153 SoCoordinate3 * G4OpenInventorXtExaminerViewe    2153 SoCoordinate3 * G4OpenInventorXtExaminerViewer::getCoordsNode(SoFullPath *path)
2154 {                                                2154 {
2155    SoLineSet *trajectory = (SoLineSet *)path-    2155    SoLineSet *trajectory = (SoLineSet *)path->getTail();
2156    SoSeparator * grpNode = (SoSeparator*)(((S    2156    SoSeparator * grpNode = (SoSeparator*)(((SoFullPath*)path)->getNodeFromTail(1));
2157    int nodeIndex = grpNode->findChild(traject    2157    int nodeIndex = grpNode->findChild(trajectory);
2158    SoNode * tmpNode;                             2158    SoNode * tmpNode;
2159                                                  2159 
2160    // We allow only 100 iterations, in case t    2160    // We allow only 100 iterations, in case the node isn't found
2161    // (should take only a few iterations)        2161    // (should take only a few iterations)
2162    for(int i = 0; i < 100; ++i){                 2162    for(int i = 0; i < 100; ++i){
2163       --nodeIndex;                               2163       --nodeIndex;
2164                                                  2164 
2165       tmpNode = grpNode->getChild(nodeIndex);    2165       tmpNode = grpNode->getChild(nodeIndex);
2166       if(tmpNode->getTypeId() == SoCoordinate    2166       if(tmpNode->getTypeId() == SoCoordinate3::getClassTypeId()){
2167          //node found                            2167          //node found
2168          return (SoCoordinate3 *)tmpNode;        2168          return (SoCoordinate3 *)tmpNode;
2169       }                                          2169       }
2170    }                                             2170    }
2171    return NULL; //coords node not found          2171    return NULL; //coords node not found
2172 }                                                2172 }
2173                                                  2173 
2174                                                  2174 
2175 // Displays scene elements on the right side     2175 // Displays scene elements on the right side of listsDialog.
2176 // else: scene graph is searched for Geant4_S    2176 // else: scene graph is searched for Geant4_SoPolyhedron type nodes
2177 void G4OpenInventorXtExaminerViewer::getScene    2177 void G4OpenInventorXtExaminerViewer::getSceneElements()
2178 {                                                2178 {
2179    std::string field, eltName;                   2179    std::string field, eltName;
2180                                                  2180 
2181    std::map<std::string, int> duplicates;        2181    std::map<std::string, int> duplicates;
2182    std::map<std::string, int> sceneElts;         2182    std::map<std::string, int> sceneElts;
2183    SoSearchAction search;                        2183    SoSearchAction search;
2184    Geant4_SoPolyhedron *node;                    2184    Geant4_SoPolyhedron *node;
2185    SoGroup *root = (SoGroup *)getSceneManager    2185    SoGroup *root = (SoGroup *)getSceneManager()->getSceneGraph();
2186                                                  2186 
2187    SoBaseKit::setSearchingChildren(TRUE);        2187    SoBaseKit::setSearchingChildren(TRUE);
2188                                                  2188 
2189    search.reset();                               2189    search.reset();
2190    search.setSearchingAll(TRUE);                 2190    search.setSearchingAll(TRUE);
2191    search.setInterest(SoSearchAction::ALL);      2191    search.setInterest(SoSearchAction::ALL);
2192    search.setType(Geant4_SoPolyhedron::getCla    2192    search.setType(Geant4_SoPolyhedron::getClassTypeId(), 0);
2193    search.apply(root);                           2193    search.apply(root);
2194                                                  2194 
2195    SoPathList &pl = search.getPaths();           2195    SoPathList &pl = search.getPaths();
2196                                                  2196 
2197                                                  2197 
2198    // First find which names occur more than     2198    // First find which names occur more than once so we can append a counter to them
2199    for(int i = 0; i < pl.getLength(); i++) {     2199    for(int i = 0; i < pl.getLength(); i++) {
2200       SoFullPath *path = (SoFullPath *)pl[i];    2200       SoFullPath *path = (SoFullPath *)pl[i];
2201       node = (Geant4_SoPolyhedron *)path->get    2201       node = (Geant4_SoPolyhedron *)path->getTail();
2202       eltName = node->getName();                 2202       eltName = node->getName();
2203       if(duplicates.count(eltName))              2203       if(duplicates.count(eltName))
2204          duplicates[eltName]++;                  2204          duplicates[eltName]++;
2205       else                                       2205       else
2206          duplicates[eltName] = 1;                2206          duplicates[eltName] = 1;
2207    }                                             2207    }
2208                                                  2208 
2209    for(int i = 0; i < pl.getLength(); i++) {     2209    for(int i = 0; i < pl.getLength(); i++) {
2210       float x,y,z;                               2210       float x,y,z;
2211       std::stringstream ssCount;                 2211       std::stringstream ssCount;
2212       SoFullPath *path = (SoFullPath *)pl[i];    2212       SoFullPath *path = (SoFullPath *)pl[i];
2213       node = (Geant4_SoPolyhedron *)path->get    2213       node = (Geant4_SoPolyhedron *)path->getTail();
2214       eltName = node->getName();                 2214       eltName = node->getName();
2215       field = eltName;                           2215       field = eltName;
2216       if(duplicates[eltName] == 1)               2216       if(duplicates[eltName] == 1)
2217          ssCount << "";//duplicates[field]       2217          ssCount << "";//duplicates[field]
2218       else {                                     2218       else {
2219          if(sceneElts.count(eltName))            2219          if(sceneElts.count(eltName))
2220             sceneElts[eltName]++;                2220             sceneElts[eltName]++;
2221          else                                    2221          else
2222             sceneElts[eltName] = 1;              2222             sceneElts[eltName] = 1;
2223                                                  2223 
2224          ssCount << sceneElts[eltName];          2224          ssCount << sceneElts[eltName];
2225          field += "_";                           2225          field += "_";
2226       }                                          2226       }
2227                                                  2227 
2228       field += ssCount.str();                    2228       field += ssCount.str();
2229                                                  2229 
2230       SoGetBoundingBoxAction bAction(getViewp    2230       SoGetBoundingBoxAction bAction(getViewportRegion());
2231       bAction.apply(path);                       2231       bAction.apply(path);
2232       SbBox3f bBox = bAction.getBoundingBox()    2232       SbBox3f bBox = bAction.getBoundingBox();
2233                                                  2233 
2234       SbVec3f centr = bBox.getCenter();          2234       SbVec3f centr = bBox.getCenter();
2235       centr.getValue(x,y,z);                     2235       centr.getValue(x,y,z);
2236                                                  2236 
2237       path->ref();                               2237       path->ref();
2238       sceneElement el = { field, path, centr,    2238       sceneElement el = { field, path, centr, 0.0 };
2239       this->sceneElements.push_back(el);         2239       this->sceneElements.push_back(el);
2240    }                                             2240    }
2241 }                                                2241 }
2242                                                  2242 
2243                                                  2243 
2244 float G4OpenInventorXtExaminerViewer::sqrlen(    2244 float G4OpenInventorXtExaminerViewer::sqrlen(const SbVec3f &a)
2245 {                                                2245 {
2246    float x,y,z;                                  2246    float x,y,z;
2247    a.getValue(x,y,z);                            2247    a.getValue(x,y,z);
2248    return x*x + y*y + z*z;                       2248    return x*x + y*y + z*z;
2249 }                                                2249 }
2250                                                  2250 
2251                                                  2251 
2252 void G4OpenInventorXtExaminerViewer::distance    2252 void G4OpenInventorXtExaminerViewer::distanceToTrajectory(const SbVec3f &q,
2253                                                  2253                                                           float &dist,
2254                                                  2254                                                 SbVec3f &closestPoint,
2255                                                  2255                                                           int &index)
2256 {                                                2256 {
2257    // a : Previous point on trajectory           2257    // a : Previous point on trajectory
2258    // b : Next point on trajectory               2258    // b : Next point on trajectory
2259    // q : the point in space                     2259    // q : the point in space
2260    // dab, daq, dbq: distance between a & b,     2260    // dab, daq, dbq: distance between a & b, a & q, b & q
2261    //                                            2261    //    
2262    // Theory:  A point p on a line ab is defi    2262    // Theory:  A point p on a line ab is defined as:
2263    //                                            2263    //
2264    //         p(t) = a+t⋅(b–a)               2264    //         p(t) = a+t⋅(b–a)
2265    //                                            2265    //
2266    //       note: All are vectors except the     2266    //       note: All are vectors except the parameter t
2267    //                                            2267    //
2268    // When t is between 0 and 1 the point p i    2268    // When t is between 0 and 1 the point p is situated between a and b on ab.
2269    // The point p is defined in terms of the     2269    // The point p is defined in terms of the parameter t, subsequently so does
2270    // the distance from the query point q to     2270    // the distance from the query point q to the point p. To find the minimum
2271    // of that distance we differentiate it an    2271    // of that distance we differentiate it and set equal to zero:
2272    //                                            2272    //
2273    //       diff(Norm(p(t)- q)) = 0              2273    //       diff(Norm(p(t)- q)) = 0
2274    //                                            2274    //
2275    //     note: diff means taking the derivat    2275    //     note: diff means taking the derivative with regard to t
2276    //                                            2276    //
2277    // The resulting t is given in the code be    2277    // The resulting t is given in the code below. The square of the distance
2278    // between p and q is given by:               2278    // between p and q is given by:
2279    //                                            2279    //
2280    //       d^2 = (Norm(p(t)-q))^2               2280    //       d^2 = (Norm(p(t)-q))^2
2281    //                                            2281    //
2282    // The expression found is given in the co    2282    // The expression found is given in the code below (current_dist)
2283    //                                            2283    //
2284    // Ref: http://programmizm.sourceforge.net    2284    // Ref: http://programmizm.sourceforge.net/blog/2012/
2285    //           distance-from-a-point-to-a-po    2285    //           distance-from-a-point-to-a-polyline
2286    //                                            2286    //
2287    //    --PLG                                   2287    //    --PLG
2288                                                  2288 
2289    const size_t count = this->refParticleTraj    2289    const size_t count = this->refParticleTrajectory.size();
2290    assert(count>0);                              2290    assert(count>0);
2291                                                  2291 
2292    SbVec3f b = this->refParticleTrajectory[0]    2292    SbVec3f b = this->refParticleTrajectory[0];
2293    SbVec3f dbq = b - q;                          2293    SbVec3f dbq = b - q;
2294    float sqrDist = sqrlen(dbq);                  2294    float sqrDist = sqrlen(dbq);
2295    closestPoint = b;                             2295    closestPoint = b;
2296    index = 0;                                    2296    index = 0;
2297    for (size_t i = 1; i < count; ++i) {          2297    for (size_t i = 1; i < count; ++i) {
2298       const SbVec3f a = b;                       2298       const SbVec3f a = b;
2299       const SbVec3f daq = dbq;                   2299       const SbVec3f daq = dbq;
2300       b = this->refParticleTrajectory[i];        2300       b = this->refParticleTrajectory[i];
2301       dbq = b - q;                               2301       dbq = b - q;
2302       const SbVec3f dab = a - b;                 2302       const SbVec3f dab = a - b;
2303                                                  2303 
2304       float dab_x, dab_y, dab_z;                 2304       float dab_x, dab_y, dab_z;
2305       dab.getValue(dab_x,dab_y,dab_z);           2305       dab.getValue(dab_x,dab_y,dab_z);
2306       float daq_x, daq_y, daq_z;                 2306       float daq_x, daq_y, daq_z;
2307       daq.getValue(daq_x, daq_y, daq_z);         2307       daq.getValue(daq_x, daq_y, daq_z);
2308       float dbq_x, dbq_y, dbq_z;                 2308       float dbq_x, dbq_y, dbq_z;
2309       dbq.getValue(dbq_x, dbq_y, dbq_z);         2309       dbq.getValue(dbq_x, dbq_y, dbq_z);
2310                                                  2310 
2311       const float inv_sqrlen = 1./sqrlen(dab)    2311       const float inv_sqrlen = 1./sqrlen(dab);
2312       const float t = (dab_x*daq_x + dab_y*da    2312       const float t = (dab_x*daq_x + dab_y*daq_y + dab_z*daq_z)*inv_sqrlen;
2313                                                  2313 
2314       if (t<0.){                                 2314       if (t<0.){
2315          // The trajectory point occurs befor    2315          // The trajectory point occurs before point a
2316          // Go to the next point                 2316          // Go to the next point
2317          continue;                               2317          continue;
2318       }                                          2318       }
2319       float current_dist;                        2319       float current_dist;
2320       if (t<=1.){                                2320       if (t<=1.){
2321          // The trajectory point occurs betwe    2321          // The trajectory point occurs between a and b.
2322          // Compute the distance to that poin    2322          // Compute the distance to that point
2323          current_dist = daq_x*daq_x + daq_y*d    2323          current_dist = daq_x*daq_x + daq_y*daq_y + daq_z*daq_z
2324             - t*(daq_x*dab_x + daq_y*dab_y +     2324             - t*(daq_x*dab_x + daq_y*dab_y + daq_z*dab_z)
2325             + t*t*(dab_x*dab_x + dab_y*dab_y     2325             + t*t*(dab_x*dab_x + dab_y*dab_y + dab_z*dab_z);
2326       }                                          2326       }
2327       else { //t>1.                              2327       else { //t>1.
2328          // The trajectory point occurs after    2328          // The trajectory point occurs after b.
2329          // Get the distance to point b          2329          // Get the distance to point b
2330          current_dist = sqrlen(dbq);             2330          current_dist = sqrlen(dbq);
2331       }                                          2331       }
2332                                                  2332 
2333       if (current_dist < sqrDist){               2333       if (current_dist < sqrDist){
2334          sqrDist = current_dist;                 2334          sqrDist = current_dist;
2335          closestPoint = a + t*(b-a);             2335          closestPoint = a + t*(b-a);
2336          index = i;                              2336          index = i;
2337       }                                          2337       }
2338    }                                             2338    }
2339                                                  2339 
2340    dist = std::sqrt(sqrDist);                    2340    dist = std::sqrt(sqrDist);
2341 }                                                2341 }
2342                                                  2342 
2343                                                  2343 
2344 void G4OpenInventorXtExaminerViewer::sortElem    2344 void G4OpenInventorXtExaminerViewer::sortElements()
2345 {                                                2345 {
2346    if(this->refParticleTrajectory.empty())       2346    if(this->refParticleTrajectory.empty())
2347       return;                                    2347       return;
2348                                                  2348 
2349    float * trajLength = new float[this->refPa    2349    float * trajLength = new float[this->refParticleTrajectory.size()];
2350    typedef std::map<elementForSorting, sceneE    2350    typedef std::map<elementForSorting, sceneElement> sortedMap;
2351    sortedMap sorted;                             2351    sortedMap sorted;
2352                                                  2352 
2353    // For every point on the reference trajec    2353    // For every point on the reference trajectory, compute
2354    // the total length from the start            2354    // the total length from the start
2355    SbVec3f prevPoint;                            2355    SbVec3f prevPoint;
2356    std::vector<SbVec3f>::iterator itRef = thi    2356    std::vector<SbVec3f>::iterator itRef = this->refParticleTrajectory.begin();
2357    int trajIndex = 0;                            2357    int trajIndex = 0;
2358    prevPoint = *itRef;                           2358    prevPoint = *itRef;
2359    trajLength[trajIndex] = 0.0;                  2359    trajLength[trajIndex] = 0.0;
2360    ++itRef;                                      2360    ++itRef;
2361    ++trajIndex;                                  2361    ++trajIndex;
2362    for(; itRef != this->refParticleTrajectory    2362    for(; itRef != this->refParticleTrajectory.end(); ++itRef, ++trajIndex){
2363       trajLength[trajIndex] = trajLength[traj    2363       trajLength[trajIndex] = trajLength[trajIndex-1] + (*itRef - prevPoint).length();
2364       prevPoint = *itRef;                        2364       prevPoint = *itRef;
2365    }                                             2365    }
2366                                                  2366 
2367    // Compute the smallest distance between t    2367    // Compute the smallest distance between the element
2368    // and the reference trajectory (find the     2368    // and the reference trajectory (find the closest point),
2369    // then map the element to the trajectory     2369    // then map the element to the trajectory length of that
2370    // point (calculated above)                   2370    // point (calculated above)
2371    SoGetBoundingBoxAction bAction(this->getVi    2371    SoGetBoundingBoxAction bAction(this->getViewportRegion());
2372    SbVec3f elementCoord;                         2372    SbVec3f elementCoord;
2373    std::vector<sceneElement>::iterator itEl;     2373    std::vector<sceneElement>::iterator itEl;
2374    int elementIndex;                             2374    int elementIndex;
2375    elementForSorting el;                         2375    elementForSorting el;
2376    for(itEl = this->sceneElements.begin(), el    2376    for(itEl = this->sceneElements.begin(), elementIndex = 0;
2377        itEl != this->sceneElements.end(); ++i    2377        itEl != this->sceneElements.end(); ++itEl, ++elementIndex){
2378       bAction.apply(itEl->path);                 2378       bAction.apply(itEl->path);
2379                                                  2379 
2380       // FWJ sceneElement already has a cente    2380       // FWJ sceneElement already has a center
2381       elementCoord = itEl->center;               2381       elementCoord = itEl->center;
2382       // ... and this sometimes returns an em    2382       // ... and this sometimes returns an empty box!
2383       //      elementCoord = bAction.getBound    2383       //      elementCoord = bAction.getBoundingBox().getCenter();
2384       //      if (bAction.getBoundingBox().is    2384       //      if (bAction.getBoundingBox().isEmpty()) {
2385       //         G4cout << "sortElements: Box    2385       //         G4cout << "sortElements: Box is empty!" << G4endl;
2386       //         G4cout << "   element name="    2386       //         G4cout << "   element name=" << itEl->name << G4endl;
2387       //      }                                  2387       //      }
2388                                                  2388 
2389       int index;                                 2389       int index;
2390       distanceToTrajectory(elementCoord, el.s    2390       distanceToTrajectory(elementCoord, el.smallestDistance, el.closestPoint, index);
2391       itEl->closestPointZCoord = el.closestPo    2391       itEl->closestPointZCoord = el.closestPointZCoord = trajLength[index];
2392       el.distanceToBeamlineStart = (itEl->cen    2392       el.distanceToBeamlineStart = (itEl->center - this->refParticleTrajectory[0]).length();
2393                                                  2393 
2394       // This map of the scene elements (or t    2394       // This map of the scene elements (or their coordinates rather)
2395       // is automatically sorted by trajector    2395       // is automatically sorted by trajectory length (Z coord), then
2396       // by the distance between the element     2396       // by the distance between the element and the point in case the Z coord
2397       // is the same as another element.  Thi    2397       // is the same as another element.  This is done by using as a key
2398       // an element structure which implement    2398       // an element structure which implements the operator for weak ordering
2399       sorted.insert(std::make_pair(el,*itEl))    2399       sorted.insert(std::make_pair(el,*itEl));
2400    }                                             2400    }
2401                                                  2401 
2402    // store the sorted elements into the vect    2402    // store the sorted elements into the vector field
2403    this->sceneElements.clear();                  2403    this->sceneElements.clear();
2404                                                  2404 
2405    sortedMap::iterator itSorted = sorted.begi    2405    sortedMap::iterator itSorted = sorted.begin();
2406    for(; itSorted != sorted.end(); itSorted++    2406    for(; itSorted != sorted.end(); itSorted++)
2407       this->sceneElements.push_back(itSorted-    2407       this->sceneElements.push_back(itSorted->second);
2408                                                  2408 
2409    this->zcoordSetFlag = true;                   2409    this->zcoordSetFlag = true;
2410                                                  2410 
2411                                                  2411 
2412    Widget formTop = XtNameToWidget(this->list    2412    Widget formTop = XtNameToWidget(this->listsDialog, "FormTop");
2413    Widget formTopRight = XtNameToWidget(formT    2413    Widget formTopRight = XtNameToWidget(formTop, "FormTopRight");
2414                                                  2414 
2415    this->createElementsList(formTopRight);       2415    this->createElementsList(formTopRight);
2416                                                  2416 
2417    delete[] trajLength;                          2417    delete[] trajLength;
2418 }                                                2418 }
2419                                                  2419 
2420                                                  2420 
2421 void G4OpenInventorXtExaminerViewer::createEl    2421 void G4OpenInventorXtExaminerViewer::createElementsList(Widget formTopRight)
2422 {                                                2422 {
2423    if(this->myElementList != NULL)               2423    if(this->myElementList != NULL)
2424       XtUnmanageChild(this->myElementList);      2424       XtUnmanageChild(this->myElementList);
2425                                                  2425 
2426    int size = this->sceneElements.size();        2426    int size = this->sceneElements.size();
2427    XmString *elements = (XmString *) XtMalloc    2427    XmString *elements = (XmString *) XtMalloc(size * sizeof(XmString));
2428                                                  2428 
2429    std::vector<sceneElement>::const_iterator     2429    std::vector<sceneElement>::const_iterator it;
2430    int count = 0;                                2430    int count = 0;
2431    std::stringstream ss;                         2431    std::stringstream ss;
2432    for(it=this->sceneElements.begin(); it!=th    2432    for(it=this->sceneElements.begin(); it!=this->sceneElements.end(); ++it) {
2433       ss << it->name;                            2433       ss << it->name;
2434       if(zcoordSetFlag)                          2434       if(zcoordSetFlag)
2435          ss << " [" << it->closestPointZCoord    2435          ss << " [" << it->closestPointZCoord << "]";
2436       elements[count] = XmStringCreateLocaliz    2436       elements[count] = XmStringCreateLocalized((char *)ss.str().c_str());
2437       ++count;                                   2437       ++count;
2438       ss.str("");                                2438       ss.str("");
2439    }                                             2439    }
2440                                                  2440 
2441    Arg args[10];                                 2441    Arg args[10];
2442    int n;                                        2442    int n;
2443                                                  2443 
2444    // Label Right                                2444    // Label Right
2445    n = 0;                                        2445    n = 0;
2446    Widget labelRight;                            2446    Widget labelRight;
2447    XtSetArg(args[n], XmNtopAttachment, XmATTA    2447    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
2448                                                  2448 
2449    labelRight = XmCreateLabelGadget(formTopRi    2449    labelRight = XmCreateLabelGadget(formTopRight, (char*)"Element [S mm]",
2450                                     args, n);    2450                                     args, n);
2451    XtManageChild(labelRight);                    2451    XtManageChild(labelRight);
2452                                                  2452 
2453    // List Right                                 2453    // List Right
2454    n = 0;                                        2454    n = 0;
2455    XtSetArg(args[n], XmNvisibleItemCount, 7);    2455    XtSetArg(args[n], XmNvisibleItemCount, 7); n++;
2456    XtSetArg(args[n], XmNitemCount, size); n++    2456    XtSetArg(args[n], XmNitemCount, size); n++;
2457    XtSetArg(args[n], XmNitems, elements); n++    2457    XtSetArg(args[n], XmNitems, elements); n++;
2458    XtSetArg(args[n], XmNtopAttachment, XmATTA    2458    XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
2459    XtSetArg(args[n], XmNtopWidget, labelRight    2459    XtSetArg(args[n], XmNtopWidget, labelRight); n++;
2460    XtSetArg(args[n], XmNrightAttachment, XmAT    2460    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
2461    XtSetArg(args[n], XmNbottomAttachment, XmA    2461    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
2462    // FWJ                                        2462    // FWJ
2463    XtSetArg(args[n], XmNwidth, 240);  n++;       2463    XtSetArg(args[n], XmNwidth, 240);  n++;
2464    //   XtSetArg(args[n], XmNwidth, 280); n++    2464    //   XtSetArg(args[n], XmNwidth, 280); n++;
2465    // XtSetArg(args[n], XmNwidth, 300); n++;     2465    // XtSetArg(args[n], XmNwidth, 300); n++;
2466                                                  2466 
2467    this->myElementList = XmCreateScrolledList    2467    this->myElementList = XmCreateScrolledList(formTopRight, (char *) "ListRight", args, n);
2468                                                  2468 
2469    XtAddCallback(this->myElementList, XmNbrow    2469    XtAddCallback(this->myElementList, XmNbrowseSelectionCallback,
2470                  (XtCallbackProc) lookAtScene    2470                  (XtCallbackProc) lookAtSceneElementCB, this);
2471    xmAddMouseEventHandler(this->myElementList    2471    xmAddMouseEventHandler(this->myElementList); // Add scrolling functionality
2472    XtManageChild(this->myElementList);           2472    XtManageChild(this->myElementList);
2473                                                  2473 
2474    if (elements != NULL) {                       2474    if (elements != NULL) {
2475       for (int i = 0; i < size; i++)             2475       for (int i = 0; i < size; i++)
2476          XmStringFree(elements[i]);              2476          XmStringFree(elements[i]);
2477       XtFree((char *) elements);                 2477       XtFree((char *) elements);
2478    }                                             2478    }
2479 }                                                2479 }
2480                                                  2480 
2481                                                  2481 
2482 // Pops up a custom dialog listsDialog contai    2482 // Pops up a custom dialog listsDialog containing 
2483 // scene elements and viewpoints.                2483 // scene elements and viewpoints.
2484                                                  2484 
2485 void G4OpenInventorXtExaminerViewer::construc    2485 void G4OpenInventorXtExaminerViewer::constructListsDialog(Widget w,
2486                                                  2486                                              XtPointer client_data,
2487                                                  2487                                              XtPointer)
2488 {                                                2488 {
2489    // G4cout << "DEBUG constructListsDialog w    2489    // G4cout << "DEBUG constructListsDialog w = " << w << G4endl;
2490    G4OpenInventorXtExaminerViewer * This = (G    2490    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
2491    if (This->listsDialog) {                      2491    if (This->listsDialog) {
2492       return;                                    2492       return;
2493    }                                             2493    }
2494                                                  2494 
2495    if (This->currentState == ANIMATION || Thi    2495    if (This->currentState == ANIMATION || This->currentState == PAUSED_ANIMATION) {
2496       if (This->animateSensor->isScheduled())    2496       if (This->animateSensor->isScheduled())
2497          This->animateSensor->unschedule();      2497          This->animateSensor->unschedule();
2498       This->refParticleIdx = This->prevRefIdx    2498       This->refParticleIdx = This->prevRefIdx;
2499       This->restoreCamera();                     2499       This->restoreCamera();
2500       This->currentState = This->prevState;      2500       This->currentState = This->prevState;
2501    }                                             2501    }
2502                                                  2502 
2503    This->step = 1; // Default values             2503    This->step = 1; // Default values
2504    This->refParticleIdx = 0;                     2504    This->refParticleIdx = 0;
2505    if (This->refParticleTrajectory.size()){      2505    if (This->refParticleTrajectory.size()){
2506       This->prevPt = This->refParticleTraject    2506       This->prevPt = This->refParticleTrajectory[0]; // For calculating distance
2507    }                                             2507    }
2508                                                  2508 
2509    This->getSceneElements();                     2509    This->getSceneElements();
2510                                                  2510 
2511    int n = 0;                                    2511    int n = 0;
2512    Arg args[10];                                 2512    Arg args[10];
2513    Atom WM_DELETE_WINDOW;                        2513    Atom WM_DELETE_WINDOW;
2514                                                  2514 
2515    ///////////////////////CUSTOM listsDialog/    2515    ///////////////////////CUSTOM listsDialog///////////////////////////////
2516                                                  2516 
2517    Widget topShell;                              2517    Widget topShell;
2518    // FWJ gets the topmost window containing     2518    // FWJ gets the topmost window containing This->getParentWidget()
2519    // This is unnecessary because the parent     2519    // This is unnecessary because the parent is passed in
2520    //   topShell = SoXt::getShellWidget(This-    2520    //   topShell = SoXt::getShellWidget(This->getParentWidget());
2521    topShell = w;                                 2521    topShell = w;
2522    // G4cout << "DEBUG PARENT (topShell) FOR     2522    // G4cout << "DEBUG PARENT (topShell) FOR AUX WINDOW = " << topShell << G4endl;
2523                                                  2523 
2524    // Shell Dialog                               2524    // Shell Dialog
2525    std::string dialogNameStr = This->fileName    2525    std::string dialogNameStr = This->fileName.substr(This->fileName.rfind('/') + 1);
2526    const int nDialog = dialogNameStr.size() +    2526    const int nDialog = dialogNameStr.size() + 1;
2527    char *dialogName = new char[nDialog];         2527    char *dialogName = new char[nDialog];
2528    strncpy(dialogName, dialogNameStr.c_str(),    2528    strncpy(dialogName, dialogNameStr.c_str(), nDialog);
2529                                                  2529 
2530    n = 0;                                        2530    n = 0;
2531    XtSetArg(args[n], XmNx, 610);  n++;           2531    XtSetArg(args[n], XmNx, 610);  n++;
2532    This->myShellDialog = XmCreateDialogShell(    2532    This->myShellDialog = XmCreateDialogShell(topShell, dialogName, args, n);
2533                                                  2533 
2534    delete[] dialogName;                          2534    delete[] dialogName;
2535    WM_DELETE_WINDOW = XInternAtom(XtDisplay(w    2535    WM_DELETE_WINDOW = XInternAtom(XtDisplay(w), "WM_DELETE_WINDOW", False);
2536    XmAddWMProtocolCallback(This->myShellDialo    2536    XmAddWMProtocolCallback(This->myShellDialog, WM_DELETE_WINDOW,
2537                            (XtCallbackProc)cl    2537                            (XtCallbackProc)closeListsDialogCB, This);
2538                                                  2538 
2539    // Main Pane(listsDialog)                     2539    // Main Pane(listsDialog)
2540    n = 0;                                        2540    n = 0;
2541    XtSetArg(args[n], XmNsashWidth, 1);  n++;     2541    XtSetArg(args[n], XmNsashWidth, 1);  n++;
2542    XtSetArg(args[n], XmNsashHeight, 1); n++;     2542    XtSetArg(args[n], XmNsashHeight, 1); n++;
2543    XtSetArg(args[n], XmNseparatorOn, False);     2543    XtSetArg(args[n], XmNseparatorOn, False);  n++;
2544    // FWJ                                        2544    // FWJ
2545    This->listsDialog = XmCreatePanedWindow(Th    2545    This->listsDialog = XmCreatePanedWindow(This->myShellDialog, (char *) "MainPane",
2546                                            ar    2546                                            args, n);
2547                                                  2547 
2548                                                  2548 
2549    ////////////////////////TOP FORM//////////    2549    ////////////////////////TOP FORM//////////////////////////
2550    n = 0;                                        2550    n = 0;
2551    // FWJ fails compile                          2551    // FWJ fails compile
2552    //   Widget formTop = XmCreateForm(This, (    2552    //   Widget formTop = XmCreateForm(This, (char *) "FormTop", args, n);
2553    Widget formTop = XmCreateForm(This->listsD    2553    Widget formTop = XmCreateForm(This->listsDialog, (char *) "FormTop", args, n);
2554                                                  2554 
2555    n = 0;                                        2555    n = 0;
2556    XtSetArg(args[n], XmNmarginWidth, 8);  n++    2556    XtSetArg(args[n], XmNmarginWidth, 8);  n++;
2557    XtSetArg(args[n], XmNmarginHeight, 8); n++    2557    XtSetArg(args[n], XmNmarginHeight, 8); n++;
2558    XtSetArg(args[n], XmNtopAttachment, XmATTA    2558    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
2559    XtSetArg(args[n], XmNrightAttachment, XmAT    2559    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
2560    XtSetArg(args[n], XmNbottomAttachment, XmA    2560    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
2561    Widget formTopRight = XmCreateForm(formTop    2561    Widget formTopRight = XmCreateForm(formTop, (char *) "FormTopRight", args,
2562                                       n);        2562                                       n);
2563                                                  2563 
2564    n = 0;                                        2564    n = 0;
2565    XtSetArg(args[n], XmNmarginWidth, 8);  n++    2565    XtSetArg(args[n], XmNmarginWidth, 8);  n++;
2566    XtSetArg(args[n], XmNmarginHeight, 8); n++    2566    XtSetArg(args[n], XmNmarginHeight, 8); n++;
2567    XtSetArg(args[n], XmNtopAttachment, XmATTA    2567    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
2568    XtSetArg(args[n], XmNleftAttachment, XmATT    2568    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2569    XtSetArg(args[n], XmNrightAttachment, XmAT    2569    XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET);  n++;
2570    XtSetArg(args[n], XmNrightWidget, formTopR    2570    XtSetArg(args[n], XmNrightWidget, formTopRight); n++;
2571    XtSetArg(args[n], XmNrightOffset, 10); n++    2571    XtSetArg(args[n], XmNrightOffset, 10); n++;
2572    XtSetArg(args[n], XmNbottomAttachment, XmA    2572    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
2573    Widget formTopLeft = XmCreateForm(formTop,    2573    Widget formTopLeft = XmCreateForm(formTop, (char *) "FormTopLeft", args, n);
2574                                                  2574 
2575    /////TOP RIGHT/////                           2575    /////TOP RIGHT/////
2576                                                  2576 
2577    This->createElementsList(formTopRight);       2577    This->createElementsList(formTopRight);
2578    XtManageChild(formTopRight);                  2578    XtManageChild(formTopRight);
2579                                                  2579 
2580    /////TOP LEFT/////                            2580    /////TOP LEFT/////
2581                                                  2581 
2582    // Label Left                                 2582    // Label Left
2583    n = 0;                                        2583    n = 0;
2584    XtSetArg(args[n], XmNtopAttachment, XmATTA    2584    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
2585    XtSetArg(args[n], XmNleftAttachment, XmATT    2585    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2586    Widget labelLeft = XmCreateLabelGadget(for    2586    Widget labelLeft = XmCreateLabelGadget(formTopLeft, (char *) "ViewPoints",
2587                                           arg    2587                                           args, n);
2588    XtManageChild(labelLeft);                     2588    XtManageChild(labelLeft);
2589                                                  2589 
2590    // List Left                                  2590    // List Left
2591    n = 0;                                        2591    n = 0;
2592    XtSetArg(args[n], XmNlistSizePolicy, XmRES    2592    XtSetArg(args[n], XmNlistSizePolicy, XmRESIZE_IF_POSSIBLE);  n++;
2593    XtSetArg(args[n], XmNvisibleItemCount, 7);    2593    XtSetArg(args[n], XmNvisibleItemCount, 7); n++;
2594    // XtSetArg(args[n], XmNwidth, 140); n++;     2594    // XtSetArg(args[n], XmNwidth, 140); n++;
2595    XtSetArg(args[n], XmNtopAttachment, XmATTA    2595    XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
2596    XtSetArg(args[n], XmNtopWidget, labelLeft)    2596    XtSetArg(args[n], XmNtopWidget, labelLeft);  n++;
2597    XtSetArg(args[n], XmNrightAttachment, XmAT    2597    XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET);  n++;
2598    XtSetArg(args[n], XmNrightWidget, This->my    2598    XtSetArg(args[n], XmNrightWidget, This->myElementList);  n++;
2599    XtSetArg(args[n], XmNleftAttachment, XmATT    2599    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2600    XtSetArg(args[n], XmNbottomAttachment, XmA    2600    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
2601    // FWJ                                        2601    // FWJ
2602    XtSetArg(args[n], XmNwidth, 160);  n++;       2602    XtSetArg(args[n], XmNwidth, 160);  n++;
2603    // XtSetArg(args[n], XmNwidth, 200); n++;     2603    // XtSetArg(args[n], XmNwidth, 200); n++;
2604                                                  2604 
2605    This->myViewPtList = XmCreateScrolledList(    2605    This->myViewPtList = XmCreateScrolledList(formTopLeft, (char *) "ListLeft",
2606                                                  2606                                              args, n);
2607    if (This->viewPtList.size())                  2607    if (This->viewPtList.size())
2608       This->addViewPoints();                     2608       This->addViewPoints();
2609    XtAddCallback(This->myViewPtList, XmNbrows    2609    XtAddCallback(This->myViewPtList, XmNbrowseSelectionCallback,
2610                  (XtCallbackProc) loadBookmar    2610                  (XtCallbackProc) loadBookmarkCB, This);
2611    xmAddMouseEventHandler(This->myViewPtList)    2611    xmAddMouseEventHandler(This->myViewPtList); // Add scrolling functionality
2612                                                  2612 
2613    XtManageChild(This->myViewPtList);            2613    XtManageChild(This->myViewPtList);
2614                                                  2614 
2615    XtManageChild(formTopLeft);                   2615    XtManageChild(formTopLeft);
2616                                                  2616 
2617    XtManageChild(formTop);                       2617    XtManageChild(formTop);
2618                                                  2618 
2619    ////////////////////MIDDLE FORM///////////    2619    ////////////////////MIDDLE FORM///////////////////////////
2620    n = 0;                                        2620    n = 0;
2621    XtSetArg(args[n], XmNmarginWidth, 6);  n++    2621    XtSetArg(args[n], XmNmarginWidth, 6);  n++;
2622    // FWJ fails compile                          2622    // FWJ fails compile
2623    //   Widget formMiddle = XmCreateForm(This    2623    //   Widget formMiddle = XmCreateForm(This->canvas, (char *) "MiddleForm", args, n);
2624    Widget formMiddle = XmCreateForm(This->lis    2624    Widget formMiddle = XmCreateForm(This->listsDialog, (char *) "MiddleForm", args, n);
2625                                                  2625 
2626    // Label                                      2626    // Label
2627    n = 0;                                        2627    n = 0;
2628    XtSetArg(args[n], XmNleftAttachment, XmATT    2628    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2629    XtSetArg(args[n], XmNtopAttachment, XmATTA    2629    XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
2630    XtSetArg(args[n], XmNtopWidget, This->myVi    2630    XtSetArg(args[n], XmNtopWidget, This->myViewPtList); n++;
2631    Widget label = XmCreateLabelGadget(formMid    2631    Widget label = XmCreateLabelGadget(formMiddle, (char *) "Selection", args,
2632                                       n);        2632                                       n);
2633    XtManageChild(label);                         2633    XtManageChild(label);
2634                                                  2634 
2635    // Text                                       2635    // Text
2636    n = 0;                                        2636    n = 0;
2637    XtSetArg(args[n], XmNleftAttachment, XmATT    2637    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2638    XtSetArg(args[n], XmNrightAttachment, XmAT    2638    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
2639    XtSetArg(args[n], XmNtopAttachment, XmATTA    2639    XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
2640    XtSetArg(args[n], XmNtopWidget, label);  n    2640    XtSetArg(args[n], XmNtopWidget, label);  n++;
2641    XtSetArg(args[n], XmNtopOffset, 3);  n++;     2641    XtSetArg(args[n], XmNtopOffset, 3);  n++;
2642    XtSetArg(args[n], XmNmaxLength, This->MAX_    2642    XtSetArg(args[n], XmNmaxLength, This->MAX_VP_NAME);  n++;
2643    This->viewPtSelection = XmCreateText(formM    2643    This->viewPtSelection = XmCreateText(formMiddle, (char *) "Txt", args, n);
2644    XtManageChild(This->viewPtSelection);         2644    XtManageChild(This->viewPtSelection);
2645                                                  2645 
2646    Dimension h1, h2, h;                          2646    Dimension h1, h2, h;
2647    XtVaGetValues(label, XmNheight, &h1, NULL)    2647    XtVaGetValues(label, XmNheight, &h1, NULL);
2648    XtVaGetValues(This->viewPtSelection, XmNhe    2648    XtVaGetValues(This->viewPtSelection, XmNheight, &h2, NULL);
2649                                                  2649 
2650    h = (Dimension) (1.1 * (h1 + h2));            2650    h = (Dimension) (1.1 * (h1 + h2));
2651                                                  2651 
2652    XtVaSetValues(formMiddle, XmNpaneMaximum,     2652    XtVaSetValues(formMiddle, XmNpaneMaximum, h, XmNpaneMinimum, h, NULL);
2653    XtManageChild(formMiddle);                    2653    XtManageChild(formMiddle);
2654                                                  2654 
2655    /////////////////////BOTTOM FORM//////////    2655    /////////////////////BOTTOM FORM///////////////////////////
2656    // Action Area Form                           2656    // Action Area Form
2657    n = 0;                                        2657    n = 0;
2658    XtSetArg(args[n], XmNfractionBase, 4); n++    2658    XtSetArg(args[n], XmNfractionBase, 4); n++;
2659    XtSetArg(args[n], XmNtopAttachment, XmATTA    2659    XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
2660    XtSetArg(args[n], XmNtopWidget, This->view    2660    XtSetArg(args[n], XmNtopWidget, This->viewPtSelection);  n++;
2661    // FWJ fails compile                          2661    // FWJ fails compile
2662    //   Widget formAction = XmCreateForm(This    2662    //   Widget formAction = XmCreateForm(This, (char *) "ActionForm", args, n);
2663    Widget formAction = XmCreateForm(This->lis    2663    Widget formAction = XmCreateForm(This->listsDialog, (char *) "ActionForm", args, n);
2664                                                  2664 
2665    n = 0;                                        2665    n = 0;
2666    XtSetArg(args[n], XmNleftAttachment, XmATT    2666    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
2667    XtSetArg(args[n], XmNrightAttachment, XmAT    2667    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
2668    XtSetArg(args[n], XmNtopOffset, 3);  n++;     2668    XtSetArg(args[n], XmNtopOffset, 3);  n++;
2669    XtSetArg(args[n], XmNbottomOffset, 5); n++    2669    XtSetArg(args[n], XmNbottomOffset, 5); n++;
2670    Widget separator = XmCreateSeparatorGadget    2670    Widget separator = XmCreateSeparatorGadget(formAction, (char *) "Sep", args, n);
2671                                                  2671 
2672    XtManageChild(separator);                     2672    XtManageChild(separator);
2673                                                  2673 
2674    Widget button = XmCreatePushButton(formAct    2674    Widget button = XmCreatePushButton(formAction, (char *) "Delete", NULL, 0);
2675    XtVaSetValues(button, XmNtopAttachment, Xm    2675    XtVaSetValues(button, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget,
2676                  separator, XmNbottomAttachme    2676                  separator, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment,
2677                  XmATTACH_POSITION, XmNleftPo    2677                  XmATTACH_POSITION, XmNleftPosition, 0, XmNrightAttachment,
2678                  XmATTACH_POSITION, XmNrightP    2678                  XmATTACH_POSITION, XmNrightPosition, 1,
2679                  XmNdefaultButtonShadowThickn    2679                  XmNdefaultButtonShadowThickness, 2, XmNwidth, 40, XmNheight, 30,
2680                  NULL);                          2680                  NULL);
2681                                                  2681 
2682    XtAddCallback(button, XmNactivateCallback,    2682    XtAddCallback(button, XmNactivateCallback,
2683                  (XtCallbackProc) deleteBookm    2683                  (XtCallbackProc) deleteBookmarkCB, This);
2684    XtManageChild(button);                        2684    XtManageChild(button);
2685                                                  2685 
2686    button = XmCreatePushButton(formAction, (c    2686    button = XmCreatePushButton(formAction, (char *) "Rename", NULL, 0);
2687    XtVaSetValues(button, XmNtopAttachment, Xm    2687    XtVaSetValues(button, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget,
2688                  separator, XmNbottomAttachme    2688                  separator, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment,
2689                  XmATTACH_POSITION, XmNleftPo    2689                  XmATTACH_POSITION, XmNleftPosition, 1, XmNrightAttachment,
2690                  XmATTACH_POSITION, XmNrightP    2690                  XmATTACH_POSITION, XmNrightPosition, 2,
2691                  XmNdefaultButtonShadowThickn    2691                  XmNdefaultButtonShadowThickness, 2, XmNwidth, 40, XmNheight, 30,
2692                  NULL);                          2692                  NULL);
2693                                                  2693 
2694    XtAddCallback(button, XmNactivateCallback,    2694    XtAddCallback(button, XmNactivateCallback,
2695                  (XtCallbackProc) renameBookm    2695                  (XtCallbackProc) renameBookmarkCB, This);
2696    XtManageChild(button);                        2696    XtManageChild(button);
2697                                                  2697 
2698    button = XmCreatePushButton(formAction, (c    2698    button = XmCreatePushButton(formAction, (char *) "Sort", NULL, 0);
2699    XtVaSetValues(button, XmNtopAttachment, Xm    2699    XtVaSetValues(button, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget,
2700                  separator, XmNbottomAttachme    2700                  separator, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment,
2701                  XmATTACH_POSITION, XmNleftPo    2701                  XmATTACH_POSITION, XmNleftPosition, 2, XmNrightAttachment,
2702                  XmATTACH_POSITION, XmNrightP    2702                  XmATTACH_POSITION, XmNrightPosition, 3,
2703                  XmNdefaultButtonShadowThickn    2703                  XmNdefaultButtonShadowThickness, 2, XmNwidth, 40, XmNheight, 30,
2704                  NULL);                          2704                  NULL);
2705                                                  2705 
2706    XtAddCallback(button, XmNactivateCallback,    2706    XtAddCallback(button, XmNactivateCallback, (XtCallbackProc) sortBookmarksCB, This);
2707    XtManageChild(button);                        2707    XtManageChild(button);
2708                                                  2708 
2709    button = XmCreatePushButton(formAction, (c    2709    button = XmCreatePushButton(formAction, (char *) "Close", NULL, 0);
2710    XtVaSetValues(button, XmNtopAttachment, Xm    2710    XtVaSetValues(button, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget,
2711                  separator, XmNbottomAttachme    2711                  separator, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment,
2712                  XmATTACH_POSITION, XmNleftPo    2712                  XmATTACH_POSITION, XmNleftPosition, 3, XmNrightAttachment,
2713                  XmATTACH_POSITION, XmNrightP    2713                  XmATTACH_POSITION, XmNrightPosition, 4,
2714                  XmNdefaultButtonShadowThickn    2714                  XmNdefaultButtonShadowThickness, 2, XmNwidth, 40, XmNheight, 30,
2715                  NULL);                          2715                  NULL);
2716                                                  2716 
2717    XtAddCallback(button, XmNactivateCallback,    2717    XtAddCallback(button, XmNactivateCallback, (XtCallbackProc) closeListsDialogCB, This);
2718    XtManageChild(button);                        2718    XtManageChild(button);
2719                                                  2719 
2720    XtManageChild(formAction);                    2720    XtManageChild(formAction);
2721    XtVaGetValues(button, XmNheight, &h1, NULL    2721    XtVaGetValues(button, XmNheight, &h1, NULL);
2722    XtVaSetValues(formAction, XmNpaneMaximum,     2722    XtVaSetValues(formAction, XmNpaneMaximum, h1, XmNpaneMinimum, h1, NULL);
2723                                                  2723 
2724    XtManageChild(This->listsDialog);             2724    XtManageChild(This->listsDialog);
2725                                                  2725 
2726    ////////////////////////CUSTOM listsDialog    2726    ////////////////////////CUSTOM listsDialog///////////////////////////////
2727 }                                                2727 }
2728                                                  2728 
2729                                                  2729 
2730 // Called when user clicks a scene element in    2730 // Called when user clicks a scene element in listsDialog.
2731 // Zooms onto that element.                      2731 // Zooms onto that element.
2732 void G4OpenInventorXtExaminerViewer::lookAtSc    2732 void G4OpenInventorXtExaminerViewer::lookAtSceneElementCB(Widget,
2733                                            Xt    2733                                            XtPointer client_data,
2734                                            Xt    2734                                            XtPointer call_data)
2735 {                                                2735 {
2736    char *value;                                  2736    char *value;
2737    std::string elementField;                     2737    std::string elementField;
2738    G4OpenInventorXtExaminerViewer * This = (G    2738    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
2739    SoCamera * cam = This->getCamera();           2739    SoCamera * cam = This->getCamera();
2740                                                  2740 
2741    if (This->SoXtExaminerViewer::isAnimating(    2741    if (This->SoXtExaminerViewer::isAnimating())
2742       This->stopAnimating();                     2742       This->stopAnimating();
2743                                                  2743 
2744    XmListCallbackStruct *cbs = (XmListCallbac    2744    XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
2745                                                  2745 
2746    value = (char *) XmStringUnparse(cbs->item    2746    value = (char *) XmStringUnparse(cbs->item, XmFONTLIST_DEFAULT_TAG,
2747                                     XmCHARSET    2747                                     XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL);
2748    if (This->currentState == ANIMATION || Thi    2748    if (This->currentState == ANIMATION || This->currentState == REVERSED_ANIMATION
2749        || This->currentState == PAUSED_ANIMAT    2749        || This->currentState == PAUSED_ANIMATION ) {
2750       if (This->animateSensor->isScheduled())    2750       if (This->animateSensor->isScheduled())
2751          This->animateSensor->unschedule();      2751          This->animateSensor->unschedule();
2752       This->setSuperimpositionEnabled(This->s    2752       This->setSuperimpositionEnabled(This->superimposition, FALSE);
2753       This->maxSpeed = 0.0f;                     2753       This->maxSpeed = 0.0f;
2754       This->scheduleRedraw();                    2754       This->scheduleRedraw();
2755       This->restoreCamera();                     2755       This->restoreCamera();
2756       This->currentState = This->prevState;      2756       This->currentState = This->prevState;
2757    } else if (This->currentState == VIEWPOINT    2757    } else if (This->currentState == VIEWPOINT)
2758       This->setSuperimpositionEnabled(This->s    2758       This->setSuperimpositionEnabled(This->superimposition, FALSE);
2759                                                  2759 
2760    elementField = value;                         2760    elementField = value;
2761                                                  2761 
2762    int idx = elementField.find_last_of("[");     2762    int idx = elementField.find_last_of("[");
2763    if(idx == -1)                                 2763    if(idx == -1)
2764       idx = elementField.size(); //if "[" not    2764       idx = elementField.size(); //if "[" not found for whatever reason (list not sorted)
2765    else                                          2765    else
2766       idx--; // To get rid of the space that     2766       idx--; // To get rid of the space that is between the name and '['
2767                                                  2767 
2768    bool error = false;                           2768    bool error = false;
2769    SoFullPath *path;                             2769    SoFullPath *path;
2770    SoSearchAction search;                        2770    SoSearchAction search;
2771    SoNode *root = This->getSceneManager()->ge    2771    SoNode *root = This->getSceneManager()->getSceneGraph();
2772    int counter(1), idxUnderscore = elementFie    2772    int counter(1), idxUnderscore = elementField.find_last_of("_");
2773                                                  2773 
2774    This->parseString<int>(counter, elementFie    2774    This->parseString<int>(counter, elementField.substr(idxUnderscore + 1, idx), error);
2775                                                  2775 
2776    SoBaseKit::setSearchingChildren(TRUE);        2776    SoBaseKit::setSearchingChildren(TRUE);
2777    search.reset();                               2777    search.reset();
2778    search.setSearchingAll(TRUE);                 2778    search.setSearchingAll(TRUE);
2779                                                  2779 
2780    if(error) { // No counter is present => el    2780    if(error) { // No counter is present => element name was not modified
2781       This->curEltName = elementField.substr(    2781       This->curEltName = elementField.substr(0, idx);
2782       search.setName(This->curEltName.c_str()    2782       search.setName(This->curEltName.c_str());
2783       search.apply(root);                        2783       search.apply(root);
2784                                                  2784 
2785       path = (SoFullPath *)search.getPath();     2785       path = (SoFullPath *)search.getPath();
2786    }                                             2786    }
2787    else {                                        2787    else {
2788       This->curEltName = elementField.substr(    2788       This->curEltName = elementField.substr(0, idxUnderscore);
2789       search.setInterest(SoSearchAction::ALL)    2789       search.setInterest(SoSearchAction::ALL);
2790       search.setName(This->curEltName.c_str()    2790       search.setName(This->curEltName.c_str());
2791       search.apply(root);                        2791       search.apply(root);
2792                                                  2792 
2793       SoPathList &pl = search.getPaths();        2793       SoPathList &pl = search.getPaths();
2794       path = (SoFullPath *)pl[counter - 1]; /    2794       path = (SoFullPath *)pl[counter - 1]; // Since counter starts at 1, not 0
2795    }                                             2795    }
2796                                                  2796 
2797    G4ThreeVector global;                         2797    G4ThreeVector global;
2798                                                  2798 
2799    if ((idx > 0) && (path)) {                    2799    if ((idx > 0) && (path)) {
2800                                                  2800 
2801       if(!This->refParticleTrajectory.empty()    2801       if(!This->refParticleTrajectory.empty()){
2802                                                  2802 
2803          SoGetBoundingBoxAction bAction(This-    2803          SoGetBoundingBoxAction bAction(This->getViewportRegion());
2804          bAction.apply(path);                    2804          bAction.apply(path);
2805          SbBox3f bBox = bAction.getBoundingBo    2805          SbBox3f bBox = bAction.getBoundingBox();
2806          SbVec3f elementCoord = bBox.getCente    2806          SbVec3f elementCoord = bBox.getCenter();
2807                                                  2807 
2808          This->refParticleIdx = 0;               2808          This->refParticleIdx = 0;
2809          SbVec3f p;                              2809          SbVec3f p;
2810                                                  2810 
2811          float absLengthNow, absLengthMin;       2811          float absLengthNow, absLengthMin;
2812          int maxIdx = This->refParticleTrajec    2812          int maxIdx = This->refParticleTrajectory.size() - 2;
2813          int targetIdx = 0;                      2813          int targetIdx = 0;
2814          SbVec3f dir;                            2814          SbVec3f dir;
2815                                                  2815 
2816          p = This->refParticleTrajectory[This    2816          p = This->refParticleTrajectory[This->refParticleIdx];
2817          absLengthMin = (p - elementCoord).le    2817          absLengthMin = (p - elementCoord).length();
2818          This->refParticleIdx++;                 2818          This->refParticleIdx++;
2819                                                  2819 
2820          // Find a ref. particle's point clos    2820          // Find a ref. particle's point closest to element's global coords
2821          while (This->refParticleIdx < maxIdx    2821          while (This->refParticleIdx < maxIdx) {
2822             p = This->refParticleTrajectory[T    2822             p = This->refParticleTrajectory[This->refParticleIdx];
2823             absLengthNow = (p - elementCoord)    2823             absLengthNow = (p - elementCoord).length();
2824                                                  2824 
2825             if (absLengthNow < absLengthMin)     2825             if (absLengthNow < absLengthMin) {
2826                absLengthMin = absLengthNow;      2826                absLengthMin = absLengthNow;
2827                targetIdx = This->refParticleI    2827                targetIdx = This->refParticleIdx;
2828             }                                    2828             }
2829             This->refParticleIdx++;              2829             This->refParticleIdx++;
2830          }                                       2830          }
2831                                                  2831 
2832          if (This->currentState != BEAMLINE)     2832          if (This->currentState != BEAMLINE) { // Set up default zoom
2833             SbVec3f p1, pN;                      2833             SbVec3f p1, pN;
2834             This->currentState = BEAMLINE;       2834             This->currentState = BEAMLINE;
2835             This->prevParticleDir = SbVec3f(0    2835             This->prevParticleDir = SbVec3f(0,0,0); //so that moveCamera() knows sets default parameters
2836                                                  2836             
2837             p1 = This->prevPt = This->refPart    2837             p1 = This->prevPt = This->refParticleTrajectory[0];
2838             pN = This->refParticleTrajectory[    2838             pN = This->refParticleTrajectory[This->refParticleTrajectory.size() - 1];
2839             This->distance = (pN - p1).length    2839             This->distance = (pN - p1).length() / 10;
2840                                                  2840 
2841             // FWJ Rather than switching to a    2841             // FWJ Rather than switching to a default height, it is more flexible
2842             // to keep the same height(magnif    2842             // to keep the same height(magnification) while moving the camera.
2843             // if (cam->isOfType(SoOrthograph    2843             // if (cam->isOfType(SoOrthographicCamera::getClassTypeId())) {
2844             //    ((SoOrthographicCamera *) c    2844             //    ((SoOrthographicCamera *) cam)->height.setValue(This->defaultHeight);
2845             // // FWJ Restore the default hei    2845             // // FWJ Restore the default height instead of hard-wired value
2846             // // ((SoOrthographicCamera *) c    2846             // // ((SoOrthographicCamera *) cam)->height.setValue(10000.0f);
2847             // }                                 2847             // }
2848             // else if (cam->isOfType(SoPersp    2848             // else if (cam->isOfType(SoPerspectiveCamera::getClassTypeId()))
2849                                                  2849 
2850             // FWJ required to avoid extreme     2850             // FWJ required to avoid extreme perspective after camera move:
2851             if (cam->isOfType(SoPerspectiveCa    2851             if (cam->isOfType(SoPerspectiveCamera::getClassTypeId()))
2852                ((SoPerspectiveCamera*)cam)->h    2852                ((SoPerspectiveCamera*)cam)->heightAngle.setValue(This->defaultHeightAngle);
2853                                                  2853 
2854          } else {                                2854          } else {
2855             if (cam->isOfType(SoPerspectiveCa    2855             if (cam->isOfType(SoPerspectiveCamera::getClassTypeId()))
2856                This->distance = (This->prevPt    2856                This->distance = (This->prevPt - cam->position.getValue()).length();
2857          }                                       2857          }
2858          This->refParticleIdx = targetIdx;       2858          This->refParticleIdx = targetIdx;
2859                                                  2859 
2860          ////////////////////////////////////    2860          //////////////////////////////////////////////////////////////
2861          This->setSuperimpositionEnabled(This    2861          This->setSuperimpositionEnabled(This->superimposition, TRUE);
2862          This->axisSwitch->whichChild.setValu    2862          This->axisSwitch->whichChild.setValue(SO_SWITCH_NONE);
2863          This->animSpeedOutlineSwitch->whichC    2863          This->animSpeedOutlineSwitch->whichChild.setValue(SO_SWITCH_NONE);
2864          This->animSpeedSwitch->whichChild.se    2864          This->animSpeedSwitch->whichChild.setValue(SO_SWITCH_NONE);
2865          This->scheduleRedraw();                 2865          This->scheduleRedraw();
2866          ////////////////////////////////////    2866          //////////////////////////////////////////////////////////////
2867                                                  2867 
2868          This->moveCamera(This->distance);       2868          This->moveCamera(This->distance);
2869          XtFree(value);                          2869          XtFree(value);
2870                                                  2870 
2871       }                                          2871       }
2872                                                  2872       
2873       else{                                      2873       else{
2874          This->offsetFromCenter.setValue(0, 0    2874          This->offsetFromCenter.setValue(0, 0, 1);
2875          This->distance = 50;// small number     2875          This->distance = 50;// small number since using viewAll() for default zoom
2876          This->upVector.setValue(0, 1, 0);       2876          This->upVector.setValue(0, 1, 0);
2877          This->moveCamera(This->distance);       2877          This->moveCamera(This->distance);
2878          cam->viewAll(path, This->getViewport    2878          cam->viewAll(path, This->getViewportRegion());
2879       }                                          2879       }
2880    }                                             2880    }
2881                                                  2881 
2882    XmTextSetString(This->viewPtSelection, NUL    2882    XmTextSetString(This->viewPtSelection, NULL);
2883 }                                                2883 }
2884                                                  2884 
2885                                                  2885 
2886 // Destroyes listsDialog and resets necessary    2886 // Destroyes listsDialog and resets necessary member fields.
2887                                                  2887 
2888 void G4OpenInventorXtExaminerViewer::closeLis    2888 void G4OpenInventorXtExaminerViewer::closeListsDialogCB(Widget, 
2889                                          XtPo    2889                                          XtPointer client_data,
2890                                          XtPo    2890                                          XtPointer)
2891 {                                                2891 {
2892    G4OpenInventorXtExaminerViewer * This = (G    2892    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
2893                                                  2893 
2894    This->sceneElements.clear();                  2894    This->sceneElements.clear();
2895    This->refParticleTrajectory.clear();          2895    This->refParticleTrajectory.clear();
2896                                                  2896 
2897    This->currentState = GENERAL;                 2897    This->currentState = GENERAL;
2898    XtDestroyWidget(This->myShellDialog);         2898    XtDestroyWidget(This->myShellDialog);
2899    This->listsDialog = NULL;                     2899    This->listsDialog = NULL;
2900 }                                                2900 }
2901                                                  2901 
2902 // Called when user clicks left arrow button.    2902 // Called when user clicks left arrow button. Loads previous viewpoint.
2903 void G4OpenInventorXtExaminerViewer::prevView    2903 void G4OpenInventorXtExaminerViewer::prevViewPtCB(Widget, XtPointer client_data,
2904                                                  2904                                                   XtPointer) {
2905    G4OpenInventorXtExaminerViewer * This = (G    2905    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
2906                                                  2906 
2907    if (This->viewPtIdx == 0)                     2907    if (This->viewPtIdx == 0)
2908       This->viewPtIdx = This->viewPtList.size    2908       This->viewPtIdx = This->viewPtList.size() - 1;
2909    else                                          2909    else
2910       This->viewPtIdx--;                         2910       This->viewPtIdx--;
2911                                                  2911 
2912    This->writeViewPtIdx();                       2912    This->writeViewPtIdx();
2913    This->setViewPt();                            2913    This->setViewPt();
2914 }                                                2914 }
2915                                                  2915 
2916 // Called when user clicks right arrow button    2916 // Called when user clicks right arrow button. Loads next viewpoint.
2917 void G4OpenInventorXtExaminerViewer::nextView    2917 void G4OpenInventorXtExaminerViewer::nextViewPtCB(Widget, XtPointer client_data,
2918                                                  2918                                                   XtPointer) {
2919    G4OpenInventorXtExaminerViewer * This = (G    2919    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
2920                                                  2920 
2921    if (This->viewPtIdx >= (int) This->viewPtL    2921    if (This->viewPtIdx >= (int) This->viewPtList.size() - 1)
2922       This->viewPtIdx = 0;                       2922       This->viewPtIdx = 0;
2923    else                                          2923    else
2924       This->viewPtIdx++;                         2924       This->viewPtIdx++;
2925                                                  2925 
2926    This->writeViewPtIdx();                       2926    This->writeViewPtIdx();
2927    This->setViewPt();                            2927    This->setViewPt();
2928 }                                                2928 }
2929                                                  2929 
2930                                                  2930 
2931 // Updates the viewPtIdx in a viewpoint file.    2931 // Updates the viewPtIdx in a viewpoint file.
2932                                                  2932 
2933 void G4OpenInventorXtExaminerViewer::writeVie    2933 void G4OpenInventorXtExaminerViewer::writeViewPtIdx()
2934 {                                                2934 {
2935    std::string idxStr;                           2935    std::string idxStr;
2936    std::stringstream out;                        2936    std::stringstream out;
2937    out << viewPtIdx;                             2937    out << viewPtIdx;
2938    idxStr = out.str();                           2938    idxStr = out.str();
2939    fileOut.seekp(0, std::ios::beg);              2939    fileOut.seekp(0, std::ios::beg);
2940                                                  2940 
2941    while ((int) idxStr.length() < MAX_VP_IDX)    2941    while ((int) idxStr.length() < MAX_VP_IDX) {
2942       idxStr += " ";                             2942       idxStr += " ";
2943    }                                             2943    }
2944                                                  2944 
2945    fileOut << idxStr << "\n";                    2945    fileOut << idxStr << "\n";
2946    fileOut.flush();                              2946    fileOut.flush();
2947    fileOut.seekp(0, std::ios::end);              2947    fileOut.seekp(0, std::ios::end);
2948 }                                                2948 }
2949                                                  2949 
2950                                                  2950 
2951 // Sets the viewpoint based on camera data th    2951 // Sets the viewpoint based on camera data that viewPtIdx is pointing to.
2952                                                  2952 
2953 void G4OpenInventorXtExaminerViewer::setViewP    2953 void G4OpenInventorXtExaminerViewer::setViewPt()
2954 {                                                2954 {
2955    if (currentState == ANIMATION || currentSt    2955    if (currentState == ANIMATION || currentState == REVERSED_ANIMATION
2956        || currentState == ROTATING) {            2956        || currentState == ROTATING) {
2957                                                  2957 
2958       if (animateSensor->isScheduled())          2958       if (animateSensor->isScheduled())
2959          animateSensor->unschedule();            2959          animateSensor->unschedule();
2960       setSuperimpositionEnabled(superimpositi    2960       setSuperimpositionEnabled(superimposition, FALSE);
2961       maxSpeed = 0.0f;                           2961       maxSpeed = 0.0f;
2962       scheduleRedraw();                          2962       scheduleRedraw();
2963    }                                             2963    }
2964                                                  2964 
2965    SoCamera * camera = getCamera();              2965    SoCamera * camera = getCamera();
2966    if (camera == NULL) {                         2966    if (camera == NULL) {
2967       String dialogName = (char *) "Missing C    2967       String dialogName = (char *) "Missing Camera Node";
2968       std::string msg = "Camera is null. Unab    2968       std::string msg = "Camera is null. Unable to set the viewpoint.";
2969       warningMsgDialog(msg, dialogName, NULL)    2969       warningMsgDialog(msg, dialogName, NULL);
2970       return;                                    2970       return;
2971    }                                             2971    }
2972                                                  2972 
2973    if (!viewPtList.size()) {                     2973    if (!viewPtList.size()) {
2974       String dialogName = (char *) "Missing V    2974       String dialogName = (char *) "Missing Viewpoints";
2975       std::string msg = "There are no viewpoi    2975       std::string msg = "There are no viewpoints to load.";
2976       warningMsgDialog(msg, dialogName, NULL)    2976       warningMsgDialog(msg, dialogName, NULL);
2977       return;                                    2977       return;
2978    }                                             2978    }
2979                                                  2979 
2980    if (SoXtExaminerViewer::isAnimating())        2980    if (SoXtExaminerViewer::isAnimating())
2981       stopAnimating();                           2981       stopAnimating();
2982                                                  2982 
2983    if (currentState != VIEWPOINT) {              2983    if (currentState != VIEWPOINT) {
2984       currentState = VIEWPOINT;                  2984       currentState = VIEWPOINT;
2985       ///////////////////////////////////////    2985       //////////////////////////////////////////////////////////////
2986       setSuperimpositionEnabled(superimpositi    2986       setSuperimpositionEnabled(superimposition, TRUE);
2987       axisSwitch->whichChild.setValue(SO_SWIT    2987       axisSwitch->whichChild.setValue(SO_SWITCH_NONE);
2988       animSpeedOutlineSwitch->whichChild.setV    2988       animSpeedOutlineSwitch->whichChild.setValue(SO_SWITCH_NONE);
2989       animSpeedSwitch->whichChild.setValue(SO    2989       animSpeedSwitch->whichChild.setValue(SO_SWITCH_NONE);
2990                                                  2990 
2991       scheduleRedraw();                          2991       scheduleRedraw();
2992       ///////////////////////////////////////    2992       ///////////////////////////////////////////////////////////////
2993    }                                             2993    }
2994                                                  2994 
2995    curViewPtName = viewPtList[viewPtIdx].view    2995    curViewPtName = viewPtList[viewPtIdx].viewPtName;
2996    camera->viewportMapping = viewPtList[viewP    2996    camera->viewportMapping = viewPtList[viewPtIdx].viewportMapping;
2997    camera->position = viewPtList[viewPtIdx].p    2997    camera->position = viewPtList[viewPtIdx].position;
2998    camera->orientation = viewPtList[viewPtIdx    2998    camera->orientation = viewPtList[viewPtIdx].orientation;
2999    camera->aspectRatio = viewPtList[viewPtIdx    2999    camera->aspectRatio = viewPtList[viewPtIdx].aspectRatio;
3000    camera->nearDistance = viewPtList[viewPtId    3000    camera->nearDistance = viewPtList[viewPtIdx].nearDistance;
3001    camera->farDistance = viewPtList[viewPtIdx    3001    camera->farDistance = viewPtList[viewPtIdx].farDistance;
3002    camera->focalDistance = viewPtList[viewPtI    3002    camera->focalDistance = viewPtList[viewPtIdx].focalDistance;
3003                                                  3003 
3004    // Restore camera height (changed by zoomi    3004    // Restore camera height (changed by zooming)
3005    if (camera->isOfType(SoPerspectiveCamera::    3005    if (camera->isOfType(SoPerspectiveCamera::getClassTypeId())) {
3006       if (viewPtList[viewPtIdx].camType == OR    3006       if (viewPtList[viewPtIdx].camType == ORTHOGRAPHIC) {
3007          toggleCameraType();                     3007          toggleCameraType();
3008          camera = getCamera();                   3008          camera = getCamera();
3009          ((SoOrthographicCamera *) camera)->h    3009          ((SoOrthographicCamera *) camera)->height.setValue(
3010                                                  3010                                                             viewPtList[viewPtIdx].height);
3011       } else                                     3011       } else
3012          ((SoPerspectiveCamera *) camera)->he    3012          ((SoPerspectiveCamera *) camera)->heightAngle.setValue(
3013                                                  3013                                                                 viewPtList[viewPtIdx].height);
3014    } else if (camera->isOfType(SoOrthographic    3014    } else if (camera->isOfType(SoOrthographicCamera::getClassTypeId())) {
3015       if (viewPtList[viewPtIdx].camType == PE    3015       if (viewPtList[viewPtIdx].camType == PERSPECTIVE) {
3016          toggleCameraType();                     3016          toggleCameraType();
3017          camera = getCamera();                   3017          camera = getCamera();
3018          ((SoPerspectiveCamera *) camera)->he    3018          ((SoPerspectiveCamera *) camera)->heightAngle.setValue(
3019                                                  3019                                                                 viewPtList[viewPtIdx].height);
3020       } else                                     3020       } else
3021          ((SoOrthographicCamera *) camera)->h    3021          ((SoOrthographicCamera *) camera)->height.setValue(
3022                                                  3022                                                             viewPtList[viewPtIdx].height);
3023    } else {                                      3023    } else {
3024       SoDebugError::post("G4OpenInventorXtExa    3024       SoDebugError::post("G4OpenInventorXtExaminerViewer::setViewPt",
3025                          "Only Perspective an    3025                          "Only Perspective and Orthographic cameras are supported.");
3026       return;                                    3026       return;
3027    }                                             3027    }
3028                                                  3028 
3029 }                                                3029 }
3030                                                  3030 
3031                                                  3031 
3032 // Pops up a prompt asking for a new viewpoin    3032 // Pops up a prompt asking for a new viewpoint name.
3033                                                  3033 
3034 void G4OpenInventorXtExaminerViewer::saveView    3034 void G4OpenInventorXtExaminerViewer::saveViewPtCB(Widget w, 
3035                                      XtPointe    3035                                      XtPointer client_data,
3036                                      XtPointe    3036                                      XtPointer)
3037 {                                                3037 {
3038    G4OpenInventorXtExaminerViewer * This = (G    3038    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
3039                                                  3039 
3040    if (This->fileName.empty()) {                 3040    if (This->fileName.empty()) {
3041       newViewPtFileCB(w, This, NULL);            3041       newViewPtFileCB(w, This, NULL);
3042       This->returnToSaveVP = true;               3042       This->returnToSaveVP = true;
3043       return; // Need to return and call this    3043       return; // Need to return and call this fn again from newViewPtFileCB since flow of control does not stall here but keeps going
3044    }                                             3044    }
3045                                                  3045 
3046    int n = 0;                                    3046    int n = 0;
3047    Arg args[4];                                  3047    Arg args[4];
3048    Widget nameViewPtDialog;                      3048    Widget nameViewPtDialog;
3049    Widget parent = This->getParentWidget(); /    3049    Widget parent = This->getParentWidget(); //gets the dialogshell of the ExaminerViewer widget
3050    XmString label = XmStringCreateLocalized((    3050    XmString label = XmStringCreateLocalized((char *) "Name the viewpoint:");
3051                                                  3051 
3052    XtSetArg(args[n], XmNselectionLabelString,    3052    XtSetArg(args[n], XmNselectionLabelString, label); n++;
3053 // Prevent the dialog from closing automatica    3053 // Prevent the dialog from closing automatically, in case the name is wrong
3054    XtSetArg(args[n], XmNautoUnmanage, False);    3054    XtSetArg(args[n], XmNautoUnmanage, False); n++;
3055 // FWJ                                           3055 // FWJ
3056    XtSetArg(args[n], XmNtitle, "Save Bookmark    3056    XtSetArg(args[n], XmNtitle, "Save Bookmark"); n++;
3057    nameViewPtDialog = XmCreatePromptDialog(pa    3057    nameViewPtDialog = XmCreatePromptDialog(parent, String("Save Bookmark"),
3058                                            ar    3058                                            args, n);
3059                                                  3059 
3060    XmStringFree(label);                          3060    XmStringFree(label);
3061    XtAddCallback(nameViewPtDialog, XmNokCallb    3061    XtAddCallback(nameViewPtDialog, XmNokCallback, getViewPtNameCB, This);
3062    XtAddCallback(nameViewPtDialog, XmNcancelC    3062    XtAddCallback(nameViewPtDialog, XmNcancelCallback,
3063                  getViewPtNameCancelCB, This)    3063                  getViewPtNameCancelCB, This);
3064    // Coverity gcc8 bad cast warning             3064    // Coverity gcc8 bad cast warning
3065    //            (XtCallbackProc) XtDestroyWi    3065    //            (XtCallbackProc) XtDestroyWidget, NULL);
3066                                                  3066 
3067    Widget text = XtNameToWidget(nameViewPtDia    3067    Widget text = XtNameToWidget(nameViewPtDialog, "Text");
3068    XtVaSetValues(text, XmNmaxLength, This->MA    3068    XtVaSetValues(text, XmNmaxLength, This->MAX_VP_NAME, NULL);
3069    std::string autoName = "";                    3069    std::string autoName = "";
3070    if (!This->warningFlag) { //leave the Text    3070    if (!This->warningFlag) { //leave the TextField as it is if coming back from warning dialog
3071       autoName = This->viewPtAutoName();         3071       autoName = This->viewPtAutoName();
3072    }                                             3072    }
3073    This->warningFlag = false;                    3073    This->warningFlag = false;
3074    XmTextSetString(text, (char *) autoName.c_    3074    XmTextSetString(text, (char *) autoName.c_str());
3075    XmTextSetInsertionPosition(text, autoName.    3075    XmTextSetInsertionPosition(text, autoName.length());
3076                                                  3076 
3077    XtUnmanageChild(XtNameToWidget(nameViewPtD    3077    XtUnmanageChild(XtNameToWidget(nameViewPtDialog, "Help"));
3078    XtManageChild(nameViewPtDialog);              3078    XtManageChild(nameViewPtDialog);
3079 }                                                3079 }
3080                                                  3080 
3081                                                  3081 
3082 std::string G4OpenInventorXtExaminerViewer::v    3082 std::string G4OpenInventorXtExaminerViewer::viewPtAutoName()
3083 {                                                3083 {
3084    std::string viewPt;                           3084    std::string viewPt;
3085    std::stringstream sstream;                    3085    std::stringstream sstream;
3086    std::vector<int> existingViewPts;             3086    std::vector<int> existingViewPts;
3087    int tmp;                                      3087    int tmp;
3088                                                  3088 
3089    //Build the list of names of the form view    3089    //Build the list of names of the form viewpoint_* already present
3090    for (unsigned int i = 0; i < this->viewPtL    3090    for (unsigned int i = 0; i < this->viewPtList.size(); ++i) {
3091       viewPt = this->viewPtList[i].viewPtName    3091       viewPt = this->viewPtList[i].viewPtName;
3092       if (viewPt.find("viewpoint_") != std::s    3092       if (viewPt.find("viewpoint_") != std::string::npos) {
3093          tmp = atoi(viewPt.substr(10).c_str()    3093          tmp = atoi(viewPt.substr(10).c_str());
3094          if (tmp == 0) {                         3094          if (tmp == 0) {
3095             //0 means couldn't convert to int    3095             //0 means couldn't convert to integer OR viewpoint_0
3096             if (!viewPt.compare("viewpoint_0"    3096             if (!viewPt.compare("viewpoint_0"))
3097                existingViewPts.push_back(0);     3097                existingViewPts.push_back(0);
3098          } else                                  3098          } else
3099             existingViewPts.push_back(tmp);      3099             existingViewPts.push_back(tmp);
3100       }                                          3100       }
3101    }                                             3101    }
3102                                                  3102 
3103    sstream.str("");                              3103    sstream.str("");
3104    sstream.clear();                              3104    sstream.clear();
3105                                                  3105 
3106    //Return the view viewpoint_* name availab    3106    //Return the view viewpoint_* name available
3107    if (existingViewPts.size() > 0) {             3107    if (existingViewPts.size() > 0) {
3108       int vpNum = 0;                             3108       int vpNum = 0;
3109       while (true) {                             3109       while (true) {
3110          if (std::find(existingViewPts.begin(    3110          if (std::find(existingViewPts.begin(), existingViewPts.end(), vpNum)
3111              == existingViewPts.end()) {         3111              == existingViewPts.end()) {
3112             sstream << "viewpoint_" << vpNum;    3112             sstream << "viewpoint_" << vpNum;
3113             return sstream.str();                3113             return sstream.str();
3114          }                                       3114          }
3115          ++vpNum;                                3115          ++vpNum;
3116       }                                          3116       }
3117    } else {                                      3117    } else {
3118       return "viewpoint_0";                      3118       return "viewpoint_0";
3119    }                                             3119    }
3120    return "";                                    3120    return "";
3121 }                                                3121 }
3122                                                  3122 
3123                                                  3123 
3124 void G4OpenInventorXtExaminerViewer::abbrOutp    3124 void G4OpenInventorXtExaminerViewer::abbrOutputCB(Widget,
3125                                    XtPointer     3125                                    XtPointer client_data,
3126                                    XtPointer)    3126                                    XtPointer)
3127 {                                                3127 {
3128    G4OpenInventorXtExaminerViewer * This =       3128    G4OpenInventorXtExaminerViewer * This =
3129       (G4OpenInventorXtExaminerViewer *) clie    3129       (G4OpenInventorXtExaminerViewer *) client_data;
3130 // G4cout << "DISARMCALLBACK abbrOutputFlag="    3130 // G4cout << "DISARMCALLBACK abbrOutputFlag=" << This->abbrOutputFlag << G4endl;
3131    This->abbrOutputFlag = !(This->abbrOutputF    3131    This->abbrOutputFlag = !(This->abbrOutputFlag);
3132 }                                                3132 }
3133                                                  3133 
3134                                                  3134 
3135 void G4OpenInventorXtExaminerViewer::pickRefP    3135 void G4OpenInventorXtExaminerViewer::pickRefPathCB(Widget,
3136                                     XtPointer    3136                                     XtPointer client_data,
3137                                     XtPointer    3137                                     XtPointer)
3138 {                                                3138 {
3139    G4OpenInventorXtExaminerViewer * This = (G    3139    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
3140                                                  3140 
3141    // Save viewing state and go to picking mo    3141    // Save viewing state and go to picking mode
3142    This->viewingBeforePickRef = This->isViewi    3142    This->viewingBeforePickRef = This->isViewing();
3143    if(This->isViewing())                         3143    if(This->isViewing())
3144       This->setViewing(false);                   3144       This->setViewing(false);
3145    This->setComponentCursor(SoXtCursor(SoXtCu    3145    This->setComponentCursor(SoXtCursor(SoXtCursor::CROSSHAIR));
3146    This->pickRefPathFlag = true;                 3146    This->pickRefPathFlag = true;
3147 }                                                3147 }
3148                                                  3148 
3149                                                  3149 
3150 void G4OpenInventorXtExaminerViewer::switchWi    3150 void G4OpenInventorXtExaminerViewer::switchWireFrameCB(Widget w,
3151                                     XtPointer    3151                                     XtPointer client_data,
3152                                     XtPointer    3152                                     XtPointer)
3153 {                                                3153 {
3154    G4OpenInventorXtExaminerViewer* This =        3154    G4OpenInventorXtExaminerViewer* This = 
3155       (G4OpenInventorXtExaminerViewer*)client    3155       (G4OpenInventorXtExaminerViewer*)client_data;
3156    //   xmToggleButton theToggleButton = (xmT    3156    //   xmToggleButton theToggleButton = (xmToggleButton)w;
3157    if (XmToggleButtonGetState(w)) {              3157    if (XmToggleButtonGetState(w)) {
3158          This->setDrawStyle(SoXtViewer::STILL    3158          This->setDrawStyle(SoXtViewer::STILL, SoXtViewer::VIEW_LINE);
3159          This->setDrawStyle(SoXtViewer::INTER    3159          This->setDrawStyle(SoXtViewer::INTERACTIVE, SoXtViewer::VIEW_LINE);
3160       } else {                                   3160       } else {
3161          This->setDrawStyle(SoXtViewer::STILL    3161          This->setDrawStyle(SoXtViewer::STILL, SoXtViewer::VIEW_AS_IS);
3162          This->setDrawStyle(SoXtViewer::INTER    3162          This->setDrawStyle(SoXtViewer::INTERACTIVE,
3163                             SoXtViewer::VIEW_    3163                             SoXtViewer::VIEW_SAME_AS_STILL);
3164       }                                          3164       }
3165 }                                                3165 }
3166                                                  3166 
3167                                                  3167 
3168 // Examines new viewpoint name and if OK call    3168 // Examines new viewpoint name and if OK calls saveViewPt.
3169                                                  3169 
3170 void G4OpenInventorXtExaminerViewer::getViewP    3170 void G4OpenInventorXtExaminerViewer::getViewPtNameCB(Widget w, 
3171                                         XtPoi    3171                                         XtPointer client_data,
3172                                         XtPoi    3172                                         XtPointer call_data)
3173 {                                                3173 {
3174    char *name = NULL;                            3174    char *name = NULL;
3175    std::string strName;                          3175    std::string strName;
3176    G4OpenInventorXtExaminerViewer * This = (G    3176    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
3177    XmSelectionBoxCallbackStruct *cbs =           3177    XmSelectionBoxCallbackStruct *cbs =
3178       (XmSelectionBoxCallbackStruct *) call_d    3178       (XmSelectionBoxCallbackStruct *) call_data;
3179    XmStringGetLtoR(cbs->value, XmFONTLIST_DEF    3179    XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &name);
3180                                                  3180 
3181    if (!name) {                                  3181    if (!name) {
3182       return;                                    3182       return;
3183    }                                             3183    }
3184    if (!*name) {                                 3184    if (!*name) {
3185       XtFree(name);                              3185       XtFree(name);
3186       return;                                    3186       return;
3187    }                                             3187    }
3188                                                  3188 
3189    strName = name;                               3189    strName = name;
3190    XtFree(name);                                 3190    XtFree(name);
3191                                                  3191 
3192    int beg = strName.find_first_not_of(' ');     3192    int beg = strName.find_first_not_of(' '); // Remove leading/trailing spaces
3193    int end = strName.find_last_not_of(' ');      3193    int end = strName.find_last_not_of(' ');
3194    strName = strName.substr(beg, end - beg +     3194    strName = strName.substr(beg, end - beg + 1);
3195                                                  3195 
3196    bool nameExists = false;                      3196    bool nameExists = false;
3197    int size = This->viewPtList.size();           3197    int size = This->viewPtList.size();
3198    for (int i = 0; i < size; i++) {              3198    for (int i = 0; i < size; i++) {
3199       if (!strcmp(This->viewPtList[i].viewPtN    3199       if (!strcmp(This->viewPtList[i].viewPtName, strName.c_str())) {
3200          nameExists = true;                      3200          nameExists = true;
3201          break;                                  3201          break;
3202       }                                          3202       }
3203    }                                             3203    }
3204                                                  3204 
3205    if (!nameExists) {                            3205    if (!nameExists) {
3206       const int nVPName = This->MAX_VP_NAME +    3206       const int nVPName = This->MAX_VP_NAME + 1;
3207       name = new char[nVPName];                  3207       name = new char[nVPName];
3208       strncpy(name, strName.c_str(), nVPName)    3208       strncpy(name, strName.c_str(), nVPName);
3209       if (This->viewPtIdx == -1)                 3209       if (This->viewPtIdx == -1)
3210          This->viewPtIdx = 0;                    3210          This->viewPtIdx = 0;
3211       This->saveViewPt(name);                    3211       This->saveViewPt(name);
3212       if (This->listsDialog) {                   3212       if (This->listsDialog) {
3213          XmListAddItemUnselected(This->myView    3213          XmListAddItemUnselected(This->myViewPtList, cbs->value, 0); // vpName
3214       }                                          3214       }
3215       //Dismiss the nameViewPtDialog dialog      3215       //Dismiss the nameViewPtDialog dialog
3216       XtUnmanageChild(w);                        3216       XtUnmanageChild(w);
3217    } else {                                      3217    } else {
3218       String dialogName = (char *) "Existing     3218       String dialogName = (char *) "Existing Viewpoint";
3219       std::string msg = "The viewpoint alread    3219       std::string msg = "The viewpoint already exists.";
3220       This->warningMsgDialog(msg, dialogName,    3220       This->warningMsgDialog(msg, dialogName, NULL);
3221                                                  3221 
3222    }                                             3222    }
3223 }                                                3223 }
3224                                                  3224 
3225 void G4OpenInventorXtExaminerViewer::getViewP    3225 void G4OpenInventorXtExaminerViewer::getViewPtNameCancelCB(Widget w,
3226                                         XtPoi    3226                                         XtPointer,
3227                                         XtPoi    3227                                         XtPointer)
3228 {                                                3228 {
3229    XtUnmanageChild(w);                           3229    XtUnmanageChild(w);
3230 }                                                3230 }   
3231                                                  3231 
3232                                                  3232 
3233 // Saves current camera parameters to a viewp    3233 // Saves current camera parameters to a viewpoint file.
3234                                                  3234 
3235 void G4OpenInventorXtExaminerViewer::saveView    3235 void G4OpenInventorXtExaminerViewer::saveViewPt(char *name)
3236 {                                                3236 {
3237    SbVec3f axis;                                 3237    SbVec3f axis;
3238    viewPtData tmp;                               3238    viewPtData tmp;
3239    float x, y, z, angle;                         3239    float x, y, z, angle;
3240    SoCamera * camera = getCamera();              3240    SoCamera * camera = getCamera();
3241                                                  3241 
3242    if (viewPtList.size() == 0) {                 3242    if (viewPtList.size() == 0) {
3243       writeViewPtIdx();                          3243       writeViewPtIdx();
3244       XtSetSensitive(nextViewPtButton, True);    3244       XtSetSensitive(nextViewPtButton, True); // Makes arrow buttons clickable
3245       XtSetSensitive(prevViewPtButton, True);    3245       XtSetSensitive(prevViewPtButton, True);
3246    }                                             3246    }
3247                                                  3247 
3248    tmp.viewPtName = name;                        3248    tmp.viewPtName = name;
3249    tmp.viewportMapping = camera->viewportMapp    3249    tmp.viewportMapping = camera->viewportMapping.getValue();
3250    tmp.position = camera->position.getValue()    3250    tmp.position = camera->position.getValue();
3251    tmp.orientation = camera->orientation.getV    3251    tmp.orientation = camera->orientation.getValue();
3252    tmp.aspectRatio = camera->aspectRatio.getV    3252    tmp.aspectRatio = camera->aspectRatio.getValue();
3253    tmp.nearDistance = camera->nearDistance.ge    3253    tmp.nearDistance = camera->nearDistance.getValue();
3254    tmp.farDistance = camera->farDistance.getV    3254    tmp.farDistance = camera->farDistance.getValue();
3255    tmp.focalDistance = camera->focalDistance.    3255    tmp.focalDistance = camera->focalDistance.getValue();
3256                                                  3256 
3257    // Save camera height (changed by zooming)    3257    // Save camera height (changed by zooming)
3258    if (camera->isOfType(SoPerspectiveCamera::    3258    if (camera->isOfType(SoPerspectiveCamera::getClassTypeId())) {
3259       tmp.height = ((SoPerspectiveCamera *) c    3259       tmp.height = ((SoPerspectiveCamera *) camera)->heightAngle.getValue();
3260       tmp.camType = PERSPECTIVE;                 3260       tmp.camType = PERSPECTIVE;
3261    } else if (camera->isOfType(SoOrthographic    3261    } else if (camera->isOfType(SoOrthographicCamera::getClassTypeId())) {
3262       tmp.height = ((SoOrthographicCamera *)     3262       tmp.height = ((SoOrthographicCamera *) camera)->height.getValue();
3263       tmp.camType = ORTHOGRAPHIC;                3263       tmp.camType = ORTHOGRAPHIC;
3264    } else {                                      3264    } else {
3265       SoDebugError::post("G4OpenInventorXtExa    3265       SoDebugError::post("G4OpenInventorXtExaminerViewer::saveViewPtCB",
3266                          "Only Perspective an    3266                          "Only Perspective and Orthographic cameras are supported.");
3267       return;                                    3267       return;
3268    }                                             3268    }
3269                                                  3269 
3270    viewPtList.push_back(tmp);                    3270    viewPtList.push_back(tmp);
3271                                                  3271 
3272    // Now save the view point to a .txt file     3272    // Now save the view point to a .txt file
3273    std::string vpName = name;                    3273    std::string vpName = name;
3274                                                  3274 
3275    while ((int) vpName.size() <= MAX_VP_NAME)    3275    while ((int) vpName.size() <= MAX_VP_NAME)
3276       vpName += " ";                             3276       vpName += " ";
3277                                                  3277 
3278    fileOut << vpName << std::endl;               3278    fileOut << vpName << std::endl;
3279    tmp.position.getValue(x, y, z);               3279    tmp.position.getValue(x, y, z);
3280    fileOut << x << " " << y << " " << z << st    3280    fileOut << x << " " << y << " " << z << std::endl;
3281                                                  3281 
3282    // Reusing x, y and z for storing the axis    3282    // Reusing x, y and z for storing the axis
3283    tmp.orientation.getValue(axis, angle);        3283    tmp.orientation.getValue(axis, angle);
3284    axis.getValue(x, y, z);                       3284    axis.getValue(x, y, z);
3285    fileOut << x << " " << y << " " << z << "     3285    fileOut << x << " " << y << " " << z << " " << angle << std::endl;
3286                                                  3286 
3287    fileOut << tmp.camType << " " << tmp.heigh    3287    fileOut << tmp.camType << " " << tmp.height << std::endl;
3288    fileOut << tmp.focalDistance << " ";          3288    fileOut << tmp.focalDistance << " ";
3289    fileOut << tmp.nearDistance << " ";           3289    fileOut << tmp.nearDistance << " ";
3290    fileOut << tmp.farDistance << std::endl;      3290    fileOut << tmp.farDistance << std::endl;
3291    fileOut << tmp.viewportMapping << " ";        3291    fileOut << tmp.viewportMapping << " ";
3292    fileOut << tmp.aspectRatio << "\n" << std:    3292    fileOut << tmp.aspectRatio << "\n" << std::endl;
3293    fileOut.flush();                              3293    fileOut.flush();
3294    viewPtIdx++;                                  3294    viewPtIdx++;
3295 }                                                3295 }
3296                                                  3296 
3297                                                  3297 
3298 void G4OpenInventorXtExaminerViewer::deleteVi    3298 void G4OpenInventorXtExaminerViewer::deleteViewPtCB(Widget,
3299                                      XtPointe    3299                                      XtPointer client_data,
3300                                      XtPointe    3300                                      XtPointer)
3301 {                                                3301 {
3302    G4OpenInventorXtExaminerViewer * This =       3302    G4OpenInventorXtExaminerViewer * This =
3303       (G4OpenInventorXtExaminerViewer *) clie    3303       (G4OpenInventorXtExaminerViewer *) client_data;
3304    This->deleteViewPt();                         3304    This->deleteViewPt();
3305 }                                                3305 }
3306                                                  3306 
3307                                                  3307 
3308 // Deletes current viewpoint the user is look    3308 // Deletes current viewpoint the user is looking at.
3309 // Updates the input file and bookmarks as we    3309 // Updates the input file and bookmarks as well.
3310                                                  3310 
3311 void G4OpenInventorXtExaminerViewer::deleteVi    3311 void G4OpenInventorXtExaminerViewer::deleteViewPt(char *vpName)
3312 {                                                3312 {
3313    std::string line;                             3313    std::string line;
3314    int end;                                      3314    int end;
3315    fileIn.open(fileName.c_str());                3315    fileIn.open(fileName.c_str());
3316    std::ofstream out("temporaryFile.txt");       3316    std::ofstream out("temporaryFile.txt");
3317                                                  3317 
3318    if (!vpName)                                  3318    if (!vpName)
3319       vpName = viewPtList[viewPtIdx].viewPtNa    3319       vpName = viewPtList[viewPtIdx].viewPtName;
3320                                                  3320 
3321    if (listsDialog) {                            3321    if (listsDialog) {
3322       XmString vpNameStr = XmStringCreateLoca    3322       XmString vpNameStr = XmStringCreateLocalized(vpName);
3323                                                  3323 
3324       XmListDeleteItem(myViewPtList, vpNameSt    3324       XmListDeleteItem(myViewPtList, vpNameStr);
3325       XmStringFree(vpNameStr);                   3325       XmStringFree(vpNameStr);
3326    }                                             3326    }
3327                                                  3327 
3328    getline(fileIn, line); // Printing the vie    3328    getline(fileIn, line); // Printing the viewpoint idx
3329    out << line << "\n";                          3329    out << line << "\n";
3330                                                  3330 
3331    while (getline(fileIn, line)) {               3331    while (getline(fileIn, line)) {
3332       end = line.find_last_not_of(' ');          3332       end = line.find_last_not_of(' ');
3333       line = line.substr(0, end + 1);            3333       line = line.substr(0, end + 1);
3334       if (!strcmp(line.c_str(), vpName)) { //    3334       if (!strcmp(line.c_str(), vpName)) { // Equal
3335          while (line.size()) {                   3335          while (line.size()) {
3336             getline(fileIn, line);               3336             getline(fileIn, line);
3337          }                                       3337          }
3338                                                  3338 
3339          while (getline(fileIn, line))           3339          while (getline(fileIn, line))
3340             out << line << "\n";                 3340             out << line << "\n";
3341       } else {                                   3341       } else {
3342          while (line.size()) {                   3342          while (line.size()) {
3343             out << line << "\n";                 3343             out << line << "\n";
3344             getline(fileIn, line);               3344             getline(fileIn, line);
3345          }                                       3345          }
3346          out << "\n";                            3346          out << "\n";
3347       }                                          3347       }
3348    }                                             3348    }
3349                                                  3349 
3350    int idx = 0; // Remove viewpoint from the     3350    int idx = 0; // Remove viewpoint from the vector
3351    int size = viewPtList.size();                 3351    int size = viewPtList.size();
3352    while (idx < size) {                          3352    while (idx < size) {
3353       if (!strcmp(viewPtList[idx].viewPtName,    3353       if (!strcmp(viewPtList[idx].viewPtName, vpName)) {
3354          viewPtList.erase(viewPtList.begin()     3354          viewPtList.erase(viewPtList.begin() + idx);
3355          break;                                  3355          break;
3356       }                                          3356       }
3357       idx++;                                     3357       idx++;
3358    }                                             3358    }
3359                                                  3359 
3360    out.close();                                  3360    out.close();
3361    fileOut.close();                              3361    fileOut.close();
3362    fileIn.clear();                               3362    fileIn.clear();
3363    fileIn.close();                               3363    fileIn.close();
3364                                                  3364 
3365    // FWJ check return status                    3365    // FWJ check return status
3366    int istat = remove(fileName.c_str());         3366    int istat = remove(fileName.c_str());
3367    if (istat == -1) {                            3367    if (istat == -1) {
3368       char dialogName[] = "Warning";             3368       char dialogName[] = "Warning";
3369       warningMsgDialog("Error removing bookma    3369       warningMsgDialog("Error removing bookmarks file", dialogName,
3370                        NULL);                    3370                        NULL);
3371    }                                             3371    }
3372    istat = rename("temporaryFile.txt", fileNa    3372    istat = rename("temporaryFile.txt", fileName.c_str());
3373    if (istat == -1) {                            3373    if (istat == -1) {
3374       char dialogName[] = "Warning";             3374       char dialogName[] = "Warning";
3375       warningMsgDialog("Error renaming bookma    3375       warningMsgDialog("Error renaming bookmarks file", dialogName,
3376                        NULL);                    3376                        NULL);
3377    }                                             3377    }
3378    fileOut.open(fileName.c_str(), std::ios::i    3378    fileOut.open(fileName.c_str(), std::ios::in);
3379    fileOut.seekp(0, std::ios::end);              3379    fileOut.seekp(0, std::ios::end);
3380                                                  3380 
3381    if (!viewPtList.size()) { // viewPtList is    3381    if (!viewPtList.size()) { // viewPtList is empty
3382       curViewPtName = (char *) "";               3382       curViewPtName = (char *) "";
3383       scheduleRedraw();                          3383       scheduleRedraw();
3384       XtSetSensitive(nextViewPtButton, False)    3384       XtSetSensitive(nextViewPtButton, False);
3385       XtSetSensitive(prevViewPtButton, False)    3385       XtSetSensitive(prevViewPtButton, False);
3386    } else {                                      3386    } else {
3387       if (viewPtIdx >= (int) viewPtList.size(    3387       if (viewPtIdx >= (int) viewPtList.size())
3388          viewPtIdx--;                            3388          viewPtIdx--;
3389       writeViewPtIdx();                          3389       writeViewPtIdx();
3390       setViewPt();                               3390       setViewPt();
3391    }                                             3391    }
3392 }                                                3392 }
3393                                                  3393 
3394                                                  3394 
3395 // Renames currently selected viewpoint.         3395 // Renames currently selected viewpoint.
3396                                                  3396 
3397 void G4OpenInventorXtExaminerViewer::renameVi    3397 void G4OpenInventorXtExaminerViewer::renameViewPt(char *vpName)
3398 {                                                3398 {
3399    int idx = 0, end, pos;                        3399    int idx = 0, end, pos;
3400    int size = viewPtList.size();                 3400    int size = viewPtList.size();
3401    std::string line, newName;                    3401    std::string line, newName;
3402    fileIn.open(fileName.c_str());                3402    fileIn.open(fileName.c_str());
3403                                                  3403 
3404    newName = vpName;                             3404    newName = vpName;
3405    while ((int) newName.size() < MAX_VP_NAME)    3405    while ((int) newName.size() < MAX_VP_NAME)
3406       newName += " ";                            3406       newName += " ";
3407                                                  3407 
3408    getline(fileIn, line);                        3408    getline(fileIn, line);
3409    pos = fileIn.tellg();                         3409    pos = fileIn.tellg();
3410    while (getline(fileIn, line)) {               3410    while (getline(fileIn, line)) {
3411       end = line.find_last_not_of(' ');          3411       end = line.find_last_not_of(' ');
3412       line = line.substr(0, end + 1);            3412       line = line.substr(0, end + 1);
3413       if (!strcmp(line.c_str(), curViewPtName    3413       if (!strcmp(line.c_str(), curViewPtName)) {
3414          fileOut.seekp(pos);                     3414          fileOut.seekp(pos);
3415          fileOut << newName;                     3415          fileOut << newName;
3416          fileOut.seekp(0, std::ios::end); //     3416          fileOut.seekp(0, std::ios::end); // Set the file pointer to the end of the file
3417          break;                                  3417          break;
3418       }                                          3418       }
3419       while (line.size())                        3419       while (line.size())
3420          getline(fileIn, line);                  3420          getline(fileIn, line);
3421       pos = fileIn.tellg();                      3421       pos = fileIn.tellg();
3422    }                                             3422    }
3423                                                  3423 
3424    fileIn.close();                               3424    fileIn.close();
3425    fileIn.clear();                               3425    fileIn.clear();
3426                                                  3426 
3427    while (idx < size) {                          3427    while (idx < size) {
3428       if (!strcmp(viewPtList[idx].viewPtName,    3428       if (!strcmp(viewPtList[idx].viewPtName, curViewPtName)) {
3429          strcpy(viewPtList[idx].viewPtName, v    3429          strcpy(viewPtList[idx].viewPtName, vpName);
3430          break;                                  3430          break;
3431       }                                          3431       }
3432       idx++;                                     3432       idx++;
3433    }                                             3433    }
3434 }                                                3434 }
3435                                                  3435 
3436                                                  3436 
3437 // Rewrites entire viewpoint file with sorted    3437 // Rewrites entire viewpoint file with sorted viewpoints.
3438                                                  3438 
3439 void G4OpenInventorXtExaminerViewer::sortView    3439 void G4OpenInventorXtExaminerViewer::sortViewPts(std::vector<std::string> sortedViewPts) 
3440 {                                                3440 {
3441    SbVec3f axis;                                 3441    SbVec3f axis;
3442    float x, y, z, angle;                         3442    float x, y, z, angle;
3443    int sortIdx = 0, unsortIdx = 0;               3443    int sortIdx = 0, unsortIdx = 0;
3444                                                  3444 
3445    if (fileOut.is_open())                        3445    if (fileOut.is_open())
3446       fileOut.close();                           3446       fileOut.close();
3447                                                  3447 
3448    fileOut.open(fileName.c_str()); // Erase c    3448    fileOut.open(fileName.c_str()); // Erase current viewpoint file
3449                                                  3449 
3450    writeViewPtIdx();                             3450    writeViewPtIdx();
3451                                                  3451 
3452    int size = sortedViewPts.size();              3452    int size = sortedViewPts.size();
3453    while (sortIdx < size) {                      3453    while (sortIdx < size) {
3454       while (strcmp(sortedViewPts[sortIdx].c_    3454       while (strcmp(sortedViewPts[sortIdx].c_str(),
3455                     viewPtList[unsortIdx].vie    3455                     viewPtList[unsortIdx].viewPtName))
3456          unsortIdx++;                            3456          unsortIdx++;
3457                                                  3457 
3458       std::string vpName = viewPtList[unsortI    3458       std::string vpName = viewPtList[unsortIdx].viewPtName;
3459                                                  3459 
3460       while ((int) vpName.size() < MAX_VP_NAM    3460       while ((int) vpName.size() < MAX_VP_NAME)
3461          vpName += " ";                          3461          vpName += " ";
3462       fileOut << vpName << std::endl;            3462       fileOut << vpName << std::endl;
3463       viewPtList[unsortIdx].position.getValue    3463       viewPtList[unsortIdx].position.getValue(x, y, z);
3464       fileOut << x << " " << y << " " << z <<    3464       fileOut << x << " " << y << " " << z << std::endl;
3465                                                  3465 
3466       // Reusing x, y and z for storing the a    3466       // Reusing x, y and z for storing the axis
3467       viewPtList[unsortIdx].orientation.getVa    3467       viewPtList[unsortIdx].orientation.getValue(axis, angle);
3468       axis.getValue(x, y, z);                    3468       axis.getValue(x, y, z);
3469       fileOut << x << " " << y << " " << z <<    3469       fileOut << x << " " << y << " " << z << " " << angle << std::endl;
3470                                                  3470 
3471       fileOut << viewPtList[unsortIdx].camTyp    3471       fileOut << viewPtList[unsortIdx].camType << " "
3472               << viewPtList[unsortIdx].height    3472               << viewPtList[unsortIdx].height << std::endl;
3473       fileOut << viewPtList[unsortIdx].focalD    3473       fileOut << viewPtList[unsortIdx].focalDistance << " ";
3474                                                  3474 
3475       fileOut << viewPtList[unsortIdx].nearDi    3475       fileOut << viewPtList[unsortIdx].nearDistance << " ";
3476                                                  3476 
3477       fileOut << viewPtList[unsortIdx].farDis    3477       fileOut << viewPtList[unsortIdx].farDistance << std::endl;
3478                                                  3478 
3479       fileOut << viewPtList[unsortIdx].viewpo    3479       fileOut << viewPtList[unsortIdx].viewportMapping << " ";
3480       fileOut << viewPtList[unsortIdx].aspect    3480       fileOut << viewPtList[unsortIdx].aspectRatio << "\n" << std::endl;
3481       fileOut.flush();                           3481       fileOut.flush();
3482                                                  3482 
3483       unsortIdx = 0;                             3483       unsortIdx = 0;
3484       sortIdx++;                                 3484       sortIdx++;
3485    }                                             3485    }
3486 }                                                3486 }
3487                                                  3487 
3488                                                  3488 
3489 //  Loads view point data from a file into a     3489 //  Loads view point data from a file into a vector.
3490                                                  3490 
3491 bool G4OpenInventorXtExaminerViewer::loadView    3491 bool G4OpenInventorXtExaminerViewer::loadViewPts() 
3492 {                                                3492 {
3493    bool error = false;                           3493    bool error = false;
3494    viewPtData tmp;                               3494    viewPtData tmp;
3495    std::string token;                            3495    std::string token;
3496    SbVec3f axis;                                 3496    SbVec3f axis;
3497    SbRotation orient;                            3497    SbRotation orient;
3498    float x(0.), y(0.), z(0.), angle(0.);         3498    float x(0.), y(0.), z(0.), angle(0.);
3499                                                  3499 
3500    // Gets the last view point accessed, stor    3500    // Gets the last view point accessed, stored in the first line of the data file.
3501    fileIn >> token;                              3501    fileIn >> token;
3502    parseString<int>(viewPtIdx, token, error);    3502    parseString<int>(viewPtIdx, token, error);
3503    getline(fileIn, token); // Remove "\n"        3503    getline(fileIn, token); // Remove "\n"
3504    // Converts data from string type into nec    3504    // Converts data from string type into necessary types
3505    while (getline(fileIn, token)) {              3505    while (getline(fileIn, token)) {
3506                                                  3506 
3507       int end = token.find_last_not_of(' ');     3507       int end = token.find_last_not_of(' '); // Remove padded spaces
3508       token = token.substr(0, end + 1);          3508       token = token.substr(0, end + 1);
3509                                                  3509 
3510       char *vpName = new char[token.size() +     3510       char *vpName = new char[token.size() + 1];
3511       strcpy(vpName, token.c_str());             3511       strcpy(vpName, token.c_str());
3512       tmp.viewPtName = vpName;                   3512       tmp.viewPtName = vpName;
3513       fileIn >> token;                           3513       fileIn >> token;
3514                                                  3514 
3515       parseString<float>(x, token, error);       3515       parseString<float>(x, token, error);
3516       fileIn >> token;                           3516       fileIn >> token;
3517       parseString<float>(y, token, error);       3517       parseString<float>(y, token, error);
3518       fileIn >> token;                           3518       fileIn >> token;
3519       parseString<float>(z, token, error);       3519       parseString<float>(z, token, error);
3520       fileIn >> token;                           3520       fileIn >> token;
3521       tmp.position = axis.setValue(x, y, z);     3521       tmp.position = axis.setValue(x, y, z);
3522                                                  3522 
3523       parseString<float>(x, token, error);       3523       parseString<float>(x, token, error);
3524       fileIn >> token;                           3524       fileIn >> token;
3525       parseString<float>(y, token, error);       3525       parseString<float>(y, token, error);
3526       fileIn >> token;                           3526       fileIn >> token;
3527       parseString<float>(z, token, error);       3527       parseString<float>(z, token, error);
3528       fileIn >> token;                           3528       fileIn >> token;
3529       parseString<float>(angle, token, error)    3529       parseString<float>(angle, token, error);
3530       fileIn >> token;                           3530       fileIn >> token;
3531       orient.setValue(axis.setValue(x, y, z),    3531       orient.setValue(axis.setValue(x, y, z), angle);
3532       tmp.orientation = orient.getValue();       3532       tmp.orientation = orient.getValue();
3533                                                  3533 
3534       int camType(0);                            3534       int camType(0);
3535       parseString<int>(camType, token, error)    3535       parseString<int>(camType, token, error);
3536       fileIn >> token;                           3536       fileIn >> token;
3537       tmp.camType = (CameraType) camType;        3537       tmp.camType = (CameraType) camType;
3538                                                  3538 
3539       parseString<float>(tmp.height, token, e    3539       parseString<float>(tmp.height, token, error);
3540       fileIn >> token;                           3540       fileIn >> token;
3541       parseString<float>(tmp.focalDistance, t    3541       parseString<float>(tmp.focalDistance, token, error);
3542       fileIn >> token;                           3542       fileIn >> token;
3543       parseString<float>(tmp.nearDistance, to    3543       parseString<float>(tmp.nearDistance, token, error);
3544       fileIn >> token;                           3544       fileIn >> token;
3545       parseString<float>(tmp.farDistance, tok    3545       parseString<float>(tmp.farDistance, token, error);
3546       fileIn >> token;                           3546       fileIn >> token;
3547       parseString<int>(tmp.viewportMapping, t    3547       parseString<int>(tmp.viewportMapping, token, error);
3548       fileIn >> token;                           3548       fileIn >> token;
3549       parseString<float>(tmp.aspectRatio, tok    3549       parseString<float>(tmp.aspectRatio, token, error);
3550                                                  3550 
3551       getline(fileIn, token); // To remove "\    3551       getline(fileIn, token); // To remove "\n" characters
3552       getline(fileIn, token);                    3552       getline(fileIn, token);
3553                                                  3553 
3554       if (error) {                               3554       if (error) {
3555          viewPtIdx = 0;                          3555          viewPtIdx = 0;
3556          viewPtList.clear();                     3556          viewPtList.clear();
3557          return false;                           3557          return false;
3558       }                                          3558       }
3559       viewPtList.push_back(tmp);                 3559       viewPtList.push_back(tmp);
3560    }                                             3560    }
3561                                                  3561 
3562    return true;                                  3562    return true;
3563 }                                                3563 }
3564                                                  3564 
3565                                                  3565 
3566 // Converts a string type word into a float t    3566 // Converts a string type word into a float type.
3567                                                  3567 
3568 template<class T>                                3568 template<class T> 
3569 void G4OpenInventorXtExaminerViewer::parseStr    3569 void G4OpenInventorXtExaminerViewer::parseString(T &t, const std::string &s,
3570                                                  3570                                                  bool &error) 
3571 {                                                3571 {
3572    std::istringstream str(s);                    3572    std::istringstream str(s);
3573    if ((str >> t).fail())                        3573    if ((str >> t).fail())
3574       error = true;                              3574       error = true;
3575 }                                                3575 }
3576                                                  3576 
3577                                                  3577 
3578 // Generic fileSelectionDialog creation.         3578 // Generic fileSelectionDialog creation.
3579                                                  3579 
3580 void G4OpenInventorXtExaminerViewer::popUpFil    3580 void G4OpenInventorXtExaminerViewer::popUpFileSelDialog(Widget &dialog,
3581                                                  3581                                                 std::string dialogName,
3582                                                  3582                                                 std::string buttonLabel,
3583                                                  3583                                                 XtCallbackProc cbOK)
3584 {                                                3584 {
3585    int n;                                        3585    int n;
3586    Arg args[3];                                  3586    Arg args[3];
3587    Widget parent, scrollWidget;                  3587    Widget parent, scrollWidget;
3588    parent = SoXt::getShellWidget(getParentWid    3588    parent = SoXt::getShellWidget(getParentWidget());
3589                                                  3589 
3590    if (dialog == NULL) {                         3590    if (dialog == NULL) {
3591                                                  3591 
3592       // Change the 'OK' button to whatever b    3592       // Change the 'OK' button to whatever buttonLabel contains
3593       XmString str = XmStringCreateLocalized(    3593       XmString str = XmStringCreateLocalized((char *) buttonLabel.c_str());
3594                                                  3594 
3595       n = 0;                                     3595       n = 0;
3596       XtSetArg(args[n], XmNokLabelString, str    3596       XtSetArg(args[n], XmNokLabelString, str);   n++;
3597       XtSetArg(args[n], XmNresizePolicy, XmRE    3597       XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE);    n++;
3598                                                  3598 
3599       dialog = XmCreateFileSelectionDialog(pa    3599       dialog = XmCreateFileSelectionDialog(parent,
3600                                            (c    3600                                            (char *) dialogName.c_str(), args, n);
3601                                                  3601 
3602       XtAddCallback(dialog, XmNokCallback, cb    3602       XtAddCallback(dialog, XmNokCallback, cbOK, this);
3603       XtAddCallback(dialog, XmNcancelCallback    3603       XtAddCallback(dialog, XmNcancelCallback, cancelFileSelDialogCB, this);
3604                                                  3604 
3605       // Adding scrolling functionality to th    3605       // Adding scrolling functionality to the widget
3606       scrollWidget = XmFileSelectionBoxGetChi    3606       scrollWidget = XmFileSelectionBoxGetChild(dialog, XmDIALOG_DIR_LIST);
3607       if (scrollWidget)                          3607       if (scrollWidget)
3608          xmAddMouseEventHandler(scrollWidget)    3608          xmAddMouseEventHandler(scrollWidget);
3609       scrollWidget = XmFileSelectionBoxGetChi    3609       scrollWidget = XmFileSelectionBoxGetChild(dialog, XmDIALOG_LIST);
3610       if (scrollWidget)                          3610       if (scrollWidget)
3611          xmAddMouseEventHandler(scrollWidget)    3611          xmAddMouseEventHandler(scrollWidget);
3612                                                  3612 
3613       XtUnmanageChild(XmSelectionBoxGetChild(    3613       XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
3614       XmStringFree(str);                         3614       XmStringFree(str);
3615    }                                             3615    }
3616    XtManageChild(dialog);                        3616    XtManageChild(dialog);
3617 }                                                3617 }
3618                                                  3618 
3619                                                  3619 
3620 // Generic fileSelectionDialog cancelation.      3620 // Generic fileSelectionDialog cancelation.
3621                                                  3621 
3622 void G4OpenInventorXtExaminerViewer::cancelFi    3622 void G4OpenInventorXtExaminerViewer::cancelFileSelDialogCB(Widget w,
3623                                                  3623                                                            XtPointer,
3624                                                  3624                                                            XtPointer)
3625 {                                                3625 {
3626    XtUnmanageChild(w);                           3626    XtUnmanageChild(w);
3627 }                                                3627 }
3628                                                  3628 
3629                                                  3629 
3630 // Displays a file selection dialog that allo    3630 // Displays a file selection dialog that allows to open a new viewpoint file.
3631                                                  3631 
3632 void G4OpenInventorXtExaminerViewer::openView    3632 void G4OpenInventorXtExaminerViewer::openViewPtFileCB(Widget,
3633                                        XtPoin    3633                                        XtPointer client_data,
3634                                        XtPoin    3634                                        XtPointer)
3635 {                                                3635 {
3636    G4OpenInventorXtExaminerViewer * This =       3636    G4OpenInventorXtExaminerViewer * This =
3637       (G4OpenInventorXtExaminerViewer *) clie    3637       (G4OpenInventorXtExaminerViewer *) client_data;
3638    This->popUpFileSelDialog(This->openFileDia    3638    This->popUpFileSelDialog(This->openFileDialog, "Open File", "Load",
3639                             viewPtFileSelecte    3639                             viewPtFileSelectedCB);
3640 }                                                3640 }
3641                                                  3641 
3642                                                  3642 
3643 void G4OpenInventorXtExaminerViewer::viewPtFi    3643 void G4OpenInventorXtExaminerViewer::viewPtFileSelectedCB(Widget w, 
3644                                                  3644                                              XtPointer client_data,
3645                                                  3645                                              XtPointer call_data)
3646 {                                                3646 {
3647    char *file = NULL;                            3647    char *file = NULL;
3648    G4OpenInventorXtExaminerViewer * This = (G    3648    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
3649    XmFileSelectionBoxCallbackStruct *cbs =       3649    XmFileSelectionBoxCallbackStruct *cbs =
3650       (XmFileSelectionBoxCallbackStruct *) ca    3650       (XmFileSelectionBoxCallbackStruct *) call_data;
3651                                                  3651 
3652    // Get the file                               3652    // Get the file
3653    if (cbs) {                                    3653    if (cbs) {
3654       if (!(file = (char *) XmStringUnparse(c    3654       if (!(file = (char *) XmStringUnparse(cbs->value,
3655                                             X    3655                                             XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0,
3656                                             X    3656                                             XmOUTPUT_ALL))) {
3657          SoDebugError::post("G4OpenInventorXt    3657          SoDebugError::post("G4OpenInventorXtExaminerViewer::fileSelectedCB",
3658                             "Internal error d    3658                             "Internal error during file opening");
3659          return;                                 3659          return;
3660       }                                          3660       }
3661                                                  3661 
3662       This->fileIn.open(file);                   3662       This->fileIn.open(file);
3663       if (!This->fileIn.fail()) {                3663       if (!This->fileIn.fail()) {
3664          // Opens a file without erasing it      3664          // Opens a file without erasing it
3665          This->cleanUpAfterPrevFile();           3665          This->cleanUpAfterPrevFile();
3666          if (!This->loadViewPts()) {             3666          if (!This->loadViewPts()) {
3667             String dialogName = (char *) "Err    3667             String dialogName = (char *) "Error Loading File";
3668             std::string msg = "Wrong or corru    3668             std::string msg = "Wrong or corrupted input file.";
3669             This->warningMsgDialog(msg, dialo    3669             This->warningMsgDialog(msg, dialogName, NULL);
3670          } else {                                3670          } else {
3671             This->fileName = file;               3671             This->fileName = file;
3672             This->fileOut.open(This->fileName    3672             This->fileOut.open(This->fileName.c_str(), std::ios::in);
3673             This->fileOut.seekp(0, std::ios::    3673             This->fileOut.seekp(0, std::ios::end);
3674                                                  3674 
3675             if (!This->listsDialog)              3675             if (!This->listsDialog)
3676                constructListsDialog(w, This,     3676                constructListsDialog(w, This, NULL); // Pop up listsDialog
3677             else                                 3677             else
3678                This->addViewPoints();            3678                This->addViewPoints();
3679                                                  3679 
3680             std::string newDialogName = This-    3680             std::string newDialogName = This->fileName.substr(
3681                                                  3681                                                               This->fileName.rfind('/') + 1);
3682             XtVaSetValues(This->myShellDialog    3682             XtVaSetValues(This->myShellDialog, XmNtitle,
3683                           (char *) newDialogN    3683                           (char *) newDialogName.c_str(), NULL);
3684                                                  3684 
3685             if (This->viewPtList.size()) {       3685             if (This->viewPtList.size()) {
3686                This->setViewPt();                3686                This->setViewPt();
3687                XmTextSetString(This->viewPtSe    3687                XmTextSetString(This->viewPtSelection, NULL);
3688                XtSetSensitive(This->nextViewP    3688                XtSetSensitive(This->nextViewPtButton, True);
3689                XtSetSensitive(This->prevViewP    3689                XtSetSensitive(This->prevViewPtButton, True);
3690             } else {                             3690             } else {
3691                XtSetSensitive(This->nextViewP    3691                XtSetSensitive(This->nextViewPtButton, False);
3692                XtSetSensitive(This->prevViewP    3692                XtSetSensitive(This->prevViewPtButton, False);
3693             }                                    3693             }
3694                                                  3694 
3695             XtUnmanageChild(w);                  3695             XtUnmanageChild(w);
3696          }                                       3696          }
3697                                                  3697 
3698          This->fileIn.close();                   3698          This->fileIn.close();
3699       } else {                                   3699       } else {
3700          String dialogName = (char *) "Nonexi    3700          String dialogName = (char *) "Nonexistent File";
3701          std::string msg = "Unable to open fi    3701          std::string msg = "Unable to open file.";
3702          This->warningMsgDialog(msg, dialogNa    3702          This->warningMsgDialog(msg, dialogName, NULL);
3703       }                                          3703       }
3704    }                                             3704    }
3705                                                  3705 
3706    This->fileIn.clear();                         3706    This->fileIn.clear();
3707    XtFree(file);                                 3707    XtFree(file);
3708 }                                                3708 }
3709                                                  3709 
3710                                                  3710 
3711 // Adds bookmarks to listsDialog.                3711 // Adds bookmarks to listsDialog.
3712                                                  3712 
3713 void G4OpenInventorXtExaminerViewer::addViewP    3713 void G4OpenInventorXtExaminerViewer::addViewPoints()
3714 {                                                3714 {
3715    int size = viewPtList.size();                 3715    int size = viewPtList.size();
3716    if (!size)                                    3716    if (!size)
3717       return;                                    3717       return;
3718                                                  3718 
3719    XmString *viewPts;                            3719    XmString *viewPts;
3720                                                  3720 
3721    viewPts = (XmString *) XtMalloc(size * siz    3721    viewPts = (XmString *) XtMalloc(size * sizeof(XmString));
3722    for (int i = 0; i < size; i++)                3722    for (int i = 0; i < size; i++)
3723       viewPts[i] = XmStringCreateLocalized(vi    3723       viewPts[i] = XmStringCreateLocalized(viewPtList[i].viewPtName);
3724                                                  3724 
3725    XmListAddItemsUnselected(myViewPtList, vie    3725    XmListAddItemsUnselected(myViewPtList, viewPts, size, 1);
3726                                                  3726 
3727    if (viewPts != NULL) {                        3727    if (viewPts != NULL) {
3728       for (int i = 0; i < size; i++)             3728       for (int i = 0; i < size; i++)
3729          XmStringFree(viewPts[i]);               3729          XmStringFree(viewPts[i]);
3730       XtFree((char *) viewPts);                  3730       XtFree((char *) viewPts);
3731    }                                             3731    }
3732 }                                                3732 }
3733                                                  3733 
3734                                                  3734 
3735 // Called before loading a new viewpoint file    3735 // Called before loading a new viewpoint file. 
3736 // Resets member fields to default values.       3736 // Resets member fields to default values.
3737                                                  3737 
3738 void G4OpenInventorXtExaminerViewer::cleanUpA    3738 void G4OpenInventorXtExaminerViewer::cleanUpAfterPrevFile()
3739 {                                                3739 {
3740    viewPtIdx = -1;                               3740    viewPtIdx = -1;
3741    viewPtList.clear();                           3741    viewPtList.clear();
3742    setSuperimpositionEnabled(superimposition,    3742    setSuperimpositionEnabled(superimposition, FALSE);
3743    scheduleRedraw();                             3743    scheduleRedraw();
3744    currentState = GENERAL;                       3744    currentState = GENERAL;
3745    if (fileOut.is_open())                        3745    if (fileOut.is_open())
3746       fileOut.close();                           3746       fileOut.close();
3747    if (listsDialog) // Clear viewpoints          3747    if (listsDialog) // Clear viewpoints
3748       XmListDeleteAllItems(myViewPtList);        3748       XmListDeleteAllItems(myViewPtList);
3749 }                                                3749 }
3750                                                  3750 
3751                                                  3751 
3752 // Generic function for displaying a warning     3752 // Generic function for displaying a warning dialog.
3753                                                  3753 
3754 void G4OpenInventorXtExaminerViewer::warningM    3754 void G4OpenInventorXtExaminerViewer::warningMsgDialog(std::string msg,
3755                                                  3755                                                       String dialogName,
3756                                                  3756                                                       XtCallbackProc cb)
3757 {                                                3757 {
3758    Arg args[5];                                  3758    Arg args[5];
3759    unsigned int n;                               3759    unsigned int n;
3760    XmString warningMsg;                          3760    XmString warningMsg;
3761                                                  3761 
3762    warningMsg = XmStringCreateLocalized((char    3762    warningMsg = XmStringCreateLocalized((char *)msg.c_str());
3763                                                  3763 
3764    n = 0;                                        3764    n = 0;
3765    XtSetArg(args[n], XmNmessageString, warnin    3765    XtSetArg(args[n], XmNmessageString, warningMsg); n++;
3766    Widget warningDialog = XmCreateWarningDial    3766    Widget warningDialog = XmCreateWarningDialog(getParentWidget(), dialogName, args, n);
3767    if (cb)                                       3767    if (cb)
3768       XtAddCallback(warningDialog, XmNokCallb    3768       XtAddCallback(warningDialog, XmNokCallback, cb, this);
3769                                                  3769 
3770    XmStringFree(warningMsg);                     3770    XmStringFree(warningMsg);
3771                                                  3771 
3772    XtVaSetValues (warningDialog, XmNdialogSty    3772    XtVaSetValues (warningDialog, XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, NULL);
3773    XtUnmanageChild(XtNameToWidget(warningDial    3773    XtUnmanageChild(XtNameToWidget(warningDialog, "Help"));
3774    XtUnmanageChild(XtNameToWidget(warningDial    3774    XtUnmanageChild(XtNameToWidget(warningDialog, "Cancel"));
3775                                                  3775 
3776    XtManageChild(warningDialog);                 3776    XtManageChild(warningDialog);
3777 }                                                3777 }
3778                                                  3778 
3779                                                  3779 
3780 void G4OpenInventorXtExaminerViewer::newViewP    3780 void G4OpenInventorXtExaminerViewer::newViewPtFileCB(Widget,
3781                                                  3781                                                      XtPointer client_data,
3782                                                  3782                                                      XtPointer)
3783 {                                                3783 {
3784    G4OpenInventorXtExaminerViewer * This =       3784    G4OpenInventorXtExaminerViewer * This = 
3785       (G4OpenInventorXtExaminerViewer *) clie    3785       (G4OpenInventorXtExaminerViewer *) client_data;
3786    This->popUpFileSelDialog(This->newFileDial    3786    This->popUpFileSelDialog(This->newFileDialog, "New File", "Save",
3787                             createNewVPFileCB    3787                             createNewVPFileCB);
3788 }                                                3788 }
3789                                                  3789 
3790                                                  3790 
3791 void G4OpenInventorXtExaminerViewer::createNe    3791 void G4OpenInventorXtExaminerViewer::createNewVPFileCB(Widget w, 
3792                                                  3792                                                        XtPointer client_data,
3793                                                  3793                                                        XtPointer call_data)
3794 {                                                3794 {
3795    char *file;                                   3795    char *file;
3796    std::string fName;                            3796    std::string fName;
3797    G4OpenInventorXtExaminerViewer * This = (G    3797    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
3798    XmFileSelectionBoxCallbackStruct *cbs =       3798    XmFileSelectionBoxCallbackStruct *cbs =
3799       (XmFileSelectionBoxCallbackStruct *) ca    3799       (XmFileSelectionBoxCallbackStruct *) call_data;
3800                                                  3800 
3801    // Get the file                               3801    // Get the file
3802    if (cbs) {                                    3802    if (cbs) {
3803       if (!(file = (char *) XmStringUnparse(c    3803       if (!(file = (char *) XmStringUnparse(cbs->value,
3804                                             X    3804                                             XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0,
3805                                             X    3805                                             XmOUTPUT_ALL))) {
3806          SoDebugError::post("G4OpenInventorXt    3806          SoDebugError::post("G4OpenInventorXtExaminerViewer::createNewVPFileCB",
3807                             "Internal error d    3807                             "Internal error during file opening");
3808          return;                                 3808          return;
3809       }                                          3809       }
3810                                                  3810 
3811       This->fileName = file;                     3811       This->fileName = file;
3812       fName = This->fileName.substr(This->fil    3812       fName = This->fileName.substr(This->fileName.rfind('/') + 1); // Extracts just the name of the file
3813       This->fileIn.open(file);                   3813       This->fileIn.open(file);
3814       if (This->fileIn.fail()) { // Filename     3814       if (This->fileIn.fail()) { // Filename does not exist
3815          This->cleanUpAfterPrevFile();           3815          This->cleanUpAfterPrevFile();
3816          This->fileOut.open(file); // Creates    3816          This->fileOut.open(file); // Creates a new empty file
3817          XtSetSensitive(This->nextViewPtButto    3817          XtSetSensitive(This->nextViewPtButton, False);
3818          XtSetSensitive(This->prevViewPtButto    3818          XtSetSensitive(This->prevViewPtButton, False);
3819          if (This->listsDialog)                  3819          if (This->listsDialog)
3820             closeListsDialogCB(w, This, NULL)    3820             closeListsDialogCB(w, This, NULL);
3821          constructListsDialog(w, This, NULL);    3821          constructListsDialog(w, This, NULL);
3822          XtUnmanageChild(w);                     3822          XtUnmanageChild(w);
3823          if (This->returnToSaveVP) {             3823          if (This->returnToSaveVP) {
3824             This->returnToSaveVP = false;        3824             This->returnToSaveVP = false;
3825             saveViewPtCB(NULL, This, NULL);      3825             saveViewPtCB(NULL, This, NULL);
3826          }                                       3826          }
3827       } else { // Filename already exists        3827       } else { // Filename already exists
3828          String dialogName = (char *) "Existi    3828          String dialogName = (char *) "Existing File";
3829          std::string msg = "'" + fName + "' a    3829          std::string msg = "'" + fName + "' already exists. Do you want to overwrite it?";
3830          This->warningMsgDialog(msg, dialogNa    3830          This->warningMsgDialog(msg, dialogName, overwriteFileCB);
3831          This->fileIn.close();                   3831          This->fileIn.close();
3832       }                                          3832       }
3833       This->fileIn.clear();                      3833       This->fileIn.clear();
3834       XtFree(file);                              3834       XtFree(file);
3835    }                                             3835    }
3836 }                                                3836 }
3837                                                  3837 
3838                                                  3838 
3839 void G4OpenInventorXtExaminerViewer::overwrit    3839 void G4OpenInventorXtExaminerViewer::overwriteFileCB(Widget, 
3840                                                  3840                                                      XtPointer client_data,
3841                                                  3841                                                      XtPointer)
3842 {                                                3842 {
3843    G4OpenInventorXtExaminerViewer * This = (G    3843    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
3844    This->cleanUpAfterPrevFile();                 3844    This->cleanUpAfterPrevFile();
3845    XtSetSensitive(This->nextViewPtButton, Fal    3845    XtSetSensitive(This->nextViewPtButton, False);
3846    XtSetSensitive(This->prevViewPtButton, Fal    3846    XtSetSensitive(This->prevViewPtButton, False);
3847                                                  3847 
3848    XtUnmanageChild(This->newFileDialog);         3848    XtUnmanageChild(This->newFileDialog);
3849                                                  3849 
3850    This->fileOut.open(This->fileName.c_str())    3850    This->fileOut.open(This->fileName.c_str());
3851                                                  3851 
3852    if (This->returnToSaveVP) {                   3852    if (This->returnToSaveVP) {
3853       This->returnToSaveVP = false;              3853       This->returnToSaveVP = false;
3854       saveViewPtCB(NULL, This, NULL);            3854       saveViewPtCB(NULL, This, NULL);
3855    }                                             3855    }
3856 }                                                3856 }
3857                                                  3857 
3858                                                  3858 
3859 void G4OpenInventorXtExaminerViewer::loadRefC    3859 void G4OpenInventorXtExaminerViewer::loadRefCoordsDialogCB(Widget,
3860                                             X    3860                                             XtPointer client_data,
3861                                             X    3861                                             XtPointer)
3862 {                                                3862 {
3863    G4OpenInventorXtExaminerViewer * This =       3863    G4OpenInventorXtExaminerViewer * This = 
3864       (G4OpenInventorXtExaminerViewer *)clien    3864       (G4OpenInventorXtExaminerViewer *)client_data;
3865    This->popUpFileSelDialog(This->loadRefCoor    3865    This->popUpFileSelDialog(This->loadRefCoordsDialog, "Load Ref Coords",
3866                             "Load", loadRefCo    3866                             "Load", loadRefCoordsCB);
3867 }                                                3867 }
3868                                                  3868 
3869                                                  3869 
3870 void G4OpenInventorXtExaminerViewer::loadRefC    3870 void G4OpenInventorXtExaminerViewer::loadRefCoordsCB(Widget w, 
3871                                                  3871                                                      XtPointer client_data,
3872                                                  3872                                                      XtPointer call_data)
3873 {                                                3873 {
3874    char *file = NULL;                            3874    char *file = NULL;
3875    G4OpenInventorXtExaminerViewer * This = (G    3875    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *)client_data;
3876    XmFileSelectionBoxCallbackStruct *cbs = (X    3876    XmFileSelectionBoxCallbackStruct *cbs = (XmFileSelectionBoxCallbackStruct *)call_data;
3877                                                  3877 
3878    // Get the file                               3878    // Get the file
3879    if(cbs) {                                     3879    if(cbs) {
3880                                                  3880 
3881       file = (char *)XmStringUnparse(cbs->val    3881       file = (char *)XmStringUnparse(cbs->value, XmFONTLIST_DEFAULT_TAG,
3882                                      XmCHARSE    3882                                      XmCHARSET_TEXT, XmCHARSET_TEXT,
3883                                      NULL, 0,    3883                                      NULL, 0, XmOUTPUT_ALL);
3884                                                  3884 
3885       std::ifstream ifs(file);                   3885       std::ifstream ifs(file);
3886       if(ifs.is_open()){                         3886       if(ifs.is_open()){
3887          This->refParticleTrajectory.clear();    3887          This->refParticleTrajectory.clear();
3888          float x,y,z;                            3888          float x,y,z;
3889          while(ifs >> x >> y >> z){              3889          while(ifs >> x >> y >> z){
3890             This->refParticleTrajectory.push_    3890             This->refParticleTrajectory.push_back(SbVec3f(x,y,z));
3891          }                                       3891          }
3892          ifs.close();                            3892          ifs.close();
3893          XtUnmanageChild(w);                     3893          XtUnmanageChild(w);
3894       }                                          3894       }
3895       else{                                      3895       else{
3896          String dialogName = (char *) "Proble    3896          String dialogName = (char *) "Problem reading file";
3897          std::string msg = "Problem reading f    3897          std::string msg = "Problem reading file";
3898          This->warningMsgDialog(msg, dialogNa    3898          This->warningMsgDialog(msg, dialogName, NULL);
3899          return;                                 3899          return;
3900                                                  3900 
3901       }                                          3901       }
3902    }                                             3902    }
3903                                                  3903 
3904    return;                                       3904    return;
3905 }                                                3905 }
3906                                                  3906 
3907                                                  3907 
3908 void G4OpenInventorXtExaminerViewer::saveRefC    3908 void G4OpenInventorXtExaminerViewer::saveRefCoordsDialogCB(Widget,
3909                                             X    3909                                             XtPointer client_data,
3910                                             X    3910                                             XtPointer)
3911 {                                                3911 {
3912    G4OpenInventorXtExaminerViewer * This = (G    3912    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
3913                                                  3913 
3914    if (!This->refParticleTrajectory.size()) {    3914    if (!This->refParticleTrajectory.size()) {
3915       String dialogName = (char *) "No Refere    3915       String dialogName = (char *) "No Reference Trajectory";
3916       std::string msg = "You need to start a     3916       std::string msg = "You need to start a run or load a reference trajectory from a file";
3917       This->warningMsgDialog(msg, dialogName,    3917       This->warningMsgDialog(msg, dialogName, NULL);
3918       return;                                    3918       return;
3919    }                                             3919    }
3920                                                  3920 
3921    int n;                                        3921    int n;
3922    Arg args[3];                                  3922    Arg args[3];
3923    Widget parent, scrollWidget;                  3923    Widget parent, scrollWidget;
3924    parent = SoXt::getShellWidget(This->getPar    3924    parent = SoXt::getShellWidget(This->getParentWidget());
3925                                                  3925 
3926    if (This->saveRefCoordsDialog == NULL) {      3926    if (This->saveRefCoordsDialog == NULL) {
3927                                                  3927 
3928       // Change the 'OK' button to whatever b    3928       // Change the 'OK' button to whatever buttonLabel contains
3929       XmString str = XmStringCreateLocalized(    3929       XmString str = XmStringCreateLocalized((char *)"Save");
3930                                                  3930 
3931       n = 0;                                     3931       n = 0;
3932       XtSetArg(args[n], XmNokLabelString, str    3932       XtSetArg(args[n], XmNokLabelString, str);   n++;
3933       XtSetArg(args[n], XmNresizePolicy, XmRE    3933       XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE);    n++;
3934                                                  3934 
3935       This->saveRefCoordsDialog = XmCreateFil    3935       This->saveRefCoordsDialog = XmCreateFileSelectionDialog(parent,(char *)"Save Ref Coords", args, n);
3936                                                  3936 
3937       XtAddCallback(This->saveRefCoordsDialog    3937       XtAddCallback(This->saveRefCoordsDialog, XmNokCallback, saveRefCoordsCB, This);
3938       XtAddCallback(This->saveRefCoordsDialog    3938       XtAddCallback(This->saveRefCoordsDialog, XmNcancelCallback, cancelFileSelDialogCB, This);
3939                                                  3939 
3940       // Adding scrolling functionality to th    3940       // Adding scrolling functionality to the widget
3941       scrollWidget = XmFileSelectionBoxGetChi    3941       scrollWidget = XmFileSelectionBoxGetChild(This->saveRefCoordsDialog, XmDIALOG_DIR_LIST);
3942       if (scrollWidget)                          3942       if (scrollWidget)
3943          xmAddMouseEventHandler(scrollWidget)    3943          xmAddMouseEventHandler(scrollWidget);
3944       scrollWidget = XmFileSelectionBoxGetChi    3944       scrollWidget = XmFileSelectionBoxGetChild(This->saveRefCoordsDialog, XmDIALOG_LIST);
3945       if (scrollWidget)                          3945       if (scrollWidget)
3946          xmAddMouseEventHandler(scrollWidget)    3946          xmAddMouseEventHandler(scrollWidget);
3947                                                  3947 
3948       XtUnmanageChild(XmSelectionBoxGetChild(    3948       XtUnmanageChild(XmSelectionBoxGetChild(This->saveRefCoordsDialog, XmDIALOG_HELP_BUTTON));
3949       XmStringFree(str);                         3949       XmStringFree(str);
3950    }                                             3950    }
3951                                                  3951 
3952    //TODO: Auto name?                            3952    //TODO: Auto name?
3953                                                  3953 
3954    XtManageChild(This->saveRefCoordsDialog);     3954    XtManageChild(This->saveRefCoordsDialog);
3955                                                  3955 
3956 }                                                3956 }
3957                                                  3957 
3958                                                  3958 
3959 void G4OpenInventorXtExaminerViewer::saveRefC    3959 void G4OpenInventorXtExaminerViewer::saveRefCoordsCB(Widget w, 
3960                                                  3960                                                      XtPointer client_data,
3961                                                  3961                                                      XtPointer call_data)
3962 {                                                3962 {
3963    char *file;                                   3963    char *file;
3964    G4OpenInventorXtExaminerViewer * This = (G    3964    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
3965    XmFileSelectionBoxCallbackStruct *cbs =       3965    XmFileSelectionBoxCallbackStruct *cbs =
3966       (XmFileSelectionBoxCallbackStruct *) ca    3966       (XmFileSelectionBoxCallbackStruct *) call_data;
3967                                                  3967 
3968    // Get the file                               3968    // Get the file
3969    if (cbs) {                                    3969    if (cbs) {
3970                                                  3970 
3971       file = (char *)XmStringUnparse(cbs->val    3971       file = (char *)XmStringUnparse(cbs->value, XmFONTLIST_DEFAULT_TAG,
3972                                      XmCHARSE    3972                                      XmCHARSET_TEXT, XmCHARSET_TEXT,
3973                                      NULL, 0,    3973                                      NULL, 0, XmOUTPUT_ALL);
3974                                                  3974 
3975       std::ifstream ifile(file);                 3975       std::ifstream ifile(file);
3976       if (ifile) {                               3976       if (ifile) {
3977          //File already exists                   3977          //File already exists
3978                                                  3978 
3979          Arg args[4];                            3979          Arg args[4];
3980          Widget parent = This->getParentWidge    3980          Widget parent = This->getParentWidget(); //gets the dialogshell of the ExaminerViewer widget
3981          Widget confirmOverwriteDialog;          3981          Widget confirmOverwriteDialog;
3982          XmString msg;                           3982          XmString msg;
3983                                                  3983 
3984          confirmOverwriteDialog = XmCreateQue    3984          confirmOverwriteDialog = XmCreateQuestionDialog (parent, (char *)"Confirm overwrite", args, 0);
3985          msg = XmStringCreateLocalized ((char    3985          msg = XmStringCreateLocalized ((char *)"File exists. Overwrite?");
3986          XtVaSetValues (confirmOverwriteDialo    3986          XtVaSetValues (confirmOverwriteDialog, XmNmessageString, msg, NULL);
3987                                                  3987 
3988          // If users presses OK, we want to r    3988          // If users presses OK, we want to return to this function and
3989          // save the file.  For that to work,    3989          // save the file.  For that to work, pass it the current widget
3990          // to be able to grab the filename.     3990          // to be able to grab the filename.
3991          XtVaSetValues (confirmOverwriteDialo    3991          XtVaSetValues (confirmOverwriteDialog, XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, NULL);
3992          XtAddCallback (confirmOverwriteDialo    3992          XtAddCallback (confirmOverwriteDialog, XmNokCallback, saveRefCoordsOverWriteCB, client_data);
3993          XtAddCallback (confirmOverwriteDialo    3993          XtAddCallback (confirmOverwriteDialog, XmNcancelCallback, saveRefCoordsOverWriteCB, client_data);
3994                                                  3994 
3995          XmStringFree (msg);                     3995          XmStringFree (msg);
3996                                                  3996 
3997          //The confirmOverwriteDialog will ne    3997          //The confirmOverwriteDialog will need this
3998          This->saveRefCoordsFileName = file;     3998          This->saveRefCoordsFileName = file;
3999          This->saveRefCoordsWidget = w;          3999          This->saveRefCoordsWidget = w;
4000                                                  4000 
4001          XtUnmanageChild(XtNameToWidget(confi    4001          XtUnmanageChild(XtNameToWidget(confirmOverwriteDialog, "Help"));
4002          XtManageChild(confirmOverwriteDialog    4002          XtManageChild(confirmOverwriteDialog);
4003                                                  4003 
4004          return;                                 4004          return;
4005       }                                          4005       }
4006       else{                                      4006       else{
4007                                                  4007 
4008          std::ofstream ofs(file);                4008          std::ofstream ofs(file);
4009          if(ofs.is_open()){                      4009          if(ofs.is_open()){
4010             float x,y,z;                         4010             float x,y,z;
4011             for(unsigned int i=0; i < This->r    4011             for(unsigned int i=0; i < This->refParticleTrajectory.size(); ++i){
4012                This->refParticleTrajectory[i]    4012                This->refParticleTrajectory[i].getValue(x,y,z);
4013                ofs << x << " " << y << " " <<    4013                ofs << x << " " << y << " " << z << "\n";
4014             }                                    4014             }
4015             ofs.close();                         4015             ofs.close();
4016             XtUnmanageChild(w);                  4016             XtUnmanageChild(w);
4017          }                                       4017          }
4018          else{                                   4018          else{
4019             String dialogName = (char *) "Err    4019             String dialogName = (char *) "Error opening file";
4020             std::string msg = "There was a pr    4020             std::string msg = "There was a problem trying to open the file '";
4021             msg += This->saveRefCoordsFileNam    4021             msg += This->saveRefCoordsFileName;
4022             msg += "'";                          4022             msg += "'";
4023                                                  4023 
4024             This->warningMsgDialog(msg, dialo    4024             This->warningMsgDialog(msg, dialogName, NULL);
4025          }                                       4025          }
4026       }                                          4026       }
4027    }                                             4027    }
4028                                                  4028 
4029    return;                                       4029    return;
4030 }                                                4030 }
4031                                                  4031 
4032                                                  4032 
4033 void G4OpenInventorXtExaminerViewer::saveRefC    4033 void G4OpenInventorXtExaminerViewer::saveRefCoordsOverWriteCB(Widget w, 
4034                                                  4034                                                  XtPointer client_data,
4035                                                  4035                                                  XtPointer call_data)
4036 {                                                4036 {
4037    XmAnyCallbackStruct *cbs = (XmAnyCallbackS    4037    XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
4038    G4OpenInventorXtExaminerViewer * This = (G    4038    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4039                                                  4039 
4040    switch (cbs->reason) {                        4040    switch (cbs->reason) {
4041    case XmCR_OK:                                 4041    case XmCR_OK:
4042       {                                          4042       {
4043          // Overwrite confirmed, save file an    4043          // Overwrite confirmed, save file and dismiss both
4044          // dialogs (file dialog and overwrit    4044          // dialogs (file dialog and overwrite confirmation dialog)
4045          std::ofstream ofs(This->saveRefCoord    4045          std::ofstream ofs(This->saveRefCoordsFileName.c_str());
4046          if(ofs.is_open()){                      4046          if(ofs.is_open()){
4047             float x,y,z;                         4047             float x,y,z;
4048             for(unsigned int i=0; i < This->r    4048             for(unsigned int i=0; i < This->refParticleTrajectory.size(); ++i){
4049                This->refParticleTrajectory[i]    4049                This->refParticleTrajectory[i].getValue(x,y,z);
4050                ofs << x << " " << y << " " <<    4050                ofs << x << " " << y << " " << z << "\n";
4051             }                                    4051             }
4052             ofs.close();                         4052             ofs.close();
4053             XtUnmanageChild(w);                  4053             XtUnmanageChild(w);
4054             XtUnmanageChild(This->saveRefCoor    4054             XtUnmanageChild(This->saveRefCoordsWidget);
4055          }                                       4055          }
4056          else{                                   4056          else{
4057             String dialogName = (char *) "Err    4057             String dialogName = (char *) "Error opening file";
4058             std::string msg = "There was a pr    4058             std::string msg = "There was a problem trying to open the file '";
4059             msg += This->saveRefCoordsFileNam    4059             msg += This->saveRefCoordsFileName;
4060             msg += "'";                          4060             msg += "'";
4061                                                  4061 
4062             This->warningMsgDialog(msg, dialo    4062             This->warningMsgDialog(msg, dialogName, NULL);
4063          }                                       4063          }
4064          break;                                  4064          break;
4065       }                                          4065       }
4066    case XmCR_CANCEL:                             4066    case XmCR_CANCEL:
4067       {                                          4067       {
4068          // Overwrite refused, dismiss overwr    4068          // Overwrite refused, dismiss overwrite confirmation
4069          // dialog and return to file dialog     4069          // dialog and return to file dialog
4070                                                  4070 
4071          // Give focus to the text field inst    4071          // Give focus to the text field instead of the OK button
4072          XmProcessTraversal(XtNameToWidget(Th    4072          XmProcessTraversal(XtNameToWidget(This->saveRefCoordsWidget, "Text"), XmTRAVERSE_CURRENT);
4073                                                  4073 
4074          XtUnmanageChild(w);                     4074          XtUnmanageChild(w);
4075          This->saveRefCoordsFileName.clear();    4075          This->saveRefCoordsFileName.clear();
4076          This->saveRefCoordsWidget = NULL;       4076          This->saveRefCoordsWidget = NULL;
4077          break;                                  4077          break;
4078       }                                          4078       }
4079    default:                                      4079    default:
4080       return;                                    4080       return;
4081    }                                             4081    }
4082 }                                                4082 }
4083                                                  4083 
4084                                                  4084 
4085 void G4OpenInventorXtExaminerViewer::loadScen    4085 void G4OpenInventorXtExaminerViewer::loadSceneGraphDialogCB(Widget,
4086                                                  4086                                              XtPointer client_data,
4087                                                  4087                                              XtPointer)
4088 {                                                4088 {
4089    G4OpenInventorXtExaminerViewer * This =       4089    G4OpenInventorXtExaminerViewer * This =
4090       (G4OpenInventorXtExaminerViewer *)clien    4090       (G4OpenInventorXtExaminerViewer *)client_data;
4091    This->popUpFileSelDialog(This->loadSceneGr    4091    This->popUpFileSelDialog(This->loadSceneGraphDialog, "Load Scene Graph",
4092                             "Load", loadScene    4092                             "Load", loadSceneGraphCB);
4093    return;                                       4093    return;
4094 }                                                4094 }
4095                                                  4095 
4096                                                  4096 
4097 void G4OpenInventorXtExaminerViewer::loadScen    4097 void G4OpenInventorXtExaminerViewer::loadSceneGraphCB(Widget w, 
4098                                                  4098                                                       XtPointer client_data,
4099                                                  4099                                                       XtPointer call_data)
4100 {                                                4100 {
4101    char *file = NULL;                            4101    char *file = NULL;
4102    G4OpenInventorXtExaminerViewer * This = (G    4102    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *)client_data;
4103    XmFileSelectionBoxCallbackStruct *cbs = (X    4103    XmFileSelectionBoxCallbackStruct *cbs = (XmFileSelectionBoxCallbackStruct *)call_data;
4104                                                  4104 
4105    if(cbs) {                                     4105    if(cbs) {
4106                                                  4106 
4107       file = (char *)XmStringUnparse(cbs->val    4107       file = (char *)XmStringUnparse(cbs->value, XmFONTLIST_DEFAULT_TAG,
4108                                      XmCHARSE    4108                                      XmCHARSET_TEXT, XmCHARSET_TEXT,
4109                                      NULL, 0,    4109                                      NULL, 0, XmOUTPUT_ALL);
4110                                                  4110 
4111       SoInput sceneInput;                        4111       SoInput sceneInput;
4112       if (!sceneInput.openFile(file)) {          4112       if (!sceneInput.openFile(file)) {
4113          String dialogName = (char *) "Proble    4113          String dialogName = (char *) "Problem opening file";
4114          std::string msg = "Cannot open file     4114          std::string msg = "Cannot open file ";
4115          msg += file;                            4115          msg += file;
4116          This->warningMsgDialog(msg, dialogNa    4116          This->warningMsgDialog(msg, dialogName, NULL);
4117                                                  4117 
4118          sceneInput.closeFile();                 4118          sceneInput.closeFile();
4119          XtUnmanageChild(w);                     4119          XtUnmanageChild(w);
4120       }                                          4120       }
4121       // Read the whole file into the databas    4121       // Read the whole file into the database
4122       This->newSceneGraph = SoDB::readAll(&sc    4122       This->newSceneGraph = SoDB::readAll(&sceneInput);
4123       if (This->newSceneGraph == NULL) {         4123       if (This->newSceneGraph == NULL) {
4124          String dialogName = (char *) "Proble    4124          String dialogName = (char *) "Problem reading file";
4125          std::string msg = "Problem reading f    4125          std::string msg = "Problem reading file";
4126          This->warningMsgDialog(msg, dialogNa    4126          This->warningMsgDialog(msg, dialogName, NULL);
4127          return;                                 4127          return;
4128       }                                          4128       }
4129                                                  4129 
4130       //This->newSceneGraph->ref();              4130       //This->newSceneGraph->ref();
4131       This->setSceneGraph(This->newSceneGraph    4131       This->setSceneGraph(This->newSceneGraph);
4132    }                                             4132    }
4133                                                  4133 
4134    return;                                       4134    return;
4135 }                                                4135 }
4136                                                  4136 
4137                                                  4137 
4138 void G4OpenInventorXtExaminerViewer::saveScen    4138 void G4OpenInventorXtExaminerViewer::saveSceneGraphDialogCB(Widget, 
4139                                                  4139                                              XtPointer client_data,
4140                                                  4140                                              XtPointer)
4141 {                                                4141 {
4142    G4OpenInventorXtExaminerViewer * This = (G    4142    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4143                                                  4143 
4144    int n;                                        4144    int n;
4145    Arg args[3];                                  4145    Arg args[3];
4146    Widget parent, scrollWidget;                  4146    Widget parent, scrollWidget;
4147    parent = SoXt::getShellWidget(This->getPar    4147    parent = SoXt::getShellWidget(This->getParentWidget());
4148                                                  4148 
4149    if (This->saveSceneGraphDialog == NULL) {     4149    if (This->saveSceneGraphDialog == NULL) {
4150                                                  4150 
4151       // Change the 'OK' button to whatever b    4151       // Change the 'OK' button to whatever buttonLabel contains
4152       XmString str = XmStringCreateLocalized(    4152       XmString str = XmStringCreateLocalized((char *)"Save");
4153                                                  4153 
4154       n = 0;                                     4154       n = 0;
4155       XtSetArg(args[n], XmNokLabelString, str    4155       XtSetArg(args[n], XmNokLabelString, str);   n++;
4156       XtSetArg(args[n], XmNresizePolicy, XmRE    4156       XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE);    n++;
4157                                                  4157 
4158       This->saveSceneGraphDialog = XmCreateFi    4158       This->saveSceneGraphDialog = XmCreateFileSelectionDialog(parent,(char *)"Save Scene Graph", args, n);
4159                                                  4159 
4160       XtAddCallback(This->saveSceneGraphDialo    4160       XtAddCallback(This->saveSceneGraphDialog, XmNokCallback, saveSceneGraphCB, This);
4161       XtAddCallback(This->saveSceneGraphDialo    4161       XtAddCallback(This->saveSceneGraphDialog, XmNcancelCallback, cancelFileSelDialogCB, This);
4162                                                  4162 
4163       // Adding scrolling functionality to th    4163       // Adding scrolling functionality to the widget
4164       scrollWidget = XmFileSelectionBoxGetChi    4164       scrollWidget = XmFileSelectionBoxGetChild(This->saveSceneGraphDialog, XmDIALOG_DIR_LIST);
4165       if (scrollWidget)                          4165       if (scrollWidget)
4166          xmAddMouseEventHandler(scrollWidget)    4166          xmAddMouseEventHandler(scrollWidget);
4167       scrollWidget = XmFileSelectionBoxGetChi    4167       scrollWidget = XmFileSelectionBoxGetChild(This->saveSceneGraphDialog, XmDIALOG_LIST);
4168       if (scrollWidget)                          4168       if (scrollWidget)
4169          xmAddMouseEventHandler(scrollWidget)    4169          xmAddMouseEventHandler(scrollWidget);
4170                                                  4170 
4171       XtUnmanageChild(XmSelectionBoxGetChild(    4171       XtUnmanageChild(XmSelectionBoxGetChild(This->saveSceneGraphDialog, XmDIALOG_HELP_BUTTON));
4172       XmStringFree(str);                         4172       XmStringFree(str);
4173    }                                             4173    }
4174                                                  4174 
4175    //TODO: Auto name?                            4175    //TODO: Auto name?
4176                                                  4176 
4177    XtManageChild(This->saveSceneGraphDialog);    4177    XtManageChild(This->saveSceneGraphDialog);
4178                                                  4178 
4179 }                                                4179 }
4180                                                  4180 
4181                                                  4181 
4182                                                  4182 
4183 void G4OpenInventorXtExaminerViewer::saveScen    4183 void G4OpenInventorXtExaminerViewer::saveSceneGraphCB(Widget w, 
4184                                                  4184                                                       XtPointer client_data,
4185                                                  4185                                                       XtPointer call_data)
4186 {                                                4186 {
4187    char *file;                                   4187    char *file;
4188    G4OpenInventorXtExaminerViewer * This = (G    4188    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4189    XmFileSelectionBoxCallbackStruct *cbs =       4189    XmFileSelectionBoxCallbackStruct *cbs =
4190       (XmFileSelectionBoxCallbackStruct *) ca    4190       (XmFileSelectionBoxCallbackStruct *) call_data;
4191                                                  4191 
4192    if (cbs) {                                    4192    if (cbs) {
4193                                                  4193 
4194       file = (char *)XmStringUnparse(cbs->val    4194       file = (char *)XmStringUnparse(cbs->value, XmFONTLIST_DEFAULT_TAG,
4195                                      XmCHARSE    4195                                      XmCHARSET_TEXT, XmCHARSET_TEXT,
4196                                      NULL, 0,    4196                                      NULL, 0, XmOUTPUT_ALL);
4197                                                  4197 
4198       std::ifstream ifile(file);                 4198       std::ifstream ifile(file);
4199       if (ifile) {                               4199       if (ifile) {
4200          //File already exists                   4200          //File already exists
4201                                                  4201 
4202          Arg args[4];                            4202          Arg args[4];
4203          Widget parent = This->getParentWidge    4203          Widget parent = This->getParentWidget(); //gets the dialogshell of the ExaminerViewer widget
4204          Widget confirmOverwriteDialog;          4204          Widget confirmOverwriteDialog;
4205          XmString msg;                           4205          XmString msg;
4206                                                  4206 
4207          confirmOverwriteDialog = XmCreateQue    4207          confirmOverwriteDialog = XmCreateQuestionDialog (parent, (char *)"Confirm overwrite", args, 0);
4208          msg = XmStringCreateLocalized ((char    4208          msg = XmStringCreateLocalized ((char *)"File exists. Overwrite?");
4209          XtVaSetValues (confirmOverwriteDialo    4209          XtVaSetValues (confirmOverwriteDialog, XmNmessageString, msg, NULL);
4210                                                  4210 
4211          // If users presses OK, we want to r    4211          // If users presses OK, we want to return to this function and
4212          // save the file.  For that to work,    4212          // save the file.  For that to work, pass it the current widget
4213          // to be able to grab the filename.     4213          // to be able to grab the filename.
4214          XtVaSetValues (confirmOverwriteDialo    4214          XtVaSetValues (confirmOverwriteDialog, XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, NULL);
4215          XtAddCallback (confirmOverwriteDialo    4215          XtAddCallback (confirmOverwriteDialog, XmNokCallback, saveSceneGraphOverWriteCB, client_data);
4216          XtAddCallback (confirmOverwriteDialo    4216          XtAddCallback (confirmOverwriteDialog, XmNcancelCallback, saveSceneGraphOverWriteCB, client_data);
4217                                                  4217 
4218          XmStringFree (msg);                     4218          XmStringFree (msg);
4219                                                  4219 
4220          //The confirmOverwriteDialog will ne    4220          //The confirmOverwriteDialog will need this
4221          This->saveScenegraphFileName = file;    4221          This->saveScenegraphFileName = file;
4222          This->saveScenegraphWidget = w;         4222          This->saveScenegraphWidget = w;
4223                                                  4223 
4224          XtUnmanageChild(XtNameToWidget(confi    4224          XtUnmanageChild(XtNameToWidget(confirmOverwriteDialog, "Help"));
4225          XtManageChild(confirmOverwriteDialog    4225          XtManageChild(confirmOverwriteDialog);
4226                                                  4226 
4227          return;                                 4227          return;
4228       }                                          4228       }
4229       else{                                      4229       else{
4230                                                  4230 
4231          SoWriteAction writeAction;              4231          SoWriteAction writeAction;
4232          SoSeparator *root = (SoSeparator *)     4232          SoSeparator *root = (SoSeparator *) (This->getSceneGraph());
4233                                                  4233 
4234          SoOutput * out = writeAction.getOutp    4234          SoOutput * out = writeAction.getOutput();
4235                                                  4235 
4236          if(out->openFile(file)){                4236          if(out->openFile(file)){
4237             out->setBinary(FALSE);               4237             out->setBinary(FALSE);
4238             writeAction.apply(root);             4238             writeAction.apply(root);
4239             out->closeFile();                    4239             out->closeFile();
4240                                                  4240 
4241             XtUnmanageChild(w);                  4241             XtUnmanageChild(w);
4242          }                                       4242          }
4243          else{                                   4243          else{
4244             String dialogName = (char *) "Err    4244             String dialogName = (char *) "Error opening file";
4245             std::string msg = "There was a pr    4245             std::string msg = "There was a problem trying to open the file '";
4246             msg += This->saveScenegraphFileNa    4246             msg += This->saveScenegraphFileName;
4247             msg += "'";                          4247             msg += "'";
4248                                                  4248 
4249             This->warningMsgDialog(msg, dialo    4249             This->warningMsgDialog(msg, dialogName, NULL);
4250          }                                       4250          }
4251                                                  4251 
4252       }                                          4252       }
4253    }                                             4253    }
4254                                                  4254 
4255    return;                                       4255    return;
4256 }                                                4256 }
4257                                                  4257 
4258                                                  4258 
4259                                                  4259 
4260 void G4OpenInventorXtExaminerViewer::saveScen    4260 void G4OpenInventorXtExaminerViewer::saveSceneGraphOverWriteCB(Widget w, 
4261                                                  4261                                                   XtPointer client_data,
4262                                                  4262                                                   XtPointer call_data)
4263 {                                                4263 {
4264    XmAnyCallbackStruct *cbs = (XmAnyCallbackS    4264    XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
4265    G4OpenInventorXtExaminerViewer * This = (G    4265    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4266                                                  4266 
4267    switch (cbs->reason) {                        4267    switch (cbs->reason) {
4268    case XmCR_OK:                                 4268    case XmCR_OK:
4269       {                                          4269       {
4270          // Overwrite confirmed, save file an    4270          // Overwrite confirmed, save file and dismiss both
4271          // dialogs (file dialog and overwrit    4271          // dialogs (file dialog and overwrite confirmation dialog)
4272          SoWriteAction writeAction;              4272          SoWriteAction writeAction;
4273          SoSeparator *root = (SoSeparator *)     4273          SoSeparator *root = (SoSeparator *) (This->getSceneGraph());
4274                                                  4274 
4275          SoOutput * out = writeAction.getOutp    4275          SoOutput * out = writeAction.getOutput();
4276          if(out->openFile(This->saveScenegrap    4276          if(out->openFile(This->saveScenegraphFileName.c_str())){
4277             out->setBinary(FALSE);               4277             out->setBinary(FALSE);
4278             writeAction.apply(root);             4278             writeAction.apply(root);
4279             out->closeFile();                    4279             out->closeFile();
4280                                                  4280 
4281             XtUnmanageChild(w);                  4281             XtUnmanageChild(w);
4282             XtUnmanageChild(This->saveScenegr    4282             XtUnmanageChild(This->saveScenegraphWidget);
4283             This->saveScenegraphFileName.clea    4283             This->saveScenegraphFileName.clear();
4284             This->saveScenegraphWidget = NULL    4284             This->saveScenegraphWidget = NULL;
4285          }                                       4285          }
4286          else{                                   4286          else{
4287             String dialogName = (char *) "Err    4287             String dialogName = (char *) "Error opening file";
4288             std::string msg = "There was a pr    4288             std::string msg = "There was a problem trying to open the file '";
4289             msg += This->saveScenegraphFileNa    4289             msg += This->saveScenegraphFileName;
4290             msg += "'";                          4290             msg += "'";
4291                                                  4291 
4292             This->warningMsgDialog(msg, dialo    4292             This->warningMsgDialog(msg, dialogName, NULL);
4293             This->saveScenegraphFileName.clea    4293             This->saveScenegraphFileName.clear();
4294             This->saveScenegraphWidget = NULL    4294             This->saveScenegraphWidget = NULL;
4295          }                                       4295          }
4296          break;                                  4296          break;
4297       }                                          4297       }
4298    case XmCR_CANCEL:                             4298    case XmCR_CANCEL:
4299       {                                          4299       {
4300          // Overwrite refused, dismiss overwr    4300          // Overwrite refused, dismiss overwrite confirmation
4301          // dialog and return to file dialog     4301          // dialog and return to file dialog
4302                                                  4302 
4303          // Give focus to the text field inst    4303          // Give focus to the text field instead of the OK button
4304          XmProcessTraversal(XtNameToWidget(Th    4304          XmProcessTraversal(XtNameToWidget(This->saveScenegraphWidget, "Text"), XmTRAVERSE_CURRENT);
4305                                                  4305 
4306          XtUnmanageChild(w);                     4306          XtUnmanageChild(w);
4307          This->saveScenegraphFileName.clear()    4307          This->saveScenegraphFileName.clear();
4308          This->saveScenegraphWidget = NULL;      4308          This->saveScenegraphWidget = NULL;
4309          break;                                  4309          break;
4310       }                                          4310       }
4311    default:                                      4311    default:
4312       return;                                    4312       return;
4313    }                                             4313    }
4314 }                                                4314 }
4315                                                  4315 
4316                                                  4316 
4317 // Receives the name of the bookmark clicked     4317 // Receives the name of the bookmark clicked and searches for it in viewPtList.
4318                                                  4318 
4319 void G4OpenInventorXtExaminerViewer::loadBook    4319 void G4OpenInventorXtExaminerViewer::loadBookmarkCB(Widget, 
4320                                                  4320                                                     XtPointer client_data,
4321                                                  4321                                                     XtPointer call_data)
4322 {                                                4322 {
4323    char *vpName;                                 4323    char *vpName;
4324    G4OpenInventorXtExaminerViewer * This = (G    4324    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4325    XmListCallbackStruct *cbs = (XmListCallbac    4325    XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
4326                                                  4326 
4327    vpName = (char *) XmStringUnparse(cbs->ite    4327    vpName = (char *) XmStringUnparse(cbs->item, XmFONTLIST_DEFAULT_TAG,
4328                                      XmCHARSE    4328                                      XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL);
4329                                                  4329 
4330    for (int i = 0; i < (int) This->viewPtList    4330    for (int i = 0; i < (int) This->viewPtList.size(); i++) {
4331       if (!strcmp(This->viewPtList[i].viewPtN    4331       if (!strcmp(This->viewPtList[i].viewPtName, vpName)) {
4332          This->viewPtIdx = i;                    4332          This->viewPtIdx = i;
4333          break;                                  4333          break;
4334       }                                          4334       }
4335    }                                             4335    }
4336    XmTextSetString(This->viewPtSelection, vpN    4336    XmTextSetString(This->viewPtSelection, vpName);
4337                                                  4337 
4338    This->writeViewPtIdx();                       4338    This->writeViewPtIdx();
4339    This->setViewPt();                            4339    This->setViewPt();
4340    XtFree(vpName);                               4340    XtFree(vpName);
4341 }                                                4341 }
4342                                                  4342 
4343                                                  4343 
4344                                                  4344 
4345 void G4OpenInventorXtExaminerViewer::deleteBo    4345 void G4OpenInventorXtExaminerViewer::deleteBookmarkCB(Widget, 
4346                                                  4346                                                       XtPointer client_data,
4347                                                  4347                                                       XtPointer)
4348 {                                                4348 {
4349    char *vpName;                                 4349    char *vpName;
4350    G4OpenInventorXtExaminerViewer * This = (G    4350    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4351                                                  4351 
4352    vpName = XmTextGetString(This->viewPtSelec    4352    vpName = XmTextGetString(This->viewPtSelection);
4353                                                  4353 
4354    XmString vpNameStr = XmStringCreateLocaliz    4354    XmString vpNameStr = XmStringCreateLocalized(vpName);
4355                                                  4355 
4356    if (XmListItemExists(This->myViewPtList, v    4356    if (XmListItemExists(This->myViewPtList, vpNameStr)) {
4357       XmListDeleteItem(This->myViewPtList, vp    4357       XmListDeleteItem(This->myViewPtList, vpNameStr);
4358       This->deleteViewPt(vpName);                4358       This->deleteViewPt(vpName);
4359    }                                             4359    }
4360                                                  4360 
4361    XmStringFree(vpNameStr);                      4361    XmStringFree(vpNameStr);
4362    XmTextSetString(This->viewPtSelection, NUL    4362    XmTextSetString(This->viewPtSelection, NULL);
4363    XtFree(vpName);                               4363    XtFree(vpName);
4364 }                                                4364 }
4365                                                  4365 
4366                                                  4366 
4367 void G4OpenInventorXtExaminerViewer::renameBo    4367 void G4OpenInventorXtExaminerViewer::renameBookmarkCB(Widget, 
4368                                                  4368                                                       XtPointer client_data,
4369                                                  4369                                                       XtPointer)
4370 {                                                4370 {
4371    std::string vpNameStr;                        4371    std::string vpNameStr;
4372    char *vpName;                                 4372    char *vpName;
4373    int *pos_list, pos_cnt;                       4373    int *pos_list, pos_cnt;
4374    G4OpenInventorXtExaminerViewer * This = (G    4374    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4375                                                  4375 
4376    vpName = XmTextGetString(This->viewPtSelec    4376    vpName = XmTextGetString(This->viewPtSelection);
4377                                                  4377 
4378    if (!strlen(vpName) || !strcmp(This->curVi    4378    if (!strlen(vpName) || !strcmp(This->curViewPtName, vpName)) {
4379       XtFree(vpName);                            4379       XtFree(vpName);
4380       return;                                    4380       return;
4381    }                                             4381    }
4382                                                  4382 
4383    vpNameStr = vpName;                           4383    vpNameStr = vpName;
4384    XtFree(vpName);                               4384    XtFree(vpName);
4385    int beg = vpNameStr.find_first_not_of(' ')    4385    int beg = vpNameStr.find_first_not_of(' '); // Remove leading/trailing spaces
4386    int end = vpNameStr.find_last_not_of(' ');    4386    int end = vpNameStr.find_last_not_of(' ');
4387    vpNameStr = vpNameStr.substr(beg, end - be    4387    vpNameStr = vpNameStr.substr(beg, end - beg + 1);
4388    const int nVPName = vpNameStr.size() + 1;     4388    const int nVPName = vpNameStr.size() + 1;
4389    char* vpName1 = new char[nVPName];            4389    char* vpName1 = new char[nVPName];
4390    strncpy(vpName1, vpNameStr.c_str(), nVPNam    4390    strncpy(vpName1, vpNameStr.c_str(), nVPName);
4391                                                  4391 
4392    int size = This->viewPtList.size();           4392    int size = This->viewPtList.size();
4393    for (int i = 0; i < size; i++) {              4393    for (int i = 0; i < size; i++) {
4394       if (!strcmp(vpName1, This->viewPtList[i    4394       if (!strcmp(vpName1, This->viewPtList[i].viewPtName)) {
4395                                                  4395 
4396          String dialogName = (char *) "Existi    4396          String dialogName = (char *) "Existing Viewpoint";
4397          std::string msg = "'";                  4397          std::string msg = "'";
4398          msg += vpName1;                         4398          msg += vpName1;
4399          msg += "' already exists. Choose a d    4399          msg += "' already exists. Choose a different name";
4400                                                  4400 
4401          This->warningMsgDialog(msg, dialogNa    4401          This->warningMsgDialog(msg, dialogName, NULL);
4402          delete[] vpName1;                       4402          delete[] vpName1;
4403          return;                                 4403          return;
4404       }                                          4404       }
4405    }                                             4405    }
4406                                                  4406 
4407    XmString vpNameXmStr = XmStringCreateLocal    4407    XmString vpNameXmStr = XmStringCreateLocalized(vpName1);
4408                                                  4408 
4409    if (XmListGetSelectedPos(This->myViewPtLis    4409    if (XmListGetSelectedPos(This->myViewPtList, &pos_list, &pos_cnt)) {
4410       XmListReplaceItemsPos(This->myViewPtLis    4410       XmListReplaceItemsPos(This->myViewPtList, &vpNameXmStr, 1, pos_list[0]);
4411       This->renameViewPt(vpName1);               4411       This->renameViewPt(vpName1);
4412       XtFree((char *) pos_list);                 4412       XtFree((char *) pos_list);
4413    }                                             4413    }
4414                                                  4414 
4415    if (This->currentState == VIEWPOINT)          4415    if (This->currentState == VIEWPOINT)
4416       This->scheduleRedraw();                    4416       This->scheduleRedraw();
4417                                                  4417 
4418    XmStringFree(vpNameXmStr);                    4418    XmStringFree(vpNameXmStr);
4419    delete[] vpName1;                             4419    delete[] vpName1;
4420 }                                                4420 }
4421                                                  4421 
4422                                                  4422 
4423 void G4OpenInventorXtExaminerViewer::sortBook    4423 void G4OpenInventorXtExaminerViewer::sortBookmarksCB(Widget, 
4424                                                  4424                                                      XtPointer client_data,
4425                                                  4425                                                      XtPointer)
4426 {                                                4426 {
4427    int size;                                     4427    int size;
4428    char *vpName;                                 4428    char *vpName;
4429    XmString *strList, *newStrList;               4429    XmString *strList, *newStrList;
4430    std::vector<std::string> charList;            4430    std::vector<std::string> charList;
4431    G4OpenInventorXtExaminerViewer * This = (G    4431    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4432                                                  4432 
4433    if (This->viewPtList.size() < 2)              4433    if (This->viewPtList.size() < 2)
4434       return;                                    4434       return;
4435                                                  4435 
4436    // Get current entries from the list          4436    // Get current entries from the list
4437    XtVaGetValues(This->myViewPtList, XmNitemC    4437    XtVaGetValues(This->myViewPtList, XmNitemCount, &size, XmNitems, &strList,
4438                  NULL);                          4438                  NULL);
4439                                                  4439 
4440    for (int i = 0; i < size; i++) {              4440    for (int i = 0; i < size; i++) {
4441       vpName = (char *) XmStringUnparse(strLi    4441       vpName = (char *) XmStringUnparse(strList[i], XmFONTLIST_DEFAULT_TAG,
4442                                         XmCHA    4442                                         XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL);
4443       charList.push_back(vpName);                4443       charList.push_back(vpName);
4444       XtFree(vpName);                            4444       XtFree(vpName);
4445    }                                             4445    }
4446                                                  4446 
4447    std::sort(charList.begin(), charList.end()    4447    std::sort(charList.begin(), charList.end());
4448                                                  4448 
4449    newStrList = (XmString *) XtMalloc(size *     4449    newStrList = (XmString *) XtMalloc(size * sizeof(XmString));
4450    for (int i = 0; i < size; i++) {              4450    for (int i = 0; i < size; i++) {
4451       // viewPtIdx has to be changed to accou    4451       // viewPtIdx has to be changed to account for a different order in viewPtList
4452       if (!strcmp(charList[i].c_str(), This->    4452       if (!strcmp(charList[i].c_str(), This->curViewPtName))
4453          This->viewPtIdx = i;                    4453          This->viewPtIdx = i;
4454       const int nVPName = charList[i].size()     4454       const int nVPName = charList[i].size() + 1;
4455       char *vpName2 = new char[nVPName];         4455       char *vpName2 = new char[nVPName];
4456       strncpy(vpName2, charList[i].c_str(), n    4456       strncpy(vpName2, charList[i].c_str(), nVPName);
4457       newStrList[i] = XmStringCreateLocalized    4457       newStrList[i] = XmStringCreateLocalized(vpName2);
4458       delete [] vpName2;                         4458       delete [] vpName2;
4459    }                                             4459    }
4460                                                  4460 
4461    XmListDeleteAllItems(This->myViewPtList);     4461    XmListDeleteAllItems(This->myViewPtList);
4462    XmListAddItemsUnselected(This->myViewPtLis    4462    XmListAddItemsUnselected(This->myViewPtList, newStrList, size, 1);
4463                                                  4463 
4464    This->sortViewPts(charList);                  4464    This->sortViewPts(charList);
4465                                                  4465 
4466    if (newStrList != NULL) {                     4466    if (newStrList != NULL) {
4467       for (int i = 0; i < size; i++)             4467       for (int i = 0; i < size; i++)
4468          XmStringFree(newStrList[i]);            4468          XmStringFree(newStrList[i]);
4469       XtFree((char *) newStrList);               4469       XtFree((char *) newStrList);
4470    }                                             4470    }
4471 }                                                4471 }
4472                                                  4472 
4473                                                  4473 
4474 void G4OpenInventorXtExaminerViewer::evenOutR    4474 void G4OpenInventorXtExaminerViewer::evenOutRefParticlePts()
4475 {                                                4475 {
4476    if(this->refParticleTrajectory.empty())       4476    if(this->refParticleTrajectory.empty())
4477       return;                                    4477       return;
4478                                                  4478 
4479    SbVec3f p1, p2, p3, dirNow, dirNxt, dir, p    4479    SbVec3f p1, p2, p3, dirNow, dirNxt, dir, p2_tmp, p_start, p_corner, p_nxt;
4480    float avgDistBtwPts = 0;                      4480    float avgDistBtwPts = 0;
4481    float totalDistBtwPts = 0;                    4481    float totalDistBtwPts = 0;
4482    std::vector<SbVec3f> newRefParticleTraject    4482    std::vector<SbVec3f> newRefParticleTrajectory;
4483    SbVec3f refPoint;                             4483    SbVec3f refPoint;
4484    int size = refParticleTrajectory.size() -     4484    int size = refParticleTrajectory.size() - 1;
4485    int numOfPts = 0;                             4485    int numOfPts = 0;
4486    for (int i = 0; i < size; i++) {              4486    for (int i = 0; i < size; i++) {
4487       p1 = refParticleTrajectory[i];             4487       p1 = refParticleTrajectory[i];
4488       p2 = refParticleTrajectory[i + 1];         4488       p2 = refParticleTrajectory[i + 1];
4489       if (p1 == p2)                              4489       if (p1 == p2)
4490          continue;                               4490          continue;
4491       numOfPts++;                                4491       numOfPts++;
4492       totalDistBtwPts += (p2 - p1).length();     4492       totalDistBtwPts += (p2 - p1).length();
4493    }                                             4493    }
4494    // Nothing useful to do (and fix Coverity)    4494    // Nothing useful to do (and fix Coverity)
4495    if (numOfPts <= 2) return;                    4495    if (numOfPts <= 2) return;
4496                                                  4496 
4497    avgDistBtwPts = totalDistBtwPts / numOfPts    4497    avgDistBtwPts = totalDistBtwPts / numOfPts;
4498    float minDistAllowed = 0.75 * avgDistBtwPt    4498    float minDistAllowed = 0.75 * avgDistBtwPts;
4499    // float maxDistAllowed = 1.25 * avgDistBt    4499    // float maxDistAllowed = 1.25 * avgDistBtwPts; // Pts tend to be close not far
4500                                                  4500 
4501    float x, y, z;                                4501    float x, y, z;
4502    int i = 0, j = 0;                             4502    int i = 0, j = 0;
4503    while (i < size) {                            4503    while (i < size) {
4504       p1 = refParticleTrajectory[i];             4504       p1 = refParticleTrajectory[i];
4505       p2 = refParticleTrajectory[i + 1];         4505       p2 = refParticleTrajectory[i + 1];
4506                                                  4506 
4507       refPoint = p1;                             4507       refPoint = p1;
4508       p1.getValue(x, y, z);                      4508       p1.getValue(x, y, z);
4509                                                  4509 
4510       newRefParticleTrajectory.push_back(refP    4510       newRefParticleTrajectory.push_back(refPoint);
4511                                                  4511 
4512       j = i;                                     4512       j = i;
4513       while ((p2 - p1).length() < minDistAllo    4513       while ((p2 - p1).length() < minDistAllowed && j < (size - 1)) {
4514          j++;                                    4514          j++;
4515                                                  4515 
4516          p1 = refParticleTrajectory[j];          4516          p1 = refParticleTrajectory[j];
4517          p2 = refParticleTrajectory[j + 1];      4517          p2 = refParticleTrajectory[j + 1];
4518       }                                          4518       }
4519       if (j != i)                                4519       if (j != i)
4520          i = j + 1;                              4520          i = j + 1;
4521       else                                       4521       else
4522          i++;                                    4522          i++;
4523    }                                             4523    }
4524                                                  4524 
4525    refParticleTrajectory.clear();                4525    refParticleTrajectory.clear();
4526    refParticleTrajectory = newRefParticleTraj    4526    refParticleTrajectory = newRefParticleTrajectory;
4527 }                                                4527 }
4528                                                  4528 
4529                                                  4529 
4530 // Called when the viewer is closed; closes a    4530 // Called when the viewer is closed; closes all open widgets.
4531                                                  4531 
4532 void G4OpenInventorXtExaminerViewer::closeMai    4532 void G4OpenInventorXtExaminerViewer::closeMainWindowCB(Widget, 
4533                                                  4533                                                        XtPointer client_data,
4534                                                  4534                                                        XtPointer)
4535 {                                                4535 {
4536    G4OpenInventorXtExaminerViewer * This =       4536    G4OpenInventorXtExaminerViewer * This =
4537       (G4OpenInventorXtExaminerViewer *) clie    4537       (G4OpenInventorXtExaminerViewer *) client_data;
4538                                                  4538 
4539    if (This->openFileDialog)                     4539    if (This->openFileDialog)
4540       XtUnmanageChild(This->openFileDialog);     4540       XtUnmanageChild(This->openFileDialog);
4541                                                  4541 
4542    if (This->newFileDialog)                      4542    if (This->newFileDialog)
4543       XtUnmanageChild(This->newFileDialog);      4543       XtUnmanageChild(This->newFileDialog);
4544                                                  4544 
4545    if (This->listsDialog)                        4545    if (This->listsDialog)
4546       closeListsDialogCB(NULL, This, NULL);      4546       closeListsDialogCB(NULL, This, NULL);
4547 }                                                4547 }
4548                                                  4548 
4549                                                  4549 
4550 void G4OpenInventorXtExaminerViewer::saveCurC    4550 void G4OpenInventorXtExaminerViewer::saveCurCamera()
4551 {                                                4551 {
4552    SoCamera *cam = getCamera();                  4552    SoCamera *cam = getCamera();
4553    camB4Animation.viewportMapping = cam->view    4553    camB4Animation.viewportMapping = cam->viewportMapping.getValue();
4554    camB4Animation.position = cam->position.ge    4554    camB4Animation.position = cam->position.getValue();
4555    camB4Animation.orientation = cam->orientat    4555    camB4Animation.orientation = cam->orientation.getValue();
4556    camB4Animation.aspectRatio = cam->aspectRa    4556    camB4Animation.aspectRatio = cam->aspectRatio.getValue();
4557    camB4Animation.nearDistance = cam->nearDis    4557    camB4Animation.nearDistance = cam->nearDistance.getValue();
4558    camB4Animation.farDistance = cam->farDista    4558    camB4Animation.farDistance = cam->farDistance.getValue();
4559    camB4Animation.focalDistance = cam->focalD    4559    camB4Animation.focalDistance = cam->focalDistance.getValue();
4560                                                  4560 
4561    if (cam->isOfType(SoPerspectiveCamera::get    4561    if (cam->isOfType(SoPerspectiveCamera::getClassTypeId())) {
4562       camB4Animation.height =                    4562       camB4Animation.height =
4563          ((SoPerspectiveCamera *) cam)->heigh    4563          ((SoPerspectiveCamera *) cam)->heightAngle.getValue();
4564       camB4Animation.camType = PERSPECTIVE;      4564       camB4Animation.camType = PERSPECTIVE;
4565    } else if (cam->isOfType(SoOrthographicCam    4565    } else if (cam->isOfType(SoOrthographicCamera::getClassTypeId())) {
4566       camB4Animation.height =                    4566       camB4Animation.height =
4567          ((SoOrthographicCamera *) cam)->heig    4567          ((SoOrthographicCamera *) cam)->height.getValue();
4568       camB4Animation.camType = ORTHOGRAPHIC;     4568       camB4Animation.camType = ORTHOGRAPHIC;
4569    }                                             4569    }
4570 }                                                4570 }
4571                                                  4571 
4572                                                  4572 
4573 void G4OpenInventorXtExaminerViewer::restoreC    4573 void G4OpenInventorXtExaminerViewer::restoreCamera()
4574 {                                                4574 {
4575    SoCamera *cam = getCamera();                  4575    SoCamera *cam = getCamera();
4576                                                  4576 
4577    cam->viewportMapping = camB4Animation.view    4577    cam->viewportMapping = camB4Animation.viewportMapping;
4578    cam->position = camB4Animation.position;      4578    cam->position = camB4Animation.position;
4579    cam->orientation = camB4Animation.orientat    4579    cam->orientation = camB4Animation.orientation;
4580    cam->aspectRatio = camB4Animation.aspectRa    4580    cam->aspectRatio = camB4Animation.aspectRatio;
4581    cam->nearDistance = camB4Animation.nearDis    4581    cam->nearDistance = camB4Animation.nearDistance;
4582    cam->farDistance = camB4Animation.farDista    4582    cam->farDistance = camB4Animation.farDistance;
4583    cam->focalDistance = camB4Animation.focalD    4583    cam->focalDistance = camB4Animation.focalDistance;
4584                                                  4584 
4585    if (cam->isOfType(SoPerspectiveCamera::get    4585    if (cam->isOfType(SoPerspectiveCamera::getClassTypeId())) {
4586       if (camB4Animation.camType == ORTHOGRAP    4586       if (camB4Animation.camType == ORTHOGRAPHIC) {
4587          toggleCameraType();                     4587          toggleCameraType();
4588          cam = getCamera();                      4588          cam = getCamera();
4589          ((SoOrthographicCamera *) cam)->heig    4589          ((SoOrthographicCamera *) cam)->height.setValue(
4590                                                  4590                                                          camB4Animation.height);
4591       } else                                     4591       } else
4592          ((SoPerspectiveCamera *) cam)->heigh    4592          ((SoPerspectiveCamera *) cam)->heightAngle.setValue(
4593                                                  4593                                                              camB4Animation.height);
4594    } else if (cam->isOfType(SoOrthographicCam    4594    } else if (cam->isOfType(SoOrthographicCamera::getClassTypeId())) {
4595       if (camB4Animation.camType == PERSPECTI    4595       if (camB4Animation.camType == PERSPECTIVE) {
4596          toggleCameraType();                     4596          toggleCameraType();
4597          cam = getCamera();                      4597          cam = getCamera();
4598          ((SoPerspectiveCamera *) cam)->heigh    4598          ((SoPerspectiveCamera *) cam)->heightAngle.setValue(
4599                                                  4599                                                              camB4Animation.height);
4600       } else                                     4600       } else
4601          ((SoOrthographicCamera *) cam)->heig    4601          ((SoOrthographicCamera *) cam)->height.setValue(
4602                                                  4602                                                          camB4Animation.height);
4603    }                                             4603    }
4604 }                                                4604 }
4605                                                  4605 
4606                                                  4606 
4607 void G4OpenInventorXtExaminerViewer::animateS    4607 void G4OpenInventorXtExaminerViewer::animateSensorRotationCB(void *data, 
4608                                                  4608                                                              SoSensor *sensor)
4609 {                                                4609 {
4610    SbTime curTime = SbTime::getTimeOfDay();      4610    SbTime curTime = SbTime::getTimeOfDay();
4611    G4OpenInventorXtExaminerViewer * This = (G    4611    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) data;
4612    SoTimerSensor *s = (SoTimerSensor *) senso    4612    SoTimerSensor *s = (SoTimerSensor *) sensor;
4613                                                  4613 
4614    float t = float((curTime - s->getBaseTime(    4614    float t = float((curTime - s->getBaseTime()).getValue())
4615       / This->animateBtwPtsPeriod;               4615       / This->animateBtwPtsPeriod;
4616                                                  4616 
4617    if ((t > 1.0f) || (t + s->getInterval().ge    4617    if ((t > 1.0f) || (t + s->getInterval().getValue() > 1.0f))
4618       t = 1.0f;                                  4618       t = 1.0f;
4619    SbBool end = (t == 1.0f);                     4619    SbBool end = (t == 1.0f);
4620                                                  4620 
4621    if (end) {                                    4621    if (end) {
4622       This->animateSensorRotation->unschedule    4622       This->animateSensorRotation->unschedule();
4623       if(This->rotCnt){                          4623       if(This->rotCnt){
4624          // rotations left                       4624          // rotations left
4625          This->rotateCamera();                   4625          This->rotateCamera();
4626       }                                          4626       }
4627       else {                                     4627       else {
4628          // rotation over                        4628          // rotation over
4629          This->currentState = This->prevState    4629          This->currentState = This->prevState;
4630          return;                                 4630          return;
4631       }                                          4631       }
4632    }                                             4632    }
4633                                                  4633 
4634 }                                                4634 }
4635                                                  4635 
4636                                                  4636 
4637 // Called repeatedly during reference particl    4637 // Called repeatedly during reference particle animation
4638                                                  4638 
4639 void G4OpenInventorXtExaminerViewer::animateS    4639 void G4OpenInventorXtExaminerViewer::animateSensorCB(void *data, 
4640                                                  4640                                                      SoSensor *sensor)
4641 {                                                4641 {
4642    SbTime curTime = SbTime::getTimeOfDay();      4642    SbTime curTime = SbTime::getTimeOfDay();
4643    G4OpenInventorXtExaminerViewer * This = (G    4643    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) data;
4644    SoCamera *cam = This->getCamera();            4644    SoCamera *cam = This->getCamera();
4645    SoTimerSensor *s = (SoTimerSensor *) senso    4645    SoTimerSensor *s = (SoTimerSensor *) sensor;
4646                                                  4646 
4647    float t = float((curTime - s->getBaseTime(    4647    float t = float((curTime - s->getBaseTime()).getValue())
4648       / This->animateBtwPtsPeriod;               4648       / This->animateBtwPtsPeriod;
4649                                                  4649 
4650    if ((t > 1.0f) || (t + s->getInterval().ge    4650    if ((t > 1.0f) || (t + s->getInterval().getValue() > 1.0f))
4651       t = 1.0f;                                  4651       t = 1.0f;
4652    SbBool end = (t == 1.0f);                     4652    SbBool end = (t == 1.0f);
4653                                                  4653 
4654    cam->orientation = SbRotation::slerp(This-    4654    cam->orientation = SbRotation::slerp(This->camStartOrient, This->camEndOrient, t);
4655    cam->position = This->camStartPos + (This-    4655    cam->position = This->camStartPos + (This->camEndPos - This->camStartPos) * t;
4656                                                  4656 
4657    if (end) {                                    4657    if (end) {
4658       This->animateSensor->unschedule();         4658       This->animateSensor->unschedule();
4659                                                  4659 
4660       if (This->currentState == ANIMATION) {     4660       if (This->currentState == ANIMATION) {
4661          if (This->refParticleIdx < (int) (Th    4661          if (This->refParticleIdx < (int) (This->refParticleTrajectory.size() - 1))
4662             This->animateRefParticle();          4662             This->animateRefParticle();
4663          else {                                  4663          else {
4664             This->animateBtwPtsPeriod = MIN_S    4664             This->animateBtwPtsPeriod = MIN_SPEED;
4665             This->speedStep = START_STEP;        4665             This->speedStep = START_STEP;
4666          }                                       4666          }
4667       }                                          4667       }
4668       if (This->currentState == REVERSED_ANIM    4668       if (This->currentState == REVERSED_ANIMATION) {
4669          if (This->refParticleIdx >= 1)          4669          if (This->refParticleIdx >= 1)
4670             This->animateRefParticle();          4670             This->animateRefParticle();
4671          else {                                  4671          else {
4672             This->animateBtwPtsPeriod = MIN_S    4672             This->animateBtwPtsPeriod = MIN_SPEED;
4673             This->speedStep = START_STEP;        4673             This->speedStep = START_STEP;
4674          }                                       4674          }
4675       }                                          4675       }
4676    }                                             4676    }
4677 }                                                4677 }
4678                                                  4678 
4679                                                  4679 
4680 void G4OpenInventorXtExaminerViewer::setStart    4680 void G4OpenInventorXtExaminerViewer::setStartingPtForAnimation()
4681 {                                                4681 {
4682    if (SoXtExaminerViewer::isAnimating())        4682    if (SoXtExaminerViewer::isAnimating())
4683       stopAnimating();                           4683       stopAnimating();
4684                                                  4684 
4685    SbRotation rot;                               4685    SbRotation rot;
4686    SbVec3f p1(0), p2(0), p2_tmp(0), camUpV(0)    4686    SbVec3f p1(0), p2(0), p2_tmp(0), camUpV(0), camD, camD_tmp, leftRightAxis;
4687    float x1(0.), y1(0.), z1(0.), x2(0.), y2(0    4687    float x1(0.), y1(0.), z1(0.), x2(0.), y2(0.), z2(0.);
4688                                                  4688 
4689    if (currentState == ANIMATION) {              4689    if (currentState == ANIMATION) {
4690       p1 = refParticleTrajectory[refParticleI    4690       p1 = refParticleTrajectory[refParticleIdx];
4691       p2 = refParticleTrajectory[++(refPartic    4691       p2 = refParticleTrajectory[++(refParticleIdx)];
4692    } else if (currentState == REVERSED_ANIMAT    4692    } else if (currentState == REVERSED_ANIMATION) {
4693       p2 = refParticleTrajectory[refParticleI    4693       p2 = refParticleTrajectory[refParticleIdx];
4694       p1 = refParticleTrajectory[--(refPartic    4694       p1 = refParticleTrajectory[--(refParticleIdx)];
4695    } else if (currentState == PAUSED_ANIMATIO    4695    } else if (currentState == PAUSED_ANIMATION) {
4696       if (refParticleIdx < (int) refParticleT    4696       if (refParticleIdx < (int) refParticleTrajectory.size()) {
4697          p1 = refParticleTrajectory[refPartic    4697          p1 = refParticleTrajectory[refParticleIdx];
4698          p2 = refParticleTrajectory[refPartic    4698          p2 = refParticleTrajectory[refParticleIdx + 1];
4699       } else {                                   4699       } else {
4700          p1 = refParticleTrajectory[refPartic    4700          p1 = refParticleTrajectory[refParticleIdx - 1];
4701          p2 = refParticleTrajectory[refPartic    4701          p2 = refParticleTrajectory[refParticleIdx];
4702       }                                          4702       }
4703    }                                             4703    }
4704    p1.getValue(x1, y1, z1);                      4704    p1.getValue(x1, y1, z1);
4705    p2.getValue(x2, y2, z2);                      4705    p2.getValue(x2, y2, z2);
4706                                                  4706 
4707    camD = p2 - p1;                               4707    camD = p2 - p1;
4708    camD.normalize();                             4708    camD.normalize();
4709                                                  4709 
4710    p2_tmp.setValue(x2, y1, z2);                  4710    p2_tmp.setValue(x2, y1, z2);
4711    camD_tmp = p2_tmp - p1;                       4711    camD_tmp = p2_tmp - p1;
4712    camD_tmp.normalize();                         4712    camD_tmp.normalize();
4713                                                  4713 
4714    camUpV.setValue(0, 1, 0);                     4714    camUpV.setValue(0, 1, 0);
4715    rot.setValue(camD_tmp, camD);                 4715    rot.setValue(camD_tmp, camD);
4716    rot.multVec(camUpV, camUpV);                  4716    rot.multVec(camUpV, camUpV);
4717                                                  4717 
4718    leftRightAxis = camD.cross(camUpV);           4718    leftRightAxis = camD.cross(camUpV);
4719                                                  4719 
4720    myCam->position = p1;                         4720    myCam->position = p1;
4721    myCam->pointAt(p2, camUpV);                   4721    myCam->pointAt(p2, camUpV);
4722                                                  4722 
4723    // Update camera position                     4723    // Update camera position
4724    p1 = p1 + (up_down * camUpV) + (left_right    4724    p1 = p1 + (up_down * camUpV) + (left_right * leftRightAxis);
4725    myCam->position = p1;                         4725    myCam->position = p1;
4726    // FWJ Try look-ahead here                    4726    // FWJ Try look-ahead here
4727    int idx = refParticleIdx + pathLookahead;     4727    int idx = refParticleIdx + pathLookahead;
4728    idx = std::min(idx, (int)refParticleTrajec    4728    idx = std::min(idx, (int)refParticleTrajectory.size() - 1);
4729    myCam->pointAt(refParticleTrajectory[idx],    4729    myCam->pointAt(refParticleTrajectory[idx], camUpV);
4730    //   myCam->pointAt(refParticleTrajectory[    4730    //   myCam->pointAt(refParticleTrajectory[idx], camUpVec);
4731    myCam->focalDistance = 0.1f;                  4731    myCam->focalDistance = 0.1f;
4732 }                                                4732 }
4733                                                  4733 
4734                                                  4734 
4735 void G4OpenInventorXtExaminerViewer::gotoRefP    4735 void G4OpenInventorXtExaminerViewer::gotoRefPathStart()
4736 {                                                4736 {
4737    G4OpenInventorXtExaminerViewer::gotoRefPat    4737    G4OpenInventorXtExaminerViewer::gotoRefPathStartCB(NULL, (void *)this, 
4738                                                  4738                                                       NULL);
4739 }                                                4739 }
4740                                                  4740 
4741                                                  4741 
4742 void G4OpenInventorXtExaminerViewer::gotoRefP    4742 void G4OpenInventorXtExaminerViewer::gotoRefPathStartCB(Widget, 
4743                                                  4743                                                         XtPointer client_data, 
4744                                                  4744                                                         XtPointer)
4745 {                                                4745 {
4746    G4OpenInventorXtExaminerViewer * This = (G    4746    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4747                                                  4747 
4748    if (!This->refParticleTrajectory.size()) {    4748    if (!This->refParticleTrajectory.size()) {
4749       String dialogName = (char *) "No Refere    4749       String dialogName = (char *) "No Reference Trajectory";
4750       std::string msg = "You need to start a     4750       std::string msg = "You need to start a run or load a reference trajectory from a file";
4751       This->warningMsgDialog(msg, dialogName,    4751       This->warningMsgDialog(msg, dialogName, NULL);
4752       return;                                    4752       return;
4753    }                                             4753    }
4754                                                  4754 
4755    if (This->currentState == ROTATING)           4755    if (This->currentState == ROTATING)
4756       return;                                    4756       return;
4757    if (This->currentState == ANIMATION || Thi    4757    if (This->currentState == ANIMATION || This->currentState == REVERSED_ANIMATION
4758        || This->currentState == PAUSED_ANIMAT    4758        || This->currentState == PAUSED_ANIMATION) {
4759       if (This->animateSensor->isScheduled())    4759       if (This->animateSensor->isScheduled())
4760          This->animateSensor->unschedule();      4760          This->animateSensor->unschedule();
4761       This->setSuperimpositionEnabled(This->s    4761       This->setSuperimpositionEnabled(This->superimposition, FALSE);
4762       This->maxSpeed = 0.0f;                     4762       This->maxSpeed = 0.0f;
4763       This->scheduleRedraw();                    4763       This->scheduleRedraw();
4764    } else {                                      4764    } else {
4765       This->saveCurCamera();                     4765       This->saveCurCamera();
4766       This->prevState = This->currentState;      4766       This->prevState = This->currentState;
4767       This->prevRefIdx = This->refParticleIdx    4767       This->prevRefIdx = This->refParticleIdx;
4768    }                                             4768    }
4769                                                  4769 
4770    if (This->SoXtExaminerViewer::isAnimating(    4770    if (This->SoXtExaminerViewer::isAnimating())
4771       This->stopAnimating();                     4771       This->stopAnimating();
4772                                                  4772 
4773    This->up_down = 0;                            4773    This->up_down = 0;
4774    This->left_right = 0;                         4774    This->left_right = 0;
4775    This->step = 1;                               4775    This->step = 1;
4776                                                  4776 
4777    This->refParticleIdx = 0;                     4777    This->refParticleIdx = 0;
4778    This->currentState = BEAMLINE;                4778    This->currentState = BEAMLINE;
4779    This->setSuperimpositionEnabled(This->supe    4779    This->setSuperimpositionEnabled(This->superimposition, TRUE);
4780    This->axisSwitch->whichChild.setValue(SO_S    4780    This->axisSwitch->whichChild.setValue(SO_SWITCH_NONE);
4781    This->animSpeedOutlineSwitch->whichChild.s    4781    This->animSpeedOutlineSwitch->whichChild.setValue(SO_SWITCH_NONE);
4782    This->animSpeedSwitch->whichChild.setValue    4782    This->animSpeedSwitch->whichChild.setValue(SO_SWITCH_NONE);
4783    This->scheduleRedraw();                       4783    This->scheduleRedraw();
4784                                                  4784 
4785    // FWJ Disabled: this is set in moveCamera    4785    // FWJ Disabled: this is set in moveCamera()
4786    // Zoom in                                    4786    // Zoom in
4787    //   SoCamera *cam = This->getCamera();       4787    //   SoCamera *cam = This->getCamera();
4788    //   cam->focalDistance = 0.1f;               4788    //   cam->focalDistance = 0.1f;
4789                                                  4789 
4790    This->prevParticleDir = SbVec3f(0,0,0);       4790    This->prevParticleDir = SbVec3f(0,0,0);
4791                                                  4791 
4792    //Default zoom                                4792    //Default zoom
4793    SbVec3f p1 = This->refParticleTrajectory[0    4793    SbVec3f p1 = This->refParticleTrajectory[0];
4794    SbVec3f pN = This->refParticleTrajectory[T    4794    SbVec3f pN = This->refParticleTrajectory[This->refParticleTrajectory.size() - 1];
4795    This->distance = (pN - p1).length() / 10;     4795    This->distance = (pN - p1).length() / 10;
4796                                                  4796 
4797    This->moveCamera(This->distance, true);       4797    This->moveCamera(This->distance, true);
4798 }                                                4798 }
4799                                                  4799 
4800                                                  4800 
4801 void G4OpenInventorXtExaminerViewer::invertRe    4801 void G4OpenInventorXtExaminerViewer::invertRefPathCB(Widget,
4802                                                  4802                                                      XtPointer client_data,
4803                                                  4803                                                      XtPointer)
4804 {                                                4804 {
4805    G4OpenInventorXtExaminerViewer * This =       4805    G4OpenInventorXtExaminerViewer * This =
4806       (G4OpenInventorXtExaminerViewer *) clie    4806       (G4OpenInventorXtExaminerViewer *) client_data;
4807    This->invertRefPath();                        4807    This->invertRefPath();
4808 }                                                4808 }
4809                                                  4809 
4810                                                  4810 
4811 void G4OpenInventorXtExaminerViewer::invertRe    4811 void G4OpenInventorXtExaminerViewer::invertRefPath()
4812 {                                                4812 {
4813    std::reverse(this->refParticleTrajectory.b    4813    std::reverse(this->refParticleTrajectory.begin(),
4814                 this->refParticleTrajectory.e    4814                 this->refParticleTrajectory.end());
4815    this->setReferencePathZPos();                 4815    this->setReferencePathZPos();
4816    this->sortElements();                         4816    this->sortElements();
4817 }                                                4817 }
4818                                                  4818 
4819                                                  4819 
4820 void G4OpenInventorXtExaminerViewer::animateR    4820 void G4OpenInventorXtExaminerViewer::animateRefParticleCB(Widget, 
4821                                            Xt    4821                                            XtPointer client_data,
4822                                            Xt    4822                                            XtPointer)
4823 {                                                4823 {
4824    G4OpenInventorXtExaminerViewer * This = (G    4824    G4OpenInventorXtExaminerViewer * This = (G4OpenInventorXtExaminerViewer *) client_data;
4825                                                  4825 
4826    if (!This->refParticleTrajectory.size()) {    4826    if (!This->refParticleTrajectory.size()) {
4827       This->returnToAnim = true;                 4827       This->returnToAnim = true;
4828       String dialogName = (char *) "No Refere    4828       String dialogName = (char *) "No Reference Trajectory";
4829       std::string msg = "You need to start a     4829       std::string msg = "You need to start a run or load a reference trajectory from a file";
4830       This->warningMsgDialog(msg, dialogName,    4830       This->warningMsgDialog(msg, dialogName, NULL);
4831       return;                                    4831       return;
4832    }                                             4832    }
4833                                                  4833 
4834    if (!This->refParticleTrajectory.size())      4834    if (!This->refParticleTrajectory.size())
4835       return;                                    4835       return;
4836                                                  4836 
4837    //////////////////////////////////////////    4837    ///////////////////////////////////////////////////////////////
4838    This->setSuperimpositionEnabled(This->supe    4838    This->setSuperimpositionEnabled(This->superimposition, TRUE);
4839    This->maxSpeed = SPEED_INDICATOR_STEP;        4839    This->maxSpeed = SPEED_INDICATOR_STEP;
4840    This->axisSwitch->whichChild.setValue(SO_S    4840    This->axisSwitch->whichChild.setValue(SO_SWITCH_ALL);
4841    This->animSpeedOutlineSwitch->whichChild.s    4841    This->animSpeedOutlineSwitch->whichChild.setValue(SO_SWITCH_ALL);
4842    This->animSpeedSwitch->whichChild.setValue    4842    This->animSpeedSwitch->whichChild.setValue(SO_SWITCH_ALL);
4843    This->scheduleRedraw();                       4843    This->scheduleRedraw();
4844    //////////////////////////////////////////    4844    ///////////////////////////////////////////////////////////////
4845                                                  4845 
4846    SoCamera *cam = This->getCamera();            4846    SoCamera *cam = This->getCamera();
4847    //   SbVec3f camDirOld, camDirNew, camDirN    4847    //   SbVec3f camDirOld, camDirNew, camDirNew_tmp, camUpVec, P0, P1, P1_tmp;
4848                                                  4848 
4849    if (This->currentState == ANIMATION || Thi    4849    if (This->currentState == ANIMATION || This->currentState == REVERSED_ANIMATION
4850        || This->currentState == ROTATING)        4850        || This->currentState == ROTATING)
4851       return;                                    4851       return;
4852                                                  4852 
4853    if (This->currentState != PAUSED_ANIMATION    4853    if (This->currentState != PAUSED_ANIMATION) {
4854                                                  4854 
4855       This->saveCurCamera();                     4855       This->saveCurCamera();
4856       This->prevState = This->currentState;      4856       This->prevState = This->currentState;
4857       This->prevRefIdx = This->refParticleIdx    4857       This->prevRefIdx = This->refParticleIdx;
4858                                                  4858 
4859       if (cam->isOfType(SoOrthographicCamera:    4859       if (cam->isOfType(SoOrthographicCamera::getClassTypeId())) {
4860          This->toggleCameraType();               4860          This->toggleCameraType();
4861          cam = This->getCamera();                4861          cam = This->getCamera();
4862       }                                          4862       }
4863                                                  4863 
4864       This->refParticleIdx = 0; // Set the ca    4864       This->refParticleIdx = 0; // Set the camera to the starting point of the animation
4865       This->animateBtwPtsPeriod = MIN_SPEED;     4865       This->animateBtwPtsPeriod = MIN_SPEED;
4866       This->speedStep = START_STEP;              4866       This->speedStep = START_STEP;
4867       This->left_right = This->up_down = 0;      4867       This->left_right = This->up_down = 0;
4868                                                  4868 
4869       cam->focalDistance = 0.1f;                 4869       cam->focalDistance = 0.1f;
4870       ((SoPerspectiveCamera *) cam)->heightAn    4870       ((SoPerspectiveCamera *) cam)->heightAngle = 0.50f;
4871    }                                             4871    }
4872                                                  4872 
4873    This->currentState = ANIMATION;               4873    This->currentState = ANIMATION;
4874    This->setStartingPtForAnimation();            4874    This->setStartingPtForAnimation();
4875                                                  4875 
4876    cam->position = (This->myCam)->position.ge    4876    cam->position = (This->myCam)->position.getValue();
4877    cam->orientation = (This->myCam)->orientat    4877    cam->orientation = (This->myCam)->orientation.getValue();
4878    This->animateRefParticle(); // Animate the    4878    This->animateRefParticle(); // Animate the camera
4879 }                                                4879 }
4880                                                  4880 
4881                                                  4881 
4882 void G4OpenInventorXtExaminerViewer::animateR    4882 void G4OpenInventorXtExaminerViewer::animateRefParticle()
4883 {                                                4883 {
4884    SoCamera *cam = getCamera();                  4884    SoCamera *cam = getCamera();
4885                                                  4885 
4886    camStartPos = cam->position.getValue();       4886    camStartPos = cam->position.getValue();
4887    camStartOrient = cam->orientation.getValue    4887    camStartOrient = cam->orientation.getValue();
4888                                                  4888 
4889    if (currentState != BEAMLINE)                 4889    if (currentState != BEAMLINE)
4890       setStartingPtForAnimation();               4890       setStartingPtForAnimation();
4891                                                  4891 
4892    camEndPos = myCam->position.getValue();       4892    camEndPos = myCam->position.getValue();
4893    camEndOrient = myCam->orientation.getValue    4893    camEndOrient = myCam->orientation.getValue();
4894                                                  4894 
4895    if (animateSensor->isScheduled())             4895    if (animateSensor->isScheduled())
4896       animateSensor->unschedule();               4896       animateSensor->unschedule();
4897                                                  4897 
4898    animateSensor->setBaseTime(SbTime::getTime    4898    animateSensor->setBaseTime(SbTime::getTimeOfDay());
4899    animateSensor->setInterval(SbTime(0.02));     4899    animateSensor->setInterval(SbTime(0.02));
4900                                                  4900 
4901    animateSensor->schedule();                    4901    animateSensor->schedule();
4902 }                                                4902 }
4903                                                  4903 
4904                                                  4904 
4905 void G4OpenInventorXtExaminerViewer::addEscap    4905 void G4OpenInventorXtExaminerViewer::addEscapeCallback(
4906                          void (*callback)(voi    4906                          void (*callback)(void *), void * object)
4907 {                                                4907 {
4908    this->escapeCallback = callback;              4908    this->escapeCallback = callback;
4909    this->examinerObject = object;                4909    this->examinerObject = object;
4910 }                                                4910 }
4911                                                  4911 
4912                                                  4912 
4913 void G4OpenInventorXtExaminerViewer::sceneCha    4913 void G4OpenInventorXtExaminerViewer::sceneChangeCB(void *userData, SoSensor *)
4914 {                                                4914 {
4915    G4OpenInventorXtExaminerViewer* This =        4915    G4OpenInventorXtExaminerViewer* This =
4916       (G4OpenInventorXtExaminerViewer*)userDa    4916       (G4OpenInventorXtExaminerViewer*)userData;
4917    if(This->newEvents){                          4917    if(This->newEvents){
4918       This->findAndSetRefPath();                 4918       This->findAndSetRefPath();
4919       This->newEvents = false;                   4919       This->newEvents = false;
4920    }                                             4920    }
4921 }                                                4921 }
4922                                                  4922 
4923                                                  4923 
4924 HookEventProcState::HookEventProcState(G4Open    4924 HookEventProcState::HookEventProcState(G4OpenInventorXtExaminerViewer* vwr)
4925 {                                                4925 {
4926    this->viewer = vwr;                           4926    this->viewer = vwr;
4927 }                                                4927 }
4928                                                  4928 
4929                                                  4929 
4930 HookEventProcState::~HookEventProcState()        4930 HookEventProcState::~HookEventProcState()
4931 {;}                                              4931 {;}
4932                                                  4932 
4933                                                  4933 
4934 G4bool HookEventProcState::Notify(G4Applicati    4934 G4bool HookEventProcState::Notify(G4ApplicationState requiredState)
4935 {                                                4935 {
4936    if(requiredState == G4State_EventProc){       4936    if(requiredState == G4State_EventProc){
4937       this->viewer->newEvents = true;            4937       this->viewer->newEvents = true;
4938    }                                             4938    }
4939    return true;                                  4939    return true;
4940 }                                                4940 }
4941                                                  4941