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 10.3.p2)


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