FeaturePython Objects

Introduction
FeaturePython objects (also often referred to as Scripted objects) provide users the ability to extend FreeCAD's with objects that integrate seamlessly into the FreeCAD framework.

This encourages:
 * Rapid prototyping of new objects and tools with custom Python classes.
 * Serialization through objects, without embedding any script in the FreeCAD document file.
 * Creative freedom to adapt FreeCAD for any task!

This wiki will provide you with a complete understanding of how to use FeaturePython objects and custom Python classes in FreeCAD. We're going to construct a complete, working example of a FeaturePython custom class, identifying all of the major components and gaining an intimate understanding of how everything works as we go.

How Does It Work?
FreeCAD comes with a number of default object types for managing different kinds of geometry. Some of them have 'FeaturePython' alternatives that allow for user customization with a custom python class.

The custom python class simply takes a reference to one of these objects and modifies it in any number of ways. For example, the python class may add properties directly to the object, modifying other properties when it's recomputed, or linking it to other objects. In addition the python class implements certain methods to enable it to respond to document events, making it possible to trap object property changes and document recomputes.

It's important to remember, however, that for as much as one can accomplish with custom classes and FeaturePython objects, when it comes time to save the document, only the FeaturePython object itself is serialized. The custom class and it's state are not retained between document reloading. Doing so would require embedding script in the FreeCAD document file, which poses a significant security risk, much like the risks posed by embedding VBA macros in Microsoft Office documents.

Thus, a FeaturePython object ultimately exists entirely apart from it's script. The inconvenience posed by not packing the script with the object in the document file is far less than the risk posed by running a file embedded with an unknown script. However, the script module path is stored in the document file. Therefore, a user need only install the custom python class code as an importable module following the same directory structure to regain the lost functionality.

Setting up your development environment
To begin, FeaturePython Object classes need to act as importable modules in FreeCAD. That means you need to place them in a path that exists in your Python environment (or add it specifically). For the purposes of this tutorial, we're going to use the FreeCAD user Macro folder, though if you have another idea in mind, feel free to use that instead!

If you don't know where the FreeCAD Macro folder is type in FreeCAD's Python console. The place is configurable but, by default, to go there:
 * Windows: Type in the filepath bar at the top of Explorer
 * Linux: Navigate to
 * Mac: Navigate to

Now we need to create some files.
 * In the Macro folder create a new folder called.
 * In the fpo folder create an empty file:.
 * In the fpo folder, create a new folder called.
 * In the box folder create two files:  and  (leave both empty for now)

A Very Basic FeaturePython Object
Let's get started by writing our class and it's constructor:

The method breakdown

In the file at the top, add the following code:

The method breakdown {|class="wikitable" cellpadding="5" style="float:right; margin-left: 15px; margin-right: 5px"
 * style="width:30%" | || Standard import for most python scripts.  The App alias is not required.
 * || Creates a new FreeCAD FeaturePython object with the name passed to the method. If there is no name clash, this will be the label and the name of the created object, i.e. what is visible in the model tree. Otherwise, a unique name and label will be created based on 'obj_name'.
 * method doesn't do anything here (except tell us that it was called), but it is the key to the magic of FeaturePython objects.
 * method doesn't do anything here (except tell us that it was called), but it is the key to the magic of FeaturePython objects.
 * method doesn't do anything here (except tell us that it was called), but it is the key to the magic of FeaturePython objects.

So that's it!

You now know how to build a basic, functional FeaturePython object!

-