diff --git a/app/web/src/components/IdeViewer/IdeViewer.tsx b/app/web/src/components/IdeViewer/IdeViewer.tsx index 7ac1e67..9bffb4d 100644 --- a/app/web/src/components/IdeViewer/IdeViewer.tsx +++ b/app/web/src/components/IdeViewer/IdeViewer.tsx @@ -31,11 +31,6 @@ function Asset({ geometry: incomingGeo }) { const colorMap = useTexture(texture) if (!incomingGeo) return null - if (incomingGeo.length) - return incomingGeo.map((shape, index) => ( - - )) - return ( @@ -166,6 +161,10 @@ const IdeViewer = ({ Loading }) => { setImage(state.objectData?.type === 'png' && state.objectData?.data) setIsDragging(false) }, [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. const pink400 = '#F472B6' @@ -268,6 +267,7 @@ const IdeViewer = ({ Loading }) => { {state.objectData?.type === 'geometry' && state.objectData?.data && ( )} + {R3FComponent && } diff --git a/app/web/src/helpers/cadPackages/common.ts b/app/web/src/helpers/cadPackages/common.ts index 3b34feb..ca91004 100644 --- a/app/web/src/helpers/cadPackages/common.ts +++ b/app/web/src/helpers/cadPackages/common.ts @@ -21,6 +21,8 @@ export interface RenderArgs { } } +export type ArtifactTypes = 'stl' | 'png' | 'geometry' | 'r3f-component' + export interface HealthyResponse { status: 'healthy' message: { @@ -30,7 +32,7 @@ export interface HealthyResponse { } objectData: { data: any - type: 'stl' | 'png' | 'geometry' + type: ArtifactTypes } customizerParams?: any[] currentParameters?: RawCustomizerParams diff --git a/app/web/src/helpers/cadPackages/jsCad/jsCadController.ts b/app/web/src/helpers/cadPackages/jsCad/jsCadController.tsx similarity index 68% rename from app/web/src/helpers/cadPackages/jsCad/jsCadController.ts rename to app/web/src/helpers/cadPackages/jsCad/jsCadController.tsx index 62a92da..56e1458 100644 --- a/app/web/src/helpers/cadPackages/jsCad/jsCadController.ts +++ b/app/web/src/helpers/cadPackages/jsCad/jsCadController.tsx @@ -31,44 +31,59 @@ const materials = { } materials.lines = materials.line -function CSG2Object3D(obj) { - const { vertices, indices, color, transforms } = obj +interface CsgObj { + vertices: Float32Array + indices: Uint16Array + color?: [number, number, number, number] + transforms: number[] + type: 'mesh' | 'line' | 'lines' +} - const materialDef = materials[obj.type] - if (!materialDef) { - console.error('Can not hangle object type: ' + obj.type, obj) - return null - } +function CSGArray2R3fComponent(Csgs: CsgObj[]): React.ReactNode { + return () => + Csgs.map(({ vertices, indices, color, transforms, type }, index) => { + 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 - if (color) { - const c = color - material = materialDef.material({ - color: new Color(c[0], c[1], c[2]), - flatShading: true, - opacity: c[3] === void 0 ? 1 : c[3], - transparent: c[3] != 1 && c[3] !== void 0, + let material = materialDef.def + if (color) { + const [r, g, b, opacity] = color + material = materialDef.material({ + color: new Color(r, g, b), + flatShading: true, + opacity: opacity === void 0 ? 1 : opacity, + 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 }) - } - - 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 @@ -143,8 +158,8 @@ export const render: DefaultKernelExport['render'] = async ({ } else { workerHelper.resolver( createHealthyResponse({ - type: 'geometry', - data: data.entities.map(CSG2Object3D).filter((o) => o), + type: 'r3f-component', + data: CSGArray2R3fComponent(data.entities), consoleMessage: data.scriptStats, date: new Date(), customizerParams: jsCadToCadhubParams(parameterDefinitions || []), diff --git a/app/web/src/helpers/hooks/useIdeState.ts b/app/web/src/helpers/hooks/useIdeState.ts index 4043182..d5ff602 100644 --- a/app/web/src/helpers/hooks/useIdeState.ts +++ b/app/web/src/helpers/hooks/useIdeState.ts @@ -1,7 +1,10 @@ import { useReducer } from 'react' import { cadPackages } from 'src/helpers/cadPackages' 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' function withThunk(dispatch, getState) { @@ -113,7 +116,7 @@ export interface State { consoleMessages: { type: 'message' | 'error'; message: string; time: Date }[] code: string objectData: { - type: 'INIT' | 'stl' | 'png' | 'geometry' + type: 'INIT' | ArtifactTypes data: any quality: 'low' | 'high' }