From 3c76a1a31811a3430d1b061f6c9aa3df2f04e352 Mon Sep 17 00:00:00 2001 From: skl Date: Sat, 7 Nov 2020 16:42:27 +0300 Subject: [PATCH] 0030998: STEPCAFControl_Writer will not export shape with Identity Location if there are other partner shapes with diff Location. Fix + 2 tests. --- src/STEPCAFControl/STEPCAFControl_Reader.cxx | 148 +++++++++++- src/STEPCAFControl/STEPCAFControl_Reader.hxx | 26 ++- src/STEPControl/STEPControl_Reader.cxx | 55 ++++- src/XCAFDoc/XCAFDoc_ShapeTool.cxx | 231 +++++++++++++++---- src/XCAFDoc/XCAFDoc_ShapeTool.hxx | 29 ++- tests/bugs/xde/bug30998_1 | 26 +++ tests/bugs/xde/bug30998_2 | 26 +++ tests/de/step_1/B3 | 2 +- tests/de/step_1/G6 | 2 +- tests/de/step_1/G7 | 2 +- tests/de/step_1/ZD6 | 2 +- tests/de/step_1/ZG2 | 2 +- 12 files changed, 479 insertions(+), 72 deletions(-) create mode 100644 tests/bugs/xde/bug30998_1 create mode 100644 tests/bugs/xde/bug30998_2 diff --git a/src/STEPCAFControl/STEPCAFControl_Reader.cxx b/src/STEPCAFControl/STEPCAFControl_Reader.cxx index 2772edc2d6..45628f74a2 100644 --- a/src/STEPCAFControl/STEPCAFControl_Reader.cxx +++ b/src/STEPCAFControl/STEPCAFControl_Reader.cxx @@ -707,10 +707,11 @@ Standard_Boolean STEPCAFControl_Reader::Transfer (STEPControl_Reader &reader, if (STool.IsNull()) return Standard_False; XCAFDoc_DataMapOfShapeLabel map; if (asOne) - Lseq.Append(AddShape(reader.OneShape(), STool, NewShapesMap, ShapePDMap, PDFileMap, map)); + Lseq.Append(AddShape2(reader.OneShape(), STool, NewShapesMap, ShapePDMap, PDFileMap, map)); else { for (i = 1; i <= num; i++) { - Lseq.Append(AddShape(reader.Shape(i), STool, NewShapesMap, ShapePDMap, PDFileMap, map)); + //Lseq.Append(AddShape(reader.Shape(i), STool, NewShapesMap, ShapePDMap, PDFileMap, map)); + Lseq.Append(AddShape2(reader.Shape(i), STool, NewShapesMap, ShapePDMap, PDFileMap, map)); } } @@ -766,7 +767,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 +780,17 @@ 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 + //AddShape(S0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap, theLevel + 1); + //TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, 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); // 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 +835,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 +848,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())) { @@ -860,6 +864,134 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S, } //======================================================================= +//function : AddExternRefs +//purpose : +//======================================================================= + +void STEPCAFControl_Reader::AddExternRefs( + const TopoDS_Shape &S, + const Handle(XCAFDoc_ShapeTool) &STool, + const TopTools_MapOfShape &NewShapesMap, + const STEPCAFControl_DataMapOfShapePD &ShapePDMap, + const STEPCAFControl_DataMapOfPDExternFile &PDFileMap) const +{ + // for compounds, compute number of subshapes and check whether this is assembly + Standard_Boolean isAssembly = Standard_False; + Standard_Integer nbComponents = 0; + TopoDS_Iterator it; + if (S.ShapeType() == TopAbs_COMPOUND) { + for (it.Initialize(S); it.More() && !isAssembly; it.Next(), nbComponents++) { + TopoDS_Shape Sub0 = it.Value(); + TopLoc_Location loc; + Sub0.Location(loc); + if (NewShapesMap.Contains(Sub0)) isAssembly = Standard_True; + } + } + + // check whether it has associated external ref + TColStd_SequenceOfHAsciiString SHAS; + if (ShapePDMap.IsBound(S) && PDFileMap.IsBound(ShapePDMap.Find(S))) { + Handle(STEPCAFControl_ExternFile) EF = PDFileMap.Find(ShapePDMap.Find(S)); + if (!EF.IsNull()) { + // (store information on extern refs in the document) + SHAS.Append(EF->GetName()); + // if yes, just return corresponding label + if (!EF->GetLabel().IsNull()) { + // but if components >0, ignore extern ref! + if (nbComponents <= 0) + { + if (STool->AddExternRef(S, EF->GetLabel())) + { + STool->SetExternRefs(EF->GetLabel(), SHAS); + } + return; + } + } + } + } + + if (isAssembly) + { + // or as assembly, component-by-component + for (it.Initialize(S); it.More(); it.Next()) + { + TopoDS_Shape Sub0 = it.Value(); + TopLoc_Location loc; + Sub0.Location(loc); + AddExternRefs(Sub0, STool, NewShapesMap, ShapePDMap, PDFileMap); + } + } +} + +//======================================================================= +//function : AddShape2 +//purpose : +//======================================================================= + +TDF_Label STEPCAFControl_Reader::AddShape2( + 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) const +{ + // if shape has already been mapped, just return corresponding label + if (ShapeLabelMap.IsBound(S)) { + return ShapeLabelMap.Find(S); + } + + // if shape is not compound, simple add it + if (S.ShapeType() != TopAbs_COMPOUND) { + TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, theLevel == 0); + ShapeLabelMap.Bind(S, L); + return L; + } + + AddExternRefs(S, STool, NewShapesMap, ShapePDMap, PDFileMap); + + // for compounds, compute number of subshapes and check whether this is assembly + //Standard_Boolean isAssembly = Standard_False; + //Standard_Integer nbComponents = 0; + //TopoDS_Iterator it; + //for (it.Initialize(S); it.More() && !isAssembly; it.Next(), nbComponents++) { + // TopoDS_Shape Sub0 = it.Value(); + // TopLoc_Location loc; + // Sub0.Location(loc); + // if (NewShapesMap.Contains(Sub0)) isAssembly = Standard_True; + //} + + TopoDS_Iterator it; + Standard_Boolean ignoreExternRef = Standard_False; + TopTools_MapOfShape::Iterator itSh(NewShapesMap); + for (; itSh.More(); itSh.Next()) + { + TopoDS_Shape currSh = itSh.Value(); + for (it.Initialize(currSh); it.More(); it.Next()) + { + TopoDS_Shape Sub0 = it.Value(); + TopLoc_Location loc; + Sub0.Location(loc); + if (NewShapesMap.Contains(Sub0)) + { + // it is assembly + STool->AddAssemblyShape(currSh); + if (S.IsEqual(currSh)) + { + ignoreExternRef = Standard_True; + } + break; + } + } + } + + TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, Standard_True); + + return L; +} + + //======================================================================= //function : ReadExternFile //purpose : //======================================================================= diff --git a/src/STEPCAFControl/STEPCAFControl_Reader.hxx b/src/STEPCAFControl/STEPCAFControl_Reader.hxx index 2aa4d23f38..779b302f1a 100644 --- a/src/STEPCAFControl/STEPCAFControl_Reader.hxx +++ b/src/STEPCAFControl/STEPCAFControl_Reader.hxx @@ -195,8 +195,30 @@ 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; + + Standard_EXPORT TDF_Label AddShape2( + 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; + + Standard_EXPORT void AddExternRefs( + const TopoDS_Shape &S, + const Handle(XCAFDoc_ShapeTool) &STool, + const TopTools_MapOfShape &NewShapesMap, + const STEPCAFControl_DataMapOfShapePD &ShapePDMap, + const STEPCAFControl_DataMapOfPDExternFile &PDFileMap) const; + //! Reads (or if returns already read) extern file with //! given name Standard_EXPORT Handle(STEPCAFControl_ExternFile) ReadExternFile (const Standard_CString file, diff --git a/src/STEPControl/STEPControl_Reader.cxx b/src/STEPControl/STEPControl_Reader.cxx index 15ea180ba0..76fed3009c 100644 --- a/src/STEPControl/STEPControl_Reader.cxx +++ b/src/STEPControl/STEPControl_Reader.cxx @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -178,11 +179,55 @@ Standard_Integer STEPControl_Reader::NbRootsForTransfer() const Interface_Graph& graph = WS()->Graph(); // determinate roots used NextAssemblyUsageOccurrence Interface_EntityIterator subs = graph.Sharings(PD); - for(subs.Start(); subs.More(); subs.Next()) { - Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = - Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs.Value()); - if (NAUO.IsNull()) continue; - if (PD==NAUO->RelatedProductDefinition()) IsRoot=Standard_False; + Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO; + for (subs.Start(); subs.More() && IsRoot; subs.Next()) + { + if (subs.Value()->IsKind(STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence))) + { + NAUO = Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs.Value()); + if (PD == NAUO->RelatedProductDefinition()) + { + IsRoot = Standard_False; + break; + } + } + } + if (NAUO.IsNull()) + { + // use additional check using RepresentationRelationship entities + subs = graph.Sharings(PD); + for (subs.Start(); subs.More() && IsRoot; subs.Next()) + { + Handle(StepRepr_ProductDefinitionShape) aPDS = + Handle(StepRepr_ProductDefinitionShape)::DownCast(subs.Value()); + if (!aPDS.IsNull()) + { + Interface_EntityIterator subs2 = graph.Sharings(aPDS); + Handle(StepShape_ShapeDefinitionRepresentation) aSDR; + for (subs2.Start(); subs2.More(); subs2.Next()) + { + aSDR = Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs2.Value()); + if (!aSDR.IsNull()) break; + } + if (aSDR.IsNull()) continue; + Handle(StepShape_ShapeRepresentation) aSR = + Handle(StepShape_ShapeRepresentation)::DownCast(aSDR->UsedRepresentation()); + subs2 = graph.Sharings(aSR); + for (subs2.Start(); subs2.More(); subs2.Next()) + { + Handle(StepRepr_ShapeRepresentationRelationship) aSRR = + Handle(StepRepr_ShapeRepresentationRelationship)::DownCast(subs2.Value()); + if (!aSRR.IsNull()) + { + if (aSRR->Rep2() == aSR) + { + IsRoot = Standard_False; + break; + } + } + } + } + } } // determinate roots used ProductDefinitionContext if(IsRoot) { diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx index 2bc4807259..0ebeb3d8b2 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx @@ -222,36 +222,36 @@ Standard_Boolean XCAFDoc_ShapeTool::Search (const TopoDS_Shape &S, // search among shapes Standard_Boolean isLocated = ! S.Location().IsIdentity(); - if ( isLocated ) { + if (isLocated) { // try to find top-level instance - if ( findInstance && FindShape ( S, L, Standard_True ) ) + if (findInstance && FindShape(S, L, Standard_True)) return Standard_True; // try to find component of assembly - if ( findComponent ) { + if (findComponent) { TDF_LabelSequence labels; - GetShapes ( labels ); - for ( Standard_Integer i=1; i <= labels.Length(); i++ ) { - if ( ! IsAssembly ( labels.Value(i) ) ) continue; - TDF_LabelSequence comp; - GetComponents ( labels.Value(i), comp ); - for ( Standard_Integer j=1; j <= comp.Length(); j++ ) { - TopoDS_Shape c = GetShape ( comp.Value(j) ); - if ( c.IsSame ( S ) ) { - L = comp.Value(j); - return Standard_True; - } - } + GetShapes(labels); + for (Standard_Integer i = 1; i <= labels.Length(); i++) { + if (!IsAssembly(labels.Value(i))) continue; + TDF_LabelSequence comp; + GetComponents(labels.Value(i), comp); + for (Standard_Integer j = 1; j <= comp.Length(); j++) { + TopoDS_Shape c = GetShape(comp.Value(j)); + if (c.IsSame(S)) { + L = comp.Value(j); + return Standard_True; + } + } } } } // try to find top-level simple shape - if ( FindShape ( S, L, Standard_False ) ) return Standard_True; - + if (FindShape(S, L, Standard_False)) return Standard_True; + // search subshapes - if ( ! findSubShape ) return Standard_False; - TDF_Label mainL = FindMainShape ( S ); - if ( mainL.IsNull() ) return Standard_False; - L = AddSubShape ( mainL, S ); + if (!findSubShape) return Standard_False; + TDF_Label mainL = FindMainShape(S); + if (mainL.IsNull()) return Standard_False; + L = AddSubShape(mainL, S); return !L.IsNull();//Standard_True; } @@ -425,13 +425,43 @@ 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) { + //std::cout << "addShape: TShape: " << S.TShape().get() << " Loc: " << !(S.Location().IsIdentity()) << std::endl; + if (myExternRefs.IsBound(S)) + { + return myExternRefs.Find(S); + } + 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 +471,10 @@ 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); + if (!myShapeLabels.IsBound(S)) { + myShapeLabels.Bind(S0, L); + } MakeReference ( ShapeLabel, L, S.Location() ); return ShapeLabel; } @@ -450,18 +483,18 @@ TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boo TNaming_Builder tnBuild(ShapeLabel); tnBuild.Generated(S); - Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel); + //Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel); // if ( ! ShapeLabel.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) { // A = XCAFDoc_ShapeMapTool::Set(ShapeLabel); // ShapeLabel.AddAttribute(A); // } - A->SetShape(S); + //A->SetShape(S); if (theAutoNaming) SetLabelNameByShape(ShapeLabel); // if shape is Compound and flag is set, create assembly - if ( makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) { + if ( (makeAssembly || myAsseblies.Contains(S)) && S.ShapeType() == TopAbs_COMPOUND ) { // mark assembly by assigning UAttribute Handle(TDataStd_UAttribute) Uattr; Uattr = TDataStd_UAttribute::Set ( ShapeLabel, XCAFDoc::AssemblyGUID() ); @@ -470,20 +503,27 @@ TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boo // iterate on components TopoDS_Iterator Iterator(S); - for (; Iterator.More(); Iterator.Next()) { + for (; Iterator.More(); Iterator.Next()) + { + // prepare label for component + TDF_Label RefLabel = aTag.NewChild(ShapeLabel); // get label for component`s shape TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp; TopLoc_Location loc; S0.Location ( loc ); - TDF_Label compL = addShape ( S0, makeAssembly ); - - // add a component as reference - TDF_Label RefLabel = aTag.NewChild(ShapeLabel); + TDF_Label compL = addShape(S0, makeAssembly, theLevel + 1); + if (!myShapeLabels.IsBound(S)) { + myShapeLabels.Bind(S0, compL); + } + // add reference MakeReference ( RefLabel, compL, Scomp.Location() ); } } - if(!IsAssembly(ShapeLabel)) { + if(!IsAssembly(ShapeLabel)) + { + Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel); + A->SetShape(S); //const TopTools_IndexedMapOfShape tmpMap = A->GetMap(); //for(Standard_Integer i=1; i<=tmpMap.Extent(); i++) //mySubShapes.Bind(tmpMap.FindKey(i),ShapeLabel); @@ -546,19 +586,75 @@ 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) +{ + //{ + // std::cout << std::endl << "----- myExternRefs: " << std::endl; + // XCAFDoc_DataMapOfShapeLabel::Iterator itSL(myExternRefs); + // for (; itSL.More(); itSL.Next()) + // { + // std::cout << " TShape: " << itSL.Key().TShape().get() << " Loc: " << !(itSL.Key().Location().IsIdentity()) << std::endl; + // } + //} // 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); } + //{ + // std::cout << std::endl << "----- Shapes: " << std::endl; + // XCAFDoc_DataMapOfShapeLabel::Iterator itSL(myShapeLabels); + // for (; itSL.More(); itSL.Next()) + // { + // std::cout << "Shape: TShape: " << itSL.Key().TShape().get() << " Loc: " << !(itSL.Key().Location().IsIdentity()) << std::endl; + // } + //} + //{ + // std::cout << "----- SubShapes: " << std::endl; + // XCAFDoc_DataMapOfShapeLabel::Iterator itSL(mySubShapes); + // for (; itSL.More(); itSL.Next()) + // { + // std::cout << "Shape: TShape: " << itSL.Key().TShape().get() << " Loc: " << !(itSL.Key().Location().IsIdentity()) << std::endl; + // } + //} + //std::cout << "----- mySimpleShapes: " << std::endl; + //XCAFDoc_DataMapOfShapeLabel::Iterator itSL(mySimpleShapes); + //for (; itSL.More(); itSL.Next()) + //{ + // std::cout << "Shape: TShape: " << itSL.Key().TShape().get() << " Loc: " << !(itSL.Key().Location().IsIdentity()) << std::endl; + //} + return L; //return addShape( S, makeAssembly ); @@ -903,29 +999,53 @@ Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L, return Standard_True; } +//======================================================================= +//function : AddLocatedShape +//purpose : +//======================================================================= + +TDF_Label XCAFDoc_ShapeTool::AddLocatedShape ( + const TDF_Label& theParentL, + const TDF_Label& theShape0L, + const TopoDS_Shape& theShape) +{ + // add as reference + TDF_TagSource aTag; + TDF_Label L = aTag.NewChild(theParentL); + TNaming_Builder tnBuild(L); + tnBuild.Generated(theShape); + MakeReference ( L, theShape0L, theShape.Location()); + + // map shape to label + if (!myShapeLabels.IsBound(theShape)) + myShapeLabels.Bind(theShape, L); + + return L; +} + //======================================================================= //function : AddComponent //purpose : //======================================================================= -TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, - const TDF_Label& compL, - const TopLoc_Location &Loc) +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 (!IsAssembly(assembly)) { // if it is simple shape, make it assembly - if ( IsSimpleShape(assembly) ) - TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() ); + 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 ); + MakeReference(L, compL, Loc); // map shape to label TopoDS_Shape aShape; @@ -952,8 +1072,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() ); } @@ -2125,6 +2245,19 @@ Handle(TDataStd_NamedData) XCAFDoc_ShapeTool::GetNamedProperties (const TopoDS_S return aNamedProperty; } +//======================================================================= +//function : AddExternRef +//purpose : +//======================================================================= +Standard_Boolean XCAFDoc_ShapeTool::AddExternRef(const TopoDS_Shape& theShape, const TDF_Label& theLabel) +{ + if (!myExternRefs.IsBound(theShape)) { + myExternRefs.Bind(theShape, theLabel); + return Standard_True; + } + return Standard_False; +} + //======================================================================= //function : DumpJson //purpose : diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx index 8980edb353..3f735c6f55 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx @@ -29,6 +29,7 @@ #include #include #include +#include #include class Standard_GUID; class TDF_Label; @@ -213,7 +214,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 +277,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& theShape0L, + const TopoDS_Shape& theShape); + //! 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); @@ -423,6 +434,15 @@ public: //! Dumps the content of me into the stream Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE; + //! Add shape which must be added as assembly in the method AddShape() + Standard_EXPORT void AddAssemblyShape(const TopoDS_Shape& theAssemblyShape) + { + myAsseblies.Add(theAssemblyShape); + } + + //! Add extern reference + Standard_EXPORT Standard_Boolean AddExternRef(const TopoDS_Shape& theShape, const TDF_Label& theLabel); + DEFINE_DERIVED_ATTRIBUTE(XCAFDoc_ShapeTool,TDataStd_GenericEmpty) @@ -438,7 +458,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 @@ -453,7 +475,8 @@ private: XCAFDoc_DataMapOfShapeLabel mySubShapes; XCAFDoc_DataMapOfShapeLabel mySimpleShapes; Standard_Boolean hasSimpleShapes; - + TopTools_MapOfShape myAsseblies; + XCAFDoc_DataMapOfShapeLabel myExternRefs; }; 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 + + diff --git a/tests/de/step_1/B3 b/tests/de/step_1/B3 index 5d4b097326..f3bc5867fb 100644 --- a/tests/de/step_1/B3 +++ b/tests/de/step_1/B3 @@ -11,7 +11,7 @@ CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) So NBSHAPES : Solid = 1 ( 1 ) Shell = 38 ( 38 ) Face = 115 ( 115 ) STATSHAPE : Solid = 2 ( 2 ) Shell = 76 ( 76 ) Face = 230 ( 230 ) FreeWire = 0 ( 0 ) TOLERANCE : MaxTol = 1e-007 ( 1e-007 ) AvgTol = 1e-007 ( 1e-007 ) -LABELS : N0Labels = 41 ( 41 ) N1Labels = 41 ( 41 ) N2Labels = 0 ( 0 ) TotalLabels = 82 ( 82 ) NameLabels = 82 ( 81 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) +LABELS : N0Labels = 41 ( 41 ) N1Labels = 41 ( 41 ) N2Labels = 0 ( 0 ) TotalLabels = 82 ( 82 ) NameLabels = 82 ( 82 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 0 ( 0 ) COLORS : Colors = ( ) diff --git a/tests/de/step_1/G6 b/tests/de/step_1/G6 index 16b782657d..7a501f516a 100644 --- a/tests/de/step_1/G6 +++ b/tests/de/step_1/G6 @@ -12,7 +12,7 @@ CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) So NBSHAPES : Solid = 5 ( 5 ) Shell = 5 ( 5 ) Face = 53 ( 53 ) STATSHAPE : Solid = 18 ( 18 ) Shell = 18 ( 18 ) Face = 160 ( 160 ) FreeWire = 0 ( 0 ) TOLERANCE : MaxTol = 7.326475973e-006 ( 7.326473926e-006 ) AvgTol = 2.618918051e-006 ( 2.651443623e-006 ) -LABELS : N0Labels = 9 ( 9 ) N1Labels = 13 ( 13 ) N2Labels = 0 ( 0 ) TotalLabels = 22 ( 22 ) NameLabels = 22 ( 19 ) ColorLabels = 5 ( 5 ) LayerLabels = 5 ( 12 ) +LABELS : N0Labels = 9 ( 9 ) N1Labels = 13 ( 13 ) N2Labels = 0 ( 0 ) TotalLabels = 22 ( 22 ) NameLabels = 22 ( 22 ) ColorLabels = 5 ( 5 ) LayerLabels = 5 ( 18 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 5 ( 5 ) COLORS : Colors = CYAN GOLD3 RED3 TURQUOISE4 YELLOW ( CYAN GOLD3 RED3 TURQUOISE4 YELLOW ) diff --git a/tests/de/step_1/G7 b/tests/de/step_1/G7 index 80dc2505e3..c72e132ba8 100644 --- a/tests/de/step_1/G7 +++ b/tests/de/step_1/G7 @@ -12,7 +12,7 @@ CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) So NBSHAPES : Solid = 5 ( 5 ) Shell = 5 ( 5 ) Face = 53 ( 53 ) STATSHAPE : Solid = 18 ( 18 ) Shell = 18 ( 18 ) Face = 160 ( 160 ) FreeWire = 0 ( 0 ) TOLERANCE : MaxTol = 1e-007 ( 1e-007 ) AvgTol = 1e-007 ( 1e-007 ) -LABELS : N0Labels = 9 ( 9 ) N1Labels = 13 ( 13 ) N2Labels = 0 ( 0 ) TotalLabels = 22 ( 22 ) NameLabels = 22 ( 19 ) ColorLabels = 5 ( 5 ) LayerLabels = 5 ( 12 ) +LABELS : N0Labels = 9 ( 9 ) N1Labels = 13 ( 13 ) N2Labels = 0 ( 0 ) TotalLabels = 22 ( 22 ) NameLabels = 22 ( 22 ) ColorLabels = 5 ( 5 ) LayerLabels = 5 ( 18 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 5 ( 5 ) COLORS : Colors = CYAN GOLD3 RED3 TURQUOISE4 YELLOW ( CYAN GOLD3 RED3 TURQUOISE4 YELLOW ) diff --git a/tests/de/step_1/ZD6 b/tests/de/step_1/ZD6 index 04fc100ad1..64b379c596 100644 --- a/tests/de/step_1/ZD6 +++ b/tests/de/step_1/ZD6 @@ -12,7 +12,7 @@ CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) So NBSHAPES : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 15 ( 15 ) STATSHAPE : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 15 ( 15 ) FreeWire = 0 ( 0 ) TOLERANCE : MaxTol = 1e-007 ( 1e-007 ) AvgTol = 1e-007 ( 1e-007 ) -LABELS : N0Labels = 3 ( 3 ) N1Labels = 2 ( 2 ) N2Labels = 0 ( 0 ) TotalLabels = 5 ( 5 ) NameLabels = 5 ( 4 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) +LABELS : N0Labels = 3 ( 3 ) N1Labels = 2 ( 2 ) N2Labels = 0 ( 0 ) TotalLabels = 5 ( 5 ) NameLabels = 5 ( 5 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 0 ( 0 ) COLORS : Colors = ( ) diff --git a/tests/de/step_1/ZG2 b/tests/de/step_1/ZG2 index a237eed2e5..e62c606ac2 100644 --- a/tests/de/step_1/ZG2 +++ b/tests/de/step_1/ZG2 @@ -11,7 +11,7 @@ CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) So NBSHAPES : Solid = 5 ( 5 ) Shell = 5 ( 5 ) Face = 39 ( 39 ) STATSHAPE : Solid = 18 ( 18 ) Shell = 18 ( 18 ) Face = 125 ( 125 ) FreeWire = 0 ( 0 ) TOLERANCE : MaxTol = 1e-007 ( 1e-005 ) AvgTol = 1e-007 ( 2.879942693e-006 ) -LABELS : N0Labels = 9 ( 9 ) N1Labels = 13 ( 13 ) N2Labels = 0 ( 0 ) TotalLabels = 22 ( 22 ) NameLabels = 22 ( 19 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) +LABELS : N0Labels = 9 ( 9 ) N1Labels = 13 ( 13 ) N2Labels = 0 ( 0 ) TotalLabels = 22 ( 22 ) NameLabels = 22 ( 22 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 0 ( 0 ) COLORS : Colors = ( ) -- 2.39.5