drawing: use `None` instead of negative values to denote no net

This commit is contained in:
Mikolaj Wielgus 2024-03-24 16:34:50 +00:00
parent 6a5be3c368
commit e23f7de07e
13 changed files with 140 additions and 92 deletions

View File

@ -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)
}

View File

@ -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<SegbendHead, LayoutException> {
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,
)?;

View File

@ -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<usize>,
}
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<usize>,
}
impl GetOffset for LooseBendWeight {

View File

@ -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<GeometryWeight> for DotWeight {}
pub struct FixedDotWeight {
pub circle: Circle,
pub layer: u64,
pub net: i64,
pub maybe_net: Option<usize>,
}
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<usize>,
}
impl_loose_weight!(LooseDotWeight, LooseDot, LooseDotIndex);

View File

@ -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<R: RulesTrait> {
@ -501,13 +501,19 @@ impl<R: RulesTrait> Drawing<R> {
) -> Result<LooseBendIndex, LayoutException> {
// 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<R: RulesTrait> Drawing<R> {
node: GeometryIndex,
maybe_except: Option<&[GeometryIndex]>,
) -> Option<Infringement> {
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<R: RulesTrait> Drawing<R> {
#[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
}
}
}

View File

@ -26,8 +26,8 @@ pub trait GetLayer {
}
#[enum_dispatch]
pub trait GetNet {
fn net(&self) -> i64;
pub trait GetMaybeNet {
fn maybe_net(&self) -> Option<usize>;
}
#[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<usize> {
self.maybe_net
}
}

View File

@ -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<usize> {
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()),
}
}
}

View File

@ -9,12 +9,12 @@ pub trait GetConditions {
#[derive(Debug, Default)]
pub struct Conditions {
pub net: i64,
pub region: Option<String>,
pub layer: Option<String>,
pub maybe_net: Option<usize>,
pub maybe_region: Option<String>,
pub maybe_layer: Option<String>,
}
pub trait RulesTrait {
fn clearance(&self, conditions1: &Conditions, conditions2: &Conditions) -> f64;
fn largest_clearance(&self, net: i64) -> f64;
fn largest_clearance(&self, net: Option<usize>) -> f64;
}

View File

@ -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<GeometryWeight> for SegWeight {}
pub struct FixedSegWeight {
pub width: f64,
pub layer: u64,
pub net: i64,
pub maybe_net: Option<usize>,
}
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<usize>,
}
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<usize>,
}
impl_loose_weight!(SeqLooseSegWeight, SeqLooseSeg, SeqLooseSegIndex);

View File

@ -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::<String, i64>::from_iter(
let pin_nets = HashMap::<String, usize>::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<structure::Point>,
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;

View File

@ -28,9 +28,9 @@ pub struct DsnRules {
// layer names -> layer IDs for Layout
pub layer_ids: HashMap<String, u64>,
// net names -> net IDs for Layout
pub net_ids: HashMap<String, i64>,
pub net_ids: HashMap<String, usize>,
// net ID -> net class
net_id_classes: HashMap<i64, String>,
net_id_classes: HashMap<usize, String>,
}
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<usize>) -> f64 {
let mut largest: f64 = 0.0;
for (class, rule) in &self.class_rules {

View File

@ -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<usize>,
}
impl GetNet for ContinentWeight {
fn net(&self) -> i64 {
self.net
impl GetMaybeNet for ContinentWeight {
fn maybe_net(&self) -> Option<usize> {
self.maybe_net
}
}

View File

@ -5,7 +5,7 @@ use crate::{
drawing::{
bend::LooseBendIndex,
dot::FixedDotIndex,
graph::{GetNet, MakePrimitive},
graph::{GetMaybeNet, MakePrimitive},
guide::{BareHead, Head, HeadTrait, SegbendHead},
rules::RulesTrait,
},