mesh: Make bends vertices, too

This commit is contained in:
Mikolaj Wielgus 2023-11-06 23:22:00 +00:00
parent d6163d3d44
commit 9fe591d4dc
4 changed files with 138 additions and 64 deletions

View File

@ -17,15 +17,15 @@ version = "0.6.3"
[dependencies.spade]
version = "2.2.0"
[dependencies.fixedbitset]
version = "0.4.0"
[dependencies.enum_dispatch]
version = "0.3.12"
[dependencies.enum-as-inner]
version = "0.6.0"
[dependencies.itertools]
version = "0.8.2"
[dependencies.contracts]
version = "0.6.3"

View File

@ -26,10 +26,11 @@ mod traverser;
mod triangulation;
use geo::point;
use graph::{FixedDotIndex, FixedSegWeight, LooseDotIndex};
use graph::{FixedDotIndex, FixedSegWeight, LooseDotIndex, MakePrimitive};
use layout::Layout;
use mesh::{Mesh, MeshEdgeReference, VertexIndex};
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
use primitive::MakeShape;
use router::RouterObserver;
use rstar::RTreeObject;
use sdl2::event::Event;
@ -39,7 +40,7 @@ use sdl2::pixels::Color;
use sdl2::render::Canvas;
use sdl2::video::Window;
use sdl2::EventPump;
use shape::Shape;
use shape::{Shape, ShapeTrait};
use std::time::Duration;
use tracer::{Trace, Tracer};
@ -144,16 +145,16 @@ fn main() {
})
.unwrap();
/*let dot2 = router
.layout
.add_fixed_dot(FixedDotWeight {
net: 1,
circle: Circle {
pos: (100.5, 500.5).into(),
r: 8.0,
},
})
.unwrap();*/
let dot2 = router
.layout
.add_fixed_dot(FixedDotWeight {
net: 1,
circle: Circle {
pos: (100.5, 500.5).into(),
r: 8.0,
},
})
.unwrap();
let dot_end = router
.layout
@ -166,6 +167,17 @@ fn main() {
})
.unwrap();
let dot_end2 = router
.layout
.add_fixed_dot(FixedDotWeight {
net: 1,
circle: Circle {
pos: (500.5, 150.5).into(),
r: 8.0,
},
})
.unwrap();
let dot1_1 = router
.layout
.add_fixed_dot(FixedDotWeight {
@ -387,6 +399,12 @@ fn main() {
-1,
);*/
let _ = router.enroute(
dot2,
dot_end2,
&mut DebugRouterObserver::new(&mut event_pump, &mut canvas),
);
render_times(
&mut event_pump,
&mut canvas,
@ -494,7 +512,7 @@ fn render_times(
}
}
}
let envelope = shape.envelope();
let envelope = ShapeTrait::envelope(&shape);
let _ = canvas.rectangle(
envelope.lower()[0] as i16,
envelope.lower()[1] as i16,
@ -506,7 +524,8 @@ fn render_times(
if let Some(ref mesh) = mesh {
for edge in mesh.edge_references() {
let endpoints = (mesh.position(edge.source()), mesh.position(edge.target()));
let start_point = edge.source().primitive(&layout.graph).shape().center();
let end_point = edge.target().primitive(&layout.graph).shape().center();
let color = if path.contains(&edge.source()) && path.contains(&edge.target()) {
Color::RGB(250, 250, 0)
@ -515,10 +534,10 @@ fn render_times(
};
let _ = canvas.line(
endpoints.0.x() as i16,
endpoints.0.y() as i16,
endpoints.1.x() as i16,
endpoints.1.y() as i16,
start_point.x() as i16,
start_point.y() as i16,
end_point.x() as i16,
end_point.y() as i16,
color,
);
}

View File

@ -1,18 +1,29 @@
use std::iter;
use enum_dispatch::enum_dispatch;
use geo::Point;
use itertools::Itertools;
use petgraph::visit;
use petgraph::{stable_graph::NodeIndex, visit::EdgeRef};
use petgraph::{
stable_graph::{NodeIndex, StableDiGraph},
visit::EdgeRef,
};
use spade::{HasPosition, InsertionError, Point2};
use crate::primitive::{GetCore, Primitive};
use crate::triangulation::TriangulationEdgeReference;
use crate::{
graph::{FixedBendIndex, FixedDotIndex, GetNodeIndex, Index, LooseBendIndex, MakePrimitive},
graph::{
FixedBendIndex, FixedDotIndex, GetNodeIndex, Index, Label, LooseBendIndex, MakePrimitive,
Weight,
},
layout::Layout,
primitive::MakeShape,
shape::ShapeTrait,
triangulation::{GetVertexIndex, Triangulation},
};
#[enum_dispatch(GetNodeIndex)]
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
pub enum VertexIndex {
FixedDot(FixedDotIndex),
@ -23,6 +34,7 @@ pub enum VertexIndex {
#[derive(Debug, Clone)]
struct TriangulationWeight {
vertex: VertexIndex,
layers: Vec<LooseBendIndex>,
pos: Point,
}
@ -59,29 +71,34 @@ impl Mesh {
Index::FixedDot(fixed_dot) => {
self.triangulation.add_vertex(TriangulationWeight {
vertex: fixed_dot.into(),
layers: vec![],
pos: center,
})?;
}
Index::FixedBend(fixed_bend) => {
self.triangulation.add_vertex(TriangulationWeight {
vertex: fixed_bend.into(),
layers: vec![],
pos: center,
})?;
}
/*Index::LooseBend(loose_bend) => {
self.triangulation.add_bend(
loose_bend.into(),
layout.primitive(loose_bend).core().into(),
);
}*/
_ => (),
}
}
Ok(())
}
pub fn position(&self, vertex: VertexIndex) -> Point {
self.triangulation.position(vertex)
for node in layout.nodes() {
match node {
Index::LooseBend(loose_bend) => {
self.triangulation
.weight_mut(layout.primitive(loose_bend).core().into())
.layers
.push(loose_bend.into());
}
_ => (),
}
}
Ok(())
}
}
@ -123,6 +140,53 @@ impl visit::EdgeRef for MeshEdgeReference {
}
}
impl<'a> visit::IntoNeighbors for &'a Mesh {
type Neighbors = Box<dyn Iterator<Item = VertexIndex> + 'a>;
fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors {
Box::new(self.triangulation.neighbors(vertex).flat_map(|neighbor| {
iter::once(neighbor).chain(
self.triangulation
.weight(neighbor)
.layers
.iter()
.map(|index| VertexIndex::from(*index)),
)
}))
}
}
fn edges(
triangulation: &Triangulation<VertexIndex, TriangulationWeight>,
edge: TriangulationEdgeReference<VertexIndex>,
) -> impl Iterator<Item = MeshEdgeReference> {
let mut from_vertices = vec![edge.source()];
from_vertices.extend(
triangulation
.weight(edge.source())
.layers
.iter()
.map(|bend| VertexIndex::from(*bend)),
);
let mut to_vertices = vec![edge.target()];
to_vertices.extend(
triangulation
.weight(edge.target())
.layers
.iter()
.map(|bend| VertexIndex::from(*bend)),
);
from_vertices
.into_iter()
.cartesian_product(to_vertices.into_iter())
.map(|pair| MeshEdgeReference {
from: pair.0,
to: pair.1,
})
}
impl<'a> visit::IntoEdgeReferences for &'a Mesh {
type EdgeRef = MeshEdgeReference;
type EdgeReferences = Box<dyn Iterator<Item = MeshEdgeReference> + 'a>;
@ -131,22 +195,11 @@ impl<'a> visit::IntoEdgeReferences for &'a Mesh {
Box::new(
self.triangulation
.edge_references()
.map(|edge| MeshEdgeReference {
from: edge.source(),
to: edge.target(),
}),
.flat_map(move |edge| edges(&self.triangulation, edge)),
)
}
}
impl<'a> visit::IntoNeighbors for &'a Mesh {
type Neighbors = Box<dyn Iterator<Item = VertexIndex> + 'a>;
fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors {
self.triangulation.neighbors(vertex)
}
}
impl<'a> visit::IntoEdges for &'a Mesh {
type Edges = Box<dyn Iterator<Item = MeshEdgeReference> + 'a>;
@ -154,10 +207,7 @@ impl<'a> visit::IntoEdges for &'a Mesh {
Box::new(
self.triangulation
.edges(node)
.map(|edge| MeshEdgeReference {
from: edge.source(),
to: edge.target(),
}),
.flat_map(move |edge| edges(&self.triangulation, edge)),
)
}
}

View File

@ -40,6 +40,11 @@ impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scal
Ok(())
}
pub fn weight(&self, vertex: I) -> &W {
spade::Triangulation::s(&self.triangulation)
.vertex_data(self.vertex_to_handle[vertex.node_index().index()].unwrap())
}
pub fn weight_mut(&mut self, vertex: I) -> &mut W {
spade::Triangulation::vertex_data_mut(
&mut self.triangulation,
@ -106,6 +111,20 @@ impl<I: Copy> visit::EdgeRef for TriangulationEdgeReference<I> {
}
}
impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
visit::IntoNeighbors for &'a Triangulation<I, W>
{
type Neighbors = Box<dyn Iterator<Item = I> + 'a>;
fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors {
Box::new(
spade::Triangulation::vertex(&self.triangulation, self.handle(vertex))
.out_edges()
.map(|handle| self.vertex(handle.to().fix())),
)
}
}
impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
visit::IntoEdgeReferences for &'a Triangulation<I, W>
{
@ -124,20 +143,6 @@ impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<
}
}
impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
visit::IntoNeighbors for &'a Triangulation<I, W>
{
type Neighbors = Box<dyn Iterator<Item = I> + 'a>;
fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors {
Box::new(
spade::Triangulation::vertex(&self.triangulation, self.handle(vertex))
.out_edges()
.map(|handle| self.vertex(handle.to().fix())),
)
}
}
impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
visit::IntoEdges for &'a Triangulation<I, W>
{