Skip to content

Commit

Permalink
Start working on Routing Engine prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
schroedtert authored and Ozaq committed Feb 6, 2024
1 parent cf6107d commit c7ec7a1
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 0 deletions.
52 changes: 52 additions & 0 deletions jps-ui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,55 @@ target_compile_definitions(jps-ui PUBLIC
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
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()
22 changes: 22 additions & 0 deletions jps-ui/src/aabb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,25 @@ 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}};
}
5 changes: 5 additions & 0 deletions jps-ui/src/aabb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#pragma once

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

struct AABB {
glm::vec2 min;
Expand All @@ -12,4 +13,8 @@ struct AABB {
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);
59 changes: 59 additions & 0 deletions jps-ui/src/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ Mesh::Mesh(const CDT& cdt)
}
}
}

updateBoundingBoxes();
};

void Mesh::MergeGreedy()
Expand All @@ -78,6 +80,8 @@ void Mesh::MergeGreedy()
// 2) "Smart" merge remaining polygons
smartMerge(true);
// 3) Validate correctness

updateBoundingBoxes();
}

void Mesh::mergeDeadEnds(DisjointSet& djs)
Expand Down Expand Up @@ -460,3 +464,58 @@ std::vector<uint16_t> Mesh::SegmentIndices() const
}
return indices;
}

void Mesh::updateBoundingBoxes()
{
boundingBoxes.clear();
boundingBoxes.reserve(polygons.size());

std::transform(
std::begin(polygons),
std::end(polygons),
std::back_inserter(boundingBoxes),
[this](const auto& polygon) {
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& pIndex : polygon.vertices) {
const auto& p = vertices[pIndex];
xMin = std::min(xMin, static_cast<float>(p.x));
xMax = std::max(xMax, static_cast<float>(p.x));
yMin = std::min(yMin, static_cast<float>(p.y));
yMax = std::max(yMax, static_cast<float>(p.y));
}

return AABB{{xMin, yMin}, {xMax, yMax}};
});
}

size_t Mesh::FindContainingPolygon(const glm::vec2& p) const
{
for(size_t index = 0; index < polygons.size(); ++index) {
if(boundingBoxes[index].Contains(p) && polygonContains(index, p)) {
return index;
}
}

return Polygon::InvalidIndex;
}

bool Mesh::polygonContains(const size_t polygonIndex, glm::vec2 p) const
{
const auto& poly = polygons[polygonIndex];

for(size_t i = 0; i < poly.vertices.size(); ++i) {

const glm::vec2 diff = vertices[(i + 1) % poly.vertices.size()] - vertices[i];
const glm::vec2 xp = p - vertices[i];

const auto cp = glm::cross(glm::vec3(diff, 0), glm::vec3(xp, 0));
if(cp.z < 0.0) {
return false;
}
}
return true;
}
4 changes: 4 additions & 0 deletions jps-ui/src/mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Mesh
std::vector<glm::dvec2> vertices{};
/// All convex polygons in this Mesh in CCW orientation.
std::vector<Polygon> polygons{};
std::vector<AABB> boundingBoxes{};

public:
Mesh(const CDT& cdt);
Expand All @@ -35,6 +36,7 @@ class Mesh
std::vector<glm::vec2> FVertices() const;
std::vector<uint16_t> TriangleIndices() const;
std::vector<uint16_t> SegmentIndices() const;
size_t FindContainingPolygon(const glm::vec2& p) const;

private:
Mesh(const Mesh& other) = delete;
Expand All @@ -51,4 +53,6 @@ class Mesh
std::tuple<std::vector<size_t>, std::vector<size_t>>
mergedPolygon(size_t polygon_a_index, size_t polygon_b_index, size_t first_common_vertex_in_a);
double polygonArea(const std::vector<size_t> indices) const;
bool polygonContains(const size_t, glm::vec2 p) const;
void updateBoundingBoxes();
};
2 changes: 2 additions & 0 deletions jps-ui/src/routing_engine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
12 changes: 12 additions & 0 deletions jps-ui/src/routing_engine.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later

#include "mesh.hpp"

class RoutingEngine
{
Mesh mesh;

public:
explicit RoutingEngine(Mesh&& mesh_) :
}
28 changes: 28 additions & 0 deletions jps-ui/tests/mesh_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright © 2012-2023 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "mesh.hpp"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

class MeshFixture : ::testing::Test
{
const std::string geometry_wkt =
"GEOMETRYCOLLECTION (POLYGON ((10 5, 25 20, 25 25, 25 30, 30 30, 30 25, 30 20, 30 15, 30 "
"5, 30 "
"0, 25 0, 15 0, 10 0, 0 0, 0 5, 10 5), (25 5, 25 15, 15 5, 25 5)))";

Mesh mesh;

void SetUp()
{
auto geo = std::make_unique<DrawableGEOS>(wkt);
mesh(geo->tri());
mesh.MergeGreedy();
}
}

TEST_F(MeshFixture, SimpleContains)
{
ASSERT_TRUE(mesh.polygonContains())
}

0 comments on commit c7ec7a1

Please sign in to comment.