I have a .csv file with (x,y,z) positions of start and end positions of cylinders.
I would like to import this into paraview and create the cylinders givent the (x,y,z) of start points, and (x,y,z) of end points and specify the radius.
Is this possible?
I will leave an example .csv file: foo.csv (1.2 KB)
In Programmable Source, I tried to use Cylinder Source and it became very complicated. nicolas.vuaille is right, it is much better to use Tube filter.
Just for reference, here is a dirty script for Programmable Source.
import numpy as np
import vtk
# CSV file to define the cylinders
csv_file = 'C:/Users/icem/Desktop/cyl/foo.csv'
# cylinder radius
r = 0.025
# CSV file reading
data = np.genfromtxt(csv_file, skip_header=2, dtype=None, names=['start_x','start_y','start_z','end_x','end_y','end_z'], delimiter=',', autostrip=True)
# obtain starting and ending coordinates of cylinders
start_pnts = np.vstack([data['start_x'],data['start_y'],data['start_z']]).T
end_pnts = np.vstack([data['end_x'],data['end_y'],data['end_z']]).T
appender = vtk.vtkAppendPolyData()
for start_pnt, end_pnt in zip(start_pnts, end_pnts):
# center coordinates of a cylinder
center = (start_pnt + end_pnt)*0.5
# direction vector of a cylinder
direc = end_pnt - start_pnt
# height of cylinder
h = np.linalg.norm(direc)
# define the local coordinate system of a cylinder
dir2 = direc / h
dir1 = np.array([dir2[1], -dir2[0], 0])
dir1 /= np.linalg.norm(dir1)
dir3 = np.cross(dir1, dir2)
# basis transformation matrix of the local coordinate system of a cylinder
T = np.array([dir1, dir2, dir3]).T
T = np.concatenate([T, np.zeros((3,1))], axis=1)
T = np.concatenate([T, np.zeros((1,4))], axis=0)
T[3, 3] = 1.0
# create a cylinder
cyl = vtk.vtkCylinderSource()
cyl.SetCenter([0,0,0])
cyl.SetRadius(r)
cyl.SetHeight(h)
cyl.SetResolution(100)
cyl.Update()
# transforms cylinder along its local coordinate system
transform = vtk.vtkTransform()
transform.PostMultiply()
transform.SetMatrix(T.flatten())
transform.Translate(center)
transformFilter = vtk.vtkTransformPolyDataFilter()
transformFilter.SetInputData(cyl.GetOutput())
transformFilter.SetTransform(transform)
transformFilter.Update()
# add a cylinder to appender
appender.AddInputData(transformFilter.GetOutput())
appender.Update()
output.DeepCopy(appender.GetOutput())
Really appreciate your help.
It can be very helpful to me.
Actually, I have a question about this problem.
In my case, I need to add various tube radii and colors.
But the error showed only scalar-type data is available.
Could you help me to solve this problem?
If the radius of each cylinder changes, you may want to add an array of radii to the zip function. Also, if you need to color by RGB, the following is a good guide.