Serialization of VTK objects

The goal of this post is to inform others about the ongoing efforts regarding serialization/deserialization in VTK.
@alexy.pellegrini and @jaswantp started separate efforts to address slightly different use cases [1], and after sharing ideas, we identified a list of requirements that should allow for addressing as many use cases as possible.
The table below presents how both approaches address the requirements.
While it is likely that the automated approach is preferred, we would love to hear your opinion about it. The goal is to try to get the best of both worlds.
The idea is also to gather other potential use cases to extend this list of requirements.

[1] Use cases:
Jaswant: trame based server communicating with a VTK-wasm client
Alexy: VTK OpenXR application with multiple clients (XR collaboration)

A Jaswant Alexy
WIP vtk@add-object-manager vtk@serialization-common
Serialization of vtkObject properties Fully automated using wrapping infrastructure + manual exceptions Fully manual using new virtual methods introduced in vtkObject
Auto-generated properties relies on David Gobbi’s property parser in Wrapping/Tools(controlled by an exclusion list documented with reason for exclusion) Only objects reimplementing the virtual methods are serialized (provides control)
Non-intrusive: Serializer code outside the class. (Register generated serializers in a manager class automatically) Intrusive: Serialization code at the vtkObject level, this provides access to private members without any friendship or trick
Autogenerated Serialize/Deserialize function pointers are registered with typeid. Only properties explicitly serialized in the overridden method are serialized: Provides control, shortcuts (e.g. serializing a matrix as a double array instead of a whole object), only what is needed (some properties are redundant or not relevant)
Instantiation of vtkObject (deserialization) Constructors identified with class name Objects identified with class name
“Factory” to create vtkObjects from class name is auto-generated Factory to create vtkObjects from class name listed (hardcoded) in serializer class. To be improved.
Format JSON JSON
data arrays in separate blobs, referenced in the json with a unique hash. Input data in json, base64 encoded. Data strategy class available to change this behavior in subclasses
Incremental and asynchronous (new clients get the whole scene upon connection, existing clients only get what changes) Supported using MTime Supported using MTime
Context is local to the vtkObjectManager instance Context is local to a serializer instance
User code registration (serialize VTK custom subclasses from the application side) Marshaling is possible externally by providing user VTK modules to the vtk_module_marshal function in CMake. Public functions available to add new types to the hardcoded factory
CMake helper functions auto-generate registration code for (de)serialization handlers and constructors.
2 Likes

FYI @Sebastien_Jourdain @Forrest @jcfr @sankhesh @mwestphal @Francois_Mazen @finetjul

1 Like

Good write up and good work on trying to unify and share effort.

I understand how vtk@serialization-common works as each class as to serialize itself however I’m confused how a fully automtized solution as the one described in vtk@add-object-manager could work.

I understand that the wrapping mechanism is already a good base to identify which what is a property and how to recreate a class with the same property however I’m sure there will be hundreds of class that will not behave properly.

A few reasons comes to mind:

  • Initialization methods
  • Property order
  • Other reasons I have not thoughts about.

For this reason, vtk@serialization-common seems more realist and conservative.

As Lucas’s post mentions, it is fully automated but that doesn’t mean every single class is wrapped. Our solution adopts a combined approach with manual intervention where necessary. There are all in all, three levels of control. All of which are mentioned in Lucas’s post, but they might not be clear, so let me try to explain :slight_smile:

Fully automated using wrapping infrastructure + manual exceptions

This is the first level of control. It is an inclusion list defined in CMake. Only the modules and headers listed in there will be wrapped. See CMake/vtkModuleMarshallingLists.cmake

Auto-generated properties relies on David Gobbi’s property parser in Wrapping/Tools(controlled by an exclusion list documented with reason for exclusion)

This is the next level of control. It works to exclude troublesome properties of allowable classes. We document the reason why it’s excluded and this reason appears as a comment in the generated code. See vtkMarshalDefs.c

Non-intrusive: Serializer code outside the class. (Register generated serializers in a manager class automatically)

CMake helper functions auto-generate registration code for (de)serialization handlers and constructors.

Finally, the third level is possible because of those two features. It basically allows one to define their own (de)serialization handlers and autogenerate the registration code so they can be fed into the manager. In VTK, some classes like vtkAlgorithm, vtkDataArray use that. See Marshalling/Extensions. Those are hand-written!

I hope this helps better understand what’s going on.