Skip to content

Commit 40a7c71

Browse files
committed
Added ability to set background opacity for IMC data
1 parent 0d01913 commit 40a7c71

File tree

2 files changed

+114
-84
lines changed

2 files changed

+114
-84
lines changed

src/imc.rs

+103-79
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use bevy::{
1616
sprite::Anchor,
1717
tasks::{AsyncComputeTaskPool, Task},
1818
};
19+
use egui::Color32;
1920
use futures_lite::future;
2021

2122
use nalgebra::Matrix4;
@@ -85,9 +86,9 @@ pub enum IMCEvent {
8586
output: ClassifierOutput,
8687
},
8788

88-
SetBackgroundColour {
89+
SetBackgroundOpacity {
8990
entity: Entity,
90-
colour: Colour,
91+
opacity: f32,
9192
},
9293

9394
SetHistogramScale {
@@ -117,9 +118,9 @@ fn handle_imc_event(
117118

118119
//load_imc(mcd, &mut commands, &mut textures, &thread_pool);
119120
}
120-
IMCEvent::SetBackgroundColour { entity, colour } => {
121+
IMCEvent::SetBackgroundOpacity { entity, opacity } => {
121122
if let Ok(mut imc) = q_imc.get_mut(*entity) {
122-
imc.background_colour = colour.clone();
123+
imc.background_alpha = *opacity;
123124
}
124125
}
125126
IMCEvent::SetHistogramScale { entity, scale } => {
@@ -1139,7 +1140,7 @@ fn load_imc(
11391140
.insert(IMCDataset {
11401141
mcd,
11411142
histogram_scale: HistogramScale::None,
1142-
background_colour: Colour::Bevy(Color::BLACK),
1143+
background_alpha: 1.0,
11431144
panoramas,
11441145
acquisitions: acquisition_entities.into_iter().collect(),
11451146
})
@@ -1185,7 +1186,7 @@ pub struct IMCDataset {
11851186

11861187
// Settings
11871188
histogram_scale: HistogramScale,
1188-
background_colour: Colour,
1189+
background_alpha: f32,
11891190

11901191
pub panoramas: Vec<Entity>,
11911192
pub acquisitions: HashMap<u16, Entity>,
@@ -1199,8 +1200,8 @@ impl IMCDataset {
11991200
.unwrap_or("Unknown name")
12001201
}
12011202

1202-
pub fn background_colour(&self) -> &Colour {
1203-
&self.background_colour
1203+
pub fn background_alpha(&self) -> f32 {
1204+
self.background_alpha
12041205
}
12051206
pub fn histogram_scale(&self) -> &HistogramScale {
12061207
&self.histogram_scale
@@ -1357,87 +1358,110 @@ fn generate_histogram(
13571358
}
13581359
}
13591360

1361+
// This needs rethinking. Ideally want to generate the mixture between the various
13601362
fn image_control_changed(
1361-
q_control: Query<(&ImageControl, &Children), Changed<ImageControl>>,
1363+
q_imc: Query<(&IMCDataset, &Children, ChangeTrackers<IMCDataset>)>,
1364+
q_control: Query<(&ImageControl, &Children, ChangeTrackers<ImageControl>)>,
13621365
q_acquisition: Query<&Handle<Image>, With<Acquisition>>,
13631366
q_acquisition_images: Query<&AcquisitionChannelImage>,
13641367
channel_data: Res<Assets<ChannelImage>>,
13651368
mut textures: ResMut<Assets<Image>>,
13661369
) {
1367-
for (control, children) in q_control.iter() {
1368-
// Check each AcquisitionChannelImage (child of ImageControl)
1369-
for child in children.iter() {
1370-
if let Ok(acq_channel_image) = q_acquisition_images.get(*child) {
1371-
if let Ok(image) = q_acquisition.get(acq_channel_image.acquisition_entity) {
1372-
if let Some(image) = textures.get_mut(image) {
1373-
match &acq_channel_image.data {
1374-
Some(data) => {
1375-
if let Some(channel_image) = channel_data.get(data) {
1376-
for (index, intensity) in
1377-
channel_image.intensities().iter().enumerate()
1378-
{
1379-
let intensity = ((intensity - control.colour_domain.0)
1380-
/ (control.colour_domain.1 - control.colour_domain.0)
1381-
* 255.0)
1382-
as u8;
1383-
1384-
match control.image_update_type {
1385-
ImageUpdateType::Red => {
1386-
image.data[index * 4] = intensity;
1387-
}
1388-
ImageUpdateType::Green => {
1389-
image.data[index * 4 + 1] = intensity;
1390-
}
1391-
ImageUpdateType::Blue => {
1392-
image.data[index * 4 + 2] = intensity;
1393-
}
1394-
ImageUpdateType::All => {
1395-
image.data[index * 4] = intensity;
1396-
image.data[index * 4 + 1] = intensity;
1397-
image.data[index * 4 + 2] = intensity;
1398-
}
1399-
}
1370+
for (imc, children, imc_tracker) in q_imc.iter() {
1371+
let requires_update = imc_tracker.is_changed();
14001372

1401-
// let intensity = image.data[index * 4 + 2]
1402-
// .max(image.data[index * 4 + 1])
1403-
// .max(image.data[index * 4]);
1404-
// let alpha = match intensity {
1405-
// 0..=25 => intensity * 10,
1406-
// _ => 255,
1407-
// };
1373+
for (control_index, (control, children, control_tracker)) in q_control.iter().enumerate() {
1374+
// Check each AcquisitionChannelImage (child of ImageControl)
14081375

1409-
// image.data[index * 4 + 3] = alpha;
1410-
image.data[index * 4 + 3] = 255;
1411-
}
1412-
}
1413-
}
1414-
None => {
1415-
// There is no data associated with this acquisition, so remove the previous data
1416-
for chunk in image.data.chunks_mut(4) {
1417-
match control.image_update_type {
1418-
ImageUpdateType::Red => {
1419-
chunk[0] = 0;
1420-
}
1421-
ImageUpdateType::Green => {
1422-
chunk[1] = 0;
1423-
}
1424-
ImageUpdateType::Blue => {
1425-
chunk[2] = 0;
1426-
}
1427-
ImageUpdateType::All => {
1428-
chunk[0] = 0;
1429-
chunk[1] = 0;
1430-
chunk[2] = 0;
1431-
}
1432-
}
1376+
if control_tracker.is_changed() || requires_update {
1377+
info!(
1378+
"Channel image updated => recalculating | {:?}",
1379+
imc.background_alpha()
1380+
);
14331381

1434-
let intensity = chunk[2].max(chunk[1].max(chunk[0]));
1435-
let alpha = match intensity {
1436-
0..=25 => intensity * 10,
1437-
_ => 255,
1438-
};
1382+
for child in children.iter() {
1383+
if let Ok(acq_channel_image) = q_acquisition_images.get(*child) {
1384+
if let Ok(image) = q_acquisition.get(acq_channel_image.acquisition_entity) {
1385+
if let Some(image) = textures.get_mut(image) {
1386+
match &acq_channel_image.data {
1387+
Some(data) => {
1388+
if let Some(channel_image) = channel_data.get(data) {
1389+
for (index, intensity) in
1390+
channel_image.intensities().iter().enumerate()
1391+
{
1392+
if control_index == 0 {
1393+
image.data[index * 4 + 3] =
1394+
(imc.background_alpha() * 255.0) as u8;
1395+
}
1396+
1397+
let intensity = ((intensity
1398+
- control.colour_domain.0)
1399+
/ (control.colour_domain.1
1400+
- control.colour_domain.0)
1401+
* 255.0)
1402+
as u8;
1403+
1404+
if intensity > 0 {
1405+
match control.image_update_type {
1406+
ImageUpdateType::Red => {
1407+
image.data[index * 4] = intensity;
1408+
}
1409+
ImageUpdateType::Green => {
1410+
image.data[index * 4 + 1] = intensity;
1411+
}
1412+
ImageUpdateType::Blue => {
1413+
image.data[index * 4 + 2] = intensity;
1414+
}
1415+
ImageUpdateType::All => {
1416+
image.data[index * 4] = intensity;
1417+
image.data[index * 4 + 1] = intensity;
1418+
image.data[index * 4 + 2] = intensity;
1419+
}
1420+
}
14391421

1440-
chunk[3] = alpha;
1422+
// let intensity = image.data[index * 4 + 2]
1423+
// .max(image.data[index * 4 + 1])
1424+
// .max(image.data[index * 4]);
1425+
// let alpha = match intensity {
1426+
// 0..=25 => intensity * 10,
1427+
// _ => 255,
1428+
// };
1429+
1430+
// image.data[index * 4 + 3] = alpha;
1431+
image.data[index * 4 + 3] = 255;
1432+
}
1433+
}
1434+
}
1435+
}
1436+
None => {
1437+
// // There is no data associated with this acquisition, so remove the previous data
1438+
// for chunk in image.data.chunks_mut(4) {
1439+
// match control.image_update_type {
1440+
// ImageUpdateType::Red => {
1441+
// chunk[0] = 0;
1442+
// }
1443+
// ImageUpdateType::Green => {
1444+
// chunk[1] = 0;
1445+
// }
1446+
// ImageUpdateType::Blue => {
1447+
// chunk[2] = 0;
1448+
// }
1449+
// ImageUpdateType::All => {
1450+
// chunk[0] = 0;
1451+
// chunk[1] = 0;
1452+
// chunk[2] = 0;
1453+
// }
1454+
// }
1455+
1456+
// let intensity = chunk[2].max(chunk[1].max(chunk[0]));
1457+
// let alpha = match intensity {
1458+
// 0..=25 => intensity * 10,
1459+
// _ => 255,
1460+
// };
1461+
1462+
// chunk[3] = alpha;
1463+
// }
1464+
}
14411465
}
14421466
}
14431467
}

src/ui/mod.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -524,14 +524,20 @@ fn ui_imc_panel(world: &mut World, ui: &mut Ui) {
524524
.num_columns(2)
525525
.spacing([40.0, 4.0])
526526
.show(ui, |ui| {
527-
ui.label("Background colour");
528-
let mut colour = imc.background_colour().egui();
527+
ui.label("Background opacity");
528+
let mut alpha = imc.background_alpha();
529529

530-
if ui.color_edit_button_srgba(&mut colour).changed() {
530+
let opacity = ui.add(
531+
Slider::new(&mut alpha, 0.0..=1.0)
532+
.step_by(0.01)
533+
.clamp_to_range(true)
534+
.orientation(egui::SliderOrientation::Horizontal),
535+
);
536+
if opacity.changed() {
531537
ui_events.push(UiEvent::Data(DataEvent::IMCEvent(
532-
IMCEvent::SetBackgroundColour {
538+
IMCEvent::SetBackgroundOpacity {
533539
entity,
534-
colour: colour.into(),
540+
opacity: alpha,
535541
},
536542
)));
537543
}

0 commit comments

Comments
 (0)