From a2361eda866ed1d795b9057a10eb8de602e6d52c Mon Sep 17 00:00:00 2001 From: azv Date: Mon, 20 Jul 2015 14:23:56 +0300 Subject: [PATCH] 0026458: BRepBuilderAPI_Copy does not copy mesh structure The possibility to preserve triangulation in the copied shape is implemented. It may be enabled by copyMesh flag, by default it is disabled. Depending on copyGeom flag, the triangulation is shared with original shape (if False) or copied (if True). Poly_Triangulation::Copy() method is added. --- src/BRepBuilderAPI/BRepBuilderAPI_Copy.cdl | 12 ++++--- src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx | 41 +++++++++++++++++----- src/BRepTest/BRepTest_BasicCommands.cxx | 29 +++++++++++---- src/BRepTools/BRepTools.cdl | 3 +- src/BRepTools/BRepTools_Modification.cdl | 13 ++++++- src/BRepTools/BRepTools_Modification.cxx | 5 +++ src/BRepTools/BRepTools_Modifier.cxx | 14 ++++++++ src/Poly/Poly_Triangulation.cdl | 3 ++ src/Poly/Poly_Triangulation.cxx | 23 ++++++++++++ 9 files changed, 122 insertions(+), 21 deletions(-) diff --git a/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cdl b/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cdl index 2482709efe..fc03712cd1 100644 --- a/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cdl +++ b/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cdl @@ -37,21 +37,25 @@ is returns Copy from BRepBuilderAPI; - Create(S: Shape from TopoDS; copyGeom: Boolean = Standard_True) + Create(S: Shape from TopoDS; copyGeom: Boolean = Standard_True; copyMesh: Boolean = Standard_False) ---Purpose: Constructs a copy framework and copies the shape S. -- Use the function Shape to access the result. + -- If copyMesh is True, triangulation contained in original shape will be + -- copied along with geometry (by default, triangulation gets lost). -- If copyGeom is False, only topological objects will be copied, while - -- geometry will be shared with original shape. + -- geometry and triangulation will be shared with original shape. -- Note: the constructed framework can be reused to copy -- other shapes: just specify them with the function Perform. returns Copy from BRepBuilderAPI; - Perform(me: in out; S: Shape from TopoDS; copyGeom: Boolean = Standard_True) + Perform(me: in out; S: Shape from TopoDS; copyGeom: Boolean = Standard_True; copyMesh: Boolean = Standard_False) ---Purpose: Copies the shape S. -- Use the function Shape to access the result. + -- If copyMesh is True, triangulation contained in original shape will be + -- copied along with geometry (by default, triangulation gets lost). -- If copyGeom is False, only topological objects will be copied, while - -- geometry will be shared with original shape. + -- geometry and triangulation will be shared with original shape. is static; diff --git a/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx b/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx index ea8862c406..7672ab5f8d 100644 --- a/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx +++ b/src/BRepBuilderAPI/BRepBuilderAPI_Copy.cxx @@ -23,13 +23,18 @@ #include #include #include +#include + +namespace { //! Tool class implementing necessary functionality for copying geometry class BRepBuilderAPI_Copy_Modification : public BRepTools_Modification { public: - BRepBuilderAPI_Copy_Modification (const Standard_Boolean copyGeom) - : myCopyGeom(copyGeom) + BRepBuilderAPI_Copy_Modification (const Standard_Boolean copyGeom, + const Standard_Boolean copyMesh) + : myCopyGeom(copyGeom), + myCopyMesh(copyMesh) { } @@ -49,6 +54,24 @@ public: return Standard_True; } + //! Returns true to indicate the need to copy triangulation; + //! copies it if required + Standard_Boolean NewTriangulation(const TopoDS_Face& F, Handle(Poly_Triangulation)& T) + { + if (!myCopyMesh) + return Standard_False; + + TopLoc_Location L; + T = BRep_Tool::Triangulation(F, L); + + if (T.IsNull()) + return Standard_False; + + if (myCopyGeom) + T = T->Copy(); + return Standard_True; + } + //! Returns true to indicate the need to copy edge; //! copies curves if requested Standard_Boolean NewCurve (const TopoDS_Edge& E, Handle(Geom_Curve)& C, @@ -117,13 +140,15 @@ public: private: Standard_Boolean myCopyGeom; + Standard_Boolean myCopyMesh; }; DEFINE_STANDARD_HANDLE(BRepBuilderAPI_Copy_Modification, BRepTools_Modification) IMPLEMENT_STANDARD_HANDLE(BRepBuilderAPI_Copy_Modification, BRepTools_Modification) - IMPLEMENT_STANDARD_RTTIEXT(BRepBuilderAPI_Copy_Modification, BRepTools_Modification) +} // anonymous namespace + //======================================================================= //function : BRepBuilderAPI_Copy //purpose : @@ -131,7 +156,7 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepBuilderAPI_Copy_Modification, BRepTools_Modificat BRepBuilderAPI_Copy::BRepBuilderAPI_Copy () { - myModification = new BRepBuilderAPI_Copy_Modification(Standard_True); + myModification = new BRepBuilderAPI_Copy_Modification(Standard_True, Standard_False); } @@ -140,9 +165,9 @@ BRepBuilderAPI_Copy::BRepBuilderAPI_Copy () //purpose : //======================================================================= -BRepBuilderAPI_Copy::BRepBuilderAPI_Copy(const TopoDS_Shape& S, const Standard_Boolean copyGeom) +BRepBuilderAPI_Copy::BRepBuilderAPI_Copy(const TopoDS_Shape& S, const Standard_Boolean copyGeom, const Standard_Boolean copyMesh) { - myModification = new BRepBuilderAPI_Copy_Modification(copyGeom); + myModification = new BRepBuilderAPI_Copy_Modification(copyGeom, copyMesh); DoModif(S); } @@ -152,9 +177,9 @@ BRepBuilderAPI_Copy::BRepBuilderAPI_Copy(const TopoDS_Shape& S, const Standard_B //purpose : //======================================================================= -void BRepBuilderAPI_Copy::Perform(const TopoDS_Shape& S, const Standard_Boolean copyGeom) +void BRepBuilderAPI_Copy::Perform(const TopoDS_Shape& S, const Standard_Boolean copyGeom, const Standard_Boolean copyMesh) { - myModification = new BRepBuilderAPI_Copy_Modification(copyGeom); + myModification = new BRepBuilderAPI_Copy_Modification(copyGeom, copyMesh); NotDone(); // on force la copie si on vient deja d`en faire une DoModif(S); } diff --git a/src/BRepTest/BRepTest_BasicCommands.cxx b/src/BRepTest/BRepTest_BasicCommands.cxx index 6b45689c47..56d5a7bf36 100644 --- a/src/BRepTest/BRepTest_BasicCommands.cxx +++ b/src/BRepTest/BRepTest_BasicCommands.cxx @@ -211,24 +211,39 @@ static Standard_Integer deform(Draw_Interpretor& di,Standard_Integer n,const cha static Standard_Integer tcopy(Draw_Interpretor& di,Standard_Integer n,const char** a) { Standard_Boolean copyGeom = Standard_True; + Standard_Boolean copyMesh = Standard_False; Standard_Integer iFirst = 1; // index of first shape argument - if (n > 1 && a[1][0] == '-' && a[1][1] == 'n' ) + if (n > 1) { - copyGeom = Standard_False; - iFirst = 2; + for (Standard_Integer i = 1; i <= 2; i++) + { + if (a[i][0] != '-') + break; + if (a[i][1] == 'n') + { + copyGeom = Standard_False; + iFirst++; + } + else if (a[i][1] == 'm') + { + copyMesh = Standard_True; + iFirst++; + } + } } if (n < 3 || (n - iFirst) % 2) { - cout << "Use: " << a[0] << " [-n(ogeom)] shape1 copy1 [shape2 copy2 [...]]" << endl; - cout << "Option -n forbids copying of geometry (it will be shared)" << endl; + cout << "Use: " << a[0] << " [-n(ogeom)] [-m(esh)] shape1 copy1 [shape2 copy2 [...]]" << endl; + cout << "Option -n forbids copying of geometry (it will be shared)" << endl; + cout << "Option -m forces copying of triangulation (disabled by default)" << endl; return 1; } BRepBuilderAPI_Copy cop; Standard_Integer nbPairs = (n - iFirst) / 2; for (Standard_Integer i=0; i < nbPairs; i++) { - cop.Perform(DBRep::Get(a[i+iFirst]), copyGeom); + cop.Perform(DBRep::Get(a[i+iFirst]), copyGeom, copyMesh); DBRep::Set(a[i+iFirst+1],cop.Shape()); di << a[i+iFirst+1] << " "; } @@ -869,7 +884,7 @@ void BRepTest::BasicCommands(Draw_Interpretor& theCommands) transform,g); theCommands.Add("tcopy", - "tcopy [-n(ogeom)] name1 result1 [name2 result2 ...]", + "tcopy [-n(ogeom)] [-m(esh)] name1 result1 [name2 result2 ...]", __FILE__, tcopy,g); diff --git a/src/BRepTools/BRepTools.cdl b/src/BRepTools/BRepTools.cdl index d35496aef9..ea4282a4e1 100644 --- a/src/BRepTools/BRepTools.cdl +++ b/src/BRepTools/BRepTools.cdl @@ -70,7 +70,8 @@ uses TColStd, TCollection, MMgt, - Message + Message, + Poly is diff --git a/src/BRepTools/BRepTools_Modification.cdl b/src/BRepTools/BRepTools_Modification.cdl index cbc2a4f5d8..ce16bc6bb3 100644 --- a/src/BRepTools/BRepTools_Modification.cdl +++ b/src/BRepTools/BRepTools_Modification.cdl @@ -31,8 +31,9 @@ uses Face from TopoDS, Surface from Geom, Curve from Geom, Curve from Geom2d, - Pnt from gp + Pnt from gp, + Triangulation from Poly is @@ -60,6 +61,16 @@ is returns Boolean from Standard is deferred; + + NewTriangulation(me: mutable; F : Face from TopoDS; + T : out Triangulation from Poly) + ---Purpose: Returns true if the face has been modified according to changed triangulation. + -- If the face has been modified: + -- - T is a new triangulation on the face + returns Boolean from Standard + is virtual; + + NewCurve(me: mutable; E : Edge from TopoDS; C : out Curve from Geom; diff --git a/src/BRepTools/BRepTools_Modification.cxx b/src/BRepTools/BRepTools_Modification.cxx index 641a93e6fb..d9057e3014 100644 --- a/src/BRepTools/BRepTools_Modification.cxx +++ b/src/BRepTools/BRepTools_Modification.cxx @@ -16,4 +16,9 @@ #include +#include +Standard_Boolean BRepTools_Modification::NewTriangulation(const TopoDS_Face&, Handle(Poly_Triangulation)&) +{ + return Standard_False; +} diff --git a/src/BRepTools/BRepTools_Modifier.cxx b/src/BRepTools/BRepTools_Modifier.cxx index 059eb9a440..454ea10a02 100644 --- a/src/BRepTools/BRepTools_Modifier.cxx +++ b/src/BRepTools/BRepTools_Modifier.cxx @@ -283,6 +283,20 @@ Standard_Boolean BRepTools_Modifier::Rebuild B.NaturalRestriction(TopoDS::Face(result), BRep_Tool::NaturalRestriction(TopoDS::Face(S))); } + + // update triangulation on the copied face + Handle(Poly_Triangulation) aTriangulation; + if (M->NewTriangulation(TopoDS::Face(S), aTriangulation)) + { + if (rebuild) // the copied face already exists => update it + B.UpdateFace(TopoDS::Face(result), aTriangulation); + else + { // create new face with bare triangulation + B.MakeFace(TopoDS::Face(result), aTriangulation); + result.Location(S.Location()); + } + rebuild = Standard_True; + } } break; diff --git a/src/Poly/Poly_Triangulation.cdl b/src/Poly/Poly_Triangulation.cdl index 2f5d9d756d..243071e2a9 100644 --- a/src/Poly/Poly_Triangulation.cdl +++ b/src/Poly/Poly_Triangulation.cdl @@ -84,6 +84,9 @@ is -- from Nodes on the surface approximated by the -- constructed triangulation. + Copy(me) returns Triangulation from Poly; + ---Purpose: Creates full copy of current triangulation. + Deflection(me) returns Real; ---Purpose: Returns the deflection of this triangulation. Deflection(me : mutable; D : Real); diff --git a/src/Poly/Poly_Triangulation.cxx b/src/Poly/Poly_Triangulation.cxx index 10b5ca02e8..5cd03948df 100644 --- a/src/Poly/Poly_Triangulation.cxx +++ b/src/Poly/Poly_Triangulation.cxx @@ -75,6 +75,29 @@ Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt& Nodes, myUVNodes->ChangeArray1() = UVNodes; } +//======================================================================= +//function : Copy +//purpose : +//======================================================================= + +Handle(Poly_Triangulation) Poly_Triangulation::Copy() const +{ + Handle(Poly_Triangulation) aCopy; + if (HasUVNodes()) + aCopy = new Poly_Triangulation(Nodes(), UVNodes(), Triangles()); + else + aCopy = new Poly_Triangulation(Nodes(), Triangles()); + aCopy->Deflection(myDeflection); + + if (HasNormals()) + { + aCopy->myNormals = new TShort_HArray1OfShortReal(myNormals->Lower(), myNormals->Upper()); + aCopy->myNormals->ChangeArray1().Assign (myNormals->Array1()); + } + + return aCopy; +} + //======================================================================= //function : Deflection //purpose :