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

Skip to content

Commit d32a372

Browse files
committed
Add a pybind11 type caster for mpl::PathIterator
1 parent 4a56e52 commit d32a372

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;
@@ -33,31 +33,21 @@ convert_polygon_vector(std::vector<Polygon> &polygons)
3333
}
3434

3535
static bool
36-
Py_point_in_path(double x, double y, double r, py::object path_obj,
36+
Py_point_in_path(double x, double y, double r, mpl::PathIterator path,
3737
agg::trans_affine trans)
3838
{
39-
mpl::PathIterator path;
40-
41-
if (!convert_path(path_obj.ptr(), &path)) {
42-
throw py::error_already_set();
43-
}
44-
4539
return point_in_path(x, y, r, path, trans);
4640
}
4741

4842
static py::array_t<double>
49-
Py_points_in_path(py::array_t<double> points_obj, double r, py::object path_obj,
43+
Py_points_in_path(py::array_t<double> points_obj, double r, mpl::PathIterator path,
5044
agg::trans_affine trans)
5145
{
5246
numpy::array_view<double, 2> points;
53-
mpl::PathIterator path;
5447

5548
if (!convert_points(points_obj.ptr(), &points)) {
5649
throw py::error_already_set();
5750
}
58-
if (!convert_path(path_obj.ptr(), &path)) {
59-
throw py::error_already_set();
60-
}
6151

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

7565
static py::tuple
76-
Py_update_path_extents(py::object path_obj, agg::trans_affine trans, agg::rect_d rect,
77-
py::array_t<double> minpos, bool ignore)
66+
Py_update_path_extents(mpl::PathIterator path, agg::trans_affine trans,
67+
agg::rect_d rect, py::array_t<double> minpos, bool ignore)
7868
{
79-
mpl::PathIterator path;
8069
bool changed;
8170

82-
if (!convert_path(path_obj.ptr(), &path)) {
83-
throw py::error_already_set();
84-
}
85-
8671
if (minpos.ndim() != 1) {
8772
throw py::value_error(
8873
"minpos must be 1D, got " + std::to_string(minpos.ndim()));
@@ -202,32 +187,17 @@ Py_point_in_path_collection(double x, double y, double radius,
202187
}
203188

204189
static bool
205-
Py_path_in_path(py::object a_obj, agg::trans_affine atrans,
206-
py::object b_obj, agg::trans_affine btrans)
190+
Py_path_in_path(mpl::PathIterator a, agg::trans_affine atrans,
191+
mpl::PathIterator b, agg::trans_affine btrans)
207192
{
208-
mpl::PathIterator a;
209-
mpl::PathIterator b;
210-
211-
if (!convert_path(a_obj.ptr(), &a)) {
212-
throw py::error_already_set();
213-
}
214-
if (!convert_path(b_obj.ptr(), &b)) {
215-
throw py::error_already_set();
216-
}
217-
218193
return path_in_path(a, atrans, b, btrans);
219194
}
220195

221196
static py::list
222-
Py_clip_path_to_rect(py::object path_obj, agg::rect_d rect, bool inside)
197+
Py_clip_path_to_rect(mpl::PathIterator path, agg::rect_d rect, bool inside)
223198
{
224-
mpl::PathIterator path;
225199
std::vector<Polygon> result;
226200

227-
if (!convert_path(path_obj.ptr(), &path)) {
228-
throw py::error_already_set();
229-
}
230-
231201
clip_path_to_rect(path, rect, inside, result);
232202

233203
return convert_polygon_vector(result);
@@ -278,21 +248,12 @@ Py_count_bboxes_overlapping_bbox(agg::rect_d bbox, py::object bboxes_obj)
278248
}
279249

280250
static bool
281-
Py_path_intersects_path(py::object p1_obj, py::object p2_obj, bool filled)
251+
Py_path_intersects_path(mpl::PathIterator p1, mpl::PathIterator p2, bool filled)
282252
{
283-
mpl::PathIterator p1;
284-
mpl::PathIterator p2;
285253
agg::trans_affine t1;
286254
agg::trans_affine t2;
287255
bool result;
288256

289-
if (!convert_path(p1_obj.ptr(), &p1)) {
290-
throw py::error_already_set();
291-
}
292-
if (!convert_path(p2_obj.ptr(), &p2)) {
293-
throw py::error_already_set();
294-
}
295-
296257
result = path_intersects_path(p1, p2);
297258
if (filled) {
298259
if (!result) {
@@ -307,46 +268,31 @@ Py_path_intersects_path(py::object p1_obj, py::object p2_obj, bool filled)
307268
}
308269

309270
static bool
310-
Py_path_intersects_rectangle(py::object path_obj, double rect_x1, double rect_y1,
271+
Py_path_intersects_rectangle(mpl::PathIterator path, double rect_x1, double rect_y1,
311272
double rect_x2, double rect_y2, bool filled)
312273
{
313-
mpl::PathIterator path;
314-
315-
if (!convert_path(path_obj.ptr(), &path)) {
316-
throw py::error_already_set();
317-
}
318-
319274
return path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled);
320275
}
321276

322277
static py::list
323-
Py_convert_path_to_polygons(py::object path_obj, agg::trans_affine trans,
278+
Py_convert_path_to_polygons(mpl::PathIterator path, agg::trans_affine trans,
324279
double width, double height, bool closed_only)
325280
{
326-
mpl::PathIterator path;
327281
std::vector<Polygon> result;
328282

329-
if (!convert_path(path_obj.ptr(), &path)) {
330-
throw py::error_already_set();
331-
}
332-
333283
convert_path_to_polygons(path, trans, width, height, closed_only, result);
334284

335285
return convert_polygon_vector(result);
336286
}
337287

338288
static py::tuple
339-
Py_cleanup_path(py::object path_obj, agg::trans_affine trans, bool remove_nans,
289+
Py_cleanup_path(mpl::PathIterator path, agg::trans_affine trans, bool remove_nans,
340290
agg::rect_d clip_rect, py::object snap_mode_obj, double stroke_width,
341291
std::optional<bool> simplify, bool return_curves, py::object sketch_obj)
342292
{
343-
mpl::PathIterator path;
344293
e_snap_mode snap_mode;
345294
SketchParams sketch;
346295

347-
if (!convert_path(path_obj.ptr(), &path)) {
348-
throw py::error_already_set();
349-
}
350296
if (!convert_snap(snap_mode_obj.ptr(), &snap_mode)) {
351297
throw py::error_already_set();
352298
}
@@ -406,19 +352,16 @@ postfix : bool
406352
)""";
407353

408354
static py::object
409-
Py_convert_to_string(py::object path_obj, agg::trans_affine trans, agg::rect_d cliprect,
410-
std::optional<bool> simplify, py::object sketch_obj, int precision,
355+
Py_convert_to_string(mpl::PathIterator path, agg::trans_affine trans,
356+
agg::rect_d cliprect, std::optional<bool> simplify,
357+
py::object sketch_obj, int precision,
411358
std::array<std::string, 5> codes_obj, bool postfix)
412359
{
413-
mpl::PathIterator path;
414360
SketchParams sketch;
415361
char *codes[5];
416362
std::string buffer;
417363
bool status;
418364

419-
if (!convert_path(path_obj.ptr(), &path)) {
420-
throw py::error_already_set();
421-
}
422365
if (!convert_sketch_params(sketch_obj.ptr(), &sketch)) {
423366
throw py::error_already_set();
424367
}

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 include `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 = src.attr("should_simplify").cast<bool>();
102+
auto simplify_threshold = src.attr("simplify_threshold").cast<double>();
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)