Hi Andras, I have tried on UnstructuredGridToVolume and refer to the code in below link: SlicerNotebookDemos/UnstructuredGridToVolume.ipynb at master · lassoan/SlicerNotebookDemos · GitHub
I believe the code is exactly the same except the input unstructuredGrid vtk file is generated by myself. Because in my case, I need convert ploydata to unstructuredGrid.
step 1: Generate the UnstructuredGrid vtk file in 3D Slicer python console, the code as blow:
v = slicer.util.getNode('View1')
v.SetBoxVisible(False)
# Sphere
sphereSource = vtk.vtkSphereSource()
sphereSource.SetCenter(0,0,0)
sphereSource.SetRadius(5.0)
sphereSource.Update()
sphereSource = sphereSource.GetOutput() # vtkPolyData()
# Create a model with the sphere and add it to scene
modelNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLModelNode')
modelNode.SetAndObservePolyData(sphereSource)
modelNode.CreateDefaultDisplayNodes()
modelNode.SetName('My sphere')
# Append the meshes
appendFilter = vtk.vtkAppendPolyData()
appendFilter.AddInputData(sphereSource)
appendFilter.Update()
ugrid = vtk.vtkUnstructuredGrid()
ugrid.DeepCopy(appendFilter.GetOutput())
writer = vtk.vtkUnstructuredGridWriter()
writer.SetFileTypeToASCII()
writer.SetFileName('unstructuredGrid.vtu')
writer.SetInputData(ugrid)
writer.Write()
after the above step, I got the generated unstructuredGrid file with the name ‘unstructuredGrid.vtu’
step 2: Use the generated UnstructuredGrid file as the input and converting it to volume. The code as below:
import math
# Load sample unstructured grid
def calculate_dimensions(bounds, spacing):
# compute dimensions
dim = [0]*3
for i in range(3):
dim[i] = int(math.ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i])) + 1
if dim[i] < 1:
dim[i] = 1
return dim
sampleModelFile = 'unstructuredGrid.vtu'
modelNode = slicer.util.loadModel(sampleModelFile)
# Set output volume properties
volumeNodeName = "MyNewVolume"
voxelType = vtk.VTK_FLOAT
# Create an empty output volume
bounds=[0,0,0,0,0,0]
modelNode.GetBounds(bounds)
spacing = [0]*3 # desired volume spacing
spacing[0] = 0.5
spacing[1] = 0.5
spacing[2] = 0.5
imageSize = calculate_dimensions(bounds, spacing)
imageOrigin = [bounds[0], bounds[2], bounds[4]]
imageSpacing = [(bounds[1]-bounds[0])/imageSize[0], (bounds[3]-bounds[2])/imageSize[1], (bounds[5]-bounds[4])/imageSize[2]]
imageDirections = [[1,0,0], [0,1,0], [0,0,1]]
imageData = vtk.vtkImageData()
imageData.SetDimensions(imageSize)
imageData.AllocateScalars(voxelType, 1)
# Create volume node
volumeNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", volumeNodeName)
volumeNode.SetOrigin(imageOrigin)
volumeNode.SetSpacing(imageSpacing)
volumeNode.SetIJKToRASDirections(imageDirections)
volumeNode.SetAndObserveImageData(imageData)
volumeNode.CreateDefaultDisplayNodes()
# Sample the mesh at each voxel of the image volume
# Set up matrices to put model points into ijk space of volume
# This assumes points are in RAS space of volume (i.e. RAS==world)
transformer = vtk.vtkTransformFilter()
transformer.SetInputConnection(modelNode.GetMeshConnection())
matrixRasToIjk = vtk.vtkMatrix4x4()
volumeNode.GetRASToIJKMatrix(matrixRasToIjk)
transformRasToIjk = vtk.vtkTransform()
transformRasToIjk.SetMatrix(matrixRasToIjk)
transformer.SetTransform(transformRasToIjk)
probe = vtk.vtkProbeFilter()
probe.SetSourceConnection(transformer.GetOutputPort())
probe.SetInputConnection(volumeNode.GetImageDataConnection())
probe.Update()
volumeNode.SetAndObserveImageData(probe.GetOutput())
# Set colormap for volume display
volumeNode.GetDisplayNode().SetAndObserveColorNodeID(getNode('Inferno').GetID())
# Show all sides of the mesh
modelNode.GetDisplayNode().BackfaceCullingOff()
# Show volume in slice viewers
slicer.util.setSliceViewerLayers(background=volumeNode)
sliceLogics = slicer.app.layoutManager().mrmlSliceLogics()
for i in range(sliceLogics.GetNumberOfItems()):
sliceLogics.GetItemAsObject(i).FitSliceToAll()
After step 2, 3D Slicer crashed without any prompt. And I cannot find any clue from the logs.
is there any wrong with the code? Thanks a lot for your great help!