VTK.js Proxies

Hi!

Would it be possible to have a fairly simple example of proxies declaration and usage?
I know there’s the ParaView Glance example, but I find it quite hard to understand everything that is involved to manage the rendering pipelines with proxies.

Is there any example somewhere offering some understanding on the proxyManager and a single 3D or 2D view to help me code with those kinds of higher level pipeline management objects?
To be more precise, I’m searching for more information on the interactions between the proxyManager, a viewProxy and a representation for a vtkImageData dataset.

Hi, there is unfortunately no good documentation on proxies at the moment, nor can I think of a good example project at the moment. I can give you some info on how you can get started with proxies, however, using paraview-medical as a simpler example than paraview glance.

  • A sample proxy config can be found in proxy.js. The definitions object defines Groups (e.g. Sources, Representations) and their constituents (e.g. TrivialProducer is part of the Sources group), while representations maps a vtk object type to a representation name for a given view. (e.g. vtkImageData uses the Volume representation for the View3D view.)
  • Just to get started, you can try a single volume representation, as seen at proxy.js:59. You’ll need to keep the Sources group and the TrivialProducer, since that represents a proxy that produces a stored object. (Terminology borrowed from ParaView)
  • You’ll need to create a ProxyManager in order to use your proxy config. Example
  • In order to use proxies to visualize a vtkImageData, you first need to add it to a TrivialProducer proxy. Example. You will also need to create a ViewProxy, e.g. proxyManager.createProxy('Views', 'View3D', { name: 'my3DView' }).
  • Finally, you need to create the proper representation of your source proxy and add it to your view. Example code is given below.
source = proxyManager.createProxy('Sources', 'TrivialProducer', { name: 'myImage' });
source.setInputData(myImageData);
view = proxyManager.createProxy('Views', 'View3D', { name: 'my3DView' });
view.setContainer(someHTMLElement);
rep = proxyManager.getRepresentation(source, view);
view.addRepresentation(rep);

Hi Forrest, Speaking of paraview-medical, I have a question. I opened the website https://paraview-medical.netlify.app/ and import my dicom series. But when I want to use the Paint or Ruler, I feel confused. In more detail, even though I clicked Paint/Ruler, I still can only use left mouse button to change the window/level. From the console, I get the information “vtkProxyManager did not request an animation”. So how can I do some annotations and measurements with the Paint and Ruler? Thanks in advance.

Hi Forrest!
Thank you so much for the example of ParaView-medical. It always helps to have more examples!

I explored quite a lot the source code of vtk.js and i’d have some questions regarding a few details and about the links.
At first, i’m a bit curious about the “Representation” group declared in the “definitions” and the “representation” section. I know from the “createProxy” function that you can’t create a proxy that isn’t in the definitions. However, what would happen if we add the representation to a viewProxy and it is not inside the “representation” section?
For example, i have in my project a working 3DView with proxies without having anything in the representation section…


edit
I’m creating the representation with createProxy and then adding it to the view with “addRepresentation”. But i can see in the “getRepresentation” function that it can create the representation if it doesn’t exist and if it’s defined in the “Definitions” section


About the links in the proxy configuration, i read a view useful functions in the macro file (proxy, setImmediateVTK, registerLinks, registerPropertyLinkForGC) and i’m trying to figure out how i can use these links and how are they useful. Is there a list of property that can be bound? Are they properties from any vtk objects (render window, interactor, mapper) or they’re more about representation properties?

If there’s a bit too much to explain, i’m always open to set up a video call

Again, thank you so much for your time! I hope this post will help people getting started with proxies!

You can manually create representation proxies and add them to a view proxy. The repreesentation definitions are only used when creating proxies through the ProxyManager, whether through createProxy or getRepresentation.

As for links, they allow you to synchronize properties of proxies, where a property is any value that has a getter and setter, e.g. the “slice” property corresponds to “getSlice” and “setSlice”. You can provide an array of links for each property you care about. Here’s one example from window/level for slices:

      SliceX: createSyncedSliceRepDefinition(
        vtkTransformedSliceRepresentationProxy,
        'X',
        [],
        [
          { link: 'WW', property: 'windowWidth', updateOnBind: true },
          { link: 'WL', property: 'windowLevel', updateOnBind: true },
        ]
      ),

Here, we have defined two links, one named “WW” and the other named “WL”. They correspond to the window width and level properties, respectively. These links mean that, whenever any SliceX representation’s window width or level changes, all other SliceX representations will also change to match. “updateOnBind” simply means to sync/receive values for a newly created SliceX representation.

Now there is one more flag not shown above: "type": "application". This means that any link of the same name will synchronize, regardless of which proxy definition it falls under. So, if SliceX and SliceY reps both have a link called “SyncedSlices” that had the type equal to “application”, then changing the SliceX slice index will update SliceY’s slice index as well.

Awesome!
This helps a lot to understand how to configure the proxy manager and the overall proxy workflow!

Also, I saw in the macro file that the ui part of the json is used to update the ui using a propertyMap.
So what kind of properties can we put in the ui part of the different configurations?
I can see in paraview Glance that they use the same properties as in the links but they’re specifiying domains…

So far the UI part is not used in Glance or else. But the goal was to enable a usage similar to ParaView so UI can be generated dynamically based on the possible parameters of a filter.

Isn’t ParaView Glance using the UI part with the links within the “ProxyUI” file?

Also, do you know if the usage of a store architecture is mandatory with vtk.js?
I’m asking this because i’m able to link different parameters between views now, but the ui only updates when a view receives a click…
So i’m wondering if i’m missing something in my proxy configuration or if the store is used for this in both ParaView Glance and ParaView Medical?

I don’t think Glance is using the UI part of the Proxy. My very first version of it did, but I don’t think we do now.

VueX store and proxy are un-related.