cyclecad 3.2.1 → 3.5.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.md +155 -1
- package/DOCKER-SETUP-VERIFICATION.md +399 -0
- package/DOCKER-TESTING.md +463 -0
- package/FUSION360_MODULES.md +478 -0
- package/FUSION_MODULES_README.md +352 -0
- package/INTEGRATION_SNIPPETS.md +608 -0
- package/KILLER-FEATURES-DELIVERY.md +469 -0
- package/MODULES_SUMMARY.txt +337 -0
- package/QUICK_REFERENCE.txt +298 -0
- package/README-DOCKER-TESTING.txt +438 -0
- package/app/index.html +23 -10
- package/app/js/fusion-help.json +1808 -0
- package/app/js/help-module-v3.js +1096 -0
- package/app/js/killer-features-help.json +395 -0
- package/app/js/killer-features.js +1508 -0
- package/app/js/modules/fusion-assembly.js +842 -0
- package/app/js/modules/fusion-cam.js +785 -0
- package/app/js/modules/fusion-data.js +814 -0
- package/app/js/modules/fusion-drawing.js +844 -0
- package/app/js/modules/fusion-inspection.js +756 -0
- package/app/js/modules/fusion-render.js +774 -0
- package/app/js/modules/fusion-simulation.js +986 -0
- package/app/js/modules/fusion-sketch.js +1044 -0
- package/app/js/modules/fusion-solid.js +1095 -0
- package/app/js/modules/fusion-surface.js +949 -0
- package/app/tests/FUSION_TEST_SUITE.md +266 -0
- package/app/tests/README.md +77 -0
- package/app/tests/TESTING-CHECKLIST.md +177 -0
- package/app/tests/TEST_SUITE_SUMMARY.txt +236 -0
- package/app/tests/brep-live-test.html +848 -0
- package/app/tests/docker-integration-test.html +811 -0
- package/app/tests/fusion-all-tests.html +670 -0
- package/app/tests/fusion-assembly-tests.html +461 -0
- package/app/tests/fusion-cam-tests.html +421 -0
- package/app/tests/fusion-simulation-tests.html +421 -0
- package/app/tests/fusion-sketch-tests.html +613 -0
- package/app/tests/fusion-solid-tests.html +529 -0
- package/app/tests/index.html +453 -0
- package/app/tests/killer-features-test.html +509 -0
- package/app/tests/run-tests.html +874 -0
- package/app/tests/step-import-live-test.html +1115 -0
- package/app/tests/test-agent-v3.html +93 -696
- package/architecture-dashboard.html +1970 -0
- package/docs/API-REFERENCE.md +1423 -0
- package/docs/BREP-LIVE-TEST-GUIDE.md +453 -0
- package/docs/DEVELOPER-GUIDE-v3.md +795 -0
- package/docs/DOCKER-QUICK-TEST.md +376 -0
- package/docs/FUSION-FEATURES-GUIDE.md +2513 -0
- package/docs/FUSION-TUTORIAL.md +1203 -0
- package/docs/INFRASTRUCTURE-GUIDE-INDEX.md +327 -0
- package/docs/KEYBOARD-SHORTCUTS.md +402 -0
- package/docs/KILLER-FEATURES-INTEGRATION.md +412 -0
- package/docs/KILLER-FEATURES-SUMMARY.md +424 -0
- package/docs/KILLER-FEATURES-TUTORIAL.md +784 -0
- package/docs/KILLER-FEATURES.md +562 -0
- package/docs/QUICK-REFERENCE.md +282 -0
- package/docs/README-v3-DOCS.md +274 -0
- package/docs/TUTORIAL-v3.md +1190 -0
- package/docs/architecture-dashboard.html +1970 -0
- package/docs/architecture-v3.html +1038 -0
- package/linkedin-post-v3.md +58 -0
- package/package.json +1 -1
- package/scripts/dev-setup.sh +338 -0
- package/scripts/docker-health-check.sh +159 -0
- package/scripts/integration-test.sh +311 -0
- package/scripts/test-docker.sh +515 -0
|
@@ -0,0 +1,1423 @@
|
|
|
1
|
+
# cycleCAD Agent API Reference
|
|
2
|
+
|
|
3
|
+
Complete documentation of the cycleCAD API for AI agents, external tools, and programmatic access.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## TABLE OF CONTENTS
|
|
8
|
+
|
|
9
|
+
1. [Overview](#overview)
|
|
10
|
+
2. [Authentication and Setup](#authentication-and-setup)
|
|
11
|
+
3. [Shape Namespace](#shape-namespace)
|
|
12
|
+
4. [Feature Namespace](#feature-namespace)
|
|
13
|
+
5. [Assembly Namespace](#assembly-namespace)
|
|
14
|
+
6. [Render Namespace](#render-namespace)
|
|
15
|
+
7. [Validate Namespace](#validate-namespace)
|
|
16
|
+
8. [Simulate Namespace](#simulate-namespace)
|
|
17
|
+
9. [CAM Namespace](#cam-namespace)
|
|
18
|
+
10. [Drawing Namespace](#drawing-namespace)
|
|
19
|
+
11. [Data Namespace](#data-namespace)
|
|
20
|
+
12. [Error Handling](#error-handling)
|
|
21
|
+
13. [Code Examples](#code-examples)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## OVERVIEW
|
|
26
|
+
|
|
27
|
+
### API Style
|
|
28
|
+
- **Protocol**: JSON-RPC 2.0 over HTTP/WebSocket
|
|
29
|
+
- **Base URL**: `https://cyclecad.com/api/v1/` or `ws://cyclecad-local:8787`
|
|
30
|
+
- **Authentication**: API key in header or token in body
|
|
31
|
+
- **Content-Type**: `application/json`
|
|
32
|
+
|
|
33
|
+
### Request Format
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"jsonrpc": "2.0",
|
|
37
|
+
"method": "shape.cylinder",
|
|
38
|
+
"params": {
|
|
39
|
+
"diameter": 50,
|
|
40
|
+
"height": 80,
|
|
41
|
+
"sketch_plane": "XY"
|
|
42
|
+
},
|
|
43
|
+
"id": 1
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Response Format
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"jsonrpc": "2.0",
|
|
51
|
+
"result": {
|
|
52
|
+
"status": "success",
|
|
53
|
+
"body_id": "body_001",
|
|
54
|
+
"geometry": {
|
|
55
|
+
"volume": 157079.6,
|
|
56
|
+
"mass": 423.92,
|
|
57
|
+
"bbox": { "min": [-25, -25, 0], "max": [25, 25, 80] }
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"id": 1
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Error Response
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"jsonrpc": "2.0",
|
|
68
|
+
"error": {
|
|
69
|
+
"code": -32602,
|
|
70
|
+
"message": "Invalid parameters",
|
|
71
|
+
"data": {
|
|
72
|
+
"field": "diameter",
|
|
73
|
+
"reason": "must be > 0"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"id": 1
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## AUTHENTICATION AND SETUP
|
|
83
|
+
|
|
84
|
+
### Initialize Session
|
|
85
|
+
```
|
|
86
|
+
POST /auth/init
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Request:**
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"api_key": "sk_live_abc123xyz"
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Response:**
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"status": "success",
|
|
100
|
+
"session_id": "sess_123xyz",
|
|
101
|
+
"token": "bearer_token_xyz",
|
|
102
|
+
"expires_in": 3600
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Get API Schema
|
|
107
|
+
```
|
|
108
|
+
GET /schema
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Returns complete schema for all methods, parameters, and return values.
|
|
112
|
+
|
|
113
|
+
**Response:**
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"version": "1.0",
|
|
117
|
+
"namespaces": [
|
|
118
|
+
{
|
|
119
|
+
"name": "shape",
|
|
120
|
+
"methods": [
|
|
121
|
+
{
|
|
122
|
+
"name": "cylinder",
|
|
123
|
+
"description": "Create 3D cylinder",
|
|
124
|
+
"params": {...},
|
|
125
|
+
"returns": {...}
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## SHAPE NAMESPACE
|
|
136
|
+
|
|
137
|
+
Geometric primitives and basic shape creation.
|
|
138
|
+
|
|
139
|
+
### shape.cylinder
|
|
140
|
+
**Create 3D cylinder**
|
|
141
|
+
|
|
142
|
+
**Parameters:**
|
|
143
|
+
- `diameter` (number, required): Cylinder diameter in mm
|
|
144
|
+
- `height` (number, required): Cylinder height in mm
|
|
145
|
+
- `center` (object, optional): Center point {x, y, z}, default [0,0,0]
|
|
146
|
+
- `name` (string, optional): Feature name, default "Cylinder"
|
|
147
|
+
|
|
148
|
+
**Returns:**
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"body_id": "body_001",
|
|
152
|
+
"feature_id": "cylinder_001",
|
|
153
|
+
"geometry": {
|
|
154
|
+
"volume": 157079.6,
|
|
155
|
+
"surface_area": 7853.98,
|
|
156
|
+
"mass": 423.92,
|
|
157
|
+
"bbox": { "min": [-25, -25, 0], "max": [25, 25, 80] }
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Example:**
|
|
163
|
+
```javascript
|
|
164
|
+
const result = await cyclecad.execute({
|
|
165
|
+
method: "shape.cylinder",
|
|
166
|
+
params: {
|
|
167
|
+
diameter: 50,
|
|
168
|
+
height: 80,
|
|
169
|
+
center: [0, 0, 0],
|
|
170
|
+
name: "Main Shaft"
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
// Result: body_id = "body_001"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### shape.box
|
|
179
|
+
**Create rectangular box**
|
|
180
|
+
|
|
181
|
+
**Parameters:**
|
|
182
|
+
- `width` (number, required): Width (X) in mm
|
|
183
|
+
- `height` (number, required): Height (Z) in mm
|
|
184
|
+
- `depth` (number, required): Depth (Y) in mm
|
|
185
|
+
- `center` (object, optional): Center point {x, y, z}
|
|
186
|
+
- `name` (string, optional): Feature name
|
|
187
|
+
|
|
188
|
+
**Returns:** Same as cylinder (body_id, geometry, etc.)
|
|
189
|
+
|
|
190
|
+
**Example:**
|
|
191
|
+
```javascript
|
|
192
|
+
const box = await cyclecad.execute({
|
|
193
|
+
method: "shape.box",
|
|
194
|
+
params: {
|
|
195
|
+
width: 100,
|
|
196
|
+
height: 50,
|
|
197
|
+
depth: 75
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
### shape.sphere
|
|
205
|
+
**Create sphere**
|
|
206
|
+
|
|
207
|
+
**Parameters:**
|
|
208
|
+
- `diameter` (number, required): Sphere diameter in mm
|
|
209
|
+
- `center` (object, optional): Center point {x, y, z}
|
|
210
|
+
- `name` (string, optional): Feature name
|
|
211
|
+
|
|
212
|
+
**Returns:** Body geometry with volume, surface area, etc.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
### shape.cone
|
|
217
|
+
**Create cone**
|
|
218
|
+
|
|
219
|
+
**Parameters:**
|
|
220
|
+
- `base_diameter` (number, required): Base diameter in mm
|
|
221
|
+
- `height` (number, required): Cone height in mm
|
|
222
|
+
- `apex_offset` (number, optional): Offset from center (creates truncated cone)
|
|
223
|
+
- `center` (object, optional): Base center point
|
|
224
|
+
- `name` (string, optional): Feature name
|
|
225
|
+
|
|
226
|
+
**Returns:** Body geometry
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### shape.torus
|
|
231
|
+
**Create torus (donut)**
|
|
232
|
+
|
|
233
|
+
**Parameters:**
|
|
234
|
+
- `outer_diameter` (number, required): Outer diameter in mm
|
|
235
|
+
- `tube_diameter` (number, required): Tube diameter in mm
|
|
236
|
+
- `center` (object, optional): Center point {x, y, z}
|
|
237
|
+
- `name` (string, optional): Feature name
|
|
238
|
+
|
|
239
|
+
**Returns:** Body geometry
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
### shape.wedge
|
|
244
|
+
**Create wedge/triangular prism**
|
|
245
|
+
|
|
246
|
+
**Parameters:**
|
|
247
|
+
- `width` (number, required): Width in mm
|
|
248
|
+
- `height` (number, required): Height in mm
|
|
249
|
+
- `depth` (number, required): Depth in mm
|
|
250
|
+
- `angle` (number, required): Taper angle in degrees
|
|
251
|
+
- `center` (object, optional): Center point
|
|
252
|
+
- `name` (string, optional): Feature name
|
|
253
|
+
|
|
254
|
+
**Returns:** Body geometry
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## FEATURE NAMESPACE
|
|
259
|
+
|
|
260
|
+
Operations that modify or add to existing bodies.
|
|
261
|
+
|
|
262
|
+
### feature.extrude
|
|
263
|
+
**Extrude a sketch profile**
|
|
264
|
+
|
|
265
|
+
**Parameters:**
|
|
266
|
+
- `sketch_id` (string, required): ID of 2D sketch to extrude
|
|
267
|
+
- `distance` (number, required): Extrusion distance in mm
|
|
268
|
+
- `direction` (string, optional): "up", "down", "symmetric", default "up"
|
|
269
|
+
- `angle` (number, optional): Draft angle in degrees
|
|
270
|
+
- `name` (string, optional): Feature name
|
|
271
|
+
|
|
272
|
+
**Returns:**
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"feature_id": "extrude_001",
|
|
276
|
+
"body_id": "body_001",
|
|
277
|
+
"geometry": { "volume": 50000, "mass": 135 }
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Example:**
|
|
282
|
+
```javascript
|
|
283
|
+
const sketch = await cyclecad.execute({
|
|
284
|
+
method: "sketch.rectangle",
|
|
285
|
+
params: { width: 50, height: 75 }
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
const extrude = await cyclecad.execute({
|
|
289
|
+
method: "feature.extrude",
|
|
290
|
+
params: {
|
|
291
|
+
sketch_id: sketch.sketch_id,
|
|
292
|
+
distance: 50,
|
|
293
|
+
direction: "up"
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
### feature.revolve
|
|
301
|
+
**Revolve a profile around an axis**
|
|
302
|
+
|
|
303
|
+
**Parameters:**
|
|
304
|
+
- `sketch_id` (string, required): Sketch profile ID
|
|
305
|
+
- `axis_id` (string, required): Axis edge/line ID
|
|
306
|
+
- `angle` (number, optional): Rotation angle, default 360
|
|
307
|
+
- `name` (string, optional): Feature name
|
|
308
|
+
|
|
309
|
+
**Returns:** Feature with body_id and geometry
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
### feature.sweep
|
|
314
|
+
**Sweep a profile along a path**
|
|
315
|
+
|
|
316
|
+
**Parameters:**
|
|
317
|
+
- `profile_id` (string, required): Profile sketch ID
|
|
318
|
+
- `path_id` (string, required): Path curve/edge ID
|
|
319
|
+
- `twist_angle` (number, optional): Twist in degrees
|
|
320
|
+
- `scale_end` (number, optional): Scale at path end (1.0 = no scale)
|
|
321
|
+
- `name` (string, optional): Feature name
|
|
322
|
+
|
|
323
|
+
**Returns:** Feature with geometry
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
### feature.loft
|
|
328
|
+
**Loft between multiple profiles**
|
|
329
|
+
|
|
330
|
+
**Parameters:**
|
|
331
|
+
- `profiles` (array, required): Array of sketch IDs [profile1, profile2, ...]
|
|
332
|
+
- `continuity` (string, optional): "positional", "tangent", "curvature", default "tangent"
|
|
333
|
+
- `name` (string, optional): Feature name
|
|
334
|
+
|
|
335
|
+
**Returns:** Feature with geometry
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
### feature.fillet
|
|
340
|
+
**Round edges on a body**
|
|
341
|
+
|
|
342
|
+
**Parameters:**
|
|
343
|
+
- `body_id` (string, required): Body to fillet
|
|
344
|
+
- `edges` (array, required): Array of edge IDs to fillet
|
|
345
|
+
- `radius` (number, required): Fillet radius in mm
|
|
346
|
+
- `name` (string, optional): Feature name
|
|
347
|
+
|
|
348
|
+
**Returns:** Feature with updated geometry
|
|
349
|
+
|
|
350
|
+
**Example:**
|
|
351
|
+
```javascript
|
|
352
|
+
const fillet = await cyclecad.execute({
|
|
353
|
+
method: "feature.fillet",
|
|
354
|
+
params: {
|
|
355
|
+
body_id: "body_001",
|
|
356
|
+
edges: ["edge_001", "edge_002", "edge_003", "edge_004"],
|
|
357
|
+
radius: 5,
|
|
358
|
+
name: "Top Edge Fillet"
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
### feature.chamfer
|
|
366
|
+
**Bevel edges on a body**
|
|
367
|
+
|
|
368
|
+
**Parameters:**
|
|
369
|
+
- `body_id` (string, required): Body to chamfer
|
|
370
|
+
- `edges` (array, required): Array of edge IDs
|
|
371
|
+
- `distance` (number, optional): Chamfer distance in mm
|
|
372
|
+
- `angle` (number, optional): Chamfer angle in degrees
|
|
373
|
+
- `name` (string, optional): Feature name
|
|
374
|
+
|
|
375
|
+
**Returns:** Feature with updated geometry
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
### feature.shell
|
|
380
|
+
**Make body hollow with uniform wall thickness**
|
|
381
|
+
|
|
382
|
+
**Parameters:**
|
|
383
|
+
- `body_id` (string, required): Body to shell
|
|
384
|
+
- `faces_to_remove` (array, optional): Face IDs to remove (open shell)
|
|
385
|
+
- `thickness` (number, required): Wall thickness in mm
|
|
386
|
+
- `name` (string, optional): Feature name
|
|
387
|
+
|
|
388
|
+
**Returns:** Feature with hollow geometry
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
### feature.draft
|
|
393
|
+
**Apply draft angle to faces**
|
|
394
|
+
|
|
395
|
+
**Parameters:**
|
|
396
|
+
- `body_id` (string, required): Body to draft
|
|
397
|
+
- `faces` (array, required): Array of face IDs
|
|
398
|
+
- `angle` (number, required): Draft angle in degrees
|
|
399
|
+
- `pull_direction` (object, optional): Direction vector {x, y, z}
|
|
400
|
+
- `name` (string, optional): Feature name
|
|
401
|
+
|
|
402
|
+
**Returns:** Feature with updated geometry
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
### feature.pattern_rectangular
|
|
407
|
+
**Create rectangular array of feature**
|
|
408
|
+
|
|
409
|
+
**Parameters:**
|
|
410
|
+
- `feature_id` (string, required): Feature to pattern (extrude, hole, etc.)
|
|
411
|
+
- `x_count` (number, required): Number of columns
|
|
412
|
+
- `y_count` (number, required): Number of rows
|
|
413
|
+
- `x_spacing` (number, required): Distance between features (X)
|
|
414
|
+
- `y_spacing` (number, required): Distance between features (Y)
|
|
415
|
+
- `name` (string, optional): Feature name
|
|
416
|
+
|
|
417
|
+
**Returns:** Pattern feature with all instances
|
|
418
|
+
|
|
419
|
+
**Example:**
|
|
420
|
+
```javascript
|
|
421
|
+
const pattern = await cyclecad.execute({
|
|
422
|
+
method: "feature.pattern_rectangular",
|
|
423
|
+
params: {
|
|
424
|
+
feature_id: "hole_001",
|
|
425
|
+
x_count: 3,
|
|
426
|
+
y_count: 2,
|
|
427
|
+
x_spacing: 30,
|
|
428
|
+
y_spacing: 25,
|
|
429
|
+
name: "Bolt Hole Pattern"
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
// Result: 6 holes total (3 × 2 grid)
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
### feature.pattern_circular
|
|
438
|
+
**Create circular array of feature**
|
|
439
|
+
|
|
440
|
+
**Parameters:**
|
|
441
|
+
- `feature_id` (string, required): Feature to pattern
|
|
442
|
+
- `axis_id` (string, optional): Rotation axis (default Z)
|
|
443
|
+
- `count` (number, required): Total number of instances
|
|
444
|
+
- `angle` (number, optional): Total rotation angle, default 360
|
|
445
|
+
- `name` (string, optional): Feature name
|
|
446
|
+
|
|
447
|
+
**Returns:** Pattern feature with instances
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
### feature.mirror
|
|
452
|
+
**Mirror a feature across a plane**
|
|
453
|
+
|
|
454
|
+
**Parameters:**
|
|
455
|
+
- `feature_id` (string, required): Feature to mirror
|
|
456
|
+
- `plane` (string, required): Mirror plane ("XY", "YZ", "XZ", or plane_id)
|
|
457
|
+
- `name` (string, optional): Feature name
|
|
458
|
+
|
|
459
|
+
**Returns:** Mirrored feature
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
### feature.boolean_union
|
|
464
|
+
**Combine two bodies**
|
|
465
|
+
|
|
466
|
+
**Parameters:**
|
|
467
|
+
- `body1_id` (string, required): First body
|
|
468
|
+
- `body2_id` (string, required): Second body
|
|
469
|
+
- `name` (string, optional): Feature name
|
|
470
|
+
|
|
471
|
+
**Returns:** New body with merged geometry
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
### feature.boolean_cut
|
|
476
|
+
**Subtract one body from another**
|
|
477
|
+
|
|
478
|
+
**Parameters:**
|
|
479
|
+
- `target_id` (string, required): Body to keep
|
|
480
|
+
- `tool_id` (string, required): Body to subtract
|
|
481
|
+
- `name` (string, optional): Feature name
|
|
482
|
+
|
|
483
|
+
**Returns:** New body with subtracted geometry
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
### feature.boolean_intersect
|
|
488
|
+
**Keep only overlapping volume**
|
|
489
|
+
|
|
490
|
+
**Parameters:**
|
|
491
|
+
- `body1_id` (string, required): First body
|
|
492
|
+
- `body2_id` (string, required): Second body
|
|
493
|
+
- `name` (string, optional): Feature name
|
|
494
|
+
|
|
495
|
+
**Returns:** New body with intersection only
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## ASSEMBLY NAMESPACE
|
|
500
|
+
|
|
501
|
+
Multi-part assembly operations and constraints.
|
|
502
|
+
|
|
503
|
+
### assembly.insert_component
|
|
504
|
+
**Add part to assembly**
|
|
505
|
+
|
|
506
|
+
**Parameters:**
|
|
507
|
+
- `part_id` (string, required): Part to insert
|
|
508
|
+
- `position` (object, optional): Position {x, y, z}
|
|
509
|
+
- `rotation` (object, optional): Rotation {x, y, z} in degrees
|
|
510
|
+
- `name` (string, optional): Component name
|
|
511
|
+
|
|
512
|
+
**Returns:**
|
|
513
|
+
```json
|
|
514
|
+
{
|
|
515
|
+
"component_id": "comp_001",
|
|
516
|
+
"assembly_id": "assembly_001",
|
|
517
|
+
"position": [0, 0, 0],
|
|
518
|
+
"rotation": [0, 0, 0]
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
### assembly.joint_rigid
|
|
525
|
+
**Lock two components in fixed position**
|
|
526
|
+
|
|
527
|
+
**Parameters:**
|
|
528
|
+
- `component1_id` (string, required): First component
|
|
529
|
+
- `component2_id` (string, required): Second component
|
|
530
|
+
- `face1_id` (string, optional): Face on first component
|
|
531
|
+
- `face2_id` (string, optional): Face on second component
|
|
532
|
+
|
|
533
|
+
**Returns:**
|
|
534
|
+
```json
|
|
535
|
+
{
|
|
536
|
+
"joint_id": "joint_rigid_001",
|
|
537
|
+
"type": "rigid",
|
|
538
|
+
"components": ["comp_001", "comp_002"]
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
### assembly.joint_revolute
|
|
545
|
+
**Allow rotation around axis (hinge)**
|
|
546
|
+
|
|
547
|
+
**Parameters:**
|
|
548
|
+
- `component1_id` (string, required): First component
|
|
549
|
+
- `component2_id` (string, required): Second component
|
|
550
|
+
- `axis_id` (string, required): Rotation axis (edge or line)
|
|
551
|
+
- `angle_min` (number, optional): Minimum angle in degrees
|
|
552
|
+
- `angle_max` (number, optional): Maximum angle in degrees
|
|
553
|
+
|
|
554
|
+
**Returns:** Joint with type "revolute" and angle limits
|
|
555
|
+
|
|
556
|
+
---
|
|
557
|
+
|
|
558
|
+
### assembly.joint_slider
|
|
559
|
+
**Allow translation along axis**
|
|
560
|
+
|
|
561
|
+
**Parameters:**
|
|
562
|
+
- `component1_id` (string, required): First component
|
|
563
|
+
- `component2_id` (string, required): Second component
|
|
564
|
+
- `axis_id` (string, required): Sliding axis
|
|
565
|
+
- `distance_min` (number, optional): Minimum distance
|
|
566
|
+
- `distance_max` (number, optional): Maximum distance
|
|
567
|
+
|
|
568
|
+
**Returns:** Joint with type "slider"
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
### assembly.joint_ball
|
|
573
|
+
**Allow rotation in all directions (ball-and-socket)**
|
|
574
|
+
|
|
575
|
+
**Parameters:**
|
|
576
|
+
- `component1_id` (string, required): First component
|
|
577
|
+
- `component2_id` (string, required): Second component
|
|
578
|
+
- `point_id` (string, required): Ball center point
|
|
579
|
+
- `cone_angle` (number, optional): Rotation limit cone angle
|
|
580
|
+
|
|
581
|
+
**Returns:** Joint with type "ball"
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
### assembly.joint_planar
|
|
586
|
+
**Lock planes together (allow translation in plane)**
|
|
587
|
+
|
|
588
|
+
**Parameters:**
|
|
589
|
+
- `component1_id` (string, required): First component
|
|
590
|
+
- `component2_id` (string, required): Second component
|
|
591
|
+
- `plane1_id` (string, required): Plane on first component
|
|
592
|
+
- `plane2_id` (string, required): Plane on second component
|
|
593
|
+
|
|
594
|
+
**Returns:** Joint with type "planar"
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
### assembly.joint_cylinder
|
|
599
|
+
**Allow rotation and translation around same axis**
|
|
600
|
+
|
|
601
|
+
**Parameters:**
|
|
602
|
+
- `component1_id` (string, required): First component
|
|
603
|
+
- `component2_id` (string, required): Second component
|
|
604
|
+
- `axis_id` (string, required): Cylinder axis
|
|
605
|
+
|
|
606
|
+
**Returns:** Joint with type "cylinder"
|
|
607
|
+
|
|
608
|
+
---
|
|
609
|
+
|
|
610
|
+
### assembly.check_collision
|
|
611
|
+
**Detect interference between components**
|
|
612
|
+
|
|
613
|
+
**Parameters:**
|
|
614
|
+
- `assembly_id` (string, required): Assembly to check
|
|
615
|
+
- `component1_id` (string, optional): First component (null = all)
|
|
616
|
+
- `component2_id` (string, optional): Second component (null = all)
|
|
617
|
+
|
|
618
|
+
**Returns:**
|
|
619
|
+
```json
|
|
620
|
+
{
|
|
621
|
+
"collisions": [
|
|
622
|
+
{
|
|
623
|
+
"component1": "comp_001",
|
|
624
|
+
"component2": "comp_002",
|
|
625
|
+
"volume": 125.4,
|
|
626
|
+
"overlap_points": [...]
|
|
627
|
+
}
|
|
628
|
+
],
|
|
629
|
+
"collision_count": 1
|
|
630
|
+
}
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
## RENDER NAMESPACE
|
|
636
|
+
|
|
637
|
+
Visualization, materials, lighting, and animation.
|
|
638
|
+
|
|
639
|
+
### render.apply_material
|
|
640
|
+
**Assign material to surface**
|
|
641
|
+
|
|
642
|
+
**Parameters:**
|
|
643
|
+
- `body_id` (string, required): Body to apply material
|
|
644
|
+
- `material` (string, required): Material name ("steel", "aluminum", "plastic", etc.)
|
|
645
|
+
- `color` (string, optional): Hex color code "#FF0000"
|
|
646
|
+
- `metalness` (number, optional): 0-1, default 0.5
|
|
647
|
+
- `roughness` (number, optional): 0-1, default 0.5
|
|
648
|
+
|
|
649
|
+
**Returns:**
|
|
650
|
+
```json
|
|
651
|
+
{
|
|
652
|
+
"body_id": "body_001",
|
|
653
|
+
"material": "steel",
|
|
654
|
+
"properties": {
|
|
655
|
+
"color": "#555555",
|
|
656
|
+
"metalness": 0.8,
|
|
657
|
+
"roughness": 0.3
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
---
|
|
663
|
+
|
|
664
|
+
### render.studio_lighting
|
|
665
|
+
**Set up professional 3-point lighting**
|
|
666
|
+
|
|
667
|
+
**Parameters:**
|
|
668
|
+
- `key_light` (object): {intensity, position: {x, y, z}, color}
|
|
669
|
+
- `fill_light` (object): {intensity, position, color}
|
|
670
|
+
- `back_light` (object): {intensity, position, color}
|
|
671
|
+
|
|
672
|
+
**Returns:** Lighting configuration
|
|
673
|
+
|
|
674
|
+
---
|
|
675
|
+
|
|
676
|
+
### render.environment
|
|
677
|
+
**Set background HDRI and reflections**
|
|
678
|
+
|
|
679
|
+
**Parameters:**
|
|
680
|
+
- `hdri_name` (string, required): HDRI map name ("studio", "outdoor", "industrial")
|
|
681
|
+
- `rotation` (number, optional): Rotation in degrees
|
|
682
|
+
- `intensity` (number, optional): 0-2, default 1.0
|
|
683
|
+
|
|
684
|
+
**Returns:** Environment configuration
|
|
685
|
+
|
|
686
|
+
---
|
|
687
|
+
|
|
688
|
+
### render.turntable
|
|
689
|
+
**Create auto-rotating animation**
|
|
690
|
+
|
|
691
|
+
**Parameters:**
|
|
692
|
+
- `body_id` (string, required): Body to rotate
|
|
693
|
+
- `speed_rpm` (number, optional): Rotation speed, default 30
|
|
694
|
+
- `duration_seconds` (number, optional): Total duration, default 10
|
|
695
|
+
- `camera_height` (number, optional): Camera height (0-1), default 0.5
|
|
696
|
+
|
|
697
|
+
**Returns:**
|
|
698
|
+
```json
|
|
699
|
+
{
|
|
700
|
+
"animation_id": "anim_turntable_001",
|
|
701
|
+
"duration": 10,
|
|
702
|
+
"format": "mp4",
|
|
703
|
+
"file_url": "https://..."
|
|
704
|
+
}
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
---
|
|
708
|
+
|
|
709
|
+
### render.storyboard
|
|
710
|
+
**Create keyframe-based animation**
|
|
711
|
+
|
|
712
|
+
**Parameters:**
|
|
713
|
+
- `keyframes` (array, required): Array of {time: seconds, position: {x, y, z}, rotation: {x, y, z}, visibility: bool}
|
|
714
|
+
- `duration_seconds` (number, optional): Total duration
|
|
715
|
+
- `camera_path` (array, optional): Array of camera positions
|
|
716
|
+
|
|
717
|
+
**Returns:** Animation with rendering progress and URL
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
### render.snapshot
|
|
722
|
+
**Capture 3D view as image**
|
|
723
|
+
|
|
724
|
+
**Parameters:**
|
|
725
|
+
- `body_id` (string, required): Body to capture
|
|
726
|
+
- `resolution` (string, optional): "1080p", "4K", custom WIDTHxHEIGHT
|
|
727
|
+
- `format` (string, optional): "png", "jpg", default "png"
|
|
728
|
+
- `background` (string, optional): "transparent", "white", "black", hex color
|
|
729
|
+
|
|
730
|
+
**Returns:**
|
|
731
|
+
```json
|
|
732
|
+
{
|
|
733
|
+
"image_url": "https://...",
|
|
734
|
+
"resolution": "1920x1080",
|
|
735
|
+
"format": "png"
|
|
736
|
+
}
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
741
|
+
## VALIDATE NAMESPACE
|
|
742
|
+
|
|
743
|
+
Design review and manufacturability analysis.
|
|
744
|
+
|
|
745
|
+
### validate.design_review
|
|
746
|
+
**Analyze design for quality**
|
|
747
|
+
|
|
748
|
+
**Parameters:**
|
|
749
|
+
- `body_id` (string, required): Body to analyze
|
|
750
|
+
- `checks` (array, optional): ["sharp_edges", "thin_walls", "undercuts", "stress", "cost"]
|
|
751
|
+
|
|
752
|
+
**Returns:**
|
|
753
|
+
```json
|
|
754
|
+
{
|
|
755
|
+
"score": "A",
|
|
756
|
+
"analysis": {
|
|
757
|
+
"sharp_edges": { "count": 3, "severity": "low" },
|
|
758
|
+
"thin_walls": { "min_thickness": 1.2, "severity": "medium" },
|
|
759
|
+
"undercuts": { "count": 1, "severity": "high" },
|
|
760
|
+
"estimated_cost": 45.50,
|
|
761
|
+
"estimated_weight": 0.65
|
|
762
|
+
},
|
|
763
|
+
"recommendations": ["Add 0.5mm fillet to top edges", "Increase wall thickness to 2mm"]
|
|
764
|
+
}
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
---
|
|
768
|
+
|
|
769
|
+
### validate.manufacturability
|
|
770
|
+
**Check for injection molding or machining**
|
|
771
|
+
|
|
772
|
+
**Parameters:**
|
|
773
|
+
- `body_id` (string, required): Body to check
|
|
774
|
+
- `process` (string, required): "injection_molding", "machining", "3d_printing"
|
|
775
|
+
|
|
776
|
+
**Returns:**
|
|
777
|
+
```json
|
|
778
|
+
{
|
|
779
|
+
"process": "injection_molding",
|
|
780
|
+
"feasibility": "excellent",
|
|
781
|
+
"issues": [],
|
|
782
|
+
"recommendations": ["Add 2-5° draft angle to side faces"],
|
|
783
|
+
"estimated_cost": 45.50,
|
|
784
|
+
"estimated_time": "45 minutes"
|
|
785
|
+
}
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
---
|
|
789
|
+
|
|
790
|
+
### validate.stress_estimate
|
|
791
|
+
**Quick stress analysis**
|
|
792
|
+
|
|
793
|
+
**Parameters:**
|
|
794
|
+
- `body_id` (string, required): Body to analyze
|
|
795
|
+
- `material` (string, required): Material name ("steel", "aluminum", etc.)
|
|
796
|
+
- `load_force` (number, required): Applied force in Newtons
|
|
797
|
+
- `load_point` (object, optional): Point of force application {x, y, z}
|
|
798
|
+
|
|
799
|
+
**Returns:**
|
|
800
|
+
```json
|
|
801
|
+
{
|
|
802
|
+
"max_stress_mpa": 245.3,
|
|
803
|
+
"safety_factor": 2.1,
|
|
804
|
+
"result": "PASS",
|
|
805
|
+
"note": "Safe for static load"
|
|
806
|
+
}
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
---
|
|
810
|
+
|
|
811
|
+
### validate.weight_estimate
|
|
812
|
+
**Calculate approximate mass**
|
|
813
|
+
|
|
814
|
+
**Parameters:**
|
|
815
|
+
- `body_id` (string, required): Body to weigh
|
|
816
|
+
- `material` (string, required): Material ("steel" = 7850 kg/m³, "aluminum" = 2700 kg/m³, etc.)
|
|
817
|
+
|
|
818
|
+
**Returns:**
|
|
819
|
+
```json
|
|
820
|
+
{
|
|
821
|
+
"volume": 0.0001234,
|
|
822
|
+
"material": "steel",
|
|
823
|
+
"density": 7850,
|
|
824
|
+
"weight_kg": 0.969,
|
|
825
|
+
"weight_lbs": 2.14
|
|
826
|
+
}
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
---
|
|
830
|
+
|
|
831
|
+
## SIMULATE NAMESPACE
|
|
832
|
+
|
|
833
|
+
Structural, thermal, and modal analysis.
|
|
834
|
+
|
|
835
|
+
### simulate.stress
|
|
836
|
+
**Static stress analysis**
|
|
837
|
+
|
|
838
|
+
**Parameters:**
|
|
839
|
+
- `body_id` (string, required): Body to simulate
|
|
840
|
+
- `material` (string, required): Material ("steel", "aluminum", etc.)
|
|
841
|
+
- `loads` (array, required): [{face_id, force_vector: {x, y, z}}, ...]
|
|
842
|
+
- `constraints` (array, required): [{face_id, type: "fixed"}, ...]
|
|
843
|
+
- `mesh_quality` (string, optional): "coarse", "medium", "fine", default "medium"
|
|
844
|
+
|
|
845
|
+
**Returns:**
|
|
846
|
+
```json
|
|
847
|
+
{
|
|
848
|
+
"simulation_id": "sim_stress_001",
|
|
849
|
+
"max_stress_mpa": 245.3,
|
|
850
|
+
"max_deflection_mm": 0.45,
|
|
851
|
+
"safety_factor": 2.1,
|
|
852
|
+
"status": "complete",
|
|
853
|
+
"results_url": "https://..."
|
|
854
|
+
}
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
---
|
|
858
|
+
|
|
859
|
+
### simulate.thermal
|
|
860
|
+
**Heat transfer analysis**
|
|
861
|
+
|
|
862
|
+
**Parameters:**
|
|
863
|
+
- `body_id` (string, required): Body to simulate
|
|
864
|
+
- `material` (string, required): Material with thermal properties
|
|
865
|
+
- `heat_sources` (array, required): [{face_id, heat_flux_w_per_m2}, ...]
|
|
866
|
+
- `boundary_conditions` (array, required): [{face_id, temperature_c}, ...]
|
|
867
|
+
- `duration_seconds` (number, optional): For transient analysis
|
|
868
|
+
|
|
869
|
+
**Returns:**
|
|
870
|
+
```json
|
|
871
|
+
{
|
|
872
|
+
"simulation_id": "sim_thermal_001",
|
|
873
|
+
"max_temperature_c": 125.4,
|
|
874
|
+
"min_temperature_c": 25.0,
|
|
875
|
+
"steady_state": true,
|
|
876
|
+
"status": "complete"
|
|
877
|
+
}
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
---
|
|
881
|
+
|
|
882
|
+
### simulate.modal
|
|
883
|
+
**Natural frequency and vibration analysis**
|
|
884
|
+
|
|
885
|
+
**Parameters:**
|
|
886
|
+
- `body_id` (string, required): Body to analyze
|
|
887
|
+
- `material` (string, required): Material with density
|
|
888
|
+
- `constraints` (array, required): [{face_id, type: "fixed"}, ...]
|
|
889
|
+
- `modes_count` (number, optional): Number of modes to find, default 5
|
|
890
|
+
|
|
891
|
+
**Returns:**
|
|
892
|
+
```json
|
|
893
|
+
{
|
|
894
|
+
"simulation_id": "sim_modal_001",
|
|
895
|
+
"modes": [
|
|
896
|
+
{ "mode": 1, "frequency_hz": 123.4, "shape": "bending_x" },
|
|
897
|
+
{ "mode": 2, "frequency_hz": 156.7, "shape": "bending_y" },
|
|
898
|
+
{ "mode": 3, "frequency_hz": 234.5, "shape": "torsion" }
|
|
899
|
+
],
|
|
900
|
+
"status": "complete"
|
|
901
|
+
}
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
---
|
|
905
|
+
|
|
906
|
+
## CAM NAMESPACE
|
|
907
|
+
|
|
908
|
+
Manufacturing tool paths and CNC code generation.
|
|
909
|
+
|
|
910
|
+
### cam.setup
|
|
911
|
+
**Define machining parameters**
|
|
912
|
+
|
|
913
|
+
**Parameters:**
|
|
914
|
+
- `body_id` (string, required): Body to machine
|
|
915
|
+
- `stock_type` (string, required): "box", "cylinder", custom
|
|
916
|
+
- `stock_dimensions` (object, required): {length, width, height} in mm
|
|
917
|
+
- `machine_type` (string, required): "mill_3axis", "mill_4axis", "lathe", "laser", "waterjet"
|
|
918
|
+
|
|
919
|
+
**Returns:**
|
|
920
|
+
```json
|
|
921
|
+
{
|
|
922
|
+
"setup_id": "cam_setup_001",
|
|
923
|
+
"machine": "mill_3axis",
|
|
924
|
+
"stock_volume": 50000,
|
|
925
|
+
"available_tools": ["endmill_10", "ballmill_8", "drill_5"]
|
|
926
|
+
}
|
|
927
|
+
```
|
|
928
|
+
|
|
929
|
+
---
|
|
930
|
+
|
|
931
|
+
### cam.contour_2d
|
|
932
|
+
**Mill outer profile of 2D sketch**
|
|
933
|
+
|
|
934
|
+
**Parameters:**
|
|
935
|
+
- `sketch_id` (string, required): 2D sketch outline
|
|
936
|
+
- `tool_id` (string, required): Tool from library
|
|
937
|
+
- `depth_per_pass` (number, required): Cut depth per pass in mm
|
|
938
|
+
- `climb_or_conventional` (string, optional): "climb", "conventional", default "climb"
|
|
939
|
+
|
|
940
|
+
**Returns:**
|
|
941
|
+
```json
|
|
942
|
+
{
|
|
943
|
+
"toolpath_id": "tp_contour_001",
|
|
944
|
+
"passes": 3,
|
|
945
|
+
"estimated_time_minutes": 12.5,
|
|
946
|
+
"total_distance_mm": 2450
|
|
947
|
+
}
|
|
948
|
+
```
|
|
949
|
+
|
|
950
|
+
---
|
|
951
|
+
|
|
952
|
+
### cam.pocket_2d
|
|
953
|
+
**Mill enclosed area to depth**
|
|
954
|
+
|
|
955
|
+
**Parameters:**
|
|
956
|
+
- `sketch_id` (string, required): Closed profile to pocket
|
|
957
|
+
- `tool_id` (string, required): Cutting tool
|
|
958
|
+
- `depth` (number, required): Pocket depth in mm
|
|
959
|
+
- `depth_per_pass` (number, required): Cut depth per pass
|
|
960
|
+
|
|
961
|
+
**Returns:** Toolpath with passes and time estimate
|
|
962
|
+
|
|
963
|
+
---
|
|
964
|
+
|
|
965
|
+
### cam.roughing_3d
|
|
966
|
+
**Remove bulk material quickly**
|
|
967
|
+
|
|
968
|
+
**Parameters:**
|
|
969
|
+
- `body_id` (string, required): Body to rough
|
|
970
|
+
- `tool_id` (string, required): Roughing tool (large diameter)
|
|
971
|
+
- `step_down` (number, required): Vertical step in mm
|
|
972
|
+
- `step_over` (number, optional): Horizontal spacing in mm
|
|
973
|
+
|
|
974
|
+
**Returns:** 3D toolpath with path points and time estimate
|
|
975
|
+
|
|
976
|
+
---
|
|
977
|
+
|
|
978
|
+
### cam.finishing_3d
|
|
979
|
+
**Fine cuts for surface quality**
|
|
980
|
+
|
|
981
|
+
**Parameters:**
|
|
982
|
+
- `body_id` (string, required): Body to finish
|
|
983
|
+
- `tool_id` (string, required): Finishing tool (ball mill or fine endmill)
|
|
984
|
+
- `step_down` (number, required): Vertical step in mm
|
|
985
|
+
- `step_over` (number, optional): Small horizontal spacing
|
|
986
|
+
|
|
987
|
+
**Returns:** 3D toolpath optimized for surface finish
|
|
988
|
+
|
|
989
|
+
---
|
|
990
|
+
|
|
991
|
+
### cam.export_gcode
|
|
992
|
+
**Generate CNC machine code**
|
|
993
|
+
|
|
994
|
+
**Parameters:**
|
|
995
|
+
- `toolpath_id` (string, required): Toolpath to export
|
|
996
|
+
- `post_processor` (string, required): "fanuc", "haas", "siemens", "mach3"
|
|
997
|
+
- `safe_z_height` (number, optional): Rapid traverse height in mm
|
|
998
|
+
|
|
999
|
+
**Returns:**
|
|
1000
|
+
```json
|
|
1001
|
+
{
|
|
1002
|
+
"gcode_url": "https://...",
|
|
1003
|
+
"file_size_bytes": 125400,
|
|
1004
|
+
"lines": 8523,
|
|
1005
|
+
"estimated_time_minutes": 45.5
|
|
1006
|
+
}
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
---
|
|
1010
|
+
|
|
1011
|
+
## DRAWING NAMESPACE
|
|
1012
|
+
|
|
1013
|
+
Engineering drawing creation and annotation.
|
|
1014
|
+
|
|
1015
|
+
### drawing.new_sheet
|
|
1016
|
+
**Create 2D drawing sheet**
|
|
1017
|
+
|
|
1018
|
+
**Parameters:**
|
|
1019
|
+
- `body_id` (string, required): Body to draw
|
|
1020
|
+
- `sheet_size` (string, optional): "A4", "A3", "Letter", "Ledger", default "A4"
|
|
1021
|
+
- `scale` (string, optional): "1:1", "1:2", "1:10", default "1:1"
|
|
1022
|
+
|
|
1023
|
+
**Returns:**
|
|
1024
|
+
```json
|
|
1025
|
+
{
|
|
1026
|
+
"drawing_id": "dwg_001",
|
|
1027
|
+
"sheet_id": "sheet_001",
|
|
1028
|
+
"sheet_size": "A4",
|
|
1029
|
+
"scale": "1:1"
|
|
1030
|
+
}
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
---
|
|
1034
|
+
|
|
1035
|
+
### drawing.orthographic_view
|
|
1036
|
+
**Add orthographic projection to drawing**
|
|
1037
|
+
|
|
1038
|
+
**Parameters:**
|
|
1039
|
+
- `drawing_id` (string, required): Drawing to add to
|
|
1040
|
+
- `view_type` (string, required): "front", "top", "right", "left", "back", "bottom", "isometric"
|
|
1041
|
+
- `position` (object, required): {x, y} on sheet in mm
|
|
1042
|
+
|
|
1043
|
+
**Returns:**
|
|
1044
|
+
```json
|
|
1045
|
+
{
|
|
1046
|
+
"view_id": "view_front_001",
|
|
1047
|
+
"type": "orthographic",
|
|
1048
|
+
"projection": "front",
|
|
1049
|
+
"position": [50, 100]
|
|
1050
|
+
}
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
---
|
|
1054
|
+
|
|
1055
|
+
### drawing.section_view
|
|
1056
|
+
**Add cross-section to drawing**
|
|
1057
|
+
|
|
1058
|
+
**Parameters:**
|
|
1059
|
+
- `drawing_id` (string, required): Drawing to add to
|
|
1060
|
+
- `cutting_plane` (object, required): {point: {x, y, z}, normal: {x, y, z}}
|
|
1061
|
+
- `position` (object, required): {x, y} on sheet
|
|
1062
|
+
|
|
1063
|
+
**Returns:** Section view with cross-section geometry
|
|
1064
|
+
|
|
1065
|
+
---
|
|
1066
|
+
|
|
1067
|
+
### drawing.dimension_auto
|
|
1068
|
+
**Automatically add dimensions from 3D constraints**
|
|
1069
|
+
|
|
1070
|
+
**Parameters:**
|
|
1071
|
+
- `view_id` (string, required): View to dimension
|
|
1072
|
+
- `placement` (string, optional): "inside", "outside", default "outside"
|
|
1073
|
+
|
|
1074
|
+
**Returns:**
|
|
1075
|
+
```json
|
|
1076
|
+
{
|
|
1077
|
+
"dimensions_added": 15,
|
|
1078
|
+
"redundant_dimensions": 2,
|
|
1079
|
+
"notes": ["Consider removing redundant width dimensions"]
|
|
1080
|
+
}
|
|
1081
|
+
```
|
|
1082
|
+
|
|
1083
|
+
---
|
|
1084
|
+
|
|
1085
|
+
### drawing.dimension_manual
|
|
1086
|
+
**Add custom dimension to view**
|
|
1087
|
+
|
|
1088
|
+
**Parameters:**
|
|
1089
|
+
- `view_id` (string, required): View to dimension
|
|
1090
|
+
- `element1_id` (string, required): First element (edge or point)
|
|
1091
|
+
- `element2_id` (string, optional): Second element (for distance)
|
|
1092
|
+
- `value` (string, optional): Dimension text (e.g., "50.00", "Ø25", "R10")
|
|
1093
|
+
- `position` (object, required): {x, y} on sheet
|
|
1094
|
+
|
|
1095
|
+
**Returns:** Dimension object with ID and properties
|
|
1096
|
+
|
|
1097
|
+
---
|
|
1098
|
+
|
|
1099
|
+
### drawing.gdt_add
|
|
1100
|
+
**Add geometric tolerance frame**
|
|
1101
|
+
|
|
1102
|
+
**Parameters:**
|
|
1103
|
+
- `view_id` (string, required): View to add GD&T to
|
|
1104
|
+
- `control_type` (string, required): "position", "flatness", "perpendicular", "runout", "profile", "angularity"
|
|
1105
|
+
- `tolerance_value` (number, required): Tolerance in mm
|
|
1106
|
+
- `primary_datum` (string, optional): Primary datum reference
|
|
1107
|
+
- `secondary_datum` (string, optional): Secondary datum
|
|
1108
|
+
- `tertiary_datum` (string, optional): Tertiary datum
|
|
1109
|
+
- `position` (object, required): {x, y} on sheet
|
|
1110
|
+
|
|
1111
|
+
**Returns:** GD&T control frame object
|
|
1112
|
+
|
|
1113
|
+
---
|
|
1114
|
+
|
|
1115
|
+
### drawing.export_pdf
|
|
1116
|
+
**Export drawing as PDF**
|
|
1117
|
+
|
|
1118
|
+
**Parameters:**
|
|
1119
|
+
- `drawing_id` (string, required): Drawing to export
|
|
1120
|
+
- `include_sheets` (array, optional): Sheet IDs (null = all)
|
|
1121
|
+
|
|
1122
|
+
**Returns:**
|
|
1123
|
+
```json
|
|
1124
|
+
{
|
|
1125
|
+
"pdf_url": "https://...",
|
|
1126
|
+
"file_size_bytes": 250000,
|
|
1127
|
+
"pages": 1
|
|
1128
|
+
}
|
|
1129
|
+
```
|
|
1130
|
+
|
|
1131
|
+
---
|
|
1132
|
+
|
|
1133
|
+
## DATA NAMESPACE
|
|
1134
|
+
|
|
1135
|
+
Version control, import/export, and collaboration.
|
|
1136
|
+
|
|
1137
|
+
### data.save_version
|
|
1138
|
+
**Create design checkpoint**
|
|
1139
|
+
|
|
1140
|
+
**Parameters:**
|
|
1141
|
+
- `project_id` (string, required): Project to version
|
|
1142
|
+
- `version_name` (string, required): Version label ("v1.0", "prototype", "final")
|
|
1143
|
+
- `description` (string, optional): Change notes
|
|
1144
|
+
|
|
1145
|
+
**Returns:**
|
|
1146
|
+
```json
|
|
1147
|
+
{
|
|
1148
|
+
"version_id": "v_001",
|
|
1149
|
+
"timestamp": "2024-03-26T10:30:00Z",
|
|
1150
|
+
"version_name": "v1.0",
|
|
1151
|
+
"size_mb": 2.5
|
|
1152
|
+
}
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
---
|
|
1156
|
+
|
|
1157
|
+
### data.restore_version
|
|
1158
|
+
**Revert to previous version**
|
|
1159
|
+
|
|
1160
|
+
**Parameters:**
|
|
1161
|
+
- `version_id` (string, required): Version to restore to
|
|
1162
|
+
|
|
1163
|
+
**Returns:**
|
|
1164
|
+
```json
|
|
1165
|
+
{
|
|
1166
|
+
"status": "success",
|
|
1167
|
+
"timestamp": "2024-03-26T10:30:00Z",
|
|
1168
|
+
"note": "Design restored to v1.0"
|
|
1169
|
+
}
|
|
1170
|
+
```
|
|
1171
|
+
|
|
1172
|
+
---
|
|
1173
|
+
|
|
1174
|
+
### data.import_step
|
|
1175
|
+
**Load STEP file**
|
|
1176
|
+
|
|
1177
|
+
**Parameters:**
|
|
1178
|
+
- `file_path` (string, required): Path to .STEP or .STP file
|
|
1179
|
+
- `action` (string, optional): "new_part", "add_to_assembly", default "new_part"
|
|
1180
|
+
|
|
1181
|
+
**Returns:**
|
|
1182
|
+
```json
|
|
1183
|
+
{
|
|
1184
|
+
"part_id": "part_imported_001",
|
|
1185
|
+
"body_count": 3,
|
|
1186
|
+
"geometry": { "volume": 50000, "mass": 135 }
|
|
1187
|
+
}
|
|
1188
|
+
```
|
|
1189
|
+
|
|
1190
|
+
---
|
|
1191
|
+
|
|
1192
|
+
### data.export_step
|
|
1193
|
+
**Save as STEP file**
|
|
1194
|
+
|
|
1195
|
+
**Parameters:**
|
|
1196
|
+
- `body_id` (string, required): Body to export
|
|
1197
|
+
- `file_path` (string, required): Output path
|
|
1198
|
+
|
|
1199
|
+
**Returns:**
|
|
1200
|
+
```json
|
|
1201
|
+
{
|
|
1202
|
+
"file_url": "https://...",
|
|
1203
|
+
"file_size_bytes": 125000,
|
|
1204
|
+
"format": "STEP"
|
|
1205
|
+
}
|
|
1206
|
+
```
|
|
1207
|
+
|
|
1208
|
+
---
|
|
1209
|
+
|
|
1210
|
+
### data.export_stl
|
|
1211
|
+
**Save as STL for 3D printing**
|
|
1212
|
+
|
|
1213
|
+
**Parameters:**
|
|
1214
|
+
- `body_id` (string, required): Body to export
|
|
1215
|
+
- `resolution` (string, optional): "coarse", "normal", "fine", default "normal"
|
|
1216
|
+
- `format` (string, optional): "ascii", "binary", default "binary"
|
|
1217
|
+
|
|
1218
|
+
**Returns:**
|
|
1219
|
+
```json
|
|
1220
|
+
{
|
|
1221
|
+
"file_url": "https://...",
|
|
1222
|
+
"file_size_bytes": 250000,
|
|
1223
|
+
"triangles": 45000
|
|
1224
|
+
}
|
|
1225
|
+
```
|
|
1226
|
+
|
|
1227
|
+
---
|
|
1228
|
+
|
|
1229
|
+
### data.export_dxf
|
|
1230
|
+
**Save 2D sketch as DXF**
|
|
1231
|
+
|
|
1232
|
+
**Parameters:**
|
|
1233
|
+
- `sketch_id` (string, required): Sketch to export
|
|
1234
|
+
- `scale` (string, optional): "1:1", "1:2", etc.
|
|
1235
|
+
|
|
1236
|
+
**Returns:**
|
|
1237
|
+
```json
|
|
1238
|
+
{
|
|
1239
|
+
"file_url": "https://...",
|
|
1240
|
+
"format": "DXF",
|
|
1241
|
+
"layers": ["geometry", "dimensions", "text"]
|
|
1242
|
+
}
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
---
|
|
1246
|
+
|
|
1247
|
+
## ERROR HANDLING
|
|
1248
|
+
|
|
1249
|
+
### Error Codes
|
|
1250
|
+
|
|
1251
|
+
| Code | HTTP Status | Meaning |
|
|
1252
|
+
|------|-------------|---------|
|
|
1253
|
+
| -32600 | 400 | Invalid Request |
|
|
1254
|
+
| -32601 | 404 | Method not found |
|
|
1255
|
+
| -32602 | 400 | Invalid parameters |
|
|
1256
|
+
| -32603 | 500 | Internal error |
|
|
1257
|
+
| -32000 | 400 | Server error (custom) |
|
|
1258
|
+
| -32001 | 409 | Conflict (e.g., body doesn't exist) |
|
|
1259
|
+
| -32002 | 422 | Validation failed |
|
|
1260
|
+
|
|
1261
|
+
### Error Response Example
|
|
1262
|
+
```json
|
|
1263
|
+
{
|
|
1264
|
+
"jsonrpc": "2.0",
|
|
1265
|
+
"error": {
|
|
1266
|
+
"code": -32602,
|
|
1267
|
+
"message": "Invalid parameter: diameter",
|
|
1268
|
+
"data": {
|
|
1269
|
+
"field": "diameter",
|
|
1270
|
+
"value": -10,
|
|
1271
|
+
"reason": "must be > 0"
|
|
1272
|
+
}
|
|
1273
|
+
},
|
|
1274
|
+
"id": 1
|
|
1275
|
+
}
|
|
1276
|
+
```
|
|
1277
|
+
|
|
1278
|
+
### Common Errors
|
|
1279
|
+
|
|
1280
|
+
**Invalid Body ID:**
|
|
1281
|
+
```
|
|
1282
|
+
Error: Body 'body_999' not found
|
|
1283
|
+
Code: -32001
|
|
1284
|
+
```
|
|
1285
|
+
|
|
1286
|
+
**Invalid Geometry:**
|
|
1287
|
+
```
|
|
1288
|
+
Error: Self-intersecting geometry detected
|
|
1289
|
+
Code: -32002
|
|
1290
|
+
```
|
|
1291
|
+
|
|
1292
|
+
**Operation Failed:**
|
|
1293
|
+
```
|
|
1294
|
+
Error: Fillet failed - radius too large for geometry
|
|
1295
|
+
Code: -32000
|
|
1296
|
+
```
|
|
1297
|
+
|
|
1298
|
+
---
|
|
1299
|
+
|
|
1300
|
+
## CODE EXAMPLES
|
|
1301
|
+
|
|
1302
|
+
### Example 1: Create a Simple Box with Fillets
|
|
1303
|
+
|
|
1304
|
+
```javascript
|
|
1305
|
+
const cyclecad = require('cyclecad-api');
|
|
1306
|
+
|
|
1307
|
+
async function createBox() {
|
|
1308
|
+
// Create sketch
|
|
1309
|
+
const sketch = await cyclecad.execute({
|
|
1310
|
+
method: "sketch.rectangle",
|
|
1311
|
+
params: { width: 100, height: 75 }
|
|
1312
|
+
});
|
|
1313
|
+
|
|
1314
|
+
// Extrude to 3D
|
|
1315
|
+
const extrude = await cyclecad.execute({
|
|
1316
|
+
method: "feature.extrude",
|
|
1317
|
+
params: {
|
|
1318
|
+
sketch_id: sketch.sketch_id,
|
|
1319
|
+
distance: 50
|
|
1320
|
+
}
|
|
1321
|
+
});
|
|
1322
|
+
|
|
1323
|
+
// Get edges for filleting
|
|
1324
|
+
const edges = extrude.geometry.edges.filter(e => e.position === "top");
|
|
1325
|
+
|
|
1326
|
+
// Add fillet
|
|
1327
|
+
const fillet = await cyclecad.execute({
|
|
1328
|
+
method: "feature.fillet",
|
|
1329
|
+
params: {
|
|
1330
|
+
body_id: extrude.body_id,
|
|
1331
|
+
edges: edges.map(e => e.id),
|
|
1332
|
+
radius: 5
|
|
1333
|
+
}
|
|
1334
|
+
});
|
|
1335
|
+
|
|
1336
|
+
return fillet;
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
createBox().then(result => console.log(result));
|
|
1340
|
+
```
|
|
1341
|
+
|
|
1342
|
+
---
|
|
1343
|
+
|
|
1344
|
+
### Example 2: Create Assembly with Moving Joint
|
|
1345
|
+
|
|
1346
|
+
```javascript
|
|
1347
|
+
async function createMechanism() {
|
|
1348
|
+
// Insert base
|
|
1349
|
+
const base = await cyclecad.execute({
|
|
1350
|
+
method: "assembly.insert_component",
|
|
1351
|
+
params: {
|
|
1352
|
+
part_id: "base_plate",
|
|
1353
|
+
position: [0, 0, 0]
|
|
1354
|
+
}
|
|
1355
|
+
});
|
|
1356
|
+
|
|
1357
|
+
// Insert lever
|
|
1358
|
+
const lever = await cyclecad.execute({
|
|
1359
|
+
method: "assembly.insert_component",
|
|
1360
|
+
params: {
|
|
1361
|
+
part_id: "lever_arm",
|
|
1362
|
+
position: [50, 0, 20]
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
|
|
1366
|
+
// Create hinge joint
|
|
1367
|
+
const joint = await cyclecad.execute({
|
|
1368
|
+
method: "assembly.joint_revolute",
|
|
1369
|
+
params: {
|
|
1370
|
+
component1_id: base.component_id,
|
|
1371
|
+
component2_id: lever.component_id,
|
|
1372
|
+
axis_id: "edge_hinge",
|
|
1373
|
+
angle_min: -90,
|
|
1374
|
+
angle_max: 90
|
|
1375
|
+
}
|
|
1376
|
+
});
|
|
1377
|
+
|
|
1378
|
+
return { base, lever, joint };
|
|
1379
|
+
}
|
|
1380
|
+
```
|
|
1381
|
+
|
|
1382
|
+
---
|
|
1383
|
+
|
|
1384
|
+
### Example 3: Design Review and Export
|
|
1385
|
+
|
|
1386
|
+
```javascript
|
|
1387
|
+
async function reviewAndExport() {
|
|
1388
|
+
const body_id = "body_001";
|
|
1389
|
+
|
|
1390
|
+
// Run design review
|
|
1391
|
+
const review = await cyclecad.execute({
|
|
1392
|
+
method: "validate.design_review",
|
|
1393
|
+
params: {
|
|
1394
|
+
body_id: body_id,
|
|
1395
|
+
checks: ["sharp_edges", "thin_walls", "undercuts", "stress", "cost"]
|
|
1396
|
+
}
|
|
1397
|
+
});
|
|
1398
|
+
|
|
1399
|
+
console.log(`Design Score: ${review.score}`);
|
|
1400
|
+
console.log(`Issues: ${review.analysis.sharp_edges.count} sharp edges`);
|
|
1401
|
+
|
|
1402
|
+
// If issues found, show recommendations
|
|
1403
|
+
if (review.recommendations.length > 0) {
|
|
1404
|
+
console.log("Recommendations:");
|
|
1405
|
+
review.recommendations.forEach(r => console.log("- " + r));
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
// Export to STEP for manufacturing
|
|
1409
|
+
const step = await cyclecad.execute({
|
|
1410
|
+
method: "data.export_step",
|
|
1411
|
+
params: {
|
|
1412
|
+
body_id: body_id,
|
|
1413
|
+
file_path: "/exports/final_design.stp"
|
|
1414
|
+
}
|
|
1415
|
+
});
|
|
1416
|
+
|
|
1417
|
+
return { review, step };
|
|
1418
|
+
}
|
|
1419
|
+
```
|
|
1420
|
+
|
|
1421
|
+
---
|
|
1422
|
+
|
|
1423
|
+
End of API Reference
|