mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-25 21:40:33 +05:00
Map identification trafo when transforming occ shapes
also propagate properties in gp_Trsf.__call__()
This commit is contained in:
parent
00e6d1d077
commit
fe8c036204
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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'")
|
||||
|
Loading…
Reference in New Issue
Block a user