diff options
author | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 14:39:34 +0300 |
---|---|---|
committer | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 16:42:24 +0300 |
commit | 77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch) | |
tree | c51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/matplotlib/py2/src/_path_wrapper.cpp | |
parent | dd6d20cadb65582270ac23f4b3b14ae189704b9d (diff) | |
download | ydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz |
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/matplotlib/py2/src/_path_wrapper.cpp')
-rw-r--r-- | contrib/python/matplotlib/py2/src/_path_wrapper.cpp | 900 |
1 files changed, 900 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py2/src/_path_wrapper.cpp b/contrib/python/matplotlib/py2/src/_path_wrapper.cpp new file mode 100644 index 0000000000..08a595e7c4 --- /dev/null +++ b/contrib/python/matplotlib/py2/src/_path_wrapper.cpp @@ -0,0 +1,900 @@ +#include "numpy_cpp.h" + +#include "_path.h" + +#include "py_converters.h" +#include "py_adaptors.h" + +PyObject *convert_polygon_vector(std::vector<Polygon> &polygons) +{ + PyObject *pyresult = PyList_New(polygons.size()); + + for (size_t i = 0; i < polygons.size(); ++i) { + Polygon poly = polygons[i]; + npy_intp dims[2]; + dims[1] = 2; + + dims[0] = (npy_intp)poly.size(); + + numpy::array_view<double, 2> subresult(dims); + memcpy(subresult.data(), &poly[0], sizeof(double) * poly.size() * 2); + + if (PyList_SetItem(pyresult, i, subresult.pyobj())) { + Py_DECREF(pyresult); + return NULL; + } + } + + return pyresult; +} + +const char *Py_point_in_path__doc__ = "point_in_path(x, y, radius, path, trans)"; + +static PyObject *Py_point_in_path(PyObject *self, PyObject *args, PyObject *kwds) +{ + double x, y, r; + py::PathIterator path; + agg::trans_affine trans; + bool result; + + if (!PyArg_ParseTuple(args, + "dddO&O&:point_in_path", + &x, + &y, + &r, + &convert_path, + &path, + &convert_trans_affine, + &trans)) { + return NULL; + } + + CALL_CPP("point_in_path", (result = point_in_path(x, y, r, path, trans))); + + if (result) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +const char *Py_points_in_path__doc__ = "points_in_path(points, radius, path, trans)"; + +static PyObject *Py_points_in_path(PyObject *self, PyObject *args, PyObject *kwds) +{ + numpy::array_view<const double, 2> points; + double r; + py::PathIterator path; + agg::trans_affine trans; + + if (!PyArg_ParseTuple(args, + "O&dO&O&:points_in_path", + &convert_points, + &points, + &r, + &convert_path, + &path, + &convert_trans_affine, + &trans)) { + return NULL; + } + + npy_intp dims[] = { (npy_intp)points.size() }; + numpy::array_view<uint8_t, 1> results(dims); + + CALL_CPP("points_in_path", (points_in_path(points, r, path, trans, results))); + + return results.pyobj(); +} + +const char *Py_point_on_path__doc__ = "point_on_path(x, y, radius, path, trans)"; + +static PyObject *Py_point_on_path(PyObject *self, PyObject *args, PyObject *kwds) +{ + double x, y, r; + py::PathIterator path; + agg::trans_affine trans; + bool result; + + if (!PyArg_ParseTuple(args, + "dddO&O&:point_on_path", + &x, + &y, + &r, + &convert_path, + &path, + &convert_trans_affine, + &trans)) { + return NULL; + } + + CALL_CPP("point_on_path", (result = point_on_path(x, y, r, path, trans))); + + if (result) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +const char *Py_points_on_path__doc__ = "points_on_path(points, radius, path, trans)"; + +static PyObject *Py_points_on_path(PyObject *self, PyObject *args, PyObject *kwds) +{ + numpy::array_view<const double, 2> points; + double r; + py::PathIterator path; + agg::trans_affine trans; + + if (!PyArg_ParseTuple(args, + "O&dO&O&:points_on_path", + &convert_points, + &points, + &r, + &convert_path, + &path, + &convert_trans_affine, + &trans)) { + return NULL; + } + + npy_intp dims[] = { (npy_intp)points.size() }; + numpy::array_view<uint8_t, 1> results(dims); + + CALL_CPP("points_on_path", (points_on_path(points, r, path, trans, results))); + + return results.pyobj(); +} + +const char *Py_get_path_extents__doc__ = "get_path_extents(path, trans)"; + +static PyObject *Py_get_path_extents(PyObject *self, PyObject *args, PyObject *kwds) +{ + py::PathIterator path; + agg::trans_affine trans; + + if (!PyArg_ParseTuple( + args, "O&O&:get_path_extents", &convert_path, &path, &convert_trans_affine, &trans)) { + return NULL; + } + + extent_limits e; + + CALL_CPP("get_path_extents", (reset_limits(e))); + CALL_CPP("get_path_extents", (update_path_extents(path, trans, e))); + + npy_intp dims[] = { 2, 2 }; + numpy::array_view<double, 2> extents(dims); + extents(0, 0) = e.x0; + extents(0, 1) = e.y0; + extents(1, 0) = e.x1; + extents(1, 1) = e.y1; + + return extents.pyobj(); +} + +const char *Py_update_path_extents__doc__ = + "update_path_extents(path, trans, rect, minpos, ignore)"; + +static PyObject *Py_update_path_extents(PyObject *self, PyObject *args, PyObject *kwds) +{ + py::PathIterator path; + agg::trans_affine trans; + agg::rect_d rect; + numpy::array_view<double, 1> minpos; + int ignore; + int changed; + + if (!PyArg_ParseTuple(args, + "O&O&O&O&i:update_path_extents", + &convert_path, + &path, + &convert_trans_affine, + &trans, + &convert_rect, + &rect, + &minpos.converter, + &minpos, + &ignore)) { + return NULL; + } + + if (minpos.dim(0) != 2) { + PyErr_Format(PyExc_ValueError, + "minpos must be of length 2, got %" NPY_INTP_FMT, + minpos.dim(0)); + return NULL; + } + + extent_limits e; + + if (ignore) { + CALL_CPP("update_path_extents", reset_limits(e)); + } else { + if (rect.x1 > rect.x2) { + e.x0 = std::numeric_limits<double>::infinity(); + e.x1 = -std::numeric_limits<double>::infinity(); + } else { + e.x0 = rect.x1; + e.x1 = rect.x2; + } + if (rect.y1 > rect.y2) { + e.y0 = std::numeric_limits<double>::infinity(); + e.y1 = -std::numeric_limits<double>::infinity(); + } else { + e.y0 = rect.y1; + e.y1 = rect.y2; + } + e.xm = minpos(0); + e.ym = minpos(1); + } + + CALL_CPP("update_path_extents", (update_path_extents(path, trans, e))); + + changed = (e.x0 != rect.x1 || e.y0 != rect.y1 || e.x1 != rect.x2 || e.y1 != rect.y2 || + e.xm != minpos(0) || e.ym != minpos(1)); + + npy_intp extentsdims[] = { 2, 2 }; + numpy::array_view<double, 2> outextents(extentsdims); + outextents(0, 0) = e.x0; + outextents(0, 1) = e.y0; + outextents(1, 0) = e.x1; + outextents(1, 1) = e.y1; + + npy_intp minposdims[] = { 2 }; + numpy::array_view<double, 1> outminpos(minposdims); + outminpos(0) = e.xm; + outminpos(1) = e.ym; + + return Py_BuildValue( + "NNi", outextents.pyobj(), outminpos.pyobj(), changed); +} + +const char *Py_get_path_collection_extents__doc__ = "get_path_collection_extents("; + +static PyObject *Py_get_path_collection_extents(PyObject *self, PyObject *args, PyObject *kwds) +{ + agg::trans_affine master_transform; + PyObject *pathsobj; + numpy::array_view<const double, 3> transforms; + numpy::array_view<const double, 2> offsets; + agg::trans_affine offset_trans; + extent_limits e; + + if (!PyArg_ParseTuple(args, + "O&OO&O&O&:get_path_collection_extents", + &convert_trans_affine, + &master_transform, + &pathsobj, + &convert_transforms, + &transforms, + &convert_points, + &offsets, + &convert_trans_affine, + &offset_trans)) { + return NULL; + } + + try + { + py::PathGenerator paths(pathsobj); + + CALL_CPP("get_path_collection_extents", + (get_path_collection_extents( + master_transform, paths, transforms, offsets, offset_trans, e))); + } + catch (const py::exception &) + { + return NULL; + } + + npy_intp dims[] = { 2, 2 }; + numpy::array_view<double, 2> extents(dims); + extents(0, 0) = e.x0; + extents(0, 1) = e.y0; + extents(1, 0) = e.x1; + extents(1, 1) = e.y1; + + return extents.pyobj(); +} + +const char *Py_point_in_path_collection__doc__ = + "point_in_path_collection(x, y, radius, master_transform, paths, transforms, offsets, " + "offset_trans, filled, offset_position)"; + +static PyObject *Py_point_in_path_collection(PyObject *self, PyObject *args, PyObject *kwds) +{ + double x, y, radius; + agg::trans_affine master_transform; + PyObject *pathsobj; + numpy::array_view<const double, 3> transforms; + numpy::array_view<const double, 2> offsets; + agg::trans_affine offset_trans; + int filled; + e_offset_position offset_position; + std::vector<int> result; + + if (!PyArg_ParseTuple(args, + "dddO&OO&O&O&iO&:point_in_path_collection", + &x, + &y, + &radius, + &convert_trans_affine, + &master_transform, + &pathsobj, + &convert_transforms, + &transforms, + &convert_points, + &offsets, + &convert_trans_affine, + &offset_trans, + &filled, + &convert_offset_position, + &offset_position)) { + return NULL; + } + + try + { + py::PathGenerator paths(pathsobj); + + CALL_CPP("point_in_path_collection", + (point_in_path_collection(x, + y, + radius, + master_transform, + paths, + transforms, + offsets, + offset_trans, + filled, + offset_position, + result))); + } + catch (const py::exception &) + { + return NULL; + } + + npy_intp dims[] = {(npy_intp)result.size() }; + numpy::array_view<int, 1> pyresult(dims); + if (result.size() > 0) { + memcpy(pyresult.data(), &result[0], result.size() * sizeof(int)); + } + return pyresult.pyobj(); +} + +const char *Py_path_in_path__doc__ = "path_in_path(path_a, trans_a, path_b, trans_b)"; + +static PyObject *Py_path_in_path(PyObject *self, PyObject *args, PyObject *kwds) +{ + py::PathIterator a; + agg::trans_affine atrans; + py::PathIterator b; + agg::trans_affine btrans; + bool result; + + if (!PyArg_ParseTuple(args, + "O&O&O&O&:path_in_path", + &convert_path, + &a, + &convert_trans_affine, + &atrans, + &convert_path, + &b, + &convert_trans_affine, + &btrans)) { + return NULL; + } + + CALL_CPP("path_in_path", (result = path_in_path(a, atrans, b, btrans))); + + if (result) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +const char *Py_clip_path_to_rect__doc__ = "clip_path_to_rect(path, rect, inside)"; + +static PyObject *Py_clip_path_to_rect(PyObject *self, PyObject *args, PyObject *kwds) +{ + py::PathIterator path; + agg::rect_d rect; + int inside; + std::vector<Polygon> result; + + if (!PyArg_ParseTuple(args, + "O&O&i:clip_path_to_rect", + &convert_path, + &path, + &convert_rect, + &rect, + &inside)) { + return NULL; + } + + CALL_CPP("clip_path_to_rect", (clip_path_to_rect(path, rect, inside, result))); + + return convert_polygon_vector(result); +} + +const char *Py_affine_transform__doc__ = "affine_transform(points, trans)"; + +static PyObject *Py_affine_transform(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *vertices_obj; + agg::trans_affine trans; + + if (!PyArg_ParseTuple(args, + "OO&:affine_transform", + &vertices_obj, + &convert_trans_affine, + &trans)) { + return NULL; + } + + try { + numpy::array_view<double, 2> vertices(vertices_obj); + npy_intp dims[] = { (npy_intp)vertices.size(), 2 }; + numpy::array_view<double, 2> result(dims); + CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result))); + return result.pyobj(); + } catch (py::exception &) { + PyErr_Clear(); + try { + numpy::array_view<double, 1> vertices(vertices_obj); + npy_intp dims[] = { (npy_intp)vertices.size() }; + numpy::array_view<double, 1> result(dims); + CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result))); + return result.pyobj(); + } catch (py::exception &) { + return NULL; + } + } +} + +const char *Py_count_bboxes_overlapping_bbox__doc__ = "count_bboxes_overlapping_bbox(bbox, bboxes)"; + +static PyObject *Py_count_bboxes_overlapping_bbox(PyObject *self, PyObject *args, PyObject *kwds) +{ + agg::rect_d bbox; + numpy::array_view<const double, 3> bboxes; + int result; + + if (!PyArg_ParseTuple(args, + "O&O&:count_bboxes_overlapping_bbox", + &convert_rect, + &bbox, + &convert_bboxes, + &bboxes)) { + return NULL; + } + + CALL_CPP("count_bboxes_overlapping_bbox", + (result = count_bboxes_overlapping_bbox(bbox, bboxes))); + + return PyLong_FromLong(result); +} + +const char *Py_path_intersects_path__doc__ = "path_intersects_path(path1, path2, filled=False)"; + +static PyObject *Py_path_intersects_path(PyObject *self, PyObject *args, PyObject *kwds) +{ + py::PathIterator p1; + py::PathIterator p2; + agg::trans_affine t1; + agg::trans_affine t2; + int filled = 0; + const char *names[] = { "p1", "p2", "filled", NULL }; + bool result; + + if (!PyArg_ParseTupleAndKeywords(args, + kwds, + "O&O&i:path_intersects_path", + (char **)names, + &convert_path, + &p1, + &convert_path, + &p2, + &filled)) { + return NULL; + } + + CALL_CPP("path_intersects_path", (result = path_intersects_path(p1, p2))); + if (filled) { + if (!result) { + CALL_CPP("path_intersects_path", + (result = path_in_path(p1, t1, p2, t2))); + } + if (!result) { + CALL_CPP("path_intersects_path", + (result = path_in_path(p2, t1, p1, t2))); + } + } + + if (result) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +const char *Py_path_intersects_rectangle__doc__ = "path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled=False)"; + +static PyObject *Py_path_intersects_rectangle(PyObject *self, PyObject *args, PyObject *kwds) +{ + py::PathIterator path; + double rect_x1, rect_y1, rect_x2, rect_y2; + int filled = 0; + const char *names[] = { "path", "rect_x1", "rect_y1", "rect_x2", "rect_y2", "filled", NULL }; + bool result; + + if (!PyArg_ParseTupleAndKeywords(args, + kwds, + "O&dddd|i:path_intersects_rectangle", + (char **)names, + &convert_path, + &path, + &rect_x1, + &rect_y1, + &rect_x2, + &rect_y2, + &filled)) { + return NULL; + } + + CALL_CPP("path_intersects_rectangle", (result = path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled))); + + if (result) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +const char *Py_convert_path_to_polygons__doc__ = + "convert_path_to_polygons(path, trans, width=0, height=0)"; + +static PyObject *Py_convert_path_to_polygons(PyObject *self, PyObject *args, PyObject *kwds) +{ + py::PathIterator path; + agg::trans_affine trans; + double width = 0.0, height = 0.0; + int closed_only = 1; + std::vector<Polygon> result; + const char *names[] = { "path", "transform", "width", "height", "closed_only", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, + kwds, + "O&O&|ddi:convert_path_to_polygons", + (char **)names, + &convert_path, + &path, + &convert_trans_affine, + &trans, + &width, + &height, + &closed_only)) { + return NULL; + } + + CALL_CPP("convert_path_to_polygons", + (convert_path_to_polygons(path, trans, width, height, closed_only, result))); + + return convert_polygon_vector(result); +} + +const char *Py_cleanup_path__doc__ = + "cleanup_path(path, trans, remove_nans, clip_rect, snap_mode, stroke_width, simplify, " + "return_curves, sketch)"; + +static PyObject *Py_cleanup_path(PyObject *self, PyObject *args, PyObject *kwds) +{ + py::PathIterator path; + agg::trans_affine trans; + int remove_nans; + agg::rect_d clip_rect; + e_snap_mode snap_mode; + double stroke_width; + PyObject *simplifyobj; + bool simplify = false; + int return_curves; + SketchParams sketch; + + if (!PyArg_ParseTuple(args, + "O&O&iO&O&dOiO&:cleanup_path", + &convert_path, + &path, + &convert_trans_affine, + &trans, + &remove_nans, + &convert_rect, + &clip_rect, + &convert_snap, + &snap_mode, + &stroke_width, + &simplifyobj, + &return_curves, + &convert_sketch_params, + &sketch)) { + return NULL; + } + + if (simplifyobj == Py_None) { + simplify = path.should_simplify(); + } else if (PyObject_IsTrue(simplifyobj)) { + simplify = true; + } + + bool do_clip = (clip_rect.x1 < clip_rect.x2 && clip_rect.y1 < clip_rect.y2); + + std::vector<double> vertices; + std::vector<npy_uint8> codes; + + CALL_CPP("cleanup_path", + (cleanup_path(path, + trans, + remove_nans, + do_clip, + clip_rect, + snap_mode, + stroke_width, + simplify, + return_curves, + sketch, + vertices, + codes))); + + size_t length = codes.size(); + + npy_intp vertices_dims[] = {(npy_intp)length, 2 }; + numpy::array_view<double, 2> pyvertices(vertices_dims); + + npy_intp codes_dims[] = {(npy_intp)length }; + numpy::array_view<unsigned char, 1> pycodes(codes_dims); + + memcpy(pyvertices.data(), &vertices[0], sizeof(double) * 2 * length); + memcpy(pycodes.data(), &codes[0], sizeof(unsigned char) * length); + + return Py_BuildValue("NN", pyvertices.pyobj(), pycodes.pyobj()); +} + +const char *Py_convert_to_string__doc__ = "convert_to_string(path, trans, " + "clip_rect, simplify, sketch, precision, codes, postfix)"; + +static PyObject *Py_convert_to_string(PyObject *self, PyObject *args, PyObject *kwds) +{ + py::PathIterator path; + agg::trans_affine trans; + agg::rect_d cliprect; + PyObject *simplifyobj; + bool simplify = false; + SketchParams sketch; + int precision; + PyObject *codesobj; + char *codes[5]; + int postfix; + char *buffer = NULL; + size_t buffersize; + PyObject *result; + int status; + + if (!PyArg_ParseTuple(args, + "O&O&O&OO&iOi:convert_to_string", + &convert_path, + &path, + &convert_trans_affine, + &trans, + &convert_rect, + &cliprect, + &simplifyobj, + &convert_sketch_params, + &sketch, + &precision, + &codesobj, + &postfix)) { + return NULL; + } + + if (simplifyobj == Py_None) { + simplify = path.should_simplify(); + } else if (PyObject_IsTrue(simplifyobj)) { + simplify = true; + } + + if (!PySequence_Check(codesobj)) { + return NULL; + } + if (PySequence_Size(codesobj) != 5) { + PyErr_SetString( + PyExc_ValueError, + "codes must be a 5-length sequence of byte strings"); + return NULL; + } + for (int i = 0; i < 5; ++i) { + PyObject *item = PySequence_GetItem(codesobj, i); + if (item == NULL) { + return NULL; + } + codes[i] = PyBytes_AsString(item); + if (codes[i] == NULL) { + return NULL; + } + } + + CALL_CPP("convert_to_string", + (status = convert_to_string( + path, trans, cliprect, simplify, sketch, + precision, codes, (bool)postfix, &buffer, + &buffersize))); + + if (status) { + free(buffer); + if (status == 1) { + PyErr_SetString(PyExc_MemoryError, "Memory error"); + } else if (status == 2) { + PyErr_SetString(PyExc_ValueError, "Malformed path codes"); + } + return NULL; + } + + if (buffersize == 0) { + result = PyBytes_FromString(""); + } else { + result = PyBytes_FromStringAndSize(buffer, buffersize); + } + + free(buffer); + + return result; +} + + +const char *Py_is_sorted__doc__ = "is_sorted(array)\n\n" + "Returns True if 1-D array is monotonically increasing, ignoring NaNs\n"; + +static PyObject *Py_is_sorted(PyObject *self, PyObject *obj) +{ + npy_intp size; + bool result; + + PyArrayObject *array = (PyArrayObject *)PyArray_FromAny( + obj, NULL, 1, 1, 0, NULL); + + if (array == NULL) { + return NULL; + } + + size = PyArray_DIM(array, 0); + + if (size < 2) { + Py_DECREF(array); + Py_RETURN_TRUE; + } + + /* Handle just the most common types here, otherwise coerce to + double */ + switch(PyArray_TYPE(array)) { + case NPY_INT: + { + _is_sorted_int<npy_int> is_sorted; + result = is_sorted(array); + } + break; + + case NPY_LONG: + { + _is_sorted_int<npy_long> is_sorted; + result = is_sorted(array); + } + break; + + case NPY_LONGLONG: + { + _is_sorted_int<npy_longlong> is_sorted; + result = is_sorted(array); + } + break; + + case NPY_FLOAT: + { + _is_sorted<npy_float> is_sorted; + result = is_sorted(array); + } + break; + + case NPY_DOUBLE: + { + _is_sorted<npy_double> is_sorted; + result = is_sorted(array); + } + break; + + default: + { + Py_DECREF(array); + array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1); + + if (array == NULL) { + return NULL; + } + + _is_sorted<npy_double> is_sorted; + result = is_sorted(array); + } + } + + Py_DECREF(array); + + if (result) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + + +extern "C" { + + static PyMethodDef module_functions[] = { + {"point_in_path", (PyCFunction)Py_point_in_path, METH_VARARGS, Py_point_in_path__doc__}, + {"points_in_path", (PyCFunction)Py_points_in_path, METH_VARARGS, Py_points_in_path__doc__}, + {"point_on_path", (PyCFunction)Py_point_on_path, METH_VARARGS, Py_point_on_path__doc__}, + {"points_on_path", (PyCFunction)Py_points_on_path, METH_VARARGS, Py_points_on_path__doc__}, + {"get_path_extents", (PyCFunction)Py_get_path_extents, METH_VARARGS, Py_get_path_extents__doc__}, + {"update_path_extents", (PyCFunction)Py_update_path_extents, METH_VARARGS, Py_update_path_extents__doc__}, + {"get_path_collection_extents", (PyCFunction)Py_get_path_collection_extents, METH_VARARGS, Py_get_path_collection_extents__doc__}, + {"point_in_path_collection", (PyCFunction)Py_point_in_path_collection, METH_VARARGS, Py_point_in_path_collection__doc__}, + {"path_in_path", (PyCFunction)Py_path_in_path, METH_VARARGS, Py_path_in_path__doc__}, + {"clip_path_to_rect", (PyCFunction)Py_clip_path_to_rect, METH_VARARGS, Py_clip_path_to_rect__doc__}, + {"affine_transform", (PyCFunction)Py_affine_transform, METH_VARARGS, Py_affine_transform__doc__}, + {"count_bboxes_overlapping_bbox", (PyCFunction)Py_count_bboxes_overlapping_bbox, METH_VARARGS, Py_count_bboxes_overlapping_bbox__doc__}, + {"path_intersects_path", (PyCFunction)Py_path_intersects_path, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_path__doc__}, + {"path_intersects_rectangle", (PyCFunction)Py_path_intersects_rectangle, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_rectangle__doc__}, + {"convert_path_to_polygons", (PyCFunction)Py_convert_path_to_polygons, METH_VARARGS|METH_KEYWORDS, Py_convert_path_to_polygons__doc__}, + {"cleanup_path", (PyCFunction)Py_cleanup_path, METH_VARARGS, Py_cleanup_path__doc__}, + {"convert_to_string", (PyCFunction)Py_convert_to_string, METH_VARARGS, Py_convert_to_string__doc__}, + {"is_sorted", (PyCFunction)Py_is_sorted, METH_O, Py_is_sorted__doc__}, + {NULL} + }; + +#if PY3K + static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_path", + NULL, + 0, + module_functions, + NULL, + NULL, + NULL, + NULL + }; + +#define INITERROR return NULL + PyMODINIT_FUNC PyInit__path(void) +#else +#define INITERROR return + PyMODINIT_FUNC init_path(void) +#endif + { + PyObject *m; +#if PY3K + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule3("_path", module_functions, NULL); +#endif + + if (m == NULL) { + INITERROR; + } + + import_array(); + +#if PY3K + return m; +#endif + } +} |