Commit: e29698d3cdeb57b4a765d9c3c7ce2a3bb37606fb
Author: Bastien Montagne
Date:   Sun Apr 13 12:51:06 2014 +0200
https://developer.blender.org/rBe29698d3cdeb57b4a765d9c3c7ce2a3bb37606fb

Split Normals I (5/5): Add support of split normals to Cycles.

Idea and code by Brecht, many thanks!

Reviewers: brecht

Reviewed By: brecht

CC: campbellbarton, dingto

Differential Revision: https://developer.blender.org/D369

===================================================================

M       intern/cycles/blender/blender_mesh.cpp
M       intern/cycles/blender/blender_util.h
M       intern/cycles/render/attribute.cpp
M       intern/cycles/render/attribute.h
M       intern/cycles/render/mesh.cpp
M       intern/cycles/render/mesh.h

===================================================================

diff --git a/intern/cycles/blender/blender_mesh.cpp 
b/intern/cycles/blender/blender_mesh.cpp
index fb667d1..dce1109 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -248,6 +248,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh 
b_mesh, const vector<
        int numverts = b_mesh.vertices.length();
        int numfaces = b_mesh.tessfaces.length();
        int numtris = 0;
+       bool use_loop_normals = b_mesh.use_auto_smooth();
 
        BL::Mesh::vertices_iterator v;
        BL::Mesh::tessfaces_iterator f;
@@ -271,6 +272,20 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh 
b_mesh, const vector<
        for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
                *N = get_float3(v->normal());
 
+       /* create generated coordinates from undeformed coordinates */
+       if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+               Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
+
+               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->undeformed_co())*size - 
loc;
+       }
+
        /* create faces */
        vector<int> nverts(numfaces);
        int fi = 0, ti = 0;
@@ -282,6 +297,28 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh 
b_mesh, const vector<
                int shader = used_shaders[mi];
                bool smooth = f->use_smooth();
 
+               /* split vertices if normal is different
+                *
+                * note all vertex attributes must have been set here so we can 
split
+                * and copy attributes in split_vertex without remapping later 
*/
+               if(use_loop_normals) {
+                       BL::Array<float, 12> loop_normals = f->split_normals();
+
+                       for(int i = 0; i < n; i++) {
+                               float3 loop_N = make_float3(loop_normals[i * 
3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
+
+                               if(N[vi[i]] != loop_N) {
+                                       int new_vi = mesh->split_vertex(vi[i]);
+
+                                       /* set new normal and vertex index */
+                                       N = attr_N->data_float3();
+                                       N[new_vi] = loop_N;
+                                       vi[i] = new_vi;
+                               }
+                       }
+               }
+
+               /* create triangles */
                if(n == 4) {
                        if(is_zero(cross(mesh->verts[vi[1]] - 
mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) ||
                                is_zero(cross(mesh->verts[vi[2]] - 
mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]]))) {
@@ -382,20 +419,6 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh 
b_mesh, const vector<
                }
        }
 
-       /* create generated coordinates from undeformed coordinates */
-       if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
-               Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
-
-               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->undeformed_co())*size - 
loc;
-       }
-
        /* for volume objects, create a matrix to transform from object space to
         * mesh texture space. this does not work with deformations but that can
         * probably only be done well with a volume grid mapping of coordinates 
*/
diff --git a/intern/cycles/blender/blender_util.h 
b/intern/cycles/blender/blender_util.h
index 45ca0e1..b2046b2 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -42,7 +42,12 @@ void python_thread_state_restore(void **python_thread_state);
 
 static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, 
BL::Scene scene, bool apply_modifiers, bool render, bool calc_undeformed)
 {
-       return data.meshes.new_from_object(scene, object, apply_modifiers, 
(render)? 2: 1, true, calc_undeformed);
+       BL::Mesh me = data.meshes.new_from_object(scene, object, 
apply_modifiers, (render)? 2: 1, false, calc_undeformed);
+       if (me.use_auto_smooth()) {
+               me.calc_normals_split(me.auto_smooth_angle());
+       }
+       me.calc_tessface();
+       return me;
 }
 
 static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int 
size)
diff --git a/intern/cycles/render/attribute.cpp 
b/intern/cycles/render/attribute.cpp
index ce232e9..14805b6 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -96,6 +96,14 @@ void Attribute::add(const VoxelAttribute& f)
                buffer.push_back(data[i]);
 }
 
+void Attribute::add(const char *data)
+{
+       size_t size = data_sizeof();
+
+       for(size_t i = 0; i < size; i++)
+               buffer.push_back(data[i]);
+}
+
 size_t Attribute::data_sizeof() const
 {
        if(element == ATTR_ELEMENT_VOXEL)
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index 3dc7b7f..9fc32db 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -82,6 +82,7 @@ public:
        void add(const float3& f);
        void add(const Transform& f);
        void add(const VoxelAttribute& f);
+       void add(const char *data);
 
        static bool same_storage(TypeDesc a, TypeDesc b);
        static const char *standard_name(AttributeStandard std);
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 2ae15e0..ddcc42a 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -134,6 +134,22 @@ void Mesh::clear()
        transform_normal = transform_identity();
 }
 
+int Mesh::split_vertex(int vertex)
+{
+       /* copy vertex location and vertex attributes */
+       verts.push_back(verts[vertex]);
+
+       foreach(Attribute& attr, attributes.attributes) {
+               if(attr.element == ATTR_ELEMENT_VERTEX) {
+                       vector<char> tmp(attr.data_sizeof());
+                       memcpy(&tmp[0], attr.data() + tmp.size()*vertex, 
tmp.size());
+                       attr.add(&tmp[0]);
+               }
+       }
+
+       return verts.size() - 1;
+}
+
 void Mesh::set_triangle(int i, int v0, int v1, int v2, int shader_, bool 
smooth_)
 {
        Triangle tri;
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index eec20ac..247e3dd 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -114,6 +114,7 @@ public:
        void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
        void add_curve_key(float3 loc, float radius);
        void add_curve(int first_key, int num_keys, int shader);
+       int split_vertex(int vertex);
 
        void compute_bounds();
        void add_face_normals();

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to