Attach arrow to mesh

Hi all,

I have a mesh data set that I can deform using Warp by Vector filter. I also have another data set containing a single force vector (at location [0,0,0], with components [fx(t),fy(t),fz(t)]. I can use Transform filter to move that vector about, but I really want to attach it to a point of the mesh (or something to that effect). Any suggestions?

Kind regards, Eelco

Not very clear. Maybe you are looking for RessampleWithDataset filter ? Or Glyph ?

Sorry for the belated response.

I added some files in an attempt to clarify my question. The mesh consist of just a few random elements due to confidentiality, but i’ll do for now.

“eturret” is a dataset containing the mesh and has attributes displacement and deformation. Only Deformation has values, the displacement is all zero for now.

“mooring” is a dataset containing the data of a force vector.

I use Glyph to create an arrow for the mooring dataset. But I want to move (attach) the base of that arrow to a point on the mesh. Any point really. And I want it to follow that point, even if I apply the Warp by Vector filter to the mesh.

Hopefully this clarifies a little!

eturret.h5 (129.9 KB) eturret.xmf (45.1 KB) mooring.h5 (41.2 KB) mooring.xmf (35.3 KB) test.pvsm (564.2 KB)

There is not direct way to do that.

But there is the “specific” way and the “convoluted” way.

For the specific way, you will need to implement a simple programmable filter that will take two inputs, the mesh and the mooring, and copy the mooring vector into each points of the mesh. You can then use a glyph without any issue. You still need to implement it in python. Let me know if you need help.
https://www.paraview.org/Wiki/Python_Programmable_Filter

The convoluted way is a bit more tricky but does not require any python. Here it is :
testConvoluted.pvsm (834.6 KB)

The idea of this is that we consider your Arrow Glyph as a source input for a Glyph with custom source applied on the mesh. The problem is that your mooring is not located in the origin on the space, so I had to translate it. If the translation is constant with all your moorings or if this translation can be removed in post-process, this solution might be acceptable.

I managed to get it working using the programmable filter. The script will attach the vector to the nearest node wrt to the coordinates you put in manually. Here’s how I went about it:

  1. Put the mesh, the warped mesh and the mooring (vector) in a GroupDataSet
  2. Push the GroupDataSet through a programmable filter with the code below.
import numpy as np

# Input coordinates. The script will find the nearest node in the mesh.
x,y,z = 0,0,-1e3

input = self.GetInputDataObject(0, 0)

iter = input.NewIterator()
iter.UnRegister(None)
iter.InitTraversal()

# Warped mesh data set
curInput1 = iter.GetCurrentDataObject()
iter.GoToNextItem()
# Vector data set
curInput2 = iter.GetCurrentDataObject()
iter.GoToNextItem()
# Mesh data set
curInput3 = iter.GetCurrentDataObject()


# initialize currOutput
curOutput = curInput2.NewInstance()
curOutput.UnRegister(None)
curOutput.ShallowCopy(curInput2)

# create output and attach curOutput
output = self.GetOutputDataObject(0)
output.CopyStructure(input)
output.SetDataSet(iter, curOutput)

loc = []
NrOfPt = curInput3.GetNumberOfPoints()
for i in range(0,NrOfPt):
    loc.append(curInput3.GetPoint(i))
    
loc = np.asarray(loc)
loc[:,0]-=x
loc[:,1]-=y
loc[:,2]-=z

lsq     = lambda x: x[:,0]**2+x[:,1]**2+x[:,2]**2
NodeNr  = np.argmin(lsq(loc))

# Set currOutput to the node
loc = curInput1.GetPoint(NodeNr)
newPoints = vtk.vtkPoints()
newPoints.InsertPoint(0,loc[0],loc[1],loc[2])
curOutput.SetPoints(newPoints)
  1. Create an arrow glyph.

DRAWBACK:
Slow. Every time step the nearest node is calculated (which is always the same). It would be better to do this calculation independent of time, but I don’t know how to do that yet. Any advice is welcome!

KR, Eelco

1 Like