Unit refactor done
This commit is contained in:
parent
cd90705ba1
commit
83addc0879
8 changed files with 63 additions and 62 deletions
|
@ -3,7 +3,7 @@ const a = require('./assert')
|
||||||
const Point = require('./point')
|
const Point = require('./point')
|
||||||
|
|
||||||
const anchor = module.exports = (raw, name, points={}, check_unexpected=true, default_point=new Point()) => units => {
|
const anchor = module.exports = (raw, name, points={}, check_unexpected=true, default_point=new Point()) => units => {
|
||||||
if (a.type(raw) == 'array') {
|
if (a.type(raw)() == 'array') {
|
||||||
// recursive call with incremental default_point mods, according to `affect`s
|
// recursive call with incremental default_point mods, according to `affect`s
|
||||||
let current = () => default_point.clone()
|
let current = () => default_point.clone()
|
||||||
for (const step of raw) {
|
for (const step of raw) {
|
||||||
|
@ -14,7 +14,7 @@ const anchor = module.exports = (raw, name, points={}, check_unexpected=true, de
|
||||||
if (check_unexpected) a.detect_unexpected(raw, name, ['ref', 'orient', 'shift', 'rotate', 'affect'])
|
if (check_unexpected) a.detect_unexpected(raw, name, ['ref', 'orient', 'shift', 'rotate', 'affect'])
|
||||||
let point = default_point.clone()
|
let point = default_point.clone()
|
||||||
if (raw.ref !== undefined) {
|
if (raw.ref !== undefined) {
|
||||||
if (a.type(raw.ref) == 'array') {
|
if (a.type(raw.ref)() == 'array') {
|
||||||
// averaging multiple anchors
|
// averaging multiple anchors
|
||||||
let x = 0, y = 0, r = 0
|
let x = 0, y = 0, r = 0
|
||||||
const len = raw.ref.length
|
const len = raw.ref.length
|
||||||
|
@ -49,7 +49,7 @@ const anchor = module.exports = (raw, name, points={}, check_unexpected=true, de
|
||||||
point = default_point.clone()
|
point = default_point.clone()
|
||||||
const valid_affects = ['x', 'y', 'r']
|
const valid_affects = ['x', 'y', 'r']
|
||||||
let affect = raw.affect || valid_affects
|
let affect = raw.affect || valid_affects
|
||||||
if (a.type(affect) == 'string') affect = affect.split('')
|
if (a.type(affect)() == 'string') affect = affect.split('')
|
||||||
affect = a.strarr(affect, `${name}.affect`)
|
affect = a.strarr(affect, `${name}.affect`)
|
||||||
let i = 0
|
let i = 0
|
||||||
for (const a of affect) {
|
for (const a of affect) {
|
||||||
|
|
23
src/cases.js
23
src/cases.js
|
@ -1,10 +1,10 @@
|
||||||
const m = require('makerjs')
|
const m = require('makerjs')
|
||||||
const u = require('./utils')
|
|
||||||
const a = require('./assert')
|
const a = require('./assert')
|
||||||
|
const o = require('./operation')
|
||||||
|
|
||||||
exports.parse = (config, outlines) => {
|
exports.parse = (config, outlines, units) => {
|
||||||
|
|
||||||
const cases_config = a.sane(config, 'cases', 'object')
|
const cases_config = a.sane(config, 'cases', 'object')()
|
||||||
|
|
||||||
const scripts = {}
|
const scripts = {}
|
||||||
const cases = {}
|
const cases = {}
|
||||||
|
@ -39,19 +39,18 @@ exports.parse = (config, outlines) => {
|
||||||
for (let [case_name, case_config] of Object.entries(cases_config)) {
|
for (let [case_name, case_config] of Object.entries(cases_config)) {
|
||||||
|
|
||||||
// config sanitization
|
// config sanitization
|
||||||
case_config = a.inherit('cases', case_name, cases_config)
|
if (a.type(case_config)() == 'array') {
|
||||||
if (a.type(case_config) == 'array') {
|
|
||||||
case_config = {...case_config}
|
case_config = {...case_config}
|
||||||
}
|
}
|
||||||
const parts = a.sane(case_config, `cases.${case_name}`, 'object')
|
const parts = a.sane(case_config, `cases.${case_name}`, 'object')()
|
||||||
|
|
||||||
const body = []
|
const body = []
|
||||||
const case_dependencies = []
|
const case_dependencies = []
|
||||||
const outline_dependencies = []
|
const outline_dependencies = []
|
||||||
let first = true
|
let first = true
|
||||||
for (let [part_name, part] of Object.entries(parts)) {
|
for (let [part_name, part] of Object.entries(parts)) {
|
||||||
if (a.type(part) == 'string') {
|
if (a.type(part)() == 'string') {
|
||||||
part = a.op_str(part, {
|
part = o.operation(part, {
|
||||||
outline: Object.keys(outlines),
|
outline: Object.keys(outlines),
|
||||||
case: Object.keys(cases)
|
case: Object.keys(cases)
|
||||||
}, ['case', 'outline'])
|
}, ['case', 'outline'])
|
||||||
|
@ -60,14 +59,14 @@ exports.parse = (config, outlines) => {
|
||||||
const part_var = `${case_name}__part_${part_name}`
|
const part_var = `${case_name}__part_${part_name}`
|
||||||
a.detect_unexpected(part, part_qname, ['type', 'name', 'extrude', 'shift', 'rotate', 'operation'])
|
a.detect_unexpected(part, part_qname, ['type', 'name', 'extrude', 'shift', 'rotate', 'operation'])
|
||||||
const type = a.in(part.type || 'outline', `${part_qname}.type`, ['outline', 'case'])
|
const type = a.in(part.type || 'outline', `${part_qname}.type`, ['outline', 'case'])
|
||||||
const name = a.sane(part.name, `${part_qname}.name`, 'string')
|
const name = a.sane(part.name, `${part_qname}.name`, 'string')()
|
||||||
const shift = a.numarr(part.shift || [0, 0, 0], `${part_qname}.shift`, 3)
|
const shift = a.numarr(part.shift || [0, 0, 0], `${part_qname}.shift`, 3)(units)
|
||||||
const rotate = a.numarr(part.rotate || [0, 0, 0], `${part_qname}.rotate`, 3)
|
const rotate = a.numarr(part.rotate || [0, 0, 0], `${part_qname}.rotate`, 3)(units)
|
||||||
const operation = a.in(part.operation || 'add', `${part_qname}.operation`, ['add', 'subtract', 'intersect'])
|
const operation = a.in(part.operation || 'add', `${part_qname}.operation`, ['add', 'subtract', 'intersect'])
|
||||||
|
|
||||||
let base
|
let base
|
||||||
if (type == 'outline') {
|
if (type == 'outline') {
|
||||||
const extrude = a.sane(part.extrude || 1, `${part_qname}.extrude`, 'number')
|
const extrude = a.sane(part.extrude || 1, `${part_qname}.extrude`, 'number')(units)
|
||||||
const outline = outlines[name]
|
const outline = outlines[name]
|
||||||
a.assert(outline, `Field "${part_qname}.name" does not name a valid outline!`)
|
a.assert(outline, `Field "${part_qname}.name" does not name a valid outline!`)
|
||||||
if (!scripts[name]) {
|
if (!scripts[name]) {
|
||||||
|
|
20
src/cli.js
20
src/cli.js
|
@ -78,17 +78,17 @@ for (const [name, outline] of Object.entries(results.outlines)) {
|
||||||
io.dump_model(outline, path.join(args.o, `outlines/${name}`), args.debug)
|
io.dump_model(outline, path.join(args.o, `outlines/${name}`), args.debug)
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (const [name, pcb] of Object.entries(results.pcbs)) {
|
for (const [name, _case] of Object.entries(results.cases)) {
|
||||||
// const file = path.join(args.o, `pcbs/${name}.kicad_pcb`)
|
const file = path.join(args.o, `cases/${name}.jscad`)
|
||||||
// fs.mkdirpSync(path.dirname(file))
|
fs.mkdirpSync(path.dirname(file))
|
||||||
// fs.writeFileSync(file, pcb)
|
fs.writeFileSync(file, _case)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// for (const [name, _case] of Object.entries(results.cases)) {
|
for (const [name, pcb] of Object.entries(results.pcbs)) {
|
||||||
// const file = path.join(args.o, `cases/${name}.jscad`)
|
const file = path.join(args.o, `pcbs/${name}.kicad_pcb`)
|
||||||
// fs.mkdirpSync(path.dirname(file))
|
fs.mkdirpSync(path.dirname(file))
|
||||||
// fs.writeFileSync(file, _case)
|
fs.writeFileSync(file, pcb)
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (args.debug) {
|
if (args.debug) {
|
||||||
fs.writeJSONSync(path.join(args.o, 'results.json'), results, {spaces: 4})
|
fs.writeJSONSync(path.join(args.o, 'results.json'), results, {spaces: 4})
|
||||||
|
|
|
@ -33,21 +33,21 @@ module.exports = {
|
||||||
results.outlines[name] = outline
|
results.outlines[name] = outline
|
||||||
}
|
}
|
||||||
|
|
||||||
// logger('Extruding cases...')
|
logger('Extruding cases...')
|
||||||
// const cases = cases_lib.parse(config.cases || {}, outlines, units)
|
const cases = cases_lib.parse(config.cases || {}, outlines, units)
|
||||||
// results.cases = {}
|
results.cases = {}
|
||||||
// for (const [case_name, case_text] of Object.entries(cases)) {
|
for (const [case_name, case_text] of Object.entries(cases)) {
|
||||||
// if (!debug && case_name.startsWith('_')) continue
|
if (!debug && case_name.startsWith('_')) continue
|
||||||
// results.cases[case_name] = case_text
|
results.cases[case_name] = case_text
|
||||||
// }
|
}
|
||||||
|
|
||||||
// logger('Scaffolding PCBs...')
|
logger('Scaffolding PCBs...')
|
||||||
// const pcbs = pcbs_lib.parse(config.pcbs || {}, points, outlines, units)
|
const pcbs = pcbs_lib.parse(config.pcbs || {}, points, outlines, units)
|
||||||
// results.pcbs = {}
|
results.pcbs = {}
|
||||||
// for (const [pcb_name, pcb_text] of Object.entries(pcbs)) {
|
for (const [pcb_name, pcb_text] of Object.entries(pcbs)) {
|
||||||
// if (!debug && pcb_name.startsWith('_')) continue
|
if (!debug && pcb_name.startsWith('_')) continue
|
||||||
// results.cases[pcb_name] = pcb_text
|
results.pcbs[pcb_name] = pcb_text
|
||||||
// }
|
}
|
||||||
|
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ exports.parse = (config = {}, points = {}, units = {}) => {
|
||||||
sx: size[0],
|
sx: size[0],
|
||||||
sy: size[1]
|
sy: size[1]
|
||||||
}, units)
|
}, units)
|
||||||
anchor = a.anchor(part, name, points, false)(rec_units)
|
anchor = make_anchor(part, name, points, false)(rec_units)
|
||||||
const corner = a.sane(part.corner || 0, `${name}.corner`, 'number')(rec_units)
|
const corner = a.sane(part.corner || 0, `${name}.corner`, 'number')(rec_units)
|
||||||
const bevel = a.sane(part.bevel || 0, `${name}.bevel`, 'number')(rec_units)
|
const bevel = a.sane(part.bevel || 0, `${name}.bevel`, 'number')(rec_units)
|
||||||
const rect_mirror = a.sane(part.mirror || false, `${name}.mirror`, 'boolean')()
|
const rect_mirror = a.sane(part.mirror || false, `${name}.mirror`, 'boolean')()
|
||||||
|
|
36
src/pcbs.js
36
src/pcbs.js
|
@ -1,8 +1,6 @@
|
||||||
const m = require('makerjs')
|
const m = require('makerjs')
|
||||||
const u = require('./utils')
|
|
||||||
const a = require('./assert')
|
const a = require('./assert')
|
||||||
|
const make_anchor = require('./anchor')
|
||||||
const Point = require('./point')
|
|
||||||
|
|
||||||
const kicad_prefix = `
|
const kicad_prefix = `
|
||||||
(kicad_pcb (version 20171130) (host pcbnew 5.1.6)
|
(kicad_pcb (version 20171130) (host pcbnew 5.1.6)
|
||||||
|
@ -145,16 +143,16 @@ const makerjs2kicad = exports._makerjs2kicad = (model, layer='Edge.Cuts') => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const footprint_types = require('./footprints')
|
const footprint_types = require('./footprints')
|
||||||
const footprint = exports._footprint = (config, name, points, point, net_indexer, component_indexer) => {
|
const footprint = exports._footprint = (config, name, points, point, net_indexer, component_indexer, units) => {
|
||||||
|
|
||||||
if (config === false) return ''
|
if (config === false) return ''
|
||||||
|
|
||||||
// config sanitization
|
// config sanitization
|
||||||
a.detect_unexpected(config, name, ['type', 'anchor', 'nets', 'params'])
|
a.detect_unexpected(config, name, ['type', 'anchor', 'nets', 'params'])
|
||||||
const type = a.in(config.type, `${name}.type`, Object.keys(footprint_types))
|
const type = a.in(config.type, `${name}.type`, Object.keys(footprint_types))
|
||||||
let anchor = a.anchor(config.anchor || {}, `${name}.anchor`, points, true, point)
|
let anchor = make_anchor(config.anchor || {}, `${name}.anchor`, points, true, point)(units)
|
||||||
const nets = a.sane(config.nets || {}, `${name}.nets`, 'object')
|
const nets = a.sane(config.nets || {}, `${name}.nets`, 'object')()
|
||||||
const params = a.sane(config.params || {}, `${name}.params`, 'object')
|
const params = a.sane(config.params || {}, `${name}.params`, 'object')()
|
||||||
|
|
||||||
// basic setup
|
// basic setup
|
||||||
const fp = footprint_types[type]
|
const fp = footprint_types[type]
|
||||||
|
@ -174,11 +172,11 @@ const footprint = exports._footprint = (config, name, points, point, net_indexer
|
||||||
// connecting parametric nets
|
// connecting parametric nets
|
||||||
for (const net_ref of (fp.nets || [])) {
|
for (const net_ref of (fp.nets || [])) {
|
||||||
let net = nets[net_ref]
|
let net = nets[net_ref]
|
||||||
a.sane(net, `${name}.nets.${net_ref}`, 'string')
|
a.sane(net, `${name}.nets.${net_ref}`, 'string')()
|
||||||
if (net.startsWith('!') && point) {
|
if (net.startsWith('!') && point) {
|
||||||
const indirect = net.substring(1)
|
const indirect = net.substring(1)
|
||||||
net = point.meta[indirect]
|
net = point.meta[indirect]
|
||||||
a.sane(net, `${name}.nets.${net_ref} --> ${point.meta.name}.${indirect}`, 'string')
|
a.sane(net, `${name}.nets.${net_ref} --> ${point.meta.name}.${indirect}`, 'string')()
|
||||||
}
|
}
|
||||||
const index = net_indexer(net)
|
const index = net_indexer(net)
|
||||||
parsed_params.net[net_ref] = `(net ${index} "${net}")`
|
parsed_params.net[net_ref] = `(net ${index} "${net}")`
|
||||||
|
@ -189,7 +187,7 @@ const footprint = exports._footprint = (config, name, points, point, net_indexer
|
||||||
for (const param of (Object.keys(fp.params || {}))) {
|
for (const param of (Object.keys(fp.params || {}))) {
|
||||||
let value = params[param] === undefined ? fp.params[param] : params[param]
|
let value = params[param] === undefined ? fp.params[param] : params[param]
|
||||||
if (value === undefined) throw new Error(`Field "${name}.params.${param}" is missing!`)
|
if (value === undefined) throw new Error(`Field "${name}.params.${param}" is missing!`)
|
||||||
if (a.type(value) == 'string' && value.startsWith('!') && point) {
|
if (a.type(value)() == 'string' && value.startsWith('!') && point) {
|
||||||
const indirect = value.substring(1)
|
const indirect = value.substring(1)
|
||||||
value = point.meta[indirect]
|
value = point.meta[indirect]
|
||||||
if (value === undefined) throw new Error(`Field "${name}.params.${param} --> ${point.meta.name}.${indirect}" is missing!`)
|
if (value === undefined) throw new Error(`Field "${name}.params.${param} --> ${point.meta.name}.${indirect}" is missing!`)
|
||||||
|
@ -204,9 +202,9 @@ const footprint = exports._footprint = (config, name, points, point, net_indexer
|
||||||
return fp.body(parsed_params)
|
return fp.body(parsed_params)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.parse = (config, points, outlines) => {
|
exports.parse = (config, points, outlines, units) => {
|
||||||
|
|
||||||
const pcbs = a.sane(config || {}, 'pcbs', 'object')
|
const pcbs = a.sane(config || {}, 'pcbs', 'object')()
|
||||||
const results = {}
|
const results = {}
|
||||||
|
|
||||||
for (const [pcb_name, pcb_config] of Object.entries(pcbs)) {
|
for (const [pcb_name, pcb_config] of Object.entries(pcbs)) {
|
||||||
|
@ -215,14 +213,14 @@ exports.parse = (config, points, outlines) => {
|
||||||
a.detect_unexpected(pcb_config, `pcbs.${pcb_name}`, ['outlines', 'footprints'])
|
a.detect_unexpected(pcb_config, `pcbs.${pcb_name}`, ['outlines', 'footprints'])
|
||||||
|
|
||||||
// outline conversion
|
// outline conversion
|
||||||
if (a.type(pcb_config.outlines) == 'array') {
|
if (a.type(pcb_config.outlines)() == 'array') {
|
||||||
pcb_config.outlines = {...pcb_config.outlines}
|
pcb_config.outlines = {...pcb_config.outlines}
|
||||||
}
|
}
|
||||||
const config_outlines = a.sane(pcb_config.outlines || {}, `pcbs.${pcb_name}.outlines`, 'object')
|
const config_outlines = a.sane(pcb_config.outlines || {}, `pcbs.${pcb_name}.outlines`, 'object')()
|
||||||
const kicad_outlines = {}
|
const kicad_outlines = {}
|
||||||
for (const [outline_name, outline] of Object.entries(config_outlines)) {
|
for (const [outline_name, outline] of Object.entries(config_outlines)) {
|
||||||
const ref = a.in(outline.outline, `pcbs.${pcb_name}.outlines.${outline_name}.outline`, Object.keys(outlines))
|
const ref = a.in(outline.outline, `pcbs.${pcb_name}.outlines.${outline_name}.outline`, Object.keys(outlines))
|
||||||
const layer = a.sane(outline.layer || 'Edge.Cuts', `pcbs.${pcb_name}.outlines.${outline_name}.outline`, 'string')
|
const layer = a.sane(outline.layer || 'Edge.Cuts', `pcbs.${pcb_name}.outlines.${outline_name}.outline`, 'string')()
|
||||||
kicad_outlines[outline_name] = makerjs2kicad(outlines[ref], layer)
|
kicad_outlines[outline_name] = makerjs2kicad(outlines[ref], layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,17 +246,17 @@ exports.parse = (config, points, outlines) => {
|
||||||
// key-level footprints
|
// key-level footprints
|
||||||
for (const [p_name, point] of Object.entries(points)) {
|
for (const [p_name, point] of Object.entries(points)) {
|
||||||
for (const [f_name, f] of Object.entries(point.meta.footprints || {})) {
|
for (const [f_name, f] of Object.entries(point.meta.footprints || {})) {
|
||||||
footprints.push(footprint(f, `${p_name}.footprints.${f_name}`, points, point, net_indexer, component_indexer))
|
footprints.push(footprint(f, `${p_name}.footprints.${f_name}`, points, point, net_indexer, component_indexer, units))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// global one-off footprints
|
// global one-off footprints
|
||||||
if (a.type(pcb_config.footprints) == 'array') {
|
if (a.type(pcb_config.footprints)() == 'array') {
|
||||||
pcb_config.footprints = {...pcb_config.footprints}
|
pcb_config.footprints = {...pcb_config.footprints}
|
||||||
}
|
}
|
||||||
const global_footprints = a.sane(pcb_config.footprints || {}, `pcbs.${pcb_name}.footprints`, 'object')
|
const global_footprints = a.sane(pcb_config.footprints || {}, `pcbs.${pcb_name}.footprints`, 'object')()
|
||||||
for (const [gf_name, gf] of Object.entries(global_footprints)) {
|
for (const [gf_name, gf] of Object.entries(global_footprints)) {
|
||||||
footprints.push(footprint(gf, `pcbs.${pcb_name}.footprints.${gf_name}`, points, undefined, net_indexer, component_indexer))
|
footprints.push(footprint(gf, `pcbs.${pcb_name}.footprints.${gf_name}`, points, undefined, net_indexer, component_indexer, units))
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalizing nets
|
// finalizing nets
|
||||||
|
|
|
@ -48,12 +48,13 @@ const _inherit = exports._inherit = (config, root, breadcrumbs) => {
|
||||||
breadcrumbs.push(key)
|
breadcrumbs.push(key)
|
||||||
let newval = _inherit(val, root, breadcrumbs)
|
let newval = _inherit(val, root, breadcrumbs)
|
||||||
if (newval && newval.extends !== undefined) {
|
if (newval && newval.extends !== undefined) {
|
||||||
let candidates = [newval.extends]
|
let candidates = u.deepcopy(newval.extends)
|
||||||
|
if (a.type(candidates)() !== 'array') candidates = [candidates]
|
||||||
const list = [newval]
|
const list = [newval]
|
||||||
while (candidates.length) {
|
while (candidates.length) {
|
||||||
const path = candidates.shift()
|
const path = candidates.shift()
|
||||||
const other = u.deepcopy(u.deep(root, path))
|
const other = u.deepcopy(u.deep(root, path))
|
||||||
a.assert(other, `"${path}" (reached from "${breadcrumbs.join('.')}.${key}.extends") does not name a valid target!`)
|
a.assert(other, `"${path}" (reached from "${breadcrumbs.join('.')}.extends") does not name a valid inheritance target!`)
|
||||||
let parents = other.extends || []
|
let parents = other.extends || []
|
||||||
if (a.type(parents)() !== 'array') parents = [parents]
|
if (a.type(parents)() !== 'array') parents = [parents]
|
||||||
candidates = candidates.concat(parents)
|
candidates = candidates.concat(parents)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
const m = require('makerjs')
|
const m = require('makerjs')
|
||||||
|
|
||||||
exports.deepcopy = (value) => JSON.parse(JSON.stringify(value))
|
exports.deepcopy = value => {
|
||||||
|
if (value === undefined) return undefined
|
||||||
|
return JSON.parse(JSON.stringify(value))
|
||||||
|
}
|
||||||
|
|
||||||
const deep = exports.deep = (obj, key, val) => {
|
const deep = exports.deep = (obj, key, val) => {
|
||||||
const levels = key.split('.')
|
const levels = key.split('.')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue