Split Element itwin.js API so GeometryStream is not held by ElementProps/Element
Why?
As we port from native to typescript caching happens on typescript side. Currently GeometryStream is held by GeometricElement. Developers access geometry streams on demand and one at a time. It can be exceptionally large and so holding element cache for substantial number of geometric elements or parts can take alot of resources.
To fix this we need to separate out GeoemtryStream from GeometricElement and make it separate Api that is responsible for reading, writing, and caching geometry stream.
The api looks as follows. With this we can deprecate geom properties in GeometricElement and part and let user use the new api to access and modify geometry stream. During deprecation period we still use the new API under the hood when reading/writing GeometricElement.
export interface GeometryLoadOptions {
wantBRepData?: boolean;
}
export interface GeometryUpdateArgs {
geom?: GeometryStreamProps;
builder?: ElementGeometryBuilderParams;
}
export interface GeometryPartUpdateArgs {
geom?: GeometryStreamProps;
builder?: ElementGeometryBuilderParamsForPart;
}
IModelDb.Elements {
GetGeometry(id: Id64String, options?: GeometryLoadOptions): GeometryStreamProps;
UpdateGeometry(id: Id64String, geom: GeometryUpdateArgs);
UpdateGeometryPart(id: Id64String, geom: GeometryPartUpdateArgs);
}
So, with new api geometry loading is completely explicit and not hidden under flag wantGeometry when loading element. While element loading does not load geometry neither it exposes any member to access it via ElementProps or Element class.
We can then only cache Uint8Array and limit the size in byte the cache can hold for geometries. Everytime user request geometry we convert uint8array to GeometryStream props via native api.
// The LRU cache for geometry stream will use eviction strategy that also considers the total bytes
// cache across all geometry streams. If loading geometry require loading bytes that exceeds max,
// then item will be remove until there is space available to load new geometry stream.
const geomCache = new LRUCache<Id64String, Uint8Array> ({count:2000, maxSizeInBytes: 1024*1024*10})
GeometryLoadOptions probably should be just:
export interface GeometryLoadOptions {
wantBRepData?: boolean;
}
GeometryLoadOptionsprobably should be just:export interface GeometryLoadOptions { wantBRepData?: boolean; }
I have updated the issue and will be working on it. But is following unnecessary? I am talking about in context of deprication. I need to mark them deprecated or noop on existing ElementLoadOptions.
displayStyle?: DisplayStyleLoadProps;
renderTimeline?: RenderTimelineLoadProps;