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

Last change on this file since 864 was 863, checked in by garnier, 17 years ago

add picking for Qt

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