Plugins
Freebird allows users to extend its functionality by creating custom plugins. A plugin is a Python file or package that defines new features, such as buttons in the Freebird main menu, custom commands, or integrations with other tools.
Where to Put Plugins
Freebird plugins live in ~/.freebird/plugins:
-
On Windows, this is typically
C:\Users\YourName\.freebird\plugins. -
On Linux, this is typically
/home/yourname/.freebird/plugins.
Freebird loads plugins from that folder when Blender starts, and when you click Reload All in Freebird Settings.
A plugin can be either:
- a single Python file such as
~/.freebird/plugins/hello.py - a folder such as
~/.freebird/plugins/hello_plugin/containing__init__.py
Plugin Structure
To be treated as a plugin, the top-level file must define fb_info with a name field.
fb_info = {"name": "My plugin"}
register() and unregister() methods are optional. If they exist, Freebird calls them when plugins are loaded or unloaded.
Install a Plugin
Place your plugin file or folder in the ~/.freebird/plugins directory, then start Blender or click Reload All in Freebird Settings.
- Open
Freebird Settingsin Blender. - Click
Open Plugins Folder. - Add a Python file or package folder inside the
~/.freebird/pluginsfolder. - Start Blender, or click
Reload Allif Blender is already open. - Open the Freebird main menu and select
CUSTOMto see your plugin buttons.
You can also click Plugins Guide from Freebird Settings to open this page.
Debugging and Logging
If your plugin fails to load, you should see an error message in Freebird's log file. You can see the log file by clicking Freebird Settings > App Log.
To debug a plugin, you can add print() statements to your plugin code (which will send to Blender's console), or use Freebird's logging utility (which will write to Freebird's log file):
from freebird.utils import log
log.info("This is a log message from my plugin")
API: Add a button to the Main Menu Launcher
Import the launcher API from freebird.api:
from freebird.api import add_launcher_button, remove_launcher_button
add_launcher_button(
"my_plugin", # plugin_id
"remesh", # button_id
"REMESH", # button label
onclick=run_remesh, # function to call when the button is clicked
)
plugin_id and button_id must be non-empty strings. label must be a non-empty string. onclick must be callable.
You can also (optionally) provide an icon parameter. This provides the absolute path to the icon file. A default icon will be used if icon is not provided or if the provided path is invalid.
Example 1: Simple "Hello" Plugin
Example file: ~/.freebird/plugins/hello.py
import os
from freebird.api import add_launcher_button, remove_launcher_button
fb_info = {"name": "Hello plugin"}
def on_launcher_click():
print("Hello from a Freebird plugin")
def register():
icon_path = os.path.join(os.path.dirname(__file__), "icon.png")
add_launcher_button(
"hello_plugin",
"hello",
"HELLO",
onclick=on_launcher_click,
icon=os.path.abspath(icon_path),
)
def unregister():
remove_launcher_button("hello_plugin", "hello")
Example 2: Remesh Plugin
Save it as: ~/.freebird/plugins/remesh.py
import bpy
from freebird.api import add_launcher_button, remove_launcher_button
from freebird.utils import log
fb_info = {"name": "Remesh Selected Meshes"}
PLUGIN_ID = "remesh_plugin"
BUTTON_ID = "remesh"
def run_remesh():
selected_meshes = [
obj for obj in bpy.context.selected_objects
if obj.type == "MESH"
]
if not selected_meshes:
log.info("No mesh objects selected")
return
for obj in selected_meshes:
try:
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
modifier = obj.modifiers.new(name="FreebirdRemesh", type="REMESH")
modifier.mode = "VOXEL"
modifier.voxel_size = 0.1
bpy.ops.object.modifier_apply(modifier=modifier.name)
log.info(f"Remeshed object: {obj.name}")
except Exception as e:
log.error(f"Failed to remesh {obj.name}: {e}")
log.info("Finished remeshing selected meshes")
def register():
add_launcher_button(
PLUGIN_ID,
BUTTON_ID,
"REMESH",
onclick=run_remesh,
)
def unregister():
remove_launcher_button(PLUGIN_ID, BUTTON_ID)