User: Can you give me some specific advice about creating an add-on for Blender ? I'm using Blender 2.79. I've written a series of Python scripts which are all stored within a .blend file. The main one runs on loading the file, and calls several other scripts that set up GUI menus. These scripts in turn call other scripts to run various functions. So at the moment, to run it you need a specific .blend file containing all these various scripts. My question is, how can I turn this into an external file (e.g. a .zip file) that the user can load from any .blend file they happen to be using ? ChatGPT: Yes, you can package your add-on as a separate file that can be loaded into Blender. Here are the steps to do this: 1. Create a new folder on your computer to store the add-on files. 2. Inside this folder, create a new Python script file. This script will be the main file that loads all the other scripts and sets up the menus. 3. Move all your other Python scripts into this folder. 4. In the main Python script file, use the `bpy.utils` module to register your add-on with Blender. You can use the `register_module()` function to register all the scripts in the folder as part of your add-on. Here is an example: ``` import bpy from bpy.utils import register_module # import all the other scripts in the folder import script1 import script2 import script3 # register the add-on with Blender register_module(__name__) ``` 5. Save the main Python script file and all the other scripts in the folder. 6. Create a new text file in the folder called `__init__.py`. This file should be empty, but it tells Blender that this folder is an add-on. 7. Select all the files in the folder and compress them into a .zip file. 8. In Blender, open the User Preferences window and go to the Add-ons tab. 9. Click the "Install Add-on from File" button and select the .zip file you just created. 10. Enable the add-on by checking the box next to its name in the list of add-ons. 11. Save the user preferences to make sure the add-on is loaded the next time you start Blender. Now your add-on should be available to use in any .blend file you open. You can distribute the .zip file to other users, who can then install the add-on in the same way. User: Oh wow, thank you so much ! I may have more questions later. ChatGPT: You're welcome! Feel free to ask any other questions you may have. I'll be happy to help! User: Does the main script need to have a special name ? How does Blender know this is the main file ? ChatGPT: The main Python script file in your add-on does not need to have a special name, but it must be named with a `.py` extension. When you use the `register_module()` function to register your add-on with Blender, you pass in the name of the module as an argument. The name of the module is determined by the name of the Python script file that contains the `register_module()` function call. For example, if your main Python script file is called `my_addon.py`, you would use the following code to register your add-on: ``` register_module("my_addon") ``` Blender will automatically load the `my_addon.py` file when the user enables the add-on in the User Preferences window. The file will be executed, and any modules or classes defined in the file will be available for use in the add-on. So in summary, Blender does not look for a specific file to be the main file of an add-on. Instead, it looks for a Python script file that contains a call to `register_module()`, and that file is considered the main file for the add-on. User: Ahh I see ! Thank you very much for that clear explanation. Are there any differences in the procedure between Blender 2.7 and later versions ? ChatGPT: The overall procedure for creating an add-on in Blender has not changed significantly between Blender 2.7 and later versions. However, there are some minor differences you should be aware of: 1. In Blender 2.8 and later versions, the User Preferences window has been renamed to the Preferences window. It can be opened by clicking the Edit menu in the top left corner of the Blender window and selecting Preferences. 2. In Blender 2.8 and later versions, the `register_module()` function has been deprecated and replaced with the `register()` function. The `register()` function is used to register classes that define operators, panels, menus, and other components of the add-on. Here is an example: ``` import bpy # define a class for an operator class MyOperator(bpy.types.Operator): bl_idname = "my_addon.my_operator" bl_label = "My Operator" def execute(self, context): # do something return {'FINISHED'} # register the class with Blender def register(): bpy.utils.register_class(MyOperator) # unregister the class with Blender def unregister(): bpy.utils.unregister_class(MyOperator) ``` 3. In Blender 2.8 and later versions, the `__init__.py` file is no longer needed to indicate that a folder contains an add-on. Instead, add-ons are defined in a `addon-info` file, which is a JSON file that contains metadata about the add-on, such as its name, version, description, and author. The `addon-info` file is located in the add-on's top-level directory. 4. In Blender 2.8 and later versions, add-ons can also be installed as `.py` files or `.zip` files, in addition to the `.blend` files used in Blender 2.7. Installing an add-on as a `.py` file requires that the add-on be contained in a directory with the same name as the `.py` file (without the `.py` extension). So if you're developing an add-on for Blender 2.7, the procedure I outlined earlier should work fine. But if you plan to migrate your add-on to Blender 2.8 or later versions, you will need to make some adjustments to your code and file structure. User: Thanks for that. Sorry but I forgot something quite important ! At the moment, my .blend file contains not only a set of scripts, but also many objects. These are included because generating them takes considerable time. In this case, is it worth converting to an add-on, or would it be better just to distribute the .blend file ? ChatGPT: If your `.blend` file contains not only scripts, but also many objects that are important for your add-on, then it might be more appropriate to distribute the `.blend` file instead of converting it to an add-on. One of the main benefits of creating an add-on is that it allows the user to easily enable and disable the add-on without affecting the objects in the scene. However, if the objects are an integral part of the add-on, and the add-on cannot function without them, then distributing a `.blend` file with the objects included might be the best option. Distributing the `.blend` file has some advantages: - It is simple and easy for the user to install and use, since they only need to open the `.blend` file to use the add-on. - The objects are included in the file, so there is no need to generate them each time the add-on is used. - It allows the user to easily modify the objects if they need to. On the other hand, distributing the `.blend` file has some disadvantages: - It may be more difficult to maintain, since any changes to the add-on or the objects will require a new version of the `.blend` file to be distributed. - It may be more difficult to distribute updates or bug fixes, since the user will need to download and replace the entire `.blend` file. - The user will need to open the `.blend` file every time they want to use the add-on, which may be less convenient than simply enabling the add-on in the User Preferences. Ultimately, the decision to distribute the add-on as an external file or as a `.blend` file will depend on the specific needs and requirements of your add-on and your users. User: What you say makes good sense. In my case I think distributing the .blend is the best solution. I also have another, different question if I may. ChatGPT: Sure, feel free to ask your question! User: So the scripts in the file typically access astronomical FITS files, which can be very large. I'd like to avoid the user having to copy the files into the same directory as the .blend fine. On Linux I can use symbolic links and the scripts are able to access the files directly, however on Windows, shortcuts (the equivalent of symbolic links) don't work. Is there something else I could use ? ChatGPT: On Windows, you can use junction points to create symbolic links between directories. A junction point is a type of symbolic link that is specifically designed for directories. To create a junction point, you can use the `mklink` command in the Command Prompt or PowerShell. Here's an example: ``` mklink /J "C:\path\to\junction" "C:\path\to\real\directory" ``` This will create a junction point at `C:\path\to\junction` that points to `C:\path\to\real\directory`. Once you've created the junction point, your Python scripts should be able to access the files in the linked directory as if they were in the same directory as the `.blend` file. Note that creating a junction point requires administrator privileges, so you may need to run the Command Prompt or PowerShell as an administrator. Also note that junction points are only available on NTFS file systems, so if you're using a different file system (such as FAT32), you may need to use a different method to create symbolic links. User: I'm trying to access files, not directories - will that work ? What happens if the file is moved ? ChatGPT: Ah, my apologies for misunderstanding your question. On Windows, you can create symbolic links to files using the `mklink` command with the `/H` flag. For example: ``` mklink /H "C:\path\to\symbolic\link.txt" "C:\path\to\real\file.txt" ``` This will create a hard link at `C:\path\to\symbolic\link.txt` that points to `C:\path\to\real\file.txt`. If the linked file is moved, the symbolic link will continue to work as long as the new location of the file is on the same volume (i.e. drive letter) as the original location. If the file is moved to a different volume, you will need to recreate the symbolic link at the new location. Note that creating symbolic links to files also requires administrator privileges, and may not work on some file systems (such as FAT32). system: User: Oh wow, that sounds great ! Thank you so much ! ChatGPT: You're welcome! I'm glad I could help. If you have any more questions, feel free to ask!