0
$\begingroup$

I would like to create add-on for blender 3.6 that allows me to mark an asset in the current file I am using then let me choose an unopened file I want it appended to. This add-on should give me options for selection for the file path of the unopened file I want to append items I've marked as an asset to.

In the same folder as the blend file I want to append these assets to, there is a file there called 'blender_assets.cats'. this file contains the names of the categories of assets for the chosen unopened file in that folder I want to append items I've marked as an asset to. This file contains the catalog names for which I want to create a dropdown menu showing the list of catalogs.

The names for the category occur after the second semicolon on eack of lines 9,10,11,12, and so on until the end of the document. I need to write proper code for handling this selection and saving the asset to the correct catalog name for the specified blend file should be written into this script.

If no 'blender_assets.cats' file exsist the catalog name should be "Catalog"

Finally I want the the add-on to have a backup file path selection button and function that allows me to save the blend file that retains its name adding 'backup" and a timestamp, to the path that's is specified. This function will back up the original before making any changes to to it. This function will also creates the new backup file before deleting the previous backup.

I've looked at the blender API and the add-on seems totally posible but I can't seem to get the code to work.

The output you produce should be a complete python script that makes a the described add-on interface in the navigation tab under the "create" tab. It will be named "Append to File" This interface should have

  1. A functional directory selection button allowing for the selection of the desired file to append to.
  2. A funtional catalog selection button that gives a drop down list that is populated by the 'blender_assets.cats' file in the manner I described.
  3. A funtional, optional that uses a check box to activate, backup directory selection box with a button to select the directory from that creates and names the backup in the described manner.

Here's the code I've come up with but cant seem to get it to work properly. Could I get some advice on what I'm doing wrong?

bl_info = {
    "name": "Append to File",
    "blender": (3, 6, 0),
    "category": "Object",
}

import bpy
import os
import subprocess
from datetime import datetime

# Directory to save temporary files
TEMP_DIRECTORY = bpy.app.tempdir

class AppendToFileOperator(bpy.types.Operator):
    bl_idname = "object.append_to_file"
    bl_label = "Append to File"
    bl_options = {'REGISTER', 'UNDO'}

    filepath: bpy.props.StringProperty(subtype='FILE_PATH')
    backup_directory: bpy.props.StringProperty(subtype='DIR_PATH', default=bpy.app.tempdir)
    select_catalog: bpy.props.BoolProperty(name="Select Catalog", default=False)
    catalog: bpy.props.StringProperty(name="Catalog")

    def execute(self, context):
        # Make sure a file is selected
        if not self.filepath:
            self.report({'ERROR'}, "No file selected")
            return {'CANCELLED'}

        # Make sure the file is a .blend file
        if not self.filepath.endswith(".blend"):
            self.report({'ERROR'}, "Selected file is not a .blend file")
            return {'CANCELLED'}

        # Append to the file
        self.append_to_file(self.filepath)

        return {'FINISHED'}

    def append_to_file(self, filepath):
        # Save current file path
        current_filepath = bpy.data.filepath

        # Backup current file with timestamp
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        backup_filename = bpy.path.basename(current_filepath) + timestamp
        backup_filepath = os.path.join(self.backup_directory, backup_filename)
        bpy.ops.wm.save_as_mainfile(filepath=backup_filepath, copy=True)

        # Save the current selected objects to a temporary .blend file
        temp_filepath = os.path.join(TEMP_DIRECTORY, "temp.blend")
        bpy.ops.wm.save_as_mainfile(filepath=temp_filepath, copy=True)

        # Script to run on the target .blend file
        catalog_string = f'"{self.catalog}"' if self.select_catalog else "None"
        script = f"""
import bpy

# Filepath of the temporary .blend file
source_blend_filepath = r"{temp_filepath}"

# Catalog to append the asset to
catalog = {catalog_string}

# Load objects from the temporary .blend file
with bpy.data.libraries.load(source_blend_filepath) as (data_from, data_to):
    data_to.objects = data_from.objects

# Link the objects to the current scene
for obj in data_to.objects:
    if obj is not None:
        bpy.context.collection.objects.link(obj)

# Save and close the .blend file
bpy.ops.wm.save_mainfile()

# Quit Blender
bpy.ops.wm.quit_blender()
"""

        # Path to the Python script
        script_filepath = os.path.join(TEMP_DIRECTORY, "append_script.py")

        # Save the Python script to a file
        with open(script_filepath, "w") as file:
            file.write(script)

        # Run a new instance of Blender with the Python script
        subprocess.run([bpy.app.binary_path, filepath, '-P', script_filepath])

class AppendToFilePanel(bpy.types.Panel):
    bl_label = "Append to File"
    bl_idname = "OBJECT_PT_append_to_file"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "Tool"

    def draw(self, context):
        layout = self.layout
        operator = layout.operator(AppendToFileOperator.bl_idname)
        layout.prop(operator, "filepath")
        layout.prop(operator, "backup_directory")
        layout.prop(operator, "select_catalog")
        if operator.select_catalog:
            layout.prop(operator, "catalog")

def register():
    bpy.utils.register_class(AppendToFileOperator)
    bpy.utils.register_class(AppendToFilePanel)

def unregister():
    bpy.utils.unregister_class(AppendToFileOperator)
    bpy.utils.unregister_class(AppendToFilePanel)

if __name__ == "__main__":
    register()
```
$\endgroup$
2
  • $\begingroup$ And what point it starts to work wrongly and what is the expected behavior? $\endgroup$
    – kemplerart
    Commented Jun 17, 2023 at 10:05
  • $\begingroup$ Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. $\endgroup$
    – Community Bot
    Commented Jun 17, 2023 at 10:06

0

You must log in to answer this question.

Browse other questions tagged .