mirror of https://codeberg.org/topola/topola.git
feat(autorouter/ratline): Only count interior ratline intersections
This hardly makes a difference for now, but may become useful later.
This commit is contained in:
parent
b49aa9e1b7
commit
e5e5f9513e
|
|
@ -115,8 +115,8 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
|
|
||||||
match options.presort_by {
|
match options.presort_by {
|
||||||
PresortBy::RatlineIntersectionCountAndLength => ratlines.sort_unstable_by(|a, b| {
|
PresortBy::RatlineIntersectionCountAndLength => ratlines.sort_unstable_by(|a, b| {
|
||||||
let a_intersector_count = a.ref_(self).find_intersecting_ratlines().count();
|
let a_intersector_count = a.ref_(self).interior_obstacle_ratlines().count();
|
||||||
let b_intersector_count = b.ref_(self).find_intersecting_ratlines().count();
|
let b_intersector_count = b.ref_(self).interior_obstacle_ratlines().count();
|
||||||
|
|
||||||
let primary_ordering = a_intersector_count.cmp(&b_intersector_count);
|
let primary_ordering = a_intersector_count.cmp(&b_intersector_count);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
use geo::{line_intersection::line_intersection, Distance, Euclidean, Line};
|
use geo::{line_intersection::line_intersection, Distance, Euclidean, Line, LineIntersection};
|
||||||
use petgraph::graph::EdgeIndex;
|
use petgraph::graph::{EdgeIndex, NodeIndex};
|
||||||
use specctra_core::mesadata::AccessMesadata;
|
use specctra_core::mesadata::AccessMesadata;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -74,26 +74,25 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
(source_dot, target_dot)
|
(source_dot, target_dot)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_intersecting_ratlines(&self) -> impl Iterator<Item = RatlineIndex> + '_ {
|
pub fn closure_obstacle_ratlines(&self) -> impl Iterator<Item = RatlineIndex> + '_ {
|
||||||
let self_line = self.line();
|
self.intersecting_ratlines()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn interior_obstacle_ratlines(&self) -> impl Iterator<Item = RatlineIndex> + '_ {
|
||||||
|
self.intersecting_ratlines()
|
||||||
|
.filter(|index| !self.is_pin_cutter(*index))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn intersecting_ratlines(&self) -> impl Iterator<Item = RatlineIndex> + '_ {
|
||||||
|
let self_line_segment = self.line_segment();
|
||||||
|
|
||||||
self.autorouter
|
self.autorouter
|
||||||
.ratsnest()
|
.ratsnest()
|
||||||
.graph()
|
.graph()
|
||||||
.edge_indices()
|
.edge_indices()
|
||||||
.filter(move |other| {
|
.filter(move |other| {
|
||||||
let (self_source, self_target) = self
|
let (self_source, self_target) = self.endpoint_indices();
|
||||||
.autorouter
|
let (other_source, other_target) = other.ref_(self.autorouter).endpoint_indices();
|
||||||
.ratsnest
|
|
||||||
.graph()
|
|
||||||
.edge_endpoints(self.index)
|
|
||||||
.unwrap();
|
|
||||||
let (other_source, other_target) = self
|
|
||||||
.autorouter
|
|
||||||
.ratsnest
|
|
||||||
.graph()
|
|
||||||
.edge_endpoints(*other)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
self_source != other_source
|
self_source != other_source
|
||||||
&& self_source != other_target
|
&& self_source != other_target
|
||||||
|
|
@ -101,19 +100,33 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
&& self_target != other_target
|
&& self_target != other_target
|
||||||
})
|
})
|
||||||
.filter(move |other| {
|
.filter(move |other| {
|
||||||
let other_line = other.ref_(self.autorouter).line();
|
let other_line_segment = other.ref_(self.autorouter).line_segment();
|
||||||
|
|
||||||
line_intersection(self_line, other_line).is_some()
|
line_intersection(self_line_segment, other_line_segment).is_some()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line(&self) -> Line {
|
fn is_pin_cutter(&self, other: RatlineIndex) -> bool {
|
||||||
let (source, target) = self
|
// TODO: For now, instead of detecting whether endpoint ratvertex pins
|
||||||
.autorouter
|
// are cut, we only check if the intersection between self and the
|
||||||
.ratsnest
|
// supposed cutter is not internal.
|
||||||
.graph()
|
|
||||||
.edge_endpoints(self.index)
|
let self_line_segment = self.line_segment();
|
||||||
.unwrap();
|
let other_line_segment = other.ref_(self.autorouter).line_segment();
|
||||||
|
|
||||||
|
if let Some(LineIntersection::SinglePoint { is_proper, .. }) =
|
||||||
|
line_intersection(self_line_segment, other_line_segment)
|
||||||
|
{
|
||||||
|
// It would make more sense to check for non-internality only in
|
||||||
|
// self, but this gives me the result I want too for now.
|
||||||
|
!is_proper
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn line_segment(&self) -> Line {
|
||||||
|
let (source, target) = self.endpoint_indices();
|
||||||
let source_pos = self
|
let source_pos = self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnest
|
.ratsnest
|
||||||
|
|
@ -131,11 +144,19 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
|
|
||||||
Line::new(source_pos, target_pos)
|
Line::new(source_pos, target_pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn endpoint_indices(&self) -> (NodeIndex<usize>, NodeIndex<usize>) {
|
||||||
|
self.autorouter
|
||||||
|
.ratsnest
|
||||||
|
.graph()
|
||||||
|
.edge_endpoints(self.index)
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M: AccessMesadata> MeasureLength for RatlineRef<'a, M> {
|
impl<'a, M: AccessMesadata> MeasureLength for RatlineRef<'a, M> {
|
||||||
fn length(&self) -> f64 {
|
fn length(&self) -> f64 {
|
||||||
let line = self.line();
|
let line = self.line_segment();
|
||||||
|
|
||||||
Euclidean::distance(&line.start_point(), &line.end_point())
|
Euclidean::distance(&line.start_point(), &line.end_point())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue