diff --git a/src/components/uploadDicomAndNonedicom/dicomFile.vue b/src/components/uploadDicomAndNonedicom/dicomFile.vue index 8ab4536a..c222c02c 100644 --- a/src/components/uploadDicomAndNonedicom/dicomFile.vue +++ b/src/components/uploadDicomAndNonedicom/dicomFile.vue @@ -712,12 +712,12 @@ export default { var studyUid = data.string('x0020000d') if (!studyUid) return resolve() var pixelDataElement = data.elements.x7fe00010 - if (!pixelDataElement && modality !== 'SR') return resolve() + if (!pixelDataElement && modality !== 'SR' && modality !== 'ECG') return resolve() var studyIndex = 0 while ( studyIndex < scope.uploadQueues.length && scope.uploadQueues[studyIndex].dicomInfo.studyUid !== studyUid && - (pixelDataElement || modality === 'SR') && + (pixelDataElement || modality === 'SR' || modality === 'ECG') && modality != '' ) { ++studyIndex diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue index 005c2349..2598f160 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue @@ -1589,7 +1589,7 @@ export default { // }) }, renderAnnotations(series) { - const taskId = series.TaskInfo.VisitTaskId + const taskId = series.TaskInfo ? series.TaskInfo.VisitTaskId : null if (!taskId || this.renderedTaskIds.includes(taskId)) return this.renderedTaskIds.push(taskId) const taskIdx = this.visitTaskList.findIndex(i => i.VisitTaskId === taskId) @@ -1726,7 +1726,7 @@ export default { if (annotation.metadata.toolName !== LabelMapEditWithContourTool.toolName) this.setToolsPassive() return } - if (annotation.data.segmentation || annotation.data.segment) return + if (annotation.metadata.segmentationId) return if (annotation.metadata.toolName === 'PlanarFreehandROI' && !annotation.data.contour.closed) return const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series if (series && series.TaskInfo.VisitTaskId && series.TaskInfo.VisitTaskId === this.taskInfo.VisitTaskId) { @@ -1814,7 +1814,7 @@ export default { if (annotation.metadata.toolName !== LabelMapEditWithContourTool.toolName) this.setToolsPassive() return } - if (annotation.data.segmentation || annotation.data.segment) return + if (annotation.metadata.segmentationId) return if (!annotation.data.label) return if (annotation.metadata.toolName === 'PlanarFreehandROI' && !annotation.data.contour.closed) return const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series @@ -1845,7 +1845,7 @@ export default { // 临时标记 return } - if (annotation.data.segmentation || annotation.data.segment) return + if (annotation.metadata.segmentationId) return if (annotation.visitTaskId === this.taskInfo.VisitTaskId) { const isBound = this.$refs[`ecrf_${annotation.visitTaskId}`][0].verifyAnnotationIsBound(annotation) if (isBound && this.activeTool === 'Eraser') { diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/Segmentations.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/Segmentations.vue index 0d5d859e..fb3ac614 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/Segmentations.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/Segmentations.vue @@ -397,7 +397,6 @@ export default { segmentationId: item.segmentationId, segmentIndices: [item.segmentIndex], }); - // console.log(bidirectionalData, 'bidirectionalData') if (bidirectionalData.length <= 0) { let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex); annotations.forEach(i => { @@ -421,11 +420,12 @@ export default { segmentIndex, segmentationId: item.segmentationId, }); - item.bidirectional = bidirectional let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional"); if (an) { annotation.locking.setAnnotationLocked(an.annotationUID, true) + annotation.visibility.setAnnotationVisibility(an.annotationUID, item.bidirectionalView) } + item.bidirectional = bidirectional if (DATA) { this.segmentationId = DATA.SegmentationId; this.segmentIndex = DATA.SegmentMumber; @@ -481,16 +481,30 @@ export default { } this.resetViewport() }, - jumpBidirectional(item) { + async 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 - let referencedImageId = an.metadata.referencedImageId; - let sliceIndex = metaData.get('generalImageModule', referencedImageId).instanceNumber + const renderingEngine = getRenderingEngine(this.renderingEngineId) const viewportId = `${this.viewportKey}-${this.activeViewportIndex}` const viewport = renderingEngine.getViewport(viewportId) - csUtils.jumpToSlice(viewport.element, { imageIndex: sliceIndex - 1 }); + 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 imageData = cache.getVolume(this.series.SeriesInstanceUid).imageData + const ijk = imageData.worldToIndex(worldPoint); + const sliceIndex = Math.abs(Math.round(ijk[2])); + let imageIds = viewport.getImageIds(this.series.SeriesInstanceUid) + // console.log(sliceIndex, 'sliceIndex') + csUtils.jumpToSlice(viewport.element, { imageIndex: imageIds.length - sliceIndex - 1 }); + } + } }, viewSegmentGroup(item) { @@ -542,7 +556,8 @@ export default { this.viewprotIds.forEach(id => { segmentation.activeSegmentation.setActiveSegmentation(id, this.segmentationId) }) - this.selectSegment({ segmentationId: this.segmentationId, segmentIndex: 1 }) + let segment = this.segmentList.find(item => item.segmentationId === this.segmentationId).segments[0] + this.selectSegment(segment) this.readingSegmentByConfig() }, async addSegmentGroup() { @@ -661,6 +676,8 @@ export default { }, // 删除分割分组 async delSegmentGroup() { + let confirm = await this.$confirm(this.$t('trials:reading:Segmentations:confirm:delSegmentions')) + if (!confirm) return false let res = await this.deleteSegmentation(this.segmentationId) if (!res) return false segmentation.removeSegmentation(this.segmentationId) @@ -682,12 +699,15 @@ export default { }, // 删除分割片段 async delSegment(segmentIndex) { + let confirm = await this.$confirm(this.$t('trials:reading:Segmentations:confirm:delSegment')) + if (!confirm) return false let groupIndex = this.segmentList.findIndex(item => item.segmentationId === this.segmentationId) if (this.segmentList[groupIndex].segments.length <= 1) return this.$confirm(this.$t('trials:reading:Segmentations:confirm:hasOneSegment')) let s = this.segmentList[groupIndex].segments.find(item => item.segmentIndex === segmentIndex) let res = await this.deleteSegment(s.id) if (!res) return false - segmentation.removeSegment(this.segmentationId, Number(segmentIndex), { setNextSegmentAsActive: false }) + segmentation.removeSegment(this.segmentationId, Number(segmentIndex), { setNextSegmentAsActive: false, recordHistory: false }) + segmentation.helpers.clearSegmentValue(this.segmentationId, Number(segmentIndex), { recordHistory: false }) // segmentation.updateSegmentations({ segmentationId: this.segmentationId }) let index = this.segmentList[groupIndex].segments.findIndex(item => item.segmentIndex === segmentIndex) this.segmentList[groupIndex].segments.splice(index, 1) @@ -711,6 +731,7 @@ export default { }, async rename(key, item) { let name = await this.customPrompt() + if (!name) return false if (key === 'segmentGroup') { let group = this.segmentList.find(i => i.segmentationId === this.segmentationId) group.name = name @@ -775,9 +796,11 @@ export default { segmentList.forEach(segment => { this.viewBidirectional(segment.segments, this.SegmentConfig.InactiveSegmentations.show) }) - let segments = this.segmentList.find(item => item.segmentationId === this.segmentationId).segments - this.viewBidirectional(segments, true) - + let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId) + if (segmentGroup) { + let segments = segmentGroup.segments + this.viewBidirectional(segments, true) + } }, // 更改分割标记显示模式 changeSegmentConfig(renderOutline, renderFill) { @@ -850,25 +873,28 @@ export default { color.slice(0, 3).map(value => value / 255) ).map(value => Math.round(value)); let segment = group.segments.find(item => item.segmentIndex === 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.bidirectional && segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata; + if (segment) { + 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.bidirectional && segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata; + } }); if (labelmap3D.metadata.length <= 0) { return false @@ -879,6 +905,9 @@ export default { labelmap3D, metaData ); + group.segments.forEach((item, index) => { + generatedSegmentation.dataset.SegmentSequence[index].SegmentNumber = item.segmentIndex.toString() + }) if (!isFile) { const buffer = Buffer.from(dcmjs.data.datasetToDict(generatedSegmentation.dataset).write()); let blob = new Blob([buffer], { type: "application/dicom" }); @@ -944,7 +973,6 @@ export default { 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." @@ -964,12 +992,28 @@ export default { const volumeScalarData = new Uint8Array( generateToolState.labelmapBufferArray[0] ); + const remappedData = new Uint8Array(volumeScalarData.length); + let mapping = {} + let segments = await this.getSegmentList(segmentationId) + if (segments.length > 0) { + segments.forEach(item => { + let SegmentJson = item.SegmentJson ? JSON.parse(item.SegmentJson) : {}; + if (SegmentJson.bidirectional && SegmentJson.stats) { + let keys = Object.keys(mapping) + mapping[keys.length + 1] = Number(item.SegmentMumber) + } + }) + } + for (let i = 0; i < volumeScalarData.length; i++) { + const value = volumeScalarData[i]; + remappedData[i] = value === 0 ? 0 : (mapping[value] ? mapping[value] : 0); + } for (let i = 0; i < derivedSegmentationImages.length; i++) { const voxelManager = derivedSegmentationImages[i].voxelManager; const scalarData = voxelManager.getScalarData(); scalarData.set( - volumeScalarData.slice( + remappedData.slice( i * scalarData.length, (i + 1) * scalarData.length ) @@ -1200,6 +1244,7 @@ export default { }) // 生成文件路径 let blob = this.exportSegmentation(segmentGroup.segmentationId, segmentGroup) + // if (!blob) return false if (blob) { let path = `/${this.$route.query.trialId}/Segment/${this.visitInfo.SubjectId }/${this.visitInfo.VisistId}/${this.series.StudyId @@ -1301,13 +1346,14 @@ export default { // this.getBidirectional(o) // }) if (SEGMENT && index === segments.length - 1) { - console.log(SEGMENT, 'SEGMENT') + // console.log(SEGMENT, 'SEGMENT') return this.getBidirectional(o, SEGMENT) } this.getBidirectional(o) }) } } + // console.log(segmentation.state.getSegmentations(), 'segmentation.state.getSegmentations()') } catch (err) { this.loading = false console.log(err) diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue index 6c3bdcf6..e5865567 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue @@ -40,10 +40,10 @@