diff --git a/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx b/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx index 76eec33383..51d0d61ca8 100644 --- a/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx +++ b/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx @@ -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 diff --git a/src/BRepTools/BRepTools_Modification.cxx b/src/BRepTools/BRepTools_Modification.cxx index 50e4b71330..a4544c1321 100644 --- a/src/BRepTools/BRepTools_Modification.cxx +++ b/src/BRepTools/BRepTools_Modification.cxx @@ -25,9 +25,20 @@ #include #include #include +#include #include 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; +} diff --git a/src/BRepTools/BRepTools_Modification.hxx b/src/BRepTools/BRepTools_Modification.hxx index be93ba765c..08200fcaf4 100644 --- a/src/BRepTools/BRepTools_Modification.hxx +++ b/src/BRepTools/BRepTools_Modification.hxx @@ -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: diff --git a/src/BRepTools/BRepTools_Modifier.cxx b/src/BRepTools/BRepTools_Modifier.cxx index 4dc0ed56d5..e92ec7b2ba 100644 --- a/src/BRepTools/BRepTools_Modifier.cxx +++ b/src/BRepTools/BRepTools_Modifier.cxx @@ -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); + } + } } } diff --git a/src/Poly/Poly_Polygon3D.cxx b/src/Poly/Poly_Polygon3D.cxx index c80577d203..52a782666e 100644 --- a/src/Poly/Poly_Polygon3D.cxx +++ b/src/Poly/Poly_Polygon3D.cxx @@ -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 diff --git a/src/Poly/Poly_Polygon3D.hxx b/src/Poly/Poly_Polygon3D.hxx index 3805611132..d56b78a0b3 100644 --- a/src/Poly/Poly_Polygon3D.hxx +++ b/src/Poly/Poly_Polygon3D.hxx @@ -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; diff --git a/src/Poly/Poly_PolygonOnTriangulation.cxx b/src/Poly/Poly_PolygonOnTriangulation.cxx index 36b9dcb4f7..c1b42cacd1 100644 --- a/src/Poly/Poly_PolygonOnTriangulation.cxx +++ b/src/Poly/Poly_PolygonOnTriangulation.cxx @@ -47,6 +47,22 @@ Poly_PolygonOnTriangulation::Poly_PolygonOnTriangulation myParameters->ChangeArray1() = Parameters; } +//======================================================================= +//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 : diff --git a/src/Poly/Poly_PolygonOnTriangulation.hxx b/src/Poly/Poly_PolygonOnTriangulation.hxx index 0d6173a7f6..b62c4586f2 100644 --- a/src/Poly/Poly_PolygonOnTriangulation.hxx +++ b/src/Poly/Poly_PolygonOnTriangulation.hxx @@ -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; diff --git a/src/Poly/Poly_Triangulation.cxx b/src/Poly/Poly_Triangulation.cxx index f86ec96ecf..44a4e8f1a8 100644 --- a/src/Poly/Poly_Triangulation.cxx +++ b/src/Poly/Poly_Triangulation.cxx @@ -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()) diff --git a/src/Poly/Poly_Triangulation.hxx b/src/Poly/Poly_Triangulation.hxx index cb241bc5e3..add28cb013 100644 --- a/src/Poly/Poly_Triangulation.hxx +++ b/src/Poly/Poly_Triangulation.hxx @@ -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 index 0000000000..b7ef1a157f --- /dev/null +++ b/tests/bugs/modalg_6/bug26897 @@ -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