fix(autorouter/anterouter): Remove fanout if seg addition fails

This commit is contained in:
Mikolaj Wielgus 2025-10-17 22:26:07 +02:00
parent d920f62a1e
commit 64a519420f
4 changed files with 36 additions and 11 deletions

View File

@ -334,7 +334,7 @@ impl Anterouter {
direction: impl Into<Point>, direction: impl Into<Point>,
options: &AnterouterOptions, options: &AnterouterOptions,
) -> Result<(), ()> { ) -> Result<(), ()> {
let (_, dots) = self.place_fanout_via_on_bbox_in_direction( let (via, dots) = self.place_fanout_via_on_bbox_in_direction(
autorouter, autorouter,
recorder, recorder,
ratvertex, ratvertex,
@ -363,7 +363,7 @@ impl Anterouter {
}) })
.unwrap(); .unwrap();
autorouter.board.layout_mut().add_fixed_seg( if let Ok(_) = autorouter.board.layout_mut().add_fixed_seg(
&mut recorder.layout_edit, &mut recorder.layout_edit,
source_dot, source_dot,
fanout_dot, fanout_dot,
@ -372,9 +372,12 @@ impl Anterouter {
layer, layer,
maybe_net, maybe_net,
}), }),
); ) {
Ok(())
Ok(()) } else {
autorouter.board.remove_via(recorder, via, dots);
Err(())
}
} }
fn place_fanout_via_on_bbox_in_direction( fn place_fanout_via_on_bbox_in_direction(

View File

@ -125,6 +125,20 @@ impl<M: AccessMesadata> Board<M> {
Ok((weight, dots)) Ok((weight, dots))
} }
pub fn remove_via(
&mut self,
recorder: &mut BoardEdit,
via: GenericIndex<ViaWeight>,
dots: Vec<FixedDotIndex>,
) {
for dot in dots.clone() {
self.pinname_nodes
.remove_by_value(&GenericNode::Primitive(dot.into()));
}
self.layout.remove_via(&mut recorder.layout_edit, via, dots);
}
/// Adds a new fixed dot with an optional pin name. /// Adds a new fixed dot with an optional pin name.
/// ///
/// Inserts the dot into the layout and, if a pin name is provided, maps it to the created dot's node. /// Inserts the dot into the layout and, if a pin name is provided, maps it to the created dot's node.

View File

@ -157,6 +157,7 @@ impl<R: AccessRules> Layout<R> {
weight: ViaWeight, weight: ViaWeight,
) -> Result<(GenericIndex<ViaWeight>, Vec<FixedDotIndex>), LayoutException> { ) -> Result<(GenericIndex<ViaWeight>, Vec<FixedDotIndex>), LayoutException> {
let compound = self.drawing.add_compound(recorder, weight.into()); let compound = self.drawing.add_compound(recorder, weight.into());
let via = GenericIndex::<ViaWeight>::new(compound.index());
let mut dots = vec![]; let mut dots = vec![];
for layer in weight.from_layer..=weight.to_layer { for layer in weight.from_layer..=weight.to_layer {
@ -180,7 +181,7 @@ impl<R: AccessRules> Layout<R> {
// trigger an infringement on its primitives. To take // trigger an infringement on its primitives. To take
// this situation into account, we also check if the // this situation into account, we also check if the
// via's center is inside the poly's polygon. // via's center is inside the poly's polygon.
self.remove_failed_via(recorder, compound, dots); self.remove_via(recorder, via, dots);
return Err(LayoutException::HasPointInPoly(HasPointInPoly( return Err(LayoutException::HasPointInPoly(HasPointInPoly(
enclosing_poly.ref_(self).shape(), enclosing_poly.ref_(self).shape(),
weight.circle.pos, weight.circle.pos,
@ -195,7 +196,7 @@ impl<R: AccessRules> Layout<R> {
); );
} }
Err(err) => { Err(err) => {
self.remove_failed_via(recorder, compound, dots); self.remove_via(recorder, via, dots);
return Err(err.into()); return Err(err.into());
} }
} }
@ -204,13 +205,14 @@ impl<R: AccessRules> Layout<R> {
Ok((GenericIndex::<ViaWeight>::new(compound.index()), dots)) Ok((GenericIndex::<ViaWeight>::new(compound.index()), dots))
} }
fn remove_failed_via( pub fn remove_via(
&mut self, &mut self,
recorder: &mut LayoutEdit, recorder: &mut LayoutEdit,
compound: GenericIndex<CompoundWeight>, via: GenericIndex<ViaWeight>,
dots: Vec<FixedDotIndex>, dots: Vec<FixedDotIndex>,
) { ) {
self.drawing.remove_compound(recorder, compound); self.drawing
.remove_compound(recorder, GenericIndex::<CompoundWeight>::new(via.index()));
// Remove inserted dots. // Remove inserted dots.
for dot in dots.iter().rev() { for dot in dots.iter().rev() {

View File

@ -24,9 +24,10 @@ use crate::{
bend::{FixedBendIndex, LooseBendIndex}, bend::{FixedBendIndex, LooseBendIndex},
dot::FixedDotIndex, dot::FixedDotIndex,
gear::{GearIndex, GetOuterGears, WalkOutwards}, gear::{GearIndex, GetOuterGears, WalkOutwards},
graph::PrimitiveIndex, graph::{MakePrimitiveRef, PrimitiveIndex},
rules::AccessRules, rules::AccessRules,
}, },
geometry::GetLayer,
graph::{GenericIndex, GetIndex, MakeRef}, graph::{GenericIndex, GetIndex, MakeRef},
layout::{CompoundEntryLabel, Layout}, layout::{CompoundEntryLabel, Layout},
math::RotationSense, math::RotationSense,
@ -157,6 +158,11 @@ impl Navmesh {
destination: FixedDotIndex, destination: FixedDotIndex,
options: RouterOptions, options: RouterOptions,
) -> Result<Self, NavmeshError> { ) -> Result<Self, NavmeshError> {
assert!(
origin.primitive_ref(layout.drawing()).layer()
== destination.primitive_ref(layout.drawing()).layer()
);
let mut graph: UnGraph<NavnodeWeight, (), usize> = UnGraph::default(); let mut graph: UnGraph<NavnodeWeight, (), usize> = UnGraph::default();
let mut origin_navnode = None; let mut origin_navnode = None;
let mut destination_navnode = None; let mut destination_navnode = None;