[Bf-blender-cvs] [e29698d] master: Split Normals I (5/5): Add support of split normals to Cycles.

Bastien Montagne noreply at git.blender.org
Sun Apr 13 15:39:07 CEST 2014


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();




More information about the Bf-blender-cvs mailing list