0026897: BRepBuilderAPI_Copy does not copy polygons
authorazv <azv@opencascade.com>
Fri, 20 Nov 2015 13:00:06 +0000 (16:00 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 27 Nov 2015 07:08:18 +0000 (10:08 +0300)
1. Implemented copying for 3D polygons and polygons on surfaces
2. Added test case bugs/modalg_6/bug26897

src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx
src/BRepTools/BRepTools_Modification.cxx
src/BRepTools/BRepTools_Modification.hxx
src/BRepTools/BRepTools_Modifier.cxx
src/Poly/Poly_Polygon3D.cxx
src/Poly/Poly_Polygon3D.hxx
src/Poly/Poly_PolygonOnTriangulation.cxx
src/Poly/Poly_PolygonOnTriangulation.hxx
src/Poly/Poly_Triangulation.cxx
src/Poly/Poly_Triangulation.hxx
tests/bugs/modalg_6/bug26897 [new file with mode: 0644]

index 76eec33..51d0d61 100644 (file)
@@ -68,6 +68,7 @@ public:
     if (T.IsNull())
       return Standard_False;
 
+    // mesh is copied if and only if the geometry need to be copied too
     if (myCopyGeom)
       T = T->Copy();
     return Standard_True;
@@ -88,6 +89,46 @@ public:
     return Standard_True;
   }
 
+  //! Returns true to indicate the need to copy polygon;
+  //! copies it if required
+  Standard_Boolean NewPolygon(const TopoDS_Edge& E, Handle(Poly_Polygon3D)& P)
+  {
+    if (!myCopyMesh)
+      return Standard_False;
+
+    TopLoc_Location aLoc;
+    P = BRep_Tool::Polygon3D(E, aLoc);
+
+    if (P.IsNull())
+      return Standard_False;
+
+    // polygon is copied if and only if the geometry need to be copied too
+    if (myCopyGeom)
+      P = P->Copy();
+    return Standard_True;
+  }
+
+  //! Returns true to indicate the need to copy polygon;
+  //! copies it if required
+  Standard_Boolean NewPolygonOnTriangulation(const TopoDS_Edge& E, const TopoDS_Face& F,
+                                             Handle(Poly_PolygonOnTriangulation)& P)
+  {
+    if (!myCopyMesh)
+      return Standard_False;
+
+    TopLoc_Location aLoc;
+    Handle(Poly_Triangulation) aTria = BRep_Tool::Triangulation(F, aLoc);
+    P = BRep_Tool::PolygonOnTriangulation(E, aTria, aLoc);
+
+    if (P.IsNull())
+      return Standard_False;
+
+    // polygon is copied if and only if the geometry need to be copied too
+    if (myCopyGeom)
+      P = P->Copy();
+    return Standard_True;
+  }
+
   //! Returns true to indicate the need to copy vertex
   Standard_Boolean NewPoint (const TopoDS_Vertex& V, gp_Pnt& P,
                              Standard_Real& Tol) Standard_OVERRIDE
index 50e4b71..a4544c1 100644 (file)
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Vertex.hxx>
+#include <Poly_PolygonOnTriangulation.hxx>
 #include <Poly_Triangulation.hxx>
 
 Standard_Boolean BRepTools_Modification::NewTriangulation(const TopoDS_Face&, Handle(Poly_Triangulation)&)
 {
   return Standard_False;
 }
+
+Standard_Boolean BRepTools_Modification::NewPolygon(const TopoDS_Edge&, Handle(Poly_Polygon3D)&)
+{
+  return Standard_False;
+}
+
+Standard_Boolean BRepTools_Modification::NewPolygonOnTriangulation(const TopoDS_Edge&, const TopoDS_Face&, Handle(Poly_PolygonOnTriangulation)&)
+{
+  return Standard_False;
+}
index be93ba7..08200fc 100644 (file)
@@ -34,6 +34,9 @@ class gp_Pnt;
 class Geom2d_Curve;
 class Poly_Triangulation;
 
+class Poly_Polygon3D;
+class Poly_PolygonOnTriangulation;
+
 
 class BRepTools_Modification;
 DEFINE_STANDARD_HANDLE(BRepTools_Modification, MMgt_TShared)
@@ -74,6 +77,16 @@ public:
   //! If the edge has not been modified, this function
   //! returns false, and the values of C, L and Tol are not significant.
   Standard_EXPORT virtual Standard_Boolean NewCurve (const TopoDS_Edge& E, Handle(Geom_Curve)& C, TopLoc_Location& L, Standard_Real& Tol) = 0;
+
+  //! Returns true if the edge has been modified according to changed polygon.
+  //! If the edge has been modified:
+  //! - P is a new polygon
+  Standard_EXPORT virtual Standard_Boolean NewPolygon(const TopoDS_Edge& E, Handle(Poly_Polygon3D)& P);
+
+  //! Returns true if the edge has been modified according to changed polygon on triangulation.
+  //! If the edge has been modified:
+  //! - P is a new polygon on triangulation
+  Standard_EXPORT virtual Standard_Boolean NewPolygonOnTriangulation(const TopoDS_Edge& E, const TopoDS_Face& F, Handle(Poly_PolygonOnTriangulation)& P);
   
   //! Returns true if the vertex V has been modified.
   //! If V has been modified:
index 4dc0ed5..e92ec7b 100644 (file)
@@ -330,6 +330,20 @@ Standard_Boolean BRepTools_Modifier::Rebuild
        B.SameRange(TopoDS::Edge(result),
                    BRep_Tool::SameRange(TopoDS::Edge(S)));
       }
+
+      // update polygonal structure on the edge
+      Handle(Poly_Polygon3D) aPolygon;
+      if (M->NewPolygon(TopoDS::Edge(S), aPolygon))
+      {
+        if (rebuild) // the copied edge already exists => update it
+          B.UpdateEdge(TopoDS::Edge(result), aPolygon, S.Location());
+        else
+        { // create new edge with bare polygon
+          B.MakeEdge(TopoDS::Edge(result), aPolygon);
+          result.Location(S.Location());
+        }
+        rebuild = Standard_True;
+      }
     }
     break;
 
@@ -405,7 +419,7 @@ Standard_Boolean BRepTools_Modifier::Rebuild
       {
         const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
 
-        if (M->NewCurve2d(edge, face, TopoDS::Edge(myMap(ex.Current())), TopoDS::Face(result), curve2d, tol)) 
+        if (M->NewCurve2d(edge, face, TopoDS::Edge(myMap(ex.Current())), TopoDS::Face(result), curve2d, tol))
         {
           // rem dub 16/09/97 : Make constant topology or not make at all.
           // Do not make if CopySurface = 1
@@ -510,6 +524,39 @@ Standard_Boolean BRepTools_Modifier::Rebuild
             }
           }
         }
+
+        // Copy polygon on triangulation
+        Handle(Poly_PolygonOnTriangulation) aPolyOnTria_1, aPolyOnTria_2;
+        Standard_Boolean aNewPonT = M->NewPolygonOnTriangulation(edge, face, aPolyOnTria_1);
+        if (BRepTools::IsReallyClosed(edge, face))
+        {
+          // Obtain triangulation on reversed edge
+          TopoDS_Edge anEdgeRev = edge;
+          anEdgeRev.Reverse();
+          aNewPonT = M->NewPolygonOnTriangulation(anEdgeRev, face, aPolyOnTria_2) || aNewPonT;
+          // It there is only one polygon on triangulation, store it to aPolyOnTria_1
+          if (aPolyOnTria_1.IsNull() && !aPolyOnTria_2.IsNull())
+          {
+            aPolyOnTria_1 = aPolyOnTria_2;
+            aPolyOnTria_2 = Handle(Poly_PolygonOnTriangulation)();
+          }
+        }
+        if (aNewPonT)
+        {
+          TopLoc_Location aLocation;
+          Handle(Poly_Triangulation) aNewFaceTria =
+              BRep_Tool::Triangulation(TopoDS::Face(myMap(face)), aLocation);
+          TopoDS_Edge aNewEdge = TopoDS::Edge(myMap(edge));
+          if (aPolyOnTria_2.IsNull())
+            B.UpdateEdge(aNewEdge, aPolyOnTria_1, aNewFaceTria, aLocation);
+          else
+          {
+            if (edge.Orientation() == TopAbs_FORWARD)
+              B.UpdateEdge(aNewEdge, aPolyOnTria_1, aPolyOnTria_2, aNewFaceTria, aLocation);
+            else
+              B.UpdateEdge(aNewEdge, aPolyOnTria_2, aPolyOnTria_1, aNewFaceTria, aLocation);
+          }
+        }
       }
 
     }
index c80577d..52a7826 100644 (file)
@@ -53,6 +53,22 @@ Poly_Polygon3D::Poly_Polygon3D(const TColgp_Array1OfPnt&   Nodes,
   }
 }
 
+//=======================================================================
+//function : Copy
+//purpose  : 
+//=======================================================================
+
+Handle(Poly_Polygon3D) Poly_Polygon3D::Copy() const
+{
+  Handle(Poly_Polygon3D) aCopy;
+  if (myParameters.IsNull())
+    aCopy = new Poly_Polygon3D(myNodes);
+  else
+    aCopy = new Poly_Polygon3D(myNodes, myParameters->Array1());
+  aCopy->Deflection(myDeflection);
+  return aCopy;
+}
+
 
 //=======================================================================
 //function : Deflection
index 3805611..d56b78a 100644 (file)
@@ -58,6 +58,9 @@ public:
   //! Both the Nodes and Parameters tables must have the
   //! same bounds. This property is not checked at construction time.
   Standard_EXPORT Poly_Polygon3D(const TColgp_Array1OfPnt& Nodes, const TColStd_Array1OfReal& Parameters);
+
+  //! Creates a copy of current polygon
+  Standard_EXPORT virtual Handle(Poly_Polygon3D) Copy() const;
   
   //! Returns the deflection of this polygon
   Standard_EXPORT Standard_Real Deflection() const;
index 36b9dcb..c1b42ca 100644 (file)
@@ -48,6 +48,22 @@ Poly_PolygonOnTriangulation::Poly_PolygonOnTriangulation
 }
 
 //=======================================================================
+//function : Copy
+//purpose  : 
+//=======================================================================
+
+Handle(Poly_PolygonOnTriangulation) Poly_PolygonOnTriangulation::Copy() const
+{
+  Handle(Poly_PolygonOnTriangulation) aCopy;
+  if (myParameters.IsNull())
+    aCopy = new Poly_PolygonOnTriangulation(myNodes);
+  else
+    aCopy = new Poly_PolygonOnTriangulation(myNodes, myParameters->Array1());
+  aCopy->Deflection(myDeflection);
+  return aCopy;
+}
+
+//=======================================================================
 //function : Deflection
 //purpose  : 
 //=======================================================================
index 0d6173a..b62c458 100644 (file)
@@ -68,7 +68,10 @@ public:
   //! The tables Nodes and Parameters must be the same size.
   //! This property is not checked at construction time.
   Standard_EXPORT Poly_PolygonOnTriangulation(const TColStd_Array1OfInteger& Nodes, const TColStd_Array1OfReal& Parameters);
-  
+
+  //! Creates a copy of current polygon
+  Standard_EXPORT virtual Handle(Poly_PolygonOnTriangulation) Copy() const;
+
   //! Returns the deflection of this polygon
   Standard_EXPORT Standard_Real Deflection() const;
   
index f86ec96..44a4e8f 100644 (file)
@@ -82,7 +82,7 @@ Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    Nodes,
 //purpose  : 
 //=======================================================================
 
-Handle(Poly_Triangulation) Poly_Triangulation::Copy()
+Handle(Poly_Triangulation) Poly_Triangulation::Copy() const
 {
   Handle(Poly_Triangulation) aCopy;
   if (HasUVNodes())
index cb241bc..add28cb 100644 (file)
@@ -91,7 +91,7 @@ public:
   Standard_EXPORT Poly_Triangulation(const TColgp_Array1OfPnt& Nodes, const TColgp_Array1OfPnt2d& UVNodes, const Poly_Array1OfTriangle& Triangles);
   
   //! Creates full copy of current triangulation
-  Standard_EXPORT virtual Handle(Poly_Triangulation) Copy();
+  Standard_EXPORT virtual Handle(Poly_Triangulation) Copy() const;
   
   //! Returns the deflection of this triangulation.
   Standard_EXPORT Standard_Real Deflection() const;
diff --git a/tests/bugs/modalg_6/bug26897 b/tests/bugs/modalg_6/bug26897
new file mode 100644 (file)
index 0000000..b7ef1a1
--- /dev/null
@@ -0,0 +1,63 @@
+puts "============"
+puts "OCC26897"
+puts "============"
+puts ""
+###############################
+## The mesh should not rebuild on copied shape
+###############################
+
+proc CHECKMESH {data nb_tria nb_nodes defl tol} {
+    regexp {This shape contains ([0-9]+) triangles.\s* ([0-9]+) nodes.} $data dummy cur_nb_tria cur_nb_nodes
+    regexp {Maximal deflection ([-0-9.+eE]+)} $data dummy cur_defl
+
+    if {$nb_tria == $cur_nb_tria && $nb_nodes == $cur_nb_nodes && abs($defl - $cur_defl) <= $tol} {
+      puts "OK: Triangulation is not changed"
+    } else {
+      if {$nb_tria != $cur_nb_tria} {
+        puts "Error: Wrong number of triangles, $cur_nb_tria instead of $nb_tria"
+      }
+      if {$nb_nodes != $cur_nb_nodes} {
+        puts "Error: Wrong number of nodes, $cur_nb_nodes instead of $nb_nodes"
+      }
+      set diff [expr {abs($defl - $cur_defl)}]
+      if {$diff > $tol} {
+        puts "Error: Wrong deflection, $cur_defl instead of $defl (difference is $diff)"
+      }
+    }
+    puts ""
+}
+
+###############################
+
+
+pload MODELING
+set tol 1.0e-7
+
+cone c 0 0 0 45 0
+mkface f c 0 6.28318530717958647 0 10
+
+# Mesh the face and store initial data
+incmesh f 0.1
+set base [trinfo f]
+regexp {This shape contains ([0-9]+) triangles.\s* ([0-9]+) nodes.} $base dummy base_tria base_nodes
+regexp {Maximal deflection ([-0-9.+eE]+)} $base dummy base_defl
+
+# Copy face
+tcopy -m f fc
+
+# Remesh initial face and check it is not changed
+incmesh f 1.0
+set data [trinfo f]
+CHECKMESH $data $base_tria $base_nodes $base_defl $tol
+
+# Compare mesh info from copied shape
+set data [trinfo fc]
+CHECKMESH $data $base_tria $base_nodes $base_defl $tol
+
+# Remesh copied shape and compare mesh once again
+incmesh fc 1.0
+set data [trinfo fc]
+CHECKMESH $data $base_tria $base_nodes $base_defl $tol
+
+copy fc result
+set 3dviewer 1