예제 #1
0
    def readTextureCSV(self):
        #TODO: search for texture in directory and link to that if it exists (swap in materials csv?)
        #TODO: figure out how to mark a texture as used in the surfaces directory in blender. Can do in UE4
        try:
            with open(self.textureCSVPath, mode='r') as csv_file:
                csv_reader = csv.reader(csv_file, delimiter=',')
                line_count = 0
                parameterNames = []
                for row in csv_reader:
                    if line_count == 0:
                        unreal.log("Parameters To Import: " + " | ".join(row))
                        parameterNames = row
                        line_count += 1
                    else:
                        #Add texture to import list
                        self.createTexture(
                            filepath=row[1],
                            importLocation=self.UETextureDirectory,
                            overwrite=row[4],
                            textureName=row[0])
                        line_count += 1

                unreal.log('Processed ' + str(line_count - 1) + ' textures')
                unreal.EditorAssetLibrary.save_directory(
                    self.UETextureDirectory)
        except Exception:
            unreal.log_warning("Issue reading texture csv file")
예제 #2
0
    def _import_to_content_browser(self, path, sg_publish_data):
        """
        Import the asset into the Unreal Content Browser.

        :param path: Path to file.
        :param sg_publish_data: Shotgun data dictionary with all the standard publish fields.
        """

        unreal.log("File to import: {}".format(path))

        if not os.path.exists(path):
            raise Exception("File not found on disk - '%s'" % path)

        destination_path, destination_name = self._get_destination_path_and_name(
            sg_publish_data)

        asset_path = _unreal_import_fbx_asset(path, destination_path,
                                              destination_name)

        if asset_path:
            self._set_asset_metadata(asset_path, sg_publish_data)

            # Focus the Unreal Content Browser on the imported asset
            asset_paths = []
            asset_paths.append(asset_path)
            unreal.EditorAssetLibrary.sync_browser_to_objects(asset_paths)
예제 #3
0
def move_assets_to_path(root, name, assets):
    """
    Moving (renaming) list of asset paths to new destination.

    Args:
        root (str): root of the path (eg. `/Game`)
        name (str): name of destination directory (eg. `Foo` )
        assets (list of str): list of asset paths

    Returns:
        str: folder name

    Example:
        This will get paths of all assets under `/Game/Test` and move them
        to `/Game/NewTest`. If `/Game/NewTest` already exists, then resulting
        path will be `/Game/NewTest1`

        >>> assets = unreal.EditorAssetLibrary.list_assets("/Game/Test")
        >>> move_assets_to_path("/Game", "NewTest", assets)
        NewTest

    """
    eal = unreal.EditorAssetLibrary
    name = create_folder(root, name)

    unreal.log(assets)
    for asset in assets:
        loaded = eal.load_asset(asset)
        eal.rename_asset(asset, "{}/{}/{}".format(root, name,
                                                  loaded.get_name()))

    return name
예제 #4
0
    def init_qt_app(self):
        self.logger.debug("%s: Initializing QtApp for Unreal", self)

        from sgtk.platform.qt5 import QtWidgets

        if not QtWidgets.QApplication.instance():
            self._qt_app = QtWidgets.QApplication(sys.argv)
            self._qt_app.setQuitOnLastWindowClosed(False)
            unreal.log("Created QApplication instance: {0}".format(
                self._qt_app))

            def _app_tick(dt):
                QtWidgets.QApplication.processEvents()

            tick_handle = unreal.register_slate_post_tick_callback(_app_tick)

            def _app_quit():
                unreal.unregister_slate_post_tick_callback(tick_handle)

            QtWidgets.QApplication.instance().aboutToQuit.connect(_app_quit)
        else:
            self._qt_app = QtWidgets.QApplication.instance()

        # Make the QApplication use the dark theme. Must be called after the QApplication is instantiated
        self._initialize_dark_look_and_feel()
예제 #5
0
    def check_asset_name(self, asset_data):
        package_name = unreal.StringLibrary.conv_name_to_string(
            asset_data.package_name)

        if isinstance(package_name, unicode):
            unreal.log('package name has unicode: {}'.format(
                package_name.encode('utf-8')))
예제 #6
0
 def _execute_callback(self, callback):
     """
     Execute the callback right away
     """
     unreal.log("_execute_callback called with {0}".format(callback.__str__()))
     self._callback = callback
     self._execute_within_exception_trap()
예제 #7
0
def _unreal_import_fbx_asset(input_path, destination_path, destination_name):
    """
    Import an FBX into Unreal Content Browser

    :param input_path: The fbx file to import
    :param destination_path: The Content Browser path where the asset will be placed
    :param destination_name: The asset name to use; if None, will use the filename without extension
    """
    tasks = []
    tasks.append(
        _generate_fbx_import_task(input_path, destination_path,
                                  destination_name))

    unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks(tasks)

    first_imported_object = None

    for task in tasks:
        unreal.log("Import Task for: {}".format(task.filename))
        for object_path in task.imported_object_paths:
            unreal.log("Imported object: {}".format(object_path))
            if not first_imported_object:
                first_imported_object = object_path

    return first_imported_object
예제 #8
0
def load_positions_from_backup():
    print('load_positions_from_backup')
    actors = get_all_actors()
    saved_positions = get_saved_positions()
    unreal.log(type(actors))
    unreal.log(type(saved_positions))
    for actor in actors:
        actor.set_actor_location(saved_positions[""], False, False)
예제 #9
0
def run():
    # Create the processor with preconfigured inputs
    global _g_processor
    _g_processor = ProcessHDAExample(get_test_hda(),
                                     node_inputs=build_inputs())
    # Activate the processor, this will starts instantiation, and then cook
    if not _g_processor.activate():
        unreal.log_warning('Activation failed.')
    else:
        unreal.log('Activated!')
예제 #10
0
    def _execute_deferred(self, callback):
        """
        Execute the callback deferred
        The primary purpose of this method is to detach the executing code from the menu invocation
        """
        unreal.log("{0} _execute_deferred called with {1}".format(self, callback.__str__()))
        self._callback = callback

        from sgtk.platform.qt5 import QtCore
        QtCore.QTimer.singleShot(0, self._execute_within_exception_trap)
예제 #11
0
    def _post_init(self):
        """
        Equivalent to __init__ but will also be called from C++
        """
        engine = sgtk.platform.current_engine()
        engine.unreal_sg_engine = self

        unreal.log(
            "ShotgunEngineWrapper._post_init: unreal_sg_engine {} with tk-unreal {}"
            .format(self, engine))
예제 #12
0
    def process(self):

        name = self.data["subset"]

        selection = []
        if (self.options or {}).get("useSelection"):
            sel_objects = unreal.EditorUtilityLibrary.get_selected_assets()
            selection = [a.get_path_name() for a in sel_objects]

        unreal.log("selection: {}".format(selection))
        instantiate(self.root, name, self.data, selection, self.suffix)
예제 #13
0
    def shutdown(self):
        from sgtk.platform.qt5 import QtWidgets

        engine = sgtk.platform.current_engine()
        if engine is not None:
            unreal.log("Shutting down %s" % self.__class__.__name__)

            # destroy_engine of tk-unreal will take care of closing all dialogs that are still opened
            engine.destroy()
            QtWidgets.QApplication.instance().quit()
            QtWidgets.QApplication.processEvents()
예제 #14
0
 def getCutNumber(self, fbxfile):
     """
     파일네임에서 s00_c000 의 규칙을 갖는 스트링 찾기.
     :type fbxfile: str
     :rtype: str
     """
     filename = os.path.basename(fbxfile)
     p = re.compile("s\d+_c\d+")
     scene_cut = p.findall(filename)
     unreal.log(fbxfile)
     return scene_cut
예제 #15
0
        def get_shotgrid_menu_items(self):
            """
            Returns the list of available menu items to populate the SG menu in Unreal.
            """
            menu_items = []

            engine = sgtk.platform.current_engine()
            menu_items = self.create_menu(engine)

            unreal.log("get_shotgrid_menu_items returned: {0}".format(menu_items.__str__()))

            return menu_items
예제 #16
0
 def RenderSequence(path):
     capture_settings = unreal.AutomatedLevelSequenceCapture()
     capture_settings.level_sequence_asset = unreal.SoftObjectPath(path)
     try:
         unreal.SequencerTools.render_movie(capture_settings,
                                            unreal.OnRenderMovieStopped())
         return True
     except Exception as e:
         print("Python Caught Exception:")
         print(e)
         return False
     unreal.log("Render Sequence...")
예제 #17
0
    def importHierarchyCSV(self):
        try:
            newname = self.fbxName.partition('.')[0]
            if newname[
                    0:
                    3] == "SM_":  #todo if there are any other prefixes in the future, test for them
                newname = "ASH_" + newname[3:]
            elif newname[
                    0:
                    4] == "CAM_":  #todo if there are any other prefixes in the future, test for them
                newname = "ASH_" + newname[4:]
            elif newname[
                    0:
                    4] == "LGT_":  #todo if there are any other prefixes in the future, test for them
                newname = "ASH_" + newname[4:]

            else:
                newname = "ASH_" + newname
            asset_name = newname

            import_tasks = []

            factory = unreal.CSVImportFactory()
            csvPath = self.rootImportFolder + asset_name + '.csv'  #todo at some point fix the hierarchy name so it is unique per import
            factory.script_factory_can_import(csvPath)  #

            AssetImportTask = unreal.AssetImportTask()
            AssetImportTask.set_editor_property('filename', csvPath)
            AssetImportTask.set_editor_property('factory', factory)
            AssetImportTask.set_editor_property('destination_path',
                                                self.UEMeshDirectory)
            AssetImportTask.set_editor_property('automated',
                                                True)  #self.automateImports)
            importSettings = unreal.CSVImportSettings()
            #importSettings.set_editor_property('import_row_struct',True)
            path_to_asset = '/OVFPPlugin/generalResources/blenderToUnrealAdgBridge/B2UADGBrige_MeshHierarcyCSV'  #.B2UADGBrige_MeshHierarcyCSV'
            asset_reg = unreal.AssetRegistryHelpers.get_asset_registry()
            #CSVstruct = asset_reg.get_asset_by_object_path(path_to_asset)
            CSVstruct = unreal.load_asset(path_to_asset)
            #unreal.log_warning(str(CSVstruct))
            factory.automated_import_settings.import_row_struct = CSVstruct

            #AssetImportTask.set_editor_property('save', False)
            import_tasks.append(AssetImportTask)

            #do the import
            self.AssetTools.import_asset_tasks(import_tasks)

            unreal.EditorAssetLibrary.save_directory(
                self.UEMeshDirectory)  #save directory we imported into
        except Exception:
            unreal.log("Issue with hierarcy file")
    def check_directory(self, directory):
        for ignore in self.ignore_paths:
            if directory.startswith(ignore):
                return

        if unreal.EditorAssetLibrary.does_directory_exist(directory):
            # get_assets_by_pathは/で終わる場合PackageNameとして認識しないので変換
            directory_name = unreal.Paths.normalize_directory_name(directory)
            if len(unreal.AssetRegistryHelpers.get_asset_registry().
                   get_assets_by_path(directory_name, True)) == 0:
                # uassetではないアセットが存在する場合はDeleteに失敗する
                unreal.EditorAssetLibrary.delete_directory(directory)
                unreal.log('delete: {}'.format(directory.encode('utf-8')))
예제 #19
0
 def _execute_within_exception_trap(self):
     """
     Execute the callback and log any exception that gets raised which may otherwise have been
     swallowed by the deferred execution of the callback.
     """
     if self._callback is not None:
         try:
             unreal.log("_execute_within_exception_trap: trying callback {0}".format(self._callback.__str__()))
             self._callback()
         except Exception, e:
             current_engine = sgtk.platform.current_engine()
             current_engine.logger.exception("An exception was raised from Toolkit")
         self._callback = None
예제 #20
0
    def check_asset(self, asset_data):
        package_name = unreal.StringLibrary.conv_name_to_string(
            asset_data.package_name)
        if len(
                unreal.EditorAssetLibrary.find_package_referencers_for_asset(
                    package_name, False)) == 0:
            asset_name = unreal.StringLibrary.conv_name_to_string(
                asset_data.asset_name)
            asset_class = asset_data.asset_class

            unreal.log('[{0}] {1} {2}'.format(asset_class,
                                              asset_name.encode('utf-8'),
                                              package_name.encode('utf-8')))
예제 #21
0
        def get_shotgun_menu_items(self):
            """
            Returns the list of available menu items to populate the SG menu in Unreal.
            """
            menu_items = []

            engine = sgtk.platform.current_engine()
            menu_items = self.create_menu(engine)

            unreal.log_warning("get_shotgun_menu_items is deprecated, get_shotgrid_menu_items should be used instead.")
            unreal.log("get_shotgun_menu_items returned: {0}".format(menu_items.__str__()))

            return menu_items
예제 #22
0
    def execute_command(self, command_name):
        """
        Callback to execute the menu item selected in the SG menu in Unreal.
        """
        engine = sgtk.platform.current_engine()

        unreal.log("execute_command called for {0}".format(command_name))
        if command_name in engine.commands:
            unreal.log("execute_command: Command {0} found.".format(command_name))
            command = engine.commands[command_name]
            command_callback = command["callback"]
            command_callback = self._get_command_override(engine, command_name, command_callback)

            self._execute_callback(command_callback)
예제 #23
0
def rename_assets(search_pattern, replace_pattern, use_case):
    # instances of unreal classes
    system_lib = unreal.SystemLibrary()
    editor_util = unreal.EditorUtilityLibrary()
    string_lib = unreal.StringLibrary()

    # get the selected assets
    selected_assets = editor_util.get_selected_assets()
    num_assets = len(selected_assets)
    replaced = 0

    unreal.log("Selected {} asset/s".format(num_assets))

    # loop over each asset and rename
    for asset in selected_assets:
        asset_name = system_lib.get_object_name(asset)

        # check if the asset name contains the to be replaced text
        if string_lib.contains(asset_name, search_pattern, use_case=use_case):
            search_case = unreal.SearchCase.CASE_SENSITIVE if use_case else unreal.SearchCase.IGNORE_CASE
            replaced_name = string_lib.replace(asset_name, search_pattern, replace_pattern, search_case=search_case)
            editor_util.rename_asset(asset, replaced_name)

            replaced += 1
            unreal.log("Replaced {} with {}".format(asset_name, replaced_name))

        else:
            unreal.log("{} did not match the search pattern, was skipped".format(asset_name))

    unreal.log("Replaced {} of {} assets".format(replaced, num_assets))
    def check_asset_data(self, asset_data):
        package_name = unreal.StringLibrary.conv_name_to_string(
            asset_data.package_name)

        texture_obj = asset_data.get_asset()

        size_x = texture_obj.blueprint_get_size_x()
        size_y = texture_obj.blueprint_get_size_y()

        invalid_x = size_x % 4 != 0
        invalid_y = size_y % 4 != 0
        if invalid_x or invalid_y:
            unreal.log('unable to compress: [{}x{}] {}'.format(
                size_x, size_y, package_name.encode('utf-8')))
예제 #25
0
    def init_qt_app(self):
        self.logger.debug("%s: Initializing QtApp for Unreal", self)

        from sgtk.platform.qt5 import QtWidgets

        if not QtWidgets.QApplication.instance():
            self._qt_app = QtWidgets.QApplication(sys.argv)
            self._qt_app.setQuitOnLastWindowClosed(False)
            unreal.log("Created QApplication instance: {0}".format(
                self._qt_app))
        else:
            self._qt_app = QtWidgets.QApplication.instance()

        # Make the QApplication use the dark theme. Must be called after the QApplication is instantiated
        self._initialize_dark_look_and_feel()
예제 #26
0
    def _emit_log_message(self, handler, record):
        """
        Called by the engine to log messages in Unreal script editor.
        All log messages from the toolkit logging namespace will be passed to this method.

        :param handler: Log handler that this message was dispatched from.
                        Its default format is "[levelname basename] message".
        :type handler: :class:`~python.logging.LogHandler`
        :param record: Standard python logging record.
        :type record: :class:`~python.logging.LogRecord`
        """
        msg = handler.format(record)

        # Assuming the Unreal Editor has a message dialog, you would call
        # here a method that allows to send text to that console. Note that
        # this method can be called from any thread that uses Toolkit logging.
        unreal.log("{0}".format(msg))
예제 #27
0
def launch_nxt_in_ue():
    os.environ[NXT_DCC_ENV_VAR] = 'unreal'
    existing = QtWidgets.QApplication.instance()
    if existing:
        unreal.log('Found existing QApp')
    else:
        unreal.log('Building new QApp for nxt')
        existing = nxt_editor._new_qapp()

    global __NXT_WINDOW
    if __NXT_WINDOW:
        __NXT_WINDOW.show()
        __NXT_WINDOW.raise_()
    else:
        __NXT_WINDOW = nxt_editor.show_new_editor()

    __NXT_WINDOW.close_signal.connect(existing.exit)
    atexit.register(__NXT_WINDOW.close)
예제 #28
0
def _sc_test_file_strings():
    unreal.log("\nTesting source control file strings.")

    # File strings used in source control commands can be:
    # - export text path (often stored on clipboard)
    file1 = _sc_get_file_from_state(
        r"Texture2D'/Engine/EditorResources/S_Actor.S_Actor'")
    # - asset
    file2 = _sc_get_file_from_state(r"/Engine/EditorResources/S_Actor.S_Actor")
    # - long package name
    file3 = _sc_get_file_from_state(r"/Engine/EditorResources/S_Actor")
    # - relative path
    file4 = _sc_get_file_from_state(r"Content/EditorResources/S_Actor.uasset")
    # - fully qualified path (just use result of relative path)
    file5 = _sc_get_file_from_state(file4)
    # All the resolved file paths should be the same
    same_paths = file1 == file2 == file3 == file4 == file5
    unreal.log(
        "The resolved file paths are all the same: {0}".format(same_paths))
 def readMaterialInstanceCSV(self):
     try:
         with open(self.materialInstanceCSVPath, mode='r') as csv_file:
             csv_reader = csv.reader(csv_file, delimiter=',')
             line_count = 0
             parameterNames = []
             for row in csv_reader:
                 if line_count == 0:
                     unreal.log("Parameters To Import: " + " | ".join(row))
                     parameterNames = row
                     line_count += 1
                 else:
                     self.createMaterialInstance(NewMatName = row[1],parameterNames = parameterNames, parameters = row)
                     #unreal.log("row:" + str(line_count) + " :".join(row))
                     line_count += 1
             unreal.log('Processed ' + str(line_count-1) + ' materials')
         #TODO: search for textures before import
         unreal.EditorAssetLibrary.save_directory(self.UEMaterialDirectory)
     except Exception:
         unreal.log_warning("Issue reading material csv file")
예제 #30
0
    def do_import(self):
        import_task = unreal.AssetImportTask()
        import_task.filename = self.asset_data.get("fbx_file_path")
        import_task.destination_path = self.asset_data.get("game_path")
        import_task.automated = not bool(self.asset_data.get("advanced_ui_import"))
        import_task.replace_existing = True
        import_task.save = False#self.asset_data.get("file_save")

        # abc import options
        if self.asset_data.get("abc_import"):
            options = self.abc_import_option()
        else:
            options = self.fbx_import_option()

        # assign the options object to the import task and import the asset
        import_task.options = options
        unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([import_task])
        skeleton_asset_name = os.path.splitext(options.get_editor_property("skeleton").get_path_name())[0]

        unreal.log(skeleton_asset_name)
        unreal.EditorAssetLibrary.save_asset(skeleton_asset_name)