Commit 6aabc072 by Philipp Adolf

Merge branch '13-nachbarn-sollten-nur-einmal-berechnet-werden' into 'patchRender'

Resolve "Nachbarn sollten nur einmal berechnet werden" Closes #13 See merge request !5
parents cf654955 13440614
...@@ -100,26 +100,6 @@ void Subdivision::subdivide(Mesh *mesh, int level) { ...@@ -100,26 +100,6 @@ void Subdivision::subdivide(Mesh *mesh, int level) {
} }
} }
void insert_edge(QMap<Triangle, QVector<Triangle::Edge>> &opposite_edges, const Triangle &triangle, const Triangle::Edge &edge_a, const Triangle::Edge &edge_b) {
QVector<Triangle::Edge> edges = opposite_edges.value(triangle, QVector<Triangle::Edge>());
edges.resize(3);
switch (edge_a.name) {
case Triangle::Edge::Name::uv:
edges[0] = edge_b;
break;
case Triangle::Edge::Name::vw:
edges[1] = edge_b;
break;
case Triangle::Edge::Name::wu:
edges[2] = edge_b;
break;
default:
qCWarning(log_subdiv) << "got" << edge_a.name << "as edge!";
break;
}
opposite_edges.insert(triangle, edges);
}
struct Edge { struct Edge {
unsigned int a; unsigned int a;
unsigned int b; unsigned int b;
...@@ -158,20 +138,24 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) { ...@@ -158,20 +138,24 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) {
QVector<Vertex> vb = input.vertex_buffer; QVector<Vertex> vb = input.vertex_buffer;
qCDebug(log_subdiv_trace) << "Vertex Buffer: " << vb; qCDebug(log_subdiv_trace) << "Vertex Buffer: " << vb;
QTime trianglesTimer; QTime subTimer;
trianglesTimer.start(); subTimer.start();
QVector<Triangle> triangles; QVector<Triangle> triangles;
ibToTriangles(&vb, ib, triangles); ibToTriangles(&vb, ib, triangles);
QVector<Triangle> triangles_regular; QVector<Triangle> triangles_regular;
ibToTriangles(&vb, ib_regular, triangles); ibToTriangles(&vb, ib_regular, triangles);
qCDebug(log_timing) << "building Triangles:" << formatTimeMeasurement(trianglesTimer.elapsed()); qCDebug(log_timing) << "building Triangles:" << formatTimeMeasurement(subTimer.elapsed());
QTime subTimer; subTimer.restart();
QMap<Triangle, Triangle::Neighbors> neighbors;
QVector<Triangle> all_triangles = triangles + triangles_regular;
buildNeighborsMap(all_triangles, neighbors);
qCDebug(log_timing) << "building neighbors map:" << formatTimeMeasurement(subTimer.elapsed());
subTimer.start(); subTimer.restart();
precomputeEdgeTable(tables, triangles, triangles_regular, (unsigned int) vb.length()); precomputeEdgeTable(tables, triangles, neighbors, (unsigned int) vb.length());
qCDebug(log_timing) << "precomputeEdgeTable:" << formatTimeMeasurement(subTimer.elapsed()); qCDebug(log_timing) << "precomputeEdgeTable:" << formatTimeMeasurement(subTimer.elapsed());
QMap<unsigned int, unsigned int> modified_vertices; QMap<unsigned int, unsigned int> modified_vertices;
...@@ -187,20 +171,16 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) { ...@@ -187,20 +171,16 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) {
return tables; return tables;
} }
void Subdivision::precomputeEdgeTable(Subdivision::Tables &tables, QVector<Triangle> &triangles, QVector<Triangle> &triangles_regular, unsigned int offset) { void Subdivision::precomputeEdgeTable(Subdivision::Tables &tables, QVector<Triangle> &triangles, QMap<Triangle, Triangle::Neighbors> &neighbors, unsigned int offset) {
//compute edge table //compute edge table
//Format: first two entries: edge vertices. last two entries: distant vertices. //Format: first two entries: edge vertices. last two entries: distant vertices.
// for each triangle the edges of the neighbor triangles are stored.
// First the edge shared with the triangles uv edge, then vw and wu.
QMap<Triangle, QVector<Triangle::Edge>> opposite_edges;
// Maps edges to the index of the new vertex added on that edge. The keys are the indices of the two vertices defining the edge and must be in the order uv, vw or uw. // Maps edges to the index of the new vertex added on that edge. The keys are the indices of the two vertices defining the edge and must be in the order uv, vw or uw.
QMap<Edge, unsigned int> edge_indices; QMap<Edge, unsigned int> edge_indices;
for (int i = 0; i < triangles.length(); i++){ for (int i = 0; i < triangles.length(); i++){
//schaue alle dreiecke an //schaue alle dreiecke an
Triangle triangle = triangles[i]; Triangle *triangle = &triangles[i];
QVector<unsigned int> edge_indices_buffer;//push all edge indices into this, then check if enough edge indices were found. if yes, copy to Tables and add to new index buffer. QVector<unsigned int> edge_indices_buffer;//push all edge indices into this, then check if enough edge indices were found. if yes, copy to Tables and add to new index buffer.
...@@ -212,85 +192,71 @@ void Subdivision::precomputeEdgeTable(Subdivision::Tables &tables, QVector<Trian ...@@ -212,85 +192,71 @@ void Subdivision::precomputeEdgeTable(Subdivision::Tables &tables, QVector<Trian
* - Each edge point will be computed twice. This allows us to implicitly know the adjacent points. * - Each edge point will be computed twice. This allows us to implicitly know the adjacent points.
*/ */
Triangle::Edge edge_a, edge_b; Triangle::Neighbors ns = neighbors.value(*triangle);
for (int j = i + 1; j < triangles.length(); j++){
if (triangle.get_shared_edge(triangles[j], edge_a, edge_b)) {
insert_edge(opposite_edges, triangle, edge_a, edge_b);
insert_edge(opposite_edges, triangles[j], edge_b, edge_a);
}
}
for (int j = 0; j < triangles_regular.length(); j++){
if (triangle.get_shared_edge(triangles_regular[j], edge_a, edge_b)) {
insert_edge(opposite_edges, triangle, edge_a, edge_b);
// no need to insert the opposite edge of a regular triangle - it won't be processed by the outer loop
}
}
QVector<Triangle::Edge> opposite = opposite_edges.value(triangle);
// indices of the three vertices added to the edges of this triangle // indices of the three vertices added to the edges of this triangle
unsigned int uv, vw, wu; unsigned int uv, vw, wu;
Edge edge; Edge edge;
edge = { triangle.u_idx(), triangle.v_idx() }; edge = { triangle->u_idx(), triangle->v_idx() };
if (edge_indices.contains(edge)) { if (edge_indices.contains(edge)) {
uv = edge_indices.value(edge); uv = edge_indices.value(edge);
} else { } else {
uv = offset++; uv = offset++;
edge_indices.insert(edge, uv); edge_indices.insert(edge, uv);
edge = { opposite[0].a, opposite[0].b }; edge = { ns.uv.edge.a, ns.uv.edge.b };
edge_indices.insert(edge, uv); edge_indices.insert(edge, uv);
tables.edge_indices.push_back(triangle.u_idx()); tables.edge_indices.push_back(triangle->u_idx());
tables.edge_indices.push_back(triangle.v_idx()); tables.edge_indices.push_back(triangle->v_idx());
tables.edge_indices.push_back(triangle.w_idx()); tables.edge_indices.push_back(triangle->w_idx());
tables.edge_indices.push_back(opposite[0].c); tables.edge_indices.push_back(ns.uv.edge.c);
} }
edge = { triangle.v_idx(), triangle.w_idx() }; edge = { triangle->v_idx(), triangle->w_idx() };
if (edge_indices.contains(edge)) { if (edge_indices.contains(edge)) {
vw = edge_indices.value(edge); vw = edge_indices.value(edge);
} else { } else {
vw = offset++; vw = offset++;
edge_indices.insert(edge, vw); edge_indices.insert(edge, vw);
edge = { opposite[1].a, opposite[1].b }; edge = { ns.vw.edge.a, ns.vw.edge.b };
edge_indices.insert(edge, vw); edge_indices.insert(edge, vw);
tables.edge_indices.push_back(triangle.v_idx()); tables.edge_indices.push_back(triangle->v_idx());
tables.edge_indices.push_back(triangle.w_idx()); tables.edge_indices.push_back(triangle->w_idx());
tables.edge_indices.push_back(triangle.u_idx()); tables.edge_indices.push_back(triangle->u_idx());
tables.edge_indices.push_back(opposite[1].c); tables.edge_indices.push_back(ns.vw.edge.c);
} }
edge = { triangle.w_idx(), triangle.u_idx() }; edge = { triangle->w_idx(), triangle->u_idx() };
if (edge_indices.contains(edge)) { if (edge_indices.contains(edge)) {
wu = edge_indices.value(edge); wu = edge_indices.value(edge);
} else { } else {
wu = offset++; wu = offset++;
edge_indices.insert(edge, wu); edge_indices.insert(edge, wu);
edge = { opposite[2].a, opposite[2].b }; edge = { ns.wu.edge.a, ns.wu.edge.b };
edge_indices.insert(edge, wu); edge_indices.insert(edge, wu);
tables.edge_indices.push_back(triangle.w_idx()); tables.edge_indices.push_back(triangle->w_idx());
tables.edge_indices.push_back(triangle.u_idx()); tables.edge_indices.push_back(triangle->u_idx());
tables.edge_indices.push_back(triangle.v_idx()); tables.edge_indices.push_back(triangle->v_idx());
tables.edge_indices.push_back(opposite[2].c); tables.edge_indices.push_back(ns.wu.edge.c);
} }
//add indices to new index buffer //add indices to new index buffer
tables.index_buffer.push_back(triangle.u_idx()); tables.index_buffer.push_back(triangle->u_idx());
tables.index_buffer.push_back(uv); tables.index_buffer.push_back(uv);
tables.index_buffer.push_back(wu); tables.index_buffer.push_back(wu);
tables.index_buffer.push_back(triangle.v_idx()); tables.index_buffer.push_back(triangle->v_idx());
tables.index_buffer.push_back(vw); tables.index_buffer.push_back(vw);
tables.index_buffer.push_back(uv); tables.index_buffer.push_back(uv);
tables.index_buffer.push_back(triangle.w_idx()); tables.index_buffer.push_back(triangle->w_idx());
tables.index_buffer.push_back(wu); tables.index_buffer.push_back(wu);
tables.index_buffer.push_back(vw); tables.index_buffer.push_back(vw);
......
...@@ -57,7 +57,7 @@ private: ...@@ -57,7 +57,7 @@ private:
QOpenGLShaderProgram *initComputeShaderProgram(QString &source); QOpenGLShaderProgram *initComputeShaderProgram(QString &source);
Tables precomputeTables(Input input); Tables precomputeTables(Input input);
void precomputeEdgeTable(Subdivision::Tables &tables, QVector<Triangle> &triangles, QVector<Triangle> &triangles_regular, unsigned int offset); void precomputeEdgeTable(Subdivision::Tables &tables, QVector<Triangle> &triangles, QMap<Triangle, Triangle::Neighbors> &neighbors, unsigned int offset);
void precomputeVertexTable(Subdivision::Tables &tables, Input &input, QMap<unsigned int, unsigned int> &modified_vertices); void precomputeVertexTable(Subdivision::Tables &tables, Input &input, QMap<unsigned int, unsigned int> &modified_vertices);
void updateIndexBuffer(QVector<unsigned int> &index_buffer, QMap<unsigned int, unsigned int> map); void updateIndexBuffer(QVector<unsigned int> &index_buffer, QMap<unsigned int, unsigned int> map);
void findRegular(QVector<unsigned int> index_buffer, QVector<Vertex> vertex_buffer, QVector<unsigned int> &regular, QVector<unsigned int> &irregular); void findRegular(QVector<unsigned int> index_buffer, QVector<Vertex> vertex_buffer, QVector<unsigned int> &regular, QVector<unsigned int> &irregular);
......
...@@ -189,6 +189,42 @@ void ibToTriangles(QVector<Vertex> *vb, QVector<unsigned int> &ib, QVector<Trian ...@@ -189,6 +189,42 @@ void ibToTriangles(QVector<Vertex> *vb, QVector<unsigned int> &ib, QVector<Trian
} }
} }
void insert_neighbor(QMap<Triangle, Triangle::Neighbors> &neighbors, const Triangle &triangle_a, const Triangle::Edge &edge_a, Triangle *triangle_b, const Triangle::Edge &edge_b) {
if (!neighbors.contains(triangle_a)) {
neighbors.insert(triangle_a, Triangle::Neighbors());
}
Triangle::Neighbors &ns = neighbors[triangle_a];
Triangle::Neighbor neighbor = { triangle_b, edge_b };
switch (edge_a.name) {
case Triangle::Edge::Name::uv:
ns.uv = neighbor;
break;
case Triangle::Edge::Name::vw:
ns.vw = neighbor;
break;
case Triangle::Edge::Name::wu:
ns.wu = neighbor;
break;
}
neighbors.insert(triangle_a, ns);
}
void buildNeighborsMap(QVector<Triangle> &triangles, QMap<Triangle, Triangle::Neighbors> &neighbors) {
Triangle::Edge edge_a, edge_b;
for (int i = 0; i < triangles.length(); i++){
Triangle *triangle_a = &triangles[i];
for (int j = i + 1; j < triangles.length(); j++){
Triangle *triangle_b = &triangles[j];
if (triangle_a->get_shared_edge(*triangle_b, edge_a, edge_b)) {
insert_neighbor(neighbors, *triangle_a, edge_a, triangle_b, edge_b);
insert_neighbor(neighbors, *triangle_b, edge_b, triangle_a, edge_a);
}
}
}
}
QDebug operator<<(QDebug d, const Triangle &triangle) { QDebug operator<<(QDebug d, const Triangle &triangle) {
QDebugStateSaver saver(d); QDebugStateSaver saver(d);
d.nospace() << "Triangle(" << triangle.u_idx() << ", " << triangle.v_idx() << ", " << triangle.w_idx() << "; " << triangle.u().pos << ", " << triangle.v().pos << ", " << triangle.w().pos << ")"; d.nospace() << "Triangle(" << triangle.u_idx() << ", " << triangle.v_idx() << ", " << triangle.w_idx() << "; " << triangle.u().pos << ", " << triangle.v().pos << ", " << triangle.w().pos << ")";
......
...@@ -21,6 +21,17 @@ class Triangle { ...@@ -21,6 +21,17 @@ class Triangle {
unsigned int c; unsigned int c;
}; };
struct Neighbor {
Triangle *triangle;
Edge edge;
};
struct Neighbors {
Neighbor uv;
Neighbor vw;
Neighbor wu;
};
Triangle(); Triangle();
Triangle(const Triangle &other); Triangle(const Triangle &other);
Triangle(const QVector<Vertex> *vertex_buffer, unsigned int u, unsigned int v, unsigned int w); Triangle(const QVector<Vertex> *vertex_buffer, unsigned int u, unsigned int v, unsigned int w);
...@@ -58,6 +69,7 @@ class Triangle { ...@@ -58,6 +69,7 @@ class Triangle {
}; };
void ibToTriangles(QVector<Vertex> *vb, QVector<unsigned int> &ib, QVector<Triangle> &triangles); void ibToTriangles(QVector<Vertex> *vb, QVector<unsigned int> &ib, QVector<Triangle> &triangles);
void buildNeighborsMap(QVector<Triangle> &triangles, QMap<Triangle, Triangle::Neighbors> &neighbors);
QDebug operator<<(QDebug d, const Triangle &triangle); QDebug operator<<(QDebug d, const Triangle &triangle);
......
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