@design-core/core 0.0.1 → 0.0.3

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 (254) hide show
  1. package/.eslintrc.json +14 -7
  2. package/.github/workflows/DesignCoreQA.yml +3 -1
  3. package/README.md +11 -4
  4. package/TODO.md +19 -0
  5. package/core/core/core.js +49 -42
  6. package/core/designCore.js +61 -2
  7. package/core/dimensions/alignedDimension.js +142 -0
  8. package/core/dimensions/angularDimension.js +550 -0
  9. package/core/dimensions/baseCircularDimension.js +244 -0
  10. package/core/dimensions/baseDimension.js +558 -0
  11. package/core/dimensions/baseLinearDimension.js +371 -0
  12. package/core/dimensions/diametricDimension.js +82 -0
  13. package/core/dimensions/dimension.js +298 -0
  14. package/core/dimensions/linearDimension.js +29 -0
  15. package/core/dimensions/radialDimension.js +78 -0
  16. package/core/dimensions/rotatedDimension.js +167 -0
  17. package/core/entities/arc.js +314 -60
  18. package/core/entities/arctext.js +642 -0
  19. package/core/entities/basePolyline.js +553 -94
  20. package/core/entities/circle.js +181 -54
  21. package/core/entities/entity.js +154 -74
  22. package/core/entities/hatch.js +807 -0
  23. package/core/entities/insert.js +200 -39
  24. package/core/entities/line.js +196 -134
  25. package/core/entities/lwpolyline.js +21 -44
  26. package/core/entities/point.js +194 -29
  27. package/core/entities/polyline.js +54 -7
  28. package/core/entities/rectangle.js +43 -13
  29. package/core/entities/solid.js +43 -6
  30. package/core/entities/text.js +324 -181
  31. package/core/lib/boundingBox.js +73 -13
  32. package/core/lib/canvas.js +256 -65
  33. package/core/lib/clipboard.js +198 -0
  34. package/core/lib/colour.js +144 -0
  35. package/core/lib/colours.js +367 -301
  36. package/core/lib/commandLine.js +16 -28
  37. package/core/lib/commandManager.js +115 -58
  38. package/core/lib/constants.js +23 -0
  39. package/core/lib/dxf/dxf.js +249 -34
  40. package/core/lib/dxf/dxfFile.js +23 -38
  41. package/core/lib/dxf/dxfIterator.js +17 -5
  42. package/core/lib/dxf/dxfRead.js +23 -7
  43. package/core/lib/dxf/dxfWrite.js +39 -129
  44. package/core/lib/dxf/handleManager.js +97 -0
  45. package/core/lib/dxf/sections/blocks.js +16 -2
  46. package/core/lib/dxf/sections/entities.js +17 -3
  47. package/core/lib/dxf/sections/header.js +10 -1
  48. package/core/lib/dxf/sections/objects.js +36 -0
  49. package/core/lib/dxf/sections/section.js +43 -5
  50. package/core/lib/dxf/sections/tables.js +17 -3
  51. package/core/lib/entityManager.js +178 -0
  52. package/core/lib/fileio.js +14 -4
  53. package/core/lib/headers.js +229 -0
  54. package/core/lib/input.js +46 -0
  55. package/core/lib/inputManager.js +199 -194
  56. package/core/lib/intersect.js +341 -468
  57. package/core/lib/logging.js +25 -1
  58. package/core/lib/matrix.js +6 -8
  59. package/core/lib/mouse.js +24 -79
  60. package/core/lib/patterns.js +690 -0
  61. package/core/lib/promptOptions.js +133 -0
  62. package/core/lib/scene.js +71 -174
  63. package/core/lib/selectionManager.js +74 -48
  64. package/core/lib/selectionWindow.js +24 -10
  65. package/core/lib/settings.js +18 -11
  66. package/core/lib/snapping.js +129 -21
  67. package/core/lib/stateManager.js +288 -0
  68. package/core/lib/strings.js +57 -5
  69. package/core/lib/utils.js +95 -11
  70. package/core/objects/dictionary.js +43 -0
  71. package/core/objects/dictionaryManager.js +80 -0
  72. package/core/properties/dimType.js +117 -0
  73. package/core/properties/flags.js +66 -0
  74. package/core/properties/property.js +26 -0
  75. package/core/properties/propertyManager.js +65 -19
  76. package/core/tables/appId.js +31 -0
  77. package/core/tables/appIdManager.js +44 -0
  78. package/core/tables/block.js +323 -0
  79. package/core/tables/blockManager.js +48 -0
  80. package/core/tables/blockRecord.js +29 -0
  81. package/core/tables/blockRecordManager.js +37 -0
  82. package/core/tables/dimStyle.js +627 -0
  83. package/core/tables/dimStyleManager.js +187 -0
  84. package/core/tables/endblk.js +28 -0
  85. package/core/tables/layer.js +219 -0
  86. package/core/tables/layerManager.js +47 -0
  87. package/core/tables/ltype.js +85 -0
  88. package/core/tables/ltypeManager.js +65 -0
  89. package/core/tables/style.js +145 -0
  90. package/core/tables/styleManager.js +55 -0
  91. package/core/tables/styleManagerBase.js +110 -0
  92. package/core/tables/tableManagerBase.js +354 -0
  93. package/core/tables/ucs.js +28 -0
  94. package/core/tables/ucsManager.js +44 -0
  95. package/core/tables/view.js +28 -0
  96. package/core/tables/viewManager.js +44 -0
  97. package/core/tables/vport.js +70 -0
  98. package/core/tables/vportManager.js +65 -0
  99. package/core/tools/chamfer.js +343 -0
  100. package/core/tools/chamferFilletBase.js +162 -0
  101. package/core/tools/copy.js +68 -40
  102. package/core/tools/copybase.js +65 -0
  103. package/core/tools/copyclip.js +59 -0
  104. package/core/tools/cornerEntity.js +138 -0
  105. package/core/tools/cutclip.js +72 -0
  106. package/core/tools/distance.js +37 -9
  107. package/core/tools/erase.js +43 -13
  108. package/core/tools/explode.js +117 -0
  109. package/core/tools/extend.js +71 -32
  110. package/core/tools/fillet.js +336 -0
  111. package/core/tools/identify.js +33 -6
  112. package/core/tools/matchProp.js +106 -0
  113. package/core/tools/mirror.js +141 -0
  114. package/core/tools/move.js +65 -32
  115. package/core/tools/offset.js +321 -0
  116. package/core/tools/pan.js +54 -0
  117. package/core/tools/pasteclip.js +93 -0
  118. package/core/tools/purge.js +90 -0
  119. package/core/tools/rotate.js +105 -70
  120. package/core/tools/scale.js +166 -0
  121. package/core/tools/tool.js +14 -4
  122. package/core/tools/trim.js +71 -32
  123. package/core/tools/zoom.js +152 -0
  124. package/package.json +3 -305
  125. package/test/dimensions/alignedDimension.test.js +211 -0
  126. package/test/dimensions/angularDimension.test.js +243 -0
  127. package/test/dimensions/baseDimension.test.js +239 -0
  128. package/test/dimensions/diametricDimension.test.js +203 -0
  129. package/test/dimensions/dimension.test.js +102 -0
  130. package/test/dimensions/radialDimension.test.js +203 -0
  131. package/test/dimensions/rotatedDimension.test.js +224 -0
  132. package/test/entities/arc.test.js +463 -41
  133. package/test/entities/arctext.test.js +329 -0
  134. package/test/entities/basePolyline.test.js +459 -10
  135. package/test/entities/circle.test.js +312 -7
  136. package/test/entities/entity.test.js +28 -9
  137. package/test/entities/hatch.test.js +606 -0
  138. package/test/entities/insert.test.js +90 -0
  139. package/test/entities/line.test.js +182 -6
  140. package/test/entities/point.test.js +375 -37
  141. package/test/entities/solid.test.js +156 -0
  142. package/test/entities/text.test.js +533 -7
  143. package/test/integration/exportIntegration.reference.dxf +1706 -0
  144. package/test/integration/exportIntegration.test.js +186 -0
  145. package/test/integration/importExportIntegration.test.js +126 -0
  146. package/test/integration/intersectionIntegration.test.js +880 -0
  147. package/test/integration/userInputIntegration.reference.dxf +1410 -0
  148. package/test/integration/userInputIntegration.test.js +269 -0
  149. package/test/lib/boundingBox.test.js +26 -2
  150. package/test/lib/canvas.test.js +613 -5
  151. package/test/lib/clipboard.test.js +70 -0
  152. package/test/lib/colour.test.js +114 -0
  153. package/test/lib/colours.test.js +63 -18
  154. package/test/lib/commandLine.test.js +159 -22
  155. package/test/lib/commandManager.test.js +4 -4
  156. package/test/lib/constants.test.js +9 -0
  157. package/test/lib/dxf/dxfFile.test.js +6 -2
  158. package/test/lib/dxf/dxfIterator.test.js +1 -1
  159. package/test/lib/dxf/dxfWrite.test.js +173 -0
  160. package/test/lib/dxf/handleManager.test.js +137 -0
  161. package/test/lib/dxf/sections/blocks.test.js +5 -5
  162. package/test/lib/dxf/sections/entities.test.js +4 -4
  163. package/test/lib/dxf/sections/header.test.js +18 -4
  164. package/test/lib/dxf/sections/objects.test.js +132 -0
  165. package/test/lib/dxf/sections/section.test.js +29 -29
  166. package/test/lib/dxf/sections/tables.test.js +3 -3
  167. package/test/lib/entityManager.test.js +163 -0
  168. package/test/lib/headers.test.js +233 -0
  169. package/test/lib/inputManager.test.js +1144 -5
  170. package/test/lib/intersect.test.js +454 -331
  171. package/test/lib/logging.test.js +1 -1
  172. package/test/lib/matrix.test.js +1 -1
  173. package/test/lib/mouse.test.js +327 -4
  174. package/test/lib/patterns.test.js +105 -0
  175. package/test/lib/promptOptions.test.js +179 -0
  176. package/test/lib/scene.test.js +16 -52
  177. package/test/lib/selectionManager.test.js +17 -5
  178. package/test/lib/settings.test.js +111 -5
  179. package/test/lib/snapping.test.js +142 -4
  180. package/test/lib/stateManager.test.js +155 -0
  181. package/test/lib/utils.test.js +81 -1
  182. package/test/objects/dictionary.test.js +81 -0
  183. package/test/objects/dictionaryManager.test.js +34 -0
  184. package/test/properties/dimType.test.js +62 -0
  185. package/test/properties/flags.test.js +164 -0
  186. package/test/properties/property.test.js +13 -0
  187. package/test/properties/propertyManager.test.js +10 -11
  188. package/test/tables/appId.test.js +46 -0
  189. package/test/tables/appIdManager.test.js +72 -0
  190. package/test/tables/block.test.js +157 -0
  191. package/test/tables/blockManager.test.js +52 -0
  192. package/test/tables/blockRecord.test.js +39 -0
  193. package/test/tables/blockRecordManager.test.js +60 -0
  194. package/test/tables/dimstyle.test.js +72 -0
  195. package/test/tables/endblk.test.js +30 -0
  196. package/test/tables/layer.test.js +95 -0
  197. package/test/tables/layerManager.test.js +172 -0
  198. package/test/{styles → tables}/ltype.test.js +7 -7
  199. package/test/{styles → tables}/ltypeManager.test.js +2 -2
  200. package/test/tables/style.test.js +44 -0
  201. package/test/tables/stylemanagerbase.test.js +220 -0
  202. package/test/tables/tableManagerBase.test.js +194 -0
  203. package/test/tables/ucs.test.js +37 -0
  204. package/test/tables/ucsManager.test.js +48 -0
  205. package/test/tables/view.test.js +37 -0
  206. package/test/tables/viewManager.test.js +48 -0
  207. package/test/tables/vport.test.js +117 -0
  208. package/test/tables/vportManager.test.js +54 -0
  209. package/test/test-helpers/test-helpers.js +66 -0
  210. package/test/tools/chamfer.test.js +970 -0
  211. package/test/tools/chamferFilletBase.test.js +446 -0
  212. package/test/tools/copy.test.js +22 -14
  213. package/test/tools/copybase.test.js +93 -0
  214. package/test/tools/copyclip.test.js +92 -0
  215. package/test/tools/cornerEntity.test.js +201 -0
  216. package/test/tools/cutclip.test.js +94 -0
  217. package/test/tools/distance.test.js +140 -18
  218. package/test/tools/erase.test.js +12 -12
  219. package/test/tools/explode.test.js +45 -0
  220. package/test/tools/extend.test.js +326 -44
  221. package/test/tools/fillet.test.js +831 -0
  222. package/test/tools/identify.test.js +115 -16
  223. package/test/tools/matchProp.test.js +84 -0
  224. package/test/tools/mirror.test.js +475 -0
  225. package/test/tools/move.test.js +75 -19
  226. package/test/tools/offset.test.js +748 -0
  227. package/test/tools/pan.test.js +72 -0
  228. package/test/tools/pasteclip.test.js +100 -0
  229. package/test/tools/purge.test.js +89 -0
  230. package/test/tools/rotate.test.js +89 -23
  231. package/test/tools/scale.test.js +529 -0
  232. package/test/tools/trim.test.js +419 -84
  233. package/test/tools/zoom.test.js +504 -0
  234. package/core/entities/alignedDimension.js +0 -279
  235. package/core/entities/angularDimension.js +0 -194
  236. package/core/entities/baseDimension.js +0 -227
  237. package/core/entities/block.js +0 -247
  238. package/core/entities/diametricDimension.js +0 -133
  239. package/core/entities/dimension.js +0 -202
  240. package/core/entities/radialDimension.js +0 -126
  241. package/core/styles/dimStyle.js +0 -719
  242. package/core/styles/dimStyleManager.js +0 -47
  243. package/core/styles/layer.js +0 -133
  244. package/core/styles/layerManager.js +0 -40
  245. package/core/styles/ltype.js +0 -86
  246. package/core/styles/ltypeManager.js +0 -50
  247. package/core/styles/style.js +0 -158
  248. package/core/styles/styleManager.js +0 -43
  249. package/core/styles/styleManagerBase.js +0 -299
  250. package/test/entities/block.test.js +0 -22
  251. package/test/styles/dimstyle.test.js +0 -19
  252. package/test/styles/layerManager.test.js +0 -150
  253. package/test/styles/style.test.js +0 -33
  254. package/test/styles/stylemanagerbase.test.js +0 -219
@@ -0,0 +1,371 @@
1
+ import { Strings } from '../lib/strings.js';
2
+ import { Line } from '../entities/line.js';
3
+ import { Text } from '../entities/text.js';
4
+ import { Input, PromptOptions } from '../lib/inputManager.js';
5
+ import { Logging } from '../lib/logging.js';
6
+ import { BaseDimension } from './baseDimension.js';
7
+ import { Point } from '../entities/point.js';
8
+
9
+ import { DesignCore } from '../designCore.js';
10
+ import { Utils } from '../lib/utils.js';
11
+
12
+ /**
13
+ * Aligned Dimension Entity Class
14
+ * @extends BaseDimension
15
+ */
16
+ export class BaseLinearDimension extends BaseDimension {
17
+ /**
18
+ * Create an Aligned Dimension
19
+ * @param {Array} data
20
+ */
21
+ constructor(data) {
22
+ super(data);
23
+ }
24
+
25
+ /**
26
+ * Execute method
27
+ * executes the workflow, requesting input required to create an entity
28
+ */
29
+ async execute() {
30
+ try {
31
+ DesignCore.Scene.selectionManager.reset();
32
+ this.dimensionStyle = DesignCore.DimStyleManager.getCstyle();
33
+ this.dimType.setDimType(0); // Rotated dimension
34
+
35
+ const op = new PromptOptions(Strings.Input.START, [Input.Type.POINT]);
36
+ const pt13 = await DesignCore.Scene.inputManager.requestInput(op);
37
+ pt13.sequence = 13;
38
+ this.points.push(pt13);
39
+
40
+ const op1 = new PromptOptions(Strings.Input.END, [Input.Type.POINT]);
41
+ const pt14 = await DesignCore.Scene.inputManager.requestInput(op1);
42
+ pt14.sequence = 14;
43
+ this.points.push(pt14);
44
+
45
+ const op2 = new PromptOptions(Strings.Input.DIMENSION, [Input.Type.POINT]);
46
+ const pt11 = await DesignCore.Scene.inputManager.requestInput(op2);
47
+ pt11.sequence = 11;
48
+ this.points.push(pt11);
49
+
50
+ const tempLine = new Line({ points: [pt13, pt14] });
51
+ this.points = LinearDimension.getPointsFromSelection([tempLine], pt11);
52
+
53
+ DesignCore.Scene.inputManager.executeCommand(this);
54
+ } catch (err) {
55
+ Logging.instance.error(`${this.type} - ${err}`);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Preview the entity during creation
61
+ */
62
+ preview() {
63
+ if (this.points.length == 1) {
64
+ const mousePoint = DesignCore.Mouse.pointOnScene();
65
+ const points = [this.points.at(0), mousePoint];
66
+ DesignCore.Scene.tempEntities.create('Line', { points: points });
67
+ }
68
+
69
+ if (this.points.length > 1) {
70
+ const pt11 = DesignCore.Mouse.pointOnScene();
71
+ pt11.sequence = 11;
72
+ const tempLine = new Line({ points: [...this.points] });
73
+ const points = this.constructor.getPointsFromSelection([tempLine], pt11);
74
+ DesignCore.Scene.tempEntities.create(this.type, { points: points, dimensionStyle: this.dimensionStyle });
75
+ }
76
+ }
77
+
78
+
79
+ /**
80
+ * Build the dimension
81
+ * @param {Object} style
82
+ * @return {Array} - Array of entities that compose the dimension
83
+ */
84
+ buildDimension() {
85
+ let dimension = 0;
86
+ const entities = [];
87
+
88
+ const Pt10 = this.getPointBySequence(this.points, 10);
89
+ const Pt13 = this.getPointBySequence(this.points, 13);
90
+ const Pt14 = this.getPointBySequence(this.points, 14);
91
+ const Pt11 = this.getPointBySequence(this.points, 11);
92
+
93
+ // Style values
94
+ const DIMTIH = this.getDimensionStyle().getValue('DIMTIH'); // Text inside horizontal alignment
95
+ const DIMTOH = this.getDimensionStyle().getValue('DIMTOH'); // Text outside horizontal alignment
96
+ const DIMASZ = this.getDimensionStyle().getValue('DIMASZ'); // Arrow size (used for extension line length)
97
+ const DIMTXT = this.getDimensionStyle().getValue('DIMTXT'); // Text size (used for estimated text width)
98
+ // const DIMTOFL = this.getDimensionStyle().getValue('DIMTOFL'); // Force extension line if text outside
99
+ const DIMTAD = this.getDimensionStyle().getValue('DIMTAD'); // Text vertical position
100
+ const DIMEXE = this.getDimensionStyle().getValue('DIMEXE'); // Extend beyond dimension line distance
101
+ const DIMEXO = this.getDimensionStyle().getValue('DIMEXO'); // Offset from origin distance
102
+ const DIMJUST = this.getDimensionStyle().getValue('DIMJUST'); // Justification of the dimension text
103
+ const DIMGAP = this.getDimensionStyle().getValue('DIMGAP'); // Gap between dimension line and text
104
+ const DIMSE1 = this.getDimensionStyle().getValue('DIMSE1'); // Suppress first extension line
105
+ const DIMSE2 = this.getDimensionStyle().getValue('DIMSE2'); // Suppress second extension line
106
+ const DIMSD1 = this.getDimensionStyle().getValue('DIMSD1'); // Suppress first dimension line
107
+ const DIMSD2 = this.getDimensionStyle().getValue('DIMSD2'); // Suppress second dimension line
108
+
109
+ // invalid points
110
+ if (Pt13.isSame(Pt14) || Pt11.closestPointOnLine(Pt13, Pt14).distance(Pt11) < DIMEXO) {
111
+ /* Pt13.distance(Pt11) < DIMEXO || Pt14.distance(Pt11) < DIMEXO ||*/
112
+ return;
113
+ }
114
+
115
+ let Pt13e = new Point();
116
+ const Pt14e = Pt10;
117
+
118
+ // generate the x and y delta values
119
+ const dx = Pt14.x - Pt13.x;
120
+ const dy = Pt14.y - Pt13.y;
121
+
122
+ // check if Line Pt13 -> P14 is perpendicular to Line Pt14 -> Pt10
123
+ const m1 = (Pt14.y - Pt13.y) / (Pt14.x - Pt13.x);
124
+ const m2 = (Pt14.y - Pt10.y) / (Pt14.x - Pt10.x);
125
+ const perpendicular = Number((m1 * m2).toFixed(1));
126
+
127
+ const isAligned = perpendicular !== -1.0 ? false : true;
128
+
129
+ if (isAligned || Utils.round(dx) === 0 || Utils.round(dy) === 0) {
130
+ Pt13e = Pt13.project(Pt14.angle(Pt10), Pt14.distance(Pt10));
131
+ dimension = Pt13.distance(Pt14);
132
+ } else {
133
+ // Not perpendicular to the selected line: get the primary axis (x or y) and calculate the dimension
134
+ const iX = ((Math.abs(Pt10.x - Pt13.x) + Math.abs(Pt14.x - Pt10.x)) - Math.abs(dx));
135
+ const iY = ((Math.abs(Pt10.y - Pt13.y) + Math.abs(Pt14.y - Pt10.y)) - Math.abs(dy));
136
+
137
+ if (iX >= iY && dy !== 0) {
138
+ Pt13e.x = Pt10.x;
139
+ Pt13e.y = Pt13.y;
140
+ dimension = dy;
141
+ } else if (iX < iY && dx !== 0) {
142
+ Pt13e.x = Pt13.x;
143
+ Pt13e.y = Pt10.y;
144
+ dimension = dx;
145
+ }
146
+ }
147
+
148
+ // ensure dimension is positive
149
+ dimension = Math.abs(dimension);
150
+
151
+ const extensionLineAngle = Pt13.angle(Pt13e);
152
+ // const reverseExtensionLineAngle = Pt13e.angle(Pt13);
153
+ const dimLineAngle = Pt13e.angle(Pt14e);
154
+ const reverseDimLineAngle = Pt14e.angle(Pt13e);
155
+ const midPoint = Pt13e.midPoint(Pt14e);
156
+
157
+ // set the dimension line angle. This is required for rotated dimension dxf definition
158
+ this.linearDimAngle = Utils.radians2degrees(dimLineAngle);
159
+
160
+ // Approximate text width based on height using the formatted dimension value i.e with units, precision and symbols
161
+ const approxTextWidth = Text.getApproximateWidth(this.getDimensionValue(dimension), DIMTXT);
162
+ const approxTextHalfWidth = approxTextWidth * 0.5;
163
+
164
+ // Check if the text can fit inside extension lines
165
+ const textOutSide = (approxTextWidth * 1.5 + DIMASZ * 2) >= dimension;
166
+ // Check if the arrows fit inside the extension lines
167
+ const arrowsOutSide = (DIMASZ * 3) >= dimension;
168
+
169
+ // DIMTIH - Text inside horizontal if nonzero, 0 = Aligns text with the dimension line, 1 = Draws text horizontally
170
+ // DIMTOH - Text outside horizontal if nonzero, 0 = Aligns text with the dimension line, 1 = Draws text horizontally
171
+ const horizontalText = (DIMTIH !== 0 && !textOutSide) || (DIMTOH !== 0 && textOutSide);
172
+
173
+ let textPosition = midPoint;
174
+ let textRotation = this.getTextDirection(horizontalText ? 0 : dimLineAngle);
175
+ // Get the direction for the dimension text offset
176
+ let textAboveDirection = textRotation + Math.PI / 2;
177
+ let textAboveDistance = DIMTXT * 0.5 + DIMGAP;
178
+
179
+ // get the distance to offset outside the extension lines
180
+ let outsideOffsetDistance = 0;
181
+ if (textOutSide) {
182
+ outsideOffsetDistance = (dimension + approxTextWidth) * 0.5 + DIMASZ + DIMEXE;
183
+ if (arrowsOutSide) {
184
+ outsideOffsetDistance += DIMASZ; // Add extra offset if arrows are outside
185
+ }
186
+ }
187
+
188
+ // get the direction to offset outside the extension lines
189
+ const outsideOffsetDirection = Pt11.distance(Pt13e) < Pt11.distance(Pt14e) ? reverseDimLineAngle : dimLineAngle;
190
+
191
+ switch (DIMJUST) {
192
+ case 0: // 0 = Center-justified between extension lines
193
+ if (textOutSide) {
194
+ textPosition = midPoint.project(outsideOffsetDirection, outsideOffsetDistance);
195
+ }
196
+ break;
197
+ case 1: // 1 = Next to first extension line
198
+ if (textOutSide) {
199
+ textPosition = midPoint.project(outsideOffsetDirection, outsideOffsetDistance);
200
+ } else {
201
+ textPosition = Pt13e.project(dimLineAngle, approxTextWidth * 0.75 + DIMASZ);
202
+ }
203
+ break;
204
+ case 2: // 2 = Next to second extension line
205
+ if (textOutSide) {
206
+ textPosition = midPoint.project(outsideOffsetDirection, outsideOffsetDistance);
207
+ } else {
208
+ textPosition = Pt14e.project(reverseDimLineAngle, approxTextWidth * 0.75 + DIMASZ);
209
+ }
210
+ break;
211
+ case 3: // 3 = Above first extension line
212
+ textPosition = Pt13e.project(extensionLineAngle, approxTextHalfWidth + DIMEXE + DIMTXT);
213
+ textRotation = this.getTextDirection(extensionLineAngle);
214
+ textAboveDirection = textRotation + Math.PI / 2;
215
+ break;
216
+ case 4: // 4 = Above second extension line
217
+ textPosition = Pt14e.project(extensionLineAngle, approxTextHalfWidth + DIMEXE + DIMASZ);
218
+ textRotation = this.getTextDirection(extensionLineAngle);
219
+ textAboveDirection = textRotation + Math.PI / 2;
220
+ break;
221
+ }
222
+
223
+ // Check if the text is aligned with the dimension line
224
+ const textAndDimlineAligned = this.alignedOrOpposite(textRotation, dimLineAngle);
225
+
226
+ // Check if the text is aligned with the extension line
227
+ const textAndExtlineAligned = this.alignedOrOpposite(textRotation, extensionLineAngle);
228
+
229
+ // Check if the text position is on an extension line
230
+ let textIsOnExtensionLine = textPosition.perpendicular(Pt13, Pt13e).isSame(textPosition) || textPosition.perpendicular(Pt14, Pt14e).isSame(textPosition);
231
+
232
+ // set the text offset to 0 for scenarios where the text offset should not be applied
233
+ if (!textAndDimlineAligned && !textIsOnExtensionLine) {
234
+ textAboveDistance = 0;
235
+ }
236
+
237
+ // DIMTAD - Text vertical position
238
+ switch (DIMTAD) {
239
+ case 0: // 0 = Centers the dimension text between the extension lines.
240
+ break;
241
+ case 1: // 1 = Places the dimension text above the dimension line except when the dimension line is not horizontal and text inside the extension lines is forced horizontal ( DIMTIH = 1).
242
+ textPosition = textPosition.project(textAboveDirection, textAboveDistance);
243
+ break;
244
+ case 2: // 2 = Places the dimension text on the side of the dimension line farthest away from the defining points.
245
+ textPosition = textPosition.project(textAboveDirection, textAboveDistance);
246
+ break;
247
+ case 3: // 3 = Places the dimension text to conform to Japanese Industrial Standards (JIS).
248
+ textPosition = textPosition.project(textAboveDirection, textAboveDistance);
249
+ break;
250
+ case 4: // 4 = Places the dimension text below the dimension line.
251
+ textPosition = textPosition.project(textAboveDirection, -textAboveDistance);
252
+ break;
253
+ }
254
+
255
+
256
+ /*
257
+ // generate the dimension text
258
+ */
259
+ // Get the dimension text using the value, position and rotation
260
+ const text = this.getDimensionText(dimension, textPosition, textRotation);
261
+ entities.push(text);
262
+
263
+ /*
264
+ // Generate points for extension and dimension lines
265
+ */
266
+ // Get the extension line start and end points
267
+ // TODO: If DIMTOFL is set force line extensions between extensions if text outside
268
+ const extLineOneStart = Pt13.project(extensionLineAngle, DIMEXO);
269
+ const extLineTwoStart = Pt14.project(extensionLineAngle, DIMEXO);
270
+
271
+ let extLineOneEnd = Pt13e.project(extensionLineAngle, DIMEXE);
272
+ let extLineTwoEnd = Pt14e.project(extensionLineAngle, DIMEXE);
273
+
274
+ /*
275
+ // generate dimension line points
276
+ */
277
+
278
+ // get the perpendicular projection of the text position onto the dimension line
279
+ const textDimlineIntersection = textPosition.perpendicular(Pt13e, Pt14e);
280
+ // check if the perpendicular projection is on the dimension line
281
+ const textDimlineIntersectionIsOnDimline = textDimlineIntersection.isOnLine(Pt13e, Pt14e);
282
+ // Check if the text position is on the dimension line
283
+ const textIsOnInternalDimLine = textPosition.isOnLine(Pt13e, Pt14e);
284
+ // Check if the text position is on an extension line
285
+ textIsOnExtensionLine = textPosition.perpendicular(Pt13, Pt13e).isSame(textPosition) || textPosition.perpendicular(Pt14, Pt14e).isSame(textPosition);
286
+
287
+ let dimLineOneStart = Pt13e;
288
+ let dimLineOneEnd = textDimlineIntersectionIsOnDimline ? textDimlineIntersection : midPoint;
289
+
290
+ let dimLineTwoStart = Pt14e;
291
+ let dimLineTwoEnd = dimLineOneEnd;
292
+
293
+ // Extend dimension line when text is outside the extension lines
294
+ if (!textDimlineIntersectionIsOnDimline && textAndDimlineAligned) {
295
+ if (!arrowsOutSide) { // Arrows are inside the extension lines
296
+ dimLineOneEnd = midPoint;
297
+ dimLineTwoEnd = midPoint;
298
+ } else { // Arrows are outside the extension lines
299
+ dimLineOneEnd = Pt13e;
300
+ dimLineTwoEnd = Pt14e;
301
+ }
302
+ // get the distance to extend the dimension line
303
+ // when text is vertically centered trim the dimension line back from the text position
304
+ // when text is not vertically centered extend the dimension line beyond the text position by half the text width
305
+ const dimlineExtendDistance = textDimlineIntersection.isSame(textPosition) ? approxTextHalfWidth + DIMGAP : -approxTextHalfWidth;
306
+
307
+ if (Pt11.distance(Pt13e) < Pt11.distance(Pt14e)) {
308
+ // Text position is closer to extension line 1
309
+ dimLineOneStart = textDimlineIntersection.project(dimLineAngle, dimlineExtendDistance);
310
+ } else {
311
+ // Text position is closer to extension line 2
312
+ dimLineTwoStart = textDimlineIntersection.project(reverseDimLineAngle, dimlineExtendDistance);
313
+ }
314
+ }
315
+
316
+ // split the dimension line when the text is centered vertically
317
+ if (textIsOnInternalDimLine) {
318
+ dimLineOneEnd = dimLineOneEnd.project(reverseDimLineAngle, approxTextWidth * 0.6);
319
+ dimLineTwoEnd = dimLineTwoEnd.project(dimLineAngle, approxTextWidth * 0.6);
320
+ }
321
+
322
+ /*
323
+ // generate extension line points
324
+ */
325
+
326
+ // Extend the extension line when text is aligned with the extension line but not on the extension line
327
+ if (textAndExtlineAligned && !textIsOnExtensionLine && !textIsOnInternalDimLine) {
328
+ if (textPosition.distance(Pt13e) < textPosition.distance(Pt14e)) {
329
+ // Text position is closer to extension line 1
330
+ const dist = extLineOneEnd.distance(textPosition.perpendicular(Pt13, Pt13e)) + approxTextHalfWidth;
331
+ extLineOneEnd = extLineOneEnd.project(extensionLineAngle, dist);
332
+ } else {
333
+ // Text position is closer to extension line 2
334
+ const dist = extLineTwoEnd.distance(textPosition.perpendicular(Pt14, Pt14e)) + approxTextHalfWidth;
335
+ extLineTwoEnd = extLineTwoEnd.project(extensionLineAngle, dist);
336
+ }
337
+ }
338
+
339
+ /*
340
+ // generate dimension geometry
341
+ */
342
+ const extLine1 = new Line({ points: [extLineOneStart, extLineOneEnd] });
343
+ // Suppress extension line 1 if DIMS1 is true
344
+ if (!DIMSE1) {
345
+ entities.push(extLine1);
346
+ }
347
+
348
+ const extLine2 = new Line({ points: [extLineTwoStart, extLineTwoEnd] });
349
+ // Suppress extension line 2 if DIMSE2 is true
350
+ if (!DIMSE2) {
351
+ entities.push(extLine2);
352
+ }
353
+
354
+ const arrowHead1 = this.getArrowHead(Pt13e, arrowsOutSide ? reverseDimLineAngle : dimLineAngle);
355
+ const arrowHead2 = this.getArrowHead(Pt14e, arrowsOutSide ? dimLineAngle : reverseDimLineAngle);
356
+
357
+ const dimLine1 = new Line({ points: [dimLineOneStart, dimLineOneEnd] });
358
+ // Suppress dimension line 1 if DIMSD1 is true
359
+ if (!DIMSD1) {
360
+ entities.push(dimLine1, arrowHead1);
361
+ }
362
+
363
+ const dimLine2 = new Line({ points: [dimLineTwoStart, dimLineTwoEnd] });
364
+ // Suppress dimension line 2 if DIMSD2 is true
365
+ if (!DIMSD2) {
366
+ entities.push(dimLine2, arrowHead2);
367
+ }
368
+
369
+ return entities;
370
+ }
371
+ }
@@ -0,0 +1,82 @@
1
+ import { DXFFile } from '../lib/dxf/dxfFile.js';
2
+ import { BaseCircularDimension } from './baseCircularDimension.js';
3
+
4
+ /**
5
+ * Diametric Dimension Entity Class
6
+ * @extends BaseCircularDimension
7
+ */
8
+ export class DiametricDimension extends BaseCircularDimension {
9
+ /**
10
+ * Create a Diametric Dimension
11
+ * @param {Array} data
12
+ */
13
+ constructor(data) {
14
+ super(data);
15
+ this.dimType.setDimType(3); // Diametric dimension
16
+ }
17
+
18
+ /**
19
+ * Register the command
20
+ * @return {Object}
21
+ * command = name of the command
22
+ * shortcut = shortcut for the command
23
+ * type = type to group command in toolbars (omitted if not shown)
24
+ */
25
+ static register() {
26
+ const command = { command: 'DiametricDimension', shortcut: 'DIMDIA' };
27
+ return command;
28
+ }
29
+
30
+ /**
31
+ * Get sequenced points from user selection
32
+ * @param {any} items
33
+ * @param {Point} textPos
34
+ * @return {Array} array of points
35
+ */
36
+ static getPointsFromSelection(items, textPos) {
37
+ const item = items[0];
38
+ const center = item.points[0];
39
+
40
+ const Pt11 = textPos;
41
+ Pt11.sequence = 11;
42
+
43
+ const angle = Pt11.angle(center);
44
+ const Pt10 = center.project(angle, item.getRadius());
45
+ Pt10.sequence = 10;
46
+ // Pt15 should be closest point to the text position
47
+ const Pt15 = center.project(angle - Math.PI, item.getRadius());
48
+ Pt15.sequence = 15;
49
+
50
+ const points = [Pt10, Pt15, Pt11];
51
+ return points;
52
+ }
53
+
54
+ /**
55
+ * Write the entity to file in the dxf format
56
+ * @param {DXFFile} file
57
+ */
58
+ dxf(file) {
59
+ const Pt10 = this.getPointBySequence(this.points, 10);
60
+ const Pt11 = this.getPointBySequence(this.points, 11);
61
+ const Pt15 = this.getPointBySequence(this.points, 15);
62
+
63
+ file.writeGroupCode('0', 'DIMENSION');
64
+ file.writeGroupCode('5', this.handle, DXFFile.Version.R2000); // Handle
65
+ file.writeGroupCode('100', 'AcDbEntity', DXFFile.Version.R2000);
66
+ file.writeGroupCode('100', 'AcDbDimension', DXFFile.Version.R2000);
67
+ file.writeGroupCode('8', this.layer);
68
+ // file.writeGroupCode('2', this.blockName); // Block not required
69
+ file.writeGroupCode('10', Pt10.x); // X - Start of Dimension Line
70
+ file.writeGroupCode('20', Pt10.y); // Y
71
+ file.writeGroupCode('30', '0.0'); // Z
72
+ file.writeGroupCode('11', Pt11.x); // X - Text Midpoint
73
+ file.writeGroupCode('21', Pt11.y); // Y
74
+ file.writeGroupCode('31', '0.0'); // Z
75
+ file.writeGroupCode('70', this.dimType.getDimType()); // DIMENSION TYPE
76
+ file.writeGroupCode('3', this.dimensionStyle); // DIMENSION STYLE
77
+ file.writeGroupCode('100', 'AcDbDiametricDimension', DXFFile.Version.R2000);
78
+ file.writeGroupCode('15', Pt15.x); // X - End of Dimension Line
79
+ file.writeGroupCode('25', Pt15.y); // Y
80
+ file.writeGroupCode('35', '0.0'); // Z
81
+ }
82
+ }