source: trunk/source/visualization/OpenGL/src/G4OpenGLViewer.cc@ 1175

Last change on this file since 1175 was 1160, checked in by garnier, 16 years ago

mise en place de Vis dans UI

  • Property svn:mime-type set to text/cpp
File size: 24.8 KB
RevLine 
[529]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//
[1137]27// $Id: G4OpenGLViewer.cc,v 1.59 2009/10/20 12:47:45 lgarnier Exp $
[873]28// GEANT4 tag $Name: $
[529]29//
30//
31// Andrew Walkden 27th March 1996
32// OpenGL view - opens window, hard copy, etc.
33
34#ifdef G4VIS_BUILD_OPENGL_DRIVER
35
36#include "G4ios.hh"
37#include "G4OpenGLViewer.hh"
38#include "G4OpenGLSceneHandler.hh"
39#include "G4OpenGLTransform3D.hh"
[923]40#include "G4OpenGL2PSAction.hh"
[529]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"
[593]49#include "G4AttHolder.hh"
50#include "G4AttCheck.hh"
[918]51
[923]52// GL2PS
53#include "Geant4_gl2ps.h"
54
[593]55#include <sstream>
[529]56
57G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene):
58G4VViewer (scene, -1),
[916]59fPrintColour (true),
60fVectoredPs (true),
[593]61fOpenGLSceneHandler(scene),
[529]62background (G4Colour(0.,0.,0.)),
63transparency_enabled (true),
64antialiasing_enabled (false),
65haloing_enabled (false),
[789]66fStartTime(-DBL_MAX),
67fEndTime(DBL_MAX),
[529]68fFadeFactor(0.),
69fDisplayHeadTime(false),
70fDisplayHeadTimeX(-0.9),
71fDisplayHeadTimeY(-0.9),
72fDisplayHeadTimeSize(24.),
73fDisplayHeadTimeRed(0.),
74fDisplayHeadTimeGreen(1.),
75fDisplayHeadTimeBlue(1.),
76fDisplayLightFront(false),
77fDisplayLightFrontX(0.),
78fDisplayLightFrontY(0.),
79fDisplayLightFrontZ(0.),
80fDisplayLightFrontT(0.),
81fDisplayLightFrontRed(0.),
82fDisplayLightFrontGreen(1.),
[916]83fDisplayLightFrontBlue(0.),
[1041]84fPrintSizeX(-1),
85fPrintSizeY(-1),
[1042]86fPrintFilename ("G4OpenGL"),
[1041]87fPrintFilenameIndex(0),
[1039]88fPointSize (0),
89fSizeHasChanged(0)
[529]90{
91 // Make changes to view parameters for OpenGL...
92 fVP.SetAutoRefresh(true);
93 fDefaultVP.SetAutoRefresh(true);
94
[921]95 fGL2PSAction = new G4OpenGL2PSAction();
96
[529]97 // glClearColor (0.0, 0.0, 0.0, 0.0);
98 // glClearDepth (1.0);
99 // glDisable (GL_BLEND);
100 // glDisable (GL_LINE_SMOOTH);
101 // glDisable (GL_POLYGON_SMOOTH);
102
103}
104
105G4OpenGLViewer::~G4OpenGLViewer () {}
106
107void G4OpenGLViewer::InitializeGLView ()
108{
109 glClearColor (0.0, 0.0, 0.0, 0.0);
110 glClearDepth (1.0);
111 glDisable (GL_BLEND);
112 glDisable (GL_LINE_SMOOTH);
113 glDisable (GL_POLYGON_SMOOTH);
[1095]114
115 fWinSize_x = fVP.GetWindowSizeHintX();
116 fWinSize_y = fVP.GetWindowSizeHintY();
[529]117}
118
119void G4OpenGLViewer::ClearView () {
[959]120#ifdef G4DEBUG_VIS_OGL
[948]121 printf("G4OpenGLViewer::ClearView\n");
[959]122#endif
[529]123 glClearColor (background.GetRed(),
124 background.GetGreen(),
125 background.GetBlue(),
126 1.);
127 glClearDepth (1.0);
128 //Below line does not compile with Mesa includes.
129 //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
130 glClear (GL_COLOR_BUFFER_BIT);
131 glClear (GL_DEPTH_BUFFER_BIT);
132 glClear (GL_STENCIL_BUFFER_BIT);
[955]133#ifdef G4DEBUG_VIS_OGL
134 printf("G4OpenGLViewer::ClearView flush\n");
135#endif
[529]136 glFlush ();
137}
138
[906]139
[1039]140void G4OpenGLViewer::ResizeWindow(unsigned int aWidth, unsigned int aHeight) {
[1038]141 if ((fWinSize_x != aWidth) || (fWinSize_y != aHeight)) {
[1037]142 fWinSize_x = aWidth;
143 fWinSize_y = aHeight;
[1039]144 fSizeHasChanged = true;
145 } else {
146 fSizeHasChanged = false;
[1037]147 }
148}
149
[906]150/**
151 * Set the viewport of the scene
[945]152 * MAXIMUM SIZE is :
153 * GLint dims[2];
154 * glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
[906]155 */
156void G4OpenGLViewer::ResizeGLView()
157{
[959]158#ifdef G4DEBUG_VIS_OGL
[949]159 printf("G4OpenGLViewer::ResizeGLView %d %d\n",fWinSize_x,fWinSize_y);
[959]160#endif
[945]161 // Check size
162 GLint dims[2];
163 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
164 if (fWinSize_x > (unsigned)dims[0]) {
165 G4cerr << "Try to resize view greater than max X viewport dimension. Desired size "<<dims[0] <<" is resize to "<< dims[0] << G4endl;
166 fWinSize_x = dims[0];
167 }
168 if (fWinSize_y > (unsigned)dims[1]) {
169 G4cerr << "Try to resize view greater than max Y viewport dimension. Desired size "<<dims[0] <<" is resize to "<< dims[1] << G4endl;
170 fWinSize_y = dims[1];
171 }
[949]172 GLsizei side = fWinSize_x;
[906]173 if (fWinSize_y < fWinSize_x) side = fWinSize_y;
[949]174
175 // SPECIAL CASE if fWinSize_x is even (69 for example)
176 // Ex : X: 69 Y: 26
177 // side = 26
178 // width / 2 = 21,5
179 // height / 2 = 0
180 // Should be fixed to closed : 21 0 for ex
181 // Then size must by change to :
182 // X:68 Y: 26
183
184 // SPECIAL CASE
185 if ((fWinSize_x - side)%2) {
[950]186 // fWinSize_x --;
187
188 side = fWinSize_x;
189 if (fWinSize_y < fWinSize_x) side = fWinSize_y;
[949]190 }
191 if ((fWinSize_y - side)%2) {
[950]192 // fWinSize_y --;
193
194 side = fWinSize_x;
195 if (fWinSize_y < fWinSize_x) side = fWinSize_y;
[949]196 }
197
[950]198 GLint X = (fWinSize_x - side) / 2;
199 GLint Y = (fWinSize_y - side) / 2;
[949]200
[959]201#ifdef G4DEBUG_VIS_OGL
[950]202 printf("G4OpenGLViewer::ResizeGLView X:%d Y:%d W:%d H:%d --side%d\n",(fWinSize_x - side) / 2,(fWinSize_y - side) / 2,fWinSize_x,fWinSize_y,side);
[959]203#endif
[950]204 glViewport(X, Y, side, side);
205 // glViewport(0, 0, fWinSize_x,fWinSize_y);
206
207
[906]208}
209
210
[529]211void G4OpenGLViewer::SetView () {
[858]212
213 if (!fSceneHandler.GetScene()) {
[908]214 G4cerr << "G4OpenGLStoredViewer: Creating a Viewer without a scene is not allowed. \nPlease use /vis/scene/create before /vis/open/.... "
[858]215 << G4endl;
216 return;
217 }
[529]218 // Calculates view representation based on extent of object being
219 // viewed and (initial) viewpoint. (Note: it can change later due
220 // to user interaction via visualization system's GUI.)
221
222 // Lighting.
223 GLfloat lightPosition [4];
224 lightPosition [0] = fVP.GetActualLightpointDirection().x();
225 lightPosition [1] = fVP.GetActualLightpointDirection().y();
226 lightPosition [2] = fVP.GetActualLightpointDirection().z();
227 lightPosition [3] = 0.;
228 // Light position is "true" light direction, so must come after gluLookAt.
229 GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.};
230 GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.};
231 glEnable (GL_LIGHT0);
232 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
233 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
234
235 // Get radius of scene, etc.
236 // Note that this procedure properly takes into account zoom, dolly and pan.
237 const G4Point3D targetPoint
238 = fSceneHandler.GetScene()->GetStandardTargetPoint()
239 + fVP.GetCurrentTargetPoint ();
240 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
241 if(radius<=0.) radius = 1.;
242 const G4double cameraDistance = fVP.GetCameraDistance (radius);
243 const G4Point3D cameraPosition =
244 targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
[906]245 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
246 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
[529]247 const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius);
248 const GLdouble left = -right;
249 const GLdouble bottom = left;
250 const GLdouble top = right;
251
[906]252 // FIXME
[1039]253 ResizeGLView();
[908]254 //SHOULD SetWindowsSizeHint()...
[906]255
[529]256 glMatrixMode (GL_PROJECTION); // set up Frustum.
257 glLoadIdentity();
258
[906]259 const G4Vector3D scaleFactor = fVP.GetScaleFactor();
260 glScaled(scaleFactor.x(),scaleFactor.y(),scaleFactor.z());
[529]261
262 if (fVP.GetFieldHalfAngle() == 0.) {
263 glOrtho (left, right, bottom, top, pnear, pfar);
264 }
265 else {
266 glFrustum (left, right, bottom, top, pnear, pfar);
[908]267 }
[906]268
[529]269 glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
270 glLoadIdentity();
271
272 const G4Normal3D& upVector = fVP.GetUpVector ();
273 G4Point3D gltarget;
274 if (cameraDistance > 1.e-6 * radius) {
275 gltarget = targetPoint;
276 }
277 else {
278 gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit();
279 }
280
281 const G4Point3D& pCamera = cameraPosition; // An alias for brevity.
282 gluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint.
283 gltarget.x(), gltarget.y(), gltarget.z(), // Target point.
284 upVector.x(), upVector.y(), upVector.z()); // Up vector.
[906]285
[529]286 // Light position is "true" light direction, so must come after gluLookAt.
287 glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
288
289 // OpenGL no longer seems to reconstruct clipped edges, so, when the
290 // BooleanProcessor is up to it, abandon this and use generic
291 // clipping in G4OpenGLSceneHandler::CreateSectionPolyhedron. Also,
292 // force kernel visit on change of clipping plane in
293 // G4OpenGLStoredViewer::CompareForKernelVisit.
294 if (fVP.IsSection () ) { // pair of back to back clip planes.
295 const G4Plane3D& s = fVP.GetSectionPlane ();
296 double sArray[4];
297 sArray[0] = s.a();
298 sArray[1] = s.b();
299 sArray[2] = s.c();
300 sArray[3] = s.d() + radius * 1.e-05;
301 glClipPlane (GL_CLIP_PLANE0, sArray);
302 glEnable (GL_CLIP_PLANE0);
303 sArray[0] = -s.a();
304 sArray[1] = -s.b();
305 sArray[2] = -s.c();
306 sArray[3] = -s.d() + radius * 1.e-05;
307 glClipPlane (GL_CLIP_PLANE1, sArray);
308 glEnable (GL_CLIP_PLANE1);
309 } else {
310 glDisable (GL_CLIP_PLANE0);
311 glDisable (GL_CLIP_PLANE1);
312 }
313
314 const G4Planes& cutaways = fVP.GetCutawayPlanes();
315 size_t nPlanes = cutaways.size();
316 if (fVP.IsCutaway() &&
317 fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection &&
318 nPlanes > 0) {
319 double a[4];
320 a[0] = cutaways[0].a();
321 a[1] = cutaways[0].b();
322 a[2] = cutaways[0].c();
323 a[3] = cutaways[0].d();
324 glClipPlane (GL_CLIP_PLANE2, a);
325 glEnable (GL_CLIP_PLANE2);
326 if (nPlanes > 1) {
327 a[0] = cutaways[1].a();
328 a[1] = cutaways[1].b();
329 a[2] = cutaways[1].c();
330 a[3] = cutaways[1].d();
331 glClipPlane (GL_CLIP_PLANE3, a);
332 glEnable (GL_CLIP_PLANE3);
333 }
334 if (nPlanes > 2) {
335 a[0] = cutaways[2].a();
336 a[1] = cutaways[2].b();
337 a[2] = cutaways[2].c();
338 a[3] = cutaways[2].d();
339 glClipPlane (GL_CLIP_PLANE4, a);
340 glEnable (GL_CLIP_PLANE4);
341 }
342 } else {
343 glDisable (GL_CLIP_PLANE2);
344 glDisable (GL_CLIP_PLANE3);
345 glDisable (GL_CLIP_PLANE4);
346 }
347
348 // Background.
349 background = fVP.GetBackgroundColour ();
350
351}
352
353void G4OpenGLViewer::HaloingFirstPass () {
354
355 //To perform haloing, first Draw all information to the depth buffer
356 //alone, using a chunky line width, and then Draw all info again, to
357 //the colour buffer, setting a thinner line width an the depth testing
358 //function to less than or equal, so if two lines cross, the one
359 //passing behind the other will not pass the depth test, and so not
360 //get rendered either side of the infront line for a short distance.
361
362 //First, disable writing to the colo(u)r buffer...
363 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
364
365 //Now enable writing to the depth buffer...
366 glDepthMask (GL_TRUE);
367 glDepthFunc (GL_LESS);
368 glClearDepth (1.0);
369
370 //Finally, set the line width to something wide...
371 glLineWidth (3.0);
372
373}
374
375void G4OpenGLViewer::HaloingSecondPass () {
376
377 //And finally, turn the colour buffer back on with a sesible line width...
378 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
379 glDepthFunc (GL_LEQUAL);
380 glLineWidth (1.0);
381
382}
383
[593]384void G4OpenGLViewer::Pick(GLdouble x, GLdouble y)
385{
386 //G4cout << "X: " << x << ", Y: " << y << G4endl;
387 const G4int BUFSIZE = 512;
388 GLuint selectBuffer[BUFSIZE];
389 glSelectBuffer(BUFSIZE, selectBuffer);
390 glRenderMode(GL_SELECT);
391 glInitNames();
392 glPushName(0);
393 glMatrixMode(GL_PROJECTION);
394 G4double currentProjectionMatrix[16];
395 glGetDoublev(GL_PROJECTION_MATRIX, currentProjectionMatrix);
396 glPushMatrix();
397 glLoadIdentity();
398 GLint viewport[4];
399 glGetIntegerv(GL_VIEWPORT, viewport);
400 // Define 5x5 pixel pick area
401 gluPickMatrix(x, viewport[3] - y, 5., 5., viewport);
402 glMultMatrixd(currentProjectionMatrix);
403 glMatrixMode(GL_MODELVIEW);
404 DrawView();
405 GLint hits = glRenderMode(GL_RENDER);
406 if (hits < 0)
407 G4cout << "Too many hits. Zoom in to reduce overlaps." << G4cout;
408 else if (hits > 0) {
409 //G4cout << hits << " hit(s)" << G4endl;
410 GLuint* p = selectBuffer;
411 for (GLint i = 0; i < hits; ++i) {
412 GLuint nnames = *p++;
413 *p++; //OR GLuint zmin = *p++;
414 *p++; //OR GLuint zmax = *p++;
415 //G4cout << "Hit " << i << ": " << nnames << " names"
416 // << "\nzmin: " << zmin << ", zmax: " << zmax << G4endl;
417 for (GLuint j = 0; j < nnames; ++j) {
418 GLuint name = *p++;
419 //G4cout << "Name " << j << ": PickName: " << name << G4endl;
420 std::map<GLuint, G4AttHolder*>::iterator iter =
421 fOpenGLSceneHandler.fPickMap.find(name);
422 if (iter != fOpenGLSceneHandler.fPickMap.end()) {
423 G4AttHolder* attHolder = iter->second;
424 if(attHolder && attHolder->GetAttDefs().size()) {
425 for (size_t i = 0; i < attHolder->GetAttDefs().size(); ++i) {
426 G4cout << G4AttCheck(attHolder->GetAttValues()[i],
427 attHolder->GetAttDefs()[i]);
428 }
429 }
430 }
431 }
432 G4cout << G4endl;
433 }
434 }
435 glMatrixMode(GL_PROJECTION);
436 glPopMatrix();
437 glMatrixMode(GL_MODELVIEW);
438}
439
440
[754]441
[593]442
[914]443GLubyte* G4OpenGLViewer::grabPixels (int inColor, unsigned int width, unsigned int height) {
444
445 GLubyte* buffer;
446 GLint swapbytes, lsbfirst, rowlength;
447 GLint skiprows, skippixels, alignment;
448 GLenum format;
449 int size;
450
451 if (inColor) {
452 format = GL_RGB;
453 size = width*height*3;
454 } else {
455 format = GL_LUMINANCE;
456 size = width*height*1;
457 }
458
459 buffer = new GLubyte[size];
460 if (buffer == NULL)
461 return NULL;
462
463 glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
464 glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
465 glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
466
467 glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
468 glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
469 glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
470
471 glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
472 glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
473 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
474
475 glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
476 glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
477 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
478
[980]479 glReadBuffer(GL_FRONT);
[914]480 glReadPixels (0, 0, (GLsizei)width, (GLsizei)height, format, GL_UNSIGNED_BYTE, (GLvoid*) buffer);
481
482 glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbytes);
483 glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst);
484 glPixelStorei (GL_UNPACK_ROW_LENGTH, rowlength);
485
486 glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows);
487 glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippixels);
488 glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
489
490 return buffer;
491}
492
[941]493void G4OpenGLViewer::printEPS() {
494 bool res;
[942]495#ifdef G4DEBUG_VIS_OGL
[1095]496 printf("G4OpenGLViewer::printEPS file:%s Vec:%d Name:%s\n",getRealPrintFilename().c_str(),fVectoredPs,GetName().c_str());
[942]497#endif
[1133]498
499 // Change the LC_NUMERIC value in order to have "." separtor and not ","
500 // This case is only useful for French, Canadien...
501 char *oldLocale = strdup(setlocale(LC_NUMERIC,NULL));
502 setlocale(LC_NUMERIC,"C");
503
[941]504 if (fVectoredPs) {
505 res = printVectoredEPS();
506 } else {
[1008]507 res = printNonVectoredEPS();
[941]508 }
[1133]509
510 // restore the local
511 if (oldLocale) {
512 setlocale(LC_NUMERIC,oldLocale);
513 free(oldLocale);
514 }
515
[941]516 if (res == false) {
[1041]517 G4cerr << "Error while saving file... "<<getRealPrintFilename().c_str()<< G4endl;
[941]518 } else {
[1042]519 G4cout << "File "<<getRealPrintFilename().c_str()<<" has been saved " << G4endl;
[941]520 }
[1041]521
522 // increment index if necessary
523 if ( fPrintFilenameIndex != -1) {
524 fPrintFilenameIndex++;
525 }
526
[941]527}
[914]528
[941]529bool G4OpenGLViewer::printVectoredEPS() {
530 return printGl2PS();
531}
532
533bool G4OpenGLViewer::printNonVectoredEPS () {
534
[1041]535 int width = getRealPrintSizeX();
536 int height = getRealPrintSizeY();
[941]537
[942]538#ifdef G4DEBUG_VIS_OGL
[1041]539 printf("G4OpenGLViewer::printNonVectoredEPS file:%s Vec:%d X:%d Y:%d col:%d\n",getRealPrintFilename().c_str(),fVectoredPs,width,height,fPrintColour);
[942]540#endif
[914]541 FILE* fp;
542 GLubyte* pixels;
543 GLubyte* curpix;
544 int components, pos, i;
545
[941]546 pixels = grabPixels (fPrintColour, width, height);
[914]547
[941]548 if (pixels == NULL) {
549 G4cerr << "Failed to get pixels from OpenGl viewport" << G4endl;
550 return false;
551 }
552 if (fPrintColour) {
[914]553 components = 3;
554 } else {
555 components = 1;
556 }
[1041]557 std::string name = getRealPrintFilename();
558 fp = fopen (name.c_str(), "w");
[914]559 if (fp == NULL) {
[1041]560 G4cerr << "Can't open filename " << name.c_str() << G4endl;
[941]561 return false;
[914]562 }
563
564 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
[1041]565 fprintf (fp, "%%%%Title: %s\n", name.c_str());
[914]566 fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
567 fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
568 fprintf (fp, "%%%%EndComments\n");
569 fprintf (fp, "gsave\n");
570 fprintf (fp, "/bwproc {\n");
571 fprintf (fp, " rgbproc\n");
572 fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
573 fprintf (fp, " 5 -1 roll {\n");
574 fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
575 fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
576 fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
577 fprintf (fp, " { 2 1 roll } ifelse\n");
578 fprintf (fp, " }forall\n");
579 fprintf (fp, " pop pop pop\n");
580 fprintf (fp, "} def\n");
581 fprintf (fp, "systemdict /colorimage known not {\n");
582 fprintf (fp, " /colorimage {\n");
583 fprintf (fp, " pop\n");
584 fprintf (fp, " pop\n");
585 fprintf (fp, " /rgbproc exch def\n");
586 fprintf (fp, " { bwproc } image\n");
587 fprintf (fp, " } def\n");
588 fprintf (fp, "} if\n");
589 fprintf (fp, "/picstr %d string def\n", width * components);
590 fprintf (fp, "%d %d scale\n", width, height);
591 fprintf (fp, "%d %d %d\n", width, height, 8);
592 fprintf (fp, "[%d 0 0 %d 0 0]\n", width, height);
593 fprintf (fp, "{currentfile picstr readhexstring pop}\n");
594 fprintf (fp, "false %d\n", components);
595 fprintf (fp, "colorimage\n");
596
597 curpix = (GLubyte*) pixels;
598 pos = 0;
599 for (i = width*height*components; i>0; i--) {
600 fprintf (fp, "%02hx ", *(curpix++));
601 if (++pos >= 32) {
602 fprintf (fp, "\n");
603 pos = 0;
604 }
605 }
606 if (pos)
607 fprintf (fp, "\n");
608
609 fprintf (fp, "grestore\n");
610 fprintf (fp, "showpage\n");
611 delete pixels;
612 fclose (fp);
[941]613
614 // Reset for next time (useful is size change)
[1041]615 // fPrintSizeX = -1;
616 // fPrintSizeY = -1;
[941]617
618 return true;
[914]619}
620
[918]621
[941]622bool G4OpenGLViewer::printGl2PS() {
[918]623
[1041]624 int width = getRealPrintSizeX();
625 int height = getRealPrintSizeY();
[941]626
[938]627 if (!fGL2PSAction) return false;
[929]628
[1041]629 fGL2PSAction->setFileName(getRealPrintFilename().c_str());
[938]630 // try to resize
631 int X = fWinSize_x;
632 int Y = fWinSize_y;
[929]633
[1039]634 fWinSize_x = width;
635 fWinSize_y = height;
636 ResizeGLView();
[921]637 if (fGL2PSAction->enableFileWriting()) {
[945]638
[948]639 // By default, we choose the line width (trajectories...)
640 fGL2PSAction->setLineWidth(1);
641 // By default, we choose the point size (markers...)
642 fGL2PSAction->setPointSize(2);
[945]643
[931]644 DrawView ();
[921]645 fGL2PSAction->disableFileWriting();
646 }
[929]647
[1039]648 fWinSize_x = X;
649 fWinSize_y = Y;
650 ResizeGLView();
[929]651
[941]652 // Reset for next time (useful is size change)
[1041]653 // fPrintSizeX = 0;
654 // fPrintSizeY = 0;
[941]655
[938]656 return true;
[918]657}
658
[1039]659unsigned int G4OpenGLViewer::getWinWidth() {
660 return fWinSize_x;
661}
662
663unsigned int G4OpenGLViewer::getWinHeight() {
664 return fWinSize_y;
665}
666
667G4bool G4OpenGLViewer::sizeHasChanged() {
668 return fSizeHasChanged;
669}
670
[1041]671G4int G4OpenGLViewer::getRealPrintSizeX() {
672 if (fPrintSizeX == -1) {
673 return fWinSize_x;
674 }
675 GLint dims[2];
676 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
677 if (fPrintSizeX > dims[0]){
678 return dims[0];
679 }
680 if (fPrintSizeX < -1){
681 return 0;
682 }
683 return fPrintSizeX;
684}
685
686G4int G4OpenGLViewer::getRealPrintSizeY() {
687 if (fPrintSizeY == -1) {
688 return fWinSize_y;
689 }
690 GLint dims[2];
691 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
692 if (fPrintSizeY > dims[1]){
693 return dims[1];
694 }
695 if (fPrintSizeY < -1){
696 return 0;
697 }
698 return fPrintSizeY;
699}
700
701void G4OpenGLViewer::setPrintSize(G4int X, G4int Y) {
702 fPrintSizeX = X;
703 fPrintSizeY = Y;
704}
705
706void G4OpenGLViewer::setPrintFilename(G4String name,G4bool inc) {
707 if (name != "") {
708 fPrintFilename = name;
709 } else {
710 fPrintFilename = "G4OpenGL"; // by default
711 }
712 if (inc) {
713 fPrintFilenameIndex=0;
714 } else {
715 fPrintFilenameIndex=-1;
716 }
717}
718
719std::string G4OpenGLViewer::getRealPrintFilename() {
[1042]720 std::string temp = fPrintFilename;
[1041]721 if (fPrintFilenameIndex != -1) {
[1042]722 temp += std::string("_");
723 std::ostringstream os;
724 os << fPrintFilenameIndex;
725 std::string nb_str = os.str();
726 temp += nb_str;
[1041]727 }
728 temp += ".eps";
729 return temp;
730}
731
[712]732GLdouble G4OpenGLViewer::getSceneNearWidth()
733{
734 const G4Point3D targetPoint
735 = fSceneHandler.GetScene()->GetStandardTargetPoint()
736 + fVP.GetCurrentTargetPoint ();
737 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
738 if(radius<=0.) radius = 1.;
739 const G4double cameraDistance = fVP.GetCameraDistance (radius);
740 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
741 return 2 * fVP.GetFrontHalfHeight (pnear, radius);
742}
743
744GLdouble G4OpenGLViewer::getSceneFarWidth()
745{
746 const G4Point3D targetPoint
747 = fSceneHandler.GetScene()->GetStandardTargetPoint()
748 + fVP.GetCurrentTargetPoint ();
749 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
750 if(radius<=0.) radius = 1.;
751 const G4double cameraDistance = fVP.GetCameraDistance (radius);
752 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
753 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
754 return 2 * fVP.GetFrontHalfHeight (pfar, radius);
755}
756
757
758GLdouble G4OpenGLViewer::getSceneDepth()
759{
760 const G4Point3D targetPoint
761 = fSceneHandler.GetScene()->GetStandardTargetPoint()
762 + fVP.GetCurrentTargetPoint ();
763 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
764 if(radius<=0.) radius = 1.;
765 const G4double cameraDistance = fVP.GetCameraDistance (radius);
766 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
767 return fVP.GetFarDistance (cameraDistance, pnear, radius)- pnear;
768}
769
770
[593]771
[798]772void G4OpenGLViewer::rotateScene(G4double dx, G4double dy,G4double deltaRotation)
773{
[1137]774 if (!fSceneHandler.GetScene()) {
775 return;
776 }
[798]777
778 G4Vector3D vp;
779 G4Vector3D up;
780
781 G4Vector3D xprime;
782 G4Vector3D yprime;
783 G4Vector3D zprime;
784
785 G4double delta_alpha;
786 G4double delta_theta;
787
788 G4Vector3D new_vp;
789 G4Vector3D new_up;
790
791 G4double cosalpha;
792 G4double sinalpha;
793
794 G4Vector3D a1;
795 G4Vector3D a2;
796 G4Vector3D delta;
797 G4Vector3D viewPoint;
798
799
800 //phi spin stuff here
801
802 vp = fVP.GetViewpointDirection ().unit ();
803 up = fVP.GetUpVector ().unit ();
804
805 yprime = (up.cross(vp)).unit();
806 zprime = (vp.cross(yprime)).unit();
807
808 if (fVP.GetLightsMoveWithCamera()) {
809 delta_alpha = dy * deltaRotation;
810 delta_theta = -dx * deltaRotation;
811 } else {
812 delta_alpha = -dy * deltaRotation;
813 delta_theta = dx * deltaRotation;
814 }
815
816 delta_alpha *= deg;
817 delta_theta *= deg;
818
819 new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
820
821 // to avoid z rotation flipping
822 // to allow more than 360° rotation
[847]823
[801]824 const G4Point3D targetPoint
825 = fSceneHandler.GetScene()->GetStandardTargetPoint()
826 + fVP.GetCurrentTargetPoint ();
827 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
828 if(radius<=0.) radius = 1.;
829 const G4double cameraDistance = fVP.GetCameraDistance (radius);
830 const G4Point3D cameraPosition =
831 targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
832
[798]833 if (fVP.GetLightsMoveWithCamera()) {
834 new_up = (new_vp.cross(yprime)).unit();
835 if (new_vp.z()*vp.z() <0) {
836 new_up.set(new_up.x(),-new_up.y(),new_up.z());
837 }
838 } else {
839 new_up = up;
840 if (new_vp.z()*vp.z() <0) {
841 new_up.set(new_up.x(),-new_up.y(),new_up.z());
842 }
843 }
844 fVP.SetUpVector(new_up);
845 ////////////////
846 // Rotates by fixed azimuthal angle delta_theta.
847
848 cosalpha = new_up.dot (new_vp.unit());
849 sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
850 yprime = (new_up.cross (new_vp.unit())).unit ();
851 xprime = yprime.cross (new_up);
852 // Projection of vp on plane perpendicular to up...
853 a1 = sinalpha * xprime;
854 // Required new projection...
855 a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
856 // Required Increment vector...
857 delta = a2 - a1;
858 // So new viewpoint is...
859 viewPoint = new_vp.unit() + delta;
860
861 fVP.SetViewAndLights (viewPoint);
862}
863
[529]864#endif
Note: See TracBrowser for help on using the repository browser.