Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Ozaq committed Jan 23, 2024
1 parent 8bbd7a2 commit f8df809
Show file tree
Hide file tree
Showing 12 changed files with 405 additions and 62 deletions.
4 changes: 4 additions & 0 deletions jps-ui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ add_executable(jps-ui
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
Expand Down
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);
};
4 changes: 4 additions & 0 deletions jps-ui/src/gui.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// 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>
Expand Down Expand Up @@ -76,6 +78,8 @@ void Gui::Draw()
const auto wkt = read_wkt(filePath / filePathName);
if(wkt) {
geo = std::make_unique<DrawableGEOS>(wkt);
const Mesh m(geo->tri());
mesh = std::make_unique<RenderingMesh>(m);
should_recenter = true;
}
}
Expand Down
3 changes: 3 additions & 0 deletions jps-ui/src/gui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once

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

#include <imgui.h>
Expand All @@ -10,6 +11,7 @@ class Gui
{
private:
std::unique_ptr<DrawableGEOS> geo{nullptr};
std::unique_ptr<RenderingMesh> mesh{nullptr};
bool should_exit = false;
bool should_recenter = false;

Expand All @@ -21,4 +23,5 @@ class Gui
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(); }
};
11 changes: 3 additions & 8 deletions jps-ui/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,6 @@ static void glfw_error_callback(int error, const char* description)
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
}

struct Mesh {
std::vector<vec3> vertices{};
std::vector<GLint> indices{};
};

struct ApplicationState {
};

const std::string vertex_shader_code = R"(
#version 330 core
layout (location = 0) in vec2 inPos;
Expand Down Expand Up @@ -136,6 +128,9 @@ int main(int argc, char** argv)
if(gui.Geometry()) {
gui.Geometry()->Draw(shader);
}
if(gui.RMesh()) {
gui.RMesh()->Draw(shader);
}
gui.Draw();

if(gui.ShouldExit()) {
Expand Down
150 changes: 150 additions & 0 deletions jps-ui/src/mesh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "mesh.hpp"
#include "disjoint_set.hpp"
#include "wkt.hpp"

#include <CGAL/number_utils.h>

#include <_types/_uint16_t.h>
#include <algorithm>
#include <vector>

template <typename T>
T into(const Point& p)
{
return {CGAL::to_double(p.x()), CGAL::to_double(p.y())};
};

Mesh::Mesh(const CDT& cdt)
{
vertices.resize(cdt.finite_vertex_handles().size());
for(const auto& v : cdt.finite_vertex_handles()) {
vertices.at(v->info()) = into<glm::dvec2>(v->point());
}
polygons.reserve(cdt.finite_face_handles().size());

std::unordered_map<CDT::Face_handle, size_t> handle_map{};
std::vector<std::vector<CDT::Face_handle>> neighbor_face_handles{};
neighbor_face_handles.reserve(polygons.capacity());
for(const CDT::Face_handle& t : cdt.finite_face_handles()) {
if(!t->get_in_domain()) {
continue;
}
Polygon p{};
p.vertices.reserve(3);
p.vertices.push_back(t->vertex(0)->info());
p.vertices.push_back(t->vertex(1)->info());
p.vertices.push_back(t->vertex(2)->info());

polygons.push_back(p);
neighbor_face_handles.emplace_back();
for(int index = 0; index < 3; ++index) {
const auto& n = t->neighbor(index);
if(n->get_in_domain()) {
neighbor_face_handles.back().emplace_back(n);
}
}
handle_map[t] = polygons.size() - 1;
}
assert(polygons.size() == neighbor_face_handles.size());
for(size_t index = 0; index < polygons.size(); ++index) {
auto& p = polygons[index];
const auto& neighbors = neighbor_face_handles[index];
p.neighbors.reserve(neighbors.size());
for(const auto& n : neighbors) {
p.neighbors.emplace_back(handle_map.at(n));
}
}
};

void Mesh::MergeGreedy()
{
DisjointSet djs{polygons.size()};
// 1) Merge polygons with only one nieghbor, aka "dead-ends"
mergeDeadEnds(djs);
// 2) "Smart" merge remaining polygons
// 3) Validate correctness
}

void Mesh::mergeDeadEnds(DisjointSet& djs)
{
while(true) {
for(auto&& p : polygons) {
if(p.neighbors.size() != 1) {
continue;
}
}
}
}

void Mesh::smartMerge()
{
}

bool Mesh::isValid() const
{
return true;
}

std::vector<glm::vec2> Mesh::FVertices() const
{
std::vector<glm::vec2> f_vertices{};
f_vertices.reserve(vertices.size());
std::transform(
std::begin(vertices),
std::end(vertices),
std::back_inserter(f_vertices),
[](const auto& v) {
return glm::vec2{v.x, v.y};
});
return f_vertices;
}

std::vector<uint16_t> Mesh::TriangleIndices() const
{
std::vector<uint16_t> indices{};
indices.reserve(polygons.size() * 3);

for(const auto& p : polygons) {
const uint16_t first = p.vertices.front();
const auto count_indices = p.vertices.size();
for(size_t index = 2; index < count_indices; ++index) {
indices.push_back(first);
indices.push_back(p.vertices[index - 1]);
indices.push_back(p.vertices[index]);
}
}
return indices;
}

std::vector<uint16_t> Mesh::SegmentIndices() const
{
using segment = std::tuple<uint16_t, uint16_t>;
const auto make_segment = [](uint16_t a, uint16_t b) {
if(a < b) {
return std::make_tuple(a, b);
}
return std::make_tuple(b, a);
};

std::set<segment> segments{};

for(const auto& p : polygons) {
const auto vertex_count = p.vertices.size();
uint16_t a = p.vertices[vertex_count - 1];
for(size_t index = 0; index < vertex_count; ++index) {
uint16_t b = p.vertices[index];
segments.insert(make_segment(a, b));
a = b;
}
}

std::vector<uint16_t> indices{};
indices.reserve(segments.size() * 2);
for(const auto& s : segments) {
indices.emplace_back(std::get<0>(s));
indices.emplace_back(std::get<1>(s));
}
return indices;
}
44 changes: 44 additions & 0 deletions jps-ui/src/mesh.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once

#include "disjoint_set.hpp"
#include "wkt.hpp"

#include <glm/vec2.hpp>

#include <vector>

class Mesh
{
public:
struct Polygon {
/// Index into the vertices store of the Mesh
std::vector<size_t> vertices{};
/// Index into the polygon store of the Mesh
std::vector<size_t> neighbors{};
};

private:
/// All vertices in this Mesh
std::vector<glm::dvec2> vertices{};
/// All convex polygons in this Mesh in CCW orientation.
std::vector<Polygon> polygons{};

public:
Mesh(const CDT& cdt);
~Mesh() = default;
void MergeGreedy();
std::vector<glm::vec2> FVertices() const;
std::vector<uint16_t> TriangleIndices() const;
std::vector<uint16_t> SegmentIndices() const;

private:
Mesh(const Mesh& other) = delete;
void operator=(const Mesh& other) = delete;
Mesh(Mesh&& other) = delete;
void operator=(Mesh&& other) = delete;
void mergeDeadEnds(DisjointSet& djs);
void smartMerge();
bool isValid() const;
};
65 changes: 65 additions & 0 deletions jps-ui/src/rendering_mesh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "rendering_mesh.hpp"
#include "mesh.hpp"

RenderingMesh::RenderingMesh(const Mesh& data)
{
glGenVertexArrays(2, vaos);
glGenBuffers(3, buffer);

const auto vertices = data.FVertices();
const auto triangle_indices = data.TriangleIndices();
index_count[0] = triangle_indices.size();

glBindVertexArray(vaos[0]);
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
glBufferData(
GL_ARRAY_BUFFER,
vertices.size() * sizeof(decltype(vertices)::value_type),
reinterpret_cast<const GLvoid*>(vertices.data()),
GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), nullptr);
glEnableVertexAttribArray(0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer[1]);
glBufferData(
GL_ELEMENT_ARRAY_BUFFER,
index_count[0] * sizeof(decltype(triangle_indices)::value_type),
reinterpret_cast<const GLvoid*>(triangle_indices.data()),
GL_STATIC_DRAW);

const auto segment_indices = data.SegmentIndices();
index_count[1] = segment_indices.size();

glBindVertexArray(vaos[1]);
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), nullptr);
glEnableVertexAttribArray(0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer[2]);
glBufferData(
GL_ELEMENT_ARRAY_BUFFER,
index_count[1] * sizeof(decltype(segment_indices)::value_type),
reinterpret_cast<const GLvoid*>(segment_indices.data()),
GL_STATIC_DRAW);
}

RenderingMesh::~RenderingMesh()
{
glDeleteBuffers(3, buffer);
glDeleteBuffers(2, vaos);
}

void RenderingMesh::Draw(Shader& shader) const
{
shader.Activate();

shader.SetUniform("color", glm::vec4(0.0f, 0.0f, 0.75f, 1.0f));
glBindVertexArray(vaos[0]);
glDrawElements(GL_TRIANGLES, index_count[0], GL_UNSIGNED_SHORT, nullptr);

shader.SetUniform("color", glm::vec4(0.0f, 0.75f, 0.0f, 1.0f));
glBindVertexArray(vaos[1]);
glDrawElements(GL_LINES, index_count[1], GL_UNSIGNED_SHORT, nullptr);
}
Loading

0 comments on commit f8df809

Please sign in to comment.