use crate::circle_event as VC;
use crate::ctypes as CT;
use crate::site_event as VSE;
use crate::visual_utils as VU;
use crate::{sync_diagram as SD, BvError};
pub use crate::{cast, InputType, OutputType};
#[allow(unused_imports)]
use crate::{t, tln};
use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::cell;
use std::cmp::Ordering;
use std::fmt;
use std::rc::Rc;
pub type SourceIndex = usize;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Hash, PartialEq, Eq, Default)]
pub struct CellIndex(pub usize);
impl fmt::Debug for CellIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "CellIndex({})", self.0)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Hash, PartialEq, Eq, Default)]
pub struct EdgeIndex(pub usize);
impl fmt::Debug for EdgeIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "EdgeIndex({})", self.0)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Hash, PartialEq, Eq, Default)]
pub struct VertexIndex(pub usize);
impl fmt::Debug for VertexIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "VertexIndex({})", self.0)
}
}
pub type ColorType = u32;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, PartialEq, Eq)]
pub(crate) struct ColorBits(pub ColorType);
#[allow(clippy::upper_case_acronyms)]
impl ColorBits {
pub(crate) const ZERO: Self = ColorBits(0x0);
pub(crate) const SINGLE_POINT__BIT: Self = ColorBits(0x0); pub(crate) const SEGMENT_START_POINT__BIT: Self = ColorBits(0x1); pub(crate) const SEGMENT_END_POINT__BIT: Self = ColorBits(0x2); pub(crate) const SITE_VERTEX__BIT: Self = ColorBits(0x4);
pub(crate) const INITIAL_SEGMENT: Self = ColorBits(0x8); pub(crate) const REVERSE_SEGMENT: Self = ColorBits(0x9);
pub(crate) const RESERVED_BITS__SHIFT: Self = Self(0x5);
pub(crate) const RESERVED__MASK: Self = ColorBits(0x1F);
pub(crate) const GEOMETRY__SHIFT: Self = ColorBits(0x3);
pub(crate) const GEOMETRY_CATEGORY_POINT__BIT: Self = ColorBits(0x0); pub(crate) const GEOMETRY_CATEGORY_SEGMENT__BIT: Self = ColorBits(0x1);
pub(crate) const IS_INVERSE__BIT: Self = Self(0x20);
pub(crate) const TEMPORARY_CELL: Self = ColorBits(u32::MAX << ColorBits::GEOMETRY__SHIFT.0);
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SourceCategory {
SinglePoint,
SegmentStart,
SegmentEnd,
Segment,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone)]
pub struct Cell {
id_: CellIndex,
source_index_: SourceIndex,
incident_edge_: Option<EdgeIndex>,
color_: ColorType,
}
impl fmt::Debug for Cell {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"(id:{:?} ii:{} ie:{} col:{})",
self.id_.0,
self.source_index_,
CT::format_id(self.incident_edge_.map(|x| x.0)),
self.color_
)
}
}
impl Cell {
pub fn new(id: CellIndex, source_index: SourceIndex, source_category: ColorType) -> Self {
Cell {
id_: id,
source_index_: source_index,
incident_edge_: None,
color_: source_category,
}
}
#[inline(always)]
pub(crate) fn internal_color(&self) -> ColorBits {
ColorBits(self.color_ & ColorBits::RESERVED__MASK.0)
}
#[inline(always)]
pub fn source_category(&self) -> SourceCategory {
match self.internal_color() {
ColorBits::SINGLE_POINT__BIT => SourceCategory::SinglePoint,
ColorBits::SEGMENT_START_POINT__BIT => SourceCategory::SegmentStart,
ColorBits::SEGMENT_END_POINT__BIT => SourceCategory::SegmentEnd,
_ => SourceCategory::Segment,
}
}
#[inline(always)]
pub fn contains_point(&self) -> bool {
let geometry = self.internal_color().0 >> ColorBits::GEOMETRY__SHIFT.0;
geometry == ColorBits::GEOMETRY_CATEGORY_POINT__BIT.0
}
#[inline(always)]
pub fn contains_segment(&self) -> bool {
let geometry = self.internal_color().0 >> ColorBits::GEOMETRY__SHIFT.0;
geometry == ColorBits::GEOMETRY_CATEGORY_SEGMENT__BIT.0
}
#[inline(always)]
pub fn contains_segment_startpoint(&self) -> bool {
self.internal_color().0 == ColorBits::SEGMENT_START_POINT__BIT.0
}
#[inline(always)]
pub fn contains_segment_endpoint(&self) -> bool {
self.internal_color().0 == ColorBits::SEGMENT_END_POINT__BIT.0
}
#[inline(always)]
pub fn id(&self) -> CellIndex {
self.id_
}
#[inline(always)]
pub fn source_index(&self) -> SourceIndex {
self.source_index_
}
#[inline(always)]
pub fn source_index_2(&self) -> (SourceIndex, SourceCategory) {
(self.source_index_, self.source_category())
}
pub fn is_degenerate(&self) -> bool {
self.incident_edge_.is_none()
}
#[inline(always)]
pub fn get_incident_edge(&self) -> Option<EdgeIndex> {
self.incident_edge_
}
}
pub struct EdgeNextIterator<'s, F: OutputType> {
diagram_: &'s Diagram<F>,
start_edge_: EdgeIndex,
next_edge_: Option<EdgeIndex>,
}
impl<'s, F: OutputType> EdgeNextIterator<'s, F> {
pub(crate) fn new(diagram: &'s Diagram<F>, starting_edge: Option<EdgeIndex>) -> Self {
if let Some(starting_edge) = starting_edge {
Self {
diagram_: diagram,
start_edge_: starting_edge,
next_edge_: Some(starting_edge),
}
} else {
Self {
diagram_: diagram,
start_edge_: EdgeIndex(0),
next_edge_: None,
}
}
}
}
impl<'s, F: OutputType> Iterator for EdgeNextIterator<'s, F> {
type Item = EdgeIndex;
fn next(&mut self) -> Option<EdgeIndex> {
let rv = self.next_edge_;
let new_next_edge = self.diagram_.edge_get_next_(self.next_edge_);
self.next_edge_ = if let Some(nne) = new_next_edge {
if nne.0 == self.start_edge_.0 {
None
} else {
Some(nne)
}
} else {
None
};
rv
}
}
pub struct EdgeRotNextIterator<'s, F: OutputType> {
diagram_: &'s Diagram<F>,
start_edge: EdgeIndex,
next_edge: Option<EdgeIndex>,
}
impl<'s, F: OutputType> EdgeRotNextIterator<'s, F> {
pub(crate) fn new(diagram: &'s Diagram<F>, starting_edge: Option<EdgeIndex>) -> Self {
if let Some(starting_edge) = starting_edge {
Self {
diagram_: diagram,
start_edge: starting_edge,
next_edge: Some(starting_edge),
}
} else {
Self {
diagram_: diagram,
start_edge: EdgeIndex(0),
next_edge: None,
}
}
}
}
impl<'s, F: OutputType> Iterator for EdgeRotNextIterator<'s, F> {
type Item = EdgeIndex;
fn next(&mut self) -> Option<EdgeIndex> {
let rv = self.next_edge;
let new_next_edge = self.diagram_.edge_rot_next_(self.next_edge);
self.next_edge = if let Some(nne) = new_next_edge {
if nne.0 == self.start_edge.0 {
None
} else {
new_next_edge
}
} else {
None
};
rv
}
}
pub struct EdgeRotPrevIterator<'s, F: OutputType> {
diagram_: &'s Diagram<F>,
start_edge: EdgeIndex,
next_edge: Option<EdgeIndex>,
}
impl<'s, F: OutputType> EdgeRotPrevIterator<'s, F> {
#[allow(dead_code)]
pub(crate) fn new(diagram: &'s Diagram<F>, starting_edge: Option<EdgeIndex>) -> Self {
if let Some(starting_edge) = starting_edge {
Self {
diagram_: diagram,
start_edge: starting_edge,
next_edge: Some(starting_edge),
}
} else {
Self {
diagram_: diagram,
start_edge: EdgeIndex(0),
next_edge: None,
}
}
}
}
impl<'s, F: OutputType> Iterator for EdgeRotPrevIterator<'s, F> {
type Item = EdgeIndex;
fn next(&mut self) -> Option<EdgeIndex> {
let rv = self.next_edge;
let new_next_edge = self.diagram_.edge_rot_prev(self.next_edge);
self.next_edge = if let Some(nne) = new_next_edge {
if nne.0 == self.start_edge.0 {
None
} else {
new_next_edge
}
} else {
None
};
rv
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone)]
pub struct Vertex<F: OutputType> {
pub(crate) id_: VertexIndex,
pub(crate) x_: F,
pub(crate) y_: F,
pub(crate) incident_edge_: Option<EdgeIndex>,
pub(crate) color_: ColorType,
}
impl<F: OutputType> fmt::Debug for Vertex<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"(id:{} x:{} y:{} ie:{} co:{})",
self.id_.0,
self.x_,
self.y_,
CT::format_id(self.incident_edge_.map(|x| x.0)),
self.color_
)
}
}
impl<F: OutputType> Vertex<F> {
pub fn new_3(id: VertexIndex, x: F, y: F, is_site_vertex: bool) -> Rc<cell::Cell<Vertex<F>>> {
let color = if is_site_vertex {
ColorBits::SITE_VERTEX__BIT.0
} else {
ColorBits::ZERO.0
};
Rc::new(cell::Cell::new(Self {
id_: id,
x_: x,
y_: y,
incident_edge_: None,
color_: color,
}))
}
fn vertex_equality_predicate_eq(&self, other: &Self) -> bool {
let ulp = 128;
let x1: f64 = NumCast::from(self.x()).unwrap();
let y1: f64 = NumCast::from(self.y()).unwrap();
let x2: f64 = NumCast::from(other.x()).unwrap();
let y2: f64 = NumCast::from(other.y()).unwrap();
CT::ulp_comparison(x1, x2, ulp) == Ordering::Equal
&& CT::ulp_comparison(y1, y2, ulp) == Ordering::Equal
}
pub fn get_id(&self) -> VertexIndex {
self.id_
}
#[inline]
#[cfg(feature = "console_debug")]
pub(crate) fn get_incident_edge_(&self) -> Option<EdgeIndex> {
self.incident_edge_
}
#[inline]
pub fn get_incident_edge(&self) -> Result<EdgeIndex, BvError> {
self.incident_edge_.ok_or_else(|| {
BvError::InternalError("Vertex didn't have an incident_edge".to_string())
})
}
#[inline]
pub fn x(&self) -> F {
self.x_
}
#[inline]
pub fn y(&self) -> F {
self.y_
}
pub fn get_color(&self) -> ColorType {
self.color_ >> ColorBits::RESERVED_BITS__SHIFT.0
}
pub fn set_color(&mut self, color: ColorType) -> ColorType {
self.color_ &= ColorBits::RESERVED__MASK.0;
self.color_ |= color << ColorBits::RESERVED_BITS__SHIFT.0;
self.color_
}
#[inline(always)]
pub fn or_color(&mut self, color: ColorType) -> ColorType {
self.set_color(self.get_color() | color)
}
#[inline]
pub fn is_site_point(&self) -> bool {
(self.color_ & ColorBits::SITE_VERTEX__BIT.0) != 0
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone)]
pub struct Edge {
id_: EdgeIndex,
cell_: Option<CellIndex>,
vertex_: Option<VertexIndex>,
twin_: Option<EdgeIndex>,
next_ccw_: Option<EdgeIndex>,
prev_ccw_: Option<EdgeIndex>,
color_: ColorType,
}
impl fmt::Debug for Edge {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"id:{} cell:{} v0:{} t:{} n:{} p:{} c:{}",
self.id_.0,
CT::format_id(self.cell_.map(|c| c.0)),
CT::format_id(self.vertex_.map(|v| v.0)),
CT::format_id(self.twin_.map(|e| e.0)),
CT::format_id(self.next_ccw_.map(|e| e.0)),
CT::format_id(self.prev_ccw_.map(|e| e.0)),
self.color_
)
}
}
impl Edge {
const BIT_IS_LINEAR: ColorType = 0x1; const BIT_IS_PRIMARY: ColorType = 0x2;
fn new_(id: EdgeIndex, cell: CellIndex, is_linear: bool, is_primary: bool) -> EdgeType {
let mut rv = Self {
id_: id,
cell_: Some(cell),
vertex_: None,
twin_: None,
next_ccw_: None,
prev_ccw_: None,
color_: 0,
};
if is_linear {
rv.color_ |= Self::BIT_IS_LINEAR;
}
if is_primary {
rv.color_ |= Self::BIT_IS_PRIMARY;
}
Rc::from(cell::Cell::from(rv))
}
pub fn id(&self) -> EdgeIndex {
self.id_
}
pub(crate) fn cell_(&self) -> Option<CellIndex> {
self.cell_
}
pub fn cell(&self) -> Result<CellIndex, BvError> {
self.cell_.ok_or_else(|| {
BvError::ValueError("Edge didn't have any valid cell associated to it.".to_string())
})
}
pub fn vertex0(&self) -> Option<VertexIndex> {
self.vertex_
}
pub(crate) fn twin_(&self) -> Option<EdgeIndex> {
self.twin_
}
pub fn twin(&self) -> Result<EdgeIndex, BvError> {
self.twin_.ok_or_else(|| {
BvError::ValueError(
"Edge didn't have any valid twin edge associated to it.".to_string(),
)
})
}
pub(crate) fn next_(&self) -> Option<EdgeIndex> {
self.next_ccw_
}
pub fn next(&self) -> Result<EdgeIndex, BvError> {
self.next_ccw_.ok_or_else(|| {
BvError::ValueError(format!(
"Edge {} didn't have any valid next edge associated to it. {}:{}",
self.id_.0,
file!(),
line!()
))
})
}
pub(crate) fn prev_(&self) -> Option<EdgeIndex> {
self.prev_ccw_
}
pub fn prev(&self) -> Result<EdgeIndex, BvError> {
self.prev_().ok_or_else(|| {
BvError::InternalError("The edge does not have a previous edge".to_string())
})
}
#[inline]
pub fn is_linear(&self) -> bool {
(self.color_ & Self::BIT_IS_LINEAR) != 0
}
#[inline]
pub fn is_curved(&self) -> bool {
!self.is_linear()
}
#[inline]
pub fn is_primary(&self) -> bool {
(self.color_ & Self::BIT_IS_PRIMARY) != 0
}
#[inline]
pub fn is_secondary(&self) -> bool {
!self.is_primary()
}
#[inline(always)]
pub fn get_color(&self) -> ColorType {
self.color_ >> ColorBits::RESERVED_BITS__SHIFT.0
}
#[inline(always)]
pub fn set_color(&mut self, color: ColorType) -> ColorType {
self.color_ &= ColorBits::RESERVED__MASK.0;
self.color_ |= color << ColorBits::RESERVED_BITS__SHIFT.0;
self.color_
}
#[inline(always)]
pub fn or_color(&mut self, color: ColorType) -> ColorType {
self.set_color(self.get_color() | color)
}
}
pub type CellType = Rc<cell::Cell<Cell>>;
pub type EdgeType = Rc<cell::Cell<Edge>>;
pub type VertexType<F> = Rc<cell::Cell<Vertex<F>>>;
#[derive(Default, Debug)]
pub struct Diagram<F: OutputType> {
cells_: Vec<CellType>, vertices_: Vec<VertexType<F>>, edges_: Vec<EdgeType>, }
impl<F: OutputType> Diagram<F> {
pub(crate) fn new(input_size: usize) -> Self {
Self {
cells_: Vec::<CellType>::with_capacity(input_size),
vertices_: Vec::<VertexType<F>>::with_capacity(input_size),
edges_: Vec::<EdgeType>::with_capacity(input_size * 2),
}
}
pub fn clear(&mut self) {
self.cells_.clear();
self.vertices_.clear();
self.edges_.clear();
}
#[inline(always)]
pub fn cells(&self) -> &Vec<CellType> {
&self.cells_
}
#[inline(always)]
pub fn vertices(&self) -> &Vec<VertexType<F>> {
&self.vertices_
}
#[inline(always)]
pub fn vertices_get_aabb<I: InputType>(&self) -> VU::Aabb2<F> {
let mut rv = VU::Aabb2::<F>::default();
for v in self.vertices_.iter() {
let v = v.get();
rv.update_vertex(v.x(), v.y());
}
rv
}
#[inline(always)]
pub fn edges(&self) -> &Vec<EdgeType> {
&self.edges_
}
#[inline(always)]
pub fn get_cell(&self, cell_id: CellIndex) -> Result<Rc<cell::Cell<Cell>>, BvError> {
Ok(Rc::clone(self.cells_.get(cell_id.0).ok_or_else(|| {
BvError::IdError(format!("The cell with id:{} does not exist", cell_id.0))
})?))
}
#[inline(always)]
pub(crate) fn get_edge_(&self, edge_id: Option<EdgeIndex>) -> Option<EdgeType> {
let edge_id = edge_id?;
self.edges_.get(edge_id.0).map(Rc::clone)
}
pub fn get_edge(&self, edge_id: EdgeIndex) -> Result<EdgeType, BvError> {
if let Some(edge) = self.edges_.get(edge_id.0) {
Ok(Rc::clone(edge))
} else {
Err(BvError::IdError(format!(
"The edge with id:{} does not exist",
edge_id.0
)))
}
}
pub(crate) fn edge_as_line_(&self, edge: Option<EdgeIndex>) -> Option<[F; 4]> {
let v0 = self.vertex_get_(self.edge_get_vertex0_(edge));
let v1 = self.vertex_get_(self.edge_get_vertex1_(edge));
if let Some(v0) = v0 {
if let Some(v1) = v1 {
let v0 = v0.get();
let v1 = v1.get();
return Some([v0.x(), v0.y(), v1.x(), v1.y()]);
}
}
None
}
#[inline]
pub fn edge_as_line(&self, edge_id: EdgeIndex) -> Result<[F; 4], BvError> {
self.edge_as_line_(Some(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(&self, external_color: ColorType) {
for it in self.edges().iter() {
let edge_id = Some(it.get().id());
if !self.edge_is_finite_(edge_id).unwrap() {
self.recurse_color_exterior(edge_id, external_color);
}
}
}
fn recurse_color_exterior(&self, edge_id: Option<EdgeIndex>, external_color: ColorType) {
if edge_id.is_none() || (self.edge_get_color_(edge_id).unwrap() & external_color) != 0 {
return;
}
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() {
return;
}
self.edge_or_color_(self.edge_get_twin_(edge_id), external_color);
if v1.is_none()
|| self.vertex_is_site_point_(v1).unwrap_or(true)
|| !self
.get_edge_(edge_id)
.map_or(false, |x| x.get().is_primary())
{
return;
}
self.vertex_set_color_(v1, external_color);
let incident_edge = self.vertex_get_incident_edge(v1);
for e in self.edge_rot_next_iterator(incident_edge) {
self.recurse_color_exterior(Some(e), external_color);
}
}
#[deprecated(since = "0.10.3", note = "please use `.cells().iter()` instead")]
pub fn cell_iter(&self) -> core::slice::Iter<'_, CellType> {
self.cells_.iter()
}
#[deprecated(since = "0.10.3", note = "please use `.vertices().iter()` instead")]
pub fn vertex_iter(&self) -> core::slice::Iter<'_, VertexType<F>> {
self.vertices_.iter()
}
#[deprecated(since = "0.10.3", note = "please use `.edges().iter()` instead")]
pub fn edge_iter(&self) -> std::slice::Iter<'_, EdgeType> {
self.edges_.iter()
}
fn make_new_cell_with_category_(
&mut self,
cell_id: CellIndex, initial_index: SourceIndex,
sc: ColorBits,
) -> CellIndex {
while self.cells_.len() < cell_id.0 {
self.cells_.push(Rc::new(cell::Cell::new(Cell::new(
CellIndex(usize::MAX),
usize::MAX,
ColorBits::TEMPORARY_CELL.0,
))));
}
self.cells_.push(Rc::new(cell::Cell::new(Cell::new(
cell_id,
initial_index,
sc.0,
))));
#[cfg(feature = "console_debug")]
assert_eq!(self.cells_[cell_id.0].get().id().0, cell_id.0);
let ccell = &self.cells_[cell_id.0];
{
let cell = ccell.get();
#[cfg(feature = "console_debug")]
{
assert_eq!(cell.id_.0, cell_id.0);
assert_eq!(cell.source_index_, initial_index);
assert_eq!(cell.color_, sc.0);
}
ccell.set(cell);
}
cell_id
}
pub fn num_cells(&self) -> usize {
self.cells_.len()
}
pub fn num_edges(&self) -> usize {
self.edges_.len()
}
pub fn num_vertices(&self) -> usize {
self.vertices_.len()
}
pub fn reserve_(&mut self, additional_sites: usize) {
self.cells_.reserve(additional_sites);
self.vertices_.reserve(additional_sites << 1);
self.edges_
.reserve((additional_sites << 2) + (additional_sites << 1));
}
pub(crate) fn process_single_site_<I: InputType>(&mut self, site: &VSE::SiteEvent<I, F>) {
let _ = self.make_new_cell_with_category_(
CellIndex(site.sorted_index()),
site.initial_index(),
site.source_category(),
);
}
#[inline]
fn cell_get_(&self, cell_id: Option<CellIndex>) -> Option<&CellType> {
let _ = cell_id?;
self.cells_.get(cell_id.unwrap().0)
}
fn cell_set_incident_edge_(&self, cell_id: Option<CellIndex>, edge: Option<EdgeIndex>) {
if cell_id.is_none() {
return;
}
if let Some(cell) = self.cell_get_(cell_id) {
let mut c = cell.get();
c.incident_edge_ = edge;
cell.set(c)
}
}
fn cell_get_incident_edge_(&self, cell_id: Option<CellIndex>) -> Option<EdgeIndex> {
let _ = cell_id?;
if let Some(cell) = self.cell_get_(cell_id) {
return cell.get().incident_edge_;
}
None
}
fn cell_is_degenerate_(&self, cell_id: Option<CellIndex>) -> bool {
if cell_id.is_none() {
return false;
}
if let Some(cell) = self.cell_get_(cell_id) {
return cell.get().is_degenerate();
}
false
}
pub fn cell_edge_iterator(&self, cell_id: CellIndex) -> EdgeNextIterator<'_, F> {
self.cell_edge_iterator_(Some(cell_id))
}
fn cell_edge_iterator_(&self, cell_id: Option<CellIndex>) -> EdgeNextIterator<'_, F> {
let incident_edge = self.cell_get_incident_edge_(cell_id);
EdgeNextIterator::<'_, F>::new(self, incident_edge)
}
#[inline]
pub(crate) fn vertex_get_(&self, vertex_id: Option<VertexIndex>) -> Option<&VertexType<F>> {
let _ = vertex_id?;
self.vertices_.get(vertex_id.unwrap().0)
}
#[inline]
pub fn vertex_get(&self, vertex_id: VertexIndex) -> Result<&VertexType<F>, BvError> {
self.vertex_get_(Some(vertex_id))
.ok_or_else(|| BvError::IdError(format!("Vertex id {} does not exists.", vertex_id.0)))
}
#[inline]
pub(crate) fn vertex_or_color_(&self, vertex_id: Option<VertexIndex>, color: ColorType) {
if vertex_id.is_none() {
return;
}
if let Some(vertexcell) = self.vertex_get_(vertex_id) {
let mut vertex = vertexcell.get();
let _ = vertex.or_color(color);
vertexcell.set(vertex);
}
}
#[inline]
pub fn vertex_or_color(&self, vertex_id: VertexIndex, color: ColorType) {
self.vertex_or_color_(Some(vertex_id), color)
}
pub fn vertex_get_color(&self, vertex_id: Option<VertexIndex>) -> Option<ColorType> {
let _ = vertex_id?;
if let Some(vertexcell) = self.vertex_get_(vertex_id) {
let vertex = vertexcell.get();
return Some(vertex.get_color());
}
None
}
fn vertex_copy_(&self, dest: usize, source: usize) {
let mut v = self.vertices_[source].get();
v.id_ = VertexIndex(dest);
self.vertices_[dest].set(v);
}
fn vertex_set_incident_edge_(&self, vertex_id: Option<VertexIndex>, edge: Option<EdgeIndex>) {
if vertex_id.is_none() {
return;
}
if let Some(vertex) = self.vertex_get_(vertex_id) {
let mut c = vertex.get();
c.incident_edge_ = edge;
vertex.set(c)
}
}
pub fn vertex_get_incident_edge(&self, vertex_id: Option<VertexIndex>) -> Option<EdgeIndex> {
let _ = vertex_id?;
self.vertex_get_(vertex_id)
.and_then(|x| x.get().incident_edge_)
}
pub(crate) fn vertex_set_color_(&self, vertex_id: Option<VertexIndex>, color: ColorType) {
if let Some(vertex_cell) = self.vertex_get_(vertex_id) {
let mut vertex = vertex_cell.get();
let _ = vertex.set_color(color);
vertex_cell.set(vertex);
}
}
pub fn vertex_set_color(
&self,
vertex_id: VertexIndex,
color: ColorType,
) -> Result<(), BvError> {
self.vertex_set_color_(Some(vertex_id), color);
Ok(())
}
#[inline]
pub(crate) fn vertex_is_site_point_(&self, vertex_id: Option<VertexIndex>) -> Option<bool> {
let _ = vertex_id?;
self.vertex_get_(vertex_id)
.map(|cell| cell.get().is_site_point())
}
#[inline]
pub fn vertex_is_site_point(&self, vertex_id: VertexIndex) -> Result<bool, BvError> {
self.vertex_is_site_point_(Some(vertex_id)).ok_or_else(|| {
BvError::IdError(format!(
"Vertex id {} (probably) does not exists",
vertex_id.0
))
})
}
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());
let new_edge = Edge::new_(new_edge_id, cell_id, is_linear, is_primary);
let _ = self.edges_.push(new_edge);
tln!("Created and inserted new edge : e={}", new_edge_id.0);
new_edge_id
}
#[inline]
pub(crate) fn edge_get_(&self, edge_id: Option<EdgeIndex>) -> Option<&EdgeType> {
let rv = self.edges_.get(edge_id?.0);
debug_assert!({
if rv.is_none() {
dbg!(edge_id.unwrap().0);
panic!();
};
true
});
rv
}
pub(crate) fn edge_copy_(&self, dest: usize, source: usize) {
let mut e = self.edges_[source].get();
e.id_ = EdgeIndex(dest);
self.edges_[dest].set(e);
}
#[inline]
pub(crate) fn edge_get_color_(&self, edge_id: Option<EdgeIndex>) -> Option<ColorType> {
let _ = edge_id?;
if let Some(edgecell) = self.edge_get_(edge_id) {
let edge = edgecell.get();
return Some(edge.get_color());
}
None
}
#[inline]
pub fn edge_get_color(&self, edge_id: EdgeIndex) -> Result<ColorType, BvError> {
self.edge_get_color_(Some(edge_id)).ok_or_else(|| {
BvError::IdError(format!("edge id {} (probably) does not exists", edge_id.0))
})
}
#[inline]
pub(crate) fn edge_set_color_(&self, edge_id: Option<EdgeIndex>, color: ColorType) {
if edge_id.is_none() {
return;
}
if let Some(edgecell) = self.edge_get_(edge_id) {
let mut edge = edgecell.get();
let _ = edge.set_color(color);
edgecell.set(edge);
}
}
#[inline]
pub fn edge_set_color(&self, edge_id: EdgeIndex, color: ColorType) -> Result<(), BvError> {
self.edge_set_color_(Some(edge_id), color);
Ok(())
}
#[inline]
pub(crate) fn edge_or_color_(&self, edge_id: Option<EdgeIndex>, color: ColorType) {
if edge_id.is_none() {
return;
}
if let Some(edgecell) = self.edge_get_(edge_id) {
let mut edge = edgecell.get();
let _ = edge.or_color(color);
edgecell.set(edge);
}
}
#[inline]
pub fn edge_or_color(&self, edge_id: EdgeIndex, color: ColorType) -> Result<(), BvError> {
self.edge_or_color_(Some(edge_id), color);
Ok(())
}
#[inline]
pub(crate) fn edge_set_twin_(&self, edge_id: Option<EdgeIndex>, twin_id: Option<EdgeIndex>) {
if edge_id.is_none() {
return;
}
if let Some(edgecell) = self.edge_get_(edge_id) {
let mut edge = edgecell.get();
edge.twin_ = twin_id;
edgecell.set(edge);
}
}
#[inline]
pub fn edge_rot_next_iterator(&self, edge_id: Option<EdgeIndex>) -> EdgeRotNextIterator<'_, F> {
EdgeRotNextIterator::new(self, edge_id)
}
#[inline]
pub fn edge_rot_prev_iterator(&self, edge_id: Option<EdgeIndex>) -> EdgeRotPrevIterator<'_, F> {
EdgeRotPrevIterator::new(self, edge_id)
}
#[inline]
pub(crate) fn edge_get_twin_(&self, edge_id: Option<EdgeIndex>) -> Option<EdgeIndex> {
let _ = edge_id?;
if let Some(edgecell) = self.edge_get_(edge_id) {
return edgecell.get().twin_();
}
None
}
#[inline]
pub fn edge_get_twin(&self, edge_id: EdgeIndex) -> Result<EdgeIndex, BvError> {
self.edge_get_twin_(Some(edge_id))
.ok_or_else(|| BvError::IdError(format!("Edge {} does not have a twin", edge_id.0)))
}
#[inline]
pub fn edge_get_next(&self, edge_id: EdgeIndex) -> Result<EdgeIndex, BvError> {
self.edge_get_next_(Some(edge_id)).ok_or_else(|| {
BvError::IdError(format!("Edge {} did not have any next edge", edge_id.0))
})
}
#[inline]
fn edge_set_cell_(&self, edge_id: Option<EdgeIndex>, cell_id: Option<CellIndex>) {
if edge_id.is_none() {
return;
}
if let Some(edgecell) = self.edge_get_(edge_id) {
let mut edge = edgecell.get();
edge.cell_ = cell_id;
edgecell.set(edge);
}
}
#[inline]
fn edge_get_cell_(&self, edge_id: Option<EdgeIndex>) -> Option<CellIndex> {
let _ = edge_id?;
self.edge_get_(edge_id)?.get().cell_()
}
#[inline]
pub fn edge_get_cell(&self, edge_id: EdgeIndex) -> Result<CellIndex, BvError> {
self.edge_get_cell_(Some(edge_id)).ok_or_else(|| {
BvError::IdError(format!(
"Either the edge id:{} or the cell didn't exists",
edge_id.0
))
})
}
#[inline]
pub(crate) fn edge_is_finite_(&self, edge_id: Option<EdgeIndex>) -> Option<bool> {
let _ = edge_id?;
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_(Some(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: Option<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_(Some(edge_id))
.ok_or_else(|| BvError::IdError(format!("Edge id {} doesn't exists", edge_id.0)))
}
fn remove_edge_(&mut self, edge: Option<EdgeIndex>) {
#[cfg(feature = "console_debug")]
if let Some(edge_id) = edge {
tln!("removing edge: {}", edge_id.0);
} else {
tln!("removing edge: but it was None!");
return;
}
let vertex = self.edge_get_vertex0_(edge);
let mut updated_edge = self.edge_rot_next_(self.edge_get_twin_(edge));
while updated_edge != self.edge_get_twin_(edge) {
self.edge_set_vertex0_(updated_edge, vertex);
updated_edge = self.edge_rot_next_(updated_edge);
}
let edge1 = edge;
let edge2 = self.edge_get_twin_(edge);
self.edge_set_next_(
self.edge_get_twin_(self.edge_rot_next_(edge1)),
self.edge_rot_prev(edge2),
);
self.edge_set_prev_(
self.edge_rot_prev(edge2),
self.edge_get_twin_(self.edge_rot_next_(edge1)),
);
self.edge_set_prev_(
self.edge_rot_prev(edge1),
self.edge_get_twin_(self.edge_rot_next_(edge2)),
);
self.edge_set_next_(
self.edge_get_twin_(self.edge_rot_next_(edge2)),
self.edge_rot_prev(edge1),
);
}
fn vertex_new_2_(&mut self, x: F, y: F, is_site_vertex: bool) -> VertexIndex {
let new_vertex_id = VertexIndex(self.vertices_.len());
let new_edge = Vertex::new_3(new_vertex_id, x, y, is_site_vertex);
let _ = self.vertices_.push(new_edge);
#[cfg(feature = "console_debug")]
assert_eq!(self.vertices_.len() - 1, new_vertex_id.0);
new_vertex_id
}
fn edge_set_vertex0_(&self, edge_id: Option<EdgeIndex>, vertex_id: Option<VertexIndex>) {
if edge_id.is_none() {
return;
}
if let Some(edgecell) = self.edge_get_(edge_id) {
let mut edge = edgecell.get();
edge.vertex_ = vertex_id;
edgecell.set(edge);
}
}
#[inline]
pub(crate) fn edge_get_vertex0_(&self, edge_id: Option<EdgeIndex>) -> Option<VertexIndex> {
let _ = edge_id?;
self.edge_get_(edge_id).and_then(|x| x.get().vertex0())
}
#[inline]
pub fn edge_get_vertex0(&self, edge_id: EdgeIndex) -> Result<Option<VertexIndex>, BvError> {
Ok(self.edge_get_vertex0_(Some(edge_id)))
}
#[inline]
pub(crate) fn edge_get_vertex1_(&self, edge_id: Option<EdgeIndex>) -> Option<VertexIndex> {
let _ = edge_id?;
let twin = self.edge_get_twin_(edge_id);
self.edge_get_vertex0_(twin)
}
#[inline]
pub fn edge_get_vertex1(&self, edge_id: EdgeIndex) -> Result<Option<VertexIndex>, BvError> {
Ok(self.edge_get_vertex1_(Some(edge_id)))
}
#[inline]
fn edge_set_prev_(&self, edge_id: Option<EdgeIndex>, prev_id: Option<EdgeIndex>) {
if edge_id.is_none() {
return;
}
if let Some(edgecell) = self.edge_get_(edge_id) {
let mut edge = edgecell.get();
edge.prev_ccw_ = prev_id;
edgecell.set(edge);
}
}
#[inline]
fn edge_set_next_(&self, edge_id: Option<EdgeIndex>, next_id: Option<EdgeIndex>) {
if edge_id.is_none() {
return;
}
if let Some(edgecell) = self.edge_get_(edge_id) {
let mut edge = edgecell.get();
edge.next_ccw_ = next_id;
edgecell.set(edge);
}
}
#[inline]
fn edge_get_next_(&self, edge_id: Option<EdgeIndex>) -> Option<EdgeIndex> {
let _ = edge_id?;
self.edges_
.get(edge_id.unwrap().0)
.and_then(|x| x.get().next_())
}
#[inline]
fn edge_get_prev_(&self, edge_id: Option<EdgeIndex>) -> Option<EdgeIndex> {
let _ = edge_id?;
self.edges_
.get(edge_id.unwrap().0)
.and_then(|x| x.get().prev_())
}
#[inline]
pub(crate) fn edge_rot_next_(&self, edge_id: Option<EdgeIndex>) -> Option<EdgeIndex> {
let _ = edge_id?;
let prev = self.edge_get_prev_(edge_id);
self.edge_get_twin_(prev)
}
#[inline]
pub fn edge_rot_next(&self, edge_id: EdgeIndex) -> Result<EdgeIndex, BvError> {
self.edge_rot_next_(Some(edge_id)).ok_or_else(|| {
BvError::IdError(format!("Edge id {} (probably) doesn't exists", edge_id.0))
})
}
#[inline]
pub fn edge_rot_prev(&self, edge_id: Option<EdgeIndex>) -> Option<EdgeIndex> {
let _ = edge_id?;
let twin = self.edge_get_twin_(edge_id);
self.edge_get_next_(twin)
}
pub(crate) fn insert_new_edge_2_<I: InputType>(
&mut self,
site1: VSE::SiteEvent<I, F>,
site2: VSE::SiteEvent<I, F>,
) -> (EdgeIndex, EdgeIndex) {
let site1_index = site1.sorted_index();
let site2_index = site2.sorted_index();
let is_linear = VSE::SiteEvent::is_linear_edge(&site1, &site2);
let is_primary = VSE::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),
site1.initial_index(),
site1.source_category(),
);
}
let _ = self.make_new_cell_with_category_(
CellIndex(site2_index),
site2.initial_index(),
site2.source_category(),
);
self.edge_set_cell_(Some(edge1_id), Some(CellIndex(site1_index)));
self.edge_set_cell_(Some(edge2_id), Some(CellIndex(site2_index)));
self.edge_set_twin_(Some(edge1_id), Some(edge2_id));
self.edge_set_twin_(Some(edge2_id), Some(edge1_id));
(edge1_id, edge2_id)
}
pub(crate) fn insert_new_edge_5_<I: InputType>(
&mut self,
site1: VSE::SiteEvent<I, F>,
site3: VSE::SiteEvent<I, F>,
circle: &VC::CircleEvent,
edge12_id: EdgeIndex,
edge23_id: EdgeIndex,
) -> (EdgeIndex, EdgeIndex) {
tln!("new vertex@{:?}", circle);
let is_linear = VSE::SiteEvent::<I, F>::is_linear_edge(&site1, &site3);
let is_primary = VSE::SiteEvent::<I, F>::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_(
cast::<f64, F>(circle.x()),
cast::<f64, F>(circle.y()),
circle.is_site_point(),
);
self.edge_set_vertex0_(Some(edge12_id), Some(new_vertex_id));
self.edge_set_vertex0_(Some(edge23_id), Some(new_vertex_id));
self.edge_set_twin_(Some(new_edge1_id), Some(new_edge2_id));
self.edge_set_twin_(Some(new_edge2_id), Some(new_edge1_id));
self.edge_set_vertex0_(Some(new_edge2_id), Some(new_vertex_id));
self.edge_set_prev_(Some(edge12_id), Some(new_edge1_id));
self.edge_set_next_(Some(new_edge1_id), Some(edge12_id));
let edge12_twin_id = self.edge_get_twin_(Some(edge12_id));
self.edge_set_next_(edge12_twin_id, Some(edge23_id));
self.edge_set_prev_(Some(edge23_id), edge12_twin_id);
let edge23_twin_id = self.edge_get_twin_(Some(edge23_id));
self.edge_set_next_(edge23_twin_id, Some(new_edge2_id));
self.edge_set_prev_(Some(new_edge2_id), edge23_twin_id);
(new_edge1_id, new_edge2_id)
}
pub(crate) fn finish(&mut self) {
#[cfg(feature = "console_debug")]
self.debug_print_edges("b4 degenerate");
if !self.edges_.is_empty() {
let mut last_edge: usize = 0;
let mut it: usize = last_edge;
let edges_end: usize = self.edges_.len();
while it < edges_end {
let is_equal = {
let v1 = self.edge_get_vertex0_(Some(EdgeIndex(it)));
let v1 = self.vertex_get_(v1);
let v2 = self.edge_get_vertex1_(Some(EdgeIndex(it)));
let v2 = self.vertex_get_(v2);
v1.is_some()
&& v2.is_some()
&& v1
.unwrap()
.get()
.vertex_equality_predicate_eq(&v2.unwrap().get())
};
if is_equal {
self.remove_edge_(Some(EdgeIndex(it)));
} else {
if it != last_edge {
self.edge_copy_(last_edge, it);
self.edge_copy_(last_edge + 1, it + 1);
let e1 = Some(EdgeIndex(last_edge));
let e2 = Some(EdgeIndex(last_edge + 1));
self.edge_set_twin_(e1, e2);
self.edge_set_twin_(e2, e1);
if self.edge_get_prev_(e1).is_some() {
self.edge_set_next_(self.edge_get_prev_(e1), e1);
self.edge_set_prev_(self.edge_get_next_(e2), e2);
}
if self.edge_get_prev_(e2).is_some() {
self.edge_set_prev_(self.edge_get_next_(e1), e1);
self.edge_set_next_(self.edge_get_prev_(e2), e2);
}
}
last_edge += 2;
}
it += 2;
}
for e in (last_edge..edges_end).rev() {
let _ = self.edges_.remove(e);
}
}
#[cfg(feature = "console_debug")]
self.debug_print_edges("after degenerate");
tln!();
for edge_it in self.edges().iter().enumerate().map(|x| EdgeIndex(x.0)) {
let cell = self.edge_get_cell_(Some(edge_it));
if self.cell_get_incident_edge_(cell).is_none() {
self.cell_set_incident_edge_(cell, Some(edge_it));
}
let vertex = self.edge_get_vertex0_(Some(edge_it));
self.vertex_set_incident_edge_(vertex, Some(edge_it));
}
#[cfg(feature = "console_debug")]
for (i, v) in self.vertices_.iter().enumerate() {
tln!(
"vertex #{} contains a point: ({:.12}, {:.12}) ie:{}",
i,
v.get().x(),
v.get().y(),
v.get()
.get_incident_edge_()
.map_or("-".to_string(), |x| x.0.clone().to_string())
);
}
tln!("vertices b4 degenerate {}", self.vertices_.len());
if !self.vertices_.is_empty() {
let mut last_vertex_iterator = (0..self.vertices_.len()).map(VertexIndex);
let mut last_vertex = last_vertex_iterator.next();
for it in (0..self.vertices_.len()).map(VertexIndex) {
let it = Some(it);
if self.vertex_get_incident_edge(it).is_some() {
if it != last_vertex {
self.vertex_copy_(last_vertex.unwrap().0, it.unwrap().0);
let v = last_vertex;
let mut e = self.vertex_get_incident_edge(last_vertex);
loop {
self.edge_set_vertex0_(e, v);
e = self.edge_rot_next_(e);
if self.vertex_get_incident_edge(v) == e {
break;
}
}
}
last_vertex = last_vertex_iterator.next();
}
}
if let Some(last_vertex) = last_vertex {
for v in (last_vertex.0..self.vertices_.len()).rev() {
let _ = self.vertices_.remove(v);
}
}
}
tln!("vertices after degenerate {}", self.vertices_.len());
if self.vertices_.is_empty() {
if !self.edges_.is_empty() {
let mut edge_it = self.edges_.iter().enumerate().map(|x| x.0);
let mut edge1 = edge_it.next().map(EdgeIndex);
self.edge_set_next_(edge1, edge1);
self.edge_set_prev_(edge1, edge1);
edge1 = edge_it.next().map(EdgeIndex);
let mut edge_it_value = edge_it.next();
while edge_it_value.is_some() {
let edge2 = edge_it_value.map(EdgeIndex);
edge_it_value = edge_it.next();
self.edge_set_next_(edge1, edge2);
self.edge_set_prev_(edge1, edge2);
self.edge_set_next_(edge2, edge1);
self.edge_set_prev_(edge2, edge1);
edge1 = edge_it_value.map(EdgeIndex);
edge_it_value = edge_it.next();
}
self.edge_set_next_(edge1, edge1);
self.edge_set_prev_(edge1, edge1);
}
} else {
for cell_it in 0..self.cells_.len() {
if self.cell_is_degenerate_(Some(CellIndex(cell_it))) {
continue;
}
let mut left_edge = self.cell_get_incident_edge_(Some(CellIndex(cell_it)));
let terminal_edge = left_edge;
while let Some(new_left_edge) = self.edge_get_prev_(left_edge) {
left_edge = Some(new_left_edge);
if left_edge == terminal_edge {
break;
}
}
if self.edge_get_prev_(left_edge).is_some() {
continue;
}
let mut right_edge = self.cell_get_incident_edge_(Some(CellIndex(cell_it)));
while let Some(new_right_edge) = self.edge_get_next_(right_edge) {
right_edge = Some(new_right_edge);
}
self.edge_set_prev_(left_edge, right_edge);
self.edge_set_next_(right_edge, left_edge);
}
}
}
#[cfg(feature = "console_debug")]
pub fn debug_print_all<FN: Fn(usize) -> bool>(&self, edge_filter: FN) {
tln!();
tln!("output:");
for (i, c) in self.cells_.iter().enumerate() {
let cc = c.get();
print!("cell#{} {:?} ", i, &cc);
if cc.contains_point() {
tln!("point");
} else if cc.contains_segment() {
tln!("segment");
} else if cc.contains_segment_startpoint() {
tln!("startpoint");
} else if cc.contains_segment_endpoint() {
tln!("endpoint");
} else {
tln!();
}
}
for (i, v) in self.vertices_.iter().enumerate() {
assert_eq!(i, v.get().id_.0);
let edges1: Vec<usize> = self
.edge_rot_next_iterator(v.get().get_incident_edge_())
.map(|x| x.0)
.filter(|x| edge_filter(*x))
.collect();
let edges2: Vec<usize> = self
.edge_rot_next_iterator(v.get().get_incident_edge_())
.map(|x| self.edge_get_twin_(Some(x)))
.flatten()
.map(|x| x.0)
.filter(|x| edge_filter(*x))
.collect();
t!("vertex#{} {:?}", i, &v.get());
t!(" outgoing edges:{:?}", edges1);
tln!(" incoming edges:{:?}", edges2);
}
}
#[cfg(feature = "console_debug")]
pub fn debug_print_edges(&self, text: &str) {
tln!("edges {} {}", text, self.edges_.len());
for (i, e) in self.edges_.iter().enumerate() {
let e = e.get();
tln!("edge{} ({:?})", e.id_.0, &e);
assert_eq!(i, e.id_.0);
}
}
}
impl<F: OutputType> From<Diagram<F>> for SD::SyncDiagram<F> {
fn from(other: Diagram<F>) -> SD::SyncDiagram<F> {
SD::SyncDiagram::new(
other.cells_.into_iter().map(|x| x.get()).collect(),
other.vertices_.into_iter().map(|x| x.get()).collect(),
other.edges_.into_iter().map(|x| x.get()).collect(),
)
}
}