concept-collection / mesh-studio
mesh-studio
Go to fileHistoryFork
.claudeMove view controls into viewport overlay; add anaglyph 3D toggle
.githubInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
publicInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
srcMove view controls into viewport overlay; add anaglyph 3D toggle
.gitignoreInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
.oxlintrc.jsonInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
CLAUDE.mdMove view controls into viewport overlay; add anaglyph 3D toggle
index.htmlInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
package-lock.jsonInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
package.jsonInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
README.mdRemove Sample STEP button; make Random CAD model the primary source button
tsconfig.app.jsonInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
tsconfig.jsonInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
tsconfig.node.jsonInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)
vite.config.tsInitial commit: mesh-studio POC (OpenCASCADE.js + three.js, NURBS extraction)

mesh-studio#

A browser playground for producing surface meshes with different tools and inspecting them interactively in 3D (three.js). This is a proof-of-concept; the first mesh-producing tool wired in is OpenCASCADE.js (the OCCT CAD kernel compiled to WebAssembly).

Everything runs client-side — no server, no uploads.

What's interesting here#

CAD B-rep faces are not triangles: each face carries an underlying NURBS (rational B-spline) surface — a piecewise polynomial in two parameters. That is exactly the "high-order mesh / polynomials on faces" idea. mesh-studio extracts those polynomial patches (control points, weights, knots, degree) alongside the triangulation, so you can:

  • shade the tessellated surface, or view its wireframe;
  • see each face's control net (the polynomial's control polygon) and its isocurves (constant-parameter curves sampled on the true surface);
  • drag a resolution slider to re-tessellate the same NURBS faces from coarse-and-faceted to smooth;
  • click a face to read its degree, pole count, knot structure and whether it is rational or purely polynomial.

Sources (v1)#

  • Built-in primitives generated in-browser: sphere, torus, cylinder, cone, box, rounded box (free-form fillet faces), and the classic OCCT "bottle".
  • Random CAD model: downloads a random real-world model from abc-step-1000, a rehosted slice of the ABC dataset of CAD models (Koch et al., CVPR 2019).
  • STEP / IGES import: open a .step/.stp or .iges/.igs file — OCCT reads it natively.

Export#

  • OBJ / PLY / STL — the current triangulation.
  • NURBS patches (JSON) — the polynomial-native representation (degrees, poles, weights, knots per face).
  • STEP — the B-rep (original bytes for an imported file; re-written from the kernel for primitives).

Internal model#

The internal representation is deliberately broader than a triangle mesh so more tools can plug in later. A SurfaceModel is a list of patches, and a patch is a discriminated union (src/model/types.ts). v1 emits nurbs patches (each carrying both a triangulation and the B-spline surface); linear, lagrange and parametric kinds are reserved growth points for future tools.

Develop#

npm install
npm run dev      # http://localhost:5173
npm run build    # tsc -b && vite build  (bundles the ~30 MB OCCT wasm as an asset)
npm run lint

The OpenCASCADE runtime (~30 MB WASM) is loaded lazily on the first source action, not at page load.

Layout#

src/
  occ/        OpenCASCADE integration (all OCCT calls confined here)
    loader.ts     lazy singleton initOpenCascade({ mainWasm })
    primitives.ts BRepPrimAPI shape builders + the tutorial bottle
    importCad.ts  STEP/IGES readers via Emscripten FS
    exportCad.ts  STEPControl_Writer
    extract.ts    shape -> SurfaceModel: BRepMesh triangulation + NURBS extraction
  model/      types.ts (SurfaceModel/Patch) + tessellate.ts (pure geometry helpers)
  render/     SurfaceView.tsx (plain three.js) + palette.ts
  export/     meshWriters.ts (OBJ/PLY/STL) + nurbsJson.ts
  sources.ts  registry of built-in primitives
  App.tsx     sidebar UI + viewport

Part of the concept-collection org.