amulet-core 2.0.7a0__cp312-cp312-macosx_10_15_universal2.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.
Files changed (53) hide show
  1. amulet/core/__init__.py +38 -0
  2. amulet/core/__init__.pyi +31 -0
  3. amulet/core/__pyinstaller/__init__.py +2 -0
  4. amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
  5. amulet/core/_amulet_core.cpython-312-darwin.so +0 -0
  6. amulet/core/_amulet_core.pyi +7 -0
  7. amulet/core/_version.py +21 -0
  8. amulet/core/amulet_coreConfig.cmake +23 -0
  9. amulet/core/biome/__init__.pyi +75 -0
  10. amulet/core/biome/biome.hpp +53 -0
  11. amulet/core/block/__init__.pyi +273 -0
  12. amulet/core/block/block.hpp +156 -0
  13. amulet/core/block_entity/__init__.pyi +78 -0
  14. amulet/core/block_entity/block_entity.hpp +84 -0
  15. amulet/core/chunk/__init__.pyi +67 -0
  16. amulet/core/chunk/chunk.hpp +126 -0
  17. amulet/core/chunk/component/__init__.pyi +15 -0
  18. amulet/core/chunk/component/biome_3d_component.hpp +99 -0
  19. amulet/core/chunk/component/block_component.hpp +101 -0
  20. amulet/core/chunk/component/block_component.pyi +28 -0
  21. amulet/core/chunk/component/block_entity_component.hpp +119 -0
  22. amulet/core/chunk/component/section_array_map.hpp +178 -0
  23. amulet/core/chunk/component/section_array_map.pyi +112 -0
  24. amulet/core/dll.hpp +21 -0
  25. amulet/core/entity/__init__.pyi +105 -0
  26. amulet/core/entity/entity.hpp +100 -0
  27. amulet/core/libamulet_core.dylib +0 -0
  28. amulet/core/palette/__init__.pyi +8 -0
  29. amulet/core/palette/biome_palette.hpp +65 -0
  30. amulet/core/palette/biome_palette.pyi +48 -0
  31. amulet/core/palette/block_palette.hpp +71 -0
  32. amulet/core/palette/block_palette.pyi +52 -0
  33. amulet/core/py.typed +0 -0
  34. amulet/core/selection/__init__.pyi +25 -0
  35. amulet/core/selection/box.hpp +97 -0
  36. amulet/core/selection/box.pyi +239 -0
  37. amulet/core/selection/box_group.hpp +89 -0
  38. amulet/core/selection/box_group.pyi +222 -0
  39. amulet/core/selection/cuboid.hpp +41 -0
  40. amulet/core/selection/cuboid.pyi +49 -0
  41. amulet/core/selection/ellipsoid.hpp +42 -0
  42. amulet/core/selection/ellipsoid.pyi +47 -0
  43. amulet/core/selection/shape.hpp +73 -0
  44. amulet/core/selection/shape.pyi +56 -0
  45. amulet/core/selection/shape_group.hpp +73 -0
  46. amulet/core/selection/shape_group.pyi +118 -0
  47. amulet/core/version/__init__.pyi +138 -0
  48. amulet/core/version/version.hpp +206 -0
  49. amulet_core-2.0.7a0.dist-info/METADATA +112 -0
  50. amulet_core-2.0.7a0.dist-info/RECORD +53 -0
  51. amulet_core-2.0.7a0.dist-info/WHEEL +5 -0
  52. amulet_core-2.0.7a0.dist-info/entry_points.txt +2 -0
  53. amulet_core-2.0.7a0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,222 @@
1
+ from __future__ import annotations
2
+
3
+ import collections.abc
4
+ import types
5
+ import typing
6
+
7
+ import amulet.core.selection.box
8
+ import amulet.core.selection.shape_group
9
+ import amulet.utils.matrix
10
+
11
+ __all__: list[str] = ["SelectionBoxGroup"]
12
+
13
+ class SelectionBoxGroup:
14
+ """
15
+ A container for zero or more :class:`SelectionBox` instances.
16
+
17
+ This allows for non-rectangular and non-contiguous selections.
18
+ """
19
+
20
+ __hash__: typing.ClassVar[None] = None # type: ignore
21
+ def __bool__(self) -> bool:
22
+ """
23
+ Are there any selections in the group.
24
+ """
25
+
26
+ @typing.overload
27
+ def __eq__(self, other: SelectionBoxGroup) -> bool:
28
+ """
29
+ Does the contents of this :class:`SelectionBoxGroup` match the other :class:`SelectionBoxGroup`.
30
+
31
+ Note if the boxes do not exactly match this will return False even if the volume represented is the same.
32
+
33
+ :param other: The other :class:`SelectionBoxGroup` to compare with.
34
+ :return: True if the boxes contained match.
35
+ """
36
+
37
+ @typing.overload
38
+ def __eq__(self, other: typing.Any) -> bool | types.NotImplementedType: ...
39
+ @typing.overload
40
+ def __init__(self) -> None:
41
+ """
42
+ Create an empty SelectionBoxGroup.
43
+
44
+ >>> SelectionBoxGroup()
45
+ """
46
+
47
+ @typing.overload
48
+ def __init__(
49
+ self, shape_group: amulet.core.selection.shape_group.SelectionShapeGroup
50
+ ) -> None: ...
51
+ @typing.overload
52
+ def __init__(
53
+ self, boxes: collections.abc.Iterable[amulet.core.selection.box.SelectionBox]
54
+ ) -> None:
55
+ """
56
+ Create a SelectionBoxGroup from the boxes in the iterable.
57
+
58
+ >>> SelectionBoxGroup([
59
+ >>> SelectionBox(0, 0, 0, 1, 1, 1),
60
+ >>> SelectionBox(1, 1, 1, 1, 1, 1)
61
+ >>> ])
62
+ """
63
+
64
+ def __iter__(
65
+ self,
66
+ ) -> collections.abc.Iterator[amulet.core.selection.box.SelectionBox]:
67
+ """
68
+ An iterable of all the :class:`SelectionBox` classes in the group.
69
+ """
70
+
71
+ def __len__(self) -> int:
72
+ """
73
+ The number of :class:`SelectionBox` classes in the group.
74
+ """
75
+
76
+ def __repr__(self) -> str: ...
77
+ def __str__(self) -> str: ...
78
+ def contains_block(
79
+ self, x: typing.SupportsInt, y: typing.SupportsInt, z: typing.SupportsInt
80
+ ) -> bool:
81
+ """
82
+ Is the block contained within the selection.
83
+
84
+ >>> selection1: AbstractBaseSelection
85
+ >>> (1, 2, 3) in selection1
86
+ True
87
+
88
+ :param x: The x coordinate of the block. Defined by the most negative corner.
89
+ :param y: The y coordinate of the block. Defined by the most negative corner.
90
+ :param z: The z coordinate of the block. Defined by the most negative corner.
91
+ :return: True if the block is in the selection.
92
+ """
93
+
94
+ def contains_point(
95
+ self, x: typing.SupportsFloat, y: typing.SupportsFloat, z: typing.SupportsFloat
96
+ ) -> bool:
97
+ """
98
+ Is the point contained within the selection.
99
+
100
+ >>> selection1: AbstractBaseSelection
101
+ >>> (1.5, 2.5, 3.5) in selection1
102
+ True
103
+
104
+ :param x: The x coordinate of the point.
105
+ :param y: The y coordinate of the point.
106
+ :param z: The z coordinate of the point.
107
+ :return: True if the point is in the selection.
108
+ """
109
+
110
+ @typing.overload
111
+ def intersects(self, other: amulet.core.selection.box.SelectionBox) -> bool:
112
+ """
113
+ Does this selection intersect ``other``.
114
+
115
+ :param other: The other selection.
116
+ :return: True if the selections intersect, False otherwise.
117
+ """
118
+
119
+ @typing.overload
120
+ def intersects(self, other: SelectionBoxGroup) -> bool: ...
121
+ def transform(self, matrix: amulet.utils.matrix.Matrix4x4) -> SelectionBoxGroup:
122
+ """
123
+ Transform the boxes in this group by the given transformation matrix.
124
+ """
125
+
126
+ def translate(
127
+ self, dx: typing.SupportsInt, dy: typing.SupportsInt, dz: typing.SupportsInt
128
+ ) -> SelectionBoxGroup:
129
+ """
130
+ Create a new :class:`SelectionBoxGroup` based on this one with the coordinates moved by the given offset.
131
+
132
+ :param dx: The x offset.
133
+ :param dy: The y offset.
134
+ :param dz: The z offset.
135
+ :return: The new selection with the given offset.
136
+ """
137
+
138
+ @property
139
+ def bounding_box(self) -> amulet.core.selection.box.SelectionBox:
140
+ """
141
+ A SelectionBox containing this entire selection.
142
+
143
+ :raises RuntimeError: If there are no boxes in the selection.
144
+ """
145
+
146
+ @property
147
+ def bounds(self) -> tuple[tuple[int, int, int], tuple[int, int, int]]:
148
+ """
149
+ The minimum and maximum x, y and z coordinates in the selection.
150
+
151
+ :raises RuntimeError: If there are no boxes in the selection.
152
+ """
153
+
154
+ @property
155
+ def boxes(self) -> collections.abc.Iterator[amulet.core.selection.box.SelectionBox]:
156
+ """
157
+ An iterator of the :class:`SelectionBox` instances stored for this group.
158
+ """
159
+
160
+ @property
161
+ def max(self) -> tuple[int, int, int]:
162
+ """
163
+ The maximum x, y and z coordinates in the selection.
164
+
165
+ :raises RuntimeError: If there are no boxes in the selection.
166
+ """
167
+
168
+ @property
169
+ def max_x(self) -> int:
170
+ """
171
+ The maximum x coordinate in the selection.
172
+
173
+ :raises RuntimeError: If there are no boxes in the selection.
174
+ """
175
+
176
+ @property
177
+ def max_y(self) -> int:
178
+ """
179
+ The maximum y coordinate in the selection.
180
+
181
+ :raises RuntimeError: If there are no boxes in the selection.
182
+ """
183
+
184
+ @property
185
+ def max_z(self) -> int:
186
+ """
187
+ The maximum z coordinate in the selection.
188
+
189
+ :raises RuntimeError: If there are no boxes in the selection.
190
+ """
191
+
192
+ @property
193
+ def min(self) -> tuple[int, int, int]:
194
+ """
195
+ The minimum x, y and z coordinates in the selection.
196
+
197
+ :raises RuntimeError: If there are no boxes in the selection.
198
+ """
199
+
200
+ @property
201
+ def min_x(self) -> int:
202
+ """
203
+ The minimum x coordinate in the selection.
204
+
205
+ :raises RuntimeError: If there are no boxes in the selection.
206
+ """
207
+
208
+ @property
209
+ def min_y(self) -> int:
210
+ """
211
+ The minimum y coordinate in the selection.
212
+
213
+ :raises RuntimeError: If there are no boxes in the selection.
214
+ """
215
+
216
+ @property
217
+ def min_z(self) -> int:
218
+ """
219
+ The minimum z coordinate in the selection.
220
+
221
+ :raises RuntimeError: If there are no boxes in the selection.
222
+ """
@@ -0,0 +1,41 @@
1
+ #pragma once
2
+
3
+ #include <amulet/core/dll.hpp>
4
+
5
+ #include "shape.hpp"
6
+
7
+ namespace Amulet {
8
+
9
+ class AMULET_CORE_EXPORT SelectionCuboid : public SelectionShape {
10
+ public:
11
+ SelectionCuboid();
12
+ SelectionCuboid(const Matrix4x4&);
13
+
14
+ SelectionCuboid(
15
+ double min_x,
16
+ double min_y,
17
+ double min_z,
18
+ double size_x,
19
+ double size_y,
20
+ double size_z
21
+ );
22
+
23
+ SelectionCuboid(const SelectionCuboid& other);
24
+
25
+ std::string serialise() const override;
26
+
27
+ std::unique_ptr<SelectionShape> copy() const override;
28
+ explicit operator std::set<SelectionBox>() const override;
29
+
30
+ // Transform
31
+ SelectionCuboid translate_cuboid(double dx, double dy, double dz) const;
32
+ SelectionCuboid transform_cuboid(const Matrix4x4&) const;
33
+ std::unique_ptr<SelectionShape> transform(const Matrix4x4&) const override;
34
+
35
+ bool almost_equal(const SelectionCuboid&) const;
36
+ bool almost_equal(const SelectionShape&) const override;
37
+ bool operator==(const SelectionCuboid&) const;
38
+ bool operator==(const SelectionShape&) const override;
39
+ };
40
+
41
+ } // namespace Amulet
@@ -0,0 +1,49 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+
5
+ import amulet.core.selection.shape
6
+ import amulet.utils.matrix
7
+
8
+ __all__: list[str] = ["SelectionCuboid"]
9
+
10
+ class SelectionCuboid(amulet.core.selection.shape.SelectionShape):
11
+ """
12
+ The SelectionCuboid class represents a single spherical selection.
13
+ """
14
+
15
+ @typing.overload
16
+ def __init__(
17
+ self,
18
+ min_x: typing.SupportsFloat,
19
+ min_y: typing.SupportsFloat,
20
+ min_z: typing.SupportsFloat,
21
+ size_x: typing.SupportsFloat,
22
+ size_y: typing.SupportsFloat,
23
+ size_z: typing.SupportsFloat,
24
+ ) -> None: ...
25
+ @typing.overload
26
+ def __init__(self, matrix: amulet.utils.matrix.Matrix4x4) -> None: ...
27
+ def __repr__(self) -> str: ...
28
+ def transform(self, matrix: amulet.utils.matrix.Matrix4x4) -> SelectionCuboid:
29
+ """
30
+ Create a new :class:`SelectionCuboid` based on this one transformed by the given matrix.
31
+
32
+ :param matrix: The matrix to transform by.
33
+ :return: The new selection with the added transform.
34
+ """
35
+
36
+ def translate(
37
+ self,
38
+ dx: typing.SupportsFloat,
39
+ dy: typing.SupportsFloat,
40
+ dz: typing.SupportsFloat,
41
+ ) -> SelectionCuboid:
42
+ """
43
+ Create a new :class:`SelectionCuboid` based on this one with the coordinates moved by the given offset.
44
+
45
+ :param dx: The x offset.
46
+ :param dy: The y offset.
47
+ :param dz: The z offset.
48
+ :return: The new selection with the given offset.
49
+ """
@@ -0,0 +1,42 @@
1
+ #pragma once
2
+ #include <cstdint>
3
+
4
+ #include <amulet/core/dll.hpp>
5
+
6
+ #include "shape.hpp"
7
+
8
+ namespace Amulet {
9
+
10
+ class SelectionBox;
11
+
12
+ // The SelectionEllipsoid class represents a single spherical selection.
13
+ class AMULET_CORE_EXPORT SelectionEllipsoid : public SelectionShape {
14
+ public:
15
+ SelectionEllipsoid();
16
+ SelectionEllipsoid(const Matrix4x4&);
17
+
18
+ SelectionEllipsoid(
19
+ double x,
20
+ double y,
21
+ double z,
22
+ double radius);
23
+
24
+ SelectionEllipsoid(const SelectionEllipsoid& other);
25
+
26
+ std::string serialise() const override;
27
+
28
+ std::unique_ptr<SelectionShape> copy() const override;
29
+ explicit operator std::set<SelectionBox>() const override;
30
+
31
+ // Transform
32
+ SelectionEllipsoid translate_ellipsoid(double dx, double dy, double dz) const;
33
+ SelectionEllipsoid transform_ellipsoid(const Matrix4x4&) const;
34
+ std::unique_ptr<SelectionShape> transform(const Matrix4x4&) const override;
35
+
36
+ bool almost_equal(const SelectionEllipsoid&) const;
37
+ bool almost_equal(const SelectionShape&) const override;
38
+ bool operator==(const SelectionEllipsoid&) const;
39
+ bool operator==(const SelectionShape&) const override;
40
+ };
41
+
42
+ } // namespace Amulet
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+
5
+ import amulet.core.selection.shape
6
+ import amulet.utils.matrix
7
+
8
+ __all__: list[str] = ["SelectionEllipsoid"]
9
+
10
+ class SelectionEllipsoid(amulet.core.selection.shape.SelectionShape):
11
+ """
12
+ The SelectionEllipsoid class represents a single ellipsoid selection.
13
+ """
14
+
15
+ @typing.overload
16
+ def __init__(
17
+ self,
18
+ x: typing.SupportsFloat,
19
+ y: typing.SupportsFloat,
20
+ z: typing.SupportsFloat,
21
+ radius: typing.SupportsFloat,
22
+ ) -> None: ...
23
+ @typing.overload
24
+ def __init__(self, matrix: amulet.utils.matrix.Matrix4x4) -> None: ...
25
+ def __repr__(self) -> str: ...
26
+ def transform(self, matrix: amulet.utils.matrix.Matrix4x4) -> SelectionEllipsoid:
27
+ """
28
+ Create a new :class:`SelectionEllipsoid` based on this one transformed by the given matrix.
29
+
30
+ :param matrix: The matrix to transform by.
31
+ :return: The new selection with the added transform.
32
+ """
33
+
34
+ def translate(
35
+ self,
36
+ dx: typing.SupportsFloat,
37
+ dy: typing.SupportsFloat,
38
+ dz: typing.SupportsFloat,
39
+ ) -> SelectionEllipsoid:
40
+ """
41
+ Create a new :class:`SelectionEllipsoid` based on this one with the coordinates moved by the given offset.
42
+
43
+ :param dx: The x offset.
44
+ :param dy: The y offset.
45
+ :param dz: The z offset.
46
+ :return: The new selection with the given offset.
47
+ """
@@ -0,0 +1,73 @@
1
+ #pragma once
2
+
3
+ #include <functional>
4
+ #include <list>
5
+ #include <memory>
6
+ #include <optional>
7
+ #include <set>
8
+ #include <string>
9
+ #include <string_view>
10
+ #include <utility>
11
+
12
+ #include <amulet/utils/matrix.hpp>
13
+
14
+ #include <amulet/core/dll.hpp>
15
+
16
+ namespace Amulet {
17
+
18
+ class SelectionBox;
19
+ class SelectionBoxGroup;
20
+
21
+ class AMULET_CORE_EXPORT SelectionShape {
22
+ private:
23
+ Matrix4x4 _matrix;
24
+
25
+ public:
26
+ SelectionShape() = default;
27
+ SelectionShape(const Matrix4x4& matrix)
28
+ : _matrix(matrix)
29
+ {
30
+ }
31
+ virtual ~SelectionShape() = default;
32
+
33
+ const Matrix4x4& get_matrix() const;
34
+ void set_matrix(const Matrix4x4&);
35
+
36
+ // Convert the class to human readable plain text.
37
+ virtual std::string serialise() const = 0;
38
+
39
+ // Deserialise the serialised data back to an object.
40
+ static std::unique_ptr<SelectionShape> deserialise(std::string_view, size_t&);
41
+ static std::unique_ptr<SelectionShape> deserialise(std::string_view);
42
+
43
+ using Deserialiser = std::function<
44
+ std::unique_ptr<SelectionShape>(std::string_view, size_t&)>;
45
+
46
+ static bool register_deserialiser(Deserialiser);
47
+
48
+ // Create a copy of the class.
49
+ virtual std::unique_ptr<SelectionShape> copy() const = 0;
50
+
51
+ explicit operator std::unique_ptr<SelectionShape>() const
52
+ {
53
+ return copy();
54
+ }
55
+
56
+ // Convert the shape into unit voxels.
57
+ virtual explicit operator std::set<SelectionBox>() const = 0;
58
+ explicit operator SelectionBoxGroup() const;
59
+ SelectionBoxGroup voxelise() const;
60
+
61
+ // translate and transform
62
+ virtual std::unique_ptr<SelectionShape> transform(const Matrix4x4&) const = 0;
63
+ std::unique_ptr<SelectionShape> translate(double dx, double dy, double dz) const
64
+ {
65
+ return transform(Matrix4x4::translation_matrix(dx, dy, dz));
66
+ }
67
+
68
+ // Equality
69
+ virtual bool almost_equal(const SelectionShape&) const = 0;
70
+ virtual bool operator==(const SelectionShape&) const = 0;
71
+ };
72
+
73
+ } // namespace Amulet
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ import types
4
+ import typing
5
+
6
+ import amulet.core.selection.box_group
7
+ import amulet.utils.matrix
8
+
9
+ __all__: list[str] = ["SelectionShape"]
10
+
11
+ class SelectionShape:
12
+ """
13
+ A base class for selection classes.
14
+ """
15
+
16
+ __hash__: typing.ClassVar[None] = None # type: ignore
17
+ matrix: amulet.utils.matrix.Matrix4x4
18
+ @staticmethod
19
+ def deserialise(s: str) -> SelectionShape:
20
+ """
21
+ Deserialise the serialised data back to an object.
22
+ """
23
+
24
+ @typing.overload
25
+ def __eq__(self, other: SelectionShape) -> bool: ...
26
+ @typing.overload
27
+ def __eq__(self, other: typing.Any) -> bool | types.NotImplementedType: ...
28
+ def almost_equal(self, other: SelectionShape) -> bool:
29
+ """
30
+ Check if this shape is equal or almost equal to another shape.
31
+ """
32
+
33
+ def serialise(self) -> str:
34
+ """
35
+ Convert the class to human readable plain text.
36
+ """
37
+
38
+ def transform(self, matrix: amulet.utils.matrix.Matrix4x4) -> SelectionShape:
39
+ """
40
+ Translate the shape by the given matrix
41
+ """
42
+
43
+ def translate(
44
+ self,
45
+ dx: typing.SupportsFloat,
46
+ dy: typing.SupportsFloat,
47
+ dz: typing.SupportsFloat,
48
+ ) -> SelectionShape:
49
+ """
50
+ Translate the shape by the given amount
51
+ """
52
+
53
+ def voxelise(self) -> amulet.core.selection.box_group.SelectionBoxGroup:
54
+ """
55
+ Convert the selection to a SelectionBoxGroup.
56
+ """
@@ -0,0 +1,73 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+ #include <string>
5
+ #include <string_view>
6
+ #include <vector>
7
+
8
+ #include <amulet/core/dll.hpp>
9
+
10
+ #include "shape.hpp"
11
+
12
+ namespace Amulet {
13
+
14
+ class SelectionBox;
15
+ class SelectionBoxGroup;
16
+
17
+ class AMULET_CORE_EXPORT SelectionShapeGroup {
18
+ private:
19
+ std::vector<std::shared_ptr<SelectionShape>> _shapes;
20
+
21
+ public:
22
+ SelectionShapeGroup();
23
+ SelectionShapeGroup(std::vector<std::shared_ptr<SelectionShape>> shapes);
24
+
25
+ SelectionShapeGroup(const SelectionShapeGroup&);
26
+ SelectionShapeGroup& operator=(const SelectionShapeGroup&);
27
+
28
+ SelectionShapeGroup(SelectionShapeGroup&&);
29
+ SelectionShapeGroup& operator=(SelectionShapeGroup&&);
30
+
31
+ SelectionShapeGroup deep_copy() const;
32
+
33
+ std::string serialise() const;
34
+ static SelectionShapeGroup deserialise(std::string_view);
35
+
36
+ const std::vector<std::shared_ptr<SelectionShape>>& get_shapes() const
37
+ {
38
+ return _shapes;
39
+ }
40
+ std::vector<std::shared_ptr<SelectionShape>>& get_shapes()
41
+ {
42
+ return _shapes;
43
+ }
44
+ void set_shapes(std::vector<std::shared_ptr<SelectionShape>> shapes)
45
+ {
46
+ _shapes = std::move(shapes);
47
+ }
48
+ std::vector<std::shared_ptr<SelectionShape>>::const_iterator begin() const
49
+ {
50
+ return _shapes.begin();
51
+ }
52
+ std::vector<std::shared_ptr<SelectionShape>>::const_iterator end() const
53
+ {
54
+ return _shapes.end();
55
+ }
56
+ operator bool() const
57
+ {
58
+ return !_shapes.empty();
59
+ }
60
+ size_t count() const
61
+ {
62
+ return _shapes.size();
63
+ }
64
+
65
+ explicit operator SelectionBoxGroup() const;
66
+ explicit operator std::set<SelectionBox>() const;
67
+ SelectionBoxGroup voxelise() const;
68
+
69
+ bool almost_equal(const SelectionShapeGroup&) const;
70
+ bool operator==(const SelectionShapeGroup&) const;
71
+ };
72
+
73
+ }