forgecad 0.6.3 → 0.8.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.
Files changed (234) hide show
  1. package/README.md +3 -12
  2. package/dist/assets/{AdminPage-CeqCUUgu.js → AdminPage-D4bocK4E.js} +250 -151
  3. package/dist/assets/{BlogPage-P_AJP0v9.js → BlogPage-CJEXL_zJ.js} +94 -70
  4. package/dist/assets/{DocsPage-CKRV2iq2.js → DocsPage-D3A_g8V3.js} +329 -163
  5. package/dist/assets/{EditorApp-CnC2k4cW.css → EditorApp-BWYUSpUN.css} +590 -136
  6. package/dist/assets/EditorApp-Cihhqcsq.js +11692 -0
  7. package/dist/assets/{EmbedViewer-DBlzmQ5i.js → EmbedViewer-kWjKaC_t.js} +2 -4
  8. package/dist/assets/LandingPageProofDriven-Bg2IUc3l.css +856 -0
  9. package/dist/assets/LandingPageProofDriven-DXkKlyhI.js +601 -0
  10. package/dist/assets/PricingPage-BsU5vzEx.js +232 -0
  11. package/dist/assets/{SettingsPage-BqCh9JcC.js → SettingsPage-PqvpAKIs.js} +129 -5
  12. package/dist/assets/{evalWorker-Ql-aKwLA.js → evalWorker-C-hzNUMy.js} +8949 -3161
  13. package/dist/assets/{Viewport-CoB46f5R.js → index-Pz321YAt.js} +38382 -7501
  14. package/dist/assets/{index-2hfs_ub0.css → index-ay13WNfa.css} +726 -53
  15. package/dist/assets/{javascript-DCxGoE5Y.js → javascript-DAl8Gmyo.js} +1 -1
  16. package/dist/assets/{manifold-CqNMHHKO.js → manifold-BcbjWLIo.js} +4 -3
  17. package/dist/assets/{manifold-Cce9wRFz.js → manifold-DBckbFgx.js} +1 -1
  18. package/dist/assets/{manifold-D6BeHIOo.js → manifold-O2AAGXyj.js} +1 -1
  19. package/dist/assets/{reportWorker-sFEFonXf.js → reportWorker-Dxr-5A7w.js} +8760 -3559
  20. package/dist/assets/{vendor-react-Dt7-aaJH.js → vendor-react-CG3i_wp0.js} +65 -8
  21. package/dist/docs/index.html +2 -2
  22. package/dist/docs-raw/CLI.md +341 -718
  23. package/dist/docs-raw/generated/assembly.md +699 -112
  24. package/dist/docs-raw/generated/concepts.md +1834 -1346
  25. package/dist/docs-raw/generated/core.md +1012 -1059
  26. package/dist/docs-raw/generated/curves.md +759 -116
  27. package/dist/docs-raw/generated/lib.md +43 -748
  28. package/dist/docs-raw/generated/output.md +139 -245
  29. package/dist/docs-raw/generated/sdf.md +208 -0
  30. package/dist/docs-raw/generated/sheet-metal.md +473 -21
  31. package/dist/docs-raw/generated/sketch.md +1518 -362
  32. package/dist/docs-raw/generated/viewport.md +368 -299
  33. package/dist/docs-raw/generated/wood.md +104 -0
  34. package/dist/index.html +2 -2
  35. package/dist/landing/proof-ams-adapter.png +0 -0
  36. package/dist/landing/proof-bolt-and-nut.png +0 -0
  37. package/dist/landing/proof-fillet-enclosure.png +0 -0
  38. package/dist/landing/proof-glasses.png +0 -0
  39. package/dist/landing/proof-gyroid.png +0 -0
  40. package/dist/sitemap.xml +6 -6
  41. package/dist-cli/forgecad.js +12321 -5700
  42. package/dist-cli/forgecad.js.map +1 -0
  43. package/dist-cli/solver-46FFSK2U.js +363 -0
  44. package/dist-cli/solver-46FFSK2U.js.map +1 -0
  45. package/dist-skill/CONTEXT.md +4890 -6302
  46. package/dist-skill/SKILL-dev.md +22 -66
  47. package/dist-skill/SKILL.md +20 -59
  48. package/dist-skill/docs/API/core/concepts.md +37 -92
  49. package/dist-skill/docs/CLI.md +341 -718
  50. package/dist-skill/docs/generated/assembly.md +699 -112
  51. package/dist-skill/docs/generated/core.md +1012 -1059
  52. package/dist-skill/docs/generated/curves.md +759 -116
  53. package/dist-skill/docs/generated/lib.md +43 -748
  54. package/dist-skill/docs/generated/output.md +139 -245
  55. package/dist-skill/docs/generated/sdf.md +208 -0
  56. package/dist-skill/docs/generated/sheet-metal.md +473 -21
  57. package/dist-skill/docs/generated/sketch.md +1518 -362
  58. package/dist-skill/docs/generated/viewport.md +368 -299
  59. package/dist-skill/docs/generated/wood.md +104 -0
  60. package/dist-skill/docs/guides/coordinate-system.md +11 -17
  61. package/dist-skill/docs/guides/geometry-conventions.md +13 -70
  62. package/dist-skill/docs/guides/joint-design.md +78 -0
  63. package/dist-skill/docs/guides/modeling-recipes.md +22 -195
  64. package/dist-skill/docs/guides/positioning.md +88 -147
  65. package/dist-skill/docs-dev/API/core/concepts.md +78 -0
  66. package/dist-skill/docs-dev/CLI.md +488 -0
  67. package/dist-skill/{docs → docs-dev}/blueprint-first.md +5 -0
  68. package/dist-skill/{docs → docs-dev}/coding-best-practices.md +6 -8
  69. package/dist-skill/{docs → docs-dev}/coding.md +2 -4
  70. package/dist-skill/docs-dev/component-model.md +164 -0
  71. package/dist-skill/docs-dev/generated/assembly.md +779 -0
  72. package/dist-skill/docs-dev/generated/core.md +1676 -0
  73. package/dist-skill/docs-dev/generated/curves.md +855 -0
  74. package/dist-skill/docs-dev/generated/lib.md +55 -0
  75. package/dist-skill/docs-dev/generated/output.md +234 -0
  76. package/dist-skill/docs-dev/generated/sdf.md +208 -0
  77. package/dist-skill/docs-dev/generated/sheet-metal.md +506 -0
  78. package/dist-skill/docs-dev/generated/sketch.md +1753 -0
  79. package/dist-skill/docs-dev/generated/viewport.md +513 -0
  80. package/dist-skill/docs-dev/generated/wood.md +104 -0
  81. package/dist-skill/docs-dev/guides/coordinate-system.md +46 -0
  82. package/dist-skill/docs-dev/guides/geometry-conventions.md +52 -0
  83. package/dist-skill/docs-dev/guides/joint-design.md +78 -0
  84. package/dist-skill/docs-dev/guides/modeling-recipes.md +77 -0
  85. package/dist-skill/docs-dev/guides/positioning.md +151 -0
  86. package/dist-skill/{docs → docs-dev}/guides/skill-maintenance.md +21 -10
  87. package/dist-skill/{docs → docs-dev}/internals/compiler.md +5 -6
  88. package/dist-skill/{docs → docs-dev}/internals/constraint-solver-quality.md +0 -1
  89. package/dist-skill/{docs → docs-dev}/internals/constraint-solver.md +0 -1
  90. package/dist-skill/{docs → docs-dev}/internals/sketch-2d-pipeline.md +2 -3
  91. package/examples/api/attachTo-basics.forge.js +8 -8
  92. package/examples/api/bill-of-materials.forge.js +9 -9
  93. package/examples/api/bolt-pattern.forge.js +5 -5
  94. package/examples/api/boolean-operations.forge.js +5 -5
  95. package/examples/api/bounding-box-visualizer.forge.js +3 -3
  96. package/examples/api/clone-duplicate.forge.js +2 -2
  97. package/examples/api/colors-union-vs-array.forge.js +6 -6
  98. package/examples/api/connector-assembly.forge.js +8 -6
  99. package/examples/api/connector-basics.forge.js +7 -7
  100. package/examples/api/constrained-sketch-mechanical.forge.js +4 -4
  101. package/examples/api/elbow-test.forge.js +3 -3
  102. package/examples/api/extrude-options.forge.js +8 -14
  103. package/examples/api/feature-created-faces.forge.js +6 -10
  104. package/examples/api/fillet-showcase.forge.js +2 -2
  105. package/examples/api/folded-service-panel-cover.forge.js +2 -2
  106. package/examples/api/gears-tier1.forge.js +5 -5
  107. package/examples/api/group-test.forge.js +3 -3
  108. package/examples/api/group-vs-union.forge.js +1 -1
  109. package/examples/api/highlight-debug.forge.js +4 -0
  110. package/examples/api/js-module-pillars.js +1 -1
  111. package/examples/api/js-module-scene.js +2 -2
  112. package/examples/api/mesh-import-slats.forge.js +4 -4
  113. package/examples/api/patterns.forge.js +3 -3
  114. package/examples/api/pointAlong-orientation.forge.js +3 -3
  115. package/examples/api/profile-2020-b-slot6.forge.js +4 -5
  116. package/examples/api/route-perimeter-flange.forge.js +1 -1
  117. package/examples/api/sdf-rover-demo.forge.js +10 -10
  118. package/examples/api/sketch-on-face-demo.forge.js +2 -2
  119. package/examples/api/sketch-regions.forge.js +4 -4
  120. package/examples/api/sketch-rounding-strategies.forge.js +1 -1
  121. package/examples/api/smooth-curve-connections.forge.js +1 -1
  122. package/examples/api/transition-curves.forge.js +4 -4
  123. package/examples/api/variable-sweep-pure-sdf-test.forge.js +162 -0
  124. package/examples/api/variable-sweep-test.forge.js +2 -2
  125. package/examples/api/wood-joinery.forge.js +60 -0
  126. package/examples/compiler-corpus/enclosure-shell-cuts.forge.js +3 -3
  127. package/examples/compiler-corpus/fastener-plate-variants.forge.js +2 -2
  128. package/examples/constraints/01-fully-constrained-rect.forge.js +2 -2
  129. package/examples/constraints/02-underconstrained-triangle.forge.js +1 -1
  130. package/examples/constraints/03-redundant-constraints.forge.js +2 -2
  131. package/examples/constraints/05-parallel-with-linedistance.forge.js +2 -2
  132. package/examples/constraints/06-complex-spectrogram.forge.js +1 -1
  133. package/examples/constraints/07-perpendicular-chain.forge.js +4 -4
  134. package/examples/constraints/08-symmetric-bracket.forge.js +4 -4
  135. package/examples/constraints/09-stress-spiral.forge.js +1 -1
  136. package/examples/constraints/10-stress-honeycomb.forge.js +1 -1
  137. package/examples/constraints/11-surface-grid.forge.js +2 -2
  138. package/examples/constraints/12-surface-nested.forge.js +4 -4
  139. package/examples/constraints/13-surface-complex.forge.js +1 -1
  140. package/examples/exact-arc-housing.forge.js +12 -0
  141. package/examples/experiments/drone-arm.forge.js +53 -0
  142. package/examples/furniture/adjustable-table.forge.js +15 -15
  143. package/examples/furniture/bathroom.forge.js +26 -26
  144. package/examples/furniture/chair.forge.js +13 -13
  145. package/examples/furniture/picture-frame.forge.js +6 -6
  146. package/examples/furniture/shoe-rack-doors.forge.js +8 -8
  147. package/examples/furniture/shoe-rack.forge.js +7 -7
  148. package/examples/furniture/table-lamp.forge.js +8 -8
  149. package/examples/gcode/lissajous-vase.forge.js +4 -4
  150. package/examples/gcode/math-surface.forge.js +3 -3
  151. package/examples/gcode/parametric-vase.forge.js +4 -4
  152. package/examples/gcode/spiral-tower.forge.js +4 -4
  153. package/examples/generative/crystal-growth.forge.js +9 -9
  154. package/examples/generative/frost-spires.forge.js +9 -9
  155. package/examples/generative/golden-spiral-tower.forge.js +11 -11
  156. package/examples/generative/molten-forge.forge.js +6 -6
  157. package/examples/generative/neon-coral.forge.js +7 -7
  158. package/examples/mechanical/3d-printer.forge.js +37 -37
  159. package/examples/mechanical/5-finger-robot-hand.forge.js +19 -19
  160. package/examples/mechanical/airplane-propeller.forge.js +9 -9
  161. package/examples/mechanical/bolt-and-nut.forge.js +10 -10
  162. package/examples/mechanical/door-with-hinges.forge.js +7 -7
  163. package/examples/mechanical/fillet-enclosure.forge.js +15 -11
  164. package/examples/mechanical/headphone-hanger-v2.forge.js +11 -11
  165. package/examples/mechanical/robot_hand.forge.js +24 -24
  166. package/examples/mechanical/robot_hand_2.forge.js +26 -26
  167. package/examples/nurbs-surface.forge.js +8 -0
  168. package/examples/nurbs-tube.forge.js +7 -0
  169. package/examples/products/bottle.forge.js +8 -8
  170. package/examples/products/chess-set.forge.js +25 -25
  171. package/examples/products/classical-piano.forge.js +20 -20
  172. package/examples/products/clock.forge.js +33 -33
  173. package/examples/products/cup.forge.js +5 -5
  174. package/examples/products/iphone.forge.js +20 -20
  175. package/examples/products/laptop.forge.js +24 -24
  176. package/examples/products/laser-cut-box.forge.js +6 -6
  177. package/examples/products/laser-cut-tray.forge.js +6 -6
  178. package/examples/products/liquid-soap-dispenser.forge.js +23 -23
  179. package/examples/products/origami-fish.forge.js +14 -12
  180. package/examples/products/spiderman-cake.forge.js +6 -6
  181. package/examples/shelf/container.forge.js +5 -5
  182. package/examples/shelf/shelf-unit.forge.js +6 -6
  183. package/examples/toolbox/bolted-joint.forge.js +7 -7
  184. package/package.json +9 -4
  185. package/dist/assets/EditorApp-B-vQvgam.js +0 -9888
  186. package/dist/assets/LandingPage-C5n9hDXI.js +0 -322
  187. package/dist/assets/PublishedModelPage-Dt7PCVBj.js +0 -146
  188. package/dist/assets/__vite-browser-external-CURh0WXD.js +0 -8
  189. package/dist/assets/deserializeRunResult-BLAFoiE0.js +0 -19365
  190. package/dist/assets/index-1CYp3zUp.js +0 -1455
  191. package/dist-skill/docs/API/API.md +0 -1666
  192. package/dist-skill/docs/API/README.md +0 -37
  193. package/dist-skill/docs/API/assembly/assembly.md +0 -617
  194. package/dist-skill/docs/API/core/edge-queries.md +0 -130
  195. package/dist-skill/docs/API/core/parameters.md +0 -122
  196. package/dist-skill/docs/API/core/reserved-terms.md +0 -137
  197. package/dist-skill/docs/API/core/sdf.md +0 -326
  198. package/dist-skill/docs/API/core/skill-cli.md +0 -194
  199. package/dist-skill/docs/API/core/skill-guide.md +0 -205
  200. package/dist-skill/docs/API/core/specs.md +0 -186
  201. package/dist-skill/docs/API/core/topology.md +0 -372
  202. package/dist-skill/docs/API/entities.md +0 -268
  203. package/dist-skill/docs/API/output/bom.md +0 -58
  204. package/dist-skill/docs/API/output/brep-export.md +0 -87
  205. package/dist-skill/docs/API/output/dimensions.md +0 -67
  206. package/dist-skill/docs/API/output/export.md +0 -110
  207. package/dist-skill/docs/API/output/gcode.md +0 -195
  208. package/dist-skill/docs/API/runtime/viewport.md +0 -420
  209. package/dist-skill/docs/API/sheet-metal/sheet-metal.md +0 -185
  210. package/dist-skill/docs/API/sketch/anchor.md +0 -37
  211. package/dist-skill/docs/API/sketch/booleans.md +0 -91
  212. package/dist-skill/docs/API/sketch/core.md +0 -73
  213. package/dist-skill/docs/API/sketch/extrude.md +0 -62
  214. package/dist-skill/docs/API/sketch/on-face.md +0 -104
  215. package/dist-skill/docs/API/sketch/operations.md +0 -78
  216. package/dist-skill/docs/API/sketch/path.md +0 -75
  217. package/dist-skill/docs/API/sketch/primitives.md +0 -146
  218. package/dist-skill/docs/API/sketch/regions.md +0 -80
  219. package/dist-skill/docs/API/sketch/text.md +0 -108
  220. package/dist-skill/docs/API/sketch/transforms.md +0 -65
  221. package/dist-skill/docs/API/toolbox/fasteners.md +0 -129
  222. package/dist-skill/docs/INDEX.md +0 -94
  223. package/dist-skill/docs/RELEASING.md +0 -55
  224. package/dist-skill/docs/cli-monetization.md +0 -111
  225. package/dist-skill/docs/deployment.md +0 -281
  226. package/dist-skill/docs/generated/concepts.md +0 -2112
  227. package/dist-skill/docs/internals/shape-from-slices.md +0 -152
  228. package/dist-skill/docs/platform/admin.md +0 -45
  229. package/dist-skill/docs/platform/architecture.md +0 -79
  230. package/dist-skill/docs/platform/auth.md +0 -110
  231. package/dist-skill/docs/platform/email.md +0 -67
  232. package/dist-skill/docs/platform/projects.md +0 -111
  233. package/dist-skill/docs/platform/sharing.md +0 -90
  234. package/dist-skill/docs/runbook.md +0 -345
@@ -3,24 +3,24 @@
3
3
  // Strategy: build small reliable modules, then combine with parametric kinematics.
4
4
 
5
5
  // ---- 1) Control params (motion + fabrication) ----
6
- const baseYaw = param("Base Yaw", 20, { min: -170, max: 170, unit: "°" });
7
- const shoulderPitch = param("Shoulder Pitch", 35, { min: -25, max: 105, unit: "°" });
8
- const elbowPitch = param("Elbow Pitch", 55, { min: -15, max: 135, unit: "°" });
9
- const wristPitch = param("Wrist Pitch", -20, { min: -100, max: 100, unit: "°" });
10
- const wristRoll = param("Wrist Roll", 10, { min: -180, max: 180, unit: "°" });
6
+ const baseYaw = Param.number("Base Yaw", 20, { min: -170, max: 170, unit: "°" });
7
+ const shoulderPitch = Param.number("Shoulder Pitch", 35, { min: -25, max: 105, unit: "°" });
8
+ const elbowPitch = Param.number("Elbow Pitch", 55, { min: -15, max: 135, unit: "°" });
9
+ const wristPitch = Param.number("Wrist Pitch", -20, { min: -100, max: 100, unit: "°" });
10
+ const wristRoll = Param.number("Wrist Roll", 10, { min: -180, max: 180, unit: "°" });
11
11
 
12
- const upperLen = param("Upper Arm Len", 210, { min: 140, max: 320, unit: "mm" });
13
- const foreLen = param("Forearm Len", 220, { min: 150, max: 340, unit: "mm" });
14
- const foreExtension = param("Forearm Ext", 70, { min: 0, max: 150, unit: "mm" });
12
+ const upperLen = Param.number("Upper Arm Len", 210, { min: 140, max: 320, unit: "mm" });
13
+ const foreLen = Param.number("Forearm Len", 220, { min: 150, max: 340, unit: "mm" });
14
+ const foreExtension = Param.number("Forearm Ext", 70, { min: 0, max: 150, unit: "mm" });
15
15
 
16
- const gripperOpen = param("Gripper Open", 55, { min: 0, max: 90, unit: "mm" });
17
- const fingerCurl = param("Finger Curl", 72, { min: 0, max: 100, unit: "°" });
18
- const payloadType = param("Payload Type", 2, { min: 1, max: 4, integer: true });
19
- const payloadSize = param("Payload Size", 36, { min: 20, max: 65, unit: "mm" });
20
- const carryPayload = param("Carry Payload", 1, { min: 0, max: 1, integer: true });
16
+ const gripperOpen = Param.number("Gripper Open", 55, { min: 0, max: 90, unit: "mm" });
17
+ const fingerCurl = Param.number("Finger Curl", 72, { min: 0, max: 100, unit: "°" });
18
+ const payloadType = Param.number("Payload Type", 2, { min: 1, max: 4, integer: true });
19
+ const payloadSize = Param.number("Payload Size", 36, { min: 20, max: 65, unit: "mm" });
20
+ const carryPayload = Param.number("Carry Payload", 1, { min: 0, max: 1, integer: true });
21
21
 
22
- const exploded = param("Exploded", 0, { min: 0, max: 140, unit: "mm" });
23
- const sectionEnabled = param("Section Enabled", 0, { min: 0, max: 1, integer: true });
22
+ const exploded = Param.number("Exploded", 0, { min: 0, max: 140, unit: "mm" });
23
+ const sectionEnabled = Param.number("Section Enabled", 0, { min: 0, max: 1, integer: true });
24
24
 
25
25
  // ---- 2) Math + transform helpers ----
26
26
  function rad(deg) {
@@ -89,7 +89,7 @@ function collectSceneBounds(items) {
89
89
  }
90
90
 
91
91
  function gearDisc(radius, thickness, teeth) {
92
- return cylinder(thickness, radius, radius, teeth, true).pointAlong([0, 1, 0]);
92
+ return cylinder(thickness, radius, radius, teeth).pointAlong([0, 1, 0]);
93
93
  }
94
94
 
95
95
  function axle(radius, length) {
@@ -185,15 +185,15 @@ function makePayloadLocal(kind, size) {
185
185
  return sphere(size * 0.5);
186
186
  }
187
187
  if (kind === 2) {
188
- return box(size, size * 0.78, size * 0.58, true);
188
+ return box(size, size * 0.78, size * 0.58);
189
189
  }
190
190
  if (kind === 3) {
191
- return cylinder(size * 0.9, size * 0.32, undefined, undefined, true);
191
+ return cylinder(size * 0.9, size * 0.32);
192
192
  }
193
193
 
194
194
  const lobeA = sphere(size * 0.35).translate(-size * 0.2, 0, 0);
195
195
  const lobeB = sphere(size * 0.28).translate(size * 0.2, size * 0.1, size * 0.05);
196
- const bridge = box(size * 0.48, size * 0.22, size * 0.28, true);
196
+ const bridge = box(size * 0.48, size * 0.22, size * 0.28);
197
197
  return union(lobeA, lobeB, bridge);
198
198
  }
199
199
 
@@ -202,7 +202,7 @@ const mountW = 180;
202
202
  const mountD = 140;
203
203
  const mountT = 8;
204
204
 
205
- let mountPlate = box(mountW, mountD, mountT, true).translate(0, 0, mountT * 0.5);
205
+ let mountPlate = box(mountW, mountD, mountT).translate(0, 0, mountT * 0.5);
206
206
  const mountHoles = [];
207
207
  for (const sx of [-1, 1]) {
208
208
  for (const sy of [-1, 1]) {
@@ -216,11 +216,11 @@ mountPlate = difference(mountPlate, ...mountHoles);
216
216
  const clampGap = 38;
217
217
  const clampNeck = box(44, 28, clampGap + mountT)
218
218
  .translate(-22, -mountD / 2 - 14, -clampGap + mountT * 0.5);
219
- const clampJaw = box(130, 28, 10, true)
219
+ const clampJaw = box(130, 28, 10)
220
220
  .translate(0, -mountD / 2 - 14, -clampGap - 5);
221
221
  const clampScrew = cylinder(clampGap + 7, 4.8)
222
222
  .translate(0, -mountD / 2 - 14, -clampGap - 1);
223
- const clampKnob = cylinder(8, 14, 14, 18, true)
223
+ const clampKnob = cylinder(8, 14, 14, 18)
224
224
  .translate(0, -mountD / 2 - 14, -clampGap - 11);
225
225
 
226
226
  const statorH = 44;
@@ -233,7 +233,7 @@ let baseRotor = cylinder(rotorH, 46).translate(0, 0, mountT + statorH - 4);
233
233
  baseRotor = baseRotor.subtract(cylinder(rotorH + 2, 30).translate(0, 0, mountT + statorH - 3));
234
234
 
235
235
  const towerH = 40;
236
- const shoulderTower = box(42, 58, towerH, true)
236
+ const shoulderTower = box(42, 58, towerH)
237
237
  .translate(0, 0, mountT + statorH + rotorH + towerH * 0.5 - 4);
238
238
 
239
239
  const yawServoLocal = makeServoLocal(44, 21, 39, 11)
@@ -518,7 +518,7 @@ function placeHandLocal(shape) {
518
518
  const rotatingRollShaftLocal = rollShaft;
519
519
  const wristCouplerLocal = union(
520
520
  cylinder(20, 8.5).pointAlong([1, 0, 0]).translate(handRootX - 20, 0, 0),
521
- box(14, 6, 18, true).translate(handRootX - 8, 0, 9)
521
+ box(14, 6, 18).translate(handRootX - 8, 0, 9)
522
522
  );
523
523
 
524
524
  const handGroup = [
@@ -602,12 +602,12 @@ const sectionMarginZ = Math.max(30, (sceneBounds.max[2] - sceneBounds.min[2]) *
602
602
  const sectionDefaultX = (sceneBounds.min[0] + sceneBounds.max[0]) * 0.5;
603
603
  const sectionDefaultZ = (sceneBounds.min[2] + sceneBounds.max[2]) * 0.5;
604
604
 
605
- const sectionX = param("Section X", sectionDefaultX, {
605
+ const sectionX = Param.number("Section X", sectionDefaultX, {
606
606
  min: sceneBounds.min[0] - sectionMarginX,
607
607
  max: sceneBounds.max[0] + sectionMarginX,
608
608
  unit: "mm",
609
609
  });
610
- const sectionZ = param("Section Z", sectionDefaultZ, {
610
+ const sectionZ = Param.number("Section Z", sectionDefaultZ, {
611
611
  min: sceneBounds.min[2] - sectionMarginZ,
612
612
  max: sceneBounds.max[2] + sectionMarginZ,
613
613
  unit: "mm",
@@ -0,0 +1,8 @@
1
+ // Freeform NURBS surface — a gently curved panel
2
+ const grid = [
3
+ [[0,0,0], [10,0,2], [20,0,2], [30,0,0]],
4
+ [[0,10,1], [10,10,6], [20,10,6], [30,10,1]],
5
+ [[0,20,1], [10,20,6], [20,20,6], [30,20,1]],
6
+ [[0,30,0], [10,30,2], [20,30,2], [30,30,0]],
7
+ ];
8
+ return nurbsSurface(grid, { thickness: 1.5 });
@@ -0,0 +1,7 @@
1
+ // NURBS curve swept into a smooth tube
2
+ const curve = nurbs3d(
3
+ [[0,0,0], [15,8,0], [25,-3,10], [40,5,15], [50,0,5]],
4
+ { degree: 3 }
5
+ );
6
+ const tube = sweep(circle2d(2), curve);
7
+ return tube;
@@ -1,13 +1,13 @@
1
1
  // Water Bottle — revolve profile with cap
2
2
  // Demonstrates: revolve, polygon, difference, smoothing, multi-object
3
3
 
4
- const bodyH = param("Body Height", 180, { min: 120, max: 250, unit: "mm" });
5
- const bodyR = param("Body Radius", 35, { min: 25, max: 50, unit: "mm" });
6
- const neckH = param("Neck Height", 30, { min: 15, max: 50, unit: "mm" });
7
- const neckR = param("Neck Radius", 14, { min: 10, max: 25, unit: "mm" });
8
- const wall = param("Wall Thickness", 2, { min: 1, max: 5, unit: "mm" });
9
- const capH = param("Cap Height", 18, { min: 10, max: 30, unit: "mm" });
10
- const shoulderR = param("Shoulder Curve", 20, { min: 5, max: 40, unit: "mm" });
4
+ const bodyH = Param.number("Body Height", 180, { min: 120, max: 250, unit: "mm" });
5
+ const bodyR = Param.number("Body Radius", 35, { min: 25, max: 50, unit: "mm" });
6
+ const neckH = Param.number("Neck Height", 30, { min: 15, max: 50, unit: "mm" });
7
+ const neckR = Param.number("Neck Radius", 14, { min: 10, max: 25, unit: "mm" });
8
+ const wall = Param.number("Wall Thickness", 2, { min: 1, max: 5, unit: "mm" });
9
+ const capH = Param.number("Cap Height", 18, { min: 10, max: 30, unit: "mm" });
10
+ const shoulderR = Param.number("Shoulder Curve", 20, { min: 5, max: 40, unit: "mm" });
11
11
 
12
12
  // Outer profile — polygon traced from bottom-center up and around
13
13
  // Bottom flat → body → shoulder curve → neck
@@ -89,7 +89,7 @@ for (let i = 0; i < ridgeCount; i++) {
89
89
  const rx = (capOuterR + 0.5) * Math.cos(rad);
90
90
  const ry = (capOuterR + 0.5) * Math.sin(rad);
91
91
  ridges.push(
92
- box(1.5, 1.5, capH - 4, true)
92
+ box(1.5, 1.5, capH - 4)
93
93
  .translate(rx, ry, bodyH + neckH + capH / 2)
94
94
  );
95
95
  }
@@ -1,9 +1,9 @@
1
- const squareSize = param("Square Size", 36, { min: 24, max: 54, unit: "mm" });
2
- const boardThickness = param("Board Thickness", 14, { min: 8, max: 24, unit: "mm" });
3
- const borderWidth = param("Border Width", 10, { min: 4, max: 18, unit: "mm" });
4
- const tileHeight = param("Tile Height", 1.8, { min: 0.8, max: 4, step: 0.1, unit: "mm" });
5
- const pieceScale = param("Piece Scale", 1, { min: 0.8, max: 1.25, step: 0.01 });
6
- const pieceLift = param("Piece Lift", 0, { min: 0, max: 16, unit: "mm" });
1
+ const squareSize = Param.number("Square Size", 36, { min: 24, max: 54, unit: "mm" });
2
+ const boardThickness = Param.number("Board Thickness", 14, { min: 8, max: 24, unit: "mm" });
3
+ const borderWidth = Param.number("Border Width", 10, { min: 4, max: 18, unit: "mm" });
4
+ const tileHeight = Param.number("Tile Height", 1.8, { min: 0.8, max: 4, step: 0.1, unit: "mm" });
5
+ const pieceScale = Param.number("Piece Scale", 1, { min: 0.8, max: 1.25, step: 0.01 });
6
+ const pieceLift = Param.number("Piece Lift", 0, { min: 0, max: 16, unit: "mm" });
7
7
 
8
8
  const boardSize = squareSize * 8;
9
9
  const frameSize = boardSize + borderWidth * 2;
@@ -52,7 +52,7 @@ function rookShape() {
52
52
  .translate(0, 0, squareSize * 0.34);
53
53
  const crown = cylinder(squareSize * 0.17, squareSize * 0.23)
54
54
  .translate(0, 0, squareSize * 0.79);
55
- const slot = box(squareSize * 0.08, squareSize * 0.18, squareSize * 0.14, true)
55
+ const slot = box(squareSize * 0.08, squareSize * 0.18, squareSize * 0.14)
56
56
  .translate(0, squareSize * 0.18, squareSize * 0.88);
57
57
  const battlements = crown.subtract(circularPattern(slot, 4));
58
58
  return union(base, lowerBody, tower, battlements);
@@ -68,8 +68,8 @@ function bishopShape() {
68
68
  const crown = ring(squareSize * 0.05, squareSize * 0.16, squareSize * 0.11)
69
69
  .translate(0, 0, squareSize * 0.74);
70
70
  const piece = union(base, lowerBody, body, crown, head);
71
- const slit = box(squareSize * 0.06, squareSize * 0.28, squareSize * 0.42, true)
72
- .rotateAround([0, 0, 0], 0, 0, 32)
71
+ const slit = box(squareSize * 0.06, squareSize * 0.28, squareSize * 0.42)
72
+ .rotateZ(32)
73
73
  .translate(0, 0, squareSize * 0.86);
74
74
  return piece.subtract(slit);
75
75
  }
@@ -100,9 +100,9 @@ function kingShape() {
100
100
  .translate(0, 0, squareSize * 0.37);
101
101
  const shoulder = sphere(squareSize * 0.12).translate(0, 0, squareSize * 0.94);
102
102
  const neck = cylinder(squareSize * 0.08, squareSize * 0.08).translate(0, 0, squareSize * 1.04);
103
- const crossStem = box(squareSize * 0.055, squareSize * 0.055, squareSize * 0.22, true)
103
+ const crossStem = box(squareSize * 0.055, squareSize * 0.055, squareSize * 0.22)
104
104
  .translate(0, 0, squareSize * 1.2);
105
- const crossArm = box(squareSize * 0.18, squareSize * 0.05, squareSize * 0.05, true)
105
+ const crossArm = box(squareSize * 0.18, squareSize * 0.05, squareSize * 0.05)
106
106
  .translate(0, 0, squareSize * 1.23);
107
107
  return union(base, lowerBody, body, shoulder, neck, crossStem, crossArm);
108
108
  }
@@ -124,17 +124,17 @@ function knightShape() {
124
124
  sphere(squareSize * 0.055).translate(0, squareSize * 0.24, squareSize * 0.98),
125
125
  sphere(squareSize * 0.045).translate(0, squareSize * 0.31, squareSize * 0.94)
126
126
  );
127
- const mane = box(squareSize * 0.08, squareSize * 0.12, squareSize * 0.36, true)
128
- .rotateAround([0, 0, 0], -12, 0, 0)
127
+ const mane = box(squareSize * 0.08, squareSize * 0.12, squareSize * 0.36)
128
+ .rotateX(-12)
129
129
  .translate(0, squareSize * 0.03, squareSize * 0.94);
130
- const earL = box(squareSize * 0.035, squareSize * 0.08, squareSize * 0.12, true)
131
- .rotateAround([0, 0, 0], -18, 0, 14)
130
+ const earL = box(squareSize * 0.035, squareSize * 0.08, squareSize * 0.12)
131
+ .rotateX(-18).rotateZ(14)
132
132
  .translate(-squareSize * 0.04, squareSize * 0.18, squareSize * 1.2);
133
- const earR = box(squareSize * 0.035, squareSize * 0.08, squareSize * 0.12, true)
134
- .rotateAround([0, 0, 0], -18, 0, -14)
133
+ const earR = box(squareSize * 0.035, squareSize * 0.08, squareSize * 0.12)
134
+ .rotateX(-18).rotateZ(-14)
135
135
  .translate(squareSize * 0.04, squareSize * 0.18, squareSize * 1.2);
136
- const chinCut = box(squareSize * 0.5, squareSize * 0.28, squareSize * 0.34, true)
137
- .rotateAround([0, 0, 0], 58, 0, 0)
136
+ const chinCut = box(squareSize * 0.5, squareSize * 0.28, squareSize * 0.34)
137
+ .rotateX(58)
138
138
  .translate(0, -squareSize * 0.04, squareSize * 0.93);
139
139
  return union(base, chest, neck, head, muzzle, mane, earL, earR).subtract(chinCut);
140
140
  }
@@ -159,15 +159,15 @@ function placePiece(kind, file, rank, color, facingDeg, name) {
159
159
  const [x, y] = squareCenter(file, rank);
160
160
  const shape = makePiece(kind)
161
161
  .scale(pieceScale)
162
- .rotateAround([0, 0, 0], 0, 0, facingDeg)
162
+ .rotateZ(facingDeg)
163
163
  .translate(x, y, pieceZ)
164
164
  .color(color);
165
165
  return { name, shape };
166
166
  }
167
167
 
168
168
  const frame = difference(
169
- box(frameSize, frameSize, boardThickness, true).translate(0, 0, boardThickness * 0.5),
170
- box(boardSize + 1, boardSize + 1, boardThickness * 0.32, true)
169
+ box(frameSize, frameSize, boardThickness).translate(0, 0, boardThickness * 0.5),
170
+ box(boardSize + 1, boardSize + 1, boardThickness * 0.32)
171
171
  .translate(0, 0, boardThickness - boardThickness * 0.16)
172
172
  )
173
173
  .color(woodDark);
@@ -177,7 +177,7 @@ const darkSquares = [];
177
177
  for (let file = 0; file < 8; file += 1) {
178
178
  for (let rank = 0; rank < 8; rank += 1) {
179
179
  const [x, y] = squareCenter(file, rank);
180
- const tile = box(squareSize, squareSize, tileHeight, true)
180
+ const tile = box(squareSize, squareSize, tileHeight)
181
181
  .translate(x, y, boardTop + tileHeight * 0.5);
182
182
  if ((file + rank) % 2 === 0) lightSquares.push(tile);
183
183
  else darkSquares.push(tile);
@@ -188,9 +188,9 @@ const lightSquareField = union(...lightSquares).color(woodLight);
188
188
  const darkSquareField = union(...darkSquares).color(squareDark);
189
189
 
190
190
  const trim = difference(
191
- box(frameSize - borderWidth * 0.45, frameSize - borderWidth * 0.45, tileHeight * 0.9, true)
191
+ box(frameSize - borderWidth * 0.45, frameSize - borderWidth * 0.45, tileHeight * 0.9)
192
192
  .translate(0, 0, boardTop + tileHeight * 0.45),
193
- box(boardSize + borderWidth * 0.2, boardSize + borderWidth * 0.2, tileHeight * 2, true)
193
+ box(boardSize + borderWidth * 0.2, boardSize + borderWidth * 0.2, tileHeight * 2)
194
194
  .translate(0, 0, boardTop + tileHeight * 0.45)
195
195
  ).color(woodMid);
196
196
 
@@ -12,15 +12,15 @@
12
12
  - Bench
13
13
  */
14
14
 
15
- const bodyWidth = param("Body Width", 180, { min: 140, max: 240, unit: "mm" });
16
- const bodyLength = param("Body Length", 280, { min: 220, max: 360, unit: "mm" });
17
- const rimHeight = param("Rim Height", 28, { min: 20, max: 40, unit: "mm" });
18
- const lidThickness = param("Lid Thickness", 6, { min: 4, max: 10, unit: "mm" });
19
- const lidOpen = param("Lid Angle", 25, { min: 0, max: 50, unit: "°" });
20
- const legHeight = param("Leg Height", 60, { min: 45, max: 90, unit: "mm" });
21
- const legTopRadius = param("Leg Top Radius", 8, { min: 5, max: 12, unit: "mm" });
22
- const keyboardDepth = param("Keyboard Depth", 60, { min: 45, max: 80, unit: "mm" });
23
- const keyHeight = param("Key Height", 5, { min: 3, max: 8, unit: "mm" });
15
+ const bodyWidth = Param.number("Body Width", 180, { min: 140, max: 240, unit: "mm" });
16
+ const bodyLength = Param.number("Body Length", 280, { min: 220, max: 360, unit: "mm" });
17
+ const rimHeight = Param.number("Rim Height", 28, { min: 20, max: 40, unit: "mm" });
18
+ const lidThickness = Param.number("Lid Thickness", 6, { min: 4, max: 10, unit: "mm" });
19
+ const lidOpen = Param.number("Lid Angle", 25, { min: 0, max: 50, unit: "°" });
20
+ const legHeight = Param.number("Leg Height", 60, { min: 45, max: 90, unit: "mm" });
21
+ const legTopRadius = Param.number("Leg Top Radius", 8, { min: 5, max: 12, unit: "mm" });
22
+ const keyboardDepth = Param.number("Keyboard Depth", 60, { min: 45, max: 80, unit: "mm" });
23
+ const keyHeight = Param.number("Key Height", 5, { min: 3, max: 8, unit: "mm" });
24
24
 
25
25
  const rimThickness = Math.min(12, bodyWidth * 0.07);
26
26
  const keyboardWidth = bodyWidth * 0.9;
@@ -130,12 +130,12 @@ const propStick = union(
130
130
  ).color('#8B7355');
131
131
 
132
132
  // --- Keybed ---
133
- const keybed = box(keyboardWidth, keyboardDepth, keybedHeight, true)
133
+ const keybed = box(keyboardWidth, keyboardDepth, keybedHeight)
134
134
  .attachTo(body, 'top-front', 'top-front', [0, 0, -2])
135
135
  .color('#222222');
136
136
 
137
137
  // --- White keys ---
138
- const whiteKey = box(whiteKeyWidth * 0.98, whiteKeyDepth, keyHeight, true).color('#f5f5f5');
138
+ const whiteKey = box(whiteKeyWidth * 0.98, whiteKeyDepth, keyHeight).color('#f5f5f5');
139
139
  const keyboardLeft = -keyboardWidth / 2 + whiteKeyWidth / 2;
140
140
 
141
141
  const whiteKeyRow = linearPattern(whiteKey, whiteKeyCount, whiteKeyWidth, 0, 0)
@@ -145,7 +145,7 @@ const whiteKeys = whiteKeyRow
145
145
  .attachTo(keybed, 'top-front', 'bottom-front', [0, -2, 0.1]);
146
146
 
147
147
  // --- Black keys ---
148
- const blackKey = box(blackKeyWidth, blackKeyDepth, blackKeyHeight, true).color('#111111');
148
+ const blackKey = box(blackKeyWidth, blackKeyDepth, blackKeyHeight).color('#111111');
149
149
  const blackPattern = [0, 1, 3, 4, 5];
150
150
  const blackKeysList = [];
151
151
 
@@ -161,12 +161,12 @@ const blackKeys = blackKeysRow
161
161
  .attachTo(keybed, 'top-front', 'bottom-front', [0, whiteKeyDepth * 0.2, 0.1]);
162
162
 
163
163
  // --- Key slip (front rail below keyboard) ---
164
- const keySlip = box(keyboardWidth, 12, 6, true)
164
+ const keySlip = box(keyboardWidth, 12, 6)
165
165
  .attachTo(keybed, 'bottom-front', 'top-front', [0, -4, -2])
166
166
  .color('#1b1b1b');
167
167
 
168
168
  // --- Fallboard (keyboard cover, resting behind the keys) ---
169
- const fallboard = box(keyboardWidth, 4, keybedHeight + keyHeight + 2, true)
169
+ const fallboard = box(keyboardWidth, 4, keybedHeight + keyHeight + 2)
170
170
  .attachTo(keybed, 'top-back', 'bottom-front', [0, 2, 0])
171
171
  .color('#111111');
172
172
 
@@ -178,16 +178,16 @@ const standLipHeight = 8;
178
178
  const standLipDepth = 6;
179
179
 
180
180
  // Main panel of the music stand
181
- const standPanel = box(standWidth, standThickness, standHeight, true)
181
+ const standPanel = box(standWidth, standThickness, standHeight)
182
182
  .translate(0, 0, standHeight / 2);
183
183
 
184
184
  // Bottom lip to hold sheet music
185
- const standLip = box(standWidth, standLipDepth, standLipHeight, true)
185
+ const standLip = box(standWidth, standLipDepth, standLipHeight)
186
186
  .attachTo(standPanel, 'bottom-front', 'bottom-back', [0, 0, 0]);
187
187
 
188
188
  // Combine panel + lip, tilt back, then position behind the fallboard
189
189
  const standAssembly = group(standPanel, standLip)
190
- .rotateAround([0, 0, 0], -12, 0, 0);
190
+ .rotateX(-12);
191
191
 
192
192
  // Position the music stand so it sits above the soundboard, behind the keyboard area
193
193
  const keybedBB = keybed.boundingBox();
@@ -223,11 +223,11 @@ const frontRightBB = frontRightLeg.boundingBox();
223
223
  const pedalRailY = (frontLeftBB.min[1] + frontLeftBB.max[1]) / 2;
224
224
  const pedalRailZ = legHeight * 0.15;
225
225
 
226
- const pedalRail = box(50, 14, 6, true)
226
+ const pedalRail = box(50, 14, 6)
227
227
  .translate(bodyCenterX, pedalRailY, pedalRailZ)
228
228
  .color('#bfa14a');
229
229
 
230
- const pedalBlade = box(4, 18, 2, true).rotateAround([0, 0, 0], 10, 0, 0).color('#d8b45a');
230
+ const pedalBlade = box(4, 18, 2).rotateX(10).color('#d8b45a');
231
231
  const pedalSpacing = 12;
232
232
 
233
233
  const pedalL = pedalBlade.attachTo(pedalRail, 'top', 'bottom', [-pedalSpacing, 0, 0]);
@@ -240,7 +240,7 @@ const benchDepth = keyboardDepth * 0.6;
240
240
  const benchSeatThickness = 6;
241
241
  const benchHeight = legHeight * 0.7;
242
242
 
243
- const benchSeat = box(benchWidth, benchDepth, benchSeatThickness, true)
243
+ const benchSeat = box(benchWidth, benchDepth, benchSeatThickness)
244
244
  .translate(bodyCenterX, frontY - keyboardDepth * 0.9, benchHeight + benchSeatThickness / 2)
245
245
  .color('#3b2a1a');
246
246
 
@@ -3,23 +3,23 @@
3
3
  // Returns named objects to preserve colors and enable individual visibility control
4
4
 
5
5
  // === Dimensions ===
6
- const diameter = param("Diameter", 220, { min: 80, max: 400, unit: "mm" });
7
- const depth = param("Depth", 18, { min: 8, max: 50, unit: "mm" });
8
- const rimWidth = param("Rim Width", 8, { min: 3, max: 30, unit: "mm" });
6
+ const diameter = Param.number("Diameter", 220, { min: 80, max: 400, unit: "mm" });
7
+ const depth = Param.number("Depth", 18, { min: 8, max: 50, unit: "mm" });
8
+ const rimWidth = Param.number("Rim Width", 8, { min: 3, max: 30, unit: "mm" });
9
9
 
10
10
  // === Time Settings — Default 10:10:30 (Apple display time) ===
11
- const hour = param("Hour", 10, { min: 1, max: 12, integer: true });
12
- const minute = param("Minute", 10, { min: 0, max: 59, integer: true });
13
- const second = param("Second", 30, { min: 0, max: 59, integer: true });
14
- const showSecondHand = param("Show Seconds", 1, { min: 0, max: 1, integer: true });
11
+ const hour = Param.number("Hour", 10, { min: 1, max: 12, integer: true });
12
+ const minute = Param.number("Minute", 10, { min: 0, max: 59, integer: true });
13
+ const second = Param.number("Second", 30, { min: 0, max: 59, integer: true });
14
+ const showSecondHand = Param.number("Show Seconds", 1, { min: 0, max: 1, integer: true });
15
15
 
16
16
  // === Color Customization ===
17
- const rimColor = param("Rim Color", 0, { min: 0, max: 3, integer: true }); // 0=silver, 1=gold, 2=black, 3=rose
18
- const faceColor = param("Face Color", 0, { min: 0, max: 2, integer: true }); // 0=white, 1=black, 2=cream
19
- const markerColor = param("Marker Color", 0, { min: 0, max: 2, integer: true }); // 0=black, 1=white, 2=gold
20
- const hourHandColor = param("Hour Hand Color", 0, { min: 0, max: 3, integer: true }); // 0=black, 1=white, 2=gold, 3=red
21
- const minuteHandColor = param("Minute Hand Color", 1, { min: 0, max: 3, integer: true }); // 0=black, 1=white, 2=gold, 3=red
22
- const secondHandColor = param("Second Hand Color", 3, { min: 0, max: 3, integer: true }); // 0=black, 1=white, 2=gold, 3=red
17
+ const rimColor = Param.number("Rim Color", 0, { min: 0, max: 3, integer: true }); // 0=silver, 1=gold, 2=black, 3=rose
18
+ const faceColor = Param.number("Face Color", 0, { min: 0, max: 2, integer: true }); // 0=white, 1=black, 2=cream
19
+ const markerColor = Param.number("Marker Color", 0, { min: 0, max: 2, integer: true }); // 0=black, 1=white, 2=gold
20
+ const hourHandColor = Param.number("Hour Hand Color", 0, { min: 0, max: 3, integer: true }); // 0=black, 1=white, 2=gold, 3=red
21
+ const minuteHandColor = Param.number("Minute Hand Color", 1, { min: 0, max: 3, integer: true }); // 0=black, 1=white, 2=gold, 3=red
22
+ const secondHandColor = Param.number("Second Hand Color", 3, { min: 0, max: 3, integer: true }); // 0=black, 1=white, 2=gold, 3=red
23
23
 
24
24
  // Color palette
25
25
  const colors = {
@@ -47,22 +47,22 @@ const innerRadius = radius - rimWidth;
47
47
  const handBaseZ = depth / 2 - 2;
48
48
 
49
49
  // === Clock Rim ===
50
- const outer = cylinder(depth, radius, undefined, undefined, true);
51
- const inner = cylinder(depth + 2, innerRadius, undefined, undefined, true);
50
+ const outer = cylinder(depth, radius);
51
+ const inner = cylinder(depth + 2, innerRadius);
52
52
  const rimBody = outer.subtract(inner);
53
53
 
54
54
  // Add subtle bevel to rim edge
55
- const bevel = cylinder(depth - 5, radius - 1, radius, undefined, true);
55
+ const bevel = cylinder(depth - 5, radius - 1, radius);
56
56
  const rim = union(rimBody, bevel).color(rimHex);
57
57
 
58
58
  // === Clock Face ===
59
- const face = cylinder(2, innerRadius - 1, undefined, undefined, true)
59
+ const face = cylinder(2, innerRadius - 1)
60
60
  .translate(0, 0, depth / 2 - 3)
61
61
  .color(faceHex);
62
62
 
63
63
  // === Hour Markers ===
64
- const markerLength = param("Marker Length", 10, { min: 5, max: 25, unit: "mm" });
65
- const markerWidth = param("Marker Width", 2.5, { min: 1, max: 6, unit: "mm" });
64
+ const markerLength = Param.number("Marker Length", 10, { min: 5, max: 25, unit: "mm" });
65
+ const markerWidth = Param.number("Marker Width", 2.5, { min: 1, max: 6, unit: "mm" });
66
66
 
67
67
  const markerShapes = [];
68
68
  for (let i = 0; i < 12; i++) {
@@ -76,7 +76,7 @@ for (let i = 0; i < 12; i++) {
76
76
  const x = Math.cos(rad) * r;
77
77
  const y = Math.sin(rad) * r;
78
78
 
79
- const tick = roundedRect(width, length, width / 2, true)
79
+ const tick = roundedRect(width, length, width / 2)
80
80
  .rotateAround([0, 0, 0], angle)
81
81
  .extrude(1)
82
82
  .translate(x, y, depth / 2 - 2);
@@ -86,12 +86,12 @@ for (let i = 0; i < 12; i++) {
86
86
  const markers = union(...markerShapes).color(markerHex);
87
87
 
88
88
  // === Clock Hands ===
89
- const hourHandLength = param("Hour Hand Length", 55, { min: 25, max: 110, unit: "mm" });
90
- const hourHandWidth = param("Hour Hand Width", 10, { min: 5, max: 20, unit: "mm" });
91
- const minuteHandLength = param("Minute Hand Length", 80, { min: 40, max: 160, unit: "mm" });
92
- const minuteHandWidth = param("Minute Hand Width", 7, { min: 3, max: 14, unit: "mm" });
93
- const secondHandLength = param("Second Hand Length", 85, { min: 50, max: 170, unit: "mm" });
94
- const secondHandWidth = param("Second Hand Width", 2, { min: 1, max: 5, unit: "mm" });
89
+ const hourHandLength = Param.number("Hour Hand Length", 55, { min: 25, max: 110, unit: "mm" });
90
+ const hourHandWidth = Param.number("Hour Hand Width", 10, { min: 5, max: 20, unit: "mm" });
91
+ const minuteHandLength = Param.number("Minute Hand Length", 80, { min: 40, max: 160, unit: "mm" });
92
+ const minuteHandWidth = Param.number("Minute Hand Width", 7, { min: 3, max: 14, unit: "mm" });
93
+ const secondHandLength = Param.number("Second Hand Length", 85, { min: 50, max: 170, unit: "mm" });
94
+ const secondHandWidth = Param.number("Second Hand Width", 2, { min: 1, max: 5, unit: "mm" });
95
95
 
96
96
  // Calculate hand angles (0 degrees = 12 o'clock, clockwise)
97
97
  const hourAngle = (hour % 12) * 30 + (minute / 60) * 30;
@@ -100,10 +100,10 @@ const secondAngle = second * 6;
100
100
 
101
101
  // Create Apple-style hand with rounded ends
102
102
  function createHand(length, width, angle, zOffset, thickness) {
103
- return roundedRect(width, length, width / 2, true)
103
+ return roundedRect(width, length, width / 2)
104
104
  .translate(0, length / 2)
105
105
  .extrude(thickness)
106
- .rotateAround([0, 0, 0], 0, 0, angle - 90)
106
+ .rotateZ(angle - 90)
107
107
  .translate(0, 0, zOffset);
108
108
  }
109
109
 
@@ -122,10 +122,10 @@ if (showSecondHand > 0) {
122
122
  const counterWidth = 4;
123
123
 
124
124
  const sweep = createHand(secondHandLength, secondHandWidth, secondAngle, handBaseZ + 10, 2);
125
- const counter = roundedRect(counterWidth, counterLength, counterWidth / 2, true)
125
+ const counter = roundedRect(counterWidth, counterLength, counterWidth / 2)
126
126
  .translate(0, -counterLength / 2)
127
127
  .extrude(2)
128
- .rotateAround([0, 0, 0], 0, 0, secondAngle - 90)
128
+ .rotateZ(secondAngle - 90)
129
129
  .translate(0, 0, handBaseZ + 10);
130
130
 
131
131
  secondHand = union(sweep, counter).color(secondHandHex);
@@ -133,11 +133,11 @@ if (showSecondHand > 0) {
133
133
 
134
134
  // === Center Cap ===
135
135
  const centerRadius = 6;
136
- const centerRing = cylinder(3, centerRadius + 2, undefined, undefined, true)
136
+ const centerRing = cylinder(3, centerRadius + 2)
137
137
  .translate(0, 0, handBaseZ + 13)
138
138
  .color(rimHex);
139
139
 
140
- const centerDot = cylinder(4, centerRadius, undefined, undefined, true)
140
+ const centerDot = cylinder(4, centerRadius)
141
141
  .translate(0, 0, handBaseZ + 13)
142
142
  .color(showSecondHand > 0 ? secondHandHex : "#444444");
143
143
 
@@ -145,7 +145,7 @@ const centerDot = cylinder(4, centerRadius, undefined, undefined, true)
145
145
  const mountWidth = 25;
146
146
  const mountHeight = 12;
147
147
  const mountDepth = 6;
148
- const mount = roundedRect(mountWidth, mountHeight, 3, true)
148
+ const mount = roundedRect(mountWidth, mountHeight, 3)
149
149
  .extrude(mountDepth)
150
150
  .translate(0, -radius + 8, -depth / 2 - mountDepth / 2)
151
151
  .color(rimHex);
@@ -1,11 +1,11 @@
1
1
  // Cup with larger top than bottom
2
2
 
3
3
  // Parameters
4
- const height = param("Height", 80, { min: 40, max: 150, unit: "mm" });
5
- const topRadius = param("Top Radius", 35, { min: 20, max: 60, unit: "mm" });
6
- const bottomRadius = param("Bottom Radius", 25, { min: 15, max: 50, unit: "mm" });
7
- const wallThickness = param("Wall Thickness", 3, { min: 1, max: 8, unit: "mm" });
8
- const baseThickness = param("Base Thickness", 5, { min: 2, max: 10, unit: "mm" });
4
+ const height = Param.number("Height", 80, { min: 40, max: 150, unit: "mm" });
5
+ const topRadius = Param.number("Top Radius", 35, { min: 20, max: 60, unit: "mm" });
6
+ const bottomRadius = Param.number("Bottom Radius", 25, { min: 15, max: 50, unit: "mm" });
7
+ const wallThickness = Param.number("Wall Thickness", 3, { min: 1, max: 8, unit: "mm" });
8
+ const baseThickness = Param.number("Base Thickness", 5, { min: 2, max: 10, unit: "mm" });
9
9
 
10
10
  // Outer cup shape - tapered cylinder (truncated cone)
11
11
  const outerCup = cylinder(height, bottomRadius, topRadius);