Skip to content

Commit 8697830

Browse files
committed
ad QEM simplification
1 parent 4ee265e commit 8697830

File tree

7 files changed

+567
-32
lines changed

7 files changed

+567
-32
lines changed

Model-Modifier/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ set(Source_Files
484484
"src/scene/surface/Surface.cpp"
485485
"src/scene/surface/Surface_CatmullClark.cpp"
486486
"src/scene/surface/Surface_DooSabin.cpp"
487+
"src/scene/surface/Surface_GarlandHeckbert.cpp"
487488
"src/scene/surface/Surface_Loop.cpp"
488489
"src/scene/util/OrderVertices.cpp"
489490
"src/scene/util/PlaneProjection.cpp"
59.9 KB
Loading

Model-Modifier/src/main.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ int main()
135135
Object obj = objects.findObj(currObject);
136136
Material meshMat;
137137

138+
// object triangle count (QEM)
139+
int triCount = static_cast<int>(obj.m_TriFaceIndices.size());
140+
int desiredTriCount = triCount;
141+
138142
VertexBufferLayout layout;
139143
layout.Push<float>(3); // 3d coordinates
140144
layout.Push<float>(3); // normals
@@ -366,17 +370,17 @@ int main()
366370
obj = Lo.Loop();
367371
ModifyModel = true;
368372
}
369-
//if (ImGui::Button("Garland Heckbert Simplication Surface"))
370-
//{
371-
// Surface GH(obj);
372-
// obj = GH.QEM();
373-
// mesh.Rebuild(obj); // rebuild mesh based on object info
374-
// numFaces = static_cast<unsigned int>(mesh.m_Object.m_FaceIndices.size()); // update number of faces
375-
376-
// objectVA.Bind();
377-
// objectVB.AssignData(mesh.m_OutVertices, mesh.m_OutNumVert * sizeof(float), DRAW_MODE::STATIC);
378-
// objectIB.AssignData(mesh.m_OutIndices, mesh.m_OutNumIdx, DRAW_MODE::STATIC);
379-
//}
373+
if (ImGui::Button("Garland Heckbert Simplification Surface"))
374+
{
375+
obj.MakeTriangleMesh(); // Triangulate first
376+
Surface GH(obj);
377+
obj = GH.QEM(desiredTriCount);
378+
ModifyModel = true;
379+
}
380+
ImGui::Indent();
381+
ImGui::SliderInt("Desired count", &desiredTriCount, triCount/5, triCount);
382+
ImGui::Unindent();
383+
380384
ImGui::Unindent();
381385
}
382386

@@ -626,6 +630,7 @@ int main()
626630
currObject = nextObject;
627631

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

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

639645
objectVA.Bind();
640646
objectVB.AssignData(mesh.m_OutVertices, mesh.m_OutNumVert * sizeof(float), DRAW_MODE::STATIC);

Model-Modifier/src/scene/surface/Surface.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -137,21 +137,3 @@ glm::vec3 Surface::ComputeFaceNormal(glm::vec3 pos0, glm::vec3 pos1, glm::vec3 p
137137
{
138138
return glm::normalize(glm::cross(pos1 - pos0, pos2 - pos0));
139139
}
140-
141-
// computer quadric matrix by summing all K_p matrices of a vertice v0
142-
glm::mat4 Surface::ComputeQuadric(VertexRecord v0)
143-
{
144-
glm::mat4 quadric{ 0.0f };
145-
// for each neighbouring face, compute K_p
146-
glm::vec3 position = v0.position;
147-
for (unsigned int faceIdx : v0.adjFacesIdx)
148-
{
149-
FaceRecord face = m_Faces[faceIdx];
150-
glm::vec3 faceNormal = ComputeFaceNormal(face);
151-
glm::vec4 plane{ faceNormal, -glm::dot(faceNormal, position) }; // plane equation ax+by+cz+d = 0
152-
153-
quadric += glm::outerProduct(plane, plane); // K_p
154-
}
155-
156-
return quadric;
157-
}

Model-Modifier/src/scene/surface/Surface.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <set>
44
#include <vector>
55
#include <unordered_map>
6+
#include <queue>
67

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

41+
// QEM
42+
struct ValidPair
43+
{
44+
unsigned int vertOne;
45+
unsigned int vertTwo;
46+
bool edge;
47+
float error;
48+
glm::vec3 newVert;
49+
};
50+
51+
struct CompareValidPairs
52+
{
53+
bool operator()(const ValidPair& a, const ValidPair& b) const
54+
{
55+
return a.error > b.error; // min heap
56+
}
57+
};
58+
4059
class Surface
4160
{
4261
public:
@@ -62,14 +81,18 @@ class Surface
6281
);
6382
Object LoOutputOBJ(std::vector<glm::vec3> edgePoints);
6483
glm::mat4 ComputeQuadric(VertexRecord v0);
84+
glm::mat4 BuildQuadricSolverMatrix(const glm::mat4& Quad);
85+
void ComputeOptimalVertexAndError(ValidPair& validPair, const glm::mat4& quadric1, const glm::mat4& quadric2);
86+
void UpdateAdjacencyIndices(std::vector<unsigned int>& adjFaces, const std::vector<unsigned int>& removedFaceIndices);
87+
Object GHOutputOBJ();
6588

6689
// Modification algorithms
6790
Object Beehive();
6891
Object Snowflake();
6992
Object CatmullClark();
7093
Object DooSabin();
7194
Object Loop();
72-
Object QEM();
95+
Object QEM(unsigned int desiredCount);
7396

7497
public:
7598
std::vector<VertexRecord> m_Vertices;
@@ -80,4 +103,6 @@ class Surface
80103
glm::vec3 m_Max;
81104

82105
std::unordered_map<unsigned int, std::unordered_map<unsigned int, unsigned int>> m_EdgeIdxLookup;
106+
private:
107+
std::priority_queue<ValidPair, std::vector<ValidPair>, CompareValidPairs> m_QuadricErrorHeap;
83108
};

0 commit comments

Comments
 (0)