Skip to content

Commit

Permalink
Merge pull request #440 from PaulHax/paint-fixes
Browse files Browse the repository at this point in the history
Paint and Polygon Tool fixes
  • Loading branch information
floryst authored Oct 4, 2023
2 parents c6a77b6 + 74050d9 commit a25452b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 72 deletions.
132 changes: 63 additions & 69 deletions src/components/tools/paint/PaintWidget2D.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ import vtkWidgetManager from '@kitware/vtk.js/Widgets/Core/WidgetManager';
import {
computed,
defineComponent,
onBeforeUnmount,
onMounted,
onUnmounted,
PropType,
ref,
toRefs,
Expand All @@ -15,14 +12,17 @@ import vtkPlaneManipulator from '@kitware/vtk.js/Widgets/Manipulators/PlaneManip
import { getLPSAxisFromDir } from '@/src/utils/lps';
import { useCurrentImage } from '@/src/composables/useCurrentImage';
import { updatePlaneManipulatorFor2DView } from '@/src/utils/manipulators';
import type { vtkSubscription } from '@kitware/vtk.js/interfaces';
import { usePaintToolStore } from '@/src/store/tools/paint';
import { vtkPaintViewWidget } from '@/src/vtk/PaintWidget';
import { useViewStore } from '@/src/store/views';
import { PaintWidgetState } from '@/src/vtk/PaintWidget/state';
import { vec3 } from 'gl-matrix';
import { manageVTKSubscription } from '@/src/composables/manageVTKSubscription';
import { LPSAxisDir } from '@/src/types/lps';
import { onVTKEvent } from '@/src/composables/onVTKEvent';
import {
onViewProxyMounted,
onViewProxyUnmounted,
} from '@/src/composables/useViewProxy';
export default defineComponent({
name: 'PaintWidget2D',
Expand All @@ -46,17 +46,14 @@ export default defineComponent({
},
setup(props) {
const {
widgetManager: widgetManagerRef,
widgetManager,
viewDirection,
slice,
viewId: viewID,
} = toRefs(props);
const paintStore = usePaintToolStore();
const factory = paintStore.getWidgetFactory();
const viewStore = useViewStore();
const viewProxyRef = computed(() => viewStore.getViewProxy(viewID.value));
const widgetFactory = paintStore.getWidgetFactory();
const widgetRef = ref<vtkPaintViewWidget>();
Expand All @@ -73,13 +70,26 @@ export default defineComponent({
return indexPoint;
};
onMounted(() => {
const widgetManager = widgetManagerRef.value;
widgetRef.value = widgetManager.addWidget(factory) as vtkPaintViewWidget;
const viewProxy = computed(() => useViewStore().getViewProxy(viewID.value));
onViewProxyMounted(viewProxy, () => {
widgetRef.value = widgetManager.value.addWidget(
widgetFactory
) as vtkPaintViewWidget;
if (!widgetRef.value) {
throw new Error('[PaintWidget2D] failed to create view widget');
}
widgetManager.value.renderWidgets();
widgetManager.value.grabFocus(widgetRef.value);
});
onViewProxyUnmounted(viewProxy, () => {
if (!widgetRef.value) {
return;
}
widgetManager.value.removeWidget(widgetRef.value);
});
// --- widget representation config --- //
Expand All @@ -97,45 +107,31 @@ export default defineComponent({
// --- interaction --- //
const subs: vtkSubscription[] = [];
onMounted(() => {
const widget = widgetRef.value!;
onVTKEvent(widgetRef, 'onStartInteractionEvent', () => {
const state = widgetRef.value!.getWidgetState() as PaintWidgetState;
// StartInteraction cannot occur if origin is null.
const indexPoint = worldPointToIndex(state.getBrush().getOrigin()!);
paintStore.startStroke(indexPoint, viewAxisIndex.value);
});
subs.push(
widget.onStartInteractionEvent(() => {
// start stroke
const state = widget.getWidgetState() as PaintWidgetState;
// StartInteraction cannot occur if origin is null.
const indexPoint = worldPointToIndex(state.getBrush().getOrigin()!);
paintStore.startStroke(indexPoint, viewAxisIndex.value);
}),
widget.onInteractionEvent(() => {
// register stroke
const state = widget.getWidgetState() as PaintWidgetState;
const indexPoint = worldPointToIndex(state.getBrush().getOrigin()!);
paintStore.placeStrokePoint(indexPoint, viewAxisIndex.value);
}),
widget.onEndInteractionEvent(() => {
// end stroke
const state = widget.getWidgetState() as PaintWidgetState;
const indexPoint = worldPointToIndex(state.getBrush().getOrigin()!);
paintStore.endStroke(indexPoint, viewAxisIndex.value);
})
);
onVTKEvent(widgetRef, 'onInteractionEvent', () => {
const state = widgetRef.value!.getWidgetState() as PaintWidgetState;
const indexPoint = worldPointToIndex(state.getBrush().getOrigin()!);
paintStore.placeStrokePoint(indexPoint, viewAxisIndex.value);
});
onUnmounted(() => {
while (subs.length) {
subs.pop()!.unsubscribe();
}
onVTKEvent(widgetRef, 'onEndInteractionEvent', () => {
// end stroke
const state = widgetRef.value!.getWidgetState() as PaintWidgetState;
const indexPoint = worldPointToIndex(state.getBrush().getOrigin()!);
paintStore.endStroke(indexPoint, viewAxisIndex.value);
});
// --- manipulator --- //
const manipulator = vtkPlaneManipulator.newInstance();
onMounted(() => {
onViewProxyMounted(viewProxy, () => {
widgetRef.value!.setManipulator(manipulator);
});
Expand All @@ -150,40 +146,38 @@ export default defineComponent({
// --- visibility --- //
onMounted(() => {
let checkIfPointerInView = false;
onViewProxyMounted(viewProxy, () => {
widgetRef.value!.setVisibility(false);
checkIfPointerInView = true;
});
manageVTKSubscription(
viewProxyRef.value!.getInteractor().onMouseEnter(() => {
const widget = widgetRef.value;
if (widget) {
paintStore.setSliceAxis(viewAxisIndex.value);
widget.setVisibility(true);
}
})
);
const viewInteractor = computed(() => viewProxy.value!.getInteractor());
manageVTKSubscription(
viewProxyRef.value!.getInteractor().onMouseLeave(() => {
const widget = widgetRef.value;
if (widget) {
widget.setVisibility(false);
}
})
);
// Turn on widget visibility if mouse starts within view
onVTKEvent(viewInteractor, 'onMouseMove', () => {
if (!checkIfPointerInView) {
return;
}
checkIfPointerInView = false;
// --- focus and rendering --- //
widgetRef.value!.setVisibility(true);
});
onMounted(() => {
const widgetManager = widgetManagerRef.value;
widgetManager.renderWidgets();
widgetManager.grabFocus(widgetRef.value!);
onVTKEvent(viewInteractor, 'onMouseEnter', () => {
const widget = widgetRef.value;
if (widget) {
paintStore.setSliceAxis(viewAxisIndex.value);
widget.setVisibility(true);
}
});
onBeforeUnmount(() => {
widgetManagerRef.value.removeWidget(widgetRef.value!);
widgetManagerRef.value.releaseFocus();
onVTKEvent(viewInteractor, 'onMouseLeave', () => {
const widget = widgetRef.value;
if (widget) {
widget.setVisibility(false);
}
});
return () => null;
Expand Down
5 changes: 4 additions & 1 deletion src/vtk/PaintWidget/behavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ export default function widgetBehavior(publicAPI: any, model: any) {

if (isPainting) {
publicAPI.invokeInteractionEvent();
return macro.EVENT_ABORT;
}
return macro.EVENT_ABORT;

// Let interactor get event
return macro.VOID;
};

/**
Expand Down
3 changes: 1 addition & 2 deletions src/vtk/PolygonWidget/behavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function widgetBehavior(publicAPI: any, model: any) {
// overSegment guards against clicking anywhere in view
const selections = model._widgetManager.getSelections();
const overSegment =
selections[0]?.getProperties().prop ===
selections?.[0]?.getProperties().prop ===
model.representations[1].getActors()[0]; // line representation is second representation
return overSegment && !overUnselectedHandle;
};
Expand Down Expand Up @@ -428,6 +428,5 @@ export default function widgetBehavior(publicAPI: any, model: any) {
model.activeState = null;
model.hasFocus = false;
model._widgetManager.enablePicking();
model._interactor.render();
};
}

0 comments on commit a25452b

Please sign in to comment.