mirror of https://codeberg.org/topola/topola.git
layout: remove inserted dots if placing via fails
This commit is contained in:
parent
7dd0f3e629
commit
a7b4a84b98
|
|
@ -155,6 +155,12 @@ impl<CW: Copy, R: RulesTrait> Drawing<CW, R> {
|
||||||
self.add_dot_with_infringables(weight, Some(&[]))
|
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().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()))]
|
#[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 {
|
pub fn add_fixed_dot_infringably(&mut self, weight: FixedDotWeight) -> FixedDotIndex {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use contracts::debug_ensures;
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use rstar::AABB;
|
use rstar::AABB;
|
||||||
|
|
@ -66,16 +67,34 @@ impl<R: RulesTrait> Layout<R> {
|
||||||
.insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw)
|
.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> {
|
pub fn add_via(&mut self, weight: ViaWeight) -> Result<GenericIndex<ViaWeight>, Infringement> {
|
||||||
let compound = self.drawing.add_compound(weight.into());
|
let compound = self.drawing.add_compound(weight.into());
|
||||||
|
let mut dots = vec![];
|
||||||
|
|
||||||
for layer in weight.from_layer..=weight.to_layer {
|
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,
|
circle: weight.circle,
|
||||||
layer,
|
layer,
|
||||||
maybe_net: weight.maybe_net,
|
maybe_net: weight.maybe_net,
|
||||||
})?;
|
}) {
|
||||||
|
Ok(dot) => {
|
||||||
self.drawing.add_to_compound(dot, compound);
|
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()))
|
Ok(GenericIndex::<ViaWeight>::new(compound.node_index()))
|
||||||
|
|
|
||||||
|
|
@ -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;
|
mod common;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_prerouted_lm317_breakout() {
|
fn test_unrouted_lm317_breakout() {
|
||||||
let mut invoker = common::load_design_and_assert(
|
let mut invoker = common::load_design_and_assert(
|
||||||
"tests/multilayer/data/prerouted_lm317_breakout/unrouted_lm317_breakout.dsn",
|
"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]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ fn test_tht_diode_bridge_rectifier() {
|
||||||
}),
|
}),
|
||||||
&mut EmptyRouterObserver,
|
&mut EmptyRouterObserver,
|
||||||
);
|
);
|
||||||
let result = dbg!(result);
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
result,
|
result,
|
||||||
Err(InvokerError::Autorouter(AutorouterError::CouldNotPlaceVia(
|
Err(InvokerError::Autorouter(AutorouterError::CouldNotPlaceVia(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue