Mixed progress, vol. 2

This commit is contained in:
Bán Dénes 2020-07-17 23:20:49 +02:00
parent c3d7643371
commit 5a380fa58c
7 changed files with 192 additions and 157 deletions

View file

@ -106,7 +106,7 @@ const extend_pair = exports.extend_pair = (to, from) => {
} else return from
}
exports.extend = (...args) => {
const extend = exports.extend = (...args) => {
let res = args[0]
for (const arg of args) {
if (res == arg) continue
@ -115,18 +115,22 @@ exports.extend = (...args) => {
return res
}
const inherit = exports.inherit = (config, name_prefix, name, set) => {
let result = u.deepcopy(config)
if (config.extends !== undefined) {
let list = config.extends
if (type(list) !== 'array') list = [list]
for (const item of list) {
const other = set[item]
assert(other, `Field "${name_prefix}.${name}" does not name a valid target!`)
result = extend_pair(inherit(other, name_prefix, config.extends, set), result)
const inherit = exports.inherit = (name_prefix, name, set) => {
let result = u.deepcopy(set[name])
if (result.extends !== undefined) {
let candidates = [name]
const list = []
while (candidates.length) {
const item = candidates.shift()
const other = u.deepcopy(set[item])
assert(other, `"${item}" (reached from "${name_prefix}.${name}.extends") does not name a valid target!`)
let parents = other.extends || []
if (type(parents) !== 'array') parents = [parents]
candidates = candidates.concat(parents)
delete other.extends
list.unshift(other)
}
delete result.extends
result = extend.apply(this, list)
}
return result
}

View file

@ -12,8 +12,8 @@ const yargs = require('yargs')
const u = require('./utils')
const io = require('./io')
const points_lib = require('./points')
const outline_lib = require('./outline')
const pcb_lib = require('./pcb')
const outlines_lib = require('./outlines')
const pcbs_lib = require('./pcbs')
// command line args
@ -68,19 +68,21 @@ if (args.debug) {
// outlines
console.log('Generating outlines...')
const outlines = outline_lib.parse(config.outline, points)
const outlines = outlines_lib.parse(config.outlines, points)
for (const [name, outline] of Object.entries(outlines)) {
if (!args.debug && name.startsWith('_')) continue
io.dump_model(outline, path.join(args.o, `outline/${name}`), args.debug)
io.dump_model(outline, path.join(args.o, `outlines/${name}`), args.debug)
}
// pcb
// pcbs
console.log('Scaffolding PCB...')
const pcb = pcb_lib.parse(config.pcb, points, outlines)
const pcb_file = path.join(args.o, `pcb/pcb.kicad_pcb`)
fs.mkdirpSync(path.dirname(pcb_file))
fs.writeFileSync(pcb_file, pcb)
console.log('Scaffolding PCBs...')
const pcbs = pcbs_lib.parse(config.pcbs, points, outlines)
for (const [pcb_name, pcb_text] of Object.entries(pcbs)) {
const pcb_file = path.join(args.o, `pcbs/${pcb_name}.kicad_pcb`)
fs.mkdirpSync(path.dirname(pcb_file))
fs.writeFileSync(pcb_file, pcb_text)
}
// goodbye

View file

@ -35,23 +35,23 @@ const layout = exports._layout = (config = {}, points = {}) => {
// Glue config sanitization
const parsed_glue = u.deepcopy(a.sane(config, 'outline.glue', 'object'))
const parsed_glue = u.deepcopy(a.sane(config, 'outlines.glue', 'object'))
for (let [gkey, gval] of Object.entries(parsed_glue)) {
gval = a.inherit(gval, 'outline.glue', gkey, config)
a.detect_unexpected(gval, `outline.glue.${gkey}`, ['top', 'bottom', 'waypoints', 'extra'])
gval = a.inherit('outlines.glue', gkey, config)
a.detect_unexpected(gval, `outlines.glue.${gkey}`, ['top', 'bottom', 'waypoints', 'extra'])
for (const y of ['top', 'bottom']) {
a.detect_unexpected(gval[y], `outline.glue.${gkey}.${y}`, ['left', 'right'])
gval[y].left = relative_anchor(gval[y].left, `outline.glue.${gkey}.${y}.left`, points)
a.detect_unexpected(gval[y], `outlines.glue.${gkey}.${y}`, ['left', 'right'])
gval[y].left = relative_anchor(gval[y].left, `outlines.glue.${gkey}.${y}.left`, points)
if (a.type(gval[y].right) != 'number') {
gval[y].right = relative_anchor(gval[y].right, `outline.glue.${gkey}.${y}.right`, points)
gval[y].right = relative_anchor(gval[y].right, `outlines.glue.${gkey}.${y}.right`, points)
}
}
gval.waypoints = a.sane(gval.waypoints || [], `outline.glue.${gkey}.waypoints`, 'array')
gval.waypoints = a.sane(gval.waypoints || [], `outlines.glue.${gkey}.waypoints`, 'array')
let wi = 0
gval.waypoints = gval.waypoints.map(w => {
const name = `outline.glue.${gkey}.waypoints[${++wi}]`
const name = `outlines.glue.${gkey}.waypoints[${++wi}]`
a.detect_unexpected(w, name, ['percent', 'width'])
w.percent = a.sane(w.percent, name + '.percent', 'number')
w.width = a.wh(w.width, name + '.width')
@ -208,12 +208,12 @@ exports.parse = (config = {}, points = {}) => {
const outlines = {}
const ex = a.sane(config.exports, 'outline.exports', 'object')
for (const [key, parts] of Object.entries(ex)) {
let index = 0
const ex = a.sane(config.exports, 'outlines.exports', 'object')
for (let [key, parts] of Object.entries(ex)) {
parts = a.inherit('outlines.exports', key, ex)
let result = {models: {}}
for (const part of parts) {
const name = `outline.exports.${key}[${++index}]`
for (const [part_name, part] of Object.entries(parts)) {
const name = `outlines.exports.${key}.${part_name}`
const expected = ['type', 'operation']
part.type = a.in(part.type, `${name}.type`, ['keys', 'rectangle', 'circle', 'polygon', 'outline'])
part.operation = a.in(part.operation || 'add', `${name}.operation`, ['add', 'subtract', 'intersect', 'stack'])

View file

@ -204,56 +204,62 @@ const footprint = exports._footprint = (config, name, points, net_indexer, point
exports.parse = (config, points, outlines) => {
// config sanitization
a.detect_unexpected(config, 'pcb', ['edge', 'footprints'])
const edge = outlines[config.edge]
if (!edge) throw new Error(`Field "pcb.edge" doesn't name a valid outline!`)
const pcbs = a.sane(config, 'pcb', 'object')
const results = {}
// Edge.Cuts conversion
const kicad_edge = makerjs2kicad(edge)
for (const [pcb_name, pcb_config] of Object.entries(pcbs)) {
// making a global net index registry
const nets = {"": 0}
const net_indexer = net => {
if (nets[net] !== undefined) return nets[net]
const index = Object.keys(nets).length
return nets[net] = index
}
// config sanitization
a.detect_unexpected(pcb_config, `pcb.${pcb_name}`, ['edge', 'footprints'])
const edge = outlines[pcb_config.edge]
if (!edge) throw new Error(`Field "pcb.${pcb_name}.edge" doesn't name a valid outline!`)
const footprints = []
// Edge.Cuts conversion
const kicad_edge = makerjs2kicad(edge)
// key-level footprints
for (const [pname, point] of Object.entries(points)) {
for (const [f_name, f] of Object.entries(point.meta.footprints || {})) {
footprints.push(footprint(f, `${pname}.footprints.${f_name}`, points, net_indexer, point))
// making a global net index registry
const nets = {"": 0}
const net_indexer = net => {
if (nets[net] !== undefined) return nets[net]
const index = Object.keys(nets).length
return nets[net] = index
}
const footprints = []
// key-level footprints
for (const [p_name, point] of Object.entries(points)) {
for (const [f_name, f] of Object.entries(point.meta.footprints || {})) {
footprints.push(footprint(f, `${p_name}.footprints.${f_name}`, points, net_indexer, point))
}
}
// global one-off footprints
const global_footprints = a.sane(pcb_config.footprints || {}, `pcb.${pcb_name}.footprints`, 'object')
for (const [gf_name, gf] of Object.entries(global_footprints)) {
footprints.push(footprint(gf, `pcb.${pcb_name}.footprints.${gf_name}`, points, net_indexer))
}
// finalizing nets
const nets_arr = []
const add_nets_arr = []
for (const [net, index] of Object.entries(nets)) {
nets_arr.push(`(net ${index} "${net}")`)
add_nets_arr.push(`(add_net "${net}")`)
}
const netclass = kicad_netclass.replace('__ADD_NET', add_nets_arr.join('\n'))
const nets_text = nets_arr.join('\n')
const footprint_text = footprints.join('\n')
results[pcb_name] = `
${kicad_prefix}
${nets_text}
${netclass}
${footprint_text}
${kicad_edge}
${kicad_suffix}
`
}
// global one-off footprints
const global_footprints = a.sane(config.footprints || {}, 'pcb.footprints', 'object')
for (const [gf_name, gf] of Object.entries(global_footprints)) {
footprints.push(footprint(gf, `pcb.footprints.${gf_name}`, points, net_indexer))
}
// finalizing nets
const nets_arr = []
const add_nets_arr = []
for (const [net, index] of Object.entries(nets)) {
nets_arr.push(`(net ${index} "${net}")`)
add_nets_arr.push(`(add_net "${net}")`)
}
const netclass = kicad_netclass.replace('__ADD_NET', add_nets_arr.join('\n'))
const nets_text = nets_arr.join('\n')
const footprint_text = footprints.join('\n')
return `
${kicad_prefix}
${nets_text}
${netclass}
${footprint_text}
${kicad_edge}
${kicad_suffix}
`
return results
}

View file

@ -180,7 +180,7 @@ exports.parse = (config = {}) => {
for (let [zone_name, zone] of Object.entries(zones)) {
// handle zone-level `extends` clauses
zone = a.inherit(zone, 'points.zones', zone_name, zones)
zone = a.inherit('points.zones', zone_name, zones)
const anchor = a.anchor(zone.anchor || {}, `points.zones.${zone_name}.anchor`, points)
points = Object.assign(points, render_zone(zone_name, zone, anchor, global_key))