mirror of https://codeberg.org/topola/topola.git
geometry: make graph private, encapsulate all mutating usage of it
This commit is contained in:
parent
410b029eb3
commit
39bd393ff7
|
|
@ -1,6 +1,8 @@
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
|
|
||||||
|
use petgraph::stable_graph::NodeIndex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{GenericIndex, GetNodeIndex},
|
graph::{GenericIndex, GetNodeIndex},
|
||||||
layout::{
|
layout::{
|
||||||
|
|
@ -16,7 +18,7 @@ use crate::{
|
||||||
math::Circle,
|
math::Circle,
|
||||||
};
|
};
|
||||||
|
|
||||||
use petgraph::stable_graph::NodeIndex;
|
use super::geometry::SetPos;
|
||||||
|
|
||||||
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
|
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
|
@ -46,7 +48,7 @@ impl TryFrom<GeometryIndex> for DotIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(GetPos, GetWidth)]
|
#[enum_dispatch(GetPos, SetPos, GetWidth)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum DotWeight {
|
pub enum DotWeight {
|
||||||
Fixed(FixedDotWeight),
|
Fixed(FixedDotWeight),
|
||||||
|
|
@ -91,6 +93,12 @@ impl GetPos for FixedDotWeight {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SetPos for FixedDotWeight {
|
||||||
|
fn set_pos(&mut self, pos: Point) {
|
||||||
|
self.circle.pos = pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GetWidth for FixedDotWeight {
|
impl GetWidth for FixedDotWeight {
|
||||||
fn width(&self) -> f64 {
|
fn width(&self) -> f64 {
|
||||||
self.circle.r * 2.0
|
self.circle.r * 2.0
|
||||||
|
|
@ -112,6 +120,12 @@ impl GetPos for LooseDotWeight {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SetPos for LooseDotWeight {
|
||||||
|
fn set_pos(&mut self, pos: Point) {
|
||||||
|
self.circle.pos = pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GetWidth for LooseDotWeight {
|
impl GetWidth for LooseDotWeight {
|
||||||
fn width(&self) -> f64 {
|
fn width(&self) -> f64 {
|
||||||
self.circle.r * 2.0
|
self.circle.r * 2.0
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,11 @@ pub trait GetPos {
|
||||||
fn pos(&self) -> Point;
|
fn pos(&self) -> Point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch]
|
||||||
|
pub trait SetPos {
|
||||||
|
fn set_pos(&mut self, pos: Point);
|
||||||
|
}
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait GetWidth {
|
pub trait GetWidth {
|
||||||
fn width(&self) -> f64;
|
fn width(&self) -> f64;
|
||||||
|
|
@ -41,7 +46,7 @@ pub enum GeometryLabel {
|
||||||
Core,
|
Core,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DotWeightTrait<GW>: GetPos + GetWidth + Into<GW> + Copy {}
|
pub trait DotWeightTrait<GW>: GetPos + SetPos + GetWidth + Into<GW> + Copy {}
|
||||||
pub trait SegWeightTrait<GW>: GetWidth + Into<GW> + Copy {}
|
pub trait SegWeightTrait<GW>: GetWidth + Into<GW> + Copy {}
|
||||||
pub trait BendWeightTrait<GW>: GetOffset + GetWidth + Into<GW> + Copy {}
|
pub trait BendWeightTrait<GW>: GetOffset + GetWidth + Into<GW> + Copy {}
|
||||||
|
|
||||||
|
|
@ -56,7 +61,7 @@ pub struct Geometry<
|
||||||
SI: GetNodeIndex + Into<GI> + Copy,
|
SI: GetNodeIndex + Into<GI> + Copy,
|
||||||
BI: GetNodeIndex + Into<GI> + Copy,
|
BI: GetNodeIndex + Into<GI> + Copy,
|
||||||
> {
|
> {
|
||||||
pub graph: StableDiGraph<GW, GeometryLabel, usize>,
|
graph: StableDiGraph<GW, GeometryLabel, usize>,
|
||||||
weight_marker: PhantomData<GW>,
|
weight_marker: PhantomData<GW>,
|
||||||
dot_weight_marker: PhantomData<DW>,
|
dot_weight_marker: PhantomData<DW>,
|
||||||
seg_weight_marker: PhantomData<SW>,
|
seg_weight_marker: PhantomData<SW>,
|
||||||
|
|
@ -140,6 +145,40 @@ impl<
|
||||||
bend
|
bend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, node: GI) {
|
||||||
|
self.graph.remove_node(node.node_index());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_dot(&mut self, dot: DI, to: Point) {
|
||||||
|
let mut weight = self.dot_weight(dot);
|
||||||
|
weight.set_pos(to);
|
||||||
|
*self.graph.node_weight_mut(dot.node_index()).unwrap() = weight.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn flip_bend(&mut self, bend: BI) {
|
||||||
|
let (from, to) = self.bend_joints(bend);
|
||||||
|
let from_edge_weight = self
|
||||||
|
.graph
|
||||||
|
.remove_edge(
|
||||||
|
self.graph
|
||||||
|
.find_edge(from.node_index(), bend.node_index())
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let to_edge_weight = self
|
||||||
|
.graph
|
||||||
|
.remove_edge(
|
||||||
|
self.graph
|
||||||
|
.find_edge(bend.node_index(), to.node_index())
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
self.graph
|
||||||
|
.update_edge(from.node_index(), bend.node_index(), to_edge_weight);
|
||||||
|
self.graph
|
||||||
|
.update_edge(bend.node_index(), to.node_index(), from_edge_weight);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reattach_bend(&mut self, bend: BI, maybe_new_inner: Option<BI>) {
|
pub fn reattach_bend(&mut self, bend: BI, maybe_new_inner: Option<BI>) {
|
||||||
if let Some(old_inner_edge) = self
|
if let Some(old_inner_edge) = self
|
||||||
.graph
|
.graph
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use crate::guide::Guide;
|
||||||
use crate::layout::bend::BendIndex;
|
use crate::layout::bend::BendIndex;
|
||||||
use crate::layout::dot::DotWeight;
|
use crate::layout::dot::DotWeight;
|
||||||
use crate::layout::geometry::{
|
use crate::layout::geometry::{
|
||||||
BendWeightTrait, DotWeightTrait, Geometry, GeometryLabel, SegWeightTrait,
|
BendWeightTrait, DotWeightTrait, Geometry, GeometryLabel, GetPos, SegWeightTrait,
|
||||||
};
|
};
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight},
|
bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight},
|
||||||
|
|
@ -188,7 +188,7 @@ impl Layout {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.remove_from_rtree(weight.retag(node.node_index()));
|
self.remove_from_rtree(weight.retag(node.node_index()));
|
||||||
self.geometry.graph.remove_node(node.node_index());
|
self.geometry.remove(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This method shouldn't be public.
|
// TODO: This method shouldn't be public.
|
||||||
|
|
@ -729,12 +729,6 @@ impl Layout {
|
||||||
.add_bend(from.into(), to.into(), core.into(), weight);
|
.add_bend(from.into(), to.into(), core.into(), weight);
|
||||||
self.geometry.reattach_bend(bend.into(), Some(inner));
|
self.geometry.reattach_bend(bend.into(), Some(inner));
|
||||||
|
|
||||||
self.geometry.graph.update_edge(
|
|
||||||
inner.node_index(),
|
|
||||||
bend.node_index(),
|
|
||||||
GeometryLabel::Outer,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.insert_into_rtree(bend.into());
|
self.insert_into_rtree(bend.into());
|
||||||
self.fail_and_remove_if_infringes_except(bend.into(), infringables)?;
|
self.fail_and_remove_if_infringes_except(bend.into(), infringables)?;
|
||||||
Ok(bend)
|
Ok(bend)
|
||||||
|
|
@ -744,15 +738,7 @@ impl Layout {
|
||||||
#[debug_ensures(self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
|
#[debug_ensures(self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
|
||||||
pub fn flip_bend(&mut self, bend: FixedBendIndex) {
|
pub fn flip_bend(&mut self, bend: FixedBendIndex) {
|
||||||
self.remove_from_rtree(bend.into());
|
self.remove_from_rtree(bend.into());
|
||||||
|
self.geometry.flip_bend(bend.into());
|
||||||
let Some(GeometryWeight::FixedBend(weight)) =
|
|
||||||
self.geometry.graph.node_weight_mut(bend.node_index())
|
|
||||||
else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
|
|
||||||
weight.cw = !weight.cw;
|
|
||||||
|
|
||||||
self.insert_into_rtree(bend.into());
|
self.insert_into_rtree(bend.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -821,32 +807,12 @@ impl Layout {
|
||||||
) -> Result<(), Infringement> {
|
) -> Result<(), Infringement> {
|
||||||
self.remove_from_rtree_with_limbs(dot.into());
|
self.remove_from_rtree_with_limbs(dot.into());
|
||||||
|
|
||||||
let mut weight = *self.geometry.graph.node_weight(dot.node_index()).unwrap();
|
let old_pos = self.geometry.dot_weight(dot).pos();
|
||||||
let old_weight = weight;
|
self.geometry.move_dot(dot, to);
|
||||||
|
|
||||||
match weight {
|
|
||||||
GeometryWeight::FixedDot(ref mut fixed) => {
|
|
||||||
fixed.circle.pos = to;
|
|
||||||
}
|
|
||||||
GeometryWeight::LooseDot(ref mut loose) => {
|
|
||||||
loose.circle.pos = to;
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
|
|
||||||
*self
|
|
||||||
.geometry
|
|
||||||
.graph
|
|
||||||
.node_weight_mut(dot.node_index())
|
|
||||||
.unwrap() = weight;
|
|
||||||
|
|
||||||
if let Some(infringement) = self.detect_infringement_except(dot.into(), infringables) {
|
if let Some(infringement) = self.detect_infringement_except(dot.into(), infringables) {
|
||||||
// Restore original state.
|
// Restore original state.
|
||||||
*self
|
self.geometry.move_dot(dot, old_pos);
|
||||||
.geometry
|
|
||||||
.graph
|
|
||||||
.node_weight_mut(dot.node_index())
|
|
||||||
.unwrap() = old_weight;
|
|
||||||
|
|
||||||
self.insert_into_rtree_with_limbs(dot.into());
|
self.insert_into_rtree_with_limbs(dot.into());
|
||||||
return Err(infringement);
|
return Err(infringement);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue