Skip to main content

Getting started with WASM

This guide will show you how to build a simple Javascript application using the ClassCAD API with WASM. ClassCAD will entirely run inside the browser. With WASM ClassCAD can be hosted on a server, a CDN or bundled with your application. The guide assumes you have a basic understanding of the Javascript ecosystem.

Create an account and get your app key

  • 1 — Visit ClassCAD and create an account.
  • 2 — Get your app key from the same user page, pick a WASM key.
  • 3 — You will be asked to provide allowed origins, type: http://localhost:5173/ which is the default port for vite apps.

Scaffold A New Project using WASM

This guide will show you how to build a simple Javascript application using the ClassCAD API with WASM. The guide assumes you have a basic understanding of the Javascript ecosystem and have Node.js installed on your computer.

First, scaffold a new Vite project. Vite is a common build tool that aims to provide a faster and leaner development experience for modern web projects. You can use any other build tool you prefer, but Vite is recommended for its speed and simplicity.

# Create a new directory for your project
mkdir projectName
cd projectName
# Install Vite and React
npm install react@18 react-dom@18
npm install --save-dev vite @vitejs/plugin-react

Create the following files in the root of your project:

vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>buerli-starter-react</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

/src/styles.css

* {
box-sizing: border-box;
}

html,
body,
#root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}

/src/main.jsx

import { createRoot } from 'react-dom/client'
import './styles.css'
import App from './App'

createRoot(document.getElementById('root')).render(<App />)

/src/App.jsx

import React from 'react'

export default function App() {
return (
<div>
<h1>Welcome to your first Buerli application.</h1>
</div>
)
}

You can now run the Vite development server to preview your application. Open a terminal in the root of your project and run:

npx vite

Vite will show you a URL where you can preview your application. Open the URL in your browser to see the default Vite application.

  VITE v5.1.6  ready in 93 ms

➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help

By now you will have the following folder structure:

/projectName
/src
App.jsx
index.jsx
styles.css
index.html
package.json
vite.config.js

Write your first Buerli app

First, install the necessary packages. We need threejs, react-three-fiber and buerli.

# Install client & buerli packages
npm install three @types/three @react-three/fiber@8 @react-three/drei@9
npm install @buerli.io/classcad@beta @buerli.io/react@beta

Modify App.jsx

You can provide the WASM either locally or from a CDN. In this example, by omitting a URL our awvstatic CDN is automatically being inferred.

import { Canvas } from '@react-three/fiber'
import { AccumulativeShadows, RandomizedLight, Center, OrbitControls } from '@react-three/drei'
import { init, WASMClient } from '@buerli.io/classcad'
import { useBuerliCadFacade } from '@buerli.io/react'
import { suspend } from 'suspend-react'

const appKey = '...'
init((did) => new WASMClient(did, { appKey }))

export default function App() {
return (
<Canvas shadows camera={{ position: [0, 0.5, 10], fov: 35 }}>
<color attach='background' args={['#f0f0f0']} />
<ambientLight intensity={0.5 * Math.PI} />
<directionalLight decay={0} position={[10, 15, 15]} castShadow />
<directionalLight decay={0} position={[-10, 15, -15]} />
<group position={[0, -1, 0]}>
<Center top>
<Cutout dHole={55} scale={0.025} />
</Center>
<AccumulativeShadows temporal frames={100} color='orange'>
<RandomizedLight radius={1} position={[5, 5, 5]} />
</AccumulativeShadows>
</group>
<OrbitControls />
</Canvas>
)
}

function Cutout({ dHole, ...props }) {
const { api, facade } = useBuerliCadFacade('mySession')
const geo = suspend(async () => {
await api.common.clear()
const part = await api.v1.part.create({ name: 'cutout' })
const ei = await api.part.entityInjection({ id: part })
const box = await api.v1.solid.box({ id: ei, width: 90, height: 90, length: 90 })
const inner = await api.v1.solid.box({ id: ei, width: 70, height: 70, length: 70 })
await api.v1.solid.subtraction({ id: ei, target: box, tools: [inner] })
const cyl = await api.v1.solid.cylinder({ id: ei, diameter: dHole, height: 2 * 90 })
await api.v1.solid.subtraction({ id: ei, target: box, tools: [cyl] })
const [geo] = await facade.createBufferGeometry(part)
return geo
}, ['cutout', dHole])
return (
<mesh castShadow receiveShadow geometry={geo} {...props}>
<meshStandardMaterial color='orange' />
</mesh>
)
}

In case your Vite dev server isn't running, start it with npm run dev. Open the URL in your browser to see the application. You should see a box with cut outs.