Documenting Python Extensions

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
gbroques
Posts: 167
Joined: Thu Jan 23, 2020 3:28 am
Location: St. Louis, Missouri

Documenting Python Extensions

Post by gbroques »

Hi all,
I'm looking to better understand the available extensions in Python.

What are the available extensions?
  • What's the motivation behind a specific extension?
  • Why would you want to use it?
  • How do you use it? What's a simple and minimal example?
How do the they relate to each other?

When would you want to use one vs. the other?

Prior work on this includes a thread started by Joel Graff: Scripted Object documentation.

DeepSOIC mentions two extensions in that thread:
1. Part::AttachExtensionPython
2. App::OriginGroupExtensionPython

I recently covered Part::AttachExtensionPython in the following forum thread and Wiki page: I'm not exactly clear on how App::OriginGroupExtensionPython differs from Part::AttachExtensionPython. They both seem to extend objects and allow you to "group or attach" them together.

See carlopav's post here demonstrating moving a wall with a window in a hierarchical fashion via App::OriginGroupExtensionPython.

The forum thread Proposal: Object Extensions offers a decent introduction to extensions, but you have to dig a lot.

I'd like to document these available extensions, and answer some of those questions from the introduction of this post.

Any information and explanations from more senior members of the community who have experience using them is appreciated.

__________________________________________________________________________
Joel_graff wrote: :bell:
DeepSOIC wrote: :bell:
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Documenting Python Extensions

Post by vocx »

gbroques wrote: Tue Jun 02, 2020 1:02 am ...
I'm not exactly clear on how App::OriginGroupExtensionPython differs from Part::AttachExtensionPython. They both seem to extend objects and allow you to "group or attach" them together.
Please compile the source documentation so that you can see the relationships between the different C++ classes better.

As I understand it, extensions are classes that extend your base object so that it acquires other behavior.

https://github.com/FreeCAD/FreeCAD/blob ... ject.h#L53

Code: Select all

class PartExport Part2DObject : public Part::Feature, public Part::AttachExtension
For example, the Part_Part2DObject, which is the base of most planar figures (Sketches and Draft objects), is based on Part_Feature, and has the Part::AttachExtension so that those geometrical elements can be attached to other elements. For these 2D shapes that means mostly surfaces.

The Part::Primitive class, which is the parent of the Part_Primtives is also derived from Part_Feature, and it also has the Part::AttachExtension, allowing those 3D objects to be attached to planes.

The attach extension is also used with Part::Datum, the parent of the PartDesign Datum objects, that is, coordinate system, line, plane, and point.

To see more information, compile the documentation and look for the App::DocumentObjectExtension class.

Code: Select all

App::DocumentObjectExtension <-- App::GroupExtension <-- App::GeoFeatureGroupExtension <-- App::OriginGroupExtension <-- App::Part
                                 (behave like group)            (with placement)                  (with origin)
The OriginGroupExtension is derived from the GroupExtension. It makes objects able to hold other objects, like groups (Std_Group), but it also provides a Placement, and the Origin object. This extension is used by App::Part, also known as Std_Part.

It is also used by the PartDesign Body, as it also has an Origin, and can group features.

Code: Select all

App::OriginGroupExtension <-- Part::BodyBase <-- PartDesign::Body
If you don't want the Origin, but you still want to group objects and control its placement, you only need to use GeoFeatureGroupExtension. This is what carlopav did. He actually didn't need the origin, only the group behavior and placement.

And if you don't want the Placement, but still want to group objects, then you only need to use GroupExtension. These are simple boxes in the tree view that allow you to store other objects, but which don't control any placement in the 3D view.

I just checked the source documentation, and it seems there are extensions for the GUI side as well. In this case the base class is Gui::ViewProviderExtension.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
gbroques
Posts: 167
Joined: Thu Jan 23, 2020 3:28 am
Location: St. Louis, Missouri

Re: Documenting Python Extensions

Post by gbroques »

Wow! Thanks for detailed and beautiful write-up vocx. This certainly helps :D

Let me try and summarize some of what I gleaned from your post in my own words.

I'm still a bit confused. I guess my hang-up is that I want the ability to have full-fledged "assembly-like funtionality" in FreeCAD, and both of these extensions seem related to "assemblies".

First, to clarify "assembly-like functionality", I mean the ability to create parts that behave as a group, and compose them together with other parts to build more complex parts, and ultimately full-fledged machines. Assembly on the Wiki offers a good introduction.

Now, to offer more detail on how both of these extensions seem related to me.

App::OriginGroupExtension

App::OriginGroupExtension is used with Std Part (App::Part). Therefore, using this extension makes your custom scripted object behave like a Std Part?

From Std Part:
The Std Part element was developed to be the basic building block to create mechanical assemblies. In particular, it is meant to arrange objects that have a Part TopoShape, like Part Primitives, PartDesign Bodies, and other Part Features.
From Assembly:
The Std Part is intended to be the basic building block to create assemblies. Unlike a PartDesign Body, an assembly is meant to be a collection of separate, distinguishable elements which are connected in some way in the physical world, for example, through pressure, screws, or glue.
App::OriginGroupExtension is also used with PartDesign::Body, which also has an Origin, and can group features.

Part::AttachExtension

Part::AttachExtension can be used with Part::Datum, and Part::Datum is used with PartDesign::Body. It simply allows a part to be parameterically linked, or attached to a PartDesign Body using Part Attachment.

From Datum:
datum objects were intended to be used inside PartDesign Bodies. However, since they are useful "reference" objects with different attachment methods, it has been proposed that they should be available outside of the PartDesign Workbench. In this way, they will be usable in all workbenches as supporting geometry, particularly in the context of creating assemblies.
Due to current limitations, this only works with Part::Datum, and thus PartDesign::Body, which groups together parts into one distinct and indistinguishable part.

However, it's been proposed to extend this idea to Std Part (App::Part). Thus, if we did extend this idea to App::Part, then we could "attach" one part to a group a distinguishable parts. This is a current and known limitation.

Is my understanding of all this correct?

Ideally I want to fill in the blanks of the below statements, and capture in a sentence why you'd want to use each extension:

For building custom scripted objects with assembly-like behavior:
  • Use App::OriginGroupExtension to _______
  • Use Part::AttachExtension to _______
Here's my take:
  • Use App::OriginGroupExtension to compose together Part TopoShape, like Part Primitives, PartDesign Bodies, and other Part Features, seen as separate and distinguishable units, so that they can be moved together in the 3D view (see below GIF)
  • Use Part::AttachExtension to give Part::Datum, and thus PartDesign::Body, seen as indistinguishable units, the ability to be "attached to" using Part Attachment (see below GIF)
Let me know if something I said is wrong, partially correct, of if you'd add or change anything.

App::OriginGroupExtension

Image

Part::AttachExtension

Image
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Documenting Python Extensions

Post by vocx »

gbroques wrote: Tue Jun 02, 2020 9:54 am App::OriginGroupExtension is also used with PartDesign::Body, which also has an Origin, and can group features.
Essentially the only difference between a Std_Part and a PartDesign_Body is that the first one can have discontiguous elements, while the second one must contain a single contiguous solid. This is a self imposed limitation, which I think is easy to bypass. If I recall correctly, realthunder has removed this limitation in his own fork, so his PartDesign Bodies can contain separate elements as if they were subassemblies themselves.

Why was this restriction in place then? Because that's the idea the original guys had in 2015 or so, when they were creating the new PartDesign Workbench, and were setting the basic structure for creating an official Assembly workbench. However, those guys didn't develop further all their ideas once v0.17 was released. Now, it seems we are heading into a slightly different direction by implementing the ideas of realthunder.
Here's my take:
  • Use App::OriginGroupExtension to compose together Part TopoShape, like Part Primitives, PartDesign Bodies, and other Part Features, seen as separate and distinguishable units, so that they can be moved together in the 3D view (see below GIF)
  • Use Part::AttachExtension to give Part::Datum, and thus PartDesign::Body, seen as indistinguishable units, the ability to be "attached to" using Part Attachment (see below GIF)
Let me know if something I said is wrong, partially correct, of if you'd add or change anything.
I'm a little bit confused by your confusion. Exactly what is not clear? Part::AttachmentExtension and App::OriginGroupExtension are not related at all.

The OriginGroupExtension allows you to create your own "custom" Std_Part-like objects. Your first point is right.

The AttachExtension allows any object to pick a "support", and become physically attached to that support (face, vertex, edge). In your second point, datum objects can be attached to things, but PartDesign Bodies themselves don't have the attach extension, so they can't be attached.

Code: Select all

>>> App.ActiveDocument.Body.hasExtension("Part::AttachExtension")
False
But you can add that extension

Code: Select all

>>> App.ActiveDocument.Body.addExtension("Part::AttachExtensionPython", App.ActiveDocument.Body)
>>> App.ActiveDocument.Body.hasExtension("Part::AttachExtension")
True
Or in a custom scripted object

Code: Select all

class MyObject:
    def __init__(self, obj):
        obj.addExtension("Part::AttachExtensionPython", self)
The idea is that the Python programmer can create custom objects with origin-like features (OriginGroupExtension), or with attachment capabilities (AttachExtension). By default most programmers would use a Part_Feature object as base (Part::FeaturePython). By default this object doesn't have any of these two extensions, so you can add them to make it behave in special ways, depending on what you want to do with it.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
gbroques
Posts: 167
Joined: Thu Jan 23, 2020 3:28 am
Location: St. Louis, Missouri

Re: Documenting Python Extensions

Post by gbroques »

vocx wrote: Tue Jun 02, 2020 3:37 pm I'm a little bit confused by your confusion. Exactly what is not clear? Part::AttachmentExtension and App::OriginGroupExtension are not related at all.

The OriginGroupExtension allows you to create your own "custom" Std_Part-like objects. Your first point is right.

The AttachExtension allows any object to pick a "support", and become physically attached to that support (face, vertex, edge). In your second point, datum objects can be attached to things, but PartDesign Bodies themselves don't have the attach extension, so they can't be attached.

Code: Select all

>>> App.ActiveDocument.Body.hasExtension("Part::AttachExtension")
False
But you can add that extension

Code: Select all

>>> App.ActiveDocument.Body.addExtension("Part::AttachExtensionPython", App.ActiveDocument.Body)
>>> App.ActiveDocument.Body.hasExtension("Part::AttachExtension")
True
Or in a custom scripted object

Code: Select all

class MyObject:
    def __init__(self, obj):
        obj.addExtension("Part::AttachExtensionPython", self)
The idea is that the Python programmer can create custom objects with origin-like features (OriginGroupExtension), or with attachment capabilities (AttachExtension). By default most programmers would use a Part_Feature object as base (Part::FeaturePython). By default this object doesn't have any of these two extensions, so you can add them to make it behave in special ways, depending on what you want to do with it.
Your reply clears up my confusion in a concise way. Thanks for that.

I'm still very new to FreeCAD so all the classes like Std Part, PartDesign Body, Part Feature, Datum, and moving parts threw me off (in addition to these extensions).

Back to other extensions.

You mention to look at the docs for App::DocumentObjectExtension and outline the related child classes which is helpful.

And we know about Part::AttachExtensionPython. Are there any other extensions worth knowing about for the Python programmer, or are those the main ones?

AN ASIDE ABOUT COMPILING DOCUMENTATION
Has anyone thought about using Travis CI to automatically build the docs and host it with Read the Docs? There's a Sphinx extension called breath for Doxygen support, so it should be possible to host our docs there.

It seems this would be preferable to having everyone manually compile the source themselves just to read the docs.

If I wanted to take that up, then do you have recommendations on how to approach that, or start that conversation?
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Documenting Python Extensions

Post by vocx »

gbroques wrote: Wed Jun 03, 2020 11:01 pm And we know about Part::AttachExtensionPython. Are there any other extensions worth knowing about for the Python programmer, or are those the main ones?
Well, the ones I mentioned above. GroupExtension (behave like a group), GeoFeatureExtension (behave like a group with placement), OriginGroupExtension (behave like a group, with placement, and origin).

Also there are a few LinkExtensions, introduced by realthunder for App::Link, but I'm not entirely sure how to use these. One example implementation is the DraftLink class that realthunder wrote in order to create "Link Arrays" in the Draft Workbench (draftobjects/draftlink). This class is used by the Draft OrthoArray, Draft PolarArray, Draft CircularArray, and Draft PathLinkArray.

Yes, join the party. This is all pretty confusing because there isn't a lot of good, up to date documentation. But I've been doing precisely that, adding tons of documentation to the wiki to try to improve the situation. Now things are better than they were a year ago.
Has anyone thought about using Travis CI to automatically build the docs and host it with Read the Docs? There's a Sphinx extension called breath for Doxygen support, so it should be possible to host our docs there.
Yes! Please do this. Somebody needs to do it! I would do it myself, but I've been busy looking into other parts of the software, so no time to investigate.

Recently a user decided to try this but the plague didn't last long enough, so he needed to resume life, and couldn't dedicate more time to this.

This is now a thread about documentation

He started by adding docstrings to the Arch Workbench files, which he did well, but didn't follow through with the whole implementing Sphinx with FreeCAD.

Check his branch and see if you can continue his work. And also, as I told him, you should document your progress in a page called Sphinx in the wiki. It should be similar to the Doxygen page, with instructions on how to work with the system. Ideally we should have a simple way of generating the documentation, like make DevDocSphinx maybe.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
gbroques
Posts: 167
Joined: Thu Jan 23, 2020 3:28 am
Location: St. Louis, Missouri

Re: Documenting Python Extensions

Post by gbroques »

vocx wrote: Thu Jun 04, 2020 12:26 am Yes, join the party. This is all pretty confusing because there isn't a lot of good, up to date documentation. But I've been doing precisely that, adding tons of documentation to the wiki to try to improve the situation. Now things are better than they were a year ago.
Hahah. :lol:

Agreed, it's confusing and the need for good up to date documentation is critical. I commend you sir!

I'd also like to help improve the situation :D
vocx wrote: Thu Jun 04, 2020 12:26 am
Has anyone thought about using Travis CI to automatically build the docs and host it with Read the Docs? There's a Sphinx extension called breath for Doxygen support, so it should be possible to host our docs there.
Yes! Please do this. Somebody needs to do it! I would do it myself, but I've been busy looking into other parts of the software, so no time to investigate.

Recently a user decided to try this but the plague didn't last long enough, so he needed to resume life, and couldn't dedicate more time to this.

This is now a thread about documentation

He started by adding docstrings to the Arch Workbench files, which he did well, but didn't follow through with the whole implementing Sphinx with FreeCAD.

Check his branch and see if you can continue his work. And also, as I told him, you should document your progress in a page called Sphinx in the wiki. It should be similar to the Doxygen page, with instructions on how to work with the system. Ideally we should have a simple way of generating the documentation, like make DevDocSphinx maybe.
OK this is a great start. I might feel uppity enough about this to make my first real contribution to FreeCAD.

In addition to documenting this in the Sphinx page, are there people I can PM for help or should I make a new thread on the forum if I need help?

Looks like that thread has been dead for over month. Is it OK to bump it?
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Documenting Python Extensions

Post by vocx »

gbroques wrote: Thu Jun 04, 2020 12:56 am In addition to documenting this in the Sphinx page, are there people I can PM for help or should I make a new thread on the forum if I need help?

Looks like that thread has been dead for over month. Is it OK to bump it?
If you want to work on the general documentation, you should probably open a new thread in the Open Discussion subforum. That thread from David was particularly focused on Arch, because he wanted to contribute to that workbench more than anything. But documentation with Doxygen and Sphinx affects the entire project, so it makes sense that it is in a central location so more people can chime in.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
gbroques
Posts: 167
Joined: Thu Jan 23, 2020 3:28 am
Location: St. Louis, Missouri

Re: Documenting Python Extensions

Post by gbroques »

vocx wrote: Thu Jun 04, 2020 1:35 am
gbroques wrote: Thu Jun 04, 2020 12:56 am In addition to documenting this in the Sphinx page, are there people I can PM for help or should I make a new thread on the forum if I need help?

Looks like that thread has been dead for over month. Is it OK to bump it?
If you want to work on the general documentation, you should probably open a new thread in the Open Discussion subforum. That thread from David was particularly focused on Arch, because he wanted to contribute to that workbench more than anything. But documentation with Doxygen and Sphinx affects the entire project, so it makes sense that it is in a central location so more people can chime in.
The post has been made! Please chime in if you feel it's applicable:
https://forum.freecadweb.org/viewtopic.php?f=8&t=47229
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Documenting Python Extensions

Post by vocx »

By the way, this is what I mean by seeing the relationships in the source documentation.

You can see the principal extensions that I mentioned above. One extension that is not pictured is a TechDraw::CosmeticExtension, but that is seemingly used only for TechDraw objects (views).
Extension_relationships.png
Extension_relationships.png (71.84 KiB) Viewed 1566 times
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
Post Reply