From f5e92b046090e586640b719c77209161e420d1b2 Mon Sep 17 00:00:00 2001 From: gka Date: Thu, 10 Sep 2015 10:54:21 +0300 Subject: [PATCH] 0026657: Data Exchange - IGES/STEP OCAF writers should keep hierarchy and colors when saving non-root elements Make modification to save in the file part of the XCAF document starting from specified label. If specified label is component of the high-level assembly then high-level assembly is saved in document with one specified component. In other case only part of the document starting from the specified label is saved. --- src/STEPCAFControl/STEPCAFControl_Writer.cxx | 82 ++++++++++++++------ src/STEPCAFControl/STEPCAFControl_Writer.hxx | 18 ++--- src/XDEDRAW/XDEDRAW_Common.cxx | 65 ++++++++++++---- tests/bugs/step/bug26657 | 28 +++++++ 4 files changed, 146 insertions(+), 47 deletions(-) create mode 100644 tests/bugs/step/bug26657 diff --git a/src/STEPCAFControl/STEPCAFControl_Writer.cxx b/src/STEPCAFControl/STEPCAFControl_Writer.cxx index 96843c3d0a..538998cc6f 100644 --- a/src/STEPCAFControl/STEPCAFControl_Writer.cxx +++ b/src/STEPCAFControl/STEPCAFControl_Writer.cxx @@ -445,28 +445,57 @@ Standard_Boolean STEPCAFControl_Writer::Transfer (STEPControl_Writer &writer, if ( shape.IsNull() ) continue; // write shape either as a whole, or as multifile (with extern refs) - if ( ! multi /* || ! XCAFDoc_ShapeTool::IsAssembly ( L ) */ ) { + if ( ! multi ) { Actor->SetStdMode ( Standard_False ); - // fill sequence of (sub) shapes for which attributes should be written - // and set actor to handle assemblies in a proper way TDF_LabelSequence comp; - XCAFDoc_ShapeTool::GetComponents ( L, comp, Standard_True ); + + //for case when only part of assemby structure should be written in the document + //if specified label is component of the assembly then + //in order to save location of this component in the high-level assembly + //and save name of high-level assembly it is necessary to represent structure of high-level assembly + //as assembly with one component specified by current label. + //For that compound containing only specified component is binded to the label of the high-level assembly. + //The such way full structure of high-level assembly was replaced on the assembly contaning one component. + if ( XCAFDoc_ShapeTool::IsComponent ( L ) ) + { + TopoDS_Compound aComp; + BRep_Builder aB; + aB.MakeCompound(aComp); + aB.Add(aComp, shape); + shape = aComp; + comp.Append(L); + TDF_Label ref; + if ( XCAFDoc_ShapeTool::GetReferredShape ( L, ref ) ) + { + if(XCAFDoc_ShapeTool::IsAssembly ( ref)) + XCAFDoc_ShapeTool::GetComponents ( ref, comp, Standard_True ); + } + L = L.Father(); + } + else + { + // fill sequence of (sub) shapes for which attributes should be written + // and set actor to handle assemblies in a proper way + if(XCAFDoc_ShapeTool::IsAssembly ( L )) + XCAFDoc_ShapeTool::GetComponents ( L, comp, Standard_True ); + } + for ( Standard_Integer k=1; k <= comp.Length(); k++ ) { - TDF_Label ref; - if ( ! XCAFDoc_ShapeTool::GetReferredShape ( comp(k), ref ) ) continue; - if ( ! myLabels.IsBound ( ref ) ) { - TopoDS_Shape refS = XCAFDoc_ShapeTool::GetShape ( ref ); - myLabels.Bind ( ref, refS ); - sublabels.Append ( ref ); - if ( XCAFDoc_ShapeTool::IsAssembly ( ref ) ) - Actor->RegisterAssembly ( refS ); - } + TDF_Label ref; + if ( ! XCAFDoc_ShapeTool::GetReferredShape ( comp(k), ref ) ) continue; + if ( ! myLabels.IsBound ( ref ) ) { + TopoDS_Shape refS = XCAFDoc_ShapeTool::GetShape ( ref ); + myLabels.Bind ( ref, refS ); + sublabels.Append ( ref ); + if ( XCAFDoc_ShapeTool::IsAssembly ( ref ) ) + Actor->RegisterAssembly ( refS ); + } } myLabels.Bind ( L, shape ); sublabels.Append ( L ); if ( XCAFDoc_ShapeTool::IsAssembly ( L ) ) - Actor->RegisterAssembly ( shape ); + Actor->RegisterAssembly ( shape ); writer.Transfer(shape,mode,Standard_False); Actor->SetStdMode ( Standard_True ); // restore default behaviour @@ -615,11 +644,10 @@ TopoDS_Shape STEPCAFControl_Writer::TransferExternFiles (const TDF_Label &L, TopoDS_Compound C; BRep_Builder B; B.MakeCompound ( C ); - labels.Append ( L ); - + //labels.Append ( L ); // if not assembly, write to separate file - if ( ! XCAFDoc_ShapeTool::IsAssembly ( L ) ) { - + if ( ! XCAFDoc_ShapeTool::IsAssembly ( L ) && !XCAFDoc_ShapeTool::IsComponent ( L )) { + labels.Append ( L ); // prepare for transfer Handle(XSControl_WorkSession) newWS = new XSControl_WorkSession; newWS->SelectNorm ( "STEP" ); @@ -660,11 +688,21 @@ TopoDS_Shape STEPCAFControl_Writer::TransferExternFiles (const TDF_Label &L, myLabels.Bind ( L, C ); return C; } - + TDF_LabelSequence comp; + TDF_Label aCurL = L; + //if specified shape is component then high-level assembly is considered + //to get valid structure with location + if ( XCAFDoc_ShapeTool::IsComponent ( L ) ) + { + comp.Append(L); + aCurL = L.Father(); + } // else iterate on components add create structure of empty compounds // representing the assembly - TDF_LabelSequence comp; - XCAFDoc_ShapeTool::GetComponents ( L, comp, Standard_False ); + else if (XCAFDoc_ShapeTool::IsAssembly ( L )) + XCAFDoc_ShapeTool::GetComponents ( L, comp, Standard_False ); + + labels.Append ( aCurL ); for ( Standard_Integer k=1; k <= comp.Length(); k++ ) { TDF_Label lab = comp(k); TDF_Label ref; @@ -673,7 +711,7 @@ TopoDS_Shape STEPCAFControl_Writer::TransferExternFiles (const TDF_Label &L, Scomp.Location ( XCAFDoc_ShapeTool::GetLocation ( lab ) ); B.Add ( C, Scomp ); } - myLabels.Bind ( L, C ); + myLabels.Bind ( aCurL, C ); return C; } diff --git a/src/STEPCAFControl/STEPCAFControl_Writer.hxx b/src/STEPCAFControl/STEPCAFControl_Writer.hxx index 915c38bfef..250bf213b8 100644 --- a/src/STEPCAFControl/STEPCAFControl_Writer.hxx +++ b/src/STEPCAFControl/STEPCAFControl_Writer.hxx @@ -50,7 +50,7 @@ class STEPCAFControl_Writer public: DEFINE_STANDARD_ALLOC - + //! Creates a writer with an empty //! STEP model and sets ColorMode, LayerMode, NameMode and @@ -80,8 +80,9 @@ public: //! gives prefix for names of extern files (can be empty string) //! Returns True if translation is OK Standard_EXPORT Standard_Boolean Transfer (const Handle(TDocStd_Document)& doc, const STEPControl_StepModelType mode = STEPControl_AsIs, const Standard_CString multi = 0); - Standard_EXPORT Standard_Boolean Transfer (const TDF_LabelSequence& L, const STEPControl_StepModelType mode = STEPControl_AsIs, const Standard_CString multi = 0); - Standard_EXPORT Standard_Boolean Transfer (const TDF_Label& L, const STEPControl_StepModelType mode = STEPControl_AsIs, const Standard_CString multi = 0); + + //! Method to transfer part of the document specified by label + Standard_EXPORT Standard_Boolean Transfer (const TDF_Label& L, const STEPControl_StepModelType mode = STEPControl_AsIs, const Standard_CString multi = 0 ); Standard_EXPORT Standard_Boolean Perform (const Handle(TDocStd_Document)& doc, const TCollection_AsciiString& filename); @@ -146,12 +147,13 @@ public: protected: - + //! Mehod to writing sequence of root assemblies or part of the file specified by use by one label + Standard_EXPORT Standard_Boolean Transfer (const TDF_LabelSequence& L, const STEPControl_StepModelType mode = STEPControl_AsIs, const Standard_CString multi = 0); //! Transfers labels to a STEP model //! Returns True if translation is OK //! isExternFile setting from TransferExternFiles method - Standard_EXPORT Standard_Boolean Transfer (STEPControl_Writer& wr, const TDF_LabelSequence& labels, const STEPControl_StepModelType mode = STEPControl_AsIs, const Standard_CString multi = 0, const Standard_Boolean isExternFile = Standard_False); + Standard_EXPORT Standard_Boolean Transfer (STEPControl_Writer& wr, const TDF_LabelSequence& labels, const STEPControl_StepModelType mode = STEPControl_AsIs, const Standard_CString multi = 0, const Standard_Boolean isExternFile = Standard_False) ; //! Parses assembly structure of label L, writes all the simple //! shapes each to its own file named by name of its label plus @@ -186,8 +188,7 @@ protected: //! Write SHUO assigned to specified component, to STEP model Standard_EXPORT Standard_Boolean WriteSHUOs (const Handle(XSControl_WorkSession)& WS, const TDF_LabelSequence& labels); - - + private: @@ -212,7 +213,4 @@ private: - - - #endif // _STEPCAFControl_Writer_HeaderFile diff --git a/src/XDEDRAW/XDEDRAW_Common.cxx b/src/XDEDRAW/XDEDRAW_Common.cxx index 5bef93cbdd..cff00719ed 100644 --- a/src/XDEDRAW/XDEDRAW_Common.cxx +++ b/src/XDEDRAW/XDEDRAW_Common.cxx @@ -43,6 +43,7 @@ #include #include #include +#include #include //============================================================ @@ -360,10 +361,13 @@ static Standard_Integer ReadStep (Draw_Interpretor& di, Standard_Integer argc, c static Standard_Integer WriteStep (Draw_Interpretor& di, Standard_Integer argc, const char** argv) { if ( argc <3 ) { - di << "Use: " << argv[0] << " Doc filename [mode=a [multifile_prefix]]: write document to the STEP file" << "\n"; - di << "Parameter mode can be: a or 0 : AsIs (default)" << "\n"; - di << "f or 1 : FacettedBRep s or 2 : ShellBasedSurfaceModel" << "\n"; - di << "m or 3 : ManifoldSolidBrep w or 4 : GeometricCurveSet/WireFrame" << "\n"; + di << "Use: " << argv[0] << " Doc filename [mode [multifile_prefix [label]]]: write document to the STEP file" << "\n"; + di << "mode can be: a or 0 : AsIs (default)" << "\n"; + di << " f or 1 : FacettedBRep s or 2 : ShellBasedSurfaceModel\n"; + di << " m or 3 : ManifoldSolidBrep w or 4 : GeometricCurveSet/WireFrame\n"; + di << "multifile_prefix: triggers writing assembly components as separate files,\n"; + di << " and defines common prefix for their names\n"; + di << "label: tag of the sub-assembly label to save only that sub-assembly\n"; return 0; } @@ -373,16 +377,16 @@ static Standard_Integer WriteStep (Draw_Interpretor& di, Standard_Integer argc, di << argv[1] << " is not a document" << "\n"; return 1; } + Standard_CString multifile = 0; - Standard_CString multifile = ( argc >4 ? argv[4] : 0 ); - + Standard_Integer k = 3; DeclareAndCast(STEPControl_Controller,ctl,XSDRAW::Controller()); if (ctl.IsNull()) XSDRAW::SetNorm("STEP"); STEPCAFControl_Writer writer ( XSDRAW::Session(), Standard_True ); - + STEPControl_StepModelType mode = STEPControl_AsIs; - if ( argc >3 ) { - switch (argv[3][0]) { + if ( argc > k ) { + switch (argv[k][0]) { case 'a' : case '0' : mode = STEPControl_AsIs; break; case 'f' : @@ -396,7 +400,7 @@ static Standard_Integer WriteStep (Draw_Interpretor& di, Standard_Integer argc, default : di<<"3st arg = mode, incorrect [give fsmw]"<<"\n"; return 1; } Standard_Boolean wrmode = Standard_True; - for ( Standard_Integer i = 0; argv[3][i] ; i++ ) + for ( Standard_Integer i = 0; argv[k][i] ; i++ ) switch (argv[3][i]) { case '-' : wrmode = Standard_False; break; case '+' : wrmode = Standard_True; break; @@ -405,13 +409,44 @@ static Standard_Integer WriteStep (Draw_Interpretor& di, Standard_Integer argc, case 'l' : writer.SetLayerMode (wrmode); break; case 'v' : writer.SetPropsMode (wrmode); break; } + k++; + } + + TDF_Label label; + if( argc > k) + { + TCollection_AsciiString aStr(argv[k]); + if( aStr.Search(":") ==-1) + multifile = argv[k++]; } - - di << "Translating document " << argv[1] << " to STEP" << "\n"; - if ( ! writer.Transfer ( Doc, mode, multifile ) ) { - di << "The document cannot be translated or gives no result" << "\n"; + if( argc > k) + { + + if( !DDF::FindLabel(Doc->Main().Data(), argv[k], label) || label.IsNull()) { + di << "No label for entry" << "\n"; + return 1; + + } } + if( !label.IsNull()) + { + di << "Translating label "<< argv[k]<<" of document " << argv[1] << " to STEP" << "\n"; + if(!writer.Transfer ( label, mode, multifile )) + { + di << "The label of document cannot be translated or gives no result" << "\n"; + return 1; + } + + } + else + { + di << "Translating document " << argv[1] << " to STEP" << "\n"; + if ( ! writer.Transfer ( Doc, mode, multifile ) ) { + di << "The document cannot be translated or gives no result" << "\n"; + } + } + di << "Writing STEP file " << argv[2] << "\n"; IFSelect_ReturnStatus stat = writer.Write(argv[2]); @@ -440,7 +475,7 @@ void XDEDRAW_Common::InitCommands(Draw_Interpretor& di) { di.Add("ReadIges" , "Doc filename: Read IGES file to DECAF document" ,__FILE__, ReadIges, g); di.Add("WriteIges" , "Doc filename: Write DECAF document to IGES file" ,__FILE__, WriteIges, g); di.Add("ReadStep" , "Doc filename: Read STEP file to DECAF document" ,__FILE__, ReadStep, g); - di.Add("WriteStep" , "Doc filename: Write DECAF document to STEP file" ,__FILE__, WriteStep, g); + di.Add("WriteStep" , "Doc filename [mode=a [multifile_prefix] [label]]: Write DECAF document to STEP file" ,__FILE__, WriteStep, g); di.Add("XFileList","Print list of files that was transfered by the last transfer" ,__FILE__, GetDicWSList , g); di.Add("XFileCur", ": returns name of file which is set as current",__FILE__, GetCurWS, g); diff --git a/tests/bugs/step/bug26657 b/tests/bugs/step/bug26657 new file mode 100644 index 0000000000..380a5f8be6 --- /dev/null +++ b/tests/bugs/step/bug26657 @@ -0,0 +1,28 @@ +pload DCAF +pload TOPTEST +pload XDE +puts "========" +puts "OCC26657" +puts "========" +puts "" +########################################################################## +# STEP OCAF writers should keep hierarchy and colors when saving non-root elements +########################################################################## +pload XDEDRAW +ReadStep D1 [locate_data_file bug26657.stp] +WriteStep D1 $imagedir/bug26657_temp.stp a 0:1:1:1:2 +if { [catch { Close D11 } catch_result] } { + puts "Document D11 is not exist" +} + +ReadStep D11 $imagedir/bug26657_temp.stp +XGetOneShape result D11 +checkshape result f + +Close D1 +checknbshapes result -solid 3 +XShow D11 +vfit +vsetdispmode 1 +vdump $imagedir/${test_image}.png +