Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Model-Modifier/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ set(Source_Files
"src/scene/surface/Surface.cpp"
"src/scene/surface/Surface_CatmullClark.cpp"
"src/scene/surface/Surface_DooSabin.cpp"
"src/scene/surface/Surface_GarlandHeckbert.cpp"
"src/scene/surface/Surface_Loop.cpp"
"src/scene/util/OrderVertices.cpp"
"src/scene/util/PlaneProjection.cpp"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 17 additions & 11 deletions Model-Modifier/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ int main()
Object obj = objects.findObj(currObject);
Material meshMat;

// object triangle count (QEM)
int triCount = static_cast<int>(obj.m_TriFaceIndices.size());
int desiredTriCount = triCount;

VertexBufferLayout layout;
layout.Push<float>(3); // 3d coordinates
layout.Push<float>(3); // normals
Expand Down Expand Up @@ -366,17 +370,17 @@ int main()
obj = Lo.Loop();
ModifyModel = true;
}
//if (ImGui::Button("Garland Heckbert Simplication Surface"))
//{
// Surface GH(obj);
// obj = GH.QEM();
// mesh.Rebuild(obj); // rebuild mesh based on object info
// numFaces = static_cast<unsigned int>(mesh.m_Object.m_FaceIndices.size()); // update number of faces

// objectVA.Bind();
// objectVB.AssignData(mesh.m_OutVertices, mesh.m_OutNumVert * sizeof(float), DRAW_MODE::STATIC);
// objectIB.AssignData(mesh.m_OutIndices, mesh.m_OutNumIdx, DRAW_MODE::STATIC);
//}
if (ImGui::Button("Garland Heckbert Simplification Surface"))
{
obj.MakeTriangleMesh(); // Triangulate first
Surface GH(obj);
obj = GH.QEM(desiredTriCount);
ModifyModel = true;
}
ImGui::Indent();
ImGui::SliderInt("Desired count", &desiredTriCount, triCount/5, triCount);
ImGui::Unindent();

ImGui::Unindent();
}

Expand Down Expand Up @@ -626,6 +630,7 @@ int main()
currObject = nextObject;

obj = objects.findObj(currObject); // search for the object requested
triCount = static_cast<int>(obj.m_TriFaceIndices.size()); desiredTriCount = triCount;

ModifyModel = true;
}
Expand All @@ -635,6 +640,7 @@ int main()
{
mesh.Rebuild(obj); // rebuild mesh based on object info
numFaces = static_cast<unsigned int>(mesh.m_Object.m_FaceIndices.size()); // update number of faces
triCount = static_cast<int>(obj.m_TriFaceIndices.size()); desiredTriCount = triCount;

objectVA.Bind();
objectVB.AssignData(mesh.m_OutVertices, mesh.m_OutNumVert * sizeof(float), DRAW_MODE::STATIC);
Expand Down
18 changes: 0 additions & 18 deletions Model-Modifier/src/scene/surface/Surface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,21 +137,3 @@ glm::vec3 Surface::ComputeFaceNormal(glm::vec3 pos0, glm::vec3 pos1, glm::vec3 p
{
return glm::normalize(glm::cross(pos1 - pos0, pos2 - pos0));
}

// computer quadric matrix by summing all K_p matrices of a vertice v0
glm::mat4 Surface::ComputeQuadric(VertexRecord v0)
{
glm::mat4 quadric{ 0.0f };
// for each neighbouring face, compute K_p
glm::vec3 position = v0.position;
for (unsigned int faceIdx : v0.adjFacesIdx)
{
FaceRecord face = m_Faces[faceIdx];
glm::vec3 faceNormal = ComputeFaceNormal(face);
glm::vec4 plane{ faceNormal, -glm::dot(faceNormal, position) }; // plane equation ax+by+cz+d = 0

quadric += glm::outerProduct(plane, plane); // K_p
}

return quadric;
}
27 changes: 26 additions & 1 deletion Model-Modifier/src/scene/surface/Surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <set>
#include <vector>
#include <unordered_map>
#include <queue>

#include "../../external/glm/ext/vector_float3.hpp"
#include "../../external/glm/ext/vector_uint2.hpp"
Expand Down Expand Up @@ -37,6 +38,24 @@ struct FaceRecord
std::vector<unsigned int> edgesIdx; // each face can have n edges
};

// QEM
struct ValidPair
{
unsigned int vertOne;
unsigned int vertTwo;
bool edge;
float error;
glm::vec3 newVert;
};

struct CompareValidPairs
{
bool operator()(const ValidPair& a, const ValidPair& b) const
{
return a.error > b.error; // min heap
}
};

class Surface
{
public:
Expand All @@ -62,14 +81,18 @@ class Surface
);
Object LoOutputOBJ(std::vector<glm::vec3> edgePoints);
glm::mat4 ComputeQuadric(VertexRecord v0);
glm::mat4 BuildQuadricSolverMatrix(const glm::mat4& Quad);
void ComputeOptimalVertexAndError(ValidPair& validPair, const glm::mat4& quadric1, const glm::mat4& quadric2);
void UpdateAdjacencyIndices(std::vector<unsigned int>& adjFaces, const std::vector<unsigned int>& removedFaceIndices);
Object GHOutputOBJ();

// Modification algorithms
Object Beehive();
Object Snowflake();
Object CatmullClark();
Object DooSabin();
Object Loop();
Object QEM();
Object QEM(unsigned int desiredCount);

public:
std::vector<VertexRecord> m_Vertices;
Expand All @@ -80,4 +103,6 @@ class Surface
glm::vec3 m_Max;

std::unordered_map<unsigned int, std::unordered_map<unsigned int, unsigned int>> m_EdgeIdxLookup;
private:
std::priority_queue<ValidPair, std::vector<ValidPair>, CompareValidPairs> m_QuadricErrorHeap;
};
Loading