Skip to content
πŸ’» 🧠 Code 1001 > πŸ“– Guides > FreeCAD > πŸ“¦ Complete Addon Code FINAL: BoxBuilderAddon

πŸ“¦ Complete Addon Code FINAL: BoxBuilderAddon

A complete, ready-to-use “Box Builder” addon with all improvements from the course β€” in one archive. Simply unpack and place the folder in Mod.

Folder structure:

BoxBuilderAddon/
β”œβ”€β”€ Resources/
β”‚   └── icons/
β”‚       β”œβ”€β”€ box_builder.svg
β”‚       └── create_box.svg
β”œβ”€β”€ InitGui.py
β”œβ”€β”€ box_builder_workbench.py
β”œβ”€β”€ package.xml
β”œβ”€β”€ README.md
└── LICENSE

πŸ“„ 1. InitGui.py

import FreeCADGui
from BoxBuilderAddon.box_builder_workbench import BoxBuilderWorkbench

FreeCADGui.addWorkbench(BoxBuilderWorkbench())

πŸ“„ 2. box_builder_workbench.py

import FreeCAD, FreeCADGui
import os
from PySide import QtGui, QtCore

PARAM_PATH = "User parameter:BaseApp/Preferences/BoxBuilderAddon"

def get_saved_settings():
    params = FreeCAD.ParamGet(PARAM_PATH)
    return {
        "length": params.GetFloat("LastLength", 30.0),
        "width": params.GetFloat("LastWidth", 20.0),
        "height": params.GetFloat("LastHeight", 10.0),
        "name": params.GetString("LastName", "CustomBox"),
        "centered": params.GetBool("LastCentered", False)
    }

def save_settings(length, width, height, name, centered):
    params = FreeCAD.ParamGet(PARAM_PATH)
    params.SetFloat("LastLength", length)
    params.SetFloat("LastWidth", width)
    params.SetFloat("LastHeight", height)
    params.SetString("LastName", name)
    params.SetBool("LastCentered", centered)

def create_box(length, width, height, name="CustomBox", centered=False):
    doc = FreeCAD.ActiveDocument
    if not doc:
        doc = FreeCAD.newDocument("BoxBuilder")

    base_name = name
    index = 1
    obj_name = base_name
    while obj_name in [obj.Name for obj in doc.Objects]:
        obj_name = f"{base_name}_{index}"
        index += 1

    box = doc.addObject("Part::Box", obj_name)
    box.Length = length
    box.Width = width
    box.Height = height

    if centered:
        from FreeCAD import Vector
        box.Placement.Base = Vector(-length/2, -width/2, -height/2)

    doc.recompute()
    return box

class BoxBuilderDialog(QtGui.QDialog):
    def __init__(self):
        super(BoxBuilderDialog, self).__init__()
        self.setWindowTitle("Box Builder")
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.resize(300, 220)

        settings = get_saved_settings()

        self.name_input = QtGui.QLineEdit(settings["name"])
        self.length_input = QtGui.QLineEdit(str(settings["length"]))
        self.width_input = QtGui.QLineEdit(str(settings["width"]))
        self.height_input = QtGui.QLineEdit(str(settings["height"]))
        self.centered_checkbox = QtGui.QCheckBox("Center on origin")
        self.centered_checkbox.setChecked(settings["centered"])

        self.create_button = QtGui.QPushButton("Create Box")
        self.cancel_button = QtGui.QPushButton("Cancel")
        self.reset_button = QtGui.QPushButton("Reset to Defaults")

        self.create_button.clicked.connect(self.on_create)
        self.cancel_button.clicked.connect(self.reject)
        self.reset_button.clicked.connect(self.on_reset)

        layout = QtGui.QFormLayout()
        layout.addRow("Name:", self.name_input)
        layout.addRow("Length (mm):", self.length_input)
        layout.addRow("Width (mm):", self.width_input)
        layout.addRow("Height (mm):", self.height_input)
        layout.addRow("", self.centered_checkbox)

        button_layout = QtGui.QHBoxLayout()
        button_layout.addWidget(self.create_button)
        button_layout.addWidget(self.cancel_button)
        button_layout.addWidget(self.reset_button)

        main_layout = QtGui.QVBoxLayout()
        main_layout.addLayout(layout)
        main_layout.addLayout(button_layout)
        self.setLayout(main_layout)

    def on_create(self):
        try:
            name = self.name_input.text().strip() or "CustomBox"
            length = float(self.length_input.text())
            width = float(self.width_input.text())
            height = float(self.height_input.text())
            centered = self.centered_checkbox.isChecked()

            if length <= 0 or width <= 0 or height <= 0:
                raise ValueError("All dimensions must be positive")

            create_box(length, width, height, name, centered)
            save_settings(length, width, height, name, centered)
            self.accept()

        except ValueError as e:
            QtGui.QMessageBox.warning(self, "Input Error", f"Invalid input:\n{str(e)}")

    def on_reset(self):
        self.name_input.setText("CustomBox")
        self.length_input.setText("30.0")
        self.width_input.setText("20.0")
        self.height_input.setText("10.0")
        self.centered_checkbox.setChecked(False)

class BoxBuilderCommand:
    def GetResources(self):
        icon_path = os.path.join(os.path.dirname(__file__), "Resources", "icons", "create_box.svg")
        return {
            "MenuText": "Box Builder",
            "ToolTip": "Create a box with custom dimensions",
            "Pixmap": icon_path
        }
    def Activated(self):
        dialog = BoxBuilderDialog()
        dialog.exec_()
    def IsActive(self):
        return True

class BoxBuilderWorkbench(FreeCADGui.Workbench):
    MenuText = "Box Builder"
    ToolTip = "Create custom boxes with GUI"

    def __init__(self):
        self.Icon = os.path.join(os.path.dirname(__file__), "Resources", "icons", "box_builder.svg")

    def Initialize(self):
        self.list = ["BoxBuilderCommand"]
        self.appendToolbar("Box Tools", self.list)
        self.appendMenu("Box Builder", self.list)

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

FreeCADGui.addCommand("BoxBuilderCommand", BoxBuilderCommand())

πŸ–Ό 3. Resources/icons/create_box.svg

<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
  <rect x="10" y="10" width="44" height="44" fill="none" stroke="black" stroke-width="4"/>
  <line x1="10" y1="10" x2="20" y2="0" stroke="black" stroke-width="4"/>
  <line x1="54" y1="10" x2="64" y2="0" stroke="black" stroke-width="4"/>
  <line x1="54" y1="54" x2="64" y2="44" stroke="black" stroke-width="4"/>
  <line x1="20" y1="0" x2="64" y2="0" stroke="black" stroke-width="4"/>
  <line x1="64" y1="0" x2="64" y2="44" stroke="black" stroke-width="4"/>
</svg>

πŸ’‘ box_builder.svg β€” simply copy this file and rename it.


πŸ“„ 4. package.xml

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<package format="1" xmlns="https://wiki.freecad.org/Package_Metadata">
  <name>BoxBuilderAddon</name>
  <description>A simple tool to create parametric boxes with custom dimensions and GUI.</description>
  <version>1.0.0</version>
  <date>2025-04-05</date>
  <maintainer email="you@example.com">Your Name</maintainer>
  <license file="LICENSE">LGPL-2.1-or-later</license>
  <url type="repository" branch="main">https://github.com/yourname/BoxBuilderAddon</url>
  <icon>Resources/icons/box_builder.svg</icon>
  <content>
    <workbench>BoxBuilderAddon</workbench>
  </content>
  <dependencies>
    <freecad>0.20</freecad>
  </dependencies>
</package>

πŸ“„ 5. README.md

# Box Builder Addon

Creates parametric boxes with custom dimensions.

## Features
- GUI input
- Saves last values
- Centering option
- Unique naming

πŸ“„ 6. LICENSE

Copy the LGPL-2.1 license text from:
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt


▢️ How to Use

  1. Download all files
  2. Create a BoxBuilderAddon folder in %APPDATA%\FreeCAD\Mod\
  3. Restart FreeCAD
  4. Select the Box Builder workbench
  5. Click the button and create boxes!

Done! This is a complete, working addon β€” from idea to publication.
Now you can modify it for your own tasks or use it as a template for new projects.

Good luck with development! πŸ› οΈ

Leave a Reply

Your email address will not be published. Required fields are marked *