Skip to content

Commit

Permalink
feat: Max projection volume rendering with picking (#552)
Browse files Browse the repository at this point in the history
  • Loading branch information
seankmartin authored Apr 11, 2024
1 parent 3bab8b0 commit a52552e
Show file tree
Hide file tree
Showing 12 changed files with 517 additions and 42 deletions.
2 changes: 1 addition & 1 deletion python/neuroglancer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
PlaceEllipsoidTool, # noqa: F401
BlendTool, # noqa: F401
OpacityTool, # noqa: F401
VolumeRenderingTool, # noqa: F401
VolumeRenderingModeTool, # noqa: F401
VolumeRenderingGainTool, # noqa: F401
VolumeRenderingDepthSamplesTool, # noqa: F401
CrossSectionRenderScaleTool, # noqa: F401
Expand Down
6 changes: 6 additions & 0 deletions python/neuroglancer/json_wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,9 @@ def number_or_string(value):
if not isinstance(value, numbers.Real) and not isinstance(value, str):
raise TypeError
return value


def bool_or_string(value):
if not isinstance(value, (bool, str)):
raise TypeError
return value
11 changes: 6 additions & 5 deletions python/neuroglancer/viewer_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
TypedList,
TypedStringMap,
array_wrapper,
bool_or_string,
number_or_string,
optional,
text_type,
Expand Down Expand Up @@ -164,9 +165,9 @@ class OpacityTool(Tool):


@export_tool
class VolumeRenderingTool(Tool):
class VolumeRenderingModeTool(Tool):
__slots__ = ()
TOOL_TYPE = "volumeRendering"
TOOL_TYPE = "volumeRenderingMode"


@export_tool
Expand Down Expand Up @@ -554,11 +555,11 @@ def __init__(self, *args, **kwargs):
)
opacity = wrapped_property("opacity", optional(float, 0.5))
blend = wrapped_property("blend", optional(str))
volume_rendering = volumeRendering = wrapped_property(
"volumeRendering", optional(bool, False)
volume_rendering_mode = volumeRenderingMode = VolumeRendering = volume_rendering = (
wrapped_property("volumeRendering", optional(bool_or_string, False))
)
volume_rendering_gain = volumeRenderingGain = wrapped_property(
"volumeRenderingGain", optional(float, 1)
"volumeRenderingGain", optional(float, 0)
)
volume_rendering_depth_samples = volumeRenderingDepthSamples = wrapped_property(
"volumeRenderingDepthSamples", optional(float, 64)
Expand Down
65 changes: 49 additions & 16 deletions src/layer/image/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import {
} from "#src/sliceview/volume/image_renderlayer.js";
import { trackableAlphaValue } from "#src/trackable_alpha.js";
import { trackableBlendModeValue } from "#src/trackable_blend.js";
import { TrackableBoolean } from "#src/trackable_boolean.js";
import { trackableFiniteFloat } from "#src/trackable_finite_float.js";
import type { WatchableValueInterface } from "#src/trackable_value.js";
import {
Expand All @@ -63,6 +62,10 @@ import { setClipboard } from "#src/util/clipboard.js";
import type { Borrowed } from "#src/util/disposable.js";
import { makeValueOrError } from "#src/util/error.js";
import { verifyOptionalObjectProperty } from "#src/util/json.js";
import {
trackableShaderModeValue,
VolumeRenderingModes,
} from "#src/volume_rendering/trackable_volume_rendering_mode.js";
import {
getVolumeRenderingDepthSamplesBoundsLogScale,
VOLUME_RENDERING_DEPTH_SAMPLES_DEFAULT_VALUE,
Expand All @@ -84,7 +87,6 @@ import {
addLayerControlToOptionsTab,
registerLayerControl,
} from "#src/widget/layer_control.js";
import { checkboxLayerControl } from "#src/widget/layer_control_checkbox.js";
import { enumLayerControl } from "#src/widget/layer_control_enum.js";
import { rangeLayerControl } from "#src/widget/layer_control_range.js";
import { makeMaximizeButton } from "#src/widget/maximize_button.js";
Expand Down Expand Up @@ -149,7 +151,7 @@ export class ImageUserLayer extends Base {
this.channelCoordinateSpace,
),
);
volumeRendering = new TrackableBoolean(false, false);
volumeRenderingMode = trackableShaderModeValue();

shaderControlState = this.registerDisposer(
new ShaderControlState(
Expand Down Expand Up @@ -208,7 +210,7 @@ export class ImageUserLayer extends Base {
this.sliceViewRenderScaleTarget.changed.add(
this.specificationChanged.dispatch,
);
this.volumeRendering.changed.add(this.specificationChanged.dispatch);
this.volumeRenderingMode.changed.add(this.specificationChanged.dispatch);
this.volumeRenderingDepthSamplesTarget.changed.add(
this.specificationChanged.dispatch,
);
Expand Down Expand Up @@ -268,18 +270,19 @@ export class ImageUserLayer extends Base {
this.volumeRenderingChunkResolutionHistogram,
localPosition: this.localPosition,
channelCoordinateSpace: this.channelCoordinateSpace,
mode: this.volumeRenderingMode,
}),
);
context.registerDisposer(
loadedSubsource.messages.addChild(volumeRenderLayer.messages),
);
context.registerDisposer(
registerNested((context, volumeRendering) => {
if (!volumeRendering) return;
registerNested((context, volumeRenderingMode) => {
if (volumeRenderingMode === VolumeRenderingModes.OFF) return;
context.registerDisposer(
this.addRenderLayer(volumeRenderLayer.addRef()),
);
}, this.volumeRendering),
}, this.volumeRenderingMode),
);
this.shaderError.changed.dispatch();
});
Expand All @@ -303,12 +306,32 @@ export class ImageUserLayer extends Base {
this.channelCoordinateSpace.restoreState(
specification[CHANNEL_DIMENSIONS_JSON_KEY],
);
this.volumeRendering.restoreState(specification[VOLUME_RENDERING_JSON_KEY]);
this.volumeRenderingGain.restoreState(
specification[VOLUME_RENDERING_GAIN_JSON_KEY],
verifyOptionalObjectProperty(
specification,
VOLUME_RENDERING_JSON_KEY,
(volumeRenderingMode) => {
if (typeof volumeRenderingMode === "boolean") {
this.volumeRenderingMode.value = volumeRenderingMode
? VolumeRenderingModes.ON
: VolumeRenderingModes.OFF;
} else {
this.volumeRenderingMode.restoreState(volumeRenderingMode);
}
},
);
verifyOptionalObjectProperty(
specification,
VOLUME_RENDERING_GAIN_JSON_KEY,
(volumeRenderingGain) =>
this.volumeRenderingGain.restoreState(volumeRenderingGain),
);
this.volumeRenderingDepthSamplesTarget.restoreState(
specification[VOLUME_RENDERING_DEPTH_SAMPLES_JSON_KEY],
verifyOptionalObjectProperty(
specification,
VOLUME_RENDERING_DEPTH_SAMPLES_JSON_KEY,
(volumeRenderingDepthSamplesTarget) =>
this.volumeRenderingDepthSamplesTarget.restoreState(
volumeRenderingDepthSamplesTarget,
),
);
}
toJSON() {
Expand All @@ -320,7 +343,7 @@ export class ImageUserLayer extends Base {
x[CROSS_SECTION_RENDER_SCALE_JSON_KEY] =
this.sliceViewRenderScaleTarget.toJSON();
x[CHANNEL_DIMENSIONS_JSON_KEY] = this.channelCoordinateSpace.toJSON();
x[VOLUME_RENDERING_JSON_KEY] = this.volumeRendering.toJSON();
x[VOLUME_RENDERING_JSON_KEY] = this.volumeRenderingMode.toJSON();
x[VOLUME_RENDERING_GAIN_JSON_KEY] = this.volumeRenderingGain.toJSON();
x[VOLUME_RENDERING_DEPTH_SAMPLES_JSON_KEY] =
this.volumeRenderingDepthSamplesTarget.toJSON();
Expand Down Expand Up @@ -458,12 +481,17 @@ const LAYER_CONTROLS: LayerControlDefinition<ImageUserLayer>[] = [
{
label: "Volume rendering (experimental)",
toolJson: VOLUME_RENDERING_JSON_KEY,
...checkboxLayerControl((layer) => layer.volumeRendering),
...enumLayerControl((layer) => layer.volumeRenderingMode),
},
{
label: "Gain (3D)",
toolJson: VOLUME_RENDERING_GAIN_JSON_KEY,
isValid: (layer) => layer.volumeRendering,
isValid: (layer) =>
makeCachedDerivedWatchableValue(
(volumeRenderingMode) =>
volumeRenderingMode === VolumeRenderingModes.ON,
[layer.volumeRenderingMode],
),
...rangeLayerControl((layer) => ({
value: layer.volumeRenderingGain,
options: { min: -10.0, max: 10.0, step: 0.1 },
Expand All @@ -472,7 +500,12 @@ const LAYER_CONTROLS: LayerControlDefinition<ImageUserLayer>[] = [
{
label: "Resolution (3D)",
toolJson: VOLUME_RENDERING_DEPTH_SAMPLES_JSON_KEY,
isValid: (layer) => layer.volumeRendering,
isValid: (layer) =>
makeCachedDerivedWatchableValue(
(volumeRenderingMode) =>
volumeRenderingMode !== VolumeRenderingModes.OFF,
[layer.volumeRenderingMode],
),
...renderScaleLayerControl(
(layer) => ({
histogram: layer.volumeRenderingChunkResolutionHistogram,
Expand Down
Loading

0 comments on commit a52552e

Please sign in to comment.