diff options
Diffstat (limited to 'src/py2geom')
-rw-r--r-- | src/py2geom/CMakeLists.txt | 118 | ||||
-rw-r--r-- | src/py2geom/__init__.py | 26 | ||||
-rw-r--r-- | src/py2geom/bezier.cpp | 89 | ||||
-rw-r--r-- | src/py2geom/cairo-helpers.cpp | 164 | ||||
-rw-r--r-- | src/py2geom/cairo-helpers.h | 27 | ||||
-rw-r--r-- | src/py2geom/circle.cpp | 72 | ||||
-rw-r--r-- | src/py2geom/conic.cpp | 176 | ||||
-rw-r--r-- | src/py2geom/convexcover.cpp | 93 | ||||
-rw-r--r-- | src/py2geom/crossing.cpp | 69 | ||||
-rw-r--r-- | src/py2geom/d2.cpp | 99 | ||||
-rw-r--r-- | src/py2geom/ellipse.cpp | 88 | ||||
-rw-r--r-- | src/py2geom/etc.cpp | 66 | ||||
-rw-r--r-- | src/py2geom/helpers.h | 59 | ||||
-rw-r--r-- | src/py2geom/interval.cpp | 159 | ||||
-rw-r--r-- | src/py2geom/line.cpp | 96 | ||||
-rw-r--r-- | src/py2geom/linear.cpp | 110 | ||||
-rw-r--r-- | src/py2geom/parser.cpp | 85 | ||||
-rw-r--r-- | src/py2geom/path.cpp | 265 | ||||
-rw-r--r-- | src/py2geom/point.cpp | 146 | ||||
-rw-r--r-- | src/py2geom/pw.cpp | 228 | ||||
-rw-r--r-- | src/py2geom/py2geom.cpp | 85 | ||||
-rw-r--r-- | src/py2geom/py2geom.h | 71 | ||||
-rw-r--r-- | src/py2geom/ray.cpp | 99 | ||||
-rw-r--r-- | src/py2geom/rect.cpp | 125 | ||||
-rw-r--r-- | src/py2geom/sbasis.cpp | 173 | ||||
-rw-r--r-- | src/py2geom/transforms.cpp | 107 |
26 files changed, 2895 insertions, 0 deletions
diff --git a/src/py2geom/CMakeLists.txt b/src/py2geom/CMakeLists.txt new file mode 100644 index 0000000..8e21e74 --- /dev/null +++ b/src/py2geom/CMakeLists.txt @@ -0,0 +1,118 @@ +SET(2GEOM_BOOST_PYTHON_SRC +etc.cpp +point.cpp +interval.cpp +transforms.cpp +rect.cpp +line.cpp +circle.cpp +ellipse.cpp +conic.cpp +crossing.cpp +sbasis.cpp +bezier.cpp +linear.cpp +pw.cpp +d2.cpp +parser.cpp +path.cpp +ray.cpp +#convexcover.cpp +py2geom.cpp +# curves +#curve.cpp +#bezier-curve.cpp +) + +IF (WIN32) + SET(BUILD_BOOST_PYTHON_STATIC FALSE) +ELSE (WIN32) + SET(BUILD_BOOST_PYTHON_STATIC FALSE) +ENDIF (WIN32) +IF (BUILD_BOOST_PYTHON_STATIC) + SET(BOOST_PYTHON_SRC "C:/boost_1_42_0/libs/python/src") + #define BOOST_PYTHON_STATIC_LIB + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_PYTHON_STATIC_LIB") + SET(2GEOM_BOOST_PYTHON_SRC + ${2GEOM_BOOST_PYTHON_SRC} + ${BOOST_PYTHON_SRC}/dict.cpp + ${BOOST_PYTHON_SRC}/errors.cpp + ${BOOST_PYTHON_SRC}/exec.cpp + ${BOOST_PYTHON_SRC}/import.cpp + ${BOOST_PYTHON_SRC}/list.cpp + ${BOOST_PYTHON_SRC}/long.cpp + ${BOOST_PYTHON_SRC}/module.cpp + ${BOOST_PYTHON_SRC}/numeric.cpp + ${BOOST_PYTHON_SRC}/object_operators.cpp + ${BOOST_PYTHON_SRC}/object_protocol.cpp + ${BOOST_PYTHON_SRC}/slice.cpp + ${BOOST_PYTHON_SRC}/str.cpp + ${BOOST_PYTHON_SRC}/tuple.cpp + ${BOOST_PYTHON_SRC}/wrapper.cpp + + ${BOOST_PYTHON_SRC}/converter/arg_to_python_base.cpp + ${BOOST_PYTHON_SRC}/converter/builtin_converters.cpp + ${BOOST_PYTHON_SRC}/converter/from_python.cpp + ${BOOST_PYTHON_SRC}/converter/registry.cpp + ${BOOST_PYTHON_SRC}/converter/type_id.cpp + + ${BOOST_PYTHON_SRC}/object/class.cpp + ${BOOST_PYTHON_SRC}/object/enum.cpp + ${BOOST_PYTHON_SRC}/object/function.cpp + ${BOOST_PYTHON_SRC}/object/function_doc_signature.cpp + ${BOOST_PYTHON_SRC}/object/inheritance.cpp + ${BOOST_PYTHON_SRC}/object/iterator.cpp + ${BOOST_PYTHON_SRC}/object/life_support.cpp + ${BOOST_PYTHON_SRC}/object/pickle_support.cpp + ${BOOST_PYTHON_SRC}/object/stl_iterator.cpp + ) +ENDIF (BUILD_BOOST_PYTHON_STATIC) + +IF(PYCAIRO_FOUND) + SET(2GEOM_BOOST_PYTHON_SRC + ${2GEOM_BOOST_PYTHON_SRC} + cairo-helpers.cpp + ) +ENDIF(PYCAIRO_FOUND) + + +OPTION(2GEOM_BOOST_PYTHON + "Build a python binding with Boost.Python" + OFF) +IF(2GEOM_BOOST_PYTHON) + FIND_PACKAGE(Python3 COMPONENTS Development Interpreter REQUIRED) + + SET(Boost_DEBUG TRUE) + SET(Boost_REALPATH FALSE) + FIND_PACKAGE(Boost 1.42.0 REQUIRED) + FIND_PACKAGE(Boost REQUIRED COMPONENTS python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}) + + IF (WIN32) + SET_TARGET_PROPERTIES(py2geom PROPERTIES SUFFIX ".pyd") + ELSEIF (APPLE) + SET(CMAKE_MACOSX_RPATH FALSE) + SET(CMAKE_SHARED_LIBRARY_SUFFIX ".so") + ENDIF(WIN32) + + INCLUDE_DIRECTORIES( src/ ${Python3_INCLUDE_DIRS} ${Boost_INCLUDE_DIR} ) + ADD_LIBRARY(py2geom SHARED ${2GEOM_BOOST_PYTHON_SRC}) + SET_TARGET_PROPERTIES(py2geom PROPERTIES PREFIX "_") + + IF (BUILD_BOOST_PYTHON_STATIC) + TARGET_LINK_LIBRARIES(py2geom 2geom ${Python3_LIBRARIES}) + ELSE (BUILD_BOOST_PYTHON_STATIC) + TARGET_LINK_LIBRARIES(py2geom 2geom ${Boost_LIBRARIES} ${Python3_LIBRARIES}) + ENDIF (BUILD_BOOST_PYTHON_STATIC) + + set_property(TARGET 2geom PROPERTY POSITION_INDEPENDENT_CODE ON) # we need -fPIC to link py2geom against 2geom + + IF(PYCAIRO_FOUND) + TARGET_LINK_LIBRARIES(py2geom ${Cairo_LIBRARIES}) + ENDIF(PYCAIRO_FOUND) + + INSTALL(TARGETS py2geom DESTINATION "${Python3_SITEARCH}/py2geom") + INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/__init__.py" DESTINATION "${Python3_SITEARCH}/py2geom") +ENDIF(2GEOM_BOOST_PYTHON) + + + diff --git a/src/py2geom/__init__.py b/src/py2geom/__init__.py new file mode 100644 index 0000000..06faf3c --- /dev/null +++ b/src/py2geom/__init__.py @@ -0,0 +1,26 @@ +# Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> +# +# This library is free software; you can redistribute it and/or +# modify it either under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation +# (the "LGPL") or, at your option, under the terms of the Mozilla +# Public License Version 1.1 (the "MPL"). If you do not alter this +# notice, a recipient may use your version of this file under either +# the MPL or the LGPL. +# +# You should have received a copy of the LGPL along with this library +# in the file COPYING-LGPL-2.1; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the MPL along with this library +# in the file COPYING-MPL-1.1 +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY +# OF ANY KIND, either express or implied. See the LGPL or the MPL for +# the specific language governing rights and limitations. + +from py2geom._py2geom import * diff --git a/src/py2geom/bezier.cpp b/src/py2geom/bezier.cpp new file mode 100644 index 0000000..f0664c1 --- /dev/null +++ b/src/py2geom/bezier.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/bezier.h" +#include "2geom/point.h" + +using namespace boost::python; + +double bezier_getitem(Geom::Bezier const& p, int index) +{ + int D = p.size(); + if (index < 0) + { + index = D + index; + } + if ((index < 0) || (index > (D - 1))) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + boost::python::throw_error_already_set(); + } + return p[index]; +} + +void wrap_bezier() { + //bezier.h + + class_<Geom::Bezier>("Bezier", init<double>()) + .def(init<double, double>()) + .def(init<double, double, double>()) + .def(init<double, double, double, double>()) + .def(self_ns::str(self)) + //TODO: add important vector funcs + .def("__getitem__", &bezier_getitem) + + .def("isZero", &Geom::Bezier::isZero) + .def("isFinite", &Geom::Bezier::isFinite) + .def("at0", (double (Geom::Bezier::*)() const) &Geom::Bezier::at0) + .def("at1", (double (Geom::Bezier::*)() const) &Geom::Bezier::at1) + .def("valueAt", &Geom::Bezier::valueAt) + .def("toSBasis", &Geom::Bezier::toSBasis) + + .def(self + float()) + .def(self - float()) + + .def(self * float()) + ; +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/cairo-helpers.cpp b/src/py2geom/cairo-helpers.cpp new file mode 100644 index 0000000..c341439 --- /dev/null +++ b/src/py2geom/cairo-helpers.cpp @@ -0,0 +1,164 @@ +#include <boost/python.hpp> +#include <cairo.h> +#include <toys/path-cairo.h> +#include <2geom/sbasis-to-bezier.h> +#include <2geom/utils.h> +#include <sstream> +#include <pycairo/pycairo.h> +#include "cairo-helpers.h" + +using namespace Geom; + + +void +cairo_move_to (cairo_t *cr, Geom::Point p1) { + cairo_move_to(cr, p1[0], p1[1]); +} + +void +cairo_line_to (cairo_t *cr, Geom::Point p1) { + cairo_line_to(cr, p1[0], p1[1]); +} + +void +cairo_curve_to (cairo_t *cr, Geom::Point p1, + Geom::Point p2, Geom::Point p3) { + cairo_curve_to(cr, p1[0], p1[1], + p2[0], p2[1], + p3[0], p3[1]); +} + +void cairo_rectangle(cairo_t *cr, Rect const& r) { + cairo_rectangle(cr, r.left(), r.top(), r.width(), r.height()); +} + +void cairo_convex_hull(cairo_t *cr, ConvexHull const& ch) { + if(ch.empty()) return; + cairo_move_to(cr, ch.back()); + for(unsigned i = 0; i < ch.size(); i++) { + cairo_line_to(cr, ch[i]); + } +} + +void cairo_curve(cairo_t *cr, Curve const& c) { + if(LineSegment const* line_segment = dynamic_cast<LineSegment const*>(&c)) { + cairo_line_to(cr, (*line_segment)[1][0], (*line_segment)[1][1]); + } + else if(QuadraticBezier const *quadratic_bezier = dynamic_cast<QuadraticBezier const*>(&c)) { + std::vector<Point> points = quadratic_bezier->controlPoints(); + Point b1 = points[0] + (2./3) * (points[1] - points[0]); + Point b2 = b1 + (1./3) * (points[2] - points[0]); + cairo_curve_to(cr, b1[0], b1[1], + b2[0], b2[1], + points[2][0], points[2][1]); + } + else if(CubicBezier const *cubic_bezier = dynamic_cast<CubicBezier const*>(&c)) { + std::vector<Point> points = cubic_bezier->controlPoints(); + cairo_curve_to(cr, points[1][0], points[1][1], points[2][0], points[2][1], points[3][0], points[3][1]); + } +// else if(EllipticalArc const *svg_elliptical_arc = dynamic_cast<EllipticalArc *>(c)) { +// //TODO: get at the innards and spit them out to cairo +// } + else { + //this case handles sbasis as well as all other curve types + Path sbasis_path = cubicbezierpath_from_sbasis(c.toSBasis(), 0.1); + + //recurse to convert the new path resulting from the sbasis to svgd + for(Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) { + cairo_curve(cr, *iter); + } + } +} + +void cairo_path(cairo_t *cr, Path const &p) { + cairo_move_to(cr, p.initialPoint()[0], p.initialPoint()[1]); + if(p.size() == 0) { // naked moveto + cairo_move_to(cr, p.finalPoint()+Point(8,0)); + cairo_line_to(cr, p.finalPoint()+Point(-8,0)); + cairo_move_to(cr, p.finalPoint()+Point(0,8)); + cairo_line_to(cr, p.finalPoint()+Point(0,-8)); + return; + } + + for(Path::const_iterator iter(p.begin()), end(p.end()); iter != end; ++iter) { + cairo_curve(cr, *iter); + } + if(p.closed()) + cairo_close_path(cr); +} + +void cairo_path_stitches(cairo_t *cr, Path const &p) { + Path::const_iterator iter; + for ( iter = p.begin() ; iter != p.end() ; ++iter ) { + Curve const &c=*iter; + if (dynamic_cast<Path::StitchSegment const *>(&c)) { + cairo_move_to(cr, c.initialPoint()[X], c.initialPoint()[Y]); + cairo_line_to(cr, c.finalPoint()[X], c.finalPoint()[Y]); + + //std::stringstream s; + //s << L1(c.finalPoint() - c.initialPoint()); + //std::string ss = s.str(); + //draw_text(cr, c.initialPoint()+Point(5,5), ss.c_str(), false, "Serif 6"); + + //std::cout << c.finalPoint() - c.initialPoint() << std::endl; + } + } +} + +void cairo_path(cairo_t *cr, PathVector const &p) { + PathVector::const_iterator it; + for(it = p.begin(); it != p.end(); ++it) { + cairo_path(cr, *it); + } +} + +void cairo_path_stitches(cairo_t *cr, PathVector const &p) { + PathVector::const_iterator it; + for ( it = p.begin() ; it != p.end() ; ++it ) { + cairo_path_stitches(cr, *it); + } +} + + +void cairo_d2_sb(cairo_t *cr, D2<SBasis> const &B) { + cairo_path(cr, path_from_sbasis(B, 0.1)); +} + +void cairo_d2_pw_sb(cairo_t *cr, D2<Piecewise<SBasis> > const &p) { + cairo_pw_d2_sb(cr, sectionize(p)); +} + +void cairo_pw_d2_sb(cairo_t *cr, Piecewise<D2<SBasis> > const &p) { + for(unsigned i = 0; i < p.size(); i++) + cairo_d2_sb(cr, p[i]); +} + +#if PY_MAJOR_VERSION < 3 +static Pycairo_CAPI_t *Pycairo_CAPI = 0; +#endif + +cairo_t* cairo_t_from_object(boost::python::object cr) { +#if PY_MAJOR_VERSION < 3 + if(!Pycairo_CAPI) + Pycairo_IMPORT; +#else + import_cairo(); +#endif + PycairoContext* pcc = (PycairoContext*)cr.ptr(); + assert(PyObject_TypeCheck(pcc, &PycairoContext_Type)); + return PycairoContext_GET(pcc); +} + + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(substatement-open . 0)) + indent-tabs-mode:nil + c-brace-offset:0 + fill-column:99 + End: + vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +*/ diff --git a/src/py2geom/cairo-helpers.h b/src/py2geom/cairo-helpers.h new file mode 100644 index 0000000..daa2960 --- /dev/null +++ b/src/py2geom/cairo-helpers.h @@ -0,0 +1,27 @@ +#include <2geom/sbasis.h> +#include <2geom/sbasis-2d.h> +#include <2geom/d2.h> +#include <2geom/piecewise.h> +#include <2geom/path.h> +#include <2geom/convex-hull.h> +#include <vector> + +typedef struct _cairo cairo_t; + +void cairo_move_to(cairo_t *cr, Geom::Point p1); +void cairo_line_to(cairo_t *cr, Geom::Point p1); +void cairo_curve_to(cairo_t *cr, Geom::Point p1, Geom::Point p2, Geom::Point p3); + +void cairo_curve(cairo_t *cr, Geom::Curve const &c); +void cairo_rectangle(cairo_t *cr, Geom::Rect const &r); +void cairo_convex_hull(cairo_t *cr, Geom::ConvexHull const &r); +void cairo_path(cairo_t *cr, Geom::Path const &p); +void cairo_path(cairo_t *cr, Geom::PathVector const &p); +void cairo_path_stitches(cairo_t *cr, Geom::Path const &p); +void cairo_path_stitches(cairo_t *cr, Geom::PathVector const &p); + +void cairo_d2_sb(cairo_t *cr, Geom::D2<Geom::SBasis> const &p); +void cairo_d2_pw_sb(cairo_t *cr, Geom::D2<Geom::Piecewise<Geom::SBasis> > const &p); +void cairo_pw_d2_sb(cairo_t *cr, Geom::Piecewise<Geom::D2<Geom::SBasis> > const &p); + +cairo_t* cairo_t_from_object(boost::python::object cr); diff --git a/src/py2geom/circle.cpp b/src/py2geom/circle.cpp new file mode 100644 index 0000000..55e683b --- /dev/null +++ b/src/py2geom/circle.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 2009 Ricardo Lafuente <r@sollec.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/point.h" +#include "2geom/circle.h" +#include "2geom/exception.h" + +// i can't get these to work +//Geom::Point (Geom::Circle::*center_point)() = (Geom::Point (*)() const)&Geom::Circle::center; +//Geom::Coord (Geom::Circle::*center_coord)(Geom::Dim2 const& d) = &Geom::Circle::center; + +using namespace boost::python; + +void wrap_circle() { + + class_<Geom::Circle>("Circle", init<double, double, double>()) + .def(init<double, double, double, double>()) + + .def("setCoefficients", &Geom::Circle::setCoefficients) + .def("fit", &Geom::Circle::fit) + .add_property("radius", &Geom::Circle::radius) + + .add_property("center", (Geom::Point (Geom::Circle::*)() const )&Geom::Circle::center) + //.def("center", center) + // requires EllipticalArc + //.def("arc", &Geom::Circle::arc) + ; + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/conic.cpp b/src/py2geom/conic.cpp new file mode 100644 index 0000000..8e5360e --- /dev/null +++ b/src/py2geom/conic.cpp @@ -0,0 +1,176 @@ +/* + * Copyright 2009 Nathan Hurst <njh@njhurst.com> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> +#include <optional> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/point.h" +#include "2geom/line.h" +#include "2geom/conicsec.h" + +using namespace boost::python; + +// helpers for point +static tuple xAx_to_tuple(Geom::xAx const& a) +{ + return make_tuple(a.c[0], a.c[1], a.c[2], a.c[3], a.c[4], a.c[5]); +} + +static Geom::xAx tuple_to_xAx(boost::python::tuple const& t) +{ + return Geom::xAx(extract<double>(t[0]), + extract<double>(t[1]), + extract<double>(t[2]), + extract<double>(t[3]), + extract<double>(t[4]), + extract<double>(t[5]) + ); +} + +static std::vector<double> xax_roots1(Geom::xAx const & xax, Geom::Point const &a, Geom::Point const &b) { return xax.roots(a,b); } +static std::vector<double> xax_roots2(Geom::xAx const & xax, Geom::Line const &l) { return xax.roots(l); } +static Geom::SBasis homo_eval_at(Geom::xAx const & xax, + Geom::SBasis const & x, + Geom::SBasis const & y, + Geom::SBasis const & w + ) { + return xax.evaluate_at(x, y, w); +} + +static Geom::SBasis xy_eval_at(Geom::xAx const & xax, + Geom::SBasis const & x, + Geom::SBasis const & y + ) { + return xax.evaluate_at(x, y); +} + +static Geom::D2<Geom::SBasis> wrap_rq_to_cubic_sb(Geom::RatQuad const & rq) { + return rq.toCubic().toSBasis(); +} + +static Geom::D2<Geom::SBasis> wrap_rq_to_cubic_sb_l(Geom::RatQuad const & rq, double l) { + return rq.toCubic(l).toSBasis(); +} + +static std::vector<Geom::Point> wrap_rq_to_cubic_l(Geom::RatQuad const & rq, double l) { + return rq.toCubic(l).controlPoints(); +} + +static std::vector<Geom::Point> wrap_rq_to_cubic(Geom::RatQuad const & rq) { + return wrap_rq_to_cubic_l(rq, rq.lambda()); +} + +static tuple wrap_rq_split(Geom::RatQuad const & rq) { + Geom::RatQuad a, b; + rq.split(a, b); + return make_tuple(a, b); +} + +static object wrap_xax_to_curve(Geom::xAx const & xax, Geom::Rect const & r) { + std::optional<Geom::RatQuad> oc = xax.toCurve(r); + return oc?object(*oc):object(); +} + + + +void wrap_conic() { + //conicsec.h + def("intersect", (std::vector<Geom::Point> (*)(Geom::xAx const &, Geom::xAx const &))Geom::intersect); + + class_<Geom::xAx>("xAx", init<>()) + .def(init<double, double, double, double, double, double>()) + .def(init<Geom::xAx const&>()) + .def_readonly("c", &Geom::xAx::c) + .def("tuple", xAx_to_tuple) + + .def("from_tuple", tuple_to_xAx) + .staticmethod("from_tuple") + .def("fromPoint", Geom::xAx::fromPoint) + .staticmethod("fromPoint") + .def("fromPoints", Geom::xAx::fromPoints) + .staticmethod("fromPoints") + .def("fromLine", (Geom::xAx (*)(Geom::Line l))Geom::xAx::fromLine) + .staticmethod("fromLine") + .def(self_ns::str(self)) + .def("valueAt", &Geom::xAx::valueAt) + + .def("implicit_form_coefficients", &Geom::xAx::implicit_form_coefficients) + + .def("isDegenerate", &Geom::xAx::isDegenerate) + .def("roots", &xax_roots1) + .def("roots", &xax_roots2) + .def("extrema", &Geom::xAx::extrema) + .def("gradient", &Geom::xAx::gradient) + .def("crossings", &Geom::xAx::crossings) + .def("evaluate_at", &xy_eval_at) + .def("evaluate_at", &homo_eval_at) + .def("toCurve", &wrap_xax_to_curve) + .def(self - self) + .def(self + float()) + .def(self * float()) + ; + + class_<Geom::RatQuad>("RatQuad", init<>()) + .def(init<Geom::Point, Geom::Point, Geom::Point, double>()) + .def_readonly("P", &Geom::RatQuad::P) + .def_readonly("w", &Geom::RatQuad::w) + .def_readonly("lam", &Geom::RatQuad::lambda) + //.def(self_ns::str(self)) + .def("at0", &Geom::RatQuad::at0) + .def("at1", &Geom::RatQuad::at1) + .def("pointAt", &Geom::RatQuad::pointAt) + + .def("toCubic", &wrap_rq_to_cubic) + .def("toCubic", &wrap_rq_to_cubic_l) + .def("toCubicSBasis", &wrap_rq_to_cubic_sb) + .def("toCubicSBasis", &wrap_rq_to_cubic_sb_l) + + .def("split", &wrap_rq_split) + .def("hermite", &Geom::RatQuad::hermite) + .def("homogeneous", &Geom::RatQuad::homogeneous) + .def("fromPointsTangents", &Geom::RatQuad::fromPointsTangents) + .staticmethod("fromPointsTangents") + ; + implicitly_convertible<Geom::Point,tuple>(); +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/convexcover.cpp b/src/py2geom/convexcover.cpp new file mode 100644 index 0000000..3f0b270 --- /dev/null +++ b/src/py2geom/convexcover.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2009 Nathan Hurst <njh@njhurst.com> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/point.h" +#include "2geom/exception.h" +#include "2geom/convex-cover.h" + + + +using namespace boost::python; + +PointVec ch_boundary(Geom::ConvexHull const &ch) { + return ch.boundary; +} + +int furthest_index(Geom::ConvexHull const &ch, Geom::Point const &p) { + return (int)(ch.furthest(p) - &ch.boundary[0]); +} + +void wrap_convex_cover() { + class_<Geom::ConvexHull>("ConvexHull", init<>()) + .def(init<PointVec>()) + + .def("merge", &Geom::ConvexHull::merge) + .def("contains_point", &Geom::ConvexHull::contains_point) + .def("strict_contains_point", &Geom::ConvexHull::strict_contains_point) + + .add_property("boundary", &ch_boundary) + .add_property("is_clockwise", &Geom::ConvexHull::is_clockwise) + .add_property("top_point_first", &Geom::ConvexHull::top_point_first) + .add_property("meets_invariants", &Geom::ConvexHull::meets_invariants) + .add_property("empty", &Geom::ConvexHull::empty) + + .add_property("singular", &Geom::ConvexHull::singular) + + .add_property("linear", &Geom::ConvexHull::linear) + .add_property("is_degenerate", &Geom::ConvexHull::is_degenerate) + + .def("centroid_and_area", &Geom::ConvexHull::centroid_and_area) + .def("area", &Geom::ConvexHull::area) + .def("furthest", &furthest_index) + + .def("is_left", &Geom::ConvexHull::is_left) + .def("is_strict_left", &Geom::ConvexHull::is_strict_left) + .def("find_left", &Geom::ConvexHull::find_left) + .def("find_strict_left", &Geom::ConvexHull::find_strict_left) + .def("narrowest_diameter", &Geom::ConvexHull::narrowest_diameter) + ; + + }; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/crossing.cpp b/src/py2geom/crossing.cpp new file mode 100644 index 0000000..6b4f050 --- /dev/null +++ b/src/py2geom/crossing.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2009 Nathan Hurst <njh@njhurst.com> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/crossing.h" +#include "2geom/point.h" + +using namespace boost::python; + +void wrap_crossing() { + //line.h + + class_<Geom::Crossing>("Crossing", init<>()) + .def(init<double, double, bool>()) + .def(init<double, double, unsigned, unsigned, bool>()) + .def_readonly("ta", &Geom::Crossing::ta) + .def_readonly("tb", &Geom::Crossing::tb) + .def_readonly("a", &Geom::Crossing::a) + .def_readonly("b", &Geom::Crossing::b) + .def_readonly("dir", &Geom::Crossing::dir) + //.def(self_ns::str(self)) + .def("getOther", &Geom::Crossing::getOther) + .def("getTime", &Geom::Crossing::getTime) + .def("getOtherTime", &Geom::Crossing::getOtherTime) + .def("onIx", &Geom::Crossing::onIx) + ; +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/d2.cpp b/src/py2geom/d2.cpp new file mode 100644 index 0000000..d646ea5 --- /dev/null +++ b/src/py2geom/d2.cpp @@ -0,0 +1,99 @@ +/* + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" +#include <2geom/point.h> +#include <2geom/sbasis.h> +#include <2geom/d2.h> +#include <2geom/piecewise.h> + +using namespace boost::python; + +void wrap_d2() { + class_<Geom::D2<Geom::SBasis> >("D2SBasis", init<>()) + .def(init<Geom::SBasis,Geom::SBasis>()) + .def("__getitem__", python_getitem<Geom::D2<Geom::SBasis>,Geom::SBasis,2>) + + .def("isZero", &Geom::D2<Geom::SBasis>::isZero) + .def("isFinite", &Geom::D2<Geom::SBasis>::isFinite) + .def("at0", &Geom::D2<Geom::SBasis>::at0) + .def("at1", &Geom::D2<Geom::SBasis>::at1) + .def("pointAt", &Geom::D2<Geom::SBasis>::valueAt) + .def("valueAndDerivatives", &Geom::D2<Geom::SBasis>::valueAndDerivatives) + .def("toSBasis", &Geom::D2<Geom::SBasis>::toSBasis) + + .def(-self) + .def(self + self) + .def(self - self) + .def(self += self) + .def(self -= self) + .def(self + Geom::Point()) + .def(self - Geom::Point()) + .def(self += Geom::Point()) + .def(self -= Geom::Point()) + .def(self * Geom::Point()) + .def(self / Geom::Point()) + .def(self *= Geom::Point()) + .def(self /= Geom::Point()) + .def(self * float()) + .def(self / float()) + .def(self *= float()) + .def(self /= float()) + ; + def("reverse", ((Geom::D2<Geom::SBasis> (*)(Geom::D2<Geom::SBasis> const &b))&Geom::reverse)); + def("portion", ((Geom::D2<Geom::SBasis> (*)(Geom::D2<Geom::SBasis> const &a, Geom::Coord f, Geom::Coord t))&Geom::portion)); + //TODO: dot, rot90, cross, compose, composeEach, eval ops, derivative, integral, L2, portion, multiply ops, + + class_<Geom::D2<Geom::Piecewise<Geom::SBasis> > >("D2PiecewiseSBasis") + .def("__getitem__", python_getitem<Geom::D2<Geom::Piecewise<Geom::SBasis> >,Geom::Piecewise<Geom::SBasis>,2>) + + //.def("isZero", &Geom::D2<Geom::Piecewise<Geom::SBasis> >::isZero) + //.def("isFinite", &Geom::D2<Geom::Piecewise<Geom::SBasis> >::isFinite) + //.def("at0", &Geom::D2<Geom::Piecewise<Geom::SBasis> >::at0) + //.def("at1", &Geom::D2<Geom::Piecewise<Geom::SBasis> >::at1) + //.def("pointAt", &Geom::D2<Geom::Piecewise<Geom::SBasis> >::valueAt) + //.def("valueAndDerivatives", &Geom::D2<Geom::Piecewise<Geom::SBasis> >::valueAndDerivatives) + //.def("toSBasis", &Geom::D2<Geom::Piecewise<Geom::SBasis> >::toSBasis) + + ; +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/ellipse.cpp b/src/py2geom/ellipse.cpp new file mode 100644 index 0000000..7592bd4 --- /dev/null +++ b/src/py2geom/ellipse.cpp @@ -0,0 +1,88 @@ +/* + * Copyright 2009 Ricardo Lafuente <r@sollec.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/point.h" +#include "2geom/ellipse.h" +#include "2geom/circle.h" +#include "2geom/exception.h" +#include "2geom/d2.h" + + +void (Geom::Ellipse::*ellipse_set1)(Geom::Point const &, Geom::Point const &, double) = &Geom::Ellipse::set; +void (Geom::Ellipse::*ellipse_set2)(double, double, double, double, double) = &Geom::Ellipse::set; +std::vector<Geom::Coord> (Geom::Ellipse::*ellipse_coefficients)() const = &Geom::Ellipse::coefficients; + +// i can't get these to work +//Geom::Point (Geom::Ellipse::*center_point)() = (Geom::Point (*)() const)&Geom::Ellipse::center; +// Geom::Coord (Geom::Ellipse::*center_coord)(Geom::Dim2 const& d) = &Geom::Ellipse::center; + +using namespace boost::python; + +void wrap_ellipse() { + class_<Geom::Ellipse>("Ellipse", init<double, double, double, double, double>()) + .def(init<double, double, double, double, double, double>()) + // needs to be mapped to PointVec, but i can't figure out how + .def(init<Geom::Circle>()) + + .def("set", ellipse_set1) + .def("set", ellipse_set2) + .def("setCoefficients", &Geom::Ellipse::setCoefficients) + .def("fit", &Geom::Ellipse::fit) + + .def("center", (Geom::Point (Geom::Ellipse::*)() const) &Geom::Ellipse::center) + // .def("center", center_coord) + + .def("ray", &Geom::Ellipse::ray) + .def("rotationAngle", &Geom::Ellipse::rotationAngle) + .def("coefficients", ellipse_coefficients) + .def(self * Geom::Affine()) + .def(self *= Geom::Affine()) + // requires EllipticalArc + //.def("arc", &Geom::Ellipse::arc) + + ; + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/etc.cpp b/src/py2geom/etc.cpp new file mode 100644 index 0000000..57fdf4c --- /dev/null +++ b/src/py2geom/etc.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2009 Ricardo Lafuente <r@sollec.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/point.h" +#include "2geom/sbasis.h" +#include "2geom/exception.h" + +using namespace boost::python; + +void wrap_etc() { + // needed for roots + class_<DoubleVec >("DoubleVec") + .def(vector_indexing_suite<std::vector<double> >()) + ; + class_<PointVec>("PointVec") + .def(vector_indexing_suite<std::vector<Geom::Point> >()) + ; + // sbasis is a subclass of + class_<LinearVec >("LinearVec") + .def(vector_indexing_suite<std::vector<Geom::Linear> >()) + ; + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/helpers.h b/src/py2geom/helpers.h new file mode 100644 index 0000000..4502fba --- /dev/null +++ b/src/py2geom/helpers.h @@ -0,0 +1,59 @@ +/* + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#ifndef SEEN_PY2GEOM_HELPERS_H +#define SEEN_PY2GEOM_HELPERS_H + +#include <boost/python.hpp> + +template <typename T, typename R, unsigned D> +R python_getitem(T const& p, int index) +{ + unsigned i = index; + if (index < 0) + { + i = index = D + index; + } + if ((index < 0) || (i > (D - 1))) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + boost::python::throw_error_already_set(); + } + return p[i]; +} + +#endif +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/interval.cpp b/src/py2geom/interval.cpp new file mode 100644 index 0000000..1ac2d60 --- /dev/null +++ b/src/py2geom/interval.cpp @@ -0,0 +1,159 @@ +/* + * Copyright 2008 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/interval.h" + +using namespace boost::python; + + +// helpers for interval +static tuple interval_to_tuple(Geom::Interval const& p) +{ + return make_tuple(p.min(), p.max()); +} + +static Geom::Interval tuple_to_interval(boost::python::tuple const& t) +{ + return Geom::Interval(extract<double>(t[0]), extract<double>(t[1])); +} + +static str interval_repr(Geom::Interval const& p) +{ + return str("(" + str(p.min()) + ", " + str(p.max()) + ")"); +} + +static Geom::Interval from_optinterval(Geom::OptInterval const & ivl) +{ + return *ivl; +} + + +static bool wrap_contains_coord(Geom::Interval const &x, Geom::Coord val) { + return x.contains(val); +} + +static bool wrap_contains_ivl(Geom::Interval const &x, Geom::Interval val) { + return x.contains(val); +} + +static bool wrap_interiorContains_coord(Geom::Interval const &x, Geom::Coord val) { + return x.interiorContains(val); +} + +static bool wrap_interiorContains_ivl(Geom::Interval const &x, Geom::Interval val) { + return x.interiorContains(val); +} + +void wrap_interval() { + def("interval_to_tuple", interval_to_tuple); + def("tuple_to_interval", tuple_to_interval); + + //def("unify", Geom::unify(Geom::Interval const &, Geom::Interval const &)); + //def("intersect", Geom::intersect(Geom::Interval const &, Geom::Interval const &)); + + //TODO: add overloaded constructors + class_<Geom::Interval>("Interval", init<double, double>()) + .def("__str__", interval_repr) + .def("__repr__", interval_repr) + .def("tuple", interval_to_tuple) + + .def("from_tuple", tuple_to_interval) + .staticmethod("from_tuple") + + .def("min", &Geom::Interval::min) + .def("max", &Geom::Interval::max) + .def("middle", &Geom::Interval::middle) + .def("extent", &Geom::Interval::extent) + .def("isSingular", &Geom::Interval::isSingular) + //TODO: fix for overloading + .def("contains", wrap_contains_coord) + .def("contains", wrap_contains_ivl) + .def("interiorContains", wrap_interiorContains_coord) + .def("interiorContains", wrap_interiorContains_ivl) + .def("intersects", &Geom::Interval::intersects) + + .def("setMin", &Geom::Interval::setMin) + .def("setMax", &Geom::Interval::setMax) + .def("expandTo", &Geom::Interval::expandTo) + .def("from_array", &Geom::Interval::from_array) + .def("expandBy", &Geom::Interval::expandBy) + .def("unionWith", &Geom::Interval::unionWith) + + .def(self == self) + .def(self != self) + + .def(self + float()) + .def(self - float()) + .def(self += float()) + .def(self -= float()) + + .def(-self) + + .def(self * float()) + .def(self / float()) + .def(self *= float()) + .def(self /= float()) + + .def(self + self) + .def(self - self) + .def(self += self) + .def(self -= self) + .def(self * self) + .def(self *= self) + ; + class_<Geom::OptInterval>("OptInterval", init<double, double>()) + .def(init<Geom::Interval>()) + .def("unionWith", &Geom::OptInterval::unionWith) + .def("empty", &Geom::OptInterval::empty) + .def("toInterval", from_optinterval) + + .def(self == self) + .def(self != self) + ; + implicitly_convertible<Geom::Interval,tuple>(); +// TODO: is this possible? +// implicitly_convertible<tuple,Geom::Interval>(); + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/line.cpp b/src/py2geom/line.cpp new file mode 100644 index 0000000..0df4360 --- /dev/null +++ b/src/py2geom/line.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2009 Nathan Hurst <njh@njhurst.com> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/line.h" +//#include "2geom/bezier-curve.h" +#include "2geom/point.h" + +using namespace boost::python; + +template <typename S, typename T> +object wrap_intersection(S const& a, T const& b) { + Geom::OptCrossing oc = intersection(a, b); + return oc?object(*oc):object(); +} + +std::vector<Geom::Coord> (Geom::Line::*coefficients_vec)() const = &Geom::Line::coefficients; + +void wrap_line() { + //line.h + + def("intersection", wrap_intersection<Geom::Line, Geom::Line>); + def("intersection", wrap_intersection<Geom::Line, Geom::Ray>); + //def("intersection", wrap_intersection<Geom::Line, Geom::LineSegment>); + def("intersection", wrap_intersection<Geom::Ray, Geom::Line>); + def("intersection", wrap_intersection<Geom::Ray, Geom::Ray>); + //def("intersection", wrap_intersection<Geom::Ray, Geom::LineSegment>); + //def("intersection", wrap_intersection<Geom::LineSegement, Geom::Line>); + //def("intersection", wrap_intersection<Geom::LineSegement, Geom::Ray>); + //def("intersection", wrap_intersection<Geom::LineSegement, Geom::LineSegment>); + class_<Geom::Line>("Line", init<>()) + .def(init<Geom::Point const&, Geom::Coord>()) + .def(init<Geom::Point const&, Geom::Point const&>()) + .def(init<double, double, double>()) + //.def(self_ns::str(self)) + .def("valueAt", &Geom::Line::valueAt) + + .def("coefficients", coefficients_vec) + .def("isDegenerate", &Geom::Line::isDegenerate) + .def("pointAt", &Geom::Line::pointAt) + .def("roots", &Geom::Line::roots) + .def("nearestTime", &Geom::Line::nearestTime) + .def("reverse", &Geom::Line::reverse) + //.def("portion", &Geom::Line::portion) + //.def("segment", &Geom::Line::segment) + .def("derivative", &Geom::Line::derivative) + .def("transformed", &Geom::Line::transformed) + .def("normal", &Geom::Line::normal) + .def("normalAndDist", &Geom::Line::normalAndDist) + .def("setPoints", &Geom::Line::setPoints) + .def("setCoefficients", &Geom::Line::setCoefficients) + ; + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/linear.cpp b/src/py2geom/linear.cpp new file mode 100644 index 0000000..419af64 --- /dev/null +++ b/src/py2geom/linear.cpp @@ -0,0 +1,110 @@ +/* + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/linear.h" +#include "2geom/point.h" +#include "2geom/sbasis.h" + +using namespace boost::python; + +// helpers for bezord +tuple bezord_to_tuple(Geom::Linear const& b) +{ + return make_tuple(b[0], b[1]); +} + +Geom::Linear tuple_to_bezord(boost::python::tuple const& t) +{ + return Geom::Linear(extract<double>(t[0]), extract<double>(t[1])); +} + +str bezord_repr(Geom::Linear const& b) +{ + return str("<" + str(b[0]) + ", " + str(b[1]) + ">"); +} + +void wrap_linear() { + def("lerp", (double (*)(double, double, double))&Geom::lerp); + def("reverse", (Geom::Linear (*)(Geom::Linear const &))&Geom::reverse); + def("bounds_fast", (Geom::OptInterval (*)(Geom::Linear const &))&Geom::bounds_fast); + def("bounds_exact", (Geom::OptInterval (*)(Geom::Linear const &))&Geom::bounds_exact); + def("bounds_local", (Geom::OptInterval (*)(Geom::Linear const &))&Geom::bounds_local); + + class_<Geom::Linear>("Linear", init<double, double>()) + .def("__str__", bezord_repr) + .def("__repr__", bezord_repr) + .def("__getitem__", python_getitem<Geom::Linear,double,2>) + .def("tuple", bezord_to_tuple) + + .def("from_tuple", tuple_to_bezord) + .staticmethod("from_tuple") + + .def("isZero", &Geom::Linear::isZero) + .def("isFinite", &Geom::Linear::isFinite) + .def("at0", (double (Geom::Linear::*)() const) &Geom::Linear::at0) + .def("at1", (double (Geom::Linear::*)() const) &Geom::Linear::at1) + .def("valueAt", &Geom::Linear::valueAt) + .def("toSBasis", &Geom::Linear::toSBasis) + + .def(-self) + .def(self + self) + .def(self - self) + .def(self += self) + .def(self -= self) + .def(self + float()) + .def(self - float()) + .def(self += float()) + .def(self -= float()) + .def(self == self) + .def(self != self) + .def(self * float()) + .def(self / float()) + .def(self *= float()) + .def(self /= float()) + ; + def("reverse", ((Geom::Linear (*)(Geom::Linear const &b))&Geom::reverse)); + //TODO: reinstate + //implicitly_convertible<Geom::Linear,tuple>(); +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/parser.cpp b/src/py2geom/parser.cpp new file mode 100644 index 0000000..8f729a1 --- /dev/null +++ b/src/py2geom/parser.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2008 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/path-sink.h" +#include "2geom/svg-path-parser.h" + + +using namespace boost::python; + +void (*parse_svg_path_str_sink) (char const *, Geom::PathSink &) = &Geom::parse_svg_path; +Geom::PathVector (*parse_svg_path_str) (char const *) = &Geom::parse_svg_path; + +void (Geom::PathSink::*feed_path)(Geom::Path const &) = &Geom::PathSink::feed; +void (Geom::PathSink::*feed_pathvector)(Geom::PathVector const &) = &Geom::PathSink::feed; + +class PathSinkWrap: public Geom::PathSink, public wrapper<Geom::PathSink> { + void moveTo(Geom::Point const &p) {this->get_override("moveTo")(p);} + void lineTo(Geom::Point const &p) {this->get_override("lineTo")(p);} + void curveTo(Geom::Point const &c0, Geom::Point const &c1, Geom::Point const &p) {this->get_override("curveTo")(c0, c1, p);} + void quadTo(Geom::Point const &c, Geom::Point const &p) {this->get_override("quadTo")(c, p);} + void arcTo(double rx, double ry, double angle, bool large_arc, bool sweep, Geom::Point const &p) {this->get_override("arcTo")(rx, ry, angle, large_arc, sweep, p);} + bool backspace() {return this->get_override("backspace")();} + void closePath() {this->get_override("closePath")();} + void flush() {this->get_override("flush")();} +}; + +void wrap_parser() { + def("parse_svg_path", parse_svg_path_str_sink); + def("parse_svg_path", parse_svg_path_str); + def("read_svgd", Geom::read_svgd); + + class_<PathSinkWrap, boost::noncopyable>("PathSink") + .def("moveTo", pure_virtual(&Geom::PathSink::moveTo)) + .def("lineTo", pure_virtual(&Geom::PathSink::lineTo)) + .def("curveTo", pure_virtual(&Geom::PathSink::curveTo)) + .def("quadTo", pure_virtual(&Geom::PathSink::quadTo)) + .def("arcTo", pure_virtual(&Geom::PathSink::arcTo)) + .def("backspace", pure_virtual(&Geom::PathSink::backspace)) + .def("closePath", pure_virtual(&Geom::PathSink::closePath)) + .def("flush", pure_virtual(&Geom::PathSink::flush)) + .def("feed", feed_path) + .def("feed", feed_pathvector) + ; +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/path.cpp b/src/py2geom/path.cpp new file mode 100644 index 0000000..68757a6 --- /dev/null +++ b/src/py2geom/path.cpp @@ -0,0 +1,265 @@ +/* + * Python bindings for lib2geom + * + * Copyright 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "2geom/curve.h" +#include "2geom/bezier-curve.h" +#include "2geom/path.h" +#include "2geom/pathvector.h" +#include "2geom/sbasis-to-bezier.h" +#include "helpers.h" + +#include "2geom/point.h" +#include "2geom/rect.h" +#include "2geom/d2.h" + +using namespace boost::python; + +Geom::Curve const &path_getitem(Geom::Path const& p, int index) +{ + unsigned size = p.size_default(); + unsigned i = index; + if (index < 0) + { + i = index = size + index; + } + if ((index < 0) || (i > (size - 1))) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + boost::python::throw_error_already_set(); + } + return p[i]; +} + +struct CurveWrap : Geom::Curve, wrapper<Geom::Curve> +{ + Geom::Point initialPoint() const {return this->get_override("initialPoint")();} + Geom::Point finalPoint() const {return this->get_override("finalPoint")();} + bool isDegenerate() const {return this->get_override("isDegenerate")();} + CurveWrap *duplicate() const {return this->get_override("duplicate")();} + Geom::Rect boundsFast() const {return this->get_override("boundsFast")();} + Geom::Rect boundsExact() const {return this->get_override("boundsExact")();} + virtual Geom::OptRect boundsLocal(Geom::OptInterval const &i, unsigned deg) const {return this->get_override("boundsLocal")(i,deg);} + std::vector<double> roots(double v, Geom::Dim2 d) const {return this->get_override("roots")(v,d);} + + int winding(Geom::Point const &p) const { + if (override f = this->get_override("winding")) { + return f(p); + } + return Geom::Curve::winding(p); + } + int default_winding(Geom::Point p) const { return this->Geom::Curve::winding(p); } + + Geom::Curve *portion(double f, double t) const { return this->get_override("portion")(f,t); } + Geom::Curve *reverse() const { + if (override f = this->get_override("reverse")) { + return f(); + } + return Geom::Curve::reverse(); + } + Geom::Curve *default_reverse() const { return this->Geom::Curve::reverse(); } + + Geom::Curve *derivative() const { return this->get_override("derivative")(); } + + + Geom::Curve *transformed(Geom::Affine const &m) const { return this->get_override("transformed")(m); } + + Geom::Point pointAt(Geom::Coord t) const { + if (override f = this->get_override("pointAt")) { + return f(t); + } + return Geom::Curve::pointAt(t); + } + Geom::Point default_pointAt(Geom::Coord t) { return this->Geom::Curve::pointAt(t); } + std::vector<Geom::Point> pointAndDerivatives(Geom::Coord t, unsigned n) const { + return this->get_override("pointAndDerivatives")(t, n); + } + + Geom::D2<Geom::SBasis> toSBasis() const {return this->get_override("sbasis")();} +}; + + +/* pycairo stuff: */ +#ifdef HAVE_PYCAIRO + +#include "cairo-helpers.h" + +void py_cairo_curve(object cr, Geom::Curve const &c) { + cairo_curve(cairo_t_from_object(cr), c); +} +void py_cairo_rectangle(object cr, Geom::Rect const &r) { + cairo_rectangle(cairo_t_from_object(cr), r); +} + +void py_cairo_convex_hull(object cr, Geom::ConvexHull const &r) { + cairo_convex_hull(cairo_t_from_object(cr), r); +} +/*void py_cairo_path(object cr, Geom::Path const &p) { + cairo_path(cairo_t_from_object(cr), p); + }*/ + +void py_cairo_path(object cr, Geom::Path const &p) { + cairo_path(cairo_t_from_object(cr), p); +} + +void py_cairo_path(object cr, Geom::PathVector const &p) { + cairo_path(cairo_t_from_object(cr), p); +} +void py_cairo_path_stitches(object cr, Geom::Path const &p) { + cairo_path_stitches(cairo_t_from_object(cr), p); +} +void py_cairo_path_stitches(object cr, Geom::PathVector const &p) { + cairo_path_stitches(cairo_t_from_object(cr), p); +} +void (*cp_1)(object, Geom::Path const &) = &py_cairo_path; +void (*cp_2)(object, Geom::PathVector const &) = &py_cairo_path; + +void (*cps_1)(object, Geom::Path const &) = &py_cairo_path_stitches; +void (*cps_2)(object, Geom::PathVector const &) = &py_cairo_path_stitches; + + +void py_cairo_d2_sb(object cr, Geom::D2<Geom::SBasis> const &p) { + cairo_d2_sb(cairo_t_from_object(cr), p); +} + +void py_cairo_d2_pw_sb(object cr, Geom::D2<Geom::Piecewise<Geom::SBasis> > const &p) { + cairo_d2_pw_sb(cairo_t_from_object(cr), p); +} + +void py_cairo_pw_d2_sb(object cr, Geom::Piecewise<Geom::D2<Geom::SBasis> > const &p) { + cairo_pw_d2_sb(cairo_t_from_object(cr), p); +} + +#endif // HAVE_PYCAIRO + +Geom::Point (Geom::Path::*path_pointAt_time)(Geom::Coord) const = &Geom::Path::pointAt; +Geom::Coord (Geom::Path::*path_valueAt_time)(Geom::Coord, Geom::Dim2) const = &Geom::Path::valueAt; +void (Geom::Path::*appendPortionTo_time)(Geom::Path &, Geom::Coord, Geom::Coord) const = &Geom::Path::appendPortionTo; +//void (Geom::Path::*appendPortionTo_pos)(Geom::Path &, Geom::PathPosition const &, Geom::PathPosition const &, bool) const = &Geom::Path::appendPortionTo; + +void wrap_path() +{ +/* class_<CurveWrap, boost::noncopyable>("Curve") + .def("initalPoint", pure_virtual(&Geom::Curve::initialPoint)) + .def("finalPoint", pure_virtual(&Geom::Curve::finalPoint)) + .def("duplicate", pure_virtual(&Geom::Curve::duplicate), return_value_policy<manage_new_object>()) + .def("boundsFast", pure_virtual(&Geom::Curve::boundsFast)) + .def("boundsExact", pure_virtual(&Geom::Curve::boundsExact)) + //.def("pointAt", &Geom::Curve::pointAt, &CurveWrap::default_pointAt) + //.def("winding", &Geom::Curve::winding, &CurveWrap::default_winding) + .def("pointAndDerivatives", pure_virtual(&Geom::Curve::pointAndDerivatives)) + .def("toSBasis", pure_virtual(&Geom::Curve::toSBasis)) + ;*/ +/* class_<Geom::LineSegment, bases<CurveWrap> >("LineSegment") + .def("points", &Geom::LineSegment::points) + ; + class_<Geom::QuadraticBezier, bases<CurveWrap> >("QuadraticBezier") + .def("points", &Geom::QuadraticBezier::points) + ; + class_<Geom::CubicBezier, bases<CurveWrap> >("CubicBezier") + .def("points", &Geom::CubicBezier::points) + ;*/ + class_<Geom::Path>("Path") + .def("__getitem__", path_getitem, return_value_policy<copy_const_reference>()) //or return_internal_reference see http://www.boost.org/doc/libs/1_36_0/libs/python/doc/v2/faq.html#question1 + .def("empty", &Geom::Path::empty) + .def("closed", &Geom::Path::closed) + .def("close", &Geom::Path::close) + .def("boundsFast", &Geom::Path::boundsFast) + .def("boundsExact", &Geom::Path::boundsExact) + .def("toPwSb", &Geom::Path::toPwSb) + .def(self * Geom::Affine()) + .def(self *= Geom::Affine()) + .def("pointAt", path_pointAt_time) + .def("valueAt", path_valueAt_time) + .def("__call__", path_pointAt_time) + .def("roots", &Geom::Path::roots) + //.def("allNearestTimes", &Geom::Path::allNearestTimes) + //.def("nearestTime", &Geom::Path::nearestTime) + .def("appendPortionTo", appendPortionTo_time) + //.def("portion", &Geom::Path::portion) + .def("reversed", &Geom::Path::reversed) + //.def("insert", &Geom::Path::insert) + .def("clear", &Geom::Path::clear) + //.def("erase", &Geom::Path::erase) + .def("erase_last", &Geom::Path::erase_last) + //.def("replace", &Geom::Path::replace) + .def("start", &Geom::Path::start) + .def("initialPoint", &Geom::Path::initialPoint) + .def("finalPoint", &Geom::Path::finalPoint) + //.def("append", &Geom::Path::append) + //.def("appendNew", &Geom::Path::appendNew) + ; + def("paths_to_pw",Geom::paths_to_pw); + class_<Geom::PathVector >("PathVector") + .def(vector_indexing_suite<Geom::PathVector >()) + .def(self * Geom::Affine()) + .def(self *= Geom::Affine()) + .def("reversed", &Geom::PathVector::reversed) + .def("reverse", &Geom::PathVector::reverse) + .def("boundsFast", &Geom::PathVector::boundsFast) + .def("boundsExact", &Geom::PathVector::boundsExact) + ; + def("path_from_piecewise", Geom::path_from_piecewise); + def("path_from_sbasis", Geom::path_from_sbasis); + def("cubicbezierpath_from_sbasis", Geom::cubicbezierpath_from_sbasis); + +#ifdef HAVE_PYCAIRO +void cairo_move_to(cairo_t *cr, Geom::Point p1); + def("cubicbezierpath_from_sbasis", Geom::cubicbezierpath_from_sbasis); +void cairo_line_to(cairo_t *cr, Geom::Point p1); + def("cubicbezierpath_from_sbasis", Geom::cubicbezierpath_from_sbasis); +void cairo_curve_to(cairo_t *cr, Geom::Point p1, Geom::Point p2, Geom::Point p3); + def("cubicbezierpath_from_sbasis", Geom::cubicbezierpath_from_sbasis); + + //def("cairo_curve", cairo_curve); + def("cairo_convex_hull", py_cairo_convex_hull); + def("cairo_path", cp_1); + def("cairo_path", cp_2); + def("cairo_path_stitches", cps_1); + def("cairo_path_stitches", cps_2); + + def("cairo_d2_sb", py_cairo_d2_sb); + def("cairo_d2_pw_sb", py_cairo_d2_pw_sb); + def("cairo_pw_d2_sb", py_cairo_pw_d2_sb); +#endif // HAVE_PYCAIRO +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(substatement-open . 0)) + indent-tabs-mode:nil + c-brace-offset:0 + fill-column:99 + End: + vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +*/ diff --git a/src/py2geom/point.cpp b/src/py2geom/point.cpp new file mode 100644 index 0000000..869240d --- /dev/null +++ b/src/py2geom/point.cpp @@ -0,0 +1,146 @@ +/* + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/point.h" + +using namespace boost::python; + + +// helpers for point +tuple point_to_tuple(Geom::Point const& p) +{ + return make_tuple(p[0], p[1]); +} + +Geom::Point tuple_to_point(boost::python::tuple const& t) +{ + return Geom::Point(extract<double>(t[0]), extract<double>(t[1])); +} + +str point_repr(Geom::Point const& p) +{ + return str("(" + str(p[0]) + ", " + str(p[1]) + ")"); +} + +//Specifications of overloads +Geom::Coord (*L2_point) (Geom::Point const &) = &Geom::L2; +Geom::Point (*rot90_point)(Geom::Point const &) = &Geom::rot90; +Geom::Coord (*dot_point) (Geom::Point const &, Geom::Point const &) = &Geom::dot; +Geom::Coord (*cross_point)(Geom::Point const &, Geom::Point const &) = &Geom::cross; +Geom::Point (*lerp_point)(Geom::Coord, Geom::Point const &, Geom::Point const &) = &Geom::lerp; + +bool near_point1(Geom::Point const &a, Geom::Point const &b) { return are_near(a,b); } +bool near_point2(Geom::Point const &a, Geom::Point const &b, double eps) { return are_near(a,b,eps); } + +void wrap_point() { + def("point_to_tuple", point_to_tuple); + def("tuple_to_point", tuple_to_point); + + def("L1", Geom::L1); + def("L2", L2_point); + def("L2sq", Geom::L2sq); + def("LInfty", Geom::LInfty); + + def("unit_vector", Geom::unit_vector); + def("is_zero", Geom::is_zero); + def("is_unit_vector", Geom::is_unit_vector); + + def("dot", dot_point); + def("cross", cross_point); + def("distance", Geom::distance); + def("distanceSq", Geom::distanceSq); + def("lerp", lerp_point); + + def("atan2", Geom::atan2); + def("angle_between", Geom::angle_between); + + def("near", near_point1); + def("near", near_point2); + + def("rot90", rot90_point); + def("abs", (Geom::Point (*)(Geom::Point const&))&Geom::abs); + + class_<Geom::Point>("Point", init<double, double>()) + .def(init<>()) + + .def("__str__", point_repr) + .def("__repr__", point_repr) + .def("__getitem__", python_getitem<Geom::Point,double,2>) + .def("tuple", point_to_tuple) + + .def("from_tuple", tuple_to_point) + .staticmethod("from_tuple") + + //point.h + //.def("polar", &Geom::Point::polar) + //.staticmethod("polar") + + .def("ccw", &Geom::Point::ccw) + .def("cw", &Geom::Point::cw) + .def("round", &Geom::Point::round) + .def("normalize", &Geom::Point::normalize) + + .def("length", &Geom::Point::length) + + .def(self + self) + .def(self - self) + .def(self += self) + .def(self -= self) + + .def(-self) + .def(self * float()).def(float() * self) + .def(self / float()) + .def(self *= float()) + + .def(self == self) + .def(self != self) + + .def(self <= self) + ; + implicitly_convertible<Geom::Point,tuple>(); +// TODO: explain why this gives a compile time error +// implicitly_convertible<tuple,Geom::Point>(); + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/pw.cpp b/src/py2geom/pw.cpp new file mode 100644 index 0000000..bbd8f2c --- /dev/null +++ b/src/py2geom/pw.cpp @@ -0,0 +1,228 @@ +/* + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "2geom/sbasis.h" +#include "2geom/piecewise.h" +#include "2geom/d2.h" +#include "2geom/sbasis-math.h" +#include "2geom/sbasis-geometric.h" + +#include "py2geom.h" +#include "helpers.h" + +using namespace boost::python; + +// helpers for point +tuple pwd2sb_centroid(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &pw) +{ + Geom::Point p; + double a; + Geom::centroid(pw, p, a); + return boost::python::make_tuple(p, a); +} + + +void (Geom::Piecewise<Geom::SBasis>::*push_pwsb)(Geom::SBasis const &, double) = &Geom::Piecewise<Geom::SBasis>::push; +void (Geom::Piecewise<Geom::SBasis>::*push_seg_pwsb)(Geom::SBasis const &) = &Geom::Piecewise<Geom::SBasis>::push_seg; +Geom::Piecewise<Geom::SBasis> (*portion_pwsb)(const Geom::Piecewise<Geom::SBasis> &, double, double) = &Geom::portion; +void (Geom::Piecewise<Geom::D2<Geom::SBasis>>::*push_pwd2sb)(Geom::D2<Geom::SBasis> const &, double) = &Geom::Piecewise<Geom::D2<Geom::SBasis>>::push; +void (Geom::Piecewise<Geom::D2<Geom::SBasis>>::*push_seg_pwd2sb)(Geom::D2<Geom::SBasis> const &) = &Geom::Piecewise<Geom::D2<Geom::SBasis>>::push_seg; +Geom::Piecewise<Geom::D2<Geom::SBasis>> (*portion_pwd2sb)(const Geom::Piecewise<Geom::D2<Geom::SBasis> > &, double, double) = &Geom::portion; +std::vector<double> (*roots_pwsb)(const Geom::Piecewise<Geom::SBasis> &) = &Geom::roots; +//Geom::Piecewise<Geom::SBasis> (*multiply_pwsb)(Geom::Piecewise<Geom::SBasis> const &, Geom::Piecewise<Geom::SBasis> const &) = &Geom::multiply; +Geom::Piecewise<Geom::SBasis> (*divide_pwsb)(Geom::Piecewise<Geom::SBasis> const &, Geom::Piecewise<Geom::SBasis> const &, unsigned) = &Geom::divide; +Geom::Piecewise<Geom::SBasis> (*compose_pwsb_sb)(Geom::Piecewise<Geom::SBasis> const &, Geom::SBasis const &) = &Geom::compose; +Geom::Piecewise<Geom::SBasis> (*compose_pwsb)(Geom::Piecewise<Geom::SBasis> const &, Geom::Piecewise<Geom::SBasis> const &) = &Geom::compose; + +Geom::Piecewise<Geom::SBasis> (*abs_pwsb)(Geom::Piecewise<Geom::SBasis> const &) = &Geom::abs; + +Geom::Piecewise<Geom::SBasis> (*min_pwsb)(Geom::Piecewise<Geom::SBasis> const &, Geom::Piecewise<Geom::SBasis> const &) = &Geom::min; +Geom::Piecewise<Geom::SBasis> (*max_pwsb)(Geom::Piecewise<Geom::SBasis> const &, Geom::Piecewise<Geom::SBasis> const &) = &Geom::max; +Geom::Piecewise<Geom::SBasis> (*signSb_pwsb)(Geom::Piecewise<Geom::SBasis> const &) = &Geom::signSb; + +Geom::Piecewise<Geom::SBasis> (*sqrt_pwsb)(Geom::Piecewise<Geom::SBasis> const &, double, int) = &Geom::sqrt; + +Geom::Piecewise<Geom::SBasis> (*sin_pwsb)(Geom::Piecewise<Geom::SBasis> const &, double, int) = &Geom::sin; +Geom::Piecewise<Geom::SBasis> (*cos_pwsb)(Geom::Piecewise<Geom::SBasis> const &, double, int) = &Geom::cos; + +//Geom::Piecewise<Geom::SBasis> (*log_pwsb)(Geom::Piecewise<Geom::SBasis> const &, double, int) = &Geom::log; +Geom::Piecewise<Geom::SBasis> (*reciprocal_pwsb)(Geom::Piecewise<Geom::SBasis> const &, double, int) = &Geom::reciprocal; + +Geom::FragmentConcept<Geom::SBasis>::BoundsType (*bounds_fast_pwsb)(Geom::Piecewise<Geom::SBasis> const &) = &Geom::bounds_fast; +Geom::FragmentConcept<Geom::SBasis>::BoundsType (*bounds_exact_pwsb)(Geom::Piecewise<Geom::SBasis> const &) = &Geom::bounds_exact; +Geom::FragmentConcept<Geom::SBasis>::BoundsType (*bounds_local_pwsb)(Geom::Piecewise<Geom::SBasis> const &, const Geom::OptInterval &) = &Geom::bounds_local; + +Geom::SBasis getitem_pwsb(Geom::Piecewise<Geom::SBasis> const &p, int index) { + unsigned D = p.size(); + unsigned i = index; + if (index < 0) + { + i = index = D + index; + } + if (index < 0 || i > (D - 1)) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + boost::python::throw_error_already_set(); + } + return p[i]; +} + +Geom::Piecewise<Geom::D2<Geom::SBasis> > (*unitVector_pwd2sb)(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &, double, unsigned int) = &Geom::unitVector; + +Geom::Piecewise<Geom::SBasis> (*arcLengthSb_pwd2sb)(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &, double) = &Geom::arcLengthSb; + +Geom::Piecewise<Geom::D2<Geom::SBasis> > (*rot90_pwd2sb)(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &) = &Geom::rot90; + +void wrap_pw() { + class_<std::vector<Geom::SBasis> >("SBasisVec") + .def(vector_indexing_suite<std::vector<Geom::SBasis> >()) + ; + class_<std::vector<Geom::D2<Geom::SBasis> > >("D2SBasisVec") + .def(vector_indexing_suite<std::vector<Geom::D2<Geom::SBasis> > >()) + ; + + def("portion", portion_pwsb); + def("portion", portion_pwd2sb); + //def("partition", &partition); + def("roots", roots_pwsb); + //def("multiply", multiply_pwsb); + def("divide", divide_pwsb); + def("compose", compose_pwsb_sb); + def("compose", compose_pwsb); + def("abs", abs_pwsb); + def("min", min_pwsb); + def("max", max_pwsb); + def("signSb", signSb_pwsb); + def("sqrt", sqrt_pwsb); + def("cos", cos_pwsb); + def("sin", sin_pwsb); + //def("log", log_pwsb); + def("reciprocal", reciprocal_pwsb); + def("bounds_fast", bounds_fast_pwsb); + def("bounds_exact", bounds_exact_pwsb); + def("bounds_local", bounds_local_pwsb); + + def("derivative", (Geom::Piecewise<Geom::SBasis> (*)(Geom::Piecewise<Geom::SBasis> const & ))&Geom::derivative); + def("integral", (Geom::Piecewise<Geom::SBasis> (*)(Geom::Piecewise<Geom::SBasis> const & ))&Geom::integral); + def("derivative", (Geom::Piecewise<Geom::D2<Geom::SBasis> > (*)(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &)) &Geom::derivative); + def("rot90", rot90_pwd2sb); + def("unit_vector", unitVector_pwd2sb); + def("arcLengthSb", arcLengthSb_pwd2sb); + + class_<Geom::Piecewise<Geom::SBasis> >("PiecewiseSBasis", init<>()) + .def(init<double>()) + .def(init<Geom::SBasis>()) + .def("__getitem__", getitem_pwsb) + .def("__call__", &Geom::Piecewise<Geom::SBasis>::valueAt) + .def_readonly("cuts", &Geom::Piecewise<Geom::SBasis>::cuts) + .def_readonly("segs", &Geom::Piecewise<Geom::SBasis>::segs) + .def("at0", &Geom::Piecewise<Geom::SBasis>::firstValue) + .def("at1", &Geom::Piecewise<Geom::SBasis>::lastValue) + .def("valueAt", &Geom::Piecewise<Geom::SBasis>::valueAt) + .def("size", &Geom::Piecewise<Geom::SBasis>::size) + .def("empty", &Geom::Piecewise<Geom::SBasis>::empty) + .def("push", push_pwsb) + .def("push_cut", &Geom::Piecewise<Geom::SBasis>::push_cut) + .def("push_seg", push_seg_pwsb) + + .def("segN", &Geom::Piecewise<Geom::SBasis>::segN) + .def("segT", &Geom::Piecewise<Geom::SBasis>::segT) + .def("offsetDomain", &Geom::Piecewise<Geom::SBasis>::offsetDomain) + .def("scaleDomain", &Geom::Piecewise<Geom::SBasis>::scaleDomain) + .def("setDomain", &Geom::Piecewise<Geom::SBasis>::setDomain) + .def("concat", &Geom::Piecewise<Geom::SBasis>::concat) + .def("continuousConcat", &Geom::Piecewise<Geom::SBasis>::continuousConcat) + .def("invariants", &Geom::Piecewise<Geom::SBasis>::invariants) + + .def(self + double()) + .def(-self) + .def(self += double()) + .def(self -= double()) + .def(self /= double()) + .def(self * double()) + .def(self *= double()) + .def(self + self) + .def(self - self) + .def(self * self) + .def(self *= self) + + ; + + class_<Geom::Piecewise<Geom::D2<Geom::SBasis> > >("PiecewiseD2SBasis", init<>()) + .def(init<Geom::D2<Geom::SBasis> >()) + .def("__getitem__", getitem_pwsb) + .def("__call__", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::valueAt) + .def_readonly("cuts", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::cuts) + .def_readonly("segs", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::segs) + .def("valueAt", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::valueAt) + .def("size", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::size) + .def("empty", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::empty) + .def("push", push_pwd2sb) + .def("push_cut", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::push_cut) + .def("push_seg", push_seg_pwd2sb) + + .def("segN", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::segN) + .def("segT", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::segT) + .def("offsetDomain", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::offsetDomain) + .def("scaleDomain", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::scaleDomain) + .def("setDomain", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::setDomain) + .def("concat", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::concat) + .def("continuousConcat", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::continuousConcat) + .def("invariants", &Geom::Piecewise<Geom::D2<Geom::SBasis> >::invariants) + + //.def(self + double()) + .def(-self) + //.def(self += double()) + //.def(self -= double()) + //.def(self /= double()) + .def(self * double()) + .def(Geom::Piecewise<Geom::SBasis>() * self) + .def(self *= double()) + .def(self + self) + .def(self - self) + //.def(self * self) + //.def(self *= self) + + ; + def("centroid", pwd2sb_centroid); + def("make_cuts_independent", Geom::make_cuts_independent); + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/py2geom.cpp b/src/py2geom/py2geom.cpp new file mode 100644 index 0000000..b1ef493 --- /dev/null +++ b/src/py2geom/py2geom.cpp @@ -0,0 +1,85 @@ +/* + * Python bindings for lib2geom + * + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * Copyright 2007 Alex Mac <ajm@cs.nott.ac.uk> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include <2geom/geom.h> + +#include "py2geom.h" + +using namespace boost::python; + +BOOST_PYTHON_MODULE(_py2geom) +{ + + /*enum_<IntersectorKind>("IntersectorKind") + .value("intersects", intersects) + .value("parallel", parallel) + .value("coincident", coincident) + .value("no_intersection", no_intersection) + ; + def("segment_intersect", segment_intersect);*/ + + wrap_point(); + wrap_etc(); + wrap_interval(); + wrap_transforms(); + wrap_rect(); + wrap_circle(); + wrap_ellipse(); + wrap_sbasis(); + wrap_bezier(); + wrap_linear(); + wrap_line(); + wrap_conic(); + wrap_pw(); + wrap_d2(); + wrap_parser(); + wrap_path(); + wrap_ray(); + // wrap_shape(); + wrap_crossing(); + // wrap_convex_cover(); + +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(substatement-open . 0)) + indent-tabs-mode:nil + c-brace-offset:0 + fill-column:99 + End: + vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +*/ diff --git a/src/py2geom/py2geom.h b/src/py2geom/py2geom.h new file mode 100644 index 0000000..ba9fb13 --- /dev/null +++ b/src/py2geom/py2geom.h @@ -0,0 +1,71 @@ +/* + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#ifndef SEEN_PY2GEOM_H +#define SEEN_PY2GEOM_H + +void wrap_point(); +void wrap_etc(); +void wrap_interval(); +void wrap_transforms(); +void wrap_rect(); +void wrap_circle(); +void wrap_ellipse(); +void wrap_sbasis(); +void wrap_bezier(); +void wrap_linear(); +void wrap_pw(); +void wrap_d2(); +void wrap_path(); +void wrap_parser(); +void wrap_ray(); +// void wrap_shape(); +void wrap_line(); +void wrap_conic(); +void wrap_crossing(); +// void wrap_convex_cover(); +namespace Geom{ +class Point; +class Linear; +}; +#include <vector> +typedef std::vector<Geom::Point > PointVec; +typedef std::vector<double > DoubleVec; +typedef std::vector<Geom::Linear> LinearVec; + +#endif +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/ray.cpp b/src/py2geom/ray.cpp new file mode 100644 index 0000000..9fda595 --- /dev/null +++ b/src/py2geom/ray.cpp @@ -0,0 +1,99 @@ +/* + * Copyright 2009 Ricardo Lafuente <r@sollec.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/point.h" +#include "2geom/ray.h" +// #include "2geom/bezier_curve.h" +#include "2geom/exception.h" + + +using namespace boost::python; + +bool (*are_near_ray)(Geom::Point const& _point, Geom::Ray const& _ray, double eps) = &Geom::are_near; +double (*angle_between_ray)(Geom::Ray const& r1, Geom::Ray const& r2, bool cw) = &Geom::angle_between; + + +double angle_between_ray_def(Geom::Ray const& r1, Geom::Ray const& r2) { + return Geom::angle_between(r1, r2); +} +double (*distance_ray)(Geom::Point const& _point, Geom::Ray const& _ray) = &Geom::distance; + +// why don't these compile? +//Geom::Point (*get_ray_origin)(Geom::Ray const) = &Geom::Ray::origin; +//void (*set_ray_origin)(Geom::Ray const, Geom::Point const& _point) = &Geom::Ray::origin; + +void wrap_ray() { + def("distance", distance_ray); + def("are_near", are_near_ray); + def("are_same", Geom::are_same); + def("angle_between", angle_between_ray); + def("angle_between", angle_between_ray_def); + def("make_angle_bisector_ray", Geom::make_angle_bisector_ray); + + class_<Geom::Ray>("Ray", init<Geom::Point, Geom::Coord>()) + .def(init<Geom::Point,Geom::Point>()) + .def(init<>()) + + // TODO: overloaded + //.add_property("origin", get_ray_origin, set_ray_origin) + // .add_property("versor", &Geom::Ray::versor, &Geom::Ray::versor) + // .add_property("angle", &Geom::Ray::angle, &Geom::Ray::angle) + + .def("isDegenerate", &Geom::Ray::isDegenerate) + .def("nearestTime", &Geom::Ray::nearestTime) + .def("setBy2Points", &Geom::Ray::setPoints) + .def("valueAt", &Geom::Ray::valueAt) + .def("pointAt", &Geom::Ray::pointAt) + .def("nearestTime", &Geom::Ray::nearestTime) + .def("reverse", &Geom::Ray::reverse) + .def("roots", &Geom::Ray::roots) + .def("transformed", &Geom::Ray::transformed) + // requires Curve + // .def("portion", &Geom::Ray::portion) + .def("segment", &Geom::Ray::segment) + ; + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/rect.cpp b/src/py2geom/rect.cpp new file mode 100644 index 0000000..3b75625 --- /dev/null +++ b/src/py2geom/rect.cpp @@ -0,0 +1,125 @@ +/* + * Copyright 2008 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/affine.h" +#include "2geom/d2.h" +#include "2geom/interval.h" + +using namespace boost::python; + +static bool wrap_contains_coord(Geom::Rect const &x, Geom::Point val) { + return x.contains(val); +} + +static bool wrap_contains_ivl(Geom::Rect const &x, Geom::Rect val) { + return x.contains(val); +} + +static bool wrap_interiorContains_coord(Geom::Rect const &x, Geom::Point val) { + return x.interiorContains(val); +} + +static bool wrap_interiorContains_ivl(Geom::Rect const &x, Geom::Rect val) { + return x.interiorContains(val); +} + +static void wrap_expandBy_pt(Geom::Rect &x, Geom::Point val) { + x.expandBy(val); +} + +static void wrap_expandBy(Geom::Rect &x, double val) { + x.expandBy(val); +} + +static void wrap_unionWith(Geom::Rect &x, Geom::Rect const &y) { + x.unionWith(y); +} +static bool wrap_intersects(Geom::Rect const &x, Geom::Rect const &y) { + return x.intersects(y); +} + +void wrap_rect() { + //TODO: fix overloads + //def("unify", Geom::unify); + def("union_list", Geom::union_list); + //def("intersect", Geom::intersect); + def("distanceSq", (double (*)( Geom::Point const&, Geom::Rect const& ))Geom::distanceSq); + def("distance", (double (*)( Geom::Point const&, Geom::Rect const& ))Geom::distance); + + class_<Geom::Rect>("Rect", init<Geom::Interval, Geom::Interval>()) + .def(init<Geom::Point,Geom::Point>()) + .def(init<>()) + .def(init<Geom::Rect const &>()) + + .def("__getitem__", python_getitem<Geom::Rect,Geom::Interval,2>) + + .def("min", &Geom::Rect::min) + .def("max", &Geom::Rect::max) + .def("corner", &Geom::Rect::corner) + .def("top", &Geom::Rect::top) + .def("bottom", &Geom::Rect::bottom) + .def("left", &Geom::Rect::left) + .def("right", &Geom::Rect::right) + .def("width", &Geom::Rect::width) + .def("height", &Geom::Rect::height) + .def("dimensions", &Geom::Rect::dimensions) + .def("midpoint", &Geom::Rect::midpoint) + .def("area", &Geom::Rect::area) + .def("maxExtent", &Geom::Rect::maxExtent) + .def("contains", wrap_contains_coord) + .def("contains", wrap_contains_ivl) + .def("interiorContains", wrap_interiorContains_coord) + .def("interiorContains", wrap_interiorContains_ivl) + .def("intersects", wrap_intersects) + .def("expandTo", &Geom::Rect::expandTo) + .def("unionWith", &wrap_unionWith) + // TODO: overloaded + .def("expandBy", wrap_expandBy) + .def("expandBy", wrap_expandBy_pt) + + .def(self * Geom::Affine()) + ; + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/sbasis.cpp b/src/py2geom/sbasis.cpp new file mode 100644 index 0000000..be547ca --- /dev/null +++ b/src/py2geom/sbasis.cpp @@ -0,0 +1,173 @@ +/* + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> +#include <boost/python/implicit.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> + +#include "py2geom.h" +#include "helpers.h" + +#include "2geom/sbasis.h" +#include "2geom/sbasis-math.h" +#include "2geom/point.h" + +using namespace boost::python; + +Geom::SBasis (*truncate_sbasis)(Geom::SBasis const &, unsigned) = &Geom::truncate; +Geom::SBasis (*multiply_sbasis)(Geom::SBasis const &, Geom::SBasis const &) = &Geom::multiply; +Geom::SBasis (*integral_sbasis)(Geom::SBasis const &) = &Geom::integral; +Geom::SBasis (*derivative_sbasis)(Geom::SBasis const &) = &Geom::derivative; + +Geom::Linear sbasis_getitem(Geom::SBasis const& p, int index) +{ + int D = p.size(); + if (index < 0) + { + index = D + index; + } + if ((index < 0) || (index > (D - 1))) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + boost::python::throw_error_already_set(); + } + return p[index]; +} + +int sbasis_len(Geom::SBasis const& p) +{ + return p.size(); +} + +#include "2geom/sbasis-to-bezier.h" +#include "2geom/bezier.h" + +Geom::Bezier sbasis_to_returned_bezier (Geom::SBasis const& sb, size_t sz = 0) { + Geom::Bezier res; + Geom::sbasis_to_bezier(res, sb, sz); + return res; +} + +/*object wrap_bounds_fast(Geom::SBasis const& sb) { + Geom::OptInterval oi = bounds_fast(sb); + return oi?object(*oi):object(); + }*/ + +template <typename T, typename target_type> +object wrap_bounds_fast(T const& sb) { + target_type oi = bounds_fast(sb); + return oi?object(*oi):object(); +} + + +object wrap_bounds_exact(Geom::SBasis const& sb) { + Geom::OptInterval oi = bounds_exact(sb); + return oi?object(*oi):object(); +} + +object wrap_bounds_local(Geom::SBasis const& sb, Geom::Interval const & iv) { + Geom::OptInterval oi = bounds_local(sb, iv); + return oi?object(*oi):object(); +} +void wrap_sbasis() { + //sbasis.h + + def("shift", (Geom::SBasis (*)(Geom::SBasis const &a, int sh))&Geom::shift); + def("truncate", truncate_sbasis); + def("multiply", multiply_sbasis); + def("compose", (Geom::SBasis (*) (Geom::SBasis const &, Geom::SBasis const &))&Geom::compose); + def("integral", integral_sbasis); + def("derivative", derivative_sbasis); + def("min", (Geom::Piecewise<Geom::SBasis> (*)(Geom::SBasis const &, Geom::SBasis const & ))&Geom::min); + def("sqrt", (Geom::SBasis (*)(Geom::SBasis const &, int ))&Geom::sqrt); + def("reciprocal", (Geom::SBasis (*)(Geom::Linear const &, int ))&Geom::reciprocal); + def("divide",(Geom::SBasis (*)(Geom::SBasis const &, Geom::SBasis const &, int )) &Geom::divide); + def("inverse", (Geom::SBasis (*)(Geom::SBasis, int ))&Geom::inverse); + //def("sin", (Geom::SBasis (*)(Geom::SBasis const &, int ))&Geom::sin); + //def("cos", (Geom::SBasis (*)(Geom::SBasis const &, int ))&Geom::cos); + def("reverse", (Geom::SBasis (*)(Geom::SBasis const &))&Geom::reverse); + def("roots", (std::vector<double> (*)(Geom::SBasis const &))&Geom::roots); + def("bounds_fast", &wrap_bounds_fast<Geom::SBasis, Geom::OptInterval>); + def("bounds_exact", &wrap_bounds_exact); + def("bounds_local", &wrap_bounds_local); + def("sbasis_to_bezier", &::sbasis_to_returned_bezier); + + class_<Geom::SBasis>("SBasis", init<double>()) + .def(init<double, double>()) + .def(init<Geom::Linear>()) + .def(self_ns::str(self)) + //TODO: add important vector funcs + .def("__getitem__", &sbasis_getitem) + .def("__len__", &sbasis_len) + + .def("isZero", &Geom::SBasis::isZero) + .def("isFinite", &Geom::SBasis::isFinite) + .def("at0", (double (Geom::SBasis::*)() const) &Geom::SBasis::at0) + .def("at1", (double (Geom::SBasis::*)() const) &Geom::SBasis::at1) + .def("valueAt", &Geom::SBasis::valueAt) + .def("toSBasis", &Geom::SBasis::toSBasis) + + .def("normalize", &Geom::SBasis::normalize) + .def("tailError", &Geom::SBasis::tailError) + .def("truncate", &Geom::SBasis::truncate) + + .def(self + self) + .def(self - self) + .def(self += self) + .def(self -= self) + + .def(self + Geom::Linear()) + .def(self - Geom::Linear()) + .def(self += Geom::Linear()) + .def(self -= Geom::Linear()) + + .def(self + float()) + .def(self - float()) + .def(self += float()) + .def(self -= float()) + + .def(-self) + .def(self * self) + .def(self *= self) + .def(self * float()) + .def(float() * self) + .def(self / float()) + .def(self *= float()) + .def(self /= float()) + ; +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/py2geom/transforms.cpp b/src/py2geom/transforms.cpp new file mode 100644 index 0000000..ea050da --- /dev/null +++ b/src/py2geom/transforms.cpp @@ -0,0 +1,107 @@ +/* + * Copyright 2006, 2007 Aaron Spike <aaron@ekips.org> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + */ + +#include <boost/python.hpp> + +#include "py2geom.h" + +#include "2geom/transforms.h" + +using namespace boost::python; + +//TODO: properly wrap other transforms + +void wrap_transforms() { + class_<Geom::Affine>("Affine", init<double, double, double, double, double, double>()) + .def(init<>()) + .def(init<Geom::Rotate>()) + .def(init<Geom::Scale>()) + .def(init<Geom::Translate>()) + .def(self_ns::str(self)) + .add_property("xAxis",&Geom::Affine::xAxis,&Geom::Affine::setXAxis) + .add_property("yAxis",&Geom::Affine::yAxis,&Geom::Affine::setYAxis) + .add_property("translation",&Geom::Affine::translation,&Geom::Affine::setTranslation) + .def("isTranslation", &Geom::Affine::isTranslation) + .def("isRotation", &Geom::Affine::isRotation) + .def("isScale", &Geom::Affine::isScale) + .def("isUniformScale", &Geom::Affine::isUniformScale) + .def("setIdentity", &Geom::Affine::setIdentity) + .def("inverse", &Geom::Affine::inverse) + .def("det", &Geom::Affine::det) + .def("descrim2", &Geom::Affine::descrim2) + .def("descrim", &Geom::Affine::descrim) + .def("expansionX", &Geom::Affine::expansionX) + .def("expansionY", &Geom::Affine::expansionY) + .def(self * self) + .def(self * other<Geom::Translate>()) + .def(self * other<Geom::Scale>()) + .def(self * other<Geom::Rotate>()) + ; + + class_<Geom::Scale>("Scale", init<double, double>()) + .def(self == self) + .def(self != self) + .def("inverse", &Geom::Scale::inverse) + .def(Geom::Point() * self) + .def(self * self) + .def(self * Geom::Affine()) + ; + + class_<Geom::Translate>("Translate", init<double, double>()) + .def(init<Geom::Point>()) + .def(self == self) + .def(self != self) + .def("inverse", &Geom::Translate::inverse) + .def(Geom::Point() * self) + .def(self * self) + .def(self * other<Geom::Rotate>()) + .def(self * other<Geom::Scale>()) + ; + + class_<Geom::Rotate>("Rotate", init<double>()) + .def(self == self) + .def(self != self) + .def("inverse", &Geom::Rotate::inverse) + .def("from_degrees", &Geom::Rotate::from_degrees) + .staticmethod("from_degrees") + .def(Geom::Point() * self) + .def(self * self) + .def(Geom::Affine() * self) + ; +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : |