mirror of https://codeberg.org/topola/topola.git
feat(drawing/query): Don't infringe or collide primitives on different layers
This commit is contained in:
parent
f4b78749b1
commit
00aa79ff31
|
|
@ -162,13 +162,7 @@ impl SpecctraMesadata {
|
|||
}
|
||||
}
|
||||
|
||||
/// Retrieves the Specctra routing rule associated with a specified net ID.
|
||||
///
|
||||
/// This function looks up the routing rule for a given net ID. It first checks if the net is
|
||||
/// associated with a net class. If a net class is found, it retrieves the corresponding rule
|
||||
/// from the class rules. If no class is associated, or if the class does not have a defined rule,
|
||||
/// it defaults to the general structure rule.
|
||||
pub fn get_rule(&self, net: usize) -> &SpecctraRule {
|
||||
pub fn rule(&self, net: usize) -> &SpecctraRule {
|
||||
self.net_netclass
|
||||
.get(&net)
|
||||
.and_then(|netclass| self.class_rules.get(netclass))
|
||||
|
|
@ -177,11 +171,15 @@ impl SpecctraMesadata {
|
|||
}
|
||||
|
||||
impl AccessRules for SpecctraMesadata {
|
||||
fn clearance(&self, conditions1: &Conditions<'_>, conditions2: &Conditions<'_>) -> f64 {
|
||||
let clearance1 = self.get_rule(conditions1.net).clearance;
|
||||
let clearance2 = self.get_rule(conditions2.net).clearance;
|
||||
fn clearance(&self, conditions1: &Conditions<'_>, conditions2: &Conditions<'_>) -> Option<f64> {
|
||||
if conditions1.maybe_layer != conditions2.maybe_layer {
|
||||
return None;
|
||||
}
|
||||
|
||||
f64::max(clearance1, clearance2)
|
||||
let clearance1 = self.rule(conditions1.net).clearance;
|
||||
let clearance2 = self.rule(conditions2.net).clearance;
|
||||
|
||||
Some(f64::max(clearance1, clearance2))
|
||||
}
|
||||
|
||||
fn largest_clearance(&self, _maybe_net: Option<usize>) -> f64 {
|
||||
|
|
|
|||
|
|
@ -26,11 +26,10 @@ pub struct Conditions<'a> {
|
|||
#[serde(borrow)]
|
||||
pub maybe_region: Option<Cow<'a, str>>,
|
||||
|
||||
#[serde(borrow)]
|
||||
pub maybe_layer: Option<Cow<'a, str>>,
|
||||
pub maybe_layer: Option<usize>,
|
||||
}
|
||||
|
||||
pub trait AccessRules {
|
||||
fn clearance(&self, conditions1: &Conditions<'_>, conditions2: &Conditions<'_>) -> f64;
|
||||
fn clearance(&self, conditions1: &Conditions<'_>, conditions2: &Conditions<'_>) -> Option<f64>;
|
||||
fn largest_clearance(&self, net: Option<usize>) -> f64;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
fn clearance(&self, lhs: Option<&Conditions<'_>>, rhs: Option<&Conditions<'_>>) -> f64 {
|
||||
match (lhs, rhs) {
|
||||
(None, _) | (_, None) => 0.0,
|
||||
(Some(lhs), Some(rhs)) => self.rules().clearance(lhs, rhs),
|
||||
(Some(lhs), Some(rhs)) => self.rules().clearance(lhs, rhs).unwrap_or(0.0),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -219,13 +219,13 @@ where
|
|||
|
||||
impl<'a, W, CW, Cel, R> GetConditions<'a> for &GenericPrimitive<'a, W, CW, Cel, R>
|
||||
where
|
||||
GenericPrimitive<'a, W, CW, Cel, R>: GetMaybeNet,
|
||||
GenericPrimitive<'a, W, CW, Cel, R>: GetMaybeNet + GetLayer,
|
||||
{
|
||||
fn conditions(self) -> Option<Conditions<'a>> {
|
||||
self.maybe_net().map(|net| Conditions {
|
||||
net,
|
||||
maybe_region: Some("A".into()),
|
||||
maybe_layer: Some("F.Cu".into()),
|
||||
maybe_region: Some("A".into()), // TODO.
|
||||
maybe_layer: Some(self.layer()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,12 +228,16 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
&conditions,
|
||||
infringee_conditions,
|
||||
) {
|
||||
(None, _) | (_, None) => 0.0,
|
||||
(None, _) | (_, None) => return None,
|
||||
(Some(lhs), Some(rhs)) => {
|
||||
let Some(clearance) = self.rules().clearance(lhs, &rhs) else {
|
||||
return None;
|
||||
};
|
||||
|
||||
// Note the epsilon comparison.
|
||||
// XXX: Epsilon is probably too large. But what should
|
||||
// it be exactly then?
|
||||
(self.rules().clearance(lhs, &rhs) - epsilon).clamp(0.0, f64::INFINITY)
|
||||
(clearance - epsilon).clamp(0.0, f64::INFINITY)
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -298,6 +302,10 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
|||
})
|
||||
.filter(|collidee| predicate(&self, collider, *collidee))
|
||||
.find_map(|collidee| {
|
||||
if collider.primitive_ref(self).layer() != collidee.primitive_ref(self).layer() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let collidee_shape = collidee.primitive_ref(self).shape();
|
||||
|
||||
if collider_shape.intersects(&collidee_shape) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue