cyclecad 0.2.3 → 0.3.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.
@@ -0,0 +1,534 @@
1
+ /**
2
+ * Machine Profiles Manager
3
+ * Manages CNC/FDM/SLA/Laser machine configurations and capabilities
4
+ * Registers on window.cycleCAD.machines
5
+ *
6
+ * Usage:
7
+ * const machine = window.cycleCAD.machines.get('shapeoko-4')
8
+ * const isCapable = window.cycleCAD.machines.canHandle('shapeoko-4', { toolDiameter: 3.175, maxRPM: 12000 })
9
+ * const profiles = window.cycleCAD.machines.list()
10
+ */
11
+
12
+ (function() {
13
+ 'use strict';
14
+
15
+ // Machine Profile Database
16
+ const MACHINE_PROFILES = {
17
+ 'shapeoko-4': {
18
+ name: 'Shapeoko 4',
19
+ type: 'CNC',
20
+ manufacturer: 'Carbide 3D',
21
+ workArea: { x: 406.4, y: 508, z: 104.14 }, // mm
22
+ maxSpindleRPM: 10000,
23
+ maxFeedRate: 3000, // mm/min
24
+ firmware: 'Grbl',
25
+ supportedTools: ['End Mill', 'Ball Mill', 'V-bit', 'Drill'],
26
+ gcodDialect: 'Grbl',
27
+ macros: {
28
+ header: 'G21 G90 G94 M3',
29
+ footer: 'M5 G28 M30',
30
+ toolChange: 'M6 T{tool}',
31
+ dwell: 'G4 P{ms}',
32
+ spindleControl: 'S{rpm} M3'
33
+ },
34
+ notes: 'Desktop benchtop CNC router'
35
+ },
36
+ 'x-carve': {
37
+ name: 'X-Carve',
38
+ type: 'CNC',
39
+ manufacturer: 'Inventables',
40
+ workArea: { x: 762, y: 762, z: 76.2 }, // mm (30x30x3 inch)
41
+ maxSpindleRPM: 24000,
42
+ maxFeedRate: 4000,
43
+ firmware: 'Grbl',
44
+ supportedTools: ['End Mill', 'Ball Mill', 'V-bit', 'Drill'],
45
+ gcodDialect: 'Grbl',
46
+ macros: {
47
+ header: 'G21 G90 G94 M3',
48
+ footer: 'M5 G28 M30',
49
+ toolChange: 'M6 T{tool}',
50
+ dwell: 'G4 P{ms}',
51
+ spindleControl: 'S{rpm} M3'
52
+ },
53
+ notes: 'Mid-range desktop CNC router'
54
+ },
55
+ 'prusa-i3-mk3': {
56
+ name: 'Prusa i3 MK3S+',
57
+ type: 'FDM',
58
+ manufacturer: 'Prusa Research',
59
+ workArea: { x: 250, y: 210, z: 210 }, // mm
60
+ maxSpindleRPM: 0,
61
+ maxFeedRate: 200, // mm/min (print speed)
62
+ firmware: 'Marlin',
63
+ supportedTools: ['Hotend 0.4mm', 'Hotend 0.6mm', 'Hotend 0.8mm'],
64
+ gcodDialect: 'Marlin',
65
+ macros: {
66
+ header: 'M109 S{nozzleTemp} ; Heat nozzle\nM190 S{bedTemp} ; Heat bed\nG28 ; Home\nG29 ; Mesh bed level',
67
+ footer: 'M104 S0 ; Cool nozzle\nM140 S0 ; Cool bed\nG28 X0 Y0 ; Home\nM84 ; Disable motors',
68
+ toolChange: '; Nozzle swap (manual)',
69
+ dwell: 'G4 S{sec}',
70
+ retraction: 'G10 ; Retract\nG11 ; Unretract'
71
+ },
72
+ notes: 'Entry-level FDM printer with excellent precision'
73
+ },
74
+ 'ender-3-pro': {
75
+ name: 'Creality Ender 3 Pro',
76
+ type: 'FDM',
77
+ manufacturer: 'Creality',
78
+ workArea: { x: 235, y: 235, z: 250 }, // mm
79
+ maxSpindleRPM: 0,
80
+ maxFeedRate: 200,
81
+ firmware: 'Marlin',
82
+ supportedTools: ['Hotend 0.4mm', 'Hotend 0.6mm'],
83
+ gcodDialect: 'Marlin',
84
+ macros: {
85
+ header: 'M104 S{nozzleTemp}\nM140 S{bedTemp}\nG28\nG29',
86
+ footer: 'M104 S0\nM140 S0\nG28 X0 Y0\nM84',
87
+ toolChange: '; Manual nozzle swap',
88
+ dwell: 'G4 S{sec}',
89
+ retraction: 'G10\nG11'
90
+ },
91
+ notes: 'Budget FDM printer, very popular'
92
+ },
93
+ 'bambu-lab-x1': {
94
+ name: 'Bambu Lab X1',
95
+ type: 'FDM',
96
+ manufacturer: 'Bambu Lab',
97
+ workArea: { x: 256, y: 256, z: 256 }, // mm
98
+ maxSpindleRPM: 0,
99
+ maxFeedRate: 500, // mm/min (very fast with 4-material AMS)
100
+ firmware: 'Proprietary',
101
+ supportedTools: ['Hotend 0.4mm', 'Hotend 0.6mm', 'Hotend 0.8mm', 'AMS (4-material)'],
102
+ gcodDialect: 'Bambu',
103
+ macros: {
104
+ header: 'M1002 judge_flag 0\nM109 S{nozzleTemp}\nM190 S{bedTemp}',
105
+ footer: 'M104 S0\nM140 S0',
106
+ toolChange: 'M620.{tool} ; AMS tool change',
107
+ dwell: 'G4 P{ms}',
108
+ retraction: 'G10\nG11'
109
+ },
110
+ notes: 'High-speed FDM with integrated multi-material system'
111
+ },
112
+ 'glowforge-basic': {
113
+ name: 'Glowforge Basic',
114
+ type: 'Laser',
115
+ manufacturer: 'Glowforge',
116
+ workArea: { x: 279.4, y: 203.2, z: 50.8 }, // mm (11x8 inch, 2 inch max thickness)
117
+ maxSpindleRPM: 0,
118
+ maxFeedRate: 1000, // mm/min (laser raster)
119
+ firmware: 'Proprietary Cloud',
120
+ supportedTools: ['CO2 Laser 40W'],
121
+ gcodDialect: 'LightBurn/Glowforge',
122
+ macros: {
123
+ header: '; Glowforge job header',
124
+ footer: '; Job complete',
125
+ toolChange: '; Laser module (fixed)',
126
+ dwell: 'WAIT {sec}s',
127
+ powerControl: 'POWER {percent}%'
128
+ },
129
+ notes: 'Consumer CO2 laser cutter/engraver'
130
+ },
131
+ 'haas-mini-mill': {
132
+ name: 'HAAS Mini Mill',
133
+ type: 'CNC',
134
+ manufacturer: 'HAAS Automation',
135
+ workArea: { x: 508, y: 457.2, z: 254 }, // mm (20x18x10 inch)
136
+ maxSpindleRPM: 7500,
137
+ maxFeedRate: 8000,
138
+ firmware: 'Mach 3',
139
+ supportedTools: ['End Mill', 'Ball Mill', 'Taper Mill', 'Drill', 'Tap', 'Center Drill'],
140
+ gcodDialect: 'ISO G-code',
141
+ macros: {
142
+ header: 'G21 G90 G94 G54 M3',
143
+ footer: 'M5 G28 M30',
144
+ toolChange: 'M6 T{tool}',
145
+ dwell: 'G4 P{ms}',
146
+ spindleControl: 'S{rpm} M3'
147
+ },
148
+ notes: 'Professional benchtop CNC mill'
149
+ },
150
+ 'tormach-pcnc-1100': {
151
+ name: 'Tormach PCNC 1100',
152
+ type: 'CNC',
153
+ manufacturer: 'Tormach',
154
+ workArea: { x: 558.8, y: 279.4, z: 177.8 }, // mm
155
+ maxSpindleRPM: 5000,
156
+ maxFeedRate: 7620,
157
+ firmware: 'Mach3/LinuxCNC',
158
+ supportedTools: ['End Mill', 'Ball Mill', 'Drill', 'Tap'],
159
+ gcodDialect: 'ISO G-code',
160
+ macros: {
161
+ header: 'G21 G90 G94 G54 M3',
162
+ footer: 'M5 G28 M30',
163
+ toolChange: 'M6 T{tool}',
164
+ dwell: 'G4 P{ms}',
165
+ spindleControl: 'S{rpm} M3'
166
+ },
167
+ notes: 'Professional benchtop mill, popular with makers'
168
+ },
169
+ 'roland-mdx-40': {
170
+ name: 'Roland MDX-40',
171
+ type: 'CNC',
172
+ manufacturer: 'Roland',
173
+ workArea: { x: 304.8, y: 152.4, z: 50.8 }, // mm (12x6x2 inch)
174
+ maxSpindleRPM: 8000,
175
+ maxFeedRate: 5000,
176
+ firmware: 'Roland proprietary',
177
+ supportedTools: ['End Mill', 'Ball Mill', 'V-bit'],
178
+ gcodDialect: 'Roland VPanel',
179
+ macros: {
180
+ header: '; Roland MDX-40 job',
181
+ footer: '; Job complete',
182
+ toolChange: 'M6 T{tool}',
183
+ dwell: 'G4 P{ms}',
184
+ spindleControl: 'S{rpm} M3'
185
+ },
186
+ notes: 'Compact desktop CNC mill, widely used in universities'
187
+ },
188
+ 'nomad-3': {
189
+ name: 'Carbide 3D Nomad 3',
190
+ type: 'CNC',
191
+ manufacturer: 'Carbide 3D',
192
+ workArea: { x: 203.2, y: 177.8, z: 76.2 }, // mm (8x7x3 inch)
193
+ maxSpindleRPM: 10000,
194
+ maxFeedRate: 3000,
195
+ firmware: 'Grbl',
196
+ supportedTools: ['End Mill', 'Ball Mill', 'V-bit', 'Drill'],
197
+ gcodDialect: 'Grbl',
198
+ macros: {
199
+ header: 'G21 G90 G94 M3',
200
+ footer: 'M5 G28 M30',
201
+ toolChange: 'M6 T{tool}',
202
+ dwell: 'G4 P{ms}',
203
+ spindleControl: 'S{rpm} M3'
204
+ },
205
+ notes: 'Compact tabletop milling machine'
206
+ },
207
+ 'formlabs-form-3': {
208
+ name: 'Formlabs Form 3',
209
+ type: 'SLA',
210
+ manufacturer: 'Formlabs',
211
+ workArea: { x: 127.5, y: 80.5, z: 100 }, // mm (5x3.2x3.9 inch build area)
212
+ maxSpindleRPM: 0,
213
+ maxFeedRate: 0, // Stereolithography
214
+ firmware: 'Proprietary Cloud',
215
+ supportedTools: ['405nm Laser', 'Build Platform'],
216
+ gcodDialect: 'Form OS (proprietary)',
217
+ macros: {
218
+ header: '; Formlabs Form 3 job',
219
+ footer: '; Print complete',
220
+ expose: 'EXPOSE {exposure}ms',
221
+ dwell: 'WAIT {sec}s'
222
+ },
223
+ notes: 'Professional SLA printer with excellent detail and surface finish'
224
+ },
225
+ 'elegoo-mars-3': {
226
+ name: 'Elegoo Mars 3',
227
+ type: 'SLA',
228
+ manufacturer: 'Elegoo',
229
+ workArea: { x: 68.04, y: 120.96, z: 80 }, // mm (2.7x4.76x3.15 inch)
230
+ maxSpindleRPM: 0,
231
+ maxFeedRate: 0,
232
+ firmware: 'Chitubox',
233
+ supportedTools: ['405nm UV Laser'],
234
+ gcodDialect: 'Chitubox',
235
+ macros: {
236
+ header: '; Elegoo Mars 3 job',
237
+ footer: '; Print complete',
238
+ expose: 'EXPOSE {exposure}ms {power}%',
239
+ liftSpeed: 'LIFT {speed}mm/s'
240
+ },
241
+ notes: 'Budget SLA printer, good value for detail work'
242
+ },
243
+ 'snapmaker-2-a350': {
244
+ name: 'Snapmaker 2 A350',
245
+ type: 'Multi (CNC/Laser/3D Print)',
246
+ manufacturer: 'Snapmaker',
247
+ workArea: { x: 345, y: 355, z: 345 }, // mm (max 345x345x345)
248
+ maxSpindleRPM: 10000,
249
+ maxFeedRate: 3000,
250
+ firmware: 'Snapmaker',
251
+ supportedTools: ['CNC Head', 'Laser Head', '3D Print Head'],
252
+ gcodDialect: 'Snapmaker G-code',
253
+ macros: {
254
+ header: 'G21 G90',
255
+ footer: 'M104 S0\nM140 S0\nG28',
256
+ toolChange: 'M200 S{toolId}',
257
+ dwell: 'G4 P{ms}'
258
+ },
259
+ notes: 'Multi-purpose modular machine (CNC/Laser/3D Print)'
260
+ },
261
+ 'longmill-30x40': {
262
+ name: 'LongMill 30x40',
263
+ type: 'CNC',
264
+ manufacturer: 'Sienci Labs',
265
+ workArea: { x: 762, y: 1016, z: 76.2 }, // mm (30x40x3 inch)
266
+ maxSpindleRPM: 10000,
267
+ maxFeedRate: 4000,
268
+ firmware: 'Grbl',
269
+ supportedTools: ['End Mill', 'Ball Mill', 'V-bit', 'Drill'],
270
+ gcodDialect: 'Grbl',
271
+ macros: {
272
+ header: 'G21 G90 G94 M3',
273
+ footer: 'M5 G28 M30',
274
+ toolChange: 'M6 T{tool}',
275
+ dwell: 'G4 P{ms}',
276
+ spindleControl: 'S{rpm} M3'
277
+ },
278
+ notes: 'Large format benchtop CNC router'
279
+ },
280
+ 'generic-cnc': {
281
+ name: 'Generic CNC Router',
282
+ type: 'CNC',
283
+ manufacturer: 'Custom',
284
+ workArea: { x: 500, y: 500, z: 100 },
285
+ maxSpindleRPM: 10000,
286
+ maxFeedRate: 3000,
287
+ firmware: 'Grbl',
288
+ supportedTools: ['End Mill', 'Ball Mill', 'V-bit', 'Drill'],
289
+ gcodDialect: 'Grbl',
290
+ macros: {
291
+ header: 'G21 G90 G94 M3',
292
+ footer: 'M5 G28 M30',
293
+ toolChange: 'M6 T{tool}',
294
+ dwell: 'G4 P{ms}',
295
+ spindleControl: 'S{rpm} M3'
296
+ },
297
+ notes: 'Generic CNC router template'
298
+ },
299
+ 'generic-fdm': {
300
+ name: 'Generic FDM Printer',
301
+ type: 'FDM',
302
+ manufacturer: 'Custom',
303
+ workArea: { x: 200, y: 200, z: 200 },
304
+ maxSpindleRPM: 0,
305
+ maxFeedRate: 150,
306
+ firmware: 'Marlin',
307
+ supportedTools: ['Hotend 0.4mm'],
308
+ gcodDialect: 'Marlin',
309
+ macros: {
310
+ header: 'M109 S{nozzleTemp}\nM190 S{bedTemp}\nG28\nG29',
311
+ footer: 'M104 S0\nM140 S0\nG28 X0 Y0\nM84',
312
+ toolChange: '; Manual nozzle swap',
313
+ dwell: 'G4 S{sec}',
314
+ retraction: 'G10\nG11'
315
+ },
316
+ notes: 'Generic FDM printer template'
317
+ },
318
+ 'generic-sla': {
319
+ name: 'Generic SLA Printer',
320
+ type: 'SLA',
321
+ manufacturer: 'Custom',
322
+ workArea: { x: 100, y: 60, z: 100 },
323
+ maxSpindleRPM: 0,
324
+ maxFeedRate: 0,
325
+ firmware: 'Proprietary',
326
+ supportedTools: ['UV Laser'],
327
+ gcodDialect: 'Chitubox',
328
+ macros: {
329
+ header: '; SLA job',
330
+ footer: '; Print complete',
331
+ expose: 'EXPOSE {exposure}ms',
332
+ liftSpeed: 'LIFT {speed}mm/s'
333
+ },
334
+ notes: 'Generic SLA printer template'
335
+ },
336
+ 'generic-laser': {
337
+ name: 'Generic Laser Cutter',
338
+ type: 'Laser',
339
+ manufacturer: 'Custom',
340
+ workArea: { x: 400, y: 600, z: 50 },
341
+ maxSpindleRPM: 0,
342
+ maxFeedRate: 1000,
343
+ firmware: 'Proprietary',
344
+ supportedTools: ['CO2 Laser', 'Fiber Laser'],
345
+ gcodDialect: 'LightBurn',
346
+ macros: {
347
+ header: '; Laser job',
348
+ footer: '; Job complete',
349
+ powerControl: 'POWER {percent}%',
350
+ speedControl: 'SPEED {percent}%'
351
+ },
352
+ notes: 'Generic laser cutter template'
353
+ }
354
+ };
355
+
356
+ /**
357
+ * Machine library API
358
+ */
359
+ const machineAPI = {
360
+ /**
361
+ * Get machine profile by ID
362
+ */
363
+ get(machineId) {
364
+ return MACHINE_PROFILES[machineId] || null;
365
+ },
366
+
367
+ /**
368
+ * List all machine profiles
369
+ */
370
+ list() {
371
+ return Object.keys(MACHINE_PROFILES).map(id => ({
372
+ id,
373
+ ...MACHINE_PROFILES[id]
374
+ }));
375
+ },
376
+
377
+ /**
378
+ * List machines by type (CNC, FDM, SLA, Laser)
379
+ */
380
+ listByType(type) {
381
+ return Object.keys(MACHINE_PROFILES)
382
+ .filter(id => MACHINE_PROFILES[id].type === type)
383
+ .map(id => ({ id, ...MACHINE_PROFILES[id] }));
384
+ },
385
+
386
+ /**
387
+ * Check if machine can handle given tooling requirements
388
+ */
389
+ canHandle(machineId, requirements) {
390
+ const machine = MACHINE_PROFILES[machineId];
391
+ if (!machine) return false;
392
+
393
+ const { toolDiameter = 0, maxRPM = 0, workAreaX = 0, workAreaY = 0, workAreaZ = 0 } = requirements;
394
+
395
+ return (
396
+ machine.maxSpindleRPM >= maxRPM &&
397
+ machine.workArea.x >= workAreaX &&
398
+ machine.workArea.y >= workAreaY &&
399
+ machine.workArea.z >= workAreaZ
400
+ );
401
+ },
402
+
403
+ /**
404
+ * Get G-code macro for machine
405
+ */
406
+ getMacro(machineId, macroType) {
407
+ const machine = MACHINE_PROFILES[machineId];
408
+ return machine && machine.macros ? machine.macros[macroType] || '' : '';
409
+ },
410
+
411
+ /**
412
+ * Get work area dimensions
413
+ */
414
+ getWorkArea(machineId) {
415
+ const machine = MACHINE_PROFILES[machineId];
416
+ return machine ? machine.workArea : null;
417
+ },
418
+
419
+ /**
420
+ * Get max spindle RPM
421
+ */
422
+ getMaxRPM(machineId) {
423
+ const machine = MACHINE_PROFILES[machineId];
424
+ return machine ? machine.maxSpindleRPM : 0;
425
+ },
426
+
427
+ /**
428
+ * Get max feed rate
429
+ */
430
+ getMaxFeedRate(machineId) {
431
+ const machine = MACHINE_PROFILES[machineId];
432
+ return machine ? machine.maxFeedRate : 0;
433
+ },
434
+
435
+ /**
436
+ * Check if machine supports tool type
437
+ */
438
+ supportsTool(machineId, toolType) {
439
+ const machine = MACHINE_PROFILES[machineId];
440
+ return machine && machine.supportedTools.includes(toolType);
441
+ },
442
+
443
+ /**
444
+ * Create custom machine profile
445
+ */
446
+ create(machineId, profile) {
447
+ if (MACHINE_PROFILES[machineId]) {
448
+ console.warn(`Machine "${machineId}" already exists. Use update() to modify.`);
449
+ return false;
450
+ }
451
+
452
+ MACHINE_PROFILES[machineId] = {
453
+ name: profile.name || machineId,
454
+ type: profile.type || 'CNC',
455
+ manufacturer: profile.manufacturer || 'Custom',
456
+ workArea: profile.workArea || { x: 300, y: 300, z: 100 },
457
+ maxSpindleRPM: profile.maxSpindleRPM || 10000,
458
+ maxFeedRate: profile.maxFeedRate || 3000,
459
+ firmware: profile.firmware || 'Grbl',
460
+ supportedTools: profile.supportedTools || ['End Mill', 'Drill'],
461
+ gcodDialect: profile.gcodDialect || 'Grbl',
462
+ macros: profile.macros || {},
463
+ notes: profile.notes || 'Custom machine'
464
+ };
465
+
466
+ return true;
467
+ },
468
+
469
+ /**
470
+ * Update existing machine profile
471
+ */
472
+ update(machineId, updates) {
473
+ if (!MACHINE_PROFILES[machineId]) {
474
+ console.warn(`Machine "${machineId}" not found.`);
475
+ return false;
476
+ }
477
+
478
+ MACHINE_PROFILES[machineId] = {
479
+ ...MACHINE_PROFILES[machineId],
480
+ ...updates
481
+ };
482
+
483
+ return true;
484
+ },
485
+
486
+ /**
487
+ * Delete custom machine
488
+ */
489
+ delete(machineId) {
490
+ if (!MACHINE_PROFILES[machineId]) {
491
+ console.warn(`Machine "${machineId}" not found.`);
492
+ return false;
493
+ }
494
+
495
+ delete MACHINE_PROFILES[machineId];
496
+ return true;
497
+ },
498
+
499
+ /**
500
+ * Export machine profile as JSON
501
+ */
502
+ export(machineId) {
503
+ const machine = MACHINE_PROFILES[machineId];
504
+ if (!machine) return null;
505
+
506
+ return JSON.stringify({
507
+ id: machineId,
508
+ ...machine
509
+ }, null, 2);
510
+ },
511
+
512
+ /**
513
+ * Import machine profile from JSON
514
+ */
515
+ import(jsonString) {
516
+ try {
517
+ const profile = JSON.parse(jsonString);
518
+ const id = profile.id || `imported-${Date.now()}`;
519
+
520
+ const { id: _, ...rest } = profile;
521
+ return this.create(id, rest);
522
+ } catch (err) {
523
+ console.error('Failed to import machine profile:', err);
524
+ return false;
525
+ }
526
+ }
527
+ };
528
+
529
+ // Register on window.cycleCAD
530
+ window.cycleCAD = window.cycleCAD || {};
531
+ window.cycleCAD.machines = machineAPI;
532
+
533
+ console.log('[cycleCAD.machines] Module loaded. 15+ preset machines available.');
534
+ })();