Map identification trafo when transforming occ shapes

also propagate properties in gp_Trsf.__call__()
This commit is contained in:
mhochsteger@cerbsim.com 2021-12-20 21:01:51 +01:00
parent 00e6d1d077
commit fe8c036204
3 changed files with 110 additions and 92 deletions

View File

@ -9,6 +9,8 @@
#ifdef OCCGEOMETRY
#include <set>
#include <meshing.hpp>
#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 <class TBuilder>
void PropagateIdentifications (TBuilder & builder, TopoDS_Shape shape, std::optional<Transformation<3>> trafo = nullopt)
{
std::map<T_Shape, std::set<T_Shape>> mod_map;
std::map<T_Shape, bool> 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 <class TBuilder>
void PropagateProperties (TBuilder & builder, TopoDS_Shape shape, std::optional<Transformation<3>> 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)

View File

@ -269,6 +269,7 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m)
py::class_<gp_Trsf>(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)
{

View File

@ -196,92 +196,6 @@ py::object CastShape(const TopoDS_Shape & s)
}
};
template <class TBuilder>
void PropagateIdentifications (TBuilder & builder, TopoDS_Shape shape)
{
std::map<T_Shape, std::set<T_Shape>> mod_map;
std::map<T_Shape, bool> 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 <class TBuilder>
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<WorkPlane>
{
@ -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'")