From 4ee11b6b5fef1116c603f4e8eca3a93f1d7605a5 Mon Sep 17 00:00:00 2001 From: Andrew Champion Date: Wed, 7 Nov 2018 19:14:33 -0500 Subject: [PATCH] Add label annotation manager for label stacks See catmaid/CATMAID#1801. --- .../catmaid/static/js/label-annotations.js | 132 ++++++++++++++++++ django/projects/mysite/pipelinefiles.py | 1 + 2 files changed, 133 insertions(+) create mode 100644 django/applications/catmaid/static/js/label-annotations.js diff --git a/django/applications/catmaid/static/js/label-annotations.js b/django/applications/catmaid/static/js/label-annotations.js new file mode 100644 index 0000000000..8c5563e4df --- /dev/null +++ b/django/applications/catmaid/static/js/label-annotations.js @@ -0,0 +1,132 @@ +(function (CATMAID) { + + "use strict"; + + class LabelAnnotations { + constructor() { + this.managers = new Map(); + this.active = undefined; + } + + activate(stackID) { + this.active = stackID; + } + + clear() { + for (const [_stack, manager] of this.managers.entries()) manager.unregister(); + this.managers.clear(); + this.active = undefined; + } + + get(stack) { + let manager = this.managers.get(stack.id); + + if (!manager) { + manager = new LabelStackAnnotations(stack); + this.managers.set(stack.id, manager); + } + + return manager; + } + } + + CATMAID.LabelAnnotations = new LabelAnnotations(); + + CATMAID.Init.on(CATMAID.Init.EVENT_PROJECT_CHANGED, CATMAID.LabelAnnotations.clear, CATMAID.LabelAnnotations); + + + const LABEL_FILTER_KEY = 'Object Label Color Map'; + + class LabelStackAnnotations { + constructor( + stack + ) { + this.stack = stack; + this.activeLabelID = undefined; + this.specialLabels = { + background: 0, + }; + if (this.stack.metadata && + this.stack.metadata.catmaidLabelMeta && + this.stack.metadata.catmaidLabelMeta.specialLabels) { + $.extend(this.specialLabels, this.stack.metadata.catmaidLabelMeta.specialLabels); + } + this.stackLayerFilters = new Map(); + + project.on(CATMAID.Project.EVENT_STACKVIEW_ADDED, + this.registerStackViewerLayers, this); + CATMAID.StackViewer.on(CATMAID.StackViewer.EVENT_STACK_LAYER_ADDED, + this.registerStackLayer, this); + CATMAID.StackViewer.on(CATMAID.StackViewer.EVENT_STACK_LAYER_REMOVED, + this.unregisterStackLayer, this); + } + + unregister() { + project.off(CATMAID.Project.EVENT_STACKVIEW_ADDED, + this.registerStackViewerLayers, this); + CATMAID.StackViewer.off(CATMAID.StackViewer.EVENT_STACK_LAYER_ADDED, + this.registerStackLayer, this); + CATMAID.StackViewer.off(CATMAID.StackViewer.EVENT_STACK_LAYER_REMOVED, + this.unregisterStackLayer, this); + this.stackLayerFilters.clear(); + } + + activateLabel(labelID) { + this.activeLabelID = labelID; + + for (const [stackLayer, filter] of this.stackLayerFilters.entries()) { + this.updateFilter(filter); + stackLayer.redraw(); + stackLayer.stackViewer.layercontrol.refresh(); + } + } + + registerAllStackLayers() { + for (const stackViewer of project.getStackViewers()) { + this.registerStackViewerLayers(stackViewer); + } + } + + registerStackViewerLayers(stackViewer) { + for (const stackLayer of stackViewer.getLayersOfType(CATMAID.StackLayer)) { + this.registerStackLayer(stackLayer, stackViewer); + } + } + + registerStackLayer(stackLayer, stackViewer) { + if (this.stack.id !== stackLayer.stack.id) return; + + let layerFilters = stackLayer.getAvailableFilters ? stackLayer.getAvailableFilters() : []; + if (LABEL_FILTER_KEY in layerFilters && !this.stackLayerFilters.has(stackLayer)) { + stackLayer.setBlendMode('add'); + stackLayer.setInterpolationMode(false); // Nearest neighbor interpolation. + stackLayer.isHideable = true; + let filter = new (layerFilters[LABEL_FILTER_KEY])(); + this.updateFilter(filter); + stackLayer.addFilter(filter); + this.stackLayerFilters.set(stackLayer, filter); + + // TODO: coupling state refresh with stack viewer. + stackLayer.redraw(); + stackViewer.layercontrol.refresh(); + } + } + + unregisterStackLayer(stackLayer, stackViewer) { + if (this.stack.id !== stackLayer.stack.id) return; + + this.stackLayerFilters.delete(stackLayer); + } + + updateFilter(filter) { + filter.pixiFilter.backgroundLabel = CATMAID.PixiLayer.Filters.int2arr( + this.specialLabels.background); + filter.pixiFilter.unknownLabel = typeof this.activeLabelID === 'undefined' ? + [-1, -1, -1, -1] : + CATMAID.PixiLayer.Filters.int2arr(this.activeLabelID); + } + } + + CATMAID.LabelStackAnnotations = LabelStackAnnotations; + +})(CATMAID); diff --git a/django/projects/mysite/pipelinefiles.py b/django/projects/mysite/pipelinefiles.py index 732c6b5775..ef8358eedc 100644 --- a/django/projects/mysite/pipelinefiles.py +++ b/django/projects/mysite/pipelinefiles.py @@ -179,6 +179,7 @@ def update(self, other_dict, key_prefix='catmaid-ext-'): 'js/widgets/detail-dialog.js', 'js/widgets/options-dialog.js', 'js/3d/*.js', + 'js/label-annotations.js', 'js/widgets/*.js', ), 'output_filename': 'js/catmaid.js',