CadQuery MVP integration #281

Merged
Irev-Dev merged 15 commits from kurt/274 into main 2021-04-27 11:53:52 +02:00
9 changed files with 295 additions and 162 deletions
Showing only changes of commit 2153e5b1bf - Show all commits

View File

@@ -1,6 +1,7 @@
import { useContext, useRef, useEffect } from 'react' import { useContext, useRef, useEffect } from 'react'
import { Mosaic, MosaicWindow } from 'react-mosaic-component' import { Mosaic, MosaicWindow } from 'react-mosaic-component'
import { IdeContext } from 'src/components/IdeToolbarNew' import { IdeContext } from 'src/components/IdeToolbarNew'
import { requestRender } from 'src/helpers/hooks/useIdeState'
import IdeEditor from 'src/components/IdeEditor' import IdeEditor from 'src/components/IdeEditor'
import IdeViewer from 'src/components/IdeViewer' import IdeViewer from 'src/components/IdeViewer'
import IdeConsole from 'src/components/IdeConsole' import IdeConsole from 'src/components/IdeConsole'
@@ -13,7 +14,7 @@ const ELEMENT_MAP = {
} }
const IdeContainer = () => { const IdeContainer = () => {
const { state, dispatch } = useContext(IdeContext) const { state, thunkDispatch } = useContext(IdeContext)
const viewerDOM = useRef(null) const viewerDOM = useRef(null)
const debounceTimeoutId = useRef const debounceTimeoutId = useRef
@@ -22,12 +23,22 @@ const IdeContainer = () => {
function handleViewerSizeUpdate() { function handleViewerSizeUpdate() {
if (viewerDOM !== null && viewerDOM.current) { if (viewerDOM !== null && viewerDOM.current) {
const { width, height } = viewerDOM.current.getBoundingClientRect() const { width, height } = viewerDOM.current.getBoundingClientRect()
dispatch({ thunkDispatch({
type: 'render', type: 'updateViewerSize',
payload: { payload: { viewerSize: { width, height } },
code: state.code, })
viewerSize: { width, height }, thunkDispatch((dispatch, getState) => {
}, const state = getState()
if (state.ideType === 'openScad') {
dispatch({ type: 'setLoading' })
requestRender({
state,
dispatch,
code: state.code,
viewerSize: { width, height },
camera: state.camera,
})
}
}) })
} }
} }
@@ -49,20 +60,27 @@ const IdeContainer = () => {
return ( return (
<div id="cadhub-ide" className="flex-auto h-full"> <div id="cadhub-ide" className="flex-auto h-full">
<Mosaic <Mosaic
renderTile={(id, path) => ( renderTile={(id, path) => {
<MosaicWindow path={path} title={id} className={id.toLowerCase()}> const title = id === 'Editor' ? `${id} (${state.ideType})` : id
{id === 'Viewer' ? ( return (
<div id="view-wrapper" className="h-full" ref={viewerDOM}> <MosaicWindow
{ELEMENT_MAP[id]} path={path}
</div> title={title}
) : ( className={id.toLowerCase()}
ELEMENT_MAP[id] >
)} {id === 'Viewer' ? (
</MosaicWindow> <div id="view-wrapper" className="h-full" ref={viewerDOM}>
)} {ELEMENT_MAP[id]}
</div>
) : (
ELEMENT_MAP[id]
)}
</MosaicWindow>
)
}}
value={state.layout} value={state.layout}
onChange={(newLayout) => onChange={(newLayout) =>
dispatch({ type: 'setLayout', payload: { message: newLayout } }) thunkDispatch({ type: 'setLayout', payload: { message: newLayout } })
} }
onRelease={handleViewerSizeUpdate} onRelease={handleViewerSizeUpdate}
/> />

View File

@@ -2,10 +2,15 @@ import { useContext, useEffect, Suspense, lazy } from 'react'
import { isBrowser } from '@redwoodjs/prerender/browserUtils' import { isBrowser } from '@redwoodjs/prerender/browserUtils'
import { IdeContext } from 'src/components/IdeToolbarNew' import { IdeContext } from 'src/components/IdeToolbarNew'
import { codeStorageKey } from 'src/helpers/hooks/useIdeState' import { codeStorageKey } from 'src/helpers/hooks/useIdeState'
import { requestRender } from 'src/helpers/hooks/useIdeState'
const Editor = lazy(() => import('@monaco-editor/react')) const Editor = lazy(() => import('@monaco-editor/react'))
const IdeEditor = () => { const IdeEditor = () => {
const { state, dispatch } = useContext(IdeContext) const { state, thunkDispatch } = useContext(IdeContext)
const ideTypeToLanguageMap = {
cadQuery: 'python',
openScad: 'cpp',
}
const scriptKey = 'encoded_script' const scriptKey = 'encoded_script'
useEffect(() => { useEffect(() => {
@@ -17,7 +22,7 @@ const IdeEditor = () => {
const [key, scriptBase64] = hash.slice(1).split('=') const [key, scriptBase64] = hash.slice(1).split('=')
if (key === scriptKey) { if (key === scriptKey) {
const script = atob(scriptBase64) const script = atob(scriptBase64)
dispatch({ type: 'updateCode', payload: script }) thunkDispatch({ type: 'updateCode', payload: script })
} }
}, []) }, [])
useEffect(() => { useEffect(() => {
@@ -27,25 +32,38 @@ const IdeEditor = () => {
}, [state.code]) }, [state.code])
function handleCodeChange(value, _event) { function handleCodeChange(value, _event) {
dispatch({ type: 'updateCode', payload: value }) thunkDispatch({ type: 'updateCode', payload: value })
} }
function handleSaveHotkey(event) { function handleSaveHotkey(event) {
//ctrl|meta + s is very intuitive for most devs //ctrl|meta + s is very intuitive for most devs
const { key, ctrlKey, metaKey } = event const { key, ctrlKey, metaKey } = event
if (key === 's' && (ctrlKey || metaKey)) { if (key === 's' && (ctrlKey || metaKey)) {
event.preventDefault() event.preventDefault()
dispatch({ type: 'render', payload: { code: state.code } }) thunkDispatch((dispatch, getState) => {
const state = getState()
dispatch({ type: 'setLoading' })
requestRender({
state,
dispatch,
code: state.code,
franknoirot commented 2021-04-27 07:13:41 +02:00 (Migrated from github.com)
Review

I had missed you added this, what a great addition! And for it to be agnostic of the CAD package; this is the kind of unifying stuff that's gonna make it so nice to switch between packages.

I had missed you added this, what a great addition! And for it to be agnostic of the CAD package; this is the kind of unifying stuff that's gonna make it so nice to switch between packages.
viewerSize: state.viewerSize,
camera: state.camera,
})
})
localStorage.setItem(codeStorageKey, state.code) localStorage.setItem(codeStorageKey, state.code)
} }
} }
return ( return (
<div className="h-full" onKeyDown={handleSaveHotkey}> <div // eslint-disable-line jsx-a11y/no-static-element-interactions
className="h-full"
onKeyDown={handleSaveHotkey}
>
<Suspense fallback={<div>. . . loading</div>}> <Suspense fallback={<div>. . . loading</div>}>
<Editor <Editor
defaultValue={state.code} defaultValue={state.code}
// TODO #247 cpp seems better than js for the time being // TODO #247 cpp seems better than js for the time being
defaultLanguage="cpp" defaultLanguage={ideTypeToLanguageMap[state.ideType] || 'cpp'}
language={ideTypeToLanguageMap[state.ideType] || 'cpp'}
onChange={handleCodeChange} onChange={handleCodeChange}
/> />
</Suspense> </Suspense>
Irev-Dev commented 2021-04-26 10:18:06 +02:00 (Migrated from github.com)
Review

I wanted this loading message to be light text on dark background to match roughly the theme of the editor, but I there must be very specific styles that force it to be white, I didn't bother digging into it too much.

I wanted this loading message to be light text on dark background to match roughly the theme of the editor, but I there must be very specific styles that force it to be white, I didn't bother digging into it too much.
franknoirot commented 2021-04-27 07:12:39 +02:00 (Migrated from github.com)
Review

Is there somewhere we can gather up these low-priority frontend things for me to go through and clean up for you? I think that might be a good way for me to be useful.

Is there somewhere we can gather up these low-priority frontend things for me to go through and clean up for you? I think that might be a good way for me to be useful.
Irev-Dev commented 2021-04-27 10:49:11 +02:00 (Migrated from github.com)
Review

Not real sure, might be worth having a chat about where to put what. my intuition says there's no problem with lots of little issues for things you want to get to.

Not real sure, might be worth having a chat about where to put what. my intuition says there's no problem with lots of little issues for things you want to get to.

View File

@@ -3,15 +3,26 @@ import IdeContainer from 'src/components/IdeContainer'
import { isBrowser } from '@redwoodjs/prerender/browserUtils' import { isBrowser } from '@redwoodjs/prerender/browserUtils'
import { useIdeState, codeStorageKey } from 'src/helpers/hooks/useIdeState' import { useIdeState, codeStorageKey } from 'src/helpers/hooks/useIdeState'
import { copyTextToClipboard } from 'src/helpers/clipboard' import { copyTextToClipboard } from 'src/helpers/clipboard'
import { requestRender } from 'src/helpers/hooks/useIdeState'
export const IdeContext = createContext() export const IdeContext = createContext()
const IdeToolbarNew = () => { const IdeToolbarNew = () => {
const [state, dispatch] = useIdeState() const [state, thunkDispatch] = useIdeState()
function setIdeType(ide) { function setIdeType(ide) {
dispatch({ type: 'setIdeType', payload: { message: ide } }) thunkDispatch({ type: 'setIdeType', payload: { message: ide } })
} }
function handleRender() { function handleRender() {
dispatch({ type: 'render', payload: { code: state.code } }) thunkDispatch((dispatch, getState) => {
const state = getState()
dispatch({ type: 'setLoading' })
requestRender({
state,
dispatch,
code: state.code,
viewerSize: state.viewerSize,
camera: state.camera,
})
})
localStorage.setItem(codeStorageKey, state.code) localStorage.setItem(codeStorageKey, state.code)
} }
function handleMakeLink() { function handleMakeLink() {
@@ -23,21 +34,17 @@ const IdeToolbarNew = () => {
} }
return ( return (
<IdeContext.Provider value={{ state, dispatch }}> <IdeContext.Provider value={{ state, thunkDispatch: thunkDispatch }}>
<div className="h-full flex flex-col"> <div className="h-full flex flex-col">
<nav className="flex"> <nav className="flex">
{/* <button <button
onClick={() => setIdeType('openCascade')} onClick={() =>
setIdeType(state.ideType === 'openScad' ? 'cadQuery' : 'openScad')
}
className="p-2 br-2 border-2 m-2 bg-blue-200" className="p-2 br-2 border-2 m-2 bg-blue-200"
> >
Switch to OpenCascade Switch to {state.ideType === 'openScad' ? 'CadQuery' : 'OpenSCAD'}
</button> </button>
<button
onClick={() => setIdeType('openScad')}
className="p-2 br-2 border-2 m-2 bg-indigo-200"
>
Switch to OpenSCAD
</button> */}
<button onClick={handleRender} className="p-2 br-2 border-2 m-2"> <button onClick={handleRender} className="p-2 br-2 border-2 m-2">
Render Render
</button> </button>

View File

@@ -1,11 +1,41 @@
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
import { IdeContext } from 'src/components/IdeToolbarNew' import { IdeContext } from 'src/components/IdeToolbarNew'
import { useRef, useState, useEffect, useContext } from 'react' import { useRef, useState, useEffect, useContext } from 'react'
import { Canvas, extend, useFrame, useThree } from 'react-three-fiber' import {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Canvas,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
extend,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
useFrame,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
useThree,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
useUpdate,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
} from 'react-three-fiber'
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { Vector3 } from 'three' import { Vector3 } from 'three'
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
import { requestRender } from 'src/helpers/hooks/useIdeState'
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
extend({ OrbitControls }) extend({ OrbitControls })
function Asset({ url }) {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
const [loadedGeometry, setLoadedGeometry] = useState()
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
const mesh = useRef()
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
const ref = useUpdate((geometry) => {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
geometry.attributes = loadedGeometry.attributes
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
})
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
useEffect(() => {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
if (url) {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
const decoded = atob(url)
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
const loader = new STLLoader()
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
setLoadedGeometry(loader.parse(decoded))
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
}, [url])
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
if (!loadedGeometry) return null
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
return (
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<mesh ref={mesh} scale={[1, 1, 1]}>
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<bufferGeometry attach="geometry" ref={ref} />
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<meshStandardMaterial color="#F472B6" />
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
</mesh>
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
)
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
let debounceTimeoutId let debounceTimeoutId
function Controls({ onCameraChange, onDragStart }) { function Controls({ onCameraChange, onDragStart }) {
const controls = useRef() const controls = useRef()
@@ -85,7 +115,7 @@ function Controls({ onCameraChange, onDragStart }) {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
} }
}, []) }, [])
useFrame(() => controls.current.update()) useFrame(() => controls.current?.update())
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
return ( return (
<orbitControls <orbitControls
ref={controls} ref={controls}
@@ -115,9 +145,8 @@ function Sphere(props) {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
</mesh> </mesh>
) )
} }
let currentCode // I have no idea why this works and using state.code is the dispatch doesn't but it was always stale
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
const IdeViewer = () => { const IdeViewer = () => {
const { state, dispatch } = useContext(IdeContext) const { state, thunkDispatch } = useContext(IdeContext)
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
const [isDragging, setIsDragging] = useState(false) const [isDragging, setIsDragging] = useState(false)
const [image, setImage] = useState() const [image, setImage] = useState()
@@ -127,8 +156,7 @@ const IdeViewer = () => {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
'data:image/png;base64,' + state.objectData?.data 'data:image/png;base64,' + state.objectData?.data
) )
setIsDragging(false) setIsDragging(false)
}, [state.objectData]) }, [state.objectData?.type, state.objectData?.data])
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
currentCode = state.code
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
const openSCADDeepOceanThemeBackground = '#323232' const openSCADDeepOceanThemeBackground = '#323232'
// the following are tailwind colors in hex, can't use these classes to color three.js meshes. // the following are tailwind colors in hex, can't use these classes to color three.js meshes.
@@ -151,41 +179,64 @@ const IdeViewer = () => {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
isDragging ? 'opacity-25' : 'opacity-100' isDragging ? 'opacity-25' : 'opacity-100'
}`} }`}
> >
<img src={image} className="h-full w-full" /> <img alt="code-cad preview" src={image} className="h-full w-full" />
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
</div> </div>
)} )}
{state.isLoading && ( <div // eslint-disable-line jsx-a11y/no-static-element-interactions
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<div className="inset-0 absolute flex items-center justify-center">
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<div className="h-16 w-16 bg-pink-600 rounded-full animate-ping"></div>
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
</div>
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
)}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<div
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
className={`opacity-0 absolute inset-0 transition-opacity duration-500 ${ className={`opacity-0 absolute inset-0 transition-opacity duration-500 ${
isDragging ? 'opacity-100' : 'hover:opacity-50' !(isDragging || state.ideType !== 'openScad')
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
? 'hover:opacity-50'
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
: 'opacity-100'
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
}`} }`}
onMouseDown={() => setIsDragging(true)} onMouseDown={() => setIsDragging(true)}
> >
<Canvas> <Canvas>
<Controls <Controls
onDragStart={() => setIsDragging(true)} onDragStart={() => setIsDragging(true)}
onCameraChange={(camera) => onCameraChange={(camera) => {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
dispatch({ thunkDispatch({
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
type: 'render', type: 'updateCamera',
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
payload: { payload: { camera },
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
code: currentCode,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
camera,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
},
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
}) })
} thunkDispatch((dispatch, getState) => {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
const state = getState()
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
if (state.ideType === 'openScad') {
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
dispatch({ type: 'setLoading' })
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
requestRender({
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
state,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
dispatch,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
code: state.code,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
viewerSize: state.viewerSize,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
camera,
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
})
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
})
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
}}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
/> />
<ambientLight /> <ambientLight />
<pointLight position={[15, 5, 10]} /> <pointLight position={[15, 5, 10]} />
<Sphere position={[0, 0, 0]} color={pink400} /> {state.ideType === 'openScad' && (
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<Box position={[0, 50, 0]} size={[1, 100, 1]} color={indigo900} /> <>
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<Box position={[0, 0, -50]} size={[1, 1, 100]} color={indigo300} /> <Sphere position={[0, 0, 0]} color={pink400} />
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<Box position={[50, 0, 0]} size={[100, 1, 1]} color={pink400} /> <Box position={[0, 50, 0]} size={[1, 100, 1]} color={indigo900} />
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<Box
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
position={[0, 0, -50]}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
size={[1, 1, 100]}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
color={indigo300}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
/>
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<Box position={[50, 0, 0]} size={[100, 1, 1]} color={pink400} />
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
</>
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
)}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
{state.ideType === 'cadQuery' && (
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<Asset url={state.objectData?.data} />
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
)}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
</Canvas> </Canvas>
</div> </div>
{state.isLoading && (
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<div className="inset-0 absolute flex items-center justify-center">
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
<div className="h-16 w-16 bg-pink-600 rounded-full animate-ping"></div>
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
</div>
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
)}
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
</div> </div>
) )
} }
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.
Irev-Dev commented 2021-04-26 10:20:10 +02:00 (Migrated from github.com)
Review

This is where the stl is loaded in for CadQuery.

This is where the stl is loaded in for CadQuery.

View File

@@ -0,0 +1,68 @@
let openScadBaseURL = process.env.CADQUERY_BASE_URL
export const render = async ({ code }) => {
const body = JSON.stringify({
settings: {},
file: code,
})
try {
const response = await fetch(openScadBaseURL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
})
if (response.status === 400) {
// TODO add proper error messages for CadQuery
const { error } = await response.json()
const cleanedErrorMessage = error.replace(
/["|']\/tmp\/.+\/main.scad["|']/g,
"'main.scad'"
)
return {
status: 'error',
message: {
type: 'error',
message: addDateToLog(cleanedErrorMessage),
},
}
}
const data = await response.json()
return {
status: 'healthy',
objectData: {
type: 'stl',
data: data.imageBase64,
},
message: {
type: 'message',
message: addDateToLog(data.result),
},
}
} catch (e) {
// TODO handle errors better
// I think we should display something overlayed on the viewer window something like "network issue try again"
// and in future I think we need timeouts differently as they maybe from a user trying to render something too complex
// or something with minkowski in it :/ either way something like "render timed out, try again or here are tips to reduce part complexity" with a link talking about $fn and minkowski etc
return {
status: 'error',
message: {
type: 'error',
message: addDateToLog('network issue'),
},
}
}
}
const openScad = {
render,
// more functions to come
}
export default openScad
function addDateToLog(message) {
return `-> ${new Date().toLocaleString()}
${message}`
}

View File

@@ -1,7 +1,7 @@
import openScad from './openScadController' import openScad from './openScadController'
import openCascade from './newCascadeController' import cadQuery from './cadQueryController'
export const cadPackages = { export const cadPackages = {
openScad, openScad,
openCascade, cadQuery,
} }

View File

@@ -1,35 +0,0 @@
// Rename this file to remove "new" once Cascade integration is complete
export const render = async ({ code, settings }) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const shouldReject = Math.random() < 0.7
if (shouldReject) {
resolve({
objectData: {
type: 'stl',
data: ((Math.random() * 256 + 1) >>> 0).toString(2), // Randomized 8-bit numbers for funzies
},
message: {
type: 'message',
message: `bodies rendered by: ${code}`,
},
})
} else {
reject({
message: {
type: 'error',
message: 'unable to parse line: x',
},
})
}
}, 700)
})
}
const openCascade = {
render,
// More functions to come
}
export default openCascade

View File

@@ -2,33 +2,16 @@ let openScadBaseURL =
process.env.OPENSCAD_BASE_URL || process.env.OPENSCAD_BASE_URL ||
'https://x2wvhihk56.execute-api.us-east-1.amazonaws.com/dev' 'https://x2wvhihk56.execute-api.us-east-1.amazonaws.com/dev'
let lastViewPortSize = 'INIT'
let lastCameraSettings = 'INIT'
export const render = async ({ code, settings }) => { export const render = async ({ code, settings }) => {
const pixelRatio = window.devicePixelRatio || 1 const pixelRatio = window.devicePixelRatio || 1
const size = settings.viewerSize const size = {
? { x: Math.round(settings.viewerSize?.width * pixelRatio),
x: Math.round(settings.viewerSize?.width * pixelRatio), y: Math.round(settings.viewerSize?.height * pixelRatio),
y: Math.round(settings.viewerSize?.height * pixelRatio),
}
: lastViewPortSize
const camera = settings.camera || lastCameraSettings
if (settings.camera) {
lastCameraSettings = settings.camera
}
if (settings.viewerSize) {
lastViewPortSize = size
}
if ([camera, size].includes('INIT')) {
return {
status: 'insufficient-preview-info',
}
} }
const body = JSON.stringify({ const body = JSON.stringify({
settings: { settings: {
size, size,
camera, camera: settings.camera,
}, },
file: code, file: code,
}) })

View File

@@ -1,6 +1,13 @@
import { useReducer } from 'react' import { useReducer } from 'react'
import { cadPackages } from 'src/helpers/cadPackages' import { cadPackages } from 'src/helpers/cadPackages'
function withThunk(dispatch, getState) {
return (actionOrThunk) =>
typeof actionOrThunk === 'function'
? actionOrThunk(dispatch, getState)
: dispatch(actionOrThunk)
}
Irev-Dev commented 2021-04-26 10:26:03 +02:00 (Migrated from github.com)
Review

I think redux thunks might be a little more complex than this, but not by much. Basically you can use this like a normal dispatch, but if you want to something async you just pass it a function instead, you would have already scrolled passed examples.

I think redux thunks might be a little more complex than this, but not by much. Basically you can use this like a normal dispatch, but if you want to something async you just pass it a function instead, you would have already scrolled passed examples.
const donutInitCode = ` const donutInitCode = `
color(c="DarkGoldenrod")rotate_extrude()translate([20,0])circle(d=30); color(c="DarkGoldenrod")rotate_extrude()translate([20,0])circle(d=30);
donut(); donut();
@@ -17,16 +24,17 @@ module stick(basewid, angl){
}` }`
export const codeStorageKey = 'Last-openscad-code' export const codeStorageKey = 'Last-openscad-code'
let mutableState = null
export const useIdeState = () => { export const useIdeState = () => {
const code = localStorage.getItem(codeStorageKey) || donutInitCode const code = localStorage.getItem(codeStorageKey) || donutInitCode
const initialState = { const initialState = {
ideType: 'openScad', ideType: 'cadQuery',
consoleMessages: [{ type: 'message', message: 'Initialising OpenSCAD' }], consoleMessages: [{ type: 'message', message: 'Initialising OpenSCAD' }],
code, code,
objectData: { objectData: {
type: 'stl', type: 'stl',
data: 'some binary', data: null,
}, },
layout: { layout: {
direction: 'row', direction: 'row',
@@ -38,6 +46,8 @@ export const useIdeState = () => {
splitPercentage: 70, splitPercentage: 70,
}, },
}, },
camera: {},
viewerSize: { width: 0, height: 0 },
isLoading: false, isLoading: false,
} }
const reducer = (state, { type, payload }) => { const reducer = (state, { type, payload }) => {
@@ -74,51 +84,64 @@ export const useIdeState = () => {
...state, ...state,
layout: payload.message, layout: payload.message,
} }
case 'updateCamera':
return {
...state,
camera: payload.camera,
}
case 'updateViewerSize':
return {
...state,
viewerSize: payload.viewerSize,
}
case 'setLoading': case 'setLoading':
return { return {
...state, ...state,
isLoading: true, isLoading: true,
} }
case 'resetLoading':
return {
...state,
isLoading: false,
}
default: default:
return state return state
} }
} }
function dispatchMiddleware(dispatch, state) {
return ({ type, payload }) => {
switch (type) {
case 'render':
cadPackages[state.ideType]
.render({
code: payload.code,
settings: {
camera: payload.camera,
viewerSize: payload.viewerSize,
},
})
.then(({ objectData, message, status }) => {
if (status === 'insufficient-preview-info') return
if (status === 'error') {
dispatch({
type: 'errorRender',
payload: { message },
})
} else {
dispatch({
type: 'healthyRender',
payload: { objectData, message },
})
}
})
dispatch({ type: 'setLoading' })
break
default:
return dispatch({ type, payload })
}
}
}
const [state, dispatch] = useReducer(reducer, initialState) const [state, dispatch] = useReducer(reducer, initialState)
return [state, dispatchMiddleware(dispatch, state)] mutableState = state
const getState = () => mutableState
return [state, withThunk(dispatch, getState)]
}
export const requestRender = ({
state,
dispatch,
code,
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
} }