brepjs-claude-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +40 -0
- package/README.md +99 -0
- package/agents/brepjs-modeler.md +146 -0
- package/agents/brepjs-validator.md +72 -0
- package/commands/analyze.md +22 -0
- package/commands/brepjs.md +70 -0
- package/commands/export.md +34 -0
- package/commands/validate.md +23 -0
- package/examples/functional/cable-organizer.ts +40 -0
- package/examples/functional/pcb-mount.ts +50 -0
- package/examples/functional/phone-stand.ts +68 -0
- package/examples/functional/tool-holder.ts +50 -0
- package/examples/progressive/01-box-with-hole.ts +147 -0
- package/examples/progressive/02-bracket-with-fillets.ts +128 -0
- package/examples/progressive/03-gear-pair.ts +104 -0
- package/examples/progressive/04-helical-gear.ts +127 -0
- package/package.json +46 -0
- package/scripts/analyze-stl.js +256 -0
- package/scripts/validate-brepjs-file.sh +73 -0
- package/scripts/validate-plugin.sh +30 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "brepjs",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Generate production-ready CAD models using expert methodology",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "brepjs team",
|
|
7
|
+
"url": "https://github.com/andymai/brepjs"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/andymai/brepjs/tree/main/brepjs-plugin",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/andymai/brepjs",
|
|
13
|
+
"directory": "brepjs-plugin"
|
|
14
|
+
},
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"commands": [
|
|
17
|
+
"brepjs",
|
|
18
|
+
"brepjs:analyze",
|
|
19
|
+
"brepjs:validate",
|
|
20
|
+
"brepjs:export"
|
|
21
|
+
],
|
|
22
|
+
"agents": [
|
|
23
|
+
"brepjs-modeler",
|
|
24
|
+
"brepjs-validator"
|
|
25
|
+
],
|
|
26
|
+
"hooks": {
|
|
27
|
+
"PostToolUse": [
|
|
28
|
+
{
|
|
29
|
+
"matcher": "Write",
|
|
30
|
+
"command": "sh ${CLAUDE_PLUGIN_ROOT}/scripts/validate-brepjs-file.sh"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"requirements": {
|
|
35
|
+
"brepjs": ">=7.0.0",
|
|
36
|
+
"node": ">=18",
|
|
37
|
+
"typescript": ">=5.0.0"
|
|
38
|
+
},
|
|
39
|
+
"keywords": ["cad", "3d-modeling", "mechanical-design", "brepjs", "opencascade", "parametric"]
|
|
40
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# brepjs Plugin
|
|
2
|
+
|
|
3
|
+
Generate CAD models using expert methodology.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### From npm (recommended)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
claude-code plugins add brepjs-claude-plugin
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### From GitHub
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
claude-code plugins add https://github.com/andymai/brepjs/tree/main/brepjs-plugin
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Local development
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
claude-code plugins add ./brepjs-plugin
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Verify installation:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
claude-code plugins list | grep brepjs
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Commands
|
|
32
|
+
|
|
33
|
+
### `/brepjs <description>`
|
|
34
|
+
|
|
35
|
+
5-phase workflow: Clarify → Explore → Design → Implement → Validate
|
|
36
|
+
|
|
37
|
+
- Asks functional questions (INTO/ONTO/THROUGH?)
|
|
38
|
+
- Presents 2-3 approaches with trade-offs
|
|
39
|
+
- Generates parametric TypeScript
|
|
40
|
+
- Auto-validates geometry
|
|
41
|
+
|
|
42
|
+
### `/brepjs:analyze <file.stl>`
|
|
43
|
+
|
|
44
|
+
Quick STL analysis (dimensions, mesh quality, ASCII preview)
|
|
45
|
+
|
|
46
|
+
### `/brepjs:validate <file.ts>`
|
|
47
|
+
|
|
48
|
+
Run model and validate output
|
|
49
|
+
|
|
50
|
+
### `/brepjs:export <format>`
|
|
51
|
+
|
|
52
|
+
Export to STEP/GLTF/OBJ/SVG
|
|
53
|
+
|
|
54
|
+
## Agents
|
|
55
|
+
|
|
56
|
+
**brepjs-modeler** (sonnet) - Decomposes designs into B-REP operations
|
|
57
|
+
|
|
58
|
+
- Workflow selection: extrude/loft/revolve/sweep
|
|
59
|
+
- Profile management: < 80 points
|
|
60
|
+
- Auto-recovery on errors
|
|
61
|
+
|
|
62
|
+
**brepjs-validator** (haiku) - Validates geometry
|
|
63
|
+
|
|
64
|
+
- Checks: execution, volume, mesh quality, dimensions
|
|
65
|
+
- ASCII preview generation
|
|
66
|
+
|
|
67
|
+
## Key Patterns
|
|
68
|
+
|
|
69
|
+
**Profile Complexity:**
|
|
70
|
+
|
|
71
|
+
- Safe: < 60 points
|
|
72
|
+
- Risky: 60-80 points
|
|
73
|
+
- Fatal: > 100 points (auto-simplifies)
|
|
74
|
+
|
|
75
|
+
**Helical Geometry:**
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// ✓ Use loft (smooth)
|
|
79
|
+
loft([bottomWire, topWire], { ruled: false });
|
|
80
|
+
|
|
81
|
+
// ✗ Never stacked slices (stair-stepping)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Functional Requirements:**
|
|
85
|
+
|
|
86
|
+
- INTO → HOLLOW
|
|
87
|
+
- ONTO → SOLID with mounting
|
|
88
|
+
- THROUGH → HOLLOW channel
|
|
89
|
+
|
|
90
|
+
## Examples
|
|
91
|
+
|
|
92
|
+
Progressive: `examples/progressive/01-04` (simple → complex)
|
|
93
|
+
Functional: `examples/functional/` (real-world parts)
|
|
94
|
+
|
|
95
|
+
## Requirements
|
|
96
|
+
|
|
97
|
+
- brepjs >= 1.0.0
|
|
98
|
+
- Node.js >= 18
|
|
99
|
+
- TypeScript >= 5.0.0
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brepjs-modeler
|
|
3
|
+
description: 'Expert CAD modeler - decomposes designs into B-REP operations. Workflow selection: extrude/loft/revolve/sweep. Manages profile complexity < 80 points.'
|
|
4
|
+
tools: [Read, Write, Edit, Glob, Grep, Bash]
|
|
5
|
+
model: sonnet
|
|
6
|
+
color: blue
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# brepjs-modeler
|
|
10
|
+
|
|
11
|
+
## Core Task
|
|
12
|
+
|
|
13
|
+
Decompose user requirements into B-REP operations. Present 2-3 approaches with trade-offs.
|
|
14
|
+
|
|
15
|
+
## Decision Tree
|
|
16
|
+
|
|
17
|
+
### 1. Base Form Selection
|
|
18
|
+
|
|
19
|
+
- **2D profile** → extrude/revolve/loft/sweep
|
|
20
|
+
- **Primitive** → box/cylinder/sphere + booleans
|
|
21
|
+
- **Combination** → multiple primitives fused
|
|
22
|
+
|
|
23
|
+
### 2. 3D Transform Selection
|
|
24
|
+
|
|
25
|
+
- **Constant cross-section** → Extrude
|
|
26
|
+
- **Axially symmetric** → Revolve
|
|
27
|
+
- **Twisted/helical** → **Loft** (NEVER stacked slices)
|
|
28
|
+
- **Path-following** → Sweep
|
|
29
|
+
|
|
30
|
+
### 3. Profile Complexity
|
|
31
|
+
|
|
32
|
+
- **< 60 points**: Safe
|
|
33
|
+
- **60-80 points**: Risky but acceptable
|
|
34
|
+
- **> 80 points**: Fatal - auto-simplify
|
|
35
|
+
|
|
36
|
+
Auto-simplification: Reduce points per feature (8→6→4) until < 80
|
|
37
|
+
|
|
38
|
+
### 4. Functional Requirements (CRITICAL)
|
|
39
|
+
|
|
40
|
+
Ask first: "What goes INTO/ONTO/THROUGH this part?"
|
|
41
|
+
|
|
42
|
+
- **INTO** (tool/wire) → HOLLOW structure
|
|
43
|
+
- **ONTO** (mount) → SOLID with features
|
|
44
|
+
- **THROUGH** (cable) → HOLLOW channel
|
|
45
|
+
|
|
46
|
+
## Workflow for /brepjs Command
|
|
47
|
+
|
|
48
|
+
### Phase 2: Exploration
|
|
49
|
+
|
|
50
|
+
Search `examples/` for similar patterns. Report:
|
|
51
|
+
|
|
52
|
+
- Relevant files
|
|
53
|
+
- Profile complexity found
|
|
54
|
+
- Recommended workflow
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
rg "extrude|loft|revolve" examples/
|
|
58
|
+
rg "gear|tooth" examples/
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Phase 3: Design (Present 2-3 approaches)
|
|
62
|
+
|
|
63
|
+
Template:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
## Approach A: [Name]
|
|
67
|
+
Operations: 1. [step], 2. [step], 3. [step]
|
|
68
|
+
Profile: [N] points ([safe/risky/fatal])
|
|
69
|
+
Stability: ⭐⭐⭐⭐⭐ (5=rock solid)
|
|
70
|
+
Flexibility: ⭐⭐⭐⭐⭐ (5=parametric)
|
|
71
|
+
Trade-off: [key limitation]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Wait for user approval before Phase 4.
|
|
75
|
+
|
|
76
|
+
### Phase 4: Implementation
|
|
77
|
+
|
|
78
|
+
Generate TypeScript with:
|
|
79
|
+
|
|
80
|
+
- Parametric interface (JSDoc)
|
|
81
|
+
- Expert thinking comments: "// This is prismatic → extrude"
|
|
82
|
+
- Profile complexity note: "// 60 points (safe)"
|
|
83
|
+
- Validation function
|
|
84
|
+
- Export logic
|
|
85
|
+
|
|
86
|
+
## Critical Patterns
|
|
87
|
+
|
|
88
|
+
### Helical Geometry
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// ✓ CORRECT - Loft
|
|
92
|
+
const bottom = createProfile(0, 0);
|
|
93
|
+
const top = createProfile(height, rotated);
|
|
94
|
+
const gear = loft([bottomWire, topWire], { ruled: false });
|
|
95
|
+
|
|
96
|
+
// ✗ WRONG - Stacked slices (stair-stepping)
|
|
97
|
+
for (let i = 0; i < 8; i++) gear = gear.fuse(slice);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Gears
|
|
101
|
+
|
|
102
|
+
- Spur: 2D profile (6 pts/tooth) → extrude
|
|
103
|
+
- Helical: Bottom + top profiles → loft
|
|
104
|
+
- Profile at pitch circle (not random)
|
|
105
|
+
- Tooth flanks must engage
|
|
106
|
+
|
|
107
|
+
## Error Recovery
|
|
108
|
+
|
|
109
|
+
| Error | Action |
|
|
110
|
+
| ---------------- | -------------------------- |
|
|
111
|
+
| Profile > 80 pts | Auto-reduce points/feature |
|
|
112
|
+
| Boolean fails | Try `heal()` first |
|
|
113
|
+
| Loft crashes | Fallback to extrude, warn |
|
|
114
|
+
| WASM error | Add `initFromOC(oc)` |
|
|
115
|
+
|
|
116
|
+
Report recoveries: "⚠️ Profile simplified: 95 → 72 points"
|
|
117
|
+
|
|
118
|
+
## Code Structure
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import initOpenCascade from 'opencascade.js';
|
|
122
|
+
import { initFromOC, box, shape, exportSTL } from 'brepjs';
|
|
123
|
+
|
|
124
|
+
interface PartParams {
|
|
125
|
+
/** Dimension in mm */
|
|
126
|
+
width: number;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function createPart(params: PartParams) {
|
|
130
|
+
// Expert thinking: [workflow choice]
|
|
131
|
+
// Profile: [N] points (safe/risky)
|
|
132
|
+
|
|
133
|
+
// Implementation
|
|
134
|
+
return solid;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function main() {
|
|
138
|
+
const oc = await initOpenCascade();
|
|
139
|
+
initFromOC(oc);
|
|
140
|
+
|
|
141
|
+
const model = createPart({ width: 40 });
|
|
142
|
+
await exportSTL(model, 'output.stl', { tolerance: 0.1 });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
main().catch(console.error);
|
|
146
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brepjs-validator
|
|
3
|
+
description: 'Validates brepjs geometry. Runs TS models, analyzes STL output, checks mesh quality, verifies dimensions, detects issues.'
|
|
4
|
+
tools: [Bash, Read, Grep]
|
|
5
|
+
model: haiku
|
|
6
|
+
color: green
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# brepjs-validator
|
|
10
|
+
|
|
11
|
+
## Validation Checklist
|
|
12
|
+
|
|
13
|
+
### 1. Execution
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx tsx file.ts
|
|
17
|
+
# Check exit code, find STL output
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 2. Geometry
|
|
21
|
+
|
|
22
|
+
- Volume > 1e-9 (not empty)
|
|
23
|
+
- All dimensions > 0.1mm (no collapse)
|
|
24
|
+
- Bounding box valid
|
|
25
|
+
|
|
26
|
+
### 3. Mesh Quality
|
|
27
|
+
|
|
28
|
+
- Triangles > 0
|
|
29
|
+
- No NaN vertices
|
|
30
|
+
- Edge lengths reasonable (0.01-50mm)
|
|
31
|
+
- Degenerate triangles < 5 (edges > 50mm)
|
|
32
|
+
|
|
33
|
+
### 4. Dimensions
|
|
34
|
+
|
|
35
|
+
Compare actual vs expected (tolerance ±0.5mm)
|
|
36
|
+
|
|
37
|
+
### 5. ASCII Preview
|
|
38
|
+
|
|
39
|
+
Generate side view (60×20 chars)
|
|
40
|
+
|
|
41
|
+
## Report Format
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
=== VALIDATION REPORT ===
|
|
45
|
+
|
|
46
|
+
Execution: ✓/❌ [status]
|
|
47
|
+
Geometry: ✓/❌ [dimensions, volume]
|
|
48
|
+
Mesh Quality: ✓/⚠️/❌ [triangles, edges]
|
|
49
|
+
ASCII Preview: [visualization]
|
|
50
|
+
Overall: ✓/⚠️/❌ [result]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Issue Detection
|
|
54
|
+
|
|
55
|
+
| Issue | Cause | Fix |
|
|
56
|
+
| -------------------- | ---------------------------- | ----------------- |
|
|
57
|
+
| Zero volume | Boolean removed entire solid | Check positioning |
|
|
58
|
+
| Dimension < 0.1mm | Extrusion height = 0 | Check parameters |
|
|
59
|
+
| Degenerate triangles | Tolerance too high | Reduce to 0.1mm |
|
|
60
|
+
| NaN vertices | WASM corruption | Restart |
|
|
61
|
+
|
|
62
|
+
## Analysis Script (Three.js)
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js';
|
|
66
|
+
|
|
67
|
+
const geometry = loader.parse(stlBuffer);
|
|
68
|
+
geometry.computeBoundingBox();
|
|
69
|
+
|
|
70
|
+
// Check volume, edges, degenerate triangles
|
|
71
|
+
// Generate ASCII preview from XZ projection
|
|
72
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Analyze STL mesh quality and dimensions
|
|
3
|
+
argument-hint: <file.stl>
|
|
4
|
+
allowed-tools: [Read, Bash]
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /brepjs:analyze
|
|
9
|
+
|
|
10
|
+
Quick STL analysis.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
node "${CLAUDE_PLUGIN_ROOT}/scripts/analyze-stl.js" "$1"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Reports:
|
|
17
|
+
|
|
18
|
+
- File size, triangles
|
|
19
|
+
- Dimensions, volume
|
|
20
|
+
- Edge lengths
|
|
21
|
+
- Degenerate triangles
|
|
22
|
+
- ASCII preview
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate CAD models using expert methodology
|
|
3
|
+
argument-hint: <model description>
|
|
4
|
+
allowed-tools: [Read, Write, Edit, Glob, Grep, Bash, Task, AskUserQuestion]
|
|
5
|
+
model: sonnet
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /brepjs
|
|
9
|
+
|
|
10
|
+
5-phase workflow: Clarify → Explore → Design → Implement → Validate
|
|
11
|
+
|
|
12
|
+
## Phase 1: Requirements
|
|
13
|
+
|
|
14
|
+
Ask:
|
|
15
|
+
|
|
16
|
+
- What goes INTO/ONTO/THROUGH this part?
|
|
17
|
+
- Dimensions, tolerances?
|
|
18
|
+
- Manufacturing method?
|
|
19
|
+
- Complexity level?
|
|
20
|
+
|
|
21
|
+
Output: Functional requirements
|
|
22
|
+
|
|
23
|
+
## Phase 2: Exploration
|
|
24
|
+
|
|
25
|
+
Launch brepjs-modeler agent:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Explore examples/ for patterns relevant to: [description]
|
|
29
|
+
Report: files found, complexity, recommended workflow
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Phase 3: Design (Approval Required)
|
|
33
|
+
|
|
34
|
+
Agent presents 2-3 approaches:
|
|
35
|
+
|
|
36
|
+
- B-REP operations
|
|
37
|
+
- Profile complexity
|
|
38
|
+
- Stability/flexibility ratings
|
|
39
|
+
- Trade-offs
|
|
40
|
+
|
|
41
|
+
Use AskUserQuestion for approval.
|
|
42
|
+
|
|
43
|
+
## Phase 4: Implementation
|
|
44
|
+
|
|
45
|
+
Generate TypeScript file:
|
|
46
|
+
|
|
47
|
+
- Parametric interface
|
|
48
|
+
- Expert thinking comments
|
|
49
|
+
- Validation code
|
|
50
|
+
- STL export
|
|
51
|
+
|
|
52
|
+
## Phase 5: Validation (Approval Required)
|
|
53
|
+
|
|
54
|
+
Auto-hook validates:
|
|
55
|
+
|
|
56
|
+
- Runs file
|
|
57
|
+
- Analyzes STL
|
|
58
|
+
- Shows report + ASCII preview
|
|
59
|
+
|
|
60
|
+
Use AskUserQuestion for confirmation.
|
|
61
|
+
|
|
62
|
+
## Error Recovery
|
|
63
|
+
|
|
64
|
+
| Error | Recovery |
|
|
65
|
+
| ---------------- | ------------------- |
|
|
66
|
+
| Profile > 80 pts | Auto-simplify |
|
|
67
|
+
| Boolean fails | Try heal() |
|
|
68
|
+
| Loft crashes | Fallback to extrude |
|
|
69
|
+
|
|
70
|
+
Report recoveries to user.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Export CAD model to STEP, GLTF, OBJ, or SVG
|
|
3
|
+
argument-hint: <format>
|
|
4
|
+
allowed-tools: [Read, Edit, Bash]
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /brepjs:export
|
|
9
|
+
|
|
10
|
+
Export to different formats.
|
|
11
|
+
|
|
12
|
+
**Formats:**
|
|
13
|
+
|
|
14
|
+
- STEP: Exact geometry (CAD)
|
|
15
|
+
- GLTF: Web 3D
|
|
16
|
+
- OBJ: Rendering
|
|
17
|
+
- SVG: 2D projections
|
|
18
|
+
|
|
19
|
+
**Action:**
|
|
20
|
+
|
|
21
|
+
1. Find recent brepjs .ts file
|
|
22
|
+
2. Add export code
|
|
23
|
+
3. Run file
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// STEP
|
|
27
|
+
await exportSTEP(model, 'output.step');
|
|
28
|
+
|
|
29
|
+
// GLTF
|
|
30
|
+
await exportGLTF(model, 'output.gltf', { tolerance: 0.1 });
|
|
31
|
+
|
|
32
|
+
// SVG (projections)
|
|
33
|
+
await exportSVG(model, 'output-top.svg', { direction: [0, 0, -1] });
|
|
34
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Execute brepjs model and validate output geometry
|
|
3
|
+
argument-hint: <file.ts>
|
|
4
|
+
allowed-tools: [Bash, Read]
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /brepjs:validate
|
|
9
|
+
|
|
10
|
+
Run TS file and validate STL output.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
cd "$(dirname "$FILE")"
|
|
14
|
+
npx tsx "$(basename "$FILE")"
|
|
15
|
+
|
|
16
|
+
# Find generated STL
|
|
17
|
+
STL=$(find . -name "*.stl" -newer "$FILE" | head -1)
|
|
18
|
+
|
|
19
|
+
# Analyze
|
|
20
|
+
node "${CLAUDE_PLUGIN_ROOT}/scripts/analyze-stl.js" "$STL"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Reports: Execution status, geometry validity, mesh quality, dimensions.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cable Organizer with Snap-Fit
|
|
3
|
+
*
|
|
4
|
+
* Functional requirements:
|
|
5
|
+
* - THROUGH: Multiple cable channels
|
|
6
|
+
* - ONTO: Mounts to desk edge with clip
|
|
7
|
+
*
|
|
8
|
+
* Manufacturing: 3D printing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import initOpenCascade from 'opencascade.js';
|
|
12
|
+
import { initFromOC, box, cylinder, shape, exportSTL } from 'brepjs';
|
|
13
|
+
|
|
14
|
+
function createCableOrganizer() {
|
|
15
|
+
// Simplified implementation
|
|
16
|
+
const body = box(100, 30, 20);
|
|
17
|
+
|
|
18
|
+
// Cable channels
|
|
19
|
+
let organizer = shape(body).val;
|
|
20
|
+
|
|
21
|
+
for (let i = 0; i < 5; i++) {
|
|
22
|
+
const channel = cylinder(5, 22, {
|
|
23
|
+
at: [20 + i * 15, 15, -1],
|
|
24
|
+
});
|
|
25
|
+
organizer = shape(organizer).cut(channel).val;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return organizer;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function main() {
|
|
32
|
+
const oc = await initOpenCascade();
|
|
33
|
+
initFromOC(oc);
|
|
34
|
+
|
|
35
|
+
const model = createCableOrganizer();
|
|
36
|
+
await exportSTL(model, 'examples/output/cable-organizer.stl');
|
|
37
|
+
console.log('✓ Cable organizer generated');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PCB Mount with Standoffs
|
|
3
|
+
*
|
|
4
|
+
* Functional requirements:
|
|
5
|
+
* - ONTO: PCB sits on raised standoffs
|
|
6
|
+
* - Precise M3 mounting holes
|
|
7
|
+
* - Standard PCB dimensions (100×80mm)
|
|
8
|
+
*
|
|
9
|
+
* Manufacturing: CNC or 3D printing
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import initOpenCascade from 'opencascade.js';
|
|
13
|
+
import { initFromOC, box, cylinder, shape, exportSTL } from 'brepjs';
|
|
14
|
+
|
|
15
|
+
function createPCBMount() {
|
|
16
|
+
// Base plate
|
|
17
|
+
const base = box(120, 100, 3);
|
|
18
|
+
|
|
19
|
+
let mount = shape(base).val;
|
|
20
|
+
|
|
21
|
+
// Add 4 standoffs at PCB corners
|
|
22
|
+
const standoffPositions = [
|
|
23
|
+
[10, 10],
|
|
24
|
+
[110, 10],
|
|
25
|
+
[10, 90],
|
|
26
|
+
[110, 90],
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
for (const [x, y] of standoffPositions) {
|
|
30
|
+
const standoff = cylinder(4, 5, { at: [x, y, 3] });
|
|
31
|
+
mount = shape(mount).fuse(standoff).val;
|
|
32
|
+
|
|
33
|
+
// M3 mounting hole through standoff
|
|
34
|
+
const hole = cylinder(1.6, 10, { at: [x, y, 0] });
|
|
35
|
+
mount = shape(mount).cut(hole).val;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return mount;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function main() {
|
|
42
|
+
const oc = await initOpenCascade();
|
|
43
|
+
initFromOC(oc);
|
|
44
|
+
|
|
45
|
+
const model = createPCBMount();
|
|
46
|
+
await exportSTL(model, 'examples/output/pcb-mount.stl');
|
|
47
|
+
console.log('✓ PCB mount generated');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phone Stand with Cable Routing
|
|
3
|
+
*
|
|
4
|
+
* Functional requirements:
|
|
5
|
+
* - ONTO: Phone rests on angled surface
|
|
6
|
+
* - THROUGH: Cable routing channel for charging
|
|
7
|
+
* - Stable base, angled back support
|
|
8
|
+
*
|
|
9
|
+
* Manufacturing: 3D printing (FDM)
|
|
10
|
+
* Material: PLA/PETG
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import initOpenCascade from 'opencascade.js';
|
|
14
|
+
import { initFromOC, box, shape, exportSTL } from 'brepjs';
|
|
15
|
+
|
|
16
|
+
interface PhoneStandParams {
|
|
17
|
+
baseWidth: number;
|
|
18
|
+
baseDepth: number;
|
|
19
|
+
baseHeight: number;
|
|
20
|
+
backHeight: number;
|
|
21
|
+
angle: number; // Degrees from vertical
|
|
22
|
+
cableChannelWidth: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function createPhoneStand(params: PhoneStandParams) {
|
|
26
|
+
// Base plate
|
|
27
|
+
const base = box(params.baseWidth, params.baseDepth, params.baseHeight);
|
|
28
|
+
|
|
29
|
+
// Angled back support
|
|
30
|
+
// (Simplified - in real implementation would use rotation)
|
|
31
|
+
const back = box(params.baseWidth, 5, params.backHeight, {
|
|
32
|
+
at: [0, params.baseDepth - 5, params.baseHeight],
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
let stand = shape(base).fuse(back).val;
|
|
36
|
+
|
|
37
|
+
// Cable routing channel (hollow through base)
|
|
38
|
+
const channel = box(
|
|
39
|
+
params.cableChannelWidth,
|
|
40
|
+
params.baseDepth + 2,
|
|
41
|
+
params.baseHeight + 2,
|
|
42
|
+
{ at: [params.baseWidth / 2 - params.cableChannelWidth / 2, -1, -1] }
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
stand = shape(stand).cut(channel).val;
|
|
46
|
+
|
|
47
|
+
return stand;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function main() {
|
|
51
|
+
const oc = await initOpenCascade();
|
|
52
|
+
initFromOC(oc);
|
|
53
|
+
|
|
54
|
+
const params: PhoneStandParams = {
|
|
55
|
+
baseWidth: 80,
|
|
56
|
+
baseDepth: 60,
|
|
57
|
+
baseHeight: 10,
|
|
58
|
+
backHeight: 100,
|
|
59
|
+
angle: 70, // 70° from vertical
|
|
60
|
+
cableChannelWidth: 10,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const model = createPhoneStand(params);
|
|
64
|
+
await exportSTL(model, 'examples/output/phone-stand.stl');
|
|
65
|
+
console.log('✓ Phone stand generated');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
main().catch(console.error);
|