Scripted objects with attachment: Difference between revisions
Renatorivo (talk | contribs) No edit summary |
Edwilliams16 (talk | contribs) (Second argument of obj.addExtension() is deprecated) |
||
(10 intermediate revisions by 7 users not shown) | |||
Line 3: | Line 3: | ||
<translate> |
<translate> |
||
==Introduction== |
==Introduction== <!--T:1--> |
||
<!--T:2--> |
|||
The purpose of this page is to show a minimal example of [[Part |
The purpose of this page is to show a minimal example of [[Part_EditAttachment|Part EditAttachment]] feature using [[Scripted objects]] in Python. |
||
<!--T:3--> |
|||
See [[#Full_and_Complete_Minimal_Example|full and complete minimal example]] below. |
See [[#Full_and_Complete_Minimal_Example|full and complete minimal example]] below. |
||
<!--T:4--> |
|||
The following |
The following GIF demonstrates attaching our custom box to a cylinder, and automatically updating it's position when the cylinder's position changes. |
||
</translate> |
</translate> |
||
[[File:Box-attached-to-cylinder-demo.gif]] |
[[File:Box-attached-to-cylinder-demo.gif]] |
||
<translate> |
<translate> |
||
<!--T:5--> |
|||
'''NOTE:''' The box is our custom scripted object, and the cylinder is a regular FreeCAD object generated from the Part workbench. |
'''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== |
==Making Scripted Objects Attachable== <!--T:6--> |
||
===Add Attach Extension=== |
===Add Attach Extension=== <!--T:7--> |
||
<!--T:8--> |
|||
First, we need to add the <code>Part::AttachExtensionPython</code> extension to our <code>Part::FeaturePython</code> oject in the constructor, or <code>__init__</code> method, of our custom scripted object. |
First, we need to add the <code>Part::AttachExtensionPython</code> extension to our <code>Part::FeaturePython</code> oject in the constructor, or <code>__init__</code> method, of our custom scripted object. |
||
</translate> |
</translate> |
||
Line 33: | Line 40: | ||
# Needed to make this object "attachable" |
# Needed to make this object "attachable" |
||
obj.addExtension('Part::AttachExtensionPython' |
obj.addExtension('Part::AttachExtensionPython') |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
<translate> |
<translate> |
||
<!--T:9--> |
|||
Without adding this code, we'll see the following warning dialog when attaching our custom scripted object to another object. |
Without adding this code, we'll see the following warning dialog when attaching our custom scripted object to another object. |
||
</translate> |
</translate> |
||
[[File:Part-attachment-warning-dialog.png]] |
[[File:Part-attachment-warning-dialog.png]] |
||
<translate> |
<translate> |
||
⚫ | |||
⚫ | |||
<!--T:11--> |
|||
Then, in the `execute` method of our custom scripted object, we need to call the `positionBySupport` on our `Part::FeaturePython` object. |
Then, in the `execute` method of our custom scripted object, we need to call the `positionBySupport` on our `Part::FeaturePython` object. |
||
</translate> |
</translate> |
||
Line 56: | Line 67: | ||
</syntaxhighlight> |
</syntaxhighlight> |
||
<translate> |
<translate> |
||
<!--T:12--> |
|||
Without calling <code>positionBySupport</code>, our custom scripted object won't update it's position when the position of the attached-to object changes. |
Without calling <code>positionBySupport</code>, our custom scripted object won't update it's position when the position of the attached-to object changes. |
||
==Full and Complete Minimal Example== |
==Full and Complete Minimal Example== <!--T:13--> |
||
</translate> |
</translate> |
||
<syntaxhighlight lang="python" line='line'> |
<syntaxhighlight lang="python" line='line'> |
||
Line 92: | Line 104: | ||
# Needed to make this object "attachable", |
# Needed to make this object "attachable", |
||
# or able to attach parameterically to other objects |
# or able to attach parameterically to other objects |
||
obj.addExtension('Part::AttachExtensionPython' |
obj.addExtension('Part::AttachExtensionPython') |
||
def execute(self, obj): |
def execute(self, obj): |
||
Line 124: | Line 136: | ||
</syntaxhighlight> |
</syntaxhighlight> |
||
<translate> |
<translate> |
||
⚫ | |||
⚫ | |||
* [[Part Attachment]] |
|||
<!--T:15--> |
|||
* [[Part_EditAttachment|Part EditAttachment]] |
|||
* [https://forum.freecadweb.org/viewtopic.php?f=22&t=24794 FreeCAD Forum - Parametric attachment of scripted object] |
* [https://forum.freecadweb.org/viewtopic.php?f=22&t=24794 FreeCAD Forum - Parametric attachment of scripted object] |
||
* [https://forum.freecadweb.org/viewtopic.php?f=10&t=18978&start=10 FreeCAD Forum - Port attachment to be an extension] |
* [https://forum.freecadweb.org/viewtopic.php?f=10&t=18978&start=10 FreeCAD Forum - Port attachment to be an extension] |
||
* [https://github.com/gbroques/freecad-part-attachment-python-example GitHub - freecad-part-attachment-python-example] |
* [https://github.com/gbroques/freecad-part-attachment-python-example GitHub - freecad-part-attachment-python-example] |
||
==Tested With the Following FreeCAD Version== |
==Tested With the Following FreeCAD Version== <!--T:16--> |
||
<!--T:17--> |
|||
Tested with the following FreeCAD version information: |
Tested with the following FreeCAD version information: |
||
</translate> |
</translate> |
||
Line 149: | Line 164: | ||
Locale: English/UnitedStates (en_US) |
Locale: English/UnitedStates (en_US) |
||
</pre> |
</pre> |
||
<translate> |
|||
<!--T:18--> |
|||
⚫ | |||
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 |
|||
</translate> |
|||
⚫ | |||
⚫ | |||
[[Category:Python Code{{#translation:}}]] |
[[Category:Python Code{{#translation:}}]] |
||
{{clear}} |
{{clear}} |
Latest revision as of 22:17, 19 March 2024
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.
class Box():
"""Custom Scripted Box Object"""
def __init__(self, obj):
self.Type = 'Box'
obj.Proxy = self
... custom properties
# Needed to make this object "attachable"
obj.addExtension('Part::AttachExtensionPython')
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.
class Box:
...
def execute(self, obj):
obj.positionBySupport()
# Assign a Shape to obj
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
import FreeCAD as App
import Part
class Box():
"""
Simple Custom Box Object
See Also:
https://wiki.freecadweb.org/FeaturePython_Objects
"""
def __init__(self, obj):
"""
Constructor
Arguments
---------
- obj: an existing document object or an object created with FreeCAD.Document.addObject('Part::FeaturePython', '{name}').
"""
self.Type = 'Box'
obj.Proxy = self
obj.addProperty('App::PropertyLength', 'Length',
'Dimensions', 'Box length').Length = 10.0
obj.addProperty('App::PropertyLength', 'Width',
'Dimensions', 'Box width').Width = 10.0
obj.addProperty('App::PropertyLength', 'Height',
'Dimensions', 'Box height').Height = 10.0
# Needed to make this object "attachable",
# or able to attach parameterically to other objects
obj.addExtension('Part::AttachExtensionPython')
def execute(self, obj):
"""
Called on document recompute
"""
# Needed to update position when attached-to object changes position.
# Reposition object based on Support, MapMode and MapPathParameter properties.
# Returns True if attachment calculation was successful, False if object is not attached and Placement wasn't updated,
obj.positionBySupport()
obj.Shape = Part.makeBox(obj.Length, obj.Width, obj.Height)
def create_box(obj_name, document):
"""
Create a Box.
"""
obj = document.addObject('Part::FeaturePython', obj_name)
Box(obj)
obj.ViewObject.Proxy = 0 # Mandatory unless ViewProvider is coded
return obj
document = App.ActiveDocument
if document is None:
document = App.newDocument('Part Attachment Example')
box = create_box('CustomBox', document)
document.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