diff --git a/CMakeLists.txt b/CMakeLists.txt index c36ed2d..8ea4175 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,9 @@ find_package(TBB REQUIRED COMPONENTS TBB::tbb) find_package(Boost REQUIRED COMPONENTS filesystem system) +# cgal +find_package(CGAL REQUIRED COMPONENTS Core) + qt_add_executable(${AppExec} @@ -78,7 +81,7 @@ qt_add_executable(${AppExec} ${ENGINE_SOURCES} ) -target_link_libraries(${AppExec} PRIVATE Qt6::Core Qt6::Widgets Qt6::SvgWidgets Qt6::OpenGLWidgets glm::glm Eigen3::Eigen TBB::tbb Boost::filesystem Boost::system) +target_link_libraries(${AppExec} PRIVATE Qt6::Core Qt6::Widgets Qt6::SvgWidgets Qt6::OpenGLWidgets glm::glm Eigen3::Eigen TBB::tbb Boost::filesystem Boost::system CGAL::CGAL CGAL::CGAL_Core) target_include_directories(${AppExec} PUBLIC ${ENGINE_INCLUDE_DIRECTORIES} ) diff --git a/src/Engine/Operator/Geometry.cpp b/src/Engine/Operator/Geometry.cpp index 589153e..9aaf233 100644 --- a/src/Engine/Operator/Geometry.cpp +++ b/src/Engine/Operator/Geometry.cpp @@ -3,7 +3,9 @@ #include "Engine/Operator/AttributeHandle.h" #include "Engine/Types.h" #include +#include #include +#include "icecream.hpp" using namespace enzo; geo::Geometry::Geometry() @@ -13,6 +15,58 @@ geo::Geometry::Geometry() addIntAttribute(ga::AttrOwner::PRIMITIVE, "vertexCount"); } +enzo::geo::HeMesh geo::Geometry::computeHalfEdgeMesh() +{ + HeMesh heMesh; + + std::shared_ptr PAttr = getAttribByName(enzo::ga::AttrOwner::POINT, "P"); + enzo::ga::AttributeHandleVector3 PAttrHandle = enzo::ga::AttributeHandleVector3(PAttr); + auto pointPositions = PAttrHandle.getAllValues(); + + std::shared_ptr pointAttr = getAttribByName(enzo::ga::AttrOwner::VERTEX, "point"); + enzo::ga::AttributeHandleInt pointAttrHandle = enzo::ga::AttributeHandleInt(pointAttr); + auto vertexPointIndices = pointAttrHandle.getAllValues(); + + std::shared_ptr vertexCountAttr = getAttribByName(enzo::ga::AttrOwner::PRIMITIVE, "vertexCount"); + enzo::ga::AttributeHandleInt vertexCountHandle = enzo::ga::AttributeHandleInt(vertexCountAttr); + auto vertexCounts = vertexCountHandle.getAllValues(); + + int vertexIndex = 0; + std::vector createdPoints; + createdPoints.reserve(pointPositions.size()); + std::vector facePoints; + facePoints.reserve(16); + + for(auto pointPos : pointPositions) + { + enzo::geo::vertexDescriptor point = heMesh.add_vertex(geo::Point(pointPos.x(), pointPos.y(), pointPos.z())); + createdPoints.push_back(point); + } + + // iterate through each prim + for(int primIndx=0; primIndx geo::Geometry::addIntAttribute(ga::AttributeOwner owner, std::string name) { auto newAttribute = std::make_shared(name, ga::AttrType::intT); diff --git a/src/Engine/Operator/Geometry.h b/src/Engine/Operator/Geometry.h index 332865f..fedac46 100644 --- a/src/Engine/Operator/Geometry.h +++ b/src/Engine/Operator/Geometry.h @@ -1,10 +1,23 @@ #pragma once #include "Engine/Operator/Attribute.h" #include "Engine/Types.h" +#include +#include #include + + namespace enzo::geo { +using Kernel = CGAL::Simple_cartesian; +using Point = Kernel::Point_3; +using Vector = Kernel::Vector_3; +using HeMesh = CGAL::Surface_mesh; +using vertexDescriptor = HeMesh::Vertex_index; +using faceDescriptor = HeMesh::Face_index; +using V_index = HeMesh::Vertex_index; +using F_index = HeMesh::Face_index; + class Geometry { public: @@ -12,6 +25,8 @@ public: ga::AttributeHandle addIntAttribute(ga::AttributeOwner owner, std::string name); ga::AttributeHandle addVector3Attribute(ga::AttributeOwner owner, std::string name); std::shared_ptr getAttribByName(ga::AttributeOwner owner, std::string name); + std::vector derivePointNormals(); + HeMesh computeHalfEdgeMesh(); private: using attribVector = std::vector>; attribVector& getAttributeStore(ga::AttributeOwner& owner); diff --git a/src/Gui/Viewport/GLMesh.cpp b/src/Gui/Viewport/GLMesh.cpp index 3217d8e..f2ce9f4 100644 --- a/src/Gui/Viewport/GLMesh.cpp +++ b/src/Gui/Viewport/GLMesh.cpp @@ -2,6 +2,8 @@ #include #include #include "Engine/Operator/AttributeHandle.h" +#include "Engine/Operator/Geometry.h" +#include @@ -55,14 +57,34 @@ void GLMesh::setPosBuffer(enzo::geo::Geometry& geometry) glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); vertices.clear(); - std::shared_ptr PAttr = geometry.getAttribByName(enzo::ga::AttrOwner::POINT, "P"); - enzo::ga::AttributeHandleVector3 PAttrHandle = enzo::ga::AttributeHandleVector3(PAttr); - auto pointPositions = PAttrHandle.getAllValues(); + enzo::geo::HeMesh heMesh = geometry.computeHalfEdgeMesh(); - for(auto position : pointPositions) + // compute mesh normals + auto vnormals = heMesh.add_property_map("v:normals", CGAL::NULL_VECTOR).first; + auto fnormals = heMesh.add_property_map("f:normals", CGAL::NULL_VECTOR).first; + namespace PMP = CGAL::Polygon_mesh_processing; + + PMP::compute_normals( + heMesh, + vnormals, + fnormals, + PMP::parameters::vertex_point_map(heMesh.points()) + ); + + + for (enzo::geo::V_index v : heMesh.vertices()) { - vertices.push_back({{position.x(), position.y(), position.z()}, {position.x(), position.y(), position.z()}}); - std::cout << position.x() << " " << position.y() << " " << position.z() << "\n"; + const enzo::geo::Point &p = heMesh.point(v); + const enzo::geo::Vector &n = vnormals[v]; + + vertices.push_back({ + { p.x(), + p.y(), + p.z()}, + { n.x(), + n.y(), + n.z()} + }); } glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); diff --git a/src/Gui/Viewport/ViewportGLWidget.cpp b/src/Gui/Viewport/ViewportGLWidget.cpp index 9babe02..ac5db16 100644 --- a/src/Gui/Viewport/ViewportGLWidget.cpp +++ b/src/Gui/Viewport/ViewportGLWidget.cpp @@ -85,12 +85,21 @@ void ViewportGLWidget::initializeGL() #version 330 core in vec3 Normal; - out vec4 FragColor; + out vec4 color; + + float remap(float value, float inMin, float inMax, float outMin, float outMax) + { + return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin); + } void main() { // FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); - FragColor = vec4(Normal, 1.0f); + // FragColor = vec4(Normal, 1.0f); + vec3 lightDir = normalize(vec3(1.0,1.0,1.0)); + float brightness = remap(dot(Normal, lightDir), -1, 1, 0.5, 1); + color = vec4(vec3(brightness), 1.0f); + } )"; GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);