]> OCCT Git - occt-copy.git/commitdiff
0030998: STEPCAFControl_Writer will not export shape with Identity Location if there... CR30998
authorskl <skl@opencascade.com>
Tue, 3 Nov 2020 12:18:44 +0000 (15:18 +0300)
committerskl <skl@opencascade.com>
Fri, 6 Nov 2020 10:28:24 +0000 (13:28 +0300)
Fix + 2 Draw tests.

src/STEPCAFControl/STEPCAFControl_Reader.cxx
src/STEPCAFControl/STEPCAFControl_Reader.hxx
src/XCAFDoc/XCAFDoc_ShapeTool.cxx
src/XCAFDoc/XCAFDoc_ShapeTool.hxx
tests/bugs/xde/bug30998_1 [new file with mode: 0644]
tests/bugs/xde/bug30998_2 [new file with mode: 0644]

index 2772edc2d6ef91ebff737ba066f32eb0b679244e..16e99f1ece5a5ab292d0509a1b46565f2fe3d039 100644 (file)
@@ -766,7 +766,8 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S,
   const TopTools_MapOfShape &NewShapesMap,
   const STEPCAFControl_DataMapOfShapePD &ShapePDMap,
   const STEPCAFControl_DataMapOfPDExternFile &PDFileMap,
-  XCAFDoc_DataMapOfShapeLabel &ShapeLabelMap) const
+  XCAFDoc_DataMapOfShapeLabel &ShapeLabelMap,
+  const Standard_Integer theLevel) const
 {
   // if shape has already been mapped, just return corresponding label
   if (ShapeLabelMap.IsBound(S)) {
@@ -778,15 +779,15 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S,
     TopoDS_Shape S0 = S;
     TopLoc_Location loc;
     S0.Location(loc);
-    AddShape(S0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap);
-    TDF_Label L = STool->AddShape(S, Standard_False); // should create reference
+    TDF_Label aS0L = AddShape(S0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap, theLevel + 1);
+    TDF_Label L = STool->AddLocatedShape(STool->Label(), aS0L, S.Location()); // should create reference
     ShapeLabelMap.Bind(S, L);
     return L;
   }
 
   // if shape is not compound, simple add it
   if (S.ShapeType() != TopAbs_COMPOUND) {
-    TDF_Label L = STool->AddShape(S, Standard_False);
+    TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, theLevel == 0);
     ShapeLabelMap.Bind(S, L);
     return L;
   }
@@ -831,7 +832,7 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S,
 
   // add compound either as a whole,
   if (!isAssembly) {
-    TDF_Label L = STool->AddShape(S, Standard_False);
+    TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, theLevel == 0);
     if (SHAS.Length() > 0) STool->SetExternRefs(L, SHAS);
     ShapeLabelMap.Bind(S, L);
     return L;
@@ -844,7 +845,7 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S,
     TopoDS_Shape Sub0 = it.Value();
     TopLoc_Location loc;
     Sub0.Location(loc);
-    TDF_Label subL = AddShape(Sub0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap);
+    TDF_Label subL = AddShape(Sub0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap, theLevel + 1);
     if (!subL.IsNull()) {
       TDF_Label instL = STool->AddComponent(L, subL, it.Value().Location());
       if (!ShapeLabelMap.IsBound(it.Value())) {
index 2aa4d23f38a30e7e21e418b50b2e527e44e58b5a..1cf9962b367e902bc5cbfb127bd063db6b2e8cf9 100644 (file)
@@ -195,7 +195,13 @@ protected:
   //! Depending on a case, this shape can be added as one, or
   //! as assembly, or (in case if it is associated with external
   //! reference) taken as that referred shape
-  Standard_EXPORT TDF_Label AddShape (const TopoDS_Shape& S, const Handle(XCAFDoc_ShapeTool)& STool, const TopTools_MapOfShape& NewShapesMap, const STEPCAFControl_DataMapOfShapePD& ShapePDMap, const STEPCAFControl_DataMapOfPDExternFile& PDFileMap, XCAFDoc_DataMapOfShapeLabel& ShapeLabelMap) const;
+  Standard_EXPORT TDF_Label AddShape(const TopoDS_Shape& S,
+    const Handle(XCAFDoc_ShapeTool)& STool,
+    const TopTools_MapOfShape& NewShapesMap,
+    const STEPCAFControl_DataMapOfShapePD& ShapePDMap,
+    const STEPCAFControl_DataMapOfPDExternFile& PDFileMap,
+    XCAFDoc_DataMapOfShapeLabel& ShapeLabelMap,
+    const Standard_Integer theLevel = 0) const;
   
   //! Reads (or if returns already read) extern file with
   //! given name
index 2bc48072599bc1482c340485afa2d7e77ff9e059..58a7be183c7af3e8f7748c4d103ca45b837ab0aa 100644 (file)
@@ -425,13 +425,37 @@ void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L,
 //purpose  : private
 //=======================================================================
 
-TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly)
+TDF_Label XCAFDoc_ShapeTool::addShape (
+  const TopoDS_Shape& S,
+  const Standard_Boolean makeAssembly,
+  const Standard_Integer theLevel)
 {
   TDF_Label ShapeLabel;
   TDF_TagSource aTag;
 
+  if (S.IsNull()) return ShapeLabel;
+
   // search if the shape already exists (with the same location)
-  if ( S.IsNull() || FindShape ( S, ShapeLabel, Standard_True ) ) return ShapeLabel;
+  if (FindShape(S, ShapeLabel, Standard_True))
+  {
+    Standard_Boolean needUpdate = !makeAssembly && S.Location().IsIdentity() && (theLevel==0 || IsFree(ShapeLabel));
+    if (needUpdate)
+    {
+      // such shape without location is placed on the top level
+      // but also we want to use this shape as a referenced shape for other
+      // top level shape => in order to avoid of missing shape we have to
+      // prepare new shape with location in the point (0,0,0) and make reference
+      // to current shape without location
+      TopoDS_Shape newS = S.EmptyCopied();
+      gp_Trsf aTrsf;
+      TopLoc_Location loc(aTrsf);
+      newS.Location(loc);
+      TDF_Label L = aTag.NewChild(Label());
+      MakeReference(L, ShapeLabel, newS.Location());
+      myShapeLabels.Bind(newS, L);
+    }
+    return ShapeLabel;
+  }
   
   // else add a new label
   ShapeLabel = aTag.NewChild(Label());
@@ -441,7 +465,7 @@ TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boo
     TopoDS_Shape S0 = S;
     TopLoc_Location loc;
     S0.Location ( loc );
-    TDF_Label L = addShape ( S0, makeAssembly );
+    TDF_Label L = addShape(S0, makeAssembly, theLevel + 1);
     MakeReference ( ShapeLabel, L, S.Location() );
     return ShapeLabel;
   }
@@ -475,7 +499,7 @@ TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boo
       TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp;
       TopLoc_Location loc;
       S0.Location ( loc );
-      TDF_Label compL = addShape ( S0, makeAssembly );
+      TDF_Label compL = addShape(S0, makeAssembly, theLevel + 1);
       
       // add a component as reference
       TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
@@ -546,14 +570,39 @@ static Standard_Boolean prepareAssembly (const TopoDS_Shape& theShape,
 
 TDF_Label XCAFDoc_ShapeTool::AddShape (const TopoDS_Shape& theShape,
                                        const Standard_Boolean makeAssembly,
-                                       const Standard_Boolean makePrepare)
+                                       const Standard_Boolean makePrepare,
+                                       const Standard_Boolean freeShape)
 {
   // PTV 17.02.2003 to avoid components without location.
   TopoDS_Shape S = theShape;
   if ( makePrepare && makeAssembly && S.ShapeType() == TopAbs_COMPOUND )
     prepareAssembly( theShape, S ); // OCC1669
-  
-  TDF_Label L = addShape(S,makeAssembly);
+
+  if (!makeAssembly && S.Location().IsIdentity() && freeShape)
+  {
+    // search if the shape already exists (with the same location)
+    TDF_Label ShapeLabel;
+    if (FindShape(S, ShapeLabel, Standard_True))
+    {
+      // such shape without location is placed on the top level
+      // but also this shape is a referenced shape for other top level shape
+      // therefore in order to avoid of missing shape we have to prepare new
+      // shape with location in the point (0,0,0) and make reference to
+      // existed shape without location
+      TopoDS_Shape newS = S.EmptyCopied();
+      gp_Trsf aTrsf;
+      TopLoc_Location loc(aTrsf);
+      newS.Location(loc);
+      TDF_TagSource aTag;
+      TDF_Label L = aTag.NewChild(Label());
+      MakeReference(L, ShapeLabel, newS.Location());
+      myShapeLabels.Bind(newS, L);
+      return L;
+    }
+  }
+
+  Standard_Integer aLevel = freeShape ? 0 : 1;
+  TDF_Label L = addShape(S,makeAssembly, aLevel);
 
   if(!myShapeLabels.IsBound(S)) {
     myShapeLabels.Bind(S,L);
@@ -904,28 +953,19 @@ Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L,
 }
 
 //=======================================================================
-//function : AddComponent
+//function : AddLocatedShape
 //purpose  : 
 //=======================================================================
 
-TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, 
-                                          const TDF_Label& compL, 
-                                          const TopLoc_Location &Loc)
+TDF_Label XCAFDoc_ShapeTool::AddLocatedShape (
+  const TDF_Label& theParentL,
+  const TDF_Label& theShapeL,
+  const TopLoc_Location &theLoc)
 {
-  TDF_Label L;
-  
-  // check that shape is assembly
-  if ( ! IsAssembly(assembly) ) {
-    // if it is simple shape, make it assembly
-    if ( IsSimpleShape(assembly) ) 
-      TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() );
-    else return L;
-  }
-  
-  // add a component as reference
+  // add as reference
   TDF_TagSource aTag;
-  L = aTag.NewChild(assembly);
-  MakeReference ( L, compL, Loc );
+  TDF_Label L = aTag.NewChild(theParentL);
+  MakeReference ( L, theShapeL, theLoc);
 
   // map shape to label
   TopoDS_Shape aShape;
@@ -943,6 +983,28 @@ TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
 //purpose  : 
 //=======================================================================
 
+TDF_Label XCAFDoc_ShapeTool::AddComponent(const TDF_Label& assembly,
+  const TDF_Label& compL,
+  const TopLoc_Location &Loc)
+{
+  TDF_Label L;
+
+  // check that shape is assembly
+  if (!IsAssembly(assembly)) {
+    // if it is simple shape, make it assembly
+    if (IsSimpleShape(assembly))
+      TDataStd_UAttribute::Set(assembly, XCAFDoc::AssemblyGUID());
+    else return L;
+  }
+
+  return AddLocatedShape(assembly, compL, Loc);
+}
+
+//=======================================================================
+//function : AddComponent
+//purpose  : 
+//=======================================================================
+
 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, 
                                           const TopoDS_Shape& comp,
                                           const Standard_Boolean expand)
@@ -952,8 +1014,8 @@ TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
   TopLoc_Location loc;
   S0.Location ( loc );
   TDF_Label compL;
-  compL = AddShape ( S0, expand );
-  
+  compL = AddShape ( S0, expand, Standard_True, Standard_False);
+
   // add component by its label
   return AddComponent ( assembly, compL, comp.Location() );
 }
index 8980edb353b5d10e1858a7f383288488764880dc..16cda13bff926e7bc10971a15b48c484958be8e7 100644 (file)
@@ -213,7 +213,10 @@ public:
   //! NOTE: <makePrepare> replace components without location
   //! in assmebly by located components to avoid some problems.
   //! If AutoNaming() is True then automatically attaches names.
-  Standard_EXPORT TDF_Label AddShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly = Standard_True, const Standard_Boolean makePrepare = Standard_True);
+  Standard_EXPORT TDF_Label AddShape (const TopoDS_Shape& S,
+    const Standard_Boolean makeAssembly = Standard_True,
+    const Standard_Boolean makePrepare = Standard_True,
+    const Standard_Boolean freeShape = Standard_True);
   
   //! Removes shape (whole label and all its sublabels)
   //! If removeCompletely is true, removes complete shape
@@ -273,6 +276,13 @@ public:
   //! Returns False if label is not assembly
   Standard_EXPORT static Standard_Boolean GetComponents (const TDF_Label& L, TDF_LabelSequence& Labels, const Standard_Boolean getsubchilds = Standard_False);
   
+  //! Adds a shape (without location) given by its label (theShapeL)
+  //! to the theParentL with given location
+  Standard_EXPORT TDF_Label AddLocatedShape(
+    const TDF_Label& theParentL,
+    const TDF_Label& theShapeL,
+    const TopLoc_Location &theLoc);
+
   //! Adds a component given by its label and location to the assembly
   //! Note: assembly must be IsAssembly() or IsSimpleShape()
   Standard_EXPORT TDF_Label AddComponent (const TDF_Label& assembly, const TDF_Label& comp, const TopLoc_Location& Loc);
@@ -438,7 +448,9 @@ private:
 
   //! Adds a new top-level (creates and returns a new label)
   //! For internal use. Used by public method AddShape.
-  Standard_EXPORT TDF_Label addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly = Standard_True);
+  Standard_EXPORT TDF_Label addShape (const TopoDS_Shape& S,
+    const Standard_Boolean makeAssembly = Standard_True,
+    const Standard_Integer theLevel = 0);
   
   //! Makes a shape on label L to be a reference to shape refL
   //! with location loc
@@ -454,7 +466,6 @@ private:
   XCAFDoc_DataMapOfShapeLabel mySimpleShapes;
   Standard_Boolean hasSimpleShapes;
 
-
 };
 
 
diff --git a/tests/bugs/xde/bug30998_1 b/tests/bugs/xde/bug30998_1
new file mode 100644 (file)
index 0000000..2f2eac0
--- /dev/null
@@ -0,0 +1,26 @@
+puts "# =============================================================================="
+puts "# 0030998: STEPCAFControl_Writer will not export shape with Identity Location"
+puts "#          if there are other partner shapes with diff Location."
+puts "# =============================================================================="
+
+# tests bug30998_1 and bug30998_2 differ in the order of adding shapes to the document
+# it is needed to check various parts of XDE functionality
+
+pload OCAF XDE MODELING
+
+restore [locate_data_file bug30998.brep] a 
+NewDocument D
+explode a
+XAddShape D a_1 0
+XAddShape D a_2 0
+WriteStep D $imagedir/${casename}.stp
+ReadStep D1 $imagedir/${casename}.stp
+XGetOneShape res D1
+
+checkprops res -s 784473
+
+checkshape res
+
+checknbshapes res -vertex 2 -edge 3 -wire 3 -face 3 -shell 1 -solid 1 -compsolid 0 -compound 3 -shape 16
+
+
diff --git a/tests/bugs/xde/bug30998_2 b/tests/bugs/xde/bug30998_2
new file mode 100644 (file)
index 0000000..0456608
--- /dev/null
@@ -0,0 +1,26 @@
+puts "# =============================================================================="
+puts "# 0030998: STEPCAFControl_Writer will not export shape with Identity Location"
+puts "#          if there are other partner shapes with diff Location."
+puts "# =============================================================================="
+
+# tests bug30998_1 and bug30998_2 differ in the order of adding shapes to the document
+# it is needed to check various parts of XDE functionality
+
+pload OCAF XDE MODELING
+
+restore [locate_data_file bug30998.brep] a 
+NewDocument D
+explode a
+XAddShape D a_2 0
+XAddShape D a_1 0
+WriteStep D $imagedir/${casename}.stp
+ReadStep D1 $imagedir/${casename}.stp
+XGetOneShape res D1
+
+checkprops res -s 784473
+
+checkshape res
+
+checknbshapes res -vertex 2 -edge 3 -wire 3 -face 3 -shell 1 -solid 1 -compsolid 0 -compound 3 -shape 16
+
+