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

Improve segment proofreading in 3D viewport #7742

Merged
merged 79 commits into from
May 2, 2024

Conversation

philippotto
Copy link
Member

@philippotto philippotto commented Apr 9, 2024

  • allows to activate segment via mesh in 3D viewport
  • highlights supervoxels on hover
  • allows merging/splitting in 3d viewport by interacting with the agglomerates / supervoxels

URL of deployed dev instance (used for testing):

  • https://___.webknossos.xyz

Steps to test:

  • create new annotation
  • select a hdf5 mapping
  • select proofreading tool and load some meshes
  • try to split and merge them in the 3D viewport

TODOs:

  • backend:
    • as an alternative to positions, also accept unmappedSegmentIds for split/merge related operations
    • implement API that maps from segmentId to a segmentPosition
  • frontend
    • integrate the above ino the context menu in the 3D viewport
    • don't show the proofreading cross in the data viewports if the user activated a supervoxel in the 3D viewport
    • bugs
      • loading the same mesh twice breaks the hovering effect for unknown reasons
      • after proofread operation, selected super voxel is not highlighted anymore (but stored as active)
      • when creating a new annotation, a new active segment id is chosen. when switching to proofreading, one can try to merge with that segment id. however, it doesn't exist anywhere.
      • [ ] selecting one partner in the 3D viewport and the other in a data viewport (or vice versa) doesn't work the user is told so now. hopefully can be improved with Load Oversegmentation Meshes during Proofreading #6569

Issues:


(Please delete unneeded items, merge only when none are left open)

@philippotto philippotto self-assigned this Apr 9, 2024
@philippotto
Copy link
Member Author

@fm3 When you have some time, it would be great if you could make the splitAgglomerate and mergeAgglomerate compatible with passing the unmapped segment ids. The same basically for the /agglomerateGraphMinCut and /getNeighborsForAgglomerateNode route 🙏

@fm3
Copy link
Member

fm3 commented Apr 15, 2024

@philippotto I’ve done that now, please give it a try! The new params are called segmentId1, segmentId2, segmentId

I assume that the frontend now always has the segment ids, right? Applying the update actions is backwards compatible, but do I need to build the same for the mincut/neighbors routes?

@philippotto
Copy link
Member Author

philippotto commented Apr 15, 2024

@philippotto I’ve done that now, please give it a try! The new params are called segmentId1, segmentId2, segmentId

Awesome, thanks, I'll give it a try.

I assume that the frontend now always has the segment ids, right?

We don't have the "magic mapping", yet, but for the typical split/merge proofreading operations we already have the (unmapped) segment ids, yes.

Applying the update actions is backwards compatible, but do I need to build the same for the mincut/neighbors routes?

For the mincut/neighbors route in non-3d-viewport, we don't have the unmapped id yet, but we can do another request to get these (like we do it for split/merge). These round trips will then be eliminated with the magic mapping soon.

@fm3
Copy link
Member

fm3 commented Apr 15, 2024

For the mincut/neighbors route in non-3d-viewport, we don't have the unmapped id yet, but we can do another request to get these (like we do it for split/merge). These round trips will then be eliminated with the magic mapping soon.

Right, I wasn’t sure about that. If it’s complicated to do these roundtrips, I can also make the routes accept both variants

@philippotto
Copy link
Member Author

@MichaelBuessemeyer Thank you for your thorough testing and feedback 👍 I incorporated most of your feedback, fixed the hiccups you noticed and did some performance optimizations. Please have another look and feel free to test again :)

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.

Thanks for incorporating the feedback 🙏

Unfortunately, I'm not sure how to do this well. As an example, the store has a property for the active cell id (should be renamed to active segment id but this is another issue ^^). If there is a mapping, this refers to the mapped id, which could also be called agglomerate id. However, if there is no mapping, "agglomerateId" is highly misleading..

Hmm, similar to the other thread above, I'm not sure how to do this well. I wouldn't want to use unmappedSegmentMesh, because (a) it's a confusing term for the frequent case where no mappings exist in the first place and (b) when a mapping exists, the back-end maps the individual mesh chunks to the requested id and then returns these chunks. So, they are mapped in a sense. I'm not very happy about it, either, but I'm having trouble to see how to it can be improved easily..

I can see your valid points :/. It make more sense to keep it the way it is 👍

During testing I encountered the following unexpected behaviours:

  • When I select the Split from all neighboring segments action, I get a A precomputed mesh could not be loaded for this segment. More information was printed to the browser's console. warning toast. All segments and buckets are reloaded as expected but this warning toast should not occur imo.

  • Moreover, during testing I came up with another potential useful feature: When I hover a segment in the data viewports the (mapped) segment id is displayed in the footer bar. But if I hover a supervoxel its mapped segment is not displayed in the footer bar. Would it be possible to add this / create a new issue for this?
    In particular I needed this use case to check whether two meshes belong to the same segment or not. This was pretty difficult as their color was nearly identical (while one of the was hovered). To check this, I needed to find the segment in the data viewport and hover them there. Imo supporting 3d viewports here as well would help out a lot in this case :)

Thanks all I could find 🎉

Btw: Thanks for getting rid of unnecessary rerendering of components once the flycam changed 🚀

docs/keyboard_shortcuts.md Show resolved Hide resolved
@philippotto
Copy link
Member Author

When I select the Split from all neighboring segments action, I get a A precomputed mesh could not be loaded for this segment. More information was printed to the browser's console. warning toast. All segments and buckets are reloaded as expected but this warning toast should not occur imo.

Can you reproduce this reliably? If so, could you share the steps for reproduction? :)

@MichaelBuessemeyer
Copy link
Contributor

Can you reproduce this reliably? If so, could you share the steps for reproduction? :)

Oh sorry, for me this behaviour occurred every time I used "Split from all neighboring segments" thus I thought that no explicit steps are needed.

I used the following steps:

@philippotto
Copy link
Member Author

Thanks for the repro steps 🙏 Indeed, it happens quite frequently on the dev instance for me, too.

@fm3 The error is coming from the back-end (the front-end might still be at fault for sending weird inputs) and I'm not sure whether I interpet it correctly.

The frontend uses the /meshes/chunks route and sends a payload à la:

{
  "meshFile": "meshfile_4-4-2",
  "segmentId": 7571522
}

Error:

[
  {
    "error": "Failed to load chunk list for segment {0} from mesh file “{1}”"
  },
  {
    "chain": "[Server Time 2024-05-02 08:04]  <~ zero chunks"
  }
]

The string interpolation doesn't seem to work, but I guess the backend simply cannot find chunks for id 7571522. Probably because that supervoxel doesn't exist in the editable mapping, anymore?

@philippotto
Copy link
Member Author

When I select the Split from all neighboring segments action, I get a A precomputed mesh could not be loaded for this segment. More information was printed to the browser's console. warning toast. All segments and buckets are reloaded as expected but this warning toast should not occur imo.

As discussed here, this issue is unrelated to this PR and even occurs in view-only mode. I created this issue for the problem.

@MichaelBuessemeyer It would be great if you could have a final look at my latest commits. I'd love to merge the PR today unless someone vetoes :)

@MichaelBuessemeyer MichaelBuessemeyer self-requested a review May 2, 2024 12:02
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.

Thanks for investigating the bug I found 🙏 as well as making it possible to deselect a super voxel via ctrl + click.

During checking your changes I found a little bug in them:

You redefined the tracing-mesh_listing_failed message in messages.tsx to a function but did not adjust the case where this message is used. Please see my indicating in line comments.
I was able to confirm the bug in the dev instance -> the displayed toast is empty:
image

That's all 🎉.

After this little fix, this PR is ready to go 🏃

frontend/javascripts/messages.tsx Show resolved Hide resolved
frontend/javascripts/oxalis/model/sagas/mesh_saga.ts Outdated Show resolved Hide resolved
@philippotto
Copy link
Member Author

During checking your changes I found a little bug in them:

Argh, you are right. TypeScript should have caught this, too, but didn't 😢 Maybe because a function can be a react component and the toast is able to render this. Still... I fixed it now!

@philippotto philippotto enabled auto-merge (squash) May 2, 2024 12:42
@philippotto philippotto merged commit 6ee06fb into master May 2, 2024
2 checks passed
@philippotto philippotto deleted the better-mesh-context-menu branch May 2, 2024 12:57
dieknolle3333 pushed a commit that referenced this pull request May 8, 2024
* allow to activate segment via mesh in 3D viewport

* annotate chunk infos with unmappedSegmentId

* don't merge mesh chunks and highlight them individually on hover

* refactor triggering the context menu by moving data into the store and avoiding passing around lambda

* rename context info vars since they are scoped now anyway

* dont pass all props to generic context menu container

* store active unmapped segment id in store

* prepare context menu actions

* clean up typing

* rename segmentationId to segmentId

* only avoid merging mesh chunks when in proofreading mode

* fix changing colors of merged or unmerged mesh chunks

* clean up

* adapt editable mapping actions to use segment ids

* small fix in DEV_INSTALL.md

* use new id based split/merge REST interface for proofreading

* implement split/merge/cut-from-neighbors for 3D viewport (mesh reloading is disabled for now, though)

* nvm in DEV_INSTALL.md

* add verbose type definition to avoid inconvenient property extraction and spread

* add agglomerateIdForSegmentId route for editable mappings

* WIP: segment to position route

* agglomerate_to_segments_offsets

* reactivate mesh reloading for split/merge/mincut and fix bug in cut-from-all-neighbors

* change opacity for whole agglomerate when hovering supervoxel

* reloading mesh in 3D viewport will not merge chunks when in proofreading mode; the user is also told what to do when trying to proofread with merged mesh chunks

* simplify mergeChunks logic when reloading mesh by always considering isProofreadingActive

* fix linting

* Revert "WIP: segment to position route"

This reverts commit 9aa64b8.

* when proofread-clicking a segment; don't reload mesh if it already exists; however, do reload if its chunks were merged before

* fix unhighlighting supervoxel in 3D viewport when activating another mesh in a data viewport

* misc clean up

* don't show proofreading cross in data viewports when a supervoxel is highlighted in the 3D viewport

* fix type error

* allow deselecting active super voxel in 3d viewport

* add route to query segment position from agglomerate file

* integrate new positionForSegment route to fix incorrect segment positions after splitting an agglomerate

* fix that initial mesh in proofreading mode wasn't always using available mesh file

* use → instead of -> in context menu label

* don't expose the term super-voxel in view mode; switch from activate to select

* fix merge error

* don't expose supervoxel id in context menu

* fix incorrectly placed } after resolving merge conflicts 🤦

* move code into segment mesh controller and ensure selected super voxel stays highlighted after proofread operation

* tell user to either use 3d viewport OR data viewports for proofreading operation

* check that active segment is registered to avoid merging/splitting from an unused segment id (which is the default when creating a new annotation)

* update changelog

* improve typing

* misc code improvements

* incorporate PR feedback

* don't depend on flycam prop in CameraController

* fix that SegmentsView.render() was called on each position and mouse move

* allow to select supervoxel/mesh in 3D viewport with ctrl + click

* update docs

* disable split option when rightclicking the active supervoxel

* fix hovering across chunks when proofreading tool is not active

* trigger loading of draco loader before downloading actual mesh chunks

* when splitting off all neighbors of a super-voxel, keep the id of that super-voxel instead of one random other partner

This fixes a problem where selecting a super-voxel and then splitting
off all neighbors wouldn't recognize the active super-voxel afterwards
in the 3D viewport. The highlighting still worked because the unmapped
id doesn't change, but the (mapped) segment id changed which led to
problems.

* throttle addMeshFromGeometries

* guard against selecting super voxel in 3D and then merging/splitting with a partner selected in data viewport

* also show hovered segment id in status bar when hovering in 3D viewport

* use debounce instead of throttle for updating user settings and increase timeout to 2500ms to avoid frequent network requests (e.g., when holding down CTRL)

* show proper shortcut infos in the status bar when proofreading in 3D viewport

* also allow to deselect a super-voxel by ctrl+clicking again

* add debug logging

* disable most ci checks

* improve error message when mesh chunks could not be loaded

* remove debug logging

* Revert "disable most ci checks"

This reverts commit cfa13a4.

* move potential explanation for mesh failure to console instead of toast

* fix missing invocation

---------

Co-authored-by: Florian M <florian@scm.io>
Co-authored-by: MichaelBuessemeyer <39529669+MichaelBuessemeyer@users.noreply.github.com>
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.

None yet

4 participants