From 96ee9c4aa417f74dd32ee4419d27e267a1dccc67 Mon Sep 17 00:00:00 2001 From: Jeremy Wright Date: Thu, 14 Oct 2021 11:39:03 -0400 Subject: [PATCH] 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 --- app/api/src/docker/cadquery/Dockerfile | 27 +++++--- app/api/src/docker/cadquery/runCQ.ts | 22 +++++-- app/api/src/docker/openscad/Dockerfile | 2 +- .../{ => cadQuery}/cadQueryController.ts | 14 +++-- .../cadPackages/cadQuery/cadQueryParams.ts | 63 +++++++++++++++++++ app/web/src/helpers/cadPackages/index.ts | 2 +- 6 files changed, 110 insertions(+), 20 deletions(-) rename app/web/src/helpers/cadPackages/{ => cadQuery}/cadQueryController.ts (78%) create mode 100644 app/web/src/helpers/cadPackages/cadQuery/cadQueryParams.ts diff --git a/app/api/src/docker/cadquery/Dockerfile b/app/api/src/docker/cadquery/Dockerfile index 0589092d..e529ccf0 100644 --- a/app/api/src/docker/cadquery/Dockerfile +++ b/app/api/src/docker/cadquery/Dockerfile @@ -1,8 +1,9 @@ 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 -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 update -qq RUN apt-get install -y wget @@ -21,7 +22,9 @@ RUN apt-get update && \ cmake \ unzip \ 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), # 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 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 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 # using built javascript from dist diff --git a/app/api/src/docker/cadquery/runCQ.ts b/app/api/src/docker/cadquery/runCQ.ts index afcb916f..64576cd3 100644 --- a/app/api/src/docker/cadquery/runCQ.ts +++ b/app/api/src/docker/cadquery/runCQ.ts @@ -1,31 +1,45 @@ import { writeFiles, runCommand } from '../common/utils' import { nanoid } from 'nanoid' +import { readFile } from 'fs/promises' export const runCQ = async ({ file, - settings: { deflection = 0.3 } = {}, + settings: { deflection = 0.3, parameters } = {}, } = {}) => { 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: ) const fullPath = `/tmp/${tempFile}/output.gz` const stlPath = `/tmp/${tempFile}/output.stl` + const customizerPath = `/tmp/${tempFile}/customizer.json` const command = [ - `cq-cli/cq-cli`, + `./cq-cli/cq-cli.py`, `--codec stl`, `--infile /tmp/${tempFile}/main.py`, `--outfile ${stlPath}`, `--outputopts "deflection:${deflection};angularDeflection:${deflection};"`, + `--params /tmp/${tempFile}/params.json`, + `--getparams ${customizerPath}`, ].join(' ') console.log('command', command) let consoleMessage = '' try { consoleMessage = await runCommand(command, 30000) + const params = JSON.parse( + await readFile(customizerPath, { encoding: 'ascii' }) + ) await writeFiles( [ { file: JSON.stringify({ + customizerParams: params, consoleMessage, type: 'stl', }), @@ -41,6 +55,6 @@ export const runCQ = async ({ ) return { consoleMessage, fullPath } } catch (error) { - return { error: consoleMessage, fullPath } + return { error: consoleMessage || error, fullPath } } } diff --git a/app/api/src/docker/openscad/Dockerfile b/app/api/src/docker/openscad/Dockerfile index 001730d5..d17153ab 100644 --- a/app/api/src/docker/openscad/Dockerfile +++ b/app/api/src/docker/openscad/Dockerfile @@ -3,7 +3,7 @@ FROM public.ecr.aws/lts/ubuntu:20.04_stable ARG DEBIAN_FRONTEND=noninteractive ## 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 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 diff --git a/app/web/src/helpers/cadPackages/cadQueryController.ts b/app/web/src/helpers/cadPackages/cadQuery/cadQueryController.ts similarity index 78% rename from app/web/src/helpers/cadPackages/cadQueryController.ts rename to app/web/src/helpers/cadPackages/cadQuery/cadQueryController.ts index 5f77b933..21d96593 100644 --- a/app/web/src/helpers/cadPackages/cadQueryController.ts +++ b/app/web/src/helpers/cadPackages/cadQuery/cadQueryController.ts @@ -7,15 +7,17 @@ import { RenderArgs, DefaultKernelExport, splitGziped, -} from './common' +} from '../common' +import { CadQueryToCadhubParams } from './cadQueryParams' export const render: DefaultKernelExport['render'] = async ({ code, - settings: { quality = 'low' }, + settings: { quality = 'low', parameters }, }: RenderArgs) => { const body = JSON.stringify({ settings: { deflection: quality === 'low' ? 0.35 : 0.11, + parameters, }, file: code, }) @@ -43,21 +45,21 @@ export const render: DefaultKernelExport['render'] = async ({ } const blob = await response.blob() const text = await new Response(blob).text() - const { consoleMessage } = splitGziped(text) + const { consoleMessage, customizerParams, type } = splitGziped(text) return createHealthyResponse({ type: 'geometry', data: await stlToGeometry(window.URL.createObjectURL(blob)), consoleMessage, date: new Date(), + customizerParams: CadQueryToCadhubParams(customizerParams), }) } catch (e) { return createUnhealthyResponse(new Date()) } } -const openscad: DefaultKernelExport = { +const cadQuery: DefaultKernelExport = { render, - // more functions to come } -export default openscad +export default cadQuery diff --git a/app/web/src/helpers/cadPackages/cadQuery/cadQueryParams.ts b/app/web/src/helpers/cadPackages/cadQuery/cadQueryParams.ts new file mode 100644 index 00000000..4df9492d --- /dev/null +++ b/app/web/src/helpers/cadPackages/cadQuery/cadQueryParams.ts @@ -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) +} diff --git a/app/web/src/helpers/cadPackages/index.ts b/app/web/src/helpers/cadPackages/index.ts index f1d3053f..ea420c6a 100644 --- a/app/web/src/helpers/cadPackages/index.ts +++ b/app/web/src/helpers/cadPackages/index.ts @@ -5,7 +5,7 @@ import openscad from './openScad/openScadController' import openScadGuide from 'src/helpers/cadPackages/openScad/userGuide.md' 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 cadQueryInitialCode from 'src/helpers/cadPackages/cadQuery/initialCode.py'