cyclecad 1.0.5 → 1.0.6
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 +7 -2
- package/app/js/ai-copilot.js +13 -1
- package/app/js/operations.js +13 -16
- package/package.json +1 -1
package/app/index.html
CHANGED
|
@@ -2904,6 +2904,11 @@
|
|
|
2904
2904
|
const pParams = prompt.params || prompt;
|
|
2905
2905
|
const result = createPrimitive(pType, pParams);
|
|
2906
2906
|
const mesh = result.mesh || result;
|
|
2907
|
+
// Apply position offset for multi-item placement (e.g., 4 holes around a part)
|
|
2908
|
+
if (pParams._offsetX || pParams._offsetZ) {
|
|
2909
|
+
mesh.position.x += (pParams._offsetX || 0) * 0.1;
|
|
2910
|
+
mesh.position.z += (pParams._offsetZ || 0) * 0.1;
|
|
2911
|
+
}
|
|
2907
2912
|
addToScene(mesh);
|
|
2908
2913
|
if (result.wireframe) addToScene(result.wireframe);
|
|
2909
2914
|
|
|
@@ -3554,7 +3559,7 @@
|
|
|
3554
3559
|
init();
|
|
3555
3560
|
}
|
|
3556
3561
|
|
|
3557
|
-
window.cycleCAD = Object.assign(window.cycleCAD || {}, { version: '1.0.
|
|
3562
|
+
window.cycleCAD = Object.assign(window.cycleCAD || {}, { version: '1.0.6', APP, init });
|
|
3558
3563
|
|
|
3559
3564
|
// Expose dialog functions globally so inline onclick="" handlers work
|
|
3560
3565
|
window.openDialog = openDialog;
|
|
@@ -5267,6 +5272,6 @@
|
|
|
5267
5272
|
</div>
|
|
5268
5273
|
</div>
|
|
5269
5274
|
|
|
5270
|
-
<span id="version-badge" style="position:fixed;bottom:42px;left:50%;transform:translateX(-50%);z-index:999;font-size:0.9rem;color:rgba(255,255,255,0.9);letter-spacing:0.1em;white-space:nowrap;padding:6px 16px;user-select:all;pointer-events:auto;font-family:monospace;font-weight:700;background:rgba(0,0,0,0.7);border:1px solid rgba(88,166,255,0.4);border-radius:6px;text-shadow:0 1px 3px rgba(0,0,0,0.5);" title="cycleCAD version">cycleCAD v1.0.
|
|
5275
|
+
<span id="version-badge" style="position:fixed;bottom:42px;left:50%;transform:translateX(-50%);z-index:999;font-size:0.9rem;color:rgba(255,255,255,0.9);letter-spacing:0.1em;white-space:nowrap;padding:6px 16px;user-select:all;pointer-events:auto;font-family:monospace;font-weight:700;background:rgba(0,0,0,0.7);border:1px solid rgba(88,166,255,0.4);border-radius:6px;text-shadow:0 1px 3px rgba(0,0,0,0.5);" title="cycleCAD version">cycleCAD v1.0.6</span>
|
|
5271
5276
|
</body>
|
|
5272
5277
|
</html>
|
package/app/js/ai-copilot.js
CHANGED
|
@@ -948,7 +948,19 @@ export async function executeTextCommand(prompt) {
|
|
|
948
948
|
if (window._executeParsedPrompt) {
|
|
949
949
|
const method = cmd.method || '';
|
|
950
950
|
const type = method.replace('shape.', '').replace('feature.', '');
|
|
951
|
-
|
|
951
|
+
// Handle count param (e.g., 4 mounting holes)
|
|
952
|
+
const count = cmd.params?.count || 1;
|
|
953
|
+
for (let ci = 0; ci < count; ci++) {
|
|
954
|
+
const p = Object.assign({}, cmd.params);
|
|
955
|
+
// Offset multiple items so they don't stack
|
|
956
|
+
if (count > 1) {
|
|
957
|
+
const angle = (ci / count) * Math.PI * 2;
|
|
958
|
+
const spread = (p.radius || 5) * 4;
|
|
959
|
+
p._offsetX = Math.cos(angle) * spread;
|
|
960
|
+
p._offsetZ = Math.sin(angle) * spread;
|
|
961
|
+
}
|
|
962
|
+
window._executeParsedPrompt({ type, params: p });
|
|
963
|
+
}
|
|
952
964
|
results.push({ ok: true, method });
|
|
953
965
|
} else if (window.cycleCAD && window.cycleCAD.execute) {
|
|
954
966
|
const result = await window.cycleCAD.execute(cmd);
|
package/app/js/operations.js
CHANGED
|
@@ -349,10 +349,9 @@ export function createPrimitive(type, params = {}, options = {}) {
|
|
|
349
349
|
const { material = 'steel' } = options;
|
|
350
350
|
let geometry;
|
|
351
351
|
|
|
352
|
-
// Scale factor:
|
|
353
|
-
//
|
|
354
|
-
|
|
355
|
-
const SCALE = 1.0;
|
|
352
|
+
// Scale factor: dimensions in mm, viewport units are ~10x smaller for good camera framing
|
|
353
|
+
// Camera starts at (150,100,150) so a 100mm cube should be ~10 units to look right
|
|
354
|
+
const SCALE = 0.1;
|
|
356
355
|
|
|
357
356
|
switch (type) {
|
|
358
357
|
case 'box':
|
|
@@ -403,19 +402,17 @@ export function createPrimitive(type, params = {}, options = {}) {
|
|
|
403
402
|
break;
|
|
404
403
|
|
|
405
404
|
case 'hole': {
|
|
406
|
-
// Create a cylinder for hole preview (visual
|
|
407
|
-
// Used by feature.hole commands from AI copilot
|
|
405
|
+
// Create a dark cylinder for hole preview (visual subtract indicator)
|
|
408
406
|
const holeRadius = (params.radius || 5) * SCALE;
|
|
409
|
-
const holeDepth = (params.depth || 20) * SCALE;
|
|
410
|
-
geometry = new THREE.CylinderGeometry(
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
break;
|
|
407
|
+
const holeDepth = (params.depth || params.height || 20) * SCALE;
|
|
408
|
+
geometry = new THREE.CylinderGeometry(holeRadius, holeRadius, holeDepth, 16, 1, false);
|
|
409
|
+
// Override material to dark red so holes are clearly visible
|
|
410
|
+
const holeMat = new THREE.MeshStandardMaterial({ color: 0x882222, metalness: 0.3, roughness: 0.7, transparent: true, opacity: 0.85 });
|
|
411
|
+
const holeMesh = new THREE.Mesh(geometry, holeMat);
|
|
412
|
+
holeMesh.castShadow = true;
|
|
413
|
+
holeMesh.receiveShadow = true;
|
|
414
|
+
const holeWire = createWireframeEdges(holeMesh);
|
|
415
|
+
return { mesh: holeMesh, wireframe: holeWire, params: { type, params, options } };
|
|
419
416
|
}
|
|
420
417
|
|
|
421
418
|
case 'bracket': {
|
package/package.json
CHANGED