@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
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { DXFFile } from '../lib/dxf/dxfFile.js';
|
|
2
|
+
import { TableManagerBase } from './tableManagerBase.js';
|
|
3
|
+
import { UCS } from './ucs.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* UCSManager Class
|
|
7
|
+
* @extends TableManagerBase
|
|
8
|
+
*/
|
|
9
|
+
export class UCSManager extends TableManagerBase {
|
|
10
|
+
/** Create a UCSManager */
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
|
|
14
|
+
this.itemProperty = 'ucs';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Get the item class */
|
|
18
|
+
get itemClass() {
|
|
19
|
+
return UCS;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Add standard items */
|
|
23
|
+
addStandardItems() {
|
|
24
|
+
// No standard UCS items
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Write the table to file in the dxf format
|
|
29
|
+
* @param {DXFFile} file
|
|
30
|
+
*/
|
|
31
|
+
dxf(file) {
|
|
32
|
+
file.writeGroupCode('0', 'TABLE', DXFFile.Version.R2000);
|
|
33
|
+
file.writeGroupCode('2', 'UCS', DXFFile.Version.R2000);
|
|
34
|
+
file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
|
|
35
|
+
file.writeGroupCode('100', 'AcDbSymbolTable', DXFFile.Version.R2000);
|
|
36
|
+
file.writeGroupCode('70', this.itemCount(), DXFFile.Version.R2000);
|
|
37
|
+
|
|
38
|
+
for (let i = 0; i < this.itemCount(); i++) {
|
|
39
|
+
this.getItemByIndex(i).dxf(file);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
file.writeGroupCode('0', 'ENDTAB', DXFFile.Version.R2000);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { DXFFile } from '../lib/dxf/dxfFile.js';
|
|
2
|
+
import { Property } from '../properties/property.js';
|
|
3
|
+
|
|
4
|
+
/** View Class */
|
|
5
|
+
export class View {
|
|
6
|
+
/**
|
|
7
|
+
* Create a View
|
|
8
|
+
* @param {Object} data
|
|
9
|
+
*/
|
|
10
|
+
constructor(data) {
|
|
11
|
+
// DXF Groupcode 5 - Handle
|
|
12
|
+
this.handle = Property.loadValue([data?.handle, data?.[5]]);
|
|
13
|
+
// DXF Groupcode 2 - Name
|
|
14
|
+
this.name = Property.loadValue([data?.name, data?.[2]], '');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Write the item to file in the dxf format
|
|
19
|
+
* @param {DXFFile} file
|
|
20
|
+
*/
|
|
21
|
+
dxf(file) {
|
|
22
|
+
file.writeGroupCode('0', 'VIEW', DXFFile.Version.R2000);
|
|
23
|
+
file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
|
|
24
|
+
file.writeGroupCode('100', 'AcDbSymbolTableRecord', DXFFile.Version.R2000);
|
|
25
|
+
file.writeGroupCode('100', 'AcDbViewTableRecord', DXFFile.Version.R2000);
|
|
26
|
+
file.writeGroupCode('2', this.name, DXFFile.Version.R2000);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { DXFFile } from '../lib/dxf/dxfFile.js';
|
|
2
|
+
import { TableManagerBase } from './tableManagerBase.js';
|
|
3
|
+
import { View } from './view.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ViewManager Class
|
|
7
|
+
* @extends TableManagerBase
|
|
8
|
+
*/
|
|
9
|
+
export class ViewManager extends TableManagerBase {
|
|
10
|
+
/** Create a ViewManager */
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
|
|
14
|
+
this.itemProperty = 'view';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Get the item class */
|
|
18
|
+
get itemClass() {
|
|
19
|
+
return View;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Add standard items */
|
|
23
|
+
addStandardItems() {
|
|
24
|
+
// No standard view items
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Write the table to file in the dxf format
|
|
29
|
+
* @param {DXFFile} file
|
|
30
|
+
*/
|
|
31
|
+
dxf(file) {
|
|
32
|
+
file.writeGroupCode('0', 'TABLE', DXFFile.Version.R2000);
|
|
33
|
+
file.writeGroupCode('2', 'VIEW', DXFFile.Version.R2000);
|
|
34
|
+
file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
|
|
35
|
+
file.writeGroupCode('100', 'AcDbSymbolTable', DXFFile.Version.R2000);
|
|
36
|
+
file.writeGroupCode('70', this.itemCount(), DXFFile.Version.R2000);
|
|
37
|
+
|
|
38
|
+
for (let i = 0; i < this.itemCount(); i++) {
|
|
39
|
+
this.getItemByIndex(i).dxf(file);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
file.writeGroupCode('0', 'ENDTAB', DXFFile.Version.R2000);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { DXFFile } from '../lib/dxf/dxfFile.js';
|
|
2
|
+
import { Property } from '../properties/property.js';
|
|
3
|
+
|
|
4
|
+
/** VPort Class */
|
|
5
|
+
export class VPort {
|
|
6
|
+
/**
|
|
7
|
+
* Create a VPort
|
|
8
|
+
* @param {Object} data
|
|
9
|
+
*/
|
|
10
|
+
constructor(data) {
|
|
11
|
+
// DXF Groupcode 5 - Handle
|
|
12
|
+
this.handle = Property.loadValue([data?.handle, data?.[5]]);
|
|
13
|
+
// DXF Groupcode 2 - Name
|
|
14
|
+
this.name = Property.loadValue([data?.name, data?.[2]], '*ACTIVE');
|
|
15
|
+
// DXF Groupcode 12 - View center X
|
|
16
|
+
this.viewCenterX = Property.loadValue([data?.viewCenterX, data?.[12]], 0);
|
|
17
|
+
// DXF Groupcode 22 - View center Y
|
|
18
|
+
this.viewCenterY = Property.loadValue([data?.viewCenterY, data?.[22]], 0);
|
|
19
|
+
// DXF Groupcode 40 - VPort height
|
|
20
|
+
this.height = Property.loadValue([data?.height, data?.[40]], 0);
|
|
21
|
+
// DXF Groupcode 41 - VPort width/height ratio
|
|
22
|
+
this.ratio = Property.loadValue([data?.ratio, data?.[41]], 0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Write the item to file in the dxf format
|
|
27
|
+
* @param {DXFFile} file
|
|
28
|
+
*/
|
|
29
|
+
dxf(file) {
|
|
30
|
+
file.writeGroupCode('0', 'VPORT');
|
|
31
|
+
file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
|
|
32
|
+
file.writeGroupCode('100', 'AcDbSymbolTableRecord', DXFFile.Version.R2000);
|
|
33
|
+
file.writeGroupCode('100', 'AcDbViewportTableRecord', DXFFile.Version.R2000);
|
|
34
|
+
file.writeGroupCode('2', this.name);
|
|
35
|
+
file.writeGroupCode('70', '0'); // vport flags
|
|
36
|
+
file.writeGroupCode('10', '0.0'); // lower left corner x pos
|
|
37
|
+
file.writeGroupCode('20', '0.0'); // lower left corner y pos
|
|
38
|
+
file.writeGroupCode('11', '1.0'); // upper right corner x pos
|
|
39
|
+
file.writeGroupCode('21', '1.0'); // upper right corner y pos
|
|
40
|
+
file.writeGroupCode('12', this.viewCenterX); // view centre x pos
|
|
41
|
+
file.writeGroupCode('22', this.viewCenterY); // view centre y pos
|
|
42
|
+
file.writeGroupCode('13', '0.0'); // snap base point x
|
|
43
|
+
file.writeGroupCode('23', '0.0'); // snap base point y
|
|
44
|
+
file.writeGroupCode('14', '10.0'); // snap spacing x
|
|
45
|
+
file.writeGroupCode('24', '10.0'); // snap spacing y
|
|
46
|
+
file.writeGroupCode('15', '10.0'); // grid spacing x
|
|
47
|
+
file.writeGroupCode('25', '10.0'); // grid spacing y
|
|
48
|
+
file.writeGroupCode('16', '0.0'); // view direction (x) from target point
|
|
49
|
+
file.writeGroupCode('26', '0.0'); // view direction (y) from target point
|
|
50
|
+
file.writeGroupCode('36', '1.0'); // view direction (z) from target point
|
|
51
|
+
file.writeGroupCode('17', '0.0'); // view target point x
|
|
52
|
+
file.writeGroupCode('27', '0.0'); // view target point y
|
|
53
|
+
file.writeGroupCode('37', '0.0'); // view target point z
|
|
54
|
+
file.writeGroupCode('40', this.height); // VPort Height
|
|
55
|
+
file.writeGroupCode('41', this.ratio); // Vport height/width ratio
|
|
56
|
+
file.writeGroupCode('42', '50.0'); // Lens Length
|
|
57
|
+
file.writeGroupCode('43', '0.0'); // Front Clipping Plane
|
|
58
|
+
file.writeGroupCode('44', '0.0'); // Back Clipping Plane
|
|
59
|
+
file.writeGroupCode('50', '0.0'); // Snap Rotation Angle
|
|
60
|
+
file.writeGroupCode('51', '0.0'); // View Twist Angle
|
|
61
|
+
file.writeGroupCode('71', '0.0'); // Viewmode (System variable)
|
|
62
|
+
file.writeGroupCode('72', '1000'); // Circle sides
|
|
63
|
+
file.writeGroupCode('73', '1'); // fast zoom setting
|
|
64
|
+
file.writeGroupCode('74', '3'); // UCSICON Setting
|
|
65
|
+
file.writeGroupCode('75', '0'); // snap on/off
|
|
66
|
+
file.writeGroupCode('76', '1'); // grid on/off
|
|
67
|
+
file.writeGroupCode('77', '0'); // snap style
|
|
68
|
+
file.writeGroupCode('78', '0'); // snap isopair
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { DXFFile } from '../lib/dxf/dxfFile.js';
|
|
2
|
+
import { TableManagerBase } from './tableManagerBase.js';
|
|
3
|
+
import { VPort } from './vport.js';
|
|
4
|
+
|
|
5
|
+
import { DesignCore } from '../designCore.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* VPortManager Class
|
|
9
|
+
* @extends TableManagerBase
|
|
10
|
+
*/
|
|
11
|
+
export class VPortManager extends TableManagerBase {
|
|
12
|
+
/** Create a VPortManager */
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
|
|
16
|
+
this.itemProperty = 'vport';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Get the item class */
|
|
20
|
+
get itemClass() {
|
|
21
|
+
return VPort;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Add standard items */
|
|
25
|
+
addStandardItems() {
|
|
26
|
+
this.addItem({ name: '*ACTIVE' });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Update the active vport from the scene
|
|
31
|
+
*/
|
|
32
|
+
updateFromScene() {
|
|
33
|
+
const extents = DesignCore.Scene.boundingBox();
|
|
34
|
+
const vport = this.getItemByName('*ACTIVE');
|
|
35
|
+
|
|
36
|
+
if (extents && vport) {
|
|
37
|
+
const width = extents.xLength;
|
|
38
|
+
const height = extents.yLength;
|
|
39
|
+
vport.viewCenterX = extents.xMin + width / 2;
|
|
40
|
+
vport.viewCenterY = extents.yMin + height / 2;
|
|
41
|
+
vport.height = height;
|
|
42
|
+
vport.ratio = height === 0 ? 1 : width / height;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Write the table to file in the dxf format
|
|
48
|
+
* @param {DXFFile} file
|
|
49
|
+
*/
|
|
50
|
+
dxf(file) {
|
|
51
|
+
this.updateFromScene();
|
|
52
|
+
|
|
53
|
+
file.writeGroupCode('0', 'TABLE');
|
|
54
|
+
file.writeGroupCode('2', 'VPORT');
|
|
55
|
+
file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
|
|
56
|
+
file.writeGroupCode('100', 'AcDbSymbolTable', DXFFile.Version.R2000);
|
|
57
|
+
file.writeGroupCode('70', this.itemCount());
|
|
58
|
+
|
|
59
|
+
for (let i = 0; i < this.itemCount(); i++) {
|
|
60
|
+
this.getItemByIndex(i).dxf(file);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
file.writeGroupCode('0', 'ENDTAB');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { Strings } from '../lib/strings.js';
|
|
2
|
+
import { ChamferFilletBase } from './chamferFilletBase.js';
|
|
3
|
+
import { Intersection } from '../lib/intersect.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 { Line } from '../entities/line.js';
|
|
8
|
+
import { BasePolyline } from '../entities/basePolyline.js';
|
|
9
|
+
import { AddState, RemoveState, UpdateState } from '../lib/stateManager.js';
|
|
10
|
+
|
|
11
|
+
import { DesignCore } from '../designCore.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Chamfer Command Class
|
|
15
|
+
* @extends ChamferFilletBase
|
|
16
|
+
*/
|
|
17
|
+
export class Chamfer extends ChamferFilletBase {
|
|
18
|
+
/**
|
|
19
|
+
* Register the command
|
|
20
|
+
* @return {Object}
|
|
21
|
+
* command = name of the command
|
|
22
|
+
* shortcut = shortcut for the command
|
|
23
|
+
* type = type to group command in toolbars (omitted if not shown)
|
|
24
|
+
*/
|
|
25
|
+
static register() {
|
|
26
|
+
const command = { command: 'Chamfer', shortcut: 'CHA' };
|
|
27
|
+
return command;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Execute method
|
|
32
|
+
* executes the workflow, requesting input required to perform the command
|
|
33
|
+
*/
|
|
34
|
+
async execute() {
|
|
35
|
+
try {
|
|
36
|
+
this.#notifySettings();
|
|
37
|
+
|
|
38
|
+
while (true) {
|
|
39
|
+
const op1 = new PromptOptions(Strings.Input.SELECT, [Input.Type.SINGLESELECTION], ['Distance', 'Angle', 'Trim', 'Method']);
|
|
40
|
+
const input1 = await DesignCore.Scene.inputManager.requestInput(op1);
|
|
41
|
+
if (input1 === undefined) return;
|
|
42
|
+
|
|
43
|
+
if (Input.getType(input1) === Input.Type.STRING) {
|
|
44
|
+
if (input1 === 'Distance') {
|
|
45
|
+
const dop1 = new PromptOptions('Specify first chamfer distance', [Input.Type.NUMBER]);
|
|
46
|
+
const d1 = await DesignCore.Scene.inputManager.requestInput(dop1);
|
|
47
|
+
if (d1 === undefined) return;
|
|
48
|
+
if (d1 < 0) {
|
|
49
|
+
DesignCore.Core.notify(`${this.type} - ${Strings.Error.INVALIDNUMBER}`);
|
|
50
|
+
} else {
|
|
51
|
+
DesignCore.Scene.headers.chamferDistanceA = d1;
|
|
52
|
+
const dop2 = new PromptOptions('Specify second chamfer distance', [Input.Type.NUMBER]);
|
|
53
|
+
const d2 = await DesignCore.Scene.inputManager.requestInput(dop2);
|
|
54
|
+
if (d2 === undefined) return;
|
|
55
|
+
if (d2 < 0) {
|
|
56
|
+
DesignCore.Core.notify(`${this.type} - ${Strings.Error.INVALIDNUMBER}`);
|
|
57
|
+
} else {
|
|
58
|
+
DesignCore.Scene.headers.chamferDistanceB = d2;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
this.#notifySettings();
|
|
62
|
+
} else if (input1 === 'Angle') {
|
|
63
|
+
const lop = new PromptOptions('Specify chamfer length on first line', [Input.Type.NUMBER]);
|
|
64
|
+
const len = await DesignCore.Scene.inputManager.requestInput(lop);
|
|
65
|
+
if (len === undefined) return;
|
|
66
|
+
if (len < 0) {
|
|
67
|
+
DesignCore.Core.notify(`${this.type} - ${Strings.Error.INVALIDNUMBER}`);
|
|
68
|
+
} else {
|
|
69
|
+
DesignCore.Scene.headers.chamferLength = len;
|
|
70
|
+
const aop = new PromptOptions(Strings.Input.ANGLE, [Input.Type.NUMBER]);
|
|
71
|
+
const ang = await DesignCore.Scene.inputManager.requestInput(aop);
|
|
72
|
+
if (ang === undefined) return;
|
|
73
|
+
if (ang <= 0 || ang >= 180) {
|
|
74
|
+
DesignCore.Core.notify(`${this.type} - ${Strings.Error.INVALIDNUMBER}`);
|
|
75
|
+
} else {
|
|
76
|
+
DesignCore.Scene.headers.chamferAngle = ang;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
this.#notifySettings();
|
|
80
|
+
} else if (input1 === 'Trim') {
|
|
81
|
+
const top = new PromptOptions(Strings.Input.OPTION, [], ['Trim', 'No trim']);
|
|
82
|
+
const trimInput = await DesignCore.Scene.inputManager.requestInput(top);
|
|
83
|
+
if (trimInput === undefined) return;
|
|
84
|
+
DesignCore.Scene.headers.trimMode = (trimInput === 'Trim');
|
|
85
|
+
this.#notifySettings();
|
|
86
|
+
} else if (input1 === 'Method') {
|
|
87
|
+
const mop = new PromptOptions(Strings.Input.OPTION, [], ['Distance', 'Angle']);
|
|
88
|
+
const methodInput = await DesignCore.Scene.inputManager.requestInput(mop);
|
|
89
|
+
if (methodInput === undefined) return;
|
|
90
|
+
DesignCore.Scene.headers.chamferMode = (methodInput === 'Angle');
|
|
91
|
+
this.#notifySettings();
|
|
92
|
+
}
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// input1 is a selection — validate and store first entity
|
|
97
|
+
const firstEntity = DesignCore.Scene.entities.get(input1.selectedItemIndex);
|
|
98
|
+
DesignCore.Scene.selectionManager.removeLastSelection();
|
|
99
|
+
if (!(firstEntity instanceof Line) && !(firstEntity instanceof BasePolyline)) {
|
|
100
|
+
DesignCore.Core.notify(`${firstEntity.type} - ${Strings.Message.NOCHAMFER}`);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (!this.firstPick.setPick(firstEntity, input1.selectedPoint, `${Strings.Strings.ARC} - ${Strings.Message.NOCHAMFER}`)) continue;
|
|
104
|
+
|
|
105
|
+
// Prompt for second object
|
|
106
|
+
const op2 = new PromptOptions(Strings.Input.SELECT, [Input.Type.SINGLESELECTION]);
|
|
107
|
+
while (true) {
|
|
108
|
+
const input2 = await DesignCore.Scene.inputManager.requestInput(op2);
|
|
109
|
+
if (input2 === undefined) return;
|
|
110
|
+
|
|
111
|
+
const candidate = DesignCore.Scene.entities.get(input2.selectedItemIndex);
|
|
112
|
+
DesignCore.Scene.selectionManager.removeLastSelection();
|
|
113
|
+
if (!(candidate instanceof Line) && !(candidate instanceof BasePolyline)) {
|
|
114
|
+
DesignCore.Core.notify(`${this.type} - ${candidate.type} ${Strings.Message.NOCHAMFER}`);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (!this.secondPick.setPick(candidate, input2.selectedPoint, `${Strings.Strings.ARC} - ${Strings.Message.NOCHAMFER}`)) continue;
|
|
118
|
+
// If both selections are the same polyline, segments must be consecutive
|
|
119
|
+
// or they must be the open-end segments of an open polyline.
|
|
120
|
+
if (candidate === firstEntity && firstEntity instanceof BasePolyline) {
|
|
121
|
+
const isConsecutive = firstEntity.areConsecutiveSegments(this.firstPick.segmentIndex, this.secondPick.segmentIndex);
|
|
122
|
+
const lastIdx = firstEntity.points.length - 1;
|
|
123
|
+
const isOpenEnds = !firstEntity.flags.hasFlag(1) &&
|
|
124
|
+
((this.firstPick.segmentIndex === 1 && this.secondPick.segmentIndex === lastIdx) ||
|
|
125
|
+
(this.secondPick.segmentIndex === 1 && this.firstPick.segmentIndex === lastIdx));
|
|
126
|
+
if (!isConsecutive && !isOpenEnds) {
|
|
127
|
+
DesignCore.Core.notify(`${this.type} - ${Strings.Message.NONCONSECUTIVESEGMENTS}`);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Apply chamfer then reset
|
|
135
|
+
DesignCore.Scene.inputManager.executeCommand();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
} catch (err) {
|
|
139
|
+
Logging.instance.error(`${this.type} - ${err}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Preview the command during execution
|
|
145
|
+
*/
|
|
146
|
+
preview() {
|
|
147
|
+
// No preview
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Perform the chamfer
|
|
152
|
+
*/
|
|
153
|
+
action() {
|
|
154
|
+
if (!this.firstPick.entity || !this.secondPick.entity) return;
|
|
155
|
+
if (!this.resolveCornerGeometry(Strings.Message.NOCHAMFER)) return;
|
|
156
|
+
|
|
157
|
+
const trimMode = DesignCore.Scene.headers.trimMode;
|
|
158
|
+
const chamferMode = DesignCore.Scene.headers.chamferMode;
|
|
159
|
+
const distA = DesignCore.Scene.headers.chamferDistanceA;
|
|
160
|
+
|
|
161
|
+
// distA = distB = 0: trim/extend both lines to the sharp intersection with no chamfer line
|
|
162
|
+
if (!chamferMode && distA === 0 && DesignCore.Scene.headers.chamferDistanceB === 0) {
|
|
163
|
+
if (trimMode) {
|
|
164
|
+
const stateChanges = this.applySharpTrim();
|
|
165
|
+
DesignCore.Scene.commit(stateChanges);
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Compute the two chamfer endpoints on each line
|
|
171
|
+
const firstUnit = this.firstPick.clickUnit(this.intersectionPoint);
|
|
172
|
+
const secondUnit = this.secondPick.clickUnit(this.intersectionPoint);
|
|
173
|
+
let firstChamferPoint;
|
|
174
|
+
let secondChamferPoint;
|
|
175
|
+
|
|
176
|
+
if (!chamferMode) {
|
|
177
|
+
// Distance method: measure distA along line1 and distB along line2 from intersection
|
|
178
|
+
const distB = DesignCore.Scene.headers.chamferDistanceB;
|
|
179
|
+
firstChamferPoint = this.intersectionPoint.add(firstUnit.scale(distA));
|
|
180
|
+
secondChamferPoint = this.intersectionPoint.add(secondUnit.scale(distB));
|
|
181
|
+
} else {
|
|
182
|
+
// Angle method: measure chamferLength along line1, then project using chamferAngle to find
|
|
183
|
+
// where the chamfer line meets line2.
|
|
184
|
+
// chamferAngle is stored in degrees (as entered by the user).
|
|
185
|
+
const chamferLength = DesignCore.Scene.headers.chamferLength;
|
|
186
|
+
const alpha = DesignCore.Scene.headers.chamferAngle * (Math.PI / 180);
|
|
187
|
+
|
|
188
|
+
if (alpha <= 0 || alpha >= Math.PI) {
|
|
189
|
+
DesignCore.Core.notify(`${this.type} - ${Strings.Error.ERROR}:${Strings.Error.INVALIDNUMBER}`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
firstChamferPoint = this.intersectionPoint.add(firstUnit.scale(chamferLength));
|
|
194
|
+
|
|
195
|
+
// Rotate firstUnit by ±(π - alpha) to get the chamfer direction from
|
|
196
|
+
// firstChamferPoint. Choose the rotation that points toward line2 (positive
|
|
197
|
+
// dot product with secondUnit).
|
|
198
|
+
const rotAngle = Math.PI - alpha;
|
|
199
|
+
const origin = new Point(0, 0);
|
|
200
|
+
const candidate1 = firstUnit.rotate(origin, rotAngle);
|
|
201
|
+
const chamferDir = candidate1.dot(secondUnit) >= 0 ? candidate1 : firstUnit.rotate(origin, -rotAngle);
|
|
202
|
+
|
|
203
|
+
// Intersect chamfer ray from firstChamferPoint with the infinite line2
|
|
204
|
+
const chamferResult = Intersection.intersectSegmentSegment(
|
|
205
|
+
firstChamferPoint, firstChamferPoint.add(chamferDir),
|
|
206
|
+
this.secondPick.lineStart, this.secondPick.lineEnd,
|
|
207
|
+
true, true,
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
const chamferStatus = chamferResult.status;
|
|
211
|
+
if (chamferStatus === Intersection.Status.PARALLEL ||
|
|
212
|
+
chamferStatus === Intersection.Status.OVERLAPPING ||
|
|
213
|
+
chamferStatus === Intersection.Status.COINCIDENT) {
|
|
214
|
+
DesignCore.Core.notify(`${this.type} - ${Strings.Error.ERROR}:${Strings.Error.PARALLELLINES}`);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
secondChamferPoint = chamferResult.points[0] || null;
|
|
219
|
+
if (!secondChamferPoint) {
|
|
220
|
+
// Chamfer direction is parallel to line2 — no intersection
|
|
221
|
+
DesignCore.Core.notify(`${this.type} - ${Strings.Error.ERROR}:${Strings.Error.PARALLELLINES}`);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Verify both chamfer endpoints lie on the correct side of the intersection and
|
|
227
|
+
// not beyond the kept endpoints. Uses the same dot-product approach as Fillet so
|
|
228
|
+
// that segments are treated as infinite lines (extensions are allowed).
|
|
229
|
+
if (trimMode) {
|
|
230
|
+
const firstKeptDir = this.firstPick.lineKeptEnd(this.intersectionPoint).subtract(this.intersectionPoint);
|
|
231
|
+
const secondKeptDir = this.secondPick.lineKeptEnd(this.intersectionPoint).subtract(this.intersectionPoint);
|
|
232
|
+
const firstChamferDot = firstChamferPoint.subtract(this.intersectionPoint).dot(firstKeptDir);
|
|
233
|
+
const secondChamferDot = secondChamferPoint.subtract(this.intersectionPoint).dot(secondKeptDir);
|
|
234
|
+
if (firstChamferDot < 0 || firstChamferDot > firstKeptDir.dot(firstKeptDir) ||
|
|
235
|
+
secondChamferDot < 0 || secondChamferDot > secondKeptDir.dot(secondKeptDir)) {
|
|
236
|
+
DesignCore.Core.notify(`${this.type} - ${Strings.Error.MAXVALUE}`);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const chamferLine = DesignCore.CommandManager.createNew('Line', {
|
|
242
|
+
points: [firstChamferPoint, secondChamferPoint],
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const firstIsPolyline = this.firstPick.entity instanceof BasePolyline;
|
|
246
|
+
const secondIsPolyline = this.secondPick.entity instanceof BasePolyline;
|
|
247
|
+
|
|
248
|
+
// The standalone chamfer Line entity is added when no polyline trimming is involved.
|
|
249
|
+
// For polyline trim cases the chamfer segment is encoded as a straight polyline segment,
|
|
250
|
+
// except for the open-ends case where the chamfer line fills the gap between the two
|
|
251
|
+
// open ends and is added separately there.
|
|
252
|
+
const stateChanges = (!trimMode || (!firstIsPolyline && !secondIsPolyline)) ?
|
|
253
|
+
[new AddState(chamferLine)] :
|
|
254
|
+
[];
|
|
255
|
+
|
|
256
|
+
if (trimMode) {
|
|
257
|
+
if (!firstIsPolyline && !secondIsPolyline) {
|
|
258
|
+
// Line + Line: trim both lines
|
|
259
|
+
stateChanges.push(new UpdateState(this.firstPick.entity, { points: [this.firstPick.lineKeptEnd(this.intersectionPoint), firstChamferPoint] }));
|
|
260
|
+
stateChanges.push(new UpdateState(this.secondPick.entity, { points: [this.secondPick.lineKeptEnd(this.intersectionPoint), secondChamferPoint] }));
|
|
261
|
+
} else if (firstIsPolyline && secondIsPolyline && this.firstPick.entity === this.secondPick.entity) {
|
|
262
|
+
const closeSegIdx = this.firstPick.entity.points.length;
|
|
263
|
+
const lastIdx = closeSegIdx - 1;
|
|
264
|
+
const segDiff = Math.abs(this.firstPick.segmentIndex - this.secondPick.segmentIndex);
|
|
265
|
+
const isOpenEnds = !this.firstPick.entity.flags.hasFlag(1) && segDiff !== 1 && (
|
|
266
|
+
(this.firstPick.segmentIndex === 1 && this.secondPick.segmentIndex === lastIdx) ||
|
|
267
|
+
(this.firstPick.segmentIndex === lastIdx && this.secondPick.segmentIndex === 1)
|
|
268
|
+
);
|
|
269
|
+
const newPoints = this.firstPick.entity.points.map((p) => p.clone());
|
|
270
|
+
if (isOpenEnds) {
|
|
271
|
+
// Open ends: trim both endpoints to their chamfer points; chamfer line fills the gap.
|
|
272
|
+
stateChanges.push(new AddState(chamferLine));
|
|
273
|
+
if (this.firstPick.segmentIndex === 1) {
|
|
274
|
+
newPoints[0] = firstChamferPoint.clone();
|
|
275
|
+
newPoints[lastIdx] = secondChamferPoint.clone();
|
|
276
|
+
} else {
|
|
277
|
+
newPoints[0] = secondChamferPoint.clone();
|
|
278
|
+
newPoints[lastIdx] = firstChamferPoint.clone();
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
// Consecutive segments: replace the shared corner vertex with the two chamfer points
|
|
282
|
+
// as a straight polyline segment — no separate chamfer Line entity needed.
|
|
283
|
+
const seg1 = this.firstPick.segmentIndex;
|
|
284
|
+
const seg2 = this.secondPick.segmentIndex;
|
|
285
|
+
const isClosingWrap = (seg1 === closeSegIdx && seg2 === 1) || (seg2 === closeSegIdx && seg1 === 1);
|
|
286
|
+
const isFirstLower = seg1 < seg2;
|
|
287
|
+
const cornerIdx = isClosingWrap ? 0 : Math.min(seg1, seg2);
|
|
288
|
+
const lowerChamfer = (isClosingWrap ? seg1 === closeSegIdx : !isFirstLower) ? secondChamferPoint : firstChamferPoint;
|
|
289
|
+
const upperChamfer = (isClosingWrap ? seg1 === closeSegIdx : !isFirstLower) ? firstChamferPoint : secondChamferPoint;
|
|
290
|
+
newPoints.splice(cornerIdx, 1, lowerChamfer.clone(), upperChamfer.clone());
|
|
291
|
+
}
|
|
292
|
+
stateChanges.push(new UpdateState(this.firstPick.entity, { points: newPoints }));
|
|
293
|
+
} else {
|
|
294
|
+
// Line + Polyline or Polyline + Line: consume the line into the polyline.
|
|
295
|
+
const [poly, line] = firstIsPolyline ? [this.firstPick, this.secondPick] : [this.secondPick, this.firstPick];
|
|
296
|
+
const polyChamferPoint = poly === this.firstPick ? firstChamferPoint : secondChamferPoint;
|
|
297
|
+
const lineChamferPoint = line === this.firstPick ? firstChamferPoint : secondChamferPoint;
|
|
298
|
+
const polySegIdx = poly.segmentIndex;
|
|
299
|
+
const keepStart = poly.keepStart(this.intersectionPoint);
|
|
300
|
+
let newPoints;
|
|
301
|
+
if (keepStart) {
|
|
302
|
+
// Keep start portion: points[0..polySegIdx-1], then chamfer, then line end
|
|
303
|
+
newPoints = [
|
|
304
|
+
...poly.entity.points.slice(0, polySegIdx).map((p) => p.clone()),
|
|
305
|
+
polyChamferPoint.clone(),
|
|
306
|
+
lineChamferPoint.clone(),
|
|
307
|
+
line.lineKeptEnd(this.intersectionPoint).clone(),
|
|
308
|
+
];
|
|
309
|
+
} else {
|
|
310
|
+
// Keep end portion: line end, then chamfer, then points[polySegIdx..end]
|
|
311
|
+
newPoints = [
|
|
312
|
+
line.lineKeptEnd(this.intersectionPoint).clone(),
|
|
313
|
+
lineChamferPoint.clone(),
|
|
314
|
+
polyChamferPoint.clone(),
|
|
315
|
+
...poly.entity.points.slice(polySegIdx).map((p) => p.clone()),
|
|
316
|
+
];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
stateChanges.push(new RemoveState(line.entity));
|
|
320
|
+
stateChanges.push(new UpdateState(poly.entity, { points: newPoints }));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
DesignCore.Scene.commit(stateChanges);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Display the current chamfer settings to the command line
|
|
329
|
+
*/
|
|
330
|
+
#notifySettings() {
|
|
331
|
+
const trimMode = DesignCore.Scene.headers.trimMode;
|
|
332
|
+
const chamferMode = DesignCore.Scene.headers.chamferMode;
|
|
333
|
+
if (chamferMode) {
|
|
334
|
+
const length = DesignCore.Scene.headers.chamferLength;
|
|
335
|
+
const angle = DesignCore.Scene.headers.chamferAngle;
|
|
336
|
+
DesignCore.Core.notify(`Current settings: Mode = ${trimMode ? 'TRIM' : 'NOTRIM'}, Method = ANGLE, Length = ${length}, Angle = ${angle}`);
|
|
337
|
+
} else {
|
|
338
|
+
const distA = DesignCore.Scene.headers.chamferDistanceA;
|
|
339
|
+
const distB = DesignCore.Scene.headers.chamferDistanceB;
|
|
340
|
+
DesignCore.Core.notify(`Current settings: Mode = ${trimMode ? 'TRIM' : 'NOTRIM'}, Method = DIST, Dist1 = ${distA}, Dist2 = ${distB}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|