Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4OpenGLWtViewer.cc
Go to the documentation of this file.
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$
28//
29//
30// G4OpenGLWtViewer : Class to provide Wt specific
31// functionality for OpenGL in GEANT4
32//
33// 27/06/2003 : G.Barrand : implementation (at last !).
34
35#ifdef G4VIS_BUILD_OPENGLWT_DRIVER
36
37#include "G4OpenGLWtViewer.hh"
38#include "G4VViewer.hh"
39#include "G4VSceneHandler.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 "G4OpenGLWtExportDialog.hh"
50//#include "G4OpenGLWtMovieDialog.hh"
51#include "G4UnitsTable.hh"
52#include "G4Wt.hh"
53#include "G4UIWt.hh"
54#include "G4UImanager.hh"
55#include "G4UIcommandTree.hh"
56
57#include <WT/WHBoxLayout>
58#include <WT/WApplication>
59
60
61
62
63//////////////////////////////////////////////////////////////////////////////
64/**
65 Implementation of virtual method of G4VViewer
66*/
67void G4OpenGLWtViewer::SetView (
68)
69//////////////////////////////////////////////////////////////////////////////
70//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
71{
72 G4OpenGLViewer::SetView ();
73}
74
75
76
77
78//////////////////////////////////////////////////////////////////////////////
79void G4OpenGLWtViewer::CreateMainWindow (
80 Wt::WGLWidget* glWidget
81 ,Wt::WString name
82)
83//////////////////////////////////////////////////////////////////////////////
84//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
85{
86#ifdef G4DEBUG_VIS_OGL
87 printf("G4OpenGLWtViewer::CreateMainWindow \n");
88#endif
89
90 if(fWindow) return; //Done.
91
92 fWindow = glWidget ;
93 // fWindow->makeCurrent();
94
95 //G4Wt* interactorManager = G4Wt::getInstance ();
96
97 ResizeWindow(fVP.GetWindowSizeHintX(),fVP.GetWindowSizeHintY());
98
99 // FIXME L.Garnier 9/11/09 Has to be check !!!
100 // Wt UI with Wt Vis
101 // Wt UI with X Vis
102 // X UI with Wt Vis
103 // X UI with X Vis
104 // Ne marche pas avec un UIBatch !! (ecran blanc)
105
106 // return false if G4UIWt was not launch
107
108 fGLWindow = fWindow;
109 // FIXME:: fGLWindow->resize(getWinWidth(), getWinHeight());
110
111 if(!fWindow) return;
112
113#ifdef _A_FINIR_FIXME
114 if (!fContextMenu)
115 createPopupMenu();
116#endif
117
118 // FIXME:: updateWWidget();
119
120}
121
122/** Close the dialog and set the pointer to NULL
123 */
124// void G4OpenGLWtViewer::dialogClosed() {
125// // fGLWindow = NULL;
126// }
127
128//////////////////////////////////////////////////////////////////////////////
129G4OpenGLWtViewer::G4OpenGLWtViewer (
130 G4OpenGLSceneHandler& scene
131 )
132 :G4VViewer (scene, -1)
133 ,G4OpenGLViewer (scene)
134 ,fWindow(0)
135 ,fRecordFrameNumber(0)
136 //#ifdef _A_FINIR_FIXME ,fContextMenu(0)
137 ,fMouseAction(STYLE1)
138 ,fDeltaRotation(1)
139 ,fDeltaSceneTranslation(0.01)
140 ,fDeltaDepth(0.01)
141 ,fDeltaZoom(0.05)
142 ,fDeltaMove(0.05)
143 ,fHoldKeyEvent(false)
144 ,fHoldMoveEvent(false)
145 ,fHoldRotateEvent(false)
146 ,fAutoMove(false)
147 ,fEncoderPath("")
148 ,fTempFolderPath("")
149 ,fMovieTempFolderPath("")
150 ,fSaveFileName("")
151 ,fParameterFileName("mpeg_encode_parameter_file.par")
152 ,fMovieParametersDialog(NULL)
153 ,fRecordingStep(WAIT)
154 ,fProcess(NULL)
155 ,fNbMaxFramesPerSec(100)
156 ,fNbMaxAnglePerSec(360)
157 ,fLaunchSpinDelay(100)
158 ,fXRot(0)
159 ,fYRot(0)
160 ,fNoKeyPress(true)
161 ,fAltKeyPress(false)
162 ,fControlKeyPress(false)
163 ,fShiftKeyPress(false)
164{
165
166 // launch Wt if not
167 G4Wt::getInstance ();
168
169#ifdef G4DEBUG_VIS_OGL
170 printf("G4OpenGLWtViewer::Create \n");
171#endif
172 fLastPos3 = Wt::WPoint(-1,-1);
173 fLastPos2 = Wt::WPoint(-1,-1);
174 fLastPos1 = Wt::WPoint(-1,-1);
175
176#ifdef _A_FINIR_FIXME
177 initMovieParameters();
178#endif
179
180 fLastEventTime = new Wt::WTime();
181
182#ifdef G4DEBUG_VIS_OGL
183 printf("G4OpenGLWtViewer::G4OpenGLWtViewer END\n");
184#endif
185}
186
187//////////////////////////////////////////////////////////////////////////////
188G4OpenGLWtViewer::~G4OpenGLWtViewer (
189)
190//////////////////////////////////////////////////////////////////////////////
191//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
192{
193#ifdef _A_FINIR_FIXME
194 G4cout <<removeTempFolder().toUTF8().c_str() <<G4endl;
195#endif
196}
197
198
199#ifdef _A_FINIR_FIXME
200/**
201 Create a popup menu for the widget. This menu is activated by right-mouse click
202*/
203void G4OpenGLWtViewer::createPopupMenu() {
204
205 fContextMenu = new WMenu("All");
206
207 WMenu *mMouseAction = fContextMenu->addMenu("&Mouse actions");
208
209 fRotateAction = mMouseAction->addAction("Rotate");
210 fMoveAction = mMouseAction->addAction("Move");
211 fPickAction = mMouseAction->addAction("Pick");
212 WAction *shortcutsAction = mMouseAction->addAction("Show shortcuts");
213
214 fRotateAction->setCheckable(true);
215 fMoveAction->setCheckable(false);
216 fPickAction->setCheckable(false);
217 shortcutsAction->setCheckable(false);
218
219 fRotateAction->setChecked(true);
220 fMoveAction->setChecked(false);
221 fPickAction->setChecked(false);
222 shortcutsAction->setChecked(false);
223
224 WObject ::connect(fRotateAction,
225 SIGNAL(triggered(bool)),
226 this,
227 SLOT(actionMouseRotate()));
228
229 WObject ::connect(fMoveAction,
230 SIGNAL(triggered(bool)),
231 this,
232 SLOT(actionMouseMove()));
233
234 WObject ::connect(fPickAction,
235 SIGNAL(triggered(bool)),
236 this,
237 SLOT(actionMousePick()));
238
239 WObject ::connect(shortcutsAction,
240 SIGNAL(triggered(bool)),
241 this,
242 SLOT(showShortcuts()));
243
244 // === Style Menu ===
245 WMenu *mStyle = fContextMenu->addMenu("&Style");
246
247 WMenu *mRepresentation = mStyle->addMenu("&Representation");
248 WMenu *mProjection = mStyle->addMenu("&Projection");
249 WAction *polyhedron = mRepresentation->addAction("Polyhedron");
250 WAction *nurbs = mRepresentation->addAction("NURBS");
251
252 WAction *ortho = mProjection->addAction("Orthographic");
253 WAction *perspective = mProjection->addAction("Persepective");
254
255 // INIT mRepresentation
257 style = fVP.GetRepStyle();
258 if (style == G4ViewParameters::polyhedron) {
259 createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),1);
260 } else if (style == G4ViewParameters::nurbs) {
261 createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),2);
262 } else {
263 mRepresentation->clear();
264 }
265
266 // INIT mProjection
267 if (fVP.GetFieldHalfAngle() == 0) {
268 createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),1);
269 } else {
270 createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),2);
271 }
272
273 // === Drawing Menu ===
274 WMenu *mDrawing = mStyle->addMenu("&Drawing");
275
276 fDrawingWireframe = mDrawing->addAction("Wireframe");
277 fDrawingWireframe->setCheckable(true);
278
279 fDrawingLineRemoval = mDrawing->addAction("Hidden line removal");
280 fDrawingLineRemoval->setCheckable(true);
281
282 fDrawingSurfaceRemoval = mDrawing->addAction("Hidden Surface removal");
283 fDrawingSurfaceRemoval->setCheckable(true);
284
285 fDrawingLineSurfaceRemoval = mDrawing->addAction("Hidden line and surface removal");
286 fDrawingLineSurfaceRemoval->setCheckable(true);
287
288 // INIT Drawing
290 d_style = fVP.GetDrawingStyle();
291
292 if (d_style == G4ViewParameters::wireframe) {
293 fDrawingWireframe->setChecked(true);
294 } else if (d_style == G4ViewParameters::hlr) {
295 fDrawingLineRemoval->setChecked(true);
296 } else if (d_style == G4ViewParameters::hsr) {
297 fDrawingSurfaceRemoval->setChecked(true);
298 } else if (d_style == G4ViewParameters::hlhsr) {
299 fDrawingLineSurfaceRemoval->setChecked(true);
300 } else {
301 mDrawing->clear();
302 }
303 WObject ::connect(fDrawingWireframe,
304 SIGNAL(triggered(bool)),
305 this,
306 SLOT(actionDrawingWireframe()));
307 WObject ::connect(fDrawingLineRemoval,
308 SIGNAL(triggered(bool)),
309 this,
310 SLOT(actionDrawingLineRemoval()));
311 WObject ::connect(fDrawingSurfaceRemoval,
312 SIGNAL(triggered(bool)),
313 this,
314 SLOT(actionDrawingSurfaceRemoval()));
315 WObject ::connect(fDrawingLineSurfaceRemoval,
316 SIGNAL(triggered(bool)),
317 this,
318 SLOT(actionDrawingLineSurfaceRemoval()));
319
320 // Background Color
321
322 WAction *backgroundColorChooser ;
323
324 // === Action Menu ===
325 backgroundColorChooser = mStyle->addAction("Background color");
326 WObject ::connect(backgroundColorChooser,
327 SIGNAL(triggered()),
328 this,
329 SLOT(actionChangeBackgroundColor()));
330
331 // Text Color
332
333 WAction *textColorChooser ;
334 // === Action Menu ===
335 textColorChooser = mStyle->addAction("Text color");
336 WObject ::connect(textColorChooser,
337 SIGNAL(triggered()),
338 this,
339 SLOT(actionChangeTextColor()));
340
341 // Default Color
342
343 WAction *defaultColorChooser ;
344 // === Action Menu ===
345 defaultColorChooser = mStyle->addAction("Default color");
346 WObject ::connect(defaultColorChooser,
347 SIGNAL(triggered()),
348 this,
349 SLOT(actionChangeDefaultColor()));
350
351
352 // === Action Menu ===
353 WMenu *mActions = fContextMenu->addMenu("&Actions");
354 WAction *createEPS = mActions->addAction("Save as ...");
355 WObject ::connect(createEPS,
356 SIGNAL(triggered()),
357 this,
358 SLOT(actionSaveImage()));
359
360 // === Action Menu ===
361 WAction *movieParameters = mActions->addAction("Movie parameters...");
362 WObject ::connect(movieParameters,
363 SIGNAL(triggered()),
364 this,
365 SLOT(actionMovieParameters()));
366
367
368
369
370 // === Special Menu ===
371 WMenu *mSpecial = fContextMenu->addMenu("S&pecial");
372 WMenu *mTransparency = mSpecial->addMenu("Transparency");
373 WAction *transparencyOn = mTransparency->addAction("On");
374 WAction *transparencyOff = mTransparency->addAction("Off");
375
376 if (transparency_enabled == false) {
377 createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),2);
378 } else if (transparency_enabled == true) {
379 createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),1);
380 } else {
381 mSpecial->clear();
382 }
383
384
385 WMenu *mAntialiasing = mSpecial->addMenu("Antialiasing");
386 WAction *antialiasingOn = mAntialiasing->addAction("On");
387 WAction *antialiasingOff = mAntialiasing->addAction("Off");
388
389 if (antialiasing_enabled == false) {
390 createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),2);
391 } else if (antialiasing_enabled == true) {
392 createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),1);
393 } else {
394 mAntialiasing->clear();
395 }
396
397 WMenu *mHaloing = mSpecial->addMenu("Haloing");
398 WAction *haloingOn = mHaloing->addAction("On");
399 WAction *haloingOff = mHaloing->addAction("Off");
400
401 if (haloing_enabled == false) {
402 createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),2);
403 } else if (haloing_enabled == true) {
404 createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),1);
405 } else {
406 mHaloing->clear();
407 }
408
409 WMenu *mAux = mSpecial->addMenu("Auxiliary edges");
410 WAction *auxOn = mAux->addAction("On");
411 WAction *auxOff = mAux->addAction("Off");
412 if (!fVP.IsAuxEdgeVisible()) {
413 createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),1);
414 } else {
415 createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),2);
416 }
417
418
419
420 WMenu *mFullScreen = mSpecial->addMenu("&Full screen");
421 fFullScreenOn = mFullScreen->addAction("On");
422 fFullScreenOff = mFullScreen->addAction("Off");
423 createRadioAction(fFullScreenOn,fFullScreenOff,SLOT(toggleFullScreen(bool)),2);
424
425}
426
427
428void G4OpenGLWtViewer::G4manageContextMenuEvent(WContextMenuEvent *e)
429{
430 if (!fGLWindow) {
431 G4cerr << "Visualization window not defined, please choose one before" << G4endl;
432 } else {
433
434 if (!fContextMenu)
435 createPopupMenu();
436
437 // launch menu
438 if ( fContextMenu ) {
439 fContextMenu->exec( e->globalPos() );
440 // delete fContextMenu;
441 }
442 }
443 e->accept();
444}
445
446
447/**
448 Create a radio button menu. The two menu will be connected. When click on one,
449 eatch state will be invert and callback method will be called.
450 @param action1 first action to connect
451 @param action2 second action to connect
452 @param method callback method
453 @param nCheck: 1 : first action will be set true. 2 : second action will be set true
454*/
455void G4OpenGLWtViewer::createRadioAction(WAction *action1,WAction *action2, const std::string& method,unsigned int nCheck) {
456
457 action1->setCheckable(true);
458 action2->setCheckable(true);
459
460 if (nCheck ==1)
461 action1->setChecked (true);
462 else
463 action2->setChecked (true);
464
465 WObject ::connect(action1, SIGNAL(triggered(bool)),action2, SLOT(toggle()));
466 WObject ::connect(action2, SIGNAL(triggered(bool)),action1, SLOT(toggle()));
467
468 WObject ::connect(action1, SIGNAL(toggled(bool)),this, method.c_str());
469
470}
471
472/**
473 Slot activate when mouseAction->rotate menu is set
474 */
475void G4OpenGLWtViewer::actionMouseRotate() {
476 emit toggleMouseAction(STYLE1);
477}
478
479
480/**
481 Slot activate when mouseAction->rotate menu is set
482 */
483void G4OpenGLWtViewer::actionMouseMove() {
484 emit toggleMouseAction(STYLE2);
485}
486
487
488/**
489 Slot activate when mouseAction->zoom menu is set
490 */
491void G4OpenGLWtViewer::actionMousePick() {
492 emit toggleMouseAction(STYLE3);
493}
494
495
496/**
497 Slot activate when drawing->wireframe menu is set
498 */
499void G4OpenGLWtViewer::actionDrawingWireframe() {
500 emit toggleDrawingAction(1);
501}
502
503/**
504 Slot activate when drawing->line removal menu is set
505 */
506void G4OpenGLWtViewer::actionDrawingLineRemoval() {
507 emit toggleDrawingAction(2);
508}
509
510/**
511 Slot activate when drawing->surface removal menu is set
512 */
513void G4OpenGLWtViewer::actionDrawingSurfaceRemoval() {
514 emit toggleDrawingAction(3);
515}
516
517/**
518 Slot activate when drawing->wireframe menu is set
519 */
520void G4OpenGLWtViewer::actionDrawingLineSurfaceRemoval() {
521 emit toggleDrawingAction(4);
522}
523
524
525/**
526 Slot activated when mouse action is toggle
527 @param aAction : STYLE1, STYLE2, STYLE3
528 */
529void G4OpenGLWtViewer::toggleMouseAction(mouseActions aAction) {
530
531 if ((aAction == STYLE1) || //initialize all
532 (aAction == STYLE2) ||
533 (aAction == STYLE3)) {
534 fRotateAction->setChecked (false);
535 fMoveAction->setChecked (false);
536 fPickAction->setChecked (false);
537 fVP.SetPicking(false);
538 fMouseAction = aAction;
539 }
540 // rotate
541 if (aAction == STYLE1) { // rotate
542 showShortcuts();
543 fRotateAction->setChecked (true);
544 } else if (aAction == STYLE2) { //move
545 fMoveAction->setChecked (true);
546 } else if (aAction == STYLE3) { //pick
547 fPickAction->setChecked (true);
548 fVP.SetPicking(true);
549 }
550}
551
552#endif
553/**
554 Show shortcuts for this mouse action
555 */
556void G4OpenGLWtViewer::showShortcuts() {
557 G4cout << "========= Mouse Shortcuts =========" << G4endl;
558 if (fMouseAction == STYLE1) { // rotate
559 G4cout << "Click and move mouse to rotate volume " << G4endl;
560 G4cout << "ALT + Click and move mouse to rotate volume (View Direction)" << G4endl;
561 G4cout << "CTRL + Click and zoom mouse to zoom in/out" << G4endl;
562 G4cout << "SHIFT + Click and zoommove camera point of view" << G4endl;
563 } else if (fMouseAction == STYLE2) { //move
564 G4cout << "Move camera point of view with mouse" << G4endl;
565 } else if (fMouseAction == STYLE3) { //pick
566 G4cout << "Click and pick " << G4endl;
567 }
568 G4cout << "========= Move Shortcuts =========" << G4endl;
569 G4cout << "Press left/right arrows to move volume left/right" << G4endl;
570 G4cout << "Press up/down arrows to move volume up/down" << G4endl;
571 G4cout << "Press '+'/'-' to move volume toward/forward" << G4endl;
572 G4cout << G4endl;
573 G4cout << "========= Rotation (Theta/Phi) Shortcuts =========" << G4endl;
574 G4cout << "Press SHIFT + left/right arrows to rotate volume left/right" << G4endl;
575 G4cout << "Press SHIFT + up/down arrows to rotate volume up/down" << G4endl;
576 G4cout << G4endl;
577 G4cout << "========= Rotation (View Direction) Shortcuts =========" << G4endl;
578 G4cout << "Press ALT + left/right to rotate volume around vertical direction" << G4endl;
579 G4cout << "Press ALT + up/down to rotate volume around horizontal direction" << G4endl;
580 G4cout << G4endl;
581 G4cout << "========= Zoom View =========" << G4endl;
582 G4cout << "Press CTRL + '+'/'-' to zoom into volume" << G4endl;
583 G4cout << G4endl;
584 G4cout << "========= Misc =========" << G4endl;
585 G4cout << "Press ALT +/- to slow/speed rotation/move" << G4endl;
586 G4cout << "Press H to reset view" << G4endl;
587 G4cout << "Press Esc to exit FullScreen" << G4endl;
588 G4cout << G4endl;
589 G4cout << "========= Video =========" << G4endl;
590 G4cout << "In video mode : " << G4endl;
591 G4cout << " Press SPACE to Start/Pause video recording " << G4endl;
592 G4cout << " Press RETURN to Stop video recording " << G4endl;
593 G4cout << G4endl;
594}
595
596
597
598#ifdef _A_FINIR_FIXME
599
600/**
601 Slot activated when drawing menu is toggle
602 Warning : When G4OpenGLStoredWtViewer::DrawView() method call,
603 KernelVisitDecision () will be call and will set the fNeedKernelVisit
604 to 1. See G4XXXStoredViewer::CompareForKernelVisit for explanations.
605 It will cause a redraw of the view
606 @param aAction : 1 wireframe, 2 line removal, 3 surface removal, 4 line & surface removal
607 @see G4OpenGLStoredWtViewer::DrawView
608 @see G4XXXStoredViewer::CompareForKernelVisit
609 */
610void G4OpenGLWtViewer::toggleDrawingAction(int aAction) {
611
613
614
615 // initialize
616 if ((aAction >0) && (aAction <5)) {
617 fDrawingWireframe->setChecked (false);
618 fDrawingLineRemoval->setChecked (false);
619 fDrawingSurfaceRemoval->setChecked (false);
620 fDrawingLineSurfaceRemoval->setChecked (false);
621 }
622 if (aAction ==1) {
623 fDrawingWireframe->setChecked (true);
624
626
627 } else if (aAction ==2) {
628 fDrawingLineRemoval->setChecked (true);
629
630 d_style = G4ViewParameters::hlr;
631
632 } else if (aAction ==3) {
633 fDrawingSurfaceRemoval->setChecked (true);
634
635 d_style = G4ViewParameters::hsr;
636
637 } else if (aAction ==4) {
638 fDrawingLineSurfaceRemoval->setChecked (true);
639 d_style = G4ViewParameters::hlhsr;
640 }
641 fVP.SetDrawingStyle(d_style);
642
643 updateWWidget();
644}
645
646
647/**
648 SLOT Activate by a click on the representation menu
649 Warning : When G4OpenGLStoredWtViewer::DrawView() method call,
650 KernelVisitDecision () will be call and will set the fNeedKernelVisit
651 to 1. See G4XXXStoredViewer::CompareForKernelVisit for explanations.
652 It will cause a redraw of the view
653 @param check : 1 polyhedron, 0 nurbs
654 @see G4OpenGLStoredWtViewer::DrawView
655 @see G4XXXStoredViewer::CompareForKernelVisit
656*/
657void G4OpenGLWtViewer::toggleRepresentation(bool check) {
658
660 if (check == 1) {
662 } else {
664 }
665 fVP.SetRepStyle (style);
666
667 updateWWidget();
668}
669
670/**
671 SLOT Activate by a click on the projection menu
672 Warning : When G4OpenGLStoredWtViewer::DrawView() method call,
673 KernelVisitDecision () will be call and will set the fNeedKernelVisit
674 to 1. See G4XXXStoredViewer::CompareForKernelVisit for explanations.
675 It will cause a redraw of the view
676 @param check : 1 orthographic, 2 perspective
677 @see G4OpenGLStoredWtViewer::DrawView
678 @see G4XXXStoredViewer::CompareForKernelVisit
679*/
680void G4OpenGLWtViewer::toggleProjection(bool check) {
681
682 if (check == 1) {
683 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection o");
684 } else {
685 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection p");
686 }
687 updateWWidget();
688}
689
690
691/**
692 SLOT Activate by a click on the transparency menu
693@param check : 1 , 0
694*/
695void G4OpenGLWtViewer::toggleTransparency(bool check) {
696
697 if (check) {
698 transparency_enabled = false;
699 } else {
700 transparency_enabled = true;
701 }
702 SetNeedKernelVisit (true);
703 updateWWidget();
704}
705
706/**
707 SLOT Activate by a click on the antialiasing menu
708@param check : 1 , 0
709*/
710void G4OpenGLWtViewer::toggleAntialiasing(bool check) {
711
712 if (!check) {
713 antialiasing_enabled = false;
714 glDisable (GL_LINE_SMOOTH);
715 glDisable (GL_POLYGON_SMOOTH);
716 } else {
717 antialiasing_enabled = true;
718 glEnable (GL_LINE_SMOOTH);
719 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
720 glEnable (GL_POLYGON_SMOOTH);
721 glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
722 }
723
724 updateWWidget();
725}
726
727/**
728 SLOT Activate by a click on the haloing menu
729@param check : 1 , 0
730*/
731//FIXME : I SEE NOTHING...
732void G4OpenGLWtViewer::toggleHaloing(bool check) {
733 if (check) {
734 haloing_enabled = false;
735 } else {
736 haloing_enabled = true;
737 }
738
739 updateWWidget();
740
741}
742
743/**
744 SLOT Activate by a click on the auxiliaire edges menu
745@param check : 1 , 0
746*/
747void G4OpenGLWtViewer::toggleAux(bool check) {
748 if (check) {
749 fVP.SetAuxEdgeVisible(true);
750 } else {
751 fVP.SetAuxEdgeVisible(false);
752 }
753 SetNeedKernelVisit (true);
754 updateWWidget();
755}
756
757/**
758 SLOT Activate by a click on the full screen menu
759*/
760void G4OpenGLWtViewer::toggleFullScreen(bool check) {
761 if (check != fGLWindow->isFullScreen()) { //toggle
762 fGLWindow->setWindowState(fGLWindow->windowState() ^ Wt::WindowFullScreen);
763 G4cerr << "This version of Wt could not do fullScreen. Resizing the widget is the only solution available." << G4endl;
764 }
765}
766#endif
767
768#ifdef _A_FINIR_FIXME
769void G4OpenGLWtViewer::savePPMToTemp() {
770 if (fMovieTempFolderPath == "") {
771 return;
772 }
773 Wt::WString fileName ="Test"+Wt::WString::number(fRecordFrameNumber)+".ppm";
774 Wt::WString filePath =fMovieTempFolderPath+fileName;
775
776 WImage image;
777 image = fWindow->grabFrameBuffer();
778 bool res = false;
779
780 res = image.save(filePath,0);
781 if (res == false) {
782 resetRecording();
783 setRecordingInfos("Can't save tmp file "+filePath);
784 return;
785 }
786
787 setRecordingInfos("File "+fileName+" saved");
788 fRecordFrameNumber++;
789}
790
791
792
793void G4OpenGLWtViewer::actionSaveImage() {
794 Wt::WString filters;
795 WList<WByteArray> formats = WImageWriter::supportedImageFormats ();
796 for (int i = 0; i < formats.size(); ++i) {
797 filters +=formats.at(i) + ";;";
798 }
799 filters += "eps;;";
800 filters += "ps;;";
801 filters += "pdf";
802 Wt::WString* selectedFormat = new Wt::WString();
803 std::string name;
804 name = WFileDialog::getSaveFileName ( fGLWindow,
805 tr("Save as ..."),
806 ".",
807 filters,
808 selectedFormat ).toUTF8().c_str();
809 // bmp jpg jpeg png ppm xbm xpm
810 if (name.empty()) {
811 return;
812 }
813 name += "." + selectedFormat->toUTF8();
814 Wt::WString format = selectedFormat->toLower();
815 setPrintFilename(name.c_str(),0);
816 G4OpenGLWtExportDialog* exportDialog= new G4OpenGLWtExportDialog(fGLWindow,format,fWindow->height(),fWindow->width());
817 if( exportDialog->exec()) {
818
819 WImage image;
820 bool res = false;
821 if ((exportDialog->getWidth() !=fWindow->width()) ||
822 (exportDialog->getHeight() !=fWindow->height())) {
823 setPrintSize(exportDialog->getWidth(),exportDialog->getHeight());
824 if ((format != Wt::WString("eps")) && (format != Wt::WString("ps"))) {
825 G4cerr << "Export->Change Size : This function is not implemented, to export in another size, please resize your frame to what you need" << G4endl;
826
827 // rescaleImage(exportDialog->getWidth(),exportDialog->getHeight());// re-scale image
828 // WGLWidget* glResized = fWindow;
829
830 // FIXME :
831 // L.Garnier : I've try to implement change size function, but the problem is
832 // the renderPixmap function call the WGLWidget to resize and it doesn't draw
833 // the content of this widget... It only draw the background.
834
835 // fWindow->renderPixmap (exportDialog->getWidth()*2,exportDialog->getHeight()*2,true );
836
837 // WPixmap pixmap = fWindow->renderPixmap ();
838
839 // image = pixmap->toImage();
840 // glResized->resize(exportDialog->getWidth()*2,exportDialog->getHeight()*2);
841 // image = glResized->grabFrameBuffer();
842 }
843 } else {
844 image = fWindow->grabFrameBuffer();
845 }
846 if (format == Wt::WString("eps")) {
847 fVectoredPs = exportDialog->getVectorEPS();
848 printEPS();
849 } else if (format == "ps") {
850 fVectoredPs = true;
851 printEPS();
852 } else if (format == "pdf") {
853
854 res = printPDF(name,exportDialog->getNbColor(),image);
855
856 } else if ((format == "tif") ||
857 (format == "tiff") ||
858 (format == "jpg") ||
859 (format == "jpeg") ||
860 (format == "png") ||
861 (format == "pbm") ||
862 (format == "pgm") ||
863 (format == "ppm") ||
864 (format == "bmp") ||
865 (format == "xbm") ||
866 (format == "xpm")) {
867 res = image.save(Wt::WString(name.c_str()),0,exportDialog->getSliderValue());
868 } else {
869 G4cerr << "This version of G4UI Could not generate the selected format" << G4endl;
870 }
871 if ((format == Wt::WString("eps")) && (format == Wt::WString("ps"))) {
872 if (res == false) {
873 G4cerr << "Error while saving file... "<<name.c_str()<< G4endl;
874 } else {
875 G4cout << "File "<<name.c_str()<<" has been saved " << G4endl;
876 }
877 }
878
879 } else { // cancel selected
880 return;
881 }
882
883}
884#endif
885
886
887#ifdef _A_FINIR_FIXME
888void G4OpenGLWtViewer::actionChangeBackgroundColor() {
889
890 // //I need to revisit the kernel if the background colour changes and
891 // //hidden line removal is enabled, because hlr drawing utilises the
892 // //background colour in its drawing...
893 // // (Note added by JA 13/9/2005) Background now handled in view
894 // // parameters. A kernel visit is triggered on change of background.
895
896 WColor color;
897 color = WColorDialog::getColor(Wt::black, fGLWindow);
898 if (color.isValid()) {
899 Wt::WString com = "/vis/viewer/set/background ";
900 Wt::WString num;
901 com += num.setNum(((float)color.red())/256)+" ";
902 com += num.setNum(((float)color.green())/256)+" ";
903 com += num.setNum(((float)color.blue())/256)+" ";
904 G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
905 updateWWidget();
906 }
907}
908
909void G4OpenGLWtViewer::actionChangeTextColor() {
910
911 WColor color;
912 color = WColorDialog::getColor(Wt::yellow, fGLWindow);
913 if (color.isValid()) {
914 Wt::WString com = "/vis/viewer/set/defaultTextColour ";
915 Wt::WString num;
916 com += num.setNum(((float)color.red())/256)+" ";
917 com += num.setNum(((float)color.green())/256)+" ";
918 com += num.setNum(((float)color.blue())/256)+" ";
919 G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
920 updateWWidget();
921 }
922}
923
924void G4OpenGLWtViewer::actionChangeDefaultColor() {
925
926 WColor color;
927 color = WColorDialog::getColor(Wt::white, fGLWindow);
928 printf("actionChangeDefaultColor\n");
929 if (color.isValid()) {
930 Wt::WString com = "/vis/viewer/set/defaultColour ";
931 Wt::WString num;
932 com += num.setNum(((float)color.red())/256)+" ";
933 com += num.setNum(((float)color.green())/256)+" ";
934 com += num.setNum(((float)color.blue())/256)+" ";
935 G4UImanager::GetUIpointer()->ApplyCommand(com.toUTF8().c_str());
936 updateWWidget();
937 }
938}
939
940
941void G4OpenGLWtViewer::actionMovieParameters() {
942 showMovieParametersDialog();
943}
944
945
946void G4OpenGLWtViewer::showMovieParametersDialog() {
947 if (!fMovieParametersDialog) {
948 fMovieParametersDialog= new G4OpenGLWtMovieDialog(this,fGLWindow);
949 displayRecordingStatus();
950 fMovieParametersDialog->checkEncoderSwParameters();
951 fMovieParametersDialog->checkSaveFileNameParameters();
952 fMovieParametersDialog->checkTempFolderParameters();
953 if (getEncoderPath() == "") {
954 setRecordingInfos("mpeg_encode is needed to encode in video format. It is available here: http://bmrc.berkeley.edu/frame/research/mpeg/");
955 }
956 }
957 fMovieParametersDialog->show();
958}
959#endif
960
961/*
962// http://www.google.com/codesearch?hl=en&q=+jpg+Wt+quality+WDialog+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
963
964void Graph::exportToSVG(const Wt::WString& fname)
965{
966 // enable workaround for Wt3 misalignments
967 WwtPainter::setSVGMode(true);
968 WPicture picture;
969 WPainter p(&picture);
970 d_plot->print(&p, d_plot->rect());
971 p.end();
972
973 picture.save(fname, "svg");
974}
975*/
976
977
978
979void G4OpenGLWtViewer::FinishView()
980{
981 glFlush ();
982
983 // L. Garnier 10/2009 : Not necessary and cause problems on mac OS X 10.6
984 // fWindow->swapBuffers ();
985}
986
987/**
988 Save the current mouse press point
989 @param p mouse click point
990*/
991void G4OpenGLWtViewer::G4MousePressEvent(Wt::WMouseEvent *event)
992{
993 if (event->button() & Wt::WMouseEvent::LeftButton) {
994#ifdef _A_FINIR_FIXME
995 fWindow->setMouseTracking(true);
996#endif
997 fAutoMove = false; // stop automove
998 fLastPos1 = Wt::WPoint(event->widget().x,event->widget().y);
999 fLastPos2 = fLastPos1;
1000 fLastPos3 = fLastPos2;
1001 fLastEventTime->start();
1002 if (fMouseAction == STYLE3){ // pick
1003 Pick(event->widget().x,event->widget().y);
1004 }
1005 }
1006}
1007
1008/**
1009*/
1010void G4OpenGLWtViewer::G4MouseReleaseEvent()
1011{
1012 fSpinningDelay = fLastEventTime->elapsed();
1013 Wt::WPoint delta = Wt::WPoint(fLastPos3.x()-fLastPos1.x(),fLastPos3.y()-fLastPos1.y());
1014 if ((delta.x() == 0) && (delta.y() == 0)) {
1015 return;
1016 }
1017 if (fSpinningDelay < fLaunchSpinDelay ) {
1018 fAutoMove = true;
1019 Wt::WTime lastMoveTime;
1020 lastMoveTime.start();
1021 // try to addapt speed move/rotate looking to drawing speed
1022 float correctionFactor = 5;
1023 while (fAutoMove) {
1024 if ( lastMoveTime.elapsed () >= (int)(1000/fNbMaxFramesPerSec)) {
1025 float lTime = 1000/((float)lastMoveTime.elapsed ());
1026 if (((((float)delta.x())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1027 ((((float)delta.x())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1028 correctionFactor = (float)delta.x()*(lTime/fNbMaxAnglePerSec);
1029 if (delta.x() <0 ) {
1030 correctionFactor = -correctionFactor;
1031 }
1032 }
1033 if (((((float)delta.y())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1034 ((((float)delta.y())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1035 correctionFactor = (float)delta.y()*(lTime/fNbMaxAnglePerSec);
1036 if (delta.y() <0 ) {
1037 correctionFactor = -correctionFactor;
1038 }
1039 }
1040
1041 // Check Wt Versions for META Keys
1042
1043 // Click and move mouse to rotate volume
1044 // ALT + Click and move mouse to rotate volume (View Direction)
1045 // SHIFT + Click and move camera point of view
1046 // CTRL + Click and zoom mouse to zoom in/out
1047
1048 if (fMouseAction == STYLE1) { // rotate
1049 if (fNoKeyPress) {
1050 rotateWtScene(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
1051 } else if (fAltKeyPress) {
1052 rotateWtSceneInViewDirection(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
1053 }
1054
1055 } else if (fMouseAction == STYLE2) { // move
1056 moveScene(-((float)delta.x())/correctionFactor,-((float)delta.y())/correctionFactor,0,true);
1057 }
1058 lastMoveTime.start();
1059 }
1060#ifdef _A_FINIR_FIXME
1061 ((Wt::WApplication*)G4Wt::getInstance ())->processEvents();
1062#endif
1063 }
1064 }
1065#ifdef _A_FINIR_FIXME
1066 fWindow->setMouseTracking(false);
1067#endif
1068}
1069
1070
1071void G4OpenGLWtViewer::G4MouseDoubleClickEvent()
1072{
1073#ifdef _A_FINIR_FIXME
1074 fWindow->setMouseTracking(true);
1075#endif
1076}
1077
1078
1079/**
1080 @param pos_x mouse x position
1081 @param pos_y mouse y position
1082 @param mButtons mouse button active
1083 @param mAutoMove true: apply this move till another evnt came, false :one time move
1084*/
1085
1086 void G4OpenGLWtViewer::G4MouseMoveEvent(Wt::WMouseEvent *event)
1087{
1088
1089 Wt::WMouseEvent::Button mButtons = event->button();
1090
1091#ifdef _A_FINIR_FIXME
1092 updateKeyModifierState(event->modifiers());
1093#endif
1094
1095 if (fAutoMove) {
1096 return;
1097 }
1098
1099 fLastPos3 = fLastPos2;
1100 fLastPos2 = fLastPos1;
1101 fLastPos1 = Wt::WPoint(event->widget().x, event->widget().y);
1102
1103 int deltaX = fLastPos2.x()-fLastPos1.x();
1104 int deltaY = fLastPos2.y()-fLastPos1.y();
1105
1106 if (fMouseAction == STYLE1) { // rotate
1107 if (mButtons & Wt::WMouseEvent::LeftButton) {
1108 if (fNoKeyPress) {
1109 rotateWtScene(((float)deltaX),((float)deltaY));
1110 } else if (fAltKeyPress) {
1111 rotateWtSceneInViewDirection(((float)deltaX),((float)deltaY));
1112 } else if (fShiftKeyPress) {
1113 unsigned int sizeWin;
1114 sizeWin = getWinWidth();
1115 if (getWinHeight() < getWinWidth()) {
1116 sizeWin = getWinHeight();
1117 }
1118
1119 // L.Garnier : 08/2010 100 is the good value, but don't ask me why !
1120 float factor = ((float)100/(float)sizeWin) ;
1121 moveScene(-(float)deltaX*factor,-(float)deltaY*factor,0,false);
1122 } else if (fControlKeyPress) {
1123 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+((float)deltaY)));
1124 }
1125 }
1126 } else if (fMouseAction == STYLE2) { // move
1127 if (mButtons & Wt::WMouseEvent::LeftButton) {
1128 moveScene(-deltaX,-deltaY,0,true);
1129 }
1130 }
1131
1132 fLastEventTime->start();
1133}
1134
1135
1136/**
1137 Move the scene of dx, dy, dz values.
1138 @param dx delta mouse x position
1139 @param dy delta mouse y position
1140 @param mouseMove : true if even comes from a mouse move, false if even comes from key action
1141*/
1142
1143void G4OpenGLWtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
1144{
1145 if (fHoldMoveEvent)
1146 return;
1147 fHoldMoveEvent = true;
1148
1149 G4double coefTrans = 0;
1150 GLdouble coefDepth = 0;
1151 if(mouseMove) {
1152 coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinWidth());
1153 if (getWinHeight() <getWinWidth()) {
1154 coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinHeight());
1155 }
1156 } else {
1157 coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1158 coefDepth = getSceneDepth()*fDeltaDepth;
1159 }
1160 fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1161 updateWWidget();
1162 if (fAutoMove)
1163#ifdef _A_FINIR_FIXME
1164 ((WApplication*)G4Wt::getInstance ())->processEvents();
1165#endif
1166
1167 fHoldMoveEvent = false;
1168}
1169
1170
1171/**
1172 @param dx delta mouse x position
1173 @param dy delta mouse y position
1174*/
1175
1176void G4OpenGLWtViewer::rotateWtScene(float dx, float dy)
1177{
1178 if (fHoldRotateEvent)
1179 return;
1180 fHoldRotateEvent = true;
1181
1182 if( dx != 0) {
1183 rotateScene(dx,0);
1184 }
1185 if( dy != 0) {
1186 rotateScene(0,dy);
1187 }
1188 updateWWidget();
1189
1190 fHoldRotateEvent = false;
1191}
1192
1193/**
1194 @param dx delta mouse x position
1195 @param dy delta mouse y position
1196*/
1197
1198void G4OpenGLWtViewer::rotateWtSceneInViewDirection(float dx, float dy)
1199{
1200 if (fHoldRotateEvent)
1201 return;
1202 fHoldRotateEvent = true;
1203
1204 fXRot +=dx;
1205 fYRot +=dy;
1206
1207 rotateSceneInViewDirection(dx/100,dy/100);
1208
1209 updateWWidget();
1210
1211 fHoldRotateEvent = false;
1212}
1213
1214/**
1215 @param dx delta mouse x position
1216 @param dy delta mouse y position
1217*/
1218
1219void G4OpenGLWtViewer::rotateWtCamera(float dx, float dy)
1220{
1221 if (fHoldRotateEvent)
1222 return;
1223 fHoldRotateEvent = true;
1224
1225 rotateScene(dx,dy);
1226 updateWWidget();
1227
1228 fHoldRotateEvent = false;
1229}
1230
1231/**
1232 @param dx delta mouse x position
1233 @param dy delta mouse y position
1234*/
1235
1236void G4OpenGLWtViewer::rotateWtCameraInViewDirection(float dx, float dy)
1237{
1238 if (fHoldRotateEvent)
1239 return;
1240 fHoldRotateEvent = true;
1241
1242 fVP.SetUpVector(G4Vector3D(0.0, 1.0, 0.0));
1243 fVP.SetViewAndLights (G4Vector3D(0.0, 0.0, 1.0));
1244
1245
1246 fXRot +=dx;
1247 fYRot +=dy;
1248
1249 rotateSceneInViewDirection(fXRot/100,fYRot/100);
1250
1251 updateWWidget();
1252
1253 fHoldRotateEvent = false;
1254}
1255
1256
1257
1258
1259
1260/** This is the benning of a rescale function. It does nothing for the moment
1261 @param aWidth : new width
1262 @param aHeight : new height
1263*/
1264void G4OpenGLWtViewer::rescaleImage(
1265 int /* aWidth */
1266,int /* aHeight */
1267){
1268 // GLfloat* feedback_buffer;
1269 // GLint returned;
1270 // FILE* file;
1271
1272// feedback_buffer = new GLfloat[size];
1273// glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1274// glRenderMode (GL_FEEDBACK);
1275
1276// DrawView();
1277// returned = glRenderMode (GL_RENDER);
1278
1279}
1280
1281
1282
1283#ifdef _A_FINIR_FIXME
1284/**
1285 Generate Postscript or PDF form image
1286 @param aFilename : name of file
1287 @param aInColor : numbers of colors : 1->BW 2->RGB
1288 @param aImage : Image to print
1289*/
1290bool G4OpenGLWtViewer::printPDF (
1291 const std::string aFilename
1292,int aInColor
1293,WImage aImage
1294)
1295{
1296
1297 WPrinter printer;
1298 // printer.setPageSize(pageSize);
1299
1300 // FIXME : L. Garnier 4/12/07
1301 // This is not working, it does nothing. Image is staying in color mode
1302 // So I have desactivate the B/W button in GUI
1303 if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1304 aImage = aImage.convertToFormat ( aImage.format(), Wt::MonoOnly);
1305 }
1306
1307
1308 if (aFilename.substr(aFilename.size()-3) == ".ps") {
1309#if WT_VERSION > 0x040200
1310 printer.setOutputFormat(WPrinter::PostScriptFormat);
1311#endif
1312 } else {
1313#if WT_VERSION > 0x040100
1314 printer.setOutputFormat(WPrinter::PdfFormat);
1315#endif
1316 }
1317#if WT_VERSION > 0x040100
1318 printer.setOutputFileName(Wt::WString(aFilename.c_str()));
1319#endif
1320 // printer.setFullPage ( true);
1321 WPainter paint(&printer);
1322 paint.drawImage (0,0,aImage);
1323 paint.end();
1324 return true;
1325}
1326
1327
1328
1329void G4OpenGLWtViewer::G4wheelEvent (Wt::WWheelEvent * event)
1330{
1331 fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1332 updateWWidget();
1333}
1334#endif
1335
1336 void G4OpenGLWtViewer::G4keyPressEvent (Wt::WKeyEvent * event)
1337{
1338 if (fHoldKeyEvent)
1339 return;
1340
1341 fHoldKeyEvent = true;
1342
1343
1344 // with no modifiers
1345#ifdef _A_FINIR_FIXME
1346 updateKeyModifierState(event->modifiers());
1347#endif
1348 if ((fNoKeyPress)) { // || (event->modifiers() == Wt::KeyboardModifier )) {
1349 if (event->key() == Wt::Key_Down) { // go down
1350 moveScene(0,1,0,false);
1351 }
1352 else if (event->key() == Wt::Key_Up) { // go up
1353 moveScene(0,-1,0,false);
1354 }
1355 if (event->key() == Wt::Key_Left) { // go left
1356 moveScene(-1,0,0,false);
1357 }
1358 else if (event->key() == Wt::Key_Right) { // go right
1359 moveScene(1,0,0,false);
1360 }
1361 if (event->text() == Wt::WString("-") ) { // go backward
1362 moveScene(0,0,1,false);
1363 }
1364 else if (event->text() == Wt::WString("+")) { // go forward
1365 moveScene(0,0,-1,false);
1366 }
1367
1368 // escaped from full screen
1369 if (event->key() == Wt::Key_Escape) {
1370#ifdef _A_FINIR_FIXME
1371 toggleFullScreen(false);
1372#endif
1373 }
1374 }
1375 // several case here : If return is pressed, in every case -> display the movie parameters dialog
1376 // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
1377 // If encoder not found-> does nothing.Only display a message in status box
1378 // If all ok-> generate parameter file
1379 // If ok -> put encoder button enabled
1380
1381#ifdef _A_FINIR_FIXME
1382 if ( (event->key() == Wt::Key_Enter)){ // end of video
1383 stopVideo();
1384 }
1385 if (event->key() == Wt::Key_Space){ // start/pause of video
1386 startPauseVideo();
1387 }
1388#endif
1389
1390 // H : Return Home view
1391 if (event->key() == Wt::Key_H){ // go Home
1392 fDeltaRotation = 1;
1393 fDeltaSceneTranslation = 0.01;
1394 fDeltaDepth = 0.01;
1395 fDeltaZoom = 0.05;
1396 fDeltaMove = 0.05;
1397
1398 fVP.SetZoomFactor(1.);
1399 fVP.SetUpVector(G4Vector3D (0., 1., 0.));
1400 fVP.SetViewAndLights (G4Vector3D (0., 0., 1.));
1401
1402 updateWWidget();
1403 }
1404
1405 // Shift Modifier
1406 if (fShiftKeyPress) {
1407 if (event->key() == Wt::Key_Down) { // rotate phi
1408 rotateWtScene(0,-fDeltaRotation);
1409 }
1410 else if (event->key() == Wt::Key_Up) { // rotate phi
1411 rotateWtScene(0,fDeltaRotation);
1412 }
1413 if (event->key() == Wt::Key_Left) { // rotate theta
1414 rotateWtScene(fDeltaRotation,0);
1415 }
1416 else if (event->key() == Wt::Key_Right) { // rotate theta
1417 rotateWtScene(-fDeltaRotation,0);
1418 }
1419
1420 // Alt Modifier
1421 }
1422 if ((fAltKeyPress)) {
1423 if (event->key() == Wt::Key_Down) { // rotate phi
1424 rotateWtSceneInViewDirection(0,-fDeltaRotation);
1425 }
1426 else if (event->key() == Wt::Key_Up) { // rotate phi
1427 rotateWtSceneInViewDirection(0,fDeltaRotation);
1428 }
1429 if (event->key() == Wt::Key_Left) { // rotate theta
1430 rotateWtSceneInViewDirection(fDeltaRotation,0);
1431 }
1432 else if (event->key() == Wt::Key_Right) { // rotate theta
1433 rotateWtSceneInViewDirection(-fDeltaRotation,0);
1434 }
1435
1436 // Rotatio +/-
1437 if (event->text() == Wt::WString("+")) {
1438 fDeltaRotation = fDeltaRotation/0.7;
1439 G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
1440 }
1441 else if (event->text() == Wt::WString("-")) {
1442 fDeltaRotation = fDeltaRotation*0.7;
1443 G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
1444 }
1445
1446 // Control Modifier OR Command on MAC
1447 }
1448 if ((fControlKeyPress)) {
1449 if (event->text() == Wt::WString("+")) {
1450 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
1451 updateWWidget();
1452 }
1453 else if (event->text() == Wt::WString("-")) {
1454 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
1455 updateWWidget();
1456 }
1457 }
1458
1459 fHoldKeyEvent = false;
1460}
1461
1462
1463#ifdef _A_FINIR_FIXME
1464void G4OpenGLWtViewer::updateKeyModifierState(Wt::KeyboardModifiers modifier) {
1465 // Check Wt Versions for META Keys
1466
1467 fNoKeyPress = true;
1468 fAltKeyPress = false;
1469 fShiftKeyPress = false;
1470 fControlKeyPress = false;
1471
1472 if (modifier & Wt::AltModifier ) {
1473 fAltKeyPress = true;
1474 fNoKeyPress = false;
1475 }
1476 if (modifier & Wt::ShiftModifier ) {
1477 fShiftKeyPress = true;
1478 fNoKeyPress = false;
1479 }
1480 if (modifier & Wt::ControlModifier ) {
1481 fControlKeyPress = true;
1482 fNoKeyPress = false;
1483 }
1484}
1485
1486/** Stop the video. Check all parameters and enable encoder button if all is ok.
1487*/
1488void G4OpenGLWtViewer::stopVideo() {
1489
1490 // if encoder parameter is wrong, display parameters dialog and return
1491 if (!fMovieParametersDialog) {
1492 showMovieParametersDialog();
1493 }
1494 setRecordingStatus(STOP);
1495
1496 if (fRecordFrameNumber >0) {
1497 // check parameters if they were modified (Re APPLY them...)
1498 if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
1499 setRecordingStatus(BAD_ENCODER);
1500 } else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
1501 setRecordingStatus(BAD_OUTPUT);
1502 }
1503 } else {
1504 resetRecording();
1505 setRecordingInfos("No frame to encode.");
1506 }
1507}
1508
1509/** Stop the video. Check all parameters and enable encoder button if all is ok.
1510*/
1511void G4OpenGLWtViewer::saveVideo() {
1512
1513 // if encoder parameter is wrong, display parameters dialog and return
1514 if (!fMovieParametersDialog) {
1515 showMovieParametersDialog();
1516 }
1517
1518 fMovieParametersDialog->checkEncoderSwParameters();
1519 fMovieParametersDialog->checkSaveFileNameParameters();
1520
1521 if (fRecordingStep == STOP) {
1522 setRecordingStatus(SAVE);
1523 generateMpegEncoderParameters();
1524 encodeVideo();
1525 }
1526}
1527
1528
1529/** Start/Pause the video..
1530*/
1531void G4OpenGLWtViewer::startPauseVideo() {
1532
1533 // first time, if temp parameter is wrong, display parameters dialog and return
1534
1535 if (( fRecordingStep == WAIT)) {
1536 if ( fRecordFrameNumber == 0) {
1537 if (getTempFolderPath() == "") { // BAD_OUTPUT
1538 showMovieParametersDialog();
1539 setRecordingInfos("You should specified the temp folder in order to make movie");
1540 return;
1541 } else {
1542 // remove temp folder if it was create
1543 Wt::WString tmp = removeTempFolder();
1544 if (tmp !="") {
1545 setRecordingInfos(tmp);
1546 return;
1547 }
1548 tmp = createTempFolder();
1549 if (tmp != "") {
1550 setRecordingInfos("Can't create temp folder."+tmp);
1551 return;
1552 }
1553 }
1554 }
1555 }
1556 if ((fRecordingStep == WAIT)) {
1557 setRecordingStatus(START);
1558 } else if (fRecordingStep == START) {
1559 setRecordingStatus(PAUSE);
1560 } else if (fRecordingStep == PAUSE) {
1561 setRecordingStatus(CONTINUE);
1562 } else if (fRecordingStep == CONTINUE) {
1563 setRecordingStatus(PAUSE);
1564 }
1565}
1566
1567void G4OpenGLWtViewer::setRecordingStatus(RECORDING_STEP step) {
1568
1569 fRecordingStep = step;
1570 displayRecordingStatus();
1571}
1572
1573
1574void G4OpenGLWtViewer::displayRecordingStatus() {
1575
1576 Wt::WString txtStatus = "";
1577 if (fRecordingStep == WAIT) {
1578 txtStatus = "Waiting to start...";
1579 fRecordFrameNumber = 0; // reset the frame number
1580 } else if (fRecordingStep == START) {
1581 txtStatus = "Start Recording...";
1582 } else if (fRecordingStep == PAUSE) {
1583 txtStatus = "Pause Recording...";
1584 } else if (fRecordingStep == CONTINUE) {
1585 txtStatus = "Continue Recording...";
1586 } else if (fRecordingStep == STOP) {
1587 txtStatus = "Stop Recording...";
1588 } else if (fRecordingStep == READY_TO_ENCODE) {
1589 txtStatus = "Ready to Encode...";
1590 } else if (fRecordingStep == ENCODING) {
1591 txtStatus = "Encoding...";
1592 } else if (fRecordingStep == FAILED) {
1593 txtStatus = "Failed to encode...";
1594 } else if ((fRecordingStep == BAD_ENCODER)
1595 || (fRecordingStep == BAD_OUTPUT)
1596 || (fRecordingStep == BAD_TMP)) {
1597 txtStatus = "Correct above errors first";
1598 } else if (fRecordingStep == SUCCESS) {
1599 txtStatus = "File encoded successfully";
1600 } else {
1601 }
1602
1603 if (fMovieParametersDialog) {
1604 fMovieParametersDialog->setRecordingStatus(txtStatus);
1605 } else {
1606 G4cout << txtStatus.toUTF8().c_str() << G4endl;
1607 }
1608 setRecordingInfos("");
1609}
1610
1611
1612void G4OpenGLWtViewer::setRecordingInfos(Wt::WString txt) {
1613 if (fMovieParametersDialog) {
1614 fMovieParametersDialog->setRecordingInfos(txt);
1615 } else {
1616 G4cout << txt.toUTF8().c_str() << G4endl;
1617 }
1618}
1619
1620/** Init the movie parameters. Temp dir and encoder path
1621*/
1622void G4OpenGLWtViewer::initMovieParameters() {
1623 //init encoder
1624
1625 //look for encoderPath
1626 fProcess = new WProcess();
1627
1628 WObject ::connect(fProcess,SIGNAL(finished ( int)),
1629 this,SLOT(processLookForFinished()));
1630 fProcess->setReadChannelMode(WProcess::MergedChannels);
1631 fProcess->start ("which mpeg_encode");
1632
1633}
1634
1635/** @return encoder path or "" if it does not exist
1636 */
1637Wt::WString G4OpenGLWtViewer::getEncoderPath() {
1638 return fEncoderPath;
1639}
1640
1641
1642/**
1643 * set the new encoder path
1644 * @return "" if correct. The error otherwise
1645*/
1646Wt::WString G4OpenGLWtViewer::setEncoderPath(Wt::WString path) {
1647 if (path == "") {
1648 return "File does not exist";
1649 }
1650
1651 path = WDir::cleanPath(path);
1652 WFileInfo *f = new WFileInfo(path);
1653 if (!f->exists()) {
1654 return "File does not exist";
1655 } else if (f->isDir()) {
1656 return "This is a directory";
1657 } else if (!f->isExecutable()) {
1658 return "File exist but is not executable";
1659 } else if (!f->isFile()) {
1660 return "This is not a file";
1661 }
1662 fEncoderPath = path;
1663
1664 if ((fRecordingStep == BAD_ENCODER)) {
1665 setRecordingStatus(STOP);
1666 }
1667 return "";
1668}
1669
1670
1671bool G4OpenGLWtViewer::isRecording(){
1672 if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
1673 return true;
1674 }
1675 return false;
1676}
1677
1678bool G4OpenGLWtViewer::isPaused(){
1679 if (fRecordingStep == PAUSE) {
1680 return true;
1681 }
1682 return false;
1683}
1684
1685bool G4OpenGLWtViewer::isEncoding(){
1686 if (fRecordingStep == ENCODING) {
1687 return true;
1688 }
1689 return false;
1690}
1691
1692bool G4OpenGLWtViewer::isWaiting(){
1693 if (fRecordingStep == WAIT) {
1694 return true;
1695 }
1696 return false;
1697}
1698
1699bool G4OpenGLWtViewer::isStopped(){
1700 if (fRecordingStep == STOP) {
1701 return true;
1702 }
1703 return false;
1704}
1705
1706bool G4OpenGLWtViewer::isFailed(){
1707 if (fRecordingStep == FAILED) {
1708 return true;
1709 }
1710 return false;
1711}
1712
1713bool G4OpenGLWtViewer::isSuccess(){
1714 if (fRecordingStep == SUCCESS) {
1715 return true;
1716 }
1717 return false;
1718}
1719
1720bool G4OpenGLWtViewer::isBadEncoder(){
1721 if (fRecordingStep == BAD_ENCODER) {
1722 return true;
1723 }
1724 return false;
1725}
1726bool G4OpenGLWtViewer::isBadTmp(){
1727 if (fRecordingStep == BAD_TMP) {
1728 return true;
1729 }
1730 return false;
1731}
1732bool G4OpenGLWtViewer::isBadOutput(){
1733 if (fRecordingStep == BAD_OUTPUT) {
1734 return true;
1735 }
1736 return false;
1737}
1738
1739void G4OpenGLWtViewer::setBadEncoder(){
1740 fRecordingStep = BAD_ENCODER;
1741 displayRecordingStatus();
1742}
1743void G4OpenGLWtViewer::setBadTmp(){
1744 fRecordingStep = BAD_TMP;
1745 displayRecordingStatus();
1746}
1747void G4OpenGLWtViewer::setBadOutput(){
1748 fRecordingStep = BAD_OUTPUT;
1749 displayRecordingStatus();
1750}
1751
1752void G4OpenGLWtViewer::setWaiting(){
1753 fRecordingStep = WAIT;
1754 displayRecordingStatus();
1755}
1756
1757
1758bool G4OpenGLWtViewer::isReadyToEncode(){
1759 if (fRecordingStep == READY_TO_ENCODE) {
1760 return true;
1761 }
1762 return false;
1763}
1764
1765void G4OpenGLWtViewer::resetRecording() {
1766 setRecordingStatus(WAIT);
1767}
1768
1769/**
1770 * set the temp folder path
1771 * @return "" if correct. The error otherwise
1772*/
1773Wt::WString G4OpenGLWtViewer::setTempFolderPath(Wt::WString path) {
1774
1775 if (path == "") {
1776 return "Path does not exist";
1777 }
1778 path = WDir::cleanPath(path);
1779 WFileInfo *d = new WFileInfo(path);
1780 if (!d->exists()) {
1781 return "Path does not exist";
1782 } else if (!d->isDir()) {
1783 return "This is not a directory";
1784 } else if (!d->isReadable()) {
1785 return path +" is read protected";
1786 } else if (!d->isWritable()) {
1787 return path +" is write protected";
1788 }
1789
1790 if ((fRecordingStep == BAD_TMP)) {
1791 setRecordingStatus(WAIT);
1792 }
1793 fTempFolderPath = path;
1794 return "";
1795}
1796
1797/** @return the temp folder path or "" if it does not exist
1798 */
1799Wt::WString G4OpenGLWtViewer::getTempFolderPath() {
1800 return fTempFolderPath;
1801}
1802
1803/**
1804 * set the save file name path
1805 * @return "" if correct. The error otherwise
1806*/
1807Wt::WString G4OpenGLWtViewer::setSaveFileName(Wt::WString path) {
1808
1809 if (path == "") {
1810 return "Path does not exist";
1811 }
1812
1813 WFileInfo *file = new WFileInfo(path);
1814 WDir dir = file->dir();
1815 path = WDir::cleanPath(path);
1816 if (file->exists()) {
1817 return "File already exist, please choose a new one";
1818 } else if (!dir.exists()) {
1819 return "Dir does not exist";
1820 } else if (!dir.isReadable()) {
1821 return path +" is read protected";
1822 }
1823
1824 if ((fRecordingStep == BAD_OUTPUT)) {
1825 setRecordingStatus(STOP);
1826 }
1827 fSaveFileName = path;
1828 return "";
1829}
1830
1831/** @return the save file path
1832 */
1833Wt::WString G4OpenGLWtViewer::getSaveFileName() {
1834 return fSaveFileName ;
1835}
1836
1837/** Create a Wt_temp folder in the temp folder given
1838* The temp folder will be like this /tmp/WtMovie_12-02-2008_12_12_58/
1839* @return "" if success. Error message if not.
1840*/
1841Wt::WString G4OpenGLWtViewer::createTempFolder() {
1842 fMovieTempFolderPath = "";
1843 //check
1844 Wt::WString tmp = setTempFolderPath(fTempFolderPath);
1845 if (tmp != "") {
1846 return tmp;
1847 }
1848 Wt::WString sep = Wt::WString(WDir::separator());
1849 Wt::WString path = sep+"WtMovie_"+WDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
1850 WDir *d = new WDir(WDir::cleanPath(fTempFolderPath));
1851 // check if it is already present
1852 if (d->exists(path)) {
1853 return "Folder "+path+" already exists.Please remove it first";
1854 }
1855 if (d->mkdir(fTempFolderPath+path)) {
1856 fMovieTempFolderPath = fTempFolderPath+path;
1857 return "";
1858 } else {
1859 return "Can't create "+fTempFolderPath+path;
1860 }
1861 return "-";
1862}
1863
1864/** Remove the Wt_temp folder in the temp folder
1865*/
1866Wt::WString G4OpenGLWtViewer::removeTempFolder() {
1867 // remove files in Wt_temp folder
1868 if (fMovieTempFolderPath == "") {
1869 return "";
1870 }
1871 WDir *d = new WDir(WDir::cleanPath(fMovieTempFolderPath));
1872 if (!d->exists()) {
1873 return ""; // already remove
1874 }
1875
1876 d->setFilter( WDir::Files );
1877 Wt::WStringList subDirList = d->entryList();
1878 int res = true;
1879 Wt::WString error = "";
1880 for (Wt::WStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
1881 const Wt::WString currentFile = *it;
1882 if (!d->remove(currentFile)) {
1883 res = false;
1884 Wt::WString file = fMovieTempFolderPath+currentFile;
1885 error +="Removing file failed : "+file;
1886 } else {
1887 }
1888 }
1889 if (res) {
1890 if (d->rmdir(fMovieTempFolderPath)) {
1891 fMovieTempFolderPath = "";
1892 return "";
1893 } else {
1894 return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
1895 }
1896
1897 }
1898 return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
1899}
1900
1901
1902
1903bool G4OpenGLWtViewer::hasPendingEvents () {
1904#ifdef _A_FINIR_FIXME
1905 return ((WApplication*)G4Wt::getInstance ())->hasPendingEvents ();
1906#endif
1907 return false;
1908}
1909
1910bool G4OpenGLWtViewer::generateMpegEncoderParameters () {
1911
1912 // save the parameter file
1913 FILE* fp;
1914 fp = fopen (Wt::WString(fMovieTempFolderPath+fParameterFileName).toUTF8().c_str(), "w");
1915
1916 if (fp == NULL) {
1917 setRecordingInfos("Generation of parameter file failed");
1918 return false;
1919 }
1920
1921 fprintf (fp,"# parameter file template with lots of comments to assist you\n");
1922 fprintf (fp,"#\n");
1923 fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
1924 fprintf (fp,"# the copy\n");
1925 fprintf (fp,"#\n");
1926 fprintf (fp,"#\n");
1927 fprintf (fp,"# any line beginning with '#' is a comment\n");
1928 fprintf (fp,"#\n");
1929 fprintf (fp,"# no line should be longer than 255 characters\n");
1930 fprintf (fp,"#\n");
1931 fprintf (fp,"#\n");
1932 fprintf (fp,"# general format of each line is:\n");
1933 fprintf (fp,"# \n");
1934 fprintf (fp,"#\n");
1935 fprintf (fp,"# lines can generally be in any order\n");
1936 fprintf (fp,"#\n");
1937 fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
1938 fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
1939 fprintf (fp,"#\n");
1940 fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
1941 fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
1942 fprintf (fp,"# the INPUT parameter.\n");
1943 fprintf (fp,"#\n");
1944 fprintf (fp,"# MUST be in UPPER CASE\n");
1945 fprintf (fp,"#\n");
1946 fprintf (fp,"\n");
1947 fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
1948 fprintf (fp,"# for more info.\n");
1949 fprintf (fp,"\n");
1950 fprintf (fp,"PATTERN IBBPBBPBBPBBPBBP\n");
1951 fprintf (fp,"OUTPUT %s\n",getSaveFileName().toUTF8().c_str());
1952 fprintf (fp,"\n");
1953 fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
1954 fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
1955 fprintf (fp,"#\n");
1956 fprintf (fp,"# You must specify the type of the input files. The choices are:\n");
1957 fprintf (fp,"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
1958 fprintf (fp,"# (must be upper case)\n");
1959 fprintf (fp,"#\n");
1960 fprintf (fp,"BASE_FILE_FORMAT PPM\n");
1961 fprintf (fp,"\n");
1962 fprintf (fp,"#\n");
1963 fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
1964 fprintf (fp,"# YUV_SIZE widthxheight\n");
1965 fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
1966 fprintf (fp,"# on just one machine\n");
1967 fprintf (fp,"#\n");
1968 fprintf (fp,"YUV_SIZE 352x240\n");
1969 fprintf (fp,"\n");
1970 fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
1971 fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
1972 fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
1973 fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
1974 fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
1975 fprintf (fp,"# to specify the file order.\n");
1976 fprintf (fp,"\n");
1977 fprintf (fp,"INPUT_FORMAT UCB\n");
1978 fprintf (fp,"\n");
1979 fprintf (fp,"# the conversion statement\n");
1980 fprintf (fp,"#\n");
1981 fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
1982 fprintf (fp,"#\n");
1983 fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
1984 fprintf (fp,"# INPUT_CONVERT giftoppm *\n");
1985 fprintf (fp,"#\n");
1986 fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
1987 fprintf (fp,"# INPUT_CONVERT cat *.Y *.U *.V\n");
1988 fprintf (fp,"#\n");
1989 fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
1990 fprintf (fp,"# INPUT_CONVERT goto frame *; grabppm\n");
1991 fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
1992 fprintf (fp,"#\n");
1993 fprintf (fp,"INPUT_CONVERT * \n");
1994 fprintf (fp,"\n");
1995 fprintf (fp,"# number of frames in a GOP.\n");
1996 fprintf (fp,"#\n");
1997 fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
1998 fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
1999 fprintf (fp,"#\n");
2000 fprintf (fp,"# later, will add more flexible GOP signalling\n");
2001 fprintf (fp,"#\n");
2002 fprintf (fp,"GOP_SIZE 16\n");
2003 fprintf (fp,"\n");
2004 fprintf (fp,"# number of slices in a frame\n");
2005 fprintf (fp,"#\n");
2006 fprintf (fp,"# 1 is a good number. another possibility is the number of macroblock rows\n");
2007 fprintf (fp,"# (which is the height divided by 16)\n");
2008 fprintf (fp,"#\n");
2009 fprintf (fp,"SLICES_PER_FRAME 1\n");
2010 fprintf (fp,"\n");
2011 fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2012 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.toUTF8().c_str());
2013 fprintf (fp,"\n");
2014 fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2015 fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2016 fprintf (fp,"# way of numbering them. See the manual for more information.\n");
2017 fprintf (fp,"INPUT\n");
2018 fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2019 fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2020 fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2021 fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2022 fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2023 fprintf (fp,"# if you do, too bad!!!\n");
2024 fprintf (fp,"#\n");
2025 fprintf (fp,"#\n");
2026 fprintf (fp,"Test*.ppm [0-%d]\n",fRecordFrameNumber-1);
2027 fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2028 fprintf (fp,"# of files\n");
2029 fprintf (fp,"END_INPUT\n");
2030 fprintf (fp,"\n");
2031 fprintf (fp,"\n");
2032 fprintf (fp,"\n");
2033 fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2034 fprintf (fp,"\n");
2035 fprintf (fp,"# FULL or HALF -- must be upper case\n");
2036 fprintf (fp,"# Should be FULL for computer generated images\n");
2037 fprintf (fp,"PIXEL FULL\n");
2038 fprintf (fp,"\n");
2039 fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2040 fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2041 fprintf (fp,"RANGE 10\n");
2042 fprintf (fp,"\n");
2043 fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2044 fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2045 fprintf (fp,"\n");
2046 fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2047 fprintf (fp,"PSEARCH_ALG LOGARITHMIC\n");
2048 fprintf (fp,"\n");
2049 fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2050 fprintf (fp,"#\n");
2051 fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2052 fprintf (fp,"#\n");
2053 fprintf (fp,"BSEARCH_ALG SIMPLE\n");
2054 fprintf (fp,"\n");
2055 fprintf (fp,"#\n");
2056 fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2057 fprintf (fp,"# (values must be between 1 and 31)\n");
2058 fprintf (fp,"# These are the Wscale values for the entire frame in variable bit-rate\n");
2059 fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2060 fprintf (fp,"#\n");
2061 fprintf (fp,"\n");
2062 fprintf (fp,"# Wscale (Wuantization scale) affects quality and compression,\n");
2063 fprintf (fp,"# but has very little effect on speed.\n");
2064 fprintf (fp,"\n");
2065 fprintf (fp,"IWSCALE 4\n");
2066 fprintf (fp,"PWSCALE 5\n");
2067 fprintf (fp,"BWSCALE 12\n");
2068 fprintf (fp,"\n");
2069 fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2070 fprintf (fp,"REFERENCE_FRAME ORIGINAL\n");
2071 fprintf (fp,"\n");
2072 fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2073 fprintf (fp,"\n");
2074 fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2075 fprintf (fp,"#BIT_RATE 1000000\n");
2076 fprintf (fp,"\n");
2077 fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2078 fprintf (fp,"BUFFER_SIZE 327680\n");
2079 fprintf (fp,"\n");
2080 fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2081 fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2082 fprintf (fp,"FRAME_RATE 30\n");
2083 fprintf (fp,"\n");
2084 fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2085 fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IWTABLE, etc.\n");
2086 fprintf (fp,"\n");
2087 fprintf (fp,"\n");
2088 fclose (fp);
2089
2090 setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2091 setRecordingStatus(READY_TO_ENCODE);
2092 return true;
2093}
2094
2095void G4OpenGLWtViewer::encodeVideo()
2096{
2097 if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2098 setRecordingStatus(ENCODING);
2099
2100 fProcess = new WProcess();
2101 WObject ::connect(fProcess,SIGNAL(finished ( int)),
2102 this,SLOT(processEncodeFinished()));
2103 WObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2104 this,SLOT(processEncodeStdout()));
2105 fProcess->setReadChannelMode(WProcess::MergedChannels);
2106 fProcess->start (fEncoderPath, Wt::WStringList(fMovieTempFolderPath+fParameterFileName));
2107 }
2108}
2109
2110
2111// FIXME : does not work on Wt3
2112void G4OpenGLWtViewer::processEncodeStdout()
2113{
2114 Wt::WString tmp = fProcess->readStdout ().data();
2115 int start = tmp.findRev("ESTIMATED TIME");
2116 tmp = tmp.mid(start,tmp.find("\n",start)-start);
2117 setRecordingInfos(tmp);
2118}
2119
2120
2121void G4OpenGLWtViewer::processEncodeFinished()
2122{
2123
2124 Wt::WString txt = "";
2125 txt = getProcessErrorMsg();
2126 if (txt == "") {
2127 setRecordingStatus(SUCCESS);
2128 } else {
2129 setRecordingStatus(FAILED);
2130 }
2131 // setRecordingInfos(txt+removeTempFolder());
2132}
2133
2134
2135void G4OpenGLWtViewer::processLookForFinished()
2136 {
2137
2138 Wt::WString txt = getProcessErrorMsg();
2139 if (txt != "") {
2140 fEncoderPath = "";
2141 } else {
2142 fEncoderPath = Wt::WString(fProcess->readAllStandardOutput ().data()).trimmed();
2143 // if not found, return "not found"
2144 if (fEncoderPath.contains(" ")) {
2145 fEncoderPath = "";
2146 } else if (!fEncoderPath.contains("mpeg_encode")) {
2147 fEncoderPath = "";
2148 }
2149 setEncoderPath(fEncoderPath);
2150 }
2151 // init temp folder
2152 setTempFolderPath(WDir::temp ().absolutePath ());
2153}
2154
2155
2156Wt::WString G4OpenGLWtViewer::getProcessErrorMsg()
2157{
2158 Wt::WString txt = "";
2159 if (fProcess->exitCode() != 0) {
2160 switch (fProcess->error()) {
2161 case WProcess::FailedToStart:
2162 txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2163 break;
2164 case WProcess::Crashed:
2165 txt = "The process crashed some time after starting successfully.\n";
2166 break;
2167 case WProcess::Timedout:
2168 txt = "The last waitFor...() function timed out. The state of WProcess is unchanged, and you can try calling waitFor...() again.\n";
2169 break;
2170 case WProcess::WriteError:
2171 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";
2172 break;
2173 case WProcess::ReadError:
2174 txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2175 break;
2176 case WProcess::UnknownError:
2177 txt = "An unknown error occurred. This is the default return value of error().\n";
2178 break;
2179 }
2180 }
2181 return txt;
2182}
2183#endif
2184
2185
2186
2187/*
2188
2189void MultiLayer::exportToSVG(const Wt::WString& fname)
2190{
2191 WPicture picture;
2192 WPainter p(&picture);
2193 for (int i=0;i<(int)graphsList->count();i++)
2194 {
2195 Graph *gr=(Graph *)graphsList->at(i);
2196 Plot *myPlot= (Plot *)gr->plotWidget();
2197
2198 Wt::WPoint pos=gr->pos();
2199
2200 int width=int(myPlot->frameGeometry().width());
2201 int height=int(myPlot->frameGeometry().height());
2202
2203 myPlot->print(&p, WRect(pos,WSize(width,height)));
2204 }
2205
2206 p.end();
2207 picture.save(fname, "svg");
2208}
2209*/
2210#endif
double G4double
Definition: G4Types.hh:64
HepGeom::Vector3D< G4double > G4Vector3D
Definition: G4Vector3D.hh:35
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
G4int ApplyCommand(const char *aCommand)
Definition: G4UImanager.cc:369
static G4UImanager * GetUIpointer()
Definition: G4UImanager.cc:51