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