0026174: Data Exchange, IGES - Loss of color after the second write of file
[occt.git] / src / BRepToIGES / BRepToIGES_BRShell.cxx
index 3095557..34e5f6d 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
 #include <BRepToIGES_BREntity.hxx>
 #include <BRepToIGES_BRShell.hxx>
 #include <BRepToIGES_BRWire.hxx>
@@ -123,8 +124,14 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
   }
 
   // pour explorer la face , il faut la mettre fORWARD.
-  TopoDS_Face myface;
+  TopoDS_Face aFace = start;
+  // Associates the input face (start) and its sub-shapes with the reversed variant,
+  // if the input face has a Reversed orientation
+  TopTools_DataMapOfShapeShape aShapeShapeMap;
   if (start.Orientation() == TopAbs_REVERSED) {
+    BRepBuilderAPI_Copy aCopy;
+    aCopy.Perform(aFace);
+   
     //create face with redirected surface
     BRep_Builder B;
     TopLoc_Location aLoc;
@@ -133,29 +140,35 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
     {
       // take basis surface, because pcurves will be transformed, so trim will be shifted,
       // accorded to new face bounds
-      Handle(Geom_RectangularTrimmedSurface) aTrimmedSurf = 
+      Handle(Geom_RectangularTrimmedSurface) aTrimmedSurf =
         Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf);
       aSurf = aTrimmedSurf->BasisSurface();
     }
     aSurf = aSurf->UReversed();
     Standard_Real aTol = BRep_Tool::Tolerance(start);
-    B.MakeFace(myface, aSurf, aLoc ,aTol);
+    B.MakeFace(aFace, aSurf, aLoc, aTol);
     // set specifics flags of a Face
-    B.NaturalRestriction(myface, BRep_Tool::NaturalRestriction(start));
+    B.NaturalRestriction(aFace, BRep_Tool::NaturalRestriction(start));
     //add wires
     TopoDS_Wire anOuter = TopoDS::Wire(ShapeAlgo::AlgoContainer()->OuterWire(start));
     TopExp_Explorer ex;
-    for (ex.Init(start,TopAbs_WIRE); ex.More(); ex.Next()) {
+    for (ex.Init(start, TopAbs_WIRE); ex.More(); ex.Next()) {
       TopoDS_Wire W = TopoDS::Wire(ex.Current());
+      TopoDS_Wire aCopyWire = TopoDS::Wire(aCopy.ModifiedShape(W));
+      aCopyWire = TopoDS::Wire(aCopyWire.Oriented(W.Orientation()));
       if (!W.IsNull() && W.IsSame(anOuter)) {
-        B.Add(myface, W);
+        B.Add(aFace, aCopyWire);
+        aShapeShapeMap.Bind(aCopyWire, W); // Bind the reversed copy of Wire to the original
         break;
       }
-    }     
-    for (ex.Init(start,TopAbs_WIRE); ex.More(); ex.Next()) {
+    }
+    for (ex.Init(start, TopAbs_WIRE); ex.More(); ex.Next()) {
       TopoDS_Wire W = TopoDS::Wire(ex.Current());
+      TopoDS_Wire aCopyWire = TopoDS::Wire(aCopy.ModifiedShape(W));
+      aCopyWire = TopoDS::Wire(aCopyWire.Oriented(W.Orientation()));
       if (!W.IsNull() && !W.IsSame(anOuter)) {
-        B.Add(myface, W);
+        B.Add(aFace, aCopyWire);
+        aShapeShapeMap.Bind(aCopyWire, W); // Bind the reversed copy of Wire to the original
       }
     }
 
@@ -167,43 +180,48 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
     gp_Ax2d axis(gp_Pnt2d(aCenter, V1), gp_Dir2d(0.,1.));
     T.SetMirror(axis);
     NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> aMap (101, new NCollection_IncAllocator);
-    for (ex.Init(myface,TopAbs_EDGE);ex.More(); ex.Next()) {
-      TopoDS_Edge anEdge = TopoDS::Edge(ex.Current());
-      if (!aMap.Add(anEdge))
+    for (ex.Init(start, TopAbs_EDGE); ex.More(); ex.Next()) {
+      TopoDS_Edge anOrigEdge = TopoDS::Edge(ex.Current());
+      TopoDS_Edge aCopyEdge = TopoDS::Edge(aCopy.ModifiedShape(anOrigEdge));
+      aCopyEdge = TopoDS::Edge(aCopyEdge.Oriented(anOrigEdge.Orientation()));
+      if (!aMap.Add(aCopyEdge))
         // seam edge has been already updated
         continue;
       Standard_Real f, l;
       Handle(Geom2d_Curve) aCurve1, aCurve2;
-      aCurve1 = BRep_Tool::CurveOnSurface(anEdge, start, f, l);
-      aTol = BRep_Tool::Tolerance(anEdge);
+      aCurve1 = BRep_Tool::CurveOnSurface(aCopyEdge, TopoDS::Face(aCopy.ModifiedShape(start)), f, l);
+      aTol = BRep_Tool::Tolerance(aCopyEdge);
       if (!aCurve1.IsNull()) {
         aCurve1 = Handle(Geom2d_Curve)::DownCast(aCurve1->Transformed(T));
-        if (BRepTools::IsReallyClosed(anEdge, start)) {
-          TopoDS_Edge revEdge = TopoDS::Edge(anEdge.Reversed());
-          aCurve2 = BRep_Tool::CurveOnSurface(revEdge, start, f, l);
+        if (BRepTools::IsReallyClosed(aCopyEdge, TopoDS::Face(aCopy.ModifiedShape(start)))) {
+          TopoDS_Edge revEdge = TopoDS::Edge(aCopyEdge.Reversed());
+          aCurve2 = BRep_Tool::CurveOnSurface(revEdge, TopoDS::Face(aCopy.ModifiedShape(start)), f, l);
           if (!aCurve2.IsNull()) {
             aCurve2 = Handle(Geom2d_Curve)::DownCast(aCurve2->Transformed(T));
-            if (anEdge.Orientation() == TopAbs_FORWARD)
-              B.UpdateEdge(anEdge, aCurve1, aCurve2, myface, aTol);
+            if (aCopyEdge.Orientation() == TopAbs_FORWARD)
+            {
+              B.UpdateEdge(aCopyEdge, aCurve1, aCurve2, aFace, aTol);
+            }
             else
-              B.UpdateEdge(anEdge, aCurve2, aCurve1, myface, aTol);
+            {
+              B.UpdateEdge(aCopyEdge, aCurve2, aCurve1, aFace, aTol);
+            }
           }
           else {
-            B.UpdateEdge(anEdge, aCurve1, myface, aTol);
+            B.UpdateEdge(aCopyEdge, aCurve1, aFace, aTol);
           }
         }
         else {
-          B.UpdateEdge(anEdge, aCurve1, myface, aTol);
+          B.UpdateEdge(aCopyEdge, aCurve1, aFace, aTol);
         }
         // set range for degenerated edges
-        if (BRep_Tool::Degenerated(anEdge)) {
-          B.Range(anEdge, myface, f, l);
+        if (BRep_Tool::Degenerated(aCopyEdge)) {
+          B.Range(aCopyEdge, aFace, f, l);
         }
       }
+      aShapeShapeMap.Bind(aCopyEdge, anOrigEdge); // Bind the reversed copy of Edge to the original
     }
-  }
-  else {
-    myface = start;
+    aShapeShapeMap.Bind(start, aFace); // Bind the original face to the reversed copy
   }
 
   //Standard_Integer Nb = 0; //szv#4:S4163:12Mar99 unused
@@ -213,13 +231,12 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
   // returns the face surface
   // ------------------------
 
-  Handle(Geom_Surface) Surf = BRep_Tool::Surface(myface);
-  Handle(Geom_Surface) Surf1;
+  Handle(Geom_Surface) Surf = BRep_Tool::Surface(aFace);
 
   if (!Surf.IsNull()) {
     Standard_Real U1, U2, V1, V2;
     // pour limiter les surfaces de base
-    BRepTools::UVBounds(myface, U1, U2, V1, V2);  
+    BRepTools::UVBounds(aFace, U1, U2, V1, V2);
     GeomToIGES_GeomSurface GS;
     GS.SetModel(GetModel());
     ISurf = GS.TransferSurface(Surf, U1, U2, V1, V2);
@@ -228,14 +245,6 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
       return res;
     }
     Length = GS.Length();
-
-    // modif mjm du 17/07/97
-    if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { 
-      DeclareAndCast(Geom_RectangularTrimmedSurface, rectang, Surf);
-      Surf1 = rectang->BasisSurface();
-    }
-    else 
-      Surf1 = Surf;
   }
 
 
@@ -249,11 +258,11 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
 
   // outer wire
   //:n3  TopoDS_Wire Outer = BRepTools::OuterWire(myface);
-  TopoDS_Wire Outer = ShapeAlgo::AlgoContainer()->OuterWire(myface); //:n3 
+  TopoDS_Wire Outer = ShapeAlgo::AlgoContainer()->OuterWire(aFace); //:n3 
   Handle(IGESGeom_CurveOnSurface) IOuter = new IGESGeom_CurveOnSurface;
   if (!Outer.IsNull()) {
     Handle(IGESData_IGESEntity) ICurve3d = 
-      BW.TransferWire(Outer, myface, ICurve2d, Length);
+      BW.TransferWire(Outer, aFace, aShapeShapeMap, ICurve2d, Length);
     if ((!ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 3; 
     if ((!ICurve3d.IsNull()) && (ICurve2d.IsNull())) Iprefer = 2; 
     if ((ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 1; 
@@ -264,7 +273,7 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
   TopExp_Explorer Ex;
   Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
 
-  for (Ex.Init(myface,TopAbs_WIRE); Ex.More(); Ex.Next()) {
+  for (Ex.Init(aFace, TopAbs_WIRE); Ex.More(); Ex.Next()) {
     TopoDS_Wire W = TopoDS::Wire(Ex.Current());
     Handle(IGESGeom_CurveOnSurface) Curve = new IGESGeom_CurveOnSurface;
     if (W.IsNull()) {
@@ -272,7 +281,7 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
     }
     else if (!W.IsSame(Outer)) {
       Handle(IGESData_IGESEntity) ICurve3d = 
-             BW.TransferWire(W, myface, ICurve2d, Length);
+             BW.TransferWire(W, aFace, aShapeShapeMap, ICurve2d, Length);
       if ((!ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 3; 
       if ((!ICurve3d.IsNull()) && (ICurve2d.IsNull())) Iprefer = 2; 
       if ((ICurve3d.IsNull()) && (!ICurve2d.IsNull())) Iprefer = 1; 
@@ -282,15 +291,15 @@ Handle(IGESData_IGESEntity) BRepToIGES_BRShell ::TransferFace(const TopoDS_Face&
   }
 
   // all inners edges not in a wire
-  for (Ex.Init(myface,TopAbs_EDGE,TopAbs_WIRE); Ex.More(); Ex.Next()) {
+  for (Ex.Init(aFace,TopAbs_EDGE,TopAbs_WIRE); Ex.More(); Ex.Next()) {
     TopoDS_Edge E = TopoDS::Edge(Ex.Current());
     Handle(IGESGeom_CurveOnSurface) Curve = new IGESGeom_CurveOnSurface;
     if (E.IsNull()) {
       AddWarning(start," an Edge is a null entity");
     }
     else {
-      Handle(IGESData_IGESEntity) ICurve3d = BW.TransferEdge(E, Standard_False);
-      Handle(IGESData_IGESEntity) newICurve2d = BW.TransferEdge(E, myface, Length, Standard_False);
+      Handle(IGESData_IGESEntity) ICurve3d = BW.TransferEdge(E, aShapeShapeMap, Standard_False);
+      Handle(IGESData_IGESEntity) newICurve2d = BW.TransferEdge(E, aFace, aShapeShapeMap, Length, Standard_False);
       if ((!ICurve3d.IsNull()) && (!newICurve2d.IsNull())) Iprefer = 3; 
       if ((!ICurve3d.IsNull()) && (newICurve2d.IsNull())) Iprefer = 2; 
       if ((ICurve3d.IsNull()) && (!newICurve2d.IsNull())) Iprefer = 1;