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

Skip to content

Commit 6dc5a08

Browse files
committed
Add a pybind11 type caster for agg::trans_affine
1 parent 362b102 commit 6dc5a08

2 files changed

Lines changed: 42 additions & 42 deletions

File tree

src/_path_wrapper.cpp

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -38,34 +38,30 @@ convert_polygon_vector(std::vector<Polygon> &polygons)
3838

3939
static bool
4040
Py_point_in_path(double x, double y, double r, py::object path_obj,
41-
py::object trans_obj)
41+
agg::trans_affine trans)
4242
{
4343
mpl::PathIterator path;
44-
agg::trans_affine trans;
4544

4645
if (!convert_path(path_obj.ptr(), &path)) {
4746
throw py::error_already_set();
4847
}
49-
convert_trans_affine(trans_obj, trans);
5048

5149
return point_in_path(x, y, r, path, trans);
5250
}
5351

5452
static py::array_t<double>
5553
Py_points_in_path(py::array_t<double> points_obj, double r, py::object path_obj,
56-
py::object trans_obj)
54+
agg::trans_affine trans)
5755
{
5856
numpy::array_view<double, 2> points;
5957
mpl::PathIterator path;
60-
agg::trans_affine trans;
6158

6259
if (!convert_points(points_obj.ptr(), &points)) {
6360
throw py::error_already_set();
6461
}
6562
if (!convert_path(path_obj.ptr(), &path)) {
6663
throw py::error_already_set();
6764
}
68-
convert_trans_affine(trans_obj, trans);
6965

7066
if (!check_trailing_shape(points, "points", 2)) {
7167
throw py::error_already_set();
@@ -81,17 +77,15 @@ Py_points_in_path(py::array_t<double> points_obj, double r, py::object path_obj,
8177
}
8278

8379
static py::tuple
84-
Py_update_path_extents(py::object path_obj, py::object trans_obj, agg::rect_d rect,
80+
Py_update_path_extents(py::object path_obj, agg::trans_affine trans, agg::rect_d rect,
8581
py::array_t<double> minpos, bool ignore)
8682
{
8783
mpl::PathIterator path;
88-
agg::trans_affine trans;
8984
bool changed;
9085

9186
if (!convert_path(path_obj.ptr(), &path)) {
9287
throw py::error_already_set();
9388
}
94-
convert_trans_affine(trans_obj, trans);
9589

9690
if (minpos.ndim() != 1) {
9791
throw py::value_error(
@@ -146,18 +140,15 @@ Py_update_path_extents(py::object path_obj, py::object trans_obj, agg::rect_d re
146140
}
147141

148142
static py::tuple
149-
Py_get_path_collection_extents(py::object master_transform_obj, py::object paths_obj,
150-
py::object transforms_obj, py::object offsets_obj,
151-
py::object offset_trans_obj)
143+
Py_get_path_collection_extents(agg::trans_affine master_transform,
144+
py::object paths_obj, py::object transforms_obj,
145+
py::object offsets_obj, agg::trans_affine offset_trans)
152146
{
153-
agg::trans_affine master_transform;
154147
mpl::PathGenerator paths;
155148
numpy::array_view<const double, 3> transforms;
156149
numpy::array_view<const double, 2> offsets;
157-
agg::trans_affine offset_trans;
158150
extent_limits e;
159151

160-
convert_trans_affine(master_transform_obj, master_transform);
161152
if (!convert_pathgen(paths_obj.ptr(), &paths)) {
162153
throw py::error_already_set();
163154
}
@@ -167,7 +158,6 @@ Py_get_path_collection_extents(py::object master_transform_obj, py::object paths
167158
if (!convert_points(offsets_obj.ptr(), &offsets)) {
168159
throw py::error_already_set();
169160
}
170-
convert_trans_affine(offset_trans_obj, offset_trans);
171161

172162
get_path_collection_extents(
173163
master_transform, paths, transforms, offsets, offset_trans, e);
@@ -189,18 +179,15 @@ Py_get_path_collection_extents(py::object master_transform_obj, py::object paths
189179

190180
static py::object
191181
Py_point_in_path_collection(double x, double y, double radius,
192-
py::object master_transform_obj, py::object paths_obj,
182+
agg::trans_affine master_transform, py::object paths_obj,
193183
py::object transforms_obj, py::object offsets_obj,
194-
py::object offset_trans_obj, bool filled)
184+
agg::trans_affine offset_trans, bool filled)
195185
{
196-
agg::trans_affine master_transform;
197186
mpl::PathGenerator paths;
198187
numpy::array_view<const double, 3> transforms;
199188
numpy::array_view<const double, 2> offsets;
200-
agg::trans_affine offset_trans;
201189
std::vector<int> result;
202190

203-
convert_trans_affine(master_transform_obj, master_transform);
204191
if (!convert_pathgen(paths_obj.ptr(), &paths)) {
205192
throw py::error_already_set();
206193
}
@@ -210,7 +197,6 @@ Py_point_in_path_collection(double x, double y, double radius,
210197
if (!convert_points(offsets_obj.ptr(), &offsets)) {
211198
throw py::error_already_set();
212199
}
213-
convert_trans_affine(offset_trans_obj, offset_trans);
214200

215201
point_in_path_collection(x, y, radius, master_transform, paths, transforms, offsets,
216202
offset_trans, filled, result);
@@ -224,22 +210,18 @@ Py_point_in_path_collection(double x, double y, double radius,
224210
}
225211

226212
static bool
227-
Py_path_in_path(py::object a_obj, py::object atrans_obj,
228-
py::object b_obj, py::object btrans_obj)
213+
Py_path_in_path(py::object a_obj, agg::trans_affine atrans,
214+
py::object b_obj, agg::trans_affine btrans)
229215
{
230216
mpl::PathIterator a;
231-
agg::trans_affine atrans;
232217
mpl::PathIterator b;
233-
agg::trans_affine btrans;
234218

235219
if (!convert_path(a_obj.ptr(), &a)) {
236220
throw py::error_already_set();
237221
}
238-
convert_trans_affine(atrans_obj, atrans);
239222
if (!convert_path(b_obj.ptr(), &b)) {
240223
throw py::error_already_set();
241224
}
242-
convert_trans_affine(btrans_obj, btrans);
243225

244226
return path_in_path(a, atrans, b, btrans);
245227
}
@@ -261,12 +243,8 @@ Py_clip_path_to_rect(py::object path_obj, agg::rect_d rect, bool inside)
261243

262244
static py::object
263245
Py_affine_transform(py::array_t<double, py::array::c_style | py::array::forcecast> vertices_arr,
264-
py::object trans_obj)
246+
agg::trans_affine trans)
265247
{
266-
agg::trans_affine trans;
267-
268-
convert_trans_affine(trans_obj, trans);
269-
270248
if (vertices_arr.ndim() == 2) {
271249
auto vertices = vertices_arr.unchecked<2>();
272250

@@ -350,37 +328,33 @@ Py_path_intersects_rectangle(py::object path_obj, double rect_x1, double rect_y1
350328
}
351329

352330
static py::list
353-
Py_convert_path_to_polygons(py::object path_obj, py::object trans_obj,
331+
Py_convert_path_to_polygons(py::object path_obj, agg::trans_affine trans,
354332
double width, double height, bool closed_only)
355333
{
356334
mpl::PathIterator path;
357-
agg::trans_affine trans;
358335
std::vector<Polygon> result;
359336

360337
if (!convert_path(path_obj.ptr(), &path)) {
361338
throw py::error_already_set();
362339
}
363-
convert_trans_affine(trans_obj, trans);
364340

365341
convert_path_to_polygons(path, trans, width, height, closed_only, result);
366342

367343
return convert_polygon_vector(result);
368344
}
369345

370346
static py::tuple
371-
Py_cleanup_path(py::object path_obj, py::object trans_obj, bool remove_nans,
347+
Py_cleanup_path(py::object path_obj, agg::trans_affine trans, bool remove_nans,
372348
agg::rect_d clip_rect, py::object snap_mode_obj, double stroke_width,
373349
std::optional<bool> simplify, bool return_curves, py::object sketch_obj)
374350
{
375351
mpl::PathIterator path;
376-
agg::trans_affine trans;
377352
e_snap_mode snap_mode;
378353
SketchParams sketch;
379354

380355
if (!convert_path(path_obj.ptr(), &path)) {
381356
throw py::error_already_set();
382357
}
383-
convert_trans_affine(trans_obj, trans);
384358
if (!convert_snap(snap_mode_obj.ptr(), &snap_mode)) {
385359
throw py::error_already_set();
386360
}
@@ -443,12 +417,11 @@ postfix : bool
443417
)""";
444418

445419
static py::object
446-
Py_convert_to_string(py::object path_obj, py::object trans_obj, agg::rect_d cliprect,
420+
Py_convert_to_string(py::object path_obj, agg::trans_affine trans, agg::rect_d cliprect,
447421
std::optional<bool> simplify, py::object sketch_obj, int precision,
448422
std::array<std::string, 5> codes_obj, bool postfix)
449423
{
450424
mpl::PathIterator path;
451-
agg::trans_affine trans;
452425
SketchParams sketch;
453426
char *codes[5];
454427
std::string buffer;
@@ -457,7 +430,6 @@ Py_convert_to_string(py::object path_obj, py::object trans_obj, agg::rect_d clip
457430
if (!convert_path(path_obj.ptr(), &path)) {
458431
throw py::error_already_set();
459432
}
460-
convert_trans_affine(trans_obj, trans);
461433
if (!convert_sketch_params(sketch_obj.ptr(), &sketch)) {
462434
throw py::error_already_set();
463435
}

src/py_converters_11.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,34 @@ namespace PYBIND11_NAMESPACE { namespace detail {
5656
return true;
5757
}
5858
};
59+
60+
template <> struct type_caster<agg::trans_affine> {
61+
public:
62+
PYBIND11_TYPE_CASTER(agg::trans_affine, const_name("trans_affine"));
63+
64+
bool load(handle src, bool) {
65+
// If None assume identity transform so leave affine unchanged
66+
if (src.is_none()) {
67+
return true;
68+
}
69+
70+
auto array = py::array_t<double, py::array::c_style>::ensure(src);
71+
if (!array || array.ndim() != 2 ||
72+
array.shape(0) != 3 || array.shape(1) != 3) {
73+
throw std::invalid_argument("Invalid affine transformation matrix");
74+
}
75+
76+
auto buffer = array.data();
77+
value.sx = buffer[0];
78+
value.shx = buffer[1];
79+
value.tx = buffer[2];
80+
value.shy = buffer[3];
81+
value.sy = buffer[4];
82+
value.ty = buffer[5];
83+
84+
return true;
85+
}
86+
};
5987
}} // namespace PYBIND11_NAMESPACE::detail
6088

6189
#endif /* MPL_PY_CONVERTERS_11_H */

0 commit comments

Comments
 (0)