Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 8 additions & 57 deletions frontend/javascripts/libs/drawing.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import type { Vector3 } from "viewer/constants";
type RangeItem = [number, number, number, boolean | null, boolean, boolean];

// This is a class with static methods and constants dealing with drawing
// lines and filling polygons
// Macros
// Constants
const SMOOTH_LENGTH = 4;
const SMOOTH_ALPHA = 0.2;
// lines and filling polygons.

class Drawing {
alpha: number = SMOOTH_ALPHA;
smoothLength: number = SMOOTH_LENGTH;

drawHorizontalLine2d(
private drawHorizontalLine2d(
y: number,
x1: number,
x2: number,
Expand Down Expand Up @@ -91,7 +84,7 @@ class Drawing {
}
}

addNextLine(
private addNextLine(
newY: number,
isNext: boolean,
downwards: boolean,
Expand Down Expand Up @@ -135,7 +128,7 @@ class Drawing {
}
}

paintBorder(
private paintBorder(
x1: number,
y1: number,
x2: number,
Expand Down Expand Up @@ -212,19 +205,15 @@ class Drawing {

while (ranges.length) {
const r = ranges.pop();
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
if (r == null) {
throw new Error("Array is exptected to be not empty.");
}
let minX = r[0];
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
let maxX = r[1];
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
y = r[2];
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
const down = r[3] === true;
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
const up = r[3] === false;
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
const extendLeft = r[4];
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
const extendRight = r[5];

if (extendLeft) {
Expand All @@ -250,19 +239,15 @@ class Drawing {
maxX++;
}
} else {
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
r[0]--;
// @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
r[1]++;
}

if (y < height) {
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'RangeItem | undefined' is not as... Remove this comment to see the full error message
this.addNextLine(y + 1, !up, true, minX, maxX, r, ranges, test, paint);
}

if (y > 0) {
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'RangeItem | undefined' is not as... Remove this comment to see the full error message
this.addNextLine(y - 1, !down, false, minX, maxX, r, ranges, test, paint);
}
}
Expand All @@ -288,40 +273,6 @@ class Drawing {
}
}
}

// Source : http://twistedoakstudios.com/blog/Post3138_mouse-path-smoothing-for-jack-lumber
smoothLine(points: Array<Vector3>, callback: (arg0: Vector3) => void): Array<Vector3> {
const smoothLength = this.smoothLength || SMOOTH_LENGTH;
const a = this.alpha || SMOOTH_ALPHA;

if (points.length > 2 + smoothLength) {
for (let i = 0; i < smoothLength; i++) {
const j = points.length - i - 2;
const p0 = points[j];
const p1 = points[j + 1];
const p = [0, 0, 0];

for (let k = 0; k < 3; k++) {
p[k] = p0[k] * (1 - a) + p1[k] * a;
}

// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'number[]' is not assignable to p... Remove this comment to see the full error message
callback(p);
// @ts-expect-error ts-migrate(2322) FIXME: Type 'number[]' is not assignable to type 'Vector3... Remove this comment to see the full error message
points[j] = p;
}
}

return points;
}

setSmoothLength(v: number): void {
this.smoothLength = v;
}

setAlpha(v: number): void {
this.alpha = v;
}
}

export default new Drawing();
24 changes: 12 additions & 12 deletions frontend/javascripts/test/reducers/volumetracing_reducer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ describe("VolumeTracing", () => {
[1, 2, 3],
[9, 3, 2],
] as Vector3[];
const addToLayerActionFn = VolumeTracingActions.addToLayerAction;
const addToContourListActionFn = VolumeTracingActions.addToContourListAction;
const alteredState = update(initialState, {
annotation: {
restrictions: {
Expand All @@ -262,9 +262,9 @@ describe("VolumeTracing", () => {
});

// Try to add positions to the contourList
let newState = VolumeTracingReducer(alteredState, addToLayerActionFn(contourList[0]));
newState = VolumeTracingReducer(newState, addToLayerActionFn(contourList[1]));
newState = VolumeTracingReducer(newState, addToLayerActionFn(contourList[2]));
let newState = VolumeTracingReducer(alteredState, addToContourListActionFn(contourList[0]));
newState = VolumeTracingReducer(newState, addToContourListActionFn(contourList[1]));
newState = VolumeTracingReducer(newState, addToContourListActionFn(contourList[2]));
expect(newState).toBe(alteredState);
});

Expand All @@ -274,13 +274,13 @@ describe("VolumeTracing", () => {
[1, 2, 3],
[9, 3, 2],
] as Vector3[];
const addToLayerActionFn = VolumeTracingActions.addToLayerAction;
const addToContourListActionFn = VolumeTracingActions.addToContourListAction;
const resetContourAction = VolumeTracingActions.resetContourAction();

// Add positions to the contourList
let newState = VolumeTracingReducer(initialState, addToLayerActionFn(contourList[0]));
newState = VolumeTracingReducer(newState, addToLayerActionFn(contourList[1]));
newState = VolumeTracingReducer(newState, addToLayerActionFn(contourList[2]));
let newState = VolumeTracingReducer(initialState, addToContourListActionFn(contourList[0]));
newState = VolumeTracingReducer(newState, addToContourListActionFn(contourList[1]));
newState = VolumeTracingReducer(newState, addToContourListActionFn(contourList[2]));

// And reset the list
newState = VolumeTracingReducer(newState, resetContourAction);
Expand All @@ -296,11 +296,11 @@ const prepareContourListTest = (state: WebknossosState) => {
[1, 2, 3],
[9, 3, 2],
] as Vector3[];
const addToLayerActionFn = VolumeTracingActions.addToLayerAction;
const addToContourListActionFn = VolumeTracingActions.addToContourListAction;

let newState = VolumeTracingReducer(state, addToLayerActionFn(contourList[0]));
newState = VolumeTracingReducer(newState, addToLayerActionFn(contourList[1]));
newState = VolumeTracingReducer(newState, addToLayerActionFn(contourList[2]));
let newState = VolumeTracingReducer(state, addToContourListActionFn(contourList[0]));
newState = VolumeTracingReducer(newState, addToContourListActionFn(contourList[1]));
newState = VolumeTracingReducer(newState, addToContourListActionFn(contourList[2]));

return {
newState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { setToolAction } from "viewer/model/actions/ui_actions";
import { setPositionAction } from "viewer/model/actions/flycam_actions";
import {
setActiveCellAction,
addToLayerAction,
addToContourListAction,
startEditingAction,
finishEditingAction,
} from "viewer/model/actions/volumetracing_actions";
Expand Down Expand Up @@ -60,7 +60,7 @@ export async function testLabelingManyBuckets(
for (const paintPosition of paintPositions1) {
Store.dispatch(setPositionAction(paintPosition));
Store.dispatch(startEditingAction(paintPosition, OrthoViews.PLANE_XY));
Store.dispatch(addToLayerAction(paintPosition));
Store.dispatch(addToContourListAction(paintPosition));
Store.dispatch(finishEditingAction());
}

Expand All @@ -73,7 +73,7 @@ export async function testLabelingManyBuckets(
for (const paintPosition of paintPositions2) {
Store.dispatch(setPositionAction(paintPosition));
Store.dispatch(startEditingAction(paintPosition, OrthoViews.PLANE_XY));
Store.dispatch(addToLayerAction(paintPosition));
Store.dispatch(addToContourListAction(paintPosition));
Store.dispatch(finishEditingAction());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import * as VolumeTracingActions from "viewer/model/actions/volumetracing_action
import { expectValueDeepEqual, execCall } from "test/helpers/sagaHelpers";
import type { ActiveMappingInfo } from "viewer/store";
import { askUserForLockingActiveMapping } from "viewer/model/sagas/saga_helpers";
import { editVolumeLayerAsync, finishLayer } from "viewer/model/sagas/volumetracing_saga";
import { editVolumeLayerAsync, finishSectionLabeler } from "viewer/model/sagas/volumetracing_saga";
import {
requestBucketModificationInVolumeTracing,
ensureMaybeActiveMappingIsLocked,
} from "viewer/model/sagas/saga_helpers";
import VolumeLayer from "viewer/model/volumetracing/volumelayer";
import SectionLabeler from "viewer/model/volumetracing/section_labeling";
import { serverVolumeToClientVolumeTracing } from "viewer/model/reducers/volumetracing_reducer";
import { Model, Store } from "viewer/singletons";
import { hasRootSagaCrashed } from "viewer/model/sagas/root_saga";
Expand All @@ -39,7 +39,7 @@ const ensureMaybeMappingIsLockedReturnValueDummy = { isMappingLockedIfNeeded: tr
const ACTIVE_CELL_ID = 5;
const setActiveCellAction = VolumeTracingActions.setActiveCellAction(ACTIVE_CELL_ID);
const startEditingAction = VolumeTracingActions.startEditingAction([0, 0, 0], OrthoViews.PLANE_XY);
const addToLayerActionFn = VolumeTracingActions.addToLayerAction;
const addToContourListActionFn = VolumeTracingActions.addToContourListAction;
const finishEditingAction = VolumeTracingActions.finishEditingAction();

describe("VolumeTracingSaga", () => {
Expand Down Expand Up @@ -158,23 +158,23 @@ describe("VolumeTracingSaga", () => {
);
saga.next(); // advance from the put action

const volumeLayer = new VolumeLayer(
const sectionLabeler = new SectionLabeler(
volumeTracing.tracingId,
OrthoViews.PLANE_XY,
10,
[1, 1, 1],
);
saga.next(volumeLayer);
saga.next(sectionLabeler);
saga.next(OrthoViews.PLANE_XY);
saga.next("action_channel");
saga.next(addToLayerActionFn([1, 2, 3]));
saga.next(addToContourListActionFn([1, 2, 3]));
saga.next(OrthoViews.PLANE_XY);
saga.next(addToLayerActionFn([2, 3, 4]));
saga.next(addToContourListActionFn([2, 3, 4]));
saga.next(OrthoViews.PLANE_XY);
saga.next(addToLayerActionFn([3, 4, 5]));
saga.next(addToContourListActionFn([3, 4, 5]));
saga.next(OrthoViews.PLANE_XY);
expect(volumeLayer.minCoord).toEqual([-1, 0, 1]);
expect(volumeLayer.maxCoord).toEqual([5, 6, 7]);
expect(sectionLabeler.minCoord).toEqual([-1, 0, 1]);
expect(sectionLabeler.maxCoord).toEqual([5, 6, 7]);
});

it("should finish a volume layer (saga test)", () => {
Expand Down Expand Up @@ -213,16 +213,16 @@ describe("VolumeTracingSaga", () => {
);
saga.next(); // advance from the put action

const volumeLayer = new VolumeLayer(
const sectionLabeler = new SectionLabeler(
volumeTracing.tracingId,
OrthoViews.PLANE_XY,
10,
[1, 1, 1],
);
saga.next(volumeLayer);
saga.next(sectionLabeler);
saga.next(OrthoViews.PLANE_XY);
saga.next("action_channel");
saga.next(addToLayerActionFn([1, 2, 3]));
saga.next(addToContourListActionFn([1, 2, 3]));
saga.next(OrthoViews.PLANE_XY);
// Validate that finishLayer was called
const wroteVoxelsBox = {
Expand All @@ -232,13 +232,12 @@ describe("VolumeTracingSaga", () => {
expect,
saga.next(finishEditingAction),
call(
finishLayer,
volumeLayer,
finishSectionLabeler,
sectionLabeler,
AnnotationTool.TRACE,
ContourModeEnum.DRAW,
OverwriteModeEnum.OVERWRITE_ALL,
0,
OrthoViews.PLANE_XY,
wroteVoxelsBox,
),
);
Expand Down Expand Up @@ -282,16 +281,16 @@ describe("VolumeTracingSaga", () => {
);
saga.next(); // advance from the put action

const volumeLayer = new VolumeLayer(
const sectionLabeler = new SectionLabeler(
volumeTracing.tracingId,
OrthoViews.PLANE_XY,
10,
[1, 1, 1],
);
saga.next(volumeLayer);
saga.next(sectionLabeler);
saga.next(OrthoViews.PLANE_XY);
saga.next("action_channel");
saga.next(addToLayerActionFn([1, 2, 3]));
saga.next(addToContourListActionFn([1, 2, 3]));
saga.next(OrthoViews.PLANE_XY);
const wroteVoxelsBox = {
value: false,
Expand All @@ -301,13 +300,12 @@ describe("VolumeTracingSaga", () => {
expect,
saga.next(finishEditingAction),
call(
finishLayer,
volumeLayer,
finishSectionLabeler,
sectionLabeler,
AnnotationTool.TRACE,
ContourModeEnum.DELETE,
OverwriteModeEnum.OVERWRITE_ALL,
0,
OrthoViews.PLANE_XY,
wroteVoxelsBox,
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
setSegmentGroupsAction,
updateSegmentAction,
setActiveCellAction,
addToLayerAction,
addToContourListAction,
startEditingAction,
finishEditingAction,
setContourTracingModeAction,
Expand Down Expand Up @@ -69,12 +69,12 @@ describe("Volume Tracing", () => {
// Brush with ${newCellId}
Store.dispatch(setActiveCellAction(newCellId));
Store.dispatch(startEditingAction(paintCenter, OrthoViews.PLANE_XY));
Store.dispatch(addToLayerAction(paintCenter));
Store.dispatch(addToContourListAction(paintCenter));
Store.dispatch(finishEditingAction());
// Brush with ${newCellId + 1}
Store.dispatch(setActiveCellAction(newCellId + 1));
Store.dispatch(startEditingAction(paintCenter, OrthoViews.PLANE_XY));
Store.dispatch(addToLayerAction(paintCenter));
Store.dispatch(addToContourListAction(paintCenter));
Store.dispatch(finishEditingAction());

expect(
Expand Down Expand Up @@ -129,7 +129,7 @@ describe("Volume Tracing", () => {
Store.dispatch(setToolAction(AnnotationTool.BRUSH));
Store.dispatch(setActiveCellAction(newCellId));
Store.dispatch(startEditingAction(paintCenter, OrthoViews.PLANE_XY));
Store.dispatch(addToLayerAction(paintCenter));
Store.dispatch(addToContourListAction(paintCenter));
Store.dispatch(finishEditingAction());
await api.tracing.save();

Expand Down Expand Up @@ -183,7 +183,7 @@ describe("Volume Tracing", () => {
Store.dispatch(setPositionAction([0, 0, 0]));
Store.dispatch(setToolAction(AnnotationTool.ERASE_BRUSH));
Store.dispatch(startEditingAction(paintCenter, OrthoViews.PLANE_XY));
Store.dispatch(addToLayerAction(paintCenter));
Store.dispatch(addToContourListAction(paintCenter));
Store.dispatch(finishEditingAction());

await api.tracing.save();
Expand Down Expand Up @@ -233,7 +233,7 @@ describe("Volume Tracing", () => {
Store.dispatch(setPositionAction([0, 0, 0]));
Store.dispatch(setToolAction(AnnotationTool.ERASE_BRUSH));
Store.dispatch(startEditingAction(paintCenter, OrthoViews.PLANE_XY));
Store.dispatch(addToLayerAction(paintCenter));
Store.dispatch(addToContourListAction(paintCenter));
Store.dispatch(finishEditingAction());

if (loadBeforeUndo) {
Expand Down Expand Up @@ -279,7 +279,7 @@ describe("Volume Tracing", () => {
Store.dispatch(setPositionAction([0, 0, 0]));
Store.dispatch(setToolAction(AnnotationTool.ERASE_BRUSH));
Store.dispatch(startEditingAction(paintCenter, OrthoViews.PLANE_XY));
Store.dispatch(addToLayerAction(paintCenter));
Store.dispatch(addToContourListAction(paintCenter));
Store.dispatch(finishEditingAction());

for (let zoomStep = 0; zoomStep <= 5; zoomStep++) {
Expand Down
Loading
Loading