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

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

r844@wl-72126: garnier | 2008-05-20 19:09:54 +0200
retour a la case depart

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