honeycomb_core/cmap/dim3/
basic_ops.rs1use std::collections::{HashSet, VecDeque};
11
12use crate::attributes::UnknownAttributeStorage;
13use crate::cmap::{
14 CMap3, DartIdType, EdgeIdType, FaceIdType, Orbit3, OrbitPolicy, VertexIdType, VolumeIdType,
15 NULL_DART_ID,
16};
17use crate::geometry::CoordsFloat;
18use crate::stm::{atomically, StmClosureResult, StmError, Transaction};
19
20impl<T: CoordsFloat> CMap3<T> {
22 #[must_use = "unused return value"]
26 pub fn n_darts(&self) -> usize {
27 self.unused_darts.len()
28 }
29
30 #[must_use = "unused return value"]
32 pub fn n_unused_darts(&self) -> usize {
33 self.unused_darts.iter().filter(|v| v.read_atomic()).count()
34 }
35
36 pub fn add_free_dart(&mut self) -> DartIdType {
44 let new_id = self.n_darts() as DartIdType;
45 self.betas.extend(1);
46 self.unused_darts.extend(1);
47 self.vertices.extend(1);
48 self.attributes.extend_storages(1);
49 new_id
50 }
51
52 pub fn add_free_darts(&mut self, n_darts: usize) -> DartIdType {
58 let new_id = self.n_darts() as DartIdType;
59 self.betas.extend(n_darts);
60 self.unused_darts.extend(n_darts);
61 self.vertices.extend(n_darts);
62 self.attributes.extend_storages(n_darts);
63 new_id
64 }
65
66 pub fn insert_free_dart(&mut self) -> DartIdType {
74 if let Some((new_id, _)) = self
75 .unused_darts
76 .iter()
77 .enumerate()
78 .find(|(_, u)| u.read_atomic())
79 {
80 atomically(|trans| self.unused_darts[new_id as DartIdType].write(trans, false));
81 new_id as DartIdType
82 } else {
83 self.add_free_dart()
84 }
85 }
86
87 pub fn remove_free_dart(&mut self, dart_id: DartIdType) {
103 atomically(|trans| {
104 assert!(self.is_free(dart_id)); assert!(!self.unused_darts[dart_id as DartIdType].replace(trans, true)?);
106 Ok(())
107 });
108 }
109}
110
111impl<T: CoordsFloat> CMap3<T> {
113 pub fn beta_transac<const I: u8>(
127 &self,
128 trans: &mut Transaction,
129 dart_id: DartIdType,
130 ) -> StmClosureResult<DartIdType> {
131 assert!(I < 4);
132 self.betas[(I, dart_id)].read(trans)
133 }
134
135 pub fn beta_rt_transac(
147 &self,
148 trans: &mut Transaction,
149 i: u8,
150 dart_id: DartIdType,
151 ) -> StmClosureResult<DartIdType> {
152 assert!(i < 4);
153 match i {
154 0 => self.beta_transac::<0>(trans, dart_id),
155 1 => self.beta_transac::<1>(trans, dart_id),
156 2 => self.beta_transac::<2>(trans, dart_id),
157 3 => self.beta_transac::<3>(trans, dart_id),
158 _ => unreachable!(),
159 }
160 }
161
162 #[must_use = "unused return value"]
168 pub fn beta<const I: u8>(&self, dart_id: DartIdType) -> DartIdType {
169 assert!(I < 4);
170 self.betas[(I, dart_id)].read_atomic()
171 }
172
173 #[must_use = "unused return value"]
179 pub fn beta_rt(&self, i: u8, dart_id: DartIdType) -> DartIdType {
180 assert!(i < 4);
181 match i {
182 0 => self.beta::<0>(dart_id),
183 1 => self.beta::<1>(dart_id),
184 2 => self.beta::<2>(dart_id),
185 3 => self.beta::<3>(dart_id),
186 _ => unreachable!(),
187 }
188 }
189
190 #[must_use = "unused return value"]
202 pub fn is_i_free<const I: u8>(&self, dart_id: DartIdType) -> bool {
203 self.beta::<I>(dart_id) == NULL_DART_ID
204 }
205
206 #[must_use = "unused return value"]
212 pub fn is_free(&self, dart_id: DartIdType) -> bool {
213 self.beta::<0>(dart_id) == NULL_DART_ID
214 && self.beta::<1>(dart_id) == NULL_DART_ID
215 && self.beta::<2>(dart_id) == NULL_DART_ID
216 && self.beta::<3>(dart_id) == NULL_DART_ID
217 }
218}
219
220impl<T: CoordsFloat> CMap3<T> {
222 #[must_use = "unused return value"]
226 pub fn vertex_id(&self, dart_id: DartIdType) -> VertexIdType {
227 let mut marked = HashSet::new();
228 let mut queue = VecDeque::new();
229 marked.insert(NULL_DART_ID);
230 queue.push_front(dart_id);
231 let mut min = dart_id;
232
233 while let Some(d) = queue.pop_front() {
234 if marked.insert(d) {
235 min = min.min(d);
236 let (b0, b2, b3) = (
237 self.beta::<0>(d), self.beta::<2>(d),
239 self.beta::<3>(d),
240 );
241 queue.push_back(self.beta::<1>(b3));
242 queue.push_back(self.beta::<3>(b2));
243 queue.push_back(self.beta::<1>(b2));
244 queue.push_back(self.beta::<3>(b0)); queue.push_back(self.beta::<2>(b0)); }
247 }
248
249 min
250 }
251
252 pub fn vertex_id_transac(
262 &self,
263 trans: &mut Transaction,
264 dart_id: DartIdType,
265 ) -> Result<VertexIdType, StmError> {
266 let mut marked = HashSet::new();
267 let mut queue = VecDeque::new();
268 marked.insert(NULL_DART_ID);
269 queue.push_front(dart_id);
270 let mut min = dart_id;
271
272 while let Some(d) = queue.pop_front() {
273 if marked.insert(d) {
274 min = min.min(d);
275 let (b0, b2, b3) = (
276 self.beta_transac::<0>(trans, d)?, self.beta_transac::<2>(trans, d)?,
278 self.beta_transac::<3>(trans, d)?,
279 );
280 queue.push_back(self.beta_transac::<1>(trans, b3)?);
281 queue.push_back(self.beta_transac::<3>(trans, b2)?);
282 queue.push_back(self.beta_transac::<1>(trans, b2)?);
283 queue.push_back(self.beta_transac::<3>(trans, b0)?); queue.push_back(self.beta_transac::<2>(trans, b0)?); }
286 }
287
288 Ok(min)
289 }
290
291 #[must_use = "unused return value"]
295 pub fn edge_id(&self, dart_id: DartIdType) -> EdgeIdType {
296 let mut marked = HashSet::new();
297 marked.insert(NULL_DART_ID);
298 let (mut lb, mut rb) = (dart_id, self.beta::<3>(dart_id));
299 let mut min = if rb == NULL_DART_ID { lb } else { lb.min(rb) };
300 let mut alt = true;
301
302 while marked.insert(lb) || marked.insert(rb) {
303 (lb, rb) = if alt {
304 (self.beta::<2>(lb), self.beta::<2>(rb))
305 } else {
306 (self.beta::<3>(lb), self.beta::<3>(rb))
307 };
308 if lb != NULL_DART_ID {
309 min = min.min(lb);
310 }
311 if rb != NULL_DART_ID {
312 min = min.min(rb);
313 }
314 alt = !alt;
315 }
316
317 min
318 }
319
320 pub fn edge_id_transac(
330 &self,
331 trans: &mut Transaction,
332 dart_id: DartIdType,
333 ) -> Result<EdgeIdType, StmError> {
334 let mut marked = HashSet::new();
335 marked.insert(NULL_DART_ID);
336 let (mut lb, mut rb) = (dart_id, self.beta_transac::<3>(trans, dart_id)?);
337 let mut min = if rb == NULL_DART_ID { lb } else { lb.min(rb) };
338 let mut alt = true;
339
340 while marked.insert(lb) || marked.insert(rb) {
341 (lb, rb) = if alt {
342 (
343 self.beta_transac::<2>(trans, lb)?,
344 self.beta_transac::<2>(trans, rb)?,
345 )
346 } else {
347 (
348 self.beta_transac::<3>(trans, lb)?,
349 self.beta_transac::<3>(trans, rb)?,
350 )
351 };
352 if lb != NULL_DART_ID {
353 min = min.min(lb);
354 }
355 if rb != NULL_DART_ID {
356 min = min.min(rb);
357 }
358 alt = !alt;
359 }
360
361 Ok(min)
362 }
363
364 #[must_use = "unused return value"]
368 pub fn face_id(&self, dart_id: DartIdType) -> FaceIdType {
369 let mut marked = HashSet::new();
370 marked.insert(NULL_DART_ID);
371 let b3_dart_id = self.beta::<3>(dart_id);
372 let (mut lb, mut rb) = (dart_id, b3_dart_id);
373 let mut min = if rb == NULL_DART_ID { lb } else { lb.min(rb) };
374
375 while marked.insert(lb) || marked.insert(rb) {
376 (lb, rb) = (self.beta::<1>(lb), self.beta::<0>(rb));
377 if lb != NULL_DART_ID {
378 min = min.min(lb);
379 }
380 if rb != NULL_DART_ID {
381 min = min.min(rb);
382 }
383 }
384 if lb == NULL_DART_ID || rb == NULL_DART_ID {
386 (lb, rb) = (self.beta::<0>(dart_id), self.beta::<1>(b3_dart_id));
387 while marked.insert(lb) || marked.insert(rb) {
388 (lb, rb) = (self.beta::<0>(lb), self.beta::<1>(rb));
389 if lb != NULL_DART_ID {
390 min = min.min(lb);
391 }
392 if rb != NULL_DART_ID {
393 min = min.min(rb);
394 }
395 }
396 }
397
398 min
399 }
400
401 pub fn face_id_transac(
411 &self,
412 trans: &mut Transaction,
413 dart_id: DartIdType,
414 ) -> Result<FaceIdType, StmError> {
415 let mut marked = HashSet::new();
416 marked.insert(NULL_DART_ID);
417 let b3_dart_id = self.beta_transac::<3>(trans, dart_id)?;
418 let (mut lb, mut rb) = (dart_id, b3_dart_id);
419 let mut min = if rb == NULL_DART_ID { lb } else { lb.min(rb) };
420
421 while marked.insert(lb) || marked.insert(rb) {
422 (lb, rb) = (
423 self.beta_transac::<1>(trans, lb)?,
424 self.beta_transac::<0>(trans, rb)?,
425 );
426 if lb != NULL_DART_ID {
427 min = min.min(lb);
428 }
429 if rb != NULL_DART_ID {
430 min = min.min(rb);
431 }
432 }
433 if lb == NULL_DART_ID || rb == NULL_DART_ID {
435 (lb, rb) = (
436 self.beta_transac::<0>(trans, dart_id)?,
437 self.beta_transac::<1>(trans, b3_dart_id)?,
438 );
439 while marked.insert(lb) || marked.insert(rb) {
440 (lb, rb) = (
441 self.beta_transac::<0>(trans, lb)?,
442 self.beta_transac::<1>(trans, rb)?,
443 );
444 if lb != NULL_DART_ID {
445 min = min.min(lb);
446 }
447 if rb != NULL_DART_ID {
448 min = min.min(rb);
449 }
450 }
451 }
452
453 Ok(min)
454 }
455
456 #[must_use = "unused return value"]
460 pub fn volume_id(&self, dart_id: DartIdType) -> VolumeIdType {
461 let mut marked = HashSet::new();
462 let mut queue = VecDeque::new();
463 marked.insert(NULL_DART_ID);
464 queue.push_front(dart_id);
465 let mut min = dart_id;
466
467 while let Some(d) = queue.pop_front() {
468 if marked.insert(d) {
469 min = min.min(d);
470 queue.push_back(self.beta::<1>(d));
471 queue.push_back(self.beta::<0>(d)); queue.push_back(self.beta::<2>(d));
473 }
474 }
475
476 min
477 }
478
479 pub fn volume_id_transac(
489 &self,
490 trans: &mut Transaction,
491 dart_id: DartIdType,
492 ) -> Result<VolumeIdType, StmError> {
493 let mut marked = HashSet::new();
494 let mut queue = VecDeque::new();
495 marked.insert(NULL_DART_ID);
496 queue.push_front(dart_id);
497 let mut min = dart_id;
498
499 while let Some(d) = queue.pop_front() {
500 if marked.insert(d) {
501 min = min.min(d);
502 queue.push_back(self.beta_transac::<1>(trans, d)?);
503 queue.push_back(self.beta_transac::<0>(trans, d)?); queue.push_back(self.beta_transac::<2>(trans, d)?);
505 }
506 }
507
508 Ok(min)
509 }
510
511 #[must_use = "unused return value"]
522 pub fn i_cell<const I: u8>(&self, dart_id: DartIdType) -> Orbit3<'_, T> {
523 assert!(I < 4);
524 match I {
525 0 => Orbit3::new(self, OrbitPolicy::Vertex, dart_id),
526 1 => Orbit3::new(self, OrbitPolicy::Edge, dart_id),
527 2 => Orbit3::new(self, OrbitPolicy::Face, dart_id),
528 3 => todo!(),
529 _ => unreachable!(),
530 }
531 }
532
533 pub fn iter_vertices(&self) -> impl Iterator<Item = VertexIdType> + '_ {
535 (1..self.n_darts() as DartIdType)
536 .zip(self.unused_darts.iter().skip(1))
537 .filter_map(
538 |(d, unused)| {
539 if unused.read_atomic() {
540 None
541 } else {
542 Some(d)
543 }
544 },
545 )
546 .filter_map(|d| {
547 let vid = self.vertex_id(d);
548 if d == vid {
549 Some(vid)
550 } else {
551 None
552 }
553 })
554 }
555
556 pub fn iter_edges(&self) -> impl Iterator<Item = EdgeIdType> + '_ {
558 (1..self.n_darts() as DartIdType)
559 .zip(self.unused_darts.iter().skip(1))
560 .filter_map(
561 |(d, unused)| {
562 if unused.read_atomic() {
563 None
564 } else {
565 Some(d)
566 }
567 },
568 )
569 .filter_map(|d| {
570 let eid = self.edge_id(d);
571 if d == eid {
572 Some(eid)
573 } else {
574 None
575 }
576 })
577 }
578
579 pub fn iter_faces(&self) -> impl Iterator<Item = FaceIdType> + '_ {
581 (1..self.n_darts() as DartIdType)
582 .zip(self.unused_darts.iter().skip(1))
583 .filter_map(
584 |(d, unused)| {
585 if unused.read_atomic() {
586 None
587 } else {
588 Some(d)
589 }
590 },
591 )
592 .filter_map(|d| {
593 let fid = self.face_id(d);
594 if d == fid {
595 Some(fid)
596 } else {
597 None
598 }
599 })
600 }
601
602 pub fn iter_volumes(&self) -> impl Iterator<Item = VolumeIdType> + '_ {
604 (1..self.n_darts() as DartIdType)
605 .zip(self.unused_darts.iter().skip(1))
606 .filter_map(
607 |(d, unused)| {
608 if unused.read_atomic() {
609 None
610 } else {
611 Some(d)
612 }
613 },
614 )
615 .filter_map(|d| {
616 let vid = self.volume_id(d);
617 if d == vid {
618 Some(vid)
619 } else {
620 None
621 }
622 })
623 }
624}