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

Skip to content

Commit 0305729

Browse files
committed
Convert remaining array_view to pybind11 array_t
1 parent 086add1 commit 0305729

File tree

5 files changed

+110
-108
lines changed

5 files changed

+110
-108
lines changed

src/_backend_agg_wrapper.cpp

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -112,43 +112,24 @@ PyRendererAgg_draw_path_collection(RendererAgg *self,
112112
GCAgg &gc,
113113
agg::trans_affine master_transform,
114114
mpl::PathGenerator paths,
115-
py::object transforms_obj,
116-
py::object offsets_obj,
115+
py::array_t<double> transforms_obj,
116+
py::array_t<double> offsets_obj,
117117
agg::trans_affine offset_trans,
118-
py::object facecolors_obj,
119-
py::object edgecolors_obj,
120-
py::object linewidths_obj,
118+
py::array_t<double> facecolors_obj,
119+
py::array_t<double> edgecolors_obj,
120+
py::array_t<double> linewidths_obj,
121121
DashesVector dashes,
122-
py::object antialiaseds_obj,
122+
py::array_t<uint8_t> antialiaseds_obj,
123123
py::object Py_UNUSED(ignored_obj),
124124
// offset position is no longer used
125125
py::object Py_UNUSED(offset_position_obj))
126126
{
127-
numpy::array_view<const double, 3> transforms;
128-
numpy::array_view<const double, 2> offsets;
129-
numpy::array_view<const double, 2> facecolors;
130-
numpy::array_view<const double, 2> edgecolors;
131-
numpy::array_view<const double, 1> linewidths;
132-
numpy::array_view<const uint8_t, 1> antialiaseds;
133-
134-
if (!convert_transforms(transforms_obj.ptr(), &transforms)) {
135-
throw py::error_already_set();
136-
}
137-
if (!convert_points(offsets_obj.ptr(), &offsets)) {
138-
throw py::error_already_set();
139-
}
140-
if (!convert_colors(facecolors_obj.ptr(), &facecolors)) {
141-
throw py::error_already_set();
142-
}
143-
if (!convert_colors(edgecolors_obj.ptr(), &edgecolors)) {
144-
throw py::error_already_set();
145-
}
146-
if (!linewidths.converter(linewidths_obj.ptr(), &linewidths)) {
147-
throw py::error_already_set();
148-
}
149-
if (!antialiaseds.converter(antialiaseds_obj.ptr(), &antialiaseds)) {
150-
throw py::error_already_set();
151-
}
127+
auto transforms = convert_transforms(transforms_obj);
128+
auto offsets = convert_points(offsets_obj);
129+
auto facecolors = convert_colors(facecolors_obj);
130+
auto edgecolors = convert_colors(edgecolors_obj);
131+
auto linewidths = linewidths_obj.unchecked<1>();
132+
auto antialiaseds = antialiaseds_obj.unchecked<1>();
152133

153134
self->draw_path_collection(gc,
154135
master_transform,
@@ -170,26 +151,16 @@ PyRendererAgg_draw_quad_mesh(RendererAgg *self,
170151
unsigned int mesh_width,
171152
unsigned int mesh_height,
172153
py::array_t<double, py::array::c_style | py::array::forcecast> coordinates_obj,
173-
py::object offsets_obj,
154+
py::array_t<double> offsets_obj,
174155
agg::trans_affine offset_trans,
175-
py::object facecolors_obj,
156+
py::array_t<double> facecolors_obj,
176157
bool antialiased,
177-
py::object edgecolors_obj)
158+
py::array_t<double> edgecolors_obj)
178159
{
179-
numpy::array_view<const double, 2> offsets;
180-
numpy::array_view<const double, 2> facecolors;
181-
numpy::array_view<const double, 2> edgecolors;
182-
183160
auto coordinates = coordinates_obj.mutable_unchecked<3>();
184-
if (!convert_points(offsets_obj.ptr(), &offsets)) {
185-
throw py::error_already_set();
186-
}
187-
if (!convert_colors(facecolors_obj.ptr(), &facecolors)) {
188-
throw py::error_already_set();
189-
}
190-
if (!convert_colors(edgecolors_obj.ptr(), &edgecolors)) {
191-
throw py::error_already_set();
192-
}
161+
auto offsets = convert_points(offsets_obj);
162+
auto facecolors = convert_colors(facecolors_obj);
163+
auto edgecolors = convert_colors(edgecolors_obj);
193164

194165
self->draw_quad_mesh(gc,
195166
master_transform,

src/_path.h

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,7 @@ inline void points_in_path(PointArray &points,
245245
typedef agg::conv_curve<no_nans_t> curve_t;
246246
typedef agg::conv_contour<curve_t> contour_t;
247247

248-
size_t i;
249-
for (i = 0; i < safe_first_shape(points); ++i) {
248+
for (auto i = 0; i < safe_first_shape(points); ++i) {
250249
result[i] = false;
251250
}
252251

@@ -270,10 +269,11 @@ template <class PathIterator>
270269
inline bool point_in_path(
271270
double x, double y, const double r, PathIterator &path, agg::trans_affine &trans)
272271
{
273-
npy_intp shape[] = {1, 2};
274-
numpy::array_view<double, 2> points(shape);
275-
points(0, 0) = x;
276-
points(0, 1) = y;
272+
py::ssize_t shape[] = {1, 2};
273+
py::array_t<double> points_arr(shape);
274+
*points_arr.mutable_data(0, 0) = x;
275+
*points_arr.mutable_data(0, 1) = y;
276+
auto points = points_arr.mutable_unchecked<2>();
277277

278278
int result[1];
279279
result[0] = 0;
@@ -292,10 +292,11 @@ inline bool point_on_path(
292292
typedef agg::conv_curve<no_nans_t> curve_t;
293293
typedef agg::conv_stroke<curve_t> stroke_t;
294294

295-
npy_intp shape[] = {1, 2};
296-
numpy::array_view<double, 2> points(shape);
297-
points(0, 0) = x;
298-
points(0, 1) = y;
295+
py::ssize_t shape[] = {1, 2};
296+
py::array_t<double> points_arr(shape);
297+
*points_arr.mutable_data(0, 0) = x;
298+
*points_arr.mutable_data(0, 1) = y;
299+
auto points = points_arr.mutable_unchecked<2>();
299300

300301
int result[1];
301302
result[0] = 0;
@@ -382,20 +383,19 @@ void get_path_collection_extents(agg::trans_affine &master_transform,
382383
throw std::runtime_error("Offsets array must have shape (N, 2)");
383384
}
384385

385-
size_t Npaths = paths.size();
386-
size_t Noffsets = safe_first_shape(offsets);
387-
size_t N = std::max(Npaths, Noffsets);
388-
size_t Ntransforms = std::min(safe_first_shape(transforms), N);
389-
size_t i;
386+
auto Npaths = paths.size();
387+
auto Noffsets = safe_first_shape(offsets);
388+
auto N = std::max(Npaths, Noffsets);
389+
auto Ntransforms = std::min(safe_first_shape(transforms), N);
390390

391391
agg::trans_affine trans;
392392

393393
reset_limits(extent);
394394

395-
for (i = 0; i < N; ++i) {
395+
for (auto i = 0; i < N; ++i) {
396396
typename PathGenerator::path_iterator path(paths(i % Npaths));
397397
if (Ntransforms) {
398-
size_t ti = i % Ntransforms;
398+
py::ssize_t ti = i % Ntransforms;
399399
trans = agg::trans_affine(transforms(ti, 0, 0),
400400
transforms(ti, 1, 0),
401401
transforms(ti, 0, 1),
@@ -429,24 +429,23 @@ void point_in_path_collection(double x,
429429
bool filled,
430430
std::vector<int> &result)
431431
{
432-
size_t Npaths = paths.size();
432+
auto Npaths = paths.size();
433433

434434
if (Npaths == 0) {
435435
return;
436436
}
437437

438-
size_t Noffsets = safe_first_shape(offsets);
439-
size_t N = std::max(Npaths, Noffsets);
440-
size_t Ntransforms = std::min(safe_first_shape(transforms), N);
441-
size_t i;
438+
auto Noffsets = safe_first_shape(offsets);
439+
auto N = std::max(Npaths, Noffsets);
440+
auto Ntransforms = std::min(safe_first_shape(transforms), N);
442441

443442
agg::trans_affine trans;
444443

445-
for (i = 0; i < N; ++i) {
444+
for (auto i = 0; i < N; ++i) {
446445
typename PathGenerator::path_iterator path = paths(i % Npaths);
447446

448447
if (Ntransforms) {
449-
size_t ti = i % Ntransforms;
448+
auto ti = i % Ntransforms;
450449
trans = agg::trans_affine(transforms(ti, 0, 0),
451450
transforms(ti, 1, 0),
452451
transforms(ti, 0, 1),

src/_path_wrapper.cpp

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,9 @@ static py::array_t<double>
4444
Py_points_in_path(py::array_t<double> points_obj, double r, mpl::PathIterator path,
4545
agg::trans_affine trans)
4646
{
47-
numpy::array_view<double, 2> points;
47+
auto points = convert_points(points_obj);
4848

49-
if (!convert_points(points_obj.ptr(), &points)) {
50-
throw py::error_already_set();
51-
}
52-
53-
if (!check_trailing_shape(points, "points", 2)) {
54-
throw py::error_already_set();
55-
}
56-
57-
py::ssize_t dims[] = { static_cast<py::ssize_t>(points.size()) };
49+
py::ssize_t dims[] = { points.shape(0) };
5850
py::array_t<uint8_t> results(dims);
5951
auto results_mutable = results.mutable_unchecked<1>();
6052

@@ -123,20 +115,15 @@ Py_update_path_extents(mpl::PathIterator path, agg::trans_affine trans,
123115

124116
static py::tuple
125117
Py_get_path_collection_extents(agg::trans_affine master_transform,
126-
mpl::PathGenerator paths, py::object transforms_obj,
127-
py::object offsets_obj, agg::trans_affine offset_trans)
118+
mpl::PathGenerator paths,
119+
py::array_t<double> transforms_obj,
120+
py::array_t<double> offsets_obj,
121+
agg::trans_affine offset_trans)
128122
{
129-
numpy::array_view<const double, 3> transforms;
130-
numpy::array_view<const double, 2> offsets;
123+
auto transforms = convert_transforms(transforms_obj);
124+
auto offsets = convert_points(offsets_obj);
131125
extent_limits e;
132126

133-
if (!convert_transforms(transforms_obj.ptr(), &transforms)) {
134-
throw py::error_already_set();
135-
}
136-
if (!convert_points(offsets_obj.ptr(), &offsets)) {
137-
throw py::error_already_set();
138-
}
139-
140127
get_path_collection_extents(
141128
master_transform, paths, transforms, offsets, offset_trans, e);
142129

@@ -158,20 +145,14 @@ Py_get_path_collection_extents(agg::trans_affine master_transform,
158145
static py::object
159146
Py_point_in_path_collection(double x, double y, double radius,
160147
agg::trans_affine master_transform, mpl::PathGenerator paths,
161-
py::object transforms_obj, py::object offsets_obj,
148+
py::array_t<double> transforms_obj,
149+
py::array_t<double> offsets_obj,
162150
agg::trans_affine offset_trans, bool filled)
163151
{
164-
numpy::array_view<const double, 3> transforms;
165-
numpy::array_view<const double, 2> offsets;
152+
auto transforms = convert_transforms(transforms_obj);
153+
auto offsets = convert_points(offsets_obj);
166154
std::vector<int> result;
167155

168-
if (!convert_transforms(transforms_obj.ptr(), &transforms)) {
169-
throw py::error_already_set();
170-
}
171-
if (!convert_points(offsets_obj.ptr(), &offsets)) {
172-
throw py::error_already_set();
173-
}
174-
175156
point_in_path_collection(x, y, radius, master_transform, paths, transforms, offsets,
176157
offset_trans, filled, result);
177158

@@ -229,13 +210,9 @@ Py_affine_transform(py::array_t<double, py::array::c_style | py::array::forcecas
229210
}
230211

231212
static int
232-
Py_count_bboxes_overlapping_bbox(agg::rect_d bbox, py::object bboxes_obj)
213+
Py_count_bboxes_overlapping_bbox(agg::rect_d bbox, py::array_t<double> bboxes_obj)
233214
{
234-
numpy::array_view<const double, 3> bboxes;
235-
236-
if (!convert_bboxes(bboxes_obj.ptr(), &bboxes)) {
237-
throw py::error_already_set();
238-
}
215+
auto bboxes = convert_bboxes(bboxes_obj);
239216

240217
return count_bboxes_overlapping_bbox(bbox, bboxes);
241218
}

src/mplutils.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ inline int prepare_and_add_type(PyTypeObject *type, PyObject *module)
6767
#ifdef __cplusplus // not for macosx.m
6868
// Check that array has shape (N, d1) or (N, d1, d2). We cast d1, d2 to longs
6969
// so that we don't need to access the NPY_INTP_FMT macro here.
70+
#include <pybind11/pybind11.h>
71+
#include <pybind11/numpy.h>
72+
73+
namespace py = pybind11;
7074

7175
template<typename T>
7276
inline bool check_trailing_shape(T array, char const* name, long d1)
@@ -113,6 +117,25 @@ inline bool check_trailing_shape(T array, char const* name, long d1, long d2)
113117
}
114118
return true;
115119
}
120+
121+
/* In most cases, code should use safe_first_shape(obj) instead of obj.shape(0), since
122+
safe_first_shape(obj) == 0 when any dimension is 0. */
123+
template <typename T, py::ssize_t ND>
124+
py::ssize_t
125+
safe_first_shape(const py::detail::unchecked_reference<T, ND> &a)
126+
{
127+
bool empty = (ND == 0);
128+
for (py::ssize_t i = 0; i < ND; i++) {
129+
if (a.shape(i) == 0) {
130+
empty = true;
131+
}
132+
}
133+
if (empty) {
134+
return 0;
135+
} else {
136+
return a.shape(0);
137+
}
138+
}
116139
#endif
117140

118141
#endif

src/py_converters_11.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,38 @@ namespace py = pybind11;
1717

1818
void convert_trans_affine(const py::object& transform, agg::trans_affine& affine);
1919

20+
inline auto convert_points(py::array_t<double> obj)
21+
{
22+
if (!check_trailing_shape(obj, "points", 2)) {
23+
throw py::error_already_set();
24+
}
25+
return obj.unchecked<2>();
26+
}
27+
28+
inline auto convert_transforms(py::array_t<double> obj)
29+
{
30+
if (!check_trailing_shape(obj, "transforms", 3, 3)) {
31+
throw py::error_already_set();
32+
}
33+
return obj.unchecked<3>();
34+
}
35+
36+
inline auto convert_bboxes(py::array_t<double> obj)
37+
{
38+
if (!check_trailing_shape(obj, "bbox array", 2, 2)) {
39+
throw py::error_already_set();
40+
}
41+
return obj.unchecked<3>();
42+
}
43+
44+
inline auto convert_colors(py::array_t<double> obj)
45+
{
46+
if (!check_trailing_shape(obj, "colors", 4)) {
47+
throw py::error_already_set();
48+
}
49+
return obj.unchecked<2>();
50+
}
51+
2052
namespace PYBIND11_NAMESPACE { namespace detail {
2153
template <> struct type_caster<agg::rect_d> {
2254
public:

0 commit comments

Comments
 (0)