@itwin/editor-frontend 3.0.0-dev.98 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +108 -1
- package/LICENSE.md +1 -1
- package/README.md +9 -9
- package/lib/cjs/EditTool.d.ts.map +1 -1
- package/lib/cjs/EditTool.js +18 -7
- package/lib/cjs/EditTool.js.map +1 -1
- package/lib/cjs/ElementGeometryTool.d.ts +64 -80
- package/lib/cjs/ElementGeometryTool.d.ts.map +1 -1
- package/lib/cjs/ElementGeometryTool.js +333 -295
- package/lib/cjs/ElementGeometryTool.js.map +1 -1
- package/lib/cjs/ProjectLocation/ProjectGeolocation.d.ts +10 -17
- package/lib/cjs/ProjectLocation/ProjectGeolocation.d.ts.map +1 -1
- package/lib/cjs/ProjectLocation/ProjectGeolocation.js +54 -94
- package/lib/cjs/ProjectLocation/ProjectGeolocation.js.map +1 -1
- package/lib/cjs/SketchTools.d.ts +21 -9
- package/lib/cjs/SketchTools.d.ts.map +1 -1
- package/lib/cjs/SketchTools.js +197 -204
- package/lib/cjs/SketchTools.js.map +1 -1
- package/lib/cjs/SolidModelingTools.d.ts +381 -0
- package/lib/cjs/SolidModelingTools.d.ts.map +1 -0
- package/lib/cjs/SolidModelingTools.js +1460 -0
- package/lib/cjs/SolidModelingTools.js.map +1 -0
- package/lib/cjs/TransformElementsTool.d.ts.map +1 -1
- package/lib/cjs/TransformElementsTool.js +8 -28
- package/lib/cjs/TransformElementsTool.js.map +1 -1
- package/lib/cjs/UndoRedoTool.js +1 -1
- package/lib/cjs/UndoRedoTool.js.map +1 -1
- package/lib/cjs/editor-frontend.d.ts +1 -0
- package/lib/cjs/editor-frontend.d.ts.map +1 -1
- package/lib/cjs/editor-frontend.js +1 -0
- package/lib/cjs/editor-frontend.js.map +1 -1
- package/lib/esm/EditTool.d.ts.map +1 -1
- package/lib/esm/EditTool.js +14 -3
- package/lib/esm/EditTool.js.map +1 -1
- package/lib/esm/ElementGeometryTool.d.ts +64 -80
- package/lib/esm/ElementGeometryTool.d.ts.map +1 -1
- package/lib/esm/ElementGeometryTool.js +334 -290
- package/lib/esm/ElementGeometryTool.js.map +1 -1
- package/lib/esm/ProjectLocation/ProjectGeolocation.d.ts +10 -17
- package/lib/esm/ProjectLocation/ProjectGeolocation.d.ts.map +1 -1
- package/lib/esm/ProjectLocation/ProjectGeolocation.js +54 -94
- package/lib/esm/ProjectLocation/ProjectGeolocation.js.map +1 -1
- package/lib/esm/SketchTools.d.ts +21 -9
- package/lib/esm/SketchTools.d.ts.map +1 -1
- package/lib/esm/SketchTools.js +198 -205
- package/lib/esm/SketchTools.js.map +1 -1
- package/lib/esm/SolidModelingTools.d.ts +381 -0
- package/lib/esm/SolidModelingTools.d.ts.map +1 -0
- package/lib/esm/SolidModelingTools.js +1435 -0
- package/lib/esm/SolidModelingTools.js.map +1 -0
- package/lib/esm/TransformElementsTool.d.ts.map +1 -1
- package/lib/esm/TransformElementsTool.js +8 -28
- package/lib/esm/TransformElementsTool.js.map +1 -1
- package/lib/esm/UndoRedoTool.js +1 -1
- package/lib/esm/UndoRedoTool.js.map +1 -1
- package/lib/esm/editor-frontend.d.ts +1 -0
- package/lib/esm/editor-frontend.d.ts.map +1 -1
- package/lib/esm/editor-frontend.js +1 -0
- package/lib/esm/editor-frontend.js.map +1 -1
- package/lib/public/locales/en/Editor.json +141 -3
- package/package.json +17 -25
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module Editing
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.
|
|
10
|
+
exports.LocateSubEntityTool = exports.ElementGeometryCacheTool = exports.SubEntityData = exports.isSameSubEntity = exports.ElementGeometryGraphicsProvider = void 0;
|
|
11
11
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
12
12
|
const editor_common_1 = require("@itwin/editor-common");
|
|
13
13
|
const core_common_1 = require("@itwin/core-common");
|
|
@@ -66,46 +66,52 @@ class ElementGeometryGraphicsProvider {
|
|
|
66
66
|
}
|
|
67
67
|
exports.ElementGeometryGraphicsProvider = ElementGeometryGraphicsProvider;
|
|
68
68
|
/** @alpha */
|
|
69
|
+
function isSameSubEntity(a, b) {
|
|
70
|
+
if (a.type !== b.type)
|
|
71
|
+
return false;
|
|
72
|
+
if (a.id !== b.id)
|
|
73
|
+
return false;
|
|
74
|
+
if ((undefined !== a.index ? a.index : 0) !== (undefined !== b.index ? b.index : 0))
|
|
75
|
+
return false;
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
exports.isSameSubEntity = isSameSubEntity;
|
|
79
|
+
/** @alpha */
|
|
69
80
|
class SubEntityData {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return false;
|
|
77
|
-
if (this.info.id !== other.id)
|
|
78
|
-
return false;
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
81
|
+
constructor(props) { this._props = props; }
|
|
82
|
+
get props() { return this._props; }
|
|
83
|
+
set props(value) { this.cleanupGraphic(); this._props = value; }
|
|
84
|
+
get geometry() { return this._geometry; }
|
|
85
|
+
set geometry(value) { this._geometry = value; }
|
|
86
|
+
isSame(other) { return isSameSubEntity(this._props, other); }
|
|
81
87
|
getAppearance(vp, accepted) {
|
|
82
|
-
var _a, _b, _c, _d
|
|
88
|
+
var _a, _b, _c, _d;
|
|
83
89
|
const color = vp.hilite.color;
|
|
84
90
|
const rgb = core_common_1.RgbColor.fromColorDef(accepted ? color.inverse() : color);
|
|
85
91
|
const transparency = 0.25;
|
|
86
92
|
const emphasized = true; // Necessary for obscured sub-entities w/SceneGraphic...
|
|
87
93
|
let weight;
|
|
88
|
-
switch (
|
|
94
|
+
switch (this.props.type) {
|
|
89
95
|
case editor_common_1.SubEntityType.Face:
|
|
90
96
|
break;
|
|
91
97
|
case editor_common_1.SubEntityType.Edge:
|
|
92
|
-
const edgeWeight = accepted ?
|
|
93
|
-
weight = ((
|
|
98
|
+
const edgeWeight = accepted ? 1 : 3;
|
|
99
|
+
weight = ((_b = (_a = this._geometry) === null || _a === void 0 ? void 0 : _a.appearance) === null || _b === void 0 ? void 0 : _b.weight) ? Math.min(this._geometry.appearance.weight + edgeWeight, 31) : edgeWeight;
|
|
94
100
|
break;
|
|
95
101
|
case editor_common_1.SubEntityType.Vertex:
|
|
96
|
-
const vertexWeight = accepted ?
|
|
97
|
-
weight = ((
|
|
102
|
+
const vertexWeight = accepted ? 8 : 10;
|
|
103
|
+
weight = ((_d = (_c = this._geometry) === null || _c === void 0 ? void 0 : _c.appearance) === null || _d === void 0 ? void 0 : _d.weight) ? Math.min(this._geometry.appearance.weight + vertexWeight, 31) : vertexWeight;
|
|
98
104
|
break;
|
|
99
105
|
}
|
|
100
106
|
return core_common_1.FeatureAppearance.fromJSON({ rgb, transparency, weight, emphasized, nonLocatable: true });
|
|
101
107
|
}
|
|
102
108
|
async createGraphic(iModel) {
|
|
103
109
|
var _a;
|
|
104
|
-
if (undefined === ((_a = this.
|
|
110
|
+
if (undefined === ((_a = this._geometry) === null || _a === void 0 ? void 0 : _a.graphic))
|
|
105
111
|
return false;
|
|
106
112
|
if (undefined === this._graphicsProvider)
|
|
107
113
|
this._graphicsProvider = new ElementGeometryGraphicsProvider(iModel);
|
|
108
|
-
return this._graphicsProvider.createGraphic(this.
|
|
114
|
+
return this._graphicsProvider.createGraphic(this._geometry.graphic);
|
|
109
115
|
}
|
|
110
116
|
cleanupGraphic() {
|
|
111
117
|
if (undefined === this._graphicsProvider)
|
|
@@ -121,16 +127,15 @@ class SubEntityData {
|
|
|
121
127
|
var _a, _b;
|
|
122
128
|
if (undefined === ((_a = this._graphicsProvider) === null || _a === void 0 ? void 0 : _a.graphic))
|
|
123
129
|
return;
|
|
124
|
-
const
|
|
125
|
-
return app.extendAppearance(this.getAppearance(context.viewport, accepted));
|
|
126
|
-
});
|
|
127
|
-
const opts = { appearanceProvider };
|
|
128
|
-
const range = (((_b = this.geom) === null || _b === void 0 ? void 0 : _b.range) ? core_geometry_1.Range3d.fromJSON(this.geom.range) : undefined);
|
|
130
|
+
const range = (((_b = this._geometry) === null || _b === void 0 ? void 0 : _b.range) ? core_geometry_1.Range3d.fromJSON(this._geometry.range) : undefined);
|
|
129
131
|
const pixelSize = context.viewport.getPixelSizeAtPoint(range ? range.center : undefined);
|
|
130
132
|
const offsetDir = context.viewport.view.getZVector();
|
|
131
133
|
offsetDir.scaleToLength(3 * pixelSize, offsetDir);
|
|
132
134
|
const offsetTrans = core_geometry_1.Transform.createTranslation(offsetDir);
|
|
133
|
-
|
|
135
|
+
const appearanceProvider = core_common_1.FeatureAppearanceProvider.supplement((app) => {
|
|
136
|
+
return app.extendAppearance(this.getAppearance(context.viewport, accepted));
|
|
137
|
+
});
|
|
138
|
+
this._graphicsProvider.addDecoration(context, core_frontend_1.GraphicType.Scene, offsetTrans, { appearanceProvider });
|
|
134
139
|
}
|
|
135
140
|
}
|
|
136
141
|
exports.SubEntityData = SubEntityData;
|
|
@@ -151,14 +156,22 @@ class ElementGeometryCacheTool extends core_frontend_1.ElementSetTool {
|
|
|
151
156
|
static callCommand(method, ...args) {
|
|
152
157
|
return EditTool_1.EditTools.callCommand(method, ...args);
|
|
153
158
|
}
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
agendaAppearance(isDynamics) {
|
|
160
|
+
if (isDynamics) {
|
|
161
|
+
if (undefined === this._agendaAppearanceDynamic)
|
|
162
|
+
this._agendaAppearanceDynamic = core_common_1.FeatureAppearance.fromTransparency(0.0);
|
|
163
|
+
return this._agendaAppearanceDynamic;
|
|
164
|
+
}
|
|
165
|
+
if (undefined === this._agendaAppearanceDefault)
|
|
166
|
+
this._agendaAppearanceDefault = core_common_1.FeatureAppearance.fromTransparency(0.9);
|
|
167
|
+
return this._agendaAppearanceDefault;
|
|
168
|
+
}
|
|
156
169
|
get wantAgendaAppearanceOverride() { return false; }
|
|
157
170
|
addFeatureOverrides(overrides, _vp) {
|
|
158
171
|
if (this.agenda.isEmpty)
|
|
159
172
|
return;
|
|
160
|
-
const
|
|
161
|
-
this.agenda.elements.forEach((
|
|
173
|
+
const appearance = this.agendaAppearance(false);
|
|
174
|
+
this.agenda.elements.forEach((elementId) => { overrides.override({ elementId, appearance }); });
|
|
162
175
|
}
|
|
163
176
|
updateAgendaAppearanceProvider(drop) {
|
|
164
177
|
if (!this.wantAgendaAppearanceOverride)
|
|
@@ -173,18 +186,25 @@ class ElementGeometryCacheTool extends core_frontend_1.ElementSetTool {
|
|
|
173
186
|
}
|
|
174
187
|
}
|
|
175
188
|
get geometryCacheFilter() { return undefined; }
|
|
189
|
+
onGeometryCacheFilterChanged() { this._checkedIds.clear(); }
|
|
190
|
+
async createElementGeometryCache(id) {
|
|
191
|
+
// NOTE: Creates cache if it doesn't already exist then test new or existing cache against filter...
|
|
192
|
+
try {
|
|
193
|
+
this._startedCmd = await this.startCommand();
|
|
194
|
+
return await ElementGeometryCacheTool.callCommand("createElementGeometryCache", id, this.geometryCacheFilter);
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
176
200
|
async acceptElementForOperation(id) {
|
|
177
201
|
if (core_bentley_1.Id64.isInvalid(id) || core_bentley_1.Id64.isTransient(id))
|
|
178
202
|
return false;
|
|
179
203
|
let accept = this._checkedIds.get(id);
|
|
180
204
|
if (undefined === accept) {
|
|
181
|
-
|
|
182
|
-
this.
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
catch (err) {
|
|
186
|
-
accept = false;
|
|
187
|
-
}
|
|
205
|
+
if (this.agenda.isEmpty && this._checkedIds.size > 1000)
|
|
206
|
+
this._checkedIds.clear(); // Limit auto-locate cache size to something reasonable...
|
|
207
|
+
accept = await this.createElementGeometryCache(id);
|
|
188
208
|
this._checkedIds.set(id, accept);
|
|
189
209
|
}
|
|
190
210
|
return accept;
|
|
@@ -212,8 +232,14 @@ class ElementGeometryCacheTool extends core_frontend_1.ElementSetTool {
|
|
|
212
232
|
return this.postFilterIds(await super.getDragSelectCandidates(vp, origin, corner, method, overlap));
|
|
213
233
|
}
|
|
214
234
|
onDynamicFrame(_ev, context) {
|
|
215
|
-
if (undefined
|
|
216
|
-
|
|
235
|
+
if (undefined === this._graphicsProvider)
|
|
236
|
+
return;
|
|
237
|
+
if (!this.wantAgendaAppearanceOverride)
|
|
238
|
+
return this._graphicsProvider.addGraphic(context);
|
|
239
|
+
const appearanceProvider = core_common_1.FeatureAppearanceProvider.supplement((app) => {
|
|
240
|
+
return app.extendAppearance(this.agendaAppearance(true));
|
|
241
|
+
});
|
|
242
|
+
this._graphicsProvider.addGraphic(context, undefined, { appearanceProvider });
|
|
217
243
|
}
|
|
218
244
|
async onMouseMotion(ev) {
|
|
219
245
|
return this.updateGraphic(ev, core_frontend_1.IModelApp.viewManager.inDynamicsMode);
|
|
@@ -276,126 +302,126 @@ class ElementGeometryCacheTool extends core_frontend_1.ElementSetTool {
|
|
|
276
302
|
}
|
|
277
303
|
}
|
|
278
304
|
exports.ElementGeometryCacheTool = ElementGeometryCacheTool;
|
|
279
|
-
/** @alpha Base class for tools that
|
|
280
|
-
class
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
305
|
+
/** @alpha Base class for tools that need to locate faces, edges, and vertices. */
|
|
306
|
+
class LocateSubEntityTool extends ElementGeometryCacheTool {
|
|
307
|
+
constructor() {
|
|
308
|
+
super(...arguments);
|
|
309
|
+
this._acceptedSubEntities = [];
|
|
310
|
+
this._summaryIds = new Map();
|
|
311
|
+
}
|
|
312
|
+
provideToolAssistance(mainInstrText, additionalInstr) {
|
|
313
|
+
if (this.wantAdditionalSubEntities) {
|
|
314
|
+
const faceKey = this.wantSubEntityType(editor_common_1.SubEntityType.Face) ? "Face" : "";
|
|
315
|
+
const edgeKey = this.wantSubEntityType(editor_common_1.SubEntityType.Edge) ? "Edge" : "";
|
|
316
|
+
const vertexKey = this.wantSubEntityType(editor_common_1.SubEntityType.Vertex) ? "Vertex" : "";
|
|
317
|
+
const subEntityKey = `${faceKey}${edgeKey}${vertexKey}`;
|
|
318
|
+
if (0 === subEntityKey.length) {
|
|
319
|
+
super.provideToolAssistance(mainInstrText, additionalInstr);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
if (undefined === mainInstrText)
|
|
323
|
+
mainInstrText = EditTool_1.EditTools.translate(`LocateSubEntities.Identify.${subEntityKey}`);
|
|
324
|
+
const leftMsg = EditTool_1.EditTools.translate(`LocateSubEntities.Accept.${subEntityKey}`);
|
|
325
|
+
const rightMsg = this.haveAcceptedSubEntities && this.allowSubEntitySelectNext ? EditTool_1.EditTools.translate(`LocateSubEntities.AcceptNext.${subEntityKey}`) : core_frontend_1.CoreTools.translate("ElementSet.Inputs.Cancel");
|
|
326
|
+
const mouseInstructions = [];
|
|
327
|
+
const touchInstructions = [];
|
|
328
|
+
if (!core_frontend_1.ToolAssistance.createTouchCursorInstructions(touchInstructions))
|
|
329
|
+
touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.OneTouchTap, leftMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
|
|
330
|
+
mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.LeftClick, leftMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
|
|
331
|
+
touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.TwoTouchTap, rightMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
|
|
332
|
+
mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.RightClick, rightMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
|
|
333
|
+
if (this.allowSubEntityControlSelect)
|
|
334
|
+
mouseInstructions.push(core_frontend_1.ToolAssistance.createModifierKeyInstruction(core_frontend_1.ToolAssistance.ctrlKey, core_frontend_1.ToolAssistanceImage.LeftClickDrag, EditTool_1.EditTools.translate(`LocateSubEntities.IdentifyAdditional.${subEntityKey}`), false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
|
|
335
|
+
if (undefined !== additionalInstr) {
|
|
336
|
+
for (const instr of additionalInstr) {
|
|
337
|
+
if (core_frontend_1.ToolAssistanceInputMethod.Touch === instr.inputMethod)
|
|
338
|
+
touchInstructions.push(instr);
|
|
339
|
+
else
|
|
340
|
+
mouseInstructions.push(instr);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
const sections = [];
|
|
344
|
+
sections.push(core_frontend_1.ToolAssistance.createSection(mouseInstructions, core_frontend_1.ToolAssistance.inputsLabel));
|
|
345
|
+
sections.push(core_frontend_1.ToolAssistance.createSection(touchInstructions, core_frontend_1.ToolAssistance.inputsLabel));
|
|
346
|
+
const mainInstruction = core_frontend_1.ToolAssistance.createInstruction(this.iconSpec, mainInstrText);
|
|
347
|
+
const instructions = core_frontend_1.ToolAssistance.createInstructions(mainInstruction, sections);
|
|
348
|
+
core_frontend_1.IModelApp.notifications.setToolAssistance(instructions);
|
|
349
|
+
return;
|
|
306
350
|
}
|
|
351
|
+
super.provideToolAssistance(mainInstrText, additionalInstr);
|
|
307
352
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
get
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
353
|
+
get wantAgendaAppearanceOverride() { return true; }
|
|
354
|
+
get wantGeometrySummary() { return false; }
|
|
355
|
+
get wantSubEntitySnap() { return false; }
|
|
356
|
+
wantSubEntityType(type) { return editor_common_1.SubEntityType.Face === type; }
|
|
357
|
+
getMaximumSubEntityHits(type) { return this.wantSubEntityType(type) ? 25 : 0; }
|
|
358
|
+
get requiredSubEntityCount() { return 1; }
|
|
359
|
+
get haveAcceptedSubEntities() { return (0 !== this._acceptedSubEntities.length); }
|
|
360
|
+
get inhibitSubEntityDisplay() { return this.isDynamicsStarted; }
|
|
361
|
+
get allowSubEntityControlSelect() { return true; }
|
|
362
|
+
get allowSubEntityControlDeselect() { return this.allowSubEntityControlSelect; }
|
|
363
|
+
get allowSubEntitySelectNext() { return !this.isDynamicsStarted; }
|
|
364
|
+
getBRepEntityTypeForSubEntity(id, subEntity) {
|
|
365
|
+
const summary = this._summaryIds.get(id);
|
|
366
|
+
if (undefined === summary)
|
|
367
|
+
return editor_common_1.BRepEntityType.Invalid;
|
|
368
|
+
const index = (undefined !== subEntity.index ? subEntity.index : 0);
|
|
369
|
+
if (index >= summary.length)
|
|
370
|
+
return editor_common_1.BRepEntityType.Invalid;
|
|
371
|
+
return summary[index];
|
|
372
|
+
}
|
|
373
|
+
async createElementGeometrySummary(id) {
|
|
374
|
+
let summary = this._summaryIds.get(id);
|
|
375
|
+
if (undefined === summary) {
|
|
376
|
+
if (this.agenda.isEmpty && this._summaryIds.size > 1000)
|
|
377
|
+
this._summaryIds.clear(); // Limit auto-locate cache size to something reasonable...
|
|
378
|
+
try {
|
|
379
|
+
this._startedCmd = await this.startCommand();
|
|
380
|
+
if (undefined === (summary = await ElementGeometryCacheTool.callCommand("summarizeElementGeometryCache", id)))
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
catch (err) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
this._summaryIds.set(id, summary);
|
|
387
|
+
}
|
|
388
|
+
return true;
|
|
334
389
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
SubtractSolidElementsTool.iconSpec = "icon-move"; // TODO: Need better icon...
|
|
339
|
-
/** @alpha Perform boolean intersection of solid geometry. */
|
|
340
|
-
class IntersectSolidElementsTool extends BooleanOperationTool {
|
|
341
|
-
get mode() { return editor_common_1.BooleanMode.Intersect; }
|
|
342
|
-
async onRestartTool() {
|
|
343
|
-
const tool = new IntersectSolidElementsTool();
|
|
344
|
-
if (!await tool.run())
|
|
345
|
-
return this.exitTool();
|
|
390
|
+
async createElementGeometryCache(id) {
|
|
391
|
+
const accept = await super.createElementGeometryCache(id);
|
|
392
|
+
return (accept && this.wantGeometrySummary ? this.createElementGeometrySummary(id) : accept);
|
|
346
393
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
/** @alpha Perform sew operation on surface geometry. */
|
|
352
|
-
class SewSheetElementsTool extends ElementGeometryCacheTool {
|
|
353
|
-
get allowSelectionSet() { return true; }
|
|
354
|
-
get allowDragSelect() { return true; }
|
|
355
|
-
get controlKeyContinuesSelection() { return true; }
|
|
356
|
-
get requiredElementCount() { return 2; }
|
|
357
|
-
get geometryCacheFilter() {
|
|
358
|
-
return { parts: true, curves: false, surfaces: true, solids: false, other: false };
|
|
359
|
-
}
|
|
360
|
-
async applyAgendaOperation() {
|
|
361
|
-
if (this.agenda.length < this.requiredElementCount)
|
|
394
|
+
getAcceptedSubEntityData(index = -1) {
|
|
395
|
+
if (-1 === index)
|
|
396
|
+
index = this._acceptedSubEntities.length - 1;
|
|
397
|
+
if (index < 0 || index > this._acceptedSubEntities.length - 1)
|
|
362
398
|
return undefined;
|
|
363
|
-
|
|
364
|
-
this._startedCmd = await this.startCommand();
|
|
365
|
-
const target = this.agenda.elements[0];
|
|
366
|
-
const tools = this.agenda.elements.slice(1);
|
|
367
|
-
const params = { tools };
|
|
368
|
-
const opts = { writeChanges: true };
|
|
369
|
-
return await ElementGeometryCacheTool.callCommand("sewSheets", target, params, opts);
|
|
370
|
-
}
|
|
371
|
-
catch (err) {
|
|
372
|
-
return undefined;
|
|
373
|
-
}
|
|
399
|
+
return this._acceptedSubEntities[index];
|
|
374
400
|
}
|
|
375
|
-
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
401
|
+
getAcceptedSubEntities() {
|
|
402
|
+
const accepted = [];
|
|
403
|
+
this._acceptedSubEntities.forEach((entry) => { accepted.push(entry.props); });
|
|
404
|
+
return accepted;
|
|
379
405
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
406
|
+
drawSubEntity(context, subEntity, accepted) {
|
|
407
|
+
subEntity.display(context, accepted);
|
|
408
|
+
}
|
|
409
|
+
drawAcceptedSubEntities(context) {
|
|
410
|
+
this._acceptedSubEntities.forEach((entry) => { this.drawSubEntity(context, entry, true); });
|
|
384
411
|
}
|
|
385
|
-
}
|
|
386
|
-
exports.SewSheetElementsTool = SewSheetElementsTool;
|
|
387
|
-
SewSheetElementsTool.toolId = "SewSheets";
|
|
388
|
-
SewSheetElementsTool.iconSpec = "icon-move"; // TODO: Need better icon...
|
|
389
|
-
/** @alpha Base class for tools that need to locate faces, edges, and vertices. */
|
|
390
|
-
class LocateSubEntityTool extends ElementGeometryCacheTool {
|
|
391
|
-
wantSubEntityType(type) { return editor_common_1.SubEntityType.Face === type; }
|
|
392
|
-
getMaximumSubEntityHits(type) { return this.wantSubEntityType(type) ? 25 : 0; }
|
|
393
|
-
get wantAgendaAppearanceOverride() { return true; }
|
|
394
412
|
decorate(context) {
|
|
395
|
-
if (!this.allowView(context.viewport))
|
|
413
|
+
if (this.inhibitSubEntityDisplay || !this.allowView(context.viewport))
|
|
396
414
|
return;
|
|
415
|
+
if (this.haveAcceptedSubEntities)
|
|
416
|
+
this.drawAcceptedSubEntities(context);
|
|
397
417
|
if (undefined !== this._currentSubEntity)
|
|
398
|
-
this.
|
|
418
|
+
this.drawSubEntity(context, this._currentSubEntity, false);
|
|
419
|
+
}
|
|
420
|
+
decorateSuspended(context) {
|
|
421
|
+
if (this.inhibitSubEntityDisplay || !this.allowView(context.viewport))
|
|
422
|
+
return;
|
|
423
|
+
if (this.haveAcceptedSubEntities)
|
|
424
|
+
this.drawAcceptedSubEntities(context);
|
|
399
425
|
}
|
|
400
426
|
getLocateAperture(ev) {
|
|
401
427
|
if (undefined === ev.viewport)
|
|
@@ -415,6 +441,19 @@ class LocateSubEntityTool extends ElementGeometryCacheTool {
|
|
|
415
441
|
// The edge and vertex hits get post-filtered on xy distance, so this is fine for perspective views...
|
|
416
442
|
return (aperture * vec[0].distance(vec[1]));
|
|
417
443
|
}
|
|
444
|
+
getRayOrigin(ev) {
|
|
445
|
+
const spacePoint = ev.point.clone();
|
|
446
|
+
const vp = ev.viewport;
|
|
447
|
+
if (undefined === vp)
|
|
448
|
+
return spacePoint;
|
|
449
|
+
vp.worldToNpc(spacePoint, spacePoint);
|
|
450
|
+
spacePoint.z = 1.0;
|
|
451
|
+
vp.npcToWorld(spacePoint, spacePoint);
|
|
452
|
+
return spacePoint;
|
|
453
|
+
}
|
|
454
|
+
wantHiddenEdges(vp) {
|
|
455
|
+
return vp.viewFlags.hiddenEdgesVisible();
|
|
456
|
+
}
|
|
418
457
|
getSubEntityFilter() { return undefined; }
|
|
419
458
|
async pickSubEntities(id, boresite, maxFace, maxEdge, maxVertex, maxDistance, hiddenEdgesVisible, filter) {
|
|
420
459
|
try {
|
|
@@ -444,8 +483,9 @@ class LocateSubEntityTool extends ElementGeometryCacheTool {
|
|
|
444
483
|
return undefined;
|
|
445
484
|
const aperture = this.getLocateAperture(ev);
|
|
446
485
|
const maxDistance = this.getMaxRayDistance(ev, aperture);
|
|
447
|
-
const
|
|
448
|
-
const
|
|
486
|
+
const spacePoint = this.getRayOrigin(ev);
|
|
487
|
+
const boresite = core_frontend_1.AccuDrawHintBuilder.getBoresite(spacePoint, vp);
|
|
488
|
+
const hiddenEdgesVisible = this.wantHiddenEdges(vp);
|
|
449
489
|
const filter = this.getSubEntityFilter();
|
|
450
490
|
let hits = await this.pickSubEntities(id, boresite, maxFace, maxEdge, maxVertex, maxDistance, hiddenEdgesVisible, filter);
|
|
451
491
|
// NOTE: Remove erroneous edge/vertex hits in perspective views by checking real xy distance to hit point...
|
|
@@ -469,39 +509,103 @@ class LocateSubEntityTool extends ElementGeometryCacheTool {
|
|
|
469
509
|
}
|
|
470
510
|
return hits;
|
|
471
511
|
}
|
|
512
|
+
async createSubEntityData(id, hit) {
|
|
513
|
+
const data = new SubEntityData(hit.subEntity);
|
|
514
|
+
const chordTolerance = (this.targetView ? (0, CreateElementTool_1.computeChordToleranceFromPoint)(this.targetView, core_geometry_1.Point3d.fromJSON(hit.point)) : undefined);
|
|
515
|
+
await this.createSubEntityGraphic(id, data, chordTolerance);
|
|
516
|
+
return data;
|
|
517
|
+
}
|
|
518
|
+
/** Append specified sub-entity to accepted array. */
|
|
519
|
+
async addSubEntity(id, props) {
|
|
520
|
+
this._acceptedSubEntities.push(await this.createSubEntityData(id, props));
|
|
521
|
+
}
|
|
522
|
+
/** Remove specified sub-entity from accepted array, or pop last sub-entity if undefined. */
|
|
523
|
+
async removeSubEntity(_id, props) {
|
|
524
|
+
if (undefined !== props)
|
|
525
|
+
this._acceptedSubEntities = this._acceptedSubEntities.filter((entry) => !isSameSubEntity(entry.props, props.subEntity));
|
|
526
|
+
else
|
|
527
|
+
this._acceptedSubEntities.pop();
|
|
528
|
+
}
|
|
529
|
+
/** Locate sub-entities for the most recently added (last) agenda entry. Tool sub-classes that wish to identity
|
|
530
|
+
* sub-entities from multiple elements are responsible for maintaining the sub-entities per-element.
|
|
531
|
+
*/
|
|
472
532
|
async doLocateSubEntity(ev, newSearch) {
|
|
533
|
+
var _a;
|
|
473
534
|
if (this.agenda.isEmpty || undefined === ev.viewport)
|
|
474
535
|
return false;
|
|
536
|
+
const id = this.agenda.elements[this.agenda.length - 1];
|
|
475
537
|
if (newSearch) {
|
|
476
|
-
|
|
477
|
-
if (undefined ===
|
|
538
|
+
this._locatedSubEntities = await this.doPickSubEntities(id, ev);
|
|
539
|
+
if (undefined === this._locatedSubEntities || 0 === this._locatedSubEntities.length)
|
|
478
540
|
return false;
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
541
|
+
/** NOTE: Set last button location to point on sub-entity when not snapping.
|
|
542
|
+
* If dynamics are enabled on this event, onDynamicFrame is called with this location.
|
|
543
|
+
*/
|
|
544
|
+
if (core_frontend_1.CoordSource.ElemSnap !== ev.coordsFrom) {
|
|
545
|
+
ev.point.setFrom(core_geometry_1.Point3d.fromJSON(this._locatedSubEntities[0].point));
|
|
546
|
+
core_frontend_1.IModelApp.toolAdmin.setAdjustedDataPoint(ev);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
await this.removeSubEntity(id);
|
|
482
551
|
}
|
|
483
|
-
this.
|
|
552
|
+
const hit = (_a = this._locatedSubEntities) === null || _a === void 0 ? void 0 : _a.shift();
|
|
553
|
+
if (undefined !== hit) {
|
|
554
|
+
if (undefined === this._acceptedSubEntities.find((entry) => isSameSubEntity(entry.props, hit.subEntity)))
|
|
555
|
+
await this.addSubEntity(id, hit);
|
|
556
|
+
else if (this.allowSubEntityControlDeselect)
|
|
557
|
+
await this.removeSubEntity(id, hit);
|
|
558
|
+
}
|
|
559
|
+
core_frontend_1.IModelApp.viewManager.invalidateDecorationsAllViews();
|
|
484
560
|
return true;
|
|
485
561
|
}
|
|
486
562
|
async chooseNextHit(ev) {
|
|
487
|
-
if (
|
|
563
|
+
if (!this.haveAcceptedSubEntities)
|
|
488
564
|
return super.chooseNextHit(ev);
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
565
|
+
if (!this.allowSubEntitySelectNext) {
|
|
566
|
+
await this.onReinitialize(); // Don't cycle through hits after starting dynamics...
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
await this.doLocateSubEntity(ev, false);
|
|
570
|
+
if (!this.haveAcceptedSubEntities)
|
|
571
|
+
await this.onReinitialize();
|
|
572
|
+
}
|
|
492
573
|
return core_frontend_1.EventHandled.No;
|
|
493
574
|
}
|
|
575
|
+
get wantAdditionalSubEntities() {
|
|
576
|
+
return (this._acceptedSubEntities.length < this.requiredSubEntityCount || (this.allowSubEntityControlSelect && this.isControlDown));
|
|
577
|
+
}
|
|
494
578
|
async gatherInput(ev) {
|
|
495
|
-
if (
|
|
579
|
+
if (this.wantAdditionalSubEntities) {
|
|
496
580
|
await this.doLocateSubEntity(ev, true);
|
|
581
|
+
if (this.wantAdditionalSubEntities) {
|
|
582
|
+
this.setupAndPromptForNextAction();
|
|
583
|
+
return core_frontend_1.EventHandled.No;
|
|
584
|
+
}
|
|
585
|
+
this.clearCurrentSubEntity();
|
|
586
|
+
}
|
|
497
587
|
return super.gatherInput(ev);
|
|
498
588
|
}
|
|
499
|
-
|
|
500
|
-
if (
|
|
501
|
-
return
|
|
502
|
-
|
|
589
|
+
getCurrentElement() {
|
|
590
|
+
if (!this.agenda.isEmpty)
|
|
591
|
+
return this.agenda.elements[this.agenda.length - 1];
|
|
592
|
+
const hit = core_frontend_1.IModelApp.accuSnap.currHit;
|
|
593
|
+
return (undefined !== hit && hit.isElementHit ? hit.sourceId : undefined);
|
|
594
|
+
}
|
|
595
|
+
clearCurrentSubEntity() {
|
|
596
|
+
if (undefined === this._currentSubEntity)
|
|
597
|
+
return;
|
|
598
|
+
this._currentSubEntity.cleanupGraphic();
|
|
599
|
+
this._currentSubEntity = undefined;
|
|
503
600
|
}
|
|
504
|
-
async setCurrentSubEntity(id,
|
|
601
|
+
async setCurrentSubEntity(id, hit, chordTolerance) {
|
|
602
|
+
if (undefined === this._currentSubEntity)
|
|
603
|
+
this._currentSubEntity = new SubEntityData(hit.subEntity);
|
|
604
|
+
else
|
|
605
|
+
this._currentSubEntity.props = hit.subEntity;
|
|
606
|
+
return this.createSubEntityGraphic(id, this._currentSubEntity, chordTolerance);
|
|
607
|
+
}
|
|
608
|
+
async changeCurrentSubEntity(id, current, chordTolerance) {
|
|
505
609
|
if (undefined === id || undefined === current) {
|
|
506
610
|
if (undefined === this._currentSubEntity || !this._currentSubEntity.hasGraphic)
|
|
507
611
|
return false;
|
|
@@ -510,162 +614,96 @@ class LocateSubEntityTool extends ElementGeometryCacheTool {
|
|
|
510
614
|
}
|
|
511
615
|
if (undefined !== this._currentSubEntity && this._currentSubEntity.hasGraphic && this._currentSubEntity.isSame(current.subEntity))
|
|
512
616
|
return false;
|
|
513
|
-
|
|
514
|
-
this._currentSubEntity = new SubEntityData();
|
|
515
|
-
else
|
|
516
|
-
this._currentSubEntity.cleanupGraphic();
|
|
517
|
-
const opts = {
|
|
518
|
-
wantGraphic: true,
|
|
519
|
-
wantRange: true,
|
|
520
|
-
wantAppearance: true,
|
|
521
|
-
chordTolerance,
|
|
522
|
-
};
|
|
523
|
-
this._currentSubEntity.info = current.subEntity;
|
|
524
|
-
this._currentSubEntity.geom = await ElementGeometryCacheTool.callCommand("getSubEntityGeometry", id, current.subEntity, opts);
|
|
525
|
-
return this._currentSubEntity.createGraphic(this.iModel);
|
|
526
|
-
}
|
|
527
|
-
clearSubEntityGraphic() {
|
|
528
|
-
if (undefined === this._currentSubEntity)
|
|
529
|
-
return;
|
|
530
|
-
this._currentSubEntity.cleanupGraphic();
|
|
531
|
-
this._currentSubEntity = undefined;
|
|
617
|
+
return this.setCurrentSubEntity(id, current, chordTolerance);
|
|
532
618
|
}
|
|
533
|
-
async
|
|
619
|
+
async updateCurrentSubEntity(ev) {
|
|
534
620
|
if (undefined === ev.viewport)
|
|
535
621
|
return false;
|
|
536
|
-
const
|
|
537
|
-
if (undefined ===
|
|
538
|
-
return this.
|
|
539
|
-
|
|
622
|
+
const id = this.wantAdditionalSubEntities ? this.getCurrentElement() : undefined;
|
|
623
|
+
if (undefined === id)
|
|
624
|
+
return this.changeCurrentSubEntity();
|
|
625
|
+
if (this._subEntityGraphicPending)
|
|
626
|
+
return false;
|
|
627
|
+
this._subEntityGraphicPending = true;
|
|
628
|
+
const current = await this.doPickSubEntities(id, ev);
|
|
540
629
|
const chordTolerance = current ? (0, CreateElementTool_1.computeChordToleranceFromPoint)(ev.viewport, core_geometry_1.Point3d.fromJSON(current[0].point)) : 0.0;
|
|
541
|
-
|
|
630
|
+
const status = await this.changeCurrentSubEntity(id, current ? current[0] : undefined, chordTolerance);
|
|
631
|
+
this._subEntityGraphicPending = undefined;
|
|
632
|
+
if (status)
|
|
633
|
+
core_frontend_1.IModelApp.viewManager.invalidateDecorationsAllViews();
|
|
634
|
+
return status;
|
|
635
|
+
}
|
|
636
|
+
async createSubEntityGraphic(id, data, chordTolerance) {
|
|
637
|
+
try {
|
|
638
|
+
const opts = {
|
|
639
|
+
wantGraphic: true,
|
|
640
|
+
wantRange: true,
|
|
641
|
+
wantAppearance: true,
|
|
642
|
+
chordTolerance,
|
|
643
|
+
};
|
|
644
|
+
data.chordTolerance = chordTolerance;
|
|
645
|
+
data.geometry = await ElementGeometryCacheTool.callCommand("getSubEntityGeometry", id, data.props, opts);
|
|
646
|
+
return await data.createGraphic(this.iModel);
|
|
647
|
+
}
|
|
648
|
+
catch (err) {
|
|
542
649
|
return false;
|
|
543
|
-
|
|
544
|
-
return true;
|
|
650
|
+
}
|
|
545
651
|
}
|
|
546
652
|
async updateGraphic(ev, isDynamics) {
|
|
547
653
|
if (isDynamics)
|
|
548
654
|
return super.updateGraphic(ev, isDynamics);
|
|
549
|
-
await this.
|
|
655
|
+
await this.updateCurrentSubEntity(ev);
|
|
550
656
|
}
|
|
551
|
-
async applyAgendaOperation(_ev, _isAccept) { return undefined; }
|
|
552
657
|
async getGraphicData(ev) {
|
|
553
658
|
const result = await this.applyAgendaOperation(ev, false);
|
|
554
659
|
return result === null || result === void 0 ? void 0 : result.graphic;
|
|
555
660
|
}
|
|
661
|
+
async applyAgendaOperation(_ev, _isAccept) { return undefined; }
|
|
556
662
|
async processAgenda(ev) {
|
|
557
|
-
if (undefined === this._acceptedSubEntity)
|
|
558
|
-
return;
|
|
559
663
|
const result = await this.applyAgendaOperation(ev, true);
|
|
560
664
|
if (result === null || result === void 0 ? void 0 : result.elementId)
|
|
561
665
|
await this.saveChanges();
|
|
562
666
|
}
|
|
667
|
+
async onModifierKeyTransition(wentDown, modifier, event) {
|
|
668
|
+
if (core_frontend_1.EventHandled.Yes === await super.onModifierKeyTransition(wentDown, modifier, event))
|
|
669
|
+
return core_frontend_1.EventHandled.Yes;
|
|
670
|
+
if (core_frontend_1.BeModifierKeys.Control !== modifier)
|
|
671
|
+
return core_frontend_1.EventHandled.No;
|
|
672
|
+
if (core_frontend_1.IModelApp.toolAdmin.isLocateCircleOn === this.wantAdditionalSubEntities)
|
|
673
|
+
return core_frontend_1.EventHandled.No;
|
|
674
|
+
this.setupAndPromptForNextAction();
|
|
675
|
+
return core_frontend_1.EventHandled.Yes;
|
|
676
|
+
}
|
|
677
|
+
changeLocateState(enableLocate, enableSnap, cursor, coordLockOvr) {
|
|
678
|
+
super.changeLocateState(enableLocate, enableSnap, cursor, coordLockOvr);
|
|
679
|
+
// Keep showing locate circle when identifing sub-entities even if done locating elements...
|
|
680
|
+
if (!core_frontend_1.IModelApp.toolAdmin.isLocateCircleOn && this.wantAdditionalSubEntities)
|
|
681
|
+
core_frontend_1.IModelApp.toolAdmin.setLocateCircleOn(true);
|
|
682
|
+
}
|
|
683
|
+
get shouldEnableSnap() {
|
|
684
|
+
if (this.isSelectByPoints || !this.wantAccuSnap)
|
|
685
|
+
return false;
|
|
686
|
+
if (this.isDynamicsStarted)
|
|
687
|
+
return true;
|
|
688
|
+
const isCtrlSelect = (this.isControlDown && (this.controlKeyContinuesSelection || this.allowSubEntityControlSelect));
|
|
689
|
+
if (isCtrlSelect || this.wantAdditionalElements || this.wantAdditionalSubEntities)
|
|
690
|
+
return this.wantSubEntitySnap;
|
|
691
|
+
return !this.wantSubEntitySnap;
|
|
692
|
+
}
|
|
563
693
|
setupAccuDraw() { }
|
|
564
694
|
setupAndPromptForNextAction() {
|
|
565
695
|
this.setupAccuDraw();
|
|
566
696
|
super.setupAndPromptForNextAction();
|
|
567
697
|
}
|
|
698
|
+
clearSubEntityGraphics() {
|
|
699
|
+
if (undefined !== this._currentSubEntity)
|
|
700
|
+
this._currentSubEntity.cleanupGraphic();
|
|
701
|
+
this._acceptedSubEntities.forEach((entry) => { entry.cleanupGraphic(); });
|
|
702
|
+
}
|
|
568
703
|
async onCleanup() {
|
|
569
|
-
this.
|
|
704
|
+
this.clearSubEntityGraphics();
|
|
570
705
|
return super.onCleanup();
|
|
571
706
|
}
|
|
572
707
|
}
|
|
573
708
|
exports.LocateSubEntityTool = LocateSubEntityTool;
|
|
574
|
-
/** @alpha Identify faces of solids and surfaces to offset. */
|
|
575
|
-
class OffsetFacesTool extends LocateSubEntityTool {
|
|
576
|
-
requireWriteableTarget() { return false; } // TODO: Testing...
|
|
577
|
-
get wantDynamics() { return true; }
|
|
578
|
-
get wantAccuSnap() { return undefined !== this._acceptedSubEntity; }
|
|
579
|
-
get geometryCacheFilter() {
|
|
580
|
-
return { minGeom: 1, maxGeom: 1, parts: true, curves: false, surfaces: true, solids: true, other: false };
|
|
581
|
-
}
|
|
582
|
-
async applyAgendaOperation(ev, isAccept) {
|
|
583
|
-
var _a, _b;
|
|
584
|
-
if (undefined === ev.viewport || this.agenda.isEmpty || undefined === ((_a = this._acceptedSubEntity) === null || _a === void 0 ? void 0 : _a.point) || undefined === ((_b = this._acceptedSubEntity) === null || _b === void 0 ? void 0 : _b.normal))
|
|
585
|
-
return undefined;
|
|
586
|
-
const facePt = core_geometry_1.Point3d.fromJSON(this._acceptedSubEntity.point);
|
|
587
|
-
const faceNormal = core_geometry_1.Vector3d.fromJSON(this._acceptedSubEntity.normal);
|
|
588
|
-
const projPt = core_frontend_1.AccuDrawHintBuilder.projectPointToLineInView(ev.point, facePt, faceNormal, ev.viewport);
|
|
589
|
-
if (undefined === projPt)
|
|
590
|
-
return undefined;
|
|
591
|
-
const offsetDir = core_geometry_1.Vector3d.createStartEnd(facePt, projPt);
|
|
592
|
-
let offset = offsetDir.magnitude();
|
|
593
|
-
if (offset < core_geometry_1.Geometry.smallMetricDistance)
|
|
594
|
-
return undefined;
|
|
595
|
-
if (offsetDir.dotProduct(faceNormal) < 0.0)
|
|
596
|
-
offset = -offset;
|
|
597
|
-
try {
|
|
598
|
-
this._startedCmd = await this.startCommand();
|
|
599
|
-
const params = { faces: this._acceptedSubEntity.subEntity, distances: offset };
|
|
600
|
-
const opts = {
|
|
601
|
-
wantGraphic: isAccept ? undefined : true,
|
|
602
|
-
chordTolerance: (0, CreateElementTool_1.computeChordToleranceFromPoint)(ev.viewport, ev.point),
|
|
603
|
-
requestId: `${this.toolId}:${this.agenda.elements[0]}`,
|
|
604
|
-
writeChanges: isAccept ? true : undefined,
|
|
605
|
-
};
|
|
606
|
-
return await ElementGeometryCacheTool.callCommand("offsetFaces", this.agenda.elements[0], params, opts);
|
|
607
|
-
}
|
|
608
|
-
catch (err) {
|
|
609
|
-
return undefined;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
setupAccuDraw() {
|
|
613
|
-
var _a, _b;
|
|
614
|
-
if (undefined === ((_a = this._acceptedSubEntity) === null || _a === void 0 ? void 0 : _a.point) || undefined === ((_b = this._acceptedSubEntity) === null || _b === void 0 ? void 0 : _b.normal))
|
|
615
|
-
return;
|
|
616
|
-
const facePt = core_geometry_1.Point3d.fromJSON(this._acceptedSubEntity.point);
|
|
617
|
-
const faceNormal = core_geometry_1.Vector3d.fromJSON(this._acceptedSubEntity.normal);
|
|
618
|
-
const hints = new core_frontend_1.AccuDrawHintBuilder();
|
|
619
|
-
hints.setOriginFixed = true;
|
|
620
|
-
hints.setLockY = true;
|
|
621
|
-
hints.setLockZ = true;
|
|
622
|
-
hints.setModeRectangular();
|
|
623
|
-
hints.setOrigin(facePt);
|
|
624
|
-
hints.setXAxis2(faceNormal);
|
|
625
|
-
hints.sendHints();
|
|
626
|
-
}
|
|
627
|
-
async onRestartTool() {
|
|
628
|
-
const tool = new OffsetFacesTool();
|
|
629
|
-
if (!await tool.run())
|
|
630
|
-
return this.exitTool();
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
exports.OffsetFacesTool = OffsetFacesTool;
|
|
634
|
-
OffsetFacesTool.toolId = "OffsetFaces";
|
|
635
|
-
OffsetFacesTool.iconSpec = "icon-move"; // TODO: Need better icon...
|
|
636
|
-
/** @alpha Identify faces to offset to hollow solids. */
|
|
637
|
-
class HollowFacesTool extends LocateSubEntityTool {
|
|
638
|
-
get geometryCacheFilter() {
|
|
639
|
-
return { minGeom: 1, maxGeom: 1, parts: true, curves: false, surfaces: false, solids: true, other: false };
|
|
640
|
-
}
|
|
641
|
-
async applyAgendaOperation(ev, isAccept) {
|
|
642
|
-
if (undefined === ev.viewport || this.agenda.isEmpty || undefined === this._acceptedSubEntity)
|
|
643
|
-
return undefined;
|
|
644
|
-
// TODO: Tool settings for shell thickness and face thickness...
|
|
645
|
-
const shellThickness = 0.1;
|
|
646
|
-
const faceThickness = 0.0;
|
|
647
|
-
try {
|
|
648
|
-
this._startedCmd = await this.startCommand();
|
|
649
|
-
const params = { faces: this._acceptedSubEntity.subEntity, distances: faceThickness, defaultDistance: shellThickness };
|
|
650
|
-
const opts = {
|
|
651
|
-
wantGraphic: isAccept ? undefined : true,
|
|
652
|
-
chordTolerance: (0, CreateElementTool_1.computeChordToleranceFromPoint)(ev.viewport, ev.point),
|
|
653
|
-
requestId: `${this.toolId}:${this.agenda.elements[0]}`,
|
|
654
|
-
writeChanges: isAccept ? true : undefined,
|
|
655
|
-
};
|
|
656
|
-
return await ElementGeometryCacheTool.callCommand("hollowFaces", this.agenda.elements[0], params, opts);
|
|
657
|
-
}
|
|
658
|
-
catch (err) {
|
|
659
|
-
return undefined;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
async onRestartTool() {
|
|
663
|
-
const tool = new HollowFacesTool();
|
|
664
|
-
if (!await tool.run())
|
|
665
|
-
return this.exitTool();
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
exports.HollowFacesTool = HollowFacesTool;
|
|
669
|
-
HollowFacesTool.toolId = "HollowFaces";
|
|
670
|
-
HollowFacesTool.iconSpec = "icon-move"; // TODO: Need better icon...
|
|
671
709
|
//# sourceMappingURL=ElementGeometryTool.js.map
|