diff options
author | OmarSquircleArt <mail@OmarEmara.dev> | 2019-11-27 13:07:20 +0300 |
---|---|---|
committer | OmarSquircleArt <mail@OmarEmara.dev> | 2019-11-27 13:07:20 +0300 |
commit | 1c2f7b022a56b034e3e24d8bd5bf03d3beb5ca94 (patch) | |
tree | c40ab4fb676efce962fe833f858c311af6c0c8e4 /intern/cycles/blender/blender_mesh.cpp | |
parent | fc1a073bcdc9d2a9ecd4b765724b0f4f4cab4d46 (diff) |
Cycles: Add Random Per Island attribute.
The Random Per Island attribute is a random float associated with each
connected component (island) of the mesh. It is particularly useful
when artists want to add variations to meshes composed of separate
units. Like tree leaves created using particle systems, wood planks
created using array modifiers, or abstract splines created using AN.
Reviewed By: Sergey Sharybin, Jacques Lucke
Differential Revision: https://developer.blender.org/D6154
Diffstat (limited to 'intern/cycles/blender/blender_mesh.cpp')
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 30417e85441..5c28404e745 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -29,8 +29,10 @@ #include "util/util_algorithm.h" #include "util/util_foreach.h" +#include "util/util_hash.h" #include "util/util_logging.h" #include "util/util_math.h" +#include "util/util_disjoint_set.h" #include "mikktspace.h" @@ -679,6 +681,55 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b } } +/* The Random Per Island attribute is a random float associated with each + * connected component (island) of the mesh. The attribute is computed by + * first classifying the vertices into different sets using a Disjoint Set + * data structure. Then the index of the root of each vertex (Which is the + * representative of the set the vertex belongs to) is hashed and stored. + * + * We are using a face attribute to avoid interpolation during rendering, + * allowing the user to safely hash the output further. Had we used vertex + * attribute, the interpolation will introduce very slight variations, + * making the output unsafe to hash. */ +static void attr_create_random_per_island(Scene *scene, + Mesh *mesh, + BL::Mesh &b_mesh, + bool subdivision) +{ + if (!mesh->need_attribute(scene, ATTR_STD_RANDOM_PER_ISLAND)) { + return; + } + + int number_of_vertices = b_mesh.vertices.length(); + if (number_of_vertices == 0) { + return; + } + + DisjointSet vertices_sets(number_of_vertices); + + BL::Mesh::edges_iterator e; + for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) { + vertices_sets.join(e->vertices()[0], e->vertices()[1]); + } + + AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; + Attribute *attribute = attributes.add(ATTR_STD_RANDOM_PER_ISLAND); + float *data = attribute->data_float(); + + if (!subdivision) { + BL::Mesh::loop_triangles_iterator t; + for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) { + data[t->index()] = hash_uint_to_float(vertices_sets.find(t->vertices()[0])); + } + } + else { + BL::Mesh::polygons_iterator p; + for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { + data[p->index()] = hash_uint_to_float(vertices_sets.find(p->vertices()[0])); + } + } +} + /* Create Mesh */ static void create_mesh(Scene *scene, @@ -799,6 +850,7 @@ static void create_mesh(Scene *scene, */ attr_create_pointiness(scene, mesh, b_mesh, subdivision); attr_create_vertex_color(scene, mesh, b_mesh, subdivision); + attr_create_random_per_island(scene, mesh, b_mesh, subdivision); if (subdivision) { attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs); |