00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 #include <QtGui/QApplication>
00037 
00038 #include <StlMesh_Mesh.hxx>
00039 #include <RWStl.hxx>
00040 #include <OSD_Path.hxx>
00041 #include <MeshVS_Mesh.hxx>
00042 #include <MeshVS_Drawer.hxx>
00043 #include <MeshVS_DrawerAttribute.hxx>
00044 #include <MeshVS_MeshPrsBuilder.hxx>
00045 #include <XSDRAWSTLVRML_DataSource.hxx>
00046 #include <Graphic3d_MaterialAspect.hxx>
00047 
00048 #include "qoccinputoutput.h"
00049 #include "qoccinternal.h"
00050 
00051 QoccInputOutput::QoccInputOutput(void)
00052 {
00053 }
00054 
00055 QoccInputOutput::~QoccInputOutput(void)
00056 {
00057 }
00058 
00059 bool QoccInputOutput::importMesh( const QString& fileName,
00060                                                                   const FileFormat format,
00061                                                                   const Handle(AIS_InteractiveContext)& ic )
00062 {
00063          
00064          Q_UNUSED(format);
00065          OSD_Path thePath(fileName.toAscii().data());
00066          Handle( StlMesh_Mesh ) aSTLMesh = RWStl::ReadFile(thePath);
00067      Handle( MeshVS_Mesh  ) aMesh = new MeshVS_Mesh();
00068      Handle( XSDRAWSTLVRML_DataSource ) aDS = new XSDRAWSTLVRML_DataSource( aSTLMesh );
00069 
00070      aMesh->SetDataSource(aDS);
00071      aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh), Standard_True );
00072 
00073      aMesh->GetDrawer()->SetBoolean(MeshVS_DA_DisplayNodes,Standard_False); 
00074      aMesh->GetDrawer()->SetBoolean(MeshVS_DA_ShowEdges,Standard_False);
00075      aMesh->GetDrawer()->SetMaterial(MeshVS_DA_FrontMaterial,Graphic3d_NOM_BRASS);
00076 
00077 
00078      aMesh->SetColor(Quantity_NOC_AZURE);
00079      aMesh->SetDisplayMode( MeshVS_DMF_Shading ); 
00080      aMesh->SetHilightMode( MeshVS_DMF_WireFrame ); 
00081 
00082      ic->Display(aMesh);
00083 
00084          return true;
00085 }
00086 
00087 bool QoccInputOutput::importModel(  const QString& fileName,
00088                                                                     const FileFormat format,
00089                                                                         const Handle(AIS_InteractiveContext)& ic )
00090 {
00091         bool result;
00092         QApplication::setOverrideCursor( Qt::WaitCursor );
00093         if (format == FormatSTL)
00094         {
00095                 
00096                 result = importMesh( fileName, format, ic );
00097         }
00098         else
00099         {
00100                 Handle(TopTools_HSequenceOfShape) shapes = importModel( format, fileName );
00101                 if ( shapes.IsNull() || !shapes->Length() )
00102                 {
00103                         result = false;
00104                 }
00105                 else
00106                 {
00107                         result = true;
00108                         for ( int i = 1; i <= shapes->Length(); i++ )
00109                         {
00110                                 Handle(AIS_Shape) anAISShape = new AIS_Shape( shapes->Value( i ) );
00111                                 ic->SetMaterial( anAISShape, Graphic3d_NOM_GOLD);
00112                                 ic->SetColor( anAISShape, Quantity_NOC_RED);
00113                                 ic->SetDisplayMode( anAISShape, 1, Standard_False );
00114                                 ic->Display(anAISShape, Standard_False);
00115                         }
00116                 }
00117         }
00118         QApplication::restoreOverrideCursor();
00119     
00120     return result;
00121 }
00122 
00123 Handle(TopTools_HSequenceOfShape) QoccInputOutput::importModel( const FileFormat format, const QString& file )
00124 {
00125     Handle(TopTools_HSequenceOfShape) shapes;
00126     try {
00127         switch ( format )
00128         {
00129         case FormatBREP:
00130             shapes = importBREP( file );
00131             break;
00132         case FormatIGES:
00133             shapes = importIGES( file );
00134             break;
00135         case FormatSTEP:
00136             shapes = importSTEP( file );
00137             break;
00138         case FormatCSFDB:
00139             shapes = importCSFDB( file );
00140             break;
00141                 default:
00142                         
00143                         break;
00144         }
00145     } catch ( Standard_Failure ) {
00146         shapes.Nullify();
00147     }
00148     return shapes;
00149 }
00150 
00151 
00152 
00153 
00154 
00155 
00156 bool QoccInputOutput::exportModel( const QString& fileName,
00157                                                                    const FileFormat format,
00158                                                                    const Handle(AIS_InteractiveContext)& ic )
00159 {
00160 
00161         Handle(TopTools_HSequenceOfShape) shapes = getShapes( ic );
00162     if ( shapes.IsNull() || !shapes->Length() )
00163         return false;
00164 
00165     QApplication::setOverrideCursor( Qt::WaitCursor );
00166     bool stat = exportModel( format, fileName, shapes );
00167     QApplication::restoreOverrideCursor();
00168     return stat;
00169 }
00170 
00171 bool QoccInputOutput::exportModel( const FileFormat format, const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
00172 {
00173     bool status;
00174     try {
00175         switch ( format )
00176         {
00177         case FormatBREP:
00178             status = exportBREP( file, shapes );
00179             break;
00180         case FormatIGES:
00181             status = exportIGES( file, shapes );
00182             break;
00183         case FormatSTEP:
00184             status = exportSTEP( file, shapes );
00185             break;
00186         case FormatCSFDB:
00187             status = exportCSFDB( file, shapes );
00188             break;
00189         case FormatSTL:
00190             status = exportSTL( file, shapes );
00191             break;
00192         case FormatVRML:
00193             status = exportVRML( file, shapes );
00194             break;
00195         }
00196     } catch ( Standard_Failure ) {
00197         status = false;
00198     }
00199     return status;
00200 }
00201 
00202 Handle(TopTools_HSequenceOfShape) QoccInputOutput::getShapes( const Handle(AIS_InteractiveContext)& ic )
00203 {
00204     Handle(TopTools_HSequenceOfShape) aSequence;
00205     Handle(AIS_InteractiveObject) picked;
00206     for ( ic->InitCurrent(); ic->MoreCurrent(); ic->NextCurrent() )
00207     {
00208         Handle(AIS_InteractiveObject) obj = ic->Current();
00209         if ( obj->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
00210         {
00211             TopoDS_Shape shape = Handle_AIS_Shape::DownCast(obj)->Shape();
00212             if ( aSequence.IsNull() )
00213                 aSequence = new TopTools_HSequenceOfShape();
00214             aSequence->Append( shape );
00215         }
00216     }
00217     return aSequence;
00218 }
00219 
00220 
00221 Handle(TopTools_HSequenceOfShape) QoccInputOutput::importBREP( const QString& file )
00222 {
00223         Handle(TopTools_HSequenceOfShape) aSequence;
00224     TopoDS_Shape aShape;
00225         BRep_Builder aBuilder;
00226 
00227         Standard_Boolean result = BRepTools::Read(  aShape, file.toAscii().data(), aBuilder );
00228         if ( result )
00229     {
00230             aSequence = new TopTools_HSequenceOfShape();
00231                 aSequence->Append( aShape );
00232     }
00233 
00234     return aSequence;
00235 }
00236 
00237 Handle(TopTools_HSequenceOfShape) QoccInputOutput::importIGES( const QString& file )
00238 {
00239     Handle(TopTools_HSequenceOfShape) aSequence;
00240     IGESControl_Reader Reader;
00241     int status = Reader.ReadFile( file.toAscii().data() );
00242 
00243     if ( status == IFSelect_RetDone )
00244     {
00245         aSequence = new TopTools_HSequenceOfShape();
00246         Reader.TransferRoots();
00247         TopoDS_Shape aShape = Reader.OneShape();
00248         aSequence->Append( aShape );
00249     }
00250         return aSequence;
00251 }
00252 
00253 Handle(TopTools_HSequenceOfShape) QoccInputOutput::importSTEP( const QString& file )
00254 {
00255         Handle(TopTools_HSequenceOfShape) aSequence;
00256 
00257         STEPControl_Reader aReader;
00258         IFSelect_ReturnStatus status = aReader.ReadFile( file.toAscii().data() );
00259         if ( status == IFSelect_RetDone )
00260     {
00261             Interface_TraceFile::SetDefault();
00262             bool failsonly = false;
00263             aReader.PrintCheckLoad( failsonly, IFSelect_ItemsByEntity );
00264 
00265             int nbr = aReader.NbRootsForTransfer();
00266             aReader.PrintCheckTransfer( failsonly, IFSelect_ItemsByEntity );
00267             for ( Standard_Integer n = 1; n <= nbr; n++ )
00268             {
00269                 bool ok = aReader.TransferRoot( n );
00270                         if (ok)
00271                         {
00272                                 int nbs = aReader.NbShapes();
00273                                 if ( nbs > 0 )
00274                                 {
00275                                         aSequence = new TopTools_HSequenceOfShape();
00276                                         for ( int i = 1; i <= nbs; i++ )
00277                                         {
00278                                                 TopoDS_Shape shape = aReader.Shape( i );
00279                                                 aSequence->Append( shape );
00280                                         }
00281                                 }
00282                         }
00283         }
00284     }
00285         return aSequence;
00286 }
00287 
00288 Handle(TopTools_HSequenceOfShape) QoccInputOutput::importCSFDB( const QString& file )
00289 {
00290         Handle(TopTools_HSequenceOfShape) aSequence;
00291 
00292     
00293     if ( FSD_File::IsGoodFileType( file.toAscii().data() ) != Storage_VSOk )
00294             return aSequence;
00295 
00296     static FSD_File fileDriver;
00297     TCollection_AsciiString aName( file.toAscii().data() );
00298     if ( fileDriver.Open( aName, Storage_VSRead ) != Storage_VSOk )
00299         return aSequence;
00300 
00301     Handle(ShapeSchema) schema = new ShapeSchema();
00302     Handle(Storage_Data) data  = schema->Read( fileDriver );
00303     if ( data->ErrorStatus() != Storage_VSOk )
00304         return aSequence;
00305 
00306     fileDriver.Close();
00307 
00308     aSequence = new TopTools_HSequenceOfShape();
00309     Handle(Storage_HSeqOfRoot) roots = data->Roots();
00310     for ( int i = 1; i <= roots->Length() ; i++ )
00311     {
00312         Handle(Storage_Root) r = roots->Value( i );
00313         Handle(Standard_Persistent) p = r->Object();
00314         Handle(PTopoDS_HShape) aPShape = Handle(PTopoDS_HShape)::DownCast(p);
00315         if ( !aPShape.IsNull() )
00316         {
00317                 PTColStd_PersistentTransientMap aMap;
00318                 TopoDS_Shape aTShape;
00319             MgtBRep::Translate( aPShape, aMap, aTShape, MgtBRep_WithTriangle );
00320             aSequence->Append( aTShape );
00321         }
00322     }
00323 
00324     return aSequence;
00325 }
00326 
00327 bool QoccInputOutput::exportBREP( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
00328 {
00329     if ( shapes.IsNull() || shapes->IsEmpty() )
00330         return false;
00331 
00332     TopoDS_Shape shape = shapes->Value( 1 );
00333     return BRepTools::Write( shape, file.toAscii().data() );
00334 }
00335 
00336 bool QoccInputOutput::exportIGES( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
00337 {
00338     if ( shapes.IsNull() || shapes->IsEmpty() )
00339         return false;
00340 
00341     IGESControl_Controller::Init();
00342         IGESControl_Writer writer( Interface_Static::CVal( "XSTEP.iges.unit" ),
00343                                Interface_Static::IVal( "XSTEP.iges.writebrep.mode" ) );
00344 
00345         for ( int i = 1; i <= shapes->Length(); i++ )
00346                 writer.AddShape ( shapes->Value( i ) );
00347         writer.ComputeModel();
00348         return writer.Write( file.toAscii().data() );
00349 }
00350 
00351 bool QoccInputOutput::exportSTEP( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
00352 {
00353     if ( shapes.IsNull() || shapes->IsEmpty() )
00354         return false;
00355 
00356     IFSelect_ReturnStatus status;
00357 
00358     STEPControl_Writer writer;
00359         for ( int i = 1; i <= shapes->Length(); i++ )
00360     {
00361                 status = writer.Transfer( shapes->Value( i ), STEPControl_AsIs );
00362         if ( status != IFSelect_RetDone )
00363             return false;
00364     }
00365 
00366     status = writer.Write( file.toAscii().data() );
00367 
00368     switch ( status )
00369     {
00370     case IFSelect_RetError:
00371         myInfo = tr( "INF_DATA_ERROR" );
00372         break;
00373     case IFSelect_RetFail:
00374         myInfo = tr( "INF_WRITING_ERROR" );
00375         break;
00376     case IFSelect_RetVoid:
00377         myInfo = tr( "INF_NOTHING_ERROR" );
00378         break;
00379         default:
00380                 break;
00381     }
00382     return status == IFSelect_RetDone;
00383 }
00384 
00385 bool QoccInputOutput::exportCSFDB( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
00386 {
00387     if ( shapes.IsNull() || shapes->IsEmpty() )
00388         return false;
00389 
00390     static FSD_File fileDriver;
00391 
00392     Handle(ShapeSchema) schema = new ShapeSchema();
00393     Handle(Storage_Data) data  = new Storage_Data();
00394     data->ClearErrorStatus();
00395 
00396     data->SetApplicationName( TCollection_ExtendedString( "Sample Import / Export" ) );
00397     data->SetApplicationVersion( "1" );
00398     data->SetDataType( TCollection_ExtendedString( "Shapes" ) );
00399     data->AddToUserInfo( "Storing a persistent set of shapes in a flat file" );
00400     data->AddToComments( TCollection_ExtendedString( "Application is based on CasCade 5.0 Professional" ) );
00401 
00402     if ( fileDriver.Open( file.toAscii().data(), Storage_VSWrite ) != Storage_VSOk )
00403     {
00404         myInfo = tr( "INF_TRANSLATE_ERROR_CANTSAVEFILE" ).arg( file );
00405         return false;
00406     }
00407 
00408     PTColStd_TransientPersistentMap aMap;
00409         for ( int i = 1; i <= shapes->Length(); i++ )
00410         {
00411                 TopoDS_Shape shape = shapes->Value( i );
00412                 if ( shape.IsNull() )
00413                 {
00414                         myInfo = tr( "INF_TRANSLATE_ERROR_INVALIDSHAPE" );
00415                         return false;
00416         }
00417 
00418         Handle(PTopoDS_HShape) pshape = MgtBRep::Translate( shape, aMap, MgtBRep_WithTriangle );
00419                 TCollection_AsciiString objName = TCollection_AsciiString( "Object_" ) + TCollection_AsciiString( i );
00420                 data->AddRoot( objName, pshape );
00421         }
00422 
00423     schema->Write( fileDriver, data );
00424     fileDriver.Close();
00425 
00426     if ( data->ErrorStatus() != Storage_VSOk )
00427     {
00428         myInfo = tr( "INF_TRANSLATE_ERROR_CANTSAVEDATA" );
00429         return false;
00430     }
00431     return true;
00432 }
00433 
00434 bool QoccInputOutput::exportSTL( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
00435 {
00436     if ( shapes.IsNull() || shapes->IsEmpty() )
00437         return false;
00438 
00439         TopoDS_Compound res;
00440         BRep_Builder builder;
00441         builder.MakeCompound( res );
00442 
00443         for ( int i = 1; i <= shapes->Length(); i++ )
00444         {
00445                 TopoDS_Shape shape = shapes->Value( i );
00446                 if ( shape.IsNull() )
00447                 {
00448                         myInfo = tr( "INF_TRANSLATE_ERROR_INVALIDSHAPE" );
00449                         return false;
00450         }
00451                 builder.Add( res, shape );
00452         }
00453 
00454         StlAPI_Writer writer;
00455         writer.Write( res, file.toAscii().data() );
00456 
00457     return true;
00458 }
00459 
00460 bool QoccInputOutput::exportVRML( const QString& file, const Handle(TopTools_HSequenceOfShape)& shapes )
00461 {
00462     if ( shapes.IsNull() || shapes->IsEmpty() )
00463         return false;
00464 
00465         TopoDS_Compound res;
00466         BRep_Builder builder;
00467         builder.MakeCompound( res );
00468 
00469         for ( int i = 1; i <= shapes->Length(); i++ )
00470         {
00471                 TopoDS_Shape shape = shapes->Value( i );
00472                 if ( shape.IsNull() )
00473                 {
00474                         myInfo = tr( "INF_TRANSLATE_ERROR_INVALIDSHAPE" );
00475                         return false;
00476         }
00477                 builder.Add( res, shape );
00478         }
00479 
00480         VrmlAPI_Writer writer;
00481         writer.Write( res, file.toAscii().data() );
00482 
00483     return true;
00484 }
00485 
00486 bool QoccInputOutput::checkFacetedBrep( const Handle(TopTools_HSequenceOfShape)& shapes )
00487 {
00488         bool err = false;
00489         for ( int i = 1; i <= shapes->Length(); i++ )
00490         {
00491             TopoDS_Shape shape = shapes->Value( i );
00492         for ( TopExp_Explorer fexp( shape, TopAbs_FACE ); fexp.More() && !err; fexp.Next() )
00493                 {
00494                     Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face( fexp.Current() ) );
00495                     if ( !surface->IsKind( STANDARD_TYPE( Geom_Plane ) ) )
00496                         err = true;
00497                 }
00498         for ( TopExp_Explorer eexp( shape, TopAbs_EDGE ); eexp.More() && !err; eexp.Next() )
00499                 {
00500                     Standard_Real fd, ld;
00501                     Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( eexp.Current() ), fd, ld );
00502                     if ( !curve->IsKind( STANDARD_TYPE( Geom_Line ) ) )
00503                         err = true;
00504                 }
00505         }
00506         return !err;
00507 }