specctra: add export of bends (downgraded to line segment chains)

This commit is contained in:
Tomasz Cichoń 2024-07-12 15:14:15 +02:00
parent e28b7f7f9d
commit 9e2a0acab0
2 changed files with 61 additions and 31 deletions

View File

@ -63,22 +63,50 @@ impl SpecctraDesign {
let mut net_outs = HashMap::<usize, structure::NetOut>::new(); let mut net_outs = HashMap::<usize, structure::NetOut>::new();
for index in drawing.primitive_nodes() { for index in drawing.primitive_nodes() {
let primitive = index.primitive(drawing); let primitive = index.primitive(drawing);
match primitive.shape() {
PrimitiveShape::Seg(seg) => {
if let Some(net) = primitive.maybe_net() {
let net_name = mesadata.net_netname(net).unwrap().to_owned();
let wire = structure::Wire { if let Some(net) = primitive.maybe_net() {
let coords = match primitive.shape() {
PrimitiveShape::Seg(seg) => {
vec![
structure::Point { x: seg.from.x(), y: seg.from.y() },
structure::Point { x: seg.to.x(), y: seg.to.y() },
]
},
PrimitiveShape::Bend(bend) => {
// Since general circle arcs don't seem to be supported
// we're downgrading each one to a chain of straight
// line segments.
// TODO: make this configurable? pick a smarter value?
let segment_count: usize = 100;
let circle = bend.circle();
let angle_from = bend.start_angle();
let angle_step = bend.spanned_angle() / segment_count as f64;
let mut points = Vec::new();
for i in 0..=segment_count {
let x = circle.pos.x() + circle.r * (angle_from + i as f64 * angle_step).cos();
let y = circle.pos.y() + circle.r * (angle_from + i as f64 * angle_step).sin();
points.push(structure::Point { x, y });
}
points
},
// Intentionally skipped for now.
// Topola stores trace segments and dots joining them
// as separate objects, but the Specctra formats and KiCad
// appear to consider them implicit.
// TODO: Vias
PrimitiveShape::Dot(_) => continue,
};
let wire = structure::WireOut {
path: structure::Path { path: structure::Path {
layer: mesadata.layer_layername(primitive.layer()).unwrap().to_owned(), layer: mesadata.layer_layername(primitive.layer()).unwrap().to_owned(),
width: primitive.width(), width: primitive.width(),
coords: vec![ coords,
structure::Point { x: seg.from.x(), y: seg.from.y() },
structure::Point { x: seg.to.x(), y: seg.to.y() },
],
}, },
net: net_name.clone(),
r#type: "route".to_owned(),
}; };
if let Some(net) = net_outs.get_mut(&net) { if let Some(net) = net_outs.get_mut(&net) {
@ -87,16 +115,13 @@ impl SpecctraDesign {
net_outs.insert( net_outs.insert(
net, net,
structure::NetOut { structure::NetOut {
name: net_name.clone(), name: mesadata.net_netname(net).unwrap().to_owned(),
wire: vec![wire], wire: vec![wire],
via: Vec::new(), via: Vec::new(),
}, },
); );
} }
} }
},
_ => (),
}
} }
let ses = structure::SesFile { let ses = structure::SesFile {

View File

@ -39,7 +39,7 @@ pub struct NetOut {
#[anon] #[anon]
pub name: String, pub name: String,
#[vec("wire")] #[vec("wire")]
pub wire: Vec<Wire>, pub wire: Vec<WireOut>,
#[vec("via")] #[vec("via")]
pub via: Vec<Via>, pub via: Vec<Via>,
} }
@ -303,6 +303,11 @@ pub struct Wire {
pub r#type: String, pub r#type: String,
} }
#[derive(ReadDsn, WriteSes, Debug)]
pub struct WireOut {
pub path: Path,
}
//////////////////////////////////////////// ////////////////////////////////////////////
// structs that appear in multiple places // // structs that appear in multiple places //
//////////////////////////////////////////// ////////////////////////////////////////////