source: trunk/source/visualization/OpenGL/src/G4OpenGLQtViewer.cc@ 831

Last change on this file since 831 was 804, checked in by garnier, 18 years ago

r846@wl-72126: garnier | 2008-05-29 12:20:22 +0200
prise en compte de la roulette de souris

  • Property svn:mime-type set to text/cpp
File size: 89.4 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: G4OpenGLQtViewer.cc,v 1.23 2008/04/29 16:58:04 lgarnier Exp $
28// GEANT4 tag $Name: $
29//
30//
31// G4OpenGLQtViewer : Class to provide Qt specific
32// functionality for OpenGL in GEANT4
33//
34// 27/06/2003 : G.Barrand : implementation (at last !).
35
36#ifdef G4VIS_BUILD_OPENGLQT_DRIVER
37
38#define GEANT4_QT_DEBUG
39#define ROTATEGL
40
41#include "G4OpenGLQtViewer.hh"
42
43#include <cmath>
44#include "G4ios.hh"
45#include "G4VisExtent.hh"
46#include "G4LogicalVolume.hh"
47#include "G4VSolid.hh"
48#include "G4Point3D.hh"
49#include "G4Normal3D.hh"
50#include "G4Scene.hh"
51#include "G4OpenGLQtExportDialog.hh"
52#include "G4OpenGLQtMovieDialog.hh"
53#include "G4UnitsTable.hh"
54#include "G4Qt.hh"
55#include "G4UImanager.hh"
56#include "G4UIcommandTree.hh"
57#include <qlayout.h>
58#include <qdialog.h>
59#include <qprocess.h>
60#include <qapplication.h>
61
62#if QT_VERSION >= 0x040000
63#include <qmenu.h>
64#include <qimagewriter.h>
65#else
66#include <qaction.h>
67#include <qwidgetlist.h>
68#include <qpopupmenu.h>
69#include <qimage.h>
70#endif
71
72#include <qapplication.h>
73#include <qmessagebox.h>
74#include <qfiledialog.h>
75#include <qprinter.h>
76#include <qdatetime.h>
77#include <qpainter.h>
78#include <qgl.h> // include <qglwidget.h>
79#include <qdialog.h>
80#include <qevent.h> //include <qcontextmenuevent.h>
81#include <qdatetime.h>
82
83//////////////////////////////////////////////////////////////////////////////
84/**
85 Implementation of virtual method of G4VViewer
86*/
87void G4OpenGLQtViewer::SetView (
88)
89//////////////////////////////////////////////////////////////////////////////
90//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
91{
92 // if(!fHDC) return;
93 // if(!fHGLRC) return;
94 // ::wglMakeCurrent(fHDC,fHGLRC);
95 // fWindow->makeCurrent();
96 // G4OpenGLViewer::SetView ();
97
98 // Calculates view representation based on extent of object being
99 // viewed and (initial) viewpoint. (Note: it can change later due
100 // to user interaction via visualization system's GUI.)
101
102 // Lighting.
103 GLfloat lightPosition [4];
104 lightPosition [0] = fVP.GetActualLightpointDirection().x();
105 lightPosition [1] = fVP.GetActualLightpointDirection().y();
106 lightPosition [2] = fVP.GetActualLightpointDirection().z();
107 lightPosition [3] = 0.;
108 // Light position is "true" light direction, so must come after gluLookAt.
109 GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.};
110 GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.};
111 glEnable (GL_LIGHT0);
112 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
113 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
114
115 // Get radius of scene, etc.
116 // Note that this procedure properly takes into account zoom, dolly and pan.
117 const G4Point3D targetPoint
118 = fSceneHandler.GetScene()->GetStandardTargetPoint()
119 + fVP.GetCurrentTargetPoint ();
120 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
121 if(radius<=0.) radius = 1.;
122 const G4double cameraDistance = fVP.GetCameraDistance (radius);
123 const G4Point3D cameraPosition =
124 targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
125 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
126 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
127 const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius);
128 const GLdouble left = -right;
129 const GLdouble bottom = left;
130 const GLdouble top = right;
131
132 glMatrixMode (GL_PROJECTION); // set up Frustum.
133 glLoadIdentity();
134
135 const G4Vector3D scale = fVP.GetScaleFactor();
136 glScaled(scale.x(),scale.y(),scale.z());
137
138 if (fVP.GetFieldHalfAngle() == 0.) {
139 glOrtho (left, right, bottom, top, pnear, pfar);
140 }
141 else {
142 glFrustum (left, right, bottom, top, pnear, pfar);
143 }
144
145 glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
146 glLoadIdentity();
147
148 const G4Normal3D& upVector = fVP.GetUpVector ();
149 G4Point3D gltarget;
150 if (cameraDistance > 1.e-6 * radius) {
151 gltarget = targetPoint;
152 }
153 else {
154 gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit();
155 }
156
157 const G4Point3D& pCamera = cameraPosition; // An alias for brevity.
158 gluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint.
159 gltarget.x(), gltarget.y(), gltarget.z(), // Target point.
160 upVector.x(), upVector.y(), upVector.z()); // Up vector.
161
162 // Light position is "true" light direction, so must come after gluLookAt.
163 glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
164
165 // OpenGL no longer seems to reconstruct clipped edges, so, when the
166 // BooleanProcessor is up to it, abandon this and use generic
167 // clipping in G4OpenGLSceneHandler::CreateSectionPolyhedron. Also,
168 // force kernel visit on change of clipping plane in
169 // G4OpenGLStoredViewer::CompareForKernelVisit.
170 if (fVP.IsSection () ) { // pair of back to back clip planes.
171 const G4Plane3D& s = fVP.GetSectionPlane ();
172 double sArray[4];
173 sArray[0] = s.a();
174 sArray[1] = s.b();
175 sArray[2] = s.c();
176 sArray[3] = s.d() + radius * 1.e-05;
177 glClipPlane (GL_CLIP_PLANE0, sArray);
178 glEnable (GL_CLIP_PLANE0);
179 sArray[0] = -s.a();
180 sArray[1] = -s.b();
181 sArray[2] = -s.c();
182 sArray[3] = -s.d() + radius * 1.e-05;
183 glClipPlane (GL_CLIP_PLANE1, sArray);
184 glEnable (GL_CLIP_PLANE1);
185 } else {
186 glDisable (GL_CLIP_PLANE0);
187 glDisable (GL_CLIP_PLANE1);
188 }
189
190 const G4Planes& cutaways = fVP.GetCutawayPlanes();
191 size_t nPlanes = cutaways.size();
192 if (fVP.IsCutaway() &&
193 fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection &&
194 nPlanes > 0) {
195 double a[4];
196 a[0] = cutaways[0].a();
197 a[1] = cutaways[0].b();
198 a[2] = cutaways[0].c();
199 a[3] = cutaways[0].d();
200 glClipPlane (GL_CLIP_PLANE2, a);
201 glEnable (GL_CLIP_PLANE2);
202 if (nPlanes > 1) {
203 a[0] = cutaways[1].a();
204 a[1] = cutaways[1].b();
205 a[2] = cutaways[1].c();
206 a[3] = cutaways[1].d();
207 glClipPlane (GL_CLIP_PLANE3, a);
208 glEnable (GL_CLIP_PLANE3);
209 }
210 if (nPlanes > 2) {
211 a[0] = cutaways[2].a();
212 a[1] = cutaways[2].b();
213 a[2] = cutaways[2].c();
214 a[3] = cutaways[2].d();
215 glClipPlane (GL_CLIP_PLANE4, a);
216 glEnable (GL_CLIP_PLANE4);
217 }
218 } else {
219 glDisable (GL_CLIP_PLANE2);
220 glDisable (GL_CLIP_PLANE3);
221 glDisable (GL_CLIP_PLANE4);
222 }
223
224 // Background.
225 background = fVP.GetBackgroundColour ();
226}
227
228void G4OpenGLQtViewer::ClearView (
229)
230//////////////////////////////////////////////////////////////////////////////
231//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
232{
233 G4OpenGLViewer::ClearView ();
234 // glLoadIdentity();
235#ifdef ROTATEGL
236 glRotatef(fRotationAngleY, 1.0, 0.0, 0.0);
237 glRotatef(fRotationAngleX, 0.0, 1.0, 0.0);
238 glRotatef(fRotationAngleZ, 0.0, 0.0, 1.0);
239#endif
240}
241
242/**
243 * Set the viewport of the scene
244 */
245void G4OpenGLQtViewer::setupViewport(int aWidth, int aHeight)
246{
247 int side = aWidth;
248 if (aHeight < aWidth) side = aHeight;
249 glViewport((aWidth - side) / 2, (aHeight - side) / 2, side, side);
250
251 glMatrixMode(GL_PROJECTION);
252 glLoadIdentity();
253 glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
254 glMatrixMode(GL_MODELVIEW);
255}
256
257
258//////////////////////////////////////////////////////////////////////////////
259/**
260 Implementation of virtual method of G4VViewer
261*/
262void G4OpenGLQtViewer::ShowView (
263)
264//////////////////////////////////////////////////////////////////////////////
265//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
266{
267#ifdef GEANT4_QT_DEBUG
268 printf("G4OpenGLQtViewer::ShowView +++++++++++++++++++++\n");
269#endif
270 if (!GLWindow) {
271 G4cerr << "Visualization window not defined, please choose one before\n" << G4endl;
272 } else {
273#if QT_VERSION < 0x040000
274 GLWindow->setActiveWindow();
275#else
276 GLWindow->activateWindow();
277#endif
278#ifdef GEANT4_QT_DEBUG
279 printf("G4OpenGLQtViewer::ShowView -----------------------\n");
280#endif
281 }
282 glFlush ();
283 // // Empty the Windows message queue :
284 // MSG event;
285 // while ( ::PeekMessage(&event, NULL, 0, 0, PM_REMOVE) ) {
286 // ::TranslateMessage(&event);
287 // ::DispatchMessage (&event);
288 // }
289}
290
291
292
293//////////////////////////////////////////////////////////////////////////////
294void G4OpenGLQtViewer::CreateGLQtContext (
295)
296//////////////////////////////////////////////////////////////////////////////
297//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
298{
299#ifdef GEANT4_QT_DEBUG
300 printf("G4OpenGLQtViewer::CreateGLQtContext \n");
301#endif
302}
303
304
305//////////////////////////////////////////////////////////////////////////////
306void G4OpenGLQtViewer::CreateMainWindow (
307 QGLWidget* glWidget
308)
309//////////////////////////////////////////////////////////////////////////////
310//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
311{
312
313 if(fWindow) return; //Done.
314#ifdef GEANT4_QT_DEBUG
315 printf("G4OpenGLQtViewer::CreateMainWindow glWidget\n");
316#endif
317
318 // launch Qt if not
319 G4Qt* interactorManager = G4Qt::getInstance ();
320 // G4UImanager* UI = G4UImanager::GetUIpointer();
321
322 fWindow = glWidget ;
323 // fWindow->makeCurrent();
324
325 // create window
326 if (((QApplication*)interactorManager->GetMainInteractor())) {
327 // look for the main window
328 bool found = false;
329#if QT_VERSION < 0x040000
330 // theses lines does nothing exept this one "GLWindow = new QDialog(0..."
331 // but if I comment them, it doesn't work...
332 QWidgetList *list = QApplication::allWidgets();
333 QWidgetListIt it( *list ); // iterate over the widgets
334 QWidget * widget;
335 while ( (widget=it.current()) != 0 ) { // for each widget...
336 ++it;
337 if ((found== false) && (widget->inherits("QMainWindow"))) {
338 GLWindow = new QDialog(0,0,FALSE,Qt::WStyle_Title | Qt::WStyle_SysMenu | Qt::WStyle_MinMax );
339 found = true;
340 }
341 }
342 delete list; // delete the list, not the widgets
343#else
344 foreach (QWidget *widget, QApplication::allWidgets()) {
345 if ((found== false) && (widget->inherits("QMainWindow"))) {
346 GLWindow = new QDialog(0,Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
347 found = true;
348 }
349 }
350#endif
351
352#if QT_VERSION < 0x040000
353 glWidget->reparent(GLWindow,0,QPoint(0,0));
354#else
355 glWidget->setParent(GLWindow);
356#endif
357
358 if (found==false) {
359#ifdef GEANT4_QT_DEBUG
360 printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist, but not found\n");
361#endif
362 GLWindow = new QDialog();
363 }
364 } else {
365#ifdef GEANT4_QT_DEBUG
366 printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist\n");
367#endif
368 GLWindow = new QDialog();
369 }
370
371 QHBoxLayout *mainLayout = new QHBoxLayout(GLWindow);
372
373 mainLayout->addWidget(fWindow);
374
375#if QT_VERSION < 0x040000
376 GLWindow->setCaption( tr( "QGl Viewer" ));
377#else
378 GLWindow->setLayout(mainLayout);
379 GLWindow->setWindowTitle(tr("QGl Viewer"));
380#endif
381 GLWindow->resize(300, 300);
382 GLWindow->move(900,300);
383 GLWindow->show();
384
385 // delete the pointer if close this
386 // GLWindow->setAttribute(Qt::WA_DeleteOnClose);
387
388#if QT_VERSION >= 0x040000
389// QObject ::connect(GLWindow,
390// SIGNAL(rejected()),
391// this,
392// SLOT(dialogClosed()));
393#endif
394
395 WinSize_x = 400;
396 WinSize_y = 400;
397 if (WinSize_x < fVP.GetWindowSizeHintX ())
398 WinSize_x = fVP.GetWindowSizeHintX ();
399 if (WinSize_y < fVP.GetWindowSizeHintY ())
400 WinSize_y = fVP.GetWindowSizeHintY ();
401
402 if(!fWindow) return;
403#ifdef GEANT4_QT_DEBUG
404 printf("G4OpenGLQtViewer::CreateMainWindow glWidget END\n");
405#endif
406
407 if (!fContextMenu)
408 createPopupMenu();
409
410}
411
412#if QT_VERSION >= 0x040000
413/** Close the dialog and set the pointer to NULL
414 */
415// void G4OpenGLQtViewer::dialogClosed() {
416// #ifdef GEANT4_QT_DEBUG
417// printf("G4OpenGLQtViewer::dialogClosed END\n");
418// #endif
419// // GLWindow = NULL;
420// }
421#endif
422
423//////////////////////////////////////////////////////////////////////////////
424G4OpenGLQtViewer::G4OpenGLQtViewer (
425 G4OpenGLSceneHandler& scene
426 )
427 :G4VViewer (scene, -1)
428 ,G4OpenGLViewer (scene)
429 ,fWindow(0)
430 ,fRecordFrameNumber(0)
431 ,fContextMenu(0)
432 ,fMouseAction(STYLE1)
433 ,fDeltaRotation(1)
434 ,fDeltaSceneTranslation(0.01)
435 ,fDeltaDepth(0.01)
436 ,fDeltaZoom(0.05)
437 ,fDeltaMove(0.05)
438 ,fHoldKeyEvent(false)
439 ,fHoldMoveEvent(false)
440 ,fHoldRotateEvent(false)
441 ,fAutoMove(false)
442 ,fEncoderPath("")
443 ,fTempFolderPath("")
444 ,fMovieTempFolderPath("")
445 ,fSaveFileName("")
446 ,fParameterFileName("mpeg_encode_parameter_file.par")
447 ,fMovieParametersDialog(NULL)
448 ,fRecordingStep(WAIT)
449 ,fProcess(NULL)
450 ,fLaunchSpinDelay(100)
451 ,fRotationAngleX(0)
452 ,fRotationAngleY(0)
453 ,fDeltaRotationAngleX(0)
454 ,fDeltaRotationAngleY(0)
455{
456
457 // launch Qt if not
458 G4Qt* interactorManager = G4Qt::getInstance ();
459
460 fLastPos3 = QPoint(-1,-1);
461 fLastPos2 = QPoint(-1,-1);
462 fLastPos1 = QPoint(-1,-1);
463
464 initMovieParameters();
465
466 fLastEventTime = new QTime();
467
468#ifdef GEANT4_QT_DEBUG
469 printf("G4OpenGLQtViewer::G4OpenGLQtViewer END\n");
470#endif
471}
472
473//////////////////////////////////////////////////////////////////////////////
474G4OpenGLQtViewer::~G4OpenGLQtViewer (
475)
476//////////////////////////////////////////////////////////////////////////////
477//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
478{
479#if QT_VERSION < 0x040000
480 G4cout <<removeTempFolder().ascii() <<G4endl;
481#else
482 G4cout <<removeTempFolder().toStdString().c_str() <<G4endl;
483#endif
484
485#ifdef GEANT4_QT_DEBUG
486 printf("G4OpenGLQtViewer::~G4OpenGLQtViewer \n");
487#endif
488}
489
490
491/**
492 Create a popup menu for the widget. This menu is activated by right-mouse click
493*/
494void G4OpenGLQtViewer::createPopupMenu() {
495
496#if QT_VERSION < 0x040000
497 fContextMenu = new QPopupMenu( GLWindow,"All" );
498#else
499 fContextMenu = new QMenu("All");
500#endif
501
502#if QT_VERSION < 0x040000
503 QPopupMenu *mMouseAction = new QPopupMenu( fContextMenu );
504 fContextMenu->insertItem("&Mouse actions",mMouseAction);
505#if QT_VERSION < 0x030200
506 fRotateAction = new QAction("&Rotate","&Rotate",CTRL+Key_R,mMouseAction,0,true);
507 fMoveAction = new QAction("&Move","&Move",CTRL+Key_M,mMouseAction,0,true);
508 fPickAction = new QAction("&Pick","&Pick",CTRL+Key_P,mMouseAction,0,true);
509 QAction * shortcutsAction = new QAction("&Show shortcuts","&Show shortcuts",CTRL+Key_S,mMouseAction,0,true);
510#else
511 fRotateAction = new QAction("&Rotate",CTRL+Key_R,mMouseAction);
512 fMoveAction = new QAction("&Move",CTRL+Key_M,mMouseAction);
513 fPickAction = new QAction("&Pick",CTRL+Key_P,mMouseAction);
514 QAction *shortcutsAction = new QAction("&Show shortcuts",CTRL+Key_S,mMouseAction);
515#endif
516 fRotateAction->addTo(mMouseAction);
517 fMoveAction->addTo(mMouseAction);
518 fPickAction->addTo(mMouseAction);
519 shortcutsAction->addTo(mMouseAction);
520
521 fRotateAction->setToggleAction(true);
522 fMoveAction->setToggleAction(true);
523 fPickAction->setToggleAction(true);
524 shortcutsAction->setToggleAction(true);
525
526 fRotateAction->setOn(true);
527 fMoveAction->setOn(false);
528 fPickAction->setOn(false);
529 shortcutsAction->setOn(false);
530
531
532 QObject ::connect(fRotateAction,
533 SIGNAL(activated()),
534 this,
535 SLOT(actionMouseRotate()));
536
537 QObject ::connect(fMoveAction,
538 SIGNAL(activated()),
539 this,
540 SLOT(actionMouseMove()));
541
542 QObject ::connect(fPickAction,
543 SIGNAL(activated()),
544 this,
545 SLOT(actionMousePick()));
546
547 QObject ::connect(shortcutsAction,
548 SIGNAL(activated()),
549 this,
550 SLOT(showShortcuts()));
551
552#else
553 QMenu *mMouseAction = fContextMenu->addMenu("&Mouse actions");
554
555 fRotateAction = mMouseAction->addAction("Rotate");
556 fMoveAction = mMouseAction->addAction("Move");
557 fPickAction = mMouseAction->addAction("Pick");
558 QAction *shortcutsAction = mMouseAction->addAction("Show shortcuts");
559
560 fRotateAction->setCheckable(true);
561 fMoveAction->setCheckable(false);
562 fPickAction->setCheckable(false);
563 shortcutsAction->setCheckable(false);
564
565 fRotateAction->setChecked(true);
566 fMoveAction->setChecked(false);
567 fPickAction->setChecked(false);
568 shortcutsAction->setChecked(false);
569
570 QObject ::connect(fRotateAction,
571 SIGNAL(triggered(bool)),
572 this,
573 SLOT(actionMouseRotate()));
574
575 QObject ::connect(fMoveAction,
576 SIGNAL(triggered(bool)),
577 this,
578 SLOT(actionMouseMove()));
579
580 QObject ::connect(fPickAction,
581 SIGNAL(triggered(bool)),
582 this,
583 SLOT(actionMousePick()));
584
585 QObject ::connect(shortcutsAction,
586 SIGNAL(triggered(bool)),
587 this,
588 SLOT(showShortcuts()));
589#endif
590
591#if QT_VERSION < 0x040000
592 // === Style Menu ===
593 QPopupMenu *mStyle = new QPopupMenu(fContextMenu);
594
595 QPopupMenu *mRepresentation = new QPopupMenu(fContextMenu);
596
597 QPopupMenu *mProjection = new QPopupMenu(fContextMenu);
598
599#if QT_VERSION < 0x030200
600 QAction *polyhedron = new QAction("&Polyhedron","&Polyhedron",CTRL+Key_P,mRepresentation,0,true);
601 QAction *nurbs = new QAction("&NURBS","&NURBS",CTRL+Key_N,mRepresentation,0,true);
602
603 QAction *ortho = new QAction("&Orthographic","&Orthographic",CTRL+Key_O,mProjection,0,true);
604 QAction *perspective = new QAction("&Perspective","&Perspective",CTRL+Key_P,mProjection,0,true);
605#else
606 QAction *polyhedron = new QAction("&Polyhedron",CTRL+Key_P,mRepresentation);
607 QAction *nurbs = new QAction("&NURBS",CTRL+Key_N,mRepresentation);
608
609 QAction *ortho = new QAction("&Orthographic",CTRL+Key_O,mProjection);
610 QAction *perspective = new QAction("&Perspective",CTRL+Key_P,mProjection);
611 polyhedron->setToggleAction(true);
612 nurbs->setToggleAction(true);
613 ortho->setToggleAction(true);
614 perspective->setToggleAction(true);
615#endif
616 polyhedron->addTo(mRepresentation);
617 nurbs->addTo(mRepresentation);
618
619 ortho->addTo(mProjection);
620 perspective->addTo(mProjection);
621
622 mStyle->insertItem("&Representation",mRepresentation);
623 mStyle->insertItem("&Projection",mProjection);
624 fContextMenu->insertItem("&Style",mStyle);
625
626
627#else
628 // === Style Menu ===
629 QMenu *mStyle = fContextMenu->addMenu("&Style");
630
631 QMenu *mRepresentation = mStyle->addMenu("&Representation");
632 QMenu *mProjection = mStyle->addMenu("&Projection");
633 QAction *polyhedron = mRepresentation->addAction("Polyhedron");
634 QAction *nurbs = mRepresentation->addAction("NURBS");
635
636 QAction *ortho = mProjection->addAction("Orthographic");
637 QAction *perspective = mProjection->addAction("Persepective");
638#endif
639
640 // INIT mRepresentation
641 G4ViewParameters::RepStyle style;
642 style = fVP.GetRepStyle();
643 if (style == G4ViewParameters::polyhedron) {
644 createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),1);
645 } else if (style == G4ViewParameters::nurbs) {
646 createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),2);
647 } else {
648 mRepresentation->clear();
649 }
650
651 // INIT mProjection
652 if (fVP.GetFieldHalfAngle() == 0) {
653 createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),1);
654 } else {
655 createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),2);
656 }
657
658#if QT_VERSION < 0x040000
659 // === Drawing Menu ===
660 QPopupMenu *mDrawing = new QPopupMenu(fContextMenu);
661 fContextMenu->insertItem("&Drawing",mDrawing);
662
663#if QT_VERSION < 0x030200
664 fDrawingWireframe = new QAction("&Wireframe","&Wireframe",CTRL+Key_W,mDrawing,0,true);
665 fDrawingLineRemoval = new QAction("&Hidden line removal","&Hidden line removal",CTRL+Key_L,mDrawing,0,true);
666 fDrawingSurfaceRemoval = new QAction("&Hidden surface removal","&Hidden surface removal",CTRL+Key_S,mDrawing,0,true);
667 fDrawingLineSurfaceRemoval = new QAction("&Hidden line and surface removal","&Hidden line and surface removal",CTRL+Key_R,mDrawing,0,true);
668#else
669 fDrawingWireframe = new QAction("&Wireframe",CTRL+Key_W,mDrawing);
670 fDrawingLineRemoval = new QAction("&Hidden line removal",CTRL+Key_L,mDrawing);
671 fDrawingSurfaceRemoval = new QAction("&Hidden surface removal",CTRL+Key_S,mDrawing);
672 fDrawingLineSurfaceRemoval = new QAction("&Hidden line and surface removal",CTRL+Key_R,mDrawing);
673#endif
674 fDrawingWireframe->setToggleAction(true);
675 fDrawingLineRemoval->setToggleAction(true);
676 fDrawingSurfaceRemoval->setToggleAction(true);
677 fDrawingLineSurfaceRemoval->setToggleAction(true);
678
679 fDrawingWireframe->addTo(mDrawing);
680 fDrawingLineRemoval->addTo(mDrawing);
681 fDrawingSurfaceRemoval->addTo(mDrawing);
682 fDrawingLineSurfaceRemoval->addTo(mDrawing);
683
684
685#else
686 // === Drawing Menu ===
687 QMenu *mDrawing = mStyle->addMenu("&Drawing");
688
689 fDrawingWireframe = mDrawing->addAction("Wireframe");
690 fDrawingWireframe->setCheckable(true);
691
692 fDrawingLineRemoval = mDrawing->addAction("Hidden line removal");
693 fDrawingLineRemoval->setCheckable(true);
694
695 fDrawingSurfaceRemoval = mDrawing->addAction("Hidden Surface removal");
696 fDrawingSurfaceRemoval->setCheckable(true);
697
698 fDrawingLineSurfaceRemoval = mDrawing->addAction("Hidden line and surface removal");
699 fDrawingLineSurfaceRemoval->setCheckable(true);
700#endif
701 // INIT Drawing
702 G4ViewParameters::DrawingStyle d_style;
703 d_style = fVP.GetDrawingStyle();
704
705#if QT_VERSION < 0x040000
706 if (d_style == G4ViewParameters::wireframe) {
707 fDrawingWireframe->setOn(true);
708 } else if (d_style == G4ViewParameters::hlr) {
709 fDrawingLineRemoval->setOn(true);
710 } else if (d_style == G4ViewParameters::hsr) {
711 fDrawingSurfaceRemoval->setOn(true);
712 } else if (d_style == G4ViewParameters::hlhsr) {
713 fDrawingLineSurfaceRemoval->setOn(true);
714 } else {
715 mDrawing->clear();
716 }
717#ifdef GEANT4_QT_DEBUG
718 printf("G4OpenGLQtViewer:: fDrawingWireframe 1\n");
719#endif
720 QObject ::connect(fDrawingWireframe,
721 SIGNAL(activated()),
722 this,
723 SLOT(actionDrawingWireframe()));
724#ifdef GEANT4_QT_DEBUG
725 printf("G4OpenGLQtViewer:: fDrawingWireframe 2\n");
726#endif
727 QObject ::connect(fDrawingLineRemoval,
728 SIGNAL(activated()),
729 this,
730 SLOT(actionDrawingLineRemoval()));
731 QObject ::connect(fDrawingSurfaceRemoval,
732 SIGNAL(activated()),
733 this,
734 SLOT(actionDrawingSurfaceRemoval()));
735 QObject ::connect(fDrawingLineSurfaceRemoval,
736 SIGNAL(activated()),
737 this,
738 SLOT(actionDrawingLineSurfaceRemoval()));
739#else
740 if (d_style == G4ViewParameters::wireframe) {
741 fDrawingWireframe->setChecked(true);
742 } else if (d_style == G4ViewParameters::hlr) {
743 fDrawingLineRemoval->setChecked(true);
744 } else if (d_style == G4ViewParameters::hsr) {
745 fDrawingSurfaceRemoval->setChecked(true);
746 } else if (d_style == G4ViewParameters::hlhsr) {
747 fDrawingLineSurfaceRemoval->setChecked(true);
748 } else {
749 mDrawing->clear();
750 }
751 QObject ::connect(fDrawingWireframe,
752 SIGNAL(triggered(bool)),
753 this,
754 SLOT(actionDrawingWireframe()));
755 QObject ::connect(fDrawingLineRemoval,
756 SIGNAL(triggered(bool)),
757 this,
758 SLOT(actionDrawingLineRemoval()));
759 QObject ::connect(fDrawingSurfaceRemoval,
760 SIGNAL(triggered(bool)),
761 this,
762 SLOT(actionDrawingSurfaceRemoval()));
763 QObject ::connect(fDrawingLineSurfaceRemoval,
764 SIGNAL(triggered(bool)),
765 this,
766 SLOT(actionDrawingLineSurfaceRemoval()));
767#endif
768
769
770
771#if QT_VERSION < 0x040000
772 QPopupMenu *mBackground = new QPopupMenu(mStyle);
773 mStyle->insertItem("&Background color",mBackground);
774
775#if QT_VERSION < 0x030200
776 QAction *white = new QAction("&White","&White",CTRL+Key_W,mBackground,0,true);
777 QAction *black = new QAction("&Black","&Black",CTRL+Key_B,mBackground,0,true);
778#else
779 QAction *white = new QAction("&White",CTRL+Key_W,mBackground);
780 QAction *black = new QAction("&Black",CTRL+Key_B,mBackground);
781 white->setToggleAction(true);
782 black->setToggleAction(true);
783#endif
784 white->addTo(mBackground);
785 black->addTo(mBackground);
786
787#else
788 QMenu *mBackground = mStyle->addMenu("&Background color");
789 QAction *white = mBackground->addAction("White");
790 QAction *black = mBackground->addAction("Black");
791
792#endif
793 if (background.GetRed() == 1. &&
794 background.GetGreen() == 1. &&
795 background.GetBlue() == 1.) {
796 createRadioAction(white,black,SLOT(toggleBackground(bool)),1);
797 } else {
798 createRadioAction(white,black,SLOT(toggleBackground(bool)),2);
799 }
800
801
802#if QT_VERSION < 0x040000
803 // === Action Menu ===
804 QPopupMenu *mActions = new QPopupMenu(fContextMenu);
805 fContextMenu->insertItem("&Actions",mActions);
806
807#if QT_VERSION < 0x030200
808 QAction *createEPS = new QAction("&Save as ...","&Save as ...",CTRL+Key_S,mActions,0,true);
809#else
810 QAction *createEPS = new QAction("&Save as ...",CTRL+Key_S,mActions);
811#endif
812 createEPS->addTo(mActions);
813 QObject ::connect(createEPS,
814 SIGNAL(activated()),
815 this,
816 SLOT(actionSaveImage()));
817
818#else
819 // === Action Menu ===
820 QMenu *mActions = fContextMenu->addMenu("&Actions");
821 QAction *createEPS = mActions->addAction("Save as ...");
822 QObject ::connect(createEPS,
823 SIGNAL(triggered()),
824 this,
825 SLOT(actionSaveImage()));
826#endif
827
828#if QT_VERSION < 0x040000
829#if QT_VERSION < 0x030200
830 QAction *movieParameters = new QAction("&Movie parameters...","&Make movie ...",CTRL+Key_M,mActions,0,true);
831#else
832 QAction *movieParameters = new QAction("&Movie parameters...",CTRL+Key_M,mActions);
833#endif
834 movieParameters->addTo(mActions);
835 QObject ::connect(movieParameters,
836 SIGNAL(activated()),
837 this,
838 SLOT(actionMovieParameters()));
839
840#else
841 // === Action Menu ===
842 QAction *movieParameters = mActions->addAction("Movie parameters...");
843 QObject ::connect(movieParameters,
844 SIGNAL(triggered()),
845 this,
846 SLOT(actionMovieParameters()));
847#endif
848
849
850
851
852#if QT_VERSION < 0x040000
853 // === Special Menu ===
854 QPopupMenu *mSpecial = new QPopupMenu(fContextMenu);
855 fContextMenu->insertItem("S&pecial",mSpecial);
856
857 QPopupMenu *mTransparency = new QPopupMenu(mSpecial);
858 mSpecial->insertItem("Transparency",mTransparency);
859
860#if QT_VERSION < 0x030200
861 QAction *transparencyOn = new QAction("&On","&On",CTRL+Key_O,mTransparency,0,true);
862 QAction *transparencyOff = new QAction("&Off","&Off",CTRL+Key_F,mTransparency,0,true);
863#else
864 QAction *transparencyOn = new QAction("&On",CTRL+Key_O,mTransparency);
865 QAction *transparencyOff = new QAction("&Off",CTRL+Key_F,mTransparency);
866 transparencyOn->setToggleAction(true);
867 transparencyOff->setToggleAction(true);
868#endif
869 transparencyOn->addTo(mTransparency);
870 transparencyOff->addTo(mTransparency);
871
872#else
873 // === Special Menu ===
874 QMenu *mSpecial = fContextMenu->addMenu("S&pecial");
875 QMenu *mTransparency = mSpecial->addMenu("Transparency");
876 QAction *transparencyOn = mTransparency->addAction("On");
877 QAction *transparencyOff = mTransparency->addAction("Off");
878#endif
879
880 if (transparency_enabled == false) {
881 createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),2);
882 } else if (transparency_enabled == true) {
883 createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),1);
884 } else {
885 mSpecial->clear();
886 }
887
888
889#if QT_VERSION < 0x040000
890 QPopupMenu *mAntialiasing = new QPopupMenu(mSpecial);
891 mSpecial->insertItem("Antialiasing",mAntialiasing);
892
893#if QT_VERSION < 0x030200
894 QAction *antialiasingOn = new QAction("&On","&On",CTRL+Key_O,mAntialiasing,0,true);
895 QAction *antialiasingOff = new QAction("&Off","&Off",CTRL+Key_F,mAntialiasing,0,true);
896#else
897 QAction *antialiasingOn = new QAction("&On",CTRL+Key_O,mAntialiasing);
898 QAction *antialiasingOff = new QAction("&Off",CTRL+Key_F,mAntialiasing);
899 antialiasingOn->setToggleAction(true);
900 antialiasingOff->setToggleAction(true);
901#endif
902 antialiasingOn->addTo(mAntialiasing);
903 antialiasingOff->addTo(mAntialiasing);
904
905#else
906 QMenu *mAntialiasing = mSpecial->addMenu("Antialiasing");
907 QAction *antialiasingOn = mAntialiasing->addAction("On");
908 QAction *antialiasingOff = mAntialiasing->addAction("Off");
909#endif
910
911 if (antialiasing_enabled == false) {
912 createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),2);
913 } else if (antialiasing_enabled == true) {
914 createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),1);
915 } else {
916 mAntialiasing->clear();
917 }
918
919#if QT_VERSION < 0x040000
920 QPopupMenu *mHaloing = new QPopupMenu(mSpecial);
921 mSpecial->insertItem("Haloing",mHaloing);
922
923#if QT_VERSION < 0x030200
924 QAction *haloingOn = new QAction("&On","&On",CTRL+Key_O,mHaloing,0,true);
925 QAction *haloingOff = new QAction("&Off","&Off",CTRL+Key_F,mHaloing,0,true);
926#else
927 QAction *haloingOn = new QAction("&On",CTRL+Key_O,mHaloing);
928 QAction *haloingOff = new QAction("&Off",CTRL+Key_F,mHaloing);
929 haloingOn->setToggleAction(true);
930 haloingOff->setToggleAction(true);
931#endif
932 haloingOn->addTo(mHaloing);
933 haloingOff->addTo(mHaloing);
934#else
935 QMenu *mHaloing = mSpecial->addMenu("Haloing");
936 QAction *haloingOn = mHaloing->addAction("On");
937 QAction *haloingOff = mHaloing->addAction("Off");
938#endif
939 if (haloing_enabled == false) {
940 createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),2);
941 } else if (haloing_enabled == true) {
942 createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),1);
943 } else {
944 mHaloing->clear();
945 }
946
947#if QT_VERSION < 0x040000
948 QPopupMenu *mAux = new QPopupMenu(mSpecial);
949 mSpecial->insertItem("Auxiliairy edges",mAux);
950
951#if QT_VERSION < 0x030200
952 QAction *auxOn = new QAction("&On","&On",CTRL+Key_O,mAux,0,true);
953 QAction *auxOff = new QAction("&Off","&Off",CTRL+Key_F,mAux,0,true);
954#else
955 QAction *auxOn = new QAction("&On",CTRL+Key_O,mAux);
956 QAction *auxOff = new QAction("&Off",CTRL+Key_F,mAux);
957 auxOn->setToggleAction(true);
958 auxOff->setToggleAction(true);
959#endif
960 auxOn->addTo(mAux);
961 auxOff->addTo(mAux);
962
963#else
964 QMenu *mAux = mSpecial->addMenu("Auxiliary edges");
965 QAction *auxOn = mAux->addAction("On");
966 QAction *auxOff = mAux->addAction("Off");
967#endif
968 if (!fVP.IsAuxEdgeVisible()) {
969 createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),1);
970 } else {
971 createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),2);
972 }
973
974
975
976#if QT_VERSION < 0x040000
977 QPopupMenu *mFullScreen = new QPopupMenu(mSpecial);
978 mSpecial->insertItem("Full screen",mFullScreen);
979
980#if QT_VERSION < 0x030200
981 fFullScreenOn = new QAction("&On","&On",CTRL+Key_O,mFullScreen,0,true);
982 fFullScreenOff = new QAction("&Off","&Off",CTRL+Key_F,mFullScreen,0,true);
983#else
984 fFullScreenOn = new QAction("&On",CTRL+Key_O,mFullScreen);
985 fFullScreenOff = new QAction("&Off",CTRL+Key_F,mFullScreen);
986 fFullScreenOn->setToggleAction(true);
987 fFullScreenOff->setToggleAction(true);
988#endif
989 fFullScreenOn->addTo(mFullScreen);
990 fFullScreenOff->addTo(mFullScreen);
991#else
992 QMenu *mFullScreen = mSpecial->addMenu("&Full screen");
993 fFullScreenOn = mFullScreen->addAction("On");
994 fFullScreenOff = mFullScreen->addAction("Off");
995#endif
996 createRadioAction(fFullScreenOn,fFullScreenOff,SLOT(toggleFullScreen(bool)),2);
997
998}
999
1000void G4OpenGLQtViewer::manageContextMenuEvent(QContextMenuEvent *e)
1001{
1002 if (!GLWindow) {
1003 G4cerr << "Visualization window not defined, please choose one before" << G4endl;
1004 } else {
1005
1006 if (!fContextMenu)
1007 createPopupMenu();
1008
1009 // launch menu
1010 if ( fContextMenu ) {
1011 fContextMenu->exec( e->globalPos() );
1012 // delete fContextMenu;
1013 }
1014 }
1015 e->accept();
1016}
1017
1018
1019/**
1020 Create a radio button menu. The two menu will be connected. When click on one,
1021 eatch state will be invert and callback method will be called.
1022 @param action1 first action to connect
1023 @param action2 second action to connect
1024 @param method callback method
1025 @param nCheck: 1 : first action will be set true. 2 : second action will be set true
1026*/
1027#if QT_VERSION < 0x040000
1028void G4OpenGLQtViewer::createRadioAction(QAction *action1,QAction *action2, const std::string& method,unsigned int nCheck) {
1029
1030 if (action1->parent()->inherits("QPopupMenu")){
1031 ((QPopupMenu*)action1->parent())->setCheckable(true);
1032 ((QPopupMenu*)action2->parent())->setCheckable(true);
1033 }
1034 action1->setOn(false);
1035 action2->setOn(false);
1036
1037 if (nCheck ==1)
1038 action1->setOn(true);
1039 else
1040 action2->setOn(true);
1041
1042 //FIXME : Should not work on Qt3
1043 QObject ::connect(action1, SIGNAL(activated()),action2, SLOT(toggle()));
1044 QObject ::connect(action2, SIGNAL(activated()),action1, SLOT(toggle()));
1045
1046 QObject ::connect(action1, SIGNAL(toggled(bool)),this, method.c_str());
1047}
1048
1049#else
1050void G4OpenGLQtViewer::createRadioAction(QAction *action1,QAction *action2, const std::string& method,unsigned int nCheck) {
1051
1052 action1->setCheckable(true);
1053 action2->setCheckable(true);
1054
1055 if (nCheck ==1)
1056 action1->setChecked (true);
1057 else
1058 action2->setChecked (true);
1059
1060 QObject ::connect(action1, SIGNAL(triggered(bool)),action2, SLOT(toggle()));
1061 QObject ::connect(action2, SIGNAL(triggered(bool)),action1, SLOT(toggle()));
1062
1063 QObject ::connect(action1, SIGNAL(toggled(bool)),this, method.c_str());
1064
1065}
1066#endif
1067
1068/**
1069 Slot activate when mouseAction->rotate menu is set
1070 */
1071void G4OpenGLQtViewer::actionMouseRotate() {
1072 emit toggleMouseAction(STYLE1);
1073}
1074
1075
1076/**
1077 Slot activate when mouseAction->rotate menu is set
1078 */
1079void G4OpenGLQtViewer::actionMouseMove() {
1080 emit toggleMouseAction(STYLE2);
1081}
1082
1083
1084/**
1085 Slot activate when mouseAction->zoom menu is set
1086 */
1087void G4OpenGLQtViewer::actionMousePick() {
1088#ifdef GEANT4_QT_DEBUG
1089 printf("G4OpenGLQtViewer::actionMousePick \n");
1090#endif
1091 emit toggleMouseAction(STYLE3);
1092}
1093
1094
1095/**
1096 Slot activate when drawing->wireframe menu is set
1097 */
1098void G4OpenGLQtViewer::actionDrawingWireframe() {
1099 emit toggleDrawingAction(1);
1100}
1101
1102/**
1103 Slot activate when drawing->line removal menu is set
1104 */
1105void G4OpenGLQtViewer::actionDrawingLineRemoval() {
1106 emit toggleDrawingAction(2);
1107}
1108
1109/**
1110 Slot activate when drawing->surface removal menu is set
1111 */
1112void G4OpenGLQtViewer::actionDrawingSurfaceRemoval() {
1113 emit toggleDrawingAction(3);
1114}
1115
1116/**
1117 Slot activate when drawing->wireframe menu is set
1118 */
1119void G4OpenGLQtViewer::actionDrawingLineSurfaceRemoval() {
1120 emit toggleDrawingAction(4);
1121}
1122
1123
1124/**
1125 Slot activated when mouse action is toggle
1126 @param aAction : STYLE1, STYLE2, STYLE3
1127 */
1128void G4OpenGLQtViewer::toggleMouseAction(mouseActions aAction) {
1129
1130 if ((aAction == STYLE1) || //initialize all
1131 (aAction == STYLE2) ||
1132 (aAction == STYLE3)) {
1133#if QT_VERSION < 0x040000
1134 fRotateAction->setOn (false);
1135 fMoveAction->setOn (false);
1136 fPickAction->setOn (false);
1137#else
1138 fRotateAction->setChecked (false);
1139 fMoveAction->setChecked (false);
1140 fPickAction->setChecked (false);
1141#endif
1142 fVP.SetPicking(false);
1143 fMouseAction = aAction;
1144 }
1145 // rotate
1146 if (aAction == STYLE1) { // rotate
1147 showShortcuts();
1148#if QT_VERSION < 0x040000
1149 fRotateAction->setOn (true);
1150#else
1151 fRotateAction->setChecked (true);
1152#endif
1153 } else if (aAction == STYLE2) { //move
1154#if QT_VERSION < 0x040000
1155 fMoveAction->setOn (true);
1156#else
1157 fMoveAction->setChecked (true);
1158#endif
1159 } else if (aAction == STYLE3) { //pick
1160#if QT_VERSION < 0x040000
1161 fPickAction->setOn (true);
1162#else
1163 fPickAction->setChecked (true);
1164#endif
1165 fVP.SetPicking(true);
1166 }
1167}
1168
1169/**
1170 Show shortcuts for this mouse action
1171 */
1172void G4OpenGLQtViewer::showShortcuts() {
1173 if (fMouseAction == STYLE1) { // rotate
1174 G4cout << "Click and move mouse to rotate volume " << G4endl;
1175 G4cout << "Press left/right arrows to move volume left/right" << G4endl;
1176 G4cout << "Press up/down arrows to move volume up/down" << G4endl;
1177 G4cout << "Press ALT+up/down arrows to move volume toward/forward" << G4endl;
1178 G4cout << "Press SHIFT+left/right arrows to rotate volume left/right" << G4endl;
1179 G4cout << "Press SHIFT+up/down arrows to rotate volume up/down" << G4endl;
1180 G4cout << "Press ALT+/- to slow/speed auto rotation/move" << G4endl;
1181 G4cout << "In video mode : " << G4endl;
1182 G4cout << " Press SPACE to Start/Pause video recording " << G4endl;
1183 G4cout << " Press RETURN to Stop video recording " << G4endl;
1184 } else if (fMouseAction == STYLE2) { //move
1185 G4cout << "Move camera point of view with mouse" << G4endl;
1186 G4cout << "Press left/right arrows to move volume left/right" << G4endl;
1187 G4cout << "Press up/down arrows to move volume up/down" << G4endl;
1188 G4cout << "Press ALT+up/down arrows to move volume toward/forward" << G4endl;
1189 G4cout << "Press SHIFT+left/right arrows to rotate volume left/right" << G4endl;
1190 G4cout << "Press SHIFT+up/down arrows to rotate volume up/down" << G4endl;
1191 G4cout << "Press +/- to zoom into volume" << G4endl;
1192 G4cout << "Press ALT+/- to slow/speed auto rotation/move" << G4endl;
1193 G4cout << "In video mode : " << G4endl;
1194 G4cout << " Press SPACE to Start/Pause video recording " << G4endl;
1195 G4cout << " Press RETURN to Stop video recording " << G4endl;
1196 } else if (fMouseAction == STYLE3) { //pick
1197 G4cout << "Click and pick " << G4endl;
1198 }
1199
1200}
1201
1202
1203
1204/**
1205 Slot activated when drawing menu is toggle
1206 Warning : When G4OpenGLStoredQtViewer::DrawView() method call,
1207 KernelVisitDecision () will be call and will set the fNeedKernelVisit
1208 to 1. See G4XXXStoredViewer::CompareForKernelVisit for explanations.
1209 It will cause a redraw of the view
1210 @param aAction : 1 wireframe, 2 line removal, 3 surface removal, 4 line & surface removal
1211 @see G4OpenGLStoredQtViewer::DrawView
1212 @see G4XXXStoredViewer::CompareForKernelVisit
1213 */
1214void G4OpenGLQtViewer::toggleDrawingAction(int aAction) {
1215
1216 G4ViewParameters::DrawingStyle d_style;
1217
1218
1219 // initialize
1220 if ((aAction >0) && (aAction <5)) {
1221#if QT_VERSION < 0x040000
1222 fDrawingWireframe->setOn(false);
1223 fDrawingLineRemoval->setOn(false);
1224 fDrawingSurfaceRemoval->setOn(false);
1225 fDrawingLineSurfaceRemoval->setOn(false);
1226#else
1227 fDrawingWireframe->setChecked (false);
1228 fDrawingLineRemoval->setChecked (false);
1229 fDrawingSurfaceRemoval->setChecked (false);
1230 fDrawingLineSurfaceRemoval->setChecked (false);
1231#endif
1232 }
1233 if (aAction ==1) {
1234#if QT_VERSION < 0x040000
1235 fDrawingWireframe->setOn(true);
1236#else
1237 fDrawingWireframe->setChecked (true);
1238#endif
1239
1240 d_style = G4ViewParameters::wireframe;
1241
1242 } else if (aAction ==2) {
1243#if QT_VERSION < 0x040000
1244 fDrawingLineRemoval->setOn(true);
1245#else
1246 fDrawingLineRemoval->setChecked (true);
1247#endif
1248
1249 d_style = G4ViewParameters::hlr;
1250
1251 } else if (aAction ==3) {
1252#if QT_VERSION < 0x040000
1253 fDrawingSurfaceRemoval->setOn(true);
1254#else
1255 fDrawingSurfaceRemoval->setChecked (true);
1256#endif
1257
1258 d_style = G4ViewParameters::hsr;
1259
1260 } else if (aAction ==4) {
1261#if QT_VERSION < 0x040000
1262 fDrawingLineSurfaceRemoval->setOn(true);
1263#else
1264 fDrawingLineSurfaceRemoval->setChecked (true);
1265#endif
1266 d_style = G4ViewParameters::hlhsr;
1267 }
1268 fVP.SetDrawingStyle(d_style);
1269
1270 updateQWidget();
1271}
1272
1273
1274/**
1275 SLOT Activate by a click on the representation menu
1276 Warning : When G4OpenGLStoredQtViewer::DrawView() method call,
1277 KernelVisitDecision () will be call and will set the fNeedKernelVisit
1278 to 1. See G4XXXStoredViewer::CompareForKernelVisit for explanations.
1279 It will cause a redraw of the view
1280 @param check : 1 polyhedron, 0 nurbs
1281 @see G4OpenGLStoredQtViewer::DrawView
1282 @see G4XXXStoredViewer::CompareForKernelVisit
1283*/
1284void G4OpenGLQtViewer::toggleRepresentation(bool check) {
1285
1286 G4ViewParameters::RepStyle style;
1287 if (check == 1) {
1288 style = G4ViewParameters::polyhedron;
1289 } else {
1290 style = G4ViewParameters::nurbs;
1291 }
1292 fVP.SetRepStyle (style);
1293
1294 updateQWidget();
1295}
1296
1297/**
1298 SLOT Activate by a click on the projection menu
1299 Warning : When G4OpenGLStoredQtViewer::DrawView() method call,
1300 KernelVisitDecision () will be call and will set the fNeedKernelVisit
1301 to 1. See G4XXXStoredViewer::CompareForKernelVisit for explanations.
1302 It will cause a redraw of the view
1303 @param check : 1 orthographic, 2 perspective
1304 @see G4OpenGLStoredQtViewer::DrawView
1305 @see G4XXXStoredViewer::CompareForKernelVisit
1306*/
1307void G4OpenGLQtViewer::toggleProjection(bool check) {
1308
1309 if (check == 1) {
1310 fVP.SetFieldHalfAngle (0);
1311 } else {
1312
1313 // look for the default parameter hidden in G4UIcommand parameters
1314 G4UImanager* UI = G4UImanager::GetUIpointer();
1315 if(UI==NULL)
1316 return;
1317 G4UIcommandTree * treeTop = UI->GetTree();
1318
1319 // find command
1320 G4UIcommand* command = treeTop->FindPath("/vis/viewer/set/projection");
1321 if (!command)
1322 return;
1323
1324 // find param
1325 G4UIparameter * angleParam = NULL;
1326 for(G4int i=0; i<command->GetParameterEntries(); i++)
1327 {
1328 if( command->GetParameter(i)->GetParameterName() == "field-half-angle" ) {
1329 angleParam = command->GetParameter(i);
1330 }
1331 }
1332 if (!angleParam)
1333 return;
1334
1335 // find unit
1336 G4UIparameter * unitParam = NULL;
1337 for(G4int i=0; i<command->GetParameterEntries(); i++)
1338 {
1339 if( command->GetParameter(i)->GetParameterName() == "unit" ) {
1340 unitParam = command->GetParameter(i);
1341 }
1342 }
1343 if (!unitParam)
1344 return;
1345
1346 G4double defaultValue = command->ConvertToDouble(angleParam->GetDefaultValue())
1347 * G4UnitDefinition::GetValueOf(unitParam->GetDefaultValue());
1348 if (defaultValue > 89.5 || defaultValue <= 0.0) {
1349 G4cerr << "Field half angle should be 0 < angle <= 89.5 degrees. Check your default Field half angle parameter";
1350 } else {
1351 G4cout << "Perspective view has been set to default value. Field half angle="<<angleParam->GetDefaultValue() <<" " << G4endl;
1352 fVP.SetFieldHalfAngle (defaultValue);
1353 SetView ();
1354 }
1355 }
1356 updateQWidget();
1357}
1358
1359
1360/**
1361 SLOT Activate by a click on the background menu
1362@param check : 1 white, 0 black
1363*/
1364void G4OpenGLQtViewer::toggleBackground(bool check) {
1365
1366 // //I need to revisit the kernel if the background colour changes and
1367 // //hidden line removal is enabled, because hlr drawing utilises the
1368 // //background colour in its drawing...
1369 // // (Note added by JA 13/9/2005) Background now handled in view
1370 // // parameters. A kernel visit is triggered on change of background.
1371 if (check == 1) {
1372 ((G4ViewParameters&)this->GetViewParameters()).
1373 SetBackgroundColour(G4Colour(1.,1.,1.)); // White
1374 } else {
1375 ((G4ViewParameters&)this->GetViewParameters()).
1376 SetBackgroundColour(G4Colour(0.,0.,0.)); // Black
1377 }
1378 updateQWidget();
1379}
1380
1381/**
1382 SLOT Activate by a click on the transparency menu
1383@param check : 1 , 0
1384*/
1385void G4OpenGLQtViewer::toggleTransparency(bool check) {
1386
1387 if (check) {
1388 transparency_enabled = false;
1389 } else {
1390 transparency_enabled = true;
1391 }
1392 SetNeedKernelVisit (true);
1393 updateQWidget();
1394}
1395
1396/**
1397 SLOT Activate by a click on the antialiasing menu
1398@param check : 1 , 0
1399*/
1400void G4OpenGLQtViewer::toggleAntialiasing(bool check) {
1401
1402 if (!check) {
1403 antialiasing_enabled = false;
1404 glDisable (GL_LINE_SMOOTH);
1405 glDisable (GL_POLYGON_SMOOTH);
1406 } else {
1407 antialiasing_enabled = true;
1408 glEnable (GL_LINE_SMOOTH);
1409 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
1410 glEnable (GL_POLYGON_SMOOTH);
1411 glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
1412 }
1413
1414 updateQWidget();
1415}
1416
1417/**
1418 SLOT Activate by a click on the haloing menu
1419@param check : 1 , 0
1420*/
1421//FIXME : I SEE NOTHING...
1422void G4OpenGLQtViewer::toggleHaloing(bool check) {
1423 if (check) {
1424 haloing_enabled = false;
1425 } else {
1426 haloing_enabled = true;
1427 }
1428
1429 updateQWidget();
1430
1431}
1432
1433/**
1434 SLOT Activate by a click on the auxiliaire edges menu
1435@param check : 1 , 0
1436*/
1437void G4OpenGLQtViewer::toggleAux(bool check) {
1438 if (check) {
1439 fVP.SetAuxEdgeVisible(false);
1440 } else {
1441 fVP.SetAuxEdgeVisible(true);
1442 }
1443 SetNeedKernelVisit (true);
1444 updateQWidget();
1445
1446}
1447
1448/**
1449 SLOT Activate by a click on the full screen menu
1450*/
1451void G4OpenGLQtViewer::toggleFullScreen(bool check) {
1452 if (check != GLWindow->isFullScreen()) { //toggle
1453#if QT_VERSION >= 0x030200
1454 GLWindow->setWindowState(GLWindow->windowState() ^ Qt::WindowFullScreen);
1455#else
1456 G4cerr << "This version of Qt could not do fullScreen. Resizing the widget is the only solution available." << G4endl;
1457#endif
1458 }
1459}
1460
1461
1462void G4OpenGLQtViewer::savePPMToTemp() {
1463 if (fMovieTempFolderPath == "") {
1464 return;
1465 }
1466 QString fileName ="Test"+QString::number(fRecordFrameNumber)+".ppm";
1467 QString filePath =fMovieTempFolderPath+fileName;
1468
1469 QImage image;
1470 image = fWindow->grabFrameBuffer();
1471 bool res = false;
1472
1473#if QT_VERSION < 0x040000
1474 res = image.save(filePath,"PPM");
1475#else
1476 res = image.save(filePath,0);
1477#endif
1478 if (res == false) {
1479 resetRecording();
1480 setRecordingInfos("Can't save tmp file "+filePath);
1481 return;
1482 }
1483
1484 setRecordingInfos("File "+fileName+" saved");
1485 fRecordFrameNumber++;
1486}
1487
1488
1489
1490void G4OpenGLQtViewer::actionSaveImage() {
1491 QString filters;
1492#if QT_VERSION < 0x040000
1493 QStrList listFormat=QImageIO::outputFormats();
1494 char *tmp=listFormat.first();
1495 while (tmp!=0) {
1496 filters += QString(tmp) + ";;";
1497 tmp=listFormat.next();
1498 }
1499#else
1500 QList<QByteArray> formats = QImageWriter::supportedImageFormats ();
1501 for (int i = 0; i < formats.size(); ++i) {
1502 filters +=formats.at(i) + ";;";
1503 }
1504#endif
1505 filters += "eps;;";
1506 filters += "ps;;";
1507 filters += "pdf";
1508 QString* selectedFormat = new QString();
1509#if QT_VERSION < 0x040000
1510 QString nomFich = QFileDialog::getSaveFileName ( ".",
1511 filters,
1512 GLWindow,
1513 "Save file dialog",
1514 tr("Save as ..."),
1515 selectedFormat );
1516#else
1517 QString nomFich = QFileDialog::getSaveFileName ( GLWindow,
1518 tr("Save as ..."),
1519 ".",
1520 filters,
1521 selectedFormat );
1522#endif
1523 // bmp jpg jpeg png ppm xbm xpm
1524 if (nomFich == "") {
1525 return;
1526 }
1527#if QT_VERSION < 0x040000
1528 nomFich += "."+QString(selectedFormat->ascii());
1529 QString format = selectedFormat->lower();
1530#else
1531 nomFich += "."+QString(selectedFormat->toStdString().c_str());
1532 QString format = selectedFormat->toLower();
1533#endif
1534 G4OpenGLQtExportDialog* exportDialog= new G4OpenGLQtExportDialog(GLWindow,format,fWindow->height(),fWindow->width());
1535 if( exportDialog->exec()) {
1536
1537 QImage image;
1538 bool res = false;
1539 if ((exportDialog->getWidth() !=fWindow->width()) ||
1540 (exportDialog->getHeight() !=fWindow->height())) {
1541 if (format != QString("eps")) {
1542 G4cerr << "Export->Change Size : This function is not implemented, to export in another size, please resize your frame to what you need" << G4endl;
1543
1544 // rescaleImage(exportDialog->getWidth(),exportDialog->getHeight());// re-scale image
1545 // QGLWidget* glResized = fWindow;
1546
1547 // FIXME :
1548 // L.Garnier : I've try to implement change size function, but the problem is
1549 // the renderPixmap function call the QGLWidget to resize and it doesn't draw
1550 // the content of this widget... It only draw the background.
1551
1552 // fWindow->renderPixmap (exportDialog->getWidth()*2,exportDialog->getHeight()*2,true );
1553
1554 // QPixmap pixmap = fWindow->renderPixmap ();
1555
1556 // image = pixmap->toImage();
1557 // glResized->resize(exportDialog->getWidth()*2,exportDialog->getHeight()*2);
1558 // image = glResized->grabFrameBuffer();
1559 }
1560 } else {
1561 image = fWindow->grabFrameBuffer();
1562 }
1563 if (format == QString("eps")) {
1564 if (exportDialog->getVectorEPS()) {
1565 res = generateVectorEPS(nomFich,exportDialog->getWidth(),exportDialog->getHeight(),image);
1566 } else {
1567 res = generateEPS(nomFich,exportDialog->getNbColor(),image);
1568 }
1569 } else if ((format == "ps") || (format == "pdf")) {
1570 res = generatePS_PDF(nomFich,exportDialog->getNbColor(),image);
1571 } else if ((format == "tif") ||
1572 (format == "tiff") ||
1573 (format == "jpg") ||
1574 (format == "jpeg") ||
1575 (format == "png") ||
1576 (format == "pbm") ||
1577 (format == "pgm") ||
1578 (format == "ppm") ||
1579 (format == "bmp") ||
1580 (format == "xbm") ||
1581 (format == "xpm")) {
1582#if QT_VERSION < 0x040000
1583 res = image.save(nomFich,selectedFormat->ascii(),exportDialog->getSliderValue());
1584#else
1585 res = image.save(nomFich,0,exportDialog->getSliderValue());
1586#endif
1587 } else {
1588 G4cerr << "This version of G4UI Could not generate the selected format" << G4endl;
1589 }
1590 if (res == false) {
1591#if QT_VERSION < 0x040000
1592 G4cerr << "Error while saving file... "<<nomFich.ascii()<<"" << G4endl;
1593#else
1594 G4cerr << "Error while saving file... "<<nomFich.toStdString().c_str()<< G4endl;
1595#endif
1596 } else {
1597#if QT_VERSION < 0x040000
1598 G4cout << "File "<<nomFich.ascii()<<" has been saved " << G4endl;
1599#else
1600 G4cout << "File "<<nomFich.toStdString().c_str()<<" has been saved " << G4endl;
1601#endif
1602 }
1603
1604 } else { // cancel selected
1605 return;
1606 }
1607
1608#ifdef GEANT4_QT_DEBUG
1609 printf("G4OpenGLQtViewer::actionSaveImage() \n");
1610#endif
1611}
1612
1613
1614void G4OpenGLQtViewer::actionMovieParameters() {
1615
1616 showMovieParametersDialog();
1617#ifdef GEANT4_QT_DEBUG
1618 printf("G4OpenGLQtViewer::actionMovieParameters() \n");
1619#endif
1620}
1621
1622
1623void G4OpenGLQtViewer::showMovieParametersDialog() {
1624 if (!fMovieParametersDialog) {
1625 fMovieParametersDialog= new G4OpenGLQtMovieDialog(this,GLWindow);
1626 displayRecordingStatus();
1627 if (getEncoderPath() == "") {
1628 setRecordingInfos("mpeg_encode is needed to encode in video format. It is available here: http://bmrc.berkeley.edu/frame/research/mpeg/");
1629 }
1630 }
1631 fMovieParametersDialog->show();
1632}
1633
1634
1635/*
1636// http://www.google.com/codesearch?hl=en&q=+jpg+Qt+quality+QDialog+show:FZkUoth8oiw:TONpW2mR-_c:tyTfrKMO-xI&sa=N&cd=2&ct=rc&cs_p=http://soft.proindependent.com/src/qtiplot-0.8.9.zip&cs_f=qtiplot-0.8.9/qtiplot/src/application.cpp#a0
1637
1638void Graph::exportToSVG(const QString& fname)
1639{
1640 // enable workaround for Qt3 misalignments
1641 QwtPainter::setSVGMode(true);
1642 QPicture picture;
1643 QPainter p(&picture);
1644 d_plot->print(&p, d_plot->rect());
1645 p.end();
1646
1647 picture.save(fname, "svg");
1648}
1649*/
1650
1651
1652
1653
1654/**
1655 Save the current mouse press point
1656 @param p mouse click point
1657*/
1658#if QT_VERSION < 0x040000
1659void G4OpenGLQtViewer::G4MousePressEvent(QPoint p)
1660#else
1661void G4OpenGLQtViewer::G4MousePressEvent(QPoint p)
1662#endif
1663{
1664 fAutoMove = false; // stop automove
1665 fLastPos1 = p;
1666 fLastPos2 = fLastPos1;
1667 fLastPos3 = fLastPos2;
1668 fLastEventTime->start();
1669 if (fMouseAction == STYLE2){ // pick
1670 Pick(p.x(),p.y());
1671 }
1672}
1673
1674/**
1675*/
1676void G4OpenGLQtViewer::G4MouseReleaseEvent()
1677{
1678#ifdef GEANT4_QT_DEBUG
1679 printf("G4OpenGLQtViewer::mouseRealease() %d,%d %d,%d %d,%d\n",fLastPos1.x(),fLastPos1.y(),fLastPos2.x(),fLastPos2.y(),fLastPos3.x(),fLastPos3.y());
1680#endif
1681 fSpinningDelay = fLastEventTime->elapsed();
1682 QPoint delta = (fLastPos3-fLastPos1);
1683 if ((delta.x() == 0) && (delta.y() == 0)) {
1684#ifdef GEANT4_QT_DEBUG
1685 printf("G4OpenGLQtViewer::mouseRealease() EXIT 1 \n");
1686#endif
1687 return;
1688 }
1689 if (fSpinningDelay < fLaunchSpinDelay ) {
1690 fAutoMove = true;
1691 QTime lastMoveTime;
1692 lastMoveTime.start();
1693 // try to addapt speed move/rotate looking to drawing speed
1694 int cycles = 4;
1695 while (fAutoMove) {
1696 // if ( lastMoveTime.elapsed() > (fSpinningDelay / (cycles/2))) {
1697 if (fMouseAction == STYLE1) { // rotate
1698 rotateQtScene(((float)delta.x())/cycles,((float)delta.y())/cycles);
1699 } else if (fMouseAction == STYLE2) { // move
1700 moveScene(-((float)delta.x())/cycles,-((float)delta.y())/cycles,0,true);
1701 }
1702 lastMoveTime.start();
1703 cycles = 1 ;
1704 // }
1705 ((QApplication*)G4Qt::getInstance ())->processEvents();
1706#ifdef GEANT4_QT_DEBUG
1707 printf("G4OpenGLQtViewer::mouseRealease() cycle :%d \n",lastMoveTime.elapsed());
1708#endif
1709 cycles ++ ;
1710 }
1711 }
1712}
1713
1714
1715/**
1716 @param pos_x mouse x position
1717 @param pos_y mouse y position
1718 @param mButtons mouse button active
1719 @param mAutoMove true: apply this move till another evnt came, false :one time move
1720*/
1721
1722#if QT_VERSION < 0x040000
1723void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::ButtonState mButtons)
1724#else
1725 void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::MouseButtons mButtons)
1726#endif
1727{
1728
1729 if (fAutoMove) {
1730 return;
1731 }
1732
1733 fLastPos3 = fLastPos2;
1734 fLastPos2 = fLastPos1;
1735 fLastPos1 = QPoint(pos_x, pos_y);
1736
1737 int deltaX = fLastPos2.x()-fLastPos1.x();
1738 int deltaY = fLastPos2.y()-fLastPos1.y();
1739
1740 if (fMouseAction == STYLE1) { // rotate
1741 if (mButtons & Qt::LeftButton) {
1742 rotateQtScene(deltaX,deltaY);
1743 }
1744 } else if (fMouseAction == STYLE2) { // move
1745 if (mButtons & Qt::LeftButton) {
1746 moveScene(-deltaX,-deltaY,0,true);
1747 }
1748 }
1749
1750 fLastEventTime->start();
1751}
1752
1753
1754/**
1755 Move the scene of dx, dy, dz values.
1756 @param dx delta mouse x position
1757 @param dy delta mouse y position
1758 @param mouseMove : true if even comes from a mouse move, false if even comes from key action
1759*/
1760
1761void G4OpenGLQtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
1762{
1763 if (fHoldMoveEvent)
1764 return;
1765 fHoldMoveEvent = true;
1766
1767 G4double coefTrans = 0;
1768 GLdouble coefDepth = 0;
1769 if(mouseMove) {
1770 coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_x);
1771 if (WinSize_y <WinSize_x) {
1772 coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_y);
1773 }
1774 } else {
1775 coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1776 coefDepth = getSceneDepth()*fDeltaDepth;
1777 }
1778 fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1779
1780 updateQWidget();
1781 if (fAutoMove)
1782 ((QApplication*)G4Qt::getInstance ())->processEvents();
1783
1784 fHoldMoveEvent = false;
1785}
1786
1787
1788/**
1789 @param dx delta mouse x position
1790 @param dy delta mouse y position
1791*/
1792
1793void G4OpenGLQtViewer::rotateQtScene(float dx, float dy)
1794{
1795 if (fHoldRotateEvent)
1796 return;
1797 fHoldRotateEvent = true;
1798
1799#ifndef ROTATEGL
1800 rotateScene(dx,0,fDeltaRotation);
1801 rotateScene(0,dy,fDeltaRotation);
1802#else
1803 // fDeltaRotationAngleX = -50*dx*M_PI/180;
1804 // fDeltaRotationAngleY = 50*dy*M_PI/180;
1805 fDeltaRotationAngleX = -50*dx*3.14/180;
1806 fDeltaRotationAngleY = 50*dy*3.14/180;
1807 fRotationAngleZ +=fDeltaRotationAngleZ;
1808 fRotationAngleY +=fDeltaRotationAngleY;
1809 fRotationAngleX +=fDeltaRotationAngleX;
1810#endif
1811 updateQWidget();
1812
1813 fHoldRotateEvent = false;
1814}
1815
1816/**
1817 @param dx delta mouse x position
1818 @param dy delta mouse y position
1819*/
1820
1821void G4OpenGLQtViewer::rotateQtCamera(float dx, float dy)
1822{
1823 if (fHoldRotateEvent)
1824 return;
1825 fHoldRotateEvent = true;
1826
1827 rotateScene(dx,dy,fDeltaRotation);
1828 updateQWidget();
1829
1830 fHoldRotateEvent = false;
1831}
1832
1833
1834
1835
1836/** This is the benning of a rescale function. It does nothing for the moment
1837 @param aWidth : new width
1838 @param aHeight : new height
1839*/
1840void G4OpenGLQtViewer::rescaleImage(
1841 int aWidth
1842,int aHeight
1843){
1844#ifdef GEANT4_QT_DEBUG
1845 printf("should rescale \n");
1846#endif
1847 GLfloat* feedback_buffer;
1848 GLint returned;
1849 FILE* file;
1850
1851// feedback_buffer = new GLfloat[size];
1852// glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1853// glRenderMode (GL_FEEDBACK);
1854
1855// glViewport (0, 0, aWidth, aHeight);
1856// DrawView();
1857// returned = glRenderMode (GL_RENDER);
1858
1859}
1860
1861/**
1862 Generate Vectorial Encapsulated Postscript form image
1863 @param aFilename : name of file
1864 @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1865 @param aImage : Image to print
1866*/
1867bool G4OpenGLQtViewer::generateVectorEPS (
1868 QString aFilename
1869,int aWidth
1870,int aHeight
1871,QImage aImage
1872)
1873{
1874 // Print vectored PostScript
1875
1876 G4int size = 5000000;
1877
1878 GLfloat* feedback_buffer;
1879 GLint returned;
1880 FILE* file;
1881
1882 feedback_buffer = new GLfloat[size];
1883 glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1884 glRenderMode (GL_FEEDBACK);
1885
1886 int side = aWidth;
1887 if (aHeight < aWidth) side = aHeight;
1888 glViewport((aWidth - side) / 2, (aHeight - side) / 2, side, side);
1889 DrawView();
1890
1891 returned = glRenderMode (GL_RENDER);
1892
1893
1894#if QT_VERSION < 0x040000
1895 file = fopen (aFilename.ascii(), "w");
1896#else
1897 file = fopen (aFilename.toStdString().c_str(), "w");
1898#endif
1899 if (file) {
1900 spewWireframeEPS (file, returned, feedback_buffer, "rendereps");
1901 } else {
1902#if QT_VERSION < 0x040000
1903 G4cerr << "Could not open "<< aFilename.ascii() << G4endl;
1904#else
1905 G4cerr << "Could not open "<< aFilename.toStdString().c_str() << G4endl;
1906#endif
1907 }
1908
1909 delete[] feedback_buffer;
1910
1911 return true;
1912}
1913
1914/**
1915 Generate Encapsulated Postscript form image
1916 @param aFilename : name of file
1917 @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1918 @param aImage : Image to print
1919*/
1920bool G4OpenGLQtViewer::generateEPS (
1921 QString aFilename
1922,int aInColor
1923,QImage aImage
1924)
1925{
1926 // FIXME
1927#ifdef GEANT4_QT_DEBUG
1928 printf("saving EPS\n");
1929#endif
1930
1931 FILE* fp;
1932
1933 if (aImage.bits () == NULL)
1934 return false;
1935
1936#if QT_VERSION < 0x040000
1937 fp = fopen (aFilename.ascii(), "w");
1938#else
1939 fp = fopen (aFilename.toStdString().c_str(), "w");
1940#endif
1941 if (fp == NULL) {
1942 return false;
1943 }
1944
1945 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
1946#if QT_VERSION < 0x040000
1947 fprintf (fp, "%%%%Title: %s\n", aFilename.ascii());
1948#else
1949 fprintf (fp, "%%%%Title: %s\n", aFilename.toStdString().c_str());
1950#endif
1951 fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
1952 fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", aImage.width(), aImage.height());
1953 fprintf (fp, "%%%%EndComments\n");
1954 fprintf (fp, "gsave\n");
1955 fprintf (fp, "/bwproc {\n");
1956 fprintf (fp, " rgbproc\n");
1957 fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
1958 fprintf (fp, " 5 -1 roll {\n");
1959 fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
1960 fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
1961 fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
1962 fprintf (fp, " { 2 1 roll } ifelse\n");
1963 fprintf (fp, " }forall\n");
1964 fprintf (fp, " pop pop pop\n");
1965 fprintf (fp, "} def\n");
1966 fprintf (fp, "systemdict /colorimage known not {\n");
1967 fprintf (fp, " /colorimage {\n");
1968 fprintf (fp, " pop\n");
1969 fprintf (fp, " pop\n");
1970 fprintf (fp, " /rgbproc exch def\n");
1971 fprintf (fp, " { bwproc } image\n");
1972 fprintf (fp, " } def\n");
1973 fprintf (fp, "} if\n");
1974 fprintf (fp, "/picstr %d string def\n", aImage.width() * aInColor);
1975 fprintf (fp, "%d %d scale\n", aImage.width(), aImage.height());
1976 fprintf (fp, "%d %d %d\n", aImage.width(), aImage.height(), 8);
1977 fprintf (fp, "[%d 0 0 %d 0 0]\n", aImage.width(), aImage.height());
1978 fprintf (fp, "{currentfile picstr readhexstring pop}\n");
1979 fprintf (fp, "false %d\n", aInColor);
1980 fprintf (fp, "colorimage\n");
1981
1982
1983 int width = aImage.width();
1984 int height = aImage.height();
1985 int depth = aImage.depth();
1986 int size = width*height;
1987
1988 if (depth == 1)
1989 size = (width+7)/8*height;
1990 else if (aInColor == 1)
1991 size = size*3;
1992
1993 int i = 0;
1994 // if ( aInColor ==1 ) {
1995 // FIXME : L. Garnier. For the moment 10 dec 2007, I could not find a way
1996 // to save correctly grayscale Image. I mean that color or grayscale image
1997 // have the same file save size !
1998
1999 /* } else*/ if (depth == 8) {
2000 for(int y=height-1; y >=0 ; y--) {
2001 const uchar * s = aImage.scanLine(y);
2002 for(int x=0; x <width; x++) {
2003 QRgb rgb = aImage.color(s[x]);
2004 if (aInColor == 1) {
2005 fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
2006 i++;
2007 } else {
2008 fprintf (fp, " %02hx %02hx %02hx",
2009 (unsigned char) qRed(rgb),
2010 (unsigned char) qGreen(rgb),
2011 (unsigned char) qBlue(rgb));
2012 i += 3;
2013 }
2014 }
2015 fprintf (fp, "\n");
2016 }
2017 } else {
2018#if QT_VERSION < 0x040000
2019 bool alpha = aImage.hasAlphaBuffer();
2020#else
2021 bool alpha = aImage.hasAlphaChannel();
2022 for(int y=height-1; y >=0 ; y--) {
2023 QRgb * s = (QRgb*)(aImage.scanLine(y));
2024 for(int x=0; x <width; x++) {
2025 QRgb rgb = (*s++);
2026 if (alpha && qAlpha(rgb) < 0x40) // 25% alpha, convert to white -
2027 rgb = qRgb(0xff, 0xff, 0xff);
2028 if (aInColor == 1) {
2029 fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
2030 i++;
2031 } else {
2032 fprintf (fp, " %02hx %02hx %02hx",
2033 (unsigned char) qRed(rgb),
2034 (unsigned char) qGreen(rgb),
2035 (unsigned char) qBlue(rgb));
2036 i += 3;
2037 }
2038 }
2039 fprintf (fp, "\n");
2040 }
2041#endif
2042
2043 }
2044
2045 fprintf (fp, "grestore\n");
2046 fprintf (fp, "showpage\n");
2047 fclose (fp);
2048
2049 return true;
2050}
2051/**
2052 Generate Postscript or PDF form image
2053 @param aFilename : name of file
2054 @param aInColor : numbers of colors : 1->BW 2->RGB
2055 @param aImage : Image to print
2056*/
2057bool G4OpenGLQtViewer::generatePS_PDF (
2058 QString aFilename
2059,int aInColor
2060,QImage aImage
2061)
2062{
2063
2064#if QT_VERSION < 0x040000
2065#ifdef Q_WS_MAC || Q_WS_X11
2066 QPrinter printer;
2067 // printer.setPageSize(pageSize);
2068 if (aInColor == 1) {
2069 printer.setColorMode(QPrinter::GrayScale);
2070 } else {
2071 printer.setColorMode(QPrinter::Color);
2072 }
2073
2074 /* FIXME : I don't know which format it will save...
2075 if (aFilename.endsWith(".ps")) {
2076 printer.setOutputFormat(QPrinter::PostScriptFormat);
2077 } else {
2078 printer.setOutputFormat(QPrinter::PdfFormat);
2079 }
2080 */
2081 printer.setOutputFileName(aFilename);
2082 // printer.setFullPage ( true);
2083 QPainter paint(&printer);
2084 paint.drawImage (0,0,aImage );
2085 paint.end();
2086#else
2087 G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4" << G4endl;
2088#endif
2089#else
2090 QPrinter printer;
2091 // printer.setPageSize(pageSize);
2092
2093 // FIXME : L. Garnier 4/12/07
2094 // This is not working, it does nothing. Image is staying in color mode
2095 // So I have desactivate the B/W button in GUI
2096 if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
2097#if QT_VERSION < 0x040000
2098 aImage = aImage.convertDepth(1,Qt::MonoOnly);
2099#else
2100 aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
2101#endif
2102 }
2103
2104
2105 if (aFilename.endsWith(".ps")) {
2106#if QT_VERSION > 0x040200
2107 printer.setOutputFormat(QPrinter::PostScriptFormat);
2108#endif
2109 } else {
2110#if QT_VERSION > 0x040100
2111 printer.setOutputFormat(QPrinter::PdfFormat);
2112#endif
2113 }
2114#if QT_VERSION > 0x040100
2115 printer.setOutputFileName(aFilename);
2116#endif
2117 // printer.setFullPage ( true);
2118 QPainter paint(&printer);
2119 paint.drawImage (0,0,aImage);
2120 paint.end();
2121#endif
2122 return true;
2123}
2124
2125
2126void G4OpenGLQtViewer::G4wheelEvent (QWheelEvent * event)
2127{
2128 fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
2129 updateQWidget();
2130
2131#ifdef GEANT4_QT_DEBUG
2132 printf("G4OpenGLQtViewer::wheel event +++++++++++++++++++++ %f %d\n",fVP.GetZoomFactor(),event->delta());
2133#endif
2134}
2135
2136
2137void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
2138{
2139 if (fHoldKeyEvent)
2140 return;
2141
2142 fHoldKeyEvent = true;
2143
2144#if QT_VERSION < 0x040000
2145 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
2146#else
2147 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
2148#endif
2149
2150 moveScene(0,0,1,false);
2151 }
2152#if QT_VERSION < 0x040000
2153 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
2154#else
2155 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
2156#endif
2157 moveScene(0,0,-1,false);
2158 }
2159#if QT_VERSION < 0x040000
2160 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
2161#else
2162 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2163#endif
2164 rotateQtCamera(0,-1);
2165 }
2166#if QT_VERSION < 0x040000
2167 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
2168#else
2169 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2170#endif
2171 rotateQtCamera(0,1);
2172 }
2173#if QT_VERSION < 0x040000
2174 if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
2175#else
2176 if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2177#endif
2178 rotateQtCamera(1,0);
2179 }
2180#if QT_VERSION < 0x040000
2181 else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
2182#else
2183 else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2184#endif
2185 rotateQtCamera(-1,0);
2186 }
2187
2188#if QT_VERSION < 0x040000
2189 if ((event->state() & Qt::AltButton)) {
2190#else
2191 if ((event->modifiers() & Qt::AltModifier)) {
2192#endif
2193 if (event->key() == Qt::Key_Plus) {
2194 fDeltaRotation = fDeltaRotation/0.7;
2195 }
2196 else if (event->key() == Qt::Key_Minus) {
2197 fDeltaRotation = fDeltaRotation*0.7;
2198 }
2199 } else {
2200 if (event->key() == Qt::Key_Plus) {
2201 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
2202 updateQWidget();
2203 }
2204 else if (event->key() == Qt::Key_Minus) {
2205 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
2206 updateQWidget();
2207 }
2208 }
2209
2210
2211 if (event->key() == Qt::Key_Escape) { // escaped from full screen
2212#if QT_VERSION >= 0x030200
2213 toggleFullScreen(false);
2214#endif
2215 }
2216 // several case here : If return is pressed, in every case -> display the movie parameters dialog
2217 // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
2218 // If encoder not found-> does nothing.Only display a message in status box
2219 // If all ok-> generate parameter file
2220 // If ok -> put encoder button enabled
2221
2222 if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
2223 stopVideo();
2224 }
2225 if (event->key() == Qt::Key_Space){ // start/pause of video
2226 startPauseVideo();
2227 }
2228
2229 // with no modifiers
2230#if QT_VERSION < 0x040000
2231 if (event->state() == Qt::NoButton) {
2232#else
2233 if ((event->modifiers() == Qt::NoModifier) || (event->modifiers() == Qt::KeypadModifier )) {
2234#endif
2235 if (event->key() == Qt::Key_Down) { // go down
2236 moveScene(0,1,0,false);
2237 }
2238 else if (event->key() == Qt::Key_Up) { // go up
2239 moveScene(0,-1,0,false);
2240 }
2241 if (event->key() == Qt::Key_Left) { // go left
2242 moveScene(-1,0,0,false);
2243 }
2244 else if (event->key() == Qt::Key_Right) { // go right
2245 moveScene(1,0,0,false);
2246 }
2247 }
2248 fHoldKeyEvent = false;
2249}
2250
2251
2252/** Stop the video. Check all parameters and enable encoder button if all is ok.
2253*/
2254void G4OpenGLQtViewer::stopVideo() {
2255
2256 // if encoder parameter is wrong, display parameters dialog and return
2257 if (!fMovieParametersDialog) {
2258 showMovieParametersDialog();
2259 }
2260 setRecordingStatus(STOP);
2261
2262 if (fRecordFrameNumber >0) {
2263 // check parameters if they were modified (Re APPLY them...)
2264 // It will enable/disable encode button
2265 fMovieParametersDialog->checkAllParameters();
2266 } else {
2267 resetRecording();
2268 setRecordingInfos("No frame to encode.");
2269 }
2270}
2271
2272
2273/** Start/Pause the video..
2274*/
2275void G4OpenGLQtViewer::startPauseVideo() {
2276
2277 // first time, if temp parameter is wrong, display parameters dialog and return
2278 if ( fRecordingStep == WAIT) {
2279 if ( fRecordFrameNumber == 0) {
2280 if (getTempFolderPath() == "") {
2281 showMovieParametersDialog();
2282 setRecordingInfos("You should specified the temp folder in order to make movie");
2283 return;
2284 } else {
2285 // remove temp folder if it was create
2286 QString tmp = removeTempFolder();
2287 if (tmp !="") {
2288 setRecordingInfos(tmp);
2289 return;
2290 }
2291 tmp = createTempFolder();
2292 if (tmp != "") {
2293 setRecordingInfos("Can't create temp folder."+tmp);
2294 return;
2295 }
2296 }
2297 }
2298 }
2299 if (fRecordingStep == WAIT) {
2300 setRecordingStatus(START);
2301 } else if (fRecordingStep == START) {
2302 setRecordingStatus(PAUSE);
2303 } else if (fRecordingStep == PAUSE) {
2304 setRecordingStatus(CONTINUE);
2305 } else if (fRecordingStep == CONTINUE) {
2306 setRecordingStatus(PAUSE);
2307 }
2308}
2309
2310
2311void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
2312
2313 fRecordingStep = step;
2314 displayRecordingStatus();
2315}
2316
2317
2318void G4OpenGLQtViewer::displayRecordingStatus() {
2319
2320 QString txt = "";
2321 if (fRecordingStep == WAIT) {
2322 txt = "Waiting to start...";
2323 fRecordFrameNumber = 0; // reset the frame number
2324 } else if (fRecordingStep == START) {
2325 txt = "Start Recording...";
2326 } else if (fRecordingStep == PAUSE) {
2327 txt = "Pause Recording...";
2328 } else if (fRecordingStep == CONTINUE) {
2329 txt = "Continue Recording...";
2330 } else if (fRecordingStep == STOP) {
2331 txt = "Stop Recording...";
2332 } else if (fRecordingStep == READY_TO_ENCODE) {
2333 txt = "Ready to Encode...";
2334 } else if (fRecordingStep == ENCODING) {
2335 txt = "Encoding...";
2336 } else if (fRecordingStep == FAILED) {
2337 txt = "Failed to encode...";
2338 } else if (fRecordingStep == SUCCESS) {
2339 txt = "File encoded successfully";
2340 } else {
2341 }
2342
2343 if (fMovieParametersDialog) {
2344 fMovieParametersDialog->setRecordingStatus(txt);
2345 } else {
2346#if QT_VERSION < 0x040000
2347 G4cout << txt.ascii() << G4endl;
2348#else
2349 G4cout << txt.toStdString().c_str() << G4endl;
2350#endif
2351 }
2352 setRecordingInfos("");
2353}
2354
2355
2356void G4OpenGLQtViewer::setRecordingInfos(QString txt) {
2357 if (fMovieParametersDialog) {
2358 fMovieParametersDialog->setRecordingInfos(txt);
2359 } else {
2360#if QT_VERSION < 0x040000
2361 G4cout << txt.ascii() << G4endl;
2362#else
2363 G4cout << txt.toStdString().c_str() << G4endl;
2364#endif
2365 }
2366}
2367
2368/** Init the movie parameters. Temp dir and encoder path
2369*/
2370void G4OpenGLQtViewer::initMovieParameters() {
2371 //init encoder
2372
2373 //look for encoderPath
2374 fProcess = new QProcess();
2375
2376#if QT_VERSION < 0x040000
2377 QObject ::connect(fProcess,SIGNAL(processExited ()),
2378 this,SLOT(processLookForFinished()));
2379 fProcess->setCommunication(QProcess::DupStderr);
2380 fProcess->setArguments(QStringList("which mpeg_encode"));
2381 fProcess->start();
2382#else
2383 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2384 this,SLOT(processLookForFinished()));
2385 fProcess->setReadChannelMode(QProcess::MergedChannels);
2386 fProcess->start ("which mpeg_encode");
2387#endif
2388
2389}
2390
2391/** @return encoder path or "" if it does not exist
2392 */
2393QString G4OpenGLQtViewer::getEncoderPath() {
2394 return fEncoderPath;
2395}
2396
2397
2398/**
2399 * set the new encoder path
2400 * @return "" if correct. The error otherwise
2401*/
2402QString G4OpenGLQtViewer::setEncoderPath(QString path) {
2403 if (path == "") {
2404 return "File does not exist";
2405 }
2406
2407#if QT_VERSION < 0x040000
2408 path = QDir::cleanDirPath(path);
2409#else
2410 path = QDir::cleanPath(path);
2411#endif
2412 QFileInfo *f = new QFileInfo(path);
2413 if (!f->exists()) {
2414 return "File does not exist";
2415 } else if (f->isDir()) {
2416 return "This is a directory";
2417 } else if (!f->isExecutable()) {
2418 return "File exist but is not executable";
2419 } else if (!f->isFile()) {
2420 return "This is not a file";
2421 }
2422 fEncoderPath = path;
2423 return "";
2424}
2425
2426
2427bool G4OpenGLQtViewer::isRecording(){
2428 if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
2429 return true;
2430 }
2431 return false;
2432}
2433
2434bool G4OpenGLQtViewer::isStopped(){
2435 if (fRecordingStep == STOP) {
2436 return true;
2437 }
2438 return false;
2439}
2440
2441
2442bool G4OpenGLQtViewer::isReadyToEncode(){
2443 if (fRecordingStep == READY_TO_ENCODE) {
2444 return true;
2445 }
2446 return false;
2447}
2448
2449void G4OpenGLQtViewer::resetRecording() {
2450 setRecordingStatus(WAIT);
2451}
2452
2453/**
2454 * set the temp folder path
2455 * @return "" if correct. The error otherwise
2456*/
2457QString G4OpenGLQtViewer::setTempFolderPath(QString path) {
2458
2459 if (path == "") {
2460 return "Path does not exist";
2461 }
2462#if QT_VERSION < 0x040000
2463 path = QDir::cleanDirPath(path);
2464#else
2465 path = QDir::cleanPath(path);
2466#endif
2467 QFileInfo *d = new QFileInfo(path);
2468 if (!d->exists()) {
2469 return "Path does not exist";
2470 } else if (!d->isDir()) {
2471 return "This is not a directory";
2472 } else if (!d->isReadable()) {
2473 return path +" is read protected";
2474 } else if (!d->isWritable()) {
2475 return path +" is write protected";
2476 }
2477
2478 fTempFolderPath = path;
2479 return "";
2480}
2481
2482/** @return the temp folder path or "" if it does not exist
2483 */
2484QString G4OpenGLQtViewer::getTempFolderPath() {
2485 return fTempFolderPath;
2486}
2487
2488/**
2489 * set the save file name path
2490 * @return "" if correct. The error otherwise
2491*/
2492QString G4OpenGLQtViewer::setSaveFileName(QString path) {
2493
2494 if (path == "") {
2495 return "Path does not exist";
2496 }
2497
2498 QFileInfo *file = new QFileInfo(path);
2499 QDir dir = file->dir();
2500#if QT_VERSION < 0x040000
2501 path = QDir::cleanDirPath(path);
2502#else
2503 path = QDir::cleanPath(path);
2504#endif
2505 if (file->exists()) {
2506 return "File already exist, please choose a new one";
2507 } else if (!dir.exists()) {
2508 return "Dir does not exist";
2509 } else if (!dir.isReadable()) {
2510 return path +" is read protected";
2511 }
2512
2513 fSaveFileName = path;
2514 return "";
2515}
2516
2517/** @return the save file path
2518 */
2519QString G4OpenGLQtViewer::getSaveFileName() {
2520 return fSaveFileName ;
2521}
2522
2523/** Create a Qt_temp folder in the temp folder given
2524* The temp folder will be like this /tmp/QtMovie_12-02-2008_12_12_58/
2525* @return "" if success. Error message if not.
2526*/
2527QString G4OpenGLQtViewer::createTempFolder() {
2528 fMovieTempFolderPath = "";
2529
2530 //check
2531 QString tmp = setTempFolderPath(fTempFolderPath);
2532 if (tmp != "") {
2533 return tmp;
2534 }
2535#if QT_VERSION < 0x040000
2536 QString sep = QChar(QDir::separator());
2537#else
2538 QString sep = QString(QDir::separator());
2539#endif
2540 QString path = sep+"QtMovie_"+QDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
2541#if QT_VERSION < 0x040000
2542 QDir *d = new QDir(QDir::cleanDirPath(fTempFolderPath));
2543#else
2544 QDir *d = new QDir(QDir::cleanPath(fTempFolderPath));
2545#endif
2546 // check if it is already present
2547 if (d->exists(path)) {
2548 return "Folder "+path+" already exists.Please remove it first";
2549 }
2550 if (d->mkdir(fTempFolderPath+path)) {
2551 fMovieTempFolderPath = fTempFolderPath+path;
2552 return "";
2553 } else {
2554 return "Can't create "+fTempFolderPath+path;
2555 }
2556 return "-";
2557}
2558
2559/** Remove the Qt_temp folder in the temp folder
2560*/
2561QString G4OpenGLQtViewer::removeTempFolder() {
2562 // remove files in Qt_temp folder
2563 if (fMovieTempFolderPath == "") {
2564 return "";
2565 }
2566#if QT_VERSION < 0x040000
2567 QDir *d = new QDir(QDir::cleanDirPath(fMovieTempFolderPath));
2568#else
2569 QDir *d = new QDir(QDir::cleanPath(fMovieTempFolderPath));
2570#endif
2571 if (!d->exists()) {
2572 return ""; // already remove
2573 }
2574
2575 d->setFilter( QDir::Files );
2576 QStringList subDirList = d->entryList();
2577 int res = true;
2578 QString error = "";
2579 for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2580 const QString currentFile = *it;
2581 if (!d->remove(currentFile)) {
2582 res = false;
2583 QString file = fMovieTempFolderPath+currentFile;
2584 error +="Removing file failed : "+file;
2585 } else {
2586 }
2587 }
2588 if (res) {
2589 if (d->rmdir(fMovieTempFolderPath)) {
2590 fMovieTempFolderPath = "";
2591 return "";
2592 } else {
2593 return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
2594 }
2595
2596 }
2597 return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
2598}
2599
2600
2601
2602bool G4OpenGLQtViewer::hasPendingEvents () {
2603 return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2604}
2605
2606bool G4OpenGLQtViewer::generateMpegEncoderParameters () {
2607
2608 // save the parameter file
2609 FILE* fp;
2610#if QT_VERSION < 0x040000
2611 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).ascii(), "w");
2612#else
2613 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(), "w");
2614#endif
2615
2616 if (fp == NULL) {
2617 setRecordingInfos("Generation of parameter file failed");
2618 return false;
2619 }
2620
2621 fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2622 fprintf (fp,"#\n");
2623 fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2624 fprintf (fp,"# the copy\n");
2625 fprintf (fp,"#\n");
2626 fprintf (fp,"#\n");
2627 fprintf (fp,"# any line beginning with '#' is a comment\n");
2628 fprintf (fp,"#\n");
2629 fprintf (fp,"# no line should be longer than 255 characters\n");
2630 fprintf (fp,"#\n");
2631 fprintf (fp,"#\n");
2632 fprintf (fp,"# general format of each line is:\n");
2633 fprintf (fp,"# \n");
2634 fprintf (fp,"#\n");
2635 fprintf (fp,"# lines can generally be in any order\n");
2636 fprintf (fp,"#\n");
2637 fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2638 fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2639 fprintf (fp,"#\n");
2640 fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2641 fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2642 fprintf (fp,"# the INPUT parameter.\n");
2643 fprintf (fp,"#\n");
2644 fprintf (fp,"# MUST be in UPPER CASE\n");
2645 fprintf (fp,"#\n");
2646 fprintf (fp,"\n");
2647 fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2648 fprintf (fp,"# for more info.\n");
2649 fprintf (fp,"\n");
2650 fprintf (fp,"PATTERN IBBPBBPBBPBBPBBP\n");
2651#if QT_VERSION < 0x040000
2652 fprintf (fp,"OUTPUT %s\n",getSaveFileName().ascii());
2653#else
2654 fprintf (fp,"OUTPUT %s\n",getSaveFileName().toStdString().c_str());
2655#endif
2656 fprintf (fp,"\n");
2657 fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2658 fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2659 fprintf (fp,"#\n");
2660 fprintf (fp,"# You must specify the type of the input files. The choices are:\n");
2661 fprintf (fp,"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2662 fprintf (fp,"# (must be upper case)\n");
2663 fprintf (fp,"#\n");
2664 fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2665 fprintf (fp,"\n");
2666 fprintf (fp,"#\n");
2667 fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2668 fprintf (fp,"# YUV_SIZE widthxheight\n");
2669 fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2670 fprintf (fp,"# on just one machine\n");
2671 fprintf (fp,"#\n");
2672 fprintf (fp,"YUV_SIZE 352x240\n");
2673 fprintf (fp,"\n");
2674 fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2675 fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2676 fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2677 fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2678 fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2679 fprintf (fp,"# to specify the file order.\n");
2680 fprintf (fp,"\n");
2681 fprintf (fp,"INPUT_FORMAT UCB\n");
2682 fprintf (fp,"\n");
2683 fprintf (fp,"# the conversion statement\n");
2684 fprintf (fp,"#\n");
2685 fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2686 fprintf (fp,"#\n");
2687 fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2688 fprintf (fp,"# INPUT_CONVERT giftoppm *\n");
2689 fprintf (fp,"#\n");
2690 fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2691 fprintf (fp,"# INPUT_CONVERT cat *.Y *.U *.V\n");
2692 fprintf (fp,"#\n");
2693 fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2694 fprintf (fp,"# INPUT_CONVERT goto frame *; grabppm\n");
2695 fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2696 fprintf (fp,"#\n");
2697 fprintf (fp,"INPUT_CONVERT * \n");
2698 fprintf (fp,"\n");
2699 fprintf (fp,"# number of frames in a GOP.\n");
2700 fprintf (fp,"#\n");
2701 fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2702 fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2703 fprintf (fp,"#\n");
2704 fprintf (fp,"# later, will add more flexible GOP signalling\n");
2705 fprintf (fp,"#\n");
2706 fprintf (fp,"GOP_SIZE 16\n");
2707 fprintf (fp,"\n");
2708 fprintf (fp,"# number of slices in a frame\n");
2709 fprintf (fp,"#\n");
2710 fprintf (fp,"# 1 is a good number. another possibility is the number of macroblock rows\n");
2711 fprintf (fp,"# (which is the height divided by 16)\n");
2712 fprintf (fp,"#\n");
2713 fprintf (fp,"SLICES_PER_FRAME 1\n");
2714 fprintf (fp,"\n");
2715 fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2716#if QT_VERSION < 0x040000
2717 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.ascii());
2718#else
2719 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.toStdString().c_str());
2720#endif
2721 fprintf (fp,"\n");
2722 fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2723 fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2724 fprintf (fp,"# way of numbering them. See the manual for more information.\n");
2725 fprintf (fp,"INPUT\n");
2726 fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2727 fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2728 fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2729 fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2730 fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2731 fprintf (fp,"# if you do, too bad!!!\n");
2732 fprintf (fp,"#\n");
2733 fprintf (fp,"#\n");
2734 fprintf (fp,"Test*.ppm [0-%d]\n",fRecordFrameNumber-1);
2735 fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2736 fprintf (fp,"# of files\n");
2737 fprintf (fp,"END_INPUT\n");
2738 fprintf (fp,"\n");
2739 fprintf (fp,"\n");
2740 fprintf (fp,"\n");
2741 fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2742 fprintf (fp,"\n");
2743 fprintf (fp,"# FULL or HALF -- must be upper case\n");
2744 fprintf (fp,"# Should be FULL for computer generated images\n");
2745 fprintf (fp,"PIXEL FULL\n");
2746 fprintf (fp,"\n");
2747 fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2748 fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2749 fprintf (fp,"RANGE 10\n");
2750 fprintf (fp,"\n");
2751 fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2752 fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2753 fprintf (fp,"\n");
2754 fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2755 fprintf (fp,"PSEARCH_ALG LOGARITHMIC\n");
2756 fprintf (fp,"\n");
2757 fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2758 fprintf (fp,"#\n");
2759 fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2760 fprintf (fp,"#\n");
2761 fprintf (fp,"BSEARCH_ALG SIMPLE\n");
2762 fprintf (fp,"\n");
2763 fprintf (fp,"#\n");
2764 fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2765 fprintf (fp,"# (values must be between 1 and 31)\n");
2766 fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2767 fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2768 fprintf (fp,"#\n");
2769 fprintf (fp,"\n");
2770 fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2771 fprintf (fp,"# but has very little effect on speed.\n");
2772 fprintf (fp,"\n");
2773 fprintf (fp,"IQSCALE 4\n");
2774 fprintf (fp,"PQSCALE 5\n");
2775 fprintf (fp,"BQSCALE 12\n");
2776 fprintf (fp,"\n");
2777 fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2778 fprintf (fp,"REFERENCE_FRAME ORIGINAL\n");
2779 fprintf (fp,"\n");
2780 fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2781 fprintf (fp,"\n");
2782 fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2783 fprintf (fp,"#BIT_RATE 1000000\n");
2784 fprintf (fp,"\n");
2785 fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2786 fprintf (fp,"BUFFER_SIZE 327680\n");
2787 fprintf (fp,"\n");
2788 fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2789 fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2790 fprintf (fp,"FRAME_RATE 30\n");
2791 fprintf (fp,"\n");
2792 fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2793 fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2794 fprintf (fp,"\n");
2795 fprintf (fp,"\n");
2796 fclose (fp);
2797
2798 setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2799 setRecordingStatus(READY_TO_ENCODE);
2800 return true;
2801}
2802
2803void G4OpenGLQtViewer::encodeVideo()
2804{
2805 if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2806 setRecordingStatus(ENCODING);
2807
2808#if QT_VERSION < 0x040000
2809 QStringList args = QStringList(fEncoderPath);
2810 args.push_back(fMovieTempFolderPath+fParameterFileName);
2811 fProcess = new QProcess(args);
2812 QObject ::connect(fProcess,SIGNAL(processExited ()),
2813 this,SLOT(processEncodeFinished()));
2814 QObject ::connect(fProcess,SIGNAL(readyReadStdout ()),
2815 this,SLOT(processEncodeStdout()));
2816 fProcess->setCommunication(QProcess::DupStderr);
2817 fProcess->launch("");
2818#else
2819 fProcess = new QProcess();
2820#if QT_VERSION > 0x040100
2821 QObject ::connect(fProcess,SIGNAL(finished ( int,QProcess::ExitStatus)),
2822 this,SLOT(processEncodeFinished()));
2823 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2824 this,SLOT(processEncodeStdout()));
2825#else
2826 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2827 this,SLOT(processEncodeFinished()));
2828 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2829 this,SLOT(processEncodeStdout()));
2830#endif
2831 fProcess->setReadChannelMode(QProcess::MergedChannels);
2832 fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2833#endif
2834 }
2835}
2836
2837
2838// FIXME : does not work on Qt3
2839void G4OpenGLQtViewer::processEncodeStdout()
2840{
2841#if QT_VERSION > 0x040000
2842 QString tmp = fProcess->readAllStandardOutput ().data();
2843 int start = tmp.lastIndexOf("ESTIMATED TIME");
2844 tmp = tmp.mid(start,tmp.indexOf("\n",start)-start);
2845#else
2846 QString tmp = fProcess->readStdout ().data();
2847 int start = tmp.findRev("ESTIMATED TIME");
2848 tmp = tmp.mid(start,tmp.find("\n",start)-start);
2849#endif
2850 setRecordingInfos(tmp);
2851}
2852
2853
2854void G4OpenGLQtViewer::processEncodeFinished()
2855{
2856
2857 QString txt = "";
2858 txt = getProcessErrorMsg();
2859 if (txt == "") {
2860 setRecordingStatus(SUCCESS);
2861 } else {
2862 setRecordingStatus(FAILED);
2863 }
2864 setRecordingInfos(txt+removeTempFolder());
2865}
2866
2867
2868void G4OpenGLQtViewer::processLookForFinished()
2869 {
2870
2871 QString txt = getProcessErrorMsg();
2872 if (txt != "") {
2873 fEncoderPath = "";
2874 } else {
2875#if QT_VERSION > 0x040000
2876 fEncoderPath = QString(fProcess->readAllStandardOutput ().data()).trimmed();
2877#else
2878 fEncoderPath = QString(fProcess->readStdout ().data()).simplifyWhiteSpace();
2879#endif
2880 // if not found, return "not found"
2881 if (fEncoderPath.contains(" ")) {
2882 fEncoderPath = "";
2883 } else if (!fEncoderPath.contains("mpeg_encode")) {
2884 fEncoderPath = "";
2885 }
2886 setEncoderPath(fEncoderPath);
2887 }
2888 // init temp folder
2889#if QT_VERSION > 0x040000
2890 setTempFolderPath(QDir::temp ().absolutePath ());
2891#else
2892 // Let's have a try
2893 setTempFolderPath("/tmp/");
2894#endif
2895}
2896
2897
2898QString G4OpenGLQtViewer::getProcessErrorMsg()
2899{
2900 QString txt = "";
2901#if QT_VERSION < 0x040000
2902 if (!fProcess->normalExit ()) {
2903 txt = "Exist status "+ fProcess->exitStatus ();
2904 }
2905#else
2906 if (fProcess->exitCode() != 0) {
2907 switch (fProcess->error()) {
2908 case QProcess::FailedToStart:
2909 txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2910 break;
2911 case QProcess::Crashed:
2912 txt = "The process crashed some time after starting successfully.\n";
2913 break;
2914 case QProcess::Timedout:
2915 txt = "The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2916 break;
2917 case QProcess::WriteError:
2918 txt = "An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel.\n";
2919 break;
2920 case QProcess::ReadError:
2921 txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2922 break;
2923 case QProcess::UnknownError:
2924 txt = "An unknown error occurred. This is the default return value of error().\n";
2925 break;
2926 }
2927 }
2928#endif
2929 return txt;
2930}
2931
2932/*
2933
2934void MultiLayer::exportToSVG(const QString& fname)
2935{
2936 QPicture picture;
2937 QPainter p(&picture);
2938 for (int i=0;i<(int)graphsList->count();i++)
2939 {
2940 Graph *gr=(Graph *)graphsList->at(i);
2941 Plot *myPlot= (Plot *)gr->plotWidget();
2942
2943 QPoint pos=gr->pos();
2944
2945 int width=int(myPlot->frameGeometry().width());
2946 int height=int(myPlot->frameGeometry().height());
2947
2948 myPlot->print(&p, QRect(pos,QSize(width,height)));
2949 }
2950
2951 p.end();
2952 picture.save(fname, "svg");
2953}
2954*/
2955#endif
Note: See TracBrowser for help on using the repository browser.