[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 (°_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