Geant4  10.00.p03
G4OpenGLViewer.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4OpenGLViewer.cc 75567 2013-11-04 11:35:11Z gcosmo $
28 //
29 //
30 // Andrew Walkden 27th March 1996
31 // OpenGL view - opens window, hard copy, etc.
32 
33 #ifdef G4VIS_BUILD_OPENGL_DRIVER
34 
35 #include "G4ios.hh"
36 #include "G4SystemOfUnits.hh"
37 #include "G4OpenGLViewer.hh"
38 #include "G4OpenGLSceneHandler.hh"
39 #include "G4OpenGLTransform3D.hh"
40 #include "G4OpenGL2PSAction.hh"
41 
42 #include "G4Scene.hh"
43 #include "G4VisExtent.hh"
44 #include "G4LogicalVolume.hh"
45 #include "G4VSolid.hh"
46 #include "G4Point3D.hh"
47 #include "G4Normal3D.hh"
48 #include "G4Plane3D.hh"
49 #include "G4AttHolder.hh"
50 #include "G4AttCheck.hh"
51 #include "G4Text.hh"
52 
53 #ifdef G4VIS_BUILD_OPENGLWT_DRIVER
54 // We need to have a Wt gl drawer because we will draw inside the WtGL component (ImmediateWtViewer)
55 #include "G4OpenGLWtDrawer.hh"
56 #endif
57 
58 // GL2PS
59 #include "Geant4_gl2ps.h"
60 
61 #include <sstream>
62 
63 G4int G4OpenGLViewer::fPrintSizeX = -1;
64 G4int G4OpenGLViewer::fPrintSizeY = -1;
65 G4String G4OpenGLViewer::fPrintFilename = "G4OpenGL";
66 int G4OpenGLViewer::fPrintFilenameIndex = 0;
67 
68 G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene):
69 G4VViewer (scene, -1),
70 #ifdef G4VIS_BUILD_OPENGLWT_DRIVER
71 fWtDrawer(NULL),
72 #endif
73 fPrintColour (true),
74 fVectoredPs (true),
75 fOpenGLSceneHandler(scene),
76 background (G4Colour(0.,0.,0.)),
77 transparency_enabled (true),
78 antialiasing_enabled (false),
79 haloing_enabled (false),
80 fStartTime(-DBL_MAX),
81 fEndTime(DBL_MAX),
82 fFadeFactor(0.),
83 fDisplayHeadTime(false),
84 fDisplayHeadTimeX(-0.9),
85 fDisplayHeadTimeY(-0.9),
86 fDisplayHeadTimeSize(24.),
87 fDisplayHeadTimeRed(0.),
88 fDisplayHeadTimeGreen(1.),
89 fDisplayHeadTimeBlue(1.),
90 fDisplayLightFront(false),
91 fDisplayLightFrontX(0.),
92 fDisplayLightFrontY(0.),
93 fDisplayLightFrontZ(0.),
94 fDisplayLightFrontT(0.),
95 fDisplayLightFrontRed(0.),
96 fDisplayLightFrontGreen(1.),
97 fDisplayLightFrontBlue(0.),
98 fRot_sens(1.),
99 fPan_sens(0.01),
100 fWinSize_x(0),
101 fWinSize_y(0),
102 fPointSize (0),
103 fSizeHasChanged(0),
104 fGl2psDefaultLineWith(1),
105 fGl2psDefaultPointSize(2)
106 {
107 #ifdef G4DEBUG_VIS_OGL
108  printf("G4OpenGLViewer:: Creation\n");
109 #endif
110  // Make changes to view parameters for OpenGL...
111  fVP.SetAutoRefresh(true);
112  fDefaultVP.SetAutoRefresh(true);
113 
114  fGL2PSAction = new G4OpenGL2PSAction();
115 
116  // glClearColor (0.0, 0.0, 0.0, 0.0);
117  // glClearDepth (1.0);
118  // glDisable (GL_BLEND);
119  // glDisable (GL_LINE_SMOOTH);
120  // glDisable (GL_POLYGON_SMOOTH);
121 
122 }
123 
124 G4OpenGLViewer::~G4OpenGLViewer ()
125 {
126  delete fGL2PSAction;
127 }
128 
129 void G4OpenGLViewer::InitializeGLView ()
130 {
131 #ifdef G4OPENGL_VERSION_2
132 
133  const char *fragmentShaderSrc =
134  "#ifdef GL_ES\n"
135  "precision highp float;\n"
136  "#endif\n"
137  "\n"
138  "varying vec3 vLightWeighting;\n"
139  "uniform vec4 uPointColor; // Point Color\n"
140  "\n"
141  "void main(void) {\n"
142  " vec4 matColor = uPointColor;\n"
143  " gl_FragColor = vec4(matColor.rgb, matColor.a);\n"
144  "}\n";
145 
146 
147 
148  const char *vertexShaderSrc =
149  "attribute vec3 aVertexPosition;\n"
150  "attribute vec3 aVertexNormal;\n"
151  "\n"
152  "uniform mat4 uMVMatrix; // [M]odel[V]iew matrix\n"
153  "uniform mat4 uCMatrix; // Client-side manipulated [C]amera matrix\n"
154  "uniform mat4 uPMatrix; // Perspective [P]rojection matrix\n"
155  "uniform mat4 uNMatrix; // [N]ormal transformation\n"
156  "// uNMatrix is the transpose of the inverse of uCMatrix * uMVMatrix\n"
157  "uniform mat4 uTMatrix; // [T]ransformation matrix\n"
158  "uniform float uPointSize; // Point size\n"
159  "\n"
160  "varying vec3 vLightWeighting;\n"
161  "\n"
162  "void main(void) {\n"
163  " // Calculate the position of this vertex\n"
164  " gl_Position = uPMatrix * uCMatrix * uMVMatrix * uTMatrix * vec4(aVertexPosition, 1.0);\n"
165  "\n"
166  " // Phong shading\n"
167  " vec3 transformedNormal = normalize((uNMatrix * vec4(normalize(aVertexNormal), 0)).xyz);\n"
168  " vec3 lightingDirection = normalize(vec3(1, 1, 1));\n"
169  " float directionalLightWeighting = max(dot(transformedNormal, lightingDirection), 0.0);\n"
170  " vec3 uAmbientLightColor = vec3(0.2, 0.2, 0.2);\n"
171  " vec3 uDirectionalColor = vec3(0.8, 0.8, 0.8);\n"
172  " gl_PointSize = uPointSize;\n"
173  " vLightWeighting = uAmbientLightColor + uDirectionalColor * directionalLightWeighting;\n"
174  "}\n";
175 
176  vertexShader_ = vertexShaderSrc;
177  fragmentShader_ = fragmentShaderSrc;
178 
179 
180 
181  // First, load a simple shader
182  Shader fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
183  const char *frag = fragmentShader_.c_str();
184  glShaderSource(fragmentShader, 1, &frag, NULL);
185  glCompileShader(fragmentShader);
186  Shader vertexShader = glCreateShader(GL_VERTEX_SHADER);
187  const char *vert = vertexShader_.c_str();
188  glShaderSource(vertexShader, 1, &vert, NULL);
189  glCompileShader(vertexShader);
190  shaderProgram_ = glCreateProgram();
191  glAttachShader(shaderProgram_, vertexShader);
192  glAttachShader(shaderProgram_, fragmentShader);
193  glLinkProgram(shaderProgram_);
194  glUseProgram(shaderProgram_);
195 
196  // UniformLocation uColor = getUniformLocation(shaderProgram_, "uColor");
197  // uniform4fv(uColor, [0.0, 0.3, 0.0, 1.0]);
198 
199  // Extract the references to the attributes from the shader.
200 
201  vertexPositionAttribute_ =
202  glGetAttribLocation(shaderProgram_, "aVertexPosition");
203  glEnableVertexAttribArray(vertexPositionAttribute_);
204 
205  // Extract the references the uniforms from the shader
206  pMatrixUniform_ = glGetUniformLocation(shaderProgram_, "uPMatrix");
207  cMatrixUniform_ = glGetUniformLocation(shaderProgram_, "uCMatrix");
208  mvMatrixUniform_ = glGetUniformLocation(shaderProgram_, "uMVMatrix");
209  nMatrixUniform_ = glGetUniformLocation(shaderProgram_, "uNMatrix");
210  tMatrixUniform_ = glGetUniformLocation(shaderProgram_, "uTMatrix");
211 
212 #endif
213 
214 #ifdef G4DEBUG_VIS_OGL
215  printf("G4OpenGLViewer::InitializeGLView\n");
216 #endif
217 
218  fWinSize_x = fVP.GetWindowSizeHintX();
219  fWinSize_y = fVP.GetWindowSizeHintY();
220 
221  glClearColor (0.0, 0.0, 0.0, 0.0);
222  glClearDepth (1.0);
223  glDisable (GL_LINE_SMOOTH);
224  glDisable (GL_POLYGON_SMOOTH);
225 
226 // clear the buffers and window?
227  ClearView ();
228  FinishView ();
229 
230  glDepthFunc (GL_LEQUAL);
231  glDepthMask (GL_TRUE);
232 
233  glEnable (GL_BLEND);
234  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
235 
236 #ifdef G4DEBUG_VIS_OGL
237  printf("G4OpenGLViewer::InitializeGLView END\n");
238 #endif
239 }
240 
241 void G4OpenGLViewer::ClearView () {
242 #ifdef G4DEBUG_VIS_OGL
243  printf("G4OpenGLViewer::ClearView\n");
244 #endif
245  glClearColor (background.GetRed(),
246  background.GetGreen(),
247  background.GetBlue(),
248  1.);
249  glClearDepth (1.0);
250  //Below line does not compile with Mesa includes.
251  //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
252  glClear (GL_COLOR_BUFFER_BIT);
253  glClear (GL_DEPTH_BUFFER_BIT);
254  glClear (GL_STENCIL_BUFFER_BIT);
255 #ifdef G4DEBUG_VIS_OGL
256  printf("G4OpenGLViewer::ClearView flush\n");
257 #endif
258  glFlush ();
259 }
260 
261 
262 void G4OpenGLViewer::ResizeWindow(unsigned int aWidth, unsigned int aHeight) {
263  if ((fWinSize_x != aWidth) || (fWinSize_y != aHeight)) {
264  fWinSize_x = aWidth;
265  fWinSize_y = aHeight;
266  fSizeHasChanged = true;
267  } else {
268  fSizeHasChanged = false;
269  }
270 }
271 
278 void G4OpenGLViewer::ResizeGLView()
279 {
280 #ifdef G4DEBUG_VIS_OGL
281  printf("G4OpenGLViewer::ResizeGLView %d %d %#lx\n",fWinSize_x,fWinSize_y,(unsigned long)this);
282 #endif
283  // Check size
284  GLint dims[2];
285  dims[0] = 0;
286  dims[1] = 0;
287 
288  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
289 
290  if ((dims[0] !=0 ) && (dims[1] !=0)) {
291 
292  if (fWinSize_x > (unsigned)dims[0]) {
293  G4cerr << "Try to resize view greater than max X viewport dimension. Desired size "<<fWinSize_x <<" is resize to "<< dims[0] << G4endl;
294  fWinSize_x = dims[0];
295  }
296  if (fWinSize_y > (unsigned)dims[1]) {
297  G4cerr << "Try to resize view greater than max Y viewport dimension. Desired size "<<fWinSize_y <<" is resize to "<< dims[1] << G4endl;
298  fWinSize_y = dims[1];
299  }
300  }
301 
302  glViewport(0, 0, fWinSize_x,fWinSize_y);
303 
304 
305 }
306 
307 
308 void G4OpenGLViewer::SetView () {
309 
310  if (!fSceneHandler.GetScene()) {
311  return;
312  }
313  // Calculates view representation based on extent of object being
314  // viewed and (initial) viewpoint. (Note: it can change later due
315  // to user interaction via visualization system's GUI.)
316 
317  // Lighting.
318  GLfloat lightPosition [4];
319  lightPosition [0] = fVP.GetActualLightpointDirection().x();
320  lightPosition [1] = fVP.GetActualLightpointDirection().y();
321  lightPosition [2] = fVP.GetActualLightpointDirection().z();
322  lightPosition [3] = 0.;
323  // Light position is "true" light direction, so must come after gluLookAt.
324  GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.};
325  GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.};
326  glEnable (GL_LIGHT0);
327  glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
328  glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
329 
330  G4double ratioX = 1;
331  G4double ratioY = 1;
332  if (fWinSize_y > fWinSize_x) {
333  ratioX = ((G4double)fWinSize_y) / ((G4double)fWinSize_x);
334  }
335  if (fWinSize_x > fWinSize_y) {
336  ratioY = ((G4double)fWinSize_x) / ((G4double)fWinSize_y);
337  }
338 
339  // Get radius of scene, etc.
340  // Note that this procedure properly takes into account zoom, dolly and pan.
341  const G4Point3D targetPoint
342  = fSceneHandler.GetScene()->GetStandardTargetPoint()
343  + fVP.GetCurrentTargetPoint ();
344  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
345  if(radius<=0.) radius = 1.;
346  const G4double cameraDistance = fVP.GetCameraDistance (radius);
347  const G4Point3D cameraPosition =
348  targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
349  const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
350  const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
351  const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius) * ratioY;
352  const GLdouble left = -right;
353  const GLdouble top = fVP.GetFrontHalfHeight (pnear, radius) * ratioX;
354  const GLdouble bottom = -top;
355 
356  // FIXME
357  ResizeGLView();
358  //SHOULD SetWindowsSizeHint()...
359 
360  glMatrixMode (GL_PROJECTION); // set up Frustum.
361  glLoadIdentity();
362 
363  const G4Vector3D scaleFactor = fVP.GetScaleFactor();
364  glScaled(scaleFactor.x(),scaleFactor.y(),scaleFactor.z());
365 
366  if (fVP.GetFieldHalfAngle() == 0.) {
367  glOrtho (left, right, bottom, top, pnear, pfar);
368  }
369  else {
370  glFrustum (left, right, bottom, top, pnear, pfar);
371  }
372 
373  glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
374  glLoadIdentity();
375 
376  const G4Normal3D& upVector = fVP.GetUpVector ();
377  G4Point3D gltarget;
378  if (cameraDistance > 1.e-6 * radius) {
379  gltarget = targetPoint;
380  }
381  else {
382  gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit();
383  }
384 
385  const G4Point3D& pCamera = cameraPosition; // An alias for brevity.
386  gluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint.
387  gltarget.x(), gltarget.y(), gltarget.z(), // Target point.
388  upVector.x(), upVector.y(), upVector.z()); // Up vector.
389 
390  // Light position is "true" light direction, so must come after gluLookAt.
391  glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
392 
393  // OpenGL no longer seems to reconstruct clipped edges, so, when the
394  // BooleanProcessor is up to it, abandon this and use generic
395  // clipping in G4OpenGLSceneHandler::CreateSectionPolyhedron. Also,
396  // force kernel visit on change of clipping plane in
397  // G4OpenGLStoredViewer::CompareForKernelVisit.
398  //if (fVP.IsSection () ) { // pair of back to back clip planes.
399  if (false) { // pair of back to back clip planes.
400  const G4Plane3D& sp = fVP.GetSectionPlane ();
401  double sArray[4];
402  sArray[0] = sp.a();
403  sArray[1] = sp.b();
404  sArray[2] = sp.c();
405  sArray[3] = sp.d() + radius * 1.e-05;
406  glClipPlane (GL_CLIP_PLANE0, sArray);
407  glEnable (GL_CLIP_PLANE0);
408  sArray[0] = -sp.a();
409  sArray[1] = -sp.b();
410  sArray[2] = -sp.c();
411  sArray[3] = -sp.d() + radius * 1.e-05;
412  glClipPlane (GL_CLIP_PLANE1, sArray);
413  glEnable (GL_CLIP_PLANE1);
414  } else {
415  glDisable (GL_CLIP_PLANE0);
416  glDisable (GL_CLIP_PLANE1);
417  }
418 
419  // What we call intersection of cutaways is easy in OpenGL. You
420  // just keep cutting. Unions are more tricky - you have to have
421  // multiple passes and this is handled in
422  // G4OpenGLImmediate/StoredViewer::ProcessView.
423  const G4Planes& cutaways = fVP.GetCutawayPlanes();
424  size_t nPlanes = cutaways.size();
425  if (fVP.IsCutaway() &&
426  fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection &&
427  nPlanes > 0) {
428  double a[4];
429  a[0] = cutaways[0].a();
430  a[1] = cutaways[0].b();
431  a[2] = cutaways[0].c();
432  a[3] = cutaways[0].d();
433  glClipPlane (GL_CLIP_PLANE2, a);
434  glEnable (GL_CLIP_PLANE2);
435  if (nPlanes > 1) {
436  a[0] = cutaways[1].a();
437  a[1] = cutaways[1].b();
438  a[2] = cutaways[1].c();
439  a[3] = cutaways[1].d();
440  glClipPlane (GL_CLIP_PLANE3, a);
441  glEnable (GL_CLIP_PLANE3);
442  }
443  if (nPlanes > 2) {
444  a[0] = cutaways[2].a();
445  a[1] = cutaways[2].b();
446  a[2] = cutaways[2].c();
447  a[3] = cutaways[2].d();
448  glClipPlane (GL_CLIP_PLANE4, a);
449  glEnable (GL_CLIP_PLANE4);
450  }
451  } else {
452  glDisable (GL_CLIP_PLANE2);
453  glDisable (GL_CLIP_PLANE3);
454  glDisable (GL_CLIP_PLANE4);
455  }
456 
457  // Background.
458  background = fVP.GetBackgroundColour ();
459 
460 }
461 
462 
463 
464 void G4OpenGLViewer::ResetView () {
466  fRot_sens = 1;
467  fPan_sens = 0.01;
468 }
469 
470 
471 void G4OpenGLViewer::HaloingFirstPass () {
472 
473  //To perform haloing, first Draw all information to the depth buffer
474  //alone, using a chunky line width, and then Draw all info again, to
475  //the colour buffer, setting a thinner line width an the depth testing
476  //function to less than or equal, so if two lines cross, the one
477  //passing behind the other will not pass the depth test, and so not
478  //get rendered either side of the infront line for a short distance.
479 
480  //First, disable writing to the colo(u)r buffer...
481  glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
482 
483  //Now enable writing to the depth buffer...
484  glDepthMask (GL_TRUE);
485  glDepthFunc (GL_LESS);
486  glClearDepth (1.0);
487 
488  //Finally, set the line width to something wide...
489  ChangeLineWidth(3.0);
490 
491 }
492 
493 void G4OpenGLViewer::HaloingSecondPass () {
494 
495  //And finally, turn the colour buffer back on with a sesible line width...
496  glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
497  glDepthFunc (GL_LEQUAL);
498  ChangeLineWidth(1.0);
499 
500 }
501 
502 void G4OpenGLViewer::Pick(GLdouble x, GLdouble y)
503 {
504  //G4cout << "X: " << x << ", Y: " << y << G4endl;
505  const G4int BUFSIZE = 512;
506  GLuint selectBuffer[BUFSIZE];
507  glSelectBuffer(BUFSIZE, selectBuffer);
508  glRenderMode(GL_SELECT);
509  glInitNames();
510  glPushName(0);
511  glMatrixMode(GL_PROJECTION);
512  G4double currentProjectionMatrix[16];
513  glGetDoublev(GL_PROJECTION_MATRIX, currentProjectionMatrix);
514  glPushMatrix();
515  glLoadIdentity();
516  GLint viewport[4];
517  glGetIntegerv(GL_VIEWPORT, viewport);
518  // Define 5x5 pixel pick area
519  gluPickMatrix(x, viewport[3] - y, 5., 5., viewport);
520  glMultMatrixd(currentProjectionMatrix);
521  glMatrixMode(GL_MODELVIEW);
522  DrawView();
523  GLint hits = glRenderMode(GL_RENDER);
524  if (hits < 0)
525  G4cout << "Too many hits. Zoom in to reduce overlaps." << G4endl;
526  else if (hits > 0) {
527  G4cout << hits << " hit(s)" << G4endl;
528  GLuint* p = selectBuffer;
529  for (GLint i = 0; i < hits; ++i) {
530  GLuint nnames = *p++;
531  // This bit of debug code or...
532  //GLuint zmin = *p++;
533  //GLuint zmax = *p++;
534  //G4cout << "Hit " << i << ": " << nnames << " names"
535  // << "\nzmin: " << zmin << ", zmax: " << zmax << G4endl;
536  // ...just increment the pointer
537  p++;
538  p++;
539  for (GLuint j = 0; j < nnames; ++j) {
540  GLuint name = *p++;
541  G4cout << "Hit: " << i
542  << ", Sub-hit: " << j
543  << ", PickName: " << name << G4endl;
544  std::map<GLuint, G4AttHolder*>::iterator iter =
545  fOpenGLSceneHandler.fPickMap.find(name);
546  if (iter != fOpenGLSceneHandler.fPickMap.end()) {
547  G4AttHolder* attHolder = iter->second;
548  if(attHolder && attHolder->GetAttDefs().size()) {
549  for (size_t iAtt = 0;
550  iAtt < attHolder->GetAttDefs().size(); ++iAtt) {
551  G4cout << G4AttCheck(attHolder->GetAttValues()[iAtt],
552  attHolder->GetAttDefs()[iAtt]);
553  }
554  }
555  }
556  }
557  G4cout << G4endl;
558  }
559  }
560  glMatrixMode(GL_PROJECTION);
561  glPopMatrix();
562  glMatrixMode(GL_MODELVIEW);
563 }
564 
565 
566 
567 
568 GLubyte* G4OpenGLViewer::grabPixels (int inColor, unsigned int width, unsigned int height) {
569 
570  GLubyte* buffer;
571  GLint swapbytes, lsbfirst, rowlength;
572  GLint skiprows, skippixels, alignment;
573  GLenum format;
574  int size;
575 
576  if (inColor) {
577  format = GL_RGB;
578  size = width*height*3;
579  } else {
580  format = GL_LUMINANCE;
581  size = width*height*1;
582  }
583 
584  buffer = new GLubyte[size];
585  if (buffer == NULL)
586  return NULL;
587 
588  glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
589  glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
590  glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
591 
592  glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
593  glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
594  glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
595 
596  glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
597  glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
598  glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
599 
600  glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
601  glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
602  glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
603 
604  glReadBuffer(GL_FRONT);
605  glReadPixels (0, 0, (GLsizei)width, (GLsizei)height, format, GL_UNSIGNED_BYTE, (GLvoid*) buffer);
606 
607  glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbytes);
608  glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst);
609  glPixelStorei (GL_UNPACK_ROW_LENGTH, rowlength);
610 
611  glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows);
612  glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippixels);
613  glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
614 
615  return buffer;
616 }
617 
618 void G4OpenGLViewer::printEPS() {
619  bool res;
620 #ifdef G4DEBUG_VIS_OGL
621  printf("G4OpenGLViewer::printEPS file:%s Vec:%d Name:%s\n",getRealPrintFilename().c_str(),fVectoredPs,GetName().c_str());
622 #endif
623 
624  // Change the LC_NUMERIC value in order to have "." separtor and not ","
625  // This case is only useful for French, Canadien...
626  size_t len = strlen(setlocale(LC_NUMERIC,NULL));
627  char* oldLocale = (char*)(malloc(len+1));
628  if(oldLocale!=NULL) strncpy(oldLocale,setlocale(LC_NUMERIC,NULL),len);
629  setlocale(LC_NUMERIC,"C");
630 
631  if (fVectoredPs) {
632  res = printVectoredEPS();
633  } else {
634  res = printNonVectoredEPS();
635  }
636 
637  // restore the local
638  if (oldLocale) {
639  setlocale(LC_NUMERIC,oldLocale);
640  free(oldLocale);
641  }
642 
643  if (res == false) {
644  G4cerr << "Error while saving file... "<<getRealPrintFilename().c_str()<< G4endl;
645  } else {
646  G4cout << "File "<<getRealPrintFilename().c_str()<<" has been saved " << G4endl;
647  }
648 
649  // increment index if necessary
650  if ( fPrintFilenameIndex != -1) {
651  fPrintFilenameIndex++;
652  }
653 
654 #ifdef G4DEBUG_VIS_OGL
655  printf("G4OpenGLViewer::printEPS END\n");
656 #endif
657 }
658 
659 bool G4OpenGLViewer::printVectoredEPS() {
660  return printGl2PS();
661 }
662 
663 bool G4OpenGLViewer::printNonVectoredEPS () {
664 
665  int width = getRealPrintSizeX();
666  int height = getRealPrintSizeY();
667 
668 #ifdef G4DEBUG_VIS_OGL
669  printf("G4OpenGLViewer::printNonVectoredEPS file:%s Vec:%d X:%d Y:%d col:%d fWinX:%d fWinY:%d\n",getRealPrintFilename().c_str(),fVectoredPs,width,height,fPrintColour,fWinSize_x,fWinSize_y);
670 #endif
671  FILE* fp;
672  GLubyte* pixels;
673  GLubyte* curpix;
674  int components, pos, i;
675 
676  pixels = grabPixels (fPrintColour, width, height);
677 
678  if (pixels == NULL) {
679  G4cerr << "Failed to get pixels from OpenGl viewport" << G4endl;
680  return false;
681  }
682  if (fPrintColour) {
683  components = 3;
684  } else {
685  components = 1;
686  }
687  std::string name = getRealPrintFilename();
688  fp = fopen (name.c_str(), "w");
689  if (fp == NULL) {
690  G4cerr << "Can't open filename " << name.c_str() << G4endl;
691  return false;
692  }
693 
694  fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
695  fprintf (fp, "%%%%Title: %s\n", name.c_str());
696  fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
697  fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
698  fprintf (fp, "%%%%EndComments\n");
699  fprintf (fp, "gsave\n");
700  fprintf (fp, "/bwproc {\n");
701  fprintf (fp, " rgbproc\n");
702  fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
703  fprintf (fp, " 5 -1 roll {\n");
704  fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
705  fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
706  fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
707  fprintf (fp, " { 2 1 roll } ifelse\n");
708  fprintf (fp, " }forall\n");
709  fprintf (fp, " pop pop pop\n");
710  fprintf (fp, "} def\n");
711  fprintf (fp, "systemdict /colorimage known not {\n");
712  fprintf (fp, " /colorimage {\n");
713  fprintf (fp, " pop\n");
714  fprintf (fp, " pop\n");
715  fprintf (fp, " /rgbproc exch def\n");
716  fprintf (fp, " { bwproc } image\n");
717  fprintf (fp, " } def\n");
718  fprintf (fp, "} if\n");
719  fprintf (fp, "/picstr %d string def\n", width * components);
720  fprintf (fp, "%d %d scale\n", width, height);
721  fprintf (fp, "%d %d %d\n", width, height, 8);
722  fprintf (fp, "[%d 0 0 %d 0 0]\n", width, height);
723  fprintf (fp, "{currentfile picstr readhexstring pop}\n");
724  fprintf (fp, "false %d\n", components);
725  fprintf (fp, "colorimage\n");
726 
727  curpix = (GLubyte*) pixels;
728  pos = 0;
729  for (i = width*height*components; i>0; i--) {
730  fprintf (fp, "%02hx ", (unsigned short)(*(curpix++)));
731  if (++pos >= 32) {
732  fprintf (fp, "\n");
733  pos = 0;
734  }
735  }
736  if (pos)
737  fprintf (fp, "\n");
738 
739  fprintf (fp, "grestore\n");
740  fprintf (fp, "showpage\n");
741  delete [] pixels;
742  fclose (fp);
743 
744  // Reset for next time (useful is size change)
745  // fPrintSizeX = -1;
746  // fPrintSizeY = -1;
747 
748  return true;
749 }
750 
753 bool G4OpenGLViewer::isGl2psWriting() {
754 
755  if (!fGL2PSAction) return false;
756  if (fGL2PSAction->fileWritingEnabled()) {
757  return true;
758  }
759  return false;
760 }
761 
762 
763 /* Draw Gl2Ps text if needed
764  */
765 void G4OpenGLViewer::DrawText(const G4Text& g4text)
766 {
767  // gl2ps or GL window ?
768  if (isGl2psWriting()) {
769 
771  G4double size = fSceneHandler.GetMarkerSize(g4text,sizeType);
772  G4Point3D position = g4text.GetPosition();
773 
774  G4String textString = g4text.GetText();
775  const char* textCString = textString.c_str();
776 
777  glRasterPos3d(position.x(),position.y(),position.z());
778  GLint align = GL2PS_TEXT_B;
779 
780  switch (g4text.GetLayout()) {
781  case G4Text::left: align = GL2PS_TEXT_BL; break;
782  case G4Text::centre: align = GL2PS_TEXT_B; break;
783  case G4Text::right: align = GL2PS_TEXT_BR;
784  }
785 
786  gl2psTextOpt(textCString,"Times-Roman",GLshort(size),align,0);
787 
788  } else {
789 
790  static G4int callCount = 0;
791  ++callCount;
792  //if (callCount <= 10 || callCount%100 == 0) {
793  if (callCount <= 1) {
794  G4cout <<
795  "G4OpenGLViewer::DrawText: Not implemented for \""
796  << fName <<
797  "\"\n Called with "
798  << g4text
799  << G4endl;
800  }
801  }
802 }
803 
806 void G4OpenGLViewer::ChangePointSize(G4double size) {
807 
808  if (isGl2psWriting()) {
809  fGL2PSAction->setPointSize(int(size));
810  } else {
811  glPointSize (size);
812  }
813 }
814 
815 
818 void G4OpenGLViewer::ChangeLineWidth(G4double width) {
819 
820  if (isGl2psWriting()) {
821  fGL2PSAction->setLineWidth(int(width));
822  } else {
823  glLineWidth (width);
824  }
825 }
826 
827 
828 bool G4OpenGLViewer::printGl2PS() {
829 
830  int width = getRealPrintSizeX();
831  int height = getRealPrintSizeY();
832 
833  if (!fGL2PSAction) return false;
834 
835  fGL2PSAction->setFileName(getRealPrintFilename().c_str());
836  // try to resize
837  int X = fWinSize_x;
838  int Y = fWinSize_y;
839 
840  fWinSize_x = width;
841  fWinSize_y = height;
842  // Laurent G. 16/03/10 : Not the good way to do.
843  // We should draw in a new offscreen context instead of
844  // resizing and drawing in current window...
845  // This should be solve when we will do an offscreen method
846  // to render OpenGL
847  // See :
848  // http://developer.apple.com/Mac/library/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_offscreen/opengl_offscreen.html
849  // http://www.songho.ca/opengl/gl_fbo.html
850 
851  ResizeGLView();
852  bool extendBuffer = true;
853  bool endWriteAction = false;
854  bool beginWriteAction = true;
855  while ((extendBuffer) && (! endWriteAction)) {
856 
857  beginWriteAction = fGL2PSAction->enableFileWriting();
858  if (beginWriteAction) {
859 
860  // Set the viewport
861  // fGL2PSAction->setViewport(0, 0, getRealPrintSizeX(),getRealPrintSizeY());
862  // By default, we choose the line width (trajectories...)
863  fGL2PSAction->setLineWidth(fGl2psDefaultLineWith);
864  // By default, we choose the point size (markers...)
865  fGL2PSAction->setPointSize(fGl2psDefaultPointSize);
866 
867  DrawView ();
868  endWriteAction = fGL2PSAction->disableFileWriting();
869  }
870  if ((! endWriteAction) || (! beginWriteAction)) {
871  extendBuffer = fGL2PSAction->extendBufferSize();
872  }
873  }
874  fGL2PSAction->resetBufferSizeParameters();
875 
876  if (!extendBuffer ) {
877  G4cerr << "gl2ps buffer size is not big enough to print this geometry. Thy to extend it. No output produced"<< G4endl;
878  }
879  if (!beginWriteAction ) {
880  G4cerr << "Error while writing in the file "<<getRealPrintFilename().c_str()<<". Check read/write access No output produced" << G4endl;
881  }
882  if (!endWriteAction ) {
883  G4cerr << "gl2ps error. No output produced" << G4endl;
884  }
885  fWinSize_x = X;
886  fWinSize_y = Y;
887 
888  // Reset for next time (useful is size change)
889  // fPrintSizeX = 0;
890  // fPrintSizeY = 0;
891 
892  return true;
893 }
894 
895 unsigned int G4OpenGLViewer::getWinWidth() const{
896  return fWinSize_x;
897 }
898 
899 unsigned int G4OpenGLViewer::getWinHeight() const{
900  return fWinSize_y;
901 }
902 
903 G4bool G4OpenGLViewer::sizeHasChanged() {
904  return fSizeHasChanged;
905 }
906 
907 G4int G4OpenGLViewer::getRealPrintSizeX() {
908  if (fPrintSizeX == -1) {
909  return fWinSize_x;
910  }
911  GLint dims[2];
912  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
913 
914  // L.Garnier 01-2010: Some problems with mac 10.6
915  if ((dims[0] !=0 ) && (dims[1] !=0)) {
916  if (fPrintSizeX > dims[0]){
917  return dims[0];
918  }
919  }
920  if (fPrintSizeX < -1){
921  return 0;
922  }
923  return fPrintSizeX;
924 }
925 
926 G4int G4OpenGLViewer::getRealPrintSizeY() {
927  if (fPrintSizeY == -1) {
928  return fWinSize_y;
929  }
930  GLint dims[2];
931  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
932 
933  // L.Garnier 01-2010: Some problems with mac 10.6
934  if ((dims[0] !=0 ) && (dims[1] !=0)) {
935  if (fPrintSizeY > dims[1]){
936  return dims[1];
937  }
938  }
939  if (fPrintSizeY < -1){
940  return 0;
941  }
942  return fPrintSizeY;
943 }
944 
945 void G4OpenGLViewer::setPrintSize(G4int X, G4int Y) {
946  fPrintSizeX = X;
947  fPrintSizeY = Y;
948 }
949 
950 void G4OpenGLViewer::setPrintFilename(G4String name,G4bool inc) {
951  if (name != "") {
952  fPrintFilename = name;
953  } else {
954  fPrintFilename = "G4OpenGL"; // by default
955  }
956  if (inc) {
957  fPrintFilenameIndex=0;
958  } else {
959  fPrintFilenameIndex=-1;
960  }
961 }
962 
963 std::string G4OpenGLViewer::getRealPrintFilename() {
964  std::string temp = fPrintFilename;
965  if (fPrintFilenameIndex != -1) {
966  temp += std::string("_");
967  std::ostringstream os;
968  os << fPrintFilenameIndex;
969  std::string nb_str = os.str();
970  temp += nb_str;
971  }
972  temp += ".eps";
973  return temp;
974 }
975 
976 GLdouble G4OpenGLViewer::getSceneNearWidth()
977 {
978  if (!fSceneHandler.GetScene()) {
979  return 0;
980  }
981  const G4Point3D targetPoint
982  = fSceneHandler.GetScene()->GetStandardTargetPoint()
983  + fVP.GetCurrentTargetPoint ();
984  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
985  if(radius<=0.) radius = 1.;
986  const G4double cameraDistance = fVP.GetCameraDistance (radius);
987  const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
988  return 2 * fVP.GetFrontHalfHeight (pnear, radius);
989 }
990 
991 GLdouble G4OpenGLViewer::getSceneFarWidth()
992 {
993  if (!fSceneHandler.GetScene()) {
994  return 0;
995  }
996  const G4Point3D targetPoint
997  = fSceneHandler.GetScene()->GetStandardTargetPoint()
998  + fVP.GetCurrentTargetPoint ();
999  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1000  if(radius<=0.) radius = 1.;
1001  const G4double cameraDistance = fVP.GetCameraDistance (radius);
1002  const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
1003  const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
1004  return 2 * fVP.GetFrontHalfHeight (pfar, radius);
1005 }
1006 
1007 
1008 GLdouble G4OpenGLViewer::getSceneDepth()
1009 {
1010  if (!fSceneHandler.GetScene()) {
1011  return 0;
1012  }
1013  const G4Point3D targetPoint
1014  = fSceneHandler.GetScene()->GetStandardTargetPoint()
1015  + fVP.GetCurrentTargetPoint ();
1016  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1017  if(radius<=0.) radius = 1.;
1018  const G4double cameraDistance = fVP.GetCameraDistance (radius);
1019  const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
1020  return fVP.GetFarDistance (cameraDistance, pnear, radius)- pnear;
1021 }
1022 
1023 
1024 
1025 void G4OpenGLViewer::rotateScene(G4double dx, G4double dy)
1026 {
1027  if (fVP.GetRotationStyle() == G4ViewParameters::freeRotation) {
1028  rotateSceneInViewDirection(dx,dy);
1029  } else {
1030  if( dx != 0) {
1031  rotateSceneThetaPhi(dx,0);
1032  }
1033  if( dy != 0) {
1034  rotateSceneThetaPhi(0,dy);
1035  }
1036  }
1037 }
1038 
1039 
1040 void G4OpenGLViewer::rotateSceneToggle(G4double dx, G4double dy)
1041 {
1042  if (fVP.GetRotationStyle() != G4ViewParameters::freeRotation) {
1043  rotateSceneInViewDirection(dx,dy);
1044  } else {
1045  if( dx != 0) {
1046  rotateSceneThetaPhi(dx,0);
1047  }
1048  if( dy != 0) {
1049  rotateSceneThetaPhi(0,dy);
1050  }
1051  }
1052 }
1053 
1054 void G4OpenGLViewer::rotateSceneThetaPhi(G4double dx, G4double dy)
1055 {
1056  if (!fSceneHandler.GetScene()) {
1057  return;
1058  }
1059 
1060  G4Vector3D vp;
1061  G4Vector3D up;
1062 
1063  G4Vector3D xprime;
1064  G4Vector3D yprime;
1065  G4Vector3D zprime;
1066 
1067  G4double delta_alpha;
1068  G4double delta_theta;
1069 
1070  G4Vector3D new_vp;
1071  G4Vector3D new_up;
1072 
1073  G4double cosalpha;
1074  G4double sinalpha;
1075 
1076  G4Vector3D a1;
1077  G4Vector3D a2;
1078  G4Vector3D delta;
1079  G4Vector3D viewPoint;
1080 
1081 
1082  //phi spin stuff here
1083 
1084  vp = fVP.GetViewpointDirection ().unit ();
1085  up = fVP.GetUpVector ().unit ();
1086 
1087  yprime = (up.cross(vp)).unit();
1088  zprime = (vp.cross(yprime)).unit();
1089 
1090  if (fVP.GetLightsMoveWithCamera()) {
1091  delta_alpha = dy * fRot_sens;
1092  delta_theta = -dx * fRot_sens;
1093  } else {
1094  delta_alpha = -dy * fRot_sens;
1095  delta_theta = dx * fRot_sens;
1096  }
1097 
1098  delta_alpha *= deg;
1099  delta_theta *= deg;
1100 
1101  new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
1102 
1103  // to avoid z rotation flipping
1104  // to allow more than 360° rotation
1105 
1106  if (fVP.GetLightsMoveWithCamera()) {
1107  new_up = (new_vp.cross(yprime)).unit();
1108  if (new_vp.z()*vp.z() <0) {
1109  new_up.set(new_up.x(),-new_up.y(),new_up.z());
1110  }
1111  } else {
1112  new_up = up;
1113  if (new_vp.z()*vp.z() <0) {
1114  new_up.set(new_up.x(),-new_up.y(),new_up.z());
1115  }
1116  }
1117  fVP.SetUpVector(new_up);
1119  // Rotates by fixed azimuthal angle delta_theta.
1120 
1121  cosalpha = new_up.dot (new_vp.unit());
1122  sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
1123  yprime = (new_up.cross (new_vp.unit())).unit ();
1124  xprime = yprime.cross (new_up);
1125  // Projection of vp on plane perpendicular to up...
1126  a1 = sinalpha * xprime;
1127  // Required new projection...
1128  a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
1129  // Required Increment vector...
1130  delta = a2 - a1;
1131  // So new viewpoint is...
1132  viewPoint = new_vp.unit() + delta;
1133 
1134  fVP.SetViewAndLights (viewPoint);
1135 }
1136 
1137 
1138 void G4OpenGLViewer::rotateSceneInViewDirection(G4double dx, G4double dy)
1139 {
1140  if (!fSceneHandler.GetScene()) {
1141  return;
1142  }
1143 
1144  G4Vector3D vp;
1145  G4Vector3D up;
1146 
1147  G4Vector3D xprime;
1148  G4Vector3D yprime;
1149  G4Vector3D zprime;
1150 
1151  G4Vector3D new_vp;
1152  G4Vector3D new_up;
1153 
1154  G4Vector3D a1;
1155  G4Vector3D a2;
1156  G4Vector3D delta;
1157  G4Vector3D viewPoint;
1158 
1159  dx = dx/100;
1160  dy = dy/100;
1161 
1162  //phi spin stuff here
1163 
1164 #ifdef G4DEBUG_VIS_OGL
1165  printf("G4OpenGLViewer::rotateScene dx:%f dy:%f delta:%f\n",dx,dy, fRot_sens);
1166 #endif
1167 
1168  vp = fVP.GetViewpointDirection ().unit();
1169  up = fVP.GetUpVector ().unit();
1170 
1171  G4Vector3D zPrimeVector = G4Vector3D(up.y()*vp.z()-up.z()*vp.y(),
1172  up.z()*vp.x()-up.x()*vp.z(),
1173  up.x()*vp.y()-up.y()*vp.x());
1174 
1175  viewPoint = vp/fRot_sens + (zPrimeVector*dx - up*dy) ;
1176  new_up = G4Vector3D(viewPoint.y()*zPrimeVector.z()-viewPoint.z()*zPrimeVector.y(),
1177  viewPoint.z()*zPrimeVector.x()-viewPoint.x()*zPrimeVector.z(),
1178  viewPoint.x()*zPrimeVector.y()-viewPoint.y()*zPrimeVector.x());
1179 
1180  G4Vector3D new_upUnit = new_up.unit();
1181 
1182 
1183 
1184  fVP.SetUpVector(new_upUnit);
1185  fVP.SetViewAndLights (viewPoint);
1186 }
1187 
1188 #ifdef G4VIS_BUILD_OPENGLWT_DRIVER
1189 
1190 // Associate the Wt drawer to the OpenGLViewer and the OpenGLSceneHandler
1191 void G4OpenGLViewer::setWtDrawer(G4OpenGLWtDrawer* drawer) {
1192  fWtDrawer = drawer;
1193  try {
1194  G4OpenGLSceneHandler& sh = dynamic_cast<G4OpenGLSceneHandler&>(fSceneHandler);
1195  sh.setWtDrawer(fWtDrawer);
1196  } catch(std::bad_cast exp) { }
1197 }
1198 
1199 #endif
1200 
1201 #endif
Definition: G4Text.hh:73
G4String fName
Definition: G4AttUtils.hh:55
void free(void *__ptr)
Definition: hjmalloc.cc:140
G4String name
Definition: TRTMaterials.hh:40
static const G4double a1
const std::vector< const std::vector< G4AttValue > * > & GetAttValues() const
Definition: G4AttHolder.hh:60
#define width
#define buffer
Definition: xmlparse.cc:611
HepGeom::Point3D< G4double > G4Point3D
Definition: G4Point3D.hh:35
HepGeom::Vector3D< G4double > G4Vector3D
Definition: G4Vector3D.hh:35
G4double a
Definition: TRTMaterials.hh:39
G4Point3D GetPosition() const
int G4int
Definition: G4Types.hh:78
G4GLOB_DLL std::ostream G4cout
virtual void ResetView()
Layout GetLayout() const
static const double deg
Definition: G4SIunits.hh:133
bool G4bool
Definition: G4Types.hh:79
std::vector< G4Plane3D > G4Planes
G4String GetText() const
int position
Definition: filter.cc:7
HepGeom::Plane3D< G4double > G4Plane3D
Definition: G4Plane3D.hh:37
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
void * malloc(size_t __size)
Definition: hjmalloc.cc:30
#define DBL_MAX
Definition: templates.hh:83
static const G4double pos
static const G4double a2
const std::vector< const std::map< G4String, G4AttDef > * > & GetAttDefs() const
Definition: G4AttHolder.hh:62
G4GLOB_DLL std::ostream G4cerr
HepGeom::Normal3D< G4double > G4Normal3D
Definition: G4Normal3D.hh:35