I want to upload two stl files, and create a subtraction against the first stl using the second. When I upload a single stl and try to subtract using a Three based geometry it works well, but when I attempt to use the loaded stl, I simply get a blank scene.
In the example below, I am trying to use the second loaded item inside the subtraction. If you remove the reference to loaded geometry, and replace with a simply three built sphere geometry, you will see that it works.
import React, { useState } from 'react'
import { useRef } from 'react'
import { Canvas } from '@react-three/fiber'
import { Geometry, Base, Subtraction, Addition } from '@react-three/csg'
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
import { Environment } from './Environment'
import { OrbitControls, PivotControls } from '@react-three/drei'
import { BufferAttribute } from 'three'
function App() {
const [stlModel, setStlModel] = useState(null)
const [stlModelB, setStlModelB] = useState(null)
const handleFileChange = (event) => {
const file = event.target.files[0]
const reader = new FileReader(file)
reader.onload = (e) => {
const loader = new STLLoader()
const geometry = loader.parse(e.target.result)
setStlModel(geometry)
}
reader.readAsArrayBuffer(file)
}
const handleFileBChange = (event) => {
const file = event.target.files[0]
const reader = new FileReader(file)
reader.onload = (e) => {
const loader = new STLLoader()
const geometry = loader.parse(e.target.result)
setStlModelB(geometry)
}
reader.readAsArrayBuffer(file)
}
const ready = stlModel && stlModelB
return (
<div>
{!ready && (
<div>
<input type="file" accept=".stl" onChange={handleFileChange} />
<input type="file" accept=".stl" onChange={handleFileBChange} />
</div>
)}
{ready && (
<Canvas shadows camera={{ position: [-15, 10, 15], fov: 55 }}>
{stlModel && (
<>
<color attach="background" args={['skyblue']} />
<ModelRender geom={stlModel} geomB={stlModelB} />
<Environment />
<OrbitControls makeDefault />
</>
)}
</Canvas>
)}
</div>
)
}
function ModelRender({ geom, geomB }) {
const csg = useRef()
geom.setAttribute(`uv`, new BufferAttribute(new Float32Array([]), 1))
return (
<mesh receiveShadow castShadow rotation={[-Math.PI / 2, 0, 0]} position={[0, -3, 0]} scale={[0.02, 0.02, 0.02]}>
<Geometry useGroups ref={csg}>
<Base geometry={geom}>
<meshPhysicalMaterial color={`green`} />
</Base>
<PivotControls activeAxes={[true, true, true]} rotation={[0, Math.PI, 0]} scale={100} anchor={[0.4, 0, 0]} onDrag={() => csg.current.update()}>
<Window geom={geomB} />
</PivotControls>
</Geometry>
</mesh>
)
}
function Window({ geom }) {
const csg = useRef()
geom.setAttribute(`uv`, new BufferAttribute(new Float32Array([]), 1))
return (
<Subtraction position={[50, 50, 50]}>
<mesh receiveShadow castShadow rotation={[-Math.PI / 2, 0, 0]} position={[0, -3, 0]} scale={[0.02, 0.02, 0.02]}>
<Geometry useGroups ref={csg}>
<Base geometry={geom}>
<meshPhysicalMaterial color={`red`} />
</Base>
</Geometry>
</mesh>
</Subtraction>
)
}
export default App