# Display fibers as tube with non-uniform radius

**URL:** <https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562>\
**Category:** Development\
**Created:** [July 13, 2019, 3:20pm UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562 "2019-07-13T15:20:36Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![fpsiddiqui91](https://avatars.discourse-cdn.com/v4/letter/f/53a042/32.png) [@fpsiddiqui91](https://discourse.slicer.org/u/fpsiddiqui91)\
**Post date:** [July 13, 2019, 3:20pm UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/1 "2019-07-13T15:20:36Z")

</div>

Hello Developers,  
I am trying to implement something similar to center line module. I want a non unifrom tube (something like vessel) around my fibers.

Can you guide how can I get something like this? How can I use center line module in my own application?

Thank you

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [July 13, 2019, 11:57pm UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/2 "2019-07-13T23:57:03Z")

</div>

If your input is vtkPolyData with points and point scalars for radius then you can use vtkTubeFilter to generate tube with the desired radius at each point.

---

<div class="post-metadata">

**Author:** ![fpsiddiqui91](https://avatars.discourse-cdn.com/v4/letter/f/53a042/32.png) [@fpsiddiqui91](https://discourse.slicer.org/u/fpsiddiqui91)\
**Post date:** [July 14, 2019, 11:10am UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/3 "2019-07-14T11:10:00Z")

</div>

Thank you for your response. I am generating the tube around my points like this

```
  def createTube(self,cord):
print ("tube mai")

modelNode = slicer.vtkMRMLModelNode()#slicer.util.getNode('SphereModel')
sizeLine = np.shape(cord)
numPoints=sizeLine[0]
lineCellArray = vtk.vtkCellArray()
lineCellArray.InsertNextCell(numPoints)
points = vtk.vtkPoints()

for i in xrange(numPoints):
  points.InsertPoint(i,cord[i])

for i in xrange(numPoints):
  lineCellArray.InsertCellPoint(i)

linePolyData = vtk.vtkPolyData()
linePolyData.SetPoints(points)
linePolyData.SetLines(lineCellArray)

tubeSegmentFilter = vtk.vtkTubeFilter()
tubeSegmentFilter.SetInputData(linePolyData)
tubeSegmentFilter.SetRadius(5) # INSERT VALUE
tubeSegmentFilter.SetNumberOfSides(10) # INSERT VALUE
tubeSegmentFilter.CappingOn()
tubeSegmentFilter.Update()
display=modelNode.GetDisplayNode()
display.SetOpacity(0.5)
modelNode.SetAndObservePolyData(tubeSegmentFilter.GetOutput())

```

The problem is I cannot give Radius array as tubeSegmentFilter.SetRadius(Array). It requires float as an input.

Thank you so much for your help.

---

<div class="post-metadata">

**Author:** ![ljod](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/ljod/32/652_2.png) [@ljod](https://discourse.slicer.org/u/ljod)\
**Post date:** [July 14, 2019, 11:58am UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/4 "2019-07-14T11:58:04Z")

</div>

Check out the vtk doc on this filter:  
[https://vtk.org/doc/nightly/html/classvtkTubeFilter.html](https://vtk.org/doc/nightly/html/classvtkTubeFilter.html)

Look at the methods related to VaryRadius. Not sure how you specify which scalar to use, but probably setting the active scalar on your polydata will work.

---

<div class="post-metadata">

**Author:** ![fpsiddiqui91](https://avatars.discourse-cdn.com/v4/letter/f/53a042/32.png) [@fpsiddiqui91](https://discourse.slicer.org/u/fpsiddiqui91)\
**Post date:** [July 14, 2019, 12:31pm UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/5 "2019-07-14T12:31:31Z")

</div>

Thank you so much for you help Andras and Lauren. I have managed to fix the problem. I am attaching the code for others.

```
  def createTube(self,cord):

modelNode = slicer.vtkMRMLModelNode()#slicer.util.getNode('SphereModel')
sizeLine = np.shape(cord)
numPoints=sizeLine[0]
lineCellArray = vtk.vtkCellArray()
lineCellArray.InsertNextCell(numPoints)
points = vtk.vtkPoints()

for i in xrange(numPoints):
  points.InsertPoint(i,cord[i])

for i in xrange(numPoints):
  lineCellArray.InsertCellPoint(i)

#Add radius
tubeRadius=vtk.vtkDoubleArray()
tubeRadius.SetNumberOfTuples(numPoints)
tubeRadius.SetName("TubeRadius")

for i in range(numPoints):
  radius=0.5*i #variable radius
  tubeRadius.SetTuple1(i, radius)

linePolyData = vtk.vtkPolyData()
linePolyData.SetPoints(points)
linePolyData.SetLines(lineCellArray)
linePolyData.GetPointData().AddArray(tubeRadius)
linePolyData.GetPointData().SetActiveScalars("TubeRadius")

tubeSegmentFilter = vtk.vtkTubeFilter()
tubeSegmentFilter.SetInputData(linePolyData)

tubeSegmentFilter.SetNumberOfSides(10) # INSERT VALUE
tubeSegmentFilter.CappingOn()
tubeSegmentFilter.SetVaryRadiusToVaryRadiusByAbsoluteScalar()
tubeSegmentFilter.Update()

modelNode.SetAndObservePolyData(tubeSegmentFilter.GetOutput())
modelDisplay = slicer.vtkMRMLModelDisplayNode()
modelDisplay.SetOpacity(0.5)
slicer.mrmlScene.AddNode(modelDisplay)
modelNode.SetAndObserveDisplayNodeID(modelDisplay.GetID())
modelDisplay.SetInputPolyDataConnection(modelNode.GetPolyDataConnection())
slicer.mrmlScene.AddNode(modelNode)
```

---

<div class="post-metadata">

**Author:** ![Roni](https://avatars.discourse-cdn.com/v4/letter/r/eada6e/32.png) [@Roni](https://discourse.slicer.org/u/Roni)\
**Post date:** [July 18, 2019, 9:36am UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/6 "2019-07-18T09:36:03Z")

</div>

@fpsiddiqui91

Grt that you found the solution. I am sort of stuck on a more implementation of my question. I already have a centerline computed, which had points and radius. But i just don’t know how i can use them?

Andras had answered and i went through the vtk examples. However, i am an ameture in python coding and i also do not know the child functions of each module. So your explanation would help someone beginner like me. My question is

1. Could you may be help me understand the logic/steps you are taking by just typing comments next to the steps? (e.g. i want to know if you are generating the points and radius or using it from some model?)
2. what would be your advice if i already have the points and radius for each center point? (which part of code should i ignore? and if you know which child function to use to port the data.

e.g.  
`1 c = getNode('ComputationModel')`  
computation model is computed based on vmtk centerlinemodel

`2 lineMapper = vtk.vtkPolyDataMapper()`  
`3 lineMapper.SetInputConnection(c.GetOutputPort())`  
–\> I want to directly feed the points and radius from my model in this step  
`get error at this step.. object has no attribute 'GetOutputPort'`

if i change line 3 to  
`3 lineMapper.SetInputConnection(c.GetOutputPolyData())`  
`get error at this step.. object has no attribute 'GetOutputPolyData'`

Your insight would be really helpful.

---

<div class="post-metadata">

**Author:** ![fpsiddiqui91](https://avatars.discourse-cdn.com/v4/letter/f/53a042/32.png) [@fpsiddiqui91](https://discourse.slicer.org/u/fpsiddiqui91)\
**Post date:** [July 18, 2019, 11:45am UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/7 "2019-07-18T11:45:58Z")

</div>

Hey,

I am actually getting my points and Radius from my own functions (They are just numpy arrays). I am just feeding them in visualization pipeline. You can find in the code how it has been converted to vtk points.

Moreover, computational model does not have Getoutput fuction in it. you need to extract the points, make a line out of it and then you can use the tube filter .

See the code:

```python
def createTube(self,cord,Radius,Opacity,Color): ##input arguments are the points, Radius , Opacity of the tube and Color
    print ("tube mai")

    modelNode = slicer.vtkMRMLModelNode()
    sizeLine = np.shape(cord)
    numPoints=sizeLine[0]
    lineCellArray = vtk.vtkCellArray()
    lineCellArray.InsertNextCell(numPoints)
    points = vtk.vtkPoints()

    for i in xrange(numPoints):
      points.InsertPoint(i,cord[i]) #These points are calculated in my own function

    for i in xrange(numPoints):
      lineCellArray.InsertCellPoint(i)

    #Add radius
    tubeRadius=vtk.vtkDoubleArray()
    tubeRadius.SetNumberOfTuples(numPoints)
    tubeRadius.SetName("TubeRadius")

    for i in range(numPoints):

      tubeRadius.SetTuple1(i, Radius[i]) #Radius is feeded in from another function

    linePolyData = vtk.vtkPolyData()
    linePolyData.SetPoints(points)
    linePolyData.SetLines(lineCellArray)
    linePolyData.GetPointData().AddArray(tubeRadius)
    linePolyData.GetPointData().SetActiveScalars("TubeRadius")

    modelNode1 = slicer.vtkMRMLModelNode()
    modelNode1.SetAndObservePolyData(linePolyData)
    modelDisplay1 = slicer.vtkMRMLModelDisplayNode()
    modelDisplay1.SetVisibility(True)
    modelDisplay1.SetColor(0.7, 0.1, 0.1)
    modelDisplay1.BackfaceCullingOff()
    modelDisplay1.SetLineWidth(3.5)

    slicer.mrmlScene.AddNode(modelDisplay1)
    modelNode1.SetAndObserveDisplayNodeID(modelDisplay1.GetID())
    modelDisplay1.SetInputPolyDataConnection(modelNode1.GetPolyDataConnection())
    slicer.mrmlScene.AddNode(modelNode1)

    tubeSegmentFilter = vtk.vtkTubeFilter()
    tubeSegmentFilter.SetInputData(linePolyData)

    tubeSegmentFilter.SetNumberOfSides(10) # INSERT VALUE
    tubeSegmentFilter.CappingOn()
    tubeSegmentFilter.SetVaryRadiusToVaryRadiusByAbsoluteScalar()
    tubeSegmentFilter.Update()

    modelNode.SetAndObservePolyData(tubeSegmentFilter.GetOutput())
    modelDisplay = slicer.vtkMRMLModelDisplayNode()
    modelDisplay.SetOpacity(Opacity)
    modelDisplay.SetColor(Color)
    slicer.mrmlScene.AddNode(modelDisplay)
    modelNode.SetAndObserveDisplayNodeID(modelDisplay.GetID())
    modelDisplay.SetInputPolyDataConnection(modelNode.GetPolyDataConnection())
    slicer.mrmlScene.AddNode(modelNode)

```

---

<div class="post-metadata">

**Author:** ![Roni](https://avatars.discourse-cdn.com/v4/letter/r/eada6e/32.png) [@Roni](https://discourse.slicer.org/u/Roni)\
**Post date:** [July 18, 2019, 1:08pm UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/8 "2019-07-18T13:08:22Z")

</div>

Hi @fpsiddiqui91 , Thanks for the quick reply and information.

Not sure if i understood completely your code, so just request you to breakit down for me.

```auto
modelNode = slicer.vtkMRMLModelNode() #does it create the node or it get's a node?
sizeLine = np.shape(cord) #what is np here ? and what becomes SizeLine ?
numPoints=sizeLine[0] #this gives you single number say 200/15 depending on value in [0] point?
lineCellArray = vtk.vtkCellArray()  
lineCellArray.InsertNextCell(numPoints) #Don't get this statement at all.
points = vtk.vtkPoints()  

for i in xrange(numPoints): #what is xrange? how do you define it?
  points.InsertPoint(i,cord[i])             

for i in xrange(numPoints): #Same what is xrange?
  lineCellArray.InsertCellPoint(i)

#Add radius
tubeRadius=vtk.vtkDoubleArray()
tubeRadius.SetNumberOfTuples(numPoints)
tubeRadius.SetName("TubeRadius")

for i in range(numPoints): #What is range here? where is it defined?

  tubeRadius.SetTuple1(i, Radius[i])       

linePolyData = vtk.vtkPolyData()
linePolyData.SetPoints(points)
linePolyData.SetLines(lineCellArray)
linePolyData.GetPointData().AddArray(tubeRadius)
linePolyData.GetPointData().SetActiveScalars("TubeRadius")

```

Could you clarify the comments/questions asked after # in your code above? I know i sound really newbie, but if you could do that, it will be a great help.  
Thanks

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [July 18, 2019, 1:18pm UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/9 "2019-07-18T13:18:13Z")

</div>

To speed up your progress, I would recommend to do a Python introduction tutorial, read the VTK textbook, play a bit with VTK examples, and complete Slicer programming tutorials. See links in [this post](https://discourse.slicer.org/t/a-free-biomedical-image-analysis-and-visualization-2-day-course/2584/10).

---

<div class="post-metadata">

**Author:** ![Roni](https://avatars.discourse-cdn.com/v4/letter/r/eada6e/32.png) [@Roni](https://discourse.slicer.org/u/Roni)\
**Post date:** [July 22, 2019, 7:43am UTC](https://discourse.slicer.org/t/display-fibers-as-tube-with-non-uniform-radius/7562/10 "2019-07-22T07:43:29Z")

</div>

Thanks Andras for the information about resources. That’s very helpful.
