69 lines
3.9 KiB
Python
69 lines
3.9 KiB
Python
"""Automated static mesh imports using the engine's enabled import pipelines."""
|
|
from pathlib import Path
|
|
|
|
import unreal
|
|
|
|
from .paths import GENERATED, slug
|
|
|
|
|
|
def import_model(filename, name="Character"):
|
|
source = Path(filename).resolve()
|
|
if not source.is_file():
|
|
raise FileNotFoundError(f"Brak modelu: {source}")
|
|
if source.suffix.lower() not in {".glb", ".gltf", ".fbx", ".obj"}:
|
|
raise ValueError("Model musi byc plikiem GLB, glTF, FBX lub OBJ.")
|
|
destination = f"{GENERATED}/Imports/{slug(name)}"
|
|
task = unreal.AssetImportTask()
|
|
task.set_editor_property("filename", str(source))
|
|
task.set_editor_property("destination_path", destination)
|
|
task.set_editor_property("destination_name", name)
|
|
task.set_editor_property("automated", True)
|
|
task.set_editor_property("replace_existing", True)
|
|
task.set_editor_property("replace_existing_settings", True)
|
|
task.set_editor_property("save", True)
|
|
task.set_editor_property("async_", False)
|
|
if source.suffix.lower() in {".glb", ".gltf"}:
|
|
# Defaults reuse existing materials without updating them. Our generated
|
|
# import folder belongs to the source file, so apply source properties.
|
|
template = unreal.load_asset("/Interchange/Pipelines/DefaultGLTFAssetsPipeline")
|
|
pipeline = unreal.load_asset(GENERATED + "/Pipelines/GLTFWorkshop")
|
|
if pipeline is None:
|
|
pipeline = unreal.AssetToolsHelpers.get_asset_tools().duplicate_asset(
|
|
"GLTFWorkshop", GENERATED + "/Pipelines", template)
|
|
pipeline.set_editor_property("reimport_strategy", unreal.ReimportStrategyFlags.APPLY_PIPELINE_PROPERTIES)
|
|
pipeline.material_pipeline.set_editor_property("import_materials", True)
|
|
# PBR images are imported explicitly into WorkshopTextures below. This
|
|
# avoids Interchange's dependency-preserving material reimport behavior.
|
|
pipeline.material_pipeline.texture_pipeline.set_editor_property("import_textures", False)
|
|
pipeline.set_editor_property("scene_name_sub_folder", True)
|
|
pipeline.set_editor_property("asset_type_sub_folders", True)
|
|
pipeline.material_pipeline.set_editor_property(
|
|
"search_location", unreal.InterchangeMaterialSearchLocation.DO_NOT_SEARCH)
|
|
pipeline.material_pipeline.set_editor_property(
|
|
"material_import", unreal.InterchangeMaterialImportOption.IMPORT_AS_MATERIAL_INSTANCES)
|
|
unreal.EditorAssetLibrary.save_loaded_asset(pipeline)
|
|
options = unreal.InterchangePipelineStackOverride()
|
|
options.set_editor_property("override_pipelines", [
|
|
unreal.SoftObjectPath(pipeline.get_path_name()),
|
|
unreal.SoftObjectPath("/Interchange/Pipelines/DefaultGLTFPipeline.DefaultGLTFPipeline")])
|
|
task.set_editor_property("options", options)
|
|
if source.suffix.lower() == ".fbx":
|
|
options = unreal.FbxImportUI()
|
|
options.set_editor_property("import_as_skeletal", False)
|
|
options.set_editor_property("mesh_type_to_import", unreal.FBXImportType.FBXIT_STATIC_MESH)
|
|
options.set_editor_property("automated_import_should_detect_type", False)
|
|
options.static_mesh_import_data.set_editor_property("combine_meshes", True)
|
|
task.set_editor_property("options", options)
|
|
unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([task])
|
|
meshes = [obj for obj in task.get_objects() if isinstance(obj, unreal.StaticMesh)]
|
|
if len(meshes) != 1:
|
|
raise RuntimeError(
|
|
f"Import {source.name}: oczekiwano jednego StaticMesh, otrzymano {len(meshes)}. "
|
|
"Polacz obiekty przed eksportem albo uzyj workshop.blender.import_character().")
|
|
if source.suffix.lower() in {".glb", ".gltf"}:
|
|
# UE preserves material edits on mesh reimport. In this workflow Blender
|
|
# owns the look; explicitly synchronize the supported PBR parameters.
|
|
from ._gltf import link_textures
|
|
link_textures(source, meshes[0], destination)
|
|
return meshes[0]
|