New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-rendering is broken when ImageData remains the same but child changes #27
Comments
I was able to resolve it by explicitly assigning an id to Show full code
import dash_vtk
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
def build_vtk_representation(field, _id):
return dash_vtk.VolumeRepresentation(
id=_id,
children=[
dash_vtk.VolumeController(),
dash_vtk.ImageData(
dimensions=[10, 10, 10],
spacing=[1, 1, 1],
origin=[0, 0, 0],
children=dash_vtk.PointData(
dash_vtk.DataArray(registration="setScalars", values=field)
),
),
]
)
views = [
build_vtk_representation([np.random.random() for i in range(10 * 10 * 10)], _id="bar"),
build_vtk_representation(np.linspace(0, 1, num=10 * 10 * 10), _id="foo"),
dash_vtk.GeometryRepresentation(
[
dash_vtk.Algorithm(
vtkClass="vtkConeSource", state={"resolution": 64, "capping": False,},
)
]
),
]
app = dash.Dash(__name__)
server = app.server
app.layout = html.Div(
style={"width": "100%", "height": "calc(90vh - 16px)"},
children=[
dcc.RadioItems(
id="radio-items",
options=[
{"value": i, "label": x}
for i, x in enumerate(["random", "progressive", "cone"])
],
value=0,
),
html.Br(),
dash_vtk.View(id="vtk-view"),
html.Div(id="output"),
],
)
@app.callback(
Output("vtk-view", "children"),
Output("vtk-view", "triggerRender"),
Input("radio-items", "value"),
)
def update_vtk_view(value):
if value is None:
return dash.no_update
return views[value], np.random.random()
if __name__ == "__main__":
app.run_server(debug=True) Snippet: def build_vtk_representation(field, _id):
return dash_vtk.VolumeRepresentation(
id=_id,
children=[
dash_vtk.VolumeController(),
dash_vtk.ImageData(
dimensions=[10, 10, 10],
spacing=[1, 1, 1],
origin=[0, 0, 0],
children=dash_vtk.PointData(
dash_vtk.DataArray(registration="setScalars", values=field)
),
),
]
) |
Are you sure it is a rendering issue? When you rotate the camera, do you see the correct image?
If that is not the problem, it might be related to the way react (or dash) update the underneath structure. I might not detect the array swap and may need to trigger a |
Also make sure you look at the console in case any error arise that could give us a clue. |
Do you mean pan/zoom? After panning or zooming the view still hasn't correctly updated. |
Great, that means it is not a rendering issue... |
Thx for the console output. But in our case it does not help. We don't see any relevant issue related to the problem at hand. |
I think it's worth investigating. I'm currently building an app where I'd dynamically change the image data and it makes it rather difficult. Even with the work around, the moment I try to make it more complex I get errors like this: Show error
|
An example of what I mean above: if you wrap the ImageData with "ShareDataset", the demo will immediately break: See full code
import dash_vtk
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
def build_vtk_representation(field, _id):
return dash_vtk.VolumeRepresentation(
id=_id,
children=[
dash_vtk.VolumeController(),
dash_vtk.ShareDataSet(
dash_vtk.ImageData(
dimensions=[10, 10, 10],
spacing=[1, 1, 1],
origin=[0, 0, 0],
children=dash_vtk.PointData(
dash_vtk.DataArray(registration="setScalars", values=field)
),
),
)
]
)
views = [
build_vtk_representation([np.random.random() for i in range(10 * 10 * 10)], _id="bar"),
build_vtk_representation(np.linspace(0, 1, num=10 * 10 * 10), _id="foo"),
dash_vtk.GeometryRepresentation(
[
dash_vtk.Algorithm(
vtkClass="vtkConeSource", state={"resolution": 64, "capping": False,},
)
]
),
]
app = dash.Dash(__name__)
server = app.server
app.layout = html.Div(
style={"width": "100%", "height": "calc(90vh - 16px)"},
children=[
dcc.RadioItems(
id="radio-items",
options=[
{"value": i, "label": x}
for i, x in enumerate(["random", "progressive", "cone"])
],
value=0,
),
html.Br(),
dash_vtk.View(id="vtk-view"),
html.Div(id="output"),
],
)
@app.callback(
Output("vtk-view", "children"),
Output("vtk-view", "triggerRender"),
Input("radio-items", "value"),
)
def update_vtk_view(value):
if value is None:
return dash.no_update
return views[value], np.random.random()
if __name__ == "__main__":
app.run_server(debug=True) def build_vtk_representation(field, _id):
return dash_vtk.VolumeRepresentation(
id=_id,
children=[
dash_vtk.VolumeController(),
dash_vtk.ShareDataSet(
dash_vtk.ImageData(
dimensions=[10, 10, 10],
spacing=[1, 1, 1],
origin=[0, 0, 0],
children=dash_vtk.PointData(
dash_vtk.DataArray(registration="setScalars", values=field)
),
),
)
]
) |
Should be fixed in the latest master (updated dependency => npm i)
|
@jourdain seems like it's now possible to alternate between two image data of the same representation, but we can't change the representation back-and-forth anymore. See full code
import dash_vtk
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
def build_vtk_representation(field):
return dash_vtk.VolumeRepresentation(
children=[
dash_vtk.VolumeController(),
dash_vtk.ShareDataSet(
dash_vtk.ImageData(
dimensions=[10, 10, 10],
spacing=[1, 1, 1],
origin=[0, 0, 0],
children=dash_vtk.PointData(
dash_vtk.DataArray(registration="setScalars", values=field)
),
),
)
]
)
views = [
build_vtk_representation([np.random.random() for i in range(10 * 10 * 10)]),
build_vtk_representation(np.linspace(0, 1, num=10 * 10 * 10)),
dash_vtk.GeometryRepresentation(
[
dash_vtk.Algorithm(
vtkClass="vtkConeSource", state={"resolution": 64, "capping": False,},
)
]
),
]
app = dash.Dash(__name__)
server = app.server
app.layout = html.Div(
style={"width": "100%", "height": "calc(90vh - 16px)"},
children=[
dcc.RadioItems(
id="radio-items",
options=[
{"value": i, "label": x}
for i, x in enumerate(["random", "progressive", "cone"])
],
value=0,
),
html.Br(),
dash_vtk.View(id="vtk-view"),
html.Div(id="output"),
],
)
@app.callback(
Output("vtk-view", "children"),
Output("vtk-view", "triggerRender"),
Input("radio-items", "value"),
)
def update_vtk_view(value):
if value is None:
return dash.no_update
return views[value], np.random.random()
if __name__ == "__main__":
app.run_server(debug=True) |
So seems like it works when I remove the sharedataset wrapper: See full code
import dash_vtk
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
def build_vtk_representation(field):
return dash_vtk.VolumeRepresentation(
children=[
dash_vtk.VolumeController(),
dash_vtk.ImageData(
dimensions=[10, 10, 10],
spacing=[1, 1, 1],
origin=[0, 0, 0],
children=dash_vtk.PointData(
dash_vtk.DataArray(registration="setScalars", values=field)
),
),
]
)
views = [
build_vtk_representation([np.random.random() for i in range(10 * 10 * 10)]),
build_vtk_representation(np.linspace(0, 1, num=10 * 10 * 10)),
dash_vtk.GeometryRepresentation(
[
dash_vtk.Algorithm(
vtkClass="vtkConeSource", state={"resolution": 64, "capping": False,},
)
]
),
]
app = dash.Dash(__name__)
server = app.server
app.layout = html.Div(
style={"width": "100%", "height": "calc(90vh - 16px)"},
children=[
dcc.RadioItems(
id="radio-items",
options=[
{"value": i, "label": x}
for i, x in enumerate(["random", "progressive", "cone"])
],
value=0,
),
html.Br(),
dash_vtk.View(id="vtk-view"),
html.Div(id="output"),
],
)
@app.callback(
Output("vtk-view", "children"),
Output("vtk-view", "triggerRender"),
Input("radio-items", "value"),
)
def update_vtk_view(value):
if value is None:
return dash.no_update
return views[value], np.random.random()
if __name__ == "__main__":
app.run_server(debug=True) |
Thanks I'm going to look at the ShareDataSet part... |
So I've created a test with the ShareDataSet and seems that things works as expected as long as you don't change the representation. (Like you said) But by design the ShareDataSet capture its children at mount time and it only register itself once with a given name... If the name of those ShareDataSet were different, it may actually work. I'm still playing with different options but I wanted to share that now since I'm looking at it |
I'm waiting an update of vtk.js to go even further. But once available, I might be able to get things working... |
Thanks for the update. I'm still experimenting around to see how to best approach this. |
There is a new The representation swap is still not working but the data swap is (even with the share dataset). In general, I'm not sure what is the idea of the rep swap. |
Actually I managed to do it and pushed it to master
|
Thanks! |
Bug
I built a set of radio buttons to alternate between different representations (volumes and algorithms). This is done through a callback. When the data (i.e.
ImageData
) remains the same, but the childPointData
changes, dash-vtk will not correctly re-render the new view.Here's a demo:
Notice how going
random -> progressive
doesn't work, butrandom -> cone
orcone -> progressive
works. This is because cone uses aAlgorithm
instead ofImageData
, so it would trigger a rerender.Code
Show full code
Here's a snippet:
The text was updated successfully, but these errors were encountered: