# Adding transform to vtkDataSet

**URL:** <https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396>\
**Category:** Development\
**Created:** [September 30, 2023, 10:41pm UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396 "2023-09-30T22:41:58Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [September 30, 2023, 10:41pm UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/1 "2023-09-30T22:41:58Z")

</div>

I am working with registration and multiple `vtkObject`’s all inheriting from `vtkDataSet`. Currently, I add orientations as field data. It is really heavy to transform data explicitly and I would like to have a property on all data. Locally, I have added this to my own clone of `vtkDataSet`.

Most often, I end up using this transform as the user transform of an actor. Would it be an idea to add a transform to `vtkDataSet` in general? I know that you have already added an orientation to `vtkImageDataSet`.

Let me know your thoughts.

Thanks in advance  
Jens Munk

---

<div class="post-metadata">

**Author:** ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)\
**Post date:** [October 1, 2023, 8:59pm UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/2 "2023-10-01T20:59:43Z")

</div>

Hi,

Well, `vtkDataSet` is abstract. I mean, it doesn’t have all possible geometric attributes (e.g. vertex normal vectors, face normal vectors, etc.) found in its concrete implementations. A transform on `vtkDataSet` would have an ill-defined behavior.

regards,

PC

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [October 1, 2023, 9:09pm UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/3 "2023-10-01T21:09:21Z")

</div>

Sorry, my bad. It is of course, `vtkPointSet`, then I have it available on `vtkStructuredGrid` and `vtkPolyData` etc. Of course, then it won’t be available on `vtkRectilinearGrid`, which I sometimes use due to its smaller memory footprint than `vtkStructuredGrid`.

---

<div class="post-metadata">

**Author:** ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)\
**Post date:** [October 1, 2023, 9:22pm UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/4 "2023-10-01T21:22:46Z")

</div>

Well, please, check out the `vtkPointSetAlgorithm` family of point set algorithms: [VTK: vtkPointSetAlgorithm Class Reference](https://vtk.org/doc/nightly/html/classvtkPointSetAlgorithm.html) . There exists quite a number of algorithms for point sets. One likely suits your need.

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [October 1, 2023, 9:28pm UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/5 "2023-10-01T21:28:58Z")

</div>

I am working with multiple registrations (real-time) and for all `vtkPolyData`, `vtkStructuredGrid`, I interpret their positions always as the result of transforming them from a local reference frame to a global reference frame. When registering, I only update their transformation. As far as I am aware of, only the plain vanilla point-to-point ICP is available in `VTK` so obviously you have not have this need yet. More specifically, I work on registration algorithms for `vtkPointSet`, where I for `vtkPolyData` exploit if normals are defined.

Thanks for replying. For now, I will check if field data has a entry “UserTransform” and update this when I register.

---

<div class="post-metadata">

**Author:** ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)\
**Post date:** [October 2, 2023, 3:51am UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/6 "2023-10-02T03:51:01Z")

</div>

In 3D Slicer, we opted to add a higher-level container class (vtkMRMLNode and its vtkMRMLTransformableNode) that can store a VTK data object (vtkImageData, vtkPolyData, vtkUnstructedGrid, vtkGeneralTransform, point set, curve, plane, etc.) and reference a parent transform. This transform can be a composite, inverse, and/or non-linear transform. The design is quite simple, clean, compatible with filter and transform pipelines, and works well for real-time display. This design might not be optimal for all use cases, but it is definitely an option if we want to keep VTK simple.

If we are ready to make VTK more complex the I would go beyond just allowing specifying translation/rotation for vtkDataSet. Instead, scene graph support could be added to VTK, and there any transform could be used to transform a branch of the tree. It should be designed so that it could replace the current scene graph that is implemented in VTK-based applications (at least in ParaView and 3D Slicer).

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [October 2, 2023, 4:19pm UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/7 "2023-10-02T16:19:44Z")

</div>

That is an option - to wrap many filters using a container - not a fan. Working on a Robust ICP with a symmetric cost function capable of registering a source to a target, where either can be any `vtkPointSet`. Normals will be computed by other means if they are absent. I think the cleanest and minimal solution for me is to keep a “local-to-global” 4x4 matrix as part of the field data and when present they will be used. Also, the option to perform implicit/explicit registration, where in the case of implicit registration only the ‘local-to-global’ matrix of the source will be updated.

---

<div class="post-metadata">

**Author:** ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)\
**Post date:** [October 5, 2023, 5:07am UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/8 "2023-10-05T05:07:39Z")

</div>

> [@Jens\_Munk\_Hansen](#):
>
> I think the cleanest and minimal solution for me is to keep a “local-to-global” 4x4 matrix as part of the field data

Only supporting linear transforms would be a very significant limitation. What are you going to do when in the next phase of your project you’ll need to go beyond linear transforms and you have to write a registration algorithm that produces a warping transform?

Maybe a better solution would be to derive vtkAbstractTransform from vtkDataSet so that they can propagate between filter connections.

@dgobbi Do you know why VTK filters cannot provide transforms on their output ports (that could be pipelined to other filters input connections)?

---

<div class="post-metadata">

**Author:** ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)\
**Post date:** [October 5, 2023, 1:17pm UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/9 "2023-10-05T13:17:54Z")

</div>

> [@lassoan](#):
>
> Do you know why VTK filters cannot provide transforms on their output ports (that could be pipelined to other filters input connections)?

VTK transforms aren’t derived from vtkDataObject and therefore can’t be pipelined via VTK algorithms. Sometime around 2001 there was some discussion about making either vtkTransform or vtkMatrix4x4 into a vtkDataObject but nothing came out of it. All the developers had other priorities.

---

<div class="post-metadata">

**Author:** ![Jens\_Munk\_Hansen](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jens_munk_hansen/32/1215_2.png) [@Jens\_Munk\_Hansen](https://discourse.vtk.org/u/Jens_Munk_Hansen)\
**Post date:** [October 6, 2023, 12:02pm UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/10 "2023-10-06T12:02:29Z")

</div>

> [@dgobbi](#):
>
> 01 there was some discussion about making either vtkTransform or vtkMat

Nice to know. That would be a useful change.

I ended up implementing a `vtkPointSetRegistrationTransform` inheriting from `vtkAlgorithm` without any connections. It has a SetSource and SetTarget method and provide functionality for finding correspondences and normal vectors using SMPTools. For this, I have implemented a threadsafe `vtkImplicitPolyDataIntersection`. The reason why I need an interface is that I have a real-time pipeline and I would to be able to re-use the logic for the real-time aspects and be able to change the registration algorithm.

My plan is to implement ICP (point-to-point), ICP (point-to-plane), ICP (bi-directional point-to-plane). All of them robust and using Gauss-Newton.

---

<div class="post-metadata">

**Author:** ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)\
**Post date:** [October 10, 2023, 11:25am UTC](https://discourse.vtk.org/t/adding-transform-to-vtkdataset/12396/11 "2023-10-10T11:25:15Z")

</div>

Thank you for your insight @dgobbi - it is good to know that there is no fundamental design issue with unifying transform pipelines with filter pipelines. Somebody would just need the resources to implement it.

Currently, in 3D Slicer we manually update transforms whenever any transform input changes. This is very simple, but not optimal in the sense that the transform may be recomputed more frequently than needed (inputs may change more frequently than we need the output for rendering or analysis). However, this is not a strong enough motivation to invest a lot of time into improving the VTK pipeline infrastructure.
