from unreal import EditorAssetLibrary, MaterialInstanceConstant

# consolidate together Material Instances assets having the same name
# WARNING: will erase consolidated assets

# retrieves all assets from the directory and its sub directories
all_asset_names = EditorAssetLibrary.list_assets("/Game/Test/", True, False)

# loads all assets of the MaterialInstanceConstant class
material_assets = []
for asset_name in all_asset_names:
    loaded_asset = EditorAssetLibrary.load_asset(asset_name)
    if loaded_asset.__class__ == MaterialInstanceConstant:
        material_assets.append(loaded_asset)

# regroup assets having identical names
asset_consolidation = {}
for i in range(0, len(material_assets)):
    name = material_assets[i].get_name()
    if not name in asset_consolidation:
        asset_consolidation[name] = []
    asset_consolidation[name].append(i)

# consolidate references of identical assets
for asset_name, assets_ids in asset_consolidation.items():
    if len(assets_ids) < 2:
        continue
    EditorAssetLibrary.consolidate_assets(
        material_assets[assets_ids[0]],
        [material_assets[i] for i in assets_ids[1:]])
Beispiel #2
0
    def process(self, instance):
        # Define extract output file path
        stagingdir = self.staging_dir(instance)

        # Perform extraction
        self.log.info("Performing extraction..")

        # Check if the loaded level is the same of the instance
        current_level = ell.get_editor_world().get_path_name()
        assert current_level == instance.data.get("level"), \
            "Wrong level loaded"

        json_data = []

        for member in instance[:]:
            actor = ell.get_actor_reference(member)
            mesh = None

            # Check type the type of mesh
            if actor.get_class().get_name() == 'SkeletalMeshActor':
                mesh = actor.skeletal_mesh_component.skeletal_mesh
            elif actor.get_class().get_name() == 'StaticMeshActor':
                mesh = actor.static_mesh_component.static_mesh

            if mesh:
                # Search the reference to the Asset Container for the object
                path = unreal.Paths.get_path(mesh.get_path_name())
                filter = unreal.ARFilter(
                    class_names=["AssetContainer"], package_paths=[path])
                ar = unreal.AssetRegistryHelpers.get_asset_registry()
                try:
                    asset_container = ar.get_assets(filter)[0].get_asset()
                except IndexError:
                    self.log.error("AssetContainer not found.")
                    return

                parent = eal.get_metadata_tag(asset_container, "parent")
                family = eal.get_metadata_tag(asset_container, "family")

                self.log.info("Parent: {}".format(parent))
                blend = io.find_one(
                    {
                        "type": "representation",
                        "parent": io.ObjectId(parent),
                        "name": "blend"
                    },
                    projection={"_id": True})
                blend_id = blend["_id"]

                json_element = {}
                json_element["reference"] = str(blend_id)
                json_element["family"] = family
                json_element["instance_name"] = actor.get_name()
                json_element["asset_name"] = mesh.get_name()
                import_data = mesh.get_editor_property("asset_import_data")
                json_element["file_path"] = import_data.get_first_filename()
                transform = actor.get_actor_transform()

                json_element["transform"] = {
                    "translation": {
                        "x": transform.translation.x,
                        "y": transform.translation.y,
                        "z": transform.translation.z
                    },
                    "rotation": {
                        "x": math.radians(transform.rotation.euler().x),
                        "y": math.radians(transform.rotation.euler().y),
                        "z": math.radians(transform.rotation.euler().z),
                    },
                    "scale": {
                        "x": transform.scale3d.x,
                        "y": transform.scale3d.y,
                        "z": transform.scale3d.z
                    }
                }
                json_data.append(json_element)

        json_filename = "{}.json".format(instance.name)
        json_path = os.path.join(stagingdir, json_filename)

        with open(json_path, "w+") as file:
            json.dump(json_data, fp=file, indent=2)

        if "representations" not in instance.data:
            instance.data["representations"] = []

        json_representation = {
            'name': 'json',
            'ext': 'json',
            'files': json_filename,
            "stagingDir": stagingdir,
        }
        instance.data["representations"].append(json_representation)
                    FBXNormalGenerationMethod, MaterialSearchLocation)

# Fix Python PATH Script Issue #9
filename = inspect.getframeinfo(inspect.currentframe()).filename
currentPath = os.path.dirname(os.path.abspath(filename))

jsonSetting = open(
    os.path.normpath(
        os.path.join(currentPath, "..", "Data", "unrealenginesetting.json")),
    "r").read()
jsonSetting = json.loads(jsonSetting)

targetFolder = "/" + os.path.join(
    "Game", "Blender", jsonSetting["subfolder"]).replace(os.sep, "/")

if EditorAssetLibrary.does_directory_exist(directory_path=targetFolder):
    EditorAssetLibrary.make_directory(directory_path=targetFolder)

for file in jsonSetting["files"]:
    sourceFile = os.path.join(jsonSetting["folder"],
                              file["name"] + ".fbx").replace(os.sep, "/")

    if os.path.exists(sourceFile):
        importOptions = FbxImportUI()

        importOptions.set_editor_property("import_mesh", True)
        importOptions.set_editor_property("import_as_skeletal", False)
        importOptions.set_editor_property('import_animations', False)

        importOptions.static_mesh_import_data.set_editor_property(
            "auto_generate_collision", (jsonSetting["auto_generate_collision"],
    proxy_option.mesh_proxy_settings.allow_distance_field = False
    proxy_option.mesh_proxy_settings.allow_vertex_colors = False
    proxy_option.mesh_proxy_settings.calculate_correct_lod_model = False
    proxy_option.mesh_proxy_settings.compute_light_map_resolution = False
    proxy_option.mesh_proxy_settings.create_collision = False
    proxy_option.mesh_proxy_settings.generate_lightmap_u_vs = False
    proxy_option.mesh_proxy_settings.hard_angle_threshold = 89
    # increased normal texture size to capture more details
    proxy_option.mesh_proxy_settings.material_settings.texture_size = (2048, 2048)
    proxy_option.mesh_proxy_settings.max_ray_cast_dist = 10.0
    proxy_option.mesh_proxy_settings.merge_distance = 1.0
    proxy_option.mesh_proxy_settings.override_transfer_distance = True
    proxy_option.mesh_proxy_settings.override_voxel_size = True
    proxy_option.mesh_proxy_settings.recalculate_normals = False
    proxy_option.mesh_proxy_settings.reuse_mesh_lightmap_u_vs = False
    # affects decimation quality
    proxy_option.mesh_proxy_settings.screen_size = 800
    proxy_option.mesh_proxy_settings.use_hard_angle_threshold = True
    proxy_option.mesh_proxy_settings.voxel_size = 0.5
    # create proxy and retrieve spawned actor
    proxy_actor = EditorLevelLibrary.create_proxy_mesh_actor(actors_to_merge, proxy_option)
    proxy_mesh = proxy_actor.static_mesh_component.static_mesh
    EditorLevelLibrary.destroy_actor(proxy_actor)
 
    slow_task.enter_progress_frame(1)
    for actor in level_actors:
        EditorLevelLibrary.destroy_actor(actor)
 
    EditorStaticMeshLibrary.set_lod_from_static_mesh(merged_mesh, 1, proxy_mesh, 0, True)
    EditorAssetLibrary.delete_loaded_asset(proxy_mesh)