@collabdt/core 0.0.50 → 0.0.53

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 (1008) hide show
  1. package/NOTICE +1021 -0
  2. package/README.md +32 -4
  3. package/dist/core/components/AppSidebarContent.d.ts.map +1 -1
  4. package/dist/core/components/AppSidebarContent.js.map +1 -1
  5. package/dist/core/components/ConfirmDialog.d.ts.map +1 -1
  6. package/dist/core/components/ConfirmDialog.js.map +1 -1
  7. package/dist/core/components/DataTableSkeleton.d.ts.map +1 -1
  8. package/dist/core/components/DataTableSkeleton.js.map +1 -1
  9. package/dist/core/components/LanguageSwitch.d.ts.map +1 -1
  10. package/dist/core/components/LanguageSwitch.js.map +1 -1
  11. package/dist/core/components/Logo.d.ts.map +1 -1
  12. package/dist/core/components/Logo.js.map +1 -1
  13. package/dist/core/components/Toolbar.d.ts.map +1 -1
  14. package/dist/core/components/Toolbar.js.map +1 -1
  15. package/dist/core/components/ToolbarBody.d.ts.map +1 -1
  16. package/dist/core/components/ToolbarBody.js.map +1 -1
  17. package/dist/core/components/ToolbarSubmenu.d.ts.map +1 -1
  18. package/dist/core/components/ToolbarSubmenu.js.map +1 -1
  19. package/dist/core/components/TopNavigationBar.d.ts.map +1 -1
  20. package/dist/core/components/TopNavigationBar.js.map +1 -1
  21. package/dist/core/components/authentication/AuthPage.d.ts.map +1 -1
  22. package/dist/core/components/authentication/AuthPage.js.map +1 -1
  23. package/dist/core/components/authentication/ForgotPassword.d.ts.map +1 -1
  24. package/dist/core/components/authentication/ForgotPassword.js.map +1 -1
  25. package/dist/core/components/authentication/PasswordError.d.ts.map +1 -1
  26. package/dist/core/components/authentication/PasswordError.js.map +1 -1
  27. package/dist/core/components/authentication/Signin.d.ts.map +1 -1
  28. package/dist/core/components/authentication/Signin.js.map +1 -1
  29. package/dist/core/components/authentication/SigninEmail.d.ts.map +1 -1
  30. package/dist/core/components/authentication/SigninEmail.js.map +1 -1
  31. package/dist/core/components/authentication/Signup.d.ts.map +1 -1
  32. package/dist/core/components/authentication/Signup.js.map +1 -1
  33. package/dist/core/components/authentication/VerifyEmail.d.ts.map +1 -1
  34. package/dist/core/components/authentication/VerifyEmail.js.map +1 -1
  35. package/dist/core/components/authentication/index.d.ts.map +1 -1
  36. package/dist/core/components/authentication/index.js.map +1 -1
  37. package/dist/core/components/index.d.ts +1 -0
  38. package/dist/core/components/index.d.ts.map +1 -1
  39. package/dist/core/components/index.js +1 -0
  40. package/dist/core/components/index.js.map +1 -1
  41. package/dist/core/components/instance-not-found/index.d.ts.map +1 -1
  42. package/dist/core/components/instance-not-found/index.js.map +1 -1
  43. package/dist/core/components/instance-not-found/src/OrganizationNotFoundSection.d.ts.map +1 -1
  44. package/dist/core/components/instance-not-found/src/OrganizationNotFoundSection.js.map +1 -1
  45. package/dist/core/components/organizationConfig/index.d.ts +2 -0
  46. package/dist/core/components/organizationConfig/index.d.ts.map +1 -0
  47. package/dist/core/components/organizationConfig/index.js +66 -0
  48. package/dist/core/components/organizationConfig/index.js.map +1 -0
  49. package/dist/core/components/organizationConfig/src/organizationConfigContent.d.ts +2 -0
  50. package/dist/core/components/organizationConfig/src/organizationConfigContent.d.ts.map +1 -0
  51. package/dist/core/components/organizationConfig/src/organizationConfigContent.js +229 -0
  52. package/dist/core/components/organizationConfig/src/organizationConfigContent.js.map +1 -0
  53. package/dist/core/components/settings/index.d.ts.map +1 -1
  54. package/dist/core/components/settings/index.js.map +1 -1
  55. package/dist/core/components/settings/src/AccountSettingsPanel.d.ts.map +1 -1
  56. package/dist/core/components/settings/src/AccountSettingsPanel.js.map +1 -1
  57. package/dist/core/components/settings/src/ChangePassword.d.ts.map +1 -1
  58. package/dist/core/components/settings/src/ChangePassword.js.map +1 -1
  59. package/dist/core/components/settings/src/OrganizationSettingsPanel.d.ts.map +1 -1
  60. package/dist/core/components/settings/src/OrganizationSettingsPanel.js.map +1 -1
  61. package/dist/core/components/settings/src/OrganizationSkeleton.d.ts.map +1 -1
  62. package/dist/core/components/settings/src/OrganizationSkeleton.js.map +1 -1
  63. package/dist/core/components/settings/src/SettingsContent.d.ts.map +1 -1
  64. package/dist/core/components/settings/src/SettingsContent.js.map +1 -1
  65. package/dist/core/components/settings/src/SettingsHeader.d.ts.map +1 -1
  66. package/dist/core/components/settings/src/SettingsHeader.js.map +1 -1
  67. package/dist/core/components/settings/src/SettingsSidebar.d.ts.map +1 -1
  68. package/dist/core/components/settings/src/SettingsSidebar.js.map +1 -1
  69. package/dist/core/components/settings/src/SettingsSkeleton.d.ts.map +1 -1
  70. package/dist/core/components/settings/src/SettingsSkeleton.js.map +1 -1
  71. package/dist/core/components/settings/src/UsersSettingsPanel.d.ts.map +1 -1
  72. package/dist/core/components/settings/src/UsersSettingsPanel.js.map +1 -1
  73. package/dist/core/components/settings/src/types.d.ts.map +1 -1
  74. package/dist/core/components/ui/Accordion.d.ts.map +1 -1
  75. package/dist/core/components/ui/Accordion.js.map +1 -1
  76. package/dist/core/components/ui/AddItemDialog.d.ts.map +1 -1
  77. package/dist/core/components/ui/AddItemDialog.js.map +1 -1
  78. package/dist/core/components/ui/AlertDialog.d.ts.map +1 -1
  79. package/dist/core/components/ui/AlertDialog.js.map +1 -1
  80. package/dist/core/components/ui/AnimatedBackground.d.ts.map +1 -1
  81. package/dist/core/components/ui/AnimatedBackground.js.map +1 -1
  82. package/dist/core/components/ui/AppSidebar.d.ts.map +1 -1
  83. package/dist/core/components/ui/AppSidebar.js +30 -15
  84. package/dist/core/components/ui/AppSidebar.js.map +1 -1
  85. package/dist/core/components/ui/Avatar.d.ts.map +1 -1
  86. package/dist/core/components/ui/Avatar.js.map +1 -1
  87. package/dist/core/components/ui/Badge.d.ts.map +1 -1
  88. package/dist/core/components/ui/Badge.js.map +1 -1
  89. package/dist/core/components/ui/Breadcrumb.d.ts.map +1 -1
  90. package/dist/core/components/ui/Breadcrumb.js.map +1 -1
  91. package/dist/core/components/ui/Button.d.ts.map +1 -1
  92. package/dist/core/components/ui/Button.js.map +1 -1
  93. package/dist/core/components/ui/Calendar.d.ts.map +1 -1
  94. package/dist/core/components/ui/Calendar.js.map +1 -1
  95. package/dist/core/components/ui/Card.d.ts.map +1 -1
  96. package/dist/core/components/ui/Card.js.map +1 -1
  97. package/dist/core/components/ui/Checkbox.d.ts.map +1 -1
  98. package/dist/core/components/ui/Checkbox.js.map +1 -1
  99. package/dist/core/components/ui/CollapsibleSection.d.ts.map +1 -1
  100. package/dist/core/components/ui/CollapsibleSection.js.map +1 -1
  101. package/dist/core/components/ui/ColorCircle.d.ts.map +1 -1
  102. package/dist/core/components/ui/ColorCircle.js.map +1 -1
  103. package/dist/core/components/ui/Command.d.ts.map +1 -1
  104. package/dist/core/components/ui/Command.js.map +1 -1
  105. package/dist/core/components/ui/Comments/CollapsibleCommentItem.d.ts.map +1 -1
  106. package/dist/core/components/ui/Comments/CollapsibleCommentItem.js.map +1 -1
  107. package/dist/core/components/ui/Comments/Comment.d.ts.map +1 -1
  108. package/dist/core/components/ui/Comments/Comment.js.map +1 -1
  109. package/dist/core/components/ui/Comments/CommentInput.d.ts.map +1 -1
  110. package/dist/core/components/ui/Comments/CommentInput.js.map +1 -1
  111. package/dist/core/components/ui/Comments/CommentsSection.d.ts.map +1 -1
  112. package/dist/core/components/ui/Comments/CommentsSection.js.map +1 -1
  113. package/dist/core/components/ui/Comments/commentUtils.d.ts.map +1 -1
  114. package/dist/core/components/ui/Comments/commentUtils.js.map +1 -1
  115. package/dist/core/components/ui/Countdown.d.ts.map +1 -1
  116. package/dist/core/components/ui/Countdown.js.map +1 -1
  117. package/dist/core/components/ui/DataTable.d.ts.map +1 -1
  118. package/dist/core/components/ui/DataTable.js.map +1 -1
  119. package/dist/core/components/ui/DatePicker.d.ts.map +1 -1
  120. package/dist/core/components/ui/DatePicker.js.map +1 -1
  121. package/dist/core/components/ui/DescriptionList.d.ts.map +1 -1
  122. package/dist/core/components/ui/DescriptionList.js.map +1 -1
  123. package/dist/core/components/ui/Dialog.d.ts.map +1 -1
  124. package/dist/core/components/ui/Dialog.js.map +1 -1
  125. package/dist/core/components/ui/DropdownMenu.d.ts.map +1 -1
  126. package/dist/core/components/ui/DropdownMenu.js.map +1 -1
  127. package/dist/core/components/ui/ExportData.d.ts.map +1 -1
  128. package/dist/core/components/ui/ExportData.js.map +1 -1
  129. package/dist/core/components/ui/FilesManager/index.d.ts.map +1 -1
  130. package/dist/core/components/ui/FilesManager/index.js.map +1 -1
  131. package/dist/core/components/ui/FilesManager/src/FileItemComponent.d.ts.map +1 -1
  132. package/dist/core/components/ui/FilesManager/src/FileItemComponent.js.map +1 -1
  133. package/dist/core/components/ui/FilesManager/src/FileMarker.d.ts.map +1 -1
  134. package/dist/core/components/ui/FilesManager/src/FileMarker.js.map +1 -1
  135. package/dist/core/components/ui/FilesManager/src/ViewerContextMenu.d.ts.map +1 -1
  136. package/dist/core/components/ui/FilesManager/src/ViewerContextMenu.js.map +1 -1
  137. package/dist/core/components/ui/FilesManager/src/convertIfcToFragmentsFile.d.ts.map +1 -1
  138. package/dist/core/components/ui/FilesManager/src/convertIfcToFragmentsFile.js.map +1 -1
  139. package/dist/core/components/ui/FilesManager/src/downloadUtils.d.ts.map +1 -1
  140. package/dist/core/components/ui/FilesManager/src/downloadUtils.js.map +1 -1
  141. package/dist/core/components/ui/FilesManager/src/useCommonFileUpload.d.ts.map +1 -1
  142. package/dist/core/components/ui/FilesManager/src/useCommonFileUpload.js.map +1 -1
  143. package/dist/core/components/ui/FilesManager/src/useFileActions.d.ts.map +1 -1
  144. package/dist/core/components/ui/FilesManager/src/useFileActions.js.map +1 -1
  145. package/dist/core/components/ui/FilesManager/src/useFileDeleteHandler.d.ts.map +1 -1
  146. package/dist/core/components/ui/FilesManager/src/useFileDeleteHandler.js.map +1 -1
  147. package/dist/core/components/ui/FilesManager/src/useFileUploadHandler.d.ts.map +1 -1
  148. package/dist/core/components/ui/FilesManager/src/useFileUploadHandler.js.map +1 -1
  149. package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.d.ts.map +1 -1
  150. package/dist/core/components/ui/FilesManager/src/useFileUploadWithProgress.js.map +1 -1
  151. package/dist/core/components/ui/Footer.d.ts.map +1 -1
  152. package/dist/core/components/ui/Footer.js.map +1 -1
  153. package/dist/core/components/ui/GenericTool.d.ts.map +1 -1
  154. package/dist/core/components/ui/GenericTool.js.map +1 -1
  155. package/dist/core/components/ui/Icons/BcfIcon.d.ts.map +1 -1
  156. package/dist/core/components/ui/Icons/BcfIcon.js.map +1 -1
  157. package/dist/core/components/ui/Icons/CdtIcon.d.ts.map +1 -1
  158. package/dist/core/components/ui/Icons/CdtIcon.js.map +1 -1
  159. package/dist/core/components/ui/Icons/FloorPlanIcon.d.ts.map +1 -1
  160. package/dist/core/components/ui/Icons/FloorPlanIcon.js.map +1 -1
  161. package/dist/core/components/ui/Icons/GoogleIcon.d.ts.map +1 -1
  162. package/dist/core/components/ui/Icons/GoogleIcon.js.map +1 -1
  163. package/dist/core/components/ui/Icons/IdsIcon.d.ts.map +1 -1
  164. package/dist/core/components/ui/Icons/IdsIcon.js.map +1 -1
  165. package/dist/core/components/ui/Icons/IfcIcon.d.ts.map +1 -1
  166. package/dist/core/components/ui/Icons/IfcIcon.js.map +1 -1
  167. package/dist/core/components/ui/Icons/index.d.ts.map +1 -1
  168. package/dist/core/components/ui/Icons/index.js.map +1 -1
  169. package/dist/core/components/ui/InfoSidebar/Container.d.ts.map +1 -1
  170. package/dist/core/components/ui/InfoSidebar/Container.js.map +1 -1
  171. package/dist/core/components/ui/InfoSidebar/Header.d.ts.map +1 -1
  172. package/dist/core/components/ui/InfoSidebar/Header.js.map +1 -1
  173. package/dist/core/components/ui/InfoSidebar/index.d.ts.map +1 -1
  174. package/dist/core/components/ui/InfoSidebar/index.js.map +1 -1
  175. package/dist/core/components/ui/Input.d.ts.map +1 -1
  176. package/dist/core/components/ui/Input.js.map +1 -1
  177. package/dist/core/components/ui/Label.d.ts.map +1 -1
  178. package/dist/core/components/ui/Label.js.map +1 -1
  179. package/dist/core/components/ui/LanguageToggle.d.ts.map +1 -1
  180. package/dist/core/components/ui/LanguageToggle.js.map +1 -1
  181. package/dist/core/components/ui/LoadingSpinner.d.ts.map +1 -1
  182. package/dist/core/components/ui/LoadingSpinner.js.map +1 -1
  183. package/dist/core/components/ui/Menubar.d.ts.map +1 -1
  184. package/dist/core/components/ui/Menubar.js.map +1 -1
  185. package/dist/core/components/ui/NavUser.d.ts.map +1 -1
  186. package/dist/core/components/ui/NavUser.js.map +1 -1
  187. package/dist/core/components/ui/Navbar.d.ts.map +1 -1
  188. package/dist/core/components/ui/Navbar.js.map +1 -1
  189. package/dist/core/components/ui/Popover.d.ts.map +1 -1
  190. package/dist/core/components/ui/Popover.js.map +1 -1
  191. package/dist/core/components/ui/Progress.d.ts.map +1 -1
  192. package/dist/core/components/ui/Progress.js.map +1 -1
  193. package/dist/core/components/ui/ScrollArea.d.ts.map +1 -1
  194. package/dist/core/components/ui/ScrollArea.js.map +1 -1
  195. package/dist/core/components/ui/SearchInput.d.ts.map +1 -1
  196. package/dist/core/components/ui/SearchInput.js.map +1 -1
  197. package/dist/core/components/ui/Select.d.ts.map +1 -1
  198. package/dist/core/components/ui/Select.js.map +1 -1
  199. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts.map +1 -1
  200. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js.map +1 -1
  201. package/dist/core/components/ui/Sensors/Sensor.d.ts.map +1 -1
  202. package/dist/core/components/ui/Sensors/Sensor.js.map +1 -1
  203. package/dist/core/components/ui/Sensors/SensorChart.d.ts.map +1 -1
  204. package/dist/core/components/ui/Sensors/SensorChart.js.map +1 -1
  205. package/dist/core/components/ui/Sensors/SensorInput.d.ts.map +1 -1
  206. package/dist/core/components/ui/Sensors/SensorInput.js.map +1 -1
  207. package/dist/core/components/ui/Sensors/SensorTagsSection.d.ts.map +1 -1
  208. package/dist/core/components/ui/Sensors/SensorTagsSection.js.map +1 -1
  209. package/dist/core/components/ui/Sensors/SensorsSection.d.ts.map +1 -1
  210. package/dist/core/components/ui/Sensors/SensorsSection.js.map +1 -1
  211. package/dist/core/components/ui/Sensors/SensorsSectionSkeleton.d.ts.map +1 -1
  212. package/dist/core/components/ui/Sensors/SensorsSectionSkeleton.js.map +1 -1
  213. package/dist/core/components/ui/Sensors/sensorUtils.d.ts.map +1 -1
  214. package/dist/core/components/ui/Sensors/sensorUtils.js.map +1 -1
  215. package/dist/core/components/ui/Separator.d.ts.map +1 -1
  216. package/dist/core/components/ui/Separator.js.map +1 -1
  217. package/dist/core/components/ui/SettingsButton.d.ts.map +1 -1
  218. package/dist/core/components/ui/SettingsButton.js.map +1 -1
  219. package/dist/core/components/ui/ShareFeature/QRCodeWithLink.d.ts.map +1 -1
  220. package/dist/core/components/ui/ShareFeature/QRCodeWithLink.js.map +1 -1
  221. package/dist/core/components/ui/ShareFeature/ShareToolSubmenu.d.ts.map +1 -1
  222. package/dist/core/components/ui/ShareFeature/ShareToolSubmenu.js.map +1 -1
  223. package/dist/core/components/ui/ShareFeature/index.d.ts.map +1 -1
  224. package/dist/core/components/ui/ShareFeature/index.js.map +1 -1
  225. package/dist/core/components/ui/Sheet.d.ts.map +1 -1
  226. package/dist/core/components/ui/Sheet.js.map +1 -1
  227. package/dist/core/components/ui/Sidebar.d.ts.map +1 -1
  228. package/dist/core/components/ui/Sidebar.js.map +1 -1
  229. package/dist/core/components/ui/Skeleton.d.ts.map +1 -1
  230. package/dist/core/components/ui/Skeleton.js.map +1 -1
  231. package/dist/core/components/ui/Slider.d.ts.map +1 -1
  232. package/dist/core/components/ui/Slider.js.map +1 -1
  233. package/dist/core/components/ui/Sonner.d.ts.map +1 -1
  234. package/dist/core/components/ui/Sonner.js.map +1 -1
  235. package/dist/core/components/ui/Switch.d.ts.map +1 -1
  236. package/dist/core/components/ui/Switch.js.map +1 -1
  237. package/dist/core/components/ui/Table.d.ts.map +1 -1
  238. package/dist/core/components/ui/Table.js.map +1 -1
  239. package/dist/core/components/ui/Tabs.d.ts.map +1 -1
  240. package/dist/core/components/ui/Tabs.js.map +1 -1
  241. package/dist/core/components/ui/Textarea.d.ts.map +1 -1
  242. package/dist/core/components/ui/Textarea.js.map +1 -1
  243. package/dist/core/components/ui/Toggle.d.ts.map +1 -1
  244. package/dist/core/components/ui/Toggle.js.map +1 -1
  245. package/dist/core/components/ui/ToggleGroup.d.ts.map +1 -1
  246. package/dist/core/components/ui/ToggleGroup.js.map +1 -1
  247. package/dist/core/components/ui/ToolbarButton.d.ts.map +1 -1
  248. package/dist/core/components/ui/ToolbarButton.js.map +1 -1
  249. package/dist/core/components/ui/Tooltip.d.ts.map +1 -1
  250. package/dist/core/components/ui/Tooltip.js.map +1 -1
  251. package/dist/core/components/ui/UserAvatar.d.ts.map +1 -1
  252. package/dist/core/components/ui/UserAvatar.js.map +1 -1
  253. package/dist/core/components/ui/chart.d.ts.map +1 -1
  254. package/dist/core/components/ui/chart.js.map +1 -1
  255. package/dist/core/components/ui/downloadUtils.d.ts.map +1 -1
  256. package/dist/core/components/ui/downloadUtils.js.map +1 -1
  257. package/dist/core/components/ui/index.d.ts.map +1 -1
  258. package/dist/core/components/ui/index.js.map +1 -1
  259. package/dist/core/components/ui/openPopupWindow.d.ts.map +1 -1
  260. package/dist/core/components/ui/openPopupWindow.js.map +1 -1
  261. package/dist/core/components/ui/openPopupWindowLCA.d.ts.map +1 -1
  262. package/dist/core/components/ui/openPopupWindowLCA.js.map +1 -1
  263. package/dist/core/components/ui/stats.d.ts.map +1 -1
  264. package/dist/core/components/ui/stats.js.map +1 -1
  265. package/dist/core/components/ui/uploadFile.d.ts.map +1 -1
  266. package/dist/core/components/ui/uploadFile.js.map +1 -1
  267. package/dist/core/components/viewers/Data/DataMenu.d.ts.map +1 -1
  268. package/dist/core/components/viewers/Data/DataMenu.js.map +1 -1
  269. package/dist/core/components/viewers/Data/FilterButtons.d.ts.map +1 -1
  270. package/dist/core/components/viewers/Data/FilterButtons.js.map +1 -1
  271. package/dist/core/components/viewers/Data/HeaderButtons.d.ts.map +1 -1
  272. package/dist/core/components/viewers/Data/HeaderButtons.js.map +1 -1
  273. package/dist/core/components/viewers/Data/MoreOptions.d.ts.map +1 -1
  274. package/dist/core/components/viewers/Data/MoreOptions.js.map +1 -1
  275. package/dist/core/components/viewers/Data/advancedFilter/Filters.d.ts.map +1 -1
  276. package/dist/core/components/viewers/Data/advancedFilter/Filters.js.map +1 -1
  277. package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.d.ts.map +1 -1
  278. package/dist/core/components/viewers/Data/advancedFilter/FiltersDialog.js.map +1 -1
  279. package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.d.ts.map +1 -1
  280. package/dist/core/components/viewers/Data/buildingDetails/AddBuilding.js.map +1 -1
  281. package/dist/core/components/viewers/Data/buildingDetails/BuildingDetails.d.ts.map +1 -1
  282. package/dist/core/components/viewers/Data/buildingDetails/BuildingDetails.js.map +1 -1
  283. package/dist/core/components/viewers/Data/buildingDetails/BuildingsMoreOptions.d.ts.map +1 -1
  284. package/dist/core/components/viewers/Data/buildingDetails/BuildingsMoreOptions.js.map +1 -1
  285. package/dist/core/components/viewers/Data/buildingDetails/FieldRenderer.d.ts.map +1 -1
  286. package/dist/core/components/viewers/Data/buildingDetails/FieldRenderer.js.map +1 -1
  287. package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.d.ts.map +1 -1
  288. package/dist/core/components/viewers/Data/buildingDetails/GeocoderInput.js.map +1 -1
  289. package/dist/core/components/viewers/Data/buildingDetails/buildingSchemaTemplate.d.ts.map +1 -1
  290. package/dist/core/components/viewers/Data/buildingDetails/buildingSchemaTemplate.js.map +1 -1
  291. package/dist/core/components/viewers/Data/details/AttachedFiles.d.ts.map +1 -1
  292. package/dist/core/components/viewers/Data/details/AttachedFiles.js.map +1 -1
  293. package/dist/core/components/viewers/Data/details/CheckboxGroup.d.ts.map +1 -1
  294. package/dist/core/components/viewers/Data/details/CheckboxGroup.js.map +1 -1
  295. package/dist/core/components/viewers/Data/details/DetailActions.d.ts.map +1 -1
  296. package/dist/core/components/viewers/Data/details/DetailActions.js.map +1 -1
  297. package/dist/core/components/viewers/Data/details/DetailHeader.d.ts.map +1 -1
  298. package/dist/core/components/viewers/Data/details/DetailHeader.js.map +1 -1
  299. package/dist/core/components/viewers/Data/details/EnergySourcesGrid.d.ts.map +1 -1
  300. package/dist/core/components/viewers/Data/details/EnergySourcesGrid.js.map +1 -1
  301. package/dist/core/components/viewers/Data/details/FieldValue.d.ts.map +1 -1
  302. package/dist/core/components/viewers/Data/details/FieldValue.js.map +1 -1
  303. package/dist/core/components/viewers/Data/details/FileUpload.d.ts.map +1 -1
  304. package/dist/core/components/viewers/Data/details/FileUpload.js.map +1 -1
  305. package/dist/core/components/viewers/Data/details/FilterFiles.d.ts.map +1 -1
  306. package/dist/core/components/viewers/Data/details/FilterFiles.js.map +1 -1
  307. package/dist/core/components/viewers/Data/details/TabSidebar.d.ts.map +1 -1
  308. package/dist/core/components/viewers/Data/details/TabSidebar.js.map +1 -1
  309. package/dist/core/components/viewers/Data/details/UnitsGrid.d.ts.map +1 -1
  310. package/dist/core/components/viewers/Data/details/UnitsGrid.js.map +1 -1
  311. package/dist/core/components/viewers/Data/details/getAttachmentFileName.d.ts.map +1 -1
  312. package/dist/core/components/viewers/Data/details/getAttachmentFileName.js.map +1 -1
  313. package/dist/core/components/viewers/Data/files/DatatableFileAdder.d.ts.map +1 -1
  314. package/dist/core/components/viewers/Data/files/DatatableFileAdder.js +3 -0
  315. package/dist/core/components/viewers/Data/files/DatatableFileAdder.js.map +1 -1
  316. package/dist/core/components/viewers/Data/files/FileDetails.d.ts.map +1 -1
  317. package/dist/core/components/viewers/Data/files/FileDetails.js.map +1 -1
  318. package/dist/core/components/viewers/Data/files/FileMoreOptions.d.ts.map +1 -1
  319. package/dist/core/components/viewers/Data/files/FileMoreOptions.js.map +1 -1
  320. package/dist/core/components/viewers/Data/files/FilePreview.d.ts.map +1 -1
  321. package/dist/core/components/viewers/Data/files/FilePreview.js.map +1 -1
  322. package/dist/core/components/viewers/Data/files/utils/fuzzySearch.d.ts.map +1 -1
  323. package/dist/core/components/viewers/Data/files/utils/fuzzySearch.js.map +1 -1
  324. package/dist/core/components/viewers/Data/infrastructureDetails/AddInfrastructure.d.ts.map +1 -1
  325. package/dist/core/components/viewers/Data/infrastructureDetails/AddInfrastructure.js.map +1 -1
  326. package/dist/core/components/viewers/Data/infrastructureDetails/FieldRenderer.d.ts.map +1 -1
  327. package/dist/core/components/viewers/Data/infrastructureDetails/FieldRenderer.js.map +1 -1
  328. package/dist/core/components/viewers/Data/infrastructureDetails/InfrastructureDetails.d.ts.map +1 -1
  329. package/dist/core/components/viewers/Data/infrastructureDetails/InfrastructureDetails.js.map +1 -1
  330. package/dist/core/components/viewers/Data/siteDetails/AddSite.d.ts.map +1 -1
  331. package/dist/core/components/viewers/Data/siteDetails/AddSite.js.map +1 -1
  332. package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.d.ts.map +1 -1
  333. package/dist/core/components/viewers/Data/siteDetails/AssociatedBuildings.js.map +1 -1
  334. package/dist/core/components/viewers/Data/siteDetails/FieldRenderer.d.ts.map +1 -1
  335. package/dist/core/components/viewers/Data/siteDetails/FieldRenderer.js.map +1 -1
  336. package/dist/core/components/viewers/Data/siteDetails/SiteDetails.d.ts.map +1 -1
  337. package/dist/core/components/viewers/Data/siteDetails/SiteDetails.js.map +1 -1
  338. package/dist/core/components/viewers/Data/userDetails/AddUser.d.ts.map +1 -1
  339. package/dist/core/components/viewers/Data/userDetails/AddUser.js.map +1 -1
  340. package/dist/core/components/viewers/Data/userDetails/UserDetails.d.ts.map +1 -1
  341. package/dist/core/components/viewers/Data/userDetails/UserDetails.js.map +1 -1
  342. package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.d.ts.map +1 -1
  343. package/dist/core/components/viewers/Data/userDetails/UserMoreOptions.js.map +1 -1
  344. package/dist/core/components/viewers/Data/utils/Columns.d.ts.map +1 -1
  345. package/dist/core/components/viewers/Data/utils/Columns.js.map +1 -1
  346. package/dist/core/components/viewers/Data/utils/Headers.d.ts.map +1 -1
  347. package/dist/core/components/viewers/Data/utils/Headers.js.map +1 -1
  348. package/dist/core/components/viewers/Data/utils/convertDate.d.ts.map +1 -1
  349. package/dist/core/components/viewers/Data/utils/convertDate.js.map +1 -1
  350. package/dist/core/components/viewers/Data/utils/csvUtils.d.ts.map +1 -1
  351. package/dist/core/components/viewers/Data/utils/csvUtils.js.map +1 -1
  352. package/dist/core/components/viewers/Data/utils/filterHelper.d.ts.map +1 -1
  353. package/dist/core/components/viewers/Data/utils/filterHelper.js.map +1 -1
  354. package/dist/core/components/viewers/Data/utils/positionParser.d.ts.map +1 -1
  355. package/dist/core/components/viewers/Data/utils/positionParser.js.map +1 -1
  356. package/dist/core/components/viewers/Data/utils/useViewerData.d.ts.map +1 -1
  357. package/dist/core/components/viewers/Data/utils/useViewerData.js.map +1 -1
  358. package/dist/core/components/viewers/Data/utils/viewerConfig.d.ts.map +1 -1
  359. package/dist/core/components/viewers/Data/utils/viewerConfig.js.map +1 -1
  360. package/dist/core/components/viewers/Viewer.d.ts.map +1 -1
  361. package/dist/core/components/viewers/Viewer.js.map +1 -1
  362. package/dist/core/components/viewers/bim/BimToolbar.d.ts.map +1 -1
  363. package/dist/core/components/viewers/bim/BimToolbar.js.map +1 -1
  364. package/dist/core/components/viewers/bim/BimViewer.d.ts.map +1 -1
  365. package/dist/core/components/viewers/bim/BimViewer.js.map +1 -1
  366. package/dist/core/components/viewers/bim/src/BCFTopicsManager.d.ts.map +1 -1
  367. package/dist/core/components/viewers/bim/src/BCFTopicsManager.js.map +1 -1
  368. package/dist/core/components/viewers/bim/src/BIMManager/index.d.ts.map +1 -1
  369. package/dist/core/components/viewers/bim/src/BIMManager/index.js.map +1 -1
  370. package/dist/core/components/viewers/bim/src/BimLoadingState/index.d.ts.map +1 -1
  371. package/dist/core/components/viewers/bim/src/BimLoadingState/index.js.map +1 -1
  372. package/dist/core/components/viewers/bim/src/BimMeasurements/LenghtMeasurement.d.ts.map +1 -1
  373. package/dist/core/components/viewers/bim/src/BimMeasurements/LenghtMeasurement.js.map +1 -1
  374. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/index.d.ts.map +1 -1
  375. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/index.js.map +1 -1
  376. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/CollapsibleTopicItem.d.ts.map +1 -1
  377. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/CollapsibleTopicItem.js.map +1 -1
  378. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/CreateTopicDialog.d.ts.map +1 -1
  379. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/CreateTopicDialog.js.map +1 -1
  380. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.d.ts.map +1 -1
  381. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.js.map +1 -1
  382. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/index.d.ts.map +1 -1
  383. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/index.js.map +1 -1
  384. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  385. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  386. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
  387. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
  388. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/index.d.ts.map +1 -1
  389. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/index.js.map +1 -1
  390. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/ElevationsSection.d.ts.map +1 -1
  391. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/ElevationsSection.js.map +1 -1
  392. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.d.ts.map +1 -1
  393. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/FloorplanSection.js.map +1 -1
  394. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/SpatialStructureSection.d.ts.map +1 -1
  395. package/dist/core/components/viewers/bim/src/BimSidebar/src/LayersTab/src/SpatialStructureSection.js.map +1 -1
  396. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.d.ts.map +1 -1
  397. package/dist/core/components/viewers/bim/src/BimSidebar/src/SensorsTab/index.js.map +1 -1
  398. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/index.d.ts.map +1 -1
  399. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/index.js.map +1 -1
  400. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/src/GridManagement.d.ts.map +1 -1
  401. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/src/GridManagement.js.map +1 -1
  402. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/src/LightingManagement.d.ts.map +1 -1
  403. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/src/LightingManagement.js.map +1 -1
  404. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/src/RenderMode.d.ts.map +1 -1
  405. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/src/RenderMode.js.map +1 -1
  406. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/src/ToggleProjection.d.ts.map +1 -1
  407. package/dist/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/src/ToggleProjection.js.map +1 -1
  408. package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.d.ts.map +1 -1
  409. package/dist/core/components/viewers/bim/src/BimSidebar/src/TabSelector.js.map +1 -1
  410. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.d.ts.map +1 -1
  411. package/dist/core/components/viewers/bim/src/BimSidebar/src/index.js.map +1 -1
  412. package/dist/core/components/viewers/bim/src/CameraProjection.d.ts.map +1 -1
  413. package/dist/core/components/viewers/bim/src/CameraProjection.js.map +1 -1
  414. package/dist/core/components/viewers/bim/src/ClippingPlane.d.ts.map +1 -1
  415. package/dist/core/components/viewers/bim/src/ClippingPlane.js.map +1 -1
  416. package/dist/core/components/viewers/bim/src/CurrentCamera.d.ts.map +1 -1
  417. package/dist/core/components/viewers/bim/src/CurrentCamera.js.map +1 -1
  418. package/dist/core/components/viewers/bim/src/CurrentWorld.d.ts.map +1 -1
  419. package/dist/core/components/viewers/bim/src/CurrentWorld.js.map +1 -1
  420. package/dist/core/components/viewers/bim/src/Cursor.d.ts.map +1 -1
  421. package/dist/core/components/viewers/bim/src/Cursor.js.map +1 -1
  422. package/dist/core/components/viewers/bim/src/DXFLoader/index.d.ts.map +1 -1
  423. package/dist/core/components/viewers/bim/src/DXFLoader/index.js.map +1 -1
  424. package/dist/core/components/viewers/bim/src/ElevationsTool/index.d.ts.map +1 -1
  425. package/dist/core/components/viewers/bim/src/ElevationsTool/index.js.map +1 -1
  426. package/dist/core/components/viewers/bim/src/ElevationsTool/src/ElevationProjector.d.ts.map +1 -1
  427. package/dist/core/components/viewers/bim/src/ElevationsTool/src/ElevationProjector.js.map +1 -1
  428. package/dist/core/components/viewers/bim/src/ElevationsTool/src/types.d.ts.map +1 -1
  429. package/dist/core/components/viewers/bim/src/ElevationsTool/src/types.js.map +1 -1
  430. package/dist/core/components/viewers/bim/src/FitCamera.d.ts.map +1 -1
  431. package/dist/core/components/viewers/bim/src/FitCamera.js.map +1 -1
  432. package/dist/core/components/viewers/bim/src/FloorplanTool/index.d.ts.map +1 -1
  433. package/dist/core/components/viewers/bim/src/FloorplanTool/index.js.map +1 -1
  434. package/dist/core/components/viewers/bim/src/FloorplanTool/src/FloorplanRenderer.d.ts.map +1 -1
  435. package/dist/core/components/viewers/bim/src/FloorplanTool/src/FloorplanRenderer.js.map +1 -1
  436. package/dist/core/components/viewers/bim/src/FloorplanTool/src/StoreyProjector.d.ts.map +1 -1
  437. package/dist/core/components/viewers/bim/src/FloorplanTool/src/StoreyProjector.js.map +1 -1
  438. package/dist/core/components/viewers/bim/src/FloorplanTool/src/types.d.ts.map +1 -1
  439. package/dist/core/components/viewers/bim/src/FloorplanTool/src/types.js.map +1 -1
  440. package/dist/core/components/viewers/bim/src/FloorplanTool/src/utils.d.ts.map +1 -1
  441. package/dist/core/components/viewers/bim/src/FloorplanTool/src/utils.js.map +1 -1
  442. package/dist/core/components/viewers/bim/src/GhostMode.d.ts.map +1 -1
  443. package/dist/core/components/viewers/bim/src/GhostMode.js.map +1 -1
  444. package/dist/core/components/viewers/bim/src/Highlighter/index.d.ts.map +1 -1
  445. package/dist/core/components/viewers/bim/src/Highlighter/index.js.map +1 -1
  446. package/dist/core/components/viewers/bim/src/IDSManager/index.d.ts.map +1 -1
  447. package/dist/core/components/viewers/bim/src/IDSManager/index.js.map +1 -1
  448. package/dist/core/components/viewers/bim/src/IDSManager/src/IDSLegend.d.ts.map +1 -1
  449. package/dist/core/components/viewers/bim/src/IDSManager/src/IDSLegend.js.map +1 -1
  450. package/dist/core/components/viewers/bim/src/IfcToFragments.d.ts.map +1 -1
  451. package/dist/core/components/viewers/bim/src/IfcToFragments.js.map +1 -1
  452. package/dist/core/components/viewers/bim/src/LoadIfcAsFragments.d.ts.map +1 -1
  453. package/dist/core/components/viewers/bim/src/LoadIfcAsFragments.js.map +1 -1
  454. package/dist/core/components/viewers/bim/src/LoadModels.d.ts.map +1 -1
  455. package/dist/core/components/viewers/bim/src/LoadModels.js.map +1 -1
  456. package/dist/core/components/viewers/bim/src/ModelManager/index.d.ts.map +1 -1
  457. package/dist/core/components/viewers/bim/src/ModelManager/index.js.map +1 -1
  458. package/dist/core/components/viewers/bim/src/SimpleBimViewer.d.ts.map +1 -1
  459. package/dist/core/components/viewers/bim/src/SimpleBimViewer.js.map +1 -1
  460. package/dist/core/components/viewers/bim/src/SpatialStructure.d.ts.map +1 -1
  461. package/dist/core/components/viewers/bim/src/SpatialStructure.js.map +1 -1
  462. package/dist/core/components/viewers/bim/src/ViewportGizmo.d.ts.map +1 -1
  463. package/dist/core/components/viewers/bim/src/ViewportGizmo.js.map +1 -1
  464. package/dist/core/components/viewers/bim/src/lib/CameraController.d.ts.map +1 -1
  465. package/dist/core/components/viewers/bim/src/lib/CameraController.js.map +1 -1
  466. package/dist/core/components/viewers/bim/src/lib/CategoryHighlighter.d.ts.map +1 -1
  467. package/dist/core/components/viewers/bim/src/lib/CategoryHighlighter.js.map +1 -1
  468. package/dist/core/components/viewers/bim/src/lib/ChromeController.d.ts.map +1 -1
  469. package/dist/core/components/viewers/bim/src/lib/ChromeController.js.map +1 -1
  470. package/dist/core/components/viewers/bim/src/lib/ClipController.d.ts.map +1 -1
  471. package/dist/core/components/viewers/bim/src/lib/ClipController.js.map +1 -1
  472. package/dist/core/components/viewers/bim/src/lib/GridController.d.ts.map +1 -1
  473. package/dist/core/components/viewers/bim/src/lib/GridController.js.map +1 -1
  474. package/dist/core/components/viewers/bim/src/lib/TrueNorthPopover.d.ts.map +1 -1
  475. package/dist/core/components/viewers/bim/src/lib/TrueNorthPopover.js.map +1 -1
  476. package/dist/core/components/viewers/bim/src/lib/ViewModeCoordinator.d.ts.map +1 -1
  477. package/dist/core/components/viewers/bim/src/lib/ViewModeCoordinator.js.map +1 -1
  478. package/dist/core/components/viewers/bim/src/lib/ViewSectionList.d.ts.map +1 -1
  479. package/dist/core/components/viewers/bim/src/lib/ViewSectionList.js.map +1 -1
  480. package/dist/core/components/viewers/bim/src/lib/drawingLayers.d.ts.map +1 -1
  481. package/dist/core/components/viewers/bim/src/lib/drawingLayers.js.map +1 -1
  482. package/dist/core/components/viewers/bim/src/lib/drawingProjection.d.ts.map +1 -1
  483. package/dist/core/components/viewers/bim/src/lib/drawingProjection.js.map +1 -1
  484. package/dist/core/components/viewers/bim/src/lib/exportDrawingToDxf.d.ts.map +1 -1
  485. package/dist/core/components/viewers/bim/src/lib/exportDrawingToDxf.js.map +1 -1
  486. package/dist/core/components/viewers/bim/src/lib/safeRun.d.ts.map +1 -1
  487. package/dist/core/components/viewers/bim/src/lib/safeRun.js.map +1 -1
  488. package/dist/core/components/viewers/bim/src/lib/useBuildingName.d.ts.map +1 -1
  489. package/dist/core/components/viewers/bim/src/lib/useBuildingName.js.map +1 -1
  490. package/dist/core/components/viewers/bim/src/lib/useFriendlyIfcClassName.d.ts.map +1 -1
  491. package/dist/core/components/viewers/bim/src/lib/useFriendlyIfcClassName.js.map +1 -1
  492. package/dist/core/components/viewers/bim/src/lib/viewSection.d.ts.map +1 -1
  493. package/dist/core/components/viewers/bim/src/lib/viewSection.js.map +1 -1
  494. package/dist/core/components/viewers/bim/src/propertiesMenu/index.d.ts.map +1 -1
  495. package/dist/core/components/viewers/bim/src/propertiesMenu/index.js.map +1 -1
  496. package/dist/core/components/viewers/bim/src/propertiesMenu/src/ElementList.d.ts.map +1 -1
  497. package/dist/core/components/viewers/bim/src/propertiesMenu/src/ElementList.js.map +1 -1
  498. package/dist/core/components/viewers/bim/src/propertiesMenu/src/PropertiesMenuHeader.d.ts.map +1 -1
  499. package/dist/core/components/viewers/bim/src/propertiesMenu/src/PropertiesMenuHeader.js.map +1 -1
  500. package/dist/core/components/viewers/bim/src/propertiesMenu/src/PropertyGroup.d.ts.map +1 -1
  501. package/dist/core/components/viewers/bim/src/propertiesMenu/src/PropertyGroup.js.map +1 -1
  502. package/dist/core/components/viewers/bim/src/propertiesMenu/src/useElementProperties.d.ts.map +1 -1
  503. package/dist/core/components/viewers/bim/src/propertiesMenu/src/useElementProperties.js.map +1 -1
  504. package/dist/core/components/viewers/bim/src/propertiesMenu/src/utils.d.ts.map +1 -1
  505. package/dist/core/components/viewers/bim/src/propertiesMenu/src/utils.js.map +1 -1
  506. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.d.ts.map +1 -1
  507. package/dist/core/components/viewers/bim/src/tools/AddToBim/index.js.map +1 -1
  508. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.d.ts.map +1 -1
  509. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddDxf.js.map +1 -1
  510. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddFile.d.ts.map +1 -1
  511. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddFile.js.map +1 -1
  512. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddSensor.d.ts.map +1 -1
  513. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddSensor.js.map +1 -1
  514. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddToBimToolbar.d.ts.map +1 -1
  515. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/AddToBimToolbar.js.map +1 -1
  516. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.d.ts.map +1 -1
  517. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimComment.js.map +1 -1
  518. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.d.ts.map +1 -1
  519. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/BimSensor.js.map +1 -1
  520. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.d.ts.map +1 -1
  521. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileHandler.js.map +1 -1
  522. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.d.ts.map +1 -1
  523. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/FileMarkerUtils.js.map +1 -1
  524. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/Position3DCard.d.ts.map +1 -1
  525. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/Position3DCard.js.map +1 -1
  526. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/index.d.ts.map +1 -1
  527. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/index.js.map +1 -1
  528. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/markerUtils.d.ts.map +1 -1
  529. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/markerUtils.js.map +1 -1
  530. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.d.ts.map +1 -1
  531. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/renderCSS2DMarkers.js.map +1 -1
  532. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.d.ts.map +1 -1
  533. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useCommentMarkers.js.map +1 -1
  534. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.d.ts.map +1 -1
  535. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useFilePlacement.js.map +1 -1
  536. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.d.ts.map +1 -1
  537. package/dist/core/components/viewers/bim/src/tools/AddToBim/src/useSensorMarkers.js.map +1 -1
  538. package/dist/core/components/viewers/bim/src/tools/BIMSearchTool.d.ts.map +1 -1
  539. package/dist/core/components/viewers/bim/src/tools/BIMSearchTool.js.map +1 -1
  540. package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.d.ts.map +1 -1
  541. package/dist/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.js.map +1 -1
  542. package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.d.ts.map +1 -1
  543. package/dist/core/components/viewers/bim/src/tools/ExplodeByLevelTool.js.map +1 -1
  544. package/dist/core/components/viewers/bim/src/tools/FitCameraTool.d.ts.map +1 -1
  545. package/dist/core/components/viewers/bim/src/tools/FitCameraTool.js.map +1 -1
  546. package/dist/core/components/viewers/bim/src/tools/InspectBimTool.d.ts.map +1 -1
  547. package/dist/core/components/viewers/bim/src/tools/InspectBimTool.js.map +1 -1
  548. package/dist/core/components/viewers/bim/src/tools/bimToolbar.d.ts.map +1 -1
  549. package/dist/core/components/viewers/bim/src/tools/bimToolbar.js.map +1 -1
  550. package/dist/core/components/viewers/bim/src/tools/measureBimTool.d.ts.map +1 -1
  551. package/dist/core/components/viewers/bim/src/tools/measureBimTool.js.map +1 -1
  552. package/dist/core/components/viewers/bim/src/tools/selectionBimTool.d.ts.map +1 -1
  553. package/dist/core/components/viewers/bim/src/tools/selectionBimTool.js.map +1 -1
  554. package/dist/core/components/viewers/bim/src/tools/shareBimTool.d.ts.map +1 -1
  555. package/dist/core/components/viewers/bim/src/tools/shareBimTool.js.map +1 -1
  556. package/dist/core/components/viewers/bim/utils/GizmoController.d.ts.map +1 -1
  557. package/dist/core/components/viewers/bim/utils/GizmoController.js.map +1 -1
  558. package/dist/core/components/viewers/bim/utils/setCameraLookAt.d.ts.map +1 -1
  559. package/dist/core/components/viewers/bim/utils/setCameraLookAt.js.map +1 -1
  560. package/dist/core/components/viewers/index.d.ts.map +1 -1
  561. package/dist/core/components/viewers/index.js.map +1 -1
  562. package/dist/core/components/viewers/map/MapViewer.d.ts.map +1 -1
  563. package/dist/core/components/viewers/map/MapViewer.js.map +1 -1
  564. package/dist/core/components/viewers/map/datasets/AddPortalDialog.d.ts.map +1 -1
  565. package/dist/core/components/viewers/map/datasets/AddPortalDialog.js.map +1 -1
  566. package/dist/core/components/viewers/map/datasets/DatasetDetails.d.ts.map +1 -1
  567. package/dist/core/components/viewers/map/datasets/DatasetDetails.js.map +1 -1
  568. package/dist/core/components/viewers/map/datasets/DatasetManager/index.d.ts.map +1 -1
  569. package/dist/core/components/viewers/map/datasets/DatasetManager/index.js.map +1 -1
  570. package/dist/core/components/viewers/map/datasets/DatasetManager/src/FieldsTable.d.ts.map +1 -1
  571. package/dist/core/components/viewers/map/datasets/DatasetManager/src/FieldsTable.js.map +1 -1
  572. package/dist/core/components/viewers/map/datasets/DatasetSkeleton.d.ts.map +1 -1
  573. package/dist/core/components/viewers/map/datasets/DatasetSkeleton.js.map +1 -1
  574. package/dist/core/components/viewers/map/datasets/Filters.d.ts.map +1 -1
  575. package/dist/core/components/viewers/map/datasets/Filters.js.map +1 -1
  576. package/dist/core/components/viewers/map/datasets/NestedFilter.d.ts.map +1 -1
  577. package/dist/core/components/viewers/map/datasets/NestedFilter.js.map +1 -1
  578. package/dist/core/components/viewers/map/datasets/RowActions.d.ts.map +1 -1
  579. package/dist/core/components/viewers/map/datasets/RowActions.js.map +1 -1
  580. package/dist/core/components/viewers/map/datasets/data.d.ts.map +1 -1
  581. package/dist/core/components/viewers/map/datasets/data.js.map +1 -1
  582. package/dist/core/components/viewers/map/datasets/index.d.ts.map +1 -1
  583. package/dist/core/components/viewers/map/datasets/index.js.map +1 -1
  584. package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.d.ts.map +1 -1
  585. package/dist/core/components/viewers/map/datasets/src/arcGISDatasets.js.map +1 -1
  586. package/dist/core/components/viewers/map/datasets/src/arcgisFetch.d.ts.map +1 -1
  587. package/dist/core/components/viewers/map/datasets/src/arcgisFetch.js.map +1 -1
  588. package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.d.ts.map +1 -1
  589. package/dist/core/components/viewers/map/datasets/src/builtinLiveDatasets.js.map +1 -1
  590. package/dist/core/components/viewers/map/datasets/src/cache.d.ts.map +1 -1
  591. package/dist/core/components/viewers/map/datasets/src/cache.js.map +1 -1
  592. package/dist/core/components/viewers/map/datasets/src/ckanDatasets.d.ts.map +1 -1
  593. package/dist/core/components/viewers/map/datasets/src/ckanDatasets.js.map +1 -1
  594. package/dist/core/components/viewers/map/datasets/src/geojsonFile.d.ts.map +1 -1
  595. package/dist/core/components/viewers/map/datasets/src/geojsonFile.js.map +1 -1
  596. package/dist/core/components/viewers/map/datasets/src/localDatasets.d.ts.map +1 -1
  597. package/dist/core/components/viewers/map/datasets/src/localDatasets.js.map +1 -1
  598. package/dist/core/components/viewers/map/datasets/src/minioDatasets.d.ts.map +1 -1
  599. package/dist/core/components/viewers/map/datasets/src/minioDatasets.js.map +1 -1
  600. package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.d.ts.map +1 -1
  601. package/dist/core/components/viewers/map/datasets/src/opendatasoftDatasets.js.map +1 -1
  602. package/dist/core/components/viewers/map/datasets/src/publishedTiles.d.ts.map +1 -1
  603. package/dist/core/components/viewers/map/datasets/src/publishedTiles.js.map +1 -1
  604. package/dist/core/components/viewers/map/datasets/src/socrataDatasets.d.ts.map +1 -1
  605. package/dist/core/components/viewers/map/datasets/src/socrataDatasets.js.map +1 -1
  606. package/dist/core/components/viewers/map/datasets/src/urlSources.d.ts.map +1 -1
  607. package/dist/core/components/viewers/map/datasets/src/urlSources.js.map +1 -1
  608. package/dist/core/components/viewers/map/datasets/src/useDatasetsForPortals.d.ts.map +1 -1
  609. package/dist/core/components/viewers/map/datasets/src/useDatasetsForPortals.js.map +1 -1
  610. package/dist/core/components/viewers/map/datasets/src/useFastDatasetCache.d.ts.map +1 -1
  611. package/dist/core/components/viewers/map/datasets/src/useFastDatasetCache.js.map +1 -1
  612. package/dist/core/components/viewers/map/datasets/src/wmsTime.d.ts +0 -8
  613. package/dist/core/components/viewers/map/datasets/src/wmsTime.d.ts.map +1 -1
  614. package/dist/core/components/viewers/map/datasets/src/wmsTime.js.map +1 -1
  615. package/dist/core/components/viewers/map/datasets/utils.d.ts.map +1 -1
  616. package/dist/core/components/viewers/map/datasets/utils.js.map +1 -1
  617. package/dist/core/components/viewers/map/legends/MapLegendHost.d.ts.map +1 -1
  618. package/dist/core/components/viewers/map/legends/MapLegendHost.js.map +1 -1
  619. package/dist/core/components/viewers/map/src/Geocoder.d.ts.map +1 -1
  620. package/dist/core/components/viewers/map/src/Geocoder.js.map +1 -1
  621. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/index.d.ts.map +1 -1
  622. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/index.js.map +1 -1
  623. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/index.d.ts.map +1 -1
  624. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/index.js.map +1 -1
  625. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.d.ts.map +1 -1
  626. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/DatabaseBuildingPopover/src/BuildingsTools.js.map +1 -1
  627. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.d.ts.map +1 -1
  628. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/NonDatabaseBuildingPopover.js.map +1 -1
  629. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.d.ts.map +1 -1
  630. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/OpenDataFeaturePopover.js.map +1 -1
  631. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/PopoverSkeleton.d.ts.map +1 -1
  632. package/dist/core/components/viewers/map/src/MapFeaturePopoverMenu/src/PopoverSkeleton.js.map +1 -1
  633. package/dist/core/components/viewers/map/src/MapLayers/index.d.ts.map +1 -1
  634. package/dist/core/components/viewers/map/src/MapLayers/index.js.map +1 -1
  635. package/dist/core/components/viewers/map/src/MapLayers/src/BimLayer/index.d.ts.map +1 -1
  636. package/dist/core/components/viewers/map/src/MapLayers/src/BimLayer/index.js.map +1 -1
  637. package/dist/core/components/viewers/map/src/MapLayers/src/BuildingLayers/index.d.ts.map +1 -1
  638. package/dist/core/components/viewers/map/src/MapLayers/src/BuildingLayers/index.js.map +1 -1
  639. package/dist/core/components/viewers/map/src/MapLayers/src/BuildingLayers/src/databaseBuildings.d.ts.map +1 -1
  640. package/dist/core/components/viewers/map/src/MapLayers/src/BuildingLayers/src/databaseBuildings.js.map +1 -1
  641. package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.d.ts.map +1 -1
  642. package/dist/core/components/viewers/map/src/MapLayers/src/CommentLayer/index.js.map +1 -1
  643. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.d.ts.map +1 -1
  644. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/countryLayerUtils.js.map +1 -1
  645. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.d.ts.map +1 -1
  646. package/dist/core/components/viewers/map/src/MapLayers/src/CountryLayer/index.js.map +1 -1
  647. package/dist/core/components/viewers/map/src/MapLayers/src/EditPosition.d.ts.map +1 -1
  648. package/dist/core/components/viewers/map/src/MapLayers/src/EditPosition.js.map +1 -1
  649. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/FileModelLayer/FileModelLayer.d.ts.map +1 -1
  650. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/FileModelLayer/FileModelLayer.js.map +1 -1
  651. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/FileIcon.d.ts.map +1 -1
  652. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/FileIcon.js.map +1 -1
  653. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/FileManagerRow.d.ts.map +1 -1
  654. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/FileManagerRow.js.map +1 -1
  655. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.d.ts.map +1 -1
  656. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileManager.js.map +1 -1
  657. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileMarker.d.ts.map +1 -1
  658. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/components/MapFileMarker.js.map +1 -1
  659. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/index.d.ts.map +1 -1
  660. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/index.js.map +1 -1
  661. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/CustomModelLayer.d.ts.map +1 -1
  662. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/CustomModelLayer.js.map +1 -1
  663. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/openFileInPopUpWindow.d.ts.map +1 -1
  664. package/dist/core/components/viewers/map/src/MapLayers/src/FileLayer/utils/openFileInPopUpWindow.js.map +1 -1
  665. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.d.ts.map +1 -1
  666. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/WmsTimeControl.js.map +1 -1
  667. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/index.d.ts.map +1 -1
  668. package/dist/core/components/viewers/map/src/MapLayers/src/OpenDataLayer/src/index.js.map +1 -1
  669. package/dist/core/components/viewers/map/src/MapLayers/src/PlaceOnMap.d.ts.map +1 -1
  670. package/dist/core/components/viewers/map/src/MapLayers/src/PlaceOnMap.js.map +1 -1
  671. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.d.ts.map +1 -1
  672. package/dist/core/components/viewers/map/src/MapLayers/src/SensorsLayer/index.js.map +1 -1
  673. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/index.d.ts.map +1 -1
  674. package/dist/core/components/viewers/map/src/MapLayers/src/SiteLayer/index.js.map +1 -1
  675. package/dist/core/components/viewers/map/src/MapLayers/src/disposeThreeScene.d.ts.map +1 -1
  676. package/dist/core/components/viewers/map/src/MapLayers/src/disposeThreeScene.js.map +1 -1
  677. package/dist/core/components/viewers/map/src/MapLayers/src/mapLayersUtils.d.ts.map +1 -1
  678. package/dist/core/components/viewers/map/src/MapLayers/src/mapLayersUtils.js.map +1 -1
  679. package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.d.ts.map +1 -1
  680. package/dist/core/components/viewers/map/src/MapSidebar/TabSelector.js.map +1 -1
  681. package/dist/core/components/viewers/map/src/MapSidebar/index.d.ts.map +1 -1
  682. package/dist/core/components/viewers/map/src/MapSidebar/index.js.map +1 -1
  683. package/dist/core/components/viewers/map/src/MapSidebar/src/CommunicationTab/index.d.ts.map +1 -1
  684. package/dist/core/components/viewers/map/src/MapSidebar/src/CommunicationTab/index.js.map +1 -1
  685. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/index.d.ts.map +1 -1
  686. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/index.js.map +1 -1
  687. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  688. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  689. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.d.ts.map +1 -1
  690. package/dist/core/components/viewers/map/src/MapSidebar/src/FileTab/src/ModelsSection.js.map +1 -1
  691. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.d.ts.map +1 -1
  692. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/index.js.map +1 -1
  693. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/src/AppliedDatasetsSection.d.ts.map +1 -1
  694. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/src/AppliedDatasetsSection.js.map +1 -1
  695. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/src/AvailableDatasetsSection.d.ts.map +1 -1
  696. package/dist/core/components/viewers/map/src/MapSidebar/src/LayersTab/src/AvailableDatasetsSection.js.map +1 -1
  697. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.d.ts.map +1 -1
  698. package/dist/core/components/viewers/map/src/MapSidebar/src/SensorsTab/index.js.map +1 -1
  699. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/index.d.ts.map +1 -1
  700. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/index.js.map +1 -1
  701. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.d.ts.map +1 -1
  702. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/LocationSettings.js.map +1 -1
  703. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapCustomization.d.ts.map +1 -1
  704. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapCustomization.js.map +1 -1
  705. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapProjection.d.ts.map +1 -1
  706. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/MapProjection.js.map +1 -1
  707. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.d.ts.map +1 -1
  708. package/dist/core/components/viewers/map/src/MapSidebar/src/SettingsTab/src/TerrainLevel.js.map +1 -1
  709. package/dist/core/components/viewers/map/src/SimpleMap.d.ts.map +1 -1
  710. package/dist/core/components/viewers/map/src/SimpleMap.js.map +1 -1
  711. package/dist/core/components/viewers/map/src/compare/AddItem.d.ts.map +1 -1
  712. package/dist/core/components/viewers/map/src/compare/AddItem.js.map +1 -1
  713. package/dist/core/components/viewers/map/src/compare/CompareDialog.d.ts.map +1 -1
  714. package/dist/core/components/viewers/map/src/compare/CompareDialog.js.map +1 -1
  715. package/dist/core/components/viewers/map/src/compare/description-list.d.ts.map +1 -1
  716. package/dist/core/components/viewers/map/src/compare/description-list.js.map +1 -1
  717. package/dist/core/components/viewers/map/src/compare/index.d.ts.map +1 -1
  718. package/dist/core/components/viewers/map/src/compare/index.js.map +1 -1
  719. package/dist/core/components/viewers/map/src/tools/AddTools/AddDataset/DatasetAdder.d.ts.map +1 -1
  720. package/dist/core/components/viewers/map/src/tools/AddTools/AddDataset/DatasetAdder.js.map +1 -1
  721. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/FileAdder.d.ts.map +1 -1
  722. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/FileAdder.js.map +1 -1
  723. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/ProgressBar.d.ts.map +1 -1
  724. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/ProgressBar.js.map +1 -1
  725. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.d.ts.map +1 -1
  726. package/dist/core/components/viewers/map/src/tools/AddTools/AddFile/utils/uploadToPresignedURLS.js.map +1 -1
  727. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/SiteAdder.d.ts.map +1 -1
  728. package/dist/core/components/viewers/map/src/tools/AddTools/AddSite/SiteAdder.js.map +1 -1
  729. package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.d.ts.map +1 -1
  730. package/dist/core/components/viewers/map/src/tools/AddTools/AddToMap.js.map +1 -1
  731. package/dist/core/components/viewers/map/src/tools/DatasetMapTool.d.ts.map +1 -1
  732. package/dist/core/components/viewers/map/src/tools/DatasetMapTool.js.map +1 -1
  733. package/dist/core/components/viewers/map/src/tools/mapTools.d.ts.map +1 -1
  734. package/dist/core/components/viewers/map/src/tools/mapTools.js.map +1 -1
  735. package/dist/core/components/viewers/map/src/tools/measureMapTool.d.ts.map +1 -1
  736. package/dist/core/components/viewers/map/src/tools/measureMapTool.js.map +1 -1
  737. package/dist/core/components/viewers/map/src/tools/shareMapTool.d.ts.map +1 -1
  738. package/dist/core/components/viewers/map/src/tools/shareMapTool.js.map +1 -1
  739. package/dist/core/components/viewers/map/utils/ClusterManager.d.ts.map +1 -1
  740. package/dist/core/components/viewers/map/utils/ClusterManager.js.map +1 -1
  741. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.d.ts.map +1 -1
  742. package/dist/core/components/viewers/map/utils/MapEventManager/MapClickManager.js.map +1 -1
  743. package/dist/core/components/viewers/map/utils/MapEventManager/MapHoverManager.d.ts.map +1 -1
  744. package/dist/core/components/viewers/map/utils/MapEventManager/MapHoverManager.js.map +1 -1
  745. package/dist/core/components/viewers/map/utils/MarkerManager.d.ts.map +1 -1
  746. package/dist/core/components/viewers/map/utils/MarkerManager.js.map +1 -1
  747. package/dist/core/components/viewers/map/utils/dateName.d.ts.map +1 -1
  748. package/dist/core/components/viewers/map/utils/dateName.js.map +1 -1
  749. package/dist/core/components/viewers/map/utils/extractCoordinates.d.ts.map +1 -1
  750. package/dist/core/components/viewers/map/utils/extractCoordinates.js.map +1 -1
  751. package/dist/core/components/viewers/map/utils/fitBuildingsBounds.d.ts.map +1 -1
  752. package/dist/core/components/viewers/map/utils/fitBuildingsBounds.js.map +1 -1
  753. package/dist/core/components/viewers/map/utils/fitGeojsonBounds.d.ts.map +1 -1
  754. package/dist/core/components/viewers/map/utils/fitGeojsonBounds.js.map +1 -1
  755. package/dist/core/components/viewers/map/utils/flyToEach.d.ts.map +1 -1
  756. package/dist/core/components/viewers/map/utils/flyToEach.js.map +1 -1
  757. package/dist/core/components/viewers/map/utils/geocoder.d.ts.map +1 -1
  758. package/dist/core/components/viewers/map/utils/geocoder.js.map +1 -1
  759. package/dist/core/components/viewers/map/utils/geocoding/adapters.d.ts.map +1 -1
  760. package/dist/core/components/viewers/map/utils/geocoding/adapters.js.map +1 -1
  761. package/dist/core/components/viewers/map/utils/geocoding/config.d.ts.map +1 -1
  762. package/dist/core/components/viewers/map/utils/geocoding/config.js.map +1 -1
  763. package/dist/core/components/viewers/map/utils/geocoding/index.d.ts.map +1 -1
  764. package/dist/core/components/viewers/map/utils/geocoding/index.js.map +1 -1
  765. package/dist/core/components/viewers/map/utils/geocoding/osm.d.ts.map +1 -1
  766. package/dist/core/components/viewers/map/utils/geocoding/osm.js.map +1 -1
  767. package/dist/core/components/viewers/map/utils/geocoding/pelias.d.ts.map +1 -1
  768. package/dist/core/components/viewers/map/utils/geocoding/pelias.js.map +1 -1
  769. package/dist/core/components/viewers/map/utils/getOsmIdFromMartin.d.ts.map +1 -1
  770. package/dist/core/components/viewers/map/utils/getOsmIdFromMartin.js.map +1 -1
  771. package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.d.ts.map +1 -1
  772. package/dist/core/components/viewers/map/utils/getOsmIdbyCoordinates.js.map +1 -1
  773. package/dist/core/components/viewers/map/utils/mapStyleCatalog.d.ts.map +1 -1
  774. package/dist/core/components/viewers/map/utils/mapStyleCatalog.js.map +1 -1
  775. package/dist/core/components/viewers/map/utils/stringToColour.d.ts.map +1 -1
  776. package/dist/core/components/viewers/map/utils/stringToColour.js.map +1 -1
  777. package/dist/core/components/viewers/map/utils/toggleBimToMap.d.ts.map +1 -1
  778. package/dist/core/components/viewers/map/utils/toggleBimToMap.js.map +1 -1
  779. package/dist/core/components/viewers/map/utils/updateBuildingOsmId.d.ts.map +1 -1
  780. package/dist/core/components/viewers/map/utils/updateBuildingOsmId.js.map +1 -1
  781. package/dist/core/components/viewers/map/utils/validateBounds.d.ts.map +1 -1
  782. package/dist/core/components/viewers/map/utils/validateBounds.js.map +1 -1
  783. package/dist/core/components/viewers/pointcloud/PointCloudToolbar.d.ts.map +1 -1
  784. package/dist/core/components/viewers/pointcloud/PointCloudToolbar.js.map +1 -1
  785. package/dist/core/components/viewers/pointcloud/PointCloudViewer.d.ts.map +1 -1
  786. package/dist/core/components/viewers/pointcloud/PointCloudViewer.js.map +1 -1
  787. package/dist/core/components/viewers/pointcloud/define.d.ts.map +1 -1
  788. package/dist/core/components/viewers/pointcloud/define.js.map +1 -1
  789. package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.d.ts.map +1 -1
  790. package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.js.map +1 -1
  791. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.d.ts.map +1 -1
  792. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudManagementTable.js.map +1 -1
  793. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.d.ts.map +1 -1
  794. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudTable.js.map +1 -1
  795. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.d.ts.map +1 -1
  796. package/dist/core/components/viewers/pointcloud/src/PointCloudManagement/PointCloudUploadPanel.js.map +1 -1
  797. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/TabSelector.d.ts.map +1 -1
  798. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/TabSelector.js.map +1 -1
  799. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.d.ts.map +1 -1
  800. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/index.js.map +1 -1
  801. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.d.ts.map +1 -1
  802. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.js.map +1 -1
  803. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  804. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  805. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.d.ts.map +1 -1
  806. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.js.map +1 -1
  807. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/SettingsTab/index.d.ts.map +1 -1
  808. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/SettingsTab/index.js.map +1 -1
  809. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/SettingsTab/src/CameraSettings.d.ts.map +1 -1
  810. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/SettingsTab/src/CameraSettings.js.map +1 -1
  811. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/SettingsTab/src/GridManagement.d.ts.map +1 -1
  812. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/SettingsTab/src/GridManagement.js.map +1 -1
  813. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/SettingsTab/src/PerformanceSettings.d.ts.map +1 -1
  814. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/SettingsTab/src/PerformanceSettings.js.map +1 -1
  815. package/dist/core/components/viewers/pointcloud/src/ViewportGizmo.d.ts.map +1 -1
  816. package/dist/core/components/viewers/pointcloud/src/ViewportGizmo.js.map +1 -1
  817. package/dist/core/components/viewers/pointcloud/src/tools/ClippingTools/ClippingTool.d.ts.map +1 -1
  818. package/dist/core/components/viewers/pointcloud/src/tools/ClippingTools/ClippingTool.js.map +1 -1
  819. package/dist/core/components/viewers/pointcloud/src/tools/FitToScreen.d.ts.map +1 -1
  820. package/dist/core/components/viewers/pointcloud/src/tools/FitToScreen.js.map +1 -1
  821. package/dist/core/components/viewers/pointcloud/src/tools/MeasureTools/AngleMeasurement.d.ts.map +1 -1
  822. package/dist/core/components/viewers/pointcloud/src/tools/MeasureTools/AngleMeasurement.js.map +1 -1
  823. package/dist/core/components/viewers/pointcloud/src/tools/MeasureTools/AreaMeasurement.d.ts.map +1 -1
  824. package/dist/core/components/viewers/pointcloud/src/tools/MeasureTools/AreaMeasurement.js.map +1 -1
  825. package/dist/core/components/viewers/pointcloud/src/tools/MeasureTools/LineMeasurement.d.ts.map +1 -1
  826. package/dist/core/components/viewers/pointcloud/src/tools/MeasureTools/LineMeasurement.js.map +1 -1
  827. package/dist/core/components/viewers/pointcloud/src/tools/MeasureTools/MeasurePointCloudTool.d.ts.map +1 -1
  828. package/dist/core/components/viewers/pointcloud/src/tools/MeasureTools/MeasurePointCloudTool.js.map +1 -1
  829. package/dist/core/components/viewers/pointcloud/src/tools/PCSearchTool.d.ts.map +1 -1
  830. package/dist/core/components/viewers/pointcloud/src/tools/PCSearchTool.js.map +1 -1
  831. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/NodeSizeSelectionTool.d.ts.map +1 -1
  832. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/NodeSizeSelectionTool.js.map +1 -1
  833. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/PerformanceSettingTools.d.ts.map +1 -1
  834. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/PerformanceSettingTools.js.map +1 -1
  835. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/PointBudgetTool.d.ts.map +1 -1
  836. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/PointBudgetTool.js.map +1 -1
  837. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/ShowOctreeBoxTool.d.ts.map +1 -1
  838. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/ShowOctreeBoxTool.js.map +1 -1
  839. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/SplatQualitySelection.d.ts.map +1 -1
  840. package/dist/core/components/viewers/pointcloud/src/tools/PerformanceSettingsTools/SplatQualitySelection.js.map +1 -1
  841. package/dist/core/components/viewers/pointcloud/src/tools/SetCameraOption.d.ts.map +1 -1
  842. package/dist/core/components/viewers/pointcloud/src/tools/SetCameraOption.js.map +1 -1
  843. package/dist/core/components/viewers/pointcloud/src/tools/SharePointCloudTool/index.d.ts.map +1 -1
  844. package/dist/core/components/viewers/pointcloud/src/tools/SharePointCloudTool/index.js.map +1 -1
  845. package/dist/core/components/viewers/pointcloud/src/tools/SharePointCloudTool/src/getCameraPosition.d.ts.map +1 -1
  846. package/dist/core/components/viewers/pointcloud/src/tools/SharePointCloudTool/src/getCameraPosition.js.map +1 -1
  847. package/dist/core/components/viewers/pointcloud/src/tools/index.d.ts.map +1 -1
  848. package/dist/core/components/viewers/pointcloud/src/tools/index.js.map +1 -1
  849. package/dist/core/components/viewers/pointcloud/src/tools/pointcloudToolbarTools.d.ts.map +1 -1
  850. package/dist/core/components/viewers/pointcloud/src/tools/pointcloudToolbarTools.js.map +1 -1
  851. package/dist/core/components/viewers/pointcloud/utils/potreeLoader.d.ts.map +1 -1
  852. package/dist/core/components/viewers/pointcloud/utils/potreeLoader.js.map +1 -1
  853. package/dist/core/components/viewers/pointcloud/utils/restoreCameraFromUrl.d.ts.map +1 -1
  854. package/dist/core/components/viewers/pointcloud/utils/restoreCameraFromUrl.js.map +1 -1
  855. package/dist/core/components/viewers/useCoordinateSystem.d.ts.map +1 -1
  856. package/dist/core/components/viewers/useCoordinateSystem.js.map +1 -1
  857. package/dist/core/hooks/buildings/buildings.d.ts.map +1 -1
  858. package/dist/core/hooks/buildings/buildings.js.map +1 -1
  859. package/dist/core/hooks/buildings/createBuildingHooks.d.ts.map +1 -1
  860. package/dist/core/hooks/buildings/createBuildingHooks.js.map +1 -1
  861. package/dist/core/hooks/comments/comments.d.ts.map +1 -1
  862. package/dist/core/hooks/comments/comments.js.map +1 -1
  863. package/dist/core/hooks/comments/createCommentHooks.d.ts.map +1 -1
  864. package/dist/core/hooks/comments/createCommentHooks.js.map +1 -1
  865. package/dist/core/hooks/files/createFileHooks.d.ts.map +1 -1
  866. package/dist/core/hooks/files/createFileHooks.js.map +1 -1
  867. package/dist/core/hooks/files/files.d.ts.map +1 -1
  868. package/dist/core/hooks/files/files.js.map +1 -1
  869. package/dist/core/hooks/index.d.ts.map +1 -1
  870. package/dist/core/hooks/index.js.map +1 -1
  871. package/dist/core/hooks/infrastructures/createInfrastructureHooks.d.ts.map +1 -1
  872. package/dist/core/hooks/infrastructures/createInfrastructureHooks.js.map +1 -1
  873. package/dist/core/hooks/infrastructures/infrastructures.d.ts.map +1 -1
  874. package/dist/core/hooks/infrastructures/infrastructures.js.map +1 -1
  875. package/dist/core/hooks/openDataPortals/createOpenDataPortalHooks.d.ts.map +1 -1
  876. package/dist/core/hooks/openDataPortals/createOpenDataPortalHooks.js.map +1 -1
  877. package/dist/core/hooks/openDataPortals/openDataPortals.d.ts.map +1 -1
  878. package/dist/core/hooks/openDataPortals/openDataPortals.js.map +1 -1
  879. package/dist/core/hooks/organizations/createOrganizationHooks.d.ts.map +1 -1
  880. package/dist/core/hooks/organizations/createOrganizationHooks.js.map +1 -1
  881. package/dist/core/hooks/organizations/organizations.d.ts.map +1 -1
  882. package/dist/core/hooks/organizations/organizations.js.map +1 -1
  883. package/dist/core/hooks/ports/apiAdapter.d.ts.map +1 -1
  884. package/dist/core/hooks/provider.d.ts.map +1 -1
  885. package/dist/core/hooks/provider.js.map +1 -1
  886. package/dist/core/hooks/sensorTypes/createSensorTypeHooks.d.ts.map +1 -1
  887. package/dist/core/hooks/sensorTypes/createSensorTypeHooks.js.map +1 -1
  888. package/dist/core/hooks/sensorTypes/sensorTypes.d.ts.map +1 -1
  889. package/dist/core/hooks/sensorTypes/sensorTypes.js.map +1 -1
  890. package/dist/core/hooks/sensors/createSensorHooks.d.ts.map +1 -1
  891. package/dist/core/hooks/sensors/createSensorHooks.js.map +1 -1
  892. package/dist/core/hooks/sensors/sensors.d.ts.map +1 -1
  893. package/dist/core/hooks/sensors/sensors.js.map +1 -1
  894. package/dist/core/hooks/sites/createSiteHooks.d.ts.map +1 -1
  895. package/dist/core/hooks/sites/createSiteHooks.js.map +1 -1
  896. package/dist/core/hooks/sites/sites.d.ts.map +1 -1
  897. package/dist/core/hooks/sites/sites.js.map +1 -1
  898. package/dist/core/hooks/ui/use-mobile.d.ts.map +1 -1
  899. package/dist/core/hooks/ui/use-mobile.js.map +1 -1
  900. package/dist/core/hooks/users/createUserHooks.d.ts.map +1 -1
  901. package/dist/core/hooks/users/createUserHooks.js.map +1 -1
  902. package/dist/core/hooks/users/users.d.ts.map +1 -1
  903. package/dist/core/hooks/users/users.js.map +1 -1
  904. package/dist/core/index.d.ts.map +1 -1
  905. package/dist/core/index.js.map +1 -1
  906. package/dist/core/plugins/host/context.d.ts.map +1 -1
  907. package/dist/core/plugins/host/context.js.map +1 -1
  908. package/dist/core/plugins/host/errors.d.ts.map +1 -1
  909. package/dist/core/plugins/host/errors.js.map +1 -1
  910. package/dist/core/plugins/host/host.d.ts.map +1 -1
  911. package/dist/core/plugins/host/host.js.map +1 -1
  912. package/dist/core/plugins/host/provider.d.ts.map +1 -1
  913. package/dist/core/plugins/host/provider.js.map +1 -1
  914. package/dist/core/plugins/host/registry.d.ts.map +1 -1
  915. package/dist/core/plugins/host/registry.js.map +1 -1
  916. package/dist/core/plugins/installed.d.ts.map +1 -1
  917. package/dist/core/plugins/installed.js.map +1 -1
  918. package/dist/core/plugins/sdk/components.d.ts.map +1 -1
  919. package/dist/core/plugins/sdk/components.js.map +1 -1
  920. package/dist/core/plugins/sdk/index.d.ts.map +1 -1
  921. package/dist/core/plugins/sdk/index.js.map +1 -1
  922. package/dist/core/plugins/sdk/types.d.ts.map +1 -1
  923. package/dist/core/plugins/sdk/types.js.map +1 -1
  924. package/dist/core/store/ActionMap.d.ts.map +1 -1
  925. package/dist/core/store/AppConfig/context.d.ts.map +1 -1
  926. package/dist/core/store/AppConfig/context.js.map +1 -1
  927. package/dist/core/store/AppConfig/reducer.d.ts.map +1 -1
  928. package/dist/core/store/AppConfig/reducer.js.map +1 -1
  929. package/dist/core/store/BIM/context.d.ts.map +1 -1
  930. package/dist/core/store/BIM/context.js.map +1 -1
  931. package/dist/core/store/BIM/reducer.d.ts.map +1 -1
  932. package/dist/core/store/BIM/reducer.js.map +1 -1
  933. package/dist/core/store/Buildings/context.d.ts.map +1 -1
  934. package/dist/core/store/Buildings/context.js.map +1 -1
  935. package/dist/core/store/Buildings/reducer.d.ts.map +1 -1
  936. package/dist/core/store/Buildings/reducer.js.map +1 -1
  937. package/dist/core/store/CombineProviders.d.ts.map +1 -1
  938. package/dist/core/store/CombineProviders.js.map +1 -1
  939. package/dist/core/store/Content/context.d.ts.map +1 -1
  940. package/dist/core/store/Content/context.js.map +1 -1
  941. package/dist/core/store/Datasets/context.d.ts.map +1 -1
  942. package/dist/core/store/Datasets/context.js.map +1 -1
  943. package/dist/core/store/Datasets/reducer.d.ts.map +1 -1
  944. package/dist/core/store/Datasets/reducer.js.map +1 -1
  945. package/dist/core/store/Files/context.d.ts.map +1 -1
  946. package/dist/core/store/Files/context.js.map +1 -1
  947. package/dist/core/store/Files/reducer.d.ts.map +1 -1
  948. package/dist/core/store/Files/reducer.js.map +1 -1
  949. package/dist/core/store/Map/context.d.ts.map +1 -1
  950. package/dist/core/store/Map/context.js.map +1 -1
  951. package/dist/core/store/Map/reducer.d.ts.map +1 -1
  952. package/dist/core/store/Map/reducer.js.map +1 -1
  953. package/dist/core/store/Menus/context.d.ts.map +1 -1
  954. package/dist/core/store/Menus/context.js.map +1 -1
  955. package/dist/core/store/Menus/reducer.d.ts.map +1 -1
  956. package/dist/core/store/Menus/reducer.js.map +1 -1
  957. package/dist/core/store/Permissions/context.d.ts.map +1 -1
  958. package/dist/core/store/Permissions/context.js.map +1 -1
  959. package/dist/core/store/PointCloud/context.d.ts.map +1 -1
  960. package/dist/core/store/PointCloud/context.js.map +1 -1
  961. package/dist/core/store/PointCloud/reducer.d.ts.map +1 -1
  962. package/dist/core/store/PointCloud/reducer.js.map +1 -1
  963. package/dist/core/store/Tools/context.d.ts.map +1 -1
  964. package/dist/core/store/Tools/context.js.map +1 -1
  965. package/dist/core/store/Tools/reducer.d.ts.map +1 -1
  966. package/dist/core/store/Tools/reducer.js.map +1 -1
  967. package/dist/core/store/index.d.ts.map +1 -1
  968. package/dist/core/store/index.js.map +1 -1
  969. package/dist/core/styles/tailwindMerge.d.ts.map +1 -1
  970. package/dist/core/styles/tailwindMerge.js.map +1 -1
  971. package/dist/core/types/bim.d.ts.map +1 -1
  972. package/dist/core/types/datasetTypes.d.ts.map +1 -1
  973. package/dist/core/types/dbTypes.d.ts.map +1 -1
  974. package/dist/core/types/dbTypes.js.map +1 -1
  975. package/dist/core/types/files.d.ts.map +1 -1
  976. package/dist/core/types/global.d.ts.map +1 -1
  977. package/dist/core/types/global.js.map +1 -1
  978. package/dist/core/types/index.d.ts.map +1 -1
  979. package/dist/core/types/index.js.map +1 -1
  980. package/dist/core/types/map.d.ts.map +1 -1
  981. package/dist/core/types/martinTypes.d.ts.map +1 -1
  982. package/dist/core/types/martinTypes.js.map +1 -1
  983. package/dist/core/types/next-auth.d.ts.map +1 -1
  984. package/dist/core/types/tools.d.ts.map +1 -1
  985. package/dist/core/types/users.d.ts.map +1 -1
  986. package/dist/core/utils/acceptedFiles.d.ts.map +1 -1
  987. package/dist/core/utils/acceptedFiles.js.map +1 -1
  988. package/dist/core/utils/errorHandler.d.ts.map +1 -1
  989. package/dist/core/utils/errorHandler.js.map +1 -1
  990. package/dist/core/utils/getFileIcon.d.ts.map +1 -1
  991. package/dist/core/utils/getFileIcon.js.map +1 -1
  992. package/dist/core/utils/imageUtils.d.ts.map +1 -1
  993. package/dist/core/utils/imageUtils.js.map +1 -1
  994. package/dist/core/utils/index.d.ts.map +1 -1
  995. package/dist/core/utils/index.js.map +1 -1
  996. package/dist/core/utils/markerUtils.d.ts.map +1 -1
  997. package/dist/core/utils/markerUtils.js.map +1 -1
  998. package/dist/core/utils/memcache.d.ts.map +1 -1
  999. package/dist/core/utils/memcache.js.map +1 -1
  1000. package/dist/core/utils/roles.d.ts.map +1 -1
  1001. package/dist/core/utils/roles.js.map +1 -1
  1002. package/dist/core/utils/timeUtils.d.ts.map +1 -1
  1003. package/dist/core/utils/timeUtils.js.map +1 -1
  1004. package/dist/core/utils/utils.d.ts.map +1 -1
  1005. package/dist/core/utils/utils.js.map +1 -1
  1006. package/dist/index.d.ts.map +1 -1
  1007. package/dist/index.js.map +1 -1
  1008. package/package.json +6 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/ModelManager/index.ts"],"sourcesContent":["import * as THREE from 'three'\r\nimport * as OBC from '@thatopen/components'\r\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'\r\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js'\r\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js'\r\nimport { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'\r\nimport { CurrentWorld } from '../CurrentWorld'\r\nimport { GizmoController } from '../../utils/GizmoController'\r\nimport { ViewportGizmo } from '../ViewportGizmo'\r\n\r\nexport interface ModelInfo {\r\n id: string\r\n name: string\r\n model: THREE.Group\r\n mixer?: THREE.AnimationMixer\r\n gizmoController?: GizmoController\r\n fileUrl?: string\r\n}\r\n\r\nexport interface LoadModelOptions {\r\n position?: THREE.Vector3\r\n scale?: number | THREE.Vector3\r\n rotation?: THREE.Euler\r\n enableGizmo?: boolean\r\n enableAnimations?: boolean\r\n extension?: string\r\n}\r\n\r\nexport class ModelManager extends OBC.Component {\r\n static uuid = '4cf01658-4a4e-49bd-8c89-4574db0032e9' as const\r\n\r\n enabled = true\r\n\r\n onModelLoaded = new OBC.Event<ModelInfo>()\r\n onModelTransformed = new OBC.Event<ModelInfo>()\r\n\r\n private _components: OBC.Components\r\n private _world: OBC.World | null = null\r\n private _gltfLoader: GLTFLoader\r\n private _objLoader: OBJLoader \r\n private _fbxLoader: FBXLoader \r\n private _colladaLoader: ColladaLoader \r\n private _models: Map<string, ModelInfo> = new Map()\r\n private _animationClock: THREE.Clock = new THREE.Clock()\r\n private _animationId: number | null = null\r\n\r\n constructor(components: OBC.Components) {\r\n super(components)\r\n components.add(ModelManager.uuid, this)\r\n this._components = components\r\n this._gltfLoader = new GLTFLoader()\r\n this._objLoader = new OBJLoader()\r\n this._fbxLoader = new FBXLoader()\r\n this._colladaLoader = new ColladaLoader()\r\n this._world = components.get(CurrentWorld).world\r\n this.startAnimationLoop()\r\n }\r\n\r\n /**\r\n * Load a 3D model (GLB/GLTF/OBJ/FBX/DAE) from a file or URL\r\n */\r\n async load(\r\n fileOrUrl: File | string,\r\n id: string,\r\n name: string,\r\n options: LoadModelOptions = {},\r\n ): Promise<ModelInfo | null> {\r\n if (!this._world) {\r\n console.error('World not available for model loading')\r\n return null\r\n }\r\n\r\n try {\r\n let fileUrl: string\r\n\r\n fileUrl = fileOrUrl instanceof File ? URL.createObjectURL(fileOrUrl) : fileOrUrl\r\n\r\n const extension = options.extension || this.getFileExtension(fileOrUrl)\r\n\r\n const result = await this.loadModelByType(fileUrl, extension)\r\n const model = result.scene || result\r\n\r\n if (options.position) {\r\n model.position.copy(options.position)\r\n }\r\n\r\n if (options.scale) {\r\n if (typeof options.scale === 'number') {\r\n model.scale.setScalar(options.scale)\r\n }\r\n else {\r\n model.scale.copy(options.scale)\r\n }\r\n }\r\n\r\n if (options.rotation) {\r\n model.rotation.copy(options.rotation)\r\n }\r\n\r\n this._world.scene.three.add(model)\r\n\r\n\r\n let mixer: THREE.AnimationMixer | undefined\r\n if (options.enableAnimations && result.animations && result.animations.length > 0) {\r\n mixer = this.setupAnimations(model, result.animations)\r\n }\r\n\r\n let gizmoController: GizmoController | undefined\r\n if (options.enableGizmo) {\r\n gizmoController = this.setupGizmo(model)\r\n }\r\n\r\n const modelInfo: ModelInfo = {\r\n id,\r\n name,\r\n model,\r\n mixer,\r\n gizmoController,\r\n fileUrl: fileOrUrl instanceof File ? fileUrl : undefined,\r\n }\r\n\r\n this._models.set(id, modelInfo);\r\n\r\n (model as any).modelId = id\r\n\r\n this.onModelLoaded.trigger(modelInfo)\r\n\r\n return modelInfo\r\n }\r\n catch (error) {\r\n console.error('Error loading 3D model:', error)\r\n\r\n if (fileOrUrl instanceof File) {\r\n URL.revokeObjectURL(fileOrUrl instanceof File ? URL.createObjectURL(fileOrUrl) : '')\r\n }\r\n\r\n return null\r\n }\r\n }\r\n\r\n /**\r\n * Remove a model from the scene\r\n */\r\n remove(id: string): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo || !this._world) return false\r\n\r\n this._world.scene.three.remove(modelInfo.model)\r\n\r\n\r\n if (modelInfo.gizmoController) {\r\n modelInfo.gizmoController.dispose()\r\n }\r\n\r\n // Cleanup mixer\r\n if (modelInfo.mixer) {\r\n modelInfo.mixer.stopAllAction()\r\n }\r\n\r\n // Cleanup file URL if it exists\r\n if (modelInfo.fileUrl) {\r\n URL.revokeObjectURL(modelInfo.fileUrl)\r\n }\r\n\r\n // Remove from storage\r\n this._models.delete(id)\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * Get model info by ID\r\n */\r\n getModel(id: string): ModelInfo | undefined {\r\n return this._models.get(id)\r\n }\r\n\r\n /**\r\n * Get model info by name (file.name)\r\n */\r\n getModelByName(name: string): ModelInfo | undefined {\r\n for (const modelInfo of this._models.values()) {\r\n if (modelInfo.name === name) return modelInfo\r\n }\r\n return undefined\r\n }\r\n\r\n /**\r\n * Get all loaded models\r\n */\r\n getAllModels(): ModelInfo[] {\r\n return [...this._models.values()]\r\n }\r\n\r\n /**\r\n * Enable/disable gizmo for a model\r\n */\r\n toggleGizmo(id: string, enable: boolean): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo || !this._world) return false\r\n\r\n if (enable && !modelInfo.gizmoController) {\r\n modelInfo.gizmoController = this.setupGizmo(modelInfo.model)\r\n return true\r\n }\r\n else if (!enable && modelInfo.gizmoController) {\r\n modelInfo.gizmoController.dispose()\r\n modelInfo.gizmoController = undefined\r\n return true\r\n }\r\n\r\n return false\r\n }\r\n\r\n /**\r\n * Update model position\r\n */\r\n setPosition(id: string, position: THREE.Vector3): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo) return false\r\n\r\n modelInfo.model.position.copy(position)\r\n this.onModelTransformed.trigger(modelInfo)\r\n return true\r\n }\r\n\r\n /**\r\n * Update model scale\r\n */\r\n setScale(id: string, scale: number | THREE.Vector3): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo) return false\r\n\r\n if (typeof scale === 'number') {\r\n modelInfo.model.scale.setScalar(scale)\r\n }\r\n else {\r\n modelInfo.model.scale.copy(scale)\r\n }\r\n\r\n this.onModelTransformed.trigger(modelInfo)\r\n return true\r\n }\r\n\r\n /**\r\n * Update model rotation\r\n */\r\n setRotation(id: string, rotation: THREE.Euler): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo) return false\r\n\r\n modelInfo.model.rotation.copy(rotation)\r\n this.onModelTransformed.trigger(modelInfo)\r\n return true\r\n }\r\n\r\n /**\r\n * Get file extension from File or URL\r\n */\r\n private getFileExtension(fileOrUrl: File | string): string {\r\n if (fileOrUrl instanceof File) {\r\n return fileOrUrl.name.split('.').pop()?.toLowerCase() || ''\r\n }\r\n const urlPath = fileOrUrl.split('?')[0]\r\n return urlPath.split('.').pop()?.toLowerCase() || ''\r\n }\r\n\r\n /**\r\n * Load model based on file type\r\n */\r\n private async loadModelByType(url: string, extension: string): Promise<any> {\r\n switch (extension) {\r\n case 'gltf':\r\n case 'glb':\r\n return this.loadGLTF(url)\r\n case 'obj':\r\n return this.loadOBJ(url)\r\n case 'fbx':\r\n return this.loadFBX(url)\r\n case 'dae':\r\n case 'collada':\r\n return this.loadCollada(url)\r\n default:\r\n throw new Error(`Unsupported file format: ${extension}`)\r\n }\r\n }\r\n\r\n /**\r\n * Load GLTF file using promise\r\n */\r\n private loadGLTF(url: string): Promise<any> {\r\n return new Promise((resolve, reject) => {\r\n this._gltfLoader.load(\r\n url,\r\n gltf => resolve(gltf),\r\n undefined,\r\n error => reject(error),\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * Load OBJ file using promise\r\n */\r\n private loadOBJ(url: string): Promise<THREE.Group> {\r\n return new Promise((resolve, reject) => {\r\n this._objLoader.load(\r\n url,\r\n obj => resolve(obj),\r\n undefined,\r\n error => reject(error),\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * Load FBX file using promise\r\n */\r\n private loadFBX(url: string): Promise<THREE.Group> {\r\n return new Promise((resolve, reject) => {\r\n this._fbxLoader.load(\r\n url,\r\n fbx => resolve(fbx),\r\n undefined,\r\n error => reject(error),\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * Load Collada file using promise\r\n */\r\n private loadCollada(url: string): Promise<any> {\r\n return new Promise((resolve, reject) => {\r\n this._colladaLoader.load(\r\n url,\r\n collada => resolve(collada),\r\n undefined,\r\n error => reject(error),\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * Setup animations for a model\r\n */\r\n private setupAnimations(model: THREE.Group, animations: THREE.AnimationClip[]): THREE.AnimationMixer {\r\n const mixer = new THREE.AnimationMixer(model)\r\n\r\n for (const clip of animations) {\r\n const action = mixer.clipAction(clip)\r\n action.play()\r\n }\r\n\r\n return mixer\r\n }\r\n\r\n /**\r\n * Setup gizmo controls for a model\r\n */\r\n private setupGizmo(model: THREE.Group): GizmoController {\r\n if (!this._world) {\r\n throw new Error('World not available for gizmo setup')\r\n }\r\n\r\n const gizmoController = new GizmoController(this._world)\r\n\r\n // Enter/Esc detach the gizmo internally; clear our reference so callers\r\n // (and the marker visibility check) know editing has ended.\r\n const endEditing = () => {\r\n const modelInfo = [...this._models.values()].find(info => info.model === model)\r\n if (!modelInfo) return\r\n model.updateMatrixWorld(true)\r\n modelInfo.gizmoController = undefined\r\n this.onModelTransformed.trigger(modelInfo)\r\n }\r\n gizmoController.onAccept = endEditing\r\n gizmoController.onCancel = endEditing\r\n\r\n gizmoController.attach(model)\r\n return gizmoController\r\n }\r\n\r\n /**\r\n * Start animation loop for all mixers\r\n */\r\n private startAnimationLoop(): void {\r\n const animate = () => {\r\n const delta = this._animationClock.getDelta()\r\n\r\n for (const [, modelInfo] of this._models) {\r\n if (modelInfo.mixer) {\r\n modelInfo.mixer.update(delta)\r\n }\r\n }\r\n\r\n this._animationId = requestAnimationFrame(animate)\r\n }\r\n\r\n animate()\r\n }\r\n\r\n /**\r\n * Stop animation loop\r\n */\r\n private stopAnimationLoop(): void {\r\n if (this._animationId !== null) {\r\n cancelAnimationFrame(this._animationId)\r\n this._animationId = null\r\n }\r\n }\r\n\r\n /**\r\n * Dispose and cleanup all resources\r\n */\r\n dispose(): void {\r\n this.stopAnimationLoop()\r\n\r\n for (const modelInfo of this._models.values()) {\r\n if (this._world) {\r\n this._world.scene.three.remove(modelInfo.model)\r\n }\r\n\r\n if (modelInfo.gizmoController) {\r\n modelInfo.gizmoController.dispose()\r\n }\r\n\r\n if (modelInfo.mixer) {\r\n modelInfo.mixer.stopAllAction()\r\n }\r\n\r\n if (modelInfo.fileUrl) {\r\n URL.revokeObjectURL(modelInfo.fileUrl)\r\n }\r\n }\r\n\r\n this._models.clear()\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/ModelManager/index.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as THREE from 'three'\r\nimport * as OBC from '@thatopen/components'\r\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'\r\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js'\r\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js'\r\nimport { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'\r\nimport { CurrentWorld } from '../CurrentWorld'\r\nimport { GizmoController } from '../../utils/GizmoController'\r\nimport { ViewportGizmo } from '../ViewportGizmo'\r\n\r\nexport interface ModelInfo {\r\n id: string\r\n name: string\r\n model: THREE.Group\r\n mixer?: THREE.AnimationMixer\r\n gizmoController?: GizmoController\r\n fileUrl?: string\r\n}\r\n\r\nexport interface LoadModelOptions {\r\n position?: THREE.Vector3\r\n scale?: number | THREE.Vector3\r\n rotation?: THREE.Euler\r\n enableGizmo?: boolean\r\n enableAnimations?: boolean\r\n extension?: string\r\n}\r\n\r\nexport class ModelManager extends OBC.Component {\r\n static uuid = '4cf01658-4a4e-49bd-8c89-4574db0032e9' as const\r\n\r\n enabled = true\r\n\r\n onModelLoaded = new OBC.Event<ModelInfo>()\r\n onModelTransformed = new OBC.Event<ModelInfo>()\r\n\r\n private _components: OBC.Components\r\n private _world: OBC.World | null = null\r\n private _gltfLoader: GLTFLoader\r\n private _objLoader: OBJLoader \r\n private _fbxLoader: FBXLoader \r\n private _colladaLoader: ColladaLoader \r\n private _models: Map<string, ModelInfo> = new Map()\r\n private _animationClock: THREE.Clock = new THREE.Clock()\r\n private _animationId: number | null = null\r\n\r\n constructor(components: OBC.Components) {\r\n super(components)\r\n components.add(ModelManager.uuid, this)\r\n this._components = components\r\n this._gltfLoader = new GLTFLoader()\r\n this._objLoader = new OBJLoader()\r\n this._fbxLoader = new FBXLoader()\r\n this._colladaLoader = new ColladaLoader()\r\n this._world = components.get(CurrentWorld).world\r\n this.startAnimationLoop()\r\n }\r\n\r\n /**\r\n * Load a 3D model (GLB/GLTF/OBJ/FBX/DAE) from a file or URL\r\n */\r\n async load(\r\n fileOrUrl: File | string,\r\n id: string,\r\n name: string,\r\n options: LoadModelOptions = {},\r\n ): Promise<ModelInfo | null> {\r\n if (!this._world) {\r\n console.error('World not available for model loading')\r\n return null\r\n }\r\n\r\n try {\r\n let fileUrl: string\r\n\r\n fileUrl = fileOrUrl instanceof File ? URL.createObjectURL(fileOrUrl) : fileOrUrl\r\n\r\n const extension = options.extension || this.getFileExtension(fileOrUrl)\r\n\r\n const result = await this.loadModelByType(fileUrl, extension)\r\n const model = result.scene || result\r\n\r\n if (options.position) {\r\n model.position.copy(options.position)\r\n }\r\n\r\n if (options.scale) {\r\n if (typeof options.scale === 'number') {\r\n model.scale.setScalar(options.scale)\r\n }\r\n else {\r\n model.scale.copy(options.scale)\r\n }\r\n }\r\n\r\n if (options.rotation) {\r\n model.rotation.copy(options.rotation)\r\n }\r\n\r\n this._world.scene.three.add(model)\r\n\r\n\r\n let mixer: THREE.AnimationMixer | undefined\r\n if (options.enableAnimations && result.animations && result.animations.length > 0) {\r\n mixer = this.setupAnimations(model, result.animations)\r\n }\r\n\r\n let gizmoController: GizmoController | undefined\r\n if (options.enableGizmo) {\r\n gizmoController = this.setupGizmo(model)\r\n }\r\n\r\n const modelInfo: ModelInfo = {\r\n id,\r\n name,\r\n model,\r\n mixer,\r\n gizmoController,\r\n fileUrl: fileOrUrl instanceof File ? fileUrl : undefined,\r\n }\r\n\r\n this._models.set(id, modelInfo);\r\n\r\n (model as any).modelId = id\r\n\r\n this.onModelLoaded.trigger(modelInfo)\r\n\r\n return modelInfo\r\n }\r\n catch (error) {\r\n console.error('Error loading 3D model:', error)\r\n\r\n if (fileOrUrl instanceof File) {\r\n URL.revokeObjectURL(fileOrUrl instanceof File ? URL.createObjectURL(fileOrUrl) : '')\r\n }\r\n\r\n return null\r\n }\r\n }\r\n\r\n /**\r\n * Remove a model from the scene\r\n */\r\n remove(id: string): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo || !this._world) return false\r\n\r\n this._world.scene.three.remove(modelInfo.model)\r\n\r\n\r\n if (modelInfo.gizmoController) {\r\n modelInfo.gizmoController.dispose()\r\n }\r\n\r\n // Cleanup mixer\r\n if (modelInfo.mixer) {\r\n modelInfo.mixer.stopAllAction()\r\n }\r\n\r\n // Cleanup file URL if it exists\r\n if (modelInfo.fileUrl) {\r\n URL.revokeObjectURL(modelInfo.fileUrl)\r\n }\r\n\r\n // Remove from storage\r\n this._models.delete(id)\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * Get model info by ID\r\n */\r\n getModel(id: string): ModelInfo | undefined {\r\n return this._models.get(id)\r\n }\r\n\r\n /**\r\n * Get model info by name (file.name)\r\n */\r\n getModelByName(name: string): ModelInfo | undefined {\r\n for (const modelInfo of this._models.values()) {\r\n if (modelInfo.name === name) return modelInfo\r\n }\r\n return undefined\r\n }\r\n\r\n /**\r\n * Get all loaded models\r\n */\r\n getAllModels(): ModelInfo[] {\r\n return [...this._models.values()]\r\n }\r\n\r\n /**\r\n * Enable/disable gizmo for a model\r\n */\r\n toggleGizmo(id: string, enable: boolean): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo || !this._world) return false\r\n\r\n if (enable && !modelInfo.gizmoController) {\r\n modelInfo.gizmoController = this.setupGizmo(modelInfo.model)\r\n return true\r\n }\r\n else if (!enable && modelInfo.gizmoController) {\r\n modelInfo.gizmoController.dispose()\r\n modelInfo.gizmoController = undefined\r\n return true\r\n }\r\n\r\n return false\r\n }\r\n\r\n /**\r\n * Update model position\r\n */\r\n setPosition(id: string, position: THREE.Vector3): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo) return false\r\n\r\n modelInfo.model.position.copy(position)\r\n this.onModelTransformed.trigger(modelInfo)\r\n return true\r\n }\r\n\r\n /**\r\n * Update model scale\r\n */\r\n setScale(id: string, scale: number | THREE.Vector3): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo) return false\r\n\r\n if (typeof scale === 'number') {\r\n modelInfo.model.scale.setScalar(scale)\r\n }\r\n else {\r\n modelInfo.model.scale.copy(scale)\r\n }\r\n\r\n this.onModelTransformed.trigger(modelInfo)\r\n return true\r\n }\r\n\r\n /**\r\n * Update model rotation\r\n */\r\n setRotation(id: string, rotation: THREE.Euler): boolean {\r\n const modelInfo = this._models.get(id)\r\n if (!modelInfo) return false\r\n\r\n modelInfo.model.rotation.copy(rotation)\r\n this.onModelTransformed.trigger(modelInfo)\r\n return true\r\n }\r\n\r\n /**\r\n * Get file extension from File or URL\r\n */\r\n private getFileExtension(fileOrUrl: File | string): string {\r\n if (fileOrUrl instanceof File) {\r\n return fileOrUrl.name.split('.').pop()?.toLowerCase() || ''\r\n }\r\n const urlPath = fileOrUrl.split('?')[0]\r\n return urlPath.split('.').pop()?.toLowerCase() || ''\r\n }\r\n\r\n /**\r\n * Load model based on file type\r\n */\r\n private async loadModelByType(url: string, extension: string): Promise<any> {\r\n switch (extension) {\r\n case 'gltf':\r\n case 'glb':\r\n return this.loadGLTF(url)\r\n case 'obj':\r\n return this.loadOBJ(url)\r\n case 'fbx':\r\n return this.loadFBX(url)\r\n case 'dae':\r\n case 'collada':\r\n return this.loadCollada(url)\r\n default:\r\n throw new Error(`Unsupported file format: ${extension}`)\r\n }\r\n }\r\n\r\n /**\r\n * Load GLTF file using promise\r\n */\r\n private loadGLTF(url: string): Promise<any> {\r\n return new Promise((resolve, reject) => {\r\n this._gltfLoader.load(\r\n url,\r\n gltf => resolve(gltf),\r\n undefined,\r\n error => reject(error),\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * Load OBJ file using promise\r\n */\r\n private loadOBJ(url: string): Promise<THREE.Group> {\r\n return new Promise((resolve, reject) => {\r\n this._objLoader.load(\r\n url,\r\n obj => resolve(obj),\r\n undefined,\r\n error => reject(error),\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * Load FBX file using promise\r\n */\r\n private loadFBX(url: string): Promise<THREE.Group> {\r\n return new Promise((resolve, reject) => {\r\n this._fbxLoader.load(\r\n url,\r\n fbx => resolve(fbx),\r\n undefined,\r\n error => reject(error),\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * Load Collada file using promise\r\n */\r\n private loadCollada(url: string): Promise<any> {\r\n return new Promise((resolve, reject) => {\r\n this._colladaLoader.load(\r\n url,\r\n collada => resolve(collada),\r\n undefined,\r\n error => reject(error),\r\n )\r\n })\r\n }\r\n\r\n /**\r\n * Setup animations for a model\r\n */\r\n private setupAnimations(model: THREE.Group, animations: THREE.AnimationClip[]): THREE.AnimationMixer {\r\n const mixer = new THREE.AnimationMixer(model)\r\n\r\n for (const clip of animations) {\r\n const action = mixer.clipAction(clip)\r\n action.play()\r\n }\r\n\r\n return mixer\r\n }\r\n\r\n /**\r\n * Setup gizmo controls for a model\r\n */\r\n private setupGizmo(model: THREE.Group): GizmoController {\r\n if (!this._world) {\r\n throw new Error('World not available for gizmo setup')\r\n }\r\n\r\n const gizmoController = new GizmoController(this._world)\r\n\r\n // Enter/Esc detach the gizmo internally; clear our reference so callers\r\n // (and the marker visibility check) know editing has ended.\r\n const endEditing = () => {\r\n const modelInfo = [...this._models.values()].find(info => info.model === model)\r\n if (!modelInfo) return\r\n model.updateMatrixWorld(true)\r\n modelInfo.gizmoController = undefined\r\n this.onModelTransformed.trigger(modelInfo)\r\n }\r\n gizmoController.onAccept = endEditing\r\n gizmoController.onCancel = endEditing\r\n\r\n gizmoController.attach(model)\r\n return gizmoController\r\n }\r\n\r\n /**\r\n * Start animation loop for all mixers\r\n */\r\n private startAnimationLoop(): void {\r\n const animate = () => {\r\n const delta = this._animationClock.getDelta()\r\n\r\n for (const [, modelInfo] of this._models) {\r\n if (modelInfo.mixer) {\r\n modelInfo.mixer.update(delta)\r\n }\r\n }\r\n\r\n this._animationId = requestAnimationFrame(animate)\r\n }\r\n\r\n animate()\r\n }\r\n\r\n /**\r\n * Stop animation loop\r\n */\r\n private stopAnimationLoop(): void {\r\n if (this._animationId !== null) {\r\n cancelAnimationFrame(this._animationId)\r\n this._animationId = null\r\n }\r\n }\r\n\r\n /**\r\n * Dispose and cleanup all resources\r\n */\r\n dispose(): void {\r\n this.stopAnimationLoop()\r\n\r\n for (const modelInfo of this._models.values()) {\r\n if (this._world) {\r\n this._world.scene.three.remove(modelInfo.model)\r\n }\r\n\r\n if (modelInfo.gizmoController) {\r\n modelInfo.gizmoController.dispose()\r\n }\r\n\r\n if (modelInfo.mixer) {\r\n modelInfo.mixer.stopAllAction()\r\n }\r\n\r\n if (modelInfo.fileUrl) {\r\n URL.revokeObjectURL(modelInfo.fileUrl)\r\n }\r\n }\r\n\r\n this._models.clear()\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"SimpleBimViewer.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/bim/src/SimpleBimViewer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAc/B,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAMnD,UAAU,KAAK;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,eAAe,CAAC,EAAC,IAAI,EAAE,KAAc,EAAE,MAAe,EAAC,EAAE,KAAK,qBAsR7E"}
1
+ {"version":3,"file":"SimpleBimViewer.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/bim/src/SimpleBimViewer.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAc/B,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAMnD,UAAU,KAAK;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,eAAe,CAAC,EAAC,IAAI,EAAE,KAAc,EAAE,MAAe,EAAC,EAAE,KAAK,qBAsR7E"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/core/components/viewers/bim/src/SimpleBimViewer.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport * as OBC from \"@thatopen/components\";\r\nimport * as OBF from \"@thatopen/components-front\"\r\nimport * as THREE from \"three\";\r\nimport { BimContext } from \"../../../../store\";\r\nimport { LoadingSpinner } from '../../../ui/LoadingSpinner';\r\n\r\nimport { CurrentWorld } from \"../src/CurrentWorld\";\r\nimport { CurrentCamera } from '../src/CurrentCamera';\r\nimport { FitCamera } from './FitCamera';\r\nimport { CameraProjection } from './CameraProjection';\r\nimport { SpatialStructure } from './SpatialStructure';\r\nimport { LoadModels } from './LoadModels';\r\nimport { IfcToFragments } from './IfcToFragments';\r\nimport { DbFile } from '../../../../types/dbTypes';\r\nimport { ModelManager } from './ModelManager';\r\nimport { FloorplanTool } from './FloorplanTool';\r\nimport { ElevationsTool } from './ElevationsTool';\r\nimport { ViewModeCoordinator } from './lib/ViewModeCoordinator';\r\n\r\ninterface Props {\r\n file: DbFile\r\n width?: string\r\n height?: string\r\n}\r\n\r\nexport function SimpleBimViewer({file, width = \"100%\", height = \"100%\"}: Props) {\r\n\r\n const { state: bimState, dispatch: bimDispatch } = React.useContext(BimContext);\r\n const { bimComponents } = bimState.bim;\r\n\r\n const containerRef = React.useRef<HTMLDivElement | null>(null);\r\n const workerUrlRef = React.useRef<string | null>(null); // To store the worker URL for cleanup\r\n const resizeObserverRef = React.useRef<ResizeObserver | null>(null); // To store the ResizeObserver for cleanup\r\n const [isLoading, setIsLoading] = React.useState(false);\r\n const [loadingMessage, setLoadingMessage] = React.useState('');\r\n\r\n const createViewer = React.useCallback(\r\n async () => {\r\n\r\n THREE.Object3D.DEFAULT_UP.set(0, 1, 0); // Y-up\r\n\r\n if (!containerRef.current || bimComponents) return;\r\n\r\n const container = containerRef.current;\r\n const components = new OBC.Components();\r\n const worlds = components.get(OBC.Worlds);\r\n const world = worlds.create<\r\n OBC.ShadowedScene,\r\n OBC.OrthoPerspectiveCamera,\r\n OBF.PostproductionRenderer\r\n >();\r\n\r\n world.scene = new OBC.ShadowedScene(components);\r\n\r\n world.renderer = new OBF.PostproductionRenderer(components, container);\r\n world.camera = new OBC.OrthoPerspectiveCamera(components);\r\n\r\n components.init();\r\n\r\n world.scene.setup();\r\n world.scene.three.background = null;\r\n\r\n const grids = components.get(OBC.Grids);\r\n const grid = grids.create(world);\r\n const axesHelper = new THREE.AxesHelper(5);\r\n world.scene.three.add(axesHelper);\r\n\r\n const fragments = components.get(OBC.FragmentsManager);\r\n\r\n const githubUrl =\r\n \"https://thatopen.github.io/engine_fragment/resources/worker.mjs\";\r\n const fetchedUrl = await fetch(githubUrl);\r\n const workerBlob = await fetchedUrl.blob();\r\n const workerFile = new File([workerBlob], \"worker.mjs\", {\r\n type: \"text/javascript\",\r\n });\r\n const workerUrl = URL.createObjectURL(workerFile);\r\n workerUrlRef.current = workerUrl; // Store reference for cleanup\r\n fragments.init(workerUrl);\r\n\r\n world.camera.controls.addEventListener(\"control\", () =>\r\n fragments.core.update(),\r\n );\r\n\r\n world.camera.controls.restThreshold = 0.005;\r\n world.camera.controls.addEventListener(\"rest\", () =>\r\n fragments.core.update(true)\r\n );\r\n\r\n components.get(CurrentWorld).world = world;\r\n components.get(CurrentCamera).camera = world.camera;\r\n\r\n // Enable shadows\r\n world.renderer.three.shadowMap.enabled = true;\r\n world.renderer.three.shadowMap.type = THREE.PCFSoftShadowMap;\r\n world.scene.setup({\r\n shadows: {\r\n cascade: 1,\r\n resolution: 1024,\r\n },\r\n });\r\n\r\n world.scene.distanceRenderer.excludedObjects.add(grid.three);\r\n\r\n await world.scene.updateShadows();\r\n\r\n world.camera.controls.addEventListener(\"rest\", async () => {\r\n await world.scene.updateShadows();\r\n });\r\n\r\n world.scene.three.background = null;\r\n\r\n bimDispatch({\r\n type: \"SET_COMPONENTS\",\r\n payload: { bimComponents: components, world, fragments }\r\n });\r\n\r\n // Use requestAnimationFrame to ensure resize happens after render\r\n requestAnimationFrame(() => {\r\n const containerWidth = container.clientWidth || 1303;\r\n const containerHeight = container.clientHeight || 500;\r\n world.renderer.resize(new THREE.Vector2(containerWidth, containerHeight));\r\n });\r\n\r\n // Get components (this will instantiate them if needed)\r\n components.get(FitCamera);\r\n components.get(CameraProjection);\r\n components.get(SpatialStructure);\r\n components.get(LoadModels);\r\n components.get(ViewModeCoordinator);\r\n components.get(FloorplanTool);\r\n components.get(ElevationsTool);\r\n\r\n // Grid injection is safe here — fragments.core is initialized.\r\n if (grid) {\r\n components.get(FloorplanTool).setGrid(grid);\r\n components.get(ElevationsTool).setGrid(grid);\r\n }\r\n const ifcToFragments = components.get(IfcToFragments);\r\n const loadModels = components.get(LoadModels);\r\n const modelManager = components.get(ModelManager);\r\n\r\n // Handle resize using container dimensions\r\n const handleResize = () => {\r\n const width = container.clientWidth || 1303;\r\n const height = container.clientHeight || 500;\r\n world.renderer?.resize(new THREE.Vector2(width, height));\r\n };\r\n \r\n // Watch for container size changes using ResizeObserver. This\r\n // already covers the window-resize case: when the window resizes,\r\n // the flex layout reshapes this container, and ResizeObserver\r\n // fires.\r\n const resizeObserver = new ResizeObserver(() => {\r\n handleResize();\r\n });\r\n resizeObserver.observe(container);\r\n resizeObserverRef.current = resizeObserver;\r\n\r\n // Listen to loading state changes from both components\r\n ifcToFragments.onLoadingStateChanged.add(({ isLoading, message }) => {\r\n setIsLoading(isLoading);\r\n setLoadingMessage(message);\r\n });\r\n\r\n loadModels.onLoadingStateChanged.add(({ isLoading, message }) => {\r\n setIsLoading(isLoading);\r\n setLoadingMessage(message);\r\n });\r\n\r\n // Load the model based on file extension\r\n try {\r\n const ext = file.extension.toLowerCase();\r\n \r\n if (ext === 'frag') {\r\n await loadModels.load(file.url, String(file.id));\r\n } else if (ext === 'ifc') {\r\n const fetchedFile = await fetch(file.url);\r\n const ifcFile = new File([await fetchedFile.arrayBuffer()], file.name, { type: \"application/octet-stream\" });\r\n const fragmentBytes = await ifcToFragments.loadFromFile(ifcFile);\r\n \r\n const fragmentBuffer = fragmentBytes.buffer as ArrayBuffer;\r\n const model = await fragments.core.load(fragmentBuffer, { modelId: String(file.id) });\r\n \r\n world.scene.three.add(model.object);\r\n model.useCamera(world.camera.three);\r\n \r\n setIsLoading(false);\r\n setLoadingMessage('');\r\n } else if (['gltf', 'glb', 'fbx', 'obj', 'dae', 'collada'].includes(ext)) {\r\n setIsLoading(true);\r\n setLoadingMessage('Loading 3D Model...');\r\n \r\n const urlWithExtension = file.url.includes('.') ? file.url : `${file.url}?ext=${ext}`;\r\n \r\n const fetchedFile = await fetch(file.url);\r\n const blob = await fetchedFile.blob();\r\n const modelFile = new File([blob], `${file.name}.${ext}`, { type: blob.type });\r\n \r\n const modelInfo = await modelManager.load(\r\n modelFile,\r\n String(file.id),\r\n file.name,\r\n {\r\n enableAnimations: true,\r\n enableGizmo: false\r\n }\r\n );\r\n \r\n if (modelInfo) {\r\n const box = new THREE.Box3().setFromObject(modelInfo.model);\r\n const center = box.getCenter(new THREE.Vector3());\r\n const size = box.getSize(new THREE.Vector3());\r\n \r\n const maxDim = Math.max(size.x, size.y, size.z);\r\n const fov = world.camera.three.fov * (Math.PI / 180);\r\n let cameraZ = Math.abs(maxDim / 2 / Math.tan(fov / 2));\r\n \r\n cameraZ *= 1.5;\r\n \r\n const camX = center.x;\r\n const camY = center.y;\r\n const camZ = center.z + cameraZ;\r\n \r\n world.camera.controls.setLookAt(\r\n camX, camY, camZ,\r\n center.x, center.y, center.z,\r\n true\r\n );\r\n }\r\n \r\n setIsLoading(false);\r\n setLoadingMessage('');\r\n }\r\n\r\n fragments.core.update(true);\r\n \r\n setTimeout(() => {\r\n const width = container.clientWidth || 1303;\r\n const height = container.clientHeight || 500;\r\n world.renderer.resize(new THREE.Vector2(width, height));\r\n \r\n window.dispatchEvent(new Event('resize'));\r\n }, 100);\r\n } catch (error) {\r\n console.error('Error loading BIM file:', error);\r\n setIsLoading(false);\r\n }\r\n \r\n }, []\r\n );\r\n\r\n React.useEffect(() => {\r\n createViewer();\r\n\r\n // Cleanup function to properly dispose of components when unmounting\r\n return () => {\r\n if (resizeObserverRef.current) {\r\n resizeObserverRef.current.disconnect();\r\n }\r\n if (bimComponents) {\r\n bimComponents.dispose();\r\n }\r\n bimDispatch({\r\n type: \"DISPOSE-BIM\"\r\n });\r\n };\r\n }, []);\r\n\r\n return (\r\n <div\r\n style={{\r\n position: \"relative\",\r\n width,\r\n height,\r\n minHeight: height,\r\n overflow: \"hidden\",\r\n display: \"flex\",\r\n flexDirection: \"column\"\r\n }}\r\n >\r\n {isLoading && (\r\n <div className=\"absolute z-10 inset-0 bg-background/50 backdrop-blur-[1px] flex items-center justify-center pointer-events-none\">\r\n <div className=\"self-stretch text-center text-foreground text-xl font-semibold font-['Inter'] leading-7 flex items-center justify-center gap-2\">\r\n {loadingMessage || \"Loading BIM Model\"}\r\n <LoadingSpinner size={20} />\r\n </div>\r\n </div>\r\n )}\r\n <div\r\n className=\"bim-container\"\r\n id=\"bim-viewer-container\"\r\n ref={containerRef}\r\n style={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n flex: 1,\r\n position: \"relative\",\r\n background: \"radial-gradient(circle, rgba(255, 255, 255, 1) 50%, rgba(220, 220, 220, 1) 100%)\",\r\n }}\r\n />\r\n </div>\r\n );\r\n}"],"mappings":"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","names":["width","height","isLoading"]}
1
+ {"version":3,"sources":["../../../../../../src/core/components/viewers/bim/src/SimpleBimViewer.tsx"],"sourcesContent":["\"use client\";\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from \"react\";\r\nimport * as OBC from \"@thatopen/components\";\r\nimport * as OBF from \"@thatopen/components-front\"\r\nimport * as THREE from \"three\";\r\nimport { BimContext } from \"../../../../store\";\r\nimport { LoadingSpinner } from '../../../ui/LoadingSpinner';\r\n\r\nimport { CurrentWorld } from \"../src/CurrentWorld\";\r\nimport { CurrentCamera } from '../src/CurrentCamera';\r\nimport { FitCamera } from './FitCamera';\r\nimport { CameraProjection } from './CameraProjection';\r\nimport { SpatialStructure } from './SpatialStructure';\r\nimport { LoadModels } from './LoadModels';\r\nimport { IfcToFragments } from './IfcToFragments';\r\nimport { DbFile } from '../../../../types/dbTypes';\r\nimport { ModelManager } from './ModelManager';\r\nimport { FloorplanTool } from './FloorplanTool';\r\nimport { ElevationsTool } from './ElevationsTool';\r\nimport { ViewModeCoordinator } from './lib/ViewModeCoordinator';\r\n\r\ninterface Props {\r\n file: DbFile\r\n width?: string\r\n height?: string\r\n}\r\n\r\nexport function SimpleBimViewer({file, width = \"100%\", height = \"100%\"}: Props) {\r\n\r\n const { state: bimState, dispatch: bimDispatch } = React.useContext(BimContext);\r\n const { bimComponents } = bimState.bim;\r\n\r\n const containerRef = React.useRef<HTMLDivElement | null>(null);\r\n const workerUrlRef = React.useRef<string | null>(null); // To store the worker URL for cleanup\r\n const resizeObserverRef = React.useRef<ResizeObserver | null>(null); // To store the ResizeObserver for cleanup\r\n const [isLoading, setIsLoading] = React.useState(false);\r\n const [loadingMessage, setLoadingMessage] = React.useState('');\r\n\r\n const createViewer = React.useCallback(\r\n async () => {\r\n\r\n THREE.Object3D.DEFAULT_UP.set(0, 1, 0); // Y-up\r\n\r\n if (!containerRef.current || bimComponents) return;\r\n\r\n const container = containerRef.current;\r\n const components = new OBC.Components();\r\n const worlds = components.get(OBC.Worlds);\r\n const world = worlds.create<\r\n OBC.ShadowedScene,\r\n OBC.OrthoPerspectiveCamera,\r\n OBF.PostproductionRenderer\r\n >();\r\n\r\n world.scene = new OBC.ShadowedScene(components);\r\n\r\n world.renderer = new OBF.PostproductionRenderer(components, container);\r\n world.camera = new OBC.OrthoPerspectiveCamera(components);\r\n\r\n components.init();\r\n\r\n world.scene.setup();\r\n world.scene.three.background = null;\r\n\r\n const grids = components.get(OBC.Grids);\r\n const grid = grids.create(world);\r\n const axesHelper = new THREE.AxesHelper(5);\r\n world.scene.three.add(axesHelper);\r\n\r\n const fragments = components.get(OBC.FragmentsManager);\r\n\r\n const githubUrl =\r\n \"https://thatopen.github.io/engine_fragment/resources/worker.mjs\";\r\n const fetchedUrl = await fetch(githubUrl);\r\n const workerBlob = await fetchedUrl.blob();\r\n const workerFile = new File([workerBlob], \"worker.mjs\", {\r\n type: \"text/javascript\",\r\n });\r\n const workerUrl = URL.createObjectURL(workerFile);\r\n workerUrlRef.current = workerUrl; // Store reference for cleanup\r\n fragments.init(workerUrl);\r\n\r\n world.camera.controls.addEventListener(\"control\", () =>\r\n fragments.core.update(),\r\n );\r\n\r\n world.camera.controls.restThreshold = 0.005;\r\n world.camera.controls.addEventListener(\"rest\", () =>\r\n fragments.core.update(true)\r\n );\r\n\r\n components.get(CurrentWorld).world = world;\r\n components.get(CurrentCamera).camera = world.camera;\r\n\r\n // Enable shadows\r\n world.renderer.three.shadowMap.enabled = true;\r\n world.renderer.three.shadowMap.type = THREE.PCFSoftShadowMap;\r\n world.scene.setup({\r\n shadows: {\r\n cascade: 1,\r\n resolution: 1024,\r\n },\r\n });\r\n\r\n world.scene.distanceRenderer.excludedObjects.add(grid.three);\r\n\r\n await world.scene.updateShadows();\r\n\r\n world.camera.controls.addEventListener(\"rest\", async () => {\r\n await world.scene.updateShadows();\r\n });\r\n\r\n world.scene.three.background = null;\r\n\r\n bimDispatch({\r\n type: \"SET_COMPONENTS\",\r\n payload: { bimComponents: components, world, fragments }\r\n });\r\n\r\n // Use requestAnimationFrame to ensure resize happens after render\r\n requestAnimationFrame(() => {\r\n const containerWidth = container.clientWidth || 1303;\r\n const containerHeight = container.clientHeight || 500;\r\n world.renderer.resize(new THREE.Vector2(containerWidth, containerHeight));\r\n });\r\n\r\n // Get components (this will instantiate them if needed)\r\n components.get(FitCamera);\r\n components.get(CameraProjection);\r\n components.get(SpatialStructure);\r\n components.get(LoadModels);\r\n components.get(ViewModeCoordinator);\r\n components.get(FloorplanTool);\r\n components.get(ElevationsTool);\r\n\r\n // Grid injection is safe here — fragments.core is initialized.\r\n if (grid) {\r\n components.get(FloorplanTool).setGrid(grid);\r\n components.get(ElevationsTool).setGrid(grid);\r\n }\r\n const ifcToFragments = components.get(IfcToFragments);\r\n const loadModels = components.get(LoadModels);\r\n const modelManager = components.get(ModelManager);\r\n\r\n // Handle resize using container dimensions\r\n const handleResize = () => {\r\n const width = container.clientWidth || 1303;\r\n const height = container.clientHeight || 500;\r\n world.renderer?.resize(new THREE.Vector2(width, height));\r\n };\r\n \r\n // Watch for container size changes using ResizeObserver. This\r\n // already covers the window-resize case: when the window resizes,\r\n // the flex layout reshapes this container, and ResizeObserver\r\n // fires.\r\n const resizeObserver = new ResizeObserver(() => {\r\n handleResize();\r\n });\r\n resizeObserver.observe(container);\r\n resizeObserverRef.current = resizeObserver;\r\n\r\n // Listen to loading state changes from both components\r\n ifcToFragments.onLoadingStateChanged.add(({ isLoading, message }) => {\r\n setIsLoading(isLoading);\r\n setLoadingMessage(message);\r\n });\r\n\r\n loadModels.onLoadingStateChanged.add(({ isLoading, message }) => {\r\n setIsLoading(isLoading);\r\n setLoadingMessage(message);\r\n });\r\n\r\n // Load the model based on file extension\r\n try {\r\n const ext = file.extension.toLowerCase();\r\n \r\n if (ext === 'frag') {\r\n await loadModels.load(file.url, String(file.id));\r\n } else if (ext === 'ifc') {\r\n const fetchedFile = await fetch(file.url);\r\n const ifcFile = new File([await fetchedFile.arrayBuffer()], file.name, { type: \"application/octet-stream\" });\r\n const fragmentBytes = await ifcToFragments.loadFromFile(ifcFile);\r\n \r\n const fragmentBuffer = fragmentBytes.buffer as ArrayBuffer;\r\n const model = await fragments.core.load(fragmentBuffer, { modelId: String(file.id) });\r\n \r\n world.scene.three.add(model.object);\r\n model.useCamera(world.camera.three);\r\n \r\n setIsLoading(false);\r\n setLoadingMessage('');\r\n } else if (['gltf', 'glb', 'fbx', 'obj', 'dae', 'collada'].includes(ext)) {\r\n setIsLoading(true);\r\n setLoadingMessage('Loading 3D Model...');\r\n \r\n const urlWithExtension = file.url.includes('.') ? file.url : `${file.url}?ext=${ext}`;\r\n \r\n const fetchedFile = await fetch(file.url);\r\n const blob = await fetchedFile.blob();\r\n const modelFile = new File([blob], `${file.name}.${ext}`, { type: blob.type });\r\n \r\n const modelInfo = await modelManager.load(\r\n modelFile,\r\n String(file.id),\r\n file.name,\r\n {\r\n enableAnimations: true,\r\n enableGizmo: false\r\n }\r\n );\r\n \r\n if (modelInfo) {\r\n const box = new THREE.Box3().setFromObject(modelInfo.model);\r\n const center = box.getCenter(new THREE.Vector3());\r\n const size = box.getSize(new THREE.Vector3());\r\n \r\n const maxDim = Math.max(size.x, size.y, size.z);\r\n const fov = world.camera.three.fov * (Math.PI / 180);\r\n let cameraZ = Math.abs(maxDim / 2 / Math.tan(fov / 2));\r\n \r\n cameraZ *= 1.5;\r\n \r\n const camX = center.x;\r\n const camY = center.y;\r\n const camZ = center.z + cameraZ;\r\n \r\n world.camera.controls.setLookAt(\r\n camX, camY, camZ,\r\n center.x, center.y, center.z,\r\n true\r\n );\r\n }\r\n \r\n setIsLoading(false);\r\n setLoadingMessage('');\r\n }\r\n\r\n fragments.core.update(true);\r\n \r\n setTimeout(() => {\r\n const width = container.clientWidth || 1303;\r\n const height = container.clientHeight || 500;\r\n world.renderer.resize(new THREE.Vector2(width, height));\r\n \r\n window.dispatchEvent(new Event('resize'));\r\n }, 100);\r\n } catch (error) {\r\n console.error('Error loading BIM file:', error);\r\n setIsLoading(false);\r\n }\r\n \r\n }, []\r\n );\r\n\r\n React.useEffect(() => {\r\n createViewer();\r\n\r\n // Cleanup function to properly dispose of components when unmounting\r\n return () => {\r\n if (resizeObserverRef.current) {\r\n resizeObserverRef.current.disconnect();\r\n }\r\n if (bimComponents) {\r\n bimComponents.dispose();\r\n }\r\n bimDispatch({\r\n type: \"DISPOSE-BIM\"\r\n });\r\n };\r\n }, []);\r\n\r\n return (\r\n <div\r\n style={{\r\n position: \"relative\",\r\n width,\r\n height,\r\n minHeight: height,\r\n overflow: \"hidden\",\r\n display: \"flex\",\r\n flexDirection: \"column\"\r\n }}\r\n >\r\n {isLoading && (\r\n <div className=\"absolute z-10 inset-0 bg-background/50 backdrop-blur-[1px] flex items-center justify-center pointer-events-none\">\r\n <div className=\"self-stretch text-center text-foreground text-xl font-semibold font-['Inter'] leading-7 flex items-center justify-center gap-2\">\r\n {loadingMessage || \"Loading BIM Model\"}\r\n <LoadingSpinner size={20} />\r\n </div>\r\n </div>\r\n )}\r\n <div\r\n className=\"bim-container\"\r\n id=\"bim-viewer-container\"\r\n ref={containerRef}\r\n style={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n flex: 1,\r\n position: \"relative\",\r\n background: \"radial-gradient(circle, rgba(255, 255, 255, 1) 50%, rgba(220, 220, 220, 1) 100%)\",\r\n }}\r\n />\r\n </div>\r\n );\r\n}"],"mappings":"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","names":["width","height","isLoading"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SpatialStructure.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/bim/src/SpatialStructure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAE3C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B;AAED,qBAAa,gBAAiB,SAAQ,GAAG,CAAC,SAAS;IACjD,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAG,sCAAsC,CAAS;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAEnE,OAAO,UAAO;IAGd,QAAQ,CAAC,yBAAyB;cAAyB,eAAe,GAAG,IAAI;OAAK;IAGtF,QAAQ,CAAC,qBAAqB;mBAA8B,OAAO;OAAK;IAExE,OAAO,CAAC,SAAS,CAAoC;IAErD,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,cAAc,CAA4C;IAClE,OAAO,CAAC,gBAAgB,CAAqD;IAC7E,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,UAAU,CAAiB;gBAEvB,UAAU,EAAE,GAAG,CAAC,UAAU;IAMtC;;OAEG;IACH,IAAI,IAAI,IAAI,eAAe,GAAG,IAAI,CAEjC;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,UAAU;IAKZ,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAqE3E;;OAEG;IACH,qBAAqB,IAAI,IAAI;IAS7B,OAAO,CAAC,0BAA0B;IAsBlC,OAAO,CAAC,2BAA2B;IAYnC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,0BAA0B;IAKlC,OAAO,CAAC,gBAAgB;YAaV,cAAc;YAMd,yBAAyB;IA8EvC,OAAO,CAAC,2BAA2B;IAuBnC,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,YAAY;IA2BpB,OAAO,CAAC,iBAAiB;CAuB1B"}
1
+ {"version":3,"file":"SpatialStructure.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/bim/src/SpatialStructure.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAE3C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B;AAED,qBAAa,gBAAiB,SAAQ,GAAG,CAAC,SAAS;IACjD,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAG,sCAAsC,CAAS;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAEnE,OAAO,UAAO;IAGd,QAAQ,CAAC,yBAAyB;cAAyB,eAAe,GAAG,IAAI;OAAK;IAGtF,QAAQ,CAAC,qBAAqB;mBAA8B,OAAO;OAAK;IAExE,OAAO,CAAC,SAAS,CAAoC;IAErD,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,cAAc,CAA4C;IAClE,OAAO,CAAC,gBAAgB,CAAqD;IAC7E,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,UAAU,CAAiB;gBAEvB,UAAU,EAAE,GAAG,CAAC,UAAU;IAMtC;;OAEG;IACH,IAAI,IAAI,IAAI,eAAe,GAAG,IAAI,CAEjC;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,UAAU;IAKZ,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAqE3E;;OAEG;IACH,qBAAqB,IAAI,IAAI;IAS7B,OAAO,CAAC,0BAA0B;IAsBlC,OAAO,CAAC,2BAA2B;IAYnC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,0BAA0B;IAKlC,OAAO,CAAC,gBAAgB;YAaV,cAAc;YAMd,yBAAyB;IA8EvC,OAAO,CAAC,2BAA2B;IAuBnC,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,YAAY;IA2BpB,OAAO,CAAC,iBAAiB;CAuB1B"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/core/components/viewers/bim/src/SpatialStructure.ts"],"sourcesContent":["import * as OBC from '@thatopen/components'\r\n\r\nexport interface SpatialTreeItem {\r\n name: string\r\n children: SpatialTreeItem[]\r\n localId?: number\r\n ifcCategory?: string | null\r\n}\r\n\r\nexport class SpatialStructure extends OBC.Component {\r\n static readonly uuid = '8f7e4d2c-1a9b-4e6f-8c3d-5b2a9f7e4d2c' as const\r\n private static readonly cacheKeyPrefix = 'bim:spatial-structure:v1'\r\n\r\n enabled = true\r\n\r\n // Event that fires when spatial structure is created\r\n readonly onSpatialStructureCreated = new OBC.Event<{ tree: SpatialTreeItem | null }>()\r\n\r\n // Event that fires when loading state changes\r\n readonly onLoadingStateChanged = new OBC.Event<{ isLoading: boolean }>()\r\n\r\n private fragments: OBC.FragmentsManager | null = null\r\n \r\n private _tree: SpatialTreeItem | null = null\r\n private _treeByModelId = new Map<string, SpatialTreeItem | null>()\r\n private _loadingPromises = new Map<string, Promise<SpatialTreeItem | null>>()\r\n private _activeRequests = 0\r\n private _isLoading: boolean = false\r\n\r\n constructor(components: OBC.Components) {\r\n super(components)\r\n components.add(SpatialStructure.uuid, this)\r\n this.fragments = components.get(OBC.FragmentsManager)\r\n }\r\n\r\n /**\r\n * Get the current spatial structure\r\n */\r\n get tree(): SpatialTreeItem | null {\r\n return this._tree\r\n }\r\n\r\n /**\r\n * Get the loading state of spatial structure processing\r\n */\r\n get isLoading(): boolean {\r\n return this._isLoading\r\n }\r\n\r\n /**\r\n * Set the loading state and trigger the loading state change event\r\n */\r\n private setLoadingState(isLoading: boolean): void {\r\n if (this._isLoading !== isLoading) {\r\n this._isLoading = isLoading\r\n this.onLoadingStateChanged.trigger({ isLoading })\r\n }\r\n }\r\n\r\n private beginLoading(): void {\r\n this._activeRequests += 1\r\n this.setLoadingState(true)\r\n }\r\n\r\n private endLoading(): void {\r\n this._activeRequests = Math.max(0, this._activeRequests - 1)\r\n this.setLoadingState(this._activeRequests > 0)\r\n }\r\n\r\n async getSpatialStructure(modelId: string): Promise<SpatialTreeItem | null> {\r\n if (!this.fragments || !modelId) {\r\n throw new Error('No fragments or modelId available')\r\n }\r\n\r\n const cachedTree = this._treeByModelId.get(modelId)\r\n if (cachedTree !== undefined) {\r\n this._tree = cachedTree\r\n this.onSpatialStructureCreated.trigger({ tree: cachedTree })\r\n return cachedTree\r\n }\r\n\r\n const persistedTree = this.readCachedSpatialStructure(modelId)\r\n if (persistedTree) {\r\n this._tree = persistedTree\r\n this._treeByModelId.set(modelId, persistedTree)\r\n this.onSpatialStructureCreated.trigger({ tree: persistedTree })\r\n return persistedTree\r\n }\r\n\r\n const existingPromise = this._loadingPromises.get(modelId)\r\n if (existingPromise) {\r\n return existingPromise\r\n }\r\n\r\n const loadingPromise = Promise.resolve()\r\n .then(async () => {\r\n this.beginLoading()\r\n\r\n const model = this.fragments.list.get(modelId)\r\n if (!model) {\r\n throw new Error(`Model with ID ${modelId} not found in fragments.`)\r\n }\r\n\r\n const structure = await model.getSpatialStructure()\r\n\r\n const transformedStructure = await this.transformSpatialStructure(structure, model, modelId)\r\n\r\n // console.log('Transformed spatial structure:', transformedStructure)\r\n\r\n // Set the current spatial structure\r\n this._tree = transformedStructure\r\n if (transformedStructure) {\r\n this._treeByModelId.set(modelId, transformedStructure)\r\n this.writeCachedSpatialStructure(modelId, transformedStructure)\r\n } else {\r\n this._treeByModelId.delete(modelId)\r\n }\r\n\r\n // Trigger the event that spatial structure is created\r\n this.onSpatialStructureCreated.trigger({ tree: transformedStructure })\r\n\r\n return transformedStructure\r\n })\r\n .catch((error) => {\r\n console.error('Error getting spatial structure:', error)\r\n this._tree = null\r\n this.onSpatialStructureCreated.trigger({ tree: null })\r\n return null\r\n })\r\n .finally(() => {\r\n this._loadingPromises.delete(modelId)\r\n this.endLoading()\r\n })\r\n\r\n this._loadingPromises.set(modelId, loadingPromise)\r\n return loadingPromise\r\n }\r\n\r\n /**\r\n * Clear the current spatial structure\r\n */\r\n clearSpatialStructure(): void {\r\n this._tree = null\r\n this._treeByModelId.clear()\r\n this._loadingPromises.clear()\r\n this._activeRequests = 0\r\n this.setLoadingState(false)\r\n this.onSpatialStructureCreated.trigger({ tree: null })\r\n }\r\n\r\n private readCachedSpatialStructure(modelId: string): SpatialTreeItem | null {\r\n if (typeof window === 'undefined') {\r\n return null\r\n }\r\n\r\n try {\r\n const cachedValue = window.localStorage.getItem(this.getCacheKey(modelId))\r\n if (!cachedValue) {\r\n return null\r\n }\r\n\r\n const parsed = JSON.parse(cachedValue) as SpatialTreeItem\r\n if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.children)) {\r\n return null\r\n }\r\n\r\n return parsed\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n private writeCachedSpatialStructure(modelId: string, tree: SpatialTreeItem): void {\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n try {\r\n window.localStorage.setItem(this.getCacheKey(modelId), JSON.stringify(tree))\r\n } catch (error) {\r\n console.warn('Failed to persist spatial structure cache:', error)\r\n }\r\n }\r\n\r\n private getCacheKey(modelId: string): string {\r\n return `${SpatialStructure.cacheKeyPrefix}:${modelId}`\r\n }\r\n\r\n private emitSpatialStructureUpdate(tree: SpatialTreeItem | null): void {\r\n this._tree = tree\r\n this.onSpatialStructureCreated.trigger({ tree: this.cloneSpatialTree(tree) })\r\n }\r\n\r\n private cloneSpatialTree(tree: SpatialTreeItem | null): SpatialTreeItem | null {\r\n if (!tree) {\r\n return null\r\n }\r\n\r\n return {\r\n name: tree.name,\r\n localId: tree.localId,\r\n ifcCategory: tree.ifcCategory,\r\n children: tree.children.map((child) => this.cloneSpatialTree(child) as SpatialTreeItem),\r\n }\r\n }\r\n\r\n private async yieldToBrowser(): Promise<void> {\r\n await new Promise<void>((resolve) => {\r\n setTimeout(resolve, 0)\r\n })\r\n }\r\n\r\n private async transformSpatialStructure(rawStructure: any, model: any, modelId: string): Promise<SpatialTreeItem | null> {\r\n if (!rawStructure) {\r\n return null\r\n }\r\n\r\n const localIdsNeedingNames = new Set<number>()\r\n this.collectLocalIdsNeedingNames(rawStructure, localIdsNeedingNames)\r\n\r\n const nameByLocalId = new Map<number, string>()\r\n if (localIdsNeedingNames.size > 0) {\r\n try {\r\n const localIds = [...localIdsNeedingNames]\r\n const itemData = await model.getItemsData(localIds, {\r\n attributesDefault: false,\r\n attributes: ['Name'],\r\n })\r\n\r\n for (let i = 0; i < itemData.length; i++) {\r\n const data = itemData[i]\r\n const localId = localIds[i]\r\n const name = data?.Name?.value\r\n if (localId !== undefined && typeof name === 'string' && name.trim()) {\r\n nameByLocalId.set(localId, name)\r\n }\r\n }\r\n } catch (error) {\r\n console.warn('Failed to batch spatial-structure names:', error)\r\n }\r\n }\r\n\r\n // Find the building first\r\n const building = this.findBuilding(rawStructure)\r\n if (!building) {\r\n console.warn('No IFCBUILDING found in spatial structure')\r\n return null\r\n }\r\n\r\n const childrenSource = this.getRenderableChildren(building)\r\n const children: SpatialTreeItem[] = childrenSource.map((child) => this.createSpatialNode(child, nameByLocalId))\r\n const root: SpatialTreeItem = {\r\n name: 'Root',\r\n children,\r\n }\r\n\r\n if (children.length === 0) {\r\n this.emitSpatialStructureUpdate(root)\r\n return root\r\n }\r\n\r\n this.emitSpatialStructureUpdate(root)\r\n await this.yieldToBrowser()\r\n\r\n let frontier: Array<{ source: any; target: SpatialTreeItem }> = children.map((target, index) => ({\r\n source: childrenSource[index],\r\n target,\r\n }))\r\n\r\n while (frontier.length > 0) {\r\n const nextFrontier: Array<{ source: any; target: SpatialTreeItem }> = []\r\n\r\n for (const { source, target } of frontier) {\r\n const sourceChildren = this.getRenderableChildren(source)\r\n const nextChildren = sourceChildren.map((child) => this.createSpatialNode(child, nameByLocalId))\r\n target.children = nextChildren\r\n\r\n for (let i = 0; i < nextChildren.length; i++) {\r\n nextFrontier.push({ source: sourceChildren[i], target: nextChildren[i] })\r\n }\r\n }\r\n\r\n this.emitSpatialStructureUpdate(root)\r\n await this.yieldToBrowser()\r\n frontier = nextFrontier\r\n }\r\n\r\n return root\r\n }\r\n\r\n private collectLocalIdsNeedingNames(item: any, localIds: Set<number>): void {\r\n if (!item) {\r\n return\r\n }\r\n\r\n if (item?.localId && !item?.Name?.value && !item?.category && !item?.type) {\r\n localIds.add(item.localId)\r\n }\r\n\r\n if (Array.isArray(item)) {\r\n for (const child of item) {\r\n this.collectLocalIdsNeedingNames(child, localIds)\r\n }\r\n return\r\n }\r\n\r\n if (item?.children) {\r\n for (const child of item.children) {\r\n this.collectLocalIdsNeedingNames(child, localIds)\r\n }\r\n }\r\n }\r\n\r\n private getRenderableChildren(item: any): any[] {\r\n const children = Array.isArray(item?.children) ? item.children : []\r\n const flattened: any[] = []\r\n\r\n for (const child of children) {\r\n if (child?.category === 'IFCBUILDINGSTOREY' || child?.type === 'IFCBUILDINGSTOREY') {\r\n if (Array.isArray(child.children)) {\r\n flattened.push(...child.children)\r\n }\r\n } else {\r\n flattened.push(child)\r\n }\r\n }\r\n\r\n return flattened\r\n }\r\n\r\n private findBuilding(item: any): any {\r\n if (!item) return null\r\n \r\n // Check if current item is a building\r\n if (item?.category === 'IFCBUILDING' || item?.type === 'IFCBUILDING') {\r\n return item\r\n }\r\n \r\n // Search in children if it's an array\r\n if (Array.isArray(item)) {\r\n for (const child of item) {\r\n const found = this.findBuilding(child)\r\n if (found) return found\r\n }\r\n }\r\n \r\n // Search in children property\r\n if (item?.children) {\r\n for (const child of item.children) {\r\n const found = this.findBuilding(child)\r\n if (found) return found\r\n }\r\n }\r\n \r\n return null\r\n }\r\n\r\n private createSpatialNode(item: any, nameByLocalId: Map<number, string>): SpatialTreeItem {\r\n // Get item name\r\n let name = 'Unknown'\r\n if (item?.Name?.value) {\r\n name = item.Name.value\r\n } else if (item?.category || item?.type) {\r\n name = item.category || item.type\r\n } else if (item?.localId && nameByLocalId.has(item.localId)) {\r\n name = nameByLocalId.get(item.localId) || `Item ${item.localId}`\r\n } else if (item?.localId) {\r\n name = `Item ${item.localId}`\r\n }\r\n\r\n const result: SpatialTreeItem = {\r\n name: String(name),\r\n children: [],\r\n }\r\n\r\n if (item?.category) result.ifcCategory = item.category\r\n if (item?.localId) result.localId = item.localId\r\n\r\n return result\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../src/core/components/viewers/bim/src/SpatialStructure.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as OBC from '@thatopen/components'\r\n\r\nexport interface SpatialTreeItem {\r\n name: string\r\n children: SpatialTreeItem[]\r\n localId?: number\r\n ifcCategory?: string | null\r\n}\r\n\r\nexport class SpatialStructure extends OBC.Component {\r\n static readonly uuid = '8f7e4d2c-1a9b-4e6f-8c3d-5b2a9f7e4d2c' as const\r\n private static readonly cacheKeyPrefix = 'bim:spatial-structure:v1'\r\n\r\n enabled = true\r\n\r\n // Event that fires when spatial structure is created\r\n readonly onSpatialStructureCreated = new OBC.Event<{ tree: SpatialTreeItem | null }>()\r\n\r\n // Event that fires when loading state changes\r\n readonly onLoadingStateChanged = new OBC.Event<{ isLoading: boolean }>()\r\n\r\n private fragments: OBC.FragmentsManager | null = null\r\n \r\n private _tree: SpatialTreeItem | null = null\r\n private _treeByModelId = new Map<string, SpatialTreeItem | null>()\r\n private _loadingPromises = new Map<string, Promise<SpatialTreeItem | null>>()\r\n private _activeRequests = 0\r\n private _isLoading: boolean = false\r\n\r\n constructor(components: OBC.Components) {\r\n super(components)\r\n components.add(SpatialStructure.uuid, this)\r\n this.fragments = components.get(OBC.FragmentsManager)\r\n }\r\n\r\n /**\r\n * Get the current spatial structure\r\n */\r\n get tree(): SpatialTreeItem | null {\r\n return this._tree\r\n }\r\n\r\n /**\r\n * Get the loading state of spatial structure processing\r\n */\r\n get isLoading(): boolean {\r\n return this._isLoading\r\n }\r\n\r\n /**\r\n * Set the loading state and trigger the loading state change event\r\n */\r\n private setLoadingState(isLoading: boolean): void {\r\n if (this._isLoading !== isLoading) {\r\n this._isLoading = isLoading\r\n this.onLoadingStateChanged.trigger({ isLoading })\r\n }\r\n }\r\n\r\n private beginLoading(): void {\r\n this._activeRequests += 1\r\n this.setLoadingState(true)\r\n }\r\n\r\n private endLoading(): void {\r\n this._activeRequests = Math.max(0, this._activeRequests - 1)\r\n this.setLoadingState(this._activeRequests > 0)\r\n }\r\n\r\n async getSpatialStructure(modelId: string): Promise<SpatialTreeItem | null> {\r\n if (!this.fragments || !modelId) {\r\n throw new Error('No fragments or modelId available')\r\n }\r\n\r\n const cachedTree = this._treeByModelId.get(modelId)\r\n if (cachedTree !== undefined) {\r\n this._tree = cachedTree\r\n this.onSpatialStructureCreated.trigger({ tree: cachedTree })\r\n return cachedTree\r\n }\r\n\r\n const persistedTree = this.readCachedSpatialStructure(modelId)\r\n if (persistedTree) {\r\n this._tree = persistedTree\r\n this._treeByModelId.set(modelId, persistedTree)\r\n this.onSpatialStructureCreated.trigger({ tree: persistedTree })\r\n return persistedTree\r\n }\r\n\r\n const existingPromise = this._loadingPromises.get(modelId)\r\n if (existingPromise) {\r\n return existingPromise\r\n }\r\n\r\n const loadingPromise = Promise.resolve()\r\n .then(async () => {\r\n this.beginLoading()\r\n\r\n const model = this.fragments.list.get(modelId)\r\n if (!model) {\r\n throw new Error(`Model with ID ${modelId} not found in fragments.`)\r\n }\r\n\r\n const structure = await model.getSpatialStructure()\r\n\r\n const transformedStructure = await this.transformSpatialStructure(structure, model, modelId)\r\n\r\n // console.log('Transformed spatial structure:', transformedStructure)\r\n\r\n // Set the current spatial structure\r\n this._tree = transformedStructure\r\n if (transformedStructure) {\r\n this._treeByModelId.set(modelId, transformedStructure)\r\n this.writeCachedSpatialStructure(modelId, transformedStructure)\r\n } else {\r\n this._treeByModelId.delete(modelId)\r\n }\r\n\r\n // Trigger the event that spatial structure is created\r\n this.onSpatialStructureCreated.trigger({ tree: transformedStructure })\r\n\r\n return transformedStructure\r\n })\r\n .catch((error) => {\r\n console.error('Error getting spatial structure:', error)\r\n this._tree = null\r\n this.onSpatialStructureCreated.trigger({ tree: null })\r\n return null\r\n })\r\n .finally(() => {\r\n this._loadingPromises.delete(modelId)\r\n this.endLoading()\r\n })\r\n\r\n this._loadingPromises.set(modelId, loadingPromise)\r\n return loadingPromise\r\n }\r\n\r\n /**\r\n * Clear the current spatial structure\r\n */\r\n clearSpatialStructure(): void {\r\n this._tree = null\r\n this._treeByModelId.clear()\r\n this._loadingPromises.clear()\r\n this._activeRequests = 0\r\n this.setLoadingState(false)\r\n this.onSpatialStructureCreated.trigger({ tree: null })\r\n }\r\n\r\n private readCachedSpatialStructure(modelId: string): SpatialTreeItem | null {\r\n if (typeof window === 'undefined') {\r\n return null\r\n }\r\n\r\n try {\r\n const cachedValue = window.localStorage.getItem(this.getCacheKey(modelId))\r\n if (!cachedValue) {\r\n return null\r\n }\r\n\r\n const parsed = JSON.parse(cachedValue) as SpatialTreeItem\r\n if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.children)) {\r\n return null\r\n }\r\n\r\n return parsed\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n private writeCachedSpatialStructure(modelId: string, tree: SpatialTreeItem): void {\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n try {\r\n window.localStorage.setItem(this.getCacheKey(modelId), JSON.stringify(tree))\r\n } catch (error) {\r\n console.warn('Failed to persist spatial structure cache:', error)\r\n }\r\n }\r\n\r\n private getCacheKey(modelId: string): string {\r\n return `${SpatialStructure.cacheKeyPrefix}:${modelId}`\r\n }\r\n\r\n private emitSpatialStructureUpdate(tree: SpatialTreeItem | null): void {\r\n this._tree = tree\r\n this.onSpatialStructureCreated.trigger({ tree: this.cloneSpatialTree(tree) })\r\n }\r\n\r\n private cloneSpatialTree(tree: SpatialTreeItem | null): SpatialTreeItem | null {\r\n if (!tree) {\r\n return null\r\n }\r\n\r\n return {\r\n name: tree.name,\r\n localId: tree.localId,\r\n ifcCategory: tree.ifcCategory,\r\n children: tree.children.map((child) => this.cloneSpatialTree(child) as SpatialTreeItem),\r\n }\r\n }\r\n\r\n private async yieldToBrowser(): Promise<void> {\r\n await new Promise<void>((resolve) => {\r\n setTimeout(resolve, 0)\r\n })\r\n }\r\n\r\n private async transformSpatialStructure(rawStructure: any, model: any, modelId: string): Promise<SpatialTreeItem | null> {\r\n if (!rawStructure) {\r\n return null\r\n }\r\n\r\n const localIdsNeedingNames = new Set<number>()\r\n this.collectLocalIdsNeedingNames(rawStructure, localIdsNeedingNames)\r\n\r\n const nameByLocalId = new Map<number, string>()\r\n if (localIdsNeedingNames.size > 0) {\r\n try {\r\n const localIds = [...localIdsNeedingNames]\r\n const itemData = await model.getItemsData(localIds, {\r\n attributesDefault: false,\r\n attributes: ['Name'],\r\n })\r\n\r\n for (let i = 0; i < itemData.length; i++) {\r\n const data = itemData[i]\r\n const localId = localIds[i]\r\n const name = data?.Name?.value\r\n if (localId !== undefined && typeof name === 'string' && name.trim()) {\r\n nameByLocalId.set(localId, name)\r\n }\r\n }\r\n } catch (error) {\r\n console.warn('Failed to batch spatial-structure names:', error)\r\n }\r\n }\r\n\r\n // Find the building first\r\n const building = this.findBuilding(rawStructure)\r\n if (!building) {\r\n console.warn('No IFCBUILDING found in spatial structure')\r\n return null\r\n }\r\n\r\n const childrenSource = this.getRenderableChildren(building)\r\n const children: SpatialTreeItem[] = childrenSource.map((child) => this.createSpatialNode(child, nameByLocalId))\r\n const root: SpatialTreeItem = {\r\n name: 'Root',\r\n children,\r\n }\r\n\r\n if (children.length === 0) {\r\n this.emitSpatialStructureUpdate(root)\r\n return root\r\n }\r\n\r\n this.emitSpatialStructureUpdate(root)\r\n await this.yieldToBrowser()\r\n\r\n let frontier: Array<{ source: any; target: SpatialTreeItem }> = children.map((target, index) => ({\r\n source: childrenSource[index],\r\n target,\r\n }))\r\n\r\n while (frontier.length > 0) {\r\n const nextFrontier: Array<{ source: any; target: SpatialTreeItem }> = []\r\n\r\n for (const { source, target } of frontier) {\r\n const sourceChildren = this.getRenderableChildren(source)\r\n const nextChildren = sourceChildren.map((child) => this.createSpatialNode(child, nameByLocalId))\r\n target.children = nextChildren\r\n\r\n for (let i = 0; i < nextChildren.length; i++) {\r\n nextFrontier.push({ source: sourceChildren[i], target: nextChildren[i] })\r\n }\r\n }\r\n\r\n this.emitSpatialStructureUpdate(root)\r\n await this.yieldToBrowser()\r\n frontier = nextFrontier\r\n }\r\n\r\n return root\r\n }\r\n\r\n private collectLocalIdsNeedingNames(item: any, localIds: Set<number>): void {\r\n if (!item) {\r\n return\r\n }\r\n\r\n if (item?.localId && !item?.Name?.value && !item?.category && !item?.type) {\r\n localIds.add(item.localId)\r\n }\r\n\r\n if (Array.isArray(item)) {\r\n for (const child of item) {\r\n this.collectLocalIdsNeedingNames(child, localIds)\r\n }\r\n return\r\n }\r\n\r\n if (item?.children) {\r\n for (const child of item.children) {\r\n this.collectLocalIdsNeedingNames(child, localIds)\r\n }\r\n }\r\n }\r\n\r\n private getRenderableChildren(item: any): any[] {\r\n const children = Array.isArray(item?.children) ? item.children : []\r\n const flattened: any[] = []\r\n\r\n for (const child of children) {\r\n if (child?.category === 'IFCBUILDINGSTOREY' || child?.type === 'IFCBUILDINGSTOREY') {\r\n if (Array.isArray(child.children)) {\r\n flattened.push(...child.children)\r\n }\r\n } else {\r\n flattened.push(child)\r\n }\r\n }\r\n\r\n return flattened\r\n }\r\n\r\n private findBuilding(item: any): any {\r\n if (!item) return null\r\n \r\n // Check if current item is a building\r\n if (item?.category === 'IFCBUILDING' || item?.type === 'IFCBUILDING') {\r\n return item\r\n }\r\n \r\n // Search in children if it's an array\r\n if (Array.isArray(item)) {\r\n for (const child of item) {\r\n const found = this.findBuilding(child)\r\n if (found) return found\r\n }\r\n }\r\n \r\n // Search in children property\r\n if (item?.children) {\r\n for (const child of item.children) {\r\n const found = this.findBuilding(child)\r\n if (found) return found\r\n }\r\n }\r\n \r\n return null\r\n }\r\n\r\n private createSpatialNode(item: any, nameByLocalId: Map<number, string>): SpatialTreeItem {\r\n // Get item name\r\n let name = 'Unknown'\r\n if (item?.Name?.value) {\r\n name = item.Name.value\r\n } else if (item?.category || item?.type) {\r\n name = item.category || item.type\r\n } else if (item?.localId && nameByLocalId.has(item.localId)) {\r\n name = nameByLocalId.get(item.localId) || `Item ${item.localId}`\r\n } else if (item?.localId) {\r\n name = `Item ${item.localId}`\r\n }\r\n\r\n const result: SpatialTreeItem = {\r\n name: String(name),\r\n children: [],\r\n }\r\n\r\n if (item?.category) result.ifcCategory = item.category\r\n if (item?.localId) result.localId = item.localId\r\n\r\n return result\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"ViewportGizmo.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/bim/src/ViewportGizmo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAI3C,qBAAa,aAAc,SAAQ,GAAG,CAAC,SAAU,YAAW,GAAG,CAAC,UAAU;IACxE,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAG,sCAAsC,CAAS;IAEtE,QAAQ,CAAC,UAAU,qBAAkB;IAErC,OAAO,CAAC,QAAQ,CAAQ;IAExB,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAMzB;IAED,OAAO,CAAC,OAAO,CAOd;IAED,SAAS,CAAC,MAAM,EAAE;QAChB,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;KACb;IAqBD,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,mBAAmB,CAAQ;gBAEvB,UAAU,EAAE,GAAG,CAAC,UAAU;IAQtC,GAAG;IAwEH,MAAM;IA6CN,OAAO;IASP,MAAM;IAMN,MAAM;IAIN,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,YAAY;CA4BrB"}
1
+ {"version":3,"file":"ViewportGizmo.d.ts","sourceRoot":"","sources":["../../../../../../src/core/components/viewers/bim/src/ViewportGizmo.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAI3C,qBAAa,aAAc,SAAQ,GAAG,CAAC,SAAU,YAAW,GAAG,CAAC,UAAU;IACxE,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAG,sCAAsC,CAAS;IAEtE,QAAQ,CAAC,UAAU,qBAAkB;IAErC,OAAO,CAAC,QAAQ,CAAQ;IAExB,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAMzB;IAED,OAAO,CAAC,OAAO,CAOd;IAED,SAAS,CAAC,MAAM,EAAE;QAChB,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;KACb;IAqBD,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,mBAAmB,CAAQ;gBAEvB,UAAU,EAAE,GAAG,CAAC,UAAU;IAQtC,GAAG;IAwEH,MAAM;IA6CN,OAAO;IASP,MAAM;IAMN,MAAM;IAIN,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,YAAY;CA4BrB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/core/components/viewers/bim/src/ViewportGizmo.ts"],"sourcesContent":["import { CurrentCamera } from './CurrentCamera'\r\nimport * as OBC from '@thatopen/components'\r\nimport { CurrentWorld } from './CurrentWorld'\r\nimport { ViewportGizmo as ThreeViewportGizmo } from 'three-viewport-gizmo'\r\n\r\nexport class ViewportGizmo extends OBC.Component implements OBC.Disposable {\r\n static readonly uuid = 'c51594f0-68af-4318-ac86-c2e0e7ee62df' as const\r\n\r\n readonly onDisposed = new OBC.Event()\r\n\r\n private _enabled = false\r\n\r\n get enabled(): boolean {\r\n return this._enabled\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this._enabled = value\r\n const gizmoDom = (this.gizmo as any)?.domElement\r\n if (gizmoDom) {\r\n gizmoDom.style.pointerEvents = this._enabled ? 'auto' : 'none'\r\n }\r\n }\r\n\r\n private _labels = {\r\n top: 'TOP',\r\n right: 'RIGHT',\r\n bottom: 'BOTTOM',\r\n left: 'LEFT',\r\n front: 'FRONT',\r\n back: 'BACK'\r\n }\r\n\r\n setLabels(labels: {\r\n top: string\r\n right: string\r\n bottom: string\r\n left: string\r\n front: string\r\n back: string\r\n }) {\r\n const labelsChanged =\r\n this._labels.top !== labels.top ||\r\n this._labels.right !== labels.right ||\r\n this._labels.bottom !== labels.bottom ||\r\n this._labels.left !== labels.left ||\r\n this._labels.front !== labels.front ||\r\n this._labels.back !== labels.back\r\n\r\n if (!labelsChanged) {\r\n return\r\n }\r\n\r\n this._labels = labels\r\n // If gizmo is already created, recreate it with new labels\r\n if (this.gizmo) {\r\n this.remove()\r\n this.add()\r\n }\r\n }\r\n\r\n private camera: OBC.OrthoPerspectiveCamera | null = null\r\n private world: OBC.World | null = null\r\n private gizmo: ThreeViewportGizmo | null = null\r\n private restoreRenderHook: (() => void) | null = null\r\n private isRenderingFromHook = false\r\n\r\n constructor(components: OBC.Components) {\r\n super(components)\r\n components.add(ViewportGizmo.uuid, this)\r\n this.camera = components.get(CurrentCamera).camera\r\n this.world = components.get(CurrentWorld).world\r\n // Reset to Three.js default\r\n }\r\n\r\n add() {\r\n if (this.gizmo) {\r\n return\r\n }\r\n\r\n if (this.camera && this.world && this.world.renderer) {\r\n const gizmoConfig = this.getGizmoConfig()\r\n\r\n this.gizmo = new ThreeViewportGizmo(\r\n this.camera.three,\r\n this.world.renderer.three,\r\n gizmoConfig,\r\n )\r\n\r\n if (this.gizmo) {\r\n this.hookRenderer()\r\n\r\n // Store references to event handlers for proper cleanup\r\n const startHandler = () => {\r\n if (this.world?.camera.controls) {\r\n this.world.camera.controls.enabled = false\r\n }\r\n };\r\n\r\n const endHandler = () => {\r\n if (this.world?.camera.controls) {\r\n this.world.camera.controls.enabled = true\r\n }\r\n };\r\n\r\n const changeHandler = () => {\r\n if (this.world?.camera.controls && this.camera) {\r\n const position = this.camera.three.position.toArray() as [number, number, number]\r\n this.world.camera.controls.setPosition(...position)\r\n }\r\n };\r\n\r\n const updateHandler = () => {\r\n if (this.gizmo && this.enabled && this.world?.camera.controls) {\r\n this.world.camera.controls.getTarget(this.gizmo.target)\r\n this.gizmo.update()\r\n }\r\n };\r\n\r\n // Store handlers on the gizmo for cleanup\r\n (this.gizmo as any)._startHandler = startHandler;\r\n (this.gizmo as any)._endHandler = endHandler;\r\n (this.gizmo as any)._changeHandler = changeHandler;\r\n (this.gizmo as any)._updateHandler = updateHandler;\r\n\r\n // Add event listeners\r\n (this.gizmo as any).addEventListener('start', startHandler);\r\n (this.gizmo as any).addEventListener('end', endHandler);\r\n (this.gizmo as any).addEventListener('change', changeHandler);\r\n\r\n this.world.camera.controls.addEventListener('update', updateHandler);\r\n\r\n if (this.world.camera.controls) {\r\n const targetArray = this.gizmo.target.set(0, 0, 0).toArray() as [number, number, number]\r\n this.world.camera.controls.setTarget(...targetArray)\r\n this.camera.three.lookAt(this.gizmo.target)\r\n }\r\n\r\n // Set initial pointer events based on enabled state\r\n const gizmoDom = (this.gizmo as any).domElement;\r\n if (gizmoDom) {\r\n gizmoDom.style.pointerEvents = this._enabled ? 'auto' : 'none';\r\n }\r\n }\r\n }\r\n }\r\n\r\n remove() {\r\n if (this.gizmo) {\r\n // Store references to the actual event listener functions for proper cleanup\r\n const gizmoStartHandler = (this.gizmo as any)._startHandler;\r\n const gizmoEndHandler = (this.gizmo as any)._endHandler;\r\n const gizmoChangeHandler = (this.gizmo as any)._changeHandler;\r\n const controlsUpdateHandler = (this.gizmo as any)._updateHandler;\r\n\r\n // Remove all event listeners if they exist\r\n if (gizmoStartHandler) {\r\n (this.gizmo as any).removeEventListener('start', gizmoStartHandler);\r\n }\r\n if (gizmoEndHandler) {\r\n (this.gizmo as any).removeEventListener('end', gizmoEndHandler);\r\n }\r\n if (gizmoChangeHandler) {\r\n (this.gizmo as any).removeEventListener('change', gizmoChangeHandler);\r\n }\r\n\r\n // Remove camera controls event listener\r\n if (this.world?.camera?.controls && controlsUpdateHandler) {\r\n this.world.camera.controls.removeEventListener('update', controlsUpdateHandler);\r\n }\r\n\r\n if (this.restoreRenderHook) {\r\n this.restoreRenderHook()\r\n this.restoreRenderHook = null\r\n }\r\n\r\n // Remove the DOM element from the document\r\n const gizmoElement = (this.gizmo as any).domElement\r\n if (gizmoElement && gizmoElement.parentNode) {\r\n gizmoElement.remove()\r\n }\r\n\r\n // Dispose of the gizmo\r\n if (this.gizmo.dispose) {\r\n this.gizmo.dispose()\r\n }\r\n\r\n // Remove all references\r\n this.gizmo = null\r\n }\r\n }\r\n\r\n dispose() {\r\n // Use remove for cleanup\r\n this.remove()\r\n\r\n // Trigger disposal event and reset\r\n this.onDisposed.trigger()\r\n this.onDisposed.reset()\r\n }\r\n\r\n render() {\r\n if (this.gizmo && this.enabled) {\r\n this.gizmo.render()\r\n }\r\n }\r\n\r\n update() {\r\n // Keep this empty to avoid duplicate updates with controls 'update' events.\r\n }\r\n\r\n private getGizmoConfig() {\r\n return {\r\n size: 75,\r\n placement: 'top-right' as const,\r\n type: 'cube' as const,\r\n top: {label: this._labels.top},\r\n right: {label: this._labels.right},\r\n bottom: {label: this._labels.bottom},\r\n left: {label: this._labels.left},\r\n front: {label: this._labels.front},\r\n back: {label: this._labels.back},\r\n }\r\n }\r\n\r\n private hookRenderer() {\r\n if (this.restoreRenderHook || !this.world?.renderer?.three) {\r\n return\r\n }\r\n\r\n const renderer = this.world.renderer.three as any\r\n const originalRender = renderer.render\r\n const self = this\r\n\r\n renderer.render = function (...args: any[]) {\r\n const result = originalRender.apply(this, args)\r\n\r\n if (self.gizmo && self.enabled && !self.isRenderingFromHook) {\r\n self.isRenderingFromHook = true\r\n try {\r\n self.gizmo.render()\r\n } finally {\r\n self.isRenderingFromHook = false\r\n }\r\n }\r\n\r\n return result\r\n }\r\n\r\n this.restoreRenderHook = () => {\r\n renderer.render = originalRender\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../src/core/components/viewers/bim/src/ViewportGizmo.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport { CurrentCamera } from './CurrentCamera'\r\nimport * as OBC from '@thatopen/components'\r\nimport { CurrentWorld } from './CurrentWorld'\r\nimport { ViewportGizmo as ThreeViewportGizmo } from 'three-viewport-gizmo'\r\n\r\nexport class ViewportGizmo extends OBC.Component implements OBC.Disposable {\r\n static readonly uuid = 'c51594f0-68af-4318-ac86-c2e0e7ee62df' as const\r\n\r\n readonly onDisposed = new OBC.Event()\r\n\r\n private _enabled = false\r\n\r\n get enabled(): boolean {\r\n return this._enabled\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this._enabled = value\r\n const gizmoDom = (this.gizmo as any)?.domElement\r\n if (gizmoDom) {\r\n gizmoDom.style.pointerEvents = this._enabled ? 'auto' : 'none'\r\n }\r\n }\r\n\r\n private _labels = {\r\n top: 'TOP',\r\n right: 'RIGHT',\r\n bottom: 'BOTTOM',\r\n left: 'LEFT',\r\n front: 'FRONT',\r\n back: 'BACK'\r\n }\r\n\r\n setLabels(labels: {\r\n top: string\r\n right: string\r\n bottom: string\r\n left: string\r\n front: string\r\n back: string\r\n }) {\r\n const labelsChanged =\r\n this._labels.top !== labels.top ||\r\n this._labels.right !== labels.right ||\r\n this._labels.bottom !== labels.bottom ||\r\n this._labels.left !== labels.left ||\r\n this._labels.front !== labels.front ||\r\n this._labels.back !== labels.back\r\n\r\n if (!labelsChanged) {\r\n return\r\n }\r\n\r\n this._labels = labels\r\n // If gizmo is already created, recreate it with new labels\r\n if (this.gizmo) {\r\n this.remove()\r\n this.add()\r\n }\r\n }\r\n\r\n private camera: OBC.OrthoPerspectiveCamera | null = null\r\n private world: OBC.World | null = null\r\n private gizmo: ThreeViewportGizmo | null = null\r\n private restoreRenderHook: (() => void) | null = null\r\n private isRenderingFromHook = false\r\n\r\n constructor(components: OBC.Components) {\r\n super(components)\r\n components.add(ViewportGizmo.uuid, this)\r\n this.camera = components.get(CurrentCamera).camera\r\n this.world = components.get(CurrentWorld).world\r\n // Reset to Three.js default\r\n }\r\n\r\n add() {\r\n if (this.gizmo) {\r\n return\r\n }\r\n\r\n if (this.camera && this.world && this.world.renderer) {\r\n const gizmoConfig = this.getGizmoConfig()\r\n\r\n this.gizmo = new ThreeViewportGizmo(\r\n this.camera.three,\r\n this.world.renderer.three,\r\n gizmoConfig,\r\n )\r\n\r\n if (this.gizmo) {\r\n this.hookRenderer()\r\n\r\n // Store references to event handlers for proper cleanup\r\n const startHandler = () => {\r\n if (this.world?.camera.controls) {\r\n this.world.camera.controls.enabled = false\r\n }\r\n };\r\n\r\n const endHandler = () => {\r\n if (this.world?.camera.controls) {\r\n this.world.camera.controls.enabled = true\r\n }\r\n };\r\n\r\n const changeHandler = () => {\r\n if (this.world?.camera.controls && this.camera) {\r\n const position = this.camera.three.position.toArray() as [number, number, number]\r\n this.world.camera.controls.setPosition(...position)\r\n }\r\n };\r\n\r\n const updateHandler = () => {\r\n if (this.gizmo && this.enabled && this.world?.camera.controls) {\r\n this.world.camera.controls.getTarget(this.gizmo.target)\r\n this.gizmo.update()\r\n }\r\n };\r\n\r\n // Store handlers on the gizmo for cleanup\r\n (this.gizmo as any)._startHandler = startHandler;\r\n (this.gizmo as any)._endHandler = endHandler;\r\n (this.gizmo as any)._changeHandler = changeHandler;\r\n (this.gizmo as any)._updateHandler = updateHandler;\r\n\r\n // Add event listeners\r\n (this.gizmo as any).addEventListener('start', startHandler);\r\n (this.gizmo as any).addEventListener('end', endHandler);\r\n (this.gizmo as any).addEventListener('change', changeHandler);\r\n\r\n this.world.camera.controls.addEventListener('update', updateHandler);\r\n\r\n if (this.world.camera.controls) {\r\n const targetArray = this.gizmo.target.set(0, 0, 0).toArray() as [number, number, number]\r\n this.world.camera.controls.setTarget(...targetArray)\r\n this.camera.three.lookAt(this.gizmo.target)\r\n }\r\n\r\n // Set initial pointer events based on enabled state\r\n const gizmoDom = (this.gizmo as any).domElement;\r\n if (gizmoDom) {\r\n gizmoDom.style.pointerEvents = this._enabled ? 'auto' : 'none';\r\n }\r\n }\r\n }\r\n }\r\n\r\n remove() {\r\n if (this.gizmo) {\r\n // Store references to the actual event listener functions for proper cleanup\r\n const gizmoStartHandler = (this.gizmo as any)._startHandler;\r\n const gizmoEndHandler = (this.gizmo as any)._endHandler;\r\n const gizmoChangeHandler = (this.gizmo as any)._changeHandler;\r\n const controlsUpdateHandler = (this.gizmo as any)._updateHandler;\r\n\r\n // Remove all event listeners if they exist\r\n if (gizmoStartHandler) {\r\n (this.gizmo as any).removeEventListener('start', gizmoStartHandler);\r\n }\r\n if (gizmoEndHandler) {\r\n (this.gizmo as any).removeEventListener('end', gizmoEndHandler);\r\n }\r\n if (gizmoChangeHandler) {\r\n (this.gizmo as any).removeEventListener('change', gizmoChangeHandler);\r\n }\r\n\r\n // Remove camera controls event listener\r\n if (this.world?.camera?.controls && controlsUpdateHandler) {\r\n this.world.camera.controls.removeEventListener('update', controlsUpdateHandler);\r\n }\r\n\r\n if (this.restoreRenderHook) {\r\n this.restoreRenderHook()\r\n this.restoreRenderHook = null\r\n }\r\n\r\n // Remove the DOM element from the document\r\n const gizmoElement = (this.gizmo as any).domElement\r\n if (gizmoElement && gizmoElement.parentNode) {\r\n gizmoElement.remove()\r\n }\r\n\r\n // Dispose of the gizmo\r\n if (this.gizmo.dispose) {\r\n this.gizmo.dispose()\r\n }\r\n\r\n // Remove all references\r\n this.gizmo = null\r\n }\r\n }\r\n\r\n dispose() {\r\n // Use remove for cleanup\r\n this.remove()\r\n\r\n // Trigger disposal event and reset\r\n this.onDisposed.trigger()\r\n this.onDisposed.reset()\r\n }\r\n\r\n render() {\r\n if (this.gizmo && this.enabled) {\r\n this.gizmo.render()\r\n }\r\n }\r\n\r\n update() {\r\n // Keep this empty to avoid duplicate updates with controls 'update' events.\r\n }\r\n\r\n private getGizmoConfig() {\r\n return {\r\n size: 75,\r\n placement: 'top-right' as const,\r\n type: 'cube' as const,\r\n top: {label: this._labels.top},\r\n right: {label: this._labels.right},\r\n bottom: {label: this._labels.bottom},\r\n left: {label: this._labels.left},\r\n front: {label: this._labels.front},\r\n back: {label: this._labels.back},\r\n }\r\n }\r\n\r\n private hookRenderer() {\r\n if (this.restoreRenderHook || !this.world?.renderer?.three) {\r\n return\r\n }\r\n\r\n const renderer = this.world.renderer.three as any\r\n const originalRender = renderer.render\r\n const self = this\r\n\r\n renderer.render = function (...args: any[]) {\r\n const result = originalRender.apply(this, args)\r\n\r\n if (self.gizmo && self.enabled && !self.isRenderingFromHook) {\r\n self.isRenderingFromHook = true\r\n try {\r\n self.gizmo.render()\r\n } finally {\r\n self.isRenderingFromHook = false\r\n }\r\n }\r\n\r\n return result\r\n }\r\n\r\n this.restoreRenderHook = () => {\r\n renderer.render = originalRender\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"CameraController.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/lib/CameraController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAC3C,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAmB9B;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAMf,OAAO,CAAC,UAAU;IAL9B,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,gBAAgB,CAA8C;gBAElD,UAAU,EAAE,GAAG,CAAC,UAAU;IAE9C;;;8DAG0D;IAC1D,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM;IAuCvB;iDAC6C;IAC7C,MAAM;IAqCN;;;;;;;;;;OAUG;IACH,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM;IAyBvE,OAAO,CAAC,MAAM;CAMf"}
1
+ {"version":3,"file":"CameraController.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/lib/CameraController.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAC3C,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAmB9B;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAMf,OAAO,CAAC,UAAU;IAL9B,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,gBAAgB,CAA8C;gBAElD,UAAU,EAAE,GAAG,CAAC,UAAU;IAE9C;;;8DAG0D;IAC1D,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM;IAuCvB;iDAC6C;IAC7C,MAAM;IAqCN;;;;;;;;;;OAUG;IACH,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM;IAyBvE,OAAO,CAAC,MAAM;CAMf"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/lib/CameraController.ts"],"sourcesContent":["import * as OBC from '@thatopen/components'\r\nimport * as THREE from 'three'\r\nimport { CurrentWorld } from '../CurrentWorld'\r\n\r\n// camera-controls ACTION constants (avoid importing the package directly).\r\nconst ACTION_NONE = 0\r\nconst ACTION_TRUCK = 2\r\nconst ACTION_ZOOM = 32\r\nconst ACTION_TOUCH_TRUCK = 128\r\nconst ACTION_TOUCH_ZOOM_TRUCK = 65536\r\n\r\ninterface SavedControls {\r\n minPolarAngle: number\r\n maxPolarAngle: number\r\n minAzimuthAngle: number\r\n maxAzimuthAngle: number\r\n mouseButtons: any\r\n touches: any\r\n}\r\n\r\n/**\r\n * Camera lock used by drawing-based view tools (FloorplanTool,\r\n * ElevationsTool). `lock()` snapshots the current pose + projection +\r\n * control limits and disables rotation so only pan/zoom remain. `frame()`\r\n * positions the camera orthographically along an arbitrary view direction\r\n * (top-down for floorplans, side-on for elevations). `unlock()` restores\r\n * the snapshot.\r\n */\r\nexport class CameraController {\r\n private _saved: SavedControls | null = null\r\n private _savedPosition: THREE.Vector3 | null = null\r\n private _savedTarget: THREE.Vector3 | null = null\r\n private _savedProjection: 'Orthographic' | 'Perspective' | null = null\r\n\r\n constructor(private components: OBC.Components) {}\r\n\r\n /** Snapshot pose + control limits, then disable rotation actions\r\n * (only pan + zoom remain). Idempotent — safe to call again while\r\n * already locked. Pass `lockPolar` to also pin the polar angle (e.g. 0\r\n * for top-down so even programmatic moves stay flat). */\r\n lock(lockPolar?: number) {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld?.camera?.controls) return\r\n if (this._saved) return\r\n const controls = sourceWorld.camera.controls as any\r\n\r\n this._saved = {\r\n minPolarAngle: controls.minPolarAngle,\r\n maxPolarAngle: controls.maxPolarAngle,\r\n minAzimuthAngle: controls.minAzimuthAngle,\r\n maxAzimuthAngle: controls.maxAzimuthAngle,\r\n mouseButtons: { ...controls.mouseButtons },\r\n touches: { ...controls.touches },\r\n }\r\n this._savedPosition = new THREE.Vector3()\r\n this._savedTarget = new THREE.Vector3()\r\n controls.getPosition(this._savedPosition)\r\n controls.getTarget(this._savedTarget)\r\n\r\n const camera = sourceWorld.camera as OBC.OrthoPerspectiveCamera\r\n try {\r\n this._savedProjection = (camera.projection as any).current ?? 'Perspective'\r\n } catch {\r\n this._savedProjection = 'Perspective'\r\n }\r\n\r\n if (lockPolar !== undefined) {\r\n controls.minPolarAngle = lockPolar\r\n controls.maxPolarAngle = lockPolar\r\n }\r\n controls.mouseButtons.left = ACTION_TRUCK\r\n controls.mouseButtons.middle = ACTION_NONE\r\n controls.mouseButtons.right = ACTION_NONE\r\n controls.mouseButtons.wheel = ACTION_ZOOM\r\n controls.touches.one = ACTION_TOUCH_TRUCK\r\n controls.touches.two = ACTION_TOUCH_ZOOM_TRUCK\r\n controls.touches.three = ACTION_TOUCH_TRUCK\r\n }\r\n\r\n /** Restore the snapshot taken in `lock`. No-op if `lock` was never called\r\n * (defensive against double-deactivate). */\r\n unlock() {\r\n if (!this._saved) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld?.camera?.controls) {\r\n this._reset()\r\n return\r\n }\r\n const controls = sourceWorld.camera.controls as any\r\n const saved = this._saved\r\n\r\n // Restore projection BEFORE pose so the orthographic frustum doesn't\r\n // fight the new perspective look-at.\r\n const camera = sourceWorld.camera as OBC.OrthoPerspectiveCamera\r\n if (this._savedProjection) {\r\n try {\r\n camera.projection.set(this._savedProjection)\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n controls.minPolarAngle = saved.minPolarAngle\r\n controls.maxPolarAngle = saved.maxPolarAngle\r\n controls.minAzimuthAngle = saved.minAzimuthAngle\r\n controls.maxAzimuthAngle = saved.maxAzimuthAngle\r\n Object.assign(controls.mouseButtons, saved.mouseButtons)\r\n Object.assign(controls.touches, saved.touches)\r\n\r\n if (this._savedPosition && this._savedTarget) {\r\n const p = this._savedPosition\r\n const t = this._savedTarget\r\n void controls.setLookAt(p.x, p.y, p.z, t.x, t.y, t.z, true)\r\n }\r\n\r\n this._reset()\r\n }\r\n\r\n /**\r\n * Frame an orthographic view of `target` looking along `viewDirection`.\r\n * The camera is placed at `target − viewDirection × span`.\r\n *\r\n * `viewDirection` is the direction the camera looks:\r\n * (0, -1, 0) → top-down (floorplan)\r\n * (0, 0, -1) → looking south (north elevation)\r\n * (0, 0, 1) → looking north (south elevation)\r\n * (-1, 0, 0) → looking west (east elevation)\r\n * ( 1, 0, 0) → looking east (west elevation)\r\n */\r\n frame(target: THREE.Vector3, viewDirection: THREE.Vector3, span: number) {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld?.camera?.controls) return\r\n const camera = sourceWorld.camera as OBC.OrthoPerspectiveCamera\r\n\r\n try {\r\n camera.projection.set('Orthographic')\r\n } catch {\r\n // already ortho\r\n }\r\n\r\n const dir = viewDirection.clone().normalize()\r\n const camPos = target.clone().sub(dir.multiplyScalar(span))\r\n\r\n void sourceWorld.camera.controls.setLookAt(\r\n camPos.x,\r\n camPos.y,\r\n camPos.z,\r\n target.x,\r\n target.y,\r\n target.z,\r\n true,\r\n )\r\n }\r\n\r\n private _reset() {\r\n this._saved = null\r\n this._savedPosition = null\r\n this._savedTarget = null\r\n this._savedProjection = null\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/lib/CameraController.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as OBC from '@thatopen/components'\r\nimport * as THREE from 'three'\r\nimport { CurrentWorld } from '../CurrentWorld'\r\n\r\n// camera-controls ACTION constants (avoid importing the package directly).\r\nconst ACTION_NONE = 0\r\nconst ACTION_TRUCK = 2\r\nconst ACTION_ZOOM = 32\r\nconst ACTION_TOUCH_TRUCK = 128\r\nconst ACTION_TOUCH_ZOOM_TRUCK = 65536\r\n\r\ninterface SavedControls {\r\n minPolarAngle: number\r\n maxPolarAngle: number\r\n minAzimuthAngle: number\r\n maxAzimuthAngle: number\r\n mouseButtons: any\r\n touches: any\r\n}\r\n\r\n/**\r\n * Camera lock used by drawing-based view tools (FloorplanTool,\r\n * ElevationsTool). `lock()` snapshots the current pose + projection +\r\n * control limits and disables rotation so only pan/zoom remain. `frame()`\r\n * positions the camera orthographically along an arbitrary view direction\r\n * (top-down for floorplans, side-on for elevations). `unlock()` restores\r\n * the snapshot.\r\n */\r\nexport class CameraController {\r\n private _saved: SavedControls | null = null\r\n private _savedPosition: THREE.Vector3 | null = null\r\n private _savedTarget: THREE.Vector3 | null = null\r\n private _savedProjection: 'Orthographic' | 'Perspective' | null = null\r\n\r\n constructor(private components: OBC.Components) {}\r\n\r\n /** Snapshot pose + control limits, then disable rotation actions\r\n * (only pan + zoom remain). Idempotent — safe to call again while\r\n * already locked. Pass `lockPolar` to also pin the polar angle (e.g. 0\r\n * for top-down so even programmatic moves stay flat). */\r\n lock(lockPolar?: number) {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld?.camera?.controls) return\r\n if (this._saved) return\r\n const controls = sourceWorld.camera.controls as any\r\n\r\n this._saved = {\r\n minPolarAngle: controls.minPolarAngle,\r\n maxPolarAngle: controls.maxPolarAngle,\r\n minAzimuthAngle: controls.minAzimuthAngle,\r\n maxAzimuthAngle: controls.maxAzimuthAngle,\r\n mouseButtons: { ...controls.mouseButtons },\r\n touches: { ...controls.touches },\r\n }\r\n this._savedPosition = new THREE.Vector3()\r\n this._savedTarget = new THREE.Vector3()\r\n controls.getPosition(this._savedPosition)\r\n controls.getTarget(this._savedTarget)\r\n\r\n const camera = sourceWorld.camera as OBC.OrthoPerspectiveCamera\r\n try {\r\n this._savedProjection = (camera.projection as any).current ?? 'Perspective'\r\n } catch {\r\n this._savedProjection = 'Perspective'\r\n }\r\n\r\n if (lockPolar !== undefined) {\r\n controls.minPolarAngle = lockPolar\r\n controls.maxPolarAngle = lockPolar\r\n }\r\n controls.mouseButtons.left = ACTION_TRUCK\r\n controls.mouseButtons.middle = ACTION_NONE\r\n controls.mouseButtons.right = ACTION_NONE\r\n controls.mouseButtons.wheel = ACTION_ZOOM\r\n controls.touches.one = ACTION_TOUCH_TRUCK\r\n controls.touches.two = ACTION_TOUCH_ZOOM_TRUCK\r\n controls.touches.three = ACTION_TOUCH_TRUCK\r\n }\r\n\r\n /** Restore the snapshot taken in `lock`. No-op if `lock` was never called\r\n * (defensive against double-deactivate). */\r\n unlock() {\r\n if (!this._saved) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld?.camera?.controls) {\r\n this._reset()\r\n return\r\n }\r\n const controls = sourceWorld.camera.controls as any\r\n const saved = this._saved\r\n\r\n // Restore projection BEFORE pose so the orthographic frustum doesn't\r\n // fight the new perspective look-at.\r\n const camera = sourceWorld.camera as OBC.OrthoPerspectiveCamera\r\n if (this._savedProjection) {\r\n try {\r\n camera.projection.set(this._savedProjection)\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n controls.minPolarAngle = saved.minPolarAngle\r\n controls.maxPolarAngle = saved.maxPolarAngle\r\n controls.minAzimuthAngle = saved.minAzimuthAngle\r\n controls.maxAzimuthAngle = saved.maxAzimuthAngle\r\n Object.assign(controls.mouseButtons, saved.mouseButtons)\r\n Object.assign(controls.touches, saved.touches)\r\n\r\n if (this._savedPosition && this._savedTarget) {\r\n const p = this._savedPosition\r\n const t = this._savedTarget\r\n void controls.setLookAt(p.x, p.y, p.z, t.x, t.y, t.z, true)\r\n }\r\n\r\n this._reset()\r\n }\r\n\r\n /**\r\n * Frame an orthographic view of `target` looking along `viewDirection`.\r\n * The camera is placed at `target − viewDirection × span`.\r\n *\r\n * `viewDirection` is the direction the camera looks:\r\n * (0, -1, 0) → top-down (floorplan)\r\n * (0, 0, -1) → looking south (north elevation)\r\n * (0, 0, 1) → looking north (south elevation)\r\n * (-1, 0, 0) → looking west (east elevation)\r\n * ( 1, 0, 0) → looking east (west elevation)\r\n */\r\n frame(target: THREE.Vector3, viewDirection: THREE.Vector3, span: number) {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld?.camera?.controls) return\r\n const camera = sourceWorld.camera as OBC.OrthoPerspectiveCamera\r\n\r\n try {\r\n camera.projection.set('Orthographic')\r\n } catch {\r\n // already ortho\r\n }\r\n\r\n const dir = viewDirection.clone().normalize()\r\n const camPos = target.clone().sub(dir.multiplyScalar(span))\r\n\r\n void sourceWorld.camera.controls.setLookAt(\r\n camPos.x,\r\n camPos.y,\r\n camPos.z,\r\n target.x,\r\n target.y,\r\n target.z,\r\n true,\r\n )\r\n }\r\n\r\n private _reset() {\r\n this._saved = null\r\n this._savedPosition = null\r\n this._savedTarget = null\r\n this._savedProjection = null\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"CategoryHighlighter.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/lib/CategoryHighlighter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAG3C,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAA;IACb;uEACmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC;+DAC2D;IAC3D,MAAM,EAAE,aAAa,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf;+DAC2D;IAC3D,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;CAC/B;AAaD,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;AAalD;;;;;;;;GAQG;AACH,qBAAa,mBAAmB;IAO5B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IAPhB,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,UAAU,CAAsB;IACxC,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAmD;gBAGzD,UAAU,EAAE,GAAG,CAAC,UAAU,EAC1B,MAAM,EAAE,yBAAyB;IAG3C;;;;;OAKG;IACG,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,cAAc,CAAC,EACpE,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC;IA+DV,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B9B;;;OAGG;IACG,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAuBhB,kBAAkB,CAAC,OAAO,EAAE,MAAM;IAMlC,kBAAkB,CAAC,QAAQ,EAAE,MAAM;YAIrB,aAAa;IAoC3B,OAAO,CAAC,QAAQ;CAQjB"}
1
+ {"version":3,"file":"CategoryHighlighter.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/lib/CategoryHighlighter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAG3C,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAA;IACb;uEACmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC;+DAC2D;IAC3D,MAAM,EAAE,aAAa,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf;+DAC2D;IAC3D,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;CAC/B;AAaD,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;AAalD;;;;;;;;GAQG;AACH,qBAAa,mBAAmB;IAO5B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IAPhB,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,UAAU,CAAsB;IACxC,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAmD;gBAGzD,UAAU,EAAE,GAAG,CAAC,UAAU,EAC1B,MAAM,EAAE,yBAAyB;IAG3C;;;;;OAKG;IACG,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,cAAc,CAAC,EACpE,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC;IA+DV,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B9B;;;OAGG;IACG,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAuBhB,kBAAkB,CAAC,OAAO,EAAE,MAAM;IAMlC,kBAAkB,CAAC,QAAQ,EAAE,MAAM;YAIrB,aAAa;IAoC3B,OAAO,CAAC,QAAQ;CAQjB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/lib/CategoryHighlighter.ts"],"sourcesContent":["import * as OBC from '@thatopen/components'\r\nimport * as THREE from 'three'\r\n\r\nexport interface CategoryGroup {\r\n /** IFC category regexes that match items in this group (e.g. /IFCSLAB/). */\r\n categories: RegExp[]\r\n /** Material color used to highlight matched items. */\r\n color: number\r\n /** Optional progress stage name emitted before this group is applied.\r\n * The UI layer is responsible for translating it to a message. */\r\n stage?: string\r\n}\r\n\r\nexport interface CategoryHighlighterConfig {\r\n /** Groups applied in order. The first group is \"fill\", subsequent are\r\n * \"cut\" / \"outline\" etc. — naming is up to the caller. */\r\n groups: CategoryGroup[]\r\n}\r\n\r\nexport interface ResolveContext {\r\n modelId: string\r\n /** When set, restrict matched ids to this set (e.g. items in a specific\r\n * storey). Pass `null` to leave the result unfiltered. */\r\n filterIds?: Set<number> | null\r\n}\r\n\r\ninterface ResolvedGroupIds {\r\n /** ids per group, parallel to config.groups */\r\n groupIds: number[][]\r\n}\r\n\r\ninterface ResolvedModel {\r\n modelId: string\r\n model: any\r\n resolved: ResolvedGroupIds\r\n}\r\n\r\nexport type StageEmitter = (stage: string) => void\r\n\r\nconst HIGHLIGHT_BASE = {\r\n opacity: 1,\r\n transparent: false,\r\n renderedFaces: 1,\r\n preserveOriginalMaterial: false,\r\n} as const\r\n\r\nconst STAGE_RESOLVE = 'resolve'\r\nconst STAGE_CULL = 'cull'\r\nconst STAGE_SWITCHING = 'switching'\r\n\r\n/**\r\n * Hides everything in every loaded model, then re-shows + colors a\r\n * configurable set of category groups (e.g. fill = slabs/roofs in white,\r\n * cut = walls/columns in dark gray). Caches resolved ids per\r\n * (entry-key × modelId) so repeat activations skip getItemsOfCategories.\r\n *\r\n * Replaces the floorplan-specific FloorplanRenderer; reused by both\r\n * FloorplanTool and ElevationsTool with different category groups.\r\n */\r\nexport class CategoryHighlighter {\r\n private _renderedModelIds: string[] = []\r\n private _activeKey: string | null = null\r\n /** entryKey → modelId → ids per group */\r\n private _idCache = new Map<string, Map<string, ResolvedGroupIds>>()\r\n\r\n constructor(\r\n private components: OBC.Components,\r\n private config: CategoryHighlighterConfig,\r\n ) {}\r\n\r\n /**\r\n * Apply the highlighter for the given entry. `entryKey` identifies the\r\n * cache slot (so two activations of the same entry are cheap); `resolve`\r\n * is called per loaded model to optionally provide a storey/region\r\n * filter.\r\n */\r\n async apply(\r\n entryKey: string,\r\n resolveCtx: (modelId: string, model: any) => Promise<ResolveContext>,\r\n onStage?: StageEmitter,\r\n ): Promise<void> {\r\n const fragments = this.components.get(OBC.FragmentsManager)\r\n const isFirstApply = this._activeKey === null\r\n const switchingFrom = this._activeKey\r\n\r\n onStage?.(STAGE_RESOLVE)\r\n const tasks: Promise<ResolvedModel | null>[] = []\r\n for (const [modelId, model] of fragments.list) {\r\n tasks.push(this._resolveModel(entryKey, modelId, model, resolveCtx))\r\n }\r\n const resolved = (await Promise.all(tasks)).filter(\r\n (r): r is ResolvedModel => !!r,\r\n )\r\n this._renderedModelIds = resolved.map((r) => r.modelId)\r\n\r\n if (isFirstApply) {\r\n onStage?.(STAGE_CULL)\r\n await Promise.all(\r\n resolved.map(({ model }) =>\r\n this._swallow(() => model.setVisible(undefined, false)),\r\n ),\r\n )\r\n } else if (switchingFrom && switchingFrom !== entryKey) {\r\n onStage?.(STAGE_SWITCHING)\r\n const prev = this._idCache.get(switchingFrom)\r\n if (prev) {\r\n await Promise.all(\r\n resolved.map(async ({ modelId, model, resolved: cur }) => {\r\n const old = prev.get(modelId)\r\n if (!old) return\r\n const nextSet = new Set(cur.groupIds.flat())\r\n const toHide = old.groupIds\r\n .flat()\r\n .filter((id) => !nextSet.has(id))\r\n if (toHide.length > 0) {\r\n await this._swallow(() => model.setVisible(toHide, false))\r\n }\r\n }),\r\n )\r\n }\r\n }\r\n\r\n // Apply each group sequentially so the bar advances stage-by-stage.\r\n for (let i = 0; i < this.config.groups.length; i++) {\r\n const group = this.config.groups[i]\r\n if (group.stage) onStage?.(group.stage)\r\n const color = new THREE.Color(group.color)\r\n await Promise.all(\r\n resolved.map(async ({ model, resolved: cur }) => {\r\n const ids = cur.groupIds[i]\r\n if (ids.length === 0) return\r\n await this._swallow(() => model.setVisible(ids, true))\r\n await this._swallow(() =>\r\n model.highlight(ids, { ...HIGHLIGHT_BASE, color }),\r\n )\r\n }),\r\n )\r\n }\r\n\r\n fragments.core.update(true)\r\n this._activeKey = entryKey\r\n }\r\n\r\n async restore(): Promise<void> {\r\n if (this._renderedModelIds.length === 0) {\r\n this._activeKey = null\r\n return\r\n }\r\n const fragments = this.components.get(OBC.FragmentsManager)\r\n const tasks: Promise<unknown>[] = []\r\n for (const modelId of this._renderedModelIds) {\r\n const model = fragments.list.get(modelId) as any\r\n if (!model) continue\r\n tasks.push(\r\n Promise.resolve()\r\n .then(() => model.resetHighlight())\r\n .catch(() => {}),\r\n )\r\n tasks.push(\r\n Promise.resolve()\r\n .then(() => model.resetVisible())\r\n .catch(() => {}),\r\n )\r\n }\r\n await Promise.all(tasks)\r\n this._renderedModelIds = []\r\n this._activeKey = null\r\n fragments.core.update(true)\r\n }\r\n\r\n /**\r\n * Re-apply a single group's highlight with a new color without re-resolving\r\n * ids or changing visibility. Noop if the entry isn't in the cache yet.\r\n */\r\n async reapplyGroupColor(\r\n entryKey: string,\r\n groupIdx: number,\r\n color: number,\r\n ): Promise<void> {\r\n const perEntry = this._idCache.get(entryKey)\r\n if (!perEntry) return\r\n const fragments = this.components.get(OBC.FragmentsManager)\r\n const threeColor = new THREE.Color(color)\r\n // Update the config so future activations also use the new color.\r\n if (this.config.groups[groupIdx]) {\r\n this.config.groups[groupIdx].color = color\r\n }\r\n await Promise.all(\r\n [...perEntry.entries()].map(async ([modelId, resolved]) => {\r\n const model = fragments.list.get(modelId) as any\r\n if (!model) return\r\n const ids = resolved.groupIds[groupIdx]\r\n if (!ids || ids.length === 0) return\r\n await this._swallow(() =>\r\n model.highlight(ids, { ...HIGHLIGHT_BASE, color: threeColor }),\r\n )\r\n }),\r\n )\r\n fragments.core.update(true)\r\n }\r\n\r\n invalidateForModel(modelId: string) {\r\n for (const perModel of this._idCache.values()) {\r\n perModel.delete(modelId)\r\n }\r\n }\r\n\r\n invalidateForEntry(entryKey: string) {\r\n this._idCache.delete(entryKey)\r\n }\r\n\r\n private async _resolveModel(\r\n entryKey: string,\r\n modelId: string,\r\n model: any,\r\n resolveCtx: (modelId: string, model: any) => Promise<ResolveContext>,\r\n ): Promise<ResolvedModel | null> {\r\n let perModel = this._idCache.get(entryKey)\r\n if (!perModel) {\r\n perModel = new Map()\r\n this._idCache.set(entryKey, perModel)\r\n }\r\n const cached = perModel.get(modelId)\r\n if (cached) return { modelId, model, resolved: cached }\r\n\r\n try {\r\n const ctx = await resolveCtx(modelId, model)\r\n // Fetch every group's category list in parallel.\r\n const groupMaps = await Promise.all(\r\n this.config.groups.map((g) => model.getItemsOfCategories(g.categories)),\r\n )\r\n let groupIds = groupMaps.map(\r\n (m) => Object.values(m).flat() as number[],\r\n )\r\n if (ctx.filterIds && ctx.filterIds.size > 0) {\r\n const filter = ctx.filterIds\r\n groupIds = groupIds.map((ids) => ids.filter((id) => filter.has(id)))\r\n }\r\n const resolved: ResolvedGroupIds = { groupIds }\r\n perModel.set(modelId, resolved)\r\n return { modelId, model, resolved }\r\n } catch (error) {\r\n console.warn('[CategoryHighlighter] resolve failed:', modelId, error)\r\n return null\r\n }\r\n }\r\n\r\n private _swallow<T>(fn: () => Promise<T> | T): Promise<T | undefined> {\r\n return Promise.resolve()\r\n .then(() => fn())\r\n .catch((e) => {\r\n console.warn('[CategoryHighlighter] op failed:', e)\r\n return undefined\r\n })\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,YAAY,SAAS;AACrB,YAAY,WAAW;AAsCvB,MAAM,iBAAiB;AAAA,EACrB,SAAS;AAAA,EACT,aAAa;AAAA,EACb,eAAe;AAAA,EACf,0BAA0B;AAC5B;AAEA,MAAM,gBAAgB;AACtB,MAAM,aAAa;AACnB,MAAM,kBAAkB;AAWjB,MAAM,oBAAoB;AAAA,EAM/B,YACU,YACA,QACR;AAFQ;AACA;AAPV,SAAQ,oBAA8B,CAAC;AACvC,SAAQ,aAA4B;AAEpC;AAAA,SAAQ,WAAW,oBAAI,IAA2C;AAAA,EAK/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQH,MAAM,MACJ,UACA,YACA,SACe;AACf,UAAM,YAAY,KAAK,WAAW,IAAI,IAAI,gBAAgB;AAC1D,UAAM,eAAe,KAAK,eAAe;AACzC,UAAM,gBAAgB,KAAK;AAE3B,uCAAU;AACV,UAAM,QAAyC,CAAC;AAChD,eAAW,CAAC,SAAS,KAAK,KAAK,UAAU,MAAM;AAC7C,YAAM,KAAK,KAAK,cAAc,UAAU,SAAS,OAAO,UAAU,CAAC;AAAA,IACrE;AACA,UAAM,YAAY,MAAM,QAAQ,IAAI,KAAK,GAAG;AAAA,MAC1C,CAAC,MAA0B,CAAC,CAAC;AAAA,IAC/B;AACA,SAAK,oBAAoB,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO;AAEtD,QAAI,cAAc;AAChB,yCAAU;AACV,YAAM,QAAQ;AAAA,QACZ,SAAS;AAAA,UAAI,CAAC,EAAE,MAAM,MACpB,KAAK,SAAS,MAAM,MAAM,WAAW,QAAW,KAAK,CAAC;AAAA,QACxD;AAAA,MACF;AAAA,IACF,WAAW,iBAAiB,kBAAkB,UAAU;AACtD,yCAAU;AACV,YAAM,OAAO,KAAK,SAAS,IAAI,aAAa;AAC5C,UAAI,MAAM;AACR,cAAM,QAAQ;AAAA,UACZ,SAAS,IAAI,OAAO,EAAE,SAAS,OAAO,UAAU,IAAI,MAAM;AACxD,kBAAM,MAAM,KAAK,IAAI,OAAO;AAC5B,gBAAI,CAAC,IAAK;AACV,kBAAM,UAAU,IAAI,IAAI,IAAI,SAAS,KAAK,CAAC;AAC3C,kBAAM,SAAS,IAAI,SAChB,KAAK,EACL,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;AAClC,gBAAI,OAAO,SAAS,GAAG;AACrB,oBAAM,KAAK,SAAS,MAAM,MAAM,WAAW,QAAQ,KAAK,CAAC;AAAA,YAC3D;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,OAAO,QAAQ,KAAK;AAClD,YAAM,QAAQ,KAAK,OAAO,OAAO,CAAC;AAClC,UAAI,MAAM,MAAO,oCAAU,MAAM;AACjC,YAAM,QAAQ,IAAI,MAAM,MAAM,MAAM,KAAK;AACzC,YAAM,QAAQ;AAAA,QACZ,SAAS,IAAI,OAAO,EAAE,OAAO,UAAU,IAAI,MAAM;AAC/C,gBAAM,MAAM,IAAI,SAAS,CAAC;AAC1B,cAAI,IAAI,WAAW,EAAG;AACtB,gBAAM,KAAK,SAAS,MAAM,MAAM,WAAW,KAAK,IAAI,CAAC;AACrD,gBAAM,KAAK;AAAA,YAAS,MAClB,MAAM,UAAU,KAAK,iCAAK,iBAAL,EAAqB,MAAM,EAAC;AAAA,UACnD;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,cAAU,KAAK,OAAO,IAAI;AAC1B,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,KAAK,kBAAkB,WAAW,GAAG;AACvC,WAAK,aAAa;AAClB;AAAA,IACF;AACA,UAAM,YAAY,KAAK,WAAW,IAAI,IAAI,gBAAgB;AAC1D,UAAM,QAA4B,CAAC;AACnC,eAAW,WAAW,KAAK,mBAAmB;AAC5C,YAAM,QAAQ,UAAU,KAAK,IAAI,OAAO;AACxC,UAAI,CAAC,MAAO;AACZ,YAAM;AAAA,QACJ,QAAQ,QAAQ,EACb,KAAK,MAAM,MAAM,eAAe,CAAC,EACjC,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACnB;AACA,YAAM;AAAA,QACJ,QAAQ,QAAQ,EACb,KAAK,MAAM,MAAM,aAAa,CAAC,EAC/B,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACnB;AAAA,IACF;AACA,UAAM,QAAQ,IAAI,KAAK;AACvB,SAAK,oBAAoB,CAAC;AAC1B,SAAK,aAAa;AAClB,cAAU,KAAK,OAAO,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBACJ,UACA,UACA,OACe;AACf,UAAM,WAAW,KAAK,SAAS,IAAI,QAAQ;AAC3C,QAAI,CAAC,SAAU;AACf,UAAM,YAAY,KAAK,WAAW,IAAI,IAAI,gBAAgB;AAC1D,UAAM,aAAa,IAAI,MAAM,MAAM,KAAK;AAExC,QAAI,KAAK,OAAO,OAAO,QAAQ,GAAG;AAChC,WAAK,OAAO,OAAO,QAAQ,EAAE,QAAQ;AAAA,IACvC;AACA,UAAM,QAAQ;AAAA,MACZ,CAAC,GAAG,SAAS,QAAQ,CAAC,EAAE,IAAI,OAAO,CAAC,SAAS,QAAQ,MAAM;AACzD,cAAM,QAAQ,UAAU,KAAK,IAAI,OAAO;AACxC,YAAI,CAAC,MAAO;AACZ,cAAM,MAAM,SAAS,SAAS,QAAQ;AACtC,YAAI,CAAC,OAAO,IAAI,WAAW,EAAG;AAC9B,cAAM,KAAK;AAAA,UAAS,MAClB,MAAM,UAAU,KAAK,iCAAK,iBAAL,EAAqB,OAAO,WAAW,EAAC;AAAA,QAC/D;AAAA,MACF,CAAC;AAAA,IACH;AACA,cAAU,KAAK,OAAO,IAAI;AAAA,EAC5B;AAAA,EAEA,mBAAmB,SAAiB;AAClC,eAAW,YAAY,KAAK,SAAS,OAAO,GAAG;AAC7C,eAAS,OAAO,OAAO;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,mBAAmB,UAAkB;AACnC,SAAK,SAAS,OAAO,QAAQ;AAAA,EAC/B;AAAA,EAEA,MAAc,cACZ,UACA,SACA,OACA,YAC+B;AAC/B,QAAI,WAAW,KAAK,SAAS,IAAI,QAAQ;AACzC,QAAI,CAAC,UAAU;AACb,iBAAW,oBAAI,IAAI;AACnB,WAAK,SAAS,IAAI,UAAU,QAAQ;AAAA,IACtC;AACA,UAAM,SAAS,SAAS,IAAI,OAAO;AACnC,QAAI,OAAQ,QAAO,EAAE,SAAS,OAAO,UAAU,OAAO;AAEtD,QAAI;AACF,YAAM,MAAM,MAAM,WAAW,SAAS,KAAK;AAE3C,YAAM,YAAY,MAAM,QAAQ;AAAA,QAC9B,KAAK,OAAO,OAAO,IAAI,CAAC,MAAM,MAAM,qBAAqB,EAAE,UAAU,CAAC;AAAA,MACxE;AACA,UAAI,WAAW,UAAU;AAAA,QACvB,CAAC,MAAM,OAAO,OAAO,CAAC,EAAE,KAAK;AAAA,MAC/B;AACA,UAAI,IAAI,aAAa,IAAI,UAAU,OAAO,GAAG;AAC3C,cAAM,SAAS,IAAI;AACnB,mBAAW,SAAS,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,OAAO,IAAI,EAAE,CAAC,CAAC;AAAA,MACrE;AACA,YAAM,WAA6B,EAAE,SAAS;AAC9C,eAAS,IAAI,SAAS,QAAQ;AAC9B,aAAO,EAAE,SAAS,OAAO,SAAS;AAAA,IACpC,SAAS,OAAO;AACd,cAAQ,KAAK,yCAAyC,SAAS,KAAK;AACpE,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,SAAY,IAAkD;AACpE,WAAO,QAAQ,QAAQ,EACpB,KAAK,MAAM,GAAG,CAAC,EACf,MAAM,CAAC,MAAM;AACZ,cAAQ,KAAK,oCAAoC,CAAC;AAClD,aAAO;AAAA,IACT,CAAC;AAAA,EACL;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/lib/CategoryHighlighter.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as OBC from '@thatopen/components'\r\nimport * as THREE from 'three'\r\n\r\nexport interface CategoryGroup {\r\n /** IFC category regexes that match items in this group (e.g. /IFCSLAB/). */\r\n categories: RegExp[]\r\n /** Material color used to highlight matched items. */\r\n color: number\r\n /** Optional progress stage name emitted before this group is applied.\r\n * The UI layer is responsible for translating it to a message. */\r\n stage?: string\r\n}\r\n\r\nexport interface CategoryHighlighterConfig {\r\n /** Groups applied in order. The first group is \"fill\", subsequent are\r\n * \"cut\" / \"outline\" etc. — naming is up to the caller. */\r\n groups: CategoryGroup[]\r\n}\r\n\r\nexport interface ResolveContext {\r\n modelId: string\r\n /** When set, restrict matched ids to this set (e.g. items in a specific\r\n * storey). Pass `null` to leave the result unfiltered. */\r\n filterIds?: Set<number> | null\r\n}\r\n\r\ninterface ResolvedGroupIds {\r\n /** ids per group, parallel to config.groups */\r\n groupIds: number[][]\r\n}\r\n\r\ninterface ResolvedModel {\r\n modelId: string\r\n model: any\r\n resolved: ResolvedGroupIds\r\n}\r\n\r\nexport type StageEmitter = (stage: string) => void\r\n\r\nconst HIGHLIGHT_BASE = {\r\n opacity: 1,\r\n transparent: false,\r\n renderedFaces: 1,\r\n preserveOriginalMaterial: false,\r\n} as const\r\n\r\nconst STAGE_RESOLVE = 'resolve'\r\nconst STAGE_CULL = 'cull'\r\nconst STAGE_SWITCHING = 'switching'\r\n\r\n/**\r\n * Hides everything in every loaded model, then re-shows + colors a\r\n * configurable set of category groups (e.g. fill = slabs/roofs in white,\r\n * cut = walls/columns in dark gray). Caches resolved ids per\r\n * (entry-key × modelId) so repeat activations skip getItemsOfCategories.\r\n *\r\n * Replaces the floorplan-specific FloorplanRenderer; reused by both\r\n * FloorplanTool and ElevationsTool with different category groups.\r\n */\r\nexport class CategoryHighlighter {\r\n private _renderedModelIds: string[] = []\r\n private _activeKey: string | null = null\r\n /** entryKey → modelId → ids per group */\r\n private _idCache = new Map<string, Map<string, ResolvedGroupIds>>()\r\n\r\n constructor(\r\n private components: OBC.Components,\r\n private config: CategoryHighlighterConfig,\r\n ) {}\r\n\r\n /**\r\n * Apply the highlighter for the given entry. `entryKey` identifies the\r\n * cache slot (so two activations of the same entry are cheap); `resolve`\r\n * is called per loaded model to optionally provide a storey/region\r\n * filter.\r\n */\r\n async apply(\r\n entryKey: string,\r\n resolveCtx: (modelId: string, model: any) => Promise<ResolveContext>,\r\n onStage?: StageEmitter,\r\n ): Promise<void> {\r\n const fragments = this.components.get(OBC.FragmentsManager)\r\n const isFirstApply = this._activeKey === null\r\n const switchingFrom = this._activeKey\r\n\r\n onStage?.(STAGE_RESOLVE)\r\n const tasks: Promise<ResolvedModel | null>[] = []\r\n for (const [modelId, model] of fragments.list) {\r\n tasks.push(this._resolveModel(entryKey, modelId, model, resolveCtx))\r\n }\r\n const resolved = (await Promise.all(tasks)).filter(\r\n (r): r is ResolvedModel => !!r,\r\n )\r\n this._renderedModelIds = resolved.map((r) => r.modelId)\r\n\r\n if (isFirstApply) {\r\n onStage?.(STAGE_CULL)\r\n await Promise.all(\r\n resolved.map(({ model }) =>\r\n this._swallow(() => model.setVisible(undefined, false)),\r\n ),\r\n )\r\n } else if (switchingFrom && switchingFrom !== entryKey) {\r\n onStage?.(STAGE_SWITCHING)\r\n const prev = this._idCache.get(switchingFrom)\r\n if (prev) {\r\n await Promise.all(\r\n resolved.map(async ({ modelId, model, resolved: cur }) => {\r\n const old = prev.get(modelId)\r\n if (!old) return\r\n const nextSet = new Set(cur.groupIds.flat())\r\n const toHide = old.groupIds\r\n .flat()\r\n .filter((id) => !nextSet.has(id))\r\n if (toHide.length > 0) {\r\n await this._swallow(() => model.setVisible(toHide, false))\r\n }\r\n }),\r\n )\r\n }\r\n }\r\n\r\n // Apply each group sequentially so the bar advances stage-by-stage.\r\n for (let i = 0; i < this.config.groups.length; i++) {\r\n const group = this.config.groups[i]\r\n if (group.stage) onStage?.(group.stage)\r\n const color = new THREE.Color(group.color)\r\n await Promise.all(\r\n resolved.map(async ({ model, resolved: cur }) => {\r\n const ids = cur.groupIds[i]\r\n if (ids.length === 0) return\r\n await this._swallow(() => model.setVisible(ids, true))\r\n await this._swallow(() =>\r\n model.highlight(ids, { ...HIGHLIGHT_BASE, color }),\r\n )\r\n }),\r\n )\r\n }\r\n\r\n fragments.core.update(true)\r\n this._activeKey = entryKey\r\n }\r\n\r\n async restore(): Promise<void> {\r\n if (this._renderedModelIds.length === 0) {\r\n this._activeKey = null\r\n return\r\n }\r\n const fragments = this.components.get(OBC.FragmentsManager)\r\n const tasks: Promise<unknown>[] = []\r\n for (const modelId of this._renderedModelIds) {\r\n const model = fragments.list.get(modelId) as any\r\n if (!model) continue\r\n tasks.push(\r\n Promise.resolve()\r\n .then(() => model.resetHighlight())\r\n .catch(() => {}),\r\n )\r\n tasks.push(\r\n Promise.resolve()\r\n .then(() => model.resetVisible())\r\n .catch(() => {}),\r\n )\r\n }\r\n await Promise.all(tasks)\r\n this._renderedModelIds = []\r\n this._activeKey = null\r\n fragments.core.update(true)\r\n }\r\n\r\n /**\r\n * Re-apply a single group's highlight with a new color without re-resolving\r\n * ids or changing visibility. Noop if the entry isn't in the cache yet.\r\n */\r\n async reapplyGroupColor(\r\n entryKey: string,\r\n groupIdx: number,\r\n color: number,\r\n ): Promise<void> {\r\n const perEntry = this._idCache.get(entryKey)\r\n if (!perEntry) return\r\n const fragments = this.components.get(OBC.FragmentsManager)\r\n const threeColor = new THREE.Color(color)\r\n // Update the config so future activations also use the new color.\r\n if (this.config.groups[groupIdx]) {\r\n this.config.groups[groupIdx].color = color\r\n }\r\n await Promise.all(\r\n [...perEntry.entries()].map(async ([modelId, resolved]) => {\r\n const model = fragments.list.get(modelId) as any\r\n if (!model) return\r\n const ids = resolved.groupIds[groupIdx]\r\n if (!ids || ids.length === 0) return\r\n await this._swallow(() =>\r\n model.highlight(ids, { ...HIGHLIGHT_BASE, color: threeColor }),\r\n )\r\n }),\r\n )\r\n fragments.core.update(true)\r\n }\r\n\r\n invalidateForModel(modelId: string) {\r\n for (const perModel of this._idCache.values()) {\r\n perModel.delete(modelId)\r\n }\r\n }\r\n\r\n invalidateForEntry(entryKey: string) {\r\n this._idCache.delete(entryKey)\r\n }\r\n\r\n private async _resolveModel(\r\n entryKey: string,\r\n modelId: string,\r\n model: any,\r\n resolveCtx: (modelId: string, model: any) => Promise<ResolveContext>,\r\n ): Promise<ResolvedModel | null> {\r\n let perModel = this._idCache.get(entryKey)\r\n if (!perModel) {\r\n perModel = new Map()\r\n this._idCache.set(entryKey, perModel)\r\n }\r\n const cached = perModel.get(modelId)\r\n if (cached) return { modelId, model, resolved: cached }\r\n\r\n try {\r\n const ctx = await resolveCtx(modelId, model)\r\n // Fetch every group's category list in parallel.\r\n const groupMaps = await Promise.all(\r\n this.config.groups.map((g) => model.getItemsOfCategories(g.categories)),\r\n )\r\n let groupIds = groupMaps.map(\r\n (m) => Object.values(m).flat() as number[],\r\n )\r\n if (ctx.filterIds && ctx.filterIds.size > 0) {\r\n const filter = ctx.filterIds\r\n groupIds = groupIds.map((ids) => ids.filter((id) => filter.has(id)))\r\n }\r\n const resolved: ResolvedGroupIds = { groupIds }\r\n perModel.set(modelId, resolved)\r\n return { modelId, model, resolved }\r\n } catch (error) {\r\n console.warn('[CategoryHighlighter] resolve failed:', modelId, error)\r\n return null\r\n }\r\n }\r\n\r\n private _swallow<T>(fn: () => Promise<T> | T): Promise<T | undefined> {\r\n return Promise.resolve()\r\n .then(() => fn())\r\n .catch((e) => {\r\n console.warn('[CategoryHighlighter] op failed:', e)\r\n return undefined\r\n })\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"ChromeController.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/lib/ChromeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAM3C;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAaf,OAAO,CAAC,UAAU;IAZ9B,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,cAAc,CAAQ;IAE9B,OAAO,CAAC,wBAAwB,CAAuB;IAEvD,OAAO,CAAC,kBAAkB,CAAuB;IAEjD,OAAO,CAAC,aAAa,CAAkC;IAEvD,OAAO,CAAC,gBAAgB,CACb;gBAES,UAAU,EAAE,GAAG,CAAC,UAAU;IAE9C,SAAS;IAQT,aAAa;IAQb,kBAAkB;IAkBlB,kBAAkB;IAOlB,SAAS;IAST,SAAS;IAUT;mEAC+D;IAC/D,aAAa;IASb,cAAc;IAUd;;2CAEuC;IACvC,sBAAsB;IAStB,iBAAiB;IAQjB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;CAShB"}
1
+ {"version":3,"file":"ChromeController.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/lib/ChromeController.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAM3C;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAaf,OAAO,CAAC,UAAU;IAZ9B,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,cAAc,CAAQ;IAE9B,OAAO,CAAC,wBAAwB,CAAuB;IAEvD,OAAO,CAAC,kBAAkB,CAAuB;IAEjD,OAAO,CAAC,aAAa,CAAkC;IAEvD,OAAO,CAAC,gBAAgB,CACb;gBAES,UAAU,EAAE,GAAG,CAAC,UAAU;IAE9C,SAAS;IAQT,aAAa;IAQb,kBAAkB;IAkBlB,kBAAkB;IAOlB,SAAS;IAST,SAAS;IAUT;mEAC+D;IAC/D,aAAa;IASb,cAAc;IAUd;;2CAEuC;IACvC,sBAAsB;IAStB,iBAAiB;IAQjB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;CAShB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/lib/ChromeController.ts"],"sourcesContent":["import * as OBC from '@thatopen/components'\r\nimport * as THREE from 'three'\r\nimport { CurrentWorld } from '../CurrentWorld'\r\nimport { Highlighter } from '../Highlighter'\r\nimport { ViewportGizmo } from '../ViewportGizmo'\r\n\r\n/**\r\n * Manages the viewer chrome muted while a drawing-based view tool is\r\n * active: cursor, selection highlighter, viewport gizmo, and ambient\r\n * lighting. Each setter is idempotent and each restore is no-op when the\r\n * corresponding apply was never called — this keeps deactivate safe even\r\n * if activate failed midway.\r\n */\r\nexport class ChromeController {\r\n private _savedCursor: string | null = null\r\n private _cursorApplied = false\r\n\r\n private _savedHighlighterEnabled: boolean | null = null\r\n\r\n private _savedGizmoEnabled: boolean | null = null\r\n\r\n private _ambientLight: THREE.AmbientLight | null = null\r\n\r\n private _savedBackground: THREE.Color | THREE.Texture | null | undefined =\r\n undefined\r\n\r\n constructor(private components: OBC.Components) {}\r\n\r\n setCursor() {\r\n const canvas = this._canvas()\r\n if (!canvas || this._cursorApplied) return\r\n this._savedCursor = canvas.style.cursor\r\n canvas.style.cursor = 'grab'\r\n this._cursorApplied = true\r\n }\r\n\r\n restoreCursor() {\r\n if (!this._cursorApplied) return\r\n const canvas = this._canvas()\r\n if (canvas) canvas.style.cursor = this._savedCursor ?? ''\r\n this._savedCursor = null\r\n this._cursorApplied = false\r\n }\r\n\r\n disableHighlighter() {\r\n if (this._savedHighlighterEnabled !== null) return\r\n const highlighter = this._tryGet(Highlighter)\r\n if (!highlighter) return\r\n this._savedHighlighterEnabled = highlighter.enabled\r\n highlighter.enabled = false\r\n // `clearSelection()` empties the internal DataSet but the\r\n // `onBeforeDelete` listener that removes selection-overlay meshes from\r\n // the scene isn't always invoked by `.clear()`. Force-remove the\r\n // overlays directly so the cyan selection tint can't bleed onto the\r\n // white slabs in floorplan mode.\r\n for (const mesh of highlighter.selectedMeshes as Iterable<THREE.Mesh>) {\r\n mesh.removeFromParent()\r\n mesh.geometry?.dispose()\r\n }\r\n highlighter.clearSelection()\r\n }\r\n\r\n restoreHighlighter() {\r\n if (this._savedHighlighterEnabled === null) return\r\n const highlighter = this._tryGet(Highlighter)\r\n if (highlighter) highlighter.enabled = this._savedHighlighterEnabled\r\n this._savedHighlighterEnabled = null\r\n }\r\n\r\n hideGizmo() {\r\n if (this._savedGizmoEnabled !== null) return\r\n const gizmo = this._tryGet(ViewportGizmo)\r\n if (!gizmo) return\r\n this._savedGizmoEnabled = gizmo.enabled\r\n gizmo.enabled = false\r\n gizmo.remove()\r\n }\r\n\r\n showGizmo() {\r\n if (this._savedGizmoEnabled === null) return\r\n const gizmo = this._tryGet(ViewportGizmo)\r\n if (gizmo) {\r\n gizmo.enabled = this._savedGizmoEnabled\r\n if (this._savedGizmoEnabled) gizmo.add()\r\n }\r\n this._savedGizmoEnabled = null\r\n }\r\n\r\n /** The default scene uses a shadowed setup where pure-white materials\r\n * read as gray; flooding with ambient white restores them. */\r\n applyLighting() {\r\n if (this._ambientLight) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld?.scene?.three) return\r\n const light = new THREE.AmbientLight(0xffffff, 3)\r\n sourceWorld.scene.three.add(light)\r\n this._ambientLight = light\r\n }\r\n\r\n removeLighting() {\r\n if (!this._ambientLight) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (sourceWorld?.scene?.three) {\r\n sourceWorld.scene.three.remove(this._ambientLight)\r\n }\r\n this._ambientLight.dispose?.()\r\n this._ambientLight = null\r\n }\r\n\r\n /** Swap the scene background to a warm off-white during floorplan mode —\r\n * pure white reads cold, most architectural prints use a softer cream.\r\n * Restored on `restoreBackground`. */\r\n applyDrawingBackground() {\r\n if (this._savedBackground !== undefined) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n const scene = sourceWorld?.scene?.three\r\n if (!scene) return\r\n this._savedBackground = scene.background ?? null\r\n scene.background = new THREE.Color(0xfafaf6)\r\n }\r\n\r\n restoreBackground() {\r\n if (this._savedBackground === undefined) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n const scene = sourceWorld?.scene?.three\r\n if (scene) scene.background = this._savedBackground\r\n this._savedBackground = undefined\r\n }\r\n\r\n private _canvas(): HTMLCanvasElement | null {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n return (sourceWorld?.renderer as any)?.three?.domElement ?? null\r\n }\r\n\r\n private _tryGet<T>(ctor: new (...args: any[]) => T): T | null {\r\n try {\r\n return this.components.get(ctor as any) as T\r\n } catch {\r\n // Not registered in this viewer (e.g. SimpleBimViewer doesn't\r\n // register Highlighter or ViewportGizmo).\r\n return null\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/lib/ChromeController.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as OBC from '@thatopen/components'\r\nimport * as THREE from 'three'\r\nimport { CurrentWorld } from '../CurrentWorld'\r\nimport { Highlighter } from '../Highlighter'\r\nimport { ViewportGizmo } from '../ViewportGizmo'\r\n\r\n/**\r\n * Manages the viewer chrome muted while a drawing-based view tool is\r\n * active: cursor, selection highlighter, viewport gizmo, and ambient\r\n * lighting. Each setter is idempotent and each restore is no-op when the\r\n * corresponding apply was never called — this keeps deactivate safe even\r\n * if activate failed midway.\r\n */\r\nexport class ChromeController {\r\n private _savedCursor: string | null = null\r\n private _cursorApplied = false\r\n\r\n private _savedHighlighterEnabled: boolean | null = null\r\n\r\n private _savedGizmoEnabled: boolean | null = null\r\n\r\n private _ambientLight: THREE.AmbientLight | null = null\r\n\r\n private _savedBackground: THREE.Color | THREE.Texture | null | undefined =\r\n undefined\r\n\r\n constructor(private components: OBC.Components) {}\r\n\r\n setCursor() {\r\n const canvas = this._canvas()\r\n if (!canvas || this._cursorApplied) return\r\n this._savedCursor = canvas.style.cursor\r\n canvas.style.cursor = 'grab'\r\n this._cursorApplied = true\r\n }\r\n\r\n restoreCursor() {\r\n if (!this._cursorApplied) return\r\n const canvas = this._canvas()\r\n if (canvas) canvas.style.cursor = this._savedCursor ?? ''\r\n this._savedCursor = null\r\n this._cursorApplied = false\r\n }\r\n\r\n disableHighlighter() {\r\n if (this._savedHighlighterEnabled !== null) return\r\n const highlighter = this._tryGet(Highlighter)\r\n if (!highlighter) return\r\n this._savedHighlighterEnabled = highlighter.enabled\r\n highlighter.enabled = false\r\n // `clearSelection()` empties the internal DataSet but the\r\n // `onBeforeDelete` listener that removes selection-overlay meshes from\r\n // the scene isn't always invoked by `.clear()`. Force-remove the\r\n // overlays directly so the cyan selection tint can't bleed onto the\r\n // white slabs in floorplan mode.\r\n for (const mesh of highlighter.selectedMeshes as Iterable<THREE.Mesh>) {\r\n mesh.removeFromParent()\r\n mesh.geometry?.dispose()\r\n }\r\n highlighter.clearSelection()\r\n }\r\n\r\n restoreHighlighter() {\r\n if (this._savedHighlighterEnabled === null) return\r\n const highlighter = this._tryGet(Highlighter)\r\n if (highlighter) highlighter.enabled = this._savedHighlighterEnabled\r\n this._savedHighlighterEnabled = null\r\n }\r\n\r\n hideGizmo() {\r\n if (this._savedGizmoEnabled !== null) return\r\n const gizmo = this._tryGet(ViewportGizmo)\r\n if (!gizmo) return\r\n this._savedGizmoEnabled = gizmo.enabled\r\n gizmo.enabled = false\r\n gizmo.remove()\r\n }\r\n\r\n showGizmo() {\r\n if (this._savedGizmoEnabled === null) return\r\n const gizmo = this._tryGet(ViewportGizmo)\r\n if (gizmo) {\r\n gizmo.enabled = this._savedGizmoEnabled\r\n if (this._savedGizmoEnabled) gizmo.add()\r\n }\r\n this._savedGizmoEnabled = null\r\n }\r\n\r\n /** The default scene uses a shadowed setup where pure-white materials\r\n * read as gray; flooding with ambient white restores them. */\r\n applyLighting() {\r\n if (this._ambientLight) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld?.scene?.three) return\r\n const light = new THREE.AmbientLight(0xffffff, 3)\r\n sourceWorld.scene.three.add(light)\r\n this._ambientLight = light\r\n }\r\n\r\n removeLighting() {\r\n if (!this._ambientLight) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (sourceWorld?.scene?.three) {\r\n sourceWorld.scene.three.remove(this._ambientLight)\r\n }\r\n this._ambientLight.dispose?.()\r\n this._ambientLight = null\r\n }\r\n\r\n /** Swap the scene background to a warm off-white during floorplan mode —\r\n * pure white reads cold, most architectural prints use a softer cream.\r\n * Restored on `restoreBackground`. */\r\n applyDrawingBackground() {\r\n if (this._savedBackground !== undefined) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n const scene = sourceWorld?.scene?.three\r\n if (!scene) return\r\n this._savedBackground = scene.background ?? null\r\n scene.background = new THREE.Color(0xfafaf6)\r\n }\r\n\r\n restoreBackground() {\r\n if (this._savedBackground === undefined) return\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n const scene = sourceWorld?.scene?.three\r\n if (scene) scene.background = this._savedBackground\r\n this._savedBackground = undefined\r\n }\r\n\r\n private _canvas(): HTMLCanvasElement | null {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n return (sourceWorld?.renderer as any)?.three?.domElement ?? null\r\n }\r\n\r\n private _tryGet<T>(ctor: new (...args: any[]) => T): T | null {\r\n try {\r\n return this.components.get(ctor as any) as T\r\n } catch {\r\n // Not registered in this viewer (e.g. SimpleBimViewer doesn't\r\n // register Highlighter or ViewportGizmo).\r\n return null\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"ClipController.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/lib/ClipController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAC3C,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B;;;;;;;;GAQG;AACH,qBAAa,cAAc;IAGb,OAAO,CAAC,UAAU;IAF9B,OAAO,CAAC,MAAM,CAAyB;gBAEnB,UAAU,EAAE,GAAG,CAAC,UAAU;IAE9C,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO;IAiB7D,MAAM,CAAC,IAAI,EAAE,MAAM;IAOnB,SAAS;IAIT,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,gBAAgB;CAazB"}
1
+ {"version":3,"file":"ClipController.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/components/viewers/bim/src/lib/ClipController.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAC3C,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B;;;;;;;;GAQG;AACH,qBAAa,cAAc;IAGb,OAAO,CAAC,UAAU;IAF9B,OAAO,CAAC,MAAM,CAAyB;gBAEnB,UAAU,EAAE,GAAG,CAAC,UAAU;IAE9C,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO;IAiB7D,MAAM,CAAC,IAAI,EAAE,MAAM;IAOnB,SAAS;IAIT,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,gBAAgB;CAazB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/lib/ClipController.ts"],"sourcesContent":["import * as OBC from '@thatopen/components'\r\nimport * as THREE from 'three'\r\nimport { CurrentWorld } from '../CurrentWorld'\r\n\r\n/**\r\n * Slot-keyed wrapper around `OBC.Clipper`. Each slot name maps to a single\r\n * clip plane; `set(slot, …)` replaces any prior plane in that slot, and\r\n * `remove(slot)` / `removeAll()` clean up. Used by drawing-based view\r\n * tools that need a section clip and possibly a lower clip.\r\n *\r\n * Best-effort: a missing Clipper component (e.g. SimpleBimViewer) makes\r\n * every method a no-op rather than throwing.\r\n */\r\nexport class ClipController {\r\n private _slots = new Map<string, any>()\r\n\r\n constructor(private components: OBC.Components) {}\r\n\r\n set(slot: string, normal: THREE.Vector3, point: THREE.Vector3) {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld) return\r\n const clipper = this._clipper()\r\n if (!clipper?.createFromNormalAndCoplanarPoint) return\r\n\r\n this.remove(slot)\r\n\r\n const handle = clipper.createFromNormalAndCoplanarPoint(\r\n sourceWorld,\r\n normal,\r\n point,\r\n )\r\n this._slots.set(slot, handle)\r\n this._hidePlaneVisual(clipper, handle)\r\n }\r\n\r\n remove(slot: string) {\r\n const handle = this._slots.get(slot)\r\n if (!handle) return\r\n this._delete(handle)\r\n this._slots.delete(slot)\r\n }\r\n\r\n removeAll() {\r\n for (const slot of [...this._slots.keys()]) this.remove(slot)\r\n }\r\n\r\n has(slot: string): boolean {\r\n return this._slots.has(slot)\r\n }\r\n\r\n private _delete(handle: any) {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld) return\r\n const clipper = this._clipper()\r\n if (!clipper) return\r\n try {\r\n void clipper.delete(sourceWorld, handle)\r\n } catch (e) {\r\n console.warn('[ClipController] clipper.delete failed:', e)\r\n }\r\n }\r\n\r\n private _clipper(): any {\r\n try {\r\n return this.components.get(OBC.Clipper)\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n private _hidePlaneVisual(clipper: any, handle: any) {\r\n try {\r\n // Some OBC versions return the plane object directly; others return an\r\n // id keyed in `clipper.list`. Cover both shapes.\r\n const plane =\r\n handle && typeof handle === 'object' && 'visible' in handle\r\n ? handle\r\n : clipper?.list?.get?.(handle)\r\n if (plane) plane.visible = false\r\n } catch {\r\n // best-effort\r\n }\r\n }\r\n}\r\n"],"mappings":"AAAA,YAAY,SAAS;AAErB,SAAS,oBAAoB;AAWtB,MAAM,eAAe;AAAA,EAG1B,YAAoB,YAA4B;AAA5B;AAFpB,SAAQ,SAAS,oBAAI,IAAiB;AAAA,EAEW;AAAA,EAEjD,IAAI,MAAc,QAAuB,OAAsB;AAC7D,UAAM,cAAc,KAAK,WAAW,IAAI,YAAY,EAAE;AACtD,QAAI,CAAC,YAAa;AAClB,UAAM,UAAU,KAAK,SAAS;AAC9B,QAAI,EAAC,mCAAS,kCAAkC;AAEhD,SAAK,OAAO,IAAI;AAEhB,UAAM,SAAS,QAAQ;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,OAAO,IAAI,MAAM,MAAM;AAC5B,SAAK,iBAAiB,SAAS,MAAM;AAAA,EACvC;AAAA,EAEA,OAAO,MAAc;AACnB,UAAM,SAAS,KAAK,OAAO,IAAI,IAAI;AACnC,QAAI,CAAC,OAAQ;AACb,SAAK,QAAQ,MAAM;AACnB,SAAK,OAAO,OAAO,IAAI;AAAA,EACzB;AAAA,EAEA,YAAY;AACV,eAAW,QAAQ,CAAC,GAAG,KAAK,OAAO,KAAK,CAAC,EAAG,MAAK,OAAO,IAAI;AAAA,EAC9D;AAAA,EAEA,IAAI,MAAuB;AACzB,WAAO,KAAK,OAAO,IAAI,IAAI;AAAA,EAC7B;AAAA,EAEQ,QAAQ,QAAa;AAC3B,UAAM,cAAc,KAAK,WAAW,IAAI,YAAY,EAAE;AACtD,QAAI,CAAC,YAAa;AAClB,UAAM,UAAU,KAAK,SAAS;AAC9B,QAAI,CAAC,QAAS;AACd,QAAI;AACF,WAAK,QAAQ,OAAO,aAAa,MAAM;AAAA,IACzC,SAAS,GAAG;AACV,cAAQ,KAAK,2CAA2C,CAAC;AAAA,IAC3D;AAAA,EACF;AAAA,EAEQ,WAAgB;AACtB,QAAI;AACF,aAAO,KAAK,WAAW,IAAI,IAAI,OAAO;AAAA,IACxC,SAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,iBAAiB,SAAc,QAAa;AAtEtD;AAuEI,QAAI;AAGF,YAAM,QACJ,UAAU,OAAO,WAAW,YAAY,aAAa,SACjD,UACA,8CAAS,SAAT,mBAAe,QAAf,4BAAqB;AAC3B,UAAI,MAAO,OAAM,UAAU;AAAA,IAC7B,SAAQ;AAAA,IAER;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../../../../src/core/components/viewers/bim/src/lib/ClipController.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as OBC from '@thatopen/components'\r\nimport * as THREE from 'three'\r\nimport { CurrentWorld } from '../CurrentWorld'\r\n\r\n/**\r\n * Slot-keyed wrapper around `OBC.Clipper`. Each slot name maps to a single\r\n * clip plane; `set(slot, …)` replaces any prior plane in that slot, and\r\n * `remove(slot)` / `removeAll()` clean up. Used by drawing-based view\r\n * tools that need a section clip and possibly a lower clip.\r\n *\r\n * Best-effort: a missing Clipper component (e.g. SimpleBimViewer) makes\r\n * every method a no-op rather than throwing.\r\n */\r\nexport class ClipController {\r\n private _slots = new Map<string, any>()\r\n\r\n constructor(private components: OBC.Components) {}\r\n\r\n set(slot: string, normal: THREE.Vector3, point: THREE.Vector3) {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld) return\r\n const clipper = this._clipper()\r\n if (!clipper?.createFromNormalAndCoplanarPoint) return\r\n\r\n this.remove(slot)\r\n\r\n const handle = clipper.createFromNormalAndCoplanarPoint(\r\n sourceWorld,\r\n normal,\r\n point,\r\n )\r\n this._slots.set(slot, handle)\r\n this._hidePlaneVisual(clipper, handle)\r\n }\r\n\r\n remove(slot: string) {\r\n const handle = this._slots.get(slot)\r\n if (!handle) return\r\n this._delete(handle)\r\n this._slots.delete(slot)\r\n }\r\n\r\n removeAll() {\r\n for (const slot of [...this._slots.keys()]) this.remove(slot)\r\n }\r\n\r\n has(slot: string): boolean {\r\n return this._slots.has(slot)\r\n }\r\n\r\n private _delete(handle: any) {\r\n const sourceWorld = this.components.get(CurrentWorld).world\r\n if (!sourceWorld) return\r\n const clipper = this._clipper()\r\n if (!clipper) return\r\n try {\r\n void clipper.delete(sourceWorld, handle)\r\n } catch (e) {\r\n console.warn('[ClipController] clipper.delete failed:', e)\r\n }\r\n }\r\n\r\n private _clipper(): any {\r\n try {\r\n return this.components.get(OBC.Clipper)\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n private _hidePlaneVisual(clipper: any, handle: any) {\r\n try {\r\n // Some OBC versions return the plane object directly; others return an\r\n // id keyed in `clipper.list`. Cover both shapes.\r\n const plane =\r\n handle && typeof handle === 'object' && 'visible' in handle\r\n ? handle\r\n : clipper?.list?.get?.(handle)\r\n if (plane) plane.visible = false\r\n } catch {\r\n // best-effort\r\n }\r\n }\r\n}\r\n"],"mappings":"AAGA,YAAY,SAAS;AAErB,SAAS,oBAAoB;AAWtB,MAAM,eAAe;AAAA,EAG1B,YAAoB,YAA4B;AAA5B;AAFpB,SAAQ,SAAS,oBAAI,IAAiB;AAAA,EAEW;AAAA,EAEjD,IAAI,MAAc,QAAuB,OAAsB;AAC7D,UAAM,cAAc,KAAK,WAAW,IAAI,YAAY,EAAE;AACtD,QAAI,CAAC,YAAa;AAClB,UAAM,UAAU,KAAK,SAAS;AAC9B,QAAI,EAAC,mCAAS,kCAAkC;AAEhD,SAAK,OAAO,IAAI;AAEhB,UAAM,SAAS,QAAQ;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,OAAO,IAAI,MAAM,MAAM;AAC5B,SAAK,iBAAiB,SAAS,MAAM;AAAA,EACvC;AAAA,EAEA,OAAO,MAAc;AACnB,UAAM,SAAS,KAAK,OAAO,IAAI,IAAI;AACnC,QAAI,CAAC,OAAQ;AACb,SAAK,QAAQ,MAAM;AACnB,SAAK,OAAO,OAAO,IAAI;AAAA,EACzB;AAAA,EAEA,YAAY;AACV,eAAW,QAAQ,CAAC,GAAG,KAAK,OAAO,KAAK,CAAC,EAAG,MAAK,OAAO,IAAI;AAAA,EAC9D;AAAA,EAEA,IAAI,MAAuB;AACzB,WAAO,KAAK,OAAO,IAAI,IAAI;AAAA,EAC7B;AAAA,EAEQ,QAAQ,QAAa;AAC3B,UAAM,cAAc,KAAK,WAAW,IAAI,YAAY,EAAE;AACtD,QAAI,CAAC,YAAa;AAClB,UAAM,UAAU,KAAK,SAAS;AAC9B,QAAI,CAAC,QAAS;AACd,QAAI;AACF,WAAK,QAAQ,OAAO,aAAa,MAAM;AAAA,IACzC,SAAS,GAAG;AACV,cAAQ,KAAK,2CAA2C,CAAC;AAAA,IAC3D;AAAA,EACF;AAAA,EAEQ,WAAgB;AACtB,QAAI;AACF,aAAO,KAAK,WAAW,IAAI,IAAI,OAAO;AAAA,IACxC,SAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,iBAAiB,SAAc,QAAa;AAzEtD;AA0EI,QAAI;AAGF,YAAM,QACJ,UAAU,OAAO,WAAW,YAAY,aAAa,SACjD,UACA,8CAAS,SAAT,mBAAe,QAAf,4BAAqB;AAC3B,UAAI,MAAO,OAAM,UAAU;AAAA,IAC7B,SAAQ;AAAA,IAER;AAAA,EACF;AACF;","names":[]}