diff --git a/src/bin/topola-sdl2-demo/main.rs b/src/bin/topola-sdl2-demo/main.rs index 6ba516f..50957c2 100644 --- a/src/bin/topola-sdl2-demo/main.rs +++ b/src/bin/topola-sdl2-demo/main.rs @@ -56,7 +56,7 @@ impl RulesTrait for SimpleRules { fn clearance(&self, conditions1: &Conditions, conditions2: &Conditions) -> f64 { *self .net_clearances - .get(&(conditions1.net, conditions2.net)) + .get(&(conditions1.maybe_net, conditions2.maybe_net)) .unwrap_or(&10.0) } diff --git a/src/draw.rs b/src/draw.rs index 59c81e5..66e7a61 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -6,7 +6,7 @@ use crate::{ drawing::{ bend::{BendIndex, LooseBendWeight}, dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight}, - graph::{GetLayer, GetNet, MakePrimitive}, + graph::{GetLayer, GetMaybeNet, MakePrimitive}, guide::{Guide, Head, HeadTrait, SegbendHead}, primitive::GetOtherJoint, rules::RulesTrait, @@ -59,17 +59,33 @@ impl<'a, R: RulesTrait> Draw<'a, R> { .extend_head(head, tangent.start_point()) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; let layer = head.face().primitive(self.layout.layout()).layer(); - let net = head.face().primitive(self.layout.layout()).net(); + let maybe_net = head.face().primitive(self.layout.layout()).maybe_net(); match head.face() { DotIndex::Fixed(dot) => { self.layout - .add_lone_loose_seg(dot, into.into(), LoneLooseSegWeight { width, layer, net }) + .add_lone_loose_seg( + dot, + into.into(), + LoneLooseSegWeight { + width, + layer, + maybe_net, + }, + ) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; } DotIndex::Loose(dot) => { self.layout - .add_seq_loose_seg(into.into(), dot, SeqLooseSegWeight { width, layer, net }) + .add_seq_loose_seg( + into.into(), + dot, + SeqLooseSegWeight { + width, + layer, + maybe_net, + }, + ) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; } } @@ -204,7 +220,7 @@ impl<'a, R: RulesTrait> Draw<'a, R> { offset: f64, ) -> Result { let layer = head.face().primitive(self.layout.layout()).layer(); - let net = head.face().primitive(self.layout.layout()).net(); + let maybe_net = head.face().primitive(self.layout.layout()).maybe_net(); let segbend = self.layout.insert_segbend( head.face(), around, @@ -214,14 +230,18 @@ impl<'a, R: RulesTrait> Draw<'a, R> { r: width / 2.0, }, layer, - net, + maybe_net, + }, + SeqLooseSegWeight { + width, + layer, + maybe_net, }, - SeqLooseSegWeight { width, layer, net }, LooseBendWeight { width, offset, layer, - net, + maybe_net, }, cw, )?; diff --git a/src/drawing/bend.rs b/src/drawing/bend.rs index 90be194..72c57b7 100644 --- a/src/drawing/bend.rs +++ b/src/drawing/bend.rs @@ -2,7 +2,7 @@ use enum_dispatch::enum_dispatch; use crate::{ drawing::{ - graph::{GeometryIndex, GeometryWeight, GetLayer, GetNet, MakePrimitive, Retag}, + graph::{GeometryIndex, GeometryWeight, GetLayer, GetMaybeNet, MakePrimitive, Retag}, primitive::{GenericPrimitive, Primitive}, rules::RulesTrait, Drawing, @@ -76,7 +76,7 @@ pub struct FixedBendWeight { pub width: f64, pub offset: f64, pub layer: u64, - pub net: i64, + pub maybe_net: Option, } impl_fixed_weight!(FixedBendWeight, FixedBend, FixedBendIndex); @@ -105,7 +105,7 @@ pub struct LooseBendWeight { pub width: f64, pub offset: f64, pub layer: u64, - pub net: i64, + pub maybe_net: Option, } impl GetOffset for LooseBendWeight { diff --git a/src/drawing/dot.rs b/src/drawing/dot.rs index 9f6231f..8ecefcf 100644 --- a/src/drawing/dot.rs +++ b/src/drawing/dot.rs @@ -5,7 +5,7 @@ use petgraph::stable_graph::NodeIndex; use crate::{ drawing::{ - graph::{GeometryIndex, GeometryWeight, GetLayer, GetNet, MakePrimitive, Retag}, + graph::{GeometryIndex, GeometryWeight, GetLayer, GetMaybeNet, MakePrimitive, Retag}, primitive::{GenericPrimitive, Primitive}, rules::RulesTrait, Drawing, @@ -77,7 +77,7 @@ impl DotWeightTrait for DotWeight {} pub struct FixedDotWeight { pub circle: Circle, pub layer: u64, - pub net: i64, + pub maybe_net: Option, } impl_fixed_weight!(FixedDotWeight, FixedDot, FixedDotIndex); @@ -105,7 +105,7 @@ impl GetWidth for FixedDotWeight { pub struct LooseDotWeight { pub circle: Circle, pub layer: u64, - pub net: i64, + pub maybe_net: Option, } impl_loose_weight!(LooseDotWeight, LooseDot, LooseDotIndex); diff --git a/src/drawing/drawing.rs b/src/drawing/drawing.rs index c844231..283d41a 100644 --- a/src/drawing/drawing.rs +++ b/src/drawing/drawing.rs @@ -12,7 +12,7 @@ use super::segbend::Segbend; use crate::drawing::bend::BendIndex; use crate::drawing::collect::Collect; use crate::drawing::dot::DotWeight; -use crate::drawing::graph::GetNet; +use crate::drawing::graph::GetMaybeNet; use crate::drawing::guide::Guide; use crate::drawing::primitive::GetLimbs; use crate::drawing::rules::GetConditions; @@ -63,7 +63,7 @@ pub struct Collision(pub Shape, pub GeometryIndex); #[derive(Error, Debug, Clone, Copy)] #[error("{1:?} is already connected to net {0}")] -pub struct AlreadyConnected(pub i64, pub GeometryIndex); +pub struct AlreadyConnected(pub usize, pub GeometryIndex); #[derive(Debug)] pub struct Drawing { @@ -501,13 +501,19 @@ impl Drawing { ) -> Result { // It makes no sense to wrap something around or under one of its connectables. // - if weight.net == around.primitive(self).net() { - return Err(AlreadyConnected(weight.net, around.into()).into()); - } - // - if let Some(wraparound) = self.wraparoundable(around).wraparound() { - if weight.net == wraparound.primitive(self).net() { - return Err(AlreadyConnected(weight.net, wraparound.into()).into()); + if let Some(net) = weight.maybe_net { + if let Some(around_net) = around.primitive(self).maybe_net() { + if net == around_net { + return Err(AlreadyConnected(net, around.into()).into()); + } + } + // + if let Some(wraparound) = self.wraparoundable(around).wraparound() { + if let Some(wraparound_net) = wraparound.primitive(self).maybe_net() { + if net == wraparound_net { + return Err(AlreadyConnected(net, wraparound.into()).into()); + } + } } } @@ -714,10 +720,12 @@ impl Drawing { node: GeometryIndex, maybe_except: Option<&[GeometryIndex]>, ) -> Option { - let limiting_shape = node - .primitive(self) - .shape() - .inflate(self.rules.largest_clearance(node.primitive(self).net())); + let limiting_shape = node.primitive(self).shape().inflate( + node.primitive(self) + .maybe_net() + .and_then(|net| Some(self.rules.largest_clearance(Some(net)))) + .unwrap_or(0.0), + ); let mut inflated_shape = limiting_shape; // Unused temporary value just for initialization. let conditions = node.primitive(self).conditions(); @@ -760,10 +768,14 @@ impl Drawing { #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] fn are_connectable(&self, node1: GeometryIndex, node2: GeometryIndex) -> bool { - let node1_net = node1.primitive(self).net(); - let node2_net = node2.primitive(self).net(); - - (node1_net == node2_net) || node1_net == -1 || node2_net == -2 + if let (Some(node1_net_id), Some(node2_net_id)) = ( + node1.primitive(self).maybe_net(), + node2.primitive(self).maybe_net(), + ) { + node1_net_id == node2_net_id + } else { + true + } } } diff --git a/src/drawing/graph.rs b/src/drawing/graph.rs index 15a7577..4e5b9b0 100644 --- a/src/drawing/graph.rs +++ b/src/drawing/graph.rs @@ -26,8 +26,8 @@ pub trait GetLayer { } #[enum_dispatch] -pub trait GetNet { - fn net(&self) -> i64; +pub trait GetMaybeNet { + fn maybe_net(&self) -> Option; } #[enum_dispatch] @@ -49,9 +49,9 @@ macro_rules! impl_weight { } } - impl<'a> GetNet for $weight_struct { - fn net(&self) -> i64 { - self.net + impl<'a> GetMaybeNet for $weight_struct { + fn maybe_net(&self) -> Option { + self.maybe_net } } diff --git a/src/drawing/primitive.rs b/src/drawing/primitive.rs index 3ec7b2a..7512dd8 100644 --- a/src/drawing/primitive.rs +++ b/src/drawing/primitive.rs @@ -4,7 +4,7 @@ use petgraph::stable_graph::NodeIndex; use crate::drawing::{ bend::{BendIndex, FixedBendWeight, LooseBendIndex, LooseBendWeight}, dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, - graph::{GeometryIndex, GeometryWeight, GetLayer, GetNet, Retag}, + graph::{GeometryIndex, GeometryWeight, GetLayer, GetMaybeNet, Retag}, loose::LooseIndex, rules::{Conditions, GetConditions, RulesTrait}, seg::{ @@ -130,9 +130,9 @@ macro_rules! impl_primitive { } } - impl<'a, R: RulesTrait> GetNet for $primitive_struct<'a, R> { - fn net(&self) -> i64 { - self.weight().net() + impl<'a, R: RulesTrait> GetMaybeNet for $primitive_struct<'a, R> { + fn maybe_net(&self) -> Option { + self.weight().maybe_net() } } }; @@ -152,7 +152,7 @@ macro_rules! impl_loose_primitive { #[enum_dispatch( GetLayer, - GetNet, + GetMaybeNet, GetWidth, GetLayout, MakeShape, @@ -223,13 +223,13 @@ where impl<'a, W, R: RulesTrait> GetConditions for GenericPrimitive<'a, W, R> where - GenericPrimitive<'a, W, R>: GetNet, + GenericPrimitive<'a, W, R>: GetMaybeNet, { fn conditions(&self) -> Conditions { Conditions { - net: self.net(), - region: Some("A".to_string()), - layer: Some("F.Cu".to_string()), + maybe_net: self.maybe_net(), + maybe_region: Some("A".to_string()), + maybe_layer: Some("F.Cu".to_string()), } } } diff --git a/src/drawing/rules.rs b/src/drawing/rules.rs index 59283a8..ecc2c4b 100644 --- a/src/drawing/rules.rs +++ b/src/drawing/rules.rs @@ -9,12 +9,12 @@ pub trait GetConditions { #[derive(Debug, Default)] pub struct Conditions { - pub net: i64, - pub region: Option, - pub layer: Option, + pub maybe_net: Option, + pub maybe_region: Option, + pub maybe_layer: Option, } pub trait RulesTrait { fn clearance(&self, conditions1: &Conditions, conditions2: &Conditions) -> f64; - fn largest_clearance(&self, net: i64) -> f64; + fn largest_clearance(&self, net: Option) -> f64; } diff --git a/src/drawing/seg.rs b/src/drawing/seg.rs index 31f499f..705a8e9 100644 --- a/src/drawing/seg.rs +++ b/src/drawing/seg.rs @@ -2,7 +2,7 @@ use enum_dispatch::enum_dispatch; use crate::{ drawing::{ - graph::{GeometryIndex, GeometryWeight, GetLayer, GetNet, MakePrimitive, Retag}, + graph::{GeometryIndex, GeometryWeight, GetLayer, GetMaybeNet, MakePrimitive, Retag}, primitive::{GenericPrimitive, Primitive}, rules::RulesTrait, Drawing, @@ -81,7 +81,7 @@ impl SegWeightTrait for SegWeight {} pub struct FixedSegWeight { pub width: f64, pub layer: u64, - pub net: i64, + pub maybe_net: Option, } impl_fixed_weight!(FixedSegWeight, FixedSeg, FixedSegIndex); @@ -97,7 +97,7 @@ impl GetWidth for FixedSegWeight { pub struct LoneLooseSegWeight { pub width: f64, pub layer: u64, - pub net: i64, + pub maybe_net: Option, } impl_loose_weight!(LoneLooseSegWeight, LoneLooseSeg, LoneLooseSegIndex); @@ -113,7 +113,7 @@ impl GetWidth for LoneLooseSegWeight { pub struct SeqLooseSegWeight { pub width: f64, pub layer: u64, - pub net: i64, + pub maybe_net: Option, } impl_loose_weight!(SeqLooseSegWeight, SeqLooseSeg, SeqLooseSegIndex); diff --git a/src/dsn/design.rs b/src/dsn/design.rs index 76e7743..34f03c6 100644 --- a/src/dsn/design.rs +++ b/src/dsn/design.rs @@ -46,7 +46,7 @@ impl DsnDesign { let mut layout = Drawing::new(rules); // mapping of pin id -> net id prepared for adding pins - let pin_nets = HashMap::::from_iter( + let pin_nets = HashMap::::from_iter( self.pcb .network .net_vec @@ -103,7 +103,7 @@ impl DsnDesign { pin.rotate.unwrap_or(0.0) as f64, circle.diameter as f64 / 2.0, layer as u64, - *net_id as i64, + *net_id, ) } Shape::Rect(rect) => { @@ -124,7 +124,7 @@ impl DsnDesign { rect.x2 as f64, rect.y2 as f64, layer as u64, - *net_id as i64, + *net_id, ) } Shape::Path(path) => { @@ -143,7 +143,7 @@ impl DsnDesign { &path.coord_vec, path.width as f64, layer as u64, - *net_id as i64, + *net_id, ) } Shape::Polygon(polygon) => { @@ -162,7 +162,7 @@ impl DsnDesign { &polygon.coord_vec, polygon.width as f64, layer as u64, - *net_id as i64, + *net_id, ) } }; @@ -200,7 +200,7 @@ impl DsnDesign { 0.0, circle.diameter as f64 / 2.0, layer as u64, - net_id as i64, + net_id, ) } Shape::Rect(rect) => { @@ -221,7 +221,7 @@ impl DsnDesign { rect.x2 as f64, rect.y2 as f64, layer as u64, - net_id as i64, + net_id, ) } Shape::Path(path) => { @@ -240,7 +240,7 @@ impl DsnDesign { &path.coord_vec, path.width as f64, layer as u64, - net_id as i64, + net_id, ) } Shape::Polygon(polygon) => { @@ -259,7 +259,7 @@ impl DsnDesign { &polygon.coord_vec, polygon.width as f64, layer as u64, - net_id as i64, + net_id, ) } }; @@ -279,7 +279,7 @@ impl DsnDesign { &wire.path.coord_vec, wire.path.width as f64, layer_id as u64, - net_id as i64, + net_id, ); } @@ -309,7 +309,7 @@ impl DsnDesign { pin_rot: f64, r: f64, layer: u64, - net: i64, + net: usize, ) { let circle = Circle { pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, 0.0, 0.0), @@ -317,7 +317,11 @@ impl DsnDesign { }; drawing - .add_fixed_dot(FixedDotWeight { circle, layer, net }) + .add_fixed_dot(FixedDotWeight { + circle, + layer, + maybe_net: Some(net), + }) .unwrap(); } @@ -332,7 +336,7 @@ impl DsnDesign { x2: f64, y2: f64, layer: u64, - net: i64, + net: usize, ) { // Corners. let dot_1_1 = drawing @@ -342,7 +346,7 @@ impl DsnDesign { r: 0.5, }, layer, - net, + maybe_net: Some(net), }) .unwrap(); let dot_2_1 = drawing @@ -352,7 +356,7 @@ impl DsnDesign { r: 0.5, }, layer, - net, + maybe_net: Some(net), }) .unwrap(); let dot_2_2 = drawing @@ -362,7 +366,7 @@ impl DsnDesign { r: 0.5, }, layer, - net, + maybe_net: Some(net), }) .unwrap(); let dot_1_2 = drawing @@ -372,7 +376,7 @@ impl DsnDesign { r: 0.5, }, layer, - net, + maybe_net: Some(net), }) .unwrap(); // Sides. @@ -383,7 +387,7 @@ impl DsnDesign { FixedSegWeight { width: 1.0, layer, - net, + maybe_net: Some(net), }, ) .unwrap(); @@ -394,7 +398,7 @@ impl DsnDesign { FixedSegWeight { width: 1.0, layer, - net, + maybe_net: Some(net), }, ) .unwrap(); @@ -405,7 +409,7 @@ impl DsnDesign { FixedSegWeight { width: 1.0, layer, - net, + maybe_net: Some(net), }, ) .unwrap(); @@ -416,7 +420,7 @@ impl DsnDesign { FixedSegWeight { width: 1.0, layer, - net, + maybe_net: Some(net), }, ) .unwrap(); @@ -431,7 +435,7 @@ impl DsnDesign { coords: &Vec, width: f64, layer: u64, - net: i64, + net: usize, ) { // add the first coordinate in the wire path as a dot and save its index let mut prev_index = drawing @@ -448,7 +452,7 @@ impl DsnDesign { r: width / 2.0, }, layer, - net, + maybe_net: Some(net), }) .unwrap(); @@ -469,13 +473,21 @@ impl DsnDesign { r: width / 2.0, }, layer, - net, + maybe_net: Some(net), }) .unwrap(); // add a seg between the current and previous coords let _ = drawing - .add_fixed_seg(prev_index, index, FixedSegWeight { width, layer, net }) + .add_fixed_seg( + prev_index, + index, + FixedSegWeight { + width, + layer, + maybe_net: Some(net), + }, + ) .unwrap(); prev_index = index; diff --git a/src/dsn/rules.rs b/src/dsn/rules.rs index 2d36a4f..c7516db 100644 --- a/src/dsn/rules.rs +++ b/src/dsn/rules.rs @@ -28,9 +28,9 @@ pub struct DsnRules { // layer names -> layer IDs for Layout pub layer_ids: HashMap, // net names -> net IDs for Layout - pub net_ids: HashMap, + pub net_ids: HashMap, // net ID -> net class - net_id_classes: HashMap, + net_id_classes: HashMap, } impl DsnRules { @@ -49,7 +49,7 @@ impl DsnRules { .iter() .flat_map(|class| &class.net_vec) .enumerate() - .map(|(id, net)| (net.clone(), id as i64)), + .map(|(id, net)| (net.clone(), id)), ); let mut net_id_classes = HashMap::new(); @@ -75,7 +75,7 @@ impl DsnRules { } } - pub fn get_rule(&self, net: i64) -> &DsnRule { + pub fn get_rule(&self, net: usize) -> &DsnRule { if let Some(netclass) = self.net_id_classes.get(&net) { self.class_rules .get(netclass) @@ -88,8 +88,12 @@ impl DsnRules { impl RulesTrait for DsnRules { fn clearance(&self, conditions1: &Conditions, conditions2: &Conditions) -> f64 { - let clr1 = self.get_rule(conditions1.net).clearance; - let clr2 = self.get_rule(conditions2.net).clearance; + let (Some(net1), Some(net2)) = (conditions1.maybe_net, conditions2.maybe_net) else { + return 0.0; + }; + + let clr1 = self.get_rule(net1).clearance; + let clr2 = self.get_rule(net2).clearance; if clr1 > clr2 { clr1 @@ -98,7 +102,7 @@ impl RulesTrait for DsnRules { } } - fn largest_clearance(&self, _net: i64) -> f64 { + fn largest_clearance(&self, maybe_net: Option) -> f64 { let mut largest: f64 = 0.0; for (class, rule) in &self.class_rules { diff --git a/src/layout/connectivity.rs b/src/layout/connectivity.rs index 61d3d27..674528a 100644 --- a/src/layout/connectivity.rs +++ b/src/layout/connectivity.rs @@ -2,7 +2,7 @@ use enum_dispatch::enum_dispatch; use petgraph::stable_graph::StableDiGraph; use crate::{ - drawing::{dot::FixedDotIndex, graph::GetNet, primitive::Primitive, rules::RulesTrait}, + drawing::{dot::FixedDotIndex, graph::GetMaybeNet, primitive::Primitive, rules::RulesTrait}, graph::GenericIndex, }; @@ -16,12 +16,12 @@ pub enum ConnectivityWeight { #[derive(Debug, Clone, Copy)] pub struct ContinentWeight { - pub net: i64, + pub maybe_net: Option, } -impl GetNet for ContinentWeight { - fn net(&self) -> i64 { - self.net +impl GetMaybeNet for ContinentWeight { + fn maybe_net(&self) -> Option { + self.maybe_net } } diff --git a/src/tracer.rs b/src/tracer.rs index ecaa4cc..bb6ae9b 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -5,7 +5,7 @@ use crate::{ drawing::{ bend::LooseBendIndex, dot::FixedDotIndex, - graph::{GetNet, MakePrimitive}, + graph::{GetMaybeNet, MakePrimitive}, guide::{BareHead, Head, HeadTrait, SegbendHead}, rules::RulesTrait, },