source: trunk/geant4/visualization/OpenGL/src/G4OpenGLQtViewer.cc@ 781

Last change on this file since 781 was 778, checked in by garnier, 18 years ago

r793@wl-72126: garnier | 2008-04-21 11:30:15 +0200
mise a jour

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