Skip to content

feat: Implement 'find path' tool for spatially indexed skeleton - #221

Open
afonsobspinto wants to merge 13 commits into
feature/edit-modefrom
feature/find-path
Open

feat: Implement 'find path' tool for spatially indexed skeleton#221
afonsobspinto wants to merge 13 commits into
feature/edit-modefrom
feature/find-path

Conversation

@afonsobspinto

@afonsobspinto afonsobspinto commented Aug 12, 2026

Copy link
Copy Markdown
Member

Closes https://metacell.atlassian.net/browse/NGLANCERSU-12

  • Adds a datasource-owned Find Path tool for spatially indexed skeletons.

  • The tool lets users select two exact nodes in a visible skeleton and renders the shortest route between them as a white annotation polyline. It is intended primarily as a debugging aid for locating erroneous connections in merged neurons.

The interaction follows Graphene's Find Path tool where applicable:

  1. Activate Find Path from the Skeleton tab.
  2. Control-left-click the source node.
  3. Control-left-click the target node. Shift may also be held.
  4. Press Enter or click Submit.
  5. Use Clear or delete an endpoint annotation to reset the selection.

Unlike Graphene, path calculation is performed locally using the complete skeleton topology already cached in the client.

Architecture overview

The implemented data flow is:

source[].state.findPath
        │
        ▼
SkeletonDataSourceState.findPathState
        │
        ├── source + target ──────────────────────┐
        │                                         │
        └── SpatialSkeletonFindPathAnnotationController
                └── endpoint points + route polyline
                                                  ▲
SegmentationUserLayer.spatialSkeletonState        │
        └── layer-wide full-skeleton cache        │
                └── segment nodes ──► navigation graph
                                          │
                                          ▼
                                  deterministic BFS
                                          │
                                          ▼
                                 findPathState.result

User-facing behavior

  • Accepts exact skeleton nodes only; edge-only picks are rejected.
  • Requires both endpoints to be:
    • Distinct nodes.
    • In the same skeleton segment.
    • In a currently visible skeleton.
  • Ignores a third pick until an endpoint is deleted or the state is cleared.
  • Uses Submit or Enter to resolve the route.
  • Uses Clear to remove both endpoints and the route.
  • Renders:
    • A white source point.
    • A white target point.
    • A white source-to-target polyline.

@afonsobspinto
afonsobspinto marked this pull request as ready for review September 3, 2026 23:26
@seankmartin

seankmartin commented Sep 4, 2026

Copy link
Copy Markdown

Thanks for the PR! A few comments from trying it (will look at the code after):

  1. I think it feels a bit odd that in the edit tool select is via regular click and here you need control click, I'd suggest we use regular click here as well. This does raise the increased need for us to extract middle mouse to move and control left click to move as regular controls against main to avoid maintaining those in each tool we create.
  2. Given that this is a frontend only operation, I think we can (unlike graphene) remove the submit button and just auto-compute every time we have a valid source and target.
  3. It's very hard to see the path and selected nodes. Maybe the shader needs to be influenced by the skeleton rendering settings or much bigger by default, or offset a little bit? If we can't get this right then maybe we do need to influence the skeleton rendering instead, but right now I still lean trying a bit more with annotations unless you think otherwise
  4. Don't feel strongly, genuinely wondering. Would it be better to just make the skeleton visible on a find path attempt instead of blocking and saying the skeleton needs to be visible?
  5. Could we include the node type in the source/target info? Would be helpful to know if it is root to leaf for e.g. - maybe even more useful than the coords if we're tight on space
  6. The skeleton details tab appears to fill if the skeleton details are cached, not just if the skeleton is visible. Should we do the same here? It's a bit confusing to see the full skeleton details but not be able to find a path

Comment thread src/skeleton/find_path.spec.ts Outdated
Comment thread src/skeleton/find_path.ts
Comment thread src/layer/segmentation/index.spec.ts Outdated
Comment thread src/layer/segmentation/index.spec.ts Outdated
Comment thread src/skeleton/find_path.spec.ts Outdated
Comment thread src/ui/skeleton_edit_tools.ts Outdated
Comment thread src/ui/skeleton_edit_tools.ts Outdated
StatusMessage.showTemporaryMessage(message);
return;
}
const segmentId = Number(source.segmentId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm aware we need to make the fix to uint64, but is it broken here if supported uint64. In other words I'm wondering is this just another aspect we need to fix later, or if it is possible to make this new part mostly uint64 ready now so it is less work later

@afonsobspinto afonsobspinto Sep 4, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm not sure if you are expecting any changes here. Find Path state is already mostly uint64-ready: node and segment IDs are stored as bigInt, serialized as decimal strings, and restored with parseUint64.
But because the spatially indexed skeletons interfaces are not, yet, we need to convert the bigInts back to number here.
Once the broader spatial skeleton uint64 migration is complete, these conversions here can be removed.

@afonsobspinto

Copy link
Copy Markdown
Member Author

Thanks for the PR! A few comments from trying it (will look at the code after):

  1. I think it feels a bit odd that in the edit tool select is via regular click and here you need control click, I'd suggest we use regular click here as well. This does raise the increased need for us to extract middle mouse to move and control left click to move as regular controls against main to avoid maintaining those in each tool we create.
  2. Given that this is a frontend only operation, I think we can (unlike graphene) remove the submit button and just auto-compute every time we have a valid source and target.
  3. It's very hard to see the path and selected nodes. Maybe the shader needs to be influenced by the skeleton rendering settings or much bigger by default, or offset a little bit? If we can't get this right then maybe we do need to influence the skeleton rendering instead, but right now I still lean trying a bit more with annotations unless you think otherwise
  4. Don't feel strongly, genuinely wondering. Would it be better to just make the skeleton visible on a find path attempt instead of blocking and saying the skeleton needs to be visible?
  5. Could we include the node type in the source/target info? Would be helpful to know if it is root to leaf for e.g. - maybe even more useful than the coords if we're tight on space
  6. The skeleton details tab appears to fill if the skeleton details are cached, not just if the skeleton is visible. Should we do the same here? It's a bit confusing to see the full skeleton details but not be able to find a path
  1. Implemented. Both accepting left click and the refactoring out of the common skeleton tool navigation.
  2. Implemented.
  3. I implemented disabling depth testing in the 3-D view (and disabling picking so the overlay cannot intercept skeleton-node selections). I tried larger custom line and marker sizes as well as dynamic contrasting colors but none were really successful. I didn't try offsetting the route from the skeleton because I'm not sure that's the best way to handle it but it's something that I can do if you would prefer that to the current solution.
  4. I understand but I personally would rather not introduce the automatic turning the skeletons visible unless we feel strongly about doing it.
  5. Implemented.
  6. Implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants