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

View File

@ -125,6 +125,20 @@ impl<M: AccessMesadata> Board<M> {
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.
///
/// 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,
) -> Result<(GenericIndex<ViaWeight>, Vec<FixedDotIndex>), LayoutException> {
let compound = self.drawing.add_compound(recorder, weight.into());
let via = GenericIndex::<ViaWeight>::new(compound.index());
let mut dots = vec![];
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
// this situation into account, we also check if the
// 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(
enclosing_poly.ref_(self).shape(),
weight.circle.pos,
@ -195,7 +196,7 @@ impl<R: AccessRules> Layout<R> {
);
}
Err(err) => {
self.remove_failed_via(recorder, compound, dots);
self.remove_via(recorder, via, dots);
return Err(err.into());
}
}
@ -204,13 +205,14 @@ impl<R: AccessRules> Layout<R> {
Ok((GenericIndex::<ViaWeight>::new(compound.index()), dots))
}
fn remove_failed_via(
pub fn remove_via(
&mut self,
recorder: &mut LayoutEdit,
compound: GenericIndex<CompoundWeight>,
via: GenericIndex<ViaWeight>,
dots: Vec<FixedDotIndex>,
) {
self.drawing.remove_compound(recorder, compound);
self.drawing
.remove_compound(recorder, GenericIndex::<CompoundWeight>::new(via.index()));
// Remove inserted dots.
for dot in dots.iter().rev() {

View File

@ -24,9 +24,10 @@ use crate::{
bend::{FixedBendIndex, LooseBendIndex},
dot::FixedDotIndex,
gear::{GearIndex, GetOuterGears, WalkOutwards},
graph::PrimitiveIndex,
graph::{MakePrimitiveRef, PrimitiveIndex},
rules::AccessRules,
},
geometry::GetLayer,
graph::{GenericIndex, GetIndex, MakeRef},
layout::{CompoundEntryLabel, Layout},
math::RotationSense,
@ -157,6 +158,11 @@ impl Navmesh {
destination: FixedDotIndex,
options: RouterOptions,
) -> 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 origin_navnode = None;
let mut destination_navnode = None;