This commit is contained in:
Tsuki 2024-09-10 20:47:53 +08:00
parent 0836c004eb
commit 6d6836a83f
16 changed files with 401 additions and 102 deletions

View File

@ -1,9 +1,11 @@
use glow::HasContext;
use log::*;
use radarg_core::{CoordType, ProbeDataType, RadarGridData};
use crate::{
components::{Program, Shader},
errors::*,
match_array_type,
pg::Attach,
shaders::geoquadmesh::{GeoQuadMeshFragment, GeoQuadMeshVertex},
};
@ -33,7 +35,7 @@ impl GeoQuadMesh {
let lat_dpi = config.lat_dpi;
let alt_dpi = config.alt_dpi;
let location = self.program.get_uniform_location(gl, "data_info");
let data_info = self.program.get_uniform_location(gl, "data_info");
self.cmap
.set_range(config.color_range[0], config.color_range[1]);
@ -44,10 +46,16 @@ impl GeoQuadMesh {
let location_r = self.program.get_uniform_location(gl, "R");
let location_layer = self.program.get_uniform_location(gl, "layer");
let tex_conf = self.program.get_uniform_location(gl, "tex_conf");
let data_shape = self.program.get_uniform_location(gl, "data_shape");
let dpi = self.program.get_uniform_location(gl, "dpi");
unsafe {
let offset = config.offset;
let scale = config.scale;
let min = config.min;
let max = config.max;
gl.uniform_1_f32(location_r.as_ref(), 6378137.0);
gl.uniform_4_f32(location.as_ref(), lon_dpi, lat_dpi, alt_dpi, 0.0);
gl.uniform_4_f32(data_info.as_ref(), offset, scale, min, max);
gl.uniform_1_f32(location_layer.as_ref(), config.layer as f32);
let lon_s = config.lon_range[0];
@ -55,6 +63,11 @@ impl GeoQuadMesh {
let lat_s = config.lat_range[0];
let lat_e = config.lat_range[1];
gl.uniform_4_f32(tex_conf.as_ref(), lon_s, lon_e, lat_s, lat_e);
// gl.uniform_3_f32(tex_shape.as_ref(), config.alt_range[1], config.lat_range[1], config.lon_range[1]);
gl.uniform_3_f32_slice(data_shape.as_ref(), &config.data_shape);
gl.uniform_3_f32(dpi.as_ref(), config.alt_dpi, config.lat_dpi, config.lon_dpi);
}
}
@ -70,7 +83,9 @@ impl GeoQuadMesh {
[f32; 2],
[f32; 2],
[f32; 3],
[f32; 3],
ProbeDataType,
f64,
)> {
if data.coord_type().is_none() {
return Err(Error::InvalidDataType(format!("Invalid CoordType")));
@ -91,16 +106,33 @@ impl GeoQuadMesh {
let alt_dpi = (hgt[1] - hgt[0]);
(Some([hgt_start, hgt_end]), alt_dpi)
} else {
(None, 0.0)
(None, 1.0)
};
let data_type = data.data_type();
let fill_value = data.info.fill_value;
let data_shape = data.data.shape();
let data_shape = if data_shape.len() == 3 {
[
data_shape[0] as f32,
data_shape[1] as f32,
data_shape[2] as f32,
]
} else {
[1.0, data_shape[0] as f32, data_shape[1] as f32]
};
Ok((
hgt_range,
[lat_start, lat_end],
[lon_start, lon_end],
[alt_dpi as f32, lat_dpi as f32, lon_dpi as f32],
data_shape,
data_type,
fill_value,
))
}
_ => Err(Error::InvalidDataType(format!("Invalid CoordType"))),
@ -111,15 +143,21 @@ impl GeoQuadMesh {
#[derive(Debug, Clone, Default)]
pub struct GeoQuadMeshConfig {
pub unvalid_value: f32,
pub layer: usize,
pub layer: f32,
pub max_layer: usize,
pub colors: Vec<[u8; 4]>,
pub color_range: [f32; 2],
pub lon_dpi: f32,
pub lat_dpi: f32,
pub alt_dpi: f32,
pub data_shape: [f32; 3],
pub lat_range: [f32; 2],
pub lon_range: [f32; 2],
pub alt_range: [f32; 2],
pub scale: f32,
pub offset: f32,
pub min: f32,
pub max: f32,
}
impl Graphics for GeoQuadMesh {
@ -137,7 +175,7 @@ impl Graphics for GeoQuadMesh {
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
unsafe {
gl.draw_arrays(glow::TRIANGLE_STRIP_ADJACENCY, 0, count);
gl.draw_arrays(glow::TRIANGLE_STRIP, 0, count);
}
Ok(())
}
@ -276,8 +314,13 @@ impl AttaWithBuffer for GeoQuadMesh {
(attach.textures.as_ref()).map(|t| t.native()),
);
let _data = &data.data;
let shape = _data.shape();
let max_depth_size = gl.get_parameter_i32(glow::MAX_3D_TEXTURE_SIZE);
info!("Max 3D Texture Size: {}", max_depth_size);
gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
let data = &data.data;
let shape = data.shape();
let (depth, height, width) = if shape.len() == 2 {
(1i32, shape[0] as i32, shape[1] as i32)
@ -285,19 +328,39 @@ impl AttaWithBuffer for GeoQuadMesh {
(shape[0] as i32, shape[1] as i32, shape[2] as i32)
};
let pixels: &[u8] = cast_slice(_data.as_slice().unwrap());
info!("Data Shape: {:?}", shape);
// let tex_width = width / 4 + 1;
// let tex_height = height / 4 + 1;
let fill_value = config.unvalid_value;
let min_value = config.min;
let max_value = config.max;
let v = data.scale_offset_to_pixel(fill_value, min_value, max_value);
let pixel_num = (v.len() / 4 + 1) as f32;
let edge_len = (pixel_num.powf(1.0 / 3.0) + 1.0) as usize;
let real_size = edge_len * edge_len * edge_len * 4;
let data_size = v.len();
let padding_size = real_size - data_size;
let mut pixels = vec![0u8; real_size as usize];
&pixels[..data_size].copy_from_slice(cast_slice(v.as_slice().unwrap()));
attach.texture_shape = Some([edge_len as f32; 3]);
gl.tex_image_3d(
glow::TEXTURE_3D,
0,
glow::R8 as i32,
width,
height,
depth,
glow::RGBA as i32,
edge_len as i32,
edge_len as i32,
edge_len as i32,
0,
glow::RED,
glow::RGBA,
glow::UNSIGNED_BYTE,
Some(pixels),
Some(pixels.as_slice()),
);
}

View File

@ -20,6 +20,32 @@ use crate::{
use glow::{HasContext, NativeBuffer, NativeTexture, NativeVertexArray};
#[macro_export]
macro_rules! match_array_type {
($array:ident, $just_do_it:expr) => {
use radarg_core::ArrayData;
match $array {
ArrayData::U8(v) => $just_do_it(v),
ArrayData::U32(v) => $just_do_it(v),
ArrayData::U64(v) => $just_do_it(v),
ArrayData::I8(v) => $just_do_it(v),
ArrayData::I16(v) => $just_do_it(v),
ArrayData::I32(v) => $just_do_it(v),
ArrayData::I64(v) => $just_do_it(v),
ArrayData::F32(v) => $just_do_it(v),
ArrayData::F64(v) => $just_do_it(v),
}
};
}
pub trait Graphics {
const id: &'static str;
type Config;

View File

@ -208,7 +208,7 @@ impl AttaWithBuffer for PPI {
for r_idx in 0..r_len {
let azi = *azimuth.get(azi_idx).unwrap() as f32;
let r = *range.get(r_idx).unwrap() as f32 / last_range;
let data = &data.data;
let data = &data.data.cast_to::<f32>();
let dt = data.get([layer, azi_idx, r_idx]).unwrap();
vertices.extend([r, azi, ele, *dt]);
}

View File

@ -43,6 +43,7 @@ static MODULE_PACKAGE_ID: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug)]
pub enum SideBarInputMsg {
Packages(Vec<(String, Rc<RefCell<ModulePackage>>)>),
ClearPackages,
SwitchTo(gtk::glib::GString),
Refresh,
None,
@ -143,7 +144,7 @@ macro_rules! impl_module_package {
}
}
#[derive(Debug)]
// #[derive(Debug)]
pub enum _ModulePackage {
$(
$b($t),
@ -183,13 +184,19 @@ macro_rules! impl_module_package {
}
}
#[derive(Debug)]
// #[derive(Debug)]
pub struct ModulePackage {
id: usize,
pub need_update: bool,
modules: _ModulePackage,
}
impl std::fmt::Debug for ModulePackage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ModulePackage {{ id: {}, need_update: {} }}", self.id, self.need_update)
}
}
impl ModulePackage {
pub fn component_builder(&self) -> ComponentBuilders {

View File

@ -16,11 +16,13 @@ use relm4::{
gtk::{self, prelude::*},
ComponentParts, SimpleComponent,
};
use toml::value;
use core::f32;
use glow::HasContext;
use std::{
cell::{RefCell, RefMut},
f32::consts::E,
rc::Rc,
sync::Arc,
};
@ -120,7 +122,7 @@ impl<'b, 'a: 'b> GeoQuadMeshModule<'b, 'a> {
config: &GeoQuadMeshModuleConfig,
) -> Result<()> {
self.geo_quad_mesh_program
.bake(&self.gl, data, &config.to_quad_config(), attach)
.bake(&self.gl, data, &mut config.to_quad_config(), attach)
}
fn bind_line_pg(
@ -140,6 +142,29 @@ impl<'b, 'a: 'b> GeoQuadMeshModule<'b, 'a> {
) -> Result<()> {
Ok(())
}
fn bind_attach_tex(&mut self, attach: &mut Attach) -> Result<()> {
if let Some(tex) = attach.textures.as_ref() {
unsafe {
self.gl.active_texture(glow::TEXTURE1);
self.gl.bind_texture(glow::TEXTURE_3D, Some(tex.native()));
let loc = self
.geo_quad_mesh_program
.program()
.get_uniform_location(&self.gl, "data_tex");
self.gl.uniform_1_i32(loc.as_ref(), 1);
let tex_shape = self
.geo_quad_mesh_program
.program()
.get_uniform_location(&self.gl, "tex_shape");
self.gl
.uniform_3_f32_slice(tex_shape.as_ref(), &attach.texture_shape.unwrap());
}
}
Ok(())
}
}
impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
@ -155,12 +180,6 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
operation: &Operation<Self::Operation>,
viewport: &ViewPort,
) -> Result<()> {
unsafe {
let err = self.gl.get_error();
if err != glow::NO_ERROR {
panic!("Error: {}", err);
}
}
// PPI Program
let data = &cursor.data;
let mut config = &mut cursor.ppi_config.borrow_mut();
@ -169,25 +188,17 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
// Deal with the operation
operation.attach_with_program(&self.gl, self.geo_quad_mesh_program.program());
let quad_attach = &mut cursor.quad_attach;
unsafe {
let err = self.gl.get_error();
if err != glow::NO_ERROR {
panic!("Error: {}", err);
}
}
// Update the config
self.geo_quad_mesh_program
.set_config(&self.gl, &config.to_quad_config())?;
unsafe {
let err = self.gl.get_error();
if err != glow::NO_ERROR {
panic!("Error: {}", err);
}
}
// Quad Draw
quad_attach.bind_self(self.geo_quad_mesh_program.program_ref());
// Bind the texture
self.bind_attach_tex(quad_attach)?;
// Draw the quad
self.geo_quad_mesh_program
.draw(&self.gl, quad_attach.len())?;
@ -207,11 +218,9 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
let mut quad_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
// Get the data info
let (hgt_range, lat_range, lon_range, dpi, t) =
let (hgt_range, lat_range, lon_range, dpi, data_shape, t, fill_value) =
self.geo_quad_mesh_program.data_info(&data)?;
println!("name: {}", data.info.value_name);
// Find the color map
let cmap = setting.find(&t);
@ -232,6 +241,10 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
let (vao, vbo, ebo, texs) = self.text_program.init(&self.gl);
let mut tick_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
let value_range = cmap.value_range();
let offset = -fill_value;
let scale = value_range[1] / value_range[0];
let mut config = GeoQuadMeshModuleConfig::default();
config.alt_dpi = dpi[0];
config.lat_dpi = dpi[1];
@ -242,9 +255,16 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
config.hgt_range = hgt_range.unwrap_or_default();
config.colors = cmap.color().unwrap();
config.color_range = cmap.value_range();
config.unvalid_value = fill_value as f32;
config.scale = scale;
config.offset = offset as f32;
config.min = value_range[0] as f32;
config.max = value_range[1] as f32;
config.data_shape = data_shape;
config.max_layer = data_shape[0] as usize;
// Bind the data
self.bind_geo_quad_mesh_pg(&mut quad_attach, data, &config);
self.bind_geo_quad_mesh_pg(&mut quad_attach, data, &config)?;
// self.bind_line_pg(&mut line_attach, &data, &config);
// self.bind_tick(&mut tick_attach, &data.borrow(), &config);
@ -272,7 +292,7 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
}
}
#[derive(Debug)]
// #[derive(Debug)]
pub struct GeoQuadMeshPackage {
draw_helper: bool,
ppi_config: Rc<RefCell<GeoQuadMeshModuleConfig>>,
@ -308,7 +328,7 @@ pub struct GeoQuadMeshModuleConfig {
pub line_color: [f32; 4],
pub line_width: f32,
pub line_antialias: f32,
pub layer: usize,
pub layer: f32,
pub colors: Vec<[u8; 4]>,
pub color_range: [f32; 2],
pub is_three_d: bool,
@ -334,6 +354,16 @@ pub struct GeoQuadMeshModuleConfig {
pub alt_dpi: f32,
#[do_not_track]
pub lon_dpi: f32,
#[do_not_track]
pub scale: f32,
#[do_not_track]
pub offset: f32,
#[do_not_track]
pub min: f32,
#[do_not_track]
pub max: f32,
#[do_not_track]
pub data_shape: [f32; 3],
}
impl Default for GeoQuadMeshModuleConfig {
@ -343,7 +373,7 @@ impl Default for GeoQuadMeshModuleConfig {
line_color: [1.0, 1.0, 1.0, 1.0],
line_width: 1.5,
line_antialias: 0.5,
layer: 0,
layer: 0.0,
colors: vec![],
color_range: [0.0, 0.0],
is_three_d: true,
@ -358,6 +388,11 @@ impl Default for GeoQuadMeshModuleConfig {
lat_range: [0.0, 0.0],
lon_range: [0.0, 0.0],
hgt_range: [0.0, 0.0],
scale: 1.0,
offset: 0.0,
min: 0.0,
max: 0.0,
data_shape: [0.0, 0.0, 0.0],
}
}
}
@ -375,6 +410,12 @@ impl GeoQuadMeshModuleConfig {
lat_range: self.lat_range,
lon_range: self.lon_range,
alt_range: self.hgt_range,
scale: self.scale,
offset: self.offset,
min: self.min,
max: self.max,
data_shape: self.data_shape,
max_layer: self.max_layer,
}
}
@ -426,6 +467,27 @@ impl SimpleComponent for GeoQuadMeshModuleConfigComponent {
}
},
adw::SpinRow {
set_title: "Layer",
set_digits: 0,
set_numeric: true,
set_snap_to_ticks: true,
#[wrap(Some)]
set_adjustment=&gtk::Adjustment::new(
init_config.layer as f64,
init_config.hgt_range[0] as f64,
init_config.hgt_range[1] as f64,
init_config.alt_dpi as f64,
1.0,
1.0,
),
connect_value_notify[sender, config_ref] => move |this| {
let num = this.value() as f32;
config_ref.borrow_mut().set_layer(num);
sender.output(OutputMsg::Refresh);
},
}
}
}

View File

@ -35,6 +35,7 @@ pub(crate) struct Attach {
pub vbo: RcGlRcBuffer,
pub ebo: Option<RcGlRcBuffer>,
pub textures: Option<RcGlRcResource<NativeTexture>>,
pub texture_shape: Option<[f32; 3]>,
pub len: i32,
}
@ -58,6 +59,7 @@ impl Attach {
vbo,
ebo,
textures,
texture_shape: None,
len: len.unwrap_or(0),
}
}
@ -68,15 +70,6 @@ impl Attach {
if let Some(ebo) = self.ebo.as_ref() {
ebo.bind(glow::ELEMENT_ARRAY_BUFFER);
}
if let Some(tex) = self.textures.as_ref() {
unsafe {
self.gl.active_texture(glow::TEXTURE0);
self.gl.bind_texture(glow::TEXTURE_3D, Some(tex.native()));
let loc = program.get_uniform_location(&self.gl, "_texture");
self.gl.uniform_1_i32(loc.as_ref(), 0);
}
}
}
fn unbind_self(&self) {

View File

@ -434,7 +434,7 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
}
}
#[derive(Debug)]
// #[derive(Debug)]
pub struct PPIPackage {
draw_helper: bool,
ppi_config: Rc<RefCell<PPIModuleConfig>>,

View File

@ -39,7 +39,7 @@ impl ColorMap {
float v = clamp((value - vmin), vmin, vmax) / (vmax - vmin);
float idx = find_idx(v);
vec4 result = texture(colormap, idx);
return result;
return vec4(result.rgb, 1.0);
}
};

View File

@ -9,7 +9,7 @@ use glsl_quasiquote::glsl;
use super::proj::Mercator;
pub struct GeoQuadMeshVertex(pub ShaderStage);
pub struct GeoQuadMeshGeom(pub ShaderStage);
// pub struct GeoQuadMeshGeom(pub ShaderStage);
pub struct GeoQuadMeshFragment(pub ShaderStage);
impl GeoQuadMeshVertex {
@ -46,9 +46,15 @@ impl GeoQuadMeshFragment {
let raw = glsl! {
// lon_s,lon_e, lat_s, lat_e
uniform vec4 tex_conf;
// lon_reso, lat_reso, alt_reso
// hgt, lat, lon
uniform vec3 tex_shape;
// offset, scale, min, max
uniform vec4 data_info;
// data shape
uniform vec3 data_shape;
// hgt, lat, lon
uniform vec3 dpi;
// Current layer
uniform float layer;
@ -57,25 +63,63 @@ impl GeoQuadMeshFragment {
in vec2 projected_meter;
// data array
uniform sampler3D _texture;
uniform sampler3D data_tex;
void main() {
vec2 lon_lat = mercatorInverse(projected_meter);
vec3 tex_coord = vec3(lon_lat.x / tex_conf.z, lon_lat.y / tex_conf.w, layer / tex_conf.x);
float x = round((lon_lat.x - tex_conf.x) / dpi.z);
float y = round((lon_lat.y - tex_conf.z) / dpi.y);
float z = floor(layer / dpi.x);
float value = texture(_texture, tex_coord).r;
uint raw_loc = uint(z * (data_shape.y * data_shape.z) + y * data_shape.z + x);
uint loc = raw_loc / 4u;
uint channel = raw_loc % 4u;
uint tex_depth = uint(tex_shape.x);
uint tex_height = uint(tex_shape.y);
uint tex_width = uint(tex_shape.z);
float tz = float(loc / (tex_width * tex_height));
float ty = float((loc % (tex_height * tex_width) / tex_width));
float tx = float(loc % tex_width);
vec3 tex_coord = vec3(tx / tex_shape.z, ty / tex_shape.y, tz / tex_shape.x);
vec4 _value = texture(data_tex, tex_coord);
float value = 0.0;
switch (channel) {
case 0:
value = _value.r;
break;
case 1:
value = _value.g;
break;
case 2:
value = _value.b;
break;
case 3:
value = _value.a;
break;
}
float min = data_info.z;
float max = data_info.w;
if (abs(value - 0.0) < 0.0001) {
discard;
}
// Real value
value = value * 255.0 / 254.0 * (max - min);
vec4 color = linear_colormap(value);
fragColor = vec4(1.0,1.0,1.0,1.0);
// if (color.a < 0.1) {
// discard;
// } else {
// fragColor = color;
// }
fragColor = color;
}
};

View File

@ -106,7 +106,7 @@ impl DataLoaderPlugin for ETWSLoader {
let data_type = data_type!(
value_key,
{ "ET" => ET },
{ "DBZ" | "CR" | "FR" | "R" => DBZ},
{ "DBZ" | "CR" | "FR" | "R" | "CR0" | "CR1" | "CR2" => DBZ},
{ "VIL" => VIL},
{ "EB" => EB},
{ "V" => V},
@ -165,7 +165,7 @@ impl DataLoaderPlugin for ETWSLoader {
let data_type = data_type!(
k,
{ "ET" => ET },
{ "DBZ" | "CR" | "FR" | "R" => DBZ},
{ "DBZ" | "CR" | "FR" | "R" | "CR0" | "CR1" | "CR2" => DBZ},
{ "VIL" => VIL},
{ "EB" => EB},
{ "V" | "VEL" => V},

View File

@ -71,6 +71,7 @@ pub enum AppMsg {
CloseRequest,
Close,
OpenFileDialog,
Packages { clear: bool },
}
#[tracker::track]
pub struct AppModel {
@ -221,6 +222,13 @@ impl Component for AppModel {
.forward(sender.input_sender(), |msg| match msg {
SideBarOutputMsg::Dialog(widget) => AppMsg::OpenDialog { widget },
SideBarOutputMsg::QueueDraw => AppMsg::Refresh,
SideBarOutputMsg::Packages { clear } => {
if clear {
AppMsg::Packages { clear: true }
} else {
AppMsg::Refresh
}
}
_ => AppMsg::Close,
});
@ -404,7 +412,8 @@ impl Component for AppModel {
let mut datapool = self.file_pool.borrow_mut();
match datapool.get_or_load(path) {
Ok(data) => {
info!("data: {}", data);
info!("data: {:?}", data);
_sender.input(AppMsg::Packages { clear: true });
_sender.input(AppMsg::FileIO {
typ: FileIOType::Open(data),
});
@ -423,6 +432,10 @@ impl Component for AppModel {
} => self.render.emit(MonitorInputMsg::PushData(data)),
AppMsg::Refresh => self.render.emit(MonitorInputMsg::QueueDraw),
AppMsg::Packages { clear } => {
self.render.emit(MonitorInputMsg::Packages { clear: true });
}
_ => {}
}
self.update_view(widgets, _sender);

View File

@ -10,6 +10,7 @@ pub enum MonitorInputMsg {
Prepare(Vec<Arc<Data>>),
KeyPress(u32),
KeyRelease(u32),
Packages { clear: bool },
QueueDraw,
None,
}
@ -27,6 +28,10 @@ impl Debug for MonitorInputMsg {
MonitorInputMsg::KeyPress(key) => write!(f, "MonitorInputMsg::Key({:?})", key),
MonitorInputMsg::KeyRelease(key) => write!(f, "MonitorInputMsg::KeyRelease({:?})", key),
MonitorInputMsg::PushData(data) => write!(f, "MonitorInputMsg::PushData({:?})", data),
&MonitorInputMsg::Packages { clear } => {
write!(f, "MonitorInputMsg::Packages {{ clear: {} }}", clear)
}
MonitorInputMsg::None => write!(f, "MonitorInputMsg::None"),
}
}

View File

@ -236,6 +236,12 @@ impl Component for MonitorModel {
MonitorInputMsg::KeyRelease(key) => {
widgets.renderer.set_key_released(key);
}
MonitorInputMsg::Packages { clear } => {
if clear {
self.update_module_packages(|p| p.clear());
}
}
MonitorInputMsg::None => {}
_ => {}
}

View File

@ -38,6 +38,7 @@ pub struct SideBarModel {
#[derive(Debug)]
pub enum SideBarOutputMsg {
Dialog(Widget),
Packages { clear: bool },
QueueDraw,
}
@ -76,6 +77,13 @@ impl Component for SideBarModel {
set_transition_type:gtk::StackTransitionType::SlideLeftRight,
set_transition_duration:200,
set_hexpand:true,
},
gtk::Button {
set_label:"Clear",
connect_clicked[sender] => move |_| {
sender.input(SideBarInputMsg::ClearPackages);
}
}
}
},
@ -133,6 +141,14 @@ impl Component for SideBarModel {
sender.output(SideBarOutputMsg::QueueDraw).unwrap();
}
SideBarInputMsg::ClearPackages => {
widgets.stack.remove_all();
self.components.clear();
widgets.dropdown.set_selected(gtk::INVALID_LIST_POSITION);
widgets.dropdown.set_model(None::<&gtk::StringList>);
sender.output(SideBarOutputMsg::Packages { clear: true });
}
_ => {}
}
}

View File

@ -44,15 +44,15 @@ impl<T: Display> Deref for Value<T> {
}
}
impl Display for Value<Data> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for data in self.0.iter() {
writeln!(f, "{:?}", data)?;
}
// impl Display for Value<Data> {
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// for data in self.0.iter() {
// writeln!(f, "{:?}", data)?;
// }
Ok(())
}
}
// Ok(())
// }
// }
pub struct DataPool {
plugin_manager: &'static PluginManager,

View File

@ -1,3 +1,4 @@
use num_traits::FromPrimitive;
use std::{
fmt::Display,
hash::Hash,
@ -14,13 +15,23 @@ use radarg_plugin_interface::{
static DATA_ID: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug, Clone)]
#[derive(Clone)]
pub struct Data {
pub id: usize,
pub description: String,
_data: _Data,
}
impl std::fmt::Debug for Data {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Data {{ id: {}, description: {}",
self.id, self.description
)
}
}
impl PartialEq for Data {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
@ -41,7 +52,7 @@ impl Display for Data {
}
}
#[derive(Debug, Clone)]
#[derive(Clone)]
pub enum _Data {
RadarGridData(Arc<RadarGridData>),
JsonData,
@ -60,14 +71,14 @@ impl Display for _Data {
}
}
#[derive(Debug, Clone)]
#[derive(Clone)]
pub struct RadarGridData {
pub data: ArrayD<f32>,
pub data: ArrayData,
pub info: GridDataInfo,
}
impl RadarGridData {
pub fn get_data(&self) -> &ArrayD<f32> {
pub fn get_data(&self) -> &ArrayData {
&self.data
}
@ -195,7 +206,67 @@ pub enum ProbeDataType {
}
macro_rules! raw2new {
($({$raw_bc:tt}),+, ($({$raw_rdt:tt}),+)) => {
($({$raw_bc:tt | $typ:ty | $from:ident}),+, ($({$raw_rdt:tt}),+)) => {
#[derive(Debug, Clone)]
pub enum ArrayData {
$(
$raw_bc(ArrayD<$typ>),
)+
}
impl ArrayData {
pub fn shape(&self) -> &[usize] {
match self {
$(
ArrayData::$raw_bc(v) => v.shape(),
)+
}
}
pub fn cast_to<T: FromPrimitive>(&self) -> ArrayD<T> {
match self {
$(
ArrayData::$raw_bc(v) => v.map(|v| T::$from(*v).unwrap()),
)+
}
}
pub fn scale_offset(&self, scale: f64, offset: f64) -> ArrayD<f32>{
match self {
$(
ArrayData::$raw_bc(v) => v.mapv(|v| v as f32 * scale as f32 + offset as f32),
)+
}
}
pub fn scale_offset_to_pixel(&self, fill_value:f32, min:f32, max:f32) -> ArrayD<u8>{
match self {
$(
ArrayData::$raw_bc(v) => v.mapv(|v| {
if (v as f32 - fill_value).abs() < 1e-6 {
0
} else {
let v = (v as f32 - min) / (max - min) * 254.0;
v as u8 + 1
}
}),
)+
}
}
$(
pub fn $raw_bc(&self) -> &ArrayD<$typ> {
match self {
ArrayData::$raw_bc(v) => v,
_ => panic!("Unsupported data type"),
}
}
)+
}
impl From<RawRadarGridData> for RadarGridData {
fn from(raw: RawRadarGridData) -> Self {
let RawRadarGridData { data, info } = raw;
@ -205,8 +276,7 @@ macro_rules! raw2new {
let data = match data {
$(
$raw_bc(v) => {
let data = v.into_iter().map(|x| x as f32).collect();
ArrayD::from_shape_vec(shape.clone(), data).unwrap()
ArrayData::$raw_bc(ArrayD::from_shape_vec(shape.clone(), v.to_vec()).unwrap())
}
)+
_ => panic!("Unsupported data type"),
@ -243,16 +313,15 @@ macro_rules! raw2new {
}
raw2new!(
{ F32 },
{ F64 },
{ I32 },
{ I16 },
{ F32 },
{ U64 },
{ U32 },
{ I8 },
{ U8 },
{ I64 },
{ F32 | f32 | from_f32 },
{ F64 | f64 | from_f64 },
{ I32 | i32 | from_i32 },
{ I16 | i16 | from_i16 },
{ U64 | u64 | from_u64 },
{ U32 | u32 | from_u32 },
{ I8 | i8 | from_i8 },
{ U8 | u8 | from_u8 },
{ I64 | i64 | from_i64 },
(
{ R },
{ V },
@ -347,10 +416,5 @@ mod test {
use super::Data;
fn test() {
let radar_data = RadarGridData {
data: ndarray::ArrayD::from_shape_vec(ndarray::IxDyn(&[1, 1]), vec![1.0]).unwrap(),
info: super::GridDataInfo::default(),
};
}
fn test() {}
}