-
Notifications
You must be signed in to change notification settings - Fork 298
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
feat: add referenceCursors tool #275
Conversation
…orSync is displayed regardless of distance, create configurable distance and also sync the position of all viewports over which the mouse is not to scroll to a slice that is close to the currentMousePosition in 3d space
…on imageChange events, added configuration for max display distance
✅ Deploy Preview for cornerstone-3d-docs ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
…toolGroup gets destroyed, might cause remaining listeners
@doepnern Hey I will go ahead and review this now |
I am not completely sure if I'm happy with how this works right now. Maybe it would be easier to not use the annotation tool at all as this doesnt use any of the features where having the worldPosition of the annotation is useful and the easiest way to render the crosshair would be to just have the current enabled element where the mouse is over and the canvas position and then just calculate the world position for every viewport on render. |
And in the current version there would need to be a cleanup of the listeners with a setMouseOverElement(null), I am not quite sure where to put it as onSetToolDisabled ist not always called (for example not if the toolGroup is destroyed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I did my first pass to understand what is going on and basically put my questions also, I have other comments as well, but I prefer to get your opinions/answers for my questions before giving you the full review.
PS: I first thought, we can avoid adding an annotation to the state, since basically it does not serve as any purpose, but then our rendering loop handles each element separately so I think right now it is fine, if we just addAnnotation
Again, great job, and welcome
Okay, so I hopefully applied most of the changes you suggested. Thanks a lot for the extensive feedback. The reason I was working with imageChange events: This leads to the cursor being stale until the next mouseMove is triggered. Also this will prevent the stacks to sync during scrolling for the same reason. The only way I found around adding the event listeners now is:
There after some longer debugging I noticed that calling triggerAnnotationRerender during an annotationRender will cause the whole tool to break (even when excluding the currently rendering viewport). For that reason, I had to wrap the call into a setTimeout. Feel kind of "hacky" but I just don't see a completely easy way to do this. You can test the whole problem by commenting out the block in the renderAnnotation checking for the stackChange. When using StackScrollWheel the cursor won't be synced and the stack states won't be synced until a mouseMove is triggered. About the cursor being rendered in all viewports: |
Thanks for all the suggestions. |
}, | ||
}; | ||
|
||
const annotationId = this._addAnnotation(element, annotation); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check which is basically checking annotation manager if there is one exists can be done very first thing at the top of this method and avoid all the object and logics up here
Thanks for the updates, this is good to go except I tried it and for the active viewport (the one with mouse) I see two cursors for some reason. Does this happen on your machine too? Update: I think I know what is going on, the active tool is set to be Pan, so there is Pan SVG Cursor, but also we decided to show the cursor for the active viewport too, so I guess you need to hide the cursor when the tool is set to active as a call back Update2: Basically your tool and some other tools only should have two states: Active and Disabled. Enabled, and Passive does not have meaning here. Previously we had mixins for this, that redirected setToolPassive to setToolDisabled (https://github.com/cornerstonejs/cornerstoneTools/blob/master/src/mixins/activeOrDisabledBinaryTool.js) let me see what I can do 8a3d4587-7a93-4b6d-a04b-8a57d10330cb.webm |
Another comment after thinking, your tool has active state, meaning that one should activate it, so I expect the demo makes |
…sor to default if there is no primary mouse cursor
I actually like the option of still having the cursor of another tool. In actual usage this tool would mostly be used while still having a tool active, so I dont like hiding the primary tool that much. I changed the look of the tool in the element with the cursor to hopefully not conflict with another tool and added a configuration to disable the other tools cursor. I was having a lot of issues with curors being replaced depending on the order in which tools are enabled. Would it maybe be useful to only change the cursor to the default one if there is no active primary cursor(I added a check for that in the ToolGroup). Feel free to remove that if you dont feel like this is wanted. |
preventHandleOutsideImage: false, | ||
displayThreshold: 5, | ||
positionSync: true, | ||
disableCursor: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default for disableCursor to be false hmmm, going back to the discussion on the cursors for this tool, I don't understand why one needs to have the pan cursor on and also the cursor for this tool at the same time. It is kind of not in harmony with the rest of the library in which the active tool on the mouse primary claims the cursor and not other tools. Can we set this tool to behave the same way by default? that it overwrite its cursor by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore this comment
} | ||
) { | ||
super(toolProps, defaultToolProps); | ||
this._disableCursorEnabled = this.configuration.disableCursor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might cause a bug when configuration changes, since you are only assigning it on the construtor, maybe always use this.configuration.disableCursor
?
const isInBounds = true; | ||
if (isInBounds) { | ||
viewport.setCamera({ focalPoint: newFocalPoint }); | ||
const renderingeEngine = viewport.getRenderingEngine(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there, see my comments
-
Is there any usecase for having positionSync off? I feel like user wants it always on, and if it is off, it will cause confusion when other viewports not showing the same image
-
The demo doesn't work when switching between disable cursor on and off (probably related to my comment for the constructor)
-
There is a one pixel offset between the pan cursor and your tool cursor, do you think that is easy to fix?
@sedghi
This will also be a problem if 2 tools want to call hideElementCursor So one would need to be sure to always clean up hideElemetCursor by calling resetElementCursor. As there is no onToolConfigurationChange Event the easiest way I found to do that was to set the internal _disableCursorEnabled every time the tool is activated and call the cleanup when the tool is disabled depending on that state. If you want to change the setting you have to deactivate and activate the tool once.
|
Yeah the cursor API is probably the worst API in the whole repo, and I tried to fix it couple of times but initial implementation does not makes sense at all (and not my fault :D) I think this is good to go Thanks again! and looking forward to your next contribution! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work
* fix: mouse-up should not unhighlight annotations (#305) * fix: annotation highlighted and tooling for ellipticalROI * update build * fix tests * chore(release): publish [skip ci] - docs@0.7.8 - @cornerstonejs/tools@0.29.7 * fix: stack viewport flip scroll (#304) * fix: use focal point for pan cache for stack viewport * fix: pan dir with flip * fix pan values while flipped * update build * apply review comments * fix build * chore(release): publish [skip ci] - @cornerstonejs/core@0.21.5 - docs@0.7.9 - @cornerstonejs/streaming-image-volume-loader@0.6.6 - @cornerstonejs/tools@0.29.8 * feat: add referenceCursors tool (#275) * added basic cursorCrosshairSync tool with example, TODO: for now cursorSync is displayed regardless of distance, create configurable distance and also sync the position of all viewports over which the mouse is not to scroll to a slice that is close to the currentMousePosition in 3d space * addde stack syncing for StackViewport and syncing for volumeViewport on imageChange events, added configuration for max display distance * refactored tool functions * added comment to possible bug * added configuration options to example * changed look of crosshair to 4 lines with central space * undid local tsconfig change * undid yarn.lock changes * added tool to example-info.json * removed from example-runner because it broke build * readded example and fixed typo * readded example-info and changed example to trigger rebuild * added cleanup for mouseoverElement when tool is disabled * added cleanup when tool gets disabled, this does not get called when toolGroup gets destroyed, might cause remaining listeners * applied naming changes, reworked adding annotation logic * removed event listeners and moved logic to check for stack scrolling into rendering logic * added planeDistanceToPoint to planar utilities * added getClosestStackImageIndexForPoint * rewrote logic to use onCameraModified * updated example-info * fixed bug with 0 being falsey * added logic to remove cursor if wanted * modified toolGroup so that setting a tool active only changes the cursor to default if there is no primary mouse cursor * fixed bug not updating disable cursor * fixed missing parentheses from merge * readded scrollWheel scrolling and api changes * fixed typos * chore(release): publish [skip ci] - @cornerstonejs/core@0.22.0 - docs@0.7.10 - @cornerstonejs/streaming-image-volume-loader@0.6.7 - @cornerstonejs/tools@0.30.0 * fix: ZoomTool fix for polyData actors with no imageData (#308) * chore(release): publish [skip ci] - docs@0.7.11 - @cornerstonejs/tools@0.30.1 * fix: If planar annotation is not visible, filter it (#318) Co-authored-by: edward65 <edward@afxmedical.com> * fix: filter planarFreeHandeROI based on parallel normals instead of equal normals. (#315) Co-authored-by: Ramon Emiliani <ramon@afxmedical.com> * fix: get correct imageData with targetId in BaseTool (#294) * limit disabled element not need to render * Update BaseTool.ts fix: get correct viewport when there are multiple viewport with same stack data Co-authored-by: chendingmiao <cdm@tomtaw.com.cn> * chore(release): publish [skip ci] - docs@0.7.12 - @cornerstonejs/tools@0.30.2 * fix: htj2k and keymodifier (#313) * fix(htj2k):Support htj2k in the streaming volume loader * fix(decodeImage):Fix htj2k image decode and mouse key modifiers * Update for PR * update ci build * chore(release): publish [skip ci] - docs@0.7.13 - @cornerstonejs/streaming-image-volume-loader@0.6.8 - @cornerstonejs/tools@0.30.3 * fix: coronal view should not be flipped (#321) * chore(release): publish [skip ci] - @cornerstonejs/core@0.22.1 - docs@0.7.14 - @cornerstonejs/streaming-image-volume-loader@0.6.9 - @cornerstonejs/tools@0.30.4 * fix: bidirectional tool when short and long axis changes (#309) * fix rotation for handles * fix: short axis movement * fix: bidirectional tool incorrect interaction * chore(release): publish [skip ci] - @cornerstonejs/core@0.22.2 - docs@0.7.15 - @cornerstonejs/streaming-image-volume-loader@0.6.10 - @cornerstonejs/tools@0.30.5 * fix(volumeViewport): Add optional scaling as the volume can be undefined (#323) While trying to get the volume from the cache, it can be undefined so getting the scaling attribute would throw an error in that case. This is a quick fix * chore(release): publish [skip ci] - @cornerstonejs/core@0.22.3 - docs@0.7.16 - @cornerstonejs/streaming-image-volume-loader@0.6.11 - @cornerstonejs/tools@0.30.6 * fix: Use queryselector instead of firstChild to get svg-layer (#268) * chore(release): publish [skip ci] - docs@0.7.17 - @cornerstonejs/tools@0.30.7 * [wip] initial dicom-loader typescript conversion * [wip] initial typescript conversion * [wip] update types for tests Co-authored-by: Alireza <ar.sedghi@gmail.com> Co-authored-by: ohif-bot <contact@ohif.org> Co-authored-by: Niclas do <32524613+doepnern@users.noreply.github.com> Co-authored-by: Neil <neil.a.macphee@gmail.com> Co-authored-by: Edward Son <edward_son@live.com> Co-authored-by: edward65 <edward@afxmedical.com> Co-authored-by: ramonemiliani93 <ramon.emiliani@umontreal.ca> Co-authored-by: Ramon Emiliani <ramon@afxmedical.com> Co-authored-by: 陈定苗 <359650098@qq.com> Co-authored-by: chendingmiao <cdm@tomtaw.com.cn> Co-authored-by: Bill Wallace <wayfarer3130@gmail.com> Co-authored-by: Gabriel Lebaudy <gabriel.lebaudy@gmail.com> Co-authored-by: Mustafa ÇİNİ <mcini@hotmail.com.tr> Co-authored-by: James Manners <james@binary.com.au>
* fix: mouse-up should not unhighlight annotations (#305) * fix: annotation highlighted and tooling for ellipticalROI * update build * fix tests * chore(release): publish [skip ci] - docs@0.7.8 - @cornerstonejs/tools@0.29.7 * fix: stack viewport flip scroll (#304) * fix: use focal point for pan cache for stack viewport * fix: pan dir with flip * fix pan values while flipped * update build * apply review comments * fix build * chore(release): publish [skip ci] - @cornerstonejs/core@0.21.5 - docs@0.7.9 - @cornerstonejs/streaming-image-volume-loader@0.6.6 - @cornerstonejs/tools@0.29.8 * feat: add referenceCursors tool (#275) * added basic cursorCrosshairSync tool with example, TODO: for now cursorSync is displayed regardless of distance, create configurable distance and also sync the position of all viewports over which the mouse is not to scroll to a slice that is close to the currentMousePosition in 3d space * addde stack syncing for StackViewport and syncing for volumeViewport on imageChange events, added configuration for max display distance * refactored tool functions * added comment to possible bug * added configuration options to example * changed look of crosshair to 4 lines with central space * undid local tsconfig change * undid yarn.lock changes * added tool to example-info.json * removed from example-runner because it broke build * readded example and fixed typo * readded example-info and changed example to trigger rebuild * added cleanup for mouseoverElement when tool is disabled * added cleanup when tool gets disabled, this does not get called when toolGroup gets destroyed, might cause remaining listeners * applied naming changes, reworked adding annotation logic * removed event listeners and moved logic to check for stack scrolling into rendering logic * added planeDistanceToPoint to planar utilities * added getClosestStackImageIndexForPoint * rewrote logic to use onCameraModified * updated example-info * fixed bug with 0 being falsey * added logic to remove cursor if wanted * modified toolGroup so that setting a tool active only changes the cursor to default if there is no primary mouse cursor * fixed bug not updating disable cursor * fixed missing parentheses from merge * readded scrollWheel scrolling and api changes * fixed typos * chore(release): publish [skip ci] - @cornerstonejs/core@0.22.0 - docs@0.7.10 - @cornerstonejs/streaming-image-volume-loader@0.6.7 - @cornerstonejs/tools@0.30.0 * fix: ZoomTool fix for polyData actors with no imageData (#308) * chore(release): publish [skip ci] - docs@0.7.11 - @cornerstonejs/tools@0.30.1 * fix: If planar annotation is not visible, filter it (#318) Co-authored-by: edward65 <edward@afxmedical.com> * fix: filter planarFreeHandeROI based on parallel normals instead of equal normals. (#315) Co-authored-by: Ramon Emiliani <ramon@afxmedical.com> * fix: get correct imageData with targetId in BaseTool (#294) * limit disabled element not need to render * Update BaseTool.ts fix: get correct viewport when there are multiple viewport with same stack data Co-authored-by: chendingmiao <cdm@tomtaw.com.cn> * chore(release): publish [skip ci] - docs@0.7.12 - @cornerstonejs/tools@0.30.2 * fix: htj2k and keymodifier (#313) * fix(htj2k):Support htj2k in the streaming volume loader * fix(decodeImage):Fix htj2k image decode and mouse key modifiers * Update for PR * update ci build * chore(release): publish [skip ci] - docs@0.7.13 - @cornerstonejs/streaming-image-volume-loader@0.6.8 - @cornerstonejs/tools@0.30.3 * fix: coronal view should not be flipped (#321) * chore(release): publish [skip ci] - @cornerstonejs/core@0.22.1 - docs@0.7.14 - @cornerstonejs/streaming-image-volume-loader@0.6.9 - @cornerstonejs/tools@0.30.4 * fix: bidirectional tool when short and long axis changes (#309) * fix rotation for handles * fix: short axis movement * fix: bidirectional tool incorrect interaction * chore(release): publish [skip ci] - @cornerstonejs/core@0.22.2 - docs@0.7.15 - @cornerstonejs/streaming-image-volume-loader@0.6.10 - @cornerstonejs/tools@0.30.5 * fix(volumeViewport): Add optional scaling as the volume can be undefined (#323) While trying to get the volume from the cache, it can be undefined so getting the scaling attribute would throw an error in that case. This is a quick fix * chore(release): publish [skip ci] - @cornerstonejs/core@0.22.3 - docs@0.7.16 - @cornerstonejs/streaming-image-volume-loader@0.6.11 - @cornerstonejs/tools@0.30.6 * fix: Use queryselector instead of firstChild to get svg-layer (#268) * chore(release): publish [skip ci] - docs@0.7.17 - @cornerstonejs/tools@0.30.7 * [wip] initial dicom-loader typescript conversion * [wip] initial typescript conversion * [wip] update types for tests * feat: enable having multiple instances of the same tool and add more seg tools (#327) * feat: add floodFill and advanced brushTool * feat: enable adding tool instances from a parent tool class * fix threshold and brush size * chore(release): publish [skip ci] - docs@0.7.18 - @cornerstonejs/tools@0.31.0 * feat: Add new 3D volume viewport (#281) * Extract common volume viewport functionality to base class * Add viewport presets * Add utility function for applying preset to volume actor * Add new 3D volume viewport * Add example for VolumeViewport3D * feat: add presets dropdown to demo * update example info json Co-authored-by: Luccas Correa <luccascorrea@estudio89.com.br> Co-authored-by: Alireza <ar.sedghi@gmail.com> * chore(release): publish [skip ci] - @cornerstonejs/core@0.23.0 - docs@0.7.19 - @cornerstonejs/streaming-image-volume-loader@0.6.12 - @cornerstonejs/tools@0.32.0 * fix: Add coplanar check in stackImageSync callback (#335) * Add coplanar check in stackImageSync callback * Refactoring function * chore(release): publish [skip ci] - docs@0.7.20 - @cornerstonejs/tools@0.32.1 * fix: could not access 'index' before initialization (#337) * Avoid circular dependancy with vite build * Nicer import * chore(release): publish [skip ci] - docs@0.7.21 - @cornerstonejs/tools@0.32.2 * [dicom-loader] update CornerstoneWadoLoaderOptions to include optional params * [dicom-image-loader] types update * [dicom-image-loader] port wadoImageLoader tests to monorepo * [dicom-image-loader] port changes from cornerstoneWADOImageLoader commit id 9d71753
…ttier. (#275) * chore: update eslint, prettier, modernize configs * chore: run prettier on whole codebase
Hey, I really love this repository and especially the improved API in the new version.
I created this tool for my personal use, its purpose is mostly to act like a linking of camera position and showing a reference to what your cursor is currently hovering over. It also helps a lot when you have multiple series which are not in the same Orientation, to have a feel for what you are looking at in different orientations. This is somewhat similar to the crosshair that exists, but it also works with Stack viewports, which I use it mostly for.
Would there be an interest in adding this tool, I would take the time to write tests as well if that is the case.
Thank you for your great library anyway!
Niclas
p.s. here is a small video
https://user-images.githubusercontent.com/32524613/199220760-a20ea8e2-9efb-4335-a763-0325ecba5f43.mp4