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

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

r818@wl-72126: garnier | 2008-04-30 12:42:00 +0200
modif mise a jour sur le cvs

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