Describe the bug
I hope to dynamically add actors in the callback function input_calculate_file of the imported file, I found that vtkCubeSource can be added, but vtkUnstructuredGrid cannot . I put the function content of add_my_file() into TrameApp's pipeline initialization function _stupuvtk, and it succeeded.How ever, in the callback function input_calculate_file it did not work. Im my test example the VFileInput is just used to trigger the function input_calculate_file and the file is always "Mine_Res-20.000000hz-21840mesh-23218node.plt"
Successful Code
from trame.app import TrameApp
from trame.decorators import change
from trame.ui.vuetify3 import SinglePageLayout,SinglePageWithDrawerLayout
from trame.widgets import vuetify3, vtklocal,trame
from trame.app import get_server
from trame.widgets import vtk as vtk_widgets
# Required for rendering initialization, not necessary for
# local rendering, but doesn't hurt to include it
import vtkmodules.vtkRenderingOpenGL2 # noqa
from trame_vtk.modules.vtk.serializers import configure_serializer
from vtkmodules.vtkCommonDataModel import vtkDataObject
from vtkmodules.vtkFiltersCore import vtkContourFilter
from vtkmodules.vtkFiltersSources import vtkConeSource, vtkCubeSource
import random
# Required for interactor initialization
import vtk
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa
from vtkmodules.vtkIOXML import vtkXMLUnstructuredGridReader
from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkDataSetMapper,
vtkPolyDataMapper,
vtkRenderer,
vtkRenderWindow,
vtkRenderWindowInteractor,
)
class Cone(TrameApp):
def __init__(self, server=None):
super().__init__(server)
self._setup_vtk()
self._build_ui()
self.state.active_ui = None
self.state.impot_success = False
self.state.array_list = []
def _setup_vtk(self):
self.reader = None
self.renderer = vtkRenderer()
self.render_window = vtkRenderWindow()
self.renderer.SetBackground(0.8, 0.8, 0.8)
self.render_window.AddRenderer(self.renderer)
self.renderWindowInteractor =vtkRenderWindowInteractor()
self.renderWindowInteractor.SetRenderWindow(self.render_window)
self.renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
self.mesh_mapper = vtkDataSetMapper()
self.mesh_actor = vtkActor()
self.contour = vtkContourFilter()
self.contour_mapper = vtkPolyDataMapper()
self.contour_actor = vtkActor()
self.contour_value = None
self.default_max = 0
self.default_min = 0
self.cube_axes = vtkCubeAxesActor()
self.dataset_arrays =[]
reader = vtk.vtkTecplotReader()
reader.SetFileName("Mine_Res-20.000000hz-21840mesh-23218node.plt")
reader.Update()
output = reader.GetOutput()
# 处理多块数据集
if output.IsA("vtkMultiBlockDataSet"):
print("多块数据集,块数:", output.GetNumberOfBlocks())
reader = None
for i in range(output.GetNumberOfBlocks()):
block = output.GetBlock(i)
if block:
print(f"块{i}类型:", block.GetClassName())
if block.IsA("vtkUnstructuredGrid") and block.GetNumberOfPoints() > 0:
reader = block
print(f"选择块{i}作为网格")
break
if reader is None:
print("未找到有效的非结构网格块")
exit()
else:
reader = output
print("输出类型:", reader.GetClassName())
print("点数:", reader.GetNumberOfPoints())
print("单元数:", reader.GetNumberOfCells())
# 检查网格有效性
if not isinstance(reader, vtk.vtkUnstructuredGrid):
print("错误:未能获取有效的非结构网格。")
exit()
# Extract Array/Field information
dataset_arrays = []
# 加载节点数据和声压数据
fields = [
(reader.GetPointData(), vtkDataObject.FIELD_ASSOCIATION_POINTS),
(reader.GetCellData(), vtkDataObject.FIELD_ASSOCIATION_CELLS),
]
for field in fields:
field_arrays, association = field
# reader.GetPointData()可能包含多组节点数据
for i in range(field_arrays.GetNumberOfArrays()):
array = field_arrays.GetArray(i)
array_range = array.GetRange()
dataset_arrays.append(
{
"text": array.GetName(),
"value": i,
"range": list(array_range),
"type": association,
}
)
default_array = dataset_arrays[2]
self.default_min, self.default_max = default_array.get("range")
self.reader=reader
self.mesh_mapper.SetInputData(self.reader)
self.mesh_actor.SetMapper(self.mesh_mapper)
self.renderer.AddActor(self.mesh_actor)
# Mesh: Setup default representation to surface
self.mesh_actor.GetProperty().SetRepresentationToSurface()
self.mesh_actor.GetProperty().SetPointSize(1)
self.mesh_actor.GetProperty().EdgeVisibilityOn()
def _build_ui(self):
with SinglePageWithDrawerLayout(self.server) as layout:
self.ui = layout
layout.title.set_text("Acoustic Model")
layout.icon.click = self.ctrl.view_reset_camera
with layout.toolbar as toolbar:
toolbar.density = "compact"
vuetify3.VSpacer()
vuetify3.VFileInput(
prepend_icon="mdi-vector-triangle",
v_model=("input_calculate_file", None),
label="input file",
)
with layout.content:
# region widget
with vtklocal.LocalView(
self.render_window,
throttle_rate=20,
) as view:
self.ctrl.view_update = view.update_throttle
self.ctrl.view_reset_camera = view.reset_camera
# endregion widget
@change("input_calculate_file")
def input_calculate_file(self,input_calculate_file,**kwargs):
if(input_calculate_file==None):
return
# cube actor
cube_source = vtkCubeSource()
cube_mapper = vtkPolyDataMapper()
cube_mapper.SetInputConnection(cube_source.GetOutputPort())
cube_actor = vtkActor()
cube_actor.SetMapper(cube_mapper)
r, g, b = random.random(), random.random(), random.random()
x, y, z = random.uniform(-0.5, 0.5), random.uniform(-0.5, 0.5), random.uniform(-0.5, 0.5)
cube_actor.GetProperty().SetColor(r, g, b)
cube_actor.SetPosition(x, y, z)
self.renderer.AddActor(cube_actor)
self.ctrl.view_update()
self.ctrl.view_reset_camera()
#add another actor
#self.add_my_file()
def add_my_file(self):
# add another actor(afiled)
reader = vtk.vtkTecplotReader()
reader.SetFileName("Mine_Res-20.000000hz-21840mesh-23218node.plt")
reader.Update()
output = reader.GetOutput()
# 处理多块数据集
if output.IsA("vtkMultiBlockDataSet"):
print("多块数据集,块数:", output.GetNumberOfBlocks())
reader = None
for i in range(output.GetNumberOfBlocks()):
block = output.GetBlock(i)
if block:
print(f"块{i}类型:", block.GetClassName())
if block.IsA("vtkUnstructuredGrid") and block.GetNumberOfPoints() > 0:
reader = block
print(f"选择块{i}作为网格")
break
if reader is None:
print("未找到有效的非结构网格块")
exit()
else:
reader = output
print("输出类型:", reader.GetClassName())
print("点数:", reader.GetNumberOfPoints())
print("单元数:", reader.GetNumberOfCells())
# 检查网格有效性
if not isinstance(reader, vtk.vtkUnstructuredGrid):
print("错误:未能获取有效的非结构网格。")
exit()
# Extract Array/Field information
dataset_arrays = []
# 加载节点数据和声压数据
fields = [
(reader.GetPointData(), vtkDataObject.FIELD_ASSOCIATION_POINTS),
(reader.GetCellData(), vtkDataObject.FIELD_ASSOCIATION_CELLS),
]
for field in fields:
field_arrays, association = field
# reader.GetPointData()可能包含多组节点数据
for i in range(field_arrays.GetNumberOfArrays()):
array = field_arrays.GetArray(i)
array_range = array.GetRange()
dataset_arrays.append(
{
"text": array.GetName(),
"value": i,
"range": list(array_range),
"type": association,
}
)
default_array = dataset_arrays[2]
self.default_min, self.default_max = default_array.get("range")
self.reader=reader
self.mesh_mapper.SetInputData(self.reader)
self.mesh_actor.SetMapper(self.mesh_mapper)
self.renderer.AddActor(self.mesh_actor)
# Mesh: Setup default representation to surface
self.mesh_actor.GetProperty().SetRepresentationToSurface()
self.mesh_actor.GetProperty().SetPointSize(1)
self.mesh_actor.GetProperty().EdgeVisibilityOn()
self.ctrl.view_update()
self.ctrl.view_reset_camera()
def main():
app = Cone()
app.server.start(port=8088)
if __name__ == "__main__":
main()
Failedl Code
from trame.app import TrameApp
from trame.decorators import change
from trame.ui.vuetify3 import SinglePageLayout,SinglePageWithDrawerLayout
from trame.widgets import vuetify3, vtklocal,trame
from trame.app import get_server
from trame.widgets import vtk as vtk_widgets
# Required for rendering initialization, not necessary for
# local rendering, but doesn't hurt to include it
import vtkmodules.vtkRenderingOpenGL2 # noqa
from trame_vtk.modules.vtk.serializers import configure_serializer
from vtkmodules.vtkCommonDataModel import vtkDataObject
from vtkmodules.vtkFiltersCore import vtkContourFilter
from vtkmodules.vtkFiltersSources import vtkConeSource, vtkCubeSource
import random
# Required for interactor initialization
import vtk
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa
from vtkmodules.vtkIOXML import vtkXMLUnstructuredGridReader
from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkDataSetMapper,
vtkPolyDataMapper,
vtkRenderer,
vtkRenderWindow,
vtkRenderWindowInteractor,
)
class Cone(TrameApp):
def __init__(self, server=None):
super().__init__(server)
self._setup_vtk()
self._build_ui()
self.state.active_ui = None
self.state.impot_success = False
self.state.array_list = []
def _setup_vtk(self):
self.reader = None
self.renderer = vtkRenderer()
self.render_window = vtkRenderWindow()
self.renderer.SetBackground(0.8, 0.8, 0.8)
self.render_window.AddRenderer(self.renderer)
self.renderWindowInteractor =vtkRenderWindowInteractor()
self.renderWindowInteractor.SetRenderWindow(self.render_window)
self.renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
self.mesh_mapper = vtkDataSetMapper()
self.mesh_actor = vtkActor()
self.contour = vtkContourFilter()
self.contour_mapper = vtkPolyDataMapper()
self.contour_actor = vtkActor()
self.contour_value = None
self.default_max = 0
self.default_min = 0
self.cube_axes = vtkCubeAxesActor()
self.dataset_arrays =[]
def _build_ui(self):
with SinglePageWithDrawerLayout(self.server) as layout:
self.ui = layout
layout.title.set_text("Acoustic Model")
layout.icon.click = self.ctrl.view_reset_camera
with layout.toolbar as toolbar:
toolbar.density = "compact"
vuetify3.VSpacer()
vuetify3.VFileInput(
prepend_icon="mdi-vector-triangle",
v_model=("input_calculate_file", None),
label="input file",
)
with layout.content:
# region widget
with vtklocal.LocalView(
self.render_window,
throttle_rate=20,
) as view:
self.ctrl.view_update = view.update_throttle
self.ctrl.view_reset_camera = view.reset_camera
# endregion widget
@change("input_calculate_file")
def input_calculate_file(self,input_calculate_file,**kwargs):
if(input_calculate_file==None):
return
# cube actor
cube_source = vtkCubeSource()
cube_mapper = vtkPolyDataMapper()
cube_mapper.SetInputConnection(cube_source.GetOutputPort())
cube_actor = vtkActor()
cube_actor.SetMapper(cube_mapper)
r, g, b = random.random(), random.random(), random.random()
x, y, z = random.uniform(-0.5, 0.5), random.uniform(-0.5, 0.5), random.uniform(-0.5, 0.5)
cube_actor.GetProperty().SetColor(r, g, b)
cube_actor.SetPosition(x, y, z)
self.renderer.AddActor(cube_actor)
self.ctrl.view_update()
self.ctrl.view_reset_camera()
#add another actor
self.add_my_file()
self.ctrl.view_update()
self.ctrl.view_reset_camera()
def add_my_file(self):
# add another actor(afiled)
reader = vtk.vtkTecplotReader()
reader.SetFileName("Mine_Res-20.000000hz-21840mesh-23218node.plt")
reader.Update()
output = reader.GetOutput()
# 处理多块数据集
if output.IsA("vtkMultiBlockDataSet"):
print("多块数据集,块数:", output.GetNumberOfBlocks())
reader = None
for i in range(output.GetNumberOfBlocks()):
block = output.GetBlock(i)
if block:
print(f"块{i}类型:", block.GetClassName())
if block.IsA("vtkUnstructuredGrid") and block.GetNumberOfPoints() > 0:
reader = block
print(f"选择块{i}作为网格")
break
if reader is None:
print("未找到有效的非结构网格块")
exit()
else:
reader = output
print("输出类型:", reader.GetClassName())
print("点数:", reader.GetNumberOfPoints())
print("单元数:", reader.GetNumberOfCells())
# 检查网格有效性
if not isinstance(reader, vtk.vtkUnstructuredGrid):
print("错误:未能获取有效的非结构网格。")
exit()
# Extract Array/Field information
dataset_arrays = []
# 加载节点数据和声压数据
fields = [
(reader.GetPointData(), vtkDataObject.FIELD_ASSOCIATION_POINTS),
(reader.GetCellData(), vtkDataObject.FIELD_ASSOCIATION_CELLS),
]
for field in fields:
field_arrays, association = field
# reader.GetPointData()可能包含多组节点数据
for i in range(field_arrays.GetNumberOfArrays()):
array = field_arrays.GetArray(i)
array_range = array.GetRange()
dataset_arrays.append(
{
"text": array.GetName(),
"value": i,
"range": list(array_range),
"type": association,
}
)
default_array = dataset_arrays[2]
self.default_min, self.default_max = default_array.get("range")
self.reader=reader
self.mesh_mapper.SetInputData(self.reader)
self.mesh_actor.SetMapper(self.mesh_mapper)
self.renderer.AddActor(self.mesh_actor)
# Mesh: Setup default representation to surface
self.mesh_actor.GetProperty().SetRepresentationToSurface()
self.mesh_actor.GetProperty().SetPointSize(1)
self.mesh_actor.GetProperty().EdgeVisibilityOn()
self.ctrl.view_update()
self.ctrl.view_reset_camera()
def main():
app = Cone()
app.server.start(port=8088)
if __name__ == "__main__":
main()
Mine_Res-20.000000hz-21840mesh-23218node.zip
Describe the bug
I hope to dynamically add actors in the callback function
input_calculate_fileof the imported file, I found thatvtkCubeSourcecan be added, butvtkUnstructuredGridcannot . I put the function content ofadd_my_file()into TrameApp's pipeline initialization function_stupuvtk, and it succeeded.How ever, in the callback functioninput_calculate_fileit did not work. Im my test example theVFileInputis just used to trigger the functioninput_calculate_fileand the file is always "Mine_Res-20.000000hz-21840mesh-23218node.plt"Successful Code
Failedl Code
Mine_Res-20.000000hz-21840mesh-23218node.zip