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 9.6.p4)


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