1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

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.
This commit is contained in:
gka 2015-09-10 10:54:21 +03:00 committed by bugmaster
parent 488e5b9da0
commit f5e92b0460
4 changed files with 146 additions and 47 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -43,6 +43,7 @@
#include <XSDRAW_Vars.hxx>
#include <XSDRAWIGES.hxx>
#include <XSDRAWSTEP.hxx>
#include <DDF.hxx>
#include <stdio.h>
//============================================================
@ -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);

28
tests/bugs/step/bug26657 Normal file
View File

@ -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