@design-core/core 0.0.7 → 51.1.0
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/.github/workflows/DesignCoreQA.yml +3 -0
- package/core/designCore.js +1 -1
- package/core/dimensions/alignedDimension.js +7 -7
- package/core/dimensions/angularDimension.js +32 -32
- package/core/dimensions/{baseCircularDimension.js → circularDimensionBase.js} +19 -19
- package/core/dimensions/diametricDimension.js +10 -10
- package/core/dimensions/dimension.js +42 -42
- package/core/dimensions/{baseDimension.js → dimensionBase.js} +17 -17
- package/core/dimensions/{baseLinearDimension.js → linearDimensionBase.js} +9 -9
- package/core/dimensions/radialDimension.js +8 -8
- package/core/dimensions/rotatedDimension.js +8 -8
- package/core/entities/arc.js +22 -22
- package/core/entities/arctext.js +13 -13
- package/core/entities/circle.js +7 -7
- package/core/entities/hatch.js +210 -40
- package/core/entities/insert.js +11 -6
- package/core/entities/point.js +19 -19
- package/core/entities/polyline.js +3 -3
- package/core/entities/{basePolyline.js → polylineBase.js} +18 -18
- package/core/entities/text.js +4 -4
- package/core/lib/boundingBox.js +11 -11
- package/core/lib/canvas.js +13 -6
- package/core/lib/clipboard.js +2 -2
- package/core/lib/dxf/dxf.js +11 -11
- package/core/lib/dxf/dxfIterator.js +2 -2
- package/core/lib/entityManager.js +19 -19
- package/core/lib/inputManager.js +1 -1
- package/core/lib/matrix.js +1 -1
- package/core/lib/patterns.js +1 -1
- package/core/lib/polylineUtils.js +9 -9
- package/core/lib/renderers/cairoRenderer.js +5 -5
- package/core/lib/renderers/canvasRenderer.js +4 -4
- package/core/lib/renderers/pdfRenderer.js +7 -7
- package/core/lib/renderers/rendererBase.js +1 -1
- package/core/lib/scene.js +1 -1
- package/core/lib/selectionManager.js +18 -18
- package/core/lib/utils.js +5 -5
- package/core/properties/entityProperties.js +2 -1
- package/core/properties/flags.js +12 -0
- package/core/properties/property.js +8 -3
- package/core/properties/propertyManager.js +52 -37
- package/core/tables/block.js +50 -46
- package/core/tables/dimStyle.js +5 -5
- package/core/tables/ltypeManager.js +1 -1
- package/core/tables/vport.js +2 -2
- package/core/tools/chamfer.js +6 -6
- package/core/tools/chamferFilletBase.js +4 -4
- package/core/tools/copy.js +8 -8
- package/core/tools/copybase.js +3 -3
- package/core/tools/copyclip.js +3 -3
- package/core/tools/cornerEntity.js +2 -2
- package/core/tools/cutclip.js +3 -3
- package/core/tools/explode.js +6 -6
- package/core/tools/extend.js +13 -13
- package/core/tools/fillet.js +6 -6
- package/core/tools/matchProp.js +1 -1
- package/core/tools/mirror.js +11 -11
- package/core/tools/move.js +5 -5
- package/core/tools/offset.js +29 -29
- package/core/tools/purge.js +10 -10
- package/core/tools/rotate.js +16 -16
- package/core/tools/scale.js +6 -6
- package/core/tools/trim.js +15 -15
- package/cspell.json +323 -0
- package/package.json +1 -1
- package/test/dimensions/alignedDimension.test.js +3 -3
- package/test/dimensions/angularDimension.test.js +7 -7
- package/test/dimensions/diametricDimension.test.js +9 -9
- package/test/dimensions/dimension.test.js +12 -12
- package/test/dimensions/{baseDimension.test.js → dimensionBase.test.js} +12 -12
- package/test/dimensions/{baseLinearDimension.test.js → linearDimensionBase.test.js} +7 -7
- package/test/dimensions/radialDimension.test.js +9 -9
- package/test/dimensions/rotatedDimension.test.js +4 -4
- package/test/entities/arc.test.js +10 -10
- package/test/entities/arctext.test.js +6 -6
- package/test/entities/circle.test.js +18 -18
- package/test/entities/hatch.test.js +362 -39
- package/test/entities/insert.test.js +9 -9
- package/test/entities/point.test.js +3 -3
- package/test/entities/{basePolyline.test.js → polylineBase.test.js} +131 -62
- package/test/entities/text.test.js +19 -19
- package/test/integration/exportIntegration.test.js +3 -3
- package/test/integration/userInputIntegration.test.js +5 -5
- package/test/lib/boundingBox.test.js +3 -3
- package/test/lib/canvas.test.js +9 -9
- package/test/lib/clipboard.test.js +73 -0
- package/test/lib/inputManager.test.js +4 -4
- package/test/lib/scene.test.js +9 -9
- package/test/lib/selectionManager.test.js +3 -3
- package/test/lib/snapping.test.js +1 -1
- package/test/properties/flags.test.js +24 -0
- package/test/properties/propertyManager.test.js +93 -22
- package/test/renderers/pdfRenderer.test.js +2 -2
- package/test/tables/block.test.js +63 -14
- package/test/tables/layerManager.test.js +2 -2
- package/test/test-helpers/hatchGridRenderer.js +3 -3
- package/test/test-helpers/test-helpers.js +6 -6
- package/test/tools/chamfer.test.js +60 -60
- package/test/tools/chamferFilletBase.test.js +36 -36
- package/test/tools/copy.test.js +6 -6
- package/test/tools/copybase.test.js +2 -2
- package/test/tools/copyclip.test.js +2 -2
- package/test/tools/cornerEntity.test.js +8 -8
- package/test/tools/cutclip.test.js +2 -2
- package/test/tools/erase.test.js +6 -6
- package/test/tools/explode.test.js +2 -2
- package/test/tools/extend.test.js +84 -84
- package/test/tools/fillet.test.js +62 -62
- package/test/tools/matchProp.test.js +6 -6
- package/test/tools/mirror.test.js +26 -26
- package/test/tools/move.test.js +7 -7
- package/test/tools/offset.test.js +65 -65
- package/test/tools/purge.test.js +4 -4
- package/test/tools/rotate.test.js +10 -10
- package/test/tools/scale.test.js +28 -28
- package/test/tools/trim.test.js +109 -109
- package/test/tools/zoom.test.js +15 -17
|
@@ -29,9 +29,12 @@ export class Property {
|
|
|
29
29
|
return this._value;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
/** @param {any} val - new value; ignored when readOnly
|
|
32
|
+
/** @param {any} val - new value; ignored when readOnly is true.
|
|
33
|
+
* Callable readOnly is evaluated by the caller (entityProperties.set) with
|
|
34
|
+
* the entity in scope; treat it as writable here to avoid stale closure issues. */
|
|
33
35
|
set value(val) {
|
|
34
|
-
|
|
36
|
+
const isReadOnly = typeof this.readOnly === 'function' ? false : this.readOnly;
|
|
37
|
+
if (!isReadOnly) {
|
|
35
38
|
this._value = val;
|
|
36
39
|
}
|
|
37
40
|
}
|
|
@@ -78,11 +81,13 @@ export class Property {
|
|
|
78
81
|
SCALE: 'scale',
|
|
79
82
|
STRING: 'string',
|
|
80
83
|
STYLENAME: 'styleName',
|
|
81
|
-
// ──
|
|
84
|
+
// ── PolylineBase ──────────────────────────────────────────────────────────
|
|
82
85
|
CLOSED: 'closed',
|
|
83
86
|
// ── Hatch ─────────────────────────────────────────────────────────────────
|
|
84
87
|
CHILDENTITIES: 'childEntities',
|
|
85
88
|
PATTERNNAME: 'patternName',
|
|
89
|
+
HATCHSPACING: 'hatchSpacing',
|
|
90
|
+
HATCHDOUBLE: 'hatchDouble',
|
|
86
91
|
// ── Text ──────────────────────────────────────────────────────────────────
|
|
87
92
|
BACKWARDS: 'backwards',
|
|
88
93
|
HORIZONTALALIGNMENT: 'horizontalAlignment',
|
|
@@ -28,81 +28,81 @@ export class PropertyManager {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* Set
|
|
31
|
+
* Set entity properties
|
|
32
32
|
* @param {string} property
|
|
33
33
|
* @param {any} newPropertyValue
|
|
34
|
-
* @param {string}
|
|
34
|
+
* @param {string} entityType
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
setEntityProperties(property, newPropertyValue, entityType='All') {
|
|
37
37
|
const stateChanges = [];
|
|
38
38
|
for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
|
|
39
39
|
const index = DesignCore.Scene.selectionManager.selectionSet.selectionSet[i];
|
|
40
40
|
|
|
41
|
-
const
|
|
41
|
+
const entity = DesignCore.Scene.entities.get(index);
|
|
42
42
|
|
|
43
|
-
// check if the
|
|
44
|
-
if (
|
|
43
|
+
// check if the entity is of the selected type
|
|
44
|
+
if (entityType !== 'All' && entity.type !== entityType) {
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
// check if the
|
|
49
|
-
if (!
|
|
48
|
+
// check if the entity has the selected property
|
|
49
|
+
if (!entity.properties?.has(property)) {
|
|
50
50
|
continue;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
const currentValue =
|
|
53
|
+
const currentValue = entity.getProperty(property);
|
|
54
54
|
|
|
55
55
|
if (typeof (currentValue) !== typeof (newPropertyValue)) {
|
|
56
56
|
DesignCore.Core.notify(Strings.Error.INPUT);
|
|
57
57
|
} else {
|
|
58
|
-
// update the
|
|
58
|
+
// update the entity property
|
|
59
59
|
const update = {};
|
|
60
60
|
update[property] = newPropertyValue;
|
|
61
|
-
const stateChange = new UpdateState(
|
|
61
|
+
const stateChange = new UpdateState(entity, update);
|
|
62
62
|
stateChanges.push(stateChange);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
DesignCore.Scene.commit(stateChanges);
|
|
66
|
-
DesignCore.Scene.selectionManager.
|
|
66
|
+
DesignCore.Scene.selectionManager.reloadSelectedEntities();
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* Get the types of items selected
|
|
71
71
|
* @return {Array}
|
|
72
72
|
*/
|
|
73
|
-
|
|
74
|
-
// Loop through the items and get a list of
|
|
75
|
-
const
|
|
73
|
+
getEntityTypes() {
|
|
74
|
+
// Loop through the items and get a list of entity types.
|
|
75
|
+
const entityTypes = [];
|
|
76
76
|
|
|
77
77
|
if (DesignCore.Scene.selectionManager.selectionSet.selectionSet.length > 0) {
|
|
78
78
|
for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
|
|
79
|
-
const
|
|
80
|
-
const
|
|
79
|
+
const entity = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]);
|
|
80
|
+
const entityType = entity.type;
|
|
81
81
|
|
|
82
|
-
if (
|
|
83
|
-
|
|
82
|
+
if (entityTypes.indexOf(entityType, 0) === -1) {
|
|
83
|
+
entityTypes.push(entityType);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// if there is more that one type add an option for all
|
|
88
|
-
if (
|
|
89
|
-
|
|
88
|
+
if (entityTypes.length > 1) {
|
|
89
|
+
entityTypes.unshift('All');
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
return
|
|
93
|
+
return entityTypes;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
|
-
* Get a list of common
|
|
98
|
-
* @param {string}
|
|
97
|
+
* Get a list of common properties
|
|
98
|
+
* @param {string} entityType
|
|
99
99
|
* @return {Array}
|
|
100
100
|
*/
|
|
101
|
-
|
|
101
|
+
getEntityProperties(entityType) {
|
|
102
102
|
// Loop through the items and get a list of common properties.
|
|
103
103
|
|
|
104
|
-
// check for valid
|
|
105
|
-
if (
|
|
104
|
+
// check for valid entityType and selectionSet
|
|
105
|
+
if (entityType === undefined || entityType === null || DesignCore.Scene.selectionManager.selectionSet.selectionSet.length <= 0) {
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -114,8 +114,8 @@ export class PropertyManager {
|
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
// get a subset of the selectionSet
|
|
117
|
-
if (
|
|
118
|
-
subset = subset.filter((el) => el.type ===
|
|
117
|
+
if (entityType !== 'All') {
|
|
118
|
+
subset = subset.filter((el) => el.type === entityType);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
const propertiesList = [];
|
|
@@ -138,38 +138,53 @@ export class PropertyManager {
|
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
140
|
* Get the Property descriptor for a named property from a representative selected entity.
|
|
141
|
-
* @param {string}
|
|
141
|
+
* @param {string} entityType
|
|
142
142
|
* @param {string} property
|
|
143
143
|
* @return {Property|undefined}
|
|
144
144
|
*/
|
|
145
|
-
|
|
145
|
+
getEntityPropertyDefinition(entityType, property) {
|
|
146
146
|
const index = DesignCore.Scene.selectionManager.selectionSet.selectionSet.find((i) => {
|
|
147
|
-
const
|
|
148
|
-
return (
|
|
147
|
+
const entity = DesignCore.Scene.entities.get(i);
|
|
148
|
+
return (entityType === 'All' || entity.type === entityType) && entity.properties?.has(property);
|
|
149
149
|
});
|
|
150
150
|
if (index === undefined) return undefined;
|
|
151
151
|
return DesignCore.Scene.entities.get(index).properties.definition(property);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Get the representative entity for a named property from the selection set.
|
|
156
|
+
* Used alongside getEntityPropertyDefinition when readOnly callbacks need an entity.
|
|
157
|
+
* @param {string} entityType
|
|
158
|
+
* @param {string} property
|
|
159
|
+
* @return {Object|undefined}
|
|
160
|
+
*/
|
|
161
|
+
getEntityForProperty(entityType, property) {
|
|
162
|
+
const index = DesignCore.Scene.selectionManager.selectionSet.selectionSet.find((i) => {
|
|
163
|
+
const entity = DesignCore.Scene.entities.get(i);
|
|
164
|
+
return (entityType === 'All' || entity.type === entityType) && entity.properties?.has(property);
|
|
165
|
+
});
|
|
166
|
+
return index !== undefined ? DesignCore.Scene.entities.get(index) : undefined;
|
|
167
|
+
}
|
|
168
|
+
|
|
154
169
|
/**
|
|
155
170
|
* Get a list the property values
|
|
156
|
-
* @param {string}
|
|
171
|
+
* @param {string} entityType
|
|
157
172
|
* @param {string} property
|
|
158
173
|
* @return {Array}
|
|
159
174
|
*/
|
|
160
|
-
|
|
175
|
+
getEntityPropertyValue(entityType, property) {
|
|
161
176
|
// Loop through the items and get a list the property values
|
|
162
177
|
const propertiesValueList = [];
|
|
163
178
|
if (DesignCore.Scene.selectionManager.selectionSet.selectionSet.length > 0) {
|
|
164
179
|
for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
|
|
165
|
-
if (DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]).type ===
|
|
180
|
+
if (DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]).type === entityType || entityType === 'All') {
|
|
166
181
|
const entity = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]);
|
|
167
182
|
propertiesValueList.push(entity.getProperty(property));
|
|
168
183
|
}
|
|
169
184
|
}
|
|
170
185
|
}
|
|
171
186
|
|
|
172
|
-
// Check if every
|
|
187
|
+
// Check if every entity in the selection set has the same value for the property
|
|
173
188
|
if (propertiesValueList.every((prop) => {
|
|
174
189
|
return prop === propertiesValueList[0];
|
|
175
190
|
})) {
|
package/core/tables/block.js
CHANGED
|
@@ -8,9 +8,11 @@ import { Input, PromptOptions } from '../lib/inputManager.js';
|
|
|
8
8
|
import { Flags } from '../properties/flags.js';
|
|
9
9
|
import { Property } from '../properties/property.js';
|
|
10
10
|
import { AddState, RemoveState } from '../lib/stateManager.js';
|
|
11
|
+
import { Logging } from '../lib/logging.js';
|
|
12
|
+
import { Utils } from '../lib/utils.js';
|
|
11
13
|
|
|
12
14
|
import { DesignCore } from '../designCore.js';
|
|
13
|
-
|
|
15
|
+
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Block Entity Class
|
|
@@ -36,7 +38,7 @@ export class Block extends Entity {
|
|
|
36
38
|
writable: true,
|
|
37
39
|
});
|
|
38
40
|
|
|
39
|
-
Object.defineProperty(this, '
|
|
41
|
+
Object.defineProperty(this, 'entities', {
|
|
40
42
|
value: [],
|
|
41
43
|
writable: true,
|
|
42
44
|
});
|
|
@@ -47,8 +49,8 @@ export class Block extends Entity {
|
|
|
47
49
|
this.name = data.name || data[2];
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
if (data.hasOwnProperty('
|
|
51
|
-
this.
|
|
52
|
+
if (data.hasOwnProperty('entities')) {
|
|
53
|
+
this.entities = data.entities;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
if (data.hasOwnProperty('flags') || data.hasOwnProperty('70')) {
|
|
@@ -114,21 +116,21 @@ export class Block extends Entity {
|
|
|
114
116
|
// array to hold state changes
|
|
115
117
|
const stateChanges = [];
|
|
116
118
|
|
|
117
|
-
// move selected
|
|
119
|
+
// move selected entities from scene to block
|
|
118
120
|
selections.forEach((index) => {
|
|
119
|
-
const
|
|
120
|
-
// remove
|
|
121
|
-
const
|
|
122
|
-
// assign a fresh handle — the block
|
|
123
|
-
|
|
124
|
-
// adjust the
|
|
121
|
+
const entity = DesignCore.Scene.entities.get(index);
|
|
122
|
+
// remove entity from scene
|
|
123
|
+
const copyOfEntity = Utils.cloneObject(entity);
|
|
124
|
+
// assign a fresh handle — the block entity is a new entity distinct from the scene entity
|
|
125
|
+
copyOfEntity.setProperty('handle', DesignCore.HandleManager.next());
|
|
126
|
+
// adjust the entity's points to reflect the insert point
|
|
125
127
|
const delta = new Point(-insertPoint.x, -insertPoint.y);
|
|
126
|
-
if (
|
|
127
|
-
const points =
|
|
128
|
-
|
|
128
|
+
if (copyOfEntity.points?.length) {
|
|
129
|
+
const points = copyOfEntity.points.map((p) => new Point(p.x, p.y, p.bulge, p.sequence).add(delta));
|
|
130
|
+
copyOfEntity.setProperty('points', points);
|
|
129
131
|
}
|
|
130
|
-
block.
|
|
131
|
-
const stateChangeRemove = new RemoveState(
|
|
132
|
+
block.entities.push(copyOfEntity);
|
|
133
|
+
const stateChangeRemove = new RemoveState(entity);
|
|
132
134
|
stateChanges.push(stateChangeRemove);
|
|
133
135
|
});
|
|
134
136
|
|
|
@@ -175,8 +177,8 @@ export class Block extends Entity {
|
|
|
175
177
|
file.writeGroupCode('3', this.name); // Name again
|
|
176
178
|
file.writeGroupCode('1', '');
|
|
177
179
|
|
|
178
|
-
for (let i = 0; i < this.
|
|
179
|
-
this.
|
|
180
|
+
for (let i = 0; i < this.entities.length; i++) {
|
|
181
|
+
this.entities[i].dxf(file);
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
const endblk = new EndBlock({ handle: this.endblkHandle });
|
|
@@ -184,18 +186,18 @@ export class Block extends Entity {
|
|
|
184
186
|
}
|
|
185
187
|
|
|
186
188
|
/**
|
|
187
|
-
* Clear
|
|
189
|
+
* Clear entities from the block
|
|
188
190
|
*/
|
|
189
|
-
|
|
190
|
-
this.
|
|
191
|
+
clearEntities() {
|
|
192
|
+
this.entities = [];
|
|
191
193
|
}
|
|
192
194
|
|
|
193
195
|
/**
|
|
194
|
-
* Add an
|
|
195
|
-
* @param {Object}
|
|
196
|
+
* Add an entity to the block
|
|
197
|
+
* @param {Object} entity
|
|
196
198
|
*/
|
|
197
|
-
|
|
198
|
-
this.
|
|
199
|
+
addEntity(entity) {
|
|
200
|
+
this.entities.push(entity);
|
|
199
201
|
}
|
|
200
202
|
|
|
201
203
|
/**
|
|
@@ -207,15 +209,15 @@ export class Block extends Entity {
|
|
|
207
209
|
snaps(mousePoint, delta) {
|
|
208
210
|
const snaps = [];
|
|
209
211
|
|
|
210
|
-
if (!this.
|
|
212
|
+
if (!this.entities.length) {
|
|
211
213
|
// nothing to draw
|
|
212
214
|
return snaps;
|
|
213
215
|
}
|
|
214
216
|
|
|
215
|
-
for (let
|
|
216
|
-
// collect the child
|
|
217
|
-
const
|
|
218
|
-
snaps.push(...
|
|
217
|
+
for (let entity = 0; entity < this.entities.length; entity++) {
|
|
218
|
+
// collect the child entity snaps
|
|
219
|
+
const entitySnaps = this.entities[entity].snaps(mousePoint, delta);
|
|
220
|
+
snaps.push(...entitySnaps);
|
|
219
221
|
}
|
|
220
222
|
|
|
221
223
|
return snaps;
|
|
@@ -230,19 +232,19 @@ export class Block extends Entity {
|
|
|
230
232
|
let distance = Infinity;
|
|
231
233
|
let minPnt = P;
|
|
232
234
|
|
|
233
|
-
if (!this.
|
|
235
|
+
if (!this.entities.length) {
|
|
234
236
|
// nothing to draw
|
|
235
237
|
return [minPnt, distance];
|
|
236
238
|
}
|
|
237
239
|
|
|
238
|
-
for (let idx = 0; idx < this.
|
|
239
|
-
const
|
|
240
|
-
const
|
|
241
|
-
const
|
|
240
|
+
for (let idx = 0; idx < this.entities.length; idx++) {
|
|
241
|
+
const entityClosestPoint = this.entities[idx].closestPoint(P);
|
|
242
|
+
const entityPnt = entityClosestPoint[0];
|
|
243
|
+
const entityDist = entityClosestPoint[1];
|
|
242
244
|
|
|
243
|
-
if (
|
|
244
|
-
distance =
|
|
245
|
-
minPnt =
|
|
245
|
+
if (entityDist < distance) {
|
|
246
|
+
distance = entityDist;
|
|
247
|
+
minPnt = entityPnt;
|
|
246
248
|
}
|
|
247
249
|
}
|
|
248
250
|
|
|
@@ -254,18 +256,20 @@ export class Block extends Entity {
|
|
|
254
256
|
* @return {BoundingBox}
|
|
255
257
|
*/
|
|
256
258
|
boundingBox() {
|
|
259
|
+
if (!this.entities.length) return null;
|
|
260
|
+
|
|
257
261
|
let xmin = Infinity;
|
|
258
262
|
let xmax = -Infinity;
|
|
259
263
|
let ymin = Infinity;
|
|
260
264
|
let ymax = -Infinity;
|
|
261
265
|
|
|
262
|
-
for (let idx = 0; idx < this.
|
|
263
|
-
const
|
|
266
|
+
for (let idx = 0; idx < this.entities.length; idx++) {
|
|
267
|
+
const entityBoundingBox = this.entities[idx].boundingBox();
|
|
264
268
|
|
|
265
|
-
xmin = Math.min(xmin,
|
|
266
|
-
xmax = Math.max(xmax,
|
|
267
|
-
ymin = Math.min(ymin,
|
|
268
|
-
ymax = Math.max(ymax,
|
|
269
|
+
xmin = Math.min(xmin, entityBoundingBox.xMin);
|
|
270
|
+
xmax = Math.max(xmax, entityBoundingBox.xMax);
|
|
271
|
+
ymin = Math.min(ymin, entityBoundingBox.yMin);
|
|
272
|
+
ymax = Math.max(ymax, entityBoundingBox.yMax);
|
|
269
273
|
}
|
|
270
274
|
|
|
271
275
|
const topLeft = new Point(xmin, ymax);
|
|
@@ -280,8 +284,8 @@ export class Block extends Entity {
|
|
|
280
284
|
* @return {boolean} true if touched
|
|
281
285
|
*/
|
|
282
286
|
touched(selection) {
|
|
283
|
-
for (let idx = 0; idx < this.
|
|
284
|
-
const touched = this.
|
|
287
|
+
for (let idx = 0; idx < this.entities.length; idx++) {
|
|
288
|
+
const touched = this.entities[idx].touched(selection);
|
|
285
289
|
if (touched) {
|
|
286
290
|
return true;
|
|
287
291
|
}
|
package/core/tables/dimStyle.js
CHANGED
|
@@ -321,11 +321,11 @@ export class DimStyle {
|
|
|
321
321
|
this.DIMTMOVE = Property.loadValue([data.DIMTMOVE, data[279]], 0);
|
|
322
322
|
|
|
323
323
|
// DXF Groupcode 280 - Horizontal dimension text position:
|
|
324
|
-
// 0 = Above dimension line and
|
|
324
|
+
// 0 = Above dimension line and centre-justified between extension lines
|
|
325
325
|
// 1 = Above dimension line and next to first extension line
|
|
326
326
|
// 2 = Above dimension line and next to second extension line
|
|
327
|
-
// 3 = Above and
|
|
328
|
-
// 4 = Above and
|
|
327
|
+
// 3 = Above and centre-justified to first extension line
|
|
328
|
+
// 4 = Above and centre-justified to second extension line
|
|
329
329
|
this.DIMJUST = Property.loadValue([data.DIMJUST, data[280]], 0);
|
|
330
330
|
|
|
331
331
|
// DXF Groupcode 281 - Suppression of first extension line:
|
|
@@ -506,7 +506,7 @@ export class DimStyle {
|
|
|
506
506
|
}
|
|
507
507
|
|
|
508
508
|
/**
|
|
509
|
-
* get the DIMCEN property for the
|
|
509
|
+
* get the DIMCEN property for the centre mark size
|
|
510
510
|
* @return {Number} DIMCEN value
|
|
511
511
|
* This uses two internal values to define the DIMCEN property
|
|
512
512
|
* DIMCENSTYL & DIMCENVALUE
|
|
@@ -604,7 +604,7 @@ export class DimStyle {
|
|
|
604
604
|
file.writeGroupCode('275', this.DIMAUNIT, DXFFile.Version.R13);
|
|
605
605
|
file.writeGroupCode('276', this.DIMFRAC, DXFFile.Version.R2000);
|
|
606
606
|
file.writeGroupCode('277', this.DIMLUNIT, DXFFile.Version.R2000);
|
|
607
|
-
// file.writeGroupCode('278', this.DIMDSEP, DXFFile.Version.R14)); - TODO: AutoCAD uses a
|
|
607
|
+
// file.writeGroupCode('278', this.DIMDSEP, DXFFile.Version.R14)); - TODO: AutoCAD uses a numerical description
|
|
608
608
|
file.writeGroupCode('279', this.DIMTMOVE, DXFFile.Version.R2000);
|
|
609
609
|
file.writeGroupCode('280', this.DIMJUST, DXFFile.Version.R13);
|
|
610
610
|
file.writeGroupCode('281', this.DIMSD1 ? 1 : 0, DXFFile.Version.R13); // convert bool to int
|
|
@@ -48,7 +48,7 @@ export class LTypeManager extends StyleManagerBase {
|
|
|
48
48
|
*/
|
|
49
49
|
dxf(file) {
|
|
50
50
|
// Create table data for ltype styles
|
|
51
|
-
// The LTYPE Table must
|
|
51
|
+
// The LTYPE Table must precede the LAYER table
|
|
52
52
|
file.writeGroupCode('0', 'TABLE');
|
|
53
53
|
file.writeGroupCode('2', 'LTYPE');
|
|
54
54
|
file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
|
package/core/tables/vport.js
CHANGED
|
@@ -12,9 +12,9 @@ export class VPort {
|
|
|
12
12
|
this.handle = Property.loadValue([data?.handle, data?.[5]]);
|
|
13
13
|
// DXF Groupcode 2 - Name
|
|
14
14
|
this.name = Property.loadValue([data?.name, data?.[2]], '*ACTIVE');
|
|
15
|
-
// DXF Groupcode 12 - View
|
|
15
|
+
// DXF Groupcode 12 - View centre X
|
|
16
16
|
this.viewCenterX = Property.loadValue([data?.viewCenterX, data?.[12]], 0);
|
|
17
|
-
// DXF Groupcode 22 - View
|
|
17
|
+
// DXF Groupcode 22 - View centre Y
|
|
18
18
|
this.viewCenterY = Property.loadValue([data?.viewCenterY, data?.[22]], 0);
|
|
19
19
|
// DXF Groupcode 40 - VPort height
|
|
20
20
|
this.height = Property.loadValue([data?.height, data?.[40]], 0);
|
package/core/tools/chamfer.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Logging } from '../lib/logging.js';
|
|
|
6
6
|
import { Utils } from '../lib/utils.js';
|
|
7
7
|
import { Point } from '../entities/point.js';
|
|
8
8
|
import { Line } from '../entities/line.js';
|
|
9
|
-
import {
|
|
9
|
+
import { PolylineBase } from '../entities/polylineBase.js';
|
|
10
10
|
import { AddState } from '../lib/stateManager.js';
|
|
11
11
|
import { Colour } from '../lib/colour.js';
|
|
12
12
|
|
|
@@ -98,9 +98,9 @@ export class Chamfer extends ChamferFilletBase {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
// input1 is a selection — validate and store first entity
|
|
101
|
-
const firstEntity = DesignCore.Scene.entities.get(input1.
|
|
101
|
+
const firstEntity = DesignCore.Scene.entities.get(input1.selectedEntityIndex);
|
|
102
102
|
DesignCore.Scene.selectionManager.removeLastSelection();
|
|
103
|
-
if (!(firstEntity instanceof Line) && !(firstEntity instanceof
|
|
103
|
+
if (!(firstEntity instanceof Line) && !(firstEntity instanceof PolylineBase)) {
|
|
104
104
|
DesignCore.Core.notify(`${firstEntity.type} - ${Strings.Message.NOCHAMFER}`);
|
|
105
105
|
continue;
|
|
106
106
|
}
|
|
@@ -112,16 +112,16 @@ export class Chamfer extends ChamferFilletBase {
|
|
|
112
112
|
const input2 = await DesignCore.Scene.inputManager.requestInput(op2);
|
|
113
113
|
if (input2 === undefined) return;
|
|
114
114
|
|
|
115
|
-
const candidate = DesignCore.Scene.entities.get(input2.
|
|
115
|
+
const candidate = DesignCore.Scene.entities.get(input2.selectedEntityIndex);
|
|
116
116
|
DesignCore.Scene.selectionManager.removeLastSelection();
|
|
117
|
-
if (!(candidate instanceof Line) && !(candidate instanceof
|
|
117
|
+
if (!(candidate instanceof Line) && !(candidate instanceof PolylineBase)) {
|
|
118
118
|
DesignCore.Core.notify(`${this.type} - ${candidate.type} ${Strings.Message.NOCHAMFER}`);
|
|
119
119
|
continue;
|
|
120
120
|
}
|
|
121
121
|
if (!this.secondPick.setPick(candidate, input2.selectedPoint, `${Strings.Strings.ARC} - ${Strings.Message.NOCHAMFER}`)) continue;
|
|
122
122
|
// If both selections are the same polyline, segments must be consecutive
|
|
123
123
|
// or they must be the open-end segments of an open polyline.
|
|
124
|
-
if (candidate === firstEntity && firstEntity instanceof
|
|
124
|
+
if (candidate === firstEntity && firstEntity instanceof PolylineBase) {
|
|
125
125
|
const isConsecutive = firstEntity.areConsecutiveSegments(this.firstPick.segmentIndex, this.secondPick.segmentIndex);
|
|
126
126
|
const lastIdx = firstEntity.points.length - 1;
|
|
127
127
|
const isOpenEnds = !firstEntity.flags.hasFlag(1) &&
|
|
@@ -2,7 +2,7 @@ import { Tool } from './tool.js';
|
|
|
2
2
|
import { Strings } from '../lib/strings.js';
|
|
3
3
|
import { Constants } from '../lib/constants.js';
|
|
4
4
|
import { Line } from '../entities/line.js';
|
|
5
|
-
import {
|
|
5
|
+
import { PolylineBase } from '../entities/polylineBase.js';
|
|
6
6
|
import { AddState, RemoveState, UpdateState } from '../lib/stateManager.js';
|
|
7
7
|
import { CornerEntity } from './cornerEntity.js';
|
|
8
8
|
import { Intersection } from '../lib/intersect.js';
|
|
@@ -104,7 +104,7 @@ export class ChamferFilletBase extends Tool {
|
|
|
104
104
|
if (index === undefined) return null;
|
|
105
105
|
|
|
106
106
|
const candidate = DesignCore.Scene.entities.get(index);
|
|
107
|
-
if (!(candidate instanceof Line) && !(candidate instanceof
|
|
107
|
+
if (!(candidate instanceof Line) && !(candidate instanceof PolylineBase)) return null;
|
|
108
108
|
|
|
109
109
|
const tempSecond = new CornerEntity();
|
|
110
110
|
if (!tempSecond.setPick(candidate, mousePoint, '')) return null;
|
|
@@ -143,8 +143,8 @@ export class ChamferFilletBase extends Tool {
|
|
|
143
143
|
*/
|
|
144
144
|
applyCornerTrim(firstCornerPoint, secondCornerPoint, newEntity) {
|
|
145
145
|
const isSharpTrim = newEntity === null;
|
|
146
|
-
const firstIsPolyline = this.firstPick.entity instanceof
|
|
147
|
-
const secondIsPolyline = this.secondPick.entity instanceof
|
|
146
|
+
const firstIsPolyline = this.firstPick.entity instanceof PolylineBase;
|
|
147
|
+
const secondIsPolyline = this.secondPick.entity instanceof PolylineBase;
|
|
148
148
|
|
|
149
149
|
// Two standalone entities: update both, optionally add the new entity.
|
|
150
150
|
if (!firstIsPolyline && !secondIsPolyline) {
|
package/core/tools/copy.js
CHANGED
|
@@ -84,10 +84,10 @@ export class Copy extends Tool {
|
|
|
84
84
|
const delta = mousePoint.subtract(this.lastMousePoint || this.points[0]);
|
|
85
85
|
this.lastMousePoint = mousePoint;
|
|
86
86
|
|
|
87
|
-
for (let i = 0; i < DesignCore.Scene.selectionManager.
|
|
88
|
-
const
|
|
89
|
-
const offsetPoints =
|
|
90
|
-
|
|
87
|
+
for (let i = 0; i < DesignCore.Scene.selectionManager.selectedEntities.length; i++) {
|
|
88
|
+
const entity = DesignCore.Scene.selectionManager.selectedEntities[i];
|
|
89
|
+
const offsetPoints = entity.points.map((p) => new Point(p.x, p.y, p.bulge, p.sequence).add(delta));
|
|
90
|
+
entity.setProperty('points', offsetPoints);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
}
|
|
@@ -103,10 +103,10 @@ export class Copy extends Tool {
|
|
|
103
103
|
const stateChanges = [];
|
|
104
104
|
|
|
105
105
|
for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
|
|
106
|
-
const
|
|
107
|
-
const offsetPoints =
|
|
108
|
-
|
|
109
|
-
const stateChange = new AddState(
|
|
106
|
+
const copyOfEntity = Utils.cloneObject(DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]));
|
|
107
|
+
const offsetPoints = copyOfEntity.points.map((p) => new Point(p.x, p.y, p.bulge, p.sequence).add(delta));
|
|
108
|
+
copyOfEntity.setProperty('points', offsetPoints);
|
|
109
|
+
const stateChange = new AddState(copyOfEntity);
|
|
110
110
|
stateChanges.push(stateChange);
|
|
111
111
|
}
|
|
112
112
|
|
package/core/tools/copybase.js
CHANGED
|
@@ -56,11 +56,11 @@ export class Copybase extends Tool {
|
|
|
56
56
|
* Perform the command
|
|
57
57
|
*/
|
|
58
58
|
action() {
|
|
59
|
-
// generate clipboard data from selected
|
|
60
|
-
const
|
|
59
|
+
// generate clipboard data from selected entities
|
|
60
|
+
const selectedEntities = DesignCore.Scene.selectionManager.selectedEntities;
|
|
61
61
|
|
|
62
62
|
// create clipboard data
|
|
63
|
-
DesignCore.Clipboard.Entities =
|
|
63
|
+
DesignCore.Clipboard.Entities = selectedEntities;
|
|
64
64
|
// set base point
|
|
65
65
|
DesignCore.Clipboard.BasePoint = this.points[0];
|
|
66
66
|
}
|
package/core/tools/copyclip.js
CHANGED
|
@@ -52,10 +52,10 @@ export class Copyclip extends Tool {
|
|
|
52
52
|
* Perform the command
|
|
53
53
|
*/
|
|
54
54
|
action() {
|
|
55
|
-
// generate clipboard data from selected
|
|
56
|
-
const
|
|
55
|
+
// generate clipboard data from selected entities
|
|
56
|
+
const selectedEntities = DesignCore.Scene.selectionManager.selectedEntities;
|
|
57
57
|
|
|
58
58
|
// create clipboard data
|
|
59
|
-
DesignCore.Clipboard.Entities =
|
|
59
|
+
DesignCore.Clipboard.Entities = selectedEntities;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Line } from '../entities/line.js';
|
|
2
|
-
import {
|
|
2
|
+
import { PolylineBase } from '../entities/polylineBase.js';
|
|
3
3
|
|
|
4
4
|
import { DesignCore } from '../designCore.js';
|
|
5
5
|
|
|
@@ -61,7 +61,7 @@ export class CornerEntity {
|
|
|
61
61
|
setPick(entity, clickPoint, arcSegmentErrorMsg) {
|
|
62
62
|
this.entity = entity;
|
|
63
63
|
this.clickPoint = clickPoint;
|
|
64
|
-
if (!(this.entity instanceof
|
|
64
|
+
if (!(this.entity instanceof PolylineBase)) {
|
|
65
65
|
this.segment = null;
|
|
66
66
|
this.segmentIndex = null;
|
|
67
67
|
return true;
|
package/core/tools/cutclip.js
CHANGED
|
@@ -53,11 +53,11 @@ export class Cutclip extends Tool {
|
|
|
53
53
|
* Perform the command
|
|
54
54
|
*/
|
|
55
55
|
action() {
|
|
56
|
-
// generate clipboard data from selected
|
|
57
|
-
const
|
|
56
|
+
// generate clipboard data from selected entities
|
|
57
|
+
const selectedEntities = DesignCore.Scene.selectionManager.selectedEntities;
|
|
58
58
|
|
|
59
59
|
// create clipboard data
|
|
60
|
-
DesignCore.Clipboard.Entities =
|
|
60
|
+
DesignCore.Clipboard.Entities = selectedEntities;
|
|
61
61
|
// get a copy of the selection set
|
|
62
62
|
const selections = DesignCore.Scene.selectionManager.selectionSet.selectionSet.slice();
|
|
63
63
|
// create state changes for each of the selections
|
package/core/tools/explode.js
CHANGED
|
@@ -83,23 +83,23 @@ export class Explode extends Tool {
|
|
|
83
83
|
|
|
84
84
|
// check the insert has a block and
|
|
85
85
|
// check the block has items
|
|
86
|
-
if (insert.block === undefined || insert.block.
|
|
86
|
+
if (insert.block === undefined || insert.block.entities.length === 0) {
|
|
87
87
|
counter++;
|
|
88
88
|
continue;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
const insertPoint = insert.points[0];
|
|
92
92
|
const block = insert.block;
|
|
93
|
-
const blockItems = block.
|
|
93
|
+
const blockItems = block.entities;
|
|
94
94
|
|
|
95
95
|
const rotation = Utils.degrees2radians(insert.getProperty('rotation'));
|
|
96
96
|
const origin = new Point(0, 0);
|
|
97
97
|
|
|
98
98
|
blockItems.forEach((blockItem) => {
|
|
99
|
-
const
|
|
100
|
-
const points =
|
|
101
|
-
|
|
102
|
-
const stateChange = new AddState(
|
|
99
|
+
const copyOfItem = Utils.cloneObject(blockItem);
|
|
100
|
+
const points = copyOfItem.points.map((p) => new Point(p.x, p.y, p.bulge, p.sequence).rotate(origin, rotation).add(insertPoint));
|
|
101
|
+
copyOfItem.points = points;
|
|
102
|
+
const stateChange = new AddState(copyOfItem);
|
|
103
103
|
stateChanges.push(stateChange);
|
|
104
104
|
});
|
|
105
105
|
|