0030779: Data Exchange - Problems with located subshapes in expand compounds
authorika <ika@opencascade.com>
Thu, 13 Jun 2019 12:30:51 +0000 (15:30 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 14 Jun 2019 09:27:34 +0000 (12:27 +0300)
Protect Expand compounds against problems with located subshapes.
Add method XCAFDoc_ShapeTool::AddSubShape() with Boolean output parameter.
Speed up XCAFDoc_ShapeTool::Expand().
Speed up XCAFDoc_ShapeTool::FindSubShape().

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

index a2dbd3d..61b9f8c 100644 (file)
@@ -1094,12 +1094,16 @@ Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL,
   TDF_ChildIterator aChldLabIt(shapeL);
   for (; aChldLabIt.More(); aChldLabIt.Next() ) {
     TDF_Label aSubLabel = aChldLabIt.Value();
-    TopoDS_Shape aSubShape;
-    if (GetShape(aSubLabel, aSubShape) && aSubShape.IsSame(sub)) {
+    Handle(TNaming_NamedShape) NS;
+    if (!aSubLabel.FindAttribute(TNaming_NamedShape::GetID(), NS))
+      continue;
+    TopoDS_Shape aSubShape = TNaming_Tool::GetShape(NS);
+    if (!aSubShape.IsNull() && aSubShape.IsSame(sub)) {
       L = aSubLabel;
       return Standard_True;
     }
   }
+
   return Standard_False;
 }
 
@@ -1126,12 +1130,38 @@ TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL,
   TNaming_Builder tnBuild(L);
   tnBuild.Generated(sub);
 
-//  if(!mySubShapes.IsBound(sub))
-//    mySubShapes.Bind(sub,L);
-   
   return L;
 }
 
+//=======================================================================
+//function : AddSubShape
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean XCAFDoc_ShapeTool::AddSubShape(const TDF_Label &shapeL,
+                                                const TopoDS_Shape &sub,
+                                                TDF_Label &addedSubShapeL) const
+{
+  addedSubShapeL = TDF_Label();
+  // Check if adding subshape is possible
+  if (!IsSimpleShape(shapeL) || !IsTopLevel(shapeL))
+    return Standard_False;
+
+  // Try to find already existed subshape
+  if (FindSubShape(shapeL, sub, addedSubShapeL))
+    return Standard_False;
+
+  if (!IsSubShape(shapeL, sub))
+    return Standard_False;
+
+  TDF_TagSource aTag;
+  addedSubShapeL = aTag.NewChild(shapeL);
+  TNaming_Builder tnBuild(addedSubShapeL);
+  tnBuild.Generated(sub);
+
+  return Standard_True;
+}
+
 
 //=======================================================================
 //function : FindMainShapeUsingMap
@@ -1915,6 +1945,7 @@ void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& theMainShapeL,
   TopoDS_Iterator anIter(theShape);
   Standard_Boolean isCompoundPart = (GetShape(thePart).ShapeType() == TopAbs_COMPOUND);
   Standard_Boolean isAssembly = IsAssembly(thePart);
+
   for(; anIter.More(); anIter.Next()) {
     const TopoDS_Shape& aChildShape = anIter.Value();
     TDF_Label aChildLabel;
@@ -1925,18 +1956,25 @@ void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& theMainShapeL,
         makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
         continue;
       }
-
       //get name
       Handle(TDataStd_Name) anAttr;
       aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr);
       TopLoc_Location aSubLoc;
       // Calculate location for subshapes of compound parts
+      aSubLoc = aChildShape.Location();
       if (isCompoundPart) 
-        aSubLoc = theLoc.Inverted() * aChildShape.Location();
+        aSubLoc = theLoc.Inverted() * aSubLoc;
       //make subshape
       TDF_Label aSubLabel;
-      if (!FindSubShape(thePart, aChildShape.Located(aSubLoc), aSubLabel)) {
-        aSubLabel = AddSubShape(thePart, aChildShape.Located(aSubLoc));
+      // Identical location and empty location are not the same for ShapeTool, so try to process both
+      // in case of aSubLoc is not identical, the second Add try will not affect algorithm.
+      Standard_Boolean isNewSubL;
+      isNewSubL = AddSubShape(thePart, aChildShape.Located(aSubLoc), aSubLabel);
+      if (aSubLabel.IsNull())
+      {
+        isNewSubL = AddSubShape(thePart, aChildShape.Located(TopLoc_Location()), aSubLabel);
+      }
+      if (isNewSubL){
         //set name to sub shape
         if (!anAttr.IsNull()) {
           TDataStd_Name::Set(aSubLabel, anAttr->Get());
@@ -1954,6 +1992,7 @@ void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& theMainShapeL,
         aChildLabel.ForgetAllAttributes();
       }
     }
+
     makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
   }
 }
index cd24816..ef257d9 100644 (file)
@@ -298,6 +298,11 @@ public:
   //! label shapeL
   //! Returns Null label if it is not subshape
   Standard_EXPORT TDF_Label AddSubShape (const TDF_Label& shapeL, const TopoDS_Shape& sub) const;
+
+  //! Adds (of finds already existed) a label for subshape <sub> of shape stored on
+  //! label shapeL. Label addedSubShapeL returns added (found) label or empty in case of wrong subshape.
+  //! Returns True, if new shape was added, False in case of already existed subshape/wrong subshape
+  Standard_EXPORT Standard_Boolean AddSubShape(const TDF_Label& shapeL, const TopoDS_Shape& sub, TDF_Label& addedSubShapeL) const;
   
   Standard_EXPORT TDF_Label FindMainShapeUsingMap (const TopoDS_Shape& sub) const;
   
diff --git a/tests/bugs/xde/bug30779 b/tests/bugs/xde/bug30779
new file mode 100644 (file)
index 0000000..b767162
--- /dev/null
@@ -0,0 +1,27 @@
+puts "============================================================================"
+puts "0030779: Data Exchange - Problems with located subshapes in expand compounds"
+puts "============================================================================"
+puts ""
+
+pload DCAF
+
+XOpen [locate_data_file bug30779.xbf] D
+XExpand D 1
+
+# check model structure after expand
+set result [XGetTopLevelShapes D]
+if {$result != "0:1:1:1 0:1:1:2 0:1:1:3 "} {
+  puts "Error: wrong result of Expand compounds."
+}
+
+# check colors of subshapes
+for {set i 1} {$i <= 4} {incr i} {
+  set sublabel 0:1:1:3:$i
+  set color [XGetShapeColor D $sublabel]
+  if {$color != "GRAY"} {
+    puts "Error: wrong color after expand compounds."
+  }
+}
+
+Close D
+