Scripted objects with attachment

From FreeCAD Documentation
Jump to navigation Jump to search
Other languages:
English • ‎français • ‎italiano • ‎русский

Introduction

The purpose of this page is to show a minimal example of Part Attachment 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.

Box-attached-to-cylinder-demo.gif

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.

 1 class 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.

Part-attachment-warning-dialog.png

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.

1 class 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

 1 import FreeCAD as App
 2 import Part
 3 
 4 
 5 class 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 
46 def 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 
56 document = App.ActiveDocument
57 if document is None:
58     document = App.newDocument('Part Attachment Example')
59 
60 box = create_box('CustomBox', document)
61 document.recompute()

References

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)