@itwin/presentation-backend 4.0.0-dev.8 → 4.0.0-dev.80

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 (59) hide show
  1. package/CHANGELOG.md +47 -1
  2. package/lib/cjs/assets/supplemental-presentation-rules/BisCore.PresentationRuleSet.json +5 -3
  3. package/lib/cjs/presentation-backend/BackendLoggerCategory.d.ts +41 -41
  4. package/lib/cjs/presentation-backend/BackendLoggerCategory.js +50 -50
  5. package/lib/cjs/presentation-backend/Constants.d.ts +8 -8
  6. package/lib/cjs/presentation-backend/Constants.js +40 -36
  7. package/lib/cjs/presentation-backend/Constants.js.map +1 -1
  8. package/lib/cjs/presentation-backend/ElementPropertiesHelper.d.ts +11 -11
  9. package/lib/cjs/presentation-backend/ElementPropertiesHelper.js +260 -262
  10. package/lib/cjs/presentation-backend/ElementPropertiesHelper.js.map +1 -1
  11. package/lib/cjs/presentation-backend/NativePlatform.d.ts +87 -87
  12. package/lib/cjs/presentation-backend/NativePlatform.d.ts.map +1 -1
  13. package/lib/cjs/presentation-backend/NativePlatform.js +140 -140
  14. package/lib/cjs/presentation-backend/NativePlatform.js.map +1 -1
  15. package/lib/cjs/presentation-backend/Presentation.d.ts +106 -106
  16. package/lib/cjs/presentation-backend/Presentation.d.ts.map +1 -1
  17. package/lib/cjs/presentation-backend/Presentation.js +148 -150
  18. package/lib/cjs/presentation-backend/Presentation.js.map +1 -1
  19. package/lib/cjs/presentation-backend/PresentationIpcHandler.d.ts +12 -12
  20. package/lib/cjs/presentation-backend/PresentationIpcHandler.js +41 -41
  21. package/lib/cjs/presentation-backend/PresentationManager.d.ts +456 -445
  22. package/lib/cjs/presentation-backend/PresentationManager.d.ts.map +1 -1
  23. package/lib/cjs/presentation-backend/PresentationManager.js +309 -311
  24. package/lib/cjs/presentation-backend/PresentationManager.js.map +1 -1
  25. package/lib/cjs/presentation-backend/PresentationManagerDetail.d.ts +61 -61
  26. package/lib/cjs/presentation-backend/PresentationManagerDetail.js +430 -430
  27. package/lib/cjs/presentation-backend/PresentationManagerDetail.js.map +1 -1
  28. package/lib/cjs/presentation-backend/PresentationRpcImpl.d.ts +62 -62
  29. package/lib/cjs/presentation-backend/PresentationRpcImpl.d.ts.map +1 -1
  30. package/lib/cjs/presentation-backend/PresentationRpcImpl.js +388 -388
  31. package/lib/cjs/presentation-backend/PresentationRpcImpl.js.map +1 -1
  32. package/lib/cjs/presentation-backend/RulesetEmbedder.d.ts +102 -102
  33. package/lib/cjs/presentation-backend/RulesetEmbedder.d.ts.map +1 -1
  34. package/lib/cjs/presentation-backend/RulesetEmbedder.js +284 -279
  35. package/lib/cjs/presentation-backend/RulesetEmbedder.js.map +1 -1
  36. package/lib/cjs/presentation-backend/RulesetManager.d.ts +53 -53
  37. package/lib/cjs/presentation-backend/RulesetManager.js +73 -73
  38. package/lib/cjs/presentation-backend/RulesetVariablesManager.d.ts +140 -140
  39. package/lib/cjs/presentation-backend/RulesetVariablesManager.js +129 -129
  40. package/lib/cjs/presentation-backend/SelectionScopesHelper.d.ts +28 -28
  41. package/lib/cjs/presentation-backend/SelectionScopesHelper.js +210 -213
  42. package/lib/cjs/presentation-backend/SelectionScopesHelper.js.map +1 -1
  43. package/lib/cjs/presentation-backend/TemporaryStorage.d.ts +123 -123
  44. package/lib/cjs/presentation-backend/TemporaryStorage.js +151 -151
  45. package/lib/cjs/presentation-backend/UpdatesTracker.d.ts +27 -27
  46. package/lib/cjs/presentation-backend/UpdatesTracker.js +54 -54
  47. package/lib/cjs/presentation-backend/Utils.d.ts +49 -49
  48. package/lib/cjs/presentation-backend/Utils.d.ts.map +1 -1
  49. package/lib/cjs/presentation-backend/Utils.js +107 -106
  50. package/lib/cjs/presentation-backend/Utils.js.map +1 -1
  51. package/lib/cjs/presentation-backend/domain/PresentationRulesDomain.d.ts +16 -16
  52. package/lib/cjs/presentation-backend/domain/PresentationRulesDomain.js +55 -51
  53. package/lib/cjs/presentation-backend/domain/PresentationRulesDomain.js.map +1 -1
  54. package/lib/cjs/presentation-backend/domain/RulesetElements.d.ts +21 -21
  55. package/lib/cjs/presentation-backend/domain/RulesetElements.js +38 -38
  56. package/lib/cjs/presentation-backend.d.ts +19 -19
  57. package/lib/cjs/presentation-backend.js +39 -35
  58. package/lib/cjs/presentation-backend.js.map +1 -1
  59. package/package.json +18 -18
@@ -1,83 +1,82 @@
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
- /** @packageDocumentation
7
- * @module Core
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.SelectionScopesHelper = void 0;
11
- const core_backend_1 = require("@itwin/core-backend");
12
- const core_bentley_1 = require("@itwin/core-bentley");
13
- const presentation_common_1 = require("@itwin/presentation-common");
14
- const Utils_1 = require("./Utils");
15
- /**
16
- * Contains helper methods for computing selection scopes. Will get removed
17
- * once rules-driven scopes are implemented.
18
- *
19
- * @internal
20
- */
21
- class SelectionScopesHelper {
22
- // istanbul ignore next
23
- constructor() { }
24
- static getSelectionScopes() {
25
- const createSelectionScope = (scopeId, label, description) => ({
26
- id: scopeId,
27
- label,
28
- description,
29
- });
30
- return [
31
- createSelectionScope("element", "Element", "Select the picked element"),
32
- createSelectionScope("assembly", "Assembly", "Select parent of the picked element"),
33
- createSelectionScope("top-assembly", "Top Assembly", "Select the topmost parent of the picked element"),
34
- // WIP: temporarily comment-out "category" and "model" scopes since we can't hilite contents of them fast enough
35
- // createSelectionScope("category", "Category", "Select all elements in the picked element's category"),
36
- // createSelectionScope("model", "Model", "Select all elements in the picked element's model"),
37
- ];
38
- }
39
- static getElementKey(iModel, elementId, ancestorLevel) {
40
- var _a, _b, _c, _d;
41
- let currId = elementId;
42
- let parentId = (_b = (_a = iModel.elements.tryGetElementProps(currId)) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.id;
43
- while (parentId && ancestorLevel !== 0) {
44
- currId = parentId;
45
- parentId = (_d = (_c = iModel.elements.tryGetElementProps(currId)) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d.id;
46
- --ancestorLevel;
47
- }
48
- return (0, Utils_1.getElementKey)(iModel, currId);
49
- }
50
- static computeElementSelection(iModel, elementIds, ancestorLevel) {
51
- const parentKeys = new presentation_common_1.KeySet();
52
- elementIds.forEach(skipTransients((id) => {
53
- const key = this.getElementKey(iModel, id, ancestorLevel);
54
- key && parentKeys.add(key);
55
- }));
56
- return parentKeys;
57
- }
58
- static computeCategorySelection(iModel, ids) {
59
- const categoryKeys = new presentation_common_1.KeySet();
60
- ids.forEach(skipTransients((id) => {
61
- const el = iModel.elements.tryGetElement(id);
62
- if (el instanceof core_backend_1.GeometricElement) {
63
- const category = iModel.elements.tryGetElementProps(el.category);
64
- if (category)
65
- categoryKeys.add({ className: category.classFullName, id: category.id });
66
- }
67
- }));
68
- return categoryKeys;
69
- }
70
- static computeModelSelection(iModel, ids) {
71
- const modelKeys = new presentation_common_1.KeySet();
72
- ids.forEach(skipTransients((id) => {
73
- const el = iModel.elements.tryGetElementProps(id);
74
- const model = el ? iModel.models.tryGetModelProps(el.model) : undefined;
75
- if (model)
76
- modelKeys.add({ className: model.classFullName, id: model.id });
77
- }));
78
- return modelKeys;
79
- }
80
- static getRelatedFunctionalElementKey(imodel, graphicalElementId) {
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
+ /** @packageDocumentation
7
+ * @module Core
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.SelectionScopesHelper = void 0;
11
+ const core_backend_1 = require("@itwin/core-backend");
12
+ const core_bentley_1 = require("@itwin/core-bentley");
13
+ const presentation_common_1 = require("@itwin/presentation-common");
14
+ const Utils_1 = require("./Utils");
15
+ /**
16
+ * Contains helper methods for computing selection scopes. Will get removed
17
+ * once rules-driven scopes are implemented.
18
+ *
19
+ * @internal
20
+ */
21
+ class SelectionScopesHelper {
22
+ // istanbul ignore next
23
+ constructor() { }
24
+ static getSelectionScopes() {
25
+ const createSelectionScope = (scopeId, label, description) => ({
26
+ id: scopeId,
27
+ label,
28
+ description,
29
+ });
30
+ return [
31
+ createSelectionScope("element", "Element", "Select the picked element"),
32
+ createSelectionScope("assembly", "Assembly", "Select parent of the picked element"),
33
+ createSelectionScope("top-assembly", "Top Assembly", "Select the topmost parent of the picked element"),
34
+ // WIP: temporarily comment-out "category" and "model" scopes since we can't hilite contents of them fast enough
35
+ // createSelectionScope("category", "Category", "Select all elements in the picked element's category"),
36
+ // createSelectionScope("model", "Model", "Select all elements in the picked element's model"),
37
+ ];
38
+ }
39
+ static getElementKey(iModel, elementId, ancestorLevel) {
40
+ let currId = elementId;
41
+ let parentId = iModel.elements.tryGetElementProps(currId)?.parent?.id;
42
+ while (parentId && ancestorLevel !== 0) {
43
+ currId = parentId;
44
+ parentId = iModel.elements.tryGetElementProps(currId)?.parent?.id;
45
+ --ancestorLevel;
46
+ }
47
+ return (0, Utils_1.getElementKey)(iModel, currId);
48
+ }
49
+ static computeElementSelection(iModel, elementIds, ancestorLevel) {
50
+ const parentKeys = new presentation_common_1.KeySet();
51
+ elementIds.forEach(skipTransients((id) => {
52
+ const key = this.getElementKey(iModel, id, ancestorLevel);
53
+ key && parentKeys.add(key);
54
+ }));
55
+ return parentKeys;
56
+ }
57
+ static computeCategorySelection(iModel, ids) {
58
+ const categoryKeys = new presentation_common_1.KeySet();
59
+ ids.forEach(skipTransients((id) => {
60
+ const el = iModel.elements.tryGetElement(id);
61
+ if (el instanceof core_backend_1.GeometricElement) {
62
+ const category = iModel.elements.tryGetElementProps(el.category);
63
+ if (category)
64
+ categoryKeys.add({ className: category.classFullName, id: category.id });
65
+ }
66
+ }));
67
+ return categoryKeys;
68
+ }
69
+ static computeModelSelection(iModel, ids) {
70
+ const modelKeys = new presentation_common_1.KeySet();
71
+ ids.forEach(skipTransients((id) => {
72
+ const el = iModel.elements.tryGetElementProps(id);
73
+ const model = el ? iModel.models.tryGetModelProps(el.model) : undefined;
74
+ if (model)
75
+ modelKeys.add({ className: model.classFullName, id: model.id });
76
+ }));
77
+ return modelKeys;
78
+ }
79
+ static getRelatedFunctionalElementKey(imodel, graphicalElementId) {
81
80
  const query = `
82
81
  SELECT funcSchemaDef.Name || '.' || funcClassDef.Name funcElClassName, fe.ECInstanceId funcElId
83
82
  FROM bis.Element e
@@ -87,30 +86,29 @@ class SelectionScopesHelper {
87
86
  INNER JOIN meta.ECClassDef funcClassDef ON funcClassDef.ECInstanceId = fe.ECClassId
88
87
  INNER JOIN meta.ECSchemaDef funcSchemaDef ON funcSchemaDef.ECInstanceId = funcClassDef.Schema.Id
89
88
  WHERE e.ECInstanceId = ?
90
- `;
91
- return imodel.withPreparedStatement(query, (stmt) => {
92
- stmt.bindId(1, graphicalElementId);
93
- // istanbul ignore else
94
- if (core_bentley_1.DbResult.BE_SQLITE_ROW === stmt.step()) {
95
- const row = stmt.getRow();
96
- if (row.funcElClassName && row.funcElId)
97
- return { className: row.funcElClassName.replace(".", ":"), id: row.funcElId };
98
- }
99
- return undefined;
100
- });
101
- }
102
- static findFirstRelatedFunctionalElementKey(imodel, graphicalElementId) {
103
- var _a, _b;
104
- let currId = graphicalElementId;
105
- while (currId) {
106
- const relatedFunctionalKey = this.getRelatedFunctionalElementKey(imodel, currId);
107
- if (relatedFunctionalKey)
108
- return relatedFunctionalKey;
109
- currId = (_b = (_a = imodel.elements.tryGetElementProps(currId)) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.id;
110
- }
111
- return undefined;
112
- }
113
- static elementClassDerivesFrom(imodel, elementId, baseClassFullName) {
89
+ `;
90
+ return imodel.withPreparedStatement(query, (stmt) => {
91
+ stmt.bindId(1, graphicalElementId);
92
+ // istanbul ignore else
93
+ if (core_bentley_1.DbResult.BE_SQLITE_ROW === stmt.step()) {
94
+ const row = stmt.getRow();
95
+ if (row.funcElClassName && row.funcElId)
96
+ return { className: row.funcElClassName.replace(".", ":"), id: row.funcElId };
97
+ }
98
+ return undefined;
99
+ });
100
+ }
101
+ static findFirstRelatedFunctionalElementKey(imodel, graphicalElementId) {
102
+ let currId = graphicalElementId;
103
+ while (currId) {
104
+ const relatedFunctionalKey = this.getRelatedFunctionalElementKey(imodel, currId);
105
+ if (relatedFunctionalKey)
106
+ return relatedFunctionalKey;
107
+ currId = imodel.elements.tryGetElementProps(currId)?.parent?.id;
108
+ }
109
+ return undefined;
110
+ }
111
+ static elementClassDerivesFrom(imodel, elementId, baseClassFullName) {
114
112
  const query = `
115
113
  SELECT 1
116
114
  FROM bis.Element e
@@ -118,113 +116,112 @@ class SelectionScopesHelper {
118
116
  INNER JOIN meta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId
119
117
  INNER JOIN meta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id
120
118
  WHERE e.ECInstanceId = ? AND (baseSchema.Name || ':' || baseClass.Name) = ?
121
- `;
122
- return imodel.withPreparedStatement(query, (stmt) => {
123
- stmt.bindId(1, elementId);
124
- stmt.bindString(2, baseClassFullName);
125
- return (core_bentley_1.DbResult.BE_SQLITE_ROW === stmt.step());
126
- });
127
- }
128
- static computeFunctionalElementSelection(iModel, ids) {
129
- const keys = new presentation_common_1.KeySet();
130
- ids.forEach(skipTransients((id) => {
131
- const is3d = this.elementClassDerivesFrom(iModel, id, core_backend_1.GeometricElement3d.classFullName);
132
- if (!is3d) {
133
- // if the input is not a 3d element, we try to find the first related functional element
134
- const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);
135
- if (firstFunctionalKey) {
136
- keys.add(firstFunctionalKey);
137
- return;
138
- }
139
- }
140
- let keyToAdd;
141
- if (is3d) {
142
- // if we're computing scope for a 3d element, try to switch to its related functional element
143
- keyToAdd = this.getRelatedFunctionalElementKey(iModel, id);
144
- }
145
- if (!keyToAdd)
146
- keyToAdd = (0, Utils_1.getElementKey)(iModel, id);
147
- keyToAdd && keys.add(keyToAdd);
148
- }));
149
- return keys;
150
- }
151
- static computeFunctionalAssemblySelection(iModel, ids) {
152
- const keys = new presentation_common_1.KeySet();
153
- ids.forEach(skipTransients((id) => {
154
- let idToGetAssemblyFor = id;
155
- const is3d = this.elementClassDerivesFrom(iModel, id, core_backend_1.GeometricElement3d.classFullName);
156
- if (!is3d) {
157
- // if the input is not a 3d element, we try to find the first related functional element
158
- const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);
159
- if (firstFunctionalKey)
160
- idToGetAssemblyFor = firstFunctionalKey.id;
161
- }
162
- // find the assembly of either the given element or the functional element
163
- const assemblyKey = this.getElementKey(iModel, idToGetAssemblyFor, 1);
164
- let keyToAdd = assemblyKey;
165
- if (is3d && keyToAdd) {
166
- // if we're computing scope for a 3d element, try to switch to its related functional element
167
- const relatedFunctionalKey = this.getRelatedFunctionalElementKey(iModel, keyToAdd.id);
168
- if (relatedFunctionalKey)
169
- keyToAdd = relatedFunctionalKey;
170
- }
171
- keyToAdd && keys.add(keyToAdd);
172
- }));
173
- return keys;
174
- }
175
- static computeFunctionalTopAssemblySelection(iModel, ids) {
176
- const keys = new presentation_common_1.KeySet();
177
- ids.forEach(skipTransients((id) => {
178
- let idToGetAssemblyFor = id;
179
- const is3d = this.elementClassDerivesFrom(iModel, id, core_backend_1.GeometricElement3d.classFullName);
180
- if (!is3d) {
181
- // if the input is not a 3d element, we try to find the first related functional element
182
- const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);
183
- if (firstFunctionalKey)
184
- idToGetAssemblyFor = firstFunctionalKey.id;
185
- }
186
- // find the top assembly of either the given element or the functional element
187
- const topAssemblyKey = this.getElementKey(iModel, idToGetAssemblyFor, Number.MAX_SAFE_INTEGER);
188
- let keyToAdd = topAssemblyKey;
189
- if (is3d && keyToAdd) {
190
- // if we're computing scope for a 3d element, try to switch to its related functional element
191
- const relatedFunctionalKey = this.getRelatedFunctionalElementKey(iModel, keyToAdd.id);
192
- if (relatedFunctionalKey)
193
- keyToAdd = relatedFunctionalKey;
194
- }
195
- keyToAdd && keys.add(keyToAdd);
196
- }));
197
- return keys;
198
- }
199
- static async computeSelection(requestOptions, elementIds, scopeId) {
200
- var _a;
201
- if (!(0, presentation_common_1.isComputeSelectionRequestOptions)(requestOptions)) {
202
- return this.computeSelection({
203
- ...requestOptions,
204
- elementIds: elementIds,
205
- scope: { id: scopeId },
206
- });
207
- }
208
- switch (requestOptions.scope.id) {
209
- case "element": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, (_a = requestOptions.scope.ancestorLevel) !== null && _a !== void 0 ? _a : 0);
210
- case "assembly": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, 1);
211
- case "top-assembly": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, Number.MAX_SAFE_INTEGER);
212
- case "category": return this.computeCategorySelection(requestOptions.imodel, requestOptions.elementIds);
213
- case "model": return this.computeModelSelection(requestOptions.imodel, requestOptions.elementIds);
214
- case "functional":
215
- case "functional-element":
216
- return this.computeFunctionalElementSelection(requestOptions.imodel, requestOptions.elementIds);
217
- case "functional-assembly": return this.computeFunctionalAssemblySelection(requestOptions.imodel, requestOptions.elementIds);
218
- case "functional-top-assembly": return this.computeFunctionalTopAssemblySelection(requestOptions.imodel, requestOptions.elementIds);
219
- }
220
- throw new presentation_common_1.PresentationError(presentation_common_1.PresentationStatus.InvalidArgument, "scopeId");
221
- }
222
- }
223
- exports.SelectionScopesHelper = SelectionScopesHelper;
224
- const skipTransients = (callback) => {
225
- return (id) => {
226
- if (!core_bentley_1.Id64.isTransient(id))
227
- callback(id);
228
- };
229
- };
119
+ `;
120
+ return imodel.withPreparedStatement(query, (stmt) => {
121
+ stmt.bindId(1, elementId);
122
+ stmt.bindString(2, baseClassFullName);
123
+ return (core_bentley_1.DbResult.BE_SQLITE_ROW === stmt.step());
124
+ });
125
+ }
126
+ static computeFunctionalElementSelection(iModel, ids) {
127
+ const keys = new presentation_common_1.KeySet();
128
+ ids.forEach(skipTransients((id) => {
129
+ const is3d = this.elementClassDerivesFrom(iModel, id, core_backend_1.GeometricElement3d.classFullName);
130
+ if (!is3d) {
131
+ // if the input is not a 3d element, we try to find the first related functional element
132
+ const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);
133
+ if (firstFunctionalKey) {
134
+ keys.add(firstFunctionalKey);
135
+ return;
136
+ }
137
+ }
138
+ let keyToAdd;
139
+ if (is3d) {
140
+ // if we're computing scope for a 3d element, try to switch to its related functional element
141
+ keyToAdd = this.getRelatedFunctionalElementKey(iModel, id);
142
+ }
143
+ if (!keyToAdd)
144
+ keyToAdd = (0, Utils_1.getElementKey)(iModel, id);
145
+ keyToAdd && keys.add(keyToAdd);
146
+ }));
147
+ return keys;
148
+ }
149
+ static computeFunctionalAssemblySelection(iModel, ids) {
150
+ const keys = new presentation_common_1.KeySet();
151
+ ids.forEach(skipTransients((id) => {
152
+ let idToGetAssemblyFor = id;
153
+ const is3d = this.elementClassDerivesFrom(iModel, id, core_backend_1.GeometricElement3d.classFullName);
154
+ if (!is3d) {
155
+ // if the input is not a 3d element, we try to find the first related functional element
156
+ const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);
157
+ if (firstFunctionalKey)
158
+ idToGetAssemblyFor = firstFunctionalKey.id;
159
+ }
160
+ // find the assembly of either the given element or the functional element
161
+ const assemblyKey = this.getElementKey(iModel, idToGetAssemblyFor, 1);
162
+ let keyToAdd = assemblyKey;
163
+ if (is3d && keyToAdd) {
164
+ // if we're computing scope for a 3d element, try to switch to its related functional element
165
+ const relatedFunctionalKey = this.getRelatedFunctionalElementKey(iModel, keyToAdd.id);
166
+ if (relatedFunctionalKey)
167
+ keyToAdd = relatedFunctionalKey;
168
+ }
169
+ keyToAdd && keys.add(keyToAdd);
170
+ }));
171
+ return keys;
172
+ }
173
+ static computeFunctionalTopAssemblySelection(iModel, ids) {
174
+ const keys = new presentation_common_1.KeySet();
175
+ ids.forEach(skipTransients((id) => {
176
+ let idToGetAssemblyFor = id;
177
+ const is3d = this.elementClassDerivesFrom(iModel, id, core_backend_1.GeometricElement3d.classFullName);
178
+ if (!is3d) {
179
+ // if the input is not a 3d element, we try to find the first related functional element
180
+ const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);
181
+ if (firstFunctionalKey)
182
+ idToGetAssemblyFor = firstFunctionalKey.id;
183
+ }
184
+ // find the top assembly of either the given element or the functional element
185
+ const topAssemblyKey = this.getElementKey(iModel, idToGetAssemblyFor, Number.MAX_SAFE_INTEGER);
186
+ let keyToAdd = topAssemblyKey;
187
+ if (is3d && keyToAdd) {
188
+ // if we're computing scope for a 3d element, try to switch to its related functional element
189
+ const relatedFunctionalKey = this.getRelatedFunctionalElementKey(iModel, keyToAdd.id);
190
+ if (relatedFunctionalKey)
191
+ keyToAdd = relatedFunctionalKey;
192
+ }
193
+ keyToAdd && keys.add(keyToAdd);
194
+ }));
195
+ return keys;
196
+ }
197
+ static async computeSelection(requestOptions, elementIds, scopeId) {
198
+ if (!(0, presentation_common_1.isComputeSelectionRequestOptions)(requestOptions)) {
199
+ return this.computeSelection({
200
+ ...requestOptions,
201
+ elementIds: elementIds,
202
+ scope: { id: scopeId },
203
+ });
204
+ }
205
+ switch (requestOptions.scope.id) {
206
+ case "element": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, requestOptions.scope.ancestorLevel ?? 0);
207
+ case "assembly": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, 1);
208
+ case "top-assembly": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, Number.MAX_SAFE_INTEGER);
209
+ case "category": return this.computeCategorySelection(requestOptions.imodel, requestOptions.elementIds);
210
+ case "model": return this.computeModelSelection(requestOptions.imodel, requestOptions.elementIds);
211
+ case "functional":
212
+ case "functional-element":
213
+ return this.computeFunctionalElementSelection(requestOptions.imodel, requestOptions.elementIds);
214
+ case "functional-assembly": return this.computeFunctionalAssemblySelection(requestOptions.imodel, requestOptions.elementIds);
215
+ case "functional-top-assembly": return this.computeFunctionalTopAssemblySelection(requestOptions.imodel, requestOptions.elementIds);
216
+ }
217
+ throw new presentation_common_1.PresentationError(presentation_common_1.PresentationStatus.InvalidArgument, "scopeId");
218
+ }
219
+ }
220
+ exports.SelectionScopesHelper = SelectionScopesHelper;
221
+ const skipTransients = (callback) => {
222
+ return (id) => {
223
+ if (!core_bentley_1.Id64.isTransient(id))
224
+ callback(id);
225
+ };
226
+ };
230
227
  //# sourceMappingURL=SelectionScopesHelper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionScopesHelper.js","sourceRoot":"","sources":["../../../src/presentation-backend/SelectionScopesHelper.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,sDAAqF;AACrF,sDAAiE;AACjE,oEAGoC;AACpC,mCAAwC;AAExC;;;;;GAKG;AACH,MAAa,qBAAqB;IAEhC,uBAAuB;IACvB,gBAAwB,CAAC;IAElB,MAAM,CAAC,kBAAkB;QAC9B,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAE,KAAa,EAAE,WAAmB,EAAkB,EAAE,CAAC,CAAC;YACrG,EAAE,EAAE,OAAO;YACX,KAAK;YACL,WAAW;SACZ,CAAC,CAAC;QACH,OAAO;YACL,oBAAoB,CAAC,SAAS,EAAE,SAAS,EAAE,2BAA2B,CAAC;YACvE,oBAAoB,CAAC,UAAU,EAAE,UAAU,EAAE,qCAAqC,CAAC;YACnF,oBAAoB,CAAC,cAAc,EAAE,cAAc,EAAE,iDAAiD,CAAC;YACvG,gHAAgH;YAChH,wGAAwG;YACxG,+FAA+F;SAChG,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,aAAa,CAAC,MAAgB,EAAE,SAAqB,EAAE,aAAqB;;QACzF,IAAI,MAAM,GAAG,SAAS,CAAC;QACvB,IAAI,QAAQ,GAAG,MAAA,MAAA,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,0CAAE,MAAM,0CAAE,EAAE,CAAC;QACtE,OAAO,QAAQ,IAAI,aAAa,KAAK,CAAC,EAAE;YACtC,MAAM,GAAG,QAAQ,CAAC;YAClB,QAAQ,GAAG,MAAA,MAAA,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,0CAAE,MAAM,0CAAE,EAAE,CAAC;YAClE,EAAE,aAAa,CAAC;SACjB;QACD,OAAO,IAAA,qBAAa,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAEO,MAAM,CAAC,uBAAuB,CAAC,MAAgB,EAAE,UAAwB,EAAE,aAAqB;QACtG,MAAM,UAAU,GAAG,IAAI,4BAAM,EAAE,CAAC;QAChC,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE;YACvC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC;YAC1D,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,UAAU,CAAC;IACpB,CAAC;IAEO,MAAM,CAAC,wBAAwB,CAAC,MAAgB,EAAE,GAAiB;QACzE,MAAM,YAAY,GAAG,IAAI,4BAAM,EAAE,CAAC;QAClC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE;YAChC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,EAAE,YAAY,+BAAgB,EAAE;gBAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;gBACjE,IAAI,QAAQ;oBACV,YAAY,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,aAAa,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAG,EAAE,CAAC,CAAC;aAC7E;QACH,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,YAAY,CAAC;IACtB,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,MAAgB,EAAE,GAAiB;QACtE,MAAM,SAAS,GAAG,IAAI,4BAAM,EAAE,CAAC;QAC/B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE;YAChC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACxE,IAAI,KAAK;gBACP,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,aAAa,EAAE,EAAE,EAAE,KAAK,CAAC,EAAG,EAAE,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,MAAM,CAAC,8BAA8B,CAAC,MAAgB,EAAE,kBAA8B;QAC5F,MAAM,KAAK,GAAG;;;;;;;;;OASX,CAAC;QACJ,OAAO,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC,IAAI,EAA2B,EAAE;YAC3E,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;YACnC,uBAAuB;YACvB,IAAI,uBAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,IAAI,EAAE,EAAE;gBAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC1B,IAAI,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,QAAQ;oBACrC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;aACjF;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,oCAAoC,CAAC,MAAgB,EAAE,kBAA8B;;QAClG,IAAI,MAAM,GAA2B,kBAAkB,CAAC;QACxD,OAAO,MAAM,EAAE;YACb,MAAM,oBAAoB,GAAG,IAAI,CAAC,8BAA8B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACjF,IAAI,oBAAoB;gBACtB,OAAO,oBAAoB,CAAC;YAC9B,MAAM,GAAG,MAAA,MAAA,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,0CAAE,MAAM,0CAAE,EAAE,CAAC;SACjE;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,MAAM,CAAC,uBAAuB,CAAC,MAAgB,EAAE,SAAqB,EAAE,iBAAyB;QACvG,MAAM,KAAK,GAAG;;;;;;;OAOX,CAAC;QACJ,OAAO,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC,IAAI,EAAW,EAAE;YAC3D,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YAC1B,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;YACtC,OAAO,CAAC,uBAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,iCAAiC,CAAC,MAAgB,EAAE,GAAiB;QAClF,MAAM,IAAI,GAAG,IAAI,4BAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAQ,EAAE;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,EAAE,iCAAkB,CAAC,aAAa,CAAC,CAAC;YACxF,IAAI,CAAC,IAAI,EAAE;gBACT,wFAAwF;gBACxF,MAAM,kBAAkB,GAAG,IAAI,CAAC,oCAAoC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjF,IAAI,kBAAkB,EAAE;oBACtB,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;oBAC7B,OAAO;iBACR;aACF;YACD,IAAI,QAAiC,CAAC;YACtC,IAAI,IAAI,EAAE;gBACR,6FAA6F;gBAC7F,QAAQ,GAAG,IAAI,CAAC,8BAA8B,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;aAC5D;YACD,IAAI,CAAC,QAAQ;gBACX,QAAQ,GAAG,IAAA,qBAAa,EAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACvC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,MAAM,CAAC,kCAAkC,CAAC,MAAgB,EAAE,GAAiB;QACnF,MAAM,IAAI,GAAG,IAAI,4BAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAQ,EAAE;YACtC,IAAI,kBAAkB,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,EAAE,iCAAkB,CAAC,aAAa,CAAC,CAAC;YACxF,IAAI,CAAC,IAAI,EAAE;gBACT,wFAAwF;gBACxF,MAAM,kBAAkB,GAAG,IAAI,CAAC,oCAAoC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjF,IAAI,kBAAkB;oBACpB,kBAAkB,GAAG,kBAAkB,CAAC,EAAE,CAAC;aAC9C;YACD,0EAA0E;YAC1E,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;YACtE,IAAI,QAAQ,GAAG,WAAW,CAAC;YAC3B,IAAI,IAAI,IAAI,QAAQ,EAAE;gBACpB,6FAA6F;gBAC7F,MAAM,oBAAoB,GAAG,IAAI,CAAC,8BAA8B,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACtF,IAAI,oBAAoB;oBACtB,QAAQ,GAAG,oBAAoB,CAAC;aACnC;YACD,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,MAAM,CAAC,qCAAqC,CAAC,MAAgB,EAAE,GAAiB;QACtF,MAAM,IAAI,GAAG,IAAI,4BAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAQ,EAAE;YACtC,IAAI,kBAAkB,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,EAAE,iCAAkB,CAAC,aAAa,CAAC,CAAC;YACxF,IAAI,CAAC,IAAI,EAAE;gBACT,wFAAwF;gBACxF,MAAM,kBAAkB,GAAG,IAAI,CAAC,oCAAoC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjF,IAAI,kBAAkB;oBACpB,kBAAkB,GAAG,kBAAkB,CAAC,EAAE,CAAC;aAC9C;YACD,8EAA8E;YAC9E,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAC/F,IAAI,QAAQ,GAAG,cAAc,CAAC;YAC9B,IAAI,IAAI,IAAI,QAAQ,EAAE;gBACpB,6FAA6F;gBAC7F,MAAM,oBAAoB,GAAG,IAAI,CAAC,8BAA8B,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACtF,IAAI,oBAAoB;oBACtB,QAAQ,GAAG,oBAAoB,CAAC;aACnC;YACD,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;IAIM,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,cAAiG,EAAE,UAAyB,EAAE,OAAgB;;QACjL,IAAI,CAAC,IAAA,sDAAgC,EAAC,cAAc,CAAC,EAAE;YACrD,OAAO,IAAI,CAAC,gBAAgB,CAAC;gBAC3B,GAAG,cAAc;gBACjB,UAAU,EAAE,UAAW;gBACvB,KAAK,EAAE,EAAE,EAAE,EAAE,OAAQ,EAAE;aACxB,CAAC,CAAC;SACJ;QAED,QAAQ,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE;YAC/B,KAAK,SAAS,CAAC,CAAC,OAAO,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,EAAE,MAAC,cAAc,CAAC,KAAoC,CAAC,aAAa,mCAAI,CAAC,CAAC,CAAC;YAC/K,KAAK,UAAU,CAAC,CAAC,OAAO,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAC1G,KAAK,cAAc,CAAC,CAAC,OAAO,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACpI,KAAK,UAAU,CAAC,CAAC,OAAO,IAAI,CAAC,wBAAwB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;YACxG,KAAK,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC,qBAAqB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;YAClG,KAAK,YAAY,CAAC;YAClB,KAAK,oBAAoB;gBACvB,OAAO,IAAI,CAAC,iCAAiC,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;YAClG,KAAK,qBAAqB,CAAC,CAAC,OAAO,IAAI,CAAC,kCAAkC,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;YAC7H,KAAK,yBAAyB,CAAC,CAAC,OAAO,IAAI,CAAC,qCAAqC,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;SACrI;QACD,MAAM,IAAI,uCAAiB,CAAC,wCAAkB,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IAC7E,CAAC;CAEF;AAvND,sDAuNC;AAED,MAAM,cAAc,GAAG,CAAC,QAAkC,EAAE,EAAE;IAC5D,OAAO,CAAC,EAAc,EAAE,EAAE;QACxB,IAAI,CAAC,mBAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACvB,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { GeometricElement, GeometricElement3d, IModelDb } from \"@itwin/core-backend\";\r\nimport { DbResult, Id64, Id64String } from \"@itwin/core-bentley\";\r\nimport {\r\n ComputeSelectionRequestOptions, ElementSelectionScopeProps, InstanceKey, isComputeSelectionRequestOptions, KeySet, PresentationError,\r\n PresentationStatus, SelectionScope, SelectionScopeRequestOptions,\r\n} from \"@itwin/presentation-common\";\r\nimport { getElementKey } from \"./Utils\";\r\n\r\n/**\r\n * Contains helper methods for computing selection scopes. Will get removed\r\n * once rules-driven scopes are implemented.\r\n *\r\n * @internal\r\n */\r\nexport class SelectionScopesHelper {\r\n\r\n // istanbul ignore next\r\n private constructor() { }\r\n\r\n public static getSelectionScopes(): SelectionScope[] {\r\n const createSelectionScope = (scopeId: string, label: string, description: string): SelectionScope => ({\r\n id: scopeId,\r\n label,\r\n description,\r\n });\r\n return [\r\n createSelectionScope(\"element\", \"Element\", \"Select the picked element\"),\r\n createSelectionScope(\"assembly\", \"Assembly\", \"Select parent of the picked element\"),\r\n createSelectionScope(\"top-assembly\", \"Top Assembly\", \"Select the topmost parent of the picked element\"),\r\n // WIP: temporarily comment-out \"category\" and \"model\" scopes since we can't hilite contents of them fast enough\r\n // createSelectionScope(\"category\", \"Category\", \"Select all elements in the picked element's category\"),\r\n // createSelectionScope(\"model\", \"Model\", \"Select all elements in the picked element's model\"),\r\n ];\r\n }\r\n\r\n private static getElementKey(iModel: IModelDb, elementId: Id64String, ancestorLevel: number) {\r\n let currId = elementId;\r\n let parentId = iModel.elements.tryGetElementProps(currId)?.parent?.id;\r\n while (parentId && ancestorLevel !== 0) {\r\n currId = parentId;\r\n parentId = iModel.elements.tryGetElementProps(currId)?.parent?.id;\r\n --ancestorLevel;\r\n }\r\n return getElementKey(iModel, currId);\r\n }\r\n\r\n private static computeElementSelection(iModel: IModelDb, elementIds: Id64String[], ancestorLevel: number) {\r\n const parentKeys = new KeySet();\r\n elementIds.forEach(skipTransients((id) => {\r\n const key = this.getElementKey(iModel, id, ancestorLevel);\r\n key && parentKeys.add(key);\r\n }));\r\n return parentKeys;\r\n }\r\n\r\n private static computeCategorySelection(iModel: IModelDb, ids: Id64String[]) {\r\n const categoryKeys = new KeySet();\r\n ids.forEach(skipTransients((id) => {\r\n const el = iModel.elements.tryGetElement(id);\r\n if (el instanceof GeometricElement) {\r\n const category = iModel.elements.tryGetElementProps(el.category);\r\n if (category)\r\n categoryKeys.add({ className: category.classFullName, id: category.id! });\r\n }\r\n }));\r\n return categoryKeys;\r\n }\r\n\r\n private static computeModelSelection(iModel: IModelDb, ids: Id64String[]) {\r\n const modelKeys = new KeySet();\r\n ids.forEach(skipTransients((id) => {\r\n const el = iModel.elements.tryGetElementProps(id);\r\n const model = el ? iModel.models.tryGetModelProps(el.model) : undefined;\r\n if (model)\r\n modelKeys.add({ className: model.classFullName, id: model.id! });\r\n }));\r\n return modelKeys;\r\n }\r\n\r\n private static getRelatedFunctionalElementKey(imodel: IModelDb, graphicalElementId: Id64String): InstanceKey | undefined {\r\n const query = `\r\n SELECT funcSchemaDef.Name || '.' || funcClassDef.Name funcElClassName, fe.ECInstanceId funcElId\r\n FROM bis.Element e\r\n LEFT JOIN func.PhysicalElementFulfillsFunction rel1 ON rel1.SourceECInstanceId = e.ECInstanceId\r\n LEFT JOIN func.DrawingGraphicRepresentsFunctionalElement rel2 ON rel2.SourceECInstanceId = e.ECInstanceId\r\n LEFT JOIN func.FunctionalElement fe ON fe.ECInstanceId IN (rel1.TargetECInstanceId, rel2.TargetECInstanceId)\r\n INNER JOIN meta.ECClassDef funcClassDef ON funcClassDef.ECInstanceId = fe.ECClassId\r\n INNER JOIN meta.ECSchemaDef funcSchemaDef ON funcSchemaDef.ECInstanceId = funcClassDef.Schema.Id\r\n WHERE e.ECInstanceId = ?\r\n `;\r\n return imodel.withPreparedStatement(query, (stmt): InstanceKey | undefined => {\r\n stmt.bindId(1, graphicalElementId);\r\n // istanbul ignore else\r\n if (DbResult.BE_SQLITE_ROW === stmt.step()) {\r\n const row = stmt.getRow();\r\n if (row.funcElClassName && row.funcElId)\r\n return { className: row.funcElClassName.replace(\".\", \":\"), id: row.funcElId };\r\n }\r\n return undefined;\r\n });\r\n }\r\n\r\n private static findFirstRelatedFunctionalElementKey(imodel: IModelDb, graphicalElementId: Id64String): InstanceKey | undefined {\r\n let currId: Id64String | undefined = graphicalElementId;\r\n while (currId) {\r\n const relatedFunctionalKey = this.getRelatedFunctionalElementKey(imodel, currId);\r\n if (relatedFunctionalKey)\r\n return relatedFunctionalKey;\r\n currId = imodel.elements.tryGetElementProps(currId)?.parent?.id;\r\n }\r\n return undefined;\r\n }\r\n\r\n private static elementClassDerivesFrom(imodel: IModelDb, elementId: Id64String, baseClassFullName: string): boolean {\r\n const query = `\r\n SELECT 1\r\n FROM bis.Element e\r\n INNER JOIN meta.ClassHasAllBaseClasses baseClassRels ON baseClassRels.SourceECInstanceId = e.ECClassId\r\n INNER JOIN meta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId\r\n INNER JOIN meta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id\r\n WHERE e.ECInstanceId = ? AND (baseSchema.Name || ':' || baseClass.Name) = ?\r\n `;\r\n return imodel.withPreparedStatement(query, (stmt): boolean => {\r\n stmt.bindId(1, elementId);\r\n stmt.bindString(2, baseClassFullName);\r\n return (DbResult.BE_SQLITE_ROW === stmt.step());\r\n });\r\n }\r\n\r\n private static computeFunctionalElementSelection(iModel: IModelDb, ids: Id64String[]) {\r\n const keys = new KeySet();\r\n ids.forEach(skipTransients((id): void => {\r\n const is3d = this.elementClassDerivesFrom(iModel, id, GeometricElement3d.classFullName);\r\n if (!is3d) {\r\n // if the input is not a 3d element, we try to find the first related functional element\r\n const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);\r\n if (firstFunctionalKey) {\r\n keys.add(firstFunctionalKey);\r\n return;\r\n }\r\n }\r\n let keyToAdd: InstanceKey | undefined;\r\n if (is3d) {\r\n // if we're computing scope for a 3d element, try to switch to its related functional element\r\n keyToAdd = this.getRelatedFunctionalElementKey(iModel, id);\r\n }\r\n if (!keyToAdd)\r\n keyToAdd = getElementKey(iModel, id);\r\n keyToAdd && keys.add(keyToAdd);\r\n }));\r\n return keys;\r\n }\r\n\r\n private static computeFunctionalAssemblySelection(iModel: IModelDb, ids: Id64String[]) {\r\n const keys = new KeySet();\r\n ids.forEach(skipTransients((id): void => {\r\n let idToGetAssemblyFor = id;\r\n const is3d = this.elementClassDerivesFrom(iModel, id, GeometricElement3d.classFullName);\r\n if (!is3d) {\r\n // if the input is not a 3d element, we try to find the first related functional element\r\n const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);\r\n if (firstFunctionalKey)\r\n idToGetAssemblyFor = firstFunctionalKey.id;\r\n }\r\n // find the assembly of either the given element or the functional element\r\n const assemblyKey = this.getElementKey(iModel, idToGetAssemblyFor, 1);\r\n let keyToAdd = assemblyKey;\r\n if (is3d && keyToAdd) {\r\n // if we're computing scope for a 3d element, try to switch to its related functional element\r\n const relatedFunctionalKey = this.getRelatedFunctionalElementKey(iModel, keyToAdd.id);\r\n if (relatedFunctionalKey)\r\n keyToAdd = relatedFunctionalKey;\r\n }\r\n keyToAdd && keys.add(keyToAdd);\r\n }));\r\n return keys;\r\n }\r\n\r\n private static computeFunctionalTopAssemblySelection(iModel: IModelDb, ids: Id64String[]) {\r\n const keys = new KeySet();\r\n ids.forEach(skipTransients((id): void => {\r\n let idToGetAssemblyFor = id;\r\n const is3d = this.elementClassDerivesFrom(iModel, id, GeometricElement3d.classFullName);\r\n if (!is3d) {\r\n // if the input is not a 3d element, we try to find the first related functional element\r\n const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);\r\n if (firstFunctionalKey)\r\n idToGetAssemblyFor = firstFunctionalKey.id;\r\n }\r\n // find the top assembly of either the given element or the functional element\r\n const topAssemblyKey = this.getElementKey(iModel, idToGetAssemblyFor, Number.MAX_SAFE_INTEGER);\r\n let keyToAdd = topAssemblyKey;\r\n if (is3d && keyToAdd) {\r\n // if we're computing scope for a 3d element, try to switch to its related functional element\r\n const relatedFunctionalKey = this.getRelatedFunctionalElementKey(iModel, keyToAdd.id);\r\n if (relatedFunctionalKey)\r\n keyToAdd = relatedFunctionalKey;\r\n }\r\n keyToAdd && keys.add(keyToAdd);\r\n }));\r\n return keys;\r\n }\r\n\r\n public static async computeSelection(requestOptions: SelectionScopeRequestOptions<IModelDb>, ids: Id64String[], scopeId: string): Promise<KeySet>;\r\n public static async computeSelection(requestOptions: ComputeSelectionRequestOptions<IModelDb>): Promise<KeySet>;\r\n public static async computeSelection(requestOptions: ComputeSelectionRequestOptions<IModelDb> | SelectionScopeRequestOptions<IModelDb>, elementIds?: Id64String[], scopeId?: string): Promise<KeySet> {\r\n if (!isComputeSelectionRequestOptions(requestOptions)) {\r\n return this.computeSelection({\r\n ...requestOptions,\r\n elementIds: elementIds!,\r\n scope: { id: scopeId! },\r\n });\r\n }\r\n\r\n switch (requestOptions.scope.id) {\r\n case \"element\": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, (requestOptions.scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\r\n case \"assembly\": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, 1);\r\n case \"top-assembly\": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, Number.MAX_SAFE_INTEGER);\r\n case \"category\": return this.computeCategorySelection(requestOptions.imodel, requestOptions.elementIds);\r\n case \"model\": return this.computeModelSelection(requestOptions.imodel, requestOptions.elementIds);\r\n case \"functional\":\r\n case \"functional-element\":\r\n return this.computeFunctionalElementSelection(requestOptions.imodel, requestOptions.elementIds);\r\n case \"functional-assembly\": return this.computeFunctionalAssemblySelection(requestOptions.imodel, requestOptions.elementIds);\r\n case \"functional-top-assembly\": return this.computeFunctionalTopAssemblySelection(requestOptions.imodel, requestOptions.elementIds);\r\n }\r\n throw new PresentationError(PresentationStatus.InvalidArgument, \"scopeId\");\r\n }\r\n\r\n}\r\n\r\nconst skipTransients = (callback: (id: Id64String) => void) => {\r\n return (id: Id64String) => {\r\n if (!Id64.isTransient(id))\r\n callback(id);\r\n };\r\n};\r\n"]}
1
+ {"version":3,"file":"SelectionScopesHelper.js","sourceRoot":"","sources":["../../../src/presentation-backend/SelectionScopesHelper.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,sDAAqF;AACrF,sDAAiE;AACjE,oEAGoC;AACpC,mCAAwC;AAExC;;;;;GAKG;AACH,MAAa,qBAAqB;IAEhC,uBAAuB;IACvB,gBAAwB,CAAC;IAElB,MAAM,CAAC,kBAAkB;QAC9B,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAE,KAAa,EAAE,WAAmB,EAAkB,EAAE,CAAC,CAAC;YACrG,EAAE,EAAE,OAAO;YACX,KAAK;YACL,WAAW;SACZ,CAAC,CAAC;QACH,OAAO;YACL,oBAAoB,CAAC,SAAS,EAAE,SAAS,EAAE,2BAA2B,CAAC;YACvE,oBAAoB,CAAC,UAAU,EAAE,UAAU,EAAE,qCAAqC,CAAC;YACnF,oBAAoB,CAAC,cAAc,EAAE,cAAc,EAAE,iDAAiD,CAAC;YACvG,gHAAgH;YAChH,wGAAwG;YACxG,+FAA+F;SAChG,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,aAAa,CAAC,MAAgB,EAAE,SAAqB,EAAE,aAAqB;QACzF,IAAI,MAAM,GAAG,SAAS,CAAC;QACvB,IAAI,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;QACtE,OAAO,QAAQ,IAAI,aAAa,KAAK,CAAC,EAAE;YACtC,MAAM,GAAG,QAAQ,CAAC;YAClB,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;YAClE,EAAE,aAAa,CAAC;SACjB;QACD,OAAO,IAAA,qBAAa,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAEO,MAAM,CAAC,uBAAuB,CAAC,MAAgB,EAAE,UAAwB,EAAE,aAAqB;QACtG,MAAM,UAAU,GAAG,IAAI,4BAAM,EAAE,CAAC;QAChC,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE;YACvC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC;YAC1D,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,UAAU,CAAC;IACpB,CAAC;IAEO,MAAM,CAAC,wBAAwB,CAAC,MAAgB,EAAE,GAAiB;QACzE,MAAM,YAAY,GAAG,IAAI,4BAAM,EAAE,CAAC;QAClC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE;YAChC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,EAAE,YAAY,+BAAgB,EAAE;gBAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;gBACjE,IAAI,QAAQ;oBACV,YAAY,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,aAAa,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAG,EAAE,CAAC,CAAC;aAC7E;QACH,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,YAAY,CAAC;IACtB,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,MAAgB,EAAE,GAAiB;QACtE,MAAM,SAAS,GAAG,IAAI,4BAAM,EAAE,CAAC;QAC/B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE;YAChC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACxE,IAAI,KAAK;gBACP,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,aAAa,EAAE,EAAE,EAAE,KAAK,CAAC,EAAG,EAAE,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,MAAM,CAAC,8BAA8B,CAAC,MAAgB,EAAE,kBAA8B;QAC5F,MAAM,KAAK,GAAG;;;;;;;;;OASX,CAAC;QACJ,OAAO,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC,IAAI,EAA2B,EAAE;YAC3E,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;YACnC,uBAAuB;YACvB,IAAI,uBAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,IAAI,EAAE,EAAE;gBAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC1B,IAAI,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,QAAQ;oBACrC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;aACjF;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,oCAAoC,CAAC,MAAgB,EAAE,kBAA8B;QAClG,IAAI,MAAM,GAA2B,kBAAkB,CAAC;QACxD,OAAO,MAAM,EAAE;YACb,MAAM,oBAAoB,GAAG,IAAI,CAAC,8BAA8B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACjF,IAAI,oBAAoB;gBACtB,OAAO,oBAAoB,CAAC;YAC9B,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;SACjE;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,MAAM,CAAC,uBAAuB,CAAC,MAAgB,EAAE,SAAqB,EAAE,iBAAyB;QACvG,MAAM,KAAK,GAAG;;;;;;;OAOX,CAAC;QACJ,OAAO,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC,IAAI,EAAW,EAAE;YAC3D,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YAC1B,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;YACtC,OAAO,CAAC,uBAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,iCAAiC,CAAC,MAAgB,EAAE,GAAiB;QAClF,MAAM,IAAI,GAAG,IAAI,4BAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAQ,EAAE;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,EAAE,iCAAkB,CAAC,aAAa,CAAC,CAAC;YACxF,IAAI,CAAC,IAAI,EAAE;gBACT,wFAAwF;gBACxF,MAAM,kBAAkB,GAAG,IAAI,CAAC,oCAAoC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjF,IAAI,kBAAkB,EAAE;oBACtB,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;oBAC7B,OAAO;iBACR;aACF;YACD,IAAI,QAAiC,CAAC;YACtC,IAAI,IAAI,EAAE;gBACR,6FAA6F;gBAC7F,QAAQ,GAAG,IAAI,CAAC,8BAA8B,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;aAC5D;YACD,IAAI,CAAC,QAAQ;gBACX,QAAQ,GAAG,IAAA,qBAAa,EAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACvC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,MAAM,CAAC,kCAAkC,CAAC,MAAgB,EAAE,GAAiB;QACnF,MAAM,IAAI,GAAG,IAAI,4BAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAQ,EAAE;YACtC,IAAI,kBAAkB,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,EAAE,iCAAkB,CAAC,aAAa,CAAC,CAAC;YACxF,IAAI,CAAC,IAAI,EAAE;gBACT,wFAAwF;gBACxF,MAAM,kBAAkB,GAAG,IAAI,CAAC,oCAAoC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjF,IAAI,kBAAkB;oBACpB,kBAAkB,GAAG,kBAAkB,CAAC,EAAE,CAAC;aAC9C;YACD,0EAA0E;YAC1E,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;YACtE,IAAI,QAAQ,GAAG,WAAW,CAAC;YAC3B,IAAI,IAAI,IAAI,QAAQ,EAAE;gBACpB,6FAA6F;gBAC7F,MAAM,oBAAoB,GAAG,IAAI,CAAC,8BAA8B,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACtF,IAAI,oBAAoB;oBACtB,QAAQ,GAAG,oBAAoB,CAAC;aACnC;YACD,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,MAAM,CAAC,qCAAqC,CAAC,MAAgB,EAAE,GAAiB;QACtF,MAAM,IAAI,GAAG,IAAI,4BAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAQ,EAAE;YACtC,IAAI,kBAAkB,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,EAAE,iCAAkB,CAAC,aAAa,CAAC,CAAC;YACxF,IAAI,CAAC,IAAI,EAAE;gBACT,wFAAwF;gBACxF,MAAM,kBAAkB,GAAG,IAAI,CAAC,oCAAoC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjF,IAAI,kBAAkB;oBACpB,kBAAkB,GAAG,kBAAkB,CAAC,EAAE,CAAC;aAC9C;YACD,8EAA8E;YAC9E,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAC/F,IAAI,QAAQ,GAAG,cAAc,CAAC;YAC9B,IAAI,IAAI,IAAI,QAAQ,EAAE;gBACpB,6FAA6F;gBAC7F,MAAM,oBAAoB,GAAG,IAAI,CAAC,8BAA8B,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACtF,IAAI,oBAAoB;oBACtB,QAAQ,GAAG,oBAAoB,CAAC;aACnC;YACD,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;IAIM,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,cAAiG,EAAE,UAAyB,EAAE,OAAgB;QACjL,IAAI,CAAC,IAAA,sDAAgC,EAAC,cAAc,CAAC,EAAE;YACrD,OAAO,IAAI,CAAC,gBAAgB,CAAC;gBAC3B,GAAG,cAAc;gBACjB,UAAU,EAAE,UAAW;gBACvB,KAAK,EAAE,EAAE,EAAE,EAAE,OAAQ,EAAE;aACxB,CAAC,CAAC;SACJ;QAED,QAAQ,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE;YAC/B,KAAK,SAAS,CAAC,CAAC,OAAO,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,EAAG,cAAc,CAAC,KAAoC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC;YAC/K,KAAK,UAAU,CAAC,CAAC,OAAO,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAC1G,KAAK,cAAc,CAAC,CAAC,OAAO,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACpI,KAAK,UAAU,CAAC,CAAC,OAAO,IAAI,CAAC,wBAAwB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;YACxG,KAAK,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC,qBAAqB,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;YAClG,KAAK,YAAY,CAAC;YAClB,KAAK,oBAAoB;gBACvB,OAAO,IAAI,CAAC,iCAAiC,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;YAClG,KAAK,qBAAqB,CAAC,CAAC,OAAO,IAAI,CAAC,kCAAkC,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;YAC7H,KAAK,yBAAyB,CAAC,CAAC,OAAO,IAAI,CAAC,qCAAqC,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;SACrI;QACD,MAAM,IAAI,uCAAiB,CAAC,wCAAkB,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IAC7E,CAAC;CAEF;AAvND,sDAuNC;AAED,MAAM,cAAc,GAAG,CAAC,QAAkC,EAAE,EAAE;IAC5D,OAAO,CAAC,EAAc,EAAE,EAAE;QACxB,IAAI,CAAC,mBAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACvB,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { GeometricElement, GeometricElement3d, IModelDb } from \"@itwin/core-backend\";\r\nimport { DbResult, Id64, Id64String } from \"@itwin/core-bentley\";\r\nimport {\r\n ComputeSelectionRequestOptions, ElementSelectionScopeProps, InstanceKey, isComputeSelectionRequestOptions, KeySet, PresentationError,\r\n PresentationStatus, SelectionScope, SelectionScopeRequestOptions,\r\n} from \"@itwin/presentation-common\";\r\nimport { getElementKey } from \"./Utils\";\r\n\r\n/**\r\n * Contains helper methods for computing selection scopes. Will get removed\r\n * once rules-driven scopes are implemented.\r\n *\r\n * @internal\r\n */\r\nexport class SelectionScopesHelper {\r\n\r\n // istanbul ignore next\r\n private constructor() { }\r\n\r\n public static getSelectionScopes(): SelectionScope[] {\r\n const createSelectionScope = (scopeId: string, label: string, description: string): SelectionScope => ({\r\n id: scopeId,\r\n label,\r\n description,\r\n });\r\n return [\r\n createSelectionScope(\"element\", \"Element\", \"Select the picked element\"),\r\n createSelectionScope(\"assembly\", \"Assembly\", \"Select parent of the picked element\"),\r\n createSelectionScope(\"top-assembly\", \"Top Assembly\", \"Select the topmost parent of the picked element\"),\r\n // WIP: temporarily comment-out \"category\" and \"model\" scopes since we can't hilite contents of them fast enough\r\n // createSelectionScope(\"category\", \"Category\", \"Select all elements in the picked element's category\"),\r\n // createSelectionScope(\"model\", \"Model\", \"Select all elements in the picked element's model\"),\r\n ];\r\n }\r\n\r\n private static getElementKey(iModel: IModelDb, elementId: Id64String, ancestorLevel: number) {\r\n let currId = elementId;\r\n let parentId = iModel.elements.tryGetElementProps(currId)?.parent?.id;\r\n while (parentId && ancestorLevel !== 0) {\r\n currId = parentId;\r\n parentId = iModel.elements.tryGetElementProps(currId)?.parent?.id;\r\n --ancestorLevel;\r\n }\r\n return getElementKey(iModel, currId);\r\n }\r\n\r\n private static computeElementSelection(iModel: IModelDb, elementIds: Id64String[], ancestorLevel: number) {\r\n const parentKeys = new KeySet();\r\n elementIds.forEach(skipTransients((id) => {\r\n const key = this.getElementKey(iModel, id, ancestorLevel);\r\n key && parentKeys.add(key);\r\n }));\r\n return parentKeys;\r\n }\r\n\r\n private static computeCategorySelection(iModel: IModelDb, ids: Id64String[]) {\r\n const categoryKeys = new KeySet();\r\n ids.forEach(skipTransients((id) => {\r\n const el = iModel.elements.tryGetElement(id);\r\n if (el instanceof GeometricElement) {\r\n const category = iModel.elements.tryGetElementProps(el.category);\r\n if (category)\r\n categoryKeys.add({ className: category.classFullName, id: category.id! });\r\n }\r\n }));\r\n return categoryKeys;\r\n }\r\n\r\n private static computeModelSelection(iModel: IModelDb, ids: Id64String[]) {\r\n const modelKeys = new KeySet();\r\n ids.forEach(skipTransients((id) => {\r\n const el = iModel.elements.tryGetElementProps(id);\r\n const model = el ? iModel.models.tryGetModelProps(el.model) : undefined;\r\n if (model)\r\n modelKeys.add({ className: model.classFullName, id: model.id! });\r\n }));\r\n return modelKeys;\r\n }\r\n\r\n private static getRelatedFunctionalElementKey(imodel: IModelDb, graphicalElementId: Id64String): InstanceKey | undefined {\r\n const query = `\r\n SELECT funcSchemaDef.Name || '.' || funcClassDef.Name funcElClassName, fe.ECInstanceId funcElId\r\n FROM bis.Element e\r\n LEFT JOIN func.PhysicalElementFulfillsFunction rel1 ON rel1.SourceECInstanceId = e.ECInstanceId\r\n LEFT JOIN func.DrawingGraphicRepresentsFunctionalElement rel2 ON rel2.SourceECInstanceId = e.ECInstanceId\r\n LEFT JOIN func.FunctionalElement fe ON fe.ECInstanceId IN (rel1.TargetECInstanceId, rel2.TargetECInstanceId)\r\n INNER JOIN meta.ECClassDef funcClassDef ON funcClassDef.ECInstanceId = fe.ECClassId\r\n INNER JOIN meta.ECSchemaDef funcSchemaDef ON funcSchemaDef.ECInstanceId = funcClassDef.Schema.Id\r\n WHERE e.ECInstanceId = ?\r\n `;\r\n return imodel.withPreparedStatement(query, (stmt): InstanceKey | undefined => {\r\n stmt.bindId(1, graphicalElementId);\r\n // istanbul ignore else\r\n if (DbResult.BE_SQLITE_ROW === stmt.step()) {\r\n const row = stmt.getRow();\r\n if (row.funcElClassName && row.funcElId)\r\n return { className: row.funcElClassName.replace(\".\", \":\"), id: row.funcElId };\r\n }\r\n return undefined;\r\n });\r\n }\r\n\r\n private static findFirstRelatedFunctionalElementKey(imodel: IModelDb, graphicalElementId: Id64String): InstanceKey | undefined {\r\n let currId: Id64String | undefined = graphicalElementId;\r\n while (currId) {\r\n const relatedFunctionalKey = this.getRelatedFunctionalElementKey(imodel, currId);\r\n if (relatedFunctionalKey)\r\n return relatedFunctionalKey;\r\n currId = imodel.elements.tryGetElementProps(currId)?.parent?.id;\r\n }\r\n return undefined;\r\n }\r\n\r\n private static elementClassDerivesFrom(imodel: IModelDb, elementId: Id64String, baseClassFullName: string): boolean {\r\n const query = `\r\n SELECT 1\r\n FROM bis.Element e\r\n INNER JOIN meta.ClassHasAllBaseClasses baseClassRels ON baseClassRels.SourceECInstanceId = e.ECClassId\r\n INNER JOIN meta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId\r\n INNER JOIN meta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id\r\n WHERE e.ECInstanceId = ? AND (baseSchema.Name || ':' || baseClass.Name) = ?\r\n `;\r\n return imodel.withPreparedStatement(query, (stmt): boolean => {\r\n stmt.bindId(1, elementId);\r\n stmt.bindString(2, baseClassFullName);\r\n return (DbResult.BE_SQLITE_ROW === stmt.step());\r\n });\r\n }\r\n\r\n private static computeFunctionalElementSelection(iModel: IModelDb, ids: Id64String[]) {\r\n const keys = new KeySet();\r\n ids.forEach(skipTransients((id): void => {\r\n const is3d = this.elementClassDerivesFrom(iModel, id, GeometricElement3d.classFullName);\r\n if (!is3d) {\r\n // if the input is not a 3d element, we try to find the first related functional element\r\n const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);\r\n if (firstFunctionalKey) {\r\n keys.add(firstFunctionalKey);\r\n return;\r\n }\r\n }\r\n let keyToAdd: InstanceKey | undefined;\r\n if (is3d) {\r\n // if we're computing scope for a 3d element, try to switch to its related functional element\r\n keyToAdd = this.getRelatedFunctionalElementKey(iModel, id);\r\n }\r\n if (!keyToAdd)\r\n keyToAdd = getElementKey(iModel, id);\r\n keyToAdd && keys.add(keyToAdd);\r\n }));\r\n return keys;\r\n }\r\n\r\n private static computeFunctionalAssemblySelection(iModel: IModelDb, ids: Id64String[]) {\r\n const keys = new KeySet();\r\n ids.forEach(skipTransients((id): void => {\r\n let idToGetAssemblyFor = id;\r\n const is3d = this.elementClassDerivesFrom(iModel, id, GeometricElement3d.classFullName);\r\n if (!is3d) {\r\n // if the input is not a 3d element, we try to find the first related functional element\r\n const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);\r\n if (firstFunctionalKey)\r\n idToGetAssemblyFor = firstFunctionalKey.id;\r\n }\r\n // find the assembly of either the given element or the functional element\r\n const assemblyKey = this.getElementKey(iModel, idToGetAssemblyFor, 1);\r\n let keyToAdd = assemblyKey;\r\n if (is3d && keyToAdd) {\r\n // if we're computing scope for a 3d element, try to switch to its related functional element\r\n const relatedFunctionalKey = this.getRelatedFunctionalElementKey(iModel, keyToAdd.id);\r\n if (relatedFunctionalKey)\r\n keyToAdd = relatedFunctionalKey;\r\n }\r\n keyToAdd && keys.add(keyToAdd);\r\n }));\r\n return keys;\r\n }\r\n\r\n private static computeFunctionalTopAssemblySelection(iModel: IModelDb, ids: Id64String[]) {\r\n const keys = new KeySet();\r\n ids.forEach(skipTransients((id): void => {\r\n let idToGetAssemblyFor = id;\r\n const is3d = this.elementClassDerivesFrom(iModel, id, GeometricElement3d.classFullName);\r\n if (!is3d) {\r\n // if the input is not a 3d element, we try to find the first related functional element\r\n const firstFunctionalKey = this.findFirstRelatedFunctionalElementKey(iModel, id);\r\n if (firstFunctionalKey)\r\n idToGetAssemblyFor = firstFunctionalKey.id;\r\n }\r\n // find the top assembly of either the given element or the functional element\r\n const topAssemblyKey = this.getElementKey(iModel, idToGetAssemblyFor, Number.MAX_SAFE_INTEGER);\r\n let keyToAdd = topAssemblyKey;\r\n if (is3d && keyToAdd) {\r\n // if we're computing scope for a 3d element, try to switch to its related functional element\r\n const relatedFunctionalKey = this.getRelatedFunctionalElementKey(iModel, keyToAdd.id);\r\n if (relatedFunctionalKey)\r\n keyToAdd = relatedFunctionalKey;\r\n }\r\n keyToAdd && keys.add(keyToAdd);\r\n }));\r\n return keys;\r\n }\r\n\r\n public static async computeSelection(requestOptions: SelectionScopeRequestOptions<IModelDb>, ids: Id64String[], scopeId: string): Promise<KeySet>;\r\n public static async computeSelection(requestOptions: ComputeSelectionRequestOptions<IModelDb>): Promise<KeySet>;\r\n public static async computeSelection(requestOptions: ComputeSelectionRequestOptions<IModelDb> | SelectionScopeRequestOptions<IModelDb>, elementIds?: Id64String[], scopeId?: string): Promise<KeySet> {\r\n if (!isComputeSelectionRequestOptions(requestOptions)) {\r\n return this.computeSelection({\r\n ...requestOptions,\r\n elementIds: elementIds!,\r\n scope: { id: scopeId! },\r\n });\r\n }\r\n\r\n switch (requestOptions.scope.id) {\r\n case \"element\": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, (requestOptions.scope as ElementSelectionScopeProps).ancestorLevel ?? 0);\r\n case \"assembly\": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, 1);\r\n case \"top-assembly\": return this.computeElementSelection(requestOptions.imodel, requestOptions.elementIds, Number.MAX_SAFE_INTEGER);\r\n case \"category\": return this.computeCategorySelection(requestOptions.imodel, requestOptions.elementIds);\r\n case \"model\": return this.computeModelSelection(requestOptions.imodel, requestOptions.elementIds);\r\n case \"functional\":\r\n case \"functional-element\":\r\n return this.computeFunctionalElementSelection(requestOptions.imodel, requestOptions.elementIds);\r\n case \"functional-assembly\": return this.computeFunctionalAssemblySelection(requestOptions.imodel, requestOptions.elementIds);\r\n case \"functional-top-assembly\": return this.computeFunctionalTopAssemblySelection(requestOptions.imodel, requestOptions.elementIds);\r\n }\r\n throw new PresentationError(PresentationStatus.InvalidArgument, \"scopeId\");\r\n }\r\n\r\n}\r\n\r\nconst skipTransients = (callback: (id: Id64String) => void) => {\r\n return (id: Id64String) => {\r\n if (!Id64.isTransient(id))\r\n callback(id);\r\n };\r\n};\r\n"]}