use fast_stm::abort;
use crate::{
attributes::UnknownAttributeStorage,
cmap::{CMap3, DartIdType, LinkError, NULL_DART_ID, OrbitPolicy, SewError},
geometry::CoordsFloat,
stm::{Transaction, TransactionClosureResult, try_or_coerce},
};
#[doc(hidden)]
impl<T: CoordsFloat> CMap3<T> {
pub(crate) fn one_sew_tx(
&self,
t: &mut Transaction,
ld: DartIdType,
rd: DartIdType,
) -> TransactionClosureResult<(), SewError> {
let b3ld = self.beta_tx::<3>(t, ld)?;
let b3rd = self.beta_tx::<3>(t, rd)?;
let b2ld = self.beta_tx::<2>(t, ld)?;
let vid_l_old = self.vertex_id_tx(t, b3ld.max(b2ld))?;
let vid_r_old = self.vertex_id_tx(t, rd)?;
try_or_coerce!(self.betas.one_link_core(t, ld, rd), SewError);
if b3ld != NULL_DART_ID && b3rd != NULL_DART_ID {
try_or_coerce!(self.betas.one_link_core(t, b3rd, b3ld), SewError);
}
let b3ld = b3ld.max(b2ld);
if b3ld != NULL_DART_ID && vid_l_old != vid_r_old {
let new_vid = vid_r_old.min(vid_l_old);
try_or_coerce!(
self.vertices.merge(t, new_vid, vid_l_old, vid_r_old),
SewError
);
try_or_coerce!(
self.attributes.merge_attributes(
t,
OrbitPolicy::Vertex,
new_vid,
vid_l_old,
vid_r_old
),
SewError
);
}
Ok(())
}
pub(crate) fn one_unsew_tx(
&self,
t: &mut Transaction,
ld: DartIdType,
) -> TransactionClosureResult<(), SewError> {
let rd = self.beta_tx::<1>(t, ld)?;
let b3ld = self.beta_tx::<3>(t, ld)?;
let b3rd = self.beta_tx::<3>(t, rd)?;
let b2ld = self.beta_tx::<2>(t, ld)?;
try_or_coerce!(self.betas.one_unlink_core(t, ld), SewError);
if b3ld != NULL_DART_ID && b3rd != NULL_DART_ID {
if self.beta_tx::<1>(t, b3rd)? != b3ld {
abort(SewError::FailedLink(LinkError::AsymmetricalFaces(ld, rd)))?;
}
try_or_coerce!(self.betas.one_unlink_core(t, b3rd), SewError);
}
let b3ld = b3ld.max(b2ld);
if b3ld != NULL_DART_ID {
let vid_l_new = self.vertex_id_tx(t, b3ld)?;
let vid_r_new = self.vertex_id_tx(t, rd)?;
if vid_l_new != vid_r_new {
try_or_coerce!(
self.vertices
.split(t, vid_l_new, vid_r_new, vid_l_new.min(vid_r_new)),
SewError
);
try_or_coerce!(
self.attributes.split_attributes(
t,
OrbitPolicy::Vertex,
vid_l_new,
vid_r_new,
vid_l_new.min(vid_r_new),
),
SewError
);
}
}
Ok(())
}
}