Cycles: Make all #include statements relative to cycles source directory
[blender.git] / intern / cycles / render / attribute.cpp
index 71a3cba681150382d407fd3aec610172f8d80741..e157a385904ad8809f1d3d553177ecb8147a159b 100644 (file)
  * limitations under the License.
  */
 
-#include "image.h"
-#include "mesh.h"
-#include "attribute.h"
+#include "render/image.h"
+#include "render/mesh.h"
+#include "render/attribute.h"
 
-#include "util_debug.h"
-#include "util_foreach.h"
-#include "util_transform.h"
+#include "util/util_debug.h"
+#include "util/util_foreach.h"
+#include "util/util_transform.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -44,6 +44,7 @@ void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
        type = type_;
        element = element_;
        std = ATTR_STD_NONE;
+       flags = 0;
 
        /* string and matrix not supported! */
        assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
@@ -51,16 +52,21 @@ void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
                type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix);
 }
 
-void Attribute::resize(int numverts, int numtris, int numsteps, int numcurves, int numkeys, bool reserve_only)
+void Attribute::resize(Mesh *mesh, AttributePrimitive prim, bool reserve_only)
 {
        if(reserve_only) {
-               buffer.reserve(buffer_size(numverts, numtris, numsteps, numcurves, numkeys));
+               buffer.reserve(buffer_size(mesh, prim));
        }
        else {
-               buffer.resize(buffer_size(numverts, numtris, numsteps, numcurves, numkeys), 0);
+               buffer.resize(buffer_size(mesh, prim), 0);
        }
 }
 
+void Attribute::resize(size_t num_elements)
+{
+       buffer.resize(num_elements * data_sizeof(), 0);
+}
+
 void Attribute::add(const float& f)
 {
        char *data = (char*)&f;
@@ -118,6 +124,8 @@ size_t Attribute::data_sizeof() const
 {
        if(element == ATTR_ELEMENT_VOXEL)
                return sizeof(VoxelAttribute);
+       else if(element == ATTR_ELEMENT_CORNER_BYTE)
+               return sizeof(uchar4);
        else if(type == TypeDesc::TypeFloat)
                return sizeof(float);
        else if(type == TypeDesc::TypeMatrix)
@@ -126,10 +134,14 @@ size_t Attribute::data_sizeof() const
                return sizeof(float3);
 }
 
-size_t Attribute::element_size(int numverts, int numtris, int numsteps, int numcurves, int numkeys) const
+size_t Attribute::element_size(Mesh *mesh, AttributePrimitive prim) const
 {
+       if(flags & ATTR_FINAL_SIZE) {
+               return buffer.size() / data_sizeof();
+       }
+
        size_t size;
-       
+
        switch(element) {
                case ATTR_ELEMENT_OBJECT:
                case ATTR_ELEMENT_MESH:
@@ -137,38 +149,54 @@ size_t Attribute::element_size(int numverts, int numtris, int numsteps, int numc
                        size = 1;
                        break;
                case ATTR_ELEMENT_VERTEX:
-                       size = numverts;
+                       size = mesh->verts.size() + mesh->num_ngons;
+                       if(prim == ATTR_PRIM_SUBD) {
+                               size -= mesh->num_subd_verts;
+                       }
                        break;
                case ATTR_ELEMENT_VERTEX_MOTION:
-                       size = numverts * (numsteps - 1);
+                       size = (mesh->verts.size() + mesh->num_ngons) * (mesh->motion_steps - 1);
+                       if(prim == ATTR_PRIM_SUBD) {
+                               size -= mesh->num_subd_verts * (mesh->motion_steps - 1);
+                       }
                        break;
                case ATTR_ELEMENT_FACE:
-                       size = numtris;
+                       if(prim == ATTR_PRIM_TRIANGLE) {
+                               size = mesh->num_triangles();
+                       }
+                       else {
+                               size = mesh->subd_faces.size() + mesh->num_ngons;
+                       }
                        break;
                case ATTR_ELEMENT_CORNER:
                case ATTR_ELEMENT_CORNER_BYTE:
-                       size = numtris*3;
+                       if(prim == ATTR_PRIM_TRIANGLE) {
+                               size = mesh->num_triangles()*3;
+                       }
+                       else {
+                               size = mesh->subd_face_corners.size() + mesh->num_ngons;
+                       }
                        break;
                case ATTR_ELEMENT_CURVE:
-                       size = numcurves;
+                       size = mesh->num_curves();
                        break;
                case ATTR_ELEMENT_CURVE_KEY:
-                       size = numkeys;
+                       size = mesh->curve_keys.size();
                        break;
                case ATTR_ELEMENT_CURVE_KEY_MOTION:
-                       size = numkeys * (numsteps - 1);
+                       size = mesh->curve_keys.size() * (mesh->motion_steps - 1);
                        break;
                default:
                        size = 0;
                        break;
        }
-       
+
        return size;
 }
 
-size_t Attribute::buffer_size(int numverts, int numtris, int numsteps, int numcurves, int numkeys) const
+size_t Attribute::buffer_size(Mesh *mesh, AttributePrimitive prim) const
 {
-       return element_size(numverts, numtris, numsteps, numcurves, numkeys)*data_sizeof();
+       return element_size(mesh, prim)*data_sizeof();
 }
 
 bool Attribute::same_storage(TypeDesc a, TypeDesc b)
@@ -188,6 +216,29 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b)
        return false;
 }
 
+void Attribute::zero_data(void* dst)
+{
+       memset(dst, 0, data_sizeof());
+}
+
+void Attribute::add_with_weight(void* dst, void* src, float weight)
+{
+       if(element == ATTR_ELEMENT_CORNER_BYTE) {
+               for(int i = 0; i < 4; i++) {
+                       ((uchar*)dst)[i] += uchar(((uchar*)src)[i] * weight);
+               }
+       }
+       else if(same_storage(type, TypeDesc::TypeFloat)) {
+               *((float*)dst) += *((float*)src) * weight;
+       }
+       else if(same_storage(type, TypeDesc::TypeVector)) {
+               *((float4*)dst) += *((float4*)src) * weight;
+       }
+       else {
+               assert(!"not implemented for this type");
+       }
+}
+
 const char *Attribute::standard_name(AttributeStandard std)
 {
        switch(std) {
@@ -257,6 +308,7 @@ AttributeSet::AttributeSet()
 {
        triangle_mesh = NULL;
        curve_mesh = NULL;
+       subd_mesh = NULL;
 }
 
 AttributeSet::~AttributeSet()
@@ -291,10 +343,12 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme
 
        /* this is weak .. */
        if(triangle_mesh)
-               attr->resize(triangle_mesh->verts.size(), triangle_mesh->num_triangles(), triangle_mesh->motion_steps, 0, 0, false);
+               attr->resize(triangle_mesh, ATTR_PRIM_TRIANGLE, false);
        if(curve_mesh)
-               attr->resize(0, 0, curve_mesh->motion_steps, curve_mesh->num_curves(), curve_mesh->curve_keys.size(), false);
-       
+               attr->resize(curve_mesh, ATTR_PRIM_CURVE, false);
+       if(subd_mesh)
+               attr->resize(subd_mesh, ATTR_PRIM_SUBD, false);
+
        return attr;
 }
 
@@ -330,7 +384,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
        if(name == ustring())
                name = Attribute::standard_name(std);
 
-       if(triangle_mesh) {
+       if(triangle_mesh || subd_mesh) {
                switch(std) {
                        case ATTR_STD_VERTEX_NORMAL:
                                attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX);
@@ -452,9 +506,11 @@ void AttributeSet::resize(bool reserve_only)
 {
        foreach(Attribute& attr, attributes) {
                if(triangle_mesh)
-                       attr.resize(triangle_mesh->verts.size(), triangle_mesh->num_triangles(), triangle_mesh->motion_steps, 0, 0, reserve_only);
+                       attr.resize(triangle_mesh, ATTR_PRIM_TRIANGLE, reserve_only);
                if(curve_mesh)
-                       attr.resize(0, 0, 0, curve_mesh->num_curves(), curve_mesh->curve_keys.size(), reserve_only);
+                       attr.resize(curve_mesh, ATTR_PRIM_CURVE, reserve_only);
+               if(subd_mesh)
+                       attr.resize(subd_mesh, ATTR_PRIM_SUBD, reserve_only);
        }
 }
 
@@ -471,12 +527,19 @@ AttributeRequest::AttributeRequest(ustring name_)
        std = ATTR_STD_NONE;
 
        triangle_type = TypeDesc::TypeFloat;
-       triangle_element = ATTR_ELEMENT_NONE;
-       triangle_offset = 0;
+       triangle_desc.element = ATTR_ELEMENT_NONE;
+       triangle_desc.offset = 0;
+       triangle_desc.type = NODE_ATTR_FLOAT;
 
        curve_type = TypeDesc::TypeFloat;
-       curve_element = ATTR_ELEMENT_NONE;
-       curve_offset = 0;
+       curve_desc.element = ATTR_ELEMENT_NONE;
+       curve_desc.offset = 0;
+       curve_desc.type = NODE_ATTR_FLOAT;
+
+       subd_type = TypeDesc::TypeFloat;
+       subd_desc.element = ATTR_ELEMENT_NONE;
+       subd_desc.offset = 0;
+       subd_desc.type = NODE_ATTR_FLOAT;
 }
 
 AttributeRequest::AttributeRequest(AttributeStandard std_)
@@ -485,12 +548,19 @@ AttributeRequest::AttributeRequest(AttributeStandard std_)
        std = std_;
 
        triangle_type = TypeDesc::TypeFloat;
-       triangle_element = ATTR_ELEMENT_NONE;
-       triangle_offset = 0;
+       triangle_desc.element = ATTR_ELEMENT_NONE;
+       triangle_desc.offset = 0;
+       triangle_desc.type = NODE_ATTR_FLOAT;
 
        curve_type = TypeDesc::TypeFloat;
-       curve_element = ATTR_ELEMENT_NONE;
-       curve_offset = 0;
+       curve_desc.element = ATTR_ELEMENT_NONE;
+       curve_desc.offset = 0;
+       curve_desc.type = NODE_ATTR_FLOAT;
+
+       subd_type = TypeDesc::TypeFloat;
+       subd_desc.element = ATTR_ELEMENT_NONE;
+       subd_desc.offset = 0;
+       subd_desc.type = NODE_ATTR_FLOAT;
 }
 
 /* AttributeRequestSet */