Skip to content

Commit

Permalink
import coco file and directly open the folder
Browse files Browse the repository at this point in the history
  • Loading branch information
bertiqwerty committed Jan 30, 2025
1 parent d408d44 commit f230333
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 20 deletions.
51 changes: 47 additions & 4 deletions rvimage/src/rvlib/control/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::cfg::{get_log_folder, Connection};
use crate::defer_file_removal;
use crate::cfg::{get_log_folder, Connection, ExportPath, ExportPathConnection, PyHttpReaderCfg};
use crate::file_util::{
osstr_to_str, to_stem_str, PathPair, SavedCfg, DEFAULT_HOMEDIR, DEFAULT_PRJ_NAME,
DEFAULT_PRJ_PATH,
Expand All @@ -8,13 +7,16 @@ use crate::history::{History, Record};
use crate::meta_data::{ConnectionData, MetaData, MetaDataFlags};
use crate::result::{trace_ok_err, trace_ok_warn};
use crate::sort_params::SortParams;
use crate::tools_data::ToolsDataMap;
use crate::tools::{BBOX_NAME, BRUSH_NAME};
use crate::tools_data::{coco_io::read_coco, ToolsDataMap};
use crate::world::{DataRaw, World};
use crate::{
cfg::Cfg, image_reader::ReaderFromCfg, threadpool::ThreadPool, types::AsyncResultImage,
};
use crate::{defer_file_removal, get_specifics_mut_from_tdm};
use chrono::{DateTime, Utc};
use detail::{create_lock_file, lock_file_path, read_user_from_lockfile};
use egui::ahash::HashSet;
use rvimage_domain::{rverr, to_rv, RvError, RvResult};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
Expand Down Expand Up @@ -481,6 +483,48 @@ impl Control {
self.import_settings(prj_path)?;
Ok(())
}
pub fn import_from_coco(
&mut self,
coco_path: &str,
tools_data_map: &mut ToolsDataMap,
connection: ExportPathConnection,
) -> RvResult<()> {
tracing::info!("importing from coco {coco_path:?}");

let meta_data = self.meta_data(None, None);
let path = ExportPath {
path: Path::new(coco_path).to_path_buf(),
conn: connection,
};
let (bbox_tool_data, brush_tool_data) = read_coco(&meta_data, &path, None)?;
let server_addresses = bbox_tool_data
.annotations_map
.keys()
.chain(brush_tool_data.annotations_map.keys())
.filter(|k| k.starts_with("http://"))
.flat_map(|k| k.rsplitn(2, '/').last())
.collect::<HashSet<_>>();
if !server_addresses.is_empty() {
self.cfg.prj.connection = Connection::PyHttp;

let server_addresses = server_addresses
.iter()
.map(|s| s.to_string())
.collect::<Vec<_>>();
self.cfg.prj.py_http_reader_cfg = Some(PyHttpReaderCfg { server_addresses });
}
let first_sa = server_addresses.iter().next().map(|s| s.to_string());
if let Some(sa) = first_sa {
self.open_relative_folder(sa.to_string())?;
}
if let Some(tdm) = get_specifics_mut_from_tdm!(BRUSH_NAME, tools_data_map, brush_mut) {
*tdm = brush_tool_data;
}
if let Some(tdm) = get_specifics_mut_from_tdm!(BBOX_NAME, tools_data_map, bbox_mut) {
*tdm = bbox_tool_data;
}
Ok(())
}

fn set_current_prj_path(&mut self, prj_path: PathBuf) -> RvResult<()> {
trace_ok_warn(detail::create_lock_file(&prj_path));
Expand Down Expand Up @@ -848,7 +892,6 @@ impl Control {
use {
crate::{
file_util::DEFAULT_TMPDIR,
tools::BBOX_NAME,
tools_data::{BboxToolData, ToolSpecifics, ToolsData},
},
rvimage_domain::{make_test_bbs, ShapeI},
Expand Down
4 changes: 2 additions & 2 deletions rvimage/src/rvlib/menu/annotations_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ fn annotations(
.show(ui, |ui| {
let n_prop: Option<usize> = ui_util::button_triggerable_number(
ui,
&mut params.text_buffers.label_propagation_buffer,
&mut params.text_buffers.label_propagation,
are_tools_active,
"propagate labels",
"number of following images to propagate label to",
Expand All @@ -544,7 +544,7 @@ fn annotations(
ui.end_row();
let n_del: Option<usize> = ui_util::button_triggerable_number(
ui,
&mut params.text_buffers.label_deletion_buffer,
&mut params.text_buffers.label_deletion,
are_tools_active,
"delete labels",
"number of following images to delete label from",
Expand Down
55 changes: 50 additions & 5 deletions rvimage/src/rvlib/menu/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
cfg::ExportPathConnection,
control::{Control, Info},
file_util::get_prj_name,
file_util::{get_prj_name, path_to_str},
image_reader::LoadImageForGui,
menu::{
self,
Expand Down Expand Up @@ -165,8 +166,9 @@ fn save_dialog_in_prjfolder(prj_path: &Path, opened_folder: Option<&str>) -> Opt
#[derive(Default)]
pub struct TextBuffers {
pub filter_string: String,
pub label_propagation_buffer: String,
pub label_deletion_buffer: String,
pub label_propagation: String,
pub label_deletion: String,
pub import_coco_from_ssh_path: String,
}

pub struct Menu {
Expand All @@ -180,14 +182,16 @@ pub struct Menu {
text_buffers: TextBuffers,
show_file_idx: bool,
annotations_menu_params: AnnotationsParams,
import_coco_from_ssh: bool,
}

impl Menu {
fn new() -> Self {
let text_buffers = TextBuffers {
filter_string: "".to_string(),
label_propagation_buffer: "".to_string(),
label_deletion_buffer: "".to_string(),
label_propagation: "".to_string(),
label_deletion: "".to_string(),
import_coco_from_ssh_path: "path on ssh server".to_string(),
};
Self {
window_open: true,
Expand All @@ -200,6 +204,7 @@ impl Menu {
text_buffers,
show_file_idx: true,
annotations_menu_params: AnnotationsParams::default(),
import_coco_from_ssh: false,
}
}
pub fn popup(&mut self, info: Info) {
Expand Down Expand Up @@ -334,6 +339,46 @@ impl Menu {
}
ui.close_menu();
}
ui.horizontal(|ui| {
if ui.button("... Annotations from COCO file").clicked() {
let prj_path = if !self.import_coco_from_ssh {
rfd::FileDialog::new()
.set_title("Annotations from COCO file")
.add_filter("coco files", &["json"])
.pick_file()
.and_then(|p| path_to_str(&p).ok().map(|s| s.to_string()))
} else {
Some(self.text_buffers.import_coco_from_ssh_path.clone())
};
if let Some(prj_path) = prj_path {
handle_error!(
|()| {
projected_loaded = true;
},
ctrl.import_from_coco(
&prj_path,
tools_data_map,
if self.import_coco_from_ssh {
ExportPathConnection::Ssh
} else {
ExportPathConnection::Local
}
),
self
);
}
ui.close_menu();
}
ui.checkbox(&mut self.import_coco_from_ssh, "ssh")
});

if self.import_coco_from_ssh {
text_edit_singleline(
ui,
&mut self.text_buffers.import_coco_from_ssh_path,
&mut self.are_tools_active,
);
}
});

let popup_id = ui.make_persistent_id("autosave-popup");
Expand Down
29 changes: 20 additions & 9 deletions rvimage/src/rvlib/tools_data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ impl ToolSpecifics {

pub fn apply_mut<T>(
&mut self,
mut f_bbox: impl FnMut(&mut BboxToolData) -> RvResult<T>,
mut f_brush: impl FnMut(&mut BrushToolData) -> RvResult<T>,
f_bbox: impl FnOnce(&mut BboxToolData) -> RvResult<T>,
f_brush: impl FnOnce(&mut BrushToolData) -> RvResult<T>,
) -> RvResult<T> {
match self {
Self::Bbox(bbox_data) => f_bbox(bbox_data),
Expand All @@ -97,8 +97,8 @@ impl ToolSpecifics {
}
pub fn apply<T>(
&self,
mut f_bbox: impl FnMut(&BboxToolData) -> RvResult<T>,
mut f_brush: impl FnMut(&BrushToolData) -> RvResult<T>,
f_bbox: impl FnOnce(&BboxToolData) -> RvResult<T>,
f_brush: impl FnOnce(&BrushToolData) -> RvResult<T>,
) -> RvResult<T> {
match self {
Self::Bbox(bbox_data) => f_bbox(bbox_data),
Expand Down Expand Up @@ -229,19 +229,30 @@ macro_rules! toolsdata_by_name {
pub type ToolsDataMap = HashMap<String, ToolsData>;

#[macro_export]
macro_rules! get_annos_from_tdm {
($actor_name:expr, $tdm:expr, $current_file_path:expr, $access_func:ident) => {
macro_rules! get_specifics_mut_from_tdm {
($actor_name:expr, $tdm:expr, $access_func:ident) => {
$tdm.get_mut($actor_name)
.and_then(|x| x.specifics.$access_func().ok())
};
}
#[macro_export]
macro_rules! get_specifics_from_tdm {
($actor_name:expr, $tdm:expr, $access_func:ident) => {
$tdm.get($actor_name)
.and_then(|x| x.specifics.$access_func().ok())
};
}
#[macro_export]
macro_rules! get_annos_from_tdm {
($actor_name:expr, $tdm:expr, $current_file_path:expr, $access_func:ident) => {
$crate::get_specifics_from_tdm!($actor_name, $tdm, $access_func)
.and_then(|d| d.get_annos($current_file_path))
};
}

#[macro_export]
macro_rules! get_labelinfo_from_tdm {
($actor_name:expr, $tdm:expr, $access_func:ident) => {
$tdm.get($actor_name)
.and_then(|x| x.specifics.$access_func().ok())
.map(|d| d.label_info())
$crate::get_specifics_from_tdm!($actor_name, $tdm, $access_func).map(|d| d.label_info())
};
}

0 comments on commit f230333

Please # to comment.