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

Skip to content

Commit add390d

Browse files
committed
Add a pybind11 type caster for agg::trans_affine
1 parent 73e3b08 commit add390d

File tree

2 files changed

+43
-43
lines changed

2 files changed

+43
-43
lines changed

src/_path_wrapper.cpp

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -44,34 +44,30 @@ convert_polygon_vector(std::vector<Polygon> &polygons)
4444

4545
static bool
4646
Py_point_in_path(double x, double y, double r, py::object path_obj,
47-
py::object trans_obj)
47+
agg::trans_affine trans)
4848
{
4949
mpl::PathIterator path;
50-
agg::trans_affine trans;
5150

5251
if (!convert_path(path_obj.ptr(), &path)) {
5352
throw py::error_already_set();
5453
}
55-
convert_trans_affine(trans_obj, trans);
5654

5755
return point_in_path(x, y, r, path, trans);
5856
}
5957

6058
static py::array_t<double>
6159
Py_points_in_path(py::array_t<double> points_obj, double r, py::object path_obj,
62-
py::object trans_obj)
60+
agg::trans_affine trans)
6361
{
6462
numpy::array_view<double, 2> points;
6563
mpl::PathIterator path;
66-
agg::trans_affine trans;
6764

6865
if (!convert_points(points_obj.ptr(), &points)) {
6966
throw py::error_already_set();
7067
}
7168
if (!convert_path(path_obj.ptr(), &path)) {
7269
throw py::error_already_set();
7370
}
74-
convert_trans_affine(trans_obj, trans);
7571

7672
if (!check_trailing_shape(points, "points", 2)) {
7773
throw py::error_already_set();
@@ -87,17 +83,15 @@ Py_points_in_path(py::array_t<double> points_obj, double r, py::object path_obj,
8783
}
8884

8985
static py::tuple
90-
Py_update_path_extents(py::object path_obj, py::object trans_obj, agg::rect_d rect,
86+
Py_update_path_extents(py::object path_obj, agg::trans_affine trans, agg::rect_d rect,
9187
py::array_t<double> minpos, bool ignore)
9288
{
9389
mpl::PathIterator path;
94-
agg::trans_affine trans;
9590
bool changed;
9691

9792
if (!convert_path(path_obj.ptr(), &path)) {
9893
throw py::error_already_set();
9994
}
100-
convert_trans_affine(trans_obj, trans);
10195

10296
if (minpos.ndim() != 1) {
10397
throw py::value_error(
@@ -152,18 +146,15 @@ Py_update_path_extents(py::object path_obj, py::object trans_obj, agg::rect_d re
152146
}
153147

154148
static py::tuple
155-
Py_get_path_collection_extents(py::object master_transform_obj, py::object paths_obj,
156-
py::object transforms_obj, py::object offsets_obj,
157-
py::object offset_trans_obj)
149+
Py_get_path_collection_extents(agg::trans_affine master_transform,
150+
py::object paths_obj, py::object transforms_obj,
151+
py::object offsets_obj, agg::trans_affine offset_trans)
158152
{
159-
agg::trans_affine master_transform;
160153
mpl::PathGenerator paths;
161154
numpy::array_view<const double, 3> transforms;
162155
numpy::array_view<const double, 2> offsets;
163-
agg::trans_affine offset_trans;
164156
extent_limits e;
165157

166-
convert_trans_affine(master_transform_obj, master_transform);
167158
if (!convert_pathgen(paths_obj.ptr(), &paths)) {
168159
throw py::error_already_set();
169160
}
@@ -173,7 +164,6 @@ Py_get_path_collection_extents(py::object master_transform_obj, py::object paths
173164
if (!convert_points(offsets_obj.ptr(), &offsets)) {
174165
throw py::error_already_set();
175166
}
176-
convert_trans_affine(offset_trans_obj, offset_trans);
177167

178168
get_path_collection_extents(
179169
master_transform, paths, transforms, offsets, offset_trans, e);
@@ -195,18 +185,15 @@ Py_get_path_collection_extents(py::object master_transform_obj, py::object paths
195185

196186
static py::object
197187
Py_point_in_path_collection(double x, double y, double radius,
198-
py::object master_transform_obj, py::object paths_obj,
188+
agg::trans_affine master_transform, py::object paths_obj,
199189
py::object transforms_obj, py::object offsets_obj,
200-
py::object offset_trans_obj, bool filled)
190+
agg::trans_affine offset_trans, bool filled)
201191
{
202-
agg::trans_affine master_transform;
203192
mpl::PathGenerator paths;
204193
numpy::array_view<const double, 3> transforms;
205194
numpy::array_view<const double, 2> offsets;
206-
agg::trans_affine offset_trans;
207195
std::vector<int> result;
208196

209-
convert_trans_affine(master_transform_obj, master_transform);
210197
if (!convert_pathgen(paths_obj.ptr(), &paths)) {
211198
throw py::error_already_set();
212199
}
@@ -216,7 +203,6 @@ Py_point_in_path_collection(double x, double y, double radius,
216203
if (!convert_points(offsets_obj.ptr(), &offsets)) {
217204
throw py::error_already_set();
218205
}
219-
convert_trans_affine(offset_trans_obj, offset_trans);
220206

221207
point_in_path_collection(x, y, radius, master_transform, paths, transforms, offsets,
222208
offset_trans, filled, result);
@@ -230,22 +216,18 @@ Py_point_in_path_collection(double x, double y, double radius,
230216
}
231217

232218
static bool
233-
Py_path_in_path(py::object a_obj, py::object atrans_obj,
234-
py::object b_obj, py::object btrans_obj)
219+
Py_path_in_path(py::object a_obj, agg::trans_affine atrans,
220+
py::object b_obj, agg::trans_affine btrans)
235221
{
236222
mpl::PathIterator a;
237-
agg::trans_affine atrans;
238223
mpl::PathIterator b;
239-
agg::trans_affine btrans;
240224

241225
if (!convert_path(a_obj.ptr(), &a)) {
242226
throw py::error_already_set();
243227
}
244-
convert_trans_affine(atrans_obj, atrans);
245228
if (!convert_path(b_obj.ptr(), &b)) {
246229
throw py::error_already_set();
247230
}
248-
convert_trans_affine(btrans_obj, btrans);
249231

250232
return path_in_path(a, atrans, b, btrans);
251233
}
@@ -267,12 +249,8 @@ Py_clip_path_to_rect(py::object path_obj, agg::rect_d rect, bool inside)
267249

268250
static py::object
269251
Py_affine_transform(py::array_t<double, py::array::c_style | py::array::forcecast> vertices_arr,
270-
py::object trans_obj)
252+
agg::trans_affine trans)
271253
{
272-
agg::trans_affine trans;
273-
274-
convert_trans_affine(trans_obj, trans);
275-
276254
if (vertices_arr.ndim() == 2) {
277255
auto vertices = vertices_arr.unchecked<2>();
278256

@@ -356,37 +334,33 @@ Py_path_intersects_rectangle(py::object path_obj, double rect_x1, double rect_y1
356334
}
357335

358336
static py::object
359-
Py_convert_path_to_polygons(py::object path_obj, py::object trans_obj,
337+
Py_convert_path_to_polygons(py::object path_obj, agg::trans_affine trans,
360338
double width, double height, bool closed_only)
361339
{
362340
mpl::PathIterator path;
363-
agg::trans_affine trans;
364341
std::vector<Polygon> result;
365342

366343
if (!convert_path(path_obj.ptr(), &path)) {
367344
throw py::error_already_set();
368345
}
369-
convert_trans_affine(trans_obj, trans);
370346

371347
convert_path_to_polygons(path, trans, width, height, closed_only, result);
372348

373349
return convert_polygon_vector(result);
374350
}
375351

376-
static pybind11::tuple
377-
Py_cleanup_path(py::object path_obj, py::object trans_obj, bool remove_nans,
352+
static py::tuple
353+
Py_cleanup_path(py::object path_obj, agg::trans_affine trans, bool remove_nans,
378354
agg::rect_d clip_rect, py::object snap_mode_obj, double stroke_width,
379355
std::optional<bool> simplify, bool return_curves, py::object sketch_obj)
380356
{
381357
mpl::PathIterator path;
382-
agg::trans_affine trans;
383358
e_snap_mode snap_mode;
384359
SketchParams sketch;
385360

386361
if (!convert_path(path_obj.ptr(), &path)) {
387362
throw py::error_already_set();
388363
}
389-
convert_trans_affine(trans_obj, trans);
390364
if (!convert_snap(snap_mode_obj.ptr(), &snap_mode)) {
391365
throw py::error_already_set();
392366
}
@@ -449,12 +423,11 @@ postfix : bool
449423
)""";
450424

451425
static py::object
452-
Py_convert_to_string(py::object path_obj, py::object trans_obj, agg::rect_d cliprect,
426+
Py_convert_to_string(py::object path_obj, agg::trans_affine trans, agg::rect_d cliprect,
453427
std::optional<bool> simplify, py::object sketch_obj, int precision,
454428
std::array<std::string, 5> codes_obj, bool postfix)
455429
{
456430
mpl::PathIterator path;
457-
agg::trans_affine trans;
458431
SketchParams sketch;
459432
char *codes[5];
460433
std::string buffer;
@@ -463,7 +436,6 @@ Py_convert_to_string(py::object path_obj, py::object trans_obj, agg::rect_d clip
463436
if (!convert_path(path_obj.ptr(), &path)) {
464437
throw py::error_already_set();
465438
}
466-
convert_trans_affine(trans_obj, trans);
467439
if (!convert_sketch_params(sketch_obj.ptr(), &sketch)) {
468440
throw py::error_already_set();
469441
}

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)