Scripted objects with attachment
Introduction
The purpose of this page is to show a minimal example of Part EditAttachment feature using Scripted objects in Python.
See full and complete minimal example below.
The following GIF demonstrates attaching our custom box to a cylinder, and automatically updating it's position when the cylinder's position changes.
NOTE: The box is our custom scripted object, and the cylinder is a regular FreeCAD object generated from the Part workbench.
Making Scripted Objects Attachable
Add Attach Extension
First, we need to add the Part::AttachExtensionPython
extension to our Part::FeaturePython
oject in the constructor, or __init__
method, of our custom scripted object.
1class Box():
2 """Custom Scripted Box Object"""
3
4 def __init__(self, obj):
5 self.Type = 'Box'
6
7 obj.Proxy = self
8
9 ... custom properties
10
11 # Needed to make this object "attachable"
12 obj.addExtension('Part::AttachExtensionPython', obj)
Without adding this code, we'll see the following warning dialog when attaching our custom scripted object to another object.
Update Position Based on Attached Object
Then, in the `execute` method of our custom scripted object, we need to call the `positionBySupport` on our `Part::FeaturePython` object.
1class Box:
2
3 ...
4
5 def execute(self, obj):
6 obj.positionBySupport()
7
8 # Assign a Shape to obj
9 obj.Shape = Part.makeBox(...)
Without calling positionBySupport
, our custom scripted object won't update it's position when the position of the attached-to object changes.
Full and Complete Minimal Example
1import FreeCAD as App
2import Part
3
4
5class Box():
6 """
7 Simple Custom Box Object
8 See Also:
9 https://wiki.freecadweb.org/FeaturePython_Objects
10 """
11
12 def __init__(self, obj):
13 """
14 Constructor
15 Arguments
16 ---------
17 - obj: an existing document object or an object created with FreeCAD.Document.addObject('Part::FeaturePython', '{name}').
18 """
19
20 self.Type = 'Box'
21
22 obj.Proxy = self
23 obj.addProperty('App::PropertyLength', 'Length',
24 'Dimensions', 'Box length').Length = 10.0
25 obj.addProperty('App::PropertyLength', 'Width',
26 'Dimensions', 'Box width').Width = 10.0
27 obj.addProperty('App::PropertyLength', 'Height',
28 'Dimensions', 'Box height').Height = 10.0
29
30 # Needed to make this object "attachable",
31 # or able to attach parameterically to other objects
32 obj.addExtension('Part::AttachExtensionPython', obj)
33
34 def execute(self, obj):
35 """
36 Called on document recompute
37 """
38 # Needed to update position when attached-to object changes position.
39 # Reposition object based on Support, MapMode and MapPathParameter properties.
40 # Returns True if attachment calculation was successful, False if object is not attached and Placement wasn't updated,
41 obj.positionBySupport()
42
43 obj.Shape = Part.makeBox(obj.Length, obj.Width, obj.Height)
44
45
46def create_box(obj_name, document):
47 """
48 Create a Box.
49 """
50 obj = document.addObject('Part::FeaturePython', obj_name)
51 Box(obj)
52 obj.ViewObject.Proxy = 0 # Mandatory unless ViewProvider is coded
53 return obj
54
55
56document = App.ActiveDocument
57if document is None:
58 document = App.newDocument('Part Attachment Example')
59
60box = create_box('CustomBox', document)
61document.recompute()
References
- Part EditAttachment
- FreeCAD Forum - Parametric attachment of scripted object
- FreeCAD Forum - Port attachment to be an extension
- GitHub - freecad-part-attachment-python-example
Tested With the Following FreeCAD Version
Tested with the following FreeCAD version information:
OS: Ubuntu 18.04.3 LTS Word size of OS: 64-bit Word size of FreeCAD: 64-bit Version: 0.18.16146 (Git) AppImage Build type: Release Branch: (HEAD detached at 0.18.4) Hash: 980bf9060e28555fecd9e3462f68ca74007b70f8 Python version: 3.6.7 Qt version: 5.6.2 Coin version: 4.0.0a OCC version: 7.3.0 Locale: English/UnitedStates (en_US)
Note: For FreeCAD 0.19 this tutorial needs a minor update:
- The second argument of the`addExtension` method got deprecated.
- For details see https://forum.freecadweb.org/viewtopic.php?f=10&t=54370

- FreeCAD scripting: Python, Introduction to Python, Python scripting tutorial, FreeCAD Scripting Basics
- Modules: Builtin modules, Units, Quantity
- Workbenches: Workbench creation, Gui Commands, Commands, Installing more workbenches
- Meshes and Parts: Mesh Scripting, Topological data scripting, Mesh to Part, PythonOCC
- Parametric objects: Scripted objects, Viewproviders (Custom icon in tree view)
- Scenegraph: Coin (Inventor) scenegraph, Pivy
- Graphical interface: Interface creation, Interface creation completely in Python (1, 2, 3, 4, 5), PySide, PySide examples beginner, intermediate, advanced
- Macros: Macros, How to install macros
- Embedding: Embedding FreeCAD, Embedding FreeCADGui
- Other: Expressions, Code snippets, Line drawing function, FreeCAD vector math library (deprecated)
- Hubs: User hub, Power users hub, Developer hub