1
1
import functools
2
- from typing import Dict , List , Optional , get_args
2
+ from typing import Dict , List , Optional , Set , get_args
3
3
4
4
from classy_blocks .base .exceptions import BlockNotFoundError , NoInstructionError
5
5
from classy_blocks .items .block import Block
6
+ from classy_blocks .items .vertex import Vertex
6
7
from classy_blocks .items .wires .axis import Axis
7
8
from classy_blocks .items .wires .wire import Wire
8
9
from classy_blocks .mesh import Mesh
9
- from classy_blocks .types import ChopTakeType , DirectionType
10
+ from classy_blocks .optimize .grid import HexGrid
11
+ from classy_blocks .types import ChopTakeType , DirectionType , OrientType
12
+ from classy_blocks .util .constants import FACE_MAP
10
13
11
14
12
15
@functools .lru_cache (maxsize = 3000 ) # that's for 1000 blocks
@@ -18,6 +21,20 @@ def get_block_from_axis(mesh: Mesh, axis: Axis) -> Block:
18
21
raise RuntimeError ("Block for Axis not found!" )
19
22
20
23
24
+ @functools .lru_cache (maxsize = 2 )
25
+ def get_defined_wall_vertices (mesh : Mesh ) -> Set [Vertex ]:
26
+ """Returns vertices that are on the 'wall' patches"""
27
+ wall_vertices : set [Vertex ] = set ()
28
+
29
+ # explicitly defined walls
30
+ for patch in mesh .patches :
31
+ if patch .kind == "wall" :
32
+ for side in patch .sides :
33
+ wall_vertices .update (set (side .vertices ))
34
+
35
+ return wall_vertices
36
+
37
+
21
38
class Instruction :
22
39
"""A descriptor that tells in which direction the specific block can be chopped."""
23
40
@@ -151,10 +168,46 @@ class Probe:
151
168
152
169
def __init__ (self , mesh : Mesh ):
153
170
self .mesh = mesh
171
+
172
+ # maps blocks to rows
154
173
self .catalogue = Catalogue (self .mesh )
155
174
175
+ # finds blocks' neighbours
176
+ self .grid = HexGrid .from_mesh (self .mesh )
177
+
156
178
def get_row_blocks (self , block : Block , direction : DirectionType ) -> List [Block ]:
157
179
return self .catalogue .get_row_blocks (block , direction )
158
180
159
181
def get_rows (self , direction : DirectionType ) -> List [Row ]:
160
182
return self .catalogue .rows [direction ]
183
+
184
+ def get_explicit_wall_vertices (self , block : Block ) -> Set [Vertex ]:
185
+ """Returns vertices from a block that lie on explicitly defined wall patches"""
186
+ mesh_vertices = get_defined_wall_vertices (self .mesh )
187
+ block_vertices = set (block .vertices )
188
+
189
+ return block_vertices .intersection (mesh_vertices )
190
+
191
+ def get_default_wall_vertices (self , block : Block ) -> Set [Vertex ]:
192
+ """Returns vertices that lie on default 'wall' patch"""
193
+ wall_vertices : Set [Vertex ] = set ()
194
+
195
+ # other sides when mesh has a default wall patch
196
+ if self .mesh .patch_list .default ["kind" ] == "wall" :
197
+ # find block boundaries
198
+ block_index = self .mesh .blocks .index (block )
199
+ cell = self .grid .cells [block_index ]
200
+
201
+ # sides with no neighbours are on boundary
202
+ boundaries : List [OrientType ] = [
203
+ orient for orient , neighbours in cell .neighbours .items () if neighbours is None
204
+ ]
205
+
206
+ for orient in boundaries :
207
+ wall_vertices .union ({block .vertices [i ] for i in FACE_MAP [orient ]})
208
+
209
+ return wall_vertices
210
+
211
+ def get_wall_vertices (self , block : Block ) -> Set [Vertex ]:
212
+ """Returns vertices that are on the 'wall' patches"""
213
+ return self .get_explicit_wall_vertices (block ).union (self .get_default_wall_vertices (block ))
0 commit comments