diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2014-03-29 16:03:48 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2014-03-29 16:03:48 +0400 |
commit | 27043b8e40f74c8b0917850d1aefbd6315fa46a5 (patch) | |
tree | 26360d0ab051bb94312e40fef974851f3c20f6e0 /intern/cycles/render | |
parent | 393216a6df934a78f541d98def7a948a89f9b5c8 (diff) |
Cycles code internals: add support for mesh voxel grid attributes.
These are internally stored as a 3D image textures, but accessible like e.g.
UV coordinates though the attribute node and getattribute().
This is convenient for rendering e.g. smoke objects where data like density is
really a property of the mesh, and it avoids having to specify the smoke object
in a texture node, instead the material will work with any smoke domain.
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/attribute.cpp | 101 | ||||
-rw-r--r-- | intern/cycles/render/attribute.h | 15 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 7 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 41 |
4 files changed, 118 insertions, 46 deletions
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index f524a9fa3bc..cd81c33a28f 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -14,6 +14,7 @@ * limitations under the License */ +#include "image.h" #include "mesh.h" #include "attribute.h" @@ -25,6 +26,17 @@ CCL_NAMESPACE_BEGIN /* Attribute */ +Attribute::~Attribute() +{ + /* for voxel data, we need to remove the image from the image manager */ + if(element == ATTR_ELEMENT_VOXEL) { + VoxelAttribute *voxel_data = data_voxel(); + + if(voxel_data) + voxel_data->manager->remove_image(voxel_data->slot); + } +} + void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_) { name = name_; @@ -75,9 +87,20 @@ void Attribute::add(const Transform& f) buffer.push_back(data[i]); } +void Attribute::add(const VoxelAttribute& f) +{ + char *data = (char*)&f; + size_t size = sizeof(f); + + for(size_t i = 0; i < size; i++) + buffer.push_back(data[i]); +} + size_t Attribute::data_sizeof() const { - if(type == TypeDesc::TypeFloat) + if(element == ATTR_ELEMENT_VOXEL) + return sizeof(VoxelAttribute); + else if(type == TypeDesc::TypeFloat) return sizeof(float); else if(type == TypeDesc::TypeMatrix) return sizeof(Transform); @@ -92,6 +115,7 @@ size_t Attribute::element_size(int numverts, int numtris, int numsteps, int numc switch(element) { case ATTR_ELEMENT_OBJECT: case ATTR_ELEMENT_MESH: + case ATTR_ELEMENT_VOXEL: size = 1; break; case ATTR_ELEMENT_VERTEX: @@ -147,40 +171,55 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b) const char *Attribute::standard_name(AttributeStandard std) { - if(std == ATTR_STD_VERTEX_NORMAL) - return "N"; - else if(std == ATTR_STD_FACE_NORMAL) - return "Ng"; - else if(std == ATTR_STD_UV) - return "uv"; - else if(std == ATTR_STD_GENERATED) - return "generated"; - else if(std == ATTR_STD_UV_TANGENT) - return "tangent"; - else if(std == ATTR_STD_UV_TANGENT_SIGN) - return "tangent_sign"; - else if(std == ATTR_STD_POSITION_UNDEFORMED) - return "undeformed"; - else if(std == ATTR_STD_POSITION_UNDISPLACED) - return "undisplaced"; - else if(std == ATTR_STD_MOTION_VERTEX_POSITION) - return "motion_P"; - else if(std == ATTR_STD_MOTION_VERTEX_NORMAL) - return "motion_N"; - else if(std == ATTR_STD_PARTICLE) - return "particle"; - else if(std == ATTR_STD_CURVE_INTERCEPT) - return "curve_intercept"; - else if(std == ATTR_STD_PTEX_FACE_ID) - return "ptex_face_id"; - else if(std == ATTR_STD_PTEX_UV) - return "ptex_uv"; - else if(std == ATTR_STD_GENERATED_TRANSFORM) - return "generated_transform"; + switch(std) { + case ATTR_STD_VERTEX_NORMAL: + return "N"; + case ATTR_STD_FACE_NORMAL: + return "Ng"; + case ATTR_STD_UV: + return "uv"; + case ATTR_STD_GENERATED: + return "generated"; + case ATTR_STD_GENERATED_TRANSFORM: + return "generated_transform"; + case ATTR_STD_UV_TANGENT: + return "tangent"; + case ATTR_STD_UV_TANGENT_SIGN: + return "tangent_sign"; + case ATTR_STD_POSITION_UNDEFORMED: + return "undeformed"; + case ATTR_STD_POSITION_UNDISPLACED: + return "undisplaced"; + case ATTR_STD_MOTION_VERTEX_POSITION: + return "motion_P"; + case ATTR_STD_MOTION_VERTEX_NORMAL: + return "motion_N"; + case ATTR_STD_PARTICLE: + return "particle"; + case ATTR_STD_CURVE_INTERCEPT: + return "curve_intercept"; + case ATTR_STD_PTEX_FACE_ID: + return "ptex_face_id"; + case ATTR_STD_PTEX_UV: + return "ptex_uv"; + case ATTR_STD_NOT_FOUND: + case ATTR_STD_NONE: + case ATTR_STD_NUM: + return ""; + } return ""; } +AttributeStandard Attribute::name_standard(const char *name) +{ + for(AttributeStandard std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++) + if(strcmp(name, Attribute::standard_name(std)) == 0) + return std; + + return ATTR_STD_NONE; +} + /* Attribute Set */ AttributeSet::AttributeSet() diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h index 5160224f4e3..3dc7b7f7401 100644 --- a/intern/cycles/render/attribute.h +++ b/intern/cycles/render/attribute.h @@ -27,12 +27,20 @@ CCL_NAMESPACE_BEGIN class Attribute; -class AttributeSet; class AttributeRequest; class AttributeRequestSet; +class AttributeSet; +class ImageManager; class Mesh; struct Transform; +/* Attributes for voxels are images */ + +struct VoxelAttribute { + ImageManager *manager; + int slot; +}; + /* Attribute * * Arbitrary data layers on meshes. @@ -48,6 +56,7 @@ public: AttributeElement element; Attribute() {} + ~Attribute(); void set(ustring name, TypeDesc type, AttributeElement element); void reserve(int numverts, int numfaces, int numsteps, int numcurves, int numkeys, bool resize); @@ -60,19 +69,23 @@ public: float4 *data_float4() { return (float4*)data(); } float *data_float() { return (float*)data(); } Transform *data_transform() { return (Transform*)data(); } + VoxelAttribute *data_voxel() { return ( VoxelAttribute*)data(); } const char *data() const { return (buffer.size())? &buffer[0]: NULL; } const float3 *data_float3() const { return (const float3*)data(); } const float4 *data_float4() const { return (const float4*)data(); } const float *data_float() const { return (const float*)data(); } const Transform *data_transform() const { return (const Transform*)data(); } + const VoxelAttribute *data_voxel() const { return (const VoxelAttribute*)data(); } void add(const float& f); void add(const float3& f); void add(const Transform& f); + void add(const VoxelAttribute& f); static bool same_storage(TypeDesc a, TypeDesc b); static const char *standard_name(AttributeStandard std); + static AttributeStandard name_standard(const char *name); }; /* Attribute Set diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 52cd946456f..2ae15e09efb 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -756,7 +756,12 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa mesh->curves.size(), mesh->curve_keys.size()); - if(mattr->type == TypeDesc::TypeFloat) { + if(mattr->element == ATTR_ELEMENT_VOXEL) { + /* store slot in offset value */ + VoxelAttribute *voxel_data = mattr->data_voxel(); + offset = voxel_data->slot; + } + else if(mattr->type == TypeDesc::TypeFloat) { float *data = mattr->data_float(); offset = attr_float.size(); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index d5e358be161..f10b956a482 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2209,8 +2209,9 @@ void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attr if(shader->has_volume) { if(!from_dupli) { - if(!output("Generated")->links.empty()) + if(!output("Generated")->links.empty()) { attributes->add(ATTR_STD_GENERATED_TRANSFORM); + } } } @@ -2629,7 +2630,7 @@ void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) if(!intercept_out->links.empty()) attributes->add(ATTR_STD_CURVE_INTERCEPT); } - + ShaderNode::attributes(shader, attributes); } @@ -3143,15 +3144,22 @@ AttributeNode::AttributeNode() void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - if(shader->has_surface) { - ShaderOutput *color_out = output("Color"); - ShaderOutput *vector_out = output("Vector"); - ShaderOutput *fac_out = output("Fac"); + ShaderOutput *color_out = output("Color"); + ShaderOutput *vector_out = output("Vector"); + ShaderOutput *fac_out = output("Fac"); - if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) + if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) { + AttributeStandard std = Attribute::name_standard(attribute.c_str()); + + if(std != ATTR_STD_NONE) + attributes->add(std); + else attributes->add(attribute); } - + + if(shader->has_volume) + attributes->add(ATTR_STD_GENERATED_TRANSFORM); + ShaderNode::attributes(shader, attributes); } @@ -3161,6 +3169,13 @@ void AttributeNode::compile(SVMCompiler& compiler) ShaderOutput *vector_out = output("Vector"); ShaderOutput *fac_out = output("Fac"); NodeType attr_node = NODE_ATTR; + AttributeStandard std = Attribute::name_standard(attribute.c_str()); + int attr; + + if(std != ATTR_STD_NONE) + attr = compiler.attribute(std); + else + attr = compiler.attribute(attribute); if(bump == SHADER_BUMP_DX) attr_node = NODE_ATTR_BUMP_DX; @@ -3168,8 +3183,6 @@ void AttributeNode::compile(SVMCompiler& compiler) attr_node = NODE_ATTR_BUMP_DY; if(!color_out->links.empty() || !vector_out->links.empty()) { - int attr = compiler.attribute(attribute); - if(!color_out->links.empty()) { compiler.stack_assign(color_out); compiler.add_node(attr_node, attr, color_out->stack_offset, NODE_ATTR_FLOAT3); @@ -3181,8 +3194,6 @@ void AttributeNode::compile(SVMCompiler& compiler) } if(!fac_out->links.empty()) { - int attr = compiler.attribute(attribute); - compiler.stack_assign(fac_out); compiler.add_node(attr_node, attr, fac_out->stack_offset, NODE_ATTR_FLOAT); } @@ -3196,8 +3207,12 @@ void AttributeNode::compile(OSLCompiler& compiler) compiler.parameter("bump_offset", "dy"); else compiler.parameter("bump_offset", "center"); + + if(Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE) + compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str()); + else + compiler.parameter("name", attribute.c_str()); - compiler.parameter("name", attribute.c_str()); compiler.add(this, "node_attribute"); } |