From bc728d262104acf4c56d22d27ccc7ada141dc623 Mon Sep 17 00:00:00 2001 From: ika Date: Fri, 16 Mar 2018 16:18:10 +0300 Subject: [PATCH] 0029599: Data Exchange - Incorrect expand compound method in XDE Improve processing of subshapes in ShapeTool Fix sharing and calculating location for subshapes Switch off autonaming for expand --- src/XCAFDoc/XCAFDoc_Editor.cxx | 15 ++- src/XCAFDoc/XCAFDoc_ShapeTool.cxx | 159 +++++++++++++++++------------- src/XCAFDoc/XCAFDoc_ShapeTool.hxx | 2 +- tests/bugs/xde/bug29599 | 36 +++++++ 4 files changed, 136 insertions(+), 76 deletions(-) create mode 100644 tests/bugs/xde/bug29599 diff --git a/src/XCAFDoc/XCAFDoc_Editor.cxx b/src/XCAFDoc/XCAFDoc_Editor.cxx index 0c3f492da0..7db50b309f 100644 --- a/src/XCAFDoc/XCAFDoc_Editor.cxx +++ b/src/XCAFDoc/XCAFDoc_Editor.cxx @@ -46,6 +46,7 @@ Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const TDF_Label& Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(Doc); Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(Doc); Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(Doc); + aShapeTool->SetAutoNaming(Standard_False); TopoDS_Shape aS = aShapeTool->GetShape(Shape); if (aShapeTool->Expand(Shape)) @@ -69,15 +70,13 @@ Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const TDF_Label& if(!aShapeTool->GetShape(aPart.Father()).IsNull()) { TopLoc_Location nulloc; + aPart.ForgetAttribute(XCAFDoc::ShapeRefGUID()); + if (aShapeTool->GetShape(aPart.Father()).ShapeType() == TopAbs_COMPOUND) { - aPart.ForgetAttribute(XCAFDoc::ShapeRefGUID()); - if(aShapeTool->GetShape(aPart.Father()).ShapeType() == TopAbs_COMPOUND) - { - aShapeTool->SetShape(aPart, aShape); - } - aPart.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID()); - aChild.ForgetAllAttributes(Standard_False); + aShapeTool->SetShape(aPart, aShape); } + aPart.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID()); + aChild.ForgetAllAttributes(Standard_False); } aChild.ForgetAttribute(TNaming_NamedShape::GetID()); aChild.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID()); @@ -112,7 +111,7 @@ Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const TDF_Label& if(aShapeTool->GetReferredShape(aChild, aPart)) { TopoDS_Shape aPartShape = aShapeTool->GetShape(aPart); - if (aPartShape.ShapeType() == TopAbs_COMPOUND) + if (!aPartShape.IsNull() && aPartShape.ShapeType() == TopAbs_COMPOUND) Expand(Doc, aPart, recursively); } } diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx index 5be7fe6f40..b39e3b0b5f 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx @@ -329,8 +329,9 @@ TDF_Label XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S, const Standard_Boolean findInstance) const { TDF_Label L; - FindShape ( S, L, findInstance ); - return L; + if (FindShape(S, L, findInstance)) + return L; + return TDF_Label(); } //======================================================================= @@ -1035,11 +1036,12 @@ Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label &shapeL, const TopoDS_Shape &sub) const { Handle(XCAFDoc_ShapeMapTool) A; - if ( ! shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) - return Standard_False; - - //TopoDS_Shape S = GetShape ( shapeL ); - //return ! S.IsNull() && CheckSubShape ( S, sub ); + if (!shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A)) + { + A = XCAFDoc_ShapeMapTool::Set(shapeL); + TopoDS_Shape aShape = GetShape(shapeL); + A->SetShape(aShape); + } return A->IsSubShape(sub); } @@ -1085,7 +1087,8 @@ TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL, TDF_Label L; if ( FindSubShape ( shapeL, sub, L ) ) return L; - if ( ! IsSubShape ( shapeL, sub ) ) return L; + if (!IsSubShape(shapeL, sub)) + return TDF_Label(); TDF_TagSource aTag; L = aTag.NewChild(shapeL); @@ -1801,13 +1804,12 @@ Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels //function : Expand //purpose : //======================================================================= - -Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& Shape) +Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL) { - if (Shape.IsNull() || IsAssembly(Shape)) + if (theShapeL.IsNull() || IsAssembly(theShapeL)) return Standard_False; - TopoDS_Shape aShape = GetShape(Shape); + TopoDS_Shape aShape = GetShape(theShapeL); if (aShape.IsNull()) return Standard_False; @@ -1817,48 +1819,64 @@ Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& Shape) if (isExpandedType) { //set assembly attribute - TDataStd_UAttribute::Set ( Shape, XCAFDoc::AssemblyGUID() ); - + TDataStd_UAttribute::Set(theShapeL, XCAFDoc::AssemblyGUID()); TopoDS_Iterator anIter(aShape); for(; anIter.More(); anIter.Next()) { TopoDS_Shape aChildShape = anIter.Value(); - TDF_Label aChild = FindShape(aChildShape, Standard_True); - TDF_TagSource aTag; - Handle(TDataStd_Name) anAttr; - //make part for child - TDF_Label aPart = aTag.NewChild(Label()); - //make child (if color isn't set or if it is compound) - if(aChild.IsNull()) - { - TopLoc_Location nulloc; - aChild = aTag.NewChild(Shape); - SetShape(aChild, aChildShape); - SetShape(aPart, aChildShape.Located(nulloc)); + TDF_Label aChild, aPart; + + // Find child shape as subshape of expanded shape + if (!FindSubShape(theShapeL, aChildShape, aChild)) { + // Fast searchig using FindSubShape() can find only the first apparation, try to find manually + TDF_ChildIterator anIt(theShapeL); + for (; anIt.More(); anIt.Next()) { + TDF_Label aSubLabel = anIt.Value(); + TopoDS_Shape aSubS; + if (GetShape(aSubLabel, aSubS) && aSubS.IsSame(aChildShape)) { + aChild = aSubLabel; + break; + } + } } - else - { + Handle(TDataStd_Name) anAttr; + //make child (if color isn't set or if it is compound) + if (aChild.IsNull()) { + aChild = AddSubShape(theShapeL, aChildShape); + } + else { //get name aChild.FindAttribute(TDataStd_Name::GetID(), anAttr); - TopLoc_Location nulloc; - SetShape(aPart, aChildShape.Located(nulloc)); - } - //set name to part - if(!anAttr.IsNull()) - { - TDataStd_Name::Set(aPart, anAttr->Get()); - } - else - { - Standard_SStream Stream; - TopAbs::Print(aChildShape.ShapeType(), Stream); - TCollection_AsciiString aName (Stream.str().c_str()); - TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName)); } + // Try to find child shape as already existed part + aPart = FindShape(aChildShape.Located(TopLoc_Location())); + if (aPart.IsNull()) { + // Create new part to link child shape + aPart = AddShape(aChildShape.Located(TopLoc_Location()), Standard_False, Standard_False); + } + + // Add shape manually, if already existed subshape found instead of creation of new part + if (!aPart.IsNull() && !IsTopLevel(aPart)) { + if (!GetReferredShape(aPart, aPart)) { + TDF_TagSource aTag; + aPart = aTag.NewChild(Label()); + SetShape(aPart, aChildShape.Located(TopLoc_Location())); + } + } + + // set name to part + if (!anAttr.IsNull()) { + TDataStd_Name::Set(aPart, anAttr->Get()); + } + else { + Standard_SStream Stream; + TopAbs::Print(aChildShape.ShapeType(), Stream); + TCollection_AsciiString aName(Stream.str().c_str()); + TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName)); + } MakeReference(aChild, aPart, aChildShape.Location()); - - makeSubShape(aPart, aChildShape); + makeSubShape(aPart, aChildShape, aChildShape.Location()); } return Standard_True; } @@ -1870,39 +1888,46 @@ Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& Shape) //purpose : //======================================================================= -void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& Part, const TopoDS_Shape& Shape) +void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& thePart, + const TopoDS_Shape& theShape, + const TopLoc_Location& theLoc) { - TDF_TagSource aTag; - TopoDS_Iterator anIter(Shape); - for(; anIter.More(); anIter.Next()) - { + TopoDS_Iterator anIter(theShape); + Standard_Boolean isCompoundPart = (GetShape(thePart).ShapeType() == TopAbs_COMPOUND); + + for(; anIter.More(); anIter.Next()) { TopoDS_Shape aChildShape = anIter.Value(); TDF_Label aChildLabel = FindShape(aChildShape,Standard_True); - if(!aChildLabel.IsNull()) - { + if(!aChildLabel.IsNull()) { //get name Handle(TDataStd_Name) anAttr; aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr); - TopLoc_Location nulloc; + TopLoc_Location aSubLoc; + // Calculate location for subshapes of compound parts + if (isCompoundPart) + aSubLoc = theLoc.Inverted() * aChildShape.Location(); //make subshape - TDF_Label aSubLabel = aTag.NewChild(Part); - SetShape(aSubLabel, aChildShape.Located(nulloc)); - //set name to sub shape - if(!anAttr.IsNull()) - { - TDataStd_Name::Set(aSubLabel, anAttr->Get()); + TDF_Label aSubLabel; + if (!FindSubShape(thePart, aChildShape.Located(aSubLoc), aSubLabel)) { + aSubLabel = AddSubShape(thePart, aChildShape.Located(aSubLoc)); + //set name to sub shape + if (!anAttr.IsNull()) { + TDataStd_Name::Set(aSubLabel, anAttr->Get()); + } + else { + Standard_SStream Stream; + TopAbs::Print(aChildShape.ShapeType(), Stream); + TCollection_AsciiString aName(Stream.str().c_str()); + TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName)); + } + // Create auxiliary link, it will be removed during moving attributes + MakeReference(aSubLabel, aChildLabel, aChildShape.Location()); } - else - { - Standard_SStream Stream; - TopAbs::Print(aChildShape.ShapeType(), Stream); - TCollection_AsciiString aName (Stream.str().c_str()); - TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName)); + else { + aChildLabel.ForgetAllAttributes(); } - // Create auxiliary link, it will be removed during moving attributes - MakeReference(aSubLabel, aChildLabel, aChildShape.Location()); } - makeSubShape(Part, aChildShape); + makeSubShape(thePart, aChildShape, theLoc); } } diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx index ca73092c11..a8638fd7f5 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx @@ -408,7 +408,7 @@ public: Standard_EXPORT Standard_Boolean Expand (const TDF_Label& Shape) ; //! Make subshape for Part from Shape - Standard_EXPORT void makeSubShape (const TDF_Label& Part, const TopoDS_Shape& Shape) ; + Standard_EXPORT void makeSubShape (const TDF_Label& thePart, const TopoDS_Shape& theShape, const TopLoc_Location& theLoc) ; diff --git a/tests/bugs/xde/bug29599 b/tests/bugs/xde/bug29599 new file mode 100644 index 0000000000..5921021c21 --- /dev/null +++ b/tests/bugs/xde/bug29599 @@ -0,0 +1,36 @@ +puts "==========" +puts "OCC29599" +puts "==========" +puts "" +########################################## +# Incorrect expand compound method in XDE +########################################## +pload ALL + +XOpen [locate_data_file bug29599.xbf] D +XExpand D 0:1:1:1 + +# check location of subshape +XGetShape sh D 0:1:1:10 +XGetShape subsh D 0:1:1:10:1 +set check_sub [issubshape subsh sh] +set check_sub [lindex $check_sub 5] + +if {$check_sub != "Index"} { + puts "Error: Wrong subshape location" +} + +# check sharing of new part +set ref1 [XGetReferredShape D 0:1:1:1:5] +set ref2 [XGetReferredShape D 0:1:1:1:8] +if {$ref1 != $ref2} { + puts "Error: Wrong sharing" +} + +# check name +set name [GetName D 0:1:1:1:5] +if {$name != "l-bracket-assembly_1"} { + puts "Error: Wrong name of component" +} + +Close D