From: skl Date: Tue, 3 Nov 2020 12:18:44 +0000 (+0300) Subject: 0030998: STEPCAFControl_Writer will not export shape with Identity Location if there... X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=2dc0f60638595233a3533c5b2b1ea27d2cc08529;p=occt-copy.git 0030998: STEPCAFControl_Writer will not export shape with Identity Location if there are other partner shapes with diff Location. Fix + 2 Draw tests. --- diff --git a/src/STEPCAFControl/STEPCAFControl_Reader.cxx b/src/STEPCAFControl/STEPCAFControl_Reader.cxx index 2772edc2d6..16e99f1ece 100644 --- a/src/STEPCAFControl/STEPCAFControl_Reader.cxx +++ b/src/STEPCAFControl/STEPCAFControl_Reader.cxx @@ -766,7 +766,8 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S, const TopTools_MapOfShape &NewShapesMap, const STEPCAFControl_DataMapOfShapePD &ShapePDMap, const STEPCAFControl_DataMapOfPDExternFile &PDFileMap, - XCAFDoc_DataMapOfShapeLabel &ShapeLabelMap) const + XCAFDoc_DataMapOfShapeLabel &ShapeLabelMap, + const Standard_Integer theLevel) const { // if shape has already been mapped, just return corresponding label if (ShapeLabelMap.IsBound(S)) { @@ -778,15 +779,15 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S, TopoDS_Shape S0 = S; TopLoc_Location loc; S0.Location(loc); - AddShape(S0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap); - TDF_Label L = STool->AddShape(S, Standard_False); // should create reference + TDF_Label aS0L = AddShape(S0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap, theLevel + 1); + TDF_Label L = STool->AddLocatedShape(STool->Label(), aS0L, S.Location()); // should create reference ShapeLabelMap.Bind(S, L); return L; } // if shape is not compound, simple add it if (S.ShapeType() != TopAbs_COMPOUND) { - TDF_Label L = STool->AddShape(S, Standard_False); + TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, theLevel == 0); ShapeLabelMap.Bind(S, L); return L; } @@ -831,7 +832,7 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S, // add compound either as a whole, if (!isAssembly) { - TDF_Label L = STool->AddShape(S, Standard_False); + TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, theLevel == 0); if (SHAS.Length() > 0) STool->SetExternRefs(L, SHAS); ShapeLabelMap.Bind(S, L); return L; @@ -844,7 +845,7 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S, TopoDS_Shape Sub0 = it.Value(); TopLoc_Location loc; Sub0.Location(loc); - TDF_Label subL = AddShape(Sub0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap); + TDF_Label subL = AddShape(Sub0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap, theLevel + 1); if (!subL.IsNull()) { TDF_Label instL = STool->AddComponent(L, subL, it.Value().Location()); if (!ShapeLabelMap.IsBound(it.Value())) { diff --git a/src/STEPCAFControl/STEPCAFControl_Reader.hxx b/src/STEPCAFControl/STEPCAFControl_Reader.hxx index 2aa4d23f38..1cf9962b36 100644 --- a/src/STEPCAFControl/STEPCAFControl_Reader.hxx +++ b/src/STEPCAFControl/STEPCAFControl_Reader.hxx @@ -195,7 +195,13 @@ protected: //! Depending on a case, this shape can be added as one, or //! as assembly, or (in case if it is associated with external //! reference) taken as that referred shape - Standard_EXPORT TDF_Label AddShape (const TopoDS_Shape& S, const Handle(XCAFDoc_ShapeTool)& STool, const TopTools_MapOfShape& NewShapesMap, const STEPCAFControl_DataMapOfShapePD& ShapePDMap, const STEPCAFControl_DataMapOfPDExternFile& PDFileMap, XCAFDoc_DataMapOfShapeLabel& ShapeLabelMap) const; + Standard_EXPORT TDF_Label AddShape(const TopoDS_Shape& S, + const Handle(XCAFDoc_ShapeTool)& STool, + const TopTools_MapOfShape& NewShapesMap, + const STEPCAFControl_DataMapOfShapePD& ShapePDMap, + const STEPCAFControl_DataMapOfPDExternFile& PDFileMap, + XCAFDoc_DataMapOfShapeLabel& ShapeLabelMap, + const Standard_Integer theLevel = 0) const; //! Reads (or if returns already read) extern file with //! given name diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx index 2bc4807259..58a7be183c 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx @@ -425,13 +425,37 @@ void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L, //purpose : private //======================================================================= -TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly) +TDF_Label XCAFDoc_ShapeTool::addShape ( + const TopoDS_Shape& S, + const Standard_Boolean makeAssembly, + const Standard_Integer theLevel) { TDF_Label ShapeLabel; TDF_TagSource aTag; + if (S.IsNull()) return ShapeLabel; + // search if the shape already exists (with the same location) - if ( S.IsNull() || FindShape ( S, ShapeLabel, Standard_True ) ) return ShapeLabel; + if (FindShape(S, ShapeLabel, Standard_True)) + { + Standard_Boolean needUpdate = !makeAssembly && S.Location().IsIdentity() && (theLevel==0 || IsFree(ShapeLabel)); + if (needUpdate) + { + // such shape without location is placed on the top level + // but also we want to use this shape as a referenced shape for other + // top level shape => in order to avoid of missing shape we have to + // prepare new shape with location in the point (0,0,0) and make reference + // to current shape without location + TopoDS_Shape newS = S.EmptyCopied(); + gp_Trsf aTrsf; + TopLoc_Location loc(aTrsf); + newS.Location(loc); + TDF_Label L = aTag.NewChild(Label()); + MakeReference(L, ShapeLabel, newS.Location()); + myShapeLabels.Bind(newS, L); + } + return ShapeLabel; + } // else add a new label ShapeLabel = aTag.NewChild(Label()); @@ -441,7 +465,7 @@ TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boo TopoDS_Shape S0 = S; TopLoc_Location loc; S0.Location ( loc ); - TDF_Label L = addShape ( S0, makeAssembly ); + TDF_Label L = addShape(S0, makeAssembly, theLevel + 1); MakeReference ( ShapeLabel, L, S.Location() ); return ShapeLabel; } @@ -475,7 +499,7 @@ TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boo TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp; TopLoc_Location loc; S0.Location ( loc ); - TDF_Label compL = addShape ( S0, makeAssembly ); + TDF_Label compL = addShape(S0, makeAssembly, theLevel + 1); // add a component as reference TDF_Label RefLabel = aTag.NewChild(ShapeLabel); @@ -546,14 +570,39 @@ static Standard_Boolean prepareAssembly (const TopoDS_Shape& theShape, TDF_Label XCAFDoc_ShapeTool::AddShape (const TopoDS_Shape& theShape, const Standard_Boolean makeAssembly, - const Standard_Boolean makePrepare) + const Standard_Boolean makePrepare, + const Standard_Boolean freeShape) { // PTV 17.02.2003 to avoid components without location. TopoDS_Shape S = theShape; if ( makePrepare && makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) prepareAssembly( theShape, S ); // OCC1669 - - TDF_Label L = addShape(S,makeAssembly); + + if (!makeAssembly && S.Location().IsIdentity() && freeShape) + { + // search if the shape already exists (with the same location) + TDF_Label ShapeLabel; + if (FindShape(S, ShapeLabel, Standard_True)) + { + // such shape without location is placed on the top level + // but also this shape is a referenced shape for other top level shape + // therefore in order to avoid of missing shape we have to prepare new + // shape with location in the point (0,0,0) and make reference to + // existed shape without location + TopoDS_Shape newS = S.EmptyCopied(); + gp_Trsf aTrsf; + TopLoc_Location loc(aTrsf); + newS.Location(loc); + TDF_TagSource aTag; + TDF_Label L = aTag.NewChild(Label()); + MakeReference(L, ShapeLabel, newS.Location()); + myShapeLabels.Bind(newS, L); + return L; + } + } + + Standard_Integer aLevel = freeShape ? 0 : 1; + TDF_Label L = addShape(S,makeAssembly, aLevel); if(!myShapeLabels.IsBound(S)) { myShapeLabels.Bind(S,L); @@ -904,28 +953,19 @@ Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L, } //======================================================================= -//function : AddComponent +//function : AddLocatedShape //purpose : //======================================================================= -TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, - const TDF_Label& compL, - const TopLoc_Location &Loc) +TDF_Label XCAFDoc_ShapeTool::AddLocatedShape ( + const TDF_Label& theParentL, + const TDF_Label& theShapeL, + const TopLoc_Location &theLoc) { - TDF_Label L; - - // check that shape is assembly - if ( ! IsAssembly(assembly) ) { - // if it is simple shape, make it assembly - if ( IsSimpleShape(assembly) ) - TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() ); - else return L; - } - - // add a component as reference + // add as reference TDF_TagSource aTag; - L = aTag.NewChild(assembly); - MakeReference ( L, compL, Loc ); + TDF_Label L = aTag.NewChild(theParentL); + MakeReference ( L, theShapeL, theLoc); // map shape to label TopoDS_Shape aShape; @@ -943,6 +983,28 @@ TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, //purpose : //======================================================================= +TDF_Label XCAFDoc_ShapeTool::AddComponent(const TDF_Label& assembly, + const TDF_Label& compL, + const TopLoc_Location &Loc) +{ + TDF_Label L; + + // check that shape is assembly + if (!IsAssembly(assembly)) { + // if it is simple shape, make it assembly + if (IsSimpleShape(assembly)) + TDataStd_UAttribute::Set(assembly, XCAFDoc::AssemblyGUID()); + else return L; + } + + return AddLocatedShape(assembly, compL, Loc); +} + +//======================================================================= +//function : AddComponent +//purpose : +//======================================================================= + TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, const TopoDS_Shape& comp, const Standard_Boolean expand) @@ -952,8 +1014,8 @@ TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, TopLoc_Location loc; S0.Location ( loc ); TDF_Label compL; - compL = AddShape ( S0, expand ); - + compL = AddShape ( S0, expand, Standard_True, Standard_False); + // add component by its label return AddComponent ( assembly, compL, comp.Location() ); } diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx index 8980edb353..16cda13bff 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx @@ -213,7 +213,10 @@ public: //! NOTE: replace components without location //! in assmebly by located components to avoid some problems. //! If AutoNaming() is True then automatically attaches names. - Standard_EXPORT TDF_Label AddShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly = Standard_True, const Standard_Boolean makePrepare = Standard_True); + Standard_EXPORT TDF_Label AddShape (const TopoDS_Shape& S, + const Standard_Boolean makeAssembly = Standard_True, + const Standard_Boolean makePrepare = Standard_True, + const Standard_Boolean freeShape = Standard_True); //! Removes shape (whole label and all its sublabels) //! If removeCompletely is true, removes complete shape @@ -273,6 +276,13 @@ public: //! Returns False if label is not assembly Standard_EXPORT static Standard_Boolean GetComponents (const TDF_Label& L, TDF_LabelSequence& Labels, const Standard_Boolean getsubchilds = Standard_False); + //! Adds a shape (without location) given by its label (theShapeL) + //! to the theParentL with given location + Standard_EXPORT TDF_Label AddLocatedShape( + const TDF_Label& theParentL, + const TDF_Label& theShapeL, + const TopLoc_Location &theLoc); + //! Adds a component given by its label and location to the assembly //! Note: assembly must be IsAssembly() or IsSimpleShape() Standard_EXPORT TDF_Label AddComponent (const TDF_Label& assembly, const TDF_Label& comp, const TopLoc_Location& Loc); @@ -438,7 +448,9 @@ private: //! Adds a new top-level (creates and returns a new label) //! For internal use. Used by public method AddShape. - Standard_EXPORT TDF_Label addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly = Standard_True); + Standard_EXPORT TDF_Label addShape (const TopoDS_Shape& S, + const Standard_Boolean makeAssembly = Standard_True, + const Standard_Integer theLevel = 0); //! Makes a shape on label L to be a reference to shape refL //! with location loc @@ -454,7 +466,6 @@ private: XCAFDoc_DataMapOfShapeLabel mySimpleShapes; Standard_Boolean hasSimpleShapes; - }; diff --git a/tests/bugs/xde/bug30998_1 b/tests/bugs/xde/bug30998_1 new file mode 100644 index 0000000000..2f2eac0c65 --- /dev/null +++ b/tests/bugs/xde/bug30998_1 @@ -0,0 +1,26 @@ +puts "# ==============================================================================" +puts "# 0030998: STEPCAFControl_Writer will not export shape with Identity Location" +puts "# if there are other partner shapes with diff Location." +puts "# ==============================================================================" + +# tests bug30998_1 and bug30998_2 differ in the order of adding shapes to the document +# it is needed to check various parts of XDE functionality + +pload OCAF XDE MODELING + +restore [locate_data_file bug30998.brep] a +NewDocument D +explode a +XAddShape D a_1 0 +XAddShape D a_2 0 +WriteStep D $imagedir/${casename}.stp +ReadStep D1 $imagedir/${casename}.stp +XGetOneShape res D1 + +checkprops res -s 784473 + +checkshape res + +checknbshapes res -vertex 2 -edge 3 -wire 3 -face 3 -shell 1 -solid 1 -compsolid 0 -compound 3 -shape 16 + + diff --git a/tests/bugs/xde/bug30998_2 b/tests/bugs/xde/bug30998_2 new file mode 100644 index 0000000000..04566087bb --- /dev/null +++ b/tests/bugs/xde/bug30998_2 @@ -0,0 +1,26 @@ +puts "# ==============================================================================" +puts "# 0030998: STEPCAFControl_Writer will not export shape with Identity Location" +puts "# if there are other partner shapes with diff Location." +puts "# ==============================================================================" + +# tests bug30998_1 and bug30998_2 differ in the order of adding shapes to the document +# it is needed to check various parts of XDE functionality + +pload OCAF XDE MODELING + +restore [locate_data_file bug30998.brep] a +NewDocument D +explode a +XAddShape D a_2 0 +XAddShape D a_1 0 +WriteStep D $imagedir/${casename}.stp +ReadStep D1 $imagedir/${casename}.stp +XGetOneShape res D1 + +checkprops res -s 784473 + +checkshape res + +checknbshapes res -vertex 2 -edge 3 -wire 3 -face 3 -shell 1 -solid 1 -compsolid 0 -compound 3 -shape 16 + +