]> OCCT Git - occt.git/commitdiff
0029821: Data Exchange - Wrong processing of subshapes in ShapeTool
authorika <ika@opencascade.com>
Mon, 28 May 2018 10:15:37 +0000 (13:15 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 14 Jun 2018 11:03:07 +0000 (14:03 +0300)
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
src/XCAFDoc/XCAFDoc_ShapeTool.cxx
src/XCAFDoc/XCAFDoc_ShapeTool.hxx
src/XDEDRAW/XDEDRAW_Shapes.cxx
tests/bugs/xde/bug29821 [new file with mode: 0644]

index 7db50b309f0ad8a5bd64b1a4257748afaa23dac9..f11d6d6a80b318124dcc55652f73e0818cc25f6c 100644 (file)
@@ -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;
 }
 
index 29edcfbdaea2a0273e3cfcb186d7171a537530b1..44c304563acc10646695df1afc6c71ccc1b01d51 100644 (file)
@@ -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);
   }
 }
 
index a8638fd7f59e11a328d96e85a5f5948cbe04b9e5..db5871973a3506ccc4668a74689de3f73fd02304 100644 (file)
@@ -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;
index 82f6dfbaa60af4d7f1b2c6c8d4847555473d1ab2..78b09d9883ab6e3e9c6d3dadae81b1fc3974d6ff 100644 (file)
@@ -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 (file)
index 0000000..68c6b06
--- /dev/null
@@ -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