use crate::attributes::{AttributeStorage, UnknownAttributeStorage};
use crate::cmap::{CMap2, DartIdType, EdgeIdType, NULL_DART_ID, OrbitPolicy, SewError};
use crate::geometry::CoordsFloat;
use crate::stm::{Transaction, TransactionClosureResult, abort, try_or_coerce};
#[doc(hidden)]
impl<T: CoordsFloat> CMap2<T> {
#[allow(clippy::too_many_lines)]
pub(super) fn two_sew(
&self,
t: &mut Transaction,
ld: DartIdType,
rd: DartIdType,
) -> TransactionClosureResult<(), SewError> {
let b1ld = self.beta_tx::<1>(t, ld)?;
let b1rd = self.beta_tx::<1>(t, rd)?;
let ld_eid = ld as EdgeIdType; let rd_eid = rd as EdgeIdType;
let ld_vid = self.vertex_id_tx(t, ld)?;
let b1rd_vid = self.vertex_id_tx(t, b1rd)?;
let b1ld_vid = self.vertex_id_tx(t, b1ld)?;
let rd_vid = self.vertex_id_tx(t, rd)?;
if let (
Some(l_vertex), Some(b1r_vertex), Some(b1l_vertex), Some(r_vertex), ) = (
self.vertices.read(t, ld_vid)?, self.vertices.read(t, b1rd_vid)?, self.vertices.read(t, b1ld_vid)?, self.vertices.read(t, rd_vid)?, ) {
let ld_vector = b1l_vertex - l_vertex;
let rd_vector = b1r_vertex - r_vertex;
if ld_vector.dot(&rd_vector) >= T::zero() {
abort(SewError::BadGeometry(2, ld, rd))?;
}
}
try_or_coerce!(self.link_tx::<2>(t, ld, rd), SewError);
try_or_coerce!(
self.attributes.merge_attributes(
t,
OrbitPolicy::Edge,
ld_eid.min(rd_eid),
ld_eid,
rd_eid,
),
SewError
);
if b1rd != NULL_DART_ID && ld_vid != b1rd_vid {
try_or_coerce!(
self.vertices
.merge(t, ld_vid.min(b1rd_vid), ld_vid, b1rd_vid),
SewError
);
try_or_coerce!(
self.attributes.merge_attributes(
t,
OrbitPolicy::Vertex,
ld_vid.min(b1rd_vid),
ld_vid,
b1rd_vid,
),
SewError
);
}
if b1ld != NULL_DART_ID && b1ld_vid != rd_vid {
try_or_coerce!(
self.vertices
.merge(t, b1ld_vid.min(rd_vid), b1ld_vid, rd_vid),
SewError
);
try_or_coerce!(
self.attributes.merge_attributes(
t,
OrbitPolicy::Vertex,
b1ld_vid.min(rd_vid),
b1ld_vid,
rd_vid,
),
SewError
);
}
Ok(())
}
#[allow(clippy::too_many_lines)]
pub(super) fn two_unsew(
&self,
t: &mut Transaction,
ld: DartIdType,
) -> TransactionClosureResult<(), SewError> {
let rd = self.beta_tx::<2>(t, ld)?;
let b1ld = self.beta_tx::<1>(t, ld)?;
let b1rd = self.beta_tx::<1>(t, rd)?;
try_or_coerce!(self.unlink_tx::<2>(t, ld), SewError);
let (new_lv_ld, new_lv_rd) = (self.vertex_id_tx(t, ld)?, self.vertex_id_tx(t, b1rd)?);
let (new_rv_ld, new_rv_rd) = (self.vertex_id_tx(t, b1ld)?, self.vertex_id_tx(t, rd)?);
try_or_coerce!(
self.attributes.split_attributes(
t,
OrbitPolicy::Edge,
ld as EdgeIdType, rd as EdgeIdType,
ld.min(rd) as EdgeIdType,
),
SewError
);
if b1rd != NULL_DART_ID && new_lv_ld != new_lv_rd {
try_or_coerce!(
self.vertices
.split(t, new_lv_ld, new_lv_rd, new_lv_ld.min(new_lv_rd)),
SewError
);
try_or_coerce!(
self.attributes.split_attributes(
t,
OrbitPolicy::Vertex,
new_lv_ld,
new_lv_rd,
new_lv_ld.min(new_lv_rd),
),
SewError
);
}
if b1ld != NULL_DART_ID && new_rv_ld != new_rv_rd {
try_or_coerce!(
self.vertices
.split(t, new_rv_ld, new_rv_rd, new_rv_ld.min(new_rv_rd)),
SewError
);
try_or_coerce!(
self.attributes.split_attributes(
t,
OrbitPolicy::Vertex,
new_rv_ld,
new_rv_rd,
new_rv_ld.min(new_rv_rd),
),
SewError
);
}
Ok(())
}
}