refactor(tools): one FBX export preset instead of six copies

The bpy.ops.export_scene.fbx argument block was duplicated in six scripts (hero,
block frontage, north buildings, site, scale test, MPFB character) and all six
carried mesh_smooth_type="OFF", which drops smoothing groups and made every
Unreal import warn and every round part faceted.

Tools/fbx_export_preset.py now owns the presets:
- preset_kwargs(preset, selection, **overrides) is bpy-free and unit-tested;
- export_static()/export_character() are thin wrappers that import bpy lazily;
- ue_metric_v1 and ue_character_v1 keep the recorded scale contract
  (FBX_SCALE_NONE, apply_unit_scale, -Y forward / Z up) and use FACE smoothing.

Callers switched: hero_facade_build, export_block_frontage, export_north_buildings,
scale_test_export, mpfb_character_export, Art/blender/site/export_site_fbx.

Verified by re-exporting every asset through the preset and re-importing all of
them: 0 smoothing warnings on site, frontage and north buildings; packaging and
-qaselftest all PASS (walk, transect 0 holes, wall probe 0/35, facade probe 0/9).
49 tool tests pass (9 new for the preset contract).
This commit is contained in:
zwitschi committed 2026-11-08 18:00:59 +01:00
1 parent 160e9144f9
commit 286d9f6479
49 files changed
+283 -158

No files matched your search

+5 -16
View File
@@ -33,6 +33,9 @@ import os
import sys
import bpy
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import fbx_export_preset as fbx_preset # noqa: E402
# --- measured / derived ------------------------------------------------------
FRONTAGE_W = 25.75
@@ -306,24 +309,10 @@ def build():
def export_fbx(path):
# Preset lives in Tools/fbx_export_preset.py (ue_metric_v1).
os.makedirs(os.path.dirname(path), exist_ok=True)
# Named export preset "ue_metric_v1" - same settings as Tools/scale_test_export.py.
bpy.ops.export_scene.fbx(
filepath=path,
use_selection=False,
object_types={"MESH"},
apply_unit_scale=True,
apply_scale_options="FBX_SCALE_NONE",
axis_forward="-Y",
axis_up="Z",
use_space_transform=True,
use_mesh_modifiers=True,
# "FACE" exports smoothing groups; without it every import logs
# "No smoothing group information was found for this mesh".
mesh_smooth_type="FACE",
path_mode="AUTO",
bake_space_transform=False,
)
fbx_preset.export_static(path)
print(f"[hero] exported FBX preset ue_metric_v1 -> {path}")