Add CadQuery customizer (#547)

* Rough changes to make the CadQuery integration work with the customizer

* Tweak runCQ

* Switched to Anaconda

* Cleaned up code

* Update CadHub after anaconda

Related to #547

* Add final tweaks to CQ customizer

* Separated out customizer.json from params.json

* Changes after discussing CadHub integration

* linting runCQ

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
This commit was merged in pull request #547.
This commit is contained in:
Jeremy Wright
2021-10-14 11:39:03 -04:00
committed by GitHub
parent 3df903ffc6
commit 96ee9c4aa4
6 changed files with 110 additions and 20 deletions

View File

@@ -1,8 +1,9 @@
FROM public.ecr.aws/lts/ubuntu:20.04_stable FROM public.ecr.aws/lts/ubuntu:20.04_stable
ENV PATH="/root/miniconda3/bin:${PATH}"
ARG PATH="/root/miniconda3/bin:${PATH}"
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update -qq RUN apt-get update --fix-missing -qq
RUN apt-get -y -qq install software-properties-common dirmngr apt-transport-https lsb-release ca-certificates xvfb RUN apt-get -y -qq install software-properties-common dirmngr apt-transport-https lsb-release ca-certificates xvfb
RUN apt-get update -qq RUN apt-get update -qq
RUN apt-get install -y wget RUN apt-get install -y wget
@@ -21,7 +22,9 @@ RUN apt-get update && \
cmake \ cmake \
unzip \ unzip \
automake autoconf libtool \ automake autoconf libtool \
libcurl4-openssl-dev libcurl4-openssl-dev \
curl \
git
# Add the lambda emulator for local dev, (see entrypoint.sh for where it's used), # Add the lambda emulator for local dev, (see entrypoint.sh for where it's used),
# I have the file locally (gitignored) to speed up build times (as it downloads everytime), # I have the file locally (gitignored) to speed up build times (as it downloads everytime),
@@ -35,15 +38,23 @@ COPY package*.json /var/task/
RUN npm install RUN npm install
RUN npm install aws-lambda-ric@1.0.0 RUN npm install aws-lambda-ric@1.0.0
# Install Miniconda
RUN wget \
https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \
&& bash Miniconda3-latest-Linux-x86_64.sh -b \
&& rm -f Miniconda3-latest-Linux-x86_64.sh
RUN conda --version
# Install CadQuery
RUN conda install -c cadquery -c conda-forge cadquery=master ocp=7.5.2 python=3.8
RUN conda info
# Get a copy of cq-cli from GitHub
RUN git clone https://github.com/CadQuery/cq-cli.git
# Get the distribution copy of cq-cli # Get the distribution copy of cq-cli
RUN apt-get install -y libglew2.1 RUN apt-get install -y libglew2.1
RUN wget https://github.com/CadQuery/cq-cli/releases/download/v2.2-beta.2/cq-cli-Linux-x86_64.zip
# Comment the entry above out and uncomment the one below to revert to the stable release
# RUN wget https://github.com/CadQuery/cq-cli/releases/download/v2.1.0/cq-cli-Linux-x86_64.zip
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 RUN echo "cadhub-concat-split" > /var/task/cadhub-concat-split
# using built javascript from dist # using built javascript from dist

View File

@@ -1,31 +1,45 @@
import { writeFiles, runCommand } from '../common/utils' import { writeFiles, runCommand } from '../common/utils'
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import { readFile } from 'fs/promises'
export const runCQ = async ({ export const runCQ = async ({
file, file,
settings: { deflection = 0.3 } = {}, settings: { deflection = 0.3, parameters } = {},
} = {}) => { } = {}) => {
const tempFile = await writeFiles( const tempFile = await writeFiles(
[{ file, fileName: 'main.py' }], [
{ file, fileName: 'main.py' },
{
file: JSON.stringify(parameters),
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: '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 fullPath = `/tmp/${tempFile}/output.gz`
const stlPath = `/tmp/${tempFile}/output.stl` const stlPath = `/tmp/${tempFile}/output.stl`
const customizerPath = `/tmp/${tempFile}/customizer.json`
const command = [ const command = [
`cq-cli/cq-cli`, `./cq-cli/cq-cli.py`,
`--codec stl`, `--codec stl`,
`--infile /tmp/${tempFile}/main.py`, `--infile /tmp/${tempFile}/main.py`,
`--outfile ${stlPath}`, `--outfile ${stlPath}`,
`--outputopts "deflection:${deflection};angularDeflection:${deflection};"`, `--outputopts "deflection:${deflection};angularDeflection:${deflection};"`,
`--params /tmp/${tempFile}/params.json`,
`--getparams ${customizerPath}`,
].join(' ') ].join(' ')
console.log('command', command) console.log('command', command)
let consoleMessage = '' let consoleMessage = ''
try { try {
consoleMessage = await runCommand(command, 30000) consoleMessage = await runCommand(command, 30000)
const params = JSON.parse(
await readFile(customizerPath, { encoding: 'ascii' })
)
await writeFiles( await writeFiles(
[ [
{ {
file: JSON.stringify({ file: JSON.stringify({
customizerParams: params,
consoleMessage, consoleMessage,
type: 'stl', type: 'stl',
}), }),
@@ -41,6 +55,6 @@ export const runCQ = async ({
) )
return { consoleMessage, fullPath } return { consoleMessage, fullPath }
} catch (error) { } catch (error) {
return { error: consoleMessage, fullPath } return { error: consoleMessage || error, fullPath }
} }
} }

View File

@@ -3,7 +3,7 @@ FROM public.ecr.aws/lts/ubuntu:20.04_stable
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
## install things needed to run openscad (xvfb is an important one) ## install things needed to run openscad (xvfb is an important one)
RUN apt-get update -qq RUN apt-get update --fix-missing -qq
# double check this below, I'm not sure we need inkscape etc # 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 apt-get -y -qq install software-properties-common dirmngr apt-transport-https lsb-release ca-certificates xvfb imagemagick unzip inkscape
RUN apt-get install -y curl wget RUN apt-get install -y curl wget

View File

@@ -7,15 +7,17 @@ import {
RenderArgs, RenderArgs,
DefaultKernelExport, DefaultKernelExport,
splitGziped, splitGziped,
} from './common' } from '../common'
import { CadQueryToCadhubParams } from './cadQueryParams'
export const render: DefaultKernelExport['render'] = async ({ export const render: DefaultKernelExport['render'] = async ({
code, code,
settings: { quality = 'low' }, settings: { quality = 'low', parameters },
}: RenderArgs) => { }: RenderArgs) => {
const body = JSON.stringify({ const body = JSON.stringify({
settings: { settings: {
deflection: quality === 'low' ? 0.35 : 0.11, deflection: quality === 'low' ? 0.35 : 0.11,
parameters,
}, },
file: code, file: code,
}) })
@@ -43,21 +45,21 @@ export const render: DefaultKernelExport['render'] = async ({
} }
const blob = await response.blob() const blob = await response.blob()
const text = await new Response(blob).text() const text = await new Response(blob).text()
const { consoleMessage } = splitGziped(text) const { consoleMessage, customizerParams, type } = splitGziped(text)
return createHealthyResponse({ return createHealthyResponse({
type: 'geometry', type: 'geometry',
data: await stlToGeometry(window.URL.createObjectURL(blob)), data: await stlToGeometry(window.URL.createObjectURL(blob)),
consoleMessage, consoleMessage,
date: new Date(), date: new Date(),
customizerParams: CadQueryToCadhubParams(customizerParams),
}) })
} catch (e) { } catch (e) {
return createUnhealthyResponse(new Date()) return createUnhealthyResponse(new Date())
} }
} }
const openscad: DefaultKernelExport = { const cadQuery: DefaultKernelExport = {
render, render,
// more functions to come
} }
export default openscad export default cadQuery

View File

@@ -0,0 +1,63 @@
import { CadhubParams } from 'src/components/Customizer/customizerConverter'
interface CadQueryParamsBase {
name: string
initial: number | string | boolean
type?: 'number' | 'string' | 'boolean'
}
interface CadQueryNumberParam extends CadQueryParamsBase {
type: 'number'
initial: number
}
interface CadQueryStringParam extends CadQueryParamsBase {
type: 'string'
initial: string
}
interface CadQueryBooleanParam extends CadQueryParamsBase {
type: 'boolean'
initial: boolean
}
export type CadQueryStringParams =
| CadQueryNumberParam
| CadQueryStringParam
| CadQueryBooleanParam
export function CadQueryToCadhubParams(
input: CadQueryStringParams[]
): CadhubParams[] {
return input
.map((param): CadhubParams => {
const common: { caption: string; name: string } = {
caption: '',
name: param.name,
}
switch (param.type) {
case 'number':
return {
type: 'number',
input: 'default-number',
...common,
initial: param.initial,
}
case 'string':
return {
type: 'string',
input: 'default-string',
...common,
initial: param.initial,
}
case 'boolean':
return {
type: 'boolean',
input: 'default-boolean',
...common,
initial: param.initial,
}
}
})
.filter((a) => a)
}

View File

@@ -5,7 +5,7 @@ import openscad from './openScad/openScadController'
import openScadGuide from 'src/helpers/cadPackages/openScad/userGuide.md' import openScadGuide from 'src/helpers/cadPackages/openScad/userGuide.md'
import openScadInitialCode from 'src/helpers/cadPackages/openScad/initialCode.scad' import openScadInitialCode from 'src/helpers/cadPackages/openScad/initialCode.scad'
import cadquery from './cadQueryController' import cadquery from './cadQuery/cadQueryController'
import cadQueryGuide from 'src/helpers/cadPackages/cadQuery/userGuide.md' import cadQueryGuide from 'src/helpers/cadPackages/cadQuery/userGuide.md'
import cadQueryInitialCode from 'src/helpers/cadPackages/cadQuery/initialCode.py' import cadQueryInitialCode from 'src/helpers/cadPackages/cadQuery/initialCode.py'