Commit 39d315af by Alisa Jung

getPatchIndexBuffer fix: check if vertices have same position (not necessarily same index)

Vertex == now only compares position Conflicts: QTProject/subdivision.h
parent 87d5c28e
...@@ -78,10 +78,10 @@ void Subdivision::subdivide(Mesh *mesh, int level) { ...@@ -78,10 +78,10 @@ void Subdivision::subdivide(Mesh *mesh, int level) {
findRegular(tables.index_buffer, result.vertex_buffer, regular, irregular); findRegular(tables.index_buffer, result.vertex_buffer, regular, irregular);
qCDebug(log_subdiv) << "Indices" << tables.index_buffer.length(); qCDebug(log_subdiv) << "Indices" << tables.index_buffer.length();
qCDebug(log_subdiv) << "regular" << regular.length(); qCDebug(log_subdiv) << "subdivide: regular" << regular.length();
qCDebug(log_subdiv) << "irregular" << irregular.length(); qCDebug(log_subdiv) << "subdivide: irregular" << irregular.length();
QVector<unsigned int> patches = getPatchIndexBuffer(regular); QVector<unsigned int> patches = getPatchIndexBuffer(regular, irregular,result.vertex_buffer);//todo is this the correct vb?
qCDebug(log_subdiv) << "patches" << patches.length(); qCDebug(log_subdiv) << "patches" << patches.length();
current_mesh->update(result.vb_handle, result.vertex_buffer, irregular, patches); current_mesh->update(result.vb_handle, result.vertex_buffer, irregular, patches);
...@@ -151,7 +151,7 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) { ...@@ -151,7 +151,7 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) {
precomputeEdgeTable(tables, triangles, (unsigned int) vb.length()); precomputeEdgeTable(tables, triangles, (unsigned int) vb.length());
precomputeVertexTable(tables, vb, ib); precomputeVertexTable(tables, vb, ib);
tables.index_regular = getPatchIndexBuffer(ib); //tables.patch_index_regular = getPatchIndexBuffer(ib, QVector<unsigned int>());//TODO pass regular and irregular index buffer?
qCDebug(log_subdiv) << "Precompute Tables Done"; qCDebug(log_subdiv) << "Precompute Tables Done";
return tables; return tables;
} }
...@@ -358,13 +358,13 @@ void Subdivision::splitRegular(Mesh *mesh) { ...@@ -358,13 +358,13 @@ void Subdivision::splitRegular(Mesh *mesh) {
findRegular(current_mesh->buffers[0]->indices_irregular, current_mesh->buffers[0]->vertices, regular, irregular); findRegular(current_mesh->buffers[0]->indices_irregular, current_mesh->buffers[0]->vertices, regular, irregular);
findRegular(current_mesh->buffers[0]->indices_regular, current_mesh->buffers[0]->vertices, regular, irregular); findRegular(current_mesh->buffers[0]->indices_regular, current_mesh->buffers[0]->vertices, regular, irregular);
QVector<unsigned int> patches = getPatchIndexBuffer(regular); QVector<unsigned int> patches = getPatchIndexBuffer(regular, irregular,current_mesh->buffers[0]->vertices);//TODO is this the corret vertex buffer?
current_mesh->buffers[0]->indices_regular = patches; current_mesh->buffers[0]->indices_regular = patches;
current_mesh->buffers[0]->indices_irregular = irregular; current_mesh->buffers[0]->indices_irregular = irregular;
current_mesh->buffers[0]->updateIndices(); current_mesh->buffers[0]->updateIndices();
qCDebug(log_subdiv) << "regular: " << regular.length(); qCDebug(log_subdiv) << "splitRegular(mesh): regular: " << regular.length();
qCDebug(log_subdiv) << "irregular: " << irregular.length(); qCDebug(log_subdiv) << "splitRegular(mesh): irregular: " << irregular.length();
} }
/** /**
...@@ -380,34 +380,44 @@ void Subdivision::splitRegular(Mesh *mesh) { ...@@ -380,34 +380,44 @@ void Subdivision::splitRegular(Mesh *mesh) {
* *
* with 367 being the original triangle. * with 367 being the original triangle.
* Assumes that each vertex \exists only once in the vertex buffer, i.e. with regular patches, each index in the index buffer \exists 6 times. * Assumes that each vertex \exists only once in the vertex buffer, i.e. with regular patches, each index in the index buffer \exists 6 times.
* @param ib original index buffer * (each index exists a total of 6 times in the regular and irregular index buffer combined)
* @param ib_regular index buffer with regular triangles. Will only generate patches for these regular triangles.
* @param ib_irregular index buffer with irregular triangles.
* patches for regular triangles might include vertices from irregular triangles that are not part of the regular index buffer.
* @param vb vertex buffer. We need this because the same location may appear multiple times in the vertex buffer (due to different normals / ...)
* and simply comparing indices isn't enough.
* @return patch index buffer with 4 times as many indices. ! if something goes wrong, the current buffer is returned and might be incomplete or empty. * @return patch index buffer with 4 times as many indices. ! if something goes wrong, the current buffer is returned and might be incomplete or empty.
*/ */
QVector<unsigned int> Subdivision::getPatchIndexBuffer(QVector<unsigned int> ib){ QVector<unsigned int> Subdivision::getPatchIndexBuffer(QVector<unsigned int> ib_regular, QVector<unsigned int> ib_irregular, QVector<Vertex> vb){
QVector<unsigned int> pib; QVector<unsigned int> pib;
for (int i = 0; i < ib.length() - 2; i+=3){ QVector<unsigned int> ib_combined = ib_regular + ib_irregular;
for (int i = 0; i < ib_regular.length() - 2; i+=3){
unsigned int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11; unsigned int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11;
//alles gegen den uzs //alles gegen den uzs
i3 = ib[i]; i3 = ib_regular[i];
i6 = ib[i+1]; i6 = ib_regular[i+1];
i7 = ib[i+2]; i7 = ib_regular[i+2];
Vertex v3 = vb[i3];
Vertex v6 = vb[i6];
Vertex v7 = vb[i7];
int count3 = 0; //counts other triangles with this vertex int count3 = 0; //counts other triangles with this vertex
int count6 = 0; int count6 = 0;
int count7 = 0; int count7 = 0;
for (int j = 0; j < ib.length(); j++){ for (int j = 0; j < ib_combined.length(); j++){
if (j != i && j != i+1 && j != i+2){ if (j != i && j != i+1 && j != i+2){
//for debugging // checking if patch is regular. //for debugging // checking if patch is regular.
if (ib[j] == i3) count3++; if (vb[ib_combined[j]] == v3) count3++;
if (ib[j] == i6) count6++; if (vb[ib_combined[j]] == v6) count6++;
if (ib[j] == i7) count7++; if (vb[ib_combined[j]] == v7) count7++;
} }
} }
if (count3 != 5 || count6 != 5 || count7 != 5){ if (count3 != 5 || count6 != 5 || count7 != 5){
qCWarning(log_subdiv) << "Counts wrong! 3: "<< count3 <<", 6: " << count6 << ", 7: " << count7; qCWarning(log_subdiv) << "Counts wrong! 3: "<< count3 <<", 6: " << count6 << ", 7: " << count7 << ".\nEither this patch is not regular, or you didn't pass all neighboring triangles.";
} }
...@@ -416,17 +426,17 @@ QVector<unsigned int> Subdivision::getPatchIndexBuffer(QVector<unsigned int> ib) ...@@ -416,17 +426,17 @@ QVector<unsigned int> Subdivision::getPatchIndexBuffer(QVector<unsigned int> ib)
bool found36 = false; bool found36 = false;
bool found67 = false; bool found67 = false;
bool found73 = false; bool found73 = false;
for (int j = 0; j < ib.length() - 2; j+=3){ for (int j = 0; j < ib_combined.length() - 2; j+=3){
unsigned int j0 = ib[j]; unsigned int j0 = ib_combined[j];
unsigned int j1 = ib[j+1]; unsigned int j1 = ib_combined[j+1];
unsigned int j2 = ib[j+2]; unsigned int j2 = ib_combined[j+2];
//Dreieck angrenzend an Kante i3 i6 //Dreieck angrenzend an Kante i3 i6
found36 |= matchAndCompleteTriangle(j0,j1,j2,i6,i3,i2); found36 |= matchAndCompleteTriangle(j0,j1,j2,i6,i3,i2,vb);
//Dreieck angrenzend an Kante i6 i7 //Dreieck angrenzend an Kante i6 i7
found67 |= matchAndCompleteTriangle(j0,j1,j2,i7,i6,i10); found67 |= matchAndCompleteTriangle(j0,j1,j2,i7,i6,i10,vb);
//Dreieck angrenzend an Kante i7 i3 //Dreieck angrenzend an Kante i7 i3
found73 |= matchAndCompleteTriangle(j0,j1,j2,i3,i7,i4); found73 |= matchAndCompleteTriangle(j0,j1,j2,i3,i7,i4,vb);
} }
if (!(found36 && found67 && found73)){ if (!(found36 && found67 && found73)){
...@@ -444,28 +454,43 @@ QVector<unsigned int> Subdivision::getPatchIndexBuffer(QVector<unsigned int> ib) ...@@ -444,28 +454,43 @@ QVector<unsigned int> Subdivision::getPatchIndexBuffer(QVector<unsigned int> ib)
bool found9 = false; bool found9 = false;
bool found8 = false; bool found8 = false;
bool found11 = false; bool found11 = false;
for (int j = 0; j < ib.length() - 2; j+=3){ for (int j = 0; j < ib_combined.length() - 2; j+=3){
unsigned int j0 = ib[j]; unsigned int j0 = ib_combined[j];
unsigned int j1 = ib[j+1]; unsigned int j1 = ib_combined[j+1];
unsigned int j2 = ib[j+2]; unsigned int j2 = ib_combined[j+2];
//find i0. //TODO assert triangle 031 \exists somewhere //find i0. //TODO assert triangle 031 \exists somewhere
found0 |= matchAndCompleteTriangle(j0,j1,j2,i2,i3,i0); found0 |= matchAndCompleteTriangle(j0,j1,j2,i2,i3,i0,vb);
found1 |= matchAndCompleteTriangle(j0,j1,j2,i3,i4,i1); found1 |= matchAndCompleteTriangle(j0,j1,j2,i3,i4,i1,vb);
//TODO maybe assert that triangle i0 i3 i1 actually \exists. //TODO maybe assert that triangle i0 i3 i1 actually \exists.
found5 |= matchAndCompleteTriangle(j0,j1,j2,i6,i2,i5); found5 |= matchAndCompleteTriangle(j0,j1,j2,i6,i2,i5,vb);
found9 |= matchAndCompleteTriangle(j0,j1,j2,i10,i6,i9); found9 |= matchAndCompleteTriangle(j0,j1,j2,i10,i6,i9,vb);
//todo assert that triangle i5 i9 i6 //todo assert that triangle i5 i9 i6
found8 |= matchAndCompleteTriangle(j0,j1,j2,i4,i7,i8); found8 |= matchAndCompleteTriangle(j0,j1,j2,i4,i7,i8,vb);
found11 |= matchAndCompleteTriangle(j0,j1,j2,i7,i10,i11); found11 |= matchAndCompleteTriangle(j0,j1,j2,i7,i10,i11,vb);
} }
if (!(found0 && found1 && found5 && found9 && found8 && found11)){ if (!(found0 && found1 && found5 && found9 && found8 && found11)){
qCWarning(log_subdiv) << "Couldnt find some neighbour at i= " << i;
qCWarning(log_subdiv) << "i3: " << i3 << ", i6: " << i6 << " i7: " << i7 << " i2 " << i2;
for (int k = 0; k < ib_combined.length() - 2; k+= 3){
if (ib_combined[k] == i3 || ib_combined[k+1] == i3 || ib_combined[k+2] == i3){
qCWarning(log_subdiv) << "i3 adjacent: " << ib_combined[k] << ", " << ib_combined[k+1] << ", " << ib_combined[k+2];
}
}
qCWarning(log_subdiv) << "Couldnt find some neighbour at i= " << i; qCWarning(log_subdiv) << "Couldnt find some neighbour at i= " << i;
qCWarning(log_subdiv) << found0 << found1 << found5 << found9 << found8 << found11; qCWarning(log_subdiv) << "found: 0 1 5 9 8 11 \n" << found0 << found1 << found5 << found9 << found8 << found11;
qCWarning(log_subdiv) << "Count3: " << count3 << " count6: " << count6 << " count7: " << count7;
qCWarning(log_subdiv) << "Abort computing patch index buffer."; qCWarning(log_subdiv) << "Abort computing patch index buffer.";
return pib; return pib;
} }
...@@ -543,7 +568,7 @@ void Subdivision::findRegular(QVector<unsigned int> index_buffer, QVector<Vertex ...@@ -543,7 +568,7 @@ void Subdivision::findRegular(QVector<unsigned int> index_buffer, QVector<Vertex
} }
} }
bool Subdivision::matchAndCompleteTriangle(unsigned int sx, unsigned int sy, unsigned int sz, unsigned int tx, unsigned int ty, unsigned int &tz){ bool Subdivision::matchAndCompleteTriangleIndices(unsigned int sx, unsigned int sy, unsigned int sz, unsigned int tx, unsigned int ty, unsigned int &tz){
if (sx == tx && sy == ty){ if (sx == tx && sy == ty){
tz = sz; tz = sz;
return true; return true;
...@@ -559,6 +584,25 @@ bool Subdivision::matchAndCompleteTriangle(unsigned int sx, unsigned int sy, uns ...@@ -559,6 +584,25 @@ bool Subdivision::matchAndCompleteTriangle(unsigned int sx, unsigned int sy, uns
return false; return false;
} }
bool Subdivision::matchAndCompleteTriangle(unsigned int sx, unsigned int sy, unsigned int sz,unsigned int tx, unsigned int ty, unsigned int &tz, QVector<Vertex> vb){
if (vb[sx] == vb[tx] && vb[sy] == vb[ty]){
tz = sz;
return true;
}
if (vb[sy] == vb[tx] && vb[sz] == vb[ty]){
tz = sx;
return true;
}
if (vb[sz] == vb[tx] && vb[sx] == vb[ty]){
tz = sy;
return true;
}
return false;
}
Subdivision::Result Subdivision::runShader(Input input, Tables &tables) { Subdivision::Result Subdivision::runShader(Input input, Tables &tables) {
qCDebug(log_subdiv) << "Running compute shader"; qCDebug(log_subdiv) << "Running compute shader";
......
...@@ -32,7 +32,7 @@ private: ...@@ -32,7 +32,7 @@ private:
QVector<GLuint> vertex_indices; QVector<GLuint> vertex_indices;
QVector<GLuint> vertex_offsets; QVector<GLuint> vertex_offsets;
QVector<GLuint> index_buffer; QVector<GLuint> index_buffer;
QVector<GLuint> index_regular; QVector<GLuint> patch_index_regular;
}; };
struct Result struct Result
...@@ -60,21 +60,41 @@ private: ...@@ -60,21 +60,41 @@ private:
void runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle); void runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle);
void runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle, GLuint offset); void runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle, GLuint offset);
//Geht davon aus, dass jeder 3D-Punkt nur einmal im Vertex-Buffer vorkommt!
QVector<unsigned int> getPatchIndexBuffer(QVector<unsigned int> ib);
QVector<unsigned int> getTriangles(QVector<unsigned int> ib); QVector<unsigned int> getTriangles(QVector<unsigned int> ib);
QVector<unsigned int> getPatchIndexBuffer(QVector<unsigned int> ib_regular, QVector<unsigned int> ib_irregular, QVector<Vertex> vb);
/**
* @brief matchAndCompleteTriangleIndices if Indices tx ty matches sxsy, sysz or szsy, fill tz with third source vertex index.
* @param sx source triangle: first vertex index
* @param sy source triangle: second vertex index
* @param sz source triangle: third vertex index
* @param tx target triangle: first known vertex index
* @param ty target triangle: second known vertex index
* @param tz target triangle: unknown vertex index.
* @return true if triangles could be matched and tz was filled.
* Only use this method if you are absolutely sure that each vertex position appears ONLY ONCE in the vertex buffer!!
* No duplicate vertices with different normals or crap like that!
*/
bool matchAndCompleteTriangleIndices(unsigned int sx, unsigned int sy, unsigned int sz, unsigned int tx, unsigned int ty, unsigned int& tz);
//same as matchandcomplete. doesn't rely on only one index per vertex location
//needs indices to fill tz
/** /**
* @brief matchAndCompleteTriangle if tx ty matches sxsy, sysz or szsy, fill tz with third source vertex index. * @brief matchAndCompleteTriangle if vertices at indices tx ty matches vertices at indices sxsy, sysz or szsy,
* @param sx source triangle: first vertex * fill tz with third source vertex index.
* @param sy source triangle: second vertex * @param sx source triangle: first vertex index
* @param sz source triangle: third vertex * @param sy source triangle: second vertex index
* @param tx target triangle: first known vertex * @param sz source triangle: third vertex index
* @param ty target triangle: second known vertex * @param tx target triangle: first known vertex index
* @param tz target triangle: unknown vertex. * @param ty target triangle: second known vertex index
* @param tz target triangle: unknown vertex index.
* @param vb Vertex Buffer. This method compares the actual positions of the vertices
* @return true if triangles could be matched and tz was filled. * @return true if triangles could be matched and tz was filled.
*/ */
bool matchAndCompleteTriangle(unsigned int sx, unsigned int sy, unsigned int sz, unsigned int tx, unsigned int ty, unsigned int& tz); bool matchAndCompleteTriangle(unsigned int sx, unsigned int sy, unsigned int sz, unsigned int tx, unsigned int ty, unsigned int &tz, QVector<Vertex> vb);
}; };
#endif #endif
...@@ -21,6 +21,12 @@ struct Vertex ...@@ -21,6 +21,12 @@ struct Vertex
Vertex(const QVector3D& pos, const QVector3D& normal, const QVector2D& tex); Vertex(const QVector3D& pos, const QVector3D& normal, const QVector2D& tex);
bool samePos(const Vertex& other) const; bool samePos(const Vertex& other) const;
bool operator==(const Vertex& other) const
{
return samePos(other);
}
}; };
#pragma pack(pop) #pragma pack(pop)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment