Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial commit of debug ui #1309

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Project setup
################################################################################
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(JuPedSim VERSION 1.1.0 LANGUAGES CXX)
project(JuPedSim VERSION 1.1.0 LANGUAGES CXX C)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
Expand Down Expand Up @@ -48,6 +48,8 @@ endif()
set(BUILD_BENCHMARKS OFF CACHE BOOL "Build micro benchmark")
print_var(BUILD_BENCHMARKS)

option(BUILD_JPS_UI "Build visualisation" OFF)

set(WITH_FORMAT OFF CACHE BOOL "Create format tools")
print_var(WITH_FORMAT)
if(WITH_FORMAT AND ${CMAKE_SYSTEM} MATCHES "Windows")
Expand Down Expand Up @@ -219,6 +221,9 @@ add_subdirectory(libjupedsim)
add_subdirectory(libcommon)
add_subdirectory(libsimulator)
add_subdirectory(python_bindings_jupedsim)
if(BUILD_JPS_UI)
add_subdirectory(jps-ui)
endif()

################################################################################
# Code formatting
Expand Down
90 changes: 90 additions & 0 deletions jps-ui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
add_executable(jps-ui
src/aabb.cpp
src/aabb.hpp
src/disjoint_set.cpp
src/disjoint_set.hpp
src/gui.cpp
src/gui.hpp
src/main.cpp
src/mesh.cpp
src/mesh.hpp
src/ortho_camera.cpp
src/ortho_camera.hpp
src/rendering_mesh.cpp
src/rendering_mesh.hpp
src/shader.cpp
src/shader.hpp
src/wkt.cpp
src/wkt.hpp
)

target_link_libraries(jps-ui
glfw
OpenGL::GL
GEOS::geos_c
CGAL::CGAL
imgui
imgui_filedialog
glm
glad
fmt
)

target_compile_definitions(jps-ui PUBLIC
GL_SILENCE_DEPRECATION
GLFW_INCLUDE_NONE
)

################################################################################
# jps-ui unit tests
################################################################################
if (BUILD_TESTS)
add_executable(jps-ui-tests
test/mesh_test.cpp
src/aabb.cpp
src/aabb.hpp
src/disjoint_set.cpp
src/disjoint_set.hpp
src/gui.cpp
src/gui.hpp
src/mesh.cpp
src/mesh.hpp
src/ortho_camera.cpp
src/ortho_camera.hpp
src/rendering_mesh.cpp
src/rendering_mesh.hpp
src/shader.cpp
src/shader.hpp
src/wkt.cpp
src/wkt.hpp

)

target_link_libraries(jps-ui-tests PRIVATE
GTest::gtest
GTest::gtest_main
GTest::gmock
glfw
OpenGL::GL
GEOS::geos_c
CGAL::CGAL
imgui
imgui_filedialog
glm
glad
fmt
)

target_compile_options(jps-ui-tests PRIVATE
${COMMON_COMPILE_OPTIONS}
)

# Also allow the unit test access to the non-public header files of jupedsim_obj
# This is required to construct some otherwise opqaue types in tests, e.g. ErrorMessage
target_include_directories(jps-ui-tests
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
)

set_property(TARGET jps-ui-tests PROPERTY INTERPROCEDURAL_OPTIMIZATION ${USE_IPO})
set_property(TARGET jps-ui-tests PROPERTY INTERPROCEDURAL_OPTIMIZATION_DEBUG OFF)
endif()
45 changes: 45 additions & 0 deletions jps-ui/src/aabb.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "aabb.hpp"

float AABB::Aspect() const
{
const auto diff = max - min;
return diff.x / diff.y;
}

float AABB::Width() const
{
return max.x - min.x;
}

float AABB::Height() const
{
return max.y - min.y;
}
glm::vec2 AABB::Center() const
{
return min + (max - min) / 2.0f;
}

bool AABB::Contains(const glm::vec2& p) const
{
return p.x >= min.x && p.x <= max.x && p.y >= min.y && p.y <= max.y;
}

AABB CreateFromPoints(const std::vector<glm::vec2>& points)
{
float xMin = std::numeric_limits<float>::max();
float xMax = std::numeric_limits<float>::lowest();
float yMin = std::numeric_limits<float>::max();
float yMax = std::numeric_limits<float>::lowest();

for(const auto& p : points) {
xMin = std::min(xMin, p.x);
xMax = std::max(xMax, p.x);
yMin = std::min(yMin, p.y);
yMax = std::max(yMax, p.y);
}

return AABB{{xMin, yMin}, {xMax, yMax}};
}
20 changes: 20 additions & 0 deletions jps-ui/src/aabb.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once

#include <glm/vec2.hpp>
#include <vector>

struct AABB {
glm::vec2 min;
glm::vec2 max;

float Aspect() const;
float Width() const;
float Height() const;
glm::vec2 Center() const;

bool Contains(const glm::vec2& point) const;
};

AABB CreateFromPoints(const std::vector<glm::vec2>& points);
30 changes: 30 additions & 0 deletions jps-ui/src/disjoint_set.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "disjoint_set.hpp"

#include <cassert>
#include <numeric>
#include <stdexcept>

DisjointSet::DisjointSet(size_t count_elements) : parent(count_elements)
{
std::iota(std::begin(parent), std::end(parent), 0);
}

size_t DisjointSet::Find(size_t id)
{
if(id >= parent.size()) {
throw std::runtime_error("Unknown id");
};
if(parent[id] != id) {
parent[id] = Find(id);
}
return parent[id];
}

void DisjointSet::Union(size_t id_a, size_t id_b)
{
const auto a = Find(id_a);
const auto b = Find(id_b);
parent[b] = a;
}
17 changes: 17 additions & 0 deletions jps-ui/src/disjoint_set.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once

#include <cstddef>
#include <vector>

class DisjointSet
{
std::vector<size_t> parent{};

public:
DisjointSet(size_t count_elements);
~DisjointSet() = default;
size_t Find(size_t id);
void Union(size_t id_a, size_t id_b);
};
91 changes: 91 additions & 0 deletions jps-ui/src/gui.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "gui.hpp"
#include "mesh.hpp"
#include "rendering_mesh.hpp"
#include "wkt.hpp"

#include <imgui_internal.h>

#include <ImGuiFileDialog.h>
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>

#include <filesystem>
#include <memory>

std::string to_shortcut(const ImGuiKeyChord key)
{
std::array<char, 32> shortcut{};
ImGui::GetKeyChordName(key, shortcut.data(), shortcut.size());
return {shortcut.data()};
}

void Gui::Draw()
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();

should_recenter = false;

if(ImGui::BeginMainMenuBar()) {
if(ImGui::BeginMenu("Menu")) {
static const auto open_shortcut = to_shortcut(ImGuiMod_Shortcut | ImGuiKey_O);
if(ImGui::MenuItem("Open", open_shortcut.c_str())) {
ImGuiFileDialog::Instance()->OpenDialog(
"ChooseFileDlgKey",
"Choose File",
".wkt",
".",
1,
nullptr,
ImGuiFileDialogFlags_Modal);
}
if(ImGui::MenuItem("Center View", "C")) {
should_recenter = true;
}
ImGui::Separator();
static const auto exit_shortcut = to_shortcut(ImGuiMod_Shortcut | ImGuiKey_Q);
if(ImGui::MenuItem("Exit", exit_shortcut.c_str())) {
should_exit = true;
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}

if(ImGui::IsKeyChordPressed(ImGuiMod_Shortcut | ImGuiKey_O)) {
ImGuiFileDialog::Instance()->OpenDialog(
"ChooseFileDlgKey", "Choose File", ".wkt", ".", 1, nullptr, ImGuiFileDialogFlags_Modal);
}

if(ImGui::IsKeyChordPressed(ImGuiMod_Shortcut | ImGuiKey_Q)) {
should_exit = true;
}

if(ImGui::IsKeyChordPressed(ImGuiKey_C)) {
should_recenter = true;
}

if(ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey")) {
if(ImGuiFileDialog::Instance()->IsOk()) {
std::filesystem::path filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
std::filesystem::path filePath = ImGuiFileDialog::Instance()->GetCurrentPath();

const auto wkt = read_wkt(filePath / filePathName);
if(wkt) {
geo = std::make_unique<DrawableGEOS>(wkt);
Mesh m(geo->tri());
m.MergeGreedy();
mesh = std::make_unique<RenderingMesh>(m);
should_recenter = true;
}
}
ImGuiFileDialog::Instance()->Close();
}

ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
27 changes: 27 additions & 0 deletions jps-ui/src/gui.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once

#include "rendering_mesh.hpp"
#include "wkt.hpp"

#include <imgui.h>

class Gui
{
private:
std::unique_ptr<DrawableGEOS> geo{nullptr};
std::unique_ptr<RenderingMesh> mesh{nullptr};
bool should_exit = false;
bool should_recenter = false;

public:
Gui() = default;
~Gui() = default;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
void Draw();
bool ShouldExit() const { return should_exit; }
bool RecenterOnGeometry() const { return should_recenter; }
const DrawableGEOS* Geometry() const { return geo.get(); }
const RenderingMesh* RMesh() const { return mesh.get(); }
};
Loading
Loading