honeycomb_kernels/remeshing/
anchoring.rs1use honeycomb_core::{
4 attributes::{AttrSparseVec, AttributeBind, AttributeError, AttributeUpdate},
5 cmap::{EdgeIdType, FaceIdType, OrbitPolicy, VertexIdType},
6};
7
8pub type NodeIdType = u32;
10pub type CurveIdType = u32;
12pub type SurfaceIdType = u32;
14pub type BodyIdType = u32;
16
17#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
28pub enum VertexAnchor {
29 Node(NodeIdType),
31 Curve(CurveIdType),
33 Surface(SurfaceIdType),
35 Body(BodyIdType),
37}
38
39impl VertexAnchor {
40 #[must_use = "unused return value"]
42 pub const fn anchor_dim(&self) -> u8 {
43 match self {
44 Self::Node(_) => 0,
45 Self::Curve(_) => 1,
46 Self::Surface(_) => 2,
47 Self::Body(_) => 3,
48 }
49 }
50}
51
52impl AttributeBind for VertexAnchor {
53 type StorageType = AttrSparseVec<Self>;
54 type IdentifierType = VertexIdType;
55 const BIND_POLICY: OrbitPolicy = OrbitPolicy::Vertex;
56}
57
58impl AttributeUpdate for VertexAnchor {
59 fn merge(attr1: Self, attr2: Self) -> Result<Self, AttributeError> {
60 match (attr1, attr2) {
61 (Self::Node(id1), Self::Node(id2)) => {
62 if id1 == id2 {
63 Ok(Self::Node(id1))
64 } else {
65 Err(AttributeError::FailedMerge(
66 std::any::type_name::<Self>(),
67 "anchors have the same dimension but different IDs",
68 ))
69 }
70 }
71 (Self::Node(id), _) | (_, Self::Node(id)) => Ok(Self::Node(id)),
72 (Self::Curve(id1), Self::Curve(id2)) => {
73 if id1 == id2 {
74 Ok(Self::Curve(id1))
75 } else {
76 Err(AttributeError::FailedMerge(
77 std::any::type_name::<Self>(),
78 "anchors have the same dimension but different IDs",
79 ))
80 }
81 }
82 (Self::Curve(id), _) | (_, Self::Curve(id)) => Ok(Self::Curve(id)),
83 (Self::Surface(id1), Self::Surface(id2)) => {
84 if id1 == id2 {
85 Ok(Self::Surface(id1))
86 } else {
87 Err(AttributeError::FailedMerge(
88 std::any::type_name::<Self>(),
89 "anchors have the same dimension but different IDs",
90 ))
91 }
92 }
93 (Self::Surface(id), _) | (_, Self::Surface(id)) => Ok(Self::Surface(id)),
94 (Self::Body(id1), Self::Body(id2)) => {
95 if id1 == id2 {
96 Ok(Self::Body(id1))
97 } else {
98 Err(AttributeError::FailedMerge(
99 std::any::type_name::<Self>(),
100 "anchors have the same dimension but different IDs",
101 ))
102 }
103 }
104 }
105 }
106
107 fn split(attr: Self) -> Result<(Self, Self), AttributeError> {
108 Ok((attr, attr))
109 }
110
111 fn merge_incomplete(val: Self) -> Result<Self, AttributeError> {
112 Ok(val)
113 }
114}
115
116impl From<EdgeAnchor> for VertexAnchor {
117 fn from(value: EdgeAnchor) -> Self {
118 match value {
119 EdgeAnchor::Curve(i) => VertexAnchor::Curve(i),
120 EdgeAnchor::Surface(i) => VertexAnchor::Surface(i),
121 EdgeAnchor::Body(i) => VertexAnchor::Body(i),
122 }
123 }
124}
125
126impl From<FaceAnchor> for VertexAnchor {
127 fn from(value: FaceAnchor) -> Self {
128 match value {
129 FaceAnchor::Surface(i) => VertexAnchor::Surface(i),
130 FaceAnchor::Body(i) => VertexAnchor::Body(i),
131 }
132 }
133}
134
135#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
146pub enum EdgeAnchor {
147 Curve(CurveIdType),
149 Surface(SurfaceIdType),
151 Body(BodyIdType),
153}
154
155impl EdgeAnchor {
156 #[must_use = "unused return value"]
158 pub const fn anchor_dim(&self) -> u8 {
159 match self {
160 Self::Curve(_) => 1,
161 Self::Surface(_) => 2,
162 Self::Body(_) => 3,
163 }
164 }
165}
166
167impl AttributeBind for EdgeAnchor {
168 type StorageType = AttrSparseVec<Self>;
169 type IdentifierType = EdgeIdType;
170 const BIND_POLICY: OrbitPolicy = OrbitPolicy::Edge;
171}
172
173impl AttributeUpdate for EdgeAnchor {
174 fn merge(attr1: Self, attr2: Self) -> Result<Self, AttributeError> {
175 match (attr1, attr2) {
176 (Self::Curve(id1), Self::Curve(id2)) => {
177 if id1 == id2 {
178 Ok(Self::Curve(id1))
179 } else {
180 Err(AttributeError::FailedMerge(
181 std::any::type_name::<Self>(),
182 "anchors have the same dimension but different IDs",
183 ))
184 }
185 }
186 (Self::Curve(id), _) | (_, Self::Curve(id)) => Ok(Self::Curve(id)),
187 (Self::Surface(id1), Self::Surface(id2)) => {
188 if id1 == id2 {
189 Ok(Self::Surface(id1))
190 } else {
191 Err(AttributeError::FailedMerge(
192 std::any::type_name::<Self>(),
193 "anchors have the same dimension but different IDs",
194 ))
195 }
196 }
197 (Self::Surface(id), _) | (_, Self::Surface(id)) => Ok(Self::Surface(id)),
198 (Self::Body(id1), Self::Body(id2)) => {
199 if id1 == id2 {
200 Ok(Self::Body(id1))
201 } else {
202 Err(AttributeError::FailedMerge(
203 std::any::type_name::<Self>(),
204 "anchors have the same dimension but different IDs",
205 ))
206 }
207 }
208 }
209 }
210
211 fn split(attr: Self) -> Result<(Self, Self), AttributeError> {
212 Ok((attr, attr))
213 }
214
215 fn merge_incomplete(val: Self) -> Result<Self, AttributeError> {
216 Ok(val)
217 }
218}
219
220impl From<FaceAnchor> for EdgeAnchor {
221 fn from(value: FaceAnchor) -> Self {
222 match value {
223 FaceAnchor::Surface(i) => EdgeAnchor::Surface(i),
224 FaceAnchor::Body(i) => EdgeAnchor::Body(i),
225 }
226 }
227}
228
229#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
240pub enum FaceAnchor {
241 Surface(SurfaceIdType),
243 Body(BodyIdType),
245}
246
247impl FaceAnchor {
248 #[must_use = "unused return value"]
250 pub const fn anchor_dim(&self) -> u8 {
251 match self {
252 Self::Surface(_) => 2,
253 Self::Body(_) => 3,
254 }
255 }
256}
257
258impl AttributeBind for FaceAnchor {
259 type StorageType = AttrSparseVec<Self>;
260 type IdentifierType = FaceIdType;
261 const BIND_POLICY: OrbitPolicy = OrbitPolicy::Face;
262}
263
264impl AttributeUpdate for FaceAnchor {
265 fn merge(attr1: Self, attr2: Self) -> Result<Self, AttributeError> {
266 match (attr1, attr2) {
267 (Self::Surface(id1), Self::Surface(id2)) => {
268 if id1 == id2 {
269 Ok(Self::Surface(id1))
270 } else {
271 Err(AttributeError::FailedMerge(
272 std::any::type_name::<Self>(),
273 "anchors have the same dimension but different IDs",
274 ))
275 }
276 }
277 (Self::Surface(id), _) | (_, Self::Surface(id)) => Ok(Self::Surface(id)),
278 (Self::Body(id1), Self::Body(id2)) => {
279 if id1 == id2 {
280 Ok(Self::Body(id1))
281 } else {
282 Err(AttributeError::FailedMerge(
283 std::any::type_name::<Self>(),
284 "anchors have the same dimension but different IDs",
285 ))
286 }
287 }
288 }
289 }
290
291 fn split(attr: Self) -> Result<(Self, Self), AttributeError> {
292 Ok((attr, attr))
293 }
294
295 fn merge_incomplete(val: Self) -> Result<Self, AttributeError> {
296 Ok(val)
297 }
298}