cyclecad 3.10.2 → 3.10.3
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/app/index.html +1 -1
- package/app/js/modules/ai-copilot.js +99 -1
- package/package.json +1 -1
package/app/index.html
CHANGED
|
@@ -1538,7 +1538,7 @@ window._dismissSplash = function(action) {
|
|
|
1538
1538
|
|
|
1539
1539
|
<!-- Killer Feature Modules -->
|
|
1540
1540
|
<script src="/app/js/agent-api.js?v=a41b98a5"></script>
|
|
1541
|
-
<script src="/app/js/modules/ai-copilot.js?v=
|
|
1541
|
+
<script src="/app/js/modules/ai-copilot.js?v=14e5d5d7"></script>
|
|
1542
1542
|
<script src="/app/js/modules/text-to-cad.js"></script>
|
|
1543
1543
|
<script src="/app/js/modules/photo-to-cad.js"></script>
|
|
1544
1544
|
<script src="/app/js/modules/manufacturability.js"></script>
|
|
@@ -390,7 +390,105 @@
|
|
|
390
390
|
{method:'view.fit', params:{}}
|
|
391
391
|
];
|
|
392
392
|
}
|
|
393
|
-
//
|
|
393
|
+
// DIN 125 washer (M3-M12)
|
|
394
|
+
const washerM = p.match(/\bm(\d+)\s*washer|washer\s+m(\d+)|din\s*125\s*m?(\d+)/);
|
|
395
|
+
if (washerM) {
|
|
396
|
+
const size = parseInt(washerM[1]||washerM[2]||washerM[3]);
|
|
397
|
+
const outerR = ({3:3.5, 4:4.5, 5:5.3, 6:6.4, 8:8.4, 10:10.5, 12:13})[size] || size*1.2;
|
|
398
|
+
const thick = ({3:0.5, 4:0.8, 5:1, 6:1.6, 8:1.6, 10:2, 12:2.5})[size] || size*0.2;
|
|
399
|
+
const holeR = (size + 0.4) / 2;
|
|
400
|
+
return [
|
|
401
|
+
{method:'sketch.start', params:{plane:'XY'}},
|
|
402
|
+
{method:'sketch.circle', params:{radius: outerR}},
|
|
403
|
+
{method:'ops.extrude', params:{depth: thick, position:[0,0,0]}, note:'DIN 125 M'+size+' washer'},
|
|
404
|
+
{method:'ops.hole', params:{position:[0, thick, 0], radius: holeR, depth: thick+2}, note:'M'+size+' hole'},
|
|
405
|
+
{method:'view.set', params:{view:'iso'}},
|
|
406
|
+
{method:'view.fit', params:{}}
|
|
407
|
+
];
|
|
408
|
+
}
|
|
409
|
+
// Flange with bolt circle
|
|
410
|
+
const flangeM = p.match(/flange/);
|
|
411
|
+
if (flangeM) {
|
|
412
|
+
const odM = p.match(/(\d+)\s*mm/);
|
|
413
|
+
const od = odM ? parseInt(odM[1]) : 80;
|
|
414
|
+
const nM = p.match(/(\d+)\s*(?:bolt\s*)?holes?/);
|
|
415
|
+
const nHoles = nM ? parseInt(nM[1]) : 4;
|
|
416
|
+
const pcdM = p.match(/pcd\s*(\d+)|bolt\s*circle\s*(\d+)/);
|
|
417
|
+
const pcd = pcdM ? parseInt(pcdM[1]||pcdM[2]) : Math.round(od*0.7);
|
|
418
|
+
const thick = 8;
|
|
419
|
+
const plan = [
|
|
420
|
+
{method:'sketch.start', params:{plane:'XY'}},
|
|
421
|
+
{method:'sketch.circle', params:{radius: od/2}},
|
|
422
|
+
{method:'ops.extrude', params:{depth: thick, position:[0,0,0]}, note:'flange body Ø'+od},
|
|
423
|
+
{method:'ops.hole', params:{position:[0, thick, 0], radius: Math.max(5, od/8), depth: thick+2}, note:'center bore'}
|
|
424
|
+
];
|
|
425
|
+
for (let i = 0; i < nHoles; i++) {
|
|
426
|
+
const a = (i / nHoles) * Math.PI * 2;
|
|
427
|
+
const x = Math.cos(a) * pcd/2, z = Math.sin(a) * pcd/2;
|
|
428
|
+
plan.push({method:'ops.hole', params:{position:[x, thick/2, z], radius: 3, depth: thick+2}, note:'bolt hole '+(i+1)+'/'+nHoles});
|
|
429
|
+
}
|
|
430
|
+
plan.push({method:'view.set', params:{view:'iso'}});
|
|
431
|
+
plan.push({method:'view.fit', params:{}});
|
|
432
|
+
return plan;
|
|
433
|
+
}
|
|
434
|
+
// Threaded rod / stud
|
|
435
|
+
const rodM = p.match(/threaded\s*rod|m(\d+)\s*rod|m(\d+)\s*stud|studding/);
|
|
436
|
+
if (rodM) {
|
|
437
|
+
const sM = p.match(/m(\d+)/);
|
|
438
|
+
const size = sM ? parseInt(sM[1]) : 8;
|
|
439
|
+
const lM = p.match(/(\d+)\s*mm/);
|
|
440
|
+
const len = lM ? parseInt(lM[1]) : 100;
|
|
441
|
+
return [
|
|
442
|
+
{method:'sketch.start', params:{plane:'XY'}},
|
|
443
|
+
{method:'sketch.circle', params:{radius: size/2}},
|
|
444
|
+
{method:'ops.extrude', params:{depth: len, position:[0,0,0]}, note:'M'+size+' threaded rod, '+len+'mm long'},
|
|
445
|
+
{method:'view.set', params:{view:'iso'}},
|
|
446
|
+
{method:'view.fit', params:{}}
|
|
447
|
+
];
|
|
448
|
+
}
|
|
449
|
+
// Mounting plate
|
|
450
|
+
const plateM = p.match(/mounting\s*plate|base\s*plate|flat\s*plate/);
|
|
451
|
+
if (plateM) {
|
|
452
|
+
const dimM = p.match(/(\d+)\s*x\s*(\d+)/);
|
|
453
|
+
const w = dimM ? parseInt(dimM[1]) : 120;
|
|
454
|
+
const h = dimM ? parseInt(dimM[2]) : 80;
|
|
455
|
+
const thick = 6;
|
|
456
|
+
const nM = p.match(/(\d+)\s*holes?/);
|
|
457
|
+
const nHoles = nM ? parseInt(nM[1]) : 4;
|
|
458
|
+
const plan = [
|
|
459
|
+
{method:'sketch.start', params:{plane:'XY'}},
|
|
460
|
+
{method:'sketch.rect', params:{width: w, height: h}},
|
|
461
|
+
{method:'ops.extrude', params:{depth: thick, position:[0,0,0]}, note: w+'x'+h+'x'+thick+' mounting plate'}
|
|
462
|
+
];
|
|
463
|
+
if (nHoles === 4) {
|
|
464
|
+
const mx = w/2 - 10, mz = h/2 - 10;
|
|
465
|
+
[[-mx,-mz],[mx,-mz],[-mx,mz],[mx,mz]].forEach((pp,i) => {
|
|
466
|
+
plan.push({method:'ops.hole', params:{position:[pp[0], thick/2, pp[1]], radius:3, depth:thick+2}, note:'corner hole '+(i+1)});
|
|
467
|
+
});
|
|
468
|
+
} else {
|
|
469
|
+
for (let i = 0; i < nHoles; i++) {
|
|
470
|
+
const x = -w/2 + 10 + (i/(nHoles-1)) * (w-20);
|
|
471
|
+
plan.push({method:'ops.hole', params:{position:[x, thick/2, 0], radius:3, depth:thick+2}, note:'hole '+(i+1)});
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
plan.push({method:'view.set', params:{view:'iso'}});
|
|
475
|
+
plan.push({method:'view.fit', params:{}});
|
|
476
|
+
return plan;
|
|
477
|
+
}
|
|
478
|
+
// Generic box NxNxN with optional fillet
|
|
479
|
+
const boxM = p.match(/\bbox\b|\bblock\b|\bcube\b|\bcuboid\b/);
|
|
480
|
+
const boxDim = p.match(/(\d+)\s*[x×]\s*(\d+)\s*[x×]\s*(\d+)/);
|
|
481
|
+
if (boxM && boxDim) {
|
|
482
|
+
const w = parseInt(boxDim[1]), h = parseInt(boxDim[2]), d = parseInt(boxDim[3]);
|
|
483
|
+
return [
|
|
484
|
+
{method:'sketch.start', params:{plane:'XY'}},
|
|
485
|
+
{method:'sketch.rect', params:{width: w, height: d}},
|
|
486
|
+
{method:'ops.extrude', params:{depth: h, position:[0,0,0]}, note: w+'x'+h+'x'+d+' box'},
|
|
487
|
+
{method:'view.set', params:{view:'iso'}},
|
|
488
|
+
{method:'view.fit', params:{}}
|
|
489
|
+
];
|
|
490
|
+
}
|
|
491
|
+
// L-bracket with holes
|
|
394
492
|
if (/l-?bracket|mounting\s*bracket|angle\s*bracket/.test(p)) {
|
|
395
493
|
const lenM = p.match(/(\d+)\s*mm/);
|
|
396
494
|
const length = lenM ? parseInt(lenM[1]) : 100;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyclecad",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.3",
|
|
4
4
|
"description": "Browser-based parametric 3D CAD modeler with AI-powered tools, native Inventor file parsing, and smart assembly management. No install required.",
|
|
5
5
|
"main": "index.html",
|
|
6
6
|
"bin": {
|