diff options
Diffstat (limited to 'source/blender/io/wavefront_obj/importer/obj_import_mesh.cc')
-rw-r--r-- | source/blender/io/wavefront_obj/importer/obj_import_mesh.cc | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index fc40333c24d..aa38a4d6715 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -8,7 +8,9 @@ #include "DNA_mesh_types.h" #include "DNA_scene_types.h" +#include "BKE_attribute.h" #include "BKE_customdata.h" +#include "BKE_deform.h" #include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_node_tree_update.h" @@ -46,10 +48,11 @@ Object *MeshFromGeometry::create_mesh(Main *bmain, obj->data = BKE_object_obdata_add_from_type(bmain, OB_MESH, ob_name.c_str()); create_vertices(mesh); - create_polys_loops(obj, mesh); + create_polys_loops(mesh, import_params.import_vertex_groups); create_edges(mesh); create_uv_verts(mesh); create_normals(mesh); + create_colors(mesh); create_materials(bmain, materials, created_materials, obj); if (import_params.validate_meshes || mesh_geometry_.has_invalid_polys_) { @@ -62,11 +65,14 @@ Object *MeshFromGeometry::create_mesh(Main *bmain, transform_object(obj, import_params); /* FIXME: after 2.80; `mesh->flag` isn't copied by #BKE_mesh_nomain_to_mesh() */ - const short autosmooth = (mesh->flag & ME_AUTOSMOOTH); + const uint16_t autosmooth = (mesh->flag & ME_AUTOSMOOTH); Mesh *dst = static_cast<Mesh *>(obj->data); BKE_mesh_nomain_to_mesh(mesh, dst, obj, &CD_MASK_EVERYTHING, true); dst->flag |= autosmooth; + /* Note: vertex groups have to be created after final mesh is assigned to the object. */ + create_vertex_groups(obj); + return obj; } @@ -161,19 +167,13 @@ void MeshFromGeometry::create_vertices(Mesh *mesh) } } -void MeshFromGeometry::create_polys_loops(Object *obj, Mesh *mesh) +void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) { - /* Will not be used if vertex groups are not imported. */ mesh->dvert = nullptr; - float weight = 0.0f; const int64_t total_verts = mesh_geometry_.vertex_count_; - if (total_verts && mesh_geometry_.use_vertex_groups_) { + if (use_vertex_groups && total_verts && mesh_geometry_.has_vertex_groups_) { mesh->dvert = static_cast<MDeformVert *>( CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, nullptr, total_verts)); - weight = 1.0f / total_verts; - } - else { - UNUSED_VARS(weight); } const int64_t tot_face_elems{mesh->totpoly}; @@ -206,28 +206,23 @@ void MeshFromGeometry::create_polys_loops(Object *obj, Mesh *mesh) tot_loop_idx++; mloop.v = curr_corner.vert_index; + /* Setup vertex group data, if needed. */ if (!mesh->dvert) { continue; } - /* Iterating over mloop results in finding the same vertex multiple times. - * Another way is to allocate memory for dvert while creating vertices and fill them here. - */ - MDeformVert &def_vert = mesh->dvert[mloop.v]; - if (!def_vert.dw) { - def_vert.dw = static_cast<MDeformWeight *>( - MEM_callocN(sizeof(MDeformWeight), "OBJ Import Deform Weight")); - } - /* Every vertex in a face is assigned the same deform group. */ - int group_idx = curr_face.vertex_group_index; - /* Deform group number (def_nr) must behave like an index into the names' list. */ - *(def_vert.dw) = {static_cast<unsigned int>(group_idx), weight}; + const int group_index = curr_face.vertex_group_index; + MDeformWeight *dw = BKE_defvert_ensure_index(mesh->dvert + mloop.v, group_index); + dw->weight = 1.0f; } } +} - if (!mesh->dvert) { +void MeshFromGeometry::create_vertex_groups(Object *obj) +{ + Mesh *mesh = static_cast<Mesh *>(obj->data); + if (mesh->dvert == nullptr) { return; } - /* Add deform group names. */ for (const std::string &name : mesh_geometry_.group_order_) { BKE_object_defgroup_add_name(obj, name.data()); } @@ -289,7 +284,7 @@ static Material *get_or_create_material(Main *bmain, /* We have not, will have to create it. Create a new default * MTLMaterial too, in case the OBJ file tries to use a material * that was not in the MTL file. */ - const MTLMaterial &mtl = *materials.lookup_or_add(name, std::make_unique<MTLMaterial>()).get(); + const MTLMaterial &mtl = *materials.lookup_or_add(name, std::make_unique<MTLMaterial>()); Material *mat = BKE_material_add(bmain, name.c_str()); ShaderNodetreeWrap mat_wrap{bmain, mtl, mat}; @@ -345,4 +340,26 @@ void MeshFromGeometry::create_normals(Mesh *mesh) MEM_freeN(loop_normals); } +void MeshFromGeometry::create_colors(Mesh *mesh) +{ + /* Nothing to do if we don't have vertex colors. */ + if (mesh_geometry_.vertex_color_count_ < 1) { + return; + } + if (mesh_geometry_.vertex_color_count_ != mesh_geometry_.vertex_count_) { + std::cerr << "Mismatching number of vertices (" << mesh_geometry_.vertex_count_ + << ") and colors (" << mesh_geometry_.vertex_color_count_ << ") on object '" + << mesh_geometry_.geometry_name_ << "', ignoring colors." << std::endl; + return; + } + + CustomDataLayer *color_layer = BKE_id_attribute_new( + &mesh->id, "Color", CD_PROP_COLOR, ATTR_DOMAIN_POINT, nullptr); + float4 *colors = (float4 *)color_layer->data; + for (int i = 0; i < mesh_geometry_.vertex_color_count_; ++i) { + float3 c = global_vertices_.vertex_colors[mesh_geometry_.vertex_color_start_ + i]; + colors[i] = float4(c.x, c.y, c.z, 1.0f); + } +} + } // namespace blender::io::obj |