180 lines
5.2 KiB
JavaScript
180 lines
5.2 KiB
JavaScript
// Router
|
|
// Version: 0.1
|
|
|
|
// Snippets of code used here were taken from https://github.com/infused-kim/kb_ergogen_fp (adjust_oint)
|
|
// Credits goes to Github infused-kim, Thanks!
|
|
|
|
module.exports = {
|
|
params: {
|
|
net: { type: "net", value: "" },
|
|
width: { type: "number", value: 0.25 },
|
|
route: { type: "string", value: "" },
|
|
routes: { type: "array", value: [] },
|
|
via_size: { type: "number", value: 0.8 },
|
|
via_drill: { type: "number", value: 0.4 },
|
|
locked: false,
|
|
},
|
|
|
|
body: (p) => {
|
|
const get_at_coordinates = () => {
|
|
const pattern = /\(at (-?[\d\.]*) (-?[\d\.]*) (-?[\d\.]*)\)/
|
|
const matches = p.at.match(pattern)
|
|
if (matches && matches.length == 4) {
|
|
return [
|
|
parseFloat(matches[1]),
|
|
parseFloat(matches[2]),
|
|
parseFloat(matches[3]),
|
|
]
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
|
|
const adjust_point = (x, y) => {
|
|
const at_l = get_at_coordinates()
|
|
if (at_l == null) {
|
|
throw new Error(`Could not get x and y coordinates from p.at: ${p.at}`)
|
|
}
|
|
const at_x = at_l[0]
|
|
const at_y = at_l[1]
|
|
const at_angle = at_l[2]
|
|
|
|
const radians = (Math.PI / 180) * at_angle,
|
|
cos = Math.cos(radians),
|
|
sin = Math.sin(radians),
|
|
nx = cos * x + sin * y + at_x,
|
|
ny = cos * y - sin * x + at_y
|
|
|
|
const point_str = `${nx.toFixed(5)/1} ${ny.toFixed(5)/1}` // the division by 1 is to remove trailing zeros
|
|
return point_str
|
|
}
|
|
|
|
// (segment (start 108.8 108) (end 109.7 108) (width 0.2) (layer "F.Cu") (net 0))
|
|
const get_segment = (start, end, layer, net) => {
|
|
if (!layer) {
|
|
throw new Error(
|
|
"Can't place segment before layer is set, use 'f' or 'b', to set starting layer"
|
|
)
|
|
}
|
|
return `(segment ${locked}(start ${adjust_point(
|
|
start[0],
|
|
start[1]
|
|
)}) (end ${adjust_point(end[0], end[1])}) (width ${
|
|
p.width
|
|
}) (layer ${layer}) (net ${net}))`
|
|
}
|
|
|
|
// (via (at 108.8 108) (size 0.8) (drill 0.4) (layers "F.Cu" "B.Cu") (net 0))
|
|
const get_via = (pos, net) => {
|
|
if (!pos) {
|
|
throw new Error(
|
|
"Can't place via when position is not set, use (x,y) to set position"
|
|
)
|
|
}
|
|
return `(via ${locked}(at ${adjust_point(pos[0], pos[1])}) (size ${
|
|
p.via_size
|
|
}) (drill ${p.via_drill}) (layers "F.Cu" "B.Cu") (net ${net}))`
|
|
}
|
|
|
|
const parse_tuple = (t) => {
|
|
let str_tuple = JSON.parse(t.replace(/\(/g, "[").replace(/\)/g, "]"))
|
|
let num_tuple = str_tuple.map((v) => Number(v))
|
|
if (isNaN(num_tuple[0] || isNaN(num_tuple[1]))) {
|
|
throw new Error(`Invalid position encountered: ${str_tuple}`)
|
|
}
|
|
return num_tuple
|
|
}
|
|
|
|
const get_traces = (route, net) => {
|
|
let traces = ""
|
|
let layer = undefined
|
|
let start = undefined // [x, y]
|
|
|
|
for (let i = 0; i < route.length; i++) {
|
|
ch = route[i].toLowerCase()
|
|
switch (ch) {
|
|
case "f":
|
|
layer = "F.Cu"
|
|
break
|
|
case "b":
|
|
layer = "B.Cu"
|
|
break
|
|
case "v":
|
|
traces = traces + get_via(start, net) + "\n"
|
|
switch (layer) {
|
|
case "F.Cu":
|
|
layer = "B.Cu"
|
|
break
|
|
case "B.Cu":
|
|
layer = "F.Cu"
|
|
break
|
|
}
|
|
break
|
|
case "(":
|
|
let tuple_str = "("
|
|
let parenthesis_idx = i
|
|
for (i = i + 1; i < route.length; i++) {
|
|
let ch = route[i]
|
|
tuple_str += ch
|
|
if (route[i] == ")") {
|
|
break
|
|
}
|
|
if (i > route.length) {
|
|
throw new Error(
|
|
`Unclosed position parenthesis in ${route} at character position ${parenthesis_idx}`
|
|
)
|
|
}
|
|
}
|
|
let pos = parse_tuple(tuple_str)
|
|
if (start) {
|
|
traces = traces + get_segment(start, pos, layer, net) + "\n"
|
|
}
|
|
start = pos
|
|
break
|
|
case "<":
|
|
let net_name = ""
|
|
let lt_idx = i
|
|
for (i = i + 1; i < route.length; i++) {
|
|
let ch = route[i]
|
|
if (route[i] == ">") {
|
|
break
|
|
}
|
|
net_name += ch
|
|
if (i > route.length) {
|
|
throw new Error(
|
|
`Unclosed net parenthesis in ${route} at character position ${lt_idx}`
|
|
)
|
|
}
|
|
}
|
|
net = p.global_net(net_name)
|
|
case "x":
|
|
case "|":
|
|
start = undefined
|
|
break
|
|
default:
|
|
throw new Error(`Unsupported character '${ch}' at position ${i}.`)
|
|
}
|
|
}
|
|
|
|
return traces
|
|
}
|
|
|
|
const get_routes_traces = (routes, net) => {
|
|
let routes_traces = routes.reduce((acc_traces, route) => {
|
|
return acc_traces + get_traces(route, net)
|
|
}, "")
|
|
return routes_traces
|
|
}
|
|
|
|
let combined_traces = ""
|
|
let locked = p.locked ? 'locked ' : ''
|
|
if (p.route) {
|
|
combined_traces += get_traces(p.route, p.net.index)
|
|
}
|
|
if (p.routes) {
|
|
combined_traces += get_routes_traces(p.routes, p.net.index)
|
|
}
|
|
|
|
return combined_traces
|
|
},
|
|
} |