@mlightcad/cad-simple-viewer 1.4.13 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. package/dist/index.js +26532 -44513
  2. package/dist/index.umd.cjs +163 -52
  3. package/dist/libredwg-parser-worker.js +4378 -7481
  4. package/dist/mtext-renderer-worker.js +4107 -3865
  5. package/dist/viewer-runtime.iife.js +3879 -0
  6. package/lib/app/AcApAnnotation.js +4 -4
  7. package/lib/app/AcApAnnotation.js.map +1 -1
  8. package/lib/app/AcApDocManager.d.ts +59 -6
  9. package/lib/app/AcApDocManager.d.ts.map +1 -1
  10. package/lib/app/AcApDocManager.js +188 -28
  11. package/lib/app/AcApDocManager.js.map +1 -1
  12. package/lib/command/AcApLogCmd.d.ts +1 -1
  13. package/lib/command/AcApLogCmd.d.ts.map +1 -1
  14. package/lib/command/AcApLogCmd.js +1 -1
  15. package/lib/command/AcApLogCmd.js.map +1 -1
  16. package/lib/command/AcApOpenCmd.d.ts +1 -1
  17. package/lib/command/AcApOpenCmd.d.ts.map +1 -1
  18. package/lib/command/AcApOpenCmd.js +1 -2
  19. package/lib/command/AcApOpenCmd.js.map +1 -1
  20. package/lib/command/AcApPanCmd.d.ts +1 -1
  21. package/lib/command/AcApPanCmd.d.ts.map +1 -1
  22. package/lib/command/AcApPanCmd.js +1 -2
  23. package/lib/command/AcApPanCmd.js.map +1 -1
  24. package/lib/command/AcApQNewCmd.d.ts +1 -1
  25. package/lib/command/AcApQNewCmd.d.ts.map +1 -1
  26. package/lib/command/AcApQNewCmd.js +1 -1
  27. package/lib/command/AcApQNewCmd.js.map +1 -1
  28. package/lib/command/AcApRegenCmd.d.ts +1 -1
  29. package/lib/command/AcApRegenCmd.d.ts.map +1 -1
  30. package/lib/command/AcApRegenCmd.js +1 -1
  31. package/lib/command/AcApRegenCmd.js.map +1 -1
  32. package/lib/command/AcApSelectCmd.d.ts +1 -1
  33. package/lib/command/AcApSelectCmd.d.ts.map +1 -1
  34. package/lib/command/AcApSelectCmd.js +1 -2
  35. package/lib/command/AcApSelectCmd.js.map +1 -1
  36. package/lib/command/AcApZoomCmd.js +3 -3
  37. package/lib/command/AcApZoomCmd.js.map +1 -1
  38. package/lib/command/{AcApConvertToDxfCmd.d.ts → convert/AcApConvertToDxfCmd.d.ts} +2 -2
  39. package/lib/command/convert/AcApConvertToDxfCmd.d.ts.map +1 -0
  40. package/lib/command/{AcApConvertToDxfCmd.js → convert/AcApConvertToDxfCmd.js} +1 -1
  41. package/lib/command/convert/AcApConvertToDxfCmd.js.map +1 -0
  42. package/lib/command/{AcApConvertToPngCmd.d.ts → convert/AcApConvertToPngCmd.d.ts} +23 -5
  43. package/lib/command/convert/AcApConvertToPngCmd.d.ts.map +1 -0
  44. package/lib/command/{AcApConvertToPngCmd.js → convert/AcApConvertToPngCmd.js} +88 -15
  45. package/lib/command/convert/AcApConvertToPngCmd.js.map +1 -0
  46. package/lib/command/{AcApConvertToSvgCmd.d.ts → convert/AcApConvertToSvgCmd.d.ts} +2 -2
  47. package/lib/command/convert/AcApConvertToSvgCmd.d.ts.map +1 -0
  48. package/lib/command/{AcApConvertToSvgCmd.js → convert/AcApConvertToSvgCmd.js} +1 -1
  49. package/lib/command/convert/AcApConvertToSvgCmd.js.map +1 -0
  50. package/lib/command/convert/AcApDxfConvertor.d.ts.map +1 -0
  51. package/lib/command/{AcApDxfConvertor.js → convert/AcApDxfConvertor.js} +1 -1
  52. package/lib/command/convert/AcApDxfConvertor.js.map +1 -0
  53. package/lib/command/convert/AcApExportHtmlCmd.d.ts +22 -0
  54. package/lib/command/convert/AcApExportHtmlCmd.d.ts.map +1 -0
  55. package/lib/command/convert/AcApExportHtmlCmd.js +93 -0
  56. package/lib/command/convert/AcApExportHtmlCmd.js.map +1 -0
  57. package/lib/command/convert/AcApHtmlConvertor.d.ts +61 -0
  58. package/lib/command/convert/AcApHtmlConvertor.d.ts.map +1 -0
  59. package/lib/command/convert/AcApHtmlConvertor.js +223 -0
  60. package/lib/command/convert/AcApHtmlConvertor.js.map +1 -0
  61. package/lib/command/convert/AcApHtmlSnapshotBuilder.d.ts +65 -0
  62. package/lib/command/convert/AcApHtmlSnapshotBuilder.d.ts.map +1 -0
  63. package/lib/command/convert/AcApHtmlSnapshotBuilder.js +301 -0
  64. package/lib/command/convert/AcApHtmlSnapshotBuilder.js.map +1 -0
  65. package/lib/command/{AcApPngConvertor.d.ts → convert/AcApPngConvertor.d.ts} +20 -35
  66. package/lib/command/convert/AcApPngConvertor.d.ts.map +1 -0
  67. package/lib/command/{AcApPngConvertor.js → convert/AcApPngConvertor.js} +99 -71
  68. package/lib/command/convert/AcApPngConvertor.js.map +1 -0
  69. package/lib/command/convert/AcApSvgConvertor.d.ts.map +1 -0
  70. package/lib/command/{AcApSvgConvertor.js → convert/AcApSvgConvertor.js} +1 -1
  71. package/lib/command/convert/AcApSvgConvertor.js.map +1 -0
  72. package/lib/command/convert/index.d.ts +9 -0
  73. package/lib/command/convert/index.d.ts.map +1 -0
  74. package/lib/command/convert/index.js +9 -0
  75. package/lib/command/convert/index.js.map +1 -0
  76. package/lib/command/draw/AcApArcCmd.d.ts +297 -0
  77. package/lib/command/draw/AcApArcCmd.d.ts.map +1 -0
  78. package/lib/command/{AcApArcCmd.js → draw/AcApArcCmd.js} +839 -32
  79. package/lib/command/draw/AcApArcCmd.js.map +1 -0
  80. package/lib/command/{AcApCircleCmd.d.ts → draw/AcApCircleCmd.d.ts} +2 -2
  81. package/lib/command/draw/AcApCircleCmd.d.ts.map +1 -0
  82. package/lib/command/{AcApCircleCmd.js → draw/AcApCircleCmd.js} +8 -9
  83. package/lib/command/draw/AcApCircleCmd.js.map +1 -0
  84. package/lib/command/{AcApDimLinearCmd.d.ts → draw/AcApDimLinearCmd.d.ts} +2 -2
  85. package/lib/command/draw/AcApDimLinearCmd.d.ts.map +1 -0
  86. package/lib/command/{AcApDimLinearCmd.js → draw/AcApDimLinearCmd.js} +3 -3
  87. package/lib/command/draw/AcApDimLinearCmd.js.map +1 -0
  88. package/lib/command/{AcApEllipseCmd.d.ts → draw/AcApEllipseCmd.d.ts} +2 -2
  89. package/lib/command/draw/AcApEllipseCmd.d.ts.map +1 -0
  90. package/lib/command/{AcApEllipseCmd.js → draw/AcApEllipseCmd.js} +7 -9
  91. package/lib/command/draw/AcApEllipseCmd.js.map +1 -0
  92. package/lib/command/{AcApHatchCmd.d.ts → draw/AcApHatchCmd.d.ts} +54 -17
  93. package/lib/command/draw/AcApHatchCmd.d.ts.map +1 -0
  94. package/lib/command/{AcApHatchCmd.js → draw/AcApHatchCmd.js} +122 -30
  95. package/lib/command/draw/AcApHatchCmd.js.map +1 -0
  96. package/lib/command/{AcApLineCmd.d.ts → draw/AcApLineCmd.d.ts} +2 -2
  97. package/lib/command/draw/AcApLineCmd.d.ts.map +1 -0
  98. package/lib/command/{AcApLineCmd.js → draw/AcApLineCmd.js} +3 -3
  99. package/lib/command/draw/AcApLineCmd.js.map +1 -0
  100. package/lib/command/draw/AcApMLineCmd.d.ts +31 -0
  101. package/lib/command/draw/AcApMLineCmd.d.ts.map +1 -0
  102. package/lib/command/draw/AcApMLineCmd.js +528 -0
  103. package/lib/command/draw/AcApMLineCmd.js.map +1 -0
  104. package/lib/command/{AcApMTextCmd.d.ts → draw/AcApMTextCmd.d.ts} +2 -2
  105. package/lib/command/draw/AcApMTextCmd.d.ts.map +1 -0
  106. package/lib/command/{AcApMTextCmd.js → draw/AcApMTextCmd.js} +6 -4
  107. package/lib/command/draw/AcApMTextCmd.js.map +1 -0
  108. package/lib/command/draw/AcApPointCmd.d.ts +16 -0
  109. package/lib/command/draw/AcApPointCmd.d.ts.map +1 -0
  110. package/lib/command/draw/AcApPointCmd.js +98 -0
  111. package/lib/command/draw/AcApPointCmd.js.map +1 -0
  112. package/lib/command/{AcApPolygonCmd.d.ts → draw/AcApPolygonCmd.d.ts} +2 -2
  113. package/lib/command/draw/AcApPolygonCmd.d.ts.map +1 -0
  114. package/lib/command/{AcApPolygonCmd.js → draw/AcApPolygonCmd.js} +7 -8
  115. package/lib/command/draw/AcApPolygonCmd.js.map +1 -0
  116. package/lib/command/{AcApPolylineCmd.d.ts → draw/AcApPolylineCmd.d.ts} +51 -2
  117. package/lib/command/draw/AcApPolylineCmd.d.ts.map +1 -0
  118. package/lib/command/{AcApPolylineCmd.js → draw/AcApPolylineCmd.js} +203 -21
  119. package/lib/command/draw/AcApPolylineCmd.js.map +1 -0
  120. package/lib/command/draw/AcApRayCmd.d.ts +10 -0
  121. package/lib/command/draw/AcApRayCmd.d.ts.map +1 -0
  122. package/lib/command/draw/AcApRayCmd.js +144 -0
  123. package/lib/command/draw/AcApRayCmd.js.map +1 -0
  124. package/lib/command/{AcApRectCmd.d.ts → draw/AcApRectCmd.d.ts} +2 -2
  125. package/lib/command/draw/AcApRectCmd.d.ts.map +1 -0
  126. package/lib/command/{AcApRectCmd.js → draw/AcApRectCmd.js} +12 -13
  127. package/lib/command/draw/AcApRectCmd.js.map +1 -0
  128. package/lib/command/{AcApSplineCmd.d.ts → draw/AcApSplineCmd.d.ts} +2 -2
  129. package/lib/command/draw/AcApSplineCmd.d.ts.map +1 -0
  130. package/lib/command/{AcApSplineCmd.js → draw/AcApSplineCmd.js} +6 -9
  131. package/lib/command/draw/AcApSplineCmd.js.map +1 -0
  132. package/lib/command/draw/AcApXLineCmd.d.ts +25 -0
  133. package/lib/command/draw/AcApXLineCmd.d.ts.map +1 -0
  134. package/lib/command/draw/AcApXLineCmd.js +209 -0
  135. package/lib/command/draw/AcApXLineCmd.js.map +1 -0
  136. package/lib/command/draw/index.d.ts +16 -0
  137. package/lib/command/draw/index.d.ts.map +1 -0
  138. package/lib/command/draw/index.js +16 -0
  139. package/lib/command/draw/index.js.map +1 -0
  140. package/lib/command/index.d.ts +6 -32
  141. package/lib/command/index.d.ts.map +1 -1
  142. package/lib/command/index.js +6 -32
  143. package/lib/command/index.js.map +1 -1
  144. package/lib/command/layer/AcApLayerCloseCmd.d.ts +23 -0
  145. package/lib/command/layer/AcApLayerCloseCmd.d.ts.map +1 -0
  146. package/lib/command/layer/AcApLayerCloseCmd.js +86 -0
  147. package/lib/command/layer/AcApLayerCloseCmd.js.map +1 -0
  148. package/lib/command/{AcApLayerCmd.d.ts → layer/AcApLayerCmd.d.ts} +3 -5
  149. package/lib/command/layer/AcApLayerCmd.d.ts.map +1 -0
  150. package/lib/command/{AcApLayerCmd.js → layer/AcApLayerCmd.js} +5 -8
  151. package/lib/command/layer/AcApLayerCmd.js.map +1 -0
  152. package/lib/command/layer/AcApLayerCurCmd.d.ts +43 -0
  153. package/lib/command/layer/AcApLayerCurCmd.d.ts.map +1 -0
  154. package/lib/command/layer/AcApLayerCurCmd.js +183 -0
  155. package/lib/command/layer/AcApLayerCurCmd.js.map +1 -0
  156. package/lib/command/layer/AcApLayerDelCmd.d.ts +112 -0
  157. package/lib/command/layer/AcApLayerDelCmd.d.ts.map +1 -0
  158. package/lib/command/layer/AcApLayerDelCmd.js +446 -0
  159. package/lib/command/layer/AcApLayerDelCmd.js.map +1 -0
  160. package/lib/command/layer/AcApLayerFreezeCmd.d.ts +103 -0
  161. package/lib/command/layer/AcApLayerFreezeCmd.d.ts.map +1 -0
  162. package/lib/command/layer/AcApLayerFreezeCmd.js +398 -0
  163. package/lib/command/layer/AcApLayerFreezeCmd.js.map +1 -0
  164. package/lib/command/layer/AcApLayerIsoCmd.d.ts +99 -0
  165. package/lib/command/layer/AcApLayerIsoCmd.d.ts.map +1 -0
  166. package/lib/command/layer/AcApLayerIsoCmd.js +485 -0
  167. package/lib/command/layer/AcApLayerIsoCmd.js.map +1 -0
  168. package/lib/command/layer/AcApLayerIsoState.d.ts +68 -0
  169. package/lib/command/layer/AcApLayerIsoState.d.ts.map +1 -0
  170. package/lib/command/layer/AcApLayerIsoState.js +53 -0
  171. package/lib/command/layer/AcApLayerIsoState.js.map +1 -0
  172. package/lib/command/layer/AcApLayerLockCmd.d.ts +50 -0
  173. package/lib/command/layer/AcApLayerLockCmd.d.ts.map +1 -0
  174. package/lib/command/layer/AcApLayerLockCmd.js +175 -0
  175. package/lib/command/layer/AcApLayerLockCmd.js.map +1 -0
  176. package/lib/command/layer/AcApLayerOffCmd.d.ts +95 -0
  177. package/lib/command/layer/AcApLayerOffCmd.d.ts.map +1 -0
  178. package/lib/command/layer/AcApLayerOffCmd.js +384 -0
  179. package/lib/command/layer/AcApLayerOffCmd.js.map +1 -0
  180. package/lib/command/layer/AcApLayerOnCmd.d.ts +30 -0
  181. package/lib/command/layer/AcApLayerOnCmd.d.ts.map +1 -0
  182. package/lib/command/layer/AcApLayerOnCmd.js +138 -0
  183. package/lib/command/layer/AcApLayerOnCmd.js.map +1 -0
  184. package/lib/command/layer/AcApLayerPCmd.d.ts +83 -0
  185. package/lib/command/layer/AcApLayerPCmd.d.ts.map +1 -0
  186. package/lib/command/layer/AcApLayerPCmd.js +241 -0
  187. package/lib/command/layer/AcApLayerPCmd.js.map +1 -0
  188. package/lib/command/layer/AcApLayerThawCmd.d.ts +37 -0
  189. package/lib/command/layer/AcApLayerThawCmd.d.ts.map +1 -0
  190. package/lib/command/layer/AcApLayerThawCmd.js +150 -0
  191. package/lib/command/layer/AcApLayerThawCmd.js.map +1 -0
  192. package/lib/command/layer/AcApLayerUnisoCmd.d.ts +52 -0
  193. package/lib/command/layer/AcApLayerUnisoCmd.d.ts.map +1 -0
  194. package/lib/command/layer/AcApLayerUnisoCmd.js +199 -0
  195. package/lib/command/layer/AcApLayerUnisoCmd.js.map +1 -0
  196. package/lib/command/layer/AcApLayerUnlockCmd.d.ts +50 -0
  197. package/lib/command/layer/AcApLayerUnlockCmd.d.ts.map +1 -0
  198. package/lib/command/layer/AcApLayerUnlockCmd.js +175 -0
  199. package/lib/command/layer/AcApLayerUnlockCmd.js.map +1 -0
  200. package/lib/command/layer/index.d.ts +14 -0
  201. package/lib/command/layer/index.d.ts.map +1 -0
  202. package/lib/command/layer/index.js +14 -0
  203. package/lib/command/layer/index.js.map +1 -0
  204. package/lib/command/measure/AcApClearMeasurementsCmd.d.ts +24 -0
  205. package/lib/command/measure/AcApClearMeasurementsCmd.d.ts.map +1 -0
  206. package/lib/command/{AcApClearMeasurementsCmd.js → measure/AcApClearMeasurementsCmd.js} +16 -5
  207. package/lib/command/measure/AcApClearMeasurementsCmd.js.map +1 -0
  208. package/lib/command/{AcApMeasureAngleCmd.d.ts → measure/AcApMeasureAngleCmd.d.ts} +2 -2
  209. package/lib/command/measure/AcApMeasureAngleCmd.d.ts.map +1 -0
  210. package/lib/command/{AcApMeasureAngleCmd.js → measure/AcApMeasureAngleCmd.js} +18 -9
  211. package/lib/command/measure/AcApMeasureAngleCmd.js.map +1 -0
  212. package/lib/command/{AcApMeasureArcCmd.d.ts → measure/AcApMeasureArcCmd.d.ts} +2 -2
  213. package/lib/command/measure/AcApMeasureArcCmd.d.ts.map +1 -0
  214. package/lib/command/{AcApMeasureArcCmd.js → measure/AcApMeasureArcCmd.js} +14 -7
  215. package/lib/command/measure/AcApMeasureArcCmd.js.map +1 -0
  216. package/lib/command/{AcApMeasureAreaCmd.d.ts → measure/AcApMeasureAreaCmd.d.ts} +2 -2
  217. package/lib/command/measure/AcApMeasureAreaCmd.d.ts.map +1 -0
  218. package/lib/command/{AcApMeasureAreaCmd.js → measure/AcApMeasureAreaCmd.js} +14 -7
  219. package/lib/command/measure/AcApMeasureAreaCmd.js.map +1 -0
  220. package/lib/command/{AcApMeasureDistanceCmd.d.ts → measure/AcApMeasureDistanceCmd.d.ts} +5 -4
  221. package/lib/command/measure/AcApMeasureDistanceCmd.d.ts.map +1 -0
  222. package/lib/command/{AcApMeasureDistanceCmd.js → measure/AcApMeasureDistanceCmd.js} +17 -9
  223. package/lib/command/measure/AcApMeasureDistanceCmd.js.map +1 -0
  224. package/lib/command/measure/index.d.ts +6 -0
  225. package/lib/command/measure/index.d.ts.map +1 -0
  226. package/lib/command/measure/index.js +6 -0
  227. package/lib/command/measure/index.js.map +1 -0
  228. package/lib/command/modify/AcApCopyCmd.d.ts +94 -0
  229. package/lib/command/modify/AcApCopyCmd.d.ts.map +1 -0
  230. package/lib/command/modify/AcApCopyCmd.js +549 -0
  231. package/lib/command/modify/AcApCopyCmd.js.map +1 -0
  232. package/lib/command/{AcApEraseCmd.d.ts → modify/AcApEraseCmd.d.ts} +2 -2
  233. package/lib/command/modify/AcApEraseCmd.d.ts.map +1 -0
  234. package/lib/command/{AcApEraseCmd.js → modify/AcApEraseCmd.js} +3 -5
  235. package/lib/command/modify/AcApEraseCmd.js.map +1 -0
  236. package/lib/command/{AcApMoveCmd.d.ts → modify/AcApMoveCmd.d.ts} +2 -2
  237. package/lib/command/modify/AcApMoveCmd.d.ts.map +1 -0
  238. package/lib/command/{AcApMoveCmd.js → modify/AcApMoveCmd.js} +3 -4
  239. package/lib/command/modify/AcApMoveCmd.js.map +1 -0
  240. package/lib/command/modify/AcApOffsetCmd.d.ts +30 -0
  241. package/lib/command/modify/AcApOffsetCmd.d.ts.map +1 -0
  242. package/lib/command/modify/AcApOffsetCmd.js +424 -0
  243. package/lib/command/modify/AcApOffsetCmd.js.map +1 -0
  244. package/lib/command/modify/AcApRotateCmd.d.ts +81 -0
  245. package/lib/command/modify/AcApRotateCmd.d.ts.map +1 -0
  246. package/lib/command/modify/AcApRotateCmd.js +486 -0
  247. package/lib/command/modify/AcApRotateCmd.js.map +1 -0
  248. package/lib/command/modify/index.d.ts +6 -0
  249. package/lib/command/modify/index.d.ts.map +1 -0
  250. package/lib/command/modify/index.js +6 -0
  251. package/lib/command/modify/index.js.map +1 -0
  252. package/lib/command/{AcApBaseRevCmd.d.ts → review/AcApBaseRevCmd.d.ts} +2 -2
  253. package/lib/command/review/AcApBaseRevCmd.d.ts.map +1 -0
  254. package/lib/command/{AcApBaseRevCmd.js → review/AcApBaseRevCmd.js} +2 -2
  255. package/lib/command/review/AcApBaseRevCmd.js.map +1 -0
  256. package/lib/command/{AcApRevCircleCmd.d.ts → review/AcApRevCircleCmd.d.ts} +1 -1
  257. package/lib/command/review/AcApRevCircleCmd.d.ts.map +1 -0
  258. package/lib/command/{AcApRevCircleCmd.js → review/AcApRevCircleCmd.js} +8 -5
  259. package/lib/command/review/AcApRevCircleCmd.js.map +1 -0
  260. package/lib/command/{AcApRevCloudCmd.d.ts → review/AcApRevCloudCmd.d.ts} +2 -2
  261. package/lib/command/review/AcApRevCloudCmd.d.ts.map +1 -0
  262. package/lib/command/{AcApRevCloudCmd.js → review/AcApRevCloudCmd.js} +3 -3
  263. package/lib/command/review/AcApRevCloudCmd.js.map +1 -0
  264. package/lib/command/{AcApRevRectCmd.d.ts → review/AcApRevRectCmd.d.ts} +1 -1
  265. package/lib/command/review/AcApRevRectCmd.d.ts.map +1 -0
  266. package/lib/command/{AcApRevRectCmd.js → review/AcApRevRectCmd.js} +3 -3
  267. package/lib/command/review/AcApRevRectCmd.js.map +1 -0
  268. package/lib/command/{AcApRevVisibilityCmd.d.ts → review/AcApRevVisibilityCmd.d.ts} +1 -1
  269. package/lib/command/review/AcApRevVisibilityCmd.d.ts.map +1 -0
  270. package/lib/command/{AcApRevVisibilityCmd.js → review/AcApRevVisibilityCmd.js} +2 -2
  271. package/lib/command/review/AcApRevVisibilityCmd.js.map +1 -0
  272. package/lib/command/{AcApSketchCmd.d.ts → review/AcApSketchCmd.d.ts} +2 -2
  273. package/lib/command/review/AcApSketchCmd.d.ts.map +1 -0
  274. package/lib/command/{AcApSketchCmd.js → review/AcApSketchCmd.js} +3 -3
  275. package/lib/command/review/AcApSketchCmd.js.map +1 -0
  276. package/lib/command/review/index.d.ts +7 -0
  277. package/lib/command/review/index.d.ts.map +1 -0
  278. package/lib/command/review/index.js +7 -0
  279. package/lib/command/review/index.js.map +1 -0
  280. package/lib/editor/global/eventBus.d.ts +4 -6
  281. package/lib/editor/global/eventBus.d.ts.map +1 -1
  282. package/lib/editor/global/eventBus.js.map +1 -1
  283. package/lib/editor/input/AcEdSelectionFilter.js +7 -6
  284. package/lib/editor/input/AcEdSelectionFilter.js.map +1 -1
  285. package/lib/editor/input/AcEditor.d.ts +17 -0
  286. package/lib/editor/input/AcEditor.d.ts.map +1 -1
  287. package/lib/editor/input/AcEditor.js +23 -0
  288. package/lib/editor/input/AcEditor.js.map +1 -1
  289. package/lib/editor/input/prompt/AcEdPromptBoxOptions.d.ts +6 -0
  290. package/lib/editor/input/prompt/AcEdPromptBoxOptions.d.ts.map +1 -1
  291. package/lib/editor/input/prompt/AcEdPromptBoxOptions.js +16 -0
  292. package/lib/editor/input/prompt/AcEdPromptBoxOptions.js.map +1 -1
  293. package/lib/editor/input/prompt/AcEdPromptDistanceOptions.d.ts.map +1 -1
  294. package/lib/editor/input/prompt/AcEdPromptDistanceOptions.js +1 -1
  295. package/lib/editor/input/prompt/AcEdPromptDistanceOptions.js.map +1 -1
  296. package/lib/editor/input/prompt/AcEdPromptPointOptions.d.ts +6 -0
  297. package/lib/editor/input/prompt/AcEdPromptPointOptions.d.ts.map +1 -1
  298. package/lib/editor/input/prompt/AcEdPromptPointOptions.js +16 -0
  299. package/lib/editor/input/prompt/AcEdPromptPointOptions.js.map +1 -1
  300. package/lib/editor/input/ui/AcEdCommandLine.d.ts +25 -23
  301. package/lib/editor/input/ui/AcEdCommandLine.d.ts.map +1 -1
  302. package/lib/editor/input/ui/AcEdCommandLine.js +101 -43
  303. package/lib/editor/input/ui/AcEdCommandLine.js.map +1 -1
  304. package/lib/editor/input/ui/AcEdFloatingInput.d.ts +9 -0
  305. package/lib/editor/input/ui/AcEdFloatingInput.d.ts.map +1 -1
  306. package/lib/editor/input/ui/AcEdFloatingInput.js +25 -5
  307. package/lib/editor/input/ui/AcEdFloatingInput.js.map +1 -1
  308. package/lib/editor/input/ui/AcEdInputManager.d.ts +46 -6
  309. package/lib/editor/input/ui/AcEdInputManager.d.ts.map +1 -1
  310. package/lib/editor/input/ui/AcEdInputManager.js +153 -43
  311. package/lib/editor/input/ui/AcEdInputManager.js.map +1 -1
  312. package/lib/editor/input/ui/AcEdMTextEditor.d.ts +67 -2
  313. package/lib/editor/input/ui/AcEdMTextEditor.d.ts.map +1 -1
  314. package/lib/editor/input/ui/AcEdMTextEditor.js +210 -19
  315. package/lib/editor/input/ui/AcEdMTextEditor.js.map +1 -1
  316. package/lib/editor/input/ui/AcEdMessageType.d.ts +10 -0
  317. package/lib/editor/input/ui/AcEdMessageType.d.ts.map +1 -0
  318. package/lib/editor/input/ui/AcEdMessageType.js +2 -0
  319. package/lib/editor/input/ui/AcEdMessageType.js.map +1 -0
  320. package/lib/editor/input/ui/AcEdRubberBand.d.ts.map +1 -1
  321. package/lib/editor/input/ui/AcEdRubberBand.js +16 -8
  322. package/lib/editor/input/ui/AcEdRubberBand.js.map +1 -1
  323. package/lib/editor/input/ui/index.d.ts +1 -0
  324. package/lib/editor/input/ui/index.d.ts.map +1 -1
  325. package/lib/editor/input/ui/index.js +1 -0
  326. package/lib/editor/input/ui/index.js.map +1 -1
  327. package/lib/editor/view/AcEdBaseView.d.ts +3 -8
  328. package/lib/editor/view/AcEdBaseView.d.ts.map +1 -1
  329. package/lib/editor/view/AcEdBaseView.js +3 -5
  330. package/lib/editor/view/AcEdBaseView.js.map +1 -1
  331. package/lib/editor/view/AcEdHoverController.d.ts +2 -3
  332. package/lib/editor/view/AcEdHoverController.d.ts.map +1 -1
  333. package/lib/editor/view/AcEdHoverController.js +7 -0
  334. package/lib/editor/view/AcEdHoverController.js.map +1 -1
  335. package/lib/editor/view/AcEdSelectionAction.d.ts +108 -0
  336. package/lib/editor/view/AcEdSelectionAction.d.ts.map +1 -0
  337. package/lib/editor/view/AcEdSelectionAction.js +74 -0
  338. package/lib/editor/view/AcEdSelectionAction.js.map +1 -0
  339. package/lib/editor/view/index.d.ts +1 -0
  340. package/lib/editor/view/index.d.ts.map +1 -1
  341. package/lib/editor/view/index.js +1 -0
  342. package/lib/editor/view/index.js.map +1 -1
  343. package/lib/i18n/en/command.d.ts +187 -13
  344. package/lib/i18n/en/command.d.ts.map +1 -1
  345. package/lib/i18n/en/command.js +195 -21
  346. package/lib/i18n/en/command.js.map +1 -1
  347. package/lib/i18n/en/jig.d.ts +579 -212
  348. package/lib/i18n/en/jig.d.ts.map +1 -1
  349. package/lib/i18n/en/jig.js +669 -302
  350. package/lib/i18n/en/jig.js.map +1 -1
  351. package/lib/i18n/zh/command.d.ts +187 -13
  352. package/lib/i18n/zh/command.d.ts.map +1 -1
  353. package/lib/i18n/zh/command.js +196 -22
  354. package/lib/i18n/zh/command.js.map +1 -1
  355. package/lib/i18n/zh/jig.d.ts +579 -212
  356. package/lib/i18n/zh/jig.d.ts.map +1 -1
  357. package/lib/i18n/zh/jig.js +668 -301
  358. package/lib/i18n/zh/jig.js.map +1 -1
  359. package/lib/index.d.ts +2 -1
  360. package/lib/index.d.ts.map +1 -1
  361. package/lib/index.js +2 -1
  362. package/lib/index.js.map +1 -1
  363. package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.d.ts +136 -2
  364. package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.d.ts.map +1 -1
  365. package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.js +154 -16
  366. package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.js.map +1 -1
  367. package/lib/util/AcApFontUtil.d.ts +69 -0
  368. package/lib/util/AcApFontUtil.d.ts.map +1 -0
  369. package/lib/util/AcApFontUtil.js +161 -0
  370. package/lib/util/AcApFontUtil.js.map +1 -0
  371. package/lib/util/index.d.ts +2 -0
  372. package/lib/util/index.d.ts.map +1 -1
  373. package/lib/util/index.js +2 -0
  374. package/lib/util/index.js.map +1 -1
  375. package/lib/util/yieldToMain.d.ts +5 -0
  376. package/lib/util/yieldToMain.d.ts.map +1 -0
  377. package/lib/util/yieldToMain.js +11 -0
  378. package/lib/util/yieldToMain.js.map +1 -0
  379. package/lib/view/AcTrLayout.d.ts +17 -0
  380. package/lib/view/AcTrLayout.d.ts.map +1 -1
  381. package/lib/view/AcTrLayout.js +34 -2
  382. package/lib/view/AcTrLayout.js.map +1 -1
  383. package/lib/view/AcTrLayoutView.d.ts +12 -0
  384. package/lib/view/AcTrLayoutView.d.ts.map +1 -1
  385. package/lib/view/AcTrLayoutView.js +18 -0
  386. package/lib/view/AcTrLayoutView.js.map +1 -1
  387. package/lib/view/AcTrPickResultUtil.d.ts +4 -0
  388. package/lib/view/AcTrPickResultUtil.d.ts.map +1 -0
  389. package/lib/view/AcTrPickResultUtil.js +54 -0
  390. package/lib/view/AcTrPickResultUtil.js.map +1 -0
  391. package/lib/view/AcTrScene.d.ts +38 -6
  392. package/lib/view/AcTrScene.d.ts.map +1 -1
  393. package/lib/view/AcTrScene.js +57 -30
  394. package/lib/view/AcTrScene.js.map +1 -1
  395. package/lib/view/AcTrView2d.d.ts +191 -0
  396. package/lib/view/AcTrView2d.d.ts.map +1 -1
  397. package/lib/view/AcTrView2d.js +795 -137
  398. package/lib/view/AcTrView2d.js.map +1 -1
  399. package/package.json +14 -8
  400. package/lib/command/AcApArcCmd.d.ts +0 -140
  401. package/lib/command/AcApArcCmd.d.ts.map +0 -1
  402. package/lib/command/AcApArcCmd.js.map +0 -1
  403. package/lib/command/AcApBaseRevCmd.d.ts.map +0 -1
  404. package/lib/command/AcApBaseRevCmd.js.map +0 -1
  405. package/lib/command/AcApCircleCmd.d.ts.map +0 -1
  406. package/lib/command/AcApCircleCmd.js.map +0 -1
  407. package/lib/command/AcApClearMeasurementsCmd.d.ts +0 -13
  408. package/lib/command/AcApClearMeasurementsCmd.d.ts.map +0 -1
  409. package/lib/command/AcApClearMeasurementsCmd.js.map +0 -1
  410. package/lib/command/AcApConvertToDxfCmd.d.ts.map +0 -1
  411. package/lib/command/AcApConvertToDxfCmd.js.map +0 -1
  412. package/lib/command/AcApConvertToPngCmd.d.ts.map +0 -1
  413. package/lib/command/AcApConvertToPngCmd.js.map +0 -1
  414. package/lib/command/AcApConvertToSvgCmd.d.ts.map +0 -1
  415. package/lib/command/AcApConvertToSvgCmd.js.map +0 -1
  416. package/lib/command/AcApDimLinearCmd.d.ts.map +0 -1
  417. package/lib/command/AcApDimLinearCmd.js.map +0 -1
  418. package/lib/command/AcApDxfConvertor.d.ts.map +0 -1
  419. package/lib/command/AcApDxfConvertor.js.map +0 -1
  420. package/lib/command/AcApEllipseCmd.d.ts.map +0 -1
  421. package/lib/command/AcApEllipseCmd.js.map +0 -1
  422. package/lib/command/AcApEraseCmd.d.ts.map +0 -1
  423. package/lib/command/AcApEraseCmd.js.map +0 -1
  424. package/lib/command/AcApHatchCmd.d.ts.map +0 -1
  425. package/lib/command/AcApHatchCmd.js.map +0 -1
  426. package/lib/command/AcApLayerCmd.d.ts.map +0 -1
  427. package/lib/command/AcApLayerCmd.js.map +0 -1
  428. package/lib/command/AcApLineCmd.d.ts.map +0 -1
  429. package/lib/command/AcApLineCmd.js.map +0 -1
  430. package/lib/command/AcApMTextCmd.d.ts.map +0 -1
  431. package/lib/command/AcApMTextCmd.js.map +0 -1
  432. package/lib/command/AcApMeasureAngleCmd.d.ts.map +0 -1
  433. package/lib/command/AcApMeasureAngleCmd.js.map +0 -1
  434. package/lib/command/AcApMeasureArcCmd.d.ts.map +0 -1
  435. package/lib/command/AcApMeasureArcCmd.js.map +0 -1
  436. package/lib/command/AcApMeasureAreaCmd.d.ts.map +0 -1
  437. package/lib/command/AcApMeasureAreaCmd.js.map +0 -1
  438. package/lib/command/AcApMeasureDistanceCmd.d.ts.map +0 -1
  439. package/lib/command/AcApMeasureDistanceCmd.js.map +0 -1
  440. package/lib/command/AcApMoveCmd.d.ts.map +0 -1
  441. package/lib/command/AcApMoveCmd.js.map +0 -1
  442. package/lib/command/AcApPngConvertor.d.ts.map +0 -1
  443. package/lib/command/AcApPngConvertor.js.map +0 -1
  444. package/lib/command/AcApPolygonCmd.d.ts.map +0 -1
  445. package/lib/command/AcApPolygonCmd.js.map +0 -1
  446. package/lib/command/AcApPolylineCmd.d.ts.map +0 -1
  447. package/lib/command/AcApPolylineCmd.js.map +0 -1
  448. package/lib/command/AcApRectCmd.d.ts.map +0 -1
  449. package/lib/command/AcApRectCmd.js.map +0 -1
  450. package/lib/command/AcApRevCircleCmd.d.ts.map +0 -1
  451. package/lib/command/AcApRevCircleCmd.js.map +0 -1
  452. package/lib/command/AcApRevCloudCmd.d.ts.map +0 -1
  453. package/lib/command/AcApRevCloudCmd.js.map +0 -1
  454. package/lib/command/AcApRevRectCmd.d.ts.map +0 -1
  455. package/lib/command/AcApRevRectCmd.js.map +0 -1
  456. package/lib/command/AcApRevVisibilityCmd.d.ts.map +0 -1
  457. package/lib/command/AcApRevVisibilityCmd.js.map +0 -1
  458. package/lib/command/AcApSketchCmd.d.ts.map +0 -1
  459. package/lib/command/AcApSketchCmd.js.map +0 -1
  460. package/lib/command/AcApSplineCmd.d.ts.map +0 -1
  461. package/lib/command/AcApSplineCmd.js.map +0 -1
  462. package/lib/command/AcApSvgConvertor.d.ts.map +0 -1
  463. package/lib/command/AcApSvgConvertor.js.map +0 -1
  464. /package/lib/command/{AcApDxfConvertor.d.ts → convert/AcApDxfConvertor.d.ts} +0 -0
  465. /package/lib/command/{AcApSvgConvertor.d.ts → convert/AcApSvgConvertor.d.ts} +0 -0
@@ -71,17 +71,18 @@ var __values = (this && this.__values) || function(o) {
71
71
  };
72
72
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
73
73
  };
74
- import { acdbHostApplicationServices, AcDbRasterImage, AcDbRay, AcDbSysVarManager, AcDbViewport, AcDbXline, AcGeBox2d, AcGePoint2d, log } from '@mlightcad/data-model';
74
+ import { acdbHostApplicationServices, AcDbMText, AcDbRasterImage, AcDbRay, AcDbSysVarManager, AcDbViewport, AcDbXline, AcGeBox2d, AcGePoint2d, log } from '@mlightcad/data-model';
75
75
  import { AcDbSystemVariables } from '@mlightcad/data-model';
76
- import { AcTrEntity, AcTrGroup, AcTrRenderer, AcTrViewportView } from '@mlightcad/three-renderer';
76
+ import { AcTrEntity, AcTrGroup, AcTrRenderer, AcTrViewportView, getMaterialMetadata, hasByLayerBinding, setMaterialMetadata } from '@mlightcad/three-renderer';
77
77
  import * as THREE from 'three';
78
78
  import Stats from 'three/examples/jsm/libs/stats.module';
79
79
  import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
80
80
  import { AcApDocManager, AcApSettingManager } from '../app';
81
- import { AcEdBaseView, AcEdConditionWaiter, AcEdCorsorType, AcEdViewMode, applyUiThemeFromBackground, eventBus } from '../editor';
81
+ import { AcEdBaseView, AcEdConditionWaiter, AcEdCorsorType, AcEdMTextEditor, AcEdOpenMode, AcEdViewMode, applyUiThemeFromBackground, eventBus, resolvePointerSelectionAction } from '../editor';
82
82
  import { AcTrGeometryUtil } from '../util';
83
83
  import { AcTrLayoutView } from './AcTrLayoutView';
84
84
  import { AcTrLayoutViewManager } from './AcTrLayoutViewManager';
85
+ import { sortPickResults } from './AcTrPickResultUtil';
85
86
  import { AcTrScene } from './AcTrScene';
86
87
  /**
87
88
  * Default view option values
@@ -144,6 +145,37 @@ var AcTrView2d = /** @class */ (function (_super) {
144
145
  * A value of `null` indicates that no animation frame is currently scheduled.
145
146
  */
146
147
  _this._rafId = null;
148
+ /**
149
+ * Block table record ids of layouts whose entities are currently being
150
+ * batch-converted into the scene. Used by
151
+ * {@link AcTrView2d.loadLayoutEntitiesIfNeeded} to guard against
152
+ * re-entrant calls before the `setTimeout` callback flips
153
+ * `AcTrLayout.isLoaded` to `true`, which would otherwise duplicate
154
+ * entities when the same layout tab is clicked twice in quick succession.
155
+ */
156
+ _this._loadingLayouts = new Set();
157
+ /**
158
+ * Block table record ids of layouts that have already received an
159
+ * initial zoom-to-fit. Used by the `layoutSwitched` handler to apply
160
+ * the auto-zoom **only on the first user visit** to each layout, and
161
+ * to preserve the camera state on subsequent visits (matches AutoCAD's
162
+ * per-tab view persistence).
163
+ *
164
+ * Cannot be inferred from `_layoutViewManager.has(btrId)` because
165
+ * `addLayout` pre-creates an `AcTrLayoutView` for every layout in the
166
+ * DWG at document load time — by the time the user clicks a layout
167
+ * tab the view already exists, so "first existence of view" is
168
+ * always false. This set tracks the orthogonal question "has the user
169
+ * actually focused on this layout before?".
170
+ *
171
+ * Marked from two entry points:
172
+ * - `onAfterOpenDocument` (via `markLayoutAsInitialized`): the
173
+ * document's startup layout is initialized externally, so we don't
174
+ * auto-zoom again when the user clicks back to it.
175
+ * - `layoutSwitched` handler: after the first user-driven switch
176
+ * completes its initial zoom-to-fit.
177
+ */
178
+ _this._initializedLayouts = new Set();
147
179
  _this.animate = function () {
148
180
  var _a;
149
181
  _this._rafId = requestAnimationFrame(_this.animate);
@@ -179,11 +211,44 @@ var AcTrView2d = /** @class */ (function (_super) {
179
211
  // Initialize background color through setter to keep renderer/cursor/foreground in sync.
180
212
  _this.backgroundColor = mergedOptions.background || 0x000000;
181
213
  _this._stats = _this.createStats(AcApSettingManager.instance.isShowStats);
214
+ // Two sysvars can drive the canvas background:
215
+ //
216
+ // - WHITEBKCOLOR (boolean): the low-level "is the paper white?" flag
217
+ // that the View has always honoured.
218
+ // - COLORTHEME (number): the AutoCAD-standard theme selector where
219
+ // 0 = dark theme (black bg) and 1 = light theme (white bg).
220
+ //
221
+ // The Vue composable `useDark` (cad-viewer) toggles only COLORTHEME
222
+ // when the user flips the theme. Without this bridge, toggling the
223
+ // UI theme left WHITEBKCOLOR stale and the canvas kept its previous
224
+ // background even though `changeForeground` had been fired through
225
+ // MTEXT/line inversion — producing e.g. a black canvas in light mode
226
+ // or a white canvas in dark mode.
227
+ //
228
+ // Listening to both sysvars keeps either entry point working. The
229
+ // two remain independent (settable in isolation) because setting
230
+ // `this.backgroundColor` is idempotent and the handler for each
231
+ // sysvar only fires when that specific variable changes.
182
232
  AcDbSysVarManager.instance().events.sysVarChanged.addEventListener(function (args) {
183
- if (args.name === AcDbSystemVariables.WHITEBKCOLOR.toLowerCase()) {
233
+ var nameLower = args.name.toLowerCase();
234
+ if (nameLower === AcDbSystemVariables.WHITEBKCOLOR.toLowerCase()) {
184
235
  var useWhiteBackgroundColor = args.newVal;
185
236
  _this.backgroundColor = useWhiteBackgroundColor ? 0xffffff : 0;
186
237
  }
238
+ else if (nameLower === AcDbSystemVariables.COLORTHEME.toLowerCase()) {
239
+ // COLORTHEME is registered with type 'number' in the data-model
240
+ // (0 = dark, 1 = light), but the sysvar bus does not strictly
241
+ // coerce values. Normalise defensively so plugins setting the
242
+ // value as a string or boolean still behave correctly.
243
+ var newVal = args.newVal;
244
+ var isLight = typeof newVal === 'number'
245
+ ? newVal === 1
246
+ : typeof newVal === 'boolean'
247
+ ? newVal
248
+ : String(newVal).toLowerCase() === 'light' ||
249
+ String(newVal) === '1';
250
+ _this.backgroundColor = isLight ? 0xffffff : 0;
251
+ }
187
252
  });
188
253
  AcApSettingManager.instance.events.modified.addEventListener(function (args) {
189
254
  if (args.key == 'isShowStats') {
@@ -194,7 +259,9 @@ var AcTrView2d = /** @class */ (function (_super) {
194
259
  var selectionStartCanvas = null;
195
260
  var selectionPreviewEl = null;
196
261
  var canHandleSelectionGesture = function () {
197
- return _this.mode === AcEdViewMode.SELECTION && !_this.editor.isActive;
262
+ return (_this.mode === AcEdViewMode.SELECTION &&
263
+ !_this.editor.isActive &&
264
+ !AcEdMTextEditor.getActiveInputBox());
198
265
  };
199
266
  var clearSelectionPreview = function () {
200
267
  selectionPreviewEl === null || selectionPreviewEl === void 0 ? void 0 : selectionPreviewEl.remove();
@@ -227,7 +294,7 @@ var AcTrView2d = /** @class */ (function (_super) {
227
294
  var width = Math.abs(p1.x - p2.x);
228
295
  var height = Math.abs(p1.y - p2.y);
229
296
  var mode = _this.getSelectionMode(selectionStartCanvas, curCanvas);
230
- var action = _this.getSelectionActionFromEvent(e);
297
+ var action = _this.getPointerSelectionAction(e);
231
298
  var style = _this.getSelectionPreviewStyle(mode, action);
232
299
  Object.assign(selectionPreviewEl.style, {
233
300
  left: "".concat(left, "px"),
@@ -248,7 +315,7 @@ var AcTrView2d = /** @class */ (function (_super) {
248
315
  });
249
316
  var endWcs = _this.screenToWorld(endCanvas);
250
317
  clearSelectionPreview();
251
- var action = _this.getSelectionActionFromEvent(e);
318
+ var action = _this.getPointerSelectionAction(e);
252
319
  if (_this.isSelectionClick(selectionStartCanvas, endCanvas)) {
253
320
  var picked = _this.pick(endWcs);
254
321
  if (picked.length > 0) {
@@ -268,6 +335,16 @@ var AcTrView2d = /** @class */ (function (_super) {
268
335
  selectionStartWcs = null;
269
336
  selectionStartCanvas = null;
270
337
  });
338
+ _this.canvas.addEventListener('dblclick', function (e) {
339
+ if (e.button !== 0)
340
+ return;
341
+ if (!canHandleSelectionGesture())
342
+ return;
343
+ if (AcApDocManager.instance.curDocument.openMode !== AcEdOpenMode.Write) {
344
+ return;
345
+ }
346
+ void _this.openPickedMTextEditor(e);
347
+ });
271
348
  // When using OrbitControls in THREE.js, it attaches its own event listeners to the DOM elements,
272
349
  // such as the canvas or the entire document. This can interfere with other event listeners you
273
350
  // add, including the keydown event.
@@ -299,10 +376,50 @@ var AcTrView2d = /** @class */ (function (_super) {
299
376
  }
300
377
  });
301
378
  acdbHostApplicationServices().layoutManager.events.layoutSwitched.addEventListener(function (args) {
302
- _this.activeLayoutBtrId = args.layout.blockTableRecordId;
303
- _this.createLayoutViewIfNeeded(args.layout.blockTableRecordId);
304
- _this.loadLayoutEntitiesIfNeeded(args.layout.blockTableRecordId);
379
+ var btrId = args.layout.blockTableRecordId;
380
+ // "First visit" is tracked separately from view existence because
381
+ // `addLayout` pre-creates an `AcTrLayoutView` for every layout in
382
+ // the DWG at load time — `_layoutViewManager.has(btrId)` is
383
+ // therefore `true` even for layouts the user has never focused
384
+ // on, and "first visit" computed from it would always be false.
385
+ // We use a dedicated set instead, marked here on first switch and
386
+ // also from `markLayoutAsInitialized` when the document opens
387
+ // straight into a layout (AcApDocManager has already framed it).
388
+ // Each AcTrLayoutView owns its own camera, so on subsequent
389
+ // visits the previous camera state is naturally restored and we
390
+ // must NOT zoom-to-fit again — that would be jarring and
391
+ // diverges from how AutoCAD preserves per-tab view state.
392
+ var isFirstVisit = !_this._initializedLayouts.has(btrId);
393
+ _this._initializedLayouts.add(btrId);
394
+ // Clear measurement overlays before swapping layouts.
395
+ // Measurements are screen/coordinate-anchored — their dimension
396
+ // text, hatch indicators, and HTML overlays were laid out in
397
+ // the previous layout's WCS (paper coords, ~unit scale) and
398
+ // would render at nonsense positions in a different layout
399
+ // (model WCS is typically O(10^5) larger, paper layouts use
400
+ // their own sheet coords). Selection state is intentionally
401
+ // **not** cleared here: it is entity-id-based and the same
402
+ // entity stays selected wherever it is rendered (the model
403
+ // entity drilled through a paper viewport remains visually
404
+ // selected when the user returns to model space, matching
405
+ // AutoCAD desktop's behaviour).
406
+ //
407
+ // Dynamic import avoids a circular dependency: the cleanup
408
+ // module already imports `AcTrView2d` for its
409
+ // `htmlTransientManager` cast, so a static import here would
410
+ // create a cycle. The cost (one extra microtask) is
411
+ // negligible for a layout switch.
412
+ void import('../command/measure/AcApClearMeasurementsCmd').then(function (_a) {
413
+ var clearAllMeasurements = _a.clearAllMeasurements;
414
+ return clearAllMeasurements(_this);
415
+ });
416
+ _this.activeLayoutBtrId = btrId;
417
+ _this.createLayoutViewIfNeeded(btrId);
418
+ _this.loadLayoutEntitiesIfNeeded(btrId);
305
419
  _this._isDirty = true;
420
+ if (isFirstVisit) {
421
+ _this.applyInitialZoom(btrId, args.layout);
422
+ }
306
423
  });
307
424
  _this._css2dRenderer = new CSS2DRenderer();
308
425
  _this._css2dRenderer.setSize(_this.width, _this.height);
@@ -321,6 +438,9 @@ var AcTrView2d = /** @class */ (function (_super) {
321
438
  _this._numOfEntitiesToProcess = 0;
322
439
  return _this;
323
440
  }
441
+ AcTrView2d.prototype.getPointerSelectionAction = function (e) {
442
+ return resolvePointerSelectionAction(e);
443
+ };
324
444
  /**
325
445
  * Initializes the viewer after renderer and camera are created.
326
446
  *
@@ -431,6 +551,9 @@ var AcTrView2d = /** @class */ (function (_super) {
431
551
  set: function (value) {
432
552
  this._renderer.setClearColor(value);
433
553
  this._renderer.changeForeground(value == 0 ? 0xffffff : 0);
554
+ // Store the canvas colour for theme-sensitive materials created after this
555
+ // point. `changeForeground` above keeps ACI 7 linework and hatches visible.
556
+ this._renderer.currentBackgroundColor = value;
434
557
  this.editor.setCursorColor(value == 0 ? 'white' : 'black');
435
558
  applyUiThemeFromBackground(value);
436
559
  this._isDirty = true;
@@ -486,6 +609,16 @@ var AcTrView2d = /** @class */ (function (_super) {
486
609
  enumerable: false,
487
610
  configurable: true
488
611
  });
612
+ Object.defineProperty(AcTrView2d.prototype, "cadScene", {
613
+ /**
614
+ * CAD scene graph used for rendering and HTML export.
615
+ */
616
+ get: function () {
617
+ return this._scene;
618
+ },
619
+ enumerable: false,
620
+ configurable: true
621
+ });
489
622
  Object.defineProperty(AcTrView2d.prototype, "internalScene", {
490
623
  /**
491
624
  * The internal THREE scene used by this view.
@@ -613,40 +746,248 @@ var AcTrView2d = /** @class */ (function (_super) {
613
746
  this.activeLayoutView.flyTo(point, scale);
614
747
  this._isDirty = true;
615
748
  };
749
+ AcTrView2d.prototype.openPickedMTextEditor = function (e) {
750
+ return __awaiter(this, void 0, void 0, function () {
751
+ var point, worldPoint, picked, entity;
752
+ return __generator(this, function (_a) {
753
+ switch (_a.label) {
754
+ case 0:
755
+ point = this.viewportToCanvas({
756
+ x: e.clientX,
757
+ y: e.clientY
758
+ });
759
+ worldPoint = this.screenToWorld(point);
760
+ picked = this.pick(worldPoint, undefined, true);
761
+ if (!picked.length)
762
+ return [2 /*return*/];
763
+ entity = AcApDocManager.instance.curDocument.database.tables.blockTable.getEntityById(picked[0].id);
764
+ if (!(entity instanceof AcDbMText))
765
+ return [2 /*return*/];
766
+ e.preventDefault();
767
+ return [4 /*yield*/, this.editMTextEntity(entity)];
768
+ case 1:
769
+ _a.sent();
770
+ return [2 /*return*/];
771
+ }
772
+ });
773
+ });
774
+ };
775
+ AcTrView2d.prototype.editMTextEntity = function (mtext) {
776
+ return __awaiter(this, void 0, void 0, function () {
777
+ var editor, applied, result;
778
+ return __generator(this, function (_a) {
779
+ switch (_a.label) {
780
+ case 0:
781
+ if (mtext.lineSpacingFactor !== AcEdMTextEditor.defaultLineSpacingFactor) {
782
+ mtext.lineSpacingFactor = AcEdMTextEditor.defaultLineSpacingFactor;
783
+ mtext.triggerModifiedEvent();
784
+ }
785
+ // Hide the in-scene MTEXT while the inline editor renders its own copy; otherwise
786
+ // both draw at once (double text) when the user double-clicks to edit.
787
+ // this.removeEntity(mtext)
788
+ this._isDirty = true;
789
+ editor = new AcEdMTextEditor();
790
+ applied = false;
791
+ _a.label = 1;
792
+ case 1:
793
+ _a.trys.push([1, , 3, 4]);
794
+ return [4 /*yield*/, editor.open({
795
+ view: this,
796
+ location: mtext.location,
797
+ width: this.resolveMTextEditorWidth(mtext),
798
+ textHeight: this.resolveMTextEditorTextHeight(mtext),
799
+ initialText: mtext.contents,
800
+ initialAttachmentPoint: mtext.attachmentPoint,
801
+ toolbarFontFamilies: this.getMTextToolbarFontFamilies()
802
+ })];
803
+ case 2:
804
+ result = _a.sent();
805
+ if (!result)
806
+ return [2 /*return*/];
807
+ mtext.location = result.location;
808
+ mtext.contents = result.contents;
809
+ mtext.width = result.width;
810
+ mtext.height = result.height;
811
+ mtext.lineSpacingFactor = result.lineSpacingFactor;
812
+ mtext.attachmentPoint = result.attachmentPoint;
813
+ mtext.triggerModifiedEvent();
814
+ applied = true;
815
+ return [3 /*break*/, 4];
816
+ case 3:
817
+ if (!applied) {
818
+ this.updateEntity(mtext);
819
+ this._isDirty = true;
820
+ }
821
+ return [7 /*endfinally*/];
822
+ case 4: return [2 /*return*/];
823
+ }
824
+ });
825
+ });
826
+ };
827
+ AcTrView2d.prototype.resolveMTextEditorWidth = function (mtext) {
828
+ var width = Number(mtext.width);
829
+ if (Number.isFinite(width) && width > 0)
830
+ return width;
831
+ return 1e-4;
832
+ };
833
+ AcTrView2d.prototype.resolveMTextEditorTextHeight = function (mtext) {
834
+ var textHeight = Number(mtext.height);
835
+ if (Number.isFinite(textHeight) && textHeight > 0)
836
+ return textHeight;
837
+ return this.pixelsToWorldY(24);
838
+ };
839
+ AcTrView2d.prototype.pixelsToWorldY = function (pixels) {
840
+ var p0 = this.screenToWorld({ x: 0, y: 0 });
841
+ var p1 = this.screenToWorld({ x: 0, y: pixels });
842
+ return Math.max(Math.abs(p1.y - p0.y), 1e-4);
843
+ };
844
+ AcTrView2d.prototype.getMTextToolbarFontFamilies = function () {
845
+ return Array.from(new Set(AcApDocManager.instance.avaiableFonts
846
+ .flatMap(function (fontInfo) { return fontInfo.name; })
847
+ .map(function (fontName) { return fontName.trim(); })
848
+ .filter(function (fontName) { return fontName.length > 0; })));
849
+ };
616
850
  /**
617
851
  * @inheritdoc
852
+ *
853
+ * In **paper space** layouts the selection pipeline supports
854
+ * "drill-through": clicks inside a viewport rectangle resolve against
855
+ * the model-space entities that are visually rendered through that
856
+ * viewport, rather than picking the viewport's border. Clicks **near**
857
+ * the border still pick the `AcDbViewport` entity itself so the user
858
+ * can grip, move, lock or delete the viewport.
859
+ *
860
+ * This mirrors AutoCAD **web** behaviour (single-click selection of
861
+ * model content through the viewport). The desktop ARX behaviour
862
+ * (explicit MSPACE/PSPACE modes, CVPORT system variable, double-click
863
+ * to enter mspace) is a separate, larger feature — tracked in
864
+ * `.claude/plans/next_14_viewports_full.md` PR-γ Option A. We
865
+ * intentionally do **not** implement it here.
866
+ *
867
+ * The border vs interior decision uses a tolerance derived from
868
+ * `selectionBoxSize` (the same pixel-sized hit radius used elsewhere
869
+ * in pick) converted to paper-space WCS via `pointToBox`. This keeps
870
+ * the gesture consistent with how other entity edges behave — you
871
+ * don't have to land pixel-perfect on the viewport line to grab it.
618
872
  */
619
873
  AcTrView2d.prototype.pick = function (point, hitRadius, pickOneOnly) {
874
+ var e_1, _a;
620
875
  if (point == null)
621
876
  point = this.curPos;
622
877
  var results = [];
623
878
  var activeLayout = this._scene.activeLayout;
624
- if (activeLayout) {
625
- var activeLayoutView = this.activeLayoutView;
626
- var box = activeLayoutView.pointToBox(point, hitRadius !== null && hitRadius !== void 0 ? hitRadius : this.selectionBoxSize);
627
- var firstQueryResults = this._scene.search(box);
628
- var threshold = Math.max(box.size.width / 2, box.size.height / 2);
629
- var raycaster_1 = activeLayoutView.resetRaycaster(point, threshold);
630
- if (pickOneOnly) {
631
- firstQueryResults.some(function (item) {
632
- var objectId = item.id;
633
- if (activeLayout.isIntersectWith(objectId, raycaster_1)) {
634
- results.push(item);
635
- return true;
879
+ if (!activeLayout)
880
+ return results;
881
+ var activeLayoutView = this.activeLayoutView;
882
+ var effectiveHitRadius = hitRadius !== null && hitRadius !== void 0 ? hitRadius : this.selectionBoxSize;
883
+ var paperBox = activeLayoutView.pointToBox(point, effectiveHitRadius);
884
+ var threshold = Math.max(paperBox.size.width / 2, paperBox.size.height / 2);
885
+ // Identify drill-through viewports (paper space only): viewports whose
886
+ // paper rectangle contains the click AND whose border is NOT within
887
+ // tolerance of the click. The border tolerance is the average of the
888
+ // hit-box width/height — a robust, scale-aware proxy for "user is
889
+ // trying to grab the frame, not click inside".
890
+ var isPaperSpace = activeLayoutView.layoutBtrId !== this._scene.modelSpaceBtrId;
891
+ var borderTolerance = (paperBox.size.width + paperBox.size.height) / 2;
892
+ var drillThroughViewports = [];
893
+ var drillThroughViewportIds = new Set();
894
+ if (isPaperSpace) {
895
+ try {
896
+ for (var _b = __values(activeLayoutView.viewportViews), _c = _b.next(); !_c.done; _c = _b.next()) {
897
+ var vpView = _c.value;
898
+ if (vpView.containsPaperPoint(point) &&
899
+ !vpView.isNearPaperBorder(point, borderTolerance)) {
900
+ drillThroughViewports.push(vpView);
901
+ drillThroughViewportIds.add(vpView.viewport.id);
636
902
  }
637
- return false;
638
- });
903
+ }
639
904
  }
640
- else {
641
- firstQueryResults.forEach(function (item) {
642
- var objectId = item.id;
643
- if (activeLayout.isIntersectWith(objectId, raycaster_1)) {
644
- results.push(item);
645
- }
646
- });
905
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
906
+ finally {
907
+ try {
908
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
909
+ }
910
+ finally { if (e_1) throw e_1.error; }
911
+ }
912
+ }
913
+ // 1) Resolve hits in the active layout. Skip the `AcDbViewport`
914
+ // entity for any viewport we're drilling through — otherwise the
915
+ // rectangle's bounding box always wins (it covers the whole click
916
+ // region) and selection feels "stuck on the frame".
917
+ var firstQueryResults = this._scene.search(paperBox);
918
+ var raycaster = activeLayoutView.resetRaycaster(point, threshold);
919
+ firstQueryResults.forEach(function (item) {
920
+ if (drillThroughViewportIds.has(item.id))
921
+ return;
922
+ if (activeLayout.isIntersectWith(item.id, raycaster)) {
923
+ results.push(item);
924
+ }
925
+ });
926
+ // 2) For each drill-through viewport, resolve hits against the
927
+ // model-space layout using the viewport's own camera/raycaster.
928
+ if (drillThroughViewports.length > 0) {
929
+ this.pickThroughViewports(point, paperBox, drillThroughViewports, results);
930
+ }
931
+ var sortedResults = sortPickResults(results, point);
932
+ return pickOneOnly ? sortedResults.slice(0, 1) : sortedResults;
933
+ };
934
+ /**
935
+ * Resolves hits against the model-space layout for each viewport the
936
+ * click drills through. Appends the matches into `results` (caller
937
+ * sorts/dedups). Kept private and separate from `pick` so the main
938
+ * pick path stays a single straight read.
939
+ *
940
+ * Each viewport gets its own raycaster shot (using the viewport view's
941
+ * own camera, which is zoomed to `viewport.viewBox` in model WCS), so
942
+ * a click that lands in overlapping viewports correctly resolves
943
+ * against each viewport's particular model framing.
944
+ *
945
+ * `pickThroughViewports` does NOT consult the active (paper) layout's
946
+ * spatial index — that work is already done by the caller. It only
947
+ * adds model-space results that would otherwise be invisible to the
948
+ * paper-space pick.
949
+ */
950
+ AcTrView2d.prototype.pickThroughViewports = function (paperPoint, paperBox, viewports, results) {
951
+ var e_2, _a;
952
+ var modelLayout = this._scene.modelSpaceLayout;
953
+ if (!modelLayout)
954
+ return;
955
+ // Half-extent of the paper-space hit box (== "radius" in paper WCS).
956
+ // Multiplied per viewport by its paper→model scale, this becomes a
957
+ // model-WCS radius that the per-viewport raycaster threshold and the
958
+ // spatial-index probe both use. This keeps the hit area visually
959
+ // consistent across viewports at different zoom levels.
960
+ var paperHalfRadius = (paperBox.size.width + paperBox.size.height) / 4;
961
+ var _loop_1 = function (vpView) {
962
+ var modelPt = vpView.paperPointToModel(paperPoint);
963
+ var modelRadius = paperHalfRadius * vpView.paperToModelScale;
964
+ if (modelRadius <= 0)
965
+ return "continue";
966
+ var modelBox = new AcGeBox2d().setFromPoints([
967
+ new AcGePoint2d(modelPt.x - modelRadius, modelPt.y - modelRadius),
968
+ new AcGePoint2d(modelPt.x + modelRadius, modelPt.y + modelRadius)
969
+ ]);
970
+ var vpRaycaster = vpView.resetRaycaster(modelPt, modelRadius);
971
+ var modelHits = modelLayout.search(modelBox);
972
+ modelHits.forEach(function (item) {
973
+ if (modelLayout.isIntersectWith(item.id, vpRaycaster)) {
974
+ results.push(item);
975
+ }
976
+ });
977
+ };
978
+ try {
979
+ for (var viewports_1 = __values(viewports), viewports_1_1 = viewports_1.next(); !viewports_1_1.done; viewports_1_1 = viewports_1.next()) {
980
+ var vpView = viewports_1_1.value;
981
+ _loop_1(vpView);
982
+ }
983
+ }
984
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
985
+ finally {
986
+ try {
987
+ if (viewports_1_1 && !viewports_1_1.done && (_a = viewports_1.return)) _a.call(viewports_1);
647
988
  }
989
+ finally { if (e_2) throw e_2.error; }
648
990
  }
649
- return results;
650
991
  };
651
992
  /**
652
993
  * @inheritdoc
@@ -674,12 +1015,27 @@ var AcTrView2d = /** @class */ (function (_super) {
674
1015
  * @inheritdoc
675
1016
  */
676
1017
  AcTrView2d.prototype.addLayer = function (layer) {
677
- this._scene.addLayer({
1018
+ var updatedLayers = this._scene.addLayer({
678
1019
  name: layer.name,
679
1020
  isFrozen: layer.isFrozen,
680
1021
  isOff: layer.isOff,
681
1022
  color: layer.color
682
1023
  });
1024
+ var traits = {
1025
+ layer: layer.name,
1026
+ color: layer.color.clone(),
1027
+ rgbColor: layer.color.RGB,
1028
+ lineType: layer.lineStyle,
1029
+ lineWeight: layer.lineWeight,
1030
+ transparency: layer.transparency
1031
+ };
1032
+ var materials = this._renderer.updateLayerMaterial(layer.name, traits);
1033
+ updatedLayers.forEach(function (updatedLayer) {
1034
+ for (var id in materials) {
1035
+ var material = materials[id];
1036
+ updatedLayer.updateMaterial(Number(id), material);
1037
+ }
1038
+ });
683
1039
  this._isDirty = true;
684
1040
  };
685
1041
  /**
@@ -806,6 +1162,91 @@ var AcTrView2d = /** @class */ (function (_super) {
806
1162
  this.createLayoutViewIfNeeded(layout.blockTableRecordId);
807
1163
  this._isDirty = true;
808
1164
  };
1165
+ /**
1166
+ * Marks a layout as already framed by an external caller (typically
1167
+ * `AcApDocManager.onAfterOpenDocument`, which zooms the startup
1168
+ * layout right after parsing). Subsequent `layoutSwitched` events
1169
+ * for this btrId will skip their initial zoom-to-fit so the user's
1170
+ * camera state on the startup layout is preserved when they click
1171
+ * back to that tab.
1172
+ *
1173
+ * This is the public counterpart of the `_initializedLayouts` set —
1174
+ * exposed so the application layer can stay in sync with the view's
1175
+ * notion of "which layouts have been framed already" without
1176
+ * needing access to private state.
1177
+ */
1178
+ AcTrView2d.prototype.markLayoutAsInitialized = function (layoutBtrId) {
1179
+ this._initializedLayouts.add(layoutBtrId);
1180
+ };
1181
+ /**
1182
+ * Applies the initial zoom-to-fit for a layout the user just switched
1183
+ * into for the first time. Picks the best available "what should the
1184
+ * camera frame?" signal in this order:
1185
+ *
1186
+ * 1. **`AcDbLayout.limits`** (LIMMIN/LIMMAX) — only when it actually
1187
+ * contains the layout's viewports. Many real DWGs ship with garbage
1188
+ * limits (e.g. `(0,0)-(12,9)` from a legacy template setup) that
1189
+ * don't reflect the actual paper sheet. We reject those by
1190
+ * checking containment against `viewportsBoundingBox`.
1191
+ *
1192
+ * 2. **`AcTrLayoutView.viewportsBoundingBox`** — bounding box of all
1193
+ * real user viewports in the layout. In production sheets viewports
1194
+ * typically span 70-90% of the paper, so this is a great proxy for
1195
+ * the printable area and (crucially) ignores outliers like title
1196
+ * blocks authored in a different unit/scale.
1197
+ *
1198
+ * 3. **`AcDbLayout.extents`** — the layout's own EXTMIN/EXTMAX, if
1199
+ * populated. Many parsers leave this empty (we've seen `(0,0)-(0,0)`),
1200
+ * so it sits below the viewport-based heuristic.
1201
+ *
1202
+ * 4. **`zoomToFitDrawing`** (entity extents from spatial index) —
1203
+ * last-resort fallback for layouts with no viewports and no
1204
+ * sensible limits/extents (e.g. a freshly created empty paper).
1205
+ * Vulnerable to scale-mismatch outliers, but better than no zoom.
1206
+ *
1207
+ * **Critically, this runs through `AcEdConditionWaiter`**: at the
1208
+ * moment `layoutSwitched` fires, the layout's entities (including its
1209
+ * `AcDbViewport`s) have not yet been batch-converted into the scene
1210
+ * — `loadLayoutEntitiesIfNeeded` chunked-converts via `setTimeout`.
1211
+ * Without the waiter, `viewportsBoundingBox` returns undefined and
1212
+ * the strategy degrades into (1) zooming to garbage `limits`, or
1213
+ * (4) zooming to an empty scene box. The waiter polls
1214
+ * `_numOfEntitiesToProcess` and only fires the heuristic once the
1215
+ * conversion is done.
1216
+ */
1217
+ AcTrView2d.prototype.applyInitialZoom = function (btrId, layout) {
1218
+ var _this = this;
1219
+ var waiter = new AcEdConditionWaiter(function () { return _this._numOfEntitiesToProcess <= 0; }, function () {
1220
+ var limits = layout.limits;
1221
+ var layoutView = _this._layoutViewManager.getAt(btrId);
1222
+ var vpsBox = layoutView === null || layoutView === void 0 ? void 0 : layoutView.viewportsBoundingBox;
1223
+ var limitsContainsViewports = (function () {
1224
+ if (!limits || limits.isEmpty())
1225
+ return false;
1226
+ if (!vpsBox)
1227
+ return true;
1228
+ return (limits.min.x <= vpsBox.min.x &&
1229
+ limits.min.y <= vpsBox.min.y &&
1230
+ limits.max.x >= vpsBox.max.x &&
1231
+ limits.max.y >= vpsBox.max.y);
1232
+ })();
1233
+ if (limits && !limits.isEmpty() && limitsContainsViewports) {
1234
+ _this.zoomTo(limits);
1235
+ }
1236
+ else if (vpsBox) {
1237
+ _this.zoomTo(vpsBox);
1238
+ }
1239
+ else if (layout.extents && !layout.extents.isEmpty()) {
1240
+ var extents = layout.extents;
1241
+ _this.zoomTo(new AcGeBox2d({ x: extents.min.x, y: extents.min.y }, { x: extents.max.x, y: extents.max.y }));
1242
+ }
1243
+ else if (_this._scene.box) {
1244
+ _this.zoomTo(AcTrGeometryUtil.threeBox3dToGeBox2d(_this._scene.box));
1245
+ }
1246
+ _this._isDirty = true;
1247
+ }, 300, 0);
1248
+ waiter.start();
1249
+ };
809
1250
  /**
810
1251
  * @inheritdoc
811
1252
  */
@@ -893,10 +1334,26 @@ var AcTrView2d = /** @class */ (function (_super) {
893
1334
  /**
894
1335
  * Load entities from the specified layout if they haven't been loaded yet.
895
1336
  * This ensures that when switching to a layout, all its entities are available for rendering.
1337
+ *
1338
+ * Two non-obvious invariants are enforced here:
1339
+ *
1340
+ * 1. The layout is looked up by `layoutBtrId` (the argument), not by
1341
+ * `this._scene.activeLayout`. The active layout reference happens to
1342
+ * match in the current `layoutSwitched` handler call site, but relying
1343
+ * on it would silently miss layouts that are pre-loaded ahead of
1344
+ * becoming active (e.g. background prefetch).
1345
+ * 2. The `_loadingLayouts` guard prevents re-entrance while the
1346
+ * `setTimeout` chunked-convert callback is still in flight. Without it,
1347
+ * clicking the same layout tab twice in quick succession (or
1348
+ * `layoutSwitched` firing twice during the async window) would iterate
1349
+ * the block table record again and duplicate every entity in the
1350
+ * layout — visible as ghosted overdraw and double the spatial-index
1351
+ * weight.
1352
+ *
896
1353
  * @param layoutBtrId Input the block table record id of the layout
897
1354
  */
898
1355
  AcTrView2d.prototype.loadLayoutEntitiesIfNeeded = function (layoutBtrId) {
899
- var e_1, _a;
1356
+ var e_3, _a;
900
1357
  var _this = this;
901
1358
  try {
902
1359
  var db = AcApDocManager.instance.curDocument.database;
@@ -904,10 +1361,60 @@ var AcTrView2d = /** @class */ (function (_super) {
904
1361
  if (!blockTableRecord) {
905
1362
  return;
906
1363
  }
907
- var layout = this._scene.activeLayout;
908
- if (layout && layout.isLoaded) {
1364
+ var existingLayout = this._scene.layouts.get(layoutBtrId);
1365
+ if (existingLayout && existingLayout.isLoaded) {
1366
+ return;
1367
+ }
1368
+ if (this._loadingLayouts.has(layoutBtrId)) {
909
1369
  return;
910
1370
  }
1371
+ // Ensure `AcTrViewportView`s exist for every real `AcDbViewport`
1372
+ // in this layout when the layout's entities were already streamed
1373
+ // in by the document parser. There is a race in the parser-driven
1374
+ // load path: `addLayout(layout)` creates the `AcTrLayoutView`,
1375
+ // but the parser may dispatch the AcDbViewport entities before
1376
+ // that happens. When that races, `batchConvert`'s viewport
1377
+ // handler does `_layoutViewManager.getAt(entity.ownerId)`, gets
1378
+ // `undefined`, and **silently skips creating the
1379
+ // AcTrViewportView**. The reload path below used to mask this by
1380
+ // re-running batchConvert after the layoutView existed, but the
1381
+ // entityCount-skip optimization that follows removes that
1382
+ // side-effect, so we do the viewport-view-only pass explicitly
1383
+ // here. Skipped when the layout is empty — in that case the
1384
+ // batchConvert path below will create the viewport views directly
1385
+ // as it processes each entity.
1386
+ var layoutView = this._layoutViewManager.getAt(layoutBtrId);
1387
+ if (existingLayout &&
1388
+ existingLayout.entityCount > 0 &&
1389
+ layoutView &&
1390
+ layoutView.viewportCount === 0) {
1391
+ this.ensureViewportViews(blockTableRecord, layoutView);
1392
+ }
1393
+ // Model space (and any other layout pre-populated by the document
1394
+ // parser at open time) lands here without `isLoaded` ever having
1395
+ // been flipped — the initial entity stream goes through
1396
+ // `addEntity()` directly, bypassing this method. Without this
1397
+ // guard, switching back to model space from a paper layout would
1398
+ // re-iterate the full block table record and re-batch-convert
1399
+ // every entity (5759+ on real DWGs), freezing the UI for several
1400
+ // seconds AND duplicating entities (every entity ends up in the
1401
+ // layout twice, doubling the spatial-index weight and render
1402
+ // cost).
1403
+ //
1404
+ // If the layout already has entities, the parser has finished
1405
+ // loading them — flip the flag and bail. The reload path below
1406
+ // is only for layouts whose entities were never streamed in
1407
+ // (typically non-active paper-space layouts loaded on first user
1408
+ // visit).
1409
+ if (existingLayout && existingLayout.entityCount > 0) {
1410
+ existingLayout.isLoaded = true;
1411
+ return;
1412
+ }
1413
+ // Ensure layout exists in scene. `addEmptyLayout` is idempotent, but
1414
+ // guarding the call avoids an unnecessary Map probe + log noise.
1415
+ if (!existingLayout) {
1416
+ this._scene.addEmptyLayout(layoutBtrId);
1417
+ }
911
1418
  // Collect all entities from this layout
912
1419
  var entities_1 = [];
913
1420
  var iterator = blockTableRecord.newIterator();
@@ -917,34 +1424,46 @@ var AcTrView2d = /** @class */ (function (_super) {
917
1424
  entities_1.push(entity);
918
1425
  }
919
1426
  }
920
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1427
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
921
1428
  finally {
922
1429
  try {
923
1430
  if (iterator_1_1 && !iterator_1_1.done && (_a = iterator_1.return)) _a.call(iterator_1);
924
1431
  }
925
- finally { if (e_1) throw e_1.error; }
1432
+ finally { if (e_3) throw e_3.error; }
926
1433
  }
927
- // Ensure layout exists in scene
928
- this._scene.addEmptyLayout(layoutBtrId);
929
- if (entities_1.length > 0) {
930
- // Load entities asynchronously
931
- this._numOfEntitiesToProcess += entities_1.length;
932
- setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
933
- var layout;
934
- return __generator(this, function (_a) {
935
- switch (_a.label) {
936
- case 0: return [4 /*yield*/, this.batchConvert(entities_1)];
937
- case 1:
938
- _a.sent();
939
- layout = this._scene.layouts.get(layoutBtrId);
940
- if (layout) {
941
- layout.isLoaded = true;
942
- }
943
- return [2 /*return*/];
944
- }
945
- });
946
- }); });
1434
+ if (entities_1.length === 0) {
1435
+ // Empty layout (e.g. a freshly-created paper space tab). Mark as
1436
+ // loaded immediately so subsequent visits short-circuit.
1437
+ var layout = this._scene.layouts.get(layoutBtrId);
1438
+ if (layout) {
1439
+ layout.isLoaded = true;
1440
+ }
1441
+ return;
947
1442
  }
1443
+ // Load entities asynchronously
1444
+ this._loadingLayouts.add(layoutBtrId);
1445
+ this._numOfEntitiesToProcess += entities_1.length;
1446
+ setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
1447
+ var layout;
1448
+ return __generator(this, function (_a) {
1449
+ switch (_a.label) {
1450
+ case 0:
1451
+ _a.trys.push([0, , 2, 3]);
1452
+ return [4 /*yield*/, this.batchConvert(entities_1)];
1453
+ case 1:
1454
+ _a.sent();
1455
+ layout = this._scene.layouts.get(layoutBtrId);
1456
+ if (layout) {
1457
+ layout.isLoaded = true;
1458
+ }
1459
+ return [3 /*break*/, 3];
1460
+ case 2:
1461
+ this._loadingLayouts.delete(layoutBtrId);
1462
+ return [7 /*endfinally*/];
1463
+ case 3: return [2 /*return*/];
1464
+ }
1465
+ });
1466
+ }); });
948
1467
  }
949
1468
  catch (error) {
950
1469
  log.error('[AcTrView2d] Error loading layout entities:', error);
@@ -966,6 +1485,48 @@ var AcTrView2d = /** @class */ (function (_super) {
966
1485
  AcTrView2d.prototype.drawEntity = function (entity, delay) {
967
1486
  return entity.worldDraw(this._renderer, delay);
968
1487
  };
1488
+ /**
1489
+ * Walks the given block table record once and creates one
1490
+ * `AcTrViewportView` for every real `AcDbViewport` entity it finds
1491
+ * (skipping the default paper-space viewport that is filtered
1492
+ * everywhere else by `AcTrViewportView.isDefaultPaperSpaceViewport`).
1493
+ *
1494
+ * This is the recovery pass for paper-space layouts whose viewport
1495
+ * entities reached `batchConvert` before the `AcTrLayoutView` was
1496
+ * created — those entities were drawn and added to the scene, but
1497
+ * the viewport-view creation step silently no-oped (lookup returned
1498
+ * undefined). Without this recovery, `viewportsBoundingBox` stays
1499
+ * `undefined` on first user visit, the initial-zoom strategy
1500
+ * degrades to the bogus `limits` branch, and the layout renders as
1501
+ * a "grain in the corner" with empty viewport scissors. See the
1502
+ * call site in `loadLayoutEntitiesIfNeeded` for the full context.
1503
+ *
1504
+ * Cheap operation: only AcDbViewport entities are inspected; for a
1505
+ * typical sheet that's a handful of entities even on 5000-entity
1506
+ * paper layouts.
1507
+ */
1508
+ AcTrView2d.prototype.ensureViewportViews = function (blockTableRecord, layoutView) {
1509
+ var e_4, _a;
1510
+ var iterator = blockTableRecord.newIterator();
1511
+ try {
1512
+ for (var iterator_2 = __values(iterator), iterator_2_1 = iterator_2.next(); !iterator_2_1.done; iterator_2_1 = iterator_2.next()) {
1513
+ var entity = iterator_2_1.value;
1514
+ if (!(entity instanceof AcDbViewport))
1515
+ continue;
1516
+ if (AcTrViewportView.isDefaultPaperSpaceViewport(entity))
1517
+ continue;
1518
+ var viewportView = new AcTrViewportView(layoutView, entity.toGiViewport(), this._renderer);
1519
+ layoutView.addViewport(viewportView);
1520
+ }
1521
+ }
1522
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
1523
+ finally {
1524
+ try {
1525
+ if (iterator_2_1 && !iterator_2_1.done && (_a = iterator_2.return)) _a.call(iterator_2);
1526
+ }
1527
+ finally { if (e_4) throw e_4.error; }
1528
+ }
1529
+ };
969
1530
  /**
970
1531
  * Converts the specified database entities to three entities
971
1532
  * @param entities - The database entities
@@ -973,89 +1534,98 @@ var AcTrView2d = /** @class */ (function (_super) {
973
1534
  */
974
1535
  AcTrView2d.prototype.batchConvert = function (entities) {
975
1536
  return __awaiter(this, void 0, void 0, function () {
976
- var _loop_1, this_1, i;
977
- var _this = this;
1537
+ var i, entity, threeEntity, isExtendBbox, layoutView, viewportView, fileName, error_1;
978
1538
  return __generator(this, function (_a) {
979
1539
  switch (_a.label) {
980
1540
  case 0:
981
- _loop_1 = function (i) {
982
- var entity, threeEntity, isExtendBbox_1, layoutView, viewportView, fileName;
983
- return __generator(this, function (_b) {
984
- switch (_b.label) {
985
- case 0:
986
- entity = entities[i];
987
- threeEntity = this_1.drawEntity(entity, true);
988
- if (!threeEntity) return [3 /*break*/, 4];
989
- threeEntity.objectId = entity.objectId;
990
- threeEntity.ownerId = entity.ownerId;
991
- threeEntity.layerName = entity.layer;
992
- threeEntity.visible = entity.visibility;
993
- if (!(threeEntity instanceof AcTrGroup &&
994
- !threeEntity.isOnTheSameLayer)) return [3 /*break*/, 1];
995
- this_1.handleGroup(threeEntity);
996
- this_1.decreaseNumOfEntitiesToProcess();
997
- return [3 /*break*/, 3];
998
- case 1:
999
- isExtendBbox_1 = !(entity instanceof AcDbRay || entity instanceof AcDbXline);
1000
- return [4 /*yield*/, threeEntity
1001
- .draw()
1002
- .then(function () {
1003
- _this._scene.addEntity(threeEntity, isExtendBbox_1);
1004
- // Release memory occupied by this entity
1005
- threeEntity.dispose();
1006
- _this._isDirty = true;
1007
- })
1008
- .finally(function () {
1009
- _this.decreaseNumOfEntitiesToProcess();
1010
- })];
1011
- case 2:
1012
- _b.sent();
1013
- _b.label = 3;
1014
- case 3:
1015
- if (entity instanceof AcDbViewport) {
1016
- // In paper space layouts, there is always a system-defined "default" viewport that exists as
1017
- // the bottom-most item. This viewport doesn't show any entities and is mainly for internal
1018
- // AutoCAD purposes. The viewport id number of this system-defined "default" viewport is 1.
1019
- if (entity.number !== 1) {
1020
- layoutView = this_1._layoutViewManager.getAt(entity.ownerId);
1021
- if (layoutView) {
1022
- viewportView = new AcTrViewportView(layoutView, entity.toGiViewport(), this_1._renderer);
1023
- layoutView.addViewport(viewportView);
1024
- }
1025
- }
1026
- }
1027
- else if (entity instanceof AcDbRasterImage) {
1028
- fileName = entity.imageFileName;
1029
- if (fileName)
1030
- this_1._missedImages.set(entity.objectId, fileName);
1031
- }
1032
- return [3 /*break*/, 5];
1033
- case 4:
1034
- this_1.decreaseNumOfEntitiesToProcess();
1035
- _b.label = 5;
1036
- case 5: return [2 /*return*/];
1037
- }
1038
- });
1039
- };
1040
- this_1 = this;
1041
1541
  i = 0;
1042
1542
  _a.label = 1;
1043
1543
  case 1:
1044
- if (!(i < entities.length)) return [3 /*break*/, 4];
1045
- return [5 /*yield**/, _loop_1(i)];
1544
+ if (!(i < entities.length)) return [3 /*break*/, 9];
1545
+ entity = entities[i];
1546
+ _a.label = 2;
1046
1547
  case 2:
1047
- _a.sent();
1048
- _a.label = 3;
1548
+ _a.trys.push([2, 6, 7, 8]);
1549
+ // Skip the default paper-space viewport (`*Paper_Space`) entirely:
1550
+ // it is an AutoCAD-internal viewport that exists in every paper
1551
+ // layout and must not be drawn (would render a giant rectangle in
1552
+ // the paper coordinate system), nor added to the spatial index
1553
+ // (would stretch the layout's bounding box and break
1554
+ // zoomToFitDrawing), nor turned into an AcTrViewportView (would
1555
+ // setScissor over most of the canvas and squeeze the real user
1556
+ // viewports into a corner). See
1557
+ // `AcTrViewportView.isDefaultPaperSpaceViewport` for the criterion
1558
+ // and the rationale (legacy `number === 1` is unreliable across
1559
+ // parsers).
1560
+ if (entity instanceof AcDbViewport &&
1561
+ AcTrViewportView.isDefaultPaperSpaceViewport(entity)) {
1562
+ return [3 /*break*/, 8];
1563
+ }
1564
+ threeEntity = this.drawEntity(entity, true);
1565
+ if (!threeEntity)
1566
+ return [3 /*break*/, 8];
1567
+ threeEntity.objectId = entity.objectId;
1568
+ threeEntity.ownerId = entity.ownerId;
1569
+ threeEntity.layerName = entity.layer;
1570
+ threeEntity.visible = entity.visibility;
1571
+ if (threeEntity instanceof AcTrGroup &&
1572
+ threeEntity.isOnTheSameLayer) {
1573
+ // Even when a block expands to a single layer bucket, children authored on
1574
+ // layer "0" still inherit the INSERT layer for ByLayer traits (color, etc.).
1575
+ this.remapInheritedLayerObjects(threeEntity.children, '0', threeEntity.layerName);
1576
+ }
1577
+ if (!(threeEntity instanceof AcTrGroup &&
1578
+ !threeEntity.isOnTheSameLayer)) return [3 /*break*/, 3];
1579
+ this.handleGroup(threeEntity);
1580
+ return [3 /*break*/, 5];
1049
1581
  case 3:
1582
+ isExtendBbox = !(entity instanceof AcDbRay || entity instanceof AcDbXline);
1583
+ return [4 /*yield*/, threeEntity.draw()];
1584
+ case 4:
1585
+ _a.sent();
1586
+ this._scene.addEntity(threeEntity, isExtendBbox);
1587
+ // Release memory occupied by this entity
1588
+ threeEntity.dispose();
1589
+ this._isDirty = true;
1590
+ _a.label = 5;
1591
+ case 5:
1592
+ if (entity instanceof AcDbViewport) {
1593
+ // Default paper-space viewport was already filtered out at the
1594
+ // top of the loop, so anything that reaches here is a real
1595
+ // user-created viewport. The redundant check below is kept as
1596
+ // a defensive guard in case a future refactor reorders the
1597
+ // early-skip — it costs ~nothing and prevents a regression.
1598
+ if (!AcTrViewportView.isDefaultPaperSpaceViewport(entity)) {
1599
+ layoutView = this._layoutViewManager.getAt(entity.ownerId);
1600
+ if (layoutView) {
1601
+ viewportView = new AcTrViewportView(layoutView, entity.toGiViewport(), this._renderer);
1602
+ layoutView.addViewport(viewportView);
1603
+ }
1604
+ }
1605
+ }
1606
+ else if (entity instanceof AcDbRasterImage) {
1607
+ fileName = entity.imageFileName;
1608
+ if (fileName)
1609
+ this._missedImages.set(entity.objectId, fileName);
1610
+ }
1611
+ return [3 /*break*/, 8];
1612
+ case 6:
1613
+ error_1 = _a.sent();
1614
+ log.error("[AcTrView2d] Failed to convert entity ".concat(entity.objectId, " (").concat(entity.type, "):"), error_1);
1615
+ return [3 /*break*/, 8];
1616
+ case 7:
1617
+ this.decreaseNumOfEntitiesToProcess();
1618
+ return [7 /*endfinally*/];
1619
+ case 8:
1050
1620
  ++i;
1051
1621
  return [3 /*break*/, 1];
1052
- case 4: return [2 /*return*/];
1622
+ case 9: return [2 /*return*/];
1053
1623
  }
1054
1624
  });
1055
1625
  });
1056
1626
  };
1057
1627
  AcTrView2d.prototype.handleGroup = function (group) {
1058
- var e_2, _a;
1628
+ var e_5, _a;
1059
1629
  var _this = this;
1060
1630
  var children = group.children;
1061
1631
  var objectsGroupByLayer = new Map();
@@ -1083,32 +1653,40 @@ var AcTrView2d = /** @class */ (function (_super) {
1083
1653
  child.parent = null;
1084
1654
  }
1085
1655
  }
1086
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
1656
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
1087
1657
  finally {
1088
1658
  try {
1089
1659
  if (children_1_1 && !children_1_1.done && (_a = children_1.return)) _a.call(children_1);
1090
1660
  }
1091
- finally { if (e_2) throw e_2.error; }
1661
+ finally { if (e_5) throw e_5.error; }
1092
1662
  }
1093
1663
  var styleManager = group.styleManager;
1094
1664
  var groupObjectId = group.objectId;
1095
1665
  var groupLayerName = group.layerName;
1096
1666
  var groupBox = group.box;
1667
+ var groupChildBoxes = group.boxes.map(function (box) { return (__assign({}, box)); });
1097
1668
  objectsGroupByLayer.forEach(function (objects, layerName) {
1098
- // In AutoCAD, an INSERT entity may reference multiple child entities that
1099
- // reside on different layers. During rendering, this engine groups entities
1100
- // by layer and assigns each group the INSERT entity's object ID.
1101
- // As a result, a single object ID (typically from an INSERT entity) may
1102
- // correspond to multiple layers. However, in this layer its object id is still
1103
- // uniqiue.
1669
+ // AutoCAD block rule: entities authored on layer "0" inherit the INSERT's layer.
1670
+ // Non-zero layers keep their original layer name.
1671
+ var effectiveLayerName = layerName === '0' ? groupLayerName : layerName;
1672
+ // Keep runtime layer metadata/material cache aligned with the inherited layer so
1673
+ // later layer style edits (color, linetype, lineweight, transparency) target this
1674
+ // object set correctly.
1675
+ _this.remapInheritedLayerObjects(objects, layerName, effectiveLayerName);
1676
+ // One INSERT can expand to children from multiple layers. Here we create one
1677
+ // render entity per layer bucket but preserve the INSERT object id for all
1678
+ // buckets, so selection/highlight still maps back to the same database object.
1679
+ // Within each layer bucket, the object id remains unique in scene indexing.
1104
1680
  var entity = new AcTrEntity(styleManager);
1105
1681
  entity.applyMatrix4(group.matrix);
1106
1682
  entity.objectId = groupObjectId;
1107
1683
  entity.ownerId = group.ownerId;
1108
- // Here one group represents one block reference. If the layer name of entities in block
1109
- // definition is '0', it should be put on layer where the group exist.
1110
- entity.layerName = layerName === '0' ? groupLayerName : layerName;
1684
+ // If block-definition entities are on layer "0", this bucket now uses the layer
1685
+ // of the block reference itself (effectiveLayerName).
1686
+ entity.layerName = effectiveLayerName;
1111
1687
  entity.box = groupBox;
1688
+ var entityUserData = entity.userData;
1689
+ entityUserData.spatialIndexChildBoxes = groupChildBoxes;
1112
1690
  // Important:
1113
1691
  // DO NOT USE spread operator when adding objects because it may be one very large array
1114
1692
  // and can result in maximum call stack size exceeded
@@ -1121,6 +1699,86 @@ var AcTrView2d = /** @class */ (function (_super) {
1121
1699
  group.dispose();
1122
1700
  this._isDirty = true;
1123
1701
  };
1702
+ /**
1703
+ * Remaps layer metadata/material bindings from a source layer to the effective render layer.
1704
+ *
1705
+ * During block decomposition, one INSERT may be split into multiple layer buckets. For
1706
+ * children authored on layer "0", AutoCAD requires inheriting the INSERT's own layer.
1707
+ * This method applies that inheritance by mutating each child's `userData.layerName` and
1708
+ * re-binding materials via renderer cache, so subsequent layer-level style changes still
1709
+ * hit the correct material instances.
1710
+ *
1711
+ * @param objects - Root objects in the current layer bucket to traverse and remap.
1712
+ * @param sourceLayerName - Layer name found in block definition before inheritance.
1713
+ * @param effectiveLayerName - Final layer name used by rendering and style updates.
1714
+ */
1715
+ AcTrView2d.prototype.remapInheritedLayerObjects = function (objects, sourceLayerName, effectiveLayerName) {
1716
+ var e_6, _a;
1717
+ var _this = this;
1718
+ if (sourceLayerName === effectiveLayerName)
1719
+ return;
1720
+ var renderer = this._renderer;
1721
+ var layerTraits = this.getEffectiveLayerTraits(effectiveLayerName);
1722
+ try {
1723
+ for (var objects_1 = __values(objects), objects_1_1 = objects_1.next(); !objects_1_1.done; objects_1_1 = objects_1.next()) {
1724
+ var object = objects_1_1.value;
1725
+ object.traverse(function (child) {
1726
+ if (child.userData.layerName === sourceLayerName) {
1727
+ child.userData.layerName = effectiveLayerName;
1728
+ }
1729
+ if (!('material' in child))
1730
+ return;
1731
+ var material = child.material;
1732
+ if (Array.isArray(material)) {
1733
+ var materials = material;
1734
+ child.material = materials.map(function (entry) {
1735
+ return renderer.getLayerBoundMaterial(_this.promoteLayerZeroByLayerColor(entry, sourceLayerName), effectiveLayerName, layerTraits);
1736
+ });
1737
+ return;
1738
+ }
1739
+ var remappedMaterial = renderer.getLayerBoundMaterial(_this.promoteLayerZeroByLayerColor(material, sourceLayerName), effectiveLayerName, layerTraits);
1740
+ child.material = remappedMaterial;
1741
+ child.userData.styleMaterialId = remappedMaterial.id;
1742
+ });
1743
+ }
1744
+ }
1745
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
1746
+ finally {
1747
+ try {
1748
+ if (objects_1_1 && !objects_1_1.done && (_a = objects_1.return)) _a.call(objects_1);
1749
+ }
1750
+ finally { if (e_6) throw e_6.error; }
1751
+ }
1752
+ };
1753
+ /**
1754
+ * Some DXF conversion paths lose `isByLayerColor` on layer-0 block contents while still
1755
+ * retaining other ByLayer markers (lineType/lineWeight/transparency). For AutoCAD-compatible
1756
+ * INSERT inheritance, treat such colors as inheritable when remapping from layer "0".
1757
+ */
1758
+ AcTrView2d.prototype.promoteLayerZeroByLayerColor = function (material, sourceLayerName) {
1759
+ var metadata = getMaterialMetadata(material);
1760
+ var hasAnyOtherByLayerBinding = hasByLayerBinding(metadata) && metadata.isByLayerColor !== true;
1761
+ if (sourceLayerName === '0' && hasAnyOtherByLayerBinding) {
1762
+ setMaterialMetadata(material, { isByLayerColor: true });
1763
+ }
1764
+ return material;
1765
+ };
1766
+ /**
1767
+ * Builds the resolved layer traits used when layer-0 block content inherits an INSERT layer.
1768
+ */
1769
+ AcTrView2d.prototype.getEffectiveLayerTraits = function (layerName) {
1770
+ var layer = AcApDocManager.instance.curDocument.database.tables.layerTable.getAt(layerName);
1771
+ if (!layer)
1772
+ return undefined;
1773
+ return {
1774
+ layer: layer.name,
1775
+ color: layer.color.clone(),
1776
+ rgbColor: layer.color.RGB,
1777
+ lineType: layer.lineStyle,
1778
+ lineWeight: layer.lineWeight,
1779
+ transparency: layer.transparency
1780
+ };
1781
+ };
1124
1782
  AcTrView2d.prototype.decreaseNumOfEntitiesToProcess = function () {
1125
1783
  this._numOfEntitiesToProcess--;
1126
1784
  if (this._numOfEntitiesToProcess < 0) {