2021-07-14 19:33:33 +02:00
|
|
|
const yaml = require('js-yaml')
|
|
|
|
|
const json5 = require('json5')
|
|
|
|
|
const makerjs = require('makerjs')
|
|
|
|
|
const jscad = require('@jscad/openjscad')
|
|
|
|
|
|
|
|
|
|
const a = require('./assert')
|
|
|
|
|
const u = require('./utils')
|
|
|
|
|
|
2021-01-01 00:50:04 +01:00
|
|
|
const prepare = require('./prepare')
|
2021-07-11 13:45:53 +02:00
|
|
|
const units_lib = require('./units')
|
2021-01-01 00:50:04 +01:00
|
|
|
const points_lib = require('./points')
|
|
|
|
|
const outlines_lib = require('./outlines')
|
|
|
|
|
const cases_lib = require('./cases')
|
|
|
|
|
const pcbs_lib = require('./pcbs')
|
|
|
|
|
|
|
|
|
|
const noop = () => {}
|
|
|
|
|
|
2021-07-14 19:33:33 +02:00
|
|
|
const twodee = (model, debug) => {
|
|
|
|
|
const assembly = makerjs.model.originate({
|
|
|
|
|
models: {
|
|
|
|
|
export: u.deepcopy(model)
|
|
|
|
|
},
|
|
|
|
|
units: 'mm'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const result = {
|
|
|
|
|
dxf: makerjs.exporter.toDXF(assembly),
|
|
|
|
|
}
|
|
|
|
|
if (debug) {
|
|
|
|
|
result.json = assembly
|
|
|
|
|
result.svg = makerjs.exporter.toSVG(assembly)
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const threedee = async (script, debug) => {
|
|
|
|
|
const compiled = await new Promise((resolve, reject) => {
|
|
|
|
|
jscad.compile(script, {}).then(compiled => {
|
|
|
|
|
resolve(compiled)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
const result = {
|
|
|
|
|
stl: jscad.generateOutput('stla', compiled).asBuffer()
|
|
|
|
|
}
|
|
|
|
|
if (debug) {
|
|
|
|
|
result.jscad = script
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-16 22:24:46 +02:00
|
|
|
module.exports = {
|
2021-01-01 00:50:04 +01:00
|
|
|
version: '__ergogen_version',
|
2021-07-14 19:33:33 +02:00
|
|
|
process: async (raw, debug=false, logger=noop) => {
|
2021-01-01 00:50:04 +01:00
|
|
|
|
2021-07-14 19:33:33 +02:00
|
|
|
const prefix = 'Interpreting format... '
|
|
|
|
|
let config = raw
|
|
|
|
|
if (a.type(raw)() != 'object') {
|
|
|
|
|
try {
|
|
|
|
|
config = yaml.safeLoad(raw)
|
|
|
|
|
logger(prefix + 'YAML detected.')
|
|
|
|
|
} catch (yamlex) {
|
|
|
|
|
try {
|
|
|
|
|
config = json5.parse(raw)
|
|
|
|
|
logger(prefix + 'JSON detected.')
|
|
|
|
|
} catch (jsonex) {
|
|
|
|
|
try {
|
|
|
|
|
config = new Function(raw)()
|
|
|
|
|
logger(prefix + 'JS code detected.')
|
|
|
|
|
} catch (codeex) {
|
|
|
|
|
logger('YAML exception:', yamlex)
|
|
|
|
|
logger('JSON exception:', jsonex)
|
|
|
|
|
logger('Code exception:', codeex)
|
|
|
|
|
throw new Error('Input is not valid YAML, JSON, or JS code!')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!config) {
|
|
|
|
|
throw new Error('Input appears to be empty!')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger('Preprocessing input...')
|
2021-01-01 00:50:04 +01:00
|
|
|
config = prepare.unnest(config)
|
|
|
|
|
config = prepare.inherit(config)
|
|
|
|
|
const results = {}
|
2021-07-14 19:33:33 +02:00
|
|
|
if (debug) {
|
|
|
|
|
results.raw = raw
|
|
|
|
|
results.canonical = config
|
|
|
|
|
}
|
2021-01-01 00:50:04 +01:00
|
|
|
|
2021-07-11 13:45:53 +02:00
|
|
|
logger('Calculating variables...')
|
|
|
|
|
const units = units_lib.parse(config)
|
|
|
|
|
if (debug) {
|
|
|
|
|
results.units = units
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-01 00:50:04 +01:00
|
|
|
logger('Parsing points...')
|
2021-07-14 19:33:33 +02:00
|
|
|
if (!config.points) {
|
|
|
|
|
throw new Error('Input does not contain any points!')
|
|
|
|
|
}
|
2021-07-11 13:45:53 +02:00
|
|
|
const points = points_lib.parse(config.points, units)
|
2021-01-01 00:50:04 +01:00
|
|
|
if (debug) {
|
2021-07-11 13:45:53 +02:00
|
|
|
results.points = points
|
2021-07-14 19:33:33 +02:00
|
|
|
results.demo = twodee(points_lib.visualize(points), debug)
|
2021-01-01 00:50:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger('Generating outlines...')
|
|
|
|
|
const outlines = outlines_lib.parse(config.outlines || {}, points, units)
|
|
|
|
|
results.outlines = {}
|
|
|
|
|
for (const [name, outline] of Object.entries(outlines)) {
|
|
|
|
|
if (!debug && name.startsWith('_')) continue
|
2021-07-14 19:33:33 +02:00
|
|
|
results.outlines[name] = twodee(outline, debug)
|
2021-01-01 00:50:04 +01:00
|
|
|
}
|
|
|
|
|
|
2021-01-01 21:46:01 +01:00
|
|
|
logger('Extruding cases...')
|
|
|
|
|
const cases = cases_lib.parse(config.cases || {}, outlines, units)
|
|
|
|
|
results.cases = {}
|
2021-07-14 19:33:33 +02:00
|
|
|
for (const [case_name, case_script] of Object.entries(cases)) {
|
2021-01-01 21:46:01 +01:00
|
|
|
if (!debug && case_name.startsWith('_')) continue
|
2021-07-14 19:33:33 +02:00
|
|
|
results.cases[case_name] = await threedee(case_script, debug)
|
2021-01-01 21:46:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger('Scaffolding PCBs...')
|
|
|
|
|
const pcbs = pcbs_lib.parse(config.pcbs || {}, points, outlines, units)
|
|
|
|
|
results.pcbs = {}
|
|
|
|
|
for (const [pcb_name, pcb_text] of Object.entries(pcbs)) {
|
|
|
|
|
if (!debug && pcb_name.startsWith('_')) continue
|
|
|
|
|
results.pcbs[pcb_name] = pcb_text
|
|
|
|
|
}
|
2021-01-01 00:50:04 +01:00
|
|
|
|
|
|
|
|
return results
|
2021-03-15 17:40:08 +01:00
|
|
|
},
|
2021-07-11 20:36:11 +02:00
|
|
|
inject_footprint: pcbs_lib.inject_footprint
|
2020-06-16 22:24:46 +02:00
|
|
|
}
|