@itwin/editor-frontend 4.5.0-dev.9 → 4.6.0-dev.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.
Files changed (101) hide show
  1. package/CHANGELOG.md +46 -1
  2. package/LICENSE.md +1 -1
  3. package/README.md +0 -29
  4. package/lib/cjs/CreateElementTool.d.ts +64 -2
  5. package/lib/cjs/CreateElementTool.d.ts.map +1 -1
  6. package/lib/cjs/CreateElementTool.js +65 -4
  7. package/lib/cjs/CreateElementTool.js.map +1 -1
  8. package/lib/cjs/EditTool.d.ts +5 -0
  9. package/lib/cjs/EditTool.d.ts.map +1 -1
  10. package/lib/cjs/EditTool.js +10 -14
  11. package/lib/cjs/EditTool.js.map +1 -1
  12. package/lib/cjs/EditToolIpc.d.ts +1 -5
  13. package/lib/cjs/EditToolIpc.d.ts.map +1 -1
  14. package/lib/cjs/EditToolIpc.js +1 -5
  15. package/lib/cjs/EditToolIpc.js.map +1 -1
  16. package/lib/cjs/ModifyElementTool.js.map +1 -1
  17. package/lib/cjs/ProjectLocation/ProjectExtentsDecoration.js.map +1 -1
  18. package/lib/cjs/ProjectLocation/ProjectGeolocation.js.map +1 -1
  19. package/lib/cjs/TransformElementsTool.d.ts +17 -98
  20. package/lib/cjs/TransformElementsTool.d.ts.map +1 -1
  21. package/lib/cjs/TransformElementsTool.js +15 -412
  22. package/lib/cjs/TransformElementsTool.js.map +1 -1
  23. package/lib/cjs/UndoRedoTool.js.map +1 -1
  24. package/lib/cjs/editor-frontend.d.ts +0 -6
  25. package/lib/cjs/editor-frontend.d.ts.map +1 -1
  26. package/lib/cjs/editor-frontend.js +0 -6
  27. package/lib/cjs/editor-frontend.js.map +1 -1
  28. package/lib/esm/CreateElementTool.d.ts +64 -2
  29. package/lib/esm/CreateElementTool.d.ts.map +1 -1
  30. package/lib/esm/CreateElementTool.js +65 -4
  31. package/lib/esm/CreateElementTool.js.map +1 -1
  32. package/lib/esm/EditTool.d.ts +5 -0
  33. package/lib/esm/EditTool.d.ts.map +1 -1
  34. package/lib/esm/EditTool.js +10 -14
  35. package/lib/esm/EditTool.js.map +1 -1
  36. package/lib/esm/EditToolIpc.d.ts +1 -5
  37. package/lib/esm/EditToolIpc.d.ts.map +1 -1
  38. package/lib/esm/EditToolIpc.js +0 -4
  39. package/lib/esm/EditToolIpc.js.map +1 -1
  40. package/lib/esm/ModifyElementTool.js.map +1 -1
  41. package/lib/esm/ProjectLocation/ProjectExtentsDecoration.js.map +1 -1
  42. package/lib/esm/ProjectLocation/ProjectGeolocation.js.map +1 -1
  43. package/lib/esm/TransformElementsTool.d.ts +17 -98
  44. package/lib/esm/TransformElementsTool.d.ts.map +1 -1
  45. package/lib/esm/TransformElementsTool.js +16 -413
  46. package/lib/esm/TransformElementsTool.js.map +1 -1
  47. package/lib/esm/UndoRedoTool.js.map +1 -1
  48. package/lib/esm/editor-frontend.d.ts +0 -6
  49. package/lib/esm/editor-frontend.d.ts.map +1 -1
  50. package/lib/esm/editor-frontend.js +0 -6
  51. package/lib/esm/editor-frontend.js.map +1 -1
  52. package/lib/public/locales/en/Editor.json +79 -490
  53. package/package.json +14 -14
  54. package/lib/cjs/DeleteElementsTool.d.ts +0 -14
  55. package/lib/cjs/DeleteElementsTool.d.ts.map +0 -1
  56. package/lib/cjs/DeleteElementsTool.js +0 -42
  57. package/lib/cjs/DeleteElementsTool.js.map +0 -1
  58. package/lib/cjs/ElementGeometryTool.d.ts +0 -148
  59. package/lib/cjs/ElementGeometryTool.d.ts.map +0 -1
  60. package/lib/cjs/ElementGeometryTool.js +0 -705
  61. package/lib/cjs/ElementGeometryTool.js.map +0 -1
  62. package/lib/cjs/ModifyCurveTools.d.ts +0 -140
  63. package/lib/cjs/ModifyCurveTools.d.ts.map +0 -1
  64. package/lib/cjs/ModifyCurveTools.js +0 -777
  65. package/lib/cjs/ModifyCurveTools.js.map +0 -1
  66. package/lib/cjs/SketchTools.d.ts +0 -308
  67. package/lib/cjs/SketchTools.d.ts.map +0 -1
  68. package/lib/cjs/SketchTools.js +0 -1708
  69. package/lib/cjs/SketchTools.js.map +0 -1
  70. package/lib/cjs/SolidModelingTools.d.ts +0 -381
  71. package/lib/cjs/SolidModelingTools.d.ts.map +0 -1
  72. package/lib/cjs/SolidModelingTools.js +0 -1453
  73. package/lib/cjs/SolidModelingTools.js.map +0 -1
  74. package/lib/cjs/SolidPrimitiveTools.d.ts +0 -322
  75. package/lib/cjs/SolidPrimitiveTools.d.ts.map +0 -1
  76. package/lib/cjs/SolidPrimitiveTools.js +0 -1376
  77. package/lib/cjs/SolidPrimitiveTools.js.map +0 -1
  78. package/lib/esm/DeleteElementsTool.d.ts +0 -14
  79. package/lib/esm/DeleteElementsTool.d.ts.map +0 -1
  80. package/lib/esm/DeleteElementsTool.js +0 -39
  81. package/lib/esm/DeleteElementsTool.js.map +0 -1
  82. package/lib/esm/ElementGeometryTool.d.ts +0 -148
  83. package/lib/esm/ElementGeometryTool.d.ts.map +0 -1
  84. package/lib/esm/ElementGeometryTool.js +0 -697
  85. package/lib/esm/ElementGeometryTool.js.map +0 -1
  86. package/lib/esm/ModifyCurveTools.d.ts +0 -140
  87. package/lib/esm/ModifyCurveTools.d.ts.map +0 -1
  88. package/lib/esm/ModifyCurveTools.js +0 -772
  89. package/lib/esm/ModifyCurveTools.js.map +0 -1
  90. package/lib/esm/SketchTools.d.ts +0 -308
  91. package/lib/esm/SketchTools.d.ts.map +0 -1
  92. package/lib/esm/SketchTools.js +0 -1704
  93. package/lib/esm/SketchTools.js.map +0 -1
  94. package/lib/esm/SolidModelingTools.d.ts +0 -381
  95. package/lib/esm/SolidModelingTools.d.ts.map +0 -1
  96. package/lib/esm/SolidModelingTools.js +0 -1445
  97. package/lib/esm/SolidModelingTools.js.map +0 -1
  98. package/lib/esm/SolidPrimitiveTools.d.ts +0 -322
  99. package/lib/esm/SolidPrimitiveTools.d.ts.map +0 -1
  100. package/lib/esm/SolidPrimitiveTools.js +0 -1372
  101. package/lib/esm/SolidPrimitiveTools.js.map +0 -1
@@ -1,777 +0,0 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.RegionBooleanTool = exports.RegionBooleanMode = exports.ExtendCurveTool = exports.BreakCurveTool = exports.OffsetCurveTool = exports.ModifyCurveTool = exports.CurveData = void 0;
8
- const appui_abstract_1 = require("@itwin/appui-abstract");
9
- const core_bentley_1 = require("@itwin/core-bentley");
10
- const core_common_1 = require("@itwin/core-common");
11
- const core_frontend_1 = require("@itwin/core-frontend");
12
- const core_geometry_1 = require("@itwin/core-geometry");
13
- const editor_common_1 = require("@itwin/editor-common");
14
- const EditTool_1 = require("./EditTool");
15
- const EditToolIpc_1 = require("./EditToolIpc");
16
- const ModifyElementTool_1 = require("./ModifyElementTool");
17
- /** @alpha */
18
- class CurveData {
19
- constructor(props, params, geom) {
20
- this.props = props;
21
- this.params = params;
22
- this.geom = geom;
23
- }
24
- }
25
- exports.CurveData = CurveData;
26
- /** @alpha Base class for modifying all types of curve geometry. */
27
- class ModifyCurveTool extends ModifyElementTool_1.ModifyElementWithDynamicsTool {
28
- async startCommand() {
29
- if (undefined !== this._startedCmd)
30
- return this._startedCmd;
31
- return EditTool_1.EditTools.startCommand({ commandId: editor_common_1.editorBuiltInCmdIds.cmdBasicManipulation, iModelKey: this.iModel.key });
32
- }
33
- static isSingleCurve(info) {
34
- const it = new core_common_1.ElementGeometry.Iterator(info);
35
- it.requestWorldCoordinates();
36
- for (const entry of it) {
37
- const geom = entry.toGeometryQuery();
38
- if (undefined === geom)
39
- return;
40
- if ("curvePrimitive" === geom.geometryCategory) {
41
- return { curve: geom, params: entry.geomParams };
42
- }
43
- else if ("curveCollection" === geom.geometryCategory) {
44
- return { curve: geom, params: entry.geomParams };
45
- }
46
- break;
47
- }
48
- return;
49
- }
50
- static isInPlane(curve, plane) {
51
- if ("curvePrimitive" === curve.geometryCategory)
52
- return curve.isInPlane(plane);
53
- if (!curve.children)
54
- return false;
55
- for (const child of curve.children) {
56
- if (child instanceof core_geometry_1.CurvePrimitive) {
57
- if (!child.isInPlane(plane))
58
- return false;
59
- }
60
- else if (child instanceof core_geometry_1.CurveCollection) {
61
- if (!this.isInPlane(child, plane))
62
- return false;
63
- }
64
- }
65
- return true;
66
- }
67
- acceptCurve(_curve) { return true; }
68
- modifyCurve(_ev, _isAccept) { return undefined; }
69
- async getCurveData(id) {
70
- try {
71
- this._startedCmd = await this.startCommand();
72
- const reject = [core_common_1.ElementGeometryOpcode.Polyface, core_common_1.ElementGeometryOpcode.SolidPrimitive, core_common_1.ElementGeometryOpcode.BsplineSurface, core_common_1.ElementGeometryOpcode.BRep];
73
- const info = await EditToolIpc_1.basicManipulationIpc.requestElementGeometry(id, { maxDisplayable: 1, reject, geometry: { curves: true, surfaces: true, solids: false } });
74
- if (undefined === info)
75
- return undefined;
76
- const data = ModifyCurveTool.isSingleCurve(info);
77
- if (undefined === data)
78
- return undefined;
79
- if (!this.acceptCurve(data.curve))
80
- return undefined;
81
- const props = await this.iModel.elements.loadProps(id);
82
- if (undefined === props)
83
- return undefined;
84
- return new CurveData(props, data.params, data.curve);
85
- }
86
- catch (err) {
87
- core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, core_common_1.BentleyError.getErrorMessage(err)));
88
- return undefined;
89
- }
90
- }
91
- async doAcceptElementForOperation(id) {
92
- return (undefined !== await this.getCurveData(id));
93
- }
94
- async onAgendaModified() {
95
- this.curveData = undefined;
96
- if (this.agenda.isEmpty)
97
- return;
98
- const id = this.agenda.elements[this.agenda.length - 1];
99
- this.curveData = await this.getCurveData(id);
100
- }
101
- setupAccuDraw() {
102
- const hints = new core_frontend_1.AccuDrawHintBuilder();
103
- hints.enableSmartRotation = true;
104
- hints.sendHints(false);
105
- }
106
- getGeometryProps(ev, isAccept) {
107
- if (undefined === this.curveData)
108
- return;
109
- const geom = this.modifyCurve(ev, isAccept);
110
- if (undefined === geom)
111
- return;
112
- const builder = new core_common_1.ElementGeometry.Builder();
113
- builder.setLocalToWorldFromPlacement(this.curveData.props.placement);
114
- if (!builder.appendGeometryParamsChange(this.curveData.params))
115
- return;
116
- if (!builder.appendGeometryQuery(geom))
117
- return;
118
- return { format: "flatbuffer", data: builder.entries };
119
- }
120
- getElementProps(ev) {
121
- if (undefined === this.curveData)
122
- return;
123
- if (!this.wantModifyOriginal) {
124
- // Create result as new element with same model and category as original...
125
- const classFullName = (ev.viewport?.view.is3d() ? "Generic:PhysicalObject" : "BisCore:DrawingGraphic");
126
- return { classFullName, model: this.curveData.props.model, category: this.curveData.props.category, code: core_common_1.Code.createEmpty(), placement: this.curveData.props.placement };
127
- }
128
- return this.curveData.props;
129
- }
130
- async doUpdateElement(elemProps) {
131
- try {
132
- this._startedCmd = await this.startCommand();
133
- if (undefined === elemProps.id) {
134
- const repeatOperation = this.wantContinueWithPreviousResult;
135
- if (repeatOperation)
136
- this.agenda.clear();
137
- const newId = await EditToolIpc_1.basicManipulationIpc.insertGeometricElement(elemProps);
138
- if (repeatOperation && this.agenda.add(newId))
139
- await this.onAgendaModified();
140
- }
141
- else {
142
- await EditToolIpc_1.basicManipulationIpc.updateGeometricElement(elemProps);
143
- }
144
- return true;
145
- }
146
- catch (err) {
147
- 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."));
148
- return false;
149
- }
150
- }
151
- get wantModifyOriginal() { return true; }
152
- get wantContinueWithPreviousResult() { return false; }
153
- async onProcessComplete() {
154
- // Don't restart tool want to continue operation using previous result...
155
- if (this.wantContinueWithPreviousResult && !this.agenda.isEmpty && undefined !== this.curveData)
156
- return;
157
- return super.onProcessComplete();
158
- }
159
- }
160
- exports.ModifyCurveTool = ModifyCurveTool;
161
- /** @alpha Tool for applying an offset to paths and loops. */
162
- class OffsetCurveTool extends ModifyCurveTool {
163
- get useDistanceProperty() {
164
- if (!this._useDistanceProperty)
165
- this._useDistanceProperty = new appui_abstract_1.DialogProperty(appui_abstract_1.PropertyDescriptionHelper.buildLockPropertyDescription("useOffsetDistance"), false);
166
- return this._useDistanceProperty;
167
- }
168
- get useDistance() { return this.useDistanceProperty.value; }
169
- set useDistance(value) { this.useDistanceProperty.value = value; }
170
- get distanceProperty() {
171
- if (!this._distanceProperty)
172
- 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);
173
- return this._distanceProperty;
174
- }
175
- get distance() { return this.distanceProperty.value; }
176
- set distance(value) { this.distanceProperty.value = value; }
177
- get makeCopyProperty() {
178
- if (!this._makeCopyProperty)
179
- this._makeCopyProperty = new appui_abstract_1.DialogProperty(appui_abstract_1.PropertyDescriptionHelper.buildToggleDescription("offsetCopy", EditTool_1.EditTools.translate("OffsetCurve.Label.MakeCopy")), false);
180
- return this._makeCopyProperty;
181
- }
182
- get makeCopy() { return this.makeCopyProperty.value; }
183
- set makeCopy(value) { this.makeCopyProperty.value = value; }
184
- getToolSettingPropertyLocked(property) {
185
- return (property === this.useDistanceProperty ? this.distanceProperty : undefined);
186
- }
187
- async applyToolSettingPropertyChange(updatedValue) {
188
- return this.changeToolSettingPropertyValue(updatedValue);
189
- }
190
- supplyToolSettingsProperties() {
191
- this.initializeToolSettingPropertyValues([this.makeCopyProperty, this.useDistanceProperty, this.distanceProperty]);
192
- const toolSettings = new Array();
193
- // ensure controls are enabled/disabled based on current lock property state
194
- this.distanceProperty.isDisabled = !this.useDistance;
195
- const useDistanceLock = this.useDistanceProperty.toDialogItem({ rowPriority: 1, columnIndex: 0 });
196
- toolSettings.push(this.distanceProperty.toDialogItem({ rowPriority: 1, columnIndex: 1 }, useDistanceLock));
197
- toolSettings.push(this.makeCopyProperty.toDialogItem({ rowPriority: 2, columnIndex: 0 }));
198
- return toolSettings;
199
- }
200
- acceptCurve(curve) {
201
- if ("curvePrimitive" === curve.geometryCategory)
202
- return true;
203
- return (curve.isOpenPath || curve.isClosedPath);
204
- }
205
- modifyCurve(ev, isAccept) {
206
- if (undefined === ev.viewport)
207
- return undefined;
208
- const geom = this.curveData?.geom;
209
- if (undefined === geom)
210
- return undefined;
211
- const matrix = core_frontend_1.AccuDrawHintBuilder.getCurrentRotation(ev.viewport, true, true);
212
- const localToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(matrix?.getColumn(2), geom);
213
- if (undefined === localToWorld)
214
- return undefined;
215
- const worldToLocal = localToWorld.inverse();
216
- if (undefined === worldToLocal)
217
- return undefined;
218
- const geomXY = ((geom instanceof core_geometry_1.CurvePrimitive) ? core_geometry_1.Path.create(geom) : geom).cloneTransformed(worldToLocal);
219
- if (undefined === geomXY)
220
- return undefined;
221
- const spacePoint = core_frontend_1.AccuDrawHintBuilder.projectPointToPlaneInView(ev.point, localToWorld.getOrigin(), localToWorld.matrix.getColumn(2), ev.viewport);
222
- if (undefined === spacePoint)
223
- return undefined;
224
- worldToLocal.multiplyPoint3d(spacePoint, spacePoint);
225
- spacePoint.z = 0.0;
226
- const closeDetail = geomXY.closestPoint(spacePoint);
227
- if (undefined === closeDetail?.curve)
228
- return undefined;
229
- const unitZ = core_geometry_1.Vector3d.unitZ();
230
- const unitX = closeDetail.curve.fractionToPointAndUnitTangent(closeDetail.fraction).direction;
231
- const unitY = unitZ.unitCrossProduct(unitX);
232
- if (undefined === unitY)
233
- return undefined;
234
- let distance = closeDetail.point.distance(spacePoint);
235
- const refDir = core_geometry_1.Vector3d.createStartEnd(closeDetail.point, spacePoint);
236
- if (refDir.dotProduct(unitY) < 0.0)
237
- distance = -distance;
238
- let offset = 0.0;
239
- if (this.useDistance) {
240
- offset = this.distance;
241
- if ((offset < 0.0 && distance > 0.0) || (offset > 0.0 && distance < 0.0))
242
- offset = -offset;
243
- }
244
- else {
245
- offset = distance;
246
- }
247
- if (Math.abs(offset) < core_geometry_1.Geometry.smallMetricDistance)
248
- return undefined;
249
- if (offset !== this.distance) {
250
- this.distance = offset;
251
- this.syncToolSettingPropertyValue(this.distanceProperty);
252
- if (isAccept)
253
- this.saveToolSettingPropertyValue(this.distanceProperty, this.distanceProperty.dialogItemValue);
254
- }
255
- const jointOptions = new core_geometry_1.JointOptions(offset);
256
- jointOptions.preserveEllipticalArcs = true;
257
- const offsetGeom = core_geometry_1.RegionOps.constructCurveXYOffset(geomXY, jointOptions);
258
- if (undefined === offsetGeom)
259
- return undefined;
260
- if (!offsetGeom.tryTransformInPlace(localToWorld))
261
- return undefined;
262
- if (geom instanceof core_geometry_1.CurvePrimitive && offsetGeom instanceof core_geometry_1.Path && 1 === offsetGeom.children.length)
263
- return offsetGeom.getChild(0); // Don't create path for offset of single open curve...
264
- return offsetGeom;
265
- }
266
- get wantModifyOriginal() {
267
- return !this.makeCopy;
268
- }
269
- get wantContinueWithPreviousResult() {
270
- return !this.wantModifyOriginal;
271
- }
272
- setupAccuDraw() {
273
- const hints = new core_frontend_1.AccuDrawHintBuilder();
274
- if (this.agenda.isEmpty) {
275
- hints.enableSmartRotation = true;
276
- }
277
- else if (undefined !== this.anchorPoint && undefined !== this.targetView) {
278
- const geom = this.curveData?.geom;
279
- const closeDetail = (geom instanceof core_geometry_1.CurvePrimitive) ? geom.closestPoint(this.anchorPoint, false) : geom?.closestPoint(this.anchorPoint);
280
- if (undefined !== closeDetail?.curve) {
281
- const unitX = closeDetail.curve.fractionToPointAndUnitTangent(closeDetail.fraction).direction;
282
- if (undefined !== unitX) {
283
- const matrix = core_frontend_1.AccuDrawHintBuilder.getCurrentRotation(this.targetView, true, true);
284
- const localToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(matrix?.getColumn(2), geom);
285
- if (undefined !== localToWorld) {
286
- const unitZ = localToWorld.matrix.getColumn(2);
287
- const frame = core_geometry_1.Matrix3d.createRigidFromColumns(unitX, unitZ, core_geometry_1.AxisOrder.XZY);
288
- if (undefined !== frame) {
289
- hints.setOrigin(closeDetail.point);
290
- hints.setMatrix(frame);
291
- }
292
- }
293
- }
294
- }
295
- }
296
- hints.sendHints(false);
297
- }
298
- provideToolAssistance(_mainInstrText, _additionalInstr) {
299
- let mainMsg;
300
- if (!this.agenda.isEmpty)
301
- mainMsg = EditTool_1.EditTools.translate("OffsetCurve.Prompts.DefineOffset");
302
- super.provideToolAssistance(mainMsg);
303
- }
304
- async onRestartTool() {
305
- const tool = new OffsetCurveTool();
306
- if (!await tool.run())
307
- return this.exitTool();
308
- }
309
- }
310
- OffsetCurveTool.toolId = "OffsetCurve";
311
- OffsetCurveTool.iconSpec = "icon-scale"; // Need better icon...
312
- exports.OffsetCurveTool = OffsetCurveTool;
313
- /** @alpha Tool for opening loops and splitting paths. */
314
- class BreakCurveTool extends ModifyCurveTool {
315
- constructor() {
316
- super(...arguments);
317
- this.modifyOriginal = true;
318
- }
319
- get wantDynamics() { return false; }
320
- get wantModifyOriginal() { return this.modifyOriginal; }
321
- acceptCurve(curve) {
322
- if ("curvePrimitive" === curve.geometryCategory)
323
- return true;
324
- return (curve.isOpenPath || curve.isClosedPath);
325
- }
326
- doBreakCurve(ev) {
327
- this.resultA = this.resultB = undefined;
328
- if (undefined === ev.viewport)
329
- return;
330
- const geom = this.curveData?.geom;
331
- if (undefined === geom)
332
- return;
333
- const closeDetail = (geom instanceof core_geometry_1.CurvePrimitive) ? geom.closestPoint(ev.point, false) : geom.closestPoint(ev.point);
334
- if (undefined === closeDetail?.curve)
335
- return;
336
- const selectedStart = (closeDetail.fraction <= core_geometry_1.Geometry.smallFraction);
337
- const selectedEnd = (closeDetail.fraction >= (1.0 - core_geometry_1.Geometry.smallFraction));
338
- if (geom instanceof core_geometry_1.CurvePrimitive) {
339
- if (selectedStart || selectedEnd)
340
- return; // split is no-op...
341
- this.resultA = geom.clonePartialCurve(0.0, closeDetail.fraction);
342
- this.resultB = geom.clonePartialCurve(closeDetail.fraction, 1.0);
343
- return;
344
- }
345
- else if (geom instanceof core_geometry_1.Path) {
346
- const firstCurve = geom.children[0];
347
- const lastCurve = geom.children[geom.children.length - 1];
348
- if ((closeDetail.curve === firstCurve && selectedStart) || (closeDetail.curve === lastCurve && selectedEnd))
349
- return; // split is no-op...
350
- let beforeCurve = true;
351
- const resultA = core_geometry_1.Path.create();
352
- const resultB = core_geometry_1.Path.create();
353
- for (const curve of geom.children) {
354
- if (curve === closeDetail.curve) {
355
- if (selectedStart) {
356
- resultB.children.push(curve.clone());
357
- }
358
- else if (selectedEnd) {
359
- resultA.children.push(curve.clone());
360
- }
361
- else {
362
- const curveA = curve.clonePartialCurve(0.0, closeDetail.fraction);
363
- if (undefined !== curveA)
364
- resultA.children.push(curveA);
365
- const curveB = curve.clonePartialCurve(closeDetail.fraction, 1.0);
366
- if (undefined !== curveB)
367
- resultB.children.push(curveB);
368
- }
369
- beforeCurve = false;
370
- }
371
- else {
372
- if (beforeCurve)
373
- resultA.children.push(curve.clone());
374
- else
375
- resultB.children.push(curve.clone());
376
- }
377
- }
378
- this.resultA = resultA;
379
- this.resultB = resultB;
380
- }
381
- else if (geom instanceof core_geometry_1.Loop) {
382
- const closeIndex = geom.children.findIndex((child) => child === closeDetail.curve);
383
- if (-1 === closeIndex)
384
- return;
385
- const endIndex = closeIndex + geom.children.length;
386
- const resultA = core_geometry_1.Path.create(); // Result is always a single path...
387
- if (selectedStart) {
388
- resultA.children.push(closeDetail.curve.clone());
389
- }
390
- else if (!selectedEnd) {
391
- const curveB = closeDetail.curve.clonePartialCurve(closeDetail.fraction, 1.0);
392
- if (undefined !== curveB)
393
- resultA.children.push(curveB);
394
- }
395
- for (let index = closeIndex; index < endIndex; ++index) {
396
- const curve = geom.cyclicCurvePrimitive(index);
397
- if (undefined === curve || curve === closeDetail.curve)
398
- continue;
399
- resultA.children.push(curve.clone());
400
- }
401
- if (selectedEnd) {
402
- resultA.children.push(closeDetail.curve.clone());
403
- }
404
- else if (!selectedStart) {
405
- const curveA = closeDetail.curve.clonePartialCurve(0.0, closeDetail.fraction);
406
- if (undefined !== curveA)
407
- resultA.children.push(curveA);
408
- }
409
- this.resultA = resultA;
410
- }
411
- }
412
- modifyCurve(_ev, _isAccept) {
413
- return (this.wantModifyOriginal ? this.resultA : this.resultB);
414
- }
415
- async processAgenda(ev) {
416
- this.doBreakCurve(ev);
417
- if (undefined === this.resultA || !await this.applyAgendaOperation(ev))
418
- return;
419
- if (undefined !== this.resultB) {
420
- this.modifyOriginal = false;
421
- await this.applyAgendaOperation(ev);
422
- }
423
- return this.saveChanges();
424
- }
425
- provideToolAssistance(_mainInstrText, _additionalInstr) {
426
- let mainMsg;
427
- if (this.agenda.isEmpty)
428
- mainMsg = EditTool_1.EditTools.translate("BreakCurve.Prompts.IdentifyBreak");
429
- super.provideToolAssistance(mainMsg);
430
- }
431
- async onRestartTool() {
432
- const tool = new BreakCurveTool();
433
- if (!await tool.run())
434
- return this.exitTool();
435
- }
436
- }
437
- BreakCurveTool.toolId = "BreakCurve";
438
- BreakCurveTool.iconSpec = "icon-scale"; // Need better icon...
439
- exports.BreakCurveTool = BreakCurveTool;
440
- /** @alpha Tool to extend or trim a path or open curve */
441
- class ExtendCurveTool extends ModifyCurveTool {
442
- get wantAgendaAppearanceOverride() { return true; }
443
- acceptCurve(curve) {
444
- if ("curvePrimitive" === curve.geometryCategory)
445
- return curve.isExtensibleFractionSpace;
446
- return curve.isOpenPath;
447
- }
448
- extendCurve(geom, pickPoint, spacePoint) {
449
- const pickDetail = geom.closestPoint(pickPoint, false);
450
- if (undefined === pickDetail?.curve)
451
- return undefined;
452
- const closeDetail = geom.closestPoint(spacePoint, true);
453
- if (undefined === closeDetail?.curve)
454
- return undefined;
455
- if (closeDetail.curve instanceof core_geometry_1.Arc3d) {
456
- if (pickDetail.fraction > 0.5 && closeDetail.fraction < 0.0) {
457
- const smallArc = closeDetail.curve.clonePartialCurve(closeDetail.fraction, 0.0);
458
- smallArc.sweep.cloneComplement(false, smallArc.sweep);
459
- return smallArc;
460
- }
461
- else if (pickDetail.fraction <= 0.5 && closeDetail.fraction > 1.0) {
462
- const smallArc = closeDetail.curve.clonePartialCurve(1.0, closeDetail.fraction);
463
- smallArc.sweep.cloneComplement(false, smallArc.sweep);
464
- return smallArc;
465
- }
466
- else if (Math.abs(pickDetail.fraction > 0.5 ? closeDetail.fraction : 1.0 - closeDetail.fraction) < core_geometry_1.Geometry.smallFraction) {
467
- const fullArc = closeDetail.curve.clone();
468
- fullArc.sweep = core_geometry_1.AngleSweep.create360();
469
- return fullArc;
470
- }
471
- }
472
- return geom.clonePartialCurve(pickDetail.fraction > 0.5 ? 0.0 : 1.0, closeDetail.fraction);
473
- }
474
- extendPathEnd(geom, closeDetail, isStart) {
475
- if (undefined === closeDetail.curve)
476
- return undefined;
477
- const curve = closeDetail.curve.clonePartialCurve(isStart ? closeDetail.fraction : 0.0, isStart ? 1.0 : closeDetail.fraction);
478
- if (undefined === curve)
479
- return undefined;
480
- if (curve instanceof core_geometry_1.Arc3d && closeDetail.curve instanceof core_geometry_1.Arc3d && (curve.sweep.isCCW !== closeDetail.curve.sweep.isCCW))
481
- curve.sweep.cloneComplement(true, curve.sweep); // Preserve current sweep direction...
482
- const result = geom.clone();
483
- result.children[isStart ? 0 : geom.children.length - 1] = curve;
484
- return result;
485
- }
486
- extendPath(geom, pickPoint, spacePoint) {
487
- if (geom.children.length < 2)
488
- return this.extendCurve(geom.children[0], pickPoint, spacePoint);
489
- const pathAsPrimitive = core_geometry_1.CurveChainWithDistanceIndex.createCapture(geom);
490
- const closeDetail = pathAsPrimitive.closestPoint(spacePoint, true);
491
- if (undefined === closeDetail?.curve || undefined === closeDetail.childDetail?.curve)
492
- return undefined;
493
- if (undefined !== this.modifyingEnd) {
494
- if (closeDetail.childDetail.curve === this.modifyingEnd) {
495
- this.modifyingEnd = undefined; // Ok to unlock extending first/last curve in path...
496
- }
497
- else {
498
- const pathEndDetail = this.modifyingEnd.closestPoint(spacePoint, true);
499
- if (undefined === pathEndDetail?.curve)
500
- return undefined;
501
- return this.extendPathEnd(geom, pathEndDetail, (pathEndDetail.curve === geom.children[0]));
502
- }
503
- }
504
- // NOTE: Special case extend instead of using CurveChainWithDistanceIndex.clonePartialCurve...
505
- if (closeDetail.fraction < 0.0) {
506
- this.modifyingEnd = closeDetail.childDetail.curve;
507
- return this.extendPathEnd(geom, closeDetail.childDetail, true);
508
- }
509
- else if (closeDetail.fraction > 1.0) {
510
- this.modifyingEnd = closeDetail.childDetail.curve;
511
- return this.extendPathEnd(geom, closeDetail.childDetail, false);
512
- }
513
- const pickDetail = pathAsPrimitive.closestPoint(pickPoint, false);
514
- if (undefined === pickDetail?.curve)
515
- return undefined;
516
- const result = pathAsPrimitive.clonePartialCurve(pickDetail.fraction > 0.5 ? 0.0 : 1.0, closeDetail.fraction);
517
- if (undefined === result)
518
- return undefined;
519
- return core_geometry_1.Path.create(...result.path.children);
520
- }
521
- modifyCurve(ev, _isAccept) {
522
- if (undefined === ev.viewport || undefined === this.anchorPoint)
523
- return undefined;
524
- const geom = this.curveData?.geom;
525
- if (undefined === geom)
526
- return undefined;
527
- const matrix = core_frontend_1.AccuDrawHintBuilder.getCurrentRotation(ev.viewport, true, true);
528
- const localToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(matrix?.getColumn(2), geom);
529
- if (undefined === localToWorld)
530
- return undefined;
531
- const worldToLocal = localToWorld.inverse();
532
- if (undefined === worldToLocal)
533
- return undefined;
534
- const spacePoint = core_frontend_1.AccuDrawHintBuilder.projectPointToPlaneInView(ev.point, localToWorld.getOrigin(), localToWorld.matrix.getColumn(2), ev.viewport);
535
- if (undefined === spacePoint)
536
- return undefined;
537
- if (geom instanceof core_geometry_1.CurvePrimitive)
538
- return this.extendCurve(geom, this.anchorPoint, spacePoint);
539
- else if (geom instanceof core_geometry_1.Path)
540
- return this.extendPath(geom, this.anchorPoint, spacePoint);
541
- return undefined;
542
- }
543
- async onAgendaModified() {
544
- core_frontend_1.IModelApp.accuSnap.neverFlash(this.agenda.elements); // Don't flash snapped segment for better preview when trimming curve/path...
545
- return super.onAgendaModified();
546
- }
547
- setupAccuDraw() {
548
- const hints = new core_frontend_1.AccuDrawHintBuilder();
549
- if (this.agenda.isEmpty) {
550
- hints.enableSmartRotation = true;
551
- }
552
- else {
553
- const geom = this.curveData?.geom;
554
- if (undefined === geom || undefined === this.anchorPoint)
555
- return;
556
- let pickDetail;
557
- if (geom instanceof core_geometry_1.CurvePrimitive)
558
- pickDetail = geom.closestPoint(this.anchorPoint, false);
559
- else if (geom instanceof core_geometry_1.Path)
560
- pickDetail = core_geometry_1.CurveChainWithDistanceIndex.createCapture(geom).closestPoint(this.anchorPoint, false);
561
- if (undefined === pickDetail?.curve)
562
- return;
563
- const curve = (undefined !== pickDetail.childDetail?.curve ? pickDetail.childDetail?.curve : pickDetail.curve);
564
- if (curve instanceof core_geometry_1.Arc3d) {
565
- const matrix = curve.matrixClone();
566
- matrix.normalizeColumnsInPlace();
567
- hints.setOrigin(curve.center);
568
- hints.setMatrix(matrix);
569
- hints.setModePolar();
570
- }
571
- else if (curve instanceof core_geometry_1.LineSegment3d) {
572
- hints.setOrigin(pickDetail.fraction > 0.5 ? curve.point0Ref : curve.point1Ref);
573
- hints.setXAxis(core_geometry_1.Vector3d.createStartEnd(pickDetail.fraction > 0.5 ? curve.point0Ref : curve.point1Ref, pickDetail.fraction > 0.5 ? curve.point1Ref : curve.point0Ref));
574
- hints.setModeRectangular();
575
- }
576
- else if (curve instanceof core_geometry_1.LineString3d) {
577
- if (curve.numPoints() > 1) {
578
- hints.setOrigin(curve.packedPoints.getPoint3dAtUncheckedPointIndex(pickDetail.fraction > 0.5 ? curve.numPoints() - 2 : 1));
579
- hints.setXAxis(core_geometry_1.Vector3d.createStartEnd(curve.packedPoints.getPoint3dAtUncheckedPointIndex(pickDetail.fraction > 0.5 ? curve.numPoints() - 2 : 1), curve.packedPoints.getPoint3dAtUncheckedPointIndex(pickDetail.fraction > 0.5 ? curve.numPoints() - 1 : 0)));
580
- }
581
- hints.setModeRectangular();
582
- }
583
- else {
584
- const ray = curve.fractionToPointAndUnitTangent(pickDetail.fraction > 0.5 ? 0.0 : 1.0);
585
- hints.setOrigin(ray.origin);
586
- hints.setXAxis(ray.direction);
587
- hints.setModeRectangular();
588
- }
589
- }
590
- hints.sendHints(false);
591
- }
592
- provideToolAssistance(_mainInstrText, _additionalInstr) {
593
- let mainMsg;
594
- if (this.agenda.isEmpty)
595
- mainMsg = EditTool_1.EditTools.translate("ExtendCurve.Prompts.IdentifyEnd");
596
- super.provideToolAssistance(mainMsg);
597
- }
598
- async onRestartTool() {
599
- const tool = new ExtendCurveTool();
600
- if (!await tool.run())
601
- return this.exitTool();
602
- }
603
- }
604
- ExtendCurveTool.toolId = "ExtendCurve";
605
- ExtendCurveTool.iconSpec = "icon-scale"; // Need better icon...
606
- exports.ExtendCurveTool = ExtendCurveTool;
607
- /** @alpha */
608
- var RegionBooleanMode;
609
- (function (RegionBooleanMode) {
610
- /** Create region from union of all input regions */
611
- RegionBooleanMode[RegionBooleanMode["Unite"] = 0] = "Unite";
612
- /** Create region from subtraction from the first input region */
613
- RegionBooleanMode[RegionBooleanMode["Subtract"] = 1] = "Subtract";
614
- /** Create region from intersection of all input regions */
615
- RegionBooleanMode[RegionBooleanMode["Intersect"] = 2] = "Intersect";
616
- })(RegionBooleanMode = exports.RegionBooleanMode || (exports.RegionBooleanMode = {}));
617
- /** @alpha Tool to unite, subtract, or intersect planar regions. */
618
- class RegionBooleanTool extends ModifyCurveTool {
619
- get makeCopyProperty() {
620
- if (!this._makeCopyProperty)
621
- this._makeCopyProperty = new appui_abstract_1.DialogProperty(appui_abstract_1.PropertyDescriptionHelper.buildToggleDescription("regionBooleanKeep", EditTool_1.EditTools.translate("RegionBoolean.Label.KeepOriginal")), false);
622
- return this._makeCopyProperty;
623
- }
624
- get makeCopy() { return this.makeCopyProperty.value; }
625
- set makeCopy(value) { this.makeCopyProperty.value = value; }
626
- static modeMessage(str) { return EditTool_1.EditTools.translate(`RegionBoolean.Mode.${str}`); }
627
- get modeProperty() {
628
- if (!this._modeProperty)
629
- this._modeProperty = new appui_abstract_1.DialogProperty(appui_abstract_1.PropertyDescriptionHelper.buildEnumPicklistEditorDescription("regionBooleanMode", EditTool_1.EditTools.translate("RegionBoolean.Label.Mode"), RegionBooleanTool.getModeChoices()), RegionBooleanMode.Unite);
630
- return this._modeProperty;
631
- }
632
- get mode() { return this.modeProperty.value; }
633
- set mode(mode) { this.modeProperty.value = mode; }
634
- get clearSelectionSet() { return false; } // Don't clear for subtract so that mode can be changed...
635
- get allowSelectionSet() { return RegionBooleanMode.Subtract !== this.mode; }
636
- get allowDragSelect() { return RegionBooleanMode.Subtract !== this.mode; }
637
- get controlKeyContinuesSelection() { return true; }
638
- get requiredElementCount() { return 2; }
639
- get wantAccuSnap() { return false; }
640
- get wantDynamics() { return false; }
641
- get wantModifyOriginal() { return !this.makeCopy; }
642
- async onAgendaModified() { } // No intermediate result preview, defer to processAgenda...
643
- acceptCurve(curve) {
644
- if ("curvePrimitive" === curve.geometryCategory)
645
- return false;
646
- return curve.isAnyRegionType;
647
- }
648
- regionBinaryOp() {
649
- switch (this.mode) {
650
- case RegionBooleanMode.Subtract:
651
- return core_geometry_1.RegionBinaryOpType.AMinusB;
652
- case RegionBooleanMode.Intersect:
653
- return core_geometry_1.RegionBinaryOpType.Intersection;
654
- default:
655
- return core_geometry_1.RegionBinaryOpType.Union;
656
- }
657
- }
658
- regionFromSignedLoops(loops) {
659
- switch (loops.negativeAreaLoops.length) {
660
- case 0:
661
- return undefined;
662
- case 1:
663
- return loops.negativeAreaLoops[0];
664
- default:
665
- return core_geometry_1.RegionOps.sortOuterAndHoleLoopsXY(loops.negativeAreaLoops);
666
- }
667
- }
668
- regionBooleanXY(tools, op) {
669
- if (tools.length < 2)
670
- return undefined;
671
- const loopsA = (core_geometry_1.RegionBinaryOpType.Union !== op ? tools[0] : tools);
672
- const loopsB = (core_geometry_1.RegionBinaryOpType.Union !== op ? tools.slice(1) : undefined);
673
- // TODO: Need to be able to specify group operation for loopsB to correctly support intersect w/o doing 2 at time...
674
- const areas = core_geometry_1.RegionOps.regionBooleanXY(loopsA, loopsB, op);
675
- if (undefined === areas)
676
- return undefined;
677
- // TODO: Holes are expected to be returned as negative area loops but currently are not...
678
- const loops = core_geometry_1.RegionOps.constructAllXYRegionLoops(areas);
679
- if (1 === loops.length)
680
- return this.regionFromSignedLoops(loops[0]);
681
- if (loops.length > 1) {
682
- const unionRegion = core_geometry_1.UnionRegion.create();
683
- for (const loop of loops) {
684
- const child = this.regionFromSignedLoops(loop);
685
- if (undefined === child)
686
- continue;
687
- unionRegion.tryAddChild(child);
688
- }
689
- if (unionRegion.children.length > 1)
690
- return unionRegion;
691
- }
692
- return undefined;
693
- }
694
- async doRegionBoolean(_ev) {
695
- this.curveData = undefined;
696
- if (this.agenda.length < this.requiredElementCount)
697
- return;
698
- const targetData = await this.getCurveData(this.agenda.elements[0]);
699
- if (undefined === targetData?.geom)
700
- return;
701
- const targetLocalToWorld = core_geometry_1.FrameBuilder.createRightHandedFrame(undefined, targetData.geom);
702
- if (undefined === targetLocalToWorld)
703
- return;
704
- const targetWorldToLocal = targetLocalToWorld.inverse();
705
- if (undefined === targetWorldToLocal)
706
- return;
707
- const targetPlane = core_geometry_1.Plane3dByOriginAndUnitNormal.create(targetLocalToWorld.getOrigin(), targetLocalToWorld.matrix.getColumn(2));
708
- if (undefined === targetPlane)
709
- return;
710
- if (!targetData.geom.tryTransformInPlace(targetWorldToLocal))
711
- return;
712
- const tools = [targetData.geom];
713
- for (const id of this.agenda.elements) {
714
- if (id === targetData.props.id)
715
- continue;
716
- const curveData = await this.getCurveData(id);
717
- if (undefined === curveData?.geom)
718
- return;
719
- if (!ModifyCurveTool.isInPlane(curveData.geom, targetPlane)) {
720
- core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Info, EditTool_1.EditTools.translate("RegionBoolean.Error.NonCoplanar")));
721
- return;
722
- }
723
- if (!curveData.geom.tryTransformInPlace(targetWorldToLocal))
724
- return;
725
- tools.push(curveData.geom);
726
- }
727
- const result = this.regionBooleanXY(tools, this.regionBinaryOp());
728
- if (undefined === result || !result.tryTransformInPlace(targetLocalToWorld))
729
- return;
730
- this.curveData = targetData;
731
- this.curveData.geom = result;
732
- }
733
- modifyCurve(_ev, _isAccept) {
734
- return this.curveData?.geom;
735
- }
736
- async applyAgendaOperation(ev) {
737
- if (!await super.applyAgendaOperation(ev))
738
- return false;
739
- if (this.wantModifyOriginal && this.agenda.length > 1)
740
- await EditToolIpc_1.basicManipulationIpc.deleteElements(core_bentley_1.CompressedId64Set.sortAndCompress(this.agenda.elements.slice(1)));
741
- return true;
742
- }
743
- async processAgenda(ev) {
744
- await this.doRegionBoolean(ev);
745
- return super.processAgenda(ev);
746
- }
747
- async onRestartTool() {
748
- const tool = new RegionBooleanTool();
749
- if (!await tool.run())
750
- return this.exitTool();
751
- }
752
- async applyToolSettingPropertyChange(updatedValue) {
753
- if (!this.changeToolSettingPropertyValue(updatedValue))
754
- return false;
755
- if (this.modeProperty.name === updatedValue.propertyName)
756
- await this.onReinitialize();
757
- return true;
758
- }
759
- supplyToolSettingsProperties() {
760
- this.initializeToolSettingPropertyValues([this.makeCopyProperty, this.modeProperty]);
761
- const toolSettings = new Array();
762
- toolSettings.push(this.modeProperty.toDialogItem({ rowPriority: 1, columnIndex: 0 }));
763
- toolSettings.push(this.makeCopyProperty.toDialogItem({ rowPriority: 2, columnIndex: 0 }));
764
- return toolSettings;
765
- }
766
- }
767
- RegionBooleanTool.toolId = "RegionBoolean";
768
- RegionBooleanTool.iconSpec = "icon-scale"; // Need better icon...
769
- RegionBooleanTool.getModeChoices = () => {
770
- return [
771
- { label: RegionBooleanTool.modeMessage("Unite"), value: RegionBooleanMode.Unite },
772
- { label: RegionBooleanTool.modeMessage("Subtract"), value: RegionBooleanMode.Subtract },
773
- { label: RegionBooleanTool.modeMessage("Intersect"), value: RegionBooleanMode.Intersect },
774
- ];
775
- };
776
- exports.RegionBooleanTool = RegionBooleanTool;
777
- //# sourceMappingURL=ModifyCurveTools.js.map