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
diff options
context:
space:
mode:
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.cc97
1 files changed, 59 insertions, 38 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 8d560bd2c8c..01f05466b3a 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"
@@ -29,13 +31,17 @@ Object *MeshFromGeometry::create_mesh(Main *bmain,
Map<std::string, Material *> &created_materials,
const OBJImportParams &import_params)
{
+ const int64_t tot_verts_object{mesh_geometry_.get_vertex_count()};
+ if (tot_verts_object <= 0) {
+ /* Empty mesh */
+ return nullptr;
+ }
std::string ob_name{mesh_geometry_.geometry_name_};
if (ob_name.empty()) {
ob_name = "Untitled";
}
fixup_invalid_faces();
- const int64_t tot_verts_object{mesh_geometry_.vertex_count_};
/* Total explicitly imported edges, not the ones belonging the polygons to be created. */
const int64_t tot_edges{mesh_geometry_.edges_.size()};
const int64_t tot_face_elems{mesh_geometry_.face_elements_.size()};
@@ -46,10 +52,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_) {
@@ -67,6 +74,9 @@ Object *MeshFromGeometry::create_mesh(Main *bmain,
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;
}
@@ -147,9 +157,9 @@ void MeshFromGeometry::fixup_invalid_faces()
void MeshFromGeometry::create_vertices(Mesh *mesh)
{
- const int tot_verts_object{mesh_geometry_.vertex_count_};
+ const int tot_verts_object{mesh_geometry_.get_vertex_count()};
for (int i = 0; i < tot_verts_object; ++i) {
- int vi = mesh_geometry_.vertex_start_ + i;
+ int vi = mesh_geometry_.vertex_index_min_ + i;
if (vi < global_vertices_.vertices.size()) {
copy_v3_v3(mesh->mvert[i].co, global_vertices_.vertices[vi]);
}
@@ -161,19 +171,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_) {
+ const int64_t total_verts = mesh_geometry_.get_vertex_count();
+ 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};
@@ -204,30 +208,25 @@ void MeshFromGeometry::create_polys_loops(Object *obj, Mesh *mesh)
const PolyCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx];
MLoop &mloop = mesh->mloop[tot_loop_idx];
tot_loop_idx++;
- mloop.v = curr_corner.vert_index;
+ mloop.v = curr_corner.vert_index - mesh_geometry_.vertex_index_min_;
+ /* 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());
}
@@ -236,14 +235,14 @@ void MeshFromGeometry::create_polys_loops(Object *obj, Mesh *mesh)
void MeshFromGeometry::create_edges(Mesh *mesh)
{
const int64_t tot_edges{mesh_geometry_.edges_.size()};
- const int64_t total_verts{mesh_geometry_.vertex_count_};
+ const int64_t total_verts{mesh_geometry_.get_vertex_count()};
UNUSED_VARS_NDEBUG(total_verts);
for (int i = 0; i < tot_edges; ++i) {
const MEdge &src_edge = mesh_geometry_.edges_[i];
MEdge &dst_edge = mesh->medge[i];
- BLI_assert(src_edge.v1 < total_verts && src_edge.v2 < total_verts);
- dst_edge.v1 = src_edge.v1;
- dst_edge.v2 = src_edge.v2;
+ dst_edge.v1 = src_edge.v1 - mesh_geometry_.vertex_index_min_;
+ dst_edge.v2 = src_edge.v2 - mesh_geometry_.vertex_index_min_;
+ BLI_assert(dst_edge.v1 < total_verts && dst_edge.v2 < total_verts);
dst_edge.flag = ME_LOOSEEDGE;
}
@@ -289,7 +288,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};
@@ -311,17 +310,14 @@ void MeshFromGeometry::create_materials(Main *bmain,
if (mat == nullptr) {
continue;
}
- BKE_object_material_slot_add(bmain, obj);
- BKE_object_material_assign(bmain, obj, mat, obj->totcol, BKE_MAT_ASSIGN_USERPREF);
+ BKE_object_material_assign_single_obdata(bmain, obj, mat, obj->totcol + 1);
}
}
void MeshFromGeometry::create_normals(Mesh *mesh)
{
- /* NOTE: Needs more clarity about what is expected in the viewport if the function works. */
-
/* No normal data: nothing to do. */
- if (global_vertices_.vertex_normals.is_empty() || !mesh_geometry_.has_vertex_normals_) {
+ if (global_vertices_.vertex_normals.is_empty()) {
return;
}
@@ -345,4 +341,29 @@ 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 at all. */
+ if (global_vertices_.vertex_colors.is_empty()) {
+ return;
+ }
+
+ /* Find which vertex color block is for this mesh (if any). */
+ for (const auto &block : global_vertices_.vertex_colors) {
+ if (mesh_geometry_.vertex_index_min_ >= block.start_vertex_index &&
+ mesh_geometry_.vertex_index_max_ < block.start_vertex_index + block.colors.size()) {
+ /* This block is suitable, use colors from it. */
+ CustomDataLayer *color_layer = BKE_id_attribute_new(
+ &mesh->id, "Color", CD_PROP_COLOR, ATTR_DOMAIN_POINT, nullptr);
+ float4 *colors = (float4 *)color_layer->data;
+ int offset = mesh_geometry_.vertex_index_min_ - block.start_vertex_index;
+ for (int i = 0, n = mesh_geometry_.get_vertex_count(); i != n; ++i) {
+ float3 c = block.colors[offset + i];
+ colors[i] = float4(c.x, c.y, c.z, 1.0f);
+ }
+ return;
+ }
+ }
+}
+
} // namespace blender::io::obj