mirror of https://codeberg.org/topola/topola.git
mesh: Make it possible for fixed and loose bends to be vertices
But not adding tem to the mesh yet, as it's going to take some effort.
This commit is contained in:
parent
b84dab9d09
commit
a3cedff577
|
|
@ -5,13 +5,12 @@ use geo::{EuclideanLength, Point};
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{
|
graph::{
|
||||||
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetNet, Index, LooseBendIndex,
|
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetNet, Index, LooseBendIndex,
|
||||||
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight,
|
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive,
|
||||||
MakePrimitive,
|
|
||||||
},
|
},
|
||||||
guide::Guide,
|
guide::Guide,
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
math::Circle,
|
math::Circle,
|
||||||
primitive::{GetOtherEnd, GetWeight},
|
primitive::GetOtherEnd,
|
||||||
rules::{Conditions, Rules},
|
rules::{Conditions, Rules},
|
||||||
segbend::Segbend,
|
segbend::Segbend,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,7 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodes(&self) -> impl Iterator<Item = Index> + '_ {
|
pub fn nodes(&self) -> impl Iterator<Item = Index> + '_ {
|
||||||
self.node_indexes().map(|ni| {
|
self.node_indices().map(|ni| {
|
||||||
self.graph
|
self.graph
|
||||||
.node_weight(ni.node_index())
|
.node_weight(ni.node_index())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -366,7 +366,7 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
||||||
self.node_indexes()
|
self.node_indices()
|
||||||
.map(|ni| ni.primitive(&self.graph).shape())
|
.map(|ni| ni.primitive(&self.graph).shape())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -374,7 +374,7 @@ impl Layout {
|
||||||
self.graph.node_count()
|
self.graph.node_count()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_indexes(&self) -> impl Iterator<Item = Index> + '_ {
|
fn node_indices(&self) -> impl Iterator<Item = Index> + '_ {
|
||||||
self.rtree.iter().map(|wrapper| wrapper.data)
|
self.rtree.iter().map(|wrapper| wrapper.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
32
src/main.rs
32
src/main.rs
|
|
@ -454,27 +454,27 @@ fn render_times(
|
||||||
//let result = panic::catch_unwind(|| {
|
//let result = panic::catch_unwind(|| {
|
||||||
for shape in layout.shapes() {
|
for shape in layout.shapes() {
|
||||||
match shape {
|
match shape {
|
||||||
Shape::Dot(FixedDot) => {
|
Shape::Dot(dot) => {
|
||||||
let _ = canvas.filled_circle(
|
let _ = canvas.filled_circle(
|
||||||
FixedDot.c.pos.x() as i16,
|
dot.c.pos.x() as i16,
|
||||||
FixedDot.c.pos.y() as i16,
|
dot.c.pos.y() as i16,
|
||||||
FixedDot.c.r as i16,
|
dot.c.r as i16,
|
||||||
Color::RGB(200, 52, 52),
|
Color::RGB(200, 52, 52),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Shape::Seg(FixedSeg) => {
|
Shape::Seg(seg) => {
|
||||||
let _ = canvas.thick_line(
|
let _ = canvas.thick_line(
|
||||||
FixedSeg.from.x() as i16,
|
seg.from.x() as i16,
|
||||||
FixedSeg.from.y() as i16,
|
seg.from.y() as i16,
|
||||||
FixedSeg.to.x() as i16,
|
seg.to.x() as i16,
|
||||||
FixedSeg.to.y() as i16,
|
seg.to.y() as i16,
|
||||||
FixedSeg.width as u8,
|
seg.width as u8,
|
||||||
Color::RGB(200, 52, 52),
|
Color::RGB(200, 52, 52),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Shape::Bend(FixedBend) => {
|
Shape::Bend(bend) => {
|
||||||
let delta1 = FixedBend.from - FixedBend.c.pos;
|
let delta1 = bend.from - bend.c.pos;
|
||||||
let delta2 = FixedBend.to - FixedBend.c.pos;
|
let delta2 = bend.to - bend.c.pos;
|
||||||
|
|
||||||
let angle1 = delta1.y().atan2(delta1.x());
|
let angle1 = delta1.y().atan2(delta1.x());
|
||||||
let angle2 = delta2.y().atan2(delta2.x());
|
let angle2 = delta2.y().atan2(delta2.x());
|
||||||
|
|
@ -483,10 +483,10 @@ fn render_times(
|
||||||
let _ = canvas.arc(
|
let _ = canvas.arc(
|
||||||
//around_circle.pos.x() as i16,
|
//around_circle.pos.x() as i16,
|
||||||
//around_circle.pos.y() as i16,
|
//around_circle.pos.y() as i16,
|
||||||
FixedBend.c.pos.x() as i16,
|
bend.c.pos.x() as i16,
|
||||||
FixedBend.c.pos.y() as i16,
|
bend.c.pos.y() as i16,
|
||||||
//(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16,
|
//(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16,
|
||||||
(FixedBend.circle().r + (d as f64)) as i16,
|
(bend.circle().r + (d as f64)) as i16,
|
||||||
angle1.to_degrees() as i16,
|
angle1.to_degrees() as i16,
|
||||||
angle2.to_degrees() as i16,
|
angle2.to_degrees() as i16,
|
||||||
Color::RGB(200, 52, 52),
|
Color::RGB(200, 52, 52),
|
||||||
|
|
|
||||||
38
src/mesh.rs
38
src/mesh.rs
|
|
@ -1,5 +1,7 @@
|
||||||
|
use enum_dispatch::enum_dispatch;
|
||||||
use fixedbitset::FixedBitSet;
|
use fixedbitset::FixedBitSet;
|
||||||
use geo::{point, Point};
|
use geo::{point, Point};
|
||||||
|
use petgraph::stable_graph::NodeIndex;
|
||||||
use petgraph::visit::{self, NodeIndexable};
|
use petgraph::visit::{self, NodeIndexable};
|
||||||
use spade::{
|
use spade::{
|
||||||
handles::{DirectedEdgeHandle, FixedDirectedEdgeHandle, FixedVertexHandle},
|
handles::{DirectedEdgeHandle, FixedDirectedEdgeHandle, FixedVertexHandle},
|
||||||
|
|
@ -8,18 +10,26 @@ use spade::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{DotIndex, FixedDotIndex, GetNodeIndex, Index},
|
graph::{FixedBendIndex, FixedDotIndex, GetNodeIndex, Index, LooseBendIndex},
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
};
|
};
|
||||||
use crate::{primitive::MakeShape, shape::ShapeTrait};
|
use crate::{primitive::MakeShape, shape::ShapeTrait};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
dot: FixedDotIndex,
|
graph_index: VertexGraphIndex,
|
||||||
x: f64,
|
x: f64,
|
||||||
y: f64,
|
y: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch(GetNodeIndex)]
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum VertexGraphIndex {
|
||||||
|
FixedDot(FixedDotIndex),
|
||||||
|
FixedBend(FixedBendIndex),
|
||||||
|
LooseBend(LooseBendIndex),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct VertexIndex {
|
pub struct VertexIndex {
|
||||||
handle: FixedVertexHandle,
|
handle: FixedVertexHandle,
|
||||||
|
|
@ -35,29 +45,30 @@ impl HasPosition for Vertex {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Mesh {
|
pub struct Mesh {
|
||||||
triangulation: DelaunayTriangulation<Vertex>,
|
triangulation: DelaunayTriangulation<Vertex>,
|
||||||
dot_to_vertex: Vec<Option<VertexIndex>>,
|
graph_index_to_vertex: Vec<Option<VertexIndex>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mesh {
|
impl Mesh {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
triangulation: DelaunayTriangulation::new(),
|
triangulation: DelaunayTriangulation::new(),
|
||||||
dot_to_vertex: Vec::new(),
|
graph_index_to_vertex: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn triangulate(&mut self, layout: &Layout) -> Result<(), InsertionError> {
|
pub fn triangulate(&mut self, layout: &Layout) -> Result<(), InsertionError> {
|
||||||
self.triangulation.clear();
|
self.triangulation.clear();
|
||||||
self.dot_to_vertex = Vec::new();
|
self.graph_index_to_vertex = Vec::new();
|
||||||
self.dot_to_vertex.resize(layout.graph.node_bound(), None);
|
self.graph_index_to_vertex
|
||||||
|
.resize(layout.graph.node_bound(), None);
|
||||||
|
|
||||||
for node in layout.nodes() {
|
for node in layout.nodes() {
|
||||||
if let Index::FixedDot(dot) = node {
|
if let Index::FixedDot(dot) = node {
|
||||||
let center = layout.primitive(dot).shape().center();
|
let center = layout.primitive(dot).shape().center();
|
||||||
|
|
||||||
self.dot_to_vertex[dot.node_index().index()] = Some(VertexIndex {
|
self.graph_index_to_vertex[dot.node_index().index()] = Some(VertexIndex {
|
||||||
handle: self.triangulation.insert(Vertex {
|
handle: self.triangulation.insert(Vertex {
|
||||||
dot,
|
graph_index: dot.into(),
|
||||||
x: center.x(),
|
x: center.x(),
|
||||||
y: center.y(),
|
y: center.y(),
|
||||||
})?,
|
})?,
|
||||||
|
|
@ -68,12 +79,15 @@ impl Mesh {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dot(&self, vertex: VertexIndex) -> FixedDotIndex {
|
pub fn graph_index(&self, vertex: VertexIndex) -> VertexGraphIndex {
|
||||||
self.triangulation.vertex(vertex.handle).as_ref().dot
|
self.triangulation
|
||||||
|
.vertex(vertex.handle)
|
||||||
|
.as_ref()
|
||||||
|
.graph_index
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vertex(&self, dot: FixedDotIndex) -> VertexIndex {
|
pub fn vertex(&self, graph_index: VertexGraphIndex) -> VertexIndex {
|
||||||
self.dot_to_vertex[dot.node_index().index()].unwrap()
|
self.graph_index_to_vertex[graph_index.node_index().index()].unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self, vertex: VertexIndex) -> Point {
|
pub fn position(&self, vertex: VertexIndex) -> Point {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use petgraph::visit::EdgeRef;
|
||||||
use spade::InsertionError;
|
use spade::InsertionError;
|
||||||
|
|
||||||
use crate::astar::{astar, AstarStrategy, PathTracker};
|
use crate::astar::{astar, AstarStrategy, PathTracker};
|
||||||
use crate::graph::{DotIndex, FixedDotIndex};
|
use crate::graph::FixedDotIndex;
|
||||||
use crate::layout::Layout;
|
use crate::layout::Layout;
|
||||||
|
|
||||||
use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
||||||
|
|
@ -26,12 +26,12 @@ pub struct Router {
|
||||||
struct RouterAstarStrategy<'a, RO: RouterObserver> {
|
struct RouterAstarStrategy<'a, RO: RouterObserver> {
|
||||||
tracer: Tracer<'a>,
|
tracer: Tracer<'a>,
|
||||||
trace: Trace,
|
trace: Trace,
|
||||||
to: VertexIndex,
|
to: FixedDotIndex,
|
||||||
observer: &'a mut RO,
|
observer: &'a mut RO,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, RO: RouterObserver> RouterAstarStrategy<'a, RO> {
|
impl<'a, RO: RouterObserver> RouterAstarStrategy<'a, RO> {
|
||||||
pub fn new(tracer: Tracer<'a>, trace: Trace, to: VertexIndex, observer: &'a mut RO) -> Self {
|
pub fn new(tracer: Tracer<'a>, trace: Trace, to: FixedDotIndex, observer: &'a mut RO) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tracer,
|
tracer,
|
||||||
trace,
|
trace,
|
||||||
|
|
@ -48,14 +48,12 @@ impl<'a, RO: RouterObserver> AstarStrategy<&Mesh, u64> for RouterAstarStrategy<'
|
||||||
self.tracer.rework_path(&mut self.trace, &new_path, 5.0);
|
self.tracer.rework_path(&mut self.trace, &new_path, 5.0);
|
||||||
self.observer.on_rework(&self.tracer, &self.trace);
|
self.observer.on_rework(&self.tracer, &self.trace);
|
||||||
|
|
||||||
self.tracer
|
self.tracer.finish(&mut self.trace, self.to, 5.0).is_ok()
|
||||||
.finish(&mut self.trace, self.tracer.mesh.dot(self.to), 5.0)
|
|
||||||
.is_ok()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edge_cost(&mut self, edge: MeshEdgeReference) -> Option<u64> {
|
fn edge_cost(&mut self, edge: MeshEdgeReference) -> Option<u64> {
|
||||||
self.observer.before_probe(&self.tracer, &self.trace, edge);
|
self.observer.before_probe(&self.tracer, &self.trace, edge);
|
||||||
if edge.target() != self.to
|
if edge.target() != self.tracer.mesh.vertex(self.to.into())
|
||||||
&& self
|
&& self
|
||||||
.tracer
|
.tracer
|
||||||
.step(&mut self.trace, edge.target(), 5.0)
|
.step(&mut self.trace, edge.target(), 5.0)
|
||||||
|
|
@ -100,8 +98,8 @@ impl Router {
|
||||||
|
|
||||||
let (_cost, _path) = astar(
|
let (_cost, _path) = astar(
|
||||||
&mesh,
|
&mesh,
|
||||||
mesh.vertex(from),
|
mesh.vertex(from.into()),
|
||||||
&mut RouterAstarStrategy::new(tracer, trace, mesh.vertex(to), observer),
|
&mut RouterAstarStrategy::new(tracer, trace, to.into(), observer),
|
||||||
)
|
)
|
||||||
.unwrap(); // TODO.
|
.unwrap(); // TODO.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use contracts::debug_ensures;
|
use contracts::debug_ensures;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
draw::{BareHead, Draw, Head, HeadTrait, SegbendHead},
|
draw::{BareHead, Draw, Head, SegbendHead},
|
||||||
graph::FixedDotIndex,
|
graph::FixedDotIndex,
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
mesh::{Mesh, VertexIndex},
|
mesh::{Mesh, VertexGraphIndex, VertexIndex},
|
||||||
rules::Rules,
|
rules::Rules,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ impl<'a> Tracer<'a> {
|
||||||
|
|
||||||
pub fn start(&mut self, from: FixedDotIndex) -> Trace {
|
pub fn start(&mut self, from: FixedDotIndex) -> Trace {
|
||||||
Trace {
|
Trace {
|
||||||
path: vec![self.mesh.vertex(from)],
|
path: vec![self.mesh.vertex(from.into())],
|
||||||
head: BareHead { dot: from }.into(),
|
head: BareHead { dot: from }.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -81,14 +81,13 @@ impl<'a> Tracer<'a> {
|
||||||
#[debug_ensures(ret.is_ok() -> trace.path.len() == old(trace.path.len() + 1))]
|
#[debug_ensures(ret.is_ok() -> trace.path.len() == old(trace.path.len() + 1))]
|
||||||
#[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))]
|
#[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))]
|
||||||
pub fn step(&mut self, trace: &mut Trace, to: VertexIndex, width: f64) -> Result<(), ()> {
|
pub fn step(&mut self, trace: &mut Trace, to: VertexIndex, width: f64) -> Result<(), ()> {
|
||||||
let to_dot = self.mesh.dot(to);
|
trace.head = self.wrap(trace.head, to, width)?.into();
|
||||||
trace.head = self.wrap(trace.head, to_dot, width)?.into();
|
|
||||||
|
|
||||||
trace.path.push(to);
|
trace.path.push(to);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap(&mut self, head: Head, around: FixedDotIndex, width: f64) -> Result<SegbendHead, ()> {
|
fn wrap(&mut self, head: Head, around: VertexIndex, width: f64) -> Result<SegbendHead, ()> {
|
||||||
/*let _around_pos = self.layout.primitive(around).weight().circle.pos;
|
/*let _around_pos = self.layout.primitive(around).weight().circle.pos;
|
||||||
let _around_primitive = self.layout.primitive(around);
|
let _around_primitive = self.layout.primitive(around);
|
||||||
|
|
||||||
|
|
@ -114,6 +113,19 @@ impl<'a> Tracer<'a> {
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
match self.mesh.graph_index(around) {
|
||||||
|
VertexGraphIndex::FixedDot(dot) => self.wrap_around_fixed_dot(head, dot, width),
|
||||||
|
VertexGraphIndex::FixedBend(_fixed_bend) => todo!(),
|
||||||
|
VertexGraphIndex::LooseBend(_loose_bend) => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wrap_around_fixed_dot(
|
||||||
|
&mut self,
|
||||||
|
head: Head,
|
||||||
|
around: FixedDotIndex,
|
||||||
|
width: f64,
|
||||||
|
) -> Result<SegbendHead, ()> {
|
||||||
self.draw().segbend_around_dot(head, around.into(), width)
|
self.draw().segbend_around_dot(head, around.into(), width)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue