Create a FeaturePython object part I

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 'App::Property' objects, without embedding any script in the FreeCAD document file.


 * Creative freedom to adapt FreeCAD for any task!

How Does It Work?
Note: Python scripted classes for FeaturePython objects are not, themselves, serialized with the object when the document file is saved. Embedding script in document files presents a significant security risk and is not permitted in FreeCAD's FCStd file format. Thus, it is important to understand that the state of custom Python class used to extend a FeaturePython object is destroyed when the document is closed and rebuilt when the document is opened and lives entirely apart from the FeaturePython object it manages. Because the code lives apart from the object in this way, it would be misleading to think of the custom Python class as a true FreeCAD object in and of itself, but rather, a manger of native FreeCAD objects. For this reason, a FeaturePython object generated by a custom Python class will lose it's custom functionality if it's document is loaded on a different installation of FreeCAD, unless that installation also has the same copies of the Python classes.

Basic example
The following sample can be found in the src/Mod/TemplatePyMod/FeaturePython.py file, together with several other examples:

Available properties
Properties are the true building stones of FeaturePython objects. Through them, the user will be able to interact and modify your object. After creating a new FeaturePython object in your document ( obj=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Box") ), you can get a list of the available properties by issuing:

You will get a list of available properties:

When adding properties to your custom objects, take care of this:
 * Do not use characters "<" or ">" in the properties descriptions (that would break the xml pieces in the .fcstd file)
 * Properties are stored alphabetically in a .fcstd file. If you have a shape in your properties, any property whose name comes after "Shape" in alphabetic order, will be loaded AFTER the shape, which can cause strange behaviours.

Property Type
By default the properties can be updated. It is possible to make the properties read-only, for instance in the case one wants to show the result of a method. It is also possible to hide the property. The property type can be set using

where mode is a short int that can be set to: 0 -- default mode, read and write 1 -- read-only 2 -- hidden

The EditorModes are not set at FreeCAD file reload. This could to be done by the __setstate__ function. See http://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=10#p108072. By using the setEditorMode the properties are only read only in PropertyEditor. They could still be changed from python. To really make them read only the setting has to be passed directly inside the addProperty function. See http://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=20#p109709 for an example.

Other more complex example
This example makes use of the Part Module to create an octahedron, then creates its coin representation with pivy.

First is the Document object itself:

Then, we have the view provider object, responsible for showing the object in the 3D scene:

Finally, once our object and its viewobject are defined, we just need to call them (The Octahedron class and viewprovider class code could be copied in the FreeCAD python console directly):

Making objects selectable
If you want to make your object selectable, or at least part of it, by clicking on it in the viewport, you must include its coin geometry inside a SoFCSelection node. If your object has complex representation, with widgets, annotations, etc, you might want to include only a part of it in a SoFCSelection. Everything that is a SoFCSelection is constantly scanned by FreeCAD to detect selection/preselection, so it makes sense try not to overload it with unneeded scanning. This is what you would do to include a self.face from the example above:

Simply, you create a SoFCSelection node, then you add your geometry nodes to it, then you add it to your main node, instead of adding your geometry nodes directly.

Working with simple shapes
If your parametric object simply outputs a shape, you don't need to use a view provider object. The shape will be displayed using FreeCAD's standard shape representation:

Same code with use ViewProviderLine

Further information
There are a few very interesting forum threads about scripted objects:

- http://forum.freecadweb.org/viewtopic.php?f=22&t=13740

- http://forum.freecadweb.org/viewtopic.php?t=12139

- https://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=20#p109709

- https://forum.freecadweb.org/viewtopic.php?f=22&t=21330

In addition to the examples presented here have a look at FreeCAD source code src/Mod/TemplatePyMod/FeaturePython.py for more examples.