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

Last change on this file since 941 was 941, checked in by garnier, 17 years ago

print methods renaming. See History file

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