diff --git a/examples/reference/panes/VTK.ipynb b/examples/reference/panes/VTK.ipynb index 86c23b8b06..eb84459b2b 100644 --- a/examples/reference/panes/VTK.ipynb +++ b/examples/reference/panes/VTK.ipynb @@ -21,6 +21,14 @@ "For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n", "\n", "* **``camera``** (dict): A dictionary reflecting the current state of the VTK camera\n", + "* **``enable_keybindings``** (bool): A boolean to activate/deactivate binded keys. Binded keys are :\n", + " - s: set representation of all actors to *surface*\n", + " - w: set representation of all actors to *wireframe*\n", + " - v: set representation of all actors to *vertex*\n", + " - r: centers the actors and moves the camera so that all actors are visible\n", + "\n", + "**Warning**: These keys bind may not work as expected in a notebook context if they interact with already binded keys\n", + " \n", "* **``object``** (str or object): Can be a string pointing to a local or remote file with a `.vtkjs` extension, or a vtkRenderWindow object \n", "\n", "___" @@ -176,6 +184,8 @@ "cylinderActor = vtk.vtkActor()\n", "cylinderActor.SetMapper(cylinderMapper)\n", "cylinderActor.GetProperty().SetColor(tomato)\n", + "# We must set ScalarVisibilty to 0 to use tomato Color\n", + "cylinderMapper.SetScalarVisibility(0)\n", "cylinderActor.RotateX(30.0)\n", "cylinderActor.RotateY(-45.0)\n", "\n", @@ -215,6 +225,7 @@ "sphereActor = vtk.vtkActor()\n", "sphereActor.SetMapper(sphereMapper)\n", "sphereActor.GetProperty().SetColor(tomato)\n", + "sphereMapper.SetScalarVisibility(0)\n", "sphereActor.RotateX(30.0)\n", "sphereActor.RotateY(-45.0)\n", "sphereActor.SetPosition(0.5, 0.5, 0.5)\n", diff --git a/panel/models/vtk.py b/panel/models/vtk.py index fa8ce0e53e..62ceac8528 100644 --- a/panel/models/vtk.py +++ b/panel/models/vtk.py @@ -31,6 +31,8 @@ class VTKPlot(HTMLBox): camera = Dict(String, Any) + enable_keybindings = Bool(default=False) + height = Override(default=300) width = Override(default=300) diff --git a/panel/models/vtk.ts b/panel/models/vtk.ts index 93997e5b70..294c5a7a34 100644 --- a/panel/models/vtk.ts +++ b/panel/models/vtk.ts @@ -10,6 +10,7 @@ export class VTKPlotView extends HTMLBoxView { protected _rendererEl: any protected _renderer: any protected _camera: any + protected _interactor: any protected _setting: boolean = false initialize(): void { @@ -31,9 +32,11 @@ export class VTKPlotView extends HTMLBoxView { container: this._container }); this._renderer = this._rendererEl.getRenderer() + this._interactor = this._rendererEl.getInteractor() this._camera = this._renderer.getActiveCamera() this._plot() this._camera.onModified(() => this._get_camera_state()) + this._key_binding() } } @@ -41,6 +44,19 @@ export class VTKPlotView extends HTMLBoxView { super.connect_signals() this.connect(this.model.properties.data.change, () => this._plot()) this.connect(this.model.properties.camera.change, () => this._set_camera_state()) + this.connect(this.model.properties.enable_keybindings.change, () => this._key_binding()) + } + + _key_binding(): void { + if (this.model.enable_keybindings) { + document.querySelector('body')!.addEventListener('keypress',this._interactor.handleKeyPress) + document.querySelector('body')!.addEventListener('keydown',this._interactor.handleKeyDown) + document.querySelector('body')!.addEventListener('keyup',this._interactor.handleKeyUp) + } else { + document.querySelector('body')!.removeEventListener('keypress',this._interactor.handleKeyPress) + document.querySelector('body')!.removeEventListener('keydown',this._interactor.handleKeyDown) + document.querySelector('body')!.removeEventListener('keyup',this._interactor.handleKeyUp) + } } render() { @@ -110,6 +126,7 @@ export namespace VTKPlot { data: p.Property append: p.Property camera: p.Property + enable_keybindings: p.Property } } @@ -127,9 +144,10 @@ export class VTKPlot extends HTMLBox { this.prototype.default_view = VTKPlotView this.define({ - data: [ p.String ], - append: [ p.Boolean, false ], - camera: [ p.Any ] + data: [ p.String ], + append: [ p.Boolean, false ], + camera: [ p.Any ], + enable_keybindings: [ p.Boolean, false ] }) this.override({ diff --git a/panel/pane/vtk.py b/panel/pane/vtk.py index d9dccddca3..7602089da1 100644 --- a/panel/pane/vtk.py +++ b/panel/pane/vtk.py @@ -331,6 +331,13 @@ class VTK(PaneBase): camera = param.Dict(doc="""State of the rendered VTK camera.""") + enable_keybindings = param.Boolean(default=False, doc=""" + Activate/Deactivate keys binding. + + Warning: These keys bind may not work as expected in a notebook + context if they interact with already binded keys + """) + _updates = True @classmethod @@ -358,7 +365,7 @@ def _get_model(self, doc, root=None, parent=None, comm=None): model = VTKPlot(data=data, **props) if root is None: root = model - self._link_props(model, ['data', 'camera'], doc, root, comm) + self._link_props(model, ['data', 'camera', 'enable_keybindings'], doc, root, comm) self._models[root.ref['id']] = (model, parent) return model @@ -404,7 +411,7 @@ def _vtksjs_from_render_window(self, render_window): mapper = renProp.GetMapper() if mapper is None: continue - dataObject = mapper.GetInputDataObject(0, 0); + dataObject = mapper.GetInputDataObject(0, 0) dataset = None if dataObject.IsA('vtkCompositeDataSet'): @@ -422,7 +429,7 @@ def _vtksjs_from_render_window(self, render_window): dataset = gf.GetOutput() else: dataset = mapper.GetInput() - + if dataset and not isinstance(dataset, (vtk.vtkPolyData)): # All data must be PolyData surfaces! gf = vtk.vtkGeometryFilter() @@ -471,7 +478,7 @@ def _vtksjs_from_render_window(self, render_window): if dataArray: # component = -1 => let specific instance get scalar from vector before mapping - colorArray = lookupTable.MapScalars(dataArray, colorMode, -1); + colorArray = lookupTable.MapScalars(dataArray, colorMode, -1) colorArrayName = '__CustomRGBColorArray__' colorArray.SetName(colorArrayName) colorMode = 0 @@ -489,7 +496,7 @@ def _vtksjs_from_render_window(self, render_window): textureName = None if renProp.GetTexture() and renProp.GetTexture().GetInput(): textureData = renProp.GetTexture().GetInput() - textureName = 'texture_%d' % _get_object_id(textureData, objIds); + textureName = 'texture_%d' % _get_object_id(textureData, objIds) textureToSave[textureName] = textureData representation = renProp.GetProperty().GetRepresentation() if hasattr(renProp, 'GetProperty') else 2