Cycles:
[blender.git] / intern / cycles / blender / blender_mesh.cpp
index c9748756d4336cc8cc8807a6a2a6004bfceb18fc..d628fa04f92170fb8ec772f39e26187fff25a485 100644 (file)
@@ -82,15 +82,21 @@ static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float
        MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
        BL::MeshTextureFace tf = userdata->layer.data[face_num];
        float3 tfuv;
-
-       if(vert_num == 0)
-               tfuv = get_float3(tf.uv1());
-       else if(vert_num == 1)
-               tfuv = get_float3(tf.uv2());
-       else if(vert_num == 2)
-               tfuv = get_float3(tf.uv3());
-       else
-               tfuv = get_float3(tf.uv4());
+       
+       switch (vert_num) {
+               case 0:
+                       tfuv = get_float3(tf.uv1());
+                       break;
+               case 1:
+                       tfuv = get_float3(tf.uv2());
+                       break;
+               case 2:
+                       tfuv = get_float3(tf.uv3());
+                       break;
+               default:
+                       tfuv = get_float3(tf.uv4());
+                       break;
+       }
        
        uv[0] = tfuv.x;
        uv[1] = tfuv.y;
@@ -100,9 +106,16 @@ static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3], const
 {
        MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
        BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
-       int4 vi = get_int4(f.vertices_raw());
-       BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]];
-       float3 vN = get_float3(v.normal());
+       float3 vN;
+
+       if(f.use_smooth()) {
+               int4 vi = get_int4(f.vertices_raw());
+               BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]];
+               vN = get_float3(v.normal());
+       }
+       else {
+               vN = get_float3(f.normal());
+       }
 
        N[0] = vN.x;
        N[1] = vN.y;
@@ -147,7 +160,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
        if(active_render)
                attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
        else
-               attr = mesh->attributes.add(name, TypeDesc::TypeVector, Attribute::CORNER);
+               attr = mesh->attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
 
        float3 *tangent = attr->data_float3();
 
@@ -161,7 +174,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
                if(active_render)
                        attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
                else
-                       attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, Attribute::CORNER);
+                       attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
 
                tangent_sign = attr_sign->data_float();
        }
@@ -223,10 +236,19 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
                int shader = used_shaders[mi];
                bool smooth = f->use_smooth();
 
-               mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
-
-               if(n == 4)
-                       mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
+               if(n == 4) {
+                       if(len_squared(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) == 0.0f ||
+                               len_squared(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])) == 0.0f) {
+                               mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth);
+                               mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth);
+                       }
+                       else {
+                               mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
+                               mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
+                       }
+               }
+               else
+                       mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
 
                nverts.push_back(n);
        }
@@ -240,7 +262,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
                                continue;
 
                        Attribute *attr = mesh->attributes.add(
-                               ustring(l->name().c_str()), TypeDesc::TypeColor, Attribute::CORNER);
+                               ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER);
 
                        BL::MeshColorLayer::data_iterator c;
                        float3 *fdata = attr->data_float3();
@@ -279,7 +301,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
                                if(active_render)
                                        attr = mesh->attributes.add(std, name);
                                else
-                                       attr = mesh->attributes.add(name, TypeDesc::TypePoint, Attribute::CORNER);
+                                       attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
 
                                BL::MeshTextureFaceLayer::data_iterator t;
                                float3 *fdata = attr->data_float3();
@@ -304,7 +326,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
                        std = (active_render)? ATTR_STD_UV_TANGENT: ATTR_STD_NONE;
                        name = ustring((string(l->name().c_str()) + ".tangent").c_str());
 
-                       if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
+                       if(mesh->need_attribute(scene, name) || (active_render && mesh->need_attribute(scene, std))) {
                                std = (active_render)? ATTR_STD_UV_TANGENT_SIGN: ATTR_STD_NONE;
                                name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
                                bool need_sign = (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std));
@@ -319,20 +341,15 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
         * is available in the api. */
        if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
                Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
-               float3 loc = get_float3(b_mesh.texspace_location());
-               float3 size = get_float3(b_mesh.texspace_size());
 
-               if(size.x != 0.0f) size.x = 0.5f/size.x;
-               if(size.y != 0.0f) size.y = 0.5f/size.y;
-               if(size.z != 0.0f) size.z = 0.5f/size.z;
-
-               loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+               float3 loc, size;
+               mesh_texture_space(b_mesh, loc, size);
 
                float3 *generated = attr->data_float3();
                size_t i = 0;
 
                for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
-                       generated[i++] = get_float3(v->co())*size - loc;
+                       generated[i++] = get_float3(v->undeformed_co())*size - loc;
        }
 }
 
@@ -376,7 +393,7 @@ static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, con
 
 /* Sync */
 
-Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
+Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris)
 {
        /* test if we can instance or if the object is modified */
        BL::ID b_ob_data = b_ob.data();
@@ -431,28 +448,41 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
        mesh_synced.insert(mesh);
 
        /* create derived mesh */
-       BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview);
+       bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
        PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles");
 
        vector<Mesh::Triangle> oldtriangle = mesh->triangles;
+       
+       /* compares curve_keys rather than strands in order to handle quick hair
+        * adjustsments in dynamic BVH - other methods could probably do this better*/
+       vector<Mesh::CurveKey> oldcurve_keys = mesh->curve_keys;
 
        mesh->clear();
        mesh->used_shaders = used_shaders;
        mesh->name = ustring(b_ob_data.name().c_str());
 
-       if(b_mesh) {
-               if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
-                       create_subd_mesh(mesh, b_mesh, &cmesh, used_shaders);
-               else
-                       create_mesh(scene, mesh, b_mesh, used_shaders);
+       if(render_layer.use_surfaces || render_layer.use_hair) {
+               BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed);
 
-               /* free derived mesh */
-               b_data.meshes.remove(b_mesh);
+               if(b_mesh) {
+                       if(render_layer.use_surfaces && !(hide_tris && experimental)) {
+                               if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
+                                       create_subd_mesh(mesh, b_mesh, &cmesh, used_shaders);
+                               else
+                                       create_mesh(scene, mesh, b_mesh, used_shaders);
+                       }
+
+                       if(render_layer.use_hair && experimental)
+                               sync_curves(mesh, b_mesh, b_ob, object_updated);
+
+                       /* free derived mesh */
+                       b_data.meshes.remove(b_mesh);
+               }
        }
 
        /* displacement method */
        if(cmesh.data) {
-               int method = RNA_enum_get(&cmesh, "displacement_method");
+               const int method = RNA_enum_get(&cmesh, "displacement_method");
 
                if(method == 0 || !experimental)
                        mesh->displacement_method = Mesh::DISPLACE_BUMP;
@@ -471,6 +501,13 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
                if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(Mesh::Triangle)*oldtriangle.size()) != 0)
                        rebuild = true;
        }
+
+       if(oldcurve_keys.size() != mesh->curve_keys.size())
+               rebuild = true;
+       else if(oldcurve_keys.size()) {
+               if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(Mesh::CurveKey)*oldcurve_keys.size()) != 0)
+                       rebuild = true;
+       }
        
        mesh->tag_update(scene, rebuild);
 
@@ -488,7 +525,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion)
                return;
 
        /* get derived mesh */
-       BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview);
+       BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false);
 
        if(b_mesh) {
                BL::Mesh::vertices_iterator v;