PR#2995: add PropertyXLinkList, refactor DlgPropertyLink

Merged, abandoned or rejected pull requests are moved here to clear the main Pull Requests forum.
Post Reply
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

PR#2995: add PropertyXLinkList, refactor DlgPropertyLink

Post by realthunder »

PR link https://github.com/FreeCAD/FreeCAD/pull/2995

A new property is added PropertyXLinkList, which provides compatible API to PropertyLinkList, with additional support of external object. This property is actually derived from PropertyXLinkSubList, and works exactly the same, except that its Python output is made compatible with PropertyLinkList, if there is no sub element reference in the property.

Another big part of the PR is for refactoring DlgPropertyLink, the dialog for editing link property from property view. It can now handle all major classes of link properties. The dialog is made modeless, so that the user can select reference from 3D view directly for sub element references.

Image
Try Assembly3 with my custom build of FreeCAD at here.
And if you'd like to show your support, you can donate through patreon, liberapay, or paypal
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: PR#2995: add PropertyXLinkList, refactor DlgPropertyLink

Post by vocx »

realthunder wrote: Tue Feb 04, 2020 2:10 am ... if there is no sub element reference in the property.
It only works if I add an XLink, but none of the older Link, LinkSubList, LinkSubListGlobal, etc. Is this correct?

Also, what is the difference then between XLink and XLinkSub? Both seem to be able to select subelements.

In the Python console it seems XLink only selects a single subelement, while XLinkSub selects many. However, in the property editor, I can see multiple elements for the first one. Maybe this is an error in displaying the subelements? In other words, XLink should only display Edge10 and not multiple Edges.

Code: Select all

>>> App.ActiveDocument.Box.XLink
(<Part::PartFeature>, 'Edge10')
>>> App.ActiveDocument.Box.XLinkSub
(<Part::PartFeature>, ['Edge10', 'Edge5', 'Edge6'])
Multiple_XLink.png
Multiple_XLink.png (35.62 KiB) Viewed 12047 times
On the other hand, XLinkList seems to be able to select only entire objects, not subelements. But XLinkSubList seems to be able to select both, multiple objects and multiple subelements.

Code: Select all

>>> App.ActiveDocument.Box.XLinkList
[<Part::PartFeature>, <Part::PartFeature>]
>>> App.ActiveDocument.Box.XLinkSubList
[(<Part::PartFeature>, ('Edge10', 'Edge5')), (<Part::PartFeature>, ('Edge1',))]
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.
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: PR#2995: add PropertyXLinkList, refactor DlgPropertyLink

Post by realthunder »

vocx wrote: Mon Jun 01, 2020 2:55 am
realthunder wrote: Tue Feb 04, 2020 2:10 am ... if there is no sub element reference in the property.
It only works if I add an XLink, but none of the older Link, LinkSubList, LinkSubListGlobal, etc. Is this correct?
I don't quite understand the question. The sentence you quoted means that PropertyXLinkList python outputs a list of linked objects if there is no sub-object reference inside the reference. If there is then its python output is the same as PropertyXLinkSubList. I didn't change the old links' python output.

In the Python console it seems XLink only selects a single subelement, while XLinkSub selects many. However, in the property editor, I can see multiple elements for the first one. Maybe this is an error in displaying the subelements? In other words, XLink should only display Edge10 and not multiple Edges.
There is really only one type of XLink that directly deals with external linking, that is, PropertyXLink. PropertyXLinkSub is derived from PropertyXLink and behaves almost exactly the same except two differences.

1) It's Python output is compatible with PropertyLinkSub,

2) The link editor dialog allows you to select multiple sub-objects (and/or sub-elements), as long as all the sub-objects belong to the same top-parent object, while for PropertyXLink you can only select one sub-object, but is allowed to select multiple sub-elements (i.e. vertices, edges, faces). Note that PropertyXLink actually can store information for multiple sub-objects. This restriction is imposed by the link editor because App::Link is designed to support only one sub-object (and so is the original implementation of PropertyXLink, but later got extended).

PropertyXLinkSubList is implemented using a list of internal PropertyXLink, so it supports multiple top-parents, multiple sub-objects/sub-elements. And PropertyXLinkList is derived from PropertyXLinkSubList and only differs in Python output.
Try Assembly3 with my custom build of FreeCAD at here.
And if you'd like to show your support, you can donate through patreon, liberapay, or paypal
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: PR#2995: add PropertyXLinkList, refactor DlgPropertyLink

Post by vocx »

realthunder wrote: Mon Jun 01, 2020 6:14 am ...I didn't change the old links' python output.
I'm mostly talking about this behavior of picking subelements from the Link dialog. That's what I mean. This behavior that you show in your GIF, being able to select subelements of different objects, and across documents is only available in the XLink variants, not in the old ones. Is this right? Meaning that if we want to have this in scripted objects, we need to migrate the property to use XLink instead of, say, LinkSubListGlobal, or any of the older types.

By the way, I'm not considering any "subobjects" here. Imagine that I have simple boxes in the root of the document. I am interested in the picking of subelements through the Link dialog. As far as I can tell there is no way of doing this with the older properties. If I want to set one of these, I need to do it from the Python console.

Code: Select all

App.ActiveDocument.Box.LinkSub = [App.ActiveDocument.Another, ["Edge1"]]
2) The link editor dialog allows you to select multiple sub-objects (and/or sub-elements), as long as all the sub-objects belong to the same top-parent object, while for PropertyXLink you can only select one sub-object, but is allowed to select multiple sub-elements (i.e. vertices, edges, faces)...
This is what I find confusing.

In the terminal, XLink prints only one Subelement, but in the Property editor, it shows the three selected Edges that I picked. Why is there a difference? Isn't that confusing?

Code: Select all

>>> App.ActiveDocument.Box.XLink
(<Part::PartFeature>, 'Edge10')
Multiple_XLink_1_alone.png
Multiple_XLink_1_alone.png (11.08 KiB) Viewed 12025 times
PropertyXLinkSubList is implemented using a list of internal PropertyXLink, so it supports multiple top-parents, multiple sub-objects/sub-elements. And PropertyXLinkList is derived from PropertyXLinkSubList and only differs in Python output.
Okay, but if I want to pick edges, I can only use XLinkSubList then.

Basically, I want to pick a single edge of a single geometrical object from the Link dialog. The two alternatives that I see are XLinkSub and XLink. I don't want to use XLinkSubList because I don't want the user to pick multiple objects, just a single object and just a single edge. In my view, XLinkSub appears correctly in the property editor because it shows me all subelements just as in the Python terminal. XLink works but it shows me several edges in the property editor, but only one in the Python console.

So for my use, I would get the value of XLinkSub, and if the user picks multiple edges, I need to discard all of them except the first one, which should be an Edge. And if the user doesn't do it right (selects a face), I need to warn him or her to make a new selection.
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.
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: PR#2995: add PropertyXLinkList, refactor DlgPropertyLink

Post by realthunder »

vocx wrote: Mon Jun 01, 2020 6:57 am I'm mostly talking about this behavior of picking subelements from the Link dialog. That's what I mean. This behavior that you show in your GIF, being able to select subelements of different objects, and across documents is only available in the XLink variants, not in the old ones. Is this right? Meaning that if we want to have this in scripted objects, we need to migrate the property to use XLink instead of, say, LinkSubListGlobal, or any of the older types.
It supports old link properties. I did forget to include PropertyLinkSubList, but fixed it in one of my pending PR. PropertyLinkSub works in upstream.

In the terminal, XLink prints only one Subelement, but in the Property editor, it shows the three selected Edges that I picked. Why is there a difference? Isn't that confusing?

Code: Select all

>>> App.ActiveDocument.Box.XLink
(<Part::PartFeature>, 'Edge10')
This is a bug. I just submit a PR for this, which also include the missing support of PropertyLinkSubList.

Okay, but if I want to pick edges, I can only use XLinkSubList then.
Why not use PropertyLinkSub? If you want external linking, PropertyXLinkSub can also do it. If you are not using sub-objects, then it behave the same as PropertyXLink, except the Python output, which is in the format you want.
Try Assembly3 with my custom build of FreeCAD at here.
And if you'd like to show your support, you can donate through patreon, liberapay, or paypal
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: PR#2995: add PropertyXLinkList, refactor DlgPropertyLink

Post by vocx »

realthunder wrote: Mon Jun 01, 2020 8:24 am ...Why not use PropertyLinkSub?
Okay, I realize it works. The thing is I tried a few properties but since I saw a strange output as explained in my previous post, I thought I'd ask before testing again. Then, probably we'll use LinkSub.
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.
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: PR#2995: add PropertyXLinkList, refactor DlgPropertyLink

Post by vocx »

realthunder wrote: Mon Jun 01, 2020 8:24 am This is a bug. I just submit a PR for this, which also include the missing support of PropertyLinkSubList.
I tested your patch and it seems to work. LinkSub and LinkSubList display well in the Python terminal, and also in the property editor, and the Link dialog allows selecting subelements and multiple objects and subelements respectively.

Code: Select all

>>> App.ActiveDocument.Box.Parameters_LinkSub
(<Part::PartFeature>, ['Edge5', 'Edge6', 'Edge10'])
>>> App.ActiveDocument.Box.Parameters_LinkSubList
[(<Part::PartFeature>, ('Edge5', 'Edge6')), (<Part::PartFeature>, ('Edge1',))]
Multiple_Links.png
Multiple_Links.png (55.51 KiB) Viewed 11954 times
And now XLink and XLinkSub also produce consistent output both in the property editor and the Python console.

Code: Select all

>>> App.ActiveDocument.Box.Parameters_XLink
(<Part::PartFeature>, ['Edge5', 'Edge6', 'Edge10'])
>>> App.ActiveDocument.Box.Parameters_XLinkSub
(<Part::PartFeature>, ['Edge5', 'Edge6', 'Edge10'])
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