e2D 2.0.0__cp313-cp313-win_amd64.whl → 2.0.1__cp313-cp313-win_amd64.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.
- e2D/__init__.py +199 -72
- e2D/__init__.pyi +145 -0
- e2D/ccolors.c +34514 -0
- e2D/ccolors.cp313-win_amd64.pyd +0 -0
- e2D/ccolors.pyi +51 -0
- e2D/ccolors.pyx +350 -0
- e2D/color_defs.py +238 -0
- e2D/colors.py +380 -0
- e2D/colors.pyi +104 -0
- e2D/commons.py +38 -10
- e2D/commons.pyi +79 -0
- e2D/cvectors.c +152 -152
- e2D/cvectors.cp313-win_amd64.pyd +0 -0
- e2D/cvectors.pyi +243 -0
- e2D/devices.py +19 -6
- e2D/devices.pyi +65 -0
- e2D/plots.py +55 -29
- e2D/plots.pyi +238 -0
- e2D/shapes.py +81 -44
- e2D/shapes.pyi +272 -0
- e2D/test_colors.py +122 -0
- e2D/text_renderer.py +46 -16
- e2D/text_renderer.pyi +118 -0
- e2D/types.py +58 -0
- e2D/types.pyi +61 -0
- e2D/vectors.py +153 -61
- e2D/vectors.pyi +106 -0
- e2D/winrec.py +275 -0
- e2D/winrec.pyi +87 -0
- {e2d-2.0.0.dist-info → e2d-2.0.1.dist-info}/METADATA +43 -15
- e2d-2.0.1.dist-info/RECORD +46 -0
- {e2d-2.0.0.dist-info → e2d-2.0.1.dist-info}/WHEEL +1 -1
- e2d-2.0.0.dist-info/RECORD +0 -26
- {e2d-2.0.0.dist-info → e2d-2.0.1.dist-info}/licenses/LICENSE +0 -0
- {e2d-2.0.0.dist-info → e2d-2.0.1.dist-info}/top_level.txt +0 -0
e2D/plots.pyi
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Type stubs for plots module
|
|
3
|
+
2D plotting with GPU-accelerated rendering
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Optional, Callable
|
|
7
|
+
from enum import Enum
|
|
8
|
+
import numpy as np
|
|
9
|
+
import numpy.typing as npt
|
|
10
|
+
from .types import BufferType, ColorType, ComputeShaderType, ContextType, ProgramType, VAOType, VectorType
|
|
11
|
+
from .color_defs import GRAY10, GRAY50, WHITE, RED, CYAN, TRANSPARENT
|
|
12
|
+
|
|
13
|
+
class ShaderManager:
|
|
14
|
+
"""Cache and manage shader files for the plots module."""
|
|
15
|
+
_cache: dict[str, str]
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def load_shader(path: str) -> str:
|
|
19
|
+
"""Load a shader file with caching."""
|
|
20
|
+
...
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def create_program(ctx: ContextType, vertex_path: str, fragment_path: str) -> ProgramType:
|
|
24
|
+
"""Create a program from shader files."""
|
|
25
|
+
...
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def create_compute(ctx: ContextType, compute_path: str) -> ComputeShaderType:
|
|
29
|
+
"""Create a compute shader from file."""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
class View2D:
|
|
33
|
+
"""
|
|
34
|
+
Manages coordinate space (World <-> Clip) via UBO.
|
|
35
|
+
"""
|
|
36
|
+
ctx: ContextType
|
|
37
|
+
binding: int
|
|
38
|
+
center: npt.NDArray[np.float32]
|
|
39
|
+
zoom: float
|
|
40
|
+
aspect: float
|
|
41
|
+
resolution: npt.NDArray[np.float32]
|
|
42
|
+
buffer: BufferType
|
|
43
|
+
|
|
44
|
+
def __init__(self, ctx: ContextType, binding: int = 0) -> None: ...
|
|
45
|
+
|
|
46
|
+
def update_win_size(self, width: int, height: int) -> None: ...
|
|
47
|
+
def pan(self, dx: float, dy: float) -> None: ...
|
|
48
|
+
def zoom_step(self, factor: float) -> None: ...
|
|
49
|
+
def zoom_at(self, factor: float, ndc_x: float, ndc_y: float) -> None: ...
|
|
50
|
+
def update_buffer(self) -> None: ...
|
|
51
|
+
|
|
52
|
+
class PlotSettings:
|
|
53
|
+
bg_color: ColorType
|
|
54
|
+
show_axis: bool
|
|
55
|
+
axis_color: ColorType
|
|
56
|
+
axis_width: float
|
|
57
|
+
show_grid: bool
|
|
58
|
+
grid_color: ColorType
|
|
59
|
+
grid_spacing: float
|
|
60
|
+
|
|
61
|
+
def __init__(
|
|
62
|
+
self,
|
|
63
|
+
bg_color: ColorType = (0.1, 0.1, 0.1, 1.0),
|
|
64
|
+
show_axis: bool = True,
|
|
65
|
+
axis_color: ColorType = (0.5, 0.5, 0.5, 1.0),
|
|
66
|
+
axis_width: float = 2.0,
|
|
67
|
+
show_grid: bool = True,
|
|
68
|
+
grid_color: ColorType = (0.2, 0.2, 0.2, 1.0),
|
|
69
|
+
grid_spacing: float = 1.0
|
|
70
|
+
) -> None: ...
|
|
71
|
+
|
|
72
|
+
class CurveSettings:
|
|
73
|
+
color: ColorType
|
|
74
|
+
width: float
|
|
75
|
+
count: int
|
|
76
|
+
|
|
77
|
+
def __init__(
|
|
78
|
+
self,
|
|
79
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0),
|
|
80
|
+
width: float = 2.0,
|
|
81
|
+
count: int = 1024
|
|
82
|
+
) -> None:
|
|
83
|
+
self.color = color
|
|
84
|
+
self.width = width
|
|
85
|
+
self.count = count
|
|
86
|
+
|
|
87
|
+
class ImplicitSettings:
|
|
88
|
+
color: ColorType
|
|
89
|
+
thickness: float
|
|
90
|
+
|
|
91
|
+
def __init__(
|
|
92
|
+
self,
|
|
93
|
+
color: ColorType = (0.4, 0.6, 1.0, 1.0),
|
|
94
|
+
thickness: float = 2.0
|
|
95
|
+
) -> None: ...
|
|
96
|
+
|
|
97
|
+
class LineType(Enum):
|
|
98
|
+
NONE: int
|
|
99
|
+
DIRECT: int
|
|
100
|
+
BEZIER_QUADRATIC: int
|
|
101
|
+
BEZIER_CUBIC: int
|
|
102
|
+
SMOOTH: int
|
|
103
|
+
|
|
104
|
+
class StreamSettings:
|
|
105
|
+
point_color: ColorType
|
|
106
|
+
point_radius: float
|
|
107
|
+
show_points: bool
|
|
108
|
+
round_points: bool
|
|
109
|
+
line_type: LineType
|
|
110
|
+
line_color: ColorType
|
|
111
|
+
line_width: float
|
|
112
|
+
curve_segments: int
|
|
113
|
+
|
|
114
|
+
def __init__(
|
|
115
|
+
self,
|
|
116
|
+
point_color: ColorType = (1.0, 0.0, 0.0, 1.0),
|
|
117
|
+
point_radius: float = 5.0,
|
|
118
|
+
show_points: bool = True,
|
|
119
|
+
round_points: bool = True,
|
|
120
|
+
line_type: LineType|int = LineType.DIRECT,
|
|
121
|
+
line_color: ColorType = (1.0, 0.0, 0.0, 1.0),
|
|
122
|
+
line_width: float = 2.0,
|
|
123
|
+
curve_segments: int = 10
|
|
124
|
+
) -> None: ...
|
|
125
|
+
|
|
126
|
+
class Plot2D:
|
|
127
|
+
"""A specific rectangular area on the screen for plotting."""
|
|
128
|
+
ctx: ContextType
|
|
129
|
+
top_left: VectorType
|
|
130
|
+
bottom_right: VectorType
|
|
131
|
+
settings: PlotSettings
|
|
132
|
+
width: int
|
|
133
|
+
height: int
|
|
134
|
+
view: View2D
|
|
135
|
+
viewport: tuple[int, int, int, int]
|
|
136
|
+
grid_prog: ProgramType
|
|
137
|
+
grid_quad: BufferType
|
|
138
|
+
grid_vao: VAOType
|
|
139
|
+
is_dragging: bool
|
|
140
|
+
last_mouse_pos: VectorType
|
|
141
|
+
|
|
142
|
+
def __init__(
|
|
143
|
+
self,
|
|
144
|
+
ctx: ContextType,
|
|
145
|
+
top_left: VectorType,
|
|
146
|
+
bottom_right: VectorType,
|
|
147
|
+
settings: Optional[PlotSettings] = None
|
|
148
|
+
) -> None: ...
|
|
149
|
+
|
|
150
|
+
def set_rect(self, top_left: VectorType, bottom_right: VectorType) -> None: ...
|
|
151
|
+
def update_window_size(self, win_width: int, win_height: int) -> None: ...
|
|
152
|
+
def render(self, draw_callback: Callable[[], None]) -> None: ...
|
|
153
|
+
def contains(self, x: float, y: float) -> bool: ...
|
|
154
|
+
def on_mouse_drag(self, dx: float, dy: float) -> None: ...
|
|
155
|
+
def on_scroll(self, yoffset: float, mouse_x: float, mouse_y: float) -> None: ...
|
|
156
|
+
|
|
157
|
+
class GpuStream:
|
|
158
|
+
"""Ring-buffer on GPU for high-performance point streaming."""
|
|
159
|
+
ctx: ContextType
|
|
160
|
+
capacity: int
|
|
161
|
+
settings: StreamSettings
|
|
162
|
+
head: int
|
|
163
|
+
size: int
|
|
164
|
+
buffer: BufferType
|
|
165
|
+
prog: ProgramType
|
|
166
|
+
vao: VAOType
|
|
167
|
+
smooth_prog: ProgramType
|
|
168
|
+
smooth_vao: VAOType
|
|
169
|
+
|
|
170
|
+
def __init__(
|
|
171
|
+
self,
|
|
172
|
+
ctx: ContextType,
|
|
173
|
+
capacity: int = 100000,
|
|
174
|
+
settings: Optional[StreamSettings] = None
|
|
175
|
+
) -> None: ...
|
|
176
|
+
|
|
177
|
+
def push(self, points: npt.NDArray[np.float32]) -> None: ...
|
|
178
|
+
def draw(self) -> None: ...
|
|
179
|
+
def shift_points(self, offset: VectorType) -> None: ...
|
|
180
|
+
|
|
181
|
+
class ComputeCurve:
|
|
182
|
+
"""Parametric curve p(t) evaluated entirely on GPU."""
|
|
183
|
+
ctx: ContextType
|
|
184
|
+
count: int
|
|
185
|
+
t_range: tuple[float, float]
|
|
186
|
+
settings: CurveSettings
|
|
187
|
+
vbo: BufferType
|
|
188
|
+
compute_prog: ComputeShaderType
|
|
189
|
+
render_prog: ProgramType
|
|
190
|
+
vao: VAOType
|
|
191
|
+
|
|
192
|
+
def __init__(
|
|
193
|
+
self,
|
|
194
|
+
ctx: ContextType,
|
|
195
|
+
func_body: str,
|
|
196
|
+
t_range: tuple[float, float],
|
|
197
|
+
count: int = 1024,
|
|
198
|
+
settings: Optional[CurveSettings] = None
|
|
199
|
+
) -> None: ...
|
|
200
|
+
|
|
201
|
+
def update(self) -> None: ...
|
|
202
|
+
def draw(self) -> None: ...
|
|
203
|
+
|
|
204
|
+
class ImplicitPlot:
|
|
205
|
+
"""Rendering of f(x,y)=0 via Fragment Shader and SDF."""
|
|
206
|
+
ctx: ContextType
|
|
207
|
+
settings: ImplicitSettings
|
|
208
|
+
quad: BufferType
|
|
209
|
+
prog: ProgramType
|
|
210
|
+
vao: VAOType
|
|
211
|
+
|
|
212
|
+
def __init__(
|
|
213
|
+
self,
|
|
214
|
+
ctx: ContextType,
|
|
215
|
+
func_body: str,
|
|
216
|
+
settings: Optional[ImplicitSettings] = None
|
|
217
|
+
) -> None: ...
|
|
218
|
+
|
|
219
|
+
def draw(self) -> None: ...
|
|
220
|
+
|
|
221
|
+
class SegmentDisplay:
|
|
222
|
+
"""Simple 7-segment display renderer for numbers."""
|
|
223
|
+
ctx: ContextType
|
|
224
|
+
prog: ProgramType
|
|
225
|
+
vbo: BufferType
|
|
226
|
+
vao: VAOType
|
|
227
|
+
digits: dict[str, list[int]]
|
|
228
|
+
|
|
229
|
+
def __init__(self, ctx: ContextType) -> None: ...
|
|
230
|
+
|
|
231
|
+
def draw_number(
|
|
232
|
+
self,
|
|
233
|
+
text: str,
|
|
234
|
+
x: float,
|
|
235
|
+
y: float,
|
|
236
|
+
size: float = 20.0,
|
|
237
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0)
|
|
238
|
+
) -> None: ...
|
e2D/shapes.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import moderngl
|
|
2
2
|
import numpy as np
|
|
3
3
|
from .commons import get_pattr, get_pattr_value, set_pattr_value
|
|
4
|
+
from .types import VAOType, VectorType, ColorType, ContextType, ProgramType, BufferType
|
|
5
|
+
from .colors import normalize_color
|
|
6
|
+
from .color_defs import WHITE, BLACK, TRANSPARENT
|
|
4
7
|
from typing import Optional, Sequence
|
|
5
8
|
from enum import Enum
|
|
6
9
|
|
|
@@ -12,8 +15,15 @@ class FillMode(Enum):
|
|
|
12
15
|
|
|
13
16
|
class ShapeLabel:
|
|
14
17
|
"""A pre-rendered shape for efficient repeated drawing."""
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
ctx: ContextType
|
|
19
|
+
prog: ProgramType
|
|
20
|
+
vbo: BufferType
|
|
21
|
+
vao: VAOType
|
|
22
|
+
vertex_count: int
|
|
23
|
+
shape_type: str
|
|
24
|
+
|
|
25
|
+
def __init__(self, ctx: ContextType, prog: ProgramType,
|
|
26
|
+
vbo: BufferType, vertex_count: int, shape_type: str = 'line') -> None:
|
|
17
27
|
self.ctx = ctx
|
|
18
28
|
self.prog = prog
|
|
19
29
|
self.vbo = vbo
|
|
@@ -45,7 +55,18 @@ class ShapeLabel:
|
|
|
45
55
|
|
|
46
56
|
class InstancedShapeBatch:
|
|
47
57
|
"""High-performance instanced batch for drawing thousands of shapes with minimal CPU overhead."""
|
|
48
|
-
|
|
58
|
+
ctx: ContextType
|
|
59
|
+
prog: ProgramType
|
|
60
|
+
shape_type: str
|
|
61
|
+
max_instances: int
|
|
62
|
+
instance_count: int
|
|
63
|
+
floats_per_instance: int
|
|
64
|
+
instance_buffer: BufferType
|
|
65
|
+
quad_vbo: BufferType
|
|
66
|
+
vao: VAOType
|
|
67
|
+
instance_data: list[float]
|
|
68
|
+
|
|
69
|
+
def __init__(self, ctx: ContextType, prog: ProgramType, shape_type: str = 'circle', max_instances: int = 100000) -> None:
|
|
49
70
|
self.ctx = ctx
|
|
50
71
|
self.prog = prog
|
|
51
72
|
self.shape_type = shape_type
|
|
@@ -128,9 +149,9 @@ class InstancedShapeBatch:
|
|
|
128
149
|
|
|
129
150
|
self.instance_data = []
|
|
130
151
|
|
|
131
|
-
def add_circle(self, center:
|
|
132
|
-
color:
|
|
133
|
-
border_color:
|
|
152
|
+
def add_circle(self, center: VectorType, radius: float,
|
|
153
|
+
color: ColorType = WHITE,
|
|
154
|
+
border_color: ColorType = TRANSPARENT,
|
|
134
155
|
border_width: float = 0.0,
|
|
135
156
|
antialiasing: float = 1.0) -> None:
|
|
136
157
|
"""Add a circle instance to the batch."""
|
|
@@ -171,10 +192,10 @@ class InstancedShapeBatch:
|
|
|
171
192
|
self.instance_data.extend(data.ravel())
|
|
172
193
|
self.instance_count += n
|
|
173
194
|
|
|
174
|
-
def add_rect(self, center:
|
|
175
|
-
color:
|
|
195
|
+
def add_rect(self, center: VectorType, size: VectorType,
|
|
196
|
+
color: ColorType = WHITE,
|
|
176
197
|
corner_radius: float = 0.0,
|
|
177
|
-
border_color:
|
|
198
|
+
border_color: ColorType = TRANSPARENT,
|
|
178
199
|
border_width: float = 0.0,
|
|
179
200
|
antialiasing: float = 1.0,
|
|
180
201
|
rotation: float = 0.0) -> None:
|
|
@@ -225,9 +246,9 @@ class InstancedShapeBatch:
|
|
|
225
246
|
self.instance_data.extend(data.ravel())
|
|
226
247
|
self.instance_count += n
|
|
227
248
|
|
|
228
|
-
def add_line(self, start:
|
|
249
|
+
def add_line(self, start: VectorType, end: VectorType,
|
|
229
250
|
width: float = 1.0,
|
|
230
|
-
color:
|
|
251
|
+
color: ColorType = WHITE) -> None:
|
|
231
252
|
"""Add a line instance to the batch."""
|
|
232
253
|
self.instance_data.extend([*start, *end, width, *color])
|
|
233
254
|
self.instance_count += 1
|
|
@@ -282,8 +303,21 @@ class ShapeRenderer:
|
|
|
282
303
|
High-performance 2D shape renderer using SDF (Signed Distance Functions) and GPU shaders.
|
|
283
304
|
Supports immediate mode, cached drawing, and batched rendering.
|
|
284
305
|
"""
|
|
306
|
+
ctx: ContextType
|
|
307
|
+
circle_instanced_prog: ProgramType
|
|
308
|
+
rect_instanced_prog: ProgramType
|
|
309
|
+
line_instanced_prog: ProgramType
|
|
310
|
+
circle_prog: ProgramType
|
|
311
|
+
rect_prog: ProgramType
|
|
312
|
+
line_prog: ProgramType
|
|
313
|
+
circle_vbo: BufferType
|
|
314
|
+
rect_vbo: BufferType
|
|
315
|
+
line_vbo: BufferType
|
|
316
|
+
circle_vao: VAOType
|
|
317
|
+
rect_vao: VAOType
|
|
318
|
+
line_vao: VAOType
|
|
285
319
|
|
|
286
|
-
def __init__(self, ctx:
|
|
320
|
+
def __init__(self, ctx: ContextType) -> None:
|
|
287
321
|
self.ctx = ctx
|
|
288
322
|
|
|
289
323
|
# ===== INSTANCED Circle Shader (for high-performance batching) =====
|
|
@@ -697,16 +731,17 @@ class ShapeRenderer:
|
|
|
697
731
|
|
|
698
732
|
# ========== CIRCLE ==========
|
|
699
733
|
|
|
700
|
-
def _generate_circle_vertices(self, center:
|
|
701
|
-
color:
|
|
734
|
+
def _generate_circle_vertices(self, center: VectorType, radius: float,
|
|
735
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0),
|
|
702
736
|
rotation: float = 0.0,
|
|
703
|
-
border_color:
|
|
737
|
+
border_color: ColorType = (0.0, 0.0, 0.0, 0.0),
|
|
704
738
|
border_width: float = 0.0,
|
|
705
739
|
antialiasing: float = 1.0) -> list[float]:
|
|
706
740
|
"""Generate vertices for a circle (as a quad).
|
|
707
741
|
Format: pos(2f), color(4f), radius(1f), border_color(4f), border_width(1f), aa(1f), center(2f)
|
|
708
742
|
"""
|
|
709
|
-
|
|
743
|
+
# Handle VectorType input - convert to tuple if needed
|
|
744
|
+
cx, cy = center[0], center[1]
|
|
710
745
|
|
|
711
746
|
# Expand for border and antialiasing
|
|
712
747
|
expand = radius + border_width + antialiasing * 2
|
|
@@ -735,10 +770,10 @@ class ShapeRenderer:
|
|
|
735
770
|
|
|
736
771
|
return vertices
|
|
737
772
|
|
|
738
|
-
def draw_circle(self, center:
|
|
739
|
-
color:
|
|
773
|
+
def draw_circle(self, center: VectorType, radius: float,
|
|
774
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0),
|
|
740
775
|
rotation: float = 0.0,
|
|
741
|
-
border_color:
|
|
776
|
+
border_color: ColorType = (0.0, 0.0, 0.0, 0.0),
|
|
742
777
|
border_width: float = 0.0,
|
|
743
778
|
antialiasing: float = 1.0) -> None:
|
|
744
779
|
"""
|
|
@@ -763,10 +798,10 @@ class ShapeRenderer:
|
|
|
763
798
|
set_pattr_value(self.circle_prog, 'resolution', self.ctx.viewport[2:])
|
|
764
799
|
self.circle_vao.render(moderngl.TRIANGLES, vertices=6)
|
|
765
800
|
|
|
766
|
-
def create_circle(self, center:
|
|
767
|
-
color:
|
|
801
|
+
def create_circle(self, center: VectorType, radius: float,
|
|
802
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0),
|
|
768
803
|
rotation: float = 0.0,
|
|
769
|
-
border_color:
|
|
804
|
+
border_color: ColorType = (0.0, 0.0, 0.0, 0.0),
|
|
770
805
|
border_width: float = 0.0,
|
|
771
806
|
antialiasing: float = 1.0) -> ShapeLabel:
|
|
772
807
|
"""Create a cached circle for repeated drawing."""
|
|
@@ -780,17 +815,18 @@ class ShapeRenderer:
|
|
|
780
815
|
|
|
781
816
|
# ========== RECTANGLE ==========
|
|
782
817
|
|
|
783
|
-
def _generate_rect_vertices(self, position:
|
|
784
|
-
color:
|
|
818
|
+
def _generate_rect_vertices(self, position: VectorType, size: VectorType,
|
|
819
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0),
|
|
785
820
|
rotation: float = 0.0,
|
|
786
821
|
corner_radius: float = 0.0,
|
|
787
|
-
border_color:
|
|
822
|
+
border_color: ColorType = (0.0, 0.0, 0.0, 0.0),
|
|
788
823
|
border_width: float = 0.0,
|
|
789
824
|
antialiasing: float = 1.0) -> list[float]:
|
|
790
825
|
"""Generate vertices for a rectangle.
|
|
791
826
|
Format: pos(2f), color(4f), radius(1f), border_color(4f), border_width(1f), aa(1f), size(2f), local_pos(2f)
|
|
792
827
|
"""
|
|
793
|
-
|
|
828
|
+
# Handle VectorType input - convert to tuple if needed
|
|
829
|
+
x, y = position[0], position[1]
|
|
794
830
|
w, h = size
|
|
795
831
|
|
|
796
832
|
# Center of rectangle
|
|
@@ -832,11 +868,11 @@ class ShapeRenderer:
|
|
|
832
868
|
|
|
833
869
|
return vertices
|
|
834
870
|
|
|
835
|
-
def draw_rect(self, position:
|
|
836
|
-
color:
|
|
871
|
+
def draw_rect(self, position: VectorType, size: VectorType,
|
|
872
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0),
|
|
837
873
|
rotation: float = 0.0,
|
|
838
874
|
corner_radius: float = 0.0,
|
|
839
|
-
border_color:
|
|
875
|
+
border_color: ColorType = (0.0, 0.0, 0.0, 0.0),
|
|
840
876
|
border_width: float = 0.0,
|
|
841
877
|
antialiasing: float = 1.0) -> None:
|
|
842
878
|
"""
|
|
@@ -862,11 +898,11 @@ class ShapeRenderer:
|
|
|
862
898
|
set_pattr_value(self.rect_prog, 'resolution', self.ctx.viewport[2:])
|
|
863
899
|
self.rect_vao.render(moderngl.TRIANGLES, vertices=6)
|
|
864
900
|
|
|
865
|
-
def create_rect(self, position:
|
|
866
|
-
color:
|
|
901
|
+
def create_rect(self, position: VectorType, size: VectorType,
|
|
902
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0),
|
|
867
903
|
rotation: float = 0.0,
|
|
868
904
|
corner_radius: float = 0.0,
|
|
869
|
-
border_color:
|
|
905
|
+
border_color: ColorType = (0.0, 0.0, 0.0, 0.0),
|
|
870
906
|
border_width: float = 0.0,
|
|
871
907
|
antialiasing: float = 1.0) -> ShapeLabel:
|
|
872
908
|
"""Create a cached rectangle for repeated drawing."""
|
|
@@ -880,12 +916,13 @@ class ShapeRenderer:
|
|
|
880
916
|
|
|
881
917
|
# ========== LINES ==========
|
|
882
918
|
|
|
883
|
-
def _generate_line_segment_vertices(self, start:
|
|
884
|
-
width: float, color:
|
|
919
|
+
def _generate_line_segment_vertices(self, start: VectorType, end: VectorType,
|
|
920
|
+
width: float, color: ColorType,
|
|
885
921
|
antialias: float = 1.0) -> list[float]:
|
|
886
922
|
"""Generate vertices for a line segment as a quad."""
|
|
887
|
-
|
|
888
|
-
|
|
923
|
+
# Handle VectorType input - convert to tuple if needed
|
|
924
|
+
x1, y1 = start[0], start[1]
|
|
925
|
+
x2, y2 = end[0], end[1]
|
|
889
926
|
|
|
890
927
|
# Calculate perpendicular direction
|
|
891
928
|
dx = x2 - x1
|
|
@@ -918,9 +955,9 @@ class ShapeRenderer:
|
|
|
918
955
|
|
|
919
956
|
return vertices
|
|
920
957
|
|
|
921
|
-
def draw_line(self, start:
|
|
958
|
+
def draw_line(self, start: VectorType, end: VectorType,
|
|
922
959
|
width: float = 1.0,
|
|
923
|
-
color:
|
|
960
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0),
|
|
924
961
|
antialiasing: float = 1.0) -> None:
|
|
925
962
|
"""
|
|
926
963
|
Draw a single line segment.
|
|
@@ -944,9 +981,9 @@ class ShapeRenderer:
|
|
|
944
981
|
set_pattr_value(self.line_prog, 'resolution', self.ctx.viewport[2:])
|
|
945
982
|
self.line_vao.render(moderngl.TRIANGLES, vertices=6)
|
|
946
983
|
|
|
947
|
-
def draw_lines(self, points: np.ndarray | Sequence[
|
|
984
|
+
def draw_lines(self, points: np.ndarray | Sequence[VectorType],
|
|
948
985
|
width: float = 1.0,
|
|
949
|
-
color:
|
|
986
|
+
color: ColorType | np.ndarray = (1.0, 1.0, 1.0, 1.0),
|
|
950
987
|
antialiasing: float = 1.0,
|
|
951
988
|
closed: bool = False) -> None:
|
|
952
989
|
"""
|
|
@@ -1003,9 +1040,9 @@ class ShapeRenderer:
|
|
|
1003
1040
|
num_segments = (len(points_array) - 1) + (1 if closed else 0)
|
|
1004
1041
|
self.line_vao.render(moderngl.TRIANGLES, vertices=num_segments * 6)
|
|
1005
1042
|
|
|
1006
|
-
def create_line(self, start:
|
|
1043
|
+
def create_line(self, start: VectorType, end: VectorType,
|
|
1007
1044
|
width: float = 1.0,
|
|
1008
|
-
color:
|
|
1045
|
+
color: ColorType = (1.0, 1.0, 1.0, 1.0),
|
|
1009
1046
|
antialiasing: float = 1.0) -> ShapeLabel:
|
|
1010
1047
|
"""Create a cached line for repeated drawing."""
|
|
1011
1048
|
vertices = self._generate_line_segment_vertices(start, end, width, color, antialiasing)
|
|
@@ -1015,9 +1052,9 @@ class ShapeRenderer:
|
|
|
1015
1052
|
|
|
1016
1053
|
return ShapeLabel(self.ctx, self.line_prog, vbo, 6, 'line')
|
|
1017
1054
|
|
|
1018
|
-
def create_lines(self, points: np.ndarray | Sequence[
|
|
1055
|
+
def create_lines(self, points: np.ndarray | Sequence[VectorType],
|
|
1019
1056
|
width: float = 1.0,
|
|
1020
|
-
color:
|
|
1057
|
+
color: ColorType | np.ndarray = (1.0, 1.0, 1.0, 1.0),
|
|
1021
1058
|
antialiasing: float = 1.0,
|
|
1022
1059
|
closed: bool = False) -> ShapeLabel:
|
|
1023
1060
|
"""Create a cached polyline for repeated drawing."""
|