-
Notifications
You must be signed in to change notification settings - Fork 208
/
RenderGraphicTileTree.ts
158 lines (129 loc) · 5.13 KB
/
RenderGraphicTileTree.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Tiles
*/
import { compareStrings, Guid, GuidString, Id64String } from "@itwin/core-bentley";
import { ViewFlagOverrides } from "@itwin/core-common";
import { Tile, TileDrawArgs, TileLoadPriority, TileTree, TileTreeOwner, TileTreeReference, TileTreeSupplier } from "./internal";
import { RenderGraphic } from "../render/RenderGraphic";
import { IModelConnection } from "../IModelConnection";
import { Range3d, Transform } from "@itwin/core-geometry";
import { IModelApp } from "../IModelApp";
import { HitDetail } from "../HitDetail";
/** Arguments supplied to [[TileTreeReference.createFromRenderGraphic]].
* @beta
*/
export interface RenderGraphicTileTreeArgs {
/** The graphics that will be drawn by the [[TileTreeReference]]. */
graphic: RenderGraphic;
/** The iModel with which to associate the [[TileTreeReference]]. */
iModel: IModelConnection;
/** A transient Id to serve as the [[TileTree.modelId]], obtained from the [[iModel]]'s [TransientIdSequence]($bentley).
* This model Id will be associated with any pickable [Feature]($common)s contained in your [[graphic]].
*/
modelId: Id64String;
/** Optional overrides for a subset of the [[Viewport]]'s [ViewFlags]($common) when drawing your [[graphic]].
* If, for example, you always want your graphic to be drawn as illuminated 3d surfaces, specify the following:
* ```ts
* { renderMode: RenderMode.SmoothShade, lighting: true }
* ```
*/
viewFlags?: ViewFlagOverrides;
/** A function that returns a tooltip describing a pickable [Feature]($common) inside your [[graphic]] when the user hovers the mouse over it. */
getToolTip?: (hit: HitDetail) => Promise<HTMLElement | string | undefined>;
}
interface TreeId extends RenderGraphicTileTreeArgs {
id: GuidString;
}
class GraphicTile extends Tile {
constructor(tree: TileTree, graphic: RenderGraphic) {
const range = new Range3d();
graphic.unionRange(range);
super({
contentId: tree.id,
range,
maximumSize: 1,
}, tree);
this.setGraphic(graphic);
}
protected _loadChildren(resolve: (children: Tile[] | undefined) => void): void {
resolve(undefined);
}
public async requestContent() {
return Promise.resolve(this.tree.id);
}
public async readContent() {
return {};
}
public get channel() {
return IModelApp.tileAdmin.channels.getForHttp("render-graphic-tile");
}
}
class GraphicTree extends TileTree {
private readonly _rootTile: GraphicTile;
private readonly _viewFlagOverrides: ViewFlagOverrides;
public constructor(args: TreeId) {
super({
iModel: args.iModel,
id: args.id,
modelId: args.modelId,
location: Transform.createIdentity(),
priority: TileLoadPriority.Primary,
});
this._rootTile = new GraphicTile(this, args.graphic);
this._viewFlagOverrides = args.viewFlags ?? { };
}
public override get rootTile() { return this._rootTile; }
// ###TODO rm TileTree.is3d - only iModel tiles care about it.
public override get is3d() { return true; }
public override get maxDepth() { return undefined; }
public override get viewFlagOverrides() { return this._viewFlagOverrides; }
protected override _selectTiles(args: TileDrawArgs) {
args.markUsed(this.rootTile);
return [this.rootTile];
}
public override prune() { }
public override draw(args: TileDrawArgs) {
const tiles = this.selectTiles(args);
for (const tile of tiles)
tile.drawGraphics(args);
args.drawGraphics();
}
}
class Supplier implements TileTreeSupplier {
public compareTileTreeIds(lhs: TreeId, rhs: TreeId): number {
return compareStrings(lhs.id, rhs.id);
}
public async createTileTree(id: TreeId): Promise<TileTree | undefined> {
return Promise.resolve(new GraphicTree(id));
}
}
const supplier = new Supplier();
class GraphicRef extends TileTreeReference {
private readonly _owner: TileTreeOwner;
private readonly _modelId: Id64String;
private readonly _getToolTip?: (hit: HitDetail) => Promise<string | HTMLElement | undefined>;
public constructor(args: TreeId) {
super();
this._owner = args.iModel.tiles.getTileTreeOwner(args, supplier);
this._modelId = args.modelId;
this._getToolTip = args.getToolTip;
}
public override get treeOwner() { return this._owner; }
public override canSupplyToolTip(hit: HitDetail): boolean {
return undefined !== this._getToolTip && this._modelId === hit.modelId;
}
public override async getToolTip(hit: HitDetail): Promise<string | HTMLElement | undefined> {
if (this._getToolTip && this._modelId === hit.modelId) {
return this._getToolTip(hit);
}
return undefined;
}
}
/** @internal */
export function tileTreeReferenceFromRenderGraphic(args: RenderGraphicTileTreeArgs): TileTreeReference {
return new GraphicRef({ ...args, id: Guid.createValue() });
}