use crate::diagram::{CellIndex, ColorType, Diagram, Edge, EdgeIndex, SourceIndex, VertexIndex};
use crate::{BvError, InputType, tln};
impl Diagram {
#[inline(always)]
pub fn edge_index_unchecked(&self, idx: usize) -> EdgeIndex {
assert!(idx < self.edges_.len(), "edge index out of bounds");
EdgeIndex(idx as u32)
}
#[inline(always)]
pub fn edges(&self) -> &[Edge] {
&self.edges_
}
#[inline(always)]
pub fn num_edges(&self) -> usize {
self.edges_.len()
}
#[inline(always)]
pub(crate) fn edge_(&self, edge_id: EdgeIndex) -> Option<&Edge> {
debug_assert_eq!(self.edges_[edge_id.usize()].id_, edge_id);
self.edges_.get(edge_id.usize())
}
pub fn edge(&self, edge_id: EdgeIndex) -> Result<&Edge, BvError> {
self.edge_(edge_id).ok_or_else(|| {
BvError::IdError(format!("The edge with id:{} does not exist", edge_id.0))
})
}
pub(crate) fn edge_as_line_(&self, edge: EdgeIndex) -> Option<[f64; 4]> {
let v0 = self.edge_get_vertex0_(edge).and_then(|v| self.vertex_(v))?;
let v1 = self.edge_get_vertex1_(edge).and_then(|v| self.vertex_(v))?;
Some([v0.x(), v0.y(), v1.x(), v1.y()])
}
#[inline]
pub fn edge_as_line(&self, edge_id: EdgeIndex) -> Result<[f64; 4], BvError> {
self.edge_as_line_(edge_id).ok_or_else(|| {
BvError::IdError(format!(
"Edge id:{} (probably) does not exists, or some vertex is missing",
edge_id.0
))
})
}
pub fn color_exterior_edges(&mut self, external_color: ColorType) {
for edge_id in self.decoupled_edges_iter() {
if !self.edge_is_finite_(edge_id).unwrap() {
self.iterative_color_exterior(edge_id, external_color);
}
}
}
fn iterative_color_exterior(&mut self, start_edge: EdgeIndex, external_color: ColorType) {
let mut queue = Vec::with_capacity(self.num_edges() / 100);
queue.push(start_edge);
while let Some(edge_id) = queue.pop() {
if self.edge_get_color_(edge_id).unwrap() & external_color != 0 {
continue;
}
self.edge_or_color_(edge_id, external_color);
let v1 = self.edge_get_vertex1_(edge_id);
if self.edge_get_vertex0_(edge_id).is_some() && v1.is_none() {
continue;
}
if let Some(twin) = self.edge_get_twin_(edge_id) {
self.edge_or_color_(twin, external_color);
}
if v1.is_none()
|| v1
.and_then(|v1| self.vertex_is_site_point_(v1))
.unwrap_or(true)
|| !self.edge_(edge_id).is_some_and(|x| x.is_primary())
{
continue;
}
if let Some(v) = v1 {
self.vertex_set_color_(v, external_color);
if let Some(incident_edge) = self.vertex_get_incident_edge(v) {
for e in self.edge_rot_next_edges(incident_edge) {
if self.edge_get_color_(e).unwrap() & external_color == 0 {
queue.push(e);
}
}
}
}
}
}
fn create_and_insert_edge(
&mut self,
cell_id: CellIndex,
is_linear: bool,
is_primary: bool,
) -> EdgeIndex {
let new_edge_id = EdgeIndex(self.edges_.len() as u32);
let new_edge = Edge::new_(new_edge_id, cell_id, is_linear, is_primary);
self.edges_.push(new_edge);
tln!("Created and inserted new edge : e={}", new_edge_id.0);
new_edge_id
}
pub(crate) fn edge_copy_(&mut self, dest: EdgeIndex, source: EdgeIndex) {
let mut e = self.edges_[source.usize()];
e.id_ = dest;
self.edges_[dest.usize()] = e;
}
#[inline]
pub(crate) fn edge_get_color_(&self, edge_id: EdgeIndex) -> Option<ColorType> {
self.edge_(edge_id).map(|edge| edge.get_color())
}
#[inline]
pub fn edge_get_color(&self, edge_id: EdgeIndex) -> Result<ColorType, BvError> {
self.edge_get_color_(edge_id).ok_or_else(|| {
BvError::IdError(format!("edge id {} (probably) does not exists", edge_id.0))
})
}
#[inline]
pub(crate) fn edge_set_color_(&mut self, edge_id: EdgeIndex, color: ColorType) {
if let Some(edge) = self.edges_.get_mut(edge_id.usize()) {
let _ = edge.set_color(color);
}
}
#[inline]
pub fn edge_set_color(&mut self, edge_id: EdgeIndex, color: ColorType) -> Result<(), BvError> {
self.edge_set_color_(edge_id, color);
Ok(())
}
#[inline]
pub(crate) fn edge_or_color_(&mut self, edge_id: EdgeIndex, color: ColorType) {
if let Some(edge) = self.edges_.get_mut(edge_id.usize()) {
let _ = edge.or_color(color);
}
}
#[inline]
pub fn edge_or_color(&mut self, edge_id: EdgeIndex, color: ColorType) -> Result<(), BvError> {
self.edge_or_color_(edge_id, color);
Ok(())
}
#[inline]
pub(crate) fn edge_set_twin_(&mut self, edge_id: EdgeIndex, twin_id: EdgeIndex) {
if let Some(edge) = self.edges_.get_mut(edge_id.usize()) {
edge.twin_ = Some(twin_id);
}
}
#[inline]
pub(crate) fn edge_get_twin_(&self, edge_id: EdgeIndex) -> Option<EdgeIndex> {
if let Some(edge) = self.edges_.get(edge_id.usize()) {
return edge.twin_();
}
None
}
#[inline]
pub fn edge_get_twin(&self, edge_id: EdgeIndex) -> Result<EdgeIndex, BvError> {
self.edge_get_twin_(edge_id)
.ok_or_else(|| BvError::IdError(format!("Edge {} does not have a twin", edge_id.0)))
}
#[inline]
pub(super) fn edge_get_next_(&self, edge_id: EdgeIndex) -> Option<EdgeIndex> {
self.edges_.get(edge_id.usize()).and_then(|e| e.next_())
}
#[inline]
pub fn edge_get_next(&self, edge_id: EdgeIndex) -> Result<EdgeIndex, BvError> {
self.edge_get_next_(edge_id).ok_or_else(|| {
BvError::IdError(format!("Edge {} did not have any next edge", edge_id.0))
})
}
#[inline]
pub(super) fn edge_get_prev_(&self, edge_id: EdgeIndex) -> Option<EdgeIndex> {
self.edges_.get(edge_id.usize()).and_then(|e| e.prev_())
}
#[inline]
pub fn edge_get_prev(&self, edge_id: EdgeIndex) -> Result<EdgeIndex, BvError> {
self.edge_get_prev_(edge_id).ok_or_else(|| {
BvError::IdError(format!("Edge {} did not have any prev edge", edge_id.0))
})
}
#[inline]
pub(crate) fn edge_is_finite_(&self, edge_id: EdgeIndex) -> Option<bool> {
Some(self.edge_get_vertex0_(edge_id).is_some() && self.edge_get_vertex1_(edge_id).is_some())
}
#[inline]
pub fn edge_is_finite(&self, edge_id: EdgeIndex) -> Result<bool, BvError> {
self.edge_is_finite_(edge_id)
.ok_or_else(|| BvError::IdError(format!("Edge id {} doesn't exists", edge_id.0)))
}
#[inline]
pub(crate) fn edge_is_infinite_(&self, edge_id: EdgeIndex) -> Option<bool> {
Some(!self.edge_is_finite_(edge_id)?)
}
#[inline]
pub fn edge_is_infinite(&self, edge_id: EdgeIndex) -> Result<bool, BvError> {
self.edge_is_infinite_(edge_id)
.ok_or_else(|| BvError::IdError(format!("Edge id {} doesn't exists", edge_id.0)))
}
pub(super) fn remove_edge_(&mut self, edge: EdgeIndex) {
let vertex = self.edge_get_vertex0_(edge);
let mut updated_edge = self
.edge_get_twin_(edge)
.and_then(|e| self.edge_rot_next(e));
while updated_edge != self.edge_get_twin_(edge) {
if let Some(u_edge) = updated_edge {
self.edge_set_vertex0_(u_edge, vertex);
updated_edge = self.edge_rot_next(u_edge);
} else {
break;
}
}
let edge1 = edge;
let edge2 = self.edge_get_twin_(edge);
if let Some(edge2) = edge2 {
if let Some(next) = self.edge_rot_next(edge1) {
let _ = self
.edge_get_twin_(next)
.map(|t| self.edge_set_next_(t, self.edge_rot_prev(edge2)));
let _ = self
.edge_rot_prev(edge2)
.map(|p| self.edge_set_prev_(p, self.edge_get_twin_(next)));
}
}
let _ = self.edge_rot_prev(edge1).map(|e| {
self.edge_set_prev_(
e,
edge2
.and_then(|e| self.edge_rot_next(e))
.and_then(|n| self.edge_get_twin_(n)),
)
});
if let Some(nt) = edge2
.and_then(|e| self.edge_rot_next(e))
.and_then(|n| self.edge_get_twin_(n))
{
self.edge_set_next_(nt, self.edge_rot_prev(edge1));
}
}
pub(super) fn edge_set_vertex0_(&mut self, edge_id: EdgeIndex, vertex_id: Option<VertexIndex>) {
if let Some(edge) = self.edges_.get_mut(edge_id.usize()) {
edge.vertex_ = vertex_id;
}
}
#[inline]
pub(crate) fn edge_get_vertex0_(&self, edge_id: EdgeIndex) -> Option<VertexIndex> {
self.edges_.get(edge_id.usize()).and_then(|x| x.vertex0())
}
#[inline]
pub fn edge_get_vertex0(&self, edge_id: EdgeIndex) -> Result<Option<VertexIndex>, BvError> {
Ok(self.edge_get_vertex0_(edge_id))
}
#[inline]
pub(crate) fn edge_get_vertex1_(&self, edge_id: EdgeIndex) -> Option<VertexIndex> {
self.edge_get_twin_(edge_id)
.and_then(|twin| self.edge_get_vertex0_(twin))
}
#[inline]
pub fn edge_get_vertex1(&self, edge_id: EdgeIndex) -> Result<Option<VertexIndex>, BvError> {
Ok(self.edge_get_vertex1_(edge_id))
}
#[inline]
pub(super) fn edge_set_prev_(&mut self, edge_id: EdgeIndex, prev_id: Option<EdgeIndex>) {
if let Some(edge) = self.edges_.get_mut(edge_id.usize()) {
edge.prev_ccw_ = prev_id;
}
}
#[inline]
pub(super) fn edge_set_next_(&mut self, edge_id: EdgeIndex, next_id: Option<EdgeIndex>) {
if let Some(edge) = self.edges_.get_mut(edge_id.usize()) {
edge.next_ccw_ = next_id;
}
}
#[inline]
pub fn edge_rot_next(&self, edge_id: EdgeIndex) -> Option<EdgeIndex> {
self.edge_get_prev_(edge_id)
.and_then(|p| self.edge_get_twin_(p))
}
#[inline]
pub fn edge_rot_prev(&self, edge_id: EdgeIndex) -> Option<EdgeIndex> {
self.edge_get_twin_(edge_id)
.and_then(|twin| self.edge_get_next_(twin))
}
pub(crate) fn insert_new_edge_2_<I: InputType>(
&mut self,
site1: crate::site_event::SiteEvent<I>,
site2: crate::site_event::SiteEvent<I>,
) -> (EdgeIndex, EdgeIndex) {
let site1_index = site1.sorted_index();
let site2_index = site2.sorted_index();
let is_linear = crate::site_event::SiteEvent::is_linear_edge(&site1, &site2);
let is_primary = crate::site_event::SiteEvent::is_primary_edge(&site1, &site2);
let edge1_id = self.create_and_insert_edge(CellIndex(site1_index), is_linear, is_primary);
let edge2_id = self.create_and_insert_edge(CellIndex(site2_index), is_linear, is_primary);
if self.cells_.is_empty() {
let _ = self.make_new_cell_with_category_(
CellIndex(site1_index),
SourceIndex(site1.initial_index()),
site1.source_category(),
);
}
let _ = self.make_new_cell_with_category_(
CellIndex(site2_index),
SourceIndex(site2.initial_index()),
site2.source_category(),
);
self.edge_set_cell_(edge1_id, CellIndex(site1_index));
self.edge_set_cell_(edge2_id, CellIndex(site2_index));
self.edge_set_twin_(edge1_id, edge2_id);
self.edge_set_twin_(edge2_id, edge1_id);
(edge1_id, edge2_id)
}
pub(crate) fn insert_new_edge_5_<I: InputType>(
&mut self,
site1: crate::site_event::SiteEvent<I>,
site3: crate::site_event::SiteEvent<I>,
circle: &crate::circle_event::CircleEvent,
edge12_id: EdgeIndex,
edge23_id: EdgeIndex,
) -> (EdgeIndex, EdgeIndex) {
tln!("new vertex@{:?}", circle);
let is_linear = crate::site_event::SiteEvent::<I>::is_linear_edge(&site1, &site3);
let is_primary = crate::site_event::SiteEvent::<I>::is_primary_edge(&site1, &site3);
let new_edge1_id =
self.create_and_insert_edge(CellIndex(site1.sorted_index()), is_linear, is_primary);
let new_edge2_id =
self.create_and_insert_edge(CellIndex(site3.sorted_index()), is_linear, is_primary);
let new_vertex_id = self.vertex_new_2_(circle.x(), circle.y(), circle.is_site_point());
self.edge_set_vertex0_(edge12_id, Some(new_vertex_id));
self.edge_set_vertex0_(edge23_id, Some(new_vertex_id));
self.edge_set_twin_(new_edge1_id, new_edge2_id);
self.edge_set_twin_(new_edge2_id, new_edge1_id);
self.edge_set_vertex0_(new_edge2_id, Some(new_vertex_id));
self.edge_set_prev_(edge12_id, Some(new_edge1_id));
self.edge_set_next_(new_edge1_id, Some(edge12_id));
let edge12_twin_id = self.edge_get_twin_(edge12_id);
let _ = edge12_twin_id
.map(|edge12_twin_id| self.edge_set_next_(edge12_twin_id, Some(edge23_id)));
self.edge_set_prev_(edge23_id, edge12_twin_id);
let edge23_twin_id = self.edge_get_twin_(edge23_id);
let _ = edge23_twin_id
.map(|edge23_twin_id| self.edge_set_next_(edge23_twin_id, Some(new_edge2_id)));
self.edge_set_prev_(new_edge2_id, edge23_twin_id);
(new_edge1_id, new_edge2_id)
}
}