Skip to content

chore: seed PartIndex positionally from VisorSceneBase.add_dataset's part-node list - #66

Merged
LKasianAnsys merged 4 commits into
mainfrom
maint/seed-part-index-positionally
Sep 4, 2026
Merged

LKasianAnsys merged 4 commits into
mainfrom
maint/seed-part-index-positionally

Conversation

@LKasianAnsys

@LKasianAnsys LKasianAnsys commented Sep 2, 2026 •

Copy link
Copy Markdown
Collaborator

Issue

Addresses #18

Context

For a multiblock dataset with multiple parts but no part names defined, on a browser refresh, the per-part state is not preserved. The expected behaviour is that preserving the per-part state on refresh is supported regardless of part names (whether set, unset, unique, or containing duplicates). For multiblock datasets with unique part names, per-part state is preserved.

Investigation traced the issue to PartIndex being seeded from a name-keyed map, so all 66 leaves resolved to one seeded ID and the index retained a single entry. The scene graph and renderer each held one node and one pipeline per leaf, so every set_part_* trigger for the other 65 resolved to no owning dataset and returned without applying, silently.

This PR fixes the PartIndex so the part properties are preserved on a browser refresh.

Python Example

Showing an example illustrating how the issue looks on the Python side. The many_blocks multiblock dataset in our tests directory has 66 parts, none of which have a 'name' attribute set. On 'main' this results in the PartIndex only containing a single part, and when the user refreshes the browser, the per-part state is not preserved for most, as it is not in the server's PartIndex.

This PR addresses the issue, resulting in a PartIndex fully populated with the expected 66 parts. The behaviour can be verified in the viewer, as a refresh now preserves the per-part state, relying on the populated PartIndex.

> from ansys.visor.viewer import Visor, Metadata
> visor = Visor()
> visor.start(input="tests/files/many_blocks/many_blocks.vtm")
   Server starting...
   Server started and ready on http://localhost:8081
> datasets = visor._scene._dataset_registry.datasets
> dataset = datasets.get(list(set(datasets.keys()))[0])

On main:

> parts = dataset.part_index.list_parts()
> print(len(parts))
   1
> print(parts)
   [{'part_id': 3888211195333123, 'name': 'untitled'}]

# Viewer behaviour:
# after adjusting per-part properties in the viewer, a browser refresh does not preserve them.

After this PR:

> parts = dataset.part_index.list_parts()
> print(len(parts))
   66
> print(parts)
   [{'part_id': 6105907393316783, 'name': 'untitled'},
    {'part_id': 4608438069187314, 'name': 'untitled'},
    {'part_id': 1383875165231248, 'name': 'untitled'},
   ... etc ... 
    {'part_id': 7165048937483098, 'name': 'untitled'},
    {'part_id': 3290956410920456, 'name': 'untitled'},
    {'part_id': 1763081068834376, 'name': 'untitled'}]

# Viewer behaviour:
# after adjusting per-part properties in the viewer, a browser refresh preserves them as expected.

Description

This pull request refactors how part IDs are assigned and seeded in the VTK dataset handling code, moving from a name-based to a positional (flat index) approach. This change ensures that part IDs match scene-graph node IDs, even when part names are missing or duplicated, which is critical for correct frontend behavior and renderer pipeline mapping. The refactor also simplifies and clarifies the contract between the backend and frontend regarding per-part state management. Extensive new and updated tests are included to pin the new behavior and verify correctness, especially in edge cases like unnamed or duplicate parts.

Core logic and API changes:

  • The PartIndex class now seeds part IDs positionally from a sequence of scene-graph node IDs (by flat index), not by part name, ensuring part_id == node_id even when names are missing or duplicated. The seed is now a sequence of IDs, not a dictionary keyed by name. [1]], [2]], [3]])
  • The VisorDataset and VisorDatasetRegistry constructors and methods are updated to accept and pass this positional seed (node_ids: Sequence[int] | None) instead of a name-to-id map. [1]], [2]], [3]], [4]])

Scene graph and registry cleanup:

  • Deprecated and removed methods for generating name-to-id maps from the scene graph, as the new approach no longer needs them. [1]], [2]])

Bug fixes and improved error handling:

  • Added strict checking and error logging when the seed length does not match the number of leaf nodes, ensuring that mismatches are surfaced and that unseeded positions fall back to random IDs. ([src/ansys/visor/viewer/vtk/datasets/part_index.pyL84-R113])
  • Clarified docstrings and comments to reflect the new positional seeding contract and its implications for frontend/backend synchronization. [1]], [2]], [3]])

Testing improvements:

  • Added a comprehensive integration test (test_part_identity_many_blocks.py) to verify correct part identity assignment in ragged, unnamed multiblock datasets, ensuring one part per leaf and correct ID mapping. ([tests/integration/test_part_identity_many_blocks.pyR1-R98])
  • Updated and expanded unit tests for PartIndex to cover positional seeding, duplicate names, zero IDs, and seed/leaf count mismatches. [1]], [2]])
  • Adjusted existing integration tests to use the new approach for extracting node names. ([tests/integration/test_input_data.pyL429-R431])

These changes ensure robust, predictable part identity assignment in all cases, improving reliability for both backend operations and frontend visualization.

@github-actions github-actions Bot added maintenance Operation not directly changing the production code - e.g., updating a devops pipeline test Work associated with testing labels Sep 2, 2026
@LKasianAnsys
LKasianAnsys merged commit 7dfd23f into main Sep 4, 2026
45 of 50 checks passed
@LKasianAnsys
LKasianAnsys deleted the maint/seed-part-index-positionally branch September 4, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance Operation not directly changing the production code - e.g., updating a devops pipeline test Work associated with testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants