mesh and subclass structures

This commit is contained in:
L-Nafaryus 2022-11-04 18:38:39 +05:00
parent cb07c61b7f
commit 3be9178126
27 changed files with 521 additions and 44 deletions

View File

@ -1,13 +1,15 @@
cmake_minimum_required (VERSION 3.16)
include(${CMAKE_SOURCE_DIR}/cmake/glad.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/imgui.cmake)
project(
hyporo
VERSION 0.20.0
LANGUAGES CXX
)
option(WITH_GTESTS "Enable GTest unit testing" ON)
enable_testing()
@ -18,8 +20,6 @@ if(WITH_GTESTS)
endif()
include(${CMAKE_SOURCE_DIR}/cmake/glad.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/imgui.cmake)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")

View File

@ -3,4 +3,4 @@ add_subdirectory(gpu)
add_subdirectory(hmesh)
add_subdirectory(hyplib)
add_subdirectory(io)
add_subdirectory(windowmanager)
add_subdirectory(window_system)

View File

@ -5,49 +5,36 @@ include_directories(
add_library(hyporo-gpu STATIC
# Source files
window_system.cpp
monitor.cpp
buffer.cpp
context.cpp
shader.cpp
window.cpp
device.cpp
opengl/buffer.cpp
opengl/context.cpp
opengl/device.cpp
opengl/shader.cpp
opengl/texture.cpp
#opengl/device.cpp
opengl/shader_program.cpp
texture.cpp
#device.cpp
glfw/window_system.cpp
glfw/monitor.cpp
glfw/window.cpp
opengl/texture.cpp
shader.cpp
shader_program.cpp
texture.cpp
# Header files
monitor.hpp
context.hpp
shader.hpp
window_context.hpp
shader_program.hpp
buffer.hpp
#device.hpp
window.hpp
device.hpp
texture.hpp
opengl/context.hpp
opengl/shader.hpp
opengl/shader_program.hpp
opengl/buffer.hpp
#opengl/device.hpp
opengl/device.hpp
opengl/texture.hpp
window_system.hpp
glfw/monitor.hpp
glfw/window.hpp
glfw/window_system.hpp
)
target_link_libraries(hyporo-gpu
glad
glfw
hyporo-hyplib
)

View File

@ -9,14 +9,10 @@ include_directories(
add_library(hyporo-hmesh STATIC
# Header files
Vertex.hpp
Edge.hpp
Face.hpp
Cell.hpp
Mesh.hpp
mesh.hpp
# Source files
Mesh.cpp
mesh.cpp
)
if(WITH_GTESTS)

View File

@ -0,0 +1 @@
#include "mesh.hpp"

View File

@ -0,0 +1,330 @@
#pragma once
#include "../hyplib/scalar/scalar.hpp"
#include "../hyplib/array/array.hpp"
#include "../hyplib/vector/vector.hpp"
#include <memory>
#include <vector>
namespace hpr::mesh
{
class Edge;
class Vertex : public vec<scalar, 3>
{
friend class Mesh;
using base = vec<scalar, 3>;
protected:
darray<Edge*> p_refEdges;
public:
Vertex() :
base {}
{}
Vertex(const scalar& x, const scalar& y, const scalar& z) :
base {x, y, z}
{}
virtual
~Vertex()
{
for (auto& e : p_refEdges)
delete e;
}
darray<Edge*>& refEdges()
{
return p_refEdges;
}
void addRefEdge(Edge* edge)
{
p_refEdges.push(edge);
}
};
class Face;
class Edge : public sarray<Vertex*, 2>
{
friend class Mesh;
using vertex_pointer = Vertex*;
using base = sarray<vertex_pointer, 2>;
protected:
darray<Face*> p_refFaces;
public:
Edge() :
base {}
{}
Edge(vertex_pointer v1, vertex_pointer v2) :
base {v1, v2}
{}
virtual
~Edge()
{
for (auto& f : p_refFaces)
delete f;
}
darray<Face*>& refFaces()
{
return p_refFaces;
}
void addRefFace(Face* face)
{
p_refFaces.push(face);
}
sarray<vertex_pointer, 2>& vertices()
{
return *this;
}
vertex_pointer vertex(size_type n)
{
return (*this)[n];
}
};
class Cell;
class Face : public darray<Edge*>
{
friend class Mesh;
using edge_pointer = Edge*;
using vertex_pointer = Vertex*;
using base = darray<edge_pointer>;
protected:
darray<Cell*> p_refCells;
public:
Face() :
base {}
{}
Face(std::initializer_list<edge_pointer> edges) :
base {edges}
{}
virtual
~Face()
{
for (auto& c : p_refCells)
delete c;
}
darray<Cell*>& refCells()
{
return p_refCells;
}
void addRefCell(Cell* cell)
{
p_refCells.push(cell);
}
darray<edge_pointer>& edges()
{
return *this;
}
edge_pointer edge(size_type n)
{
return (*this)[n];
}
darray<vertex_pointer> vertices()
{
darray<vertex_pointer> vertices_ {size(), nullptr};
for (auto n = 0; n < size(); ++n)
vertices_[n] = edge(n)->vertex(0);
return vertices_;
}
};
class Cell : public darray<Face*>
{
using face_pointer = Face*;
using base = darray<face_pointer>;
public:
Cell(std::initializer_list<face_pointer> faces) :
base {faces}
{}
};
class Mesh
{
#include "vertex.hpp"
public:
using size_type = std::size_t;
using vertex_pointer = Vertex*;
using edge_pointer = Edge*;
using face_pointer = Face*;
using cell_pointer = Cell*;
protected:
darray<Vertex*> p_vertices;
darray<Edge*> p_edges;
darray<Face*> p_faces;
darray<Cell*> p_cells;
public:
Mesh() = default;
Mesh(const Mesh&) = default;
~Mesh()
{
for (auto& v : p_vertices)
delete v;
for (auto& e : p_edges)
delete e;
for (auto& f : p_faces)
delete f;
for (auto& c : p_cells)
delete c;
}
int indexOf(vertex_pointer v)
{
for (int n = 0; n < vertices().size(); ++n)
if (vertex(n) == v)
return n;
return -1;
}
int indexOf(edge_pointer e)
{
for (int n = 0; n < edges().size(); ++n)
if (edge(n) == e)
return n;
return -1;
}
int indexOf(face_pointer e)
{
for (int n = 0; n < faces().size(); ++n)
if (face(n) == e)
return n;
return -1;
}
int indexOf(cell_pointer e)
{
for (int n = 0; n < cells().size(); ++n)
if (cell(n) == e)
return n;
return -1;
}
darray<Vertex*>& vertices()
{
return p_vertices;
}
[[nodiscard]]
vertex_pointer vertex(size_type n) const
{
return p_vertices[n];
}
void addVertex(const scalar& x, const scalar& y, const scalar& z)
{
p_vertices.push(new Vertex(x, y, z));
}
void removeNullVertices()
{
vertices().remove([](vertex_pointer vertex){ return vertex == nullptr; });
}
void removeVertex(size_type n, bool erase = true, bool cascade = true)
{
if (cascade)
{
for (auto &refEdge: vertex(n)->refEdges())
removeEdge(indexOf(refEdge), false);
removeNullEdges();
}
delete vertex(n);
if (erase)
vertices().remove(n);
}
darray<Edge*>& edges()
{
return p_edges;
}
[[nodiscard]]
edge_pointer edge(size_type n) const
{
return p_edges[n];
}
void addEdge(vertex_pointer v1, vertex_pointer v2)
{
edges().push(new Edge {v1, v2});
v1->addRefEdge(edges().back());
v2->addRefEdge(edges().back());
}
void removeNullEdges()
{
edges().remove([](edge_pointer edge){ return edge == nullptr; });
}
void removeEdge(size_type n, bool erase = true, bool cascade = true)
{
if (cascade)
{
for (auto &refFace: edge(n)->refFaces())
removeFace(indexOf(refFace), false);
removeNullFaces();
}
delete edge(n);
if (erase)
edges().remove(n);
}
darray<Face*>& faces()
{
return p_faces;
}
[[nodiscard]]
face_pointer face(size_type n) const
{
return p_faces[n];
}
template <std::convertible_to<edge_pointer>... Edges>
void addFace(const Edges& ...edges)
{
faces().push(new Face {static_cast<edge_pointer>(edges)...});
for (auto& edge : *faces().back())
edge->addRefFace(faces().back());
}
void removeNullFaces()
{
faces().remove([](face_pointer face){ return face == nullptr; });
}
void removeFace(size_type n, bool erase = true, bool cascade = true)
{
if (cascade)
{
for (auto &refCell: face(n)->refCells())
removeCell(indexOf(refCell), false);
removeNullFaces();
}
delete face(n);
if (erase)
faces().remove(n);
}
darray<Cell*>& cells()
{
return p_cells;
}
[[nodiscard]]
cell_pointer cell(size_type n) const
{
return p_cells[n];
}
void removeNullCells()
{
cells().remove([](cell_pointer cell){ return cell == nullptr; });
}
void removeCell(size_type n, bool erase = true, bool cascade = true)
{
static_cast<void>(cascade);
delete cell(n);
if (erase)
cells().remove(n);
}
};
}

View File

@ -1,6 +1,10 @@
#include <gtest/gtest.h>
#include "Mesh.hpp"
#include "../mesh.hpp"
TEST(hmeshTest, MeshCreation)
TEST(hmeshTest, Mesh)
{
hpr::mesh::Mesh mesh;
mesh.addVertex(1, 2, 3);
mesh.addVertex(1, 3, 3);
mesh.addEdge(mesh.vertex(0), mesh.vertex(1));
}

View File

@ -2,6 +2,9 @@
#include "iterator.hpp"
#include <limits>
#include <memory>
#include <functional>
namespace hpr
{
@ -71,6 +74,31 @@ public:
std::copy(list.begin(), list.end(), p_start);
}
inline
DynamicArray(size_type size, value_type value) :
p_size {size},
p_capacity {size},
p_start {new value_type[p_capacity]},
p_end {p_start + p_size},
p_storage_end {p_start + p_capacity}
{
for (auto n = 0; n < p_size; ++n)
*(p_start + n) = value;
}
inline
DynamicArray& operator=(const DynamicArray& vs) noexcept
{
delete[] p_start;
p_size = vs.p_size;
p_capacity = vs.p_size;
p_start = new value_type[p_capacity];
p_end = p_start + p_size;
p_storage_end = p_start + p_capacity;
std::copy(vs.begin(), vs.end(), begin());
return *this;
}
inline
DynamicArray& operator=(DynamicArray&& arr) noexcept
{
@ -255,16 +283,19 @@ public:
++p_end;
}
virtual
/*virtual
int findByAddress(const value_type& value)
{
// TODO: make better approach
for (int n = 0; n < p_size; ++n) {
if (*std::addressof(*(p_start + n)) == *std::addressof(value))
std::equal_to
pointer lhs = (p_start + n); //*std::addressof(*(p_start + n));
pointer rhs = *value; //*std::addressof(value);
if (lhs == rhs)
return n;
}
return -1;
}
}*/
virtual
void remove(size_type position)
@ -277,6 +308,31 @@ public:
}
virtual
void remove(iterator position)
{
if (position + 1 != end())
std::copy(position + 1, end(), position);
std::destroy_at(p_end);
--p_end;
--p_size;
}
virtual
void remove(const std::function<bool(value_type)>& condition)
{
size_type newSize = p_size;
for (size_type offset = 0; offset < newSize; ++offset)
if (condition(*(p_start + offset))) {
for (size_type n = offset; n < newSize; ++n) {
*(p_start + n) = std::move(*(p_start + n + 1));
}
--newSize;
--offset;
}
p_size = newSize;
p_end = p_start + p_size;
}
/*virtual
void remove(const value_type& value)
{
int index = findByAddress(value);
@ -284,6 +340,17 @@ public:
remove(index);
else
throw std::runtime_error("Value is not found to remove it");
}*/
virtual
void clear()
{
delete[] p_start;
p_size = 0;
p_capacity = 1;
p_start = new value_type[p_capacity];
p_end = p_start;
p_storage_end = p_end + p_capacity;
}
// Friend functions
@ -297,6 +364,15 @@ public:
std::swap(lhs.p_end, rhs.p_end);
std::swap(lhs.p_storage_end, rhs.p_storage_end);
}
friend
bool operator==(const DynamicArray& lhs, const DynamicArray& rhs)
{
for (auto n = 0; n < lhs.size(); ++n)
if (lhs[n] != rhs[n])
return false;
return true;
}
};
}

View File

@ -72,12 +72,21 @@ public:
return temp;
}
friend bool operator==(const iterator& lhs, const iterator& rhs)
iterator operator+(int value)
{
iterator temp {*this};
temp.p_ptr += value;
return temp;
}
friend
bool operator==(const iterator& lhs, const iterator& rhs)
{
return lhs.p_ptr == rhs.p_ptr;
}
friend bool operator!=(const iterator& lhs, const iterator& rhs)
friend
bool operator!=(const iterator& lhs, const iterator& rhs)
{
return lhs.p_ptr != rhs.p_ptr;
}

View File

@ -89,10 +89,20 @@ public:
StaticArray {list.begin(), list.end()}
{}
template <std::convertible_to<value_type>... Args>
inline
StaticArray(const value_type& v, const Args& ...args) :
StaticArray {std::initializer_list<value_type>({std::forward<value_type>(v),
std::forward<value_type>(static_cast<value_type>(args))...})}
{
static_assert(1 + sizeof...(args) == Size, "Number of arguments must be equal to size of array");
}
template <std::convertible_to<value_type>... Args>
inline
StaticArray(value_type&& v, Args&& ...args) :
StaticArray {std::initializer_list<value_type>({v, static_cast<value_type>(args)...})}
StaticArray {std::initializer_list<value_type>({std::forward<value_type>(v),
std::forward<value_type>(static_cast<value_type>(args))...})}
{
static_assert(1 + sizeof...(args) == Size, "Number of arguments must be equal to size of array");
}
@ -113,6 +123,13 @@ public:
(*this)[pos++] = val;
}
inline
StaticArray& operator=(const StaticArray& vs) noexcept
{
std::copy(vs.begin(), vs.end(), begin());
return *this;
}
inline
StaticArray& operator=(StaticArray&& arr) noexcept
{

View File

@ -13,6 +13,24 @@ TEST(hyplib, Array)
EXPECT_EQ(sarr, sarr2);
}
TEST(hyplib, DynamicArray)
{
hpr::DynamicArray<float> arr {1, 3, 2};
hpr::DynamicArray<float> arr2 {1, 3, 2};
EXPECT_EQ(arr, arr2);
arr.remove(1);
EXPECT_EQ(arr, hpr::darray<float>({1, 2}));
auto iter = arr2.begin();
++iter;
arr2.remove(iter);
EXPECT_EQ(arr2, hpr::darray<float>({1, 2}));
hpr::DynamicArray<float> arr3 {1, 3, 0, 2, 9, 0, 5};
arr3.remove([](float num) { return num == 0; });
EXPECT_EQ(arr3, hpr::darray<float>({1, 3, 2, 9, 5}));
EXPECT_EQ(arr3.size(), 5);
}
TEST(hyplib, Vector)
{
hpr::vec3 v1 {1, 3, 2};

View File

@ -36,9 +36,22 @@ public:
inline
VectorSpace(VectorSpace&& vs) noexcept :
base {std::move(static_cast<base>(vs))}
base {std::forward<base>(static_cast<base>(vs))}
{}
inline
VectorSpace& operator=(const VectorSpace& vs) noexcept = default;
inline
VectorSpace& operator=(VectorSpace&& vs) noexcept
{
std::swap(*this, vs);
return *this;
}
virtual
~VectorSpace() = default;
inline
VectorSpace(typename base::iterator start, typename base::iterator end) :
base {start, end}
@ -75,7 +88,7 @@ public:
{
for (auto n = 0; n < subvs.size(); ++n)
(*this)[n] = subvs[n];
(*this)[subvs.size() - 1] = v;
(*this)[subvs.size()] = v;
}
// Member functions
@ -123,10 +136,8 @@ public:
v /= val;
}
using type = VectorSpace<Type, Size>;
friend inline
type operator+(const VectorSpace& lhs, const value_type& rhs)
VectorSpace operator+(const VectorSpace& lhs, const value_type& rhs)
{
VectorSpace vs {lhs};
vs += rhs;

View File

@ -0,0 +1,28 @@
include_directories(
../hyplib
)
add_library(hyporo-window-system STATIC
# Source files
window_system.cpp
monitor.cpp
window.cpp
glfw/window_system.cpp
glfw/monitor.cpp
glfw/window.cpp
# Header files
monitor.hpp
window_context.hpp
window.hpp
window_system.hpp
glfw/monitor.hpp
glfw/window.hpp
glfw/window_system.hpp
)
target_link_libraries(hyporo-window-system
glfw
hyporo-hyplib
)