fix tool import

This commit is contained in:
Ross
2025-06-02 09:59:51 +01:00
parent 1fd3020f0c
commit b408ba96b3
+155 -117
View File
@@ -1073,132 +1073,152 @@ function App() {
}
useEffect(() => {
// Export the current viewer state as JSON
window.exportViewerState = () => {
const numActive = viewportGrid.rows * viewportGrid.cols;
const modes = viewportModes.slice(0, numActive);
const stackIdx = selectedStackIdx.slice(0, numActive);
const stacks = availableStacks.map(s => ({
i: s.imageIds, // imageIds
u: s.studyInstanceUID // studyInstanceUID
}));
window.exportViewerState = () => {
const numActive = viewportGrid.rows * viewportGrid.cols;
const modes = viewportModes.slice(0, numActive);
const stackIdx = selectedStackIdx.slice(0, numActive);
const stacks = availableStacks.map(s => ({
i: s.imageIds, // imageIds
u: s.studyInstanceUID // studyInstanceUID
}));
// Only keep minimal properties
const renderingEngine = renderingEngineRef.current;
const props: any[] = [];
const stackPos: number[] = [];
const cam: any[] = [];
for (let i = 0; i < numActive; i++) {
let p = null, s = null, c = null;
if (renderingEngine) {
const viewportId = `CT_${i}`;
const viewport = renderingEngine.getViewport(viewportId);
if (viewport) {
if (typeof viewport.getProperties === "function") {
const { voiRange, invert, interpolationType, VOILUTFunction, colormap } = viewport.getProperties();
p = { voiRange, invert, interpolationType, VOILUTFunction, colormap };
}
if (typeof viewport.getCurrentImageIdIndex === "function") {
s = viewport.getCurrentImageIdIndex();
}
if (typeof viewport.getCamera === "function") {
c = viewport.getCamera();
}
}
}
props.push(p);
stackPos.push(s);
cam.push(c);
}
// Use short keys for compactness
const state = {
grid: viewportGrid,
modes,
stacks,
stackIdx,
stackPos,
props,
cam,
};
return JSON.stringify(state);
};
// Import and restore a viewer state from JSON (using stack indices)
window.importViewerState = (json: string) => {
try {
restoringStateRef.current = true;
const state = typeof json === "string" ? JSON.parse(json) : json;
if (state.grid) setViewportGrid(state.grid);
if (state.modes) setViewportModes(state.modes);
if (state.stacks) setAvailableStacks(state.stacks.map((s: any) => ({
imageIds: s.i,
studyInstanceUID: s.u,
})));
if (state.stackIdx && state.stacks) {
const reconstructed = state.stackIdx.map(
(idx: number) => state.stacks[idx]?.i || []
);
setViewportImageIds(reconstructed);
setSelectedStackIdx(state.stackIdx);
}
setTimeout(() => {
// Only keep minimal properties
const renderingEngine = renderingEngineRef.current;
if (!renderingEngine) {
restoringStateRef.current = false;
return;
}
const numActive = state.grid?.rows * state.grid?.cols || 1;
const props: any[] = [];
const stackPos: number[] = [];
const cam: any[] = [];
for (let i = 0; i < numActive; i++) {
const viewportId = `CT_${i}`;
const viewport = renderingEngine.getViewport(viewportId);
if (!viewport) continue;
// Restore stack position
if (
state.stackPos &&
typeof state.stackPos[i] === "number" &&
typeof viewport.setImageIdIndex === "function"
) {
if (csUtilities && csUtilities.jumpToSlice) {
csUtilities.jumpToSlice(viewport.element, { imageIndex: state.stackPos[i] });
} else {
viewport.setImageIdIndex(state.stackPos[i]);
let p = null, s = null, c = null;
if (renderingEngine) {
const viewportId = `CT_${i}`;
const viewport = renderingEngine.getViewport(viewportId);
if (viewport) {
if (typeof viewport.getProperties === "function") {
const { voiRange, invert, interpolationType, VOILUTFunction, colormap } = viewport.getProperties();
p = { voiRange, invert, interpolationType, VOILUTFunction, colormap };
}
if (typeof viewport.getCurrentImageIdIndex === "function") {
s = viewport.getCurrentImageIdIndex();
}
if (typeof viewport.getCamera === "function") {
c = viewport.getCamera();
}
}
}
// Restore properties
if (
state.props &&
state.props[i] &&
typeof viewport.setProperties === "function"
) {
viewport.setProperties(state.props[i]);
viewport.render();
}
// Restore camera
if (
state.cam &&
state.cam[i] &&
typeof viewport.setCamera === "function"
) {
viewport.setCamera(state.cam[i]);
viewport.render();
}
props.push(p);
stackPos.push(s);
cam.push(c);
}
restoringStateRef.current = false;
}, 300);
} catch (e) {
restoringStateRef.current = false;
alert("Failed to import viewer state: " + e);
}
};
// Use short keys for compactness
const state = {
grid: viewportGrid,
modes,
stacks,
stackIdx,
stackPos,
props,
cam,
};
return JSON.stringify(state);
};
// Import and restore a viewer state from JSON (using stack indices)
window.importViewerState = (json: string) => {
try {
restoringStateRef.current = true;
const state = typeof json === "string" ? JSON.parse(json) : json;
if (state.grid) setViewportGrid(state.grid);
if (state.modes) setViewportModes(state.modes);
if (state.stacks) setAvailableStacks(state.stacks.map((s: any) => ({
imageIds: s.i,
studyInstanceUID: s.u,
})));
if (state.stackIdx && state.stacks) {
const reconstructed = state.stackIdx.map(
(idx: number) => state.stacks[idx]?.i || []
);
setViewportImageIds(reconstructed);
setSelectedStackIdx(state.stackIdx);
}
setTimeout(() => {
const renderingEngine = renderingEngineRef.current;
if (!renderingEngine) {
restoringStateRef.current = false;
return;
}
const numActive = state.grid?.rows * state.grid?.cols || 1;
for (let i = 0; i < numActive; i++) {
const viewportId = `CT_${i}`;
const viewport = renderingEngine.getViewport(viewportId);
if (!viewport) continue;
// Restore stack position
if (
state.stackPos &&
typeof state.stackPos[i] === "number" &&
typeof viewport.setImageIdIndex === "function"
) {
if (csUtilities && csUtilities.jumpToSlice) {
csUtilities.jumpToSlice(viewport.element, { imageIndex: state.stackPos[i] });
} else {
viewport.setImageIdIndex(state.stackPos[i]);
}
}
// Restore properties
if (
state.props &&
state.props[i] &&
typeof viewport.setProperties === "function"
) {
viewport.setProperties(state.props[i]);
viewport.render();
}
// Restore camera
if (
state.cam &&
state.cam[i] &&
typeof viewport.setCamera === "function"
) {
viewport.setCamera(state.cam[i]);
viewport.render();
}
}
restoringStateRef.current = false;
}, 300);
} catch (e) {
restoringStateRef.current = false;
alert("Failed to import viewer state: " + e);
}
};
// Export all annotations using cornerstoneTools.annotation.state.getAllAnnotations()
window.exportAnnotations = () => {
try {
const allAnnotations = cornerstoneTools.annotation.state.getAllAnnotations();
let allAnnotations = cornerstoneTools.annotation.state.getAllAnnotations();
console.log("Exporting annotations:", allAnnotations);
// Remove ReferenceLines annotations (toolName may be 'ReferenceLines')
if (Array.isArray(allAnnotations)) {
// Only keep annotations with toolName in the allowed list
const allowedTools = [
LengthTool.toolName,
ArrowAnnotateTool.toolName,
RectangleROITool.toolName,
EllipticalROITool.toolName,
PlanarFreehandROITool.toolName,
PlanarFreehandContourSegmentationTool.toolName,
ProbeTool.toolName,
SculptorTool.toolName,
];
allAnnotations = allAnnotations.filter(
ann => allowedTools.includes(ann.metadata.toolName)
);
} else {
return "{}"; // If no annotations found, return empty object
}
return JSON.stringify(allAnnotations, null, 2);
} catch (e) {
alert("Failed to export annotations: " + e);
@@ -1210,7 +1230,25 @@ window.importViewerState = (json: string) => {
window.importAnnotations = (json: string) => {
try {
const annotationData = typeof json === "string" ? JSON.parse(json) : json;
cornerstoneTools.annotation.state.restoreAnnotations(annotationData);
// Remove all existing annotations if needed
if (cornerstoneTools.annotation.state.removeAllAnnotations) {
cornerstoneTools.annotation.state.removeAllAnnotations();
}
// Add each annotation from the imported data
if (Array.isArray(annotationData)) {
annotationData.forEach(ann => {
cornerstoneTools.annotation.state.addAnnotation(ann);
});
} else if (annotationData && typeof annotationData === "object") {
// If the data is an object with tool types as keys
Object.values(annotationData).forEach((anns: any) => {
if (Array.isArray(anns)) {
anns.forEach(ann => {
cornerstoneTools.annotation.state.addAnnotation(ann);
});
}
});
}
if (renderingEngineRef.current) {
renderingEngineRef.current.render();
}