@itwin/core-frontend 5.4.0-dev.6 → 5.4.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 +70 -1
- package/lib/cjs/IModelApp.d.ts +12 -0
- package/lib/cjs/IModelApp.d.ts.map +1 -1
- package/lib/cjs/IModelApp.js +9 -0
- package/lib/cjs/IModelApp.js.map +1 -1
- package/lib/cjs/IModelConnection.d.ts.map +1 -1
- package/lib/cjs/IModelConnection.js +6 -2
- package/lib/cjs/IModelConnection.js.map +1 -1
- package/lib/cjs/SheetViewState.d.ts +7 -5
- package/lib/cjs/SheetViewState.d.ts.map +1 -1
- package/lib/cjs/SheetViewState.js +52 -683
- package/lib/cjs/SheetViewState.js.map +1 -1
- package/lib/cjs/internal/SheetViewAttachments.d.ts +57 -0
- package/lib/cjs/internal/SheetViewAttachments.d.ts.map +1 -0
- package/lib/cjs/internal/SheetViewAttachments.js +336 -0
- package/lib/cjs/internal/SheetViewAttachments.js.map +1 -0
- package/lib/cjs/internal/ViewAttachmentRenderer.d.ts +32 -0
- package/lib/cjs/internal/ViewAttachmentRenderer.d.ts.map +1 -0
- package/lib/cjs/internal/ViewAttachmentRenderer.js +462 -0
- package/lib/cjs/internal/ViewAttachmentRenderer.js.map +1 -0
- package/lib/cjs/internal/render/webgl/SceneCompositor.js +1 -1
- package/lib/cjs/internal/render/webgl/SceneCompositor.js.map +1 -1
- package/lib/cjs/internal/render/webgl/ShaderBuilder.d.ts.map +1 -1
- package/lib/cjs/internal/render/webgl/ShaderBuilder.js +8 -1
- package/lib/cjs/internal/render/webgl/ShaderBuilder.js.map +1 -1
- package/lib/cjs/properties/AngleDescription.js +4 -4
- package/lib/cjs/properties/AngleDescription.js.map +1 -1
- package/lib/cjs/properties/LengthDescription.js +9 -9
- package/lib/cjs/properties/LengthDescription.js.map +1 -1
- package/lib/cjs/quantity-formatting/QuantityFormatter.d.ts.map +1 -1
- package/lib/cjs/quantity-formatting/QuantityFormatter.js +9 -8
- package/lib/cjs/quantity-formatting/QuantityFormatter.js.map +1 -1
- package/lib/cjs/tools/EventController.js +1 -1
- package/lib/cjs/tools/EventController.js.map +1 -1
- package/lib/cjs/tools/MeasureTool.js +21 -21
- package/lib/cjs/tools/MeasureTool.js.map +1 -1
- package/lib/esm/IModelApp.d.ts +12 -0
- package/lib/esm/IModelApp.d.ts.map +1 -1
- package/lib/esm/IModelApp.js +9 -0
- package/lib/esm/IModelApp.js.map +1 -1
- package/lib/esm/IModelConnection.d.ts.map +1 -1
- package/lib/esm/IModelConnection.js +7 -3
- package/lib/esm/IModelConnection.js.map +1 -1
- package/lib/esm/SheetViewState.d.ts +7 -5
- package/lib/esm/SheetViewState.d.ts.map +1 -1
- package/lib/esm/SheetViewState.js +55 -686
- package/lib/esm/SheetViewState.js.map +1 -1
- package/lib/esm/internal/SheetViewAttachments.d.ts +57 -0
- package/lib/esm/internal/SheetViewAttachments.d.ts.map +1 -0
- package/lib/esm/internal/SheetViewAttachments.js +332 -0
- package/lib/esm/internal/SheetViewAttachments.js.map +1 -0
- package/lib/esm/internal/ViewAttachmentRenderer.d.ts +32 -0
- package/lib/esm/internal/ViewAttachmentRenderer.d.ts.map +1 -0
- package/lib/esm/internal/ViewAttachmentRenderer.js +459 -0
- package/lib/esm/internal/ViewAttachmentRenderer.js.map +1 -0
- package/lib/esm/internal/render/webgl/SceneCompositor.js +1 -1
- package/lib/esm/internal/render/webgl/SceneCompositor.js.map +1 -1
- package/lib/esm/internal/render/webgl/ShaderBuilder.d.ts.map +1 -1
- package/lib/esm/internal/render/webgl/ShaderBuilder.js +8 -1
- package/lib/esm/internal/render/webgl/ShaderBuilder.js.map +1 -1
- package/lib/esm/properties/AngleDescription.js +4 -4
- package/lib/esm/properties/AngleDescription.js.map +1 -1
- package/lib/esm/properties/LengthDescription.js +9 -9
- package/lib/esm/properties/LengthDescription.js.map +1 -1
- package/lib/esm/quantity-formatting/QuantityFormatter.d.ts.map +1 -1
- package/lib/esm/quantity-formatting/QuantityFormatter.js +9 -8
- package/lib/esm/quantity-formatting/QuantityFormatter.js.map +1 -1
- package/lib/esm/tools/EventController.js +1 -1
- package/lib/esm/tools/EventController.js.map +1 -1
- package/lib/esm/tools/MeasureTool.js +21 -21
- package/lib/esm/tools/MeasureTool.js.map +1 -1
- package/lib/public/scripts/parse-imdl-worker.js +1 -1
- package/lib/workers/webpack/parse-imdl-worker.js +1 -1
- package/package.json +21 -21
|
@@ -13,18 +13,10 @@ const core_geometry_1 = require("@itwin/core-geometry");
|
|
|
13
13
|
const core_common_1 = require("@itwin/core-common");
|
|
14
14
|
const CategorySelectorState_1 = require("./CategorySelectorState");
|
|
15
15
|
const DisplayStyleState_1 = require("./DisplayStyleState");
|
|
16
|
-
const GraphicBranch_1 = require("./render/GraphicBranch");
|
|
17
16
|
const Frustum2d_1 = require("./Frustum2d");
|
|
18
|
-
const MockRender_1 = require("./internal/render/MockRender");
|
|
19
|
-
const FeatureSymbology_1 = require("./render/FeatureSymbology");
|
|
20
|
-
const IModelApp_1 = require("./IModelApp");
|
|
21
|
-
const CoordSystem_1 = require("./CoordSystem");
|
|
22
|
-
const Viewport_1 = require("./Viewport");
|
|
23
17
|
const ViewState_1 = require("./ViewState");
|
|
24
|
-
const internal_1 = require("./tile/internal");
|
|
25
|
-
const ImageUtil_1 = require("./common/ImageUtil");
|
|
26
|
-
const ViewRect_1 = require("./common/ViewRect");
|
|
27
18
|
const GraphicType_1 = require("./common/render/GraphicType");
|
|
19
|
+
const SheetViewAttachments_1 = require("./internal/SheetViewAttachments");
|
|
28
20
|
// cSpell:ignore ovrs
|
|
29
21
|
/** Describes the geometry and styling of a sheet border decoration.
|
|
30
22
|
* The sheet border decoration mimics a sheet of paper with a drop shadow.
|
|
@@ -98,189 +90,6 @@ class SheetBorder {
|
|
|
98
90
|
builder.addLineString2d(this._rect, 0);
|
|
99
91
|
}
|
|
100
92
|
}
|
|
101
|
-
/** The information required to instantiate an ViewAttachments object to draw ViewAttachments into a sheet. The list of view attachment Ids is
|
|
102
|
-
* supplied to SheetViewState via the constructor. The corresponding ViewAttachmentProps for each attachment are obtained asynchronously in
|
|
103
|
-
* SheetViewState.load(). The Attachments object is created in SheetViewState.attachToViewport and disposed of in SheetViewState.detachFromViewport.
|
|
104
|
-
*/
|
|
105
|
-
class ViewAttachmentsInfo {
|
|
106
|
-
_attachments;
|
|
107
|
-
get attachments() { return this._attachments; }
|
|
108
|
-
constructor(attachments) {
|
|
109
|
-
this._attachments = attachments;
|
|
110
|
-
}
|
|
111
|
-
get isLoaded() {
|
|
112
|
-
return 0 === this._attachments.length || "string" !== typeof this._attachments[0];
|
|
113
|
-
}
|
|
114
|
-
get viewAttachmentProps() {
|
|
115
|
-
return this.isLoaded ? this._props : [];
|
|
116
|
-
}
|
|
117
|
-
get _props() {
|
|
118
|
-
(0, core_bentley_1.assert)(this.isLoaded);
|
|
119
|
-
return this._attachments;
|
|
120
|
-
}
|
|
121
|
-
get _ids() {
|
|
122
|
-
(0, core_bentley_1.assert)(!this.isLoaded);
|
|
123
|
-
return this._attachments;
|
|
124
|
-
}
|
|
125
|
-
static fromJSON(ids = []) {
|
|
126
|
-
return new ViewAttachmentsInfo(ids);
|
|
127
|
-
}
|
|
128
|
-
toJSON() {
|
|
129
|
-
return this.isLoaded ? this._props.map((x) => (0, core_bentley_1.expectDefined)(x.id)) : [...this._ids];
|
|
130
|
-
}
|
|
131
|
-
clone(iModel) {
|
|
132
|
-
let attachments = this._attachments;
|
|
133
|
-
if (this.isLoaded) {
|
|
134
|
-
// Need to clone the attached ViewStates.
|
|
135
|
-
attachments = attachments.map((attachment) => {
|
|
136
|
-
(0, core_bentley_1.assert)(typeof attachment !== "string");
|
|
137
|
-
return {
|
|
138
|
-
...attachment,
|
|
139
|
-
attachedView: attachment.attachedView.clone(iModel),
|
|
140
|
-
};
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
return new ViewAttachmentsInfo(attachments);
|
|
144
|
-
}
|
|
145
|
-
preload(options) {
|
|
146
|
-
if (this.isLoaded)
|
|
147
|
-
return;
|
|
148
|
-
options.sheetViewAttachmentIds = core_bentley_1.CompressedId64Set.sortAndCompress(this._ids);
|
|
149
|
-
options.viewStateLoadProps = {
|
|
150
|
-
displayStyle: {
|
|
151
|
-
omitScheduleScriptElementIds: !IModelApp_1.IModelApp.tileAdmin.enableFrontendScheduleScripts,
|
|
152
|
-
compressExcludedElementIds: true,
|
|
153
|
-
},
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
async postload(options, iModel) {
|
|
157
|
-
if (options.sheetViewViews === undefined)
|
|
158
|
-
return;
|
|
159
|
-
if (options.sheetViewAttachmentProps === undefined)
|
|
160
|
-
return;
|
|
161
|
-
const viewStateProps = options.sheetViewViews; // This is viewstateProps, need to turn this into ViewState
|
|
162
|
-
const promises = [];
|
|
163
|
-
for (const viewProps of viewStateProps) {
|
|
164
|
-
const loadView = async () => {
|
|
165
|
-
try {
|
|
166
|
-
if (viewProps === undefined)
|
|
167
|
-
return undefined;
|
|
168
|
-
const view = await iModel.views.convertViewStatePropsToViewState(viewProps);
|
|
169
|
-
return view;
|
|
170
|
-
}
|
|
171
|
-
catch {
|
|
172
|
-
return undefined;
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
promises.push(loadView());
|
|
176
|
-
}
|
|
177
|
-
const views = await Promise.all(promises);
|
|
178
|
-
const attachmentProps = options.sheetViewAttachmentProps;
|
|
179
|
-
(0, core_bentley_1.assert)(views.length === attachmentProps.length);
|
|
180
|
-
const attachments = [];
|
|
181
|
-
for (let i = 0; i < views.length; i++) {
|
|
182
|
-
const view = views[i];
|
|
183
|
-
if (view && !(view instanceof SheetViewState)) {
|
|
184
|
-
const props = attachmentProps[i];
|
|
185
|
-
props.attachedView = view;
|
|
186
|
-
attachments.push(props);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
this._attachments = attachments;
|
|
190
|
-
}
|
|
191
|
-
async load(iModel) {
|
|
192
|
-
if (this.isLoaded)
|
|
193
|
-
return;
|
|
194
|
-
const attachmentProps = await iModel.elements.getProps(this._ids);
|
|
195
|
-
const promises = [];
|
|
196
|
-
for (const attachment of attachmentProps) {
|
|
197
|
-
const loadView = async () => {
|
|
198
|
-
try {
|
|
199
|
-
const view = await iModel.views.load(attachment.view.id);
|
|
200
|
-
return view;
|
|
201
|
-
}
|
|
202
|
-
catch {
|
|
203
|
-
return undefined;
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
promises.push(loadView());
|
|
207
|
-
}
|
|
208
|
-
const views = await Promise.all(promises);
|
|
209
|
-
(0, core_bentley_1.assert)(views.length === attachmentProps.length);
|
|
210
|
-
const attachments = [];
|
|
211
|
-
for (let i = 0; i < views.length; i++) {
|
|
212
|
-
const view = views[i];
|
|
213
|
-
if (view && !(view instanceof SheetViewState)) {
|
|
214
|
-
const props = attachmentProps[i];
|
|
215
|
-
props.attachedView = view;
|
|
216
|
-
attachments.push(props);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
this._attachments = attachments;
|
|
220
|
-
}
|
|
221
|
-
createAttachments(sheetView) {
|
|
222
|
-
return this.isLoaded ? new ViewAttachments(this._props, sheetView) : undefined;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
/** The set of view attachments to be displayed in a Viewport via a SheetViewState. Allocated when the view becomes attached to a Viewport;
|
|
226
|
-
* disposed of when it becomes detached from the viewport.
|
|
227
|
-
*/
|
|
228
|
-
class ViewAttachments {
|
|
229
|
-
_attachments = [];
|
|
230
|
-
maxDepth = Frustum2d_1.Frustum2d.minimumZDistance;
|
|
231
|
-
constructor(infos, sheetView) {
|
|
232
|
-
for (const info of infos) {
|
|
233
|
-
const drawAsRaster = info.jsonProperties?.displayOptions?.drawAsRaster || (info.attachedView.is3d() && info.attachedView.isCameraOn);
|
|
234
|
-
const ctor = drawAsRaster ? RasterAttachment : OrthographicAttachment;
|
|
235
|
-
const attachment = new ctor(info.attachedView, info, sheetView);
|
|
236
|
-
this._attachments.push(attachment);
|
|
237
|
-
this.maxDepth = Math.max(this.maxDepth, attachment.zDepth);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
[Symbol.dispose]() {
|
|
241
|
-
for (const attachment of this._attachments)
|
|
242
|
-
attachment[Symbol.dispose]();
|
|
243
|
-
this._attachments.length = 0;
|
|
244
|
-
}
|
|
245
|
-
[Symbol.iterator]() {
|
|
246
|
-
return this._attachments[Symbol.iterator]();
|
|
247
|
-
}
|
|
248
|
-
/** For tests. */
|
|
249
|
-
get attachments() {
|
|
250
|
-
return this._attachments;
|
|
251
|
-
}
|
|
252
|
-
get isEmpty() {
|
|
253
|
-
return 0 === this._attachments.length;
|
|
254
|
-
}
|
|
255
|
-
areAllTileTreesLoaded(displayedExtents) {
|
|
256
|
-
return this._attachments.every((x) => {
|
|
257
|
-
const placement = core_common_1.Placement2d.fromJSON(x.viewAttachmentProps.placement);
|
|
258
|
-
const attachmentRange = placement.calculateRange();
|
|
259
|
-
if (!attachmentRange.intersectsRangeXY(displayedExtents))
|
|
260
|
-
return true;
|
|
261
|
-
return x.areAllTileTreesLoaded;
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
/** Strictly for testing purposes */
|
|
265
|
-
areAllAttachmentsLoaded() {
|
|
266
|
-
return this._attachments.every((attachment) => attachment.areAllTileTreesLoaded);
|
|
267
|
-
}
|
|
268
|
-
discloseTileTrees(trees) {
|
|
269
|
-
for (const attachment of this._attachments)
|
|
270
|
-
trees.disclose(attachment);
|
|
271
|
-
}
|
|
272
|
-
collectStatistics(stats) {
|
|
273
|
-
for (const attachment of this._attachments)
|
|
274
|
-
attachment.collectStatistics(stats);
|
|
275
|
-
}
|
|
276
|
-
addToScene(context) {
|
|
277
|
-
for (const attachment of this._attachments)
|
|
278
|
-
attachment.addToScene(context);
|
|
279
|
-
}
|
|
280
|
-
findById(attachmentId) {
|
|
281
|
-
return this._attachments.find((attachment) => attachment.viewAttachmentProps.id === attachmentId);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
93
|
/** A view of a [SheetModel]($backend).
|
|
285
94
|
* @public
|
|
286
95
|
* @extensions
|
|
@@ -288,11 +97,13 @@ class ViewAttachments {
|
|
|
288
97
|
class SheetViewState extends ViewState_1.ViewState2d {
|
|
289
98
|
/** The width and height of the sheet in world coordinates. */
|
|
290
99
|
sheetSize;
|
|
291
|
-
|
|
292
|
-
_attachments;
|
|
100
|
+
_viewAttachments;
|
|
293
101
|
_viewedExtents;
|
|
102
|
+
_onViewAttachmentsReloaded = () => undefined;
|
|
103
|
+
/** Strictly for tests. */
|
|
104
|
+
onViewAttachmentsReloaded = new core_bentley_1.BeEvent();
|
|
294
105
|
get attachmentIds() {
|
|
295
|
-
return this.
|
|
106
|
+
return this._viewAttachments.attachmentIds;
|
|
296
107
|
}
|
|
297
108
|
static get className() { return "SheetViewDefinition"; }
|
|
298
109
|
static createFromProps(viewStateData, iModel) {
|
|
@@ -303,7 +114,7 @@ class SheetViewState extends ViewState_1.ViewState2d {
|
|
|
303
114
|
}
|
|
304
115
|
toProps() {
|
|
305
116
|
const props = super.toProps();
|
|
306
|
-
props.sheetAttachments = this.
|
|
117
|
+
props.sheetAttachments = [...this.attachmentIds];
|
|
307
118
|
// For sheetProps all that is actually used is the size, so just null out everything else.
|
|
308
119
|
const codeProps = { spec: "", scope: "", value: "" };
|
|
309
120
|
props.sheetProps = {
|
|
@@ -318,20 +129,15 @@ class SheetViewState extends ViewState_1.ViewState2d {
|
|
|
318
129
|
}
|
|
319
130
|
/** Strictly for testing. @internal */
|
|
320
131
|
get viewAttachmentProps() {
|
|
321
|
-
return this.
|
|
322
|
-
return {
|
|
323
|
-
...x,
|
|
324
|
-
attachedView: undefined,
|
|
325
|
-
};
|
|
326
|
-
});
|
|
132
|
+
return this._viewAttachments.attachmentProps;
|
|
327
133
|
}
|
|
328
134
|
/** Strictly for testing. @internal */
|
|
329
135
|
get viewAttachmentInfos() {
|
|
330
|
-
return this.
|
|
136
|
+
return this._viewAttachments.attachmentInfos;
|
|
331
137
|
}
|
|
332
138
|
/** Strictly for testing. @internal */
|
|
333
139
|
get attachments() {
|
|
334
|
-
return this.
|
|
140
|
+
return this._viewAttachments.attachments;
|
|
335
141
|
}
|
|
336
142
|
isDrawingView() { return false; }
|
|
337
143
|
isSheetView() { return true; }
|
|
@@ -340,41 +146,53 @@ class SheetViewState extends ViewState_1.ViewState2d {
|
|
|
340
146
|
if (categories instanceof SheetViewState) {
|
|
341
147
|
// we are coming from clone...
|
|
342
148
|
this.sheetSize = categories.sheetSize.clone();
|
|
343
|
-
this.
|
|
149
|
+
this._viewAttachments = categories._viewAttachments.clone(iModel);
|
|
344
150
|
this._viewedExtents = categories._viewedExtents.clone();
|
|
345
151
|
}
|
|
346
152
|
else {
|
|
347
153
|
this.sheetSize = core_geometry_1.Point2d.create(sheetProps.width, sheetProps.height);
|
|
348
|
-
this.
|
|
154
|
+
this._viewAttachments = SheetViewAttachments_1.SheetViewAttachments.create(attachments);
|
|
349
155
|
const extents = new core_geometry_1.Range3d(0, 0, 0, this.sheetSize.x, this.sheetSize.y, 0);
|
|
350
156
|
const margin = 1.1;
|
|
351
157
|
extents.scaleAboutCenterInPlace(margin);
|
|
352
158
|
this._viewedExtents = extents;
|
|
353
159
|
}
|
|
160
|
+
if (iModel.isBriefcaseConnection()) {
|
|
161
|
+
iModel.txns.onElementsChanged.addListener(async (changes) => {
|
|
162
|
+
let reload = false;
|
|
163
|
+
for (const change of changes.filter({ includeMetadata: (meta) => meta.is("BisCore:ViewAttachment") })) {
|
|
164
|
+
if (change.type === "inserted" || this._viewAttachments.attachmentIds.includes(change.id)) {
|
|
165
|
+
reload = true;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (reload) {
|
|
170
|
+
await this._viewAttachments.reload(this.baseModelId, iModel);
|
|
171
|
+
this._onViewAttachmentsReloaded();
|
|
172
|
+
this.onViewAttachmentsReloaded.raiseEvent();
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
354
176
|
}
|
|
355
177
|
getOrigin() {
|
|
356
178
|
const origin = super.getOrigin();
|
|
357
|
-
|
|
358
|
-
origin.z = -this._attachments.maxDepth;
|
|
179
|
+
origin.z = -this._viewAttachments.maxDepth;
|
|
359
180
|
return origin;
|
|
360
181
|
}
|
|
361
182
|
getExtents() {
|
|
362
183
|
const extents = super.getExtents();
|
|
363
|
-
|
|
364
|
-
extents.z = this._attachments.maxDepth + Frustum2d_1.Frustum2d.minimumZDistance;
|
|
184
|
+
extents.z = this._viewAttachments.maxDepth + Frustum2d_1.Frustum2d.minimumZDistance;
|
|
365
185
|
return extents;
|
|
366
186
|
}
|
|
367
187
|
/** Overrides [[ViewState.discloseTileTrees]] to include tile trees associated with [ViewAttachment]($backend)s displayed on this sheet. */
|
|
368
188
|
discloseTileTrees(trees) {
|
|
369
189
|
super.discloseTileTrees(trees);
|
|
370
|
-
|
|
371
|
-
trees.disclose(this._attachments);
|
|
190
|
+
trees.disclose(this._viewAttachments);
|
|
372
191
|
}
|
|
373
192
|
/** @internal */
|
|
374
193
|
collectNonTileTreeStatistics(stats) {
|
|
375
194
|
super.collectNonTileTreeStatistics(stats);
|
|
376
|
-
|
|
377
|
-
this._attachments.collectStatistics(stats);
|
|
195
|
+
this._viewAttachments.collectStatistics(stats);
|
|
378
196
|
}
|
|
379
197
|
get defaultExtentLimits() {
|
|
380
198
|
return { min: core_geometry_1.Constant.oneMillimeter, max: this.sheetSize.magnitude() * 10 };
|
|
@@ -385,36 +203,23 @@ class SheetViewState extends ViewState_1.ViewState2d {
|
|
|
385
203
|
/** @internal */
|
|
386
204
|
preload(hydrateRequest) {
|
|
387
205
|
super.preload(hydrateRequest);
|
|
388
|
-
this.
|
|
206
|
+
this._viewAttachments.preload(hydrateRequest);
|
|
389
207
|
}
|
|
390
208
|
/** @internal */
|
|
391
209
|
async postload(hydrateResponse) {
|
|
392
210
|
const promises = [];
|
|
393
211
|
promises.push(super.postload(hydrateResponse));
|
|
394
|
-
promises.push(this.
|
|
212
|
+
promises.push(this._viewAttachments.postload(hydrateResponse, this.iModel));
|
|
395
213
|
await Promise.all(promises);
|
|
396
214
|
}
|
|
397
215
|
/** @internal */
|
|
398
216
|
createScene(context) {
|
|
399
217
|
super.createScene(context);
|
|
400
|
-
|
|
401
|
-
this._attachments.addToScene(context);
|
|
218
|
+
this._viewAttachments.addToScene(context);
|
|
402
219
|
}
|
|
403
220
|
/** @internal */
|
|
404
221
|
get secondaryViewports() {
|
|
405
|
-
|
|
406
|
-
return super.secondaryViewports;
|
|
407
|
-
const attachments = this._attachments;
|
|
408
|
-
function* iterator() {
|
|
409
|
-
for (const attachment of attachments) {
|
|
410
|
-
const vp = attachment.viewport;
|
|
411
|
-
if (vp)
|
|
412
|
-
yield vp;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
return {
|
|
416
|
-
[Symbol.iterator]: () => iterator(),
|
|
417
|
-
};
|
|
222
|
+
return this._viewAttachments.getSecondaryViewports();
|
|
418
223
|
}
|
|
419
224
|
/** @internal */
|
|
420
225
|
async queryAttachmentIds() {
|
|
@@ -427,34 +232,38 @@ class SheetViewState extends ViewState_1.ViewState2d {
|
|
|
427
232
|
async changeViewedModel(modelId) {
|
|
428
233
|
await super.changeViewedModel(modelId);
|
|
429
234
|
const attachmentIds = await this.queryAttachmentIds();
|
|
430
|
-
|
|
431
|
-
|
|
235
|
+
(0, core_bentley_1.dispose)(this._viewAttachments);
|
|
236
|
+
this._viewAttachments = SheetViewAttachments_1.SheetViewAttachments.create(attachmentIds);
|
|
432
237
|
}
|
|
433
238
|
/** See [[ViewState.attachToViewport]]. */
|
|
434
239
|
attachToViewport(args) {
|
|
435
240
|
super.attachToViewport(args);
|
|
436
|
-
|
|
437
|
-
|
|
241
|
+
this._viewAttachments.attachToViewport({
|
|
242
|
+
backgroundColor: this.displayStyle.backgroundColor,
|
|
243
|
+
sheetModelId: this.baseModelId,
|
|
244
|
+
});
|
|
245
|
+
this._onViewAttachmentsReloaded = () => args.invalidateController();
|
|
438
246
|
}
|
|
439
247
|
/** See [[ViewState.detachFromViewport]]. */
|
|
440
248
|
detachFromViewport() {
|
|
441
249
|
super.detachFromViewport();
|
|
442
|
-
this.
|
|
250
|
+
this._viewAttachments.detachFromViewport();
|
|
251
|
+
this._onViewAttachmentsReloaded = () => undefined;
|
|
443
252
|
}
|
|
444
253
|
get areAllTileTreesLoaded() {
|
|
254
|
+
if (!super.areAllTileTreesLoaded) {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
445
257
|
let displayedExtents = this._viewedExtents;
|
|
446
258
|
const frustum = this.calculateFrustum();
|
|
447
259
|
if (frustum) {
|
|
448
260
|
displayedExtents = frustum.toRange();
|
|
449
261
|
}
|
|
450
|
-
return
|
|
262
|
+
return this._viewAttachments.areAllTileTreesLoaded(displayedExtents);
|
|
451
263
|
}
|
|
452
264
|
/** @internal Strictly for testing */
|
|
453
265
|
areAllAttachmentsLoaded() {
|
|
454
|
-
|
|
455
|
-
return this._attachments.areAllAttachmentsLoaded();
|
|
456
|
-
}
|
|
457
|
-
return true;
|
|
266
|
+
return this._viewAttachments.areAllAttachmentsLoaded();
|
|
458
267
|
}
|
|
459
268
|
/** Create a sheet border decoration graphic. */
|
|
460
269
|
createBorder(width, height, context) {
|
|
@@ -479,454 +288,14 @@ class SheetViewState extends ViewState_1.ViewState2d {
|
|
|
479
288
|
}
|
|
480
289
|
/** @internal */
|
|
481
290
|
getAttachmentViewport(args) {
|
|
482
|
-
|
|
483
|
-
if (!attachment) {
|
|
484
|
-
return undefined;
|
|
485
|
-
}
|
|
486
|
-
return args.inSectionDrawingAttachment ? attachment.viewport?.view.getAttachmentViewport({ inSectionDrawingAttachment: true }) : attachment.viewport;
|
|
291
|
+
return this._viewAttachments.getAttachmentViewport(args);
|
|
487
292
|
}
|
|
488
293
|
/** @beta */
|
|
489
294
|
computeDisplayTransform(args) {
|
|
490
295
|
// ###TODO we're currently ignoring model and element Id in args, assuming irrelevant for sheets.
|
|
491
296
|
// Should probably call super or have super call us.
|
|
492
|
-
|
|
493
|
-
if (!attachment || !(attachment instanceof OrthographicAttachment)) {
|
|
494
|
-
return undefined;
|
|
495
|
-
}
|
|
496
|
-
const sheetTransform = attachment.toSheet;
|
|
497
|
-
const sectionTransform = args.inSectionDrawingAttachment ? attachment.view.computeDisplayTransform(args) : undefined;
|
|
498
|
-
if (!sectionTransform) {
|
|
499
|
-
return sheetTransform.clone(args.output);
|
|
500
|
-
}
|
|
501
|
-
return sheetTransform.multiplyTransformTransform(sectionTransform, args.output);
|
|
297
|
+
return this._viewAttachments.computeDisplayTransform(args);
|
|
502
298
|
}
|
|
503
299
|
}
|
|
504
300
|
exports.SheetViewState = SheetViewState;
|
|
505
|
-
/** A mostly no-op RenderTarget for an Attachment.
|
|
506
|
-
* its Scene and symbology overrides.
|
|
507
|
-
*/
|
|
508
|
-
class AttachmentTarget extends MockRender_1.MockRender.OffScreenTarget {
|
|
509
|
-
_attachment;
|
|
510
|
-
constructor(attachment) {
|
|
511
|
-
// The dimensions don't matter - we're not drawing anything.
|
|
512
|
-
const rect = new ViewRect_1.ViewRect(1, 1);
|
|
513
|
-
super(IModelApp_1.IModelApp.renderSystem, rect);
|
|
514
|
-
this._attachment = attachment;
|
|
515
|
-
}
|
|
516
|
-
changeScene(scene) {
|
|
517
|
-
this._attachment.scene = scene;
|
|
518
|
-
}
|
|
519
|
-
overrideFeatureSymbology(ovrs) {
|
|
520
|
-
this._attachment.symbologyOverrides = ovrs;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
/** Draws the contents a 2d or orthographic 3d view directly into a sheet view.
|
|
524
|
-
* We select tiles for the view in the context of a light-weight offscreen viewport with a no-op RenderTarget, then
|
|
525
|
-
* collect the resultant graphics and add them to the sheet view's scene.
|
|
526
|
-
*/
|
|
527
|
-
class OrthographicAttachment {
|
|
528
|
-
_viewport;
|
|
529
|
-
_props;
|
|
530
|
-
_sheetModelId;
|
|
531
|
-
_viewFlagOverrides;
|
|
532
|
-
_toSheet;
|
|
533
|
-
_fromSheet;
|
|
534
|
-
_sizeInMeters;
|
|
535
|
-
_range;
|
|
536
|
-
_viewRect = new ViewRect_1.ViewRect(0, 0, 1, 1);
|
|
537
|
-
_originalFrustum = new core_common_1.Frustum();
|
|
538
|
-
_clipVolume;
|
|
539
|
-
_hiddenLineSettings;
|
|
540
|
-
_scale;
|
|
541
|
-
_debugFeatureTable;
|
|
542
|
-
scene;
|
|
543
|
-
symbologyOverrides;
|
|
544
|
-
zDepth;
|
|
545
|
-
get view() {
|
|
546
|
-
return this._viewport.view;
|
|
547
|
-
}
|
|
548
|
-
get viewAttachmentProps() {
|
|
549
|
-
return this._props;
|
|
550
|
-
}
|
|
551
|
-
get viewport() {
|
|
552
|
-
return this._viewport;
|
|
553
|
-
}
|
|
554
|
-
constructor(view, props, sheetView) {
|
|
555
|
-
this.symbologyOverrides = new FeatureSymbology_1.FeatureSymbology.Overrides(view);
|
|
556
|
-
const target = new AttachmentTarget(this);
|
|
557
|
-
this._viewport = Viewport_1.OffScreenViewport.createViewport(view, target, true);
|
|
558
|
-
this._props = props;
|
|
559
|
-
this._sheetModelId = sheetView.baseModelId;
|
|
560
|
-
const applyClip = true; // set to false for debugging
|
|
561
|
-
this._viewFlagOverrides = {
|
|
562
|
-
...view.viewFlags,
|
|
563
|
-
clipVolume: applyClip,
|
|
564
|
-
lighting: false,
|
|
565
|
-
shadows: false,
|
|
566
|
-
};
|
|
567
|
-
const placement = core_common_1.Placement2d.fromJSON(props.placement);
|
|
568
|
-
const range = placement.calculateRange();
|
|
569
|
-
this._range = range;
|
|
570
|
-
this._sizeInMeters = new core_geometry_1.Point2d(range.xLength(), range.yLength());
|
|
571
|
-
// Compute transform from attached view's world coordinates to sheet's world coordinates.
|
|
572
|
-
// NB: We obtain the extents and origin from the *viewport* not the *view* - they may have been adjusted by the viewport.
|
|
573
|
-
const applySkew = true; // set to false for debugging
|
|
574
|
-
const skew = applySkew ? view.getAspectRatioSkew() : 1;
|
|
575
|
-
const extents = this._viewport.viewingSpace.viewDelta.clone();
|
|
576
|
-
const zDepth = Math.abs(extents.z);
|
|
577
|
-
const scaleX = this._sizeInMeters.x / Math.abs(extents.x);
|
|
578
|
-
const scaleY = skew * this._sizeInMeters.y / Math.abs(extents.y);
|
|
579
|
-
this._scale = { x: 1 / scaleX, y: 1 / scaleY };
|
|
580
|
-
const zBias = Frustum2d_1.Frustum2d.depthFromDisplayPriority(props.jsonProperties?.displayPriority ?? 0);
|
|
581
|
-
this.zDepth = 1.01 * (zDepth - zBias); // give a little padding so that geometry right up against far plane doesn't get clipped.
|
|
582
|
-
// View origin is at the *back* of the view. Align *front* of view based on display priority.
|
|
583
|
-
const viewRot = view.getRotation();
|
|
584
|
-
const viewOrg = viewRot.multiplyVector(this._viewport.viewingSpace.viewOrigin);
|
|
585
|
-
viewOrg.z += zDepth;
|
|
586
|
-
viewRot.multiplyTransposeVectorInPlace(viewOrg);
|
|
587
|
-
const matrix = core_geometry_1.Matrix3d.createScale(scaleX, scaleY, 1);
|
|
588
|
-
matrix.multiplyMatrixMatrix(viewRot, matrix);
|
|
589
|
-
const origin = core_geometry_1.Matrix3d.xyzMinusMatrixTimesXYZ(viewOrg, matrix, viewOrg);
|
|
590
|
-
const attachmentOrigin = core_geometry_1.Point3d.createFrom(placement.origin);
|
|
591
|
-
attachmentOrigin.z = zBias;
|
|
592
|
-
const viewOrgToAttachment = attachmentOrigin.minus(viewOrg);
|
|
593
|
-
origin.addInPlace(viewOrgToAttachment);
|
|
594
|
-
this._toSheet = core_geometry_1.Transform.createRefs(origin, matrix);
|
|
595
|
-
this._fromSheet = (0, core_bentley_1.expectDefined)(this._toSheet.inverse());
|
|
596
|
-
// If the attached view is a section drawing, it may itself have an attached spatial view with a clip.
|
|
597
|
-
// The clip needs to be transformed into sheet space.
|
|
598
|
-
if (view.isDrawingView())
|
|
599
|
-
this._viewport.drawingToSheetTransform = this._toSheet;
|
|
600
|
-
// ###TODO? If we also apply the attachment's clip to the attached view, we may get additional culling during tile selection.
|
|
601
|
-
// However the attached view's frustum is already clipped by intersection with sheet view's frustum, and additional clipping planes
|
|
602
|
-
// introduce additional computation, so possibly not worth it.
|
|
603
|
-
// Transform the view's clip (if any) to sheet space
|
|
604
|
-
let viewClip = view.viewFlags.clipVolume ? view.getViewClip()?.clone() : undefined;
|
|
605
|
-
if (viewClip)
|
|
606
|
-
viewClip.transformInPlace(this._toSheet);
|
|
607
|
-
else
|
|
608
|
-
viewClip = core_geometry_1.ClipVector.createEmpty();
|
|
609
|
-
let sheetClip;
|
|
610
|
-
if (undefined !== props.jsonProperties?.clip)
|
|
611
|
-
sheetClip = core_geometry_1.ClipVector.fromJSON(props.jsonProperties?.clip);
|
|
612
|
-
if (sheetClip && sheetClip.isValid) {
|
|
613
|
-
// Clip to view attachment's clip. NB: clip is in sheet coordinate space.
|
|
614
|
-
for (const clip of sheetClip.clips)
|
|
615
|
-
viewClip.clips.push(clip);
|
|
616
|
-
}
|
|
617
|
-
else {
|
|
618
|
-
// Clip to view attachment's bounding box
|
|
619
|
-
viewClip.appendShape([
|
|
620
|
-
core_geometry_1.Point3d.create(this._range.low.x, this._range.low.y),
|
|
621
|
-
core_geometry_1.Point3d.create(this._range.high.x, this._range.low.y),
|
|
622
|
-
core_geometry_1.Point3d.create(this._range.high.x, this._range.high.y),
|
|
623
|
-
core_geometry_1.Point3d.create(this._range.low.x, this._range.high.y),
|
|
624
|
-
]);
|
|
625
|
-
}
|
|
626
|
-
this._clipVolume = IModelApp_1.IModelApp.renderSystem.createClipVolume(viewClip);
|
|
627
|
-
// Save off the original frustum (potentially adjusted by viewport).
|
|
628
|
-
this._viewport.setupFromView();
|
|
629
|
-
this._viewport.viewingSpace.getFrustum(CoordSystem_1.CoordSystem.World, true, this._originalFrustum);
|
|
630
|
-
const applyHiddenLineSettings = true; // for debugging edge display, set to false...
|
|
631
|
-
const style = view.displayStyle;
|
|
632
|
-
if (style.is3d() && applyHiddenLineSettings)
|
|
633
|
-
this._hiddenLineSettings = style.settings.hiddenLineSettings;
|
|
634
|
-
}
|
|
635
|
-
[Symbol.dispose]() {
|
|
636
|
-
this._viewport[Symbol.dispose]();
|
|
637
|
-
}
|
|
638
|
-
discloseTileTrees(trees) {
|
|
639
|
-
trees.disclose(this._viewport);
|
|
640
|
-
}
|
|
641
|
-
addToScene(context) {
|
|
642
|
-
if (context.viewport.freezeScene)
|
|
643
|
-
return;
|
|
644
|
-
if (!context.viewport.view.viewsCategory(this._props.category))
|
|
645
|
-
return;
|
|
646
|
-
const wantBounds = context.viewport.wantViewAttachmentBoundaries;
|
|
647
|
-
const wantClipShapes = context.viewport.wantViewAttachmentClipShapes;
|
|
648
|
-
if (wantBounds || wantClipShapes) {
|
|
649
|
-
const builder = context.createSceneGraphicBuilder();
|
|
650
|
-
if (wantBounds) {
|
|
651
|
-
builder.setSymbology(core_common_1.ColorDef.red, core_common_1.ColorDef.red, 2);
|
|
652
|
-
builder.addRangeBox(this._range);
|
|
653
|
-
}
|
|
654
|
-
if (wantClipShapes && this._clipVolume) {
|
|
655
|
-
builder.setSymbology(core_common_1.ColorDef.blue, core_common_1.ColorDef.blue, 2);
|
|
656
|
-
for (const prim of this._clipVolume.clipVector.clips) {
|
|
657
|
-
if (!(prim instanceof core_geometry_1.ClipShape))
|
|
658
|
-
continue; // ###TODO handle non-shape primitives, if any such ever encountered
|
|
659
|
-
const pts = [];
|
|
660
|
-
const tf = prim.transformFromClip;
|
|
661
|
-
for (const pt of prim.polygon) {
|
|
662
|
-
const tfPt = tf ? tf.multiplyPoint3d(pt) : pt;
|
|
663
|
-
pts.push(new core_geometry_1.Point2d(tfPt.x, tfPt.y));
|
|
664
|
-
}
|
|
665
|
-
builder.addLineString2d(pts, 0);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
// Put into a Batch so that we can see tooltip with attachment Id on mouseover.
|
|
669
|
-
const batch = context.target.renderSystem.createBatch(builder.finish(), this.getDebugFeatureTable(), this._range);
|
|
670
|
-
context.outputGraphic(batch);
|
|
671
|
-
}
|
|
672
|
-
if (!context.viewport.wantViewAttachments)
|
|
673
|
-
return;
|
|
674
|
-
// Pixel size used to compute size of ViewRect so that tiles of appropriate LOD are selected.
|
|
675
|
-
const pixelSize = context.viewport.getPixelSizeAtPoint();
|
|
676
|
-
if (0 === pixelSize)
|
|
677
|
-
return;
|
|
678
|
-
// Adjust attached view frustum based on intersection with sheet view frustum.
|
|
679
|
-
const attachFrustum = this._originalFrustum.transformBy(this._toSheet);
|
|
680
|
-
const attachFrustumRange = attachFrustum.toRange();
|
|
681
|
-
const sheetFrustum = context.viewport.getWorldFrustum();
|
|
682
|
-
const sheetFrustumRange = sheetFrustum.toRange();
|
|
683
|
-
const intersect = attachFrustumRange.intersect(sheetFrustumRange);
|
|
684
|
-
if (intersect.isNull)
|
|
685
|
-
return;
|
|
686
|
-
attachFrustum.initFromRange(intersect);
|
|
687
|
-
attachFrustum.transformBy(this._fromSheet, attachFrustum);
|
|
688
|
-
this._viewport.setupViewFromFrustum(attachFrustum);
|
|
689
|
-
// Adjust view rect based on size of attachment on screen so that tiles of appropriate LOD are selected.
|
|
690
|
-
const width = this._sizeInMeters.x * intersect.xLength() / attachFrustumRange.xLength();
|
|
691
|
-
const height = this._sizeInMeters.y * intersect.yLength() / attachFrustumRange.yLength();
|
|
692
|
-
this._viewRect.width = Math.max(1, Math.round(width / pixelSize));
|
|
693
|
-
this._viewRect.height = Math.max(1, Math.round(height / pixelSize));
|
|
694
|
-
this._viewport.setRect(this._viewRect);
|
|
695
|
-
// Propagate settings from on-screen viewport.
|
|
696
|
-
this._viewport.debugBoundingBoxes = context.viewport.debugBoundingBoxes;
|
|
697
|
-
this._viewport.setTileSizeModifier(context.viewport.tileSizeModifier);
|
|
698
|
-
// Create the scene.
|
|
699
|
-
this._viewport.renderFrame();
|
|
700
|
-
const scene = this.scene;
|
|
701
|
-
if (!scene)
|
|
702
|
-
return;
|
|
703
|
-
// Extract scene graphics and insert into on-screen scene context.
|
|
704
|
-
const options = {
|
|
705
|
-
viewAttachmentId: this._props.id,
|
|
706
|
-
clipVolume: this._clipVolume,
|
|
707
|
-
hline: this._hiddenLineSettings,
|
|
708
|
-
frustum: {
|
|
709
|
-
is3d: this.view.is3d(),
|
|
710
|
-
scale: this._scale,
|
|
711
|
-
},
|
|
712
|
-
};
|
|
713
|
-
const outputGraphics = (source) => {
|
|
714
|
-
if (0 === source.length)
|
|
715
|
-
return;
|
|
716
|
-
const graphics = new GraphicBranch_1.GraphicBranch();
|
|
717
|
-
graphics.setViewFlagOverrides(this._viewFlagOverrides);
|
|
718
|
-
graphics.symbologyOverrides = this.symbologyOverrides;
|
|
719
|
-
for (const graphic of source)
|
|
720
|
-
graphics.entries.push(graphic);
|
|
721
|
-
const branch = context.createGraphicBranch(graphics, this._toSheet, options);
|
|
722
|
-
context.outputGraphic(branch);
|
|
723
|
-
};
|
|
724
|
-
outputGraphics(scene.foreground);
|
|
725
|
-
context.withGraphicType(internal_1.TileGraphicType.BackgroundMap, () => outputGraphics(scene.background));
|
|
726
|
-
context.withGraphicType(internal_1.TileGraphicType.Overlay, () => outputGraphics(scene.overlay));
|
|
727
|
-
// Report tile statistics to sheet view's viewport.
|
|
728
|
-
const tileAdmin = IModelApp_1.IModelApp.tileAdmin;
|
|
729
|
-
const selectedAndReady = tileAdmin.getTilesForUser(this._viewport);
|
|
730
|
-
const requested = tileAdmin.getRequestsForUser(this._viewport);
|
|
731
|
-
tileAdmin.addExternalTilesForUser(context.viewport, {
|
|
732
|
-
requested: requested?.size ?? 0,
|
|
733
|
-
selected: selectedAndReady?.selected.size ?? 0,
|
|
734
|
-
ready: selectedAndReady?.ready.size ?? 0,
|
|
735
|
-
});
|
|
736
|
-
}
|
|
737
|
-
getDebugFeatureTable() {
|
|
738
|
-
if (this._debugFeatureTable)
|
|
739
|
-
return this._debugFeatureTable;
|
|
740
|
-
const featureTable = new core_common_1.FeatureTable(1, this._sheetModelId);
|
|
741
|
-
featureTable.insert(new core_common_1.Feature(this._props.id));
|
|
742
|
-
this._debugFeatureTable = core_common_1.PackedFeatureTable.pack(featureTable);
|
|
743
|
-
return this._debugFeatureTable;
|
|
744
|
-
}
|
|
745
|
-
get areAllTileTreesLoaded() {
|
|
746
|
-
return this.view.areAllTileTreesLoaded;
|
|
747
|
-
}
|
|
748
|
-
collectStatistics(_stats) {
|
|
749
|
-
// Handled by discloseTileTrees()
|
|
750
|
-
}
|
|
751
|
-
get toSheet() {
|
|
752
|
-
return this._toSheet;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
function createRasterAttachmentViewport(_view, _rect, _attachment) {
|
|
756
|
-
class RasterAttachmentViewport extends Viewport_1.OffScreenViewport {
|
|
757
|
-
_sceneContext;
|
|
758
|
-
_isSceneReady = false;
|
|
759
|
-
_attachment;
|
|
760
|
-
constructor(view, rect, attachment) {
|
|
761
|
-
super(IModelApp_1.IModelApp.renderSystem.createOffscreenTarget(rect));
|
|
762
|
-
this._attachment = attachment;
|
|
763
|
-
this._isAspectRatioLocked = true;
|
|
764
|
-
this.changeView(view);
|
|
765
|
-
}
|
|
766
|
-
createSceneContext() {
|
|
767
|
-
(0, core_bentley_1.assert)(!this._isSceneReady);
|
|
768
|
-
this._sceneContext = super.createSceneContext();
|
|
769
|
-
return this._sceneContext;
|
|
770
|
-
}
|
|
771
|
-
renderFrame() {
|
|
772
|
-
(0, core_bentley_1.assert)(!this._isSceneReady);
|
|
773
|
-
this.clearSceneContext();
|
|
774
|
-
super.renderFrame();
|
|
775
|
-
if (undefined !== this._sceneContext) {
|
|
776
|
-
this._isSceneReady = !this._sceneContext.hasMissingTiles && this.view.areAllTileTreesLoaded;
|
|
777
|
-
if (this._isSceneReady)
|
|
778
|
-
this._attachment.produceGraphics(this._sceneContext);
|
|
779
|
-
this._sceneContext = undefined;
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
clearSceneContext() {
|
|
783
|
-
this._sceneContext = undefined;
|
|
784
|
-
}
|
|
785
|
-
addDecorations(_decorations) {
|
|
786
|
-
// ###TODO: skybox, ground plane, possibly grid. DecorateContext requires a ScreenViewport...
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
return new RasterAttachmentViewport(_view, _rect, _attachment);
|
|
790
|
-
}
|
|
791
|
-
/** Draws a 3d view with camera enabled into a sheet view by producing an image of the view's contents offscreen. */
|
|
792
|
-
class RasterAttachment {
|
|
793
|
-
_props;
|
|
794
|
-
_placement;
|
|
795
|
-
_transform;
|
|
796
|
-
zDepth;
|
|
797
|
-
_viewport;
|
|
798
|
-
_graphics;
|
|
799
|
-
constructor(view, props, sheetView) {
|
|
800
|
-
// Render to a 2048x2048 view rect. Scale in Y to preserve aspect ratio.
|
|
801
|
-
const maxSize = 2048;
|
|
802
|
-
const rect = new ViewRect_1.ViewRect(0, 0, maxSize, maxSize);
|
|
803
|
-
const height = maxSize * view.getAspectRatio() * view.getAspectRatioSkew();
|
|
804
|
-
const skew = maxSize / height;
|
|
805
|
-
view.setAspectRatioSkew(skew);
|
|
806
|
-
if (true !== props.jsonProperties?.displayOptions?.preserveBackground) {
|
|
807
|
-
// Make background color 100% transparent so that Viewport.readImageBuffer() will discard transparent pixels.
|
|
808
|
-
const bgColor = sheetView.displayStyle.backgroundColor.withAlpha(0);
|
|
809
|
-
view.displayStyle.backgroundColor = bgColor;
|
|
810
|
-
}
|
|
811
|
-
this._viewport = createRasterAttachmentViewport(view, rect, this);
|
|
812
|
-
this._props = props;
|
|
813
|
-
this._placement = core_common_1.Placement2d.fromJSON(props.placement);
|
|
814
|
-
this._transform = this._placement.transform;
|
|
815
|
-
this.zDepth = Frustum2d_1.Frustum2d.depthFromDisplayPriority(props.jsonProperties?.displayPriority ?? 0);
|
|
816
|
-
}
|
|
817
|
-
[Symbol.dispose]() {
|
|
818
|
-
this._viewport?.[Symbol.dispose]();
|
|
819
|
-
}
|
|
820
|
-
get viewAttachmentProps() {
|
|
821
|
-
return this._props;
|
|
822
|
-
}
|
|
823
|
-
get viewport() {
|
|
824
|
-
return this._viewport;
|
|
825
|
-
}
|
|
826
|
-
get areAllTileTreesLoaded() {
|
|
827
|
-
return this._viewport?.areAllTileTreesLoaded ?? true;
|
|
828
|
-
}
|
|
829
|
-
addToScene(context) {
|
|
830
|
-
// ###TODO: check viewport.wantViewAttachmentClipShapes
|
|
831
|
-
if (!context.viewport.view.viewsCategory(this._props.category))
|
|
832
|
-
return;
|
|
833
|
-
if (context.viewport.wantViewAttachmentBoundaries) {
|
|
834
|
-
const builder = context.createSceneGraphicBuilder(this._transform);
|
|
835
|
-
builder.setSymbology(core_common_1.ColorDef.red, core_common_1.ColorDef.red, 2);
|
|
836
|
-
builder.addRangeBox(core_geometry_1.Range3d.createRange2d(this._placement.bbox));
|
|
837
|
-
context.outputGraphic(builder.finish());
|
|
838
|
-
}
|
|
839
|
-
if (!context.viewport.wantViewAttachments)
|
|
840
|
-
return;
|
|
841
|
-
if (this._graphics) {
|
|
842
|
-
context.outputGraphic(this._graphics);
|
|
843
|
-
return;
|
|
844
|
-
}
|
|
845
|
-
if (undefined === this._viewport)
|
|
846
|
-
return;
|
|
847
|
-
this._viewport.debugBoundingBoxes = context.viewport.debugBoundingBoxes;
|
|
848
|
-
this._viewport.setTileSizeModifier(context.viewport.tileSizeModifier);
|
|
849
|
-
this._viewport.renderFrame();
|
|
850
|
-
if (this._graphics)
|
|
851
|
-
context.outputGraphic(this._graphics);
|
|
852
|
-
}
|
|
853
|
-
discloseTileTrees(trees) {
|
|
854
|
-
if (this._viewport)
|
|
855
|
-
trees.disclose(this._viewport);
|
|
856
|
-
}
|
|
857
|
-
produceGraphics(context) {
|
|
858
|
-
(0, core_bentley_1.assert)(context.viewport === this._viewport);
|
|
859
|
-
this._graphics = this.createGraphics(this._viewport);
|
|
860
|
-
this._viewport = (0, core_bentley_1.dispose)(this._viewport);
|
|
861
|
-
if (undefined !== this._graphics)
|
|
862
|
-
context.outputGraphic(this._graphics);
|
|
863
|
-
}
|
|
864
|
-
createGraphics(vp) {
|
|
865
|
-
// Create a texture from the contents of the view.
|
|
866
|
-
const image = vp.readImageBuffer({ upsideDown: true });
|
|
867
|
-
if (undefined === image)
|
|
868
|
-
return undefined;
|
|
869
|
-
const debugImage = false; // set to true to open a window displaying the captured image.
|
|
870
|
-
if (debugImage) {
|
|
871
|
-
const url = (0, ImageUtil_1.imageBufferToPngDataUrl)(image, false);
|
|
872
|
-
if (url)
|
|
873
|
-
(0, ImageUtil_1.openImageDataUrlInNewWindow)(url, "Attachment");
|
|
874
|
-
}
|
|
875
|
-
const texture = IModelApp_1.IModelApp.renderSystem.createTexture({
|
|
876
|
-
image: { source: image, transparency: core_common_1.TextureTransparency.Opaque },
|
|
877
|
-
});
|
|
878
|
-
if (!texture)
|
|
879
|
-
return undefined;
|
|
880
|
-
// Create a material for the texture
|
|
881
|
-
const graphicParams = new core_common_1.GraphicParams();
|
|
882
|
-
graphicParams.material = IModelApp_1.IModelApp.renderSystem.createRenderMaterial({ textureMapping: { texture } });
|
|
883
|
-
// Apply the texture to a rectangular polyface.
|
|
884
|
-
const depth = this.zDepth;
|
|
885
|
-
const east = this._placement.bbox.low.x;
|
|
886
|
-
const west = this._placement.bbox.high.x;
|
|
887
|
-
const north = this._placement.bbox.low.y;
|
|
888
|
-
const south = this._placement.bbox.high.y;
|
|
889
|
-
const corners = [
|
|
890
|
-
core_geometry_1.Point3d.create(east, north, depth),
|
|
891
|
-
core_geometry_1.Point3d.create(west, north, depth),
|
|
892
|
-
core_geometry_1.Point3d.create(west, south, depth),
|
|
893
|
-
core_geometry_1.Point3d.create(east, south, depth),
|
|
894
|
-
];
|
|
895
|
-
const params = [
|
|
896
|
-
core_geometry_1.Point2d.create(0, 0),
|
|
897
|
-
core_geometry_1.Point2d.create(1, 0),
|
|
898
|
-
core_geometry_1.Point2d.create(1, 1),
|
|
899
|
-
core_geometry_1.Point2d.create(0, 1),
|
|
900
|
-
];
|
|
901
|
-
const strokeOptions = new core_geometry_1.StrokeOptions();
|
|
902
|
-
strokeOptions.needParams = strokeOptions.shouldTriangulate = true;
|
|
903
|
-
const polyfaceBuilder = core_geometry_1.PolyfaceBuilder.create(strokeOptions);
|
|
904
|
-
polyfaceBuilder.addQuadFacet(corners, params);
|
|
905
|
-
const polyface = polyfaceBuilder.claimPolyface();
|
|
906
|
-
const graphicBuilder = IModelApp_1.IModelApp.renderSystem.createGraphicBuilder(core_geometry_1.Transform.createIdentity(), GraphicType_1.GraphicType.Scene, vp, this._props.id);
|
|
907
|
-
graphicBuilder.activateGraphicParams(graphicParams);
|
|
908
|
-
graphicBuilder.addPolyface(polyface, false);
|
|
909
|
-
const graphic = graphicBuilder.finish();
|
|
910
|
-
// Wrap the polyface in a GraphicBranch.
|
|
911
|
-
const branch = new GraphicBranch_1.GraphicBranch(true);
|
|
912
|
-
const vfOvrs = (0, internal_1.createDefaultViewFlagOverrides)({ clipVolume: true, shadows: false, lighting: false, thematic: false });
|
|
913
|
-
// Disable transparency - background pixels are 100% transparent so they will be discarded anyway. Other pixels are 100% opaque.
|
|
914
|
-
vfOvrs.transparency = false;
|
|
915
|
-
branch.setViewFlagOverrides(vfOvrs);
|
|
916
|
-
branch.symbologyOverrides = new FeatureSymbology_1.FeatureSymbology.Overrides();
|
|
917
|
-
branch.entries.push(graphic);
|
|
918
|
-
// Apply the attachment's clip, if any.
|
|
919
|
-
let clipVolume;
|
|
920
|
-
if (this._props.jsonProperties?.clip) {
|
|
921
|
-
const clipVector = core_geometry_1.ClipVector.fromJSON(this._props.jsonProperties?.clip);
|
|
922
|
-
if (clipVector.isValid)
|
|
923
|
-
clipVolume = IModelApp_1.IModelApp.renderSystem.createClipVolume(clipVector);
|
|
924
|
-
}
|
|
925
|
-
return IModelApp_1.IModelApp.renderSystem.createGraphicBranch(branch, this._transform, { clipVolume });
|
|
926
|
-
}
|
|
927
|
-
collectStatistics(stats) {
|
|
928
|
-
if (this._graphics)
|
|
929
|
-
this._graphics.collectStatistics(stats);
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
301
|
//# sourceMappingURL=SheetViewState.js.map
|