From fe8c036204e56767325a5c6eae9523218095dbd0 Mon Sep 17 00:00:00 2001 From: "mhochsteger@cerbsim.com" Date: Mon, 20 Dec 2021 21:01:51 +0100 Subject: [PATCH] Map identification trafo when transforming occ shapes also propagate properties in gp_Trsf.__call__() --- libsrc/occ/occgeom.hpp | 101 +++++++++++++++++++++++++++++++ libsrc/occ/python_occ_basic.cpp | 5 +- libsrc/occ/python_occ_shapes.cpp | 96 ++--------------------------- 3 files changed, 110 insertions(+), 92 deletions(-) diff --git a/libsrc/occ/occgeom.hpp b/libsrc/occ/occgeom.hpp index 0619cb97..ef46d86d 100644 --- a/libsrc/occ/occgeom.hpp +++ b/libsrc/occ/occgeom.hpp @@ -9,6 +9,8 @@ #ifdef OCCGEOMETRY +#include + #include #include "occ_utils.hpp" #include "occmeshsurf.hpp" @@ -367,6 +369,105 @@ namespace netgen const MeshingParameters & mparam, int nr, int projecttype, bool delete_on_failure); + template + void PropagateIdentifications (TBuilder & builder, TopoDS_Shape shape, std::optional> trafo = nullopt) + { + std::map> mod_map; + std::map tshape_handled; + Transformation<3> trafo_inv; + if(trafo) + trafo_inv = trafo->CalcInverse(); + + for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX }) + for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) + { + auto tshape = e.Current().TShape(); + mod_map[tshape].insert(tshape); + tshape_handled[tshape] = false; + } + + for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX }) + for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) + { + auto tshape = e.Current().TShape(); + + for (auto mods : builder.Modified(e.Current())) + mod_map[tshape].insert(mods.TShape()); + } + + for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX }) + for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) + { + auto tshape = e.Current().TShape(); + + if(tshape_handled[tshape]) + continue; + tshape_handled[tshape] = true; + + if(OCCGeometry::identifications.count(tshape)==0) + continue; + + auto tshape_mapped = mod_map[tshape]; + + for(auto ident : OCCGeometry::identifications[tshape]) + { + // nothing happened + if(mod_map[ident.to].size()==1 && mod_map[ident.from].size() ==1) + continue; + + auto from = ident.from; + auto to = ident.to; + + for(auto from_mapped : mod_map[from]) + for(auto to_mapped : mod_map[to]) + { + if(from==from_mapped && to==to_mapped) + continue; + + TopoDS_Shape s_from; s_from.TShape(from_mapped); + TopoDS_Shape s_to; s_to.TShape(to_mapped); + + Transformation<3> trafo_mapped; + if(trafo) + { + Transformation<3> trafo_temp; + trafo_temp.Combine(ident.trafo, trafo_inv); + trafo_mapped.Combine(*trafo, trafo_temp); + } + + if(!IsMappedShape(trafo_mapped, s_from, s_to)) + continue; + + OCCIdentification id_new = ident; + id_new.to = to_mapped; + id_new.from = from_mapped; + if(trafo) + id_new.trafo = trafo_mapped; + auto id_owner = from == tshape ? from_mapped : to_mapped; + OCCGeometry::identifications[id_owner].push_back(id_new); + } + } + } + } + + template + void PropagateProperties (TBuilder & builder, TopoDS_Shape shape, std::optional> trafo = nullopt) + { + bool have_identifications = false; + + for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE }) + for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) + { + auto tshape = e.Current().TShape(); + auto & prop = OCCGeometry::global_shape_properties[tshape]; + for (auto mods : builder.Modified(e.Current())) + OCCGeometry::global_shape_properties[mods.TShape()].Merge(prop); + have_identifications |= OCCGeometry::identifications.count(tshape) > 0; + } + if(have_identifications) + PropagateIdentifications(builder, shape, trafo); + } + namespace step_utils { inline Handle(TCollection_HAsciiString) MakeName (string s) diff --git a/libsrc/occ/python_occ_basic.cpp b/libsrc/occ/python_occ_basic.cpp index 3384e3ef..cdf338fe 100644 --- a/libsrc/occ/python_occ_basic.cpp +++ b/libsrc/occ/python_occ_basic.cpp @@ -269,6 +269,7 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m) py::class_(m, "gp_Trsf") .def(py::init<>()) .def("SetMirror", [] (gp_Trsf & trafo, const gp_Ax1 & ax) { trafo.SetMirror(ax); return trafo; }) + .def("Inverted", &gp_Trsf::Inverted) .def_static("Translation", [] (const gp_Vec & v) { gp_Trsf trafo; trafo.SetTranslation(v); return trafo; }) .def_static("Scale", [] (const gp_Pnt & p, double s) { gp_Trsf trafo; trafo.SetScale(p,s); return trafo; }) .def_static("Mirror", [] (const gp_Ax1 & ax) { gp_Trsf trafo; trafo.SetMirror(ax); return trafo; }) @@ -280,7 +281,9 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m) { gp_Trsf trafo; trafo.SetTransformation(from, to); return trafo; }) .def(py::self * py::self) .def("__call__", [] (gp_Trsf & trafo, const TopoDS_Shape & shape) { - return BRepBuilderAPI_Transform(shape, trafo, true).Shape(); + BRepBuilderAPI_Transform builder(shape, trafo, true); + PropagateProperties(builder, shape, occ2ng(trafo)); + return builder.Shape(); }) .def("__str__", [](gp_Trsf & trafo) { diff --git a/libsrc/occ/python_occ_shapes.cpp b/libsrc/occ/python_occ_shapes.cpp index 178dfbc5..b29fa0b2 100644 --- a/libsrc/occ/python_occ_shapes.cpp +++ b/libsrc/occ/python_occ_shapes.cpp @@ -196,92 +196,6 @@ py::object CastShape(const TopoDS_Shape & s) } }; -template -void PropagateIdentifications (TBuilder & builder, TopoDS_Shape shape) -{ - std::map> mod_map; - std::map tshape_handled; - - for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX }) - for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) - { - auto tshape = e.Current().TShape(); - mod_map[tshape].insert(tshape); - tshape_handled[tshape] = false; - } - - for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX }) - for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) - { - auto tshape = e.Current().TShape(); - - for (auto mods : builder.Modified(e.Current())) - mod_map[tshape].insert(mods.TShape()); - } - - for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX }) - for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) - { - auto tshape = e.Current().TShape(); - - if(tshape_handled[tshape]) - continue; - tshape_handled[tshape] = true; - - if(OCCGeometry::identifications.count(tshape)==0) - continue; - - auto tshape_mapped = mod_map[tshape]; - - for(auto ident : OCCGeometry::identifications[tshape]) - { - // nothing happened - if(mod_map[ident.to].size()==1 && mod_map[ident.from].size() ==1) - continue; - - auto from = ident.from; - auto to = ident.to; - - for(auto from_mapped : mod_map[from]) - for(auto to_mapped : mod_map[to]) - { - if(from==from_mapped && to==to_mapped) - continue; - - TopoDS_Shape s_from; s_from.TShape(from_mapped); - TopoDS_Shape s_to; s_to.TShape(to_mapped); - - if(!IsMappedShape(ident.trafo, s_from, s_to)) - continue; - - OCCIdentification id_new = ident; - id_new.to = to_mapped; - id_new.from = from_mapped; - auto id_owner = from == tshape ? from_mapped : to_mapped; - OCCGeometry::identifications[id_owner].push_back(id_new); - } - } - } -} - -template -void PropagateProperties (TBuilder & builder, TopoDS_Shape shape) -{ - bool have_identifications = false; - - for (auto typ : { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE }) - for (TopExp_Explorer e(shape, typ); e.More(); e.Next()) - { - auto tshape = e.Current().TShape(); - auto & prop = OCCGeometry::global_shape_properties[tshape]; - for (auto mods : builder.Modified(e.Current())) - OCCGeometry::global_shape_properties[mods.TShape()].Merge(prop); - have_identifications |= OCCGeometry::identifications.count(tshape) > 0; - } - if(have_identifications) - PropagateIdentifications(builder, shape); -} - class WorkPlane : public enable_shared_from_this { @@ -740,7 +654,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) gp_Trsf trafo; trafo.SetTranslation(v); BRepBuilderAPI_Transform builder(shape, trafo, true); - PropagateProperties(builder, shape); + PropagateProperties(builder, shape, occ2ng(trafo)); return builder.Shape(); // version 2: change location // ... @@ -752,7 +666,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) gp_Trsf trafo; trafo.SetRotation(ax, ang*M_PI/180); BRepBuilderAPI_Transform builder(shape, trafo, true); - PropagateProperties(builder, shape); + PropagateProperties(builder, shape, occ2ng(trafo)); return builder.Shape(); }, py::arg("axis"), py::arg("ang"), "copy shape, and rotet copy by 'ang' degrees around 'axis'") @@ -762,7 +676,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) gp_Trsf trafo; trafo.SetMirror(ax.Ax2()); BRepBuilderAPI_Transform builder(shape, trafo, true); - PropagateProperties(builder, shape); + PropagateProperties(builder, shape, occ2ng(trafo)); return builder.Shape(); }, py::arg("axes"), "copy shape, and mirror over plane defined by 'axes'") @@ -772,7 +686,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) gp_Trsf trafo; trafo.SetMirror(ax); BRepBuilderAPI_Transform builder(shape, trafo, true); - PropagateProperties(builder, shape); + PropagateProperties(builder, shape, occ2ng(trafo)); return builder.Shape(); }, py::arg("axes"), "copy shape, and mirror around axis 'axis'") @@ -782,7 +696,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) gp_Trsf trafo; trafo.SetScale(p, s); BRepBuilderAPI_Transform builder(shape, trafo, true); - PropagateProperties(builder, shape); + PropagateProperties(builder, shape, occ2ng(trafo)); return builder.Shape(); }, py::arg("p"), py::arg("s"), "copy shape, and scale copy by factor 's'")