amulet-core 1.9.19__py3-none-any.whl → 1.9.20__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.
Potentially problematic release.
This version of amulet-core might be problematic. Click here for more details.
- amulet/__init__.py +27 -27
- amulet/__pyinstaller/__init__.py +2 -2
- amulet/__pyinstaller/hook-amulet.py +4 -4
- amulet/_version.py +21 -21
- amulet/api/__init__.py +2 -2
- amulet/api/abstract_base_entity.py +128 -128
- amulet/api/block.py +630 -630
- amulet/api/block_entity.py +71 -71
- amulet/api/cache.py +107 -107
- amulet/api/chunk/__init__.py +6 -6
- amulet/api/chunk/biomes.py +207 -207
- amulet/api/chunk/block_entity_dict.py +175 -175
- amulet/api/chunk/blocks.py +46 -46
- amulet/api/chunk/chunk.py +389 -389
- amulet/api/chunk/entity_list.py +75 -75
- amulet/api/chunk/status.py +167 -167
- amulet/api/data_types/__init__.py +4 -4
- amulet/api/data_types/generic_types.py +4 -4
- amulet/api/data_types/operation_types.py +16 -16
- amulet/api/data_types/world_types.py +49 -49
- amulet/api/data_types/wrapper_types.py +71 -71
- amulet/api/entity.py +74 -74
- amulet/api/errors.py +119 -119
- amulet/api/history/__init__.py +36 -36
- amulet/api/history/base/__init__.py +3 -3
- amulet/api/history/base/base_history.py +26 -26
- amulet/api/history/base/history_manager.py +63 -63
- amulet/api/history/base/revision_manager.py +73 -73
- amulet/api/history/changeable.py +15 -15
- amulet/api/history/data_types.py +7 -7
- amulet/api/history/history_manager/__init__.py +3 -3
- amulet/api/history/history_manager/container.py +102 -102
- amulet/api/history/history_manager/database.py +279 -279
- amulet/api/history/history_manager/meta.py +93 -93
- amulet/api/history/history_manager/object.py +116 -116
- amulet/api/history/revision_manager/__init__.py +2 -2
- amulet/api/history/revision_manager/disk.py +33 -33
- amulet/api/history/revision_manager/ram.py +12 -12
- amulet/api/item.py +75 -75
- amulet/api/level/__init__.py +4 -4
- amulet/api/level/base_level/__init__.py +1 -1
- amulet/api/level/base_level/base_level.py +1035 -1026
- amulet/api/level/base_level/chunk_manager.py +227 -227
- amulet/api/level/base_level/clone.py +389 -389
- amulet/api/level/base_level/player_manager.py +101 -101
- amulet/api/level/immutable_structure/__init__.py +1 -1
- amulet/api/level/immutable_structure/immutable_structure.py +94 -94
- amulet/api/level/immutable_structure/void_format_wrapper.py +117 -117
- amulet/api/level/structure.py +22 -22
- amulet/api/level/world.py +19 -19
- amulet/api/partial_3d_array/__init__.py +2 -2
- amulet/api/partial_3d_array/base_partial_3d_array.py +263 -263
- amulet/api/partial_3d_array/bounded_partial_3d_array.py +528 -528
- amulet/api/partial_3d_array/data_types.py +15 -15
- amulet/api/partial_3d_array/unbounded_partial_3d_array.py +229 -229
- amulet/api/partial_3d_array/util.py +152 -152
- amulet/api/player.py +65 -65
- amulet/api/registry/__init__.py +2 -2
- amulet/api/registry/base_registry.py +34 -34
- amulet/api/registry/biome_manager.py +153 -153
- amulet/api/registry/block_manager.py +156 -156
- amulet/api/selection/__init__.py +2 -2
- amulet/api/selection/abstract_selection.py +315 -315
- amulet/api/selection/box.py +805 -805
- amulet/api/selection/group.py +488 -488
- amulet/api/structure.py +37 -37
- amulet/api/wrapper/__init__.py +8 -8
- amulet/api/wrapper/chunk/interface.py +441 -441
- amulet/api/wrapper/chunk/translator.py +567 -567
- amulet/api/wrapper/format_wrapper.py +772 -772
- amulet/api/wrapper/structure_format_wrapper.py +116 -116
- amulet/api/wrapper/world_format_wrapper.py +63 -63
- amulet/level/__init__.py +1 -1
- amulet/level/formats/anvil_forge_world.py +40 -40
- amulet/level/formats/anvil_world/__init__.py +3 -3
- amulet/level/formats/anvil_world/_sector_manager.py +291 -384
- amulet/level/formats/anvil_world/data_pack/__init__.py +2 -2
- amulet/level/formats/anvil_world/data_pack/data_pack.py +224 -224
- amulet/level/formats/anvil_world/data_pack/data_pack_manager.py +77 -77
- amulet/level/formats/anvil_world/dimension.py +177 -177
- amulet/level/formats/anvil_world/format.py +769 -769
- amulet/level/formats/anvil_world/region.py +384 -384
- amulet/level/formats/construction/__init__.py +3 -3
- amulet/level/formats/construction/format_wrapper.py +515 -515
- amulet/level/formats/construction/interface.py +134 -134
- amulet/level/formats/construction/section.py +60 -60
- amulet/level/formats/construction/util.py +165 -165
- amulet/level/formats/leveldb_world/__init__.py +3 -3
- amulet/level/formats/leveldb_world/chunk.py +33 -33
- amulet/level/formats/leveldb_world/dimension.py +385 -419
- amulet/level/formats/leveldb_world/format.py +659 -641
- amulet/level/formats/leveldb_world/interface/chunk/__init__.py +36 -36
- amulet/level/formats/leveldb_world/interface/chunk/base_leveldb_interface.py +836 -836
- amulet/level/formats/leveldb_world/interface/chunk/generate_interface.py +31 -31
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_0.py +30 -30
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_1.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_10.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_11.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_12.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_13.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_14.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_15.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_16.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_17.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_18.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_19.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_2.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_20.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_21.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_22.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_23.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_24.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_25.py +24 -24
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_26.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_27.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_28.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_29.py +33 -33
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_3.py +57 -57
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_30.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_31.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_32.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_33.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_34.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_35.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_36.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_37.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_38.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_39.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_4.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_40.py +16 -16
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_5.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_6.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_7.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_8.py +180 -180
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_9.py +18 -18
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_chunk_versions.py +79 -79
- amulet/level/formats/mcstructure/__init__.py +3 -3
- amulet/level/formats/mcstructure/chunk.py +50 -50
- amulet/level/formats/mcstructure/format_wrapper.py +408 -408
- amulet/level/formats/mcstructure/interface.py +175 -175
- amulet/level/formats/schematic/__init__.py +3 -3
- amulet/level/formats/schematic/chunk.py +55 -55
- amulet/level/formats/schematic/data_types.py +4 -4
- amulet/level/formats/schematic/format_wrapper.py +373 -373
- amulet/level/formats/schematic/interface.py +142 -142
- amulet/level/formats/sponge_schem/__init__.py +4 -4
- amulet/level/formats/sponge_schem/chunk.py +62 -62
- amulet/level/formats/sponge_schem/format_wrapper.py +463 -463
- amulet/level/formats/sponge_schem/interface.py +118 -118
- amulet/level/formats/sponge_schem/varint/__init__.py +1 -1
- amulet/level/formats/sponge_schem/varint/varint.py +87 -87
- amulet/level/interfaces/chunk/anvil/anvil_0.py +72 -72
- amulet/level/interfaces/chunk/anvil/anvil_1444.py +336 -336
- amulet/level/interfaces/chunk/anvil/anvil_1466.py +94 -94
- amulet/level/interfaces/chunk/anvil/anvil_1467.py +37 -37
- amulet/level/interfaces/chunk/anvil/anvil_1484.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1503.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1519.py +34 -34
- amulet/level/interfaces/chunk/anvil/anvil_1901.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1908.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1912.py +21 -21
- amulet/level/interfaces/chunk/anvil/anvil_1934.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_2203.py +69 -69
- amulet/level/interfaces/chunk/anvil/anvil_2529.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_2681.py +76 -76
- amulet/level/interfaces/chunk/anvil/anvil_2709.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_2844.py +267 -267
- amulet/level/interfaces/chunk/anvil/anvil_3463.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_na.py +607 -607
- amulet/level/interfaces/chunk/anvil/base_anvil_interface.py +326 -326
- amulet/level/load.py +59 -59
- amulet/level/loader.py +95 -95
- amulet/level/translators/chunk/bedrock/__init__.py +267 -267
- amulet/level/translators/chunk/bedrock/bedrock_nbt_blockstate_translator.py +46 -46
- amulet/level/translators/chunk/bedrock/bedrock_numerical_translator.py +39 -39
- amulet/level/translators/chunk/bedrock/bedrock_psudo_numerical_translator.py +37 -37
- amulet/level/translators/chunk/java/java_1_18_translator.py +40 -40
- amulet/level/translators/chunk/java/java_blockstate_translator.py +94 -94
- amulet/level/translators/chunk/java/java_numerical_translator.py +62 -62
- amulet/libs/leveldb/__init__.py +7 -7
- amulet/operations/__init__.py +5 -5
- amulet/operations/clone.py +18 -18
- amulet/operations/delete_chunk.py +32 -32
- amulet/operations/fill.py +30 -30
- amulet/operations/paste.py +65 -65
- amulet/operations/replace.py +58 -58
- amulet/utils/__init__.py +14 -14
- amulet/utils/format_utils.py +41 -41
- amulet/utils/generator.py +15 -15
- amulet/utils/matrix.py +243 -243
- amulet/utils/numpy_helpers.py +46 -46
- amulet/utils/world_utils.py +349 -349
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/METADATA +97 -97
- amulet_core-1.9.20.dist-info/RECORD +208 -0
- amulet_core-1.9.19.dist-info/RECORD +0 -208
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/WHEEL +0 -0
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/entry_points.txt +0 -0
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/top_level.txt +0 -0
|
@@ -1,315 +1,315 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from abc import ABC, abstractmethod
|
|
4
|
-
from typing import Iterable, Tuple
|
|
5
|
-
import numpy
|
|
6
|
-
from .. import selection
|
|
7
|
-
|
|
8
|
-
from amulet.api.data_types import (
|
|
9
|
-
CoordinatesAny,
|
|
10
|
-
ChunkCoordinates,
|
|
11
|
-
SubChunkCoordinates,
|
|
12
|
-
FloatTriplet,
|
|
13
|
-
BlockCoordinates,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class AbstractBaseSelection(ABC):
|
|
18
|
-
"""
|
|
19
|
-
A parent selection class to force a consistent API for selection group and box.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
__slots__ = ()
|
|
23
|
-
|
|
24
|
-
@abstractmethod
|
|
25
|
-
def __contains__(self, item: CoordinatesAny) -> bool:
|
|
26
|
-
"""
|
|
27
|
-
Is the given block/point contained within the selection.
|
|
28
|
-
|
|
29
|
-
>>> (1, 2, 3) in selection1
|
|
30
|
-
True
|
|
31
|
-
>>> (1.5, 2.5, 3.5) in selection1
|
|
32
|
-
True
|
|
33
|
-
|
|
34
|
-
Will return False if the coordinate is on the most positive edge.
|
|
35
|
-
See :meth:`contains_point` to include the top edge.
|
|
36
|
-
|
|
37
|
-
:param item: The block/point to check.
|
|
38
|
-
:return: True if the block/point is in the selection, False otherwise.
|
|
39
|
-
"""
|
|
40
|
-
raise NotImplementedError
|
|
41
|
-
|
|
42
|
-
@abstractmethod
|
|
43
|
-
def __eq__(self, other) -> bool:
|
|
44
|
-
"""
|
|
45
|
-
Is the selection equal to the other selection.
|
|
46
|
-
|
|
47
|
-
>>> selection1 == selection2
|
|
48
|
-
True
|
|
49
|
-
|
|
50
|
-
:param other: The other selection to test.
|
|
51
|
-
:return: True if the selections are the same, False otherwise.
|
|
52
|
-
"""
|
|
53
|
-
raise NotImplementedError
|
|
54
|
-
|
|
55
|
-
@abstractmethod
|
|
56
|
-
def __iter__(self):
|
|
57
|
-
raise NotImplementedError
|
|
58
|
-
|
|
59
|
-
@abstractmethod
|
|
60
|
-
def __repr__(self) -> str:
|
|
61
|
-
raise NotImplementedError
|
|
62
|
-
|
|
63
|
-
@abstractmethod
|
|
64
|
-
def __str__(self) -> str:
|
|
65
|
-
raise NotImplementedError
|
|
66
|
-
|
|
67
|
-
@property
|
|
68
|
-
@abstractmethod
|
|
69
|
-
def blocks(self) -> Iterable[BlockCoordinates]:
|
|
70
|
-
"""
|
|
71
|
-
The location of every block in the selection.
|
|
72
|
-
|
|
73
|
-
:return: An iterable of block locations.
|
|
74
|
-
"""
|
|
75
|
-
raise NotImplementedError
|
|
76
|
-
|
|
77
|
-
@property
|
|
78
|
-
@abstractmethod
|
|
79
|
-
def bounds(self) -> Tuple[BlockCoordinates, BlockCoordinates]:
|
|
80
|
-
"""
|
|
81
|
-
The minimum and maximum points in the selection.
|
|
82
|
-
"""
|
|
83
|
-
raise NotImplementedError
|
|
84
|
-
|
|
85
|
-
@property
|
|
86
|
-
@abstractmethod
|
|
87
|
-
def bounds_array(self) -> numpy.ndarray:
|
|
88
|
-
"""
|
|
89
|
-
The minimum and maximum points in the selection as a numpy array.
|
|
90
|
-
"""
|
|
91
|
-
raise NotImplementedError
|
|
92
|
-
|
|
93
|
-
@abstractmethod
|
|
94
|
-
def chunk_boxes(
|
|
95
|
-
self, sub_chunk_size: int = 16
|
|
96
|
-
) -> Iterable[Tuple[ChunkCoordinates, selection.box.SelectionBox]]:
|
|
97
|
-
"""
|
|
98
|
-
An iterable of chunk coordinates and boxes that intersect the selection and the chunk.
|
|
99
|
-
|
|
100
|
-
>>> for (cx, cz), box in selection1.chunk_boxes():
|
|
101
|
-
>>> ...
|
|
102
|
-
|
|
103
|
-
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
104
|
-
"""
|
|
105
|
-
raise NotImplementedError
|
|
106
|
-
|
|
107
|
-
@abstractmethod
|
|
108
|
-
def chunk_count(self, sub_chunk_size: int = 16) -> int:
|
|
109
|
-
"""
|
|
110
|
-
The number of chunks that intersect the selection.
|
|
111
|
-
|
|
112
|
-
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
113
|
-
"""
|
|
114
|
-
raise NotImplementedError
|
|
115
|
-
|
|
116
|
-
@abstractmethod
|
|
117
|
-
def chunk_locations(self, sub_chunk_size: int = 16) -> Iterable[ChunkCoordinates]:
|
|
118
|
-
"""
|
|
119
|
-
An iterable of chunk coordinates that intersect the selection.
|
|
120
|
-
|
|
121
|
-
>>> for cx, cz in selection1.chunk_locations():
|
|
122
|
-
>>> ...
|
|
123
|
-
|
|
124
|
-
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
125
|
-
"""
|
|
126
|
-
raise NotImplementedError
|
|
127
|
-
|
|
128
|
-
@abstractmethod
|
|
129
|
-
def contains_block(self, coords: CoordinatesAny) -> bool:
|
|
130
|
-
"""
|
|
131
|
-
Is the block contained within the selection.
|
|
132
|
-
|
|
133
|
-
>>> (1, 2, 3) in selection1
|
|
134
|
-
True
|
|
135
|
-
|
|
136
|
-
:param coords: The coordinate of the block defined by the most negative corner.
|
|
137
|
-
:return: True if the block is in the selection.
|
|
138
|
-
"""
|
|
139
|
-
raise NotImplementedError
|
|
140
|
-
|
|
141
|
-
# @abstractmethod
|
|
142
|
-
# def contains_box(self, other: box.SelectionBox) -> bool:
|
|
143
|
-
# raise NotImplementedError
|
|
144
|
-
|
|
145
|
-
@abstractmethod
|
|
146
|
-
def contains_point(self, coords: CoordinatesAny) -> bool:
|
|
147
|
-
"""
|
|
148
|
-
Is the point contained within the selection.
|
|
149
|
-
|
|
150
|
-
>>> (1.5, 2.5, 3.5) in selection1
|
|
151
|
-
True
|
|
152
|
-
|
|
153
|
-
:param coords: The coordinate of the point.
|
|
154
|
-
:return: True if the point is in the selection.
|
|
155
|
-
"""
|
|
156
|
-
raise NotImplementedError
|
|
157
|
-
|
|
158
|
-
@abstractmethod
|
|
159
|
-
def intersection(self, other):
|
|
160
|
-
"""
|
|
161
|
-
Create and return a new a selection containing the volume that this selection and other both contain.
|
|
162
|
-
|
|
163
|
-
If the selections do not intersect the returned selection will have no volume.
|
|
164
|
-
|
|
165
|
-
Use :meth:`intersects` to test if the two selections intersect.
|
|
166
|
-
|
|
167
|
-
:param other: The other selection.
|
|
168
|
-
:return: A new selection containing the intersection.
|
|
169
|
-
"""
|
|
170
|
-
raise NotImplementedError
|
|
171
|
-
|
|
172
|
-
@abstractmethod
|
|
173
|
-
def intersects(self, other) -> bool:
|
|
174
|
-
"""
|
|
175
|
-
Does this selection intersect ``other``.
|
|
176
|
-
|
|
177
|
-
:param other: The other selection.
|
|
178
|
-
:return: True if the selections intersect, False otherwise.
|
|
179
|
-
"""
|
|
180
|
-
raise NotImplementedError
|
|
181
|
-
|
|
182
|
-
@property
|
|
183
|
-
@abstractmethod
|
|
184
|
-
def max(self) -> BlockCoordinates:
|
|
185
|
-
"""
|
|
186
|
-
The maximum point in the selection.
|
|
187
|
-
"""
|
|
188
|
-
raise NotImplementedError
|
|
189
|
-
|
|
190
|
-
@property
|
|
191
|
-
@abstractmethod
|
|
192
|
-
def max_array(self) -> numpy.ndarray:
|
|
193
|
-
"""
|
|
194
|
-
The maximum point in the selection as a numpy array.
|
|
195
|
-
"""
|
|
196
|
-
raise NotImplementedError
|
|
197
|
-
|
|
198
|
-
@property
|
|
199
|
-
@abstractmethod
|
|
200
|
-
def max_x(self) -> int:
|
|
201
|
-
"""
|
|
202
|
-
The maximum x coordinate of the selection.
|
|
203
|
-
"""
|
|
204
|
-
raise NotImplementedError
|
|
205
|
-
|
|
206
|
-
@property
|
|
207
|
-
@abstractmethod
|
|
208
|
-
def max_y(self) -> int:
|
|
209
|
-
"""
|
|
210
|
-
The maximum y coordinate of the selection.
|
|
211
|
-
"""
|
|
212
|
-
raise NotImplementedError
|
|
213
|
-
|
|
214
|
-
@property
|
|
215
|
-
@abstractmethod
|
|
216
|
-
def max_z(self) -> int:
|
|
217
|
-
"""
|
|
218
|
-
The maximum z coordinate of the selection.
|
|
219
|
-
"""
|
|
220
|
-
raise NotImplementedError
|
|
221
|
-
|
|
222
|
-
@property
|
|
223
|
-
@abstractmethod
|
|
224
|
-
def min(self) -> BlockCoordinates:
|
|
225
|
-
"""
|
|
226
|
-
The minimum point in the selection.
|
|
227
|
-
"""
|
|
228
|
-
raise NotImplementedError
|
|
229
|
-
|
|
230
|
-
@property
|
|
231
|
-
@abstractmethod
|
|
232
|
-
def min_array(self) -> numpy.ndarray:
|
|
233
|
-
"""
|
|
234
|
-
The minimum point in the selection as a numpy array.
|
|
235
|
-
"""
|
|
236
|
-
raise NotImplementedError
|
|
237
|
-
|
|
238
|
-
@property
|
|
239
|
-
@abstractmethod
|
|
240
|
-
def min_x(self) -> int:
|
|
241
|
-
"""
|
|
242
|
-
The minimum x coordinate of the selection.
|
|
243
|
-
"""
|
|
244
|
-
raise NotImplementedError
|
|
245
|
-
|
|
246
|
-
@property
|
|
247
|
-
@abstractmethod
|
|
248
|
-
def min_y(self) -> int:
|
|
249
|
-
"""
|
|
250
|
-
The minimum y coordinate of the selection.
|
|
251
|
-
"""
|
|
252
|
-
raise NotImplementedError
|
|
253
|
-
|
|
254
|
-
@property
|
|
255
|
-
@abstractmethod
|
|
256
|
-
def min_z(self) -> int:
|
|
257
|
-
"""
|
|
258
|
-
The minimum z coordinate of the selection.
|
|
259
|
-
"""
|
|
260
|
-
raise NotImplementedError
|
|
261
|
-
|
|
262
|
-
@abstractmethod
|
|
263
|
-
def sub_chunk_boxes(
|
|
264
|
-
self, sub_chunk_size: int = 16
|
|
265
|
-
) -> Iterable[Tuple[SubChunkCoordinates, selection.box.SelectionBox]]:
|
|
266
|
-
"""
|
|
267
|
-
An iterable of sub-chunk coordinates and boxes that intersect the selection and the sub-chunk.
|
|
268
|
-
|
|
269
|
-
>>> for (cx, cy, cz), box in selection1.sub_chunk_boxes():
|
|
270
|
-
>>> ...
|
|
271
|
-
|
|
272
|
-
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
273
|
-
"""
|
|
274
|
-
raise NotImplementedError
|
|
275
|
-
|
|
276
|
-
@abstractmethod
|
|
277
|
-
def sub_chunk_count(self, sub_chunk_size: int = 16) -> int:
|
|
278
|
-
"""
|
|
279
|
-
The number of sub-chunks that intersect the selection.
|
|
280
|
-
|
|
281
|
-
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
282
|
-
"""
|
|
283
|
-
raise NotImplementedError
|
|
284
|
-
|
|
285
|
-
@abstractmethod
|
|
286
|
-
def sub_chunk_locations(
|
|
287
|
-
self, sub_chunk_size: int = 16
|
|
288
|
-
) -> Iterable[SubChunkCoordinates]:
|
|
289
|
-
"""
|
|
290
|
-
An iterable of sub-chunk coordinates that intersect the selection.
|
|
291
|
-
|
|
292
|
-
>>> for cx, cy, cz in selection1.sub_chunk_locations():
|
|
293
|
-
>>> ...
|
|
294
|
-
|
|
295
|
-
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
296
|
-
"""
|
|
297
|
-
raise NotImplementedError
|
|
298
|
-
|
|
299
|
-
@abstractmethod
|
|
300
|
-
def subtract(self, other):
|
|
301
|
-
raise NotImplementedError
|
|
302
|
-
|
|
303
|
-
@abstractmethod
|
|
304
|
-
def transform(
|
|
305
|
-
self, scale: FloatTriplet, rotation: FloatTriplet, translation: FloatTriplet
|
|
306
|
-
):
|
|
307
|
-
raise NotImplementedError
|
|
308
|
-
|
|
309
|
-
@property
|
|
310
|
-
@abstractmethod
|
|
311
|
-
def volume(self) -> int:
|
|
312
|
-
"""
|
|
313
|
-
The number of blocks in the selection.
|
|
314
|
-
"""
|
|
315
|
-
raise NotImplementedError
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Iterable, Tuple
|
|
5
|
+
import numpy
|
|
6
|
+
from .. import selection
|
|
7
|
+
|
|
8
|
+
from amulet.api.data_types import (
|
|
9
|
+
CoordinatesAny,
|
|
10
|
+
ChunkCoordinates,
|
|
11
|
+
SubChunkCoordinates,
|
|
12
|
+
FloatTriplet,
|
|
13
|
+
BlockCoordinates,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AbstractBaseSelection(ABC):
|
|
18
|
+
"""
|
|
19
|
+
A parent selection class to force a consistent API for selection group and box.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
__slots__ = ()
|
|
23
|
+
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def __contains__(self, item: CoordinatesAny) -> bool:
|
|
26
|
+
"""
|
|
27
|
+
Is the given block/point contained within the selection.
|
|
28
|
+
|
|
29
|
+
>>> (1, 2, 3) in selection1
|
|
30
|
+
True
|
|
31
|
+
>>> (1.5, 2.5, 3.5) in selection1
|
|
32
|
+
True
|
|
33
|
+
|
|
34
|
+
Will return False if the coordinate is on the most positive edge.
|
|
35
|
+
See :meth:`contains_point` to include the top edge.
|
|
36
|
+
|
|
37
|
+
:param item: The block/point to check.
|
|
38
|
+
:return: True if the block/point is in the selection, False otherwise.
|
|
39
|
+
"""
|
|
40
|
+
raise NotImplementedError
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def __eq__(self, other) -> bool:
|
|
44
|
+
"""
|
|
45
|
+
Is the selection equal to the other selection.
|
|
46
|
+
|
|
47
|
+
>>> selection1 == selection2
|
|
48
|
+
True
|
|
49
|
+
|
|
50
|
+
:param other: The other selection to test.
|
|
51
|
+
:return: True if the selections are the same, False otherwise.
|
|
52
|
+
"""
|
|
53
|
+
raise NotImplementedError
|
|
54
|
+
|
|
55
|
+
@abstractmethod
|
|
56
|
+
def __iter__(self):
|
|
57
|
+
raise NotImplementedError
|
|
58
|
+
|
|
59
|
+
@abstractmethod
|
|
60
|
+
def __repr__(self) -> str:
|
|
61
|
+
raise NotImplementedError
|
|
62
|
+
|
|
63
|
+
@abstractmethod
|
|
64
|
+
def __str__(self) -> str:
|
|
65
|
+
raise NotImplementedError
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def blocks(self) -> Iterable[BlockCoordinates]:
|
|
70
|
+
"""
|
|
71
|
+
The location of every block in the selection.
|
|
72
|
+
|
|
73
|
+
:return: An iterable of block locations.
|
|
74
|
+
"""
|
|
75
|
+
raise NotImplementedError
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
@abstractmethod
|
|
79
|
+
def bounds(self) -> Tuple[BlockCoordinates, BlockCoordinates]:
|
|
80
|
+
"""
|
|
81
|
+
The minimum and maximum points in the selection.
|
|
82
|
+
"""
|
|
83
|
+
raise NotImplementedError
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
@abstractmethod
|
|
87
|
+
def bounds_array(self) -> numpy.ndarray:
|
|
88
|
+
"""
|
|
89
|
+
The minimum and maximum points in the selection as a numpy array.
|
|
90
|
+
"""
|
|
91
|
+
raise NotImplementedError
|
|
92
|
+
|
|
93
|
+
@abstractmethod
|
|
94
|
+
def chunk_boxes(
|
|
95
|
+
self, sub_chunk_size: int = 16
|
|
96
|
+
) -> Iterable[Tuple[ChunkCoordinates, selection.box.SelectionBox]]:
|
|
97
|
+
"""
|
|
98
|
+
An iterable of chunk coordinates and boxes that intersect the selection and the chunk.
|
|
99
|
+
|
|
100
|
+
>>> for (cx, cz), box in selection1.chunk_boxes():
|
|
101
|
+
>>> ...
|
|
102
|
+
|
|
103
|
+
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
104
|
+
"""
|
|
105
|
+
raise NotImplementedError
|
|
106
|
+
|
|
107
|
+
@abstractmethod
|
|
108
|
+
def chunk_count(self, sub_chunk_size: int = 16) -> int:
|
|
109
|
+
"""
|
|
110
|
+
The number of chunks that intersect the selection.
|
|
111
|
+
|
|
112
|
+
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
113
|
+
"""
|
|
114
|
+
raise NotImplementedError
|
|
115
|
+
|
|
116
|
+
@abstractmethod
|
|
117
|
+
def chunk_locations(self, sub_chunk_size: int = 16) -> Iterable[ChunkCoordinates]:
|
|
118
|
+
"""
|
|
119
|
+
An iterable of chunk coordinates that intersect the selection.
|
|
120
|
+
|
|
121
|
+
>>> for cx, cz in selection1.chunk_locations():
|
|
122
|
+
>>> ...
|
|
123
|
+
|
|
124
|
+
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
125
|
+
"""
|
|
126
|
+
raise NotImplementedError
|
|
127
|
+
|
|
128
|
+
@abstractmethod
|
|
129
|
+
def contains_block(self, coords: CoordinatesAny) -> bool:
|
|
130
|
+
"""
|
|
131
|
+
Is the block contained within the selection.
|
|
132
|
+
|
|
133
|
+
>>> (1, 2, 3) in selection1
|
|
134
|
+
True
|
|
135
|
+
|
|
136
|
+
:param coords: The coordinate of the block defined by the most negative corner.
|
|
137
|
+
:return: True if the block is in the selection.
|
|
138
|
+
"""
|
|
139
|
+
raise NotImplementedError
|
|
140
|
+
|
|
141
|
+
# @abstractmethod
|
|
142
|
+
# def contains_box(self, other: box.SelectionBox) -> bool:
|
|
143
|
+
# raise NotImplementedError
|
|
144
|
+
|
|
145
|
+
@abstractmethod
|
|
146
|
+
def contains_point(self, coords: CoordinatesAny) -> bool:
|
|
147
|
+
"""
|
|
148
|
+
Is the point contained within the selection.
|
|
149
|
+
|
|
150
|
+
>>> (1.5, 2.5, 3.5) in selection1
|
|
151
|
+
True
|
|
152
|
+
|
|
153
|
+
:param coords: The coordinate of the point.
|
|
154
|
+
:return: True if the point is in the selection.
|
|
155
|
+
"""
|
|
156
|
+
raise NotImplementedError
|
|
157
|
+
|
|
158
|
+
@abstractmethod
|
|
159
|
+
def intersection(self, other):
|
|
160
|
+
"""
|
|
161
|
+
Create and return a new a selection containing the volume that this selection and other both contain.
|
|
162
|
+
|
|
163
|
+
If the selections do not intersect the returned selection will have no volume.
|
|
164
|
+
|
|
165
|
+
Use :meth:`intersects` to test if the two selections intersect.
|
|
166
|
+
|
|
167
|
+
:param other: The other selection.
|
|
168
|
+
:return: A new selection containing the intersection.
|
|
169
|
+
"""
|
|
170
|
+
raise NotImplementedError
|
|
171
|
+
|
|
172
|
+
@abstractmethod
|
|
173
|
+
def intersects(self, other) -> bool:
|
|
174
|
+
"""
|
|
175
|
+
Does this selection intersect ``other``.
|
|
176
|
+
|
|
177
|
+
:param other: The other selection.
|
|
178
|
+
:return: True if the selections intersect, False otherwise.
|
|
179
|
+
"""
|
|
180
|
+
raise NotImplementedError
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
@abstractmethod
|
|
184
|
+
def max(self) -> BlockCoordinates:
|
|
185
|
+
"""
|
|
186
|
+
The maximum point in the selection.
|
|
187
|
+
"""
|
|
188
|
+
raise NotImplementedError
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
@abstractmethod
|
|
192
|
+
def max_array(self) -> numpy.ndarray:
|
|
193
|
+
"""
|
|
194
|
+
The maximum point in the selection as a numpy array.
|
|
195
|
+
"""
|
|
196
|
+
raise NotImplementedError
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
@abstractmethod
|
|
200
|
+
def max_x(self) -> int:
|
|
201
|
+
"""
|
|
202
|
+
The maximum x coordinate of the selection.
|
|
203
|
+
"""
|
|
204
|
+
raise NotImplementedError
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
@abstractmethod
|
|
208
|
+
def max_y(self) -> int:
|
|
209
|
+
"""
|
|
210
|
+
The maximum y coordinate of the selection.
|
|
211
|
+
"""
|
|
212
|
+
raise NotImplementedError
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
@abstractmethod
|
|
216
|
+
def max_z(self) -> int:
|
|
217
|
+
"""
|
|
218
|
+
The maximum z coordinate of the selection.
|
|
219
|
+
"""
|
|
220
|
+
raise NotImplementedError
|
|
221
|
+
|
|
222
|
+
@property
|
|
223
|
+
@abstractmethod
|
|
224
|
+
def min(self) -> BlockCoordinates:
|
|
225
|
+
"""
|
|
226
|
+
The minimum point in the selection.
|
|
227
|
+
"""
|
|
228
|
+
raise NotImplementedError
|
|
229
|
+
|
|
230
|
+
@property
|
|
231
|
+
@abstractmethod
|
|
232
|
+
def min_array(self) -> numpy.ndarray:
|
|
233
|
+
"""
|
|
234
|
+
The minimum point in the selection as a numpy array.
|
|
235
|
+
"""
|
|
236
|
+
raise NotImplementedError
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
@abstractmethod
|
|
240
|
+
def min_x(self) -> int:
|
|
241
|
+
"""
|
|
242
|
+
The minimum x coordinate of the selection.
|
|
243
|
+
"""
|
|
244
|
+
raise NotImplementedError
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
@abstractmethod
|
|
248
|
+
def min_y(self) -> int:
|
|
249
|
+
"""
|
|
250
|
+
The minimum y coordinate of the selection.
|
|
251
|
+
"""
|
|
252
|
+
raise NotImplementedError
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
@abstractmethod
|
|
256
|
+
def min_z(self) -> int:
|
|
257
|
+
"""
|
|
258
|
+
The minimum z coordinate of the selection.
|
|
259
|
+
"""
|
|
260
|
+
raise NotImplementedError
|
|
261
|
+
|
|
262
|
+
@abstractmethod
|
|
263
|
+
def sub_chunk_boxes(
|
|
264
|
+
self, sub_chunk_size: int = 16
|
|
265
|
+
) -> Iterable[Tuple[SubChunkCoordinates, selection.box.SelectionBox]]:
|
|
266
|
+
"""
|
|
267
|
+
An iterable of sub-chunk coordinates and boxes that intersect the selection and the sub-chunk.
|
|
268
|
+
|
|
269
|
+
>>> for (cx, cy, cz), box in selection1.sub_chunk_boxes():
|
|
270
|
+
>>> ...
|
|
271
|
+
|
|
272
|
+
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
273
|
+
"""
|
|
274
|
+
raise NotImplementedError
|
|
275
|
+
|
|
276
|
+
@abstractmethod
|
|
277
|
+
def sub_chunk_count(self, sub_chunk_size: int = 16) -> int:
|
|
278
|
+
"""
|
|
279
|
+
The number of sub-chunks that intersect the selection.
|
|
280
|
+
|
|
281
|
+
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
282
|
+
"""
|
|
283
|
+
raise NotImplementedError
|
|
284
|
+
|
|
285
|
+
@abstractmethod
|
|
286
|
+
def sub_chunk_locations(
|
|
287
|
+
self, sub_chunk_size: int = 16
|
|
288
|
+
) -> Iterable[SubChunkCoordinates]:
|
|
289
|
+
"""
|
|
290
|
+
An iterable of sub-chunk coordinates that intersect the selection.
|
|
291
|
+
|
|
292
|
+
>>> for cx, cy, cz in selection1.sub_chunk_locations():
|
|
293
|
+
>>> ...
|
|
294
|
+
|
|
295
|
+
:param sub_chunk_size: The dimension of a sub-chunk. Default 16.
|
|
296
|
+
"""
|
|
297
|
+
raise NotImplementedError
|
|
298
|
+
|
|
299
|
+
@abstractmethod
|
|
300
|
+
def subtract(self, other):
|
|
301
|
+
raise NotImplementedError
|
|
302
|
+
|
|
303
|
+
@abstractmethod
|
|
304
|
+
def transform(
|
|
305
|
+
self, scale: FloatTriplet, rotation: FloatTriplet, translation: FloatTriplet
|
|
306
|
+
):
|
|
307
|
+
raise NotImplementedError
|
|
308
|
+
|
|
309
|
+
@property
|
|
310
|
+
@abstractmethod
|
|
311
|
+
def volume(self) -> int:
|
|
312
|
+
"""
|
|
313
|
+
The number of blocks in the selection.
|
|
314
|
+
"""
|
|
315
|
+
raise NotImplementedError
|