-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathutils.py
More file actions
125 lines (94 loc) · 3.94 KB
/
utils.py
File metadata and controls
125 lines (94 loc) · 3.94 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
from contextlib import contextmanager
from typing import Callable, Iterable, Sequence
import numpy as np
from ._collection_base import GraphicCollection
from ._base import Graphic
@contextmanager
def pause_events(*graphics: Graphic, event_handlers: Iterable[Callable] = None):
"""
Context manager for pausing Graphic events.
Optionally pass in only specific event handlers which are blocked. Other events for the graphic will not be blocked.
Examples
--------
.. code-block::
# pass in any number of graphics
with fpl.pause_events(graphic1, graphic2, graphic3):
# enter context manager
# all events are blocked from graphic1, graphic2, graphic3
# context manager exited, event states restored.
"""
if not all([isinstance(g, Graphic) for g in graphics]):
raise TypeError(
f"`pause_events` only takes Graphic instances as arguments, "
f"you have passed the following types:\n{[type(g) for g in graphics]}"
)
original_vals = [g.block_events for g in graphics]
for g in graphics:
if event_handlers is not None:
g.block_handlers.extend([e for e in event_handlers])
else:
g.block_events = True
yield
for g, value in zip(graphics, original_vals):
if event_handlers is not None:
g.block_handlers.clear()
else:
g.block_events = value
def get_nearest_graphics_indices(
pos: tuple[float, float] | tuple[float, float, float],
graphics: Sequence[Graphic] | GraphicCollection,
) -> np.ndarray[int]:
"""
Returns indices of the nearest ``graphics`` to the passed position ``pos`` in world space
in order of closest to furtherst. Uses the distance between ``pos`` and the center of the
bounding sphere for each graphic.
Parameters
----------
pos: (x, y) | (x, y, z)
position in world space, z-axis is ignored when calculating L2 norms if ``pos`` is 2D
graphics: Sequence, i.e. array, list, tuple, etc. of Graphic | GraphicCollection
the graphics from which to return a sorted array of graphics in order of closest
to furthest graphic
Returns
-------
ndarray[int]
indices of the nearest nearest graphics to ``pos`` in order
"""
if isinstance(graphics, GraphicCollection):
graphics = graphics.graphics
if not all(isinstance(g, Graphic) for g in graphics):
raise TypeError("all elements of `graphics` must be Graphic objects")
pos = np.asarray(pos).ravel()
if pos.shape != (2,) and pos.shape != (3,):
raise TypeError(
f"pos.shape must be (2,) or (3,), the shape of pos you have passed is: {pos.shape}"
)
# get centers
centers = np.empty(shape=(len(graphics), len(pos)))
for i in range(centers.shape[0]):
centers[i] = graphics[i].world_object.get_world_bounding_sphere()[: len(pos)]
# l2
distances = np.linalg.norm(centers[:, : len(pos)] - pos, ord=2, axis=1)
sort_indices = np.argsort(distances)
return sort_indices
def get_nearest_graphics(
pos: tuple[float, float] | tuple[float, float, float],
graphics: Sequence[Graphic] | GraphicCollection,
) -> np.ndarray[Graphic]:
"""
Returns the nearest ``graphics`` to the passed position ``pos`` in world space.
Uses the distance between ``pos`` and the center of the bounding sphere for each graphic.
Parameters
----------
pos: (x, y) | (x, y, z)
position in world space, z-axis is ignored when calculating L2 norms if ``pos`` is 2D
graphics: Sequence, i.e. array, list, tuple, etc. of Graphic | GraphicCollection
the graphics from which to return a sorted array of graphics in order of closest
to furthest graphic
Returns
-------
ndarray[Graphic]
nearest graphics to ``pos`` in order
"""
sort_indices = get_nearest_graphics_indices(pos, graphics)
return np.asarray(graphics)[sort_indices]