r3f-ify jsCadController
This commit is contained in:
@@ -31,11 +31,6 @@ function Asset({ geometry: incomingGeo }) {
|
|||||||
const colorMap = useTexture(texture)
|
const colorMap = useTexture(texture)
|
||||||
if (!incomingGeo) return null
|
if (!incomingGeo) return null
|
||||||
|
|
||||||
if (incomingGeo.length)
|
|
||||||
return incomingGeo.map((shape, index) => (
|
|
||||||
<primitive object={shape} key={index} />
|
|
||||||
))
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group dispose={null}>
|
<group dispose={null}>
|
||||||
<mesh ref={mesh} scale={[1, 1, 1]} geometry={incomingGeo}>
|
<mesh ref={mesh} scale={[1, 1, 1]} geometry={incomingGeo}>
|
||||||
@@ -166,6 +161,10 @@ const IdeViewer = ({ Loading }) => {
|
|||||||
setImage(state.objectData?.type === 'png' && state.objectData?.data)
|
setImage(state.objectData?.type === 'png' && state.objectData?.data)
|
||||||
setIsDragging(false)
|
setIsDragging(false)
|
||||||
}, [state.objectData?.type, state.objectData?.data])
|
}, [state.objectData?.type, state.objectData?.data])
|
||||||
|
const R3FComponent = React.useMemo(
|
||||||
|
() => state.objectData?.type === 'r3f-component' && state.objectData?.data,
|
||||||
|
[state.objectData?.type, state.objectData?.data]
|
||||||
|
)
|
||||||
|
|
||||||
// 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.
|
||||||
const pink400 = '#F472B6'
|
const pink400 = '#F472B6'
|
||||||
@@ -268,6 +267,7 @@ const IdeViewer = ({ Loading }) => {
|
|||||||
{state.objectData?.type === 'geometry' && state.objectData?.data && (
|
{state.objectData?.type === 'geometry' && state.objectData?.data && (
|
||||||
<Asset geometry={state.objectData?.data} />
|
<Asset geometry={state.objectData?.data} />
|
||||||
)}
|
)}
|
||||||
|
{R3FComponent && <R3FComponent />}
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</div>
|
</div>
|
||||||
<DelayedPingAnimation isLoading={state.isLoading} />
|
<DelayedPingAnimation isLoading={state.isLoading} />
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ export interface RenderArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ArtifactTypes = 'stl' | 'png' | 'geometry' | 'r3f-component'
|
||||||
|
|
||||||
export interface HealthyResponse {
|
export interface HealthyResponse {
|
||||||
status: 'healthy'
|
status: 'healthy'
|
||||||
message: {
|
message: {
|
||||||
@@ -30,7 +32,7 @@ export interface HealthyResponse {
|
|||||||
}
|
}
|
||||||
objectData: {
|
objectData: {
|
||||||
data: any
|
data: any
|
||||||
type: 'stl' | 'png' | 'geometry'
|
type: ArtifactTypes
|
||||||
}
|
}
|
||||||
customizerParams?: any[]
|
customizerParams?: any[]
|
||||||
currentParameters?: RawCustomizerParams
|
currentParameters?: RawCustomizerParams
|
||||||
|
|||||||
@@ -31,44 +31,59 @@ const materials = {
|
|||||||
}
|
}
|
||||||
materials.lines = materials.line
|
materials.lines = materials.line
|
||||||
|
|
||||||
function CSG2Object3D(obj) {
|
interface CsgObj {
|
||||||
const { vertices, indices, color, transforms } = obj
|
vertices: Float32Array
|
||||||
|
indices: Uint16Array
|
||||||
|
color?: [number, number, number, number]
|
||||||
|
transforms: number[]
|
||||||
|
type: 'mesh' | 'line' | 'lines'
|
||||||
|
}
|
||||||
|
|
||||||
const materialDef = materials[obj.type]
|
function CSGArray2R3fComponent(Csgs: CsgObj[]): React.ReactNode {
|
||||||
if (!materialDef) {
|
return () =>
|
||||||
console.error('Can not hangle object type: ' + obj.type, obj)
|
Csgs.map(({ vertices, indices, color, transforms, type }, index) => {
|
||||||
return null
|
const materialDef = materials[type]
|
||||||
}
|
if (!materialDef) {
|
||||||
|
console.error('Can not hangle object type: ' + type, {
|
||||||
|
vertices,
|
||||||
|
indices,
|
||||||
|
color,
|
||||||
|
transforms,
|
||||||
|
type,
|
||||||
|
})
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
let material = materialDef.def
|
let material = materialDef.def
|
||||||
if (color) {
|
if (color) {
|
||||||
const c = color
|
const [r, g, b, opacity] = color
|
||||||
material = materialDef.material({
|
material = materialDef.material({
|
||||||
color: new Color(c[0], c[1], c[2]),
|
color: new Color(r, g, b),
|
||||||
flatShading: true,
|
flatShading: true,
|
||||||
opacity: c[3] === void 0 ? 1 : c[3],
|
opacity: opacity === void 0 ? 1 : opacity,
|
||||||
transparent: c[3] != 1 && c[3] !== void 0,
|
transparent: opacity != 1 && opacity !== void 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const geo = new BufferGeometry()
|
||||||
|
geo.setAttribute('position', new BufferAttribute(vertices, 3))
|
||||||
|
|
||||||
|
let mesh
|
||||||
|
switch (type) {
|
||||||
|
case 'mesh':
|
||||||
|
geo.setIndex(new BufferAttribute(indices, 1))
|
||||||
|
mesh = new Mesh(geo, material)
|
||||||
|
break
|
||||||
|
case 'line':
|
||||||
|
mesh = new Line(geo, material)
|
||||||
|
break
|
||||||
|
case 'lines':
|
||||||
|
mesh = new LineSegments(geo, material)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (transforms) mesh.applyMatrix4({ elements: transforms })
|
||||||
|
return <primitive object={mesh} key={index} />
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
const geo = new BufferGeometry()
|
|
||||||
geo.setAttribute('position', new BufferAttribute(vertices, 3))
|
|
||||||
|
|
||||||
let mesh
|
|
||||||
switch (obj.type) {
|
|
||||||
case 'mesh':
|
|
||||||
geo.setIndex(new BufferAttribute(indices, 1))
|
|
||||||
mesh = new Mesh(geo, material)
|
|
||||||
break
|
|
||||||
case 'line':
|
|
||||||
mesh = new Line(geo, material)
|
|
||||||
break
|
|
||||||
case 'lines':
|
|
||||||
mesh = new LineSegments(geo, material)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if (transforms) mesh.applyMatrix4({ elements: transforms })
|
|
||||||
return mesh
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let scriptWorker
|
let scriptWorker
|
||||||
@@ -143,8 +158,8 @@ export const render: DefaultKernelExport['render'] = async ({
|
|||||||
} else {
|
} else {
|
||||||
workerHelper.resolver(
|
workerHelper.resolver(
|
||||||
createHealthyResponse({
|
createHealthyResponse({
|
||||||
type: 'geometry',
|
type: 'r3f-component',
|
||||||
data: data.entities.map(CSG2Object3D).filter((o) => o),
|
data: CSGArray2R3fComponent(data.entities),
|
||||||
consoleMessage: data.scriptStats,
|
consoleMessage: data.scriptStats,
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
customizerParams: jsCadToCadhubParams(parameterDefinitions || []),
|
customizerParams: jsCadToCadhubParams(parameterDefinitions || []),
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
import { useReducer } from 'react'
|
import { useReducer } from 'react'
|
||||||
import { cadPackages } from 'src/helpers/cadPackages'
|
import { cadPackages } from 'src/helpers/cadPackages'
|
||||||
import type { RootState } from '@react-three/fiber'
|
import type { RootState } from '@react-three/fiber'
|
||||||
import type { RawCustomizerParams } from 'src/helpers/cadPackages/common'
|
import type {
|
||||||
|
RawCustomizerParams,
|
||||||
|
ArtifactTypes,
|
||||||
|
} from 'src/helpers/cadPackages/common'
|
||||||
import { CadhubParams } from 'src/components/Customizer/customizerConverter'
|
import { CadhubParams } from 'src/components/Customizer/customizerConverter'
|
||||||
|
|
||||||
function withThunk(dispatch, getState) {
|
function withThunk(dispatch, getState) {
|
||||||
@@ -113,7 +116,7 @@ export interface State {
|
|||||||
consoleMessages: { type: 'message' | 'error'; message: string; time: Date }[]
|
consoleMessages: { type: 'message' | 'error'; message: string; time: Date }[]
|
||||||
code: string
|
code: string
|
||||||
objectData: {
|
objectData: {
|
||||||
type: 'INIT' | 'stl' | 'png' | 'geometry'
|
type: 'INIT' | ArtifactTypes
|
||||||
data: any
|
data: any
|
||||||
quality: 'low' | 'high'
|
quality: 'low' | 'high'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user