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.34 2007/05/24 18:27:13 allison Exp $ >> 28 // GEANT4 tag $Name: geant4-09-01-patch-03 $ 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(-G4OPENGL_DBL_MAX), 68 fPan_sens(0.01), << 93 fEndTime(G4OPENGL_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(); << 88 tools_gl2ps_gl_funcs_t _funcs = { << 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 114 108 // Change the default name << 109 fExportFilename += fDefaultExportFilename + << 110 << 111 // glClearColor (0.0, 0.0, 0.0, 0.0); 115 // glClearColor (0.0, 0.0, 0.0, 0.0); 112 // glClearDepth (1.0); 116 // glClearDepth (1.0); 113 // glDisable (GL_BLEND); 117 // glDisable (GL_BLEND); 114 // glDisable (GL_LINE_SMOOTH); 118 // glDisable (GL_LINE_SMOOTH); 115 // glDisable (GL_POLYGON_SMOOTH); 119 // glDisable (GL_POLYGON_SMOOTH); 116 120 >> 121 strcpy (print_string, "G4OpenGL.eps"); 117 } 122 } 118 123 119 G4OpenGLViewer::~G4OpenGLViewer () << 124 G4OpenGLViewer::~G4OpenGLViewer () {} 120 { << 121 delete fGL2PSAction; << 122 } << 123 125 124 void G4OpenGLViewer::InitializeGLView () 126 void G4OpenGLViewer::InitializeGLView () 125 { 127 { 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); 128 glClearColor (0.0, 0.0, 0.0, 0.0); 134 glClearDepth (1.0); 129 glClearDepth (1.0); >> 130 glDisable (GL_BLEND); 135 glDisable (GL_LINE_SMOOTH); 131 glDisable (GL_LINE_SMOOTH); 136 glDisable (GL_POLYGON_SMOOTH); 132 glDisable (GL_POLYGON_SMOOTH); 137 << 133 } 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 134 150 void G4OpenGLViewer::ClearView () { 135 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(), 136 glClearColor (background.GetRed(), 169 background.GetGreen(), << 137 background.GetGreen(), 170 background.GetBlue(), << 138 background.GetBlue(), 171 1.); << 139 1.); 172 glClearDepth (1.0); 140 glClearDepth (1.0); 173 //Below line does not compile with Mesa incl << 141 //Below line does not compile with Mesa includes. 174 //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BU << 142 //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 175 glClear (GL_COLOR_BUFFER_BIT); 143 glClear (GL_COLOR_BUFFER_BIT); 176 glClear (GL_DEPTH_BUFFER_BIT); 144 glClear (GL_DEPTH_BUFFER_BIT); 177 glClear (GL_STENCIL_BUFFER_BIT); 145 glClear (GL_STENCIL_BUFFER_BIT); >> 146 glFlush (); 178 } 147 } 179 148 180 << 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 /** << 192 * Set the viewport of the scene << 193 * MAXIMUM SIZE is : << 194 * GLint dims[2]; << 195 * glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); << 196 */ << 197 void G4OpenGLViewer::ResizeGLView() << 198 { << 199 // Check size << 200 GLint dims[2]; << 201 dims[0] = 0; << 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 } << 222 << 223 << 224 void G4OpenGLViewer::SetView () { 149 void G4OpenGLViewer::SetView () { 225 // if getting pick infos, should not resize << 226 if (fIsGettingPickInfos) return; << 227 150 228 if (!fSceneHandler.GetScene()) { << 229 return; << 230 } << 231 // Calculates view representation based on e 151 // Calculates view representation based on extent of object being 232 // viewed and (initial) viewpoint. (Note: i 152 // viewed and (initial) viewpoint. (Note: it can change later due 233 // to user interaction via visualization sys 153 // to user interaction via visualization system's GUI.) 234 154 235 // Lighting. 155 // Lighting. 236 GLfloat lightPosition [4]; 156 GLfloat lightPosition [4]; 237 lightPosition [0] = fVP.GetActualLightpointD 157 lightPosition [0] = fVP.GetActualLightpointDirection().x(); 238 lightPosition [1] = fVP.GetActualLightpointD 158 lightPosition [1] = fVP.GetActualLightpointDirection().y(); 239 lightPosition [2] = fVP.GetActualLightpointD 159 lightPosition [2] = fVP.GetActualLightpointDirection().z(); 240 lightPosition [3] = 0.; 160 lightPosition [3] = 0.; 241 // Light position is "true" light direction, 161 // Light position is "true" light direction, so must come after gluLookAt. 242 GLfloat ambient [] = { 0.2f, 0.2f, 0.2f, 1.f << 162 GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.}; 243 GLfloat diffuse [] = { 0.8f, 0.8f, 0.8f, 1.f << 163 GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.}; 244 glEnable (GL_LIGHT0); 164 glEnable (GL_LIGHT0); 245 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient); 165 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient); 246 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse); 166 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse); 247 167 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. 168 // Get radius of scene, etc. 258 // Note that this procedure properly takes i 169 // Note that this procedure properly takes into account zoom, dolly and pan. 259 const G4Point3D targetPoint 170 const G4Point3D targetPoint 260 = fSceneHandler.GetScene()->GetStandardTar 171 = fSceneHandler.GetScene()->GetStandardTargetPoint() 261 + fVP.GetCurrentTargetPoint (); 172 + fVP.GetCurrentTargetPoint (); 262 G4double radius = fSceneHandler.GetScene()-> 173 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius(); 263 if(radius<=0.) radius = 1.; 174 if(radius<=0.) radius = 1.; 264 const G4double cameraDistance = fVP.GetCamer 175 const G4double cameraDistance = fVP.GetCameraDistance (radius); 265 const G4Point3D cameraPosition = 176 const G4Point3D cameraPosition = 266 targetPoint + cameraDistance * fVP.GetView 177 targetPoint + cameraDistance * fVP.GetViewpointDirection().unit(); 267 const GLdouble pnear = fVP.GetNearDistance << 178 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius); 268 const GLdouble pfar = fVP.GetFarDistance << 179 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius); 269 const GLdouble right = fVP.GetFrontHalfHeig << 180 const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius); 270 const GLdouble left = -right; 181 const GLdouble left = -right; 271 const GLdouble top = fVP.GetFrontHalfHeig << 182 const GLdouble bottom = left; 272 const GLdouble bottom = -top; << 183 const GLdouble top = right; 273 184 274 // FIXME << 275 ResizeGLView(); << 276 //SHOULD SetWindowsSizeHint()... << 277 << 278 glMatrixMode (GL_PROJECTION); // set up Frus 185 glMatrixMode (GL_PROJECTION); // set up Frustum. 279 glLoadIdentity(); 186 glLoadIdentity(); 280 187 281 const G4Vector3D scaleFactor = fVP.GetScaleF << 188 const G4Vector3D scale = fVP.GetScaleFactor(); 282 glScaled(scaleFactor.x(),scaleFactor.y(),sca << 189 glScaled(scale.x(),scale.y(),scale.z()); 283 190 284 if (fVP.GetFieldHalfAngle() == 0.) { 191 if (fVP.GetFieldHalfAngle() == 0.) { 285 g4GlOrtho (left, right, bottom, top, pnear << 192 glOrtho (left, right, bottom, top, pnear, pfar); 286 } 193 } 287 else { 194 else { 288 g4GlFrustum (left, right, bottom, top, pne << 195 glFrustum (left, right, bottom, top, pnear, pfar); 289 } << 196 } 290 << 197 291 glMatrixMode (GL_MODELVIEW); // apply furthe 198 glMatrixMode (GL_MODELVIEW); // apply further transformations to scene. 292 glLoadIdentity(); 199 glLoadIdentity(); 293 200 294 const G4Normal3D& upVector = fVP.GetUpVector 201 const G4Normal3D& upVector = fVP.GetUpVector (); 295 G4Point3D gltarget; 202 G4Point3D gltarget; 296 if (cameraDistance > 1.e-6 * radius) { 203 if (cameraDistance > 1.e-6 * radius) { 297 gltarget = targetPoint; 204 gltarget = targetPoint; 298 } 205 } 299 else { 206 else { 300 gltarget = targetPoint - radius * fVP.GetV 207 gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit(); 301 } 208 } 302 209 303 const G4Point3D& pCamera = cameraPosition; 210 const G4Point3D& pCamera = cameraPosition; // An alias for brevity. 304 << 211 gluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint. 305 g4GluLookAt (pCamera.x(), pCamera.y(), pCa << 212 gltarget.x(), gltarget.y(), gltarget.z(), // Target point. 306 gltarget.x(), gltarget.y(), gltar << 213 upVector.x(), upVector.y(), upVector.z()); // Up vector. 307 upVector.x(), upVector.y(), upVec << 214 308 // Light position is "true" light direction, 215 // Light position is "true" light direction, so must come after gluLookAt. 309 glLightfv (GL_LIGHT0, GL_POSITION, lightPosi 216 glLightfv (GL_LIGHT0, GL_POSITION, lightPosition); 310 217 311 // The idea is to use back-to-back clipping << 218 // OpenGL no longer seems to reconstruct clipped edges, so, when the 312 // down to just a few pixels, which can make << 219 // BooleanProcessor is up to it, abandon this and use generic 313 // now, comment this out and use the generic << 220 // clipping in G4OpenGLSceneHandler::CreateSectionPolyhedron. Also, 314 // G4VSolid* G4OpenGLSceneHandler::CreateSec << 221 // force kernel visit on change of clipping plane in 315 // { return G4VSceneHandler::CreateSectionSo << 222 // G4OpenGLStoredViewer::CompareForKernelVisit. 316 // if (fVP.IsSection () ) { // pair of back << 223 if (fVP.IsSection () ) { // pair of back to back clip planes. 317 // const G4Plane3D& sp = fVP.GetSectionPlan << 224 const G4Plane3D& s = fVP.GetSectionPlane (); 318 // double sArray[4]; << 225 double sArray[4]; 319 // sArray[0] = sp.a(); << 226 sArray[0] = s.a(); 320 // sArray[1] = sp.b(); << 227 sArray[1] = s.b(); 321 // sArray[2] = sp.c(); << 228 sArray[2] = s.c(); 322 // sArray[3] = sp.d() + radius * 1.e-05; << 229 sArray[3] = s.d() + radius * 1.e-05; 323 // glClipPlane (GL_CLIP_PLANE0, sArray); << 230 glClipPlane (GL_CLIP_PLANE0, sArray); 324 // glEnable (GL_CLIP_PLANE0); << 231 glEnable (GL_CLIP_PLANE0); 325 // sArray[0] = -sp.a(); << 232 sArray[0] = -s.a(); 326 // sArray[1] = -sp.b(); << 233 sArray[1] = -s.b(); 327 // sArray[2] = -sp.c(); << 234 sArray[2] = -s.c(); 328 // sArray[3] = -sp.d() + radius * 1.e-05; << 235 sArray[3] = -s.d() + radius * 1.e-05; 329 // glClipPlane (GL_CLIP_PLANE1, sArray); << 236 glClipPlane (GL_CLIP_PLANE1, sArray); 330 // glEnable (GL_CLIP_PLANE1); << 237 glEnable (GL_CLIP_PLANE1); 331 // } else { << 238 } else { 332 // glDisable (GL_CLIP_PLANE0); << 239 glDisable (GL_CLIP_PLANE0); 333 // glDisable (GL_CLIP_PLANE1); << 240 glDisable (GL_CLIP_PLANE1); 334 // } << 241 } 335 << 242 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 243 const G4Planes& cutaways = fVP.GetCutawayPlanes(); 341 size_t nPlanes = cutaways.size(); 244 size_t nPlanes = cutaways.size(); 342 if (fVP.IsCutaway() && 245 if (fVP.IsCutaway() && 343 fVP.GetCutawayMode() == G4ViewParameters << 246 fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection && >> 247 nPlanes > 0) { 344 double a[4]; 248 double a[4]; 345 a[0] = cutaways[0].a(); 249 a[0] = cutaways[0].a(); 346 a[1] = cutaways[0].b(); 250 a[1] = cutaways[0].b(); 347 a[2] = cutaways[0].c(); 251 a[2] = cutaways[0].c(); 348 a[3] = cutaways[0].d(); 252 a[3] = cutaways[0].d(); 349 glClipPlane (GL_CLIP_PLANE2, a); 253 glClipPlane (GL_CLIP_PLANE2, a); 350 glEnable (GL_CLIP_PLANE2); 254 glEnable (GL_CLIP_PLANE2); 351 if (nPlanes > 1) { 255 if (nPlanes > 1) { 352 a[0] = cutaways[1].a(); 256 a[0] = cutaways[1].a(); 353 a[1] = cutaways[1].b(); 257 a[1] = cutaways[1].b(); 354 a[2] = cutaways[1].c(); 258 a[2] = cutaways[1].c(); 355 a[3] = cutaways[1].d(); 259 a[3] = cutaways[1].d(); 356 glClipPlane (GL_CLIP_PLANE3, a); 260 glClipPlane (GL_CLIP_PLANE3, a); 357 glEnable (GL_CLIP_PLANE3); 261 glEnable (GL_CLIP_PLANE3); 358 } 262 } 359 if (nPlanes > 2) { 263 if (nPlanes > 2) { 360 a[0] = cutaways[2].a(); 264 a[0] = cutaways[2].a(); 361 a[1] = cutaways[2].b(); 265 a[1] = cutaways[2].b(); 362 a[2] = cutaways[2].c(); 266 a[2] = cutaways[2].c(); 363 a[3] = cutaways[2].d(); 267 a[3] = cutaways[2].d(); 364 glClipPlane (GL_CLIP_PLANE4, a); 268 glClipPlane (GL_CLIP_PLANE4, a); 365 glEnable (GL_CLIP_PLANE4); 269 glEnable (GL_CLIP_PLANE4); 366 } 270 } 367 } else { 271 } else { 368 glDisable (GL_CLIP_PLANE2); 272 glDisable (GL_CLIP_PLANE2); 369 glDisable (GL_CLIP_PLANE3); 273 glDisable (GL_CLIP_PLANE3); 370 glDisable (GL_CLIP_PLANE4); 274 glDisable (GL_CLIP_PLANE4); 371 } 275 } 372 276 373 // Background. 277 // Background. 374 background = fVP.GetBackgroundColour (); 278 background = fVP.GetBackgroundColour (); 375 279 376 } 280 } 377 281 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 () { 282 void G4OpenGLViewer::HaloingFirstPass () { 388 283 389 //To perform haloing, first Draw all informa 284 //To perform haloing, first Draw all information to the depth buffer 390 //alone, using a chunky line width, and then 285 //alone, using a chunky line width, and then Draw all info again, to 391 //the colour buffer, setting a thinner line 286 //the colour buffer, setting a thinner line width an the depth testing 392 //function to less than or equal, so if two 287 //function to less than or equal, so if two lines cross, the one 393 //passing behind the other will not pass the 288 //passing behind the other will not pass the depth test, and so not 394 //get rendered either side of the infront li 289 //get rendered either side of the infront line for a short distance. 395 290 396 //First, disable writing to the colo(u)r buf 291 //First, disable writing to the colo(u)r buffer... 397 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, G 292 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 398 293 399 //Now enable writing to the depth buffer... 294 //Now enable writing to the depth buffer... 400 glDepthMask (GL_TRUE); 295 glDepthMask (GL_TRUE); 401 glDepthFunc (GL_LESS); 296 glDepthFunc (GL_LESS); 402 glClearDepth (1.0); 297 glClearDepth (1.0); 403 298 404 //Finally, set the line width to something w 299 //Finally, set the line width to something wide... 405 ChangeLineWidth(3.0); << 300 glLineWidth (3.0); 406 301 407 } 302 } 408 303 409 void G4OpenGLViewer::HaloingSecondPass () { 304 void G4OpenGLViewer::HaloingSecondPass () { 410 305 411 //And finally, turn the colour buffer back o 306 //And finally, turn the colour buffer back on with a sesible line width... 412 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_T 307 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 413 glDepthFunc (GL_LEQUAL); 308 glDepthFunc (GL_LEQUAL); 414 ChangeLineWidth(1.0); << 309 glLineWidth (1.0); 415 310 416 } 311 } 417 312 418 G4String G4OpenGLViewer::Pick(GLdouble x, GLdo << 313 void G4OpenGLViewer::Pick(GLdouble x, GLdouble y) 419 { << 420 const std::vector < G4OpenGLViewerPickMap* > << 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 { 314 { 436 static std::vector < G4OpenGLViewerPickMap* << 315 //G4cout << "X: " << x << ", Y: " << y << G4endl; 437 for (auto pickMap: pickMapVector) { << 438 delete pickMap; << 439 } << 440 pickMapVector.clear(); << 441 << 442 const G4int BUFSIZE = 512; 316 const G4int BUFSIZE = 512; 443 GLuint selectBuffer[BUFSIZE]; 317 GLuint selectBuffer[BUFSIZE]; 444 glSelectBuffer(BUFSIZE, selectBuffer); 318 glSelectBuffer(BUFSIZE, selectBuffer); 445 glRenderMode(GL_SELECT); 319 glRenderMode(GL_SELECT); 446 glInitNames(); 320 glInitNames(); 447 glPushName(0); 321 glPushName(0); 448 glMatrixMode(GL_PROJECTION); 322 glMatrixMode(GL_PROJECTION); 449 G4double currentProjectionMatrix[16]; 323 G4double currentProjectionMatrix[16]; 450 glGetDoublev(GL_PROJECTION_MATRIX, currentPr 324 glGetDoublev(GL_PROJECTION_MATRIX, currentProjectionMatrix); 451 glPushMatrix(); 325 glPushMatrix(); 452 glLoadIdentity(); 326 glLoadIdentity(); 453 GLint viewport[4]; 327 GLint viewport[4]; 454 glGetIntegerv(GL_VIEWPORT, viewport); 328 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 329 // Define 5x5 pixel pick area 463 g4GluPickMatrix(x, viewport[3] - y, 5., 5., << 330 gluPickMatrix(x, viewport[3] - y, 5., 5., viewport); 464 glMultMatrixd(currentProjectionMatrix); 331 glMultMatrixd(currentProjectionMatrix); 465 glMatrixMode(GL_MODELVIEW); 332 glMatrixMode(GL_MODELVIEW); 466 DrawView(); 333 DrawView(); 467 GLint hits = glRenderMode(GL_RENDER); 334 GLint hits = glRenderMode(GL_RENDER); 468 fIsGettingPickInfos = false; << 335 if (hits < 0) 469 if (hits < 0) { << 336 G4cout << "Too many hits. Zoom in to reduce overlaps." << G4cout; 470 G4cout << "Too many hits. Zoom in to redu << 337 else if (hits > 0) { 471 goto restoreMatrices; << 338 //G4cout << hits << " hit(s)" << G4endl; 472 } << 473 if (hits > 0) { << 474 GLuint* p = selectBuffer; 339 GLuint* p = selectBuffer; 475 for (GLint i = 0; i < hits; ++i) { 340 for (GLint i = 0; i < hits; ++i) { 476 GLuint nnames = *p++; 341 GLuint nnames = *p++; 477 // This bit of debug code or... << 342 *p++; //OR GLuint zmin = *p++; 478 //GLuint zmin = *p++; << 343 *p++; //OR GLuint zmax = *p++; 479 //GLuint zmax = *p++; << 480 //G4cout << "Hit " << i << ": " << nname 344 //G4cout << "Hit " << i << ": " << nnames << " names" 481 // << "\nzmin: " << zmin << ", zma << 345 // << "\nzmin: " << zmin << ", zmax: " << zmax << G4endl; 482 // ...just increment the pointer << 483 p++; << 484 p++; << 485 for (GLuint j = 0; j < nnames; ++j) { 346 for (GLuint j = 0; j < nnames; ++j) { 486 GLuint name = *p++; << 347 GLuint name = *p++; >> 348 //G4cout << "Name " << j << ": PickName: " << name << G4endl; 487 std::map<GLuint, G4AttHolder*>::iterator ite 349 std::map<GLuint, G4AttHolder*>::iterator iter = 488 fOpenGLSceneHandler.fPickMap.find(name); 350 fOpenGLSceneHandler.fPickMap.find(name); 489 if (iter != fOpenGLSceneHandler.fPickMap.end 351 if (iter != fOpenGLSceneHandler.fPickMap.end()) { 490 G4AttHolder* attHolder = iter->second; 352 G4AttHolder* attHolder = iter->second; 491 if(attHolder && attHolder->GetAttDefs().si 353 if(attHolder && attHolder->GetAttDefs().size()) { 492 for (size_t iAtt = 0; << 354 for (size_t i = 0; i < attHolder->GetAttDefs().size(); ++i) { 493 iAtt < attHolder->GetAttDefs().size(); ++ << 355 G4cout << G4AttCheck(attHolder->GetAttValues()[i], 494 std::ostringstream oss; << 356 attHolder->GetAttDefs()[i]); 495 oss << G4AttCheck(attHolder->GetAttVal << 357 } 496 attHolder->Get << 358 } 497 G4OpenGLViewerPickMap* pickMap = << 359 } 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 } 360 } >> 361 G4cout << G4endl; 513 } 362 } 514 } 363 } 515 << 516 restoreMatrices: << 517 glMatrixMode(GL_PROJECTION); 364 glMatrixMode(GL_PROJECTION); 518 glPopMatrix(); 365 glPopMatrix(); 519 glMatrixMode(GL_MODELVIEW); 366 glMatrixMode(GL_MODELVIEW); 520 << 521 return pickMapVector; << 522 } 367 } 523 368 524 GLubyte* G4OpenGLViewer::grabPixels << 369 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 370 541 buffer = new GLubyte[size]; << 371 // 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 372 568 glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows << 373 G4int size = 5000000; 569 glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippi << 570 glPixelStorei (GL_UNPACK_ALIGNMENT, alignmen << 571 << 572 return buffer; << 573 } << 574 374 575 bool G4OpenGLViewer::printVectoredEPS() { << 375 GLfloat* feedback_buffer; 576 return printGl2PS(); << 376 GLint returned; 577 } << 377 FILE* file; 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 378 607 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n"); << 379 feedback_buffer = new GLfloat[size]; 608 fprintf (fp, "%%%%Title: %s\n", name.c_str() << 380 glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer); 609 fprintf (fp, "%%%%Creator: OpenGL pixmap ren << 381 glRenderMode (GL_FEEDBACK); 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 382 640 curpix = (GLubyte*) pixels; << 383 DrawView(); 641 pos = 0; << 384 returned = glRenderMode (GL_RENDER); 642 for (i = width*height*components; i>0; i--) << 385 643 fprintf (fp, "%02hx ", (unsigned short)(*( << 386 if (print_string) { 644 if (++pos >= 32) { << 387 file = fopen (print_string, "w"); 645 fprintf (fp, "\n"); << 388 if (file) { 646 pos = 0; << 389 spewWireframeEPS (file, returned, feedback_buffer, "rendereps"); 647 } << 390 } else { 648 } << 391 printf("Could not open %s\n", print_string); 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 << 718 switch (g4text.GetLayout()) { << 719 case G4Text::left: align = GL2PS_TEXT_BL; << 720 case G4Text::centre: align = GL2PS_TEXT_B; << 721 case G4Text::right: align = GL2PS_TEXT_BR; << 722 } 392 } 723 << 724 fGL2PSAction->addTextOpt(textString.c_str( << 725 << 726 } else { 393 } else { 727 << 394 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 } 395 } 740 } << 741 396 742 /** Change PointSize on gl2ps if needed << 397 delete[] feedback_buffer; 743 */ << 744 void G4OpenGLViewer::ChangePointSize(G4double << 745 << 746 if (isGl2psWriting()) { << 747 fGL2PSAction->setPointSize(int(size)); << 748 } else { << 749 glPointSize (size); << 750 } << 751 } 398 } 752 399 >> 400 void G4OpenGLViewer::print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer) >> 401 { >> 402 G4int i; 753 403 754 /** Change LineSize on gl2ps if needed << 404 printf(" "); 755 */ << 405 for (i = 0; i < 7; i++) { 756 void G4OpenGLViewer::ChangeLineWidth(G4double << 406 printf("%4.2f ", buffer[size - (*count)]); 757 << 407 *count = *count - 1; 758 if (isGl2psWriting()) { << 759 fGL2PSAction->setLineWidth(int(width)); << 760 } else { << 761 glLineWidth (width); << 762 } 408 } >> 409 printf("\n"); 763 } 410 } 764 411 765 /** << 412 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 << 775 if (! setExportFilename(name)) { << 776 return false; << 777 } << 778 << 779 if ((width != -1) && (height != -1)) { << 780 setExportSize(width, height); << 781 } << 782 << 783 if (fExportImageFormat == "eps") { << 784 fGL2PSAction->setExportImageFormat_EPS(); << 785 } else if (fExportImageFormat == "ps") { << 786 fGL2PSAction->setExportImageFormat_PS(); << 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 413 796 bool res; << 414 GLfloat EPS_GOURAUD_THRESHOLD=0.1; 797 415 798 // Change the LC_NUMERIC value in order to h << 416 GLfloat clearColor[4], viewport[4]; 799 // This case is only useful for French, Cana << 417 GLfloat lineWidth; 800 size_t len = strlen(setlocale(LC_NUMERIC,NUL << 418 G4int i; 801 char* oldLocale = (char*)(malloc(len+1)); << 802 if(oldLocale!=NULL) strncpy(oldLocale,setloc << 803 setlocale(LC_NUMERIC,"C"); << 804 419 805 if (((fExportImageFormat == "eps") || (fExpo << 420 glGetFloatv (GL_VIEWPORT, viewport); 806 res = printNonVectoredEPS(); << 421 glGetFloatv (GL_COLOR_CLEAR_VALUE, clearColor); 807 } else { << 422 glGetFloatv (GL_LINE_WIDTH, &lineWidth); 808 res = printVectoredEPS(); << 423 glGetFloatv (GL_POINT_SIZE, &pointSize); 809 } << 810 << 811 // restore the local << 812 if (oldLocale) { << 813 setlocale(LC_NUMERIC,oldLocale); << 814 free(oldLocale); << 815 } << 816 424 817 if (res == false) { << 425 fputs ("%!PS-Adobe-2.0 EPSF-2.0\n", file); 818 G4cerr << "Error saving file... " << getRe << 426 fprintf (file, "%%%%Creator: %s (using OpenGL feedback)\n", cr); 819 } else { << 427 fprintf (file, "%%%%BoundingBox: %g %g %g %g\n", viewport[0], viewport[1], viewport[2], viewport[3]); 820 G4cout << "File " << getRealPrintFilename( << 428 fputs ("%%EndComments\n", file); >> 429 fputs ("\n", file); >> 430 fputs ("gsave\n", file); >> 431 fputs ("\n", file); 821 432 822 // increment index if necessary << 433 fputs ("% the gouraudtriangle PostScript fragment below is free\n", file); 823 if ( fExportFilenameIndex != -1) { << 434 fputs ("% written by Frederic Delhoume (delhoume@ilog.fr)\n", file); 824 fExportFilenameIndex++; << 435 fprintf (file, "/threshold %g def\n", EPS_GOURAUD_THRESHOLD); 825 } << 436 for (i=0; gouraudtriangleEPS[i]; i++) { >> 437 fprintf (file, "%s\n", gouraudtriangleEPS[i]); 826 } 438 } 827 439 828 return res; << 440 fprintf(file, "\n%g setlinewidth\n", lineWidth); 829 } << 441 830 << 442 fprintf (file, "%g %g %g setrgbcolor\n", clearColor[0], clearColor[1], clearColor[2]); 831 << 443 fprintf (file, "%g %g %g %g rectfill\n\n", viewport[0], viewport[1], viewport[2], viewport[3]); 832 bool G4OpenGLViewer::printGl2PS() { << 833 << 834 int width = getRealExportWidth(); << 835 int height = getRealExportHeight(); << 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 << 925 return res; << 926 } << 927 444 928 unsigned int G4OpenGLViewer::getWinWidth() con << 445 spewSortedFeedback (file, size, buffer); 929 return fWinSize_x; << 930 } << 931 446 932 unsigned int G4OpenGLViewer::getWinHeight() co << 447 fputs ("grestore\n\n", file); 933 return fWinSize_y; << 448 fputs ("showpage\n", file); 934 } << 935 449 936 G4bool G4OpenGLViewer::sizeHasChanged() { << 450 fclose(file); 937 return fSizeHasChanged; << 938 } 451 } 939 452 940 G4int G4OpenGLViewer::getRealExportWidth() { << 453 void G4OpenGLViewer::printBuffer (GLint size, GLfloat* buffer) { 941 if (fPrintSizeX == -1) { << 942 return fWinSize_x; << 943 } << 944 GLint dims[2]; << 945 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); << 946 << 947 // L.Garnier 01-2010: Some problems with mac << 948 if ((dims[0] !=0 ) && (dims[1] !=0)) { << 949 if (fPrintSizeX > dims[0]){ << 950 return dims[0]; << 951 } << 952 } << 953 if (fPrintSizeX < -1){ << 954 return 0; << 955 } << 956 return fPrintSizeX; << 957 } << 958 454 959 G4int G4OpenGLViewer::getRealExportHeight() { << 455 GLint count; 960 if (fPrintSizeY == -1) { << 456 G4int token, nvertices; 961 return fWinSize_y; << 962 } << 963 GLint dims[2]; << 964 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); << 965 457 966 // L.Garnier 01-2010: Some problems with mac << 458 count=size; 967 if ((dims[0] !=0 ) && (dims[1] !=0)) { << 459 while(count) { 968 if (fPrintSizeY > dims[1]){ << 460 token=G4int (buffer[size-count]); 969 return dims[1]; << 461 count--; 970 } << 462 switch (token) { 971 } << 972 if (fPrintSizeY < -1){ << 973 return 0; << 974 } << 975 return fPrintSizeY; << 976 } << 977 463 978 void G4OpenGLViewer::setExportSize(G4int X, G4 << 464 case GL_PASS_THROUGH_TOKEN: 979 fPrintSizeX = X; << 465 printf ("GL_PASS_THROUGH_TOKEN\n"); 980 fPrintSizeY = Y; << 466 printf (" %4.2f\n", buffer[size-count]); 981 } << 467 count--; >> 468 break; 982 469 983 /** << 470 case GL_POINT_TOKEN: 984 If name is "" or "!", filename and extension << 471 printf ("GL_POINT_TOKEN\n"); 985 If name is "toto.png", set the name to "toto" << 472 print3DcolorVertex (size, &count, buffer); 986 If name is "toto", set the name to "toto" and << 473 break; 987 If name is the same as previous, do not reset << 988 */ << 989 bool G4OpenGLViewer::setExportFilename(G4Strin << 990 if (name == "!") { << 991 name = ""; << 992 } << 993 474 994 if (inc) { << 475 case GL_LINE_TOKEN: 995 if ((name != "") && (fExportFilename != na << 476 printf ("GL_LINE_TOKEN\n"); 996 fExportFilenameIndex=0; << 477 print3DcolorVertex (size, &count, buffer); 997 } << 478 print3DcolorVertex (size, &count, buffer); 998 } else { << 479 break; 999 fExportFilenameIndex=-1; << 480 1000 } << 481 case GL_LINE_RESET_TOKEN: >> 482 printf ("GL_LINE_RESET_TOKEN\n"); >> 483 print3DcolorVertex (size, &count, buffer); >> 484 print3DcolorVertex (size, &count, buffer); >> 485 break; 1001 486 1002 if (name.size() == 0) { << 487 case GL_POLYGON_TOKEN: 1003 name = getRealPrintFilename().c_str(); << 488 printf ("GL_POLYGON_TOKEN\n"); 1004 } else { << 489 nvertices=G4int (buffer[size-count]); 1005 // guess format by extention << 490 count--; 1006 std::string extension = name.substr(name. << 491 for (; nvertices>0; nvertices--) { 1007 // If there is a dot in the name the abov << 492 print3DcolorVertex (size, &count, buffer); 1008 if (extension.size() >= 3 && extension.si << 1009 if (setExportImageFormat(extension, fal << 1010 fExportFilename = name.substr(0,name. << 1011 } else { // No viable extension found << 1012 return false; << 1013 } 493 } 1014 } else { // Assume name is already the r << 1015 fExportFilename = name; << 1016 } 494 } 1017 } 495 } 1018 return true; << 1019 } << 1020 << 1021 std::string G4OpenGLViewer::getRealPrintFilen << 1022 std::string temp = fExportFilename; << 1023 if (fExportFilenameIndex != -1) { << 1024 temp += std::string("_"); << 1025 std::ostringstream os; << 1026 os << std::setw(4) << std::setfill('0') < << 1027 std::string nb_str = os.str(); << 1028 temp += nb_str; << 1029 } << 1030 temp += "."+fExportImageFormat; << 1031 return temp; << 1032 } << 1033 << 1034 GLdouble G4OpenGLViewer::getSceneNearWidth() << 1035 { << 1036 if (!fSceneHandler.GetScene()) { << 1037 return 0; << 1038 } << 1039 const G4Point3D targetPoint << 1040 = fSceneHandler.GetScene()->GetStandardTa << 1041 + fVP.GetCurrentTargetPoint (); << 1042 G4double radius = fSceneHandler.GetScene()- << 1043 if(radius<=0.) radius = 1.; << 1044 const G4double cameraDistance = fVP.GetCame << 1045 const GLdouble pnear = fVP.GetNearDistanc << 1046 return 2 * fVP.GetFrontHalfHeight (pnear, r << 1047 } << 1048 << 1049 GLdouble G4OpenGLViewer::getSceneFarWidth() << 1050 { << 1051 if (!fSceneHandler.GetScene()) { << 1052 return 0; << 1053 } << 1054 const G4Point3D targetPoint << 1055 = fSceneHandler.GetScene()->GetStandardTa << 1056 + fVP.GetCurrentTargetPoint (); << 1057 G4double radius = fSceneHandler.GetScene()- << 1058 if(radius<=0.) radius = 1.; << 1059 const G4double cameraDistance = fVP.GetCame << 1060 const GLdouble pnear = fVP.GetNearDistanc << 1061 const GLdouble pfar = fVP.GetFarDistance << 1062 return 2 * fVP.GetFrontHalfHeight (pfar, ra << 1063 } << 1064 << 1065 << 1066 GLdouble G4OpenGLViewer::getSceneDepth() << 1067 { << 1068 if (!fSceneHandler.GetScene()) { << 1069 return 0; << 1070 } << 1071 const G4Point3D targetPoint << 1072 = fSceneHandler.GetScene()->GetStandardTa << 1073 + fVP.GetCurrentTargetPoint (); << 1074 G4double radius = fSceneHandler.GetScene()- << 1075 if(radius<=0.) radius = 1.; << 1076 const G4double cameraDistance = fVP.GetCame << 1077 const GLdouble pnear = fVP.GetNearDistanc << 1078 return fVP.GetFarDistance (cameraDistance, << 1079 } 496 } 1080 497 >> 498 G4float* G4OpenGLViewer::spewPrimitiveEPS (FILE* file, GLfloat* loc) { >> 499 >> 500 G4int token; >> 501 G4int nvertices, i; >> 502 GLfloat red, green, blue, intensity; >> 503 G4int smooth; >> 504 GLfloat dx, dy, dr, dg, db, absR, absG, absB, colormax; >> 505 G4int steps; >> 506 Feedback3Dcolor *vertex; >> 507 GLfloat xstep(0.), ystep(0.), rstep(0.), gstep(0.), bstep(0.); >> 508 GLfloat xnext(0.), ynext(0.), rnext(0.), gnext(0.), bnext(0.), distance(0.); >> 509 >> 510 token=G4int (*loc); >> 511 loc++; >> 512 switch (token) { >> 513 case GL_LINE_RESET_TOKEN: >> 514 case GL_LINE_TOKEN: >> 515 vertex=(Feedback3Dcolor*)loc; >> 516 dr=vertex[1].red - vertex[0].red; >> 517 dg=vertex[1].green - vertex[0].green; >> 518 db=vertex[1].blue - vertex[0].blue; >> 519 >> 520 if (!print_colour) { >> 521 dr+=(dg+db); >> 522 dr/=3.0; >> 523 dg=dr; >> 524 db=dr; >> 525 } >> 526 >> 527 if (dr!=0 || dg!=0 || db!=0) { >> 528 dx=vertex[1].x - vertex[0].x; >> 529 dy=vertex[1].y - vertex[0].y; >> 530 distance=std::sqrt(dx*dx + dy*dy); >> 531 >> 532 absR=std::fabs(dr); >> 533 absG=std::fabs(dg); >> 534 absB=std::fabs(db); >> 535 >> 536 #define Max(a, b) (((a)>(b))?(a):(b)) >> 537 >> 538 #define EPS_SMOOTH_LINE_FACTOR 0.06 >> 539 >> 540 colormax=Max(absR, Max(absG, absB)); >> 541 steps=Max(1, G4int (colormax*distance*EPS_SMOOTH_LINE_FACTOR)); >> 542 >> 543 xstep=dx/steps; >> 544 ystep=dy/steps; >> 545 >> 546 rstep=dr/steps; >> 547 gstep=dg/steps; >> 548 bstep=db/steps; >> 549 >> 550 xnext=vertex[0].x; >> 551 ynext=vertex[0].y; >> 552 rnext=vertex[0].red; >> 553 gnext=vertex[0].green; >> 554 bnext=vertex[0].blue; >> 555 >> 556 if (!print_colour) { >> 557 rnext+=(gnext+bnext); >> 558 rnext/=3.0; >> 559 gnext=rnext; >> 560 bnext=rnext; >> 561 } 1081 562 1082 << 563 xnext -= xstep/2.0; 1083 void G4OpenGLViewer::rotateScene(G4double dx, << 564 ynext -= ystep/2.0; 1084 { << 565 rnext -= rstep/2.0; 1085 if (fVP.GetRotationStyle() == G4ViewParamet << 566 gnext -= gstep/2.0; 1086 rotateSceneInViewDirection(dx,dy); << 567 bnext -= bstep/2.0; 1087 } else { << 568 } else { 1088 if( dx != 0) { << 569 steps=0; 1089 rotateSceneThetaPhi(dx,0); << 1090 } << 1091 if( dy != 0) { << 1092 rotateSceneThetaPhi(0,dy); << 1093 } 570 } 1094 } << 571 if (print_colour) { 1095 } << 572 fprintf (file, "%g %g %g setrgbcolor\n", 1096 << 573 vertex[0].red, vertex[0].green, vertex[0].blue); >> 574 } else { >> 575 intensity = (vertex[0].red + vertex[0].green + vertex[0].blue) / 3.0; >> 576 fprintf (file, "%g %g %g setrgbcolor\n", >> 577 intensity, intensity, intensity); >> 578 } >> 579 fprintf (file, "%g %g moveto\n", vertex[0].x, vertex[0].y); >> 580 >> 581 for (i=0; i<steps; i++) { >> 582 >> 583 xnext += xstep; >> 584 ynext += ystep; >> 585 rnext += rstep; >> 586 gnext += gstep; >> 587 bnext += bstep; >> 588 >> 589 fprintf (file, "%g %g lineto stroke\n", xnext, ynext); >> 590 fprintf (file, "%g %g %g setrgbcolor\n", rnext, gnext, bnext); >> 591 fprintf (file, "%g %g moveto\n", xnext, ynext); >> 592 } >> 593 fprintf (file, "%g %g lineto stroke\n", vertex[1].x, vertex[1].y); >> 594 >> 595 loc += 14; >> 596 break; >> 597 >> 598 case GL_POLYGON_TOKEN: >> 599 nvertices = G4int (*loc); >> 600 loc++; >> 601 vertex=(Feedback3Dcolor*)loc; >> 602 if (nvertices>0) { >> 603 red=vertex[0].red; >> 604 green=vertex[0].green; >> 605 blue=vertex[0].blue; >> 606 smooth=0; >> 607 >> 608 if (!print_colour) { >> 609 red+=(green+blue); >> 610 red/=3.0; >> 611 green=red; >> 612 blue=red; >> 613 } >> 614 >> 615 if (print_colour) { >> 616 for (i=1; i<nvertices; i++) { >> 617 if (red!=vertex[i].red || green!=vertex[i].green || blue!=vertex[i].blue) { >> 618 smooth=1; >> 619 break; >> 620 } >> 621 } >> 622 } else { >> 623 for (i=1; i<nvertices; i++) { >> 624 intensity = vertex[i].red + vertex[i].green + vertex[i].blue; >> 625 intensity/=3.0; >> 626 if (red!=intensity) { >> 627 smooth=1; >> 628 break; >> 629 } >> 630 } >> 631 } 1097 632 1098 void G4OpenGLViewer::rotateSceneToggle(G4doub << 633 if (smooth) { 1099 { << 634 G4int triOffset; 1100 if (fVP.GetRotationStyle() != G4ViewParamet << 635 for (i=0; i<nvertices-2; i++) { 1101 rotateSceneInViewDirection(dx,dy); << 636 triOffset = i*7; 1102 } else { << 637 fprintf (file, "[%g %g %g %g %g %g]", 1103 if( dx != 0) { << 638 vertex[0].x, vertex[i+1].x, vertex[i+2].x, 1104 rotateSceneThetaPhi(dx,0); << 639 vertex[0].y, vertex[i+1].y, vertex[i+2].y); 1105 } << 640 if (print_colour) { 1106 if( dy != 0) { << 641 fprintf (file, " [%g %g %g] [%g %g %g] [%g %g %g] gouraudtriangle\n", 1107 rotateSceneThetaPhi(0,dy); << 642 vertex[0].red, vertex[0].green, vertex[0].blue, >> 643 vertex[i+1].red, vertex[i+1].green, vertex[i+1].blue, >> 644 vertex[i+2].red, vertex[i+2].green, vertex[i+2].blue); >> 645 } else { >> 646 >> 647 intensity = vertex[0].red + vertex[0].green + vertex[0].blue; >> 648 intensity/=3.0; >> 649 fprintf (file, " [%g %g %g]", intensity, intensity, intensity); >> 650 >> 651 intensity = vertex[1].red + vertex[1].green + vertex[1].blue; >> 652 intensity/=3.0; >> 653 fprintf (file, " [%g %g %g]", intensity, intensity, intensity); >> 654 >> 655 intensity = vertex[2].red + vertex[2].green + vertex[2].blue; >> 656 intensity/=3.0; >> 657 fprintf (file, " [%g %g %g] gouraudtriangle\n", intensity, intensity, intensity); >> 658 } >> 659 } >> 660 } else { >> 661 fprintf (file, "newpath\n"); >> 662 fprintf (file, "%g %g %g setrgbcolor\n", red, green, blue); >> 663 fprintf (file, "%g %g moveto\n", vertex[0].x, vertex[0].y); >> 664 for (i=1; i<nvertices; i++) { >> 665 fprintf (file, "%g %g lineto\n", vertex[i].x, vertex[i].y); >> 666 } >> 667 fprintf (file, "closepath fill\n\n"); >> 668 } 1108 } 669 } 1109 } << 670 loc += nvertices*7; 1110 } << 671 break; 1111 << 1112 void G4OpenGLViewer::rotateSceneThetaPhi(G4do << 1113 { << 1114 if (!fSceneHandler.GetScene()) { << 1115 return; << 1116 } << 1117 672 1118 G4Vector3D vp; << 673 case GL_POINT_TOKEN: 1119 G4Vector3D up; << 674 vertex=(Feedback3Dcolor*)loc; 1120 << 675 if (print_colour) { 1121 G4Vector3D xprime; << 676 fprintf (file, "%g %g %g setrgbcolor\n", vertex[0].red, vertex[0].green, vertex[0].blue); 1122 G4Vector3D yprime; << 677 } else { 1123 G4Vector3D zprime; << 678 intensity = vertex[0].red + vertex[0].green + vertex[0].blue; 1124 << 679 intensity/=3.0; 1125 G4double delta_alpha; << 680 fprintf (file, "%g %g %g setrgbcolor\n", intensity, intensity, intensity); 1126 G4double delta_theta; << 681 } 1127 << 682 fprintf(file, "%g %g %g 0 360 arc fill\n\n", vertex[0].x, vertex[0].y, pointSize / 2.0); 1128 G4Vector3D new_vp; << 683 loc += 7; /* Each vertex element in the feedback 1129 G4Vector3D new_up; << 684 buffer is 7 GLfloats. */ 1130 << 685 break; 1131 G4double cosalpha; << 686 default: 1132 G4double sinalpha; << 687 /* XXX Left as an excersie to the reader. */ 1133 << 688 static G4bool spewPrimitiveEPSWarned = false; 1134 G4Vector3D a1; << 689 if (!spewPrimitiveEPSWarned) { 1135 G4Vector3D a2; << 690 std::ostringstream oss; 1136 G4Vector3D delta; << 691 oss << 1137 G4Vector3D viewPoint; << 692 "Incomplete implementation. Unexpected token (" << token << ")." >> 693 "\n (Seems to be caused by text.)"; >> 694 G4Exception("G4OpenGLViewer::spewPrimitiveEPS", >> 695 "Unexpected token", >> 696 JustWarning, >> 697 oss.str().c_str()); >> 698 spewPrimitiveEPSWarned = true; >> 699 } >> 700 } >> 701 return loc; >> 702 } >> 703 >> 704 typedef struct G4OpenGLViewerDepthIndex { >> 705 GLfloat *ptr; >> 706 GLfloat depth; >> 707 } DepthIndex; 1138 708 >> 709 extern "C" { >> 710 int G4OpenGLViewercompare(const void *a, const void *b) >> 711 { >> 712 const DepthIndex *p1 = (DepthIndex *) a; >> 713 const DepthIndex *p2 = (DepthIndex *) b; >> 714 GLfloat diff = p2->depth - p1->depth; 1139 715 1140 //phi spin stuff here << 716 if (diff > 0.0) { 1141 << 717 return 1; 1142 vp = fVP.GetViewpointDirection ().unit (); << 718 } else if (diff < 0.0) { 1143 up = fVP.GetUpVector ().unit (); << 719 return -1; 1144 << 720 } else { 1145 yprime = (up.cross(vp)).unit(); << 721 return 0; 1146 zprime = (vp.cross(yprime)).unit(); << 1147 << 1148 if (fVP.GetLightsMoveWithCamera()) { << 1149 delta_alpha = dy * fRot_sens; << 1150 delta_theta = -dx * fRot_sens; << 1151 } else { << 1152 delta_alpha = -dy * fRot_sens; << 1153 delta_theta = dx * fRot_sens; << 1154 } << 1155 << 1156 delta_alpha *= CLHEP::deg; << 1157 delta_theta *= CLHEP::deg; << 1158 << 1159 new_vp = std::cos(delta_alpha) * vp + std:: << 1160 << 1161 // to avoid z rotation flipping << 1162 // to allow more than 360° rotation << 1163 << 1164 if (fVP.GetLightsMoveWithCamera()) { << 1165 new_up = (new_vp.cross(yprime)).unit(); << 1166 if (new_vp.z()*vp.z() <0) { << 1167 new_up.set(new_up.x(),-new_up.y(),new_u << 1168 } << 1169 } else { << 1170 new_up = up; << 1171 if (new_vp.z()*vp.z() <0) { << 1172 new_up.set(new_up.x(),-new_up.y(),new_u << 1173 } 722 } 1174 } 723 } 1175 fVP.SetUpVector(new_up); << 1176 //////////////// << 1177 // Rotates by fixed azimuthal angle delta_t << 1178 << 1179 cosalpha = new_up.dot (new_vp.unit()); << 1180 sinalpha = std::sqrt (1. - std::pow (cosalp << 1181 yprime = (new_up.cross (new_vp.unit())).uni << 1182 xprime = yprime.cross (new_up); << 1183 // Projection of vp on plane perpendicular << 1184 a1 = sinalpha * xprime; << 1185 // Required new projection... << 1186 a2 = sinalpha * (std::cos (delta_theta) * x << 1187 // Required Increment vector... << 1188 delta = a2 - a1; << 1189 // So new viewpoint is... << 1190 viewPoint = new_vp.unit() + delta; << 1191 << 1192 fVP.SetViewAndLights (viewPoint); << 1193 } 724 } 1194 725 1195 << 726 void G4OpenGLViewer::spewSortedFeedback(FILE * file, GLint size, GLfloat * buffer) 1196 void G4OpenGLViewer::rotateSceneInViewDirecti << 1197 { 727 { 1198 if (!fSceneHandler.GetScene()) { << 728 int token; 1199 return; << 729 GLfloat *loc, *end; 1200 } << 730 Feedback3Dcolor *vertex; 1201 << 731 GLfloat depthSum; 1202 G4Vector3D vp; << 732 int nprimitives, item; 1203 G4Vector3D up; << 733 DepthIndex *prims; 1204 << 734 int nvertices, i; 1205 G4Vector3D xprime; << 735 1206 G4Vector3D yprime; << 736 end = buffer + size; 1207 G4Vector3D zprime; << 737 1208 << 738 /* Count how many primitives there are. */ 1209 G4Vector3D new_vp; << 739 nprimitives = 0; 1210 G4Vector3D new_up; << 740 loc = buffer; 1211 << 741 while (loc < end) { 1212 G4Vector3D a1; << 742 token = int (*loc); 1213 G4Vector3D a2; << 743 loc++; 1214 G4Vector3D delta; << 744 switch (token) { 1215 G4Vector3D viewPoint; << 745 case GL_LINE_TOKEN: 1216 << 746 case GL_LINE_RESET_TOKEN: 1217 dx = dx/100; << 747 loc += 14; 1218 dy = dy/100; << 748 nprimitives++; 1219 << 749 break; 1220 //phi spin stuff here << 750 case GL_POLYGON_TOKEN: 1221 << 751 nvertices = int (*loc); 1222 vp = fVP.GetViewpointDirection ().unit(); << 752 loc++; 1223 up = fVP.GetUpVector ().unit(); << 753 loc += (7 * nvertices); 1224 << 754 nprimitives++; 1225 G4Vector3D zPrimeVector = G4Vector3D(up.y() << 755 break; 1226 up.z()*vp.x()-up << 756 case GL_POINT_TOKEN: 1227 up.x()*vp.y()-up << 757 loc += 7; 1228 << 758 nprimitives++; 1229 viewPoint = vp/fRot_sens + (zPrimeVector*dx << 759 break; 1230 new_up = G4Vector3D(viewPoint.y()*zPrimeVec << 760 default: 1231 viewPoint.z()*zPrimeVe << 761 /* XXX Left as an excersie to the reader. */ 1232 viewPoint.x()*zPrimeVe << 762 static G4bool spewSortedFeedbackWarned = false; 1233 << 763 if (!spewSortedFeedbackWarned) { 1234 G4Vector3D new_upUnit = new_up.unit(); << 764 std::ostringstream oss; 1235 << 765 oss << 1236 << 766 "Incomplete implementation. Unexpected token (" << token << ")." 1237 << 767 "\n (Seems to be caused by text.)"; 1238 fVP.SetUpVector(new_upUnit); << 768 G4Exception("G4OpenGLViewer::spewSortedFeedback", 1239 fVP.SetViewAndLights (viewPoint); << 769 "Unexpected token", 1240 } << 770 JustWarning, 1241 << 771 oss.str().c_str()); 1242 << 772 spewSortedFeedbackWarned = true; 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 } 773 } 1261 return true; << 774 nprimitives++; 1262 } << 1263 } << 1264 if (! found) { << 1265 if (format.size() == 0) { << 1266 G4cout << " Current formats availables << 1267 } else { << 1268 G4cerr << " Format \"" << format << "\" << 1269 } 775 } 1270 } 776 } 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 777 >> 778 /* Allocate an array of pointers that will point back at >> 779 primitives in the feedback buffer. There will be one >> 780 entry per primitive. This array is also where we keep the >> 781 primitive's average depth. There is one entry per >> 782 primitive in the feedback buffer. */ >> 783 prims = (DepthIndex *) malloc(sizeof(DepthIndex) * nprimitives); >> 784 >> 785 item = 0; >> 786 loc = buffer; >> 787 while (loc < end) { >> 788 prims[item].ptr = loc; /* Save this primitive's location. */ >> 789 token = int (*loc); >> 790 loc++; >> 791 switch (token) { >> 792 case GL_LINE_TOKEN: >> 793 case GL_LINE_RESET_TOKEN: >> 794 vertex = (Feedback3Dcolor *) loc; >> 795 depthSum = vertex[0].z + vertex[1].z; >> 796 prims[item].depth = depthSum / 2.0; >> 797 loc += 14; >> 798 break; >> 799 case GL_POLYGON_TOKEN: >> 800 nvertices = int (*loc); >> 801 loc++; >> 802 vertex = (Feedback3Dcolor *) loc; >> 803 depthSum = vertex[0].z; >> 804 for (i = 1; i < nvertices; i++) { >> 805 depthSum += vertex[i].z; >> 806 } >> 807 prims[item].depth = depthSum / nvertices; >> 808 loc += (7 * nvertices); >> 809 break; >> 810 case GL_POINT_TOKEN: >> 811 vertex = (Feedback3Dcolor *) loc; >> 812 prims[item].depth = vertex[0].z; >> 813 loc += 7; >> 814 break; >> 815 default: >> 816 /* XXX Left as an excersie to the reader. */ >> 817 assert(1); >> 818 } >> 819 item++; >> 820 } >> 821 assert(item == nprimitives); >> 822 >> 823 /* Sort the primitives back to front. */ >> 824 qsort(prims, nprimitives, sizeof(DepthIndex), G4OpenGLViewercompare); >> 825 >> 826 /* Understand that sorting by a primitives average depth >> 827 doesn't allow us to disambiguate some cases like self >> 828 intersecting polygons. Handling these cases would require >> 829 breaking up the primitives. That's too involved for this >> 830 example. Sorting by depth is good enough for lots of >> 831 applications. */ >> 832 >> 833 /* Emit the Encapsulated PostScript for the primitives in >> 834 back to front order. */ >> 835 for (item = 0; item < nprimitives; item++) { >> 836 (void) spewPrimitiveEPS(file, prims[item].ptr); >> 837 } 1421 838 1422 void G4OpenGLViewer::g4GlFrustum (GLdouble le << 839 free(prims); 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 } 840 } 1446 841 1447 G4String G4OpenGLViewerPickMap::print() { << 842 #endif 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 843