0026723: Qt IE sample can not import STEP and IGES files with names containing not...
[occt.git] / samples / qt / Interface / src / Translate.cxx
CommitLineData
7fd59977 1#include "Translate.h"
2
3#include "Application.h"
4
5#include <QDir>
6#include <QLayout>
7#include <QComboBox>
8#include <QGroupBox>
9#include <QList>
10#include <QListView>
11#include <QFileDialog>
12#include <QApplication>
13#include <QWidget>
861a7b03 14#include <QStyleFactory>
7fd59977 15
16#include <AIS_Shape.hxx>
17#include <AIS_InteractiveObject.hxx>
18
19#include <FSD_File.hxx>
20
7fd59977 21#include <IGESControl_Reader.hxx>
22#include <IGESControl_Writer.hxx>
23#include <IGESControl_Controller.hxx>
24#include <STEPControl_Reader.hxx>
25#include <STEPControl_Writer.hxx>
26#include <STEPControl_StepModelType.hxx>
27#include <Interface_Static.hxx>
28//#include <Interface_TraceFile.hxx>
29
30#include <StlAPI_Writer.hxx>
31#include <VrmlAPI_Writer.hxx>
32
7fd59977 33#include <BRepTools.hxx>
34#include <BRep_Tool.hxx>
35#include <BRep_Builder.hxx>
36
37#include <TopoDS.hxx>
38#include <TopoDS_Shape.hxx>
39#include <TopoDS_Compound.hxx>
40#include <TopExp_Explorer.hxx>
41#include <TopTools_HSequenceOfShape.hxx>
42
43#include <Geom_Line.hxx>
44#include <Geom_Curve.hxx>
45#include <Geom_Plane.hxx>
46#include <Geom_Surface.hxx>
47
48
49#include <Standard_ErrorHandler.hxx>
50#include <Standard_CString.hxx>
51
52// ---------------------------- TranslateDlg -----------------------------------------
53
54class TranslateDlg : public QFileDialog
55{
56public:
57 TranslateDlg( QWidget* = 0, Qt::WindowFlags flags = 0, bool = true );
58 ~TranslateDlg();
59 int getMode() const;
60 void setMode( const int );
61 void addMode( const int, const QString& );
62 void clear();
63
64protected:
65 void showEvent ( QShowEvent* event );
66
67private:
68 QListView* findListView( const QObjectList& );
69
70private:
71 QComboBox* myBox;
72 QList<int> myList;
73};
74
75TranslateDlg::TranslateDlg( QWidget* parent, Qt::WindowFlags flags, bool modal )
76: QFileDialog( parent, flags )
77{
861a7b03 78 setOption( QFileDialog::DontUseNativeDialog );
7fd59977 79 setModal( modal );
861a7b03 80
7fd59977 81 QGridLayout* grid = ::qobject_cast<QGridLayout*>( layout() );
82
83 if( grid )
84 {
85 QVBoxLayout *vbox = new QVBoxLayout;
86
87 QWidget* paramGroup = new QWidget( this );
88 paramGroup->setLayout( vbox );
89
90 myBox = new QComboBox( paramGroup );
91 vbox->addWidget( myBox );
92
93 int row = grid->rowCount();
94 grid->addWidget( paramGroup, row, 1, 1, 3 ); // make combobox occupy 1 row and 3 columns starting from 1
95 }
96}
97
98TranslateDlg::~TranslateDlg()
99{
100}
101
102int TranslateDlg::getMode() const
103{
104 if ( myBox->currentIndex() < 0 || myBox->currentIndex() > (int)myList.count() - 1 )
105 return -1;
106 else
107 return myList.at( myBox->currentIndex() );
108}
109
110void TranslateDlg::setMode( const int mode )
111{
112 int idx = myList.indexOf( mode );
113 if ( idx >= 0 )
114 myBox->setCurrentIndex( idx );
115}
116
117void TranslateDlg::addMode( const int mode, const QString& name )
118{
119 myBox->show();
120 myBox->addItem( name );
121 myList.append( mode );
122 myBox->updateGeometry();
123 updateGeometry();
124}
125
126void TranslateDlg::clear()
127{
128 myList.clear();
129 myBox->clear();
130 myBox->hide();
131 myBox->updateGeometry();
132 updateGeometry();
133}
134
135QListView* TranslateDlg::findListView( const QObjectList & childList )
136{
137 QListView* listView = 0;
138 for ( int i = 0, n = childList.count(); i < n && !listView; i++ )
139 {
140 listView = qobject_cast<QListView*>( childList.at( i ) );
141 if ( !listView && childList.at( i ) )
142 {
143 listView = findListView( childList.at( i )->children() );
144 }
145 }
146 return listView;
147}
148
149void TranslateDlg::showEvent ( QShowEvent* event )
150{
151 QFileDialog::showEvent ( event );
152 QListView* aListView = findListView( children() );
153 aListView->setViewMode( QListView::ListMode );
154}
155
156
157// ---------------------------- Translate -----------------------------------------
158
159Translate::Translate( QObject* parent )
160: QObject( parent ),
161myDlg( 0 )
162{
163}
164
165Translate::~Translate()
166{
167 if ( myDlg )
168 delete myDlg;
169}
170
171QString Translate::info() const
172{
173 return myInfo;
174}
175
176bool Translate::importModel( const int format, const Handle(AIS_InteractiveContext)& ic )
177{
178 myInfo = QString();
179 QString fileName = selectFileName( format, true );
180 if ( fileName.isEmpty() )
181 return true;
182
183 if ( !QFileInfo( fileName ).exists() )
184 {
185 myInfo = QObject::tr( "INF_TRANSLATE_FILENOTFOUND" ).arg( fileName );
186 return false;
187 }
188
189 QApplication::setOverrideCursor( Qt::WaitCursor );
190 Handle(TopTools_HSequenceOfShape) shapes = importModel( format, fileName );
191 QApplication::restoreOverrideCursor();
192
193 return displayShSequence(ic, shapes);
194}
195
196bool Translate::displayShSequence(const Handle(AIS_InteractiveContext)& ic,
197 const Handle(TopTools_HSequenceOfShape)& shapes )
198{
199 if ( shapes.IsNull() || !shapes->Length() )
200 return false;
201
202 for ( int i = 1; i <= shapes->Length(); i++ )
203 ic->Display( new AIS_Shape( shapes->Value( i ) ), false );
204 ic->UpdateCurrentViewer();
205 return true;
206}
207
208Handle(TopTools_HSequenceOfShape) Translate::importModel( const int format, const QString& file )
209{
210 Handle(TopTools_HSequenceOfShape) shapes;
211 try {
212 switch ( format )
213 {
214 case FormatBREP:
215 shapes = importBREP( file );
216 break;
217 case FormatIGES:
218 shapes = importIGES( file );
219 break;
220 case FormatSTEP:
221 shapes = importSTEP( file );
222 break;
7fd59977 223 }
224 } catch ( Standard_Failure ) {
225 shapes.Nullify();
226 }
227 return shapes;
228}
229
230bool Translate::exportModel( const int format, const Handle(AIS_InteractiveContext)& ic )
231{
232 myInfo = QString();
233 QString fileName = selectFileName( format, false );
234 if ( fileName.isEmpty() )
235 return true;
236
237 Handle(TopTools_HSequenceOfShape) shapes = getShapes( ic );
238 if ( shapes.IsNull() || !shapes->Length() )
239 return false;
240
241 QApplication::setOverrideCursor( Qt::WaitCursor );
242 bool stat = exportModel( format, fileName, shapes );
243 QApplication::restoreOverrideCursor();
244
245 return stat;
246}
247
248bool Translate::exportModel( const int format, const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
249{
250 bool status;
251 try {
252 switch ( format )
253 {
254 case FormatBREP:
255 status = exportBREP( file, shapes );
256 break;
257 case FormatIGES:
258 status = exportIGES( file, shapes );
259 break;
260 case FormatSTEP:
261 status = exportSTEP( file, shapes );
262 break;
7fd59977 263 case FormatSTL:
264 status = exportSTL( file, shapes );
265 break;
266 case FormatVRML:
267 status = exportVRML( file, shapes );
268 break;
269 }
270 } catch ( Standard_Failure ) {
271 status = false;
272 }
273 return status;
274}
275
276Handle(TopTools_HSequenceOfShape) Translate::getShapes( const Handle(AIS_InteractiveContext)& ic )
277{
278 Handle(TopTools_HSequenceOfShape) aSequence;
279 Handle(AIS_InteractiveObject) picked;
280 for ( ic->InitCurrent(); ic->MoreCurrent(); ic->NextCurrent() )
281 {
282 Handle(AIS_InteractiveObject) obj = ic->Current();
283 if ( obj->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
284 {
285 TopoDS_Shape shape = Handle(AIS_Shape)::DownCast(obj)->Shape();
286 if ( aSequence.IsNull() )
287 aSequence = new TopTools_HSequenceOfShape();
288 aSequence->Append( shape );
289 }
290 }
291 return aSequence;
292}
293
294/*!
295 Selects a file from standard dialog acoording to selection 'filter'
296*/
297QString Translate::selectFileName( const int format, const bool import )
298{
299 TranslateDlg* theDlg = getDialog( format, import );
300
301 int ret = theDlg->exec();
302
303 qApp->processEvents();
304
305 QString file;
306 QStringList fileNames;
307 if ( ret != QDialog::Accepted )
308 return file;
309
310 fileNames = theDlg->selectedFiles();
311 if (!fileNames.isEmpty())
312 file = fileNames[0];
313
314 if ( !QFileInfo( file ).completeSuffix().length() )
315 {
861a7b03 316 QString selFilter = theDlg->selectedNameFilter();
7fd59977 317 int idx = selFilter.indexOf( "(*." );
318 if ( idx != -1 )
319 {
320 QString tail = selFilter.mid( idx + 3 );
321 int idx = tail.indexOf( " " );
322 if ( idx == -1 )
323 idx = tail.indexOf( ")" );
324 QString ext = tail.left( idx );
325 if ( ext.length() )
326 file += QString( "." ) + ext;
327 }
328 }
329
330 return file;
331}
332
333TranslateDlg* Translate::getDialog( const int format, const bool import )
334{
335 if ( !myDlg )
336 myDlg = new TranslateDlg( 0, 0, true );
337
338 if ( format < 0 )
339 return myDlg;
340
341 QString formatFilter = QObject::tr( QString( "INF_FILTER_FORMAT_%1" ).arg( format ).toLatin1().constData() );
342 QString allFilter = QObject::tr( "INF_FILTER_FORMAT_ALL" );
343
344 QString filter;
345 filter.append( formatFilter );
346 filter.append( "\t" );
347
348 if ( import )
349 {
350 filter.append( allFilter );
351 filter.append( "\t" );
352 }
353
354 cout << filter.toLatin1().constData() << endl;
355 QStringList filters = filter.split( "\t" );
861a7b03 356 myDlg->setNameFilters ( filters );
7fd59977 357
358 if ( import )
359 {
360 myDlg->setWindowTitle( QObject::tr( "INF_APP_IMPORT" ) );
361 ((QFileDialog*)myDlg)->setFileMode( QFileDialog::ExistingFile );
362 }
363 else
364 {
365 myDlg->setWindowTitle( QObject::tr( "INF_APP_EXPORT" ) );
366 ((QFileDialog*)myDlg)->setFileMode( QFileDialog::AnyFile );
367 }
368
861a7b03 369 QString datadir = (QString (qgetenv ("CASROOT").constData()) + QObject::tr( QString("INF_PATH_%1").arg( format ).toLatin1().constData() ) );
7fd59977 370
371 myDlg->clear();
372
373 if ( !import )
374 {
375 switch ( format )
376 {
377 case FormatSTEP:
378 myDlg->addMode( STEPControl_ManifoldSolidBrep, QObject::tr( "INF_BREP_MOIFOLD" ) );
379 myDlg->addMode( STEPControl_FacetedBrep, QObject::tr( "INF_BREP_FACETED" ) );
380 myDlg->addMode( STEPControl_ShellBasedSurfaceModel, QObject::tr( "INF_BREP_SHELL" ) );
381 myDlg->addMode( STEPControl_GeometricCurveSet, QObject::tr( "INF_BREP_CURVE" ) );
382 break;
7fd59977 383 }
384 }
385
386 return myDlg;
387}
388
389// ----------------------------- Import functionality -----------------------------
390
391Handle(TopTools_HSequenceOfShape) Translate::importBREP( const QString& file )
392{
393 Handle(TopTools_HSequenceOfShape) aSequence;
394 TopoDS_Shape aShape;
395 BRep_Builder aBuilder;
90c8c7f3 396 TCollection_AsciiString aFilePath = file.toUtf8().data();
397 Standard_Boolean result = BRepTools::Read( aShape, aFilePath.ToCString(), aBuilder );
7fd59977 398 if ( result )
399 {
400 aSequence = new TopTools_HSequenceOfShape();
401 aSequence->Append( aShape );
402 }
403 return aSequence;
404}
405
406Handle(TopTools_HSequenceOfShape) Translate::importIGES( const QString& file )
407{
408 Handle(TopTools_HSequenceOfShape) aSequence;
90c8c7f3 409 TCollection_AsciiString aFilePath = file.toUtf8().data();
410
7fd59977 411 IGESControl_Reader Reader;
90c8c7f3 412 int status = Reader.ReadFile(aFilePath.ToCString() );
7fd59977 413
414 if ( status == IFSelect_RetDone )
415 {
416 aSequence = new TopTools_HSequenceOfShape();
417 Reader.TransferRoots();
418 TopoDS_Shape aShape = Reader.OneShape();
419 aSequence->Append( aShape );
420 }
421 return aSequence;
422}
423
424Handle(TopTools_HSequenceOfShape) Translate::importSTEP( const QString& file )
425{
426 Handle(TopTools_HSequenceOfShape) aSequence;
90c8c7f3 427 TCollection_AsciiString aFilePath = file.toUtf8().data();
7fd59977 428 STEPControl_Reader aReader;
90c8c7f3 429 IFSelect_ReturnStatus status = aReader.ReadFile( aFilePath.ToCString() );
7fd59977 430 if ( status == IFSelect_RetDone )
431 {
432 //Interface_TraceFile::SetDefault();
433 bool failsonly = false;
434 aReader.PrintCheckLoad( failsonly, IFSelect_ItemsByEntity );
435
436 int nbr = aReader.NbRootsForTransfer();
437 aReader.PrintCheckTransfer( failsonly, IFSelect_ItemsByEntity );
438 for ( Standard_Integer n = 1; n <= nbr; n++ )
439 {
440 bool ok = aReader.TransferRoot( n );
441 int nbs = aReader.NbShapes();
861a7b03 442 if ( ok == true && nbs > 0 )
7fd59977 443 {
444 aSequence = new TopTools_HSequenceOfShape();
445 for ( int i = 1; i <= nbs; i++ )
446 {
447 TopoDS_Shape shape = aReader.Shape( i );
448 aSequence->Append( shape );
449 }
450 }
451 }
452 }
453 return aSequence;
454}
455
7fd59977 456// ----------------------------- Export functionality -----------------------------
457
458bool Translate::exportBREP( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
459{
460 if ( shapes.IsNull() || shapes->IsEmpty() )
461 return false;
462
463 TopoDS_Shape shape = shapes->Value( 1 );
464 return BRepTools::Write( shape, (Standard_CString)file.toLatin1().constData() );
465}
466
467bool Translate::exportIGES( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
468{
469 if ( shapes.IsNull() || shapes->IsEmpty() )
470 return false;
471
472 IGESControl_Controller::Init();
473 IGESControl_Writer writer( Interface_Static::CVal( "XSTEP.iges.unit" ),
474 Interface_Static::IVal( "XSTEP.iges.writebrep.mode" ) );
475
476 for ( int i = 1; i <= shapes->Length(); i++ )
477 writer.AddShape ( shapes->Value( i ) );
478 writer.ComputeModel();
479 return writer.Write( (Standard_CString)file.toLatin1().constData() );
480}
481
482bool Translate::exportSTEP( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
483{
484 if ( shapes.IsNull() || shapes->IsEmpty() )
485 return false;
486
487 TranslateDlg* theDlg = getDialog( -1, false );
488 STEPControl_StepModelType type = (STEPControl_StepModelType)theDlg->getMode();
489 if ( type < 0 )
490 return false;
491
492 IFSelect_ReturnStatus status;
493
494 if ( type == STEPControl_FacetedBrep && !checkFacetedBrep( shapes ) )
495 {
496 myInfo = QObject::tr( "INF_FACET_ERROR" );
497 return false;
498 }
499
500 STEPControl_Writer writer;
501 for ( int i = 1; i <= shapes->Length(); i++ )
502 {
503 status = writer.Transfer( shapes->Value( i ), type );
504 if ( status != IFSelect_RetDone )
505 return false;
506 }
507
508 status = writer.Write( (Standard_CString)file.toLatin1().constData() );
509
510 switch ( status )
511 {
512 case IFSelect_RetError:
513 myInfo = QObject::tr( "INF_DATA_ERROR" );
514 break;
515 case IFSelect_RetFail:
516 myInfo = QObject::tr( "INF_WRITING_ERROR" );
517 break;
518 case IFSelect_RetVoid:
519 myInfo = QObject::tr( "INF_NOTHING_ERROR" );
520 break;
521 }
522 return status == IFSelect_RetDone;
523}
524
7fd59977 525bool Translate::exportSTL( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
526{
527 if ( shapes.IsNull() || shapes->IsEmpty() )
528 return false;
529
530 TopoDS_Compound res;
531 BRep_Builder builder;
532 builder.MakeCompound( res );
533
534 for ( int i = 1; i <= shapes->Length(); i++ )
535 {
536 TopoDS_Shape shape = shapes->Value( i );
537 if ( shape.IsNull() )
538 {
539 myInfo = QObject::tr( "INF_TRANSLATE_ERROR_INVALIDSHAPE" );
540 return false;
541 }
542 builder.Add( res, shape );
543 }
544
545 StlAPI_Writer writer;
546 writer.Write( res, (Standard_CString)file.toLatin1().constData() );
547
548 return true;
549}
550
551bool Translate::exportVRML( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
552{
553 if ( shapes.IsNull() || shapes->IsEmpty() )
554 return false;
555
556 TopoDS_Compound res;
557 BRep_Builder builder;
558 builder.MakeCompound( res );
559
560 for ( int i = 1; i <= shapes->Length(); i++ )
561 {
562 TopoDS_Shape shape = shapes->Value( i );
563 if ( shape.IsNull() )
564 {
565 myInfo = QObject::tr( "INF_TRANSLATE_ERROR_INVALIDSHAPE" );
566 return false;
567 }
568 builder.Add( res, shape );
569 }
570
571 VrmlAPI_Writer writer;
572 writer.Write( res, (Standard_CString)file.toLatin1().constData() );
573
574 return true;
575}
576
577bool Translate::checkFacetedBrep( const Handle(TopTools_HSequenceOfShape)& shapes )
578{
579 bool err = false;
580 for ( int i = 1; i <= shapes->Length(); i++ )
581 {
582 TopoDS_Shape shape = shapes->Value( i );
583 for ( TopExp_Explorer fexp( shape, TopAbs_FACE ); fexp.More() && !err; fexp.Next() )
584 {
585 Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face( fexp.Current() ) );
586 if ( !surface->IsKind( STANDARD_TYPE( Geom_Plane ) ) )
587 err = true;
588 }
589 for ( TopExp_Explorer eexp( shape, TopAbs_EDGE ); eexp.More() && !err; eexp.Next() )
590 {
591 Standard_Real fd, ld;
592 Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( eexp.Current() ), fd, ld );
593 if ( !curve->IsKind( STANDARD_TYPE( Geom_Line ) ) )
594 err = true;
595 }
596 }
597 return !err;
598}
599
600
601