mirror of
https://github.com/NGSolve/netgen.git
synced 2025-01-13 14:40:35 +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
|
#ifdef OCCGEOMETRY
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include <meshing.hpp>
|
#include <meshing.hpp>
|
||||||
#include "occ_utils.hpp"
|
#include "occ_utils.hpp"
|
||||||
#include "occmeshsurf.hpp"
|
#include "occmeshsurf.hpp"
|
||||||
@ -367,6 +369,105 @@ namespace netgen
|
|||||||
const MeshingParameters & mparam, int nr, int projecttype, bool delete_on_failure);
|
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
|
namespace step_utils
|
||||||
{
|
{
|
||||||
inline Handle(TCollection_HAsciiString) MakeName (string s)
|
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")
|
py::class_<gp_Trsf>(m, "gp_Trsf")
|
||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
.def("SetMirror", [] (gp_Trsf & trafo, const gp_Ax1 & ax) { trafo.SetMirror(ax); return trafo; })
|
.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("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("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; })
|
.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; })
|
{ gp_Trsf trafo; trafo.SetTransformation(from, to); return trafo; })
|
||||||
.def(py::self * py::self)
|
.def(py::self * py::self)
|
||||||
.def("__call__", [] (gp_Trsf & trafo, const TopoDS_Shape & shape) {
|
.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)
|
.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>
|
class WorkPlane : public enable_shared_from_this<WorkPlane>
|
||||||
{
|
{
|
||||||
@ -740,7 +654,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
gp_Trsf trafo;
|
gp_Trsf trafo;
|
||||||
trafo.SetTranslation(v);
|
trafo.SetTranslation(v);
|
||||||
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
||||||
PropagateProperties(builder, shape);
|
PropagateProperties(builder, shape, occ2ng(trafo));
|
||||||
return builder.Shape();
|
return builder.Shape();
|
||||||
// version 2: change location
|
// version 2: change location
|
||||||
// ...
|
// ...
|
||||||
@ -752,7 +666,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
gp_Trsf trafo;
|
gp_Trsf trafo;
|
||||||
trafo.SetRotation(ax, ang*M_PI/180);
|
trafo.SetRotation(ax, ang*M_PI/180);
|
||||||
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
||||||
PropagateProperties(builder, shape);
|
PropagateProperties(builder, shape, occ2ng(trafo));
|
||||||
return builder.Shape();
|
return builder.Shape();
|
||||||
}, py::arg("axis"), py::arg("ang"),
|
}, py::arg("axis"), py::arg("ang"),
|
||||||
"copy shape, and rotet copy by 'ang' degrees around 'axis'")
|
"copy shape, and rotet copy by 'ang' degrees around 'axis'")
|
||||||
@ -762,7 +676,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
gp_Trsf trafo;
|
gp_Trsf trafo;
|
||||||
trafo.SetMirror(ax.Ax2());
|
trafo.SetMirror(ax.Ax2());
|
||||||
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
||||||
PropagateProperties(builder, shape);
|
PropagateProperties(builder, shape, occ2ng(trafo));
|
||||||
return builder.Shape();
|
return builder.Shape();
|
||||||
}, py::arg("axes"),
|
}, py::arg("axes"),
|
||||||
"copy shape, and mirror over plane defined by 'axes'")
|
"copy shape, and mirror over plane defined by 'axes'")
|
||||||
@ -772,7 +686,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
gp_Trsf trafo;
|
gp_Trsf trafo;
|
||||||
trafo.SetMirror(ax);
|
trafo.SetMirror(ax);
|
||||||
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
||||||
PropagateProperties(builder, shape);
|
PropagateProperties(builder, shape, occ2ng(trafo));
|
||||||
return builder.Shape();
|
return builder.Shape();
|
||||||
}, py::arg("axes"),
|
}, py::arg("axes"),
|
||||||
"copy shape, and mirror around axis 'axis'")
|
"copy shape, and mirror around axis 'axis'")
|
||||||
@ -782,7 +696,7 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
gp_Trsf trafo;
|
gp_Trsf trafo;
|
||||||
trafo.SetScale(p, s);
|
trafo.SetScale(p, s);
|
||||||
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
BRepBuilderAPI_Transform builder(shape, trafo, true);
|
||||||
PropagateProperties(builder, shape);
|
PropagateProperties(builder, shape, occ2ng(trafo));
|
||||||
return builder.Shape();
|
return builder.Shape();
|
||||||
}, py::arg("p"), py::arg("s"),
|
}, py::arg("p"), py::arg("s"),
|
||||||
"copy shape, and scale copy by factor 's'")
|
"copy shape, and scale copy by factor 's'")
|
||||||
|
Loading…
Reference in New Issue
Block a user