Path: add option to use pybind11 instead of boost-python for libarea
This commit is contained in:
@@ -11,27 +11,33 @@ endif(MSVC)
|
||||
include_directories(${PYTHON_INCLUDE_DIRS})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(NOT FREECAD_LIBPACK_USE OR FREECAD_LIBPACK_CHECKFILE_CLBUNDLER)
|
||||
if(NOT PYTHON_VERSION_MAJOR LESS 3)
|
||||
find_package( Boost COMPONENTS python3)
|
||||
if (NOT Boost_PYTHON3_FOUND)
|
||||
find_package( Boost COMPONENTS python REQUIRED)
|
||||
|
||||
OPTION(USE_BOOST_PYTHON "use BOOST_PYTHON, otherwise use PYBIND11" ON)
|
||||
|
||||
if(USE_BOOST_PYTHON)
|
||||
if(NOT FREECAD_LIBPACK_USE OR FREECAD_LIBPACK_CHECKFILE_CLBUNDLER)
|
||||
if(NOT PYTHON_VERSION_MAJOR LESS 3)
|
||||
find_package( Boost COMPONENTS python3)
|
||||
if (NOT Boost_PYTHON3_FOUND)
|
||||
find_package( Boost COMPONENTS python REQUIRED)
|
||||
endif()
|
||||
else()
|
||||
find_package( Boost COMPONENTS python REQUIRED) # find BOOST and boost-python
|
||||
endif()
|
||||
|
||||
if(Boost_FOUND)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
MESSAGE(STATUS "found Boost: " ${Boost_LIB_VERSION})
|
||||
MESSAGE(STATUS "boost-incude dirs are: " ${Boost_INCLUDE_DIRS})
|
||||
MESSAGE(STATUS "boost-python lib is: " ${Boost_PYTHON_LIBRARY})
|
||||
MESSAGE(STATUS "boost_LIBRARY_DIRS is: " ${Boost_LIBRARY_DIRS})
|
||||
MESSAGE(STATUS "Boost_LIBRARIES is: " ${Boost_LIBRARIES})
|
||||
endif()
|
||||
else()
|
||||
find_package( Boost COMPONENTS python REQUIRED) # find BOOST and boost-python
|
||||
endif()
|
||||
|
||||
if(Boost_FOUND)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
MESSAGE(STATUS "found Boost: " ${Boost_LIB_VERSION})
|
||||
MESSAGE(STATUS "boost-incude dirs are: " ${Boost_INCLUDE_DIRS})
|
||||
MESSAGE(STATUS "boost-python lib is: " ${Boost_PYTHON_LIBRARY})
|
||||
MESSAGE(STATUS "boost_LIBRARY_DIRS is: " ${Boost_LIBRARY_DIRS})
|
||||
MESSAGE(STATUS "Boost_LIBRARIES is: " ${Boost_LIBRARIES})
|
||||
endif()
|
||||
else()
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
endif()
|
||||
endif(USE_BOOST_PYTHON)
|
||||
|
||||
|
||||
# this defines the source-files for library
|
||||
set(AREA_SRC_COMMON
|
||||
@@ -56,9 +62,15 @@ set(AREA_SRC_CLIPPER
|
||||
)
|
||||
|
||||
# this defines the additional source-files for python module (wrapper to libarea)
|
||||
set(PYAREA_SRC
|
||||
PythonStuff.cpp
|
||||
)
|
||||
if (USE_BOOST_PYTHON)
|
||||
set(PYAREA_SRC
|
||||
PythonStuff.cpp
|
||||
)
|
||||
else(USE_BOOST_PYTHON)
|
||||
set(PYAREA_SRC
|
||||
pyarea.cpp
|
||||
)
|
||||
endif(USE_BOOST_PYTHON)
|
||||
|
||||
# this defines the headers
|
||||
if(DEFINED INCLUDE_INSTALL_DIR)
|
||||
|
||||
360
src/Mod/Path/libarea/pyarea.cpp
Normal file
360
src/Mod/Path/libarea/pyarea.cpp
Normal file
@@ -0,0 +1,360 @@
|
||||
// pyarea.cpp
|
||||
// Copyright 2017, Lorenz Lechner
|
||||
// This program is released under the BSD license. See the file COPYING for details.
|
||||
|
||||
#include "Area.h"
|
||||
#include "Point.h"
|
||||
#include "AreaDxf.h"
|
||||
#include "kurve/geometry.h"
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/operators.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
|
||||
std::list<CVertex> getVertices(const CCurve& curve) {
|
||||
return curve.m_vertices;
|
||||
}
|
||||
|
||||
std::list<CCurve> getCurves(const CArea& area) {
|
||||
return area.m_curves;
|
||||
}
|
||||
|
||||
py::tuple transformed_point(const geoff_geometry::Matrix &matrix, double x, double y, double z)
|
||||
{
|
||||
geoff_geometry::Point3d p(x,y,z);
|
||||
p = p.Transform(matrix);
|
||||
|
||||
return py::make_tuple(p.x,p.y,p.z);
|
||||
}
|
||||
|
||||
static void print_curve(const CCurve& c)
|
||||
{
|
||||
std::size_t nvertices = c.m_vertices.size();
|
||||
#if defined SIZEOF_SIZE_T && SIZEOF_SIZE_T == 4
|
||||
printf("number of vertices = %d\n", nvertices);
|
||||
#else
|
||||
printf("number of vertices = %lu\n", nvertices);
|
||||
#endif
|
||||
int i = 0;
|
||||
for(std::list<CVertex>::const_iterator It = c.m_vertices.begin(); It != c.m_vertices.end(); It++, i++)
|
||||
{
|
||||
const CVertex& vertex = *It;
|
||||
printf("vertex %d type = %d, x = %g, y = %g", i+1, vertex.m_type, vertex.m_p.x / CArea::get_units(), vertex.m_p.y / CArea::get_units());
|
||||
if(vertex.m_type)printf(", xc = %g, yc = %g", vertex.m_c.x / CArea::get_units(), vertex.m_c.y / CArea::get_units());
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void print_area(const CArea &a)
|
||||
{
|
||||
for(std::list<CCurve>::const_iterator It = a.m_curves.begin(); It != a.m_curves.end(); It++)
|
||||
{
|
||||
const CCurve& curve = *It;
|
||||
print_curve(curve);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int num_vertices(const CCurve& curve)
|
||||
{
|
||||
return static_cast<unsigned int>(curve.m_vertices.size());
|
||||
}
|
||||
|
||||
static CVertex FirstVertex(const CCurve& curve)
|
||||
{
|
||||
return curve.m_vertices.front();
|
||||
}
|
||||
|
||||
static CVertex LastVertex(const CCurve& curve)
|
||||
{
|
||||
return curve.m_vertices.back();
|
||||
}
|
||||
|
||||
static void set_units(double units)
|
||||
{
|
||||
CArea::set_units(units);
|
||||
}
|
||||
|
||||
static double get_units()
|
||||
{
|
||||
return CArea::get_units();
|
||||
}
|
||||
|
||||
static bool holes_linked()
|
||||
{
|
||||
return CArea::HolesLinked();
|
||||
}
|
||||
|
||||
static CArea AreaFromDxf(const char* filepath)
|
||||
{
|
||||
CArea area;
|
||||
AreaDxfRead dxf(&area, filepath);
|
||||
dxf.DoRead();
|
||||
return area;
|
||||
}
|
||||
|
||||
static void append_point(CCurve& c, const Point& p)
|
||||
{
|
||||
c.m_vertices.push_back(CVertex(p));
|
||||
}
|
||||
|
||||
static py::tuple nearest_point_to_curve(CCurve& c1, const CCurve& c2)
|
||||
{
|
||||
double dist;
|
||||
Point p = c1.NearestPoint(c2, &dist);
|
||||
|
||||
return py::make_tuple(p, dist);
|
||||
}
|
||||
|
||||
std::list<CCurve> MakePocketToolpath(const CArea& a, double tool_radius, double extra_offset, double stepover, bool from_center, bool use_zig_zag, double zig_angle)
|
||||
{
|
||||
std::list<CCurve> toolpath;
|
||||
|
||||
CAreaPocketParams params(tool_radius, extra_offset, stepover, from_center, use_zig_zag ? ZigZagPocketMode : SpiralPocketMode, zig_angle);
|
||||
a.SplitAndMakePocketToolpath(toolpath, params);
|
||||
|
||||
return toolpath;
|
||||
}
|
||||
|
||||
std::list<CArea> SplitArea(const CArea& a)
|
||||
{
|
||||
std::list<CArea> areas;
|
||||
a.Split(areas);
|
||||
|
||||
return areas;
|
||||
}
|
||||
|
||||
void dxfArea(CArea& area, const char* /*str*/)
|
||||
{
|
||||
area = CArea();
|
||||
}
|
||||
|
||||
py::list getCurveSpans(const CCurve& c)
|
||||
{
|
||||
py::list span_list;
|
||||
const Point *prev_p = NULL;
|
||||
|
||||
for(std::list<CVertex>::const_iterator VIt = c.m_vertices.begin(); VIt != c.m_vertices.end(); VIt++)
|
||||
{
|
||||
const CVertex& vertex = *VIt;
|
||||
|
||||
if(prev_p)
|
||||
{
|
||||
span_list.append(Span(*prev_p, vertex));
|
||||
}
|
||||
prev_p = &(vertex.m_p);
|
||||
}
|
||||
|
||||
return span_list;
|
||||
}
|
||||
|
||||
Span getFirstCurveSpan(const CCurve& c)
|
||||
{
|
||||
if(c.m_vertices.size() < 2)return Span();
|
||||
|
||||
std::list<CVertex>::const_iterator VIt = c.m_vertices.begin();
|
||||
const Point &p = (*VIt).m_p;
|
||||
VIt++;
|
||||
return Span(p, *VIt, true);
|
||||
}
|
||||
|
||||
Span getLastCurveSpan(const CCurve& c)
|
||||
{
|
||||
if(c.m_vertices.size() < 2)return Span();
|
||||
|
||||
std::list<CVertex>::const_reverse_iterator VIt = c.m_vertices.rbegin();
|
||||
const CVertex &v = (*VIt);
|
||||
VIt++;
|
||||
|
||||
return Span((*VIt).m_p, v, c.m_vertices.size() == 2);
|
||||
}
|
||||
|
||||
py::tuple TangentialArc(const Point &p0, const Point &p1, const Point &v0)
|
||||
{
|
||||
Point c;
|
||||
int dir;
|
||||
tangential_arc(p0, p1, v0, c, dir);
|
||||
|
||||
return py::make_tuple(c, dir);
|
||||
}
|
||||
|
||||
std::list<Point> spanIntersect(const Span& span1, const Span& span2) {
|
||||
std::list<Point> pts;
|
||||
span1.Intersect(span2, pts);
|
||||
return pts;
|
||||
}
|
||||
|
||||
|
||||
void MatrixFromVector(geoff_geometry::Matrix& instance, std::vector<double> v){
|
||||
double array[16];
|
||||
int i = 0;
|
||||
for (double vi: v){
|
||||
array[i] = vi;
|
||||
i++;
|
||||
if(i>=16) break;
|
||||
}
|
||||
new (&instance) geoff_geometry::Matrix(array);
|
||||
}
|
||||
|
||||
std::list<CCurve> InsideCurves(const CArea& a, const CCurve& curve) {
|
||||
std::list<CCurve> curves_inside;
|
||||
a.InsideCurves(curve, curves_inside);
|
||||
return curves_inside;
|
||||
}
|
||||
|
||||
std::list<Point> CurveIntersections(const CCurve& c1, const CCurve& c2) {
|
||||
std::list<Point> pts;
|
||||
c1.CurveIntersections(c2, pts);
|
||||
return pts;
|
||||
}
|
||||
|
||||
std::list<Point> AreaIntersections(const CArea& a, const CCurve& c2) {
|
||||
std::list<Point> pts;
|
||||
a.CurveIntersections(c2, pts);
|
||||
return pts;
|
||||
}
|
||||
|
||||
double AreaGetArea(const CArea& a)
|
||||
{
|
||||
return a.GetArea();
|
||||
}
|
||||
|
||||
|
||||
void init_pyarea(py::module &m){
|
||||
py::class_<Point>(m, "Point")
|
||||
.def(py::init<double, double>())
|
||||
.def(py::init<Point>())
|
||||
.def(float() * py::self)
|
||||
.def(py::self * float())
|
||||
.def(py::self / float())
|
||||
.def(py::self * py::self)
|
||||
.def(py::self - py::self)
|
||||
.def(py::self + py::self)
|
||||
.def(py::self ^ py::self)
|
||||
.def(py::self == py::self)
|
||||
.def(py::self != py::self)
|
||||
.def(-py::self)
|
||||
.def(~py::self)
|
||||
.def("dist", &Point::dist)
|
||||
.def("length", &Point::length)
|
||||
.def("normalize", &Point::normalize)
|
||||
.def("Rotate", static_cast< void (Point::*)(double, double) >(&Point::Rotate))
|
||||
.def("Rotate", static_cast< void (Point::*)(double) >(&Point::Rotate))
|
||||
.def_readwrite("x", &Point::x)
|
||||
.def_readwrite("y", &Point::y)
|
||||
.def("Transform", &Point::Transform)
|
||||
;
|
||||
|
||||
py::class_<CVertex>(m, "Vertex")
|
||||
.def(py::init<CVertex>())
|
||||
.def(py::init<int, Point, Point>())
|
||||
.def(py::init<Point>())
|
||||
.def(py::init<int, Point, Point, int>())
|
||||
.def_readwrite("type", &CVertex::m_type)
|
||||
.def_readwrite("p", &CVertex::m_p)
|
||||
.def_readwrite("c", &CVertex::m_c)
|
||||
.def_readwrite("user_data", &CVertex::m_user_data)
|
||||
;
|
||||
|
||||
py::class_<Span>(m, "Span")
|
||||
.def(py::init<Span>())
|
||||
.def(py::init<Point, CVertex, bool>())
|
||||
.def("NearestPoint", static_cast< Point (Span::*)(const Point& p)const >(&Span::NearestPoint))
|
||||
.def("NearestPoint", static_cast< Point (Span::*)(const Span& p, double *d)const >(&Span::NearestPoint))
|
||||
.def("GetBox", &Span::GetBox)
|
||||
.def("IncludedAngle", &Span::IncludedAngle)
|
||||
.def("GetArea", &Span::GetArea)
|
||||
.def("On", &Span::On)
|
||||
.def("MidPerim", &Span::MidPerim)
|
||||
.def("MidParam", &Span::MidParam)
|
||||
.def("Length", &Span::Length)
|
||||
.def("GetVector", &Span::GetVector)
|
||||
.def("Intersect", &spanIntersect)
|
||||
.def_readwrite("p", &Span::m_p)
|
||||
.def_readwrite("v", &Span::m_v)
|
||||
;
|
||||
|
||||
py::class_<CCurve>(m, "Curve")
|
||||
.def(py::init<CCurve>())
|
||||
.def("getVertices", &getVertices)
|
||||
.def("append",&CCurve::append)
|
||||
.def("append",&append_point)
|
||||
.def("text", &print_curve)
|
||||
.def("NearestPoint", static_cast< Point (CCurve::*)(const Point& p)const >(&CCurve::NearestPoint))
|
||||
.def("NearestPoint", &nearest_point_to_curve)
|
||||
.def("Reverse", &CCurve::Reverse)
|
||||
.def("getNumVertices", &num_vertices)
|
||||
.def("FirstVertex", &FirstVertex)
|
||||
.def("LastVertex", &LastVertex)
|
||||
.def("GetArea", &CCurve::GetArea)
|
||||
.def("IsClockwise", &CCurve::IsClockwise)
|
||||
.def("IsClosed", &CCurve::IsClosed)
|
||||
.def("ChangeStart",&CCurve::ChangeStart)
|
||||
.def("ChangeEnd",&CCurve::ChangeEnd)
|
||||
.def("Offset",&CCurve::Offset)
|
||||
.def("OffsetForward",&CCurve::OffsetForward)
|
||||
.def("GetSpans",&getCurveSpans)
|
||||
.def("GetFirstSpan",&getFirstCurveSpan)
|
||||
.def("GetLastSpan",&getLastCurveSpan)
|
||||
.def("Break",&CCurve::Break)
|
||||
.def("Perim",&CCurve::Perim)
|
||||
.def("PerimToPoint",&CCurve::PerimToPoint)
|
||||
.def("PointToPerim",&CCurve::PointToPerim)
|
||||
.def("FitArcs",&CCurve::FitArcs)
|
||||
.def("UnFitArcs",&CCurve::UnFitArcs)
|
||||
.def("Intersections",&CurveIntersections)
|
||||
;
|
||||
|
||||
py::class_<CBox2D>(m, "Box")
|
||||
.def(py::init<CBox2D>())
|
||||
.def("MinX", &CBox2D::MinX)
|
||||
.def("MaxX", &CBox2D::MaxX)
|
||||
.def("MinY", &CBox2D::MinY)
|
||||
.def("MaxY", &CBox2D::MaxY)
|
||||
;
|
||||
|
||||
py::class_<CArea>(m, "Area")
|
||||
.def(py::init<CArea>())
|
||||
.def("getCurves", &getCurves)
|
||||
.def("append",&CArea::append)
|
||||
.def("Subtract",&CArea::Subtract)
|
||||
.def("Intersect",&CArea::Intersect)
|
||||
.def("Union",&CArea::Union)
|
||||
.def("Offset",&CArea::Offset)
|
||||
.def("FitArcs",&CArea::FitArcs)
|
||||
.def("text", &print_area)
|
||||
.def("num_curves", &CArea::num_curves)
|
||||
.def("NearestPoint", &CArea::NearestPoint)
|
||||
.def("GetBox", &CArea::GetBox)
|
||||
.def("Reorder", &CArea::Reorder)
|
||||
.def("MakePocketToolpath", &MakePocketToolpath)
|
||||
.def("Split", &SplitArea)
|
||||
.def("InsideCurves", &InsideCurves)
|
||||
.def("Thicken", &CArea::Thicken)
|
||||
.def("Intersections",&AreaIntersections)
|
||||
.def("GetArea",&AreaGetArea)
|
||||
;
|
||||
|
||||
py::class_<geoff_geometry::Matrix, std::shared_ptr<geoff_geometry::Matrix> > (m, "Matrix")
|
||||
.def(py::init<geoff_geometry::Matrix>())
|
||||
.def("__init__", &MatrixFromVector)
|
||||
.def("TransformedPoint", &transformed_point)
|
||||
.def("Multiply", &geoff_geometry::Matrix::Multiply)
|
||||
;
|
||||
|
||||
m.def("set_units", set_units);
|
||||
m.def("get_units", get_units);
|
||||
m.def("holes_linked", holes_linked);
|
||||
m.def("AreaFromDxf", AreaFromDxf);
|
||||
m.def("TangentialArc", TangentialArc);
|
||||
}
|
||||
|
||||
PYBIND11_PLUGIN(area){
|
||||
py::module m("area");
|
||||
init_pyarea(m);
|
||||
return m.ptr();
|
||||
};
|
||||
Reference in New Issue
Block a user