From 2cf9f61395952096450797c9195fd0b438d96921 Mon Sep 17 00:00:00 2001 From: spielhuus Date: Thu, 2 May 2024 21:39:57 +0200 Subject: [PATCH] work on pcb plotter --- src/plotter/src/lib.rs | 2 +- src/plotter/src/pcb.rs | 27 +++++++++++++++--------- src/sexp/src/math.rs | 48 ++++++++++++++++++------------------------ 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/plotter/src/lib.rs b/src/plotter/src/lib.rs index 4600a5c..b748b1b 100644 --- a/src/plotter/src/lib.rs +++ b/src/plotter/src/lib.rs @@ -108,7 +108,7 @@ pub fn plot(input: &str, output: &str, border: bool, theme: Theme, scale: f64, p //} } else if input.ends_with(".kicad_pcb") { - debug!("Write PCB: input:{}, output:{:?}", input, output); + debug!("Write PCB: input:{}, output:{:?}, border: {} theme: {:?}", input, output, border, theme); let layers = if let Some(layers) = layers { layers } else { diff --git a/src/plotter/src/pcb.rs b/src/plotter/src/pcb.rs index 7f7f05b..ee19b35 100644 --- a/src/plotter/src/pcb.rs +++ b/src/plotter/src/pcb.rs @@ -280,7 +280,6 @@ impl<'a> PcbPlot<'a> { } pub fn write(&self, plotter: &mut dyn PlotterImpl, layers: Vec) -> Result<(), Error> { - trace!("write layer: {:?}", layers); let tree = if let Some(tree) = &self.tree { tree.clone() } else { @@ -709,6 +708,11 @@ impl<'a> PlotElement> for PcbPlot<'a> { ) -> Result<(), Error> { //create a tmp element to fix the angle and mirror + let footprint: String = item.item.get(0).unwrap(); + let at: Array1 = sexp::utils::at(item.item).unwrap(); + let angle = sexp::utils::angle(item.item).unwrap_or(0.0); + let fp_layer: String = item.item.value(el::LAYER).unwrap(); + for element in item.item.nodes() { let name: &String = &element.name; if name == "fp_arc" { @@ -764,7 +768,7 @@ impl<'a> PlotElement> for PcbPlot<'a> { Shape::transform_pad( item.item, item.is_flipped(), - 0.0, + None, &arr2(&[ [line_start[0], line_start[1]], [line_end[0], line_end[1]], @@ -799,7 +803,7 @@ impl<'a> PlotElement> for PcbPlot<'a> { plot_items.push(PlotItem::Polyline( 20, Polyline::new( - Shape::transform_pad(item.item, item.is_flipped(), 0.0, &pts), + Shape::transform_pad(item.item, item.is_flipped(), None, &pts), stroke, Some(format!("{}_{}", self.name, layer.replace('.', "_"))), ), @@ -820,7 +824,7 @@ impl<'a> PlotElement> for PcbPlot<'a> { plot_items.push(PlotItem::Circle( 1, Circle::new( - Shape::transform_pad(item.item, item.is_flipped(), 0.0, ¢er), + Shape::transform_pad(item.item, item.is_flipped(), None, ¢er), radius, stroke, Some(format!("{}_{}", self.name, layer.replace('.', "_"))), @@ -831,7 +835,7 @@ impl<'a> PlotElement> for PcbPlot<'a> { let text_layer: String = element.value(el::LAYER).unwrap(); if PcbPlot::is_layer_in(layer, &text_layer) { let at = sexp::utils::at(element).unwrap(); - let angle = sexp::utils::angle(element).unwrap_or(0.0); + let angle = sexp::utils::angle(element).unwrap(); let mut effects = Effects::from(element); effects.font_color = self.theme.layer_color(&[Style::from(text_layer)]); let text: String = element.get(1).unwrap(); @@ -839,7 +843,7 @@ impl<'a> PlotElement> for PcbPlot<'a> { plot_items.push(PlotItem::Text( 10, Text::new( - Shape::transform_pad(item.item, item.is_flipped(), angle, &at), + Shape::transform_pad(item.item, item.is_flipped(), None, &at), angle, text, effects, @@ -878,7 +882,7 @@ impl<'a> PlotElement> for PcbPlot<'a> { plot_items.push(PlotItem::Text( 10, Text::new( - Shape::transform_pad(item.item, item.is_flipped(), angle, &at), + Shape::transform_pad(item.item, item.is_flipped(), None, &at), angle, text, effects, @@ -888,14 +892,17 @@ impl<'a> PlotElement> for PcbPlot<'a> { )); } } else if name == el::PAD { - let at = sexp::utils::at(element).unwrap(); - let angle = sexp::utils::angle(element).unwrap_or(0.0); + let pad_type = PadType::from(>::get(element, 1).unwrap()); let pad_shape = PadShape::from(>::get(element, 2).unwrap()); + let at = sexp::utils::at(element).unwrap(); + let angle = sexp::utils::angle(element); + + let layers_node: &Sexp = element.query("layers").next().expect("expect layers"); let layers: Vec = layers_node.values(); let pad_size: Array1 = element.value(el::SIZE).unwrap(); @@ -1045,7 +1052,7 @@ impl<'a> PlotElement> for PcbPlot<'a> { plot_items.push(PlotItem::Circle( 10, Circle::new( - Shape::transform(item.item, &at), + Shape::transform_pad(item.item,item.is_flipped(), angle, &at), drill.width.unwrap_or(0.0), stroke, Some(format!("{}_{}", self.name, layer.replace('.', "_"))), diff --git a/src/sexp/src/math.rs b/src/sexp/src/math.rs index d3c5355..f5941a0 100644 --- a/src/sexp/src/math.rs +++ b/src/sexp/src/math.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use lazy_static::lazy_static; use ndarray::{arr1, arr2, s, Array, Array1, Array2}; -use log::error; +use log::{trace, error}; use crate::{el, utils, Error, Sexp, SexpValueQuery, SexpValuesQuery}; @@ -61,7 +61,7 @@ impl Shape { /// transform the coordinates to absolute values. pub trait Transform { fn transform(node: &U, pts: &T) -> T; - fn transform_pad(node: &U, front: bool, angle: f64, pts: &T) -> T; + fn transform_pad(node: &U, front: bool, angle: Option, pts: &T) -> T; } impl Transform> for Shape { fn transform(symbol: &Sexp, pts: &Array2) -> Array2 { @@ -84,21 +84,19 @@ impl Transform> for Shape { let verts = &symbol_pos + verts; verts.mapv_into(|v| format!("{:.2}", v).parse::().unwrap()) } - fn transform_pad(symbol: &Sexp, flip: bool, angle: f64, pts: &Array2) -> Array2 { + fn transform_pad(symbol: &Sexp, flip: bool, angle: Option, pts: &Array2) -> Array2 { let symbol_pos = utils::at(symbol).unwrap(); - let mut angle = utils::angle(symbol).unwrap_or(0.0); // + angle; - let mut mirror: Option = if let Some(mirror) = symbol.query(el::MIRROR).next() { - error!("footprint has a mirror {:?}", mirror); - mirror.get(0) + let angle = if let Some(angle) = angle { + angle } else { - None + symbol.query(el::AT).next().unwrap().get(2).unwrap_or(0.0) }; - if flip { - angle += 180.0; - mirror = Some("y".to_string()); - } + let mirror = if flip { + //angle += 180.0; + Some("y".to_string()) + } else { None }; let theta = -angle.to_radians(); let rot = arr2(&[[theta.cos(), -theta.sin()], [theta.sin(), theta.cos()]]); @@ -122,12 +120,6 @@ impl Transform> for Shape { let angle: f64 = symbol.query(el::AT).next().unwrap().get(2).unwrap_or(0.0); let mirror: Option = if let Some(mirror) = symbol.query(el::MIRROR).next() { mirror.get(0) - } else if let Some(layer) = >::value(symbol, el::LAYER) { - if layer.starts_with("B.") { - Some("y".to_string()) - } else { - None - } } else { None }; @@ -150,24 +142,24 @@ impl Transform> for Shape { } }) } - fn transform_pad(symbol: &Sexp, front: bool, angle: f64, pts: &Array1) -> Array1 { + fn transform_pad(symbol: &Sexp, flip: bool, angle: Option, pts: &Array1) -> Array1 { let symbol_at = symbol.query(el::AT).next().unwrap(); let symbol_x: f64 = symbol_at.get(0).unwrap(); let symbol_y: f64 = symbol_at.get(1).unwrap(); let symbol_pos = arr1(&[symbol_x, symbol_y]); - let angle: f64 = symbol.query(el::AT).next().unwrap().get(2).unwrap_or(0.0); // + angle; - let mirror: Option = if let Some(layer) = >::value(symbol, el::LAYER) { - if layer.starts_with("B.") { + let angle = if let Some(angle) = angle { + angle + } else { + symbol.query(el::AT).next().unwrap().get(2).unwrap_or(0.0) + }; + + let mirror = if flip { + //angle += 180.0; Some("y".to_string()) } else { None - } - //let mirror: Option = if !front { - // Some("y".to_string()) - } else { - None - }; + }; let theta = -angle.to_radians(); let rot = arr2(&[[theta.cos(), -theta.sin()], [theta.sin(), theta.cos()]]);