Add web port research

This commit is contained in:
Nettika 2026-01-28 14:36:34 -08:00
parent 9ca012e6c6
commit f8ce503a40
No known key found for this signature in database
2 changed files with 547 additions and 0 deletions

View file

@ -49,6 +49,7 @@ MatterControl is a comprehensive 3D printing workflow application built by Matte
| Document | Description |
| -------- | ----------- |
| [Design-Only Fork](design-only-fork.md) | Plan to strip MatterControl down to a pure 3D design/modeling application, removing all printing, slicing, and cloud features. |
| [Web Port Feasibility](web-port-feasibility.md) | Analysis of porting design features to a web app (JavaScript, WASM, WebGL). Includes technology mapping and timeline estimates. |
| [Linux Migration](linux-migration.md) | Feasibility of migrating the project from its many Windows-only dependencies to cross platform alternatives to fully support Linux. |
## Key Entry Points

View file

@ -0,0 +1,546 @@
# Feasibility Analysis: Porting MatterControl Design Features to Web
**Goal:** Evaluate porting the design-only features of MatterControl to a web application using JavaScript, WebAssembly, and WebGL.
## Executive Summary
| Component | Porting Difficulty | Recommended Approach |
|-----------|-------------------|---------------------|
| **3D Rendering** | Medium | WebGL 2.0 + three.js |
| **UI Framework** | High | React/Vue + custom Canvas widgets |
| **Mesh Operations** | Medium-High | WASM (C# via Blazor or manual port) |
| **File Formats** | Medium | JS parsers + pako for compression |
| **Persistence** | Low | IndexedDB + File API |
**Overall Assessment:** Feasible but substantial effort (4-6 months for MVP)
---
## Technology Stack Comparison
| Desktop (Current) | Web Equivalent |
|-------------------|----------------|
| .NET 6.0 (C#) | TypeScript + WASM |
| OpenGL 3.3 | WebGL 2.0 |
| agg-sharp (2D) | Canvas 2D API |
| GuiWidget (UI) | React/Vue components |
| SQLite | IndexedDB |
| File System | File API + virtual FS |
| Typography module | Web Fonts + Canvas text |
---
## 1. 3D Rendering (WebGL)
### Current Implementation
- OpenGL 3.3 with VAO/VBO/EBO
- GLSL 330 shaders (simple vertex → fragment)
- Custom `IOpenGL` abstraction layer
- Features: textures, lighting (2 directional), depth testing, face culling
### Web Porting Options
**Option A: three.js (Recommended)**
- Mature WebGL abstraction
- Built-in: cameras, raycasting, materials, scene graph
- Large ecosystem and documentation
- Handles WebGL 1.0/2.0 fallback
**Option B: Custom WebGL 2.0**
- More control, smaller bundle
- Requires implementing: shader management, buffer handling, picking
- Similar to current `IOpenGL` abstraction
**Option C: Babylon.js**
- Full game engine, heavier than three.js
- Excellent tooling and inspector
- May be overkill for CAD-style app
### Porting Complexity
| Feature | Desktop | Web Equivalent | Effort |
|---------|---------|----------------|--------|
| Mesh rendering | GLMeshTrianglePlugin | three.js BufferGeometry | Low |
| Camera control | TrackballTumbleWidget | three.js OrbitControls | Low |
| Picking/selection | Ray + BVH | three.js Raycaster | Low |
| Transform gizmos | Custom implementation | three.js TransformControls | Low |
| Wireframe overlay | GLMeshWirePlugin | three.js EdgesGeometry | Low |
| Texture mapping | ImageGlPlugin | three.js Texture | Low |
| **Total 3D rendering** | | | **2-3 weeks** |
---
## 2. UI Framework
### Current Implementation
- **GuiWidget**: Custom widget system with 2500+ line base class
- **Layout**: HAnchor/VAnchor enum-based positioning, FlowLayout
- **Widgets**: Button, TextEdit, Slider, Menu, ScrollableWidget, TreeView, etc.
- **Theming**: JSON-based ThemeConfig
- **Rendering**: agg-sharp software rasterization to ImageBuffer
### Web Porting Options
**Option A: React + CSS (Recommended)**
```
GuiWidget hierarchy → React component tree
HAnchor/VAnchor → CSS Flexbox
FlowLayoutWidget → flex-direction
ThemeConfig → CSS Custom Properties
Events → React synthetic events
```
**Option B: Vue + CSS**
- Similar mapping to React
- Reactive state management built-in
**Option C: Canvas-based (like current)**
- Port GuiWidget directly to Canvas 2D
- High effort, poor accessibility
- Not recommended
### Widget Mapping
| MatterControl Widget | Web Equivalent |
|---------------------|----------------|
| GuiWidget | React.Component + div |
| FlowLayoutWidget | Flexbox container |
| Button | `<button>` + CSS |
| TextEditWidget | `<input>` / `<textarea>` |
| Slider | `<input type="range">` + custom |
| ScrollableWidget | `overflow: auto` |
| Menu/DropDownList | Headless UI / Radix |
| TreeView | react-arborist or custom |
| TabControl | Headless Tabs |
| ColorPicker | react-colorful |
### Special Widgets (Canvas-based)
Some widgets need Canvas 2D rendering:
- **View3DWidget** → WebGL canvas
- **GCode2DWidget** → Canvas 2D (if keeping G-code preview)
- **Custom sliders** → SVG or Canvas
**Estimated effort: 4-6 weeks** (most time-consuming component)
---
## 3. Mesh & Geometry Operations
### Current Implementation
- **PolygonMesh**: Mesh data structure (Vector3Float vertices, faces)
- **geometry3Sharp**: Comprehensive geometry library (DMesh3, CSG, smoothing)
- **Clipper**: 2D polygon clipping (64-bit integers)
- **All pure C#** - no native dependencies
### Porting Options
**Option A: WebAssembly (C# via Blazor)**
- Compile existing C# to WASM
- Minimal code changes
- ~2-3MB WASM bundle (includes .NET runtime)
- Full geometry3Sharp available
**Option B: WebAssembly (Rust) - Recommended for Performance**
- Native WASM target via `wasm-bindgen` + `wasm-pack`
- No garbage collection = smaller bundles (~100KB-500KB)
- Excellent performance (comparable to native)
- Strong ecosystem for geometry (see below)
- Steeper learning curve, requires rewrite
**Option C: WebAssembly (Emscripten/C++)**
- Translate C# → C++ → WASM
- Good performance, medium bundle size
- Significant translation effort
- Can wrap existing C++ libraries (CGAL, OpenCascade)
**Option D: JavaScript/TypeScript port**
- Manual translation to TypeScript
- Use existing JS libraries where possible
- Best for simple operations, slow for complex
**Option E: Hybrid (Practical Choice)**
- Simple ops in JS (transforms, normals)
- Complex ops in WASM (CSG, smoothing)
- Use existing JS libraries (jscad, csg.js)
---
### Rust → WASM Deep Dive
**Why Rust is compelling:**
| Factor | Rust | C# (Blazor) | C++ (Emscripten) |
|--------|------|-------------|------------------|
| Bundle size | ~100-500KB | ~2-3MB | ~500KB-2MB |
| Runtime overhead | None (no GC) | .NET runtime | Minimal |
| Performance | Excellent | Good | Excellent |
| Memory safety | Compile-time | Runtime | Manual |
| WASM tooling | First-class | Mature | Mature |
| Learning curve | Steep | Low (existing code) | Medium |
**Rust geometry ecosystem:**
| Library | Purpose | Maturity |
|---------|---------|----------|
| `nalgebra` | Linear algebra (vectors, matrices, transforms) | Excellent |
| `parry3d` | Collision detection, ray casting, BVH | Excellent |
| `ncollide3d` | Older collision library | Good |
| `rstar` | R-tree spatial indexing | Good |
| `geo` | 2D geometry operations | Excellent |
| `meshopt` | Mesh optimization (simplification) | Good |
| `lyon` | 2D path tessellation | Excellent |
| `truck` | B-rep CAD kernel (experimental) | Early |
**What's missing in Rust (would need implementation):**
- Full mesh boolean/CSG (partial in `parry3d`)
- Marching cubes
- Laplacian smoothing
- Mesh repair algorithms
- AMF/3MF file parsers
**Rust WASM workflow:**
```bash
# Setup
cargo install wasm-pack
# Build
wasm-pack build --target web
# Output: pkg/
# - mesh_ops.js (JS bindings)
# - mesh_ops_bg.wasm (WASM binary)
# - mesh_ops.d.ts (TypeScript types)
```
**Example Rust mesh module:**
```rust
use wasm_bindgen::prelude::*;
use nalgebra::{Point3, Vector3};
#[wasm_bindgen]
pub struct Mesh {
vertices: Vec<Point3<f32>>,
indices: Vec<u32>,
}
#[wasm_bindgen]
impl Mesh {
#[wasm_bindgen(constructor)]
pub fn new() -> Mesh {
Mesh { vertices: vec![], indices: vec![] }
}
pub fn add_vertex(&mut self, x: f32, y: f32, z: f32) {
self.vertices.push(Point3::new(x, y, z));
}
pub fn compute_normals(&self) -> Vec<f32> {
// Fast normal computation
}
pub fn simplify(&mut self, target_ratio: f32) {
// Mesh decimation using meshopt
}
}
```
**Feasibility assessment for Rust:**
| Task | Effort | Notes |
|------|--------|-------|
| Basic mesh ops (transforms, normals) | 1-2 weeks | Use nalgebra |
| Spatial queries (BVH, ray casting) | 1 week | Use parry3d |
| Mesh simplification | 1 week | Use meshopt |
| CSG boolean operations | 3-4 weeks | Partial parry3d, or port |
| Marching cubes | 1-2 weeks | Port from geometry3Sharp |
| Laplacian smoothing | 1 week | Port algorithm |
| File I/O (STL, OBJ) | 1 week | Existing crates available |
| **Total** | **10-14 weeks** | For full geometry3Sharp equivalent |
**Recommendation:**
For a **new web CAD project**, Rust → WASM is the better long-term choice:
- Smaller bundles, better performance
- No runtime overhead
- Growing ecosystem
For **porting MatterControl specifically**, the hybrid approach is more practical:
- Use existing JS/TS for UI and simple geometry
- Use Rust WASM for performance-critical operations (CSG, simplification)
- Consider wrapping existing Rust libraries rather than porting C#
**Existing Rust WASM CAD projects to reference:**
- `truck` - B-rep CAD kernel (early stage)
- `opencascade-rs` - OpenCascade Rust bindings (can compile to WASM)
- `manifold` - Google's CSG library has Rust bindings
### Performance Tiers
| Operation | JS Performance | WASM Needed? |
|-----------|---------------|--------------|
| Primitive generation | Fast | No |
| Transforms (rotate, scale) | Fast | No |
| Normal calculation | Fast | No |
| Vertex merging | Medium | Recommended |
| BVH construction | Medium | Recommended |
| **CSG boolean ops** | Slow | **Yes** |
| **Mesh smoothing** | Slow | **Yes** |
| **Marching cubes** | Very slow | **Yes** |
| **Mesh simplification** | Slow | **Yes** |
### Existing JS Libraries
| Operation | Library | Notes |
|-----------|---------|-------|
| CSG | csg.js, jscad | Reasonable performance |
| Mesh simplification | simplify-js | Basic implementation |
| Clipper polygons | js-clipper | Port of Clipper |
| STL parsing | three.js STLLoader | Built-in |
| OBJ parsing | three.js OBJLoader | Built-in |
**Estimated effort: 3-4 weeks** (using existing libraries + selective WASM)
---
## 4. File Format Support
### Current Formats
- **STL**: Binary/ASCII (three.js has loader)
- **OBJ**: With MTL materials (three.js has loader)
- **AMF**: XML + ZIP compression
- **3MF**: XML + ZIP archive
- **MCX**: Custom JSON/ZIP format
### Web Implementation
| Format | Parser | Compression | Effort |
|--------|--------|-------------|--------|
| STL | three.js STLLoader | None | Trivial |
| OBJ | three.js OBJLoader | None | Trivial |
| AMF | Custom XML parser | pako (zlib) | Medium |
| 3MF | Custom XML parser | JSZip | Medium |
| MCX | JSON.parse | JSZip | Low |
### File API Usage
```javascript
// File input
<input type="file" accept=".stl,.obj,.amf,.3mf,.mcx" />
// Drag and drop
element.addEventListener('drop', handleFiles);
// File System Access API (modern browsers)
const handle = await window.showOpenFilePicker();
const file = await handle.getFile();
```
### Large File Handling
- Use `FileReader` with chunked reading
- Stream parsing for STL (avoid loading entire file)
- Web Workers for parsing (non-blocking UI)
**Estimated effort: 1-2 weeks**
---
## 5. Persistence Layer
### Current Implementation
- **SQLite**: Tables for library, settings, history
- **File System**: Direct file access for library items
- **JSON**: Settings and scene serialization
### Web Implementation
**IndexedDB** (replaces SQLite):
```javascript
// Library structure
const db = await openDB('MatterControl', 1, {
upgrade(db) {
db.createObjectStore('library', { keyPath: 'id' });
db.createObjectStore('settings', { keyPath: 'key' });
db.createObjectStore('meshCache', { keyPath: 'hash' });
}
});
```
**LocalStorage** (for simple settings):
```javascript
localStorage.setItem('theme', 'dark');
localStorage.setItem('recentFiles', JSON.stringify([...]));
```
**Cache API** (for thumbnails and assets):
```javascript
const cache = await caches.open('thumbnails');
await cache.put(url, response);
```
### Migration Path
| Desktop | Web |
|---------|-----|
| `PrintItemCollection` table | IndexedDB `library` store |
| `PrintItem` table | IndexedDB `items` store |
| `SystemSetting` table | localStorage |
| `UserSetting` table | localStorage |
| File system paths | IndexedDB blob storage |
| Thumbnails | Cache API |
**Estimated effort: 1 week**
---
## 6. Design Tools (DesignTools/)
### What Needs Porting
The DesignTools module is **independent of printing** and includes:
**Primitives:**
- Box, Sphere, Cylinder, Cone, Torus
- Text (3D text generation)
- Image to 3D (heightmap, lithophane)
**Operations:**
- Boolean (Union, Subtract, Intersect)
- Transform (Rotate, Scale, Mirror, Array)
- Mesh (Repair, Decimate, Hollow, Twist, Pinch)
- Path (Extrude, Revolve, Offset)
### Porting Strategy
Most primitives are simple geometry generation:
```typescript
// Example: Box primitive in TypeScript
function createBox(width: number, height: number, depth: number): BufferGeometry {
return new THREE.BoxGeometry(width, height, depth);
}
```
For complex operations, use existing libraries or WASM:
- **Boolean ops**: csg.js or WASM port
- **Text**: opentype.js for font parsing + three.js TextGeometry
- **Mesh repair**: Custom or WASM
**Estimated effort: 2-3 weeks** (leveraging three.js primitives)
---
## 7. Architecture Recommendation
### Recommended Stack
```
┌─────────────────────────────────────────┐
│ React + TypeScript │
│ (UI Components, State) │
├─────────────────────────────────────────┤
│ three.js │
│ (3D Rendering, Scene Graph) │
├─────────────────────────────────────────┤
│ Web Workers + WASM │
│ (Heavy computation: CSG, smoothing) │
├─────────────────────────────────────────┤
│ IndexedDB + File API + Cache │
│ (Persistence, Files) │
└─────────────────────────────────────────┘
```
### Key Libraries
| Purpose | Library |
|---------|---------|
| 3D rendering | three.js |
| UI framework | React + Tailwind |
| State management | Zustand or Jotai |
| File parsing | three.js loaders + custom |
| CSG operations | csg.js or manifold (WASM) |
| Compression | pako + JSZip |
| Persistence | idb (IndexedDB wrapper) |
### Project Structure
```
src/
├── components/ # React UI components
│ ├── Viewport/ # 3D view
│ ├── Library/ # File browser
│ ├── Properties/ # Object properties
│ └── Toolbar/ # Tools and actions
├── core/
│ ├── scene/ # Scene graph management
│ ├── mesh/ # Mesh operations
│ ├── primitives/ # Geometry generators
│ └── io/ # File import/export
├── workers/
│ ├── csg.worker.ts # CSG operations
│ └── parse.worker.ts # File parsing
├── store/ # State management
└── utils/ # Helpers
```
---
## 8. Timeline Estimate
| Phase | Duration | Deliverable |
|-------|----------|-------------|
| **Phase 1: Core** | 4 weeks | 3D viewport, basic UI, file loading |
| **Phase 2: Primitives** | 2 weeks | All primitive shapes |
| **Phase 3: Operations** | 3 weeks | Boolean, transforms, basic mesh ops |
| **Phase 4: Polish** | 2 weeks | Library, persistence, export |
| **Phase 5: Advanced** | 3 weeks | Complex mesh ops (WASM) |
| **Buffer** | 2 weeks | Testing, optimization |
| **Total** | **16 weeks** | Full design-only web app |
---
## 9. Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| CSG performance | High | Use WASM (manifold library) |
| Large file handling | Medium | Streaming parsers, Web Workers |
| Browser compatibility | Medium | Target modern browsers, polyfills |
| Memory limits | Medium | Lazy loading, mesh LOD |
| UI complexity | High | Start with essential features |
---
## 10. Alternative: Existing Web CAD Libraries
Before building from scratch, consider:
| Library | Pros | Cons |
|---------|------|------|
| **OpenCascade.js** | Full CAD kernel, BREP | Large (~30MB), complex |
| **JSCAD** | CSG-focused, small | Limited mesh operations |
| **CadQuery (WASM)** | Python CAD in browser | Experimental |
| **three.js + csg.js** | Lightweight, flexible | Basic CSG only |
| **Manifold (WASM)** | Fast CSG, Google-backed | New, limited docs |
**Recommendation:** Start with three.js + manifold (WASM) for CSG, add features incrementally.
---
## Conclusion
**Porting MatterControl design features to web is feasible** with these considerations:
1. **Use three.js** for 3D rendering - don't reinvent the wheel
2. **Use React** for UI - better than porting GuiWidget
3. **Use WASM selectively** for CPU-intensive operations (CSG, mesh processing)
4. **Leverage existing parsers** (three.js loaders, JSZip)
5. **Start minimal** - viewport + primitives + basic transforms first
**Estimated total effort: 4-6 months** for a production-quality design-only web app.
The biggest challenges are:
- UI complexity (4-6 weeks)
- CSG/mesh operations (3-4 weeks with WASM)
- Matching the feature richness of desktop app
A simpler approach would be using OpenCascade.js or similar existing web CAD framework as the foundation.