diff options
author | Nicholas Bishop <nicholasbishop@gmail.com> | 2015-02-10 20:37:57 +0300 |
---|---|---|
committer | Nicholas Bishop <nicholasbishop@gmail.com> | 2015-02-10 20:37:57 +0300 |
commit | 232fb32187b05af1baec035c99cb943d1670a593 (patch) | |
tree | 644fc7f027bfd2c493deea4a33cc54559926edcb /intern/cycles | |
parent | 27b23c326e7dce6750cd45f79966ce5a200da3a5 (diff) | |
parent | a9c5d0ba51f453e5ffc8d392970cff5d36b9501d (diff) |
Merge remote-tracking branch 'origin/master' into cycles-ptex-49
Conflicts:
intern/cycles/kernel/kernel_types.h
intern/cycles/render/attribute.cpp
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 64 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_geometry.osl | 5 | ||||
-rw-r--r-- | intern/cycles/render/attribute.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 16 |
5 files changed, 92 insertions, 2 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 01f7b34a29a..613d17120dd 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -28,6 +28,7 @@ #include "util_foreach.h" #include "util_logging.h" +#include "util_math.h" #include "mikktspace.h" @@ -473,6 +474,69 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< } } + /* create vertex pointiness attributes */ + /* TODO(sergey): Consider moving all the attribute creation into own + * functions for clarity. + */ + { + if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) { + Attribute *attr = mesh->attributes.add(ATTR_STD_POINTINESS); + float *data = attr->data_float(); + int *counter = new int[numverts]; + float *raw_data = new float[numverts]; + float3 *edge_accum = new float3[numverts]; + + /* Calculate pointiness using single ring neighborhood. */ + memset(counter, 0, sizeof(int) * numverts); + memset(raw_data, 0, sizeof(float) * numverts); + memset(edge_accum, 0, sizeof(float3) * numverts); + BL::Mesh::edges_iterator e; + i = 0; + for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) { + int v0 = b_mesh.edges[i].vertices()[0], + v1 = b_mesh.edges[i].vertices()[1]; + float3 co0 = get_float3(b_mesh.vertices[v0].co()), + co1 = get_float3(b_mesh.vertices[v1].co()); + float3 edge = normalize(co1 - co0); + edge_accum[v0] += edge; + edge_accum[v1] += -edge; + ++counter[v0]; + ++counter[v1]; + } + i = 0; + for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) { + if(counter[i] > 0) { + float3 normal = get_float3(b_mesh.vertices[i].normal()); + float angle = safe_acosf(dot(normal, edge_accum[i] / counter[i])); + raw_data[i] = angle * M_1_PI_F; + } + else { + raw_data[i] = 0.0f; + } + } + + /* Blur vertices to approximate 2 ring neighborhood. */ + memset(counter, 0, sizeof(int) * numverts); + memcpy(data, raw_data, sizeof(float) * numverts); + i = 0; + for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) { + int v0 = b_mesh.edges[i].vertices()[0], + v1 = b_mesh.edges[i].vertices()[1]; + data[v0] += raw_data[v1]; + data[v1] += raw_data[v0]; + ++counter[v0]; + ++counter[v1]; + } + for(i = 0; i < numverts; ++i) { + data[i] /= counter[i] + 1; + } + + delete [] counter; + delete [] raw_data; + delete [] edge_accum; + } + } + /* create uv map attributes */ if (b_mesh.tessface_uv_textures.length() != 0) { BL::Mesh::tessface_uv_textures_iterator l; diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 19452b97c30..54aa2f478b9 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -534,6 +534,7 @@ typedef enum AttributeStandard { ATTR_STD_VOLUME_FLAME, ATTR_STD_VOLUME_HEAT, ATTR_STD_VOLUME_VELOCITY, + ATTR_STD_POINTINESS, ATTR_STD_PTEX_LAYER, ATTR_STD_NUM, diff --git a/intern/cycles/kernel/shaders/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl index 580ccba8238..2bbaaff2133 100644 --- a/intern/cycles/kernel/shaders/node_geometry.osl +++ b/intern/cycles/kernel/shaders/node_geometry.osl @@ -26,7 +26,8 @@ shader node_geometry( output normal TrueNormal = normal(0.0, 0.0, 0.0), output vector Incoming = vector(0.0, 0.0, 0.0), output point Parametric = point(0.0, 0.0, 0.0), - output float Backfacing = 0.0) + output float Backfacing = 0.0, + output float Pointiness = 0.0) { Position = P; Normal = NormalIn; @@ -57,5 +58,7 @@ shader node_geometry( /* otherwise use surface derivatives */ Tangent = normalize(dPdu); } + + getattribute("geom:pointiness", Pointiness); } diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index fbd751fd778..22fe2075148 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -230,6 +230,8 @@ const char *Attribute::standard_name(AttributeStandard std) return "heat"; case ATTR_STD_VOLUME_VELOCITY: return "velocity"; + case ATTR_STD_POINTINESS: + return "pointiness"; case ATTR_STD_PTEX_LAYER: return "ptex_layer"; case ATTR_STD_NOT_FOUND: @@ -377,6 +379,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) case ATTR_STD_VOLUME_VELOCITY: attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_VOXEL); break; + case ATTR_STD_POINTINESS: + attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX); + break; case ATTR_STD_PTEX_LAYER: attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_MESH); break; @@ -400,6 +405,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) case ATTR_STD_GENERATED_TRANSFORM: attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH); break; + case ATTR_STD_POINTINESS: + attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX); + break; default: assert(0); break; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index c572cdde75d..aaf8d1d09d3 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2400,13 +2400,18 @@ GeometryNode::GeometryNode() add_output("Incoming", SHADER_SOCKET_VECTOR); add_output("Parametric", SHADER_SOCKET_POINT); add_output("Backfacing", SHADER_SOCKET_FLOAT); + add_output("Pointiness", SHADER_SOCKET_FLOAT); } void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes) { if(shader->has_surface) { - if(!output("Tangent")->links.empty()) + if(!output("Tangent")->links.empty()) { attributes->add(ATTR_STD_GENERATED); + } + if(!output("Pointiness")->links.empty()) { + attributes->add(ATTR_STD_POINTINESS); + } } ShaderNode::attributes(shader, attributes); @@ -2463,6 +2468,15 @@ void GeometryNode::compile(SVMCompiler& compiler) compiler.stack_assign(out); compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, out->stack_offset); } + + out = output("Pointiness"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_ATTR, + ATTR_STD_POINTINESS, + out->stack_offset, + NODE_ATTR_FLOAT); + } } void GeometryNode::compile(OSLCompiler& compiler) |