Commit 14249461 by Philipp Adolf

Rewrite getPatchIndexBuffer

parent b4a91fe7
......@@ -103,12 +103,11 @@ void Subdivision::subdivide(Mesh *mesh, int level) {
qCDebug(log_subdiv) << "subdivide: regular" << regular.length();
qCDebug(log_subdiv) << "subdivide: irregular" << irregular.length();
QVector<unsigned int> regular_ib;
trianglesToIB(regular, regular_ib);
QVector<unsigned int> irregular_ib;
trianglesToIB(irregular, irregular_ib);
QVector<unsigned int> patches = getPatchIndexBuffer(regular_ib, irregular_ib, result.vertex_buffer);
QVector<unsigned int> patches;
getPatchIndexBuffer(regular, neighbors, patches);
qCDebug(log_subdiv) << "patches" << patches.length();
current_mesh->update(result.vb_handle, result.vertex_buffer, irregular_ib, patches);
......@@ -585,12 +584,12 @@ void Subdivision::splitRegular(Mesh *mesh) {
QVector<Triangle> irregular;
findRegular(all_triangles, neighbors, regular, irregular);
QVector<unsigned int> regular_ib;
trianglesToIB(regular, regular_ib);
QVector<unsigned int> irregular_ib;
trianglesToIB(irregular, irregular_ib);
QVector<unsigned int> patches = getPatchIndexBuffer(regular_ib, irregular_ib, current_mesh->buffers[0]->vertices);
QVector<unsigned int> patches;
getPatchIndexBuffer(regular, neighbors, patches);
current_mesh->buffers[0]->indices_regular = patches;
current_mesh->buffers[0]->indices_irregular = irregular_ib;
current_mesh->buffers[0]->updateIndices();
......@@ -601,188 +600,92 @@ void Subdivision::splitRegular(Mesh *mesh) {
qCDebug(log_subdiv) << "splitRegular(mesh): irregular: " << irregular.length();
}
/**
* @brief Subdivision::getPatchIndexBuffer
* Computes an index buffer for the patches. patches are in order from figure 6(a) from the paper:
* 0 1
*
* 2 3 4
*
* 5 6 7 8
*
* 9 10 11
*
* 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.
* (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.
*/
QVector<unsigned int> Subdivision::getPatchIndexBuffer(QVector<unsigned int> ib_regular, QVector<unsigned int> ib_irregular, QVector<Vertex> vb){
void Subdivision::getPatchIndexBuffer(QVector<Triangle> &triangles, QMap<Triangle, Triangle::Neighbors> &neighbors, QVector<unsigned int> &patch_ib) {
QTime totalTimer;
totalTimer.start();
qCDebug(log_timing)<<"PatchIndexBuffer started";
QVector<unsigned int> pib;
if (ib_regular.size() == 0) return pib;
QTime tempTimer;
tempTimer.start();
QVector<unsigned int> ib_combined = ib_regular + ib_irregular; //DO NOT swap regular and irregular! iteration over ib_combined starting from index in ib_regular
qCDebug(log_timing) << "ib_combined:" << formatTimeMeasurement(tempTimer.elapsed());
QMap<Triangle,QVector<Triangle>> adj;
// qDebug()<<"combined lenght"<<ib_combined.length();
for (int i = 0; i < ib_combined.length() - 2; i+=3){
// qDebug()<<"Index"<<i;
unsigned int i3,i6,i7;
//alles gegen den uzs
i3 = ib_combined[i];
i6 = ib_combined[i+1];
i7 = ib_combined[i+2];
if(log_subdiv_trace().isDebugEnabled()){
if (i < ib_regular.length()){
Vertex v3 = vb[i3];
Vertex v6 = vb[i6];
Vertex v7 = vb[i7];
int count3 = 0; //counts other triangles with this vertex
int count6 = 0;
int count7 = 0;
for (int j = 0; j < ib_combined.length(); j++){
if (j != i && j != i+1 && j != i+2){
//for debugging // checking if patch is regular.
if (vb[ib_combined[j]].samePos(v3)) count3++;
if (vb[ib_combined[j]].samePos(v6)) count6++;
if (vb[ib_combined[j]].samePos(v7)) count7++;
}
}
if (count3 != 5 || count6 != 5 || count7 != 5){
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.";
}
}
}
Triangle t367(&vb,i3,i6,i7);
QVector<unsigned int> patch;
patch.resize(12);
for (int j = i+3; j < ib_combined.length()-2; j += 3){
unsigned int j0 = ib_combined[j];
unsigned int j1 = ib_combined[j+1];
unsigned int j2 = ib_combined[j+2];
QVectorIterator<Triangle> it(triangles);
while (it.hasNext()) {
Triangle triangle = it.next();
Triangle tj(&vb,j0,j1,j2);
// These three vertices come from the triangle we're looking at
patch[3] = triangle.u_idx();
patch[6] = triangle.v_idx();
patch[7] = triangle.w_idx();
if (t367.hasSharedEdge(tj)){
QVector<Triangle> neighbors = adj.value(tj,QVector<Triangle>());
neighbors.push_back(t367);
adj.insert(tj,neighbors);
neighbors = adj.value(t367,QVector<Triangle>());
if (neighbors.length() == 3) break;
neighbors.push_back(tj);
adj.insert(t367,neighbors);
}
// These three vertices are those completing the three neighboring triangles
Triangle::Neighbors ns = neighbors.value(triangle);
patch[2] = ns.uv.edge.c;
patch[10] = ns.vw.edge.c;
patch[4] = ns.wu.edge.c;
// TODO: there's a lot of repetition in the rest of this loop but for now it's good enough
// To get the two vertices at the top we go from the left neighbor to its top neighbor and the the top neighbor of that triangle
Triangle::Neighbors left_neighbors = neighbors.value(*ns.uv.triangle);
Triangle::Neighbor top_left = left_neighbors.get_neighbor(rotate_edge_name(ns.uv.edge.name));
Triangle::Neighbors top_left_neighbors = neighbors.value(*top_left.triangle);
Triangle *top = top_left_neighbors.get_neighbor(rotate_edge_name(top_left.edge.name)).triangle;
// Then we find the one vertex shared with the main triangle and use the other two vertices
if (triangle.u().samePos(top->u())) {
patch[0] = top->w_idx();
patch[1] = top->v_idx();
} else if (triangle.u().samePos(top->v())) {
patch[0] = top->u_idx();
patch[1] = top->w_idx();
} else if (triangle.u().samePos(top->w())) {
patch[0] = top->v_idx();
patch[1] = top->u_idx();
} else {
assert(false);
}
if (adj.value(t367,QVector<Triangle>()).size() != 3){
qCDebug(log_subdiv_trace)<<"no 3 adjacent triangles found";
// The four vertices at the bottom are similar to those at the top, but we start with the bottom neighbor and go left/right
Triangle::Neighbors bottom_neighbors = neighbors.value(*ns.vw.triangle);
Triangle::Neighbor bottom_middle_left = bottom_neighbors.get_neighbor(rotate_edge_name(ns.vw.edge.name));
Triangle::Neighbors bottom_middle_left_neighbors = neighbors.value(*bottom_middle_left.triangle);
Triangle *bottom_left = bottom_middle_left_neighbors.get_neighbor(rotate_edge_name(bottom_middle_left.edge.name)).triangle;
if (triangle.v().samePos(bottom_left->u())) {
patch[5] = bottom_left->v_idx();
patch[9] = bottom_left->w_idx();
} else if (triangle.v().samePos(bottom_left->v())) {
patch[5] = bottom_left->w_idx();
patch[9] = bottom_left->u_idx();
} else if (triangle.v().samePos(bottom_left->w())) {
patch[5] = bottom_left->u_idx();
patch[9] = bottom_left->v_idx();
} else {
assert(false);
}
}
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;
i3 = ib_regular[i];
i6 = ib_regular[i+1];
i7 = ib_regular[i+2];
Triangle ti(&vb,i3,i6,i7);
bool found0, found1, found5, found8, found9, found11;
QVector<Triangle> neighbors = adj.value(ti,QVector<Triangle>());
for (int j = 0; j < neighbors.length(); j++){
Triangle::Edge a,b;
Triangle tj = neighbors[j];
ti.get_shared_edge(tj,a,b);
Triangle::Edge c,d;
QVector<Triangle> an = adj.value(tj,QVector<Triangle>());
if (a.name == Triangle::Edge::Name::uv){
i2 = b.c;
for(int k = 0; k < an.length(); k++){
tj.get_shared_edge(an[k],c,d);
if (tj.next_ctrclockwise(b,c)){
i0 = d.c;
found0 = true;
}
if (tj.next_clockwise(b,c)){
i5 = d.c;
found5 = true;
}
}
} else if (a.name == Triangle::Edge::Name::vw){
i10 = b.c;
for (int k = 0; k < an.length(); k++){
tj.get_shared_edge(an[k],c,d);
if (tj.next_ctrclockwise(b,c)){
i9 = d.c;
found9 = true;
}
if (tj.next_clockwise(b,c)){
i11 = d.c;
found11 = true;
}
}
} else if (a.name == Triangle::Edge::Name::wu){
i4 = b.c;
for (int k = 0; k < an.length(); k++){
tj.get_shared_edge(an[k],c,d);
if (tj.next_ctrclockwise(b,c)){
i8 = d.c;
found8 = true;
}
if (tj.next_clockwise(b,c)){
i1 = d.c;
found1 = true;
}
}
}
Triangle::Neighbor bottom_middle_right = bottom_neighbors.get_neighbor(rotate_edge_name(rotate_edge_name(ns.vw.edge.name)));
Triangle::Neighbors bottom_middle_right_neighbors = neighbors.value(*bottom_middle_right.triangle);
Triangle *bottom_right = bottom_middle_right_neighbors.get_neighbor(rotate_edge_name(rotate_edge_name(bottom_middle_right.edge.name))).triangle;
if (triangle.w().samePos(bottom_right->u())) {
patch[8] = bottom_right->w_idx();
patch[11] = bottom_right->v_idx();
} else if (triangle.w().samePos(bottom_right->v())) {
patch[8] = bottom_right->u_idx();
patch[11] = bottom_right->w_idx();
} else if (triangle.w().samePos(bottom_right->w())) {
patch[8] = bottom_right->v_idx();
patch[11] = bottom_right->u_idx();
} else {
assert(false);
}
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) << "found: 0 1 5 9 8 11 \n" << found0 << found1 << found5 << found9 << found8 << found11;
qCWarning(log_subdiv) << "Abort computing patch index buffer.";
return pib;
}
//else qCWarning(log_subdiv) << "found all neighbours for patch.";
pib.push_back(i0);
pib.push_back(i1);
pib.push_back(i2);
pib.push_back(i3);
pib.push_back(i4);
pib.push_back(i5);
pib.push_back(i6);
pib.push_back(i7);
pib.push_back(i8);
pib.push_back(i9);
pib.push_back(i10);
pib.push_back(i11);
patch_ib += patch;
}
qCDebug(log_timing)<<"PatchIndexBuffer done:"<<formatTimeMeasurement(totalTimer.elapsed());
return pib;
qCDebug(log_timing) << "PatchIndexBuffer done:" << formatTimeMeasurement(totalTimer.elapsed());
}
/**
......
......@@ -70,7 +70,7 @@ private:
QVector<unsigned int> patchIBToTriangleIB(QVector<unsigned int> ib);
QVector<unsigned int> getPatchIndexBuffer(QVector<unsigned int> ib_regular, QVector<unsigned int> ib_irregular, QVector<Vertex> vb);
void getPatchIndexBuffer(QVector<Triangle> &triangles, QMap<Triangle, Triangle::Neighbors> &neighbors, QVector<unsigned int> &patch_ib);
};
#endif
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