Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/ToolsSG/include/private/G4ToolsSGViewer.hh

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/ToolsSG/include/private/G4ToolsSGViewer.hh (Version 11.3.0) and /visualization/ToolsSG/include/private/G4ToolsSGViewer.hh (Version 11.2.2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // John Allison  6th October 2019                  26 // John Allison  6th October 2019
 27                                                    27 
 28 #ifndef G4TOOLSSGVIEWER_HH                         28 #ifndef G4TOOLSSGVIEWER_HH
 29 #define G4TOOLSSGVIEWER_HH                         29 #define G4TOOLSSGVIEWER_HH
 30                                                    30 
 31 #include "G4VViewer.hh"                            31 #include "G4VViewer.hh"
 32                                                    32 
 33 #include "G4ToolsSGSceneHandler.hh"                33 #include "G4ToolsSGSceneHandler.hh"
 34 #include "G4Scene.hh"                              34 #include "G4Scene.hh"
 35 #include "G4VVisCommand.hh"                        35 #include "G4VVisCommand.hh"
 36                                                    36 
 37 #include <tools/fpng>                              37 #include <tools/fpng>
 38 #include <tools/toojpeg>                           38 #include <tools/toojpeg>
 39                                                    39 
 40 #include <tools/sg/device_interactor>              40 #include <tools/sg/device_interactor>
 41 #include <tools/sg/separator>                      41 #include <tools/sg/separator>
 42 #include <tools/sg/ortho>                          42 #include <tools/sg/ortho>
 43 #include <tools/sg/perspective>                    43 #include <tools/sg/perspective>
 44 #include <tools/sg/torche>                         44 #include <tools/sg/torche>
 45 #include <tools/sg/blend>                          45 #include <tools/sg/blend>
 46 #include <tools/sg/noderef>                        46 #include <tools/sg/noderef>
 47 #include <tools/sg/keys>                           47 #include <tools/sg/keys>
 48                                                    48 
 49 #include <tools/tokenize>                          49 #include <tools/tokenize>
 50 #include <tools/sg/write_paper>                    50 #include <tools/sg/write_paper>
 51                                                    51 
 52 template <class SG_SESSION,class SG_VIEWER>        52 template <class SG_SESSION,class SG_VIEWER>
 53 class G4ToolsSGViewer : public G4VViewer, tool     53 class G4ToolsSGViewer : public G4VViewer, tools::sg::device_interactor {
 54   typedef G4VViewer parent;                        54   typedef G4VViewer parent;
 55   typedef tools::sg::device_interactor parent_     55   typedef tools::sg::device_interactor parent_interactor;
 56 public: //tools::sg::device_interactor interfa     56 public: //tools::sg::device_interactor interface.
 57   virtual void key_press(const tools::sg::key_     57   virtual void key_press(const tools::sg::key_down_event& a_event) {
 58     fKeyPressed = true;                            58     fKeyPressed = true;
 59     fKeyShift = a_event.key() == tools::sg::ke     59     fKeyShift = a_event.key() == tools::sg::key_shift()?true:false;
 60   }                                                60   }
 61   virtual void key_release(const tools::sg::ke     61   virtual void key_release(const tools::sg::key_up_event&) {fKeyPressed = false;}
 62   virtual void mouse_press(const tools::sg::mo     62   virtual void mouse_press(const tools::sg::mouse_down_event& a_event) {
 63     fMousePressed = true;                          63     fMousePressed = true;
 64     fMousePressedX = a_event.x();                  64     fMousePressedX = a_event.x();
 65     fMousePressedY = a_event.y();                  65     fMousePressedY = a_event.y();
 66   }                                                66   }
 67   virtual void mouse_release(const tools::sg::     67   virtual void mouse_release(const tools::sg::mouse_up_event&) {fMousePressed = false;}    
 68   virtual void mouse_move(const tools::sg::mou     68   virtual void mouse_move(const tools::sg::mouse_move_event& a_event) {
 69     G4double x = a_event.x();                      69     G4double x = a_event.x();
 70     G4double y = a_event.y();                      70     G4double y = a_event.y();
 71     G4double dx = x-fMousePressedX;                71     G4double dx = x-fMousePressedX;
 72     G4double dy = y-fMousePressedY;                72     G4double dy = y-fMousePressedY;
 73     fMousePressedX = x;                            73     fMousePressedX = x;
 74     fMousePressedY = y;                            74     fMousePressedY = y;
 75                                                    75 
 76     if (fMousePressed) {                           76     if (fMousePressed) {
 77                                                    77 
 78       if (fKeyPressed && fKeyShift) {  // Tran     78       if (fKeyPressed && fKeyShift) {  // Translation (pan)
 79                                                    79 
 80         const G4double sceneRadius = fSGSceneH     80         const G4double sceneRadius = fSGSceneHandler.GetScene()->GetExtent().GetExtentRadius();
 81         const G4double scale = 300;  // Roughl     81         const G4double scale = 300;  // Roughly pixels per window, empirically chosen
 82         const G4double dxScene = dx*sceneRadiu     82         const G4double dxScene = dx*sceneRadius/scale;
 83         const G4double dyScene = dy*sceneRadiu     83         const G4double dyScene = dy*sceneRadius/scale;
 84         fVP.IncrementPan(-dxScene,dyScene);        84         fVP.IncrementPan(-dxScene,dyScene);
 85                                                    85 
 86       } else {  // Rotation                        86       } else {  // Rotation
 87                                                    87 
 88         // Simple ad-hoc algorithms                88         // Simple ad-hoc algorithms
 89         const G4Vector3D& x_prime = fVP.GetVie     89         const G4Vector3D& x_prime = fVP.GetViewpointDirection().cross(fVP.GetUpVector());
 90         const G4Vector3D& y_prime = x_prime.cr     90         const G4Vector3D& y_prime = x_prime.cross(fVP.GetViewpointDirection());
 91         const G4double scale = 200;  // Roughl     91         const G4double scale = 200;  // Roughly pixels per window, empirically chosen
 92         G4Vector3D newViewpointDirection = fVP     92         G4Vector3D newViewpointDirection = fVP.GetViewpointDirection();
 93         newViewpointDirection += dx*x_prime/sc     93         newViewpointDirection += dx*x_prime/scale;
 94         newViewpointDirection += dy*y_prime/sc     94         newViewpointDirection += dy*y_prime/scale;
 95         fVP.SetViewpointDirection(newViewpoint     95         fVP.SetViewpointDirection(newViewpointDirection.unit());
 96                                                    96 
 97         if (fVP.GetRotationStyle() == G4ViewPa     97         if (fVP.GetRotationStyle() == G4ViewParameters::freeRotation) {
 98           G4Vector3D newUpVector = fVP.GetUpVe     98           G4Vector3D newUpVector = fVP.GetUpVector();
 99           newUpVector += dx*x_prime/scale;         99           newUpVector += dx*x_prime/scale;
100           newUpVector += dy*y_prime/scale;        100           newUpVector += dy*y_prime/scale;
101           fVP.SetUpVector(newUpVector.unit());    101           fVP.SetUpVector(newUpVector.unit());
102         }                                         102         }
103       }                                           103       }
104     }                                             104     }
105                                                   105 
106     SetView();                                    106     SetView();
107     DrawView();                                   107     DrawView();
108   }                                               108   }
109   virtual void wheel_rotate(const tools::sg::w    109   virtual void wheel_rotate(const tools::sg::wheel_rotate_event& a_event) {
110     const G4double angleY = a_event.angle();      110     const G4double angleY = a_event.angle();
111     if (fVP.GetFieldHalfAngle() == 0.) {  // O    111     if (fVP.GetFieldHalfAngle() == 0.) {  // Orthographic projection
112       const G4double scale = 500;  // Empirica    112       const G4double scale = 500;  // Empirically chosen
113       fVP.MultiplyZoomFactor(1.+angleY/scale);    113       fVP.MultiplyZoomFactor(1.+angleY/scale);
114     } else {                              // P    114     } else {                              // Perspective projection
115       const G4double delta = fSceneHandler.Get    115       const G4double delta = fSceneHandler.GetExtent().GetExtentRadius()/200.;  // Empirical
116       fVP.SetDolly(fVP.GetDolly()+angleY*delta    116       fVP.SetDolly(fVP.GetDolly()+angleY*delta);
117     }                                             117     }
118     SetView();                                    118     SetView();
119     DrawView();                                   119     DrawView();
120   }                                               120   }
121 public:                                           121 public:
122   G4ToolsSGViewer(SG_SESSION& a_session,G4Tool    122   G4ToolsSGViewer(SG_SESSION& a_session,G4ToolsSGSceneHandler& a_scene_handler, const G4String& a_name)
123   :parent(a_scene_handler,a_scene_handler.Incr    123   :parent(a_scene_handler,a_scene_handler.IncrementViewCount(),a_name)
124   ,fSGSession(a_session)                          124   ,fSGSession(a_session)
125   ,fSGSceneHandler(a_scene_handler)               125   ,fSGSceneHandler(a_scene_handler)
126   ,fSGViewer(nullptr)                             126   ,fSGViewer(nullptr)
127   ,fKeyPressed(false)                             127   ,fKeyPressed(false)
128   ,fKeyShift(false)                               128   ,fKeyShift(false)
129   ,fMousePressed(false)                           129   ,fMousePressed(false)
130   ,fMousePressedX(0)                              130   ,fMousePressedX(0)
131   ,fMousePressedY(0)                              131   ,fMousePressedY(0)
132   {                                               132   {
133     //::printf("debug : G4ToolsSGViewer::G4Too    133     //::printf("debug : G4ToolsSGViewer::G4ToolsSGViewer: %lu, %s\n",this,a_name.c_str());
134     Messenger::Create();                          134     Messenger::Create();
135   }                                               135   }
136                                                   136 
137   virtual ~G4ToolsSGViewer() {                    137   virtual ~G4ToolsSGViewer() {
138     //::printf("debug : G4ToolsSGViewer::~G4To    138     //::printf("debug : G4ToolsSGViewer::~G4ToolsSGViewer: %lu\n",this);
139     //WARNING : nodes may refer f_gl2ps_mgr, f    139     //WARNING : nodes may refer f_gl2ps_mgr, f_zb_mgr (to handle gstos (for GPU) or textures), then
140     //          we have to delete them first.     140     //          we have to delete them first.
141     fSGViewer->sg().clear();                      141     fSGViewer->sg().clear();
142     delete fSGViewer;                             142     delete fSGViewer;
143   }                                               143   }
144 protected:                                        144 protected:
145   G4ToolsSGViewer(const G4ToolsSGViewer& a_fro    145   G4ToolsSGViewer(const G4ToolsSGViewer& a_from)
146   :parent(a_from)                                 146   :parent(a_from)
147   ,parent_interactor(a_from)                      147   ,parent_interactor(a_from)
148   ,fSGSession(a_from.fSGSession)                  148   ,fSGSession(a_from.fSGSession)
149   ,fSGSceneHandler(a_from.fSGSceneHandler)        149   ,fSGSceneHandler(a_from.fSGSceneHandler)
150   ,fSGViewer(nullptr)                             150   ,fSGViewer(nullptr)
151   ,fKeyPressed(false)                             151   ,fKeyPressed(false)
152   ,fKeyShift(false)                               152   ,fKeyShift(false)
153   ,fMousePressed(false)                           153   ,fMousePressed(false)
154   ,fMousePressedX(0)                              154   ,fMousePressedX(0)
155   ,fMousePressedY(0)                              155   ,fMousePressedY(0)
156   {}                                              156   {}
157   G4ToolsSGViewer& operator=(const G4ToolsSGVi    157   G4ToolsSGViewer& operator=(const G4ToolsSGViewer&) {return *this;}
158 public:                                           158 public:  
159   virtual void Initialise() {                     159   virtual void Initialise() {
160     if(fSGViewer) return; //done.                 160     if(fSGViewer) return; //done.
161     fVP.SetAutoRefresh(true);                     161     fVP.SetAutoRefresh(true);
162     fDefaultVP.SetAutoRefresh(true);              162     fDefaultVP.SetAutoRefresh(true);
163     //::printf("debug : G4ToolsSGViewer::Initi    163     //::printf("debug : G4ToolsSGViewer::Initialise\n");
164     //////////////////////////////////////////    164     //////////////////////////////////////////////////////////
165     /// create the viewer, set the scene graph    165     /// create the viewer, set the scene graph ///////////////
166     //////////////////////////////////////////    166     //////////////////////////////////////////////////////////
167     fSGViewer = new SG_VIEWER(fSGSession          167     fSGViewer = new SG_VIEWER(fSGSession
168       ,fVP.GetWindowAbsoluteLocationHintX(1440    168       ,fVP.GetWindowAbsoluteLocationHintX(1440)
169       ,fVP.GetWindowAbsoluteLocationHintY(900)    169       ,fVP.GetWindowAbsoluteLocationHintY(900)
170       ,fVP.GetWindowSizeHintX()                   170       ,fVP.GetWindowSizeHintX()
171       ,fVP.GetWindowSizeHintY()                   171       ,fVP.GetWindowSizeHintY()
172       ,fName);                                    172       ,fName);
173     if(!fSGViewer->has_window()) {                173     if(!fSGViewer->has_window()) {
174       fViewId = -1;  // This flags an error.      174       fViewId = -1;  // This flags an error.
175       G4cerr << "G4ToolsSGViewer::Initialise :    175       G4cerr << "G4ToolsSGViewer::Initialise : SG_VIEWER::has_window() failed." << G4endl;
176       return;                                     176       return;
177     }                                             177     }
178     fSGViewer->set_device_interactor(this);       178     fSGViewer->set_device_interactor(this);
179   }                                               179   }
180                                                   180   
181   virtual void SetView() {                        181   virtual void SetView() {
182     //::printf("debug : G4ToolsSGViewer::SetVi    182     //::printf("debug : G4ToolsSGViewer::SetView\n");
183     if(!fSceneHandler.GetScene()) {               183     if(!fSceneHandler.GetScene()) {
184       fSGViewer->set_clear_color(0.3,0.3,0.3,1    184       fSGViewer->set_clear_color(0.3,0.3,0.3,1); //some grey color to signal the user that something is wrong.
185       G4cerr << "G4ToolsSGViewer::SetView : no    185       G4cerr << "G4ToolsSGViewer::SetView : no G4Scene.." << G4endl;
186       return;                                     186       return;
187     }                                             187     }
188                                                   188 
189     //////////////////////////////////////////    189     //////////////////////////////////////////////////////////
190     //////////////////////////////////////////    190     //////////////////////////////////////////////////////////
191     //////////////////////////////////////////    191     //////////////////////////////////////////////////////////
192     // Get radius of scene, etc.                  192     // Get radius of scene, etc.
193     // Note that this procedure properly takes    193     // Note that this procedure properly takes into account zoom, dolly and pan.
194     const G4Point3D targetPoint                   194     const G4Point3D targetPoint
195       = fSceneHandler.GetScene()->GetStandardT    195       = fSceneHandler.GetScene()->GetStandardTargetPoint() + fVP.GetCurrentTargetPoint ();
196     G4double radius = fSceneHandler.GetScene()    196     G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
197     if(radius<=0.) radius = 1.;                   197     if(radius<=0.) radius = 1.;
198     const G4double cameraDistance = fVP.GetCam    198     const G4double cameraDistance = fVP.GetCameraDistance (radius);
199     const G4Point3D cameraPosition = targetPoi    199     const G4Point3D cameraPosition = targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
200     const G4Normal3D& up = fVP.GetUpVector ();    200     const G4Normal3D& up = fVP.GetUpVector ();  
201     const G4double pnear  = fVP.GetNearDistanc    201     const G4double pnear  = fVP.GetNearDistance (cameraDistance, radius);
202     const G4double pfar   = fVP.GetFarDistance    202     const G4double pfar   = fVP.GetFarDistance  (cameraDistance, pnear, radius);
203   //const G4double right  = fVP.GetFrontHalfHe    203   //const G4double right  = fVP.GetFrontHalfHeight (pnear, radius);
204   //const G4double left   = -right;               204   //const G4double left   = -right;
205     const G4double top    = fVP.GetFrontHalfHe    205     const G4double top    = fVP.GetFrontHalfHeight (pnear, radius);
206     const G4double bottom = -top;                 206     const G4double bottom = -top;
207     // sanity check :                             207     // sanity check :
208     tools::vec3f dir(float(targetPoint.x()-cam    208     tools::vec3f dir(float(targetPoint.x()-cameraPosition.x()),
209                      float(targetPoint.y()-cam    209                      float(targetPoint.y()-cameraPosition.y()),
210                      float(targetPoint.z()-cam    210                      float(targetPoint.z()-cameraPosition.z()));
211     if(!dir.length()) {                           211     if(!dir.length()) {
212       fSGViewer->set_clear_color(0.3,0.3,0.3,1    212       fSGViewer->set_clear_color(0.3,0.3,0.3,1);
213       G4cerr << "G4ToolsSGViewer::SetView : nu    213       G4cerr << "G4ToolsSGViewer::SetView : null size viewer area." << G4endl;
214       return;                                     214       return;      
215     }                                             215     }
216                                                   216     
217     //////////////////////////////////////////    217     //////////////////////////////////////////////////////////
218     //////////////////////////////////////////    218     //////////////////////////////////////////////////////////
219     //////////////////////////////////////////    219     //////////////////////////////////////////////////////////
220     /*                                            220     /*
221     G4cout << "debug : 0002 : radius " << radi    221     G4cout << "debug : 0002 : radius " << radius << std::endl;
222     G4cout << "debug : cameraDistance : " << c    222     G4cout << "debug : cameraDistance : " << cameraDistance << std::endl;
223     G4cout << "debug : fieldHalfAngle : " << f    223     G4cout << "debug : fieldHalfAngle : " << fVP.GetFieldHalfAngle() << std::endl;
224     G4cout << "debug : zoomFactor : " << fVP.G    224     G4cout << "debug : zoomFactor : " << fVP.GetZoomFactor() << std::endl;
225     G4cout << "debug : up : " << up.x() << " "    225     G4cout << "debug : up : " << up.x() << " " << up.y() << " " << up.z() << std::endl;
226     G4cout << "debug : targetPoint : " << targ    226     G4cout << "debug : targetPoint : " << targetPoint.x() << " " << targetPoint.y() << " " << targetPoint.z() << std::endl;
227     G4cout << "debug : cameraPosition : " << c    227     G4cout << "debug : cameraPosition : " << cameraPosition.x() << " " << cameraPosition.y() << " " << cameraPosition.z() << std::endl;
228     G4cout << "debug : camera : znear " << pne    228     G4cout << "debug : camera : znear " << pnear << ", zfar " << pfar << std::endl;
229     */                                            229     */
230     //////////////////////////////////////////    230     //////////////////////////////////////////////////////////
231     /// create scene graph ///////////////////    231     /// create scene graph ///////////////////////////////////
232     //////////////////////////////////////////    232     //////////////////////////////////////////////////////////
233     // Set projection, then create the tools::    233     // Set projection, then create the tools::sg camera node :
234     tools::sg::base_camera* _camera = nullptr;    234     tools::sg::base_camera* _camera = nullptr;
235     if (fVP.GetFieldHalfAngle() <= 0.) {          235     if (fVP.GetFieldHalfAngle() <= 0.) {
236       //G4cout << "debug : camera : ortho : to    236       //G4cout << "debug : camera : ortho : top " << top << " bottom " << bottom << " top-bottom " << top-bottom << std::endl;
237       if((top-bottom)<=0) {                       237       if((top-bottom)<=0) {
238         fSGViewer->set_clear_color(0.3,0.3,0.3    238         fSGViewer->set_clear_color(0.3,0.3,0.3,1);
239         G4cerr << "G4ToolsSGViewer::SetView :     239         G4cerr << "G4ToolsSGViewer::SetView : for ortho camera, (top-bottom)<=0." << G4endl;
240         return;                                   240         return;
241       }                                           241       }
242       tools::sg::ortho* ortho_camera = new too    242       tools::sg::ortho* ortho_camera = new tools::sg::ortho;
243       ortho_camera->height.value(float(top-bot    243       ortho_camera->height.value(float(top-bottom));
244       _camera = ortho_camera;                     244       _camera = ortho_camera;
245     } else {                                      245     } else {
246       //G4cout << "debug : camera : perspec :     246       //G4cout << "debug : camera : perspec : heightAngle " << float(2*fVP.GetFieldHalfAngle()) << std::endl;
247       tools::sg::perspective* perspective_came    247       tools::sg::perspective* perspective_camera = new tools::sg::perspective;
248       perspective_camera->height_angle.value(f    248       perspective_camera->height_angle.value(float(2*fVP.GetFieldHalfAngle()));
249       _camera = perspective_camera;               249       _camera = perspective_camera;
250     }                                             250     }
251                                                   251     
252     _camera->position.value                       252     _camera->position.value
253       (tools::vec3f(float(cameraPosition.x()),    253       (tools::vec3f(float(cameraPosition.x()),
254         float(cameraPosition.y()),                254         float(cameraPosition.y()),
255         float(cameraPosition.z())));              255         float(cameraPosition.z())));
256     _camera->znear.value(float(pnear));           256     _camera->znear.value(float(pnear));
257     _camera->zfar.value(float(pfar));             257     _camera->zfar.value(float(pfar));
258                                                   258 
259     _camera->look_at(dir,tools::vec3f(up.x(),u    259     _camera->look_at(dir,tools::vec3f(up.x(),up.y(),up.z()));  //same logic as in G4OpenInventorViewer.
260                                                   260 
261     /*                                            261     /*
262     const G4Vector3D& lightDirection = fVP.Get    262     const G4Vector3D& lightDirection = fVP.GetLightpointDirection();
263     G4cout << "debug : lightDirection : " << l    263     G4cout << "debug : lightDirection : " << lightDirection.x() << " " << lightDirection.y() << " " << lightDirection.z() << std::endl;
264     const G4Vector3D& actualLightDirection = f    264     const G4Vector3D& actualLightDirection = fVP.GetActualLightpointDirection();
265     G4cout << "debug : actualLightDirection :     265     G4cout << "debug : actualLightDirection : " << actualLightDirection.x() << " " << actualLightDirection.y() << " " << actualLightDirection.z() << std::endl;
266     */                                            266     */
267                                                   267 
268     CreateSG(_camera,fVP.GetActualLightpointDi    268     CreateSG(_camera,fVP.GetActualLightpointDirection());
269                                                   269     
270    {G4Color background = fVP.GetBackgroundColo    270    {G4Color background = fVP.GetBackgroundColour ();
271     fSGViewer->set_clear_color(float(backgroun    271     fSGViewer->set_clear_color(float(background.GetRed()),float(background.GetGreen()),float(background.GetBlue()),1);}
272   }                                               272   }
273                                                   273 
274   virtual void ClearView() {}                     274   virtual void ClearView() {}
275                                                   275 
276   virtual void DrawView() {                       276   virtual void DrawView() {
277     if (!fNeedKernelVisit) KernelVisitDecision    277     if (!fNeedKernelVisit) KernelVisitDecision();
278     G4bool kernelVisitWasNeeded = fNeedKernelV    278     G4bool kernelVisitWasNeeded = fNeedKernelVisit; // Keep (ProcessView resets).
279     fLastVP = fVP;                                279     fLastVP = fVP;
280     ProcessView();  // Clears store and proces    280     ProcessView();  // Clears store and processes scene only if necessary.
281     if (kernelVisitWasNeeded) {                   281     if (kernelVisitWasNeeded) {
282       // We might need to do something if the     282       // We might need to do something if the kernel was visited.
283     } else {                                      283     } else {
284     }                                             284     }
285     FinishView ();       // Flush streams and/    285     FinishView ();       // Flush streams and/or swap buffers.
286   }                                               286   }
287                                                   287 
288   virtual void ShowView() {FinishView();}         288   virtual void ShowView() {FinishView();}
289                                                   289 
290   virtual void FinishView() {                     290   virtual void FinishView() {
291     if(fSGViewer) {                               291     if(fSGViewer) {
292       fSGSceneHandler.TouchPlotters(fSGViewer-    292       fSGSceneHandler.TouchPlotters(fSGViewer->sg());
293       fSGViewer->show();                          293       fSGViewer->show();
294       fSGViewer->win_render();                    294       fSGViewer->win_render();
295       fSGSession.sync();                          295       fSGSession.sync();
296     }                                             296     }
297   }                                               297   }
298                                                   298 
                                                   >> 299 #ifdef G4MULTITHREADED
299   virtual void SwitchToVisSubThread() {}          300   virtual void SwitchToVisSubThread() {}
300                                                   301   
301   virtual void SwitchToMasterThread() {           302   virtual void SwitchToMasterThread() {
302     if (G4Threading::IsMultithreadedApplicatio    303     if (G4Threading::IsMultithreadedApplication()) {
303       // I have not figured out how to draw du    304       // I have not figured out how to draw during a run.
304       //                                          305       //
305       // Setting fNeedKernelVisit=true causes     306       // Setting fNeedKernelVisit=true causes scene deletion and a complete rebuild,
306       // including trajectories, hits, etc. fr    307       // including trajectories, hits, etc. from kept events.
307       //                                          308       //
308       // Clearly this is a limitation because     309       // Clearly this is a limitation because even if you run 1000 events you only
309       // get those kept (default 100), and eve    310       // get those kept (default 100), and even worse, if end-if-event-action is
310       // "refresh", you only get one event (th    311       // "refresh", you only get one event (the last I think).
311       //                                          312       //
312       // Also, strictly, there is no need to r    313       // Also, strictly, there is no need to rebuid run-duration models (detector),
313       // but a complete rebuild is the easiest    314       // but a complete rebuild is the easiest way (already imeplemented).
314       //                                          315       //
315       // Only do this if there are end-of-even    316       // Only do this if there are end-of-event models (e.g., trajectories) that
316       // may require it.                          317       // may require it.
317       if (fSceneHandler.GetScene() && fSceneHa    318       if (fSceneHandler.GetScene() && fSceneHandler.GetScene()->GetEndOfEventModelList().size()) {
318         fNeedKernelVisit = true;                  319         fNeedKernelVisit = true;
319         DrawView();  // Draw trajectories, etc    320         DrawView();  // Draw trajectories, etc., from kept events
320       }                                           321       }
321     }                                             322     }
322   }                                               323   }
                                                   >> 324 #endif
323                                                   325   
324   //SG_VIEWER* sg_viewer() {return fSGViewer;}    326   //SG_VIEWER* sg_viewer() {return fSGViewer;}
325 protected:                                        327 protected:
326   void KernelVisitDecision () {                   328   void KernelVisitDecision () {
327     if (CompareForKernelVisit(fLastVP)) {         329     if (CompareForKernelVisit(fLastVP)) {
328       NeedKernelVisit ();  // Sets fNeedKernel    330       NeedKernelVisit ();  // Sets fNeedKernelVisit.
329     }                                             331     }
330   }                                               332   }
331                                                   333   
332   G4bool CompareForKernelVisit(G4ViewParameter    334   G4bool CompareForKernelVisit(G4ViewParameters& vp) {
333     // Typical comparison.  Taken from OpenInv    335     // Typical comparison.  Taken from OpenInventor.
334     if (                                          336     if (
335        (vp.GetDrawingStyle ()    != fVP.GetDra    337        (vp.GetDrawingStyle ()    != fVP.GetDrawingStyle ())    ||
336        (vp.GetNumberOfCloudPoints()  != fVP.Ge    338        (vp.GetNumberOfCloudPoints()  != fVP.GetNumberOfCloudPoints())  ||
337        (vp.IsAuxEdgeVisible ()   != fVP.IsAuxE    339        (vp.IsAuxEdgeVisible ()   != fVP.IsAuxEdgeVisible ())   ||
338        (vp.IsCulling ()          != fVP.IsCull    340        (vp.IsCulling ()          != fVP.IsCulling ())          ||
339        (vp.IsCullingInvisible () != fVP.IsCull    341        (vp.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
340        (vp.IsDensityCulling ()   != fVP.IsDens    342        (vp.IsDensityCulling ()   != fVP.IsDensityCulling ())   ||
341        (vp.IsCullingCovered ()   != fVP.IsCull    343        (vp.IsCullingCovered ()   != fVP.IsCullingCovered ())   ||
342        (vp.GetCBDAlgorithmNumber() !=             344        (vp.GetCBDAlgorithmNumber() !=
343         fVP.GetCBDAlgorithmNumber())              345         fVP.GetCBDAlgorithmNumber())                           ||
344        (vp.IsSection ()          != fVP.IsSect    346        (vp.IsSection ()          != fVP.IsSection ())          ||
345        (vp.IsCutaway ()          != fVP.IsCuta    347        (vp.IsCutaway ()          != fVP.IsCutaway ())          ||
346        // This assumes use of generic clipping    348        // This assumes use of generic clipping (sectioning, slicing,
347        // DCUT, cutaway).  If a decision is ma    349        // DCUT, cutaway).  If a decision is made to implement locally,
348        // this will need changing.  See G4Open    350        // this will need changing.  See G4OpenGLViewer::SetView,
349        // G4OpenGLStoredViewer.cc::CompareForK    351        // G4OpenGLStoredViewer.cc::CompareForKernelVisit and
350        // G4OpenGLStoredSceneHander::CreateSec    352        // G4OpenGLStoredSceneHander::CreateSection/CutawayPolyhedron.
351        (vp.IsExplode ()          != fVP.IsExpl    353        (vp.IsExplode ()          != fVP.IsExplode ())          ||
352        (vp.GetNoOfSides ()       != fVP.GetNoO    354        (vp.GetNoOfSides ()       != fVP.GetNoOfSides ())       ||
353        (vp.GetGlobalMarkerScale()    != fVP.Ge    355        (vp.GetGlobalMarkerScale()    != fVP.GetGlobalMarkerScale())    ||
354        (vp.GetGlobalLineWidthScale() != fVP.Ge    356        (vp.GetGlobalLineWidthScale() != fVP.GetGlobalLineWidthScale()) ||
355        (vp.IsMarkerNotHidden ()  != fVP.IsMark    357        (vp.IsMarkerNotHidden ()  != fVP.IsMarkerNotHidden ())  ||
356        (vp.GetDefaultVisAttributes()->GetColou    358        (vp.GetDefaultVisAttributes()->GetColour() !=
357         fVP.GetDefaultVisAttributes()->GetColo    359         fVP.GetDefaultVisAttributes()->GetColour())            ||
358        (vp.GetDefaultTextVisAttributes()->GetC    360        (vp.GetDefaultTextVisAttributes()->GetColour() !=
359         fVP.GetDefaultTextVisAttributes()->Get    361         fVP.GetDefaultTextVisAttributes()->GetColour())        ||
360        (vp.GetBackgroundColour ()!= fVP.GetBac    362        (vp.GetBackgroundColour ()!= fVP.GetBackgroundColour ())||
361        (vp.IsPicking ()          != fVP.IsPick    363        (vp.IsPicking ()          != fVP.IsPicking ())          ||
362        // Scaling for Open Inventor is done by    364        // Scaling for Open Inventor is done by the scene handler so it
363        // needs a kernel visit.  (In this resp    365        // needs a kernel visit.  (In this respect, it differs from the
364        // OpenGL drivers, where it's done in S    366        // OpenGL drivers, where it's done in SetView.)
365        (vp.GetScaleFactor ()     != fVP.GetSca    367        (vp.GetScaleFactor ()     != fVP.GetScaleFactor ())     ||
366        (vp.GetVisAttributesModifiers() !=         368        (vp.GetVisAttributesModifiers() !=
367         fVP.GetVisAttributesModifiers())          369         fVP.GetVisAttributesModifiers())                       ||
368        (vp.IsSpecialMeshRendering() !=            370        (vp.IsSpecialMeshRendering() !=
369         fVP.IsSpecialMeshRendering())             371         fVP.IsSpecialMeshRendering())                          ||
370        (vp.GetSpecialMeshRenderingOption() !=     372        (vp.GetSpecialMeshRenderingOption() !=
371         fVP.GetSpecialMeshRenderingOption())      373         fVP.GetSpecialMeshRenderingOption())
372        )                                          374        )
373     return true;                                  375     return true;
374                                                   376 
375     if (vp.IsDensityCulling () &&                 377     if (vp.IsDensityCulling () &&
376         (vp.GetVisibleDensity () != fVP.GetVis    378         (vp.GetVisibleDensity () != fVP.GetVisibleDensity ()))
377       return true;                                379       return true;
378                                                   380 
379     if (vp.GetCBDAlgorithmNumber() > 0) {         381     if (vp.GetCBDAlgorithmNumber() > 0) {
380       if (vp.GetCBDParameters().size() != fVP.    382       if (vp.GetCBDParameters().size() != fVP.GetCBDParameters().size()) return true;
381       else if (vp.GetCBDParameters() != fVP.Ge    383       else if (vp.GetCBDParameters() != fVP.GetCBDParameters()) return true;
382     }                                             384     }
383                                                   385 
384     if (vp.IsSection () &&                        386     if (vp.IsSection () &&
385         (vp.GetSectionPlane () != fVP.GetSecti    387         (vp.GetSectionPlane () != fVP.GetSectionPlane ()))
386       return true;                                388       return true;
387                                                   389 
388     if (vp.IsCutaway ()) {                        390     if (vp.IsCutaway ()) {
389       if (vp.GetCutawayMode() != fVP.GetCutawa    391       if (vp.GetCutawayMode() != fVP.GetCutawayMode()) return true;
390       if (vp.GetCutawayPlanes ().size () !=       392       if (vp.GetCutawayPlanes ().size () !=
391           fVP.GetCutawayPlanes ().size ()) ret    393           fVP.GetCutawayPlanes ().size ()) return true;
392       for (size_t i = 0; i < vp.GetCutawayPlan    394       for (size_t i = 0; i < vp.GetCutawayPlanes().size(); ++i)
393       if (vp.GetCutawayPlanes()[i] != fVP.GetC    395       if (vp.GetCutawayPlanes()[i] != fVP.GetCutawayPlanes()[i])
394         return true;                              396         return true;
395     }                                             397     }
396                                                   398 
397     if (vp.IsExplode () &&                        399     if (vp.IsExplode () &&
398         (vp.GetExplodeFactor () != fVP.GetExpl    400         (vp.GetExplodeFactor () != fVP.GetExplodeFactor ()))
399       return true;                                401       return true;
400                                                   402 
401     if (vp.IsSpecialMeshRendering() &&            403     if (vp.IsSpecialMeshRendering() &&
402         (vp.GetSpecialMeshVolumes() != fVP.Get    404         (vp.GetSpecialMeshVolumes() != fVP.GetSpecialMeshVolumes()))
403       return true;                                405       return true;
404                                                   406 
405     return false;                                 407     return false;
406   }                                               408   }
407 //  void keyPressEvent        (KeyEvent*);        409 //  void keyPressEvent        (KeyEvent*);
408 //  void keyReleaseEvent      (KeyEvent*);        410 //  void keyReleaseEvent      (KeyEvent*);
409 //  void mouseDoubleClickEvent(MouseEvent*);      411 //  void mouseDoubleClickEvent(MouseEvent*);
410 //  void mouseMoveEvent       (MouseEvent*);      412 //  void mouseMoveEvent       (MouseEvent*);
411 //  void mousePressEvent      (MouseEvent*);      413 //  void mousePressEvent      (MouseEvent*);
412 //  void mouseReleaseEvent    (MouseEvent*);      414 //  void mouseReleaseEvent    (MouseEvent*);
413 //  void wheelEvent           (WheelEvent*);      415 //  void wheelEvent           (WheelEvent*);
414                                                   416 
415 protected:                                        417 protected:
416   void CreateSG(tools::sg::base_camera* a_came    418   void CreateSG(tools::sg::base_camera* a_camera,const G4Vector3D& a_light_dir) {
417     tools::sg::group& _parent = fSGViewer->sg(    419     tools::sg::group& _parent = fSGViewer->sg();
418     _parent.clear();                              420     _parent.clear();    
419                                                   421 
420     //////////////////////////////////////////    422     ///////////////////////////////////////////////////
421     /// 2D scene graph: //////////////////////    423     /// 2D scene graph: ///////////////////////////////
422     //////////////////////////////////////////    424     ///////////////////////////////////////////////////
423     tools::sg::separator* scene_2D = new tools    425     tools::sg::separator* scene_2D = new tools::sg::separator;
424     _parent.add(scene_2D);                        426     _parent.add(scene_2D);
425     scene_2D->add(new tools::sg::noderef(fSGSc    427     scene_2D->add(new tools::sg::noderef(fSGSceneHandler.GetTransient2DObjects()));
426     scene_2D->add(new tools::sg::noderef(fSGSc    428     scene_2D->add(new tools::sg::noderef(fSGSceneHandler.GetPersistent2DObjects()));
427                                                   429   
428     //////////////////////////////////////////    430     ///////////////////////////////////////////////////
429     /// 3D scene graph: //////////////////////    431     /// 3D scene graph: ///////////////////////////////
430     //////////////////////////////////////////    432     ///////////////////////////////////////////////////
431     tools::sg::separator* scene_3D = new tools    433     tools::sg::separator* scene_3D = new tools::sg::separator;
432     _parent.add(scene_3D);                        434     _parent.add(scene_3D);
433                                                   435   
434     scene_3D->add(a_camera);                      436     scene_3D->add(a_camera);
435                                                   437   
436    {tools::sg::torche* light = new tools::sg::    438    {tools::sg::torche* light = new tools::sg::torche;
437     light->on = true;                             439     light->on = true;
438     light->direction = tools::vec3f(-a_light_d    440     light->direction = tools::vec3f(-a_light_dir.x(),-a_light_dir.y(),-a_light_dir.z());
439     light->ambient = tools::colorf(0.2f,0.2f,0    441     light->ambient = tools::colorf(0.2f,0.2f,0.2f,1.0f);  //same as in G4OpenGLViewer.cc glLight(GL_LIGHT0,GL_AMBIENT and GL_DIFFUSE).
440     light->color = tools::colorf(0.8f,0.8f,0.8    442     light->color = tools::colorf(0.8f,0.8f,0.8f,1.0f);    //idem.
441     scene_3D->add(light);}                        443     scene_3D->add(light);}
442                                                   444   
443    {tools::sg::blend* blend = new tools::sg::b    445    {tools::sg::blend* blend = new tools::sg::blend;
444     blend->on = true; //to handle transparency    446     blend->on = true; //to handle transparency.
445     scene_3D->add(blend);}                        447     scene_3D->add(blend);}
446                                                   448 
447     scene_3D->add(new tools::sg::noderef(fSGSc    449     scene_3D->add(new tools::sg::noderef(fSGSceneHandler.GetTransient3DObjects()));
448     scene_3D->add(new tools::sg::noderef(fSGSc    450     scene_3D->add(new tools::sg::noderef(fSGSceneHandler.GetPersistent3DObjects()));
449   }                                               451   }
450                                                   452   
451   void Export(const G4String& a_format,const G    453   void Export(const G4String& a_format,const G4String& a_file,G4bool a_do_transparency) {
452     if(!fSGViewer) return;                        454     if(!fSGViewer) return;
453     const G4Colour& back_color = fVP.GetBackgr    455     const G4Colour& back_color = fVP.GetBackgroundColour();
454     bool top_to_bottom = false;  //if using to    456     bool top_to_bottom = false;  //if using tools::fpng, tools::toojpeg.
455     if(!tools::sg::write_paper(G4cout,f_gl2ps_    457     if(!tools::sg::write_paper(G4cout,f_gl2ps_mgr,f_zb_mgr,
456                     tools::fpng::write,tools::    458                     tools::fpng::write,tools::toojpeg::write,
457                     float(back_color.GetRed())    459                     float(back_color.GetRed()),float(back_color.GetGreen()),float(back_color.GetBlue()),float(back_color.GetAlpha()),
458                     fSGViewer->sg(),fSGViewer-    460                     fSGViewer->sg(),fSGViewer->width(),fSGViewer->height(),
459                     a_file,a_format,a_do_trans    461                     a_file,a_format,a_do_transparency,top_to_bottom,std::string(),std::string())) {
460       G4cout << "G4ToolsSGViewer::Export: writ    462       G4cout << "G4ToolsSGViewer::Export: write_paper() failed." << G4endl;
461       return;                                     463       return;
462     }                                             464     }
463   }                                               465   }
464                                                   466 
465 protected:                                        467 protected:  
466   class Messenger: public G4VVisCommand {         468   class Messenger: public G4VVisCommand {
467   public:                                         469   public:  
468     static void Create() {static Messenger s_m    470     static void Create() {static Messenger s_messenger;}
469   private:                                        471   private:  
470     Messenger() {                                 472     Messenger() {
471       G4UIparameter* parameter;                   473       G4UIparameter* parameter;
472       ////////////////////////////////////////    474       //////////////////////////////////////////////////////////
473       ////////////////////////////////////////    475       //////////////////////////////////////////////////////////
474       write_scene = new G4UIcommand("/vis/tsg/    476       write_scene = new G4UIcommand("/vis/tsg/export", this);
475       write_scene->SetGuidance("Write the cont    477       write_scene->SetGuidance("Write the content of the current viewer in a file at various formats.");
476       write_scene->SetGuidance("Default file i    478       write_scene->SetGuidance("Default file is out.eps and default format is gl2ps_eps.");
477       write_scene->SetGuidance("Available form    479       write_scene->SetGuidance("Available formats are:");
478       write_scene->SetGuidance("- gl2ps_eps: g    480       write_scene->SetGuidance("- gl2ps_eps: gl2ps producing eps");
479       write_scene->SetGuidance("- gl2ps_ps:  g    481       write_scene->SetGuidance("- gl2ps_ps:  gl2ps producing ps");
480       write_scene->SetGuidance("- gl2ps_pdf: g    482       write_scene->SetGuidance("- gl2ps_pdf: gl2ps producing pdf");
481       write_scene->SetGuidance("- gl2ps_svg: g    483       write_scene->SetGuidance("- gl2ps_svg: gl2ps producing svg");
482       write_scene->SetGuidance("- gl2ps_tex: g    484       write_scene->SetGuidance("- gl2ps_tex: gl2ps producing tex");
483       write_scene->SetGuidance("- gl2ps_pgf: g    485       write_scene->SetGuidance("- gl2ps_pgf: gl2ps producing pgf");
484       write_scene->SetGuidance("- zb_ps: tools    486       write_scene->SetGuidance("- zb_ps: tools::sg offscreen zbuffer put in a PostScript file.");
485       write_scene->SetGuidance("- zb_png: tool    487       write_scene->SetGuidance("- zb_png: tools::sg offscreen zbuffer put in a png file.");
486       write_scene->SetGuidance("- zb_jpeg: too    488       write_scene->SetGuidance("- zb_jpeg: tools::sg offscreen zbuffer put in a jpeg file.");
487                                                   489 
488       parameter = new G4UIparameter("format",'    490       parameter = new G4UIparameter("format",'s',true);
489       parameter->SetDefaultValue("gl2ps_eps");    491       parameter->SetDefaultValue("gl2ps_eps");
490       write_scene->SetParameter (parameter);      492       write_scene->SetParameter (parameter);
491                                                   493 
492       parameter = new G4UIparameter("file",'s'    494       parameter = new G4UIparameter("file",'s',true);
493       parameter->SetDefaultValue("out.eps");      495       parameter->SetDefaultValue("out.eps");
494       write_scene->SetParameter (parameter);      496       write_scene->SetParameter (parameter);
495                                                   497 
496       parameter =  new G4UIparameter ("do_tran    498       parameter =  new G4UIparameter ("do_transparency", 'b', true);
497       parameter->SetDefaultValue  ("true");       499       parameter->SetDefaultValue  ("true");
498       write_scene->SetParameter (parameter);      500       write_scene->SetParameter (parameter);
499                                                   501 
500     }                                             502     }
501     virtual ~Messenger() {                        503     virtual ~Messenger() {
502       delete write_scene;                         504       delete write_scene;
503     }                                             505     }
504   public:                                         506   public:
505     virtual void SetNewValue(G4UIcommand* a_cm    507     virtual void SetNewValue(G4UIcommand* a_cmd,G4String a_value) {
506       G4VisManager::Verbosity verbosity = GetV    508       G4VisManager::Verbosity verbosity = GetVisManager()->GetVerbosity();
507       G4VViewer* viewer = GetVisManager()->Get    509       G4VViewer* viewer = GetVisManager()->GetCurrentViewer();
508       if (!viewer) {                              510       if (!viewer) {
509         if (verbosity >= G4VisManager::errors)    511         if (verbosity >= G4VisManager::errors) G4cerr << "ERROR: No current viewer." << G4endl;
510         return;                                   512         return;
511       }                                           513       }
512       G4ToolsSGViewer* tsg_viewer = dynamic_ca    514       G4ToolsSGViewer* tsg_viewer = dynamic_cast<G4ToolsSGViewer*>(viewer);
513       if(!tsg_viewer) {                           515       if(!tsg_viewer) {
514         G4cout << "G4ToolsSGViewer::SetNewValu    516         G4cout << "G4ToolsSGViewer::SetNewValue:"
515                << " current viewer is not a G4    517                << " current viewer is not a G4ToolsSGViewer." << G4endl;
516         return;                                   518         return;
517       }                                           519       }
518       std::vector<std::string> args;              520       std::vector<std::string> args;
519       tools::double_quotes_tokenize(a_value,ar    521       tools::double_quotes_tokenize(a_value,args);
520       if(args.size()!=a_cmd->GetParameterEntri    522       if(args.size()!=a_cmd->GetParameterEntries()) return;
521       if(a_cmd==write_scene) {                    523       if(a_cmd==write_scene) {
522         G4bool do_transparency = G4UIcommand::    524         G4bool do_transparency = G4UIcommand::ConvertToBool(args[2].c_str());
523         tsg_viewer->Export(args[0],args[1],do_    525         tsg_viewer->Export(args[0],args[1],do_transparency);
524       }                                           526       }
525     }                                             527     }
526   private:                                        528   private:
527     G4UIcommand* write_scene;                     529     G4UIcommand* write_scene;
528   };                                              530   };
529                                                   531   
530 protected:                                        532 protected:
531   SG_SESSION& fSGSession;                         533   SG_SESSION& fSGSession;
532   G4ToolsSGSceneHandler& fSGSceneHandler;         534   G4ToolsSGSceneHandler& fSGSceneHandler;
533   SG_VIEWER* fSGViewer;                           535   SG_VIEWER* fSGViewer;
534   G4ViewParameters fLastVP;  // Memory for mak    536   G4ViewParameters fLastVP;  // Memory for making kernel visit decisions.
535                                                   537   
536   G4bool fKeyPressed;                             538   G4bool fKeyPressed;
537   G4bool fKeyShift;                               539   G4bool fKeyShift;
538   G4bool fMousePressed;                           540   G4bool fMousePressed;
539   G4double fMousePressedX, fMousePressedY;        541   G4double fMousePressedX, fMousePressedY;
540                                                   542 
541   tools::sg::zb_manager f_zb_mgr;                 543   tools::sg::zb_manager f_zb_mgr;
542   tools::sg::gl2ps_manager f_gl2ps_mgr;           544   tools::sg::gl2ps_manager f_gl2ps_mgr;
543                                                   545   
544 };                                                546 };
545                                                   547 
546 #endif                                            548 #endif
547                                                   549