Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persist tree visibility #3942

Merged
merged 36 commits into from
Apr 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5a46836
add visibility to trees and responding update actions #3666
Mar 14, 2019
d41ddcc
adapt behavior when called with no isVisible attribute #3503
Mar 14, 2019
0ca6785
Merge branch 'master' of github.com:scalableminds/webknossos into per…
Mar 20, 2019
1511f56
Merge branch 'master' of github.com:scalableminds/webknossos into per…
philippotto Mar 25, 2019
82873b7
read and update isVisible per tree
philippotto Mar 25, 2019
1da34d5
implement 'smart' compaction logic for toggling tree groups
philippotto Mar 27, 2019
91a6bd9
Merge branch 'persist-tree-visibility' of github.com:scalableminds/we…
philippotto Mar 27, 2019
8d22171
Merge branch 'master' of github.com:scalableminds/webknossos into
Mar 28, 2019
f86bc9b
add update-tree-visibility updateAction #3942
Mar 28, 2019
9cf6cc2
make tree visibility persistence work
philippotto Mar 28, 2019
0b18703
extract compaction logic into separate modules
philippotto Mar 28, 2019
40c530e
fix flow
philippotto Mar 28, 2019
b393f08
fix linting
philippotto Mar 28, 2019
394db6f
add comments and more typing
philippotto Mar 28, 2019
b2f1444
update changelog
philippotto Mar 28, 2019
8893a17
fix existing tests
philippotto Mar 28, 2019
fceaa54
fix existing tests
philippotto Apr 1, 2019
2d4e33e
tmp: add new tests for compact toggle actions
philippotto Apr 1, 2019
1c566b8
Merge branch 'master' of github.com:scalableminds/webknossos into per…
philippotto Apr 3, 2019
cb9d5fc
make compact-toggle tests work
philippotto Apr 4, 2019
c918855
extract defaultState into own module; fix flow for compact-toggle-tests
philippotto Apr 4, 2019
10dc038
Update frontend/javascripts/oxalis/model/helpers/compaction/compact_t…
daniel-wer Apr 4, 2019
d78266b
incorporate further feedback
philippotto Apr 4, 2019
c6248b6
Merge branch 'persist-tree-visibility' of github.com:scalableminds/we…
philippotto Apr 4, 2019
fd5bda7
add comment to clarify null handling of isVisible
Apr 4, 2019
30a5b23
Merge branch 'persist-tree-visibility' of github.com:scalableminds/we…
Apr 4, 2019
0f58984
use tree.isVisible = true if isVisible is undefined
philippotto Apr 4, 2019
518ade5
don't render invisible trees when loading tracing
philippotto Apr 4, 2019
405cf98
Merge branch 'persist-tree-visibility' of github.com:scalableminds/we…
philippotto Apr 4, 2019
8fe3495
change tree visibility recursively #3942
Apr 4, 2019
42eab50
Merge branch 'persist-tree-visibility' of github.com:scalableminds/we…
Apr 4, 2019
0d25d80
Merge branch 'master' into persist-tree-visibility
youri-k Apr 4, 2019
420c076
improve readability
Apr 4, 2019
ca4d17b
Merge branch 'persist-tree-visibility' of github.com:scalableminds/we…
Apr 4, 2019
13e3f9b
Merge branch 'master' of github.com:scalableminds/webknossos into per…
philippotto Apr 8, 2019
7890730
fix missing handling of empty groups when compacting toggle actions
philippotto Apr 8, 2019
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Also the data viewing and tracing workflow is smoothed further:
- Segmentation ID mappings can now be used in volume and hybrid tracings. [#3949](https://github.com/scalableminds/webknossos/pull/3949)
- A maximize-button was added to the viewports in the annotation view. Maximization can also be toggled with the `.` shortcut. [#3876](https://github.com/scalableminds/webknossos/pull/3876)
- [webknossos-connect](https://github.com/scalableminds/webknossos-connect) now starts with webKnossos on local and development instances by default. [#3913](https://github.com/scalableminds/webknossos/pull/3913)
- The visibilities of trees in a skeleton tracing is now persisted across page loads. [#3942](https://github.com/scalableminds/webknossos/pull/3942)
- Added a button for each color layer to enable/disable the layer. [#3943](https://github.com/scalableminds/webknossos/pull/3943)
- Paginated routes now send a `X-Total-Count` HTTP header which shows how many entries were found in total. [#3899](https://github.com/scalableminds/webknossos/pull/3899)

Expand Down
1 change: 1 addition & 0 deletions frontend/javascripts/admin/api_flow_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ export type ServerSkeletonTracingTree = {
treeId: number,
createdTimestamp: number,
groupId?: ?number,
isVisible?: boolean,
};

export type ServerTracingBase = {|
Expand Down
195 changes: 195 additions & 0 deletions frontend/javascripts/oxalis/default_state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
// @flow

import type { OxalisState } from "oxalis/store";
import Constants, { ControlModeEnum, OrthoViews } from "oxalis/constants";

const defaultViewportRect = {
top: 0,
left: 0,
width: Constants.VIEWPORT_WIDTH,
height: Constants.VIEWPORT_WIDTH,
};

const initialAnnotationInfo = {
annotationId: "",
restrictions: {
branchPointsAllowed: false,
allowUpdate: false,
allowFinish: false,
allowAccess: true,
allowDownload: false,
somaClickingAllowed: false,
allowedModes: ["orthogonal", "oblique", "flight"],
},
isPublic: false,
tags: [],
description: "",
name: "",
tracingStore: {
name: "localhost",
url: "http://localhost:9000",
},
annotationType: "View",
meshes: [],
};

const defaultState: OxalisState = {
datasetConfiguration: {
fourBit: false,
interpolation: false,
layers: {},
quality: 0,
loadingStrategy: "PROGRESSIVE_QUALITY",
segmentationOpacity: 20,
highlightHoveredCellId: true,
renderIsosurfaces: false,
renderMissingDataBlack: true,
},
userConfiguration: {
autoSaveLayouts: true,
brushSize: 50,
clippingDistance: 50,
clippingDistanceArbitrary: 64,
crosshairSize: 0.1,
displayCrosshair: true,
displayScalebars: true,
dynamicSpaceDirection: true,
hideTreeRemovalWarning: false,
highlightCommentedNodes: false,
keyboardDelay: 200,
layoutScaleValue: 1,
mouseRotateValue: 0.004,
moveValue3d: 300,
moveValue: 300,
newNodeNewTree: false,
overrideNodeRadius: true,
particleSize: 5,
radius: 5,
rotateValue: 0.01,
sortCommentsAsc: true,
sortTreesByName: false,
sphericalCapRadius: Constants.DEFAULT_SPHERICAL_CAP_RADIUS,
tdViewDisplayPlanes: true,
},
temporaryConfiguration: {
viewMode: Constants.MODE_PLANE_TRACING,
flightmodeRecording: false,
controlMode: ControlModeEnum.VIEW,
mousePosition: null,
hoveredIsosurfaceId: 0,
activeMapping: {
mappingName: null,
mapping: null,
mappingColors: null,
hideUnmappedIds: false,
isMappingEnabled: false,
mappingSize: 0,
},
isMergerModeEnabled: false,
},
task: null,
dataset: {
name: "Test Dataset",
isUnreported: false,
created: 123,
dataSource: {
dataLayers: [],
scale: [5, 5, 5],
id: {
name: "Test Dataset",
team: "",
},
},
details: null,
isPublic: false,
isActive: true,
isEditable: true,
dataStore: {
name: "localhost",
url: "http://localhost:9000",
isScratch: false,
isForeign: false,
isConnector: false,
},
owningOrganization: "Connectomics department",
description: null,
displayName: "Awesome Test Dataset",
allowedTeams: [],
logoUrl: null,
lastUsedByUser: 0,
isForeign: false,
sortingKey: 123,
publication: null,
},
tracing: {
...initialAnnotationInfo,
readOnly: {
boundingBox: null,
createdTimestamp: 0,
userBoundingBox: null,
type: "readonly",
version: 0,
tracingId: "",
},
volume: null,
skeleton: null,
user: null,
},
save: {
queue: {
skeleton: [],
volume: [],
},
isBusyInfo: {
skeleton: false,
volume: false,
},
lastSaveTimestamp: 0,
progressInfo: {
processedActionCount: 0,
totalActionCount: 0,
},
},
flycam: {
zoomStep: 1.3,
currentMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
spaceDirectionOrtho: [1, 1, 1],
direction: [0, 0, 0],
},
viewModeData: {
plane: {
activeViewport: OrthoViews.PLANE_XY,
tdCamera: {
near: 0,
far: 0,
left: 0,
right: 0,
top: 0,
bottom: 0,
up: [0, 0, 0],
lookAt: [0, 0, 0],
position: [0, 0, 0],
},
inputCatcherRects: {
PLANE_XY: defaultViewportRect,
PLANE_YZ: defaultViewportRect,
PLANE_XZ: defaultViewportRect,
TDView: defaultViewportRect,
},
},
arbitrary: {
inputCatcherRect: defaultViewportRect,
},
},
activeUser: null,
uiInformation: {
showDropzoneModal: false,
showVersionRestore: false,
storedLayouts: {},
isImportingMesh: false,
isInAnnotationView: false,
hasOrganizations: false,
},
};

export default defaultState;
10 changes: 5 additions & 5 deletions frontend/javascripts/oxalis/geometries/skeleton.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ class Skeleton {
*/
refresh(skeletonTracing: SkeletonTracing) {
const state = Store.getState();
const diff = cachedDiffTrees(this.prevTracing.trees, skeletonTracing.trees);
const diff = cachedDiffTrees(this.prevTracing, skeletonTracing);

for (const update of diff) {
switch (update.name) {
Expand Down Expand Up @@ -312,8 +312,8 @@ class Skeleton {
case "createTree":
this.updateTreeColor(update.value.id, update.value.color);
break;
case "toggleTree": {
const treeId = update.value.id;
case "updateTreeVisibility": {
const { treeId } = update.value;
const tree = skeletonTracing.trees[treeId];
this.updateTreeColor(treeId, tree.color, tree.isVisible);
break;
Expand Down Expand Up @@ -355,7 +355,7 @@ class Skeleton {
// Unused for now
break;
default:
throw new Error("[Skeleton] Unhandled skeletontracing diff action");
throw new Error(`[Skeleton] Unhandled skeletontracing diff action: ${update.name}`);
}
}

Expand Down Expand Up @@ -439,7 +439,7 @@ class Skeleton {
this.createEdge(tree.treeId, source, target);
}

this.updateTreeColor(tree.treeId, tree.color);
this.updateTreeColor(tree.treeId, tree.color, tree.isVisible);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ export const SkeletonTracingSaveRelevantActions = [
"SET_TREE_GROUPS",
"SET_TREE_GROUP",
"SET_MERGER_MODE_ENABLED",
"TOGGLE_TREE",
"TOGGLE_TREE_GROUP",
"TOGGLE_ALL_TREES",
"TOGGLE_INACTIVE_TREES",
];

const noAction = (): NoAction => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// @flow

import _ from "lodash";

import type { SaveQueueEntry } from "oxalis/store";

function removeAllButLastUpdateTracingAction(updateActionsBatches: Array<SaveQueueEntry>) {
// This part of the code removes all entries from the save queue that consist only of
// one updateTracing update action, except for the last one
const updateTracingOnlyBatches = updateActionsBatches.filter(
batch => batch.actions.length === 1 && batch.actions[0].name === "updateTracing",
);
return _.without(updateActionsBatches, ...updateTracingOnlyBatches.slice(0, -1));
}

function removeSubsequentUpdateTreeActions(updateActionsBatches: Array<SaveQueueEntry>) {
const obsoleteUpdateActions = [];
// If two updateTree update actions for the same treeId follow one another, the first one is obsolete
for (let i = 0; i < updateActionsBatches.length - 1; i++) {
const actions1 = updateActionsBatches[i].actions;
const actions2 = updateActionsBatches[i + 1].actions;
if (
actions1.length === 1 &&
actions1[0].name === "updateTree" &&
actions2.length === 1 &&
actions2[0].name === "updateTree" &&
actions1[0].value.id === actions2[0].value.id
) {
obsoleteUpdateActions.push(updateActionsBatches[i]);
}
}
return _.without(updateActionsBatches, ...obsoleteUpdateActions);
}

export default function compactSaveQueue(
updateActionsBatches: Array<SaveQueueEntry>,
): Array<SaveQueueEntry> {
// Remove empty batches
const result = updateActionsBatches.filter(
updateActionsBatch => updateActionsBatch.actions.length > 0,
);

return removeSubsequentUpdateTreeActions(removeAllButLastUpdateTracingAction(result));
}
Loading