feat(segmentation mode): Add create, and export SEG with Brushes (#3632)
This commit is contained in:
1 parent
896866e9d0
commit
48bbd6281a
186 files changed
+6801
-2883
No files matched your search
@@ -116,6 +116,26 @@ In the video below notice that there is `platform/viewer` which has been renamed
|
||||
<iframe src="https://player.vimeo.com/video/551957266?badge=0&autopause=0&player_id=0&app_id=58479" frameBorder="0" allow="autoplay; fullscreen; picture-in-picture" allowFullScreen style= {{ position:"absolute",top:0,left:0,width:"100%",height:"100%"}} title="measurement-report"></iframe>
|
||||
</div>
|
||||
|
||||
### Build for non-root path
|
||||
|
||||
If you would like to access the viewer from a non-root path (e.g., `/my-awesome-viewer` instead of `/`),
|
||||
You can achieve so by using the `PUBLIC_URL` environment variable AND the `routerBasename` configuration option.
|
||||
|
||||
1. use a config (e.g. config/myConfig.js) file that is using the `routerBasename` of your choice `/my-awesome-viewer` (note there is only one / - it is not /my-awesome-viewer/).
|
||||
2. build the viewer with `PUBLIC_URL=/my-awesome-viewer/ APP_CONFIG=config/myConfig.js yarn build` (note there are two / - it is not /my-awesome-viewer).
|
||||
|
||||
|
||||
:::tip
|
||||
The PUBLIC_URL tells the application where to find the static assets and the routerBasename will tell the application how to handle the routes
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Testing, you can use `npx http-server` to serve the files in the generated `dist` folder and access the viewer from `http://localhost:8080/my-awesome-viewer`. To achieve
|
||||
so, you should first rename the `dist` folder to `my-awesome-viewer` and then change the working directory
|
||||
to the `platform/app` folder and run `npx http-server ./`. Then on the browser, you can access the viewer from `http://localhost:8080/my-awesome-viewer`
|
||||
:::
|
||||
|
||||
|
||||
### Automating Builds and Deployments
|
||||
|
||||
If you found setting up your environment and running all of these steps to be a
|
||||
|
||||
@@ -28,7 +28,7 @@ It is also required that the PUBLIC_URL environment variable is set to the same
|
||||
`<iframe src="./ohif" />` (which means there is a `ohif` folder containing the build in your main app), then you need to:
|
||||
|
||||
1. use a config (e.g. config/myConfig.js) file that is using the `routerBasename` of `/ohif` (note the one / - it is not /ohif/).
|
||||
2. build the viewer with `PUBLIC_URL=./ohif/ APP_CONFIG=config/myConfig.js yarn build` (note the one / - it is not /ohif/).
|
||||
2. build the viewer with `PUBLIC_URL=/ohif/ APP_CONFIG=config/myConfig.js yarn build` (note the two / - it is not /ohif).
|
||||
|
||||
:::tip
|
||||
Check to make sure the `app-config.js` in the build is reflecting the correct routerBasename.
|
||||
|
||||
@@ -21,7 +21,7 @@ specific `SOPClassHandlerUID`, so if you want to fork just a single Viewport
|
||||
component for a specialized mode, this is possible.
|
||||
|
||||
```jsx
|
||||
// displaySet, viewportIndex, dataSource
|
||||
// displaySet, dataSource
|
||||
const getViewportModule = () => {
|
||||
const wrappedViewport = props => {
|
||||
return (
|
||||
|
||||
@@ -45,8 +45,8 @@ There are seven events that get publish in `MeasurementService`:
|
||||
|
||||
### Segment Behavior
|
||||
|
||||
- setSegmentLockedForSegmentation, removeSegment, addSegment, setSegmentLockedForSegmentation, setSegmentLabel, setActiveSegmentForSegmentation,
|
||||
setSegmentRGBAColorForSegmentation
|
||||
- setSegmentLocked, removeSegment, addSegment, setSegmentLocked, setSegmentLabel, setActiveSegment,
|
||||
setSegmentRGBAColor
|
||||
|
||||
### Segmentation Configuration
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ In the `value` of each customizations, you will define customization prototype(s
|
||||
These customization prototype(s) can be considered like "Prototype" in Javascript.
|
||||
These can be used to extend the customization definitions from configurations.
|
||||
Default customizations will be often used to define all the customization prototypes,
|
||||
Default customizations will be often used to define all the customization prototypes,
|
||||
as they will be loaded automatically along with the defining extension or mode.
|
||||
|
||||
|
||||
@@ -58,7 +59,6 @@ For example, the `@ohif/extension-default` extension defines,
|
||||
value: [
|
||||
{
|
||||
id: 'ohif.overlayItem',
|
||||
uiType: 'uiType',
|
||||
content: function (props) {
|
||||
if (this.condition && !this.condition(props)) return null;
|
||||
|
||||
@@ -92,8 +92,9 @@ For example, the `@ohif/extension-default` extension defines,
|
||||
],
|
||||
```
|
||||
|
||||
And this `ohif.overlayItem` object will be used as a prototype to define items
|
||||
to be displayed on `CustomizableViewportOverlay`. See the next section.
|
||||
And this `ohif.overlayItem` object will be used as a prototype (and template) to define items
|
||||
to be displayed on `CustomizableViewportOverlay`. See how we use the `ohif.overlayItem` in
|
||||
the example below.
|
||||
|
||||
## Configuring customizations
|
||||
|
||||
@@ -119,13 +120,16 @@ window.config = {
|
||||
customizationService: {
|
||||
cornerstoneOverlayTopRight: {
|
||||
id: 'cornerstoneOverlayTopRight',
|
||||
customizationType: 'ohif.cornerstoneOverlay',
|
||||
items: [
|
||||
{
|
||||
id: 'PatientNameOverlay',
|
||||
// Note the overlayItem as a parent type - this provides the
|
||||
// rendering functionality to read the attribute and use the label.
|
||||
// Note below that here we are using the customization prototype of
|
||||
// `ohif.overlayItem` which was registered to the customization module in
|
||||
// `ohif/extension-default` extension.
|
||||
customizationType: 'ohif.overlayItem',
|
||||
// the following props are passed to the `ohif.overlayItem` prototype
|
||||
// which is used to render the overlay item based on the label, color,
|
||||
// conditions, etc.
|
||||
attribute: 'PatientName',
|
||||
label: 'PN:',
|
||||
title: 'Patient Name',
|
||||
@@ -157,20 +161,19 @@ The `customizationType` field is simply the id of another customization object.
|
||||
### Mode Customizations
|
||||
|
||||
Mode-specific customizations are no different from the global ones,
|
||||
except that the mode customizations are cleared before the mode `onModeEnter`
|
||||
is called, and they can have new values registered in the `onModeEnter`
|
||||
except that the mode customizations are specific to one mode and
|
||||
are not globally applied. Mode-specific customizations are also cleared
|
||||
before the mode `onModeEnter` is called, and they can have new values registered in the `onModeEnter`
|
||||
|
||||
In the mode customization, the overlay is then further customized
|
||||
with a bottom-right overlay, which extends the customizationService configuration.
|
||||
Following on our example above to customize the overlay, we can now add a mode customization
|
||||
with a bottom-right overlay.
|
||||
|
||||
```js
|
||||
// Import the type from the extension itself
|
||||
import OverlayUICustomization from '@ohif/cornerstone-extension';
|
||||
|
||||
import OverlayUICustomization from "@ohif/cornerstone-extension";
|
||||
|
||||
// In the mode itself, customizations can be registered:
|
||||
onModeEnter() {
|
||||
...
|
||||
onModeEnter: {
|
||||
// Note how the object can be strongly typed
|
||||
const bottomRight: OverlayUICustomization = {
|
||||
id: 'cornerstoneOverlayBottomRight',
|
||||
@@ -182,6 +185,7 @@ onModeEnter() {
|
||||
],
|
||||
};
|
||||
customizationService.addModeCustomizations(bottomRight);
|
||||
}
|
||||
```
|
||||
|
||||
The mode customizations are retrieved via the `getModeCustomization` function,
|
||||
@@ -198,9 +202,17 @@ can then be used in a way defined by the extension provided that customization
|
||||
point.
|
||||
|
||||
```ts
|
||||
cornerstoneOverlay = uiConfigurationService.getModeCustomization("cornerstoneOverlay", {customizationType: "ohif.cornerstoneOverlay", ...});
|
||||
const { component: overlayComponent, props} = uiConfigurationService.getComponent(cornerstoneOverlay);
|
||||
return (<defaultComponent {...props} overlay={cornerstoneOverlay}....></defaultComponent>);
|
||||
const cornerstoneOverlay = customizationService.getModeCustomization(
|
||||
"cornerstoneOverlay",
|
||||
{ customizationType: "ohif.cornerstoneOverlay" },
|
||||
);
|
||||
|
||||
const { component: overlayComponent, props } =
|
||||
customizationService.getComponent(cornerstoneOverlay);
|
||||
|
||||
return (
|
||||
<defaultComponent {...props} overlay={cornerstoneOverlay}></defaultComponent>
|
||||
);
|
||||
```
|
||||
|
||||
This example shows fetching the default component to render this object. The
|
||||
@@ -210,8 +222,11 @@ example (this example comes from the context menu customizations as that one
|
||||
uses commands lists):
|
||||
|
||||
```ts
|
||||
cornerstoneContextMenu = uiConfigurationService.get("cornerstoneContextMenu", defaultMenu);
|
||||
commandsManager.run(cornerstoneContextMenu, extraProps);
|
||||
cornerstoneContextMenu = customizationService.get(
|
||||
"cornerstoneContextMenu",
|
||||
defaultMenu,
|
||||
);
|
||||
commandsManager.run(cornerstoneContextMenu, extraProps);
|
||||
```
|
||||
|
||||
### Global Customizations
|
||||
@@ -339,7 +354,6 @@ window.config = {
|
||||
customizationService: {
|
||||
cornerstoneOverlayTopLeft: {
|
||||
id: 'cornerstoneOverlayTopLeft',
|
||||
customizationType: 'ohif.cornerstoneOverlay',
|
||||
items: [
|
||||
{
|
||||
id: 'WindowLevel',
|
||||
@@ -398,7 +412,6 @@ window.config = {
|
||||
},
|
||||
cornerstoneOverlayTopRight: {
|
||||
id: 'cornerstoneOverlayTopRight',
|
||||
customizationType: 'ohif.cornerstoneOverlay',
|
||||
|
||||
items: [
|
||||
{
|
||||
@@ -438,7 +451,6 @@ window.config = {
|
||||
},
|
||||
cornerstoneOverlayBottomLeft: {
|
||||
id: 'cornerstoneOverlayBottomLeft',
|
||||
customizationType: 'ohif.cornerstoneOverlay',
|
||||
|
||||
items: [
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ is expected to support, [check out it's interface in `@ohif/core`][interface]
|
||||
| `reset()` | Resets the default states |
|
||||
| `getNumViewportPanes()` | Gets the number of visible viewport panes |
|
||||
| `getLayoutOptionsFromState(gridState)` | Utility method that produces a `ViewportLayoutOptions` based on the passed in state|
|
||||
| `getActiveViewportId()` | Returns the viewport Id of the active viewport in the grid|
|
||||
|
||||
## Implementations
|
||||
|
||||
|
||||
Reference in new issue
Block a user