From 2dc506fcfd13b9109980c738885aa21eb35a0eaf Mon Sep 17 00:00:00 2001 From: Joachim Schoeberl Date: Tue, 24 Aug 2021 10:13:18 +0200 Subject: [PATCH] Interval selectors (draft) --- libsrc/occ/python_occ.hpp | 69 ++++++++++++++++++++++++++++++++ libsrc/occ/python_occ_basic.cpp | 54 ++++++++++++++++++++++++- libsrc/occ/python_occ_shapes.cpp | 42 +++++++++++++++---- 3 files changed, 156 insertions(+), 9 deletions(-) create mode 100644 libsrc/occ/python_occ.hpp diff --git a/libsrc/occ/python_occ.hpp b/libsrc/occ/python_occ.hpp new file mode 100644 index 00000000..55c6a16c --- /dev/null +++ b/libsrc/occ/python_occ.hpp @@ -0,0 +1,69 @@ +class DirectionalInterval +{ +public: + gp_Vec dir; + double minval = -1e99; + double maxval = 1e99; + bool openmin = false, openmax = false; + + DirectionalInterval (gp_Vec adir) : dir(adir) { ; } + DirectionalInterval (const DirectionalInterval & i2) + : dir(i2.dir), minval(i2.minval), maxval(i2.maxval) { ; } + + DirectionalInterval operator< (double val) const + { + cout << "create interval with < " << ", val = " << val << endl; + cout << "me = " << this->minval << " - " << this->maxval << endl; + DirectionalInterval i2 = *this; + i2.maxval = val; + + cout << "resulting i = " << i2.minval << " - " << i2.maxval << endl; + return i2; + } + + DirectionalInterval operator> (double val) const + { + cout << "create interval with > " << ", val = " << val << endl; + cout << "me = " << this->minval << " - " << this->maxval << endl; + + DirectionalInterval i2 = *this; + i2.minval = val; + cout << "resulting i = " << i2.minval << " - " << i2.maxval << endl; + + return i2; + } + + + bool Contains (gp_Pnt p, double eps = 1e-8) + { + // cout << "Contains point " << p.X() << "," << p.Y() << "," << p.Z() << " ? " << endl; + double val = dir.X()*p.X() + dir.Y()*p.Y() + dir.Z() * p.Z(); + // cout << "minval = " << minval << ", val = " << val << " maxval = " << maxval << endl; + if (openmin) { + if (val < minval+eps) return false; + } else { + if (val < minval-eps) return false; + } + if (openmax) { + if (val > maxval-eps) return false; + } else { + if (val > maxval+eps) return false; + } + return true; + } +}; + + +inline gp_Pnt Center (TopoDS_Shape shape) +{ + GProp_GProps props; + switch (shape.ShapeType()) + { + case TopAbs_FACE: + BRepGProp::SurfaceProperties (shape, props); break; + default: + BRepGProp::LinearProperties(shape, props); + } + return props.CentreOfMass(); +} + diff --git a/libsrc/occ/python_occ_basic.cpp b/libsrc/occ/python_occ_basic.cpp index abc1686b..0d6f31e9 100644 --- a/libsrc/occ/python_occ_basic.cpp +++ b/libsrc/occ/python_occ_basic.cpp @@ -44,6 +44,9 @@ #include #include +#include + + #if OCC_VERSION_MAJOR>=7 && OCC_VERSION_MINOR>=4 #define OCC_HAVE_DUMP_JSON #endif @@ -115,7 +118,18 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m) .def("__sub__", [](gp_Vec v1, gp_Vec v2) { return v1-v2; }) .def("__rmul__", [](gp_Vec v, double s) { return s*v; }) .def("__neg__", [](gp_Vec v) { return -v; }) - .def("__xor__", [](gp_Vec v1, gp_Vec v2) { return v1^v2; }) + .def("__xor__", [](gp_Vec v1, gp_Vec v2) { return v1^v2; }) + + .def("__lt__", [](gp_Vec v, double val) + { + cout << "vec, lt v - " << netgen::occ2ng(v) << ", val = " << val << endl; + return DirectionalInterval(v) < val; + }) + .def("__gt__", [](gp_Vec v, double val) + { + cout << "vec, gt v - " << netgen::occ2ng(v) << ", val = " << val << endl; + return DirectionalInterval(v) > val; + }) ; py::class_(m, "gp_Dir") @@ -242,6 +256,30 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m) throw Exception("OCC-Points only in 2D or 3D"); }); + m.def("Vec", [](double x, double y) { return gp_Vec2d(x,y); }); + m.def("Vec", [](double x, double y, double z) { return gp_Vec(x,y,z); }); + m.def("Vec", [](std::vector p) + { + if (p.size() == 2) + return py::cast(gp_Vec2d(p[0], p[1])); + if (p.size() == 3) + return py::cast(gp_Vec(p[0], p[1], p[2])); + throw Exception("OCC-Vecs only in 2D or 3D"); + }); + + m.def("Dir", [](double x, double y) { return gp_Dir2d(x,y); }); + m.def("Dir", [](double x, double y, double z) { return gp_Dir(x,y,z); }); + m.def("Dir", [](std::vector p) + { + if (p.size() == 2) + return py::cast(gp_Dir2d(p[0], p[1])); + if (p.size() == 3) + return py::cast(gp_Dir(p[0], p[1], p[2])); + throw Exception("OCC-Dirs only in 2D or 3D"); + }); + + + py::class_(m, "gp_Ax2d") .def(py::init([](gp_Pnt2d p, gp_Dir2d d) { @@ -281,6 +319,20 @@ DLL_HEADER void ExportNgOCCBasic(py::module &m) .def("Transformation", [](const TopLoc_Location & loc) { return loc.Transformation(); }) ; + + py::class_ (m, "DirectionalInterval") + .def("__lt__", [](DirectionalInterval i, double val) + { + cout << "directionalinterval, lt, imin/max = " << i.minval << " / " << i.maxval << endl; + return i < val; + }) + .def("__gt__", [](DirectionalInterval i, double val) + { + cout << "directionalinterval, gt, imin/max = " << i.minval << " / " << i.maxval << endl; + return i > val; + }) + ; + py::implicitly_convertible(); py::implicitly_convertible(); py::implicitly_convertible(); diff --git a/libsrc/occ/python_occ_shapes.cpp b/libsrc/occ/python_occ_shapes.cpp index 2196ced1..3f55f8a5 100644 --- a/libsrc/occ/python_occ_shapes.cpp +++ b/libsrc/occ/python_occ_shapes.cpp @@ -56,6 +56,8 @@ #include #include +#include + #if OCC_VERSION_MAJOR>=7 && OCC_VERSION_MINOR>=4 #define OCC_HAVE_DUMP_JSON #endif @@ -683,6 +685,17 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) return BRepBuilderAPI_Transform(shape, trafo).Shape(); }) + .def("Scale", [](const TopoDS_Shape & shape, const gp_Pnt p, double s) + { + // which one to choose ? + // version 1: Transoformation + gp_Trsf trafo; + trafo.SetScale(p, s); + return BRepBuilderAPI_Transform(shape, trafo).Shape(); + // version 2: change location + // ... + }, py::arg("p"), py::arg("s")) + .def("bc", [](const TopoDS_Shape & shape, const string & name) { for (TopExp_Explorer e(shape, TopAbs_FACE); e.More(); e.Next()) @@ -861,14 +874,18 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) } throw Exception("no face found for extrusion"); }) - - .def("Revolve", [](const TopoDS_Shape & shape, const gp_Ax1 &A, const double D) { - for (TopExp_Explorer e(shape, TopAbs_FACE); e.More(); e.Next()) - { - return BRepPrimAPI_MakeRevol (shape, A, D*M_PI/180).Shape(); - } - throw Exception("no face found for revolve"); + + .def("Extrude", [] (const TopoDS_Shape & face, gp_Vec vec) { + return BRepPrimAPI_MakePrism (face, vec).Shape(); }) + + .def("Revolve", [](const TopoDS_Shape & shape, const gp_Ax1 &A, const double D) { + for (TopExp_Explorer e(shape, TopAbs_FACE); e.More(); e.Next()) + { + return BRepPrimAPI_MakeRevol (shape, A, D*M_PI/180).Shape(); + } + throw Exception("no face found for revolve"); + }) .def("Find", [](const TopoDS_Shape & shape, gp_Pnt p) { @@ -1298,7 +1315,16 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m) selected.push_back(s); return selected; }) - + + .def("__getitem__",[](const ListOfShapes & self, DirectionalInterval interval) + { + ListOfShapes selected; + for (auto s : self) + if (interval.Contains(Center(s))) + selected.push_back(s); + return selected; + }) + .def("Sorted",[](ListOfShapes self, gp_Vec dir) { std::map sortval;