diff --git a/src/components/tools/polygon/PolygonTool.vue b/src/components/tools/polygon/PolygonTool.vue index 1d1134ce..7153760e 100644 --- a/src/components/tools/polygon/PolygonTool.vue +++ b/src/components/tools/polygon/PolygonTool.vue @@ -54,6 +54,7 @@ import { import AnnotationContextMenu from '@/src/components/tools/AnnotationContextMenu.vue'; import AnnotationInfo from '@/src/components/tools/AnnotationInfo.vue'; import { useFrameOfReference } from '@/src/composables/useFrameOfReference'; +import { actionToKey } from '@/src/composables/useKeyboardShortcuts'; import { Maybe } from '@/src/types'; import { useSliceInfo } from '@/src/composables/useSliceInfo'; import { useMagicKeys, watchImmediate } from '@vueuse/core'; @@ -126,7 +127,11 @@ export default defineComponent({ placingTool.remove(); }); - const { v: mergeKey } = useMagicKeys(); + const keys = useMagicKeys(); + const mergeKey = computed( + () => keys[actionToKey.value.mergeNewPolygon].value + ); + const onToolPlaced = () => { if (imageId.value) { const newToolId = placingTool.id.value; diff --git a/src/composables/actions.ts b/src/composables/actions.ts index d481aa4d..99660b60 100644 --- a/src/composables/actions.ts +++ b/src/composables/actions.ts @@ -51,5 +51,7 @@ export const ACTION_TO_FUNC = { decrementLabel: applyLabelOffset(-1), incrementLabel: applyLabelOffset(1), + mergeNewPolygon: () => {}, // acts as a modifier key rather than immediate effect, so no-op + showKeyboardShortcuts, } as const satisfies Record void>; diff --git a/src/config.ts b/src/config.ts index fb564eee..67fdc478 100644 --- a/src/config.ts +++ b/src/config.ts @@ -296,6 +296,7 @@ export const ACTION_TO_KEY = { crosshairs: 'c', crop: 'b', polygon: 'g', + mergeNewPolygon: 'g', select: 's', decrementLabel: 'q', diff --git a/src/constants.ts b/src/constants.ts index 8212207b..ebc62ce1 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -60,6 +60,10 @@ export const ACTIONS = { readable: 'Activate next Label', }, + mergeNewPolygon: { + readable: 'Hold down to merge new polygons with overlapping polygons', + }, + showKeyboardShortcuts: { readable: 'Show keyboard shortcuts dialog', }, diff --git a/src/store/tools/polygons.ts b/src/store/tools/polygons.ts index 2a3f292c..a3e48f74 100644 --- a/src/store/tools/polygons.ts +++ b/src/store/tools/polygons.ts @@ -1,4 +1,4 @@ -import * as polygonClipping from 'polyclip-ts'; +import { intersection, union, Geom } from 'polyclip-ts'; import type { Vector3 } from '@kitware/vtk.js/types'; import { computed } from 'vue'; import { @@ -42,7 +42,7 @@ export const usePolygonStore = defineAnnotationToolStore('polygon', () => { const polygonsOverlap = (a: Tool, b: Tool) => { const [aGeo, bGeo] = [a, b].map(toGeoJSON); if (!aGeo || !bGeo) return false; - return polygonClipping.intersection(aGeo, bGeo).length > 0; + return intersection(aGeo, bGeo).length > 0; }; const sameSliceAndLabel = (a: Tool, b: Tool) => @@ -82,14 +82,13 @@ export const usePolygonStore = defineAnnotationToolStore('polygon', () => { }); function mergeToolGroup(mergeGroup: Tool[]) { - const firstTool = mergeGroup[0]; - const polygons = mergeGroup.map(toGeoJSON); if (polygons.some((p) => !p)) throw new Error('Trying to merge invalid polygons'); - const [first, ...rest] = polygons as unknown as polygonClipping.Geom[]; - const merged = polygonClipping.union(first, ...rest); + const [first, ...rest] = polygons as unknown as Geom[]; + const merged = union(first, ...rest); + const firstTool = mergeGroup[0]; const { to3D } = getPlaneTransforms(firstTool.frameOfReference); const points = merged.flatMap((p) => p.flatMap((ring) => ring.map(to3D)));