分割长短径工具问题修复
parent
64d1ebf350
commit
c3a154f762
|
|
@ -538,6 +538,7 @@ import SegmentForm from './SegmentForm.vue'
|
|||
import colorMap from './colorMap.vue'
|
||||
import RectangleROITool from './tools/RectangleROITool'
|
||||
import ScaleOverlayTool from './tools/ScaleOverlayTool'
|
||||
import SegmentBidirectionalTool from './tools/SegmentBidirectionalTool'
|
||||
import FixedRadiusCircleROITool from './tools/FixedRadiusCircleROITool'
|
||||
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
||||
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
||||
|
|
@ -574,7 +575,7 @@ const {
|
|||
synchronizers,
|
||||
LabelMapEditWithContourTool,
|
||||
BrushTool,
|
||||
SegmentBidirectionalTool,
|
||||
// SegmentBidirectionalTool,
|
||||
utilities: CStUtils,
|
||||
// cursors
|
||||
} = cornerstoneTools
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@
|
|||
</el-switch>
|
||||
<span style="margin-left: 5px;">{{
|
||||
$t('trials:reading:Segmentations:title:InactiveSegmentationsShow')
|
||||
}}</span>
|
||||
}}</span>
|
||||
</div>
|
||||
<!-- <div class="SegmentConfig" v-if="SegmentConfig.InactiveSegmentations.show">
|
||||
<span>{{ $t('trials:reading:Segmentations:title:Opacity') }}</span>
|
||||
|
|
@ -133,7 +133,7 @@
|
|||
<div class="messageBox">
|
||||
<el-popover placement="left" :title="item.SegmentLabel" width="200" trigger="hover">
|
||||
<div class="Bidirectionalbox">
|
||||
<div class="BidirectionalBtn" @click.stop="getBidirectional(item)"
|
||||
<div class="BidirectionalBtn" @click.stop="getBidirectional([item])"
|
||||
v-if="!item.bidirectional">
|
||||
{{ $t('trials:reading:Segmentations:button:getBidirectional') }}
|
||||
</div>
|
||||
|
|
@ -155,7 +155,7 @@
|
|||
<div v-for="k in statsKey" :key="k" class="statsBox">
|
||||
<span>{{ k }}</span>
|
||||
<span v-if="item.stats[k]">{{ Number(item.stats[k].value).toFixed(2)
|
||||
}}<i>{{ item.stats[k].unit }}</i></span>
|
||||
}}<i>{{ item.stats[k].unit }}</i></span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="serialNum" slot="reference">{{ item.segmentIndex }}</div>
|
||||
|
|
@ -385,8 +385,11 @@ export default {
|
|||
this.actionConfiguration.contourBidirectional.data.segmentationId = segmentationId
|
||||
this.actionConfiguration.contourBidirectional.data.segmentIndex = segmentIndex
|
||||
},
|
||||
getBidirectional(item, DATA = null) {
|
||||
this.createSegmentConfiguration(item.segmentIndex, item.segmentationId);
|
||||
getBidirectional(list, DATA = null) {
|
||||
list.forEach(item => {
|
||||
this.createSegmentConfiguration(item.segmentIndex, item.segmentationId);
|
||||
})
|
||||
|
||||
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
||||
const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
|
||||
const viewport = renderingEngine.getViewport(viewportId);
|
||||
|
|
@ -394,16 +397,20 @@ export default {
|
|||
[viewport.element].forEach(async (element) => {
|
||||
const bidirectionalData =
|
||||
await CStUtils.segmentation.getSegmentLargestBidirectional({
|
||||
segmentationId: item.segmentationId,
|
||||
segmentIndices: [item.segmentIndex],
|
||||
segmentationId: list[0].segmentationId,
|
||||
segmentIndices: list.map(item => item.segmentIndex),
|
||||
});
|
||||
if (bidirectionalData.length <= 0) {
|
||||
let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex);
|
||||
annotations.forEach(i => {
|
||||
annotation.state.removeAnnotation(i.annotationUID)
|
||||
list.forEach(item => {
|
||||
let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex);
|
||||
annotations.forEach(i => {
|
||||
annotation.state.removeAnnotation(i.annotationUID)
|
||||
})
|
||||
item.bidirectional = null
|
||||
})
|
||||
|
||||
this.resetViewport(false)
|
||||
item.bidirectional = null
|
||||
|
||||
if (DATA) {
|
||||
this.segmentationId = DATA.SegmentationId;
|
||||
this.segmentIndex = DATA.SegmentMumber;
|
||||
|
|
@ -415,7 +422,7 @@ export default {
|
|||
bidirectionalData.forEach((bidirectional) => {
|
||||
const { segmentIndex } = bidirectional;
|
||||
const { majorAxis, minorAxis, maxMajor, maxMinor } = bidirectional;
|
||||
|
||||
let item = list.find(i => i.segmentIndex === segmentIndex)
|
||||
SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], {
|
||||
segmentIndex,
|
||||
segmentationId: item.segmentationId,
|
||||
|
|
@ -979,9 +986,21 @@ export default {
|
|||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await this.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)
|
||||
})
|
||||
console.log(mapping, 'mapping')
|
||||
const megmentGroup =
|
||||
segmentation.state.getSegmentation(segmentationId);
|
||||
const { imageIds } = megmentGroup.representationData.Labelmap;
|
||||
|
|
@ -993,21 +1012,9 @@ export default {
|
|||
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);
|
||||
remappedData[i] = value === 0 ? 0 : (mapping[value] ? mapping[value] : value);
|
||||
}
|
||||
for (let i = 0; i < derivedSegmentationImages.length; i++) {
|
||||
const voxelManager = derivedSegmentationImages[i].voxelManager;
|
||||
|
|
@ -1145,14 +1152,14 @@ export default {
|
|||
this.calculateStatistics([this.segmentIndex], this.segmentationId, 'individual');
|
||||
let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
|
||||
let segment = segmentGroup.segments.find(item => item.segmentIndex === this.segmentIndex)
|
||||
this.getBidirectional(segment)
|
||||
this.getBidirectional([segment])
|
||||
} else {
|
||||
let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
|
||||
let segmentIndexs = []
|
||||
segmentGroup.segments.forEach(item => {
|
||||
segmentIndexs.push(item.segmentIndex)
|
||||
this.getBidirectional(item)
|
||||
})
|
||||
this.getBidirectional(segmentGroup.segments)
|
||||
this.calculateStatistics(segmentIndexs, this.segmentationId, 'individual');
|
||||
}
|
||||
this.isDel = false
|
||||
|
|
@ -1339,17 +1346,13 @@ export default {
|
|||
this.selectSegment(o)
|
||||
this.changeColor(s.ColorRgb, o)
|
||||
this.lockSegment(o, true)
|
||||
// setTimeout(() => {
|
||||
// if (SEGMENT && index === segments.length - 1) {
|
||||
// return this.getBidirectional(o, SEGMENT)
|
||||
// }
|
||||
// this.getBidirectional(o)
|
||||
// })
|
||||
if (SEGMENT && index === segments.length - 1) {
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
if (SEGMENT) {
|
||||
// console.log(SEGMENT, 'SEGMENT')
|
||||
return this.getBidirectional(o, SEGMENT)
|
||||
return this.getBidirectional(obj.segments, SEGMENT)
|
||||
}
|
||||
this.getBidirectional(o)
|
||||
this.getBidirectional(obj.segments)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,264 @@
|
|||
// import { getEnabledElement, utilities as csUtils, getEnabledElementByViewportId, utilities, } from '@cornerstonejs/core';
|
||||
// import { addAnnotation, getAllAnnotations, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
|
||||
// import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
|
||||
// import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
|
||||
// import { drawLine as drawLineSvg, drawHandles as drawHandlesSvg, } from '../../drawingSvg';
|
||||
// import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
|
||||
// import { hideElementCursor } from '../../cursors/elementCursor';
|
||||
// import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
|
||||
// import BidirectionalTool from '../annotation/BidirectionalTool';
|
||||
// import { getSegmentIndexColor } from '../../stateManagement/segmentation/config/segmentationColor';
|
||||
|
||||
|
||||
import { utilities, getEnabledElementByViewportId, getEnabledElement } from '@cornerstonejs/core';
|
||||
import * as cornerstoneTools from '@cornerstonejs/tools'
|
||||
const {
|
||||
annotation,
|
||||
drawing,
|
||||
utilities: TSUtilities,
|
||||
BidirectionalTool,
|
||||
cursors,
|
||||
segmentation
|
||||
} = cornerstoneTools
|
||||
const { addAnnotation, getAllAnnotations, getAnnotations, removeAnnotation } = annotation.state
|
||||
const { isAnnotationLocked } = annotation.locking
|
||||
const { isAnnotationVisible } = annotation.visibility
|
||||
const { drawLine: drawLineSvg, drawHandles: drawHandlesSvg } = drawing
|
||||
const { getViewportIdsWithToolToRender } = TSUtilities.viewportFilters
|
||||
const { triggerAnnotationRenderForViewportIds } = TSUtilities
|
||||
const { hideElementCursor } = cursors.elementCursor
|
||||
const { getSegmentIndexColor } = segmentation.config.color
|
||||
class SegmentBidirectionalTool extends BidirectionalTool {
|
||||
static { this.toolName = 'SegmentBidirectional'; }
|
||||
constructor(toolProps = {}) {
|
||||
super(toolProps);
|
||||
this.renderAnnotation = (enabledElement, svgDrawingHelper) => {
|
||||
let renderStatus = true;
|
||||
const { viewport } = enabledElement;
|
||||
const { element } = viewport;
|
||||
const viewportId = viewport.id;
|
||||
let annotations = getAnnotations(this.getToolName(), element);
|
||||
if (!annotations?.length) {
|
||||
return renderStatus;
|
||||
}
|
||||
annotations = this.filterInteractableAnnotationsForElement(element, annotations);
|
||||
if (!annotations?.length) {
|
||||
return renderStatus;
|
||||
}
|
||||
const targetId = this.getTargetId(viewport);
|
||||
const renderingEngine = viewport.getRenderingEngine();
|
||||
const styleSpecifier = {
|
||||
toolGroupId: this.toolGroupId,
|
||||
toolName: this.getToolName(),
|
||||
viewportId: enabledElement.viewport.id,
|
||||
};
|
||||
for (let i = 0; i < annotations.length; i++) {
|
||||
const annotation = annotations[i];
|
||||
const { annotationUID, data } = annotation;
|
||||
const { points, activeHandleIndex } = data.handles;
|
||||
const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
|
||||
styleSpecifier.annotationUID = annotationUID;
|
||||
const { segmentIndex, segmentationId } = annotation.metadata;
|
||||
const { lineWidth, lineDash, shadow } = this.getAnnotationStyle({
|
||||
annotation,
|
||||
styleSpecifier,
|
||||
});
|
||||
const colorArray = getSegmentIndexColor(viewportId, segmentationId, segmentIndex) || [255, 255, 255];
|
||||
// console.log(viewportId, segmentationId, segmentIndex, 'colorArray')
|
||||
// console.log(colorArray, 'colorArray')
|
||||
const color = `rgb(${colorArray.slice(0, 3).join(',')})`;
|
||||
if (!data.cachedStats[targetId] ||
|
||||
data.cachedStats[targetId].unit == null) {
|
||||
data.cachedStats[targetId] = {
|
||||
length: null,
|
||||
width: null,
|
||||
unit: null,
|
||||
};
|
||||
this._calculateCachedStats(annotation, renderingEngine, enabledElement);
|
||||
}
|
||||
else if (annotation.invalidated) {
|
||||
this._throttledCalculateCachedStats(annotation, renderingEngine, enabledElement);
|
||||
}
|
||||
if (!viewport.getRenderingEngine()) {
|
||||
console.warn('Rendering Engine has been destroyed');
|
||||
return renderStatus;
|
||||
}
|
||||
let activeHandleCanvasCoords;
|
||||
if (!isAnnotationVisible(annotationUID)) {
|
||||
continue;
|
||||
}
|
||||
if (!isAnnotationLocked(annotationUID) &&
|
||||
!this.editData &&
|
||||
activeHandleIndex !== null) {
|
||||
activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]];
|
||||
}
|
||||
if (activeHandleCanvasCoords) {
|
||||
const handleGroupUID = '0';
|
||||
drawHandlesSvg(svgDrawingHelper, annotationUID, handleGroupUID, activeHandleCanvasCoords, {
|
||||
color,
|
||||
});
|
||||
}
|
||||
const dataId1 = `${annotationUID}-line-1`;
|
||||
const dataId2 = `${annotationUID}-line-2`;
|
||||
const lineUID = '0';
|
||||
drawLineSvg(svgDrawingHelper, annotationUID, lineUID, canvasCoordinates[0], canvasCoordinates[1], {
|
||||
color,
|
||||
lineWidth,
|
||||
lineDash,
|
||||
shadow,
|
||||
}, dataId1);
|
||||
const secondLineUID = '1';
|
||||
drawLineSvg(svgDrawingHelper, annotationUID, secondLineUID, canvasCoordinates[2], canvasCoordinates[3], {
|
||||
color,
|
||||
lineWidth,
|
||||
lineDash,
|
||||
shadow,
|
||||
}, dataId2);
|
||||
renderStatus = true;
|
||||
const textLines = this.configuration.getTextLines(data, targetId);
|
||||
if (!textLines || textLines.length === 0) {
|
||||
continue;
|
||||
}
|
||||
if (!this.renderLinkedTextBoxAnnotation({
|
||||
enabledElement,
|
||||
svgDrawingHelper,
|
||||
annotation,
|
||||
styleSpecifier,
|
||||
textLines,
|
||||
canvasCoordinates,
|
||||
})) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return renderStatus;
|
||||
};
|
||||
}
|
||||
addNewAnnotation(evt) {
|
||||
const eventDetail = evt.detail;
|
||||
const { currentPoints, element } = eventDetail;
|
||||
const worldPos = currentPoints.world;
|
||||
const enabledElement = getEnabledElement(element);
|
||||
const { viewport } = enabledElement;
|
||||
this.isDrawing = true;
|
||||
const camera = viewport.getCamera();
|
||||
const { viewPlaneNormal, viewUp } = camera;
|
||||
const referencedImageId = this.getReferencedImageId(viewport, worldPos, viewPlaneNormal, viewUp);
|
||||
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
|
||||
const annotation = {
|
||||
highlighted: true,
|
||||
invalidated: true,
|
||||
metadata: {
|
||||
toolName: this.getToolName(),
|
||||
viewPlaneNormal: [...viewPlaneNormal],
|
||||
viewUp: [...viewUp],
|
||||
FrameOfReferenceUID,
|
||||
referencedImageId,
|
||||
...viewport.getViewReference({ points: [worldPos] }),
|
||||
},
|
||||
data: {
|
||||
handles: {
|
||||
points: [
|
||||
[...worldPos],
|
||||
[...worldPos],
|
||||
[...worldPos],
|
||||
[...worldPos],
|
||||
],
|
||||
textBox: {
|
||||
hasMoved: false,
|
||||
worldPosition: [0, 0, 0],
|
||||
worldBoundingBox: {
|
||||
topLeft: [0, 0, 0],
|
||||
topRight: [0, 0, 0],
|
||||
bottomLeft: [0, 0, 0],
|
||||
bottomRight: [0, 0, 0],
|
||||
},
|
||||
},
|
||||
activeHandleIndex: null,
|
||||
},
|
||||
label: '',
|
||||
cachedStats: {},
|
||||
},
|
||||
};
|
||||
addAnnotation(annotation, element);
|
||||
const viewportIdsToRender = getViewportIdsWithToolToRender(element, this.getToolName());
|
||||
this.editData = {
|
||||
annotation,
|
||||
viewportIdsToRender,
|
||||
handleIndex: 1,
|
||||
movingTextBox: false,
|
||||
newAnnotation: true,
|
||||
hasMoved: false,
|
||||
};
|
||||
this._activateDraw(element);
|
||||
hideElementCursor(element);
|
||||
evt.preventDefault();
|
||||
triggerAnnotationRenderForViewportIds(viewportIdsToRender);
|
||||
return annotation;
|
||||
}
|
||||
static {
|
||||
this.hydrate = (viewportId, axis, options) => {
|
||||
const enabledElement = getEnabledElementByViewportId(viewportId);
|
||||
if (!enabledElement) {
|
||||
return;
|
||||
}
|
||||
const { viewport } = enabledElement;
|
||||
const existingAnnotations = getAllAnnotations();
|
||||
const toolAnnotations = existingAnnotations.filter((annotation) => annotation.metadata.toolName === 'SegmentBidirectional');
|
||||
const existingAnnotation = toolAnnotations.find((annotation) => {
|
||||
const { metadata } = annotation;
|
||||
if (metadata.segmentIndex === options?.segmentIndex &&
|
||||
metadata.segmentationId === options?.segmentationId) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (existingAnnotation) {
|
||||
removeAnnotation(existingAnnotation.annotationUID);
|
||||
}
|
||||
const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, } = this.hydrateBase(SegmentBidirectionalTool, enabledElement, axis[0], options);
|
||||
const [majorAxis, minorAxis] = axis;
|
||||
const [major0, major1] = majorAxis;
|
||||
const [minor0, minor1] = minorAxis;
|
||||
const points = [major0, major1, minor0, minor1];
|
||||
const { toolInstance, ...serializableOptions } = options || {};
|
||||
const annotation = {
|
||||
annotationUID: options?.annotationUID || utilities.uuidv4(),
|
||||
data: {
|
||||
handles: {
|
||||
points,
|
||||
activeHandleIndex: null,
|
||||
textBox: {
|
||||
hasMoved: false,
|
||||
worldPosition: [0, 0, 0],
|
||||
worldBoundingBox: {
|
||||
topLeft: [0, 0, 0],
|
||||
topRight: [0, 0, 0],
|
||||
bottomLeft: [0, 0, 0],
|
||||
bottomRight: [0, 0, 0],
|
||||
},
|
||||
},
|
||||
},
|
||||
cachedStats: {},
|
||||
},
|
||||
highlighted: false,
|
||||
autoGenerated: false,
|
||||
invalidated: false,
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
metadata: {
|
||||
segmentIndex: options?.segmentIndex,
|
||||
segmentationId: options?.segmentationId,
|
||||
toolName: instance.getToolName(),
|
||||
viewPlaneNormal,
|
||||
FrameOfReferenceUID,
|
||||
referencedImageId,
|
||||
...serializableOptions,
|
||||
},
|
||||
};
|
||||
addAnnotation(annotation, viewport.element);
|
||||
triggerAnnotationRenderForViewportIds([viewport.id]);
|
||||
return annotation;
|
||||
};
|
||||
}
|
||||
}
|
||||
export default SegmentBidirectionalTool;
|
||||
Loading…
Reference in New Issue