Init multiple types of cadPackages

This commit is contained in:
Kurt Hutten
2021-04-26 07:48:52 +10:00
parent 4ebf5921e2
commit 76a570b0c3
11 changed files with 159 additions and 84 deletions

View File

@@ -1,6 +1,7 @@
const express = require('express')
var cors = require('cors')
const axios = require('axios')
const { restart } = require('nodemon')
const app = express()
const port = 8080
app.use(express.json())
@@ -10,19 +11,29 @@ const invocationURL = (port) =>
`http://localhost:${port}/2015-03-31/functions/function/invocations`
app.post('/openscad/preview', async (req, res) => {
const { data } = await axios.post(invocationURL(5052), {
body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
})
res.status(data.statusCode)
res.send(data.body)
try {
const { data } = await axios.post(invocationURL(5052), {
body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
})
res.status(data.statusCode)
res.send(data.body)
} catch (e) {
res.status(500)
res.send()
}
})
app.post('/cadquery/stl', async (req, res) => {
console.log('making post request to 5060')
const { data } = await axios.post(invocationURL(5060), {
body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
})
res.status(data.statusCode)
res.send(data.body)
try {
const { data } = await axios.post(invocationURL(5060), {
body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
})
res.status(data.statusCode)
res.send(data.body)
} catch (e) {
res.status(500)
res.send()
}
})
app.listen(port, () => {

View File

@@ -13,6 +13,7 @@
]
},
"dependencies": {
"@headlessui/react": "^1.0.0",
"@material-ui/core": "^4.11.0",
"@monaco-editor/react": "^4.0.11",
"@redwoodjs/auth": "^0.30.1",

View File

@@ -35,7 +35,7 @@ const Routes = () => {
)
return (
<Router>
<Route path="/dev-ide" page={DevIdePage} name="devIde" />
<Route path="/dev-ide/{cadPackage}" page={DevIdePage} name="devIde" />
<Route path="/policies/privacy-policy" page={PrivacyPolicyPage} name="privacyPolicy" />
<Route path="/policies/code-of-conduct" page={CodeOfConductPage} name="codeOfConduct" />
<Route path="/account-recovery/update-password" page={UpdatePasswordPage} name="updatePassword" />

View File

@@ -12,25 +12,6 @@ const IdeEditor = () => {
openScad: 'cpp',
}
const scriptKey = 'encoded_script'
useEffect(() => {
// load code from hash if it's there
let hash
if (isBrowser) {
hash = window.location.hash
}
const [key, scriptBase64] = hash.slice(1).split('=')
if (key === scriptKey) {
const script = atob(scriptBase64)
thunkDispatch({ type: 'updateCode', payload: script })
}
}, [])
useEffect(() => {
if (isBrowser) {
window.location.hash = ''
}
}, [state.code])
function handleCodeChange(value, _event) {
thunkDispatch({ type: 'updateCode', payload: value })
}
@@ -61,6 +42,7 @@ const IdeEditor = () => {
<Suspense fallback={<div>. . . loading</div>}>
<Editor
defaultValue={state.code}
value={state.code}
// TODO #247 cpp seems better than js for the time being
defaultLanguage={ideTypeToLanguageMap[state.ideType] || 'cpp'}
language={ideTypeToLanguageMap[state.ideType] || 'cpp'}

View File

@@ -1,4 +1,4 @@
import { createContext } from 'react'
import { createContext, useEffect } from 'react'
import IdeContainer from 'src/components/IdeContainer'
import { isBrowser } from '@redwoodjs/prerender/browserUtils'
import { useIdeState, codeStorageKey } from 'src/helpers/hooks/useIdeState'
@@ -6,11 +6,27 @@ import { copyTextToClipboard } from 'src/helpers/clipboard'
import { requestRender } from 'src/helpers/hooks/useIdeState'
export const IdeContext = createContext()
const IdeToolbarNew = () => {
const IdeToolbarNew = ({ cadPackage }) => {
const [state, thunkDispatch] = useIdeState()
function setIdeType(ide) {
thunkDispatch({ type: 'setIdeType', payload: { message: ide } })
}
const scriptKey = 'encoded_script'
useEffect(() => {
thunkDispatch({
type: 'initIde',
payload: { cadPackage },
})
// load code from hash if it's there
let hash
if (isBrowser) {
hash = window.location.hash
}
const [key, scriptBase64] = hash.slice(1).split('=')
if (key === scriptKey) {
const script = atob(scriptBase64)
thunkDispatch({ type: 'updateCode', payload: script })
}
window.location.hash = ''
setTimeout(() => handleRender()) // definitely a little hacky, timeout with no delay is just to push it into the next event loop.
}, [cadPackage])
function handleRender() {
thunkDispatch((dispatch, getState) => {
const state = getState()
@@ -37,14 +53,6 @@ const IdeToolbarNew = () => {
<IdeContext.Provider value={{ state, thunkDispatch: thunkDispatch }}>
<div className="h-full flex flex-col">
<nav className="flex">
<button
onClick={() =>
setIdeType(state.ideType === 'openScad' ? 'cadQuery' : 'openScad')
}
className="p-2 br-2 border-2 m-2 bg-blue-200"
>
Switch to {state.ideType === 'openScad' ? 'CadQuery' : 'OpenSCAD'}
</button>
<button onClick={handleRender} className="p-2 br-2 border-2 m-2">
Render
</button>

View File

@@ -0,0 +1,48 @@
import { Link, routes } from '@redwoodjs/router'
import Svg from 'src/components/Svg/Svg'
import { Popover } from '@headlessui/react'
const NavPlusButton: React.FC = () => {
return (
<Popover className="relative outline-none w-full h-full">
<Popover.Button className="h-full w-full outline-none">
<Svg name="plus" className="text-indigo-300" />
</Popover.Button>
<Popover.Panel className="absolute z-10">
<ul className="bg-gray-200 mt-4 rounded shadow-md overflow-hidden">
{[
{
name: 'OpenSCAD',
sub: 'beta',
ideType: 'openScad',
},
{ name: 'CadQuery', sub: 'beta', ideType: 'cadQuery' },
{
name: 'CascadeStudio',
sub: 'soon to be deprecated',
},
].map(({ name, sub, ideType }) => (
<li
key={name}
className="px-4 py-2 hover:bg-gray-400 text-gray-800"
>
<Link
to={
name === 'CascadeStudio'
? routes.draftPart()
: routes.devIde({ cadPackage: ideType })
}
>
<div>{name}</div>
<div className="text-xs text-gray-600 font-light">{sub}</div>
</Link>
</li>
))}
</ul>
</Popover.Panel>
</Popover>
)
}
export default NavPlusButton

View File

@@ -13,6 +13,9 @@ export const render = async ({ code, settings }) => {
},
file: code,
})
if (!settings.camera.position) {
return
}
try {
const response = await fetch(lambdaBaseURL + '/openscad/preview', {
method: 'POST',

View File

@@ -8,7 +8,8 @@ function withThunk(dispatch, getState) {
: dispatch(actionOrThunk)
}
const donutInitCode = `
const initCodeMap = {
openScad: `
color(c="DarkGoldenrod")rotate_extrude()translate([20,0])circle(d=30);
donut();
module donut() {
@@ -21,16 +22,31 @@ module stick(basewid, angl){
sphere(7);
translate([0,0,10])sphere(9);
}
}`
}`,
cadQuery: `import cadquery as cq
from cadquery import exporters
diam = 5.0
result = (cq.Workplane().circle(diam).extrude(20.0)
.faces(">Z").workplane(invert=True).circle(1.05).cutBlind(8.0)
.faces("<Z").workplane(invert=True).circle(0.8).cutBlind(12.0)
.edges("%CIRCLE").chamfer(0.15))
# exporters.export(coupler, "/home/jwright/Downloads/coupler.stl", exporters.ExportTypes.STL)
show_object(result)
`,
}
export const codeStorageKey = 'Last-openscad-code'
let mutableState = null
export const useIdeState = () => {
const code = localStorage.getItem(codeStorageKey) || donutInitCode
const code = localStorage.getItem(codeStorageKey) || initCodeMap.openscad
const initialState = {
ideType: 'cadQuery',
consoleMessages: [{ type: 'message', message: 'Initialising OpenSCAD' }],
ideType: 'INIT',
consoleMessages: [{ type: 'message', message: 'Initialising' }],
code,
objectData: {
type: 'stl',
@@ -52,6 +68,12 @@ export const useIdeState = () => {
}
const reducer = (state, { type, payload }) => {
switch (type) {
case 'initIde':
return {
...state,
code: initCodeMap[payload.cadPackage] || initCodeMap.openscad,
ideType: payload.cadPackage,
}
case 'updateCode':
return { ...state, code: payload }
case 'healthyRender':
@@ -74,11 +96,6 @@ export const useIdeState = () => {
: payload.message,
isLoading: false,
}
case 'setIdeType':
return {
...state,
ideType: payload.message,
}
case 'setLayout':
return {
...state,
@@ -122,26 +139,28 @@ export const requestRender = ({
camera,
viewerSize,
}) => {
cadPackages[state.ideType]
.render({
code,
settings: {
camera,
viewerSize,
},
})
.then(({ objectData, message, status }) => {
if (status === 'error') {
dispatch({
type: 'errorRender',
payload: { message },
})
} else {
dispatch({
type: 'healthyRender',
payload: { objectData, message },
})
}
})
.catch(() => dispatch({ type: 'resetLoading' })) // TODO should probably display something to the user here
state.ideType !== 'INIT' &&
!state.isLoading &&
cadPackages[state.ideType]
.render({
code,
settings: {
camera,
viewerSize,
},
})
.then(({ objectData, message, status }) => {
if (status === 'error') {
dispatch({
type: 'errorRender',
payload: { message },
})
} else {
dispatch({
type: 'healthyRender',
payload: { objectData, message, lastRunCode: code },
})
}
})
.catch(() => dispatch({ type: 'resetLoading' })) // TODO should probably display something to the user here
}

View File

@@ -8,6 +8,7 @@ import { getActiveClasses } from 'get-active-classes'
import Footer from 'src/components/Footer'
import { useLocation } from '@redwoodjs/router'
import LoginModal from 'src/components/LoginModal'
import NavPlusButton from 'src/components/NavPlusButton'
import ReactGA from 'react-ga'
import { isBrowser } from '@redwoodjs/prerender/browserUtils'
@@ -132,9 +133,7 @@ const MainLayout = ({ children, shouldRemoveFooterInIde }) => {
'mr-8 h-10 w-10 rounded-full border-2 border-indigo-300 flex items-center justify-center'
)}
>
<Link className="h-full w-full" to={routes.draftPart()}>
<Svg name="plus" className="text-indigo-300 w-full h-full" />
</Link>
<NavPlusButton />
</li>
{isAuthenticated ? (
<li

View File

@@ -3,7 +3,7 @@ import Seo from 'src/components/Seo/Seo'
import IdeToolbar from 'src/components/IdeToolbarNew'
import OutBound from 'src/components/OutBound'
const DevIdePage = () => {
const DevIdePage = ({ cadPackage }) => {
return (
<div className="h-screen flex flex-col">
<MainLayout shouldRemoveFooterInIde>
@@ -12,10 +12,9 @@ const DevIdePage = () => {
description="new ide in development"
lang="en-US"
/>
<div className="py-4 bg-pink-200">
<div className="mx-auto max-w-6xl">
Woah, woah. You shouldn't be here! We're still working on this.
Since you've seen it now, have a look what{' '}
<div className="py-2 bg-pink-200">
<div className="mx-auto max-w-3xl">
We're still working on this. Since you're here, have a look what{' '}
<OutBound
className="text-pink-700"
to="https://github.com/Irev-Dev/cadhub/discussions/212"
@@ -27,7 +26,7 @@ const DevIdePage = () => {
</div>
</MainLayout>
<div className="flex-auto">
<IdeToolbar />
<IdeToolbar cadPackage={cadPackage} />
</div>
</div>
)

View File

@@ -1404,6 +1404,11 @@
resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-2.0.0.tgz#5bb2193eb685c0007540ca61d166d4e1edaf918d"
integrity sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==
"@headlessui/react@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.0.0.tgz#661b50ebfd25041abb45d8eedd85e7559056bcaf"
integrity sha512-mjqRJrgkbcHQBfAHnqH0yRxO/y/22jYrdltpE7WkurafREKZ+pj5bPBwYHMt935Sdz/n16yRcVmsSCqDFHee9A==
"@icons/material@^0.2.4":
version "0.2.4"
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"