From 02a0b964f2a69748271dcb97fa43ad50a7e7b76a Mon Sep 17 00:00:00 2001 From: apn Date: Fri, 7 Sep 2012 13:03:39 +0400 Subject: [PATCH] 0023384: Translate sub-shape names between XDE document and STEP Sub-shapes naming translation between XDE and STEP implemented as an optional mode of Reader/Writer. New static variables are now available: write.stepcaf.subshapes.name for Writer and read.stepcaf.subshapes.name for Reader (both have 0 values by default). XOpen command implemented in scope of XDEDRAW asset. Added test case bugs xde CR23384 --- .../STEPCAFControl_Controller.cxx | 24 +- src/STEPCAFControl/STEPCAFControl_Reader.cdl | 50 ++- src/STEPCAFControl/STEPCAFControl_Reader.cxx | 301 +++++++++++++++++- src/STEPCAFControl/STEPCAFControl_Writer.cxx | 40 +++ src/XDEDRAW/XDEDRAW.cxx | 50 +++ tests/bugs/xde/CR23384 | 1 - 6 files changed, 459 insertions(+), 7 deletions(-) diff --git a/src/STEPCAFControl/STEPCAFControl_Controller.cxx b/src/STEPCAFControl/STEPCAFControl_Controller.cxx index 8a647212f7..9f00413847 100755 --- a/src/STEPCAFControl/STEPCAFControl_Controller.cxx +++ b/src/STEPCAFControl/STEPCAFControl_Controller.cxx @@ -21,6 +21,7 @@ #include #include #include +#include //======================================================================= //function : STEPCAFControl_Controller @@ -45,9 +46,30 @@ Standard_Boolean STEPCAFControl_Controller::Init () inic = Standard_True; // self-registering Handle(STEPCAFControl_Controller) STEPCTL = new STEPCAFControl_Controller; -// do XSAlgo::Init, cause it does not called before. + // do XSAlgo::Init, cause it does not called before. XSAlgo::Init(); // do something to avoid warnings... STEPCTL->AutoRecord(); + + //----------------------------------------------------------- + // Few variables for advanced control of translation process + //----------------------------------------------------------- + + // Indicates whether to write sub-shape names to 'Name' attributes of + // STEP Representation Items + Interface_Static::Init ("stepcaf", "write.stepcaf.subshapes.name", 'e', ""); + Interface_Static::Init ("stepcaf", "write.stepcaf.subshapes.name", '&', "enum 0"); + Interface_Static::Init ("stepcaf", "write.stepcaf.subshapes.name", '&', "eval Off"); // 0 + Interface_Static::Init ("stepcaf", "write.stepcaf.subshapes.name", '&', "eval On"); // 1 + Interface_Static::SetIVal("write.stepcaf.subshapes.name", 0); // Disabled by default + + // Indicates whether to read sub-shape names from 'Name' attributes of + // STEP Representation Items + Interface_Static::Init ("stepcaf", "read.stepcaf.subshapes.name", 'e', ""); + Interface_Static::Init ("stepcaf", "read.stepcaf.subshapes.name", '&', "enum 0"); + Interface_Static::Init ("stepcaf", "read.stepcaf.subshapes.name", '&', "eval Off"); // 0 + Interface_Static::Init ("stepcaf", "read.stepcaf.subshapes.name", '&', "eval On"); // 1 + Interface_Static::SetIVal("read.stepcaf.subshapes.name", 0); // Disabled by default + return Standard_True; } diff --git a/src/STEPCAFControl/STEPCAFControl_Reader.cdl b/src/STEPCAFControl/STEPCAFControl_Reader.cdl index 75c87cef01..33122ea272 100755 --- a/src/STEPCAFControl/STEPCAFControl_Reader.cdl +++ b/src/STEPCAFControl/STEPCAFControl_Reader.cdl @@ -53,7 +53,10 @@ uses ShapeTool from XCAFDoc, Label from TDF, LabelSequence from TDF, - HSequenceOfTransient from TColStd + HSequenceOfTransient from TColStd, + RepresentationItem from StepRepr, + TransientProcess from Transfer, + ConnectedFaceSet from StepShape is @@ -204,6 +207,51 @@ is ---Purpose: Reads materials for instances defined in the STEP model and -- set reference between shape instances from different assemblyes + SettleShapeData(me; theItem: RepresentationItem from StepRepr; + theLab: out Label from TDF; + theShapeTool: ShapeTool from XCAFDoc; + theTP: TransientProcess from Transfer) + returns Label from TDF is protected; + --- Purpose: Populates the sub-Label of the passed TDF Label with shape + -- data associated with the given STEP Representation Item, + -- including naming and topological information. + + ExpandSubShapes(me; theShapeTool: ShapeTool from XCAFDoc; + theShapeLabelMap: DataMapOfShapeLabel from XCAFDoc; + theShapePDMap: DataMapOfShapePD from STEPCAFControl) + is protected; + --- Purpose: Given the maps of already translated shapes, this method + -- expands their correspondent Labels in XDE Document so that + -- to have a dedicated sub-Label for each sub-shape coming + -- with associated name in its STEP Representation Item. + + ExpandManifoldSolidBrep(me; theLab: out Label from TDF; + theItem: RepresentationItem from StepRepr; + theTP: TransientProcess from Transfer; + theShapeTool: ShapeTool from XCAFDoc) + is protected; + --- Purpose: Expands the topological structure of Manifold Solid BRep + -- STEP entity to OCAF sub-tree. Entities having no names + -- associated via their Representation Items are skipped. + + ExpandSBSM(me; theLab: out Label from TDF; + theItem: RepresentationItem from StepRepr; + theTP: TransientProcess from Transfer; + theShapeTool: ShapeTool from XCAFDoc) + is protected; + --- Purpose: Expands the topological structure of Shell-Based Surface + -- Model STEP entity to OCAF sub-tree. Entities having no names + -- associated via their Representation Items are skipped. + + ExpandShell(me; theShell: ConnectedFaceSet from StepShape; + theLab: out Label from TDF; + theTP: TransientProcess from Transfer; + theShapeTool: ShapeTool from XCAFDoc) + is protected; + --- Purpose: Expands STEP Shell structure to OCAF sub-tree. Entities + -- having no names associated via their Representation Items + -- are skipped. + FindInstance (myclass; NAUO: NextAssemblyUsageOccurrence from StepRepr; STool: ShapeTool from XCAFDoc; Tool: Tool from STEPConstruct; diff --git a/src/STEPCAFControl/STEPCAFControl_Reader.cxx b/src/STEPCAFControl/STEPCAFControl_Reader.cxx index e4c44be55d..e3878c6af9 100755 --- a/src/STEPCAFControl/STEPCAFControl_Reader.cxx +++ b/src/STEPCAFControl/STEPCAFControl_Reader.cxx @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -161,9 +162,60 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -//#include +#ifdef DEB +//! Converts address of the passed shape (TShape) to string. +//! \param theShape [in] Shape to dump. +//! \return corresponding string. +TCollection_AsciiString AddrToString(const TopoDS_Shape& theShape) +{ + std::string anAddrStr; + std::ostringstream ost; + ost << theShape.TShape().Access(); + anAddrStr = ost.str(); + TCollection_AsciiString aStr = + TCollection_AsciiString("[").Cat( anAddrStr.c_str() ).Cat("]"); + + return aStr; +} +#endif + +//======================================================================= +//function : IsEqual +//purpose : global function to check equality of topological shapes +//======================================================================= + +inline Standard_Boolean IsEqual(const TopoDS_Shape& theShape1, + const TopoDS_Shape& theShape2) +{ + return theShape1.IsEqual(theShape2); +} + +//======================================================================= +//function : AllocateSubLabel +//purpose : +//======================================================================= + +static TDF_Label AllocateSubLabel(TDF_Label& theRoot) +{ + return TDF_TagSource::NewChild(theRoot); +} //======================================================================= //function : STEPCAFControl_Reader @@ -189,7 +241,7 @@ STEPCAFControl_Reader::STEPCAFControl_Reader (): //======================================================================= STEPCAFControl_Reader::STEPCAFControl_Reader (const Handle(XSControl_WorkSession)& WS, - const Standard_Boolean scratch) : + const Standard_Boolean scratch) : myColorMode( Standard_True ), myNameMode ( Standard_True ), myLayerMode( Standard_True ), @@ -538,8 +590,10 @@ cout<<"filename="<Name(); + if ( hName.IsNull() || hName->IsEmpty() ) + return aResult; + + Handle(Transfer_Binder) aBinder = TP->Find(theItem); + if ( aBinder.IsNull() ) + return aResult; + + TopoDS_Shape aShape = TransferBRep::ShapeResult(aBinder); + if ( aShape.IsNull() ) + return aResult; + + // Allocate sub-Label + aResult = AllocateSubLabel(theLab); + + TCollection_AsciiString aName = hName->String(); + TDataStd_Name::Set(aResult, aName); + theShapeTool->SetShape(aResult, aShape); + + return aResult; +} + +//======================================================================= +//function : ExpandSubShapes +//purpose : +//======================================================================= + +void STEPCAFControl_Reader::ExpandSubShapes(const Handle(XCAFDoc_ShapeTool)& ShapeTool, + const XCAFDoc_DataMapOfShapeLabel& ShapeLabelMap, + const STEPCAFControl_DataMapOfShapePD& ShapePDMap) const +{ + const Handle(Interface_InterfaceModel)& Model = Reader().WS()->Model(); + const Handle(Transfer_TransientProcess)& TP = Reader().WS()->TransferReader()->TransientProcess(); + NCollection_DataMap ShapeNameMap; + TColStd_MapOfTransient aRepItems; + + // Read translation control variables + Standard_Boolean doReadSNames = (Interface_Static::IVal("read.stepcaf.subshapes.name") > 0); + + if ( !doReadSNames ) + return; + + const Interface_Graph& Graph = Reader().WS()->Graph(); + + for ( STEPCAFControl_DataMapIteratorOfDataMapOfShapePD it(ShapePDMap); it.More(); it.Next() ) + { + const TopoDS_Shape& aRootShape = it.Key(); + const Handle(StepBasic_ProductDefinition)& aPDef = it.Value(); + if ( aPDef.IsNull() ) + continue; + + // Find SDR by Product + Handle(StepShape_ShapeDefinitionRepresentation) aSDR; + Interface_EntityIterator entIt = Graph.TypedSharings( aPDef, STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation) ); + for ( entIt.Start(); entIt.More(); entIt.Next() ) + { + const Handle(Standard_Transient)& aReferer = entIt.Value(); + aSDR = Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(aReferer); + if ( !aSDR.IsNull() ) + break; + } + + if ( aSDR.IsNull() ) + continue; + + // Access shape representation + Handle(StepShape_ShapeRepresentation) + aShapeRepr = Handle(StepShape_ShapeRepresentation)::DownCast( aSDR->UsedRepresentation() ); + + if ( aShapeRepr.IsNull() ) + continue; + + // Access representation items + Handle(StepRepr_HArray1OfRepresentationItem) aReprItems = aShapeRepr->Items(); + + if ( aReprItems.IsNull() ) + continue; + + if ( !ShapeLabelMap.IsBound(aRootShape) ) + continue; + + TDF_Label aRootLab = ShapeLabelMap.Find(aRootShape); + + StepRepr_SequenceOfRepresentationItem aMSBSeq; + StepRepr_SequenceOfRepresentationItem aSBSMSeq; + + // Iterate over the top level representation items collecting the + // topological containers to expand + for ( Standard_Integer i = aReprItems->Lower(); i <= aReprItems->Upper(); ++i ) + { + Handle(StepRepr_RepresentationItem) aTRepr = aReprItems->Value(i); + if ( aTRepr->IsKind( STANDARD_TYPE(StepShape_ManifoldSolidBrep) ) ) + aMSBSeq.Append(aTRepr); + else if ( aTRepr->IsKind( STANDARD_TYPE(StepShape_ShellBasedSurfaceModel) ) ) + aSBSMSeq.Append(aTRepr); + } + + // Insert intermediate OCAF Labels for SOLIDs in case there are more + // than one Manifold Solid BRep in the Shape Representation + Standard_Boolean doInsertSolidLab = (aMSBSeq.Length() > 1); + + // Expand Manifold Solid BReps + for ( Standard_Integer i = 1; i <= aMSBSeq.Length(); ++i ) + { + const Handle(StepRepr_RepresentationItem)& aManiRepr = aMSBSeq.Value(i); + + // Put additional Label for SOLID + TDF_Label aManiLab; + if ( doInsertSolidLab ) + aManiLab = SettleShapeData(aManiRepr, aRootLab, ShapeTool, TP); + else + aManiLab = aRootLab; + + ExpandManifoldSolidBrep(aManiLab, aMSBSeq.Value(i), TP, ShapeTool); + } + + // Expand Shell-Based Surface Models + for ( Standard_Integer i = 1; i <= aSBSMSeq.Length(); ++i ) + ExpandSBSM(aRootLab, aSBSMSeq.Value(i), TP, ShapeTool); + } +} + +//======================================================================= +//function : ExpandManifoldSolidBrep +//purpose : +//======================================================================= + +void STEPCAFControl_Reader::ExpandManifoldSolidBrep(TDF_Label& ShapeLab, + const Handle(StepRepr_RepresentationItem)& Repr, + const Handle(Transfer_TransientProcess)& TP, + const Handle(XCAFDoc_ShapeTool)& ShapeTool) const +{ + // Access outer shell + Handle(StepShape_ManifoldSolidBrep) aMSB = Handle(StepShape_ManifoldSolidBrep)::DownCast(Repr); + Handle(StepShape_ClosedShell) aShell = aMSB->Outer(); + + // Expand shell contents to CAF tree + ExpandShell(aShell, ShapeLab, TP, ShapeTool); +} + +//======================================================================= +//function : ExpandSBSM +//purpose : +//======================================================================= + +void STEPCAFControl_Reader::ExpandSBSM(TDF_Label& ShapeLab, + const Handle(StepRepr_RepresentationItem)& Repr, + const Handle(Transfer_TransientProcess)& TP, + const Handle(XCAFDoc_ShapeTool)& ShapeTool) const +{ + Handle(StepShape_ShellBasedSurfaceModel) aSBSM = Handle(StepShape_ShellBasedSurfaceModel)::DownCast(Repr); + + // Access boundary shells + Handle(StepShape_HArray1OfShell) aShells = aSBSM->SbsmBoundary(); + for ( Standard_Integer s = aShells->Lower(); s <= aShells->Upper(); ++s ) + { + const StepShape_Shell& aShell = aShells->Value(s); + Handle(StepShape_ConnectedFaceSet) aCFS; + Handle(StepShape_OpenShell) anOpenShell = aShell.OpenShell(); + Handle(StepShape_ClosedShell) aClosedShell = aShell.ClosedShell(); + + if ( !anOpenShell.IsNull() ) + aCFS = anOpenShell; + else + aCFS = aClosedShell; + + ExpandShell(aCFS, ShapeLab, TP, ShapeTool); + } +} + +//======================================================================= +//function : ExpandShell +//purpose : +//======================================================================= + +void STEPCAFControl_Reader::ExpandShell(const Handle(StepShape_ConnectedFaceSet)& Shell, + TDF_Label& RootLab, + const Handle(Transfer_TransientProcess)& TP, + const Handle(XCAFDoc_ShapeTool)& ShapeTool) const +{ + // Record CAF data + TDF_Label aShellLab = SettleShapeData(Shell, RootLab, ShapeTool, TP); + + // Access faces + Handle(StepShape_HArray1OfFace) aFaces = Shell->CfsFaces(); + for ( Standard_Integer f = aFaces->Lower(); f <= aFaces->Upper(); ++f ) + { + const Handle(StepShape_Face)& aFace = aFaces->Value(f); + + // Record CAF data + TDF_Label aFaceLab = SettleShapeData(aFace, aShellLab, ShapeTool, TP); + + // Access face bounds + Handle(StepShape_HArray1OfFaceBound) aWires = aFace->Bounds(); + for ( Standard_Integer w = aWires->Lower(); w <= aWires->Upper(); ++w ) + { + const Handle(StepShape_Loop)& aWire = aWires->Value(w)->Bound(); + + // Record CAF data + TDF_Label aWireLab = SettleShapeData(aWire, aFaceLab, ShapeTool, TP); + + // Access wire edges + // Currently only EDGE LOOPs are considered (!) + if ( !aWire->IsInstance( STANDARD_TYPE(StepShape_EdgeLoop) ) ) + continue; + + // Access edges + Handle(StepShape_EdgeLoop) anEdgeLoop = Handle(StepShape_EdgeLoop)::DownCast(aWire); + Handle(StepShape_HArray1OfOrientedEdge) anEdges = anEdgeLoop->EdgeList(); + for ( Standard_Integer e = anEdges->Lower(); e <= anEdges->Upper(); ++e ) + { + Handle(StepShape_Edge) anEdge = anEdges->Value(e)->EdgeElement(); + + // Record CAF data + TDF_Label anEdgeLab = SettleShapeData(anEdge, aWireLab, ShapeTool, TP); + + // Access vertices + Handle(StepShape_Vertex) aV1 = anEdge->EdgeStart(); + Handle(StepShape_Vertex) aV2 = anEdge->EdgeEnd(); + + // Record CAF data + SettleShapeData(aV1, anEdgeLab, ShapeTool, TP); + SettleShapeData(aV2, anEdgeLab, ShapeTool, TP); + } + } + } +} //======================================================================= //function : SetColorMode diff --git a/src/STEPCAFControl/STEPCAFControl_Writer.cxx b/src/STEPCAFControl/STEPCAFControl_Writer.cxx index 51765e76bc..468d4f9602 100755 --- a/src/STEPCAFControl/STEPCAFControl_Writer.cxx +++ b/src/STEPCAFControl/STEPCAFControl_Writer.cxx @@ -77,6 +77,7 @@ #include #include #include +#include #include #include @@ -544,6 +545,45 @@ Standard_Boolean STEPCAFControl_Writer::Transfer (STEPControl_Writer &writer, // refresh graph writer.WS()->ComputeGraph ( Standard_True ); + /* ================================ + * Write names for the sub-shapes + * ================================ */ + + if ( Interface_Static::IVal("write.stepcaf.subshapes.name") ) + { + Handle(XSControl_TransferWriter) TW = this->ChangeWriter().WS()->TransferWriter(); + Handle(Transfer_FinderProcess) FP = TW->FinderProcess(); + + for ( int i = 1; i <= labels.Length(); i++ ) + { + TDF_Label L = labels.Value(i); + + for ( TDF_ChildIterator it(L, Standard_True); it.More(); it.Next() ) + { + TDF_Label SubL = it.Value(); + + // Access name recorded in OCAF TDataStd_Name attribute + Handle(TCollection_HAsciiString) hSubName = new TCollection_HAsciiString; + if ( !GetLabelName(SubL, hSubName) ) + continue; + + // Access topological data + TopoDS_Shape SubS = XCAFDoc_ShapeTool::GetShape(SubL); + if ( SubS.IsNull() ) + continue; + + // Access the correspondent STEP Representation Item + Handle(StepRepr_RepresentationItem) RI; + Handle(TransferBRep_ShapeMapper) aShMapper = TransferBRep::ShapeMapper(FP, SubS); + if ( !FP->FindTypedTransient(aShMapper, STANDARD_TYPE(StepRepr_RepresentationItem), RI) ) + continue; + + // Record the name + RI->SetName(hSubName); + } + } + } + return Standard_True; } diff --git a/src/XDEDRAW/XDEDRAW.cxx b/src/XDEDRAW/XDEDRAW.cxx index 02819baa08..aafa46f02a 100755 --- a/src/XDEDRAW/XDEDRAW.cxx +++ b/src/XDEDRAW/XDEDRAW.cxx @@ -40,6 +40,8 @@ #include #include +#include + #include #include #include @@ -161,6 +163,48 @@ static Standard_Integer saveDoc (Draw_Interpretor& di, Standard_Integer argc, co return 0; } +//======================================================================= +//function : openDoc +//purpose : +//======================================================================= +static Standard_Integer openDoc (Draw_Interpretor& di, Standard_Integer argc, const char** argv) +{ + Handle(TDocStd_Document) D; + Handle(DDocStd_DrawDocument) DD; + Handle(TDocStd_Application) A; + + if ( !DDocStd::Find(A) ) + return 1; + + if ( argc != 3 ) + { + di << "invalid number of arguments. Usage:\t XOpen filename docname" << "\n"; + return 1; + } + + Standard_CString Filename = argv[1]; + Standard_CString DocName = argv[2]; + + if ( DDocStd::GetDocument(DocName, D, Standard_False) ) + { + di << "document with name " << DocName << " already exists" << "\n"; + return 1; + } + + if ( A->Open(Filename, D) != PCDM_RS_OK ) + { + di << "cannot open XDE document" << "\n"; + return 1; + } + + DD = new DDocStd_DrawDocument(D); + TDataStd_Name::Set(D->GetData()->Root(), DocName); + Draw::Set(DocName, DD); + + di << "document " << DocName << " opened" << "\n"; + + return 0; +} //======================================================================= //function : dump @@ -841,6 +885,9 @@ void XDEDRAW::Init(Draw_Interpretor& di) static Standard_Boolean initactor = Standard_False; if (initactor) return; initactor = Standard_True; + // Load static variables for STEPCAF (ssv; 16.08.2012) + STEPCAFControl_Controller::Init(); + // OCAF *** szy: use command // DDF::AllCommands(di); @@ -867,6 +914,9 @@ void XDEDRAW::Init(Draw_Interpretor& di) di.Add ("XSave","[Doc Path] \t: Save Doc or first document in session", __FILE__, saveDoc, g); + di.Add ("XOpen","Path Doc \t: Open XDE Document with name Doc from Path", + __FILE__, openDoc, g); + di.Add ("Xdump","Doc [int deep (0/1)] \t: Print information about tree's structure", __FILE__, dump, g); diff --git a/tests/bugs/xde/CR23384 b/tests/bugs/xde/CR23384 index 0894f3a972..bcfc0601b2 100755 --- a/tests/bugs/xde/CR23384 +++ b/tests/bugs/xde/CR23384 @@ -50,7 +50,6 @@ if { ${l0} != ${l0_1} || ${nb} != ${nb_1} || ${nbname} != ${nbname_1} } { puts "Error : Document is read/written wrong!" - puts "Error : It's $nb indtead of $check_nb!" }