Compare commits

..

No commits in common. "47d7fb00e2fe967149446e5f37d99255cb4bd698" and "0ff5a21d049fec6b87a2a2f421684336e61bf7f6" have entirely different histories.

6 changed files with 503 additions and 1224 deletions

View File

@ -16,7 +16,6 @@
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "3.726.1", "@aws-sdk/client-s3": "3.726.1",
"@cornerstonejs/adapters": "^4.19.2", "@cornerstonejs/adapters": "^4.19.2",
"@cornerstonejs/polymorphic-segmentation": "4.19.2",
"@cornerstonejs/calculate-suv": "^1.1.0", "@cornerstonejs/calculate-suv": "^1.1.0",
"@cornerstonejs/core": "^4.19.2", "@cornerstonejs/core": "^4.19.2",
"@cornerstonejs/dicom-image-loader": "^4.19.2", "@cornerstonejs/dicom-image-loader": "^4.19.2",
@ -125,4 +124,4 @@
"not dead", "not dead",
"not op_mini all" "not op_mini all"
] ]
} }

View File

@ -81,19 +81,6 @@ import {
} from './helpers/index.js' } from './helpers/index.js'
import { vec3, mat4 } from 'gl-matrix' import { vec3, mat4 } from 'gl-matrix'
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent' import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
import {
renderSegmentation,
readingSegmentByConfig,
selectSegmentation,
selectSegment,
createSegmentationRepresentation,
viewSegmentation,
viewSegment,
jumpBidirectional,
viewBidirectional,
changeColor,
resetViewport
} from "./helpers/segmentations"
export default { export default {
name: 'MPRViewport', name: 'MPRViewport',
props: { props: {
@ -118,32 +105,6 @@ export default {
histogramVisible: { histogramVisible: {
type: Boolean, type: Boolean,
default: false default: false
},
actionConfiguration: {
type: Object,
default: () => {
return {}
}
},
SegmentConfig: {
type: Object,
default: () => {
return {}
}
},
curSegSeries: {
type: Object,
default: () => {
return {}
}
},
segmentIndex: {
type: Number,
default: 0
},
segmentationId: {
type: String,
default: ''
} }
}, },
data() { data() {
@ -194,39 +155,6 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.initViewport() this.initViewport()
}) })
DicomEvent.$on('createSegmentationRepresentation', (segmentationId) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
createSegmentationRepresentation(this.viewportId, segmentationId)
})
DicomEvent.$on('viewSegmentation', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
viewSegmentation(obj, this.viewportId)
})
DicomEvent.$on('viewSegment', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
viewSegment(obj, this.viewportId)
})
DicomEvent.$on('jumpBidirectional', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
jumpBidirectional(obj, this.viewportId, this.volumeId)
})
DicomEvent.$on('viewBidirectional', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
viewBidirectional(obj, this.viewportId)
})
DicomEvent.$on('changeColor', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
changeColor(obj, this.viewportId)
})
DicomEvent.$on('resetViewport', () => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
resetViewport(this.viewportId)
})
DicomEvent.$on('renderSegmentation', async (viewportId) => {
// if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
if (this.viewportId !== viewportId) return false
await renderSegmentation(this.series, this.series.TaskInfo, this.viewportId, this.SegmentConfig, this.segmentationId, this.segmentIndex, this.renderingEngineId, null, this.actionConfiguration)
})
}, },
watch: { watch: {
MPRInfo: { MPRInfo: {
@ -245,25 +173,6 @@ export default {
} }
}, },
deep: true deep: true
},
SegmentConfig: {
handler() {
if (!this.segmentationId) return false
if (!this.series.TaskInfo) return false
readingSegmentByConfig(this.series, this.series.TaskInfo, this.viewportId, this.segmentationId, this.SegmentConfig)
},
deep: true
},
segmentIndex() {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
if (this.segmentIndex <= 0) return false
selectSegment(this.viewportId, this.segmentationId, this.segmentIndex)
},
segmentationId() {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
if (!this.segmentationId) return false
selectSegmentation(this.viewportId, this.segmentationId)
readingSegmentByConfig(this.series, this.series.TaskInfo, this.viewportId, this.segmentationId, this.SegmentConfig)
} }
}, },
methods: { methods: {
@ -596,6 +505,7 @@ export default {
setCtTransferFunctionForVolumeActor(r) setCtTransferFunctionForVolumeActor(r)
} }
console.log("渲染成功") console.log("渲染成功")
DicomEvent.$emit("isloaded", { isChange: false })
} }
}]).then(r => { }]).then(r => {
if (data.isLocation || !this.imageInfo.zoom) { if (data.isLocation || !this.imageInfo.zoom) {
@ -612,7 +522,6 @@ export default {
renderingEngine.render() renderingEngine.render()
}, 100) }, 100)
} }
await renderSegmentation(this.series, this.series.TaskInfo, this.viewportId, this.SegmentConfig, this.segmentationId, this.segmentIndex, this.renderingEngineId, null, this.actionConfiguration)
} catch (e) { } catch (e) {
console.log(e) console.log(e)
} }

View File

@ -313,9 +313,7 @@
@dblclick="toggleFullScreen($event, index)" @click="activeViewport(index)"> @dblclick="toggleFullScreen($event, index)" @click="activeViewport(index)">
<VolumeViewport :ref="`viewport-${index}`" :data-viewport-uid="`viewport-${index}`" <VolumeViewport :ref="`viewport-${index}`" :data-viewport-uid="`viewport-${index}`"
:rendering-engine-id="renderingEngineId" :viewport-id="`viewport-${index}`" :viewport-index="index" :rendering-engine-id="renderingEngineId" :viewport-id="`viewport-${index}`" :viewport-index="index"
:histogramVisible="histogramVisible" :actionConfiguration="actionConfiguration" :histogramVisible="histogramVisible" @activeViewport="activeViewport"
:SegmentConfig="SegmentConfig" :segmentationId.sync="segId" :segmentIndex.sync="segIndex"
:curSegSeries.sync="curSegSeries" @activeViewport="activeViewport"
@toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD" @toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD"
@renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup" @renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup"
@resetViewport="resetViewport" v-if="readingTool === 3" @resetViewport="resetViewport" v-if="readingTool === 3"
@ -335,10 +333,7 @@
@dblclick="toggleFullScreen($event, index)" @click="activeViewport(index)"> @dblclick="toggleFullScreen($event, index)" @click="activeViewport(index)">
<MPRViewport :ref="`viewport-MPR-${index}`" :data-viewport-uid="`viewport-MPR-${index}`" <MPRViewport :ref="`viewport-MPR-${index}`" :data-viewport-uid="`viewport-MPR-${index}`"
:rendering-engine-id="renderingEngineId" :viewport-id="`viewport-MPR-${index}`" :rendering-engine-id="renderingEngineId" :viewport-id="`viewport-MPR-${index}`"
:viewport-index="index" :histogramVisible="histogramVisible" :viewport-index="index" :MPRInfo="MPRInfo" @activeViewport="activeViewport" @setMPRInfo="setMPRInfo"
:actionConfiguration="actionConfiguration" :SegmentConfig="SegmentConfig"
:segmentationId.sync="segId" :segmentIndex.sync="segIndex" :curSegSeries.sync="curSegSeries"
:MPRInfo="MPRInfo" @activeViewport="activeViewport" @setMPRInfo="setMPRInfo"
@toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD" @toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD"
@renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup" @renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup"
v-resize="(e) => handleSizeChange(e, `viewport-MPR-${index}`)" /> v-resize="(e) => handleSizeChange(e, `viewport-MPR-${index}`)" />
@ -367,11 +362,9 @@
<Segmentations ref="Segmentations" :visitInfo="taskInfo" :isMPR="isMPR" <Segmentations ref="Segmentations" :visitInfo="taskInfo" :isMPR="isMPR"
:volumeToolGroupId="volumeToolGroupId" :viewportKey="viewportKey" :global-loading.sync="loading" :volumeToolGroupId="volumeToolGroupId" :viewportKey="viewportKey" :global-loading.sync="loading"
:loadingText.sync="loadingText" :rendering-engine-id="renderingEngineId" :loadingText.sync="loadingText" :rendering-engine-id="renderingEngineId"
:SegmentConfig="SegmentConfig" :segId.sync="segId" :segIndex.sync="segIndex" :activeViewportIndex="activeViewportIndex" :activeTool.sync="activeTool"
:curSegSeries.sync="curSegSeries" :activeViewportIndex="activeViewportIndex" :actionConfiguration="actionConfiguration" :histogramVisible="histogramVisible"
:activeTool.sync="activeTool" :actionConfiguration="actionConfiguration" @setToolsPassive="setToolsPassive" @resetQuestion="resetQuestion" />
:histogramVisible="histogramVisible" @setToolsPassive="setToolsPassive"
@resetQuestion="resetQuestion" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('trials:reading:dicom3D:tabs:ecrf')" name="ecrf"> <el-tab-pane :label="$t('trials:reading:dicom3D:tabs:ecrf')" name="ecrf">
<div v-for="s in visitTaskList" v-show="lastViewportTaskId === s.VisitTaskId" :key="s.VisitTaskId" <div v-for="s in visitTaskList" v-show="lastViewportTaskId === s.VisitTaskId" :key="s.VisitTaskId"
@ -505,11 +498,6 @@
<!--直方图--> <!--直方图-->
<histogram ref="histogram" v-if="readingTool === 3" :visible.sync="histogramVisible" :activeTool.sync="activeTool" <histogram ref="histogram" v-if="readingTool === 3" :visible.sync="histogramVisible" :activeTool.sync="activeTool"
:viewportKey="viewportKey" :rendering-engine-id="renderingEngineId" :activeViewportIndex="activeViewportIndex" /> :viewportKey="viewportKey" :rendering-engine-id="renderingEngineId" :activeViewportIndex="activeViewportIndex" />
<!--分割可视化窗口-->
<!-- <SurfaceViewport ref="surfaceViewport" viewportId="surfaceViewport" v-if="readingTool === 3"
:visible.sync="surfaceVisible" :renderingEngineId="renderingEngineId" :visitInfo="taskInfo" />
<ContourViewport ref="contourViewport" viewportId="contourViewport" v-if="readingTool === 3"
:renderingEngineId="renderingEngineId" :visitInfo="taskInfo" /> -->
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :subject-id="uploadSubjectId" <upload-dicom-and-nonedicom v-if="uploadImageVisible" :subject-id="uploadSubjectId"
:subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible" :subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible"
:visit-task-id="taskId" :is-reading-task-view-in-order="isReadingTaskViewInOrder" /> :visit-task-id="taskId" :is-reading-task-view-in-order="isReadingTaskViewInOrder" />
@ -528,7 +516,6 @@ import {
RenderingEngine, RenderingEngine,
Enums, Enums,
// imageLoader, // imageLoader,
// CONSTANTS,
metaData, metaData,
volumeLoader, volumeLoader,
getRenderingEngine, getRenderingEngine,
@ -550,8 +537,6 @@ import MPRViewport from './MPRViewport'
import VolumeViewport from './VolumeViewport' import VolumeViewport from './VolumeViewport'
import Segmentations from './Segmentations' import Segmentations from './Segmentations'
import histogram from "./histogram" import histogram from "./histogram"
// import SurfaceViewport from "./SurfaceViewport"
// import ContourViewport from "./ContourViewport"
import mRecisit from './mRecist/QuestionList' import mRecisit from './mRecist/QuestionList'
import recisit from './Recist/QuestionList' import recisit from './Recist/QuestionList'
import customizeQuestionList from './customize/QuestionList' import customizeQuestionList from './customize/QuestionList'
@ -582,9 +567,6 @@ const {
ToolGroupManager, ToolGroupManager,
Enums: csToolsEnums, Enums: csToolsEnums,
StackScrollTool, StackScrollTool,
TrackballRotateTool,
PlanarFreehandContourSegmentationTool,
SplineContourSegmentationTool,
// ScaleOverlayTool, // ScaleOverlayTool,
PanTool, PanTool,
ZoomTool, ZoomTool,
@ -647,8 +629,6 @@ export default {
VolumeViewport, VolumeViewport,
Segmentations, Segmentations,
histogram, histogram,
// SurfaceViewport,
// ContourViewport,
mRecisit, mRecisit,
recisit, recisit,
customizeQuestionList, customizeQuestionList,
@ -682,7 +662,7 @@ export default {
activeTaskIndex: -1, activeTaskIndex: -1,
activeStudyIndex: -1, activeStudyIndex: -1,
activeSeriesIndex: -1, activeSeriesIndex: -1,
currentVisitInfo: {}, currentVisitInfo: null,
layout: 1, layout: 1,
cellsMax: 4, cellsMax: 4,
rows: 1, rows: 1,
@ -792,28 +772,14 @@ export default {
}, },
}, },
}, },
SegmentConfig: {
renderOutline: true,
renderFill: true,
fillAlpha: 0.5,
outlineWidth: 1,
InactiveSegmentations: {
show: true,
fillAlpha: 0.3,
}
},
segId: null,
segIndex: null,
curSegSeries: {},
fusionOverlayModality: null, fusionOverlayModality: null,
lastUpper: null, lastUpper: null,
hasFusionUpperInitialized: false, hasFusionUpperInitialized: false,
timer: {}, timer: null,
FullTimerOut: null, FullTimerOut: null,
isDelay: false, isDelay: false,
histogramVisible: false, histogramVisible: false
// surfaceVisible: false
} }
}, },
computed: { computed: {
@ -985,11 +951,6 @@ export default {
this.getSystemInfoReading(); this.getSystemInfoReading();
}, },
methods: { methods: {
showSurface(obj) {
// this.surfaceVisible = true
// this.$refs.contourViewport.setSeriesInfo(obj)
// this.$refs.surfaceViewport.setSeriesInfo(obj)
},
async openHistogram() { async openHistogram() {
this.histogramVisible = true this.histogramVisible = true
this.setToolsPassive() this.setToolsPassive()
@ -997,8 +958,8 @@ export default {
}, },
handleSizeChange(e, viewportId) { handleSizeChange(e, viewportId) {
let index = this.$refs[viewportId][0].series.SliceIndex // console.log('handleSizeChange', e)
this.resetRenderingEngine(viewportId, index) this.resetRenderingEngine(viewportId)
}, },
resetQuestion() { resetQuestion() {
this.$refs[`ecrf_${this.lastViewportTaskId}`][0].getQuestions(false) this.$refs[`ecrf_${this.lastViewportTaskId}`][0].getQuestions(false)
@ -1336,27 +1297,6 @@ export default {
} }
} }
] ]
// let element5 = this.$refs.surfaceViewport.$el
// let element6 = this.$refs.contourViewport.$el
// viewportInputArray.push({
// viewportId: 'surfaceViewport',
// type: ViewportType.VOLUME_3D,
// element: element5,
// defaultOptions: {
// orientation: Enums.OrientationAxis.CORONAL,
// background: [1, 1, 1]
// }
// })
// viewportInputArray.push({
// viewportId: 'contourViewport',
// type: ViewportType.ORTHOGRAPHIC,
// element: element6,
// defaultOptions: {
// orientation: Enums.OrientationAxis.AXIAL
// }
// })
// viewportIds.push('surfaceViewport')
// viewportIds.push('contourViewport')
} }
if ((this.criterionType === 0 && this.readingTool === 0) || this.readingTool === 3) { if ((this.criterionType === 0 && this.readingTool === 0) || this.readingTool === 3) {
const volumeElement1 = this.$refs['viewport-MPR-0'][0].$el const volumeElement1 = this.$refs['viewport-MPR-0'][0].$el
@ -1437,7 +1377,6 @@ export default {
} }
renderingEngine.setViewports(viewportInputArray) renderingEngine.setViewports(viewportInputArray)
this.addAnnotationListeners() this.addAnnotationListeners()
// cornerstoneTools.addTool(TrackballRotateTool)
cornerstoneTools.addTool(StackScrollTool) cornerstoneTools.addTool(StackScrollTool)
cornerstoneTools.addTool(PanTool) cornerstoneTools.addTool(PanTool)
cornerstoneTools.addTool(ZoomTool) cornerstoneTools.addTool(ZoomTool)
@ -1462,8 +1401,6 @@ export default {
cornerstoneTools.addTool(LabelMapEditWithContourTool) cornerstoneTools.addTool(LabelMapEditWithContourTool)
cornerstoneTools.addTool(BrushTool) cornerstoneTools.addTool(BrushTool)
cornerstoneTools.addTool(SegmentBidirectionalTool) cornerstoneTools.addTool(SegmentBidirectionalTool)
// cornerstoneTools.addTool(PlanarFreehandContourSegmentationTool);
// cornerstoneTools.addTool(SplineContourSegmentationTool);
viewportIds.forEach((viewportId, i) => { viewportIds.forEach((viewportId, i) => {
// const toolGroupId = `viewport-${i}` // const toolGroupId = `viewport-${i}`
let toolGroupId = viewportId let toolGroupId = viewportId
@ -1473,222 +1410,196 @@ export default {
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId) ? ToolGroupManager.getToolGroup(toolGroupId) : ToolGroupManager.createToolGroup(toolGroupId) const toolGroup = ToolGroupManager.getToolGroup(toolGroupId) ? ToolGroupManager.getToolGroup(toolGroupId) : ToolGroupManager.createToolGroup(toolGroupId)
toolGroup.addViewport(viewportId, renderingEngineId) toolGroup.addViewport(viewportId, renderingEngineId)
if (toolGroupId.includes('surface')) { toolGroup.addTool(StackScrollTool.toolName, {
// toolGroup.addTool(TrackballRotateTool.toolName, { loop: true, //
// rotateSampleDistanceFactor: 0, })
// }); toolGroup.addTool(ScaleOverlayTool.toolName)
// toolGroup.setToolActive(TrackballRotateTool.toolName, {
// bindings: [
// {
// mouseButton: MouseBindings.Primary,
// },
// ],
// });
} else if (toolGroupId.includes('contour')) {
// toolGroup.addTool(PlanarFreehandContourSegmentationTool.toolName);
// toolGroup.addTool(SplineContourSegmentationTool.toolName);
// toolGroup.setToolActive(PlanarFreehandContourSegmentationTool.toolName, {
// bindings: [
// {
// mouseButton: MouseBindings.Primary, // Middle Click
// },
// ],
// });
} else {
toolGroup.addTool(StackScrollTool.toolName, {
loop: true, //
})
toolGroup.addTool(ScaleOverlayTool.toolName) toolGroup.addTool(PanTool.toolName)
toolGroup.addTool(ZoomTool.toolName)
toolGroup.addTool(PanTool.toolName) toolGroup.addTool(BrushTool.toolName)
toolGroup.addTool(ZoomTool.toolName) if (this.readingTool === 3 || toolGroupId === this.volumeToolGroupId) {
toolGroup.addTool(BrushTool.toolName) toolGroup.addToolInstance(
if (this.readingTool === 3 || toolGroupId === this.volumeToolGroupId) { 'histogram_RectangleROI',
toolGroup.addToolInstance( RectangleROITool.toolName,
'histogram_RectangleROI', );
RectangleROITool.toolName, toolGroup.addToolInstance(
); 'histogram_CircleROI',
toolGroup.addToolInstance( CircleROITool.toolName,
'histogram_CircleROI', );
CircleROITool.toolName, toolGroup.addToolInstance(
); 'histogram_PlanarFreehandROI',
toolGroup.addToolInstance( PlanarFreehandROITool.toolName,
'histogram_PlanarFreehandROI', );
PlanarFreehandROITool.toolName, toolGroup.addToolInstance(
); 'CircularBrush',
toolGroup.addToolInstance( BrushTool.toolName,
'CircularBrush',
BrushTool.toolName,
{
activeStrategy: 'FILL_INSIDE_CIRCLE',
preview: {
previewColors: {}
}
}
);
toolGroup.addToolInstance(
'CircularEraser',
BrushTool.toolName,
{
activeStrategy: 'ERASE_INSIDE_CIRCLE',
preview: {
previewColors: {}
}
}
)
toolGroup.addToolInstance(
'ThresholdCircle',
BrushTool.toolName,
{
activeStrategy: 'THRESHOLD_INSIDE_CIRCLE',
}
)
toolGroup.addToolInstance(
'ThresholdSphere',
BrushTool.toolName,
{
activeStrategy: 'THRESHOLD_INSIDE_SPHERE',
}
)
toolGroup.addTool(LabelMapEditWithContourTool.toolName);
toolGroup.addTool(SegmentBidirectionalTool.toolName, {
getTextLines: this.getBidirectionalToolTextLines
});
}
if (volumeViewportIds.includes(viewportId)) {
toolGroup.addTool(WindowLevelTool.toolName, {
targetViewportIds: volumeViewportIds
})
toolGroup.addTool(CrosshairsTool.toolName, {
getReferenceLineColor: this.setCrosshairsToolLineColor
});
} else {
toolGroup.addTool(WindowLevelTool.toolName)
}
toolGroup.addTool(WindowLevelTool.toolName)
toolGroup.addTool(WindowLevelRegionTool.toolName)
toolGroup.addTool(PlanarRotateTool.toolName)
toolGroup.addTool(ArrowAnnotateTool.toolName, {
arrowHeadStyle: 'standard',
changeTextCallback: async (data, eventData, doneChangingTextCallback) => {
return doneChangingTextCallback(data.text)
},
getTextCallback: async (doneChangingTextCallback) => {
return doneChangingTextCallback('Annotation')
}
})
toolGroup.addTool(RectangleROITool.toolName, {
cachedStats: false,
getTextLines: this.criterionType === 0 ? this.getCustomRectangleROIToolTextLines : this.getRectangleROIToolTextLines
})
toolGroup.addTool(PlanarFreehandROITool.toolName, {
allowOpenContours: false,
cachedStats: false,
getTextLines: this.getPlanarFreehandROIToolTextLines
})
toolGroup.addTool(EraserTool.toolName)
toolGroup.addTool(LengthTool.toolName, {
getTextLines: this.getLengthToolTextLines
// cachedStats: false
})
toolGroup.addTool(BidirectionalTool.toolName, {
// cachedStats: true,
actions: this.actionConfiguration,
getTextLines: this.getBidirectionalToolTextLines
})
toolGroup.addTool(CircleROITool.toolName, {
getTextLines: this.getCircleROIToolTextLines
})
toolGroup.addTool(EllipticalROITool.toolName, {
getTextLines: this.getEllipticalROIToolTextLines
})
toolGroup.addTool(FixedRadiusCircleROITool.toolName), {
getTextLines: this.getCircleROIToolTextLines
}
toolGroup.addTool(AngleTool.toolName, {
getTextLines: this.getAngleToolTextLines
})
toolGroup.addTool(CobbAngleTool.toolName, {
getTextLines: this.getCobbAngleToolTextLines
})
if (toolGroupId === 'viewport-fusion-3') {
toolGroup.addTool(VolumeRotateTool.toolName)
toolGroup.setToolActive(VolumeRotateTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Wheel // mouse wheel
}
]
})
toolGroup.addTool(MIPJumpToClickTool.toolName, {
targetViewportIds: fusionViewportIds.filter((id) => id !== toolGroupId)
})
// Set the initial state of the tools, here we set one tool active on left click.
// This means left click will draw that tool.
toolGroup.setToolActive(MIPJumpToClickTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Primary // Left Click
}
]
})
}
toolGroup.setToolConfiguration(
ScaleOverlayTool.toolName,
{ {
scaleLocation: 'bottom' activeStrategy: 'FILL_INSIDE_CIRCLE',
}, preview: {
true // overwrite previewColors: {}
) }
toolGroup.setToolActive(StackScrollTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Wheel }]
})
toolGroup.setToolActive(ZoomTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Secondary }]
})
toolGroup.setToolActive(PanTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Auxiliary }]
})
toolGroup.setToolPassive(WindowLevelTool.toolName)
toolGroup.setToolPassive(WindowLevelRegionTool.toolName)
toolGroup.setToolPassive(PlanarRotateTool.toolName)
if (this.readingTaskState < 2) {
toolGroup.setToolPassive(ArrowAnnotateTool.toolName)
toolGroup.setToolPassive(RectangleROITool.toolName)
toolGroup.setToolPassive(PlanarFreehandROITool.toolName)
toolGroup.setToolPassive(LengthTool.toolName)
toolGroup.setToolPassive(BidirectionalTool.toolName)
toolGroup.setToolPassive(CircleROITool.toolName)
toolGroup.setToolPassive(EllipticalROITool.toolName)
toolGroup.setToolPassive(FixedRadiusCircleROITool.toolName)
toolGroup.setToolPassive(AngleTool.toolName)
toolGroup.setToolPassive(CobbAngleTool.toolName)
if (this.readingTool === 3) {
toolGroup.setToolPassive(LabelMapEditWithContourTool.toolName)
toolGroup.setToolPassive(SegmentBidirectionalTool.toolName, {});
} }
} else { );
toolGroup.setToolEnabled(ArrowAnnotateTool.toolName) toolGroup.addToolInstance(
toolGroup.setToolEnabled(RectangleROITool.toolName) 'CircularEraser',
toolGroup.setToolEnabled(PlanarFreehandROITool.toolName) BrushTool.toolName,
toolGroup.setToolEnabled(LengthTool.toolName) {
toolGroup.setToolEnabled(BidirectionalTool.toolName) activeStrategy: 'ERASE_INSIDE_CIRCLE',
toolGroup.setToolEnabled(CircleROITool.toolName) preview: {
toolGroup.setToolEnabled(EllipticalROITool.toolName) previewColors: {}
toolGroup.setToolEnabled(FixedRadiusCircleROITool.toolName) }
toolGroup.setToolEnabled(AngleTool.toolName)
toolGroup.setToolEnabled(CobbAngleTool.toolName)
if (this.readingTool === 3) toolGroup.setToolEnabled(LabelMapEditWithContourTool.toolName)
}
toolGroup.setToolPassive(EraserTool.toolName)
}
}
)
toolGroup.addToolInstance(
'ThresholdCircle',
BrushTool.toolName,
{
activeStrategy: 'THRESHOLD_INSIDE_CIRCLE',
}
)
toolGroup.addToolInstance(
'ThresholdSphere',
BrushTool.toolName,
{
activeStrategy: 'THRESHOLD_INSIDE_SPHERE',
}
)
toolGroup.addTool(LabelMapEditWithContourTool.toolName);
toolGroup.addTool(SegmentBidirectionalTool.toolName, {
getTextLines: this.getBidirectionalToolTextLines
});
}
if (volumeViewportIds.includes(viewportId)) {
toolGroup.addTool(WindowLevelTool.toolName, {
targetViewportIds: volumeViewportIds
})
toolGroup.addTool(CrosshairsTool.toolName, {
getReferenceLineColor: this.setCrosshairsToolLineColor
});
} else {
toolGroup.addTool(WindowLevelTool.toolName)
}
toolGroup.addTool(WindowLevelTool.toolName)
toolGroup.addTool(WindowLevelRegionTool.toolName)
toolGroup.addTool(PlanarRotateTool.toolName)
toolGroup.addTool(ArrowAnnotateTool.toolName, {
arrowHeadStyle: 'standard',
changeTextCallback: async (data, eventData, doneChangingTextCallback) => {
return doneChangingTextCallback(data.text)
},
getTextCallback: async (doneChangingTextCallback) => {
return doneChangingTextCallback('Annotation')
}
})
toolGroup.addTool(RectangleROITool.toolName, {
cachedStats: false,
getTextLines: this.criterionType === 0 ? this.getCustomRectangleROIToolTextLines : this.getRectangleROIToolTextLines
})
toolGroup.addTool(PlanarFreehandROITool.toolName, {
allowOpenContours: false,
cachedStats: false,
getTextLines: this.getPlanarFreehandROIToolTextLines
})
toolGroup.addTool(EraserTool.toolName)
toolGroup.addTool(LengthTool.toolName, {
getTextLines: this.getLengthToolTextLines
// cachedStats: false
})
toolGroup.addTool(BidirectionalTool.toolName, {
// cachedStats: true,
actions: this.actionConfiguration,
getTextLines: this.getBidirectionalToolTextLines
})
toolGroup.addTool(CircleROITool.toolName, {
getTextLines: this.getCircleROIToolTextLines
})
toolGroup.addTool(EllipticalROITool.toolName, {
getTextLines: this.getEllipticalROIToolTextLines
})
toolGroup.addTool(FixedRadiusCircleROITool.toolName), {
getTextLines: this.getCircleROIToolTextLines
}
toolGroup.addTool(AngleTool.toolName, {
getTextLines: this.getAngleToolTextLines
})
toolGroup.addTool(CobbAngleTool.toolName, {
getTextLines: this.getCobbAngleToolTextLines
})
if (toolGroupId === 'viewport-fusion-3') {
toolGroup.addTool(VolumeRotateTool.toolName)
toolGroup.setToolActive(VolumeRotateTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Wheel // mouse wheel
}
]
})
toolGroup.addTool(MIPJumpToClickTool.toolName, {
targetViewportIds: fusionViewportIds.filter((id) => id !== toolGroupId)
})
// Set the initial state of the tools, here we set one tool active on left click.
// This means left click will draw that tool.
toolGroup.setToolActive(MIPJumpToClickTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Primary // Left Click
}
]
})
}
toolGroup.setToolConfiguration(
ScaleOverlayTool.toolName,
{
scaleLocation: 'bottom'
},
true // overwrite
)
toolGroup.setToolActive(StackScrollTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Wheel }]
})
toolGroup.setToolActive(ZoomTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Secondary }]
})
toolGroup.setToolActive(PanTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Auxiliary }]
})
toolGroup.setToolPassive(WindowLevelTool.toolName)
toolGroup.setToolPassive(WindowLevelRegionTool.toolName)
toolGroup.setToolPassive(PlanarRotateTool.toolName)
if (this.readingTaskState < 2) {
toolGroup.setToolPassive(ArrowAnnotateTool.toolName)
toolGroup.setToolPassive(RectangleROITool.toolName)
toolGroup.setToolPassive(PlanarFreehandROITool.toolName)
toolGroup.setToolPassive(LengthTool.toolName)
toolGroup.setToolPassive(BidirectionalTool.toolName)
toolGroup.setToolPassive(CircleROITool.toolName)
toolGroup.setToolPassive(EllipticalROITool.toolName)
toolGroup.setToolPassive(FixedRadiusCircleROITool.toolName)
toolGroup.setToolPassive(AngleTool.toolName)
toolGroup.setToolPassive(CobbAngleTool.toolName)
if (this.readingTool === 3) {
toolGroup.setToolPassive(LabelMapEditWithContourTool.toolName)
toolGroup.setToolPassive(SegmentBidirectionalTool.toolName, {});
}
} else {
toolGroup.setToolEnabled(ArrowAnnotateTool.toolName)
toolGroup.setToolEnabled(RectangleROITool.toolName)
toolGroup.setToolEnabled(PlanarFreehandROITool.toolName)
toolGroup.setToolEnabled(LengthTool.toolName)
toolGroup.setToolEnabled(BidirectionalTool.toolName)
toolGroup.setToolEnabled(CircleROITool.toolName)
toolGroup.setToolEnabled(EllipticalROITool.toolName)
toolGroup.setToolEnabled(FixedRadiusCircleROITool.toolName)
toolGroup.setToolEnabled(AngleTool.toolName)
toolGroup.setToolEnabled(CobbAngleTool.toolName)
if (this.readingTool === 3) toolGroup.setToolEnabled(LabelMapEditWithContourTool.toolName)
}
toolGroup.setToolPassive(EraserTool.toolName)
}) })
eventTarget.addEventListener('cornerstoneimageloadprogress', this.imageLoadProgress) eventTarget.addEventListener('cornerstoneimageloadprogress', this.imageLoadProgress)
// console.log(Events, toolsEvents) // console.log(Events, toolsEvents)
@ -2716,7 +2627,7 @@ export default {
viewport.render() viewport.render()
renderingEngine.render() renderingEngine.render()
if (this.readingTool === 3) { if (this.readingTool === 3) {
DicomEvent.$emit('isloaded', { isChange: false, viewportId }) DicomEvent.$emit('isloaded', { isChange: false })
} }
}, },
// //
@ -2996,25 +2907,25 @@ export default {
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].resize(forceFitToWindow) this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].resize(forceFitToWindow)
}, },
// //
resetRenderingEngine(viewportId = null, i) { resetRenderingEngine(viewportId = null) {
if (this.timer[viewportId]) { if (this.timer) {
clearInterval(this.timer[viewportId]) clearInterval(this.timer)
this.timer[viewportId] = null this.timer = null
} }
const renderingEngine = getRenderingEngine(renderingEngineId) const renderingEngine = getRenderingEngine(renderingEngineId)
const viewport = renderingEngine.getViewport(viewportId) const viewport = renderingEngine.getViewport(viewportId)
if (!viewport) return false if (!viewport) return false
if (viewport.volumeIds.size <= 0) return false if (viewport.volumeIds.size <= 0) return false
let index = null let index = null
this.timer[viewportId] = setTimeout(() => { this.timer = setTimeout(() => {
index = i || i === 0 ? i : this.$refs[viewportId ? viewportId : `${this.viewportKey}-${this.activeViewportIndex}`][0].series.SliceIndex index = index || index === 0 ? index : this.$refs[viewportId ? viewportId : `${this.viewportKey}-${this.activeViewportIndex}`][0].series.SliceIndex
renderingEngine.resize(true, false) renderingEngine.resize(true, false)
renderingEngine.render() renderingEngine.render()
this.$refs[viewportId ? viewportId : `${this.viewportKey}-${this.activeViewportIndex}`][0].setFullScreen(index) this.$refs[viewportId ? viewportId : `${this.viewportKey}-${this.activeViewportIndex}`][0].setFullScreen(index)
clearTimeout(this.timer[viewportId]) clearTimeout(this.timer)
this.timer[viewportId] = null this.timer = null
if (this.readingTool === 3) { if (this.readingTool === 3) {
DicomEvent.$emit('isloaded', { isChange: false, viewportId }) DicomEvent.$emit('isloaded', { isChange: false })
} }
}, 100) }, 100)
}, },
@ -3035,7 +2946,7 @@ export default {
if (this.readingTool === 3 || this.isMPR) { if (this.readingTool === 3 || this.isMPR) {
// this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setSeriesInfo(this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series) // this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setSeriesInfo(this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series)
this.$nextTick(() => { this.$nextTick(() => {
// this.resetRenderingEngine(`${this.viewportKey}-${index}`) this.resetRenderingEngine()
this.isDelay = true this.isDelay = true
this.setDelay(2000) this.setDelay(2000)
// if (this.readingTool === 3) { // if (this.readingTool === 3) {
@ -4137,13 +4048,8 @@ export default {
this.saveCustomAnnotationTimer = null this.saveCustomAnnotationTimer = null
} }
if (this.timer) { if (this.timer) {
Object.keys(this.timer).forEach(key => { clearInterval(this.timer)
if (this.timer[key]) { this.timer = null
clearInterval(this.timer[key])
this.timer[key] = null
}
})
this.timer = {}
} }
if (this.FullTimerOut) { if (this.FullTimerOut) {
clearTimeout(this.FullTimerOut) clearTimeout(this.FullTimerOut)

View File

@ -80,8 +80,7 @@
@click.stop="changeShowSegmentConfig" /> @click.stop="changeShowSegmentConfig" />
</div> </div>
</template> </template>
<div class="addSegmentBox viewHover" @click.stop="addSegment" <div class="addSegmentBox viewHover" @click.stop="addSegment" v-if="segmentList.length <= 0">
v-if="segmentList.length <= 0 && readingTaskState < 2">
<span><i class="el-icon-plus"></i> <span><i class="el-icon-plus"></i>
{{ $t('trials:reading:Segmentations:button:addSegmention') }} {{ $t('trials:reading:Segmentations:button:addSegmention') }}
</span> </span>
@ -125,11 +124,16 @@
$t('trials:reading:Segmentations:title:InactiveSegmentationsShow') $t('trials:reading:Segmentations:title:InactiveSegmentationsShow')
}}</span> }}</span>
</div> </div>
<!-- <div class="SegmentConfig" v-if="SegmentConfig.InactiveSegmentations.show">
<span>{{ $t('trials:reading:Segmentations:title:Opacity') }}</span>
<el-slider v-model="SegmentConfig.InactiveSegmentations.fillAlpha" show-input :step="0.1"
:max="1" input-size="mini" :show-input-controls="false" />
</div> -->
</div> </div>
<template v-if="segmentList.length > 0"> <template v-if="segmentList.length > 0">
<div class="SegmentGroupBox"> <div class="SegmentGroupBox">
<div style="display: flex;align-items: center;"> <div style="display: flex;align-items: center;">
<el-popover placement="left" width="40" trigger="click" v-if="readingTaskState < 2"> <el-popover placement="left" width="40" trigger="click">
<div class="SegmentGroupBtnBox"> <div class="SegmentGroupBtnBox">
<div class="SegmentGroupBtn" @click.stop="addSegmentGroup"> <div class="SegmentGroupBtn" @click.stop="addSegmentGroup">
{{ $t('trials:reading:Segmentations:button:addSegmentGroup') }} {{ $t('trials:reading:Segmentations:button:addSegmentGroup') }}
@ -152,7 +156,7 @@
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<div style="display: flex;align-items: center;" v-if="readingTaskState < 2"> <div style="display: flex;align-items: center;">
<i class="el-icon-warning-outline" style="color:red;margin-right: 5px;" <i class="el-icon-warning-outline" style="color:red;margin-right: 5px;"
:title="$t('trials:reading:Segmentations:tip:segmentationIsNotSave')" :title="$t('trials:reading:Segmentations:tip:segmentationIsNotSave')"
v-if="!curSegmentGroup.isSaved"></i> v-if="!curSegmentGroup.isSaved"></i>
@ -163,8 +167,7 @@
</div> </div>
</div> </div>
<div class="addSegmentBox" @click.stop="addSegment" <div class="addSegmentBox" @click.stop="addSegment"
style="display: flex;align-items: center;justify-content: space-between;" style="display: flex;align-items: center;justify-content: space-between;">
v-if="readingTaskState < 2">
<span><i class="el-icon-plus"></i> <span><i class="el-icon-plus"></i>
{{ $t('trials:reading:Segmentations:button:addSegment') }} {{ $t('trials:reading:Segmentations:button:addSegment') }}
</span> </span>
@ -217,7 +220,7 @@
<i class="el-icon-lock" v-if="item.lock" @click.stop="lockSegment(item, false)"></i> <i class="el-icon-lock" v-if="item.lock" @click.stop="lockSegment(item, false)"></i>
<el-popover placement="bottom" width="40" trigger="click" class="docShow" <el-popover placement="bottom" width="40" trigger="click" class="docShow"
:value="popoverId === `popover-${item.segmentationId}_${item.segmentIndex}`" :value="popoverId === `popover-${item.segmentationId}_${item.segmentIndex}`"
@show="handleClickPopover(item)" v-if="readingTaskState < 2"> @show="handleClickPopover(item)">
<div class="SegmentGroupBtnBox"> <div class="SegmentGroupBtnBox">
<div class="SegmentGroupBtn" @click.stop="rename('segment', item)"> <div class="SegmentGroupBtn" @click.stop="rename('segment', item)">
{{ $t('trials:reading:Segmentations:button:renameSegmentGroup') }} {{ $t('trials:reading:Segmentations:button:renameSegmentGroup') }}
@ -242,7 +245,7 @@
</template> </template>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
<div class="saveBtnBox" v-if="readingTaskState < 2"> <div class="saveBtnBox">
<el-button type="success" size="small" :disabled="saveLoading" @click="saveSegmentGroup()"> <el-button type="success" size="small" :disabled="saveLoading" @click="saveSegmentGroup()">
{{ $t("trials:reading:Segmentations:button:saveAll") }} {{ $t("trials:reading:Segmentations:button:saveAll") }}
</el-button> </el-button>
@ -258,8 +261,6 @@ import * as cornerstoneAdapters from "@cornerstonejs/adapters";
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader' import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent' import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
import { getCustomizeStandardsSegmentDicomTools } from './toolConfig' import { getCustomizeStandardsSegmentDicomTools } from './toolConfig'
import * as polySeg from '@cornerstonejs/polymorphic-segmentation'
cornerstoneTools.init({ addons: { polySeg } })
const { const {
ToolGroupManager, ToolGroupManager,
Enums: csToolsEnums, Enums: csToolsEnums,
@ -270,7 +271,6 @@ const {
CrosshairsTool, CrosshairsTool,
utilities: CStUtils, utilities: CStUtils,
} = cornerstoneTools; } = cornerstoneTools;
const { MouseBindings, Events: toolsEvents } = csToolsEnums const { MouseBindings, Events: toolsEvents } = csToolsEnums
const { segmentation: segmentationUtils } = CStUtils; const { segmentation: segmentationUtils } = CStUtils;
const { cache, getRenderingEngine, imageLoader, eventTarget, metaData, utilities: csUtils, volumeLoader } = cornerstone; const { cache, getRenderingEngine, imageLoader, eventTarget, metaData, utilities: csUtils, volumeLoader } = cornerstone;
@ -305,32 +305,12 @@ export default {
return {} return {}
} }
}, },
SegmentConfig: {
type: Object,
default: () => {
return {}
}
},
actionConfiguration: { actionConfiguration: {
type: Object, type: Object,
default: () => { default: () => {
return {} return {}
} }
}, },
curSegSeries: {
type: Object,
default: () => {
return {}
}
},
segId: {
type: String,
default: ''
},
segIndex: {
type: Number,
default: 0
},
renderingEngineId: { renderingEngineId: {
type: String, type: String,
required: true required: true
@ -363,6 +343,16 @@ export default {
ThresholdTools: ['ThresholdCircle', 'ThresholdSphere'], ThresholdTools: ['ThresholdCircle', 'ThresholdSphere'],
thresholdType: null, thresholdType: null,
showSegmentConfig: false, showSegmentConfig: false,
SegmentConfig: {
renderOutline: true,
renderFill: true,
fillAlpha: 0.5,
outlineWidth: 1,
InactiveSegmentations: {
show: true,
fillAlpha: 0.3,
}
},
segmentList: [], segmentList: [],
segmentationId: "", segmentationId: "",
segmentIndex: null, segmentIndex: null,
@ -378,7 +368,7 @@ export default {
'#ff994d', '#ff994d',
'#fb628b', '#fb628b',
], ],
viewportIds: [], // viewprotIds: ['viewport-0', 'viewport-1', 'viewport-2', 'viewport-3', 'viewport-MPR-0', 'viewport-MPR-1', 'viewport-MPR-2'], //
statsKey: [], statsKey: [],
drawing: false, // drawing: false, //
// isDel: false, // isDel: false,
@ -398,24 +388,14 @@ export default {
this.segmentationModifiedCallback this.segmentationModifiedCallback
); );
DicomEvent.$on('activeSeries', (series) => { DicomEvent.$on('activeSeries', (series) => {
console.log(series, 'series')
let { TaskInfo = {}, Id } = series
if (Id === this.series.Id && TaskInfo.VisitTaskId === this.visitInfo.VisitTaskId) return false
this.series = series this.series = series
this.$emit("update:curSegSeries", Object.assign(series, {}))
this.getSegmentationList()
}) })
DicomEvent.$on('isloaded', (data) => { DicomEvent.$on('isloaded', (data) => {
let { segment, isChange = true, viewportId, series } = data if (this.isloaded) return false
DicomEvent.$emit('renderSegmentation', viewportId) this.isloaded = true
// if (!series.TaskInfo || series.TaskInfo.VisitTaskId !== this.visitInfo.VisitTaskId) return false let { segment, isChange = true } = data
// if (this.isloaded) return false this.delAllSegment(isChange)
// this.isloaded = true this.getSegmentationList(segment)
// this.series = series
// this.viewportIds = []
// this.viewportIds.push(viewportId)
// // this.delAllSegment(isChange)
// this.readingSegmentToViewport(segment)
}) })
const digitPlaces = Number(localStorage.getItem('digitPlaces')) const digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
@ -434,15 +414,12 @@ export default {
s = this.curSegmentGroup.segments.find(item => item.segmentIndex === this.segmentIndex) s = this.curSegmentGroup.segments.find(item => item.segmentIndex === this.segmentIndex)
} }
return s return s
},
readingTaskState() {
return this.series.TaskInfo ? this.series.TaskInfo.ReadingTaskState : 0
} }
}, },
watch: { watch: {
SegmentConfig: { SegmentConfig: {
handler() { handler() {
// this.readingSegmentByConfig() this.readingSegmentByConfig()
}, },
deep: true deep: true
}, },
@ -457,23 +434,9 @@ export default {
this.setBrushThreshold() this.setBrushThreshold()
}, },
deep: true deep: true
},
segmentIndex() {
this.$emit('update:segIndex', this.segmentIndex)
},
segmentationId() {
this.$emit('update:segId', this.segmentationId)
} }
}, },
methods: { methods: {
showSurface(item) {
this.$emit("showSurface", {
segmentationId: item.segmentationId,
segmentIndex: item.segmentIndex,
volumeId: this.series.SeriesInstanceUid,
segmentations: this.curSegmentGroup
})
},
handleClickPopover(item) { handleClickPopover(item) {
this.popoverId = `popover-${item.segmentationId}_${item.segmentIndex}` this.popoverId = `popover-${item.segmentationId}_${item.segmentIndex}`
}, },
@ -541,6 +504,7 @@ export default {
segmentationId: list[0].segmentationId, segmentationId: list[0].segmentationId,
segmentIndices: list.map(item => item.segmentIndex), segmentIndices: list.map(item => item.segmentIndex),
}); });
console.log(bidirectionalData, list[0].segmentationId, 'bidirectionalData')
if (bidirectionalData.length <= 0) { if (bidirectionalData.length <= 0) {
list.forEach(item => { list.forEach(item => {
let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex); let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex);
@ -599,7 +563,6 @@ export default {
}, },
setToolActive(toolName) { setToolActive(toolName) {
// if (!this.series.TaskInfo || this.series.TaskInfo.VisitTaskId !== this.visitInfo.VisitTaskId) return false
if (this.segmentList.length <= 0) return false if (this.segmentList.length <= 0) return false
if (this.curSegment.lock) return false if (this.curSegment.lock) return false
if (this.histogramVisible && !this.ThresholdTools.includes(toolName)) return false if (this.histogramVisible && !this.ThresholdTools.includes(toolName)) return false
@ -639,33 +602,71 @@ export default {
viewBidirectional(arr, view) { viewBidirectional(arr, view) {
for (let j = 0; j < arr.length; j++) { for (let j = 0; j < arr.length; j++) {
let item = arr[j] let item = arr[j]
let bidirectional = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
item.bidirectionalView = view item.bidirectionalView = view
// let bidirectional = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex && i.metadata.toolName === "SegmentBidirectional"); if (!bidirectional) continue
// item.bidirectionalView = view annotation.visibility.setAnnotationVisibility(bidirectional.annotationUID, view)
// if (!bidirectional) continue
// annotation.visibility.setAnnotationVisibility(bidirectional.annotationUID, view)
} }
DicomEvent.$emit('viewBidirectional', arr) this.resetViewport()
// this.resetViewport()
}, },
async jumpBidirectional(item) { async jumpBidirectional(item) {
DicomEvent.$emit('jumpBidirectional', item) if (item.bidirectional) {
let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
console.log(an, 'an')
if (!an) return false
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
const viewport = renderingEngine.getViewport(viewportId)
let key = Object.keys(an.data.cachedStats)[0]; // referencedImageId
if (key) {
let sliceIndex = key.split("?")[1].split("&")[0].split("=")[1]
csUtils.jumpToSlice(viewport.element, { imageIndex: sliceIndex });
} else {
const points = an.data.handles.points;
const worldPoint = points[0]; //
let volume = cache.getVolume(this.series.SeriesInstanceUid)
let { imageData, numFrames } = volume
const ijk = imageData.worldToIndex(worldPoint);
const sliceIndex = Math.abs(Math.round(ijk[2]));
// console.log(sliceIndex, 'sliceIndex')
csUtils.jumpToSlice(viewport.element, { imageIndex: numFrames - sliceIndex - 1 });
}
}
}, },
viewSegmentGroup(item) { viewSegmentGroup(item) {
item.view = !item.view let view = !item.view
item.segments.forEach(i => { this.viewprotIds.forEach(id => {
i.view = item.view segmentation.config.visibility.setSegmentationRepresentationVisibility(
id,
{
segmentationId: item.segmentationId,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
},
view
);
}) })
DicomEvent.$emit('viewSegmentation', item) item.view = view
// this.viewBidirectional(item.segments, view)
item.segments.forEach(i => {
i.view = view
// this.viewBidirectional(i, view)
})
this.viewBidirectional(item.segments, view)
}, },
viewSegment(item, view) { viewSegment(item, view) {
this.viewprotIds.forEach(id => {
segmentation.config.visibility.setSegmentIndexVisibility(id, {
segmentationId: item.segmentationId,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
}, item.segmentIndex, view)
})
item.view = view item.view = view
this.viewBidirectional([item], view)
this.$emit('setToolsPassive') this.$emit('setToolsPassive')
DicomEvent.$emit('viewSegment', item)
}, },
lockSegment(item, lock) { lockSegment(item, lock) {
if (this.readingTaskState >= 2) return false
segmentation.segmentLocking.setSegmentIndexLocked(item.segmentationId, item.segmentIndex, lock) segmentation.segmentLocking.setSegmentIndexLocked(item.segmentationId, item.segmentIndex, lock)
item.lock = lock item.lock = lock
if (!lock) this.changeSegmentationSavedStatus(item.segmentationId, lock) if (!lock) this.changeSegmentationSavedStatus(item.segmentationId, lock)
@ -675,7 +676,7 @@ export default {
this.segmentationId = item.segmentationId; this.segmentationId = item.segmentationId;
this.segmentIndex = item.segmentIndex; this.segmentIndex = item.segmentIndex;
} }
// segmentation.segmentIndex.setActiveSegmentIndex(item.segmentationId, item.segmentIndex); segmentation.segmentIndex.setActiveSegmentIndex(item.segmentationId, item.segmentIndex);
if (isChange) { this.jumpBidirectional(item) } if (isChange) { this.jumpBidirectional(item) }
if (item.lock) { if (item.lock) {
@ -684,14 +685,15 @@ export default {
// this.resetViewport() // this.resetViewport()
}, },
selectSegmentGroup(s) { selectSegmentGroup(s) {
// segmentation.activeSegmentation.setActiveSegmentation(`${this.viewportKey}-${this.activeViewportIndex}`, this.segmentationId) this.viewprotIds.forEach(id => {
segmentation.activeSegmentation.setActiveSegmentation(id, this.segmentationId)
})
let segment = s ? s : this.segmentList.find(item => item.segmentationId === this.segmentationId).segments[0] let segment = s ? s : this.segmentList.find(item => item.segmentationId === this.segmentationId).segments[0]
this.segmentIndex = segment.segmentIndex this.selectSegment(segment, s ? false : true)
// this.selectSegment(segment, s ? false : true) this.readingSegmentByConfig()
// this.readingSegmentByConfig()
}, },
async addSegmentGroup() { async addSegmentGroup() {
let viewportIds = this.viewportIds let viewprotIds = this.viewprotIds
// let segmentationId = this.$guid(); // let segmentationId = this.$guid();
let obj = { let obj = {
name: this.$t('trials:reading:Segmentations:name:SegmentGroup') + (this.segmentList.length + 1), name: this.$t('trials:reading:Segmentations:name:SegmentGroup') + (this.segmentList.length + 1),
@ -721,14 +723,13 @@ export default {
await this.createSegmentation(obj.segmentationId) await this.createSegmentation(obj.segmentationId)
this.createSegmentationRepresentation(obj.segmentationId) this.createSegmentationRepresentation(obj.segmentationId)
this.segmentIndex = 1 this.segmentIndex = 1
this.changeColor(this.colors[0], { segmentationId: obj.segmentationId, segmentIndex: 1, color: this.colors[0] }) viewprotIds.forEach(id => {
// viewportIds.forEach(id => { segmentation.config.color.setSegmentIndexColor(id, obj.segmentationId, 1, this.hex2Rgb(this.colors[0]))
// segmentation.config.color.setSegmentIndexColor(id, obj.segmentationId, 1, this.hex2Rgb(this.colors[0])) })
// })
this.selectSegmentGroup() this.selectSegmentGroup()
}, },
async addSegment() { async addSegment() {
let viewportIds = this.viewportIds; let viewprotIds = this.viewprotIds;
if (this.segmentList.length <= 0) { if (this.segmentList.length <= 0) {
let obj = { let obj = {
name: this.$t('trials:reading:Segmentations:name:SegmentGroup') + 1, name: this.$t('trials:reading:Segmentations:name:SegmentGroup') + 1,
@ -758,11 +759,10 @@ export default {
this.createSegmentationRepresentation(this.segmentationId) this.createSegmentationRepresentation(this.segmentationId)
this.segmentIndex = 1 this.segmentIndex = 1
segmentation.segmentIndex.setActiveSegmentIndex(this.segmentList[0].segmentationId, 1); segmentation.segmentIndex.setActiveSegmentIndex(this.segmentList[0].segmentationId, 1);
this.changeColor(this.colors[0], { segmentationId: this.segmentList[0].segmentationId, segmentIndex: 1, color: this.colors[0] }) viewprotIds.forEach(id => {
// viewportIds.forEach(id => { segmentation.config.color.setSegmentIndexColor(id, this.segmentList[0].segmentationId, 1, this.hex2Rgb(this.colors[0]))
// segmentation.config.color.setSegmentIndexColor(id, this.segmentList[0].segmentationId, 1, this.hex2Rgb(this.colors[0])) })
// }) this.readingSegmentByConfig()
// this.readingSegmentByConfig()
} else { } else {
let item = this.segmentList.find(i => i.segmentationId === this.segmentationId) let item = this.segmentList.find(i => i.segmentationId === this.segmentationId)
@ -787,22 +787,19 @@ export default {
let id = await this.addOrUpdateSegment({ name: obj.SegmentLabel, color: obj.color, segmentIndex: obj.segmentIndex, segmentationId: obj.segmentationId }) let id = await this.addOrUpdateSegment({ name: obj.SegmentLabel, color: obj.color, segmentIndex: obj.segmentIndex, segmentationId: obj.segmentationId })
obj.id = id obj.id = id
item.segments.push(obj) item.segments.push(obj)
this.segmentIndex = obj.segmentIndex
segmentation.segmentIndex.setActiveSegmentIndex(obj.segmentationId, obj.segmentIndex); segmentation.segmentIndex.setActiveSegmentIndex(obj.segmentationId, obj.segmentIndex);
this.changeColor(obj.color, { segmentationId: obj.segmentationId, segmentIndex: obj.segmentIndex, color: obj.color }) viewprotIds.forEach(id => {
// viewportIds.forEach(id => { segmentation.config.color.setSegmentIndexColor(id, obj.segmentationId, obj.segmentIndex, this.hex2Rgb(obj.color))
// segmentation.config.color.setSegmentIndexColor(id, obj.segmentationId, obj.segmentIndex, this.hex2Rgb(obj.color)) })
// }) this.segmentIndex = obj.segmentIndex
} }
}, },
changeColor(e, item) { changeColor(e, item) {
DicomEvent.$emit('changeColor', item) this.viewprotIds.forEach(id => {
// this.viewportIds.forEach(id => { segmentation.config.color.setSegmentIndexColor(id, item.segmentationId, item.segmentIndex, this.hex2Rgb(e))
// segmentation.config.color.setSegmentIndexColor(id, item.segmentationId, item.segmentIndex, this.hex2Rgb(e)) })
// })
}, },
// //
delAllSegment(isChange) { delAllSegment(isChange) {
@ -839,7 +836,7 @@ export default {
} else { } else {
this.segmentationId = '' this.segmentationId = ''
} }
// this.readingSegmentByConfig() this.readingSegmentByConfig()
this.resetViewport() this.resetViewport()
this.$emit('resetQuestion') this.$emit('resetQuestion')
}, },
@ -871,7 +868,11 @@ export default {
}, },
resetViewport(passive = true) { resetViewport(passive = true) {
DicomEvent.$emit('resetViewport') let renderingEngine = getRenderingEngine(this.renderingEngineId)
this.viewprotIds.forEach(id => {
const viewport = renderingEngine.getViewport(id)
viewport.render()
})
if (passive) this.$emit('setToolsPassive') if (passive) this.$emit('setToolsPassive')
}, },
async rename(key, item) { async rename(key, item) {
@ -924,7 +925,7 @@ export default {
// //
changeInactiveSegmentShow() { changeInactiveSegmentShow() {
let segmentList = this.segmentList.filter(item => item.segmentationId !== this.segmentationId) let segmentList = this.segmentList.filter(item => item.segmentationId !== this.segmentationId)
this.viewportIds.forEach(id => { this.viewprotIds.forEach(id => {
segmentation.config.visibility.setSegmentationRepresentationVisibility( segmentation.config.visibility.setSegmentationRepresentationVisibility(
id, id,
{ {
@ -966,118 +967,113 @@ export default {
this.exportSegmentation(this.segmentationId, group, true) this.exportSegmentation(this.segmentationId, group, true)
}, },
exportSegmentation(segmentationId, group, isFile = false) { exportSegmentation(segmentationId, group, isFile = false) {
try { const segmentationIds = segmentation.state
const segmentationIds = segmentation.state .getSegmentations()
.getSegmentations() .map(x => x.segmentationId);
.map(x => x.segmentationId); if (!segmentationIds.length) {
if (!segmentationIds.length) { return;
return; }
} const segmentGroup =
const segmentGroup = segmentation.state.getSegmentation(segmentationId);
segmentation.state.getSegmentation(segmentationId);
let { imageIds } = segmentGroup.representationData.Labelmap; let { imageIds } = segmentGroup.representationData.Labelmap;
let segImages = imageIds.map(imageId => cache.getImage(imageId)); let segImages = imageIds.map(imageId => cache.getImage(imageId));
segImages = segImages.reverse() segImages = segImages.reverse()
let referencedImages = segImages.map(image => let referencedImages = segImages.map(image =>
cache.getImage(image.referencedImageId) cache.getImage(image.referencedImageId)
); );
const labelmaps2D = []; const labelmaps2D = [];
let z = 0; let z = 0;
for (const segImage of segImages) { for (const segImage of segImages) {
const segmentsOnLabelmap = new Set(); const segmentsOnLabelmap = new Set();
const pixelData = segImage.getPixelData(); const pixelData = segImage.getPixelData();
const { rows, columns } = segImage; const { rows, columns } = segImage;
for (let i = 0; i < pixelData.length; i++) { for (let i = 0; i < pixelData.length; i++) {
const segment = pixelData[i]; const segment = pixelData[i];
if (segment !== 0) { if (segment !== 0) {
segmentsOnLabelmap.add(segment); segmentsOnLabelmap.add(segment);
}
} }
labelmaps2D[z++] = {
segmentsOnLabelmap: Array.from(segmentsOnLabelmap),
pixelData,
rows,
columns
};
} }
const allSegmentsOnLabelmap = labelmaps2D.map( labelmaps2D[z++] = {
labelmap => labelmap.segmentsOnLabelmap segmentsOnLabelmap: Array.from(segmentsOnLabelmap),
); pixelData,
rows,
const labelmap3D = { columns
segmentsOnLabelmap: Array.from(new Set(allSegmentsOnLabelmap.flat())),
metadata: [],
labelmaps2D
}; };
let segmentIndexs = []
labelmap3D.segmentsOnLabelmap.forEach(segmentIndex => {
const color = segmentation.config.color.getSegmentIndexColor(
`${this.viewportKey}-${this.activeViewportIndex}`,
segmentationId,
segmentIndex
);
const RecommendedDisplayCIELabValue = dcmjs.data.Colors.rgb2DICOMLAB(
color.slice(0, 3).map(value => value / 255)
).map(value => Math.round(value));
let segment = group.segments.find(item => item.segmentIndex === segmentIndex)
if (segment) {
segmentIndexs.push(segmentIndex)
let SegmentLabel = segment.SegmentLabel
const segmentMetadata = {
SegmentNumber: segmentIndex.toString(),
SegmentLabel: SegmentLabel,
SegmentAlgorithmType: "MANUAL",
SegmentAlgorithmName: "OHIF Brush",
RecommendedDisplayCIELabValue,
SegmentedPropertyCategoryCodeSequence: {
CodeValue: "T-D0050",
CodingSchemeDesignator: "SRT",
CodeMeaning: "Tissue"
},
SegmentedPropertyTypeCodeSequence: {
CodeValue: "T-D0050",
CodingSchemeDesignator: "SRT",
CodeMeaning: "Tissue"
}
};
if (segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata;
}
});
if (labelmap3D.metadata.length <= 0) {
return false
}
const generatedSegmentation =
Cornerstone3D.Segmentation.generateSegmentation(
referencedImages,
labelmap3D,
metaData
);
segmentIndexs.forEach((item, index) => {
if (generatedSegmentation.dataset.SegmentSequence[index]) {
generatedSegmentation.dataset.SegmentSequence[index].SegmentNumber = item.toString()
}
})
generatedSegmentation.dataset.SegmentSequence.sort((a, b) => a.SegmentNumber - b.SegmentNumber)
if (!isFile) {
const buffer = Buffer.from(dcmjs.data.datasetToDict(generatedSegmentation.dataset).write());
let blob = new Blob([buffer], { type: "application/dicom" });
return blob
} else {
this.downloadDICOMData(generatedSegmentation.dataset, `${group.name}.dcm`);
}
} catch (err) {
console.log(err)
} }
const allSegmentsOnLabelmap = labelmaps2D.map(
labelmap => labelmap.segmentsOnLabelmap
);
const labelmap3D = {
segmentsOnLabelmap: Array.from(new Set(allSegmentsOnLabelmap.flat())),
metadata: [],
labelmaps2D
};
let segmentIndexs = []
labelmap3D.segmentsOnLabelmap.forEach(segmentIndex => {
const color = segmentation.config.color.getSegmentIndexColor(
`${this.viewportKey}-${this.activeViewportIndex}`,
segmentationId,
segmentIndex
);
const RecommendedDisplayCIELabValue = dcmjs.data.Colors.rgb2DICOMLAB(
color.slice(0, 3).map(value => value / 255)
).map(value => Math.round(value));
let segment = group.segments.find(item => item.segmentIndex === segmentIndex)
if (segment) {
segmentIndexs.push(segmentIndex)
let SegmentLabel = segment.SegmentLabel
const segmentMetadata = {
SegmentNumber: segmentIndex.toString(),
SegmentLabel: SegmentLabel,
SegmentAlgorithmType: "MANUAL",
SegmentAlgorithmName: "OHIF Brush",
RecommendedDisplayCIELabValue,
SegmentedPropertyCategoryCodeSequence: {
CodeValue: "T-D0050",
CodingSchemeDesignator: "SRT",
CodeMeaning: "Tissue"
},
SegmentedPropertyTypeCodeSequence: {
CodeValue: "T-D0050",
CodingSchemeDesignator: "SRT",
CodeMeaning: "Tissue"
}
};
if (segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata;
}
});
if (labelmap3D.metadata.length <= 0) {
return false
}
const generatedSegmentation =
Cornerstone3D.Segmentation.generateSegmentation(
referencedImages,
labelmap3D,
metaData
);
segmentIndexs.forEach((item, index) => {
if (generatedSegmentation.dataset.SegmentSequence[index]) {
generatedSegmentation.dataset.SegmentSequence[index].SegmentNumber = item.toString()
}
})
generatedSegmentation.dataset.SegmentSequence.sort((a, b) => a.SegmentNumber - b.SegmentNumber)
if (!isFile) {
const buffer = Buffer.from(dcmjs.data.datasetToDict(generatedSegmentation.dataset).write());
let blob = new Blob([buffer], { type: "application/dicom" });
return blob
} else {
this.downloadDICOMData(generatedSegmentation.dataset, `${group.name}.dcm`);
}
}, },
downloadDICOMData(bufferOrDataset, filename) { downloadDICOMData(bufferOrDataset, filename) {
let blob; let blob;
@ -1127,7 +1123,7 @@ export default {
const arrayBuffer = image.data.byteArray.buffer; const arrayBuffer = image.data.byteArray.buffer;
await this.loadSegmentation(arrayBuffer, obj.segmentationId); await this.loadSegmentation(arrayBuffer, obj.segmentationId);
// this.createSegmentationRepresentation(obj.segmentationId); this.createSegmentationRepresentation(obj.segmentationId);
}, },
async loadSegmentation(arrayBuffer, segmentationId) { async loadSegmentation(arrayBuffer, segmentationId) {
const generateToolState = const generateToolState =
@ -1310,49 +1306,51 @@ export default {
} }
}, },
createSegmentationRepresentation(segmentationId) { createSegmentationRepresentation(segmentationId) {
DicomEvent.$emit('createSegmentationRepresentation', segmentationId) this.viewprotIds.forEach(id => {
segmentation.addSegmentationRepresentations(id, [
{
segmentationId,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
},
])
})
this.$emit('setToolsPassive') this.$emit('setToolsPassive')
}, },
contentMouseup() { contentMouseup() {
try { // console.log("segment contentMouseup")
// console.log("segment contentMouseup") if (!this.drawing) return false
if (!this.drawing) return false if (this.timeoutId) {
if (this.timeoutId) { clearTimeout(this.timeoutId);
clearTimeout(this.timeoutId); this.timeoutId = null;
this.timeoutId = null;
}
this.timeoutId = setTimeout(() => {
this.timeoutId = null;
this.drawing = false;
let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
if (segmentGroup && segmentGroup.segments && segmentGroup.segments.length > 0) {
let segmentIndexs = []
segmentGroup.segments.forEach(item => {
segmentIndexs.push(item.segmentIndex)
item.bidirectional = null
item.stats = null
})
annotation.state.getAllAnnotations().forEach(i => {
if (i.metadata.segmentationId === this.segmentationId && i.metadata.toolName === "SegmentBidirectional") {
annotation.state.removeAnnotation(i.annotationUID)
}
})
this.calculateStatistics(segmentIndexs, this.segmentationId, 'individual');
this.resetViewport(false)
// this.getBidirectional(segmentGroup.segments)
}
}, 500);
} catch (err) {
console.log(err)
} }
this.timeoutId = setTimeout(() => {
this.timeoutId = null;
this.drawing = false;
let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
if (segmentGroup && segmentGroup.segments && segmentGroup.segments.length > 0) {
let segmentIndexs = []
segmentGroup.segments.forEach(item => {
segmentIndexs.push(item.segmentIndex)
item.bidirectional = null
item.stats = null
})
annotation.state.getAllAnnotations().forEach(i => {
if (i.metadata.segmentationId === this.segmentationId && i.metadata.toolName === "SegmentBidirectional") {
annotation.state.removeAnnotation(i.annotationUID)
}
})
this.calculateStatistics(segmentIndexs, this.segmentationId, 'individual');
this.resetViewport(false)
// this.getBidirectional(segmentGroup.segments)
}
}, 500);
}, },
// //
async getSegmentBindingList(param = {}) { async getSegmentBindingList(param = {}) {
try { try {
let data = { let data = {
VisitTaskId: this.series.TaskInfo.VisitTaskId, VisitTaskId: this.visitInfo.VisitTaskId,
PageSize: 9999, PageSize: 9999,
PageIndex: 1, PageIndex: 1,
} }
@ -1369,7 +1367,7 @@ export default {
async saveSegmentBindingAndAnswer(list) { async saveSegmentBindingAndAnswer(list) {
try { try {
let data = { let data = {
VisitTaskId: this.series.TaskInfo.VisitTaskId, VisitTaskId: this.visitInfo.VisitTaskId,
BindingList: list BindingList: list
} }
let res = await saveSegmentBindingAndAnswer(data) let res = await saveSegmentBindingAndAnswer(data)
@ -1484,7 +1482,7 @@ export default {
let bidirectional = bidirectionalData[0] let bidirectional = bidirectionalData[0]
const { segmentIndex } = bidirectional; const { segmentIndex } = bidirectional;
const { majorAxis, minorAxis } = bidirectional; const { majorAxis, minorAxis, maxMajor, maxMinor } = bidirectional;
let item = list.find(i => i.segmentIndex === segmentIndex) let item = list.find(i => i.segmentIndex === segmentIndex)
SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], { SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], {
segmentIndex, segmentIndex,
@ -1493,7 +1491,7 @@ export default {
let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional"); let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
if (an) { if (an) {
annotation.locking.setAnnotationLocked(an.annotationUID, true) annotation.locking.setAnnotationLocked(an.annotationUID, true)
annotation.visibility.setAnnotationVisibility(an.annotationUID, true) annotation.visibility.setAnnotationVisibility(an.annotationUID, item.bidirectionalView)
} }
item.bidirectional = bidirectional item.bidirectional = bidirectional
reslove(true) reslove(true)
@ -1538,7 +1536,7 @@ export default {
SegmentId: item.SegmentId, SegmentId: item.SegmentId,
SegmentationId: item.SegmentationId, SegmentationId: item.SegmentationId,
TableQuestionId: item.TableQuestionId, TableQuestionId: item.TableQuestionId,
VisitTaskId: this.series.TaskInfo.VisitTaskId, VisitTaskId: this.visitInfo.VisitTaskId,
} }
bindingList.push(o) bindingList.push(o)
} }
@ -1556,7 +1554,7 @@ export default {
SubjectId: this.visitInfo.SubjectId, SubjectId: this.visitInfo.SubjectId,
SubjectVisitId: this.visitInfo.VisistId, SubjectVisitId: this.visitInfo.VisistId,
TrialId: this.$route.query.trialId, TrialId: this.$route.query.trialId,
VisitTaskId: this.series.TaskInfo.VisitTaskId, VisitTaskId: this.visitInfo.VisitTaskId,
} }
if (url) data.SegUrl = url; if (url) data.SegUrl = url;
if (id) data.Id = id; if (id) data.Id = id;
@ -1576,7 +1574,7 @@ export default {
try { try {
let data = { let data = {
SeriesId: this.series.Id, SeriesId: this.series.Id,
VisitTaskId: this.series.TaskInfo.VisitTaskId, VisitTaskId: this.visitInfo.VisitTaskId,
PageSize: 9999, PageSize: 9999,
PageIndex: 1, PageIndex: 1,
} }
@ -1585,8 +1583,6 @@ export default {
this.loading = false; this.loading = false;
if (res.IsSuccess) { if (res.IsSuccess) {
this.segmentList = [] this.segmentList = []
this.segmentationId = null;
this.segmentIndex = null;
let list = res.Result.CurrentPageData; let list = res.Result.CurrentPageData;
for (let i = 0; i < list.length; i++) { for (let i = 0; i < list.length; i++) {
let item = list[i] let item = list[i]
@ -1601,12 +1597,12 @@ export default {
segments: [] segments: []
} }
this.segmentList.push(obj) this.segmentList.push(obj)
// if (item.SEGUrl) { if (item.SEGUrl) {
// await this.readSegmentation(obj) await this.readSegmentation(obj)
// } else { } else {
// await this.createSegmentation(obj.segmentationId) await this.createSegmentation(obj.segmentationId)
// // this.createSegmentationRepresentation(obj.segmentationId) this.createSegmentationRepresentation(obj.segmentationId)
// } }
} }
if (!this.segmentationId) { if (!this.segmentationId) {
this.segmentationId = obj.segmentationId this.segmentationId = obj.segmentationId
@ -1625,41 +1621,45 @@ export default {
bidirectional: SegmentJson.bidirectional, bidirectional: SegmentJson.bidirectional,
bidirectionalView: true, bidirectionalView: true,
view: true, view: true,
lock: true, lock: item.locked,
id: s.Id id: s.Id
} }
obj.segments.push(o) obj.segments.push(o)
// this.selectSegment(o, false) this.selectSegment(o, false)
// this.changeColor(s.ColorRgb, o) this.changeColor(s.ColorRgb, o)
// this.lockSegment(o, true) this.lockSegment(o, true)
} }
if (!this.segmentIndex) { if (!this.segmentIndex) {
this.segmentIndex = s.SegmentNumber this.segmentIndex = s.SegmentNumber
} }
}) })
// this.$nextTick(() => { this.$nextTick(() => {
// if (SEGMENT) { if (SEGMENT) {
// // console.log(SEGMENT, 'SEGMENT') // console.log(SEGMENT, 'SEGMENT')
// return this.getBidirectional(obj.segments, SEGMENT) return this.getBidirectional(obj.segments, SEGMENT)
// } }
// this.getBidirectional(obj.segments, null, false) this.getBidirectional(obj.segments, null, false)
// }) })
}
if (this.segmentationId && this.segmentIndex && this.segmentList && this.segmentList.length > 0) {
let o = this.segmentList.find(item => item.segmentationId === this.segmentationId)
if (o) {
let s = o.segments.find(item => item.segmentIndex === this.segmentIndex)
this.selectSegmentGroup(s)
} else {
this.segmentationId = this.segmentList[0].segmentationId
this.segmentIndex = this.segmentationId ? this.segmentList[0].segments[0].segmentIndex : null
if (this.segmentationId && this.segmentIndex) {
this.selectSegmentGroup(this.segmentList[0].segments[0])
}
}
// console.log(segment, 'segment')
// this.selectSegment(segment)
} }
// if (this.segmentationId && this.segmentIndex && this.segmentList && this.segmentList.length > 0) {
// let o = this.segmentList.find(item => item.segmentationId === this.segmentationId)
// if (o) {
// let s = o.segments.find(item => item.segmentIndex === this.segmentIndex)
// this.selectSegmentGroup(s)
// } else {
// this.segmentationId = this.segmentList[0].segmentationId
// this.segmentIndex = this.segmentationId ? this.segmentList[0].segments[0].segmentIndex : null
// if (this.segmentationId && this.segmentIndex) {
// this.selectSegmentGroup(this.segmentList[0].segments[0])
// }
// }
// }
this.isloaded = false this.isloaded = false
// this.readingSegmentByConfig() this.readingSegmentByConfig()
} }
} catch (err) { } catch (err) {
this.loading = false this.loading = false
@ -1688,7 +1688,7 @@ export default {
SegmentName: name, SegmentName: name,
SegmentNumber: segmentIndex, SegmentNumber: segmentIndex,
SegmentationId: segmentationId, SegmentationId: segmentationId,
VisitTaskId: this.series.TaskInfo.VisitTaskId, VisitTaskId: this.visitInfo.VisitTaskId,
SegmentJson: segmentJson SegmentJson: segmentJson
} }
if (id) data.Id = id if (id) data.Id = id

View File

@ -14,25 +14,6 @@
<div v-if="imageInfo.total">Image: #{{ `${series.SliceIndex + 1}/${imageInfo.total}` }}</div> <div v-if="imageInfo.total">Image: #{{ `${series.SliceIndex + 1}/${imageInfo.total}` }}</div>
<div>{{ series.Modality }}</div> <div>{{ series.Modality }}</div>
</div> </div>
<div v-if="series && taskInfo && taskInfo.IsReadingTaskViewInOrder === 1" class="top-center-tool">
<div class="toggle-visit-container">
<div class="arrw_icon"
:style="{ cursor: series.TaskInfo && series.TaskInfo.VisitTaskNum !== 0 ? 'pointer' : 'not-allowed', color: series.TaskInfo && series.TaskInfo.VisitTaskNum !== 0 ? '#fff' : '#6b6b6b' }"
@click.stop.prevent="toggleTask($event, series.TaskInfo.VisitTaskNum, -1)"
@dblclick.stop="preventDefault($event)">
<i class="el-icon-caret-left" />
</div>
<div class="arrow_text">
{{ series.TaskInfo ? series.TaskInfo.TaskBlindName : '' }}
</div>
<div class="arrw_icon"
:style="{ cursor: series.TaskInfo && series.TaskInfo.VisitTaskNum < taskInfo.VisitNum ? 'pointer' : 'not-allowed', color: series.TaskInfo && series.TaskInfo.VisitTaskNum < taskInfo.VisitNum ? '#fff' : '#6b6b6b' }"
@click.stop.prevent="toggleTask($event, series.TaskInfo.VisitTaskNum, 1)"
@dblclick.stop="preventDefault($event)">
<i class="el-icon-caret-right" />
</div>
</div>
</div>
<div v-if="series" class="right-top-text"> <div v-if="series" class="right-top-text">
<div>{{ series.Description }}</div> <div>{{ series.Description }}</div>
</div> </div>
@ -59,10 +40,10 @@
<div v-if="series" class="right-bottom-text"> <div v-if="series" class="right-bottom-text">
<div v-show="imageInfo.location">Location: {{ <div v-show="imageInfo.location">Location: {{
`${Number(imageInfo.location).toFixed(digitPlaces)} mm` `${Number(imageInfo.location).toFixed(digitPlaces)} mm`
}}</div> }}</div>
<div v-show="imageInfo.sliceThickness">Slice Thickness: {{ <div v-show="imageInfo.sliceThickness">Slice Thickness: {{
`${Number(imageInfo.sliceThickness).toFixed(digitPlaces)} mm` `${Number(imageInfo.sliceThickness).toFixed(digitPlaces)} mm`
}}</div> }}</div>
<div v-show="imageInfo.wwwc">WW/WL: {{ imageInfo.wwwc }}</div> <div v-show="imageInfo.wwwc">WW/WL: {{ imageInfo.wwwc }}</div>
</div> </div>
<div class="orientation-top"> <div class="orientation-top">
@ -102,19 +83,6 @@ import {
setPetTransferFunctionForVolumeActor setPetTransferFunctionForVolumeActor
} from './helpers/index.js' } from './helpers/index.js'
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent' import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
import {
renderSegmentation,
readingSegmentByConfig,
selectSegmentation,
selectSegment,
createSegmentationRepresentation,
viewSegmentation,
viewSegment,
jumpBidirectional,
viewBidirectional,
changeColor,
resetViewport
} from "./helpers/segmentations"
export default { export default {
name: 'MPRViewport', name: 'MPRViewport',
props: { props: {
@ -133,32 +101,6 @@ export default {
histogramVisible: { histogramVisible: {
type: Boolean, type: Boolean,
default: false default: false
},
actionConfiguration: {
type: Object,
default: () => {
return {}
}
},
SegmentConfig: {
type: Object,
default: () => {
return {}
}
},
curSegSeries: {
type: Object,
default: () => {
return {}
}
},
segmentIndex: {
type: Number,
default: 0
},
segmentationId: {
type: String,
default: ''
} }
}, },
data() { data() {
@ -212,39 +154,6 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.initViewport() this.initViewport()
}) })
DicomEvent.$on('createSegmentationRepresentation', (segmentationId) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
createSegmentationRepresentation(this.viewportId, segmentationId)
})
DicomEvent.$on('viewSegmentation', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
viewSegmentation(obj, this.viewportId)
})
DicomEvent.$on('viewSegment', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
viewSegment(obj, this.viewportId)
})
DicomEvent.$on('jumpBidirectional', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
jumpBidirectional(obj, this.viewportId, this.volumeId)
})
DicomEvent.$on('viewBidirectional', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
viewBidirectional(obj, this.viewportId)
})
DicomEvent.$on('changeColor', (obj) => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
changeColor(obj, this.viewportId)
})
DicomEvent.$on('resetViewport', () => {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
resetViewport(this.viewportId)
})
DicomEvent.$on('renderSegmentation', async (viewportId) => {
// if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
if (this.viewportId !== viewportId) return false
await renderSegmentation(this.series, this.series.TaskInfo, this.viewportId, this.SegmentConfig, this.segmentationId, this.segmentIndex, this.renderingEngineId, null, this.actionConfiguration)
})
}, },
watch: { watch: {
MPRInfo: { MPRInfo: {
@ -263,25 +172,6 @@ export default {
} }
}, },
deep: true deep: true
},
SegmentConfig: {
handler() {
if (!this.segmentationId) return false
if (!this.series.TaskInfo) return false
readingSegmentByConfig(this.series, this.series.TaskInfo, this.viewportId, this.segmentationId, this.SegmentConfig)
},
deep: true
},
segmentIndex() {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
if (this.segmentIndex <= 0) return false
selectSegment(this.viewportId, this.segmentationId, this.segmentIndex)
},
segmentationId() {
if (this.curSegSeries.Id !== this.series.Id || this.curSegSeries.VisitTaskId !== this.series.VisitTaskId) return false
if (!this.segmentationId) return false
selectSegmentation(this.viewportId, this.segmentationId)
readingSegmentByConfig(this.series, this.series.TaskInfo, this.viewportId, this.segmentationId, this.SegmentConfig)
} }
}, },
methods: { methods: {
@ -659,9 +549,13 @@ export default {
console.log("渲染成功") console.log("渲染成功")
} }
}]).then(r => { }]).then(r => {
if (data.segment) {
return DicomEvent.$emit("isloaded", { segment: data.segment, isChange: data.isChange })
}
if (data.isLocation) { if (data.isLocation) {
setTimeout(() => { csUtils.jumpToSlice(viewport.element, { imageIndex: data.SliceIndex }); }) setTimeout(() => { csUtils.jumpToSlice(viewport.element, { imageIndex: data.SliceIndex }); })
} }
DicomEvent.$emit("isloaded", { isChange: data.isChange })
}) })
viewport.render() viewport.render()
if (this.series.Modality === 'PT' || this.series.Modality === 'NM') { if (this.series.Modality === 'PT' || this.series.Modality === 'NM') {
@ -673,10 +567,11 @@ export default {
renderingEngine.render() renderingEngine.render()
}, 100) }, 100)
} }
await renderSegmentation(this.series, this.series.TaskInfo, this.viewportId, this.SegmentConfig, this.segmentationId, this.segmentIndex, this.renderingEngineId, data.segment, this.actionConfiguration)
} catch (e) { } catch (e) {
console.log(e) console.log(e)
} }
}, },
cornerstoneToolsMouseMove(e) { cornerstoneToolsMouseMove(e) {
const { currentPoints } = e.detail const { currentPoints } = e.detail

View File

@ -1,430 +0,0 @@
import * as cornerstoneTools from '@cornerstonejs/tools';
import * as cornerstone from "@cornerstonejs/core";
import dcmjs from '@/utils/dcmUpload/dcmjs'
import * as cornerstoneAdapters from "@cornerstonejs/adapters";
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'
import * as polySeg from '@cornerstonejs/polymorphic-segmentation'
cornerstoneTools.init({ addons: { polySeg } })
import { getSegmentationList, getSegmentList } from '@/api/reading'
import Vue from 'vue'
const {
ToolGroupManager,
Enums: csToolsEnums,
segmentation,
annotation,
LabelMapEditWithContourTool,
SegmentBidirectionalTool,
CrosshairsTool,
utilities: CStUtils,
} = cornerstoneTools;
const { MouseBindings, Events: toolsEvents } = csToolsEnums
const { segmentation: segmentationUtils } = CStUtils;
const { cache, getRenderingEngine, imageLoader, eventTarget, metaData, utilities: csUtils, volumeLoader } = cornerstone;
const { Cornerstone3D } = cornerstoneAdapters.adaptersSEG;
let viewportInfo = {}
let renderingEngineId = null
async function createSegmentation(toolGroupId, volumeId, segmentationId) {
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId) || ToolGroupManager.getToolGroup('share-viewport-volume')
toolGroup.setToolActive(
LabelMapEditWithContourTool.toolName,
);
if (!cache.getVolume(segmentationId)) {
await volumeLoader.createAndCacheDerivedLabelmapVolume(
volumeId,
{
volumeId: segmentationId
}
)
}
if (!segmentation.state.getSegmentation(segmentationId)) {
segmentation.addSegmentations([
{
segmentationId,
representation: {
type: cornerstoneTools.Enums.SegmentationRepresentations
.Labelmap,
data: {
volumeId: segmentationId
}
}
}
]);
}
}
async function createSegmentationRepresentation(viewportId, segmentationId) {
segmentation.addSegmentationRepresentations(viewportId, [
{
segmentationId,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
},
])
}
async function readSegmentation(obj, series, segmentationId, isFile = false) {
let imageId = null
if (isFile) {
imageId = cornerstoneDICOMImageLoader.wadouri.fileManager.add(obj);
} else {
const imageIdObj = await cornerstoneDICOMImageLoader.wadouri.loadImage(`wadouri:${Vue.prototype.OSSclientConfig.basePath}${obj}`).promise
imageId = imageIdObj.imageId
}
const image = await imageLoader.loadAndCacheImage(imageId);
if (!image) {
return;
}
const instance = metaData.get("instance", imageId);
if (instance.Modality !== "SEG") {
console.error("This is not segmentation: " + file.name);
return;
}
const arrayBuffer = image.data.byteArray.buffer;
await loadSegmentation(arrayBuffer, series, segmentationId);
}
async function loadSegmentation(arrayBuffer, series, segmentationId) {
const generateToolState =
await Cornerstone3D.Segmentation.generateToolState(
series.ImageIds,
arrayBuffer,
metaData,
);
if (generateToolState.labelmapBufferArray.length !== 1) {
alert(
"Overlapping segments in your segmentation are not supported yet. You can turn on the skipOverlapping option but it will override the overlapping segments."
);
return;
}
// await createSegmentation(segmentationId);
let arr = []
generateToolState.segMetadata.data.forEach(item => {
if (item) {
let Target = JSON.parse(JSON.stringify(item))
arr.push(Target)
}
})
let mapping = {}
arr.forEach((item, index) => {
mapping[index + 1] = Number(item.SegmentNumber)
})
const megmentGroup =
segmentation.state.getSegmentation(segmentationId);
const { imageIds } = megmentGroup.representationData.Labelmap;
const derivedSegmentationImages = imageIds.map(imageId =>
cache.getImage(imageId)
);
const volumeScalarData = new Uint8Array(
generateToolState.labelmapBufferArray[0]
);
const remappedData = new Uint8Array(volumeScalarData.length);
for (let i = 0; i < volumeScalarData.length; i++) {
const value = volumeScalarData[i];
remappedData[i] = value === 0 ? 0 : (mapping[value] ? mapping[value] : value);
}
for (let i = 0; i < derivedSegmentationImages.length; i++) {
const voxelManager = derivedSegmentationImages[i].voxelManager;
const scalarData = voxelManager.getScalarData();
scalarData.set(
remappedData.slice(
i * scalarData.length,
(i + 1) * scalarData.length
)
);
voxelManager.setScalarData(scalarData);
}
}
function hex2Rgb(hexValue, alpha = 1) {
const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
const hex = hexValue.replace(rgx, (m, r, g, b) => r + r + g + g + b + b);
const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
if (!rgb) {
return hexValue;
}
const r = parseInt(rgb[1], 16),
g = parseInt(rgb[2], 16),
b = parseInt(rgb[3], 16);
return [r, g, b, alpha * 255];
}
function removeSegmentFromViewport(viewportId) {
return new Promise(resolve => {
if (viewportInfo[viewportId] && viewportInfo[viewportId].length > 0) {
viewportInfo[viewportId].forEach(async segmentationId => {
segmentation.removeSegmentation(segmentationId)
segmentation.state.removeSegmentation(segmentationId)
let annotations = annotation.state.getAllAnnotations().filter(item => item.metadata.segmentationId && segmentationId === item.metadata.segmentationId && item.metadata.segmentIndex && item.metadata.toolName === "SegmentBidirectional");
annotations.forEach(item => {
annotation.state.removeAnnotation(item.annotationUID)
})
})
}
viewportInfo[viewportId] = []
resolve(true)
})
}
function createSegmentConfiguration(segmentIndex, segmentationId, viewportId, actionConfiguration, otherSegments) {
const containedSegmentIndices = otherSegments
? { has: (segmentIndex) => otherSegments.indexOf(segmentIndex) !== -1 }
: undefined;
const colorConfig = segmentation.config.color.getSegmentIndexColor(
viewportId,
segmentationId,
segmentIndex
);
// Allow null style to skip style set
let color, activeColor;
if (colorConfig?.length) {
color = `rgb(${colorConfig.join(',')})`;
activeColor = color;
}
const style = {
color,
colorHighlightedActive: activeColor,
colorActive: activeColor,
textBoxColor: color,
textBoxColorActive: activeColor,
textBoxColorHighlightedActive: activeColor,
};
const label = otherSegments
? `Combined ${segmentIndex} with ${otherSegments.join(', ')}`
: `Segment ${segmentIndex}`;
actionConfiguration.contourBidirectional.data.segmentData.set(segmentIndex, {
containedSegmentIndices,
label,
style,
});
actionConfiguration.contourBidirectional.data.segmentationId = segmentationId
actionConfiguration.contourBidirectional.data.segmentIndex = segmentIndex
}
async function readingSegmentByConfig(series, visitInfo, viewportId, segmentationId, SegmentConfig) {
let data = {
SeriesId: series.Id,
VisitTaskId: visitInfo.VisitTaskId,
PageSize: 9999,
PageIndex: 1,
}
let res = await getSegmentationList(data);
if (res.IsSuccess) {
let list = res.Result.CurrentPageData;
changeInactiveSegmentShow(list, viewportId, segmentationId, SegmentConfig)
}
segmentation.config.style.setStyle(
{
type: csToolsEnums.SegmentationRepresentations.Labelmap,
},
{
renderFill: SegmentConfig.renderFill,
renderOutline: SegmentConfig.renderOutline,
outlineWidth: Number(SegmentConfig.outlineWidth),
fillAlpha: Number(SegmentConfig.fillAlpha),
}
)
}
function selectSegmentation(viewportId, segmentationId) {
segmentation.activeSegmentation.setActiveSegmentation(viewportId, segmentationId)
}
function selectSegment(viewportId, segmentationId, segmentIndex) {
selectSegmentation(viewportId, segmentationId)
segmentation.segmentIndex.setActiveSegmentIndex(segmentationId, segmentIndex);
}
async function changeInactiveSegmentShow(list, viewportId, segmentationId, SegmentConfig) {
let segmentList = list
segmentList.forEach(segment => {
segmentation.config.visibility.setSegmentationRepresentationVisibility(
viewportId,
{
segmentationId: segment.Id,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
},
SegmentConfig.InactiveSegmentations.show
);
})
segmentation.config.visibility.setSegmentationRepresentationVisibility(
viewportId,
{
segmentationId: segmentationId,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
},
true
);
let arr = []
for (let i = 0; i < segmentList.length; i++) {
let item = segmentList[i]
let params = {
SegmentationId: item.Id,
PageSize: 9999,
PageIndex: 1,
}
let r = await getSegmentList(params)
if (r.IsSuccess) {
let segments = r.Result.CurrentPageData
segments.forEach(s => {
let obj = {
segmentationId: item.Id,
segmentIndex: s.SegmentNumber,
view: SegmentConfig.InactiveSegmentations.show
}
if (item.Id === segmentationId) {
obj.view = true
}
arr.push(obj)
})
}
}
viewBidirectional(arr, viewportId)
}
function viewSegmentation(item, viewportId) {
segmentation.config.visibility.setSegmentationRepresentationVisibility(
viewportId,
{
segmentationId: item.segmentationId,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
},
item.view
);
viewBidirectional(item.segments, viewportId)
}
async function jumpBidirectional(item, viewportId, volumeId) {
// DicomEvent.$emit('jumpBidirectional', item)
if (item.bidirectional) {
let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
console.log(an, 'an')
if (!an) return false
const renderingEngine = getRenderingEngine(renderingEngineId)
const viewport = renderingEngine.getViewport(viewportId)
let key = Object.keys(an.data.cachedStats)[0]; // referencedImageId
if (key) {
let sliceIndex = key.split("?")[1].split("&")[0].split("=")[1]
csUtils.jumpToSlice(viewport.element, { imageIndex: sliceIndex });
} else {
const points = an.data.handles.points;
const worldPoint = points[0]; // 取一个点
let volume = cache.getVolume(volumeId)
let { imageData, numFrames } = volume
const ijk = imageData.worldToIndex(worldPoint);
const sliceIndex = Math.abs(Math.round(ijk[2]));
// console.log(sliceIndex, 'sliceIndex')
csUtils.jumpToSlice(viewport.element, { imageIndex: numFrames - sliceIndex - 1 });
}
}
}
function viewSegment(item, viewportId) {
segmentation.config.visibility.setSegmentIndexVisibility(viewportId, {
segmentationId: item.segmentationId,
type: csToolsEnums.SegmentationRepresentations.Labelmap,
}, item.segmentIndex, item.view)
viewBidirectional([item], viewportId)
}
function viewBidirectional(arr, viewportId) {
for (let j = 0; j < arr.length; j++) {
let item = arr[j]
let bidirectional = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
// item.bidirectionalView = view
if (!bidirectional) continue
annotation.visibility.setAnnotationVisibility(bidirectional.annotationUID, item.view)
}
resetViewport(viewportId)
}
function resetViewport(viewportId) {
let renderingEngine = getRenderingEngine(renderingEngineId)
const viewport = renderingEngine.getViewport(viewportId)
viewport.render()
}
function changeColor(item, viewportId) {
segmentation.config.color.setSegmentIndexColor(viewportId, item.segmentationId, item.segmentIndex, hex2Rgb(item.color))
}
async function renderSegmentation(series, visitInfo, viewportId, SegmentConfig, segmentationId, segmentIndex, RenderingEngineId, Segment = null, actionConfiguration) {
try {
// console.log(segmentation, 'segmentation')
renderingEngineId = RenderingEngineId
await removeSegmentFromViewport(viewportId)
let data = {
SeriesId: series.Id,
VisitTaskId: visitInfo.VisitTaskId,
PageSize: 9999,
PageIndex: 1,
}
let res = await getSegmentationList(data);
if (res.IsSuccess) {
let list = res.Result.CurrentPageData;
for (let i = 0; i < list.length; i++) {
let item = list[i]
await createSegmentation(viewportId, series.SeriesInstanceUid, item.Id)
if (item.SEGUrl) await readSegmentation(item.SEGUrl, series, item.Id)
createSegmentationRepresentation(viewportId, item.Id)
if (!viewportInfo[viewportId]) {
viewportInfo[viewportId] = [item.Id]
} else {
viewportInfo[viewportId].push(item.Id)
}
let params = {
SegmentationId: item.Id,
PageSize: 9999,
PageIndex: 1,
}
let r = await getSegmentList(params)
if (r.IsSuccess) {
let segments = r.Result.CurrentPageData
segments.forEach(s => {
let SegmentJson = s.SegmentJson ? JSON.parse(s.SegmentJson) : {};
segmentation.segmentIndex.setActiveSegmentIndex(s.SegmentationId, s.SegmentNumber);
segmentation.config.color.setSegmentIndexColor(viewportId, s.SegmentationId, s.SegmentNumber, hex2Rgb(s.ColorRgb))
segmentation.segmentLocking.setSegmentIndexLocked(s.SegmentationId, s.SegmentNumber, true)
if (SegmentJson.bidirectional) {
let { majorAxis, minorAxis } = SegmentJson.bidirectional
// createSegmentConfiguration(s.SegmentNumber, s.SegmentationId, viewportId, actionConfiguration)
SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], {
segmentIndex: s.SegmentNumber,
segmentationId: s.SegmentationId,
})
let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === s.SegmentationId && i.metadata.segmentIndex === SegmentJson.bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
if (an) {
annotation.locking.setAnnotationLocked(an.annotationUID, true)
annotation.visibility.setAnnotationVisibility(an.annotationUID, item.bidirectionalView)
}
}
})
}
// this.$nextTick(() => {
// if (SEGMENT) {
// // console.log(SEGMENT, 'SEGMENT')
// return this.getBidirectional(obj.segments, SEGMENT)
// }
// this.getBidirectional(obj.segments, null, false)
// })
selectSegment(viewportId, segmentationId, segmentIndex)
if (Segment) {
jumpBidirectional(Segment, viewportId, series.SeriesInstanceUid)
}
}
}
readingSegmentByConfig(series, visitInfo, viewportId, segmentationId, SegmentConfig)
} catch (err) {
console.log(err)
}
}
export {
createSegmentation,
createSegmentationRepresentation,
readSegmentation,
renderSegmentation,
readingSegmentByConfig,
selectSegment,
selectSegmentation,
viewSegmentation,
viewSegment,
jumpBidirectional,
viewBidirectional,
changeColor,
resetViewport
}