From 81e316397fd9c5dedf7fd68821b15a61d37bf23f Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 23 Dec 2023 02:32:43 +0000 Subject: [PATCH] layout,main: display attempted shapes that caused probe to fail --- src/layout.rs | 32 ++++++------ src/main.rs | 132 +++++++++++++++++++++++++++----------------------- 2 files changed, 89 insertions(+), 75 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index c0b7cd8..00bef0b 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -31,7 +31,7 @@ pub enum LayoutException { NoTangents(NoTangents), Infringement(Infringement), Collision(Collision), - AreConnected(AreConnected), + IsConnected(IsConnected), } impl From for LayoutException { @@ -52,20 +52,20 @@ impl From for LayoutException { } } -impl From for LayoutException { - fn from(err: AreConnected) -> Self { - LayoutException::AreConnected(err) +impl From for LayoutException { + fn from(err: IsConnected) -> Self { + LayoutException::IsConnected(err) } } #[derive(Debug, Clone, Copy)] -pub struct Infringement(pub Index, pub Index); +pub struct Infringement(pub Shape, pub Index); #[derive(Debug, Clone, Copy)] -pub struct Collision(pub Index, pub Index); +pub struct Collision(pub Shape, pub Index); #[derive(Debug, Clone, Copy)] -pub struct AreConnected(pub Weight, pub Index); +pub struct IsConnected(pub i64, pub Index); #[derive(Debug, Clone, Copy)] pub struct Band { @@ -562,9 +562,11 @@ impl Layout { infringables: &[Index], ) -> Result { // It makes no sense to wrap something around or under one of its connectables. - if self.bands[weight.band].net == around.primitive(self).net() { - return Err(LayoutException::AreConnected(AreConnected( - weight.into(), + let net = self.bands[weight.band].net; + // + if net == around.primitive(self).net() { + return Err(LayoutException::IsConnected(IsConnected( + net, around.into(), ))); } @@ -574,9 +576,9 @@ impl Layout { WraparoundableIndex::FixedBend(around) => self.primitive(around).wraparound(), WraparoundableIndex::LooseBend(around) => self.primitive(around).wraparound(), } { - if self.bands[weight.band].net == wraparound.primitive(self).net() { - return Err(LayoutException::AreConnected(AreConnected( - weight.into(), + if net == wraparound.primitive(self).net() { + return Err(LayoutException::IsConnected(IsConnected( + net, wraparound.into(), ))); } @@ -799,7 +801,7 @@ impl Layout { .filter(|wrapper| shape.intersects(wrapper.geom())) .map(|wrapper| wrapper.data) .next() - .and_then(|infringee| Some(Infringement(index, infringee))) + .and_then(|infringee| Some(Infringement(shape, infringee))) } // TODO: Collision and infringement are the same for now. Change this. @@ -815,7 +817,7 @@ impl Layout { .filter(|wrapper| shape.intersects(wrapper.geom())) .map(|wrapper| wrapper.data) .next() - .and_then(|collidee| Some(Collision(index, collidee))) + .and_then(|collidee| Some(Collision(shape, collidee))) } #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] diff --git a/src/main.rs b/src/main.rs index 4715737..1fc5966 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,7 +39,7 @@ use sdl2::video::{GLProfile, Window}; use sdl2::EventPump; use shape::{Shape, ShapeTrait}; -use pathfinder_canvas::{ArcDirection, ColorU, FillRule}; +use pathfinder_canvas::{ArcDirection, CanvasRenderingContext2D, ColorU, FillRule}; use pathfinder_canvas::{Canvas, CanvasFontContext, Path2D}; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::vector::{vec2f, vec2i}; @@ -116,6 +116,7 @@ impl<'a> RouterObserver for DebugRouterObserver<'a> { Some(tracer.mesh.clone()), &trace.path, &[], + &[], 40, ); } @@ -134,6 +135,7 @@ impl<'a> RouterObserver for DebugRouterObserver<'a> { Some(tracer.mesh.clone()), &path, &[], + &[], 10, ); } @@ -145,15 +147,13 @@ impl<'a> RouterObserver for DebugRouterObserver<'a> { _edge: MeshEdgeReference, result: Result<(), DrawException>, ) { - let highlight = match result { + let (ghosts, highlighteds, delay) = match result { Err(DrawException::CannotWrapAround( .., - LayoutException::Infringement(Infringement(.., infringee1)), - LayoutException::Infringement(Infringement(.., infringee2)), - )) => { - vec![infringee1, infringee2] - } - _ => vec![], + LayoutException::Infringement(Infringement(shape1, infringee1)), + LayoutException::Infringement(Infringement(shape2, infringee2)), + )) => (vec![shape1, shape2], vec![infringee1, infringee2], 30), + _ => (vec![], vec![], 10), }; render_times( @@ -166,8 +166,9 @@ impl<'a> RouterObserver for DebugRouterObserver<'a> { None, Some(tracer.mesh.clone()), &trace.path, - &highlight, - 10, + &ghosts, + &highlighteds, + delay, ); } @@ -500,6 +501,7 @@ fn main() { None, &[], &[], + &[], -1, ); @@ -532,6 +534,7 @@ fn main() { None, &[], &[], + &[], -1, ); @@ -552,6 +555,7 @@ fn main() { None, &[], &[], + &[], -1, ); } @@ -566,7 +570,8 @@ fn render_times( follower: Option, mut mesh: Option, path: &[VertexIndex], - highlight: &[Index], + ghosts: &[Shape], + highlighteds: &[Index], times: i64, ) { let mut i = 0; @@ -621,62 +626,18 @@ fn render_times( //let result = panic::catch_unwind(|| { for node in layout.nodes() { - let color = if highlight.contains(&node) { + let color = if highlighteds.contains(&node) { ColorU::new(255, 100, 100, 255) } else { ColorU::new(200, 52, 52, 255) }; - canvas.set_stroke_style(color); - canvas.set_fill_style(color); - let shape = node.primitive(layout).shape(); + render_shape(&mut canvas, &shape, color); + } - match shape { - Shape::Dot(dot) => { - let mut path = Path2D::new(); - path.ellipse( - vec2f(dot.c.pos.x() as f32, dot.c.pos.y() as f32), - dot.c.r as f32, - 0.0, - 0.0, - std::f32::consts::TAU, - ); - canvas.fill_path(path, FillRule::Winding); - } - Shape::Seg(seg) => { - let mut path = Path2D::new(); - path.move_to(vec2f(seg.from.x() as f32, seg.from.y() as f32)); - path.line_to(vec2f(seg.to.x() as f32, seg.to.y() as f32)); - canvas.set_line_width(seg.width as f32); - canvas.stroke_path(path); - } - Shape::Bend(bend) => { - let delta1 = bend.from - bend.c.pos; - let delta2 = bend.to - bend.c.pos; - - let angle1 = delta1.y().atan2(delta1.x()); - let angle2 = delta2.y().atan2(delta2.x()); - - let mut path = Path2D::new(); - path.arc( - vec2f(bend.c.pos.x() as f32, bend.c.pos.y() as f32), - bend.circle().r as f32, - angle1 as f32, - angle2 as f32, - ArcDirection::CW, - ); - canvas.set_line_width(bend.width as f32); - canvas.stroke_path(path); - } - } - let envelope = ShapeTrait::envelope(&shape); - // XXX: points represented as arrays can't be conveniently converted to vector types - let topleft = vec2f(envelope.lower()[0] as f32, envelope.lower()[1] as f32); - let bottomright = vec2f(envelope.upper()[0] as f32, envelope.upper()[1] as f32); - canvas.set_line_width(1.0); - canvas.set_stroke_style(ColorU::new(100, 100, 100, 255)); - canvas.stroke_rect(RectF::new(topleft, bottomright - topleft)); + for ghost in ghosts { + render_shape(&mut canvas, &ghost, ColorU::new(75, 75, 150, 255)); } if let Some(ref mesh) = mesh { @@ -723,3 +684,54 @@ fn render_times( ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)); } } + +fn render_shape(canvas: &mut CanvasRenderingContext2D, shape: &Shape, color: ColorU) { + canvas.set_stroke_style(color); + canvas.set_fill_style(color); + + match shape { + Shape::Dot(dot) => { + let mut path = Path2D::new(); + path.ellipse( + vec2f(dot.c.pos.x() as f32, dot.c.pos.y() as f32), + dot.c.r as f32, + 0.0, + 0.0, + std::f32::consts::TAU, + ); + canvas.fill_path(path, FillRule::Winding); + } + Shape::Seg(seg) => { + let mut path = Path2D::new(); + path.move_to(vec2f(seg.from.x() as f32, seg.from.y() as f32)); + path.line_to(vec2f(seg.to.x() as f32, seg.to.y() as f32)); + canvas.set_line_width(seg.width as f32); + canvas.stroke_path(path); + } + Shape::Bend(bend) => { + let delta1 = bend.from - bend.c.pos; + let delta2 = bend.to - bend.c.pos; + + let angle1 = delta1.y().atan2(delta1.x()); + let angle2 = delta2.y().atan2(delta2.x()); + + let mut path = Path2D::new(); + path.arc( + vec2f(bend.c.pos.x() as f32, bend.c.pos.y() as f32), + bend.circle().r as f32, + angle1 as f32, + angle2 as f32, + ArcDirection::CW, + ); + canvas.set_line_width(bend.width as f32); + canvas.stroke_path(path); + } + } + let envelope = ShapeTrait::envelope(shape); + // XXX: points represented as arrays can't be conveniently converted to vector types + let topleft = vec2f(envelope.lower()[0] as f32, envelope.lower()[1] as f32); + let bottomright = vec2f(envelope.upper()[0] as f32, envelope.upper()[1] as f32); + canvas.set_line_width(1.0); + canvas.set_stroke_style(ColorU::new(100, 100, 100, 255)); + canvas.stroke_rect(RectF::new(topleft, bottomright - topleft)); +}