mirror of https://codeberg.org/topola/topola.git
feat(autorouter/anterouter): As second choice, anteroute fanouts in ordinal directions
This commit is contained in:
parent
43f8d69281
commit
60cf00e014
|
|
@ -11,7 +11,11 @@ use serde::{Deserialize, Serialize};
|
|||
use specctra_core::mesadata::AccessMesadata;
|
||||
|
||||
use crate::{
|
||||
autorouter::{compass_direction::CardinalDirection, ratline::RatlineIndex, Autorouter},
|
||||
autorouter::{
|
||||
compass_direction::{CardinalDirection, CompassDirection, OrdinalDirection},
|
||||
ratline::RatlineIndex,
|
||||
Autorouter,
|
||||
},
|
||||
board::edit::BoardEdit,
|
||||
drawing::{
|
||||
dot::FixedDotIndex,
|
||||
|
|
@ -157,7 +161,7 @@ impl Anterouter {
|
|||
source_dot,
|
||||
small_bbox,
|
||||
target_layer,
|
||||
CardinalDirection::nearest_to_vector(ratline_delta),
|
||||
CardinalDirection::nearest_from_vector(ratline_delta),
|
||||
options,
|
||||
)
|
||||
.is_ok()
|
||||
|
|
@ -190,7 +194,37 @@ impl Anterouter {
|
|||
source_dot,
|
||||
large_bbox,
|
||||
target_layer,
|
||||
CardinalDirection::nearest_to_vector(ratline_delta),
|
||||
CardinalDirection::nearest_from_vector(ratline_delta),
|
||||
options,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if self
|
||||
.anteroute_fanout_on_bbox(
|
||||
autorouter,
|
||||
ratvertex,
|
||||
source_dot,
|
||||
small_bbox,
|
||||
target_layer,
|
||||
OrdinalDirection::nearest_from_vector(ratline_delta),
|
||||
options,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if self
|
||||
.anteroute_fanout_on_bbox(
|
||||
autorouter,
|
||||
ratvertex,
|
||||
source_dot,
|
||||
large_bbox,
|
||||
target_layer,
|
||||
OrdinalDirection::nearest_from_vector(ratline_delta),
|
||||
options,
|
||||
)
|
||||
.is_ok()
|
||||
|
|
@ -208,17 +242,17 @@ impl Anterouter {
|
|||
source_dot: FixedDotIndex,
|
||||
bbox: AABB<[f64; 2]>,
|
||||
target_layer: usize,
|
||||
preferred_cardinal_direction: CardinalDirection,
|
||||
preferred_compass_direction: impl CompassDirection,
|
||||
options: &AnterouterOptions,
|
||||
) -> Result<(), ()> {
|
||||
if self
|
||||
.anteroute_fanout_on_bbox_in_cardinal_direction(
|
||||
.anteroute_fanout_on_bbox_in_direction(
|
||||
autorouter,
|
||||
ratvertex,
|
||||
source_dot,
|
||||
bbox,
|
||||
target_layer,
|
||||
preferred_cardinal_direction,
|
||||
preferred_compass_direction,
|
||||
options,
|
||||
)
|
||||
.is_ok()
|
||||
|
|
@ -226,15 +260,15 @@ impl Anterouter {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let mut counterclockwise_turning_cardinal_direction = preferred_cardinal_direction;
|
||||
let mut clockwise_turning_cardinal_direction = preferred_cardinal_direction;
|
||||
let mut counterclockwise_turning_cardinal_direction = preferred_compass_direction;
|
||||
let mut clockwise_turning_cardinal_direction = preferred_compass_direction;
|
||||
|
||||
loop {
|
||||
counterclockwise_turning_cardinal_direction =
|
||||
counterclockwise_turning_cardinal_direction.turn_counterclockwise();
|
||||
|
||||
if self
|
||||
.anteroute_fanout_on_bbox_in_cardinal_direction(
|
||||
.anteroute_fanout_on_bbox_in_direction(
|
||||
autorouter,
|
||||
ratvertex,
|
||||
source_dot,
|
||||
|
|
@ -252,7 +286,7 @@ impl Anterouter {
|
|||
clockwise_turning_cardinal_direction.turn_clockwise();
|
||||
|
||||
if self
|
||||
.anteroute_fanout_on_bbox_in_cardinal_direction(
|
||||
.anteroute_fanout_on_bbox_in_direction(
|
||||
autorouter,
|
||||
ratvertex,
|
||||
source_dot,
|
||||
|
|
@ -266,31 +300,31 @@ impl Anterouter {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
if counterclockwise_turning_cardinal_direction == preferred_cardinal_direction
|
||||
|| clockwise_turning_cardinal_direction == preferred_cardinal_direction
|
||||
if counterclockwise_turning_cardinal_direction == preferred_compass_direction
|
||||
|| clockwise_turning_cardinal_direction == preferred_compass_direction
|
||||
{
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn anteroute_fanout_on_bbox_in_cardinal_direction(
|
||||
fn anteroute_fanout_on_bbox_in_direction(
|
||||
&mut self,
|
||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||
ratvertex: NodeIndex<usize>,
|
||||
source_dot: FixedDotIndex,
|
||||
bbox: AABB<[f64; 2]>,
|
||||
target_layer: usize,
|
||||
cardinal_direction: CardinalDirection,
|
||||
direction: impl Into<Point>,
|
||||
options: &AnterouterOptions,
|
||||
) -> Result<(), ()> {
|
||||
let (_, dots) = self.place_fanout_via_on_bbox_in_cardinal_direction(
|
||||
let (_, dots) = self.place_fanout_via_on_bbox_in_direction(
|
||||
autorouter,
|
||||
ratvertex,
|
||||
source_dot,
|
||||
bbox,
|
||||
target_layer,
|
||||
cardinal_direction,
|
||||
direction,
|
||||
options,
|
||||
)?;
|
||||
|
||||
|
|
@ -326,14 +360,14 @@ impl Anterouter {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn place_fanout_via_on_bbox_in_cardinal_direction(
|
||||
fn place_fanout_via_on_bbox_in_direction(
|
||||
&mut self,
|
||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||
ratvertex: NodeIndex<usize>,
|
||||
source_dot: FixedDotIndex,
|
||||
bbox: AABB<[f64; 2]>,
|
||||
target_layer: usize,
|
||||
cardinal_direction: CardinalDirection,
|
||||
direction: impl Into<Point>,
|
||||
options: &AnterouterOptions,
|
||||
) -> Result<(GenericIndex<ViaWeight>, Vec<FixedDotIndex>), ()> {
|
||||
let source_layer = autorouter
|
||||
|
|
@ -357,7 +391,7 @@ impl Anterouter {
|
|||
.shape()
|
||||
.center();
|
||||
|
||||
let cardinal_direction_vector = Point::from(cardinal_direction);
|
||||
let cardinal_direction_vector = direction.into();
|
||||
|
||||
let bbox_anchor = point! {
|
||||
x: (bbox.upper()[0] - bbox.lower()[0]) / 2.0 * cardinal_direction_vector.x(),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@
|
|||
|
||||
use geo::Point;
|
||||
|
||||
pub trait CompassDirection: Copy + PartialEq + Into<Point> {
|
||||
fn nearest_from_vector(vector: Point) -> Self;
|
||||
fn turn_clockwise(self) -> Self;
|
||||
fn turn_counterclockwise(self) -> Self;
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CardinalDirection {
|
||||
North,
|
||||
|
|
@ -13,8 +19,8 @@ pub enum CardinalDirection {
|
|||
}
|
||||
|
||||
impl From<CardinalDirection> for Point {
|
||||
fn from(compass_direction: CardinalDirection) -> Point {
|
||||
match compass_direction {
|
||||
fn from(cardinal_direction: CardinalDirection) -> Point {
|
||||
match cardinal_direction {
|
||||
CardinalDirection::North => [0.0, -1.0].into(),
|
||||
CardinalDirection::West => [-1.0, 0.0].into(),
|
||||
CardinalDirection::South => [0.0, 1.0].into(),
|
||||
|
|
@ -23,8 +29,8 @@ impl From<CardinalDirection> for Point {
|
|||
}
|
||||
}
|
||||
|
||||
impl CardinalDirection {
|
||||
pub fn nearest_to_vector(vector: Point) -> Self {
|
||||
impl CompassDirection for CardinalDirection {
|
||||
fn nearest_from_vector(vector: Point) -> Self {
|
||||
if vector.x().abs() > vector.y().abs() {
|
||||
if vector.x() > 0.0 {
|
||||
Self::East
|
||||
|
|
@ -40,7 +46,16 @@ impl CardinalDirection {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn turn_counterclockwise(self) -> Self {
|
||||
fn turn_clockwise(self) -> Self {
|
||||
match self {
|
||||
Self::North => Self::East,
|
||||
Self::East => Self::South,
|
||||
Self::South => Self::West,
|
||||
Self::West => Self::North,
|
||||
}
|
||||
}
|
||||
|
||||
fn turn_counterclockwise(self) -> Self {
|
||||
match self {
|
||||
Self::North => Self::West,
|
||||
Self::West => Self::South,
|
||||
|
|
@ -48,13 +63,55 @@ impl CardinalDirection {
|
|||
Self::East => Self::North,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn turn_clockwise(self) -> Self {
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum OrdinalDirection {
|
||||
NorthWest,
|
||||
SouthWest,
|
||||
SouthEast,
|
||||
NorthEast,
|
||||
}
|
||||
|
||||
impl From<OrdinalDirection> for Point {
|
||||
fn from(ordinal_direction: OrdinalDirection) -> Point {
|
||||
match ordinal_direction {
|
||||
OrdinalDirection::NorthWest => [-1.0, -1.0].into(),
|
||||
OrdinalDirection::SouthWest => [-1.0, 1.0].into(),
|
||||
OrdinalDirection::SouthEast => [1.0, 1.0].into(),
|
||||
OrdinalDirection::NorthEast => [1.0, -1.0].into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CompassDirection for OrdinalDirection {
|
||||
fn nearest_from_vector(vector: Point) -> Self {
|
||||
if vector.x() > 0.0 && vector.y() > 0.0 {
|
||||
Self::SouthEast
|
||||
} else if vector.x() > 0.0 && vector.y() < 0.0 {
|
||||
Self::NorthEast
|
||||
} else if vector.x() < 0.0 && vector.y() < 0.0 {
|
||||
Self::NorthWest
|
||||
} else {
|
||||
Self::NorthEast
|
||||
}
|
||||
}
|
||||
|
||||
fn turn_clockwise(self) -> Self {
|
||||
match self {
|
||||
Self::North => Self::East,
|
||||
Self::East => Self::South,
|
||||
Self::South => Self::West,
|
||||
Self::West => Self::North,
|
||||
Self::NorthWest => Self::SouthWest,
|
||||
Self::SouthWest => Self::SouthEast,
|
||||
Self::SouthEast => Self::SouthWest,
|
||||
Self::NorthEast => Self::NorthWest,
|
||||
}
|
||||
}
|
||||
|
||||
fn turn_counterclockwise(self) -> Self {
|
||||
match self {
|
||||
Self::NorthWest => Self::SouthWest,
|
||||
Self::SouthWest => Self::SouthEast,
|
||||
Self::SouthEast => Self::NorthEast,
|
||||
Self::NorthEast => Self::NorthWest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -86,8 +143,8 @@ impl From<PrincipalWind> for Point {
|
|||
}
|
||||
}
|
||||
|
||||
impl PrincipalWind {
|
||||
pub fn nearest_to_vector(vector: Point) -> Self {
|
||||
impl CompassDirection for PrincipalWind {
|
||||
fn nearest_from_vector(vector: Point) -> Self {
|
||||
if vector.x() == 0.0 && vector.y() == 0.0 {
|
||||
panic!("Zero vector has no direction");
|
||||
}
|
||||
|
|
@ -110,20 +167,7 @@ impl PrincipalWind {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn turn_counterclockwise(self) -> Self {
|
||||
match self {
|
||||
Self::North => Self::NorthWest,
|
||||
Self::NorthWest => Self::West,
|
||||
Self::West => Self::SouthWest,
|
||||
Self::SouthWest => Self::South,
|
||||
Self::South => Self::SouthEast,
|
||||
Self::SouthEast => Self::East,
|
||||
Self::East => Self::NorthEast,
|
||||
Self::NorthEast => Self::North,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn turn_clockwise(self) -> Self {
|
||||
fn turn_clockwise(self) -> Self {
|
||||
match self {
|
||||
Self::North => Self::NorthEast,
|
||||
Self::NorthEast => Self::East,
|
||||
|
|
@ -135,4 +179,17 @@ impl PrincipalWind {
|
|||
Self::NorthWest => Self::North,
|
||||
}
|
||||
}
|
||||
|
||||
fn turn_counterclockwise(self) -> Self {
|
||||
match self {
|
||||
Self::North => Self::NorthWest,
|
||||
Self::NorthWest => Self::West,
|
||||
Self::West => Self::SouthWest,
|
||||
Self::SouthWest => Self::South,
|
||||
Self::South => Self::SouthEast,
|
||||
Self::SouthEast => Self::East,
|
||||
Self::East => Self::NorthEast,
|
||||
Self::NorthEast => Self::North,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue