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

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

on bloque si l encoder est un dir+le status est mis a jour des le debut

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