Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2014-04-13 14:51:06 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2014-04-13 14:51:13 +0400
commite29698d3cdeb57b4a765d9c3c7ce2a3bb37606fb (patch)
tree2137956ccc06095765311a5df94c5ea49eb6ec46 /intern
parent776f8d5a6fa00403e6c46887fbb19956edbd4f05 (diff)
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
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_mesh.cpp51
-rw-r--r--intern/cycles/blender/blender_util.h7
-rw-r--r--intern/cycles/render/attribute.cpp8
-rw-r--r--intern/cycles/render/attribute.h1
-rw-r--r--intern/cycles/render/mesh.cpp16
-rw-r--r--intern/cycles/render/mesh.h1
6 files changed, 69 insertions, 15 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index fb667d1ba2f..dce1109aa88 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 45ca0e17550..b2046b290b2 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 ce232e90ffc..14805b6f11a 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 3dc7b7f7401..9fc32db8444 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 2ae15e09efb..ddcc42a9ae9 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 eec20acd3a9..247e3dd555e 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();