├── .gitignore ├── 00_setup └── app.py ├── 01_vtk ├── app_cone.py ├── app_flow.py ├── solution_cone.py ├── solution_flow.py └── solution_ray_cast.py ├── 02_layouts ├── app_cone.py ├── solution_FullScreenPage.py ├── solution_SinglePage.py └── solution_SinglePageWithDrawer.py ├── 03_html ├── app_cone.py ├── solution_buttons.py └── solution_final.py ├── 04_application ├── app.py └── solution.py ├── 05_paraview ├── SimpleCone.py └── StateLoader.py ├── README.md ├── course └── introduction │ ├── Introduction_to_trame.pdf │ ├── README.md │ ├── exercises.zip │ └── trame_intro_ref.pdf ├── data ├── carotid.vtk ├── disk_out_ref.vtu ├── ironProt.vtk ├── pv-state-diskout.pvsm └── pv-state.pvsm └── presentation.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ -------------------------------------------------------------------------------- /00_setup/app.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageLayout 3 | 4 | # ----------------------------------------------------------------------------- 5 | # Get a server to work with 6 | # ----------------------------------------------------------------------------- 7 | 8 | server = get_server(client_type = "vue2") 9 | 10 | # ----------------------------------------------------------------------------- 11 | # GUI 12 | # ----------------------------------------------------------------------------- 13 | 14 | with SinglePageLayout(server) as layout: 15 | layout.title.set_text("Hello trame") 16 | 17 | # ----------------------------------------------------------------------------- 18 | # Main 19 | # ----------------------------------------------------------------------------- 20 | 21 | if __name__ == "__main__": 22 | server.start() 23 | -------------------------------------------------------------------------------- /01_vtk/app_cone.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageLayout 3 | 4 | # ----------------------------------------------------------------------------- 5 | # Get a server to work with 6 | # ----------------------------------------------------------------------------- 7 | 8 | server = get_server(client_type = "vue2") 9 | 10 | # ----------------------------------------------------------------------------- 11 | # GUI 12 | # ----------------------------------------------------------------------------- 13 | 14 | with SinglePageLayout(server) as layout: 15 | layout.title.set_text("Hello trame") 16 | 17 | # ----------------------------------------------------------------------------- 18 | # Main 19 | # ----------------------------------------------------------------------------- 20 | 21 | if __name__ == "__main__": 22 | server.start() 23 | -------------------------------------------------------------------------------- /01_vtk/app_flow.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageLayout 3 | from trame.widgets import vtk, vuetify 4 | 5 | from vtkmodules.vtkFiltersSources import vtkConeSource 6 | from vtkmodules.vtkRenderingCore import ( 7 | vtkActor, 8 | vtkPolyDataMapper, 9 | vtkRenderer, 10 | vtkRenderWindow, 11 | vtkRenderWindowInteractor, 12 | ) 13 | 14 | # Required for interactor initialization 15 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 16 | 17 | # Required for rendering initialization, not necessary for 18 | # local rendering, but doesn't hurt to include it 19 | import vtkmodules.vtkRenderingOpenGL2 # noqa 20 | 21 | 22 | # ----------------------------------------------------------------------------- 23 | # VTK pipeline 24 | # ----------------------------------------------------------------------------- 25 | 26 | renderer = vtkRenderer() 27 | renderWindow = vtkRenderWindow() 28 | renderWindow.AddRenderer(renderer) 29 | 30 | renderWindowInteractor = vtkRenderWindowInteractor() 31 | renderWindowInteractor.SetRenderWindow(renderWindow) 32 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 33 | 34 | cone_source = vtkConeSource() 35 | mapper = vtkPolyDataMapper() 36 | mapper.SetInputConnection(cone_source.GetOutputPort()) 37 | actor = vtkActor() 38 | actor.SetMapper(mapper) 39 | 40 | renderer.AddActor(actor) 41 | renderer.ResetCamera() 42 | 43 | # ----------------------------------------------------------------------------- 44 | # Trame 45 | # ----------------------------------------------------------------------------- 46 | 47 | server = get_server(client_type = "vue2") 48 | ctrl = server.controller 49 | 50 | with SinglePageLayout(server) as layout: 51 | layout.title.set_text("Hello trame") 52 | 53 | with layout.content: 54 | with vuetify.VContainer( 55 | fluid=True, 56 | classes="pa-0 fill-height", 57 | ): 58 | view = vtk.VtkLocalView(renderWindow) 59 | 60 | 61 | # ----------------------------------------------------------------------------- 62 | # Main 63 | # ----------------------------------------------------------------------------- 64 | 65 | if __name__ == "__main__": 66 | server.start() 67 | -------------------------------------------------------------------------------- /01_vtk/solution_cone.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageLayout 3 | from trame.widgets import vtk, vuetify 4 | 5 | from vtkmodules.vtkFiltersSources import vtkConeSource 6 | from vtkmodules.vtkRenderingCore import ( 7 | vtkActor, 8 | vtkPolyDataMapper, 9 | vtkRenderer, 10 | vtkRenderWindow, 11 | vtkRenderWindowInteractor, 12 | ) 13 | 14 | # Required for interactor initialization 15 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 16 | 17 | # Required for rendering initialization, not necessary for 18 | # local rendering, but doesn't hurt to include it 19 | import vtkmodules.vtkRenderingOpenGL2 # noqa 20 | 21 | 22 | # ----------------------------------------------------------------------------- 23 | # VTK pipeline 24 | # ----------------------------------------------------------------------------- 25 | 26 | renderer = vtkRenderer() 27 | renderWindow = vtkRenderWindow() 28 | renderWindow.AddRenderer(renderer) 29 | 30 | renderWindowInteractor = vtkRenderWindowInteractor() 31 | renderWindowInteractor.SetRenderWindow(renderWindow) 32 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 33 | 34 | cone_source = vtkConeSource() 35 | mapper = vtkPolyDataMapper() 36 | mapper.SetInputConnection(cone_source.GetOutputPort()) 37 | actor = vtkActor() 38 | actor.SetMapper(mapper) 39 | 40 | renderer.AddActor(actor) 41 | renderer.ResetCamera() 42 | 43 | # ----------------------------------------------------------------------------- 44 | # Trame 45 | # ----------------------------------------------------------------------------- 46 | 47 | server = get_server(client_type = "vue2") 48 | ctrl = server.controller 49 | 50 | with SinglePageLayout(server) as layout: 51 | layout.title.set_text("Hello trame") 52 | 53 | with layout.content: 54 | with vuetify.VContainer( 55 | fluid=True, 56 | classes="pa-0 fill-height", 57 | ): 58 | view = vtk.VtkLocalView(renderWindow) 59 | 60 | 61 | # ----------------------------------------------------------------------------- 62 | # Main 63 | # ----------------------------------------------------------------------------- 64 | 65 | if __name__ == "__main__": 66 | server.start() 67 | -------------------------------------------------------------------------------- /01_vtk/solution_flow.py: -------------------------------------------------------------------------------- 1 | import os 2 | from trame.app import get_server 3 | from trame.ui.vuetify import SinglePageLayout 4 | from trame.widgets import vtk, vuetify 5 | 6 | from vtkmodules.vtkCommonColor import vtkNamedColors 7 | from vtkmodules.vtkCommonCore import vtkLookupTable 8 | from vtkmodules.vtkFiltersCore import ( 9 | vtkContourFilter, 10 | vtkGlyph3D, 11 | vtkMaskPoints, 12 | vtkThresholdPoints, 13 | ) 14 | from vtkmodules.vtkFiltersModeling import vtkOutlineFilter 15 | from vtkmodules.vtkFiltersSources import vtkConeSource 16 | from vtkmodules.vtkIOLegacy import vtkStructuredPointsReader 17 | from vtkmodules.vtkRenderingCore import ( 18 | vtkActor, 19 | vtkPolyDataMapper, 20 | vtkRenderer, 21 | vtkRenderWindow, 22 | vtkRenderWindowInteractor, 23 | ) 24 | 25 | # Required for interactor initialization 26 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 27 | 28 | # Required for rendering initialization, not necessary for 29 | # local rendering, but doesn't hurt to include it 30 | import vtkmodules.vtkRenderingOpenGL2 # noqa 31 | 32 | CURRENT_DIRECTORY = os.path.abspath(os.path.dirname(__file__)) 33 | 34 | # ----------------------------------------------------------------------------- 35 | # VTK pipeline 36 | # ----------------------------------------------------------------------------- 37 | 38 | renderer = vtkRenderer() 39 | renderWindow = vtkRenderWindow() 40 | renderWindow.AddRenderer(renderer) 41 | 42 | renderWindowInteractor = vtkRenderWindowInteractor() 43 | renderWindowInteractor.SetRenderWindow(renderWindow) 44 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 45 | 46 | # Read the data 47 | 48 | reader = vtkStructuredPointsReader() 49 | reader.SetFileName(os.path.join(CURRENT_DIRECTORY, "../data/carotid.vtk")) 50 | 51 | # Glyphs 52 | 53 | threshold = vtkThresholdPoints() 54 | threshold.SetInputConnection(reader.GetOutputPort()) 55 | threshold.ThresholdByUpper(200) 56 | 57 | mask = vtkMaskPoints() 58 | mask.SetInputConnection(threshold.GetOutputPort()) 59 | mask.SetOnRatio(5) 60 | 61 | cone = vtkConeSource() 62 | cone.SetResolution(11) 63 | cone.SetHeight(1) 64 | cone.SetRadius(0.25) 65 | 66 | cones = vtkGlyph3D() 67 | cones.SetInputConnection(mask.GetOutputPort()) 68 | cones.SetSourceConnection(cone.GetOutputPort()) 69 | cones.SetScaleFactor(0.4) 70 | cones.SetScaleModeToScaleByVector() 71 | 72 | lut = vtkLookupTable() 73 | lut.SetHueRange(0.667, 0.0) 74 | lut.Build() 75 | 76 | scalarRange = [0] * 2 77 | cones.Update() 78 | scalarRange[0] = cones.GetOutput().GetPointData().GetScalars().GetRange()[0] 79 | scalarRange[1] = cones.GetOutput().GetPointData().GetScalars().GetRange()[1] 80 | 81 | vectorMapper = vtkPolyDataMapper() 82 | vectorMapper.SetInputConnection(cones.GetOutputPort()) 83 | vectorMapper.SetScalarRange(scalarRange[0], scalarRange[1]) 84 | vectorMapper.SetLookupTable(lut) 85 | 86 | vectorActor = vtkActor() 87 | vectorActor.SetMapper(vectorMapper) 88 | 89 | # Contours 90 | 91 | iso = vtkContourFilter() 92 | iso.SetInputConnection(reader.GetOutputPort()) 93 | iso.SetValue(0, 175) 94 | 95 | isoMapper = vtkPolyDataMapper() 96 | isoMapper.SetInputConnection(iso.GetOutputPort()) 97 | isoMapper.ScalarVisibilityOff() 98 | 99 | isoActor = vtkActor() 100 | isoActor.SetMapper(isoMapper) 101 | isoActor.GetProperty().SetRepresentationToWireframe() 102 | isoActor.GetProperty().SetOpacity(0.25) 103 | 104 | # Outline 105 | 106 | colors = vtkNamedColors() 107 | 108 | outline = vtkOutlineFilter() 109 | outline.SetInputConnection(reader.GetOutputPort()) 110 | 111 | outlineMapper = vtkPolyDataMapper() 112 | outlineMapper.SetInputConnection(outline.GetOutputPort()) 113 | 114 | outlineActor = vtkActor() 115 | outlineActor.SetMapper(outlineMapper) 116 | outlineActor.GetProperty().SetColor(colors.GetColor3d("White")) 117 | 118 | # Add the actors to the renderer 119 | 120 | renderer.AddActor(outlineActor) 121 | renderer.AddActor(vectorActor) 122 | renderer.AddActor(isoActor) 123 | renderer.ResetCamera() 124 | renderWindow.Render() 125 | 126 | # ----------------------------------------------------------------------------- 127 | # GUI 128 | # ----------------------------------------------------------------------------- 129 | 130 | server = get_server(client_type = "vue2") 131 | ctrl = server.controller 132 | 133 | with SinglePageLayout(server) as layout: 134 | layout.title.set_text("Hello trame") 135 | 136 | with layout.content: 137 | with vuetify.VContainer( 138 | fluid=True, 139 | classes="pa-0 fill-height", 140 | ): 141 | view = vtk.VtkLocalView(renderWindow) 142 | 143 | 144 | # ----------------------------------------------------------------------------- 145 | # Main 146 | # ----------------------------------------------------------------------------- 147 | 148 | if __name__ == "__main__": 149 | server.start() 150 | -------------------------------------------------------------------------------- /01_vtk/solution_ray_cast.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Web imports 4 | import os 5 | from trame.app import get_server 6 | from trame.ui.vuetify import SinglePageLayout 7 | from trame.widgets import vtk, vuetify 8 | 9 | # ----------------------------------------------------------------------------- 10 | # Example: SimpleRayCast 11 | # taken from: https://kitware.github.io/vtk-examples/site/Python/ 12 | # ----------------------------------------------------------------------------- 13 | 14 | # noinspection PyUnresolvedReferences 15 | import vtkmodules.vtkInteractionStyle 16 | from vtkmodules.vtkCommonColor import vtkNamedColors 17 | from vtkmodules.vtkCommonDataModel import vtkPiecewiseFunction 18 | from vtkmodules.vtkIOLegacy import vtkStructuredPointsReader 19 | from vtkmodules.vtkRenderingCore import ( 20 | vtkColorTransferFunction, 21 | vtkRenderWindow, 22 | vtkRenderWindowInteractor, 23 | vtkRenderer, 24 | vtkVolume, 25 | vtkVolumeProperty, 26 | ) 27 | from vtkmodules.vtkRenderingVolume import vtkFixedPointVolumeRayCastMapper 28 | 29 | # noinspection PyUnresolvedReferences 30 | from vtkmodules.vtkRenderingVolumeOpenGL2 import vtkOpenGLRayCastImageDisplayHelper 31 | 32 | 33 | CURRENT_DIRECTORY = os.path.abspath(os.path.dirname(__file__)) 34 | 35 | # ----------------------------------------------------------------------------- 36 | # VTK pipeline 37 | # ----------------------------------------------------------------------------- 38 | 39 | colors = vtkNamedColors() 40 | 41 | # This is a simple volume rendering example that 42 | # uses a vtkFixedPointVolumeRayCastMapper 43 | 44 | # Create the standard renderer, render window 45 | # and interactor. 46 | ren1 = vtkRenderer() 47 | 48 | renWin = vtkRenderWindow() 49 | renWin.AddRenderer(ren1) 50 | 51 | iren = vtkRenderWindowInteractor() 52 | iren.SetRenderWindow(renWin) 53 | iren.GetInteractorStyle().SetCurrentStyleToTrackballCamera() # +++ 54 | 55 | # Create the reader for the data. 56 | reader = vtkStructuredPointsReader() 57 | reader.SetFileName(os.path.join(CURRENT_DIRECTORY, "../data/ironProt.vtk")) 58 | 59 | # Create transfer mapping scalar value to opacity. 60 | opacityTransferFunction = vtkPiecewiseFunction() 61 | opacityTransferFunction.AddPoint(20, 0.0) 62 | opacityTransferFunction.AddPoint(255, 0.2) 63 | 64 | # Create transfer mapping scalar value to color. 65 | colorTransferFunction = vtkColorTransferFunction() 66 | colorTransferFunction.AddRGBPoint(0.0, 0.0, 0.0, 0.0) 67 | colorTransferFunction.AddRGBPoint(64.0, 1.0, 0.0, 0.0) 68 | colorTransferFunction.AddRGBPoint(128.0, 0.0, 0.0, 1.0) 69 | colorTransferFunction.AddRGBPoint(192.0, 0.0, 1.0, 0.0) 70 | colorTransferFunction.AddRGBPoint(255.0, 0.0, 0.2, 0.0) 71 | 72 | # The property describes how the data will look. 73 | volumeProperty = vtkVolumeProperty() 74 | volumeProperty.SetColor(colorTransferFunction) 75 | volumeProperty.SetScalarOpacity(opacityTransferFunction) 76 | volumeProperty.ShadeOn() 77 | volumeProperty.SetInterpolationTypeToLinear() 78 | 79 | # The mapper / ray cast function know how to render the data. 80 | volumeMapper = vtkFixedPointVolumeRayCastMapper() 81 | volumeMapper.SetInputConnection(reader.GetOutputPort()) 82 | 83 | # The volume holds the mapper and the property and 84 | # can be used to position/orient the volume. 85 | volume = vtkVolume() 86 | volume.SetMapper(volumeMapper) 87 | volume.SetProperty(volumeProperty) 88 | 89 | ren1.AddVolume(volume) 90 | ren1.SetBackground(colors.GetColor3d("Wheat")) 91 | ren1.GetActiveCamera().Azimuth(45) 92 | ren1.GetActiveCamera().Elevation(30) 93 | ren1.ResetCameraClippingRange() 94 | ren1.ResetCamera() 95 | 96 | # ----------------------------------------------------------------------------- 97 | # Web Application setup 98 | # ----------------------------------------------------------------------------- 99 | 100 | server = get_server(client_type = "vue2") 101 | ctrl = server.controller 102 | 103 | with SinglePageLayout(server) as layout: 104 | layout.title.set_text("Hello trame") 105 | 106 | with layout.content: 107 | with vuetify.VContainer( 108 | fluid=True, 109 | classes="pa-0 fill-height", 110 | ): 111 | view = vtk.VtkRemoteView(renWin) 112 | # view = vtk.VtkLocalView(renWin) 113 | 114 | 115 | # ----------------------------------------------------------------------------- 116 | # Main 117 | # ----------------------------------------------------------------------------- 118 | 119 | if __name__ == "__main__": 120 | server.start() 121 | -------------------------------------------------------------------------------- /02_layouts/app_cone.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageLayout 3 | from trame.widgets import vtk, vuetify 4 | 5 | from vtkmodules.vtkFiltersSources import vtkConeSource 6 | from vtkmodules.vtkRenderingCore import ( 7 | vtkActor, 8 | vtkPolyDataMapper, 9 | vtkRenderer, 10 | vtkRenderWindow, 11 | vtkRenderWindowInteractor, 12 | ) 13 | 14 | # Required for interactor initialization 15 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 16 | 17 | # Required for rendering initialization, not necessary for 18 | # local rendering, but doesn't hurt to include it 19 | import vtkmodules.vtkRenderingOpenGL2 # noqa 20 | 21 | 22 | # ----------------------------------------------------------------------------- 23 | # VTK pipeline 24 | # ----------------------------------------------------------------------------- 25 | 26 | renderer = vtkRenderer() 27 | renderWindow = vtkRenderWindow() 28 | renderWindow.AddRenderer(renderer) 29 | 30 | renderWindowInteractor = vtkRenderWindowInteractor() 31 | renderWindowInteractor.SetRenderWindow(renderWindow) 32 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 33 | 34 | cone_source = vtkConeSource() 35 | mapper = vtkPolyDataMapper() 36 | mapper.SetInputConnection(cone_source.GetOutputPort()) 37 | actor = vtkActor() 38 | actor.SetMapper(mapper) 39 | 40 | renderer.AddActor(actor) 41 | renderer.ResetCamera() 42 | 43 | # ----------------------------------------------------------------------------- 44 | # Trame 45 | # ----------------------------------------------------------------------------- 46 | 47 | server = get_server(client_type = "vue2") 48 | ctrl = server.controller 49 | 50 | with SinglePageLayout(server) as layout: 51 | layout.title.set_text("Hello trame") 52 | 53 | with layout.content: 54 | with vuetify.VContainer( 55 | fluid=True, 56 | classes="pa-0 fill-height", 57 | ): 58 | view = vtk.VtkLocalView(renderWindow) 59 | 60 | 61 | # ----------------------------------------------------------------------------- 62 | # Main 63 | # ----------------------------------------------------------------------------- 64 | 65 | if __name__ == "__main__": 66 | server.start() 67 | -------------------------------------------------------------------------------- /02_layouts/solution_FullScreenPage.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import VAppLayout 3 | from trame.widgets import vtk, vuetify 4 | 5 | from vtkmodules.vtkFiltersSources import vtkConeSource 6 | from vtkmodules.vtkRenderingCore import ( 7 | vtkActor, 8 | vtkPolyDataMapper, 9 | vtkRenderer, 10 | vtkRenderWindow, 11 | vtkRenderWindowInteractor, 12 | ) 13 | 14 | # Required for interactor initialization 15 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 16 | 17 | # Required for rendering initialization, not necessary for 18 | # local rendering, but doesn't hurt to include it 19 | import vtkmodules.vtkRenderingOpenGL2 # noqa 20 | 21 | 22 | # ----------------------------------------------------------------------------- 23 | # VTK pipeline 24 | # ----------------------------------------------------------------------------- 25 | 26 | renderer = vtkRenderer() 27 | renderWindow = vtkRenderWindow() 28 | renderWindow.AddRenderer(renderer) 29 | 30 | renderWindowInteractor = vtkRenderWindowInteractor() 31 | renderWindowInteractor.SetRenderWindow(renderWindow) 32 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 33 | 34 | cone_source = vtkConeSource() 35 | mapper = vtkPolyDataMapper() 36 | mapper.SetInputConnection(cone_source.GetOutputPort()) 37 | actor = vtkActor() 38 | actor.SetMapper(mapper) 39 | 40 | renderer.AddActor(actor) 41 | renderer.ResetCamera() 42 | 43 | # ----------------------------------------------------------------------------- 44 | # Trame 45 | # ----------------------------------------------------------------------------- 46 | 47 | server = get_server(client_type = "vue2") 48 | ctrl = server.controller 49 | 50 | with VAppLayout(server) as layout: 51 | with layout.root: 52 | with vuetify.VContainer( 53 | fluid=True, 54 | classes="pa-0 fill-height", 55 | ): 56 | view = vtk.VtkLocalView(renderWindow) 57 | 58 | # ----------------------------------------------------------------------------- 59 | # Main 60 | # ----------------------------------------------------------------------------- 61 | 62 | if __name__ == "__main__": 63 | server.start() 64 | -------------------------------------------------------------------------------- /02_layouts/solution_SinglePage.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageLayout 3 | from trame.widgets import vtk, vuetify 4 | 5 | from vtkmodules.vtkFiltersSources import vtkConeSource 6 | from vtkmodules.vtkRenderingCore import ( 7 | vtkActor, 8 | vtkPolyDataMapper, 9 | vtkRenderer, 10 | vtkRenderWindow, 11 | vtkRenderWindowInteractor, 12 | ) 13 | 14 | # Required for interactor initialization 15 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 16 | 17 | # Required for rendering initialization, not necessary for 18 | # local rendering, but doesn't hurt to include it 19 | import vtkmodules.vtkRenderingOpenGL2 # noqa 20 | 21 | 22 | # ----------------------------------------------------------------------------- 23 | # VTK pipeline 24 | # ----------------------------------------------------------------------------- 25 | 26 | renderer = vtkRenderer() 27 | renderWindow = vtkRenderWindow() 28 | renderWindow.AddRenderer(renderer) 29 | 30 | renderWindowInteractor = vtkRenderWindowInteractor() 31 | renderWindowInteractor.SetRenderWindow(renderWindow) 32 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 33 | 34 | cone_source = vtkConeSource() 35 | mapper = vtkPolyDataMapper() 36 | mapper.SetInputConnection(cone_source.GetOutputPort()) 37 | actor = vtkActor() 38 | actor.SetMapper(mapper) 39 | 40 | renderer.AddActor(actor) 41 | renderer.ResetCamera() 42 | 43 | # ----------------------------------------------------------------------------- 44 | # Trame 45 | # ----------------------------------------------------------------------------- 46 | 47 | server = get_server(client_type = "vue2") 48 | ctrl = server.controller 49 | 50 | with SinglePageLayout(server) as layout: 51 | layout.title.set_text("Hello trame") 52 | 53 | with layout.content: 54 | with vuetify.VContainer( 55 | fluid=True, 56 | classes="pa-0 fill-height", 57 | ): 58 | view = vtk.VtkLocalView(renderWindow) 59 | 60 | # ----------------------------------------------------------------------------- 61 | # Main 62 | # ----------------------------------------------------------------------------- 63 | 64 | if __name__ == "__main__": 65 | server.start() 66 | -------------------------------------------------------------------------------- /02_layouts/solution_SinglePageWithDrawer.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageWithDrawerLayout 3 | from trame.widgets import vtk, vuetify 4 | 5 | from vtkmodules.vtkFiltersSources import vtkConeSource 6 | from vtkmodules.vtkRenderingCore import ( 7 | vtkActor, 8 | vtkPolyDataMapper, 9 | vtkRenderer, 10 | vtkRenderWindow, 11 | vtkRenderWindowInteractor, 12 | ) 13 | 14 | # Required for interactor initialization 15 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 16 | 17 | # Required for rendering initialization, not necessary for 18 | # local rendering, but doesn't hurt to include it 19 | import vtkmodules.vtkRenderingOpenGL2 # noqa 20 | 21 | 22 | # ----------------------------------------------------------------------------- 23 | # VTK pipeline 24 | # ----------------------------------------------------------------------------- 25 | 26 | renderer = vtkRenderer() 27 | renderWindow = vtkRenderWindow() 28 | renderWindow.AddRenderer(renderer) 29 | 30 | renderWindowInteractor = vtkRenderWindowInteractor() 31 | renderWindowInteractor.SetRenderWindow(renderWindow) 32 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 33 | 34 | cone_source = vtkConeSource() 35 | mapper = vtkPolyDataMapper() 36 | mapper.SetInputConnection(cone_source.GetOutputPort()) 37 | actor = vtkActor() 38 | actor.SetMapper(mapper) 39 | 40 | renderer.AddActor(actor) 41 | renderer.ResetCamera() 42 | 43 | # ----------------------------------------------------------------------------- 44 | # Trame 45 | # ----------------------------------------------------------------------------- 46 | 47 | server = get_server(client_type = "vue2") 48 | ctrl = server.controller 49 | 50 | with SinglePageWithDrawerLayout(server) as layout: 51 | layout.title.set_text("Hello trame") 52 | 53 | with layout.content: 54 | with vuetify.VContainer( 55 | fluid=True, 56 | classes="pa-0 fill-height", 57 | ): 58 | view = vtk.VtkLocalView(renderWindow) 59 | 60 | 61 | # ----------------------------------------------------------------------------- 62 | # Main 63 | # ----------------------------------------------------------------------------- 64 | 65 | if __name__ == "__main__": 66 | server.start() 67 | -------------------------------------------------------------------------------- /03_html/app_cone.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageLayout 3 | from trame.widgets import vtk, vuetify 4 | 5 | from vtkmodules.vtkFiltersSources import vtkConeSource 6 | from vtkmodules.vtkRenderingCore import ( 7 | vtkActor, 8 | vtkPolyDataMapper, 9 | vtkRenderer, 10 | vtkRenderWindow, 11 | vtkRenderWindowInteractor, 12 | ) 13 | 14 | # Required for interactor initialization 15 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 16 | 17 | # Required for rendering initialization, not necessary for 18 | # local rendering, but doesn't hurt to include it 19 | import vtkmodules.vtkRenderingOpenGL2 # noqa 20 | 21 | 22 | # ----------------------------------------------------------------------------- 23 | # VTK pipeline 24 | # ----------------------------------------------------------------------------- 25 | 26 | renderer = vtkRenderer() 27 | renderWindow = vtkRenderWindow() 28 | renderWindow.AddRenderer(renderer) 29 | 30 | renderWindowInteractor = vtkRenderWindowInteractor() 31 | renderWindowInteractor.SetRenderWindow(renderWindow) 32 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 33 | 34 | cone_source = vtkConeSource() 35 | mapper = vtkPolyDataMapper() 36 | mapper.SetInputConnection(cone_source.GetOutputPort()) 37 | actor = vtkActor() 38 | actor.SetMapper(mapper) 39 | 40 | renderer.AddActor(actor) 41 | renderer.ResetCamera() 42 | 43 | # ----------------------------------------------------------------------------- 44 | # Trame 45 | # ----------------------------------------------------------------------------- 46 | 47 | server = get_server(client_type = "vue2") 48 | ctrl = server.controller 49 | 50 | with SinglePageLayout(server) as layout: 51 | layout.title.set_text("Hello trame") 52 | 53 | with layout.content: 54 | with vuetify.VContainer( 55 | fluid=True, 56 | classes="pa-0 fill-height", 57 | ): 58 | view = vtk.VtkLocalView(renderWindow) 59 | 60 | 61 | # ----------------------------------------------------------------------------- 62 | # Main 63 | # ----------------------------------------------------------------------------- 64 | 65 | if __name__ == "__main__": 66 | server.start() 67 | -------------------------------------------------------------------------------- /03_html/solution_buttons.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageLayout 3 | from trame.widgets import vtk, vuetify 4 | 5 | from vtkmodules.vtkFiltersSources import vtkConeSource 6 | from vtkmodules.vtkRenderingCore import ( 7 | vtkActor, 8 | vtkPolyDataMapper, 9 | vtkRenderer, 10 | vtkRenderWindow, 11 | vtkRenderWindowInteractor, 12 | ) 13 | 14 | # Required for interactor initialization 15 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 16 | 17 | # Required for rendering initialization, not necessary for 18 | # local rendering, but doesn't hurt to include it 19 | import vtkmodules.vtkRenderingOpenGL2 # noqa 20 | 21 | 22 | # ----------------------------------------------------------------------------- 23 | # VTK pipeline 24 | # ----------------------------------------------------------------------------- 25 | 26 | renderer = vtkRenderer() 27 | renderWindow = vtkRenderWindow() 28 | renderWindow.AddRenderer(renderer) 29 | 30 | renderWindowInteractor = vtkRenderWindowInteractor() 31 | renderWindowInteractor.SetRenderWindow(renderWindow) 32 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 33 | 34 | cone_source = vtkConeSource() 35 | mapper = vtkPolyDataMapper() 36 | mapper.SetInputConnection(cone_source.GetOutputPort()) 37 | actor = vtkActor() 38 | actor.SetMapper(mapper) 39 | 40 | renderer.AddActor(actor) 41 | renderer.ResetCamera() 42 | 43 | # ----------------------------------------------------------------------------- 44 | # Trame 45 | # ----------------------------------------------------------------------------- 46 | 47 | server = get_server(client_type = "vue2") 48 | ctrl = server.controller 49 | 50 | with SinglePageLayout(server) as layout: 51 | layout.title.set_text("Hello trame") 52 | 53 | with layout.content: 54 | with vuetify.VContainer( 55 | fluid=True, 56 | classes="pa-0 fill-height", 57 | ): 58 | view = vtk.VtkLocalView(renderWindow) 59 | ctrl.view_reset_camera = view.reset_camera 60 | 61 | with layout.toolbar: 62 | vuetify.VSpacer() 63 | vuetify.VSwitch( 64 | v_model="$vuetify.theme.dark", 65 | hide_details=True, 66 | dense=True, 67 | ) 68 | with vuetify.VBtn(icon=True, click=ctrl.view_reset_camera): 69 | vuetify.VIcon("mdi-crop-free") 70 | 71 | # ----------------------------------------------------------------------------- 72 | # Main 73 | # ----------------------------------------------------------------------------- 74 | 75 | if __name__ == "__main__": 76 | server.start() 77 | -------------------------------------------------------------------------------- /03_html/solution_final.py: -------------------------------------------------------------------------------- 1 | from trame.app import get_server 2 | from trame.ui.vuetify import SinglePageLayout 3 | from trame.widgets import vtk, vuetify 4 | 5 | from vtkmodules.vtkFiltersSources import vtkConeSource 6 | from vtkmodules.vtkRenderingCore import ( 7 | vtkActor, 8 | vtkPolyDataMapper, 9 | vtkRenderer, 10 | vtkRenderWindow, 11 | vtkRenderWindowInteractor, 12 | ) 13 | 14 | # Required for interactor initialization 15 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 16 | 17 | # Required for rendering initialization, not necessary for 18 | # local rendering, but doesn't hurt to include it 19 | import vtkmodules.vtkRenderingOpenGL2 # noqa 20 | 21 | # ----------------------------------------------------------------------------- 22 | # Globals 23 | # ----------------------------------------------------------------------------- 24 | 25 | DEFAULT_RESOLUTION = 6 26 | 27 | # ----------------------------------------------------------------------------- 28 | # VTK pipeline 29 | # ----------------------------------------------------------------------------- 30 | 31 | renderer = vtkRenderer() 32 | renderWindow = vtkRenderWindow() 33 | renderWindow.AddRenderer(renderer) 34 | 35 | renderWindowInteractor = vtkRenderWindowInteractor() 36 | renderWindowInteractor.SetRenderWindow(renderWindow) 37 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 38 | 39 | cone_source = vtkConeSource() 40 | mapper = vtkPolyDataMapper() 41 | mapper.SetInputConnection(cone_source.GetOutputPort()) 42 | actor = vtkActor() 43 | actor.SetMapper(mapper) 44 | 45 | renderer.AddActor(actor) 46 | renderer.ResetCamera() 47 | 48 | # ----------------------------------------------------------------------------- 49 | # Trame setup 50 | # ----------------------------------------------------------------------------- 51 | 52 | server = get_server(client_type = "vue2") 53 | state, ctrl = server.state, server.controller 54 | 55 | # ----------------------------------------------------------------------------- 56 | # Functions 57 | # ----------------------------------------------------------------------------- 58 | 59 | 60 | @state.change("resolution") 61 | def update_resolution(resolution, **kwargs): 62 | cone_source.SetResolution(resolution) 63 | ctrl.view_update() 64 | 65 | 66 | def reset_resolution(): 67 | state.resolution = DEFAULT_RESOLUTION 68 | 69 | 70 | # ----------------------------------------------------------------------------- 71 | # GUI 72 | # ----------------------------------------------------------------------------- 73 | 74 | with SinglePageLayout(server) as layout: 75 | layout.title.set_text("Hello trame") 76 | 77 | with layout.content: 78 | with vuetify.VContainer( 79 | fluid=True, 80 | classes="pa-0 fill-height", 81 | ): 82 | view = vtk.VtkLocalView(renderWindow) 83 | ctrl.view_update = view.update 84 | ctrl.view_reset_camera = view.reset_camera 85 | 86 | with layout.toolbar: 87 | vuetify.VSpacer() 88 | vuetify.VSlider( 89 | v_model=("resolution", DEFAULT_RESOLUTION), 90 | min=3, 91 | max=60, 92 | step=1, 93 | hide_details=True, 94 | dense=True, 95 | style="max-width: 300px", 96 | ) 97 | with vuetify.VBtn(icon=True, click=reset_resolution): 98 | vuetify.VIcon("mdi-restore") 99 | 100 | vuetify.VDivider(vertical=True, classes="mx-2") 101 | 102 | vuetify.VSwitch( 103 | v_model="$vuetify.theme.dark", 104 | hide_details=True, 105 | dense=True, 106 | ) 107 | with vuetify.VBtn(icon=True, click=ctrl.view_reset_camera): 108 | vuetify.VIcon("mdi-crop-free") 109 | 110 | # ----------------------------------------------------------------------------- 111 | # Main 112 | # ----------------------------------------------------------------------------- 113 | 114 | if __name__ == "__main__": 115 | server.start() 116 | -------------------------------------------------------------------------------- /04_application/app.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from trame.app import get_server 4 | from trame.ui.vuetify import SinglePageLayout 5 | from trame.widgets import vtk, vuetify 6 | 7 | from vtkmodules.vtkRenderingCore import ( 8 | vtkActor, 9 | vtkDataSetMapper, 10 | vtkRenderer, 11 | vtkRenderWindow, 12 | vtkRenderWindowInteractor, 13 | ) 14 | 15 | # Required for interactor initialization 16 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 17 | 18 | # Required for rendering initialization, not necessary for 19 | # local rendering, but doesn't hurt to include it 20 | import vtkmodules.vtkRenderingOpenGL2 # noqa 21 | 22 | CURRENT_DIRECTORY = os.path.abspath(os.path.dirname(__file__)) 23 | 24 | # ----------------------------------------------------------------------------- 25 | # Constants 26 | # ----------------------------------------------------------------------------- 27 | 28 | 29 | # ----------------------------------------------------------------------------- 30 | # VTK pipeline 31 | # ----------------------------------------------------------------------------- 32 | 33 | renderer = vtkRenderer() 34 | renderWindow = vtkRenderWindow() 35 | renderWindow.AddRenderer(renderer) 36 | 37 | renderWindowInteractor = vtkRenderWindowInteractor() 38 | renderWindowInteractor.SetRenderWindow(renderWindow) 39 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 40 | 41 | # Read Data 42 | 43 | # Extract Array/Field information 44 | 45 | # Mesh 46 | # Mesh: Setup default representation to surface 47 | # Mesh: Apply rainbow color map 48 | # Mesh: Color by default array 49 | 50 | # Contour 51 | # Contour: ContourBy default array 52 | # Contour: Setup default representation to surface 53 | # Contour: Apply rainbow color map 54 | # Contour: Color by default array 55 | 56 | # Cube Axes 57 | # Cube Axes: Boundaries, camera, and styling 58 | 59 | renderer.ResetCamera() 60 | 61 | # ----------------------------------------------------------------------------- 62 | # Trame setup 63 | # ----------------------------------------------------------------------------- 64 | 65 | server = get_server(client_type="vue2") 66 | state, ctrl = server.state, server.controller 67 | 68 | # ----------------------------------------------------------------------------- 69 | # Callbacks 70 | # ----------------------------------------------------------------------------- 71 | 72 | # ----------------------------------------------------------------------------- 73 | # GUI elements 74 | # ----------------------------------------------------------------------------- 75 | 76 | # ----------------------------------------------------------------------------- 77 | # GUI 78 | # ----------------------------------------------------------------------------- 79 | 80 | with SinglePageLayout(server) as layout: 81 | layout.title.set_text("Viewer") 82 | 83 | with layout.toolbar: 84 | # toolbar components 85 | pass 86 | 87 | with layout.content: 88 | # content components 89 | with vuetify.VContainer( 90 | fluid=True, 91 | classes="pa-0 fill-height", 92 | ): 93 | view = vtk.VtkLocalView(renderWindow) 94 | ctrl.view_update = view.update 95 | ctrl.view_reset_camera = view.reset_camera 96 | 97 | # ----------------------------------------------------------------------------- 98 | # Main 99 | # ----------------------------------------------------------------------------- 100 | 101 | if __name__ == "__main__": 102 | server.start() 103 | -------------------------------------------------------------------------------- /04_application/solution.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from trame.app import get_server 4 | from trame.ui.vuetify import SinglePageWithDrawerLayout 5 | from trame.widgets import vtk, vuetify, trame 6 | 7 | from trame_vtk.modules.vtk.serializers import configure_serializer 8 | 9 | from vtkmodules.vtkCommonDataModel import vtkDataObject 10 | from vtkmodules.vtkFiltersCore import vtkContourFilter 11 | from vtkmodules.vtkIOXML import vtkXMLUnstructuredGridReader 12 | from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor 13 | 14 | from vtkmodules.vtkRenderingCore import ( 15 | vtkActor, 16 | vtkDataSetMapper, 17 | vtkRenderer, 18 | vtkRenderWindow, 19 | vtkRenderWindowInteractor, 20 | ) 21 | 22 | # Required for interactor initialization 23 | from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa 24 | 25 | # Required for rendering initialization, not necessary for 26 | # local rendering, but doesn't hurt to include it 27 | import vtkmodules.vtkRenderingOpenGL2 # noqa 28 | 29 | CURRENT_DIRECTORY = os.path.abspath(os.path.dirname(__file__)) 30 | 31 | # Configure scene encoder 32 | configure_serializer(encode_lut=True, skip_light=True) 33 | 34 | # ----------------------------------------------------------------------------- 35 | # Constants 36 | # ----------------------------------------------------------------------------- 37 | 38 | 39 | class Representation: 40 | Points = 0 41 | Wireframe = 1 42 | Surface = 2 43 | SurfaceWithEdges = 3 44 | 45 | 46 | class LookupTable: 47 | Rainbow = 0 48 | Inverted_Rainbow = 1 49 | Greyscale = 2 50 | Inverted_Greyscale = 3 51 | 52 | 53 | # ----------------------------------------------------------------------------- 54 | # VTK pipeline 55 | # ----------------------------------------------------------------------------- 56 | 57 | renderer = vtkRenderer() 58 | renderWindow = vtkRenderWindow() 59 | renderWindow.AddRenderer(renderer) 60 | 61 | renderWindowInteractor = vtkRenderWindowInteractor() 62 | renderWindowInteractor.SetRenderWindow(renderWindow) 63 | renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() 64 | 65 | # Read Data 66 | reader = vtkXMLUnstructuredGridReader() 67 | reader.SetFileName(os.path.join(CURRENT_DIRECTORY, "../data/disk_out_ref.vtu")) 68 | reader.Update() 69 | 70 | # Extract Array/Field information 71 | dataset_arrays = [] 72 | fields = [ 73 | (reader.GetOutput().GetPointData(), vtkDataObject.FIELD_ASSOCIATION_POINTS), 74 | (reader.GetOutput().GetCellData(), vtkDataObject.FIELD_ASSOCIATION_CELLS), 75 | ] 76 | for field in fields: 77 | field_arrays, association = field 78 | for i in range(field_arrays.GetNumberOfArrays()): 79 | array = field_arrays.GetArray(i) 80 | array_range = array.GetRange() 81 | dataset_arrays.append( 82 | { 83 | "text": array.GetName(), 84 | "value": i, 85 | "range": list(array_range), 86 | "type": association, 87 | } 88 | ) 89 | default_array = dataset_arrays[0] 90 | default_min, default_max = default_array.get("range") 91 | 92 | # Mesh 93 | mesh_mapper = vtkDataSetMapper() 94 | mesh_mapper.SetInputConnection(reader.GetOutputPort()) 95 | mesh_actor = vtkActor() 96 | mesh_actor.SetMapper(mesh_mapper) 97 | renderer.AddActor(mesh_actor) 98 | 99 | # Mesh: Setup default representation to surface 100 | mesh_actor.GetProperty().SetRepresentationToSurface() 101 | mesh_actor.GetProperty().SetPointSize(1) 102 | mesh_actor.GetProperty().EdgeVisibilityOff() 103 | 104 | # Mesh: Apply rainbow color map 105 | mesh_lut = mesh_mapper.GetLookupTable() 106 | mesh_lut.SetHueRange(0.666, 0.0) 107 | mesh_lut.SetSaturationRange(1.0, 1.0) 108 | mesh_lut.SetValueRange(1.0, 1.0) 109 | mesh_lut.Build() 110 | 111 | # Mesh: Color by default array 112 | mesh_mapper.SelectColorArray(default_array.get("text")) 113 | mesh_mapper.GetLookupTable().SetRange(default_min, default_max) 114 | if default_array.get("type") == vtkDataObject.FIELD_ASSOCIATION_POINTS: 115 | mesh_mapper.SetScalarModeToUsePointFieldData() 116 | else: 117 | mesh_mapper.SetScalarModeToUseCellFieldData() 118 | mesh_mapper.SetScalarVisibility(True) 119 | mesh_mapper.SetUseLookupTableScalarRange(True) 120 | 121 | # Contour 122 | contour = vtkContourFilter() 123 | contour.SetInputConnection(reader.GetOutputPort()) 124 | contour_mapper = vtkDataSetMapper() 125 | contour_mapper.SetInputConnection(contour.GetOutputPort()) 126 | contour_actor = vtkActor() 127 | contour_actor.SetMapper(contour_mapper) 128 | renderer.AddActor(contour_actor) 129 | 130 | # Contour: ContourBy default array 131 | contour_value = 0.5 * (default_max + default_min) 132 | contour.SetInputArrayToProcess( 133 | 0, 0, 0, default_array.get("type"), default_array.get("text") 134 | ) 135 | contour.SetValue(0, contour_value) 136 | 137 | # Contour: Setup default representation to surface 138 | contour_actor.GetProperty().SetRepresentationToSurface() 139 | contour_actor.GetProperty().SetPointSize(1) 140 | contour_actor.GetProperty().EdgeVisibilityOff() 141 | 142 | # Contour: Apply rainbow color map 143 | contour_lut = contour_mapper.GetLookupTable() 144 | contour_lut.SetHueRange(0.666, 0.0) 145 | contour_lut.SetSaturationRange(1.0, 1.0) 146 | contour_lut.SetValueRange(1.0, 1.0) 147 | contour_lut.Build() 148 | 149 | # Contour: Color by default array 150 | contour_mapper.SelectColorArray(default_array.get("text")) 151 | contour_mapper.GetLookupTable().SetRange(default_min, default_max) 152 | if default_array.get("type") == vtkDataObject.FIELD_ASSOCIATION_POINTS: 153 | contour_mapper.SetScalarModeToUsePointFieldData() 154 | else: 155 | contour_mapper.SetScalarModeToUseCellFieldData() 156 | contour_mapper.SetScalarVisibility(True) 157 | contour_mapper.SetUseLookupTableScalarRange(True) 158 | 159 | # Cube Axes 160 | cube_axes = vtkCubeAxesActor() 161 | renderer.AddActor(cube_axes) 162 | 163 | # Cube Axes: Boundaries, camera, and styling 164 | cube_axes.SetBounds(mesh_actor.GetBounds()) 165 | cube_axes.SetCamera(renderer.GetActiveCamera()) 166 | cube_axes.SetXLabelFormat("%6.1f") 167 | cube_axes.SetYLabelFormat("%6.1f") 168 | cube_axes.SetZLabelFormat("%6.1f") 169 | cube_axes.SetFlyModeToOuterEdges() 170 | 171 | renderer.ResetCamera() 172 | 173 | # ----------------------------------------------------------------------------- 174 | # Trame setup 175 | # ----------------------------------------------------------------------------- 176 | 177 | server = get_server(client_type="vue2") 178 | state, ctrl = server.state, server.controller 179 | 180 | state.setdefault("active_ui", None) 181 | 182 | # ----------------------------------------------------------------------------- 183 | # Callbacks 184 | # ----------------------------------------------------------------------------- 185 | 186 | 187 | @state.change("cube_axes_visibility") 188 | def update_cube_axes_visibility(cube_axes_visibility, **kwargs): 189 | cube_axes.SetVisibility(cube_axes_visibility) 190 | ctrl.view_update() 191 | 192 | 193 | # Selection Change 194 | def actives_change(ids): 195 | _id = ids[0] 196 | if _id == "1": # Mesh 197 | state.active_ui = "mesh" 198 | elif _id == "2": # Contour 199 | state.active_ui = "contour" 200 | else: 201 | state.active_ui = "nothing" 202 | 203 | 204 | # Visibility Change 205 | def visibility_change(event): 206 | _id = event["id"] 207 | _visibility = event["visible"] 208 | 209 | if _id == "1": # Mesh 210 | mesh_actor.SetVisibility(_visibility) 211 | elif _id == "2": # Contour 212 | contour_actor.SetVisibility(_visibility) 213 | ctrl.view_update() 214 | 215 | 216 | # Representation Callbacks 217 | def update_representation(actor, mode): 218 | property = actor.GetProperty() 219 | if mode == Representation.Points: 220 | property.SetRepresentationToPoints() 221 | property.SetPointSize(5) 222 | property.EdgeVisibilityOff() 223 | elif mode == Representation.Wireframe: 224 | property.SetRepresentationToWireframe() 225 | property.SetPointSize(1) 226 | property.EdgeVisibilityOff() 227 | elif mode == Representation.Surface: 228 | property.SetRepresentationToSurface() 229 | property.SetPointSize(1) 230 | property.EdgeVisibilityOff() 231 | elif mode == Representation.SurfaceWithEdges: 232 | property.SetRepresentationToSurface() 233 | property.SetPointSize(1) 234 | property.EdgeVisibilityOn() 235 | 236 | 237 | @state.change("mesh_representation") 238 | def update_mesh_representation(mesh_representation, **kwargs): 239 | update_representation(mesh_actor, mesh_representation) 240 | ctrl.view_update() 241 | 242 | 243 | @state.change("contour_representation") 244 | def update_contour_representation(contour_representation, **kwargs): 245 | update_representation(contour_actor, contour_representation) 246 | ctrl.view_update() 247 | 248 | 249 | # Color By Callbacks 250 | def color_by_array(actor, array): 251 | _min, _max = array.get("range") 252 | mapper = actor.GetMapper() 253 | mapper.SelectColorArray(array.get("text")) 254 | mapper.GetLookupTable().SetRange(_min, _max) 255 | if array.get("type") == vtkDataObject.FIELD_ASSOCIATION_POINTS: 256 | mesh_mapper.SetScalarModeToUsePointFieldData() 257 | else: 258 | mesh_mapper.SetScalarModeToUseCellFieldData() 259 | mapper.SetScalarVisibility(True) 260 | mapper.SetUseLookupTableScalarRange(True) 261 | 262 | 263 | @state.change("mesh_color_array_idx") 264 | def update_mesh_color_by_name(mesh_color_array_idx, **kwargs): 265 | array = dataset_arrays[mesh_color_array_idx] 266 | color_by_array(mesh_actor, array) 267 | ctrl.view_update() 268 | 269 | 270 | @state.change("contour_color_array_idx") 271 | def update_contour_color_by_name(contour_color_array_idx, **kwargs): 272 | array = dataset_arrays[contour_color_array_idx] 273 | color_by_array(contour_actor, array) 274 | ctrl.view_update() 275 | 276 | 277 | # Color Map Callbacks 278 | def use_preset(actor, preset): 279 | lut = actor.GetMapper().GetLookupTable() 280 | if preset == LookupTable.Rainbow: 281 | lut.SetHueRange(0.666, 0.0) 282 | lut.SetSaturationRange(1.0, 1.0) 283 | lut.SetValueRange(1.0, 1.0) 284 | elif preset == LookupTable.Inverted_Rainbow: 285 | lut.SetHueRange(0.0, 0.666) 286 | lut.SetSaturationRange(1.0, 1.0) 287 | lut.SetValueRange(1.0, 1.0) 288 | elif preset == LookupTable.Greyscale: 289 | lut.SetHueRange(0.0, 0.0) 290 | lut.SetSaturationRange(0.0, 0.0) 291 | lut.SetValueRange(0.0, 1.0) 292 | elif preset == LookupTable.Inverted_Greyscale: 293 | lut.SetHueRange(0.0, 0.666) 294 | lut.SetSaturationRange(0.0, 0.0) 295 | lut.SetValueRange(1.0, 0.0) 296 | lut.Build() 297 | 298 | 299 | @state.change("mesh_color_preset") 300 | def update_mesh_color_preset(mesh_color_preset, **kwargs): 301 | use_preset(mesh_actor, mesh_color_preset) 302 | ctrl.view_update() 303 | 304 | 305 | @state.change("contour_color_preset") 306 | def update_contour_color_preset(contour_color_preset, **kwargs): 307 | use_preset(contour_actor, contour_color_preset) 308 | ctrl.view_update() 309 | 310 | 311 | # Opacity Callbacks 312 | @state.change("mesh_opacity") 313 | def update_mesh_opacity(mesh_opacity, **kwargs): 314 | mesh_actor.GetProperty().SetOpacity(mesh_opacity) 315 | ctrl.view_update() 316 | 317 | 318 | @state.change("contour_opacity") 319 | def update_contour_opacity(contour_opacity, **kwargs): 320 | contour_actor.GetProperty().SetOpacity(contour_opacity) 321 | ctrl.view_update() 322 | 323 | 324 | # Contour Callbacks 325 | @state.change("contour_by_array_idx") 326 | def update_contour_by(contour_by_array_idx, **kwargs): 327 | array = dataset_arrays[contour_by_array_idx] 328 | contour_min, contour_max = array.get("range") 329 | contour_step = 0.01 * (contour_max - contour_min) 330 | contour_value = 0.5 * (contour_max + contour_min) 331 | contour.SetInputArrayToProcess(0, 0, 0, array.get("type"), array.get("text")) 332 | contour.SetValue(0, contour_value) 333 | 334 | # Update UI 335 | state.contour_min = contour_min 336 | state.contour_max = contour_max 337 | state.contour_value = contour_value 338 | state.contour_step = contour_step 339 | 340 | # Update View 341 | ctrl.view_update() 342 | 343 | 344 | @state.change("contour_value") 345 | def update_contour_value(contour_value, **kwargs): 346 | contour.SetValue(0, float(contour_value)) 347 | ctrl.view_update() 348 | 349 | 350 | # ----------------------------------------------------------------------------- 351 | # GUI elements 352 | # ----------------------------------------------------------------------------- 353 | 354 | 355 | def standard_buttons(): 356 | vuetify.VCheckbox( 357 | v_model=("cube_axes_visibility", True), 358 | on_icon="mdi-cube-outline", 359 | off_icon="mdi-cube-off-outline", 360 | classes="mx-1", 361 | hide_details=True, 362 | dense=True, 363 | ) 364 | vuetify.VCheckbox( 365 | v_model="$vuetify.theme.dark", 366 | on_icon="mdi-lightbulb-off-outline", 367 | off_icon="mdi-lightbulb-outline", 368 | classes="mx-1", 369 | hide_details=True, 370 | dense=True, 371 | ) 372 | vuetify.VCheckbox( 373 | v_model=("viewMode", "local"), 374 | on_icon="mdi-lan-disconnect", 375 | off_icon="mdi-lan-connect", 376 | true_value="local", 377 | false_value="remote", 378 | classes="mx-1", 379 | hide_details=True, 380 | dense=True, 381 | ) 382 | with vuetify.VBtn(icon=True, click="$refs.view.resetCamera()"): 383 | vuetify.VIcon("mdi-crop-free") 384 | 385 | 386 | def pipeline_widget(): 387 | trame.GitTree( 388 | sources=( 389 | "pipeline", 390 | [ 391 | {"id": "1", "parent": "0", "visible": 1, "name": "Mesh"}, 392 | {"id": "2", "parent": "1", "visible": 1, "name": "Contour"}, 393 | ], 394 | ), 395 | actives_change=(actives_change, "[$event]"), 396 | visibility_change=(visibility_change, "[$event]"), 397 | ) 398 | 399 | 400 | def ui_card(title, ui_name): 401 | with vuetify.VCard(v_show=f"active_ui == '{ui_name}'"): 402 | vuetify.VCardTitle( 403 | title, 404 | classes="grey lighten-1 py-1 grey--text text--darken-3", 405 | style="user-select: none; cursor: pointer", 406 | hide_details=True, 407 | dense=True, 408 | ) 409 | content = vuetify.VCardText(classes="py-2") 410 | return content 411 | 412 | 413 | def mesh_card(): 414 | with ui_card(title="Mesh", ui_name="mesh"): 415 | vuetify.VSelect( 416 | # Representation 417 | v_model=("mesh_representation", Representation.Surface), 418 | items=( 419 | "representations", 420 | [ 421 | {"text": "Points", "value": 0}, 422 | {"text": "Wireframe", "value": 1}, 423 | {"text": "Surface", "value": 2}, 424 | {"text": "SurfaceWithEdges", "value": 3}, 425 | ], 426 | ), 427 | label="Representation", 428 | hide_details=True, 429 | dense=True, 430 | outlined=True, 431 | classes="pt-1", 432 | ) 433 | with vuetify.VRow(classes="pt-2", dense=True): 434 | with vuetify.VCol(cols="6"): 435 | vuetify.VSelect( 436 | # Color By 437 | label="Color by", 438 | v_model=("mesh_color_array_idx", 0), 439 | items=("array_list", dataset_arrays), 440 | hide_details=True, 441 | dense=True, 442 | outlined=True, 443 | classes="pt-1", 444 | ) 445 | with vuetify.VCol(cols="6"): 446 | vuetify.VSelect( 447 | # Color Map 448 | label="Colormap", 449 | v_model=("mesh_color_preset", LookupTable.Rainbow), 450 | items=( 451 | "colormaps", 452 | [ 453 | {"text": "Rainbow", "value": 0}, 454 | {"text": "Inv Rainbow", "value": 1}, 455 | {"text": "Greyscale", "value": 2}, 456 | {"text": "Inv Greyscale", "value": 3}, 457 | ], 458 | ), 459 | hide_details=True, 460 | dense=True, 461 | outlined=True, 462 | classes="pt-1", 463 | ) 464 | vuetify.VSlider( 465 | # Opacity 466 | v_model=("mesh_opacity", 1.0), 467 | min=0, 468 | max=1, 469 | step=0.1, 470 | label="Opacity", 471 | classes="mt-1", 472 | hide_details=True, 473 | dense=True, 474 | ) 475 | 476 | 477 | def contour_card(): 478 | with ui_card(title="Contour", ui_name="contour"): 479 | vuetify.VSelect( 480 | # Contour By 481 | label="Contour by", 482 | v_model=("contour_by_array_idx", 0), 483 | items=("array_list", dataset_arrays), 484 | hide_details=True, 485 | dense=True, 486 | outlined=True, 487 | classes="pt-1", 488 | ) 489 | vuetify.VSlider( 490 | # Contour Value 491 | v_model=("contour_value", contour_value), 492 | min=("contour_min", default_min), 493 | max=("contour_max", default_max), 494 | step=("contour_step", 0.01 * (default_max - default_min)), 495 | label="Value", 496 | classes="my-1", 497 | hide_details=True, 498 | dense=True, 499 | ) 500 | vuetify.VSelect( 501 | # Representation 502 | v_model=("contour_representation", Representation.Surface), 503 | items=( 504 | "representations", 505 | [ 506 | {"text": "Points", "value": 0}, 507 | {"text": "Wireframe", "value": 1}, 508 | {"text": "Surface", "value": 2}, 509 | {"text": "SurfaceWithEdges", "value": 3}, 510 | ], 511 | ), 512 | label="Representation", 513 | hide_details=True, 514 | dense=True, 515 | outlined=True, 516 | classes="pt-1", 517 | ) 518 | with vuetify.VRow(classes="pt-2", dense=True): 519 | with vuetify.VCol(cols="6"): 520 | vuetify.VSelect( 521 | # Color By 522 | label="Color by", 523 | v_model=("contour_color_array_idx", 0), 524 | items=("array_list", dataset_arrays), 525 | hide_details=True, 526 | dense=True, 527 | outlined=True, 528 | classes="pt-1", 529 | ) 530 | with vuetify.VCol(cols="6"): 531 | vuetify.VSelect( 532 | # Color Map 533 | label="Colormap", 534 | v_model=("contour_color_preset", LookupTable.Rainbow), 535 | items=( 536 | "colormaps", 537 | [ 538 | {"text": "Rainbow", "value": 0}, 539 | {"text": "Inv Rainbow", "value": 1}, 540 | {"text": "Greyscale", "value": 2}, 541 | {"text": "Inv Greyscale", "value": 3}, 542 | ], 543 | ), 544 | hide_details=True, 545 | dense=True, 546 | outlined=True, 547 | classes="pt-1", 548 | ) 549 | vuetify.VSlider( 550 | # Opacity 551 | v_model=("contour_opacity", 1.0), 552 | min=0, 553 | max=1, 554 | step=0.1, 555 | label="Opacity", 556 | classes="mt-1", 557 | hide_details=True, 558 | dense=True, 559 | ) 560 | 561 | 562 | # ----------------------------------------------------------------------------- 563 | # GUI 564 | # ----------------------------------------------------------------------------- 565 | 566 | with SinglePageWithDrawerLayout(server) as layout: 567 | layout.title.set_text("Viewer") 568 | 569 | with layout.toolbar: 570 | # toolbar components 571 | vuetify.VSpacer() 572 | vuetify.VDivider(vertical=True, classes="mx-2") 573 | standard_buttons() 574 | 575 | with layout.drawer as drawer: 576 | # drawer components 577 | drawer.width = 325 578 | pipeline_widget() 579 | vuetify.VDivider(classes="mb-2") 580 | mesh_card() 581 | contour_card() 582 | 583 | with layout.content: 584 | # content components 585 | with vuetify.VContainer( 586 | fluid=True, 587 | classes="pa-0 fill-height", 588 | ): 589 | # view = vtk.VtkRemoteView(renderWindow, interactive_ratio=1) 590 | # view = vtk.VtkLocalView(renderWindow) 591 | view = vtk.VtkRemoteLocalView( 592 | renderWindow, namespace="view", mode="local", interactive_ratio=1 593 | ) 594 | ctrl.view_update = view.update 595 | ctrl.view_reset_camera = view.reset_camera 596 | 597 | # ----------------------------------------------------------------------------- 598 | # Main 599 | # ----------------------------------------------------------------------------- 600 | 601 | if __name__ == "__main__": 602 | server.start() 603 | -------------------------------------------------------------------------------- /05_paraview/SimpleCone.py: -------------------------------------------------------------------------------- 1 | import paraview.web.venv # Available in PV 5.10 2 | 3 | from trame.app import get_server 4 | from trame.widgets import vuetify, paraview 5 | from trame.ui.vuetify import SinglePageLayout 6 | 7 | from paraview import simple 8 | 9 | # ----------------------------------------------------------------------------- 10 | # trame setup 11 | # ----------------------------------------------------------------------------- 12 | 13 | server = get_server(client_type = "vue2") 14 | state, ctrl = server.state, server.controller 15 | 16 | # ----------------------------------------------------------------------------- 17 | # ParaView code 18 | # ----------------------------------------------------------------------------- 19 | 20 | DEFAULT_RESOLUTION = 6 21 | 22 | cone = simple.Cone() 23 | representation = simple.Show(cone) 24 | view = simple.Render() 25 | 26 | 27 | @state.change("resolution") 28 | def update_cone(resolution, **kwargs): 29 | cone.Resolution = resolution 30 | ctrl.view_update() 31 | 32 | 33 | def update_reset_resolution(): 34 | state.resolution = DEFAULT_RESOLUTION 35 | 36 | 37 | # ----------------------------------------------------------------------------- 38 | # GUI 39 | # ----------------------------------------------------------------------------- 40 | 41 | state.trame__title = "ParaView cone" 42 | 43 | with SinglePageLayout(server) as layout: 44 | layout.icon.click = ctrl.view_reset_camera 45 | layout.title.set_text("Cone Application") 46 | 47 | with layout.toolbar: 48 | vuetify.VSpacer() 49 | vuetify.VSlider( 50 | v_model=("resolution", DEFAULT_RESOLUTION), 51 | min=3, 52 | max=60, 53 | step=1, 54 | hide_details=True, 55 | dense=True, 56 | style="max-width: 300px", 57 | ) 58 | vuetify.VDivider(vertical=True, classes="mx-2") 59 | with vuetify.VBtn(icon=True, click=update_reset_resolution): 60 | vuetify.VIcon("mdi-undo-variant") 61 | 62 | with layout.content: 63 | with vuetify.VContainer( 64 | fluid=True, 65 | classes="pa-0 fill-height", 66 | ): 67 | html_view = paraview.VtkRemoteView(view) 68 | # html_view = paraview.VtkLocalView(view) 69 | ctrl.view_update = html_view.update 70 | ctrl.view_reset_camera = html_view.reset_camera 71 | 72 | # ----------------------------------------------------------------------------- 73 | # Main 74 | # ----------------------------------------------------------------------------- 75 | 76 | if __name__ == "__main__": 77 | server.start() 78 | -------------------------------------------------------------------------------- /05_paraview/StateLoader.py: -------------------------------------------------------------------------------- 1 | from paraview.web import venv # Available in PV 5.10-RC2+ 2 | from paraview import simple 3 | 4 | from pathlib import Path 5 | from trame.app import get_server 6 | from trame.widgets import vuetify, paraview, client 7 | from trame.ui.vuetify import SinglePageLayout 8 | 9 | # ----------------------------------------------------------------------------- 10 | # Trame setup 11 | # ----------------------------------------------------------------------------- 12 | 13 | server = get_server(client_type = "vue2") 14 | state, ctrl = server.state, server.controller 15 | 16 | # Preload paraview modules onto server 17 | paraview.initialize(server) 18 | 19 | # ----------------------------------------------------------------------------- 20 | # ParaView code 21 | # ----------------------------------------------------------------------------- 22 | 23 | 24 | def load_data(**kwargs): 25 | # CLI 26 | args, _ = server.cli.parse_known_args() 27 | 28 | full_path = str(Path(args.data).resolve().absolute()) 29 | working_directory = str(Path(args.data).parent.resolve().absolute()) 30 | 31 | # ParaView 32 | simple.LoadState( 33 | full_path, 34 | data_directory=working_directory, 35 | restrict_to_data_directory=True, 36 | ) 37 | view = simple.GetActiveView() 38 | view.MakeRenderWindowInteractor(True) 39 | simple.Render(view) 40 | 41 | # HTML 42 | with SinglePageLayout(server) as layout: 43 | layout.icon.click = ctrl.view_reset_camera 44 | layout.title.set_text("ParaView State Viewer") 45 | 46 | with layout.content: 47 | with vuetify.VContainer(fluid=True, classes="pa-0 fill-height"): 48 | html_view = paraview.VtkRemoteView(view) 49 | ctrl.view_reset_camera = html_view.reset_camera 50 | ctrl.view_update = html_view.update 51 | 52 | 53 | ctrl.on_server_ready.add(load_data) 54 | 55 | # ----------------------------------------------------------------------------- 56 | # GUI 57 | # ----------------------------------------------------------------------------- 58 | 59 | state.trame__title = "State Viewer" 60 | 61 | with SinglePageLayout(server) as layout: 62 | layout.icon.click = ctrl.view_reset_camera 63 | layout.title.set_text("ParaView State Viewer") 64 | 65 | with layout.content: 66 | with vuetify.VContainer(fluid=True, classes="pa-0 fill-height"): 67 | client.Loading("Loading state") 68 | 69 | 70 | # ----------------------------------------------------------------------------- 71 | # Main 72 | # ----------------------------------------------------------------------------- 73 | 74 | if __name__ == "__main__": 75 | server.cli.add_argument("--data", help="Path to state file", dest="data") 76 | server.start() 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tutorial material for trame v2 2 | 3 | trame - a web framework that weaves together open source components into customized visual analytics easily. 4 | 5 | Please use the links below to find more informations: 6 | - [Tutorial](https://kitware.github.io/trame/guide/tutorial/) 7 | - [trame website](https://kitware.github.io/trame/) 8 | -------------------------------------------------------------------------------- /course/introduction/Introduction_to_trame.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kitware/trame-tutorial/688114ad8b375b83bf53efcea4e6eb62b1357bc0/course/introduction/Introduction_to_trame.pdf -------------------------------------------------------------------------------- /course/introduction/README.md: -------------------------------------------------------------------------------- 1 | # Introductory course 2 | 3 | We have a 2h introduction course on trame that let you dive into its core and how you can leverage trame for your own workflow. 4 | 5 | - [Video recording](https://vimeo.com/761096621/af2287747f) 6 | - [Slides](./Introduction_to_trame.pdf) 7 | - [Exercises / code samples](./exercises.zip) 8 | - [Short reference to keep](./trame_intro_ref.pdf) 9 | -------------------------------------------------------------------------------- /course/introduction/exercises.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kitware/trame-tutorial/688114ad8b375b83bf53efcea4e6eb62b1357bc0/course/introduction/exercises.zip -------------------------------------------------------------------------------- /course/introduction/trame_intro_ref.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kitware/trame-tutorial/688114ad8b375b83bf53efcea4e6eb62b1357bc0/course/introduction/trame_intro_ref.pdf -------------------------------------------------------------------------------- /data/carotid.vtk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kitware/trame-tutorial/688114ad8b375b83bf53efcea4e6eb62b1357bc0/data/carotid.vtk -------------------------------------------------------------------------------- /data/disk_out_ref.vtu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kitware/trame-tutorial/688114ad8b375b83bf53efcea4e6eb62b1357bc0/data/disk_out_ref.vtu -------------------------------------------------------------------------------- /data/ironProt.vtk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kitware/trame-tutorial/688114ad8b375b83bf53efcea4e6eb62b1357bc0/data/ironProt.vtk -------------------------------------------------------------------------------- /presentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kitware/trame-tutorial/688114ad8b375b83bf53efcea4e6eb62b1357bc0/presentation.pdf --------------------------------------------------------------------------------