Mixed progress, vol. 2
This commit is contained in:
parent
c3d7643371
commit
5a380fa58c
7 changed files with 192 additions and 157 deletions
|
@ -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
|
||||
}
|
22
src/cli.js
22
src/cli.js
|
@ -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
|
||||
|
||||
|
|
|
@ -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'])
|
|
@ -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
|
||||
}
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue