Commit 8d23b49c by Alisa Jung Committed by Philipp Adolf

sharp edges: different mask types depending on edge vertices

parent c58d06a0
......@@ -25,7 +25,14 @@ layout(std430, binding=3) readonly buffer OutputOffset {
};
layout(std430, binding=4) readonly buffer EdgeSharpness {
unsigned int sharpness[];
unsigned int sharpness[];//1st value: is sharp? 2nd value: mask type.
/*
0: no sharpness, smooth edge mask
1: sharp, but still use smooth edge mask
2: regular crease edge mask
3: non-regular crease edge mask, weight 5 for first index, 3 for second
4: non-regular crease edge mask, weight 3 for first index, 5 for second
*/
};
void main(){
......@@ -39,13 +46,29 @@ void main(){
unsigned int s = sharpness[gl_GlobalInvocationID.x];
vec3 pos;
if (s > 0){
edges[output_offset + gl_GlobalInvocationID.x].pos = 0.5f*a.pos + 0.5f*b.pos;
edges[output_offset + gl_GlobalInvocationID.x].norm = normalize(0.5f*a.norm + 0.5f*b.norm);
vec3 norm;
if (s == 0 || s == 1){
pos = 3.0f/8.0f * a.pos + 3.0f/8.0f * b.pos + 1.0f/8.0f * c.pos + 1.0f/8.0f * d.pos;
norm = normalize(3.0f/8.0f * a.norm + 3.0f/8.0f * b.norm + 1.0f/8.0f * c.norm + 1.0f/8.0f * d.norm);
}
else if (s == 2){
pos = 0.5f*a.pos + 0.5f*b.pos;
norm = normalize(0.5f*a.norm + 0.5f*b.norm);
}
else if (s == 3){
pos = 0.725f*a.pos + 0.375f*b.pos;
norm = normalize(0.725f*a.norm + 0.375f*b.norm);
}
else if (s == 4){
pos = 0.375f*a.pos + 0.725f*b.pos;
norm = normalize(0.375f*a.norm + 0.725f*b.norm);
}
else {
edges[output_offset + gl_GlobalInvocationID.x].pos = 3.0f/8.0f * a.pos + 3.0f/8.0f * b.pos + 1.0f/8.0f * c.pos + 1.0f/8.0f * d.pos;
edges[output_offset + gl_GlobalInvocationID.x].norm = normalize(3.0f/8.0f * a.norm + 3.0f/8.0f * b.norm + 1.0f/8.0f * c.norm + 1.0f/8.0f * d.norm);
pos = vec3(0,0,0);
norm = vec3(1,0,0);
}
edges[output_offset + gl_GlobalInvocationID.x].pos = pos;
edges[output_offset + gl_GlobalInvocationID.x].norm = norm;
}
......@@ -139,7 +139,7 @@ void Subdivision::subdivide(Mesh *mesh, int level) {
*
* sharpEdges: Vorher leer, wird sonst geleert, wird gefüllt mit neuen sharp edges, alte sollten im Input stehen.
*/
Subdivision::Tables Subdivision::precomputeTables(Input input) {
Subdivision::Tables Subdivision::precomputeTables(Input& input) {
Tables tables;
QVector<unsigned int> ib = input.index_irregular_buffer;
......@@ -192,6 +192,122 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) {
subTimer.restart();
updateSharpEdges(input.sharp_edges,tables.sharp_edges,modified_vertices,old_edge_to_new_vertex);
qCDebug(log_timing) << "updateSharpEdges: " << formatTimeMeasurement(subTimer.elapsed());
subTimer.restart();
for(Triangle t : triangles){
if (t.has_sharp_edge()){
Edge uv(t.u_idx(),t.v_idx());
Edge vw(t.v_idx(),t.w_idx());
Edge wu(t.w_idx(),t.u_idx());
Triangle::Neighbors ns = neighbors[t];
QVector<Triangle::Neighbor> n_uvw;
n_uvw.push_back(ns.get_neighbor(Triangle::Edge::Name::uv));
n_uvw.push_back(ns.get_neighbor(Triangle::Edge::Name::vw));
n_uvw.push_back(ns.get_neighbor(Triangle::Edge::Name::wu));
int sharpnessCounter[3] = {0,0,0};
if (t.get_sharpness_uv()>0) sharpnessCounter[0]++;
if (t.get_sharpness_vw()>0) sharpnessCounter[1]++;
if (t.get_sharpness_wu()>0) sharpnessCounter[2]++;
bool thirdEdgeIsSharp[3] = {false,false,false};
int loopCounter[3] = {0,0,0};
for (int i = 0; i < n_uvw.size(); i++){
Triangle::Neighbor n = n_uvw[i];
while (*n.triangle != t) {
loopCounter[i]++;
switch (n.edge.name) {
case Triangle::Edge::Name::uv:
if (n.triangle->get_sharpness_vw()){
if (loopCounter[i] == 3) thirdEdgeIsSharp[i] = true;
sharpnessCounter[i]++;
}
break;
case Triangle::Edge::Name::vw:
if (n.triangle->get_sharpness_wu()){
if (loopCounter[i] == 3) thirdEdgeIsSharp[i] = true;
sharpnessCounter[i]++;
}
break;
case Triangle::Edge::Name::wu:
if (n.triangle->get_sharpness_uv()){
if (loopCounter[i] == 3) thirdEdgeIsSharp[i] = true;
sharpnessCounter[i]++;
}
break;
}
n = neighbors.value(*n.triangle).get_neighbor(rotate_edge_name(n.edge.name));
}
}
bool u_is_regular = (thirdEdgeIsSharp[0] &&
loopCounter[0] == 5 &&
t.get_sharpness_uv() &&
sharpnessCounter[0] == 2);
bool u_is_dart = sharpnessCounter[0] == 1;
bool u_is_corner = sharpnessCounter[0] >= 3;
bool u_non_regular = sharpnessCounter[0] == 2 && !u_is_regular;
bool v_is_regular = (thirdEdgeIsSharp[1] &&
loopCounter[1] == 5 &&
t.get_sharpness_vw() &&
sharpnessCounter[1] == 2);
bool v_is_dart = sharpnessCounter[1] == 1;
bool v_is_corner = sharpnessCounter[1] >= 3;
bool v_non_regular = sharpnessCounter[1] == 2 && !v_is_regular;
bool w_is_regular = (thirdEdgeIsSharp[2] &&
loopCounter[2] == 5 &&
t.get_sharpness_wu() &&
sharpnessCounter[2] == 2);
bool w_is_dart = sharpnessCounter[2] == 1;
bool w_is_corner = sharpnessCounter[2] >= 3;
bool w_non_regular = sharpnessCounter[2] == 2 && !w_is_regular;
if (t.get_sharpness_uv() > 0){
if (!input.sharp_edge_mask_types.contains(uv)){
if (u_is_dart || v_is_dart){
input.sharp_edge_mask_types.insert(uv,1);
} else if (u_is_regular && (v_non_regular || v_is_corner)){
input.sharp_edge_mask_types.insert(uv,3);
} else if (v_is_regular && (u_non_regular || u_is_corner)){
input.sharp_edge_mask_types.insert(uv,4);
} else {
input.sharp_edge_mask_types.insert(uv,2);
}
}
}
if (t.get_sharpness_wu() > 0){
if (!input.sharp_edge_mask_types.contains(wu)){
if (w_is_dart || u_is_dart){
input.sharp_edge_mask_types.insert(wu,1);
} else if (w_is_regular && (u_non_regular || u_is_corner)){
input.sharp_edge_mask_types.insert(wu,3);
} else if (u_is_regular && (w_non_regular || w_is_corner)){
input.sharp_edge_mask_types.insert(wu,4);
} else {
input.sharp_edge_mask_types.insert(wu,2);
}
}
}
if (t.get_sharpness_vw() > 0){
if (!input.sharp_edge_mask_types.contains(vw)){
if (v_is_dart || w_is_dart){
input.sharp_edge_mask_types.insert(vw,1);
} else if (v_is_regular && (w_non_regular || w_is_corner)){
input.sharp_edge_mask_types.insert(vw,3);
} else if (w_is_regular && (v_non_regular || v_is_corner)){
input.sharp_edge_mask_types.insert(vw,4);
} else {
input.sharp_edge_mask_types.insert(vw,2);
}
}
}
}
}
qCDebug(log_subdiv) << "Precompute Tables Done";
return tables;
......@@ -779,9 +895,9 @@ void Subdivision::splitRegular(Mesh *mesh) {
QVector<Triangle> all_triangles;
ibToTriangles(&current_mesh->buffers[0]->vertices,
current_mesh->buffers[0]->indices_irregular,
current_mesh->buffers[0]->m_sharp_edges,
all_triangles);
current_mesh->buffers[0]->indices_irregular,
current_mesh->buffers[0]->m_sharp_edges,
all_triangles);
QVector<unsigned int> old_regular_ib = patchIBToTriangleIB(current_mesh->buffers[0]->indices_regular);
regularIbToTriangles(&current_mesh->buffers[0]->vertices, old_regular_ib, all_triangles);
......@@ -1005,13 +1121,7 @@ Subdivision::Result Subdivision::runShader(Input input, Tables &tables) {
unsigned int u = tables.edge_indices[i];
unsigned int v = tables.edge_indices[i+1];
Edge uv(u,v);
Edge vu(v,u);
if (input.sharp_edges.contains(uv)){
sharpness.push_back(input.sharp_edges[uv]);
}else if (input.sharp_edges.contains(vu)){
sharpness.push_back(input.sharp_edges[vu]);
}
else sharpness.push_back(0);
sharpness.push_back(input.sharp_edge_mask_types.value(uv,0));
}
qCWarning(log_subdiv_trace)<<"Sharpness: "<< sharpness;
GLuint edge_sharpness_handle;
......
......@@ -25,6 +25,7 @@ private:
QVector<unsigned int> index_irregular_buffer;
QVector<unsigned int> index_regular_buffer;
QMap<Edge,unsigned int> sharp_edges;
QMap<Edge, unsigned int> sharp_edge_mask_types;
QVector<Vertex> vertex_buffer;
};
......@@ -62,7 +63,7 @@ private:
QOpenGLShaderProgram *vertexShader;
QOpenGLShaderProgram *initComputeShaderProgram(QString &source);
Tables precomputeTables(Input input);
Tables precomputeTables(Input& input);
void buildNeighborsMap(QVector<Vertex> &vb, QVector<Triangle> &triangles, QMap<Triangle, Triangle::Neighbors> &neighbors);
QVector<Triangle> vertexNeighbors(Triangle &triangle, Triangle::Neighbor current_neighbor, QMap<Triangle, Triangle::Neighbors> neighbors);
void precomputeEdgeTable(Subdivision::Tables &tables,
......
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