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.
|
pub fn rule(&self, net: usize) -> &SpecctraRule {
|
||||||
///
|
|
||||||
/// 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 {
|
|
||||||
self.net_netclass
|
self.net_netclass
|
||||||
.get(&net)
|
.get(&net)
|
||||||
.and_then(|netclass| self.class_rules.get(netclass))
|
.and_then(|netclass| self.class_rules.get(netclass))
|
||||||
|
|
@ -177,11 +171,15 @@ impl SpecctraMesadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccessRules for SpecctraMesadata {
|
impl AccessRules for SpecctraMesadata {
|
||||||
fn clearance(&self, conditions1: &Conditions<'_>, conditions2: &Conditions<'_>) -> f64 {
|
fn clearance(&self, conditions1: &Conditions<'_>, conditions2: &Conditions<'_>) -> Option<f64> {
|
||||||
let clearance1 = self.get_rule(conditions1.net).clearance;
|
if conditions1.maybe_layer != conditions2.maybe_layer {
|
||||||
let clearance2 = self.get_rule(conditions2.net).clearance;
|
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 {
|
fn largest_clearance(&self, _maybe_net: Option<usize>) -> f64 {
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,10 @@ pub struct Conditions<'a> {
|
||||||
#[serde(borrow)]
|
#[serde(borrow)]
|
||||||
pub maybe_region: Option<Cow<'a, str>>,
|
pub maybe_region: Option<Cow<'a, str>>,
|
||||||
|
|
||||||
#[serde(borrow)]
|
pub maybe_layer: Option<usize>,
|
||||||
pub maybe_layer: Option<Cow<'a, str>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AccessRules {
|
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;
|
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 {
|
fn clearance(&self, lhs: Option<&Conditions<'_>>, rhs: Option<&Conditions<'_>>) -> f64 {
|
||||||
match (lhs, rhs) {
|
match (lhs, rhs) {
|
||||||
(None, _) | (_, None) => 0.0,
|
(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>
|
impl<'a, W, CW, Cel, R> GetConditions<'a> for &GenericPrimitive<'a, W, CW, Cel, R>
|
||||||
where
|
where
|
||||||
GenericPrimitive<'a, W, CW, Cel, R>: GetMaybeNet,
|
GenericPrimitive<'a, W, CW, Cel, R>: GetMaybeNet + GetLayer,
|
||||||
{
|
{
|
||||||
fn conditions(self) -> Option<Conditions<'a>> {
|
fn conditions(self) -> Option<Conditions<'a>> {
|
||||||
self.maybe_net().map(|net| Conditions {
|
self.maybe_net().map(|net| Conditions {
|
||||||
net,
|
net,
|
||||||
maybe_region: Some("A".into()),
|
maybe_region: Some("A".into()), // TODO.
|
||||||
maybe_layer: Some("F.Cu".into()),
|
maybe_layer: Some(self.layer()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -228,12 +228,16 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
|
||||||
&conditions,
|
&conditions,
|
||||||
infringee_conditions,
|
infringee_conditions,
|
||||||
) {
|
) {
|
||||||
(None, _) | (_, None) => 0.0,
|
(None, _) | (_, None) => return None,
|
||||||
(Some(lhs), Some(rhs)) => {
|
(Some(lhs), Some(rhs)) => {
|
||||||
|
let Some(clearance) = self.rules().clearance(lhs, &rhs) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
// Note the epsilon comparison.
|
// Note the epsilon comparison.
|
||||||
// XXX: Epsilon is probably too large. But what should
|
// XXX: Epsilon is probably too large. But what should
|
||||||
// it be exactly then?
|
// 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))
|
.filter(|collidee| predicate(&self, collider, *collidee))
|
||||||
.find_map(|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();
|
let collidee_shape = collidee.primitive_ref(self).shape();
|
||||||
|
|
||||||
if collider_shape.intersects(&collidee_shape) {
|
if collider_shape.intersects(&collidee_shape) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue