I have a MultiBlockDataSet imported from a .vtm file. I am trying to set up specific colors for every block. My first attempt is to set the same color for every blocks but the color never changes.
okay. it complains because GetOutput returns a vtkPolyData but in your case we want a vtkCompositeDataSet. Replace GetOutput with GetOutputDataObject, and SetInputData with SetInputDataObject.
Full code that should work (tested on my end)
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkIOXML import vtkXMLMultiBlockDataReader
from vtkmodules.vtkFiltersGeometry import vtkGeometryFilter
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkCompositePolyDataMapper,
vtkCompositeDataDisplayAttributes,
vtkRenderer,
vtkRenderWindow,
vtkRenderWindowInteractor,
)
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleTrackballCamera
from vtkmodules.vtkCommonDataModel import vtkDataObjectTreeIterator
VTM_PATH = "viewable.vtm"
renderer = vtkRenderer()
renderer.SetBackground(0.2, 0.2, 0.2)
render_window = vtkRenderWindow()
render_window.AddRenderer(renderer)
render_window.SetSize(1200, 700)
reader = vtkXMLMultiBlockDataReader()
reader.SetFileName(VTM_PATH)
geo_filter = vtkGeometryFilter()
geo_filter.SetInputConnection(reader.GetOutputPort())
geo_filter.Update()
# NEW
geometry_output = geo_filter.GetOutputDataObject(0)
mapper = vtkCompositePolyDataMapper()
mapper.SetInputDataObject(geometry_output) # NEW
attributes = vtkCompositeDataDisplayAttributes()
mapper.SetCompositeDataDisplayAttributes(attributes)
actor = vtkActor()
actor.SetMapper(mapper)
renderer.AddActor(actor)
original_block_iterator = vtkDataObjectTreeIterator(
data_set=geometry_output, # NEW
visit_only_leaves=True, traverse_sub_tree=True)
original_block_iterator.InitTraversal()
while not original_block_iterator.IsDoneWithTraversal():
original_block = original_block_iterator.GetCurrentDataObject()
attributes.SetBlockColor(original_block, [0,1,1])
original_block_iterator.GoToNextItem()
renderer.ResetCamera()
interactor = vtkRenderWindowInteractor()
interactor.SetRenderWindow(render_window)
style = vtkInteractorStyleTrackballCamera()
interactor.SetInteractorStyle(style)
render_window.Render()
interactor.Start()
Can you explain why I need to get the data out from the filter and not directly connect the algorithm connection output? Looks counter intuitive with the classic vtk pipeline.
the vtkCompositeDataDisplayAttributes needs the data object.
You can still make a pipeline connection. Just ensure that the data objects passed in attributes.SetBlockColor are valid datasets that are rendered by the mapper.