Skip to content

Commit 6804110

Browse files
committed
feat: track visible items
1 parent f5ee358 commit 6804110

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

packages/fragments/src/FragmentsModels/src/model/fragments-model.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { FragmentsConnection } from "../multithreading/fragments-connection";
2626
import { MeshManager } from "./mesh-manager";
2727

2828
import { AlignmentsManager } from "./alignments-manager";
29-
import { DataMap, EditRequest } from "../../../Utils";
29+
import { DataMap, EditRequest, Event } from "../../../Utils";
3030
import { SetupManager } from "./setup-manager";
3131
import { BoxManager } from "./box-manager";
3232
import { CoordinatesManager } from "./coordinates-manager";
@@ -69,6 +69,20 @@ export class FragmentsModel {
6969
*/
7070
readonly tiles = new DataMap<string | number, BIMMesh>();
7171

72+
/**
73+
* Event triggered after a view update cycle finishes processing.
74+
* Listeners receive this FragmentsModel instance, allowing queries
75+
* like {@link getItemsByVisibility} to retrieve seen/unseen elements.
76+
*/
77+
readonly onViewUpdated = new Event<FragmentsModel>();
78+
79+
/**
80+
* A set of item IDs that are currently visible (i.e. have at least
81+
* one tile rendered on screen). Updated automatically as tiles are
82+
* created and deleted by the mesh manager.
83+
*/
84+
readonly visibleItems = new Set<number>();
85+
7286
/**
7387
* The object that represents the model in the Three.js scene.
7488
*/
@@ -204,6 +218,8 @@ export class FragmentsModel {
204218
*/
205219
async dispose() {
206220
this._isLoaded = false;
221+
this.visibleItems.clear();
222+
this.onViewUpdated.reset();
207223
await this._dataManager.dispose(
208224
this,
209225
this._meshManager,
@@ -887,6 +903,7 @@ export class FragmentsModel {
887903
*/
888904
_finishProcessing() {
889905
this._isProcessing = false;
906+
this.onViewUpdated.trigger(this);
890907
}
891908

892909
_setDeltaModel(modelId: string) {

packages/fragments/src/FragmentsModels/src/model/mesh-manager.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,15 @@ export class MeshManager {
8080
if (request.objectClass === undefined) return;
8181
const tile = this.create(request);
8282
this.setTileData(tile, request);
83+
const uniqueIds = this.extractUniqueItemIds(request.itemIds);
84+
tile.userData.itemIds = uniqueIds;
85+
this.trackVisibleItems(model, uniqueIds, true);
8386
model.tiles.set(tile.userData.tileId, tile);
8487
} else if (tileRequestClass === TileRequestClass.DELETE) {
88+
const tile = model.tiles.get(tileId);
89+
if (tile?.userData.itemIds) {
90+
this.trackVisibleItems(model, tile.userData.itemIds, false);
91+
}
8592
model.tiles.delete(tileId);
8693
} else if (tileRequestClass === TileRequestClass.UPDATE) {
8794
const tileObject = model.tiles.get(tileId);
@@ -91,6 +98,29 @@ export class MeshManager {
9198
}
9299
}
93100

101+
private extractUniqueItemIds(itemIds: any): Set<number> {
102+
const unique = new Set<number>();
103+
if (!itemIds) return unique;
104+
for (let i = 0; i < itemIds.length; i++) {
105+
unique.add(itemIds[i]);
106+
}
107+
return unique;
108+
}
109+
110+
private trackVisibleItems(
111+
model: FragmentsModel,
112+
itemIds: Set<number>,
113+
added: boolean,
114+
) {
115+
for (const itemId of itemIds) {
116+
if (added) {
117+
model.visibleItems.add(itemId);
118+
} else {
119+
model.visibleItems.delete(itemId);
120+
}
121+
}
122+
}
123+
94124
private createMesh(request: any) {
95125
const { indices, positions, normals, itemIds, faceIds } = request;
96126
const geometry = new THREE.BufferGeometry();

0 commit comments

Comments
 (0)