I am looking at a problem, where a module needs to access data from the past. I am thinking of writing a module similar to vtkTemporalDataCache, but where data are stored using a time derived from GetMTime(), e.g. GetMTime() % (2 << 16) and made available using UPDATE_TIME_STEP(). If no UPDATE_TIME_STEP key is present, the cache will pass on the last data object. The modulo operation is to ensure elements can be located correctly using the double type, which is used for time-awareness.
In this way data will flow in a graph
A → CACHE → B → C, where a module e.g. C will have the possibility for query an input for a specific modification time.
The real problem is that I am running a segmentation in one pipeline and after the segmentation is complete a registration is performed, which must be applied to a pose from an earlier time. I have made a small source module, which exposes 4x4 matrices, which is connected to a port on my registration module. The registration module will then ideally fetch the correct 4x4 matrix for an earlier time using a modification time of the image.
I am sort of trying to build something that is time-aware rather than relying on application domain time.
Thanks in advance
Pretty complicated stuff Can you describe it a bit more specifically? For example, for the time stuff to work, you need to provide a time range and time steps. How are you doing that? The more details the better we can help .
Thanks for reaching out. You are right, pretty complicated stuff. I managed to create a simple source, which generates 4x4 matrices and where I can connect a vtkTransform. Also, I managed to create a modified version of the vtkTemporalDatasetCache and it works. Now I am stuck at some other issue / challenge.
I have made a vtkIGTServer, which is a sink and when updated, it will send its vtkImageData input from a single port using IGTLink. I have used a std::thread for waiting for connections. On the receiving end, I have implemented a vtkIGTClient, which uses a std::thread for receiving and inserting the data into a small circular buffer. When executing Update() on the client data are pulled. The problem is now that I want this to be synchronized with the input rate. I have created a vtkUserEvent and invokes this from the receiver thread. Is this safe? E.g. would it be okay for using this for calling Render(). In general is there a mechanism for moving a call to the thread of the event loop?
I have made everyting similarly to how the vtkDicom is made with IGTLink and an NDI driver residing in a ThirdParty folder. After a few iterations, I will consider adding this to the VTK repository if the community finds it interesting. It is kept extremely lightweight
If you create the render context in the main thread and then trigger rendering from a different thread via a VTK message then the application is expected to crash.
In a GUI application you can use mechanism provided by the GUI toolkit. For example, Qt provides very convenient and elegant mechanisms (Qt signals/slot mechanism works across threads).
If you want a pure-VTK solution then you can use C++ threading functions to safely communicate between threads.
Note that you don’t need to invent anything from scratch. Real-time multi-threaded acquisition of transforms and images and sending them via OpenIGTLink is implemented in Plus toolkit. Receiving of data via OpenIGTLink and rendering of tracked images is implemented in several medical image computing applications, such as 3D Slicer and MITK-IGT, CustusX, and Ibis. All free, open-source restriction-free software that you can use or copy-paste code from.
Thanks you Andras. I have stolen some parts from Plus Toolkit and created a client and a server (about 300 lines of code each). I find it convenient with a more minimalistic solution without Qt. Primarily because I have encountered a number of issues on Windows when combing VTK, Qt and Python. The issues appear when using PyQt5 og PySide2 from the python distribution.
I have not seen a crash yet, when simply invoking an event from a user thread. I could go check if this is implemented using an atomic. This would explain why it is working flawlessly. It I am going to use C++ threading functions I need a way to hook into the event loop created using vtkRenderWindowInteractor. The easiest way is to use a repeating timer and inside this use standard C++ threading functions (the reader thread can interrupt the event loop - this works, but perhaps it would be more elegant to create a new interactor I can give to the client receiving data).