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

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

last updates

  • Property svn:mime-type set to text/cpp
File size: 84.5 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: $
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* interactorManager = 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("&Movie parameters...","&Make movie ...",CTRL+Key_M,mActions,0,true);
692#else
693 QAction *movieParameters = new QAction("&Movie parameters...",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 if (getEncoderPath() == "") {
1489 setRecordingInfos("mpeg_encode is needed to encode in video format. It is available here: http://bmrc.berkeley.edu/frame/research/mpeg/");
1490 }
1491 }
1492 fMovieParametersDialog->show();
1493}
1494
1495
1496/*
1497// 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
1498
1499void Graph::exportToSVG(const QString& fname)
1500{
1501 // enable workaround for Qt3 misalignments
1502 QwtPainter::setSVGMode(true);
1503 QPicture picture;
1504 QPainter p(&picture);
1505 d_plot->print(&p, d_plot->rect());
1506 p.end();
1507
1508 picture.save(fname, "svg");
1509}
1510*/
1511
1512
1513
1514
1515/**
1516 Save the current mouse press point
1517 @param p mouse click point
1518*/
1519#if QT_VERSION < 0x040000
1520void G4OpenGLQtViewer::G4MousePressEvent(QPoint p)
1521#else
1522void G4OpenGLQtViewer::G4MousePressEvent(QPoint p)
1523#endif
1524{
1525 fAutoMove = false; // stop automove
1526 fLastPos1 = p;
1527 fLastPos2 = fLastPos1;
1528 fLastPos3 = fLastPos2;
1529 fLastEventTime->start();
1530 if (fMouseAction == STYLE2){ // pick
1531 Pick(p.x(),p.y());
1532 }
1533}
1534
1535/**
1536*/
1537void G4OpenGLQtViewer::G4MouseReleaseEvent()
1538{
1539#ifdef GEANT4_QT_DEBUG
1540 printf("G4OpenGLQtViewer::mouseRealease() %d,%d %d,%d %d,%d\n",fLastPos1.x(),fLastPos1.y(),fLastPos2.x(),fLastPos2.y(),fLastPos3.x(),fLastPos3.y());
1541#endif
1542 fSpinningDelay = fLastEventTime->elapsed();
1543 QPoint delta = (fLastPos3-fLastPos1);
1544 if ((delta.x() == 0) && (delta.y() == 0)) {
1545#ifdef GEANT4_QT_DEBUG
1546 printf("G4OpenGLQtViewer::mouseRealease() EXIT 1 \n");
1547#endif
1548 return;
1549 }
1550 if (fSpinningDelay < fLaunchSpinDelay ) {
1551 fAutoMove = true;
1552 QTime lastMoveTime;
1553 lastMoveTime.start();
1554 // try to addapt speed move/rotate looking to drawing speed
1555 int cycles = 4;
1556 while (fAutoMove) {
1557 // if ( lastMoveTime.elapsed() > (fSpinningDelay / (cycles/2))) {
1558 if (fMouseAction == STYLE1) { // rotate
1559 rotateQtScene(((float)delta.x())/cycles,((float)delta.y())/cycles);
1560 } else if (fMouseAction == STYLE2) { // move
1561 moveScene(-((float)delta.x())/cycles,-((float)delta.y())/cycles,0,true);
1562 }
1563 lastMoveTime.start();
1564 cycles = 1 ;
1565 // }
1566 ((QApplication*)G4Qt::getInstance ())->processEvents();
1567#ifdef GEANT4_QT_DEBUG
1568 printf("G4OpenGLQtViewer::mouseRealease() cycle :%d \n",lastMoveTime.elapsed());
1569#endif
1570 cycles ++ ;
1571 }
1572 }
1573}
1574
1575
1576/**
1577 @param pos_x mouse x position
1578 @param pos_y mouse y position
1579 @param mButtons mouse button active
1580 @param mAutoMove true: apply this move till another evnt came, false :one time move
1581*/
1582
1583#if QT_VERSION < 0x040000
1584void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::ButtonState mButtons)
1585#else
1586 void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::MouseButtons mButtons)
1587#endif
1588{
1589
1590 if (fAutoMove) {
1591 return;
1592 }
1593
1594 fLastPos3 = fLastPos2;
1595 fLastPos2 = fLastPos1;
1596 fLastPos1 = QPoint(pos_x, pos_y);
1597
1598 int deltaX = fLastPos2.x()-fLastPos1.x();
1599 int deltaY = fLastPos2.y()-fLastPos1.y();
1600
1601 if (fMouseAction == STYLE1) { // rotate
1602 if (mButtons & Qt::LeftButton) {
1603 rotateQtScene(deltaX,deltaY);
1604 }
1605 } else if (fMouseAction == STYLE2) { // move
1606 if (mButtons & Qt::LeftButton) {
1607 moveScene(-deltaX,-deltaY,0,true);
1608 }
1609 }
1610
1611 fLastEventTime->start();
1612}
1613
1614
1615/**
1616 Move the scene of dx, dy, dz values.
1617 @param dx delta mouse x position
1618 @param dy delta mouse y position
1619 @param mouseMove : true if even comes from a mouse move, false if even comes from key action
1620*/
1621
1622void G4OpenGLQtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
1623{
1624 if (fHoldMoveEvent)
1625 return;
1626 fHoldMoveEvent = true;
1627
1628 G4double coefTrans = 0;
1629 GLdouble coefDepth = 0;
1630 if(mouseMove) {
1631 coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_x);
1632 if (WinSize_y <WinSize_x) {
1633 coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_y);
1634 }
1635 } else {
1636 coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1637 coefDepth = getSceneDepth()*fDeltaDepth;
1638 }
1639 fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1640 emit moveX(-dx*coefTrans);
1641 emit moveY(dy*coefTrans);
1642 emit moveZ(dz*coefTrans);
1643
1644 updateQWidget();
1645 if (fAutoMove)
1646 ((QApplication*)G4Qt::getInstance ())->processEvents();
1647
1648 fHoldMoveEvent = false;
1649}
1650
1651
1652/**
1653 @param dx delta mouse x position
1654 @param dy delta mouse y position
1655*/
1656
1657void G4OpenGLQtViewer::rotateQtScene(float dx, float dy)
1658{
1659 if (fHoldRotateEvent)
1660 return;
1661 fHoldRotateEvent = true;
1662
1663 if( dx != 0) {
1664 rotateScene(dx,0,fDeltaRotation);
1665 emit rotateTheta(dx);
1666 }
1667 if( dy != 0) {
1668 rotateScene(0,dy,fDeltaRotation);
1669 emit rotatePhi(dy);
1670 }
1671 updateQWidget();
1672
1673 fHoldRotateEvent = false;
1674}
1675
1676/**
1677 @param dx delta mouse x position
1678 @param dy delta mouse y position
1679*/
1680
1681void G4OpenGLQtViewer::rotateQtCamera(float dx, float dy)
1682{
1683 if (fHoldRotateEvent)
1684 return;
1685 fHoldRotateEvent = true;
1686
1687 rotateScene(dx,dy,fDeltaRotation);
1688 emit rotateTheta(dx);
1689 emit rotatePhi(dy);
1690 updateQWidget();
1691
1692 fHoldRotateEvent = false;
1693}
1694
1695
1696
1697
1698/** This is the benning of a rescale function. It does nothing for the moment
1699 @param aWidth : new width
1700 @param aHeight : new height
1701*/
1702void G4OpenGLQtViewer::rescaleImage(
1703 int aWidth
1704,int aHeight
1705){
1706#ifdef GEANT4_QT_DEBUG
1707 printf("should rescale \n");
1708#endif
1709 GLfloat* feedback_buffer;
1710 GLint returned;
1711 FILE* file;
1712
1713// feedback_buffer = new GLfloat[size];
1714// glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1715// glRenderMode (GL_FEEDBACK);
1716
1717// glViewport (0, 0, aWidth, aHeight);
1718// DrawView();
1719// returned = glRenderMode (GL_RENDER);
1720
1721}
1722
1723/**
1724 Generate Vectorial Encapsulated Postscript form image
1725 @param aFilename : name of file
1726 @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1727 @param aImage : Image to print
1728*/
1729bool G4OpenGLQtViewer::generateVectorEPS (
1730 QString aFilename
1731,int aWidth
1732,int aHeight
1733,QImage aImage
1734)
1735{
1736 // Print vectored PostScript
1737
1738 G4int size = 5000000;
1739
1740 GLfloat* feedback_buffer;
1741 GLint returned;
1742 FILE* file;
1743
1744 feedback_buffer = new GLfloat[size];
1745 glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1746 glRenderMode (GL_FEEDBACK);
1747
1748 int side = aWidth;
1749 if (aHeight < aWidth) side = aHeight;
1750 glViewport((aWidth - side) / 2, (aHeight - side) / 2, side, side);
1751 DrawView();
1752
1753 returned = glRenderMode (GL_RENDER);
1754
1755
1756#if QT_VERSION < 0x040000
1757 file = fopen (aFilename.ascii(), "w");
1758#else
1759 file = fopen (aFilename.toStdString().c_str(), "w");
1760#endif
1761 if (file) {
1762 spewWireframeEPS (file, returned, feedback_buffer, "rendereps");
1763 } else {
1764#if QT_VERSION < 0x040000
1765 G4cerr << "Could not open "<< aFilename.ascii() << G4endl;
1766#else
1767 G4cerr << "Could not open "<< aFilename.toStdString().c_str() << G4endl;
1768#endif
1769 }
1770
1771 delete[] feedback_buffer;
1772
1773 return true;
1774}
1775
1776/**
1777 Generate Encapsulated Postscript form image
1778 @param aFilename : name of file
1779 @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1780 @param aImage : Image to print
1781*/
1782bool G4OpenGLQtViewer::generateEPS (
1783 QString aFilename
1784,int aInColor
1785,QImage aImage
1786)
1787{
1788 // FIXME
1789#ifdef GEANT4_QT_DEBUG
1790 printf("saving EPS\n");
1791#endif
1792
1793 FILE* fp;
1794
1795 if (aImage.bits () == NULL)
1796 return false;
1797
1798#if QT_VERSION < 0x040000
1799 fp = fopen (aFilename.ascii(), "w");
1800#else
1801 fp = fopen (aFilename.toStdString().c_str(), "w");
1802#endif
1803 if (fp == NULL) {
1804 return false;
1805 }
1806
1807 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
1808#if QT_VERSION < 0x040000
1809 fprintf (fp, "%%%%Title: %s\n", aFilename.ascii());
1810#else
1811 fprintf (fp, "%%%%Title: %s\n", aFilename.toStdString().c_str());
1812#endif
1813 fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
1814 fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", aImage.width(), aImage.height());
1815 fprintf (fp, "%%%%EndComments\n");
1816 fprintf (fp, "gsave\n");
1817 fprintf (fp, "/bwproc {\n");
1818 fprintf (fp, " rgbproc\n");
1819 fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
1820 fprintf (fp, " 5 -1 roll {\n");
1821 fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
1822 fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
1823 fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
1824 fprintf (fp, " { 2 1 roll } ifelse\n");
1825 fprintf (fp, " }forall\n");
1826 fprintf (fp, " pop pop pop\n");
1827 fprintf (fp, "} def\n");
1828 fprintf (fp, "systemdict /colorimage known not {\n");
1829 fprintf (fp, " /colorimage {\n");
1830 fprintf (fp, " pop\n");
1831 fprintf (fp, " pop\n");
1832 fprintf (fp, " /rgbproc exch def\n");
1833 fprintf (fp, " { bwproc } image\n");
1834 fprintf (fp, " } def\n");
1835 fprintf (fp, "} if\n");
1836 fprintf (fp, "/picstr %d string def\n", aImage.width() * aInColor);
1837 fprintf (fp, "%d %d scale\n", aImage.width(), aImage.height());
1838 fprintf (fp, "%d %d %d\n", aImage.width(), aImage.height(), 8);
1839 fprintf (fp, "[%d 0 0 %d 0 0]\n", aImage.width(), aImage.height());
1840 fprintf (fp, "{currentfile picstr readhexstring pop}\n");
1841 fprintf (fp, "false %d\n", aInColor);
1842 fprintf (fp, "colorimage\n");
1843
1844
1845 int width = aImage.width();
1846 int height = aImage.height();
1847 int depth = aImage.depth();
1848 int size = width*height;
1849
1850 if (depth == 1)
1851 size = (width+7)/8*height;
1852 else if (aInColor == 1)
1853 size = size*3;
1854
1855 int i = 0;
1856 // if ( aInColor ==1 ) {
1857 // FIXME : L. Garnier. For the moment 10 dec 2007, I could not find a way
1858 // to save correctly grayscale Image. I mean that color or grayscale image
1859 // have the same file save size !
1860
1861 /* } else*/ if (depth == 8) {
1862 for(int y=height-1; y >=0 ; y--) {
1863 const uchar * s = aImage.scanLine(y);
1864 for(int x=0; x <width; x++) {
1865 QRgb rgb = aImage.color(s[x]);
1866 if (aInColor == 1) {
1867 fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1868 i++;
1869 } else {
1870 fprintf (fp, " %02hx %02hx %02hx",
1871 (unsigned char) qRed(rgb),
1872 (unsigned char) qGreen(rgb),
1873 (unsigned char) qBlue(rgb));
1874 i += 3;
1875 }
1876 }
1877 fprintf (fp, "\n");
1878 }
1879 } else {
1880#if QT_VERSION < 0x040000
1881 bool alpha = aImage.hasAlphaBuffer();
1882#else
1883 bool alpha = aImage.hasAlphaChannel();
1884 for(int y=height-1; y >=0 ; y--) {
1885 QRgb * s = (QRgb*)(aImage.scanLine(y));
1886 for(int x=0; x <width; x++) {
1887 QRgb rgb = (*s++);
1888 if (alpha && qAlpha(rgb) < 0x40) // 25% alpha, convert to white -
1889 rgb = qRgb(0xff, 0xff, 0xff);
1890 if (aInColor == 1) {
1891 fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1892 i++;
1893 } else {
1894 fprintf (fp, " %02hx %02hx %02hx",
1895 (unsigned char) qRed(rgb),
1896 (unsigned char) qGreen(rgb),
1897 (unsigned char) qBlue(rgb));
1898 i += 3;
1899 }
1900 }
1901 fprintf (fp, "\n");
1902 }
1903#endif
1904
1905 }
1906
1907 fprintf (fp, "grestore\n");
1908 fprintf (fp, "showpage\n");
1909 fclose (fp);
1910
1911 return true;
1912}
1913/**
1914 Generate Postscript or PDF form image
1915 @param aFilename : name of file
1916 @param aInColor : numbers of colors : 1->BW 2->RGB
1917 @param aImage : Image to print
1918*/
1919bool G4OpenGLQtViewer::generatePS_PDF (
1920 QString aFilename
1921,int aInColor
1922,QImage aImage
1923)
1924{
1925
1926#if QT_VERSION < 0x040000
1927#ifdef Q_WS_MAC || Q_WS_X11
1928 QPrinter printer;
1929 // printer.setPageSize(pageSize);
1930 if (aInColor == 1) {
1931 printer.setColorMode(QPrinter::GrayScale);
1932 } else {
1933 printer.setColorMode(QPrinter::Color);
1934 }
1935
1936 /* FIXME : I don't know which format it will save...
1937 if (aFilename.endsWith(".ps")) {
1938 printer.setOutputFormat(QPrinter::PostScriptFormat);
1939 } else {
1940 printer.setOutputFormat(QPrinter::PdfFormat);
1941 }
1942 */
1943 printer.setOutputFileName(aFilename);
1944 // printer.setFullPage ( true);
1945 QPainter paint(&printer);
1946 paint.drawImage (0,0,aImage );
1947 paint.end();
1948#else
1949 G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4" << G4endl;
1950#endif
1951#else
1952 QPrinter printer;
1953 // printer.setPageSize(pageSize);
1954
1955 // FIXME : L. Garnier 4/12/07
1956 // This is not working, it does nothing. Image is staying in color mode
1957 // So I have desactivate the B/W button in GUI
1958 if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1959#if QT_VERSION < 0x040000
1960 aImage = aImage.convertDepth(1,Qt::MonoOnly);
1961#else
1962 aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
1963#endif
1964 }
1965
1966
1967 if (aFilename.endsWith(".ps")) {
1968#if QT_VERSION > 0x040200
1969 printer.setOutputFormat(QPrinter::PostScriptFormat);
1970#endif
1971 } else {
1972#if QT_VERSION > 0x040100
1973 printer.setOutputFormat(QPrinter::PdfFormat);
1974#endif
1975 }
1976#if QT_VERSION > 0x040100
1977 printer.setOutputFileName(aFilename);
1978#endif
1979 // printer.setFullPage ( true);
1980 QPainter paint(&printer);
1981 paint.drawImage (0,0,aImage);
1982 paint.end();
1983#endif
1984 return true;
1985}
1986
1987
1988void G4OpenGLQtViewer::G4wheelEvent (QWheelEvent * event)
1989{
1990 fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1991 updateQWidget();
1992
1993#ifdef GEANT4_QT_DEBUG
1994 printf("G4OpenGLQtViewer::wheel event +++++++++++++++++++++ %f %d\n",fVP.GetZoomFactor(),event->delta());
1995#endif
1996}
1997
1998
1999void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
2000{
2001 if (fHoldKeyEvent)
2002 return;
2003
2004 fHoldKeyEvent = true;
2005
2006#if QT_VERSION < 0x040000
2007 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
2008#else
2009 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
2010#endif
2011
2012 moveScene(0,0,1,false);
2013 }
2014#if QT_VERSION < 0x040000
2015 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
2016#else
2017 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
2018#endif
2019 moveScene(0,0,-1,false);
2020 }
2021#if QT_VERSION < 0x040000
2022 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
2023#else
2024 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2025#endif
2026 rotateQtCamera(0,-1);
2027 }
2028#if QT_VERSION < 0x040000
2029 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
2030#else
2031 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2032#endif
2033 rotateQtCamera(0,1);
2034 }
2035#if QT_VERSION < 0x040000
2036 if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
2037#else
2038 if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2039#endif
2040 rotateQtCamera(1,0);
2041 }
2042#if QT_VERSION < 0x040000
2043 else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
2044#else
2045 else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2046#endif
2047 rotateQtCamera(-1,0);
2048 }
2049
2050#if QT_VERSION < 0x040000
2051 if ((event->state() & Qt::AltButton)) {
2052#else
2053 if ((event->modifiers() & Qt::AltModifier)) {
2054#endif
2055 if (event->key() == Qt::Key_Plus) {
2056 fDeltaRotation = fDeltaRotation/0.7;
2057 }
2058 else if (event->key() == Qt::Key_Minus) {
2059 fDeltaRotation = fDeltaRotation*0.7;
2060 }
2061 } else {
2062 if (event->key() == Qt::Key_Plus) {
2063 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
2064 updateQWidget();
2065 }
2066 else if (event->key() == Qt::Key_Minus) {
2067 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
2068 updateQWidget();
2069 }
2070 }
2071
2072
2073 if (event->key() == Qt::Key_Escape) { // escaped from full screen
2074#if QT_VERSION >= 0x030200
2075 toggleFullScreen(false);
2076#endif
2077 }
2078 // several case here : If return is pressed, in every case -> display the movie parameters dialog
2079 // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
2080 // If encoder not found-> does nothing.Only display a message in status box
2081 // If all ok-> generate parameter file
2082 // If ok -> put encoder button enabled
2083
2084 if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
2085 stopVideo();
2086 }
2087 if (event->key() == Qt::Key_Space){ // start/pause of video
2088 startPauseVideo();
2089 }
2090
2091 // with no modifiers
2092#if QT_VERSION < 0x040000
2093 if (event->state() == Qt::NoButton) {
2094#else
2095 if ((event->modifiers() == Qt::NoModifier) || (event->modifiers() == Qt::KeypadModifier )) {
2096#endif
2097 if (event->key() == Qt::Key_Down) { // go down
2098 moveScene(0,1,0,false);
2099 }
2100 else if (event->key() == Qt::Key_Up) { // go up
2101 moveScene(0,-1,0,false);
2102 }
2103 if (event->key() == Qt::Key_Left) { // go left
2104 moveScene(-1,0,0,false);
2105 }
2106 else if (event->key() == Qt::Key_Right) { // go right
2107 moveScene(1,0,0,false);
2108 }
2109 }
2110 fHoldKeyEvent = false;
2111}
2112
2113
2114/** Stop the video. Check all parameters and enable encoder button if all is ok.
2115*/
2116void G4OpenGLQtViewer::stopVideo() {
2117
2118 // if encoder parameter is wrong, display parameters dialog and return
2119 if (!fMovieParametersDialog) {
2120 showMovieParametersDialog();
2121 }
2122 setRecordingStatus(STOP);
2123
2124 if (fRecordFrameNumber >0) {
2125 // check parameters if they were modified (Re APPLY them...)
2126 // It will enable/disable encode button
2127 fMovieParametersDialog->checkAllParameters();
2128 } else {
2129 resetRecording();
2130 setRecordingInfos("No frame to encode.");
2131 }
2132}
2133
2134
2135/** Start/Pause the video..
2136*/
2137void G4OpenGLQtViewer::startPauseVideo() {
2138
2139 // first time, if temp parameter is wrong, display parameters dialog and return
2140 if ( fRecordingStep == WAIT) {
2141 if ( fRecordFrameNumber == 0) {
2142 if (getTempFolderPath() == "") {
2143 showMovieParametersDialog();
2144 setRecordingInfos("You should specified the temp folder in order to make movie");
2145 return;
2146 } else {
2147 // remove temp folder if it was create
2148 QString tmp = removeTempFolder();
2149 if (tmp !="") {
2150 setRecordingInfos(tmp);
2151 return;
2152 }
2153 tmp = createTempFolder();
2154 if (tmp != "") {
2155 setRecordingInfos("Can't create temp folder."+tmp);
2156 return;
2157 }
2158 }
2159 }
2160 }
2161 if (fRecordingStep == WAIT) {
2162 setRecordingStatus(START);
2163 } else if (fRecordingStep == START) {
2164 setRecordingStatus(PAUSE);
2165 } else if (fRecordingStep == PAUSE) {
2166 setRecordingStatus(CONTINUE);
2167 } else if (fRecordingStep == CONTINUE) {
2168 setRecordingStatus(PAUSE);
2169 }
2170}
2171
2172
2173void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
2174
2175 fRecordingStep = step;
2176 displayRecordingStatus();
2177}
2178
2179
2180void G4OpenGLQtViewer::displayRecordingStatus() {
2181
2182 QString txt = "";
2183 if (fRecordingStep == WAIT) {
2184 txt = "Waiting to start...";
2185 fRecordFrameNumber = 0; // reset the frame number
2186 } else if (fRecordingStep == START) {
2187 txt = "Start Recording...";
2188 } else if (fRecordingStep == PAUSE) {
2189 txt = "Pause Recording...";
2190 } else if (fRecordingStep == CONTINUE) {
2191 txt = "Continue Recording...";
2192 } else if (fRecordingStep == STOP) {
2193 txt = "Stop Recording...";
2194 } else if (fRecordingStep == READY_TO_ENCODE) {
2195 txt = "Ready to Encode...";
2196 } else if (fRecordingStep == ENCODING) {
2197 txt = "Encoding...";
2198 } else if (fRecordingStep == FAILED) {
2199 txt = "Failed to encode...";
2200 } else if (fRecordingStep == SUCCESS) {
2201 txt = "File encoded successfully";
2202 } else {
2203 }
2204
2205 if (fMovieParametersDialog) {
2206 fMovieParametersDialog->setRecordingStatus(txt);
2207 } else {
2208#if QT_VERSION < 0x040000
2209 G4cout << txt.ascii() << G4endl;
2210#else
2211 G4cout << txt.toStdString().c_str() << G4endl;
2212#endif
2213 }
2214 setRecordingInfos("");
2215}
2216
2217
2218void G4OpenGLQtViewer::setRecordingInfos(QString txt) {
2219 if (fMovieParametersDialog) {
2220 fMovieParametersDialog->setRecordingInfos(txt);
2221 } else {
2222#if QT_VERSION < 0x040000
2223 G4cout << txt.ascii() << G4endl;
2224#else
2225 G4cout << txt.toStdString().c_str() << G4endl;
2226#endif
2227 }
2228}
2229
2230/** Init the movie parameters. Temp dir and encoder path
2231*/
2232void G4OpenGLQtViewer::initMovieParameters() {
2233 //init encoder
2234
2235 //look for encoderPath
2236 fProcess = new QProcess();
2237
2238#if QT_VERSION < 0x040000
2239 QObject ::connect(fProcess,SIGNAL(processExited ()),
2240 this,SLOT(processLookForFinished()));
2241 fProcess->setCommunication(QProcess::DupStderr);
2242 fProcess->setArguments(QStringList("which mpeg_encode"));
2243 fProcess->start();
2244#else
2245 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2246 this,SLOT(processLookForFinished()));
2247 fProcess->setReadChannelMode(QProcess::MergedChannels);
2248 fProcess->start ("which mpeg_encode");
2249#endif
2250
2251}
2252
2253/** @return encoder path or "" if it does not exist
2254 */
2255QString G4OpenGLQtViewer::getEncoderPath() {
2256 return fEncoderPath;
2257}
2258
2259
2260/**
2261 * set the new encoder path
2262 * @return "" if correct. The error otherwise
2263*/
2264QString G4OpenGLQtViewer::setEncoderPath(QString path) {
2265 if (path == "") {
2266 return "File does not exist";
2267 }
2268
2269#if QT_VERSION < 0x040000
2270 path = QDir::cleanDirPath(path);
2271#else
2272 path = QDir::cleanPath(path);
2273#endif
2274 QFileInfo *f = new QFileInfo(path);
2275 if (!f->exists()) {
2276 return "File does not exist";
2277 } else if (f->isDir()) {
2278 return "This is a directory";
2279 } else if (!f->isExecutable()) {
2280 return "File exist but is not executable";
2281 } else if (!f->isFile()) {
2282 return "This is not a file";
2283 }
2284 fEncoderPath = path;
2285 return "";
2286}
2287
2288
2289bool G4OpenGLQtViewer::isRecording(){
2290 if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
2291 return true;
2292 }
2293 return false;
2294}
2295
2296bool G4OpenGLQtViewer::isStopped(){
2297 if (fRecordingStep == STOP) {
2298 return true;
2299 }
2300 return false;
2301}
2302
2303
2304bool G4OpenGLQtViewer::isReadyToEncode(){
2305 if (fRecordingStep == READY_TO_ENCODE) {
2306 return true;
2307 }
2308 return false;
2309}
2310
2311void G4OpenGLQtViewer::resetRecording() {
2312 setRecordingStatus(WAIT);
2313}
2314
2315/**
2316 * set the temp folder path
2317 * @return "" if correct. The error otherwise
2318*/
2319QString G4OpenGLQtViewer::setTempFolderPath(QString path) {
2320
2321 if (path == "") {
2322 return "Path does not exist";
2323 }
2324#if QT_VERSION < 0x040000
2325 path = QDir::cleanDirPath(path);
2326#else
2327 path = QDir::cleanPath(path);
2328#endif
2329 QFileInfo *d = new QFileInfo(path);
2330 if (!d->exists()) {
2331 return "Path does not exist";
2332 } else if (!d->isDir()) {
2333 return "This is not a directory";
2334 } else if (!d->isReadable()) {
2335 return path +" is read protected";
2336 } else if (!d->isWritable()) {
2337 return path +" is write protected";
2338 }
2339
2340 fTempFolderPath = path;
2341 return "";
2342}
2343
2344/** @return the temp folder path or "" if it does not exist
2345 */
2346QString G4OpenGLQtViewer::getTempFolderPath() {
2347 return fTempFolderPath;
2348}
2349
2350/**
2351 * set the save file name path
2352 * @return "" if correct. The error otherwise
2353*/
2354QString G4OpenGLQtViewer::setSaveFileName(QString path) {
2355
2356 if (path == "") {
2357 return "Path does not exist";
2358 }
2359
2360 QFileInfo *file = new QFileInfo(path);
2361 QDir dir = file->dir();
2362#if QT_VERSION < 0x040000
2363 path = QDir::cleanDirPath(path);
2364#else
2365 path = QDir::cleanPath(path);
2366#endif
2367 if (file->exists()) {
2368 return "File already exist, please choose a new one";
2369 } else if (!dir.exists()) {
2370 return "Dir does not exist";
2371 } else if (!dir.isReadable()) {
2372 return path +" is read protected";
2373 }
2374
2375 fSaveFileName = path;
2376 return "";
2377}
2378
2379/** @return the save file path
2380 */
2381QString G4OpenGLQtViewer::getSaveFileName() {
2382 return fSaveFileName ;
2383}
2384
2385/** Create a Qt_temp folder in the temp folder given
2386* The temp folder will be like this /tmp/QtMovie_12-02-2008_12_12_58/
2387* @return "" if success. Error message if not.
2388*/
2389QString G4OpenGLQtViewer::createTempFolder() {
2390 fMovieTempFolderPath = "";
2391
2392 //check
2393 QString tmp = setTempFolderPath(fTempFolderPath);
2394 if (tmp != "") {
2395 return tmp;
2396 }
2397#if QT_VERSION < 0x040000
2398 QString sep = QChar(QDir::separator());
2399#else
2400 QString sep = QString(QDir::separator());
2401#endif
2402 QString path = sep+"QtMovie_"+QDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
2403#if QT_VERSION < 0x040000
2404 QDir *d = new QDir(QDir::cleanDirPath(fTempFolderPath));
2405#else
2406 QDir *d = new QDir(QDir::cleanPath(fTempFolderPath));
2407#endif
2408 // check if it is already present
2409 if (d->exists(path)) {
2410 return "Folder "+path+" already exists.Please remove it first";
2411 }
2412 if (d->mkdir(fTempFolderPath+path)) {
2413 fMovieTempFolderPath = fTempFolderPath+path;
2414 return "";
2415 } else {
2416 return "Can't create "+fTempFolderPath+path;
2417 }
2418 return "-";
2419}
2420
2421/** Remove the Qt_temp folder in the temp folder
2422*/
2423QString G4OpenGLQtViewer::removeTempFolder() {
2424 // remove files in Qt_temp folder
2425 if (fMovieTempFolderPath == "") {
2426 return "";
2427 }
2428#if QT_VERSION < 0x040000
2429 QDir *d = new QDir(QDir::cleanDirPath(fMovieTempFolderPath));
2430#else
2431 QDir *d = new QDir(QDir::cleanPath(fMovieTempFolderPath));
2432#endif
2433 if (!d->exists()) {
2434 return ""; // already remove
2435 }
2436
2437 d->setFilter( QDir::Files );
2438 QStringList subDirList = d->entryList();
2439 int res = true;
2440 QString error = "";
2441 for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2442 const QString currentFile = *it;
2443 if (!d->remove(currentFile)) {
2444 res = false;
2445 QString file = fMovieTempFolderPath+currentFile;
2446 error +="Removing file failed : "+file;
2447 } else {
2448 }
2449 }
2450 if (res) {
2451 if (d->rmdir(fMovieTempFolderPath)) {
2452 fMovieTempFolderPath = "";
2453 return "";
2454 } else {
2455 return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
2456 }
2457
2458 }
2459 return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
2460}
2461
2462
2463
2464bool G4OpenGLQtViewer::hasPendingEvents () {
2465 return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2466}
2467
2468bool G4OpenGLQtViewer::generateMpegEncoderParameters () {
2469
2470 // save the parameter file
2471 FILE* fp;
2472#if QT_VERSION < 0x040000
2473 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).ascii(), "w");
2474#else
2475 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(), "w");
2476#endif
2477
2478 if (fp == NULL) {
2479 setRecordingInfos("Generation of parameter file failed");
2480 return false;
2481 }
2482
2483 fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2484 fprintf (fp,"#\n");
2485 fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2486 fprintf (fp,"# the copy\n");
2487 fprintf (fp,"#\n");
2488 fprintf (fp,"#\n");
2489 fprintf (fp,"# any line beginning with '#' is a comment\n");
2490 fprintf (fp,"#\n");
2491 fprintf (fp,"# no line should be longer than 255 characters\n");
2492 fprintf (fp,"#\n");
2493 fprintf (fp,"#\n");
2494 fprintf (fp,"# general format of each line is:\n");
2495 fprintf (fp,"# \n");
2496 fprintf (fp,"#\n");
2497 fprintf (fp,"# lines can generally be in any order\n");
2498 fprintf (fp,"#\n");
2499 fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2500 fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2501 fprintf (fp,"#\n");
2502 fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2503 fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2504 fprintf (fp,"# the INPUT parameter.\n");
2505 fprintf (fp,"#\n");
2506 fprintf (fp,"# MUST be in UPPER CASE\n");
2507 fprintf (fp,"#\n");
2508 fprintf (fp,"\n");
2509 fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2510 fprintf (fp,"# for more info.\n");
2511 fprintf (fp,"\n");
2512 fprintf (fp,"PATTERN IBBPBBPBBPBBPBBP\n");
2513#if QT_VERSION < 0x040000
2514 fprintf (fp,"OUTPUT %s\n",getSaveFileName().ascii());
2515#else
2516 fprintf (fp,"OUTPUT %s\n",getSaveFileName().toStdString().c_str());
2517#endif
2518 fprintf (fp,"\n");
2519 fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2520 fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2521 fprintf (fp,"#\n");
2522 fprintf (fp,"# You must specify the type of the input files. The choices are:\n");
2523 fprintf (fp,"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2524 fprintf (fp,"# (must be upper case)\n");
2525 fprintf (fp,"#\n");
2526 fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2527 fprintf (fp,"\n");
2528 fprintf (fp,"#\n");
2529 fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2530 fprintf (fp,"# YUV_SIZE widthxheight\n");
2531 fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2532 fprintf (fp,"# on just one machine\n");
2533 fprintf (fp,"#\n");
2534 fprintf (fp,"YUV_SIZE 352x240\n");
2535 fprintf (fp,"\n");
2536 fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2537 fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2538 fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2539 fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2540 fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2541 fprintf (fp,"# to specify the file order.\n");
2542 fprintf (fp,"\n");
2543 fprintf (fp,"INPUT_FORMAT UCB\n");
2544 fprintf (fp,"\n");
2545 fprintf (fp,"# the conversion statement\n");
2546 fprintf (fp,"#\n");
2547 fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2548 fprintf (fp,"#\n");
2549 fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2550 fprintf (fp,"# INPUT_CONVERT giftoppm *\n");
2551 fprintf (fp,"#\n");
2552 fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2553 fprintf (fp,"# INPUT_CONVERT cat *.Y *.U *.V\n");
2554 fprintf (fp,"#\n");
2555 fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2556 fprintf (fp,"# INPUT_CONVERT goto frame *; grabppm\n");
2557 fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2558 fprintf (fp,"#\n");
2559 fprintf (fp,"INPUT_CONVERT * \n");
2560 fprintf (fp,"\n");
2561 fprintf (fp,"# number of frames in a GOP.\n");
2562 fprintf (fp,"#\n");
2563 fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2564 fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2565 fprintf (fp,"#\n");
2566 fprintf (fp,"# later, will add more flexible GOP signalling\n");
2567 fprintf (fp,"#\n");
2568 fprintf (fp,"GOP_SIZE 16\n");
2569 fprintf (fp,"\n");
2570 fprintf (fp,"# number of slices in a frame\n");
2571 fprintf (fp,"#\n");
2572 fprintf (fp,"# 1 is a good number. another possibility is the number of macroblock rows\n");
2573 fprintf (fp,"# (which is the height divided by 16)\n");
2574 fprintf (fp,"#\n");
2575 fprintf (fp,"SLICES_PER_FRAME 1\n");
2576 fprintf (fp,"\n");
2577 fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2578#if QT_VERSION < 0x040000
2579 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.ascii());
2580#else
2581 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.toStdString().c_str());
2582#endif
2583 fprintf (fp,"\n");
2584 fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2585 fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2586 fprintf (fp,"# way of numbering them. See the manual for more information.\n");
2587 fprintf (fp,"INPUT\n");
2588 fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2589 fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2590 fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2591 fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2592 fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2593 fprintf (fp,"# if you do, too bad!!!\n");
2594 fprintf (fp,"#\n");
2595 fprintf (fp,"#\n");
2596 fprintf (fp,"Test*.ppm [0-%d]\n",fRecordFrameNumber-1);
2597 fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2598 fprintf (fp,"# of files\n");
2599 fprintf (fp,"END_INPUT\n");
2600 fprintf (fp,"\n");
2601 fprintf (fp,"\n");
2602 fprintf (fp,"\n");
2603 fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2604 fprintf (fp,"\n");
2605 fprintf (fp,"# FULL or HALF -- must be upper case\n");
2606 fprintf (fp,"# Should be FULL for computer generated images\n");
2607 fprintf (fp,"PIXEL FULL\n");
2608 fprintf (fp,"\n");
2609 fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2610 fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2611 fprintf (fp,"RANGE 10\n");
2612 fprintf (fp,"\n");
2613 fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2614 fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2615 fprintf (fp,"\n");
2616 fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2617 fprintf (fp,"PSEARCH_ALG LOGARITHMIC\n");
2618 fprintf (fp,"\n");
2619 fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2620 fprintf (fp,"#\n");
2621 fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2622 fprintf (fp,"#\n");
2623 fprintf (fp,"BSEARCH_ALG SIMPLE\n");
2624 fprintf (fp,"\n");
2625 fprintf (fp,"#\n");
2626 fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2627 fprintf (fp,"# (values must be between 1 and 31)\n");
2628 fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2629 fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2630 fprintf (fp,"#\n");
2631 fprintf (fp,"\n");
2632 fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2633 fprintf (fp,"# but has very little effect on speed.\n");
2634 fprintf (fp,"\n");
2635 fprintf (fp,"IQSCALE 4\n");
2636 fprintf (fp,"PQSCALE 5\n");
2637 fprintf (fp,"BQSCALE 12\n");
2638 fprintf (fp,"\n");
2639 fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2640 fprintf (fp,"REFERENCE_FRAME ORIGINAL\n");
2641 fprintf (fp,"\n");
2642 fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2643 fprintf (fp,"\n");
2644 fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2645 fprintf (fp,"#BIT_RATE 1000000\n");
2646 fprintf (fp,"\n");
2647 fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2648 fprintf (fp,"BUFFER_SIZE 327680\n");
2649 fprintf (fp,"\n");
2650 fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2651 fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2652 fprintf (fp,"FRAME_RATE 30\n");
2653 fprintf (fp,"\n");
2654 fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2655 fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2656 fprintf (fp,"\n");
2657 fprintf (fp,"\n");
2658 fclose (fp);
2659
2660 setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2661 setRecordingStatus(READY_TO_ENCODE);
2662 return true;
2663}
2664
2665void G4OpenGLQtViewer::encodeVideo()
2666{
2667 if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2668 setRecordingStatus(ENCODING);
2669
2670#if QT_VERSION < 0x040000
2671 QStringList args = QStringList(fEncoderPath);
2672 args.push_back(fMovieTempFolderPath+fParameterFileName);
2673 fProcess = new QProcess(args);
2674 QObject ::connect(fProcess,SIGNAL(processExited ()),
2675 this,SLOT(processEncodeFinished()));
2676 QObject ::connect(fProcess,SIGNAL(readyReadStdout ()),
2677 this,SLOT(processEncodeStdout()));
2678 fProcess->setCommunication(QProcess::DupStderr);
2679 fProcess->launch("");
2680#else
2681 fProcess = new QProcess();
2682#if QT_VERSION > 0x040100
2683 QObject ::connect(fProcess,SIGNAL(finished ( int,QProcess::ExitStatus)),
2684 this,SLOT(processEncodeFinished()));
2685 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2686 this,SLOT(processEncodeStdout()));
2687#else
2688 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2689 this,SLOT(processEncodeFinished()));
2690 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2691 this,SLOT(processEncodeStdout()));
2692#endif
2693 fProcess->setReadChannelMode(QProcess::MergedChannels);
2694 fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2695#endif
2696 }
2697}
2698
2699
2700// FIXME : does not work on Qt3
2701void G4OpenGLQtViewer::processEncodeStdout()
2702{
2703#if QT_VERSION > 0x040000
2704 QString tmp = fProcess->readAllStandardOutput ().data();
2705 int start = tmp.lastIndexOf("ESTIMATED TIME");
2706 tmp = tmp.mid(start,tmp.indexOf("\n",start)-start);
2707#else
2708 QString tmp = fProcess->readStdout ().data();
2709 int start = tmp.findRev("ESTIMATED TIME");
2710 tmp = tmp.mid(start,tmp.find("\n",start)-start);
2711#endif
2712 setRecordingInfos(tmp);
2713}
2714
2715
2716void G4OpenGLQtViewer::processEncodeFinished()
2717{
2718
2719 QString txt = "";
2720 txt = getProcessErrorMsg();
2721 if (txt == "") {
2722 setRecordingStatus(SUCCESS);
2723 } else {
2724 setRecordingStatus(FAILED);
2725 }
2726 setRecordingInfos(txt+removeTempFolder());
2727}
2728
2729
2730void G4OpenGLQtViewer::processLookForFinished()
2731 {
2732
2733 QString txt = getProcessErrorMsg();
2734 if (txt != "") {
2735 fEncoderPath = "";
2736 } else {
2737#if QT_VERSION > 0x040000
2738 fEncoderPath = QString(fProcess->readAllStandardOutput ().data()).trimmed();
2739#else
2740 fEncoderPath = QString(fProcess->readStdout ().data()).simplifyWhiteSpace();
2741#endif
2742 // if not found, return "not found"
2743 if (fEncoderPath.contains(" ")) {
2744 fEncoderPath = "";
2745 } else if (!fEncoderPath.contains("mpeg_encode")) {
2746 fEncoderPath = "";
2747 }
2748 setEncoderPath(fEncoderPath);
2749 }
2750 // init temp folder
2751#if QT_VERSION > 0x040000
2752 setTempFolderPath(QDir::temp ().absolutePath ());
2753#else
2754 // Let's have a try
2755 setTempFolderPath("/tmp/");
2756#endif
2757}
2758
2759
2760QString G4OpenGLQtViewer::getProcessErrorMsg()
2761{
2762 QString txt = "";
2763#if QT_VERSION < 0x040000
2764 if (!fProcess->normalExit ()) {
2765 txt = "Exist status "+ fProcess->exitStatus ();
2766 }
2767#else
2768 if (fProcess->exitCode() != 0) {
2769 switch (fProcess->error()) {
2770 case QProcess::FailedToStart:
2771 txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2772 break;
2773 case QProcess::Crashed:
2774 txt = "The process crashed some time after starting successfully.\n";
2775 break;
2776 case QProcess::Timedout:
2777 txt = "The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2778 break;
2779 case QProcess::WriteError:
2780 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";
2781 break;
2782 case QProcess::ReadError:
2783 txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2784 break;
2785 case QProcess::UnknownError:
2786 txt = "An unknown error occurred. This is the default return value of error().\n";
2787 break;
2788 }
2789 }
2790#endif
2791 return txt;
2792}
2793
2794/*
2795
2796void MultiLayer::exportToSVG(const QString& fname)
2797{
2798 QPicture picture;
2799 QPainter p(&picture);
2800 for (int i=0;i<(int)graphsList->count();i++)
2801 {
2802 Graph *gr=(Graph *)graphsList->at(i);
2803 Plot *myPlot= (Plot *)gr->plotWidget();
2804
2805 QPoint pos=gr->pos();
2806
2807 int width=int(myPlot->frameGeometry().width());
2808 int height=int(myPlot->frameGeometry().height());
2809
2810 myPlot->print(&p, QRect(pos,QSize(width,height)));
2811 }
2812
2813 p.end();
2814 picture.save(fname, "svg");
2815}
2816*/
2817#endif
Note: See TracBrowser for help on using the repository browser.