Skip to content
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

isosurfaces for volume tracings #4567

Merged
merged 34 commits into from
Sep 17, 2020
Merged

Conversation

youri-k
Copy link
Contributor

@youri-k youri-k commented Apr 24, 2020

This PR makes it possible to fetch isosurfaces from the backend in volume tracings. An isosurface can be loaded by using ctrl + leftMouse. This PR adds a button to the 3d viewport that makes it possible to reload the fetched isosurfaces whose annotation changed.

URL of deployed dev instance (used for testing):

  • https://___.webknossos.xyz

Steps to test:

  • Open a volume tracing and do some volume annotation.
  • Load the isosurface of your annotation by usning ctrl + leftMouse in one of the plane viewports. The isosurface should be loaded. Then change the annotation of that cell and use the reload button in the top right corner of the 3d viewport. The isosurface should be erased and the reloaded to the newest version.

Issues:


@youri-k youri-k self-assigned this Apr 30, 2020
@MichaelBuessemeyer
Copy link
Contributor

MichaelBuessemeyer commented Jul 29, 2020

Finally, I to the time to work on this issue. 😌

I added a button to the 3d viewport that is only visible if the isosurface feature is enabled. The isosurface saga now also tracks the cell ids of cells that got annotated between reloads. A reload will only reload the cells that got annotated.

Still existing problems:

  • Currently, the reload button can be always triggered. I'd like to disable the button when no cell with a loaded isosurface got modified. @philippotto Do you have an idea how to do this with little effort? -> thats fine
  • The loading of an isosurface stops at the border of a cube and so will the reloading. If the user loaded all isosurface segments of all cubes, the reloading will only reload the isosurface data of a single cube (as the request stops at the border of the cube)
    -> @philippotto What do you think about modifying the isosurface loading functionality to load isosurfaces across cubes?

@MichaelBuessemeyer
Copy link
Contributor

The loading of an isosurface stops at the border of a cube and so will the reloading. If the user loaded all isosurface segments of all cubes, the reloading will only reload the isosurface data of a single cube (as the request stops at the border of the cube)
-> @philippotto What do you think about modifying the isosurface loading functionality to load isosurfaces across cubes?

@philippotto just fixed it :D

@MichaelBuessemeyer
Copy link
Contributor

MichaelBuessemeyer commented Jul 30, 2020

@philippotto The frontend is ready to receive your awesome feedback 🎉

@philippotto
Copy link
Member

Very cool! What's the state in the back-end? Maybe you could update the PR description a bit, so that there is some explanation about the future and that current state is clear :)

@MichaelBuessemeyer
Copy link
Contributor

Very cool! What's the state in the back-end?

I think the backend is working but I am not sure whether the code is reviewed and cleaned up. @youri-k Do you know more about this?

@youri-k youri-k requested a review from fm3 August 9, 2020 14:18
@youri-k
Copy link
Contributor Author

youri-k commented Aug 9, 2020

I think the backend is good for review 🙂 @fm3 could you have a look?

@youri-k youri-k marked this pull request as ready for review August 9, 2020 14:19
@youri-k youri-k changed the title [WIP] isosurfaces for volume tracings isosurfaces for volume tracings Aug 9, 2020
@philippotto
Copy link
Member

Unfortunately, the CI doesn't pass, as the smoke test repeatedly fails. Is this related to the back-end changes?

@youri-k
Copy link
Contributor Author

youri-k commented Aug 11, 2020

Yes, this is a backend related problem. I'm working on it.

@philippotto
Copy link
Member

philippotto commented Aug 13, 2020

Really cool to see the isosurfaces for own annotations 👍 However, testing didn't went totally smooth for me. Here are my observations:

  • Initially, I had trouble to get the rendering to work at all. I think, I expected that the current cell ID for isosurface rendering was the same as the "brush ID". However, the two ids seem to be different? I know that the isosurface code also needs to work in "view"-mode where no brush id exists, but when being in a volume tracing this shouldn't be a problem? Either way, it's not really transparent right now which cell ID will be rendered. Maybe we should make this more visible somehow?
  • When only annotating one slice and then using the isosurface feature, nothing is rendered. I think this is because the rendering always considers blocks of X voxels and takes the median of these (is this correct, @youri-k?). So, right now this is expected behavior. However, this can be very confusing to the user.
    • Idea 1: When taking the mode of X voxels within a block, ignore cell id 0. I think this should always result in intuitive results. But maybe I'm missing something?
    • Idea 2: Communicate to the user why nothing shows up. However, I think this will be very hard to explain and also not intuitive. I hope idea 1 works
  • The reload button can be improved in multiple ways:
    • before requesting new isosurfaces, the front-end should save everything so that the rendered isosurfaces are up-to-date
    • as soon as the button is clicked, a spinner should be shown (also, it should be disabled). after the reload has been completed, the spinner should be hidden again obviously.
    • right now, the old isosurfaces are immediately removed. then, the request takes some time and the isosurfaces are rendered again. I suggest to only remove the isosurfaces shortly before the new ones are added.

Probably out of scope for this PR, but I'm starting to think that we should probably list all the isosurfaces explicitly in the "meshes" tab. Then, we could have functionality for reloading, removing etc. very transparently. Something like this:
image

Maybe it makes sense to combine this with a general segment tab, so that all segments are listed (and when you click it you jump to it). And if you want, you can activate the isosurface rendering for one particular cell. Also see #4667.

However, a first version of this feature could simply list the cells for which isosurfaces have been loaded (that should be rather easy to do).

What do you think?

Copy link
Contributor

@MichaelBuessemeyer MichaelBuessemeyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I applied your feedback for the frontend @philippotto. Could you please check the newest changes?

frontend/javascripts/oxalis/api/api_latest.js Outdated Show resolved Hide resolved
@philippotto
Copy link
Member

Cool stuff! I'll look through the code to give feedback in a bit, @MichaelBuessemeyer!

What's the status of volume (or hybrid) annotations with fallback segmentation? Since this will be the new default soon, there should also be isosurface support. However, I couldn't get it to work? It's probably also not trivial, since the back-end can only compute isosurfaces for volume tracings or for segmentation layers, but not for the overlay via fallbacks, right? @youri-k

We probably need to discuss this in person together with @youri-k, when he's back again.

Copy link
Member

@philippotto philippotto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! This already looks very good 🕺 Just left some mostly minor feedback :)

frontend/javascripts/oxalis/default_state.js Outdated Show resolved Hide resolved
frontend/javascripts/oxalis/view/td_view_controls.js Outdated Show resolved Hide resolved
frontend/javascripts/oxalis/api/api_latest.js Outdated Show resolved Hide resolved
frontend/javascripts/oxalis/model/sagas/isosurface_saga.js Outdated Show resolved Hide resolved
frontend/javascripts/oxalis/model/sagas/isosurface_saga.js Outdated Show resolved Hide resolved
frontend/javascripts/oxalis/model/sagas/isosurface_saga.js Outdated Show resolved Hide resolved
frontend/javascripts/oxalis/model/sagas/isosurface_saga.js Outdated Show resolved Hide resolved
let shouldBeRemoved = true;
for (const [, position] of isoSurfacePositions) {
// Reload the Isosurface.
yield* call(ensureSuitableIsosurface, null, position, cellId, shouldBeRemoved);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a comment which explains that no redundant work will be done, since the isosurface-loading-code always checks whether a request has already been performed. I myself just stumbled here a bit, since the code requests a new isosurface for each position in the three-d-map, even though ensureSuitableIsosurface will also traverse the 3D space. However, your approach is still very correct (since multiple seeds might still be necessary to reconstruct everything). I'd just add the comment so that the next reader does not stumble here :)

yield _takeEvery("TRIGGER_ISOSURFACE_DOWNLOAD", downloadActiveIsosurfaceCell);
yield _takeEvery("IMPORT_ISOSURFACE_FROM_STL", importIsosurfaceFromStl);
yield _takeEvery("REMOVE_ISOSURFACE", removeIsosurface);
yield _takeEvery("REFRESH_ISOSURFACES", refreshIsosurfaces);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the refresh button is clicked, I think it would also make sense to fetch the isosurfaces at the current position (as a seed) with the cell id at that position. That way, the button can also be used to render the very first isosurface without needing to know about shift+click.

@philippotto
Copy link
Member

What's the status of volume (or hybrid) annotations with fallback segmentation? Since this will be the new default soon, there should also be isosurface support. However, I couldn't get it to work? It's probably also not trivial, since the back-end can only compute isosurfaces for volume tracings or for segmentation layers, but not for the overlay via fallbacks, right? @youri-k

I had a discussion with Florian and Norman and we agreed for this version of the feature to simply follow this logic: if the current tracing uses a fallback segmentation layer, fetch the isosurfaces from the datastore (i.e, the traced data gets ignored completely) and if there's no fallback layer, use the tracingstore.
Consequently, the isosurfaces rendering will work well for the case of simply "opening a fresh tracing for a dataset with a segmentation layer". It will also work for "opening a new tracing for a dataset without a segmentation layer". And editing a volume tracing will only work well if there's no fallback, but since this hasn't been possible before at all, this seems like a fine trade-off for me.

@MichaelBuessemeyer Could you make sure that the logic explained above is implemented? Also see my other PR feedback :)

@philippotto
Copy link
Member

@fm3 Could you also review the back-end code in case you haven't done it already? :)

Copy link
Member

@fm3 fm3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backend mostly looks good to me, I added some small comments.
I like the holder structure :)

@MichaelBuessemeyer
Copy link
Contributor

@philippotto I thin I covered all your feedback

Copy link
Member

@philippotto philippotto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent 👍 Works well for me :)

Now, only the back-end's feedback needs to be integrated, I think.

@MichaelBuessemeyer
Copy link
Contributor

MichaelBuessemeyer commented Sep 8, 2020

@fm3 @youri-k ping

Copy link
Member

@fm3 fm3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had another look and merged the master. I’d say backend LGTM now! Let’s do a quick final round of testing after the CI is done, then this should be good to go. Edit: did some testing, seemed to work :) I agree with philippotto that progress/overview UI would be beneficial, though.

@fm3 fm3 added the automerge label Sep 17, 2020
@bulldozer-boy bulldozer-boy bot merged commit ae10f2d into master Sep 17, 2020
@bulldozer-boy bulldozer-boy bot deleted the isosurface-for-volume-tracing branch September 17, 2020 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Isosurface for volume annotations
4 participants