Skip to content

Commit

Permalink
work on pcb plotter
Browse files Browse the repository at this point in the history
  • Loading branch information
spielhuus committed May 2, 2024
1 parent 066fa35 commit 2cf9f61
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/plotter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
27 changes: 17 additions & 10 deletions src/plotter/src/pcb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ impl<'a> PcbPlot<'a> {
}

pub fn write(&self, plotter: &mut dyn PlotterImpl, layers: Vec<String>) -> Result<(), Error> {
trace!("write layer: {:?}", layers);
let tree = if let Some(tree) = &self.tree {
tree.clone()
} else {
Expand Down Expand Up @@ -709,6 +708,11 @@ impl<'a> PlotElement<FootprintElement<'a>> 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<f64> = 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" {
Expand Down Expand Up @@ -764,7 +768,7 @@ impl<'a> PlotElement<FootprintElement<'a>> 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]],
Expand Down Expand Up @@ -799,7 +803,7 @@ impl<'a> PlotElement<FootprintElement<'a>> 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('.', "_"))),
),
Expand All @@ -820,7 +824,7 @@ impl<'a> PlotElement<FootprintElement<'a>> for PcbPlot<'a> {
plot_items.push(PlotItem::Circle(
1,
Circle::new(
Shape::transform_pad(item.item, item.is_flipped(), 0.0, &center),
Shape::transform_pad(item.item, item.is_flipped(), None, &center),
radius,
stroke,
Some(format!("{}_{}", self.name, layer.replace('.', "_"))),
Expand All @@ -831,15 +835,15 @@ impl<'a> PlotElement<FootprintElement<'a>> 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();

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,
Expand Down Expand Up @@ -878,7 +882,7 @@ impl<'a> PlotElement<FootprintElement<'a>> 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,
Expand All @@ -888,14 +892,17 @@ impl<'a> PlotElement<FootprintElement<'a>> 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(<Sexp as SexpValueQuery<String>>::get(element, 1).unwrap());
let pad_shape =
PadShape::from(<Sexp as SexpValueQuery<String>>::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<String> = layers_node.values();
let pad_size: Array1<f64> = element.value(el::SIZE).unwrap();
Expand Down Expand Up @@ -1045,7 +1052,7 @@ impl<'a> PlotElement<FootprintElement<'a>> 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('.', "_"))),
Expand Down
48 changes: 20 additions & 28 deletions src/sexp/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -61,7 +61,7 @@ impl Shape {
/// transform the coordinates to absolute values.
pub trait Transform<U, T> {
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<f64>, pts: &T) -> T;
}
impl Transform<Sexp, Array2<f64>> for Shape {
fn transform(symbol: &Sexp, pts: &Array2<f64>) -> Array2<f64> {
Expand All @@ -84,21 +84,19 @@ impl Transform<Sexp, Array2<f64>> for Shape {
let verts = &symbol_pos + verts;
verts.mapv_into(|v| format!("{:.2}", v).parse::<f64>().unwrap())
}
fn transform_pad(symbol: &Sexp, flip: bool, angle: f64, pts: &Array2<f64>) -> Array2<f64> {
fn transform_pad(symbol: &Sexp, flip: bool, angle: Option<f64>, pts: &Array2<f64>) -> Array2<f64> {
let symbol_pos = utils::at(symbol).unwrap();
let mut angle = utils::angle(symbol).unwrap_or(0.0); // + angle;

let mut mirror: Option<String> = 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()]]);
Expand All @@ -122,12 +120,6 @@ impl Transform<Sexp, Array1<f64>> for Shape {
let angle: f64 = symbol.query(el::AT).next().unwrap().get(2).unwrap_or(0.0);
let mirror: Option<String> = if let Some(mirror) = symbol.query(el::MIRROR).next() {
mirror.get(0)
} else if let Some(layer) = <Sexp as SexpValueQuery<String>>::value(symbol, el::LAYER) {
if layer.starts_with("B.") {
Some("y".to_string())
} else {
None
}
} else {
None
};
Expand All @@ -150,24 +142,24 @@ impl Transform<Sexp, Array1<f64>> for Shape {
}
})
}
fn transform_pad(symbol: &Sexp, front: bool, angle: f64, pts: &Array1<f64>) -> Array1<f64> {
fn transform_pad(symbol: &Sexp, flip: bool, angle: Option<f64>, pts: &Array1<f64>) -> Array1<f64> {
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<String> = if let Some(layer) = <Sexp as SexpValueQuery<String>>::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<String> = if !front {
// Some("y".to_string())
} else {
None
};
};

let theta = -angle.to_radians();
let rot = arr2(&[[theta.cos(), -theta.sin()], [theta.sin(), theta.cos()]]);
Expand Down

0 comments on commit 2cf9f61

Please sign in to comment.