0029599: Data Exchange - Incorrect expand compound method in XDE
authorika <ika@opencascade.com>
Fri, 16 Mar 2018 13:18:10 +0000 (16:18 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 29 Mar 2018 14:13:24 +0000 (17:13 +0300)
Improve processing of subshapes in ShapeTool
Fix sharing and calculating location for subshapes
Switch off autonaming for expand

src/XCAFDoc/XCAFDoc_Editor.cxx
src/XCAFDoc/XCAFDoc_ShapeTool.cxx
src/XCAFDoc/XCAFDoc_ShapeTool.hxx
tests/bugs/xde/bug29599 [new file with mode: 0644]

index 0c3f492..7db50b3 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);
+  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);
         }
       }
index 5be7fe6..b39e3b0 100644 (file)
@@ -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;
+      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;
+          }
+        }
+      }
       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));
+      if (aChild.IsNull()) {
+        aChild = AddSubShape(theShapeL, aChildShape);
       }
-      else
-      {
+      else {
         //get name
         aChild.FindAttribute(TDataStd_Name::GetID(), anAttr);
-        TopLoc_Location nulloc;
-        SetShape(aPart, aChildShape.Located(nulloc));
       }
-      //set name to part
-      if(!anAttr.IsNull())
-      {
+
+      // 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
-      {
+      else {
         Standard_SStream Stream;
         TopAbs::Print(aChildShape.ShapeType(), Stream);
-        TCollection_AsciiString aName (Stream.str().c_str());
+        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);
   }
 }
 
index ca73092..a8638fd 100644 (file)
@@ -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 (file)
index 0000000..5921021
--- /dev/null
@@ -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