From f277ba3771b0115ad586ba5c383876a175b7d85d Mon Sep 17 00:00:00 2001 From: ika Date: Mon, 28 May 2018 13:15:37 +0300 Subject: [PATCH] 0029821: Data Exchange - Wrong processing of subshapes in ShapeTool Improve FindSubShape method in ShapeTool. Update Expand compounds, according to changes in ShapeTool. Add FindSubShape and AddSubShape commands for Draw. --- src/XCAFDoc/XCAFDoc_Editor.cxx | 5 ++- src/XCAFDoc/XCAFDoc_ShapeTool.cxx | 63 +++++++++++++++---------------- src/XCAFDoc/XCAFDoc_ShapeTool.hxx | 8 ++-- src/XDEDRAW/XDEDRAW_Shapes.cxx | 61 ++++++++++++++++++++++++++++++ tests/bugs/xde/bug29821 | 47 +++++++++++++++++++++++ 5 files changed, 147 insertions(+), 37 deletions(-) create mode 100644 tests/bugs/xde/bug29821 diff --git a/src/XCAFDoc/XCAFDoc_Editor.cxx b/src/XCAFDoc/XCAFDoc_Editor.cxx index 7db50b309f..f11d6d6a80 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); + Standard_Boolean isAutoNaming = aShapeTool->AutoNaming(); aShapeTool->SetAutoNaming(Standard_False); TopoDS_Shape aS = aShapeTool->GetShape(Shape); @@ -91,10 +92,10 @@ Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const TDF_Label& for (Standard_Integer i = 1; i <= aUsers.Length(); i++) { TDF_Label aSubLabel = aUsers.Value(i); - setParams(Doc, aSubLabel, aColors, aLayers, aName); //remove unnecessary links aSubLabel.ForgetAttribute(XCAFDoc::ShapeRefGUID()); aSubLabel.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID()); + setParams(Doc, aSubLabel, aColors, aLayers, aName); } aChild.ForgetAllAttributes(Standard_False); } @@ -116,8 +117,10 @@ Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const TDF_Label& } } } + aShapeTool->SetAutoNaming(isAutoNaming); return Standard_True; } + aShapeTool->SetAutoNaming(isAutoNaming); return Standard_False; } diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx index 29edcfbdae..44c304563a 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx @@ -1057,24 +1057,34 @@ Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL, const TopoDS_Shape &sub, TDF_Label &L) const { - // this code is used instead of the following for performance reasons - if ( TNaming_Tool::HasLabel(Label(), sub) ) { + if (sub.IsNull()) + return Standard_False; + + if (TNaming_Tool::HasLabel(Label(), sub)) { int TransDef = 0; L = TNaming_Tool::Label(Label(), sub, TransDef); - return ( ! L.IsNull() && L.Father() == shapeL ); + if (L.IsNull()) + return Standard_False; + if (L.Father() == shapeL) + return Standard_True; + } + else + { + return Standard_False; } -/* - TDF_ChildIterator chldLabIt(shapeL); - for (; chldLabIt.More(); chldLabIt.Next() ) { - TDF_Label subLabel = chldLabIt.Value(); - TopoDS_Shape S; - if ( GetShape ( subLabel, S ) && S.IsSame ( sub ) ) { - L = subLabel; + // if subshape was found wrong, try to do it manually + // it can be possible if several part shapes has the same subshapes + L = TDF_Label(); + TDF_ChildIterator aChldLabIt(shapeL); + for (; aChldLabIt.More(); aChldLabIt.Next() ) { + TDF_Label aSubLabel = aChldLabIt.Value(); + TopoDS_Shape aSubShape; + if (GetShape(aSubLabel, aSubShape) && aSubShape.IsSame(sub)) { + L = aSubLabel; return Standard_True; } } -*/ return Standard_False; } @@ -1820,8 +1830,6 @@ Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL) aShapeType == TopAbs_SHELL || aShapeType == TopAbs_WIRE; if (isExpandedType) { - //set assembly attribute - TDataStd_UAttribute::Set(theShapeL, XCAFDoc::AssemblyGUID()); TopoDS_Iterator anIter(aShape); for(; anIter.More(); anIter.Next()) { @@ -1829,18 +1837,7 @@ Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL) 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; - } - } - } + FindSubShape(theShapeL, aChildShape, aChild); Handle(TDataStd_Name) anAttr; //make child (if color isn't set or if it is compound) if (aChild.IsNull()) { @@ -1857,7 +1854,6 @@ Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL) // 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)) { @@ -1878,8 +1874,10 @@ Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL) TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName)); } MakeReference(aChild, aPart, aChildShape.Location()); - makeSubShape(aPart, aChildShape, aChildShape.Location()); + makeSubShape(theShapeL, aPart, aChildShape, aChildShape.Location()); } + //set assembly attribute + TDataStd_UAttribute::Set(theShapeL, XCAFDoc::AssemblyGUID()); return Standard_True; } return Standard_False; @@ -1890,17 +1888,18 @@ Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL) //purpose : //======================================================================= -void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& thePart, +void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& theMainShapeL, + const TDF_Label& thePart, const TopoDS_Shape& theShape, const TopLoc_Location& theLoc) { 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()) { + TDF_Label aChildLabel; + FindSubShape(theMainShapeL, aChildShape, aChildLabel); + if(!aChildLabel.IsNull()) { //get name Handle(TDataStd_Name) anAttr; aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr); @@ -1929,7 +1928,7 @@ void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& thePart, aChildLabel.ForgetAllAttributes(); } } - makeSubShape(thePart, aChildShape, theLoc); + makeSubShape(theMainShapeL, thePart, aChildShape, theLoc); } } diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx index a8638fd7f5..db5871973a 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx @@ -407,10 +407,6 @@ public: //! Convert Shape (compound/compsolid/shell/wire) to assembly Standard_EXPORT Standard_Boolean Expand (const TDF_Label& Shape) ; - //! Make subshape for Part from Shape - Standard_EXPORT void makeSubShape (const TDF_Label& thePart, const TopoDS_Shape& theShape, const TopLoc_Location& theLoc) ; - - DEFINE_STANDARD_RTTIEXT(XCAFDoc_ShapeTool,TDF_Attribute) @@ -435,6 +431,10 @@ private: //! with location loc Standard_EXPORT static void MakeReference (const TDF_Label& L, const TDF_Label& refL, const TopLoc_Location& loc); + //! Auxiliary method for Expand + //! Make subshape for thePart from theShape after expanding theMainShapeL + Standard_EXPORT void makeSubShape(const TDF_Label& theMainShapeL, const TDF_Label& thePart, const TopoDS_Shape& theShape, const TopLoc_Location& theLoc); + XCAFDoc_DataMapOfShapeLabel myShapeLabels; XCAFDoc_DataMapOfShapeLabel mySubShapes; XCAFDoc_DataMapOfShapeLabel mySimpleShapes; diff --git a/src/XDEDRAW/XDEDRAW_Shapes.cxx b/src/XDEDRAW/XDEDRAW_Shapes.cxx index 82f6dfbaa6..78b09d9883 100644 --- a/src/XDEDRAW/XDEDRAW_Shapes.cxx +++ b/src/XDEDRAW/XDEDRAW_Shapes.cxx @@ -180,6 +180,61 @@ static Standard_Integer findShape (Draw_Interpretor& di, Standard_Integer argc, return 0; } +static Standard_Integer findSubShape(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +{ + if (argc != 4) { + di << "Use: " << argv[0] << " DocName Shape ParentLabel\n"; + return 1; + } + Handle(TDocStd_Document) aDoc; + DDocStd::GetDocument(argv[1], aDoc); + if (aDoc.IsNull()) { + di << argv[1] << " is not a document\n"; + return 1; + } + + TopoDS_Shape aShape; + aShape = DBRep::Get(argv[2]); + + TDF_Label aParentLabel; + TDF_Tool::Label(aDoc->GetData(), argv[3], aParentLabel); + + TDF_Label aLabel; + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(aDoc->Main()); + aShapeTool->FindSubShape(aParentLabel, aShape, aLabel); + + TCollection_AsciiString anEntry; + TDF_Tool::Entry(aLabel, anEntry); + di << anEntry.ToCString(); + return 0; +} + +static Standard_Integer addSubShape(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +{ + if (argc != 4) { + di << "Use: " << argv[0] << " DocName Shape ParentLabel\n"; + return 1; + } + Handle(TDocStd_Document) aDoc; + DDocStd::GetDocument(argv[1], aDoc); + if (aDoc.IsNull()) { di << argv[1] << " is not a document\n"; return 1; } + + TopoDS_Shape aShape; + aShape = DBRep::Get(argv[2]); + + TDF_Label aParentLabel; + TDF_Tool::Label(aDoc->GetData(), argv[3], aParentLabel); + + TDF_Label aLabel; + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(aDoc->Main()); + aLabel = aShapeTool->AddSubShape(aParentLabel, aShape); + + TCollection_AsciiString anEntry; + TDF_Tool::Entry(aLabel, anEntry); + di << anEntry.ToCString(); + return 0; +} + static Standard_Integer labelInfo (Draw_Interpretor& di, Standard_Integer argc, const char** argv) { if (argc!=3) { @@ -878,6 +933,12 @@ void XDEDRAW_Shapes::InitCommands(Draw_Interpretor& di) di.Add ("XFindShape","Doc Shape \t: Find and print label with indicated top-level shape", __FILE__, findShape, g); + di.Add("XFindSubShape", "Doc Shape ParentLabel \t: Find subshape under given parent shape label", + __FILE__, findSubShape, g); + + di.Add("XAddSubShape", "Doc Shape ParentLabel \t: Add subshape under given parent shape label", + __FILE__, addSubShape, g); + di.Add ("XLabelInfo","Doc Label \t: Print information about object at following label", __FILE__, labelInfo, g); diff --git a/tests/bugs/xde/bug29821 b/tests/bugs/xde/bug29821 new file mode 100644 index 0000000000..68c6b06a42 --- /dev/null +++ b/tests/bugs/xde/bug29821 @@ -0,0 +1,47 @@ +puts "==========" +puts "OCC29821" +puts "==========" +puts "" +############################################# +# Wrong processing of subshapes in ShapeTool +############################################# +pload ALL + +# create test document +box b 1 1 1 +box bb 2 0 0 1 1 1 +compound b bb c +XNewDoc D +XAddShape D c 0 +# 0:1:1:1 +XAddShape D b +# 0:1:1:2 +explode b f +# b_1 b_2 b_3 b_4 b_5 b_6 +XAddSubShape D b_1 0:1:1:1 +# 0:1:1:1:1 +XAddSubShape D b_1 0:1:1:2 +# 0:1:1:2:1 + +# FindSubShape check +set first_find1 [XFindSubShape D b_1 0:1:1:1] +if {$first_find1 != "0:1:1:1:1"} { + puts "Error: wrong subshape is found" +} +set first_find2 [XFindSubShape D b_1 0:1:1:2] +if {$first_find2 != "0:1:1:2:1"} { + puts "Error: wrong subshape is found" +} + +# FindSubShape check#2 +ForgetAll D 0:1:1:1:1 +set second_find1 [XFindSubShape D b_1 0:1:1:1] +if {$second_find1 != ""} { + puts "Error: wrong subshape is found" +} +set second_find2 [XFindSubShape D b_1 0:1:1:2] +if {$second_find2 != "0:1:1:2:1"} { + puts "Error: wrong subshape is found" +} + +Close D