diff --git a/Assignment_2_Execution.hpp b/Assignment_2_Execution.hpp index 1a25288..4b5eaf9 100644 --- a/Assignment_2_Execution.hpp +++ b/Assignment_2_Execution.hpp @@ -1,5 +1,8 @@ #pragma once + + + #include "DGL/DGL.hpp" #include "Cpp_Alias.hpp" @@ -11,20 +14,101 @@ namespace Execution inline namespace LibraryReferences { using DGL::HE_Model; + + using OMeshInterface::OMesh_HE; + } + + bool Float64_ApproxEqual(double _first, double _second) + { + //Implementation influenced by: https://floating-point-gui.de/errors/comparison/, https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ + + double firstAbs = fabsl(_first ), + secondAbs = fabsl(_second ), + diffAbs = fabsl(_first - _second) ; + + bool ExactlyEqual, + CloseToZero ; + + ExactlyEqual = (_first == _second ); + CloseToZero = (_first == 0 || _second == 0 || diffAbs < DBL_MIN); + + if (ExactlyEqual) //Handles infinites + { + return true; + } + else if (CloseToZero) //Close to zero + { + return (diffAbs < (DBL_EPSILON * DBL_EPSILON)); + } + else //Relative Error + { + return (diffAbs / fminl(firstAbs + secondAbs, DBL_MAX) < DBL_EPSILON); + } + } + + void VerifyMesh(string _filePathForMesh, int genus) + { + cout << "Verifying: " << _filePathForMesh << endl; + + OMesh_HE mesh; + + mesh.Load(_filePathForMesh); + + + // Euler Number: + + int eulerNumLeft = mesh.GetVerticies().size() + mesh.GetFaces().size() - mesh.GetEdges().size(); + + cout << "Left Side Value: " << eulerNumLeft << endl; + + int eulerNumRight = 2 - 2 * genus; + + cout << "Right Side Value: " << eulerNumRight << endl << endl; + + + // Gauss Curvatures: + + cout << "Calculating Discrete Gauss Curvatures..." << endl; + + double curvatureByVertex = mesh.GetGuassianCurvature_Discretely(); + + cout << "Curvature by Vertex: " << curvatureByVertex << endl; + + double curvatureByEuler = 2 * OMeshInterface::PI() * eulerNumRight; + + cout << "Curvature by Euler : " << curvatureByEuler << endl << endl; + + if (eulerNumRight == eulerNumLeft && Float64_ApproxEqual(curvatureByVertex, curvatureByEuler)) + { + cout << _filePathForMesh << " is valid." << endl << endl;; + } + else + { + cout << _filePathForMesh << " is invalid." << endl << endl;; + } } int Execute_Assignment2() { - cout << "Assignment 2:" << endl << endl; + cout << "Assignment 2: Mesh operations" << endl << endl; - HE_Model BlenderTorus("./Models/torus_Blender.obj"); + VerifyMesh("./Models/bunny.obj", 0); - BlenderTorus.Load(); + VerifyMesh("./Models/eight.obj", 2); - + VerifyMesh("./Models/gargoyle.obj", 0); + VerifyMesh("./Models/hand.obj", 1); + VerifyMesh("./Models/horse.obj", 0); + + VerifyMesh("./Models/sculpture.obj", 3); + + VerifyMesh("./Models/topology.obj", 13); + + VerifyMesh("./Models/torus.obj", 1); + return EXIT_SUCCESS; } } diff --git a/OMesh/OMeshInterface.hpp b/OMesh/OMeshInterface.hpp index 0fd1cc1..cd70875 100644 --- a/OMesh/OMeshInterface.hpp +++ b/OMesh/OMeshInterface.hpp @@ -1,5 +1,7 @@ #pragma once +#include + // DGL #include "DGL/DGL_Types.hpp" @@ -46,10 +48,14 @@ namespace OMeshInterface using FaceHandles = vector; using HalfEdgeHandles = vector; using VertHandles = vector; - } + using std::atan; + } - + double PI() + { + return std::atan(1) * 4; + } class OMesh_HE { @@ -88,7 +94,7 @@ namespace OMeshInterface GenerateVertexList (); GenerateVertexNormalList(); GenerateFaceNormalList (); - GenerateVertexEdgeList (); + GenerateEdgeList (); GenerateFaceList (); return; @@ -104,7 +110,7 @@ namespace OMeshInterface return vertNormals; } - const EdgeList& GetVertEdges() const + const EdgeList& GetEdges() const { return edges; } @@ -119,6 +125,62 @@ namespace OMeshInterface return faceNormals; } + const int GetGenus() const + { + + } + + + void GetInteriorAngle() + { + + } + + + const double GetGuassianCurvature_Discretely() + { + double result = 2 * PI(); + + using FAngleList = vector; + using AngleList = vector; + + AngleList vertAngleSumList; + + for (HE_Mesh::VertexIter vertElem = oMeshObj.vertices_begin(); vertElem != oMeshObj.vertices_end(); vertElem++) + { + using OutgoingEdgeIter = HE_Mesh::VertexOHalfedgeIter; + + FAngleList interiorAngles; + + double sumOfAngles = 0.0; + + for (OutgoingEdgeIter oEdgeElem = oMeshObj.voh_begin(*vertElem); oEdgeElem != oMeshObj.voh_end(*vertElem); oEdgeElem++) + { + /*OutgoingEdgeIter next = oEdgeElem; next++; + + if (next == oMeshObj.voh_end(*vertElem)) + { + continue; + }*/ + + float angle = oMeshObj.calc_sector_angle(*oEdgeElem); + + angle *= PI() / 180.0; // To Radians + + interiorAngles.push_back(angle); + + sumOfAngles += angle; + } + + vertAngleSumList.push_back(sumOfAngles); + + result -= sumOfAngles; + } + + return result; + } + + protected: void GenerateVertexList() @@ -161,11 +223,11 @@ namespace OMeshInterface } } - void GenerateVertexEdgeList() + void GenerateEdgeList() { using EdgeIter = HE_Mesh::EdgeIter; - for (EdgeIter element = oMeshObj.edges_begin(); element != oMeshObj.edges_begin(); element++) + for (EdgeIter element = oMeshObj.edges_begin(); element != oMeshObj.edges_end(); element++) { using OEdge = decltype(oMeshObj.edge(*element)); @@ -203,6 +265,10 @@ namespace OMeshInterface VertexList verticies ; VertexList vertNormals; VertexList faceNormals; + + HalfEdgeHandles LeftHandles ; + HalfEdgeHandles RightHandles; + EdgeList edges ; FaceList faces ; };