-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
Expand file tree
/
Copy pathmplutils.h
More file actions
131 lines (113 loc) · 3.2 KB
/
Copy pathmplutils.h
File metadata and controls
131 lines (113 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* -*- mode: c++; c-basic-offset: 4 -*- */
/* Small utilities that are shared by most extension modules. */
#ifndef MPLUTILS_H
#define MPLUTILS_H
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef _POSIX_C_SOURCE
# undef _POSIX_C_SOURCE
#endif
#ifndef _AIX
#ifdef _XOPEN_SOURCE
# undef _XOPEN_SOURCE
#endif
#endif
// Prevent multiple conflicting definitions of swab from stdlib.h and unistd.h
#if defined(__sun) || defined(sun)
#if defined(_XPG4)
#undef _XPG4
#endif
#if defined(_XPG3)
#undef _XPG3
#endif
#endif
inline int mpl_round_to_int(double v)
{
return (int)(v + ((v >= 0.0) ? 0.5 : -0.5));
}
inline double mpl_round(double v)
{
return (double)mpl_round_to_int(v);
}
// 'kind' codes for paths.
enum {
STOP = 0,
MOVETO = 1,
LINETO = 2,
CURVE3 = 3,
CURVE4 = 4,
CLOSEPOLY = 0x4f
};
#ifdef __cplusplus // not for macosx.m
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <array>
#include <cstddef>
namespace py = pybind11;
using namespace pybind11::literals;
// Helper for std::visit.
template<typename... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<typename... Ts> overloaded(Ts...) -> overloaded<Ts...>;
// Check that array has shape (N, d1) or (N, d1, d2). We cast d1, d2 to longs
// so that we don't need to access the NPY_INTP_FMT macro here.
template<typename T>
inline void check_trailing_shape(T array, char const* name, long d1)
{
if (array.ndim() != 2) {
throw py::value_error(
"Expected 2-dimensional array, got {}"_s.format(array.ndim()));
}
if (array.size() == 0) {
// Sometimes things come through as atleast_2d, etc., but they're empty, so
// don't bother enforcing the trailing shape.
return;
}
if (array.shape(1) != d1) {
throw py::value_error(
"{} must have shape (N, {}), got ({}, {})"_s.format(
name, d1, array.shape(0), array.shape(1)));
}
}
template<typename T>
inline void check_trailing_shape(T array, char const* name, long d1, long d2)
{
if (array.ndim() != 3) {
throw py::value_error(
"Expected 3-dimensional array, got {}"_s.format(array.ndim()));
}
if (array.size() == 0) {
// Sometimes things come through as atleast_3d, etc., but they're empty, so
// don't bother enforcing the trailing shape.
return;
}
if (array.shape(1) != d1 || array.shape(2) != d2) {
throw py::value_error(
"{} must have shape (N, {}, {}), got ({}, {}, {})"_s.format(
name, d1, d2, array.shape(0), array.shape(1), array.shape(2)));
}
}
// In most cases, code should use safe_first_shape(obj) instead of
// obj.shape(0), since safe_first_shape(obj) == 0 when any dimension is 0.
template <typename T, py::ssize_t ND>
py::ssize_t safe_first_shape(const py::detail::unchecked_reference<T, ND> &a)
{
bool empty = (ND == 0);
for (py::ssize_t i = 0; i < ND; i++) {
if (a.shape(i) == 0) {
empty = true;
}
}
if (empty) {
return 0;
} else {
return a.shape(0);
}
}
template <typename T, std::size_t N>
constexpr std::size_t
safe_first_shape(const std::array<T, N> &)
{
return N;
}
#endif
#endif