Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 80aaf64

Browse files
committed
Add a pybind11 type caster for mpl::PathIterator
1 parent 1be96aa commit 80aaf64

File tree

2 files changed

+41
-72
lines changed

2 files changed

+41
-72
lines changed

src/_path_wrapper.cpp

Lines changed: 15 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
#include "_path.h"
1313

14+
#include "py_adaptors.h"
1415
#include "py_converters.h"
1516
#include "py_converters_11.h"
16-
#include "py_adaptors.h"
1717

1818
namespace py = pybind11;
1919
using namespace pybind11::literals;
@@ -43,31 +43,21 @@ convert_polygon_vector(std::vector<Polygon> &polygons)
4343
}
4444

4545
static bool
46-
Py_point_in_path(double x, double y, double r, py::object path_obj,
46+
Py_point_in_path(double x, double y, double r, mpl::PathIterator path,
4747
agg::trans_affine trans)
4848
{
49-
mpl::PathIterator path;
50-
51-
if (!convert_path(path_obj.ptr(), &path)) {
52-
throw py::error_already_set();
53-
}
54-
5549
return point_in_path(x, y, r, path, trans);
5650
}
5751

5852
static py::array_t<double>
59-
Py_points_in_path(py::array_t<double> points_obj, double r, py::object path_obj,
53+
Py_points_in_path(py::array_t<double> points_obj, double r, mpl::PathIterator path,
6054
agg::trans_affine trans)
6155
{
6256
numpy::array_view<double, 2> points;
63-
mpl::PathIterator path;
6457

6558
if (!convert_points(points_obj.ptr(), &points)) {
6659
throw py::error_already_set();
6760
}
68-
if (!convert_path(path_obj.ptr(), &path)) {
69-
throw py::error_already_set();
70-
}
7161

7262
if (!check_trailing_shape(points, "points", 2)) {
7363
throw py::error_already_set();
@@ -83,16 +73,11 @@ Py_points_in_path(py::array_t<double> points_obj, double r, py::object path_obj,
8373
}
8474

8575
static py::tuple
86-
Py_update_path_extents(py::object path_obj, agg::trans_affine trans, agg::rect_d rect,
87-
py::array_t<double> minpos, bool ignore)
76+
Py_update_path_extents(mpl::PathIterator path, agg::trans_affine trans,
77+
agg::rect_d rect, py::array_t<double> minpos, bool ignore)
8878
{
89-
mpl::PathIterator path;
9079
bool changed;
9180

92-
if (!convert_path(path_obj.ptr(), &path)) {
93-
throw py::error_already_set();
94-
}
95-
9681
if (minpos.ndim() != 1) {
9782
throw py::value_error(
9883
"minpos must be of 1D, got " + std::to_string(minpos.ndim()));
@@ -216,32 +201,17 @@ Py_point_in_path_collection(double x, double y, double radius,
216201
}
217202

218203
static bool
219-
Py_path_in_path(py::object a_obj, agg::trans_affine atrans,
220-
py::object b_obj, agg::trans_affine btrans)
204+
Py_path_in_path(mpl::PathIterator a, agg::trans_affine atrans,
205+
mpl::PathIterator b, agg::trans_affine btrans)
221206
{
222-
mpl::PathIterator a;
223-
mpl::PathIterator b;
224-
225-
if (!convert_path(a_obj.ptr(), &a)) {
226-
throw py::error_already_set();
227-
}
228-
if (!convert_path(b_obj.ptr(), &b)) {
229-
throw py::error_already_set();
230-
}
231-
232207
return path_in_path(a, atrans, b, btrans);
233208
}
234209

235210
static py::object
236-
Py_clip_path_to_rect(py::object path_obj, agg::rect_d rect, bool inside)
211+
Py_clip_path_to_rect(mpl::PathIterator path, agg::rect_d rect, bool inside)
237212
{
238-
mpl::PathIterator path;
239213
std::vector<Polygon> result;
240214

241-
if (!convert_path(path_obj.ptr(), &path)) {
242-
throw py::error_already_set();
243-
}
244-
245215
clip_path_to_rect(path, rect, inside, result);
246216

247217
return convert_polygon_vector(result);
@@ -292,21 +262,12 @@ Py_count_bboxes_overlapping_bbox(agg::rect_d bbox, py::object bboxes_obj)
292262
}
293263

294264
static bool
295-
Py_path_intersects_path(py::object p1_obj, py::object p2_obj, bool filled)
265+
Py_path_intersects_path(mpl::PathIterator p1, mpl::PathIterator p2, bool filled)
296266
{
297-
mpl::PathIterator p1;
298-
mpl::PathIterator p2;
299267
agg::trans_affine t1;
300268
agg::trans_affine t2;
301269
bool result;
302270

303-
if (!convert_path(p1_obj.ptr(), &p1)) {
304-
throw py::error_already_set();
305-
}
306-
if (!convert_path(p2_obj.ptr(), &p2)) {
307-
throw py::error_already_set();
308-
}
309-
310271
result = path_intersects_path(p1, p2);
311272
if (filled) {
312273
if (!result) {
@@ -321,46 +282,31 @@ Py_path_intersects_path(py::object p1_obj, py::object p2_obj, bool filled)
321282
}
322283

323284
static bool
324-
Py_path_intersects_rectangle(py::object path_obj, double rect_x1, double rect_y1,
285+
Py_path_intersects_rectangle(mpl::PathIterator path, double rect_x1, double rect_y1,
325286
double rect_x2, double rect_y2, bool filled)
326287
{
327-
mpl::PathIterator path;
328-
329-
if (!convert_path(path_obj.ptr(), &path)) {
330-
throw py::error_already_set();
331-
}
332-
333288
return path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled);
334289
}
335290

336291
static py::object
337-
Py_convert_path_to_polygons(py::object path_obj, agg::trans_affine trans,
292+
Py_convert_path_to_polygons(mpl::PathIterator path, agg::trans_affine trans,
338293
double width, double height, bool closed_only)
339294
{
340-
mpl::PathIterator path;
341295
std::vector<Polygon> result;
342296

343-
if (!convert_path(path_obj.ptr(), &path)) {
344-
throw py::error_already_set();
345-
}
346-
347297
convert_path_to_polygons(path, trans, width, height, closed_only, result);
348298

349299
return convert_polygon_vector(result);
350300
}
351301

352302
static py::tuple
353-
Py_cleanup_path(py::object path_obj, agg::trans_affine trans, bool remove_nans,
303+
Py_cleanup_path(mpl::PathIterator path, agg::trans_affine trans, bool remove_nans,
354304
agg::rect_d clip_rect, py::object snap_mode_obj, double stroke_width,
355305
std::optional<bool> simplify, bool return_curves, py::object sketch_obj)
356306
{
357-
mpl::PathIterator path;
358307
e_snap_mode snap_mode;
359308
SketchParams sketch;
360309

361-
if (!convert_path(path_obj.ptr(), &path)) {
362-
throw py::error_already_set();
363-
}
364310
if (!convert_snap(snap_mode_obj.ptr(), &snap_mode)) {
365311
throw py::error_already_set();
366312
}
@@ -423,19 +369,16 @@ postfix : bool
423369
)""";
424370

425371
static py::object
426-
Py_convert_to_string(py::object path_obj, agg::trans_affine trans, agg::rect_d cliprect,
427-
std::optional<bool> simplify, py::object sketch_obj, int precision,
372+
Py_convert_to_string(mpl::PathIterator path, agg::trans_affine trans,
373+
agg::rect_d cliprect, std::optional<bool> simplify,
374+
py::object sketch_obj, int precision,
428375
std::array<std::string, 5> codes_obj, bool postfix)
429376
{
430-
mpl::PathIterator path;
431377
SketchParams sketch;
432378
char *codes[5];
433379
std::string buffer;
434380
bool status;
435381

436-
if (!convert_path(path_obj.ptr(), &path)) {
437-
throw py::error_already_set();
438-
}
439382
if (!convert_sketch_params(sketch_obj.ptr(), &sketch)) {
440383
throw py::error_already_set();
441384
}

src/py_converters_11.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,32 @@ namespace PYBIND11_NAMESPACE { namespace detail {
8484
return true;
8585
}
8686
};
87+
88+
/* Remove all this macro magic after dropping NumPy usage and just import `py_adaptors.h`. */
89+
#ifdef MPL_PY_ADAPTORS_H
90+
template <> struct type_caster<mpl::PathIterator> {
91+
public:
92+
PYBIND11_TYPE_CASTER(mpl::PathIterator, const_name("PathIterator"));
93+
94+
bool load(handle src, bool) {
95+
if (src.is_none()) {
96+
return true;
97+
}
98+
99+
auto vertices = src.attr("vertices");
100+
auto codes = src.attr("codes");
101+
auto should_simplify = py::cast<bool>(src.attr("should_simplify"));
102+
auto simplify_threshold = py::cast<double>(src.attr("simplify_threshold"));
103+
104+
if (!value.set(vertices.ptr(), codes.ptr(),
105+
should_simplify, simplify_threshold)) {
106+
return false;
107+
}
108+
109+
return true;
110+
}
111+
};
112+
#endif
87113
}} // namespace PYBIND11_NAMESPACE::detail
88114

89115
#endif /* MPL_PY_CONVERTERS_11_H */

0 commit comments

Comments
 (0)