Function insert_vertices_on_edge

Source
pub fn insert_vertices_on_edge<T: CoordsFloat>(
    cmap: &CMap2<T>,
    trans: &mut Transaction,
    edge_id: EdgeIdType,
    new_darts: &[DartIdType],
    midpoint_vertices: &[T],
) -> TransactionClosureResult<(), VertexInsertionError>
Expand description

Insert n vertices in an edge, cutting it into n+1 segments.

This implementation is 2D specific.

§Arguments

  • cmap: &mut CMap2<T> – Reference to the modified map.
  • trans: &mut Transaction – Associated transaction.
  • edge_id: EdgeIdentifier – Target edge.
  • new_darts: &[DartIdentifier] – Dart IDs used to build the new vertices/segments.
  • midpoint_vertices: &[T] – Relative positions of new vertices, starting from the vertex of the dart sharing edge_id as its identifier.

§Dart IDs Requirements & Usage

Because of the dimension, we can easily compute the number of dart needed to perform this operation. These are the requirements for the darts:

  • identifiers are passed as a slice:
    • slice length should verify new_darts.len() == 2 * midpoint_vertices.len()
  • the first half of the slice will always be used if the operation is successful.
  • the second half of the slice will only be used if the original edge is made of two darts; if that is not the case, the second half IDs can all be NULL_DART_IDs.
  • all of these darts should be free

§Errors

This function will abort and raise an error if:

  • the transaction cannot be completed,
  • a hypothesis over input isn’t verified (see VertexInsertionError),
  • an internal operation failed.

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 to retry or abort as he wishes using Transaction::with_control_and_err.

§Example

// before
//    <--2---
//  1         2
//    ---1-->

let mut map: CMap2<_> = CMapBuilder::<2, _>::from_n_darts(2)
                            .build()
                            .unwrap();
map.force_link::<2>(1, 2);
map.force_write_vertex(1, (0.0, 0.0));
map.force_write_vertex(2, (1.0, 0.0));

let nd = map.add_free_darts(6);

// split
assert!(
    atomically_with_err(|t| insert_vertices_on_edge(
        &map,
        t,
        1,
        &[nd, nd + 1, nd + 2, nd + 3, nd + 4, nd + 5],
        &[0.25, 0.50, 0.75],
    )).is_ok()
);

// after
//    <-<-<-<
//  1 -3-4-5- 2
//    >->->->

// checks
let new_darts = [
    map.beta::<1>(1),
    map.beta::<1>(map.beta::<1>(1)),
    map.beta::<1>(map.beta::<1>(map.beta::<1>(1))),
];
assert_eq!(&new_darts, &[3, 4, 5]);
assert_eq!(map.force_read_vertex(3), Some(Vertex2(0.25, 0.0)));
assert_eq!(map.force_read_vertex(4), Some(Vertex2(0.50, 0.0)));
assert_eq!(map.force_read_vertex(5), Some(Vertex2(0.75, 0.0)));

assert_eq!(map.beta::<1>(1), 3);
assert_eq!(map.beta::<1>(3), 4);
assert_eq!(map.beta::<1>(4), 5);
assert_eq!(map.beta::<1>(5), NULL_DART_ID);

assert_eq!(map.beta::<1>(2), 6);
assert_eq!(map.beta::<1>(6), 7);
assert_eq!(map.beta::<1>(7), 8);
assert_eq!(map.beta::<1>(8), NULL_DART_ID);

assert_eq!(map.beta::<2>(1), 8);
assert_eq!(map.beta::<2>(3), 7);
assert_eq!(map.beta::<2>(4), 6);
assert_eq!(map.beta::<2>(5), 2);