@pascal-app/core 1.0.0 → 1.0.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.
Files changed (345) hide show
  1. package/dist/capture/index.d.ts +2 -2
  2. package/dist/capture/index.js +2 -2
  3. package/dist/capture/schema.d.ts.map +1 -1
  4. package/dist/capture/schema.js +2 -0
  5. package/dist/capture/source.d.ts +1 -1
  6. package/dist/capture/source.js +1 -1
  7. package/dist/events/bus.d.ts +6 -3
  8. package/dist/events/bus.d.ts.map +1 -1
  9. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +4 -4
  10. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -1
  11. package/dist/hooks/spatial-grid/floor-placed-elevation.js +7 -12
  12. package/dist/hooks/spatial-grid/floor-placed-footprints.d.ts +4 -0
  13. package/dist/hooks/spatial-grid/floor-placed-footprints.d.ts.map +1 -0
  14. package/dist/hooks/spatial-grid/floor-placed-footprints.js +7 -0
  15. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +5 -8
  16. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  17. package/dist/hooks/spatial-grid/spatial-grid-manager.js +23 -106
  18. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +263 -84
  19. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
  20. package/dist/hooks/spatial-grid/spatial-grid-sync.js +77 -13
  21. package/dist/hooks/spatial-grid/support-host-patch.d.ts +1 -1
  22. package/dist/hooks/spatial-grid/support-host-patch.js +6 -6
  23. package/dist/hooks/spatial-grid/use-spatial-query.d.ts +1 -1
  24. package/dist/hooks/spatial-grid/use-spatial-query.js +1 -1
  25. package/dist/index.d.ts +77 -72
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +74 -69
  28. package/dist/lib/door-operation.d.ts +1 -1
  29. package/dist/lib/item-polygon-overlap.d.ts +6 -0
  30. package/dist/lib/item-polygon-overlap.d.ts.map +1 -0
  31. package/dist/lib/item-polygon-overlap.js +67 -0
  32. package/dist/lib/level-name.d.ts +1 -1
  33. package/dist/lib/measurement-geometry.d.ts +4 -4
  34. package/dist/lib/node-visibility.d.ts +12 -0
  35. package/dist/lib/node-visibility.d.ts.map +1 -0
  36. package/dist/lib/node-visibility.js +12 -0
  37. package/dist/lib/plan-footprint.d.ts +41 -0
  38. package/dist/lib/plan-footprint.d.ts.map +1 -0
  39. package/dist/lib/plan-footprint.js +58 -0
  40. package/dist/lib/room-topology-index.d.ts +1 -1
  41. package/dist/lib/room-topology-index.js +1 -1
  42. package/dist/lib/selection-proxy.d.ts +1 -1
  43. package/dist/lib/slab-polygon.d.ts +2 -2
  44. package/dist/lib/slab-polygon.js +2 -2
  45. package/dist/lib/space-detection.d.ts +1 -1
  46. package/dist/lib/space-detection.d.ts.map +1 -1
  47. package/dist/lib/space-detection.js +16 -11
  48. package/dist/lib/terrain-brush.d.ts +1 -1
  49. package/dist/lib/terrain-brush.js +1 -1
  50. package/dist/lib/terrain-codec.d.ts +2 -2
  51. package/dist/lib/terrain-codec.js +1 -1
  52. package/dist/lib/terrain-raycast.d.ts +1 -1
  53. package/dist/lib/terrain-raycast.js +1 -1
  54. package/dist/lib/terrain-source.d.ts +3 -3
  55. package/dist/lib/terrain-source.js +3 -3
  56. package/dist/lib/terrain-support.d.ts +1 -1
  57. package/dist/lib/terrain-support.js +3 -3
  58. package/dist/lib/unit-containment.d.ts +19 -0
  59. package/dist/lib/unit-containment.d.ts.map +1 -0
  60. package/dist/lib/unit-containment.js +158 -0
  61. package/dist/lib/unit-report.d.ts +19 -0
  62. package/dist/lib/unit-report.d.ts.map +1 -0
  63. package/dist/lib/unit-report.js +36 -0
  64. package/dist/lib/wall-distance.d.ts +2 -2
  65. package/dist/lib/wall-distance.js +1 -1
  66. package/dist/lib/zone-quantities.d.ts +1 -1
  67. package/dist/lib/zone-quantities.js +7 -7
  68. package/dist/material-library.d.ts +1 -1
  69. package/dist/material-library.js +1 -1
  70. package/dist/procedural-items/fixtures.d.ts +261 -0
  71. package/dist/procedural-items/fixtures.d.ts.map +1 -0
  72. package/dist/procedural-items/fixtures.js +349 -0
  73. package/dist/procedural-items/index.d.ts +10 -0
  74. package/dist/procedural-items/index.d.ts.map +1 -0
  75. package/dist/procedural-items/index.js +9 -0
  76. package/dist/procedural-items/integration.d.ts +92 -0
  77. package/dist/procedural-items/integration.d.ts.map +1 -0
  78. package/dist/procedural-items/integration.js +19 -0
  79. package/dist/procedural-items/library-colors.d.ts +56 -0
  80. package/dist/procedural-items/library-colors.d.ts.map +1 -0
  81. package/dist/procedural-items/library-colors.js +84 -0
  82. package/dist/procedural-items/materials.d.ts +5 -0
  83. package/dist/procedural-items/materials.d.ts.map +1 -0
  84. package/dist/procedural-items/materials.js +47 -0
  85. package/dist/procedural-items/node.d.ts +280 -0
  86. package/dist/procedural-items/node.d.ts.map +1 -0
  87. package/dist/procedural-items/node.js +71 -0
  88. package/dist/procedural-items/placement.d.ts +7 -0
  89. package/dist/procedural-items/placement.d.ts.map +1 -0
  90. package/dist/procedural-items/placement.js +48 -0
  91. package/dist/procedural-items/query.d.ts +51 -0
  92. package/dist/procedural-items/query.d.ts.map +1 -0
  93. package/dist/procedural-items/query.js +342 -0
  94. package/dist/procedural-items/recipe.d.ts +144 -0
  95. package/dist/procedural-items/recipe.d.ts.map +1 -0
  96. package/dist/procedural-items/recipe.js +372 -0
  97. package/dist/procedural-items/spatial.d.ts +19 -0
  98. package/dist/procedural-items/spatial.d.ts.map +1 -0
  99. package/dist/procedural-items/spatial.js +39 -0
  100. package/dist/registry/__bench__/relations-resolver.bench.js +2 -2
  101. package/dist/registry/handles.d.ts +40 -5
  102. package/dist/registry/handles.d.ts.map +1 -1
  103. package/dist/registry/index.d.ts +6 -6
  104. package/dist/registry/index.d.ts.map +1 -1
  105. package/dist/registry/index.js +4 -4
  106. package/dist/registry/registry.d.ts +1 -1
  107. package/dist/registry/relations-resolver.d.ts +2 -2
  108. package/dist/registry/relations-resolver.js +1 -1
  109. package/dist/registry/scene-api.d.ts +2 -2
  110. package/dist/registry/scene-api.js +2 -2
  111. package/dist/registry/subtree.d.ts +1 -1
  112. package/dist/registry/subtree.d.ts.map +1 -1
  113. package/dist/registry/subtree.js +8 -2
  114. package/dist/registry/types.d.ts +32 -10
  115. package/dist/registry/types.d.ts.map +1 -1
  116. package/dist/registry/use-registry-version.js +1 -1
  117. package/dist/registry/validate-relations.d.ts +4 -0
  118. package/dist/registry/validate-relations.d.ts.map +1 -0
  119. package/dist/registry/validate-relations.js +22 -0
  120. package/dist/schema/__bench__/node-parsers.bench.js +3 -3
  121. package/dist/schema/__fixtures__/node-fixtures.d.ts +1 -1
  122. package/dist/schema/__fixtures__/node-fixtures.d.ts.map +1 -1
  123. package/dist/schema/__fixtures__/node-fixtures.js +4 -2
  124. package/dist/schema/base.js +1 -1
  125. package/dist/schema/collections.d.ts +1 -1
  126. package/dist/schema/collections.js +1 -1
  127. package/dist/schema/compiled-node-parsers.d.ts +1 -1
  128. package/dist/schema/compiled-node-parsers.js +1 -1
  129. package/dist/schema/index.d.ts +74 -70
  130. package/dist/schema/index.d.ts.map +1 -1
  131. package/dist/schema/index.js +65 -61
  132. package/dist/schema/material.d.ts +1 -1
  133. package/dist/schema/material.js +1 -1
  134. package/dist/schema/nodes/automatic-downspout.d.ts +4 -4
  135. package/dist/schema/nodes/automatic-downspout.js +5 -5
  136. package/dist/schema/nodes/block.d.ts +3 -3
  137. package/dist/schema/nodes/block.d.ts.map +1 -1
  138. package/dist/schema/nodes/block.js +24 -12
  139. package/dist/schema/nodes/box-vent.js +2 -2
  140. package/dist/schema/nodes/building.d.ts +1 -1
  141. package/dist/schema/nodes/building.d.ts.map +1 -1
  142. package/dist/schema/nodes/building.js +8 -5
  143. package/dist/schema/nodes/cabinet.d.ts +4 -4
  144. package/dist/schema/nodes/cabinet.js +4 -4
  145. package/dist/schema/nodes/ceiling.d.ts +1 -1
  146. package/dist/schema/nodes/ceiling.js +5 -5
  147. package/dist/schema/nodes/chimney.js +2 -2
  148. package/dist/schema/nodes/column.d.ts +1 -0
  149. package/dist/schema/nodes/column.d.ts.map +1 -1
  150. package/dist/schema/nodes/column.js +3 -2
  151. package/dist/schema/nodes/construction-dimension.d.ts +3 -3
  152. package/dist/schema/nodes/construction-dimension.js +2 -2
  153. package/dist/schema/nodes/cupola.d.ts +1 -1
  154. package/dist/schema/nodes/cupola.js +2 -2
  155. package/dist/schema/nodes/curtain-wall.d.ts +129 -0
  156. package/dist/schema/nodes/curtain-wall.d.ts.map +1 -0
  157. package/dist/schema/nodes/curtain-wall.js +49 -0
  158. package/dist/schema/nodes/door.d.ts +2 -2
  159. package/dist/schema/nodes/door.js +2 -2
  160. package/dist/schema/nodes/dormer.d.ts +3 -3
  161. package/dist/schema/nodes/dormer.js +4 -4
  162. package/dist/schema/nodes/downspout.js +2 -2
  163. package/dist/schema/nodes/duct-fitting.js +1 -1
  164. package/dist/schema/nodes/duct-segment.js +2 -2
  165. package/dist/schema/nodes/duct-terminal.js +1 -1
  166. package/dist/schema/nodes/elevator.js +2 -2
  167. package/dist/schema/nodes/eyebrow-vent.js +2 -2
  168. package/dist/schema/nodes/fence.js +2 -2
  169. package/dist/schema/nodes/guide.js +2 -2
  170. package/dist/schema/nodes/gutter.d.ts +1 -1
  171. package/dist/schema/nodes/gutter.js +4 -4
  172. package/dist/schema/nodes/hvac-equipment.js +1 -1
  173. package/dist/schema/nodes/imported-mesh.d.ts +40 -0
  174. package/dist/schema/nodes/imported-mesh.d.ts.map +1 -0
  175. package/dist/schema/nodes/imported-mesh.js +27 -0
  176. package/dist/schema/nodes/item.d.ts +3 -3
  177. package/dist/schema/nodes/item.js +3 -3
  178. package/dist/schema/nodes/lean-to-extension.js +4 -4
  179. package/dist/schema/nodes/level.d.ts +1 -1
  180. package/dist/schema/nodes/level.d.ts.map +1 -1
  181. package/dist/schema/nodes/level.js +1 -1
  182. package/dist/schema/nodes/lineset.js +1 -1
  183. package/dist/schema/nodes/liquid-line.js +1 -1
  184. package/dist/schema/nodes/measurement.js +2 -2
  185. package/dist/schema/nodes/pipe-fitting.d.ts +1 -1
  186. package/dist/schema/nodes/pipe-fitting.js +1 -1
  187. package/dist/schema/nodes/pipe-segment.d.ts +1 -1
  188. package/dist/schema/nodes/pipe-segment.js +2 -2
  189. package/dist/schema/nodes/pipe-trap.d.ts +1 -1
  190. package/dist/schema/nodes/pipe-trap.js +1 -1
  191. package/dist/schema/nodes/ridge-vent.d.ts +1 -1
  192. package/dist/schema/nodes/ridge-vent.js +3 -3
  193. package/dist/schema/nodes/roof-segment-shape.d.ts +1 -1
  194. package/dist/schema/nodes/roof-segment-shape.js +1 -1
  195. package/dist/schema/nodes/roof-segment-walls.d.ts +1 -1
  196. package/dist/schema/nodes/roof-segment-walls.js +1 -1
  197. package/dist/schema/nodes/roof-segment.d.ts +2 -2
  198. package/dist/schema/nodes/roof-segment.js +2 -2
  199. package/dist/schema/nodes/roof.d.ts +1 -1
  200. package/dist/schema/nodes/roof.js +3 -3
  201. package/dist/schema/nodes/scan.js +3 -3
  202. package/dist/schema/nodes/shelf.d.ts +1 -1
  203. package/dist/schema/nodes/shelf.d.ts.map +1 -1
  204. package/dist/schema/nodes/shelf.js +3 -4
  205. package/dist/schema/nodes/site.js +2 -2
  206. package/dist/schema/nodes/skylight.d.ts +4 -4
  207. package/dist/schema/nodes/skylight.js +2 -2
  208. package/dist/schema/nodes/slab.js +3 -3
  209. package/dist/schema/nodes/solar-panel.js +3 -3
  210. package/dist/schema/nodes/spawn.js +1 -1
  211. package/dist/schema/nodes/stair-segment.js +2 -2
  212. package/dist/schema/nodes/stair.d.ts +1 -1
  213. package/dist/schema/nodes/stair.js +3 -3
  214. package/dist/schema/nodes/structural-grid.js +1 -1
  215. package/dist/schema/nodes/turbine-vent.d.ts +1 -1
  216. package/dist/schema/nodes/turbine-vent.js +2 -2
  217. package/dist/schema/nodes/unit.d.ts +33 -0
  218. package/dist/schema/nodes/unit.d.ts.map +1 -0
  219. package/dist/schema/nodes/unit.js +13 -0
  220. package/dist/schema/nodes/wall.d.ts +75 -2
  221. package/dist/schema/nodes/wall.d.ts.map +1 -1
  222. package/dist/schema/nodes/wall.js +10 -6
  223. package/dist/schema/nodes/window.js +2 -2
  224. package/dist/schema/nodes/zone.js +1 -1
  225. package/dist/schema/scene-material.js +2 -2
  226. package/dist/schema/types.d.ts +417 -22
  227. package/dist/schema/types.d.ts.map +1 -1
  228. package/dist/schema/types.js +56 -49
  229. package/dist/services/__fixtures__/hosting.d.ts +3 -0
  230. package/dist/services/__fixtures__/hosting.d.ts.map +1 -0
  231. package/dist/services/__fixtures__/hosting.js +9 -0
  232. package/dist/services/__fixtures__/shelf-surface-rows.d.ts +4 -0
  233. package/dist/services/__fixtures__/shelf-surface-rows.d.ts.map +1 -0
  234. package/dist/services/__fixtures__/shelf-surface-rows.js +18 -0
  235. package/dist/services/alignment-anchors.d.ts +6 -11
  236. package/dist/services/alignment-anchors.d.ts.map +1 -1
  237. package/dist/services/alignment-anchors.js +7 -34
  238. package/dist/services/drag-session.d.ts +4 -4
  239. package/dist/services/drag-session.js +1 -1
  240. package/dist/services/hosting.d.ts +5 -8
  241. package/dist/services/hosting.d.ts.map +1 -1
  242. package/dist/services/hosting.js +25 -18
  243. package/dist/services/index.d.ts +16 -13
  244. package/dist/services/index.d.ts.map +1 -1
  245. package/dist/services/index.js +16 -13
  246. package/dist/services/level-height.d.ts +2 -2
  247. package/dist/services/level-height.js +3 -3
  248. package/dist/services/movement.d.ts +3 -3
  249. package/dist/services/movement.js +2 -2
  250. package/dist/services/port-connectivity.d.ts +1 -1
  251. package/dist/services/port-connectivity.js +1 -1
  252. package/dist/services/riser-diagram.d.ts +1 -1
  253. package/dist/services/shelf-board.d.ts +5 -0
  254. package/dist/services/shelf-board.d.ts.map +1 -0
  255. package/dist/services/shelf-board.js +15 -0
  256. package/dist/services/snap.d.ts +3 -0
  257. package/dist/services/snap.d.ts.map +1 -1
  258. package/dist/services/snap.js +11 -0
  259. package/dist/services/storey.d.ts +2 -2
  260. package/dist/services/storey.js +2 -2
  261. package/dist/services/surface-hosting-procedural-parity.fixtures.d.ts +13 -0
  262. package/dist/services/surface-hosting-procedural-parity.fixtures.d.ts.map +1 -0
  263. package/dist/services/surface-hosting-procedural-parity.fixtures.js +4691 -0
  264. package/dist/services/surface-hosting-shelf-parity.fixtures.d.ts +1060 -0
  265. package/dist/services/surface-hosting-shelf-parity.fixtures.d.ts.map +1 -0
  266. package/dist/services/surface-hosting-shelf-parity.fixtures.js +3127 -0
  267. package/dist/services/surface-hosting.d.ts +92 -0
  268. package/dist/services/surface-hosting.d.ts.map +1 -0
  269. package/dist/services/surface-hosting.js +305 -0
  270. package/dist/services/surface-region.d.ts +8 -0
  271. package/dist/services/surface-region.d.ts.map +1 -0
  272. package/dist/services/surface-region.js +44 -0
  273. package/dist/services/system-graph.d.ts +2 -2
  274. package/dist/services/system-graph.js +2 -2
  275. package/dist/services/validate-dwv.d.ts +1 -1
  276. package/dist/services/validate-dwv.js +1 -1
  277. package/dist/store/actions/node-actions.d.ts +2 -2
  278. package/dist/store/actions/node-actions.d.ts.map +1 -1
  279. package/dist/store/actions/node-actions.js +50 -104
  280. package/dist/store/history-control.d.ts +3 -3
  281. package/dist/store/history-invalidation.d.ts +1 -1
  282. package/dist/store/history-invalidation.js +1 -1
  283. package/dist/store/use-interactive.d.ts +2 -2
  284. package/dist/store/use-live-terrain.d.ts +1 -1
  285. package/dist/store/use-scene.d.ts +4 -4
  286. package/dist/store/use-scene.d.ts.map +1 -1
  287. package/dist/store/use-scene.js +50 -32
  288. package/dist/systems/elevator/elevator-dispatch.d.ts +2 -2
  289. package/dist/systems/elevator/elevator-dispatch.js +1 -1
  290. package/dist/systems/elevator/elevator-geometry.d.ts +1 -1
  291. package/dist/systems/elevator/elevator-opening-sync.d.ts +1 -1
  292. package/dist/systems/elevator/elevator-opening-sync.js +2 -2
  293. package/dist/systems/elevator/elevator-opening-system.js +3 -3
  294. package/dist/systems/elevator/elevator-runtime.d.ts +3 -3
  295. package/dist/systems/elevator/elevator-runtime.js +3 -3
  296. package/dist/systems/elevator/elevator-service.d.ts +1 -1
  297. package/dist/systems/elevator/elevator-service.js +1 -1
  298. package/dist/systems/fence/fence-centerline.d.ts +2 -2
  299. package/dist/systems/fence/fence-centerline.js +2 -2
  300. package/dist/systems/fence/fence-spline.d.ts +2 -2
  301. package/dist/systems/roof/roof-elevation-system.js +3 -3
  302. package/dist/systems/roof/roof-elevation.d.ts +2 -2
  303. package/dist/systems/roof/roof-elevation.js +6 -6
  304. package/dist/systems/roof/roof-footprint.d.ts +1 -1
  305. package/dist/systems/roof/roof-footprint.js +3 -3
  306. package/dist/systems/slab/slab-placement.d.ts +1 -1
  307. package/dist/systems/slab/slab-support.d.ts +1 -1
  308. package/dist/systems/slab/slab-support.js +4 -4
  309. package/dist/systems/stair/stair-flight.d.ts +2 -2
  310. package/dist/systems/stair/stair-flight.js +2 -2
  311. package/dist/systems/stair/stair-footprint.d.ts +1 -1
  312. package/dist/systems/stair/stair-opening-preview.d.ts +248 -87
  313. package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
  314. package/dist/systems/stair/stair-opening-preview.js +2 -2
  315. package/dist/systems/stair/stair-opening-sync.d.ts +1 -1
  316. package/dist/systems/stair/stair-opening-sync.js +6 -6
  317. package/dist/systems/stair/stair-opening-system.js +8 -8
  318. package/dist/systems/stair/stair-rise.d.ts +1 -1
  319. package/dist/systems/stair/stair-rise.js +3 -3
  320. package/dist/systems/wall/wall-curve.d.ts +2 -2
  321. package/dist/systems/wall/wall-footprint.d.ts +3 -3
  322. package/dist/systems/wall/wall-footprint.js +3 -3
  323. package/dist/systems/wall/wall-merge.d.ts +38 -0
  324. package/dist/systems/wall/wall-merge.d.ts.map +1 -0
  325. package/dist/systems/wall/wall-merge.js +240 -0
  326. package/dist/systems/wall/wall-mitering.d.ts +1 -1
  327. package/dist/systems/wall/wall-mitering.js +1 -1
  328. package/dist/systems/wall/wall-move.d.ts +1 -1
  329. package/dist/systems/wall/wall-operations.d.ts +28 -0
  330. package/dist/systems/wall/wall-operations.d.ts.map +1 -0
  331. package/dist/systems/wall/wall-operations.js +145 -0
  332. package/dist/systems/wall/wall-top.d.ts +1 -1
  333. package/dist/systems/wall/wall-topology.d.ts +9 -2
  334. package/dist/systems/wall/wall-topology.d.ts.map +1 -1
  335. package/dist/systems/wall/wall-topology.js +57 -9
  336. package/dist/utils/clone-scene-graph.d.ts +3 -3
  337. package/dist/utils/clone-scene-graph.d.ts.map +1 -1
  338. package/dist/utils/clone-scene-graph.js +9 -3
  339. package/dist/utils/scene-migrations.d.ts +3 -3
  340. package/dist/utils/scene-migrations.js +3 -3
  341. package/dist/utils/vertical-scene-migration.js +5 -5
  342. package/dist/validation/validate-build-json.d.ts +5 -2
  343. package/dist/validation/validate-build-json.d.ts.map +1 -1
  344. package/dist/validation/validate-build-json.js +57 -4
  345. package/package.json +15 -4
@@ -0,0 +1,4691 @@
1
+ // Captured from the passing production-query/validator comparisons at ad2a57b8 before legacy removal.
2
+ export const frozenProceduralParity = [
3
+ {
4
+ host: {
5
+ object: 'node',
6
+ id: 'procedural-item_frozen-0',
7
+ type: 'procedural-item',
8
+ parentId: null,
9
+ visible: true,
10
+ metadata: {},
11
+ recipe: {
12
+ version: 1,
13
+ name: 'Everyday shelf',
14
+ description: 'An open timber bookcase with adjustable shelves and a contrasting back.',
15
+ parameters: [
16
+ {
17
+ id: 'width',
18
+ label: 'Width',
19
+ default: 1.2,
20
+ min: 0.6,
21
+ max: 2.4,
22
+ step: 0.05,
23
+ unit: 'm',
24
+ axis: 'x',
25
+ },
26
+ {
27
+ id: 'height',
28
+ label: 'Height',
29
+ default: 1.8,
30
+ min: 0.8,
31
+ max: 2.5,
32
+ step: 0.05,
33
+ unit: 'm',
34
+ axis: 'y',
35
+ },
36
+ {
37
+ id: 'depth',
38
+ label: 'Depth',
39
+ default: 0.4,
40
+ min: 0.25,
41
+ max: 0.7,
42
+ step: 0.025,
43
+ unit: 'm',
44
+ axis: 'z',
45
+ },
46
+ {
47
+ id: 'rows',
48
+ label: 'Shelves',
49
+ default: 4,
50
+ min: 2,
51
+ max: 7,
52
+ step: 1,
53
+ unit: 'count',
54
+ part: 'shelves',
55
+ },
56
+ {
57
+ id: 'thickness',
58
+ label: 'Board thickness',
59
+ default: 0.03,
60
+ min: 0.015,
61
+ max: 0.06,
62
+ step: 0.005,
63
+ unit: 'm',
64
+ part: 'frame',
65
+ },
66
+ ],
67
+ slots: [
68
+ {
69
+ id: 'frame',
70
+ label: 'Frame',
71
+ color: '#b58a60',
72
+ },
73
+ {
74
+ id: 'shelves',
75
+ label: 'Shelves',
76
+ color: '#d5b38d',
77
+ },
78
+ {
79
+ id: 'back',
80
+ label: 'Back',
81
+ color: '#495b50',
82
+ },
83
+ ],
84
+ parts: [
85
+ {
86
+ id: 'frame',
87
+ label: 'Frame',
88
+ count: 2,
89
+ shapes: [
90
+ {
91
+ id: 'side',
92
+ primitive: 'box',
93
+ slot: 'frame',
94
+ size: ['thickness', 'height', 'depth'],
95
+ position: [
96
+ {
97
+ op: 'mul',
98
+ args: [
99
+ {
100
+ op: 'sub',
101
+ args: ['index', 0.5],
102
+ },
103
+ {
104
+ op: 'sub',
105
+ args: ['width', 'thickness'],
106
+ },
107
+ ],
108
+ },
109
+ {
110
+ op: 'div',
111
+ args: ['height', 2],
112
+ },
113
+ 0,
114
+ ],
115
+ },
116
+ ],
117
+ },
118
+ {
119
+ id: 'shelves',
120
+ label: 'Shelves',
121
+ count: 'rows',
122
+ shapes: [
123
+ {
124
+ id: 'board',
125
+ primitive: 'box',
126
+ slot: 'shelves',
127
+ size: [
128
+ {
129
+ op: 'sub',
130
+ args: [
131
+ 'width',
132
+ {
133
+ op: 'mul',
134
+ args: [2, 'thickness'],
135
+ },
136
+ ],
137
+ },
138
+ 'thickness',
139
+ 'depth',
140
+ ],
141
+ position: [
142
+ 0,
143
+ {
144
+ op: 'add',
145
+ args: [
146
+ {
147
+ op: 'div',
148
+ args: ['thickness', 2],
149
+ },
150
+ {
151
+ op: 'mul',
152
+ args: [
153
+ 'index',
154
+ {
155
+ op: 'div',
156
+ args: [
157
+ {
158
+ op: 'sub',
159
+ args: ['height', 'thickness'],
160
+ },
161
+ {
162
+ op: 'sub',
163
+ args: ['rows', 1],
164
+ },
165
+ ],
166
+ },
167
+ ],
168
+ },
169
+ ],
170
+ },
171
+ 0,
172
+ ],
173
+ support: true,
174
+ },
175
+ ],
176
+ },
177
+ {
178
+ id: 'back',
179
+ label: 'Back panel',
180
+ count: 1,
181
+ shapes: [
182
+ {
183
+ id: 'panel',
184
+ primitive: 'box',
185
+ slot: 'back',
186
+ size: [
187
+ {
188
+ op: 'sub',
189
+ args: [
190
+ 'width',
191
+ {
192
+ op: 'mul',
193
+ args: [2, 'thickness'],
194
+ },
195
+ ],
196
+ },
197
+ 'height',
198
+ 0.012,
199
+ ],
200
+ position: [
201
+ 0,
202
+ {
203
+ op: 'div',
204
+ args: ['height', 2],
205
+ },
206
+ {
207
+ op: 'add',
208
+ args: [
209
+ {
210
+ op: 'div',
211
+ args: ['depth', -2],
212
+ },
213
+ 0.006,
214
+ ],
215
+ },
216
+ ],
217
+ },
218
+ ],
219
+ },
220
+ ],
221
+ constraints: [],
222
+ },
223
+ parameters: {
224
+ height: 1.8,
225
+ },
226
+ slots: {},
227
+ position: [0, 0, 0],
228
+ rotation: [0, 0, 0],
229
+ children: [],
230
+ attachments: {},
231
+ },
232
+ rows: [
233
+ {
234
+ childKind: 'item',
235
+ childFootprint: {
236
+ size: [0.2, 1, 0.2],
237
+ rotationY: 0,
238
+ },
239
+ hit: {
240
+ point: [0, 0.03, 0],
241
+ normalWorldY: 1,
242
+ },
243
+ expected: {
244
+ position: [0, 0.03, 0],
245
+ rotationY: 0,
246
+ surfaceId: 'shelves:0:board:top',
247
+ childFrame: 'surface-local',
248
+ surfaceLocal: {
249
+ position: [0, -0, 0],
250
+ rotationY: 0,
251
+ rotation: [0, 0, 0],
252
+ },
253
+ },
254
+ rejections: [],
255
+ },
256
+ {
257
+ childKind: 'item',
258
+ childFootprint: {
259
+ size: [0.2, 1, 0.2],
260
+ rotationY: 0.3,
261
+ },
262
+ hit: {
263
+ point: [0.1, 0.03, 0],
264
+ normalWorldY: 1,
265
+ },
266
+ expected: {
267
+ position: [0.1, 0.03, 0],
268
+ rotationY: 0.3,
269
+ surfaceId: 'shelves:0:board:top',
270
+ childFrame: 'surface-local',
271
+ surfaceLocal: {
272
+ position: [0.1, -0, 0],
273
+ rotationY: 0.3,
274
+ rotation: [0, 0.3, 0],
275
+ },
276
+ },
277
+ rejections: [],
278
+ },
279
+ {
280
+ childKind: 'item',
281
+ childFootprint: {
282
+ size: [0.2, 1, 0.6],
283
+ rotationY: 1.5707963267948966,
284
+ },
285
+ hit: {
286
+ point: [0, 0.03, 0],
287
+ normalWorldY: 1,
288
+ },
289
+ expected: {
290
+ position: [0, 0.03, 0],
291
+ rotationY: 1.5707963267948966,
292
+ surfaceId: 'shelves:0:board:top',
293
+ childFrame: 'surface-local',
294
+ surfaceLocal: {
295
+ position: [0, -0, 0],
296
+ rotationY: 1.5707963267948966,
297
+ rotation: [0, 1.5707963267948966, 0],
298
+ },
299
+ },
300
+ rejections: [],
301
+ },
302
+ {
303
+ childKind: 'item',
304
+ childFootprint: {
305
+ size: [0.6, 1, 0.2],
306
+ rotationY: 0.7853981633974483,
307
+ },
308
+ hit: {
309
+ point: [0, 0.03, 0],
310
+ normalWorldY: 1,
311
+ },
312
+ expected: {
313
+ position: [0, 0.03, 0],
314
+ rotationY: 0.7853981633974483,
315
+ surfaceId: 'shelves:0:board:top',
316
+ childFrame: 'surface-local',
317
+ surfaceLocal: {
318
+ position: [0, -0, 0],
319
+ rotationY: 0.7853981633974483,
320
+ rotation: [0, 0.7853981633974483, 0],
321
+ },
322
+ },
323
+ rejections: [],
324
+ },
325
+ {
326
+ childKind: 'item',
327
+ childFootprint: {
328
+ size: [0.4, 1, 0.2],
329
+ rotationY: 0,
330
+ },
331
+ hit: {
332
+ point: [0.5, 0.03, 0],
333
+ normalWorldY: 1,
334
+ },
335
+ expected: {
336
+ position: [0.5, 0.03, 0],
337
+ rotationY: 0,
338
+ surfaceId: 'shelves:0:board:top',
339
+ childFrame: 'surface-local',
340
+ surfaceLocal: {
341
+ position: [0.5, -0, 0],
342
+ rotationY: 0,
343
+ rotation: [0, 0, 0],
344
+ },
345
+ },
346
+ rejections: [],
347
+ },
348
+ {
349
+ childKind: 'item',
350
+ childFootprint: {
351
+ size: [1.1400009999999998, 1, 0.4],
352
+ rotationY: 0,
353
+ },
354
+ hit: {
355
+ point: [0, 0.03, 0],
356
+ normalWorldY: 1,
357
+ },
358
+ expected: {
359
+ position: [0, 0.03, 0],
360
+ rotationY: 0,
361
+ surfaceId: 'shelves:0:board:top',
362
+ childFrame: 'surface-local',
363
+ surfaceLocal: {
364
+ position: [0, -0, 0],
365
+ rotationY: 0,
366
+ rotation: [0, 0, 0],
367
+ },
368
+ },
369
+ rejections: [],
370
+ },
371
+ {
372
+ childKind: 'item',
373
+ childFootprint: {
374
+ size: [1.1400039999999998, 1, 0.4],
375
+ rotationY: 0,
376
+ },
377
+ hit: {
378
+ point: [0, 0.03, 0],
379
+ normalWorldY: 1,
380
+ },
381
+ expected: {
382
+ position: [0, 0.03, 0],
383
+ rotationY: 0,
384
+ surfaceId: 'shelves:0:board:top',
385
+ childFrame: 'surface-local',
386
+ surfaceLocal: {
387
+ position: [0, -0, 0],
388
+ rotationY: 0,
389
+ rotation: [0, 0, 0],
390
+ },
391
+ },
392
+ rejections: [],
393
+ },
394
+ {
395
+ childKind: 'item',
396
+ childFootprint: {
397
+ size: [0.2, 1, 0.2],
398
+ rotationY: 0,
399
+ },
400
+ hit: {
401
+ point: [0, 0.62, 0],
402
+ normalWorldY: 1,
403
+ },
404
+ expected: {
405
+ position: [0, 0.62, 0],
406
+ rotationY: 0,
407
+ surfaceId: 'shelves:1:board:top',
408
+ childFrame: 'surface-local',
409
+ surfaceLocal: {
410
+ position: [0, -0, 0],
411
+ rotationY: 0,
412
+ rotation: [0, 0, 0],
413
+ },
414
+ },
415
+ rejections: [],
416
+ },
417
+ {
418
+ childKind: 'item',
419
+ childFootprint: {
420
+ size: [0.2, 1, 0.2],
421
+ rotationY: 0.3,
422
+ },
423
+ hit: {
424
+ point: [0.1, 0.62, 0],
425
+ normalWorldY: 1,
426
+ },
427
+ expected: {
428
+ position: [0.1, 0.62, 0],
429
+ rotationY: 0.3,
430
+ surfaceId: 'shelves:1:board:top',
431
+ childFrame: 'surface-local',
432
+ surfaceLocal: {
433
+ position: [0.1, -0, 0],
434
+ rotationY: 0.3,
435
+ rotation: [0, 0.3, 0],
436
+ },
437
+ },
438
+ rejections: [],
439
+ },
440
+ {
441
+ childKind: 'item',
442
+ childFootprint: {
443
+ size: [0.2, 1, 0.6],
444
+ rotationY: 1.5707963267948966,
445
+ },
446
+ hit: {
447
+ point: [0, 0.62, 0],
448
+ normalWorldY: 1,
449
+ },
450
+ expected: {
451
+ position: [0, 0.62, 0],
452
+ rotationY: 1.5707963267948966,
453
+ surfaceId: 'shelves:1:board:top',
454
+ childFrame: 'surface-local',
455
+ surfaceLocal: {
456
+ position: [0, -0, 0],
457
+ rotationY: 1.5707963267948966,
458
+ rotation: [0, 1.5707963267948966, 0],
459
+ },
460
+ },
461
+ rejections: [],
462
+ },
463
+ {
464
+ childKind: 'item',
465
+ childFootprint: {
466
+ size: [0.6, 1, 0.2],
467
+ rotationY: 0.7853981633974483,
468
+ },
469
+ hit: {
470
+ point: [0, 0.62, 0],
471
+ normalWorldY: 1,
472
+ },
473
+ expected: {
474
+ position: [0, 0.62, 0],
475
+ rotationY: 0.7853981633974483,
476
+ surfaceId: 'shelves:1:board:top',
477
+ childFrame: 'surface-local',
478
+ surfaceLocal: {
479
+ position: [0, -0, 0],
480
+ rotationY: 0.7853981633974483,
481
+ rotation: [0, 0.7853981633974483, 0],
482
+ },
483
+ },
484
+ rejections: [],
485
+ },
486
+ {
487
+ childKind: 'item',
488
+ childFootprint: {
489
+ size: [0.4, 1, 0.2],
490
+ rotationY: 0,
491
+ },
492
+ hit: {
493
+ point: [0.5, 0.62, 0],
494
+ normalWorldY: 1,
495
+ },
496
+ expected: {
497
+ position: [0.5, 0.62, 0],
498
+ rotationY: 0,
499
+ surfaceId: 'shelves:1:board:top',
500
+ childFrame: 'surface-local',
501
+ surfaceLocal: {
502
+ position: [0.5, -0, 0],
503
+ rotationY: 0,
504
+ rotation: [0, 0, 0],
505
+ },
506
+ },
507
+ rejections: [],
508
+ },
509
+ {
510
+ childKind: 'item',
511
+ childFootprint: {
512
+ size: [1.1400009999999998, 1, 0.4],
513
+ rotationY: 0,
514
+ },
515
+ hit: {
516
+ point: [0, 0.62, 0],
517
+ normalWorldY: 1,
518
+ },
519
+ expected: {
520
+ position: [0, 0.62, 0],
521
+ rotationY: 0,
522
+ surfaceId: 'shelves:1:board:top',
523
+ childFrame: 'surface-local',
524
+ surfaceLocal: {
525
+ position: [0, -0, 0],
526
+ rotationY: 0,
527
+ rotation: [0, 0, 0],
528
+ },
529
+ },
530
+ rejections: [],
531
+ },
532
+ {
533
+ childKind: 'item',
534
+ childFootprint: {
535
+ size: [1.1400039999999998, 1, 0.4],
536
+ rotationY: 0,
537
+ },
538
+ hit: {
539
+ point: [0, 0.62, 0],
540
+ normalWorldY: 1,
541
+ },
542
+ expected: {
543
+ position: [0, 0.62, 0],
544
+ rotationY: 0,
545
+ surfaceId: 'shelves:1:board:top',
546
+ childFrame: 'surface-local',
547
+ surfaceLocal: {
548
+ position: [0, -0, 0],
549
+ rotationY: 0,
550
+ rotation: [0, 0, 0],
551
+ },
552
+ },
553
+ rejections: [],
554
+ },
555
+ {
556
+ childKind: 'item',
557
+ childFootprint: {
558
+ size: [0.2, 1, 0.2],
559
+ rotationY: 0,
560
+ },
561
+ hit: {
562
+ point: [0, 1.2099999999999997, 0],
563
+ normalWorldY: 1,
564
+ },
565
+ expected: {
566
+ position: [0, 1.2099999999999997, 0],
567
+ rotationY: 0,
568
+ surfaceId: 'shelves:2:board:top',
569
+ childFrame: 'surface-local',
570
+ surfaceLocal: {
571
+ position: [0, -0, 0],
572
+ rotationY: 0,
573
+ rotation: [0, 0, 0],
574
+ },
575
+ },
576
+ rejections: [],
577
+ },
578
+ {
579
+ childKind: 'item',
580
+ childFootprint: {
581
+ size: [0.2, 1, 0.2],
582
+ rotationY: 0.3,
583
+ },
584
+ hit: {
585
+ point: [0.1, 1.2099999999999997, 0],
586
+ normalWorldY: 1,
587
+ },
588
+ expected: {
589
+ position: [0.1, 1.2099999999999997, 0],
590
+ rotationY: 0.3,
591
+ surfaceId: 'shelves:2:board:top',
592
+ childFrame: 'surface-local',
593
+ surfaceLocal: {
594
+ position: [0.1, -0, 0],
595
+ rotationY: 0.3,
596
+ rotation: [0, 0.3, 0],
597
+ },
598
+ },
599
+ rejections: [],
600
+ },
601
+ {
602
+ childKind: 'item',
603
+ childFootprint: {
604
+ size: [0.2, 1, 0.6],
605
+ rotationY: 1.5707963267948966,
606
+ },
607
+ hit: {
608
+ point: [0, 1.2099999999999997, 0],
609
+ normalWorldY: 1,
610
+ },
611
+ expected: {
612
+ position: [0, 1.2099999999999997, 0],
613
+ rotationY: 1.5707963267948966,
614
+ surfaceId: 'shelves:2:board:top',
615
+ childFrame: 'surface-local',
616
+ surfaceLocal: {
617
+ position: [0, -0, 0],
618
+ rotationY: 1.5707963267948966,
619
+ rotation: [0, 1.5707963267948966, 0],
620
+ },
621
+ },
622
+ rejections: [],
623
+ },
624
+ {
625
+ childKind: 'item',
626
+ childFootprint: {
627
+ size: [0.6, 1, 0.2],
628
+ rotationY: 0.7853981633974483,
629
+ },
630
+ hit: {
631
+ point: [0, 1.2099999999999997, 0],
632
+ normalWorldY: 1,
633
+ },
634
+ expected: {
635
+ position: [0, 1.2099999999999997, 0],
636
+ rotationY: 0.7853981633974483,
637
+ surfaceId: 'shelves:2:board:top',
638
+ childFrame: 'surface-local',
639
+ surfaceLocal: {
640
+ position: [0, -0, 0],
641
+ rotationY: 0.7853981633974483,
642
+ rotation: [0, 0.7853981633974483, 0],
643
+ },
644
+ },
645
+ rejections: [],
646
+ },
647
+ {
648
+ childKind: 'item',
649
+ childFootprint: {
650
+ size: [0.4, 1, 0.2],
651
+ rotationY: 0,
652
+ },
653
+ hit: {
654
+ point: [0.5, 1.2099999999999997, 0],
655
+ normalWorldY: 1,
656
+ },
657
+ expected: {
658
+ position: [0.5, 1.2099999999999997, 0],
659
+ rotationY: 0,
660
+ surfaceId: 'shelves:2:board:top',
661
+ childFrame: 'surface-local',
662
+ surfaceLocal: {
663
+ position: [0.5, -0, 0],
664
+ rotationY: 0,
665
+ rotation: [0, 0, 0],
666
+ },
667
+ },
668
+ rejections: [],
669
+ },
670
+ {
671
+ childKind: 'item',
672
+ childFootprint: {
673
+ size: [1.1400009999999998, 1, 0.4],
674
+ rotationY: 0,
675
+ },
676
+ hit: {
677
+ point: [0, 1.2099999999999997, 0],
678
+ normalWorldY: 1,
679
+ },
680
+ expected: {
681
+ position: [0, 1.2099999999999997, 0],
682
+ rotationY: 0,
683
+ surfaceId: 'shelves:2:board:top',
684
+ childFrame: 'surface-local',
685
+ surfaceLocal: {
686
+ position: [0, -0, 0],
687
+ rotationY: 0,
688
+ rotation: [0, 0, 0],
689
+ },
690
+ },
691
+ rejections: [],
692
+ },
693
+ {
694
+ childKind: 'item',
695
+ childFootprint: {
696
+ size: [1.1400039999999998, 1, 0.4],
697
+ rotationY: 0,
698
+ },
699
+ hit: {
700
+ point: [0, 1.2099999999999997, 0],
701
+ normalWorldY: 1,
702
+ },
703
+ expected: {
704
+ position: [0, 1.2099999999999997, 0],
705
+ rotationY: 0,
706
+ surfaceId: 'shelves:2:board:top',
707
+ childFrame: 'surface-local',
708
+ surfaceLocal: {
709
+ position: [0, -0, 0],
710
+ rotationY: 0,
711
+ rotation: [0, 0, 0],
712
+ },
713
+ },
714
+ rejections: [],
715
+ },
716
+ {
717
+ childKind: 'item',
718
+ childFootprint: {
719
+ size: [0.2, 1, 0.2],
720
+ rotationY: 0,
721
+ },
722
+ hit: {
723
+ point: [0, 1.7999999999999998, 0],
724
+ normalWorldY: 1,
725
+ },
726
+ expected: {
727
+ position: [0, 1.7999999999999998, 0],
728
+ rotationY: 0,
729
+ surfaceId: 'shelves:3:board:top',
730
+ childFrame: 'surface-local',
731
+ surfaceLocal: {
732
+ position: [0, -0, 0],
733
+ rotationY: 0,
734
+ rotation: [0, 0, 0],
735
+ },
736
+ },
737
+ rejections: [],
738
+ },
739
+ {
740
+ childKind: 'item',
741
+ childFootprint: {
742
+ size: [0.2, 1, 0.2],
743
+ rotationY: 0.3,
744
+ },
745
+ hit: {
746
+ point: [0.1, 1.7999999999999998, 0],
747
+ normalWorldY: 1,
748
+ },
749
+ expected: {
750
+ position: [0.1, 1.7999999999999998, 0],
751
+ rotationY: 0.3,
752
+ surfaceId: 'shelves:3:board:top',
753
+ childFrame: 'surface-local',
754
+ surfaceLocal: {
755
+ position: [0.1, -0, 0],
756
+ rotationY: 0.3,
757
+ rotation: [0, 0.3, 0],
758
+ },
759
+ },
760
+ rejections: [],
761
+ },
762
+ {
763
+ childKind: 'item',
764
+ childFootprint: {
765
+ size: [0.2, 1, 0.6],
766
+ rotationY: 1.5707963267948966,
767
+ },
768
+ hit: {
769
+ point: [0, 1.7999999999999998, 0],
770
+ normalWorldY: 1,
771
+ },
772
+ expected: {
773
+ position: [0, 1.7999999999999998, 0],
774
+ rotationY: 1.5707963267948966,
775
+ surfaceId: 'shelves:3:board:top',
776
+ childFrame: 'surface-local',
777
+ surfaceLocal: {
778
+ position: [0, -0, 0],
779
+ rotationY: 1.5707963267948966,
780
+ rotation: [0, 1.5707963267948966, 0],
781
+ },
782
+ },
783
+ rejections: [],
784
+ },
785
+ {
786
+ childKind: 'item',
787
+ childFootprint: {
788
+ size: [0.6, 1, 0.2],
789
+ rotationY: 0.7853981633974483,
790
+ },
791
+ hit: {
792
+ point: [0, 1.7999999999999998, 0],
793
+ normalWorldY: 1,
794
+ },
795
+ expected: {
796
+ position: [0, 1.7999999999999998, 0],
797
+ rotationY: 0.7853981633974483,
798
+ surfaceId: 'shelves:3:board:top',
799
+ childFrame: 'surface-local',
800
+ surfaceLocal: {
801
+ position: [0, -0, 0],
802
+ rotationY: 0.7853981633974483,
803
+ rotation: [0, 0.7853981633974483, 0],
804
+ },
805
+ },
806
+ rejections: [],
807
+ },
808
+ {
809
+ childKind: 'item',
810
+ childFootprint: {
811
+ size: [0.4, 1, 0.2],
812
+ rotationY: 0,
813
+ },
814
+ hit: {
815
+ point: [0.5, 1.7999999999999998, 0],
816
+ normalWorldY: 1,
817
+ },
818
+ expected: {
819
+ position: [0.5, 1.7999999999999998, 0],
820
+ rotationY: 0,
821
+ surfaceId: 'shelves:3:board:top',
822
+ childFrame: 'surface-local',
823
+ surfaceLocal: {
824
+ position: [0.5, -0, 0],
825
+ rotationY: 0,
826
+ rotation: [0, 0, 0],
827
+ },
828
+ },
829
+ rejections: [],
830
+ },
831
+ {
832
+ childKind: 'item',
833
+ childFootprint: {
834
+ size: [1.1400009999999998, 1, 0.4],
835
+ rotationY: 0,
836
+ },
837
+ hit: {
838
+ point: [0, 1.7999999999999998, 0],
839
+ normalWorldY: 1,
840
+ },
841
+ expected: {
842
+ position: [0, 1.7999999999999998, 0],
843
+ rotationY: 0,
844
+ surfaceId: 'shelves:3:board:top',
845
+ childFrame: 'surface-local',
846
+ surfaceLocal: {
847
+ position: [0, -0, 0],
848
+ rotationY: 0,
849
+ rotation: [0, 0, 0],
850
+ },
851
+ },
852
+ rejections: [],
853
+ },
854
+ {
855
+ childKind: 'item',
856
+ childFootprint: {
857
+ size: [1.1400039999999998, 1, 0.4],
858
+ rotationY: 0,
859
+ },
860
+ hit: {
861
+ point: [0, 1.7999999999999998, 0],
862
+ normalWorldY: 1,
863
+ },
864
+ expected: {
865
+ position: [0, 1.7999999999999998, 0],
866
+ rotationY: 0,
867
+ surfaceId: 'shelves:3:board:top',
868
+ childFrame: 'surface-local',
869
+ surfaceLocal: {
870
+ position: [0, -0, 0],
871
+ rotationY: 0,
872
+ rotation: [0, 0, 0],
873
+ },
874
+ },
875
+ rejections: [],
876
+ },
877
+ ],
878
+ label: 'shelf height 1.8: containment and tolerance',
879
+ },
880
+ {
881
+ host: {
882
+ object: 'node',
883
+ id: 'procedural-item_frozen-1',
884
+ type: 'procedural-item',
885
+ parentId: null,
886
+ visible: true,
887
+ metadata: {},
888
+ recipe: {
889
+ version: 1,
890
+ name: 'Everyday shelf',
891
+ description: 'An open timber bookcase with adjustable shelves and a contrasting back.',
892
+ parameters: [
893
+ {
894
+ id: 'width',
895
+ label: 'Width',
896
+ default: 1.2,
897
+ min: 0.6,
898
+ max: 2.4,
899
+ step: 0.05,
900
+ unit: 'm',
901
+ axis: 'x',
902
+ },
903
+ {
904
+ id: 'height',
905
+ label: 'Height',
906
+ default: 1.8,
907
+ min: 0.8,
908
+ max: 2.5,
909
+ step: 0.05,
910
+ unit: 'm',
911
+ axis: 'y',
912
+ },
913
+ {
914
+ id: 'depth',
915
+ label: 'Depth',
916
+ default: 0.4,
917
+ min: 0.25,
918
+ max: 0.7,
919
+ step: 0.025,
920
+ unit: 'm',
921
+ axis: 'z',
922
+ },
923
+ {
924
+ id: 'rows',
925
+ label: 'Shelves',
926
+ default: 4,
927
+ min: 2,
928
+ max: 7,
929
+ step: 1,
930
+ unit: 'count',
931
+ part: 'shelves',
932
+ },
933
+ {
934
+ id: 'thickness',
935
+ label: 'Board thickness',
936
+ default: 0.03,
937
+ min: 0.015,
938
+ max: 0.06,
939
+ step: 0.005,
940
+ unit: 'm',
941
+ part: 'frame',
942
+ },
943
+ ],
944
+ slots: [
945
+ {
946
+ id: 'frame',
947
+ label: 'Frame',
948
+ color: '#b58a60',
949
+ },
950
+ {
951
+ id: 'shelves',
952
+ label: 'Shelves',
953
+ color: '#d5b38d',
954
+ },
955
+ {
956
+ id: 'back',
957
+ label: 'Back',
958
+ color: '#495b50',
959
+ },
960
+ ],
961
+ parts: [
962
+ {
963
+ id: 'frame',
964
+ label: 'Frame',
965
+ count: 2,
966
+ shapes: [
967
+ {
968
+ id: 'side',
969
+ primitive: 'box',
970
+ slot: 'frame',
971
+ size: ['thickness', 'height', 'depth'],
972
+ position: [
973
+ {
974
+ op: 'mul',
975
+ args: [
976
+ {
977
+ op: 'sub',
978
+ args: ['index', 0.5],
979
+ },
980
+ {
981
+ op: 'sub',
982
+ args: ['width', 'thickness'],
983
+ },
984
+ ],
985
+ },
986
+ {
987
+ op: 'div',
988
+ args: ['height', 2],
989
+ },
990
+ 0,
991
+ ],
992
+ },
993
+ ],
994
+ },
995
+ {
996
+ id: 'shelves',
997
+ label: 'Shelves',
998
+ count: 'rows',
999
+ shapes: [
1000
+ {
1001
+ id: 'board',
1002
+ primitive: 'box',
1003
+ slot: 'shelves',
1004
+ size: [
1005
+ {
1006
+ op: 'sub',
1007
+ args: [
1008
+ 'width',
1009
+ {
1010
+ op: 'mul',
1011
+ args: [2, 'thickness'],
1012
+ },
1013
+ ],
1014
+ },
1015
+ 'thickness',
1016
+ 'depth',
1017
+ ],
1018
+ position: [
1019
+ 0,
1020
+ {
1021
+ op: 'add',
1022
+ args: [
1023
+ {
1024
+ op: 'div',
1025
+ args: ['thickness', 2],
1026
+ },
1027
+ {
1028
+ op: 'mul',
1029
+ args: [
1030
+ 'index',
1031
+ {
1032
+ op: 'div',
1033
+ args: [
1034
+ {
1035
+ op: 'sub',
1036
+ args: ['height', 'thickness'],
1037
+ },
1038
+ {
1039
+ op: 'sub',
1040
+ args: ['rows', 1],
1041
+ },
1042
+ ],
1043
+ },
1044
+ ],
1045
+ },
1046
+ ],
1047
+ },
1048
+ 0,
1049
+ ],
1050
+ support: true,
1051
+ },
1052
+ ],
1053
+ },
1054
+ {
1055
+ id: 'back',
1056
+ label: 'Back panel',
1057
+ count: 1,
1058
+ shapes: [
1059
+ {
1060
+ id: 'panel',
1061
+ primitive: 'box',
1062
+ slot: 'back',
1063
+ size: [
1064
+ {
1065
+ op: 'sub',
1066
+ args: [
1067
+ 'width',
1068
+ {
1069
+ op: 'mul',
1070
+ args: [2, 'thickness'],
1071
+ },
1072
+ ],
1073
+ },
1074
+ 'height',
1075
+ 0.012,
1076
+ ],
1077
+ position: [
1078
+ 0,
1079
+ {
1080
+ op: 'div',
1081
+ args: ['height', 2],
1082
+ },
1083
+ {
1084
+ op: 'add',
1085
+ args: [
1086
+ {
1087
+ op: 'div',
1088
+ args: ['depth', -2],
1089
+ },
1090
+ 0.006,
1091
+ ],
1092
+ },
1093
+ ],
1094
+ },
1095
+ ],
1096
+ },
1097
+ ],
1098
+ constraints: [],
1099
+ },
1100
+ parameters: {
1101
+ height: 2.4,
1102
+ },
1103
+ slots: {},
1104
+ position: [0, 0, 0],
1105
+ rotation: [0, 0, 0],
1106
+ children: [],
1107
+ attachments: {},
1108
+ },
1109
+ rows: [
1110
+ {
1111
+ childKind: 'item',
1112
+ childFootprint: {
1113
+ size: [0.2, 1, 0.2],
1114
+ rotationY: 0,
1115
+ },
1116
+ hit: {
1117
+ point: [0, 0.03, 0],
1118
+ normalWorldY: 1,
1119
+ },
1120
+ expected: {
1121
+ position: [0, 0.03, 0],
1122
+ rotationY: 0,
1123
+ surfaceId: 'shelves:0:board:top',
1124
+ childFrame: 'surface-local',
1125
+ surfaceLocal: {
1126
+ position: [0, -0, 0],
1127
+ rotationY: 0,
1128
+ rotation: [0, 0, 0],
1129
+ },
1130
+ },
1131
+ rejections: [],
1132
+ },
1133
+ {
1134
+ childKind: 'item',
1135
+ childFootprint: {
1136
+ size: [0.2, 1, 0.2],
1137
+ rotationY: 0.3,
1138
+ },
1139
+ hit: {
1140
+ point: [0.1, 0.03, 0],
1141
+ normalWorldY: 1,
1142
+ },
1143
+ expected: {
1144
+ position: [0.1, 0.03, 0],
1145
+ rotationY: 0.3,
1146
+ surfaceId: 'shelves:0:board:top',
1147
+ childFrame: 'surface-local',
1148
+ surfaceLocal: {
1149
+ position: [0.1, -0, 0],
1150
+ rotationY: 0.3,
1151
+ rotation: [0, 0.3, 0],
1152
+ },
1153
+ },
1154
+ rejections: [],
1155
+ },
1156
+ {
1157
+ childKind: 'item',
1158
+ childFootprint: {
1159
+ size: [0.2, 1, 0.6],
1160
+ rotationY: 1.5707963267948966,
1161
+ },
1162
+ hit: {
1163
+ point: [0, 0.03, 0],
1164
+ normalWorldY: 1,
1165
+ },
1166
+ expected: {
1167
+ position: [0, 0.03, 0],
1168
+ rotationY: 1.5707963267948966,
1169
+ surfaceId: 'shelves:0:board:top',
1170
+ childFrame: 'surface-local',
1171
+ surfaceLocal: {
1172
+ position: [0, -0, 0],
1173
+ rotationY: 1.5707963267948966,
1174
+ rotation: [0, 1.5707963267948966, 0],
1175
+ },
1176
+ },
1177
+ rejections: [],
1178
+ },
1179
+ {
1180
+ childKind: 'item',
1181
+ childFootprint: {
1182
+ size: [0.6, 1, 0.2],
1183
+ rotationY: 0.7853981633974483,
1184
+ },
1185
+ hit: {
1186
+ point: [0, 0.03, 0],
1187
+ normalWorldY: 1,
1188
+ },
1189
+ expected: {
1190
+ position: [0, 0.03, 0],
1191
+ rotationY: 0.7853981633974483,
1192
+ surfaceId: 'shelves:0:board:top',
1193
+ childFrame: 'surface-local',
1194
+ surfaceLocal: {
1195
+ position: [0, -0, 0],
1196
+ rotationY: 0.7853981633974483,
1197
+ rotation: [0, 0.7853981633974483, 0],
1198
+ },
1199
+ },
1200
+ rejections: [],
1201
+ },
1202
+ {
1203
+ childKind: 'item',
1204
+ childFootprint: {
1205
+ size: [0.4, 1, 0.2],
1206
+ rotationY: 0,
1207
+ },
1208
+ hit: {
1209
+ point: [0.5, 0.03, 0],
1210
+ normalWorldY: 1,
1211
+ },
1212
+ expected: {
1213
+ position: [0.5, 0.03, 0],
1214
+ rotationY: 0,
1215
+ surfaceId: 'shelves:0:board:top',
1216
+ childFrame: 'surface-local',
1217
+ surfaceLocal: {
1218
+ position: [0.5, -0, 0],
1219
+ rotationY: 0,
1220
+ rotation: [0, 0, 0],
1221
+ },
1222
+ },
1223
+ rejections: [],
1224
+ },
1225
+ {
1226
+ childKind: 'item',
1227
+ childFootprint: {
1228
+ size: [1.1400009999999998, 1, 0.4],
1229
+ rotationY: 0,
1230
+ },
1231
+ hit: {
1232
+ point: [0, 0.03, 0],
1233
+ normalWorldY: 1,
1234
+ },
1235
+ expected: {
1236
+ position: [0, 0.03, 0],
1237
+ rotationY: 0,
1238
+ surfaceId: 'shelves:0:board:top',
1239
+ childFrame: 'surface-local',
1240
+ surfaceLocal: {
1241
+ position: [0, -0, 0],
1242
+ rotationY: 0,
1243
+ rotation: [0, 0, 0],
1244
+ },
1245
+ },
1246
+ rejections: [],
1247
+ },
1248
+ {
1249
+ childKind: 'item',
1250
+ childFootprint: {
1251
+ size: [1.1400039999999998, 1, 0.4],
1252
+ rotationY: 0,
1253
+ },
1254
+ hit: {
1255
+ point: [0, 0.03, 0],
1256
+ normalWorldY: 1,
1257
+ },
1258
+ expected: {
1259
+ position: [0, 0.03, 0],
1260
+ rotationY: 0,
1261
+ surfaceId: 'shelves:0:board:top',
1262
+ childFrame: 'surface-local',
1263
+ surfaceLocal: {
1264
+ position: [0, -0, 0],
1265
+ rotationY: 0,
1266
+ rotation: [0, 0, 0],
1267
+ },
1268
+ },
1269
+ rejections: [],
1270
+ },
1271
+ {
1272
+ childKind: 'item',
1273
+ childFootprint: {
1274
+ size: [0.2, 1, 0.2],
1275
+ rotationY: 0,
1276
+ },
1277
+ hit: {
1278
+ point: [0, 0.8200000000000001, 0],
1279
+ normalWorldY: 1,
1280
+ },
1281
+ expected: {
1282
+ position: [0, 0.8200000000000001, 0],
1283
+ rotationY: 0,
1284
+ surfaceId: 'shelves:1:board:top',
1285
+ childFrame: 'surface-local',
1286
+ surfaceLocal: {
1287
+ position: [0, -0, 0],
1288
+ rotationY: 0,
1289
+ rotation: [0, 0, 0],
1290
+ },
1291
+ },
1292
+ rejections: [],
1293
+ },
1294
+ {
1295
+ childKind: 'item',
1296
+ childFootprint: {
1297
+ size: [0.2, 1, 0.2],
1298
+ rotationY: 0.3,
1299
+ },
1300
+ hit: {
1301
+ point: [0.1, 0.8200000000000001, 0],
1302
+ normalWorldY: 1,
1303
+ },
1304
+ expected: {
1305
+ position: [0.1, 0.8200000000000001, 0],
1306
+ rotationY: 0.3,
1307
+ surfaceId: 'shelves:1:board:top',
1308
+ childFrame: 'surface-local',
1309
+ surfaceLocal: {
1310
+ position: [0.1, -0, 0],
1311
+ rotationY: 0.3,
1312
+ rotation: [0, 0.3, 0],
1313
+ },
1314
+ },
1315
+ rejections: [],
1316
+ },
1317
+ {
1318
+ childKind: 'item',
1319
+ childFootprint: {
1320
+ size: [0.2, 1, 0.6],
1321
+ rotationY: 1.5707963267948966,
1322
+ },
1323
+ hit: {
1324
+ point: [0, 0.8200000000000001, 0],
1325
+ normalWorldY: 1,
1326
+ },
1327
+ expected: {
1328
+ position: [0, 0.8200000000000001, 0],
1329
+ rotationY: 1.5707963267948966,
1330
+ surfaceId: 'shelves:1:board:top',
1331
+ childFrame: 'surface-local',
1332
+ surfaceLocal: {
1333
+ position: [0, -0, 0],
1334
+ rotationY: 1.5707963267948966,
1335
+ rotation: [0, 1.5707963267948966, 0],
1336
+ },
1337
+ },
1338
+ rejections: [],
1339
+ },
1340
+ {
1341
+ childKind: 'item',
1342
+ childFootprint: {
1343
+ size: [0.6, 1, 0.2],
1344
+ rotationY: 0.7853981633974483,
1345
+ },
1346
+ hit: {
1347
+ point: [0, 0.8200000000000001, 0],
1348
+ normalWorldY: 1,
1349
+ },
1350
+ expected: {
1351
+ position: [0, 0.8200000000000001, 0],
1352
+ rotationY: 0.7853981633974483,
1353
+ surfaceId: 'shelves:1:board:top',
1354
+ childFrame: 'surface-local',
1355
+ surfaceLocal: {
1356
+ position: [0, -0, 0],
1357
+ rotationY: 0.7853981633974483,
1358
+ rotation: [0, 0.7853981633974483, 0],
1359
+ },
1360
+ },
1361
+ rejections: [],
1362
+ },
1363
+ {
1364
+ childKind: 'item',
1365
+ childFootprint: {
1366
+ size: [0.4, 1, 0.2],
1367
+ rotationY: 0,
1368
+ },
1369
+ hit: {
1370
+ point: [0.5, 0.8200000000000001, 0],
1371
+ normalWorldY: 1,
1372
+ },
1373
+ expected: {
1374
+ position: [0.5, 0.8200000000000001, 0],
1375
+ rotationY: 0,
1376
+ surfaceId: 'shelves:1:board:top',
1377
+ childFrame: 'surface-local',
1378
+ surfaceLocal: {
1379
+ position: [0.5, -0, 0],
1380
+ rotationY: 0,
1381
+ rotation: [0, 0, 0],
1382
+ },
1383
+ },
1384
+ rejections: [],
1385
+ },
1386
+ {
1387
+ childKind: 'item',
1388
+ childFootprint: {
1389
+ size: [1.1400009999999998, 1, 0.4],
1390
+ rotationY: 0,
1391
+ },
1392
+ hit: {
1393
+ point: [0, 0.8200000000000001, 0],
1394
+ normalWorldY: 1,
1395
+ },
1396
+ expected: {
1397
+ position: [0, 0.8200000000000001, 0],
1398
+ rotationY: 0,
1399
+ surfaceId: 'shelves:1:board:top',
1400
+ childFrame: 'surface-local',
1401
+ surfaceLocal: {
1402
+ position: [0, -0, 0],
1403
+ rotationY: 0,
1404
+ rotation: [0, 0, 0],
1405
+ },
1406
+ },
1407
+ rejections: [],
1408
+ },
1409
+ {
1410
+ childKind: 'item',
1411
+ childFootprint: {
1412
+ size: [1.1400039999999998, 1, 0.4],
1413
+ rotationY: 0,
1414
+ },
1415
+ hit: {
1416
+ point: [0, 0.8200000000000001, 0],
1417
+ normalWorldY: 1,
1418
+ },
1419
+ expected: {
1420
+ position: [0, 0.8200000000000001, 0],
1421
+ rotationY: 0,
1422
+ surfaceId: 'shelves:1:board:top',
1423
+ childFrame: 'surface-local',
1424
+ surfaceLocal: {
1425
+ position: [0, -0, 0],
1426
+ rotationY: 0,
1427
+ rotation: [0, 0, 0],
1428
+ },
1429
+ },
1430
+ rejections: [],
1431
+ },
1432
+ {
1433
+ childKind: 'item',
1434
+ childFootprint: {
1435
+ size: [0.2, 1, 0.2],
1436
+ rotationY: 0,
1437
+ },
1438
+ hit: {
1439
+ point: [0, 1.6099999999999999, 0],
1440
+ normalWorldY: 1,
1441
+ },
1442
+ expected: {
1443
+ position: [0, 1.6099999999999999, 0],
1444
+ rotationY: 0,
1445
+ surfaceId: 'shelves:2:board:top',
1446
+ childFrame: 'surface-local',
1447
+ surfaceLocal: {
1448
+ position: [0, -0, 0],
1449
+ rotationY: 0,
1450
+ rotation: [0, 0, 0],
1451
+ },
1452
+ },
1453
+ rejections: [],
1454
+ },
1455
+ {
1456
+ childKind: 'item',
1457
+ childFootprint: {
1458
+ size: [0.2, 1, 0.2],
1459
+ rotationY: 0.3,
1460
+ },
1461
+ hit: {
1462
+ point: [0.1, 1.6099999999999999, 0],
1463
+ normalWorldY: 1,
1464
+ },
1465
+ expected: {
1466
+ position: [0.1, 1.6099999999999999, 0],
1467
+ rotationY: 0.3,
1468
+ surfaceId: 'shelves:2:board:top',
1469
+ childFrame: 'surface-local',
1470
+ surfaceLocal: {
1471
+ position: [0.1, -0, 0],
1472
+ rotationY: 0.3,
1473
+ rotation: [0, 0.3, 0],
1474
+ },
1475
+ },
1476
+ rejections: [],
1477
+ },
1478
+ {
1479
+ childKind: 'item',
1480
+ childFootprint: {
1481
+ size: [0.2, 1, 0.6],
1482
+ rotationY: 1.5707963267948966,
1483
+ },
1484
+ hit: {
1485
+ point: [0, 1.6099999999999999, 0],
1486
+ normalWorldY: 1,
1487
+ },
1488
+ expected: {
1489
+ position: [0, 1.6099999999999999, 0],
1490
+ rotationY: 1.5707963267948966,
1491
+ surfaceId: 'shelves:2:board:top',
1492
+ childFrame: 'surface-local',
1493
+ surfaceLocal: {
1494
+ position: [0, -0, 0],
1495
+ rotationY: 1.5707963267948966,
1496
+ rotation: [0, 1.5707963267948966, 0],
1497
+ },
1498
+ },
1499
+ rejections: [],
1500
+ },
1501
+ {
1502
+ childKind: 'item',
1503
+ childFootprint: {
1504
+ size: [0.6, 1, 0.2],
1505
+ rotationY: 0.7853981633974483,
1506
+ },
1507
+ hit: {
1508
+ point: [0, 1.6099999999999999, 0],
1509
+ normalWorldY: 1,
1510
+ },
1511
+ expected: {
1512
+ position: [0, 1.6099999999999999, 0],
1513
+ rotationY: 0.7853981633974483,
1514
+ surfaceId: 'shelves:2:board:top',
1515
+ childFrame: 'surface-local',
1516
+ surfaceLocal: {
1517
+ position: [0, -0, 0],
1518
+ rotationY: 0.7853981633974483,
1519
+ rotation: [0, 0.7853981633974483, 0],
1520
+ },
1521
+ },
1522
+ rejections: [],
1523
+ },
1524
+ {
1525
+ childKind: 'item',
1526
+ childFootprint: {
1527
+ size: [0.4, 1, 0.2],
1528
+ rotationY: 0,
1529
+ },
1530
+ hit: {
1531
+ point: [0.5, 1.6099999999999999, 0],
1532
+ normalWorldY: 1,
1533
+ },
1534
+ expected: {
1535
+ position: [0.5, 1.6099999999999999, 0],
1536
+ rotationY: 0,
1537
+ surfaceId: 'shelves:2:board:top',
1538
+ childFrame: 'surface-local',
1539
+ surfaceLocal: {
1540
+ position: [0.5, -0, 0],
1541
+ rotationY: 0,
1542
+ rotation: [0, 0, 0],
1543
+ },
1544
+ },
1545
+ rejections: [],
1546
+ },
1547
+ {
1548
+ childKind: 'item',
1549
+ childFootprint: {
1550
+ size: [1.1400009999999998, 1, 0.4],
1551
+ rotationY: 0,
1552
+ },
1553
+ hit: {
1554
+ point: [0, 1.6099999999999999, 0],
1555
+ normalWorldY: 1,
1556
+ },
1557
+ expected: {
1558
+ position: [0, 1.6099999999999999, 0],
1559
+ rotationY: 0,
1560
+ surfaceId: 'shelves:2:board:top',
1561
+ childFrame: 'surface-local',
1562
+ surfaceLocal: {
1563
+ position: [0, -0, 0],
1564
+ rotationY: 0,
1565
+ rotation: [0, 0, 0],
1566
+ },
1567
+ },
1568
+ rejections: [],
1569
+ },
1570
+ {
1571
+ childKind: 'item',
1572
+ childFootprint: {
1573
+ size: [1.1400039999999998, 1, 0.4],
1574
+ rotationY: 0,
1575
+ },
1576
+ hit: {
1577
+ point: [0, 1.6099999999999999, 0],
1578
+ normalWorldY: 1,
1579
+ },
1580
+ expected: {
1581
+ position: [0, 1.6099999999999999, 0],
1582
+ rotationY: 0,
1583
+ surfaceId: 'shelves:2:board:top',
1584
+ childFrame: 'surface-local',
1585
+ surfaceLocal: {
1586
+ position: [0, -0, 0],
1587
+ rotationY: 0,
1588
+ rotation: [0, 0, 0],
1589
+ },
1590
+ },
1591
+ rejections: [],
1592
+ },
1593
+ {
1594
+ childKind: 'item',
1595
+ childFootprint: {
1596
+ size: [0.2, 1, 0.2],
1597
+ rotationY: 0,
1598
+ },
1599
+ hit: {
1600
+ point: [0, 2.4000000000000004, 0],
1601
+ normalWorldY: 1,
1602
+ },
1603
+ expected: {
1604
+ position: [0, 2.4000000000000004, 0],
1605
+ rotationY: 0,
1606
+ surfaceId: 'shelves:3:board:top',
1607
+ childFrame: 'surface-local',
1608
+ surfaceLocal: {
1609
+ position: [0, -0, 0],
1610
+ rotationY: 0,
1611
+ rotation: [0, 0, 0],
1612
+ },
1613
+ },
1614
+ rejections: [],
1615
+ },
1616
+ {
1617
+ childKind: 'item',
1618
+ childFootprint: {
1619
+ size: [0.2, 1, 0.2],
1620
+ rotationY: 0.3,
1621
+ },
1622
+ hit: {
1623
+ point: [0.1, 2.4000000000000004, 0],
1624
+ normalWorldY: 1,
1625
+ },
1626
+ expected: {
1627
+ position: [0.1, 2.4000000000000004, 0],
1628
+ rotationY: 0.3,
1629
+ surfaceId: 'shelves:3:board:top',
1630
+ childFrame: 'surface-local',
1631
+ surfaceLocal: {
1632
+ position: [0.1, -0, 0],
1633
+ rotationY: 0.3,
1634
+ rotation: [0, 0.3, 0],
1635
+ },
1636
+ },
1637
+ rejections: [],
1638
+ },
1639
+ {
1640
+ childKind: 'item',
1641
+ childFootprint: {
1642
+ size: [0.2, 1, 0.6],
1643
+ rotationY: 1.5707963267948966,
1644
+ },
1645
+ hit: {
1646
+ point: [0, 2.4000000000000004, 0],
1647
+ normalWorldY: 1,
1648
+ },
1649
+ expected: {
1650
+ position: [0, 2.4000000000000004, 0],
1651
+ rotationY: 1.5707963267948966,
1652
+ surfaceId: 'shelves:3:board:top',
1653
+ childFrame: 'surface-local',
1654
+ surfaceLocal: {
1655
+ position: [0, -0, 0],
1656
+ rotationY: 1.5707963267948966,
1657
+ rotation: [0, 1.5707963267948966, 0],
1658
+ },
1659
+ },
1660
+ rejections: [],
1661
+ },
1662
+ {
1663
+ childKind: 'item',
1664
+ childFootprint: {
1665
+ size: [0.6, 1, 0.2],
1666
+ rotationY: 0.7853981633974483,
1667
+ },
1668
+ hit: {
1669
+ point: [0, 2.4000000000000004, 0],
1670
+ normalWorldY: 1,
1671
+ },
1672
+ expected: {
1673
+ position: [0, 2.4000000000000004, 0],
1674
+ rotationY: 0.7853981633974483,
1675
+ surfaceId: 'shelves:3:board:top',
1676
+ childFrame: 'surface-local',
1677
+ surfaceLocal: {
1678
+ position: [0, -0, 0],
1679
+ rotationY: 0.7853981633974483,
1680
+ rotation: [0, 0.7853981633974483, 0],
1681
+ },
1682
+ },
1683
+ rejections: [],
1684
+ },
1685
+ {
1686
+ childKind: 'item',
1687
+ childFootprint: {
1688
+ size: [0.4, 1, 0.2],
1689
+ rotationY: 0,
1690
+ },
1691
+ hit: {
1692
+ point: [0.5, 2.4000000000000004, 0],
1693
+ normalWorldY: 1,
1694
+ },
1695
+ expected: {
1696
+ position: [0.5, 2.4000000000000004, 0],
1697
+ rotationY: 0,
1698
+ surfaceId: 'shelves:3:board:top',
1699
+ childFrame: 'surface-local',
1700
+ surfaceLocal: {
1701
+ position: [0.5, -0, 0],
1702
+ rotationY: 0,
1703
+ rotation: [0, 0, 0],
1704
+ },
1705
+ },
1706
+ rejections: [],
1707
+ },
1708
+ {
1709
+ childKind: 'item',
1710
+ childFootprint: {
1711
+ size: [1.1400009999999998, 1, 0.4],
1712
+ rotationY: 0,
1713
+ },
1714
+ hit: {
1715
+ point: [0, 2.4000000000000004, 0],
1716
+ normalWorldY: 1,
1717
+ },
1718
+ expected: {
1719
+ position: [0, 2.4000000000000004, 0],
1720
+ rotationY: 0,
1721
+ surfaceId: 'shelves:3:board:top',
1722
+ childFrame: 'surface-local',
1723
+ surfaceLocal: {
1724
+ position: [0, -0, 0],
1725
+ rotationY: 0,
1726
+ rotation: [0, 0, 0],
1727
+ },
1728
+ },
1729
+ rejections: [],
1730
+ },
1731
+ {
1732
+ childKind: 'item',
1733
+ childFootprint: {
1734
+ size: [1.1400039999999998, 1, 0.4],
1735
+ rotationY: 0,
1736
+ },
1737
+ hit: {
1738
+ point: [0, 2.4000000000000004, 0],
1739
+ normalWorldY: 1,
1740
+ },
1741
+ expected: {
1742
+ position: [0, 2.4000000000000004, 0],
1743
+ rotationY: 0,
1744
+ surfaceId: 'shelves:3:board:top',
1745
+ childFrame: 'surface-local',
1746
+ surfaceLocal: {
1747
+ position: [0, -0, 0],
1748
+ rotationY: 0,
1749
+ rotation: [0, 0, 0],
1750
+ },
1751
+ },
1752
+ rejections: [],
1753
+ },
1754
+ ],
1755
+ label: 'shelf height 2.4: containment and tolerance',
1756
+ },
1757
+ {
1758
+ host: {
1759
+ object: 'node',
1760
+ id: 'procedural-item_frozen-2',
1761
+ type: 'procedural-item',
1762
+ parentId: 'shelf_outer',
1763
+ visible: true,
1764
+ metadata: {},
1765
+ recipe: {
1766
+ version: 1,
1767
+ name: 'Everyday shelf',
1768
+ description: 'An open timber bookcase with adjustable shelves and a contrasting back.',
1769
+ surfaces: [
1770
+ {
1771
+ id: 'ledge',
1772
+ label: 'Ledge',
1773
+ position: [2, 3, -1],
1774
+ rotation: [0, 0.6, 0],
1775
+ size: [1.5, 0.6],
1776
+ },
1777
+ ],
1778
+ parameters: [
1779
+ {
1780
+ id: 'width',
1781
+ label: 'Width',
1782
+ default: 1.2,
1783
+ min: 0.6,
1784
+ max: 2.4,
1785
+ step: 0.05,
1786
+ unit: 'm',
1787
+ axis: 'x',
1788
+ },
1789
+ {
1790
+ id: 'height',
1791
+ label: 'Height',
1792
+ default: 1.8,
1793
+ min: 0.8,
1794
+ max: 2.5,
1795
+ step: 0.05,
1796
+ unit: 'm',
1797
+ axis: 'y',
1798
+ },
1799
+ {
1800
+ id: 'depth',
1801
+ label: 'Depth',
1802
+ default: 0.4,
1803
+ min: 0.25,
1804
+ max: 0.7,
1805
+ step: 0.025,
1806
+ unit: 'm',
1807
+ axis: 'z',
1808
+ },
1809
+ {
1810
+ id: 'rows',
1811
+ label: 'Shelves',
1812
+ default: 4,
1813
+ min: 2,
1814
+ max: 7,
1815
+ step: 1,
1816
+ unit: 'count',
1817
+ part: 'shelves',
1818
+ },
1819
+ {
1820
+ id: 'thickness',
1821
+ label: 'Board thickness',
1822
+ default: 0.03,
1823
+ min: 0.015,
1824
+ max: 0.06,
1825
+ step: 0.005,
1826
+ unit: 'm',
1827
+ part: 'frame',
1828
+ },
1829
+ ],
1830
+ slots: [
1831
+ {
1832
+ id: 'frame',
1833
+ label: 'Frame',
1834
+ color: '#b58a60',
1835
+ },
1836
+ {
1837
+ id: 'shelves',
1838
+ label: 'Shelves',
1839
+ color: '#d5b38d',
1840
+ },
1841
+ {
1842
+ id: 'back',
1843
+ label: 'Back',
1844
+ color: '#495b50',
1845
+ },
1846
+ ],
1847
+ parts: [
1848
+ {
1849
+ id: 'frame',
1850
+ label: 'Frame',
1851
+ count: 2,
1852
+ shapes: [
1853
+ {
1854
+ id: 'side',
1855
+ primitive: 'box',
1856
+ slot: 'frame',
1857
+ size: ['thickness', 'height', 'depth'],
1858
+ position: [
1859
+ {
1860
+ op: 'mul',
1861
+ args: [
1862
+ {
1863
+ op: 'sub',
1864
+ args: ['index', 0.5],
1865
+ },
1866
+ {
1867
+ op: 'sub',
1868
+ args: ['width', 'thickness'],
1869
+ },
1870
+ ],
1871
+ },
1872
+ {
1873
+ op: 'div',
1874
+ args: ['height', 2],
1875
+ },
1876
+ 0,
1877
+ ],
1878
+ },
1879
+ ],
1880
+ },
1881
+ {
1882
+ id: 'shelves',
1883
+ label: 'Shelves',
1884
+ count: 'rows',
1885
+ shapes: [
1886
+ {
1887
+ id: 'board',
1888
+ primitive: 'box',
1889
+ slot: 'shelves',
1890
+ size: [
1891
+ {
1892
+ op: 'sub',
1893
+ args: [
1894
+ 'width',
1895
+ {
1896
+ op: 'mul',
1897
+ args: [2, 'thickness'],
1898
+ },
1899
+ ],
1900
+ },
1901
+ 'thickness',
1902
+ 'depth',
1903
+ ],
1904
+ position: [
1905
+ 0,
1906
+ {
1907
+ op: 'add',
1908
+ args: [
1909
+ {
1910
+ op: 'div',
1911
+ args: ['thickness', 2],
1912
+ },
1913
+ {
1914
+ op: 'mul',
1915
+ args: [
1916
+ 'index',
1917
+ {
1918
+ op: 'div',
1919
+ args: [
1920
+ {
1921
+ op: 'sub',
1922
+ args: ['height', 'thickness'],
1923
+ },
1924
+ {
1925
+ op: 'sub',
1926
+ args: ['rows', 1],
1927
+ },
1928
+ ],
1929
+ },
1930
+ ],
1931
+ },
1932
+ ],
1933
+ },
1934
+ 0,
1935
+ ],
1936
+ support: true,
1937
+ },
1938
+ ],
1939
+ },
1940
+ {
1941
+ id: 'back',
1942
+ label: 'Back panel',
1943
+ count: 1,
1944
+ shapes: [
1945
+ {
1946
+ id: 'panel',
1947
+ primitive: 'box',
1948
+ slot: 'back',
1949
+ size: [
1950
+ {
1951
+ op: 'sub',
1952
+ args: [
1953
+ 'width',
1954
+ {
1955
+ op: 'mul',
1956
+ args: [2, 'thickness'],
1957
+ },
1958
+ ],
1959
+ },
1960
+ 'height',
1961
+ 0.012,
1962
+ ],
1963
+ position: [
1964
+ 0,
1965
+ {
1966
+ op: 'div',
1967
+ args: ['height', 2],
1968
+ },
1969
+ {
1970
+ op: 'add',
1971
+ args: [
1972
+ {
1973
+ op: 'div',
1974
+ args: ['depth', -2],
1975
+ },
1976
+ 0.006,
1977
+ ],
1978
+ },
1979
+ ],
1980
+ },
1981
+ ],
1982
+ },
1983
+ ],
1984
+ constraints: [],
1985
+ },
1986
+ parameters: {},
1987
+ slots: {},
1988
+ position: [8, 2, 7],
1989
+ rotation: [0, 1, 0],
1990
+ children: [],
1991
+ attachments: {},
1992
+ },
1993
+ rows: [
1994
+ {
1995
+ childKind: 'plugin-child',
1996
+ childFootprint: {
1997
+ size: [0.4, 1, 0.2],
1998
+ rotationY: 0.6,
1999
+ },
2000
+ hit: {
2001
+ point: [2.1932992466516876, 3, -1.0716617139335232],
2002
+ normalWorldY: 1,
2003
+ },
2004
+ expected: {
2005
+ position: [2.1932992466516876, 3, -1.0716617139335232],
2006
+ rotationY: 0.6,
2007
+ surfaceId: 'ledge',
2008
+ childFrame: 'surface-local',
2009
+ surfaceLocal: {
2010
+ position: [0.20000000000000018, -0, 0.05000000000000011],
2011
+ rotationY: 0,
2012
+ rotation: [0, 0, 0],
2013
+ },
2014
+ },
2015
+ rejections: [],
2016
+ },
2017
+ {
2018
+ childKind: 'item',
2019
+ childFootprint: {
2020
+ size: [0.5, 1, 0.5],
2021
+ rotationY: 0,
2022
+ },
2023
+ hit: {
2024
+ point: [20, 3, 20],
2025
+ normalWorldY: 1,
2026
+ },
2027
+ expected: null,
2028
+ rejections: ['no-surface'],
2029
+ },
2030
+ ],
2031
+ label: 'offset yawed ledge: free placement and outside hit',
2032
+ },
2033
+ {
2034
+ host: {
2035
+ object: 'node',
2036
+ id: 'procedural-item_frozen-3',
2037
+ type: 'procedural-item',
2038
+ parentId: null,
2039
+ visible: true,
2040
+ metadata: {},
2041
+ recipe: {
2042
+ version: 1,
2043
+ name: 'Everyday shelf',
2044
+ description: 'An open timber bookcase with adjustable shelves and a contrasting back.',
2045
+ surfaces: [
2046
+ {
2047
+ id: 'ledge',
2048
+ label: 'Ledge',
2049
+ position: [2, 3, -1],
2050
+ rotation: [0, 0.6, 0],
2051
+ size: [1.5, 0.6],
2052
+ },
2053
+ ],
2054
+ parameters: [
2055
+ {
2056
+ id: 'width',
2057
+ label: 'Width',
2058
+ default: 1.2,
2059
+ min: 0.6,
2060
+ max: 2.4,
2061
+ step: 0.05,
2062
+ unit: 'm',
2063
+ axis: 'x',
2064
+ },
2065
+ {
2066
+ id: 'height',
2067
+ label: 'Height',
2068
+ default: 1.8,
2069
+ min: 0.8,
2070
+ max: 2.5,
2071
+ step: 0.05,
2072
+ unit: 'm',
2073
+ axis: 'y',
2074
+ },
2075
+ {
2076
+ id: 'depth',
2077
+ label: 'Depth',
2078
+ default: 0.4,
2079
+ min: 0.25,
2080
+ max: 0.7,
2081
+ step: 0.025,
2082
+ unit: 'm',
2083
+ axis: 'z',
2084
+ },
2085
+ {
2086
+ id: 'rows',
2087
+ label: 'Shelves',
2088
+ default: 4,
2089
+ min: 2,
2090
+ max: 7,
2091
+ step: 1,
2092
+ unit: 'count',
2093
+ part: 'shelves',
2094
+ },
2095
+ {
2096
+ id: 'thickness',
2097
+ label: 'Board thickness',
2098
+ default: 0.03,
2099
+ min: 0.015,
2100
+ max: 0.06,
2101
+ step: 0.005,
2102
+ unit: 'm',
2103
+ part: 'frame',
2104
+ },
2105
+ ],
2106
+ slots: [
2107
+ {
2108
+ id: 'frame',
2109
+ label: 'Frame',
2110
+ color: '#b58a60',
2111
+ },
2112
+ {
2113
+ id: 'shelves',
2114
+ label: 'Shelves',
2115
+ color: '#d5b38d',
2116
+ },
2117
+ {
2118
+ id: 'back',
2119
+ label: 'Back',
2120
+ color: '#495b50',
2121
+ },
2122
+ ],
2123
+ parts: [
2124
+ {
2125
+ id: 'frame',
2126
+ label: 'Frame',
2127
+ count: 2,
2128
+ shapes: [
2129
+ {
2130
+ id: 'side',
2131
+ primitive: 'box',
2132
+ slot: 'frame',
2133
+ size: ['thickness', 'height', 'depth'],
2134
+ position: [
2135
+ {
2136
+ op: 'mul',
2137
+ args: [
2138
+ {
2139
+ op: 'sub',
2140
+ args: ['index', 0.5],
2141
+ },
2142
+ {
2143
+ op: 'sub',
2144
+ args: ['width', 'thickness'],
2145
+ },
2146
+ ],
2147
+ },
2148
+ {
2149
+ op: 'div',
2150
+ args: ['height', 2],
2151
+ },
2152
+ 0,
2153
+ ],
2154
+ },
2155
+ ],
2156
+ },
2157
+ {
2158
+ id: 'shelves',
2159
+ label: 'Shelves',
2160
+ count: 'rows',
2161
+ shapes: [
2162
+ {
2163
+ id: 'board',
2164
+ primitive: 'box',
2165
+ slot: 'shelves',
2166
+ size: [
2167
+ {
2168
+ op: 'sub',
2169
+ args: [
2170
+ 'width',
2171
+ {
2172
+ op: 'mul',
2173
+ args: [2, 'thickness'],
2174
+ },
2175
+ ],
2176
+ },
2177
+ 'thickness',
2178
+ 'depth',
2179
+ ],
2180
+ position: [
2181
+ 0,
2182
+ {
2183
+ op: 'add',
2184
+ args: [
2185
+ {
2186
+ op: 'div',
2187
+ args: ['thickness', 2],
2188
+ },
2189
+ {
2190
+ op: 'mul',
2191
+ args: [
2192
+ 'index',
2193
+ {
2194
+ op: 'div',
2195
+ args: [
2196
+ {
2197
+ op: 'sub',
2198
+ args: ['height', 'thickness'],
2199
+ },
2200
+ {
2201
+ op: 'sub',
2202
+ args: ['rows', 1],
2203
+ },
2204
+ ],
2205
+ },
2206
+ ],
2207
+ },
2208
+ ],
2209
+ },
2210
+ 0,
2211
+ ],
2212
+ support: true,
2213
+ },
2214
+ ],
2215
+ },
2216
+ {
2217
+ id: 'back',
2218
+ label: 'Back panel',
2219
+ count: 1,
2220
+ shapes: [
2221
+ {
2222
+ id: 'panel',
2223
+ primitive: 'box',
2224
+ slot: 'back',
2225
+ size: [
2226
+ {
2227
+ op: 'sub',
2228
+ args: [
2229
+ 'width',
2230
+ {
2231
+ op: 'mul',
2232
+ args: [2, 'thickness'],
2233
+ },
2234
+ ],
2235
+ },
2236
+ 'height',
2237
+ 0.012,
2238
+ ],
2239
+ position: [
2240
+ 0,
2241
+ {
2242
+ op: 'div',
2243
+ args: ['height', 2],
2244
+ },
2245
+ {
2246
+ op: 'add',
2247
+ args: [
2248
+ {
2249
+ op: 'div',
2250
+ args: ['depth', -2],
2251
+ },
2252
+ 0.006,
2253
+ ],
2254
+ },
2255
+ ],
2256
+ },
2257
+ ],
2258
+ },
2259
+ ],
2260
+ constraints: [],
2261
+ },
2262
+ parameters: {},
2263
+ slots: {},
2264
+ position: [8, 2, 7],
2265
+ rotation: [0.1, 1, -0.15],
2266
+ children: [],
2267
+ attachments: {},
2268
+ },
2269
+ rows: [
2270
+ {
2271
+ childKind: 'item',
2272
+ childFootprint: {
2273
+ size: [0.2, 0.1, 0.2],
2274
+ rotationY: 0.6,
2275
+ },
2276
+ hit: {
2277
+ point: [2.539507643010095, 3, -1.344864470674629],
2278
+ normalWorldY: 1,
2279
+ },
2280
+ expected: {
2281
+ position: [2.539507643010095, 3, -1.344864470674629],
2282
+ rotationY: 0.6,
2283
+ surfaceId: 'ledge',
2284
+ childFrame: 'surface-local',
2285
+ surfaceLocal: {
2286
+ position: [0.6400000000000001, -0, 0.020000000000000018],
2287
+ rotationY: 0,
2288
+ rotation: [0, 0, 0],
2289
+ },
2290
+ },
2291
+ rejections: [],
2292
+ },
2293
+ {
2294
+ childKind: 'item',
2295
+ childFootprint: {
2296
+ size: [0.2, 0.1, 0.2],
2297
+ rotationY: 0.6,
2298
+ },
2299
+ hit: {
2300
+ point: [2.5560143553082884, 3, -1.3561573201425299],
2301
+ normalWorldY: 1,
2302
+ },
2303
+ expected: {
2304
+ position: [2.5560143553082884, 3, -1.3561573201425299],
2305
+ rotationY: 0.6,
2306
+ surfaceId: 'ledge',
2307
+ childFrame: 'surface-local',
2308
+ surfaceLocal: {
2309
+ position: [0.66, -0, 0.019999999999999907],
2310
+ rotationY: 0,
2311
+ rotation: [0, 0, 0],
2312
+ },
2313
+ },
2314
+ rejections: [],
2315
+ },
2316
+ {
2317
+ childKind: 'item',
2318
+ childFootprint: {
2319
+ size: [0.2, 0.1, 0.2],
2320
+ rotationY: 0.6,
2321
+ },
2322
+ hit: {
2323
+ point: [2.5560143553082884, 3, -1.3561573201425299],
2324
+ normalWorldY: 1,
2325
+ },
2326
+ checkFootprint: false,
2327
+ expected: {
2328
+ position: [2.5560143553082884, 3, -1.3561573201425299],
2329
+ rotationY: 0.6,
2330
+ surfaceId: 'ledge',
2331
+ childFrame: 'surface-local',
2332
+ surfaceLocal: {
2333
+ position: [0.66, -0, 0.019999999999999907],
2334
+ rotationY: 0,
2335
+ rotation: [0, 0, 0],
2336
+ },
2337
+ },
2338
+ rejections: [],
2339
+ },
2340
+ ],
2341
+ label: 'offset ledge: inverse point at edge and overhang',
2342
+ },
2343
+ {
2344
+ host: {
2345
+ object: 'node',
2346
+ id: 'procedural-item_frozen-4',
2347
+ type: 'procedural-item',
2348
+ parentId: null,
2349
+ visible: true,
2350
+ metadata: {},
2351
+ recipe: {
2352
+ version: 1,
2353
+ name: 'Everyday shelf',
2354
+ description: 'An open timber bookcase with adjustable shelves and a contrasting back.',
2355
+ surfaces: [
2356
+ {
2357
+ id: 'ledge',
2358
+ label: 'Ledge',
2359
+ position: [2, 3, -1],
2360
+ rotation: [0, 0.6, 0],
2361
+ size: [1.5, 0.6],
2362
+ },
2363
+ ],
2364
+ parameters: [
2365
+ {
2366
+ id: 'width',
2367
+ label: 'Width',
2368
+ default: 1.2,
2369
+ min: 0.6,
2370
+ max: 2.4,
2371
+ step: 0.05,
2372
+ unit: 'm',
2373
+ axis: 'x',
2374
+ },
2375
+ {
2376
+ id: 'height',
2377
+ label: 'Height',
2378
+ default: 1.8,
2379
+ min: 0.8,
2380
+ max: 2.5,
2381
+ step: 0.05,
2382
+ unit: 'm',
2383
+ axis: 'y',
2384
+ },
2385
+ {
2386
+ id: 'depth',
2387
+ label: 'Depth',
2388
+ default: 0.4,
2389
+ min: 0.25,
2390
+ max: 0.7,
2391
+ step: 0.025,
2392
+ unit: 'm',
2393
+ axis: 'z',
2394
+ },
2395
+ {
2396
+ id: 'rows',
2397
+ label: 'Shelves',
2398
+ default: 4,
2399
+ min: 2,
2400
+ max: 7,
2401
+ step: 1,
2402
+ unit: 'count',
2403
+ part: 'shelves',
2404
+ },
2405
+ {
2406
+ id: 'thickness',
2407
+ label: 'Board thickness',
2408
+ default: 0.03,
2409
+ min: 0.015,
2410
+ max: 0.06,
2411
+ step: 0.005,
2412
+ unit: 'm',
2413
+ part: 'frame',
2414
+ },
2415
+ ],
2416
+ slots: [
2417
+ {
2418
+ id: 'frame',
2419
+ label: 'Frame',
2420
+ color: '#b58a60',
2421
+ },
2422
+ {
2423
+ id: 'shelves',
2424
+ label: 'Shelves',
2425
+ color: '#d5b38d',
2426
+ },
2427
+ {
2428
+ id: 'back',
2429
+ label: 'Back',
2430
+ color: '#495b50',
2431
+ },
2432
+ ],
2433
+ parts: [
2434
+ {
2435
+ id: 'frame',
2436
+ label: 'Frame',
2437
+ count: 2,
2438
+ shapes: [
2439
+ {
2440
+ id: 'side',
2441
+ primitive: 'box',
2442
+ slot: 'frame',
2443
+ size: ['thickness', 'height', 'depth'],
2444
+ position: [
2445
+ {
2446
+ op: 'mul',
2447
+ args: [
2448
+ {
2449
+ op: 'sub',
2450
+ args: ['index', 0.5],
2451
+ },
2452
+ {
2453
+ op: 'sub',
2454
+ args: ['width', 'thickness'],
2455
+ },
2456
+ ],
2457
+ },
2458
+ {
2459
+ op: 'div',
2460
+ args: ['height', 2],
2461
+ },
2462
+ 0,
2463
+ ],
2464
+ },
2465
+ ],
2466
+ },
2467
+ {
2468
+ id: 'shelves',
2469
+ label: 'Shelves',
2470
+ count: 'rows',
2471
+ shapes: [
2472
+ {
2473
+ id: 'board',
2474
+ primitive: 'box',
2475
+ slot: 'shelves',
2476
+ size: [
2477
+ {
2478
+ op: 'sub',
2479
+ args: [
2480
+ 'width',
2481
+ {
2482
+ op: 'mul',
2483
+ args: [2, 'thickness'],
2484
+ },
2485
+ ],
2486
+ },
2487
+ 'thickness',
2488
+ 'depth',
2489
+ ],
2490
+ position: [
2491
+ 0,
2492
+ {
2493
+ op: 'add',
2494
+ args: [
2495
+ {
2496
+ op: 'div',
2497
+ args: ['thickness', 2],
2498
+ },
2499
+ {
2500
+ op: 'mul',
2501
+ args: [
2502
+ 'index',
2503
+ {
2504
+ op: 'div',
2505
+ args: [
2506
+ {
2507
+ op: 'sub',
2508
+ args: ['height', 'thickness'],
2509
+ },
2510
+ {
2511
+ op: 'sub',
2512
+ args: ['rows', 1],
2513
+ },
2514
+ ],
2515
+ },
2516
+ ],
2517
+ },
2518
+ ],
2519
+ },
2520
+ 0,
2521
+ ],
2522
+ support: true,
2523
+ },
2524
+ ],
2525
+ },
2526
+ {
2527
+ id: 'back',
2528
+ label: 'Back panel',
2529
+ count: 1,
2530
+ shapes: [
2531
+ {
2532
+ id: 'panel',
2533
+ primitive: 'box',
2534
+ slot: 'back',
2535
+ size: [
2536
+ {
2537
+ op: 'sub',
2538
+ args: [
2539
+ 'width',
2540
+ {
2541
+ op: 'mul',
2542
+ args: [2, 'thickness'],
2543
+ },
2544
+ ],
2545
+ },
2546
+ 'height',
2547
+ 0.012,
2548
+ ],
2549
+ position: [
2550
+ 0,
2551
+ {
2552
+ op: 'div',
2553
+ args: ['height', 2],
2554
+ },
2555
+ {
2556
+ op: 'add',
2557
+ args: [
2558
+ {
2559
+ op: 'div',
2560
+ args: ['depth', -2],
2561
+ },
2562
+ 0.006,
2563
+ ],
2564
+ },
2565
+ ],
2566
+ },
2567
+ ],
2568
+ },
2569
+ ],
2570
+ constraints: [],
2571
+ },
2572
+ parameters: {},
2573
+ slots: {},
2574
+ position: [8, 2, 7],
2575
+ rotation: [0.1, 1, -0.15],
2576
+ children: [],
2577
+ attachments: {},
2578
+ },
2579
+ rows: [
2580
+ {
2581
+ childKind: 'item',
2582
+ childFootprint: {
2583
+ size: [0.8, 0.1, 0.2],
2584
+ rotationY: 0.6,
2585
+ },
2586
+ hit: {
2587
+ point: [2.365310480078546, 3, -1.0681780987178604],
2588
+ normalWorldY: 1,
2589
+ },
2590
+ expected: {
2591
+ position: [2.365310480078546, 3, -1.0681780987178604],
2592
+ rotationY: 0.6,
2593
+ surfaceId: 'ledge',
2594
+ childFrame: 'surface-local',
2595
+ surfaceLocal: {
2596
+ position: [0.33999999999999997, -0, 0.14999999999999986],
2597
+ rotationY: 0,
2598
+ rotation: [0, 0, 0],
2599
+ },
2600
+ },
2601
+ rejections: [],
2602
+ },
2603
+ {
2604
+ childKind: 'item',
2605
+ childFootprint: {
2606
+ size: [0.8, 0.1, 0.2],
2607
+ rotationY: 0.6,
2608
+ },
2609
+ hit: {
2610
+ point: [2.3818171923767393, 3, -1.079470948185761],
2611
+ normalWorldY: 1,
2612
+ },
2613
+ expected: {
2614
+ position: [2.3818171923767393, 3, -1.079470948185761],
2615
+ rotationY: 0.6,
2616
+ surfaceId: 'ledge',
2617
+ childFrame: 'surface-local',
2618
+ surfaceLocal: {
2619
+ position: [0.3599999999999998, -0, 0.1499999999999999],
2620
+ rotationY: 0,
2621
+ rotation: [0, 0, 0],
2622
+ },
2623
+ },
2624
+ rejections: [],
2625
+ },
2626
+ {
2627
+ childKind: 'item',
2628
+ childFootprint: {
2629
+ size: [0.8, 0.1, 0.2],
2630
+ rotationY: 0.6,
2631
+ },
2632
+ hit: {
2633
+ point: [2.3818171923767393, 3, -1.079470948185761],
2634
+ normalWorldY: 1,
2635
+ },
2636
+ checkFootprint: false,
2637
+ expected: {
2638
+ position: [2.3818171923767393, 3, -1.079470948185761],
2639
+ rotationY: 0.6,
2640
+ surfaceId: 'ledge',
2641
+ childFrame: 'surface-local',
2642
+ surfaceLocal: {
2643
+ position: [0.3599999999999998, -0, 0.1499999999999999],
2644
+ rotationY: 0,
2645
+ rotation: [0, 0, 0],
2646
+ },
2647
+ },
2648
+ rejections: [],
2649
+ },
2650
+ ],
2651
+ label: 'yawed ledge: rotated footprint at edge and overhang',
2652
+ },
2653
+ {
2654
+ host: {
2655
+ object: 'node',
2656
+ id: 'procedural-item_frozen-5',
2657
+ type: 'procedural-item',
2658
+ parentId: null,
2659
+ visible: true,
2660
+ metadata: {},
2661
+ recipe: {
2662
+ version: 1,
2663
+ name: 'Everyday shelf',
2664
+ description: 'An open timber bookcase with adjustable shelves and a contrasting back.',
2665
+ surfaces: [
2666
+ {
2667
+ id: 'ledge',
2668
+ label: 'Ledge',
2669
+ position: [2, 3, -1],
2670
+ rotation: [0.3, 0.6, 0.2],
2671
+ size: [1.5, 0.6],
2672
+ },
2673
+ ],
2674
+ parameters: [
2675
+ {
2676
+ id: 'width',
2677
+ label: 'Width',
2678
+ default: 1.2,
2679
+ min: 0.6,
2680
+ max: 2.4,
2681
+ step: 0.05,
2682
+ unit: 'm',
2683
+ axis: 'x',
2684
+ },
2685
+ {
2686
+ id: 'height',
2687
+ label: 'Height',
2688
+ default: 1.8,
2689
+ min: 0.8,
2690
+ max: 2.5,
2691
+ step: 0.05,
2692
+ unit: 'm',
2693
+ axis: 'y',
2694
+ },
2695
+ {
2696
+ id: 'depth',
2697
+ label: 'Depth',
2698
+ default: 0.4,
2699
+ min: 0.25,
2700
+ max: 0.7,
2701
+ step: 0.025,
2702
+ unit: 'm',
2703
+ axis: 'z',
2704
+ },
2705
+ {
2706
+ id: 'rows',
2707
+ label: 'Shelves',
2708
+ default: 4,
2709
+ min: 2,
2710
+ max: 7,
2711
+ step: 1,
2712
+ unit: 'count',
2713
+ part: 'shelves',
2714
+ },
2715
+ {
2716
+ id: 'thickness',
2717
+ label: 'Board thickness',
2718
+ default: 0.03,
2719
+ min: 0.015,
2720
+ max: 0.06,
2721
+ step: 0.005,
2722
+ unit: 'm',
2723
+ part: 'frame',
2724
+ },
2725
+ ],
2726
+ slots: [
2727
+ {
2728
+ id: 'frame',
2729
+ label: 'Frame',
2730
+ color: '#b58a60',
2731
+ },
2732
+ {
2733
+ id: 'shelves',
2734
+ label: 'Shelves',
2735
+ color: '#d5b38d',
2736
+ },
2737
+ {
2738
+ id: 'back',
2739
+ label: 'Back',
2740
+ color: '#495b50',
2741
+ },
2742
+ ],
2743
+ parts: [
2744
+ {
2745
+ id: 'frame',
2746
+ label: 'Frame',
2747
+ count: 2,
2748
+ shapes: [
2749
+ {
2750
+ id: 'side',
2751
+ primitive: 'box',
2752
+ slot: 'frame',
2753
+ size: ['thickness', 'height', 'depth'],
2754
+ position: [
2755
+ {
2756
+ op: 'mul',
2757
+ args: [
2758
+ {
2759
+ op: 'sub',
2760
+ args: ['index', 0.5],
2761
+ },
2762
+ {
2763
+ op: 'sub',
2764
+ args: ['width', 'thickness'],
2765
+ },
2766
+ ],
2767
+ },
2768
+ {
2769
+ op: 'div',
2770
+ args: ['height', 2],
2771
+ },
2772
+ 0,
2773
+ ],
2774
+ },
2775
+ ],
2776
+ },
2777
+ {
2778
+ id: 'shelves',
2779
+ label: 'Shelves',
2780
+ count: 'rows',
2781
+ shapes: [
2782
+ {
2783
+ id: 'board',
2784
+ primitive: 'box',
2785
+ slot: 'shelves',
2786
+ size: [
2787
+ {
2788
+ op: 'sub',
2789
+ args: [
2790
+ 'width',
2791
+ {
2792
+ op: 'mul',
2793
+ args: [2, 'thickness'],
2794
+ },
2795
+ ],
2796
+ },
2797
+ 'thickness',
2798
+ 'depth',
2799
+ ],
2800
+ position: [
2801
+ 0,
2802
+ {
2803
+ op: 'add',
2804
+ args: [
2805
+ {
2806
+ op: 'div',
2807
+ args: ['thickness', 2],
2808
+ },
2809
+ {
2810
+ op: 'mul',
2811
+ args: [
2812
+ 'index',
2813
+ {
2814
+ op: 'div',
2815
+ args: [
2816
+ {
2817
+ op: 'sub',
2818
+ args: ['height', 'thickness'],
2819
+ },
2820
+ {
2821
+ op: 'sub',
2822
+ args: ['rows', 1],
2823
+ },
2824
+ ],
2825
+ },
2826
+ ],
2827
+ },
2828
+ ],
2829
+ },
2830
+ 0,
2831
+ ],
2832
+ support: true,
2833
+ },
2834
+ ],
2835
+ },
2836
+ {
2837
+ id: 'back',
2838
+ label: 'Back panel',
2839
+ count: 1,
2840
+ shapes: [
2841
+ {
2842
+ id: 'panel',
2843
+ primitive: 'box',
2844
+ slot: 'back',
2845
+ size: [
2846
+ {
2847
+ op: 'sub',
2848
+ args: [
2849
+ 'width',
2850
+ {
2851
+ op: 'mul',
2852
+ args: [2, 'thickness'],
2853
+ },
2854
+ ],
2855
+ },
2856
+ 'height',
2857
+ 0.012,
2858
+ ],
2859
+ position: [
2860
+ 0,
2861
+ {
2862
+ op: 'div',
2863
+ args: ['height', 2],
2864
+ },
2865
+ {
2866
+ op: 'add',
2867
+ args: [
2868
+ {
2869
+ op: 'div',
2870
+ args: ['depth', -2],
2871
+ },
2872
+ 0.006,
2873
+ ],
2874
+ },
2875
+ ],
2876
+ },
2877
+ ],
2878
+ },
2879
+ ],
2880
+ constraints: [],
2881
+ },
2882
+ parameters: {},
2883
+ slots: {},
2884
+ position: [8, 2, 7],
2885
+ rotation: [0.1, 1, -0.15],
2886
+ children: [],
2887
+ attachments: {},
2888
+ },
2889
+ rows: [
2890
+ {
2891
+ childKind: 'item',
2892
+ childFootprint: {
2893
+ size: [0.2, 0.1, 0.2],
2894
+ rotationY: 0.6,
2895
+ rotation: [0.3, 0.6, 0.2],
2896
+ },
2897
+ hit: {
2898
+ point: [2.1091205088372544, 3.0231381489851734, -1.0075723584594645],
2899
+ normalWorldY: 0.9031427513007916,
2900
+ },
2901
+ expected: {
2902
+ position: [2.1091205088372544, 3.0231381489851734, -1.0075723584594645],
2903
+ rotationY: 0.6,
2904
+ surfaceId: 'ledge',
2905
+ childFrame: 'surface-local',
2906
+ surfaceLocal: {
2907
+ position: [0.10000000000000009, -0, 0.05000000000000014],
2908
+ rotationY: 1.1102230246251565e-16,
2909
+ rotation: [-0, 1.1102230246251565e-16, -0],
2910
+ },
2911
+ },
2912
+ rejections: [],
2913
+ },
2914
+ ],
2915
+ label: 'tilted ledge: positive pitch',
2916
+ },
2917
+ {
2918
+ host: {
2919
+ object: 'node',
2920
+ id: 'procedural-item_frozen-6',
2921
+ type: 'procedural-item',
2922
+ parentId: null,
2923
+ visible: true,
2924
+ metadata: {},
2925
+ recipe: {
2926
+ version: 1,
2927
+ name: 'Everyday shelf',
2928
+ description: 'An open timber bookcase with adjustable shelves and a contrasting back.',
2929
+ surfaces: [
2930
+ {
2931
+ id: 'ledge',
2932
+ label: 'Ledge',
2933
+ position: [2, 3, -1],
2934
+ rotation: [-0.35, -0.7, 0.25],
2935
+ size: [1.5, 0.6],
2936
+ },
2937
+ ],
2938
+ parameters: [
2939
+ {
2940
+ id: 'width',
2941
+ label: 'Width',
2942
+ default: 1.2,
2943
+ min: 0.6,
2944
+ max: 2.4,
2945
+ step: 0.05,
2946
+ unit: 'm',
2947
+ axis: 'x',
2948
+ },
2949
+ {
2950
+ id: 'height',
2951
+ label: 'Height',
2952
+ default: 1.8,
2953
+ min: 0.8,
2954
+ max: 2.5,
2955
+ step: 0.05,
2956
+ unit: 'm',
2957
+ axis: 'y',
2958
+ },
2959
+ {
2960
+ id: 'depth',
2961
+ label: 'Depth',
2962
+ default: 0.4,
2963
+ min: 0.25,
2964
+ max: 0.7,
2965
+ step: 0.025,
2966
+ unit: 'm',
2967
+ axis: 'z',
2968
+ },
2969
+ {
2970
+ id: 'rows',
2971
+ label: 'Shelves',
2972
+ default: 4,
2973
+ min: 2,
2974
+ max: 7,
2975
+ step: 1,
2976
+ unit: 'count',
2977
+ part: 'shelves',
2978
+ },
2979
+ {
2980
+ id: 'thickness',
2981
+ label: 'Board thickness',
2982
+ default: 0.03,
2983
+ min: 0.015,
2984
+ max: 0.06,
2985
+ step: 0.005,
2986
+ unit: 'm',
2987
+ part: 'frame',
2988
+ },
2989
+ ],
2990
+ slots: [
2991
+ {
2992
+ id: 'frame',
2993
+ label: 'Frame',
2994
+ color: '#b58a60',
2995
+ },
2996
+ {
2997
+ id: 'shelves',
2998
+ label: 'Shelves',
2999
+ color: '#d5b38d',
3000
+ },
3001
+ {
3002
+ id: 'back',
3003
+ label: 'Back',
3004
+ color: '#495b50',
3005
+ },
3006
+ ],
3007
+ parts: [
3008
+ {
3009
+ id: 'frame',
3010
+ label: 'Frame',
3011
+ count: 2,
3012
+ shapes: [
3013
+ {
3014
+ id: 'side',
3015
+ primitive: 'box',
3016
+ slot: 'frame',
3017
+ size: ['thickness', 'height', 'depth'],
3018
+ position: [
3019
+ {
3020
+ op: 'mul',
3021
+ args: [
3022
+ {
3023
+ op: 'sub',
3024
+ args: ['index', 0.5],
3025
+ },
3026
+ {
3027
+ op: 'sub',
3028
+ args: ['width', 'thickness'],
3029
+ },
3030
+ ],
3031
+ },
3032
+ {
3033
+ op: 'div',
3034
+ args: ['height', 2],
3035
+ },
3036
+ 0,
3037
+ ],
3038
+ },
3039
+ ],
3040
+ },
3041
+ {
3042
+ id: 'shelves',
3043
+ label: 'Shelves',
3044
+ count: 'rows',
3045
+ shapes: [
3046
+ {
3047
+ id: 'board',
3048
+ primitive: 'box',
3049
+ slot: 'shelves',
3050
+ size: [
3051
+ {
3052
+ op: 'sub',
3053
+ args: [
3054
+ 'width',
3055
+ {
3056
+ op: 'mul',
3057
+ args: [2, 'thickness'],
3058
+ },
3059
+ ],
3060
+ },
3061
+ 'thickness',
3062
+ 'depth',
3063
+ ],
3064
+ position: [
3065
+ 0,
3066
+ {
3067
+ op: 'add',
3068
+ args: [
3069
+ {
3070
+ op: 'div',
3071
+ args: ['thickness', 2],
3072
+ },
3073
+ {
3074
+ op: 'mul',
3075
+ args: [
3076
+ 'index',
3077
+ {
3078
+ op: 'div',
3079
+ args: [
3080
+ {
3081
+ op: 'sub',
3082
+ args: ['height', 'thickness'],
3083
+ },
3084
+ {
3085
+ op: 'sub',
3086
+ args: ['rows', 1],
3087
+ },
3088
+ ],
3089
+ },
3090
+ ],
3091
+ },
3092
+ ],
3093
+ },
3094
+ 0,
3095
+ ],
3096
+ support: true,
3097
+ },
3098
+ ],
3099
+ },
3100
+ {
3101
+ id: 'back',
3102
+ label: 'Back panel',
3103
+ count: 1,
3104
+ shapes: [
3105
+ {
3106
+ id: 'panel',
3107
+ primitive: 'box',
3108
+ slot: 'back',
3109
+ size: [
3110
+ {
3111
+ op: 'sub',
3112
+ args: [
3113
+ 'width',
3114
+ {
3115
+ op: 'mul',
3116
+ args: [2, 'thickness'],
3117
+ },
3118
+ ],
3119
+ },
3120
+ 'height',
3121
+ 0.012,
3122
+ ],
3123
+ position: [
3124
+ 0,
3125
+ {
3126
+ op: 'div',
3127
+ args: ['height', 2],
3128
+ },
3129
+ {
3130
+ op: 'add',
3131
+ args: [
3132
+ {
3133
+ op: 'div',
3134
+ args: ['depth', -2],
3135
+ },
3136
+ 0.006,
3137
+ ],
3138
+ },
3139
+ ],
3140
+ },
3141
+ ],
3142
+ },
3143
+ ],
3144
+ constraints: [],
3145
+ },
3146
+ parameters: {},
3147
+ slots: {},
3148
+ position: [8, 2, 7],
3149
+ rotation: [0.1, 1, -0.15],
3150
+ children: [],
3151
+ attachments: {},
3152
+ },
3153
+ rows: [
3154
+ {
3155
+ childKind: 'item',
3156
+ childFootprint: {
3157
+ size: [0.2, 0.1, 0.2],
3158
+ rotationY: -0.7,
3159
+ rotation: [-0.35, -0.7, 0.25],
3160
+ },
3161
+ hit: {
3162
+ point: [2.0418956252289435, 3.057756944346273, -0.9139250793409752],
3163
+ normalWorldY: 0.8555181495362177,
3164
+ },
3165
+ expected: {
3166
+ position: [2.0418956252289435, 3.057756944346273, -0.9139250793409752],
3167
+ rotationY: -0.7,
3168
+ surfaceId: 'ledge',
3169
+ childFrame: 'surface-local',
3170
+ surfaceLocal: {
3171
+ position: [0.09999999999999996, 5.551115123125783e-18, 0.04999999999999994],
3172
+ rotationY: 5.551115123125783e-17,
3173
+ rotation: [-0, 5.551115123125783e-17, -5.551115123125783e-17],
3174
+ },
3175
+ },
3176
+ rejections: [],
3177
+ },
3178
+ ],
3179
+ label: 'tilted ledge: negative pitch',
3180
+ },
3181
+ {
3182
+ host: {
3183
+ object: 'node',
3184
+ id: 'procedural-item_frozen-7',
3185
+ type: 'procedural-item',
3186
+ parentId: null,
3187
+ visible: true,
3188
+ metadata: {},
3189
+ recipe: {
3190
+ version: 1,
3191
+ name: 'Everyday shelf',
3192
+ description: 'An open timber bookcase with adjustable shelves and a contrasting back.',
3193
+ surfaces: [
3194
+ {
3195
+ id: 'ledge',
3196
+ label: 'Ledge',
3197
+ position: [2, 3, -1],
3198
+ rotation: [0, 1.5707963267948966, 0],
3199
+ size: [1.5, 0.6],
3200
+ },
3201
+ ],
3202
+ parameters: [
3203
+ {
3204
+ id: 'width',
3205
+ label: 'Width',
3206
+ default: 1.2,
3207
+ min: 0.6,
3208
+ max: 2.4,
3209
+ step: 0.05,
3210
+ unit: 'm',
3211
+ axis: 'x',
3212
+ },
3213
+ {
3214
+ id: 'height',
3215
+ label: 'Height',
3216
+ default: 1.8,
3217
+ min: 0.8,
3218
+ max: 2.5,
3219
+ step: 0.05,
3220
+ unit: 'm',
3221
+ axis: 'y',
3222
+ },
3223
+ {
3224
+ id: 'depth',
3225
+ label: 'Depth',
3226
+ default: 0.4,
3227
+ min: 0.25,
3228
+ max: 0.7,
3229
+ step: 0.025,
3230
+ unit: 'm',
3231
+ axis: 'z',
3232
+ },
3233
+ {
3234
+ id: 'rows',
3235
+ label: 'Shelves',
3236
+ default: 4,
3237
+ min: 2,
3238
+ max: 7,
3239
+ step: 1,
3240
+ unit: 'count',
3241
+ part: 'shelves',
3242
+ },
3243
+ {
3244
+ id: 'thickness',
3245
+ label: 'Board thickness',
3246
+ default: 0.03,
3247
+ min: 0.015,
3248
+ max: 0.06,
3249
+ step: 0.005,
3250
+ unit: 'm',
3251
+ part: 'frame',
3252
+ },
3253
+ ],
3254
+ slots: [
3255
+ {
3256
+ id: 'frame',
3257
+ label: 'Frame',
3258
+ color: '#b58a60',
3259
+ },
3260
+ {
3261
+ id: 'shelves',
3262
+ label: 'Shelves',
3263
+ color: '#d5b38d',
3264
+ },
3265
+ {
3266
+ id: 'back',
3267
+ label: 'Back',
3268
+ color: '#495b50',
3269
+ },
3270
+ ],
3271
+ parts: [
3272
+ {
3273
+ id: 'frame',
3274
+ label: 'Frame',
3275
+ count: 2,
3276
+ shapes: [
3277
+ {
3278
+ id: 'side',
3279
+ primitive: 'box',
3280
+ slot: 'frame',
3281
+ size: ['thickness', 'height', 'depth'],
3282
+ position: [
3283
+ {
3284
+ op: 'mul',
3285
+ args: [
3286
+ {
3287
+ op: 'sub',
3288
+ args: ['index', 0.5],
3289
+ },
3290
+ {
3291
+ op: 'sub',
3292
+ args: ['width', 'thickness'],
3293
+ },
3294
+ ],
3295
+ },
3296
+ {
3297
+ op: 'div',
3298
+ args: ['height', 2],
3299
+ },
3300
+ 0,
3301
+ ],
3302
+ },
3303
+ ],
3304
+ },
3305
+ {
3306
+ id: 'shelves',
3307
+ label: 'Shelves',
3308
+ count: 'rows',
3309
+ shapes: [
3310
+ {
3311
+ id: 'board',
3312
+ primitive: 'box',
3313
+ slot: 'shelves',
3314
+ size: [
3315
+ {
3316
+ op: 'sub',
3317
+ args: [
3318
+ 'width',
3319
+ {
3320
+ op: 'mul',
3321
+ args: [2, 'thickness'],
3322
+ },
3323
+ ],
3324
+ },
3325
+ 'thickness',
3326
+ 'depth',
3327
+ ],
3328
+ position: [
3329
+ 0,
3330
+ {
3331
+ op: 'add',
3332
+ args: [
3333
+ {
3334
+ op: 'div',
3335
+ args: ['thickness', 2],
3336
+ },
3337
+ {
3338
+ op: 'mul',
3339
+ args: [
3340
+ 'index',
3341
+ {
3342
+ op: 'div',
3343
+ args: [
3344
+ {
3345
+ op: 'sub',
3346
+ args: ['height', 'thickness'],
3347
+ },
3348
+ {
3349
+ op: 'sub',
3350
+ args: ['rows', 1],
3351
+ },
3352
+ ],
3353
+ },
3354
+ ],
3355
+ },
3356
+ ],
3357
+ },
3358
+ 0,
3359
+ ],
3360
+ support: true,
3361
+ },
3362
+ ],
3363
+ },
3364
+ {
3365
+ id: 'back',
3366
+ label: 'Back panel',
3367
+ count: 1,
3368
+ shapes: [
3369
+ {
3370
+ id: 'panel',
3371
+ primitive: 'box',
3372
+ slot: 'back',
3373
+ size: [
3374
+ {
3375
+ op: 'sub',
3376
+ args: [
3377
+ 'width',
3378
+ {
3379
+ op: 'mul',
3380
+ args: [2, 'thickness'],
3381
+ },
3382
+ ],
3383
+ },
3384
+ 'height',
3385
+ 0.012,
3386
+ ],
3387
+ position: [
3388
+ 0,
3389
+ {
3390
+ op: 'div',
3391
+ args: ['height', 2],
3392
+ },
3393
+ {
3394
+ op: 'add',
3395
+ args: [
3396
+ {
3397
+ op: 'div',
3398
+ args: ['depth', -2],
3399
+ },
3400
+ 0.006,
3401
+ ],
3402
+ },
3403
+ ],
3404
+ },
3405
+ ],
3406
+ },
3407
+ ],
3408
+ constraints: [],
3409
+ },
3410
+ parameters: {},
3411
+ slots: {},
3412
+ position: [8, 2, 7],
3413
+ rotation: [0.1, 1, -0.15],
3414
+ children: [],
3415
+ attachments: {},
3416
+ },
3417
+ rows: [
3418
+ {
3419
+ childKind: 'item',
3420
+ childFootprint: {
3421
+ size: [0.2, 0.1, 0.2],
3422
+ rotationY: 1.5707963267948966,
3423
+ rotation: [0, 1.5707963267948966, 0],
3424
+ },
3425
+ hit: {
3426
+ point: [2.05, 3, -1.1],
3427
+ normalWorldY: 1,
3428
+ },
3429
+ expected: {
3430
+ position: [2.05, 3, -1.1],
3431
+ rotationY: 1.5707963267948966,
3432
+ surfaceId: 'ledge',
3433
+ childFrame: 'surface-local',
3434
+ surfaceLocal: {
3435
+ position: [0.10000000000000009, -0, 0.049999999999999815],
3436
+ rotationY: 0,
3437
+ rotation: [0, 0, 0],
3438
+ },
3439
+ },
3440
+ rejections: [],
3441
+ },
3442
+ ],
3443
+ label: 'ledge: quarter-turn yaw',
3444
+ },
3445
+ {
3446
+ host: {
3447
+ object: 'node',
3448
+ id: 'procedural-item_frozen-8',
3449
+ type: 'procedural-item',
3450
+ parentId: null,
3451
+ visible: true,
3452
+ metadata: {},
3453
+ recipe: {
3454
+ version: 1,
3455
+ name: 'Everyday shelf',
3456
+ description: 'An open timber bookcase with adjustable shelves and a contrasting back.',
3457
+ surfaces: [
3458
+ {
3459
+ id: 'ledge',
3460
+ label: 'Ledge',
3461
+ position: [2, 3, -1],
3462
+ rotation: [0, 0, 0],
3463
+ size: [1.5, 0.6],
3464
+ },
3465
+ ],
3466
+ parameters: [
3467
+ {
3468
+ id: 'width',
3469
+ label: 'Width',
3470
+ default: 1.2,
3471
+ min: 0.6,
3472
+ max: 2.4,
3473
+ step: 0.05,
3474
+ unit: 'm',
3475
+ axis: 'x',
3476
+ },
3477
+ {
3478
+ id: 'height',
3479
+ label: 'Height',
3480
+ default: 1.8,
3481
+ min: 0.8,
3482
+ max: 2.5,
3483
+ step: 0.05,
3484
+ unit: 'm',
3485
+ axis: 'y',
3486
+ },
3487
+ {
3488
+ id: 'depth',
3489
+ label: 'Depth',
3490
+ default: 0.4,
3491
+ min: 0.25,
3492
+ max: 0.7,
3493
+ step: 0.025,
3494
+ unit: 'm',
3495
+ axis: 'z',
3496
+ },
3497
+ {
3498
+ id: 'rows',
3499
+ label: 'Shelves',
3500
+ default: 4,
3501
+ min: 2,
3502
+ max: 7,
3503
+ step: 1,
3504
+ unit: 'count',
3505
+ part: 'shelves',
3506
+ },
3507
+ {
3508
+ id: 'thickness',
3509
+ label: 'Board thickness',
3510
+ default: 0.03,
3511
+ min: 0.015,
3512
+ max: 0.06,
3513
+ step: 0.005,
3514
+ unit: 'm',
3515
+ part: 'frame',
3516
+ },
3517
+ ],
3518
+ slots: [
3519
+ {
3520
+ id: 'frame',
3521
+ label: 'Frame',
3522
+ color: '#b58a60',
3523
+ },
3524
+ {
3525
+ id: 'shelves',
3526
+ label: 'Shelves',
3527
+ color: '#d5b38d',
3528
+ },
3529
+ {
3530
+ id: 'back',
3531
+ label: 'Back',
3532
+ color: '#495b50',
3533
+ },
3534
+ ],
3535
+ parts: [
3536
+ {
3537
+ id: 'frame',
3538
+ label: 'Frame',
3539
+ count: 2,
3540
+ shapes: [
3541
+ {
3542
+ id: 'side',
3543
+ primitive: 'box',
3544
+ slot: 'frame',
3545
+ size: ['thickness', 'height', 'depth'],
3546
+ position: [
3547
+ {
3548
+ op: 'mul',
3549
+ args: [
3550
+ {
3551
+ op: 'sub',
3552
+ args: ['index', 0.5],
3553
+ },
3554
+ {
3555
+ op: 'sub',
3556
+ args: ['width', 'thickness'],
3557
+ },
3558
+ ],
3559
+ },
3560
+ {
3561
+ op: 'div',
3562
+ args: ['height', 2],
3563
+ },
3564
+ 0,
3565
+ ],
3566
+ },
3567
+ ],
3568
+ },
3569
+ {
3570
+ id: 'shelves',
3571
+ label: 'Shelves',
3572
+ count: 'rows',
3573
+ shapes: [
3574
+ {
3575
+ id: 'board',
3576
+ primitive: 'box',
3577
+ slot: 'shelves',
3578
+ size: [
3579
+ {
3580
+ op: 'sub',
3581
+ args: [
3582
+ 'width',
3583
+ {
3584
+ op: 'mul',
3585
+ args: [2, 'thickness'],
3586
+ },
3587
+ ],
3588
+ },
3589
+ 'thickness',
3590
+ 'depth',
3591
+ ],
3592
+ position: [
3593
+ 0,
3594
+ {
3595
+ op: 'add',
3596
+ args: [
3597
+ {
3598
+ op: 'div',
3599
+ args: ['thickness', 2],
3600
+ },
3601
+ {
3602
+ op: 'mul',
3603
+ args: [
3604
+ 'index',
3605
+ {
3606
+ op: 'div',
3607
+ args: [
3608
+ {
3609
+ op: 'sub',
3610
+ args: ['height', 'thickness'],
3611
+ },
3612
+ {
3613
+ op: 'sub',
3614
+ args: ['rows', 1],
3615
+ },
3616
+ ],
3617
+ },
3618
+ ],
3619
+ },
3620
+ ],
3621
+ },
3622
+ 0,
3623
+ ],
3624
+ support: true,
3625
+ },
3626
+ ],
3627
+ },
3628
+ {
3629
+ id: 'back',
3630
+ label: 'Back panel',
3631
+ count: 1,
3632
+ shapes: [
3633
+ {
3634
+ id: 'panel',
3635
+ primitive: 'box',
3636
+ slot: 'back',
3637
+ size: [
3638
+ {
3639
+ op: 'sub',
3640
+ args: [
3641
+ 'width',
3642
+ {
3643
+ op: 'mul',
3644
+ args: [2, 'thickness'],
3645
+ },
3646
+ ],
3647
+ },
3648
+ 'height',
3649
+ 0.012,
3650
+ ],
3651
+ position: [
3652
+ 0,
3653
+ {
3654
+ op: 'div',
3655
+ args: ['height', 2],
3656
+ },
3657
+ {
3658
+ op: 'add',
3659
+ args: [
3660
+ {
3661
+ op: 'div',
3662
+ args: ['depth', -2],
3663
+ },
3664
+ 0.006,
3665
+ ],
3666
+ },
3667
+ ],
3668
+ },
3669
+ ],
3670
+ },
3671
+ ],
3672
+ constraints: [],
3673
+ },
3674
+ parameters: {},
3675
+ slots: {},
3676
+ position: [8, 2, 7],
3677
+ rotation: [0.1, 1, -0.15],
3678
+ children: [],
3679
+ attachments: {},
3680
+ },
3681
+ rows: [
3682
+ {
3683
+ childKind: 'item',
3684
+ childFootprint: {
3685
+ size: [0.3, 0.4, 0.2],
3686
+ rotationY: 0.2,
3687
+ rotation: [0.4, 0.2, 0],
3688
+ localBounds: {
3689
+ min: [-0.15, 0, -0.1],
3690
+ max: [0.15, 0.4, 0.1],
3691
+ },
3692
+ },
3693
+ hit: {
3694
+ point: [2, 3, -1],
3695
+ normalWorldY: 1,
3696
+ },
3697
+ checkFootprint: false,
3698
+ expected: {
3699
+ position: [2, 3.049770412429372, -1],
3700
+ rotationY: 0.2,
3701
+ surfaceId: 'ledge',
3702
+ childFrame: 'surface-local',
3703
+ surfaceLocal: {
3704
+ position: [0, 0.04977041242937208, 0],
3705
+ rotationY: 0.2,
3706
+ rotation: [0.39999999999999997, 0.2, -0],
3707
+ },
3708
+ },
3709
+ rejections: [],
3710
+ },
3711
+ {
3712
+ childKind: 'item',
3713
+ childFootprint: {
3714
+ size: [0.3, 0.4, 0.2],
3715
+ rotationY: 0.2,
3716
+ rotation: [0.4, 0.2, 0],
3717
+ localBounds: {
3718
+ min: [-0.15, 0, -0.1],
3719
+ max: [0.15, 0.4, 0.1],
3720
+ },
3721
+ },
3722
+ hit: {
3723
+ point: [2, 3, -1],
3724
+ normalWorldY: 1,
3725
+ },
3726
+ expected: {
3727
+ position: [2, 3.049770412429372, -1],
3728
+ rotationY: 0.2,
3729
+ surfaceId: 'ledge',
3730
+ childFrame: 'surface-local',
3731
+ surfaceLocal: {
3732
+ position: [0, 0.04977041242937208, 0],
3733
+ rotationY: 0.2,
3734
+ rotation: [0.39999999999999997, 0.2, -0],
3735
+ },
3736
+ },
3737
+ rejections: [],
3738
+ },
3739
+ {
3740
+ childKind: 'item',
3741
+ childFootprint: {
3742
+ size: [0.3, 0.4, 0.2],
3743
+ rotationY: 0.2,
3744
+ rotation: [0.4, 0.2, 0],
3745
+ localBounds: {
3746
+ min: [-0.15, 0, -0.1],
3747
+ max: [0.15, 0.4, 0.1],
3748
+ },
3749
+ },
3750
+ hit: {
3751
+ point: [2.35, 3, -1],
3752
+ normalWorldY: 1,
3753
+ },
3754
+ checkFootprint: false,
3755
+ expected: {
3756
+ position: [2.35, 3.049770412429372, -1],
3757
+ rotationY: 0.2,
3758
+ surfaceId: 'ledge',
3759
+ childFrame: 'surface-local',
3760
+ surfaceLocal: {
3761
+ position: [0.3500000000000001, 0.04977041242937208, 0],
3762
+ rotationY: 0.2,
3763
+ rotation: [0.39999999999999997, 0.2, -0],
3764
+ },
3765
+ },
3766
+ rejections: [],
3767
+ },
3768
+ {
3769
+ childKind: 'item',
3770
+ childFootprint: {
3771
+ size: [0.3, 0.4, 0.2],
3772
+ rotationY: 0.2,
3773
+ rotation: [0.4, 0.2, 0],
3774
+ localBounds: {
3775
+ min: [-0.15, 0, -0.1],
3776
+ max: [0.15, 0.4, 0.1],
3777
+ },
3778
+ },
3779
+ hit: {
3780
+ point: [2.35, 3, -1],
3781
+ normalWorldY: 1,
3782
+ },
3783
+ expected: {
3784
+ position: [2.35, 3.049770412429372, -1],
3785
+ rotationY: 0.2,
3786
+ surfaceId: 'ledge',
3787
+ childFrame: 'surface-local',
3788
+ surfaceLocal: {
3789
+ position: [0.3500000000000001, 0.04977041242937208, 0],
3790
+ rotationY: 0.2,
3791
+ rotation: [0.39999999999999997, 0.2, -0],
3792
+ },
3793
+ },
3794
+ rejections: [],
3795
+ },
3796
+ {
3797
+ childKind: 'item',
3798
+ childFootprint: {
3799
+ size: [0.3, 0.4, 0.2],
3800
+ rotationY: 0.2,
3801
+ rotation: [0.4, 0.2, 0],
3802
+ localBounds: {
3803
+ min: [-0.15, 0, -0.1],
3804
+ max: [0.15, 0.4, 0.1],
3805
+ },
3806
+ },
3807
+ hit: {
3808
+ point: [2.6, 3, -1],
3809
+ normalWorldY: 1,
3810
+ },
3811
+ checkFootprint: false,
3812
+ expected: {
3813
+ position: [2.6, 3.049770412429372, -1],
3814
+ rotationY: 0.2,
3815
+ surfaceId: 'ledge',
3816
+ childFrame: 'surface-local',
3817
+ surfaceLocal: {
3818
+ position: [0.6000000000000001, 0.04977041242937208, 0],
3819
+ rotationY: 0.2,
3820
+ rotation: [0.39999999999999997, 0.2, -0],
3821
+ },
3822
+ },
3823
+ rejections: [],
3824
+ },
3825
+ {
3826
+ childKind: 'item',
3827
+ childFootprint: {
3828
+ size: [0.3, 0.4, 0.2],
3829
+ rotationY: 0.2,
3830
+ rotation: [0.4, 0.2, 0],
3831
+ localBounds: {
3832
+ min: [-0.15, 0, -0.1],
3833
+ max: [0.15, 0.4, 0.1],
3834
+ },
3835
+ },
3836
+ hit: {
3837
+ point: [2.6, 3, -1],
3838
+ normalWorldY: 1,
3839
+ },
3840
+ expected: {
3841
+ position: [2.6, 3.049770412429372, -1],
3842
+ rotationY: 0.2,
3843
+ surfaceId: 'ledge',
3844
+ childFrame: 'surface-local',
3845
+ surfaceLocal: {
3846
+ position: [0.6000000000000001, 0.04977041242937208, 0],
3847
+ rotationY: 0.2,
3848
+ rotation: [0.39999999999999997, 0.2, -0],
3849
+ },
3850
+ },
3851
+ rejections: [],
3852
+ },
3853
+ {
3854
+ childKind: 'procedural-item',
3855
+ childFootprint: {
3856
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
3857
+ rotationY: 0.2,
3858
+ rotation: [0.4, 0.2, 0],
3859
+ localBounds: {
3860
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
3861
+ max: [0.4, 0.55, 0.05],
3862
+ },
3863
+ },
3864
+ hit: {
3865
+ point: [2, 3, -1],
3866
+ normalWorldY: 1,
3867
+ },
3868
+ checkFootprint: false,
3869
+ expected: {
3870
+ position: [2, 2.8731870978577416, -1],
3871
+ rotationY: 0.2,
3872
+ surfaceId: 'ledge',
3873
+ childFrame: 'surface-local',
3874
+ surfaceLocal: {
3875
+ position: [0, -0.1268129021422585, 0],
3876
+ rotationY: 0.2,
3877
+ rotation: [0.39999999999999997, 0.2, -0],
3878
+ },
3879
+ },
3880
+ rejections: [],
3881
+ },
3882
+ {
3883
+ childKind: 'procedural-item',
3884
+ childFootprint: {
3885
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
3886
+ rotationY: 0.2,
3887
+ rotation: [0.4, 0.2, 0],
3888
+ localBounds: {
3889
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
3890
+ max: [0.4, 0.55, 0.05],
3891
+ },
3892
+ },
3893
+ hit: {
3894
+ point: [2, 3, -1],
3895
+ normalWorldY: 1,
3896
+ },
3897
+ expected: {
3898
+ position: [2, 2.8731870978577416, -1],
3899
+ rotationY: 0.2,
3900
+ surfaceId: 'ledge',
3901
+ childFrame: 'surface-local',
3902
+ surfaceLocal: {
3903
+ position: [0, -0.1268129021422585, 0],
3904
+ rotationY: 0.2,
3905
+ rotation: [0.39999999999999997, 0.2, -0],
3906
+ },
3907
+ },
3908
+ rejections: [],
3909
+ },
3910
+ {
3911
+ childKind: 'procedural-item',
3912
+ childFootprint: {
3913
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
3914
+ rotationY: 0.2,
3915
+ rotation: [0.4, 0.2, 0],
3916
+ localBounds: {
3917
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
3918
+ max: [0.4, 0.55, 0.05],
3919
+ },
3920
+ },
3921
+ hit: {
3922
+ point: [2.35, 3, -1],
3923
+ normalWorldY: 1,
3924
+ },
3925
+ checkFootprint: false,
3926
+ expected: {
3927
+ position: [2.35, 2.8731870978577416, -1],
3928
+ rotationY: 0.2,
3929
+ surfaceId: 'ledge',
3930
+ childFrame: 'surface-local',
3931
+ surfaceLocal: {
3932
+ position: [0.3500000000000001, -0.1268129021422585, 0],
3933
+ rotationY: 0.2,
3934
+ rotation: [0.39999999999999997, 0.2, -0],
3935
+ },
3936
+ },
3937
+ rejections: [],
3938
+ },
3939
+ {
3940
+ childKind: 'procedural-item',
3941
+ childFootprint: {
3942
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
3943
+ rotationY: 0.2,
3944
+ rotation: [0.4, 0.2, 0],
3945
+ localBounds: {
3946
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
3947
+ max: [0.4, 0.55, 0.05],
3948
+ },
3949
+ },
3950
+ hit: {
3951
+ point: [2.35, 3, -1],
3952
+ normalWorldY: 1,
3953
+ },
3954
+ expected: {
3955
+ position: [2.35, 2.8731870978577416, -1],
3956
+ rotationY: 0.2,
3957
+ surfaceId: 'ledge',
3958
+ childFrame: 'surface-local',
3959
+ surfaceLocal: {
3960
+ position: [0.3500000000000001, -0.1268129021422585, 0],
3961
+ rotationY: 0.2,
3962
+ rotation: [0.39999999999999997, 0.2, -0],
3963
+ },
3964
+ },
3965
+ rejections: [],
3966
+ },
3967
+ {
3968
+ childKind: 'procedural-item',
3969
+ childFootprint: {
3970
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
3971
+ rotationY: 0.2,
3972
+ rotation: [0.4, 0.2, 0],
3973
+ localBounds: {
3974
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
3975
+ max: [0.4, 0.55, 0.05],
3976
+ },
3977
+ },
3978
+ hit: {
3979
+ point: [2.6, 3, -1],
3980
+ normalWorldY: 1,
3981
+ },
3982
+ checkFootprint: false,
3983
+ expected: {
3984
+ position: [2.6, 2.8731870978577416, -1],
3985
+ rotationY: 0.2,
3986
+ surfaceId: 'ledge',
3987
+ childFrame: 'surface-local',
3988
+ surfaceLocal: {
3989
+ position: [0.6000000000000001, -0.1268129021422585, 0],
3990
+ rotationY: 0.2,
3991
+ rotation: [0.39999999999999997, 0.2, -0],
3992
+ },
3993
+ },
3994
+ rejections: [],
3995
+ },
3996
+ {
3997
+ childKind: 'procedural-item',
3998
+ childFootprint: {
3999
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4000
+ rotationY: 0.2,
4001
+ rotation: [0.4, 0.2, 0],
4002
+ localBounds: {
4003
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4004
+ max: [0.4, 0.55, 0.05],
4005
+ },
4006
+ },
4007
+ hit: {
4008
+ point: [2.6, 3, -1],
4009
+ normalWorldY: 1,
4010
+ },
4011
+ expected: null,
4012
+ rejections: ['footprint-outside-surface'],
4013
+ },
4014
+ {
4015
+ childKind: 'item',
4016
+ childFootprint: {
4017
+ size: [0.3, 0.4, 0.2],
4018
+ rotationY: -0.3,
4019
+ rotation: [0, -0.3, 0.45],
4020
+ localBounds: {
4021
+ min: [-0.15, 0, -0.1],
4022
+ max: [0.15, 0.4, 0.1],
4023
+ },
4024
+ },
4025
+ hit: {
4026
+ point: [2, 3, -1],
4027
+ normalWorldY: 1,
4028
+ },
4029
+ checkFootprint: false,
4030
+ expected: {
4031
+ position: [2, 3.0652448301166846, -1],
4032
+ rotationY: -0.3,
4033
+ surfaceId: 'ledge',
4034
+ childFrame: 'surface-local',
4035
+ surfaceLocal: {
4036
+ position: [0, 0.06524483011668453, 0],
4037
+ rotationY: -0.3,
4038
+ rotation: [-0, -0.3, 0.45],
4039
+ },
4040
+ },
4041
+ rejections: [],
4042
+ },
4043
+ {
4044
+ childKind: 'item',
4045
+ childFootprint: {
4046
+ size: [0.3, 0.4, 0.2],
4047
+ rotationY: -0.3,
4048
+ rotation: [0, -0.3, 0.45],
4049
+ localBounds: {
4050
+ min: [-0.15, 0, -0.1],
4051
+ max: [0.15, 0.4, 0.1],
4052
+ },
4053
+ },
4054
+ hit: {
4055
+ point: [2, 3, -1],
4056
+ normalWorldY: 1,
4057
+ },
4058
+ expected: {
4059
+ position: [2, 3.0652448301166846, -1],
4060
+ rotationY: -0.3,
4061
+ surfaceId: 'ledge',
4062
+ childFrame: 'surface-local',
4063
+ surfaceLocal: {
4064
+ position: [0, 0.06524483011668453, 0],
4065
+ rotationY: -0.3,
4066
+ rotation: [-0, -0.3, 0.45],
4067
+ },
4068
+ },
4069
+ rejections: [],
4070
+ },
4071
+ {
4072
+ childKind: 'item',
4073
+ childFootprint: {
4074
+ size: [0.3, 0.4, 0.2],
4075
+ rotationY: -0.3,
4076
+ rotation: [0, -0.3, 0.45],
4077
+ localBounds: {
4078
+ min: [-0.15, 0, -0.1],
4079
+ max: [0.15, 0.4, 0.1],
4080
+ },
4081
+ },
4082
+ hit: {
4083
+ point: [2.35, 3, -1],
4084
+ normalWorldY: 1,
4085
+ },
4086
+ checkFootprint: false,
4087
+ expected: {
4088
+ position: [2.35, 3.0652448301166846, -1],
4089
+ rotationY: -0.3,
4090
+ surfaceId: 'ledge',
4091
+ childFrame: 'surface-local',
4092
+ surfaceLocal: {
4093
+ position: [0.3500000000000001, 0.06524483011668453, 0],
4094
+ rotationY: -0.3,
4095
+ rotation: [-0, -0.3, 0.45],
4096
+ },
4097
+ },
4098
+ rejections: [],
4099
+ },
4100
+ {
4101
+ childKind: 'item',
4102
+ childFootprint: {
4103
+ size: [0.3, 0.4, 0.2],
4104
+ rotationY: -0.3,
4105
+ rotation: [0, -0.3, 0.45],
4106
+ localBounds: {
4107
+ min: [-0.15, 0, -0.1],
4108
+ max: [0.15, 0.4, 0.1],
4109
+ },
4110
+ },
4111
+ hit: {
4112
+ point: [2.35, 3, -1],
4113
+ normalWorldY: 1,
4114
+ },
4115
+ expected: {
4116
+ position: [2.35, 3.0652448301166846, -1],
4117
+ rotationY: -0.3,
4118
+ surfaceId: 'ledge',
4119
+ childFrame: 'surface-local',
4120
+ surfaceLocal: {
4121
+ position: [0.3500000000000001, 0.06524483011668453, 0],
4122
+ rotationY: -0.3,
4123
+ rotation: [-0, -0.3, 0.45],
4124
+ },
4125
+ },
4126
+ rejections: [],
4127
+ },
4128
+ {
4129
+ childKind: 'item',
4130
+ childFootprint: {
4131
+ size: [0.3, 0.4, 0.2],
4132
+ rotationY: -0.3,
4133
+ rotation: [0, -0.3, 0.45],
4134
+ localBounds: {
4135
+ min: [-0.15, 0, -0.1],
4136
+ max: [0.15, 0.4, 0.1],
4137
+ },
4138
+ },
4139
+ hit: {
4140
+ point: [2.6, 3, -1],
4141
+ normalWorldY: 1,
4142
+ },
4143
+ checkFootprint: false,
4144
+ expected: {
4145
+ position: [2.6, 3.0652448301166846, -1],
4146
+ rotationY: -0.3,
4147
+ surfaceId: 'ledge',
4148
+ childFrame: 'surface-local',
4149
+ surfaceLocal: {
4150
+ position: [0.6000000000000001, 0.06524483011668453, 0],
4151
+ rotationY: -0.3,
4152
+ rotation: [-0, -0.3, 0.45],
4153
+ },
4154
+ },
4155
+ rejections: [],
4156
+ },
4157
+ {
4158
+ childKind: 'item',
4159
+ childFootprint: {
4160
+ size: [0.3, 0.4, 0.2],
4161
+ rotationY: -0.3,
4162
+ rotation: [0, -0.3, 0.45],
4163
+ localBounds: {
4164
+ min: [-0.15, 0, -0.1],
4165
+ max: [0.15, 0.4, 0.1],
4166
+ },
4167
+ },
4168
+ hit: {
4169
+ point: [2.6, 3, -1],
4170
+ normalWorldY: 1,
4171
+ },
4172
+ expected: {
4173
+ position: [2.6, 3.0652448301166846, -1],
4174
+ rotationY: -0.3,
4175
+ surfaceId: 'ledge',
4176
+ childFrame: 'surface-local',
4177
+ surfaceLocal: {
4178
+ position: [0.6000000000000001, 0.06524483011668453, 0],
4179
+ rotationY: -0.3,
4180
+ rotation: [-0, -0.3, 0.45],
4181
+ },
4182
+ },
4183
+ rejections: [],
4184
+ },
4185
+ {
4186
+ childKind: 'procedural-item',
4187
+ childFootprint: {
4188
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4189
+ rotationY: -0.3,
4190
+ rotation: [0, -0.3, 0.45],
4191
+ localBounds: {
4192
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4193
+ max: [0.4, 0.55, 0.05],
4194
+ },
4195
+ },
4196
+ hit: {
4197
+ point: [2, 3, -1],
4198
+ normalWorldY: 1,
4199
+ },
4200
+ checkFootprint: false,
4201
+ expected: {
4202
+ position: [2, 2.8214363812359755, -1],
4203
+ rotationY: -0.3,
4204
+ surfaceId: 'ledge',
4205
+ childFrame: 'surface-local',
4206
+ surfaceLocal: {
4207
+ position: [0, -0.17856361876402452, 0],
4208
+ rotationY: -0.3,
4209
+ rotation: [-0, -0.3, 0.45],
4210
+ },
4211
+ },
4212
+ rejections: [],
4213
+ },
4214
+ {
4215
+ childKind: 'procedural-item',
4216
+ childFootprint: {
4217
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4218
+ rotationY: -0.3,
4219
+ rotation: [0, -0.3, 0.45],
4220
+ localBounds: {
4221
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4222
+ max: [0.4, 0.55, 0.05],
4223
+ },
4224
+ },
4225
+ hit: {
4226
+ point: [2, 3, -1],
4227
+ normalWorldY: 1,
4228
+ },
4229
+ expected: {
4230
+ position: [2, 2.8214363812359755, -1],
4231
+ rotationY: -0.3,
4232
+ surfaceId: 'ledge',
4233
+ childFrame: 'surface-local',
4234
+ surfaceLocal: {
4235
+ position: [0, -0.17856361876402452, 0],
4236
+ rotationY: -0.3,
4237
+ rotation: [-0, -0.3, 0.45],
4238
+ },
4239
+ },
4240
+ rejections: [],
4241
+ },
4242
+ {
4243
+ childKind: 'procedural-item',
4244
+ childFootprint: {
4245
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4246
+ rotationY: -0.3,
4247
+ rotation: [0, -0.3, 0.45],
4248
+ localBounds: {
4249
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4250
+ max: [0.4, 0.55, 0.05],
4251
+ },
4252
+ },
4253
+ hit: {
4254
+ point: [2.35, 3, -1],
4255
+ normalWorldY: 1,
4256
+ },
4257
+ checkFootprint: false,
4258
+ expected: {
4259
+ position: [2.35, 2.8214363812359755, -1],
4260
+ rotationY: -0.3,
4261
+ surfaceId: 'ledge',
4262
+ childFrame: 'surface-local',
4263
+ surfaceLocal: {
4264
+ position: [0.3500000000000001, -0.17856361876402452, 0],
4265
+ rotationY: -0.3,
4266
+ rotation: [-0, -0.3, 0.45],
4267
+ },
4268
+ },
4269
+ rejections: [],
4270
+ },
4271
+ {
4272
+ childKind: 'procedural-item',
4273
+ childFootprint: {
4274
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4275
+ rotationY: -0.3,
4276
+ rotation: [0, -0.3, 0.45],
4277
+ localBounds: {
4278
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4279
+ max: [0.4, 0.55, 0.05],
4280
+ },
4281
+ },
4282
+ hit: {
4283
+ point: [2.35, 3, -1],
4284
+ normalWorldY: 1,
4285
+ },
4286
+ expected: {
4287
+ position: [2.35, 2.8214363812359755, -1],
4288
+ rotationY: -0.3,
4289
+ surfaceId: 'ledge',
4290
+ childFrame: 'surface-local',
4291
+ surfaceLocal: {
4292
+ position: [0.3500000000000001, -0.17856361876402452, 0],
4293
+ rotationY: -0.3,
4294
+ rotation: [-0, -0.3, 0.45],
4295
+ },
4296
+ },
4297
+ rejections: [],
4298
+ },
4299
+ {
4300
+ childKind: 'procedural-item',
4301
+ childFootprint: {
4302
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4303
+ rotationY: -0.3,
4304
+ rotation: [0, -0.3, 0.45],
4305
+ localBounds: {
4306
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4307
+ max: [0.4, 0.55, 0.05],
4308
+ },
4309
+ },
4310
+ hit: {
4311
+ point: [2.6, 3, -1],
4312
+ normalWorldY: 1,
4313
+ },
4314
+ checkFootprint: false,
4315
+ expected: {
4316
+ position: [2.6, 2.8214363812359755, -1],
4317
+ rotationY: -0.3,
4318
+ surfaceId: 'ledge',
4319
+ childFrame: 'surface-local',
4320
+ surfaceLocal: {
4321
+ position: [0.6000000000000001, -0.17856361876402452, 0],
4322
+ rotationY: -0.3,
4323
+ rotation: [-0, -0.3, 0.45],
4324
+ },
4325
+ },
4326
+ rejections: [],
4327
+ },
4328
+ {
4329
+ childKind: 'procedural-item',
4330
+ childFootprint: {
4331
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4332
+ rotationY: -0.3,
4333
+ rotation: [0, -0.3, 0.45],
4334
+ localBounds: {
4335
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4336
+ max: [0.4, 0.55, 0.05],
4337
+ },
4338
+ },
4339
+ hit: {
4340
+ point: [2.6, 3, -1],
4341
+ normalWorldY: 1,
4342
+ },
4343
+ expected: {
4344
+ position: [2.6, 2.8214363812359755, -1],
4345
+ rotationY: -0.3,
4346
+ surfaceId: 'ledge',
4347
+ childFrame: 'surface-local',
4348
+ surfaceLocal: {
4349
+ position: [0.6000000000000001, -0.17856361876402452, 0],
4350
+ rotationY: -0.3,
4351
+ rotation: [-0, -0.3, 0.45],
4352
+ },
4353
+ },
4354
+ rejections: [],
4355
+ },
4356
+ {
4357
+ childKind: 'item',
4358
+ childFootprint: {
4359
+ size: [0.3, 0.4, 0.2],
4360
+ rotationY: 0.2,
4361
+ rotation: [0.3, 0.2, -0.4],
4362
+ localBounds: {
4363
+ min: [-0.15, 0, -0.1],
4364
+ max: [0.15, 0.4, 0.1],
4365
+ },
4366
+ },
4367
+ hit: {
4368
+ point: [2, 3, -1],
4369
+ normalWorldY: 1,
4370
+ },
4371
+ checkFootprint: false,
4372
+ expected: {
4373
+ position: [2, 3.076655346148867, -1],
4374
+ rotationY: 0.2,
4375
+ surfaceId: 'ledge',
4376
+ childFrame: 'surface-local',
4377
+ surfaceLocal: {
4378
+ position: [0, 0.07665534614886717, 0],
4379
+ rotationY: 0.2,
4380
+ rotation: [0.3, 0.2, -0.39999999999999997],
4381
+ },
4382
+ },
4383
+ rejections: [],
4384
+ },
4385
+ {
4386
+ childKind: 'item',
4387
+ childFootprint: {
4388
+ size: [0.3, 0.4, 0.2],
4389
+ rotationY: 0.2,
4390
+ rotation: [0.3, 0.2, -0.4],
4391
+ localBounds: {
4392
+ min: [-0.15, 0, -0.1],
4393
+ max: [0.15, 0.4, 0.1],
4394
+ },
4395
+ },
4396
+ hit: {
4397
+ point: [2, 3, -1],
4398
+ normalWorldY: 1,
4399
+ },
4400
+ expected: {
4401
+ position: [2, 3.076655346148867, -1],
4402
+ rotationY: 0.2,
4403
+ surfaceId: 'ledge',
4404
+ childFrame: 'surface-local',
4405
+ surfaceLocal: {
4406
+ position: [0, 0.07665534614886717, 0],
4407
+ rotationY: 0.2,
4408
+ rotation: [0.3, 0.2, -0.39999999999999997],
4409
+ },
4410
+ },
4411
+ rejections: [],
4412
+ },
4413
+ {
4414
+ childKind: 'item',
4415
+ childFootprint: {
4416
+ size: [0.3, 0.4, 0.2],
4417
+ rotationY: 0.2,
4418
+ rotation: [0.3, 0.2, -0.4],
4419
+ localBounds: {
4420
+ min: [-0.15, 0, -0.1],
4421
+ max: [0.15, 0.4, 0.1],
4422
+ },
4423
+ },
4424
+ hit: {
4425
+ point: [2.35, 3, -1],
4426
+ normalWorldY: 1,
4427
+ },
4428
+ checkFootprint: false,
4429
+ expected: {
4430
+ position: [2.35, 3.076655346148867, -1],
4431
+ rotationY: 0.2,
4432
+ surfaceId: 'ledge',
4433
+ childFrame: 'surface-local',
4434
+ surfaceLocal: {
4435
+ position: [0.3500000000000001, 0.07665534614886717, 0],
4436
+ rotationY: 0.2,
4437
+ rotation: [0.3, 0.2, -0.39999999999999997],
4438
+ },
4439
+ },
4440
+ rejections: [],
4441
+ },
4442
+ {
4443
+ childKind: 'item',
4444
+ childFootprint: {
4445
+ size: [0.3, 0.4, 0.2],
4446
+ rotationY: 0.2,
4447
+ rotation: [0.3, 0.2, -0.4],
4448
+ localBounds: {
4449
+ min: [-0.15, 0, -0.1],
4450
+ max: [0.15, 0.4, 0.1],
4451
+ },
4452
+ },
4453
+ hit: {
4454
+ point: [2.35, 3, -1],
4455
+ normalWorldY: 1,
4456
+ },
4457
+ expected: {
4458
+ position: [2.35, 3.076655346148867, -1],
4459
+ rotationY: 0.2,
4460
+ surfaceId: 'ledge',
4461
+ childFrame: 'surface-local',
4462
+ surfaceLocal: {
4463
+ position: [0.3500000000000001, 0.07665534614886717, 0],
4464
+ rotationY: 0.2,
4465
+ rotation: [0.3, 0.2, -0.39999999999999997],
4466
+ },
4467
+ },
4468
+ rejections: [],
4469
+ },
4470
+ {
4471
+ childKind: 'item',
4472
+ childFootprint: {
4473
+ size: [0.3, 0.4, 0.2],
4474
+ rotationY: 0.2,
4475
+ rotation: [0.3, 0.2, -0.4],
4476
+ localBounds: {
4477
+ min: [-0.15, 0, -0.1],
4478
+ max: [0.15, 0.4, 0.1],
4479
+ },
4480
+ },
4481
+ hit: {
4482
+ point: [2.6, 3, -1],
4483
+ normalWorldY: 1,
4484
+ },
4485
+ checkFootprint: false,
4486
+ expected: {
4487
+ position: [2.6, 3.076655346148867, -1],
4488
+ rotationY: 0.2,
4489
+ surfaceId: 'ledge',
4490
+ childFrame: 'surface-local',
4491
+ surfaceLocal: {
4492
+ position: [0.6000000000000001, 0.07665534614886717, 0],
4493
+ rotationY: 0.2,
4494
+ rotation: [0.3, 0.2, -0.39999999999999997],
4495
+ },
4496
+ },
4497
+ rejections: [],
4498
+ },
4499
+ {
4500
+ childKind: 'item',
4501
+ childFootprint: {
4502
+ size: [0.3, 0.4, 0.2],
4503
+ rotationY: 0.2,
4504
+ rotation: [0.3, 0.2, -0.4],
4505
+ localBounds: {
4506
+ min: [-0.15, 0, -0.1],
4507
+ max: [0.15, 0.4, 0.1],
4508
+ },
4509
+ },
4510
+ hit: {
4511
+ point: [2.6, 3, -1],
4512
+ normalWorldY: 1,
4513
+ },
4514
+ expected: {
4515
+ position: [2.6, 3.076655346148867, -1],
4516
+ rotationY: 0.2,
4517
+ surfaceId: 'ledge',
4518
+ childFrame: 'surface-local',
4519
+ surfaceLocal: {
4520
+ position: [0.6000000000000001, 0.07665534614886717, 0],
4521
+ rotationY: 0.2,
4522
+ rotation: [0.3, 0.2, -0.39999999999999997],
4523
+ },
4524
+ },
4525
+ rejections: [],
4526
+ },
4527
+ {
4528
+ childKind: 'procedural-item',
4529
+ childFootprint: {
4530
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4531
+ rotationY: 0.2,
4532
+ rotation: [0.3, 0.2, -0.4],
4533
+ localBounds: {
4534
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4535
+ max: [0.4, 0.55, 0.05],
4536
+ },
4537
+ },
4538
+ hit: {
4539
+ point: [2, 3, -1],
4540
+ normalWorldY: 1,
4541
+ },
4542
+ checkFootprint: false,
4543
+ expected: {
4544
+ position: [2, 3.006243267008579, -1],
4545
+ rotationY: 0.2,
4546
+ surfaceId: 'ledge',
4547
+ childFrame: 'surface-local',
4548
+ surfaceLocal: {
4549
+ position: [0, 0.006243267008578949, 0],
4550
+ rotationY: 0.2,
4551
+ rotation: [0.3, 0.2, -0.39999999999999997],
4552
+ },
4553
+ },
4554
+ rejections: [],
4555
+ },
4556
+ {
4557
+ childKind: 'procedural-item',
4558
+ childFootprint: {
4559
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4560
+ rotationY: 0.2,
4561
+ rotation: [0.3, 0.2, -0.4],
4562
+ localBounds: {
4563
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4564
+ max: [0.4, 0.55, 0.05],
4565
+ },
4566
+ },
4567
+ hit: {
4568
+ point: [2, 3, -1],
4569
+ normalWorldY: 1,
4570
+ },
4571
+ expected: {
4572
+ position: [2, 3.006243267008579, -1],
4573
+ rotationY: 0.2,
4574
+ surfaceId: 'ledge',
4575
+ childFrame: 'surface-local',
4576
+ surfaceLocal: {
4577
+ position: [0, 0.006243267008578949, 0],
4578
+ rotationY: 0.2,
4579
+ rotation: [0.3, 0.2, -0.39999999999999997],
4580
+ },
4581
+ },
4582
+ rejections: [],
4583
+ },
4584
+ {
4585
+ childKind: 'procedural-item',
4586
+ childFootprint: {
4587
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4588
+ rotationY: 0.2,
4589
+ rotation: [0.3, 0.2, -0.4],
4590
+ localBounds: {
4591
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4592
+ max: [0.4, 0.55, 0.05],
4593
+ },
4594
+ },
4595
+ hit: {
4596
+ point: [2.35, 3, -1],
4597
+ normalWorldY: 1,
4598
+ },
4599
+ checkFootprint: false,
4600
+ expected: {
4601
+ position: [2.35, 3.006243267008579, -1],
4602
+ rotationY: 0.2,
4603
+ surfaceId: 'ledge',
4604
+ childFrame: 'surface-local',
4605
+ surfaceLocal: {
4606
+ position: [0.3500000000000001, 0.006243267008578949, 0],
4607
+ rotationY: 0.2,
4608
+ rotation: [0.3, 0.2, -0.39999999999999997],
4609
+ },
4610
+ },
4611
+ rejections: [],
4612
+ },
4613
+ {
4614
+ childKind: 'procedural-item',
4615
+ childFootprint: {
4616
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4617
+ rotationY: 0.2,
4618
+ rotation: [0.3, 0.2, -0.4],
4619
+ localBounds: {
4620
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4621
+ max: [0.4, 0.55, 0.05],
4622
+ },
4623
+ },
4624
+ hit: {
4625
+ point: [2.35, 3, -1],
4626
+ normalWorldY: 1,
4627
+ },
4628
+ expected: {
4629
+ position: [2.35, 3.006243267008579, -1],
4630
+ rotationY: 0.2,
4631
+ surfaceId: 'ledge',
4632
+ childFrame: 'surface-local',
4633
+ surfaceLocal: {
4634
+ position: [0.3500000000000001, 0.006243267008578949, 0],
4635
+ rotationY: 0.2,
4636
+ rotation: [0.3, 0.2, -0.39999999999999997],
4637
+ },
4638
+ },
4639
+ rejections: [],
4640
+ },
4641
+ {
4642
+ childKind: 'procedural-item',
4643
+ childFootprint: {
4644
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4645
+ rotationY: 0.2,
4646
+ rotation: [0.3, 0.2, -0.4],
4647
+ localBounds: {
4648
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4649
+ max: [0.4, 0.55, 0.05],
4650
+ },
4651
+ },
4652
+ hit: {
4653
+ point: [2.6, 3, -1],
4654
+ normalWorldY: 1,
4655
+ },
4656
+ checkFootprint: false,
4657
+ expected: {
4658
+ position: [2.6, 3.006243267008579, -1],
4659
+ rotationY: 0.2,
4660
+ surfaceId: 'ledge',
4661
+ childFrame: 'surface-local',
4662
+ surfaceLocal: {
4663
+ position: [0.6000000000000001, 0.006243267008578949, 0],
4664
+ rotationY: 0.2,
4665
+ rotation: [0.3, 0.2, -0.39999999999999997],
4666
+ },
4667
+ },
4668
+ rejections: [],
4669
+ },
4670
+ {
4671
+ childKind: 'procedural-item',
4672
+ childFootprint: {
4673
+ size: [0.30000000000000004, 0.4000000000000001, 0.2],
4674
+ rotationY: 0.2,
4675
+ rotation: [0.3, 0.2, -0.4],
4676
+ localBounds: {
4677
+ min: [0.1, 0.14999999999999997, -0.15000000000000002],
4678
+ max: [0.4, 0.55, 0.05],
4679
+ },
4680
+ },
4681
+ hit: {
4682
+ point: [2.6, 3, -1],
4683
+ normalWorldY: 1,
4684
+ },
4685
+ expected: null,
4686
+ rejections: ['footprint-outside-surface'],
4687
+ },
4688
+ ],
4689
+ label: 'full child rotation: centred and off-centre bounds',
4690
+ },
4691
+ ];