@ifc-lite/create 4.0.0 → 5.1.1

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 (336) hide show
  1. package/README.md +34 -0
  2. package/dist/in-store/align-boxes.d.ts +38 -0
  3. package/dist/in-store/align-boxes.d.ts.map +1 -0
  4. package/dist/in-store/align-boxes.js +97 -0
  5. package/dist/in-store/align-boxes.js.map +1 -0
  6. package/dist/in-store/anchor.d.ts.map +1 -1
  7. package/dist/in-store/anchor.js +13 -2
  8. package/dist/in-store/anchor.js.map +1 -1
  9. package/dist/in-store/beam.d.ts.map +1 -1
  10. package/dist/in-store/beam.js +3 -10
  11. package/dist/in-store/beam.js.map +1 -1
  12. package/dist/in-store/copy-array.d.ts +17 -0
  13. package/dist/in-store/copy-array.d.ts.map +1 -0
  14. package/dist/in-store/copy-array.js +47 -0
  15. package/dist/in-store/copy-array.js.map +1 -0
  16. package/dist/in-store/copy-batch.d.ts +27 -0
  17. package/dist/in-store/copy-batch.d.ts.map +1 -0
  18. package/dist/in-store/copy-batch.js +101 -0
  19. package/dist/in-store/copy-batch.js.map +1 -0
  20. package/dist/in-store/copy-dependent-walk.d.ts +27 -0
  21. package/dist/in-store/copy-dependent-walk.d.ts.map +1 -0
  22. package/dist/in-store/copy-dependent-walk.js +61 -0
  23. package/dist/in-store/copy-dependent-walk.js.map +1 -0
  24. package/dist/in-store/copy-frame.d.ts +4 -3
  25. package/dist/in-store/copy-frame.d.ts.map +1 -1
  26. package/dist/in-store/copy-frame.js +14 -1
  27. package/dist/in-store/copy-frame.js.map +1 -1
  28. package/dist/in-store/copy-product.d.ts +0 -20
  29. package/dist/in-store/copy-product.d.ts.map +1 -1
  30. package/dist/in-store/copy-product.js +35 -35
  31. package/dist/in-store/copy-product.js.map +1 -1
  32. package/dist/in-store/duplicate.d.ts +8 -0
  33. package/dist/in-store/duplicate.d.ts.map +1 -1
  34. package/dist/in-store/duplicate.js +8 -1
  35. package/dist/in-store/duplicate.js.map +1 -1
  36. package/dist/in-store/edit/effective-mutation-view.d.ts +6 -0
  37. package/dist/in-store/edit/effective-mutation-view.d.ts.map +1 -0
  38. package/dist/in-store/edit/effective-mutation-view.js +45 -0
  39. package/dist/in-store/edit/effective-mutation-view.js.map +1 -0
  40. package/dist/in-store/edit/effective-storey.d.ts +13 -0
  41. package/dist/in-store/edit/effective-storey.d.ts.map +1 -0
  42. package/dist/in-store/edit/effective-storey.js +36 -0
  43. package/dist/in-store/edit/effective-storey.js.map +1 -0
  44. package/dist/in-store/edit/effective-storeys.d.ts +9 -0
  45. package/dist/in-store/edit/effective-storeys.d.ts.map +1 -0
  46. package/dist/in-store/edit/effective-storeys.js +16 -0
  47. package/dist/in-store/edit/effective-storeys.js.map +1 -0
  48. package/dist/in-store/edit/hosted-opening-refit.d.ts +29 -0
  49. package/dist/in-store/edit/hosted-opening-refit.d.ts.map +1 -0
  50. package/dist/in-store/edit/hosted-opening-refit.js +168 -0
  51. package/dist/in-store/edit/hosted-opening-refit.js.map +1 -0
  52. package/dist/in-store/edit/length-unit-scale.d.ts +24 -0
  53. package/dist/in-store/edit/length-unit-scale.d.ts.map +1 -0
  54. package/dist/in-store/edit/length-unit-scale.js +37 -0
  55. package/dist/in-store/edit/length-unit-scale.js.map +1 -0
  56. package/dist/in-store/edit/linear-element-edit.d.ts +131 -0
  57. package/dist/in-store/edit/linear-element-edit.d.ts.map +1 -0
  58. package/dist/in-store/edit/linear-element-edit.js +259 -0
  59. package/dist/in-store/edit/linear-element-edit.js.map +1 -0
  60. package/dist/in-store/edit/metadata-clone-effective.d.ts +5 -0
  61. package/dist/in-store/edit/metadata-clone-effective.d.ts.map +1 -0
  62. package/dist/in-store/edit/metadata-clone-effective.js +47 -0
  63. package/dist/in-store/edit/metadata-clone-effective.js.map +1 -0
  64. package/dist/in-store/edit/metadata-clone.d.ts +40 -0
  65. package/dist/in-store/edit/metadata-clone.d.ts.map +1 -0
  66. package/dist/in-store/edit/metadata-clone.js +142 -0
  67. package/dist/in-store/edit/metadata-clone.js.map +1 -0
  68. package/dist/in-store/edit/placement-core.d.ts +140 -0
  69. package/dist/in-store/edit/placement-core.d.ts.map +1 -0
  70. package/dist/in-store/edit/placement-core.js +317 -0
  71. package/dist/in-store/edit/placement-core.js.map +1 -0
  72. package/dist/in-store/edit/polygon-clip.d.ts +58 -0
  73. package/dist/in-store/edit/polygon-clip.d.ts.map +1 -0
  74. package/dist/in-store/edit/polygon-clip.js +153 -0
  75. package/dist/in-store/edit/polygon-clip.js.map +1 -0
  76. package/dist/in-store/edit/read-profile.d.ts +6 -0
  77. package/dist/in-store/edit/read-profile.d.ts.map +1 -0
  78. package/dist/in-store/edit/read-profile.js +95 -0
  79. package/dist/in-store/edit/read-profile.js.map +1 -0
  80. package/dist/in-store/edit/slab-edit-frame.d.ts +40 -0
  81. package/dist/in-store/edit/slab-edit-frame.d.ts.map +1 -0
  82. package/dist/in-store/edit/slab-edit-frame.js +146 -0
  83. package/dist/in-store/edit/slab-edit-frame.js.map +1 -0
  84. package/dist/in-store/edit/slab-edit.d.ts +112 -0
  85. package/dist/in-store/edit/slab-edit.d.ts.map +1 -0
  86. package/dist/in-store/edit/slab-edit.js +275 -0
  87. package/dist/in-store/edit/slab-edit.js.map +1 -0
  88. package/dist/in-store/edit/slab-opening-carry.d.ts +10 -0
  89. package/dist/in-store/edit/slab-opening-carry.d.ts.map +1 -0
  90. package/dist/in-store/edit/slab-opening-carry.js +65 -0
  91. package/dist/in-store/edit/slab-opening-carry.js.map +1 -0
  92. package/dist/in-store/edit/split-guid.d.ts +29 -0
  93. package/dist/in-store/edit/split-guid.d.ts.map +1 -0
  94. package/dist/in-store/edit/split-guid.js +64 -0
  95. package/dist/in-store/edit/split-guid.js.map +1 -0
  96. package/dist/in-store/edit/split-target.d.ts +90 -0
  97. package/dist/in-store/edit/split-target.d.ts.map +1 -0
  98. package/dist/in-store/edit/split-target.js +116 -0
  99. package/dist/in-store/edit/split-target.js.map +1 -0
  100. package/dist/in-store/edit/target.d.ts +8 -0
  101. package/dist/in-store/edit/target.d.ts.map +1 -0
  102. package/dist/in-store/edit/target.js +5 -0
  103. package/dist/in-store/edit/target.js.map +1 -0
  104. package/dist/in-store/edit/trim-extend-geometry.d.ts +99 -0
  105. package/dist/in-store/edit/trim-extend-geometry.d.ts.map +1 -0
  106. package/dist/in-store/edit/trim-extend-geometry.js +105 -0
  107. package/dist/in-store/edit/trim-extend-geometry.js.map +1 -0
  108. package/dist/in-store/edit/wall-axis-edit.d.ts +16 -0
  109. package/dist/in-store/edit/wall-axis-edit.d.ts.map +1 -0
  110. package/dist/in-store/edit/wall-axis-edit.js +40 -0
  111. package/dist/in-store/edit/wall-axis-edit.js.map +1 -0
  112. package/dist/in-store/edit/wall-edit.d.ts +157 -0
  113. package/dist/in-store/edit/wall-edit.d.ts.map +1 -0
  114. package/dist/in-store/edit/wall-edit.js +276 -0
  115. package/dist/in-store/edit/wall-edit.js.map +1 -0
  116. package/dist/in-store/edit/wall-hosted-cuts.d.ts +35 -0
  117. package/dist/in-store/edit/wall-hosted-cuts.d.ts.map +1 -0
  118. package/dist/in-store/edit/wall-hosted-cuts.js +27 -0
  119. package/dist/in-store/edit/wall-hosted-cuts.js.map +1 -0
  120. package/dist/in-store/edit/wall-opening-reassign.d.ts +18 -0
  121. package/dist/in-store/edit/wall-opening-reassign.d.ts.map +1 -0
  122. package/dist/in-store/edit/wall-opening-reassign.js +50 -0
  123. package/dist/in-store/edit/wall-opening-reassign.js.map +1 -0
  124. package/dist/in-store/element-align.d.ts +13 -0
  125. package/dist/in-store/element-align.d.ts.map +1 -0
  126. package/dist/in-store/element-align.js +90 -0
  127. package/dist/in-store/element-align.js.map +1 -0
  128. package/dist/in-store/element-replacement.d.ts +26 -0
  129. package/dist/in-store/element-replacement.d.ts.map +1 -0
  130. package/dist/in-store/element-replacement.js +68 -0
  131. package/dist/in-store/element-replacement.js.map +1 -0
  132. package/dist/in-store/element-size-edit.d.ts +40 -0
  133. package/dist/in-store/element-size-edit.d.ts.map +1 -0
  134. package/dist/in-store/element-size-edit.js +103 -0
  135. package/dist/in-store/element-size-edit.js.map +1 -0
  136. package/dist/in-store/element-split-axis.d.ts +6 -0
  137. package/dist/in-store/element-split-axis.d.ts.map +1 -0
  138. package/dist/in-store/element-split-axis.js +87 -0
  139. package/dist/in-store/element-split-axis.js.map +1 -0
  140. package/dist/in-store/element-split-joined.d.ts +13 -0
  141. package/dist/in-store/element-split-joined.d.ts.map +1 -0
  142. package/dist/in-store/element-split-joined.js +74 -0
  143. package/dist/in-store/element-split-joined.js.map +1 -0
  144. package/dist/in-store/element-split-placement.d.ts +19 -0
  145. package/dist/in-store/element-split-placement.d.ts.map +1 -0
  146. package/dist/in-store/element-split-placement.js +48 -0
  147. package/dist/in-store/element-split-placement.js.map +1 -0
  148. package/dist/in-store/element-split-slab.d.ts +19 -0
  149. package/dist/in-store/element-split-slab.d.ts.map +1 -0
  150. package/dist/in-store/element-split-slab.js +86 -0
  151. package/dist/in-store/element-split-slab.js.map +1 -0
  152. package/dist/in-store/element-split.d.ts +49 -0
  153. package/dist/in-store/element-split.d.ts.map +1 -0
  154. package/dist/in-store/element-split.js +52 -0
  155. package/dist/in-store/element-split.js.map +1 -0
  156. package/dist/in-store/element-transform-edit.d.ts +33 -0
  157. package/dist/in-store/element-transform-edit.d.ts.map +1 -0
  158. package/dist/in-store/element-transform-edit.js +97 -0
  159. package/dist/in-store/element-transform-edit.js.map +1 -0
  160. package/dist/in-store/element-transform-frames.d.ts +45 -0
  161. package/dist/in-store/element-transform-frames.d.ts.map +1 -0
  162. package/dist/in-store/element-transform-frames.js +121 -0
  163. package/dist/in-store/element-transform-frames.js.map +1 -0
  164. package/dist/in-store/element-transform-joins.d.ts +4 -0
  165. package/dist/in-store/element-transform-joins.d.ts.map +1 -0
  166. package/dist/in-store/element-transform-joins.js +62 -0
  167. package/dist/in-store/element-transform-joins.js.map +1 -0
  168. package/dist/in-store/element-transform-plan.d.ts +38 -0
  169. package/dist/in-store/element-transform-plan.d.ts.map +1 -0
  170. package/dist/in-store/element-transform-plan.js +115 -0
  171. package/dist/in-store/element-transform-plan.js.map +1 -0
  172. package/dist/in-store/element-trim-extend.d.ts +25 -0
  173. package/dist/in-store/element-trim-extend.d.ts.map +1 -0
  174. package/dist/in-store/element-trim-extend.js +97 -0
  175. package/dist/in-store/element-trim-extend.js.map +1 -0
  176. package/dist/in-store/extract-grids.d.ts +7 -17
  177. package/dist/in-store/extract-grids.d.ts.map +1 -1
  178. package/dist/in-store/extract-grids.js +11 -2
  179. package/dist/in-store/extract-grids.js.map +1 -1
  180. package/dist/in-store/grid-column.d.ts +23 -0
  181. package/dist/in-store/grid-column.d.ts.map +1 -0
  182. package/dist/in-store/grid-column.js +73 -0
  183. package/dist/in-store/grid-column.js.map +1 -0
  184. package/dist/in-store/grid-intersection-read.d.ts +10 -0
  185. package/dist/in-store/grid-intersection-read.d.ts.map +1 -0
  186. package/dist/in-store/grid-intersection-read.js +45 -0
  187. package/dist/in-store/grid-intersection-read.js.map +1 -0
  188. package/dist/in-store/grid.d.ts +7 -1
  189. package/dist/in-store/grid.d.ts.map +1 -1
  190. package/dist/in-store/grid.js +12 -2
  191. package/dist/in-store/grid.js.map +1 -1
  192. package/dist/in-store/group-evidence.d.ts +49 -0
  193. package/dist/in-store/group-evidence.d.ts.map +1 -0
  194. package/dist/in-store/group-evidence.js +111 -0
  195. package/dist/in-store/group-evidence.js.map +1 -0
  196. package/dist/in-store/group-graph.d.ts +51 -0
  197. package/dist/in-store/group-graph.d.ts.map +1 -0
  198. package/dist/in-store/group-graph.js +207 -0
  199. package/dist/in-store/group-graph.js.map +1 -0
  200. package/dist/in-store/group.d.ts +34 -0
  201. package/dist/in-store/group.d.ts.map +1 -0
  202. package/dist/in-store/group.js +181 -0
  203. package/dist/in-store/group.js.map +1 -0
  204. package/dist/in-store/host-geometry-frame.d.ts +5 -1
  205. package/dist/in-store/host-geometry-frame.d.ts.map +1 -1
  206. package/dist/in-store/host-geometry-frame.js +58 -10
  207. package/dist/in-store/host-geometry-frame.js.map +1 -1
  208. package/dist/in-store/index.d.ts +7 -0
  209. package/dist/in-store/index.d.ts.map +1 -1
  210. package/dist/in-store/index.js +7 -0
  211. package/dist/in-store/index.js.map +1 -1
  212. package/dist/in-store/linear-profile-frame.d.ts +10 -0
  213. package/dist/in-store/linear-profile-frame.d.ts.map +1 -0
  214. package/dist/in-store/linear-profile-frame.js +17 -0
  215. package/dist/in-store/linear-profile-frame.js.map +1 -0
  216. package/dist/in-store/material.d.ts.map +1 -1
  217. package/dist/in-store/material.js +17 -6
  218. package/dist/in-store/material.js.map +1 -1
  219. package/dist/in-store/member.d.ts.map +1 -1
  220. package/dist/in-store/member.js +3 -7
  221. package/dist/in-store/member.js.map +1 -1
  222. package/dist/in-store/ordinary-element.d.ts +47 -0
  223. package/dist/in-store/ordinary-element.d.ts.map +1 -0
  224. package/dist/in-store/ordinary-element.js +38 -0
  225. package/dist/in-store/ordinary-element.js.map +1 -0
  226. package/dist/in-store/placement-frame.d.ts +5 -17
  227. package/dist/in-store/placement-frame.d.ts.map +1 -1
  228. package/dist/in-store/placement-frame.js +59 -43
  229. package/dist/in-store/placement-frame.js.map +1 -1
  230. package/dist/in-store/resolve-anchor.d.ts +3 -2
  231. package/dist/in-store/resolve-anchor.d.ts.map +1 -1
  232. package/dist/in-store/resolve-anchor.js +7 -5
  233. package/dist/in-store/resolve-anchor.js.map +1 -1
  234. package/dist/in-store/resolve-relations.d.ts +3 -1
  235. package/dist/in-store/resolve-relations.d.ts.map +1 -1
  236. package/dist/in-store/resolve-relations.js +8 -3
  237. package/dist/in-store/resolve-relations.js.map +1 -1
  238. package/dist/in-store/resolve-source.d.ts.map +1 -1
  239. package/dist/in-store/resolve-source.js +10 -3
  240. package/dist/in-store/resolve-source.js.map +1 -1
  241. package/dist/in-store/room-candidates.d.ts +58 -0
  242. package/dist/in-store/room-candidates.d.ts.map +1 -0
  243. package/dist/in-store/room-candidates.js +135 -0
  244. package/dist/in-store/room-candidates.js.map +1 -0
  245. package/dist/in-store/room-creation-plan.d.ts +16 -0
  246. package/dist/in-store/room-creation-plan.d.ts.map +1 -0
  247. package/dist/in-store/room-creation-plan.js +28 -0
  248. package/dist/in-store/room-creation-plan.js.map +1 -0
  249. package/dist/in-store/room-floor-height.d.ts +24 -0
  250. package/dist/in-store/room-floor-height.d.ts.map +1 -0
  251. package/dist/in-store/room-floor-height.js +32 -0
  252. package/dist/in-store/room-floor-height.js.map +1 -0
  253. package/dist/in-store/room-footprint-native.d.ts +19 -0
  254. package/dist/in-store/room-footprint-native.d.ts.map +1 -0
  255. package/dist/in-store/room-footprint-native.js +117 -0
  256. package/dist/in-store/room-footprint-native.js.map +1 -0
  257. package/dist/in-store/room-layout-cache.d.ts +23 -0
  258. package/dist/in-store/room-layout-cache.d.ts.map +1 -0
  259. package/dist/in-store/room-layout-cache.js +84 -0
  260. package/dist/in-store/room-layout-cache.js.map +1 -0
  261. package/dist/in-store/room-layout-core.d.ts +68 -0
  262. package/dist/in-store/room-layout-core.d.ts.map +1 -0
  263. package/dist/in-store/room-layout-core.js +153 -0
  264. package/dist/in-store/room-layout-core.js.map +1 -0
  265. package/dist/in-store/room-population.d.ts +5 -0
  266. package/dist/in-store/room-population.d.ts.map +1 -0
  267. package/dist/in-store/room-population.js +28 -0
  268. package/dist/in-store/room-population.js.map +1 -0
  269. package/dist/in-store/room-space-meshes.d.ts +15 -0
  270. package/dist/in-store/room-space-meshes.d.ts.map +1 -0
  271. package/dist/in-store/room-space-meshes.js +38 -0
  272. package/dist/in-store/room-space-meshes.js.map +1 -0
  273. package/dist/in-store/room-store.d.ts +55 -0
  274. package/dist/in-store/room-store.d.ts.map +1 -0
  275. package/dist/in-store/room-store.js +173 -0
  276. package/dist/in-store/room-store.js.map +1 -0
  277. package/dist/in-store/room-storey-elevation.d.ts +5 -0
  278. package/dist/in-store/room-storey-elevation.d.ts.map +1 -0
  279. package/dist/in-store/room-storey-elevation.js +42 -0
  280. package/dist/in-store/room-storey-elevation.js.map +1 -0
  281. package/dist/in-store/room-storey-frame.d.ts +47 -0
  282. package/dist/in-store/room-storey-frame.d.ts.map +1 -0
  283. package/dist/in-store/room-storey-frame.js +48 -0
  284. package/dist/in-store/room-storey-frame.js.map +1 -0
  285. package/dist/in-store/room-wall-rects.d.ts +117 -0
  286. package/dist/in-store/room-wall-rects.d.ts.map +1 -0
  287. package/dist/in-store/room-wall-rects.js +157 -0
  288. package/dist/in-store/room-wall-rects.js.map +1 -0
  289. package/dist/in-store/schema-attributes.d.ts +3 -3
  290. package/dist/in-store/schema-attributes.d.ts.map +1 -1
  291. package/dist/in-store/schema-attributes.js +9 -7
  292. package/dist/in-store/schema-attributes.js.map +1 -1
  293. package/dist/in-store/slab.d.ts.map +1 -1
  294. package/dist/in-store/slab.js +1 -4
  295. package/dist/in-store/slab.js.map +1 -1
  296. package/dist/in-store/stair-removal.d.ts +17 -0
  297. package/dist/in-store/stair-removal.d.ts.map +1 -0
  298. package/dist/in-store/stair-removal.js +134 -0
  299. package/dist/in-store/stair-removal.js.map +1 -0
  300. package/dist/in-store/storey-plan-frame.d.ts +2 -1
  301. package/dist/in-store/storey-plan-frame.d.ts.map +1 -1
  302. package/dist/in-store/storey-plan-frame.js +20 -11
  303. package/dist/in-store/storey-plan-frame.js.map +1 -1
  304. package/dist/in-store/storey-reassignment-plan.d.ts +53 -0
  305. package/dist/in-store/storey-reassignment-plan.d.ts.map +1 -0
  306. package/dist/in-store/storey-reassignment-plan.js +237 -0
  307. package/dist/in-store/storey-reassignment-plan.js.map +1 -0
  308. package/dist/in-store/storey-reassignment.d.ts +8 -0
  309. package/dist/in-store/storey-reassignment.d.ts.map +1 -0
  310. package/dist/in-store/storey-reassignment.js +52 -0
  311. package/dist/in-store/storey-reassignment.js.map +1 -0
  312. package/dist/in-store/trim-extend-plan.d.ts +27 -0
  313. package/dist/in-store/trim-extend-plan.d.ts.map +1 -0
  314. package/dist/in-store/trim-extend-plan.js +49 -0
  315. package/dist/in-store/trim-extend-plan.js.map +1 -0
  316. package/dist/in-store/wall-join-edit.d.ts +0 -17
  317. package/dist/in-store/wall-join-edit.d.ts.map +1 -1
  318. package/dist/in-store/wall-join-edit.js +41 -7
  319. package/dist/in-store/wall-join-edit.js.map +1 -1
  320. package/dist/in-store/wall-section-edit.d.ts +16 -0
  321. package/dist/in-store/wall-section-edit.d.ts.map +1 -0
  322. package/dist/in-store/wall-section-edit.js +75 -0
  323. package/dist/in-store/wall-section-edit.js.map +1 -0
  324. package/dist/in-store/wall-size-edit.d.ts +29 -0
  325. package/dist/in-store/wall-size-edit.d.ts.map +1 -0
  326. package/dist/in-store/wall-size-edit.js +65 -0
  327. package/dist/in-store/wall-size-edit.js.map +1 -0
  328. package/dist/index.d.ts +24 -0
  329. package/dist/index.d.ts.map +1 -1
  330. package/dist/index.js +23 -0
  331. package/dist/index.js.map +1 -1
  332. package/dist/landxml/profile-geometry.d.ts +10 -0
  333. package/dist/landxml/profile-geometry.d.ts.map +1 -1
  334. package/dist/landxml/profile-geometry.js +16 -1
  335. package/dist/landxml/profile-geometry.js.map +1 -1
  336. package/package.json +9 -8
@@ -0,0 +1,153 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ const EPS = 1e-9;
5
+ /**
6
+ * Signed perpendicular distance of `p` to the directed line through
7
+ * `a → b`. Positive means `p` is to the LEFT of A→B in standard
8
+ * math coords (y-up) — i.e. the side reached by rotating the A→B
9
+ * direction 90° counter-clockwise.
10
+ */
11
+ function signedDistance(a, b, p) {
12
+ // Standard 2D cross product (b - a) × (p - a).
13
+ return (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0]);
14
+ }
15
+ /**
16
+ * Linear interpolation between two polygon vertices at the cut line.
17
+ * `da`, `db` are signed distances of `a` and `b` from the line; the
18
+ * intersection sits where the signed distance crosses zero.
19
+ */
20
+ function intersectEdge(a, b, da, db) {
21
+ const t = da / (da - db); // never 0/0 because callers ensure signs differ
22
+ return [a[0] + t * (b[0] - a[0]), a[1] + t * (b[1] - a[1])];
23
+ }
24
+ /**
25
+ * Clip a polygon to one side of the cut line. `keep` selects which
26
+ * side to retain: `'positive'` keeps vertices with signed distance
27
+ * > 0 (left of A→B); `'negative'` keeps vertices with signed
28
+ * distance < 0 (right). On-line vertices (|d| < EPS) belong to
29
+ * both halves and are emitted unchanged.
30
+ *
31
+ * Standard Sutherland-Hodgman: walk each edge of the input polygon,
32
+ * decide whether to emit the current vertex and/or an intersection
33
+ * with the cut line based on which side current and previous
34
+ * vertices are on.
35
+ */
36
+ function clipPolygonHalfPlane(polygon, a, b, keep) {
37
+ if (polygon.length === 0)
38
+ return [];
39
+ const out = [];
40
+ const sign = keep === 'positive' ? 1 : -1;
41
+ const pushUnique = (p) => {
42
+ // Skip duplicate emits — the on-line edge case (prev outside,
43
+ // curr on the line) would otherwise emit the intersection AND
44
+ // curr, which are the same point. Cheap O(1) check against the
45
+ // most recent vertex; the polygon body itself is allowed to
46
+ // have repeated adjacent vertices in pathological input but we
47
+ // don't want to manufacture them.
48
+ if (out.length > 0) {
49
+ const last = out[out.length - 1];
50
+ if (Math.abs(last[0] - p[0]) < EPS && Math.abs(last[1] - p[1]) < EPS)
51
+ return;
52
+ }
53
+ out.push(p);
54
+ };
55
+ let prev = polygon[polygon.length - 1];
56
+ let prevD = signedDistance(a, b, prev) * sign;
57
+ for (const curr of polygon) {
58
+ const currD = signedDistance(a, b, curr) * sign;
59
+ if (currD >= -EPS) {
60
+ // Current vertex is inside (or on the line).
61
+ if (prevD < -EPS) {
62
+ // Crossing into the half-plane — emit the intersection.
63
+ pushUnique(intersectEdge(prev, curr, prevD, currD));
64
+ }
65
+ pushUnique(curr);
66
+ }
67
+ else if (prevD >= -EPS) {
68
+ // Crossing out of the half-plane — emit the intersection.
69
+ pushUnique(intersectEdge(prev, curr, prevD, currD));
70
+ }
71
+ // Else both outside — skip.
72
+ prev = curr;
73
+ prevD = currD;
74
+ }
75
+ // The pushUnique guard runs against the previous push; the
76
+ // wrap-around (last vs first) can also produce a dup when the
77
+ // polygon closes on a near-coincident pair. Trim once.
78
+ if (out.length > 1) {
79
+ const first = out[0];
80
+ const last = out[out.length - 1];
81
+ if (Math.abs(last[0] - first[0]) < EPS && Math.abs(last[1] - first[1]) < EPS) {
82
+ out.pop();
83
+ }
84
+ }
85
+ return out;
86
+ }
87
+ /**
88
+ * Split a polygon into two halves by a cut line.
89
+ *
90
+ * Inputs:
91
+ * - `polygon` — outer curve as an ordered list of 2D vertices
92
+ * (CW or CCW; the algorithm is orientation-independent).
93
+ * First vertex should NOT repeat at the end.
94
+ * - `a`, `b` — two points defining the cut line. The line
95
+ * extends infinitely in both directions through these points,
96
+ * so the user-clicked endpoints don't need to lie on the
97
+ * polygon edge.
98
+ *
99
+ * Returns `{ ok: true, left, right }` when both halves are valid
100
+ * polygons (≥ 3 vertices). Otherwise returns `{ ok: false, reason }`.
101
+ */
102
+ export function clipPolygonByLine(polygon, a, b) {
103
+ if (polygon.length < 3) {
104
+ return { ok: false, reason: 'Polygon must have at least 3 vertices' };
105
+ }
106
+ const dx = b[0] - a[0];
107
+ const dy = b[1] - a[1];
108
+ if (Math.hypot(dx, dy) < EPS) {
109
+ return { ok: false, reason: 'Cut endpoints are coincident' };
110
+ }
111
+ // Count how many vertices land strictly on each side. If all
112
+ // vertices are on one side, the cut line misses the polygon.
113
+ let pos = 0;
114
+ let neg = 0;
115
+ for (const p of polygon) {
116
+ const d = signedDistance(a, b, p);
117
+ if (d > EPS)
118
+ pos++;
119
+ else if (d < -EPS)
120
+ neg++;
121
+ }
122
+ if (pos === 0 || neg === 0) {
123
+ return { ok: false, reason: 'Cut line does not cross the polygon' };
124
+ }
125
+ const left = clipPolygonHalfPlane(polygon, a, b, 'positive');
126
+ const right = clipPolygonHalfPlane(polygon, a, b, 'negative');
127
+ if (left.length < 3 || right.length < 3) {
128
+ return { ok: false, reason: 'Cut produces a degenerate half (< 3 vertices)' };
129
+ }
130
+ return { ok: true, left, right };
131
+ }
132
+ /**
133
+ * Test helper: is `p` strictly inside `polygon` (ray-cast). Used by
134
+ * the slab-split tool to figure out which half the user clicked on
135
+ * after committing the cut, so we can move selection to that half.
136
+ */
137
+ export function pointInPolygon(polygon, p) {
138
+ if (polygon.length < 3)
139
+ return false;
140
+ let inside = false;
141
+ let j = polygon.length - 1;
142
+ for (let i = 0; i < polygon.length; i++) {
143
+ const a = polygon[i];
144
+ const b = polygon[j];
145
+ const intersects = (a[1] > p[1]) !== (b[1] > p[1]) &&
146
+ p[0] < ((b[0] - a[0]) * (p[1] - a[1])) / (b[1] - a[1] + EPS) + a[0];
147
+ if (intersects)
148
+ inside = !inside;
149
+ j = i;
150
+ }
151
+ return inside;
152
+ }
153
+ //# sourceMappingURL=polygon-clip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polygon-clip.js","sourceRoot":"","sources":["../../../src/in-store/edit/polygon-clip.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type ProfileSection } from '../profile.js';
2
+ /** Whether `stepType` names one of the nine profile classes the picker writes. */
3
+ export declare function isSectionProfileClass(stepType: string | null | undefined): boolean;
4
+ /** Read a profile in metres without dropping geometry when it is rebuilt. */
5
+ export declare function sectionFromProfile(stepType: string, attributes: readonly unknown[], lengthUnitScale: number, schemaVersion?: string): ProfileSection | null;
6
+ //# sourceMappingURL=read-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-profile.d.ts","sourceRoot":"","sources":["../../../src/in-store/edit/read-profile.ts"],"names":[],"mappings":"AAiBA,OAAO,EAA0B,KAAK,cAAc,EAA2B,MAAM,eAAe,CAAC;AAsBrG,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAElF;AAQD,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,SAAS,OAAO,EAAE,EAC9B,eAAe,EAAE,MAAM,EACvB,aAAa,SAAS,GACrB,cAAc,GAAG,IAAI,CAwCvB"}
@@ -0,0 +1,95 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { getCanonicalEntityName } from '@ifc-lite/parser';
5
+ /**
6
+ * A profile entity read back as a `ProfileSection` (charter #6232, D2): the
7
+ * inverse of `emitProfileSection`, for the inspector's Profile section, for
8
+ * split (a piece of an I-beam is an I-beam) and for one undo of a change.
9
+ *
10
+ * Attribute positions come from the model's schema registry. Supported optional
11
+ * radii survive an edit or split; a populated geometry attribute the shared
12
+ * builder cannot reproduce refuses editing rather than silently changing the
13
+ * section. Invalid dimensions also read as null.
14
+ */
15
+ import { fromNativeLength } from '../anchor.js';
16
+ import { validateProfileSection } from '../profile.js';
17
+ import { getAttributeNamesAcrossSchemas, getSchemaRegistryForVersion } from '@ifc-lite/parser';
18
+ /** IFC class (upper case, as STEP stores it) to section type and the attribute names from index 3. */
19
+ const LAYOUT = {
20
+ IFCRECTANGLEPROFILEDEF: { type: 'Rectangle', names: ['XDim', 'YDim'] },
21
+ IFCISHAPEPROFILEDEF: { type: 'I', names: ['OverallWidth', 'OverallDepth', 'WebThickness', 'FlangeThickness'] },
22
+ IFCLSHAPEPROFILEDEF: { type: 'L', names: ['Depth', 'Width', 'Thickness'] },
23
+ IFCTSHAPEPROFILEDEF: { type: 'T', names: ['Depth', 'FlangeWidth', 'WebThickness', 'FlangeThickness'] },
24
+ IFCUSHAPEPROFILEDEF: { type: 'U', names: ['Depth', 'FlangeWidth', 'WebThickness', 'FlangeThickness'] },
25
+ IFCCSHAPEPROFILEDEF: { type: 'C', names: ['Depth', 'Width', 'WallThickness', 'Girth'] },
26
+ IFCCIRCLEPROFILEDEF: { type: 'Circle', names: ['Radius'] },
27
+ IFCRECTANGLEHOLLOWPROFILEDEF: { type: 'RectangleHollow', names: ['XDim', 'YDim', 'WallThickness'] },
28
+ IFCCIRCLEHOLLOWPROFILEDEF: { type: 'CircleHollow', names: ['Radius', 'WallThickness'] },
29
+ };
30
+ /** A REAL attribute: a plain number, or the `{ real }` wrapper the overlay keeps a whole-number REAL in. */
31
+ function realOf(raw) {
32
+ const value = typeof raw === 'object' && raw !== null && 'real' in raw ? raw.real : raw;
33
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
34
+ }
35
+ /** Whether `stepType` names one of the nine profile classes the picker writes. */
36
+ export function isSectionProfileClass(stepType) {
37
+ return stepType !== null && stepType !== undefined && stepType.toUpperCase() in LAYOUT;
38
+ }
39
+ /** Optional geometry the shared ProfileSection/emitProfileSection can reproduce. */
40
+ const OPTIONAL = {
41
+ I: ['FilletRadius'], L: ['FilletRadius'], T: ['FilletRadius'], U: ['FilletRadius'],
42
+ C: ['InternalFilletRadius'], RectangleHollow: ['InnerFilletRadius', 'OuterFilletRadius'],
43
+ };
44
+ /** Read a profile in metres without dropping geometry when it is rebuilt. */
45
+ export function sectionFromProfile(stepType, attributes, lengthUnitScale, schemaVersion = 'IFC4') {
46
+ const upper = stepType.toUpperCase();
47
+ const layout = LAYOUT[upper];
48
+ if (!layout || !Number.isFinite(lengthUnitScale) || lengthUnitScale <= 0)
49
+ return null;
50
+ let declared;
51
+ if (schemaVersion === 'IFC2X3' || schemaVersion === 'IFC4' || schemaVersion === 'IFC4X3') {
52
+ const registry = getSchemaRegistryForVersion(schemaVersion);
53
+ const name = getCanonicalEntityName(registry, upper);
54
+ declared = name ? registry.entities[name].allAttributes?.map((attribute) => attribute.name) : undefined;
55
+ }
56
+ else if (schemaVersion === 'IFC5' && layout.type === 'Rectangle') {
57
+ // IFCX adapts positional attributes using this same canonical name list.
58
+ // Basic rectangular authoring remains supported; profiled emission refuses IFC5.
59
+ declared = getAttributeNamesAcrossSchemas(stepType);
60
+ }
61
+ if (!declared || declared.length === 0)
62
+ return null;
63
+ // Extra positional values cannot be recreated by a builder using this registry.
64
+ if (attributes.slice(declared.length).some((value) => value != null))
65
+ return null;
66
+ const section = { Type: layout.type };
67
+ const optional = OPTIONAL[layout.type] ?? [];
68
+ for (let i = 3; i < declared.length; i++) {
69
+ const field = declared[i];
70
+ const required = layout.names.includes(field);
71
+ const raw = attributes[i];
72
+ if (raw == null && !required)
73
+ continue;
74
+ // The builder has no representation of slopes, edge radii or schema-specific
75
+ // gravity offsets: refusing is safer than authoring a different cross-section.
76
+ if (!required && !optional.includes(field))
77
+ return null;
78
+ const value = realOf(raw);
79
+ if (value === null || (required ? value <= 0 : value < 0))
80
+ return null;
81
+ section[field] = fromNativeLength({ lengthUnitScale }, value);
82
+ }
83
+ const result = section;
84
+ try {
85
+ validateProfileSection(result, 'profile');
86
+ }
87
+ catch (error) {
88
+ // Malformed file dimensions are a normal refusal, not an editable section.
89
+ if (error instanceof Error)
90
+ return null;
91
+ throw error;
92
+ }
93
+ return result;
94
+ }
95
+ //# sourceMappingURL=read-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-profile.js","sourceRoot":"","sources":["../../../src/in-store/edit/read-profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { IfcDataStore } from '@ifc-lite/parser';
2
+ import type { MutablePropertyView, StoreEditor } from '@ifc-lite/mutations';
3
+ /**
4
+ * Null when the element is not a vertical extrusion of its plan outline;
5
+ * otherwise the NATIVE-unit height of the extrusion's bottom above the
6
+ * element placement's origin.
7
+ */
8
+ export declare function slabExtrusionBase(dataStore: IfcDataStore, view: MutablePropertyView, editor: StoreEditor, elementAxisPlacementId: number, solidAttrs: readonly unknown[], depth: number): number | null;
9
+ /**
10
+ * {@link slabExtrusionBase} plus the direction the depth runs: `up` is true
11
+ * when the extrusion grows upward from the solid's profile plane (the layout
12
+ * the builders write and AC20's `Bodenplatte` has), false when the solid or
13
+ * its extrusion direction is flipped so it grows downward from it. Push /
14
+ * pull needs it: a bigger depth moves the top face in the first case and the
15
+ * underside in the second (#6232 C4).
16
+ */
17
+ export declare function slabExtrusionFrame(dataStore: IfcDataStore, view: MutablePropertyView, editor: StoreEditor, elementAxisPlacementId: number, solidAttrs: readonly unknown[], depth: number): {
18
+ base: number;
19
+ up: boolean;
20
+ } | null;
21
+ /**
22
+ * A 2D rigid transform mapping a profile-coordinate point into the
23
+ * solid's local plan (XY). Built from the `IfcExtrudedAreaSolid`'s
24
+ * `Position` (an `IfcAxis2Placement3D`), it folds in the in-place
25
+ * translation + rotation that real-world authoring tools bake there.
26
+ * In-store-built slabs carry an identity Position, so the resolver
27
+ * defaults to the identity transform for them.
28
+ */
29
+ export type Xform2D = (p: [number, number]) => [number, number];
30
+ /**
31
+ * Build the plan-space transform for an `IfcExtrudedAreaSolid.Position`.
32
+ * The profile lives in the placement's local XY plane; we map a profile
33
+ * point `(px, py)` to `origin + px·X + py·Y` and keep the XY components
34
+ * (the footprint is the plan). X comes from RefDirection (orthonormalised
35
+ * against the Axis/Z), Y = Z × X — matching the IFC placement convention,
36
+ * including axis flips (e.g. Axis `(0,0,-1)`, RefDirection `(-1,0,0)`).
37
+ * Returns identity when the placement is absent or degenerate.
38
+ */
39
+ export declare function resolveSolidPositionXform(dataStore: IfcDataStore, view: MutablePropertyView, editor: StoreEditor, placementId: number | null): Xform2D;
40
+ //# sourceMappingURL=slab-edit-frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slab-edit-frame.d.ts","sourceRoot":"","sources":["../../../src/in-store/edit/slab-edit-frame.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgB5E;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,WAAW,EACnB,sBAAsB,EAAE,MAAM,EAC9B,UAAU,EAAE,SAAS,OAAO,EAAE,EAC9B,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAEf;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,WAAW,EACnB,sBAAsB,EAAE,MAAM,EAC9B,UAAU,EAAE,SAAS,OAAO,EAAE,EAC9B,KAAK,EAAE,MAAM,GACZ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA0BtC;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAehE;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,OAAO,CAiDT"}
@@ -0,0 +1,146 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * The frame of a slab-like element's extrusion: the solid position's plan
6
+ * transform the footprint is read through, and (#6233) whether the element
7
+ * is a vertical extrusion of that plan outline at all.
8
+ *
9
+ * The slab chain reads a FOOTPRINT in plan: the element placement's origin
10
+ * plus the solid position's plan transform (which may flip or turn the
11
+ * profile about Z). A split re-authors pieces from that plan outline, so it
12
+ * is only faithful when the element really is a vertical extrusion of that
13
+ * outline:
14
+ * - the element placement is not rotated (the chain reads only its origin);
15
+ * - the solid position's Axis is vertical (a tilted roof slab is not a
16
+ * plan outline — AC20's `Dach-1` extrudes along (0, 0.5, 0.866));
17
+ * - the extrusion direction is vertical in the solid's frame.
18
+ * Otherwise the element is refused, rather than cut into flat slabs.
19
+ *
20
+ * For an accepted element it also returns where the extrusion starts,
21
+ * above the placement origin: AC20's `Bodenplatte` hangs 0.2 m below its
22
+ * placement (solid Location z = -0.2), which a re-authored piece must keep.
23
+ */
24
+ import { firstProjAxis } from '@ifc-lite/data';
25
+ import { axis3d } from '../host-geometry-frame.js';
26
+ import { asCoordinateTriple, asDirectionRatios, asExpressIdRef, readAttributes } from './placement-core.js';
27
+ const EPS = 1e-6;
28
+ /** A unit-normalised direction, or `fallback` when the slot is `$`; null when unreadable. */
29
+ function direction(read, id, fallback) {
30
+ if (id == null)
31
+ return fallback;
32
+ const d = asDirectionRatios(read(asExpressIdRef(id))?.[0]);
33
+ const len = d ? Math.hypot(d[0], d[1], d[2]) : 0;
34
+ return d && len > EPS ? [d[0] / len, d[1] / len, d[2] / len] : null;
35
+ }
36
+ /**
37
+ * Null when the element is not a vertical extrusion of its plan outline;
38
+ * otherwise the NATIVE-unit height of the extrusion's bottom above the
39
+ * element placement's origin.
40
+ */
41
+ export function slabExtrusionBase(dataStore, view, editor, elementAxisPlacementId, solidAttrs, depth) {
42
+ return slabExtrusionFrame(dataStore, view, editor, elementAxisPlacementId, solidAttrs, depth)?.base ?? null;
43
+ }
44
+ /**
45
+ * {@link slabExtrusionBase} plus the direction the depth runs: `up` is true
46
+ * when the extrusion grows upward from the solid's profile plane (the layout
47
+ * the builders write and AC20's `Bodenplatte` has), false when the solid or
48
+ * its extrusion direction is flipped so it grows downward from it. Push /
49
+ * pull needs it: a bigger depth moves the top face in the first case and the
50
+ * underside in the second (#6232 C4).
51
+ */
52
+ export function slabExtrusionFrame(dataStore, view, editor, elementAxisPlacementId, solidAttrs, depth) {
53
+ const read = (id) => (id === null ? null : readAttributes(dataStore, view, editor, id));
54
+ const reader = {
55
+ entity(id) {
56
+ const attributes = read(id), type = editor.getEntityType(id);
57
+ return attributes && type ? { type, attributes } : null;
58
+ },
59
+ };
60
+ const placement = axis3d(reader, elementAxisPlacementId);
61
+ // #6589: a cosine-only check admits rotations of order sqrt(EPS).
62
+ // Compare the actual orthonormal frame components, including the small
63
+ // transverse components that the origin-only plan reader cannot retain.
64
+ if (!placement || Math.abs(placement.x[0] - 1) > EPS || Math.abs(placement.x[1]) > EPS
65
+ || Math.abs(placement.x[2]) > EPS || Math.abs(placement.z[0]) > EPS
66
+ || Math.abs(placement.z[1]) > EPS || Math.abs(placement.z[2] - 1) > EPS)
67
+ return null;
68
+ const position = axis3d(reader, solidAttrs[1]);
69
+ if (!position || Math.abs(position.z[0]) > EPS || Math.abs(position.z[1]) > EPS
70
+ || Math.abs(Math.abs(position.z[2]) - 1) > EPS)
71
+ return null;
72
+ const extrusion = direction(read, solidAttrs[2], [0, 0, 1]);
73
+ if (!extrusion || Math.abs(extrusion[0]) > EPS || Math.abs(extrusion[1]) > EPS
74
+ || Math.abs(Math.abs(extrusion[2]) - 1) > EPS)
75
+ return null;
76
+ // Upward (+1) or downward (-1) in the element frame.
77
+ const up = Math.sign(position.z[2] * extrusion[2]);
78
+ return { base: position.o[2] + Math.min(0, up * depth), up: up > 0 };
79
+ }
80
+ const IDENTITY_XFORM2D = (p) => [p[0], p[1]];
81
+ function readDirection(dataStore, view, editor, id) {
82
+ if (id === null)
83
+ return null;
84
+ const attrs = readAttributes(dataStore, view, editor, id);
85
+ return attrs ? asDirectionRatios(attrs[0]) : null;
86
+ }
87
+ /**
88
+ * Build the plan-space transform for an `IfcExtrudedAreaSolid.Position`.
89
+ * The profile lives in the placement's local XY plane; we map a profile
90
+ * point `(px, py)` to `origin + px·X + py·Y` and keep the XY components
91
+ * (the footprint is the plan). X comes from RefDirection (orthonormalised
92
+ * against the Axis/Z), Y = Z × X — matching the IFC placement convention,
93
+ * including axis flips (e.g. Axis `(0,0,-1)`, RefDirection `(-1,0,0)`).
94
+ * Returns identity when the placement is absent or degenerate.
95
+ */
96
+ export function resolveSolidPositionXform(dataStore, view, editor, placementId) {
97
+ if (placementId === null)
98
+ return IDENTITY_XFORM2D;
99
+ const attrs = readAttributes(dataStore, view, editor, placementId);
100
+ if (!attrs)
101
+ return IDENTITY_XFORM2D;
102
+ // IfcAxis2Placement3D: [0] Location · [1] Axis (Z) · [2] RefDirection (X).
103
+ const locId = asExpressIdRef(attrs[0]);
104
+ let ox = 0;
105
+ let oy = 0;
106
+ if (locId !== null) {
107
+ const locAttrs = readAttributes(dataStore, view, editor, locId);
108
+ const c = locAttrs ? asCoordinateTriple(locAttrs[0]) : null;
109
+ if (c) {
110
+ ox = c[0];
111
+ oy = c[1];
112
+ }
113
+ }
114
+ // IfcDirection ratios are NOT guaranteed unit length, so normalise Z
115
+ // before using it as a basis vector — otherwise the Gram-Schmidt
116
+ // projection (which assumes |Z|=1) and Y = Z × X both pick up |Z| as a
117
+ // stray scale factor, skewing the footprint away from the rendered mesh
118
+ // for files with e.g. Axis=(0,0,2). The Rust profile extractor
119
+ // normalises the same placement.
120
+ const rawZ = readDirection(dataStore, view, editor, asExpressIdRef(attrs[1])) ?? [0, 0, 1];
121
+ const zlen = Math.hypot(rawZ[0], rawZ[1], rawZ[2]);
122
+ if (zlen < 1e-9)
123
+ return IDENTITY_XFORM2D;
124
+ const z = [rawZ[0] / zlen, rawZ[1] / zlen, rawZ[2] / zlen];
125
+ // A `$` RefDirection takes the renderer's fill, not world X as-is (#5922).
126
+ const refX = readDirection(dataStore, view, editor, asExpressIdRef(attrs[2])) ?? firstProjAxis(z);
127
+ // Orthonormalise X against the unit Z (Gram-Schmidt), then Y = Z × X.
128
+ const dot = refX[0] * z[0] + refX[1] * z[1] + refX[2] * z[2];
129
+ let xv = [
130
+ refX[0] - dot * z[0],
131
+ refX[1] - dot * z[1],
132
+ refX[2] - dot * z[2],
133
+ ];
134
+ const xlen = Math.hypot(xv[0], xv[1], xv[2]);
135
+ if (xlen < 1e-9)
136
+ return IDENTITY_XFORM2D;
137
+ xv = [xv[0] / xlen, xv[1] / xlen, xv[2] / xlen];
138
+ // Z and X are now orthonormal, so Y = Z × X is already unit length.
139
+ const yv = [
140
+ z[1] * xv[2] - z[2] * xv[1],
141
+ z[2] * xv[0] - z[0] * xv[2],
142
+ z[0] * xv[1] - z[1] * xv[0],
143
+ ];
144
+ return (p) => [ox + p[0] * xv[0] + p[1] * yv[0], oy + p[0] * xv[1] + p[1] * yv[1]];
145
+ }
146
+ //# sourceMappingURL=slab-edit-frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slab-edit-frame.js","sourceRoot":"","sources":["../../../src/in-store/edit/slab-edit-frame.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Footprint reader + cut helpers for slab-like elements (IfcSlab,
3
+ * IfcRoof, IfcPlate, IfcSpace) shaped by the in-store builders in
4
+ * `@ifc-lite/create`. The shared shape is:
5
+ *
6
+ * IfcExtrudedAreaSolid
7
+ * ├── SweptArea : IfcRectangleProfileDef (W × D) — rectangle mode
8
+ * │ OR IfcArbitraryClosedProfileDef → IfcPolyline — polygon mode
9
+ * └── Depth : thickness along +Z (storey-local)
10
+ *
11
+ * The "footprint" is the profile polygon in storey-local 2D (XY).
12
+ * For rectangle mode we derive it from (placementOrigin, W, D); for
13
+ * polygon mode we read the polyline's vertex list.
14
+ *
15
+ * The split workflow:
16
+ *
17
+ * 1. user clicks twice on the slab (in storey-local 2D)
18
+ * 2. polygon-clip cuts the footprint into two halves
19
+ * 3. caller builds two fresh slabs via `addSlab` polygon-mode
20
+ * (cleaner than trying to detect "rectangle still fits" — most
21
+ * cuts produce non-rectangular halves)
22
+ * 4. source is tombstoned + its mesh hidden
23
+ *
24
+ * Source-buffer slabs with unusual representations (mapped shapes,
25
+ * tessellated faces, …) refuse with a clear reason and the caller's
26
+ * Split tool stays armed.
27
+ */
28
+ import type { IfcDataStore } from '@ifc-lite/parser';
29
+ import type { MutablePropertyView, StoreEditor } from '@ifc-lite/mutations';
30
+ import { type Point2D } from './polygon-clip.js';
31
+ /**
32
+ * Slab-like element types this module handles. Matches the STEP
33
+ * storage form (`IFCSLAB`, …) so the slice's split action can
34
+ * dispatch to the right `addSlab` / `addRoof` / `addPlate` /
35
+ * `addSpace` follow-up. (Roof/plate/space are added in subsequent
36
+ * commits but their representation is identical, so this resolver
37
+ * already accepts them.)
38
+ */
39
+ export type SlabLikeType = 'IfcSlab' | 'IfcRoof' | 'IfcPlate' | 'IfcSpace';
40
+ export interface SlabEditChain {
41
+ /** STEP type name, for the slice's dispatch. */
42
+ elementType: SlabLikeType;
43
+ /** Placement origin (storey-local). The footprint polygon is in
44
+ * world-XY space, with the origin already added. */
45
+ placementOrigin: [number, number, number];
46
+ /**
47
+ * Storey-local height where the extrusion starts, or null when the element
48
+ * is not a vertical extrusion of its plan outline (`slab-edit-frame.ts`):
49
+ * the footprint still reads, but a split must refuse it (#6233).
50
+ */
51
+ baseElevation: number | null;
52
+ /**
53
+ * Whether the depth grows upward from the profile plane (the builders'
54
+ * layout) or the slab hangs down from it. Meaningful only when
55
+ * `baseElevation` is not null; true otherwise.
56
+ */
57
+ extrusionUp: boolean;
58
+ /** Footprint polygon as an ordered list of 2D vertices (storey-
59
+ * local world XY). First vertex does NOT repeat at the end. */
60
+ footprint: Point2D[];
61
+ /** IfcExtrudedAreaSolid id — holds the thickness on attr 3. */
62
+ extrudedSolidId: number;
63
+ /** Current extrusion thickness (metres along +Z). */
64
+ thickness: number;
65
+ /**
66
+ * Whether the source profile was a rectangle (XDim/YDim) or an
67
+ * arbitrary polygon (IfcArbitraryClosedProfileDef → IfcPolyline).
68
+ * Surface for telemetry; not required by the split flow.
69
+ */
70
+ profileKind: 'rectangle' | 'polygon';
71
+ }
72
+ /**
73
+ * Resolve the slab chain (placement + footprint + extrusion). Works
74
+ * for IfcSlab / IfcRoof / IfcPlate / IfcSpace whose representation
75
+ * matches the in-store builder shape; null otherwise.
76
+ *
77
+ * `lengthUnitScale` is the model's native-unit → metre factor (e.g.
78
+ * `0.001` for a millimetre file). Raw STEP coordinate reads are in
79
+ * native units, but the rest of the split flow — raycast cut points,
80
+ * preview meshes, selection hit-tests — lives in metres, so the
81
+ * resolved footprint/thickness are scaled to match. Authored overlay
82
+ * entities are scaled too: the in-store builders convert their metre
83
+ * params to the file's native unit (`toNativePoint3` / `toNativeLength`),
84
+ * so an authored slab in a millimetre file stores millimetres (#6233).
85
+ */
86
+ export declare function resolveSlabEditChain(dataStore: IfcDataStore, view: MutablePropertyView, editor: StoreEditor, expressId: number, lengthUnitScale?: number,
87
+ /** A validated extrusion beneath an envelope's clipping results. */
88
+ bodyItemId?: number): SlabEditChain | null;
89
+ export interface SlabSplitResult {
90
+ ok: true;
91
+ leftFootprint: Point2D[];
92
+ rightFootprint: Point2D[];
93
+ thickness: number;
94
+ placementOrigin: [number, number, number];
95
+ elementType: SlabLikeType;
96
+ }
97
+ export type SlabSplitOutcome = SlabSplitResult | {
98
+ ok: false;
99
+ reason: string;
100
+ };
101
+ /**
102
+ * Pure split-geometry helper. Clips the slab's footprint by a cut
103
+ * line (defined by two storey-local 2D points) and returns the two
104
+ * halves so the caller can build new slabs with `addSlab`. Both
105
+ * halves carry the source's thickness + storey placement; only the
106
+ * outer-curve polygon changes.
107
+ *
108
+ * Returns the underlying polygon-clip reason on failure so the UI
109
+ * can surface "Cut line does not cross the slab" verbatim.
110
+ */
111
+ export declare function computeSlabSplitGeometry(chain: SlabEditChain, cutA: Point2D, cutB: Point2D): SlabSplitOutcome;
112
+ //# sourceMappingURL=slab-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slab-edit.d.ts","sourceRoot":"","sources":["../../../src/in-store/edit/slab-edit.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAO5E,OAAO,EAAqB,KAAK,OAAO,EAA0B,MAAM,mBAAmB,CAAC;AAI5F;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAa3E,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,WAAW,EAAE,YAAY,CAAC;IAC1B;wDACoD;IACpD,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C;;;;OAIG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;OAIG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;mEAC+D;IAC/D,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,+DAA+D;IAC/D,eAAe,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;CACtC;AA6GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,eAAe,SAAI;AACnB,oEAAoE;AACpE,UAAU,CAAC,EAAE,MAAM,GAClB,aAAa,GAAG,IAAI,CAiHtB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,IAAI,CAAC;IACT,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,cAAc,EAAE,OAAO,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,WAAW,EAAE,YAAY,CAAC;CAC3B;AAED,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,OAAO,GACZ,gBAAgB,CAalB"}