Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2 : Fix Deserializers #527

Merged
merged 4 commits into from
Mar 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 19 additions & 22 deletions packages/cli/src/generateOutputData.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const fs = require('fs')
const { isAbsolute, resolve } = require('path')

const { solidsAsBlob } = require('@jscad/io')
// const rebuildSolids = require('@jscad/core/code-evaluation/rebuildGeometry')

const rebuildSolids = require('@jscad/core/code-evaluation/rebuildGeometryCli')
const { registerAllExtensions } = require('@jscad/core/io/registerExtensions')

Expand All @@ -23,37 +24,33 @@ const generateOutputData = (source, params, options) => {
options = Object.assign({}, defaults, options)
const { outputFile, outputFormat, inputFile, inputFormat, version, inputIsDirectory } = options

const inputPath = isAbsolute(inputFile) ? inputFile : resolve(process.cwd(), inputFile) // path.dirname(inputFile)
options.filename = inputFile // for deserializers

// console.log('foo', outputFile, outputFormat, inputFile, inputFormat, version)
// objects = rebuildSolid(source, '', params, globals, callback)
return new Promise(function (resolve, reject) {
const callback = (err, result) => {
if (!err) {
return resolve(result)
}
return reject(err)
}
const inputPath = isAbsolute(inputFile) ? inputFile : resolve(process.cwd(), inputFile)

// setup support for require-ing files with .jscad, .stl etc extensions
registerAllExtensions(fs, require)
// setup support for require-ing files with .jscad, .stl etc extensions
registerAllExtensions(fs, require)

return new Promise((resolve, reject) => {
// FIXME this table should come from core
const conversionTable = {
amf: data => require('@jscad/io').amfDeSerializer.deserialize(data.source, data.inputFile, options),
obj: data => require('@jscad/io').objDeSerializer.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),
amf: data => require('@jscad/io').amfDeSerializer.deserialize(data.options, data.source),
z3dev marked this conversation as resolved.
Show resolved Hide resolved
obj: data => require('@jscad/io').objDeSerializer.deserialize(data.options, data.source),
stl: data => require('@jscad/io').stlDeSerializer.deserialize(data.options, data.source),
svg: data => require('@jscad/io').svgDeSerializer.deserialize(data.options, data.source),
dxf: data => require('@jscad/io').dxfDeSerializer.deserialize(data.options, data.source),
json: data => require('@jscad/io').jsonDeSerializer.deserialize(data.options, data.source),
jscad: data => data.source,
js: data => data.source,
/*
scad: data => {
const source = !data.source.match(/^\/\/!OpenSCAD/i) ? '//!OpenSCAD\n' + data.source : data.source
const parsed = require('@jscad/openscad-openjscad-translator').parse(source)
return `//producer: OpenJSCAD ${version}
// source: ${outputFile}
${parsed}`
},
*/
undefined: data => reject(new Error(`unsuported input format ${inputFormat}`))
}

Expand All @@ -62,8 +59,9 @@ const generateOutputData = (source, params, options) => {

if (outputFormat === 'jscad' || outputFormat === 'js') {
resolve(source)
} else if ((inputFormat === 'jscad' || inputFormat === 'js') &&
outputFormat !== 'jscad' && outputFormat !== 'js') {
} else {
// } else if ((inputFormat === 'jscad' || inputFormat === 'js') &&
z3dev marked this conversation as resolved.
Show resolved Hide resolved
// outputFormat !== 'jscad' && outputFormat !== 'js') {
try {
const solids = rebuildSolids({ mainPath: inputPath, parameterValues: params, inputIsDirectory, source })
resolve(solids)
Expand All @@ -73,7 +71,6 @@ const generateOutputData = (source, params, options) => {
}
})
.then(solids => {
// Buffer.from(outputData.data),{encoding: outputData.mimeType},
return solidsAsBlob(solids, { format: outputFormat })
})
}
Expand Down
14 changes: 8 additions & 6 deletions packages/core/code-loading/transformSources.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,41 @@ const createJscadEntry = (entry, source) => {
const transformAmfToJscad = (options, entry) => {
// console.log('***** transformAmfToJscad',options,entry)
const deserialize = require('@jscad/io').amfDeSerializer.deserialize
const source = deserialize(entry.source, entry.name, options)
const source = deserialize(options, entry.source)
return createJscadEntry(entry, source)
}

const transformDxfToJscad = (options, entry) => {
// console.log('***** transformDxfToJscad',options,entry)
const deserialize = require('@jscad/io').dxfDeSerializer.deserialize
const source = deserialize(entry.source, entry.name, options)
const source = deserialize(options, entry.source)
return createJscadEntry(entry, source)
}

const transformObjToJscad = (options, entry) => {
// console.log('***** transformObjToJscad',options,entry)
const deserialize = require('@jscad/io').objDeSerializer.deserialize
const source = deserialize(entry.source, entry.name, options)
const source = deserialize(options, entry.source)
return createJscadEntry(entry, source)
}

const transformStlToJscad = (options, entry) => {
// console.log('***** transformStlToJscad',options,entry)
const deserialize = require('@jscad/io').stlDeSerializer.deserialize
const source = deserialize(entry.source, entry.name, options)
const source = deserialize(options, entry.source)
return createJscadEntry(entry, source)
}

const transformSvgToJscad = (options, entry) => {
// console.log('***** transformSvgToJscad',options,entry)
const deserialize = require('@jscad/io').svgDeSerializer.deserialize
const source = deserialize(entry.source, entry.name, options)
const source = deserialize(options, entry.source)
return createJscadEntry(entry, source)
}

const transformSources = (options, filesAndFolders) => {
// console.log('***** transformSources', options, filesAndFolders)
// FIXME this table should come from IO
const transformsPerFormat = {
'js': [modulifyTransform],
'jscad': [modulifyTransform],
Expand All @@ -73,9 +74,10 @@ const transformSources = (options, filesAndFolders) => {

function updateEntry (entry) {
if (entry.source) {
const transformOptions = Object.assign({}, options, {filename: entry.name})
const transforms = transformsPerFormat[entry.ext] ? transformsPerFormat[entry.ext] : [passThroughTransform]
const transformedEntry = transforms.reduce((entry, transform) => {
return transform(options, entry)
return transform(transformOptions, entry)
}, entry)

return transformedEntry
Expand Down
4 changes: 2 additions & 2 deletions packages/core/code-loading/webRequire.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ test('webRequire: should allow using require.extensions like the native node req
const deserializer = require('@jscad/io').stlDeSerializer
_require.extensions['.stl'] = (module, filename) => {
const content = fs.readFileSync(filename, 'utf8')
const parsed = deserializer.deserialize(content, filename, { output: 'geometry' })
const parsed = deserializer.deserialize({ filename, output: 'geometry' }, content)
module.exports = parsed
}
}
Expand Down Expand Up @@ -320,4 +320,4 @@ test('webRequire: should allow using require.extensions like the native node req
t.true(designRootModule.main instanceof Function)
const resultOfMain = designRootModule.main()
t.true('cube' in resultOfMain)
})
})
6 changes: 3 additions & 3 deletions packages/core/io/registerExtensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const registerStlExtension = (fs, _require) => {
const deserializer = require('@jscad/io').stlDeSerializer
_require.extensions['.stl'] = (module, filename) => {
const content = fs.readFileSync(filename, 'utf8')
const parsed = deserializer.deserialize(content, filename, { output: 'geometry' })
const parsed = deserializer.deserialize({ filename, output: 'geometry' }, content)
module.exports = parsed
}
}
Expand All @@ -26,7 +26,7 @@ const registerAmfExtension = (fs, _require) => {
const deserializer = require('@jscad/io').amfDeSerializer
_require.extensions['.amf'] = (module, filename) => {
const content = fs.readFileSync(filename, 'utf8')
const parsed = deserializer.deserialize(content, filename, { output: 'geometry' })
const parsed = deserializer.deserialize({ filename, output: 'geometry' }, content)
module.exports = parsed
}
}
Expand All @@ -38,7 +38,7 @@ const registerDxfExtension = (fs, _require) => {
const deserializer = require('@jscad/io').dxfDeSerializer
_require.extensions['.dxf'] = (module, filename) => {
const content = fs.readFileSync(filename, 'utf8')
const parsed = deserializer.deserialize(content, filename, { output: 'geometry' })
const parsed = deserializer.deserialize({ filename, output: 'geometry' }, content)
module.exports = parsed
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/io/amf-deserializer/deserialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const createObject = require('./objectBuilder')

const parse = require('./parse')

const instantiate = (src, filename, options) => {
const instantiate = (options, src) => {
const defaults = {
pxPmm: require('./constants').pxPmm
}
Expand Down
22 changes: 12 additions & 10 deletions packages/io/amf-deserializer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,29 @@ const instantiate = require('./deserialize')

/**
* Deserialize the given AMF source (xml) into either a script or an array of geometry
* @param {String} input - AMF source data
* @param {String} [filename] - original filename of AMF source
* @param {Object} [options] - options used during deserializing
* @param {String} [options.output='jscad'] - either 'jscad' or 'object' to set desired output
* @param {String} [options.filename='amf'] - filename of original AMF source
* @param {String} [options.output='script'] - either 'script' or 'geometry' to set desired output
* @param {String} [options.version='0.0.0'] - version number to add to the metadata
* @param {Boolean} [options.addMetadata=true] - toggle injection of metadata at the start of the script
* @return {[geometry]/String} either an array of geometry (object) or a string (jscad)
* @param {String} input - AMF source data
* @return {[geometry]/String} either an array of objects (geometry) or a string (script)
*/
const deserialize = (input, filename, options) => {
const deserialize = (options, input) => {
const defaults = {
output: 'jscad',
filename: 'amf',
output: 'script',
version,
addMetaData: true
}
options = Object.assign({}, defaults, options)

filename = filename || 'amf'

return options.output === 'jscad' ? translate(input, filename, options) : instantiate(input, filename, options)
return options.output === 'script' ? translate(options, input) : instantiate(options, input)
}

const extension = 'amf'

module.exports = {
deserialize
deserialize,
extension
}
2 changes: 1 addition & 1 deletion packages/io/amf-deserializer/tests/instantiate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test('deserialize simple amf to geometry', function (t) {
const inputPath = path.resolve(samplesPath, 'amf/Amf_Cube.amf')
const inputFile = fs.readFileSync(inputPath, 'utf8')

const observed = deserializer.deserialize(inputFile, undefined, { output: 'csg', addMetaData: false })
const observed = deserializer.deserialize({ output: 'geometry', addMetaData: false }, inputFile)
t.is(observed.length, 1)
const polygons = geometry.geom3.toPolygons(observed[0])
t.deepEqual(polygons.length, 12)
Expand Down
8 changes: 4 additions & 4 deletions packages/io/amf-deserializer/tests/translate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ const countOf = (search, string) => {
return count
}

test('deserialize simple amf file to jscad code', function (t) {
test('deserialize simple amf file to jscad script', function (t) {
const inputPath = path.resolve(samplesPath, 'amf/Amf_Cube.amf')
const inputFile = fs.readFileSync(inputPath)

const observed = deserializer.deserialize(inputFile, undefined, { output: 'jscad', addMetaData: false })
const observed = deserializer.deserialize({ output: 'script', addMetaData: false }, inputFile)
t.is(countOf('poly3.fromPoints', observed), 12)
t.is(countOf('color.color', observed), 12)
t.is(countOf('geom3.create', observed), 1)
})

test('deserialize amf file with materials to jscad code', function (t) {
test('deserialize amf file with materials to jscad script', function (t) {
const inputPath = path.resolve(samplesPath, 'amf/cube-with-hole.amf')
const inputFile = fs.readFileSync(inputPath)

const observed = deserializer.deserialize(inputFile, undefined, { output: 'jscad', addMetaData: false })
const observed = deserializer.deserialize({ output: 'script', addMetaData: false }, inputFile)
t.is(countOf('poly3.fromPoints', observed), 144)
t.is(countOf('color.color', observed), 144)
t.is(countOf('geom3.create', observed), 1)
Expand Down
4 changes: 2 additions & 2 deletions packages/io/amf-deserializer/translate.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const createObject = require('./objectBuilder')
const parse = require('./parse')

const translate = (src, filename, options) => {
const translate = (options, src) => {
const defaults = {
pxPmm: require('./constants').pxPmm
}
options = Object.assign({}, defaults, options)
const { version, pxPmm, addMetaData } = options
const { version, pxPmm, addMetaData, filename } = options

options && options.statusCallback && options.statusCallback({ progress: 0 })

Expand Down
26 changes: 15 additions & 11 deletions packages/io/dxf-deserializer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ const createReader = (src, options) => {
//
// instantiate the give DXF definition (src) into a set of CSG library objects
//
const instantiate = (src, filename, options) => {
const instantiate = (src, options) => {
const reader = createReader(src, options)
const objs = instantiateAsciiDxf(reader, options)
return objs
Expand All @@ -555,33 +555,34 @@ const instantiate = (src, filename, options) => {
//
// translate the give DXF definition (src) into a JSCAD script
//
const translate = (src, filename, options) => {
const translate = (src, options) => {
const reader = createReader(src, options)

let code = `// Produced by JSCAD IO Library : DXF Deserializer (${options.version})

`
// code += '// date: ' + (new Date()) + '\n'
// code += '// source: ' + filename + '\n'
// code += '// source: ' + options.filename + '\n'
code += translateAsciiDxf(reader, options)
return code
}

/**
* Deserialize the given source and return the requested 'output'
* @param {string} src DXF data stream
* @param {string} filename (optional) original filename of DXF data stream if any
* @param {object} options (optional) anonymous object with:
* @param {string} [options.filename='dxf'] filename of original DXF data stream
* @param {string} [options.version='0.0.1'] version number to add to the metadata
* @param {string} [options.output='jscad'] either jscad or geometry to set desired output
* @param {string} [options.output='script'] either script or geometry to set desired output
* @param {boolean} [options.strict=true] obey strict DXF specifications
* @param {array} [options.colorindex=[]] list of colors (256) for use during rendering
* @return {string|[objects]} a string (jscad script) or array of objects
* @param {string} src DXF data stream
* @return {string|[objects]} a string (script) or array of objects (geometry)
*/
const deserialize = (src, filename, options) => {
const deserialize = (options, src) => {
const defaults = {
filename: 'dxf',
version,
output: 'jscad',
output: 'script',
strict: true,
colorindex: colorIndex,
dxf: {
Expand All @@ -591,9 +592,12 @@ const deserialize = (src, filename, options) => {
}
}
options = Object.assign({}, defaults, options)
return options.output === 'jscad' ? translate(src, filename, options) : instantiate(src, filename, options)
return options.output === 'script' ? translate(src, options) : instantiate(src, options)
}

const extension = 'dxf'

module.exports = {
deserialize
deserialize,
extension
}
Loading