Skip to content

feat: [Remote rendering 3.5b] client uses server owned variables - #153

Open
LKasianAnsys wants to merge 9 commits into
feat/3.5a-move-variable-ownership-to-serverfrom
feat/3.5b-client-uses-server-owned-variables
Open

LKasianAnsys wants to merge 9 commits into
feat/3.5a-move-variable-ownership-to-serverfrom
feat/3.5b-client-uses-server-owned-variables

Conversation

@LKasianAnsys

@LKasianAnsys LKasianAnsys commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Issue

Addresses #23

Context

This is the second PR for user story 3.5 in Phase 3 of the remote rendering epic, which sees the visualizer state authority move from client to server.

In this PR, the client stops owning the variable definition on its end, and treats VisorVariableManager as a projection of the delivered records. Custom range edits are sent to the server and re-delivered.

Callouts:

  • On its own this branch has an intermittent bug on add_dataset, which is attributable to the fact that the client still replaces the color lookup tables. This is resolved in the PR for 3.5c (feat: [Remote rendering 3.5c] Server creates color lookup table and client stops creating its own #161), where the lookup tables are created only on the server.
  • The client no longer computes anything about variables: id and range come from the delivered record.
  • The rebuild carry-across (where the client reapplies its cached version of the viewer state, in onServerUpdateAsync in App.tsx) no longer carries variable state. The delivered record is the only source after a rebuild.

Pre-existing issue fix:

  • a dataset containing an array with a component count the client has no labels for (anything outside 1, 2, 3, 4, 9) broke the page on the current main. setRecords now skips a record whose component count has no label definition with one console warning instead of refusing the whole delivery. The server still lists such variables, but the client does not display them.
  • Also, onServerUpdateAsync now registers its server listeners in a finally block, so a failed rebuild can no longer leave the page silently ignoring later pushes.

What to look for:

  • A custom range survives a browser reload and an add_dataset
  • the legend reflects the delivered range
  • no code path falls back to a client-computed range
  • variable default range widening on add_dataset.

To test the last bullet point, run the following:

  1. Start VISOR with a dataset (e.g. examples/assets/vtk_scene_sphere_l2_b3_r32_v3_c1_z0.vtm), and color a part by a variable with range [0, 1] (e.g. gradient)
  2. Run add_dataset to add a dataset with the same variable but having a wider range (eg vtk_scene_sphere_l2_b3_r32_v3_c1_s2_z6.vtm, which has [0, 2] on the same variable).

This should result in the new default range being applied to all parts colored by that variable. Run the same test after having set a custom variable range on before adding the second variable, and the custom range should be preserved after add_dataset.


Copilot summary

This pull request shifts variable state ownership to the server. The client now reads and applies variable records delivered by the server, rather than maintaining its own copies. This results in a cleaner separation of responsibilities and improved synchronization between client and server variable states. The changes also include improved handling of variable range updates, more robust frontend rebuilds, and enhanced panel refresh logic.

Variable State Ownership and Synchronization:

  • The client no longer constructs or carries its own variable records; instead, variable records are now delivered by the server and applied on each state update, ensuring the client always reflects the server's authoritative variable state. [1] [2] [3]
  • The VisorFrontend class now includes a sendVariableRangeAsync method to report variable range changes to the server, with errors logged but not rethrown, and updates the setVariableRangeAsync method to always notify the server after applying a range locally. [1] [2] [3]

Frontend and UI Handling:

  • Improved frontend rebuild logic in App.tsx to ensure event listeners are consistently managed and that the new frontend instance is only set after successful initialization. [1] [2] [3]
  • The top-right panel utility now exposes a refreshSelectionAsync method, allowing the UI to re-read and display the current selection's variable ranges after state updates. [1] [2] [3] [4] [5]

Scene Graph and Variable Application:

  • Scene graph nodes now read variable collections directly from the server-delivered records, and when recoloring by the same variable slot, only re-apply the range if it has changed. [1] [2] [3] [4]

Testing and Utilities:

  • Jest tests updated to use server-style variable records and the revised variable manager, ensuring tests accurately reflect the new data flow. [1] [2] [3] [4]

@github-actions github-actions Bot added the added label Oct 1, 2026
@LKasianAnsys LKasianAnsys changed the title Feat/3.5b client uses server owned variables feat: [Remote rendering 3.5b] client uses server owned variables Oct 1, 2026
@github-actions github-actions Bot added the enhancement New feature or request label Oct 1, 2026
@LKasianAnsys
LKasianAnsys force-pushed the feat/3.5a-move-variable-ownership-to-server branch from a6e2619 to 328ccf1 Compare October 2, 2026 17:22
@LKasianAnsys
LKasianAnsys force-pushed the feat/3.5b-client-uses-server-owned-variables branch from c04cb7f to 77400e7 Compare October 2, 2026 17:30
@LKasianAnsys LKasianAnsys self-assigned this Oct 2, 2026
@LKasianAnsys
LKasianAnsys force-pushed the feat/3.5b-client-uses-server-owned-variables branch from c74c908 to bf18e1b Compare October 6, 2026 11:57
@LKasianAnsys
LKasianAnsys force-pushed the feat/3.5a-move-variable-ownership-to-server branch from 08b8ab1 to be7deda Compare October 6, 2026 16:40
@LKasianAnsys
LKasianAnsys force-pushed the feat/3.5b-client-uses-server-owned-variables branch from bf18e1b to 40fb6b1 Compare October 6, 2026 16:41
@LKasianAnsys
LKasianAnsys force-pushed the feat/3.5b-client-uses-server-owned-variables branch from 40fb6b1 to 857b098 Compare October 7, 2026 20:29

@ansBAkula ansBAkula left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@LKasianAnsys Cool stuff again.

I tried to break the "a dataset containing an array with a component count the client has no labels for" case by manually setting numComponents to 14 in the state JSON file and then loading it back. However, it loaded successfully and did not throw any error.

Also, you mentioned that labels are currently supported for component counts 1, 2, 3, 4, and 9. I can easily map 1, 2, 3, and 9 to common field types, but I'm curious about 4. What kind of field or use case does the 4-component label correspond to?

@LKasianAnsys

Copy link
Copy Markdown
Collaborator Author

@ansBAkula Thanks! Yes, editing numComponents in the state file doesn't reach that path; the server builds the variable records from the dataset arrays themselves, and the file only carries custom ranges across by ID. If you also edit the ID, it matches no record and the color restore on that part is refused with a server warning. (It is a best-effort state application; it doesn't abort the whole state-load, which is why you'd see a server log warning rather than the whole operation failing.)

To hit that path, you need actual data with an unsupported width, for example a dataset where at least one part has a 6-component array. With the latest commit on this branch it should not throw an error: setRecords skips that variable with one console.warn and keeps the rest, and later updates still apply. Before that commit the throw blocked every later push.

If you do test on a dataset with, say, a 6-component variable, you should see the following:

  • The server will create a record for the 6-component variable, no errors (it doesn't know about limitations on numbers of components)
  • The client will ignore it, and will log a warning in the console
  • The client will display any other variables that do have an allowed number of components.

For the 4-component with: yes good question. It looks like we display this as [x, y, z, w], so as a quaternion. The supported widths are a client-side limit for now, which preserves the previous behaviour. Having said that, we may want to move this to the server instead; but that's left as a later decision.

@LKasianAnsys
LKasianAnsys requested a review from ansBAkula October 9, 2026 13:57

This branch has not been deployed

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

Labels

added enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants