Skip to content

Commit

Permalink
feat(createImageRenderingActor): add color range min/max
Browse files Browse the repository at this point in the history
Min max color range source of truth is still colorRange array,
but we the auto adjust boolean bookkeeping is per min and max.
Was just one boolean for colorRange before.
  • Loading branch information
PaulHax committed Dec 21, 2023
1 parent 2138166 commit 14fef1c
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 16 deletions.
2 changes: 2 additions & 0 deletions examples/test-conglomerate.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
]
viewer.setImagePiecewiseFunctionPoints(newPoints, 0)
viewer.setImageColorMap('glasbey', 0)
viewer.setImageColorRangeMin(30)
viewer.setImageColorRangeMax(200)
window.viewer = viewer
}

Expand Down
3 changes: 2 additions & 1 deletion src/Context/ImageActorContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class ImageActorContext {

// Keep growing component ranges as new parts of the image are loaded
// Map of image intensity component to Boolean
colorRangesAutoAdjust = null
colorRangeMinAutoAdjust = null
colorRangeMaxAutoAdjust = null

// Map of image intensity component to array of [minBound, maxBound] for
// limiting the color range in the UI
Expand Down
8 changes: 8 additions & 0 deletions src/ImJoyPluginAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@ class ImJoyPluginAPI {
return this.viewer.getImageColorRange(component, name)
}

setImageColorRangeMin(min, component, name) {
this.viewer.setImageColorRangeMin(min, component, name)
}

setImageColorRangeMax(max, component, name) {
this.viewer.setImageColorRangeMax(max, component, name)
}

setImageColorRangeBounds(bounds, component, name) {
this.viewer.setImageColorRangeBounds(bounds, component, name)
}
Expand Down
75 changes: 71 additions & 4 deletions src/Rendering/Images/createImageRenderingActor.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,77 @@ const assignColorRange = assign({
{ images },
{ data: { name, component, range, keepAutoAdjusting = false } }
) => {
const { colorRanges, colorRangesAutoAdjust } = images.actorContext.get(name)
const {
colorRanges,
colorRangeMinAutoAdjust,
colorRangeMaxAutoAdjust,
} = images.actorContext.get(name)

colorRanges.set(component, range)

colorRangesAutoAdjust.set(
colorRangeMinAutoAdjust.set(
component,
colorRangesAutoAdjust.get(component) && keepAutoAdjusting
colorRangeMinAutoAdjust.get(component) && keepAutoAdjusting
)
colorRangeMaxAutoAdjust.set(
component,
colorRangeMaxAutoAdjust.get(component) && keepAutoAdjusting
)

return images
},
})

const assignColorRangeMin = assign({
images: ({ images }, { data: { name, component } }) => {
const { colorRangeMinAutoAdjust } = images.actorContext.get(name)
colorRangeMinAutoAdjust.set(component, false)
return images
},
})

const updateColorRangeMin = (context, e) => {
const {
data: { name, component, value },
} = e
const { colorRanges } = context.images.actorContext.get(name)
const [, max] = colorRanges.get(component)
context.service.send({
type: 'IMAGE_COLOR_RANGE_CHANGED',
data: {
name,
component,
range: [value, max],
keepAutoAdjusting: true, // let max change
},
})
}

const assignColorRangeMax = assign({
images: ({ images }, { data: { name, component } }) => {
const { colorRangeMaxAutoAdjust } = images.actorContext.get(name)
colorRangeMaxAutoAdjust.set(component, false)
return images
},
})

const updateColorRangeMax = (context, e) => {
const {
data: { name, component, value },
} = e
const { colorRanges } = context.images.actorContext.get(name)
const [min] = colorRanges.get(component)
context.service.send({
type: 'IMAGE_COLOR_RANGE_CHANGED',
data: {
name,
component,
range: [min, value],
keepAutoAdjusting: true, // let min change
},
})
}

const assignUpdateRenderedName = assign({
images: (context, event) => {
const images = context.images
Expand Down Expand Up @@ -316,7 +374,10 @@ const cleanColorRanges = (c, { data: { name } }) => {
actorContext.colorRangeBoundsAutoAdjust = new Map(
[...Array(componentCount).keys()].map(c => [c, true])
)
actorContext.colorRangesAutoAdjust = new Map(
actorContext.colorRangeMinAutoAdjust = new Map(
[...Array(componentCount).keys()].map(c => [c, true])
)
actorContext.colorRangeMaxAutoAdjust = new Map(
[...Array(componentCount).keys()].map(c => [c, true])
)
actorContext.piecewiseFunctionPointsAutoAdjust = new Map(
Expand Down Expand Up @@ -481,6 +542,12 @@ const eventResponses = {
IMAGE_COLOR_RANGE_CHANGED: {
actions: [assignColorRange, 'applyColorRange'],
},
IMAGE_COLOR_RANGE_MIN_CHANGED: {
actions: [assignColorRangeMin, updateColorRangeMin],
},
IMAGE_COLOR_RANGE_MAX_CHANGED: {
actions: [assignColorRangeMax, updateColorRangeMax],
},
IMAGE_COLOR_RANGE_POINTS_CHANGED: {
actions: 'mapToColorFunctionRange',
},
Expand Down
2 changes: 2 additions & 0 deletions src/Rendering/Images/createImagesRenderingMachine.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ function createImagesRenderingMachine(options, context) {
'IMAGE_COLOR_RANGE_RESET',
'ANIMATE_IMAGE_MIX',
'TOGGLE_LAYER_BBOX',
'IMAGE_COLOR_RANGE_MIN_CHANGED',
'IMAGE_COLOR_RANGE_MAX_CHANGED',
],
{ actions: forwardToNamedActor }
),
Expand Down
10 changes: 8 additions & 2 deletions src/Rendering/VTKJS/Images/applyRenderedImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ function applyRenderedImage(context, { data: { name } }) {
colorRangeBoundsAutoAdjust,
colorRangeBounds,
colorRanges,
colorRangesAutoAdjust,
colorRangeMinAutoAdjust,
colorRangeMaxAutoAdjust,
} = actorContext

const dataArray = actorContext.fusedImage.getPointData().getScalars()
Expand All @@ -282,7 +283,9 @@ function applyRenderedImage(context, { data: { name } }) {
: [dataMin, dataMax]

const storedColorRange = colorRanges.get(componentIndex)
if (colorRangesAutoAdjust.get(componentIndex) || !storedColorRange) {
const minAutoAdjust = colorRangeMinAutoAdjust.get(componentIndex)
const maxAutoAdjust = colorRangeMaxAutoAdjust.get(componentIndex)
if (minAutoAdjust || maxAutoAdjust || !storedColorRange) {
const fullRange = actorContext.colorRangeBounds.get(componentIndex) ?? [
0,
1,
Expand All @@ -299,6 +302,9 @@ function applyRenderedImage(context, { data: { name } }) {
return x * newDelta + newMin
})

if (!minAutoAdjust) newRange[0] = range[0]
if (!maxAutoAdjust) newRange[1] = range[1]

context.service.send({
type: 'IMAGE_COLOR_RANGE_CHANGED',
data: {
Expand Down
6 changes: 6 additions & 0 deletions src/Rendering/createRenderingMachine.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ const createRenderingMachine = (options, context) => {
IMAGE_COLOR_RANGE_CHANGED: {
actions: forwardTo('images'),
},
IMAGE_COLOR_RANGE_MIN_CHANGED: {
actions: forwardTo('images'),
},
IMAGE_COLOR_RANGE_MAX_CHANGED: {
actions: forwardTo('images'),
},
IMAGE_COLOR_RANGE_POINTS_CHANGED: {
actions: forwardTo('images'),
},
Expand Down
15 changes: 6 additions & 9 deletions src/UI/Layers/createLayersUIMachine.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,12 @@ const assignImageContext = assign({
actorContext.colorRanges.set(component, [0.2, 0.8])
}

actorContext.colorRangesAutoAdjust = new Map(
[...Array(components).keys()].map(c => [c, true]) // { 0: true, 1: true, ... n: true}
)
actorContext.colorRangeBoundsAutoAdjust = new Map(
[...Array(components).keys()].map(c => [c, true])
)
actorContext.piecewiseFunctionPointsAutoAdjust = new Map(
[...Array(components).keys()].map(c => [c, true])
)
// make Maps like this: { 0: true, 1: true, ... n: true}
const trueForAll = [...Array(components).keys()].map(c => [c, true])
actorContext.colorRangeMinAutoAdjust = new Map([...trueForAll])
actorContext.colorRangeMaxAutoAdjust = new Map([...trueForAll])
actorContext.colorRangeBoundsAutoAdjust = new Map([...trueForAll])
actorContext.piecewiseFunctionPointsAutoAdjust = new Map([...trueForAll])

return images
},
Expand Down
18 changes: 18 additions & 0 deletions src/createViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,24 @@ const createViewer = async (
return actorContext.colorRanges.get(component)
}

publicAPI.setImageColorRangeMin = (value, component, name) => {
const selectedComponent = component ?? 0
const selectedName = name ?? context.images.selectedName
service.send({
type: 'IMAGE_COLOR_RANGE_MIN_CHANGED',
data: { name: selectedName, component: selectedComponent, value },
})
}

publicAPI.setImageColorRangeMax = (value, component, name) => {
const selectedComponent = component ?? 0
const selectedName = name ?? context.images.selectedName
service.send({
type: 'IMAGE_COLOR_RANGE_MAX_CHANGED',
data: { name: selectedName, component: selectedComponent, value },
})
}

publicAPI.setImageColorRangeBounds = (range, component, name) => {
if (typeof name === 'undefined') {
name = context.images.selectedName
Expand Down
6 changes: 6 additions & 0 deletions src/createViewerMachine.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ const createViewerMachine = (options, context, eventEmitterCallback) => {
forwardTo('eventEmitter'),
],
},
IMAGE_COLOR_RANGE_MIN_CHANGED: {
actions: [forwardTo('rendering')],
},
IMAGE_COLOR_RANGE_MAX_CHANGED: {
actions: [forwardTo('rendering')],
},
IMAGE_COLOR_RANGE_POINTS_CHANGED: {
actions: [forwardTo('rendering')],
},
Expand Down

0 comments on commit 14fef1c

Please sign in to comment.