@itwin/editor-frontend 3.0.0-dev.98 → 3.0.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/CHANGELOG.md +108 -1
- package/LICENSE.md +1 -1
- package/README.md +9 -9
- package/lib/cjs/EditTool.d.ts.map +1 -1
- package/lib/cjs/EditTool.js +18 -7
- package/lib/cjs/EditTool.js.map +1 -1
- package/lib/cjs/ElementGeometryTool.d.ts +64 -80
- package/lib/cjs/ElementGeometryTool.d.ts.map +1 -1
- package/lib/cjs/ElementGeometryTool.js +333 -295
- package/lib/cjs/ElementGeometryTool.js.map +1 -1
- package/lib/cjs/ProjectLocation/ProjectGeolocation.d.ts +10 -17
- package/lib/cjs/ProjectLocation/ProjectGeolocation.d.ts.map +1 -1
- package/lib/cjs/ProjectLocation/ProjectGeolocation.js +54 -94
- package/lib/cjs/ProjectLocation/ProjectGeolocation.js.map +1 -1
- package/lib/cjs/SketchTools.d.ts +21 -9
- package/lib/cjs/SketchTools.d.ts.map +1 -1
- package/lib/cjs/SketchTools.js +197 -204
- package/lib/cjs/SketchTools.js.map +1 -1
- package/lib/cjs/SolidModelingTools.d.ts +381 -0
- package/lib/cjs/SolidModelingTools.d.ts.map +1 -0
- package/lib/cjs/SolidModelingTools.js +1460 -0
- package/lib/cjs/SolidModelingTools.js.map +1 -0
- package/lib/cjs/TransformElementsTool.d.ts.map +1 -1
- package/lib/cjs/TransformElementsTool.js +8 -28
- package/lib/cjs/TransformElementsTool.js.map +1 -1
- package/lib/cjs/UndoRedoTool.js +1 -1
- package/lib/cjs/UndoRedoTool.js.map +1 -1
- package/lib/cjs/editor-frontend.d.ts +1 -0
- package/lib/cjs/editor-frontend.d.ts.map +1 -1
- package/lib/cjs/editor-frontend.js +1 -0
- package/lib/cjs/editor-frontend.js.map +1 -1
- package/lib/esm/EditTool.d.ts.map +1 -1
- package/lib/esm/EditTool.js +14 -3
- package/lib/esm/EditTool.js.map +1 -1
- package/lib/esm/ElementGeometryTool.d.ts +64 -80
- package/lib/esm/ElementGeometryTool.d.ts.map +1 -1
- package/lib/esm/ElementGeometryTool.js +334 -290
- package/lib/esm/ElementGeometryTool.js.map +1 -1
- package/lib/esm/ProjectLocation/ProjectGeolocation.d.ts +10 -17
- package/lib/esm/ProjectLocation/ProjectGeolocation.d.ts.map +1 -1
- package/lib/esm/ProjectLocation/ProjectGeolocation.js +54 -94
- package/lib/esm/ProjectLocation/ProjectGeolocation.js.map +1 -1
- package/lib/esm/SketchTools.d.ts +21 -9
- package/lib/esm/SketchTools.d.ts.map +1 -1
- package/lib/esm/SketchTools.js +198 -205
- package/lib/esm/SketchTools.js.map +1 -1
- package/lib/esm/SolidModelingTools.d.ts +381 -0
- package/lib/esm/SolidModelingTools.d.ts.map +1 -0
- package/lib/esm/SolidModelingTools.js +1435 -0
- package/lib/esm/SolidModelingTools.js.map +1 -0
- package/lib/esm/TransformElementsTool.d.ts.map +1 -1
- package/lib/esm/TransformElementsTool.js +8 -28
- package/lib/esm/TransformElementsTool.js.map +1 -1
- package/lib/esm/UndoRedoTool.js +1 -1
- package/lib/esm/UndoRedoTool.js.map +1 -1
- package/lib/esm/editor-frontend.d.ts +1 -0
- package/lib/esm/editor-frontend.d.ts.map +1 -1
- package/lib/esm/editor-frontend.js +1 -0
- package/lib/esm/editor-frontend.js.map +1 -1
- package/lib/public/locales/en/Editor.json +141 -3
- package/package.json +17 -25
package/lib/esm/SketchTools.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import { BentleyError } from "@itwin/core-bentley";
|
|
6
|
-
import { Angle, AngleSweep, Arc3d, BSplineCurve3d,
|
|
6
|
+
import { Angle, AngleSweep, Arc3d, BSplineCurve3d, CurveFactory, FrameBuilder, Geometry, IModelJson, InterpolationCurve3d, InterpolationCurve3dOptions, LineString3d, Loop, Matrix3d, Path, Plane3dByOriginAndUnitNormal, Point3d, PointString3d, Ray3d, RegionOps, Transform, Vector3d, YawPitchRollAngles } from "@itwin/core-geometry";
|
|
7
7
|
import { Code, ColorDef, ElementGeometry, isPlacement3dProps, LinePixels } from "@itwin/core-common";
|
|
8
8
|
import { AccuDrawHintBuilder, AngleDescription, BeButton, BeModifierKeys, CoreTools, EventHandled, GraphicType, IModelApp, LengthDescription, NotifyMessageDetails, OutputMessagePriority, TentativeOrAccuSnap, ToolAssistance, ToolAssistanceImage, ToolAssistanceInputMethod } from "@itwin/core-frontend";
|
|
9
9
|
import { editorBuiltInCmdIds } from "@itwin/editor-common";
|
|
@@ -233,6 +233,7 @@ export class CreateOrContinuePathTool extends CreateElementTool {
|
|
|
233
233
|
switch (curve.curvePrimitiveType) {
|
|
234
234
|
case "arc":
|
|
235
235
|
case "bsplineCurve":
|
|
236
|
+
case "interpolationCurve":
|
|
236
237
|
break;
|
|
237
238
|
default:
|
|
238
239
|
return;
|
|
@@ -267,6 +268,12 @@ export class CreateOrContinuePathTool extends CreateElementTool {
|
|
|
267
268
|
builder.addPointString(poles);
|
|
268
269
|
break;
|
|
269
270
|
}
|
|
271
|
+
case "interpolationCurve": {
|
|
272
|
+
const fitCurve = curve;
|
|
273
|
+
builder.setSymbology(context.viewport.getContrastToBackgroundColor(), ColorDef.black, 5);
|
|
274
|
+
builder.addPointString(fitCurve.options.fitPoints); // deep copy shoulnd't be necessary...
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
270
277
|
default:
|
|
271
278
|
break;
|
|
272
279
|
}
|
|
@@ -554,11 +561,17 @@ export class CreateOrContinuePathTool extends CreateElementTool {
|
|
|
554
561
|
await this.updateCurveAndContinuationData(ev, false, phase);
|
|
555
562
|
return true;
|
|
556
563
|
}
|
|
564
|
+
async cancelPoint(_ev) { return true; }
|
|
557
565
|
async onDataButtonDown(ev) {
|
|
558
566
|
if (!await this.acceptPoint(ev))
|
|
559
567
|
return EventHandled.Yes;
|
|
560
568
|
return super.onDataButtonDown(ev);
|
|
561
569
|
}
|
|
570
|
+
async onResetButtonUp(ev) {
|
|
571
|
+
if (!await this.cancelPoint(ev))
|
|
572
|
+
return EventHandled.Yes;
|
|
573
|
+
return super.onResetButtonUp(ev);
|
|
574
|
+
}
|
|
562
575
|
async onUndoPreviousStep() {
|
|
563
576
|
if (0 === this.accepted.length)
|
|
564
577
|
return false;
|
|
@@ -617,13 +630,13 @@ export class CreateLineStringTool extends CreateOrContinuePathTool {
|
|
|
617
630
|
const pts = (isDynamics ? [...this.accepted, ev.point] : this.accepted);
|
|
618
631
|
return LineString3d.create(pts);
|
|
619
632
|
}
|
|
620
|
-
async
|
|
633
|
+
async cancelPoint(ev) {
|
|
621
634
|
// NOTE: Starting another tool will not create element...require reset or closure...
|
|
622
635
|
if (this.isComplete(ev)) {
|
|
623
636
|
await this.updateCurveAndContinuationData(ev, false, CreateCurvePhase.DefineEnd);
|
|
624
637
|
await this.createElement();
|
|
625
638
|
}
|
|
626
|
-
return
|
|
639
|
+
return true;
|
|
627
640
|
}
|
|
628
641
|
async onRestartTool() {
|
|
629
642
|
const tool = new CreateLineStringTool();
|
|
@@ -914,70 +927,28 @@ export class CreateArcTool extends CreateOrContinuePathTool {
|
|
|
914
927
|
return;
|
|
915
928
|
}
|
|
916
929
|
const syncData = [];
|
|
917
|
-
if (!this.useRadius)
|
|
918
|
-
this.radiusProperty.displayValue = this.radiusProperty.description.format(this.radius);
|
|
919
|
-
this.radiusProperty.isDisabled = !this.useRadius;
|
|
930
|
+
if (!this.useRadius)
|
|
920
931
|
syncData.push(this.radiusProperty.syncItem);
|
|
921
|
-
|
|
922
|
-
if (!this.useSweep) {
|
|
923
|
-
this.sweepProperty.displayValue = this.sweepProperty.description.format(this.sweep);
|
|
924
|
-
this.sweepProperty.isDisabled = !this.useSweep;
|
|
932
|
+
if (!this.useSweep)
|
|
925
933
|
syncData.push(this.sweepProperty.syncItem);
|
|
926
|
-
}
|
|
927
934
|
if (0 !== syncData.length)
|
|
928
935
|
this.syncToolSettingsProperties(syncData);
|
|
929
936
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
this.sweepProperty.displayValue = this.sweepProperty.description.format(this.sweep);
|
|
937
|
-
this.sweepProperty.isDisabled = !this.useSweep;
|
|
938
|
-
this.syncToolSettingsProperties([this.sweepProperty.syncItem]);
|
|
937
|
+
getToolSettingPropertyLocked(property) {
|
|
938
|
+
if (property === this.useRadiusProperty)
|
|
939
|
+
return this.radiusProperty;
|
|
940
|
+
else if (property === this.useSweepProperty)
|
|
941
|
+
return this.sweepProperty;
|
|
942
|
+
return undefined;
|
|
939
943
|
}
|
|
940
944
|
async applyToolSettingPropertyChange(updatedValue) {
|
|
941
|
-
if (this.
|
|
942
|
-
|
|
943
|
-
|
|
945
|
+
if (!this.changeToolSettingPropertyValue(updatedValue))
|
|
946
|
+
return false;
|
|
947
|
+
if (this.methodProperty.name === updatedValue.propertyName)
|
|
944
948
|
await this.onReinitialize();
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
this.useRadius = updatedValue.value.value;
|
|
949
|
-
IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.useRadiusProperty.item);
|
|
950
|
-
this.syncRadiusState();
|
|
951
|
-
return true;
|
|
952
|
-
}
|
|
953
|
-
else if (updatedValue.propertyName === this.useSweepProperty.name) {
|
|
954
|
-
this.useSweep = updatedValue.value.value;
|
|
955
|
-
IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.useSweepProperty.item);
|
|
956
|
-
this.syncSweepState();
|
|
957
|
-
return true;
|
|
958
|
-
}
|
|
959
|
-
else if (updatedValue.propertyName === this.radiusProperty.name) {
|
|
960
|
-
if (!updatedValue.value.value) {
|
|
961
|
-
this.syncRadiusState(); // force UI to redisplay last valid value
|
|
962
|
-
return false;
|
|
963
|
-
}
|
|
964
|
-
this.radius = updatedValue.value.value;
|
|
965
|
-
IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.radiusProperty.item);
|
|
966
|
-
// If radius is changed when creating arc by start/center after center has been defined, back up a step to defined a new center point...
|
|
967
|
-
if (ArcMethod.StartCenter === this.method && this.useRadius && 2 === this.accepted.length)
|
|
968
|
-
await this.onUndoPreviousStep();
|
|
969
|
-
return true;
|
|
970
|
-
}
|
|
971
|
-
else if (updatedValue.propertyName === this.sweepProperty.name) {
|
|
972
|
-
if (!updatedValue.value.value) {
|
|
973
|
-
this.syncSweepState(); // force UI to redisplay last valid value
|
|
974
|
-
return false;
|
|
975
|
-
}
|
|
976
|
-
this.sweep = updatedValue.value.value;
|
|
977
|
-
IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.sweepProperty.item);
|
|
978
|
-
return true;
|
|
979
|
-
}
|
|
980
|
-
return false;
|
|
949
|
+
else if (updatedValue.propertyName === this.radiusProperty.name && ArcMethod.StartCenter === this.method && this.useRadius && 2 === this.accepted.length)
|
|
950
|
+
await this.onUndoPreviousStep(); // If radius is changed when creating arc by start/center after center has been defined, back up a step to defined a new center point...
|
|
951
|
+
return true;
|
|
981
952
|
}
|
|
982
953
|
supplyToolSettingsProperties() {
|
|
983
954
|
const toolSettings = new Array();
|
|
@@ -1002,23 +973,9 @@ export class CreateArcTool extends CreateOrContinuePathTool {
|
|
|
1002
973
|
if (!await super.onInstall())
|
|
1003
974
|
return false;
|
|
1004
975
|
// Setup initial values here instead of supplyToolSettingsProperties to support keyin args w/o appui-react...
|
|
1005
|
-
|
|
1006
|
-
if (undefined !== methodValue)
|
|
1007
|
-
this.methodProperty.dialogItemValue = methodValue;
|
|
1008
|
-
const radiusValue = IModelApp.toolAdmin.toolSettingsState.getInitialToolSettingValue(this.toolId, this.radiusProperty.name);
|
|
1009
|
-
if (undefined !== radiusValue)
|
|
1010
|
-
this.radiusProperty.dialogItemValue = radiusValue;
|
|
1011
|
-
const useRadiusValue = IModelApp.toolAdmin.toolSettingsState.getInitialToolSettingValue(this.toolId, this.useRadiusProperty.name);
|
|
1012
|
-
if (undefined !== useRadiusValue)
|
|
1013
|
-
this.useRadiusProperty.dialogItemValue = useRadiusValue;
|
|
976
|
+
this.initializeToolSettingPropertyValues([this.methodProperty, this.radiusProperty, this.useRadiusProperty, this.sweepProperty, this.useSweepProperty]);
|
|
1014
977
|
if (!this.radius)
|
|
1015
978
|
this.useRadius = false;
|
|
1016
|
-
const useSweepValue = IModelApp.toolAdmin.toolSettingsState.getInitialToolSettingValue(this.toolId, this.useSweepProperty.name);
|
|
1017
|
-
if (undefined !== useSweepValue)
|
|
1018
|
-
this.useSweepProperty.dialogItemValue = useSweepValue;
|
|
1019
|
-
const sweepValue = IModelApp.toolAdmin.toolSettingsState.getInitialToolSettingValue(this.toolId, this.sweepProperty.name);
|
|
1020
|
-
if (undefined !== sweepValue)
|
|
1021
|
-
this.sweepProperty.dialogItemValue = sweepValue;
|
|
1022
979
|
if (!this.sweep)
|
|
1023
980
|
this.useSweep = false;
|
|
1024
981
|
return true;
|
|
@@ -1070,16 +1027,16 @@ export class CreateArcTool extends CreateOrContinuePathTool {
|
|
|
1070
1027
|
}
|
|
1071
1028
|
// Update current session values so keyin args are picked up for tool settings/restart...
|
|
1072
1029
|
if (undefined !== arcMethod)
|
|
1073
|
-
|
|
1030
|
+
this.saveToolSettingPropertyValue(this.methodProperty, { value: arcMethod });
|
|
1074
1031
|
if (undefined !== arcRadius) {
|
|
1075
1032
|
if (0.0 !== arcRadius)
|
|
1076
|
-
|
|
1077
|
-
|
|
1033
|
+
this.saveToolSettingPropertyValue(this.radiusProperty, { value: arcRadius });
|
|
1034
|
+
this.saveToolSettingPropertyValue(this.useRadiusProperty, { value: 0.0 !== arcRadius });
|
|
1078
1035
|
}
|
|
1079
1036
|
if (undefined !== arcSweep) {
|
|
1080
1037
|
if (0.0 !== arcSweep)
|
|
1081
|
-
|
|
1082
|
-
|
|
1038
|
+
this.saveToolSettingPropertyValue(this.sweepProperty, { value: arcSweep });
|
|
1039
|
+
this.saveToolSettingPropertyValue(this.useSweepProperty, { value: 0.0 !== arcSweep });
|
|
1083
1040
|
}
|
|
1084
1041
|
return this.run();
|
|
1085
1042
|
}
|
|
@@ -1189,56 +1146,30 @@ export class CreateCircleTool extends CreateOrContinuePathTool {
|
|
|
1189
1146
|
vector90.scaleToLength(radius, vector90);
|
|
1190
1147
|
return Arc3d.create(center, vector0, vector90);
|
|
1191
1148
|
}
|
|
1192
|
-
async
|
|
1149
|
+
async cancelPoint(_ev) {
|
|
1193
1150
|
if (CircleMethod.Center === this.method && this.useRadius) {
|
|
1194
1151
|
// Exit instead of restarting to avoid having circle "stuck" on cursor...
|
|
1195
1152
|
await this.exitTool();
|
|
1196
|
-
return
|
|
1153
|
+
return false;
|
|
1197
1154
|
}
|
|
1198
|
-
return
|
|
1155
|
+
return true;
|
|
1199
1156
|
}
|
|
1200
1157
|
syncToolSettingsRadius() {
|
|
1201
1158
|
if (this.useRadius)
|
|
1202
1159
|
return;
|
|
1203
|
-
const syncData = [];
|
|
1204
|
-
if (!this.useRadius) {
|
|
1205
|
-
this.radiusProperty.displayValue = this.radiusProperty.description.format(this.radius);
|
|
1206
|
-
this.radiusProperty.isDisabled = !this.useRadius;
|
|
1207
|
-
syncData.push(this.radiusProperty.syncItem);
|
|
1208
|
-
}
|
|
1209
|
-
if (0 !== syncData.length)
|
|
1210
|
-
this.syncToolSettingsProperties(syncData);
|
|
1211
|
-
}
|
|
1212
|
-
syncRadiusState() {
|
|
1213
|
-
this.radiusProperty.displayValue = this.radiusProperty.description.format(this.radius);
|
|
1214
|
-
this.radiusProperty.isDisabled = !this.useRadius;
|
|
1215
1160
|
this.syncToolSettingsProperties([this.radiusProperty.syncItem]);
|
|
1216
1161
|
}
|
|
1162
|
+
getToolSettingPropertyLocked(property) {
|
|
1163
|
+
return (property === this.useRadiusProperty ? this.radiusProperty : undefined);
|
|
1164
|
+
}
|
|
1217
1165
|
async applyToolSettingPropertyChange(updatedValue) {
|
|
1218
|
-
if (this.
|
|
1219
|
-
|
|
1220
|
-
|
|
1166
|
+
if (!this.changeToolSettingPropertyValue(updatedValue))
|
|
1167
|
+
return false;
|
|
1168
|
+
if (this.methodProperty.name === updatedValue.propertyName)
|
|
1221
1169
|
await this.onReinitialize();
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
this.useRadius = updatedValue.value.value;
|
|
1226
|
-
IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.useRadiusProperty.item);
|
|
1227
|
-
this.syncRadiusState();
|
|
1228
|
-
if (CircleMethod.Center === this.method && this.useRadius && 0 === this.accepted.length)
|
|
1229
|
-
await this.onReinitialize();
|
|
1230
|
-
return true;
|
|
1231
|
-
}
|
|
1232
|
-
else if (updatedValue.propertyName === this.radiusProperty.name) {
|
|
1233
|
-
if (!updatedValue.value.value) {
|
|
1234
|
-
this.syncRadiusState(); // force UI to redisplay last valid value
|
|
1235
|
-
return false;
|
|
1236
|
-
}
|
|
1237
|
-
this.radius = updatedValue.value.value;
|
|
1238
|
-
IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.radiusProperty.item);
|
|
1239
|
-
return true;
|
|
1240
|
-
}
|
|
1241
|
-
return false;
|
|
1170
|
+
else if (updatedValue.propertyName === this.useRadiusProperty.name && CircleMethod.Center === this.method && this.useRadius && 0 === this.accepted.length)
|
|
1171
|
+
await this.onReinitialize();
|
|
1172
|
+
return true;
|
|
1242
1173
|
}
|
|
1243
1174
|
supplyToolSettingsProperties() {
|
|
1244
1175
|
const toolSettings = new Array();
|
|
@@ -1278,15 +1209,7 @@ export class CreateCircleTool extends CreateOrContinuePathTool {
|
|
|
1278
1209
|
if (!await super.onInstall())
|
|
1279
1210
|
return false;
|
|
1280
1211
|
// Setup initial values here instead of supplyToolSettingsProperties to support keyin args w/o appui-react...
|
|
1281
|
-
|
|
1282
|
-
if (undefined !== methodValue)
|
|
1283
|
-
this.methodProperty.dialogItemValue = methodValue;
|
|
1284
|
-
const radiusValue = IModelApp.toolAdmin.toolSettingsState.getInitialToolSettingValue(this.toolId, this.radiusProperty.name);
|
|
1285
|
-
if (undefined !== radiusValue)
|
|
1286
|
-
this.radiusProperty.dialogItemValue = radiusValue;
|
|
1287
|
-
const useRadiusValue = IModelApp.toolAdmin.toolSettingsState.getInitialToolSettingValue(this.toolId, this.useRadiusProperty.name);
|
|
1288
|
-
if (undefined !== useRadiusValue)
|
|
1289
|
-
this.useRadiusProperty.dialogItemValue = useRadiusValue;
|
|
1212
|
+
this.initializeToolSettingPropertyValues([this.methodProperty, this.radiusProperty, this.useRadiusProperty]);
|
|
1290
1213
|
if (!this.radius)
|
|
1291
1214
|
this.useRadius = false;
|
|
1292
1215
|
return true;
|
|
@@ -1324,11 +1247,11 @@ export class CreateCircleTool extends CreateOrContinuePathTool {
|
|
|
1324
1247
|
}
|
|
1325
1248
|
// Update current session values so keyin args are picked up for tool settings/restart...
|
|
1326
1249
|
if (undefined !== circleMethod)
|
|
1327
|
-
|
|
1250
|
+
this.saveToolSettingPropertyValue(this.methodProperty, { value: circleMethod });
|
|
1328
1251
|
if (undefined !== circleRadius) {
|
|
1329
1252
|
if (0.0 !== circleRadius)
|
|
1330
|
-
|
|
1331
|
-
|
|
1253
|
+
this.saveToolSettingPropertyValue(this.radiusProperty, { value: circleRadius });
|
|
1254
|
+
this.saveToolSettingPropertyValue(this.useRadiusProperty, { value: 0.0 !== circleRadius });
|
|
1332
1255
|
}
|
|
1333
1256
|
return this.run();
|
|
1334
1257
|
}
|
|
@@ -1481,27 +1404,11 @@ export class CreateRectangleTool extends CreateOrContinuePathTool {
|
|
|
1481
1404
|
return;
|
|
1482
1405
|
return { format: "flatbuffer", data: builder.entries };
|
|
1483
1406
|
}
|
|
1484
|
-
|
|
1485
|
-
this.
|
|
1486
|
-
this.radiusProperty.isDisabled = !this.useRadius;
|
|
1487
|
-
this.syncToolSettingsProperties([this.radiusProperty.syncItem]);
|
|
1407
|
+
getToolSettingPropertyLocked(property) {
|
|
1408
|
+
return (property === this.useRadiusProperty ? this.radiusProperty : undefined);
|
|
1488
1409
|
}
|
|
1489
1410
|
async applyToolSettingPropertyChange(updatedValue) {
|
|
1490
|
-
|
|
1491
|
-
this.useRadius = updatedValue.value.value;
|
|
1492
|
-
IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.useRadiusProperty.item);
|
|
1493
|
-
this.syncRadiusState();
|
|
1494
|
-
}
|
|
1495
|
-
else if (updatedValue.propertyName === this.radiusProperty.name) {
|
|
1496
|
-
if (!updatedValue.value.value) {
|
|
1497
|
-
this.syncRadiusState(); // force UI to redisplay last valid value
|
|
1498
|
-
return false;
|
|
1499
|
-
}
|
|
1500
|
-
this.radius = updatedValue.value.value;
|
|
1501
|
-
IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.radiusProperty.item);
|
|
1502
|
-
return true;
|
|
1503
|
-
}
|
|
1504
|
-
return false;
|
|
1411
|
+
return this.changeToolSettingPropertyValue(updatedValue);
|
|
1505
1412
|
}
|
|
1506
1413
|
supplyToolSettingsProperties() {
|
|
1507
1414
|
const toolSettings = new Array();
|
|
@@ -1520,12 +1427,7 @@ export class CreateRectangleTool extends CreateOrContinuePathTool {
|
|
|
1520
1427
|
if (!await super.onInstall())
|
|
1521
1428
|
return false;
|
|
1522
1429
|
// Setup initial values here instead of supplyToolSettingsProperties to support keyin args w/o appui-react...
|
|
1523
|
-
|
|
1524
|
-
if (undefined !== radiusValue)
|
|
1525
|
-
this.radiusProperty.dialogItemValue = radiusValue;
|
|
1526
|
-
const useRadiusValue = IModelApp.toolAdmin.toolSettingsState.getInitialToolSettingValue(this.toolId, this.useRadiusProperty.name);
|
|
1527
|
-
if (undefined !== useRadiusValue)
|
|
1528
|
-
this.useRadiusProperty.dialogItemValue = useRadiusValue;
|
|
1430
|
+
this.initializeToolSettingPropertyValues([this.radiusProperty, this.useRadiusProperty]);
|
|
1529
1431
|
if (!this.radius)
|
|
1530
1432
|
this.useRadius = false;
|
|
1531
1433
|
return true;
|
|
@@ -1549,8 +1451,8 @@ export class CreateRectangleTool extends CreateOrContinuePathTool {
|
|
|
1549
1451
|
// Update current session values so keyin args are picked up for tool settings/restart...
|
|
1550
1452
|
if (undefined !== cornerRadius) {
|
|
1551
1453
|
if (0.0 !== cornerRadius)
|
|
1552
|
-
|
|
1553
|
-
|
|
1454
|
+
this.saveToolSettingPropertyValue(this.radiusProperty, { value: cornerRadius });
|
|
1455
|
+
this.saveToolSettingPropertyValue(this.useRadiusProperty, { value: 0.0 !== cornerRadius });
|
|
1554
1456
|
}
|
|
1555
1457
|
return this.run();
|
|
1556
1458
|
}
|
|
@@ -1565,13 +1467,24 @@ export var BCurveMethod;
|
|
|
1565
1467
|
})(BCurveMethod || (BCurveMethod = {}));
|
|
1566
1468
|
/** @alpha Creates a bspline curve by poles or through points. Uses model and category from ToolAdmin.ActiveSettings. */
|
|
1567
1469
|
export class CreateBCurveTool extends CreateOrContinuePathTool {
|
|
1470
|
+
constructor() {
|
|
1471
|
+
super(...arguments);
|
|
1472
|
+
this._isPhysicallyClosedOrComplete = false;
|
|
1473
|
+
this._tangentPhase = CreateCurvePhase.DefineOther;
|
|
1474
|
+
}
|
|
1475
|
+
static get minArgs() { return 0; }
|
|
1476
|
+
static get maxArgs() { return 3; } // method, order, tangents...
|
|
1568
1477
|
get wantPickableDynamics() { return true; } // Allow snapping to control polygon or through points...
|
|
1569
1478
|
get showCurveConstructions() { return true; } // Display control polygon or through points...
|
|
1570
1479
|
provideToolAssistance(_mainInstrText, _additionalInstr) {
|
|
1571
1480
|
const nPts = this.accepted.length;
|
|
1572
|
-
|
|
1481
|
+
let mainMsg;
|
|
1482
|
+
if (CreateCurvePhase.DefineOther === this._tangentPhase)
|
|
1483
|
+
mainMsg = CoreTools.translate(0 === nPts ? "ElementSet.Prompts.StartPoint" : "ElementSet.Inputs.AdditionalPoint");
|
|
1484
|
+
else
|
|
1485
|
+
mainMsg = EditTools.translate(CreateCurvePhase.DefineStart === this._tangentPhase ? "CreateBCurve.Prompts.StartTangent" : "CreateBCurve.Prompts.EndTangent");
|
|
1573
1486
|
const leftMsg = CoreTools.translate("ElementSet.Inputs.AcceptPoint");
|
|
1574
|
-
const rightMsg = CoreTools.translate(nPts
|
|
1487
|
+
const rightMsg = CoreTools.translate(CreateCurvePhase.DefineOther === this._tangentPhase && nPts >= this.requiredPointCount ? "ElementSet.Inputs.Complete" : "ElementSet.Inputs.Cancel");
|
|
1575
1488
|
const mouseInstructions = [];
|
|
1576
1489
|
const touchInstructions = [];
|
|
1577
1490
|
if (!ToolAssistance.createTouchCursorInstructions(touchInstructions))
|
|
@@ -1603,43 +1516,97 @@ export class CreateBCurveTool extends CreateOrContinuePathTool {
|
|
|
1603
1516
|
set order(value) { this.orderProperty.value = value; }
|
|
1604
1517
|
get minOrder() { return 2; }
|
|
1605
1518
|
get maxOrder() { return 16; }
|
|
1519
|
+
get tangentsProperty() {
|
|
1520
|
+
if (!this._tangentsProperty)
|
|
1521
|
+
this._tangentsProperty = new DialogProperty(PropertyDescriptionHelper.buildToggleDescription("bcurveTangents", EditTools.translate("CreateBCurve.Label.Tangents")), false);
|
|
1522
|
+
return this._tangentsProperty;
|
|
1523
|
+
}
|
|
1524
|
+
get tangents() { return this.tangentsProperty.value; }
|
|
1525
|
+
set tangents(value) { this.tangentsProperty.value = value; }
|
|
1606
1526
|
get wantClosure() {
|
|
1607
1527
|
// A bcurve can support physical closure when creating a new path...
|
|
1608
1528
|
return this.allowClosure;
|
|
1609
1529
|
}
|
|
1530
|
+
get requiredPointCount() {
|
|
1531
|
+
if (BCurveMethod.ThroughPoints === this.method)
|
|
1532
|
+
return 3; // Interpolation curve is always order 4 with 3 point minimum...
|
|
1533
|
+
return this.order;
|
|
1534
|
+
}
|
|
1535
|
+
get createCurvePhase() {
|
|
1536
|
+
if (CreateCurvePhase.DefineOther !== this._tangentPhase)
|
|
1537
|
+
return CreateCurvePhase.DefineOther;
|
|
1538
|
+
return super.createCurvePhase;
|
|
1539
|
+
}
|
|
1610
1540
|
isComplete(ev) {
|
|
1611
1541
|
// Accept on reset with sufficient points...
|
|
1612
1542
|
if (BeButton.Reset === ev.button)
|
|
1613
|
-
return (this.accepted.length >= this.
|
|
1543
|
+
return (this.accepted.length >= this.requiredPointCount);
|
|
1614
1544
|
// Allow data to complete on physical closure...
|
|
1615
|
-
return this.isClosed;
|
|
1545
|
+
return this.isClosed || this._isPhysicallyClosedOrComplete;
|
|
1546
|
+
}
|
|
1547
|
+
showConstructionGraphics(ev, context) {
|
|
1548
|
+
if (CreateCurvePhase.DefineOther !== this._tangentPhase && this.current) {
|
|
1549
|
+
const fitCurve = this.current;
|
|
1550
|
+
const builder = context.createGraphic({ type: GraphicType.WorldOverlay });
|
|
1551
|
+
const color = context.viewport.getContrastToBackgroundColor();
|
|
1552
|
+
builder.setSymbology(color, ColorDef.black, 1, LinePixels.Code2);
|
|
1553
|
+
builder.addLineString([ev.point, fitCurve.options.fitPoints[CreateCurvePhase.DefineStart === this._tangentPhase ? 0 : fitCurve.options.fitPoints.length - 1]]);
|
|
1554
|
+
builder.setSymbology(color, ColorDef.black, 8);
|
|
1555
|
+
builder.addPointString([ev.point]);
|
|
1556
|
+
context.addGraphic(builder.finish());
|
|
1557
|
+
}
|
|
1558
|
+
return super.showConstructionGraphics(ev, context);
|
|
1616
1559
|
}
|
|
1617
1560
|
createNewCurvePrimitive(ev, isDynamics) {
|
|
1561
|
+
if (CreateCurvePhase.DefineOther !== this._tangentPhase && this.current) {
|
|
1562
|
+
const fitCurve = this.current;
|
|
1563
|
+
if (CreateCurvePhase.DefineStart === this._tangentPhase) {
|
|
1564
|
+
const tangentS = Vector3d.createStartEnd(ev.point, fitCurve.options.fitPoints[0]);
|
|
1565
|
+
if (tangentS.magnitude() > Geometry.smallMetricDistance)
|
|
1566
|
+
fitCurve.options.startTangent = tangentS;
|
|
1567
|
+
}
|
|
1568
|
+
else {
|
|
1569
|
+
const tangentE = Vector3d.createStartEnd(ev.point, fitCurve.options.fitPoints[fitCurve.options.fitPoints.length - 1]);
|
|
1570
|
+
if (tangentE.magnitude() > Geometry.smallMetricDistance)
|
|
1571
|
+
fitCurve.options.endTangent = tangentE;
|
|
1572
|
+
}
|
|
1573
|
+
return fitCurve;
|
|
1574
|
+
}
|
|
1618
1575
|
// Don't include current point if it's the same as the last accepted point, want dynamics to show an accurate preview of what reset will accept...
|
|
1619
1576
|
const includeCurrPt = (isDynamics && (0 === this.accepted.length || !ev.point.isAlmostEqual(this.accepted[this.accepted.length - 1])));
|
|
1620
1577
|
const pts = (includeCurrPt ? [...this.accepted, ev.point] : this.accepted);
|
|
1621
|
-
const numRequired = this.
|
|
1578
|
+
const numRequired = this.requiredPointCount;
|
|
1622
1579
|
if (pts.length < numRequired) {
|
|
1623
1580
|
// Create point/linestring construction geometry to support join...
|
|
1624
1581
|
this.isConstruction = true;
|
|
1625
1582
|
return LineString3d.create(1 === pts.length ? [pts[0], pts[0]] : pts);
|
|
1626
1583
|
}
|
|
1627
|
-
//
|
|
1628
|
-
|
|
1584
|
+
// Create periodic-looking curve on physical closure with sufficient points even when not creating a loop/surface...
|
|
1585
|
+
this._isPhysicallyClosedOrComplete = (undefined === this.continuationData && pts[0].isAlmostEqual(pts[pts.length - 1]));
|
|
1586
|
+
if (BCurveMethod.ControlPoints === this.method) {
|
|
1587
|
+
if (this._isPhysicallyClosedOrComplete && this.order > 2) {
|
|
1588
|
+
const tmpPts = pts.slice(undefined, -1); // Don't include closure point...
|
|
1589
|
+
return BSplineCurve3d.createPeriodicUniformKnots(tmpPts, this.order);
|
|
1590
|
+
}
|
|
1629
1591
|
return BSplineCurve3d.createUniformKnots(pts, this.order);
|
|
1630
|
-
// TODO: InterpolationCurve3d, set end tangents using continuation curve...self-closure, etc.
|
|
1631
|
-
return BSplineCurveOps.createThroughPoints(pts, this.order);
|
|
1632
|
-
}
|
|
1633
|
-
addConstructionGraphics(curve, showCurve, context) {
|
|
1634
|
-
// TODO: Need proper Interpolation curve class to extract/show through points...
|
|
1635
|
-
if (BCurveMethod.ThroughPoints === this.method && !showCurve && 0 !== this.accepted.length) {
|
|
1636
|
-
const builder = context.createGraphic({ type: GraphicType.WorldOverlay });
|
|
1637
|
-
builder.setSymbology(context.viewport.getContrastToBackgroundColor(), ColorDef.black, 5);
|
|
1638
|
-
builder.addPointString(this.accepted);
|
|
1639
|
-
context.addGraphic(builder.finish());
|
|
1640
|
-
return;
|
|
1641
1592
|
}
|
|
1642
|
-
|
|
1593
|
+
const interpProps = { fitPoints: pts, closed: this._isPhysicallyClosedOrComplete, isChordLenKnots: 1, isColinearTangents: 1 };
|
|
1594
|
+
// Create interpolation curve tangent to continuation curve...
|
|
1595
|
+
if (undefined !== this.continuationData && this.tangents) {
|
|
1596
|
+
const tangentS = this.continuationData.path.children[0].fractionToPointAndUnitTangent(0.0);
|
|
1597
|
+
const tangentE = this.continuationData.path.children[this.continuationData.path.children.length - 1].fractionToPointAndUnitTangent(1.0);
|
|
1598
|
+
if (pts[0].isAlmostEqual(tangentS.origin))
|
|
1599
|
+
interpProps.startTangent = tangentS.direction.scale(-1);
|
|
1600
|
+
else if (pts[0].isAlmostEqual(tangentE.origin))
|
|
1601
|
+
interpProps.startTangent = tangentE.direction;
|
|
1602
|
+
if (pts[pts.length - 1].isAlmostEqual(tangentS.origin))
|
|
1603
|
+
interpProps.endTangent = tangentS.direction.scale(-1);
|
|
1604
|
+
else if (pts[pts.length - 1].isAlmostEqual(tangentE.origin))
|
|
1605
|
+
interpProps.endTangent = tangentE.direction;
|
|
1606
|
+
this._isPhysicallyClosedOrComplete = (undefined !== interpProps.startTangent && undefined !== interpProps.endTangent);
|
|
1607
|
+
}
|
|
1608
|
+
const interpOpts = InterpolationCurve3dOptions.create(interpProps);
|
|
1609
|
+
return InterpolationCurve3d.createCapture(interpOpts);
|
|
1643
1610
|
}
|
|
1644
1611
|
getSnapGeometry() {
|
|
1645
1612
|
// Only snap to through points...
|
|
@@ -1647,40 +1614,63 @@ export class CreateBCurveTool extends CreateOrContinuePathTool {
|
|
|
1647
1614
|
return (this.accepted.length > 1 ? PointString3d.create(this.accepted) : undefined);
|
|
1648
1615
|
return super.getSnapGeometry();
|
|
1649
1616
|
}
|
|
1650
|
-
async
|
|
1617
|
+
async acceptPoint(ev) {
|
|
1618
|
+
switch (this._tangentPhase) {
|
|
1619
|
+
case CreateCurvePhase.DefineOther:
|
|
1620
|
+
return super.acceptPoint(ev);
|
|
1621
|
+
case CreateCurvePhase.DefineStart:
|
|
1622
|
+
this._tangentPhase = CreateCurvePhase.DefineEnd;
|
|
1623
|
+
break;
|
|
1624
|
+
case CreateCurvePhase.DefineEnd:
|
|
1625
|
+
this._isPhysicallyClosedOrComplete = true;
|
|
1626
|
+
break;
|
|
1627
|
+
}
|
|
1628
|
+
await this.updateCurveAndContinuationData(ev, false, CreateCurvePhase.DefineOther);
|
|
1629
|
+
return true;
|
|
1630
|
+
}
|
|
1631
|
+
async cancelPoint(ev) {
|
|
1651
1632
|
// NOTE: Starting another tool will not create element...require reset or closure...
|
|
1652
1633
|
if (this.isComplete(ev)) {
|
|
1634
|
+
if (BCurveMethod.ThroughPoints === this.method && this.tangents && this.current) {
|
|
1635
|
+
const fitCurve = this.current;
|
|
1636
|
+
switch (this._tangentPhase) {
|
|
1637
|
+
case CreateCurvePhase.DefineOther:
|
|
1638
|
+
await this.updateCurveAndContinuationData(ev, false, CreateCurvePhase.DefineEnd);
|
|
1639
|
+
this._tangentPhase = (undefined === fitCurve.options.startTangent ? CreateCurvePhase.DefineStart : CreateCurvePhase.DefineEnd);
|
|
1640
|
+
IModelApp.toolAdmin.updateDynamics();
|
|
1641
|
+
this.setupAndPromptForNextAction();
|
|
1642
|
+
return false;
|
|
1643
|
+
case CreateCurvePhase.DefineStart:
|
|
1644
|
+
fitCurve.options.startTangent = undefined; // Not accepted, compute default start tangent...
|
|
1645
|
+
this._tangentPhase = CreateCurvePhase.DefineEnd;
|
|
1646
|
+
IModelApp.toolAdmin.updateDynamics();
|
|
1647
|
+
this.setupAndPromptForNextAction();
|
|
1648
|
+
return false;
|
|
1649
|
+
case CreateCurvePhase.DefineEnd:
|
|
1650
|
+
fitCurve.options.endTangent = undefined; // Not accepted, compute default end tangent...
|
|
1651
|
+
await this.createElement();
|
|
1652
|
+
return true;
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1653
1655
|
await this.updateCurveAndContinuationData(ev, false, CreateCurvePhase.DefineEnd);
|
|
1654
1656
|
await this.createElement();
|
|
1655
1657
|
}
|
|
1656
|
-
return
|
|
1657
|
-
}
|
|
1658
|
-
syncOrderState() {
|
|
1659
|
-
this.orderProperty.displayValue = this.orderProperty.description.format(this.order);
|
|
1660
|
-
this.syncToolSettingsProperties([this.orderProperty.syncItem]);
|
|
1658
|
+
return true;
|
|
1661
1659
|
}
|
|
1662
1660
|
async applyToolSettingPropertyChange(updatedValue) {
|
|
1663
|
-
if (this.
|
|
1664
|
-
|
|
1665
|
-
|
|
1661
|
+
if (!this.changeToolSettingPropertyValue(updatedValue))
|
|
1662
|
+
return false;
|
|
1663
|
+
if (this.methodProperty.name === updatedValue.propertyName)
|
|
1666
1664
|
await this.onReinitialize();
|
|
1667
|
-
|
|
1668
|
-
}
|
|
1669
|
-
else if (updatedValue.propertyName === this.orderProperty.name) {
|
|
1670
|
-
if (!updatedValue.value.value) {
|
|
1671
|
-
this.syncOrderState(); // force UI to redisplay last valid value
|
|
1672
|
-
return false;
|
|
1673
|
-
}
|
|
1674
|
-
this.order = updatedValue.value.value;
|
|
1675
|
-
IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.orderProperty.item);
|
|
1676
|
-
return true;
|
|
1677
|
-
}
|
|
1678
|
-
return false;
|
|
1665
|
+
return true;
|
|
1679
1666
|
}
|
|
1680
1667
|
supplyToolSettingsProperties() {
|
|
1681
1668
|
const toolSettings = new Array();
|
|
1682
1669
|
toolSettings.push(this.methodProperty.toDialogItem({ rowPriority: 1, columnIndex: 0 }));
|
|
1683
|
-
|
|
1670
|
+
if (BCurveMethod.ThroughPoints === this.method)
|
|
1671
|
+
toolSettings.push(this.tangentsProperty.toDialogItem({ rowPriority: 2, columnIndex: 0 }));
|
|
1672
|
+
else
|
|
1673
|
+
toolSettings.push(this.orderProperty.toDialogItem({ rowPriority: 2, columnIndex: 1 }));
|
|
1684
1674
|
return toolSettings;
|
|
1685
1675
|
}
|
|
1686
1676
|
async onRestartTool() {
|
|
@@ -1692,21 +1682,18 @@ export class CreateBCurveTool extends CreateOrContinuePathTool {
|
|
|
1692
1682
|
if (!await super.onInstall())
|
|
1693
1683
|
return false;
|
|
1694
1684
|
// Setup initial values here instead of supplyToolSettingsProperties to support keyin args w/o appui-react...
|
|
1695
|
-
|
|
1696
|
-
if (undefined !== methodValue)
|
|
1697
|
-
this.methodProperty.dialogItemValue = methodValue;
|
|
1698
|
-
const orderValue = IModelApp.toolAdmin.toolSettingsState.getInitialToolSettingValue(this.toolId, this.orderProperty.name);
|
|
1699
|
-
if (undefined !== orderValue)
|
|
1700
|
-
this.orderProperty.dialogItemValue = orderValue;
|
|
1685
|
+
this.initializeToolSettingPropertyValues([this.methodProperty, this.orderProperty, this.tangentsProperty]);
|
|
1701
1686
|
return true;
|
|
1702
1687
|
}
|
|
1703
1688
|
/** The keyin takes the following arguments, all of which are optional:
|
|
1704
1689
|
* - `method=0|1` How bcurve will be defined. 0 for control points, 1 for through points.
|
|
1705
1690
|
* - `order=number` bcurve order from 2 to 16.
|
|
1691
|
+
* - 'tangents=0|1 Whether to specify start/end tangents for through points construction.
|
|
1706
1692
|
*/
|
|
1707
1693
|
async parseAndRun(...inputArgs) {
|
|
1708
1694
|
let bcurveMethod;
|
|
1709
1695
|
let bcurveOrder;
|
|
1696
|
+
let bcurveTangents;
|
|
1710
1697
|
for (const arg of inputArgs) {
|
|
1711
1698
|
const parts = arg.split("=");
|
|
1712
1699
|
if (2 !== parts.length)
|
|
@@ -1730,12 +1717,18 @@ export class CreateBCurveTool extends CreateOrContinuePathTool {
|
|
|
1730
1717
|
bcurveOrder = order;
|
|
1731
1718
|
}
|
|
1732
1719
|
}
|
|
1720
|
+
else if (parts[0].toLowerCase().startsWith("ta")) {
|
|
1721
|
+
const tangents = Number.parseInt(parts[1], 10);
|
|
1722
|
+
bcurveTangents = (0 !== tangents);
|
|
1723
|
+
}
|
|
1733
1724
|
}
|
|
1734
1725
|
// Update current session values so keyin args are picked up for tool settings/restart...
|
|
1735
1726
|
if (undefined !== bcurveMethod)
|
|
1736
|
-
|
|
1727
|
+
this.saveToolSettingPropertyValue(this.methodProperty, { value: bcurveMethod });
|
|
1737
1728
|
if (undefined !== bcurveOrder)
|
|
1738
|
-
|
|
1729
|
+
this.saveToolSettingPropertyValue(this.orderProperty, { value: bcurveOrder });
|
|
1730
|
+
if (undefined !== bcurveTangents)
|
|
1731
|
+
this.saveToolSettingPropertyValue(this.tangentsProperty, { value: bcurveTangents });
|
|
1739
1732
|
return this.run();
|
|
1740
1733
|
}
|
|
1741
1734
|
}
|