@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
@@ -1,14 +1,25 @@
1
- import {Point} from './point.js';
2
- import {Strings} from '../lib/strings.js';
3
- import {Entity} from './entity.js';
4
- import {Input, PromptOptions} from '../lib/inputManager.js';
5
- import {Logging} from '../lib/logging.js';
6
- import {DXFFile} from '../lib/dxf/dxfFile.js';
7
- import {BoundingBox} from '../lib/boundingBox.js';
8
-
9
- import {DesignCore} from '../designCore.js';
10
-
1
+ import { Point } from './point.js';
2
+ import { Strings } from '../lib/strings.js';
3
+ import { Entity } from './entity.js';
4
+ import { Input, PromptOptions } from '../lib/inputManager.js';
5
+ import { Logging } from '../lib/logging.js';
6
+ import { DXFFile } from '../lib/dxf/dxfFile.js';
7
+ import { BoundingBox } from '../lib/boundingBox.js';
8
+ import { Property } from '../properties/property.js';
9
+ import { Utils } from '../lib/utils.js';
10
+
11
+ import { DesignCore } from '../designCore.js';
12
+ import { AddState, RemoveState } from '../lib/stateManager.js';
13
+
14
+ /**
15
+ * Circle Entity Class
16
+ * @extends Entity
17
+ */
11
18
  export class Circle extends Entity {
19
+ /**
20
+ * Create a Circle Entity
21
+ * @param {Array} data
22
+ */
12
23
  constructor(data) {
13
24
  super(data);
14
25
 
@@ -20,111 +31,218 @@ export class Circle extends Entity {
20
31
  enumerable: true,
21
32
  });
22
33
 
23
- // ensure a radius is set
24
- // this.setRadius(1);
25
-
26
34
  if (data) {
27
- if (data.radius || data[40]) {
35
+ if (data.hasOwnProperty('radius') || data.hasOwnProperty('40')) {
28
36
  // DXF Groupcode 40 - Radius
29
- const radius = data.radius || data[40];
30
- this.setRadius(radius);
37
+ this.setRadius(Property.loadValue([data.radius, data[40]], 0));
31
38
  }
32
39
  }
33
40
  }
34
41
 
42
+ /**
43
+ * Register the command
44
+ * @return {Object}
45
+ * command = name of the command
46
+ * shortcut = shortcut for the command
47
+ * type = type to group command in toolbars (omitted if not shown)
48
+ */
35
49
  static register() {
36
- const command = {command: 'Circle', shortcut: 'C', type: 'Entity'};
50
+ const command = { command: 'Circle', shortcut: 'C', type: 'Entity' };
37
51
  return command;
38
52
  }
39
53
 
54
+ /**
55
+ * Execute method
56
+ * executes the workflow, requesting input required to create an entity
57
+ */
40
58
  async execute() {
41
59
  try {
42
- const op = new PromptOptions(Strings.Input.START, [Input.Type.POINT]);
60
+ const op = new PromptOptions(Strings.Input.CENTER, [Input.Type.POINT]);
43
61
  const pt1 = await DesignCore.Scene.inputManager.requestInput(op);
62
+ if (pt1 === undefined) return;
44
63
  this.points.push(pt1);
45
64
 
46
- const op2 = new PromptOptions(Strings.Input.RADIUS, [Input.Type.POINT, Input.Type.NUMBER]);
47
- const pt2 = await DesignCore.Scene.inputManager.requestInput(op2);
48
- if (Input.getType(pt2) === Input.Type.POINT) {
49
- this.points.push(pt2);
65
+ const op2 = new PromptOptions(Strings.Input.RADIUS, [Input.Type.POINT, Input.Type.NUMBER], ['Diameter']);
66
+
67
+ while (true) {
68
+ const pt2 = await DesignCore.Scene.inputManager.requestInput(op2);
69
+ if (pt2 === undefined) return;
70
+
71
+ if (Input.getType(pt2) === Input.Type.POINT) {
72
+ if (pt1.distance(pt2) <= 0) {
73
+ DesignCore.Core.notify(`${this.type} - ${Strings.Error.NONZERO}`);
74
+ continue;
75
+ }
76
+ this.points.push(pt2);
77
+ break;
78
+ } else if (Input.getType(pt2) === Input.Type.NUMBER) {
79
+ if (pt2 <= 0) {
80
+ DesignCore.Core.notify(`${this.type} - ${Strings.Error.NONZERO}`);
81
+ continue;
82
+ }
83
+ this.setRadius(pt2);
84
+ break;
85
+ } else if (Input.getType(pt2) === Input.Type.STRING && pt2 === 'Diameter') {
86
+ const op3 = new PromptOptions(Strings.Input.DIAMETER, [Input.Type.NUMBER]);
87
+ while (true) {
88
+ const diameter = await DesignCore.Scene.inputManager.requestInput(op3);
89
+ if (diameter === undefined) return;
90
+ if (diameter <= 0) {
91
+ DesignCore.Core.notify(`${this.type} - ${Strings.Error.NONZERO}`);
92
+ continue;
93
+ }
94
+ this.setRadius(diameter / 2);
95
+ break;
96
+ }
97
+ break;
98
+ }
50
99
  }
51
100
 
52
- if (Input.getType(pt2) === Input.Type.NUMBER) {
53
- this.setRadius(pt2);
54
- }
55
101
  DesignCore.Scene.inputManager.executeCommand(this);
56
102
  } catch (err) {
57
103
  Logging.instance.error(`${this.type} - ${err}`);
58
104
  }
59
105
  }
60
106
 
107
+ /**
108
+ * Preview the entity during creation
109
+ */
61
110
  preview() {
62
111
  if (this.points.length >= 1) {
63
112
  const mousePoint = DesignCore.Mouse.pointOnScene();
64
113
  const points = [this.points.at(-1), mousePoint];
65
- DesignCore.Scene.createTempItem(this.type, {points: points});
114
+ DesignCore.Scene.tempEntities.create(this.type, { points: points });
66
115
  }
67
116
  }
68
117
 
118
+ /**
119
+ * Get Circle radius
120
+ * @return {number} - circle radius
121
+ */
69
122
  getRadius() {
70
123
  return this.points[0].distance(this.points[1]);
71
124
  }
72
125
 
126
+ /**
127
+ * Set Circle radius
128
+ * @param {number} rad
129
+ */
73
130
  setRadius(rad) {
74
131
  this.points[1] = this.points[0].project(0, rad);
75
132
  }
76
133
 
134
+ /**
135
+ * Draw the entity
136
+ * @param {Object} ctx - context
137
+ * @param {number} scale
138
+ */
77
139
  draw(ctx, scale) {
78
140
  ctx.arc(this.points[0].x, this.points[0].y, this.radius, 0, 6.283);
79
141
  ctx.stroke();
80
142
  }
81
143
 
144
+ /**
145
+ * Write the entity to file in the dxf format
146
+ * @param {DXFFile} file
147
+ */
82
148
  dxf(file) {
83
149
  file.writeGroupCode('0', 'CIRCLE');
84
- file.writeGroupCode('5', file.nextHandle(), DXFFile.Version.R2000); // Handle
150
+ file.writeGroupCode('5', this.handle, DXFFile.Version.R2000); // Handle
85
151
  file.writeGroupCode('100', 'AcDbEntity', DXFFile.Version.R2000);
86
152
  file.writeGroupCode('100', 'AcDbCircle', DXFFile.Version.R2000);
87
153
  file.writeGroupCode('8', this.layer);
154
+ file.writeGroupCode('6', this.lineType);
155
+ this.writeDxfColour(file);
88
156
  file.writeGroupCode('10', this.points[0].x);
89
157
  file.writeGroupCode('20', this.points[0].y);
90
158
  file.writeGroupCode('30', '0.0');
159
+ file.writeGroupCode('39', this.lineWidth);
91
160
  file.writeGroupCode('40', this.radius);
92
161
  }
93
162
 
94
- trim(points) {
95
- if (points.length > 1) {
96
- const start = points[0];
97
- const cen = DesignCore.Mouse.pointOnScene();
98
- const end = points[1];
99
-
100
- const arcPoints = [this.points[0]];
101
-
102
- const dir = (start.x - cen.x) * (end.y - cen.y) - (start.y - cen.y) * (end.x - cen.x);
103
- if (dir > 0) {
104
- arcPoints.push(points[0], points[1]);
105
- } else if (dir < 0) {
106
- arcPoints.push(points[1], points[0]);
107
- }
163
+ /**
164
+ * Return a list of points representing a polyline version of this entity
165
+ * @return {Array}
166
+ */
167
+ toPolylinePoints() {
168
+ const startPoint = this.points[0].project(0, this.radius);
169
+ startPoint.bulge = 1;
170
+ const endPoint = this.points[0].project(0, -this.radius);
171
+ endPoint.bulge = 1;
172
+ const closurePoint = this.points[0].project(0, this.radius);
173
+ return [startPoint, endPoint, closurePoint];
174
+ }
108
175
 
176
+ /**
177
+ * Set entity points from a polyline point representation
178
+ * @param {Array} points
179
+ */
180
+ fromPolylinePoints(points) {
181
+ const center = points[0].bulgeCentrePoint(points[1]);
182
+ const radius = center.distance(points[0]);
183
+ this.points = [center, center.project(0, radius)];
184
+ }
109
185
 
110
- const data = {
111
- points: arcPoints,
112
- colour: this.colour,
113
- layer: this.layer,
114
- lineWidth: this.lineWidth,
115
- };
186
+ /**
187
+ * Trim the entity
188
+ * @param {Array} intersections
189
+ * @return {Array} - array of state changes
190
+ */
191
+ trim(intersections) {
192
+ // array to hold state changes
193
+ const stateChanges = [];
194
+
195
+ if (intersections?.length === 0 || !intersections) {
196
+ return stateChanges;
197
+ }
116
198
 
117
- DesignCore.Scene.addItem('Arc', data, DesignCore.Scene.items.indexOf(this));
199
+ const direction = 1; // Circle is always CCW for trimming purposes
200
+
201
+ // get the mouse position
202
+ const mousePosition = DesignCore.Mouse.pointOnScene();
203
+ // get the point on the arc closest to the mouse
204
+ const pointOnCircle = mousePosition.closestPointOnArc(this.points[1], this.points[1], this.points[0]);
205
+ // sort intersection points
206
+ Utils.sortPointsOnArc(intersections, this.points[0], this.points[0], this.points[0], direction);
207
+ // Repeat the first point to close the circle
208
+ const testPoints = [...intersections, intersections.at(0)]; // Closing the circle
209
+
210
+ // Test if mouse position is between two intersection points
211
+ if (testPoints.length > 1) {
212
+ for (let i = 0; i < testPoints.length - 1; i++) {
213
+ const startPoint = testPoints[i];
214
+ const endPoint = testPoints[i + 1];
215
+
216
+ // check if the mouse is between startPoint and endPoint
217
+ if (pointOnCircle.isOnArc(startPoint, endPoint, this.points[0], direction)) {
218
+ // create a new arc entity
219
+ const arc = DesignCore.CommandManager.createNew('Arc', this);
220
+ arc.handle = undefined;
221
+ // flip direction
222
+ arc.direction = direction * -1;
223
+ arc.points = [this.points[0], startPoint, endPoint];
224
+ const addState = new AddState(arc);
225
+ stateChanges.push(addState);
226
+
227
+ // Remove the existing arc
228
+ if (stateChanges.length > 0) {
229
+ const removeState = new RemoveState(this);
230
+ stateChanges.push(removeState);
231
+ return stateChanges;
232
+ }
233
+ }
234
+ }
118
235
  }
119
- }
120
236
 
121
- intersectPoints() {
122
- return {
123
- centre: this.points[0],
124
- radius: this.radius,
125
- };
237
+ return stateChanges;
126
238
  }
127
239
 
240
+ /**
241
+ * Get snap points
242
+ * @param {Point} mousePoint
243
+ * @param {number} delta
244
+ * @return {Array} - array of snap points
245
+ */
128
246
  snaps(mousePoint, delta) {
129
247
  const snaps = [];
130
248
 
@@ -154,6 +272,11 @@ export class Circle extends Entity {
154
272
  return snaps;
155
273
  }
156
274
 
275
+ /**
276
+ * Get closest point on entity
277
+ * @param {Point} P
278
+ * @return {Array} - [Point, distance]
279
+ */
157
280
  closestPoint(P) {
158
281
  // find the closest point on the circle
159
282
  const closest = P.closestPointOnArc(this.points[1], this.points[1], this.points[0]);
@@ -162,6 +285,10 @@ export class Circle extends Entity {
162
285
  return [closest, distance];
163
286
  }
164
287
 
288
+ /**
289
+ * Return boundingbox for entity
290
+ * @return {BoundingBox}
291
+ */
165
292
  boundingBox() {
166
293
  const xmin = this.points[0].x - this.radius;
167
294
  const xmax = this.points[0].x + this.radius;
@@ -1,11 +1,22 @@
1
- import {Colours} from '../lib/colours.js';
2
- import {Intersection} from '../lib/intersect.js';
3
- import {Point} from './point.js';
4
- import {Strings} from '../lib/strings.js';
1
+ import { Colours } from '../lib/colours.js';
2
+ import { EntityColour } from '../lib/colour.js';
3
+ import { Intersection } from '../lib/intersect.js';
4
+ import { Point } from './point.js';
5
+ import { Strings } from '../lib/strings.js';
6
+ import { Property } from '../properties/property.js';
5
7
 
6
- import {DesignCore} from '../designCore.js';
7
8
 
9
+ import { DesignCore } from '../designCore.js';
10
+
11
+ /**
12
+ * Entity Class
13
+ * @extend Entity
14
+ */
8
15
  export class Entity {
16
+ /**
17
+ * Create a Entity
18
+ * @param {Array} data
19
+ */
9
20
  constructor(data) {
10
21
  Object.defineProperty(this, 'type', {
11
22
  value: this.constructor.name,
@@ -17,33 +28,52 @@ export class Entity {
17
28
  writable: true,
18
29
  });
19
30
 
20
- /*
21
- Object.defineProperty(this, 'trueColour', {
22
- //enumerable: false,
31
+ Object.defineProperty(this, 'colour', {
32
+ get: this.getColour,
33
+ set: this.setColour,
34
+ });
35
+
36
+ Object.defineProperty(this, 'entityColour', {
37
+ value: new EntityColour(),
23
38
  writable: true,
24
39
  });
25
- */
26
40
 
27
41
  this.lineWidth = 2;
28
- this.colour = 'BYLAYER';
29
- this.lineType = 'BYLAYER';
42
+ this.lineType = 'ByLayer';
30
43
  this.layer = '0';
31
44
 
45
+ // DXF Groupcode 5 - Handle
46
+ Object.defineProperty(this, 'handle', {
47
+ value: Property.loadValue([data?.handle, data?.[5]]),
48
+ writable: true,
49
+ });
50
+ // DXF Groupcode 6 - lineType
51
+ this.lineType = Property.loadValue([data?.lineType, data?.[6]], 'ByLayer');
52
+ // DXF Groupcode 39 - Thickness (lineWidth)
53
+ this.lineWidth = Property.loadValue([data?.lineWidth, data?.[39]], 2);
54
+ // DXF Groupcode 8 - layername
55
+ this.layer = Property.loadValue([data?.layer, data?.[8]], '0');
32
56
 
33
57
  if (data) {
34
- if (data.points) {
58
+ if (data.hasOwnProperty('points')) {
35
59
  this.points = data.points;
36
60
  }
37
61
 
38
- if (data.colour || data[62]) {
39
- // DXF Groupcode 62 - Color Number
40
- // (present if not BYLAYER); zero indicates the BYBLOCK
41
- // (floating) color; 256 indicates BYLAYER; a negative value indicates that
42
- // the layer is turned off (optional)
43
- this.colour = data.colour || Colours.getHexColour(data[62]);
62
+ if (data.hasOwnProperty('colour') || data.hasOwnProperty('62')) {
63
+ // DXF Groupcode 62 - Color Number (present if not BYLAYER)(optional);
64
+ // zero indicates BYBLOCK
65
+ // 256 indicates BYLAYER;
66
+ // a negative value indicates that the layer is turned off
67
+ if (data.colour) {
68
+ if (Colours.isRGB(data.colour)) {
69
+ this.colour = data.colour;
70
+ }
71
+ } else if (data.hasOwnProperty('62')) {
72
+ this.entityColour.setColourFromACI(Math.abs(data[62]));
73
+ }
44
74
  }
45
75
 
46
- if (data.trueColour || data[420]) {
76
+ if (data.hasOwnProperty('trueColour') || data.hasOwnProperty('420')) {
47
77
  // DXF Groupcode 420 - true color
48
78
  // A 24-bit color value that should be dealt with in terms of bytes with values
49
79
  // of 0 to 255. The lowest byte is the blue value, the middle byte is the
@@ -51,66 +81,94 @@ export class Entity {
51
81
  // 0. The group code cannot be used by custom entities for their own data
52
82
  // because the group code is reserved for AcDbEntity, class-level color data
53
83
  // and AcDbEntity, class-level transparency data
54
- // this.trueColour = data.trueColour;
55
- const err = 'Groupcode 420 not implemented';
56
- Logging.instance.warn(`${this.type} - ${err}`);
57
- }
58
84
 
59
-
60
- if (data.lineType || data[6]) {
61
- // DXF Groupcode 6 - lineType
62
- this.lineType = data.lineType || data[6];
63
- }
64
-
65
- if (data.layer || data[8]) {
66
- // DXF Groupcode 8 - layername
67
- this.layer = data.layer || data[8];
85
+ const trueColour = Colours.trueColourToRGB(data.trueColour || data[420]);
86
+ if (trueColour) {
87
+ this.colour = trueColour;
88
+ }
68
89
  }
69
90
  }
70
91
  }
71
92
 
93
+
94
+ /**
95
+ * get rgb colour
96
+ * @return {number} rgb colour object
97
+ */
72
98
  getColour() {
73
- // if (this.trueColour !== undefined) {
74
- // return this.trueColour;
75
- // }
99
+ return this.entityColour.getColour(); ;
100
+ }
76
101
 
77
- let colour = this.colour;
102
+ /**
103
+ * get rgb colour to draw
104
+ * @return {number} rgb colour object
105
+ */
106
+ getDrawColour() {
107
+ let rgb = this.getColour();
78
108
 
79
- if (colour === 'BYLAYER') {
80
- const layer = DesignCore.LayerManager.getStyleByName(this.layer);
81
- colour = layer.colour;
109
+ if (this.entityColour.byLayer) {
110
+ const layer = DesignCore.LayerManager.getItemByName(this.layer);
111
+ rgb = layer?.colour;
82
112
  }
83
113
 
84
- return colour;
114
+ return rgb;
85
115
  }
86
116
 
117
+ /**
118
+ * Set the entity colour
119
+ * @param {Object} rgb
120
+ */
121
+ setColour(rgb) {
122
+ this.entityColour.setColour(rgb);
123
+ }
124
+
125
+ /**
126
+ * Get the line type
127
+ * @return {LType}
128
+ */
87
129
  getLineType() {
88
130
  let lineTypeName = this.lineType;
89
131
 
90
- if (lineTypeName === 'BYLAYER') {
91
- const layer = DesignCore.LayerManager.getStyleByName(this.layer);
92
- lineTypeName = layer.lineType;
132
+ if (lineTypeName.toUpperCase() === 'BYLAYER') {
133
+ const layer = DesignCore.LayerManager.getItemByName(this.layer);
134
+ lineTypeName = layer?.lineType;
93
135
  }
94
136
 
95
- const lineType = DesignCore.LTypeManager.getStyleByName(lineTypeName);
137
+ const lineType = DesignCore.LTypeManager.getItemByName(lineTypeName);
96
138
 
97
139
  return lineType;
98
140
  }
99
141
 
142
+ /**
143
+ * Write the colour to file in the dxf format
144
+ * @param {DXFFile} file
145
+ */
146
+ writeDxfColour(file) {
147
+ if (this.entityColour.aci != 256) {
148
+ file.writeGroupCode('62', this.entityColour.aci);
149
+ }
150
+ if (this.entityColour.isTrueColour) {
151
+ file.writeGroupCode('420', Colours.rgbToTrueColour(this.colour));
152
+ }
153
+ }
100
154
 
101
- within(selectionExtremes) {
102
- const layer = DesignCore.LayerManager.getStyleByName(this.layer);
155
+ /**
156
+ * Determine if the entity is within the selection
157
+ * @param {Object} selection - {min: Point, max: Point}
158
+ * @return {boolean} true if within
159
+ */
160
+ within(selection) {
161
+ const layer = DesignCore.LayerManager.getItemByName(this.layer);
103
162
 
104
- if (!layer.isSelectable) {
163
+ if (!layer?.isSelectable) {
105
164
  return;
106
165
  }
107
166
 
108
- // determin if this entities is within a the window specified by selectionExtremes
109
167
  const boundingBox = this.boundingBox();
110
- if ( boundingBox.xMin > selectionExtremes[0] &&
111
- boundingBox.xMax < selectionExtremes[1] &&
112
- boundingBox.yMin > selectionExtremes[2] &&
113
- boundingBox.yMax < selectionExtremes[3]
168
+ if (boundingBox.xMin > selection.min.x &&
169
+ boundingBox.xMax < selection.max.x &&
170
+ boundingBox.yMin > selection.min.y &&
171
+ boundingBox.yMax < selection.max.y
114
172
  ) {
115
173
  return true;
116
174
  }
@@ -118,43 +176,65 @@ export class Entity {
118
176
  return false;
119
177
  }
120
178
 
121
- touched(selectionExtremes) {
122
- const layer = DesignCore.LayerManager.getStyleByName(this.layer);
179
+ /**
180
+ * Determine if the entity is touch the selection window
181
+ * @param {Object} selection - {min: Point, max: Point}
182
+ * @return {boolean} true if touched
183
+ */
184
+ touched(selection) {
185
+ const layer = DesignCore.LayerManager.getItemByName(this.layer);
123
186
 
124
- if (!layer.isSelectable) {
187
+ if (!layer?.isSelectable) {
125
188
  return;
126
189
  }
127
190
 
128
- const rP1 = new Point(selectionExtremes[0], selectionExtremes[2]);
129
- const rP2 = new Point(selectionExtremes[1], selectionExtremes[3]);
130
-
131
- const rectPoints = {
132
- start: rP1,
133
- end: rP2,
134
- };
191
+ const rectPoints = [
192
+ selection.min,
193
+ new Point(selection.max.x, selection.min.y),
194
+ selection.max,
195
+ new Point(selection.min.x, selection.max.y),
196
+ selection.min,
197
+ ];
135
198
 
136
- const intersectFunction = `intersect${this.type}Rectangle`;
199
+ const output = Intersection.intersectPolylinePolyline(this.toPolylinePoints(), rectPoints);
137
200
 
138
- if (Intersection.hasOwnProperty(intersectFunction) === false) {
139
- const msg = `${Strings.Error.INVALIDINTERSECTTYPE}: ${this.type}`;
140
- DesignCore.Core.notify(msg);
141
- throw Error(msg);
142
- }
143
-
144
- const output = Intersection[intersectFunction](this.intersectPoints(), rectPoints);
145
-
146
- if (output.status === 'Intersection') {
201
+ if (output.status === Intersection.Status.INTERSECTION) {
147
202
  return true;
148
203
  }
149
204
  // no intersection found. return false
150
205
  return false;
151
206
  }
152
207
 
208
+ /**
209
+ * Extend the entity
210
+ * @param {Array} points
211
+ * @return {Array} - array of state changes
212
+ */
153
213
  extend(points) {
154
- // extend function to be overidden by implementation
214
+ // extend function to be overridden by implementation
215
+ DesignCore.Core.notify(`${this.type} - ${Strings.Message.NOEXTEND}`);
216
+ return [];
155
217
  }
156
218
 
219
+ /**
220
+ * Trim the entity
221
+ * @param {Array} points
222
+ * @return {Array} - array of state changes
223
+ */
157
224
  trim(points) {
158
- // trim function to be overidden by implementation
225
+ // trim function to be overridden by implementation
226
+ DesignCore.Core.notify(`${this.type} - ${Strings.Message.NOTRIM}`);
227
+ return [];
228
+ }
229
+
230
+ /**
231
+ * Set a property if it exists
232
+ * @param {string} property
233
+ * @param {any} value
234
+ */
235
+ setProperty(property, value) {
236
+ if (this.hasOwnProperty(property)) {
237
+ this[property] = value;
238
+ }
159
239
  }
160
240
  }