@linkiez/dxf-renew 7.0.0 → 7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/.eslintrc.json +1 -16
  2. package/.github/instructions/code-patterns.instructions.md +1 -1
  3. package/.github/instructions/exdxf.instruction.md +161 -0
  4. package/.github/instructions/tdd.instructions.md +271 -0
  5. package/.yarn/install-state.gz +0 -0
  6. package/ARCHITECTURE.md +163 -0
  7. package/CHANGELOG.md +39 -0
  8. package/CONTRIBUTING.md +16 -14
  9. package/README.md +113 -16
  10. package/{PLAN.md → ROADMAP.md} +244 -102
  11. package/dist/dxf.js +2212 -454
  12. package/docs/EZDXF_REFERENCE_SITEMAP.md +55 -0
  13. package/docs/FIXTURE_VALIDATION_EZDXF.md +62 -0
  14. package/lib/Helper.cjs +6 -2
  15. package/lib/Helper.cjs.map +3 -3
  16. package/lib/Helper.js +6 -2
  17. package/lib/Helper.js.map +2 -2
  18. package/lib/denormalise.cjs +131 -91
  19. package/lib/denormalise.cjs.map +2 -2
  20. package/lib/denormalise.js +131 -91
  21. package/lib/denormalise.js.map +2 -2
  22. package/lib/dimensionToSVG.cjs +318 -53
  23. package/lib/dimensionToSVG.cjs.map +3 -3
  24. package/lib/dimensionToSVG.js +316 -52
  25. package/lib/dimensionToSVG.js.map +2 -2
  26. package/lib/entityToPolyline.cjs +95 -0
  27. package/lib/entityToPolyline.cjs.map +3 -3
  28. package/lib/entityToPolyline.js +95 -0
  29. package/lib/entityToPolyline.js.map +2 -2
  30. package/lib/handlers/entities.cjs +111 -27
  31. package/lib/handlers/entities.cjs.map +3 -3
  32. package/lib/handlers/entities.js +111 -27
  33. package/lib/handlers/entities.js.map +3 -3
  34. package/lib/handlers/entity/dgnUnderlay.cjs +106 -0
  35. package/lib/handlers/entity/dgnUnderlay.cjs.map +7 -0
  36. package/lib/handlers/entity/dgnUnderlay.js +71 -0
  37. package/lib/handlers/entity/dgnUnderlay.js.map +7 -0
  38. package/lib/handlers/entity/dimension.cjs +24 -0
  39. package/lib/handlers/entity/dimension.cjs.map +2 -2
  40. package/lib/handlers/entity/dimension.js +24 -0
  41. package/lib/handlers/entity/dimension.js.map +2 -2
  42. package/lib/handlers/entity/dwfUnderlay.cjs +106 -0
  43. package/lib/handlers/entity/dwfUnderlay.cjs.map +7 -0
  44. package/lib/handlers/entity/dwfUnderlay.js +71 -0
  45. package/lib/handlers/entity/dwfUnderlay.js.map +7 -0
  46. package/lib/handlers/entity/image.cjs +123 -0
  47. package/lib/handlers/entity/image.cjs.map +7 -0
  48. package/lib/handlers/entity/image.js +88 -0
  49. package/lib/handlers/entity/image.js.map +7 -0
  50. package/lib/handlers/entity/leader.cjs +148 -0
  51. package/lib/handlers/entity/leader.cjs.map +7 -0
  52. package/lib/handlers/entity/leader.js +113 -0
  53. package/lib/handlers/entity/leader.js.map +7 -0
  54. package/lib/handlers/entity/mleader.cjs +69 -0
  55. package/lib/handlers/entity/mleader.cjs.map +7 -0
  56. package/lib/handlers/entity/mleader.js +34 -0
  57. package/lib/handlers/entity/mleader.js.map +7 -0
  58. package/lib/handlers/entity/mline.cjs +91 -0
  59. package/lib/handlers/entity/mline.cjs.map +7 -0
  60. package/lib/handlers/entity/mline.js +56 -0
  61. package/lib/handlers/entity/mline.js.map +7 -0
  62. package/lib/handlers/entity/oleframe.cjs +98 -0
  63. package/lib/handlers/entity/oleframe.cjs.map +7 -0
  64. package/lib/handlers/entity/oleframe.js +63 -0
  65. package/lib/handlers/entity/oleframe.js.map +7 -0
  66. package/lib/handlers/entity/pdfUnderlay.cjs +106 -0
  67. package/lib/handlers/entity/pdfUnderlay.cjs.map +7 -0
  68. package/lib/handlers/entity/pdfUnderlay.js +71 -0
  69. package/lib/handlers/entity/pdfUnderlay.js.map +7 -0
  70. package/lib/handlers/entity/ray.cjs +81 -0
  71. package/lib/handlers/entity/ray.cjs.map +7 -0
  72. package/lib/handlers/entity/ray.js +46 -0
  73. package/lib/handlers/entity/ray.js.map +7 -0
  74. package/lib/handlers/entity/region.cjs +67 -0
  75. package/lib/handlers/entity/region.cjs.map +7 -0
  76. package/lib/handlers/entity/region.js +32 -0
  77. package/lib/handlers/entity/region.js.map +7 -0
  78. package/lib/handlers/entity/shape.cjs +95 -0
  79. package/lib/handlers/entity/shape.cjs.map +7 -0
  80. package/lib/handlers/entity/shape.js +60 -0
  81. package/lib/handlers/entity/shape.js.map +7 -0
  82. package/lib/handlers/entity/table.cjs +71 -0
  83. package/lib/handlers/entity/table.cjs.map +7 -0
  84. package/lib/handlers/entity/table.js +36 -0
  85. package/lib/handlers/entity/table.js.map +7 -0
  86. package/lib/handlers/entity/tolerance.cjs +90 -0
  87. package/lib/handlers/entity/tolerance.cjs.map +7 -0
  88. package/lib/handlers/entity/tolerance.js +55 -0
  89. package/lib/handlers/entity/tolerance.js.map +7 -0
  90. package/lib/handlers/entity/trace.cjs +101 -0
  91. package/lib/handlers/entity/trace.cjs.map +7 -0
  92. package/lib/handlers/entity/trace.js +66 -0
  93. package/lib/handlers/entity/trace.js.map +7 -0
  94. package/lib/handlers/entity/wipeout.cjs +122 -0
  95. package/lib/handlers/entity/wipeout.cjs.map +7 -0
  96. package/lib/handlers/entity/wipeout.js +87 -0
  97. package/lib/handlers/entity/wipeout.js.map +7 -0
  98. package/lib/handlers/entity/xline.cjs +81 -0
  99. package/lib/handlers/entity/xline.cjs.map +7 -0
  100. package/lib/handlers/entity/xline.js +46 -0
  101. package/lib/handlers/entity/xline.js.map +7 -0
  102. package/lib/handlers/objects.cjs +299 -136
  103. package/lib/handlers/objects.cjs.map +2 -2
  104. package/lib/handlers/objects.js +299 -136
  105. package/lib/handlers/objects.js.map +2 -2
  106. package/lib/handlers/tables.cjs +96 -17
  107. package/lib/handlers/tables.cjs.map +2 -2
  108. package/lib/handlers/tables.js +96 -17
  109. package/lib/handlers/tables.js.map +2 -2
  110. package/lib/index.cjs +5 -2
  111. package/lib/index.cjs.map +3 -3
  112. package/lib/index.js +18 -16
  113. package/lib/index.js.map +3 -3
  114. package/lib/toJson.cjs +29 -0
  115. package/lib/toJson.cjs.map +7 -0
  116. package/lib/toJson.js +9 -0
  117. package/lib/toJson.js.map +7 -0
  118. package/lib/toSVG.cjs +105 -11
  119. package/lib/toSVG.cjs.map +3 -3
  120. package/lib/toSVG.js +106 -12
  121. package/lib/toSVG.js.map +2 -2
  122. package/lib/types/dimension-entity.cjs.map +1 -1
  123. package/lib/types/entity.cjs.map +1 -1
  124. package/lib/types/helper.cjs.map +1 -1
  125. package/lib/types/image-entity.cjs +17 -0
  126. package/lib/types/image-entity.cjs.map +7 -0
  127. package/lib/types/image-entity.js +1 -0
  128. package/lib/types/image-entity.js.map +7 -0
  129. package/lib/types/index.cjs +28 -0
  130. package/lib/types/index.cjs.map +2 -2
  131. package/lib/types/index.js +14 -0
  132. package/lib/types/index.js.map +2 -2
  133. package/lib/types/leader-entity.cjs +17 -0
  134. package/lib/types/leader-entity.cjs.map +7 -0
  135. package/lib/types/leader-entity.js +1 -0
  136. package/lib/types/leader-entity.js.map +7 -0
  137. package/lib/types/mleader-entity.cjs +17 -0
  138. package/lib/types/mleader-entity.cjs.map +7 -0
  139. package/lib/types/mleader-entity.js +1 -0
  140. package/lib/types/mleader-entity.js.map +7 -0
  141. package/lib/types/mline-entity.cjs +17 -0
  142. package/lib/types/mline-entity.cjs.map +7 -0
  143. package/lib/types/mline-entity.js +1 -0
  144. package/lib/types/mline-entity.js.map +7 -0
  145. package/lib/types/oleframe-entity.cjs +17 -0
  146. package/lib/types/oleframe-entity.cjs.map +7 -0
  147. package/lib/types/oleframe-entity.js +1 -0
  148. package/lib/types/oleframe-entity.js.map +7 -0
  149. package/lib/types/options.cjs.map +1 -1
  150. package/lib/types/ray-entity.cjs +17 -0
  151. package/lib/types/ray-entity.cjs.map +7 -0
  152. package/lib/types/ray-entity.js +1 -0
  153. package/lib/types/ray-entity.js.map +7 -0
  154. package/lib/types/region-entity.cjs +17 -0
  155. package/lib/types/region-entity.cjs.map +7 -0
  156. package/lib/types/region-entity.js +1 -0
  157. package/lib/types/region-entity.js.map +7 -0
  158. package/lib/types/shape-entity.cjs +17 -0
  159. package/lib/types/shape-entity.cjs.map +7 -0
  160. package/lib/types/shape-entity.js +1 -0
  161. package/lib/types/shape-entity.js.map +7 -0
  162. package/lib/types/table-entity.cjs +17 -0
  163. package/lib/types/table-entity.cjs.map +7 -0
  164. package/lib/types/table-entity.js +1 -0
  165. package/lib/types/table-entity.js.map +7 -0
  166. package/lib/types/tables.cjs.map +1 -1
  167. package/lib/types/tolerance-entity.cjs +17 -0
  168. package/lib/types/tolerance-entity.cjs.map +7 -0
  169. package/lib/types/tolerance-entity.js +1 -0
  170. package/lib/types/tolerance-entity.js.map +7 -0
  171. package/lib/types/trace-entity.cjs +17 -0
  172. package/lib/types/trace-entity.cjs.map +7 -0
  173. package/lib/types/trace-entity.js +1 -0
  174. package/lib/types/trace-entity.js.map +7 -0
  175. package/lib/types/underlay-entity.cjs +17 -0
  176. package/lib/types/underlay-entity.cjs.map +7 -0
  177. package/lib/types/underlay-entity.js +1 -0
  178. package/lib/types/underlay-entity.js.map +7 -0
  179. package/lib/types/wipeout-entity.cjs +17 -0
  180. package/lib/types/wipeout-entity.cjs.map +7 -0
  181. package/lib/types/wipeout-entity.js +1 -0
  182. package/lib/types/wipeout-entity.js.map +7 -0
  183. package/lib/types/xline-entity.cjs +17 -0
  184. package/lib/types/xline-entity.cjs.map +7 -0
  185. package/lib/types/xline-entity.js +1 -0
  186. package/lib/types/xline-entity.js.map +7 -0
  187. package/lib/util/escapeXmlText.cjs +27 -0
  188. package/lib/util/escapeXmlText.cjs.map +7 -0
  189. package/lib/util/escapeXmlText.js +7 -0
  190. package/lib/util/escapeXmlText.js.map +7 -0
  191. package/package.json +9 -18
  192. package/playwright.config.cjs +20 -0
  193. package/src/Helper.ts +8 -3
  194. package/src/denormalise.ts +182 -116
  195. package/src/dimensionToSVG.ts +466 -54
  196. package/src/entityToPolyline.ts +124 -2
  197. package/src/handlers/entities.ts +129 -34
  198. package/src/handlers/entity/dgnUnderlay.ts +94 -0
  199. package/src/handlers/entity/dimension.ts +27 -1
  200. package/src/handlers/entity/dwfUnderlay.ts +94 -0
  201. package/src/handlers/entity/image.ts +118 -0
  202. package/src/handlers/entity/leader.ts +153 -0
  203. package/src/handlers/entity/mleader.ts +46 -0
  204. package/src/handlers/entity/mline.ts +74 -0
  205. package/src/handlers/entity/oleframe.ts +62 -0
  206. package/src/handlers/entity/pdfUnderlay.ts +94 -0
  207. package/src/handlers/entity/ray.ts +52 -0
  208. package/src/handlers/entity/region.ts +42 -0
  209. package/src/handlers/entity/shape.ts +73 -0
  210. package/src/handlers/entity/table.ts +49 -0
  211. package/src/handlers/entity/tolerance.ts +75 -0
  212. package/src/handlers/entity/trace.ts +72 -0
  213. package/src/handlers/entity/wipeout.ts +114 -0
  214. package/src/handlers/entity/xline.ts +52 -0
  215. package/src/handlers/objects.ts +379 -139
  216. package/src/handlers/tables.ts +134 -21
  217. package/src/index.ts +9 -18
  218. package/src/toJson.ts +8 -0
  219. package/src/toSVG.ts +143 -10
  220. package/src/types/dimension-entity.ts +11 -0
  221. package/src/types/entity.ts +30 -0
  222. package/src/types/helper.ts +2 -1
  223. package/src/types/image-entity.ts +35 -0
  224. package/src/types/index.ts +14 -0
  225. package/src/types/leader-entity.ts +40 -0
  226. package/src/types/mleader-entity.ts +8 -0
  227. package/src/types/mline-entity.ts +12 -0
  228. package/src/types/oleframe-entity.ts +40 -0
  229. package/src/types/options.ts +48 -0
  230. package/src/types/ray-entity.ts +12 -0
  231. package/src/types/region-entity.ts +11 -0
  232. package/src/types/shape-entity.ts +19 -0
  233. package/src/types/table-entity.ts +14 -0
  234. package/src/types/tables.ts +160 -0
  235. package/src/types/tolerance-entity.ts +20 -0
  236. package/src/types/trace-entity.ts +14 -0
  237. package/src/types/underlay-entity.ts +35 -0
  238. package/src/types/wipeout-entity.ts +20 -0
  239. package/src/types/xline-entity.ts +12 -0
  240. package/src/util/escapeXmlText.ts +10 -0
  241. package/tools/browser_test_server.cjs +87 -0
  242. package/tools/ezdxf_generate_dimensions_all_types.py +246 -0
  243. package/tools/ezdxf_generate_dimensions_angular_3p.py +59 -0
  244. package/tools/ezdxf_generate_dimensions_large_scale.py +87 -0
  245. package/tools/ezdxf_regenerate_problem_fixtures.py +184 -0
  246. package/tools/ezdxf_validate_fixtures.py +165 -0
  247. package/docs/DIMENSION_SUMMARY.md +0 -248
  248. package/docs/DIMENSION_SUMMARY.pt-BR.md +0 -248
  249. package/docs/IMPLEMENTED-2D-ENTITIES.md +0 -54
  250. package/docs/IMPLEMENTED-2D-ENTITIES.pt-BR.md +0 -54
  251. package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.md +0 -241
  252. package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.pt-BR.md +0 -169
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/dimensionToSVG.ts"],
4
- "sourcesContent": ["import { Box2 } from 'vecks'\n\nimport colors from './util/colors'\n\nimport type { DimensionEntity } from './types'\nimport type { DimStyleTable } from './types/dxf'\nimport type { BoundsAndElement } from './types/svg'\n\n/**\n * Convert DXF color number to SVG color string\n */\nfunction colorNumberToSVG(colorNumber?: number): string {\n if (colorNumber === undefined || colorNumber < 0) {\n return 'currentColor'\n }\n\n // DXF color 0 is ByBlock, 256 is ByLayer, 7 is white/black (depends on bg)\n if (colorNumber === 0 || colorNumber === 256) {\n return 'currentColor'\n }\n\n // Get RGB from color table\n const rgb = colors[colorNumber]\n if (!rgb) {\n return 'currentColor'\n }\n\n return `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`\n}\n\n/**\n * Get dimension colors and weights from DIMSTYLE with defaults\n */\nfunction getDimensionColors(dimStyle?: DimStyleTable): {\n dimLineColor: string\n extLineColor: string\n textColor: string\n dimLineWeight: number\n extLineWeight: number\n} {\n return {\n dimLineColor: colorNumberToSVG(dimStyle?.dimClrd),\n extLineColor: colorNumberToSVG(dimStyle?.dimClre),\n textColor: colorNumberToSVG(dimStyle?.dimClrt),\n dimLineWeight: dimStyle?.dimLwd ?? 0.5,\n extLineWeight: dimStyle?.dimLwe ?? 0.5,\n }\n}\n\n/**\n * Render DIMENSION entity to SVG with proper DIMSTYLE support\n */\nexport default function dimensionToSVG(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n): BoundsAndElement {\n // Dispatch to appropriate renderer based on dimension type\n switch (entity.dimensionType) {\n case 0: // Rotated, horizontal, or vertical\n case 1: // Aligned\n return renderLinearDimension(entity, dimStyle)\n case 2: // Angular\n return renderAngularDimension(entity, dimStyle)\n case 3: // Diameter\n return renderDiameterDimension(entity, dimStyle)\n case 4: // Radius\n return renderRadialDimension(entity, dimStyle)\n case 6: // Ordinate\n return renderOrdinateDimension(entity, dimStyle)\n default:\n // Fallback to simple line rendering\n return renderFallbackDimension(entity)\n }\n}\n\n/**\n * Create SVG marker definition for dimension arrows\n */\nexport function createArrowMarker(\n id: string,\n size: number,\n color: string,\n): string {\n const arrowPath = `M 0 0 L ${size} ${size / 2} L 0 ${size} z`\n return `<marker id=\"${id}\" markerWidth=\"${size}\" markerHeight=\"${size}\" refX=\"${size}\" refY=\"${size / 2}\" orient=\"auto\" markerUnits=\"strokeWidth\">\n <path d=\"${arrowPath}\" fill=\"${color}\" />\n </marker>`\n}\n\n/**\n * Render linear dimension (rotated, horizontal, vertical, or aligned)\n */\nfunction renderLinearDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n const markers: string[] = []\n\n // Get dimension style properties with defaults\n const arrowSize = dimStyle?.dimAsz ?? 2.5\n const textHeight = dimStyle?.dimTxt ?? 2.5\n const extLineOffset = dimStyle?.dimExo ?? 0.625\n const extLineExtension = dimStyle?.dimExe ?? 1.25\n const { dimLineColor, extLineColor, textColor, dimLineWeight, extLineWeight } = getDimensionColors(dimStyle)\n\n // Extract dimension geometry\n const defPoint1X = entity.measureStart?.x ?? 0\n const defPoint1Y = entity.measureStart?.y ?? 0\n const defPoint2X = entity.measureEnd?.x ?? 0\n const defPoint2Y = entity.measureEnd?.y ?? 0\n const dimLineY = entity.start?.y ?? 0\n const textX = entity.textMidpoint?.x ?? (defPoint1X + defPoint2X) / 2\n const textY = entity.textMidpoint?.y ?? (defPoint1Y + defPoint2Y) / 2\n\n // Calculate dimension line angle\n const angle = Math.atan2(defPoint2Y - defPoint1Y, defPoint2X - defPoint1X)\n const perpAngle = angle + Math.PI / 2\n\n // Calculate dimension line endpoints\n const dimLine1X = defPoint1X + Math.cos(perpAngle) * (dimLineY - defPoint1Y)\n const dimLine1Y = defPoint1Y + Math.sin(perpAngle) * (dimLineY - defPoint1Y)\n const dimLine2X = defPoint2X + Math.cos(perpAngle) * (dimLineY - defPoint2Y)\n const dimLine2Y = defPoint2Y + Math.sin(perpAngle) * (dimLineY - defPoint2Y)\n\n // Expand bounding box\n bbox.expandByPoint({ x: defPoint1X, y: defPoint1Y })\n bbox.expandByPoint({ x: defPoint2X, y: defPoint2Y })\n bbox.expandByPoint({ x: dimLine1X, y: dimLine1Y })\n bbox.expandByPoint({ x: dimLine2X, y: dimLine2Y })\n bbox.expandByPoint({ x: textX, y: textY })\n\n // Create unique marker IDs for arrows\n const markerId1 = `dim-arrow-start-${Date.now()}`\n const markerId2 = `dim-arrow-end-${Date.now()}`\n\n // Create arrow markers with dimension line color\n markers.push(\n createArrowMarker(markerId1, arrowSize, dimLineColor),\n createArrowMarker(markerId2, arrowSize, dimLineColor),\n )\n\n // Draw extension lines\n const extLine1StartX = defPoint1X + Math.cos(perpAngle) * extLineOffset\n const extLine1StartY = defPoint1Y + Math.sin(perpAngle) * extLineOffset\n const extLine1EndX = dimLine1X + Math.cos(perpAngle) * extLineExtension\n const extLine1EndY = dimLine1Y + Math.sin(perpAngle) * extLineExtension\n\n const extLine2StartX = defPoint2X + Math.cos(perpAngle) * extLineOffset\n const extLine2StartY = defPoint2Y + Math.sin(perpAngle) * extLineOffset\n const extLine2EndX = dimLine2X + Math.cos(perpAngle) * extLineExtension\n const extLine2EndY = dimLine2Y + Math.sin(perpAngle) * extLineExtension\n\n elements.push(\n `<line x1=\"${extLine1StartX}\" y1=\"${extLine1StartY}\" x2=\"${extLine1EndX}\" y2=\"${extLine1EndY}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n `<line x1=\"${extLine2StartX}\" y1=\"${extLine2StartY}\" x2=\"${extLine2EndX}\" y2=\"${extLine2EndY}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n `<line x1=\"${dimLine1X}\" y1=\"${dimLine1Y}\" x2=\"${dimLine2X}\" y2=\"${dimLine2Y}\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" marker-start=\"url(#${markerId1})\" marker-end=\"url(#${markerId2})\" />`,\n )\n\n // Add dimension text\n if (entity.text) {\n const textRotation = (angle * 180) / Math.PI\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${entity.text}</text>`,\n )\n }\n\n return {\n bbox,\n element: `<defs>${markers.join('')}</defs><g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Render angular dimension\n */\nfunction renderAngularDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n const markers: string[] = []\n\n // Get dimension style properties\n const arrowSize = dimStyle?.dimAsz ?? 2.5\n const textHeight = dimStyle?.dimTxt ?? 2.5\n const { dimLineColor, extLineColor, textColor, dimLineWeight, extLineWeight } = getDimensionColors(dimStyle)\n\n // Extract points\n const centerX = entity.start?.x ?? 0\n const centerY = entity.start?.y ?? 0\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.measureEnd?.x ?? 0\n const y2 = entity.measureEnd?.y ?? 0\n const textX = entity.textMidpoint?.x ?? centerX\n const textY = entity.textMidpoint?.y ?? centerY\n\n bbox.expandByPoint({ x: centerX, y: centerY })\n bbox.expandByPoint({ x: x1, y: y1 })\n bbox.expandByPoint({ x: x2, y: y2 })\n bbox.expandByPoint({ x: textX, y: textY })\n\n // Create arrow markers\n const markerId1 = `dim-angular-arrow-start-${Date.now()}`\n const markerId2 = `dim-angular-arrow-end-${Date.now()}`\n markers.push(\n createArrowMarker(markerId1, arrowSize, dimLineColor),\n createArrowMarker(markerId2, arrowSize, dimLineColor),\n )\n\n // Draw extension lines from center to definition points\n elements.push(\n `<line x1=\"${centerX}\" y1=\"${centerY}\" x2=\"${x1}\" y2=\"${y1}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n `<line x1=\"${centerX}\" y1=\"${centerY}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n )\n\n // Calculate arc radius (distance from center to text midpoint)\n const radius = Math.hypot(textX - centerX, textY - centerY)\n const startAngle = Math.atan2(y1 - centerY, x1 - centerX)\n const endAngle = Math.atan2(y2 - centerY, x2 - centerX)\n\n // Draw arc for angular dimension\n const largeArcFlag = Math.abs(endAngle - startAngle) > Math.PI ? 1 : 0\n const arcStartX = centerX + radius * Math.cos(startAngle)\n const arcStartY = centerY + radius * Math.sin(startAngle)\n const arcEndX = centerX + radius * Math.cos(endAngle)\n const arcEndY = centerY + radius * Math.sin(endAngle)\n\n elements.push(\n `<path d=\"M ${arcStartX} ${arcStartY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${arcEndX} ${arcEndY}\" fill=\"none\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" marker-start=\"url(#${markerId1})\" marker-end=\"url(#${markerId2})\" />`,\n )\n\n // Add dimension text\n if (entity.text) {\n const midAngle = (startAngle + endAngle) / 2\n const textRotation = (midAngle * 180) / Math.PI\n\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${entity.text}</text>`,\n )\n }\n\n return {\n bbox,\n element: `<defs>${markers.join('')}</defs><g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Render diameter dimension\n */\nfunction renderDiameterDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n const markers: string[] = []\n\n // Get dimension style properties\n const arrowSize = dimStyle?.dimAsz ?? 2.5\n const textHeight = dimStyle?.dimTxt ?? 2.5\n const { dimLineColor, textColor, dimLineWeight } = getDimensionColors(dimStyle)\n\n // Extract geometry\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.measureEnd?.x ?? 0\n const y2 = entity.measureEnd?.y ?? 0\n const textX = entity.textMidpoint?.x ?? (x1 + x2) / 2\n const textY = entity.textMidpoint?.y ?? (y1 + y2) / 2\n\n bbox.expandByPoint({ x: x1, y: y1 })\n bbox.expandByPoint({ x: x2, y: y2 })\n bbox.expandByPoint({ x: textX, y: textY })\n\n // Create arrow markers\n const markerId = `dim-diameter-arrow-${Date.now()}`\n markers.push(createArrowMarker(markerId, arrowSize, dimLineColor))\n\n // Create diameter line with arrow at the end\n elements.push(\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" marker-end=\"url(#${markerId})\" />`,\n )\n\n // Add dimension text with diameter symbol\n const diameterText = entity.text ? `\u2300${entity.text}` : '\u2300'\n const angle = Math.atan2(y2 - y1, x2 - x1)\n const textRotation = (angle * 180) / Math.PI\n\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${diameterText}</text>`,\n )\n\n return {\n bbox,\n element: `<defs>${markers.join('')}</defs><g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Render radial dimension\n */\nfunction renderRadialDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n const markers: string[] = []\n\n // Get dimension style properties\n const arrowSize = dimStyle?.dimAsz ?? 2.5\n const textHeight = dimStyle?.dimTxt ?? 2.5\n const { dimLineColor, textColor, dimLineWeight } = getDimensionColors(dimStyle)\n\n // Extract geometry\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.measureEnd?.x ?? 0\n const y2 = entity.measureEnd?.y ?? 0\n const textX = entity.textMidpoint?.x ?? (x1 + x2) / 2\n const textY = entity.textMidpoint?.y ?? (y1 + y2) / 2\n\n bbox.expandByPoint({ x: x1, y: y1 })\n bbox.expandByPoint({ x: x2, y: y2 })\n bbox.expandByPoint({ x: textX, y: textY })\n\n // Create arrow markers\n const markerId = `dim-radius-arrow-${Date.now()}`\n markers.push(createArrowMarker(markerId, arrowSize, dimLineColor))\n\n // Create radius line with arrow at the end\n elements.push(\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" marker-end=\"url(#${markerId})\" />`,\n )\n\n // Add dimension text with radius symbol\n const radiusText = entity.text ? `R${entity.text}` : 'R'\n const angle = Math.atan2(y2 - y1, x2 - x1)\n const textRotation = (angle * 180) / Math.PI\n\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${radiusText}</text>`,\n )\n\n return {\n bbox,\n element: `<defs>${markers.join('')}</defs><g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Render ordinate dimension\n */\nfunction renderOrdinateDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n\n // Get dimension style properties\n const textHeight = dimStyle?.dimTxt ?? 2.5\n const { dimLineColor, textColor, dimLineWeight } = getDimensionColors(dimStyle)\n\n // Extract geometry\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.start?.x ?? 0\n const y2 = entity.start?.y ?? 0\n const textX = entity.textMidpoint?.x ?? x2\n const textY = entity.textMidpoint?.y ?? y2\n\n bbox.expandByPoint({ x: x1, y: y1 })\n bbox.expandByPoint({ x: x2, y: y2 })\n bbox.expandByPoint({ x: textX, y: textY })\n\n // Create leader line (no arrow for ordinate dimensions)\n elements.push(\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" />`,\n )\n\n // Add dimension text\n if (entity.text) {\n const angle = Math.atan2(y2 - y1, x2 - x1)\n const textRotation = (angle * 180) / Math.PI\n\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${entity.text}</text>`,\n )\n }\n\n return {\n bbox,\n element: `<g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Fallback renderer for unsupported dimension types\n */\nfunction renderFallbackDimension(entity: DimensionEntity): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n\n // Just render text at midpoint\n if (entity.textMidpoint) {\n const textX = entity.textMidpoint.x ?? 0\n const textY = entity.textMidpoint.y ?? 0\n bbox.expandByPoint({ x: textX, y: textY })\n\n if (entity.text) {\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"2.5\" text-anchor=\"middle\" transform=\"scale(1,-1) translate(0 ${-2 * textY})\">${entity.text}</text>`,\n )\n }\n }\n\n return {\n bbox,\n element: `<g>${elements.join('')}</g>`,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box2 } from 'vecks'\n\nimport colors from './util/colors'\nimport escapeXmlText from './util/escapeXmlText'\nimport round10 from './util/round10'\n\nimport type { DimensionEntity, ToSVGOptions } from './types'\nimport type { DimStyleTable } from './types/dxf'\nimport type { BoundsAndElement } from './types/svg'\n\nconst DEFAULT_DIMENSION_DECIMALS = 2\n\nexport interface DimensionViewport {\n width: number\n height: number\n}\n\n// AutoScale is meant to improve readability of dimension graphics.\n// Scale is derived from the drawing viewport (final SVG viewBox size).\n// No min/max clamp by design.\nconst AUTOSCALE_VIEWPORT_REFERENCE = 40\n\nconst computeViewportAutoScaleFactor = (\n viewport: DimensionViewport,\n options: ToSVGOptions | undefined,\n): number => {\n const viewportMin = Math.min(Math.abs(viewport.width), Math.abs(viewport.height))\n if (!Number.isFinite(viewportMin) || viewportMin <= 0) return 1\n\n const reference = options?.dimension?.autoScaleViewportReference\n const safeReference = Number.isFinite(reference) && (reference ?? 0) > 0\n ? (reference as number)\n : AUTOSCALE_VIEWPORT_REFERENCE\n\n return viewportMin / safeReference\n}\n\nconst getViewportMin = (viewport: DimensionViewport): number => {\n const viewportMin = Math.min(Math.abs(viewport.width), Math.abs(viewport.height))\n return Number.isFinite(viewportMin) ? viewportMin : Number.NaN\n}\n\nconst getViewportPercentageSize = (\n viewport: DimensionViewport,\n percent: number | undefined,\n): number | undefined => {\n if (!Number.isFinite(percent) || (percent ?? 0) <= 0) return undefined\n const viewportMin = getViewportMin(viewport)\n if (!Number.isFinite(viewportMin) || viewportMin <= 0) return undefined\n return viewportMin * ((percent as number) / 100)\n}\n\nexport const getDimensionGeometryBBox = (entity: DimensionEntity): Box2 => {\n const bbox = new Box2()\n\n const points = [\n entity.start,\n entity.angleVertex,\n entity.arcPoint,\n entity.textMidpoint,\n entity.measureStart,\n entity.measureEnd,\n ]\n\n for (const p of points) {\n if (!p) continue\n const x = p.x\n const y = p.y\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue\n bbox.expandByPoint({ x, y })\n }\n\n return bbox\n}\n\nconst getScaledDimensionSizes = (\n dimStyle: DimStyleTable | undefined,\n options: ToSVGOptions | undefined,\n viewport: DimensionViewport | undefined,\n): {\n arrowSize: number\n textHeight: number\n extLineOffset: number\n extLineExtension: number\n} => {\n const autoScale = options?.dimension?.autoScale === true\n\n const baseArrowSize = dimStyle?.dimAsz ?? 2.5\n const baseTextHeight = dimStyle?.dimTxt ?? 2.5\n const baseExtLineOffset = dimStyle?.dimExo ?? 0.625\n const baseExtLineExtension = dimStyle?.dimExe ?? 1.25\n\n if (!autoScale || !viewport) {\n return {\n arrowSize: baseArrowSize,\n textHeight: baseTextHeight,\n extLineOffset: baseExtLineOffset,\n extLineExtension: baseExtLineExtension,\n }\n }\n\n const scale = computeViewportAutoScaleFactor(viewport, options)\n\n const perc = options?.dimension?.autoScaleViewportPercentages\n const arrowFromPct = getViewportPercentageSize(viewport, perc?.arrowSize)\n const textFromPct = getViewportPercentageSize(viewport, perc?.textHeight)\n const offsetFromPct = getViewportPercentageSize(viewport, perc?.extLineOffset)\n const extensionFromPct = getViewportPercentageSize(viewport, perc?.extLineExtension)\n\n return {\n arrowSize: arrowFromPct ?? (baseArrowSize * scale),\n textHeight: textFromPct ?? (baseTextHeight * scale),\n extLineOffset: offsetFromPct ?? (baseExtLineOffset * scale),\n extLineExtension: extensionFromPct ?? (baseExtLineExtension * scale),\n }\n}\n\nconst formatDimensionValue = (\n value: number,\n decimals: number = DEFAULT_DIMENSION_DECIMALS,\n): string => {\n if (!Number.isFinite(value)) return ''\n const rounded = round10(value, -decimals)\n return rounded.toFixed(decimals)\n}\n\nconst computeRadiusFallback = (entity: DimensionEntity): number => {\n const cx = entity.start?.x ?? 0\n const cy = entity.start?.y ?? 0\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.measureEnd?.x ?? 0\n const y2 = entity.measureEnd?.y ?? 0\n\n const r1 = Math.hypot(x1 - cx, y1 - cy)\n const r2 = Math.hypot(x2 - cx, y2 - cy)\n const chord = Math.hypot(x2 - x1, y2 - y1)\n return Math.max(r1, r2, chord)\n}\n\nconst computeLinearDistance = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): number => Math.hypot(x2 - x1, y2 - y1)\n\nconst computeAngularDegreesMinimal = (\n cx: number,\n cy: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): number => {\n const a1 = Math.atan2(y1 - cy, x1 - cx)\n const a2 = Math.atan2(y2 - cy, x2 - cx)\n let delta = Math.abs(a2 - a1)\n while (delta > Math.PI * 2) delta -= Math.PI * 2\n if (delta > Math.PI) delta = Math.PI * 2 - delta\n return (delta * 180) / Math.PI\n}\n\nconst computeAngularDegreesCCW = (\n cx: number,\n cy: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): number => {\n const a1 = Math.atan2(y1 - cy, x1 - cx)\n const a2 = Math.atan2(y2 - cy, x2 - cx)\n let delta = a2 - a1\n while (delta < 0) delta += Math.PI * 2\n while (delta >= Math.PI * 2) delta -= Math.PI * 2\n return (delta * 180) / Math.PI\n}\n\nconst computeDimensionMeasurement = (entity: DimensionEntity): string => {\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.measureEnd?.x ?? 0\n const y2 = entity.measureEnd?.y ?? 0\n\n switch (entity.dimensionType) {\n case 0:\n case 1:\n case 6: {\n const dist = computeLinearDistance(x1, y1, x2, y2)\n return formatDimensionValue(dist)\n }\n case 3: {\n const dist = computeLinearDistance(x1, y1, x2, y2)\n if (dist > 0) return formatDimensionValue(dist)\n const radius = computeRadiusFallback(entity)\n return formatDimensionValue(radius * 2)\n }\n case 4: {\n const dist = computeLinearDistance(x1, y1, x2, y2)\n if (dist > 0) return formatDimensionValue(dist)\n const radius = computeRadiusFallback(entity)\n return formatDimensionValue(radius)\n }\n case 2: {\n const cx = entity.start?.x ?? 0\n const cy = entity.start?.y ?? 0\n const degrees = computeAngularDegreesMinimal(cx, cy, x1, y1, x2, y2)\n const formatted = formatDimensionValue(degrees)\n return formatted ? `${formatted}\u00B0` : ''\n }\n case 5: {\n const cx = entity.angleVertex?.x ?? 0\n const cy = entity.angleVertex?.y ?? 0\n const degrees = computeAngularDegreesCCW(cx, cy, x1, y1, x2, y2)\n const formatted = formatDimensionValue(degrees)\n return formatted ? `${formatted}\u00B0` : ''\n }\n default:\n return ''\n }\n}\n\nconst resolveDimensionText = (entity: DimensionEntity): string => {\n const raw = typeof entity.text === 'string' ? entity.text : ''\n const trimmed = raw.trim()\n const measured = computeDimensionMeasurement(entity)\n\n if (!trimmed) return measured\n if (trimmed.includes('<>')) {\n return trimmed.split('<>').join(measured)\n }\n return trimmed\n}\n\nconst expandBBoxForMarker = (bbox: Box2, x: number, y: number, size: number) => {\n bbox.expandByPoint({ x: x - size, y: y - size })\n bbox.expandByPoint({ x: x + size, y: y + size })\n}\n\nconst expandBBoxForText = (\n bbox: Box2,\n x: number,\n y: number,\n height: number,\n content: string,\n) => {\n const textWidth = content.length * height * 0.6\n // text-anchor=\"middle\" is used everywhere in DIMENSION rendering\n bbox.expandByPoint({ x: x - textWidth / 2, y: y - height })\n bbox.expandByPoint({ x: x + textWidth / 2, y: y + height })\n}\n\n/**\n * Convert DXF color number to SVG color string\n */\nfunction colorNumberToSVG(colorNumber?: number): string {\n if (colorNumber === undefined || colorNumber < 0) {\n return 'currentColor'\n }\n\n // DXF color 0 is ByBlock, 256 is ByLayer, 7 is white/black (depends on bg)\n if (colorNumber === 0 || colorNumber === 256) {\n return 'currentColor'\n }\n\n // Get RGB from color table\n const rgb = colors[colorNumber]\n if (!rgb) {\n return 'currentColor'\n }\n\n return `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`\n}\n\n/**\n * Get dimension colors and weights from DIMSTYLE with defaults\n */\nfunction getDimensionColors(dimStyle?: DimStyleTable): {\n dimLineColor: string\n extLineColor: string\n textColor: string\n dimLineWeight: number\n extLineWeight: number\n} {\n return {\n dimLineColor: colorNumberToSVG(dimStyle?.dimClrd),\n extLineColor: colorNumberToSVG(dimStyle?.dimClre),\n textColor: colorNumberToSVG(dimStyle?.dimClrt),\n dimLineWeight: dimStyle?.dimLwd ?? 0.5,\n extLineWeight: dimStyle?.dimLwe ?? 0.5,\n }\n}\n\n/**\n * Render DIMENSION entity to SVG with proper DIMSTYLE support\n */\nexport default function dimensionToSVG(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n options?: ToSVGOptions,\n viewport?: DimensionViewport,\n): BoundsAndElement {\n // Dispatch to appropriate renderer based on dimension type\n switch (entity.dimensionType) {\n case 0: // Rotated, horizontal, or vertical\n case 1: // Aligned\n return renderLinearDimension(entity, dimStyle, options, viewport)\n case 2: // Angular\n return renderAngularDimension(entity, dimStyle, options, viewport)\n case 5: // Angular 3-point\n return renderAngular3PointDimension(entity, dimStyle, options, viewport)\n case 3: // Diameter\n return renderDiameterDimension(entity, dimStyle, options, viewport)\n case 4: // Radius\n return renderRadialDimension(entity, dimStyle, options, viewport)\n case 6: // Ordinate\n return renderOrdinateDimension(entity, dimStyle, options, viewport)\n default:\n // Fallback to simple line rendering\n return renderFallbackDimension(entity)\n }\n}\n\n/**\n * Render angular 3-point dimension (type 5).\n *\n * Based on DXF reference + ezdxf: angle is measured from p1 to p2\n * counter-clockwise around the vertex.\n */\nfunction renderAngular3PointDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n options?: ToSVGOptions,\n viewport?: DimensionViewport,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n const markers: string[] = []\n\n const { arrowSize, textHeight } = getScaledDimensionSizes(dimStyle, options, viewport)\n const { dimLineColor, extLineColor, textColor, dimLineWeight, extLineWeight } = getDimensionColors(dimStyle)\n\n const vertexX = entity.angleVertex?.x ?? 0\n const vertexY = entity.angleVertex?.y ?? 0\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.measureEnd?.x ?? 0\n const y2 = entity.measureEnd?.y ?? 0\n\n // DXF reference: point (10,20,30) specifies the dimension line arc location.\n // In practice, ezdxf may also provide (16,26,36); prefer arcPoint only if it\n // yields a meaningful radius away from the vertex.\n const startArcX = entity.start?.x ?? 0\n const startArcY = entity.start?.y ?? 0\n const arcPointX = entity.arcPoint?.x\n const arcPointY = entity.arcPoint?.y\n\n const arcPointRadius =\n Number.isFinite(arcPointX) && Number.isFinite(arcPointY)\n ? Math.hypot((arcPointX as number) - vertexX, (arcPointY as number) - vertexY)\n : Number.NaN\n\n const useArcPoint = Number.isFinite(arcPointRadius) && arcPointRadius > 1e-9\n const arcLocationX = useArcPoint ? (arcPointX as number) : startArcX\n const arcLocationY = useArcPoint ? (arcPointY as number) : startArcY\n\n const textX = entity.textMidpoint?.x ?? arcLocationX\n const textY = entity.textMidpoint?.y ?? arcLocationY\n\n bbox.expandByPoint({ x: vertexX, y: vertexY })\n bbox.expandByPoint({ x: x1, y: y1 })\n bbox.expandByPoint({ x: x2, y: y2 })\n bbox.expandByPoint({ x: arcLocationX, y: arcLocationY })\n bbox.expandByPoint({ x: textX, y: textY })\n\n const a1 = Math.atan2(y1 - vertexY, x1 - vertexX)\n const a2 = Math.atan2(y2 - vertexY, x2 - vertexX)\n\n let radius = Math.hypot(arcLocationX - vertexX, arcLocationY - vertexY)\n if (!Number.isFinite(radius) || radius <= 1e-9) {\n radius = Math.hypot(textX - vertexX, textY - vertexY)\n }\n if (!Number.isFinite(radius) || radius <= 1e-9) {\n radius = Math.max(\n Math.hypot(x1 - vertexX, y1 - vertexY),\n Math.hypot(x2 - vertexX, y2 - vertexY),\n )\n }\n\n const arcStartX = vertexX + radius * Math.cos(a1)\n const arcStartY = vertexY + radius * Math.sin(a1)\n const arcEndX = vertexX + radius * Math.cos(a2)\n const arcEndY = vertexY + radius * Math.sin(a2)\n\n bbox.expandByPoint({ x: arcStartX, y: arcStartY })\n bbox.expandByPoint({ x: arcEndX, y: arcEndY })\n\n // Create arrow markers\n const markerId1 = `dim-angular-3p-arrow-start-${Date.now()}`\n const markerId2 = `dim-angular-3p-arrow-end-${Date.now()}`\n markers.push(\n createArrowMarker(markerId1, arrowSize, dimLineColor, 'backward'),\n createArrowMarker(markerId2, arrowSize, dimLineColor, 'forward'),\n )\n\n // Extension lines from definition points to arc endpoints.\n elements.push(\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${arcStartX}\" y2=\"${arcStartY}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n `<line x1=\"${x2}\" y1=\"${y2}\" x2=\"${arcEndX}\" y2=\"${arcEndY}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n )\n\n // Arc from a1 to a2 in CCW orientation.\n let delta = a2 - a1\n while (delta < 0) delta += Math.PI * 2\n while (delta >= Math.PI * 2) delta -= Math.PI * 2\n const largeArcFlag = delta > Math.PI ? 1 : 0\n const sweepFlag = 1\n\n expandBBoxForMarker(bbox, arcStartX, arcStartY, arrowSize)\n expandBBoxForMarker(bbox, arcEndX, arcEndY, arrowSize)\n\n elements.push(\n `<path d=\"M ${arcStartX} ${arcStartY} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${arcEndX} ${arcEndY}\" fill=\"none\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" marker-start=\"url(#${markerId1})\" marker-end=\"url(#${markerId2})\" />`,\n )\n\n const resolvedText = resolveDimensionText(entity)\n if (resolvedText) {\n const midAngle = a1 + delta / 2\n const textRotation = (midAngle * 180) / Math.PI\n\n expandBBoxForText(bbox, textX, textY, textHeight, resolvedText)\n\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${escapeXmlText(resolvedText)}</text>`,\n )\n }\n\n return {\n bbox,\n element: `<defs>${markers.join('')}</defs><g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Create SVG marker definition for dimension arrows\n */\nexport function createArrowMarker(\n id: string,\n size: number,\n color: string,\n direction: 'forward' | 'backward' = 'forward',\n): string {\n const arrowPath = direction === 'forward'\n ? `M 0 0 L ${size} ${size / 2} L 0 ${size} z`\n : `M ${size} 0 L 0 ${size / 2} L ${size} ${size} z`\n const refX = direction === 'forward' ? size : 0\n\n return `<marker id=\"${id}\" markerWidth=\"${size}\" markerHeight=\"${size}\" refX=\"${refX}\" refY=\"${size / 2}\" orient=\"auto\" markerUnits=\"userSpaceOnUse\">\n <path d=\"${arrowPath}\" fill=\"${color}\" />\n </marker>`\n}\n\n/**\n * Render linear dimension (rotated, horizontal, vertical, or aligned)\n */\nfunction renderLinearDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n options?: ToSVGOptions,\n viewport?: DimensionViewport,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n const markers: string[] = []\n\n // Get dimension style properties with defaults (optionally auto-scaled)\n const { arrowSize, textHeight, extLineOffset, extLineExtension } =\n getScaledDimensionSizes(dimStyle, options, viewport)\n const { dimLineColor, extLineColor, textColor, dimLineWeight, extLineWeight } = getDimensionColors(dimStyle)\n\n // Extract dimension geometry\n const defPoint1X = entity.measureStart?.x ?? 0\n const defPoint1Y = entity.measureStart?.y ?? 0\n const defPoint2X = entity.measureEnd?.x ?? 0\n const defPoint2Y = entity.measureEnd?.y ?? 0\n const dimLineY = entity.start?.y ?? 0\n const textX = entity.textMidpoint?.x ?? (defPoint1X + defPoint2X) / 2\n const textY = entity.textMidpoint?.y ?? (defPoint1Y + defPoint2Y) / 2\n\n // Calculate dimension line angle\n const angle = Math.atan2(defPoint2Y - defPoint1Y, defPoint2X - defPoint1X)\n const perpAngle = angle + Math.PI / 2\n\n // Calculate dimension line endpoints\n const dimLine1X = defPoint1X + Math.cos(perpAngle) * (dimLineY - defPoint1Y)\n const dimLine1Y = defPoint1Y + Math.sin(perpAngle) * (dimLineY - defPoint1Y)\n const dimLine2X = defPoint2X + Math.cos(perpAngle) * (dimLineY - defPoint2Y)\n const dimLine2Y = defPoint2Y + Math.sin(perpAngle) * (dimLineY - defPoint2Y)\n\n // Expand bounding box\n bbox.expandByPoint({ x: defPoint1X, y: defPoint1Y })\n bbox.expandByPoint({ x: defPoint2X, y: defPoint2Y })\n bbox.expandByPoint({ x: dimLine1X, y: dimLine1Y })\n bbox.expandByPoint({ x: dimLine2X, y: dimLine2Y })\n bbox.expandByPoint({ x: textX, y: textY })\n\n // Create unique marker IDs for arrows\n const markerId1 = `dim-arrow-start-${Date.now()}`\n const markerId2 = `dim-arrow-end-${Date.now()}`\n\n // Create arrow markers with dimension line color\n markers.push(\n createArrowMarker(markerId1, arrowSize, dimLineColor, 'backward'),\n createArrowMarker(markerId2, arrowSize, dimLineColor, 'forward'),\n )\n\n // Draw extension lines\n const extLine1StartX = defPoint1X + Math.cos(perpAngle) * extLineOffset\n const extLine1StartY = defPoint1Y + Math.sin(perpAngle) * extLineOffset\n const extLine1EndX = dimLine1X + Math.cos(perpAngle) * extLineExtension\n const extLine1EndY = dimLine1Y + Math.sin(perpAngle) * extLineExtension\n\n const extLine2StartX = defPoint2X + Math.cos(perpAngle) * extLineOffset\n const extLine2StartY = defPoint2Y + Math.sin(perpAngle) * extLineOffset\n const extLine2EndX = dimLine2X + Math.cos(perpAngle) * extLineExtension\n const extLine2EndY = dimLine2Y + Math.sin(perpAngle) * extLineExtension\n\n // Expand bounding box to include full extension lines and arrow markers\n bbox.expandByPoint({ x: extLine1StartX, y: extLine1StartY })\n bbox.expandByPoint({ x: extLine1EndX, y: extLine1EndY })\n bbox.expandByPoint({ x: extLine2StartX, y: extLine2StartY })\n bbox.expandByPoint({ x: extLine2EndX, y: extLine2EndY })\n expandBBoxForMarker(bbox, dimLine1X, dimLine1Y, arrowSize)\n expandBBoxForMarker(bbox, dimLine2X, dimLine2Y, arrowSize)\n\n elements.push(\n `<line x1=\"${extLine1StartX}\" y1=\"${extLine1StartY}\" x2=\"${extLine1EndX}\" y2=\"${extLine1EndY}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n `<line x1=\"${extLine2StartX}\" y1=\"${extLine2StartY}\" x2=\"${extLine2EndX}\" y2=\"${extLine2EndY}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n `<line x1=\"${dimLine1X}\" y1=\"${dimLine1Y}\" x2=\"${dimLine2X}\" y2=\"${dimLine2Y}\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" marker-start=\"url(#${markerId1})\" marker-end=\"url(#${markerId2})\" />`,\n )\n\n // Add dimension text\n const resolvedText = resolveDimensionText(entity)\n if (resolvedText) {\n const textRotation = (angle * 180) / Math.PI\n expandBBoxForText(bbox, textX, textY, textHeight, resolvedText)\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${escapeXmlText(resolvedText)}</text>`,\n )\n }\n\n return {\n bbox,\n element: `<defs>${markers.join('')}</defs><g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Render angular dimension\n */\nfunction renderAngularDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n options?: ToSVGOptions,\n viewport?: DimensionViewport,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n const markers: string[] = []\n\n // Get dimension style properties (optionally auto-scaled)\n const { arrowSize, textHeight } = getScaledDimensionSizes(dimStyle, options, viewport)\n const { dimLineColor, extLineColor, textColor, dimLineWeight, extLineWeight } = getDimensionColors(dimStyle)\n\n // Extract points\n const centerX = entity.start?.x ?? 0\n const centerY = entity.start?.y ?? 0\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.measureEnd?.x ?? 0\n const y2 = entity.measureEnd?.y ?? 0\n const textX = entity.textMidpoint?.x ?? centerX\n const textY = entity.textMidpoint?.y ?? centerY\n\n bbox.expandByPoint({ x: centerX, y: centerY })\n bbox.expandByPoint({ x: x1, y: y1 })\n bbox.expandByPoint({ x: x2, y: y2 })\n bbox.expandByPoint({ x: textX, y: textY })\n\n // Create arrow markers\n const markerId1 = `dim-angular-arrow-start-${Date.now()}`\n const markerId2 = `dim-angular-arrow-end-${Date.now()}`\n markers.push(\n createArrowMarker(markerId1, arrowSize, dimLineColor, 'backward'),\n createArrowMarker(markerId2, arrowSize, dimLineColor, 'forward'),\n )\n\n // Draw extension lines from center to definition points\n elements.push(\n `<line x1=\"${centerX}\" y1=\"${centerY}\" x2=\"${x1}\" y2=\"${y1}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n `<line x1=\"${centerX}\" y1=\"${centerY}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${extLineColor}\" stroke-width=\"${extLineWeight}\" />`,\n )\n\n // Calculate arc radius (distance from center to text midpoint)\n const radius = Math.hypot(textX - centerX, textY - centerY)\n const startAngle = Math.atan2(y1 - centerY, x1 - centerX)\n const endAngle = Math.atan2(y2 - centerY, x2 - centerX)\n\n // Draw arc for angular dimension\n const largeArcFlag = Math.abs(endAngle - startAngle) > Math.PI ? 1 : 0\n const arcStartX = centerX + radius * Math.cos(startAngle)\n const arcStartY = centerY + radius * Math.sin(startAngle)\n const arcEndX = centerX + radius * Math.cos(endAngle)\n const arcEndY = centerY + radius * Math.sin(endAngle)\n\n elements.push(\n `<path d=\"M ${arcStartX} ${arcStartY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${arcEndX} ${arcEndY}\" fill=\"none\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" marker-start=\"url(#${markerId1})\" marker-end=\"url(#${markerId2})\" />`,\n )\n\n // Add dimension text\n const resolvedText = resolveDimensionText(entity)\n if (resolvedText) {\n const midAngle = (startAngle + endAngle) / 2\n const textRotation = (midAngle * 180) / Math.PI\n\n expandBBoxForText(bbox, textX, textY, textHeight, resolvedText)\n\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${escapeXmlText(resolvedText)}</text>`,\n )\n }\n\n return {\n bbox,\n element: `<defs>${markers.join('')}</defs><g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Render diameter dimension\n */\nfunction renderDiameterDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n options?: ToSVGOptions,\n viewport?: DimensionViewport,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n const markers: string[] = []\n\n // Get dimension style properties (optionally auto-scaled)\n const { arrowSize, textHeight } = getScaledDimensionSizes(dimStyle, options, viewport)\n const { dimLineColor, textColor, dimLineWeight } = getDimensionColors(dimStyle)\n\n // Extract geometry\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.measureEnd?.x ?? 0\n const y2 = entity.measureEnd?.y ?? 0\n const textX = entity.textMidpoint?.x ?? (x1 + x2) / 2\n const textY = entity.textMidpoint?.y ?? (y1 + y2) / 2\n\n bbox.expandByPoint({ x: x1, y: y1 })\n bbox.expandByPoint({ x: x2, y: y2 })\n bbox.expandByPoint({ x: textX, y: textY })\n\n const diameterLen = Math.hypot(x2 - x1, y2 - y1)\n if (Number.isFinite(diameterLen) && diameterLen > 1e-6) {\n // Create arrow markers\n const markerId = `dim-diameter-arrow-${Date.now()}`\n markers.push(createArrowMarker(markerId, arrowSize, dimLineColor, 'backward'))\n\n // Create diameter line with arrow at the end\n elements.push(\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" marker-end=\"url(#${markerId})\" />`,\n )\n\n expandBBoxForMarker(bbox, x2, y2, arrowSize)\n }\n\n // Add dimension text with diameter symbol\n const resolvedText = resolveDimensionText(entity)\n const diameterText = resolvedText ? `\u2300${resolvedText}` : '\u2300'\n const angle = Math.atan2(y2 - y1, x2 - x1)\n const textRotation = (angle * 180) / Math.PI\n\n expandBBoxForText(bbox, textX, textY, textHeight, diameterText)\n\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${escapeXmlText(diameterText)}</text>`,\n )\n\n return {\n bbox,\n element: `<defs>${markers.join('')}</defs><g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Render radial dimension\n */\nfunction renderRadialDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n options?: ToSVGOptions,\n viewport?: DimensionViewport,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n const markers: string[] = []\n\n // Get dimension style properties (optionally auto-scaled)\n const { arrowSize, textHeight } = getScaledDimensionSizes(dimStyle, options, viewport)\n const { dimLineColor, textColor, dimLineWeight } = getDimensionColors(dimStyle)\n\n // Extract geometry\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.measureEnd?.x ?? 0\n const y2 = entity.measureEnd?.y ?? 0\n const textX = entity.textMidpoint?.x ?? (x1 + x2) / 2\n const textY = entity.textMidpoint?.y ?? (y1 + y2) / 2\n\n bbox.expandByPoint({ x: x1, y: y1 })\n bbox.expandByPoint({ x: x2, y: y2 })\n bbox.expandByPoint({ x: textX, y: textY })\n\n const radiusLen = Math.hypot(x2 - x1, y2 - y1)\n if (Number.isFinite(radiusLen) && radiusLen > 1e-6) {\n // Create arrow markers\n const markerId = `dim-radius-arrow-${Date.now()}`\n markers.push(createArrowMarker(markerId, arrowSize, dimLineColor, 'backward'))\n\n // Create radius line with arrow at the end\n elements.push(\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" marker-end=\"url(#${markerId})\" />`,\n )\n\n expandBBoxForMarker(bbox, x2, y2, arrowSize)\n }\n\n // Add dimension text with radius symbol\n const resolvedText = resolveDimensionText(entity)\n const radiusText = resolvedText ? `R${resolvedText}` : 'R'\n const angle = Math.atan2(y2 - y1, x2 - x1)\n const textRotation = (angle * 180) / Math.PI\n\n expandBBoxForText(bbox, textX, textY, textHeight, radiusText)\n\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${escapeXmlText(radiusText)}</text>`,\n )\n\n return {\n bbox,\n element: `<defs>${markers.join('')}</defs><g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Render ordinate dimension\n */\nfunction renderOrdinateDimension(\n entity: DimensionEntity,\n dimStyle?: DimStyleTable,\n options?: ToSVGOptions,\n viewport?: DimensionViewport,\n): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n\n // Get dimension style properties (optionally auto-scaled)\n const { textHeight } = getScaledDimensionSizes(dimStyle, options, viewport)\n const { dimLineColor, textColor, dimLineWeight } = getDimensionColors(dimStyle)\n\n // Extract geometry\n const x1 = entity.measureStart?.x ?? 0\n const y1 = entity.measureStart?.y ?? 0\n const x2 = entity.start?.x ?? 0\n const y2 = entity.start?.y ?? 0\n const textX = entity.textMidpoint?.x ?? x2\n const textY = entity.textMidpoint?.y ?? y2\n\n bbox.expandByPoint({ x: x1, y: y1 })\n bbox.expandByPoint({ x: x2, y: y2 })\n bbox.expandByPoint({ x: textX, y: textY })\n\n // Create leader line (no arrow for ordinate dimensions)\n elements.push(\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"${dimLineColor}\" stroke-width=\"${dimLineWeight}\" />`,\n )\n\n // Add dimension text\n const resolvedText = resolveDimensionText(entity)\n if (resolvedText) {\n const angle = Math.atan2(y2 - y1, x2 - x1)\n const textRotation = (angle * 180) / Math.PI\n\n expandBBoxForText(bbox, textX, textY, textHeight, resolvedText)\n\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"${textHeight}\" fill=\"${textColor}\" text-anchor=\"middle\" transform=\"rotate(${-textRotation} ${textX} ${textY}) scale(1,-1) translate(0 ${-2 * textY})\">${escapeXmlText(resolvedText)}</text>`,\n )\n }\n\n return {\n bbox,\n element: `<g>${elements.join('')}</g>`,\n }\n}\n\n/**\n * Fallback renderer for unsupported dimension types\n */\nfunction renderFallbackDimension(entity: DimensionEntity): BoundsAndElement {\n const bbox = new Box2()\n const elements: string[] = []\n\n // Just render text at midpoint\n if (entity.textMidpoint) {\n const textX = entity.textMidpoint.x ?? 0\n const textY = entity.textMidpoint.y ?? 0\n bbox.expandByPoint({ x: textX, y: textY })\n\n const resolvedText = resolveDimensionText(entity)\n if (resolvedText) {\n elements.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-size=\"2.5\" text-anchor=\"middle\" transform=\"scale(1,-1) translate(0 ${-2 * textY})\">${escapeXmlText(resolvedText)}</text>`,\n )\n }\n }\n\n return {\n bbox,\n element: `<g>${elements.join('')}</g>`,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -144,12 +144,95 @@ const polyfaceOutline = (entity) => {
144
144
  function entityToPolyline(entity, options) {
145
145
  options = options || {};
146
146
  let polyline;
147
+ const INFINITE_LINE_LENGTH = 1e3;
148
+ const normalize2 = (x, y) => {
149
+ const len = Math.hypot(x, y);
150
+ if (len === 0) return null;
151
+ return { x: x / len, y: y / len };
152
+ };
147
153
  if (entity.type === "LINE") {
148
154
  polyline = [
149
155
  [entity.start.x, entity.start.y],
150
156
  [entity.end.x, entity.end.y]
151
157
  ];
152
158
  }
159
+ if (entity.type === "LEADER") {
160
+ if (entity.vertices.length >= 2) {
161
+ polyline = entity.vertices.map((v) => [v.x, v.y]);
162
+ } else {
163
+ import_logger.default.warn("LEADER entity with insufficient vertices");
164
+ polyline = [];
165
+ }
166
+ }
167
+ if (entity.type === "RAY") {
168
+ const dir = normalize2(entity.direction.x, entity.direction.y);
169
+ if (dir === null) {
170
+ import_logger.default.warn("RAY entity with zero direction vector");
171
+ polyline = [];
172
+ } else {
173
+ polyline = [
174
+ [entity.start.x, entity.start.y],
175
+ [
176
+ entity.start.x + dir.x * INFINITE_LINE_LENGTH,
177
+ entity.start.y + dir.y * INFINITE_LINE_LENGTH
178
+ ]
179
+ ];
180
+ }
181
+ }
182
+ if (entity.type === "XLINE") {
183
+ const dir = normalize2(entity.direction.x, entity.direction.y);
184
+ if (dir === null) {
185
+ import_logger.default.warn("XLINE entity with zero direction vector");
186
+ polyline = [];
187
+ } else {
188
+ polyline = [
189
+ [
190
+ entity.basePoint.x - dir.x * INFINITE_LINE_LENGTH,
191
+ entity.basePoint.y - dir.y * INFINITE_LINE_LENGTH
192
+ ],
193
+ [
194
+ entity.basePoint.x + dir.x * INFINITE_LINE_LENGTH,
195
+ entity.basePoint.y + dir.y * INFINITE_LINE_LENGTH
196
+ ]
197
+ ];
198
+ }
199
+ }
200
+ if (entity.type === "SHAPE") {
201
+ const x = entity.insertionPoint?.x ?? 0;
202
+ const y = entity.insertionPoint?.y ?? 0;
203
+ const size = entity.size ?? 0;
204
+ const scaleX = entity.relativeXScale ?? 1;
205
+ const length = size * scaleX;
206
+ polyline = [
207
+ [x, y],
208
+ [x + length, y]
209
+ ];
210
+ }
211
+ if (entity.type === "WIPEOUT") {
212
+ const verts = entity.clipBoundaryVertices;
213
+ if (!verts || verts.length < 2) {
214
+ import_logger.default.warn("WIPEOUT entity with missing clip boundary vertices");
215
+ polyline = [];
216
+ } else {
217
+ const insX = entity.insertionPoint?.x ?? 0;
218
+ const insY = entity.insertionPoint?.y ?? 0;
219
+ const ux = entity.uVector?.x ?? 1;
220
+ const uy = entity.uVector?.y ?? 0;
221
+ const vx = entity.vVector?.x ?? 0;
222
+ const vy = entity.vVector?.y ?? 1;
223
+ polyline = verts.map((p) => [
224
+ insX + ux * p.x + vx * p.y,
225
+ insY + uy * p.x + vy * p.y
226
+ ]);
227
+ if (polyline.length > 0) {
228
+ const first = polyline[0];
229
+ const last = polyline[polyline.length - 1];
230
+ if (first[0] !== last[0] || first[1] !== last[1]) {
231
+ polyline.push(first);
232
+ }
233
+ }
234
+ }
235
+ }
153
236
  if (entity.type === "LWPOLYLINE" || entity.type === "POLYLINE") {
154
237
  polyline = [];
155
238
  if (entity.polyfaceMesh) {
@@ -234,6 +317,18 @@ function entityToPolyline(entity, options) {
234
317
  entity.weights
235
318
  );
236
319
  }
320
+ if (entity.type === "SOLID" || entity.type === "TRACE") {
321
+ const corners = entity.corners ?? entity.points;
322
+ if (corners && corners.length >= 4) {
323
+ polyline = [
324
+ [corners[0].x, corners[0].y],
325
+ [corners[1].x, corners[1].y],
326
+ [corners[2].x, corners[2].y],
327
+ [corners[3].x, corners[3].y],
328
+ [corners[0].x, corners[0].y]
329
+ ];
330
+ }
331
+ }
237
332
  if (!polyline) {
238
333
  import_logger.default.warn("unsupported entity for converting to polyline:", entity.type);
239
334
  return [];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/entityToPolyline.ts"],
4
- "sourcesContent": ["import bSpline from './util/bSpline'\nimport createArcForLWPolyine from './util/createArcForLWPolyline'\nimport logger from './util/logger'\n\nimport type {\n ArcEntity,\n CircleEntity,\n ControlPoint,\n EllipseEntity,\n EntityToPolylineOptions,\n HandlerVertex,\n LineEntity,\n SplineEntity,\n} from './types'\nimport type { PointTuple } from './types/common'\n\n// Re-export types for backward compatibility\nexport type { ControlPoint, EntityToPolylineOptions } from './types'\n\ntype Point = PointTuple\n\n// Local vertex type with required coordinates for runtime processing\ninterface LocalVertex extends HandlerVertex {\n faces?: number[]\n}\n\n// Local polyline type that uses our vertex with required coordinates\ninterface LocalPolylineEntity {\n type: string\n vertices: LocalVertex[]\n closed?: boolean\n polyfaceMesh?: boolean\n polygonMesh?: boolean\n}\n\ntype Entity =\n | LineEntity\n | (LocalPolylineEntity & { type: 'LWPOLYLINE' | 'POLYLINE' })\n | CircleEntity\n | EllipseEntity\n | ArcEntity\n | SplineEntity\n\n/**\n * Rotate a set of points.\n *\n * @param points the points\n * @param angle the rotation angle\n */\nconst rotate = (points: Point[], angle: number): Point[] => {\n return points.map(function (p) {\n return [\n p[0] * Math.cos(angle) - p[1] * Math.sin(angle),\n p[1] * Math.cos(angle) + p[0] * Math.sin(angle),\n ]\n })\n}\n\n/**\n * Interpolate an ellipse\n * @param cx center X\n * @param cy center Y\n * @param rx radius X\n * @param ry radius Y\n * @param start start angle in radians\n * @param start end angle in radians\n */\nconst interpolateEllipse = (\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n start: number,\n end: number,\n rotationAngle?: number\n): Point[] => {\n if (end < start) {\n end += Math.PI * 2\n }\n\n // ----- Relative points -----\n\n // Start point\n let points: Point[] = []\n const dTheta = (Math.PI * 2) / 72\n const EPS = 1e-6\n for (let theta = start; theta < end - EPS; theta += dTheta) {\n points.push([Math.cos(theta) * rx, Math.sin(theta) * ry])\n }\n points.push([Math.cos(end) * rx, Math.sin(end) * ry])\n\n // ----- Rotate -----\n if (rotationAngle) {\n points = rotate(points, rotationAngle)\n }\n\n // ----- Offset center -----\n points = points.map(function (p): Point {\n return [cx + p[0], cy + p[1]]\n })\n\n return points\n}\n\n/**\n * Interpolate a b-spline. The algorithm examins the knot vector\n * to create segments for interpolation. The parameterisation value\n * is re-normalised back to [0,1] as that is what the lib expects (\n * and t i de-normalised in the b-spline library)\n *\n * @param controlPoints the control points\n * @param degree the b-spline degree\n * @param knots the knot vector\n * @returns the polyline\n */\nexport const interpolateBSpline = (\n controlPoints: ControlPoint[],\n degree: number,\n knots: number[],\n interpolationsPerSplineSegment?: number,\n weights?: number[]\n): Point[] => {\n const polyline: Point[] = []\n const controlPointsForLib = controlPoints.map(function (p): Point {\n return [p.x, p.y]\n })\n\n const segmentTs = [knots[degree]]\n const domain: Point = [knots[degree], knots[knots.length - 1 - degree]]\n\n for (let k = degree + 1; k < knots.length - degree; ++k) {\n if (segmentTs[segmentTs.length - 1] !== knots[k]) {\n segmentTs.push(knots[k])\n }\n }\n\n interpolationsPerSplineSegment = interpolationsPerSplineSegment || 25\n for (let i = 1; i < segmentTs.length; ++i) {\n const uMin = segmentTs[i - 1]\n const uMax = segmentTs[i]\n for (let k = 0; k <= interpolationsPerSplineSegment; ++k) {\n const u = (k / interpolationsPerSplineSegment) * (uMax - uMin) + uMin\n // Clamp t to 0, 1 to handle numerical precision issues\n let t = (u - domain[0]) / (domain[1] - domain[0])\n t = Math.max(t, 0)\n t = Math.min(t, 1)\n const p = bSpline(t, degree, controlPointsForLib, knots, weights)\n polyline.push([p[0], p[1]])\n }\n }\n return polyline\n}\n\nexport const polyfaceOutline = (entity: LocalPolylineEntity): Point[][] => {\n const vertices: Array<{ x: number; y: number }> = []\n const faces: Array<{ indices: number[]; hiddens: boolean[] }> = []\n\n for (const v of entity.vertices) {\n if (v.faces) {\n const face: { indices: number[]; hiddens: boolean[] } = {\n indices: [],\n hiddens: [],\n }\n for (const i of v.faces) {\n if (i === 0) {\n break\n }\n // Negative indices signify hidden edges\n face.indices.push(i < 0 ? -i - 1 : i - 1)\n face.hiddens.push(i < 0)\n }\n if ([3, 4].includes(face.indices.length)) faces.push(face)\n } else {\n vertices.push({ x: v.x, y: v.y })\n }\n }\n\n // If a segment starts at the end of a previous line, continue it\n const polylines: number[][] = []\n const segment = (a: number, b: number): void => {\n for (const prev of polylines) {\n if (prev.slice(-1)[0] === a) {\n prev.push(b)\n return\n }\n }\n polylines.push([a, b])\n }\n\n for (const face of faces) {\n for (let beg = 0; beg < face.indices.length; beg++) {\n if (face.hiddens[beg]) {\n continue\n }\n const end = (beg + 1) % face.indices.length\n segment(face.indices[beg], face.indices[end])\n }\n }\n\n // Sometimes segments are not sequential, in that case\n // we need to find if they can mend gaps between others\n for (const a of polylines) {\n for (const b of polylines) {\n if (a !== b && a[0] === b.slice(-1)[0]) {\n b.push(...a.slice(1))\n a.splice(0, a.length)\n break\n }\n }\n }\n\n return polylines\n .filter((l) => l.length)\n .map((l) => l.map((i) => vertices[i]).map((v) => [v.x, v.y]))\n}\n\n/**\n * Convert a parsed DXF entity to a polyline. These can be used to render the\n * the DXF in SVG, Canvas, WebGL etc., without depending on native support\n * of primitive objects (ellispe, spline etc.)\n */\nexport default function entityToPolyline(\n entity: Entity,\n options?: EntityToPolylineOptions,\n): Point[] {\n options = options || {}\n let polyline: Point[] | undefined\n\n if (entity.type === 'LINE') {\n polyline = [\n [entity.start.x, entity.start.y],\n [entity.end.x, entity.end.y],\n ]\n }\n\n if (entity.type === 'LWPOLYLINE' || entity.type === 'POLYLINE') {\n polyline = []\n if (entity.polyfaceMesh) {\n // Only return the first polyline because we can't return many\n polyline.push(...polyfaceOutline(entity)[0])\n } else if (entity.polygonMesh) {\n // Do not attempt to render polygon meshes\n } else if (entity.vertices.length) {\n if (entity.closed) {\n entity.vertices = entity.vertices.concat(entity.vertices[0])\n }\n for (let i = 0, il = entity.vertices.length; i < il - 1; ++i) {\n const from: Point = [entity.vertices[i].x, entity.vertices[i].y]\n const to: Point = [entity.vertices[i + 1].x, entity.vertices[i + 1].y]\n polyline.push(from)\n if (entity.vertices[i].bulge) {\n polyline = polyline.concat(\n createArcForLWPolyine(from, to, entity.vertices[i].bulge!),\n )\n }\n // The last iteration of the for loop\n if (i === il - 2) {\n polyline.push(to)\n }\n }\n } else {\n logger.warn('Polyline entity with no vertices')\n }\n }\n\n if (entity.type === 'CIRCLE') {\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n entity.r,\n entity.r,\n 0,\n Math.PI * 2,\n )\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'ELLIPSE') {\n const rx = Math.hypot(entity.majorX, entity.majorY)\n const ry = entity.axisRatio * rx\n const majorAxisRotation = -Math.atan2(-entity.majorY, entity.majorX)\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n rx,\n ry,\n entity.startAngle,\n entity.endAngle,\n majorAxisRotation,\n )\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'ARC') {\n // Why on earth DXF has degree start & end angles for arc,\n // and radian start & end angles for ellipses is a mystery\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n entity.r,\n entity.r,\n entity.startAngle,\n entity.endAngle,\n )\n\n // I kid you not, ARCs and ELLIPSEs handle this differently,\n // as evidenced by how AutoCAD actually renders these entities\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'SPLINE') {\n polyline = interpolateBSpline(\n entity.controlPoints,\n entity.degree,\n entity.knots,\n options.interpolationsPerSplineSegment,\n entity.weights,\n )\n }\n\n if (!polyline) {\n logger.warn('unsupported entity for converting to polyline:', entity.type)\n return []\n }\n return polyline\n}\n"],
5
- "mappings": "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",
6
- "names": ["bSpline", "createArcForLWPolyine", "logger"]
4
+ "sourcesContent": ["import bSpline from './util/bSpline'\nimport createArcForLWPolyine from './util/createArcForLWPolyline'\nimport logger from './util/logger'\n\nimport type {\n ArcEntity,\n CircleEntity,\n ControlPoint,\n EllipseEntity,\n EntityToPolylineOptions,\n HandlerVertex,\n LeaderEntity,\n LineEntity,\n RayEntity,\n ShapeEntity,\n SplineEntity,\n WipeoutEntity,\n XLineEntity,\n} from './types'\nimport type { PointTuple } from './types/common'\n\n// Re-export types for backward compatibility\nexport type { ControlPoint, EntityToPolylineOptions } from './types'\n\ntype Point = PointTuple\n\n// Local vertex type with required coordinates for runtime processing\ninterface LocalVertex extends HandlerVertex {\n faces?: number[]\n}\n\n// Local polyline type that uses our vertex with required coordinates\ninterface LocalPolylineEntity {\n type: string\n vertices: LocalVertex[]\n closed?: boolean\n polyfaceMesh?: boolean\n polygonMesh?: boolean\n}\n\ntype Entity =\n | LineEntity\n | LeaderEntity\n | RayEntity\n | XLineEntity\n | ShapeEntity\n | WipeoutEntity\n | (LocalPolylineEntity & { type: 'LWPOLYLINE' | 'POLYLINE' })\n | {\n type: 'SOLID' | 'TRACE'\n corners?: Array<{ x: number; y: number }>\n points?: Array<{ x: number; y: number }>\n }\n | CircleEntity\n | EllipseEntity\n | ArcEntity\n | SplineEntity\n\n/**\n * Rotate a set of points.\n *\n * @param points the points\n * @param angle the rotation angle\n */\nconst rotate = (points: Point[], angle: number): Point[] => {\n return points.map(function (p) {\n return [\n p[0] * Math.cos(angle) - p[1] * Math.sin(angle),\n p[1] * Math.cos(angle) + p[0] * Math.sin(angle),\n ]\n })\n}\n\n/**\n * Interpolate an ellipse\n * @param cx center X\n * @param cy center Y\n * @param rx radius X\n * @param ry radius Y\n * @param start start angle in radians\n * @param start end angle in radians\n */\nconst interpolateEllipse = (\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n start: number,\n end: number,\n rotationAngle?: number\n): Point[] => {\n if (end < start) {\n end += Math.PI * 2\n }\n\n // ----- Relative points -----\n\n // Start point\n let points: Point[] = []\n const dTheta = (Math.PI * 2) / 72\n const EPS = 1e-6\n for (let theta = start; theta < end - EPS; theta += dTheta) {\n points.push([Math.cos(theta) * rx, Math.sin(theta) * ry])\n }\n points.push([Math.cos(end) * rx, Math.sin(end) * ry])\n\n // ----- Rotate -----\n if (rotationAngle) {\n points = rotate(points, rotationAngle)\n }\n\n // ----- Offset center -----\n points = points.map(function (p): Point {\n return [cx + p[0], cy + p[1]]\n })\n\n return points\n}\n\n/**\n * Interpolate a b-spline. The algorithm examins the knot vector\n * to create segments for interpolation. The parameterisation value\n * is re-normalised back to [0,1] as that is what the lib expects (\n * and t i de-normalised in the b-spline library)\n *\n * @param controlPoints the control points\n * @param degree the b-spline degree\n * @param knots the knot vector\n * @returns the polyline\n */\nexport const interpolateBSpline = (\n controlPoints: ControlPoint[],\n degree: number,\n knots: number[],\n interpolationsPerSplineSegment?: number,\n weights?: number[]\n): Point[] => {\n const polyline: Point[] = []\n const controlPointsForLib = controlPoints.map(function (p): Point {\n return [p.x, p.y]\n })\n\n const segmentTs = [knots[degree]]\n const domain: Point = [knots[degree], knots[knots.length - 1 - degree]]\n\n for (let k = degree + 1; k < knots.length - degree; ++k) {\n if (segmentTs[segmentTs.length - 1] !== knots[k]) {\n segmentTs.push(knots[k])\n }\n }\n\n interpolationsPerSplineSegment = interpolationsPerSplineSegment || 25\n for (let i = 1; i < segmentTs.length; ++i) {\n const uMin = segmentTs[i - 1]\n const uMax = segmentTs[i]\n for (let k = 0; k <= interpolationsPerSplineSegment; ++k) {\n const u = (k / interpolationsPerSplineSegment) * (uMax - uMin) + uMin\n // Clamp t to 0, 1 to handle numerical precision issues\n let t = (u - domain[0]) / (domain[1] - domain[0])\n t = Math.max(t, 0)\n t = Math.min(t, 1)\n const p = bSpline(t, degree, controlPointsForLib, knots, weights)\n polyline.push([p[0], p[1]])\n }\n }\n return polyline\n}\n\nexport const polyfaceOutline = (entity: LocalPolylineEntity): Point[][] => { // NOSONAR\n const vertices: Array<{ x: number; y: number }> = []\n const faces: Array<{ indices: number[]; hiddens: boolean[] }> = []\n\n for (const v of entity.vertices) {\n if (v.faces) {\n const face: { indices: number[]; hiddens: boolean[] } = {\n indices: [],\n hiddens: [],\n }\n for (const i of v.faces) {\n if (i === 0) {\n break\n }\n // Negative indices signify hidden edges\n face.indices.push(i < 0 ? -i - 1 : i - 1)\n face.hiddens.push(i < 0)\n }\n if ([3, 4].includes(face.indices.length)) faces.push(face)\n } else {\n vertices.push({ x: v.x, y: v.y })\n }\n }\n\n // If a segment starts at the end of a previous line, continue it\n const polylines: number[][] = []\n const segment = (a: number, b: number): void => {\n for (const prev of polylines) {\n if (prev.slice(-1)[0] === a) {\n prev.push(b)\n return\n }\n }\n polylines.push([a, b])\n }\n\n for (const face of faces) {\n for (let beg = 0; beg < face.indices.length; beg++) {\n if (face.hiddens[beg]) {\n continue\n }\n const end = (beg + 1) % face.indices.length\n segment(face.indices[beg], face.indices[end])\n }\n }\n\n // Sometimes segments are not sequential, in that case\n // we need to find if they can mend gaps between others\n for (const a of polylines) {\n for (const b of polylines) {\n if (a !== b && a[0] === b.slice(-1)[0]) {\n b.push(...a.slice(1))\n a.splice(0, a.length)\n break\n }\n }\n }\n\n return polylines\n .filter((l) => l.length)\n .map((l) => l.map((i) => vertices[i]).map((v) => [v.x, v.y]))\n}\n\n/**\n * Convert a parsed DXF entity to a polyline. These can be used to render the\n * the DXF in SVG, Canvas, WebGL etc., without depending on native support\n * of primitive objects (ellispe, spline etc.)\n */\nexport default function entityToPolyline( // NOSONAR\n entity: Entity,\n options?: EntityToPolylineOptions,\n): Point[] {\n options = options || {}\n let polyline: Point[] | undefined\n\n const INFINITE_LINE_LENGTH = 1000\n\n const normalize2 = (x: number, y: number): { x: number; y: number } | null => {\n const len = Math.hypot(x, y)\n if (len === 0) return null\n return { x: x / len, y: y / len }\n }\n\n if (entity.type === 'LINE') {\n polyline = [\n [entity.start.x, entity.start.y],\n [entity.end.x, entity.end.y],\n ]\n }\n\n if (entity.type === 'LEADER') {\n if (entity.vertices.length >= 2) {\n polyline = entity.vertices.map((v) => [v.x, v.y])\n } else {\n logger.warn('LEADER entity with insufficient vertices')\n polyline = []\n }\n }\n\n if (entity.type === 'RAY') {\n const dir = normalize2(entity.direction.x, entity.direction.y)\n if (dir === null) {\n logger.warn('RAY entity with zero direction vector')\n polyline = []\n } else {\n polyline = [\n [entity.start.x, entity.start.y],\n [\n entity.start.x + dir.x * INFINITE_LINE_LENGTH,\n entity.start.y + dir.y * INFINITE_LINE_LENGTH,\n ],\n ]\n }\n }\n\n if (entity.type === 'XLINE') {\n const dir = normalize2(entity.direction.x, entity.direction.y)\n if (dir === null) {\n logger.warn('XLINE entity with zero direction vector')\n polyline = []\n } else {\n polyline = [\n [\n entity.basePoint.x - dir.x * INFINITE_LINE_LENGTH,\n entity.basePoint.y - dir.y * INFINITE_LINE_LENGTH,\n ],\n [\n entity.basePoint.x + dir.x * INFINITE_LINE_LENGTH,\n entity.basePoint.y + dir.y * INFINITE_LINE_LENGTH,\n ],\n ]\n }\n }\n\n if (entity.type === 'SHAPE') {\n const x = entity.insertionPoint?.x ?? 0\n const y = entity.insertionPoint?.y ?? 0\n const size = entity.size ?? 0\n const scaleX = entity.relativeXScale ?? 1\n const length = size * scaleX\n polyline = [\n [x, y],\n [x + length, y],\n ]\n }\n\n if (entity.type === 'WIPEOUT') {\n const verts = entity.clipBoundaryVertices\n if (!verts || verts.length < 2) {\n logger.warn('WIPEOUT entity with missing clip boundary vertices')\n polyline = []\n } else {\n const insX = entity.insertionPoint?.x ?? 0\n const insY = entity.insertionPoint?.y ?? 0\n\n const ux = entity.uVector?.x ?? 1\n const uy = entity.uVector?.y ?? 0\n\n const vx = entity.vVector?.x ?? 0\n const vy = entity.vVector?.y ?? 1\n\n polyline = verts.map((p) => [\n insX + ux * p.x + vx * p.y,\n insY + uy * p.x + vy * p.y,\n ])\n\n if (polyline.length > 0) {\n const first = polyline[0]\n const last = polyline[polyline.length - 1]\n if (first[0] !== last[0] || first[1] !== last[1]) {\n polyline.push(first)\n }\n }\n }\n }\n\n if (entity.type === 'LWPOLYLINE' || entity.type === 'POLYLINE') {\n polyline = []\n if (entity.polyfaceMesh) {\n // Only return the first polyline because we can't return many\n polyline.push(...polyfaceOutline(entity)[0])\n } else if (entity.polygonMesh) {\n // Do not attempt to render polygon meshes\n } else if (entity.vertices.length) {\n if (entity.closed) {\n entity.vertices = entity.vertices.concat(entity.vertices[0])\n }\n for (let i = 0, il = entity.vertices.length; i < il - 1; ++i) {\n const from: Point = [entity.vertices[i].x, entity.vertices[i].y]\n const to: Point = [entity.vertices[i + 1].x, entity.vertices[i + 1].y]\n polyline.push(from)\n if (entity.vertices[i].bulge) {\n polyline = polyline.concat(\n createArcForLWPolyine(from, to, entity.vertices[i].bulge!),\n )\n }\n // The last iteration of the for loop\n if (i === il - 2) {\n polyline.push(to)\n }\n }\n } else {\n logger.warn('Polyline entity with no vertices')\n }\n }\n\n if (entity.type === 'CIRCLE') {\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n entity.r,\n entity.r,\n 0,\n Math.PI * 2,\n )\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'ELLIPSE') {\n const rx = Math.hypot(entity.majorX, entity.majorY)\n const ry = entity.axisRatio * rx\n const majorAxisRotation = -Math.atan2(-entity.majorY, entity.majorX)\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n rx,\n ry,\n entity.startAngle,\n entity.endAngle,\n majorAxisRotation,\n )\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'ARC') {\n // Why on earth DXF has degree start & end angles for arc,\n // and radian start & end angles for ellipses is a mystery\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n entity.r,\n entity.r,\n entity.startAngle,\n entity.endAngle,\n )\n\n // I kid you not, ARCs and ELLIPSEs handle this differently,\n // as evidenced by how AutoCAD actually renders these entities\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'SPLINE') {\n polyline = interpolateBSpline(\n entity.controlPoints,\n entity.degree,\n entity.knots,\n options.interpolationsPerSplineSegment,\n entity.weights,\n )\n }\n\n if (entity.type === 'SOLID' || entity.type === 'TRACE') {\n const corners = entity.corners ?? entity.points\n if (corners && corners.length >= 4) {\n polyline = [\n [corners[0].x, corners[0].y],\n [corners[1].x, corners[1].y],\n [corners[2].x, corners[2].y],\n [corners[3].x, corners[3].y],\n [corners[0].x, corners[0].y],\n ]\n }\n }\n\n if (!polyline) {\n logger.warn('unsupported entity for converting to polyline:', entity.type)\n return []\n }\n return polyline\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["bSpline", "logger", "createArcForLWPolyine"]
7
7
  }
@@ -109,12 +109,95 @@ const polyfaceOutline = (entity) => {
109
109
  function entityToPolyline(entity, options) {
110
110
  options = options || {};
111
111
  let polyline;
112
+ const INFINITE_LINE_LENGTH = 1e3;
113
+ const normalize2 = (x, y) => {
114
+ const len = Math.hypot(x, y);
115
+ if (len === 0) return null;
116
+ return { x: x / len, y: y / len };
117
+ };
112
118
  if (entity.type === "LINE") {
113
119
  polyline = [
114
120
  [entity.start.x, entity.start.y],
115
121
  [entity.end.x, entity.end.y]
116
122
  ];
117
123
  }
124
+ if (entity.type === "LEADER") {
125
+ if (entity.vertices.length >= 2) {
126
+ polyline = entity.vertices.map((v) => [v.x, v.y]);
127
+ } else {
128
+ logger.warn("LEADER entity with insufficient vertices");
129
+ polyline = [];
130
+ }
131
+ }
132
+ if (entity.type === "RAY") {
133
+ const dir = normalize2(entity.direction.x, entity.direction.y);
134
+ if (dir === null) {
135
+ logger.warn("RAY entity with zero direction vector");
136
+ polyline = [];
137
+ } else {
138
+ polyline = [
139
+ [entity.start.x, entity.start.y],
140
+ [
141
+ entity.start.x + dir.x * INFINITE_LINE_LENGTH,
142
+ entity.start.y + dir.y * INFINITE_LINE_LENGTH
143
+ ]
144
+ ];
145
+ }
146
+ }
147
+ if (entity.type === "XLINE") {
148
+ const dir = normalize2(entity.direction.x, entity.direction.y);
149
+ if (dir === null) {
150
+ logger.warn("XLINE entity with zero direction vector");
151
+ polyline = [];
152
+ } else {
153
+ polyline = [
154
+ [
155
+ entity.basePoint.x - dir.x * INFINITE_LINE_LENGTH,
156
+ entity.basePoint.y - dir.y * INFINITE_LINE_LENGTH
157
+ ],
158
+ [
159
+ entity.basePoint.x + dir.x * INFINITE_LINE_LENGTH,
160
+ entity.basePoint.y + dir.y * INFINITE_LINE_LENGTH
161
+ ]
162
+ ];
163
+ }
164
+ }
165
+ if (entity.type === "SHAPE") {
166
+ const x = entity.insertionPoint?.x ?? 0;
167
+ const y = entity.insertionPoint?.y ?? 0;
168
+ const size = entity.size ?? 0;
169
+ const scaleX = entity.relativeXScale ?? 1;
170
+ const length = size * scaleX;
171
+ polyline = [
172
+ [x, y],
173
+ [x + length, y]
174
+ ];
175
+ }
176
+ if (entity.type === "WIPEOUT") {
177
+ const verts = entity.clipBoundaryVertices;
178
+ if (!verts || verts.length < 2) {
179
+ logger.warn("WIPEOUT entity with missing clip boundary vertices");
180
+ polyline = [];
181
+ } else {
182
+ const insX = entity.insertionPoint?.x ?? 0;
183
+ const insY = entity.insertionPoint?.y ?? 0;
184
+ const ux = entity.uVector?.x ?? 1;
185
+ const uy = entity.uVector?.y ?? 0;
186
+ const vx = entity.vVector?.x ?? 0;
187
+ const vy = entity.vVector?.y ?? 1;
188
+ polyline = verts.map((p) => [
189
+ insX + ux * p.x + vx * p.y,
190
+ insY + uy * p.x + vy * p.y
191
+ ]);
192
+ if (polyline.length > 0) {
193
+ const first = polyline[0];
194
+ const last = polyline[polyline.length - 1];
195
+ if (first[0] !== last[0] || first[1] !== last[1]) {
196
+ polyline.push(first);
197
+ }
198
+ }
199
+ }
200
+ }
118
201
  if (entity.type === "LWPOLYLINE" || entity.type === "POLYLINE") {
119
202
  polyline = [];
120
203
  if (entity.polyfaceMesh) {
@@ -199,6 +282,18 @@ function entityToPolyline(entity, options) {
199
282
  entity.weights
200
283
  );
201
284
  }
285
+ if (entity.type === "SOLID" || entity.type === "TRACE") {
286
+ const corners = entity.corners ?? entity.points;
287
+ if (corners && corners.length >= 4) {
288
+ polyline = [
289
+ [corners[0].x, corners[0].y],
290
+ [corners[1].x, corners[1].y],
291
+ [corners[2].x, corners[2].y],
292
+ [corners[3].x, corners[3].y],
293
+ [corners[0].x, corners[0].y]
294
+ ];
295
+ }
296
+ }
202
297
  if (!polyline) {
203
298
  logger.warn("unsupported entity for converting to polyline:", entity.type);
204
299
  return [];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/entityToPolyline.ts"],
4
- "sourcesContent": ["import bSpline from './util/bSpline'\nimport createArcForLWPolyine from './util/createArcForLWPolyline'\nimport logger from './util/logger'\n\nimport type {\n ArcEntity,\n CircleEntity,\n ControlPoint,\n EllipseEntity,\n EntityToPolylineOptions,\n HandlerVertex,\n LineEntity,\n SplineEntity,\n} from './types'\nimport type { PointTuple } from './types/common'\n\n// Re-export types for backward compatibility\nexport type { ControlPoint, EntityToPolylineOptions } from './types'\n\ntype Point = PointTuple\n\n// Local vertex type with required coordinates for runtime processing\ninterface LocalVertex extends HandlerVertex {\n faces?: number[]\n}\n\n// Local polyline type that uses our vertex with required coordinates\ninterface LocalPolylineEntity {\n type: string\n vertices: LocalVertex[]\n closed?: boolean\n polyfaceMesh?: boolean\n polygonMesh?: boolean\n}\n\ntype Entity =\n | LineEntity\n | (LocalPolylineEntity & { type: 'LWPOLYLINE' | 'POLYLINE' })\n | CircleEntity\n | EllipseEntity\n | ArcEntity\n | SplineEntity\n\n/**\n * Rotate a set of points.\n *\n * @param points the points\n * @param angle the rotation angle\n */\nconst rotate = (points: Point[], angle: number): Point[] => {\n return points.map(function (p) {\n return [\n p[0] * Math.cos(angle) - p[1] * Math.sin(angle),\n p[1] * Math.cos(angle) + p[0] * Math.sin(angle),\n ]\n })\n}\n\n/**\n * Interpolate an ellipse\n * @param cx center X\n * @param cy center Y\n * @param rx radius X\n * @param ry radius Y\n * @param start start angle in radians\n * @param start end angle in radians\n */\nconst interpolateEllipse = (\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n start: number,\n end: number,\n rotationAngle?: number\n): Point[] => {\n if (end < start) {\n end += Math.PI * 2\n }\n\n // ----- Relative points -----\n\n // Start point\n let points: Point[] = []\n const dTheta = (Math.PI * 2) / 72\n const EPS = 1e-6\n for (let theta = start; theta < end - EPS; theta += dTheta) {\n points.push([Math.cos(theta) * rx, Math.sin(theta) * ry])\n }\n points.push([Math.cos(end) * rx, Math.sin(end) * ry])\n\n // ----- Rotate -----\n if (rotationAngle) {\n points = rotate(points, rotationAngle)\n }\n\n // ----- Offset center -----\n points = points.map(function (p): Point {\n return [cx + p[0], cy + p[1]]\n })\n\n return points\n}\n\n/**\n * Interpolate a b-spline. The algorithm examins the knot vector\n * to create segments for interpolation. The parameterisation value\n * is re-normalised back to [0,1] as that is what the lib expects (\n * and t i de-normalised in the b-spline library)\n *\n * @param controlPoints the control points\n * @param degree the b-spline degree\n * @param knots the knot vector\n * @returns the polyline\n */\nexport const interpolateBSpline = (\n controlPoints: ControlPoint[],\n degree: number,\n knots: number[],\n interpolationsPerSplineSegment?: number,\n weights?: number[]\n): Point[] => {\n const polyline: Point[] = []\n const controlPointsForLib = controlPoints.map(function (p): Point {\n return [p.x, p.y]\n })\n\n const segmentTs = [knots[degree]]\n const domain: Point = [knots[degree], knots[knots.length - 1 - degree]]\n\n for (let k = degree + 1; k < knots.length - degree; ++k) {\n if (segmentTs[segmentTs.length - 1] !== knots[k]) {\n segmentTs.push(knots[k])\n }\n }\n\n interpolationsPerSplineSegment = interpolationsPerSplineSegment || 25\n for (let i = 1; i < segmentTs.length; ++i) {\n const uMin = segmentTs[i - 1]\n const uMax = segmentTs[i]\n for (let k = 0; k <= interpolationsPerSplineSegment; ++k) {\n const u = (k / interpolationsPerSplineSegment) * (uMax - uMin) + uMin\n // Clamp t to 0, 1 to handle numerical precision issues\n let t = (u - domain[0]) / (domain[1] - domain[0])\n t = Math.max(t, 0)\n t = Math.min(t, 1)\n const p = bSpline(t, degree, controlPointsForLib, knots, weights)\n polyline.push([p[0], p[1]])\n }\n }\n return polyline\n}\n\nexport const polyfaceOutline = (entity: LocalPolylineEntity): Point[][] => {\n const vertices: Array<{ x: number; y: number }> = []\n const faces: Array<{ indices: number[]; hiddens: boolean[] }> = []\n\n for (const v of entity.vertices) {\n if (v.faces) {\n const face: { indices: number[]; hiddens: boolean[] } = {\n indices: [],\n hiddens: [],\n }\n for (const i of v.faces) {\n if (i === 0) {\n break\n }\n // Negative indices signify hidden edges\n face.indices.push(i < 0 ? -i - 1 : i - 1)\n face.hiddens.push(i < 0)\n }\n if ([3, 4].includes(face.indices.length)) faces.push(face)\n } else {\n vertices.push({ x: v.x, y: v.y })\n }\n }\n\n // If a segment starts at the end of a previous line, continue it\n const polylines: number[][] = []\n const segment = (a: number, b: number): void => {\n for (const prev of polylines) {\n if (prev.slice(-1)[0] === a) {\n prev.push(b)\n return\n }\n }\n polylines.push([a, b])\n }\n\n for (const face of faces) {\n for (let beg = 0; beg < face.indices.length; beg++) {\n if (face.hiddens[beg]) {\n continue\n }\n const end = (beg + 1) % face.indices.length\n segment(face.indices[beg], face.indices[end])\n }\n }\n\n // Sometimes segments are not sequential, in that case\n // we need to find if they can mend gaps between others\n for (const a of polylines) {\n for (const b of polylines) {\n if (a !== b && a[0] === b.slice(-1)[0]) {\n b.push(...a.slice(1))\n a.splice(0, a.length)\n break\n }\n }\n }\n\n return polylines\n .filter((l) => l.length)\n .map((l) => l.map((i) => vertices[i]).map((v) => [v.x, v.y]))\n}\n\n/**\n * Convert a parsed DXF entity to a polyline. These can be used to render the\n * the DXF in SVG, Canvas, WebGL etc., without depending on native support\n * of primitive objects (ellispe, spline etc.)\n */\nexport default function entityToPolyline(\n entity: Entity,\n options?: EntityToPolylineOptions,\n): Point[] {\n options = options || {}\n let polyline: Point[] | undefined\n\n if (entity.type === 'LINE') {\n polyline = [\n [entity.start.x, entity.start.y],\n [entity.end.x, entity.end.y],\n ]\n }\n\n if (entity.type === 'LWPOLYLINE' || entity.type === 'POLYLINE') {\n polyline = []\n if (entity.polyfaceMesh) {\n // Only return the first polyline because we can't return many\n polyline.push(...polyfaceOutline(entity)[0])\n } else if (entity.polygonMesh) {\n // Do not attempt to render polygon meshes\n } else if (entity.vertices.length) {\n if (entity.closed) {\n entity.vertices = entity.vertices.concat(entity.vertices[0])\n }\n for (let i = 0, il = entity.vertices.length; i < il - 1; ++i) {\n const from: Point = [entity.vertices[i].x, entity.vertices[i].y]\n const to: Point = [entity.vertices[i + 1].x, entity.vertices[i + 1].y]\n polyline.push(from)\n if (entity.vertices[i].bulge) {\n polyline = polyline.concat(\n createArcForLWPolyine(from, to, entity.vertices[i].bulge!),\n )\n }\n // The last iteration of the for loop\n if (i === il - 2) {\n polyline.push(to)\n }\n }\n } else {\n logger.warn('Polyline entity with no vertices')\n }\n }\n\n if (entity.type === 'CIRCLE') {\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n entity.r,\n entity.r,\n 0,\n Math.PI * 2,\n )\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'ELLIPSE') {\n const rx = Math.hypot(entity.majorX, entity.majorY)\n const ry = entity.axisRatio * rx\n const majorAxisRotation = -Math.atan2(-entity.majorY, entity.majorX)\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n rx,\n ry,\n entity.startAngle,\n entity.endAngle,\n majorAxisRotation,\n )\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'ARC') {\n // Why on earth DXF has degree start & end angles for arc,\n // and radian start & end angles for ellipses is a mystery\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n entity.r,\n entity.r,\n entity.startAngle,\n entity.endAngle,\n )\n\n // I kid you not, ARCs and ELLIPSEs handle this differently,\n // as evidenced by how AutoCAD actually renders these entities\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'SPLINE') {\n polyline = interpolateBSpline(\n entity.controlPoints,\n entity.degree,\n entity.knots,\n options.interpolationsPerSplineSegment,\n entity.weights,\n )\n }\n\n if (!polyline) {\n logger.warn('unsupported entity for converting to polyline:', entity.type)\n return []\n }\n return polyline\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import bSpline from './util/bSpline'\nimport createArcForLWPolyine from './util/createArcForLWPolyline'\nimport logger from './util/logger'\n\nimport type {\n ArcEntity,\n CircleEntity,\n ControlPoint,\n EllipseEntity,\n EntityToPolylineOptions,\n HandlerVertex,\n LeaderEntity,\n LineEntity,\n RayEntity,\n ShapeEntity,\n SplineEntity,\n WipeoutEntity,\n XLineEntity,\n} from './types'\nimport type { PointTuple } from './types/common'\n\n// Re-export types for backward compatibility\nexport type { ControlPoint, EntityToPolylineOptions } from './types'\n\ntype Point = PointTuple\n\n// Local vertex type with required coordinates for runtime processing\ninterface LocalVertex extends HandlerVertex {\n faces?: number[]\n}\n\n// Local polyline type that uses our vertex with required coordinates\ninterface LocalPolylineEntity {\n type: string\n vertices: LocalVertex[]\n closed?: boolean\n polyfaceMesh?: boolean\n polygonMesh?: boolean\n}\n\ntype Entity =\n | LineEntity\n | LeaderEntity\n | RayEntity\n | XLineEntity\n | ShapeEntity\n | WipeoutEntity\n | (LocalPolylineEntity & { type: 'LWPOLYLINE' | 'POLYLINE' })\n | {\n type: 'SOLID' | 'TRACE'\n corners?: Array<{ x: number; y: number }>\n points?: Array<{ x: number; y: number }>\n }\n | CircleEntity\n | EllipseEntity\n | ArcEntity\n | SplineEntity\n\n/**\n * Rotate a set of points.\n *\n * @param points the points\n * @param angle the rotation angle\n */\nconst rotate = (points: Point[], angle: number): Point[] => {\n return points.map(function (p) {\n return [\n p[0] * Math.cos(angle) - p[1] * Math.sin(angle),\n p[1] * Math.cos(angle) + p[0] * Math.sin(angle),\n ]\n })\n}\n\n/**\n * Interpolate an ellipse\n * @param cx center X\n * @param cy center Y\n * @param rx radius X\n * @param ry radius Y\n * @param start start angle in radians\n * @param start end angle in radians\n */\nconst interpolateEllipse = (\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n start: number,\n end: number,\n rotationAngle?: number\n): Point[] => {\n if (end < start) {\n end += Math.PI * 2\n }\n\n // ----- Relative points -----\n\n // Start point\n let points: Point[] = []\n const dTheta = (Math.PI * 2) / 72\n const EPS = 1e-6\n for (let theta = start; theta < end - EPS; theta += dTheta) {\n points.push([Math.cos(theta) * rx, Math.sin(theta) * ry])\n }\n points.push([Math.cos(end) * rx, Math.sin(end) * ry])\n\n // ----- Rotate -----\n if (rotationAngle) {\n points = rotate(points, rotationAngle)\n }\n\n // ----- Offset center -----\n points = points.map(function (p): Point {\n return [cx + p[0], cy + p[1]]\n })\n\n return points\n}\n\n/**\n * Interpolate a b-spline. The algorithm examins the knot vector\n * to create segments for interpolation. The parameterisation value\n * is re-normalised back to [0,1] as that is what the lib expects (\n * and t i de-normalised in the b-spline library)\n *\n * @param controlPoints the control points\n * @param degree the b-spline degree\n * @param knots the knot vector\n * @returns the polyline\n */\nexport const interpolateBSpline = (\n controlPoints: ControlPoint[],\n degree: number,\n knots: number[],\n interpolationsPerSplineSegment?: number,\n weights?: number[]\n): Point[] => {\n const polyline: Point[] = []\n const controlPointsForLib = controlPoints.map(function (p): Point {\n return [p.x, p.y]\n })\n\n const segmentTs = [knots[degree]]\n const domain: Point = [knots[degree], knots[knots.length - 1 - degree]]\n\n for (let k = degree + 1; k < knots.length - degree; ++k) {\n if (segmentTs[segmentTs.length - 1] !== knots[k]) {\n segmentTs.push(knots[k])\n }\n }\n\n interpolationsPerSplineSegment = interpolationsPerSplineSegment || 25\n for (let i = 1; i < segmentTs.length; ++i) {\n const uMin = segmentTs[i - 1]\n const uMax = segmentTs[i]\n for (let k = 0; k <= interpolationsPerSplineSegment; ++k) {\n const u = (k / interpolationsPerSplineSegment) * (uMax - uMin) + uMin\n // Clamp t to 0, 1 to handle numerical precision issues\n let t = (u - domain[0]) / (domain[1] - domain[0])\n t = Math.max(t, 0)\n t = Math.min(t, 1)\n const p = bSpline(t, degree, controlPointsForLib, knots, weights)\n polyline.push([p[0], p[1]])\n }\n }\n return polyline\n}\n\nexport const polyfaceOutline = (entity: LocalPolylineEntity): Point[][] => { // NOSONAR\n const vertices: Array<{ x: number; y: number }> = []\n const faces: Array<{ indices: number[]; hiddens: boolean[] }> = []\n\n for (const v of entity.vertices) {\n if (v.faces) {\n const face: { indices: number[]; hiddens: boolean[] } = {\n indices: [],\n hiddens: [],\n }\n for (const i of v.faces) {\n if (i === 0) {\n break\n }\n // Negative indices signify hidden edges\n face.indices.push(i < 0 ? -i - 1 : i - 1)\n face.hiddens.push(i < 0)\n }\n if ([3, 4].includes(face.indices.length)) faces.push(face)\n } else {\n vertices.push({ x: v.x, y: v.y })\n }\n }\n\n // If a segment starts at the end of a previous line, continue it\n const polylines: number[][] = []\n const segment = (a: number, b: number): void => {\n for (const prev of polylines) {\n if (prev.slice(-1)[0] === a) {\n prev.push(b)\n return\n }\n }\n polylines.push([a, b])\n }\n\n for (const face of faces) {\n for (let beg = 0; beg < face.indices.length; beg++) {\n if (face.hiddens[beg]) {\n continue\n }\n const end = (beg + 1) % face.indices.length\n segment(face.indices[beg], face.indices[end])\n }\n }\n\n // Sometimes segments are not sequential, in that case\n // we need to find if they can mend gaps between others\n for (const a of polylines) {\n for (const b of polylines) {\n if (a !== b && a[0] === b.slice(-1)[0]) {\n b.push(...a.slice(1))\n a.splice(0, a.length)\n break\n }\n }\n }\n\n return polylines\n .filter((l) => l.length)\n .map((l) => l.map((i) => vertices[i]).map((v) => [v.x, v.y]))\n}\n\n/**\n * Convert a parsed DXF entity to a polyline. These can be used to render the\n * the DXF in SVG, Canvas, WebGL etc., without depending on native support\n * of primitive objects (ellispe, spline etc.)\n */\nexport default function entityToPolyline( // NOSONAR\n entity: Entity,\n options?: EntityToPolylineOptions,\n): Point[] {\n options = options || {}\n let polyline: Point[] | undefined\n\n const INFINITE_LINE_LENGTH = 1000\n\n const normalize2 = (x: number, y: number): { x: number; y: number } | null => {\n const len = Math.hypot(x, y)\n if (len === 0) return null\n return { x: x / len, y: y / len }\n }\n\n if (entity.type === 'LINE') {\n polyline = [\n [entity.start.x, entity.start.y],\n [entity.end.x, entity.end.y],\n ]\n }\n\n if (entity.type === 'LEADER') {\n if (entity.vertices.length >= 2) {\n polyline = entity.vertices.map((v) => [v.x, v.y])\n } else {\n logger.warn('LEADER entity with insufficient vertices')\n polyline = []\n }\n }\n\n if (entity.type === 'RAY') {\n const dir = normalize2(entity.direction.x, entity.direction.y)\n if (dir === null) {\n logger.warn('RAY entity with zero direction vector')\n polyline = []\n } else {\n polyline = [\n [entity.start.x, entity.start.y],\n [\n entity.start.x + dir.x * INFINITE_LINE_LENGTH,\n entity.start.y + dir.y * INFINITE_LINE_LENGTH,\n ],\n ]\n }\n }\n\n if (entity.type === 'XLINE') {\n const dir = normalize2(entity.direction.x, entity.direction.y)\n if (dir === null) {\n logger.warn('XLINE entity with zero direction vector')\n polyline = []\n } else {\n polyline = [\n [\n entity.basePoint.x - dir.x * INFINITE_LINE_LENGTH,\n entity.basePoint.y - dir.y * INFINITE_LINE_LENGTH,\n ],\n [\n entity.basePoint.x + dir.x * INFINITE_LINE_LENGTH,\n entity.basePoint.y + dir.y * INFINITE_LINE_LENGTH,\n ],\n ]\n }\n }\n\n if (entity.type === 'SHAPE') {\n const x = entity.insertionPoint?.x ?? 0\n const y = entity.insertionPoint?.y ?? 0\n const size = entity.size ?? 0\n const scaleX = entity.relativeXScale ?? 1\n const length = size * scaleX\n polyline = [\n [x, y],\n [x + length, y],\n ]\n }\n\n if (entity.type === 'WIPEOUT') {\n const verts = entity.clipBoundaryVertices\n if (!verts || verts.length < 2) {\n logger.warn('WIPEOUT entity with missing clip boundary vertices')\n polyline = []\n } else {\n const insX = entity.insertionPoint?.x ?? 0\n const insY = entity.insertionPoint?.y ?? 0\n\n const ux = entity.uVector?.x ?? 1\n const uy = entity.uVector?.y ?? 0\n\n const vx = entity.vVector?.x ?? 0\n const vy = entity.vVector?.y ?? 1\n\n polyline = verts.map((p) => [\n insX + ux * p.x + vx * p.y,\n insY + uy * p.x + vy * p.y,\n ])\n\n if (polyline.length > 0) {\n const first = polyline[0]\n const last = polyline[polyline.length - 1]\n if (first[0] !== last[0] || first[1] !== last[1]) {\n polyline.push(first)\n }\n }\n }\n }\n\n if (entity.type === 'LWPOLYLINE' || entity.type === 'POLYLINE') {\n polyline = []\n if (entity.polyfaceMesh) {\n // Only return the first polyline because we can't return many\n polyline.push(...polyfaceOutline(entity)[0])\n } else if (entity.polygonMesh) {\n // Do not attempt to render polygon meshes\n } else if (entity.vertices.length) {\n if (entity.closed) {\n entity.vertices = entity.vertices.concat(entity.vertices[0])\n }\n for (let i = 0, il = entity.vertices.length; i < il - 1; ++i) {\n const from: Point = [entity.vertices[i].x, entity.vertices[i].y]\n const to: Point = [entity.vertices[i + 1].x, entity.vertices[i + 1].y]\n polyline.push(from)\n if (entity.vertices[i].bulge) {\n polyline = polyline.concat(\n createArcForLWPolyine(from, to, entity.vertices[i].bulge!),\n )\n }\n // The last iteration of the for loop\n if (i === il - 2) {\n polyline.push(to)\n }\n }\n } else {\n logger.warn('Polyline entity with no vertices')\n }\n }\n\n if (entity.type === 'CIRCLE') {\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n entity.r,\n entity.r,\n 0,\n Math.PI * 2,\n )\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'ELLIPSE') {\n const rx = Math.hypot(entity.majorX, entity.majorY)\n const ry = entity.axisRatio * rx\n const majorAxisRotation = -Math.atan2(-entity.majorY, entity.majorX)\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n rx,\n ry,\n entity.startAngle,\n entity.endAngle,\n majorAxisRotation,\n )\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'ARC') {\n // Why on earth DXF has degree start & end angles for arc,\n // and radian start & end angles for ellipses is a mystery\n polyline = interpolateEllipse(\n entity.x,\n entity.y,\n entity.r,\n entity.r,\n entity.startAngle,\n entity.endAngle,\n )\n\n // I kid you not, ARCs and ELLIPSEs handle this differently,\n // as evidenced by how AutoCAD actually renders these entities\n if (entity.extrusionZ === -1) {\n polyline = polyline.map(function (p): Point {\n return [-p[0], p[1]]\n })\n }\n }\n\n if (entity.type === 'SPLINE') {\n polyline = interpolateBSpline(\n entity.controlPoints,\n entity.degree,\n entity.knots,\n options.interpolationsPerSplineSegment,\n entity.weights,\n )\n }\n\n if (entity.type === 'SOLID' || entity.type === 'TRACE') {\n const corners = entity.corners ?? entity.points\n if (corners && corners.length >= 4) {\n polyline = [\n [corners[0].x, corners[0].y],\n [corners[1].x, corners[1].y],\n [corners[2].x, corners[2].y],\n [corners[3].x, corners[3].y],\n [corners[0].x, corners[0].y],\n ]\n }\n }\n\n if (!polyline) {\n logger.warn('unsupported entity for converting to polyline:', entity.type)\n return []\n }\n return polyline\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }