Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/OpenGL/src/G4OpenGLViewer.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/OpenGL/src/G4OpenGLViewer.cc (Version 11.3.0) and /visualization/OpenGL/src/G4OpenGLViewer.cc (Version 9.2.p1)


  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 // $Id: G4OpenGLViewer.cc,v 1.41.2.1 2009/03/13 09:02:57 gcosmo Exp $
                                                   >>  28 // GEANT4 tag $Name: geant4-09-02-patch-01 $
 27 //                                                 29 //
 28 //                                                 30 // 
 29 // Andrew Walkden  27th March 1996                 31 // Andrew Walkden  27th March 1996
 30 // OpenGL view - opens window, hard copy, etc.     32 // OpenGL view - opens window, hard copy, etc.
 31                                                    33 
                                                   >>  34 #ifdef G4VIS_BUILD_OPENGL_DRIVER
                                                   >>  35 
 32 #include "G4ios.hh"                                36 #include "G4ios.hh"
 33 #include <CLHEP/Units/SystemOfUnits.h>         << 
 34 #include "G4OpenGLViewer.hh"                       37 #include "G4OpenGLViewer.hh"
 35 #include "G4OpenGLSceneHandler.hh"                 38 #include "G4OpenGLSceneHandler.hh"
 36 #include "G4OpenGLTransform3D.hh"                  39 #include "G4OpenGLTransform3D.hh"
 37                                                    40 
 38 #include "G4gl2ps.hh"                          << 
 39 #define GL2PS_TEXT_B  TOOLS_GL2PS_TEXT_B       << 
 40 #define GL2PS_TEXT_BL TOOLS_GL2PS_TEXT_BL      << 
 41 #define GL2PS_TEXT_BR TOOLS_GL2PS_TEXT_BR      << 
 42                                                << 
 43 #include "G4Scene.hh"                              41 #include "G4Scene.hh"
 44 #include "G4VisExtent.hh"                          42 #include "G4VisExtent.hh"
 45 #include "G4LogicalVolume.hh"                      43 #include "G4LogicalVolume.hh"
 46 #include "G4VSolid.hh"                             44 #include "G4VSolid.hh"
 47 #include "G4Point3D.hh"                            45 #include "G4Point3D.hh"
 48 #include "G4Normal3D.hh"                           46 #include "G4Normal3D.hh"
 49 #include "G4Plane3D.hh"                            47 #include "G4Plane3D.hh"
 50 #include "G4AttHolder.hh"                          48 #include "G4AttHolder.hh"
 51 #include "G4AttCheck.hh"                           49 #include "G4AttCheck.hh"
 52 #include "G4Text.hh"                           << 
 53                                                << 
 54 #include <sstream>                                 50 #include <sstream>
 55 #include <string>                              <<  51 
 56 #include <iomanip>                             <<  52 static const char* gouraudtriangleEPS[] =
                                                   >>  53 {
                                                   >>  54   "/bd{bind def}bind def /triangle { aload pop   setrgbcolor  aload pop 5 3",
                                                   >>  55   "roll 4 2 roll 3 2 roll exch moveto lineto lineto closepath fill } bd",
                                                   >>  56   "/computediff1 { 2 copy sub abs threshold ge {pop pop pop true} { exch 2",
                                                   >>  57   "index sub abs threshold ge { pop pop true} { sub abs threshold ge } ifelse",
                                                   >>  58   "} ifelse } bd /computediff3 { 3 copy 0 get 3 1 roll 0 get 3 1 roll 0 get",
                                                   >>  59   "computediff1 {true} { 3 copy 1 get 3 1 roll 1 get 3 1 roll 1 get",
                                                   >>  60   "computediff1 {true} { 3 copy 2 get 3 1 roll  2 get 3 1 roll 2 get",
                                                   >>  61   "computediff1 } ifelse } ifelse } bd /middlecolor { aload pop 4 -1 roll",
                                                   >>  62   "aload pop 4 -1 roll add 2 div 5 1 roll 3 -1 roll add 2 div 3 1 roll add 2",
                                                   >>  63   "div 3 1 roll exch 3 array astore } bd /gouraudtriangle { computediff3 { 4",
                                                   >>  64   "-1 roll aload 7 1 roll 6 -1 roll pop 3 -1 roll pop add 2 div 3 1 roll add",
                                                   >>  65   "2 div exch 3 -1 roll aload 7 1 roll exch pop 4 -1 roll pop add 2 div 3 1",
                                                   >>  66   "roll add 2 div exch 3 -1 roll aload 7 1 roll pop 3 -1 roll pop add 2 div 3",
                                                   >>  67   "1 roll add 2 div exch 7 3 roll 10 -3 roll dup 3 index middlecolor 4 1 roll",
                                                   >>  68   "2 copy middlecolor 4 1 roll 3 copy pop middlecolor 4 1 roll 13 -1 roll",
                                                   >>  69   "aload pop 17 index 6 index 15 index 19 index 6 index 17 index 6 array",
                                                   >>  70   "astore 10 index 10 index 14 index gouraudtriangle 17 index 5 index 17",
                                                   >>  71   "index 19 index 5 index 19 index 6 array astore 10 index 9 index 13 index",
                                                   >>  72   "gouraudtriangle 13 index 16 index 5 index 15 index 18 index 5 index 6",
                                                   >>  73   "array astore 12 index 12 index 9 index gouraudtriangle 17 index 16 index",
                                                   >>  74   "15 index 19 index 18 index 17 index 6 array astore 10 index 12 index 14",
                                                   >>  75   "index gouraudtriangle 18 {pop} repeat } { aload pop 5 3 roll aload pop 7 3",
                                                   >>  76   "roll aload pop 9 3 roll 4 index 6 index 4 index add add 3 div 10 1 roll 7",
                                                   >>  77   "index 5 index 3 index add add 3 div 10 1 roll 6 index 4 index 2 index add",
                                                   >>  78   "add 3 div 10 1 roll 9 {pop} repeat 3 array astore triangle } ifelse } bd",
                                                   >>  79   NULL
                                                   >>  80 };
 57                                                    81 
 58 G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneH     82 G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene):
 59 G4VViewer (scene, -1),                             83 G4VViewer (scene, -1),
 60 fPrintColour (true),                           <<  84 pointSize (0),
 61 fVectoredPs (true),                            <<  85 print_colour (true),
                                                   >>  86 vectored_ps (true),
 62 fOpenGLSceneHandler(scene),                        87 fOpenGLSceneHandler(scene),
 63 background (G4Colour(0.,0.,0.)),                   88 background (G4Colour(0.,0.,0.)),
 64 transparency_enabled (true),                       89 transparency_enabled (true),
 65 antialiasing_enabled (false),                      90 antialiasing_enabled (false),
 66 haloing_enabled (false),                           91 haloing_enabled (false),
 67 fRot_sens(1.),                                 <<  92 fStartTime(-DBL_MAX),
 68 fPan_sens(0.01),                               <<  93 fEndTime(DBL_MAX),
 69 fWinSize_x(0),                                 <<  94 fFadeFactor(0.),
 70 fWinSize_y(0),                                 <<  95 fDisplayHeadTime(false),
 71 fDefaultExportImageFormat("pdf"),              <<  96 fDisplayHeadTimeX(-0.9),
 72 fExportImageFormat("pdf"),                     <<  97 fDisplayHeadTimeY(-0.9),
 73 fExportFilenameIndex(0),                       <<  98 fDisplayHeadTimeSize(24.),
 74 fPrintSizeX(-1),                               <<  99 fDisplayHeadTimeRed(0.),
 75 fPrintSizeY(-1),                               << 100 fDisplayHeadTimeGreen(1.),
 76 fPointSize (0),                                << 101 fDisplayHeadTimeBlue(1.),
 77 fDefaultExportFilename("G4OpenGL"),            << 102 fDisplayLightFront(false),
 78 fSizeHasChanged(0),                            << 103 fDisplayLightFrontX(0.),
 79 fGl2psDefaultLineWith(1),                      << 104 fDisplayLightFrontY(0.),
 80 fGl2psDefaultPointSize(2),                     << 105 fDisplayLightFrontZ(0.),
 81 fGlViewInitialized(false),                     << 106 fDisplayLightFrontT(0.),
 82 fIsGettingPickInfos(false)                     << 107 fDisplayLightFrontRed(0.),
                                                   >> 108 fDisplayLightFrontGreen(1.),
                                                   >> 109 fDisplayLightFrontBlue(0.)
 83 {                                                 110 {
 84   // Make changes to view parameters for OpenG    111   // Make changes to view parameters for OpenGL...
 85   fVP.SetAutoRefresh(true);                       112   fVP.SetAutoRefresh(true);
 86   fDefaultVP.SetAutoRefresh(true);                113   fDefaultVP.SetAutoRefresh(true);
 87   fGL2PSAction = new G4gl2ps();                << 114   fWinSize_x = fVP.GetWindowSizeHintX();
 88   tools_gl2ps_gl_funcs_t _funcs = {            << 115   fWinSize_y = fVP.GetWindowSizeHintY();
 89     (tools_glIsEnabled_func)glIsEnabled,       << 
 90     (tools_glBegin_func)glBegin,               << 
 91     (tools_glEnd_func)glEnd,                   << 
 92     (tools_glGetFloatv_func)glGetFloatv,       << 
 93     (tools_glVertex3f_func)glVertex3f,         << 
 94     (tools_glGetBooleanv_func)glGetBooleanv,   << 
 95     (tools_glGetIntegerv_func)glGetIntegerv,   << 
 96     (tools_glRenderMode_func)glRenderMode,     << 
 97     (tools_glFeedbackBuffer_func)glFeedbackBuf << 
 98     (tools_glPassThrough_func)glPassThrough    << 
 99   };                                           << 
100   fGL2PSAction->setOpenGLFunctions(&_funcs);   << 
101                                                << 
102   // add supported export image format         << 
103   addExportImageFormat("eps");                 << 
104   addExportImageFormat("ps");                  << 
105   addExportImageFormat("pdf");                 << 
106   addExportImageFormat("svg");                 << 
107                                                   116 
108   // Change the default name                   << 
109   fExportFilename += fDefaultExportFilename +  << 
110                                                << 
111   //  glClearColor (0.0, 0.0, 0.0, 0.0);          117   //  glClearColor (0.0, 0.0, 0.0, 0.0);
112   //  glClearDepth (1.0);                         118   //  glClearDepth (1.0);
113   //  glDisable (GL_BLEND);                       119   //  glDisable (GL_BLEND);
114   //  glDisable (GL_LINE_SMOOTH);                 120   //  glDisable (GL_LINE_SMOOTH);
115   //  glDisable (GL_POLYGON_SMOOTH);              121   //  glDisable (GL_POLYGON_SMOOTH);
116                                                   122 
                                                   >> 123   strcpy (print_string, "G4OpenGL.eps");
117 }                                                 124 }
118                                                   125 
119 G4OpenGLViewer::~G4OpenGLViewer ()             << 126 G4OpenGLViewer::~G4OpenGLViewer () {}
120 {                                              << 
121   delete fGL2PSAction;                         << 
122 }                                              << 
123                                                   127 
124 void G4OpenGLViewer::InitializeGLView ()          128 void G4OpenGLViewer::InitializeGLView () 
125 {                                                 129 {
126   if (fWinSize_x == 0) {                       << 
127     fWinSize_x = fVP.GetWindowSizeHintX();     << 
128   }                                            << 
129   if (fWinSize_y == 0) {                       << 
130     fWinSize_y = fVP.GetWindowSizeHintY();     << 
131   }                                            << 
132                                                << 
133   glClearColor (0.0, 0.0, 0.0, 0.0);              130   glClearColor (0.0, 0.0, 0.0, 0.0);
134   glClearDepth (1.0);                             131   glClearDepth (1.0);
                                                   >> 132   glDisable (GL_BLEND);
135   glDisable (GL_LINE_SMOOTH);                     133   glDisable (GL_LINE_SMOOTH);
136   glDisable (GL_POLYGON_SMOOTH);                  134   glDisable (GL_POLYGON_SMOOTH);
137                                                << 135 }  
138 // clear the buffers and window?               << 
139   ClearView ();                                << 
140   FinishView ();                               << 
141                                                << 
142   glDepthFunc (GL_LEQUAL);                     << 
143   glDepthMask (GL_TRUE);                       << 
144                                                << 
145   glEnable (GL_BLEND);                         << 
146   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ << 
147                                                << 
148 }                                              << 
149                                                   136 
150 void G4OpenGLViewer::ClearView () {               137 void G4OpenGLViewer::ClearView () {
151   ClearViewWithoutFlush();                     << 
152                                                << 
153   if(!isFramebufferReady()) {                  << 
154     return;                                    << 
155   }                                            << 
156                                                << 
157   glFlush();                                   << 
158 }                                              << 
159                                                << 
160                                                << 
161 void G4OpenGLViewer::ClearViewWithoutFlush ()  << 
162   // Ready for clear ?                         << 
163   // See : http://lists.apple.com/archives/mac << 
164   if(!isFramebufferReady()) {                  << 
165     return;                                    << 
166   }                                            << 
167                                                << 
168   glClearColor (background.GetRed(),              138   glClearColor (background.GetRed(),
169                 background.GetGreen(),         << 139     background.GetGreen(),
170                 background.GetBlue(),          << 140     background.GetBlue(),
171                 1.);                           << 141     1.);
172   glClearDepth (1.0);                             142   glClearDepth (1.0);
173   //Below line does not compile with Mesa incl << 143   //Below line does not compile with Mesa includes. 
174   //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BU << 144   //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
175   glClear (GL_COLOR_BUFFER_BIT);                  145   glClear (GL_COLOR_BUFFER_BIT);
176   glClear (GL_DEPTH_BUFFER_BIT);                  146   glClear (GL_DEPTH_BUFFER_BIT);
177   glClear (GL_STENCIL_BUFFER_BIT);                147   glClear (GL_STENCIL_BUFFER_BIT);
                                                   >> 148   glFlush ();
178 }                                                 149 }
179                                                   150 
180                                                   151 
181 void G4OpenGLViewer::ResizeWindow(unsigned int << 
182   if ((fWinSize_x != aWidth) || (fWinSize_y != << 
183     fWinSize_x = aWidth;                       << 
184     fWinSize_y = aHeight;                      << 
185     fSizeHasChanged = true;                    << 
186   } else {                                     << 
187     fSizeHasChanged = false;                   << 
188   }                                            << 
189 }                                              << 
190                                                << 
191 /**                                               152 /**
192  * Set the viewport of the scene                  153  * Set the viewport of the scene
193  * MAXIMUM SIZE is :                           << 
194  * GLint dims[2];                              << 
195  * glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);  << 
196  */                                               154  */
197 void G4OpenGLViewer::ResizeGLView()               155 void G4OpenGLViewer::ResizeGLView()
198 {                                                 156 {
199   // Check size                                << 157   int side = fWinSize_x;
200   GLint dims[2];                               << 158   if (fWinSize_y < fWinSize_x) side = fWinSize_y;
201   dims[0] = 0;                                 << 159   glViewport((fWinSize_x - side) / 2, (fWinSize_y - side) / 2, side, side);  
202   dims[1] = 0;                                 << 
203                                                << 
204   glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);   << 
205                                                << 
206   if ((dims[0] !=0 ) && (dims[1] !=0)) {       << 
207                                                << 
208     if (fWinSize_x > (unsigned)dims[0]) {      << 
209       G4cerr << "Try to resize view greater th << 
210       fWinSize_x = dims[0];                    << 
211     }                                          << 
212     if (fWinSize_y > (unsigned)dims[1]) {      << 
213       G4cerr << "Try to resize view greater th << 
214       fWinSize_y = dims[1];                    << 
215     }                                          << 
216   }                                            << 
217                                                << 
218   glViewport(0, 0, fWinSize_x,fWinSize_y);     << 
219                                                << 
220                                                << 
221 }                                                 160 }
222                                                   161 
223                                                   162 
224 void G4OpenGLViewer::SetView () {                 163 void G4OpenGLViewer::SetView () {
225   // if getting pick infos, should not resize  << 164 
226   if (fIsGettingPickInfos) return;             << 
227                                                << 
228   if (!fSceneHandler.GetScene()) {                165   if (!fSceneHandler.GetScene()) {
                                                   >> 166     G4cerr << "G4OpenGLStoredViewer: Creating a Viewer without a scene is not allowed. \nPlease use /vis/scene/create before /vis/open/.... "
                                                   >> 167      << G4endl;
229     return;                                       168     return;
230   }                                               169   }
231   // Calculates view representation based on e    170   // Calculates view representation based on extent of object being
232   // viewed and (initial) viewpoint.  (Note: i    171   // viewed and (initial) viewpoint.  (Note: it can change later due
233   // to user interaction via visualization sys    172   // to user interaction via visualization system's GUI.)
234                                                   173   
235   // Lighting.                                    174   // Lighting.
236   GLfloat lightPosition [4];                      175   GLfloat lightPosition [4];
237   lightPosition [0] = fVP.GetActualLightpointD    176   lightPosition [0] = fVP.GetActualLightpointDirection().x();
238   lightPosition [1] = fVP.GetActualLightpointD    177   lightPosition [1] = fVP.GetActualLightpointDirection().y();
239   lightPosition [2] = fVP.GetActualLightpointD    178   lightPosition [2] = fVP.GetActualLightpointDirection().z();
240   lightPosition [3] = 0.;                         179   lightPosition [3] = 0.;
241   // Light position is "true" light direction,    180   // Light position is "true" light direction, so must come after gluLookAt.
242   GLfloat ambient [] = { 0.2f, 0.2f, 0.2f, 1.f << 181   GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.};
243   GLfloat diffuse [] = { 0.8f, 0.8f, 0.8f, 1.f << 182   GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.};
244   glEnable (GL_LIGHT0);                           183   glEnable (GL_LIGHT0);
245   glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);     184   glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
246   glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);     185   glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
247                                                   186   
248   G4double ratioX = 1;                         << 
249   G4double ratioY = 1;                         << 
250   if (fWinSize_y > fWinSize_x) {               << 
251     ratioX = ((G4double)fWinSize_y) / ((G4doub << 
252   }                                            << 
253   if (fWinSize_x > fWinSize_y) {               << 
254     ratioY = ((G4double)fWinSize_x) / ((G4doub << 
255   }                                            << 
256                                                << 
257   // Get radius of scene, etc.                    187   // Get radius of scene, etc.
258   // Note that this procedure properly takes i    188   // Note that this procedure properly takes into account zoom, dolly and pan.
259   const G4Point3D targetPoint                     189   const G4Point3D targetPoint
260     = fSceneHandler.GetScene()->GetStandardTar    190     = fSceneHandler.GetScene()->GetStandardTargetPoint()
261     + fVP.GetCurrentTargetPoint ();               191     + fVP.GetCurrentTargetPoint ();
262   G4double radius = fSceneHandler.GetScene()->    192   G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
263   if(radius<=0.) radius = 1.;                     193   if(radius<=0.) radius = 1.;
264   const G4double cameraDistance = fVP.GetCamer    194   const G4double cameraDistance = fVP.GetCameraDistance (radius);
265   const G4Point3D cameraPosition =                195   const G4Point3D cameraPosition =
266     targetPoint + cameraDistance * fVP.GetView    196     targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
267   const GLdouble pnear  = fVP.GetNearDistance     197   const GLdouble pnear  = fVP.GetNearDistance (cameraDistance, radius);
268   const GLdouble pfar   = fVP.GetFarDistance      198   const GLdouble pfar   = fVP.GetFarDistance  (cameraDistance, pnear, radius);
269   const GLdouble right  = fVP.GetFrontHalfHeig << 199   const GLdouble right  = fVP.GetFrontHalfHeight (pnear, radius);
270   const GLdouble left   = -right;                 200   const GLdouble left   = -right;
271   const GLdouble top    = fVP.GetFrontHalfHeig << 201   const GLdouble bottom = left;
272   const GLdouble bottom = -top;                << 202   const GLdouble top    = right;
273                                                   203   
274   // FIXME                                        204   // FIXME
275   ResizeGLView();                                 205   ResizeGLView();
276   //SHOULD SetWindowsSizeHint()...                206   //SHOULD SetWindowsSizeHint()...
277                                                   207 
278   glMatrixMode (GL_PROJECTION); // set up Frus    208   glMatrixMode (GL_PROJECTION); // set up Frustum.
279   glLoadIdentity();                               209   glLoadIdentity();
280                                                   210 
281   const G4Vector3D scaleFactor = fVP.GetScaleF    211   const G4Vector3D scaleFactor = fVP.GetScaleFactor();
282   glScaled(scaleFactor.x(),scaleFactor.y(),sca    212   glScaled(scaleFactor.x(),scaleFactor.y(),scaleFactor.z());
283                                                   213   
284   if (fVP.GetFieldHalfAngle() == 0.) {            214   if (fVP.GetFieldHalfAngle() == 0.) {
285     g4GlOrtho (left, right, bottom, top, pnear << 215     glOrtho (left, right, bottom, top, pnear, pfar);
286   }                                               216   }
287   else {                                          217   else {
288     g4GlFrustum (left, right, bottom, top, pne << 218     glFrustum (left, right, bottom, top, pnear, pfar);
289   }                                               219   }  
290                                                   220 
291   glMatrixMode (GL_MODELVIEW); // apply furthe    221   glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
292   glLoadIdentity();                               222   glLoadIdentity();
293                                                   223   
294   const G4Normal3D& upVector = fVP.GetUpVector    224   const G4Normal3D& upVector = fVP.GetUpVector ();  
295   G4Point3D gltarget;                             225   G4Point3D gltarget;
296   if (cameraDistance > 1.e-6 * radius) {          226   if (cameraDistance > 1.e-6 * radius) {
297     gltarget = targetPoint;                       227     gltarget = targetPoint;
298   }                                               228   }
299   else {                                          229   else {
300     gltarget = targetPoint - radius * fVP.GetV    230     gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit();
301   }                                               231   }
302                                                   232 
303   const G4Point3D& pCamera = cameraPosition;      233   const G4Point3D& pCamera = cameraPosition;  // An alias for brevity.
                                                   >> 234   gluLookAt (pCamera.x(),  pCamera.y(),  pCamera.z(),       // Viewpoint.
                                                   >> 235        gltarget.x(), gltarget.y(), gltarget.z(),      // Target point.
                                                   >> 236        upVector.x(), upVector.y(), upVector.z());     // Up vector.
304                                                   237 
305   g4GluLookAt (pCamera.x(),  pCamera.y(),  pCa << 
306              gltarget.x(), gltarget.y(), gltar << 
307              upVector.x(), upVector.y(), upVec << 
308   // Light position is "true" light direction,    238   // Light position is "true" light direction, so must come after gluLookAt.
309   glLightfv (GL_LIGHT0, GL_POSITION, lightPosi    239   glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
310                                                   240 
311   // The idea is to use back-to-back clipping  << 241   // OpenGL no longer seems to reconstruct clipped edges, so, when the
312   // down to just a few pixels, which can make << 242   // BooleanProcessor is up to it, abandon this and use generic
313   // now, comment this out and use the generic << 243   // clipping in G4OpenGLSceneHandler::CreateSectionPolyhedron.  Also,
314   // G4VSolid* G4OpenGLSceneHandler::CreateSec << 244   // force kernel visit on change of clipping plane in
315   // { return G4VSceneHandler::CreateSectionSo << 245   // G4OpenGLStoredViewer::CompareForKernelVisit.
316 //  if (fVP.IsSection () ) {  // pair of back  << 246   if (fVP.IsSection () ) {  // pair of back to back clip planes.
317 //    const G4Plane3D& sp = fVP.GetSectionPlan << 247     const G4Plane3D& s = fVP.GetSectionPlane ();
318 //    double sArray[4];                        << 248     double sArray[4];
319 //    sArray[0] = sp.a();                      << 249     sArray[0] = s.a();
320 //    sArray[1] = sp.b();                      << 250     sArray[1] = s.b();
321 //    sArray[2] = sp.c();                      << 251     sArray[2] = s.c();
322 //    sArray[3] = sp.d() + radius * 1.e-05;    << 252     sArray[3] = s.d() + radius * 1.e-05;
323 //    glClipPlane (GL_CLIP_PLANE0, sArray);    << 253     glClipPlane (GL_CLIP_PLANE0, sArray);
324 //    glEnable (GL_CLIP_PLANE0);               << 254     glEnable (GL_CLIP_PLANE0);
325 //    sArray[0] = -sp.a();                     << 255     sArray[0] = -s.a();
326 //    sArray[1] = -sp.b();                     << 256     sArray[1] = -s.b();
327 //    sArray[2] = -sp.c();                     << 257     sArray[2] = -s.c();
328 //    sArray[3] = -sp.d() + radius * 1.e-05;   << 258     sArray[3] = -s.d() + radius * 1.e-05;
329 //    glClipPlane (GL_CLIP_PLANE1, sArray);    << 259     glClipPlane (GL_CLIP_PLANE1, sArray);
330 //    glEnable (GL_CLIP_PLANE1);               << 260     glEnable (GL_CLIP_PLANE1);
331 //  } else {                                   << 261   } else {
332 //    glDisable (GL_CLIP_PLANE0);              << 262     glDisable (GL_CLIP_PLANE0);
333 //    glDisable (GL_CLIP_PLANE1);              << 263     glDisable (GL_CLIP_PLANE1);
334 //  }                                          << 264   }
335                                                << 265 
336   // What we call intersection of cutaways is  << 
337   // just keep cutting.  Unions are more trick << 
338   // multiple passes and this is handled in    << 
339   // G4OpenGLImmediate/StoredViewer::ProcessVi << 
340   const G4Planes& cutaways = fVP.GetCutawayPla    266   const G4Planes& cutaways = fVP.GetCutawayPlanes();
341   size_t nPlanes = cutaways.size();               267   size_t nPlanes = cutaways.size();
342   if (fVP.IsCutaway() &&                          268   if (fVP.IsCutaway() &&
343       fVP.GetCutawayMode() == G4ViewParameters << 269       fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection &&
                                                   >> 270       nPlanes > 0) {
344     double a[4];                                  271     double a[4];
345     a[0] = cutaways[0].a();                       272     a[0] = cutaways[0].a();
346     a[1] = cutaways[0].b();                       273     a[1] = cutaways[0].b();
347     a[2] = cutaways[0].c();                       274     a[2] = cutaways[0].c();
348     a[3] = cutaways[0].d();                       275     a[3] = cutaways[0].d();
349     glClipPlane (GL_CLIP_PLANE2, a);              276     glClipPlane (GL_CLIP_PLANE2, a);
350     glEnable (GL_CLIP_PLANE2);                    277     glEnable (GL_CLIP_PLANE2);
351     if (nPlanes > 1) {                            278     if (nPlanes > 1) {
352       a[0] = cutaways[1].a();                     279       a[0] = cutaways[1].a();
353       a[1] = cutaways[1].b();                     280       a[1] = cutaways[1].b();
354       a[2] = cutaways[1].c();                     281       a[2] = cutaways[1].c();
355       a[3] = cutaways[1].d();                     282       a[3] = cutaways[1].d();
356       glClipPlane (GL_CLIP_PLANE3, a);            283       glClipPlane (GL_CLIP_PLANE3, a);
357       glEnable (GL_CLIP_PLANE3);                  284       glEnable (GL_CLIP_PLANE3);
358     }                                             285     }
359     if (nPlanes > 2) {                            286     if (nPlanes > 2) {
360       a[0] = cutaways[2].a();                     287       a[0] = cutaways[2].a();
361       a[1] = cutaways[2].b();                     288       a[1] = cutaways[2].b();
362       a[2] = cutaways[2].c();                     289       a[2] = cutaways[2].c();
363       a[3] = cutaways[2].d();                     290       a[3] = cutaways[2].d();
364       glClipPlane (GL_CLIP_PLANE4, a);            291       glClipPlane (GL_CLIP_PLANE4, a);
365       glEnable (GL_CLIP_PLANE4);                  292       glEnable (GL_CLIP_PLANE4);
366     }                                             293     }
367   } else {                                        294   } else {
368     glDisable (GL_CLIP_PLANE2);                   295     glDisable (GL_CLIP_PLANE2);
369     glDisable (GL_CLIP_PLANE3);                   296     glDisable (GL_CLIP_PLANE3);
370     glDisable (GL_CLIP_PLANE4);                   297     glDisable (GL_CLIP_PLANE4);
371   }                                               298   }
372                                                   299 
373   // Background.                                  300   // Background.
374   background = fVP.GetBackgroundColour ();        301   background = fVP.GetBackgroundColour ();
375                                                   302 
376 }                                                 303 }
377                                                   304 
378                                                << 
379                                                << 
380 void G4OpenGLViewer::ResetView () {            << 
381   G4VViewer::ResetView();                      << 
382   fRot_sens = 1;                               << 
383   fPan_sens = 0.01;                            << 
384 }                                              << 
385                                                << 
386                                                << 
387 void G4OpenGLViewer::HaloingFirstPass () {        305 void G4OpenGLViewer::HaloingFirstPass () {
388                                                   306   
389   //To perform haloing, first Draw all informa    307   //To perform haloing, first Draw all information to the depth buffer
390   //alone, using a chunky line width, and then    308   //alone, using a chunky line width, and then Draw all info again, to
391   //the colour buffer, setting a thinner line     309   //the colour buffer, setting a thinner line width an the depth testing 
392   //function to less than or equal, so if two     310   //function to less than or equal, so if two lines cross, the one 
393   //passing behind the other will not pass the    311   //passing behind the other will not pass the depth test, and so not
394   //get rendered either side of the infront li    312   //get rendered either side of the infront line for a short distance.
395                                                   313 
396   //First, disable writing to the colo(u)r buf    314   //First, disable writing to the colo(u)r buffer...
397   glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, G    315   glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
398                                                   316 
399   //Now enable writing to the depth buffer...     317   //Now enable writing to the depth buffer...
400   glDepthMask (GL_TRUE);                          318   glDepthMask (GL_TRUE);
401   glDepthFunc (GL_LESS);                          319   glDepthFunc (GL_LESS);
402   glClearDepth (1.0);                             320   glClearDepth (1.0);
403                                                   321 
404   //Finally, set the line width to something w    322   //Finally, set the line width to something wide...
405   ChangeLineWidth(3.0);                        << 323   glLineWidth (3.0);
406                                                   324 
407 }                                                 325 }
408                                                   326 
409 void G4OpenGLViewer::HaloingSecondPass () {       327 void G4OpenGLViewer::HaloingSecondPass () {
410                                                   328 
411   //And finally, turn the colour buffer back o    329   //And finally, turn the colour buffer back on with a sesible line width...
412   glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_T    330   glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
413   glDepthFunc (GL_LEQUAL);                        331   glDepthFunc (GL_LEQUAL);
414   ChangeLineWidth(1.0);                        << 332   glLineWidth (1.0);
415                                                   333 
416 }                                                 334 }
417                                                   335 
418 G4String G4OpenGLViewer::Pick(GLdouble x, GLdo << 336 void G4OpenGLViewer::Pick(GLdouble x, GLdouble y)
419 {                                                 337 {
420   const std::vector < G4OpenGLViewerPickMap* > << 338   //G4cout << "X: " << x << ", Y: " << y << G4endl;
421   G4String txt = "";                           << 
422   if (pickMap.size() == 0) {                   << 
423 //        txt += "No hits recorded.";;         << 
424   } else {                                     << 
425     for (unsigned int a=0; a < pickMap.size(); << 
426       if (pickMap[a]->getAttributes().size() > << 
427         txt += pickMap[a]->print();            << 
428       }                                        << 
429     }                                          << 
430   }                                            << 
431   return txt;                                  << 
432 }                                              << 
433                                                << 
434 const std::vector < G4OpenGLViewerPickMap* > & << 
435 {                                              << 
436   static std::vector < G4OpenGLViewerPickMap*  << 
437   for (auto pickMap: pickMapVector) {          << 
438     delete pickMap;                            << 
439   }                                            << 
440   pickMapVector.clear();                       << 
441                                                << 
442   const G4int BUFSIZE = 512;                      339   const G4int BUFSIZE = 512;
443   GLuint selectBuffer[BUFSIZE];                   340   GLuint selectBuffer[BUFSIZE];
444   glSelectBuffer(BUFSIZE, selectBuffer);          341   glSelectBuffer(BUFSIZE, selectBuffer);
445   glRenderMode(GL_SELECT);                        342   glRenderMode(GL_SELECT);
446   glInitNames();                                  343   glInitNames();
447   glPushName(0);                                  344   glPushName(0);
448   glMatrixMode(GL_PROJECTION);                    345   glMatrixMode(GL_PROJECTION);
449   G4double currentProjectionMatrix[16];           346   G4double currentProjectionMatrix[16];
450   glGetDoublev(GL_PROJECTION_MATRIX, currentPr    347   glGetDoublev(GL_PROJECTION_MATRIX, currentProjectionMatrix);
451   glPushMatrix();                                 348   glPushMatrix();
452   glLoadIdentity();                               349   glLoadIdentity();
453   GLint viewport[4];                              350   GLint viewport[4];
454   glGetIntegerv(GL_VIEWPORT, viewport);           351   glGetIntegerv(GL_VIEWPORT, viewport);
455 /*  G4cout                                     << 
456   << "viewport, x,y: "                         << 
457   << viewport[0] << ',' << viewport[1] << ','  << 
458   << ", " << x << ',' << y                     << 
459   << G4endl;                                   << 
460 */                                             << 
461   fIsGettingPickInfos = true;                  << 
462   // Define 5x5 pixel pick area                   352   // Define 5x5 pixel pick area
463   g4GluPickMatrix(x, viewport[3] - y, 5., 5.,  << 353   gluPickMatrix(x, viewport[3] - y, 5., 5., viewport);
464   glMultMatrixd(currentProjectionMatrix);         354   glMultMatrixd(currentProjectionMatrix);
465   glMatrixMode(GL_MODELVIEW);                     355   glMatrixMode(GL_MODELVIEW);
466   DrawView();                                     356   DrawView();
467   GLint hits = glRenderMode(GL_RENDER);           357   GLint hits = glRenderMode(GL_RENDER);
468   fIsGettingPickInfos = false;                 << 358   if (hits < 0)
469   if (hits < 0) {                              << 359     G4cout << "Too many hits.  Zoom in to reduce overlaps." << G4cout;
470     G4cout << "Too many hits.  Zoom in to redu << 360   else if (hits > 0) {
471     goto restoreMatrices;                      << 361     //G4cout << hits << " hit(s)" << G4endl;
472   }                                            << 
473   if (hits > 0) {                              << 
474     GLuint* p = selectBuffer;                     362     GLuint* p = selectBuffer;
475     for (GLint i = 0; i < hits; ++i) {            363     for (GLint i = 0; i < hits; ++i) {
476       GLuint nnames = *p++;                       364       GLuint nnames = *p++;
477       // This bit of debug code or...          << 365       *p++; //OR GLuint zmin = *p++;
478       //GLuint zmin = *p++;                    << 366       *p++; //OR GLuint zmax = *p++;
479       //GLuint zmax = *p++;                    << 
480       //G4cout << "Hit " << i << ": " << nname    367       //G4cout << "Hit " << i << ": " << nnames << " names"
481       //       << "\nzmin: " << zmin << ", zma << 368       //     << "\nzmin: " << zmin << ", zmax: " << zmax << G4endl;
482       // ...just increment the pointer         << 
483       p++;                                     << 
484       p++;                                     << 
485       for (GLuint j = 0; j < nnames; ++j) {       369       for (GLuint j = 0; j < nnames; ++j) {
486         GLuint name = *p++;                    << 370   GLuint name = *p++;
                                                   >> 371   //G4cout << "Name " << j << ": PickName: " << name << G4endl;
487   std::map<GLuint, G4AttHolder*>::iterator ite    372   std::map<GLuint, G4AttHolder*>::iterator iter =
488     fOpenGLSceneHandler.fPickMap.find(name);      373     fOpenGLSceneHandler.fPickMap.find(name);
489   if (iter != fOpenGLSceneHandler.fPickMap.end    374   if (iter != fOpenGLSceneHandler.fPickMap.end()) {
490     G4AttHolder* attHolder = iter->second;        375     G4AttHolder* attHolder = iter->second;
491     if(attHolder && attHolder->GetAttDefs().si    376     if(attHolder && attHolder->GetAttDefs().size()) {
492       for (size_t iAtt = 0;                    << 377       for (size_t i = 0; i < attHolder->GetAttDefs().size(); ++i) {
493      iAtt < attHolder->GetAttDefs().size(); ++ << 378         G4cout << G4AttCheck(attHolder->GetAttValues()[i],
494               std::ostringstream oss;          << 379            attHolder->GetAttDefs()[i]);
495         oss << G4AttCheck(attHolder->GetAttVal << 380       }
496                                 attHolder->Get << 381     }
497               G4OpenGLViewerPickMap* pickMap = << 382   }
498 //              G4cout                         << 
499 //              << "i,j, attHolder->GetAttDefs << 
500 //              << i << ',' << j               << 
501 //              << ", " << attHolder->GetAttDe << 
502 //              << G4endl;                     << 
503 //              G4cout << "G4OpenGLViewer::Get << 
504               pickMap->addAttributes(oss.str() << 
505               pickMap->setHitNumber(i);        << 
506               pickMap->setSubHitNumber(j);     << 
507               pickMap->setPickName(name);      << 
508               pickMapVector.push_back(pickMap) << 
509             }                                  << 
510           }                                    << 
511         }                                      << 
512       }                                           383       }
                                                   >> 384       G4cout << G4endl;
513     }                                             385     }
514   }                                               386   }
515                                                << 
516 restoreMatrices:                               << 
517   glMatrixMode(GL_PROJECTION);                    387   glMatrixMode(GL_PROJECTION);
518   glPopMatrix();                                  388   glPopMatrix();
519   glMatrixMode(GL_MODELVIEW);                     389   glMatrixMode(GL_MODELVIEW);
520                                                << 
521   return pickMapVector;                        << 
522 }                                                 390 }
523                                                   391 
524 GLubyte* G4OpenGLViewer::grabPixels            << 392 void G4OpenGLViewer::print() {
525 (int inColor, unsigned int width, unsigned int << 
526                                                << 
527   GLubyte* buffer;                             << 
528   GLint swapbytes, lsbfirst, rowlength;        << 
529   GLint skiprows, skippixels, alignment;       << 
530   GLenum format;                               << 
531   int size;                                    << 
532                                                << 
533   if (inColor) {                               << 
534     format = GL_RGB;                           << 
535     size = width*height*3;                     << 
536   } else {                                     << 
537     format = GL_LUMINANCE;                     << 
538     size = width*height*1;                     << 
539   }                                            << 
540                                                   393 
541   buffer = new GLubyte[size];                  << 394   // Print vectored PostScript
542   if (buffer == NULL)                          << 
543     return NULL;                               << 
544                                                << 
545   glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapby << 
546   glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirs << 
547   glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlen << 
548                                                << 
549   glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprow << 
550   glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skipp << 
551   glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignme << 
552                                                << 
553   glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALS << 
554   glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE << 
555   glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);     << 
556                                                << 
557   glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);      << 
558   glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);    << 
559   glPixelStorei (GL_UNPACK_ALIGNMENT, 1);      << 
560                                                << 
561   glReadBuffer(GL_FRONT);                      << 
562   glReadPixels (0, 0, (GLsizei)width, (GLsizei << 
563                                                << 
564   glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbyt << 
565   glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst << 
566   glPixelStorei (GL_UNPACK_ROW_LENGTH, rowleng << 
567                                                << 
568   glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows << 
569   glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippi << 
570   glPixelStorei (GL_UNPACK_ALIGNMENT, alignmen << 
571                                                   395   
572   return buffer;                               << 396   G4int size = 5000000;
573 }                                              << 397   GLfloat* feedback_buffer = new GLfloat[size];
574                                                << 398   glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
575 bool G4OpenGLViewer::printVectoredEPS() {      << 399   glRenderMode (GL_FEEDBACK);
576   return printGl2PS();                         << 
577 }                                              << 
578                                                << 
579 bool G4OpenGLViewer::printNonVectoredEPS () {  << 
580                                                << 
581   int width = getRealExportWidth();            << 
582   int height = getRealExportHeight();          << 
583                                                << 
584   FILE* fp;                                    << 
585   GLubyte* pixels;                             << 
586   GLubyte* curpix;                             << 
587   int components, pos, i;                      << 
588                                                << 
589   pixels = grabPixels (fPrintColour, width, he << 
590                                                << 
591   if (pixels == NULL) {                        << 
592       G4cerr << "Failed to get pixels from Ope << 
593     return false;                              << 
594   }                                            << 
595   if (fPrintColour) {                          << 
596     components = 3;                            << 
597   } else {                                     << 
598     components = 1;                            << 
599   }                                            << 
600   std::string name = getRealPrintFilename();   << 
601   fp = fopen (name.c_str(), "w");              << 
602   if (fp == NULL) {                            << 
603     G4cerr << "Can't open filename " << name.c << 
604     return false;                              << 
605   }                                            << 
606                                                   400   
607   fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");  << 401   DrawView();
608   fprintf (fp, "%%%%Title: %s\n", name.c_str() << 
609   fprintf (fp, "%%%%Creator: OpenGL pixmap ren << 
610   fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", << 
611   fprintf (fp, "%%%%EndComments\n");           << 
612   fprintf (fp, "gsave\n");                     << 
613   fprintf (fp, "/bwproc {\n");                 << 
614   fprintf (fp, "    rgbproc\n");               << 
615   fprintf (fp, "    dup length 3 idiv string 0 << 
616   fprintf (fp, "    5 -1 roll {\n");           << 
617   fprintf (fp, "    add 2 1 roll 1 sub dup 0 e << 
618   fprintf (fp, "    { pop 3 idiv 3 -1 roll dup << 
619   fprintf (fp, "       3 1 roll 5 -1 roll } pu << 
620   fprintf (fp, "    { 2 1 roll } ifelse\n");   << 
621   fprintf (fp, "    }forall\n");               << 
622   fprintf (fp, "    pop pop pop\n");           << 
623   fprintf (fp, "} def\n");                     << 
624   fprintf (fp, "systemdict /colorimage known n << 
625   fprintf (fp, "   /colorimage {\n");          << 
626   fprintf (fp, "       pop\n");                << 
627   fprintf (fp, "       pop\n");                << 
628   fprintf (fp, "       /rgbproc exch def\n");  << 
629   fprintf (fp, "       { bwproc } image\n");   << 
630   fprintf (fp, "   }  def\n");                 << 
631   fprintf (fp, "} if\n");                      << 
632   fprintf (fp, "/picstr %d string def\n", widt << 
633   fprintf (fp, "%d %d scale\n", width, height) << 
634   fprintf (fp, "%d %d %d\n", width, height, 8) << 
635   fprintf (fp, "[%d 0 0 %d 0 0]\n", width, hei << 
636   fprintf (fp, "{currentfile picstr readhexstr << 
637   fprintf (fp, "false %d\n", components);      << 
638   fprintf (fp, "colorimage\n");                << 
639                                                << 
640   curpix = (GLubyte*) pixels;                  << 
641   pos = 0;                                     << 
642   for (i = width*height*components; i>0; i--)  << 
643     fprintf (fp, "%02hx ", (unsigned short)(*( << 
644     if (++pos >= 32) {                         << 
645       fprintf (fp, "\n");                      << 
646       pos = 0;                                 << 
647     }                                          << 
648   }                                            << 
649   if (pos)                                     << 
650     fprintf (fp, "\n");                        << 
651                                                << 
652   fprintf (fp, "grestore\n");                  << 
653   fprintf (fp, "showpage\n");                  << 
654   delete [] pixels;                            << 
655   fclose (fp);                                 << 
656                                                << 
657   // Reset for next time (useful if size chang << 
658   //  fPrintSizeX = -1;                        << 
659   //  fPrintSizeY = -1;                        << 
660                                                << 
661   return true;                                 << 
662 }                                              << 
663                                                << 
664 /** Return if gl2ps is currently writing       << 
665  */                                            << 
666 bool G4OpenGLViewer::isGl2psWriting() {        << 
667                                                << 
668   if (!fGL2PSAction) return false;             << 
669   if (fGL2PSAction->fileWritingEnabled()) {    << 
670     return true;                               << 
671   }                                            << 
672   return false;                                << 
673 }                                              << 
674                                                << 
675                                                << 
676 G4bool G4OpenGLViewer::isFramebufferReady() {  << 
677   bool check = false;                          << 
678 #ifdef G4VIS_BUILD_OPENGLQT_DRIVER             << 
679   check = true;                                << 
680 #endif                                         << 
681 #ifdef G4VIS_BUILD_OPENGLX_DRIVER              << 
682   check = false;                               << 
683 #endif                                         << 
684 #ifdef G4VIS_BUILD_OPENGLXM_DRIVER             << 
685   check = false;                               << 
686 #endif                                         << 
687 #ifdef G4VIS_BUILD_OPENGLWIN32_DRIVER          << 
688   check = false;                               << 
689 #endif                                         << 
690                                                << 
691 #if GL_ARB_framebuffer_object                  << 
692   if (check) {                                 << 
693 //    if ( glCheckFramebufferStatus(GL_FRAMEBU << 
694 //      return false;                          << 
695 //    }                                        << 
696   }                                            << 
697 #endif                                         << 
698     return true;                               << 
699 }                                              << 
700                                                << 
701                                                << 
702 /* Draw Gl2Ps text if needed                   << 
703  */                                            << 
704 void G4OpenGLViewer::DrawText(const G4Text& g4 << 
705 {                                              << 
706   // gl2ps or GL window ?                      << 
707   if (isGl2psWriting()) {                      << 
708                                                << 
709     G4VSceneHandler::MarkerSizeType sizeType;  << 
710     G4double size = fSceneHandler.GetMarkerSiz << 
711     G4Point3D position = g4text.GetPosition(); << 
712                                                << 
713     G4String textString = g4text.GetText();    << 
714                                                << 
715     glRasterPos3d(position.x(),position.y(),po << 
716     GLint align = GL2PS_TEXT_B;                << 
717                                                   402 
718     switch (g4text.GetLayout()) {              << 403   GLint returned;
719     case G4Text::left: align = GL2PS_TEXT_BL;  << 404   returned = glRenderMode (GL_RENDER);
720     case G4Text::centre: align = GL2PS_TEXT_B; << 405   
721     case G4Text::right: align = GL2PS_TEXT_BR; << 406   FILE* file;
                                                   >> 407   if (print_string) {
                                                   >> 408     file = fopen (print_string, "w");
                                                   >> 409     if (file) {
                                                   >> 410       spewWireframeEPS (file, returned, feedback_buffer, "rendereps");
                                                   >> 411     } else {
                                                   >> 412       printf("Could not open %s\n", print_string);
722     }                                             413     }
723                                                << 
724     fGL2PSAction->addTextOpt(textString.c_str( << 
725                                                << 
726   } else {                                        414   } else {
727                                                << 415     printBuffer (returned, feedback_buffer);
728     static G4int callCount = 0;                << 
729     ++callCount;                               << 
730     //if (callCount <= 10 || callCount%100 ==  << 
731     if (callCount <= 1) {                      << 
732       G4cout <<                                << 
733   "G4OpenGLViewer::DrawText: Not implemented f << 
734        << fName <<                             << 
735   "\"\n  Called with "                         << 
736        << g4text                               << 
737        << G4endl;                              << 
738     }                                          << 
739   }                                               416   }
740 }                                              << 
741                                                << 
742 /** Change PointSize on gl2ps if needed        << 
743  */                                            << 
744 void G4OpenGLViewer::ChangePointSize(G4double  << 
745                                                   417 
746   if (isGl2psWriting()) {                      << 418   delete[] feedback_buffer;
747     fGL2PSAction->setPointSize(int(size));     << 
748   } else {                                     << 
749     glPointSize (size);                        << 
750   }                                            << 
751 }                                                 419 }
752                                                   420 
                                                   >> 421 void G4OpenGLViewer::print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer)
                                                   >> 422 {
                                                   >> 423   G4int i;
753                                                   424 
754 /** Change LineSize on gl2ps if needed         << 425   printf("  ");
755  */                                            << 426   for (i = 0; i < 7; i++) {
756 void G4OpenGLViewer::ChangeLineWidth(G4double  << 427     printf("%4.2f ", buffer[size - (*count)]);
757                                                << 428     *count = *count - 1;
758   if (isGl2psWriting()) {                      << 
759     fGL2PSAction->setLineWidth(int(width));    << 
760   } else {                                     << 
761     glLineWidth (width);                       << 
762   }                                               429   }
                                                   >> 430   printf("\n");
763 }                                                 431 }
764                                                   432 
765 /**                                            << 433 void G4OpenGLViewer::spewWireframeEPS (FILE* file, GLint size, GLfloat* buffer, const char* cr) {
766  Export image with the given name with width a << 
767  Several cases :                               << 
768  If name is "", filename will have the default << 
769  If name is "toto.png", set the name to "toto" << 
770  If name is "toto", set the name to "toto" and << 
771    Will also add an incremented suffix at the  << 
772 */                                             << 
773 bool G4OpenGLViewer::exportImage(std::string n << 
774                                                   434 
775   if (! setExportFilename(name)) {             << 435   GLfloat EPS_GOURAUD_THRESHOLD=0.1;
776     return false;                              << 
777   }                                            << 
778                                                   436 
779   if ((width != -1) && (height != -1)) {       << 437   GLfloat clearColor[4], viewport[4];
780     setExportSize(width, height);              << 438   GLfloat lineWidth;
781   }                                            << 439   G4int i;
782                                                   440 
783   if (fExportImageFormat == "eps") {           << 441   glGetFloatv (GL_VIEWPORT, viewport);
784     fGL2PSAction->setExportImageFormat_EPS();  << 442   glGetFloatv (GL_COLOR_CLEAR_VALUE, clearColor);
785   } else if (fExportImageFormat == "ps") {     << 443   glGetFloatv (GL_LINE_WIDTH, &lineWidth);
786     fGL2PSAction->setExportImageFormat_PS();   << 444   glGetFloatv (GL_POINT_SIZE, &pointSize);
787   } else if (fExportImageFormat == "svg") {    << 
788     fGL2PSAction->setExportImageFormat_SVG();  << 
789   } else if (fExportImageFormat == "pdf") {    << 
790     fGL2PSAction->setExportImageFormat_PDF();  << 
791   } else {                                     << 
792     setExportImageFormat(fExportImageFormat,tr << 
793     return false;                              << 
794   }                                            << 
795                                                << 
796   bool res;                                    << 
797                                                   445 
798   // Change the LC_NUMERIC value in order to h << 446   fputs ("%!PS-Adobe-2.0 EPSF-2.0\n", file);
799   // This case is only useful for French, Cana << 447   fprintf (file, "%%%%Creator: %s (using OpenGL feedback)\n", cr);
800   size_t len = strlen(setlocale(LC_NUMERIC,NUL << 448   fprintf (file, "%%%%BoundingBox: %g %g %g %g\n", viewport[0], viewport[1], viewport[2], viewport[3]);
801   char* oldLocale = (char*)(malloc(len+1));    << 449   fputs ("%%EndComments\n", file);
802   if(oldLocale!=NULL) strncpy(oldLocale,setloc << 450   fputs ("\n", file);
803   setlocale(LC_NUMERIC,"C");                   << 451   fputs ("gsave\n", file);
                                                   >> 452   fputs ("\n", file);
804                                                   453 
805   if (((fExportImageFormat == "eps") || (fExpo << 454   fputs ("% the gouraudtriangle PostScript fragment below is free\n", file);
806     res = printNonVectoredEPS();               << 455   fputs ("% written by Frederic Delhoume (delhoume@ilog.fr)\n", file);
807   } else {                                     << 456   fprintf (file, "/threshold %g def\n", EPS_GOURAUD_THRESHOLD);
808     res = printVectoredEPS();                  << 457   for (i=0; gouraudtriangleEPS[i]; i++) {
                                                   >> 458     fprintf (file, "%s\n", gouraudtriangleEPS[i]);
809   }                                               459   }
810                                                   460 
811   // restore the local                         << 461   fprintf(file, "\n%g setlinewidth\n", lineWidth);
812   if (oldLocale) {                             << 462   
813     setlocale(LC_NUMERIC,oldLocale);           << 463   fprintf (file, "%g %g %g setrgbcolor\n", clearColor[0], clearColor[1], clearColor[2]);
814     free(oldLocale);                           << 464   fprintf (file, "%g %g %g %g rectfill\n\n", viewport[0], viewport[1], viewport[2], viewport[3]);
815   }                                            << 
816                                                << 
817   if (res == false) {                          << 
818     G4cerr << "Error saving file... " << getRe << 
819   } else {                                     << 
820     G4cout << "File " << getRealPrintFilename( << 
821                                                << 
822     // increment index if necessary            << 
823     if ( fExportFilenameIndex != -1) {         << 
824       fExportFilenameIndex++;                  << 
825     }                                          << 
826   }                                            << 
827                                                << 
828   return res;                                  << 
829 }                                              << 
830                                                << 
831                                                   465 
832 bool G4OpenGLViewer::printGl2PS() {            << 466   spewSortedFeedback (file, size, buffer);
833                                                   467 
834   int width = getRealExportWidth();            << 468   fputs ("grestore\n\n", file);
835   int height = getRealExportHeight();          << 469   fputs ("showpage\n", file);
836   bool res = true;                             << 
837                                                << 
838   // no need to redraw at each new primitive f << 
839   G4OpenGLSceneHandler& oglSceneHandler = dyna << 
840   G4OpenGLSceneHandler::FlushAction originalFl << 
841   oglSceneHandler.SetFlushAction(G4OpenGLScene << 
842                                                << 
843   if (!fGL2PSAction) return false;             << 
844                                                << 
845   fGL2PSAction->setFileName(getRealPrintFilena << 
846   // try to resize                             << 
847   int X = fWinSize_x;                          << 
848   int Y = fWinSize_y;                          << 
849                                                << 
850   fWinSize_x = width;                          << 
851   fWinSize_y = height;                         << 
852   // Laurent G. 16/03/10 : Not the good way to << 
853   // We should draw in a new offscreen context << 
854   // resizing and drawing in current window... << 
855   // This should be solve when we will do an o << 
856   // to render OpenGL                          << 
857   // See :                                     << 
858   // http://developer.apple.com/Mac/library/do << 
859   // http://www.songho.ca/opengl/gl_fbo.html   << 
860                                                << 
861    ResizeGLView();                             << 
862    bool extendBuffer = true;                   << 
863    bool endWriteAction = false;                << 
864    bool beginWriteAction = true;               << 
865    bool filePointerOk = true;                  << 
866    while ((extendBuffer) && (! endWriteAction) << 
867                                                << 
868      beginWriteAction = fGL2PSAction->enableFi << 
869      if(beginWriteAction) {                    << 
870        GLint vp[4];                            << 
871        ::glGetIntegerv(GL_VIEWPORT,vp);        << 
872        fGL2PSAction->setViewport(vp[0],vp[1],v << 
873        beginWriteAction = fGL2PSAction->beginP << 
874      }                                         << 
875                                                << 
876      // 3 cases :                              << 
877      // - true                                 << 
878      // - false && ! fGL2PSAction->fileWriting << 
879      // - false && fGL2PSAction->fileWritingEn << 
880                                                << 
881      filePointerOk = fGL2PSAction->fileWriting << 
882                                                << 
883      if (beginWriteAction) {                   << 
884                                                << 
885        // Set the viewport                     << 
886        // By default, we choose the line width << 
887        fGL2PSAction->setLineWidth(fGl2psDefaul << 
888        // By default, we choose the point size << 
889        fGL2PSAction->setPointSize(fGl2psDefaul << 
890                                                << 
891        DrawView ();                            << 
892                                                << 
893        endWriteAction = fGL2PSAction->endPage( << 
894        fGL2PSAction->disableFileWriting();     << 
895      }                                         << 
896      if (filePointerOk) {                      << 
897        if ((! endWriteAction) || (! beginWrite << 
898          extendBuffer = fGL2PSAction->extendBu << 
899        }                                       << 
900      }                                         << 
901    }                                           << 
902    fGL2PSAction->resetBufferSizeParameters();  << 
903                                                << 
904    if (!extendBuffer ) {                       << 
905      G4cerr << "ERROR: gl2ps buffer size is no << 
906      res = false;                              << 
907    }                                           << 
908    if (!beginWriteAction ) {                   << 
909      G4cerr << "ERROR: saving file "<<getRealP << 
910      res = false;                              << 
911    }                                           << 
912    if (!endWriteAction ) {                     << 
913      G4cerr << "gl2ps error. No output produce << 
914      res = false;                              << 
915    }                                           << 
916   fWinSize_x = X;                              << 
917   fWinSize_y = Y;                              << 
918                                                << 
919   oglSceneHandler.SetFlushAction(originalFlush << 
920                                                << 
921   // Reset for next time (useful is size chang << 
922   //  fPrintSizeX = 0;                         << 
923   //  fPrintSizeY = 0;                         << 
924                                                   470 
925   return res;                                  << 471   fclose(file);
926 }                                                 472 }
927                                                   473 
928 unsigned int G4OpenGLViewer::getWinWidth() con << 474 void G4OpenGLViewer::printBuffer (GLint size, GLfloat* buffer) {
929   return fWinSize_x;                           << 
930 }                                              << 
931                                                   475 
932 unsigned int G4OpenGLViewer::getWinHeight() co << 476   GLint count;
933   return fWinSize_y;                           << 477   G4int token, nvertices;
934 }                                              << 
935                                                   478 
936 G4bool G4OpenGLViewer::sizeHasChanged() {      << 479   count=size;
937   return fSizeHasChanged;                      << 480   while(count) {
938 }                                              << 481     token=G4int (buffer[size-count]);
                                                   >> 482     count--;
                                                   >> 483     switch (token) {
939                                                   484 
940 G4int G4OpenGLViewer::getRealExportWidth() {   << 485     case GL_PASS_THROUGH_TOKEN:
941   if (fPrintSizeX == -1) {                     << 486       printf ("GL_PASS_THROUGH_TOKEN\n");
942     return fWinSize_x;                         << 487       printf ("  %4.2f\n", buffer[size-count]);
943   }                                            << 488       count--;
944   GLint dims[2];                               << 489       break;
945   glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);   << 
946                                                   490 
947   // L.Garnier 01-2010: Some problems with mac << 491     case GL_POINT_TOKEN:
948   if ((dims[0] !=0 ) && (dims[1] !=0)) {       << 492       printf ("GL_POINT_TOKEN\n");
949     if (fPrintSizeX > dims[0]){                << 493       print3DcolorVertex (size, &count, buffer);
950       return dims[0];                          << 494       break;
951     }                                          << 
952   }                                            << 
953   if (fPrintSizeX < -1){                       << 
954     return 0;                                  << 
955   }                                            << 
956   return fPrintSizeX;                          << 
957 }                                              << 
958                                                   495 
959 G4int G4OpenGLViewer::getRealExportHeight() {  << 496     case GL_LINE_TOKEN:
960   if (fPrintSizeY == -1) {                     << 497       printf ("GL_LINE_TOKEN\n");
961     return fWinSize_y;                         << 498       print3DcolorVertex (size, &count, buffer);
962   }                                            << 499       print3DcolorVertex (size, &count, buffer);
963   GLint dims[2];                               << 500       break;
964   glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);   << 501       
                                                   >> 502     case GL_LINE_RESET_TOKEN:
                                                   >> 503       printf ("GL_LINE_RESET_TOKEN\n");
                                                   >> 504       print3DcolorVertex (size, &count, buffer);
                                                   >> 505       print3DcolorVertex (size, &count, buffer);
                                                   >> 506       break;
965                                                   507 
966   // L.Garnier 01-2010: Some problems with mac << 508     case GL_POLYGON_TOKEN:
967   if ((dims[0] !=0 ) && (dims[1] !=0)) {       << 509       printf ("GL_POLYGON_TOKEN\n");
968     if (fPrintSizeY > dims[1]){                << 510       nvertices=G4int (buffer[size-count]);
969       return dims[1];                          << 511       count--;
                                                   >> 512       for (; nvertices>0; nvertices--) {
                                                   >> 513   print3DcolorVertex (size, &count, buffer);
                                                   >> 514       }
970     }                                             515     }
971   }                                               516   }
972   if (fPrintSizeY < -1){                       << 
973     return 0;                                  << 
974   }                                            << 
975   return fPrintSizeY;                          << 
976 }                                              << 
977                                                << 
978 void G4OpenGLViewer::setExportSize(G4int X, G4 << 
979   fPrintSizeX = X;                             << 
980   fPrintSizeY = Y;                             << 
981 }                                                 517 }
982                                                   518 
983 /**                                            << 519 G4float* G4OpenGLViewer::spewPrimitiveEPS (FILE* file, GLfloat* loc) {
984  If name is "" or "!", filename and extension  << 520   
985  If name is "toto.png", set the name to "toto" << 521   G4int token;
986  If name is "toto", set the name to "toto" and << 522   G4int nvertices, i;
987  If name is the same as previous, do not reset << 523   GLfloat red, green, blue, intensity;
988 */                                             << 524   G4int smooth;
989 bool G4OpenGLViewer::setExportFilename(G4Strin << 525   GLfloat dx, dy, dr, dg, db, absR, absG, absB, colormax;
990   if (name == "!") {                           << 526   G4int steps;
991     name = "";                                 << 527   Feedback3Dcolor *vertex;
992   }                                            << 528   GLfloat xstep(0.), ystep(0.), rstep(0.), gstep(0.), bstep(0.);
                                                   >> 529   GLfloat xnext(0.), ynext(0.), rnext(0.), gnext(0.), bnext(0.), distance(0.);
                                                   >> 530 
                                                   >> 531   token=G4int (*loc);
                                                   >> 532   loc++;
                                                   >> 533   switch (token) {
                                                   >> 534   case GL_LINE_RESET_TOKEN:
                                                   >> 535   case GL_LINE_TOKEN:
                                                   >> 536     vertex=(Feedback3Dcolor*)loc;
                                                   >> 537     dr=vertex[1].red - vertex[0].red;
                                                   >> 538     dg=vertex[1].green - vertex[0].green;
                                                   >> 539     db=vertex[1].blue - vertex[0].blue;
                                                   >> 540 
                                                   >> 541     if (!print_colour) {
                                                   >> 542       dr+=(dg+db);
                                                   >> 543       dr/=3.0;
                                                   >> 544       dg=dr;
                                                   >> 545       db=dr;
                                                   >> 546     }
                                                   >> 547 
                                                   >> 548     if (dr!=0 || dg!=0 || db!=0) {
                                                   >> 549       dx=vertex[1].x - vertex[0].x;
                                                   >> 550       dy=vertex[1].y - vertex[0].y;
                                                   >> 551       distance=std::sqrt(dx*dx + dy*dy);
                                                   >> 552 
                                                   >> 553       absR=std::fabs(dr);
                                                   >> 554       absG=std::fabs(dg);
                                                   >> 555       absB=std::fabs(db);
                                                   >> 556 
                                                   >> 557       #define Max(a, b) (((a)>(b))?(a):(b))
                                                   >> 558 
                                                   >> 559       #define EPS_SMOOTH_LINE_FACTOR 0.06
                                                   >> 560 
                                                   >> 561       colormax=Max(absR, Max(absG, absB));
                                                   >> 562       steps=Max(1, G4int (colormax*distance*EPS_SMOOTH_LINE_FACTOR));
                                                   >> 563       
                                                   >> 564       xstep=dx/steps;
                                                   >> 565       ystep=dy/steps;
                                                   >> 566 
                                                   >> 567       rstep=dr/steps;
                                                   >> 568       gstep=dg/steps;
                                                   >> 569       bstep=db/steps;
                                                   >> 570 
                                                   >> 571       xnext=vertex[0].x;
                                                   >> 572       ynext=vertex[0].y;
                                                   >> 573       rnext=vertex[0].red;
                                                   >> 574       gnext=vertex[0].green;
                                                   >> 575       bnext=vertex[0].blue;
                                                   >> 576 
                                                   >> 577       if (!print_colour) {
                                                   >> 578   rnext+=(gnext+bnext);
                                                   >> 579   rnext/=3.0;
                                                   >> 580   gnext=rnext;
                                                   >> 581   bnext=rnext;
                                                   >> 582       }
993                                                   583 
994   if (inc) {                                   << 584       xnext -= xstep/2.0;
995     if ((name != "") && (fExportFilename != na << 585       ynext -= ystep/2.0;
996       fExportFilenameIndex=0;                  << 586       rnext -= rstep/2.0;
                                                   >> 587       gnext -= gstep/2.0;
                                                   >> 588       bnext -= bstep/2.0;
                                                   >> 589     } else {
                                                   >> 590       steps=0;
997     }                                             591     }
998   } else {                                     << 592     if (print_colour) {
999     fExportFilenameIndex=-1;                   << 593       fprintf (file, "%g %g %g setrgbcolor\n",
1000   }                                           << 594          vertex[0].red, vertex[0].green, vertex[0].blue);
                                                   >> 595     } else {
                                                   >> 596       intensity = (vertex[0].red + vertex[0].green + vertex[0].blue) / 3.0;
                                                   >> 597       fprintf (file, "%g %g %g setrgbcolor\n",
                                                   >> 598          intensity, intensity, intensity);
                                                   >> 599     }      
                                                   >> 600     fprintf (file, "%g %g moveto\n", vertex[0].x, vertex[0].y);
                                                   >> 601 
                                                   >> 602     for (i=0; i<steps; i++) {
                                                   >> 603 
                                                   >> 604       xnext += xstep;
                                                   >> 605       ynext += ystep;
                                                   >> 606       rnext += rstep;
                                                   >> 607       gnext += gstep;
                                                   >> 608       bnext += bstep;
                                                   >> 609 
                                                   >> 610       fprintf (file, "%g %g lineto stroke\n", xnext, ynext);
                                                   >> 611       fprintf (file, "%g %g %g setrgbcolor\n", rnext, gnext, bnext);
                                                   >> 612       fprintf (file, "%g %g moveto\n", xnext, ynext);
                                                   >> 613     }
                                                   >> 614     fprintf (file, "%g %g lineto stroke\n", vertex[1].x, vertex[1].y);
                                                   >> 615 
                                                   >> 616     loc += 14;
                                                   >> 617     break;
                                                   >> 618 
                                                   >> 619   case GL_POLYGON_TOKEN:
                                                   >> 620     nvertices = G4int (*loc);
                                                   >> 621     loc++;
                                                   >> 622     vertex=(Feedback3Dcolor*)loc;
                                                   >> 623     if (nvertices>0) {
                                                   >> 624       red=vertex[0].red;
                                                   >> 625       green=vertex[0].green;
                                                   >> 626       blue=vertex[0].blue;
                                                   >> 627       smooth=0;
                                                   >> 628       
                                                   >> 629       if (!print_colour) {
                                                   >> 630   red+=(green+blue);
                                                   >> 631   red/=3.0;
                                                   >> 632   green=red;
                                                   >> 633   blue=red;
                                                   >> 634       }
                                                   >> 635       
                                                   >> 636       if (print_colour) {
                                                   >> 637   for (i=1; i<nvertices; i++) {
                                                   >> 638     if (red!=vertex[i].red || green!=vertex[i].green || blue!=vertex[i].blue) {
                                                   >> 639       smooth=1;
                                                   >> 640       break;
                                                   >> 641     }
                                                   >> 642   }
                                                   >> 643       } else {
                                                   >> 644   for (i=1; i<nvertices; i++) {
                                                   >> 645     intensity = vertex[i].red + vertex[i].green + vertex[i].blue;
                                                   >> 646     intensity/=3.0;
                                                   >> 647     if (red!=intensity) {
                                                   >> 648       smooth=1;
                                                   >> 649       break;
                                                   >> 650     }
                                                   >> 651   }
                                                   >> 652       }
1001                                                  653 
1002   if (name.size() == 0) {                     << 654       if (smooth) {
1003     name = getRealPrintFilename().c_str();    << 655   G4int triOffset;
1004   } else {                                    << 656   for (i=0; i<nvertices-2; i++) {
1005     // guess format by extention              << 657     triOffset = i*7;
1006     std::string extension = name.substr(name. << 658     fprintf (file, "[%g %g %g %g %g %g]",
1007     // If there is a dot in the name the abov << 659        vertex[0].x, vertex[i+1].x, vertex[i+2].x,
1008     if (extension.size() >= 3 && extension.si << 660        vertex[0].y, vertex[i+1].y, vertex[i+2].y);
1009       if (setExportImageFormat(extension, fal << 661     if (print_colour) {
1010         fExportFilename = name.substr(0,name. << 662       fprintf (file, " [%g %g %g] [%g %g %g] [%g %g %g] gouraudtriangle\n",
1011       } else {  // No viable extension found  << 663          vertex[0].red, vertex[0].green, vertex[0].blue,
1012         return false;                         << 664          vertex[i+1].red, vertex[i+1].green, vertex[i+1].blue,
                                                   >> 665          vertex[i+2].red, vertex[i+2].green, vertex[i+2].blue);
                                                   >> 666     } else {
                                                   >> 667 
                                                   >> 668       intensity = vertex[0].red + vertex[0].green + vertex[0].blue;
                                                   >> 669       intensity/=3.0;
                                                   >> 670       fprintf (file, " [%g %g %g]", intensity, intensity, intensity);
                                                   >> 671 
                                                   >> 672       intensity = vertex[1].red + vertex[1].green + vertex[1].blue;
                                                   >> 673       intensity/=3.0;
                                                   >> 674       fprintf (file, " [%g %g %g]", intensity, intensity, intensity);
                                                   >> 675 
                                                   >> 676       intensity = vertex[2].red + vertex[2].green + vertex[2].blue;
                                                   >> 677       intensity/=3.0;
                                                   >> 678       fprintf (file, " [%g %g %g] gouraudtriangle\n", intensity, intensity, intensity);
                                                   >> 679     }
                                                   >> 680   }
                                                   >> 681       } else {
                                                   >> 682   fprintf (file, "newpath\n");
                                                   >> 683   fprintf (file, "%g %g %g setrgbcolor\n", red, green, blue);
                                                   >> 684   fprintf (file, "%g %g moveto\n", vertex[0].x, vertex[0].y);
                                                   >> 685   for (i=1; i<nvertices; i++) {
                                                   >> 686     fprintf (file, "%g %g lineto\n", vertex[i].x, vertex[i].y);
                                                   >> 687   }
                                                   >> 688   fprintf (file, "closepath fill\n\n");
1013       }                                          689       }
1014     } else {  // Assume name is already the r << 
1015         fExportFilename = name;               << 
1016     }                                            690     }
1017   }                                           << 691     loc += nvertices*7;
1018   return true;                                << 692     break;
1019 }                                             << 
1020                                                  693 
1021 std::string G4OpenGLViewer::getRealPrintFilen << 694   case GL_POINT_TOKEN:
1022   std::string temp = fExportFilename;         << 695     vertex=(Feedback3Dcolor*)loc;
1023   if (fExportFilenameIndex != -1) {           << 696     if (print_colour) {
1024     temp += std::string("_");                 << 697       fprintf (file, "%g %g %g setrgbcolor\n", vertex[0].red, vertex[0].green, vertex[0].blue);
1025     std::ostringstream os;                    << 698     } else {
1026     os << std::setw(4) << std::setfill('0') < << 699       intensity = vertex[0].red + vertex[0].green + vertex[0].blue;
1027     std::string nb_str = os.str();            << 700       intensity/=3.0;
1028     temp += nb_str;                           << 701       fprintf (file, "%g %g %g setrgbcolor\n", intensity, intensity, intensity);
                                                   >> 702     }      
                                                   >> 703     fprintf(file, "%g %g %g 0 360 arc fill\n\n", vertex[0].x, vertex[0].y, pointSize / 2.0);
                                                   >> 704     loc += 7;           /* Each vertex element in the feedback
                                                   >> 705                            buffer is 7 GLfloats. */
                                                   >> 706     break;
                                                   >> 707   default:
                                                   >> 708     /* XXX Left as an excersie to the reader. */
                                                   >> 709     static G4bool spewPrimitiveEPSWarned = false;
                                                   >> 710     if (!spewPrimitiveEPSWarned) {
                                                   >> 711       std::ostringstream oss;
                                                   >> 712       oss <<
                                                   >> 713   "Incomplete implementation.  Unexpected token (" << token << ")."
                                                   >> 714   "\n  (Seems to be caused by text.)";
                                                   >> 715       G4Exception("G4OpenGLViewer::spewPrimitiveEPS",
                                                   >> 716       "Unexpected token",
                                                   >> 717       JustWarning,
                                                   >> 718       oss.str().c_str());
                                                   >> 719       spewPrimitiveEPSWarned = true;
                                                   >> 720     }
                                                   >> 721   }
                                                   >> 722   return loc;
                                                   >> 723 }
                                                   >> 724 
                                                   >> 725 typedef struct G4OpenGLViewerDepthIndex {
                                                   >> 726   GLfloat *ptr;
                                                   >> 727   GLfloat depth;
                                                   >> 728 } DepthIndex;
                                                   >> 729 
                                                   >> 730 extern "C" {
                                                   >> 731   int G4OpenGLViewercompare(const void *a, const void *b)
                                                   >> 732   {
                                                   >> 733     const DepthIndex *p1 = (DepthIndex *) a;
                                                   >> 734     const DepthIndex *p2 = (DepthIndex *) b;
                                                   >> 735     GLfloat diff = p2->depth - p1->depth;
                                                   >> 736     
                                                   >> 737     if (diff > 0.0) {
                                                   >> 738       return 1;
                                                   >> 739     } else if (diff < 0.0) {
                                                   >> 740       return -1;
                                                   >> 741     } else {
                                                   >> 742       return 0;
                                                   >> 743     }
1029   }                                              744   }
1030   temp += "."+fExportImageFormat;             << 
1031   return temp;                                << 
1032 }                                                745 }
1033                                                  746 
1034 GLdouble G4OpenGLViewer::getSceneNearWidth()     747 GLdouble G4OpenGLViewer::getSceneNearWidth()
1035 {                                                748 {
1036   if (!fSceneHandler.GetScene()) {            << 
1037     return 0;                                 << 
1038   }                                           << 
1039   const G4Point3D targetPoint                    749   const G4Point3D targetPoint
1040     = fSceneHandler.GetScene()->GetStandardTa    750     = fSceneHandler.GetScene()->GetStandardTargetPoint()
1041     + fVP.GetCurrentTargetPoint ();              751     + fVP.GetCurrentTargetPoint ();
1042   G4double radius = fSceneHandler.GetScene()-    752   G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1043   if(radius<=0.) radius = 1.;                    753   if(radius<=0.) radius = 1.;
1044   const G4double cameraDistance = fVP.GetCame    754   const G4double cameraDistance = fVP.GetCameraDistance (radius);
1045   const GLdouble pnear   = fVP.GetNearDistanc    755   const GLdouble pnear   = fVP.GetNearDistance (cameraDistance, radius);
1046   return 2 * fVP.GetFrontHalfHeight (pnear, r    756   return 2 * fVP.GetFrontHalfHeight (pnear, radius);
1047 }                                                757 }
1048                                                  758 
1049 GLdouble G4OpenGLViewer::getSceneFarWidth()      759 GLdouble G4OpenGLViewer::getSceneFarWidth()
1050 {                                                760 {
1051   if (!fSceneHandler.GetScene()) {            << 
1052     return 0;                                 << 
1053   }                                           << 
1054   const G4Point3D targetPoint                    761   const G4Point3D targetPoint
1055     = fSceneHandler.GetScene()->GetStandardTa    762     = fSceneHandler.GetScene()->GetStandardTargetPoint()
1056     + fVP.GetCurrentTargetPoint ();              763     + fVP.GetCurrentTargetPoint ();
1057   G4double radius = fSceneHandler.GetScene()-    764   G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1058   if(radius<=0.) radius = 1.;                    765   if(radius<=0.) radius = 1.;
1059   const G4double cameraDistance = fVP.GetCame    766   const G4double cameraDistance = fVP.GetCameraDistance (radius);
1060   const GLdouble pnear   = fVP.GetNearDistanc    767   const GLdouble pnear   = fVP.GetNearDistance (cameraDistance, radius);
1061   const GLdouble pfar    = fVP.GetFarDistance    768   const GLdouble pfar    = fVP.GetFarDistance  (cameraDistance, pnear, radius);
1062   return 2 * fVP.GetFrontHalfHeight (pfar, ra    769   return 2 * fVP.GetFrontHalfHeight (pfar, radius);
1063 }                                                770 }
1064                                                  771 
1065                                                  772 
1066 GLdouble G4OpenGLViewer::getSceneDepth()         773 GLdouble G4OpenGLViewer::getSceneDepth()
1067 {                                                774 {
1068   if (!fSceneHandler.GetScene()) {            << 
1069     return 0;                                 << 
1070   }                                           << 
1071   const G4Point3D targetPoint                    775   const G4Point3D targetPoint
1072     = fSceneHandler.GetScene()->GetStandardTa    776     = fSceneHandler.GetScene()->GetStandardTargetPoint()
1073     + fVP.GetCurrentTargetPoint ();              777     + fVP.GetCurrentTargetPoint ();
1074   G4double radius = fSceneHandler.GetScene()-    778   G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1075   if(radius<=0.) radius = 1.;                    779   if(radius<=0.) radius = 1.;
1076   const G4double cameraDistance = fVP.GetCame    780   const G4double cameraDistance = fVP.GetCameraDistance (radius);
1077   const GLdouble pnear   = fVP.GetNearDistanc    781   const GLdouble pnear   = fVP.GetNearDistance (cameraDistance, radius);
1078   return fVP.GetFarDistance  (cameraDistance,    782   return fVP.GetFarDistance  (cameraDistance, pnear, radius)- pnear;
1079 }                                                783 }
1080                                                  784 
1081                                                  785 
1082                                               << 786 void G4OpenGLViewer::spewSortedFeedback(FILE * file, GLint size, GLfloat * buffer)
1083 void G4OpenGLViewer::rotateScene(G4double dx, << 
1084 {                                                787 {
1085   if (fVP.GetRotationStyle() == G4ViewParamet << 788   int token;
1086     rotateSceneInViewDirection(dx,dy);        << 789   GLfloat *loc, *end;
1087   } else {                                    << 790   Feedback3Dcolor *vertex;
1088     if( dx != 0) {                            << 791   GLfloat depthSum;
1089       rotateSceneThetaPhi(dx,0);              << 792   int nprimitives, item;
1090     }                                         << 793   DepthIndex *prims;
1091     if( dy != 0) {                            << 794   int nvertices, i;
1092       rotateSceneThetaPhi(0,dy);              << 795 
                                                   >> 796   end = buffer + size;
                                                   >> 797 
                                                   >> 798   /* Count how many primitives there are. */
                                                   >> 799   nprimitives = 0;
                                                   >> 800   loc = buffer;
                                                   >> 801   while (loc < end) {
                                                   >> 802     token = int (*loc);
                                                   >> 803     loc++;
                                                   >> 804     switch (token) {
                                                   >> 805     case GL_LINE_TOKEN:
                                                   >> 806     case GL_LINE_RESET_TOKEN:
                                                   >> 807       loc += 14;
                                                   >> 808       nprimitives++;
                                                   >> 809       break;
                                                   >> 810     case GL_POLYGON_TOKEN:
                                                   >> 811       nvertices = int (*loc);
                                                   >> 812       loc++;
                                                   >> 813       loc += (7 * nvertices);
                                                   >> 814       nprimitives++;
                                                   >> 815       break;
                                                   >> 816     case GL_POINT_TOKEN:
                                                   >> 817       loc += 7;
                                                   >> 818       nprimitives++;
                                                   >> 819       break;
                                                   >> 820     default:
                                                   >> 821       /* XXX Left as an excersie to the reader. */
                                                   >> 822       static G4bool spewSortedFeedbackWarned = false;
                                                   >> 823       if (!spewSortedFeedbackWarned) {
                                                   >> 824   std::ostringstream oss;
                                                   >> 825   oss <<
                                                   >> 826     "Incomplete implementation.  Unexpected token (" << token << ")."
                                                   >> 827     "\n  (Seems to be caused by text.)";
                                                   >> 828   G4Exception("G4OpenGLViewer::spewSortedFeedback",
                                                   >> 829         "Unexpected token",
                                                   >> 830         JustWarning,
                                                   >> 831         oss.str().c_str());
                                                   >> 832   spewSortedFeedbackWarned = true;
                                                   >> 833       }
                                                   >> 834       nprimitives++;
1093     }                                            835     }
1094   }                                              836   }
1095 }                                             << 
1096                                               << 
1097                                                  837 
1098 void G4OpenGLViewer::rotateSceneToggle(G4doub << 838   /* Allocate an array of pointers that will point back at
1099 {                                             << 839      primitives in the feedback buffer.  There will be one
1100   if (fVP.GetRotationStyle() != G4ViewParamet << 840      entry per primitive.  This array is also where we keep the
1101     rotateSceneInViewDirection(dx,dy);        << 841      primitive's average depth.  There is one entry per
1102   } else {                                    << 842      primitive  in the feedback buffer. */
1103     if( dx != 0) {                            << 843   prims = (DepthIndex *) malloc(sizeof(DepthIndex) * nprimitives);
1104       rotateSceneThetaPhi(dx,0);              << 844 
1105     }                                         << 845   item = 0;
1106     if( dy != 0) {                            << 846   loc = buffer;
1107       rotateSceneThetaPhi(0,dy);              << 847   while (loc < end) {
1108     }                                         << 848     prims[item].ptr = loc;  /* Save this primitive's location. */
                                                   >> 849     token = int (*loc);
                                                   >> 850     loc++;
                                                   >> 851     switch (token) {
                                                   >> 852     case GL_LINE_TOKEN:
                                                   >> 853     case GL_LINE_RESET_TOKEN:
                                                   >> 854       vertex = (Feedback3Dcolor *) loc;
                                                   >> 855       depthSum = vertex[0].z + vertex[1].z;
                                                   >> 856       prims[item].depth = depthSum / 2.0;
                                                   >> 857       loc += 14;
                                                   >> 858       break;
                                                   >> 859     case GL_POLYGON_TOKEN:
                                                   >> 860       nvertices = int (*loc);
                                                   >> 861       loc++;
                                                   >> 862       vertex = (Feedback3Dcolor *) loc;
                                                   >> 863       depthSum = vertex[0].z;
                                                   >> 864       for (i = 1; i < nvertices; i++) {
                                                   >> 865         depthSum += vertex[i].z;
                                                   >> 866       }
                                                   >> 867       prims[item].depth = depthSum / nvertices;
                                                   >> 868       loc += (7 * nvertices);
                                                   >> 869       break;
                                                   >> 870     case GL_POINT_TOKEN:
                                                   >> 871       vertex = (Feedback3Dcolor *) loc;
                                                   >> 872       prims[item].depth = vertex[0].z;
                                                   >> 873       loc += 7;
                                                   >> 874       break;
                                                   >> 875     default:
                                                   >> 876       /* XXX Left as an excersie to the reader. */
                                                   >> 877       assert(1);
                                                   >> 878     }
                                                   >> 879     item++;
                                                   >> 880   }
                                                   >> 881   assert(item == nprimitives);
                                                   >> 882 
                                                   >> 883   /* Sort the primitives back to front. */
                                                   >> 884   qsort(prims, nprimitives, sizeof(DepthIndex), G4OpenGLViewercompare);
                                                   >> 885 
                                                   >> 886   /* Understand that sorting by a primitives average depth
                                                   >> 887      doesn't allow us to disambiguate some cases like self
                                                   >> 888      intersecting polygons.  Handling these cases would require
                                                   >> 889      breaking up the primitives.  That's too involved for this
                                                   >> 890      example.  Sorting by depth is good enough for lots of
                                                   >> 891      applications. */
                                                   >> 892 
                                                   >> 893   /* Emit the Encapsulated PostScript for the primitives in
                                                   >> 894      back to front order. */
                                                   >> 895   for (item = 0; item < nprimitives; item++) {
                                                   >> 896     (void) spewPrimitiveEPS(file, prims[item].ptr);
1109   }                                              897   }
                                                   >> 898 
                                                   >> 899   free(prims);
1110 }                                                900 }
1111                                                  901 
1112 void G4OpenGLViewer::rotateSceneThetaPhi(G4do << 902 void G4OpenGLViewer::rotateScene(G4double dx, G4double dy,G4double deltaRotation)
1113 {                                                903 {
1114   if (!fSceneHandler.GetScene()) {            << 
1115     return;                                   << 
1116   }                                           << 
1117                                                  904 
1118   G4Vector3D vp;                                 905   G4Vector3D vp;
1119   G4Vector3D up;                                 906   G4Vector3D up;
1120                                                  907   
1121   G4Vector3D xprime;                             908   G4Vector3D xprime;
1122   G4Vector3D yprime;                             909   G4Vector3D yprime;
1123   G4Vector3D zprime;                             910   G4Vector3D zprime;
1124                                                  911   
1125   G4double delta_alpha;                          912   G4double delta_alpha;
1126   G4double delta_theta;                          913   G4double delta_theta;
1127                                                  914   
1128   G4Vector3D new_vp;                             915   G4Vector3D new_vp;
1129   G4Vector3D new_up;                             916   G4Vector3D new_up;
1130                                                  917   
1131   G4double cosalpha;                             918   G4double cosalpha;
1132   G4double sinalpha;                             919   G4double sinalpha;
1133                                                  920   
1134   G4Vector3D a1;                                 921   G4Vector3D a1;
1135   G4Vector3D a2;                                 922   G4Vector3D a2;
1136   G4Vector3D delta;                              923   G4Vector3D delta;
1137   G4Vector3D viewPoint;                          924   G4Vector3D viewPoint;
1138                                                  925 
1139                                                  926     
1140   //phi spin stuff here                          927   //phi spin stuff here
1141                                                  928   
1142   vp = fVP.GetViewpointDirection ().unit ();     929   vp = fVP.GetViewpointDirection ().unit ();
1143   up = fVP.GetUpVector ().unit ();               930   up = fVP.GetUpVector ().unit ();
1144                                                  931   
1145   yprime = (up.cross(vp)).unit();                932   yprime = (up.cross(vp)).unit();
1146   zprime = (vp.cross(yprime)).unit();            933   zprime = (vp.cross(yprime)).unit();
1147                                                  934   
1148   if (fVP.GetLightsMoveWithCamera()) {           935   if (fVP.GetLightsMoveWithCamera()) {
1149     delta_alpha = dy * fRot_sens;             << 936     delta_alpha = dy * deltaRotation;
1150     delta_theta = -dx * fRot_sens;            << 937     delta_theta = -dx * deltaRotation;
1151   } else {                                       938   } else {
1152     delta_alpha = -dy * fRot_sens;            << 939     delta_alpha = -dy * deltaRotation;
1153     delta_theta = dx * fRot_sens;             << 940     delta_theta = dx * deltaRotation;
1154   }                                              941   }    
1155                                                  942   
1156   delta_alpha *= CLHEP::deg;                  << 943   delta_alpha *= deg;
1157   delta_theta *= CLHEP::deg;                  << 944   delta_theta *= deg;
1158                                                  945   
1159   new_vp = std::cos(delta_alpha) * vp + std::    946   new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
1160                                                  947   
1161   // to avoid z rotation flipping                948   // to avoid z rotation flipping
1162   // to allow more than 360° rotation        << 949   // to allow more than 360° rotation
                                                   >> 950 
                                                   >> 951   const G4Point3D targetPoint
                                                   >> 952     = fSceneHandler.GetScene()->GetStandardTargetPoint()
                                                   >> 953     + fVP.GetCurrentTargetPoint ();
                                                   >> 954   G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
                                                   >> 955   if(radius<=0.) radius = 1.;
                                                   >> 956   const G4double cameraDistance = fVP.GetCameraDistance (radius);
                                                   >> 957   const G4Point3D cameraPosition =
                                                   >> 958     targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
1163                                                  959 
1164   if (fVP.GetLightsMoveWithCamera()) {           960   if (fVP.GetLightsMoveWithCamera()) {
1165     new_up = (new_vp.cross(yprime)).unit();      961     new_up = (new_vp.cross(yprime)).unit();
1166     if (new_vp.z()*vp.z() <0) {                  962     if (new_vp.z()*vp.z() <0) {
1167       new_up.set(new_up.x(),-new_up.y(),new_u    963       new_up.set(new_up.x(),-new_up.y(),new_up.z());
1168     }                                            964     }
1169   } else {                                       965   } else {
1170     new_up = up;                                 966     new_up = up;
1171     if (new_vp.z()*vp.z() <0) {                  967     if (new_vp.z()*vp.z() <0) {
1172       new_up.set(new_up.x(),-new_up.y(),new_u    968       new_up.set(new_up.x(),-new_up.y(),new_up.z());
1173     }                                            969     }
1174   }                                              970   }
1175   fVP.SetUpVector(new_up);                       971   fVP.SetUpVector(new_up);
1176   ////////////////                               972   ////////////////
1177   // Rotates by fixed azimuthal angle delta_t    973   // Rotates by fixed azimuthal angle delta_theta.
1178                                                  974   
1179   cosalpha = new_up.dot (new_vp.unit());         975   cosalpha = new_up.dot (new_vp.unit());
1180   sinalpha = std::sqrt (1. - std::pow (cosalp    976   sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
1181   yprime = (new_up.cross (new_vp.unit())).uni    977   yprime = (new_up.cross (new_vp.unit())).unit ();
1182   xprime = yprime.cross (new_up);                978   xprime = yprime.cross (new_up);
1183   // Projection of vp on plane perpendicular     979   // Projection of vp on plane perpendicular to up...
1184   a1 = sinalpha * xprime;                        980   a1 = sinalpha * xprime;
1185   // Required new projection...                  981   // Required new projection...
1186   a2 = sinalpha * (std::cos (delta_theta) * x    982   a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
1187   // Required Increment vector...                983   // Required Increment vector...
1188   delta = a2 - a1;                               984   delta = a2 - a1;
1189   // So new viewpoint is...                      985   // So new viewpoint is...
1190   viewPoint = new_vp.unit() + delta;             986   viewPoint = new_vp.unit() + delta;
1191                                                  987   
1192   fVP.SetViewAndLights (viewPoint);              988   fVP.SetViewAndLights (viewPoint);
1193 }                                                989 }
1194                                                  990 
1195                                               << 991 #endif
1196 void G4OpenGLViewer::rotateSceneInViewDirecti << 
1197 {                                             << 
1198   if (!fSceneHandler.GetScene()) {            << 
1199     return;                                   << 
1200   }                                           << 
1201                                               << 
1202   G4Vector3D vp;                              << 
1203   G4Vector3D up;                              << 
1204                                               << 
1205   G4Vector3D xprime;                          << 
1206   G4Vector3D yprime;                          << 
1207   G4Vector3D zprime;                          << 
1208                                               << 
1209   G4Vector3D new_vp;                          << 
1210   G4Vector3D new_up;                          << 
1211                                               << 
1212   G4Vector3D a1;                              << 
1213   G4Vector3D a2;                              << 
1214   G4Vector3D delta;                           << 
1215   G4Vector3D viewPoint;                       << 
1216                                               << 
1217   dx = dx/100;                                << 
1218   dy = dy/100;                                << 
1219                                               << 
1220   //phi spin stuff here                       << 
1221                                               << 
1222   vp = fVP.GetViewpointDirection ().unit();   << 
1223   up = fVP.GetUpVector ().unit();             << 
1224                                               << 
1225   G4Vector3D zPrimeVector = G4Vector3D(up.y() << 
1226                              up.z()*vp.x()-up << 
1227                              up.x()*vp.y()-up << 
1228                                               << 
1229   viewPoint = vp/fRot_sens + (zPrimeVector*dx << 
1230   new_up = G4Vector3D(viewPoint.y()*zPrimeVec << 
1231                        viewPoint.z()*zPrimeVe << 
1232                        viewPoint.x()*zPrimeVe << 
1233                                               << 
1234   G4Vector3D new_upUnit = new_up.unit();      << 
1235                                               << 
1236                                               << 
1237                                               << 
1238    fVP.SetUpVector(new_upUnit);               << 
1239    fVP.SetViewAndLights (viewPoint);          << 
1240 }                                             << 
1241                                               << 
1242                                               << 
1243 void G4OpenGLViewer::addExportImageFormat(std << 
1244   fExportImageFormatVector.push_back(format); << 
1245 }                                             << 
1246                                               << 
1247 bool G4OpenGLViewer::setExportImageFormat(std << 
1248   bool found = false;                         << 
1249   std::string list;                           << 
1250   for (unsigned int a=0; a<fExportImageFormat << 
1251     list +=fExportImageFormatVector.at(a) + " << 
1252                                               << 
1253     if (fExportImageFormatVector.at(a) == for << 
1254       if (! quiet) {                          << 
1255         G4cout << " Changing export format to << 
1256       }                                       << 
1257       if (format != fExportImageFormat) {     << 
1258         fExportFilenameIndex = 0;             << 
1259         fExportImageFormat = format;          << 
1260       }                                       << 
1261       return true;                            << 
1262     }                                         << 
1263   }                                           << 
1264   if (! found) {                              << 
1265     if (format.size() == 0) {                 << 
1266       G4cout << " Current formats availables  << 
1267     } else {                                  << 
1268       G4cerr << " Format \"" << format << "\" << 
1269     }                                         << 
1270   }                                           << 
1271   return false;                               << 
1272 }                                             << 
1273                                               << 
1274                                               << 
1275 // From MESA implementation :                 << 
1276 // http://www.techques.com/question/1-8660454 << 
1277                                               << 
1278 void G4OpenGLViewer::g4GluPickMatrix(GLdouble << 
1279                      GLint viewport[4])       << 
1280   {                                           << 
1281     GLdouble mat[16];                         << 
1282     GLdouble sx, sy;                          << 
1283     GLdouble tx, ty;                          << 
1284                                               << 
1285     sx = viewport[2] / width;                 << 
1286     sy = viewport[3] / height;                << 
1287     tx = (viewport[2] + 2.0 * (viewport[0] -  << 
1288     ty = (viewport[3] + 2.0 * (viewport[1] -  << 
1289                                               << 
1290 #define M(row, col) mat[col*4+row]            << 
1291     M(0, 0) = sx;                             << 
1292     M(0, 1) = 0.0;                            << 
1293     M(0, 2) = 0.0;                            << 
1294     M(0, 3) = tx;                             << 
1295     M(1, 0) = 0.0;                            << 
1296     M(1, 1) = sy;                             << 
1297     M(1, 2) = 0.0;                            << 
1298     M(1, 3) = ty;                             << 
1299     M(2, 0) = 0.0;                            << 
1300     M(2, 1) = 0.0;                            << 
1301     M(2, 2) = 1.0;                            << 
1302     M(2, 3) = 0.0;                            << 
1303     M(3, 0) = 0.0;                            << 
1304     M(3, 1) = 0.0;                            << 
1305     M(3, 2) = 0.0;                            << 
1306     M(3, 3) = 1.0;                            << 
1307 #undef M                                      << 
1308                                               << 
1309     glMultMatrixd(mat);                       << 
1310 }                                             << 
1311                                               << 
1312                                               << 
1313                                               << 
1314                                               << 
1315                                               << 
1316 // From MESA implementation :                 << 
1317 // https://github.com/jlamarche/iOS-OpenGLES- << 
1318 // or http://www.daniweb.com/software-develop << 
1319                                               << 
1320 void G4OpenGLViewer::g4GluLookAt( GLdouble ey << 
1321                         GLdouble centerx, GLd << 
1322                         centerz,              << 
1323                         GLdouble upx, GLdoubl << 
1324 {                                             << 
1325   GLdouble mat[16];                           << 
1326   GLdouble x[3], y[3], z[3];                  << 
1327   GLdouble mag;                               << 
1328                                               << 
1329   /* Make rotation matrix */                  << 
1330                                               << 
1331   /* Z vector */                              << 
1332   z[0] = eyex - centerx;                      << 
1333   z[1] = eyey - centery;                      << 
1334   z[2] = eyez - centerz;                      << 
1335   mag = std::sqrt(z[0] * z[0] + z[1] * z[1] + << 
1336   if (mag) {      /* mpichler, 19950515 */    << 
1337     z[0] /= mag;                              << 
1338     z[1] /= mag;                              << 
1339     z[2] /= mag;                              << 
1340   }                                           << 
1341                                               << 
1342   /* Y vector */                              << 
1343   y[0] = upx;                                 << 
1344   y[1] = upy;                                 << 
1345   y[2] = upz;                                 << 
1346                                               << 
1347   /* X vector = Y cross Z */                  << 
1348   x[0] = y[1] * z[2] - y[2] * z[1];           << 
1349   x[1] = -y[0] * z[2] + y[2] * z[0];          << 
1350   x[2] = y[0] * z[1] - y[1] * z[0];           << 
1351                                               << 
1352   /* Recompute Y = Z cross X */               << 
1353   y[0] = z[1] * x[2] - z[2] * x[1];           << 
1354   y[1] = -z[0] * x[2] + z[2] * x[0];          << 
1355   y[2] = z[0] * x[1] - z[1] * x[0];           << 
1356                                               << 
1357   /* mpichler, 19950515 */                    << 
1358   /* cross product gives area of parallelogra << 
1359    * non-perpendicular unit-length vectors; s << 
1360    */                                         << 
1361                                               << 
1362   mag = std::sqrt(x[0] * x[0] + x[1] * x[1] + << 
1363   if (mag) {                                  << 
1364     x[0] /= mag;                              << 
1365     x[1] /= mag;                              << 
1366     x[2] /= mag;                              << 
1367   }                                           << 
1368                                               << 
1369   mag = std::sqrt(y[0] * y[0] + y[1] * y[1] + << 
1370   if (mag) {                                  << 
1371     y[0] /= mag;                              << 
1372     y[1] /= mag;                              << 
1373     y[2] /= mag;                              << 
1374   }                                           << 
1375                                               << 
1376 #define M(row,col)  mat[col*4+row]            << 
1377   M(0, 0) = x[0];                             << 
1378   M(0, 1) = x[1];                             << 
1379   M(0, 2) = x[2];                             << 
1380   M(0, 3) = 0.0;                              << 
1381   M(1, 0) = y[0];                             << 
1382   M(1, 1) = y[1];                             << 
1383   M(1, 2) = y[2];                             << 
1384   M(1, 3) = 0.0;                              << 
1385   M(2, 0) = z[0];                             << 
1386   M(2, 1) = z[1];                             << 
1387   M(2, 2) = z[2];                             << 
1388   M(2, 3) = 0.0;                              << 
1389   M(3, 0) = 0.0;                              << 
1390   M(3, 1) = 0.0;                              << 
1391   M(3, 2) = 0.0;                              << 
1392   M(3, 3) = 1.0;                              << 
1393 #undef M                                      << 
1394   glMultMatrixd(mat);                         << 
1395                                               << 
1396   /* Translate Eye to Origin */               << 
1397   glTranslated(-eyex, -eyey, -eyez);          << 
1398 }                                             << 
1399                                               << 
1400 void G4OpenGLViewer::g4GlOrtho (GLdouble left << 
1401   //  glOrtho (left, right, bottom, top, near << 
1402                                               << 
1403   GLdouble a = 2.0 / (right - left);          << 
1404   GLdouble b = 2.0 / (top - bottom);          << 
1405   GLdouble c = -2.0 / (zFar - zNear);         << 
1406                                               << 
1407   GLdouble tx = - (right + left)/(right - lef << 
1408   GLdouble ty = - (top + bottom)/(top - botto << 
1409   GLdouble tz = - (zFar + zNear)/(zFar - zNea << 
1410                                               << 
1411   GLdouble ortho[16] = {                      << 
1412     a, 0, 0, 0,                               << 
1413     0, b, 0, 0,                               << 
1414     0, 0, c, 0,                               << 
1415     tx, ty, tz, 1                             << 
1416   };                                          << 
1417   glMultMatrixd(ortho);                       << 
1418                                               << 
1419 }                                             << 
1420                                               << 
1421                                               << 
1422 void G4OpenGLViewer::g4GlFrustum (GLdouble le << 
1423   //  glFrustum (left, right, bottom, top, ne << 
1424                                               << 
1425   GLdouble deltaX = right - left;             << 
1426   GLdouble deltaY = top - bottom;             << 
1427   GLdouble deltaZ = zFar - zNear;             << 
1428                                               << 
1429   GLdouble a = 2.0f * zNear / deltaX;         << 
1430   GLdouble b = 2.0f * zNear / deltaY;         << 
1431   GLdouble c = (right + left) / deltaX;       << 
1432   GLdouble d = (top + bottom) / deltaY;       << 
1433   GLdouble e = -(zFar + zNear) / (zFar - zNea << 
1434   GLdouble f = -2.0f * zFar * zNear / deltaZ; << 
1435                                               << 
1436   GLdouble proj[16] = {                       << 
1437     a, 0, 0, 0,                               << 
1438     0, b, 0, 0,                               << 
1439     c, d, e, -1.0f,                           << 
1440     0, 0, f, 0                                << 
1441   };                                          << 
1442                                               << 
1443   glMultMatrixd(proj);                        << 
1444                                               << 
1445 }                                             << 
1446                                               << 
1447 G4String G4OpenGLViewerPickMap::print() {     << 
1448   std::ostringstream txt;                     << 
1449   for (unsigned int a=0; a<fAttributes.size() << 
1450     txt << fAttributes[a];                    << 
1451     if (a < fAttributes.size() - 1) txt << "\ << 
1452   }                                           << 
1453   return txt.str();                           << 
1454 }                                             << 
1455                                                  992