@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,22 +1,41 @@
1
- import {Strings} from '../lib/strings.js';
2
- import {Tool} from './tool.js';
3
- import {Utils} from '../lib/utils.js';
4
- import {Input, PromptOptions} from '../lib/inputManager.js';
5
- import {Logging} from '../lib/logging.js';
6
-
7
- import {DesignCore} from '../designCore.js';
8
-
9
-
1
+ import { Strings } from '../lib/strings.js';
2
+ import { Tool } from './tool.js';
3
+ import { Utils } from '../lib/utils.js';
4
+ import { Input, PromptOptions } from '../lib/inputManager.js';
5
+ import { Logging } from '../lib/logging.js';
6
+ import { Point } from '../entities/point.js';
7
+ import { UpdateState } from '../lib/stateManager.js';
8
+
9
+ import { DesignCore } from '../designCore.js';
10
+
11
+ /**
12
+ * Rotate Command Class
13
+ * @extends Tool
14
+ */
10
15
  export class Rotate extends Tool {
16
+ /** Create a Rotate command */
11
17
  constructor() {
12
18
  super();
19
+ this.baseAngle = 0;
20
+ this.basePoint = null;
13
21
  }
14
22
 
23
+ /**
24
+ * Register the command
25
+ * @return {Object}
26
+ * command = name of the command
27
+ * shortcut = shortcut for the command
28
+ * type = type to group command in toolbars (omitted if not shown)
29
+ */
15
30
  static register() {
16
- const command = {command: 'Rotate', shortcut: 'RO', type: 'Tool'};
31
+ const command = { command: 'Rotate', shortcut: 'RO', type: 'Tool' };
17
32
  return command;
18
33
  }
19
34
 
35
+ /**
36
+ * Execute method
37
+ * executes the workflow, requesting input required to perform the command
38
+ */
20
39
  async execute() {
21
40
  try {
22
41
  const op = new PromptOptions(Strings.Input.SELECTIONSET, [Input.Type.SELECTIONSET]);
@@ -26,87 +45,103 @@ export class Rotate extends Tool {
26
45
  }
27
46
 
28
47
  const op2 = new PromptOptions(Strings.Input.BASEPOINT, [Input.Type.POINT]);
29
- const pt1 = await DesignCore.Scene.inputManager.requestInput(op2);
30
- this.points.push(pt1);
31
-
32
- const op3 = new PromptOptions(Strings.Input.START, [Input.Type.POINT]);
33
- const pt2 = await DesignCore.Scene.inputManager.requestInput(op3);
34
- this.points.push(pt2);
35
-
36
- const op4 = new PromptOptions(Strings.Input.ROTATION, [Input.Type.POINT, Input.Type.NUMBER]);
37
- const pt3 = await DesignCore.Scene.inputManager.requestInput(op4);
38
- if (Input.getType(pt3) === Input.Type.POINT) {
39
- this.points.push(pt3);
40
- } else if (Input.getType(pt3) === Input.Type.NUMBER) {
41
- const basePoint = this.points.at(0);
42
- const startPoint = this.points.at(1);
43
- const angle = Utils.degrees2radians(pt3);
44
- const point = startPoint.rotate(basePoint, angle);
45
- this.points.push(point);
48
+ const input1 = await DesignCore.Scene.inputManager.requestInput(op2);
49
+ if (input1 === undefined) return;
50
+ this.points.push(input1);
51
+
52
+ while (this.points.length < 2) {
53
+ const op3 = new PromptOptions(Strings.Input.ROTATION, [Input.Type.POINT, Input.Type.NUMBER], ['Reference']);
54
+ const input2 = await DesignCore.Scene.inputManager.requestInput(op3);
55
+ if (input2 === undefined) return;
56
+
57
+ if (Input.getType(input2) === Input.Type.STRING) {
58
+ // set the base angle to null to prevent the preview
59
+ this.baseAngle = null;
60
+ const op4 = new PromptOptions(Strings.Input.START, [Input.Type.POINT]);
61
+ const refBase = await DesignCore.Scene.inputManager.requestInput(op4);
62
+ if (refBase === undefined) return;
63
+ // set the base point to the reference start point
64
+ this.basePoint = refBase;
65
+
66
+ const op5 = new PromptOptions(Strings.Input.END, [Input.Type.POINT]);
67
+ const refEnd = await DesignCore.Scene.inputManager.requestInput(op5);
68
+ if (refEnd === undefined) return;
69
+ // set the base angle to the reference
70
+ this.baseAngle = refBase.angle(refEnd);
71
+ // set the base point to null
72
+ this.basePoint = null;
73
+ } else if (Input.getType(input2) === Input.Type.NUMBER) {
74
+ const basePoint = this.points.at(0);
75
+ const angle = Utils.degrees2radians(input2);
76
+ const point = basePoint.project(angle, 100);
77
+ this.points.push(point);
78
+ } else if (Input.getType(input2) === Input.Type.POINT) {
79
+ this.points.push(input2);
80
+ }
46
81
  }
47
82
 
48
-
49
83
  DesignCore.Scene.inputManager.executeCommand();
50
84
  } catch (err) {
51
85
  Logging.instance.error(`${this.type} - ${err}`);
52
86
  }
53
87
  }
54
88
 
89
+ /**
90
+ * Preview the command during execution
91
+ */
55
92
  preview() {
56
93
  const mousePoint = DesignCore.Mouse.pointOnScene();
57
94
 
58
- if (this.points.length >= 1) {
95
+ if (this.points.length >= 1 && this.baseAngle !== null || this.basePoint !== null) {
59
96
  // Draw a line
60
- const points = [this.points.at(0), mousePoint];
61
-
62
- DesignCore.Scene.createTempItem('Line', {points: points});
97
+ const center = this.basePoint === null ? this.points.at(0) : this.basePoint;
98
+ const points = [center, mousePoint];
99
+ DesignCore.Scene.tempEntities.create('Line', { points: points });
63
100
  }
64
101
 
65
- if (this.points.length >= 2) {
66
- const A = this.points[0].x - this.points[1].x;
67
- const O = this.points[0].y - this.points[1].y;
68
-
69
- const A1 = this.points[0].x - mousePoint.x;
70
- const O1 = this.points[0].y - mousePoint.y;
71
-
72
- const ang1 = Math.atan2(O, A);
73
- const ang2 = Math.atan2(O1, A1);
74
-
75
- const theta = ang2 - ang1;
76
-
77
- for (let i = 0; i <DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
78
- for (let j = 0; j <DesignCore.Scene.selectionManager.selectedItems[i].points.length; j++) {
79
- const x = this.points[0].x + (DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].x - this.points[0].x) * Math.cos(theta) - (DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].y - this.points[0].y) * Math.sin(theta);
80
- const y = this.points[0].y + (DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].x - this.points[0].x) * Math.sin(theta) + (DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].y - this.points[0].y) * Math.cos(theta);
81
-
82
- DesignCore.Scene.selectionManager.selectedItems[i].points[j].x = x;
83
- DesignCore.Scene.selectionManager.selectedItems[i].points[j].y = y;
84
- }
102
+ if (this.points.length >= 1) {
103
+ const ang = this.points[0].angle(mousePoint);
104
+ const theta = this.baseAngle === null ? 0 : ang - this.baseAngle;
105
+ const center = this.points[0];
106
+
107
+ for (let i = 0; i < DesignCore.Scene.selectionManager.selectedItems.length; i++) {
108
+ const item = DesignCore.Scene.selectionManager.selectedItems[i];
109
+ // get the original points from the scene entities
110
+ const entityIndex = DesignCore.Scene.selectionManager.selectionSet.selectionSet[i];
111
+ const originalItem = DesignCore.Scene.entities.get(entityIndex);
112
+ item.setProperty('points', this.getRotatedPoints(originalItem.points, center, theta));
85
113
  }
86
114
  }
87
115
  };
88
116
 
89
-
117
+ /**
118
+ * Perform the command
119
+ */
90
120
  action() {
91
- const A = this.points[0].x - this.points[1].x;
92
- const O = this.points[0].y - this.points[1].y;
93
-
94
- const A1 = this.points[0].x - this.points[2].x;
95
- const O1 = this.points[0].y - this.points[2].y;
96
-
97
- const ang1 = Math.atan2(O, A);
98
- const ang2 = Math.atan2(O1, A1);
121
+ const ang = this.points[0].angle(this.points[1]);
122
+ const theta = ang - this.baseAngle;
123
+ const center = this.points[0];
99
124
 
100
- const theta = ang2 - ang1;
125
+ const stateChanges = [];
101
126
 
102
- for (let i = 0; i <DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
103
- for (let j = 0; j <DesignCore.Scene.selectionManager.selectedItems[i].points.length; j++) {
104
- const x = this.points[0].x + (DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].x - this.points[0].x) * Math.cos(theta) - (DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].y - this.points[0].y) * Math.sin(theta);
105
- const y = this.points[0].y + (DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].x - this.points[0].x) * Math.sin(theta) + (DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].y - this.points[0].y) * Math.cos(theta);
106
-
107
- DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].x = x;
108
- DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].points[j].y = y;
109
- }
127
+ for (let index = 0; index < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; index++) {
128
+ const item = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[index]);
129
+ const stateChange = new UpdateState(item, { points: this.getRotatedPoints(item.points, center, theta) });
130
+ stateChanges.push(stateChange);
110
131
  }
132
+
133
+ DesignCore.Scene.commit(stateChanges);
111
134
  };
135
+
136
+ /**
137
+ * Get rotated points
138
+ * @param {Array} points
139
+ * @param {Point} center
140
+ * @param {Point} theta
141
+ * @return {Array} rotatedPoints
142
+ */
143
+ getRotatedPoints(points, center, theta) {
144
+ const rotatedPoints = points.map((p) => new Point(p.x, p.y, p.bulge, p.sequence).rotate(center, theta));
145
+ return rotatedPoints;
146
+ }
112
147
  }
@@ -0,0 +1,166 @@
1
+ import { Strings } from '../lib/strings.js';
2
+ import { Tool } from './tool.js';
3
+ import { Input, PromptOptions } from '../lib/inputManager.js';
4
+ import { Logging } from '../lib/logging.js';
5
+ import { Point } from '../entities/point.js';
6
+ import { UpdateState } from '../lib/stateManager.js';
7
+
8
+ import { DesignCore } from '../designCore.js';
9
+
10
+ /**
11
+ * Scale Command Class
12
+ * @extends Tool
13
+ */
14
+ export class Scale extends Tool {
15
+ /** Create a Scale command */
16
+ constructor() {
17
+ super();
18
+ this.scaleFactor = 1;
19
+ this.referencePoint = null;
20
+ this.referenceLength = null;
21
+ }
22
+
23
+ /**
24
+ * Register the command
25
+ * @return {Object}
26
+ * command = name of the command
27
+ * shortcut = shortcut for the command
28
+ * type = type to group command in toolbars (omitted if not shown)
29
+ */
30
+ static register() {
31
+ const command = { command: 'Scale', shortcut: 'SC' }; // , type: 'Tool' };
32
+ return command;
33
+ }
34
+
35
+ /**
36
+ * Execute method
37
+ * executes the workflow, requesting input required to perform the command
38
+ */
39
+ async execute() {
40
+ try {
41
+ const op = new PromptOptions(Strings.Input.SELECTIONSET, [Input.Type.SELECTIONSET]);
42
+
43
+ if (!DesignCore.Scene.selectionManager.selectionSet.selectionSet.length) {
44
+ await DesignCore.Scene.inputManager.requestInput(op);
45
+ }
46
+
47
+ const op2 = new PromptOptions(Strings.Input.BASEPOINT, [Input.Type.POINT]);
48
+ const basePoint = await DesignCore.Scene.inputManager.requestInput(op2);
49
+ if (basePoint === undefined) return;
50
+ this.points.push(basePoint);
51
+
52
+ while (this.points.length < 2) {
53
+ const op3 = new PromptOptions(Strings.Input.SCALEFACTOR, [Input.Type.POINT, Input.Type.NUMBER], ['Reference']);
54
+ const input = await DesignCore.Scene.inputManager.requestInput(op3);
55
+ if (input === undefined) return;
56
+
57
+ if (Input.getType(input) === Input.Type.STRING) {
58
+ // Reference workflow: define a reference length then a new length
59
+ // set referencePoint temporarily to prevent preview scaling
60
+ this.referencePoint = basePoint;
61
+
62
+ const op4 = new PromptOptions(Strings.Input.REFERENCELENGTH, [Input.Type.POINT, Input.Type.NUMBER]);
63
+ const refInput = await DesignCore.Scene.inputManager.requestInput(op4);
64
+ if (refInput === undefined) return;
65
+
66
+ let referenceLength;
67
+ if (Input.getType(refInput) === Input.Type.NUMBER) {
68
+ referenceLength = refInput;
69
+ this.referencePoint = null;
70
+ } else {
71
+ // refInput is a point — store it and ask for second point
72
+ this.referencePoint = refInput;
73
+ const op5 = new PromptOptions(Strings.Input.END, [Input.Type.POINT]);
74
+ const refEnd = await DesignCore.Scene.inputManager.requestInput(op5);
75
+ if (refEnd === undefined) return;
76
+ referenceLength = refInput.distance(refEnd);
77
+ this.referencePoint = null;
78
+ }
79
+
80
+ if (referenceLength === 0) return;
81
+
82
+ this.referenceLength = referenceLength;
83
+ const op6 = new PromptOptions(Strings.Input.NEWLENGTH, [Input.Type.POINT, Input.Type.NUMBER]);
84
+ const newInput = await DesignCore.Scene.inputManager.requestInput(op6);
85
+ if (newInput === undefined) return;
86
+
87
+ let newLength;
88
+ if (Input.getType(newInput) === Input.Type.NUMBER) {
89
+ newLength = newInput;
90
+ } else {
91
+ newLength = basePoint.distance(newInput);
92
+ }
93
+
94
+ this.scaleFactor = newLength / referenceLength;
95
+ // Push a dummy second point to satisfy the loop condition
96
+ this.points.push(basePoint);
97
+ } else if (Input.getType(input) === Input.Type.NUMBER) {
98
+ this.scaleFactor = input;
99
+ this.points.push(basePoint);
100
+ } else if (Input.getType(input) === Input.Type.POINT) {
101
+ // Scale factor is the distance from the base point to the input point
102
+ const distance = basePoint.distance(input);
103
+ this.scaleFactor = distance;
104
+ this.points.push(input);
105
+ }
106
+ }
107
+
108
+ DesignCore.Scene.inputManager.executeCommand();
109
+ } catch (err) {
110
+ Logging.instance.error(`${this.type} - ${err}`);
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Preview the command during execution
116
+ */
117
+ preview() {
118
+ const mousePoint = DesignCore.Mouse.pointOnScene();
119
+
120
+ if (this.points.length >= 1 && this.referencePoint === null) {
121
+ // Draw a line from base point to mouse
122
+ const points = [this.points[0], mousePoint];
123
+ DesignCore.Scene.tempEntities.create('Line', { points: points });
124
+
125
+ const base = this.points[0];
126
+ const distance = base.distance(mousePoint);
127
+ if (distance === 0) return;
128
+
129
+ const factor = this.referenceLength !== null ? distance / this.referenceLength : distance;
130
+
131
+ for (let i = 0; i < DesignCore.Scene.selectionManager.selectedItems.length; i++) {
132
+ const item = DesignCore.Scene.selectionManager.selectedItems[i];
133
+ const entityIndex = DesignCore.Scene.selectionManager.selectionSet.selectionSet[i];
134
+ const originalItem = DesignCore.Scene.entities.get(entityIndex);
135
+ item.setProperty('points', this.getScaledPoints(originalItem.points, base, factor));
136
+ }
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Perform the command
142
+ */
143
+ action() {
144
+ const base = this.points[0];
145
+ const stateChanges = [];
146
+
147
+ for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
148
+ const item = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]);
149
+ const stateChange = new UpdateState(item, { points: this.getScaledPoints(item.points, base, this.scaleFactor) });
150
+ stateChanges.push(stateChange);
151
+ }
152
+
153
+ DesignCore.Scene.commit(stateChanges);
154
+ }
155
+
156
+ /**
157
+ * Get scaled points about a base point
158
+ * @param {Array} points
159
+ * @param {Point} base
160
+ * @param {number} factor
161
+ * @return {Array} scaledPoints
162
+ */
163
+ getScaledPoints(points, base, factor) {
164
+ return points.map((p) => new Point(p.x, p.y, p.bulge, p.sequence).scaleFrom(base, factor));
165
+ }
166
+ }
@@ -1,4 +1,8 @@
1
+ /**
2
+ * Tool Class
3
+ */
1
4
  export class Tool {
5
+ /** Create a Tool command */
2
6
  constructor() {
3
7
  Object.defineProperty(this, 'type', {
4
8
  value: this.constructor.name,
@@ -11,12 +15,18 @@ export class Tool {
11
15
  });
12
16
  }
13
17
 
14
- action() {
15
- // action function to be overidden by implementation
18
+ /**
19
+ * Preview the command during execution
20
+ */
21
+ preview() {
22
+ // preview function to be overridden by implementation
16
23
  };
17
24
 
18
- preview() {
19
- // preview function to be overidden by implementation
25
+ /**
26
+ * Perform the command
27
+ */
28
+ action() {
29
+ // action function to be overridden by implementation
20
30
  };
21
31
  }
22
32
 
@@ -1,72 +1,111 @@
1
- import {Intersection} from '../lib/intersect.js';
2
- import {Strings} from '../lib/strings.js';
3
- import {Tool} from './tool.js';
4
- import {Input, PromptOptions} from '../lib/inputManager.js';
5
- import {Logging} from '../lib/logging.js';
1
+ import { Intersection } from '../lib/intersect.js';
2
+ import { Strings } from '../lib/strings.js';
3
+ import { Tool } from './tool.js';
4
+ import { Input, PromptOptions } from '../lib/inputManager.js';
5
+ import { Logging } from '../lib/logging.js';
6
6
 
7
- import {DesignCore} from '../designCore.js';
7
+ import { DesignCore } from '../designCore.js';
8
8
 
9
+ /**
10
+ * Trim Command Class
11
+ * @extends Tool
12
+ */
9
13
  export class Trim extends Tool {
14
+ /** Create a Trim command */
10
15
  constructor() {
11
16
  super();
12
- this.selectedIndex;
17
+ this.selectedItem = null;
18
+ this.selectedBoundaryItems = [];
13
19
  }
14
20
 
21
+ /**
22
+ * Register the command
23
+ * @return {Object}
24
+ * command = name of the command
25
+ * shortcut = shortcut for the command
26
+ * type = type to group command in toolbars (omitted if not shown)
27
+ */
15
28
  static register() {
16
- const command = {command: 'Trim', shortcut: 'TR', type: 'Tool'};
29
+ const command = { command: 'Trim', shortcut: 'TR', type: 'Tool' };
17
30
  return command;
18
31
  }
19
32
 
33
+ /**
34
+ * Execute method
35
+ * executes the workflow, requesting input required to perform the command
36
+ */
20
37
  async execute() {
21
38
  try {
22
39
  const op = new PromptOptions(Strings.Input.BOUNDARY, [Input.Type.SELECTIONSET]);
23
40
 
24
41
  if (!DesignCore.Scene.selectionManager.selectionSet.selectionSet.length) {
25
- await DesignCore.Scene.inputManager.requestInput(op);
42
+ const boundary = await DesignCore.Scene.inputManager.requestInput(op);
43
+ if (boundary === undefined) return;
44
+ }
45
+
46
+ // add all selected items to boundary items
47
+ for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
48
+ const boundaryItem = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]);
49
+ this.selectedBoundaryItems.push(boundaryItem);
26
50
  }
27
51
 
28
52
  const op2 = new PromptOptions(Strings.Input.SELECT, [Input.Type.SINGLESELECTION]);
29
53
  while (true) {
30
54
  const selection = await DesignCore.Scene.inputManager.requestInput(op2);
31
- this.selectedIndex = selection.selectedItemIndex;
55
+ if (selection === undefined) break;
56
+ this.selectedItem = DesignCore.Scene.entities.get(selection.selectedItemIndex);
57
+ DesignCore.Scene.selectionManager.removeLastSelection();
32
58
  DesignCore.Scene.inputManager.actionCommand();
33
59
  }
34
- } catch (error) {
60
+
61
+ DesignCore.Scene.inputManager.executeCommand();
62
+ } catch (err) {
35
63
  Logging.instance.error(`${this.type} - ${err}`);
36
64
  }
37
65
  }
38
66
 
39
- action() {
40
- const item = this.selectedIndex;
67
+ /**
68
+ * Preview the command during execution
69
+ */
70
+ preview() {
71
+ // No Preview
72
+ }
41
73
 
42
- if (item !== undefined) {
74
+ /**
75
+ * Perform the command
76
+ */
77
+ action() {
78
+ if (this.selectedItem && this.selectedBoundaryItems.length) {
43
79
  const intersectPoints = [];
44
- let TrimItem;
45
80
 
46
- for (let i = 0; i <DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
47
- if (DesignCore.Scene.selectionManager.selectionSet.selectionSet[i] !== item) {
48
- const boundaryItem = DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]];
49
- TrimItem = DesignCore.Scene.items[item];
50
-
51
- const functionName = 'intersect' + boundaryItem.type + TrimItem.type;
52
- const intersect = Intersection[functionName](boundaryItem.intersectPoints(), TrimItem.intersectPoints());
53
-
54
- if (intersect.points.length) {
55
- for (let point = 0; point < intersect.points.length; point++) {
56
- intersectPoints.push(intersect.points[point]);
81
+ for (const boundaryItem of this.selectedBoundaryItems) {
82
+ if (boundaryItem !== this.selectedItem) {
83
+ try {
84
+ const intersect = Intersection.intersectPolylinePolyline(boundaryItem.toPolylinePoints(), this.selectedItem.toPolylinePoints());
85
+ if (intersect.points.length) {
86
+ for (let point = 0; point < intersect.points.length; point++) {
87
+ intersectPoints.push(intersect.points[point]);
88
+ }
57
89
  }
90
+ } catch {
91
+ Logging.instance.warn(`${this.constructor.name}: Error intersecting between ${boundaryItem.type} and ${this.selectedItem.type}`);
92
+ continue;
58
93
  }
59
94
  }
60
95
  }
61
96
 
62
- if (intersectPoints) {
63
- TrimItem.trim(intersectPoints);
97
+ if (intersectPoints.length) {
98
+ const stateChanges = this.selectedItem.trim(intersectPoints);
99
+ if (stateChanges?.length) {
100
+ DesignCore.Scene.commit(stateChanges);
101
+ }
102
+ } else {
103
+ DesignCore.Core.notify(`${this.type} - ${this.selectedItem.type} ${Strings.Message.NOTRIM}`);
64
104
  }
65
-
66
- // remove item from selection set and reset the selectedIndex
67
- DesignCore.Scene.selectionManager.removeFromSelectionSet(this.selectedIndex);
68
- this.selectedIndex = undefined;
69
105
  }
106
+
107
+ // reset selected item
108
+ this.selectedItem = null;
70
109
  }
71
110
  }
72
111