diff --git a/benches/benches/core/cmap2/link_and_sew.rs b/benches/benches/core/cmap2/link_and_sew.rs index 3505a10e..2deefe40 100644 --- a/benches/benches/core/cmap2/link_and_sew.rs +++ b/benches/benches/core/cmap2/link_and_sew.rs @@ -51,7 +51,7 @@ fn get_sew_map(n_square: usize) -> CMap2 { #[bench::medium(&mut get_link_map(64))] #[bench::large(&mut get_link_map(256))] fn one_link(map: &mut CMap2) -> &mut CMap2 { - map.force_one_link(4, 6); + map.force_link::<1>(4, 6); black_box(map) } @@ -60,7 +60,7 @@ fn one_link(map: &mut CMap2) -> &mut CMap2 { #[bench::medium(&mut get_link_map(64))] #[bench::large(&mut get_link_map(256))] fn two_link(map: &mut CMap2) -> &mut CMap2 { - map.force_two_link(4, 6); + map.force_link::<2>(4, 6); black_box(map) } @@ -69,7 +69,7 @@ fn two_link(map: &mut CMap2) -> &mut CMap2 { #[bench::medium(&mut get_map(64))] #[bench::large(&mut get_map(256))] fn one_unlink(map: &mut CMap2) -> &mut CMap2 { - map.force_one_unlink(4); + map.force_unlink::<1>(4); black_box(map) } @@ -78,7 +78,7 @@ fn one_unlink(map: &mut CMap2) -> &mut CMap2 { #[bench::medium(&mut get_map(64))] #[bench::large(&mut get_map(256))] fn two_unlink(map: &mut CMap2) -> &mut CMap2 { - map.force_two_unlink(4); + map.force_unlink::<2>(4); black_box(map) } @@ -98,7 +98,7 @@ library_benchmark_group!( #[bench::medium(&mut get_sew_map(64))] #[bench::large(&mut get_sew_map(256))] fn one_sew(map: &mut CMap2) -> &mut CMap2 { - map.force_one_sew(4, 6); + map.force_sew::<1>(4, 6); black_box(map) } @@ -107,7 +107,7 @@ fn one_sew(map: &mut CMap2) -> &mut CMap2 { #[bench::medium(&mut get_sew_map(64))] #[bench::large(&mut get_sew_map(256))] fn two_sew(map: &mut CMap2) -> &mut CMap2 { - map.force_two_sew(4, 6); + map.force_sew::<2>(4, 6); black_box(map) } @@ -116,7 +116,7 @@ fn two_sew(map: &mut CMap2) -> &mut CMap2 { #[bench::medium(&mut get_map(64))] #[bench::large(&mut get_map(256))] fn one_unsew(map: &mut CMap2) -> &mut CMap2 { - map.force_one_unsew(4); + map.force_unsew::<1>(4); black_box(map) } @@ -125,7 +125,7 @@ fn one_unsew(map: &mut CMap2) -> &mut CMap2 { #[bench::medium(&mut get_map(64))] #[bench::large(&mut get_map(256))] fn two_unsew(map: &mut CMap2) -> &mut CMap2 { - map.force_two_unsew(4); + map.force_unsew::<2>(4); black_box(map) } diff --git a/examples/examples/io/write.rs b/examples/examples/io/write.rs index 6453c02b..9651807a 100644 --- a/examples/examples/io/write.rs +++ b/examples/examples/io/write.rs @@ -39,17 +39,17 @@ fn main() { // unsew the square & duplicate vertices to avoid data loss // this duplication effectively means that there are two existing vertices // for a short time, before being merged back by the sewing ops - map.force_one_unsew(d1); - map.force_one_unsew(d3); + map.force_unsew::<1>(d1); + map.force_unsew::<1>(d3); // link the two new dart in order to - map.force_two_link(dsplit1, dsplit2); + map.force_link::<2>(dsplit1, dsplit2); // define beta1 of the new darts, i.e. tell them where they point to - map.force_one_sew(dsplit1, d4); - map.force_one_sew(dsplit2, d2); + map.force_sew::<1>(dsplit1, d4); + map.force_sew::<1>(dsplit2, d2); // sew the original darts to the new darts - map.force_one_sew(d1, dsplit1); - map.force_one_sew(d3, dsplit2); + map.force_sew::<1>(d1, dsplit1); + map.force_sew::<1>(d3, dsplit2); // fuse the edges; this is where duplicated vertices are merged back together }); let elapsed = now.elapsed(); diff --git a/honeycomb-core/src/attributes/tests.rs b/honeycomb-core/src/attributes/tests.rs index 52e4c3c8..83ab1242 100644 --- a/honeycomb-core/src/attributes/tests.rs +++ b/honeycomb-core/src/attributes/tests.rs @@ -136,10 +136,10 @@ fn temperature_map() { .add_attribute::(); let map: CMap2 = builder.build().unwrap(); - map.force_two_link(1, 2); - map.force_two_link(3, 4); - map.force_two_link(5, 6); - map.force_one_link(1, 3); + map.force_link::<2>(1, 2); + map.force_link::<2>(3, 4); + map.force_link::<2>(5, 6); + map.force_link::<1>(1, 3); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); map.force_write_vertex(4, (1.5, 0.0)); @@ -161,7 +161,7 @@ fn temperature_map() { Some(Temperature::from(273.)) ); // sew one segment - map.force_one_sew(3, 5); + map.force_sew::<1>(3, 5); assert_eq!(map.vertex_id(4), map.vertex_id(5)); assert_eq!( map.force_read_attribute::(map.vertex_id(4)), @@ -172,7 +172,7 @@ fn temperature_map() { Some(Vertex2::from((2., 0.))) ); // unsew another - map.force_one_unsew(1); + map.force_unsew::<1>(1); assert_ne!(map.vertex_id(2), map.vertex_id(3)); assert_eq!( map.force_read_attribute::(map.vertex_id(2)), diff --git a/honeycomb-core/src/cmap/builder/io.rs b/honeycomb-core/src/cmap/builder/io.rs index 5c472318..dd459a7a 100644 --- a/honeycomb-core/src/cmap/builder/io.rs +++ b/honeycomb-core/src/cmap/builder/io.rs @@ -205,10 +205,10 @@ pub fn build_2d_from_vtk( d2 as VertexIdType, vertices[vids[2]], ); - cmap.force_one_link(d0, d1); // edge d0 links vertices vids[0] & vids[1] - cmap.force_one_link(d1, d2); // edge d1 links vertices vids[1] & vids[2] - cmap.force_one_link(d2, d0); // edge d2 links vertices vids[2] & vids[0] - // record a trace of the built cell for future 2-sew + cmap.force_link::<1>(d0, d1); // edge d0 links vertices vids[0] & vids[1] + cmap.force_link::<1>(d1, d2); // edge d1 links vertices vids[1] & vids[2] + cmap.force_link::<1>(d2, d0); // edge d2 links vertices vids[2] & vids[0] + // record a trace of the built cell for future 2-sew sew_buffer.insert((vids[0], vids[1]), d0); sew_buffer.insert((vids[1], vids[2]), d1); sew_buffer.insert((vids[2], vids[0]), d2); @@ -230,7 +230,7 @@ pub fn build_2d_from_vtk( di as VertexIdType, vertices[vids[i]], ); - cmap.force_one_link(di, dip1); + cmap.force_link::<1>(di, dip1); sew_buffer .insert((vids[i], vids[(i + 1) % n_vertices]), di); }); @@ -265,11 +265,11 @@ pub fn build_2d_from_vtk( d3 as VertexIdType, vertices[vids[3]], ); - cmap.force_one_link(d0, d1); // edge d0 links vertices vids[0] & vids[1] - cmap.force_one_link(d1, d2); // edge d1 links vertices vids[1] & vids[2] - cmap.force_one_link(d2, d3); // edge d2 links vertices vids[2] & vids[3] - cmap.force_one_link(d3, d0); // edge d3 links vertices vids[3] & vids[0] - // record a trace of the built cell for future 2-sew + cmap.force_link::<1>(d0, d1); // edge d0 links vertices vids[0] & vids[1] + cmap.force_link::<1>(d1, d2); // edge d1 links vertices vids[1] & vids[2] + cmap.force_link::<1>(d2, d3); // edge d2 links vertices vids[2] & vids[3] + cmap.force_link::<1>(d3, d0); // edge d3 links vertices vids[3] & vids[0] + // record a trace of the built cell for future 2-sew sew_buffer.insert((vids[0], vids[1]), d0); sew_buffer.insert((vids[1], vids[2]), d1); sew_buffer.insert((vids[2], vids[3]), d2); @@ -298,7 +298,7 @@ pub fn build_2d_from_vtk( } while let Some(((id0, id1), dart_id0)) = sew_buffer.pop_first() { if let Some(dart_id1) = sew_buffer.remove(&(id1, id0)) { - cmap.force_two_sew(dart_id0, dart_id1); + cmap.force_sew::<2>(dart_id0, dart_id1); } } Ok(cmap) diff --git a/honeycomb-core/src/cmap/dim2/links/mod.rs b/honeycomb-core/src/cmap/dim2/links/mod.rs index 012d6ca4..cd7ad565 100644 --- a/honeycomb-core/src/cmap/dim2/links/mod.rs +++ b/honeycomb-core/src/cmap/dim2/links/mod.rs @@ -1,2 +1,151 @@ mod one; mod two; + +use stm::{StmResult, Transaction}; + +use crate::{ + cmap::{CMap2, DartIdType}, + prelude::CoordsFloat, +}; + +/// # **Link operations** +impl CMap2 { + /// # `I`-link operator. + /// + /// This operation corresponds to coherently linking two darts via their *β* images. Unlike + /// sewing, this does not affect associated attributes. + /// + /// For a thorough explanation of this operation, its hypothesis & consequences, refer + /// to the [user guide][UG]. + /// + /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html + /// + /// # Arguments + /// + /// - `const I: u8` -- Sew dimension. + /// - `trans: &mut Transaction` -- Transaction associated to the operation. + /// - `ld: DartIdType` -- First dart ID. + /// - `rd: DartIdType` -- Second dart ID. + /// + /// # Errors + /// + /// This method should be called in a transactional context. The `Result` is then used to + /// validate the transaction; It should not be processed manually. The policy in case of + /// failure can be defined when creating the transaction, using `Transaction::with_control`. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0`, + /// - the two darts are not I-linkable. + pub fn link( + &self, + trans: &mut Transaction, + ld: DartIdType, + rd: DartIdType, + ) -> StmResult<()> { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.one_link(trans, ld, rd), + 2 => self.two_link(trans, ld, rd), + _ => unreachable!(), + } + } + + /// # `I`-unlink operator. + /// + /// This operation corresponds to unlinking two darts by resetting their *β* images. Unlike + /// linking, this does not affect associated attributes. + /// + /// For a thorough explanation of this operation, its hypothesis & consequences, refer + /// to the [user guide][UG]. + /// + /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html + /// + /// # Arguments + /// + /// - `const I: u8` -- Unsew dimension. + /// - `trans: &mut Transaction` -- Transaction associated to the operation. + /// - `ld: DartIdType` -- First dart ID. + /// + /// The second dart ID is fetched using `I` and `ld`. + /// + /// # Errors + /// + /// This method should be called in a transactional context. The `Result` is then used to + /// validate the transaction; It should not be processed manually. The policy in case of + /// failure can be defined when creating the transaction, using `Transaction::with_control`. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0` + /// - `ld` is already `I`-free, + pub fn unlink(&self, trans: &mut Transaction, ld: DartIdType) -> StmResult<()> { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.one_unlink(trans, ld), + 2 => self.two_unlink(trans, ld), + _ => unreachable!(), + } + } + + /// # `I`-link operator. + /// + /// This variant is equivalent to `sew`, but internally uses a transaction that will + /// be retried until validated. + /// + /// # Arguments + /// + /// - `const I: u8` -- Sew dimension. + /// - `ld: DartIdType` -- First dart ID. + /// - `rd: DartIdType` -- Second dart ID. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0`, + /// - the two darts are not I-linkable. + pub fn force_link(&self, ld: DartIdType, rd: DartIdType) { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.force_one_link(ld, rd), + 2 => self.force_two_link(ld, rd), + _ => unreachable!(), + } + } + + /// # `I`-unlink operator. + /// + /// This variant is equivalent to `sew`, but internally uses a transaction that will + /// be retried until validated. + /// + /// # Arguments + /// + /// - `const I: u8` -- Unsew dimension. + /// - `ld: DartIdType` -- First dart ID. + /// + /// The second dart ID is fetched using `I` and `ld`. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0` + /// - `ld` is already `I`-free, + pub fn force_unlink(&self, ld: DartIdType) { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.force_one_unlink(ld), + 2 => self.force_two_unlink(ld), + _ => unreachable!(), + } + } +} diff --git a/honeycomb-core/src/cmap/dim2/links/one.rs b/honeycomb-core/src/cmap/dim2/links/one.rs index 3c720e97..fa8d108f 100644 --- a/honeycomb-core/src/cmap/dim2/links/one.rs +++ b/honeycomb-core/src/cmap/dim2/links/one.rs @@ -1,5 +1,3 @@ -//! 1D link implementations - use stm::{atomically, StmResult, Transaction}; use crate::{ @@ -7,28 +5,11 @@ use crate::{ prelude::CoordsFloat, }; +#[doc(hidden)] /// 1-links impl CMap2 { - /// 1-link operation. - /// - /// This operation corresponds to linking two darts via the *β1* function. Unlike - /// its sewing counterpart, this method does not contain any code to update the attributes or - /// geometrical data of the affected cell(s). The *β0* function is also updated. - /// - /// # Arguments - /// - /// - `lhs_dart_id: DartIdentifier` -- ID of the first dart to be linked. - /// - `rhs_dart_id: DartIdentifier` -- ID of the second dart to be linked. - /// - /// # Errors - /// - /// This method is meant to be called in a context where the returned `Result` is used to - /// validate the transaction passed as argument. The result should not be processed manually. - /// - /// # Panics - /// - /// This method may panic if `lhs_dart_id` isn't 1-free or `rhs_dart_id` isn't 0-free. - pub fn one_link( + /// 1-link implementation. + pub(super) fn one_link( &self, trans: &mut Transaction, lhs_dart_id: DartIdType, @@ -37,55 +18,26 @@ impl CMap2 { self.betas.one_link_core(trans, lhs_dart_id, rhs_dart_id) } - /// 1-link operation. - /// - /// This variant is equivalent to `one_link`, but internally uses a transaction that will be - /// retried until validated. - pub fn force_one_link(&self, lhs_dart_id: DartIdType, rhs_dart_id: DartIdType) { + /// 1-link defensive implementation. + pub(super) fn force_one_link(&self, lhs_dart_id: DartIdType, rhs_dart_id: DartIdType) { atomically(|trans| self.betas.one_link_core(trans, lhs_dart_id, rhs_dart_id)); } } +#[doc(hidden)] /// 1-unlinks impl CMap2 { - /// 1-unlink operation. - /// - /// This operation corresponds to unlinking two darts that are linked via the *β1* - /// function. Unlike its sewing counterpart, this method does not contain any code to update - /// the attributes or geometrical data of the affected cell(s). The *β0* function is - /// also updated. - /// - /// # Arguments - /// - /// - `lhs_dart_id: DartIdentifier` -- ID of the dart to unlink. - /// - /// # Errors - /// - /// This method is meant to be called in a context where the returned `Result` is used to - /// validate the transaction passed as argument. The result should not be processed manually. - /// - /// # Panics - /// - /// This method may panic if one of `lhs_dart_id` is already 1-free. - pub fn one_unlink(&self, trans: &mut Transaction, lhs_dart_id: DartIdType) -> StmResult<()> { + /// 1-unlink implementation. + pub(super) fn one_unlink( + &self, + trans: &mut Transaction, + lhs_dart_id: DartIdType, + ) -> StmResult<()> { self.betas.one_unlink_core(trans, lhs_dart_id) } - /// 1-unlink operation. - /// - /// This operation corresponds to unlinking two darts that are linked via the *β1* - /// function. Unlike its sewing counterpart, this method does not contain any code to update - /// the attributes or geometrical data of the affected cell(s). The *β0* function is - /// also updated. - /// - /// # Arguments - /// - /// - `lhs_dart_id: DartIdentifier` -- ID of the dart to unlink. - /// - /// # Panics - /// - /// This method may panic if one of `lhs_dart_id` is already 1-free. - pub fn force_one_unlink(&self, lhs_dart_id: DartIdType) { + /// 1-unlink defensive implementation. + pub(super) fn force_one_unlink(&self, lhs_dart_id: DartIdType) { atomically(|trans| self.betas.one_unlink_core(trans, lhs_dart_id)); } } diff --git a/honeycomb-core/src/cmap/dim2/links/two.rs b/honeycomb-core/src/cmap/dim2/links/two.rs index 33975498..88b7b84d 100644 --- a/honeycomb-core/src/cmap/dim2/links/two.rs +++ b/honeycomb-core/src/cmap/dim2/links/two.rs @@ -1,5 +1,3 @@ -//! 2D link implementations - use stm::{atomically, StmResult, Transaction}; use crate::{ @@ -7,28 +5,11 @@ use crate::{ prelude::CoordsFloat, }; +#[doc(hidden)] /// 2-links impl CMap2 { - /// 2-link operation. - /// - /// This operation corresponds to linking two darts via the *β2* function. Unlike - /// its sewing counterpart, this method does not contain any code to update the attributes or - /// geometrical data of the affected cell(s). - /// - /// # Arguments - /// - /// - `lhs_dart_id: DartIdentifier` -- ID of the first dart to be linked. - /// - `rhs_dart_id: DartIdentifier` -- ID of the second dart to be linked. - /// - /// # Errors - /// - /// This method is meant to be called in a context where the returned `Result` is used to - /// validate the transaction passed as argument. The result should not be processed manually. - /// - /// # Panics - /// - /// This method may panic if one of `lhs_dart_id` or `rhs_dart_id` isn't 2-free. - pub fn two_link( + /// 2-link implementation. + pub(super) fn two_link( &self, trans: &mut Transaction, lhs_dart_id: DartIdType, @@ -37,44 +18,26 @@ impl CMap2 { self.betas.two_link_core(trans, lhs_dart_id, rhs_dart_id) } - /// 2-link operation. - /// - /// This variant is equivalent to `two_link`, but internally uses a transaction that will be - /// retried until validated. - pub fn force_two_link(&self, lhs_dart_id: DartIdType, rhs_dart_id: DartIdType) { + /// 2-link defensive implementation. + pub(super) fn force_two_link(&self, lhs_dart_id: DartIdType, rhs_dart_id: DartIdType) { atomically(|trans| self.betas.two_link_core(trans, lhs_dart_id, rhs_dart_id)); } } +#[doc(hidden)] /// 2-unlinks impl CMap2 { - /// 2-unlink operation. - /// - /// This operation corresponds to unlinking two darts that are linked via the *β2* - /// function. Unlike its sewing counterpart, this method does not contain any code to update - /// the attributes or geometrical data of the affected cell(s). - /// - /// # Arguments - /// - /// - `lhs_dart_id: DartIdentifier` -- ID of the dart to unlink. - /// - /// # Errors - /// - /// This method is meant to be called in a context where the returned `Result` is used to - /// validate the transaction passed as argument. The result should not be processed manually. - /// - /// # Panics - /// - /// This method may panic if one of `lhs_dart_id` is already 2-free. - pub fn two_unlink(&self, trans: &mut Transaction, lhs_dart_id: DartIdType) -> StmResult<()> { + /// 2-unlink implementation. + pub(super) fn two_unlink( + &self, + trans: &mut Transaction, + lhs_dart_id: DartIdType, + ) -> StmResult<()> { self.betas.two_unlink_core(trans, lhs_dart_id) } - /// 2-unlink operation. - /// - /// This variant is equivalent to `two_unlink`, but internally uses a transaction that will - /// be retried until validated. - pub fn force_two_unlink(&self, lhs_dart_id: DartIdType) { + /// 2-unlink defensive implementation. + pub(super) fn force_two_unlink(&self, lhs_dart_id: DartIdType) { atomically(|trans| self.betas.two_unlink_core(trans, lhs_dart_id)); } } diff --git a/honeycomb-core/src/cmap/dim2/orbits.rs b/honeycomb-core/src/cmap/dim2/orbits.rs index 133ddcd1..ccfc611e 100644 --- a/honeycomb-core/src/cmap/dim2/orbits.rs +++ b/honeycomb-core/src/cmap/dim2/orbits.rs @@ -192,23 +192,23 @@ mod tests { fn simple_map() -> CMap2 { let mut map: CMap2 = CMap2::new(11); // tri1 - map.force_one_link(1, 2); - map.force_one_link(2, 3); - map.force_one_link(3, 1); + map.force_link::<1>(1, 2); + map.force_link::<1>(2, 3); + map.force_link::<1>(3, 1); // tri2 - map.force_one_link(4, 5); - map.force_one_link(5, 6); - map.force_one_link(6, 4); + map.force_link::<1>(4, 5); + map.force_link::<1>(5, 6); + map.force_link::<1>(6, 4); // pent on top - map.force_one_link(7, 8); - map.force_one_link(8, 9); - map.force_one_link(9, 10); - map.force_one_link(10, 11); - map.force_one_link(11, 7); + map.force_link::<1>(7, 8); + map.force_link::<1>(8, 9); + map.force_link::<1>(9, 10); + map.force_link::<1>(10, 11); + map.force_link::<1>(11, 7); // link all - map.force_two_link(2, 4); - map.force_two_link(6, 7); + map.force_link::<2>(2, 4); + map.force_link::<2>(6, 7); assert!(map.force_write_vertex(1, (0.0, 0.0)).is_none()); assert!(map.force_write_vertex(2, (1.0, 0.0)).is_none()); diff --git a/honeycomb-core/src/cmap/dim2/sews/mod.rs b/honeycomb-core/src/cmap/dim2/sews/mod.rs index 012d6ca4..54f8959b 100644 --- a/honeycomb-core/src/cmap/dim2/sews/mod.rs +++ b/honeycomb-core/src/cmap/dim2/sews/mod.rs @@ -1,2 +1,242 @@ mod one; mod two; + +use stm::{StmResult, Transaction}; + +use crate::{ + cmap::{CMap2, CMapResult, DartIdType}, + prelude::CoordsFloat, +}; + +/// # **Sew implementations** +impl CMap2 { + /// # `I`-sew operator. + /// + /// This operation corresponds to: + /// - coherently linking two darts via their *β* images, + /// - merging the attributes associated to their respective original `I`-cells. + /// + /// For a thorough explanation of this operation, its hypothesis & consequences, refer + /// to the [user guide][UG]. + /// + /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html + /// + /// # Arguments + /// + /// - `const I: u8` -- Sew dimension. + /// - `trans: &mut Transaction` -- Transaction associated to the operation. + /// - `ld: DartIdType` -- First dart ID. + /// - `rd: DartIdType` -- Second dart ID. + /// + /// # Errors + /// + /// This method should be called in a transactional context. The `Result` is then used to + /// validate the transaction; It should not be processed manually. The policy in case of + /// failure can be defined when creating the transaction, using `Transaction::with_control`. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0` + /// - the two darts are not I-sewable, + /// - for `I == 2`: orientation is inconsistent. + pub fn sew( + &self, + trans: &mut Transaction, + ld: DartIdType, + rd: DartIdType, + ) -> StmResult<()> { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.one_sew(trans, ld, rd), + 2 => self.two_sew(trans, ld, rd), + _ => unreachable!(), + } + } + + /// # `I`-unsew operator. + /// + /// This operation corresponds to: + /// - unlinking two darts by resetting their *β* images, + /// - splitting the attributes associated to the original `I`-cell. + /// + /// For a thorough explanation of this operation, its hypothesis & consequences, refer + /// to the [user guide][UG]. + /// + /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html + /// + /// # Arguments + /// + /// - `const I: u8` -- Unsew dimension. + /// - `trans: &mut Transaction` -- Transaction associated to the operation. + /// - `ld: DartIdType` -- First dart ID. + /// + /// The second dart ID is fetched using `I` and `ld`. + /// + /// # Errors + /// + /// This method should be called in a transactional context. The `Result` is then used to + /// validate the transaction; It should not be processed manually. The policy in case of + /// failure can be defined when creating the transaction, using `Transaction::with_control`. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0` + /// - `ld` is already `I`-free, + pub fn unsew(&self, trans: &mut Transaction, ld: DartIdType) -> StmResult<()> { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.one_unsew(trans, ld), + 2 => self.two_unsew(trans, ld), + _ => unreachable!(), + } + } + + /// # `I`-sew operator. + /// + /// This variant is equivalent to `sew`, but internally uses a transaction that will + /// be retried until validated. + /// + /// # Arguments + /// + /// - `const I: u8` -- Sew dimension. + /// - `ld: DartIdType` -- First dart ID. + /// - `rd: DartIdType` -- Second dart ID. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0` + /// - the two darts are not I-sewable, + /// - for `I == 2`: orientation is inconsistent. + pub fn force_sew(&self, ld: DartIdType, rd: DartIdType) { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.force_one_sew(ld, rd), + 2 => self.force_two_sew(ld, rd), + _ => unreachable!(), + } + } + + /// # `I`-unsew operator. + /// + /// This variant is equivalent to `sew`, but internally uses a transaction that will + /// be retried until validated. + /// + /// # Arguments + /// + /// - `const I: u8` -- Unsew dimension. + /// - `ld: DartIdType` -- First dart ID. + /// + /// The second dart ID is fetched using `I` and `ld`. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0` + /// - `ld` is already `I`-free, + pub fn force_unsew(&self, ld: DartIdType) { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.force_one_unsew(ld), + 2 => self.force_two_unsew(ld), + _ => unreachable!(), + } + } + + /// # `I`-sew operator. + /// + /// This variant will abort the unsew operation and raise an error if attributes cannot be + /// merged correctly. + /// + /// # Arguments + /// + /// - `const I: u8` -- Sew dimension. + /// - `trans: &mut Transaction` -- Transaction associated to the operation. + /// - `ld: DartIdType` -- First dart ID. + /// - `rd: DartIdType` -- Second dart ID. + /// + /// # Errors + /// + /// This method will fail, returning an error, if: + /// - the transaction cannot be completed, + /// - one (or more) attribute merge fails, + /// - for `I == 2`: orientation is inconsistent. + /// + /// The returned error can be used in conjunction with transaction control to avoid any + /// modifications in case of failure at attribute level. The user can then choose, through its + /// transaction control policy, to retry or abort as he wishes. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0` + /// - the two darts are not I-sewable, + pub fn try_sew( + &self, + trans: &mut Transaction, + ld: DartIdType, + rd: DartIdType, + ) -> CMapResult<()> { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.try_one_sew(trans, ld, rd), + 2 => self.try_two_sew(trans, ld, rd), + _ => unreachable!(), + } + } + + /// # `I`-unsew operator. + /// + /// This variant will abort the unsew operation and raise an error if attributes cannot be + /// split correctly. + /// + /// # Arguments + /// + /// - `const I: u8` -- Unsew dimension. + /// - `trans: &mut Transaction` -- Transaction associated to the operation. + /// - `ld: DartIdType` -- First dart ID. + /// + /// The second dart ID is fetched using `I` and `ld`. + /// + /// # Errors + /// + /// This method will fail, returning an error, if: + /// - the transaction cannot be completed, + /// - one (or more) attribute split fails, + /// + /// The returned error can be used in conjunction with transaction control to avoid any + /// modifications in case of failure at attribute level. The user can then choose, through its + /// transaction control policy, to retry or abort as he wishes. + /// + /// # Panics + /// + /// The method may panic if: + /// - `I >= 3` or `I == 0` + /// - `ld` is already `I`-free, + pub fn try_unsew( + &self, + trans: &mut Transaction, + ld: DartIdType, + ) -> CMapResult<()> { + // these assertions + match on a const are optimized away + assert!(I < 3); + assert_ne!(I, 0); + match I { + 1 => self.try_one_unsew(trans, ld), + 2 => self.try_two_unsew(trans, ld), + _ => unreachable!(), + } + } +} diff --git a/honeycomb-core/src/cmap/dim2/sews/one.rs b/honeycomb-core/src/cmap/dim2/sews/one.rs index ed9316be..54562fe4 100644 --- a/honeycomb-core/src/cmap/dim2/sews/one.rs +++ b/honeycomb-core/src/cmap/dim2/sews/one.rs @@ -1,5 +1,3 @@ -//! 1D sew implementations - use stm::{atomically, StmResult, Transaction}; use crate::{ @@ -8,37 +6,11 @@ use crate::{ prelude::CoordsFloat, }; +#[doc(hidden)] /// 1-sews impl CMap2 { - /// 1-sew operation. - /// - /// This operation corresponds to *coherently linking* two darts via the *β1* - /// function. For a thorough explanation of this operation (and implied hypothesis & - /// consequences), refer to the [user guide][UG]. - /// - /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/ - /// - /// # Arguments - /// - /// - `lhs_dart_id: DartIdentifier` -- ID of the first dart to be linked. - /// - `rhs_dart_id: DartIdentifier` -- ID of the second dart to be linked. - /// - `policy: SewPolicy` -- Geometrical sewing policy to follow. - /// - /// After the sewing operation, these darts will verify - /// *β1(`lhs_dart`) = `rhs_dart`*. The *β0* function is also updated. - /// - /// # Errors - /// - /// This method is meant to be called in a context where the returned `Result` is used to - /// validate the transaction passed as argument. The result should not be processed manually. - /// - /// The policy in case of failure can be defined through the transaction, using - /// `Transaction::with_control` for construction. - /// - /// # Panics - /// - /// The method may panic if the two darts are not 1-sewable. - pub fn one_sew( + /// 1-sew transactional implementation. + pub(super) fn one_sew( &self, trans: &mut Transaction, lhs_dart_id: DartIdType, @@ -64,26 +36,13 @@ impl CMap2 { } } - /// 1-sew two darts. - /// - /// This variant is equivalent to `one_sew`, but internally uses a transaction that will be - /// retried until validated. - pub fn force_one_sew(&self, lhs_dart_id: DartIdType, rhs_dart_id: DartIdType) { + /// 1-sew implementation. + pub(super) fn force_one_sew(&self, lhs_dart_id: DartIdType, rhs_dart_id: DartIdType) { atomically(|trans| self.one_sew(trans, lhs_dart_id, rhs_dart_id)); } - /// Attempt to 1-sew two darts. - /// - /// # Errors - /// - /// This method will fail, returning an error, if: - /// - the transaction cannot be completed - /// - one (or more) attribute merge fails - /// - /// The returned error can be used in conjunction with transaction control to avoid any - /// modifications in case of failure at attribute level. The user can then choose, through its - /// transaction control policy, to retry or abort as he wishes. - pub fn try_one_sew( + /// 1-sew defensive implementation. + pub(super) fn try_one_sew( &self, trans: &mut Transaction, lhs_dart_id: DartIdType, @@ -114,38 +73,15 @@ impl CMap2 { } } +#[doc(hidden)] /// 1-unsews impl CMap2 { - /// 1-unsew operation. - /// - /// This operation corresponds to *coherently separating* two darts linked via the - /// *β1* function. For a thorough explanation of this operation (and implied - /// hypothesis & consequences), refer to the [user guide][UG]. - /// - /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/ - /// - /// # Arguments - /// - /// - `lhs_dart_id: DartIdentifier` -- ID of the dart to separate. - /// - `policy: UnsewPolicy` -- Geometrical unsewing policy to follow. - /// - /// Note that we do not need to take two darts as arguments since the second dart can be - /// obtained through the *β1* function. The *β0* function is also updated. - /// - /// # Errors - /// - /// This method is meant to be called in a context where the returned `Result` is used to - /// validate the transaction passed as argument. The result should not be processed manually. - /// - /// The policy in case of failure can be defined through the transaction, using - /// `Transaction::with_control` for construction. - /// - /// # Panics - /// - /// The method may panic if there's a missing attribute at the splitting step. While the - /// implementation could fall back to a simple unlink operation, it probably should have been - /// called by the user, instead of unsew, in the first place. - pub fn one_unsew(&self, trans: &mut Transaction, lhs_dart_id: DartIdType) -> StmResult<()> { + /// 1-unsew transactional implementation. + pub(super) fn one_unsew( + &self, + trans: &mut Transaction, + lhs_dart_id: DartIdType, + ) -> StmResult<()> { let b2lhs_dart_id = self.betas[(2, lhs_dart_id)].read(trans)?; if b2lhs_dart_id == NULL_DART_ID { self.betas.one_unlink_core(trans, lhs_dart_id)?; @@ -168,26 +104,13 @@ impl CMap2 { Ok(()) } - /// 1-unsew two darts. - /// - /// This variant is equivalent to `one_unsew`, but internally uses a transaction that will - /// be retried until validated. - pub fn force_one_unsew(&self, lhs_dart_id: DartIdType) { + /// 1-unsew implementation. + pub(super) fn force_one_unsew(&self, lhs_dart_id: DartIdType) { atomically(|trans| self.one_unsew(trans, lhs_dart_id)); } - /// Attempt to 1-unsew two darts. - /// - /// # Errors - /// - /// This method will fail, returning an error, if: - /// - the transaction cannot be completed - /// - one (or more) attribute merge fails - /// - /// The returned error can be used in conjunction with transaction control to avoid any - /// modifications in case of failure at attribute level. The user can then choose, through its - /// transaction control policy, to retry or abort as he wishes. - pub fn try_one_unsew( + /// 1-unsew defensive implementation. + pub(super) fn try_one_unsew( &self, trans: &mut Transaction, lhs_dart_id: DartIdType, diff --git a/honeycomb-core/src/cmap/dim2/sews/two.rs b/honeycomb-core/src/cmap/dim2/sews/two.rs index ceff0c91..29f03663 100644 --- a/honeycomb-core/src/cmap/dim2/sews/two.rs +++ b/honeycomb-core/src/cmap/dim2/sews/two.rs @@ -1,5 +1,3 @@ -//! 2D sew implementations - use stm::{atomically, StmResult, Transaction}; use crate::{ @@ -8,40 +6,12 @@ use crate::{ prelude::CoordsFloat, }; +#[doc(hidden)] /// 2-sews impl CMap2 { - /// 2-sew operation. - /// - /// This operation corresponds to *coherently linking* two darts via the *β2* - /// function. For a thorough explanation of this operation (and implied hypothesis & - /// consequences), refer to the [user guide][UG]. - /// - /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/ - /// - /// # Arguments - /// - /// - `lhs_dart_id: DartIdentifier` -- ID of the first dart to be linked. - /// - `rhs_dart_id: DartIdentifier` -- ID of the second dart to be linked. - /// - `policy: SewPolicy` -- Geometrical sewing policy to follow. - /// - /// After the sewing operation, these darts will verify - /// *β2(`lhs_dart`) = `rhs_dart`* and *β2(`rhs_dart`) = `lhs_dart`*. - /// - /// # Errors - /// - /// This method is meant to be called in a context where the returned `Result` is used to - /// validate the transaction passed as argument. The result should not be processed manually. - /// - /// The policy in case of failure can be defined through the transaction, using - /// `Transaction::with_control` for construction. - /// - /// # Panics - /// - /// The method may panic if: - /// - the two darts are not 2-sewable, - /// - the method cannot resolve orientation issues. + /// 2-sew transactional implementation. #[allow(clippy::too_many_lines)] - pub fn two_sew( + pub(super) fn two_sew( &self, trans: &mut Transaction, lhs_dart_id: DartIdType, @@ -164,27 +134,14 @@ impl CMap2 { Ok(()) } - /// 2-sew two darts. - /// - /// This variant is equivalent to `two_sew`, but internally uses a transaction that will be - /// retried until validated. - pub fn force_two_sew(&self, lhs_dart_id: DartIdType, rhs_dart_id: DartIdType) { + /// 2-sew implementation. + pub(super) fn force_two_sew(&self, lhs_dart_id: DartIdType, rhs_dart_id: DartIdType) { atomically(|trans| self.two_sew(trans, lhs_dart_id, rhs_dart_id)); } - /// Attempt to 2-sew two darts. - /// - /// # Errors - /// - /// This method will fail, returning an error, if: - /// - the transaction cannot be completed - /// - one (or more) attribute merge fails - /// - /// The returned error can be used in conjunction with transaction control to avoid any - /// modifications in case of failure at attribute level. The user can then choose, through its - /// transaction control policy, to retry or abort as he wishes. + /// 2-sew defensive implementation. #[allow(clippy::too_many_lines, clippy::missing_panics_doc)] - pub fn try_two_sew( + pub(super) fn try_two_sew( &self, trans: &mut Transaction, lhs_dart_id: DartIdType, @@ -320,38 +277,15 @@ impl CMap2 { } } +#[doc(hidden)] /// 2-unsews impl CMap2 { - /// 2-unsew operation. - /// - /// This operation corresponds to *coherently separating* two darts linked via the - /// *β2* function. For a thorough explanation of this operation (and implied - /// hypothesis & consequences), refer to the [user guide][UG]. - /// - /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/ - /// - /// # Arguments - /// - /// - `lhs_dart_id: DartIdentifier` -- ID of the dart to separate. - /// - `policy: UnsewPolicy` -- Geometrical unsewing policy to follow. - /// - /// Note that we do not need to take two darts as arguments since the second dart can be - /// obtained through the *β2* function. - /// - /// # Errors - /// - /// This method is meant to be called in a context where the returned `Result` is used to - /// validate the transaction passed as argument. The result should not be processed manually. - /// - /// The policy in case of failure can be defined through the transaction, using - /// `Transaction::with_control` for construction. - /// - /// # Panics - /// - /// The method may panic if there's a missing attribute at the splitting step. While the - /// implementation could fall back to a simple unlink operation, it probably should have been - /// called by the user, instead of unsew, in the first place. - pub fn two_unsew(&self, trans: &mut Transaction, lhs_dart_id: DartIdType) -> StmResult<()> { + /// 2-unsew transactional implementation. + pub(super) fn two_unsew( + &self, + trans: &mut Transaction, + lhs_dart_id: DartIdType, + ) -> StmResult<()> { let rhs_dart_id = self.betas[(2, lhs_dart_id)].read(trans)?; let b1lhs_dart_id = self.betas[(1, lhs_dart_id)].read(trans)?; let b1rhs_dart_id = self.betas[(1, rhs_dart_id)].read(trans)?; @@ -442,26 +376,13 @@ impl CMap2 { Ok(()) } - /// 2-unsew two darts. - /// - /// This variant is equivalent to `two_unsew`, but internally uses a transaction that will - /// be retried until validated. - pub fn force_two_unsew(&self, lhs_dart_id: DartIdType) { + /// 2-unsew implementation. + pub(super) fn force_two_unsew(&self, lhs_dart_id: DartIdType) { atomically(|trans| self.two_unsew(trans, lhs_dart_id)); } - /// Attempt to 2-unsew two darts. - /// - /// # Errors - /// - /// This method will fail, returning an error, if: - /// - the transaction cannot be completed - /// - one (or more) attribute merge fails - /// - /// The returned error can be used in conjunction with transaction control to avoid any - /// modifications in case of failure at attribute level. The user can then choose, through its - /// transaction control policy, to retry or abort as he wishes. - pub fn try_two_unsew( + /// 2-unsew defensive implementation. + pub(super) fn try_two_unsew( &self, trans: &mut Transaction, lhs_dart_id: DartIdType, diff --git a/honeycomb-core/src/cmap/dim2/structure.rs b/honeycomb-core/src/cmap/dim2/structure.rs index 4969ace4..a229357a 100644 --- a/honeycomb-core/src/cmap/dim2/structure.rs +++ b/honeycomb-core/src/cmap/dim2/structure.rs @@ -72,9 +72,9 @@ use crate::{ /// /// // build a triangle /// let mut map: CMap2 = CMapBuilder::default().n_darts(3).build().unwrap(); // three darts -/// map.force_one_link(1, 2); // beta1(1) = 2 & beta0(2) = 1 -/// map.force_one_link(2, 3); // beta1(2) = 3 & beta0(3) = 2 -/// map.force_one_link(3, 1); // beta1(3) = 1 & beta0(1) = 3 +/// map.force_link::<1>(1, 2); // beta1(1) = 2 & beta0(2) = 1 +/// map.force_link::<1>(2, 3); // beta1(2) = 3 & beta0(3) = 2 +/// map.force_link::<1>(3, 1); // beta1(3) = 1 & beta0(1) = 3 /// map.force_write_vertex(1, (0.0, 0.0)); /// map.force_write_vertex(2, (1.0, 0.0)); /// map.force_write_vertex(3, (0.0, 1.0)); @@ -89,9 +89,9 @@ use crate::{ /// // build a second triangle /// let first_added_dart_id = map.add_free_darts(3); /// assert_eq!(first_added_dart_id, 4); -/// map.force_one_link(4, 5); -/// map.force_one_link(5, 6); -/// map.force_one_link(6, 4); +/// map.force_link::<1>(4, 5); +/// map.force_link::<1>(5, 6); +/// map.force_link::<1>(6, 4); /// map.force_write_vertex(4, (0.0, 2.0)); /// map.force_write_vertex(5, (2.0, 0.0)); /// map.force_write_vertex(6, (1.0, 1.0)); @@ -101,7 +101,7 @@ use crate::{ /// assert_eq!(&faces, &[1, 4]); /// /// // sew both triangles -/// map.force_two_sew(2, 4); +/// map.force_sew::<2>(2, 4); /// /// // there are 5 edges now, making up a square & its diagonal /// let edges: Vec<_> = map.iter_edges().collect(); @@ -119,17 +119,17 @@ use crate::{ /// ); /// /// // separate the diagonal from the rest -/// map.force_one_unsew(1); -/// map.force_one_unsew(2); -/// map.force_one_unsew(6); -/// map.force_one_unsew(4); +/// map.force_unsew::<1>(1); +/// map.force_unsew::<1>(2); +/// map.force_unsew::<1>(6); +/// map.force_unsew::<1>(4); /// // break up & remove the diagonal -/// map.force_two_unsew(2); // this makes dart 2 and 4 free +/// map.force_unsew::<2>(2); // this makes dart 2 and 4 free /// map.remove_free_dart(2); /// map.remove_free_dart(4); /// // sew the square back up -/// map.force_one_sew(1, 5); -/// map.force_one_sew(6, 3); +/// map.force_sew::<1>(1, 5); +/// map.force_sew::<1>(6, 3); /// /// // there's only the square face left /// let faces: Vec<_> = map.iter_faces().collect(); diff --git a/honeycomb-core/src/cmap/dim2/tests.rs b/honeycomb-core/src/cmap/dim2/tests.rs index 31fd44ef..2eeebabf 100644 --- a/honeycomb-core/src/cmap/dim2/tests.rs +++ b/honeycomb-core/src/cmap/dim2/tests.rs @@ -14,9 +14,9 @@ use crate::{ fn example_test() { // build a triangle let mut map: CMap2 = CMapBuilder::default().n_darts(3).build().unwrap(); - map.force_one_link(1, 2); - map.force_one_link(2, 3); - map.force_one_link(3, 1); + map.force_link::<1>(1, 2); + map.force_link::<1>(2, 3); + map.force_link::<1>(3, 1); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); map.force_write_vertex(3, (0.0, 1.0)); @@ -33,9 +33,9 @@ fn example_test() { // build a second triangle map.add_free_darts(3); - map.force_one_link(4, 5); - map.force_one_link(5, 6); - map.force_one_link(6, 4); + map.force_link::<1>(4, 5); + map.force_link::<1>(5, 6); + map.force_link::<1>(6, 4); map.force_write_vertex(4, (0.0, 2.0)); map.force_write_vertex(5, (2.0, 0.0)); map.force_write_vertex(6, (1.0, 1.0)); @@ -50,7 +50,7 @@ fn example_test() { assert_eq!(face.next(), None); // sew both triangles - map.force_two_sew(2, 4); + map.force_sew::<2>(2, 4); // checks assert_eq!(map.beta::<2>(2), 4); @@ -76,17 +76,17 @@ fn example_test() { assert_eq!(map.force_read_vertex(3).unwrap(), Vertex2::from((0.0, 1.0))); // separate the diagonal from the rest - map.force_one_unsew(1); - map.force_one_unsew(2); - map.force_one_unsew(6); - map.force_one_unsew(4); + map.force_unsew::<1>(1); + map.force_unsew::<1>(2); + map.force_unsew::<1>(6); + map.force_unsew::<1>(4); // break up & remove the diagonal - map.force_two_unsew(2); // this makes dart 2 and 4 free + map.force_unsew::<2>(2); // this makes dart 2 and 4 free map.remove_free_dart(2); map.remove_free_dart(4); // sew the square back up - map.force_one_sew(1, 5); - map.force_one_sew(6, 3); + map.force_sew::<1>(1, 5); + map.force_sew::<1>(6, 3); // i-cells let faces: Vec<_> = map.iter_faces().collect(); @@ -135,13 +135,13 @@ fn remove_dart_twice() { #[test] fn two_sew_complete() { let mut map: CMap2 = CMap2::new(4); - map.force_one_link(1, 2); - map.force_one_link(3, 4); + map.force_link::<1>(1, 2); + map.force_link::<1>(3, 4); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (0.0, 1.0)); map.force_write_vertex(3, (1.0, 1.0)); map.force_write_vertex(4, (1.0, 0.0)); - map.force_two_sew(1, 3); + map.force_sew::<2>(1, 3); assert_eq!(map.force_read_vertex(1).unwrap(), Vertex2::from((0.5, 0.0))); assert_eq!(map.force_read_vertex(2).unwrap(), Vertex2::from((0.5, 1.0))); } @@ -149,18 +149,18 @@ fn two_sew_complete() { #[test] fn two_sew_incomplete() { let mut map: CMap2 = CMap2::new(3); - map.force_one_link(1, 2); + map.force_link::<1>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (0.0, 1.0)); map.force_write_vertex(3, (1.0, 1.0)); - map.force_two_sew(1, 3); + map.force_sew::<2>(1, 3); // missing beta1 image for dart 3 assert_eq!(map.force_read_vertex(1).unwrap(), Vertex2::from((0.0, 0.0))); assert_eq!(map.force_read_vertex(2).unwrap(), Vertex2::from((0.5, 1.0))); - map.force_two_unsew(1); + map.force_unsew::<2>(1); assert_eq!(map.add_free_dart(), 4); - map.force_one_link(3, 4); - map.force_two_sew(1, 3); + map.force_link::<1>(3, 4); + map.force_sew::<2>(1, 3); // missing vertex for dart 4 assert_eq!(map.force_read_vertex(1).unwrap(), Vertex2::from((0.0, 0.0))); assert_eq!(map.force_read_vertex(2).unwrap(), Vertex2::from((0.5, 1.0))); @@ -171,7 +171,7 @@ fn two_sew_no_b1() { let mut map: CMap2 = CMap2::new(2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 1.0)); - map.force_two_sew(1, 2); + map.force_sew::<2>(1, 2); assert_eq!(map.force_read_vertex(1).unwrap(), Vertex2::from((0.0, 0.0))); assert_eq!(map.force_read_vertex(2).unwrap(), Vertex2::from((1.0, 1.0))); } @@ -180,49 +180,49 @@ fn two_sew_no_b1() { // #[should_panic] // FIXME: find a way to test what's printed? fn two_sew_no_attributes() { let mut map: CMap2 = CMap2::new(2); - map.force_two_sew(1, 2); // should panic + map.force_sew::<2>(1, 2); // should panic } #[test] // #[should_panic] // FIXME: find a way to test what's printed? fn two_sew_no_attributes_bis() { let mut map: CMap2 = CMap2::new(4); - map.force_one_link(1, 2); - map.force_one_link(3, 4); - map.force_two_sew(1, 3); // panic + map.force_link::<1>(1, 2); + map.force_link::<1>(3, 4); + map.force_sew::<2>(1, 3); // panic } #[test] #[should_panic(expected = "Dart 1 and 3 do not have consistent orientation for 2-sewing")] fn two_sew_bad_orientation() { let mut map: CMap2 = CMap2::new(4); - map.force_one_link(1, 2); - map.force_one_link(3, 4); + map.force_link::<1>(1, 2); + map.force_link::<1>(3, 4); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (0.0, 1.0)); // 1->2 goes up map.force_write_vertex(3, (1.0, 0.0)); map.force_write_vertex(4, (1.0, 1.0)); // 3->4 also goes up - map.force_two_sew(1, 3); // panic + map.force_sew::<2>(1, 3); // panic } #[test] fn one_sew_complete() { let mut map: CMap2 = CMap2::new(3); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (0.0, 1.0)); map.force_write_vertex(3, (0.0, 2.0)); - map.force_one_sew(1, 3); + map.force_sew::<1>(1, 3); assert_eq!(map.force_read_vertex(2).unwrap(), Vertex2::from((0.0, 1.5))); } #[test] fn one_sew_incomplete_attributes() { let mut map: CMap2 = CMap2::new(3); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (0.0, 1.0)); - map.force_one_sew(1, 3); + map.force_sew::<1>(1, 3); assert_eq!(map.force_read_vertex(2).unwrap(), Vertex2::from((0.0, 1.0))); } @@ -231,22 +231,22 @@ fn one_sew_incomplete_beta() { let mut map: CMap2 = CMap2::new(3); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (0.0, 1.0)); - map.force_one_sew(1, 2); + map.force_sew::<1>(1, 2); assert_eq!(map.force_read_vertex(2).unwrap(), Vertex2::from((0.0, 1.0))); } #[test] // #[should_panic] // FIXME: find a way to test what's printed? fn one_sew_no_attributes() { let mut map: CMap2 = CMap2::new(2); - map.force_one_sew(1, 2); // should panic + map.force_sew::<1>(1, 2); // should panic } #[test] // #[should_panic] // FIXME: find a way to test what's printed? fn one_sew_no_attributes_bis() { let mut map: CMap2 = CMap2::new(3); - map.force_two_link(1, 2); - map.force_one_sew(1, 3); // panic + map.force_link::<2>(1, 2); + map.force_sew::<1>(1, 3); // panic } // --- IO @@ -268,29 +268,29 @@ fn io_write() { // 1---2---6 let mut cmap: CMap2 = CMap2::new(16); // bottom left square - cmap.force_one_link(1, 2); - cmap.force_one_link(2, 3); - cmap.force_one_link(3, 4); - cmap.force_one_link(4, 1); + cmap.force_link::<1>(1, 2); + cmap.force_link::<1>(2, 3); + cmap.force_link::<1>(3, 4); + cmap.force_link::<1>(4, 1); // bottom right triangles - cmap.force_one_link(5, 6); - cmap.force_one_link(6, 7); - cmap.force_one_link(7, 5); - cmap.force_two_link(7, 8); - cmap.force_one_link(8, 9); - cmap.force_one_link(9, 10); - cmap.force_one_link(10, 8); + cmap.force_link::<1>(5, 6); + cmap.force_link::<1>(6, 7); + cmap.force_link::<1>(7, 5); + cmap.force_link::<2>(7, 8); + cmap.force_link::<1>(8, 9); + cmap.force_link::<1>(9, 10); + cmap.force_link::<1>(10, 8); // top polygon - cmap.force_one_link(11, 12); - cmap.force_one_link(12, 13); - cmap.force_one_link(13, 14); - cmap.force_one_link(14, 15); - cmap.force_one_link(15, 16); - cmap.force_one_link(16, 11); + cmap.force_link::<1>(11, 12); + cmap.force_link::<1>(12, 13); + cmap.force_link::<1>(13, 14); + cmap.force_link::<1>(14, 15); + cmap.force_link::<1>(15, 16); + cmap.force_link::<1>(16, 11); // assemble - cmap.force_two_link(2, 10); - cmap.force_two_link(3, 11); - cmap.force_two_link(9, 12); + cmap.force_link::<2>(2, 10); + cmap.force_link::<2>(3, 11); + cmap.force_link::<2>(9, 12); // insert vertices cmap.force_write_vertex(1, (0.0, 0.0)); @@ -355,8 +355,8 @@ fn sew_ordering() { loom::model(|| { // setup the map let map: CMap2 = CMapBuilder::default().n_darts(5).build().unwrap(); - map.force_two_link(1, 2); - map.force_one_link(4, 5); + map.force_link::<2>(1, 2); + map.force_link::<1>(4, 5); map.force_write_vertex(2, Vertex2(1.0, 1.0)); map.force_write_vertex(3, Vertex2(1.0, 2.0)); map.force_write_vertex(5, Vertex2(2.0, 2.0)); @@ -372,11 +372,11 @@ fn sew_ordering() { // 2-sew before 1-sew: (1.25, 1.5) let t1 = loom::thread::spawn(move || { - m1.force_one_sew(1, 3); + m1.force_sew::<1>(1, 3); }); let t2 = loom::thread::spawn(move || { - m2.force_two_sew(3, 4); + m2.force_sew::<2>(3, 4); }); t1.join().unwrap(); @@ -404,10 +404,10 @@ fn unsew_ordering() { .add_attribute::() .build() .unwrap(); - map.force_two_link(1, 2); - map.force_two_link(3, 4); - map.force_one_link(1, 3); - map.force_one_link(4, 5); + map.force_link::<2>(1, 2); + map.force_link::<2>(3, 4); + map.force_link::<1>(1, 3); + map.force_link::<1>(4, 5); map.force_write_vertex(2, Vertex2(0.0, 0.0)); map.force_write_attribute(2, Weight(33)); let arc = loom::sync::Arc::new(map); @@ -422,11 +422,11 @@ fn unsew_ordering() { // 2-unsew before 1-unsew: (W2, W3, W5) = (9, 8, 16) let t1 = loom::thread::spawn(move || { - m1.force_one_unsew(1); + m1.force_unsew::<1>(1); }); let t2 = loom::thread::spawn(move || { - m2.force_two_unsew(3); + m2.force_unsew::<2>(3); }); t1.join().unwrap(); diff --git a/honeycomb-kernels/src/grisubal/routines/insert_new_edges.rs b/honeycomb-kernels/src/grisubal/routines/insert_new_edges.rs index 71db1cea..7161c938 100644 --- a/honeycomb-kernels/src/grisubal/routines/insert_new_edges.rs +++ b/honeycomb-kernels/src/grisubal/routines/insert_new_edges.rs @@ -51,19 +51,19 @@ pub(crate) fn insert_edges_in_map(cmap: &mut CMap2, edges: &[ // remove deprecated connectivities & save what data is necessary let b1_start_old = cmap.beta::<1>(*start); let b0_end_old = cmap.beta::<0>(*end); - cmap.force_one_unlink(*start); - cmap.force_one_unlink(b0_end_old); + cmap.force_unlink::<1>(*start); + cmap.force_unlink::<1>(b0_end_old); let &[d_new, b2_d_new] = &dslice[0..2] else { unreachable!() }; - cmap.force_two_link(d_new, b2_d_new); + cmap.force_link::<2>(d_new, b2_d_new); // rebuild - this is the final construct if there are no intermediates - cmap.force_one_link(*start, d_new); - cmap.force_one_link(b2_d_new, b1_start_old); - cmap.force_one_link(d_new, *end); - cmap.force_one_link(b0_end_old, b2_d_new); + cmap.force_link::<1>(*start, d_new); + cmap.force_link::<1>(b2_d_new, b1_start_old); + cmap.force_link::<1>(d_new, *end); + cmap.force_link::<1>(b0_end_old, b2_d_new); if !intermediates.is_empty() { // create the topology components diff --git a/honeycomb-kernels/src/splits/edge_multiple.rs b/honeycomb-kernels/src/splits/edge_multiple.rs index 50fd6b8f..f0befe1f 100644 --- a/honeycomb-kernels/src/splits/edge_multiple.rs +++ b/honeycomb-kernels/src/splits/edge_multiple.rs @@ -45,7 +45,7 @@ use honeycomb_core::geometry::CoordsFloat; /// .n_darts(2) /// .build() /// .unwrap(); -/// map.force_two_link(1, 2); +/// map.force_link::<2>(1, 2); /// map.force_write_vertex(1, (0.0, 0.0)); /// map.force_write_vertex(2, (1.0, 0.0)); /// // split @@ -222,7 +222,7 @@ fn inner_splitn( cmap.set_beta::<1>(base_dart1, 0); cmap.set_beta::<0>(b1d1_old, 0); if base_dart2 != NULL_DART_ID { - cmap.force_two_unlink(base_dart1); + cmap.force_unlink::<2>(base_dart1); } // insert new vertices / darts on base_dart1's side let mut prev_d = base_dart1; @@ -234,11 +234,11 @@ fn inner_splitn( // println!("{W_VERTEX_BOUND}"); } let new_v = v1 + seg * t; - cmap.force_one_link(prev_d, new_d); + cmap.force_link::<1>(prev_d, new_d); cmap.force_write_vertex(new_d, new_v); prev_d = new_d; }); - cmap.force_one_link(prev_d, b1d1_old); + cmap.force_link::<1>(prev_d, b1d1_old); // if b2(base_dart1) is defined, insert vertices / darts on its side too if base_dart2 != NULL_DART_ID { @@ -252,12 +252,12 @@ fn inner_splitn( .rev() .zip(darts_sh.iter()) .for_each(|(d, new_d)| { - cmap.force_two_link(prev_d, *d); - cmap.force_one_link(prev_d, *new_d); + cmap.force_link::<2>(prev_d, *d); + cmap.force_link::<1>(prev_d, *new_d); prev_d = *new_d; }); - cmap.force_one_link(prev_d, b1d2_old); - cmap.force_two_link(prev_d, base_dart1); + cmap.force_link::<1>(prev_d, b1d2_old); + cmap.force_link::<2>(prev_d, base_dart1); } Ok(()) diff --git a/honeycomb-kernels/src/splits/edge_single.rs b/honeycomb-kernels/src/splits/edge_single.rs index c80694b5..cc3606a7 100644 --- a/honeycomb-kernels/src/splits/edge_single.rs +++ b/honeycomb-kernels/src/splits/edge_single.rs @@ -166,8 +166,8 @@ fn inner_split( cmap.set_beta::<1>(base_dart1, 0); cmap.set_beta::<0>(b1d1_old, 0); // rebuild the edge - cmap.force_one_link(base_dart1, b1d1_new); - cmap.force_one_link(b1d1_new, b1d1_old); + cmap.force_link::<1>(base_dart1, b1d1_new); + cmap.force_link::<1>(b1d1_new, b1d1_old); // insert the new vertex let seg = v2 - v1; cmap.force_write_vertex( @@ -190,18 +190,18 @@ fn inner_split( cmap.set_beta::<0>(b1d1_old, 0); cmap.set_beta::<1>(base_dart2, 0); cmap.set_beta::<0>(b1d2_old, 0); - cmap.force_two_unlink(base_dart1); + cmap.force_unlink::<2>(base_dart1); // rebuild the edge - cmap.force_one_link(base_dart1, b1d1_new); + cmap.force_link::<1>(base_dart1, b1d1_new); if b1d1_old != NULL_DART_ID { - cmap.force_one_link(b1d1_new, b1d1_old); + cmap.force_link::<1>(b1d1_new, b1d1_old); } - cmap.force_one_link(base_dart2, b1d2_new); + cmap.force_link::<1>(base_dart2, b1d2_new); if b1d2_old != NULL_DART_ID { - cmap.force_one_link(b1d2_new, b1d2_old); + cmap.force_link::<1>(b1d2_new, b1d2_old); } - cmap.force_two_link(base_dart1, b1d2_new); - cmap.force_two_link(base_dart2, b1d1_new); + cmap.force_link::<2>(base_dart1, b1d2_new); + cmap.force_link::<2>(base_dart2, b1d1_new); // insert the new vertex let seg = v2 - v1; cmap.force_write_vertex( diff --git a/honeycomb-kernels/src/splits/tests.rs b/honeycomb-kernels/src/splits/tests.rs index 5e8ad9d4..2ea76dda 100644 --- a/honeycomb-kernels/src/splits/tests.rs +++ b/honeycomb-kernels/src/splits/tests.rs @@ -19,13 +19,13 @@ mod standard { // 1 2 3 4 // ---1--> ---2--> ---3--> let mut map: CMap2 = newmap(6); - map.force_one_link(1, 2); - map.force_one_link(2, 3); - map.force_one_link(4, 5); - map.force_one_link(5, 6); - map.force_two_link(1, 6); - map.force_two_link(2, 5); - map.force_two_link(3, 4); + map.force_link::<1>(1, 2); + map.force_link::<1>(2, 3); + map.force_link::<1>(4, 5); + map.force_link::<1>(5, 6); + map.force_link::<2>(1, 6); + map.force_link::<2>(2, 5); + map.force_link::<2>(3, 4); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); map.force_write_vertex(3, (2.0, 0.0)); @@ -61,7 +61,7 @@ mod standard { // 1 2 // ---1--> let mut map: CMap2 = newmap(2); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); // split @@ -89,7 +89,7 @@ mod standard { // before // 1 -----> 2 -> let mut map: CMap2 = newmap(2); - map.force_one_link(1, 2); + map.force_link::<1>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); // split @@ -108,7 +108,7 @@ mod standard { // 1 ? // ---1--> let mut map: CMap2 = newmap(2); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); // map.force_write_vertex(2, (1.0, 0.0)); missing vertex! // split @@ -124,13 +124,13 @@ mod standard { // 1 2 3 4 // ---1--> ---2--> ---3--> let mut map: CMap2 = newmap(6); - map.force_one_link(1, 2); - map.force_one_link(2, 3); - map.force_one_link(4, 5); - map.force_one_link(5, 6); - map.force_two_link(1, 6); - map.force_two_link(2, 5); - map.force_two_link(3, 4); + map.force_link::<1>(1, 2); + map.force_link::<1>(2, 3); + map.force_link::<1>(4, 5); + map.force_link::<1>(5, 6); + map.force_link::<2>(1, 6); + map.force_link::<2>(2, 5); + map.force_link::<2>(3, 4); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); map.force_write_vertex(3, (2.0, 0.0)); @@ -174,7 +174,7 @@ mod standard { // 1 2 // ---1--> let mut map: CMap2 = newmap(2); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); // split @@ -211,7 +211,7 @@ mod standard { // before // 1 -----> 2 -> let mut map: CMap2 = newmap(2); - map.force_one_link(1, 2); + map.force_link::<1>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); // split @@ -245,7 +245,7 @@ mod standard { // 1 ? // ---1--> let mut map: CMap2 = newmap(2); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); // map.force_write_vertex(2, (1.0, 0.0)); missing vertex! // split @@ -264,13 +264,13 @@ mod noalloc { // 1 2 3 4 // ---1--> ---2--> ---3--> let mut map: CMap2 = newmap(6); - map.force_one_link(1, 2); - map.force_one_link(2, 3); - map.force_one_link(4, 5); - map.force_one_link(5, 6); - map.force_two_link(1, 6); - map.force_two_link(2, 5); - map.force_two_link(3, 4); + map.force_link::<1>(1, 2); + map.force_link::<1>(2, 3); + map.force_link::<1>(4, 5); + map.force_link::<1>(5, 6); + map.force_link::<2>(1, 6); + map.force_link::<2>(2, 5); + map.force_link::<2>(3, 4); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); map.force_write_vertex(3, (2.0, 0.0)); @@ -307,7 +307,7 @@ mod noalloc { // 1 2 // ---1--> let mut map: CMap2 = newmap(2); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); // split @@ -336,7 +336,7 @@ mod noalloc { // before // 1 -----> 2 -> let mut map: CMap2 = newmap(2); - map.force_one_link(1, 2); + map.force_link::<1>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); // split @@ -356,7 +356,7 @@ mod noalloc { // 1 ? // ---1--> let mut map: CMap2 = newmap(2); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); // map.force_write_vertex(2, (1.0, 0.0)); missing vertex! // split @@ -374,13 +374,13 @@ mod noalloc { // 1 2 3 4 // ---1--> ---2--> ---3--> let mut map: CMap2 = newmap(6); - map.force_one_link(1, 2); - map.force_one_link(2, 3); - map.force_one_link(4, 5); - map.force_one_link(5, 6); - map.force_two_link(1, 6); - map.force_two_link(2, 5); - map.force_two_link(3, 4); + map.force_link::<1>(1, 2); + map.force_link::<1>(2, 3); + map.force_link::<1>(4, 5); + map.force_link::<1>(5, 6); + map.force_link::<2>(1, 6); + map.force_link::<2>(2, 5); + map.force_link::<2>(3, 4); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); map.force_write_vertex(3, (2.0, 0.0)); @@ -421,7 +421,7 @@ mod noalloc { // 1 2 // ---1--> let mut map: CMap2 = newmap(2); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); // split @@ -458,7 +458,7 @@ mod noalloc { // before // 1 -----> 2 -> let mut map: CMap2 = newmap(2); - map.force_one_link(1, 2); + map.force_link::<1>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); map.force_write_vertex(2, (1.0, 0.0)); // split @@ -501,7 +501,7 @@ mod noalloc { // 1 ? // ---1--> let mut map: CMap2 = newmap(2); - map.force_two_link(1, 2); + map.force_link::<2>(1, 2); map.force_write_vertex(1, (0.0, 0.0)); // map.force_write_vertex(2, (1.0, 0.0)); missing vertex! // split diff --git a/honeycomb-kernels/src/triangulation/ear_clipping.rs b/honeycomb-kernels/src/triangulation/ear_clipping.rs index 1d4bd48b..c8984a3a 100644 --- a/honeycomb-kernels/src/triangulation/ear_clipping.rs +++ b/honeycomb-kernels/src/triangulation/ear_clipping.rs @@ -115,13 +115,13 @@ pub fn process_cell( ndart_id += 2; // FIXME: using link methods only works if new identifiers are greater than all existing // FIXME: using sew methods in parallel could crash bc of the panic when no vertex defined - cmap.force_one_unlink(b0_d_ear1); - cmap.force_one_unlink(d_ear2); - cmap.force_one_link(d_ear2, nd1); - cmap.force_one_link(nd1, d_ear1); - cmap.force_one_link(b0_d_ear1, nd2); - cmap.force_one_link(nd2, b1_d_ear2); - cmap.force_two_link(nd1, nd2); + cmap.force_unlink::<1>(b0_d_ear1); + cmap.force_unlink::<1>(d_ear2); + cmap.force_link::<1>(d_ear2, nd1); + cmap.force_link::<1>(nd1, d_ear1); + cmap.force_link::<1>(b0_d_ear1, nd2); + cmap.force_link::<1>(nd2, b1_d_ear2); + cmap.force_link::<2>(nd1, nd2); // edit existing vectors darts.remove((ear + 1) % n); diff --git a/honeycomb-kernels/src/triangulation/fan.rs b/honeycomb-kernels/src/triangulation/fan.rs index 39712bae..81662968 100644 --- a/honeycomb-kernels/src/triangulation/fan.rs +++ b/honeycomb-kernels/src/triangulation/fan.rs @@ -86,20 +86,20 @@ pub fn process_cell( // THIS CANNOT BE PARALLELIZED AS IS let b0_sdart = cmap.beta::<0>(*sdart); let v0 = cmap.force_read_vertex(cmap.vertex_id(*sdart)).unwrap(); - cmap.force_one_unsew(b0_sdart); + cmap.force_unsew::<1>(b0_sdart); let mut d0 = *sdart; for sl in new_darts.chunks_exact(2) { let [d1, d2] = sl else { unreachable!() }; let b1_d0 = cmap.beta::<1>(d0); let b1b1_d0 = cmap.beta::<1>(cmap.beta::<1>(d0)); - cmap.force_one_unsew(b1_d0); - cmap.force_two_link(*d1, *d2); - cmap.force_one_link(*d2, b1b1_d0); - cmap.force_one_sew(b1_d0, *d1); - cmap.force_one_sew(*d1, d0); + cmap.force_unsew::<1>(b1_d0); + cmap.force_link::<2>(*d1, *d2); + cmap.force_link::<1>(*d2, b1b1_d0); + cmap.force_sew::<1>(b1_d0, *d1); + cmap.force_sew::<1>(*d1, d0); d0 = *d2; } - cmap.force_one_sew(cmap.beta::<1>(cmap.beta::<1>(d0)), d0); + cmap.force_sew::<1>(cmap.beta::<1>(cmap.beta::<1>(d0)), d0); cmap.force_write_vertex(cmap.vertex_id(*sdart), v0); } else { // println!("W: face {face_id} isn't fannable -- skipping triangulation"); @@ -160,20 +160,20 @@ pub fn process_convex_cell( // THIS CANNOT BE PARALLELIZED AS IS let b0_sdart = cmap.beta::<0>(sdart); let v0 = cmap.force_read_vertex(cmap.vertex_id(sdart)).unwrap(); - cmap.force_one_unsew(b0_sdart); + cmap.force_unsew::<1>(b0_sdart); let mut d0 = sdart; for sl in new_darts.chunks_exact(2) { let [d1, d2] = sl else { unreachable!() }; let b1_d0 = cmap.beta::<1>(d0); let b1b1_d0 = cmap.beta::<1>(cmap.beta::<1>(d0)); - cmap.force_one_unsew(b1_d0); - cmap.force_two_link(*d1, *d2); - cmap.force_one_link(*d2, b1b1_d0); - cmap.force_one_sew(b1_d0, *d1); - cmap.force_one_sew(*d1, d0); + cmap.force_unsew::<1>(b1_d0); + cmap.force_link::<2>(*d1, *d2); + cmap.force_link::<1>(*d2, b1b1_d0); + cmap.force_sew::<1>(b1_d0, *d1); + cmap.force_sew::<1>(*d1, d0); d0 = *d2; } - cmap.force_one_sew(cmap.beta::<1>(cmap.beta::<1>(d0)), d0); + cmap.force_sew::<1>(cmap.beta::<1>(cmap.beta::<1>(d0)), d0); cmap.force_write_vertex(cmap.vertex_id(sdart), v0); Ok(()) diff --git a/honeycomb-kernels/src/triangulation/tests.rs b/honeycomb-kernels/src/triangulation/tests.rs index a9f1d543..7d9d52d6 100644 --- a/honeycomb-kernels/src/triangulation/tests.rs +++ b/honeycomb-kernels/src/triangulation/tests.rs @@ -13,46 +13,46 @@ fn generate_map() -> CMap2 { let cmap: CMap2 = CMapBuilder::default().n_darts(28).build().unwrap(); // topology - cmap.force_one_link(1, 2); - cmap.force_one_link(2, 3); - cmap.force_one_link(3, 4); - cmap.force_one_link(4, 5); - cmap.force_one_link(5, 6); - cmap.force_one_link(6, 1); - - cmap.force_one_link(7, 8); - cmap.force_one_link(8, 9); - cmap.force_one_link(9, 10); - cmap.force_one_link(10, 11); - cmap.force_one_link(11, 12); - cmap.force_one_link(12, 7); - - cmap.force_one_link(13, 14); - cmap.force_one_link(14, 15); - cmap.force_one_link(15, 16); - cmap.force_one_link(16, 13); - - cmap.force_one_link(17, 18); - cmap.force_one_link(18, 19); - cmap.force_one_link(19, 20); - cmap.force_one_link(20, 21); - cmap.force_one_link(21, 22); - cmap.force_one_link(22, 23); - cmap.force_one_link(23, 24); - cmap.force_one_link(24, 25); - cmap.force_one_link(25, 17); - - cmap.force_one_link(26, 27); - cmap.force_one_link(27, 28); - cmap.force_one_link(28, 26); - - cmap.force_two_link(3, 7); - cmap.force_two_link(4, 13); - cmap.force_two_link(10, 27); - cmap.force_two_link(11, 26); - cmap.force_two_link(12, 14); - cmap.force_two_link(15, 17); - cmap.force_two_link(18, 28); + cmap.force_link::<1>(1, 2); + cmap.force_link::<1>(2, 3); + cmap.force_link::<1>(3, 4); + cmap.force_link::<1>(4, 5); + cmap.force_link::<1>(5, 6); + cmap.force_link::<1>(6, 1); + + cmap.force_link::<1>(7, 8); + cmap.force_link::<1>(8, 9); + cmap.force_link::<1>(9, 10); + cmap.force_link::<1>(10, 11); + cmap.force_link::<1>(11, 12); + cmap.force_link::<1>(12, 7); + + cmap.force_link::<1>(13, 14); + cmap.force_link::<1>(14, 15); + cmap.force_link::<1>(15, 16); + cmap.force_link::<1>(16, 13); + + cmap.force_link::<1>(17, 18); + cmap.force_link::<1>(18, 19); + cmap.force_link::<1>(19, 20); + cmap.force_link::<1>(20, 21); + cmap.force_link::<1>(21, 22); + cmap.force_link::<1>(22, 23); + cmap.force_link::<1>(23, 24); + cmap.force_link::<1>(24, 25); + cmap.force_link::<1>(25, 17); + + cmap.force_link::<1>(26, 27); + cmap.force_link::<1>(27, 28); + cmap.force_link::<1>(28, 26); + + cmap.force_link::<2>(3, 7); + cmap.force_link::<2>(4, 13); + cmap.force_link::<2>(10, 27); + cmap.force_link::<2>(11, 26); + cmap.force_link::<2>(12, 14); + cmap.force_link::<2>(15, 17); + cmap.force_link::<2>(18, 28); // geometry cmap.force_write_vertex(1, (1.0, 0.0));