]> OCCT Git - occt-copy.git/commitdiff
0030998: STEPCAFControl_Writer will not export shape with Identity Location if there... CR30998_2
authorskl <skl@opencascade.com>
Sat, 7 Nov 2020 13:42:27 +0000 (16:42 +0300)
committerskl <skl@opencascade.com>
Tue, 24 Nov 2020 06:36:09 +0000 (09:36 +0300)
Fix + 2 tests.

12 files changed:
src/STEPCAFControl/STEPCAFControl_Reader.cxx
src/STEPCAFControl/STEPCAFControl_Reader.hxx
src/STEPControl/STEPControl_Reader.cxx
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]
tests/de/step_1/B3
tests/de/step_1/G6
tests/de/step_1/G7
tests/de/step_1/ZD6
tests/de/step_1/ZG2

index 2772edc2d6ef91ebff737ba066f32eb0b679244e..45628f74a21aa44064ef77edd6919ce3cbdb3ec6 100644 (file)
@@ -707,10 +707,11 @@ Standard_Boolean STEPCAFControl_Reader::Transfer (STEPControl_Reader &reader,
   if (STool.IsNull()) return Standard_False;
   XCAFDoc_DataMapOfShapeLabel map;
   if (asOne)
-    Lseq.Append(AddShape(reader.OneShape(), STool, NewShapesMap, ShapePDMap, PDFileMap, map));
+    Lseq.Append(AddShape2(reader.OneShape(), STool, NewShapesMap, ShapePDMap, PDFileMap, map));
   else {
     for (i = 1; i <= num; i++) {
-      Lseq.Append(AddShape(reader.Shape(i), STool, NewShapesMap, ShapePDMap, PDFileMap, map));
+      //Lseq.Append(AddShape(reader.Shape(i), STool, NewShapesMap, ShapePDMap, PDFileMap, map));
+      Lseq.Append(AddShape2(reader.Shape(i), STool, NewShapesMap, ShapePDMap, PDFileMap, map));
     }
   }
 
@@ -766,7 +767,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 +780,17 @@ 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
+    //AddShape(S0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap, theLevel + 1);
+    //TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, 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); // 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 +835,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 +848,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())) {
@@ -860,6 +864,134 @@ TDF_Label STEPCAFControl_Reader::AddShape(const TopoDS_Shape &S,
 }
 
 //=======================================================================
+//function : AddExternRefs
+//purpose  : 
+//=======================================================================
+
+void STEPCAFControl_Reader::AddExternRefs(
+  const TopoDS_Shape &S,
+  const Handle(XCAFDoc_ShapeTool) &STool,
+  const TopTools_MapOfShape &NewShapesMap,
+  const STEPCAFControl_DataMapOfShapePD &ShapePDMap,
+  const STEPCAFControl_DataMapOfPDExternFile &PDFileMap) const
+{
+  // for compounds, compute number of subshapes and check whether this is assembly
+  Standard_Boolean isAssembly = Standard_False;
+  Standard_Integer nbComponents = 0;
+  TopoDS_Iterator it;
+  if (S.ShapeType() == TopAbs_COMPOUND) {
+    for (it.Initialize(S); it.More() && !isAssembly; it.Next(), nbComponents++) {
+      TopoDS_Shape Sub0 = it.Value();
+      TopLoc_Location loc;
+      Sub0.Location(loc);
+      if (NewShapesMap.Contains(Sub0)) isAssembly = Standard_True;
+    }
+  }
+
+  // check whether it has associated external ref
+  TColStd_SequenceOfHAsciiString SHAS;
+  if (ShapePDMap.IsBound(S) && PDFileMap.IsBound(ShapePDMap.Find(S))) {
+    Handle(STEPCAFControl_ExternFile) EF = PDFileMap.Find(ShapePDMap.Find(S));
+    if (!EF.IsNull()) {
+      // (store information on extern refs in the document)
+      SHAS.Append(EF->GetName());
+      // if yes, just return corresponding label
+      if (!EF->GetLabel().IsNull()) {
+        // but if components >0, ignore extern ref!
+        if (nbComponents <= 0)
+        {
+          if (STool->AddExternRef(S, EF->GetLabel()))
+          {
+            STool->SetExternRefs(EF->GetLabel(), SHAS);
+          }
+          return;
+        }
+      }
+    }
+  }
+
+  if (isAssembly)
+  {
+    // or as assembly, component-by-component
+    for (it.Initialize(S); it.More(); it.Next())
+    {
+      TopoDS_Shape Sub0 = it.Value();
+      TopLoc_Location loc;
+      Sub0.Location(loc);
+      AddExternRefs(Sub0, STool, NewShapesMap, ShapePDMap, PDFileMap);
+    }
+  }
+}
+
+//=======================================================================
+//function : AddShape2
+//purpose  : 
+//=======================================================================
+
+TDF_Label STEPCAFControl_Reader::AddShape2(
+  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) const
+{
+  // if shape has already been mapped, just return corresponding label
+  if (ShapeLabelMap.IsBound(S)) {
+    return ShapeLabelMap.Find(S);
+  }
+
+  // if shape is not compound, simple add it
+  if (S.ShapeType() != TopAbs_COMPOUND) {
+    TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, theLevel == 0);
+    ShapeLabelMap.Bind(S, L);
+    return L;
+  }
+
+  AddExternRefs(S, STool, NewShapesMap, ShapePDMap, PDFileMap);
+
+  // for compounds, compute number of subshapes and check whether this is assembly
+  //Standard_Boolean isAssembly = Standard_False;
+  //Standard_Integer nbComponents = 0;
+  //TopoDS_Iterator it;
+  //for (it.Initialize(S); it.More() && !isAssembly; it.Next(), nbComponents++) {
+  //  TopoDS_Shape Sub0 = it.Value();
+  //  TopLoc_Location loc;
+  //  Sub0.Location(loc);
+  //  if (NewShapesMap.Contains(Sub0)) isAssembly = Standard_True;
+  //}
+
+  TopoDS_Iterator it;
+  Standard_Boolean ignoreExternRef = Standard_False;
+  TopTools_MapOfShape::Iterator itSh(NewShapesMap);
+  for (; itSh.More(); itSh.Next())
+  {
+    TopoDS_Shape currSh = itSh.Value();
+    for (it.Initialize(currSh); it.More(); it.Next())
+    {
+      TopoDS_Shape Sub0 = it.Value();
+      TopLoc_Location loc;
+      Sub0.Location(loc);
+      if (NewShapesMap.Contains(Sub0))
+      {
+        // it is assembly
+        STool->AddAssemblyShape(currSh);
+        if (S.IsEqual(currSh))
+        {
+          ignoreExternRef = Standard_True;
+        }
+        break;
+      }
+    }
+  }
+
+  TDF_Label L = STool->AddShape(S, Standard_False, Standard_True, Standard_True); 
+
+  return L;
+}
+
+  //=======================================================================
 //function : ReadExternFile
 //purpose  : 
 //=======================================================================
index 2aa4d23f38a30e7e21e418b50b2e527e44e58b5a..779b302f1ac27c98813e0bda028d97bfd683edca 100644 (file)
@@ -195,8 +195,30 @@ 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;
+  
+  Standard_EXPORT TDF_Label AddShape2(
+    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;
+
+  Standard_EXPORT void AddExternRefs(
+    const TopoDS_Shape &S,
+    const Handle(XCAFDoc_ShapeTool) &STool,
+    const TopTools_MapOfShape &NewShapesMap,
+    const STEPCAFControl_DataMapOfShapePD &ShapePDMap,
+    const STEPCAFControl_DataMapOfPDExternFile &PDFileMap) const;
+
   //! Reads (or if returns already read) extern file with
   //! given name
   Standard_EXPORT Handle(STEPCAFControl_ExternFile) ReadExternFile (const Standard_CString file,
index 15ea180ba0ddc61c68a61317c4f958671d73e7cb..76fed3009c01a5d25eaa9f669d4271231fe1212c 100644 (file)
@@ -53,6 +53,7 @@
 #include <StepRepr_RepresentationMap.hxx>
 #include <StepRepr_RepresentationRelationship.hxx>
 #include <StepRepr_ShapeAspect.hxx>
+#include <StepRepr_ShapeRepresentationRelationship.hxx>
 #include <StepShape_ManifoldSolidBrep.hxx>
 #include <StepShape_ShapeDefinitionRepresentation.hxx>
 #include <StepShape_ShapeRepresentation.hxx>
@@ -178,11 +179,55 @@ Standard_Integer STEPControl_Reader::NbRootsForTransfer()
       const Interface_Graph& graph = WS()->Graph();
       // determinate roots used NextAssemblyUsageOccurrence
       Interface_EntityIterator subs = graph.Sharings(PD);
-      for(subs.Start(); subs.More(); subs.Next()) {
-        Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO = 
-          Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs.Value());
-        if (NAUO.IsNull()) continue;
-        if (PD==NAUO->RelatedProductDefinition()) IsRoot=Standard_False;
+      Handle(StepRepr_NextAssemblyUsageOccurrence) NAUO;
+      for (subs.Start(); subs.More() && IsRoot; subs.Next())
+      {
+        if (subs.Value()->IsKind(STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence)))
+        {
+          NAUO = Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs.Value());
+          if (PD == NAUO->RelatedProductDefinition())
+          {
+            IsRoot = Standard_False;
+            break;
+          }
+        }
+      }
+      if (NAUO.IsNull())
+      {
+        // use additional check using RepresentationRelationship entities
+        subs = graph.Sharings(PD);
+        for (subs.Start(); subs.More() && IsRoot; subs.Next())
+        {
+          Handle(StepRepr_ProductDefinitionShape) aPDS =
+            Handle(StepRepr_ProductDefinitionShape)::DownCast(subs.Value());
+          if (!aPDS.IsNull())
+          {
+            Interface_EntityIterator subs2 = graph.Sharings(aPDS);
+            Handle(StepShape_ShapeDefinitionRepresentation) aSDR;
+            for (subs2.Start(); subs2.More(); subs2.Next())
+            {
+              aSDR = Handle(StepShape_ShapeDefinitionRepresentation)::DownCast(subs2.Value());
+              if (!aSDR.IsNull()) break;
+            }
+            if (aSDR.IsNull()) continue;
+            Handle(StepShape_ShapeRepresentation) aSR =
+              Handle(StepShape_ShapeRepresentation)::DownCast(aSDR->UsedRepresentation());
+            subs2 = graph.Sharings(aSR);
+            for (subs2.Start(); subs2.More(); subs2.Next())
+            {
+              Handle(StepRepr_ShapeRepresentationRelationship) aSRR =
+                Handle(StepRepr_ShapeRepresentationRelationship)::DownCast(subs2.Value());
+              if (!aSRR.IsNull())
+              {
+                if (aSRR->Rep2() == aSR)
+                {
+                  IsRoot = Standard_False;
+                  break;
+                }
+              }
+            }
+          }
+        }
       }
       // determinate roots used ProductDefinitionContext
       if(IsRoot) {
index 2bc48072599bc1482c340485afa2d7e77ff9e059..0ebeb3d8b2a2a3b50fd6ce13b542031014a85334 100644 (file)
@@ -222,36 +222,36 @@ Standard_Boolean XCAFDoc_ShapeTool::Search (const TopoDS_Shape &S,
   // search among shapes
   Standard_Boolean isLocated = ! S.Location().IsIdentity();
   
-  if ( isLocated ) {
+  if (isLocated) {
     // try to find top-level instance
-    if ( findInstance && FindShape ( S, L, Standard_True ) )
+    if (findInstance && FindShape(S, L, Standard_True))
       return Standard_True;
     // try to find component of assembly
-    if ( findComponent ) {
+    if (findComponent) {
       TDF_LabelSequence labels;
-      GetShapes ( labels );
-      for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
-       if ( ! IsAssembly ( labels.Value(i) ) ) continue;
-       TDF_LabelSequence comp;
-       GetComponents ( labels.Value(i), comp );
-       for ( Standard_Integer j=1; j <= comp.Length(); j++ ) {
-         TopoDS_Shape c = GetShape ( comp.Value(j) );
-         if ( c.IsSame ( S ) ) {
-           L = comp.Value(j);
-           return Standard_True;
-         }
-       }
+      GetShapes(labels);
+      for (Standard_Integer i = 1; i <= labels.Length(); i++) {
+        if (!IsAssembly(labels.Value(i))) continue;
+        TDF_LabelSequence comp;
+        GetComponents(labels.Value(i), comp);
+        for (Standard_Integer j = 1; j <= comp.Length(); j++) {
+          TopoDS_Shape c = GetShape(comp.Value(j));
+          if (c.IsSame(S)) {
+            L = comp.Value(j);
+            return Standard_True;
+          }
+        }
       }
     }
   }
   // try to find top-level simple shape
-  if ( FindShape ( S, L, Standard_False ) ) return Standard_True;
-  
+  if (FindShape(S, L, Standard_False)) return Standard_True;
+
   // search subshapes
-  if ( ! findSubShape ) return Standard_False;
-  TDF_Label mainL = FindMainShape ( S );
-  if ( mainL.IsNull() ) return Standard_False;
-  L = AddSubShape ( mainL, S );
+  if (!findSubShape) return Standard_False;
+  TDF_Label mainL = FindMainShape(S);
+  if (mainL.IsNull()) return Standard_False;
+  L = AddSubShape(mainL, S);
   return !L.IsNull();//Standard_True;
 }
 
@@ -425,13 +425,43 @@ 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)
 {
+  //std::cout << "addShape:  TShape: " << S.TShape().get() << "  Loc: " << !(S.Location().IsIdentity()) << std::endl;
+  if (myExternRefs.IsBound(S))
+  {
+    return myExternRefs.Find(S);
+  }
+
   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 +471,10 @@ 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);
+    if (!myShapeLabels.IsBound(S)) {
+      myShapeLabels.Bind(S0, L);
+    }
     MakeReference ( ShapeLabel, L, S.Location() );
     return ShapeLabel;
   }
@@ -450,18 +483,18 @@ TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boo
   TNaming_Builder tnBuild(ShapeLabel);
   tnBuild.Generated(S);
   
-  Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
+  //Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
 //  if ( ! ShapeLabel.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
 //    A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
 //    ShapeLabel.AddAttribute(A);
 //  }
-  A->SetShape(S);
+  //A->SetShape(S);
   
   if (theAutoNaming)
     SetLabelNameByShape(ShapeLabel);
 
   // if shape is Compound and flag is set, create assembly
-  if ( makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) {
+  if ( (makeAssembly || myAsseblies.Contains(S)) && S.ShapeType() == TopAbs_COMPOUND ) {
     // mark assembly by assigning UAttribute
     Handle(TDataStd_UAttribute) Uattr;
     Uattr = TDataStd_UAttribute::Set ( ShapeLabel, XCAFDoc::AssemblyGUID() );
@@ -470,20 +503,27 @@ TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boo
 
     // iterate on components
     TopoDS_Iterator Iterator(S);
-    for (; Iterator.More(); Iterator.Next()) {
+    for (; Iterator.More(); Iterator.Next())
+    {
+      // prepare label for component
+      TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
       // get label for component`s shape
       TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp;
       TopLoc_Location loc;
       S0.Location ( loc );
-      TDF_Label compL = addShape ( S0, makeAssembly );
-      
-      // add a component as reference
-      TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
+      TDF_Label compL = addShape(S0, makeAssembly, theLevel + 1);
+      if (!myShapeLabels.IsBound(S)) {
+        myShapeLabels.Bind(S0, compL);
+      }
+      // add reference
       MakeReference ( RefLabel, compL, Scomp.Location() );
     }
   }
   
-  if(!IsAssembly(ShapeLabel)) {
+  if(!IsAssembly(ShapeLabel))
+  {
+    Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
+    A->SetShape(S);
     //const TopTools_IndexedMapOfShape tmpMap = A->GetMap();
     //for(Standard_Integer i=1; i<=tmpMap.Extent(); i++)
     //mySubShapes.Bind(tmpMap.FindKey(i),ShapeLabel);
@@ -546,19 +586,75 @@ 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)
+{
+  //{
+  //  std::cout << std::endl << "----- myExternRefs: " << std::endl;
+  //  XCAFDoc_DataMapOfShapeLabel::Iterator itSL(myExternRefs);
+  //  for (; itSL.More(); itSL.Next())
+  //  {
+  //    std::cout << "  TShape: " << itSL.Key().TShape().get() << "  Loc: " << !(itSL.Key().Location().IsIdentity()) << std::endl;
+  //  }
+  //}
   // 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);
   }
 
+  //{
+  //  std::cout << std::endl << "----- Shapes: " << std::endl;
+  //  XCAFDoc_DataMapOfShapeLabel::Iterator itSL(myShapeLabels);
+  //  for (; itSL.More(); itSL.Next())
+  //  {
+  //    std::cout << "Shape:  TShape: " << itSL.Key().TShape().get() << "  Loc: " << !(itSL.Key().Location().IsIdentity()) << std::endl;
+  //  }
+  //}
+  //{
+  //  std::cout << "----- SubShapes: " << std::endl;
+  //  XCAFDoc_DataMapOfShapeLabel::Iterator itSL(mySubShapes);
+  //  for (; itSL.More(); itSL.Next())
+  //  {
+  //    std::cout << "Shape: TShape: " << itSL.Key().TShape().get() << "  Loc: " << !(itSL.Key().Location().IsIdentity()) << std::endl;
+  //  }
+  //}
+  //std::cout << "----- mySimpleShapes: " << std::endl;
+  //XCAFDoc_DataMapOfShapeLabel::Iterator itSL(mySimpleShapes);
+  //for (; itSL.More(); itSL.Next())
+  //{
+  //  std::cout << "Shape: TShape: " << itSL.Key().TShape().get() << "  Loc: " << !(itSL.Key().Location().IsIdentity()) << std::endl;
+  //}
+
   return L;
 
   //return addShape( S, makeAssembly );
@@ -903,29 +999,53 @@ Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L,
   return Standard_True;
 }
 
+//=======================================================================
+//function : AddLocatedShape
+//purpose  : 
+//=======================================================================
+
+TDF_Label XCAFDoc_ShapeTool::AddLocatedShape (
+  const TDF_Label& theParentL,
+  const TDF_Label& theShape0L,
+  const TopoDS_Shape& theShape)
+{
+  // add as reference
+  TDF_TagSource aTag;
+  TDF_Label L = aTag.NewChild(theParentL);
+  TNaming_Builder tnBuild(L);
+  tnBuild.Generated(theShape);
+  MakeReference ( L, theShape0L, theShape.Location());
+
+  // map shape to label
+  if (!myShapeLabels.IsBound(theShape))
+    myShapeLabels.Bind(theShape, L);
+
+  return L;
+}
+
 //=======================================================================
 //function : AddComponent
 //purpose  : 
 //=======================================================================
 
-TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, 
-                                          const TDF_Label& compL, 
-                                          const TopLoc_Location &Loc)
+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 (!IsAssembly(assembly)) {
     // if it is simple shape, make it assembly
-    if ( IsSimpleShape(assembly) ) 
-      TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() );
+    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 );
+  MakeReference(L, compL, Loc);
 
   // map shape to label
   TopoDS_Shape aShape;
@@ -952,8 +1072,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() );
 }
@@ -2125,6 +2245,19 @@ Handle(TDataStd_NamedData) XCAFDoc_ShapeTool::GetNamedProperties (const TopoDS_S
   return aNamedProperty;
 }
 
+//=======================================================================
+//function : AddExternRef
+//purpose  : 
+//=======================================================================
+Standard_Boolean XCAFDoc_ShapeTool::AddExternRef(const TopoDS_Shape& theShape, const TDF_Label& theLabel)
+{
+  if (!myExternRefs.IsBound(theShape)) {
+    myExternRefs.Bind(theShape, theLabel);
+    return Standard_True;
+  }
+  return Standard_False;
+}
+
 //=======================================================================
 //function : DumpJson
 //purpose  : 
index 8980edb353b5d10e1858a7f383288488764880dc..3f735c6f550e59511b79d6d23586c2d0f6f0503a 100644 (file)
@@ -29,6 +29,7 @@
 #include <Standard_OStream.hxx>
 #include <TColStd_SequenceOfHAsciiString.hxx>
 #include <TDF_AttributeSequence.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopTools_SequenceOfShape.hxx>
 class Standard_GUID;
 class TDF_Label;
@@ -213,7 +214,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 +277,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& theShape0L,
+    const TopoDS_Shape& theShape);
+
   //! 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);
@@ -423,6 +434,15 @@ public:
   //! Dumps the content of me into the stream
   Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
 
+  //! Add shape which must be added as assembly in the method AddShape()
+  Standard_EXPORT void AddAssemblyShape(const TopoDS_Shape& theAssemblyShape)
+  {
+    myAsseblies.Add(theAssemblyShape);
+  }
+
+  //! Add extern reference
+  Standard_EXPORT Standard_Boolean AddExternRef(const TopoDS_Shape& theShape, const TDF_Label& theLabel);
+
 
   DEFINE_DERIVED_ATTRIBUTE(XCAFDoc_ShapeTool,TDataStd_GenericEmpty)
 
@@ -438,7 +458,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
@@ -453,7 +475,8 @@ private:
   XCAFDoc_DataMapOfShapeLabel mySubShapes;
   XCAFDoc_DataMapOfShapeLabel mySimpleShapes;
   Standard_Boolean hasSimpleShapes;
-
+  TopTools_MapOfShape myAsseblies;
+  XCAFDoc_DataMapOfShapeLabel myExternRefs;
 
 };
 
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
+
+
index 5d4b0973260ff9794c384898667f338d5eb93d7e..f3bc5867fb68aeb3062788738f7003980df1d5cb 100644 (file)
@@ -11,7 +11,7 @@ CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   So
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 38  ( 38 )  Face     = 115  ( 115 ) 
 STATSHAPE   : Solid    = 2  ( 2 )  Shell    = 76  ( 76 )  Face     = 230  ( 230 )   FreeWire = 0  ( 0 ) 
 TOLERANCE   : MaxTol   =         1e-007  (         1e-007 )  AvgTol   =          1e-007  (          1e-007 )
-LABELS      : N0Labels = 41  ( 41 )  N1Labels = 41  ( 41 )  N2Labels = 0  ( 0 )   TotalLabels = 82  ( 82 )   NameLabels = 82  ( 81 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
+LABELS      : N0Labels = 41  ( 41 )  N1Labels = 41  ( 41 )  N2Labels = 0  ( 0 )   TotalLabels = 82  ( 82 )   NameLabels = 82  ( 82 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
 COLORS      : Colors   =   (  )
index 16b782657dc816aa52556f53447e9a2b46a5c24c..7a501f516aad8927e3bc5e2c8bce705d11fa00cc 100644 (file)
@@ -12,7 +12,7 @@ CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   So
 NBSHAPES    : Solid    = 5  ( 5 )  Shell    = 5  ( 5 )  Face     = 53  ( 53 ) 
 STATSHAPE   : Solid    = 18  ( 18 )  Shell    = 18  ( 18 )  Face     = 160  ( 160 )   FreeWire = 0  ( 0 ) 
 TOLERANCE   : MaxTol   = 7.326475973e-006  ( 7.326473926e-006 )  AvgTol   =  2.618918051e-006  (  2.651443623e-006 )
-LABELS      : N0Labels = 9  ( 9 )  N1Labels = 13  ( 13 )  N2Labels = 0  ( 0 )   TotalLabels = 22  ( 22 )   NameLabels = 22  ( 19 )   ColorLabels = 5  ( 5 )   LayerLabels = 5  ( 12 )
+LABELS      : N0Labels = 9  ( 9 )  N1Labels = 13  ( 13 )  N2Labels = 0  ( 0 )   TotalLabels = 22  ( 22 )   NameLabels = 22  ( 22 )   ColorLabels = 5  ( 5 )   LayerLabels = 5  ( 18 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 5  ( 5 )
 COLORS      : Colors   = CYAN GOLD3 RED3 TURQUOISE4 YELLOW  ( CYAN GOLD3 RED3 TURQUOISE4 YELLOW )
index 80dc2505e331bf3408892dd1e05b7ebc1de27f38..c72e132ba8e00e38589a0717bfb1aa8b486dbf92 100644 (file)
@@ -12,7 +12,7 @@ CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   So
 NBSHAPES    : Solid    = 5  ( 5 )  Shell    = 5  ( 5 )  Face     = 53  ( 53 ) 
 STATSHAPE   : Solid    = 18  ( 18 )  Shell    = 18  ( 18 )  Face     = 160  ( 160 )   FreeWire = 0  ( 0 ) 
 TOLERANCE   : MaxTol   =         1e-007  (         1e-007 )  AvgTol   =          1e-007  (          1e-007 )
-LABELS      : N0Labels = 9  ( 9 )  N1Labels = 13  ( 13 )  N2Labels = 0  ( 0 )   TotalLabels = 22  ( 22 )   NameLabels = 22  ( 19 )   ColorLabels = 5  ( 5 )   LayerLabels = 5  ( 12 )
+LABELS      : N0Labels = 9  ( 9 )  N1Labels = 13  ( 13 )  N2Labels = 0  ( 0 )   TotalLabels = 22  ( 22 )   NameLabels = 22  ( 22 )   ColorLabels = 5  ( 5 )   LayerLabels = 5  ( 18 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 5  ( 5 )
 COLORS      : Colors   = CYAN GOLD3 RED3 TURQUOISE4 YELLOW  ( CYAN GOLD3 RED3 TURQUOISE4 YELLOW )
index 04fc100ad1420900d1f46e56dd430617f0f92445..64b379c596958fc31b55c0261c9a28c2ae2de045 100644 (file)
@@ -12,7 +12,7 @@ CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   So
 NBSHAPES    : Solid    = 2  ( 2 )  Shell    = 2  ( 2 )  Face     = 15  ( 15 ) 
 STATSHAPE   : Solid    = 2  ( 2 )  Shell    = 2  ( 2 )  Face     = 15  ( 15 )   FreeWire = 0  ( 0 ) 
 TOLERANCE   : MaxTol   =         1e-007  (         1e-007 )  AvgTol   =          1e-007  (          1e-007 )
-LABELS      : N0Labels = 3  ( 3 )  N1Labels = 2  ( 2 )  N2Labels = 0  ( 0 )   TotalLabels = 5  ( 5 )   NameLabels = 5  ( 4 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
+LABELS      : N0Labels = 3  ( 3 )  N1Labels = 2  ( 2 )  N2Labels = 0  ( 0 )   TotalLabels = 5  ( 5 )   NameLabels = 5  ( 5 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
 COLORS      : Colors   =   (  )
index a237eed2e53ea2d475fcf5ba0c451d50c6a31069..e62c606ac254d16a244d26bd2a12ae70b51170e5 100644 (file)
@@ -11,7 +11,7 @@ CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   So
 NBSHAPES    : Solid    = 5  ( 5 )  Shell    = 5  ( 5 )  Face     = 39  ( 39 ) 
 STATSHAPE   : Solid    = 18  ( 18 )  Shell    = 18  ( 18 )  Face     = 125  ( 125 )   FreeWire = 0  ( 0 ) 
 TOLERANCE   : MaxTol   =         1e-007  (         1e-005 )  AvgTol   =          1e-007  (  2.879942693e-006 )
-LABELS      : N0Labels = 9  ( 9 )  N1Labels = 13  ( 13 )  N2Labels = 0  ( 0 )   TotalLabels = 22  ( 22 )   NameLabels = 22  ( 19 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
+LABELS      : N0Labels = 9  ( 9 )  N1Labels = 13  ( 13 )  N2Labels = 0  ( 0 )   TotalLabels = 22  ( 22 )   NameLabels = 22  ( 22 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
 COLORS      : Colors   =   (  )