[Bf-blender-cvs] [b599820418f] master: OBJ: add split by objects/groups import options (T103839)

Aras Pranckevicius noreply at git.blender.org
Thu Jan 12 21:52:19 CET 2023


Commit: b599820418fbfa1cbec88572ed5ff8a6dbce9e13
Author: Aras Pranckevicius
Date:   Thu Jan 12 22:47:39 2023 +0200
Branches: master
https://developer.blender.org/rBb599820418fbfa1cbec88572ed5ff8a6dbce9e13

OBJ: add split by objects/groups import options (T103839)

The new C++ OBJ importer was missing "split by objects" / "split by
groups" import settings of the older Python importer.
Implements T103839.

Added test coverage for all 4 possible combinations of these two
options.

===================================================================

M	source/blender/editors/io/io_obj.c
M	source/blender/io/wavefront_obj/IO_wavefront_obj.h
M	source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
M	source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
M	source/blender/io/wavefront_obj/tests/obj_importer_tests.cc

===================================================================

diff --git a/source/blender/editors/io/io_obj.c b/source/blender/editors/io/io_obj.c
index ce121203972..e1dba4ee954 100644
--- a/source/blender/editors/io/io_obj.c
+++ b/source/blender/editors/io/io_obj.c
@@ -410,6 +410,8 @@ static int wm_obj_import_exec(bContext *C, wmOperator *op)
   import_params.clamp_size = RNA_float_get(op->ptr, "clamp_size");
   import_params.forward_axis = RNA_enum_get(op->ptr, "forward_axis");
   import_params.up_axis = RNA_enum_get(op->ptr, "up_axis");
+  import_params.use_split_objects = RNA_boolean_get(op->ptr, "use_split_objects");
+  import_params.use_split_groups = RNA_boolean_get(op->ptr, "use_split_groups");
   import_params.import_vertex_groups = RNA_boolean_get(op->ptr, "import_vertex_groups");
   import_params.validate_meshes = RNA_boolean_get(op->ptr, "validate_meshes");
   import_params.relative_paths = ((U.flag & USER_RELPATHS) != 0);
@@ -472,6 +474,8 @@ static void ui_obj_import_settings(uiLayout *layout, PointerRNA *imfptr)
   box = uiLayoutBox(layout);
   uiItemL(box, IFACE_("Options"), ICON_EXPORT);
   col = uiLayoutColumn(box, false);
+  uiItemR(col, imfptr, "use_split_objects", 0, NULL, ICON_NONE);
+  uiItemR(col, imfptr, "use_split_groups", 0, NULL, ICON_NONE);
   uiItemR(col, imfptr, "import_vertex_groups", 0, NULL, ICON_NONE);
   uiItemR(col, imfptr, "validate_meshes", 0, NULL, ICON_NONE);
 }
@@ -531,6 +535,16 @@ void WM_OT_obj_import(struct wmOperatorType *ot)
   RNA_def_property_update_runtime(prop, (void *)forward_axis_update);
   prop = RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Y, "Up Axis", "");
   RNA_def_property_update_runtime(prop, (void *)up_axis_update);
+  RNA_def_boolean(ot->srna,
+                  "use_split_objects",
+                  true,
+                  "Split By Object",
+                  "Import each OBJ 'o' as a separate object");
+  RNA_def_boolean(ot->srna,
+                  "use_split_groups",
+                  false,
+                  "Split By Group",
+                  "Import each OBJ 'g' as a separate object");
   RNA_def_boolean(ot->srna,
                   "import_vertex_groups",
                   false,
diff --git a/source/blender/io/wavefront_obj/IO_wavefront_obj.h b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
index cf6464eeb37..2c039958bee 100644
--- a/source/blender/io/wavefront_obj/IO_wavefront_obj.h
+++ b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
@@ -68,6 +68,8 @@ struct OBJImportParams {
   float global_scale;
   eIOAxis forward_axis;
   eIOAxis up_axis;
+  bool use_split_objects;
+  bool use_split_groups;
   bool import_vertex_groups;
   bool validate_meshes;
   bool relative_paths;
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
index 1a3a333d957..b90a0c99424 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
@@ -363,6 +363,24 @@ static void geom_update_smooth_group(const char *p, const char *end, bool &r_sta
   r_state_shaded_smooth = smooth != 0;
 }
 
+static void geom_new_object(const char *p,
+                            const char *end,
+                            bool &r_state_shaded_smooth,
+                            std::string &r_state_group_name,
+                            int &r_state_material_index,
+                            Geometry *&r_curr_geom,
+                            Vector<std::unique_ptr<Geometry>> &r_all_geometries)
+{
+  r_state_shaded_smooth = false;
+  r_state_group_name = "";
+  /* Reset object-local material index that's used in face infos.
+   * NOTE: do not reset the material name; that has to carry over
+   * into the next object if needed. */
+  r_state_material_index = -1;
+  r_curr_geom = create_geometry(
+      r_curr_geom, GEOM_MESH, StringRef(p, end).trim(), r_all_geometries);
+}
+
 OBJParser::OBJParser(const OBJImportParams &import_params, size_t read_buffer_size = 64 * 1024)
     : import_params_(import_params), read_buffer_size_(read_buffer_size)
 {
@@ -534,22 +552,34 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
       }
       /* Objects. */
       else if (parse_keyword(p, end, "o")) {
-        state_shaded_smooth = false;
-        state_group_name = "";
-        /* Reset object-local material index that's used in face infos.
-         * NOTE: do not reset the material name; that has to carry over
-         * into the next object if needed. */
-        state_material_index = -1;
-        curr_geom = create_geometry(
-            curr_geom, GEOM_MESH, StringRef(p, end).trim(), r_all_geometries);
+        if (import_params_.use_split_objects) {
+          geom_new_object(p,
+                          end,
+                          state_shaded_smooth,
+                          state_group_name,
+                          state_material_index,
+                          curr_geom,
+                          r_all_geometries);
+        }
       }
       /* Groups. */
       else if (parse_keyword(p, end, "g")) {
-        geom_update_group(StringRef(p, end).trim(), state_group_name);
-        int new_index = curr_geom->group_indices_.size();
-        state_group_index = curr_geom->group_indices_.lookup_or_add(state_group_name, new_index);
-        if (new_index == state_group_index) {
-          curr_geom->group_order_.append(state_group_name);
+        if (import_params_.use_split_groups) {
+          geom_new_object(p,
+                          end,
+                          state_shaded_smooth,
+                          state_group_name,
+                          state_material_index,
+                          curr_geom,
+                          r_all_geometries);
+        }
+        else {
+          geom_update_group(StringRef(p, end).trim(), state_group_name);
+          int new_index = curr_geom->group_indices_.size();
+          state_group_index = curr_geom->group_indices_.lookup_or_add(state_group_name, new_index);
+          if (new_index == state_group_index) {
+            curr_geom->group_order_.append(state_group_name);
+          }
         }
       }
       /* Smoothing groups. */
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 6323b5ba1fc..794d307730c 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
@@ -53,7 +53,7 @@ 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(mesh, import_params.import_vertex_groups);
+  create_polys_loops(mesh, import_params.import_vertex_groups && !import_params.use_split_groups);
   create_edges(mesh);
   create_uv_verts(mesh);
   create_normals(mesh);
@@ -222,8 +222,11 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups)
         continue;
       }
       const int group_index = curr_face.vertex_group_index;
-      MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[mloop.v], group_index);
-      dw->weight = 1.0f;
+      /* Note: face might not belong to any group */
+      if (group_index >= 0 || 1) {
+        MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[mloop.v], group_index);
+        dw->weight = 1.0f;
+      }
     }
   }
 
diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
index 5f5587577a1..f15687e7bef 100644
--- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
@@ -48,6 +48,19 @@ struct Expectation {
 
 class obj_importer_test : public BlendfileLoadingBaseTest {
  public:
+  obj_importer_test()
+  {
+    params.global_scale = 1.0f;
+    params.clamp_size = 0;
+    params.forward_axis = IO_AXIS_NEGATIVE_Z;
+    params.up_axis = IO_AXIS_Y;
+    params.validate_meshes = true;
+    params.use_split_objects = true;
+    params.use_split_groups = false;
+    params.import_vertex_groups = false;
+    params.relative_paths = true;
+    params.clear_selection = true;
+  }
   void import_and_check(const char *path,
                         const Expectation *expect,
                         size_t expect_count,
@@ -59,16 +72,6 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
       return;
     }
 
-    OBJImportParams params;
-    params.global_scale = 1.0f;
-    params.clamp_size = 0;
-    params.forward_axis = IO_AXIS_NEGATIVE_Z;
-    params.up_axis = IO_AXIS_Y;
-    params.validate_meshes = true;
-    params.import_vertex_groups = false;
-    params.relative_paths = true;
-    params.clear_selection = true;
-
     std::string obj_path = blender::tests::flags_test_asset_dir() + "/io_tests/obj/" + path;
     strncpy(params.filepath, obj_path.c_str(), FILE_MAX - 1);
     const size_t read_buffer_size = 650;
@@ -81,6 +84,32 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
     deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
                               DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
                               DEG_ITER_OBJECT_FLAG_DUPLI;
+
+    constexpr bool print_result_scene = false;
+    if (print_result_scene) {
+      printf("Result was:\n");
+      DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, object) {
+        printf("  {\"%s\", ", object->id.name);
+        if (object->type == OB_MESH) {
+          Mesh *mesh = BKE_object_get_evaluated_mesh(object);
+          const Span<float3> positions = mesh->vert_positions();
+          printf("OB_MESH, %i, %i, %i, %i, float3(%g, %g, %g), float3(%g, %g, %g)",
+                 mesh->totvert,
+                 mesh->totedge,
+                 mesh->totpoly,
+                 mesh->totloop,
+                 positions.first().x,
+                 positions.first().y,
+                 positions.first().z,
+                 positions.last().x,
+                 positions.last().y,
+                 positions.last().z);
+        }
+        printf("},\

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list