layout: remove inserted dots if placing via fails

This commit is contained in:
Mikolaj Wielgus 2024-06-17 23:58:03 +02:00
parent 7dd0f3e629
commit a7b4a84b98
4 changed files with 59 additions and 6 deletions

View File

@ -155,6 +155,12 @@ impl<CW: Copy, R: RulesTrait> Drawing<CW, R> {
self.add_dot_with_infringables(weight, Some(&[]))
}
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() - 1))]
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
pub fn remove_fixed_dot(&mut self, dot: FixedDotIndex) {
self.geometry_with_rtree.remove_dot(dot.into());
}
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))]
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
pub fn add_fixed_dot_infringably(&mut self, weight: FixedDotWeight) -> FixedDotIndex {

View File

@ -1,3 +1,4 @@
use contracts::debug_ensures;
use enum_dispatch::enum_dispatch;
use geo::Point;
use rstar::AABB;
@ -66,16 +67,34 @@ impl<R: RulesTrait> Layout<R> {
.insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw)
}
#[debug_ensures(ret.is_ok() -> self.drawing.node_count() == old(self.drawing.node_count()) + weight.to_layer - weight.from_layer)]
#[debug_ensures(ret.is_err() -> self.drawing.node_count() == old(self.drawing.node_count()))]
pub fn add_via(&mut self, weight: ViaWeight) -> Result<GenericIndex<ViaWeight>, Infringement> {
let compound = self.drawing.add_compound(weight.into());
let mut dots = vec![];
for layer in weight.from_layer..=weight.to_layer {
let dot = self.drawing.add_fixed_dot(FixedDotWeight {
match self.drawing.add_fixed_dot(FixedDotWeight {
circle: weight.circle,
layer,
maybe_net: weight.maybe_net,
})?;
self.drawing.add_to_compound(dot, compound);
}) {
Ok(dot) => {
self.drawing.add_to_compound(dot, compound);
dots.push(dot);
}
Err(err) => {
// Remove inserted dots.
self.drawing.remove_compound(compound);
for dot in dots.iter().rev() {
self.drawing.remove_fixed_dot(*dot);
}
return Err(err);
}
}
}
Ok(GenericIndex::<ViaWeight>::new(compound.node_index()))

View File

@ -1,12 +1,41 @@
use topola::board::mesadata::MesadataTrait;
use topola::{
autorouter::{
invoker::{Command, InvokerError},
AutorouterError,
},
board::mesadata::MesadataTrait,
layout::via::ViaWeight,
math::Circle,
router::EmptyRouterObserver,
};
mod common;
#[test]
fn test_prerouted_lm317_breakout() {
fn test_unrouted_lm317_breakout() {
let mut invoker = common::load_design_and_assert(
"tests/multilayer/data/prerouted_lm317_breakout/unrouted_lm317_breakout.dsn",
);
let result = invoker.execute(
Command::PlaceVia(ViaWeight {
from_layer: 0,
to_layer: 1,
circle: Circle {
pos: [125000.0, -84000.0].into(),
r: 1000.0,
},
maybe_net: Some(1234),
}),
&mut EmptyRouterObserver,
);
let result = dbg!(result);
assert!(matches!(
result,
Err(InvokerError::Autorouter(AutorouterError::CouldNotPlaceVia(
..
)))
));
}
#[test]

View File

@ -54,7 +54,6 @@ fn test_tht_diode_bridge_rectifier() {
}),
&mut EmptyRouterObserver,
);
let result = dbg!(result);
assert!(matches!(
result,
Err(InvokerError::Autorouter(AutorouterError::CouldNotPlaceVia(