From c26652724f43dbb3baa79dbf61b66c3146d3acf7 Mon Sep 17 00:00:00 2001 From: Jean-Romain Date: Wed, 28 Aug 2024 09:35:37 -0400 Subject: [PATCH] Clean code --- R/RcppExports.R | 4 +- R/plot.R | 9 +- src/RcppExports.cpp | 9 +- src/camera.cpp | 203 +++++--------------------------- src/camera.h | 14 +-- src/drawer.cpp | 43 ++++--- src/drawer.h | 2 + src/lidRviewer.cpp | 277 +++++++++++++++++++++++++++++++++----------- src/sdlglutils.cpp | 3 +- 9 files changed, 279 insertions(+), 285 deletions(-) diff --git a/R/RcppExports.R b/R/RcppExports.R index 674c2a4..fbaead9 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -1,7 +1,7 @@ # Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 -viewer <- function(df, hnof) { - invisible(.Call(`_lidRviewer_viewer`, df, hnof)) +viewer <- function(df, detach, hnof) { + invisible(.Call(`_lidRviewer_viewer`, df, detach, hnof)) } diff --git a/R/plot.R b/R/plot.R index 53c4ca6..6445d27 100644 --- a/R/plot.R +++ b/R/plot.R @@ -14,7 +14,7 @@ #' #' @param x a point cloud with minimally 3 columns named X,Y,Z #' @param y Unused (inherited from R base) -#' @param ... unused +#' @param ... Support detach = TRUE #' @export #' @method plot LAS #' @importClassesFrom lidR LAS @@ -23,7 +23,9 @@ #' @md setMethod("plot", signature(x = "LAS", y = "missing"), function(x, y, ...) { - viewer(x@data, "") + p = list(...) + detach = isTRUE(p$detach) + viewer(x@data, detach, "") }) render = function(f) @@ -32,8 +34,7 @@ render = function(f) las = lidR::readLAS(x) hnof = paste0(substr(x, 1, nchar(x) - 3), "hno") f = if (file.exists(hnof)) hnof else x - print(f) - viewer(las@data, f) + viewer(las@data, FALSE, f) } diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index a79d492..4f8af47 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -11,19 +11,20 @@ Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); #endif // viewer -void viewer(DataFrame df, std::string hnof); -RcppExport SEXP _lidRviewer_viewer(SEXP dfSEXP, SEXP hnofSEXP) { +void viewer(DataFrame df, bool detach, std::string hnof); +RcppExport SEXP _lidRviewer_viewer(SEXP dfSEXP, SEXP detachSEXP, SEXP hnofSEXP) { BEGIN_RCPP Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< DataFrame >::type df(dfSEXP); + Rcpp::traits::input_parameter< bool >::type detach(detachSEXP); Rcpp::traits::input_parameter< std::string >::type hnof(hnofSEXP); - viewer(df, hnof); + viewer(df, detach, hnof); return R_NilValue; END_RCPP } static const R_CallMethodDef CallEntries[] = { - {"_lidRviewer_viewer", (DL_FUNC) &_lidRviewer_viewer, 2}, + {"_lidRviewer_viewer", (DL_FUNC) &_lidRviewer_viewer, 3}, {NULL, NULL, 0} }; diff --git a/src/camera.cpp b/src/camera.cpp index dfdb7f6..6d1b496 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -1,8 +1,5 @@ #include "camera.h" -#include "sdlglutils.h" -#include "Frustum.h" -#include #include #include @@ -139,97 +136,6 @@ static bool InvertMatrix(const GLfloat m[16], GLfloat invOut[16]) Camera::Camera() { - const char *hand1[] = - { - /* width height num_colors chars_per_pixel */ - " 16 16 3 1 ", - /* colors */ - "X c #000000", - ". c #ffffff", - " c None", - /* pixels */ - " XX ", - " XX X..XXX ", - " X..XX..X..X ", - " X..XX..X..X X ", - " X..X..X..XX.X", - " X..X..X..X..X", - " XX X.......X..X", - "X..XX..........X", - "X...X.........X ", - " X............X ", - " X...........X ", - " X..........X ", - " X.........X ", - " X.......X ", - " X......X ", - " X......X ", - "0,0" - }; - - const char *hand2[] = - { - /* width height num_colors chars_per_pixel */ - " 16 16 3 1 ", - /* colors */ - "X c #000000", - ". c #ffffff", - " c None", - /* pixels */ - " ", - " ", - " ", - " ", - " XX XX XX ", - " X..X..X..XX ", - " X........X.X ", - " X.........X ", - " XX.........X ", - " X...........X ", - " X...........X ", - " X..........X ", - " X.........X ", - " X.......X ", - " X......X ", - " X......X ", - "0,0" - }; - - const char *move[] = - { - /* width height num_colors chars_per_pixel */ - " 16 16 1 ", - /* colors */ - "X c #000000", - ". c #ffffff", - " c None", - /* pixels */ - " XX ", - " X..X ", - " X....X ", - " X......X ", - " X XX..XX X ", - " X.X X..X X.X ", - " X..XXX..XXX..X ", - "X..............X", - "X..............X", - " X..XXX..XXX..X ", - " X.X X..X X.X ", - " X XX..XX X ", - " X......X ", - " X....X ", - " X..X ", - " XX ", - "0,0" - }; - - _hand1 = cursorFromXPM(hand1); - _hand2 = cursorFromXPM(hand2); - _move = cursorFromXPM(move); - - SDL_SetCursor(_hand1); - holdleft = false; - holdright = false; angleY = 20; angleZ = -30; deltaX = 0; @@ -242,94 +148,43 @@ Camera::Camera() zoomSensivity = 30; } -void Camera::OnMouseMotion(const SDL_MouseMotionEvent & event) +void Camera::rotate(int xrel, int yrel) { - if (holdleft) // Rotate - { - //printf("Rotate\n"); - angleZ += event.xrel*rotateSensivity; - angleY += event.yrel*rotateSensivity; + angleZ += xrel*rotateSensivity; + angleY += yrel*rotateSensivity; - if (angleY > 90) - angleY = 90; - else if (angleY < -90) - angleY = -90; + if (angleY > 90) + angleY = 90; + else if (angleY < -90) + angleY = -90; - changed = true; - } - else if (holdright) // Pan - { - panSensivity = distance*0.01; - //printf("Pan\n"); - deltaX += event.xrel*panSensivity; - deltaY -= event.yrel*panSensivity; - changed = true; - } + changed = true; } -void Camera::OnMouseEvent(const SDL_MouseButtonEvent &event, const SDL_MouseWheelEvent &event_wheel) +void Camera::pan(int xrel, int yrel) { - //printf("Mouse event\n"); + panSensivity = distance*0.01; + deltaX += xrel*panSensivity; + deltaY -= yrel*panSensivity; + changed = true; +} - if (event.button == SDL_BUTTON_LEFT) - { - if ((holdleft) && (event.type == SDL_MOUSEBUTTONUP)) - { - holdleft = false; - SDL_SetCursor(_hand1); - } - else if ((!holdleft) && (event.type == SDL_MOUSEBUTTONDOWN)) - { - holdleft = true; - SDL_SetCursor(_hand2); - } - } - else if (event.button == SDL_BUTTON_RIGHT) +void Camera::zoom(int zrel) +{ + if (zrel > 0) { - if ((holdright) && (event.type == SDL_MOUSEBUTTONUP)) - { - holdright = false; - SDL_SetCursor(_hand1); - } - else if ((!holdright) && (event.type == SDL_MOUSEBUTTONDOWN)) - { - holdright = true; - SDL_SetCursor(_move); - } + distance += zoomSensivity; + panSensivity = distance * 0.001; + zoomSensivity = distance * 0.05; } - - // Handle mouse wheel event separately - if (event_wheel.type == SDL_MOUSEWHEEL) + else if (zrel < 0) { - //printf("Wheel even\n"); - - if (event_wheel.y > 0) - { - //printf("Wheel up\n"); - distance += zoomSensivity; - panSensivity = distance * 0.001; - zoomSensivity = distance * 0.05; - changed = true; - } - else if (event_wheel.y < 0) - { - //printf("Wheel down\n"); - distance -= zoomSensivity; - panSensivity = distance * 0.001; - zoomSensivity = distance * 0.05; - changed = true; - } + distance -= zoomSensivity; + panSensivity = distance * 0.001; + zoomSensivity = distance * 0.05; } -} -void Camera::OnKeyboard(const SDL_KeyboardEvent & event) -{ - if ((event.type == SDL_KEYDOWN)&&(event.keysym.sym == SDLK_HOME)) - { - angleY = 0; - angleZ = 0; - changed = true; - } + changed = true; } void Camera::setPanSensivity(double sensivity) @@ -360,13 +215,6 @@ void Camera::setDistance(double dist) distance = dist; } -Camera::~Camera() -{ - SDL_FreeCursor(_hand1); - SDL_FreeCursor(_hand2); - SDL_SetCursor(NULL); -} - void Camera::look() { glTranslated(deltaX, deltaY, 0.0); @@ -377,6 +225,7 @@ void Camera::look() frustum.CalculateFrustum(); + // Get the camera position GLfloat viewMatrix[16]; glGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix); diff --git a/src/camera.h b/src/camera.h index 47d9611..b5d028e 100644 --- a/src/camera.h +++ b/src/camera.h @@ -2,18 +2,15 @@ #define CAMERA_H #include "Frustum.h" -#include class Camera { public: Camera(); - ~Camera(); - - void OnMouseMotion(const SDL_MouseMotionEvent & event); - void OnMouseEvent(const SDL_MouseButtonEvent & event, const SDL_MouseWheelEvent & event_wheel); - void OnKeyboard(const SDL_KeyboardEvent & event); + void rotate(int xrel, int yrel); + void pan(int xrel, int yrel); + void zoom(int zrel); void look(); void setRotateSensivity(double sensivity); void setPanSensivity(double sensivity); @@ -36,11 +33,6 @@ class Camera double deltaX; double deltaY; double deltaZ; - bool holdleft; - bool holdright; - SDL_Cursor * _hand1; - SDL_Cursor * _hand2; - SDL_Cursor * _move; private: CFrustum frustum; diff --git a/src/drawer.cpp b/src/drawer.cpp index 1fa9c6e..777bc16 100644 --- a/src/drawer.cpp +++ b/src/drawer.cpp @@ -91,25 +91,7 @@ Drawer::Drawer(SDL_Window *window, DataFrame df, std::string hnof) zFar = 100000; fov = 70; - SDL_GetWindowSize(window, &width, &height); - - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(fov, (float)width/(float)height, zNear, zFar); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - glEnable(GL_POINT_SMOOTH); - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + init_viewport(); this->window = window; @@ -212,6 +194,29 @@ Drawer::Drawer(SDL_Window *window, DataFrame df, std::string hnof) draw(); } +void Drawer::init_viewport() +{ + SDL_GetWindowSize(window, &width, &height); + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(fov, (float)width/(float)height, zNear, zFar); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + glEnable(GL_POINT_SMOOTH); + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +} + void Drawer::setAttribute(Attribute x) { if (x == Attribute::RGB && df.containsElementNamed("R")) diff --git a/src/drawer.h b/src/drawer.h index 40a2a83..b406742 100644 --- a/src/drawer.h +++ b/src/drawer.h @@ -2,6 +2,7 @@ #define DRAWER_H #include +#include #include "Octree.h" #include "camera.h" @@ -36,6 +37,7 @@ class Drawer void compute_cell_visibility(); void query_rendered_point(); void traverse_and_collect(const Key& key, std::vector& visible_octants); + void init_viewport(); bool draw_index; uint32_t npoints; diff --git a/src/lidRviewer.cpp b/src/lidRviewer.cpp index a7e116e..f4dc6bd 100644 --- a/src/lidRviewer.cpp +++ b/src/lidRviewer.cpp @@ -6,10 +6,96 @@ #include #include "drawer.h" +#include "sdlglutils.h" + +const char *hand1[] = +{ + /* width height num_colors chars_per_pixel */ + " 16 16 3 1 ", + /* colors */ + "X c #000000", + ". c #ffffff", + " c None", + /* pixels */ + " XX ", + " XX X..XXX ", + " X..XX..X..X ", + " X..XX..X..X X ", + " X..X..X..XX.X", + " X..X..X..X..X", + " XX X.......X..X", + "X..XX..........X", + "X...X.........X ", + " X............X ", + " X...........X ", + " X..........X ", + " X.........X ", + " X.......X ", + " X......X ", + " X......X ", + "0,0" +}; + +const char *hand2[] = + { + /* width height num_colors chars_per_pixel */ + " 16 16 3 1 ", + /* colors */ + "X c #000000", + ". c #ffffff", + " c None", + /* pixels */ + " ", + " ", + " ", + " ", + " XX XX XX ", + " X..X..X..XX ", + " X........X.X ", + " X.........X ", + " XX.........X ", + " X...........X ", + " X...........X ", + " X..........X ", + " X.........X ", + " X.......X ", + " X......X ", + " X......X ", + "0,0" + }; + +const char *move[] = + { + /* width height num_colors chars_per_pixel */ + " 16 16 1 ", + /* colors */ + "X c #000000", + ". c #ffffff", + " c None", + /* pixels */ + " XX ", + " X..X ", + " X....X ", + " X......X ", + " X XX..XX X ", + " X.X X..X X.X ", + " X..XXX..XXX..X ", + "X..............X", + "X..............X", + " X..XXX..XXX..X ", + " X.X X..X X.X ", + " X XX..XX X ", + " X......X ", + " X....X ", + " X..X ", + " XX ", + "0,0" + }; + + const Uint32 time_per_frame = 1000 / 30; bool running = false; - std::thread sdl_thread; void sdl_loop(DataFrame df, std::string hnof) @@ -39,6 +125,11 @@ void sdl_loop(DataFrame df, std::string hnof) SDL_GLContext glContext = SDL_GL_CreateContext(window); SDL_GL_SetSwapInterval(1); // Enable VSync + SDL_Cursor* _hand1 = cursorFromXPM(hand1); + SDL_Cursor* _hand2 = cursorFromXPM(hand2); + SDL_Cursor* _move = cursorFromXPM(move); + SDL_SetCursor(_hand1); + Drawer *drawer = new Drawer(window, df, hnof); drawer->camera.setRotateSensivity(0.1); drawer->camera.setZoomSensivity(10); @@ -48,6 +139,8 @@ void sdl_loop(DataFrame df, std::string hnof) last_time = SDL_GetTicks(); bool ctrlPressed = false; + bool rotate = false; + bool pan = false; while (run) { @@ -55,80 +148,121 @@ void sdl_loop(DataFrame df, std::string hnof) { switch (event.type) { - case SDL_QUIT: - run = false; - break; - case SDL_KEYDOWN: - switch (event.key.keysym.sym) + case SDL_QUIT: { - case SDLK_LCTRL: - case SDLK_RCTRL: - ctrlPressed = true; - break; - case SDLK_ESCAPE: run = false; break; - case SDLK_z: - drawer->setAttribute(Attribute::Z); - break; - case SDLK_i: - drawer->setAttribute(Attribute::I); - break; - case SDLK_c: - drawer->setAttribute(Attribute::CLASS); + } + + case SDL_KEYDOWN: + { + switch (event.key.keysym.sym) + { + case SDLK_LCTRL: + case SDLK_RCTRL: + ctrlPressed = true; + break; + case SDLK_ESCAPE: + run = false; + break; + case SDLK_z: + drawer->setAttribute(Attribute::Z); + break; + case SDLK_i: + drawer->setAttribute(Attribute::I); + break; + case SDLK_c: + drawer->setAttribute(Attribute::CLASS); + break; + case SDLK_r: + case SDLK_g: + case SDLK_b: + drawer->setAttribute(Attribute::RGB); + break; + case SDLK_q: + drawer->display_hide_spatial_index(); + break; + case SDLK_l: + drawer->display_hide_edl(); + break; + case SDLK_PLUS: + case SDLK_KP_PLUS: + drawer->point_size_plus(); + break; + case SDLK_MINUS: + case SDLK_KP_MINUS: + drawer->point_size_minus(); + break; + break; + } break; - case SDLK_r: - case SDLK_g: - case SDLK_b: - drawer->setAttribute(Attribute::RGB); + } + + case SDL_KEYUP: + { + switch (event.key.keysym.sym) + { + case SDLK_LCTRL: + case SDLK_RCTRL: + ctrlPressed = false; + break; + } break; - case SDLK_q: - drawer->display_hide_spatial_index(); + } + + case SDL_MOUSEBUTTONUP: + { + switch(event.button.button) + { + case SDL_BUTTON_LEFT: + rotate = false; + SDL_SetCursor(_hand1); + break; + case SDL_BUTTON_RIGHT: + pan = false; + SDL_SetCursor(_hand1); + break; + } break; - case SDLK_l: - drawer->display_hide_edl(); + } + + case SDL_MOUSEBUTTONDOWN: + { + switch(event.button.button) + { + case SDL_BUTTON_LEFT: + rotate = true; + SDL_SetCursor(_hand2); + break; + case SDL_BUTTON_RIGHT: + pan = true; + SDL_SetCursor(_move); + break; + } break; - case SDLK_PLUS: - case SDLK_KP_PLUS: - drawer->point_size_plus(); + } + + case SDL_MOUSEMOTION: + { + if (pan) drawer->camera.pan(event.motion.xrel, event.motion.yrel); + if (rotate) drawer->camera.rotate(event.motion.xrel, event.motion.yrel); break; - case SDLK_MINUS: - case SDLK_KP_MINUS: - drawer->point_size_minus(); + } + + case SDL_MOUSEWHEEL: + { + if (ctrlPressed && event.wheel.y > 0) drawer->budget_plus(); + else if (ctrlPressed && event.wheel.y < 0) drawer->budget_minus(); + else drawer->camera.zoom(event.wheel.y); break; - default: - drawer->camera.OnKeyboard(event.key); - break; } - break; - case SDL_KEYUP: - { - switch (event.key.keysym.sym) + + case SDL_WINDOWEVENT: { - case SDLK_LCTRL: - case SDLK_RCTRL: - ctrlPressed = true; + drawer->resize(); break; } } - case SDL_MOUSEMOTION: - drawer->camera.OnMouseMotion(event.motion); - break; - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEBUTTONDOWN: - drawer->camera.OnMouseEvent(event.button, SDL_MouseWheelEvent{}); // Pass an empty SDL_MouseWheelEvent - break; - - case SDL_MOUSEWHEEL: - if (ctrlPressed && event.wheel.y > 0) drawer->budget_plus(); - else if (ctrlPressed && event.wheel.y < 0) drawer->budget_minus(); - else drawer->camera.OnMouseEvent(SDL_MouseButtonEvent{}, event.wheel); // Pass an empty SDL_MouseButtonEvent - break; - - case SDL_WINDOWEVENT: - drawer->resize(); - break; - } } current_time = SDL_GetTicks(); @@ -159,6 +293,10 @@ void sdl_loop(DataFrame df, std::string hnof) } delete drawer; + SDL_SetCursor(NULL); + SDL_FreeCursor(_hand1); + SDL_FreeCursor(_hand2); + SDL_FreeCursor(_move); SDL_GL_DeleteContext(glContext); SDL_DestroyWindow(window); SDL_Quit(); @@ -166,10 +304,17 @@ void sdl_loop(DataFrame df, std::string hnof) } // [[Rcpp::export]] -void viewer(DataFrame df, std::string hnof) +void viewer(DataFrame df, bool detach, std::string hnof) { - if (running) Rcpp::stop("lidRviewer is limited to one rendering point cloud"); - sdl_thread = std::thread(sdl_loop, df, hnof); - sdl_thread.detach(); // Detach the thread to allow it to run independently - running = true; + if (detach) + { + if (running) Rcpp::stop("lidRviewer is limited to one rendering point cloud"); + sdl_thread = std::thread(sdl_loop, df, hnof); + sdl_thread.detach(); // Detach the thread to allow it to run independently + running = true; + } + else + { + sdl_loop(df, hnof); + } } diff --git a/src/sdlglutils.cpp b/src/sdlglutils.cpp index 7f8da30..94b7a1e 100644 --- a/src/sdlglutils.cpp +++ b/src/sdlglutils.cpp @@ -1,6 +1,5 @@ #include "sdlglutils.h" -#include -#include + #include #include