Skip to content

Simplification of the loading process for rasterized tiles and mesh tiles #2609

Open
gchoqueux wants to merge 4 commits into
iTowns:masterfrom
gchoqueux:refacto/simple_loading_tile
Open

Simplification of the loading process for rasterized tiles and mesh tiles #2609
gchoqueux wants to merge 4 commits into
iTowns:masterfrom
gchoqueux:refacto/simple_loading_tile

Conversation

@gchoqueux

@gchoqueux gchoqueux commented Oct 6, 2025

Copy link
Copy Markdown
Contributor

Description

This PR proposes a possible simplification of the loading process for rasterized tiles and mesh tiles.

Summary of changes

  • TileMesh instances are now created directly in TiledGeometryLayer, without using commands or providers.
  • TileMesh.pendingSubdivision has been removed.
  • TiledGeometryLayer#hasEnoughTexturesToSubdivide has been removed.
  • updateLayeredMaterialNodeImagery and updateLayeredMaterialNodeElevation have been merged into a single lightweight method.
  • TileProvider has been deleted.
  • Texture loading is now handled by RasterTile#load.

@gchoqueux gchoqueux changed the title Simplification of the loading process for **rasterized tiles** and **mesh tiles**. Simplification of the loading process for rasterized tiles and mesh tiles Oct 6, 2025
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 13 times, most recently from 489581c to afdfc01 Compare October 8, 2025 13:13
@gchoqueux

Copy link
Copy Markdown
Contributor Author

Rebased

@gchoqueux

Copy link
Copy Markdown
Contributor Author

I’ve come up with a possible way to simplify this — what do you think of these changes?

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch from afdfc01 to 6f64fdf Compare October 10, 2025 09:24
@jailln

jailln commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

It seems related to #2521 and #2525 which haven't been merged yet; but it goes a bit further, is that right? These PR where not merged because of #2530 . Do you have the same issue?

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 4 times, most recently from 2cec783 to 15dfa04 Compare October 13, 2025 11:12
@gchoqueux

gchoqueux commented Oct 13, 2025

Copy link
Copy Markdown
Contributor Author

It seems related to #2521 and #2525 which haven't been merged yet; but it goes a bit further, is that right? These PR where not merged because of #2530 . Do you have the same issue?

It doesn’t seem to have the same issue in the functional tests.
However, I did change the number of displayed tiles in the functional tests — maybe because this PR is not finished yet.

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 4 times, most recently from c7b4635 to 4bd5c32 Compare October 14, 2025 09:13
@gchoqueux

gchoqueux commented Oct 14, 2025

Copy link
Copy Markdown
Contributor Author

My bad, there's a issue with VIEW_EVENTS.LAYERS_INITIALIZED, but it is not the same, it's called very late, it's almost the opposite.
I'll investigate
solved

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch from e9aab85 to 3d3be67 Compare October 14, 2025 15:48
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 2 times, most recently from eecc503 to 4c86123 Compare December 15, 2025 14:53
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 3 times, most recently from 5235375 to 7a3ea9a Compare January 7, 2026 15:34
@Neptilo

Neptilo commented Jan 16, 2026

Copy link
Copy Markdown
Contributor

Hi! I'm starting to look into the loading processes to get familiar with them, in order to improve them after this simplification is completed. Thanks for the work done so far!
Do you need help fixing the remaining bugs?
What is the display bug you mention in ElevationLayer.anyVisibleData? I can see that changing the first current.source to current?.source already makes a big difference, but I assume you are referring to a deeper bug...

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 2 times, most recently from 7a07fe7 to 47507b0 Compare January 20, 2026 16:54
@gchoqueux

gchoqueux commented Jan 20, 2026

Copy link
Copy Markdown
Contributor Author

Remaining work in this PR

  • finalize the method for verifying data visibility : anyVisibleData vs extentInsideLimit methods
  • rewrite some unit tests
  • finalize tiles property in RasterTile

FAQ

What is the display bug you mention in ElevationLayer.anyVisibleData?

I don't remember exactly i remove the commentary

I can see that changing the first current.source to current?.source, you are referring to a deeper bug ?

I think it's not a bug

the others bugs :

  • wrong tile visibility
  • wrong parent texture update

@gchoqueux

Copy link
Copy Markdown
Contributor Author

Next steps to move forward on the PR

  • An initial code review by at least 2 reviewers on the architecture and the core aspects of the PR.
    The main code of this PR hasn’t changed for weeks; only minor formatting changes and rebases have been made.

Assistance can be provided on the following points:

  • Validation and finalization of the development of anyVisibleData
  • Rewriting unit tests and improving coverage
  • Help testing this PR on the various itowns examples

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch from 47507b0 to 5b6ea96 Compare January 30, 2026 14:02
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 8 times, most recently from 92e8c4c to a9618c4 Compare February 16, 2026 16:23
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch from a9618c4 to c581383 Compare February 17, 2026 14:59

@Desplandis Desplandis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposed changes are fine by me. It makes the code more easy to understand (e.g. no need to track the changes of layerUpdateState across 4 different files). I did some high-level comments on the code (and some low-level too sorry), those are some questions about the behaviour before and after this PR.

Note that I did not tested it across our examples, nor did I run the tests.

Could you please provide a list of the remaining things to address in this PR?

Comment thread packages/Main/src/Core/Prefab/TileBuilder.ts Outdated
Comment thread packages/Main/src/Core/Prefab/TileBuilder.ts
Comment thread packages/Main/src/Core/Tile/Tile.ts
Comment thread packages/Main/src/Layer/ElevationLayer.js Outdated
Comment thread packages/Main/src/Layer/LayerUpdateStrategy.ts Outdated
Comment thread packages/Main/src/Renderer/RasterTile.js
Comment thread packages/Main/src/Renderer/RasterTile.js
Comment on lines +328 to +329
// [TEMP] find best place to update uniforms
node.material.layersNeedUpdate = node.material.visible;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is similar to the old behaviour, but I agree that we should reconsider where we should request a new update of the material!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it's not the best place, because node.material.layersNeedUpdate is true each time that tileMesh is visible

Comment thread packages/Main/src/Layer/RasterLayer.js Outdated
anyVisibleData(node) {
const current = node.material.getElevationTile()?.layer;
return super.anyVisibleData(node)
&& (current?.source == this.source || this.source.zoom.min > (current?.source.zoom.max || -1));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the meaning of -1 here?

@gchoqueux gchoqueux Mar 6, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's for this.source.zoom.min > -1 would be always true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, the data is considered visible if source.zoom.min < layer.source.zoom.max? Not sure to follow here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I clarified this by refactoring the code

@Desplandis

Copy link
Copy Markdown
Contributor

@gchoqueux Are you available for a session of peer programming on this PR tomorrow or the following monday? I would like to converge on this one. =)

@Desplandis

Desplandis commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

I'm currently looking to the PR (hope we can finalise this), catched a regression on view_25d_map when moving or zooming out, we don't have textures (neither elevation nor imagery) when loading new levels. I'll try to investigate a bit during my review.

P.S.: misc_clamp_ground too

Comment thread examples/misc_clamp_ground.html Outdated
return layer;
}
itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
const p = itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a top-level await would be clearer. This comment applies to all examples of itowns per-se.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (this.shouldWriteTextureAtIndex(index, texture)) {
this.level = (texture && texture.extent) ? texture.extent.zoom : this.level;
this.textures[index] = texture || null;
if (texture && this.shouldWriteTextureAtIndex(index, texture)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some places where we could pass an undefined texture there? Shall those undefined be filtered before at the call sites?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we filter out undefined textures, we lose the indexing needed to assign them

Comment on lines +18 to +24
function refinementCommandCancellationFn(cmd) {
const { requester, view } = cmd;
const child = requester.children[0];

// to do remove useless
return !cmd.force && (!view || !requester.parent || !requester.material || !requester.material.visible || child?.visible);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gchoqueux Are those points addressed?

colorlayers.sort((a, b) =>
this.colorTileIds.indexOf(a.id) - this.colorTileIds.indexOf(b.id),
);
if (this.layersNeedUpdate) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer an early return with the !this.layersNeedUpdate condition.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


node.material.visible = true;
node.material.layersNeedUpdate = true;
if (node.visible && this.subdivision(context, node)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some issues with the freshly subdivided tiles which have no terrain and no imagery (e.g. view_25dmap and misc_clamp_ground issues are flagrant). Re-adding the hasEnoughTexturesToSubvide condition seems to fix the problem, however I think the problem is more profound.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may be add hasEnoughTexturesToSubvide for the first tile ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and refactor hasEnoughTexturesToSubvide to LayeredMaterial

@gchoqueux gchoqueux Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add a new wip commit :

5a42809 fix(TiledGeometryLayer): [WIP][PROPOSAL] avoid to subdivide node mesh if raster tiles aren't loaded

@Desplandis

Copy link
Copy Markdown
Contributor

Looking at it, I think the problem is two-fold:

  • Since we are not blocking subdivision with hasEnoughTexturesToSubvide, we do not trigger parent texture loading
  • Since everything is synchronous, when we call initFromParent, the texture is not loaded on the parent and we don't have a mechanism to notify descendant tiles of a loaded ancestor texture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants