some optimisations
This commit is contained in:
parent
7234064f12
commit
5450144797
3 changed files with 95 additions and 66 deletions
|
@ -7,20 +7,29 @@ pub fn mat_editor<const R: usize, const C: usize>(
|
||||||
id: &str,
|
id: &str,
|
||||||
skip_last: bool,
|
skip_last: bool,
|
||||||
) -> egui::Response {
|
) -> egui::Response {
|
||||||
egui::Grid::new(id)
|
let mut any_change = false;
|
||||||
|
let mut r = egui::Grid::new(id)
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
mat.row_iter_mut().enumerate().for_each(|(i, mut row)| {
|
mat.row_iter_mut().enumerate().for_each(|(i, mut row)| {
|
||||||
if !skip_last || i + 1 < R {
|
if !skip_last || i + 1 < R {
|
||||||
row.iter_mut().for_each(|item| {
|
row.iter_mut().for_each(|item| {
|
||||||
ui.add(
|
any_change |= ui
|
||||||
|
.add(
|
||||||
egui::DragValue::new(item)
|
egui::DragValue::new(item)
|
||||||
.speed(0.01)
|
.speed(0.01)
|
||||||
.clamp_range(-10.0..=10.0),
|
.clamp_range(-10.0..=10.0),
|
||||||
);
|
)
|
||||||
|
.changed();
|
||||||
});
|
});
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.response
|
.response;
|
||||||
|
|
||||||
|
if any_change {
|
||||||
|
r.mark_changed()
|
||||||
|
}
|
||||||
|
|
||||||
|
r
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{
|
||||||
|
|
||||||
use eframe::egui::{self, TextureOptions};
|
use eframe::egui::{self, TextureOptions};
|
||||||
use image::{DynamicImage, Pixel, Rgb, Rgb32FImage};
|
use image::{DynamicImage, Pixel, Rgb, Rgb32FImage};
|
||||||
use nalgebra::{SMatrix, Vector3, Vector4};
|
use nalgebra::{ComplexField, Const, Matrix, OMatrix, SMatrix, Vector3, Vector4};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
use image::EncodableLayout;
|
use image::EncodableLayout;
|
||||||
|
@ -16,6 +16,7 @@ struct ProcessorInstruction {
|
||||||
ret: oneshot::Sender<(egui::TextureHandle, (f32, f32))>,
|
ret: oneshot::Sender<(egui::TextureHandle, (f32, f32))>,
|
||||||
ctx: egui::Context,
|
ctx: egui::Context,
|
||||||
handle: Option<egui::TextureHandle>,
|
handle: Option<egui::TextureHandle>,
|
||||||
|
realloc: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Processor {
|
pub struct Processor {
|
||||||
|
@ -26,6 +27,7 @@ impl Processor {
|
||||||
pub fn init() -> Self {
|
pub fn init() -> Self {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
thread::spawn(|| {
|
thread::spawn(|| {
|
||||||
|
let mut working_img = DynamicImage::new_rgb32f(1, 1);
|
||||||
for ProcessorInstruction {
|
for ProcessorInstruction {
|
||||||
img,
|
img,
|
||||||
color_matrix,
|
color_matrix,
|
||||||
|
@ -33,51 +35,81 @@ impl Processor {
|
||||||
ret,
|
ret,
|
||||||
ctx,
|
ctx,
|
||||||
handle,
|
handle,
|
||||||
|
realloc,
|
||||||
} in rx
|
} in rx
|
||||||
{
|
{
|
||||||
let (width, height) = img.dimensions();
|
let (width, height) = img.dimensions();
|
||||||
|
|
||||||
// let mut r = (*img).clone();
|
if realloc {
|
||||||
let mut r = Rgb32FImage::new(width, height);
|
working_img = DynamicImage::new_rgb32f(width, height);
|
||||||
if !pos_matrix.is_identity(f32::EPSILON) && pos_matrix.is_invertible() {
|
}
|
||||||
let mut inv_mat = pos_matrix.try_inverse().unwrap();
|
|
||||||
let mut cols_mut = inv_mat.column_part_mut(2, 2);
|
let do_pos_trans =
|
||||||
|
!pos_matrix.is_identity(f32::EPSILON) && pos_matrix.is_invertible();
|
||||||
|
let do_color_trans = !color_matrix.is_identity(f32::EPSILON);
|
||||||
|
|
||||||
|
let mut inv_pos_mat = OMatrix::<f32, Const<3>, Const<3>>::identity();
|
||||||
|
if do_pos_trans {
|
||||||
|
inv_pos_mat = pos_matrix.try_inverse().unwrap();
|
||||||
|
let mut cols_mut = inv_pos_mat.column_part_mut(2, 2);
|
||||||
*(cols_mut.get_mut(0).unwrap()) *= width as f32;
|
*(cols_mut.get_mut(0).unwrap()) *= width as f32;
|
||||||
*(cols_mut.get_mut(1).unwrap()) *= height as f32;
|
*(cols_mut.get_mut(1).unwrap()) *= height as f32;
|
||||||
|
}
|
||||||
|
|
||||||
r.par_enumerate_pixels_mut().for_each(|(x, y, px)| {
|
{
|
||||||
let r = inv_mat * Vector3::new(x as f32, y as f32, 1.0);
|
let working_img = working_img.as_mut_rgb32f().unwrap();
|
||||||
*px = if r.x.is_sign_positive() && r.y.is_sign_positive() {
|
match (do_pos_trans, do_color_trans) {
|
||||||
*img.get_pixel_checked(r.x as u32, r.y as u32)
|
(true, true) => {
|
||||||
|
working_img
|
||||||
|
.par_enumerate_pixels_mut()
|
||||||
|
.for_each(|(x, y, px)| {
|
||||||
|
let org_pos =
|
||||||
|
inv_pos_mat * Vector3::new(x as f32, y as f32, 1.0);
|
||||||
|
|
||||||
|
let Rgb([r, g, b]) = *img
|
||||||
|
.get_pixel_checked(
|
||||||
|
org_pos.x.abs() as u32 % width,
|
||||||
|
org_pos.y.abs() as u32 % height,
|
||||||
|
)
|
||||||
|
.unwrap_or(&Rgb([0., 0., 0.]));
|
||||||
|
*px = Rgb::from(Into::<[f32; 3]>::into(
|
||||||
|
color_matrix * Vector4::new(r, g, b, 1.0),
|
||||||
|
));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
(true, false) => {
|
||||||
|
working_img
|
||||||
|
.par_enumerate_pixels_mut()
|
||||||
|
.for_each(|(x, y, px)| {
|
||||||
|
let r = inv_pos_mat * Vector3::new(x as f32, y as f32, 1.0);
|
||||||
|
*px = *img
|
||||||
|
.get_pixel_checked(
|
||||||
|
r.x.abs() as u32 % width,
|
||||||
|
r.y.abs() as u32 % height,
|
||||||
|
)
|
||||||
.unwrap_or(&Rgb([0., 0., 0.]))
|
.unwrap_or(&Rgb([0., 0., 0.]))
|
||||||
} else {
|
|
||||||
Rgb([0., 0., 0.])
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
r = (*img).clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
if !color_matrix.is_identity(f32::EPSILON) {
|
|
||||||
r.par_pixels_mut().for_each(|px| {
|
|
||||||
*px = Rgb::from(
|
|
||||||
TryInto::<[f32; 3]>::try_into(
|
|
||||||
(color_matrix * Vector4::new(px.0[0], px.0[1], px.0[2], 1.))
|
|
||||||
.as_slice(),
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
(false, true) => {
|
||||||
|
working_img
|
||||||
|
.par_enumerate_pixels_mut()
|
||||||
|
.for_each(|(x, y, px)| {
|
||||||
|
let Rgb([r, g, b]) = *img.get_pixel(x, y);
|
||||||
|
*px = Rgb::from(Into::<[f32; 3]>::into(
|
||||||
|
color_matrix * Vector4::new(r, g, b, 1.0),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
(false, false) => {
|
||||||
|
*working_img = (*img).clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let color_image = {
|
let color_image = egui::ColorImage::from_rgb(
|
||||||
let image = DynamicImage::from(r).to_rgb8();
|
[working_img.width() as usize, working_img.height() as usize],
|
||||||
|
working_img.to_rgb8().as_bytes(),
|
||||||
egui::ColorImage::from_rgb(
|
);
|
||||||
[image.width() as usize, image.height() as usize],
|
|
||||||
image.as_bytes(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let handle = if let Some(mut handle) = handle {
|
let handle = if let Some(mut handle) = handle {
|
||||||
handle.set(color_image, TextureOptions::default());
|
handle.set(color_image, TextureOptions::default());
|
||||||
handle
|
handle
|
||||||
|
@ -99,6 +131,7 @@ impl Processor {
|
||||||
pos_matrix: SMatrix<f32, 3, 3>,
|
pos_matrix: SMatrix<f32, 3, 3>,
|
||||||
ctx: egui::Context,
|
ctx: egui::Context,
|
||||||
handle: Option<egui::TextureHandle>,
|
handle: Option<egui::TextureHandle>,
|
||||||
|
realloc: bool,
|
||||||
) -> oneshot::Receiver<(egui::TextureHandle, (f32, f32))> {
|
) -> oneshot::Receiver<(egui::TextureHandle, (f32, f32))> {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
|
|
||||||
|
@ -109,6 +142,7 @@ impl Processor {
|
||||||
ret: tx,
|
ret: tx,
|
||||||
ctx,
|
ctx,
|
||||||
handle,
|
handle,
|
||||||
|
realloc,
|
||||||
});
|
});
|
||||||
dbg!(r).unwrap();
|
dbg!(r).unwrap();
|
||||||
|
|
||||||
|
|
32
src/lib.rs
32
src/lib.rs
|
@ -64,36 +64,33 @@ impl eframe::App for App {
|
||||||
self.pos_matrix,
|
self.pos_matrix,
|
||||||
ctx.clone(),
|
ctx.clone(),
|
||||||
self.cur_res.clone(),
|
self.cur_res.clone(),
|
||||||
|
true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.add_space(8.);
|
ui.add_space(8.);
|
||||||
let old_color_mat = self.color_matrix;
|
|
||||||
let old_pos_mat = self.pos_matrix;
|
|
||||||
ui.label("Color Matrix Editor");
|
ui.label("Color Matrix Editor");
|
||||||
let color_mat_edited =
|
let color_mat_edited =
|
||||||
components::mat_editor(ui, &mut self.color_matrix, "color_matrix", false).dragged();
|
components::mat_editor(ui, &mut self.color_matrix, "color_matrix", false).changed();
|
||||||
ui.add_space(8.);
|
ui.add_space(8.);
|
||||||
ui.label("Position Matrix Editor");
|
ui.label("Position Matrix Editor");
|
||||||
let pos_mat_edited =
|
let pos_mat_edited =
|
||||||
components::mat_editor(ui, &mut self.pos_matrix, "pos_matrix", true).dragged();
|
components::mat_editor(ui, &mut self.pos_matrix, "pos_matrix", true).changed();
|
||||||
mats_changed |= old_color_mat == self.color_matrix || old_pos_mat == self.pos_matrix;
|
|
||||||
|
|
||||||
if mats_changed
|
if dbg!(self.cur_img.is_some())
|
||||||
&& self.cur_img.is_some()
|
&& dbg!((color_mat_edited || pos_mat_edited))
|
||||||
&& self.cur_res.is_some()
|
&& dbg!(self.cur_res.is_some())
|
||||||
&& !color_mat_edited
|
&& dbg!(self.cur_rx.is_none())
|
||||||
&& !pos_mat_edited
|
|
||||||
&& self.cur_rx.is_none()
|
|
||||||
{
|
{
|
||||||
self.cur_rx = Some(self.proc.exec(
|
self.cur_rx = Some(self.proc.exec(
|
||||||
self.cur_img.clone().unwrap(),
|
self.cur_img.clone().unwrap(),
|
||||||
self.color_matrix,
|
dbg!(self.color_matrix),
|
||||||
self.pos_matrix,
|
self.pos_matrix,
|
||||||
ctx.clone(),
|
ctx.clone(),
|
||||||
self.cur_res.clone(),
|
self.cur_res.clone(),
|
||||||
|
false,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -119,17 +116,6 @@ impl eframe::App for App {
|
||||||
let img = egui::Image::from_texture(sized_img);
|
let img = egui::Image::from_texture(sized_img);
|
||||||
ui.add(img);
|
ui.add(img);
|
||||||
}
|
}
|
||||||
// if let Some(dimensions) = self.cur_img_size {
|
|
||||||
// egui::Frame::canvas(ui.style()).show(ui, |ui| {
|
|
||||||
// let (rect, response) = ui.allocate_exact_size(dimensions, egui::Sense::drag());
|
|
||||||
|
|
||||||
// let callback = egui_wgpu::Callback::new_paint_callback(
|
|
||||||
// rect,
|
|
||||||
// CustomTriangleCallback { angle: 0.5 },
|
|
||||||
// );
|
|
||||||
// ui.painter().add(callback);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue