set up local development for openscad lamdas
and make a start on combining with Three.js IdeViewer Resolves #227 related #231
This commit is contained in:
@@ -1,25 +1,133 @@
|
||||
import { useContext } from 'react'
|
||||
import { IdeContext } from 'src/components/IdeToolbarNew'
|
||||
import { useRef, useState, useEffect, useContext, useMemo } from 'react'
|
||||
import { Canvas, extend, useFrame, useThree } from 'react-three-fiber'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
import { Vector3 } from 'three'
|
||||
|
||||
extend({ OrbitControls })
|
||||
|
||||
function Controls({ onCameraChange }) {
|
||||
const controls = useRef()
|
||||
const { scene, camera, gl } = useThree()
|
||||
useEffect(() => {
|
||||
// init camera position
|
||||
camera.position.x = 12
|
||||
camera.position.y = 12
|
||||
|
||||
if (controls.current) {
|
||||
const callback = ({ target }) => {
|
||||
// TODO figure out Three's rotations to make it match openscad's camera
|
||||
const vector = new Vector3()
|
||||
camera.getWorldDirection(vector)
|
||||
console.log(Object.values(vector).map((val) => (val * 180) / Math.PI))
|
||||
const { _x, _y, _z } = target.object.rotation
|
||||
const rad2Deg = 180 / Math.PI
|
||||
const [x, y, z] = [_x * rad2Deg, -_y * rad2Deg, _z * rad2Deg]
|
||||
console.log({ y, z, x })
|
||||
console.log(target, 'target')
|
||||
onCameraChange({
|
||||
position: target.object.position,
|
||||
rotation: { x, y, z },
|
||||
})
|
||||
}
|
||||
controls.current.addEventListener('end', callback)
|
||||
return () => controls.current.removeEventListener('end', callback)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useFrame(() => controls.current.update())
|
||||
return (
|
||||
<orbitControls
|
||||
ref={controls}
|
||||
args={[camera, gl.domElement]}
|
||||
enableDamping
|
||||
dampingFactor={0.1}
|
||||
rotateSpeed={0.5}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function Box(props) {
|
||||
// This reference will give us direct access to the mesh
|
||||
const mesh = useRef()
|
||||
|
||||
// Set up state for the hovered and active state
|
||||
const [hovered, setHover] = useState(false)
|
||||
const [active, setActive] = useState(false)
|
||||
|
||||
return (
|
||||
<mesh
|
||||
{...props}
|
||||
ref={mesh}
|
||||
scale={[1, 1, 1]}
|
||||
onClick={(event) => setActive(!active)}
|
||||
onPointerOver={(event) => setHover(true)}
|
||||
onPointerOut={(event) => setHover(false)}
|
||||
>
|
||||
<boxBufferGeometry args={[10, 10, 10]} />
|
||||
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
|
||||
</mesh>
|
||||
)
|
||||
}
|
||||
|
||||
const IdeViewer = () => {
|
||||
const { state } = useContext(IdeContext)
|
||||
const image =
|
||||
state.objectData?.type === 'png' &&
|
||||
state.objectData?.data &&
|
||||
window.URL.createObjectURL(state.objectData?.data)
|
||||
const { state, dispatch } = useContext(IdeContext)
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
|
||||
const image = useMemo(
|
||||
() =>
|
||||
state.objectData?.type === 'png' &&
|
||||
state.objectData?.data &&
|
||||
window.URL.createObjectURL(state.objectData?.data),
|
||||
[state.objectData]
|
||||
)
|
||||
return (
|
||||
<div className="p-8 border-2 m-2">
|
||||
<div className="pb-4">hi I'm viewer</div>
|
||||
<div>
|
||||
I should be showing an{' '}
|
||||
<span className="font-mono uppercase">{state.objectData?.type}</span>{' '}
|
||||
right now with the data{' '}
|
||||
<div className="pb-4">
|
||||
Rotating the Three.js Cube should than update the openscad camera to
|
||||
view the CAD object from the same angle. But having trouble translating
|
||||
between the two coordinate systems. OpenScad's camera only changes X and
|
||||
Z angles and Y is always 0. Where as rotation values from Three seem to
|
||||
change all x, y and z. I probably need to learn a bit more about 3d
|
||||
math.
|
||||
</div>
|
||||
{image && (
|
||||
<div>
|
||||
<img src={image} className="" />
|
||||
<div className="relative" style={{ height: '500px', width: '500px' }}>
|
||||
{image && (
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{ opacity: isDragging ? '0%' : '100%' }}
|
||||
>
|
||||
<img src={image} className="" />
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`opacity-0 absolute inset-0 ${
|
||||
isDragging ? 'opacity-100' : 'hover:opacity-50'
|
||||
}`}
|
||||
onMouseDown={() => setIsDragging(true)}
|
||||
onMouseUp={() => setIsDragging(false)}
|
||||
>
|
||||
<Canvas>
|
||||
<Controls
|
||||
onCameraChange={({ position, rotation }) => {
|
||||
dispatch({
|
||||
type: 'render',
|
||||
payload: {
|
||||
code: state.code,
|
||||
camera: {
|
||||
position,
|
||||
rotation,
|
||||
},
|
||||
},
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<ambientLight />
|
||||
<pointLight position={[15, 5, 10]} />
|
||||
<Box position={[0, 0, 0]} />
|
||||
</Canvas>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
// const openScadBaseURL = 'http://localhost:8080' // for local development
|
||||
const openScadBaseURL =
|
||||
'https://x2wvhihk56.execute-api.us-east-1.amazonaws.com/dev'
|
||||
|
||||
export const render = async ({ code, settings }) => {
|
||||
const body = JSON.stringify({
|
||||
settings: {
|
||||
size: {
|
||||
x: 500,
|
||||
y: 500,
|
||||
},
|
||||
camera: settings.camera,
|
||||
},
|
||||
file: code,
|
||||
})
|
||||
const response = await fetch(openScadBaseURL + '/render', {
|
||||
method: 'POST',
|
||||
headers: new Headers().append('Content-Type', 'application/json'),
|
||||
body: JSON.stringify({
|
||||
settings: {
|
||||
size: {
|
||||
x: 700,
|
||||
y: 300,
|
||||
},
|
||||
},
|
||||
file: code,
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body,
|
||||
})
|
||||
if (response.status === 400) {
|
||||
const { error } = await response.json()
|
||||
|
||||
@@ -22,7 +22,7 @@ export const useIdeState = () => {
|
||||
second: 'Console',
|
||||
splitPercentage: 70,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
const reducer = (state, { type, payload }) => {
|
||||
switch (type) {
|
||||
@@ -56,6 +56,8 @@ export const useIdeState = () => {
|
||||
...state,
|
||||
layout: payload.message,
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +66,10 @@ export const useIdeState = () => {
|
||||
switch (type) {
|
||||
case 'render':
|
||||
cadPackages[state.ideType]
|
||||
.render({ code: payload.code })
|
||||
.render({
|
||||
code: payload.code,
|
||||
settings: { camera: payload.camera },
|
||||
})
|
||||
.then(({ objectData, message, isError }) => {
|
||||
if (isError) {
|
||||
dispatch({
|
||||
|
||||
Reference in New Issue
Block a user