Skip to content

Commit

Permalink
require-geometry-files (#71)
Browse files Browse the repository at this point in the history
I hacked up a quick support to require stl and other jscad supported
geometry.

it may not work for all that work on jscad web, but it definitely works
for openjscad examples
https://github.com/jscad/OpenJSCAD.org/tree/master/packages/examples/import


AMFImport

![image](https://github.com/hrgdavor/jscadui/assets/2480762/db129913-c667-4aca-9285-3944b88b4417)

STLImport

![image](https://github.com/hrgdavor/jscadui/assets/2480762/14bad511-27dc-47b0-8aad-fe9787b52fb4)

SVGImport

![image](https://github.com/hrgdavor/jscadui/assets/2480762/96b6722b-d18e-487e-a1d4-c5b45edddd8f)
  • Loading branch information
hrgdavor authored Dec 7, 2023
1 parent 92896fe commit c70e968
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 8 deletions.
20 changes: 19 additions & 1 deletion apps/jscad-web/src_bundle/bundle.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,22 @@ const exportData = ({format, options={}})=>{
return withTransferable({ data }, data.filter(v=>typeof v !== 'string'))
}

initWorker(transformcjs, exportData)
const importData = (url, readFile, base, root, moduleBase)=>{
try {
const jscad_io = require('./bundle.jscad_io.js', null, readFileWeb)
let idx = url.lastIndexOf('/')
let filename = url.substring(idx+1)
idx = filename.lastIndexOf('.')
let ext = filename.substring(idx+1)
let deserializer = jscad_io.deserializers[ext]
let file = readFile(url,{output:ext === 'stl' ? 'bin':'text'})

if(deserializer) return deserializer({output:'geometry', filename}, file)
throw new Error('unsupportd format in '+url)
} catch (error) {
console.error(error)
throw error
}
}

initWorker(transformcjs, exportData, importData)
10 changes: 9 additions & 1 deletion packages/require/src/readFileWeb.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@
export const readFileWeb = (path, {base = '', output='text'}={}) => {
const req = new XMLHttpRequest()
req.open('GET', base ? new URL(path, base) : path, 0) // sync

if(output !== 'text'){
// this hack was hard to find, and we can not use fetch because we need sync request
// XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
req.overrideMimeType("text/plain; charset=x-user-defined");
}

req.send()
if (req.status && req.status === 404) {
throw new Error(`file not found ${path}`)
} else if (req.status && req.status !== 200) {
throw new Error(`failed to fetch file ${path} ${req.status} ${req.statusText}`)
}
return req.responseText

return output == 'text' ? req.responseText : req.response
}
10 changes: 8 additions & 2 deletions packages/require/src/require.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const runModule = (typeof self === 'undefined' ? eval : self.eval)(
'(require, exports, module, source)=>eval(source)',
)

export const require = (urlOrSource, transform, readFile, base, root, moduleBase = MODULE_BASE) => {
export const require = (urlOrSource, transform, readFile, base, root, importData = null, moduleBase = MODULE_BASE) => {
let source
let url
let isRelativeFile
Expand All @@ -46,6 +46,12 @@ export const require = (urlOrSource, transform, readFile, base, root, moduleBase
const aliasedUrl = bundleAlias || requireCache.alias[url] || url

const resolved = resolveUrl(aliasedUrl, base, root, moduleBase)
const resolvedStr = resolved.url.toString()
const isJs = resolvedStr.endsWith('.ts') || resolvedStr.endsWith('.js')
if(!isJs && importData){
return importData(resolvedStr, readFile, base, root, moduleBase)
}

isRelativeFile = resolved.isRelativeFile
resolvedUrl = resolved.url
cacheUrl = resolved.url
Expand Down Expand Up @@ -90,7 +96,7 @@ export const require = (urlOrSource, transform, readFile, base, root, moduleBase
// do not transform bundles that are already cjs ( requireCache.bundleAlias.*)
if (transform && !bundleAlias) source = transform(source, resolvedUrl).code
// construct require function relative to resolvedUrl
let requireFunc = newUrl => require(newUrl, transform, readFile, resolvedUrl, root, moduleBase)
let requireFunc = newUrl => require(newUrl, transform, readFile, resolvedUrl, root, importData, moduleBase)
const module = requireModule(url, resolvedUrl, source, requireFunc)
module.local = isRelativeFile
exports = module.exports
Expand Down
9 changes: 5 additions & 4 deletions packages/worker/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ let transformFunc = x => x
let client
let globalBase = location.origin
let userInstances
let importData

export const flatten = arr=>{
const doFlatten = (_in, out)=>{
Expand Down Expand Up @@ -72,11 +73,10 @@ const exportReg = /export.*from/
const runScript = async ({ script, url, base=globalBase, root=base }) => {
if(!script) script = readFileWeb(resolveUrl(url, base, root).url)

console.log('{ script, url, base, root }', { script, url, base, root })
const shouldTransform = url.endsWith('.ts') || script.includes('import') && (importReg.test(script) || exportReg.test(script))
let def = []

const scriptModule = require({url,script}, shouldTransform ? transformFunc : undefined, readFileWeb, base, root)
const scriptModule = require({url,script}, shouldTransform ? transformFunc : undefined, readFileWeb, base, root, importData)
const fromSource = getParameterDefinitionsFromSource(script)
def = combineParameterDefinitions(fromSource, await scriptModule.getParameterDefinitions?.())
main = scriptModule.main
Expand Down Expand Up @@ -108,9 +108,10 @@ export const currentSolids = ()=>solids

const handlers = { runScript, init, runMain, clearTempCache, clearFileCache, exportData }

export const initWorker = (transform, exportData) => {
export const initWorker = (transform, exportData, _importData) => {
if (transform) transformFunc = transform
if(exportData) handlers.exportData = exportData
importData = _importData

client = initMessaging(self, handlers)
}

0 comments on commit c70e968

Please sign in to comment.