diff --git a/libsrc/occ/occ_utils.cpp b/libsrc/occ/occ_utils.cpp index 8b747137..210e358e 100644 --- a/libsrc/occ/occ_utils.cpp +++ b/libsrc/occ/occ_utils.cpp @@ -11,6 +11,22 @@ namespace netgen return occ2ng( Handle(BRep_TVertex)::DownCast(shape)->Pnt() ); } + Transformation<3> occ2ng (const gp_Trsf & occ_trafo) + { + Transformation<3> trafo; + auto v = occ_trafo.TranslationPart(); + auto m = occ_trafo.VectorialPart(); + auto & tv = trafo.GetVector(); + auto & tm = trafo.GetMatrix(); + for(auto i : Range(3)) + { + tv[i] = v.Coord(i+1); + for(auto k : Range(3)) + tm(i,k) = m(i+1,k+1); + } + return trafo; + } + Box<3> GetBoundingBox( const TopoDS_Shape & shape ) { Bnd_Box bb; diff --git a/libsrc/occ/occ_utils.hpp b/libsrc/occ/occ_utils.hpp index 1e9fa9a1..e51a2b51 100644 --- a/libsrc/occ/occ_utils.hpp +++ b/libsrc/occ/occ_utils.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "meshing.hpp" @@ -47,6 +48,8 @@ namespace netgen return occ2ng (BRep_Tool::Pnt (v)); } + DLL_HEADER Transformation<3> occ2ng (const gp_Trsf & t); + inline gp_Pnt ng2occ (const Point<3> & p) { return gp_Pnt(p(0), p(1), p(2)); diff --git a/libsrc/occ/occgeom.cpp b/libsrc/occ/occgeom.cpp index 290c4ece..b013b073 100644 --- a/libsrc/occ/occgeom.cpp +++ b/libsrc/occ/occgeom.cpp @@ -1940,12 +1940,19 @@ namespace netgen return occ2ng( props.CentreOfMass() ); } - void OCCGeometry :: IdentifyEdges(const TopoDS_Shape & me, const TopoDS_Shape & you, string name, Identifications::ID_TYPE type) + void OCCGeometry :: IdentifyEdges(const TopoDS_Shape & me, const TopoDS_Shape & you, string name, Identifications::ID_TYPE type, std::optional opt_trafo) { - auto cme = GetCenter(me); - auto cyou = GetCenter(you); - Transformation<3> trafo{cyou-cme}; - identifications[me.TShape()].push_back( {me.TShape(), you.TShape(), Transformation<3>(cyou - cme), name, type} ); + Transformation<3> trafo; + if(opt_trafo) + trafo = occ2ng(*opt_trafo); + else + { + auto cme = GetCenter(me); + auto cyou = GetCenter(you); + trafo = Transformation<3>{cyou-cme}; + } + + identifications[me.TShape()].push_back( {me.TShape(), you.TShape(), trafo, name, type} ); auto vme = GetVertices(me); auto vyou = GetVertices(you); @@ -1976,6 +1983,11 @@ namespace netgen std::map vmap; auto verts_me = GetVertices(me); + auto verts_you = GetVertices(you); + + if(verts_me.size() != verts_you.size()) + return false; + for (auto i : Range(verts_me.size())) { auto s = verts_me[i].TShape(); @@ -1987,7 +1999,7 @@ namespace netgen } bool all_verts_mapped = true; - for (auto vert : GetVertices(you)) + for (auto vert : verts_you) { auto s = vert.TShape(); auto p = occ2ng(s); @@ -2006,22 +2018,40 @@ namespace netgen return all_verts_mapped; } - void OCCGeometry :: IdentifyFaces(const TopoDS_Shape & solid, const TopoDS_Shape & me, const TopoDS_Shape & you, string name, Identifications::ID_TYPE type) + void OCCGeometry :: IdentifyFaces(const TopoDS_Shape & solid, const TopoDS_Shape & me, const TopoDS_Shape & you, string name, Identifications::ID_TYPE type, std::optional opt_trafo) { - auto cme = GetCenter(me); - auto cyou = GetCenter(you); - Transformation<3> trafo(cyou-cme); + Transformation<3> trafo; + if(opt_trafo) + { + trafo = occ2ng(*opt_trafo); + } + else + { + auto cme = GetCenter(me); + auto cyou = GetCenter(you); + trafo = Transformation<3>(cyou-cme); + } - identifications[me.TShape()].push_back - (OCCIdentification { me.TShape(), you.TShape(), trafo, name, type }); + auto faces_me = GetFaces(me); + auto faces_you = GetFaces(you); - auto edges_me = GetEdges(me); - auto edges_you = GetEdges(you); + for(auto face_me : faces_me) + for(auto face_you : faces_you) + { + if(!IsMappedShape(trafo, face_me, face_you)) + continue; - for (auto e_me : edges_me) - for (auto e_you : edges_you) - if(IsMappedShape(trafo, e_me, e_you)) - IdentifyEdges(e_me, e_you, name, type); + identifications[face_me.TShape()].push_back + (OCCIdentification { face_me.TShape(), face_you.TShape(), trafo, name, type }); + + auto edges_me = GetEdges(me); + auto edges_you = GetEdges(you); + + for (auto e_me : edges_me) + for (auto e_you : edges_you) + if(IsMappedShape(trafo, e_me, e_you)) + IdentifyEdges(e_me, e_you, name, type, opt_trafo); + } } void OCCParameters :: Print(ostream & ost) const diff --git a/libsrc/occ/occgeom.hpp b/libsrc/occ/occgeom.hpp index 27eae5b7..790d9727 100644 --- a/libsrc/occ/occgeom.hpp +++ b/libsrc/occ/occgeom.hpp @@ -341,8 +341,8 @@ namespace netgen bool ErrorInSurfaceMeshing (); // void WriteOCC_STL(char * filename); - static void IdentifyEdges(const TopoDS_Shape & me, const TopoDS_Shape & you, string name, Identifications::ID_TYPE type); - static void IdentifyFaces(const TopoDS_Shape & solid,const TopoDS_Shape & me, const TopoDS_Shape & you, string name, Identifications::ID_TYPE type); + static void IdentifyEdges(const TopoDS_Shape & me, const TopoDS_Shape & you, string name, Identifications::ID_TYPE type, std::optional opt_trafo = nullopt); + static void IdentifyFaces(const TopoDS_Shape & solid,const TopoDS_Shape & me, const TopoDS_Shape & you, string name, Identifications::ID_TYPE type, std::optional opt_trafo = nullopt); private: //bool FastProject (int surfi, Point<3> & ap, double& u, double& v) const; diff --git a/libsrc/occ/python_occ_shapes.cpp b/libsrc/occ/python_occ_shapes.cpp index e52d270b..bf4d90ab 100644 --- a/libsrc/occ/python_occ_shapes.cpp +++ b/libsrc/occ/python_occ_shapes.cpp @@ -1091,7 +1091,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) }, py::arg("other"), py::arg("name"), py::arg("type")=Identifications::PERIODIC, "Identify shapes for periodic meshing") .def("Identify", OCCGeometry::IdentifyFaces, "Identify faces", - py::arg("from"), py::arg("to"), py::arg("name"), py::arg("type")=Identifications::PERIODIC) + py::arg("from"), py::arg("to"), py::arg("name"), py::arg("type")=Identifications::PERIODIC, py::arg("trafo")=nullopt) .def("Distance", [](const TopoDS_Shape& self, const TopoDS_Shape& other)