# Bitbybit - Browser-Based CAD Platform ## Introduction Bitbybit is an open-source, browser-based CAD (Computer-Aided Design) platform providing core 3D geometry algorithms for parametric modeling and computational design. Built as a TypeScript monorepo, it exposes powerful CAD kernels (OpenCascade, JSCAD, Manifold 3D) through a unified API that works seamlessly in both Node.js and browser environments. The platform enables developers to create sophisticated 3D modeling applications, product configurators, and CAD tools using familiar web technologies while leveraging professional-grade geometry engines compiled to WebAssembly for high-performance computation. The architecture follows a layered approach with 11 npm packages spanning from foundational vector mathematics (@bitbybit-dev/base) through specialized CAD kernels (@bitbybit-dev/occt, @bitbybit-dev/jscad, @bitbybit-dev/manifold) to rendering engine integrations (@bitbybit-dev/threejs, @bitbybit-dev/babylonjs, @bitbybit-dev/playcanvas). Worker packages enable non-blocking asynchronous operations via Web Workers, ensuring smooth UI performance during complex geometry calculations. The platform supports multiple file formats (STEP, STL, DXF, 3MF), making it ideal for 3D printing, AEC applications, automotive design, game development, and product development workflows. --- ## APIs and Key Functions ### Base Package - Vector Mathematics Foundation package providing pure TypeScript implementations of vector math, transformations, and basic geometry operations with no external dependencies. ```typescript import { Vector, Point, Transforms } from '@bitbybit-dev/base'; // Initialize services const math = new MathBitByBit(); const geometryHelper = new GeometryHelper(); const vector = new Vector(math, geometryHelper); const transforms = new Transforms(vector, math); const lists = new Lists(); const point = new Point(geometryHelper, transforms, vector, lists); // Vector operations - calculate angle between two vectors const angle = vector.angleBetween({ first: [1, 0, 0], second: [0, 1, 0] }); console.log(`Angle: ${angle} degrees`); // Output: 90 degrees // Add vectors together const sum = vector.addAll({ vectors: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] }); console.log(sum); // Output: [12, 15, 18] // Remove duplicate vectors with tolerance const unique = vector.removeAllDuplicateVectors({ vectors: [[0, 0, 0], [0.001, 0.001, 0.001], [1, 1, 1]], tolerance: 0.01 }); console.log(unique); // Output: [[0, 0, 0], [1, 1, 1]] ``` ### Base Package - Point Transformations Manipulate 3D points in space using transformation matrices for translation, rotation, and scaling operations. ```typescript import { Point, Transforms } from '@bitbybit-dev/base'; const transforms = new Transforms(vector, math); const point = new Point(geometryHelper, transforms, vector, lists); // Transform a single point const transformed = point.transformPoint({ point: [1, 0, 0], transformation: [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5, 5, 5, 1 // Translation by [5, 5, 5] ] }); console.log(transformed); // Output: [6, 5, 5] // Translate multiple points const translated = point.translatePoints({ points: [[0, 0, 0], [1, 1, 1], [2, 2, 2]], translation: [10, 20, 30] }); console.log(translated); // Output: [[10, 20, 30], [11, 21, 31], [12, 22, 32]] // Translate points with individual vectors const individualTranslations = point.translatePointsWithVectors({ points: [[0, 0, 0], [1, 1, 1]], translations: [[5, 0, 0], [0, 5, 0]] }); console.log(individualTranslations); // Output: [[5, 0, 0], [1, 6, 1]] ``` ### Base Package - Transformation Matrices Create rotation, translation, and scaling transformations using 4x4 matrices represented as flat 16-number arrays. ```typescript import { Transforms } from '@bitbybit-dev/base'; const transforms = new Transforms(vector, math); // Rotation around center point with custom axis const rotationTransforms = transforms.rotationCenterAxis({ center: [5, 5, 5], axis: [0, 1, 0], angle: 90 // degrees }); // Returns array of 3 transformations: translate to origin, rotate, translate back // Rotation around X axis at center point const rotationX = transforms.rotationCenterX({ center: [0, 0, 0], angle: 45 }); // Rotation around Y axis at center point const rotationY = transforms.rotationCenterY({ center: [1, 2, 3], angle: 180 }); // Rotation around Z axis at center point const rotationZ = transforms.rotationCenterZ({ center: [0, 5, 0], angle: -30 }); // Create translation transformation const translation = transforms.translationXYZ({ translation: [10, 20, 30] }); // Create multiple translations at once const translations = transforms.translationsXYZ({ translations: [[1, 0, 0], [0, 1, 0], [0, 0, 1]] }); ``` ### OCCT Package - Creating Basic Wires in Node.js OpenCascade Technology kernel integration for professional NURBS-based CAD operations, supporting STEP file export and complex geometric modeling. ```typescript import initOpenCascade from "@bitbybit-dev/occt/bitbybit-dev-occt/node.js"; import { OCCTWire } from "@bitbybit-dev/occt/lib/services/shapes/wire.js"; import { OccHelper } from "@bitbybit-dev/occt/lib/occ-helper.js"; import { VectorHelperService } from "@bitbybit-dev/occt/lib/api/vector-helper.service.js"; import { ShapesHelperService } from "@bitbybit-dev/occt/lib/api/shapes-helper.service.js"; async function createGeometry() { console.log("Initializing OpenCascade..."); const occ = await initOpenCascade(); const vecHelper = new VectorHelperService(); const shapesHelper = new ShapesHelperService(); const helper = new OccHelper(vecHelper, shapesHelper, occ); const wire = new OCCTWire(occ, helper); // Create a circle wire const circle = wire.createCircleWire({ radius: 10, center: [0, 0, 0], direction: [0, 1, 0] // Circle in XZ plane }); // Get point on wire at parameter const pt = wire.pointOnWireAtParam({ shape: circle, param: 0.2 // 20% along the wire }); console.log("Point on circle:", pt); // Output: [x, y, z] coordinates // Create polygon wire (closed polyline) const polygon = wire.createPolygonWire({ points: [[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0]] }); // Create polyline wire (open) const polyline = wire.createPolylineWire({ points: [[0, 0, 0], [5, 5, 0], [10, 0, 0], [15, 5, 0]] }); return { circle, polygon, polyline }; } createGeometry().catch(console.error); ``` ### OCCT Package - Creating Complex Wires and Curves Advanced wire creation including Bezier curves, B-splines, and interpolation through points. ```typescript import { OCCTWire } from "@bitbybit-dev/occt/lib/services/shapes/wire.js"; // Bezier curve through control points const bezierWire = wire.createBezier({ points: [[0, 0, 0], [5, 10, 0], [10, 10, 0], [15, 0, 0]], closed: false }); // Bezier curve with weights for rational curves const weightedBezier = wire.createBezierWeights({ points: [[0, 0, 0], [5, 10, 0], [10, 10, 0], [15, 0, 0]], weights: [1, 2, 2, 1], // Higher weights pull curve toward control points closed: false }); // B-spline curve (NURBS) const bspline = wire.createBSpline({ points: [[0, 0, 0], [3, 5, 0], [6, 3, 0], [9, 7, 0], [12, 0, 0]], closed: false, degree: 3 // Cubic B-spline }); // Interpolate smooth curve through points const interpolated = wire.interpolatePoints({ points: [[0, 0, 0], [2, 3, 1], [5, 2, 2], [8, 5, 1], [10, 0, 0]], tolerance: 0.01, periodic: false }); // Create line with extensions beyond endpoints const extendedLine = wire.createLineWireWithExtensions({ start: [0, 0, 0], end: [10, 10, 0], extensionStart: 2, // Extend 2 units before start extensionEnd: 3 // Extend 3 units past end }); // Combine multiple edges and wires into single wire const combined = wire.combineEdgesAndWiresIntoAWire({ shapes: [wire1, edge1, wire2, edge2] }); ``` ### OCCT Package - Creating 3D Solids Create primitive and complex solid geometries using the OpenCascade kernel. ```typescript import { OCCTSolid } from "@bitbybit-dev/occt/lib/services/shapes/solid.js"; // Create a box (rectangular prism) const box = solid.createBox({ width: 10, length: 20, height: 5, center: [0, 0, 0] }); // Create a cube const cube = solid.createCube({ size: 10, center: [5, 5, 5] }); // Create box from corner point const boxFromCorner = solid.createBoxFromCorner({ corner: [0, 0, 0], width: 15, length: 15, height: 10 }); // Create cylinder const cylinder = solid.createCylinder({ radius: 5, height: 20, center: [0, 0, 0], direction: [0, 1, 0] // Cylinder along Y axis }); // Create cylinders along lines const cylinders = solid.createCylindersOnLines({ lines: [ { start: [0, 0, 0], end: [10, 0, 0] }, { start: [0, 0, 0], end: [0, 10, 0] } ], radius: 1 }); // Create sphere const sphere = solid.createSphere({ radius: 8, center: [0, 0, 0] }); // Create cone const cone = solid.createCone({ radius1: 5, // Base radius radius2: 0, // Top radius (point) height: 10, center: [0, 0, 0], direction: [0, 1, 0] }); // Get solid properties const volume = solid.getSolidVolume({ shape: box }); const surfaceArea = solid.getSolidSurfaceArea({ shape: sphere }); const centerOfMass = solid.getSolidCenterOfMass({ shape: cylinder }); console.log(`Volume: ${volume}, Area: ${surfaceArea}, COM: ${centerOfMass}`); ``` ### JSCAD Package - CSG Boolean Operations JSCAD kernel for Constructive Solid Geometry operations with fast boolean operations and STL export support. ```typescript import * as JSCAD from '@jscad/modeling'; import { JSCADShapes } from '@bitbybit-dev/jscad'; import { MathBitByBit } from '@bitbybit-dev/base'; const math = new MathBitByBit(); const shapes = new JSCADShapes(JSCAD, math); // Create cube const cube = shapes.cube({ center: [0, 0, 0], size: 10 }); // Create cuboid (rectangular prism) const cuboid = shapes.cuboid({ center: [0, 0, 0], width: 10, height: 5, length: 15 }); // Create multiple cubes at different centers const cubes = shapes.cubesOnCenterPoints({ centers: [[0, 0, 0], [15, 0, 0], [30, 0, 0]], size: 8 }); // Create cylinder const cylinder = shapes.cylinder({ center: [0, 0, 0], radius: 5, height: 20, segments: 32 }); // Create multiple cylinders const cylinders = shapes.cylindersOnCenterPoints({ centers: [[0, 0, 0], [0, 25, 0]], radius: 4, height: 15, segments: 32 }); // Create elliptic cylinder const ellipticCylinder = shapes.cylinderElliptic({ center: [0, 0, 0], height: 10, startRadius: [5, 3], endRadius: [3, 2], segments: 32 }); // Create ellipsoid const ellipsoid = shapes.ellipsoid({ center: [0, 0, 0], radius: [6, 4, 8], segments: 32 }); console.log(`Created ${cubes.length} cubes`); ``` ### Manifold 3D Package - High-Performance Boolean Operations Manifold 3D kernel providing robust, fast mesh boolean operations and watertight geometry guarantees. ```typescript import * as Manifold3D from 'manifold-3d'; import { ManifoldShapes } from '@bitbybit-dev/manifold'; async function createManifoldGeometry() { const wasm = await Manifold3D.default(); const shapes = new ManifoldShapes(wasm); // Create cube const cube = shapes.cube({ size: 10, center: true }); // Create sphere const sphere = shapes.sphere({ radius: 8, circularSegments: 64 }); // Create tetrahedron const tetrahedron = shapes.tetrahedron(); // Create manifold from mesh data const customManifold = shapes.manifoldFromMesh({ mesh: { numProp: 3, vertProperties: new Float32Array([ 0, 0, 0, // vertex 0 1, 0, 0, // vertex 1 0, 1, 0 // vertex 2 ]), triVerts: new Uint32Array([0, 1, 2]) // Triangle indices } }); // Create manifold from polygon points (automatically handles deduplication) const fromPolygons = shapes.fromPolygonPoints({ polygonPoints: [ [[0, 0, 0], [1, 0, 0], [0, 1, 0]], // Triangle 1 [[1, 0, 0], [1, 1, 0], [0, 1, 0]] // Triangle 2 ] }); return { cube, sphere, tetrahedron, customManifold, fromPolygons }; } createManifoldGeometry().catch(console.error); ``` ### BabylonJS Integration - React Application with OCCT Worker Full React application integrating Babylon.js rendering with OCCT worker for non-blocking CAD operations. ```typescript import React, { useEffect, useState } from 'react'; import { BitByBitBase } from '@bitbybit-dev/babylonjs'; import { OccStateEnum } from '@bitbybit-dev/occt-worker'; import { Scene, Engine, Color4, HemisphericLight, Vector3, ArcRotateCamera } from '@babylonjs/core'; function CupConfiguratorApp() { const [showSpinner, setShowSpinner] = useState(true); const [bitByBitInitialised, setBitByBitInitialised] = useState(false); const [cupHeight, setCupHeight] = useState(13); const [cupRadius, setCupRadius] = useState(4.5); useEffect(() => { // Initialize BitByBit with Babylon.js const bitbybit = new BitByBitBase(); const canvas = document.getElementById('renderCanvas') as HTMLCanvasElement; // Setup Babylon.js engine and scene const engine = new Engine(canvas); const scene = new Scene(engine); engine.setHardwareScalingLevel(0.5); scene.clearColor = new Color4(26/255, 28/255, 31/255, 1); // Setup camera const camera = new ArcRotateCamera('Camera', 0, 10, 10, new Vector3(0, 0, 0), scene); camera.attachControl(canvas, true); // Setup lighting const light = new HemisphericLight('HemiLight', new Vector3(0, 1, 0), scene); light.intensity = 1; // Initialize OCCT web worker for non-blocking operations const occt = new Worker( new URL('./occ.worker', import.meta.url), { name: 'OCC', type: 'module' } ); bitbybit.init(scene, occt, undefined); // Start render loop engine.runRenderLoop(() => { scene.render(); }); window.onresize = () => { if (engine) engine.resize(); }; // Subscribe to OCCT worker state changes bitbybit.occtWorkerManager.occWorkerState$.subscribe(state => { if (state.state === OccStateEnum.initialised) { setShowSpinner(false); setBitByBitInitialised(true); engine.resize(); // Ready to compute geometry } else if (state.state === OccStateEnum.computing) { setShowSpinner(true); } else if (state.state === OccStateEnum.loaded) { setShowSpinner(false); } }); }, []); return (
{showSpinner && (
Computing geometry...
)}
); } export default CupConfiguratorApp; ``` ### OCCT Worker - Asynchronous CAD Operations Expose OCCT operations via Web Worker with RxJS observables for non-blocking geometry computation. ```typescript import { BitByBitBase } from '@bitbybit-dev/babylonjs'; import { OccStateEnum } from '@bitbybit-dev/occt-worker'; import { filter, first } from 'rxjs/operators'; async function performAsyncCADOperations(bitbybit: BitByBitBase) { // Wait for OCCT worker initialization await bitbybit.occtWorkerManager.occWorkerState$.pipe( filter(s => s.state === OccStateEnum.initialised), first() ).toPromise(); // All operations now run in worker thread without blocking UI try { // Create wire asynchronously const circle = await bitbybit.occt.wire.createCircleWire({ radius: 50, center: [0, 0, 0], direction: [0, 1, 0] }); // Extrude wire into face const face = await bitbybit.occt.operations.extrude({ shape: circle, direction: [0, 10, 0] }); // Create solid from face const solid = await bitbybit.occt.operations.makeThickSolidSimple({ shape: face, offset: 2 }); // Perform boolean operations const box = await bitbybit.occt.solid.createBox({ width: 30, length: 30, height: 30, center: [0, 5, 0] }); const result = await bitbybit.occt.booleans.difference({ shape: solid, shapes: [box] }); // Export to STEP file const stepFile = await bitbybit.occt.io.saveShapeSTEP({ shape: result, filename: 'output.step', adjustYtoZ: false }); console.log('STEP file generated:', stepFile); return result; } catch (error) { console.error('CAD operation failed:', error); throw error; } } // Subscribe to worker state for real-time feedback function monitorWorkerState(bitbybit: BitByBitBase) { bitbybit.occtWorkerManager.occWorkerState$.subscribe(state => { switch(state.state) { case OccStateEnum.initialising: console.log('Initializing OCCT...'); break; case OccStateEnum.initialised: console.log('OCCT ready'); break; case OccStateEnum.computing: console.log('Computing geometry...'); break; case OccStateEnum.loaded: console.log('Geometry loaded'); break; case OccStateEnum.error: console.error('Worker error:', state.error); break; } }); } ``` ### File Export - STEP and STL File Generation Export CAD geometry to industry-standard formats for 3D printing and CAD software interoperability. ```typescript import { BitByBitBase } from '@bitbybit-dev/babylonjs'; async function exportGeometry(bitbybit: BitByBitBase, shape: any) { try { // Export to STEP format (CAD standard) const stepData = await bitbybit.occt.io.saveShapeSTEP({ shape: shape, filename: 'model.step', adjustYtoZ: true, // Convert Y-up to Z-up coordinate system precision: 0.001 }); // Trigger browser download const stepBlob = new Blob([stepData], { type: 'application/step' }); const stepUrl = URL.createObjectURL(stepBlob); const stepLink = document.createElement('a'); stepLink.href = stepUrl; stepLink.download = 'model.step'; stepLink.click(); URL.revokeObjectURL(stepUrl); // Export to STL format (3D printing standard) const stlData = await bitbybit.occt.io.saveShapeSTL({ shape: shape, filename: 'model.stl', adjustYtoZ: true, linearDeflection: 0.1, // Mesh quality (lower = finer) angularDeflection: 0.5, binary: true // Binary STL (smaller file size) }); // Trigger browser download const stlBlob = new Blob([stlData], { type: 'application/sla' }); const stlUrl = URL.createObjectURL(stlBlob); const stlLink = document.createElement('a'); stlLink.href = stlUrl; stlLink.download = 'model.stl'; stlLink.click(); URL.revokeObjectURL(stlUrl); console.log('Files exported successfully'); return { step: stepData, stl: stlData }; } catch (error) { console.error('Export failed:', error); throw new Error(`Failed to export geometry: ${error.message}`); } } // Export with error handling and user feedback async function exportWithFeedback( bitbybit: BitByBitBase, shape: any, onProgress: (message: string) => void ) { onProgress('Preparing STEP export...'); const step = await bitbybit.occt.io.saveShapeSTEP({ shape: shape, filename: 'model.step', adjustYtoZ: true }); onProgress('Preparing STL export...'); const stl = await bitbybit.occt.io.saveShapeSTL({ shape: shape, filename: 'model.stl', adjustYtoZ: true, linearDeflection: 0.05 }); onProgress('Export complete!'); return { step, stl }; } ``` ### ThreeJS Integration - 3D Visualization Integrate Three.js renderer for real-time 3D visualization of CAD geometry in web browsers. ```typescript import * as THREE from 'three'; import { BitByBitThree } from '@bitbybit-dev/threejs'; import initOpenCascade from '@bitbybit-dev/occt/bitbybit-dev-occt/bitbybit-dev-occt.js'; async function setupThreeJSScene() { // Initialize Three.js scene const scene = new THREE.Scene(); scene.background = new THREE.Color(0x1a1c1f); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.set(50, 50, 50); camera.lookAt(0, 0, 0); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Setup lighting const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); directionalLight.position.set(10, 10, 10); scene.add(directionalLight); // Initialize BitByBit Three.js integration const occ = await initOpenCascade(); const bitbybitThree = new BitByBitThree(scene, occ); // Create and visualize OCCT geometry const box = await bitbybitThree.occt.solid.createBox({ width: 20, length: 20, height: 20, center: [0, 0, 0] }); // Draw OCCT shape in Three.js scene const mesh = await bitbybitThree.draw.drawOcctShape({ shape: box, options: { colour: '#ff6b6b', opacity: 1, drawEdges: true, edgeColour: '#333333', edgeWidth: 2 } }); // Animation loop function animate() { requestAnimationFrame(animate); mesh.rotation.y += 0.01; renderer.render(scene, camera); } animate(); // Handle window resize window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); return { scene, camera, renderer, bitbybitThree }; } setupThreeJSScene().catch(console.error); ``` ### Complex CAD Operations - Boolean Operations and Fillets Advanced CAD operations including union, intersection, difference, and edge filleting. ```typescript import { BitByBitBase } from '@bitbybit-dev/babylonjs'; async function complexCADOperations(bitbybit: BitByBitBase) { // Create base shapes const box = await bitbybit.occt.solid.createBox({ width: 50, length: 50, height: 50, center: [0, 0, 0] }); const cylinder = await bitbybit.occt.solid.createCylinder({ radius: 15, height: 70, center: [0, 0, 0], direction: [0, 1, 0] }); const sphere = await bitbybit.occt.solid.createSphere({ radius: 30, center: [25, 25, 0] }); // Boolean difference (subtract cylinder from box) const boxWithHole = await bitbybit.occt.booleans.difference({ shape: box, shapes: [cylinder], keepEdges: true }); // Boolean union (combine shapes) const combined = await bitbybit.occt.booleans.union({ shapes: [boxWithHole, sphere], tolerance: 0.01 }); // Boolean intersection (get overlapping volume) const intersection = await bitbybit.occt.booleans.intersection({ shapes: [box, sphere] }); // Apply fillets to edges const edges = await bitbybit.occt.edge.getEdges({ shape: combined }); const filletedShape = await bitbybit.occt.fillets.filletEdges({ shape: combined, radius: 3, edges: edges.slice(0, 4) // Fillet first 4 edges }); // Apply chamfer to edges const chamferedShape = await bitbybit.occt.fillets.chamferEdges({ shape: combined, distance: 2, edges: edges.slice(4, 8) }); // Offset faces (shell operation) const shell = await bitbybit.occt.operations.makeThickSolidSimple({ shape: box, offset: -2, // Negative for internal offset tolerance: 0.01 }); // Calculate properties const volume = await bitbybit.occt.solid.getSolidVolume({ shape: filletedShape }); const area = await bitbybit.occt.solid.getSolidSurfaceArea({ shape: filletedShape }); const centerOfMass = await bitbybit.occt.solid.getSolidCenterOfMass({ shape: filletedShape }); console.log(`Volume: ${volume} mm³`); console.log(`Surface Area: ${area} mm²`); console.log(`Center of Mass: [${centerOfMass.join(', ')}]`); return { boxWithHole, combined, intersection, filletedShape, chamferedShape, shell, properties: { volume, area, centerOfMass } }; } ``` ### PlayCanvas Integration - High-Performance 3D Visualization PlayCanvas game engine integration for real-time 3D CAD visualization with optimized mobile performance and entity-component architecture. ```typescript import * as pc from 'playcanvas'; import { BitByBitBase, Inputs } from '@bitbybit-dev/playcanvas'; async function setupPlayCanvasCAD() { // Setup PlayCanvas application const canvas = document.getElementById('playcanvas') as HTMLCanvasElement; const app = new pc.Application(canvas, { graphicsDeviceOptions: { antialias: true, alpha: false, devicePixelRatio: 0.5 }, mouse: new pc.Mouse(canvas), touch: new pc.TouchDevice(canvas) }); // Configure canvas app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW); app.setCanvasResolution(pc.RESOLUTION_AUTO); // Create scene hierarchy const scene = new pc.Entity('scene'); app.root.addChild(scene); // Setup camera const camera = new pc.Entity('camera'); camera.addComponent('camera', { clearColor: new pc.Color(0x1a / 255, 0x1c / 255, 0x1f / 255, 1), fov: 70, nearClip: 0.1, farClip: 1000 }); camera.setPosition(10, 5, 15); scene.addChild(camera); // Set lighting app.scene.ambientLight = new pc.Color(0.4, 0.4, 0.4); // Initialize BitByBit with PlayCanvas const bitbybit = new BitByBitBase(); // Initialize OCCT worker for CAD operations const occtWorker = new Worker( new URL('./occ.worker', import.meta.url), { name: 'OCC', type: 'module' } ); bitbybit.init(app, scene, occtWorker); // Start render loop app.start(); // Wait for OCCT initialization await bitbybit.occtWorkerManager.occWorkerState$.pipe( filter(s => s.state === OccStateEnum.initialised), first() ).toPromise(); // Create and draw CAD geometry const box = await bitbybit.occt.solid.createBox({ width: 10, length: 10, height: 10, center: [0, 0, 0] }); const cylinder = await bitbybit.occt.solid.createCylinder({ radius: 3, height: 12, center: [0, 0, 0], direction: [0, 1, 0] }); // Boolean difference operation const result = await bitbybit.occt.booleans.difference({ shape: box, shapes: [cylinder] }); // Draw the result in PlayCanvas scene await bitbybit.draw.drawAnyAsync({ entity: result, options: { updatable: false } }); // Setup orbit camera controls const cameraOptions = new Inputs.PlayCanvasCamera.OrbitCameraDto(); cameraOptions.distance = 20; cameraOptions.pitch = -24; cameraOptions.yaw = 27; cameraOptions.frameOnStart = false; cameraOptions.inertiaFactor = 0.2; cameraOptions.focusEntity = camera; bitbybit.playcanvas.camera.orbitCamera.create(cameraOptions); return { bitbybit, app, scene, camera }; } // Handle window resize window.addEventListener('resize', () => { if (app) app.resizeCanvas(); }); setupPlayCanvasCAD().catch(console.error); ``` ### PlayCanvas - Creating Directional Lights and Ground Plane Setup scene lighting and environment for PlayCanvas CAD applications. ```typescript import * as pc from 'playcanvas'; import { BitByBitBase } from '@bitbybit-dev/playcanvas'; function createSceneEnvironment(scene: pc.Entity) { // Create directional light with shadows const dirLight = new pc.Entity('directionalLight'); dirLight.addComponent('light', { type: 'directional', color: new pc.Color(1, 1, 1), intensity: 0.8, castShadows: true, shadowDistance: 40, shadowResolution: 4000, shadowBias: 0.2, normalOffsetBias: 0.02, shadowType: 1 // PCF shadow type }); dirLight.setPosition(70, 25, -70); dirLight.lookAt(0, 0, 0); scene.addChild(dirLight); // Create ground plane const ground = new pc.Entity('ground'); ground.addComponent('render', { type: 'plane' }); ground.setLocalScale(74, 1, 74); ground.setPosition(0, -0.01, 0); // Apply material to ground const groundMaterial = new pc.StandardMaterial(); groundMaterial.diffuse = new pc.Color(0x22 / 255, 0x22 / 255, 0x22 / 255); groundMaterial.update(); if (ground.render) { ground.render.meshInstances[0].material = groundMaterial; } scene.addChild(ground); return { dirLight, ground }; } // Update loop for animations function setupAnimationLoop(app: pc.Application, entities: pc.Entity[]) { const rotationSpeed = 0.0005; app.on('update', (dt: number) => { entities.forEach(entity => { entity.rotate(0, -rotationSpeed * 180 / Math.PI, 0); }); }); } ``` --- ## Summary and Integration Patterns Bitbybit provides a comprehensive CAD platform accessible through standard web technologies, enabling developers to build sophisticated 3D modeling applications without deep CAD expertise. The primary use cases span product configurators (cups, furniture, laptop holders), 3D printing preparation tools, AEC visualization applications, game development with CAD precision, and automotive design systems. The platform's strength lies in its layered architecture where base mathematical operations support specialized CAD kernels (OCCT for NURBS precision, JSCAD for CSG speed, Manifold for robust booleans), all unified under a consistent TypeScript API. Worker packages ensure smooth UI performance during complex geometry calculations by leveraging Web Workers for non-blocking computation. Integration patterns typically follow either a Node.js batch processing approach for server-side geometry generation or a browser-based interactive application using React/Angular/Vue with Babylon.js, Three.js, or PlayCanvas for real-time visualization. The platform now supports three major game engines: BabylonJS (best compatibility with Bitbybit visual scripts, includes physics and GUI), ThreeJS (vast ecosystem and smaller bundle size), and PlayCanvas (exceptional performance and mobile optimization with entity-component architecture). The Web Worker architecture is critical for browser applications, allowing parametric updates and boolean operations to execute without freezing the UI. File export capabilities (STEP, STL, DXF, 3MF) ensure seamless interoperability with professional CAD software and 3D printing workflows. The platform's open-source MIT license and modular package structure make it ideal for both commercial product development and educational applications, with comprehensive TypeScript types providing excellent IDE support and reducing integration complexity.