@itwin/editor-frontend 3.4.0-dev.9 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +53 -1
  2. package/lib/cjs/CreateElementTool.d.ts +100 -100
  3. package/lib/cjs/CreateElementTool.js +327 -327
  4. package/lib/cjs/CreateElementTool.js.map +1 -1
  5. package/lib/cjs/DeleteElementsTool.d.ts +15 -15
  6. package/lib/cjs/DeleteElementsTool.js +40 -40
  7. package/lib/cjs/DeleteElementsTool.js.map +1 -1
  8. package/lib/cjs/EditTool.d.ts +37 -37
  9. package/lib/cjs/EditTool.js +135 -135
  10. package/lib/cjs/EditTool.js.map +1 -1
  11. package/lib/cjs/ElementGeometryTool.d.ts +148 -148
  12. package/lib/cjs/ElementGeometryTool.d.ts.map +1 -1
  13. package/lib/cjs/ElementGeometryTool.js +711 -708
  14. package/lib/cjs/ElementGeometryTool.js.map +1 -1
  15. package/lib/cjs/ModifyCurveTools.d.ts +118 -118
  16. package/lib/cjs/ModifyCurveTools.js +668 -668
  17. package/lib/cjs/ModifyCurveTools.js.map +1 -1
  18. package/lib/cjs/ProjectLocation/ProjectExtentsDecoration.d.ts +137 -137
  19. package/lib/cjs/ProjectLocation/ProjectExtentsDecoration.d.ts.map +1 -1
  20. package/lib/cjs/ProjectLocation/ProjectExtentsDecoration.js +824 -821
  21. package/lib/cjs/ProjectLocation/ProjectExtentsDecoration.js.map +1 -1
  22. package/lib/cjs/ProjectLocation/ProjectGeolocation.d.ts +135 -135
  23. package/lib/cjs/ProjectLocation/ProjectGeolocation.d.ts.map +1 -1
  24. package/lib/cjs/ProjectLocation/ProjectGeolocation.js +532 -507
  25. package/lib/cjs/ProjectLocation/ProjectGeolocation.js.map +1 -1
  26. package/lib/cjs/SketchTools.d.ts +306 -306
  27. package/lib/cjs/SketchTools.js +1707 -1707
  28. package/lib/cjs/SketchTools.js.map +1 -1
  29. package/lib/cjs/SolidModelingTools.d.ts +380 -380
  30. package/lib/cjs/SolidModelingTools.d.ts.map +1 -1
  31. package/lib/cjs/SolidModelingTools.js +1461 -1459
  32. package/lib/cjs/SolidModelingTools.js.map +1 -1
  33. package/lib/cjs/SolidPrimitiveTools.d.ts +254 -254
  34. package/lib/cjs/SolidPrimitiveTools.js +1095 -1095
  35. package/lib/cjs/SolidPrimitiveTools.js.map +1 -1
  36. package/lib/cjs/TransformElementsTool.d.ts +166 -166
  37. package/lib/cjs/TransformElementsTool.js +654 -654
  38. package/lib/cjs/TransformElementsTool.js.map +1 -1
  39. package/lib/cjs/UndoRedoTool.d.ts +16 -16
  40. package/lib/cjs/UndoRedoTool.js +42 -42
  41. package/lib/cjs/UndoRedoTool.js.map +1 -1
  42. package/lib/cjs/editor-frontend.d.ts +15 -15
  43. package/lib/cjs/editor-frontend.js +31 -31
  44. package/lib/cjs/editor-frontend.js.map +1 -1
  45. package/lib/esm/CreateElementTool.d.ts +100 -100
  46. package/lib/esm/CreateElementTool.js +319 -319
  47. package/lib/esm/CreateElementTool.js.map +1 -1
  48. package/lib/esm/DeleteElementsTool.d.ts +15 -15
  49. package/lib/esm/DeleteElementsTool.js +36 -36
  50. package/lib/esm/DeleteElementsTool.js.map +1 -1
  51. package/lib/esm/EditTool.d.ts +37 -37
  52. package/lib/esm/EditTool.js +131 -131
  53. package/lib/esm/EditTool.js.map +1 -1
  54. package/lib/esm/ElementGeometryTool.d.ts +148 -148
  55. package/lib/esm/ElementGeometryTool.d.ts.map +1 -1
  56. package/lib/esm/ElementGeometryTool.js +703 -700
  57. package/lib/esm/ElementGeometryTool.js.map +1 -1
  58. package/lib/esm/ModifyCurveTools.d.ts +118 -118
  59. package/lib/esm/ModifyCurveTools.js +660 -660
  60. package/lib/esm/ModifyCurveTools.js.map +1 -1
  61. package/lib/esm/ProjectLocation/ProjectExtentsDecoration.d.ts +137 -137
  62. package/lib/esm/ProjectLocation/ProjectExtentsDecoration.d.ts.map +1 -1
  63. package/lib/esm/ProjectLocation/ProjectExtentsDecoration.js +816 -813
  64. package/lib/esm/ProjectLocation/ProjectExtentsDecoration.js.map +1 -1
  65. package/lib/esm/ProjectLocation/ProjectGeolocation.d.ts +135 -135
  66. package/lib/esm/ProjectLocation/ProjectGeolocation.d.ts.map +1 -1
  67. package/lib/esm/ProjectLocation/ProjectGeolocation.js +526 -501
  68. package/lib/esm/ProjectLocation/ProjectGeolocation.js.map +1 -1
  69. package/lib/esm/SketchTools.d.ts +306 -306
  70. package/lib/esm/SketchTools.js +1697 -1697
  71. package/lib/esm/SketchTools.js.map +1 -1
  72. package/lib/esm/SolidModelingTools.d.ts +380 -380
  73. package/lib/esm/SolidModelingTools.d.ts.map +1 -1
  74. package/lib/esm/SolidModelingTools.js +1436 -1434
  75. package/lib/esm/SolidModelingTools.js.map +1 -1
  76. package/lib/esm/SolidPrimitiveTools.d.ts +254 -254
  77. package/lib/esm/SolidPrimitiveTools.js +1086 -1086
  78. package/lib/esm/SolidPrimitiveTools.js.map +1 -1
  79. package/lib/esm/TransformElementsTool.d.ts +166 -166
  80. package/lib/esm/TransformElementsTool.js +646 -646
  81. package/lib/esm/TransformElementsTool.js.map +1 -1
  82. package/lib/esm/UndoRedoTool.d.ts +16 -16
  83. package/lib/esm/UndoRedoTool.js +36 -36
  84. package/lib/esm/UndoRedoTool.js.map +1 -1
  85. package/lib/esm/editor-frontend.d.ts +15 -15
  86. package/lib/esm/editor-frontend.js +19 -19
  87. package/lib/esm/editor-frontend.js.map +1 -1
  88. package/lib/public/locales/en/Editor.json +448 -448
  89. package/package.json +15 -15
@@ -1,669 +1,669 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExtendCurveTool = exports.BreakCurveTool = exports.OffsetCurveTool = exports.ModifyCurveTool = exports.CurveData = void 0;
4
- /*---------------------------------------------------------------------------------------------
5
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
- * See LICENSE.md in the project root for license terms and full copyright notice.
7
- *--------------------------------------------------------------------------------------------*/
8
- const core_frontend_1 = require("@itwin/core-frontend");
9
- const core_common_1 = require("@itwin/core-common");
10
- const EditTool_1 = require("./EditTool");
11
- const core_geometry_1 = require("@itwin/core-geometry");
12
- const editor_common_1 = require("@itwin/editor-common");
13
- const CreateElementTool_1 = require("./CreateElementTool");
14
- const appui_abstract_1 = require("@itwin/appui-abstract");
15
- const core_bentley_1 = require("@itwin/core-bentley");
16
- /** @alpha */
17
- class CurveData {
18
- constructor(props, params, geom) {
19
- this.props = props;
20
- this.params = params;
21
- this.geom = geom;
22
- }
23
- }
24
- exports.CurveData = CurveData;
25
- /** @alpha Base class for applying an offset to path and loops. */
26
- class ModifyCurveTool extends core_frontend_1.ElementSetTool {
27
- constructor() {
28
- super(...arguments);
29
- this._checkedIds = new Map();
30
- this._firstResult = true;
31
- }
32
- allowView(_vp) { return true; }
33
- isCompatibleViewport(vp, isSelectedViewChange) { return (super.isCompatibleViewport(vp, isSelectedViewChange) && undefined !== vp && this.allowView(vp)); }
34
- async startCommand() {
35
- if (undefined !== this._startedCmd)
36
- return this._startedCmd;
37
- return EditTool_1.EditTools.startCommand(editor_common_1.editorBuiltInCmdIds.cmdBasicManipulation, this.iModel.key);
38
- }
39
- static callCommand(method, ...args) {
40
- return EditTool_1.EditTools.callCommand(method, ...args);
41
- }
42
- agendaAppearance(isDynamics) {
43
- if (isDynamics) {
44
- if (undefined === this._agendaAppearanceDynamic)
45
- this._agendaAppearanceDynamic = core_common_1.FeatureAppearance.fromTransparency(0.0);
46
- return this._agendaAppearanceDynamic;
47
- }
48
- if (undefined === this._agendaAppearanceDefault)
49
- this._agendaAppearanceDefault = core_common_1.FeatureAppearance.fromTransparency(0.9);
50
- return this._agendaAppearanceDefault;
51
- }
52
- get wantAgendaAppearanceOverride() { return false; }
53
- addFeatureOverrides(overrides, _vp) {
54
- if (this.agenda.isEmpty)
55
- return;
56
- const appearance = this.agendaAppearance(false);
57
- this.agenda.elements.forEach((elementId) => { overrides.override({ elementId, appearance }); });
58
- }
59
- updateAgendaAppearanceProvider(drop) {
60
- if (!this.wantAgendaAppearanceOverride)
61
- return;
62
- for (const vp of core_frontend_1.IModelApp.viewManager) {
63
- if (!this.allowView(vp))
64
- continue;
65
- if (drop || this.agenda.isEmpty)
66
- vp.dropFeatureOverrideProvider(this);
67
- else if (!vp.addFeatureOverrideProvider(this))
68
- vp.setFeatureOverrideProviderChanged();
69
- }
70
- }
71
- clearGraphics() {
72
- if (undefined === this._graphicsProvider)
73
- return;
74
- this._graphicsProvider.cleanupGraphic();
75
- this._graphicsProvider = undefined;
76
- }
77
- async createGraphics(ev) {
78
- if (!core_frontend_1.IModelApp.viewManager.inDynamicsMode)
79
- return; // Don't need to create graphic if dynamics aren't yet active...
80
- const geometry = this.getGeometryProps(ev, false);
81
- if (undefined === geometry)
82
- return;
83
- const elemProps = this.getElementProps(ev);
84
- if (undefined === (elemProps === null || elemProps === void 0 ? void 0 : elemProps.placement))
85
- return;
86
- if (undefined === this._graphicsProvider) {
87
- if (this._firstResult) {
88
- this.updateAgendaAppearanceProvider();
89
- this._firstResult = false;
90
- }
91
- this._graphicsProvider = new CreateElementTool_1.DynamicGraphicsProvider(this.iModel, this.toolId);
92
- }
93
- // Set chord tolerance for non-linear curve primitives...
94
- if (ev.viewport)
95
- this._graphicsProvider.chordTolerance = (0, CreateElementTool_1.computeChordToleranceFromPoint)(ev.viewport, ev.point);
96
- await this._graphicsProvider.createGraphic(elemProps.category, elemProps.placement, geometry);
97
- }
98
- static isSingleCurve(info) {
99
- const it = new core_common_1.ElementGeometry.Iterator(info);
100
- it.requestWorldCoordinates();
101
- for (const entry of it) {
102
- const geom = entry.toGeometryQuery();
103
- if (undefined === geom)
104
- return;
105
- if ("curvePrimitive" === geom.geometryCategory) {
106
- return { curve: geom, params: entry.geomParams };
107
- }
108
- else if ("curveCollection" === geom.geometryCategory) {
109
- return { curve: geom, params: entry.geomParams };
110
- }
111
- break;
112
- }
113
- return;
114
- }
115
- acceptCurve(_curve) { return true; }
116
- modifyCurve(_ev, _isAccept) { return undefined; }
117
- async getCurveData(id) {
118
- try {
119
- this._startedCmd = await this.startCommand();
120
- const reject = [core_common_1.ElementGeometryOpcode.Polyface, core_common_1.ElementGeometryOpcode.SolidPrimitive, core_common_1.ElementGeometryOpcode.BsplineSurface, core_common_1.ElementGeometryOpcode.BRep];
121
- const info = await ModifyCurveTool.callCommand("requestElementGeometry", id, { maxDisplayable: 1, reject, geometry: { curves: true, surfaces: true, solids: false } });
122
- if (undefined === info)
123
- return undefined;
124
- const data = ModifyCurveTool.isSingleCurve(info);
125
- if (undefined === data)
126
- return undefined;
127
- if (!this.acceptCurve(data.curve))
128
- return undefined;
129
- const props = await this.iModel.elements.loadProps(id);
130
- if (undefined === props)
131
- return undefined;
132
- return new CurveData(props, data.params, data.curve);
133
- }
134
- catch (err) {
135
- core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, core_common_1.BentleyError.getErrorMessage(err)));
136
- return undefined;
137
- }
138
- }
139
- onGeometryFilterChanged() { this._checkedIds.clear(); }
140
- async acceptElementForOperation(id) {
141
- if (core_bentley_1.Id64.isInvalid(id) || core_bentley_1.Id64.isTransient(id))
142
- return false;
143
- let accept = this._checkedIds.get(id);
144
- if (undefined === accept) {
145
- if (this.agenda.isEmpty && this._checkedIds.size > 1000)
146
- this._checkedIds.clear(); // Limit auto-locate cache size to something reasonable...
147
- accept = (undefined !== await this.getCurveData(id));
148
- this._checkedIds.set(id, accept);
149
- }
150
- return accept;
151
- }
152
- async isElementValidForOperation(hit, out) {
153
- if (!await super.isElementValidForOperation(hit, out))
154
- return false;
155
- return this.acceptElementForOperation(hit.sourceId);
156
- }
157
- async onAgendaModified() {
158
- this.curveData = undefined;
159
- if (this.agenda.isEmpty)
160
- return;
161
- const id = this.agenda.elements[this.agenda.length - 1];
162
- this.curveData = await this.getCurveData(id);
163
- }
164
- onDynamicFrame(_ev, context) {
165
- if (undefined !== this._graphicsProvider)
166
- this._graphicsProvider.addGraphic(context);
167
- }
168
- async onMouseMotion(ev) {
169
- return this.createGraphics(ev);
170
- }
171
- setupAccuDraw() {
172
- const hints = new core_frontend_1.AccuDrawHintBuilder();
173
- hints.enableSmartRotation = true;
174
- hints.sendHints(false);
175
- }
176
- setupAndPromptForNextAction() {
177
- this.setupAccuDraw();
178
- super.setupAndPromptForNextAction();
179
- }
180
- getGeometryProps(ev, isAccept) {
181
- if (undefined === this.curveData)
182
- return;
183
- const offset = this.modifyCurve(ev, isAccept);
184
- if (undefined === offset)
185
- return;
186
- const builder = new core_common_1.ElementGeometry.Builder();
187
- builder.setLocalToWorldFromPlacement(this.curveData.props.placement);
188
- if (!builder.appendGeometryParamsChange(this.curveData.params))
189
- return;
190
- if (!builder.appendGeometryQuery(offset))
191
- return;
192
- return { format: "flatbuffer", data: builder.entries };
193
- }
194
- getElementProps(ev) {
195
- var _a;
196
- if (undefined === this.curveData)
197
- return;
198
- if (!this.wantModifyOriginal) {
199
- // Create result as new element with same model and category as original...
200
- const classFullName = (((_a = ev.viewport) === null || _a === void 0 ? void 0 : _a.view.is3d()) ? "Generic:PhysicalObject" : "BisCore:DrawingGraphic");
201
- return { classFullName, model: this.curveData.props.model, category: this.curveData.props.category, code: core_common_1.Code.createEmpty(), placement: this.curveData.props.placement };
202
- }
203
- return this.curveData.props;
204
- }
205
- async applyAgendaOperation(ev) {
206
- const geometry = this.getGeometryProps(ev, true);
207
- if (undefined === geometry)
208
- return false;
209
- const elemProps = this.getElementProps(ev);
210
- if (undefined === elemProps)
211
- return false;
212
- if ("flatbuffer" === geometry.format)
213
- elemProps.elementGeometryBuilderParams = { entryArray: geometry.data };
214
- else
215
- elemProps.geom = geometry.data;
216
- try {
217
- this._startedCmd = await this.startCommand();
218
- if (undefined === elemProps.id) {
219
- const repeatOperation = this.wantContinueWithPreviousResult;
220
- if (repeatOperation)
221
- this.agenda.clear();
222
- const newId = await ModifyCurveTool.callCommand("insertGeometricElement", elemProps);
223
- if (repeatOperation && this.agenda.add(newId))
224
- await this.onAgendaModified();
225
- }
226
- else {
227
- await ModifyCurveTool.callCommand("updateGeometricElement", elemProps);
228
- }
229
- return true;
230
- }
231
- catch (err) {
232
- core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, core_common_1.BentleyError.getErrorMessage(err) || "An unknown error occurred."));
233
- return false;
234
- }
235
- }
236
- async processAgenda(ev) {
237
- if (await this.applyAgendaOperation(ev))
238
- return this.saveChanges();
239
- }
240
- get wantModifyOriginal() { return true; }
241
- get wantContinueWithPreviousResult() { return false; }
242
- async onProcessComplete() {
243
- // Don't restart tool want to continue operation using previous result...
244
- if (this.wantContinueWithPreviousResult && !this.agenda.isEmpty && undefined !== this.curveData)
245
- return;
246
- return super.onProcessComplete();
247
- }
248
- async onUnsuspend() {
249
- if (!this._firstResult)
250
- this.updateAgendaAppearanceProvider();
251
- return super.onUnsuspend();
252
- }
253
- async onSuspend() {
254
- if (!this._firstResult)
255
- this.updateAgendaAppearanceProvider(true);
256
- return super.onSuspend();
257
- }
258
- async onPostInstall() {
259
- await super.onPostInstall();
260
- if (this.wantAgendaAppearanceOverride)
261
- this.agenda.manageHiliteState = false;
262
- }
263
- async onCleanup() {
264
- this.clearGraphics();
265
- this.updateAgendaAppearanceProvider(true);
266
- return super.onCleanup();
267
- }
268
- }
269
- exports.ModifyCurveTool = ModifyCurveTool;
270
- /** @alpha Tool for applying an offset to paths and loops. */
271
- class OffsetCurveTool extends ModifyCurveTool {
272
- get wantAccuSnap() { return true; }
273
- get wantDynamics() { return true; }
274
- get useDistanceProperty() {
275
- if (!this._useDistanceProperty)
276
- this._useDistanceProperty = new appui_abstract_1.DialogProperty(appui_abstract_1.PropertyDescriptionHelper.buildLockPropertyDescription("useOffsetDistance"), false);
277
- return this._useDistanceProperty;
278
- }
279
- get useDistance() { return this.useDistanceProperty.value; }
280
- set useDistance(value) { this.useDistanceProperty.value = value; }
281
- get distanceProperty() {
282
- if (!this._distanceProperty)
283
- this._distanceProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.LengthDescription("offsetDistance", EditTool_1.EditTools.translate("OffsetCurve.Label.Distance")), 0.1, undefined, !this.useDistance);
284
- return this._distanceProperty;
285
- }
286
- get distance() { return this.distanceProperty.value; }
287
- set distance(value) { this.distanceProperty.value = value; }
288
- get makeCopyProperty() {
289
- if (!this._makeCopyProperty)
290
- this._makeCopyProperty = new appui_abstract_1.DialogProperty(appui_abstract_1.PropertyDescriptionHelper.buildToggleDescription("offsetCopy", EditTool_1.EditTools.translate("OffsetCurve.Label.MakeCopy")), false);
291
- return this._makeCopyProperty;
292
- }
293
- get makeCopy() { return this.makeCopyProperty.value; }
294
- set makeCopy(value) { this.makeCopyProperty.value = value; }
295
- getToolSettingPropertyLocked(property) {
296
- return (property === this.useDistanceProperty ? this.distanceProperty : undefined);
297
- }
298
- async applyToolSettingPropertyChange(updatedValue) {
299
- return this.changeToolSettingPropertyValue(updatedValue);
300
- }
301
- supplyToolSettingsProperties() {
302
- this.initializeToolSettingPropertyValues([this.makeCopyProperty, this.useDistanceProperty, this.distanceProperty]);
303
- const toolSettings = new Array();
304
- // ensure controls are enabled/disabled based on current lock property state
305
- this.distanceProperty.isDisabled = !this.useDistance;
306
- const useDistanceLock = this.useDistanceProperty.toDialogItem({ rowPriority: 1, columnIndex: 0 });
307
- toolSettings.push(this.distanceProperty.toDialogItem({ rowPriority: 1, columnIndex: 1 }, useDistanceLock));
308
- toolSettings.push(this.makeCopyProperty.toDialogItem({ rowPriority: 2, columnIndex: 0 }));
309
- return toolSettings;
310
- }
311
- acceptCurve(curve) {
312
- if ("curvePrimitive" === curve.geometryCategory)
313
- return true;
314
- switch (curve.curveCollectionType) {
315
- case "path":
316
- case "loop":
317
- return true;
318
- default:
319
- return false;
320
- }
321
- }
322
- modifyCurve(ev, isAccept) {
323
- var _a;
324
- if (undefined === ev.viewport)
325
- return undefined;
326
- const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
327
- if (undefined === geom)
328
- return undefined;
329
- const matrix = core_frontend_1.AccuDrawHintBuilder.getCurrentRotation(ev.viewport, true, true);
330
- const localToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(matrix === null || matrix === void 0 ? void 0 : matrix.getColumn(2), geom);
331
- if (undefined === localToWorld)
332
- return undefined;
333
- const worldToLocal = localToWorld.inverse();
334
- if (undefined === worldToLocal)
335
- return undefined;
336
- const geomXY = ((geom instanceof core_geometry_1.CurvePrimitive) ? core_geometry_1.Path.create(geom) : geom).cloneTransformed(worldToLocal);
337
- if (undefined === geomXY)
338
- return undefined;
339
- const spacePoint = core_frontend_1.AccuDrawHintBuilder.projectPointToPlaneInView(ev.point, localToWorld.getOrigin(), localToWorld.matrix.getColumn(2), ev.viewport);
340
- if (undefined === spacePoint)
341
- return undefined;
342
- worldToLocal.multiplyPoint3d(spacePoint, spacePoint);
343
- spacePoint.z = 0.0;
344
- const closeDetail = geomXY.closestPoint(spacePoint);
345
- if (undefined === (closeDetail === null || closeDetail === void 0 ? void 0 : closeDetail.curve))
346
- return undefined;
347
- const unitZ = core_geometry_1.Vector3d.unitZ();
348
- const unitX = closeDetail.curve.fractionToPointAndUnitTangent(closeDetail.fraction).direction;
349
- const unitY = unitZ.unitCrossProduct(unitX);
350
- if (undefined === unitY)
351
- return undefined;
352
- let distance = closeDetail.point.distance(spacePoint);
353
- const refDir = core_geometry_1.Vector3d.createStartEnd(closeDetail.point, spacePoint);
354
- if (refDir.dotProduct(unitY) < 0.0)
355
- distance = -distance;
356
- let offset = 0.0;
357
- if (this.useDistance) {
358
- offset = this.distance;
359
- if ((offset < 0.0 && distance > 0.0) || (offset > 0.0 && distance < 0.0))
360
- offset = -offset;
361
- }
362
- else {
363
- offset = distance;
364
- }
365
- if (Math.abs(offset) < core_geometry_1.Geometry.smallMetricDistance)
366
- return undefined;
367
- if (offset !== this.distance) {
368
- this.distance = offset;
369
- this.syncToolSettingPropertyValue(this.distanceProperty);
370
- if (isAccept)
371
- this.saveToolSettingPropertyValue(this.distanceProperty, this.distanceProperty.dialogItemValue);
372
- }
373
- const jointOptions = new core_geometry_1.JointOptions(offset);
374
- jointOptions.preserveEllipticalArcs = true;
375
- const offsetGeom = core_geometry_1.RegionOps.constructCurveXYOffset(geomXY, jointOptions);
376
- if (undefined === offsetGeom)
377
- return undefined;
378
- if (!offsetGeom.tryTransformInPlace(localToWorld))
379
- return undefined;
380
- if (geom instanceof core_geometry_1.CurvePrimitive && offsetGeom instanceof core_geometry_1.Path && 1 === offsetGeom.children.length)
381
- return offsetGeom.getChild(0); // Don't create path for offset of single open curve...
382
- return offsetGeom;
383
- }
384
- get wantModifyOriginal() {
385
- return !this.makeCopy;
386
- }
387
- get wantContinueWithPreviousResult() {
388
- return !this.wantModifyOriginal;
389
- }
390
- setupAccuDraw() {
391
- var _a;
392
- const hints = new core_frontend_1.AccuDrawHintBuilder();
393
- if (this.agenda.isEmpty) {
394
- hints.enableSmartRotation = true;
395
- }
396
- else if (undefined !== this.anchorPoint && undefined !== this.targetView) {
397
- const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
398
- const closeDetail = (geom instanceof core_geometry_1.CurvePrimitive) ? geom.closestPoint(this.anchorPoint, false) : geom === null || geom === void 0 ? void 0 : geom.closestPoint(this.anchorPoint);
399
- if (undefined !== (closeDetail === null || closeDetail === void 0 ? void 0 : closeDetail.curve)) {
400
- const unitX = closeDetail.curve.fractionToPointAndUnitTangent(closeDetail.fraction).direction;
401
- if (undefined !== unitX) {
402
- const matrix = core_frontend_1.AccuDrawHintBuilder.getCurrentRotation(this.targetView, true, true);
403
- const localToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(matrix === null || matrix === void 0 ? void 0 : matrix.getColumn(2), geom);
404
- if (undefined !== localToWorld) {
405
- const unitZ = localToWorld.matrix.getColumn(2);
406
- const frame = core_geometry_1.Matrix3d.createRigidFromColumns(unitX, unitZ, core_geometry_1.AxisOrder.XZY);
407
- if (undefined !== frame) {
408
- hints.setOrigin(closeDetail.point);
409
- hints.setMatrix(frame);
410
- }
411
- }
412
- }
413
- }
414
- }
415
- hints.sendHints(false);
416
- }
417
- provideToolAssistance(_mainInstrText, _additionalInstr) {
418
- let mainMsg;
419
- if (!this.agenda.isEmpty)
420
- mainMsg = EditTool_1.EditTools.translate("OffsetCurve.Prompts.DefineOffset");
421
- super.provideToolAssistance(mainMsg);
422
- }
423
- async onRestartTool() {
424
- const tool = new OffsetCurveTool();
425
- if (!await tool.run())
426
- return this.exitTool();
427
- }
428
- }
429
- exports.OffsetCurveTool = OffsetCurveTool;
430
- OffsetCurveTool.toolId = "OffsetCurve";
431
- OffsetCurveTool.iconSpec = "icon-scale"; // Need better icon...
432
- /** @alpha Tool for opening loops and splitting paths. */
433
- class BreakCurveTool extends ModifyCurveTool {
434
- constructor() {
435
- super(...arguments);
436
- this.modifyOriginal = true;
437
- }
438
- get wantAccuSnap() { return true; }
439
- get wantModifyOriginal() { return this.modifyOriginal; }
440
- acceptCurve(curve) {
441
- if ("curvePrimitive" === curve.geometryCategory)
442
- return true;
443
- switch (curve.curveCollectionType) {
444
- case "path":
445
- case "loop":
446
- return true;
447
- default:
448
- return false;
449
- }
450
- }
451
- doBreakCurve(ev) {
452
- var _a;
453
- this.resultA = this.resultB = undefined;
454
- if (undefined === ev.viewport)
455
- return;
456
- const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
457
- if (undefined === geom)
458
- return;
459
- const closeDetail = (geom instanceof core_geometry_1.CurvePrimitive) ? geom.closestPoint(ev.point, false) : geom.closestPoint(ev.point);
460
- if (undefined === (closeDetail === null || closeDetail === void 0 ? void 0 : closeDetail.curve))
461
- return;
462
- const selectedStart = (closeDetail.fraction <= core_geometry_1.Geometry.smallFraction);
463
- const selectedEnd = (closeDetail.fraction >= (1.0 - core_geometry_1.Geometry.smallFraction));
464
- if (geom instanceof core_geometry_1.CurvePrimitive) {
465
- if (selectedStart || selectedEnd)
466
- return; // split is no-op...
467
- this.resultA = geom.clonePartialCurve(0.0, closeDetail.fraction);
468
- this.resultB = geom.clonePartialCurve(closeDetail.fraction, 1.0);
469
- return;
470
- }
471
- else if (geom instanceof core_geometry_1.Path) {
472
- const firstCurve = geom.children[0];
473
- const lastCurve = geom.children[geom.children.length - 1];
474
- if ((closeDetail.curve === firstCurve && selectedStart) || (closeDetail.curve === lastCurve && selectedEnd))
475
- return; // split is no-op...
476
- let beforeCurve = true;
477
- const resultA = core_geometry_1.Path.create();
478
- const resultB = core_geometry_1.Path.create();
479
- for (const curve of geom.children) {
480
- if (curve === closeDetail.curve) {
481
- if (selectedStart) {
482
- resultB.children.push(curve.clone());
483
- }
484
- else if (selectedEnd) {
485
- resultA.children.push(curve.clone());
486
- }
487
- else {
488
- const curveA = curve.clonePartialCurve(0.0, closeDetail.fraction);
489
- if (undefined !== curveA)
490
- resultA.children.push(curveA);
491
- const curveB = curve.clonePartialCurve(closeDetail.fraction, 1.0);
492
- if (undefined !== curveB)
493
- resultB.children.push(curveB);
494
- }
495
- beforeCurve = false;
496
- }
497
- else {
498
- if (beforeCurve)
499
- resultA.children.push(curve.clone());
500
- else
501
- resultB.children.push(curve.clone());
502
- }
503
- }
504
- this.resultA = resultA;
505
- this.resultB = resultB;
506
- }
507
- else if (geom instanceof core_geometry_1.Loop) {
508
- const closeIndex = geom.children.findIndex((child) => child === closeDetail.curve);
509
- if (-1 === closeIndex)
510
- return;
511
- const endIndex = closeIndex + geom.children.length;
512
- const resultA = core_geometry_1.Path.create(); // Result is always a single path...
513
- if (selectedStart) {
514
- resultA.children.push(closeDetail.curve.clone());
515
- }
516
- else if (!selectedEnd) {
517
- const curveB = closeDetail.curve.clonePartialCurve(closeDetail.fraction, 1.0);
518
- if (undefined !== curveB)
519
- resultA.children.push(curveB);
520
- }
521
- for (let index = closeIndex; index < endIndex; ++index) {
522
- const curve = geom.cyclicCurvePrimitive(index);
523
- if (undefined === curve || curve === closeDetail.curve)
524
- continue;
525
- resultA.children.push(curve.clone());
526
- }
527
- if (selectedEnd) {
528
- resultA.children.push(closeDetail.curve.clone());
529
- }
530
- else if (!selectedStart) {
531
- const curveA = closeDetail.curve.clonePartialCurve(0.0, closeDetail.fraction);
532
- if (undefined !== curveA)
533
- resultA.children.push(curveA);
534
- }
535
- this.resultA = resultA;
536
- }
537
- }
538
- modifyCurve(_ev, _isAccept) {
539
- return (this.wantModifyOriginal ? this.resultA : this.resultB);
540
- }
541
- async processAgenda(ev) {
542
- this.doBreakCurve(ev);
543
- if (undefined === this.resultA || !await this.applyAgendaOperation(ev))
544
- return;
545
- if (undefined !== this.resultB) {
546
- this.modifyOriginal = false;
547
- await this.applyAgendaOperation(ev);
548
- }
549
- return this.saveChanges();
550
- }
551
- provideToolAssistance(_mainInstrText, _additionalInstr) {
552
- let mainMsg;
553
- if (this.agenda.isEmpty)
554
- mainMsg = EditTool_1.EditTools.translate("BreakCurve.Prompts.IdentifyBreak");
555
- super.provideToolAssistance(mainMsg);
556
- }
557
- async onRestartTool() {
558
- const tool = new BreakCurveTool();
559
- if (!await tool.run())
560
- return this.exitTool();
561
- }
562
- }
563
- exports.BreakCurveTool = BreakCurveTool;
564
- BreakCurveTool.toolId = "BreakCurve";
565
- BreakCurveTool.iconSpec = "icon-scale"; // Need better icon...
566
- /** @alpha Tool for extending/shortening curves. */
567
- class ExtendCurveTool extends ModifyCurveTool {
568
- get wantAccuSnap() { return true; }
569
- get wantDynamics() { return true; }
570
- get wantAgendaAppearanceOverride() { return true; }
571
- acceptCurve(curve) {
572
- if ("curvePrimitive" !== curve.geometryCategory)
573
- return false;
574
- return curve.isExtensibleFractionSpace;
575
- }
576
- modifyCurve(ev, _isAccept) {
577
- var _a;
578
- if (undefined === ev.viewport || undefined === this.anchorPoint)
579
- return undefined;
580
- const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
581
- if (undefined === geom)
582
- return undefined;
583
- const matrix = core_frontend_1.AccuDrawHintBuilder.getCurrentRotation(ev.viewport, true, true);
584
- const localToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(matrix === null || matrix === void 0 ? void 0 : matrix.getColumn(2), geom);
585
- if (undefined === localToWorld)
586
- return undefined;
587
- const worldToLocal = localToWorld.inverse();
588
- if (undefined === worldToLocal)
589
- return undefined;
590
- const spacePoint = core_frontend_1.AccuDrawHintBuilder.projectPointToPlaneInView(ev.point, localToWorld.getOrigin(), localToWorld.matrix.getColumn(2), ev.viewport);
591
- if (undefined === spacePoint)
592
- return undefined;
593
- const pickDetail = geom.closestPoint(this.anchorPoint, false);
594
- if (undefined === (pickDetail === null || pickDetail === void 0 ? void 0 : pickDetail.curve))
595
- return undefined;
596
- const closeDetail = geom.closestPoint(spacePoint, true);
597
- if (undefined === (closeDetail === null || closeDetail === void 0 ? void 0 : closeDetail.curve))
598
- return undefined;
599
- if (closeDetail.curve instanceof core_geometry_1.Arc3d) {
600
- if (pickDetail.fraction > 0.5 && closeDetail.fraction < 0.0) {
601
- const smallArc = closeDetail.curve.clonePartialCurve(closeDetail.fraction, 0.0);
602
- smallArc.sweep.cloneComplement(false, smallArc.sweep);
603
- return smallArc;
604
- }
605
- else if (pickDetail.fraction <= 0.5 && closeDetail.fraction > 1.0) {
606
- const smallArc = closeDetail.curve.clonePartialCurve(1.0, closeDetail.fraction);
607
- smallArc.sweep.cloneComplement(false, smallArc.sweep);
608
- return smallArc;
609
- }
610
- else if (Math.abs(pickDetail.fraction > 0.5 ? closeDetail.fraction : 1.0 - closeDetail.fraction) < core_geometry_1.Geometry.smallFraction) {
611
- const fullArc = closeDetail.curve.clone();
612
- fullArc.sweep = core_geometry_1.AngleSweep.create360();
613
- return fullArc;
614
- }
615
- }
616
- return closeDetail.curve.clonePartialCurve(pickDetail.fraction > 0.5 ? 0.0 : 1.0, closeDetail.fraction);
617
- }
618
- setupAccuDraw() {
619
- var _a;
620
- const hints = new core_frontend_1.AccuDrawHintBuilder();
621
- if (this.agenda.isEmpty) {
622
- hints.enableSmartRotation = true;
623
- }
624
- else {
625
- const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
626
- if (undefined === geom || "curvePrimitive" !== geom.geometryCategory)
627
- return;
628
- if (geom instanceof core_geometry_1.Arc3d) {
629
- const matrix = geom.matrixClone();
630
- matrix.normalizeColumnsInPlace();
631
- hints.setOrigin(geom.center);
632
- hints.setMatrix(matrix);
633
- hints.setModePolar();
634
- }
635
- else if (geom instanceof core_geometry_1.LineSegment3d) {
636
- const pickDetail = (undefined !== this.anchorPoint ? geom.closestPoint(this.anchorPoint, false) : undefined);
637
- if (undefined !== (pickDetail === null || pickDetail === void 0 ? void 0 : pickDetail.curve)) {
638
- hints.setOrigin(pickDetail.fraction > 0.5 ? geom.point0Ref : geom.point1Ref);
639
- hints.setXAxis(core_geometry_1.Vector3d.createStartEnd(pickDetail.fraction > 0.5 ? geom.point0Ref : geom.point1Ref, pickDetail.fraction > 0.5 ? geom.point1Ref : geom.point0Ref));
640
- }
641
- hints.setModeRectangular();
642
- }
643
- else if (geom instanceof core_geometry_1.LineString3d) {
644
- const pickDetail = (undefined !== this.anchorPoint ? geom.closestPoint(this.anchorPoint, false) : undefined);
645
- if (undefined !== (pickDetail === null || pickDetail === void 0 ? void 0 : pickDetail.curve) && geom.numPoints() > 1) {
646
- hints.setOrigin(geom.packedPoints.getPoint3dAtUncheckedPointIndex(pickDetail.fraction > 0.5 ? geom.numPoints() - 2 : 1));
647
- hints.setXAxis(core_geometry_1.Vector3d.createStartEnd(geom.packedPoints.getPoint3dAtUncheckedPointIndex(pickDetail.fraction > 0.5 ? geom.numPoints() - 2 : 1), geom.packedPoints.getPoint3dAtUncheckedPointIndex(pickDetail.fraction > 0.5 ? geom.numPoints() - 1 : 0)));
648
- }
649
- hints.setModeRectangular();
650
- }
651
- }
652
- hints.sendHints(false);
653
- }
654
- provideToolAssistance(_mainInstrText, _additionalInstr) {
655
- let mainMsg;
656
- if (this.agenda.isEmpty)
657
- mainMsg = EditTool_1.EditTools.translate("ExtendCurve.Prompts.IdentifyEnd");
658
- super.provideToolAssistance(mainMsg);
659
- }
660
- async onRestartTool() {
661
- const tool = new ExtendCurveTool();
662
- if (!await tool.run())
663
- return this.exitTool();
664
- }
665
- }
666
- exports.ExtendCurveTool = ExtendCurveTool;
667
- ExtendCurveTool.toolId = "ExtendCurve";
668
- ExtendCurveTool.iconSpec = "icon-scale"; // Need better icon...
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExtendCurveTool = exports.BreakCurveTool = exports.OffsetCurveTool = exports.ModifyCurveTool = exports.CurveData = void 0;
4
+ /*---------------------------------------------------------------------------------------------
5
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
+ * See LICENSE.md in the project root for license terms and full copyright notice.
7
+ *--------------------------------------------------------------------------------------------*/
8
+ const core_frontend_1 = require("@itwin/core-frontend");
9
+ const core_common_1 = require("@itwin/core-common");
10
+ const EditTool_1 = require("./EditTool");
11
+ const core_geometry_1 = require("@itwin/core-geometry");
12
+ const editor_common_1 = require("@itwin/editor-common");
13
+ const CreateElementTool_1 = require("./CreateElementTool");
14
+ const appui_abstract_1 = require("@itwin/appui-abstract");
15
+ const core_bentley_1 = require("@itwin/core-bentley");
16
+ /** @alpha */
17
+ class CurveData {
18
+ constructor(props, params, geom) {
19
+ this.props = props;
20
+ this.params = params;
21
+ this.geom = geom;
22
+ }
23
+ }
24
+ exports.CurveData = CurveData;
25
+ /** @alpha Base class for applying an offset to path and loops. */
26
+ class ModifyCurveTool extends core_frontend_1.ElementSetTool {
27
+ constructor() {
28
+ super(...arguments);
29
+ this._checkedIds = new Map();
30
+ this._firstResult = true;
31
+ }
32
+ allowView(_vp) { return true; }
33
+ isCompatibleViewport(vp, isSelectedViewChange) { return (super.isCompatibleViewport(vp, isSelectedViewChange) && undefined !== vp && this.allowView(vp)); }
34
+ async startCommand() {
35
+ if (undefined !== this._startedCmd)
36
+ return this._startedCmd;
37
+ return EditTool_1.EditTools.startCommand(editor_common_1.editorBuiltInCmdIds.cmdBasicManipulation, this.iModel.key);
38
+ }
39
+ static callCommand(method, ...args) {
40
+ return EditTool_1.EditTools.callCommand(method, ...args);
41
+ }
42
+ agendaAppearance(isDynamics) {
43
+ if (isDynamics) {
44
+ if (undefined === this._agendaAppearanceDynamic)
45
+ this._agendaAppearanceDynamic = core_common_1.FeatureAppearance.fromTransparency(0.0);
46
+ return this._agendaAppearanceDynamic;
47
+ }
48
+ if (undefined === this._agendaAppearanceDefault)
49
+ this._agendaAppearanceDefault = core_common_1.FeatureAppearance.fromTransparency(0.9);
50
+ return this._agendaAppearanceDefault;
51
+ }
52
+ get wantAgendaAppearanceOverride() { return false; }
53
+ addFeatureOverrides(overrides, _vp) {
54
+ if (this.agenda.isEmpty)
55
+ return;
56
+ const appearance = this.agendaAppearance(false);
57
+ this.agenda.elements.forEach((elementId) => overrides.override({ elementId, appearance }));
58
+ }
59
+ updateAgendaAppearanceProvider(drop) {
60
+ if (!this.wantAgendaAppearanceOverride)
61
+ return;
62
+ for (const vp of core_frontend_1.IModelApp.viewManager) {
63
+ if (!this.allowView(vp))
64
+ continue;
65
+ if (drop || this.agenda.isEmpty)
66
+ vp.dropFeatureOverrideProvider(this);
67
+ else if (!vp.addFeatureOverrideProvider(this))
68
+ vp.setFeatureOverrideProviderChanged();
69
+ }
70
+ }
71
+ clearGraphics() {
72
+ if (undefined === this._graphicsProvider)
73
+ return;
74
+ this._graphicsProvider.cleanupGraphic();
75
+ this._graphicsProvider = undefined;
76
+ }
77
+ async createGraphics(ev) {
78
+ if (!core_frontend_1.IModelApp.viewManager.inDynamicsMode)
79
+ return; // Don't need to create graphic if dynamics aren't yet active...
80
+ const geometry = this.getGeometryProps(ev, false);
81
+ if (undefined === geometry)
82
+ return;
83
+ const elemProps = this.getElementProps(ev);
84
+ if (undefined === (elemProps === null || elemProps === void 0 ? void 0 : elemProps.placement))
85
+ return;
86
+ if (undefined === this._graphicsProvider) {
87
+ if (this._firstResult) {
88
+ this.updateAgendaAppearanceProvider();
89
+ this._firstResult = false;
90
+ }
91
+ this._graphicsProvider = new CreateElementTool_1.DynamicGraphicsProvider(this.iModel, this.toolId);
92
+ }
93
+ // Set chord tolerance for non-linear curve primitives...
94
+ if (ev.viewport)
95
+ this._graphicsProvider.chordTolerance = (0, CreateElementTool_1.computeChordToleranceFromPoint)(ev.viewport, ev.point);
96
+ await this._graphicsProvider.createGraphic(elemProps.category, elemProps.placement, geometry);
97
+ }
98
+ static isSingleCurve(info) {
99
+ const it = new core_common_1.ElementGeometry.Iterator(info);
100
+ it.requestWorldCoordinates();
101
+ for (const entry of it) {
102
+ const geom = entry.toGeometryQuery();
103
+ if (undefined === geom)
104
+ return;
105
+ if ("curvePrimitive" === geom.geometryCategory) {
106
+ return { curve: geom, params: entry.geomParams };
107
+ }
108
+ else if ("curveCollection" === geom.geometryCategory) {
109
+ return { curve: geom, params: entry.geomParams };
110
+ }
111
+ break;
112
+ }
113
+ return;
114
+ }
115
+ acceptCurve(_curve) { return true; }
116
+ modifyCurve(_ev, _isAccept) { return undefined; }
117
+ async getCurveData(id) {
118
+ try {
119
+ this._startedCmd = await this.startCommand();
120
+ const reject = [core_common_1.ElementGeometryOpcode.Polyface, core_common_1.ElementGeometryOpcode.SolidPrimitive, core_common_1.ElementGeometryOpcode.BsplineSurface, core_common_1.ElementGeometryOpcode.BRep];
121
+ const info = await ModifyCurveTool.callCommand("requestElementGeometry", id, { maxDisplayable: 1, reject, geometry: { curves: true, surfaces: true, solids: false } });
122
+ if (undefined === info)
123
+ return undefined;
124
+ const data = ModifyCurveTool.isSingleCurve(info);
125
+ if (undefined === data)
126
+ return undefined;
127
+ if (!this.acceptCurve(data.curve))
128
+ return undefined;
129
+ const props = await this.iModel.elements.loadProps(id);
130
+ if (undefined === props)
131
+ return undefined;
132
+ return new CurveData(props, data.params, data.curve);
133
+ }
134
+ catch (err) {
135
+ core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, core_common_1.BentleyError.getErrorMessage(err)));
136
+ return undefined;
137
+ }
138
+ }
139
+ onGeometryFilterChanged() { this._checkedIds.clear(); }
140
+ async acceptElementForOperation(id) {
141
+ if (core_bentley_1.Id64.isInvalid(id) || core_bentley_1.Id64.isTransient(id))
142
+ return false;
143
+ let accept = this._checkedIds.get(id);
144
+ if (undefined === accept) {
145
+ if (this.agenda.isEmpty && this._checkedIds.size > 1000)
146
+ this._checkedIds.clear(); // Limit auto-locate cache size to something reasonable...
147
+ accept = (undefined !== await this.getCurveData(id));
148
+ this._checkedIds.set(id, accept);
149
+ }
150
+ return accept;
151
+ }
152
+ async isElementValidForOperation(hit, out) {
153
+ if (!await super.isElementValidForOperation(hit, out))
154
+ return false;
155
+ return this.acceptElementForOperation(hit.sourceId);
156
+ }
157
+ async onAgendaModified() {
158
+ this.curveData = undefined;
159
+ if (this.agenda.isEmpty)
160
+ return;
161
+ const id = this.agenda.elements[this.agenda.length - 1];
162
+ this.curveData = await this.getCurveData(id);
163
+ }
164
+ onDynamicFrame(_ev, context) {
165
+ if (undefined !== this._graphicsProvider)
166
+ this._graphicsProvider.addGraphic(context);
167
+ }
168
+ async onMouseMotion(ev) {
169
+ return this.createGraphics(ev);
170
+ }
171
+ setupAccuDraw() {
172
+ const hints = new core_frontend_1.AccuDrawHintBuilder();
173
+ hints.enableSmartRotation = true;
174
+ hints.sendHints(false);
175
+ }
176
+ setupAndPromptForNextAction() {
177
+ this.setupAccuDraw();
178
+ super.setupAndPromptForNextAction();
179
+ }
180
+ getGeometryProps(ev, isAccept) {
181
+ if (undefined === this.curveData)
182
+ return;
183
+ const offset = this.modifyCurve(ev, isAccept);
184
+ if (undefined === offset)
185
+ return;
186
+ const builder = new core_common_1.ElementGeometry.Builder();
187
+ builder.setLocalToWorldFromPlacement(this.curveData.props.placement);
188
+ if (!builder.appendGeometryParamsChange(this.curveData.params))
189
+ return;
190
+ if (!builder.appendGeometryQuery(offset))
191
+ return;
192
+ return { format: "flatbuffer", data: builder.entries };
193
+ }
194
+ getElementProps(ev) {
195
+ var _a;
196
+ if (undefined === this.curveData)
197
+ return;
198
+ if (!this.wantModifyOriginal) {
199
+ // Create result as new element with same model and category as original...
200
+ const classFullName = (((_a = ev.viewport) === null || _a === void 0 ? void 0 : _a.view.is3d()) ? "Generic:PhysicalObject" : "BisCore:DrawingGraphic");
201
+ return { classFullName, model: this.curveData.props.model, category: this.curveData.props.category, code: core_common_1.Code.createEmpty(), placement: this.curveData.props.placement };
202
+ }
203
+ return this.curveData.props;
204
+ }
205
+ async applyAgendaOperation(ev) {
206
+ const geometry = this.getGeometryProps(ev, true);
207
+ if (undefined === geometry)
208
+ return false;
209
+ const elemProps = this.getElementProps(ev);
210
+ if (undefined === elemProps)
211
+ return false;
212
+ if ("flatbuffer" === geometry.format)
213
+ elemProps.elementGeometryBuilderParams = { entryArray: geometry.data };
214
+ else
215
+ elemProps.geom = geometry.data;
216
+ try {
217
+ this._startedCmd = await this.startCommand();
218
+ if (undefined === elemProps.id) {
219
+ const repeatOperation = this.wantContinueWithPreviousResult;
220
+ if (repeatOperation)
221
+ this.agenda.clear();
222
+ const newId = await ModifyCurveTool.callCommand("insertGeometricElement", elemProps);
223
+ if (repeatOperation && this.agenda.add(newId))
224
+ await this.onAgendaModified();
225
+ }
226
+ else {
227
+ await ModifyCurveTool.callCommand("updateGeometricElement", elemProps);
228
+ }
229
+ return true;
230
+ }
231
+ catch (err) {
232
+ core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, core_common_1.BentleyError.getErrorMessage(err) || "An unknown error occurred."));
233
+ return false;
234
+ }
235
+ }
236
+ async processAgenda(ev) {
237
+ if (await this.applyAgendaOperation(ev))
238
+ return this.saveChanges();
239
+ }
240
+ get wantModifyOriginal() { return true; }
241
+ get wantContinueWithPreviousResult() { return false; }
242
+ async onProcessComplete() {
243
+ // Don't restart tool want to continue operation using previous result...
244
+ if (this.wantContinueWithPreviousResult && !this.agenda.isEmpty && undefined !== this.curveData)
245
+ return;
246
+ return super.onProcessComplete();
247
+ }
248
+ async onUnsuspend() {
249
+ if (!this._firstResult)
250
+ this.updateAgendaAppearanceProvider();
251
+ return super.onUnsuspend();
252
+ }
253
+ async onSuspend() {
254
+ if (!this._firstResult)
255
+ this.updateAgendaAppearanceProvider(true);
256
+ return super.onSuspend();
257
+ }
258
+ async onPostInstall() {
259
+ await super.onPostInstall();
260
+ if (this.wantAgendaAppearanceOverride)
261
+ this.agenda.manageHiliteState = false;
262
+ }
263
+ async onCleanup() {
264
+ this.clearGraphics();
265
+ this.updateAgendaAppearanceProvider(true);
266
+ return super.onCleanup();
267
+ }
268
+ }
269
+ exports.ModifyCurveTool = ModifyCurveTool;
270
+ /** @alpha Tool for applying an offset to paths and loops. */
271
+ class OffsetCurveTool extends ModifyCurveTool {
272
+ get wantAccuSnap() { return true; }
273
+ get wantDynamics() { return true; }
274
+ get useDistanceProperty() {
275
+ if (!this._useDistanceProperty)
276
+ this._useDistanceProperty = new appui_abstract_1.DialogProperty(appui_abstract_1.PropertyDescriptionHelper.buildLockPropertyDescription("useOffsetDistance"), false);
277
+ return this._useDistanceProperty;
278
+ }
279
+ get useDistance() { return this.useDistanceProperty.value; }
280
+ set useDistance(value) { this.useDistanceProperty.value = value; }
281
+ get distanceProperty() {
282
+ if (!this._distanceProperty)
283
+ this._distanceProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.LengthDescription("offsetDistance", EditTool_1.EditTools.translate("OffsetCurve.Label.Distance")), 0.1, undefined, !this.useDistance);
284
+ return this._distanceProperty;
285
+ }
286
+ get distance() { return this.distanceProperty.value; }
287
+ set distance(value) { this.distanceProperty.value = value; }
288
+ get makeCopyProperty() {
289
+ if (!this._makeCopyProperty)
290
+ this._makeCopyProperty = new appui_abstract_1.DialogProperty(appui_abstract_1.PropertyDescriptionHelper.buildToggleDescription("offsetCopy", EditTool_1.EditTools.translate("OffsetCurve.Label.MakeCopy")), false);
291
+ return this._makeCopyProperty;
292
+ }
293
+ get makeCopy() { return this.makeCopyProperty.value; }
294
+ set makeCopy(value) { this.makeCopyProperty.value = value; }
295
+ getToolSettingPropertyLocked(property) {
296
+ return (property === this.useDistanceProperty ? this.distanceProperty : undefined);
297
+ }
298
+ async applyToolSettingPropertyChange(updatedValue) {
299
+ return this.changeToolSettingPropertyValue(updatedValue);
300
+ }
301
+ supplyToolSettingsProperties() {
302
+ this.initializeToolSettingPropertyValues([this.makeCopyProperty, this.useDistanceProperty, this.distanceProperty]);
303
+ const toolSettings = new Array();
304
+ // ensure controls are enabled/disabled based on current lock property state
305
+ this.distanceProperty.isDisabled = !this.useDistance;
306
+ const useDistanceLock = this.useDistanceProperty.toDialogItem({ rowPriority: 1, columnIndex: 0 });
307
+ toolSettings.push(this.distanceProperty.toDialogItem({ rowPriority: 1, columnIndex: 1 }, useDistanceLock));
308
+ toolSettings.push(this.makeCopyProperty.toDialogItem({ rowPriority: 2, columnIndex: 0 }));
309
+ return toolSettings;
310
+ }
311
+ acceptCurve(curve) {
312
+ if ("curvePrimitive" === curve.geometryCategory)
313
+ return true;
314
+ switch (curve.curveCollectionType) {
315
+ case "path":
316
+ case "loop":
317
+ return true;
318
+ default:
319
+ return false;
320
+ }
321
+ }
322
+ modifyCurve(ev, isAccept) {
323
+ var _a;
324
+ if (undefined === ev.viewport)
325
+ return undefined;
326
+ const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
327
+ if (undefined === geom)
328
+ return undefined;
329
+ const matrix = core_frontend_1.AccuDrawHintBuilder.getCurrentRotation(ev.viewport, true, true);
330
+ const localToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(matrix === null || matrix === void 0 ? void 0 : matrix.getColumn(2), geom);
331
+ if (undefined === localToWorld)
332
+ return undefined;
333
+ const worldToLocal = localToWorld.inverse();
334
+ if (undefined === worldToLocal)
335
+ return undefined;
336
+ const geomXY = ((geom instanceof core_geometry_1.CurvePrimitive) ? core_geometry_1.Path.create(geom) : geom).cloneTransformed(worldToLocal);
337
+ if (undefined === geomXY)
338
+ return undefined;
339
+ const spacePoint = core_frontend_1.AccuDrawHintBuilder.projectPointToPlaneInView(ev.point, localToWorld.getOrigin(), localToWorld.matrix.getColumn(2), ev.viewport);
340
+ if (undefined === spacePoint)
341
+ return undefined;
342
+ worldToLocal.multiplyPoint3d(spacePoint, spacePoint);
343
+ spacePoint.z = 0.0;
344
+ const closeDetail = geomXY.closestPoint(spacePoint);
345
+ if (undefined === (closeDetail === null || closeDetail === void 0 ? void 0 : closeDetail.curve))
346
+ return undefined;
347
+ const unitZ = core_geometry_1.Vector3d.unitZ();
348
+ const unitX = closeDetail.curve.fractionToPointAndUnitTangent(closeDetail.fraction).direction;
349
+ const unitY = unitZ.unitCrossProduct(unitX);
350
+ if (undefined === unitY)
351
+ return undefined;
352
+ let distance = closeDetail.point.distance(spacePoint);
353
+ const refDir = core_geometry_1.Vector3d.createStartEnd(closeDetail.point, spacePoint);
354
+ if (refDir.dotProduct(unitY) < 0.0)
355
+ distance = -distance;
356
+ let offset = 0.0;
357
+ if (this.useDistance) {
358
+ offset = this.distance;
359
+ if ((offset < 0.0 && distance > 0.0) || (offset > 0.0 && distance < 0.0))
360
+ offset = -offset;
361
+ }
362
+ else {
363
+ offset = distance;
364
+ }
365
+ if (Math.abs(offset) < core_geometry_1.Geometry.smallMetricDistance)
366
+ return undefined;
367
+ if (offset !== this.distance) {
368
+ this.distance = offset;
369
+ this.syncToolSettingPropertyValue(this.distanceProperty);
370
+ if (isAccept)
371
+ this.saveToolSettingPropertyValue(this.distanceProperty, this.distanceProperty.dialogItemValue);
372
+ }
373
+ const jointOptions = new core_geometry_1.JointOptions(offset);
374
+ jointOptions.preserveEllipticalArcs = true;
375
+ const offsetGeom = core_geometry_1.RegionOps.constructCurveXYOffset(geomXY, jointOptions);
376
+ if (undefined === offsetGeom)
377
+ return undefined;
378
+ if (!offsetGeom.tryTransformInPlace(localToWorld))
379
+ return undefined;
380
+ if (geom instanceof core_geometry_1.CurvePrimitive && offsetGeom instanceof core_geometry_1.Path && 1 === offsetGeom.children.length)
381
+ return offsetGeom.getChild(0); // Don't create path for offset of single open curve...
382
+ return offsetGeom;
383
+ }
384
+ get wantModifyOriginal() {
385
+ return !this.makeCopy;
386
+ }
387
+ get wantContinueWithPreviousResult() {
388
+ return !this.wantModifyOriginal;
389
+ }
390
+ setupAccuDraw() {
391
+ var _a;
392
+ const hints = new core_frontend_1.AccuDrawHintBuilder();
393
+ if (this.agenda.isEmpty) {
394
+ hints.enableSmartRotation = true;
395
+ }
396
+ else if (undefined !== this.anchorPoint && undefined !== this.targetView) {
397
+ const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
398
+ const closeDetail = (geom instanceof core_geometry_1.CurvePrimitive) ? geom.closestPoint(this.anchorPoint, false) : geom === null || geom === void 0 ? void 0 : geom.closestPoint(this.anchorPoint);
399
+ if (undefined !== (closeDetail === null || closeDetail === void 0 ? void 0 : closeDetail.curve)) {
400
+ const unitX = closeDetail.curve.fractionToPointAndUnitTangent(closeDetail.fraction).direction;
401
+ if (undefined !== unitX) {
402
+ const matrix = core_frontend_1.AccuDrawHintBuilder.getCurrentRotation(this.targetView, true, true);
403
+ const localToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(matrix === null || matrix === void 0 ? void 0 : matrix.getColumn(2), geom);
404
+ if (undefined !== localToWorld) {
405
+ const unitZ = localToWorld.matrix.getColumn(2);
406
+ const frame = core_geometry_1.Matrix3d.createRigidFromColumns(unitX, unitZ, core_geometry_1.AxisOrder.XZY);
407
+ if (undefined !== frame) {
408
+ hints.setOrigin(closeDetail.point);
409
+ hints.setMatrix(frame);
410
+ }
411
+ }
412
+ }
413
+ }
414
+ }
415
+ hints.sendHints(false);
416
+ }
417
+ provideToolAssistance(_mainInstrText, _additionalInstr) {
418
+ let mainMsg;
419
+ if (!this.agenda.isEmpty)
420
+ mainMsg = EditTool_1.EditTools.translate("OffsetCurve.Prompts.DefineOffset");
421
+ super.provideToolAssistance(mainMsg);
422
+ }
423
+ async onRestartTool() {
424
+ const tool = new OffsetCurveTool();
425
+ if (!await tool.run())
426
+ return this.exitTool();
427
+ }
428
+ }
429
+ exports.OffsetCurveTool = OffsetCurveTool;
430
+ OffsetCurveTool.toolId = "OffsetCurve";
431
+ OffsetCurveTool.iconSpec = "icon-scale"; // Need better icon...
432
+ /** @alpha Tool for opening loops and splitting paths. */
433
+ class BreakCurveTool extends ModifyCurveTool {
434
+ constructor() {
435
+ super(...arguments);
436
+ this.modifyOriginal = true;
437
+ }
438
+ get wantAccuSnap() { return true; }
439
+ get wantModifyOriginal() { return this.modifyOriginal; }
440
+ acceptCurve(curve) {
441
+ if ("curvePrimitive" === curve.geometryCategory)
442
+ return true;
443
+ switch (curve.curveCollectionType) {
444
+ case "path":
445
+ case "loop":
446
+ return true;
447
+ default:
448
+ return false;
449
+ }
450
+ }
451
+ doBreakCurve(ev) {
452
+ var _a;
453
+ this.resultA = this.resultB = undefined;
454
+ if (undefined === ev.viewport)
455
+ return;
456
+ const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
457
+ if (undefined === geom)
458
+ return;
459
+ const closeDetail = (geom instanceof core_geometry_1.CurvePrimitive) ? geom.closestPoint(ev.point, false) : geom.closestPoint(ev.point);
460
+ if (undefined === (closeDetail === null || closeDetail === void 0 ? void 0 : closeDetail.curve))
461
+ return;
462
+ const selectedStart = (closeDetail.fraction <= core_geometry_1.Geometry.smallFraction);
463
+ const selectedEnd = (closeDetail.fraction >= (1.0 - core_geometry_1.Geometry.smallFraction));
464
+ if (geom instanceof core_geometry_1.CurvePrimitive) {
465
+ if (selectedStart || selectedEnd)
466
+ return; // split is no-op...
467
+ this.resultA = geom.clonePartialCurve(0.0, closeDetail.fraction);
468
+ this.resultB = geom.clonePartialCurve(closeDetail.fraction, 1.0);
469
+ return;
470
+ }
471
+ else if (geom instanceof core_geometry_1.Path) {
472
+ const firstCurve = geom.children[0];
473
+ const lastCurve = geom.children[geom.children.length - 1];
474
+ if ((closeDetail.curve === firstCurve && selectedStart) || (closeDetail.curve === lastCurve && selectedEnd))
475
+ return; // split is no-op...
476
+ let beforeCurve = true;
477
+ const resultA = core_geometry_1.Path.create();
478
+ const resultB = core_geometry_1.Path.create();
479
+ for (const curve of geom.children) {
480
+ if (curve === closeDetail.curve) {
481
+ if (selectedStart) {
482
+ resultB.children.push(curve.clone());
483
+ }
484
+ else if (selectedEnd) {
485
+ resultA.children.push(curve.clone());
486
+ }
487
+ else {
488
+ const curveA = curve.clonePartialCurve(0.0, closeDetail.fraction);
489
+ if (undefined !== curveA)
490
+ resultA.children.push(curveA);
491
+ const curveB = curve.clonePartialCurve(closeDetail.fraction, 1.0);
492
+ if (undefined !== curveB)
493
+ resultB.children.push(curveB);
494
+ }
495
+ beforeCurve = false;
496
+ }
497
+ else {
498
+ if (beforeCurve)
499
+ resultA.children.push(curve.clone());
500
+ else
501
+ resultB.children.push(curve.clone());
502
+ }
503
+ }
504
+ this.resultA = resultA;
505
+ this.resultB = resultB;
506
+ }
507
+ else if (geom instanceof core_geometry_1.Loop) {
508
+ const closeIndex = geom.children.findIndex((child) => child === closeDetail.curve);
509
+ if (-1 === closeIndex)
510
+ return;
511
+ const endIndex = closeIndex + geom.children.length;
512
+ const resultA = core_geometry_1.Path.create(); // Result is always a single path...
513
+ if (selectedStart) {
514
+ resultA.children.push(closeDetail.curve.clone());
515
+ }
516
+ else if (!selectedEnd) {
517
+ const curveB = closeDetail.curve.clonePartialCurve(closeDetail.fraction, 1.0);
518
+ if (undefined !== curveB)
519
+ resultA.children.push(curveB);
520
+ }
521
+ for (let index = closeIndex; index < endIndex; ++index) {
522
+ const curve = geom.cyclicCurvePrimitive(index);
523
+ if (undefined === curve || curve === closeDetail.curve)
524
+ continue;
525
+ resultA.children.push(curve.clone());
526
+ }
527
+ if (selectedEnd) {
528
+ resultA.children.push(closeDetail.curve.clone());
529
+ }
530
+ else if (!selectedStart) {
531
+ const curveA = closeDetail.curve.clonePartialCurve(0.0, closeDetail.fraction);
532
+ if (undefined !== curveA)
533
+ resultA.children.push(curveA);
534
+ }
535
+ this.resultA = resultA;
536
+ }
537
+ }
538
+ modifyCurve(_ev, _isAccept) {
539
+ return (this.wantModifyOriginal ? this.resultA : this.resultB);
540
+ }
541
+ async processAgenda(ev) {
542
+ this.doBreakCurve(ev);
543
+ if (undefined === this.resultA || !await this.applyAgendaOperation(ev))
544
+ return;
545
+ if (undefined !== this.resultB) {
546
+ this.modifyOriginal = false;
547
+ await this.applyAgendaOperation(ev);
548
+ }
549
+ return this.saveChanges();
550
+ }
551
+ provideToolAssistance(_mainInstrText, _additionalInstr) {
552
+ let mainMsg;
553
+ if (this.agenda.isEmpty)
554
+ mainMsg = EditTool_1.EditTools.translate("BreakCurve.Prompts.IdentifyBreak");
555
+ super.provideToolAssistance(mainMsg);
556
+ }
557
+ async onRestartTool() {
558
+ const tool = new BreakCurveTool();
559
+ if (!await tool.run())
560
+ return this.exitTool();
561
+ }
562
+ }
563
+ exports.BreakCurveTool = BreakCurveTool;
564
+ BreakCurveTool.toolId = "BreakCurve";
565
+ BreakCurveTool.iconSpec = "icon-scale"; // Need better icon...
566
+ /** @alpha Tool for extending/shortening curves. */
567
+ class ExtendCurveTool extends ModifyCurveTool {
568
+ get wantAccuSnap() { return true; }
569
+ get wantDynamics() { return true; }
570
+ get wantAgendaAppearanceOverride() { return true; }
571
+ acceptCurve(curve) {
572
+ if ("curvePrimitive" !== curve.geometryCategory)
573
+ return false;
574
+ return curve.isExtensibleFractionSpace;
575
+ }
576
+ modifyCurve(ev, _isAccept) {
577
+ var _a;
578
+ if (undefined === ev.viewport || undefined === this.anchorPoint)
579
+ return undefined;
580
+ const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
581
+ if (undefined === geom)
582
+ return undefined;
583
+ const matrix = core_frontend_1.AccuDrawHintBuilder.getCurrentRotation(ev.viewport, true, true);
584
+ const localToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(matrix === null || matrix === void 0 ? void 0 : matrix.getColumn(2), geom);
585
+ if (undefined === localToWorld)
586
+ return undefined;
587
+ const worldToLocal = localToWorld.inverse();
588
+ if (undefined === worldToLocal)
589
+ return undefined;
590
+ const spacePoint = core_frontend_1.AccuDrawHintBuilder.projectPointToPlaneInView(ev.point, localToWorld.getOrigin(), localToWorld.matrix.getColumn(2), ev.viewport);
591
+ if (undefined === spacePoint)
592
+ return undefined;
593
+ const pickDetail = geom.closestPoint(this.anchorPoint, false);
594
+ if (undefined === (pickDetail === null || pickDetail === void 0 ? void 0 : pickDetail.curve))
595
+ return undefined;
596
+ const closeDetail = geom.closestPoint(spacePoint, true);
597
+ if (undefined === (closeDetail === null || closeDetail === void 0 ? void 0 : closeDetail.curve))
598
+ return undefined;
599
+ if (closeDetail.curve instanceof core_geometry_1.Arc3d) {
600
+ if (pickDetail.fraction > 0.5 && closeDetail.fraction < 0.0) {
601
+ const smallArc = closeDetail.curve.clonePartialCurve(closeDetail.fraction, 0.0);
602
+ smallArc.sweep.cloneComplement(false, smallArc.sweep);
603
+ return smallArc;
604
+ }
605
+ else if (pickDetail.fraction <= 0.5 && closeDetail.fraction > 1.0) {
606
+ const smallArc = closeDetail.curve.clonePartialCurve(1.0, closeDetail.fraction);
607
+ smallArc.sweep.cloneComplement(false, smallArc.sweep);
608
+ return smallArc;
609
+ }
610
+ else if (Math.abs(pickDetail.fraction > 0.5 ? closeDetail.fraction : 1.0 - closeDetail.fraction) < core_geometry_1.Geometry.smallFraction) {
611
+ const fullArc = closeDetail.curve.clone();
612
+ fullArc.sweep = core_geometry_1.AngleSweep.create360();
613
+ return fullArc;
614
+ }
615
+ }
616
+ return closeDetail.curve.clonePartialCurve(pickDetail.fraction > 0.5 ? 0.0 : 1.0, closeDetail.fraction);
617
+ }
618
+ setupAccuDraw() {
619
+ var _a;
620
+ const hints = new core_frontend_1.AccuDrawHintBuilder();
621
+ if (this.agenda.isEmpty) {
622
+ hints.enableSmartRotation = true;
623
+ }
624
+ else {
625
+ const geom = (_a = this.curveData) === null || _a === void 0 ? void 0 : _a.geom;
626
+ if (undefined === geom || "curvePrimitive" !== geom.geometryCategory)
627
+ return;
628
+ if (geom instanceof core_geometry_1.Arc3d) {
629
+ const matrix = geom.matrixClone();
630
+ matrix.normalizeColumnsInPlace();
631
+ hints.setOrigin(geom.center);
632
+ hints.setMatrix(matrix);
633
+ hints.setModePolar();
634
+ }
635
+ else if (geom instanceof core_geometry_1.LineSegment3d) {
636
+ const pickDetail = (undefined !== this.anchorPoint ? geom.closestPoint(this.anchorPoint, false) : undefined);
637
+ if (undefined !== (pickDetail === null || pickDetail === void 0 ? void 0 : pickDetail.curve)) {
638
+ hints.setOrigin(pickDetail.fraction > 0.5 ? geom.point0Ref : geom.point1Ref);
639
+ hints.setXAxis(core_geometry_1.Vector3d.createStartEnd(pickDetail.fraction > 0.5 ? geom.point0Ref : geom.point1Ref, pickDetail.fraction > 0.5 ? geom.point1Ref : geom.point0Ref));
640
+ }
641
+ hints.setModeRectangular();
642
+ }
643
+ else if (geom instanceof core_geometry_1.LineString3d) {
644
+ const pickDetail = (undefined !== this.anchorPoint ? geom.closestPoint(this.anchorPoint, false) : undefined);
645
+ if (undefined !== (pickDetail === null || pickDetail === void 0 ? void 0 : pickDetail.curve) && geom.numPoints() > 1) {
646
+ hints.setOrigin(geom.packedPoints.getPoint3dAtUncheckedPointIndex(pickDetail.fraction > 0.5 ? geom.numPoints() - 2 : 1));
647
+ hints.setXAxis(core_geometry_1.Vector3d.createStartEnd(geom.packedPoints.getPoint3dAtUncheckedPointIndex(pickDetail.fraction > 0.5 ? geom.numPoints() - 2 : 1), geom.packedPoints.getPoint3dAtUncheckedPointIndex(pickDetail.fraction > 0.5 ? geom.numPoints() - 1 : 0)));
648
+ }
649
+ hints.setModeRectangular();
650
+ }
651
+ }
652
+ hints.sendHints(false);
653
+ }
654
+ provideToolAssistance(_mainInstrText, _additionalInstr) {
655
+ let mainMsg;
656
+ if (this.agenda.isEmpty)
657
+ mainMsg = EditTool_1.EditTools.translate("ExtendCurve.Prompts.IdentifyEnd");
658
+ super.provideToolAssistance(mainMsg);
659
+ }
660
+ async onRestartTool() {
661
+ const tool = new ExtendCurveTool();
662
+ if (!await tool.run())
663
+ return this.exitTool();
664
+ }
665
+ }
666
+ exports.ExtendCurveTool = ExtendCurveTool;
667
+ ExtendCurveTool.toolId = "ExtendCurve";
668
+ ExtendCurveTool.iconSpec = "icon-scale"; // Need better icon...
669
669
  //# sourceMappingURL=ModifyCurveTools.js.map