# Algorithm interface (non-pipelined)

**URL:** https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417
**Category:** Development
**Created:** [October 4, 2023, 5:31pm UTC](https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417 "2023-10-04T17:31:56Z")
**Posts on this page:** 8
**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: [October 4, 2023, 5:31pm UTC](https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417/1 "2023-10-04T17:31:57Z")

</div>

Hi Developers

I am making some algorithms, which are meant for assignment to a filter. More precisely registration algorithms, which I will use in homemade `vtkContinuousRegistrationFilter` inheriting from `vtkTemporalAlgorithm`.

I would them to implement `UpdateProgress`, `CheckAbort` and a `SetSource(vtkPointSet*)` and `SetTarget(vtkPointSet*)`. The containing filter `vtkContinousRegistrationFilter` should use the internal algorithm for its execution.

Would the right approach be to inherit `vtkAlgorithm` and set the number of input and output ports to zero or would you prefer another design?

After execution of the internal registration algorithm, the output is just a homogeneous transform.

Thanks in advance  
Jens

---

<div class="post-metadata">

### Author: ![Yohann\_Bearzi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/yohann_bearzi/32/671_2.png) [@Yohann\_Bearzi](https://discourse.vtk.org/u/Yohann_Bearzi)
#### Post date: [October 9, 2023, 12:59pm UTC](https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417/2 "2023-10-09T12:59:23Z")

</div>

Are you trying to embed a `vtkAlgorithm` inside `vtkContinuonsRegistration`? I would appreciate a bit more details on the design you are trying to come up with, it is not very clear to me right now.

There is a new base algorithm called `vtkForEach` (in master) which could potentially help better than `vtkTemporalAlgorithm` for your specific use case. There is a discourse discussion about it [there](https://discourse.vtk.org/t/introduce-vtkforeach-filter/12448). Don’t hesitate to interact in the thread if it is of interest.

---

<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 9, 2023, 5:02pm UTC](https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417/3 "2023-10-09T17:02:44Z")

</div>

Thanks for reaching out. Yes, I have created a virtual subclass of `vtkPointSetAlgorithm` implementing a `SetSource` and a `SetTarget`. It contains threaded versions for finding correspondences using either closest point or rays. I am working on multiple classes implementing this interface for ICP(point-to-point, point-to-plane, plane-to-plane), the possibility for using Gauss-Newton or Levenberg-Marquardt optimizers. It is a spare-time project I am making to convince my employer that VTK may be a good framework for product, but it is kind of a long shot.

Right now, I only support `vtkPolyData` and a new polydata with a smaller memory footprint, where the triangulation is stored in cell and point data. For the subclass I am using the possibility to cancel and provide progress. The `vtkContinuousRegistration` has a method `SetRegistrationAlgorithm`. The next months, I will only work on the registration and not so much on the real-time part.

I have a feature branch, where some of this is outlined (only the idea). I am primarily working on a (right now non-public) stand-alone project made roughly like the `vtkDICOM` was - hence I use the VTK pipeline.

---

<div class="post-metadata">

### Author: ![Yohann\_Bearzi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/yohann_bearzi/32/671_2.png) [@Yohann\_Bearzi](https://discourse.vtk.org/u/Yohann_Bearzi)
#### Post date: [October 9, 2023, 5:59pm UTC](https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417/4 "2023-10-09T17:59:51Z")

</div>

I am not sure I understand why you want a `vtkAlgorithm` with zero input and output ports.

Let me summarize what I understand from what you described: You want to have a class of filters that do iterative geometry processing on point clouds (such as ICP and such). You are thinking about doing it considering your dataset as a temporal dataset, having something like output\_{t+1} = filter(output\_t) with output\_0 = input, until convergence, and you want to be able to see intermediary results at will.

The way I would design that would be by having a subclass of `vtkTemporalAlgorithm` embedded inside a larger filter. It sounds to me that you want to have something like:

```auto
class vtkContinuousRegistrationFilter
{
public:
  // SetTarget SetSource etc.

  // subclasses need to define when we converged to the solution
  virtual bool Converged() = 0;

protected:
  vtkSmartPointer<vtkAlgorithm> Implementation;
};

int vtkContinuousRegistrationFilter::RequestData(/* ... */)
{
  vtkPointSet* target = GetTargetSomehow();
  vtkPointSet* source = GetSourceSomehow();

  this->Implementation->SetInputSource(source);
  this->Implementation->SetInputTarget(target);

  int iteration = 0;
  while (!this->Converged())
  {
    this->Implementation->UpdateTimeStep(iteration++);
  }

  // Deal with output

  return 1;
}

```

Say you create a subclass `vtkMyFilter`, and here is how `vtkMyFilter.cxx` would look like:

```auto
namespace
{
class vtkImplementation : public vtkTemporalAlgorithm<vtkPolyData>
{
  // Implementation
  // Need to cache previous output to generate next output
};
} // anonymous namespace

vtkMyFilter::vtkMyFilter()
  : Implementation(vtkSmartPointer<vtkImplementation>::New())
{}

bool vtkMyFilter::Converged() { /* some criterion */ }

```

---

<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 9, 2023, 6:23pm UTC](https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417/5 "2023-10-09T18:23:37Z")

</div>

That is not what I want (or not entirely).

Two weeks a go, I uploaded a branch of a preliminary `vtkContinuousRegistrationFilter` that does work in the case the input is from a `vtkFileSeriesReader` providing temporal data downstream. The branch is called temporalRegistration and I have included some file series readers to ensure that the example, `TestContinousPointRegistration` works. All registrations are implicit and since the `vtkPointSet` does not have an orientation and position, I have decided to keep the results of the registrations in FieldData.

I have a temporal pipeline either live or with feed from a `vtkFileSeriesReader`. The `vtkContinousRegistrationFilter` will register an input to the previous dataset. In the feature branch, the filter simple returns the first dataset and keeps a reference for registration of the next input. Soon, it will continue executing instead until two successive inputs has been registered to one-another and return the first of the input and keep a shallow copy of the second for continuous registration. Further down the pipeline, I update a signed distance field (in-progress) and extract a larger mesh. The `vtkContinuousRegistrationFilter` will at a later time own a reference to a larger mesh and be able to register to this mesh using RANSAC.

The only reason why I introduce a `vtkContinuousRegistration` is to isolate the temporal aspects for continuity and allow the possibility for changing the registration algorithm and also the “resnap” algorithm, which could be RANSAC. This is a typical pipeline for solving a SLAM problem.

---

<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 9, 2023, 6:49pm UTC](https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417/6 "2023-10-09T18:49:35Z")

</div>

For real-time application, what I hope to be able to do is the following.

Insert a dataset into the pipeline  
Update at the end of the pipeline, if only one dataset I will get an empty output  
Insert another dataset into the pipeline  
Update at the end of the pipeline. I `vtkTemporalDataSetCache` with length 2 is at the beginning of the pipeline, so now I can get an output.

I was considering to have a module in the beginning which exposed a `TIME_RANGE` downstream and set the `UPDATE_TIME_STEP()` at the end before each update. I guess with the new `vtkTemporalAlgorithm`, I will need to run it in real-time mode where I request each temporal update - also in the case of knowing all time steps in advance. I will figure it out when I get to this. Right now, I am working on the registration algorithms and doing some experiments with FLANN, since I am not really satisfied with the performance of the VTK locators. I managed to get an almost linear speed-up by using SMPTools, where the correspondences are made using by a modified `vtkImplicitPolyDataDistance`, where I can get both the closest point and an interpolated normal - the `SharedEvaluate` is not public at moment.

---

<div class="post-metadata">

### Author: ![Yohann\_Bearzi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/yohann_bearzi/32/671_2.png) [@Yohann\_Bearzi](https://discourse.vtk.org/u/Yohann_Bearzi)
#### Post date: [October 9, 2023, 8:03pm UTC](https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417/7 "2023-10-09T20:03:26Z")

</div>

Can you describe what the internal algorithm would be? I am having trouble fully understanding what you are intending to do. Maybe you could give a coarse execution trace of an example?

---

<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 9, 2023, 8:44pm UTC](https://discourse.vtk.org/t/algorithm-interface-non-pipelined/12417/8 "2023-10-09T20:44:27Z")

</div>

Sure, you could also run the test in my remote branch. It does exactly what I want except that here all time-steps are known beforehand. It is a little difficult without implementing everything.

```
RealTimeSource -> TemporalCache(2) -> ContRegistration   

contReg->Update():

```

Internals:

- Search upstream and register two consecutive temporal datasets to one another. If a LastTarget exist, try instead to register to this, but only if the new data data is at time `i` and the old last target is at time `i-1`. If this fails, we need to reset the internals, since we only interested in having a chain of datasets each registered a previous dataset at one time step earlier.
- If registration succeeds, store the most recent dataset as a LastTarget and return the current data with a transformation relative to the first Source. I am concatenating transforms internally to fulfill this.

Further down the pipeline, I will update a truncated signed distance field and every now and then, I can extract a mesh. In the image, I have shown my application doing exactly this - except this is not made with a temporal pipeline, but a bunch of callbacks and some global variables.

 ![image](https://discourse.vtk.org/uploads/default/original/2X/2/22c37218c3ff219dd3fc4c57becf26fafec7dbb0.jpeg)
