11 September 2017 at 22 h 36 min #9967
Is there any possibility to mark a target point/node on a FEM in SOFA and track their position after the deformation?
Basically I am interested in the displacement of some targets. Since the volumetric meshes will be deformed, I need to “track” those targets in order to make them to homologous points. Is there any similar function in SOFA which can do this?
Siming12 September 2017 at 11 h 23 min #9970HugoKeymaster
- SOFA Consortium
To my knowledge, there is no direct way. However, using python it can be pretty easy!
All you need to do is to add this in your XML scene:
<Node name="root" /> <RequiredPlugin name="SofaPython" pluginName="SofaPython" /> <PythonScriptController filename="trackingScript.py" classname="trackingScript"/> ... </Node>
and create your tracking script using python:
import Sofa import sys #your python class class trackingScript(Sofa.PythonScriptController): # after creation of the graph, then initialization comes # you need to retrieve the MechanicalObject associated to your object def initGraph(self,rootnode): self.yourNode = rootnode.getChild("YourNode") self.yourMO = self.yourNode.getObject("name_of_your_MechanicalObject") return 0 # called on each animation step def onBeginAnimationStep(self,dt): # here access the node you want .. vector_of_position = self.yourMO.findData('position').value print vector_of_position return 0
Hope this helps,
Hugo12 September 2017 at 14 h 12 min #9972
Great! Thank you Hugo!! I think this helps me a lot.
Today, I tried another work around: 1)use VTKExport to export the “position” and “rest_position”. 2)Substract them from each other via ParaView (These two steps are exactly the same as Michl´s methode in https://www.sofa-framework.org/community/forum/section/user-forum/using-sofa/). This works well and I am able to calculate the displacement of each node. Since I am not directly interested on the displacement of certain node, but on the displacement of certain voxels on a image volume which I generated previoursly based on the mesh (before and after deformation with FEA) by using VTK, I still face the problem how to find the right correspondence between certain nodes on the mesh and certain voxel on the image. So maybe I can use your script to track some nodes directly in SOFA and combine the result with VTK. I´ll try.
Siming12 September 2017 at 14 h 42 min #9973MPfeifferParticipant
- NCT Dresden
If I understand you correctly, I recently did something very similar to what you are trying to accomplish. I export the SOFA result using the VTKExporter and then wrote a “voxelize” program which uses VTK to resample the results into a regular grid.
The “vtkProbeFilter” does what you want. Here’s a small excerpt from the code:
// Perform the interpolation vtkSmartPointer<vtkProbeFilter> probeFilter = vtkSmartPointer<vtkProbeFilter>::New(); probeFilter->SetValidPointMaskArrayName("mesh"); probeFilter->SetSourceData( ugrid ); probeFilter->SetInputData( cellCenters ); // Interpolate 'Source' at these points probeFilter->Update();
Here, “ugrid” is a vtkUnstructuredGrid, “cellCenters” is a vtkPolyData which was previously filled with points (which can either be done manually or, if you already have the goal structure, by taking the cell centers of the image which you mentioned).
Micha12 September 2017 at 21 h 24 min #9974
Thank you for this piece of code. Yes, I am actually looking for a method to interpolate the displacement on the nodes to a image volume. So “vtkProbeFilter” could be the solution.
Siming12 September 2017 at 23 h 26 min #9975
by the way, what do you mean by “cell centers” of the image? I have generated a binary image from the mesh by using “vtkPolyDataToImageStencil”, which means my image is a standard DICOM image volume….
Siming13 September 2017 at 9 h 05 min #9978MPfeifferParticipant
- NCT Dresden
The way I use the vtkProbeFilter is that I generate a regular grid of cubic elements first and then want to calculate a value from the source data for each of these cubic elements. So I want to interpolate the source data at the center of each of the cubic cells, hence the name “cellCenters”.
I’ve never used vtkImageStencil, but if you originally have a vtkPolyData you might not need to get any cell centers, you might just be able to use the vtkPolyData you already have. The vtkProbeFilter documentation says that the “point attributes are computed at the Input point positions by interpolating into the source data”, so if your vtkPolyData contains a vertex at each position where you want to sample the source data (i.e. in every image pixel/voxel), you can just use that.
Just beware that if the vtkPolyData does not describe the pixel centers and instead describes the pixel corners, you might be interpolating at the wrong positions (offset of half a pixel size).
Did that answer the question?
Micha13 September 2017 at 22 h 29 min #9984
Yes, this really answer my question. According to the VTK Doc and your explanatation, I think I need to generate a new “vtkPolyData” from the binary image volume which I produced before, with the voxel center as the cell center. VTK should contains some filter to convert a binary image volume to vtkPolyData.
Thank you for your support.
By the way, since this is a SOFA Forum, I am not sure, wether it is appropriate to discuss issues only related to VTK. It seems like that our research topic are somehow related to each other. Would we like to have some more communication in the further via our mail? email@example.com
- You must be logged in to reply to this topic.