Skip to content

Commit

Permalink
feat(dxf input support): add support of dxf files as inputs (#361)
Browse files Browse the repository at this point in the history
* added required changes for dxf input support
* changed input file format detection/ validation to be able to use the list of input formats
from core/io directly
* feat(metadata): added ability to pass -add-metadata option to CLI
to remove problematic (for tests) metadata in some output files
(so no more injection of jscad version, timestamps etc if passed false)
  • Loading branch information
kaosat-dev authored Mar 10, 2018
1 parent e121c0a commit bfd2835
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 43 deletions.
45 changes: 28 additions & 17 deletions packages/cli/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,15 @@
const fs = require('fs')
const env = require('./env')
const version = require('./package.json').version
const { formats } = require('@jscad/core/io/formats')
const { formats, conversionFormats } = require('@jscad/core/io/formats')
const { getDesignEntryPoint } = require('@jscad/core/code-loading/requireDesignUtilsFs')
const generateOutputData = require('./generateOutputData')

/*
const getExtension = filename => {
const ext = extname(filename || '').split('.')
return ext[ext.length - 1]
} */

// var csg = sphere(1); // -- basic test
// var csg = require(file).main; // -- treating .jscad as module? later perhaps

const args = process.argv.splice(2)

// handle arguments
// inputs, outputs
let {inputFile, inputFormat, outputFile, outputFormat, params} = parseArgs(args)
let {inputFile, inputFormat, outputFile, outputFormat, params, addMetaData} = parseArgs(args)

// outputs
const output = determineOutputNameAndFormat(outputFormat, outputFile)
Expand All @@ -73,12 +64,13 @@ let src = fs.readFileSync(inputFile, inputFile.match(/\.stl$/i) ? 'binary' : 'UT
// const outputData = generateOutputData(src, params, {outputFormat})
// -- and write it to disk
// writeOutputDataToFile(outputFile, outputData)
generateOutputData(src, params, {outputFile, outputFormat, inputFile, inputFormat, version})
generateOutputData(src, params, {outputFile, outputFormat, inputFile, inputFormat, version, addMetaData})
.then(function (outputData) {
writeOutputDataToFile(outputFile, outputData)
}).catch(error => console.error(error))

// -- helper functions ---------------------------------------------------------------------------------------

function parseArgs (args) {
// hint: https://github.com/substack/node-optimist
// https://github.com/visionmedia/commander.js
Expand All @@ -88,7 +80,7 @@ function parseArgs (args) {
// })
if (args.length < 1) {
console.log('USAGE:\n\nopenjscad [-v] <file> [-of <format>] [-o <output>]')
console.log('\t<file> :\tinput file (Supported types: .jscad, .js, .scad, .stl, .amf, .obj, .gcode, .svg, .json)')
console.log('\t<file> :\tinput file (Supported types: .jscad, .js, .scad, .stl, .amf, .obj, .gcode, .svg, .json, .dxf)')
console.log('\t<output>:\toutput file (Supported types: .jscad, .stl, .amf, .dxf, .svg, .json)')
console.log("\t<format>:\t'jscad', 'stla' (STL ASCII, default), 'stlb' (STL Binary), 'amf', 'dxf', 'svg', 'json'")
process.exit(1)
Expand All @@ -98,7 +90,22 @@ function parseArgs (args) {
let inputFormat
let outputFile
let outputFormat
let params = {}
let params = {} // parameters to feed the script if applicable
let addMetaData = false // wether to add metadata to outputs or not : ie version info, timestamp etc

// let supportedInputFormats = conversionFormats.join('|')
// console.log('supportedInputFormats', supportedInputFormats)
const isValidInputFileFormat = input => {
if (input === undefined || input === null || !(typeof input === 'string')) {
return false
}
return conversionFormats.reduce(function (acc, format) {
return input.toLowerCase().endsWith(format.toLowerCase()) || acc
}, false)
}
const getFileExtensionFromString = input => (input.substring(input.lastIndexOf('.') + 1)).toLowerCase()

const parseBool = input => input.toLowerCase() === "true"

for (let i = 0; i < args.length; i++) {
if (args[i] === '-of') { // -of <format>
Expand All @@ -108,15 +115,17 @@ function parseArgs (args) {
outputFile = outputFile.replace(/^\-o(\S+)$/, '$1')
} else if (args[i] === '-o') { // -o <output>
outputFile = args[++i]
} else if (args[i] === '-add-metadata') { // -metadata true/false
addMetaData = parseBool(args[++i])
} else if (args[i].match(/^--(\w+)=(.*)/)) { // params for main()
params[RegExp.$1] = RegExp.$2
} else if (args[i].match(/^--(\w+)$/)) { // params for main()
params[RegExp.$1] = args[++i]
} else if (args[i].match(/^--(\w+)$/)) { // params for main()
params[RegExp.$1] = args[++i]
} else if (args[i].match(/.+\.(jscad|js|scad|stl|amf|obj|gcode|svg|json)$/i)) {
} else if (isValidInputFileFormat(args[i])) {
inputFile = args[i]
inputFormat = RegExp.$1
inputFormat = getFileExtensionFromString(args[i])
if (!fs.statSync(inputFile).isFile()) {
console.log('ERROR: cannot open input file/directory <' + inputFile + '>')
process.exit(1)
Expand Down Expand Up @@ -150,7 +159,9 @@ function parseArgs (args) {
inputFormat,
outputFile,
outputFormat,
params}
params,
addMetaData
}
}

function determineOutputNameAndFormat (outputFormat, outputFile) {
Expand Down
42 changes: 22 additions & 20 deletions packages/cli/cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ test.beforeEach(t => {
jscadPath: path.resolve(__dirname, jscadPath)
}
})
// console.log('stl', fs.statSync(outputPath).size)

test('require() support', t => {
const jscadPath = t.context.jscadPath
Expand All @@ -36,7 +37,7 @@ test('require() support', t => {
// first install the module's dependencies, just in case
execSync('npm install', {cwd: designPath})
// note that in this case, we pass a FOLDER to the CLI, not a file
const cmd = `node ${jscadPath} ${designPath} --size 12.4 -o ${outputPath} -of stla`
const cmd = `node ${jscadPath} ${designPath} --size 12.4 -o ${outputPath} -of stla -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 1121, 2)
Expand All @@ -48,7 +49,7 @@ test('jscad (basic, input file only)', t => {
const expPath = path.join(examplesPath, '/logo.stl')
t.context = {outputPath: expPath}

const cmd = `node ${jscadPath} ${inputPath}`
const cmd = `node ${jscadPath} ${inputPath} -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(expPath).size, 338371, 2) // this has to be set this large because of the cross platform differences
Expand All @@ -60,7 +61,7 @@ test('jscad with parameters', t => {
const outputPath = 'JustMe_Geek_name_plate.amf'
const expPath = outputPath
t.context = {outputPath}
const cmd = `node ${jscadPath} ${inputPath} --name "Just Me" --title "Geek" -o ${outputPath} `
const cmd = `node ${jscadPath} ${inputPath} --name "Just Me" --title "Geek" -o ${outputPath} -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(expPath).size, 655732, 50)
Expand All @@ -72,7 +73,7 @@ test('jscad with complex/ multiple type of parameters', t => {
const outputPath = 'grille.stl'
const expPath = outputPath
t.context = {outputPath}
const cmd = `node ${jscadPath} ${inputPath} --outerwidth 176.25 --outerdepth 15.2 --numdividers 4 --addlooseners "Yes" --show "grille" --mouseears 0 --quality 0 -o ${outputPath} `
const cmd = `node ${jscadPath} ${inputPath} --outerwidth 176.25 --outerdepth 15.2 --numdividers 4 --addlooseners "Yes" --show "grille" --mouseears 0 --quality 0 -o ${outputPath} -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(expPath).size, 216484, 50)
Expand All @@ -85,7 +86,7 @@ test('jscad to stl (ascii)', t => {
const expPath = 'test.stl'
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stla`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stla -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(expPath).size, 338371, 2)
Expand All @@ -97,7 +98,7 @@ test('jscad to stl(binary)', t => {
const outputPath = 'test.stl'
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stlb`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stlb -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(outputPath))
// t.deepEqual(fs.readFileSync(expPath), fs.readFileSync(outputPath))
Expand All @@ -110,7 +111,7 @@ test('jscad to amf', t => {
const outputPath = 'test.amf'
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of amf`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of amf -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(outputPath))
almostEquals(t, fs.statSync(outputPath).size, 397341, 50)
Expand All @@ -123,7 +124,7 @@ test('jscad to amf(with transparency)', t => {
const expPath = outputPath
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of amf`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of amf -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 240108, 50)
Expand All @@ -136,7 +137,7 @@ test('openscad to stl (ascii)', t => {
const expPath = 'test.stl'
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stla`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stla -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 629242, 100)
Expand All @@ -149,7 +150,7 @@ test('openscad to stl(binary)', t => {
// const expPath = path.join(examplesPath, '/logo-binary.stl')
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stlb`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stlb -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(outputPath))
// t.deepEqual(fs.readFileSync(expPath), fs.readFileSync(outputPath))
Expand All @@ -163,7 +164,7 @@ test('openscad to amf', t => {
const expPath = outputPath
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of amf`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of amf -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 626177, 120)
Expand All @@ -176,7 +177,7 @@ test('openscad to openjscad', t => {
const expPath = outputPath
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of jscad`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of jscad -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 646, 2)
Expand All @@ -190,7 +191,7 @@ test('openscad to openjscad to stl', t => {
const expPath = outputPath
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${jscadOutputPath} -of jscad`
const cmd = `node ${jscadPath} ${inputPath} -o ${jscadOutputPath} -of jscad -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})

const cmd2 = `node ${jscadPath} ${jscadOutputPath} -o ${outputPath}`
Expand All @@ -208,7 +209,7 @@ test('echo() support', t => {
const expPath = outputPath
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of jscad`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of jscad -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 683, 2)
Expand All @@ -221,7 +222,7 @@ test('include support', t => {
const expPath = outputPath
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stla`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stla -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 19681, 60)
Expand All @@ -234,7 +235,7 @@ test('include support, with sub folders', t => {
const expPath = outputPath
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stla`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -of stla -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})
t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 281479, 2)
Expand All @@ -247,11 +248,11 @@ test('stl to openjscad', t => {
const expPath = outputPath
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath}`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})

t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 3707734, 2)
almostEquals(t, fs.statSync(outputPath).size, 3780879, 2)
})

test('amf to openjscad', t => {
Expand All @@ -261,11 +262,12 @@ test('amf to openjscad', t => {
const expPath = outputPath
t.context = {outputPath}

const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath}`
const cmd = `node ${jscadPath} ${inputPath} -o ${outputPath} -add-metadata false`
execSync(cmd, {stdio: [0, 1, 2]})

t.deepEqual(true, fs.existsSync(expPath))
almostEquals(t, fs.statSync(outputPath).size, 1870, 2)

almostEquals(t, fs.statSync(outputPath).size, 1754, 2)
})

// FIXME: DXF not working
Expand Down
4 changes: 3 additions & 1 deletion packages/cli/generateOutputData.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ function generateOutputData (source, params, options) {
outputFile: undefined,
outputFormat: 'stl',
inputFile: '',
version: ''
version: '',
addMetaData: true
}
options = Object.assign({}, defaults, options)
const {implicitGlobals, outputFile, outputFormat, inputFile, inputFormat, version} = options
Expand Down Expand Up @@ -53,6 +54,7 @@ function generateOutputData (source, params, options) {
gcode: data => require('@jscad/io').gcodeDeSerializer.deserialize(data.source, data.inputFile, options),
stl: data => require('@jscad/io').stlDeSerializer.deserialize(data.source, data.inputFile, options),
svg: data => require('@jscad/io').svgDeSerializer.deserialize(data.source, data.inputFile, options),
dxf: data => require('@jscad/io').dxfDeSerializer.deserialize(data.source, data.inputFile, options),
json: data => require('@jscad/io').jsonDeSerializer.deserialize(data.source, data.inputFile, options),
jscad: data => data.source,
js: data => data.source,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@jscad/core": "^0.1.0",
"@jscad/csg": "0.5.2",
"@jscad/examples": "^1.7.0",
"@jscad/io": "0.3.7",
"@jscad/io": "0.4.0",
"@jscad/openscad-openjscad-translator": "0.0.10"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions packages/core/io/formats.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ const conversionFormats = [
'obj',
'scad',
'stl',
'dxf',
// 2D file formats
'svg'
]
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"license": "MIT",
"dependencies": {
"@jscad/csg": "0.5.2",
"@jscad/io": "0.3.7",
"@jscad/io": "0.4.0",
"@jscad/openscad-openjscad-translator": "0.0.10",
"astring": "^1.0.2",
"esprima": "^3.1.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@jscad/core": "^0.1.0",
"@jscad/csg": "0.5.2",
"@jscad/examples": "^1.7.0",
"@jscad/io": "0.3.7",
"@jscad/io": "0.4.0",
"@jscad/openscad-openjscad-translator": "0.0.10",
"astring": "^1.0.2",
"brace": "0.10.0",
Expand Down
6 changes: 4 additions & 2 deletions packages/web/src/io/conversionWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
//
// NOTE: Additional scripts (libraries) are imported only if necessary



module.exports = function (self) {
self.onmessage = function (e) {
var r = { source: '', converted: '', filename: '', baseurl: '', cache: false }
Expand Down Expand Up @@ -82,6 +80,10 @@ module.exports = function (self) {
const deserializeJson = require('@jscad/io').jsonDeSerializer.deserialize
r.source = r.converted = deserializeJson(data.source, data.filename, options)
break
case 'dxf':
const deserializeDXF = require('@jscad/io').dxfDeSerializer.deserialize
r.source = r.converted = deserializeDXF(data.source, data.filename, options)
break
default:
r.source = r.converted = '// Invalid file type in conversion (' + e + ')'
break
Expand Down

0 comments on commit bfd2835

Please sign in to comment.