It’s possible to create callbacks based on user clicks and hovering. First, you need to specify the pickingModes
prop in
vtk_view
to be a list of modes you want to capture. The following values are accepted:
* "click"
* "hover"
Afterwards, you need to create callbacks where the inputs and states include one of the following read-only properties of vtk_view
.
* clickInfo
: Called when the user clicks on an object.
* hoverInfo
: Called when the user hovers over an object.
The full documentation for
vtk_view
can be found in the API reference.
You can notice that the clickInfo
or hoverInfo
data will be a dictionary with various keys describing the picked object. The keys include:
* displayPosition
: The x,y,z coordinate with on the user’s screen.
* ray
: A line between two points in 3D space (xyz1, xyz2) that represent the mouse position. It covers the full space under the 2D mouse position.
* representationId
: The ID assigned to the vtk_geometryrepresentation
containing your object.
* worldPosition
: The x, y, z coordinates in the 3D environment that you are rendering where the ray hit the object. It corresponds to the 3D coordinate on the surface of the object under your mouse.
clickInfo
to html_pre
The following example shows you how to concisely display the output of clickInfo
inside an html_pre
:
View full code
using JSON3, DashVtk, DashHtmlComponents, Dash
filepath = download("https://github.com/plotly/dash-vtk/blob/master/demos/data/cow-nonormals.obj");
txt_content = read(filepath, String);
view = vtk_view(
id="click-info-view",
pickingModes=["click"],
children=[
vtk_geometryrepresentation(id="cow-geometry", children=[
vtk_reader(
vtkClass="vtkOBJReader",
parseAsText=txt_content,
),
]),
],
);
# Dash setup
app = dash()
app.layout = html_div([
html_div(view, style=Dict("width" => "100%", "height" => "300px")),
html_b("Output of clickInfo (try clicking on the object above):"),
html_pre(
id="click-info-output",
style=Dict("overflowX" => "scroll")
)
]);
# Dash setup
app = dash()
callback!(
app,
Output("click-info-output", "children"),
Input("click-info-view", "clickInfo")
) do click_info
return JSON3(click_info, indent=2)
end
run_server(app, "0.0.0.0", debug = true)
hoverInfo
You can also construct more complex hover callbacks, which would affect the actor
and state
of your geometry representations.
In the terrain mesh demo, whenever you hover
over the surface, a callback is fired and the output is displayed on your screen:
The full code can be found here, but the
following snippet summarizes what is needed to capture hover events in the image above:
# ...
vtk_view = vtk_view(
id="vtk-view",
pickingModes=["hover"],
children=[
vtk_geometryrepresentation(id="vtk-representation", ...),
vtk_geometryrepresentation(
id="pick-rep",
children=[
dash_vtk.Algorithm(id="pick-sphere", ...)
],
# ...
),
],
)
app.layout = html_div([
# ...,
vtk_view,
# ...
])
callback!(
app,
Output("tooltip", "children"),
Output("pick-sphere", "state"),
Output("pick-rep", "actor"),
Input("vtk-view", "clickInfo"), Input("vtk-view", "hoverInfo"),
) do (clickData, hoverData)
info = hoverData ? hoverData : clickData
if info
if (
"representationId" in info &&
info["representationId"] == "vtk-representation"
)
return (
[JSON3.write(info, indent=2)],
Dict("center" => info["worldPosition"]),
Dict("visibility" => true),
)
end
return no_update, no_update, no_update
end
return [""], Dict(), Dict("visibility" => false)
end
You can also use hoverInfo
to update the state of another geometry representation. The image below shows how to update a cone position, orientation and size in order to probe the race car object:
Learn more by reading the Python source code or trying out the Vehicle Geometry app