Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf8cadb3

Browse files
authored
Merge pull request#28856 from QuLogic/pybind11-finals
Convert remaining code to pybind11
2 parents7593423 +37206c2 commitf8cadb3

File tree

9 files changed

+395
-424
lines changed

9 files changed

+395
-424
lines changed

‎src/_backend_agg_basic_types.h

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
/* Contains some simple types from the Agg backend that are also used
55
by other modules*/
66

7+
#include<pybind11/pybind11.h>
8+
9+
#include<unordered_map>
710
#include<vector>
811

912
#include"agg_color_rgba.h"
@@ -13,6 +16,8 @@
1316

1417
#include"py_adaptors.h"
1518

19+
namespacepy= pybind11;
20+
1621
structClipPath
1722
{
1823
mpl::PathIterator path;
@@ -121,4 +126,132 @@ class GCAgg
121126
GCAgg &operator=(const GCAgg &);
122127
};
123128

129+
namespacePYBIND11_NAMESPACE {namespacedetail {
130+
template<>structtype_caster<agg::line_cap_e> {
131+
public:
132+
PYBIND11_TYPE_CASTER(agg::line_cap_e, const_name("line_cap_e"));
133+
134+
boolload(handle src,bool) {
135+
const std::unordered_map<std::string, agg::line_cap_e> enum_values = {
136+
{"butt", agg::butt_cap},
137+
{"round", agg::round_cap},
138+
{"projecting", agg::square_cap},
139+
};
140+
value = enum_values.at(src.cast<std::string>());
141+
returntrue;
142+
}
143+
};
144+
145+
template<>structtype_caster<agg::line_join_e> {
146+
public:
147+
PYBIND11_TYPE_CASTER(agg::line_join_e, const_name("line_join_e"));
148+
149+
boolload(handle src,bool) {
150+
const std::unordered_map<std::string, agg::line_join_e> enum_values = {
151+
{"miter", agg::miter_join_revert},
152+
{"round", agg::round_join},
153+
{"bevel", agg::bevel_join},
154+
};
155+
value = enum_values.at(src.cast<std::string>());
156+
returntrue;
157+
}
158+
};
159+
160+
template<>structtype_caster<ClipPath> {
161+
public:
162+
PYBIND11_TYPE_CASTER(ClipPath, const_name("ClipPath"));
163+
164+
boolload(handle src,bool) {
165+
if (src.is_none()) {
166+
returntrue;
167+
}
168+
169+
auto [path, trans] =
170+
src.cast<std::pair<std::optional<mpl::PathIterator>, agg::trans_affine>>();
171+
if (path) {
172+
value.path = *path;
173+
}
174+
value.trans = trans;
175+
176+
returntrue;
177+
}
178+
};
179+
180+
template<>structtype_caster<Dashes> {
181+
public:
182+
PYBIND11_TYPE_CASTER(Dashes, const_name("Dashes"));
183+
184+
boolload(handle src,bool) {
185+
auto [dash_offset, dashes_seq_or_none] =
186+
src.cast<std::pair<double, std::optional<py::sequence>>>();
187+
188+
if (!dashes_seq_or_none) {
189+
returntrue;
190+
}
191+
192+
auto dashes_seq = *dashes_seq_or_none;
193+
194+
auto nentries = dashes_seq.size();
195+
// If the dashpattern has odd length, iterate through it twice (in
196+
// accordance with the pdf/ps/svg specs).
197+
auto dash_pattern_length = (nentries %2) ?2 * nentries : nentries;
198+
199+
for (py::size_t i =0; i < dash_pattern_length; i +=2) {
200+
auto length = dashes_seq[i % nentries].cast<double>();
201+
auto skip = dashes_seq[(i +1) % nentries].cast<double>();
202+
203+
value.add_dash_pair(length, skip);
204+
}
205+
206+
value.set_dash_offset(dash_offset);
207+
208+
returntrue;
209+
}
210+
};
211+
212+
template<>structtype_caster<SketchParams> {
213+
public:
214+
PYBIND11_TYPE_CASTER(SketchParams, const_name("SketchParams"));
215+
216+
boolload(handle src,bool) {
217+
if (src.is_none()) {
218+
value.scale =0.0;
219+
value.length =0.0;
220+
value.randomness =0.0;
221+
returntrue;
222+
}
223+
224+
auto params = src.cast<std::tuple<double,double,double>>();
225+
std::tie(value.scale, value.length, value.randomness) = params;
226+
227+
returntrue;
228+
}
229+
};
230+
231+
template<>structtype_caster<GCAgg> {
232+
public:
233+
PYBIND11_TYPE_CASTER(GCAgg, const_name("GCAgg"));
234+
235+
boolload(handle src,bool) {
236+
value.linewidth = src.attr("_linewidth").cast<double>();
237+
value.alpha = src.attr("_alpha").cast<double>();
238+
value.forced_alpha = src.attr("_forced_alpha").cast<bool>();
239+
value.color = src.attr("_rgb").cast<agg::rgba>();
240+
value.isaa = src.attr("_antialiased").cast<bool>();
241+
value.cap = src.attr("_capstyle").cast<agg::line_cap_e>();
242+
value.join = src.attr("_joinstyle").cast<agg::line_join_e>();
243+
value.dashes = src.attr("get_dashes")().cast<Dashes>();
244+
value.cliprect = src.attr("_cliprect").cast<agg::rect_d>();
245+
value.clippath = src.attr("get_clip_path")().cast<ClipPath>();
246+
value.snap_mode = src.attr("get_snap")().cast<e_snap_mode>();
247+
value.hatchpath = src.attr("get_hatch_path")().cast<mpl::PathIterator>();
248+
value.hatch_color = src.attr("get_hatch_color")().cast<agg::rgba>();
249+
value.hatch_linewidth = src.attr("get_hatch_linewidth")().cast<double>();
250+
value.sketch = src.attr("get_sketch_params")().cast<SketchParams>();
251+
252+
returntrue;
253+
}
254+
};
255+
}}// namespace PYBIND11_NAMESPACE::detail
256+
124257
#endif

‎src/_backend_agg_wrapper.cpp

Lines changed: 19 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -111,48 +111,25 @@ static void
111111
PyRendererAgg_draw_path_collection(RendererAgg *self,
112112
GCAgg &gc,
113113
agg::trans_affine master_transform,
114-
py::object paths_obj,
115-
py::object transforms_obj,
116-
py::object offsets_obj,
114+
mpl::PathGenerator paths,
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::objectPy_UNUSED(ignored_obj),
124124
// offset position is no longer used
125125
py::object Py_UNUSED(offset_position_obj))
126126
{
127-
mpl::PathGenerator paths;
128-
numpy::array_view<constdouble,3> transforms;
129-
numpy::array_view<constdouble,2> offsets;
130-
numpy::array_view<constdouble,2> facecolors;
131-
numpy::array_view<constdouble,2> edgecolors;
132-
numpy::array_view<constdouble,1> linewidths;
133-
numpy::array_view<constuint8_t,1> antialiaseds;
134-
135-
if (!convert_pathgen(paths_obj.ptr(), &paths)) {
136-
throwpy::error_already_set();
137-
}
138-
if (!convert_transforms(transforms_obj.ptr(), &transforms)) {
139-
throwpy::error_already_set();
140-
}
141-
if (!convert_points(offsets_obj.ptr(), &offsets)) {
142-
throwpy::error_already_set();
143-
}
144-
if (!convert_colors(facecolors_obj.ptr(), &facecolors)) {
145-
throwpy::error_already_set();
146-
}
147-
if (!convert_colors(edgecolors_obj.ptr(), &edgecolors)) {
148-
throwpy::error_already_set();
149-
}
150-
if (!linewidths.converter(linewidths_obj.ptr(), &linewidths)) {
151-
throwpy::error_already_set();
152-
}
153-
if (!antialiaseds.converter(antialiaseds_obj.ptr(), &antialiaseds)) {
154-
throwpy::error_already_set();
155-
}
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>();
156133

157134
self->draw_path_collection(gc,
158135
master_transform,
@@ -174,26 +151,16 @@ PyRendererAgg_draw_quad_mesh(RendererAgg *self,
174151
unsignedint mesh_width,
175152
unsignedint mesh_height,
176153
py::array_t<double, py::array::c_style | py::array::forcecast> coordinates_obj,
177-
py::object offsets_obj,
154+
py::array_t<double> offsets_obj,
178155
agg::trans_affine offset_trans,
179-
py::object facecolors_obj,
156+
py::array_t<double> facecolors_obj,
180157
bool antialiased,
181-
py::object edgecolors_obj)
158+
py::array_t<double> edgecolors_obj)
182159
{
183-
numpy::array_view<constdouble,2> offsets;
184-
numpy::array_view<constdouble,2> facecolors;
185-
numpy::array_view<constdouble,2> edgecolors;
186-
187160
auto coordinates = coordinates_obj.mutable_unchecked<3>();
188-
if (!convert_points(offsets_obj.ptr(), &offsets)) {
189-
throwpy::error_already_set();
190-
}
191-
if (!convert_colors(facecolors_obj.ptr(), &facecolors)) {
192-
throwpy::error_already_set();
193-
}
194-
if (!convert_colors(edgecolors_obj.ptr(), &edgecolors)) {
195-
throwpy::error_already_set();
196-
}
161+
auto offsets =convert_points(offsets_obj);
162+
auto facecolors =convert_colors(facecolors_obj);
163+
auto edgecolors =convert_colors(edgecolors_obj);
197164

198165
self->draw_quad_mesh(gc,
199166
master_transform,

‎src/_path.h

Lines changed: 27 additions & 30 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
inlineboolpoint_in_path(
271270
double x,double y,constdouble 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
throwstd::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 (autoi =0; i < N; ++i) {
396396
typename PathGenerator::path_iteratorpath(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 (autoi =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),
@@ -1224,17 +1223,15 @@ bool convert_to_string(PathIterator &path,
12241223
}
12251224

12261225
template<classT>
1227-
boolis_sorted_and_has_non_nan(PyArrayObject *array)
1226+
boolis_sorted_and_has_non_nan(py::array_t<T>array)
12281227
{
1229-
char* ptr =PyArray_BYTES(array);
1230-
npy_intp size =PyArray_DIM(array,0),
1231-
stride =PyArray_STRIDE(array,0);
1228+
auto size = array.shape(0);
12321229
using limits = std::numeric_limits<T>;
12331230
T last = limits::has_infinity ? -limits::infinity() :limits::min();
12341231
bool found_non_nan =false;
12351232

1236-
for (npy_intp i =0; i < size; ++i, ptr += stride) {
1237-
T current = *(T*)ptr;
1233+
for (auto i =0; i < size; ++i) {
1234+
T current = *array.data(i);
12381235
// The following tests !isnan(current), but also works for integral
12391236
// types. (The isnan(IntegralType) overload is absent on MSVC.)
12401237
if (current == current) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp