diff options
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 7edf797e096..e2b18c22d95 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -310,6 +310,133 @@ static void attr_create_sculpt_vertex_color(Scene *scene, } } +template<typename TypeInCycles, typename GetValueAtIndex> +static void fill_generic_attribute(BL::Mesh &b_mesh, + TypeInCycles *data, + const AttributeElement element, + const GetValueAtIndex &get_value_at_index) +{ + switch (element) { + case ATTR_ELEMENT_CORNER: { + for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) { + const int index = t.index() * 3; + BL::Array<int, 3> loops = t.loops(); + data[index] = get_value_at_index(loops[0]); + data[index + 1] = get_value_at_index(loops[1]); + data[index + 2] = get_value_at_index(loops[2]); + } + break; + } + case ATTR_ELEMENT_VERTEX: { + const int num_verts = b_mesh.vertices.length(); + for (int i = 0; i < num_verts; i++) { + data[i] = get_value_at_index(i); + } + break; + } + case ATTR_ELEMENT_FACE: { + for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) { + data[t.index()] = get_value_at_index(t.polygon_index()); + } + break; + } + default: { + assert(false); + break; + } + } +} + +static void attr_create_generic(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision) +{ + if (subdivision) { + /* TODO: Handle subdivison correctly. */ + return; + } + AttributeSet &attributes = mesh->attributes; + + for (BL::Attribute &b_attribute : b_mesh.attributes) { + const ustring name{b_attribute.name().c_str()}; + if (!mesh->need_attribute(scene, name)) { + continue; + } + if (attributes.find(name)) { + continue; + } + + const BL::Attribute::domain_enum b_domain = b_attribute.domain(); + const BL::Attribute::data_type_enum b_data_type = b_attribute.data_type(); + + AttributeElement element = ATTR_ELEMENT_NONE; + switch (b_domain) { + case BL::Attribute::domain_CORNER: + element = ATTR_ELEMENT_CORNER; + break; + case BL::Attribute::domain_POINT: + element = ATTR_ELEMENT_VERTEX; + break; + case BL::Attribute::domain_POLYGON: + element = ATTR_ELEMENT_FACE; + break; + default: + break; + } + if (element == ATTR_ELEMENT_NONE) { + /* Not supported. */ + continue; + } + switch (b_data_type) { + case BL::Attribute::data_type_FLOAT: { + BL::FloatAttribute b_float_attribute{b_attribute}; + Attribute *attr = attributes.add(name, TypeFloat, element); + float *data = attr->data_float(); + fill_generic_attribute( + b_mesh, data, element, [&](int i) { return b_float_attribute.data[i].value(); }); + break; + } + case BL::Attribute::data_type_BOOLEAN: { + BL::BoolAttribute b_bool_attribute{b_attribute}; + Attribute *attr = attributes.add(name, TypeFloat, element); + float *data = attr->data_float(); + fill_generic_attribute( + b_mesh, data, element, [&](int i) { return (float)b_bool_attribute.data[i].value(); }); + break; + } + case BL::Attribute::data_type_INT: { + BL::IntAttribute b_int_attribute{b_attribute}; + Attribute *attr = attributes.add(name, TypeFloat, element); + float *data = attr->data_float(); + fill_generic_attribute( + b_mesh, data, element, [&](int i) { return (float)b_int_attribute.data[i].value(); }); + break; + } + case BL::Attribute::data_type_FLOAT_VECTOR: { + BL::FloatVectorAttribute b_vector_attribute{b_attribute}; + Attribute *attr = attributes.add(name, TypeVector, element); + float3 *data = attr->data_float3(); + fill_generic_attribute(b_mesh, data, element, [&](int i) { + BL::Array<float, 3> v = b_vector_attribute.data[i].vector(); + return make_float3(v[0], v[1], v[2]); + }); + break; + } + case BL::Attribute::data_type_FLOAT_COLOR: { + BL::FloatColorAttribute b_color_attribute{b_attribute}; + Attribute *attr = attributes.add(name, TypeRGBA, element); + float4 *data = attr->data_float4(); + fill_generic_attribute(b_mesh, data, element, [&](int i) { + BL::Array<float, 4> v = b_color_attribute.data[i].color(); + return make_float4(v[0], v[1], v[2], v[3]); + }); + break; + } + default: + /* Not supported. */ + break; + } + } +} + /* Create vertex color attributes. */ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision) { @@ -837,6 +964,7 @@ static void create_mesh(Scene *scene, attr_create_vertex_color(scene, mesh, b_mesh, subdivision); attr_create_sculpt_vertex_color(scene, mesh, b_mesh, subdivision); attr_create_random_per_island(scene, mesh, b_mesh, subdivision); + attr_create_generic(scene, mesh, b_mesh, subdivision); if (subdivision) { attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs); |