From 90e60954c8e7f979b1b13d44aaa6842e46271fa0 Mon Sep 17 00:00:00 2001 From: yuckinus <40965122+yuckinus@users.noreply.github.com> Date: Thu, 4 Dec 2025 22:47:06 +0200 Subject: [PATCH 1/2] Raw data viewer upgrade - first step in raw data viewer app upgrade (added icon, switched some built in functions to standard utils.cpp) - minor fixes in apps based on github issues --- .../mandeye_compare_trajectories.cpp | 2 +- .../lidar_odometry_gui.cpp | 2 +- apps/lidar_odometry_step_1/resource.rc | 8 +- .../mandeye_mission_recorder_calibration.cpp | 2 + .../resource.rc | 8 +- apps/mandeye_raw_data_viewer/CMakeLists.txt | 14 +- apps/mandeye_raw_data_viewer/icon.ico | Bin 0 -> 25645 bytes .../mandeye_raw_data_viewer.cpp | 276 ++++-------------- apps/mandeye_raw_data_viewer/resource.h | 17 ++ apps/mandeye_raw_data_viewer/resource.rc | 50 ++++ .../mandeye_single_session_viewer/resource.rc | 8 +- .../multi_session_registration.cpp | 3 +- apps/multi_session_registration/resource.rc | 8 +- .../multi_view_tls_registration_gui.cpp | 1 - apps/multi_view_tls_registration/resource.rc | 8 +- core/include/utils.hpp | 4 +- 16 files changed, 157 insertions(+), 254 deletions(-) create mode 100644 apps/mandeye_raw_data_viewer/icon.ico create mode 100644 apps/mandeye_raw_data_viewer/resource.h create mode 100644 apps/mandeye_raw_data_viewer/resource.rc diff --git a/apps/compare_trajectories/mandeye_compare_trajectories.cpp b/apps/compare_trajectories/mandeye_compare_trajectories.cpp index 588f219e..d1190b0f 100644 --- a/apps/compare_trajectories/mandeye_compare_trajectories.cpp +++ b/apps/compare_trajectories/mandeye_compare_trajectories.cpp @@ -708,7 +708,7 @@ void project_gui() for (Eigen::SparseMatrix::InnerIterator it(x, k); it; ++it) { h_x.push_back(it.value()); - std::cout << it.row() << " " << it.col() << " " << it.value() << std::endl; + std::cout << std::fixed << std::setprecision(6) << it.row() << " " << it.col() << " " << it.value() << std::endl; } } diff --git a/apps/lidar_odometry_step_1/lidar_odometry_gui.cpp b/apps/lidar_odometry_step_1/lidar_odometry_gui.cpp index 2c8fc8da..0d3ef806 100644 --- a/apps/lidar_odometry_step_1/lidar_odometry_gui.cpp +++ b/apps/lidar_odometry_step_1/lidar_odometry_gui.cpp @@ -956,7 +956,7 @@ void project_gui() } if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Select all IMU *.csv and LiDAR *.laz files produced by MANDEYE saved in 'continousScanning_*' folder"); + ImGui::SetTooltip("Select folder containing IMU *.csv and LiDAR *.laz files produced by MANDEYE (e.g.: 'continousScanning_*')"); } if (step_1_done && !step_2_done) { diff --git a/apps/lidar_odometry_step_1/resource.rc b/apps/lidar_odometry_step_1/resource.rc index 3da62eee..1a74ec5f 100644 --- a/apps/lidar_odometry_step_1/resource.rc +++ b/apps/lidar_odometry_step_1/resource.rc @@ -20,8 +20,8 @@ IDI_ICON1 ICON "icon.ico" // VS_VERSION_INFO VERSIONINFO -FILEVERSION 0, 0, 9, 0 -PRODUCTVERSION 0, 0, 9, 0 +FILEVERSION 0, 0, 9, 2 +PRODUCTVERSION 0, 0, 9, 2 FILEFLAGSMASK 0x3fL FILEOS 0x40004 FILETYPE 0x1 @@ -32,11 +32,11 @@ BLOCK "040904B0" BEGIN VALUE "CompanyName", "Mandeye\0" VALUE "FileDescription", "HDMapping Step 1\0" -VALUE "FileVersion", "0.8.9\0" +VALUE "FileVersion", "0.9.2\0" VALUE "InternalName", "Odometry\0" VALUE "LegalCopyright", "(c) 2025 github.com/MapsHD/HDMapping\0" VALUE "OriginalFilename", "lidar_odometry_step_1.exe\0" -VALUE "ProductVersion", "0.8.9\0" +VALUE "ProductVersion", "0.9.2\0" VALUE "ProgramID", "github.com/MapsHD/HDMapping\0" VALUE "ProductName", "HDMapping\0" END diff --git a/apps/mandeye_mission_recorder_calibration/mandeye_mission_recorder_calibration.cpp b/apps/mandeye_mission_recorder_calibration/mandeye_mission_recorder_calibration.cpp index 7a50e13f..9dc43a7e 100644 --- a/apps/mandeye_mission_recorder_calibration/mandeye_mission_recorder_calibration.cpp +++ b/apps/mandeye_mission_recorder_calibration/mandeye_mission_recorder_calibration.cpp @@ -33,6 +33,8 @@ #include "resource.h" #endif +/////////////////////////////////////////////////////////////////////////////////// + std::string winTitle = std::string("MR calibration ") + HDMAPPING_VERSION_STRING; std::vector infoLines = { diff --git a/apps/mandeye_mission_recorder_calibration/resource.rc b/apps/mandeye_mission_recorder_calibration/resource.rc index e587ecab..ef2b9e31 100644 --- a/apps/mandeye_mission_recorder_calibration/resource.rc +++ b/apps/mandeye_mission_recorder_calibration/resource.rc @@ -20,8 +20,8 @@ IDI_ICON1 ICON "icon.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,9,0 - PRODUCTVERSION 0,0,9,0 + FILEVERSION 0,0,9,2 + PRODUCTVERSION 0,0,9,2 FILEFLAGSMASK 0x3fL FILEOS 0x40004 FILETYPE 0x1 @@ -32,11 +32,11 @@ BEGIN BEGIN VALUE "CompanyName", "Mandeye\0" VALUE "FileDescription", "HDMapping MR Calibration\0" - VALUE "FileVersion", "0.8.9\0" + VALUE "FileVersion", "0.9.2\0" VALUE "InternalName", "Mission Recorder Calibration\0" VALUE "LegalCopyright", "(c) 2025 github.com/MapsHD/HDMapping\0" VALUE "OriginalFilename", "mandeye_mission_recorder_calibration.exe\0" - VALUE "ProductVersion", "0.8.9\0" + VALUE "ProductVersion", "0.9.2\0" VALUE "ProgramID", "github.com/MapsHD/HDMapping\0" VALUE "ProductName", "HDMapping\0" END diff --git a/apps/mandeye_raw_data_viewer/CMakeLists.txt b/apps/mandeye_raw_data_viewer/CMakeLists.txt index 799d5c9f..ca00c883 100644 --- a/apps/mandeye_raw_data_viewer/CMakeLists.txt +++ b/apps/mandeye_raw_data_viewer/CMakeLists.txt @@ -2,12 +2,22 @@ cmake_minimum_required(VERSION 4.0.0) project(mandeye_raw_data_viewer) -add_executable( - mandeye_raw_data_viewer +# Source files +set(SOURCES mandeye_raw_data_viewer.cpp ../lidar_odometry_step_1/lidar_odometry_utils.cpp ../lidar_odometry_step_1/lidar_odometry_gui_utils.cpp ../lidar_odometry_step_1/lidar_odometry_utils_optimizers.cpp + "../../core/src/utils.cpp" +) + +# Windows: add resource file +if(WIN32) + list(APPEND SOURCES resource.rc) +endif() + +add_executable( + mandeye_raw_data_viewer ${SOURCES} ) target_include_directories( diff --git a/apps/mandeye_raw_data_viewer/icon.ico b/apps/mandeye_raw_data_viewer/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..710913e34e4b182cb7412859d885face7f382cd6 GIT binary patch literal 25645 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

`U#R1=n0`c}Im`Jg^ffTC9P3 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 #include +#include + #include #include @@ -27,32 +29,34 @@ #include +#ifdef _WIN32 + #include + #include // <-- Required for ShellExecuteA + #include "resource.h" +#endif + +/////////////////////////////////////////////////////////////////////////////////// + +std::string winTitle = std::string("Raw data viewer ") + HDMAPPING_VERSION_STRING; + +std::vector infoLines = { + "This program is optional step in MANDEYE process", + "", + "It analyzes LiDAR data created by Mission Recorder", + "Next step will be to load data with 'lidar_odometry_step_1' app" +}; + +//App specific shortcuts (using empty dummy until needed) +std::vector appShortcuts(80, { "", "", "" }); + + #define SAMPLE_PERIOD (1.0 / 200.0) namespace fs = std::filesystem; -const unsigned int window_width = 800; -const unsigned int window_height = 600; -double camera_ortho_xy_view_zoom = 10; -double camera_ortho_xy_view_shift_x = 0.0; -double camera_ortho_xy_view_shift_y = 0.0; -double camera_mode_ortho_z_center_h = 0.0; -double camera_ortho_xy_view_rotation_angle_deg = 0; -bool is_ortho = false; -bool show_axes = true; ImVec4 clear_color = ImVec4(0.8f, 0.8f, 0.8f, 1.00f); ImVec4 pc_color = ImVec4(1.0f, 0.0f, 0.0f, 1.00f); ImVec4 pc_color2 = ImVec4(0.0f, 0.0f, 1.0f, 1.00f); -int point_size = 1; -Eigen::Vector3f rotation_center = Eigen::Vector3f::Zero(); -float translate_x, translate_y = 0.0; -float translate_z = -50.0; -float rotate_x = 0.0, rotate_y = 0.0; -int mouse_old_x, mouse_old_y; -int mouse_buttons = 0; -bool gui_mouse_down{false}; -float mouse_sensitivity = 1.0; - float m_ortho_projection[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, @@ -144,80 +148,6 @@ namespace photos int photo_width_cam0 = 0; int photo_height_cam0 = 0; } -void reshape(int w, int h) -{ - glViewport(0, 0, (GLsizei)w, (GLsizei)h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - if (!is_ortho) - { - gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 0.01, 10000.0); - } - else - { - ImGuiIO &io = ImGui::GetIO(); - float ratio = float(io.DisplaySize.x) / float(io.DisplaySize.y); - - glOrtho(-camera_ortho_xy_view_zoom, camera_ortho_xy_view_zoom, - -camera_ortho_xy_view_zoom / ratio, - camera_ortho_xy_view_zoom / ratio, -100000, 100000); - // glOrtho(-translate_z, translate_z, -translate_z * (float)h / float(w), translate_z * float(h) / float(w), -10000, 10000); - } - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); -} - -void motion(int x, int y) -{ - ImGuiIO &io = ImGui::GetIO(); - io.MousePos = ImVec2((float)x, (float)y); - - if (!io.WantCaptureMouse) - { - float dx, dy; - dx = (float)(x - mouse_old_x); - dy = (float)(y - mouse_old_y); - - if (is_ortho) - { - if (mouse_buttons & 1) - { - float ratio = float(io.DisplaySize.x) / float(io.DisplaySize.y); - Eigen::Vector3d v(dx * (camera_ortho_xy_view_zoom / (GLsizei)io.DisplaySize.x * 2), - dy * (camera_ortho_xy_view_zoom / (GLsizei)io.DisplaySize.y * 2 / ratio), 0); - TaitBryanPose pose_tb; - pose_tb.px = 0.0; - pose_tb.py = 0.0; - pose_tb.pz = 0.0; - pose_tb.om = 0.0; - pose_tb.fi = 0.0; - pose_tb.ka = camera_ortho_xy_view_rotation_angle_deg * M_PI / 180.0; - auto m = affine_matrix_from_pose_tait_bryan(pose_tb); - Eigen::Vector3d v_t = m * v; - camera_ortho_xy_view_shift_x += v_t.x(); - camera_ortho_xy_view_shift_y += v_t.y(); - } - } - else - { - gui_mouse_down = mouse_buttons > 0; - if (mouse_buttons & 1) - { - rotate_x += dy * 0.2f; // * mouse_sensitivity; - rotate_y += dx * 0.2f; // * mouse_sensitivity; - } - if (mouse_buttons & 4) - { - translate_x += dx * 0.05f * mouse_sensitivity; - translate_y -= dy * 0.05f * mouse_sensitivity; - } - } - - mouse_old_x = x; - mouse_old_y = y; - } - glutPostRedisplay(); -} static ImVec2 DisplayImageFit(ImTextureID tex, int tex_w, int tex_h, bool allow_upscale = true) { @@ -290,12 +220,11 @@ void project_gui() ImGui::Text("timestamp: %s", std::to_string(photos::nearestTs).c_str()); // get available size DisplayImageFit((ImTextureID)photos::photo_texture_cam0, photo_width_cam0, photo_height_cam0); - - } ImGui::End(); } + if (ImGui::Begin("main gui window")) { ImGui::ColorEdit3("clear color", (float *)&clear_color); @@ -351,13 +280,9 @@ void project_gui() all_file_names.push_back(fileName); } else if (fileName.ends_with(".csv")) - { csv_files.push_back(fileName); - } else if (fileName.ends_with(".sn")) - { sn_files.push_back(fileName); - } else if (fileName.ends_with(".jpg")) { photos_files.push_back(fileName); // decode filename e.g.: ` cam0_1761264773592270949.jpg` @@ -394,9 +319,7 @@ void project_gui() { std::cout << "Loaded calibration for: \n"; for (const auto &[sn, _] : preloadedCalibration) - { std::cout << " -> " << sn << std::endl; - } } else { @@ -429,16 +352,13 @@ void project_gui() fs::path wdp = fs::path(input_file_names[0]).parent_path(); wdp /= "preview"; if (!fs::exists(wdp)) - { fs::create_directory(wdp); - } working_directory_preview = wdp.string(); for (size_t i = 0; i < input_file_names.size(); i++) - { std::cout << input_file_names[i] << std::endl; - } + std::cout << "loading imu" << std::endl; std::vector, FusionVector, FusionVector>> imu_data; @@ -492,9 +412,7 @@ void project_gui() std::ofstream testPointcloud{calibrationValidtationFile.c_str()}; for (const auto &p : data) - { testPointcloud << p.point.x() << "\t" << p.point.y() << "\t" << p.point.z() << "\t" << p.intensity << "\t" << (int)p.lidarid << "\n"; - } } std::unique_lock lck(mtx); @@ -513,17 +431,14 @@ void project_gui() FusionAhrsInitialise(&ahrs); if (fusionConventionNwu) - { ahrs.settings.convention = FusionConventionNwu; - } + if (fusionConventionEnu) - { ahrs.settings.convention = FusionConventionEnu; - } + if (fusionConventionNed) - { ahrs.settings.convention = FusionConventionNed; - } + ahrs.settings.gain = ahrs_gain; std::map> trajectory; @@ -586,9 +501,7 @@ void project_gui() const FusionEuler euler = FusionQuaternionToEuler(FusionAhrsGetQuaternion(&ahrs)); counter++; if (counter % 100 == 0) - { printf("Roll %0.1f, Pitch %0.1f, Yaw %0.1f [%d of %d]\n", euler.angle.roll, euler.angle.pitch, euler.angle.yaw, counter++, imu_data.size()); - } // log it for implot imu_data_plot.timestampLidar.push_back(timestamp_pair.first); @@ -615,9 +528,8 @@ void project_gui() int number_of_points = 0; for (const auto &pp : pointsPerFile) - { number_of_points += pp.size(); - } + std::cout << "number of points: " << number_of_points << std::endl; std::cout << "start indexing points" << std::endl; @@ -714,9 +626,7 @@ void project_gui() //std::cout << "ts_end " << data.timestamps[data.timestamps.size() - 1].first << std::endl; for (int pp = 0; pp < data.points_local.size(); pp++) - { data.points_local[pp].timestamp = ts_begin + pp * ts_step; - } } all_data.push_back(data); @@ -784,9 +694,7 @@ void project_gui() }*/ if (!exportLaz(output_file_name, pointcloud, intensity, timestamps, 0, 0, 0)) - { std::cout << "problem with saving file: " << output_file_name << std::endl; - } } } @@ -806,20 +714,16 @@ void project_gui() ImGui::Text("---------------------------------------------"); if (ImGui::Button("optimize")) - { optimize(); - } if (ImGui::Button("get_nn")) - { rgd_nn = get_nn(); - } + ImGui::Checkbox("show show_rgd_nn", &show_rgd_nn); if (ImGui::Button("get_mean_cov")) - { mean_cov = get_mean_cov(); - } + ImGui::Checkbox("show_mean_cov", &show_mean_cov); if (ImGui::Button("debug text")) @@ -850,9 +754,7 @@ void project_gui() std::cout << "max_diff " << max_diff << std::endl; std::cout << "----------------" << std::endl; for (int k = 0; k < all_data[index_rendered_points_local].timestamps.size(); k++) - { std::cout << all_data[index_rendered_points_local].timestamps[k].first << std::endl; - } } } @@ -872,9 +774,7 @@ void project_gui() if (index_rendered_points_local >= 0 && index_rendered_points_local < all_data.size()) { if (all_data[index_rendered_points_local].timestamps.size() > 0) - { annotation = all_data[index_rendered_points_local].timestamps.front().first; - } } if (ImPlot::BeginPlot("Imu - acceleration 'm/s^2", ImVec2(-1, 0))) { @@ -1133,13 +1033,10 @@ void display() Eigen::Vector3d p = m * all_data[index_rendered_points_local].points_local[i].point; if (all_data[index_rendered_points_local].lidar_ids[i] == 0) - { glColor3f(pc_color.x, pc_color.y, pc_color.z); - } else - { glColor3f(pc_color2.x, pc_color2.y, pc_color2.z); - } + glVertex3f(p.x(), p.y(), p.z()); //} } @@ -1210,9 +1107,7 @@ void display() if (show_mean_cov) { for (const auto &mc : mean_cov) - { draw_ellipse(mc.second, mc.first, Eigen::Vector3f(1, 0, 0), 1); - } } ImGui_ImplOpenGL2_NewFrame(); @@ -1228,42 +1123,6 @@ void display() glutPostRedisplay(); } -bool initGL(int *argc, char **argv) -{ - glutInit(argc, argv); - glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); - glutInitWindowSize(window_width, window_height); - glutCreateWindow("mandeye raw data viewer " HDMAPPING_VERSION_STRING); - glutDisplayFunc(display); - glutMotionFunc(motion); - - // default initialization - glClearColor(0.0, 0.0, 0.0, 1.0); - glEnable(GL_DEPTH_TEST); - - // viewport - glViewport(0, 0, window_width, window_height); - - // projection - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(60.0, (GLfloat)window_width / (GLfloat)window_height, 0.01, 10000.0); - glutReshapeFunc(reshape); - ImGui::CreateContext(); - ImPlot::CreateContext(); - ImGuiIO &io = ImGui::GetIO(); - (void)io; - // io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - - ImGui::StyleColorsDark(); - ImGui_ImplGLUT_Init(); - ImGui_ImplGLUT_InstallFuncs(); - ImGui_ImplOpenGL2_Init(); - return true; -} - -void wheel(int button, int dir, int x, int y); - void mouse(int glut_button, int state, int x, int y) { ImGuiIO &io = ImGui::GetIO(); @@ -1306,60 +1165,33 @@ void mouse(int glut_button, int state, int x, int y) } } -void wheel(int button, int dir, int x, int y) +int main(int argc, char* argv[]) { - ImGuiIO &io = ImGui::GetIO(); - io.MouseWheel += (float)dir; - if (io.WantCaptureMouse) + try { - // ImGui is handling the mouse wheel - return; - } + initGL(&argc, argv, winTitle, display, mouse); - if (dir > 0) - { - if (is_ortho) - { - camera_ortho_xy_view_zoom -= 0.1f * camera_ortho_xy_view_zoom; + glutMainLoop(); - if (camera_ortho_xy_view_zoom < 0.1) - { - camera_ortho_xy_view_zoom = 0.1; - } - } - else - { - translate_z -= 0.05f * translate_z; - } + ImGui_ImplOpenGL2_Shutdown(); + ImGui_ImplGLUT_Shutdown(); + ImGui::DestroyContext(); + ImPlot::DestroyContext(); } - else + catch (const std::bad_alloc& e) { - if (is_ortho) - { - camera_ortho_xy_view_zoom += 0.1 * camera_ortho_xy_view_zoom; - } - else - { - translate_z += 0.05f * translate_z; - } + std::cerr << "System is out of memory : " << e.what() << std::endl; + mandeye::fd::OutOfMemMessage(); + } + catch (const std::exception& e) + { + std::cout << e.what(); + } + catch (...) + { + std::cerr << "Unknown fatal error occurred." << std::endl; } - return; -} -int main(int argc, char *argv[]) -{ - initGL(&argc, argv); - glutDisplayFunc(display); - glutMouseFunc(mouse); - glutMotionFunc(motion); - glutMouseWheelFunc(wheel); - glutMainLoop(); - - ImGui_ImplOpenGL2_Shutdown(); - ImGui_ImplGLUT_Shutdown(); - - ImPlot::DestroyContext(); - ImGui::DestroyContext(); return 0; } @@ -1980,13 +1812,9 @@ std::vector> get_mean_cov() int index_pose = std::distance(worker_data.timestamps.begin(), lower) - 1; if (index_pose >= 0 && index_pose < worker_data.poses.size()) - { worker_data.points_local[i].index_pose = index_pose; - } else - { worker_data.points_local[i].index_pose = -1; - } } NDT::GridParameters rgd_params; @@ -2064,4 +1892,4 @@ std::vector> get_mean_cov() } return mc; -} +} \ No newline at end of file diff --git a/apps/mandeye_raw_data_viewer/resource.h b/apps/mandeye_raw_data_viewer/resource.h new file mode 100644 index 00000000..936648af --- /dev/null +++ b/apps/mandeye_raw_data_viewer/resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDI_ICON1 101 //application icon +#define VS_VERSION_INFO 1 //version info + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/apps/mandeye_raw_data_viewer/resource.rc b/apps/mandeye_raw_data_viewer/resource.rc new file mode 100644 index 00000000..d399a03f --- /dev/null +++ b/apps/mandeye_raw_data_viewer/resource.rc @@ -0,0 +1,50 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,9,2 + PRODUCTVERSION 0,0,9,2 + FILEFLAGSMASK 0x3fL + FILEOS 0x40004 + FILETYPE 0x1 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "Mandeye\0" + VALUE "FileDescription", "HDMapping Raw Data Viewer\0" + VALUE "FileVersion", "0.9.2\0" + VALUE "InternalName", "Raw data viewer\0" + VALUE "LegalCopyright", "(c) 2025 github.com/MapsHD/HDMapping\0" + VALUE "OriginalFilename", "mandeye_raw_data_viewer.exe\0" + VALUE "ProductVersion", "0.9.2\0" + VALUE "ProgramID", "github.com/MapsHD/HDMapping\0" + VALUE "ProductName", "HDMapping\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0x04B0 + END +END +///////////////////////////////////////////////////////////////////////////// + diff --git a/apps/mandeye_single_session_viewer/resource.rc b/apps/mandeye_single_session_viewer/resource.rc index 86502833..9ab99052 100644 --- a/apps/mandeye_single_session_viewer/resource.rc +++ b/apps/mandeye_single_session_viewer/resource.rc @@ -20,8 +20,8 @@ IDI_ICON1 ICON "icon.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,9,0 - PRODUCTVERSION 0,0,9,0 + FILEVERSION 0,0,9,2 + PRODUCTVERSION 0,0,9,2 FILEFLAGSMASK 0x3fL FILEOS 0x40004 FILETYPE 0x1 @@ -32,11 +32,11 @@ BEGIN BEGIN VALUE "CompanyName", "Mandeye\0" VALUE "FileDescription", "HDMapping Session Viewer\0" - VALUE "FileVersion", "0.8.9\0" + VALUE "FileVersion", "0.9.2\0" VALUE "InternalName", "Single session viewer\0" VALUE "LegalCopyright", "(c) 2025 github.com/MapsHD/HDMapping\0" VALUE "OriginalFilename", "mandeye_single_session_viewer.exe\0" - VALUE "ProductVersion", "0.8.9\0" + VALUE "ProductVersion", "0.9.2\0" VALUE "ProgramID", "github.com/MapsHD/HDMapping\0" VALUE "ProductName", "HDMapping\0" END diff --git a/apps/multi_session_registration/multi_session_registration.cpp b/apps/multi_session_registration/multi_session_registration.cpp index f691835d..e237ed0e 100644 --- a/apps/multi_session_registration/multi_session_registration.cpp +++ b/apps/multi_session_registration/multi_session_registration.cpp @@ -2732,9 +2732,8 @@ void project_gui() ImGui::InputDouble("Increment", &fast_plus); ImGui::InputDouble("Fast increment", &fast_plus_plus); - ImGui::PopItemWidth(); - ImGui::SetNextItemWidth(ImGuiNumberWidth); ImGui::InputDouble("Timestamp offset", &time_stamp_offset, fast_plus, fast_plus_plus); + ImGui::PopItemWidth(); ImGui::SameLine(); if (ImGui::Button("Set to origin")) { diff --git a/apps/multi_session_registration/resource.rc b/apps/multi_session_registration/resource.rc index 572caf87..433dda28 100644 --- a/apps/multi_session_registration/resource.rc +++ b/apps/multi_session_registration/resource.rc @@ -20,8 +20,8 @@ IDI_ICON1 ICON "icon.ico" // VS_VERSION_INFO VERSIONINFO -FILEVERSION 0, 0, 9, 0 -PRODUCTVERSION 0, 0, 9, 0 +FILEVERSION 0, 0, 9, 2 +PRODUCTVERSION 0, 0, 9, 2 FILEFLAGSMASK 0x3fL FILEOS 0x40004 FILETYPE 0x1 @@ -32,11 +32,11 @@ BLOCK "040904B0" BEGIN VALUE "CompanyName", "Mandeye\0" VALUE "FileDescription", "HDMapping Step 3\0" -VALUE "FileVersion", "0.8.9\0" +VALUE "FileVersion", "0.9.2\0" VALUE "InternalName", "Multi session registration\0" VALUE "LegalCopyright", "(c) 2025 github.com/MapsHD/HDMapping\0" VALUE "OriginalFilename", "multi_session_registration_step_3.exe\0" -VALUE "ProductVersion", "0.8.9\0" +VALUE "ProductVersion", "0.9.2\0" VALUE "ProgramID", "github.com/MapsHD/HDMapping\0" VALUE "ProductName", "HDMapping\0" END diff --git a/apps/multi_view_tls_registration/multi_view_tls_registration_gui.cpp b/apps/multi_view_tls_registration/multi_view_tls_registration_gui.cpp index 9a649f88..5e50d6be 100644 --- a/apps/multi_view_tls_registration/multi_view_tls_registration_gui.cpp +++ b/apps/multi_view_tls_registration/multi_view_tls_registration_gui.cpp @@ -3304,7 +3304,6 @@ int main(int argc, char *argv[]) { initGL(&argc, argv, winTitle, display, mouse); - glutMainLoop(); ImGui_ImplOpenGL2_Shutdown(); diff --git a/apps/multi_view_tls_registration/resource.rc b/apps/multi_view_tls_registration/resource.rc index b3446f4d..a790594a 100644 --- a/apps/multi_view_tls_registration/resource.rc +++ b/apps/multi_view_tls_registration/resource.rc @@ -20,8 +20,8 @@ IDI_ICON1 ICON "icon.ico" // VS_VERSION_INFO VERSIONINFO -FILEVERSION 0, 0, 9, 0 -PRODUCTVERSION 0, 0, 9, 0 +FILEVERSION 0, 0, 9, 2 +PRODUCTVERSION 0, 0, 9, 2 FILEFLAGSMASK 0x3fL FILEOS 0x40004 FILETYPE 0x1 @@ -32,11 +32,11 @@ BLOCK "040904B0" BEGIN VALUE "CompanyName", "Mandeye\0" VALUE "FileDescription", "HDMapping Step 2\0" -VALUE "FileVersion", "0.8.9\0" +VALUE "FileVersion", "0.9.2\0" VALUE "InternalName", "Multi view TLS registration\0" VALUE "LegalCopyright", "(c) 2025 github.com/MapsHD/HDMapping\0" VALUE "OriginalFilename", "multi_view_tls_registration_step_2.exe\0" -VALUE "ProductVersion", "0.8.9\0" +VALUE "ProductVersion", "0.9.2\0" VALUE "ProgramID", "github.com/MapsHD/HDMapping\0" VALUE "ProductName", "HDMapping\0" END diff --git a/core/include/utils.hpp b/core/include/utils.hpp index 3b3e209c..ca24a819 100644 --- a/core/include/utils.hpp +++ b/core/include/utils.hpp @@ -44,7 +44,6 @@ enum CameraPreset { extern int viewer_decimate_point_cloud; extern int mouse_old_x, mouse_old_y; -extern bool gui_mouse_down; extern int mouse_buttons; extern float mouse_sensitivity; @@ -61,8 +60,7 @@ extern Eigen::Affine3f viewLocal; extern Eigen::Vector3f rotation_center; extern float rotate_x, rotate_y; -extern float translate_x, translate_y; -extern float translate_z; +extern float translate_x, translate_y, translate_z; extern double camera_ortho_xy_view_zoom; extern double camera_ortho_xy_view_shift_x; From cd1df0430c507858ec4ef7e3df5ddd9e2b02a55c Mon Sep 17 00:00:00 2001 From: yuckinus <40965122+yuckinus@users.noreply.github.com> Date: Fri, 5 Dec 2025 08:51:32 +0200 Subject: [PATCH 2/2] Fix step2 Save all marked trajectories duplicate menu items --- .../multi_view_tls_registration_gui.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/multi_view_tls_registration/multi_view_tls_registration_gui.cpp b/apps/multi_view_tls_registration/multi_view_tls_registration_gui.cpp index 5e50d6be..45f321ea 100644 --- a/apps/multi_view_tls_registration/multi_view_tls_registration_gui.cpp +++ b/apps/multi_view_tls_registration/multi_view_tls_registration_gui.cpp @@ -2507,7 +2507,7 @@ void display() ImGui::Separator(); ImGui::Text("(x,y,z,r00,r01,r02,r10,r11,r12,r20,r21,r22)"); - if (ImGui::MenuItem("Save all as csv (timestamp Lidar)")) + if (ImGui::MenuItem("Save all as csv (timestamp Lidar)##1")) { const auto output_file_name = mandeye::fd::SaveFileDialog(out_fn.c_str(), mandeye::fd::Csv_filter, ".csv"); std::cout << "csv file to save: '" << output_file_name << "'" << std::endl; @@ -2515,7 +2515,7 @@ void display() if (output_file_name.size() > 0) save_trajectories(session, output_file_name, tls_registration.curve_consecutive_distance_meters, tls_registration.not_curve_consecutive_distance_meters, tls_registration.is_trajectory_export_downsampling, true, false, false, false); } - if (ImGui::MenuItem("Save all as csv (timestamp Unix)")) + if (ImGui::MenuItem("Save all as csv (timestamp Unix)##1")) { const auto output_file_name = mandeye::fd::SaveFileDialog(out_fn.c_str(), mandeye::fd::Csv_filter, ".csv"); std::cout << "csv file to save: '" << output_file_name << "'" << std::endl; @@ -2523,7 +2523,7 @@ void display() if (output_file_name.size() > 0) save_trajectories(session, output_file_name, tls_registration.curve_consecutive_distance_meters, tls_registration.not_curve_consecutive_distance_meters, tls_registration.is_trajectory_export_downsampling, false, true, false, false); } - if (ImGui::MenuItem("Save all as csv (timestamp Lidar, Unix)")) + if (ImGui::MenuItem("Save all as csv (timestamp Lidar, Unix)##1")) { const auto output_file_name = mandeye::fd::SaveFileDialog(out_fn.c_str(), mandeye::fd::Csv_filter, ".csv"); std::cout << "csv file to save: '" << output_file_name << "'" << std::endl; @@ -2535,7 +2535,7 @@ void display() ImGui::Separator(); ImGui::Text("(x,y,z,qx,qy,qz,qw)"); - if (ImGui::MenuItem("Save all as csv (timestamp Lidar)")) + if (ImGui::MenuItem("Save all as csv (timestamp Lidar)##2")) { const auto output_file_name = mandeye::fd::SaveFileDialog(out_fn.c_str(), mandeye::fd::Csv_filter, ".csv"); std::cout << "csv file to save: '" << output_file_name << "'" << std::endl; @@ -2543,7 +2543,7 @@ void display() if (output_file_name.size() > 0) save_trajectories(session, output_file_name, tls_registration.curve_consecutive_distance_meters, tls_registration.not_curve_consecutive_distance_meters, tls_registration.is_trajectory_export_downsampling, true, false, true, false); } - if (ImGui::MenuItem("Save all as csv (timestamp Unix)")) + if (ImGui::MenuItem("Save all as csv (timestamp Unix)##2")) { const auto output_file_name = mandeye::fd::SaveFileDialog(out_fn.c_str(), mandeye::fd::Csv_filter, ".csv"); std::cout << "csv file to save: '" << output_file_name << "'" << std::endl; @@ -2551,7 +2551,7 @@ void display() if (output_file_name.size() > 0) save_trajectories(session, output_file_name, tls_registration.curve_consecutive_distance_meters, tls_registration.not_curve_consecutive_distance_meters, tls_registration.is_trajectory_export_downsampling, false, true, true, false); } - if (ImGui::MenuItem("Save all as csv (timestamp Lidar, Unix)")) + if (ImGui::MenuItem("Save all as csv (timestamp Lidar, Unix)##2")) { const auto output_file_name = mandeye::fd::SaveFileDialog(out_fn.c_str(), mandeye::fd::Csv_filter, ".csv"); std::cout << "csv file to save: '" << output_file_name << "'" << std::endl;