feat(tmtv-mode): Add Brush tools and move SUV peak calculation to web worker (#4053)
This commit is contained in:
1 parent
8c5ab942b9
commit
8192e348ec
27 files changed
+593
-212
No files matched your search
@@ -99,7 +99,10 @@ function modeFactory({ modeConfiguration }) {
|
||||
'Pan',
|
||||
'SyncToggle',
|
||||
]);
|
||||
toolbarService.createButtonSection('ROIThresholdToolbox', ['RectangleROIStartEndThreshold']);
|
||||
toolbarService.createButtonSection('ROIThresholdToolbox', [
|
||||
'RectangleROIStartEndThreshold',
|
||||
'BrushTools',
|
||||
]);
|
||||
|
||||
customizationService.addModeCustomizations([
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@ export const toolGroupIds = {
|
||||
Fusion: 'fusionToolGroup',
|
||||
MIP: 'mipToolGroup',
|
||||
default: 'default',
|
||||
// MPR: 'mpr',
|
||||
};
|
||||
|
||||
function _initToolGroups(toolNames, Enums, toolGroupService, commandsManager, modeLabelConfig) {
|
||||
@@ -59,6 +58,67 @@ function _initToolGroups(toolNames, Enums, toolGroupService, commandsManager, mo
|
||||
{ toolName: toolNames.Angle },
|
||||
{ toolName: toolNames.CobbAngle },
|
||||
{ toolName: toolNames.Magnify },
|
||||
{
|
||||
toolName: 'CircularBrush',
|
||||
parentTool: 'Brush',
|
||||
configuration: {
|
||||
activeStrategy: 'FILL_INSIDE_CIRCLE',
|
||||
},
|
||||
},
|
||||
{
|
||||
toolName: 'CircularEraser',
|
||||
parentTool: 'Brush',
|
||||
configuration: {
|
||||
activeStrategy: 'ERASE_INSIDE_CIRCLE',
|
||||
},
|
||||
},
|
||||
{
|
||||
toolName: 'SphereBrush',
|
||||
parentTool: 'Brush',
|
||||
configuration: {
|
||||
activeStrategy: 'FILL_INSIDE_SPHERE',
|
||||
},
|
||||
},
|
||||
{
|
||||
toolName: 'SphereEraser',
|
||||
parentTool: 'Brush',
|
||||
configuration: {
|
||||
activeStrategy: 'ERASE_INSIDE_SPHERE',
|
||||
},
|
||||
},
|
||||
{
|
||||
toolName: 'ThresholdCircularBrush',
|
||||
parentTool: 'Brush',
|
||||
configuration: {
|
||||
activeStrategy: 'THRESHOLD_INSIDE_CIRCLE',
|
||||
},
|
||||
},
|
||||
{
|
||||
toolName: 'ThresholdSphereBrush',
|
||||
parentTool: 'Brush',
|
||||
configuration: {
|
||||
activeStrategy: 'THRESHOLD_INSIDE_SPHERE',
|
||||
},
|
||||
},
|
||||
{
|
||||
toolName: 'ThresholdCircularBrushDynamic',
|
||||
parentTool: 'Brush',
|
||||
configuration: {
|
||||
activeStrategy: 'THRESHOLD_INSIDE_CIRCLE',
|
||||
// preview: {
|
||||
// enabled: true,
|
||||
// },
|
||||
strategySpecificConfiguration: {
|
||||
// to use the use the center segment index to determine
|
||||
// if inside -> same segment, if outside -> eraser
|
||||
// useCenterSegmentIndex: true,
|
||||
THRESHOLD: {
|
||||
isDynamic: true,
|
||||
dynamicRadius: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
enabled: [{ toolName: toolNames.SegmentationDisplay }],
|
||||
disabled: [
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { defaults, ToolbarService } from '@ohif/core';
|
||||
import { ToolbarService } from '@ohif/core';
|
||||
import { toolGroupIds } from './initToolGroups';
|
||||
|
||||
const { windowLevelPresets } = defaults;
|
||||
|
||||
const setToolActiveToolbar = {
|
||||
commandName: 'setToolActiveToolbar',
|
||||
commandOptions: {
|
||||
@@ -10,6 +8,18 @@ const setToolActiveToolbar = {
|
||||
},
|
||||
};
|
||||
|
||||
function _createSetToolActiveCommands(toolName) {
|
||||
return [
|
||||
{
|
||||
commandName: 'setToolActiveToolbar',
|
||||
commandOptions: {
|
||||
toolName,
|
||||
toolGroupIds: [toolGroupIds.CT, toolGroupIds.PT, toolGroupIds.Fusion],
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const toolbarButtons = [
|
||||
{
|
||||
id: 'MeasurementTools',
|
||||
@@ -107,13 +117,183 @@ const toolbarButtons = [
|
||||
icon: 'tool-create-threshold',
|
||||
label: 'Rectangle ROI Threshold',
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: {
|
||||
name: 'evaluate.cornerstoneTool',
|
||||
disabledText: 'Select the PT Axial to enable this tool',
|
||||
},
|
||||
evaluate: [
|
||||
'evaluate.cornerstone.segmentation',
|
||||
// need to put the disabled text last, since each evaluator will
|
||||
// merge the result text into the final result
|
||||
{
|
||||
name: 'evaluate.cornerstoneTool',
|
||||
disabledText: 'Select the PT Axial to enable this tool',
|
||||
},
|
||||
],
|
||||
options: 'tmtv.RectangleROIThresholdOptions',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'BrushTools',
|
||||
uiType: 'ohif.buttonGroup',
|
||||
props: {
|
||||
groupId: 'BrushTools',
|
||||
items: [
|
||||
{
|
||||
id: 'Brush',
|
||||
icon: 'icon-tool-brush',
|
||||
label: 'Brush',
|
||||
evaluate: {
|
||||
name: 'evaluate.cornerstone.segmentation',
|
||||
toolNames: ['CircularBrush', 'SphereBrush'],
|
||||
disabledText: 'Create new segmentation to enable this tool.',
|
||||
},
|
||||
commands: _createSetToolActiveCommands('CircularBrush'),
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
id: 'brush-radius',
|
||||
type: 'range',
|
||||
min: 0.5,
|
||||
max: 99.5,
|
||||
step: 0.5,
|
||||
value: 25,
|
||||
commands: {
|
||||
commandName: 'setBrushSize',
|
||||
commandOptions: { toolNames: ['CircularBrush', 'SphereBrush'] },
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
type: 'radio',
|
||||
id: 'brush-mode',
|
||||
value: 'CircularBrush',
|
||||
values: [
|
||||
{ value: 'CircularBrush', label: 'Circle' },
|
||||
{ value: 'SphereBrush', label: 'Sphere' },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'Eraser',
|
||||
icon: 'icon-tool-eraser',
|
||||
label: 'Eraser',
|
||||
evaluate: {
|
||||
name: 'evaluate.cornerstone.segmentation',
|
||||
toolNames: ['CircularEraser', 'SphereEraser'],
|
||||
},
|
||||
commands: _createSetToolActiveCommands('CircularEraser'),
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
id: 'eraser-radius',
|
||||
type: 'range',
|
||||
min: 0.5,
|
||||
max: 99.5,
|
||||
step: 0.5,
|
||||
value: 25,
|
||||
commands: {
|
||||
commandName: 'setBrushSize',
|
||||
commandOptions: { toolNames: ['CircularEraser', 'SphereEraser'] },
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
type: 'radio',
|
||||
id: 'eraser-mode',
|
||||
value: 'CircularEraser',
|
||||
values: [
|
||||
{ value: 'CircularEraser', label: 'Circle' },
|
||||
{ value: 'SphereEraser', label: 'Sphere' },
|
||||
],
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'Threshold',
|
||||
icon: 'icon-tool-threshold',
|
||||
label: 'Threshold Tool',
|
||||
evaluate: {
|
||||
name: 'evaluate.cornerstone.segmentation',
|
||||
toolNames: ['ThresholdCircularBrush', 'ThresholdSphereBrush'],
|
||||
},
|
||||
commands: _createSetToolActiveCommands('ThresholdCircularBrush'),
|
||||
options: [
|
||||
{
|
||||
name: 'Radius (mm)',
|
||||
id: 'threshold-radius',
|
||||
type: 'range',
|
||||
min: 0.5,
|
||||
max: 99.5,
|
||||
step: 0.5,
|
||||
value: 25,
|
||||
commands: {
|
||||
commandName: 'setBrushSize',
|
||||
commandOptions: {
|
||||
toolNames: [
|
||||
'ThresholdCircularBrush',
|
||||
'ThresholdSphereBrush',
|
||||
'ThresholdCircularBrushDynamic',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Threshold',
|
||||
type: 'radio',
|
||||
id: 'dynamic-mode',
|
||||
value: 'ThresholdRange',
|
||||
values: [
|
||||
{ value: 'ThresholdDynamic', label: 'Dynamic' },
|
||||
{ value: 'ThresholdRange', label: 'Range' },
|
||||
],
|
||||
commands: ({ value, commandsManager }) => {
|
||||
if (value === 'ThresholdDynamic') {
|
||||
commandsManager.run('setToolActive', {
|
||||
toolName: 'ThresholdCircularBrushDynamic',
|
||||
});
|
||||
} else {
|
||||
commandsManager.run('setToolActive', {
|
||||
toolName: 'ThresholdCircularBrush',
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Shape',
|
||||
type: 'radio',
|
||||
id: 'eraser-mode',
|
||||
value: 'ThresholdCircularBrush',
|
||||
values: [
|
||||
{ value: 'ThresholdCircularBrush', label: 'Circle' },
|
||||
{ value: 'ThresholdSphereBrush', label: 'Sphere' },
|
||||
],
|
||||
condition: ({ options }) =>
|
||||
options.find(option => option.id === 'dynamic-mode').value === 'ThresholdRange',
|
||||
commands: 'setToolActiveToolbar',
|
||||
},
|
||||
{
|
||||
name: 'ThresholdRange',
|
||||
type: 'double-range',
|
||||
id: 'threshold-range',
|
||||
min: 0,
|
||||
max: 50,
|
||||
step: 0.5,
|
||||
values: [2.5, 50],
|
||||
condition: ({ options }) =>
|
||||
options.find(option => option.id === 'dynamic-mode').value === 'ThresholdRange',
|
||||
commands: {
|
||||
commandName: 'setThresholdRange',
|
||||
commandOptions: {
|
||||
toolNames: ['ThresholdCircularBrush', 'ThresholdSphereBrush'],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default toolbarButtons;
|
||||
Reference in new issue
Block a user