@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.
- package/.eslintrc.json +14 -7
- package/.github/workflows/DesignCoreQA.yml +3 -1
- package/README.md +11 -4
- package/TODO.md +19 -0
- package/core/core/core.js +49 -42
- package/core/designCore.js +61 -2
- package/core/dimensions/alignedDimension.js +142 -0
- package/core/dimensions/angularDimension.js +550 -0
- package/core/dimensions/baseCircularDimension.js +244 -0
- package/core/dimensions/baseDimension.js +558 -0
- package/core/dimensions/baseLinearDimension.js +371 -0
- package/core/dimensions/diametricDimension.js +82 -0
- package/core/dimensions/dimension.js +298 -0
- package/core/dimensions/linearDimension.js +29 -0
- package/core/dimensions/radialDimension.js +78 -0
- package/core/dimensions/rotatedDimension.js +167 -0
- package/core/entities/arc.js +314 -60
- package/core/entities/arctext.js +642 -0
- package/core/entities/basePolyline.js +553 -94
- package/core/entities/circle.js +181 -54
- package/core/entities/entity.js +154 -74
- package/core/entities/hatch.js +807 -0
- package/core/entities/insert.js +200 -39
- package/core/entities/line.js +196 -134
- package/core/entities/lwpolyline.js +21 -44
- package/core/entities/point.js +194 -29
- package/core/entities/polyline.js +54 -7
- package/core/entities/rectangle.js +43 -13
- package/core/entities/solid.js +43 -6
- package/core/entities/text.js +324 -181
- package/core/lib/boundingBox.js +73 -13
- package/core/lib/canvas.js +256 -65
- package/core/lib/clipboard.js +198 -0
- package/core/lib/colour.js +144 -0
- package/core/lib/colours.js +367 -301
- package/core/lib/commandLine.js +16 -28
- package/core/lib/commandManager.js +115 -58
- package/core/lib/constants.js +23 -0
- package/core/lib/dxf/dxf.js +249 -34
- package/core/lib/dxf/dxfFile.js +23 -38
- package/core/lib/dxf/dxfIterator.js +17 -5
- package/core/lib/dxf/dxfRead.js +23 -7
- package/core/lib/dxf/dxfWrite.js +39 -129
- package/core/lib/dxf/handleManager.js +97 -0
- package/core/lib/dxf/sections/blocks.js +16 -2
- package/core/lib/dxf/sections/entities.js +17 -3
- package/core/lib/dxf/sections/header.js +10 -1
- package/core/lib/dxf/sections/objects.js +36 -0
- package/core/lib/dxf/sections/section.js +43 -5
- package/core/lib/dxf/sections/tables.js +17 -3
- package/core/lib/entityManager.js +178 -0
- package/core/lib/fileio.js +14 -4
- package/core/lib/headers.js +229 -0
- package/core/lib/input.js +46 -0
- package/core/lib/inputManager.js +199 -194
- package/core/lib/intersect.js +341 -468
- package/core/lib/logging.js +25 -1
- package/core/lib/matrix.js +6 -8
- package/core/lib/mouse.js +24 -79
- package/core/lib/patterns.js +690 -0
- package/core/lib/promptOptions.js +133 -0
- package/core/lib/scene.js +71 -174
- package/core/lib/selectionManager.js +74 -48
- package/core/lib/selectionWindow.js +24 -10
- package/core/lib/settings.js +18 -11
- package/core/lib/snapping.js +129 -21
- package/core/lib/stateManager.js +288 -0
- package/core/lib/strings.js +57 -5
- package/core/lib/utils.js +95 -11
- package/core/objects/dictionary.js +43 -0
- package/core/objects/dictionaryManager.js +80 -0
- package/core/properties/dimType.js +117 -0
- package/core/properties/flags.js +66 -0
- package/core/properties/property.js +26 -0
- package/core/properties/propertyManager.js +65 -19
- package/core/tables/appId.js +31 -0
- package/core/tables/appIdManager.js +44 -0
- package/core/tables/block.js +323 -0
- package/core/tables/blockManager.js +48 -0
- package/core/tables/blockRecord.js +29 -0
- package/core/tables/blockRecordManager.js +37 -0
- package/core/tables/dimStyle.js +627 -0
- package/core/tables/dimStyleManager.js +187 -0
- package/core/tables/endblk.js +28 -0
- package/core/tables/layer.js +219 -0
- package/core/tables/layerManager.js +47 -0
- package/core/tables/ltype.js +85 -0
- package/core/tables/ltypeManager.js +65 -0
- package/core/tables/style.js +145 -0
- package/core/tables/styleManager.js +55 -0
- package/core/tables/styleManagerBase.js +110 -0
- package/core/tables/tableManagerBase.js +354 -0
- package/core/tables/ucs.js +28 -0
- package/core/tables/ucsManager.js +44 -0
- package/core/tables/view.js +28 -0
- package/core/tables/viewManager.js +44 -0
- package/core/tables/vport.js +70 -0
- package/core/tables/vportManager.js +65 -0
- package/core/tools/chamfer.js +343 -0
- package/core/tools/chamferFilletBase.js +162 -0
- package/core/tools/copy.js +68 -40
- package/core/tools/copybase.js +65 -0
- package/core/tools/copyclip.js +59 -0
- package/core/tools/cornerEntity.js +138 -0
- package/core/tools/cutclip.js +72 -0
- package/core/tools/distance.js +37 -9
- package/core/tools/erase.js +43 -13
- package/core/tools/explode.js +117 -0
- package/core/tools/extend.js +71 -32
- package/core/tools/fillet.js +336 -0
- package/core/tools/identify.js +33 -6
- package/core/tools/matchProp.js +106 -0
- package/core/tools/mirror.js +141 -0
- package/core/tools/move.js +65 -32
- package/core/tools/offset.js +321 -0
- package/core/tools/pan.js +54 -0
- package/core/tools/pasteclip.js +93 -0
- package/core/tools/purge.js +90 -0
- package/core/tools/rotate.js +105 -70
- package/core/tools/scale.js +166 -0
- package/core/tools/tool.js +14 -4
- package/core/tools/trim.js +71 -32
- package/core/tools/zoom.js +152 -0
- package/package.json +3 -305
- package/test/dimensions/alignedDimension.test.js +211 -0
- package/test/dimensions/angularDimension.test.js +243 -0
- package/test/dimensions/baseDimension.test.js +239 -0
- package/test/dimensions/diametricDimension.test.js +203 -0
- package/test/dimensions/dimension.test.js +102 -0
- package/test/dimensions/radialDimension.test.js +203 -0
- package/test/dimensions/rotatedDimension.test.js +224 -0
- package/test/entities/arc.test.js +463 -41
- package/test/entities/arctext.test.js +329 -0
- package/test/entities/basePolyline.test.js +459 -10
- package/test/entities/circle.test.js +312 -7
- package/test/entities/entity.test.js +28 -9
- package/test/entities/hatch.test.js +606 -0
- package/test/entities/insert.test.js +90 -0
- package/test/entities/line.test.js +182 -6
- package/test/entities/point.test.js +375 -37
- package/test/entities/solid.test.js +156 -0
- package/test/entities/text.test.js +533 -7
- package/test/integration/exportIntegration.reference.dxf +1706 -0
- package/test/integration/exportIntegration.test.js +186 -0
- package/test/integration/importExportIntegration.test.js +126 -0
- package/test/integration/intersectionIntegration.test.js +880 -0
- package/test/integration/userInputIntegration.reference.dxf +1410 -0
- package/test/integration/userInputIntegration.test.js +269 -0
- package/test/lib/boundingBox.test.js +26 -2
- package/test/lib/canvas.test.js +613 -5
- package/test/lib/clipboard.test.js +70 -0
- package/test/lib/colour.test.js +114 -0
- package/test/lib/colours.test.js +63 -18
- package/test/lib/commandLine.test.js +159 -22
- package/test/lib/commandManager.test.js +4 -4
- package/test/lib/constants.test.js +9 -0
- package/test/lib/dxf/dxfFile.test.js +6 -2
- package/test/lib/dxf/dxfIterator.test.js +1 -1
- package/test/lib/dxf/dxfWrite.test.js +173 -0
- package/test/lib/dxf/handleManager.test.js +137 -0
- package/test/lib/dxf/sections/blocks.test.js +5 -5
- package/test/lib/dxf/sections/entities.test.js +4 -4
- package/test/lib/dxf/sections/header.test.js +18 -4
- package/test/lib/dxf/sections/objects.test.js +132 -0
- package/test/lib/dxf/sections/section.test.js +29 -29
- package/test/lib/dxf/sections/tables.test.js +3 -3
- package/test/lib/entityManager.test.js +163 -0
- package/test/lib/headers.test.js +233 -0
- package/test/lib/inputManager.test.js +1144 -5
- package/test/lib/intersect.test.js +454 -331
- package/test/lib/logging.test.js +1 -1
- package/test/lib/matrix.test.js +1 -1
- package/test/lib/mouse.test.js +327 -4
- package/test/lib/patterns.test.js +105 -0
- package/test/lib/promptOptions.test.js +179 -0
- package/test/lib/scene.test.js +16 -52
- package/test/lib/selectionManager.test.js +17 -5
- package/test/lib/settings.test.js +111 -5
- package/test/lib/snapping.test.js +142 -4
- package/test/lib/stateManager.test.js +155 -0
- package/test/lib/utils.test.js +81 -1
- package/test/objects/dictionary.test.js +81 -0
- package/test/objects/dictionaryManager.test.js +34 -0
- package/test/properties/dimType.test.js +62 -0
- package/test/properties/flags.test.js +164 -0
- package/test/properties/property.test.js +13 -0
- package/test/properties/propertyManager.test.js +10 -11
- package/test/tables/appId.test.js +46 -0
- package/test/tables/appIdManager.test.js +72 -0
- package/test/tables/block.test.js +157 -0
- package/test/tables/blockManager.test.js +52 -0
- package/test/tables/blockRecord.test.js +39 -0
- package/test/tables/blockRecordManager.test.js +60 -0
- package/test/tables/dimstyle.test.js +72 -0
- package/test/tables/endblk.test.js +30 -0
- package/test/tables/layer.test.js +95 -0
- package/test/tables/layerManager.test.js +172 -0
- package/test/{styles → tables}/ltype.test.js +7 -7
- package/test/{styles → tables}/ltypeManager.test.js +2 -2
- package/test/tables/style.test.js +44 -0
- package/test/tables/stylemanagerbase.test.js +220 -0
- package/test/tables/tableManagerBase.test.js +194 -0
- package/test/tables/ucs.test.js +37 -0
- package/test/tables/ucsManager.test.js +48 -0
- package/test/tables/view.test.js +37 -0
- package/test/tables/viewManager.test.js +48 -0
- package/test/tables/vport.test.js +117 -0
- package/test/tables/vportManager.test.js +54 -0
- package/test/test-helpers/test-helpers.js +66 -0
- package/test/tools/chamfer.test.js +970 -0
- package/test/tools/chamferFilletBase.test.js +446 -0
- package/test/tools/copy.test.js +22 -14
- package/test/tools/copybase.test.js +93 -0
- package/test/tools/copyclip.test.js +92 -0
- package/test/tools/cornerEntity.test.js +201 -0
- package/test/tools/cutclip.test.js +94 -0
- package/test/tools/distance.test.js +140 -18
- package/test/tools/erase.test.js +12 -12
- package/test/tools/explode.test.js +45 -0
- package/test/tools/extend.test.js +326 -44
- package/test/tools/fillet.test.js +831 -0
- package/test/tools/identify.test.js +115 -16
- package/test/tools/matchProp.test.js +84 -0
- package/test/tools/mirror.test.js +475 -0
- package/test/tools/move.test.js +75 -19
- package/test/tools/offset.test.js +748 -0
- package/test/tools/pan.test.js +72 -0
- package/test/tools/pasteclip.test.js +100 -0
- package/test/tools/purge.test.js +89 -0
- package/test/tools/rotate.test.js +89 -23
- package/test/tools/scale.test.js +529 -0
- package/test/tools/trim.test.js +419 -84
- package/test/tools/zoom.test.js +504 -0
- package/core/entities/alignedDimension.js +0 -279
- package/core/entities/angularDimension.js +0 -194
- package/core/entities/baseDimension.js +0 -227
- package/core/entities/block.js +0 -247
- package/core/entities/diametricDimension.js +0 -133
- package/core/entities/dimension.js +0 -202
- package/core/entities/radialDimension.js +0 -126
- package/core/styles/dimStyle.js +0 -719
- package/core/styles/dimStyleManager.js +0 -47
- package/core/styles/layer.js +0 -133
- package/core/styles/layerManager.js +0 -40
- package/core/styles/ltype.js +0 -86
- package/core/styles/ltypeManager.js +0 -50
- package/core/styles/style.js +0 -158
- package/core/styles/styleManager.js +0 -43
- package/core/styles/styleManagerBase.js +0 -299
- package/test/entities/block.test.js +0 -22
- package/test/styles/dimstyle.test.js +0 -19
- package/test/styles/layerManager.test.js +0 -150
- package/test/styles/style.test.js +0 -33
- package/test/styles/stylemanagerbase.test.js +0 -219
package/core/tools/rotate.js
CHANGED
|
@@ -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 {
|
|
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
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
|
61
|
-
|
|
62
|
-
DesignCore.Scene.
|
|
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 >=
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
92
|
-
const
|
|
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
|
|
125
|
+
const stateChanges = [];
|
|
101
126
|
|
|
102
|
-
for (let
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
+
}
|
package/core/tools/tool.js
CHANGED
|
@@ -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
|
-
|
|
15
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Preview the command during execution
|
|
20
|
+
*/
|
|
21
|
+
preview() {
|
|
22
|
+
// preview function to be overridden by implementation
|
|
16
23
|
};
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Perform the command
|
|
27
|
+
*/
|
|
28
|
+
action() {
|
|
29
|
+
// action function to be overridden by implementation
|
|
20
30
|
};
|
|
21
31
|
}
|
|
22
32
|
|
package/core/tools/trim.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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
|
-
|
|
60
|
+
|
|
61
|
+
DesignCore.Scene.inputManager.executeCommand();
|
|
62
|
+
} catch (err) {
|
|
35
63
|
Logging.instance.error(`${this.type} - ${err}`);
|
|
36
64
|
}
|
|
37
65
|
}
|
|
38
66
|
|
|
39
|
-
|
|
40
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Preview the command during execution
|
|
69
|
+
*/
|
|
70
|
+
preview() {
|
|
71
|
+
// No Preview
|
|
72
|
+
}
|
|
41
73
|
|
|
42
|
-
|
|
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 (
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
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
|
|