Try Live
Add Docs
Rankings
Pricing
Docs
Install
Theme
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Bitbybit
https://github.com/bitbybit-dev/bitbybit
Admin
Bitbybit is an open-source platform providing core 3D algorithms and packages for geometry
...
Tokens:
721,797
Snippets:
1,801
Trust Score:
6.8
Update:
2 months ago
Context
Skills
Chat
Benchmark
78.9
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Bitbybit - Browser-Based 3D CAD Platform Bitbybit is a comprehensive open-source monorepo containing browser-based CAD (Computer-Aided Design) algorithms that enable parametric 3D modeling, geometry manipulation, and visualization. The platform wraps powerful CAD kernels including OpenCascade (OCCT), JSCAD, and Manifold, making industrial-grade geometry algorithms accessible in web browsers and Node.js environments through a unified TypeScript API. The library provides seamless integration with major 3D rendering engines (BabylonJS, ThreeJS, PlayCanvas), enabling developers to build interactive 3D configurators, product visualizers, and CAD applications. All CAD operations run asynchronously via web workers, ensuring non-blocking performance for complex geometric computations like boolean operations, fillets, extrusions, and STEP file import/export. --- ## Installation and Setup ### Installing the ThreeJS Package The ThreeJS integration package provides CAD capabilities with Three.js rendering. ```bash npm install @bitbybit-dev/threejs three ``` ```typescript import { BitByBitBase, Inputs, initBitByBit, initThreeJS, type InitBitByBitOptions } from "@bitbybit-dev/threejs"; async function start() { // Initialize ThreeJS scene const sceneOptions = new Inputs.ThreeJSScene.InitThreeJSDto(); sceneOptions.canvasId = "three-canvas"; sceneOptions.sceneSize = 10; const { scene, startAnimationLoop } = initThreeJS(sceneOptions); startAnimationLoop(); // Initialize BitByBit with desired CAD kernels const bitbybit = new BitByBitBase(); const options: InitBitByBitOptions = { enableOCCT: true, // OpenCascade for BREP modeling enableJSCAD: true, // JSCAD for CSG operations enableManifold: true, // Manifold for fast mesh booleans }; await initBitByBit(scene, bitbybit, options); // Now ready to create 3D geometry console.log("BitByBit initialized with ThreeJS"); } start(); ``` --- ### Installing the BabylonJS Package The BabylonJS integration provides CAD capabilities with Babylon.js rendering including shadows and ground plane. ```bash npm install @bitbybit-dev/babylonjs @babylonjs/core @babylonjs/gui @babylonjs/loaders ``` ```typescript import { BitByBitBase, Inputs, initBitByBit, initBabylonJS, type InitBitByBitOptions } from "@bitbybit-dev/babylonjs"; async function start() { // Initialize BabylonJS scene with shadows and ground const sceneOptions = new Inputs.BabylonJSScene.InitBabylonJSDto(); sceneOptions.canvasId = "babylon-canvas"; sceneOptions.sceneSize = 10; sceneOptions.enableShadows = true; sceneOptions.enableGround = true; sceneOptions.groundColor = "#333333"; const { scene, engine } = initBabylonJS(sceneOptions); const bitbybit = new BitByBitBase(); const options: InitBitByBitOptions = { enableOCCT: true, enableJSCAD: true, enableManifold: true, }; await initBitByBit(scene, bitbybit, options); // Start render loop engine.runRenderLoop(() => { if (scene.activeCamera) { scene.render(); } }); console.log("BitByBit initialized with BabylonJS"); } start(); ``` --- ## OCCT (OpenCascade) - Creating Solid Shapes ### Creating a Cube with Filleted Edges OpenCascade provides professional-grade BREP (Boundary Representation) modeling for precise solid geometry with fillets, chamfers, and boolean operations. ```typescript import { BitByBitBase, Inputs } from "@bitbybit-dev/threejs"; async function createRoundedCube(bitbybit: BitByBitBase) { // Create a cube solid const cubeOptions = new Inputs.OCCT.CubeDto(); cubeOptions.size = 2.5; cubeOptions.center = [0, 1.25, 0]; // [x, y, z] position const cube = await bitbybit.occt.shapes.solid.createCube(cubeOptions); // Apply fillet (rounded edges) to all edges const filletOptions = new Inputs.OCCT.FilletDto<Inputs.OCCT.TopoDSShapePointer>(); filletOptions.shape = cube; filletOptions.radius = 0.4; const roundedCube = await bitbybit.occt.fillets.filletEdges(filletOptions); // Draw the shape with custom styling const drawOptions = new Inputs.Draw.DrawOcctShapeOptions(); drawOptions.edgeWidth = 0.5; drawOptions.faceColour = "#ff0000"; drawOptions.drawVertices = true; drawOptions.vertexSize = 0.05; drawOptions.vertexColour = "#ffffff"; await bitbybit.draw.drawAnyAsync({ entity: roundedCube, options: drawOptions, }); return roundedCube; } ``` --- ### Creating Primitive Solids (Sphere, Cylinder, Cone, Torus) OCCT provides various primitive solid creation methods for common 3D shapes. ```typescript async function createPrimitiveSolids(bitbybit: BitByBitBase) { // Create a sphere const sphereOptions = new Inputs.OCCT.SphereDto(); sphereOptions.radius = 1.5; sphereOptions.center = [0, 0, 0]; const sphere = await bitbybit.occt.shapes.solid.createSphere(sphereOptions); // Create a cylinder const cylinderOptions = new Inputs.OCCT.CylinderDto(); cylinderOptions.radius = 1; cylinderOptions.height = 3; cylinderOptions.center = [4, 0, 0]; const cylinder = await bitbybit.occt.shapes.solid.createCylinder(cylinderOptions); // Create a cone const coneOptions = new Inputs.OCCT.ConeDto(); coneOptions.radius1 = 1.5; coneOptions.radius2 = 0.5; coneOptions.height = 2; coneOptions.center = [8, 0, 0]; const cone = await bitbybit.occt.shapes.solid.createCone(coneOptions); // Create a torus (donut shape) const torusOptions = new Inputs.OCCT.TorusDto(); torusOptions.radiusMajor = 2; torusOptions.radiusMinor = 0.5; torusOptions.center = [12, 0, 0]; const torus = await bitbybit.occt.shapes.solid.createTorus(torusOptions); // Draw all shapes const drawOptions = new Inputs.Draw.DrawOcctShapeOptions(); drawOptions.faceColour = "#4488ff"; await bitbybit.draw.drawAnyAsync({ entity: sphere, options: drawOptions }); await bitbybit.draw.drawAnyAsync({ entity: cylinder, options: drawOptions }); await bitbybit.draw.drawAnyAsync({ entity: cone, options: drawOptions }); await bitbybit.draw.drawAnyAsync({ entity: torus, options: drawOptions }); return { sphere, cylinder, cone, torus }; } ``` --- ### Boolean Operations (Union, Difference, Intersection) Boolean operations allow combining or subtracting solid shapes to create complex geometry. ```typescript async function booleanOperations(bitbybit: BitByBitBase) { // Create two overlapping shapes const box1 = await bitbybit.occt.shapes.solid.createBox({ width: 2, height: 2, length: 2, center: [0, 0, 0] }); const box2 = await bitbybit.occt.shapes.solid.createBox({ width: 2, height: 2, length: 2, center: [1, 1, 1] }); // Union: Combine two shapes into one const unionResult = await bitbybit.occt.booleans.union({ shapes: [box1, box2], keepEdges: false }); // Difference: Subtract second shape from first const sphere = await bitbybit.occt.shapes.solid.createSphere({ radius: 1.5, center: [0, 0, 0] }); const cube = await bitbybit.occt.shapes.solid.createCube({ size: 2, center: [0, 0, 0] }); const differenceResult = await bitbybit.occt.booleans.difference({ shape: cube, shapes: [sphere], keepEdges: false }); // Intersection: Keep only overlapping volume const intersectionResult = await bitbybit.occt.booleans.intersection({ shapes: [box1, box2], keepEdges: false }); // Draw results await bitbybit.draw.drawAnyAsync({ entity: unionResult }); await bitbybit.draw.drawAnyAsync({ entity: differenceResult }); await bitbybit.draw.drawAnyAsync({ entity: intersectionResult }); return { unionResult, differenceResult, intersectionResult }; } ``` --- ### Exporting to STEP File Format OCCT supports exporting geometry to industry-standard STEP format for CAD interoperability. ```typescript async function exportToStep(bitbybit: BitByBitBase, shape: Inputs.OCCT.TopoDSShapePointer) { // Export shape to STEP file and trigger download await bitbybit.occt.io.saveShapeSTEP({ shape: shape, fileName: "my-model", adjustYtoZ: true, // Convert Y-up to Z-up coordinate system tryDownload: true // Trigger browser download }); // Alternatively, get STEP content as string const stepContent = await bitbybit.occt.io.saveShapeSTEP({ shape: shape, fileName: "my-model", adjustYtoZ: true, tryDownload: false }); console.log("STEP file content length:", stepContent.length); return stepContent; } ``` --- ### Importing STEP Files Load existing CAD models from STEP format for viewing or further manipulation. ```typescript async function importStepFile(bitbybit: BitByBitBase) { // Import from URL const importedShape = await bitbybit.occt.io.loadSTEPorIGES({ filetext: await fetch('/models/part.step').then(r => r.text()), adjustZtoY: true // Convert Z-up to Y-up coordinate system }); // Draw the imported shape const drawOptions = new Inputs.Draw.DrawOcctShapeOptions(); drawOptions.faceColour = "#888888"; drawOptions.edgeColour = "#000000"; drawOptions.edgeWidth = 1; await bitbybit.draw.drawAnyAsync({ entity: importedShape, options: drawOptions }); return importedShape; } ``` --- ## JSCAD - CSG Solid Modeling ### Creating Shapes with JSCAD JSCAD provides Constructive Solid Geometry (CSG) operations for boolean-based modeling. ```typescript async function createJscadGeometry(bitbybit: BitByBitBase) { // Create a geodesic sphere (icosphere) const geodesicSphereOptions = new Inputs.JSCAD.GeodesicSphereDto(); geodesicSphereOptions.radius = 1.5; geodesicSphereOptions.center = [0, 1.5, 0]; const geodesicSphere = await bitbybit.jscad.shapes.geodesicSphere(geodesicSphereOptions); // Create a regular sphere const sphereOptions = new Inputs.JSCAD.SphereDto(); sphereOptions.radius = 1; sphereOptions.center = [0, 3, 0.5]; const simpleSphere = await bitbybit.jscad.shapes.sphere(sphereOptions); // Union two shapes together const unionOptions = new Inputs.JSCAD.BooleanTwoObjectsDto(); unionOptions.first = geodesicSphere; unionOptions.second = simpleSphere; const unionShape = await bitbybit.jscad.booleans.unionTwo(unionOptions); // Draw with custom color const drawOptions = new Inputs.Draw.DrawBasicGeometryOptions(); drawOptions.colours = "#0000ff"; await bitbybit.draw.drawAnyAsync({ entity: unionShape, options: drawOptions, }); return unionShape; } ``` --- ## Manifold - Fast Mesh Boolean Operations ### Creating and Manipulating Manifold Geometry Manifold provides extremely fast boolean operations on mesh geometry. ```typescript async function createManifoldGeometry(bitbybit: BitByBitBase) { // Create a sphere const sphereOptions = new Inputs.Manifold.SphereDto(); sphereOptions.radius = 1.5; sphereOptions.circularSegments = 32; const sphere = await bitbybit.manifold.manifold.shapes.sphere(sphereOptions); // Create a cube const cubeOptions = new Inputs.Manifold.CubeDto(); cubeOptions.size = 2.5; const cube = await bitbybit.manifold.manifold.shapes.cube(cubeOptions); // Boolean difference: cube minus sphere const diffedShape = await bitbybit.manifold.manifold.booleans.differenceTwo({ manifold1: cube, manifold2: sphere, }); // Transform: translate the result const translationOptions = new Inputs.Manifold.TranslateDto<Inputs.Manifold.ManifoldPointer>(); translationOptions.manifold = diffedShape; translationOptions.vector = [0, 1.25, -4]; const movedShape = await bitbybit.manifold.manifold.transforms.translate(translationOptions); // Draw with custom options const drawOptions = new Inputs.Draw.DrawManifoldOrCrossSectionOptions(); drawOptions.faceColour = "#00ff00"; await bitbybit.draw.drawAnyAsync({ entity: movedShape, options: drawOptions, }); return movedShape; } ``` --- ## Drawing and Visualization ### Drawing Any Geometry Type The unified draw API automatically detects geometry type and renders appropriately. ```typescript async function drawGeometry(bitbybit: BitByBitBase, scene: any) { // Draw points const points: Inputs.Base.Point3[] = [[0, 0, 0], [1, 1, 1], [2, 0, 0]]; await bitbybit.draw.drawAnyAsync({ entity: points, options: { colours: "#ff0000", size: 5 } }); // Draw polyline const polyline: Inputs.Base.Polyline3 = { points: [[0, 0, 0], [1, 2, 0], [2, 1, 0], [3, 2, 0]] }; await bitbybit.draw.drawAnyAsync({ entity: polyline, options: { colours: "#00ff00", size: 2 } }); // Draw OCCT shape with full options const cube = await bitbybit.occt.shapes.solid.createCube({ size: 1, center: [5, 0.5, 0] }); const occtDrawOptions = new Inputs.Draw.DrawOcctShapeOptions(); occtDrawOptions.faceColour = "#4488ff"; occtDrawOptions.edgeColour = "#000000"; occtDrawOptions.edgeWidth = 2; occtDrawOptions.drawEdges = true; occtDrawOptions.drawFaces = true; occtDrawOptions.drawVertices = false; await bitbybit.draw.drawAnyAsync({ entity: cube, options: occtDrawOptions }); } ``` --- ### Drawing a Grid Helper Create a visual grid on the ground plane for spatial reference. ```typescript function drawGrid(bitbybit: BitByBitBase) { const gridOptions = new Inputs.Draw.SceneDrawGridMeshDto(); gridOptions.width = 20; gridOptions.height = 20; gridOptions.subdivisions = 20; gridOptions.majorUnitFrequency = 5; gridOptions.minorUnitVisibility = 0.3; gridOptions.gridRatio = 0.5; gridOptions.mainColor = "#333333"; gridOptions.secondaryColor = "#666666"; gridOptions.opacity = 0.8; gridOptions.backFaceCulling = false; const gridMesh = bitbybit.draw.drawGridMesh(gridOptions); return gridMesh; } ``` --- ## Vector and Math Utilities ### Vector Operations The base package provides comprehensive vector math operations. ```typescript import { Vector } from "@bitbybit-dev/base"; function vectorOperations() { const vector = new Vector(/* dependencies injected */); // Create vectors const v1 = vector.vectorXYZ({ x: 1, y: 2, z: 3 }); // [1, 2, 3] const v2 = vector.vectorXYZ({ x: 4, y: 5, z: 6 }); // [4, 5, 6] // Basic operations const sum = vector.add({ first: v1, second: v2 }); // [5, 7, 9] const diff = vector.sub({ first: v2, second: v1 }); // [3, 3, 3] const scaled = vector.mul({ vector: v1, scalar: 2 }); // [2, 4, 6] const divided = vector.div({ vector: v2, scalar: 2 }); // [2, 2.5, 3] // Vector products const dotProduct = vector.dot({ first: v1, second: v2 }); // 32 const crossProduct = vector.cross({ first: v1, second: v2 }); // [-3, 6, -3] // Length and normalization const length = vector.length({ vector: v1 }); // 3.74... const normalized = vector.normalized({ vector: v1 }); // unit vector // Distance between points const distance = vector.dist({ first: v1, second: v2 }); // 5.196... // Angle between vectors (in degrees) const angle = vector.angleBetween({ first: v1, second: v2 }); // ~12.9 degrees // Linear interpolation const lerped = vector.lerp({ first: v1, second: v2, fraction: 0.5 }); // [2.5, 3.5, 4.5] return { sum, diff, scaled, dotProduct, crossProduct, length, normalized, distance, angle, lerped }; } ``` --- ### Creating Number Sequences Generate arrays of numbers for parametric modeling. ```typescript function createSequences() { const vector = new Vector(/* dependencies */); // Create range [0, 1, 2, 3, 4] const range = vector.range({ max: 5 }); // Create span with step: [0, 2, 4, 6, 8, 10] const span = vector.span({ min: 0, max: 10, step: 2 }); // Create evenly spaced items: [0, 2.5, 5, 7.5, 10] const linearItems = vector.spanLinearItems({ min: 0, max: 10, nrItems: 5 }); // Create eased distribution (accelerating intervals) const easedItems = vector.spanEaseItems({ min: 0, max: 100, nrItems: 5, ease: "easeInQuad", intervals: false }); return { range, span, linearItems, easedItems }; } ``` --- ## Complete Application Example ### Interactive Cup Configurator A complete example showing how to build a parametric 3D product configurator. ```typescript import { BitByBitBase, Inputs, initBitByBit, initThreeJS } from "@bitbybit-dev/threejs"; import { GUI } from "lil-gui"; interface CupModel { height: number; radius: number; thickness: number; color: string; } async function createCupConfigurator() { // Initialize scene const { scene, startAnimationLoop } = initThreeJS({ canvasId: "canvas", sceneSize: 20 }); startAnimationLoop(); const bitbybit = new BitByBitBase(); await initBitByBit(scene, bitbybit, { enableOCCT: true }); // Model state const model: CupModel = { height: 10, radius: 4, thickness: 0.8, color: "#4488ff" }; let currentShape: Inputs.OCCT.TopoDSShapePointer | undefined; // Create cup geometry async function createCup(): Promise<Inputs.OCCT.TopoDSShapePointer> { // Outer cylinder const outer = await bitbybit.occt.shapes.solid.createCylinder({ radius: model.radius, height: model.height, center: [0, model.height / 2, 0] }); // Inner cylinder (for hollow) const inner = await bitbybit.occt.shapes.solid.createCylinder({ radius: model.radius - model.thickness, height: model.height - model.thickness, center: [0, (model.height - model.thickness) / 2 + model.thickness, 0] }); // Subtract inner from outer to create hollow cup const cup = await bitbybit.occt.booleans.difference({ shape: outer, shapes: [inner], keepEdges: false }); // Fillet the top edge const filletedCup = await bitbybit.occt.fillets.filletEdges({ shape: cup, radius: model.thickness / 4 }); return filletedCup; } // Draw function async function updateDisplay() { // Clear previous if (currentShape) { // Note: In real app, also dispose Three.js meshes } currentShape = await createCup(); const drawOptions = new Inputs.Draw.DrawOcctShapeOptions(); drawOptions.faceColour = model.color; drawOptions.edgeColour = "#000000"; drawOptions.edgeWidth = 1; await bitbybit.draw.drawAnyAsync({ entity: currentShape, options: drawOptions }); } // Create GUI const gui = new GUI(); gui.add(model, "height", 5, 15, 0.1).name("Height").onFinishChange(updateDisplay); gui.add(model, "radius", 2, 8, 0.1).name("Radius").onFinishChange(updateDisplay); gui.add(model, "thickness", 0.3, 1.5, 0.1).name("Thickness").onFinishChange(updateDisplay); gui.addColor(model, "color").name("Color").onFinishChange(updateDisplay); gui.add({ downloadSTEP: async () => { if (currentShape) { await bitbybit.occt.io.saveShapeSTEP({ shape: currentShape, fileName: "cup", adjustYtoZ: true, tryDownload: true }); } } }, "downloadSTEP").name("Download STEP"); // Initial render await updateDisplay(); } createCupConfigurator(); ``` --- ## Summary Bitbybit provides a powerful, unified API for browser-based CAD development by wrapping three complementary geometry kernels: OpenCascade (OCCT) for precise BREP modeling with industrial features like fillets and STEP export, JSCAD for straightforward CSG operations, and Manifold for high-performance mesh booleans. The library's architecture separates concerns cleanly: the `@bitbybit-dev/base` package provides mathematical utilities, kernel-specific packages (`@bitbybit-dev/occt`, `@bitbybit-dev/jscad`, `@bitbybit-dev/manifold`) implement geometry algorithms, worker packages (`@bitbybit-dev/occt-worker`, etc.) enable non-blocking async execution, and engine packages (`@bitbybit-dev/babylonjs`, `@bitbybit-dev/threejs`, `@bitbybit-dev/playcanvas`) provide rendering integration. For integration, developers typically choose one rendering engine package which re-exports the core APIs, then initialize with `initBitByBit()` specifying which CAD kernels to load. The universal `draw.drawAnyAsync()` method handles visualization of any geometry type. Common use cases include interactive product configurators with real-time parameter updates, CAD file viewers supporting STEP/IGES import, geometry processing pipelines for manufacturing, and educational tools for teaching parametric design. The async worker architecture ensures smooth UI responsiveness even during complex operations like boolean computations on detailed models.