mirror of https://codeberg.org/topola/topola.git
feat(autorouter/ratsnest): Have one terminating dot for each layer of ratvertex
Some routes projects still crash while autorouting, but we are progressing.
This commit is contained in:
parent
d53aa2a678
commit
b50e58b0fa
|
|
@ -11,17 +11,18 @@ use specctra_core::mesadata::AccessMesadata;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{ratline::RatlineIndex, Autorouter},
|
autorouter::{ratline::RatlineIndex, Autorouter},
|
||||||
|
board::edit::BoardEdit,
|
||||||
drawing::{
|
drawing::{
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
graph::{GetMaybeNet, MakePrimitiveRef},
|
graph::{GetMaybeNet, MakePrimitiveRef},
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
},
|
},
|
||||||
geometry::GetLayer,
|
geometry::{GenericNode, GetLayer},
|
||||||
graph::{GenericIndex, GetIndex, MakeRef},
|
graph::{GenericIndex, GetIndex, MakeRef},
|
||||||
layout::{
|
layout::{
|
||||||
poly::{MakePolygon, PolyWeight},
|
poly::{MakePolygon, PolyWeight},
|
||||||
via::ViaWeight,
|
via::ViaWeight,
|
||||||
CompoundWeight, LayoutEdit,
|
CompoundWeight,
|
||||||
},
|
},
|
||||||
math::Circle,
|
math::Circle,
|
||||||
};
|
};
|
||||||
|
|
@ -53,15 +54,23 @@ impl Anterouter {
|
||||||
let endpoint_indices = ratline.ref_(autorouter).endpoint_indices();
|
let endpoint_indices = ratline.ref_(autorouter).endpoint_indices();
|
||||||
let endpoint_dots = ratline.ref_(autorouter).endpoint_dots();
|
let endpoint_dots = ratline.ref_(autorouter).endpoint_dots();
|
||||||
|
|
||||||
|
autorouter
|
||||||
|
.ratsnest
|
||||||
|
.assign_layer_to_ratline(*ratline, *layer);
|
||||||
|
|
||||||
if let Some(terminating_scheme) = self
|
if let Some(terminating_scheme) = self
|
||||||
.plan
|
.plan
|
||||||
.ratline_endpoint_dot_to_terminating_scheme
|
.ratline_endpoint_dot_to_terminating_scheme
|
||||||
.get(&endpoint_dots.0)
|
.get(&endpoint_dots.0)
|
||||||
{
|
{
|
||||||
match terminating_scheme {
|
match terminating_scheme {
|
||||||
TerminatingScheme::ExistingFixedDot(terminating_dot) => autorouter
|
TerminatingScheme::ExistingFixedDot(terminating_dot) => {
|
||||||
.ratsnest
|
autorouter.ratsnest.assign_terminating_dot_to_ratvertex(
|
||||||
.assign_terminating_dot_to_ratvertex(endpoint_indices.0, *terminating_dot),
|
endpoint_indices.0,
|
||||||
|
*layer,
|
||||||
|
*terminating_dot,
|
||||||
|
)
|
||||||
|
}
|
||||||
TerminatingScheme::Anteroute(pin_bbox_to_anchor) => self
|
TerminatingScheme::Anteroute(pin_bbox_to_anchor) => self
|
||||||
.anteroute_dot_to_anchor(
|
.anteroute_dot_to_anchor(
|
||||||
autorouter,
|
autorouter,
|
||||||
|
|
@ -79,9 +88,13 @@ impl Anterouter {
|
||||||
.get(&endpoint_dots.1)
|
.get(&endpoint_dots.1)
|
||||||
{
|
{
|
||||||
match terminating_scheme {
|
match terminating_scheme {
|
||||||
TerminatingScheme::ExistingFixedDot(terminating_dot) => autorouter
|
TerminatingScheme::ExistingFixedDot(terminating_dot) => {
|
||||||
.ratsnest
|
autorouter.ratsnest.assign_terminating_dot_to_ratvertex(
|
||||||
.assign_terminating_dot_to_ratvertex(endpoint_indices.1, *terminating_dot),
|
endpoint_indices.1,
|
||||||
|
*layer,
|
||||||
|
*terminating_dot,
|
||||||
|
)
|
||||||
|
}
|
||||||
TerminatingScheme::Anteroute(pin_bbox_to_anchor) => self
|
TerminatingScheme::Anteroute(pin_bbox_to_anchor) => self
|
||||||
.anteroute_dot_to_anchor(
|
.anteroute_dot_to_anchor(
|
||||||
autorouter,
|
autorouter,
|
||||||
|
|
@ -170,10 +183,10 @@ impl Anterouter {
|
||||||
|
|
||||||
//let via_bbox_to_anchor = [-pin_bbox_to_anchor[0], -pin_bbox_to_anchor[1]];
|
//let via_bbox_to_anchor = [-pin_bbox_to_anchor[0], -pin_bbox_to_anchor[1]];
|
||||||
|
|
||||||
let mut layout_edit = LayoutEdit::new();
|
let mut board_edit = BoardEdit::new();
|
||||||
|
|
||||||
if let Ok((.., dots)) = autorouter.board.layout_mut().add_via(
|
if let Ok((.., dots)) = autorouter.board.add_via(
|
||||||
&mut layout_edit,
|
&mut board_edit,
|
||||||
ViaWeight {
|
ViaWeight {
|
||||||
from_layer: std::cmp::min(pin_layer, to_layer),
|
from_layer: std::cmp::min(pin_layer, to_layer),
|
||||||
to_layer: std::cmp::max(pin_layer, to_layer),
|
to_layer: std::cmp::max(pin_layer, to_layer),
|
||||||
|
|
@ -183,6 +196,10 @@ impl Anterouter {
|
||||||
},
|
},
|
||||||
maybe_net: pin_maybe_net,
|
maybe_net: pin_maybe_net,
|
||||||
},
|
},
|
||||||
|
autorouter
|
||||||
|
.board()
|
||||||
|
.node_pinname(&GenericNode::Primitive(dot.into()))
|
||||||
|
.cloned(),
|
||||||
) {
|
) {
|
||||||
let terminating_dot = dots
|
let terminating_dot = dots
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -193,9 +210,11 @@ impl Anterouter {
|
||||||
.layer()
|
.layer()
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
autorouter
|
autorouter.ratsnest.assign_terminating_dot_to_ratvertex(
|
||||||
.ratsnest
|
ratvertex,
|
||||||
.assign_terminating_dot_to_ratvertex(ratvertex, *terminating_dot);
|
to_layer,
|
||||||
|
*terminating_dot,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/*let bbox = if let Some(poly) = autorouter.board().layout().drawing().geometry().compounds(dot).find(|(_, compound_weight)| {
|
/*let bbox = if let Some(poly) = autorouter.board().layout().drawing().geometry().compounds(dot).find(|(_, compound_weight)| {
|
||||||
matches!(compound_weight, CompoundWeight::Poly(..))
|
matches!(compound_weight, CompoundWeight::Poly(..))
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@ use geo::Point;
|
||||||
use petgraph::graph::NodeIndex;
|
use petgraph::graph::NodeIndex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use spade::InsertionError;
|
use spade::InsertionError;
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::BTreeSet;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{
|
autorouter::{
|
||||||
anterouter::AnterouterPlan, multilayer_autoroute::MultilayerAutorouteExecutionStepper,
|
multilayer_autoroute::MultilayerAutorouteExecutionStepper,
|
||||||
permutator::PlanarAutorouteExecutionPermutator, planner::Planner,
|
permutator::PlanarAutorouteExecutionPermutator, planner::Planner,
|
||||||
},
|
},
|
||||||
board::{AccessMesadata, Board},
|
board::{AccessMesadata, Board},
|
||||||
|
|
@ -213,22 +213,22 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
active_layer,
|
active_layer,
|
||||||
allowed_edges,
|
allowed_edges,
|
||||||
ratlines.into_iter().filter_map(|ratline| {
|
ratlines.into_iter().filter_map(|ratline| {
|
||||||
let (source, target) = ratline.ref_(self).terminating_dots();
|
let (origin, destination) = ratline.ref_(self).terminating_dots();
|
||||||
|
|
||||||
if navmesh
|
if navmesh
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.node_data(&NavmeshIndex::Primal(source))
|
.node_data(&NavmeshIndex::Primal(origin))
|
||||||
.is_none()
|
.is_none()
|
||||||
|| navmesh
|
|| navmesh
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.node_data(&NavmeshIndex::Primal(target))
|
.node_data(&NavmeshIndex::Primal(destination))
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
// e.g. due to wrong active layer
|
// e.g. due to wrong active layer
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.board.band_between_nodes(source, target).is_some() {
|
if self.board.band_between_nodes(origin, destination).is_some() {
|
||||||
// already connected
|
// already connected
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
@ -236,8 +236,8 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
got_any_valid_goals = true;
|
got_any_valid_goals = true;
|
||||||
|
|
||||||
Some(ng::Goal {
|
Some(ng::Goal {
|
||||||
source,
|
source: origin,
|
||||||
target,
|
target: destination,
|
||||||
width,
|
width,
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ impl<M: AccessMesadata + Clone> ExecutionStepper<M> {
|
||||||
for (ep, band) in &autoroute.last_bands {
|
for (ep, band) in &autoroute.last_bands {
|
||||||
let (source, target) = ep.end_points.into();
|
let (source, target) = ep.end_points.into();
|
||||||
autorouter.board.try_set_band_between_nodes(
|
autorouter.board.try_set_band_between_nodes(
|
||||||
&mut autoroute.last_recorder.data_edit,
|
&mut autoroute.last_recorder.board_data_edit,
|
||||||
source,
|
source,
|
||||||
target,
|
target,
|
||||||
*band,
|
*band,
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarAutorouteCo
|
||||||
self.curr_ratline_index += 1;
|
self.curr_ratline_index += 1;
|
||||||
|
|
||||||
if let Some(new_ratline) = self.ratlines.get(self.curr_ratline_index) {
|
if let Some(new_ratline) = self.ratlines.get(self.curr_ratline_index) {
|
||||||
let (source, target) = new_ratline.ref_(autorouter).terminating_dots();
|
let (origin, destination) = new_ratline.ref_(autorouter).terminating_dots();
|
||||||
let mut router =
|
let mut router =
|
||||||
Router::new(autorouter.board.layout_mut(), self.options.router_options);
|
Router::new(autorouter.board.layout_mut(), self.options.router_options);
|
||||||
|
|
||||||
|
|
@ -216,8 +216,8 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarAutorouteCo
|
||||||
|
|
||||||
self.route = Some(router.route(
|
self.route = Some(router.route(
|
||||||
recorder,
|
recorder,
|
||||||
source,
|
origin,
|
||||||
target,
|
destination,
|
||||||
self.options.router_options.routed_band_width,
|
self.options.router_options.routed_band_width,
|
||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ impl Planner {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map_or(TerminatingScheme::Anteroute([-1.0, -1.0]), |dot| {
|
.map_or(TerminatingScheme::Anteroute([-2.0, 0.0]), |dot| {
|
||||||
TerminatingScheme::ExistingFixedDot(dot)
|
TerminatingScheme::ExistingFixedDot(dot)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
graph::{GetMaybeNet, MakePrimitiveRef, PrimitiveIndex},
|
graph::{GetMaybeNet, MakePrimitiveRef, PrimitiveIndex},
|
||||||
},
|
},
|
||||||
geometry::{shape::MeasureLength, GetLayer},
|
geometry::shape::MeasureLength,
|
||||||
graph::MakeRef,
|
graph::MakeRef,
|
||||||
triangulation::GetTrianvertexNodeIndex,
|
triangulation::GetTrianvertexNodeIndex,
|
||||||
};
|
};
|
||||||
|
|
@ -23,6 +23,7 @@ pub type RatlineIndex = EdgeIndex<usize>;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
pub struct RatlineWeight {
|
pub struct RatlineWeight {
|
||||||
|
pub layer: usize,
|
||||||
pub band_termseg: Option<BandTermsegIndex>,
|
pub band_termseg: Option<BandTermsegIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +103,9 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(source)
|
.node_weight(source)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_terminating_dot
|
.layer_terminating_dots
|
||||||
|
.get(&self.layer())
|
||||||
|
.copied()
|
||||||
.unwrap_or(self.endpoint_dots().0);
|
.unwrap_or(self.endpoint_dots().0);
|
||||||
let target_dot = self
|
let target_dot = self
|
||||||
.autorouter
|
.autorouter
|
||||||
|
|
@ -110,17 +113,25 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(target)
|
.node_weight(target)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_terminating_dot
|
.layer_terminating_dots
|
||||||
|
.get(&self.layer())
|
||||||
|
.copied()
|
||||||
.unwrap_or(self.endpoint_dots().1);
|
.unwrap_or(self.endpoint_dots().1);
|
||||||
|
|
||||||
(source_dot, target_dot)
|
(source_dot, target_dot)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layer(&self) -> usize {
|
pub fn layer(&self) -> usize {
|
||||||
self.endpoint_dots()
|
self.autorouter
|
||||||
.0
|
.ratsnest()
|
||||||
.primitive_ref(self.autorouter.board().layout().drawing())
|
.graph()
|
||||||
.layer()
|
.edge_weight(self.index)
|
||||||
|
.unwrap()
|
||||||
|
.layer
|
||||||
|
/*self.endpoint_dots()
|
||||||
|
.0
|
||||||
|
.primitive_ref(self.autorouter.board().layout().drawing())
|
||||||
|
.layer()*/
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn net(&self) -> usize {
|
pub fn net(&self) -> usize {
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,11 @@ impl From<RatvertexNodeIndex> for crate::layout::NodeIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RatvertexWeight {
|
pub struct RatvertexWeight {
|
||||||
vertex: RatvertexNodeIndex,
|
vertex: RatvertexNodeIndex,
|
||||||
pub pos: Point,
|
pub pos: Point,
|
||||||
pub maybe_terminating_dot: Option<FixedDotIndex>,
|
pub layer_terminating_dots: BTreeMap<usize, FixedDotIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetTrianvertexNodeIndex<RatvertexNodeIndex> for RatvertexWeight {
|
impl GetTrianvertexNodeIndex<RatvertexNodeIndex> for RatvertexWeight {
|
||||||
|
|
@ -118,11 +118,11 @@ impl Ratsnest {
|
||||||
|
|
||||||
let mut triangulations = BTreeMap::new();
|
let mut triangulations = BTreeMap::new();
|
||||||
|
|
||||||
this.add_layer_to_ratsnest(board, &mut triangulations, principal_layer);
|
this.add_layer_to_ratsnest_triangulations(board, &mut triangulations, principal_layer);
|
||||||
|
|
||||||
for layer in 0..board.layout().drawing().layer_count() {
|
for layer in 0..board.layout().drawing().layer_count() {
|
||||||
if layer != principal_layer {
|
if layer != principal_layer {
|
||||||
this.add_layer_to_ratsnest(board, &mut triangulations, layer);
|
this.add_layer_to_ratsnest_triangulations(board, &mut triangulations, layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,7 +158,7 @@ impl Ratsnest {
|
||||||
Ok(this)
|
Ok(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_layer_to_ratsnest(
|
fn add_layer_to_ratsnest_triangulations(
|
||||||
&mut self,
|
&mut self,
|
||||||
board: &Board<impl AccessMesadata>,
|
board: &Board<impl AccessMesadata>,
|
||||||
triangulations: &mut BTreeMap<
|
triangulations: &mut BTreeMap<
|
||||||
|
|
@ -190,7 +190,7 @@ impl Ratsnest {
|
||||||
triangulation.add_vertex(RatvertexWeight {
|
triangulation.add_vertex(RatvertexWeight {
|
||||||
vertex,
|
vertex,
|
||||||
pos,
|
pos,
|
||||||
maybe_terminating_dot: None,
|
layer_terminating_dots: BTreeMap::new(),
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
@ -229,12 +229,18 @@ impl Ratsnest {
|
||||||
pub fn assign_terminating_dot_to_ratvertex(
|
pub fn assign_terminating_dot_to_ratvertex(
|
||||||
&mut self,
|
&mut self,
|
||||||
node_index: NodeIndex<usize>,
|
node_index: NodeIndex<usize>,
|
||||||
|
layer: usize,
|
||||||
terminating_dot: FixedDotIndex,
|
terminating_dot: FixedDotIndex,
|
||||||
) {
|
) {
|
||||||
self.graph
|
self.graph
|
||||||
.node_weight_mut(node_index)
|
.node_weight_mut(node_index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_terminating_dot = Some(terminating_dot)
|
.layer_terminating_dots
|
||||||
|
.insert(layer, terminating_dot);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assign_layer_to_ratline(&mut self, ratline: RatlineIndex, layer: usize) {
|
||||||
|
self.graph.edge_weight_mut(ratline).unwrap().layer = layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_band_termseg_to_ratline(
|
pub fn assign_band_termseg_to_ratline(
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ impl Edit for BoardDataEdit {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct BoardEdit {
|
pub struct BoardEdit {
|
||||||
pub data_edit: BoardDataEdit,
|
pub board_data_edit: BoardDataEdit,
|
||||||
pub layout_edit: LayoutEdit,
|
pub layout_edit: LayoutEdit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ impl BoardEdit {
|
||||||
|
|
||||||
pub fn new_from_edits(data_edit: BoardDataEdit, layout_edit: LayoutEdit) -> Self {
|
pub fn new_from_edits(data_edit: BoardDataEdit, layout_edit: LayoutEdit) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data_edit,
|
board_data_edit: data_edit,
|
||||||
layout_edit,
|
layout_edit,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,12 +48,12 @@ impl BoardEdit {
|
||||||
|
|
||||||
impl Edit for BoardEdit {
|
impl Edit for BoardEdit {
|
||||||
fn reverse_inplace(&mut self) {
|
fn reverse_inplace(&mut self) {
|
||||||
self.data_edit.reverse_inplace();
|
self.board_data_edit.reverse_inplace();
|
||||||
self.layout_edit.reverse_inplace();
|
self.layout_edit.reverse_inplace();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge(&mut self, edit: Self) {
|
fn merge(&mut self, edit: Self) {
|
||||||
self.data_edit.merge(edit.data_edit);
|
self.board_data_edit.merge(edit.board_data_edit);
|
||||||
self.layout_edit.merge(edit.layout_edit);
|
self.layout_edit.merge(edit.layout_edit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ use crate::{
|
||||||
dot::{FixedDotIndex, FixedDotWeight},
|
dot::{FixedDotIndex, FixedDotWeight},
|
||||||
graph::PrimitiveIndex,
|
graph::PrimitiveIndex,
|
||||||
seg::{FixedSegIndex, FixedSegWeight},
|
seg::{FixedSegIndex, FixedSegWeight},
|
||||||
DrawingException,
|
DrawingException, Infringement,
|
||||||
},
|
},
|
||||||
geometry::{edit::ApplyGeometryEdit, GenericNode, GetLayer},
|
geometry::{edit::ApplyGeometryEdit, GenericNode, GetLayer},
|
||||||
graph::{GenericIndex, MakeRef},
|
graph::{GenericIndex, MakeRef},
|
||||||
layout::{poly::PolyWeight, CompoundWeight, Layout, NodeIndex},
|
layout::{poly::PolyWeight, via::ViaWeight, CompoundWeight, Layout, NodeIndex},
|
||||||
router::ng::EtchedPath,
|
router::ng::EtchedPath,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -105,6 +105,24 @@ impl<M> Board<M> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: AccessMesadata> Board<M> {
|
impl<M: AccessMesadata> Board<M> {
|
||||||
|
pub fn add_via(
|
||||||
|
&mut self,
|
||||||
|
recorder: &mut BoardEdit,
|
||||||
|
weight: ViaWeight,
|
||||||
|
maybe_pin: Option<String>,
|
||||||
|
) -> Result<(GenericIndex<ViaWeight>, Vec<FixedDotIndex>), Infringement> {
|
||||||
|
let (weight, dots) = self.layout.add_via(&mut recorder.layout_edit, weight)?;
|
||||||
|
|
||||||
|
if let Some(pin) = maybe_pin {
|
||||||
|
for dot in dots.clone() {
|
||||||
|
self.pinname_nodes
|
||||||
|
.insert(pin.clone(), GenericNode::Primitive(dot.into()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((weight, 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.
|
||||||
|
|
@ -295,7 +313,7 @@ impl<M: AccessMesadata> Board<M> {
|
||||||
}
|
}
|
||||||
|
|
||||||
recorder
|
recorder
|
||||||
.data_edit
|
.board_data_edit
|
||||||
.bands
|
.bands
|
||||||
.insert(bandname, (maybe_band, None));
|
.insert(bandname, (maybe_band, None));
|
||||||
|
|
||||||
|
|
@ -328,7 +346,7 @@ impl<M: AccessMesadata> Board<M> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_edit(&mut self, edit: &BoardEdit) {
|
pub fn apply_edit(&mut self, edit: &BoardEdit) {
|
||||||
for (bandname, (maybe_old_band_uid, ..)) in &edit.data_edit.bands {
|
for (bandname, (maybe_old_band_uid, ..)) in &edit.board_data_edit.bands {
|
||||||
if maybe_old_band_uid.is_some() {
|
if maybe_old_band_uid.is_some() {
|
||||||
self.band_bandname.remove_by_right(bandname);
|
self.band_bandname.remove_by_right(bandname);
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +354,7 @@ impl<M: AccessMesadata> Board<M> {
|
||||||
|
|
||||||
self.layout_mut().apply(&edit.layout_edit);
|
self.layout_mut().apply(&edit.layout_edit);
|
||||||
|
|
||||||
for (bandname, (.., maybe_new_band_uid)) in &edit.data_edit.bands {
|
for (bandname, (.., maybe_new_band_uid)) in &edit.board_data_edit.bands {
|
||||||
if let Some(band_uid) = maybe_new_band_uid {
|
if let Some(band_uid) = maybe_new_band_uid {
|
||||||
self.band_bandname.insert(*band_uid, bandname.clone());
|
self.band_bandname.insert(*band_uid, bandname.clone());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,7 @@ impl<
|
||||||
|
|
||||||
pub fn remove_primitive(&mut self, primitive: PI) {
|
pub fn remove_primitive(&mut self, primitive: PI) {
|
||||||
let maybe_removed = self.graph.remove_node(primitive.index().into());
|
let maybe_removed = self.graph.remove_node(primitive.index().into());
|
||||||
debug_assert!(maybe_removed.is_some());
|
assert!(maybe_removed.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_dot(&mut self, dot: DI, to: Point) {
|
pub fn move_dot(&mut self, dot: DI, to: Point) {
|
||||||
|
|
@ -356,7 +356,7 @@ impl<
|
||||||
.find(|edge| matches!(edge.weight(), GeometryLabel::Outer))
|
.find(|edge| matches!(edge.weight(), GeometryLabel::Outer))
|
||||||
{
|
{
|
||||||
let maybe_removed = self.graph.remove_edge(old_inner_edge.id());
|
let maybe_removed = self.graph.remove_edge(old_inner_edge.id());
|
||||||
debug_assert!(maybe_removed.is_some());
|
assert!(maybe_removed.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(new_inner) = maybe_new_inner {
|
if let Some(new_inner) = maybe_new_inner {
|
||||||
|
|
@ -656,7 +656,7 @@ impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, D
|
||||||
|
|
||||||
fn remove_compound(&mut self, compound: GenericIndex<CW>) {
|
fn remove_compound(&mut self, compound: GenericIndex<CW>) {
|
||||||
let maybe_removed = self.graph.remove_node(compound.index().into());
|
let maybe_removed = self.graph.remove_node(compound.index().into());
|
||||||
debug_assert!(maybe_removed.is_some());
|
assert!(maybe_removed.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_to_compound<I>(&mut self, primitive: I, entry_label: Cel, compound: GenericIndex<CW>)
|
fn add_to_compound<I>(&mut self, primitive: I, entry_label: Cel, compound: GenericIndex<CW>)
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,8 @@ impl Prenavmesh {
|
||||||
let primitive = node.primitive_ref(layout.drawing());
|
let primitive = node.primitive_ref(layout.drawing());
|
||||||
|
|
||||||
let Some(primitive_net) = primitive.maybe_net() else {
|
let Some(primitive_net) = primitive.maybe_net() else {
|
||||||
|
assert_ne!(node, origin.into());
|
||||||
|
assert_ne!(node, destination.into());
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -215,6 +217,10 @@ impl Prenavmesh {
|
||||||
// false positives in some cases, so in the future, instead of this,
|
// false positives in some cases, so in the future, instead of this,
|
||||||
// create a fillet compound type and check for compound membership.
|
// create a fillet compound type and check for compound membership.
|
||||||
if Self::is_fixed_dot_filleted(layout, dot) {
|
if Self::is_fixed_dot_filleted(layout, dot) {
|
||||||
|
// FIXME: anteroute dot may get skipped here, which
|
||||||
|
// results in a panic.
|
||||||
|
assert_ne!(origin, dot);
|
||||||
|
assert_ne!(destination, dot);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue