ncca-ngl 0.1.0__py3-none-any.whl

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.
ncca/ngl/vec4.py ADDED
@@ -0,0 +1,229 @@
1
+ """
2
+ Simple Float only Vec3 class for 3D graphics, very similar to the pyngl ones
3
+ """
4
+
5
+ import ctypes
6
+ import math
7
+
8
+ import numpy as np
9
+
10
+ from .log import logger
11
+
12
+
13
+ class Vec4:
14
+ __slots__ = ["_x", "_y", "_z", "_w"]
15
+ "by using slots we fix our class attributes to x,y,z,w"
16
+
17
+ def __init__(self, x=0.0, y=0.0, z=0.0, w=1.0):
18
+ """simple ctor"""
19
+ self._x = x # x component of vector : float
20
+ self._y = y # y component of vector : float
21
+ self._z = z # z component of vector : float
22
+ self._w = w # w component of vector : float
23
+
24
+ @classmethod
25
+ def sizeof(cls):
26
+ return 4 * ctypes.sizeof(ctypes.c_float)
27
+
28
+ def _validate_and_set(self, v, name):
29
+ """
30
+ check if v is a float or int
31
+ Args:
32
+ v (number): The value to check.
33
+ Raises:
34
+ ValueError: If v is not a float or int.
35
+ """
36
+ if not isinstance(v, (int, float)):
37
+ raise ValueError("need float or int")
38
+ else:
39
+ setattr(self, name, v)
40
+
41
+ def __iter__(self):
42
+ """
43
+ Make the Vec3 class iterable.
44
+ Yields:
45
+ float: The x, y, and z components of the vector.
46
+ """
47
+ yield self.x
48
+ yield self.y
49
+ yield self.z
50
+ yield self.w
51
+
52
+ def __getitem__(self, index):
53
+ """
54
+ Get the component of the vector at the given index.
55
+ Args:
56
+ index (int): The index of the component (0 for x, 1 for y, 2 for z).
57
+ Returns:
58
+ float: The value of the component at the given index.
59
+ Raises:
60
+ IndexError: If the index is out of range.
61
+ """
62
+ components = [self.x, self.y, self.z, self.w]
63
+ try:
64
+ return components[index]
65
+ except IndexError:
66
+ raise IndexError("Index out of range. Valid indices are 0, 1, 2, and 3.")
67
+
68
+ def clone(self) -> "Vec4":
69
+ """
70
+ Create a copy of the vector.
71
+ Returns:
72
+ Vec4: A new Vec4 instance with the same values.
73
+ """
74
+ return Vec4(self.x, self.y, self.z, self.w)
75
+
76
+ def __add__(self, rhs):
77
+ "return a+b vector addition"
78
+ r = Vec4()
79
+ r.x = self.x + rhs.x
80
+ r.y = self.y + rhs.y
81
+ r.z = self.z + rhs.z
82
+ r.w = self.w + rhs.w
83
+ return r
84
+
85
+ def __iadd__(self, rhs):
86
+ "return a+=b vector addition"
87
+ self.x += rhs.x
88
+ self.y += rhs.y
89
+ self.z += rhs.z
90
+ self.w += rhs.w
91
+
92
+ return self
93
+
94
+ def __sub__(self, rhs):
95
+ "return a+b vector addition"
96
+ r = Vec4()
97
+ r.x = self.x - rhs.x
98
+ r.y = self.y - rhs.y
99
+ r.z = self.z - rhs.z
100
+ r.w = self.w - rhs.w
101
+ return r
102
+
103
+ def __isub__(self, rhs):
104
+ "return a+=b vector addition"
105
+ self.x -= rhs.x
106
+ self.y -= rhs.y
107
+ self.z -= rhs.z
108
+ self.w -= rhs.w
109
+ return self
110
+
111
+ def set(self, x, y, z, w=1.0):
112
+ "set from x,y,z,w will convert to float an raise value error if problem"
113
+ try:
114
+ self.x = float(x)
115
+ self.y = float(y)
116
+ self.z = float(z)
117
+ self.w = float(w)
118
+ except ValueError:
119
+ logger.warning("need float values")
120
+ raise
121
+
122
+ def dot(self, rhs):
123
+ return (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z) + (self.w * rhs.w)
124
+
125
+ def length(self):
126
+ "length of vector"
127
+ return math.sqrt(self.x**2 + self.y**2 + self.z**2 + self.w**2)
128
+
129
+ def length_squared(self):
130
+ "square length of vector"
131
+ return self.x**2 + self.y**2 + self.z**2 + self.w**2
132
+
133
+ def normalize(self):
134
+ "normalize this vector"
135
+ length = self.length()
136
+ try:
137
+ self.x /= length
138
+ self.y /= length
139
+ self.z /= length
140
+ self.w /= length
141
+ except ZeroDivisionError:
142
+ raise ZeroDivisionError("cannot normalize the zero vector")
143
+ return self
144
+
145
+ def __eq__(self, rhs):
146
+ "test a==b using math.isclose"
147
+ if not isinstance(rhs, Vec4):
148
+ return NotImplemented
149
+ return (
150
+ math.isclose(self.x, rhs.x)
151
+ and math.isclose(self.y, rhs.y)
152
+ and math.isclose(self.z, rhs.z)
153
+ and math.isclose(self.w, rhs.w)
154
+ )
155
+
156
+ def __neq__(self, rhs):
157
+ "test a!=b using math.isclose"
158
+ if not isinstance(rhs, Vec4):
159
+ return NotImplemented
160
+ return not (
161
+ math.isclose(self.x, rhs.x)
162
+ and math.isclose(self.y, rhs.y)
163
+ and math.isclose(self.z, rhs.z)
164
+ and math.isclose(self.w, rhs.w)
165
+ )
166
+
167
+ def __neg__(self):
168
+ self.x = -self.x
169
+ self.y = -self.y
170
+ self.z = -self.z
171
+ self.w = -self.w
172
+ return self
173
+
174
+ def __mul__(self, rhs):
175
+ if isinstance(rhs, (float, int)):
176
+ "Vec4 * scalar multiplication"
177
+ return Vec4(self.x * rhs, self.y * rhs, self.z * rhs, self.w * rhs)
178
+ else:
179
+ raise ValueError
180
+
181
+ def __rmul__(self, rhs):
182
+ return self * rhs
183
+
184
+ def __truediv__(self, rhs):
185
+ if isinstance(rhs, (float, int)):
186
+ return Vec4(self.x / rhs, self.y / rhs, self.z / rhs, self.w / rhs)
187
+ elif isinstance(rhs, Vec4):
188
+ return Vec4(self.x / rhs.x, self.y / rhs.y, self.z / rhs.z, self.w / rhs.w)
189
+ else:
190
+ raise ValueError(f"can only do piecewise division with a scalar {rhs=}")
191
+
192
+ def __matmul__(self, rhs):
193
+ "Vec4 @ Mat4 matrix multiplication"
194
+ return Vec4(
195
+ self.x * rhs.m[0][0] + self.y * rhs.m[1][0] + self.z * rhs.m[2][0] + self.w * rhs.m[3][0],
196
+ self.x * rhs.m[0][1] + self.y * rhs.m[1][1] + self.z * rhs.m[2][1] + self.w * rhs.m[3][1],
197
+ self.x * rhs.m[0][2] + self.y * rhs.m[1][2] + self.z * rhs.m[2][2] + self.w * rhs.m[3][2],
198
+ self.x * rhs.m[0][3] + self.y * rhs.m[1][3] + self.z * rhs.m[2][3] + self.w * rhs.m[3][3],
199
+ )
200
+
201
+ def __repr__(self):
202
+ "repr for debugging purposes"
203
+ return f"Vec4 [{self.x},{self.y},{self.z},{self.w}]"
204
+
205
+ def __str__(self):
206
+ "print out the vector as a string"
207
+ return f"[{self.x},{self.y},{self.z},{self.w}]"
208
+
209
+ def to_list(self):
210
+ return [self.x, self.y, self.z, self.w]
211
+
212
+ def to_numpy(self):
213
+ return np.array([self.x, self.y, self.z, self.w])
214
+
215
+
216
+ # Helper function to create properties
217
+ def _create_property(attr_name):
218
+ def getter(self):
219
+ return getattr(self, f"_{attr_name}")
220
+
221
+ def setter(self, value):
222
+ self._validate_and_set(value, f"_{attr_name}")
223
+
224
+ return property(getter, setter)
225
+
226
+
227
+ # Dynamically add properties for x, y, z,w
228
+ for attr in ["x", "y", "z", "w"]:
229
+ setattr(Vec4, attr, _create_property(attr))
ncca/ngl/vec4_array.py ADDED
@@ -0,0 +1,106 @@
1
+ """
2
+ A container for ngl.Vec4 objects that mimics some of the behavior of a std::vector
3
+ """
4
+
5
+ import numpy as np
6
+
7
+ from .vec4 import Vec4
8
+
9
+
10
+ class Vec4Array:
11
+ """
12
+ A class to hold a list of Vec4 objects and perform operations on them.
13
+ """
14
+
15
+ def __init__(self, values=None):
16
+ """
17
+ Initializes the Vec4Array.
18
+
19
+ Args:
20
+ values (iterable, optional): An iterable of Vec4 objects. Defaults to None.
21
+ """
22
+ self._data = []
23
+ if values is not None:
24
+ for v in values:
25
+ if not isinstance(v, Vec4):
26
+ raise TypeError("All elements must be of type Vec4")
27
+ self._data.append(v)
28
+
29
+ def __getitem__(self, index):
30
+ """
31
+ Get the Vec4 at the specified index.
32
+
33
+ Args:
34
+ index (int): The index of the element.
35
+
36
+ Returns:
37
+ Vec4: The Vec4 object at the given index.
38
+ """
39
+ return self._data[index]
40
+
41
+ def __len__(self):
42
+ """
43
+ Return the number of elements in the array.
44
+ """
45
+ return len(self._data)
46
+
47
+ def __iter__(self):
48
+ """
49
+ Return an iterator for the array.
50
+ """
51
+ return iter(self._data)
52
+
53
+ def append(self, value):
54
+ """
55
+ Append a Vec4 object to the array.
56
+
57
+ Args:
58
+ value (Vec4): The Vec4 object to append.
59
+ """
60
+ if not isinstance(value, Vec4):
61
+ raise TypeError("Only Vec4 objects can be appended")
62
+ self._data.append(value)
63
+
64
+ def extend(self, values):
65
+ """
66
+ Extend the array with a list of Vec4 objects.
67
+
68
+ Args:
69
+ values (list): A list of Vec4 objects to extend.
70
+ """
71
+ if not all(isinstance(v, Vec4) for v in values):
72
+ raise TypeError("All elements must be of type Vec4")
73
+ self._data.extend(values)
74
+
75
+ def to_list(self):
76
+ """
77
+ Convert the array of Vec4 objects to a single flat list of floats.
78
+
79
+ Returns:
80
+ list: A list of x, y, z, w components concatenated.
81
+ """
82
+ return [comp for vec in self._data for comp in vec]
83
+
84
+ def to_numpy(self):
85
+ """
86
+ Convert the array of Vec4 objects to a numpy array.
87
+
88
+ Returns:
89
+ numpy.ndarray: A numpy array of the vector data.
90
+ """
91
+ return np.array(self.to_list(), dtype=np.float32)
92
+
93
+ def __repr__(self):
94
+ return f"Vec4Array({self._data!r})"
95
+
96
+ def __str__(self):
97
+ return str(self._data)
98
+
99
+ def sizeof(self):
100
+ """
101
+ Return the size of the array in bytes.
102
+
103
+ Returns:
104
+ int: The size of the array in bytes.
105
+ """
106
+ return len(self._data) * Vec4.sizeof()
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.4
2
+ Name: ncca-ngl
3
+ Version: 0.1.0
4
+ Summary: A Python version of the NGL graphics library.
5
+ Author-email: Jon Macey <jmacey@bournemouth.ac.uk>
6
+ License: Copyright 2024 Jon Macey
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
+ Project-URL: Homepage, https://github.com/NCCA/PyNGL
14
+ Project-URL: Issues, https://github.com/NCCA/PyNGL/issues
15
+ Requires-Python: >=3.13
16
+ License-File: LICENSE.txt
17
+ Requires-Dist: numpy>=2.3.3
18
+ Requires-Dist: PyOpenGL
19
+ Requires-Dist: Pillow
20
+ Requires-Dist: glfw>=2.9.0
21
+ Requires-Dist: freetype-py>=2.5.1
22
+ Requires-Dist: pyside6>=6.9.2
23
+ Dynamic: license-file
@@ -0,0 +1,41 @@
1
+ ncca/ngl/__init__.py,sha256=i01MBdh814MrDmPDvG4dPI6azBWZWTq212cfVNnKkR8,2308
2
+ ncca/ngl/abstract_vao.py,sha256=VLKp3pmPYK_dQgEImMOAQ0DufAswK_0H4DR4r8flp2U,2104
3
+ ncca/ngl/base_mesh.py,sha256=2JmVT5_bvgLHra1VnwRld-mh-20IqqekgEu1dbGU1a4,5736
4
+ ncca/ngl/base_mesh.pyi,sha256=kobLuNnCSZlRRobIgVopQaS7Bjg0tJ3m4M64WXt5I-M,173
5
+ ncca/ngl/bbox.py,sha256=PylB6ju_bkdDUqQkzO1n2E-jsmxiviNkyBLY-sN59n8,6578
6
+ ncca/ngl/bezier_curve.py,sha256=A0aidWJ7c8Bh2KGCgCJ7aH8c8MakP8xrFFEFvCjva38,2297
7
+ ncca/ngl/first_person_camera.py,sha256=Rrt3ibMh72K8gPBu6B8neIbYk5lnNZcDnvBB8mq5pz0,5890
8
+ ncca/ngl/image.py,sha256=zpG8egzXWkUJKQxpRhXndpRxJDKOKHZkDjQuKSRXN2E,2692
9
+ ncca/ngl/log.py,sha256=b7l-XNJIpP36VqcCGXBV_0XT5Nkd5eyuC7043lWegcw,1282
10
+ ncca/ngl/mat2.py,sha256=algDowqqP_pQ3Crl-xiqkQqRaYohfpymfaZYxvbH0qc,3437
11
+ ncca/ngl/mat3.py,sha256=imWKkMuPPWLctIpU2lDqKTu014bWHSq5eEpIj4E7MzE,12404
12
+ ncca/ngl/mat4.py,sha256=eGvmLfw_wwKuuVh29wAKrvSZJB41jgmcYV5EufzyXbo,17273
13
+ ncca/ngl/multi_buffer_vao.py,sha256=cuNE6gSrqkNcYvfIOYOZp4MVnpCvChUgnzsf7b60pWg,1752
14
+ ncca/ngl/obj.py,sha256=AGldNouHrkrDs2UhATClGkgo4dzr6lzArR4YeCxQKmo,13667
15
+ ncca/ngl/plane.py,sha256=96WuGzexYKhoeRVevGP2pZcustt9fzyyAjuwJHT25tk,1299
16
+ ncca/ngl/primitives.py,sha256=G4X5kPROgcO2hZf8YkYvviS5C2kPLXrlSerJUdD6Fog,22575
17
+ ncca/ngl/pyside_event_handling_mixin.py,sha256=L8obXeTp-g2Va2eXyd1hnmSp-sY7p4GX6EcFYRnH1F4,10588
18
+ ncca/ngl/quaternion.py,sha256=MeQ-oxufo96TJ1GusRdpaHJsjfD6hG1ADsqTiBbHxlM,3814
19
+ ncca/ngl/random.py,sha256=wX1R2rMpb76TP4rk44NUp5XoVuMisH9d-eBG5kFBZsM,5579
20
+ ncca/ngl/shader.py,sha256=fEz8R_itsQssIxQp1E8-PhY3aOaTdm7sXpyFYoARSic,7696
21
+ ncca/ngl/shader_lib.py,sha256=YmF3EJM9roTEt5OI5sHonAVN_ydIseyiOUBFZTX4KdA,18627
22
+ ncca/ngl/shader_program.py,sha256=GAOWSlixWn6IzN4mM6tIahKtQytsatUXQVsNhu2ynO4,28407
23
+ ncca/ngl/simple_index_vao.py,sha256=1IVy1WQH4V8_viZbRoIMbDRJsiH7iAhw0GEWUV9KpAU,2338
24
+ ncca/ngl/simple_vao.py,sha256=jfU2O3yliaM6iWNvfcRbjQ6o2_IVSPrOR3GthDiul6Q,1419
25
+ ncca/ngl/text.py,sha256=dMakFdwCWNY4PWbOF8SPZsYa-qFUzwTBp1XfrGnY6l0,13535
26
+ ncca/ngl/texture.py,sha256=OgBBEItgUDohCsVWgmjEWcQWBJaXl9w070PTOOywPx4,2303
27
+ ncca/ngl/transform.py,sha256=_PibgtFoU_exfvQUWucmts0WF5OreSTNbftvSa3zT8g,2938
28
+ ncca/ngl/util.py,sha256=RLgGmxTq4gzlMKdAfLrO3gtV8VUSP5WtQK4hyLV6waQ,3558
29
+ ncca/ngl/vao_factory.py,sha256=v87VfrUMaoqcsE-CS9kM7h5Fyk_e0LGl_iA6xqaomPg,930
30
+ ncca/ngl/vec2.py,sha256=hJ0RWBxmeh-OOro_Y9lKocgiuu0f9vxp6L2_6vKfwUQ,10331
31
+ ncca/ngl/vec2_array.py,sha256=k3jYqUqsc_nXVxzpkipNw49-y6uFEQZBHiBkA5s4u0A,2693
32
+ ncca/ngl/vec3.py,sha256=q4HI4y4Xk3lTdlB8YdF4T2mCdwK2jXRattjDHlJi7vg,12265
33
+ ncca/ngl/vec3_array.py,sha256=okRU8rp-jGYg2AzEUWx-ErsBkH1fG4L16c8nGKu-v04,2808
34
+ ncca/ngl/vec4.py,sha256=zF0zw5EO4UE7EmqN30LPR3QQfaMcA1VcMID8CZALDiU,6740
35
+ ncca/ngl/vec4_array.py,sha256=CCyHM4nIHvlwWxa12jCrJp-j6qfIYvU_irbdcB7NO0g,2699
36
+ ncca/ngl/PrimData/pack_arrays.py,sha256=aWShJX8QPHXKTj66C8yu1DskmD3VEzFXyaADcxw6YKs,362
37
+ ncca_ngl-0.1.0.dist-info/licenses/LICENSE.txt,sha256=WY4-vI3NTjw6HGwshZcyvEYhvAKBX3rpY7x9wMF_FhA,1056
38
+ ncca_ngl-0.1.0.dist-info/METADATA,sha256=K_RFj72JMSY1SwA0-7kBTMECJ-35KHRe0G029qb4WSM,1620
39
+ ncca_ngl-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
+ ncca_ngl-0.1.0.dist-info/top_level.txt,sha256=nCKLyKtzlEVkOyE2KwxaykU3UgPocbQqRoMUXcICm3s,5
41
+ ncca_ngl-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,7 @@
1
+ Copyright 2024 Jon Macey
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ ncca