Geant4 Cross Reference |
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