309 lines
11 KiB
Python
309 lines
11 KiB
Python
|
"""
|
||
|
Rendering of 3D TIFF stacks with VTK
|
||
|
"""
|
||
|
|
||
|
import os
|
||
|
from argparse import ArgumentParser
|
||
|
import vtk
|
||
|
import mp_color_map
|
||
|
|
||
|
def get_ox_map():
|
||
|
|
||
|
files = ["/home/grogan/oxygen_solution_loc_0.vti",
|
||
|
"/home/grogan/oxygen_solution_loc_1.vti",
|
||
|
"/home/grogan/oxygen_solution_loc_2.vti",
|
||
|
"/home/grogan/oxygen_solution_loc_3.vti"]
|
||
|
offsets = [(0.0,0.0), (40.0, 0.0), (40.0, 40.0), (0.0, 40.0)]
|
||
|
|
||
|
ox_actors = []
|
||
|
for idx, eachFile in enumerate(files):
|
||
|
reader = vtk.vtkXMLImageDataReader()
|
||
|
reader.SetFileName(eachFile)
|
||
|
reader.Update()
|
||
|
reader.GetOutput().GetPointData().SetScalars(reader.GetOutput().GetPointData().GetArray("oxygen"))
|
||
|
|
||
|
plane = vtk.vtkPlane()
|
||
|
plane.SetOrigin(0.0, 0, 3)
|
||
|
plane.SetNormal(0, 0, 1)
|
||
|
|
||
|
cutter = vtk.vtkCutter()
|
||
|
cutter.SetInputData(reader.GetOutput())
|
||
|
cutter.SetCutFunction(plane)
|
||
|
cutter.GenerateCutScalarsOn()
|
||
|
cutter.Update()
|
||
|
|
||
|
trans = vtk.vtkTransform()
|
||
|
trans.Scale(42.375, 42.375, 42.375)
|
||
|
transf = vtk.vtkTransformFilter()
|
||
|
transf.SetInputData(cutter.GetOutput())
|
||
|
transf.SetTransform(trans)
|
||
|
transf.Update()
|
||
|
|
||
|
trans1 = vtk.vtkTransform()
|
||
|
trans1.Translate(42.375*offsets[idx][0], 42.375*offsets[idx][1], 0.0)
|
||
|
transf2 = vtk.vtkTransformFilter()
|
||
|
transf2.SetInputData(transf.GetOutput())
|
||
|
transf2.SetTransform(trans1)
|
||
|
transf2.Update()
|
||
|
|
||
|
warp = vtk.vtkWarpScalar()
|
||
|
warp.SetInputData(transf2.GetOutput())
|
||
|
warp.SetScaleFactor(0.15*42.375)
|
||
|
warp.Update()
|
||
|
|
||
|
scaled_ctf = vtk.vtkColorTransferFunction()
|
||
|
scalar_range = [0, 0]
|
||
|
warp.GetOutput().GetPointData().GetArray("oxygen").GetRange(scalar_range)
|
||
|
for idx in range(256):
|
||
|
color = [0, 0, 0]
|
||
|
mp_color_map.get_ctf().GetColor(float(idx)/255.0, color)
|
||
|
scaled_ctf.AddRGBPoint(scalar_range[0] + float(idx)*(scalar_range[1]-scalar_range[0])/255.0,
|
||
|
color[0], color[1], color[2])
|
||
|
|
||
|
ox_mapper = vtk.vtkPolyDataMapper()
|
||
|
ox_mapper.SetInputData(warp.GetOutput())
|
||
|
ox_mapper.ScalarVisibilityOn()
|
||
|
ox_mapper.SetLookupTable(scaled_ctf)
|
||
|
ox_mapper.SelectColorArray("oxygen")
|
||
|
ox_mapper.SetScalarModeToUsePointFieldData()
|
||
|
ox_mapper.SetColorModeToMapScalars()
|
||
|
|
||
|
#ox_mapper.ScalarVisibilityOn()
|
||
|
ox_actor = vtk.vtkActor()
|
||
|
ox_actor.SetMapper(ox_mapper)
|
||
|
ox_actor.GetProperty().SetColor(0.0, 1.0, 0.0)
|
||
|
ox_actor.GetProperty().SetOpacity(0.5)
|
||
|
ox_actors.append(ox_actor)
|
||
|
|
||
|
scale_bar = vtk.vtkScalarBarActor()
|
||
|
scale_bar.SetLookupTable(scaled_ctf);
|
||
|
#scale_bar.SetTitle("Oxygen Tension (mmHg)");
|
||
|
scale_bar.SetOrientationToVertical();
|
||
|
scale_bar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport();
|
||
|
scale_bar.GetPositionCoordinate().SetValue(0.23, 0.27);
|
||
|
scale_bar.SetWidth(0.08);
|
||
|
scale_bar.SetHeight(0.6);
|
||
|
#scale_bar.SetAnnotationTextScalingOff()
|
||
|
#scale_bar.UnconstrainedFontSizeOn()
|
||
|
scale_bar.GetTitleTextProperty().ItalicOff();
|
||
|
scale_bar.GetLabelTextProperty().ItalicOff();
|
||
|
scale_bar.GetTitleTextProperty().BoldOff();
|
||
|
scale_bar.GetLabelTextProperty().BoldOff();
|
||
|
scale_bar.GetTitleTextProperty().ShadowOff();
|
||
|
scale_bar.GetLabelTextProperty().ShadowOff();
|
||
|
scale_bar.SetLabelFormat("%.2g");
|
||
|
scale_bar.GetTitleTextProperty().SetFontSize(15)
|
||
|
scale_bar.GetLabelTextProperty().SetFontSize(15)
|
||
|
scale_bar.GetTitleTextProperty().SetColor(1.0, 1.0, 1.0);
|
||
|
scale_bar.GetLabelTextProperty().SetColor(1.0, 1.0, 1.0);
|
||
|
|
||
|
return ox_actors, scale_bar
|
||
|
|
||
|
def add_cells():
|
||
|
|
||
|
cell_files = ["/scratch/jgrogan/TBME_16_Work/Simulations/BioHigh_15x/Bio3d_1/results_from_time_0/results_20.vtu",
|
||
|
"/scratch/jgrogan/TBME_16_Work/Simulations/BioHigh_15x/Bio3d_1/results_from_time_0/results_100.vtu",
|
||
|
"/scratch/jgrogan/TBME_16_Work/Simulations/BioHigh_15x/Bio3d_1/results_from_time_0/results_150.vtu"]
|
||
|
|
||
|
cell_actors = []
|
||
|
|
||
|
for eachFile in cell_files:
|
||
|
reader = vtk.vtkXMLUnstructuredGridReader()
|
||
|
reader.SetFileName(eachFile)
|
||
|
reader.Update()
|
||
|
|
||
|
spheres = vtk.vtkSphereSource()
|
||
|
spheres.SetRadius(0.6)
|
||
|
spheres.SetPhiResolution(8)
|
||
|
spheres.SetThetaResolution(8)
|
||
|
|
||
|
glyph = vtk.vtkGlyph3D()
|
||
|
glyph.SetInputData(reader.GetOutput());
|
||
|
glyph.SetSourceConnection(spheres.GetOutputPort());
|
||
|
glyph.ClampingOff();
|
||
|
glyph.SetScaleModeToScaleByScalar();
|
||
|
glyph.SetScaleFactor(0.8);
|
||
|
glyph.Update();
|
||
|
|
||
|
trans = vtk.vtkTransform()
|
||
|
trans.Scale(42.375, 42.375, 42.375)
|
||
|
transf = vtk.vtkTransformFilter()
|
||
|
transf.SetInputData(glyph.GetOutput())
|
||
|
transf.SetTransform(trans)
|
||
|
transf.Update()
|
||
|
|
||
|
scaled_ctf = vtk.vtkColorTransferFunction()
|
||
|
scalar_range = [0, 0]
|
||
|
reader.GetOutput().GetPointData().GetArray("Cell types").GetRange(scalar_range)
|
||
|
for idx in range(256):
|
||
|
color = [0, 0, 0]
|
||
|
mp_color_map.get_disc_ctf().GetColor(float(idx)/255.0, color)
|
||
|
scaled_ctf.AddRGBPoint(scalar_range[0] + float(idx)*(scalar_range[1]-scalar_range[0])/255.0,
|
||
|
color[0], color[1], color[2])
|
||
|
|
||
|
mapper = vtk.vtkPolyDataMapper();
|
||
|
mapper.SetInputData(transf.GetOutput());
|
||
|
mapper.SetLookupTable(scaled_ctf);
|
||
|
mapper.ScalarVisibilityOn();
|
||
|
mapper.SelectColorArray("Cell types");
|
||
|
mapper.SetScalarModeToUsePointFieldData();
|
||
|
mapper.SetColorModeToMapScalars();
|
||
|
|
||
|
actor = vtk.vtkActor();
|
||
|
actor.SetMapper(mapper);
|
||
|
actor.GetProperty().SetOpacity(0.8);
|
||
|
|
||
|
cell_actors.append(actor)
|
||
|
return cell_actors
|
||
|
|
||
|
# if(!this->mDataLabel.empty() and this->mShowScaleBar)
|
||
|
# {
|
||
|
# this->mpScaleBar->SetLookupTable(p_scaled_ctf);
|
||
|
# this->mpScaleBar->SetTitle(this->mDataLabel.c_str());
|
||
|
# pRenderer->AddActor(this->mpScaleBar);
|
||
|
# }
|
||
|
|
||
|
def render_image(image_path, threshold = 20.0):
|
||
|
|
||
|
"""
|
||
|
Render the 3D stack with VTK
|
||
|
"""
|
||
|
|
||
|
input_files = []
|
||
|
for eachFile in os.listdir(image_path):
|
||
|
if eachFile.endswith(".vti"):
|
||
|
input_files.append(image_path + "/"+eachFile)
|
||
|
|
||
|
renderer = vtk.vtkRenderer()
|
||
|
renderer.SetBackground(20.0/255.0,30.0/255.0,48.0/255.0);
|
||
|
renderer.SetBackground2(36.0/255.0,59.0/255.0,85.0/255.0);
|
||
|
|
||
|
for eachImage in input_files:
|
||
|
reader= vtk.vtkXMLImageDataReader()
|
||
|
reader.SetFileName(eachImage)
|
||
|
reader.Update()
|
||
|
|
||
|
volume_mapper = vtk.vtkVolumeRayCastMapper()
|
||
|
volume_mapper.SetInputData(reader.GetOutput())
|
||
|
composite_function = vtk.vtkVolumeRayCastCompositeFunction()
|
||
|
volume_mapper.SetVolumeRayCastFunction(composite_function)
|
||
|
|
||
|
color_transfer_func = vtk.vtkColorTransferFunction()
|
||
|
color_transfer_func.AddRGBPoint(0, 0.0, 1.0, 0.0 )
|
||
|
color_transfer_func.AddRGBPoint(threshold-1, 0.0, 1.0, 0.0 )
|
||
|
color_transfer_func.AddRGBPoint(threshold, 1.0, 0.0, 0.0 )
|
||
|
color_transfer_func.AddRGBPoint(255.0, 1.0, 0.0, 0.0 )
|
||
|
|
||
|
opacity_transfer_func = vtk.vtkPiecewiseFunction()
|
||
|
opacity_transfer_func.AddPoint(0, 0.0 )
|
||
|
opacity_transfer_func.AddPoint(threshold-1.0, 0.0 )
|
||
|
#opacity_transfer_func.AddPoint(threshold, 1.0 )
|
||
|
opacity_transfer_func.AddPoint(255.0, 0.1 )
|
||
|
|
||
|
volume_properties = vtk.vtkVolumeProperty()
|
||
|
volume_properties.SetColor( color_transfer_func )
|
||
|
volume_properties.SetScalarOpacity( opacity_transfer_func )
|
||
|
|
||
|
volume = vtk.vtkVolume()
|
||
|
volume.SetMapper(volume_mapper)
|
||
|
volume.SetProperty(volume_properties)
|
||
|
renderer.AddVolume(volume)
|
||
|
|
||
|
# textActor = vtk.vtkTextActor()
|
||
|
# textActor.SetTextScaleModeToNone()
|
||
|
# textActor.SetDisplayPosition(200, 300)
|
||
|
# textActor.SetInput("Oxygen Tension (mmHg)")
|
||
|
# tprop = textActor.GetTextProperty()
|
||
|
# tprop.SetFontSize(10)
|
||
|
# tprop.SetFontFamilyToArial()
|
||
|
# tprop.SetJustificationToCentered()
|
||
|
# tprop.BoldOff()
|
||
|
# tprop.ItalicOff()
|
||
|
# tprop.ShadowOff()
|
||
|
# tprop.SetColor(1, 1, 1)
|
||
|
# #renderer.AddActor2D(textActor)
|
||
|
|
||
|
renderer.ResetCamera()
|
||
|
render_window = vtk.vtkRenderWindow()
|
||
|
window_interactor = vtk.vtkRenderWindowInteractor()
|
||
|
|
||
|
render_window.AddRenderer(renderer)
|
||
|
window_interactor.SetRenderWindow(render_window)
|
||
|
|
||
|
render_window.SetSize(170, 177)
|
||
|
render_window.Render()
|
||
|
ox_actors, scale_bar_actor = get_ox_map()
|
||
|
#renderer.AddActor(scale_bar_actor)
|
||
|
render_window.Render()
|
||
|
|
||
|
renderer.GetActiveCamera().Elevation(-33.0)
|
||
|
renderer.GetActiveCamera().Zoom(1.0)
|
||
|
position = list(renderer.GetActiveCamera().GetFocalPoint())
|
||
|
#position[0] = position[0] - 750
|
||
|
#position[1] = position[1] - 105
|
||
|
renderer.GetActiveCamera().SetFocalPoint(position)
|
||
|
renderer.ResetCameraClippingRange()
|
||
|
render_window.Render()
|
||
|
|
||
|
window_to_image_filter = vtk.vtkWindowToImageFilter()
|
||
|
window_to_image_filter.SetInput(render_window)
|
||
|
writer = vtk.vtkTIFFWriter()
|
||
|
extension = ".tiff"
|
||
|
writer.SetInputConnection(window_to_image_filter.GetOutputPort())
|
||
|
writer.SetFileName("vtk_animation_0"+extension)
|
||
|
writer.Write()
|
||
|
|
||
|
|
||
|
num_samples = 1
|
||
|
for idx in range(num_samples):
|
||
|
|
||
|
if idx==0:
|
||
|
for eachActor in ox_actors:
|
||
|
renderer.AddActor(eachActor)
|
||
|
|
||
|
renderer.GetActiveCamera().OrthogonalizeViewUp()
|
||
|
#time.sleep(0.02)
|
||
|
|
||
|
#renderer.GetActiveCamera().Dolly(1.002))
|
||
|
render_window.Render()
|
||
|
window_to_image_filter.Modified()
|
||
|
writer.SetFileName("vtk_animation_"+str(idx+1)+extension)
|
||
|
writer.Write()
|
||
|
|
||
|
renderer.RemoveActor(ox_actors[0])
|
||
|
render_window.Render()
|
||
|
window_to_image_filter.Modified()
|
||
|
writer.SetFileName("vtk_animation_"+str(num_samples+1)+extension)
|
||
|
writer.Write()
|
||
|
|
||
|
cell_actors = add_cells()
|
||
|
renderer.AddActor(cell_actors[0])
|
||
|
render_window.Render()
|
||
|
window_to_image_filter.Modified()
|
||
|
writer.SetFileName("vtk_animation_"+str(num_samples+2)+extension)
|
||
|
writer.Write()
|
||
|
renderer.RemoveActor(cell_actors[0])
|
||
|
|
||
|
renderer.AddActor(cell_actors[1])
|
||
|
render_window.Render()
|
||
|
window_to_image_filter.Modified()
|
||
|
writer.SetFileName("vtk_animation_"+str(num_samples+3)+extension)
|
||
|
writer.Write()
|
||
|
renderer.RemoveActor(cell_actors[1])
|
||
|
|
||
|
renderer.AddActor(cell_actors[2])
|
||
|
render_window.Render()
|
||
|
window_to_image_filter.Modified()
|
||
|
writer.SetFileName("vtk_animation_"+str(num_samples+4)+extension)
|
||
|
writer.Write()
|
||
|
|
||
|
window_interactor.Start()
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
|
||
|
|
||
|
parser = ArgumentParser()
|
||
|
parser.add_argument("-i", "--input_file", type=str, help='vtk input file')
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
render_image(args.input_file)
|