ofs-dxf-ts 1.0.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 (97) hide show
  1. package/API.md +411 -0
  2. package/CHANGELOG.md +26 -0
  3. package/LICENSE +21 -0
  4. package/README.md +119 -0
  5. package/dist/core/dxf-builder.d.ts +348 -0
  6. package/dist/core/dxf-builder.js +549 -0
  7. package/dist/core/dxf-document.d.ts +220 -0
  8. package/dist/core/dxf-document.js +529 -0
  9. package/dist/core/dxf-entities.d.ts +327 -0
  10. package/dist/core/dxf-entities.js +22 -0
  11. package/dist/core/dxf-serializer.d.ts +48 -0
  12. package/dist/core/dxf-serializer.js +595 -0
  13. package/dist/core/hatch-patterns.d.ts +15 -0
  14. package/dist/core/hatch-patterns.js +214 -0
  15. package/dist/core/modelspace.d.ts +106 -0
  16. package/dist/core/modelspace.js +351 -0
  17. package/dist/geometry/math.utils.d.ts +8 -0
  18. package/dist/geometry/math.utils.js +43 -0
  19. package/dist/geometry/offset.utils.d.ts +32 -0
  20. package/dist/geometry/offset.utils.js +87 -0
  21. package/dist/geometry/polyline.utils.d.ts +10 -0
  22. package/dist/geometry/polyline.utils.js +63 -0
  23. package/dist/geometry/text.utils.d.ts +15 -0
  24. package/dist/geometry/text.utils.js +28 -0
  25. package/dist/index.d.ts +23 -0
  26. package/dist/index.js +29 -0
  27. package/dist/parser/auto-cad-color-index.d.ts +8 -0
  28. package/dist/parser/auto-cad-color-index.js +265 -0
  29. package/dist/parser/dim-style-codes.d.ts +5 -0
  30. package/dist/parser/dim-style-codes.js +32 -0
  31. package/dist/parser/dxf-parser.d.ts +16 -0
  32. package/dist/parser/dxf-parser.js +824 -0
  33. package/dist/parser/entities/3dface.d.ts +5 -0
  34. package/dist/parser/entities/3dface.js +76 -0
  35. package/dist/parser/entities/arc.d.ts +5 -0
  36. package/dist/parser/entities/arc.js +34 -0
  37. package/dist/parser/entities/attdef.d.ts +5 -0
  38. package/dist/parser/entities/attdef.js +86 -0
  39. package/dist/parser/entities/attribute.d.ts +5 -0
  40. package/dist/parser/entities/attribute.js +106 -0
  41. package/dist/parser/entities/circle.d.ts +5 -0
  42. package/dist/parser/entities/circle.js +40 -0
  43. package/dist/parser/entities/dimension.d.ts +5 -0
  44. package/dist/parser/entities/dimension.js +65 -0
  45. package/dist/parser/entities/ellipse.d.ts +5 -0
  46. package/dist/parser/entities/ellipse.js +42 -0
  47. package/dist/parser/entities/hatch.d.ts +5 -0
  48. package/dist/parser/entities/hatch.js +321 -0
  49. package/dist/parser/entities/insert.d.ts +5 -0
  50. package/dist/parser/entities/insert.js +52 -0
  51. package/dist/parser/entities/line.d.ts +5 -0
  52. package/dist/parser/entities/line.js +30 -0
  53. package/dist/parser/entities/lwpolyline.d.ts +5 -0
  54. package/dist/parser/entities/lwpolyline.js +101 -0
  55. package/dist/parser/entities/mtext.d.ts +5 -0
  56. package/dist/parser/entities/mtext.js +54 -0
  57. package/dist/parser/entities/point.d.ts +5 -0
  58. package/dist/parser/entities/point.js +30 -0
  59. package/dist/parser/entities/polyline.d.ts +5 -0
  60. package/dist/parser/entities/polyline.js +85 -0
  61. package/dist/parser/entities/solid.d.ts +5 -0
  62. package/dist/parser/entities/solid.js +35 -0
  63. package/dist/parser/entities/spline.d.ts +5 -0
  64. package/dist/parser/entities/spline.js +69 -0
  65. package/dist/parser/entities/text.d.ts +5 -0
  66. package/dist/parser/entities/text.js +47 -0
  67. package/dist/parser/entities/vertex.d.ts +5 -0
  68. package/dist/parser/entities/vertex.js +59 -0
  69. package/dist/parser/extended-data-parser.d.ts +18 -0
  70. package/dist/parser/extended-data-parser.js +100 -0
  71. package/dist/parser/index.d.ts +10 -0
  72. package/dist/parser/index.js +9 -0
  73. package/dist/parser/log.d.ts +14 -0
  74. package/dist/parser/log.js +39 -0
  75. package/dist/parser/parse-helpers.d.ts +23 -0
  76. package/dist/parser/parse-helpers.js +128 -0
  77. package/dist/parser/scanner.d.ts +29 -0
  78. package/dist/parser/scanner.js +143 -0
  79. package/dist/parser/types.d.ts +78 -0
  80. package/dist/parser/types.js +5 -0
  81. package/dist/symbols/slope-symbol.d.ts +21 -0
  82. package/dist/symbols/slope-symbol.js +81 -0
  83. package/dist/symbols/structures.d.ts +9 -0
  84. package/dist/symbols/structures.js +120 -0
  85. package/dist/template/blank-document.d.ts +13 -0
  86. package/dist/template/blank-document.js +13 -0
  87. package/dist/template/block-registry.d.ts +16 -0
  88. package/dist/template/block-registry.js +135 -0
  89. package/dist/template/index.d.ts +17 -0
  90. package/dist/template/index.js +17 -0
  91. package/dist/template/template-injector.d.ts +45 -0
  92. package/dist/template/template-injector.js +487 -0
  93. package/dist/template/template-reader.d.ts +28 -0
  94. package/dist/template/template-reader.js +80 -0
  95. package/dist/types/index.d.ts +24 -0
  96. package/dist/types/index.js +8 -0
  97. package/package.json +59 -0
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Built-in hatch pattern definitions (ISO, millimetre based — as in acadiso.pat).
3
+ *
4
+ * Each line is `[angle, [baseX, baseY], [offsetX, offsetY], dashes]` exactly as
5
+ * stored in a DXF HATCH (group codes 53 / 43,44 / 45,46 / 49): the offset vector
6
+ * is already in world orientation. Scale/rotation are applied at serialization.
7
+ *
8
+ * A curated subset of ezdxf's ISO pattern table (MIT). Pass your own
9
+ * definition via `addHatch(..., { patternLines })` for anything not listed.
10
+ *
11
+ * GENERATED by tools/gen_hatch_patterns.py — do not edit by hand.
12
+ */
13
+ export const HATCH_PATTERNS = {
14
+ 'ANGLE': [
15
+ [0, [0, 0], [0, 13.97], [10.16, -3.81]],
16
+ [90, [0, 0], [-13.97, 0], [10.16, -3.81]],
17
+ ],
18
+ 'ANSI31': [
19
+ [45, [0, 0], [-2.2450640303, 2.2450640303], []],
20
+ ],
21
+ 'ANSI32': [
22
+ [45, [0, 0], [-6.7351920908, 6.7351920908], []],
23
+ [45, [4.490128053, 0], [-6.7351920908, 6.7351920908], []],
24
+ ],
25
+ 'ANSI33': [
26
+ [45, [0, 0], [-4.4901280605, 4.4901280605], []],
27
+ [45, [4.490128053, 0], [-4.4901280605, 4.4901280605], [3.175, -1.5875]],
28
+ ],
29
+ 'ANSI34': [
30
+ [45, [0, 0], [-13.4703841816, 13.4703841816], []],
31
+ [45, [4.490128053, 0], [-13.4703841816, 13.4703841816], []],
32
+ [45, [8.9802561314, 0], [-13.4703841816, 13.4703841816], []],
33
+ [45, [13.4703841844, 0], [-13.4703841816, 13.4703841816], []],
34
+ ],
35
+ 'ANSI35': [
36
+ [45, [0, 0], [-4.4901280605, 4.4901280605], []],
37
+ [45, [4.490128053, 0], [-4.4901280605, 4.4901280605], [7.9375, -1.5875, 0, -1.5875]],
38
+ ],
39
+ 'ANSI36': [
40
+ [45, [0, 0], [1.6837980227, 6.1739260832], [7.9375, -1.5875, 0, -1.5875]],
41
+ ],
42
+ 'ANSI37': [
43
+ [45, [0, 0], [-2.2450640303, 2.2450640303], []],
44
+ [135, [0, 0], [-2.2450640303, -2.2450640303], []],
45
+ ],
46
+ 'ANSI38': [
47
+ [45, [0, 0], [-2.2450640303, 2.2450640303], []],
48
+ [135, [0, 0], [-6.7351920908, 2.2450640303], [7.9375, -4.7625]],
49
+ ],
50
+ 'AR-CONC': [
51
+ [50, [0, 0], [182.184668996, -15.9390855389], [19.05, -209.55]],
52
+ [355, [0, 0], [-35.243421425, 191.056845239], [15.24, -167.64058417]],
53
+ [100.4514447, [15.182007, -1.3282535], [146.9412470904, 175.1177519122], [16.1900088, -178.0902446]],
54
+ [46.1842, [0, 50.8], [271.0790408921, -42.0423279327], [28.575, -314.325]],
55
+ [96.63555761, [22.5899, 47.2965], [237.4041340515, 247.4261245977], [24.28502314, -267.13560816]],
56
+ [351.18415117, [0, 50.8], [237.404134065, 247.4261245855], [22.85996707, -251.45973192]],
57
+ [21, [25.4, 38.1], [151.6143912691, -102.2651981871], [19.05, -209.55]],
58
+ [326, [25.4, 38.1], [61.8020283476, 184.1879661223], [15.24, -167.64]],
59
+ [71.451445, [38.0345326, 29.5779001], [213.4164192787, 81.9227688859], [16.1900088, -178.0899376]],
60
+ [37.5, [0, 0], [3.0886032506, 84.5550388732], [0, -165.608, 0, -170.18, 0, -168.275]],
61
+ [7.5, [0, 0], [66.8196625103, 100.1805748181], [0, -97.028, 0, -161.798, 0, -64.135]],
62
+ [-32.5, [-56.642, 0], [135.5905951669, -5.7287439927], [0, -63.5, 0, -198.12, 0, -262.89]],
63
+ [-42.5, [-82.042, 0], [148.129181386, 25.4264910333], [0, -82.55, 0, -131.572, 0, -186.69]],
64
+ ],
65
+ 'AR-SAND': [
66
+ [37.5, [0, 0], [-1.600031296, 48.9413237329], [0, -38.608, 0, -43.18, 0, -41.275]],
67
+ [7.5, [0, 0], [44.9523283138, 71.6825100568], [0, -20.828, 0, -34.798, 0, -13.335]],
68
+ [-32.5, [-31.242, 0], [79.0992370241, 0.1437184679], [0, -12.7, 0, -45.72, 0, -59.69]],
69
+ [-42.5, [-31.242, 0], [76.3556452472, 22.2929323257], [0, -6.35, 0, -29.972, 0, -34.29]],
70
+ ],
71
+ 'BOX': [
72
+ [90, [0, 0], [-25.4, 0], []],
73
+ [90, [6.35, 0], [-25.4, 0], []],
74
+ [0, [0, 0], [0, 25.4], [-6.35, 6.35]],
75
+ [0, [0, 6.35], [0, 25.4], [-6.35, 6.35]],
76
+ [0, [0, 12.7], [0, 25.4], [6.35, -6.35]],
77
+ [0, [0, 19.05], [0, 25.4], [6.35, -6.35]],
78
+ [90, [12.7, 0], [-25.4, 0], [6.35, -6.35]],
79
+ [90, [19.05, 0], [-25.4, 0], [6.35, -6.35]],
80
+ ],
81
+ 'BRICK': [
82
+ [0, [0, 0], [0, 6.35], []],
83
+ [90, [0, 0], [-12.7, 0], [6.35, -6.35]],
84
+ [90, [6.35, 0], [-12.7, 0], [-6.35, 6.35]],
85
+ ],
86
+ 'CROSS': [
87
+ [0, [0, 0], [6.35, 6.35], [3.175, -9.525]],
88
+ [90, [1.5875, -1.5875], [-6.35, 6.35], [3.175, -9.525]],
89
+ ],
90
+ 'DASH': [
91
+ [0, [0, 0], [3.175, 3.175], [3.175, -3.175]],
92
+ ],
93
+ 'DOTS': [
94
+ [0, [0, 0], [0.79375, 1.5875], [0, -1.5875]],
95
+ ],
96
+ 'EARTH': [
97
+ [0, [0, 0], [6.35, 6.35], [6.35, -6.35]],
98
+ [0, [0, 2.38125], [6.35, 6.35], [6.35, -6.35]],
99
+ [0, [0, 4.7625], [6.35, 6.35], [6.35, -6.35]],
100
+ [90, [0.79375, 5.55625], [-6.35, 6.35], [6.35, -6.35]],
101
+ [90, [3.175, 5.55625], [-6.35, 6.35], [6.35, -6.35]],
102
+ [90, [5.55625, 5.55625], [-6.35, 6.35], [6.35, -6.35]],
103
+ ],
104
+ 'GRASS': [
105
+ [90, [0, 0], [-17.96051224, 17.96051224], [4.7625, -31.15852448]],
106
+ [45, [0, 0], [-17.9605122421, 17.9605122421], [4.7625, -20.6375]],
107
+ [135, [0, 0], [-17.9605122421, -17.9605122421], [4.7625, -20.6375]],
108
+ ],
109
+ 'GRATE': [
110
+ [0, [0, 0], [0, 0.79375], []],
111
+ [90, [0, 0], [-3.175, 0], []],
112
+ ],
113
+ 'GRAVEL': [
114
+ [228.0127875, [18.288, 25.4], [-203.200000016, -228.5999999858], [3.4172144, -338.3048363956]],
115
+ [184.969741, [16.002, 22.86], [304.7999998794, 25.400001447], [5.8640472, -580.5404889352]],
116
+ [132.5104471, [10.16, 22.352], [254.0000001073, -279.3999999025], [4.1348152, -409.347227941]],
117
+ [267.273689, [0.254, 16.002], [25.4000000532, 507.9999999973], [5.3400452, -528.6643742574]],
118
+ [292.83365418, [0, 10.668], [-127.0000000106, 304.7999999956], [5.236337, -518.3980774534]],
119
+ [357.273689, [2.032, 5.842], [-507.9999999973, 25.4000000532], [5.3400452, -528.6643742574]],
120
+ [37.69424047, [7.366, 5.588], [-330.1999999854, -254.000000019], [7.0619366, -699.1311531425]],
121
+ [72.25532837, [12.954, 9.906], [177.8000000478, 558.7999999848], [6.6671952, -660.0525660191]],
122
+ [121.42956562, [14.986, 16.256], [-203.2000000288, 330.1999999823], [5.35813, -530.4554569871]],
123
+ [175.2363583, [12.192, 20.828], [279.399999996, -25.4000000439], [6.1171328, -299.7393695]],
124
+ [222.3974378, [6.096, 21.336], [-304.7999999902, -279.4000000106], [7.9107792, -783.1677251218]],
125
+ [138.81407483, [25.4, 15.748], [-177.7999999893, 152.4000000124], [2.7000454, -267.3056582434]],
126
+ [171.4692344, [23.368, 17.526], [330.2000000089, -50.7999999424], [5.1368198, -508.5463899704]],
127
+ [225, [18.288, 18.288], [0, -25.4], [3.5920934, -32.3289310843]],
128
+ [203.19859051, [16.51, 21.336], [127.0000000035, 50.7999999911], [1.9344132, -191.5062236889]],
129
+ [291.80140949, [14.732, 20.574], [-25.4000000053, 76.1999999982], [2.7356562, -134.0475299]],
130
+ [30.96375653, [15.748, 18.034], [76.2000000019, 50.7999999972], [4.4431966, -143.6629815291]],
131
+ [161.56505118, [19.558, 20.32], [50.8000000013, -25.3999999973], [3.2128714, -77.1089811683]],
132
+ [16.389540334, [0, 20.574], [254, 76.2], [4.50088, -445.5882667254]],
133
+ [70.34617594, [4.318, 21.844], [-101.6000000093, -279.3999999967], [3.7759894, -373.822156782]],
134
+ [293.19859051, [19.558, 25.4], [-50.7999999911, 127.0000000036], [3.868801, -189.5718358889]],
135
+ [343.61045967, [21.082, 21.844], [-254.0000000053, 76.1999999822], [4.50088, -445.5882667254]],
136
+ [339.44395478, [0, 4.826], [-127, 50.8], [4.340352, -212.6773431311]],
137
+ [294.7751406, [4.064, 3.302], [-127.0000001512, 279.3999999313], [3.6367212, -360.0359338072]],
138
+ [66.80140949, [19.812, 0], [50.799999992, 127.0000000032], [3.868801, -189.5718358889]],
139
+ [17.35402464, [21.336, 3.556], [-330.1999999934, -101.6000000213], [4.2578274, -421.523759802]],
140
+ [69.44395478, [7.366, 0], [-50.8000000009, -126.9999999996], [2.170176, -214.8475191311]],
141
+ [101.309932474, [18.288, 0], [-25.4, 101.6], [1.295146, -128.2199496453]],
142
+ [165.963756532, [18.034, 1.27], [76.2, -25.4], [5.236337, -99.4905458907]],
143
+ [186.00900596, [12.954, 2.54], [253.9999999987, 25.4000000133], [4.85267, -480.4136486334]],
144
+ [303.69006753, [15.748, 15.748], [-25.4000000035, 50.7999999982], [3.6632388, -87.9177635968]],
145
+ [353.15722659, [17.78, 12.7], [431.8000000027, -50.7999999774], [6.3955676, -633.1600906503]],
146
+ [60.9453959, [24.13, 11.938], [-101.6000000028, -177.7999999984], [2.6150824, -258.8939231811]],
147
+ [90, [25.4, 14.224], [-25.4, 25.4], [1.524, -23.876]],
148
+ [120.25643716, [12.446, 3.302], [101.5999999876, -177.8000000071], [3.5286696, -349.339407732]],
149
+ [48.0127875, [10.668, 6.35], [203.2000000168, 228.5999999851], [6.8344288, -334.8876219957]],
150
+ [0, [15.24, 11.43], [25.4, 25.4], [6.604, -18.796]],
151
+ [325.3048465, [21.844, 11.43], [254.0000000962, -177.7999998625], [4.0160956, -397.5931672414]],
152
+ [254.0546041, [25.146, 9.144], [-25.3999999982, -101.6000000004], [3.6982908, -181.2165003877]],
153
+ [207.64597536, [24.13, 5.588], [-482.6000000177, -253.9999999663], [6.021451, -596.1246442294]],
154
+ [175.42607874, [18.796, 2.794], [-330.2, 25.4], [6.3702946, -630.6584645624]],
155
+ ],
156
+ 'HEX': [
157
+ [0, [0, 0], [0, 5.4992613154], [3.175, -6.35]],
158
+ [120, [0, 0], [-4.7625000012, -2.7496306577], [3.175, -6.35]],
159
+ [60, [3.175, 0], [-4.7625000012, 2.7496306577], [3.175, -6.35]],
160
+ ],
161
+ 'HONEY': [
162
+ [0, [0, 0], [4.7625, 2.749630645], [3.175, -6.35]],
163
+ [120, [0, 0], [-4.7624999896, 2.749630663], [3.175, -6.35]],
164
+ [60, [0, 0], [1.04e-08, 5.499261308], [-6.35, 3.175]],
165
+ ],
166
+ 'INSUL': [
167
+ [0, [0, 0], [0, 9.525], []],
168
+ [0, [0, 3.175], [0, 9.525], [3.175, -3.175]],
169
+ [0, [0, 6.35], [0, 9.525], [3.175, -3.175]],
170
+ ],
171
+ 'LINE': [
172
+ [0, [0, 0], [0, 3.175], []],
173
+ ],
174
+ 'NET': [
175
+ [0, [0, 0], [0, 3.175], []],
176
+ [90, [0, 0], [-3.175, 0], []],
177
+ ],
178
+ 'NET3': [
179
+ [0, [0, 0], [0, 3.175], []],
180
+ [60, [0, 0], [-2.749630657, 1.5875], []],
181
+ [120, [0, 0], [-2.749630657, -1.5875], []],
182
+ ],
183
+ 'PLAST': [
184
+ [0, [0, 0], [0, 6.35], []],
185
+ [0, [0, 0.79375], [0, 6.35], []],
186
+ [0, [0, 1.5875], [0, 6.35], []],
187
+ ],
188
+ 'SQUARE': [
189
+ [0, [0, 0], [0, 3.175], [3.175, -3.175]],
190
+ [90, [0, 0], [-3.175, 0], [3.175, -3.175]],
191
+ ],
192
+ 'STARS': [
193
+ [0, [0, 0], [0, 5.4992613154], [3.175, -3.175]],
194
+ [60, [0, 0], [-4.7625000012, 2.7496306577], [3.175, -3.175]],
195
+ [120, [1.5875, 2.7496306704], [-4.7625000012, -2.7496306577], [3.175, -3.175]],
196
+ ],
197
+ 'SWAMP': [
198
+ [0, [0, 0], [12.7, 21.9970452362], [3.175, -22.225]],
199
+ [90, [1.5875, 0], [-12.7, 21.9970452362], [1.5875, -42.4065904724]],
200
+ [90, [1.984375, 0], [-12.7, 21.9970452362], [1.27, -42.7240904724]],
201
+ [90, [1.190625, 0], [-12.7, 21.9970452362], [1.27, -42.7240904724]],
202
+ [60, [2.38125, 0], [-12.6999999827, 21.9970452462], [1.016, -24.384]],
203
+ [120, [0.79375, 0], [-25.3999999827, 1e-08], [1.016, -24.384]],
204
+ ],
205
+ 'TRIANG': [
206
+ [60, [0, 0], [-4.7624999908, 8.2488919657], [4.7625, -4.7625]],
207
+ [120, [0, 0], [-9.5249999908, 5.3e-09], [4.7625, -4.7625]],
208
+ [0, [-2.38125, 4.1244459802], [4.7625, 8.2488919604], [4.7625, -4.7625]],
209
+ ],
210
+ 'ZIGZAG': [
211
+ [0, [0, 0], [6.35, 6.35], [6.35, -6.35]],
212
+ [90, [6.35, 0], [-6.35, 6.35], [6.35, -6.35]],
213
+ ],
214
+ };
@@ -0,0 +1,106 @@
1
+ import { DxfEntity, LineEntity, LwPolylineEntity, PolylineEntity, CircleEntity, ArcEntity, EllipseEntity, TextEntity, MTextEntity, InsertEntity, PointEntity, SolidEntity, TraceEntity, SplineEntity, HatchEntity, HatchBoundary, DimensionEntity, LeaderEntity, ViewportEntity, ImageEntity, WipeoutEntity, RegionEntity, MeshEntity, MLeaderEntity, TableDef, DxfAttribs, TextAttribs, BlockRefAttribs, TextEntityAlignment } from './dxf-entities.js';
2
+ import { HatchPatternLine } from './hatch-patterns.js';
3
+ /**
4
+ * An entity collector — used for model space, paper space layouts and block
5
+ * definitions alike.
6
+ */
7
+ export declare class Modelspace {
8
+ private _entities;
9
+ get entities(): DxfEntity[];
10
+ add_line(start: [number, number], end: [number, number], dxfattribs?: DxfAttribs): LineEntity;
11
+ add_lwpolyline(points: [number, number][], dxfattribs?: DxfAttribs, close?: boolean): LwPolylineEntity;
12
+ add_polyline(points: [number, number, number][], dxfattribs?: DxfAttribs, close?: boolean): PolylineEntity;
13
+ add_circle(center: [number, number], radius: number, dxfattribs?: DxfAttribs): CircleEntity;
14
+ add_arc(center: [number, number], radius: number, startAngle: number, endAngle: number, dxfattribs?: DxfAttribs): ArcEntity;
15
+ add_ellipse(center: [number, number], majorAxis: [number, number], ratio: number, startParam?: number, endParam?: number, dxfattribs?: DxfAttribs): EllipseEntity;
16
+ add_point(location: [number, number], dxfattribs?: DxfAttribs): PointEntity;
17
+ add_solid(points: [[number, number], [number, number], [number, number], [number, number]], dxfattribs?: DxfAttribs): SolidEntity;
18
+ add_trace(points: [[number, number], [number, number], [number, number], [number, number]], dxfattribs?: DxfAttribs): TraceEntity;
19
+ add_text(text: string, dxfattribs?: TextAttribs): {
20
+ set_placement: (pos: [number, number], align?: TextEntityAlignment) => TextEntity;
21
+ };
22
+ add_mtext(text: string, dxfattribs?: TextAttribs & {
23
+ width?: number;
24
+ attachment_point?: number;
25
+ }): MTextEntity;
26
+ add_blockref(blockName: string, insert: [number, number], dxfattribs?: BlockRefAttribs): InsertEntity;
27
+ add_spline(controlPoints: [number, number][], degree?: number, dxfattribs?: DxfAttribs, opts?: {
28
+ fitPoints?: [number, number][];
29
+ knots?: number[];
30
+ weights?: number[];
31
+ closed?: boolean;
32
+ }): SplineEntity;
33
+ /**
34
+ * Add a HATCH. Pattern names resolve against the built-in HATCH_PATTERNS
35
+ * (ISO, mm based) unless `opts.patternLines` supplies a custom definition.
36
+ */
37
+ add_hatch(patternName: string | undefined, boundaries: HatchBoundary[], dxfattribs?: DxfAttribs, opts?: {
38
+ solid?: boolean;
39
+ scale?: number;
40
+ angle?: number;
41
+ patternLines?: HatchPatternLine[];
42
+ }): HatchEntity;
43
+ add_dimension(point1: [number, number], point2: [number, number], dimLine: [number, number], dxfattribs?: DxfAttribs & {
44
+ text?: string;
45
+ rotation?: number;
46
+ style?: string;
47
+ dimensionType?: number;
48
+ }): DimensionEntity;
49
+ add_leader(vertices: [number, number][], dxfattribs?: DxfAttribs & {
50
+ style?: string;
51
+ has_arrowhead?: boolean;
52
+ annotation_type?: number;
53
+ annotation_text?: string;
54
+ }): LeaderEntity;
55
+ /**
56
+ * Add a MULTILEADER entity (modern annotation — AutoCAD 2008+).
57
+ * Combines leader line with MTEXT content.
58
+ *
59
+ * @deprecated The MULTILEADER written for this entity is incomplete and is
60
+ * not read reliably by AutoCAD. Use `DxfBuilder.addCallout()` instead.
61
+ */
62
+ add_mleader(vertices: [number, number][], text: string, textPosition: [number, number], dxfattribs?: DxfAttribs & {
63
+ text_height?: number;
64
+ text_width?: number;
65
+ arrow_size?: number;
66
+ style?: string;
67
+ dogleg_length?: number;
68
+ leader_type?: number;
69
+ content_type?: number;
70
+ }): MLeaderEntity;
71
+ /**
72
+ * Add a TABLE as composite LINE + TEXT entities.
73
+ * Note: DXF ACAD_TABLE is extremely complex; this draws a visual table
74
+ * using primitive entities for maximum compatibility.
75
+ *
76
+ * Cells may span columns/rows (`colSpan` / `rowSpan`); grid lines inside a
77
+ * merged cell are omitted.
78
+ */
79
+ add_table(tableDef: TableDef): void;
80
+ add_viewport(center: [number, number], width: number, height: number, viewCenter: [number, number], viewHeight: number, dxfattribs?: DxfAttribs & {
81
+ status?: number;
82
+ id?: number;
83
+ frozen_layers?: string[];
84
+ locked?: boolean;
85
+ }): ViewportEntity;
86
+ /**
87
+ * Add a raster IMAGE.
88
+ * @param insertionPoint lower-left corner (WCS)
89
+ * @param imagePath file path as the CAD application should resolve it
90
+ * @param imageSize image size in pixels
91
+ * @param pixelSize drawing units per pixel — one value, or [x, y]
92
+ */
93
+ add_image(insertionPoint: [number, number], imagePath: string, imageSize: [number, number], pixelSize?: number | [number, number], dxfattribs?: DxfAttribs, opts?: {
94
+ rotation?: number;
95
+ clip?: [number, number][];
96
+ brightness?: number;
97
+ contrast?: number;
98
+ fade?: number;
99
+ }): ImageEntity;
100
+ add_wipeout(boundary: [number, number][], dxfattribs?: DxfAttribs): WipeoutEntity;
101
+ add_region(acisData: string[], dxfattribs?: DxfAttribs): RegionEntity;
102
+ add_mesh(vertices: [number, number, number][], faces: number[][], dxfattribs?: DxfAttribs & {
103
+ subdivision_level?: number;
104
+ }): MeshEntity;
105
+ query(entityType: string): DxfEntity[];
106
+ }
@@ -0,0 +1,351 @@
1
+ import { TextEntityAlignment } from './dxf-entities.js';
2
+ import { HATCH_PATTERNS } from './hatch-patterns.js';
3
+ /** Common entity attributes from ezdxf-style dxfattribs. */
4
+ function base(dxfattribs) {
5
+ return {
6
+ layer: dxfattribs.layer || '0',
7
+ color: dxfattribs.color,
8
+ linetype: dxfattribs.linetype,
9
+ lineweight: dxfattribs.lineweight,
10
+ };
11
+ }
12
+ /**
13
+ * An entity collector — used for model space, paper space layouts and block
14
+ * definitions alike.
15
+ */
16
+ export class Modelspace {
17
+ _entities = [];
18
+ get entities() { return this._entities; }
19
+ // ─── Basic Geometry ───
20
+ add_line(start, end, dxfattribs = {}) {
21
+ const e = { type: 'LINE', ...base(dxfattribs), start, end };
22
+ this._entities.push(e);
23
+ return e;
24
+ }
25
+ add_lwpolyline(points, dxfattribs = {}, close = false) {
26
+ const e = { type: 'LWPOLYLINE', ...base(dxfattribs), points: [...points], closed: close };
27
+ this._entities.push(e);
28
+ return e;
29
+ }
30
+ add_polyline(points, dxfattribs = {}, close = false) {
31
+ const e = { type: 'POLYLINE', ...base(dxfattribs), points: [...points], closed: close };
32
+ this._entities.push(e);
33
+ return e;
34
+ }
35
+ add_circle(center, radius, dxfattribs = {}) {
36
+ const e = { type: 'CIRCLE', ...base(dxfattribs), center, radius };
37
+ this._entities.push(e);
38
+ return e;
39
+ }
40
+ add_arc(center, radius, startAngle, endAngle, dxfattribs = {}) {
41
+ const e = { type: 'ARC', ...base(dxfattribs), center, radius, startAngle, endAngle };
42
+ this._entities.push(e);
43
+ return e;
44
+ }
45
+ add_ellipse(center, majorAxis, ratio, startParam = 0, endParam = Math.PI * 2, dxfattribs = {}) {
46
+ const e = { type: 'ELLIPSE', ...base(dxfattribs), center, majorAxis, ratioMinorToMajor: ratio, startParam, endParam };
47
+ this._entities.push(e);
48
+ return e;
49
+ }
50
+ add_point(location, dxfattribs = {}) {
51
+ const e = { type: 'POINT', ...base(dxfattribs), position: location };
52
+ this._entities.push(e);
53
+ return e;
54
+ }
55
+ add_solid(points, dxfattribs = {}) {
56
+ const e = { type: 'SOLID', ...base(dxfattribs), points };
57
+ this._entities.push(e);
58
+ return e;
59
+ }
60
+ add_trace(points, dxfattribs = {}) {
61
+ const e = { type: 'TRACE', ...base(dxfattribs), points };
62
+ this._entities.push(e);
63
+ return e;
64
+ }
65
+ // ─── Text Entities ───
66
+ add_text(text, dxfattribs = {}) {
67
+ const e = {
68
+ type: 'TEXT', ...base(dxfattribs),
69
+ text, position: [0, 0], height: dxfattribs.height || 2.5, rotation: dxfattribs.rotation || 0,
70
+ style: dxfattribs.style || 'Standard', halign: dxfattribs.halign || 0, valign: dxfattribs.valign || 0,
71
+ };
72
+ this._entities.push(e);
73
+ return {
74
+ set_placement: (pos, align) => {
75
+ if (align !== undefined) {
76
+ if (align >= 30) {
77
+ e.valign = 1;
78
+ e.halign = align - 30;
79
+ }
80
+ else if (align >= 20) {
81
+ e.valign = 3;
82
+ e.halign = align - 20;
83
+ }
84
+ else if (align >= 10) {
85
+ e.valign = 2;
86
+ e.halign = align - 10;
87
+ }
88
+ else if (align === TextEntityAlignment.MIDDLE) {
89
+ e.halign = 4;
90
+ e.valign = 0;
91
+ }
92
+ else {
93
+ e.halign = align;
94
+ e.valign = 0;
95
+ }
96
+ }
97
+ if (e.halign === 0 && e.valign === 0) {
98
+ e.position = pos;
99
+ }
100
+ else {
101
+ e.position = pos;
102
+ e.alignmentPoint = pos;
103
+ }
104
+ return e;
105
+ }
106
+ };
107
+ }
108
+ add_mtext(text, dxfattribs = {}) {
109
+ const e = {
110
+ type: 'MTEXT', ...base(dxfattribs),
111
+ text, position: [0, 0], height: dxfattribs.height || 2.5, rotation: dxfattribs.rotation || 0,
112
+ width: dxfattribs.width || 100, style: dxfattribs.style || 'Standard', attachmentPoint: dxfattribs.attachment_point || 1,
113
+ };
114
+ this._entities.push(e);
115
+ return e;
116
+ }
117
+ // ─── Block Reference ───
118
+ add_blockref(blockName, insert, dxfattribs = {}) {
119
+ const e = {
120
+ type: 'INSERT', ...base(dxfattribs),
121
+ blockName, position: insert, xScale: dxfattribs.xscale || 1, yScale: dxfattribs.yscale || 1,
122
+ zScale: dxfattribs.zscale || 1, rotation: dxfattribs.rotation || 0,
123
+ };
124
+ this._entities.push(e);
125
+ return e;
126
+ }
127
+ // ─── Complex Entities ───
128
+ add_spline(controlPoints, degree = 3, dxfattribs = {}, opts = {}) {
129
+ const n = controlPoints.length;
130
+ const order = degree + 1;
131
+ const knots = opts.knots || Array.from({ length: n + order }, (_, i) => i);
132
+ const e = {
133
+ type: 'SPLINE', ...base(dxfattribs),
134
+ degree, closed: opts.closed || false, controlPoints: [...controlPoints],
135
+ fitPoints: opts.fitPoints ? [...opts.fitPoints] : [], knots, weights: opts.weights,
136
+ };
137
+ this._entities.push(e);
138
+ return e;
139
+ }
140
+ /**
141
+ * Add a HATCH. Pattern names resolve against the built-in HATCH_PATTERNS
142
+ * (ISO, mm based) unless `opts.patternLines` supplies a custom definition.
143
+ */
144
+ add_hatch(patternName = 'SOLID', boundaries, dxfattribs = {}, opts = {}) {
145
+ const solid = opts.solid !== undefined ? opts.solid : patternName.toUpperCase() === 'SOLID';
146
+ if (!solid && !opts.patternLines && !HATCH_PATTERNS[patternName.toUpperCase()]) {
147
+ throw new Error(`Unknown hatch pattern "${patternName}". Use one of ${Object.keys(HATCH_PATTERNS).join(', ')}, ` +
148
+ `or pass opts.patternLines.`);
149
+ }
150
+ const e = {
151
+ type: 'HATCH', ...base(dxfattribs),
152
+ patternName, solid, scale: opts.scale || 1, angle: opts.angle || 0, boundaries,
153
+ patternLines: opts.patternLines,
154
+ };
155
+ this._entities.push(e);
156
+ return e;
157
+ }
158
+ add_dimension(point1, point2, dimLine, dxfattribs = {}) {
159
+ const textMid = [(point1[0] + point2[0]) / 2, dimLine[1]];
160
+ const e = {
161
+ type: 'DIMENSION', ...base(dxfattribs),
162
+ dimensionType: dxfattribs.dimensionType || 0, definitionPoint: dimLine, textMidpoint: textMid,
163
+ insertionPoint: dimLine, text: dxfattribs.text || '', rotation: dxfattribs.rotation || 0,
164
+ style: dxfattribs.style || 'Standard', point1, point2,
165
+ };
166
+ this._entities.push(e);
167
+ return e;
168
+ }
169
+ add_leader(vertices, dxfattribs = {}) {
170
+ const e = {
171
+ type: 'LEADER', ...base(dxfattribs),
172
+ vertices: [...vertices], hasArrowhead: dxfattribs.has_arrowhead !== false,
173
+ annotationType: dxfattribs.annotation_type || 3, style: dxfattribs.style || 'Standard',
174
+ annotationText: dxfattribs.annotation_text,
175
+ };
176
+ this._entities.push(e);
177
+ return e;
178
+ }
179
+ /**
180
+ * Add a MULTILEADER entity (modern annotation — AutoCAD 2008+).
181
+ * Combines leader line with MTEXT content.
182
+ *
183
+ * @deprecated The MULTILEADER written for this entity is incomplete and is
184
+ * not read reliably by AutoCAD. Use `DxfBuilder.addCallout()` instead.
185
+ */
186
+ add_mleader(vertices, text, textPosition, dxfattribs = {}) {
187
+ const e = {
188
+ type: 'MLEADER', ...base(dxfattribs),
189
+ vertices: [...vertices], text, textPosition,
190
+ textHeight: dxfattribs.text_height || 2.5,
191
+ textWidth: dxfattribs.text_width || 50,
192
+ arrowSize: dxfattribs.arrow_size || 2.5,
193
+ style: dxfattribs.style || 'Standard',
194
+ doglegLength: dxfattribs.dogleg_length || 8,
195
+ leaderType: dxfattribs.leader_type || 1,
196
+ contentType: dxfattribs.content_type || 2,
197
+ };
198
+ this._entities.push(e);
199
+ return e;
200
+ }
201
+ /**
202
+ * Add a TABLE as composite LINE + TEXT entities.
203
+ * Note: DXF ACAD_TABLE is extremely complex; this draws a visual table
204
+ * using primitive entities for maximum compatibility.
205
+ *
206
+ * Cells may span columns/rows (`colSpan` / `rowSpan`); grid lines inside a
207
+ * merged cell are omitted.
208
+ */
209
+ add_table(tableDef) {
210
+ const { position, columnWidths, rows, layer, textHeight } = tableDef;
211
+ const gridColor = tableDef.gridColor || 7;
212
+ const textColor = tableDef.textColor || 7;
213
+ const numCols = columnWidths.length;
214
+ const numRows = rows.length;
215
+ const xs = [position[0]];
216
+ for (const w of columnWidths)
217
+ xs.push(xs[xs.length - 1] + w);
218
+ const ys = [position[1]];
219
+ for (let r = 0; r < numRows; r++)
220
+ ys.push(ys[r] - (tableDef.rowHeights?.[r] ?? tableDef.rowHeight));
221
+ // Place cells on the grid (HTML table semantics); owner[r][c] = placed cell index.
222
+ const owner = Array.from({ length: numRows }, () => new Array(numCols).fill(-1));
223
+ const placed = [];
224
+ for (let r = 0; r < numRows; r++) {
225
+ let c = 0;
226
+ for (let i = 0; i < rows[r].length; i++) {
227
+ while (c < numCols && owner[r][c] !== -1)
228
+ c++;
229
+ if (c >= numCols)
230
+ break;
231
+ const cell = rows[r][i];
232
+ const cs = Math.max(1, Math.min(cell.colSpan ?? 1, numCols - c));
233
+ const rs = Math.max(1, Math.min(cell.rowSpan ?? 1, numRows - r));
234
+ for (let rr = r; rr < r + rs; rr++) {
235
+ for (let cc = c; cc < c + cs; cc++)
236
+ owner[rr][cc] = placed.length;
237
+ }
238
+ placed.push({ r, c, rs, cs, row: r, col: i });
239
+ c += cs;
240
+ }
241
+ }
242
+ // Positions not covered by any cell still get their own grid box.
243
+ let next = placed.length;
244
+ for (let r = 0; r < numRows; r++) {
245
+ for (let c = 0; c < numCols; c++)
246
+ if (owner[r][c] === -1)
247
+ owner[r][c] = next++;
248
+ }
249
+ const gridAttr = { layer, color: gridColor };
250
+ // Horizontal borders: between rows k-1 and k, wherever the owning cell changes.
251
+ for (let k = 0; k <= numRows; k++) {
252
+ let start = -1;
253
+ for (let c = 0; c <= numCols; c++) {
254
+ const draw = c < numCols && (k === 0 || k === numRows || owner[k - 1][c] !== owner[k][c]);
255
+ if (draw && start === -1)
256
+ start = c;
257
+ if (!draw && start !== -1) {
258
+ this.add_line([xs[start], ys[k]], [xs[c], ys[k]], gridAttr);
259
+ start = -1;
260
+ }
261
+ }
262
+ }
263
+ // Vertical borders: between columns k-1 and k.
264
+ for (let k = 0; k <= numCols; k++) {
265
+ let start = -1;
266
+ for (let r = 0; r <= numRows; r++) {
267
+ const draw = r < numRows && (k === 0 || k === numCols || owner[r][k - 1] !== owner[r][k]);
268
+ if (draw && start === -1)
269
+ start = r;
270
+ if (!draw && start !== -1) {
271
+ this.add_line([xs[k], ys[start]], [xs[k], ys[r]], gridAttr);
272
+ start = -1;
273
+ }
274
+ }
275
+ }
276
+ // Cell text, centered in the (possibly merged) cell box.
277
+ for (const p of placed) {
278
+ const cell = rows[p.row][p.col];
279
+ if (!cell.text)
280
+ continue;
281
+ const cx = (xs[p.c] + xs[p.c + p.cs]) / 2;
282
+ const cy = (ys[p.r] + ys[p.r + p.rs]) / 2;
283
+ const isHeader = p.r === 0 && tableDef.headerColor !== undefined;
284
+ const color = cell.color || (isHeader ? tableDef.headerColor : textColor) || textColor;
285
+ this.add_text(cell.text, {
286
+ height: textHeight, layer,
287
+ color, style: cell.style,
288
+ }).set_placement([cx, cy], cell.alignment || TextEntityAlignment.MIDDLE_CENTER);
289
+ }
290
+ }
291
+ add_viewport(center, width, height, viewCenter, viewHeight, dxfattribs = {}) {
292
+ const e = {
293
+ type: 'VIEWPORT', ...base(dxfattribs),
294
+ center, width, height, viewCenter, viewHeight, status: dxfattribs.status || 1,
295
+ id: dxfattribs.id, frozenLayers: dxfattribs.frozen_layers, locked: dxfattribs.locked,
296
+ };
297
+ this._entities.push(e);
298
+ return e;
299
+ }
300
+ /**
301
+ * Add a raster IMAGE.
302
+ * @param insertionPoint lower-left corner (WCS)
303
+ * @param imagePath file path as the CAD application should resolve it
304
+ * @param imageSize image size in pixels
305
+ * @param pixelSize drawing units per pixel — one value, or [x, y]
306
+ */
307
+ add_image(insertionPoint, imagePath, imageSize, pixelSize = 1, dxfattribs = {}, opts = {}) {
308
+ const [sx, sy] = typeof pixelSize === 'number' ? [pixelSize, pixelSize] : pixelSize;
309
+ const a = (opts.rotation || 0) * Math.PI / 180;
310
+ const e = {
311
+ type: 'IMAGE', ...base(dxfattribs),
312
+ insertionPoint, imagePath, imageSize,
313
+ uVector: [Math.cos(a) * sx, Math.sin(a) * sx],
314
+ vVector: [-Math.sin(a) * sy, Math.cos(a) * sy],
315
+ clipBoundary: opts.clip, brightness: opts.brightness, contrast: opts.contrast, fade: opts.fade,
316
+ };
317
+ this._entities.push(e);
318
+ return e;
319
+ }
320
+ add_wipeout(boundary, dxfattribs = {}) {
321
+ const xs = boundary.map(p => p[0]);
322
+ const ys = boundary.map(p => p[1]);
323
+ const minX = Math.min(...xs), minY = Math.min(...ys);
324
+ const maxX = Math.max(...xs), maxY = Math.max(...ys);
325
+ const w = maxX - minX || 1, h = maxY - minY || 1;
326
+ const normalized = boundary.map(p => [(p[0] - minX) / w, (p[1] - minY) / h]);
327
+ const e = {
328
+ type: 'WIPEOUT', ...base(dxfattribs),
329
+ insertionPoint: [minX, minY], uVector: [w, 0], vVector: [0, h], imageSize: [1, 1], clipBoundary: normalized,
330
+ };
331
+ this._entities.push(e);
332
+ return e;
333
+ }
334
+ add_region(acisData, dxfattribs = {}) {
335
+ const e = { type: 'REGION', ...base(dxfattribs), acisData };
336
+ this._entities.push(e);
337
+ return e;
338
+ }
339
+ add_mesh(vertices, faces, dxfattribs = {}) {
340
+ const e = {
341
+ type: 'MESH', ...base(dxfattribs),
342
+ subdivisionLevel: dxfattribs.subdivision_level || 0, vertices: [...vertices], faces: faces.map(f => [...f]),
343
+ };
344
+ this._entities.push(e);
345
+ return e;
346
+ }
347
+ // ─── Query ───
348
+ query(entityType) {
349
+ return this._entities.filter(e => e.type === entityType);
350
+ }
351
+ }
@@ -0,0 +1,8 @@
1
+ import { Coordinate, Coordinate3D } from '../types/index.js';
2
+ export declare function formatDistance(distance: number): string;
3
+ export declare function calculateDistance(p1: Coordinate, p2: Coordinate): number;
4
+ export declare function calculateAzimuth(x1: number, y1: number, x2: number, y2: number): number;
5
+ export declare function rotatePoint(x: number, y: number, angleDeg: number, shiftX: number, shiftY: number): Coordinate3D;
6
+ export declare function rotatePointAzimuth(x: number, y: number, azimuthDeg: number, shiftX: number, shiftY: number): Coordinate3D;
7
+ export declare function isPointInBounds(x: number, y: number, xmin: number, ymin: number, xmax: number, ymax: number): boolean;
8
+ export declare function snapBound(value: number, step: number, direction?: 'up' | 'down'): number;