diff --git a/app/api/src/docker/cadquery/Dockerfile b/app/api/src/docker/cadquery/Dockerfile
index 861c222..e4465fa 100644
--- a/app/api/src/docker/cadquery/Dockerfile
+++ b/app/api/src/docker/cadquery/Dockerfile
@@ -43,6 +43,7 @@ RUN wget https://github.com/CadQuery/cq-cli/releases/download/v2.2-beta.2/cq-cli
RUN unzip cq-cli-Linux-x86_64.zip
RUN chmod +x cq-cli/cq-cli
+RUN echo "cadhub-concat-split" > /var/task/cadhub-concat-split
COPY cadquery/*.js /var/task/
COPY common/*.js /var/common/
diff --git a/app/api/src/docker/cadquery/cadquery.js b/app/api/src/docker/cadquery/cadquery.js
index bd7f372..c4a4b32 100644
--- a/app/api/src/docker/cadquery/cadquery.js
+++ b/app/api/src/docker/cadquery/cadquery.js
@@ -31,7 +31,6 @@ const stl = async (req, _context, callback) => {
statusCode: 200,
body: JSON.stringify({
url: getObjectUrl(params, s3, tk),
- consoleMessage: previousAsset.consoleMessage,
}),
}
callback(null, response)
diff --git a/app/api/src/docker/cadquery/runCQ.js b/app/api/src/docker/cadquery/runCQ.js
index 8bf1867..65c13d0 100644
--- a/app/api/src/docker/cadquery/runCQ.js
+++ b/app/api/src/docker/cadquery/runCQ.js
@@ -1,24 +1,42 @@
-const { makeFile, runCommand } = require('../common/utils')
+const { writeFiles, runCommand } = require('../common/utils')
const { nanoid } = require('nanoid')
module.exports.runCQ = async ({
file,
settings: { deflection = 0.3 } = {},
} = {}) => {
- const tempFile = await makeFile(file, '.py', nanoid)
- const fullPath = `/tmp/${tempFile}/output.stl`
+ const tempFile = await writeFiles(
+ [{ file, fileName: 'main.py' }],
+ 'a' + nanoid() // 'a' ensure nothing funny happens if it start with a bad character like "-", maybe I should pick a safer id generator :shrug:
+ )
+ const fullPath = `/tmp/${tempFile}/output.gz`
+ const stlPath = `/tmp/${tempFile}/output.stl`
const command = [
`cq-cli/cq-cli`,
`--codec stl`,
`--infile /tmp/${tempFile}/main.py`,
- `--outfile ${fullPath}`,
+ `--outfile ${stlPath}`,
`--outputopts "deflection:${deflection};angularDeflection:${deflection};"`,
- `&& gzip ${fullPath}`,
].join(' ')
console.log('command', command)
try {
const consoleMessage = await runCommand(command, 30000)
+ await writeFiles(
+ [
+ {
+ file: JSON.stringify({
+ consoleMessage,
+ }),
+ fileName: 'metadata.json',
+ },
+ ],
+ tempFile
+ )
+ await runCommand(
+ `cat ${stlPath} /var/task/cadhub-concat-split /tmp/${tempFile}/metadata.json | gzip > ${fullPath}`,
+ 15000
+ )
return { consoleMessage, fullPath }
} catch (error) {
return { error, fullPath }
diff --git a/app/api/src/docker/common/utils.js b/app/api/src/docker/common/utils.js
index 0fab7ea..6ee7a9b 100644
--- a/app/api/src/docker/common/utils.js
+++ b/app/api/src/docker/common/utils.js
@@ -3,24 +3,19 @@ const { promises } = require('fs')
const { writeFile } = promises
const { createHash } = require('crypto')
-const CONSOLE_MESSAGE_KEY = 'console-message-b64'
-function putConsoleMessageInMetadata(consoleMessage) {
- return {
- [CONSOLE_MESSAGE_KEY]: Buffer.from(consoleMessage, 'utf-8').toString(
- 'base64'
- ),
+async function writeFiles(files = [], tempFile) {
+ console.log(`file to write: ${files.length}`)
+
+ try {
+ await runCommand(`mkdir /tmp/${tempFile}`)
+ } catch (e) {
+ //
}
-}
-function getConsoleMessageFromMetadata(metadata) {
- return Buffer.from(metadata[CONSOLE_MESSAGE_KEY], 'base64').toString('utf-8')
-}
-
-async function makeFile(file, extension = '.scad', makeHash) {
- const tempFile = 'a' + makeHash() // 'a' ensure nothing funny happens if it start with a bad character like "-", maybe I should pick a safer id generator :shrug:
- console.log(`file to write: ${file}`)
-
- await runCommand(`mkdir /tmp/${tempFile}`)
- await writeFile(`/tmp/${tempFile}/main${extension}`, file)
+ await Promise.all(
+ files.map(({ file, fileName }) =>
+ writeFile(`/tmp/${tempFile}/${fileName}`, file)
+ )
+ )
return tempFile
}
@@ -54,10 +49,8 @@ function makeHash(script) {
async function checkIfAlreadyExists(params, s3) {
try {
- const objectHead = await s3.headObject(params).promise()
- const consoleMessage = getConsoleMessageFromMetadata(objectHead.Metadata)
- console.log('consoleMessage', consoleMessage)
- return { isAlreadyInBucket: true, consoleMessage }
+ await s3.headObject(params).promise()
+ return { isAlreadyInBucket: true }
} catch (e) {
console.log("couldn't find it", e)
return { isAlreadyInBucket: false }
@@ -117,7 +110,7 @@ async function storeAssetAndReturnUrl({
let buffer
try {
- buffer = await readFile(`${fullPath}.gz`)
+ buffer = await readFile(fullPath)
} catch (e) {
console.log('read file error', e)
const response = {
@@ -136,7 +129,6 @@ async function storeAssetAndReturnUrl({
CacheControl: `max-age=${FiveDays}`, // browser caching to stop downloads of the same part
ContentType: 'text/stl',
ContentEncoding: 'gzip',
- Metadata: putConsoleMessageInMetadata(consoleMessage),
})
.promise()
console.log('stored object', storedRender)
@@ -146,7 +138,6 @@ async function storeAssetAndReturnUrl({
statusCode: 200,
body: JSON.stringify({
url,
- consoleMessage,
}),
}
callback(null, response)
@@ -156,7 +147,7 @@ async function storeAssetAndReturnUrl({
module.exports = {
runCommand,
- makeFile,
+ writeFiles,
makeHash,
checkIfAlreadyExists,
getObjectUrl,
diff --git a/app/api/src/docker/openscad/Dockerfile b/app/api/src/docker/openscad/Dockerfile
index e5580e3..4c7aea7 100644
--- a/app/api/src/docker/openscad/Dockerfile
+++ b/app/api/src/docker/openscad/Dockerfile
@@ -6,10 +6,12 @@ ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update -qq
# double check this below, I'm not sure we need inkscape etc
RUN apt-get -y -qq install software-properties-common dirmngr apt-transport-https lsb-release ca-certificates xvfb imagemagick unzip inkscape
-RUN add-apt-repository ppa:openscad/releases
-RUN apt-get update -qq
-RUN apt-get install -y -qq openscad
RUN apt-get install -y curl wget
+RUN touch /etc/apt/sources.list.d/openscad.list
+RUN echo "deb https://download.opensuse.org/repositories/home:/t-paul/xUbuntu_20.04/ ./" >> /etc/apt/sources.list.d/openscad.list
+RUN wget -qO - https://files.openscad.org/OBS-Repository-Key.pub | apt-key add -
+RUN apt-get update -qq
+RUN apt-get install -y openscad-nightly
# install node14, see comment at the to of node14source_setup.sh
ADD common/node14source_setup.sh /nodesource_setup.sh
@@ -44,7 +46,9 @@ RUN echo "OPENSCADPATH=/var/task/openscad" >>/etc/profile && \
wget -P /var/task/openscad/ https://github.com/Irev-Dev/Round-Anything/archive/refs/tags/1.0.4.zip && \
unzip /var/task/openscad/1.0.4
# Add our own theming (based on DeepOcean with a different "background" and "opencsg-face-back")
-COPY openscad/cadhubtheme.json /usr/share/openscad/color-schemes/render/
+COPY openscad/cadhubtheme.json /usr/share/openscad-nightly/color-schemes/render/
+
+RUN echo "cadhub-concat-split" > /var/task/cadhub-concat-split
COPY openscad/*.js /var/task/
COPY common/*.js /var/common/
diff --git a/app/api/src/docker/openscad/openscad.js b/app/api/src/docker/openscad/openscad.js
index 1f37469..bced701 100644
--- a/app/api/src/docker/openscad/openscad.js
+++ b/app/api/src/docker/openscad/openscad.js
@@ -57,8 +57,6 @@ const preview = async (req, _context, callback) => {
s3,
tk
),
- consoleMessage:
- previousAsset.consoleMessage || previousAssetPng.consoleMessage,
type,
}),
}
@@ -67,7 +65,10 @@ const preview = async (req, _context, callback) => {
}
const { file, settings } = JSON.parse(eventBody)
- const { error, consoleMessage, fullPath } = await runScad({ file, settings })
+ const { error, consoleMessage, fullPath, customizerPath } = await runScad({
+ file,
+ settings,
+ })
await storeAssetAndReturnUrl({
error,
callback,
@@ -100,14 +101,16 @@ const stl = async (req, _context, callback) => {
statusCode: 200,
body: JSON.stringify({
url: getObjectUrl({ ...params }, s3, tk),
- consoleMessage: previousAsset.consoleMessage,
}),
}
callback(null, response)
return
}
- const { file } = JSON.parse(eventBody)
- const { error, consoleMessage, fullPath } = await stlExport({ file })
+ const { file, settings } = JSON.parse(eventBody)
+ const { error, consoleMessage, fullPath, customizerPath } = await stlExport({
+ file,
+ settings,
+ })
await storeAssetAndReturnUrl({
error,
callback,
@@ -121,6 +124,6 @@ const stl = async (req, _context, callback) => {
}
module.exports = {
- stl: middy(stl).use(cors()),
+ stl: middy(loggerWrap(stl)).use(cors()),
preview: middy(loggerWrap(preview)).use(cors()),
}
diff --git a/app/api/src/docker/openscad/runScad.js b/app/api/src/docker/openscad/runScad.js
index 6e69122..ac27deb 100644
--- a/app/api/src/docker/openscad/runScad.js
+++ b/app/api/src/docker/openscad/runScad.js
@@ -1,7 +1,8 @@
-const { makeFile, runCommand } = require('../common/utils')
+const { writeFiles, runCommand } = require('../common/utils')
const { nanoid } = require('nanoid')
+const { readFile } = require('fs/promises')
-const OPENSCAD_COMMON = `xvfb-run --auto-servernum --server-args "-screen 0 1024x768x24" openscad`
+const OPENSCAD_COMMON = `xvfb-run --auto-servernum --server-args "-screen 0 1024x768x24" openscad-nightly`
/** Removes our generated/hash filename with just "main.scad", so that it's a nice message in the IDE */
const cleanOpenScadError = (error) =>
@@ -11,6 +12,7 @@ module.exports.runScad = async ({
file,
settings: {
size: { x = 500, y = 500 } = {},
+ parameters,
camera: {
position = { x: 40, y: 40, z: 40 },
rotation = { x: 55, y: 0, z: 25 },
@@ -18,46 +20,113 @@ module.exports.runScad = async ({
} = {},
} = {}, // TODO add view settings
} = {}) => {
- const tempFile = await makeFile(file, '.scad', nanoid)
+ const tempFile = await writeFiles(
+ [
+ { file, fileName: 'main.scad' },
+ {
+ file: JSON.stringify({
+ parameterSets: { default: parameters },
+ fileFormatVersion: '1',
+ }),
+ fileName: 'params.json',
+ },
+ ],
+ 'a' + nanoid() // 'a' ensure nothing funny happens if it start with a bad character like "-", maybe I should pick a safer id generator :shrug:
+ )
const { x: rx, y: ry, z: rz } = rotation
const { x: px, y: py, z: pz } = position
const cameraArg = `--camera=${px},${py},${pz},${rx},${ry},${rz},${dist}`
- const fullPath = `/tmp/${tempFile}/output.png`
+ const fullPath = `/tmp/${tempFile}/output.gz`
+ const imPath = `/tmp/${tempFile}/output.png`
+ const customizerPath = `/tmp/${tempFile}/customizer.param`
const command = [
OPENSCAD_COMMON,
- `-o ${fullPath}`,
+ `-o ${customizerPath}`,
+ `-o ${imPath}`,
+ `-p /tmp/${tempFile}/params.json -P default`,
cameraArg,
`--imgsize=${x},${y}`,
`--colorscheme CadHub`,
`/tmp/${tempFile}/main.scad`,
- `&& gzip ${fullPath}`,
].join(' ')
console.log('command', command)
try {
const consoleMessage = await runCommand(command, 15000)
- return { consoleMessage, fullPath }
+ const params = JSON.parse(
+ await readFile(customizerPath, { encoding: 'ascii' })
+ ).parameters
+ await writeFiles(
+ [
+ {
+ file: JSON.stringify({
+ customizerParams: params,
+ consoleMessage,
+ }),
+ fileName: 'metadata.json',
+ },
+ ],
+ tempFile
+ )
+ await runCommand(
+ `cat ${imPath} /var/task/cadhub-concat-split /tmp/${tempFile}/metadata.json | gzip > ${fullPath}`,
+ 15000
+ )
+ return { consoleMessage, fullPath, customizerPath }
} catch (dirtyError) {
- const error = cleanOpenScadError(dirtyError)
- return { error }
+ return { error: cleanOpenScadError(dirtyError) }
}
}
-module.exports.stlExport = async ({ file } = {}) => {
- const tempFile = await makeFile(file, '.scad', nanoid)
- const fullPath = `/tmp/${tempFile}/output.stl`
+module.exports.stlExport = async ({ file, settings: { parameters } } = {}) => {
+ const tempFile = await writeFiles(
+ [
+ { file, fileName: 'main.scad' },
+ {
+ file: JSON.stringify({
+ parameterSets: { default: parameters },
+ fileFormatVersion: '1',
+ }),
+ fileName: 'params.json',
+ },
+ ],
+ 'a' + nanoid() // 'a' ensure nothing funny happens if it start with a bad character like "-", maybe I should pick a safer id generator :shrug:
+ )
+ const fullPath = `/tmp/${tempFile}/output.gz`
+ const stlPath = `/tmp/${tempFile}/output.stl`
+ const customizerPath = `/tmp/${tempFile}/customizer.param`
const command = [
OPENSCAD_COMMON,
- `--export-format=binstl`,
- `-o ${fullPath}`,
+ // `--export-format=binstl`,
+ `-o ${customizerPath}`,
+ `-o ${stlPath}`,
+ `-p /tmp/${tempFile}/params.json -P default`,
`/tmp/${tempFile}/main.scad`,
- `&& gzip ${fullPath}`,
].join(' ')
try {
// lambda will time out before this, we might need to look at background jobs if we do git integration stl generation
const consoleMessage = await runCommand(command, 60000)
- return { consoleMessage, fullPath }
+ const params = JSON.parse(
+ await readFile(customizerPath, { encoding: 'ascii' })
+ ).parameters
+ await writeFiles(
+ [
+ {
+ file: JSON.stringify({
+ customizerParams: params,
+ consoleMessage,
+ }),
+ fileName: 'metadata.json',
+ },
+ ],
+ tempFile
+ )
+ await runCommand(
+ `cat ${stlPath} /var/task/cadhub-concat-split /tmp/${tempFile}/metadata.json | gzip > ${fullPath}`,
+ 15000
+ )
+ return { consoleMessage, fullPath, customizerPath }
} catch (error) {
return { error, fullPath }
}
diff --git a/app/web/src/components/Customizer/Customizer.tsx b/app/web/src/components/Customizer/Customizer.tsx
index 4928640..657faa2 100644
--- a/app/web/src/components/Customizer/Customizer.tsx
+++ b/app/web/src/components/Customizer/Customizer.tsx
@@ -8,7 +8,6 @@ import {
CadhubNumberParam,
CadhubStringChoiceParam,
CadhubNumberChoiceParam,
- CadhubChoiceParam,
} from './customizerConverter'
const Customizer = () => {
@@ -82,17 +81,22 @@ const Customizer = () => {
{customizerParams.map((param, index) => {
const otherProps = {
value: currentParameters[param.name],
- onChange: (value) => updateCustomizerParam(param.name, param.type == 'number' ? Number(value) : value),
+ onChange: (value) =>
+ updateCustomizerParam(
+ param.name,
+ param.type == 'number' ? Number(value) : value
+ ),
}
- if(param.input === 'choice-string' || param.input === 'choice-number'){
- return
- // }else if(param.input === 'choice-number'){
- // return
- }else if (param.type === 'string') {
- return
- } else if (param.type === 'number') {
- return
- } else if (param.type === 'boolean') {
+ if (
+ param.input === 'choice-string' ||
+ param.input === 'choice-number'
+ ) {
+ return
+ } else if (param.input === 'default-string') {
+ return
+ } else if (param.input === 'default-number') {
+ return
+ } else if (param.input === 'default-boolean') {
return
}
return
{JSON.stringify(param)}
@@ -180,12 +184,12 @@ function StringParam({
)
}
-function StringChoiceParam({
+function ChoiceParam({
param,
value,
onChange,
}: {
- param: CadhubChoiceParam
+ param: CadhubStringChoiceParam | CadhubNumberChoiceParam
value: any
onChange: Function
}) {
@@ -196,7 +200,11 @@ function StringChoiceParam({
value={value}
onChange={({ target }) => onChange(target?.value)}
>
- {param.options.map(opt=>)}
+ {param.options.map((opt) => (
+
+ ))}
)
diff --git a/app/web/src/components/Customizer/customizerConverter.ts b/app/web/src/components/Customizer/customizerConverter.ts
index 3972248..0b93d1c 100644
--- a/app/web/src/components/Customizer/customizerConverter.ts
+++ b/app/web/src/components/Customizer/customizerConverter.ts
@@ -1,7 +1,12 @@
// CadHub
type CadhubTypeNames = 'number' | 'string' | 'boolean'
-type CadhubInputNames = 'default-number' | 'default-string' | 'default-boolean' | 'choice-string' | 'choice-number'
+type CadhubInputNames =
+ | 'default-number'
+ | 'default-string'
+ | 'default-boolean'
+ | 'choice-string'
+ | 'choice-number'
export interface CadhubStringOption {
name: string
@@ -29,6 +34,7 @@ export interface CadhubStringParam extends CadhubParamBase {
}
export interface CadhubBooleanParam extends CadhubParamBase {
type: 'boolean'
+ input: 'default-boolean'
initial?: boolean
}
export interface CadhubNumberParam extends CadhubParamBase {
@@ -45,13 +51,13 @@ export interface CadhubStringChoiceParam extends CadhubParamBase {
type: 'string'
input: 'choice-string'
initial: string
- options: Array
+ options: Array
}
export interface CadhubNumberChoiceParam extends CadhubParamBase {
type: 'number'
input: 'choice-number'
initial: number
- options: Array
+ options: Array
}
export type CadhubParams =
@@ -60,91 +66,3 @@ export type CadhubParams =
| CadhubNumberParam
| CadhubStringChoiceParam
| CadhubNumberChoiceParam
-
-// OpenSCAD
-const openscadValues = `
-// slider widget for number with max. value
-sliderWithMax =34; // [50]
-
-// slider widget for number in range
-sliderWithRange =34; // [10:100]
-
-//step slider for number
-stepSlider=2; //[0:5:100]
-
-// slider widget for number in range
-sliderCentered =0; // [-10:0.1:10]
-
-// spinbox with step size 1
-Spinbox= 5;
-
-// Text box for string
-String="hello";
-
-// Text box for string with length 8
-String2="length"; //8
-
-//description
-Variable = true;
-`
-
-const openscadConverted: CadhubParams[] = [
- {
- type: 'number',
- name: 'sliderWithMax',
- caption: 'slider widget for number with max. value',
- initial: 34,
- step: 1,
- max: 50,
- },
- {
- type: 'number',
- name: 'sliderWithRange',
- caption: 'slider widget for number in range',
- initial: 34,
- step: 1,
- min: 10,
- max: 100,
- },
- {
- type: 'number',
- name: 'stepSlider',
- caption: 'step slider for number',
- initial: 2,
- step: 5,
- min: 0,
- max: 100,
- },
- {
- type: 'number',
- name: 'sliderCentered',
- caption: 'slider widget for number in range',
- initial: 0,
- step: 0.1,
- min: -10,
- max: 10,
- },
- {
- type: 'number',
- name: 'Spinbox',
- caption: 'spinbox with step size 1',
- initial: 5,
- step: 1,
- },
-
- {
- type: 'string',
- name: 'String',
- caption: 'Text box for string',
- initial: 'hello',
- },
- {
- type: 'string',
- name: 'String2',
- caption: 'Text box for string with length 8',
- initial: 'length',
- maxLength: 8,
- },
-
- { type: 'boolean', name: 'Variable', caption: 'description', initial: true },
-]
diff --git a/app/web/src/components/IdeConsole/IdeConsole.tsx b/app/web/src/components/IdeConsole/IdeConsole.tsx
index 24ea63d..a85ce5e 100644
--- a/app/web/src/components/IdeConsole/IdeConsole.tsx
+++ b/app/web/src/components/IdeConsole/IdeConsole.tsx
@@ -22,7 +22,7 @@ const IdeConsole = () => {
{time?.toLocaleString()}
- {message.split('\n').map((line, index) => {
+ {(message || '').split('\n').map((line, index) => {
return (
{line.startsWith('ECHO:') ? (
diff --git a/app/web/src/helpers/cadPackages/cadQueryController.ts b/app/web/src/helpers/cadPackages/cadQueryController.ts
index b2c4a81..6524ad8 100644
--- a/app/web/src/helpers/cadPackages/cadQueryController.ts
+++ b/app/web/src/helpers/cadPackages/cadQueryController.ts
@@ -6,6 +6,7 @@ import {
timeoutErrorMessage,
RenderArgs,
DefaultKernelExport,
+ splitGziped,
} from './common'
export const render: DefaultKernelExport['render'] = async ({
@@ -41,11 +42,19 @@ export const render: DefaultKernelExport['render'] = async ({
return createUnhealthyResponse(new Date(), timeoutErrorMessage)
}
const data = await response.json()
- const geometry = await stlToGeometry(data.url)
+ const newData = await fetch(data.url).then(async (a) => {
+ const blob = await a.blob()
+ const text = await new Response(blob).text()
+ const { consoleMessage } = splitGziped(text)
+ return {
+ data: await stlToGeometry(window.URL.createObjectURL(blob)),
+ consoleMessage,
+ }
+ })
return createHealthyResponse({
type: 'geometry',
- data: geometry,
- consoleMessage: data.consoleMessage,
+ data: newData.data,
+ consoleMessage: newData.consoleMessage,
date: new Date(),
})
} catch (e) {
diff --git a/app/web/src/helpers/cadPackages/common.ts b/app/web/src/helpers/cadPackages/common.ts
index ca91004..73b76dc 100644
--- a/app/web/src/helpers/cadPackages/common.ts
+++ b/app/web/src/helpers/cadPackages/common.ts
@@ -13,8 +13,8 @@ export const stlToGeometry = (url) =>
export interface RenderArgs {
code: State['code']
- parameters?: RawCustomizerParams
settings: {
+ parameters?: RawCustomizerParams
camera: State['camera']
viewerSize: State['viewerSize']
quality: State['objectData']['quality']
@@ -103,3 +103,16 @@ export type RenderResponse = HealthyResponse | ErrorResponse
export interface DefaultKernelExport {
render: (arg: RenderArgs) => Promise
}
+
+export const splitGziped = (text: string) => {
+ const concatSplitStr = 'cadhub-concat-split'
+ const splitIndex = text.indexOf(concatSplitStr)
+ const json = text.slice(splitIndex + concatSplitStr.length)
+
+ try {
+ return JSON.parse(json)
+ } catch (e) {
+ console.log(json, e)
+ return {}
+ }
+}
diff --git a/app/web/src/helpers/cadPackages/index.ts b/app/web/src/helpers/cadPackages/index.ts
index 568e9b9..90223a0 100644
--- a/app/web/src/helpers/cadPackages/index.ts
+++ b/app/web/src/helpers/cadPackages/index.ts
@@ -1,7 +1,7 @@
import { DefaultKernelExport } from './common'
import type { CadPackage } from 'src/helpers/hooks/useIdeState'
-import openscad from './openScadController'
+import openscad from './openScad/openScadController'
import cadquery from './cadQueryController'
import jscad from './jsCad/jsCadController'
diff --git a/app/web/src/helpers/cadPackages/jsCad/jsCadController.tsx b/app/web/src/helpers/cadPackages/jsCad/jsCadController.tsx
index 56e1458..4f8c2f2 100644
--- a/app/web/src/helpers/cadPackages/jsCad/jsCadController.tsx
+++ b/app/web/src/helpers/cadPackages/jsCad/jsCadController.tsx
@@ -130,7 +130,6 @@ const workerHelper = new WorkerHelper()
export const render: DefaultKernelExport['render'] = async ({
code,
- parameters,
settings,
}: RenderArgs) => {
if (!scriptWorker) {
@@ -169,11 +168,11 @@ export const render: DefaultKernelExport['render'] = async ({
}
})
- workerHelper.resolver()
+ workerHelper.resolver(null)
scriptWorker.postMessage({ action: 'init', baseURI, alias: [] })
}
- return workerHelper.render(code, parameters)
+ return workerHelper.render(code, settings.parameters)
}
const jsCadController: DefaultKernelExport = {
diff --git a/app/web/src/helpers/cadPackages/jsCad/jscadParams.ts b/app/web/src/helpers/cadPackages/jsCad/jscadParams.ts
index b541406..c990902 100644
--- a/app/web/src/helpers/cadPackages/jsCad/jscadParams.ts
+++ b/app/web/src/helpers/cadPackages/jsCad/jscadParams.ts
@@ -1,4 +1,10 @@
-import { CadhubNumberChoiceParam, CadhubNumberOption, CadhubParams, CadhubStringChoiceParam, CadhubStringOption } from 'src/components/Customizer/customizerConverter'
+import {
+ CadhubNumberChoiceParam,
+ CadhubNumberOption,
+ CadhubParams,
+ CadhubStringChoiceParam,
+ CadhubStringOption,
+} from 'src/components/Customizer/customizerConverter'
type JscadTypeNames =
| 'group'
@@ -19,6 +25,7 @@ interface JscadParamBase {
type: JscadTypeNames
caption: string
name: string
+ initial?: number | string | boolean
}
interface JscadGroupParam extends JscadParamBase {
type: 'group'
@@ -81,6 +88,10 @@ type JsCadParams =
export function jsCadToCadhubParams(input: JsCadParams[]): CadhubParams[] {
return input
.map((param): CadhubParams => {
+ const common: { caption: string; name: string } = {
+ caption: param.caption,
+ name: param.name,
+ }
switch (param.type) {
case 'slider':
case 'number':
@@ -88,8 +99,7 @@ export function jsCadToCadhubParams(input: JsCadParams[]): CadhubParams[] {
return {
type: 'number',
input: 'default-number',
- caption: param.caption,
- name: param.name,
+ ...common,
initial: param.initial,
min: param.min,
max: param.max,
@@ -105,8 +115,7 @@ export function jsCadToCadhubParams(input: JsCadParams[]): CadhubParams[] {
return {
type: 'string',
input: 'default-string',
- caption: param.caption,
- name: param.name,
+ ...common,
initial: param.initial,
placeholder:
param.type === 'text' ||
@@ -123,43 +132,38 @@ export function jsCadToCadhubParams(input: JsCadParams[]): CadhubParams[] {
return {
type: 'boolean',
input: 'default-boolean',
- caption: param.caption,
- name: param.name,
+ ...common,
initial: !!param.initial,
}
- case 'choice':
- case 'radio':
- if(typeof param.values[0] === 'number'){
- let options:Array = []
- let captions = param.captions || param.values
- param.values.forEach((value,i)=>{
- options[i] = {name:String(captions[i]), value:Number(value)}
- })
- return {
- type: 'number',
- input: 'choice-number',
- caption: param.caption,
- name: param.name,
- initial: Number(param.initial),
- options
- }
- }else{
- let options:Array = []
- let captions = param.captions || param.values
- param.values.forEach((value,i)=>{
- options[i] = {name:String(captions[i]), value:String(value)}
- })
- return {
- type: 'string',
- input: 'choice-string',
- caption: param.caption,
- name: param.name,
- initial: String(param.initial),
- options
- }
+ case 'choice':
+ case 'radio':
+ if (typeof param.values[0] === 'number') {
+ const options: Array = []
+ const captions = param.captions || param.values
+ param.values.forEach((value, i) => {
+ options[i] = { name: String(captions[i]), value: Number(value) }
+ })
+ return {
+ type: 'number',
+ input: 'choice-number',
+ ...common,
+ initial: Number(param.initial),
+ options,
}
-
-
+ } else {
+ const options: Array = []
+ const captions = param.captions || param.values
+ param.values.forEach((value, i) => {
+ options[i] = { name: String(captions[i]), value: String(value) }
+ })
+ return {
+ type: 'string',
+ input: 'choice-string',
+ ...common,
+ initial: String(param.initial),
+ options,
+ }
+ }
}
})
.filter((a) => a)
diff --git a/app/web/src/helpers/cadPackages/openScadController.ts b/app/web/src/helpers/cadPackages/openScad/openScadController.ts
similarity index 70%
rename from app/web/src/helpers/cadPackages/openScadController.ts
rename to app/web/src/helpers/cadPackages/openScad/openScadController.ts
index 1986d19..56ebc4c 100644
--- a/app/web/src/helpers/cadPackages/openScadController.ts
+++ b/app/web/src/helpers/cadPackages/openScad/openScadController.ts
@@ -5,7 +5,9 @@ import {
createUnhealthyResponse,
timeoutErrorMessage,
RenderArgs,
-} from './common'
+ splitGziped,
+} from '../common'
+import { openScadToCadhubParams } from './openScadParams'
export const render = async ({ code, settings }: RenderArgs) => {
const pixelRatio = window.devicePixelRatio || 1
@@ -17,6 +19,7 @@ export const render = async ({ code, settings }: RenderArgs) => {
const body = JSON.stringify({
settings: {
size,
+ parameters: settings.parameters,
camera: {
// rounding to give our caching a chance to sometimes work
...settings.camera,
@@ -56,15 +59,25 @@ export const render = async ({ code, settings }: RenderArgs) => {
}
const data = await response.json()
const type = data.type !== 'stl' ? 'png' : 'geometry'
- const newData =
- data.type !== 'stl'
- ? fetch(data.url).then((a) => a.blob())
- : stlToGeometry(data.url)
+ const newData = await fetch(data.url).then(async (a) => {
+ const blob = await a.blob()
+ const text = await new Response(blob).text()
+ const { consoleMessage, customizerParams } = splitGziped(text)
+ return {
+ data:
+ data.type !== 'stl'
+ ? blob
+ : await stlToGeometry(window.URL.createObjectURL(blob)),
+ consoleMessage,
+ customizerParams,
+ }
+ })
return createHealthyResponse({
type,
- data: await newData,
- consoleMessage: data.consoleMessage,
+ data: newData.data,
+ consoleMessage: newData.consoleMessage,
date: new Date(),
+ customizerParams: openScadToCadhubParams(newData.customizerParams || []),
})
} catch (e) {
return createUnhealthyResponse(new Date())
@@ -93,12 +106,22 @@ export const stl = async ({ code, settings }: RenderArgs) => {
return createUnhealthyResponse(new Date(), timeoutErrorMessage)
}
const data = await response.json()
- const geometry = await stlToGeometry(data.url)
+ const newData = await fetch(data.url).then(async (a) => {
+ const blob = await a.blob()
+ const text = await new Response(blob).text()
+ const { consoleMessage, customizerParams } = splitGziped(text)
+ return {
+ data: await stlToGeometry(window.URL.createObjectURL(blob)),
+ consoleMessage,
+ customizerParams,
+ }
+ })
return createHealthyResponse({
type: 'geometry',
- data: geometry,
- consoleMessage: data.consoleMessage,
+ data: newData.data,
+ consoleMessage: newData.consoleMessage,
date: new Date(),
+ customizerParams: openScadToCadhubParams(newData.customizerParams || []),
})
} catch (e) {
return createUnhealthyResponse(new Date())
diff --git a/app/web/src/helpers/cadPackages/openScad/openScadParams.ts b/app/web/src/helpers/cadPackages/openScad/openScadParams.ts
new file mode 100644
index 0000000..4720a2a
--- /dev/null
+++ b/app/web/src/helpers/cadPackages/openScad/openScadParams.ts
@@ -0,0 +1,102 @@
+import { CadhubParams } from 'src/components/Customizer/customizerConverter'
+
+interface OpenScadParamsBase {
+ caption: string
+ name: string
+ group: string
+ initial: number | string | boolean | number[]
+ type: 'string' | 'number' | 'boolean'
+}
+
+interface OpenScadNumberParam extends OpenScadParamsBase {
+ type: 'number'
+ initial: number | number[]
+ max?: number
+ min?: number
+ step?: number
+ options?: { name: string; value: number }[]
+}
+interface OpenScadStringParam extends OpenScadParamsBase {
+ type: 'string'
+ initial: string
+ maxLength?: number
+ options?: { name: string; value: string }[]
+}
+interface OpenScadBooleanParam extends OpenScadParamsBase {
+ type: 'boolean'
+ initial: boolean
+}
+
+export type OpenScadParams =
+ | OpenScadNumberParam
+ | OpenScadStringParam
+ | OpenScadBooleanParam
+
+export function openScadToCadhubParams(
+ input: OpenScadParams[]
+): CadhubParams[] {
+ return input
+ .map((param): CadhubParams => {
+ const common: { caption: string; name: string } = {
+ caption: param.caption,
+ name: param.name,
+ }
+ switch (param.type) {
+ case 'boolean':
+ return {
+ type: 'boolean',
+ input: 'default-boolean',
+ ...common,
+ initial: param.initial,
+ }
+ case 'string':
+ if (!Array.isArray(param?.options)) {
+ return {
+ type: 'string',
+ input: 'default-string',
+ ...common,
+ initial: param.initial,
+ maxLength: param.maxLength,
+ }
+ } else {
+ return {
+ type: 'string',
+ input: 'choice-string',
+ ...common,
+ initial: param.initial,
+ options: param.options,
+ }
+ }
+ case 'number':
+ if (
+ !Array.isArray(param?.options) &&
+ !Array.isArray(param?.initial)
+ ) {
+ return {
+ type: 'number',
+ input: 'default-number',
+ ...common,
+ initial: param.initial,
+ min: param.min,
+ max: param.max,
+ step: param.step,
+ }
+ } else if (
+ Array.isArray(param?.options) &&
+ !Array.isArray(param?.initial)
+ ) {
+ return {
+ type: 'number',
+ input: 'choice-number',
+ ...common,
+ initial: param.initial,
+ options: param.options,
+ }
+ } // TODO else vector
+ break
+ default:
+ return
+ }
+ })
+ .filter((a) => a)
+}
diff --git a/app/web/src/helpers/hooks/useIdeState.ts b/app/web/src/helpers/hooks/useIdeState.ts
index 9846bce..f4a3d2b 100644
--- a/app/web/src/helpers/hooks/useIdeState.ts
+++ b/app/web/src/helpers/hooks/useIdeState.ts
@@ -51,13 +51,12 @@ show_object(result)
const jscad = require('@jscad/modeling')
// https://openjscad.xyz/docs/module-modeling_primitives.html
-const { circle, rectangle, cube, cuboid, sphere, cylinder } = jscad.primitives
+const { cuboid, cylinder } = jscad.primitives
-const { rotate, scale, translate } = jscad.transforms
+const { rotate, translate } = jscad.transforms
const { degToRad } = jscad.utils // because jscad uses radians for rotations
-const { colorize } = jscad.colors
// https://openjscad.xyz/docs/module-modeling_booleans.html
-const { union, intersect, subtract } = jscad.booleans
+const { subtract } = jscad.booleans
function main({//@jscad-params
// Box example
@@ -66,6 +65,7 @@ function main({//@jscad-params
height=10, // Height
hole=3,// Hole for cables diameter (0=no hole)
wall=1, // wall {min:0.5, step:0.5}
+ flip=0, // print orientation {type: 'choice', values: [0, 90, 180]}
}){
let wallOffset = wall * 2
@@ -78,7 +78,7 @@ function main({//@jscad-params
translate([width/2-wall/2], rotate([0, degToRad(90), 0 ], cylinder({radius:hole/2, height:wall})))
)
}
- return rotate([0,0, degToRad(90)], model)
+ return rotate([degToRad(flip), 0, degToRad(90)], model)
}
module.exports = {main}
@@ -281,8 +281,8 @@ export const requestRender = ({
: cadPackages[state.ideType].render
return renderFn({
code,
- parameters,
settings: {
+ parameters,
camera,
viewerSize,
quality,