#include "Translate.h" #include "Application.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // ---------------------------- TranslateDlg ----------------------------------------- class TranslateDlg : public QFileDialog { public: TranslateDlg( QWidget* = 0, Qt::WindowFlags flags = 0, bool = true ); ~TranslateDlg(); int getMode() const; void setMode( const int ); void addMode( const int, const QString& ); void clear(); protected: void showEvent ( QShowEvent* event ); private: QListView* findListView( const QObjectList& ); private: QComboBox* myBox; QList myList; }; TranslateDlg::TranslateDlg( QWidget* parent, Qt::WindowFlags flags, bool modal ) : QFileDialog( parent, flags ) { setOption( QFileDialog::DontUseNativeDialog ); setModal( modal ); QGridLayout* grid = ::qobject_cast( layout() ); if( grid ) { QVBoxLayout *vbox = new QVBoxLayout; QWidget* paramGroup = new QWidget( this ); paramGroup->setLayout( vbox ); myBox = new QComboBox( paramGroup ); vbox->addWidget( myBox ); int row = grid->rowCount(); grid->addWidget( paramGroup, row, 1, 1, 3 ); // make combobox occupy 1 row and 3 columns starting from 1 } } TranslateDlg::~TranslateDlg() { } int TranslateDlg::getMode() const { if ( myBox->currentIndex() < 0 || myBox->currentIndex() > (int)myList.count() - 1 ) return -1; else return myList.at( myBox->currentIndex() ); } void TranslateDlg::setMode( const int mode ) { int idx = myList.indexOf( mode ); if ( idx >= 0 ) myBox->setCurrentIndex( idx ); } void TranslateDlg::addMode( const int mode, const QString& name ) { myBox->show(); myBox->addItem( name ); myList.append( mode ); myBox->updateGeometry(); updateGeometry(); } void TranslateDlg::clear() { myList.clear(); myBox->clear(); myBox->hide(); myBox->updateGeometry(); updateGeometry(); } QListView* TranslateDlg::findListView( const QObjectList & childList ) { QListView* listView = 0; for ( int i = 0, n = childList.count(); i < n && !listView; i++ ) { listView = qobject_cast( childList.at( i ) ); if ( !listView && childList.at( i ) ) { listView = findListView( childList.at( i )->children() ); } } return listView; } void TranslateDlg::showEvent ( QShowEvent* event ) { QFileDialog::showEvent ( event ); QListView* aListView = findListView( children() ); aListView->setViewMode( QListView::ListMode ); } // ---------------------------- Translate ----------------------------------------- Translate::Translate( QObject* parent ) : QObject( parent ), myDlg( 0 ) { } Translate::~Translate() { if ( myDlg ) delete myDlg; } QString Translate::info() const { return myInfo; } bool Translate::importModel( const int format, const Handle(AIS_InteractiveContext)& ic ) { myInfo = QString(); QString fileName = selectFileName( format, true ); if ( fileName.isEmpty() ) return true; if ( !QFileInfo( fileName ).exists() ) { myInfo = QObject::tr( "INF_TRANSLATE_FILENOTFOUND" ).arg( fileName ); return false; } QApplication::setOverrideCursor( Qt::WaitCursor ); Handle(TopTools_HSequenceOfShape) shapes = importModel( format, fileName ); QApplication::restoreOverrideCursor(); return displayShSequence(ic, shapes); } bool Translate::displayShSequence(const Handle(AIS_InteractiveContext)& ic, const Handle(TopTools_HSequenceOfShape)& shapes ) { if ( shapes.IsNull() || !shapes->Length() ) return false; for ( int i = 1; i <= shapes->Length(); i++ ) ic->Display( new AIS_Shape( shapes->Value( i ) ), false ); ic->UpdateCurrentViewer(); return true; } Handle(TopTools_HSequenceOfShape) Translate::importModel( const int format, const QString& file ) { Handle(TopTools_HSequenceOfShape) shapes; try { switch ( format ) { case FormatBREP: shapes = importBREP( file ); break; case FormatIGES: shapes = importIGES( file ); break; case FormatSTEP: shapes = importSTEP( file ); break; } } catch ( Standard_Failure ) { shapes.Nullify(); } return shapes; } bool Translate::exportModel( const int format, const Handle(AIS_InteractiveContext)& ic ) { myInfo = QString(); QString fileName = selectFileName( format, false ); if ( fileName.isEmpty() ) return true; Handle(TopTools_HSequenceOfShape) shapes = getShapes( ic ); if ( shapes.IsNull() || !shapes->Length() ) return false; QApplication::setOverrideCursor( Qt::WaitCursor ); bool stat = exportModel( format, fileName, shapes ); QApplication::restoreOverrideCursor(); return stat; } bool Translate::exportModel( const int format, const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes ) { try { switch ( format ) { case FormatBREP: return exportBREP( file, shapes ); case FormatIGES: return exportIGES( file, shapes ); case FormatSTEP: return exportSTEP( file, shapes ); case FormatSTL: return exportSTL ( file, shapes ); case FormatVRML: return exportVRML( file, shapes ); } } catch ( Standard_Failure ) { // } return false; } Handle(TopTools_HSequenceOfShape) Translate::getShapes( const Handle(AIS_InteractiveContext)& ic ) { Handle(TopTools_HSequenceOfShape) aSequence; Handle(AIS_InteractiveObject) picked; for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() ) { Handle(AIS_InteractiveObject) obj = ic->SelectedInteractive(); if ( obj->IsKind( STANDARD_TYPE( AIS_Shape ) ) ) { TopoDS_Shape shape = Handle(AIS_Shape)::DownCast(obj)->Shape(); if ( aSequence.IsNull() ) aSequence = new TopTools_HSequenceOfShape(); aSequence->Append( shape ); } } return aSequence; } /*! Selects a file from standard dialog according to selection 'filter' */ QString Translate::selectFileName( const int format, const bool import ) { TranslateDlg* theDlg = getDialog( format, import ); int ret = theDlg->exec(); qApp->processEvents(); QString file; QStringList fileNames; if ( ret != QDialog::Accepted ) return file; fileNames = theDlg->selectedFiles(); if (!fileNames.isEmpty()) file = fileNames[0]; if ( !QFileInfo( file ).completeSuffix().length() ) { QString selFilter = theDlg->selectedNameFilter(); int idx = selFilter.indexOf( "(*." ); if ( idx != -1 ) { QString tail = selFilter.mid( idx + 3 ); idx = tail.indexOf( " " ); if ( idx == -1 ) idx = tail.indexOf( ")" ); QString ext = tail.left( idx ); if ( ext.length() ) file += QString( "." ) + ext; } } return file; } TranslateDlg* Translate::getDialog( const int format, const bool import ) { if ( !myDlg ) myDlg = new TranslateDlg( 0, 0, true ); if ( format < 0 ) return myDlg; QString formatFilter = QObject::tr( QString( "INF_FILTER_FORMAT_%1" ).arg( format ).toLatin1().constData() ); QString allFilter = QObject::tr( "INF_FILTER_FORMAT_ALL" ); QString filter; filter.append( formatFilter ); filter.append( "\t" ); if ( import ) { filter.append( allFilter ); filter.append( "\t" ); } std::cout << filter.toLatin1().constData() << std::endl; QStringList filters = filter.split( "\t" ); myDlg->setNameFilters ( filters ); if ( import ) { myDlg->setWindowTitle( QObject::tr( "INF_APP_IMPORT" ) ); ((QFileDialog*)myDlg)->setFileMode( QFileDialog::ExistingFile ); } else { myDlg->setWindowTitle( QObject::tr( "INF_APP_EXPORT" ) ); ((QFileDialog*)myDlg)->setFileMode( QFileDialog::AnyFile ); } myDlg->clear(); if ( !import ) { switch ( format ) { case FormatSTEP: myDlg->addMode( STEPControl_ManifoldSolidBrep, QObject::tr( "INF_BREP_MOIFOLD" ) ); myDlg->addMode( STEPControl_FacetedBrep, QObject::tr( "INF_BREP_FACETED" ) ); myDlg->addMode( STEPControl_ShellBasedSurfaceModel, QObject::tr( "INF_BREP_SHELL" ) ); myDlg->addMode( STEPControl_GeometricCurveSet, QObject::tr( "INF_BREP_CURVE" ) ); break; } } return myDlg; } // ----------------------------- Import functionality ----------------------------- Handle(TopTools_HSequenceOfShape) Translate::importBREP( const QString& file ) { Handle(TopTools_HSequenceOfShape) aSequence; TopoDS_Shape aShape; BRep_Builder aBuilder; TCollection_AsciiString aFilePath = file.toUtf8().data(); Standard_Boolean result = BRepTools::Read( aShape, aFilePath.ToCString(), aBuilder ); if ( result ) { aSequence = new TopTools_HSequenceOfShape(); aSequence->Append( aShape ); } return aSequence; } Handle(TopTools_HSequenceOfShape) Translate::importIGES( const QString& file ) { Handle(TopTools_HSequenceOfShape) aSequence; TCollection_AsciiString aFilePath = file.toUtf8().data(); IGESControl_Reader Reader; int status = Reader.ReadFile(aFilePath.ToCString() ); if ( status == IFSelect_RetDone ) { aSequence = new TopTools_HSequenceOfShape(); Reader.TransferRoots(); TopoDS_Shape aShape = Reader.OneShape(); aSequence->Append( aShape ); } return aSequence; } Handle(TopTools_HSequenceOfShape) Translate::importSTEP( const QString& file ) { Handle(TopTools_HSequenceOfShape) aSequence = new TopTools_HSequenceOfShape; TCollection_AsciiString aFilePath = file.toUtf8().data(); STEPControl_Reader aReader; IFSelect_ReturnStatus status = aReader.ReadFile( aFilePath.ToCString() ); if ( status != IFSelect_RetDone ) { return aSequence; } //Interface_TraceFile::SetDefault(); bool failsonly = false; aReader.PrintCheckLoad( failsonly, IFSelect_ItemsByEntity ); int nbr = aReader.NbRootsForTransfer(); aReader.PrintCheckTransfer( failsonly, IFSelect_ItemsByEntity ); for ( Standard_Integer n = 1; n <= nbr; n++ ) { aReader.TransferRoot( n ); } int nbs = aReader.NbShapes(); if ( nbs > 0 ) { for ( int i = 1; i <= nbs; i++ ) { TopoDS_Shape shape = aReader.Shape( i ); aSequence->Append( shape ); } } return aSequence; } // ----------------------------- Export functionality ----------------------------- bool Translate::exportBREP( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes ) { if ( shapes.IsNull() || shapes->IsEmpty() ) return false; TopoDS_Shape shape = shapes->Value( 1 ); const TCollection_AsciiString anUtf8Path (file.toUtf8().data()); return BRepTools::Write( shape, anUtf8Path.ToCString() ); } bool Translate::exportIGES( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes ) { if ( shapes.IsNull() || shapes->IsEmpty() ) return false; IGESControl_Controller::Init(); IGESControl_Writer writer( Interface_Static::CVal( "XSTEP.iges.unit" ), Interface_Static::IVal( "XSTEP.iges.writebrep.mode" ) ); for ( int i = 1; i <= shapes->Length(); i++ ) writer.AddShape ( shapes->Value( i ) ); writer.ComputeModel(); const TCollection_AsciiString anUtf8Path (file.toUtf8().data()); return writer.Write( anUtf8Path.ToCString() ); } bool Translate::exportSTEP( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes ) { if ( shapes.IsNull() || shapes->IsEmpty() ) return false; TranslateDlg* theDlg = getDialog( -1, false ); STEPControl_StepModelType type = (STEPControl_StepModelType)theDlg->getMode(); if ( type < 0 ) return false; IFSelect_ReturnStatus status; if ( type == STEPControl_FacetedBrep && !checkFacetedBrep( shapes ) ) { myInfo = QObject::tr( "INF_FACET_ERROR" ); return false; } STEPControl_Writer writer; for ( int i = 1; i <= shapes->Length(); i++ ) { status = writer.Transfer( shapes->Value( i ), type ); if ( status != IFSelect_RetDone ) return false; } const TCollection_AsciiString anUtf8Path (file.toUtf8().data()); status = writer.Write( anUtf8Path.ToCString() ); switch ( status ) { case IFSelect_RetError: myInfo = QObject::tr( "INF_DATA_ERROR" ); break; case IFSelect_RetFail: myInfo = QObject::tr( "INF_WRITING_ERROR" ); break; case IFSelect_RetVoid: myInfo = QObject::tr( "INF_NOTHING_ERROR" ); break; case IFSelect_RetStop: case IFSelect_RetDone: break; } return status == IFSelect_RetDone; } bool Translate::exportSTL( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes ) { if ( shapes.IsNull() || shapes->IsEmpty() ) return false; TopoDS_Compound res; BRep_Builder builder; builder.MakeCompound( res ); for ( int i = 1; i <= shapes->Length(); i++ ) { TopoDS_Shape shape = shapes->Value( i ); if ( shape.IsNull() ) { myInfo = QObject::tr( "INF_TRANSLATE_ERROR_INVALIDSHAPE" ); return false; } builder.Add( res, shape ); } StlAPI_Writer writer; const TCollection_AsciiString anUtf8Path (file.toUtf8().data()); writer.Write( res, anUtf8Path.ToCString() ); return true; } bool Translate::exportVRML( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes ) { if ( shapes.IsNull() || shapes->IsEmpty() ) return false; TopoDS_Compound res; BRep_Builder builder; builder.MakeCompound( res ); for ( int i = 1; i <= shapes->Length(); i++ ) { TopoDS_Shape shape = shapes->Value( i ); if ( shape.IsNull() ) { myInfo = QObject::tr( "INF_TRANSLATE_ERROR_INVALIDSHAPE" ); return false; } builder.Add( res, shape ); } VrmlAPI_Writer writer; const TCollection_AsciiString anUtf8Path (file.toUtf8().data()); writer.Write( res, anUtf8Path.ToCString() ); return true; } bool Translate::checkFacetedBrep( const Handle(TopTools_HSequenceOfShape)& shapes ) { bool err = false; for ( int i = 1; i <= shapes->Length(); i++ ) { TopoDS_Shape shape = shapes->Value( i ); for ( TopExp_Explorer fexp( shape, TopAbs_FACE ); fexp.More() && !err; fexp.Next() ) { Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face( fexp.Current() ) ); if ( !surface->IsKind( STANDARD_TYPE( Geom_Plane ) ) ) err = true; } for ( TopExp_Explorer eexp( shape, TopAbs_EDGE ); eexp.More() && !err; eexp.Next() ) { Standard_Real fd, ld; Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( eexp.Current() ), fd, ld ); if ( !curve->IsKind( STANDARD_TYPE( Geom_Line ) ) ) err = true; } } return !err; }