diff --git a/src/draw.rs b/src/draw.rs index c25f003..0a01938 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -7,7 +7,7 @@ use crate::{ layout::{ bend::{BendIndex, LooseBendWeight}, dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight}, - graph::{GetNet, MakePrimitive}, + graph::{GetLayer, GetNet, MakePrimitive}, guide::{Guide, Head, HeadTrait, SegbendHead}, primitive::GetOtherJoint, rules::RulesTrait, @@ -58,17 +58,18 @@ impl<'a, R: RulesTrait> Draw<'a, R> { let head = self .extend_head(head, tangent.start_point()) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; + let layer = head.face().primitive(self.board.layout()).layer(); let net = head.face().primitive(self.board.layout()).net(); match head.face() { DotIndex::Fixed(dot) => { self.board - .add_lone_loose_seg(dot, into.into(), LoneLooseSegWeight { net, width }) + .add_lone_loose_seg(dot, into.into(), LoneLooseSegWeight { width, layer, net }) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; } DotIndex::Loose(dot) => { self.board - .add_seq_loose_seg(into.into(), dot, SeqLooseSegWeight { net, width }) + .add_seq_loose_seg(into.into(), dot, SeqLooseSegWeight { width, layer, net }) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; } } @@ -202,19 +203,26 @@ impl<'a, R: RulesTrait> Draw<'a, R> { width: f64, offset: f64, ) -> Result { + let layer = head.face().primitive(self.board.layout()).layer(); let net = head.face().primitive(self.board.layout()).net(); let segbend = self.board.insert_segbend( head.face(), around, LooseDotWeight { - net, circle: Circle { pos: to, r: width / 2.0, }, + layer, + net, + }, + SeqLooseSegWeight { width, layer, net }, + LooseBendWeight { + width, + offset, + layer, + net, }, - SeqLooseSegWeight { net, width }, - LooseBendWeight { net, width, offset }, cw, )?; Ok::(SegbendHead { diff --git a/src/dsn/design.rs b/src/dsn/design.rs index 89ca81a..18c606f 100644 --- a/src/dsn/design.rs +++ b/src/dsn/design.rs @@ -85,75 +85,73 @@ impl DsnDesign { .find(|padstack| padstack.name == pin.name) .unwrap(); - // no layer support yet, pick the first one - match &padstack.shape_vec[0] { - Shape::Circle(circle) => { - let circle = Circle { - pos: ((place.x + pin.x) as f64, -(place.y + pin.y) as f64).into(), - r: circle.diameter as f64 / 2.0, - }; + for (layer, shape) in padstack.shape_vec.iter().enumerate() { + match shape { + Shape::Circle(circle) => { + let circle = Circle { + pos: ((place.x + pin.x) as f64, -(place.y + pin.y) as f64) + .into(), + r: circle.diameter as f64 / 2.0, + }; - layout - .add_fixed_dot(FixedDotWeight { - net: *net_id as i64, - circle, - }) - .unwrap(); - } - Shape::Rect(_) => (), - Shape::Path(_) => (), - Shape::Polygon(_) => (), - }; + layout + .add_fixed_dot(FixedDotWeight { + circle, + layer: layer as u64, + net: *net_id as i64, + }) + .unwrap(); + } + Shape::Rect(_) => (), + Shape::Path(_) => (), + Shape::Polygon(_) => (), + }; + } } } } - // add vias to layout and save indices of dots in the order they appear in the file - let _dot_indices: Vec<_> = self - .pcb - .wiring - .via_vec - .iter() - .map(|via| { - let net_id = layout.rules().net_ids.get(&via.net).unwrap(); + for via in &self.pcb.wiring.via_vec { + let net_id = *layout.rules().net_ids.get(&via.net).unwrap(); - // find the padstack referenced by this via placement - let padstack = &self - .pcb - .library - .padstack_vec - .iter() - .find(|padstack| padstack.name == via.name) - .unwrap(); + // find the padstack referenced by this via placement + let padstack = &self + .pcb + .library + .padstack_vec + .iter() + .find(|padstack| padstack.name == via.name) + .unwrap(); - // no layer support yet, pick the first one - let circle = match &padstack.shape_vec[0] { + // no layer support yet, pick the first one + for shape in &padstack.shape_vec { + let circle = match shape { Shape::Circle(circle) => circle, Shape::Rect(_) => todo!(), Shape::Path(_) => todo!(), Shape::Polygon(_) => todo!(), }; + let layer_id = *layout.rules().layer_ids.get(&circle.layer).unwrap(); let circle = Circle { pos: (via.x as f64, -via.y as f64).into(), r: circle.diameter as f64 / 2.0, }; - layout - .add_fixed_dot(FixedDotWeight { - net: *net_id as i64, - circle, - }) - .unwrap() - }) - .collect(); + layout.add_fixed_dot(FixedDotWeight { + circle, + layer: layer_id as u64, + net: net_id as i64, + }); + } + } for wire in self.pcb.wiring.wire_vec.iter() { + let layer_id = *layout.rules().layer_ids.get(&wire.path.layer).unwrap(); let net_id = *layout.rules().net_ids.get(&wire.net).unwrap(); // add the first coordinate in the wire path as a dot and save its index let mut prev_index = layout .add_fixed_dot(FixedDotWeight { - net: net_id as i64, circle: Circle { pos: ( wire.path.coord_vec[0].x as f64, @@ -162,6 +160,8 @@ impl DsnDesign { .into(), r: wire.path.width as f64 / 2.0, }, + layer: layer_id as u64, + net: net_id as i64, }) .unwrap(); @@ -169,11 +169,12 @@ impl DsnDesign { for coord in wire.path.coord_vec.iter().skip(1) { let index = layout .add_fixed_dot(FixedDotWeight { - net: net_id as i64, circle: Circle { pos: (coord.x as f64, -coord.y as f64).into(), r: wire.path.width as f64 / 2.0, }, + layer: layer_id as u64, + net: net_id as i64, }) .unwrap(); @@ -183,8 +184,9 @@ impl DsnDesign { prev_index, index, FixedSegWeight { - net: net_id as i64, width: wire.path.width as f64, + layer: layer_id as u64, + net: net_id as i64, }, ) .unwrap(); diff --git a/src/dsn/rules.rs b/src/dsn/rules.rs index d891509..bb31c01 100644 --- a/src/dsn/rules.rs +++ b/src/dsn/rules.rs @@ -25,6 +25,8 @@ pub struct DsnRules { // net class name -> rule class_rules: HashMap, + // layer names -> layer IDs for Layout + pub layer_ids: HashMap, // net names -> net IDs for Layout pub net_ids: HashMap, // net ID -> net class @@ -33,6 +35,13 @@ pub struct DsnRules { impl DsnRules { pub fn from_pcb(pcb: &Pcb) -> Self { + let layer_ids = HashMap::from_iter( + pcb.structure + .layer_vec + .iter() + .map(|layer| (layer.name.clone(), layer.property.index as u64)), + ); + // keeping this as a separate iter pass because it might be moved into a different struct later? let net_ids = HashMap::from_iter( pcb.network @@ -60,6 +69,7 @@ impl DsnRules { Self { structure_rule: DsnRule::from_dsn(&pcb.structure.rule), class_rules, + layer_ids, net_ids, net_id_classes, } diff --git a/src/layout/bend.rs b/src/layout/bend.rs index 0aa4945..fc8c16c 100644 --- a/src/layout/bend.rs +++ b/src/layout/bend.rs @@ -4,7 +4,7 @@ use crate::{ geometry::{BendWeightTrait, GetOffset, GetWidth, SetOffset}, graph::{GenericIndex, GetNodeIndex}, layout::{ - graph::{GeometryIndex, GeometryWeight, GetNet, MakePrimitive, Retag}, + graph::{GeometryIndex, GeometryWeight, GetLayer, GetNet, MakePrimitive, Retag}, primitive::{GenericPrimitive, Primitive}, rules::RulesTrait, Layout, @@ -73,9 +73,10 @@ impl BendWeightTrait for BendWeight {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct FixedBendWeight { - pub net: i64, pub width: f64, pub offset: f64, + pub layer: u64, + pub net: i64, } impl_fixed_weight!(FixedBendWeight, FixedBend, FixedBendIndex); @@ -101,9 +102,10 @@ impl GetWidth for FixedBendWeight { #[derive(Debug, Clone, Copy, PartialEq)] pub struct LooseBendWeight { - pub net: i64, pub width: f64, pub offset: f64, + pub layer: u64, + pub net: i64, } impl GetOffset for LooseBendWeight { diff --git a/src/layout/dot.rs b/src/layout/dot.rs index 814984b..8af5d96 100644 --- a/src/layout/dot.rs +++ b/src/layout/dot.rs @@ -7,7 +7,7 @@ use crate::{ geometry::{DotWeightTrait, GetPos, GetWidth, SetPos}, graph::{GenericIndex, GetNodeIndex}, layout::{ - graph::{GeometryIndex, GeometryWeight, GetNet, MakePrimitive, Retag}, + graph::{GeometryIndex, GeometryWeight, GetLayer, GetNet, MakePrimitive, Retag}, primitive::{GenericPrimitive, Primitive}, rules::RulesTrait, Layout, @@ -75,8 +75,9 @@ impl DotWeightTrait for DotWeight {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct FixedDotWeight { - pub net: i64, pub circle: Circle, + pub layer: u64, + pub net: i64, } impl_fixed_weight!(FixedDotWeight, FixedDot, FixedDotIndex); @@ -102,8 +103,9 @@ impl GetWidth for FixedDotWeight { #[derive(Debug, Clone, Copy, PartialEq)] pub struct LooseDotWeight { - pub net: i64, pub circle: Circle, + pub layer: u64, + pub net: i64, } impl_loose_weight!(LooseDotWeight, LooseDot, LooseDotIndex); diff --git a/src/layout/graph.rs b/src/layout/graph.rs index 0ef8432..9df736e 100644 --- a/src/layout/graph.rs +++ b/src/layout/graph.rs @@ -24,6 +24,11 @@ pub trait Retag { fn retag(&self, index: NodeIndex) -> GeometryIndex; } +#[enum_dispatch] +pub trait GetLayer { + fn layer(&self) -> u64; +} + #[enum_dispatch] pub trait GetNet { fn net(&self) -> i64; @@ -42,6 +47,12 @@ macro_rules! impl_weight { } } + impl<'a> GetLayer for $weight_struct { + fn layer(&self) -> u64 { + self.layer + } + } + impl<'a> GetNet for $weight_struct { fn net(&self) -> i64 { self.net diff --git a/src/layout/primitive.rs b/src/layout/primitive.rs index 6c953a6..0dd6ba9 100644 --- a/src/layout/primitive.rs +++ b/src/layout/primitive.rs @@ -9,10 +9,10 @@ use crate::geometry::{ use crate::graph::{GenericIndex, GetNodeIndex}; use crate::layout::{ bend::{BendIndex, FixedBendWeight, LooseBendIndex, LooseBendWeight}, - dot::DotWeight, - dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, - graph::{GeometryIndex, GeometryWeight, Retag}, + dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, + graph::{GeometryIndex, GeometryWeight, GetLayer, GetNet, Retag}, loose::LooseIndex, + rules::{Conditions, GetConditions, RulesTrait}, seg::{ FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, SeqLooseSegIndex, SeqLooseSegWeight, @@ -20,9 +20,6 @@ use crate::layout::{ Layout, }; -use super::graph::GetNet; -use super::rules::{Conditions, GetConditions, RulesTrait}; - #[enum_dispatch] pub trait GetLayout<'a, R: RulesTrait> { fn layout(&self) -> &Layout; @@ -127,6 +124,12 @@ macro_rules! impl_primitive { } } + impl<'a, R: RulesTrait> GetLayer for $primitive_struct<'a, R> { + fn layer(&self) -> u64 { + self.weight().layer() + } + } + impl<'a, R: RulesTrait> GetNet for $primitive_struct<'a, R> { fn net(&self) -> i64 { self.weight().net() @@ -147,7 +150,15 @@ macro_rules! impl_loose_primitive { }; } -#[enum_dispatch(GetNet, GetWidth, GetLayout, MakeShape, GetLimbs, GetConditions)] +#[enum_dispatch( + GetLayer, + GetNet, + GetWidth, + GetLayout, + MakeShape, + GetLimbs, + GetConditions +)] pub enum Primitive<'a, R: RulesTrait> { FixedDot(FixedDot<'a, R>), LooseDot(LooseDot<'a, R>), diff --git a/src/layout/seg.rs b/src/layout/seg.rs index 67af603..436f5d0 100644 --- a/src/layout/seg.rs +++ b/src/layout/seg.rs @@ -4,7 +4,7 @@ use crate::{ geometry::{GetWidth, SegWeightTrait}, graph::{GenericIndex, GetNodeIndex}, layout::{ - graph::{GeometryIndex, GeometryWeight, GetNet, MakePrimitive, Retag}, + graph::{GeometryIndex, GeometryWeight, GetLayer, GetNet, MakePrimitive, Retag}, primitive::{GenericPrimitive, Primitive}, rules::RulesTrait, Layout, @@ -79,8 +79,9 @@ impl SegWeightTrait for SegWeight {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct FixedSegWeight { - pub net: i64, pub width: f64, + pub layer: u64, + pub net: i64, } impl_fixed_weight!(FixedSegWeight, FixedSeg, FixedSegIndex); @@ -94,8 +95,9 @@ impl GetWidth for FixedSegWeight { #[derive(Debug, Clone, Copy, PartialEq)] pub struct LoneLooseSegWeight { - pub net: i64, pub width: f64, + pub layer: u64, + pub net: i64, } impl_loose_weight!(LoneLooseSegWeight, LoneLooseSeg, LoneLooseSegIndex); @@ -109,8 +111,9 @@ impl GetWidth for LoneLooseSegWeight { #[derive(Debug, Clone, Copy, PartialEq)] pub struct SeqLooseSegWeight { - pub net: i64, pub width: f64, + pub layer: u64, + pub net: i64, } impl_loose_weight!(SeqLooseSegWeight, SeqLooseSeg, SeqLooseSegIndex);