IO: Add Apply Transforms option to obj exporter

When enabled (default), exported OBJ files have the object transform
applied to their vertices. This is the previous default behaviour.

When disabled, exported vertices use their local object coordinates.

Pull Request: https://projects.blender.org/blender/blender/pulls/139436
This commit is contained in:
Thomas Hope
2025-08-15 15:03:44 +02:00
committed by Aras Pranckevicius
parent f4103acb3f
commit da46eed108
4 changed files with 19 additions and 5 deletions

View File

@@ -102,6 +102,7 @@ static wmOperatorStatus wm_obj_export_exec(bContext *C, wmOperator *op)
export_params.up_axis = eIOAxis(RNA_enum_get(op->ptr, "up_axis"));
export_params.global_scale = RNA_float_get(op->ptr, "global_scale");
export_params.apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers");
export_params.apply_transform = RNA_boolean_get(op->ptr, "apply_transform");
export_params.export_eval_mode = eEvaluationMode(RNA_enum_get(op->ptr, "export_eval_mode"));
export_params.export_selected_objects = RNA_boolean_get(op->ptr, "export_selected_objects");
@@ -168,6 +169,7 @@ static void ui_obj_export_settings(const bContext *C, uiLayout *layout, PointerR
col->prop(
ptr, "export_triangulated_mesh", UI_ITEM_NONE, IFACE_("Triangulated Mesh"), ICON_NONE);
col->prop(ptr, "apply_modifiers", UI_ITEM_NONE, IFACE_("Apply Modifiers"), ICON_NONE);
col->prop(ptr, "apply_transform", UI_ITEM_NONE, IFACE_("Apply Transform"), ICON_NONE);
col->prop(ptr, "export_eval_mode", UI_ITEM_NONE, IFACE_("Properties"), ICON_NONE);
}
@@ -322,6 +324,11 @@ void WM_OT_obj_export(wmOperatorType *ot)
/* File Writer options. */
RNA_def_boolean(
ot->srna, "apply_modifiers", true, "Apply Modifiers", "Apply modifiers to exported meshes");
RNA_def_boolean(ot->srna,
"apply_transform",
true,
"Apply Transform",
"Apply object transforms to exported vertices");
RNA_def_enum(ot->srna,
"export_eval_mode",
io_obj_export_evaluation_mode,

View File

@@ -47,6 +47,7 @@ struct OBJExportParams {
/* File Write Options. */
bool export_selected_objects = false;
bool apply_modifiers = true;
bool apply_transform = true;
eEvaluationMode export_eval_mode = DAG_EVAL_VIEWPORT;
bool export_uv = true;
bool export_normals = true;

View File

@@ -69,8 +69,11 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj
this->materials[i] = BKE_object_material_get_eval(obj_eval, i + 1);
}
set_world_axes_transform(
*obj_eval, export_params.forward_axis, export_params.up_axis, export_params.global_scale);
set_world_axes_transform(*obj_eval,
export_params.forward_axis,
export_params.up_axis,
export_params.global_scale,
export_params.apply_transform);
}
/**
@@ -146,13 +149,15 @@ void OBJMesh::triangulate_mesh_eval()
void OBJMesh::set_world_axes_transform(const Object &obj_eval,
const eIOAxis forward,
const eIOAxis up,
const float global_scale)
const float global_scale,
const bool apply_transform)
{
float3x3 axes_transform;
/* +Y-forward and +Z-up are the default Blender axis settings. */
mat3_from_axis_conversion(forward, up, IO_AXIS_Y, IO_AXIS_Z, axes_transform.ptr());
const float4x4 &object_to_world = obj_eval.object_to_world();
const float4x4 &object_to_world = apply_transform ? obj_eval.object_to_world() :
float4x4::identity();
const float3x3 transform = axes_transform * float3x3(object_to_world);
world_and_axes_transform_ = float4x4(transform);

View File

@@ -223,6 +223,7 @@ class OBJMesh : NonCopyable {
void set_world_axes_transform(const Object &obj_eval,
eIOAxis forward,
eIOAxis up,
float global_scale);
float global_scale,
bool apply_transform);
};
} // namespace blender::io::obj