3 #include <AIS_InteractiveContext.hxx>
4 #include <OSD_Timer.hxx>
5 #include <Graphic3d_ArrayOfPrimitives.hxx>
6 #include <AIS_ListOfInteractive.hxx>
7 #include <AIS_ListIteratorOfListOfInteractive.hxx>
8 #include <AIS_Shape.hxx>
9 #include <TopoDS_Shape.hxx>
10 #include <TopExp_Explorer.hxx>
11 #include <TopoDS_Face.hxx>
12 #include <Poly_Triangulation.hxx>
13 #include <BRep_TFace.hxx>
15 #include <Sphere_Sphere.hxx>
16 #include <AIS_Trihedron.hxx>
18 #include <qapplication.h>
\r
20 #include <qworkspace.h>
21 #include <qstatusbar.h>
23 #include <qmessagebox.h>
24 #include <qtextedit.h>
25 #include <qlayout.h>
\r
29 #include "Application.h"
31 #include "MDIWindow.h"
32 #include "Translate.h"
33 #include "ViewOperations.h" // to have access to its enumeration
34 #include "AutoTestDlg.h"
36 //#define OUTPUT_WINDOW
38 static Application* stApp;
39 static OSD_Timer timer;
41 Application::Application() : QMainWindow( 0 )
45 myIsDocuments = false;
47 // create and define the central widget
\r
48 QFrame* vBox = new QFrame( this );
\r
49 vBox->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
50 QVBoxLayout* main = new QVBoxLayout( vBox );
\r
51 main->setMargin( 0 );
\r
53 myWorkSpace = new QWorkspace( vBox );
\r
54 main->addWidget( myWorkSpace );
55 setCentralWidget( vBox );
\r
60 statusBar()->showMessage( tr("INF_READY"), 2001 );
62 verify( connect( myWorkSpace, SIGNAL( windowActivated( QWidget* ) ),
63 this, SLOT( onWindowActivated( QWidget* ) ) ) );
65 myOutput = new OutputWindow( 0 );
73 Application::~Application()
75 if (myViewDlg) delete myViewDlg;
76 if (myOutput) delete myOutput;
79 void Application::createActions()
81 QString dir = getResourceDir();
82 QPixmap newIcon( dir + tr( "ICON_NEW" ) ),
83 helpIcon( dir + tr( "ICON_HELP" ) ),
84 closeIcon( dir + tr( "ICON_CLOSE" ) ),
85 autoIcon( dir + tr( "ICON_AUTO_TEST" ) ),
86 optimIcon( dir + tr( "ICON_OPTIM" ) ),
\r
87 stopIcon( dir + tr( "ICON_STOP" ) ),
88 tileIcon( dir + tr( "ICON_TILE" ) ),
89 cascadeIcon( dir + tr( "ICON_CASCADE" ) );
91 // toolbar with standard actions: new, save...
92 myStdToolBar = new QToolBar( this );
\r
93 addToolBar( Qt::TopToolBarArea, myStdToolBar );
95 // menu with all actions
96 myFilePopup = menuBar()->addMenu( tr( "MEN_FILE" ) );
99 QMenu* view = menuBar()->addMenu( tr( "MEN_VIEW" ) );
101 // Tools menu (it is shown or hidden dynamically)
102 myToolsMenu = new QMenu( tr( "MEN_TOOLS" ), this );
105 myWinMenu = menuBar()->addMenu( tr( "MEN_WINDOWS" ) );
106 verify(connect( myWinMenu, SIGNAL( aboutToShow() ),
107 this, SLOT( updateWindowList() ) ));
110 QMenu* help = menuBar()->addMenu( tr( "MEN_HELP" ) );
111 menuBar()->addSeparator();
113 QAction* a = new QAction( newIcon, tr( "MEN_NEW" ), this );
\r
114 a->setToolTip( tr( "TBR_NEW" ) );
\r
115 a->setShortcut( Qt::CTRL+Qt::Key_N );
116 verify( connect( a, SIGNAL( activated() ), this, SLOT( onNewDocument() ) ) );
117 myStdActions.insert( FileNewId, a );
\r
118 myStdToolBar->addAction( a );
\r
119 myFilePopup ->addAction( a );
121 a = new QAction( tr( "MEN_QUIT" ), this );
122 a->setShortcut( Qt::CTRL+Qt::Key_Q );
\r
123 a->setToolTip( tr( "TBR_QUIT" ) );
\r
124 verify( connect( a, SIGNAL( activated() ), qApp, SLOT( closeAllWindows() ) ) );
125 myStdActions.insert( FileQuitId, a );
126 myFilePopup ->addAction( a );
\r
128 a = new QAction( tr( "MEN_TOOL_BAR" ), this );
129 a->setToolTip( tr( "TBR_TOOL_BAR" ) );
\r
130 verify( connect( a, SIGNAL( activated() ), this, SLOT( onViewToolBar() ) ) );
131 a->setCheckable(true);
132 a->setChecked( true );
133 myStdActions.insert( ViewToolId, a );
134 view->addAction( a );
\r
136 a = new QAction( tr("MEN_STATUS_BAR"), this );
137 a->setToolTip( tr( "TBR_STATUS_BAR" ) );
\r
138 verify( connect( a, SIGNAL( activated() ), this, SLOT( onViewStatusBar() ) ) );
139 a->setCheckable(true);
140 a->setChecked( true );
141 myStdActions.insert( ViewStatusId, a );
142 view->addAction( a );
\r
144 a = new QAction( helpIcon, tr( "MEN_ABOUT" ), this );
145 a->setShortcut( Qt::Key_F1 );
\r
146 a->setToolTip( tr( "TBR_ABOUT" ) );
\r
147 verify( connect( a, SIGNAL( activated() ) , this, SLOT( onAbout() ) ) );
148 myStdActions.insert( HelpAboutId, a );
149 myStdToolBar->addAction( a );
150 help->addAction( a );
\r
152 myStdToolBar->addSeparator();
154 // Tools menu actions
155 a = new QAction( optimIcon, tr( "MEN_OPTIM" ), this );
156 a->setToolTip( tr( "TBR_OPTIM" ) );
\r
157 verify( connect( a, SIGNAL( toggled(bool) ) , this, SLOT( onToggleOptim(bool) ) ) );
158 a->setCheckable(true);
159 a->setChecked(Graphic3d_ArrayOfPrimitives::IsEnable());
160 myStdActions.insert( OptimId, a );
161 myToolsMenu->addAction( a );
\r
163 a = new QAction( autoIcon, tr( "TBR_AUTO_TEST" ), this );
164 a->setToolTip( tr( "TBR_AUTO_TEST" ) );
\r
165 verify( connect( a, SIGNAL( activated() ) , this, SLOT( onAutoTest() ) ) );
166 myStdActions.insert( AutoTestId, a );
167 myToolsMenu->addAction( a );
\r
169 a = new QAction( stopIcon, tr( "TBR_STOP" ), this );
\r
170 a->setToolTip( tr( "TBR_STOP" ) );
\r
171 verify( connect( a, SIGNAL( activated() ) , this, SLOT( onStop() ) ) );
\r
172 myStdActions.insert( StopId, a );
\r
173 myToolsMenu->addAction( a );
\r
175 // Window menu action
176 a = new QAction( cascadeIcon, tr( "MEN_CASCADE" ), this );
177 verify( connect( a, SIGNAL( activated() ) , myWorkSpace, SLOT( cascade() ) ) );
178 myStdActions.insert( CascadeId, a );
179 myWinMenu->addAction( a );
\r
181 a = new QAction( tileIcon, tr( "MEN_TILE" ), this );
182 verify( connect( a, SIGNAL( activated() ), myWorkSpace, SLOT( tile() ) ) );
183 myStdActions.insert( TileId, a );
184 myWinMenu->addAction( a );
\r
188 void Application::createCCActions()
193 void Application::createIEPopups()
195 myImportPopup = new QMenu( tr( "MEN_FILE_IMPORT" ), this );
197 QAction* a = new QAction( tr( "MEN_IMPORT_BREP" ), this );
\r
198 a->setToolTip( tr( "TBR_IMPORT_BREP" ) );
199 verify( connect( a, SIGNAL( activated() ) , SLOT( onTranslate() ) ) );
200 myCCActions.insert( FileImportBREPId, a );
201 myImportPopup->addAction( a );
204 QWorkspace* Application::getWorkspace()
206 return getApplication()->workspace();
209 Application* Application::getApplication()
214 void Application::updateWindowList()
216 while ( myWinMenu->actions().count() > 2)
217 myWinMenu->removeAction(myWinMenu->actions().last());
219 QWidgetList lst = myWorkSpace->windowList();
222 myWinMenu->addSeparator();
223 for ( int i = 0; i < int(lst.count()); ++i )
225 QAction* a = myWinMenu->addAction( lst.at(i)->windowTitle(),
226 this, SLOT( activateWindow() ) );
\r
227 a->setCheckable( true );
\r
228 a->setChecked( myWorkSpace->activeWindow() == lst.at(i) );
234 void Application::activateWindow()
236 QAction* a = qobject_cast<QAction*>( sender() );
\r
238 int idx = myWinMenu->actions().indexOf( a ) - 3; // tile, cascade and separator
239 QWidget* w = myWorkSpace->windowList().at( idx );
243 // w->setActiveWindow();
247 void Application::updateActions()
249 int count = myFilePopup->actions().count() - 1;
251 int popupCount = menuBar()->actions().count();
252 while (myWinMenu->actions().count() > 2)
253 myWinMenu->removeAction(myWinMenu->actions().last());
255 if( myWorkSpace->windowList().isEmpty() )
257 QAction* optim = myStdActions.at(OptimId);
258 QAction* autoTest = myStdActions.at(AutoTestId);
259 QAction* stop = myStdActions.at(StopId);
\r
261 if( myNbDocuments ) {
262 myFilePopup->insertMenu( myFilePopup->actions().last(), myImportPopup );
263 myFilePopup->insertSeparator( myFilePopup->actions().last() );
265 menuBar()->insertMenu( menuBar()->actions().at( popupCount - 3 ), myToolsMenu );
267 if (optim) myStdToolBar->addAction( optim );
268 if (autoTest) myStdToolBar->addAction( autoTest );
269 if (stop) myStdToolBar->addAction( stop );
\r
270 stop->setEnabled(false);
271 myIsDocuments = true;
274 myFilePopup->actions().removeAt( --count );
275 myFilePopup->actions().removeAt( --count );
276 myFilePopup->actions().removeAt( --count );
278 menuBar()->actions().removeAt( popupCount - 4 );
280 if (optim) myStdToolBar->removeAction( optim );
281 if (autoTest) myStdToolBar->removeAction( autoTest );
282 if (stop) myStdToolBar->removeAction( stop );
283 myIsDocuments = false;
288 Document* Application::onNewDocument()
294 Document* aDoc = new Document( myNbDocuments, this );
295 verify( connect( aDoc, SIGNAL( sendCloseDocument( Document* ) ),
296 SLOT( onCloseDocument( Document* ) ) ) );
301 void Application::onCloseDocument(Document* theDoc)
308 void Application::onTranslate()
310 const QObject* sentBy = sender();
311 typedef void (Translate::*LPFN_IMPORT)
312 ( const Handle( AIS_InteractiveContext ));//, const QString& );
314 static LPFN_IMPORT lpfnImport[] = { &Translate::importBREP };
316 static QAction* actions[] = { myCCActions.at( FileImportBREPId ) };
318 for ( int i = 0; i < sizeof(actions)/sizeof(QAction*); i++ )
320 if ( actions[i] == sentBy )
322 Translate* anTrans = new Translate( 0 );
323 MDIWindow* win = myActiveMDI;//(MDIWindow*) myWorkSpace->activeWindow();
324 Handle(AIS_InteractiveContext) aContext = win->getDocument()->getContext();
328 (anTrans->*lpfnImport[i])( aContext );
330 catch ( Standard_Failure )
332 /* WARNING: an exception raised but we eat it
333 silently because the shape seems OK
337 /* commit transaction */
338 win->activateAction( ViewOperations::ViewFitAllId );
344 void Application::importBREP()
346 Translate* anTrans = new Translate( 0 );
347 MDIWindow* win = myActiveMDI;//(MDIWindow*) myWorkSpace->activeWindow();
348 Handle(AIS_InteractiveContext) aContext = win->getDocument()->getContext();
351 anTrans->importBREP( aContext );
353 catch ( Standard_Failure ) {
354 /* WARNING: an exception raised but we eat it
355 silently because the shape seems OK
359 win->activateAction( ViewOperations::ViewFitAllId );
362 QString Application::getResourceDir()
364 static QString resDir( getenv( "CSF_ResourcesDefaults" ) + QString( "/" ) );
368 void Application::onViewToolBar()
370 bool show = myStdActions.at( ViewToolId )->isChecked();
371 if ( show == myStdToolBar->isVisible() )
374 myStdToolBar->show();
376 myStdToolBar->hide();
379 void Application::onViewStatusBar()
381 bool show = myStdActions.at( ViewStatusId )->isChecked();
382 if ( show == statusBar()->isVisible() )
385 statusBar()->show();
\r
390 void Application::onAbout()
392 QMessageBox::information(this,tr("TIT_ABOUT"),tr("INF_ABOUT"), tr("BTN_OK"),
393 QString::null, QString::null, 0, 0);
396 void Application::onQuit()
399 QWidgetList aList = stWs->windowList();
400 for(MDIWindow* aWindow = (MDIWindow*) aList.first();aWindow;aWindow = (MDIWindow*) aList.next()) {
401 aWindow->closeEvent(0);
408 MDIWindow* Application::getActiveMDI()
413 void Application::onWindowActivated( QWidget* w )
415 if ( w != NULL && w->inherits( "MDIWindow" ) ){
416 myActiveMDI = (MDIWindow*)w;
\r
419 else if (myViewDlg)
\r
421 delete myViewDlg; myViewDlg = NULL;
\r
425 void Application::startTimer()
431 void Application::stopTimer( int count, const char* mes, bool addToGraph, int aOpt )
433 Standard_Integer m,h;
434 Standard_Real fps,elaps,cpu;
436 const char* message = ( mes == NULL ) ? "" : mes;
439 timer.Show( elaps, m, h, cpu );
440 elaps += m * 60. + h * 3600.;
441 fps = Standard_Real( count ) / elaps;
443 sprintf( title, " ====> '%s'. speed is %f frames/second", message, fps );
446 elaps /= count; cpu /= count;
447 sprintf( title, " ====> '%s'. average elapsed/cpu time is %f/%f seconds", message, elaps, cpu );
450 sprintf( title," ====> '%s'. elapsed/cpu time is %f/%f seconds.", message, elaps, cpu );
457 MDIWindow::ResultType type = MDIWindow::Undefined;
458 bool isOptOn = false;
\r
460 isOptOn |= (aOpt > 0);
\r
462 isOptOn = Graphic3d_ArrayOfPrimitives::IsEnable();
\r
464 if (qmes.contains(tr("MES_DISPLAY"), Qt::CaseInsensitive))
465 type = isOptOn ? MDIWindow::DisplayOpt : MDIWindow::DisplayNonOpt;
466 else if (qmes.contains(tr("MES_UPDATE"), Qt::CaseInsensitive))
467 type = isOptOn ? MDIWindow::UpdateOpt : MDIWindow::UpdateNonOpt;
468 if (type != MDIWindow::Undefined)
470 addResult(type, elaps);
474 QString str( title );
475 cout << title << endl;
476 Application::getApplication()->statusBar()->showMessage( str );
477 Application::getApplication()->showMessage( str );
478 //printf("%s\n",title);
481 void Application::showTimer( const char* mes )
483 Standard_Integer m,h;
484 Standard_Real elaps,cpu;
486 const char* message = ( mes == NULL) ? "" : mes;
488 timer.Show( elaps, m, h, cpu );
489 elaps += m * 60. + h * 3600.;
490 sprintf( title," ====> '%s'. elapsed/cpu time is %f/%f seconds", message, elaps, cpu );
492 QString str( title );
493 Application::getApplication()->statusBar()->showMessage( str );
494 Application::getApplication()->showMessage( str );
495 cout << title << endl;
498 void Application::showMessage( QString& message )
501 myOutput->print( message );
505 void Application::onToggleOptim(bool state)
507 state ? Graphic3d_ArrayOfPrimitives::Enable() : Graphic3d_ArrayOfPrimitives::Disable();
510 void Application::addResult(MDIWindow::ResultType item, double value)
512 MDIWindow* activeWin = getApplication()->getActiveMDI();
513 Handle(AIS_InteractiveContext) activeCtx = activeWin->getDocument()->getContext();
515 // Counting triangles...
517 AIS_ListOfInteractive displayedObjs;
518 activeCtx->DisplayedObjects(displayedObjs);
519 AIS_ListIteratorOfListOfInteractive dispIt(displayedObjs);
520 for ( ; dispIt.More(); dispIt.Next())
522 Handle(AIS_InteractiveObject) aisObj = dispIt.Value();
523 if (aisObj->IsKind(STANDARD_TYPE(Sphere_Sphere)))
525 Handle(Sphere_Sphere) sphere = Handle(Sphere_Sphere)::DownCast(aisObj);
526 Standard_Real rad = sphere->Radius();
527 Standard_Real defl = sphere->Sphere_BasicShape::Deflection();
529 nbTriangles += Sphere_Sphere::NbItems(Sphere_Sphere::NbPanes(rad, defl));
531 else if (aisObj->IsKind(STANDARD_TYPE(AIS_Shape)))
533 Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(aisObj);
534 TopoDS_Shape topoShape = shape->Shape();
535 TopExp_Explorer exp(topoShape, TopAbs_FACE);
536 for ( ; exp.More(); exp.Next())
538 TopoDS_Face face = TopoDS::Face(exp.Current());
541 Handle(Poly_Triangulation) triangles =
542 Handle(BRep_TFace)::DownCast(face.TShape())->Triangulation();
543 if (!triangles.IsNull())
545 nbTriangles += triangles->NbTriangles();
551 activeWin->addResult(item, nbTriangles, value);
554 QWorkspace* Application::workspace() const
\r
556 return myWorkSpace;
\r
559 void Application::keyPressEvent(QKeyEvent* e)
561 if (e->key() == Qt::Key_Escape)
565 void Application::onAutoTest()
567 AutoTestDlg autoDlg(getApplication());
568 if (autoDlg.exec() == QDialog::Accepted)
570 QApplication::setOverrideCursor( Qt::WaitCursor );
571 myEscPressed = false;
\r
572 myStopPressed = false;
573 QAction* stop = myStdActions.at(StopId);
\r
575 stop->setEnabled(true);
\r
577 // Define the range for testing
578 int startItems = autoDlg.getStartNbItems();
579 int stopItems = autoDlg.getStopNbItems();
580 int step = autoDlg.getStep();
\r
581 bool isTe = autoDlg.isText();
582 if (stopItems < startItems) stopItems = startItems;
584 Standard_Real radius = 100; // default sphere radius
585 gp_Pnt pos(0, 0, 0); // default sphere center position
587 Handle(AIS_InteractiveContext) ctx = getActiveMDI()->getDocument()->getContext();
589 for (int currItems = startItems; currItems <= stopItems; currItems += step)
591 for (int useOptim = 0; useOptim < 2; useOptim++)
593 qApp->processEvents();
594 if (myEscPressed || myStopPressed)
596 QApplication::restoreOverrideCursor();
\r
597 stop->setEnabled(false);
601 // Toggle optimization
602 useOptim || isTe ? Graphic3d_ArrayOfPrimitives::Enable() : Graphic3d_ArrayOfPrimitives::Disable();
604 // Remove all old objects
605 AIS_ListOfInteractive displayedObjs;
606 ctx->DisplayedObjects(displayedObjs);
607 AIS_ListIteratorOfListOfInteractive dispIt(displayedObjs);
608 for ( ; dispIt.More(); dispIt.Next())
610 Handle(AIS_InteractiveObject) obj = dispIt.Value();
611 if (!obj->IsKind(STANDARD_TYPE(AIS_Trihedron)))
612 ctx->Remove(obj, false);
614 ctx->UpdateCurrentViewer();
\r
616 getActiveMDI()->getView()->SetScale(3.0316);
618 // Generate new sphere
619 Standard_Integer nbPanes = Sphere_Sphere::NbPanes(currItems);
620 Standard_Real deflection = Sphere_Sphere::Deflection(radius, nbPanes);
621 Handle(Sphere_Sphere) sphere = new Sphere_Sphere(pos, radius, deflection,
622 1/*myVNormalsFlag*/, 0/*myVColorsFlag*/, 0/*myVTexelsFlag*/, isTe, useOptim);
624 // Display the sphere
625 ctx->SetDisplayMode( sphere, getActiveMDI()->getDisplayMode(), false );
626 Application::startTimer();
627 ctx->Display( sphere, false );
628 Application::stopTimer( 0, "Display Sphere::Sphere", true, useOptim);
630 qApp->processEvents();
\r
631 if (myEscPressed || myStopPressed)
\r
633 QApplication::restoreOverrideCursor();
\r
634 stop->setEnabled(false);
\r
639 Application::startTimer();
640 getActiveMDI()->getView()->Update();
641 Application::stopTimer( 0, "UPDATE", true, useOptim);
\r
644 QApplication::restoreOverrideCursor();
\r
645 stop->setEnabled(false);
649 /* ------------------ class OutputWindow ----------------- */
650 OutputWindow::OutputWindow( QWidget* parent ) : QWidget( parent ), myLineCounter( 0 )
652 setWindowTitle( "Output window" );
655 QVBoxLayout* topLayout = new QVBoxLayout( this );
656 myLineEdit = new QTextEdit( this );
658 topLayout->addWidget( myLineEdit );
661 OutputWindow::~OutputWindow()
665 void OutputWindow::print( QString& s )
667 myLineEdit->append( QString().setNum( myLineCounter ) + s );
671 void Application::InitApp()
\r
676 void Application::onStop()
\r
678 myStopPressed = true;
\r
681 void Application::onEditViewProperties()
\r
683 if ( !myViewDlg ) {
\r
684 myViewDlg = new ViewDlg(this);
\r
685 verify( connect( myWorkSpace, SIGNAL( windowActivated( QWidget* ) ),
\r
686 myViewDlg, SLOT( Update() ) ) );
\r
688 myViewDlg->raise();
\r
692 void Application::updateViewDlg()
\r
694 if(myViewDlg) myViewDlg->Update();
\r