How to Create a Custom FreeCAD Workbench in Python

This guide provides a step-by-step overview of creating a custom workbench in FreeCAD using Python. You will learn where to locate the extensions directory, how to configure the necessary file structure, how to define the workbench class using InitGui.py, and how to register a functional Python command to your workbench toolbar and menus.

Step 1: Locate the FreeCAD Addon Directory

FreeCAD loads user-defined workbenches from its Mod directory. Locate the directory based on your operating system:

  • Linux: ~/.local/share/FreeCAD/Mod/ or ~/.FreeCAD/Mod/
  • macOS: ~/Library/Application Support/FreeCAD/Mod/
  • Windows: %APPDATA%\FreeCAD\Mod\

Create a new folder inside the Mod directory for your custom workbench, for example, MyCustomWorkbench.

Step 2: Create the File Structure

Inside your new folder MyCustomWorkbench, create two files:

  1. InitGui.py – Contains the workbench definition, menu/toolbar setup, and FreeCAD GUI registration.
  2. my_command.py – Contains the logic for the specific tool or command you want to run.

Step 3: Write the Custom Command Logic

Open my_command.py and implement a standard FreeCAD GUI command class:

import FreeCAD
import FreeCADGui

class SimpleBoxCommand:
    """Command that creates a standard box in the active document."""

    def GetResources(self):
        return {
            'Pixmap': 'Std_Tool1', # Built-in icon name or path to an .svg/.xpm file
            'MenuText': 'Create Test Box',
            'ToolTip': 'Creates a simple box at the origin'
        }

    def Activated(self):
        doc = FreeCAD.ActiveDocument
        if not doc:
            doc = FreeCAD.newDocument()
        
        box = doc.addObject("Part::Box", "MyBox")
        box.Length = 10.0
        box.Width = 10.0
        box.Height = 10.0
        doc.recompute()
        FreeCAD.Console.PrintMessage("Custom Box Created Successfully!\n")

    def IsActive(self):
        return True

# Register the command with FreeCAD's GUI command manager
FreeCADGui.addCommand('MyCustom_CreateBox', SimpleBoxCommand())

Step 4: Define the Workbench in InitGui.py

FreeCAD scans InitGui.py on startup to register the interface elements. Open InitGui.py and define the workbench:

import FreeCADGui
import my_command  # Imports and registers your custom commands

class MyCustomWorkbench(FreeCADGui.Workbench):
    """Custom Workbench definition."""

    MenuText = "My Custom Workbench"
    ToolTip = "A custom workbench built with Python"
    Icon = """
        /* XPM */
        static char * custom_icon[] = {
        "16 16 2 1",
        "  c None",
        ". c #0000FF",
        "                ",
        "  ............  ",
        "  ............  ",
        "  ..        ..  ",
        "  ..        ..  ",
        "  ..        ..  ",
        "  ..        ..  ",
        "  ............  ",
        "  ............  ",
        "  ..        ..  ",
        "  ..        ..  ",
        "  ..        ..  ",
        "  ..        ..  ",
        "  ............  ",
        "  ............  ",
        "                "};
    """

    def Initialize(self):
        """Executed when the workbench is activated for the first time."""
        # Define toolbars
        self.appendToolbar("Custom Tools", ["MyCustom_CreateBox"])
        
        # Define menus
        self.appendMenu("Custom Tools", ["MyCustom_CreateBox"])

    def Activated(self):
        """Executed whenever the user switches to this workbench."""
        pass

    def Deactivated(self):
        """Executed whenever the user switches away from this workbench."""
        pass

    def ContextMenu(self, recipient):
        """Optional context menu items."""
        pass

    def GetClassName(self): 
        return "Gui::PythonWorkbench"

# Register the workbench class
FreeCADGui.addWorkbench(MyCustomWorkbench())

Step 5: Test the Workbench

  1. Launch or restart FreeCAD.
  2. Open the workbench selector dropdown in the top navigation bar.
  3. Select My Custom Workbench.
  4. Click the newly added Create Test Box button in the toolbar or select it from the Custom Tools menu to verify that the command executes.