math3d-py 1.3.0__tar.gz → 1.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of math3d-py might be problematic. Click here for more details.
- {math3d_py-1.3.0 → math3d_py-1.3.4}/PKG-INFO +1 -1
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/SupportingTypes.h +22 -2
- {math3d_py-1.3.0 → math3d_py-1.3.4}/py/CMakeLists.txt +1 -1
- math3d_py-1.3.4/py/math3d/math3d.pyi +303 -0
- math3d_py-1.3.4/py/math3d/py.typed +0 -0
- math3d_py-1.3.4/py/math3d/types.hpp +84 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/pyproject.toml +1 -1
- {math3d_py-1.3.0 → math3d_py-1.3.4}/pypublish +2 -2
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/Types.cpp +24 -0
- math3d_py-1.3.4/tmp/math3d/__init__.py +1 -0
- math3d_py-1.3.4/tmp/math3d/__init__.pyi +20 -0
- math3d_py-1.3.4/tmp/math3d/linear_system.hpp +15 -0
- math3d_py-1.3.4/tmp/math3d/math3d.cpp +116 -0
- math3d_py-1.3.4/tmp/math3d/math3d.cpython-313-darwin.so +0 -0
- math3d_py-1.3.4/tmp/math3d/matrix.hpp +57 -0
- math3d_py-1.3.4/tmp/math3d/py.typed +0 -0
- {math3d_py-1.3.0/py → math3d_py-1.3.4/tmp}/math3d/types.hpp +26 -0
- math3d_py-1.3.4/tmp/math3d/util.h +13 -0
- math3d_py-1.3.4/tmp/math3d/vector.hpp +101 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.DS_Store +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.github/workflows/cmake-single-platform.yml +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.github/workflows/jekyll-gh-pages.yml +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.gitignore +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.idea/.gitignore +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.idea/3dmath.iml +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.idea/editor.xml +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.idea/misc.xml +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.idea/modules.xml +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/.idea/vcs.xml +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/CMakeLists.txt +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/LICENSE.txt +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/README.md +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/.DS_Store +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/Constants.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/IdentityMatrix.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/LinearSystem.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/Matrix.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/MatrixOperations.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/MatrixUtil.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/OrthographicProjectionMatrix.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/PolarCoordinates.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/ProjectionMatrix.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/Quaternion.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/RotationMatrix.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/ScalingMatrix.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/TranslationMatrix.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/TypeAliases.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/Utilities.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/Vector.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/primitives/ConvexPrimitive.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/primitives/Plane.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/primitives/Primitive.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/primitives/Ray.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/include/3dmath/primitives/Sphere.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/poetry.lock +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/py/math3d/__init__.py +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/py/math3d/__init__.pyi +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/py/math3d/linear_system.hpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/py/math3d/math3d.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/py/math3d/matrix.hpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/py/math3d/util.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/py/math3d/vector.hpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/CMakeLists.txt +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/ConvexPrimitive.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/LinearSystem.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/Matrix.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/MatrixOperations.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/OrthographicProjectionMatrix.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/Plane.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/PolarCoordinates.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/Quaternion.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/Ray.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/RotationMatrix.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/ScalingMatrix.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/Sphere.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/TestSupport.h +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/TranslationMatrix.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/Vector.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/VectorConvenienceMembers.cpp +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/baseline/Ray.obj +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/baseline/Sphere.obj +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/baseline/Sphere.stl +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/baseline/Xy.stl +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/baseline/Xz.stl +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/baseline/Yz.stl +0 -0
- {math3d_py-1.3.0 → math3d_py-1.3.4}/tests/support/PrimitivesTestSupport.h +0 -0
- {math3d_py-1.3.0/py → math3d_py-1.3.4/tmp}/math3d/math3d.pyi +0 -0
|
@@ -21,9 +21,13 @@ namespace math3d {
|
|
|
21
21
|
T length() const { return max - min; }
|
|
22
22
|
T center() const { return static_cast<T>(0.5*(max + min)); }
|
|
23
23
|
void scale(T const scale) { min *= scale; max *= scale; }
|
|
24
|
-
std::string asString() const {
|
|
24
|
+
[[nodiscard]] std::string asString() const {
|
|
25
25
|
return std::format("[{},{}]", min, max);
|
|
26
26
|
}
|
|
27
|
+
void merge(Extent const& another) {
|
|
28
|
+
min = std::min(min, another.min);
|
|
29
|
+
max = std::max(max, another.max);
|
|
30
|
+
}
|
|
27
31
|
};
|
|
28
32
|
|
|
29
33
|
template<typename T>
|
|
@@ -130,9 +134,25 @@ namespace math3d {
|
|
|
130
134
|
return ss.str();
|
|
131
135
|
}
|
|
132
136
|
|
|
133
|
-
bool isValid() const {
|
|
137
|
+
[[nodiscard]] bool isValid() const {
|
|
134
138
|
return x.min < x.max && y.min < y.max && z.min < z.max;
|
|
135
139
|
}
|
|
140
|
+
|
|
141
|
+
void merge(Bounds3D const& another) {
|
|
142
|
+
x.merge(another.x);
|
|
143
|
+
y.merge(another.y);
|
|
144
|
+
z.merge(another.z);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
[[nodiscard]]
|
|
148
|
+
Vector3<T> min() const {
|
|
149
|
+
return {x.min, y.min, z.min};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
[[nodiscard]]
|
|
153
|
+
Vector3<T> max() const {
|
|
154
|
+
return {x.max, y.max, z.max};
|
|
155
|
+
}
|
|
136
156
|
};
|
|
137
157
|
|
|
138
158
|
template<typename T>
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import typing
|
|
3
|
+
__all__: list[str] = ['AABB', 'Extent', 'Identity2', 'Identity3', 'Identity4', 'LinearSystem2', 'LinearSystem3', 'LinearSystem4', 'Matrix2', 'Matrix3', 'Matrix4', 'Vector2', 'Vector3', 'Vector4', 'col_major', 'order', 'row_major']
|
|
4
|
+
class AABB:
|
|
5
|
+
@typing.overload
|
|
6
|
+
def __init__(self) -> None:
|
|
7
|
+
...
|
|
8
|
+
@typing.overload
|
|
9
|
+
def __init__(self, arg0: Extent, arg1: Extent, arg2: Extent) -> None:
|
|
10
|
+
...
|
|
11
|
+
def __repr__(self) -> str:
|
|
12
|
+
...
|
|
13
|
+
def __str__(self) -> str:
|
|
14
|
+
...
|
|
15
|
+
def merge(self, arg0: AABB) -> None:
|
|
16
|
+
...
|
|
17
|
+
class Extent:
|
|
18
|
+
max: float
|
|
19
|
+
min: float
|
|
20
|
+
@typing.overload
|
|
21
|
+
def __init__(self) -> None:
|
|
22
|
+
...
|
|
23
|
+
@typing.overload
|
|
24
|
+
def __init__(self, arg0: float, arg1: float) -> None:
|
|
25
|
+
...
|
|
26
|
+
def __repr__(self) -> str:
|
|
27
|
+
...
|
|
28
|
+
def __str__(self) -> str:
|
|
29
|
+
...
|
|
30
|
+
def center(self) -> float:
|
|
31
|
+
...
|
|
32
|
+
def length(self) -> float:
|
|
33
|
+
...
|
|
34
|
+
def update(self, arg0: float) -> None:
|
|
35
|
+
...
|
|
36
|
+
class Identity2(Matrix2):
|
|
37
|
+
def __init__(self) -> None:
|
|
38
|
+
...
|
|
39
|
+
class Identity3(Matrix3):
|
|
40
|
+
def __init__(self) -> None:
|
|
41
|
+
...
|
|
42
|
+
class Identity4(Matrix4):
|
|
43
|
+
def __init__(self) -> None:
|
|
44
|
+
...
|
|
45
|
+
class LinearSystem2:
|
|
46
|
+
@staticmethod
|
|
47
|
+
def solve(arg0: Matrix2, arg1: Vector2) -> Vector2:
|
|
48
|
+
...
|
|
49
|
+
class LinearSystem3:
|
|
50
|
+
@staticmethod
|
|
51
|
+
def solve(arg0: Matrix3, arg1: Vector3) -> Vector3:
|
|
52
|
+
...
|
|
53
|
+
class LinearSystem4:
|
|
54
|
+
@staticmethod
|
|
55
|
+
def solve(arg0: Matrix4, arg1: Vector4) -> Vector4:
|
|
56
|
+
...
|
|
57
|
+
class Matrix2:
|
|
58
|
+
@typing.overload
|
|
59
|
+
def __getitem__(self, arg0: int) -> Vector2:
|
|
60
|
+
...
|
|
61
|
+
@typing.overload
|
|
62
|
+
def __getitem__(self, arg0: tuple[int, int]) -> float:
|
|
63
|
+
...
|
|
64
|
+
@typing.overload
|
|
65
|
+
def __init__(self) -> None:
|
|
66
|
+
...
|
|
67
|
+
@typing.overload
|
|
68
|
+
def __init__(self, arg0: typing.Iterable, arg1: order) -> None:
|
|
69
|
+
...
|
|
70
|
+
@typing.overload
|
|
71
|
+
def __mul__(self, arg0: Matrix2) -> Matrix2:
|
|
72
|
+
...
|
|
73
|
+
@typing.overload
|
|
74
|
+
def __mul__(self, arg0: Vector2) -> Vector2:
|
|
75
|
+
...
|
|
76
|
+
def __repr__(self) -> str:
|
|
77
|
+
...
|
|
78
|
+
def __str__(self) -> str:
|
|
79
|
+
...
|
|
80
|
+
def determinant(self) -> float:
|
|
81
|
+
...
|
|
82
|
+
def inverse(self) -> Matrix2:
|
|
83
|
+
...
|
|
84
|
+
def row(self, arg0: int) -> Vector2:
|
|
85
|
+
...
|
|
86
|
+
def transpose(self) -> Matrix2:
|
|
87
|
+
...
|
|
88
|
+
def upper_triangular(self) -> Matrix2:
|
|
89
|
+
...
|
|
90
|
+
class Matrix3:
|
|
91
|
+
@typing.overload
|
|
92
|
+
def __getitem__(self, arg0: int) -> Vector3:
|
|
93
|
+
...
|
|
94
|
+
@typing.overload
|
|
95
|
+
def __getitem__(self, arg0: tuple[int, int]) -> float:
|
|
96
|
+
...
|
|
97
|
+
@typing.overload
|
|
98
|
+
def __init__(self) -> None:
|
|
99
|
+
...
|
|
100
|
+
@typing.overload
|
|
101
|
+
def __init__(self, arg0: typing.Iterable, arg1: order) -> None:
|
|
102
|
+
...
|
|
103
|
+
@typing.overload
|
|
104
|
+
def __mul__(self, arg0: Matrix3) -> Matrix3:
|
|
105
|
+
...
|
|
106
|
+
@typing.overload
|
|
107
|
+
def __mul__(self, arg0: Vector3) -> Vector3:
|
|
108
|
+
...
|
|
109
|
+
def __repr__(self) -> str:
|
|
110
|
+
...
|
|
111
|
+
def __str__(self) -> str:
|
|
112
|
+
...
|
|
113
|
+
def determinant(self) -> float:
|
|
114
|
+
...
|
|
115
|
+
def inverse(self) -> Matrix3:
|
|
116
|
+
...
|
|
117
|
+
def row(self, arg0: int) -> Vector3:
|
|
118
|
+
...
|
|
119
|
+
def transpose(self) -> Matrix3:
|
|
120
|
+
...
|
|
121
|
+
def upper_triangular(self) -> Matrix3:
|
|
122
|
+
...
|
|
123
|
+
class Matrix4:
|
|
124
|
+
@typing.overload
|
|
125
|
+
def __getitem__(self, arg0: int) -> Vector4:
|
|
126
|
+
...
|
|
127
|
+
@typing.overload
|
|
128
|
+
def __getitem__(self, arg0: tuple[int, int]) -> float:
|
|
129
|
+
...
|
|
130
|
+
@typing.overload
|
|
131
|
+
def __init__(self) -> None:
|
|
132
|
+
...
|
|
133
|
+
@typing.overload
|
|
134
|
+
def __init__(self, arg0: typing.Iterable, arg1: order) -> None:
|
|
135
|
+
...
|
|
136
|
+
@typing.overload
|
|
137
|
+
def __mul__(self, arg0: Matrix4) -> Matrix4:
|
|
138
|
+
...
|
|
139
|
+
@typing.overload
|
|
140
|
+
def __mul__(self, arg0: Vector4) -> Vector4:
|
|
141
|
+
...
|
|
142
|
+
def __repr__(self) -> str:
|
|
143
|
+
...
|
|
144
|
+
def __str__(self) -> str:
|
|
145
|
+
...
|
|
146
|
+
def determinant(self) -> float:
|
|
147
|
+
...
|
|
148
|
+
def inverse(self) -> Matrix4:
|
|
149
|
+
...
|
|
150
|
+
def row(self, arg0: int) -> Vector4:
|
|
151
|
+
...
|
|
152
|
+
def transpose(self) -> Matrix4:
|
|
153
|
+
...
|
|
154
|
+
def upper_triangular(self) -> Matrix4:
|
|
155
|
+
...
|
|
156
|
+
class Vector2:
|
|
157
|
+
x: float
|
|
158
|
+
y: float
|
|
159
|
+
def __add__(self, arg0: Vector2) -> Vector2:
|
|
160
|
+
...
|
|
161
|
+
@typing.overload
|
|
162
|
+
def __init__(self) -> None:
|
|
163
|
+
...
|
|
164
|
+
@typing.overload
|
|
165
|
+
def __init__(self, arg0: typing.Iterable) -> None:
|
|
166
|
+
...
|
|
167
|
+
def __mul__(self, arg0: float) -> Vector2:
|
|
168
|
+
...
|
|
169
|
+
def __repr__(self) -> str:
|
|
170
|
+
...
|
|
171
|
+
def __str__(self) -> str:
|
|
172
|
+
...
|
|
173
|
+
def __sub__(self, arg0: Vector2) -> Vector2:
|
|
174
|
+
...
|
|
175
|
+
def __truediv__(self, arg0: float) -> Vector2:
|
|
176
|
+
...
|
|
177
|
+
def dot(self, arg0: Vector2) -> float:
|
|
178
|
+
...
|
|
179
|
+
def length(self) -> float:
|
|
180
|
+
...
|
|
181
|
+
def length_sqr(self) -> float:
|
|
182
|
+
...
|
|
183
|
+
def normalize(self) -> Vector2:
|
|
184
|
+
...
|
|
185
|
+
def projection(self, arg0: Vector2) -> tuple[Vector2, Vector2]:
|
|
186
|
+
...
|
|
187
|
+
class Vector3:
|
|
188
|
+
x: float
|
|
189
|
+
y: float
|
|
190
|
+
z: float
|
|
191
|
+
def __add__(self, arg0: Vector3) -> Vector3:
|
|
192
|
+
...
|
|
193
|
+
@typing.overload
|
|
194
|
+
def __init__(self) -> None:
|
|
195
|
+
...
|
|
196
|
+
@typing.overload
|
|
197
|
+
def __init__(self, arg0: typing.Iterable) -> None:
|
|
198
|
+
...
|
|
199
|
+
@typing.overload
|
|
200
|
+
def __init__(self, arg0: float, arg1: float, arg2: float) -> None:
|
|
201
|
+
...
|
|
202
|
+
@typing.overload
|
|
203
|
+
def __mul__(self, arg0: float) -> Vector3:
|
|
204
|
+
...
|
|
205
|
+
@typing.overload
|
|
206
|
+
def __mul__(self, arg0: Vector3) -> Vector3:
|
|
207
|
+
...
|
|
208
|
+
def __repr__(self) -> str:
|
|
209
|
+
...
|
|
210
|
+
def __str__(self) -> str:
|
|
211
|
+
...
|
|
212
|
+
def __sub__(self, arg0: Vector3) -> Vector3:
|
|
213
|
+
...
|
|
214
|
+
def __truediv__(self, arg0: float) -> Vector3:
|
|
215
|
+
...
|
|
216
|
+
def dot(self, arg0: Vector3) -> float:
|
|
217
|
+
...
|
|
218
|
+
def length(self) -> float:
|
|
219
|
+
...
|
|
220
|
+
def length_sqr(self) -> float:
|
|
221
|
+
...
|
|
222
|
+
def normalize(self) -> Vector3:
|
|
223
|
+
...
|
|
224
|
+
def projection(self, arg0: Vector3) -> tuple[Vector3, Vector3]:
|
|
225
|
+
...
|
|
226
|
+
class Vector4:
|
|
227
|
+
w: float
|
|
228
|
+
x: float
|
|
229
|
+
y: float
|
|
230
|
+
z: float
|
|
231
|
+
def __add__(self, arg0: Vector4) -> Vector4:
|
|
232
|
+
...
|
|
233
|
+
@typing.overload
|
|
234
|
+
def __init__(self) -> None:
|
|
235
|
+
...
|
|
236
|
+
@typing.overload
|
|
237
|
+
def __init__(self, arg0: typing.Iterable) -> None:
|
|
238
|
+
...
|
|
239
|
+
@typing.overload
|
|
240
|
+
def __init__(self, arg0: float, arg1: float, arg2: float, arg3: float) -> None:
|
|
241
|
+
...
|
|
242
|
+
@typing.overload
|
|
243
|
+
def __init__(self, arg0: Vector3) -> None:
|
|
244
|
+
...
|
|
245
|
+
def __mul__(self, arg0: float) -> Vector4:
|
|
246
|
+
...
|
|
247
|
+
def __repr__(self) -> str:
|
|
248
|
+
...
|
|
249
|
+
def __str__(self) -> str:
|
|
250
|
+
...
|
|
251
|
+
def __sub__(self, arg0: Vector4) -> Vector4:
|
|
252
|
+
...
|
|
253
|
+
def __truediv__(self, arg0: float) -> Vector4:
|
|
254
|
+
...
|
|
255
|
+
def dot(self, arg0: Vector4) -> float:
|
|
256
|
+
...
|
|
257
|
+
def length(self) -> float:
|
|
258
|
+
...
|
|
259
|
+
def length_sqr(self) -> float:
|
|
260
|
+
...
|
|
261
|
+
def normalize(self) -> Vector4:
|
|
262
|
+
...
|
|
263
|
+
def projection(self, arg0: Vector4) -> tuple[Vector4, Vector4]:
|
|
264
|
+
...
|
|
265
|
+
class order:
|
|
266
|
+
"""
|
|
267
|
+
Members:
|
|
268
|
+
|
|
269
|
+
row_major
|
|
270
|
+
|
|
271
|
+
col_major
|
|
272
|
+
"""
|
|
273
|
+
__members__: typing.ClassVar[dict[str, order]] # value = {'row_major': <order.row_major: 1>, 'col_major': <order.col_major: 0>}
|
|
274
|
+
col_major: typing.ClassVar[order] # value = <order.col_major: 0>
|
|
275
|
+
row_major: typing.ClassVar[order] # value = <order.row_major: 1>
|
|
276
|
+
def __eq__(self, other: typing.Any) -> bool:
|
|
277
|
+
...
|
|
278
|
+
def __getstate__(self) -> int:
|
|
279
|
+
...
|
|
280
|
+
def __hash__(self) -> int:
|
|
281
|
+
...
|
|
282
|
+
def __index__(self) -> int:
|
|
283
|
+
...
|
|
284
|
+
def __init__(self, value: int) -> None:
|
|
285
|
+
...
|
|
286
|
+
def __int__(self) -> int:
|
|
287
|
+
...
|
|
288
|
+
def __ne__(self, other: typing.Any) -> bool:
|
|
289
|
+
...
|
|
290
|
+
def __repr__(self) -> str:
|
|
291
|
+
...
|
|
292
|
+
def __setstate__(self, state: int) -> None:
|
|
293
|
+
...
|
|
294
|
+
def __str__(self) -> str:
|
|
295
|
+
...
|
|
296
|
+
@property
|
|
297
|
+
def name(self) -> str:
|
|
298
|
+
...
|
|
299
|
+
@property
|
|
300
|
+
def value(self) -> int:
|
|
301
|
+
...
|
|
302
|
+
col_major: order # value = <order.col_major: 0>
|
|
303
|
+
row_major: order # value = <order.row_major: 1>
|
|
File without changes
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "pybind11/pybind11.h"
|
|
4
|
+
|
|
5
|
+
#include "SupportingTypes.h"
|
|
6
|
+
|
|
7
|
+
namespace py = pybind11;
|
|
8
|
+
namespace m3d = math3d;
|
|
9
|
+
|
|
10
|
+
template<typename T>
|
|
11
|
+
void bind_Extent(py::module_ const& module, std::string_view className) {
|
|
12
|
+
using Extent = m3d::Extent<T>;
|
|
13
|
+
py::class_<Extent>(module, className.data())
|
|
14
|
+
.def(py::init([] {
|
|
15
|
+
Extent extent;
|
|
16
|
+
extent.min = std::numeric_limits<T>::max();
|
|
17
|
+
extent.max = -std::numeric_limits<T>::max();
|
|
18
|
+
return extent;
|
|
19
|
+
}))
|
|
20
|
+
.def(py::init([](T min, T max) {
|
|
21
|
+
Extent extent {};
|
|
22
|
+
extent.min = min;
|
|
23
|
+
extent.max = max;
|
|
24
|
+
return extent;
|
|
25
|
+
}))
|
|
26
|
+
.def_property("min",
|
|
27
|
+
[](Extent const& extent) {
|
|
28
|
+
return extent.min;
|
|
29
|
+
},
|
|
30
|
+
[](Extent& extent, T min) {
|
|
31
|
+
extent.min = min;
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
.def_property("max",
|
|
35
|
+
[](Extent const& extent) {
|
|
36
|
+
return extent.max;
|
|
37
|
+
},
|
|
38
|
+
[](Extent& extent, T max) {
|
|
39
|
+
extent.max = max;
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
.def("length", [](Extent const& extent) {
|
|
43
|
+
return extent.length();
|
|
44
|
+
})
|
|
45
|
+
.def("center", [](Extent const& extent) {
|
|
46
|
+
return extent.center();
|
|
47
|
+
})
|
|
48
|
+
.def("update", [](Extent& extent, T val) {
|
|
49
|
+
extent.min = std::min(extent.min, val);
|
|
50
|
+
extent.max = std::max(extent.max, val);
|
|
51
|
+
})
|
|
52
|
+
.def("__str__", [](Extent const& extent) {
|
|
53
|
+
return extent.asString();
|
|
54
|
+
})
|
|
55
|
+
.def("__repr__", [](Extent const& extent) {
|
|
56
|
+
return std::format("Extent = {} Valid = {}", extent.asString(), extent.min < extent.max);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
template<typename T>
|
|
61
|
+
void bind_Bounds(py::module_ const& module, std::string_view className) {
|
|
62
|
+
using Bounds = m3d::Bounds3D<T>;
|
|
63
|
+
py::class_<Bounds>(module, className.data())
|
|
64
|
+
.def(py::init())
|
|
65
|
+
.def(py::init([](m3d::Extent<T> const& x, m3d::Extent<T> const& y, m3d::Extent<T> const& z) {
|
|
66
|
+
return Bounds {x, y, z};
|
|
67
|
+
}))
|
|
68
|
+
.def("merge", [](Bounds& self, Bounds const& another) {
|
|
69
|
+
self.merge(another);
|
|
70
|
+
})
|
|
71
|
+
.def("__str__", [](Bounds const& bounds) {
|
|
72
|
+
return bounds.asString();
|
|
73
|
+
})
|
|
74
|
+
.def("__repr__", [](Bounds const& bounds) {
|
|
75
|
+
return std::format(
|
|
76
|
+
"{} Valid = {}\n"
|
|
77
|
+
"Center = {}\n"
|
|
78
|
+
"X Length = {}\n"
|
|
79
|
+
"Y Length = {}\n"
|
|
80
|
+
"Z Length = {}\n"
|
|
81
|
+
"Diagonal Length {}", bounds.asString(), bounds.isValid(), bounds.center().asString(),
|
|
82
|
+
bounds.x.length(), bounds.y.length(), bounds.z.length(), bounds.length());
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "math3d_py"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.4"
|
|
8
8
|
description = "Python bindings for 3dmath"
|
|
9
9
|
authors = [{ name = "Murali Dhanakoti", email = "dhanakoti.murali@gmail.com" }]
|
|
10
10
|
requires-python = ">=3.13,<3.14"
|
|
@@ -27,8 +27,8 @@ if [[ $# -eq 1 && "$1" == "major_ver" ]]; then
|
|
|
27
27
|
fi
|
|
28
28
|
|
|
29
29
|
rm -rf dist/*
|
|
30
|
-
CMAKE_BUILD_PARALLEL_LEVEL=$(sysctl -n hw.ncpu) \
|
|
31
|
-
CMAKE_ARGS="-DenableTesting=OFF" poetry run python -m build
|
|
32
30
|
touch py/math3d/py.typed
|
|
33
31
|
poetry run pybind11-stubgen math3d -o py
|
|
32
|
+
CMAKE_BUILD_PARALLEL_LEVEL="$(sysctl -n hw.ncpu)" \
|
|
33
|
+
CMAKE_ARGS="-DenableTesting=OFF" poetry run python -m build
|
|
34
34
|
poetry run twine upload dist/*
|
|
@@ -122,3 +122,27 @@ TEST(Bounds3D, Validity) {
|
|
|
122
122
|
{+0.5, +0.5, +0.5}};
|
|
123
123
|
ASSERT_TRUE(bounds.isValid()) << "Bounds initialized with a unit cube must have been classified as valid";
|
|
124
124
|
}
|
|
125
|
+
|
|
126
|
+
TEST(Extent, Merging) {
|
|
127
|
+
Extent e1 {-10.F, 0.F};
|
|
128
|
+
Extent constexpr e2 {5.F, 10.F};
|
|
129
|
+
e1.merge(e2);
|
|
130
|
+
ASSERT_EQ(e1.min, -10.F);
|
|
131
|
+
ASSERT_EQ(e1.max, 10.F);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
TEST(Bounds, Merging) {
|
|
135
|
+
Bounds3D smallerBounds {{-10, -10, -10}, {10, 10, 10}};
|
|
136
|
+
Bounds3D const biggerBounds {{-100, -100, -100}, {100, 100, 100}};
|
|
137
|
+
ASSERT_FALSE(smallerBounds.contains({-100, -100, -100}));
|
|
138
|
+
smallerBounds.merge(biggerBounds);
|
|
139
|
+
ASSERT_TRUE(smallerBounds.contains({-100, -100, -100}));
|
|
140
|
+
ASSERT_TRUE(smallerBounds.contains({100, 100, 100}));
|
|
141
|
+
|
|
142
|
+
Bounds3D boundsA {{-10, -10, -10}, { 10, 10, 10}};
|
|
143
|
+
Bounds3D const boundsB {{-100, -1, -2}, { 5, 200, 3}};
|
|
144
|
+
boundsA.merge(boundsB);
|
|
145
|
+
ASSERT_NEAR((boundsA.min() - Vector3{-100, -10, -10}).lengthSquared(), 0, 1e-6);
|
|
146
|
+
ASSERT_NEAR((boundsA.max() - Vector3{10, 200, 10}).lengthSquared(), 0, 1e-6);
|
|
147
|
+
|
|
148
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .math3d import *
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from math3d.math3d import AABB
|
|
3
|
+
from math3d.math3d import Extent
|
|
4
|
+
from math3d.math3d import Identity2
|
|
5
|
+
from math3d.math3d import Identity3
|
|
6
|
+
from math3d.math3d import Identity4
|
|
7
|
+
from math3d.math3d import LinearSystem2
|
|
8
|
+
from math3d.math3d import LinearSystem3
|
|
9
|
+
from math3d.math3d import LinearSystem4
|
|
10
|
+
from math3d.math3d import Matrix2
|
|
11
|
+
from math3d.math3d import Matrix3
|
|
12
|
+
from math3d.math3d import Matrix4
|
|
13
|
+
from math3d.math3d import Vector2
|
|
14
|
+
from math3d.math3d import Vector3
|
|
15
|
+
from math3d.math3d import Vector4
|
|
16
|
+
from math3d.math3d import order
|
|
17
|
+
from . import math3d
|
|
18
|
+
__all__: list[str] = ['AABB', 'Extent', 'Identity2', 'Identity3', 'Identity4', 'LinearSystem2', 'LinearSystem3', 'LinearSystem4', 'Matrix2', 'Matrix3', 'Matrix4', 'Vector2', 'Vector3', 'Vector4', 'col_major', 'math3d', 'order', 'row_major']
|
|
19
|
+
col_major: order # value = <order.col_major: 0>
|
|
20
|
+
row_major: order # value = <order.row_major: 1>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "pybind11/pybind11.h"
|
|
3
|
+
#include "LinearSystem.h"
|
|
4
|
+
|
|
5
|
+
namespace py = pybind11;
|
|
6
|
+
|
|
7
|
+
template<typename T, uint32_t Size>
|
|
8
|
+
void bind_linearSystem(py::module_ const& module, char const* className) {
|
|
9
|
+
|
|
10
|
+
using linear_system = math3d::LinearSystem<T, Size>;
|
|
11
|
+
|
|
12
|
+
py::class_<linear_system>(module, className)
|
|
13
|
+
.def_static("solve", &linear_system::solveLinearSystem);
|
|
14
|
+
|
|
15
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#include "pybind11/pybind11.h"
|
|
2
|
+
#include "vector.hpp"
|
|
3
|
+
#include "matrix.hpp"
|
|
4
|
+
#include "linear_system.hpp"
|
|
5
|
+
#include "types.hpp"
|
|
6
|
+
|
|
7
|
+
#include <unordered_map>
|
|
8
|
+
#include <format>
|
|
9
|
+
|
|
10
|
+
namespace {
|
|
11
|
+
|
|
12
|
+
#ifdef MAX_DIMENSIONS
|
|
13
|
+
auto constexpr MaxDimension {MAX_DIMENSIONS};
|
|
14
|
+
#else
|
|
15
|
+
auto constexpr MaxDimension {4};
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
enum class Type : uint8_t {
|
|
19
|
+
Vector,
|
|
20
|
+
Matrix,
|
|
21
|
+
LinearSystem,
|
|
22
|
+
IdentityMatrix,
|
|
23
|
+
Extent,
|
|
24
|
+
Bounds
|
|
25
|
+
};
|
|
26
|
+
std::unordered_map<Type, char const*> TypePrefixMap {
|
|
27
|
+
{Type::Vector, "Vector"},
|
|
28
|
+
{Type::Matrix, "Matrix"},
|
|
29
|
+
{Type::LinearSystem, "LinearSystem"},
|
|
30
|
+
{Type::IdentityMatrix, "Identity"},
|
|
31
|
+
{Type::Bounds, "AABB"},
|
|
32
|
+
{Type::Extent, "Extent"}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
template<typename Type, Type Start, Type End>
|
|
36
|
+
class TypeIterator {
|
|
37
|
+
public:
|
|
38
|
+
TypeIterator() = default;
|
|
39
|
+
|
|
40
|
+
TypeIterator begin() {
|
|
41
|
+
return *this;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
TypeIterator end() {
|
|
45
|
+
return TypeIterator{End + 1};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
bool operator==(TypeIterator const& another) {
|
|
49
|
+
return value == another.value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private:
|
|
53
|
+
std::underlying_type_t<Type> value {Start};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
auto pyCompositeTypeCreator = [](Type const type, pybind11::module_ const& pythonModule, auto const integerConstant) {
|
|
57
|
+
constexpr uint8_t dimension = integerConstant + 2;
|
|
58
|
+
auto const typeName = TypePrefixMap[type] + std::to_string(dimension);
|
|
59
|
+
if (typeName.empty()) {
|
|
60
|
+
throw std::runtime_error{std::format("Unknown type {}", std::to_underlying(type))};
|
|
61
|
+
}
|
|
62
|
+
switch (type) {
|
|
63
|
+
case Type::Vector:
|
|
64
|
+
bind_Vector<double, dimension>(pythonModule, typeName.c_str());
|
|
65
|
+
break;
|
|
66
|
+
case Type::Matrix:
|
|
67
|
+
bind_Matrix<double, dimension, dimension>(pythonModule, typeName.c_str());
|
|
68
|
+
break;
|
|
69
|
+
case Type::LinearSystem:
|
|
70
|
+
bind_linearSystem<double, dimension>(pythonModule, typeName.c_str());
|
|
71
|
+
break;
|
|
72
|
+
case Type::IdentityMatrix:
|
|
73
|
+
bind_identityMatrix<double, dimension, dimension>(pythonModule, typeName.c_str());
|
|
74
|
+
break;
|
|
75
|
+
default:
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
void createSimpleType(Type const type, pybind11::module_ const& module) {
|
|
81
|
+
auto const typeName = TypePrefixMap.at(type);
|
|
82
|
+
switch (type) {
|
|
83
|
+
case Type::Extent:
|
|
84
|
+
bind_Extent<double>(module, typeName);
|
|
85
|
+
break;
|
|
86
|
+
case Type::Bounds:
|
|
87
|
+
bind_Bounds<double>(module, typeName);
|
|
88
|
+
break;
|
|
89
|
+
default:
|
|
90
|
+
throw std::runtime_error(std::format("Unknown simple type {}", std::to_underlying(type)));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
template <uint8_t... integers>
|
|
96
|
+
void createCompositeType(Type const type, pybind11::module_& module, std::integer_sequence<uint8_t, integers...>) {
|
|
97
|
+
(pyCompositeTypeCreator(type, module, std::integral_constant<uint8_t, integers>{}), ...);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
PYBIND11_MODULE(math3d, module) {
|
|
102
|
+
// NOTE: std::make_integer_sequence returns integer_sequence<unsigned, 0, 1, ... , N-1>
|
|
103
|
+
// Therefore, when MaxDimension is 4, the integer sequence is 0, 1, 2 (range [0, 3)), which gets is translated to
|
|
104
|
+
// types with suffix 2, 3, 4 e.g. vec2, vec3, and vec4
|
|
105
|
+
auto constexpr intSeq = std::make_integer_sequence<uint8_t, MaxDimension-1>{};
|
|
106
|
+
createCompositeType(Type::Vector, module, intSeq);
|
|
107
|
+
py::enum_<math3d::Order>(module, "order")
|
|
108
|
+
.value("row_major", math3d::Order::RowMajor)
|
|
109
|
+
.value("col_major", math3d::Order::ColumnMajor)
|
|
110
|
+
.export_values();
|
|
111
|
+
createCompositeType(Type::Matrix, module, intSeq);
|
|
112
|
+
createCompositeType(Type::LinearSystem, module, intSeq);
|
|
113
|
+
createCompositeType(Type::IdentityMatrix, module, intSeq);
|
|
114
|
+
createSimpleType(Type::Extent, module);
|
|
115
|
+
createSimpleType(Type::Bounds, module);
|
|
116
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "pybind11/pybind11.h"
|
|
3
|
+
#include "pybind11/operators.h"
|
|
4
|
+
|
|
5
|
+
#include "MatrixOperations.h"
|
|
6
|
+
|
|
7
|
+
namespace py = pybind11;
|
|
8
|
+
|
|
9
|
+
template<typename T, uint32_t Rows, uint32_t Cols>
|
|
10
|
+
void bind_Matrix(py::module_ const& module, char const* className) {
|
|
11
|
+
|
|
12
|
+
using matrix = math3d::Matrix<T, Rows, Cols>;
|
|
13
|
+
using vector = math3d::Vector<T, Cols>;
|
|
14
|
+
|
|
15
|
+
py::class_<matrix>(module, className)
|
|
16
|
+
.def(py::init())
|
|
17
|
+
.def(py::init([](py::iterable const& data, math3d::Order const order) {
|
|
18
|
+
std::vector<std::vector<T>> dataAsVec;
|
|
19
|
+
for (auto outer : data) {
|
|
20
|
+
std::vector<T> inner = outer.cast<std::vector<T>>();
|
|
21
|
+
dataAsVec.push_back(std::move(inner));
|
|
22
|
+
}
|
|
23
|
+
return matrix{dataAsVec, order};
|
|
24
|
+
}))
|
|
25
|
+
.def("__getitem__", [](matrix const& matrix, uint32_t const index) {
|
|
26
|
+
return matrix.operator[](index);
|
|
27
|
+
})
|
|
28
|
+
.def("__getitem__", [](matrix const& matrix, std::pair<uint32_t, uint32_t> const& index_pair) {
|
|
29
|
+
return matrix.operator()(index_pair.first, index_pair.second);
|
|
30
|
+
})
|
|
31
|
+
.def("row", [](matrix const& matrix, uint32_t row) {
|
|
32
|
+
return matrix.operator()(row);
|
|
33
|
+
})
|
|
34
|
+
.def(py::self * py::self)
|
|
35
|
+
.def(py::self * vector{})
|
|
36
|
+
.def("__str__", &matrix::asString)
|
|
37
|
+
.def("__repr__", &matrix::asString)
|
|
38
|
+
|
|
39
|
+
// Operations
|
|
40
|
+
.def("transpose", &matrix::transpose)
|
|
41
|
+
.def("upper_triangular", [](matrix const& input) {
|
|
42
|
+
matrix output;
|
|
43
|
+
input.convertToUpperTriangular(output);
|
|
44
|
+
return output;
|
|
45
|
+
})
|
|
46
|
+
.def("determinant", &matrix::determinant)
|
|
47
|
+
.def("inverse", &matrix::inverse)
|
|
48
|
+
;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
template<typename T, uint32_t Rows, uint32_t Cols>
|
|
52
|
+
void bind_identityMatrix(py::module_ const& module, char const* className) {
|
|
53
|
+
using identityMatrix = math3d::IdentityMatrix<T, Rows, Cols>;
|
|
54
|
+
using matrix = math3d::Matrix<T, Rows, Cols>;
|
|
55
|
+
py::class_<identityMatrix, matrix>(module, className)
|
|
56
|
+
.def(py::init());
|
|
57
|
+
}
|
|
File without changes
|
|
@@ -11,18 +11,44 @@ template<typename T>
|
|
|
11
11
|
void bind_Extent(py::module_ const& module, std::string_view className) {
|
|
12
12
|
using Extent = m3d::Extent<T>;
|
|
13
13
|
py::class_<Extent>(module, className.data())
|
|
14
|
+
.def(py::init([] {
|
|
15
|
+
Extent extent;
|
|
16
|
+
extent.min = std::numeric_limits<T>::max();
|
|
17
|
+
extent.max = -std::numeric_limits<T>::max();
|
|
18
|
+
return extent;
|
|
19
|
+
}))
|
|
14
20
|
.def(py::init([](T min, T max) {
|
|
15
21
|
Extent extent {};
|
|
16
22
|
extent.min = min;
|
|
17
23
|
extent.max = max;
|
|
18
24
|
return extent;
|
|
19
25
|
}))
|
|
26
|
+
.def_property("min",
|
|
27
|
+
[](Extent const& extent) {
|
|
28
|
+
return extent.min;
|
|
29
|
+
},
|
|
30
|
+
[](Extent& extent, T min) {
|
|
31
|
+
extent.min = min;
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
.def_property("max",
|
|
35
|
+
[](Extent const& extent) {
|
|
36
|
+
return extent.max;
|
|
37
|
+
},
|
|
38
|
+
[](Extent& extent, T max) {
|
|
39
|
+
extent.max = max;
|
|
40
|
+
}
|
|
41
|
+
)
|
|
20
42
|
.def("length", [](Extent const& extent) {
|
|
21
43
|
return extent.length();
|
|
22
44
|
})
|
|
23
45
|
.def("center", [](Extent const& extent) {
|
|
24
46
|
return extent.center();
|
|
25
47
|
})
|
|
48
|
+
.def("update", [](Extent& extent, T val) {
|
|
49
|
+
extent.min = std::min(extent.min, val);
|
|
50
|
+
extent.max = std::max(extent.max, val);
|
|
51
|
+
})
|
|
26
52
|
.def("__str__", [](Extent const& extent) {
|
|
27
53
|
return extent.asString();
|
|
28
54
|
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include <ranges>
|
|
3
|
+
#include <string>
|
|
4
|
+
#include <algorithm>
|
|
5
|
+
|
|
6
|
+
namespace util {
|
|
7
|
+
inline auto convertSpaceToNewLine = [](std::string&& str) {
|
|
8
|
+
std::string result{std::move(str)};
|
|
9
|
+
std::ranges::replace(result.begin(), result.end(), ' ', '\n');
|
|
10
|
+
result = result.substr(1, result.size()-2);
|
|
11
|
+
return result;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "pybind11/pybind11.h"
|
|
3
|
+
#include "pybind11/operators.h"
|
|
4
|
+
#include "pybind11/stl.h"
|
|
5
|
+
#include "util.h"
|
|
6
|
+
#include "Vector.h"
|
|
7
|
+
|
|
8
|
+
namespace py = pybind11;
|
|
9
|
+
|
|
10
|
+
template<typename T, uint32_t Size>
|
|
11
|
+
void bind_Vector(py::module_ const& module, char const* className) {
|
|
12
|
+
using vector = math3d::Vector<T, Size>;
|
|
13
|
+
auto pyVecClass =
|
|
14
|
+
py::class_<vector>(module, className)
|
|
15
|
+
// Construction
|
|
16
|
+
.def(py::init())
|
|
17
|
+
.def(py::init([](py::iterable const& list) {
|
|
18
|
+
auto const input = list.cast<std::vector<T>>();
|
|
19
|
+
return vector{input};
|
|
20
|
+
}))
|
|
21
|
+
// Formatted output
|
|
22
|
+
.def("__str__", [](vector const& v) {
|
|
23
|
+
return util::convertSpaceToNewLine(v.asString());
|
|
24
|
+
})
|
|
25
|
+
.def("__repr__", [](vector const& v) {
|
|
26
|
+
return util::convertSpaceToNewLine(v.asString());
|
|
27
|
+
})
|
|
28
|
+
// Operations
|
|
29
|
+
.def(py::self + py::self)
|
|
30
|
+
.def(py::self - py::self)
|
|
31
|
+
.def(py::self * T{})
|
|
32
|
+
.def(py::self / T{})
|
|
33
|
+
.def("dot", &vector::dot)
|
|
34
|
+
.def("normalize", [](vector& v) { v.normalize(); return v; })
|
|
35
|
+
.def("length", [](vector const& v) { return v.length(); })
|
|
36
|
+
.def("length_sqr", [](vector const& v) { return v.lengthSquared(); })
|
|
37
|
+
.def("projection", [](vector const& self, vector const& u) {
|
|
38
|
+
auto vectorProjection = self.getVectorProjection(u);
|
|
39
|
+
return std::pair{vectorProjection.parallel, vectorProjection.perpendicular};
|
|
40
|
+
});
|
|
41
|
+
if constexpr (Size == 3) {
|
|
42
|
+
pyVecClass
|
|
43
|
+
.def(py::init([](T x, T y, T z) {
|
|
44
|
+
return vector({x, y, z});
|
|
45
|
+
}))
|
|
46
|
+
.def(py::self * py::self);
|
|
47
|
+
}
|
|
48
|
+
if constexpr (Size == 4) {
|
|
49
|
+
pyVecClass
|
|
50
|
+
.def(py::init([](T x, T y, T z, T w) {
|
|
51
|
+
return vector({x, y, z, w});
|
|
52
|
+
}))
|
|
53
|
+
.def(py::init([](math3d::Vector3<T> const& vec3) {
|
|
54
|
+
std::vector<T> input {vec3.x, vec3.y, vec3.z, 1.F};
|
|
55
|
+
return vector{input};
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Convenience member access (x, y, z, w)
|
|
60
|
+
// .x, .y, .z, .w are Vector<T, N>::Proxy and its conversion operator has to be invoked to get the raw value
|
|
61
|
+
// hence the static cast
|
|
62
|
+
if constexpr (Size >= 2 && Size <= 4) {
|
|
63
|
+
pyVecClass.def_property("x",
|
|
64
|
+
[](vector const& self) {
|
|
65
|
+
return static_cast<T>(self.x);
|
|
66
|
+
},
|
|
67
|
+
[](vector& self, T value) {
|
|
68
|
+
self.x = value;
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
.def_property("y",
|
|
72
|
+
[](vector const& self) {
|
|
73
|
+
return static_cast<T>(self.y);
|
|
74
|
+
},
|
|
75
|
+
[](vector& self, T value) {
|
|
76
|
+
self.y = value;
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
if constexpr (Size == 3 || Size == 4 ) {
|
|
81
|
+
pyVecClass.def_property("z",
|
|
82
|
+
[](vector const& self) {
|
|
83
|
+
return static_cast<T>(self.z);
|
|
84
|
+
},
|
|
85
|
+
[](vector& self, T value) {
|
|
86
|
+
self.z = value;
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
if constexpr (Size == 4) {
|
|
91
|
+
pyVecClass.def_property("w",
|
|
92
|
+
[](vector const& self) {
|
|
93
|
+
return static_cast<T>(self.w);
|
|
94
|
+
},
|
|
95
|
+
[](vector& self, T value) {
|
|
96
|
+
self.w = value;
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|