trying to add a separate geometry conversion progress as well as data loading progress (#4710)

* Adding more progress to loading and rendering of a model

* have separate values for loading totals

* Allow callback to be null

* Fix loading test

* Prettier

* Revert sandbox changes
This commit is contained in:
Adam Hathcock
2025-05-30 15:14:32 +01:00
committed by GitHub
parent 9bb420c08b
commit eec93469b3
5 changed files with 56 additions and 16 deletions
+21 -3
View File
@@ -1325,17 +1325,35 @@ export default class Sandbox {
true,
undefined
)
let progress = 0
let dataProgress = 0
let renderedCount = 0
let traversedCount = 0
/** Too spammy */
loader.on(LoaderEvent.LoadProgress, (arg: { progress: number; id: string }) => {
const p = Math.floor(arg.progress * 100)
if (p > progress) {
if (p > dataProgress) {
if (colorImage)
colorImage.style.clipPath = `inset(${(1 - arg.progress) * 100}% 0 0 0)`
progress = p
dataProgress = p
console.log(`Loading ${p}%`)
}
})
loader.on(LoaderEvent.Traversed, (arg: { count: number }) => {
if (arg.count > traversedCount) {
traversedCount = arg.count
if (traversedCount % 777 === 0) {
console.log(`Traversed Data ${traversedCount}`)
}
}
})
loader.on(LoaderEvent.Converted, (arg: { count: number }) => {
if (arg.count > renderedCount) {
renderedCount = arg.count
if (renderedCount % 777 === 0) {
console.log(`Rendering Data ${renderedCount}`)
}
}
})
loader.on(LoaderEvent.LoadCancelled, (resource: string) => {
console.warn(`Resource ${resource} loading was canceled`)
})
+2 -2
View File
@@ -117,10 +117,10 @@ const getStream = () => {
// 'https://latest.speckle.systems/streams/58b5648c4d/commits/60371ecb2d'
//bad commit! not all items uploaded to server
// 'https://app.speckle.systems/projects/8e4347e65d/models/39bea37d69'
//'https://app.speckle.systems/projects/8e4347e65d/models/39bea37d69'
// 'Super' heavy revit shit
// 'https://app.speckle.systems/streams/e6f9156405/commits/0694d53bb5'
//'https://app.speckle.systems/streams/e6f9156405/commits/0694d53bb5'
// IFC building (good for a tree based structure)
// 'https://latest.speckle.systems/streams/92b620fb17/commits/2ebd336223'
// IFC story, a subtree of the above
@@ -3,11 +3,15 @@ import EventEmitter from '../EventEmitter.js'
export enum LoaderEvent {
LoadProgress = 'load-progress',
LoadCancelled = 'load-cancelled',
LoadWarning = 'load-warning'
LoadWarning = 'load-warning',
Converted = 'converted',
Traversed = 'traversed'
}
export interface LoaderEventPayload {
[LoaderEvent.LoadProgress]: { progress: number; id: string }
[LoaderEvent.Converted]: { count: number }
[LoaderEvent.Traversed]: { count: number }
[LoaderEvent.LoadCancelled]: string
[LoaderEvent.LoadWarning]: { message: string }
}
@@ -86,9 +86,9 @@ export class SpeckleLoader extends Loader {
public async load(): Promise<boolean> {
const start = performance.now()
let first = true
let current = 0
let dataloading = 0
const total = await this.loader.getTotalObjectCount()
let viewerLoads = 0
let traversals = 0
let firstObjectPromise = null
Logger.warn('Downloading object ', this.resource)
@@ -103,14 +103,17 @@ export class SpeckleLoader extends Loader {
this.resource,
obj as SpeckleObject,
async () => {
viewerLoads++
traversals++
this.emit(LoaderEvent.Traversed, {
count: traversals
})
}
)
first = false
}
current++
dataloading++
this.emit(LoaderEvent.LoadProgress, {
progress: current / (total + 1),
progress: dataloading / (total + 1),
id: this.resource
})
}
@@ -125,7 +128,7 @@ export class SpeckleLoader extends Loader {
} seconds. Node count: ${this.tree.nodeCount}`
)
if (viewerLoads === 0) {
if (traversals === 0) {
Logger.warn(`Viewer: no 3d objects found in object ${this.resource}`)
this.emit(LoaderEvent.LoadWarning, {
message: `No displayable objects found in object ${this.resource}.`
@@ -144,7 +147,17 @@ export class SpeckleLoader extends Loader {
const renderTree = this.tree.getRenderTree(this.resource)
if (!renderTree) return Promise.resolve(false)
const p = renderTree.buildRenderTree(geometryConverter)
let converted = 0
const p = renderTree.buildRenderTree(geometryConverter, () => {
converted++
this.emit(LoaderEvent.Converted, {
count: converted
})
})
Logger.warn(
`Finished rendering object . Node count: ${this.tree.nodeCount} Total: ${total}`
)
void p.then(() => {
Logger.log('ASYNC Tree build time -> ', performance.now() - t0)
@@ -29,10 +29,13 @@ export class RenderTree {
this.root = subtreeRoot
}
public buildRenderTree(geometryConverter: GeometryConverter): Promise<boolean> {
public buildRenderTree(
geometryConverter: GeometryConverter,
callback?: () => void
): Promise<boolean> {
const p = this.tree.walkAsync((node: TreeNode): boolean => {
let start = performance.now()
const rendeNode = this.buildRenderNode(node, geometryConverter)
const rendeNode = this.buildRenderNode(node, geometryConverter, callback)
node.model.renderView = rendeNode ? new NodeRenderView(rendeNode) : null
this.buildNodeTime += performance.now() - start
start = performance.now()
@@ -71,11 +74,13 @@ export class RenderTree {
private buildRenderNode(
node: TreeNode,
geometryConverter: GeometryConverter
geometryConverter: GeometryConverter,
callback?: () => void
): NodeRenderData | null {
let ret: NodeRenderData | null = null
let start = performance.now()
const geometryData = geometryConverter.convertNodeToGeometryData(node.model)
if (callback) callback()
this.convertTime += performance.now() - start
if (geometryData) {
start = performance.now()