[Solved] Selection of a Link, get the Name and Placement

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
freedman
Veteran
Posts: 3441
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

[Solved] Selection of a Link, get the Name and Placement

Post by freedman »

I'm trying to select a 3D object (selection observer) and change it's placement. Does any one have code example of how to select a Link and then reference the object to it's placement. Links are new to me and I can't figure out how to get the Link name as an object and then change the Link placement.
Thanks
Last edited by freedman on Mon Dec 06, 2021 10:47 pm, edited 3 times in total.
freedman
Veteran
Posts: 3441
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: Looking for selection of a Link object

Post by freedman »

I finally got something to work. I read the Link page stuff a few times and most of it is over my head, no examples of selecting a Link and doing something with it, at least not that I could find.
Here is what got me going.
https://forum.freecadweb.org/viewtopic. ... nk#p351748

What I wanted, what I did:
In my model I made a Link of an object, then I set the Element count (of the Link) to 16. When the element count is changed to more than zero FreeCAD makes the current link a kind-of Part container and creates 16 sublinks under the Link. The code below detects a Link and then displays the link placement, which is what I wanted.

I hacked away to get this, maybe someone can clean it up to more resemble what we would normally want, like a reference to an object. I don't know why FreeCAD can't just convert to get the link object, then we could select and do "obj.Name". Anyway a Link is a subobject and there it is. :)

Code: Select all

self.obj_link = False
self.ob1 =  Gui.Selection.getSelectionEx("",0)[0]
if self.ob1.ObjectName == "Link":
	print("It's a Link..............")
        self.obj_link = True
self.ob1 =  Gui.Selection.getSelectionEx("",0)
for sel in self.ob1:
	for subname in sel.SubElementNames:
        	for x,obj in enumerate(sel.Object.getSubObjectList(subname)):
                	if x == 1:
                        	print(obj.Name)
                                print(obj.Placement)
                                self.ob1 = obj
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: [Solved] Selection of a Link, get the name and Placement

Post by TheMarkster »

if obj.Name == "Link" works fine as long as there is only one link and this is it. But if it is the 2nd link created it will be "Link001" and the test will fail. Suggest you use obj.TypeId == "App::Link" instead.
User avatar
onekk
Veteran
Posts: 6146
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: [Solved] Selection of a Link, get the name and Placement

Post by onekk »

As @TheMarkster has said testing for a Name usually involve that at least you will test using .startswith("something") as Names are usually assigned automatically by FreeCAD during creation, and not in all cases could be assigned even using a script at object creation.

Plus if you will use some objects, I've encountered this behaviour with Path:Job some action are triggered by the presence of the "Job" in the Name itself, so even if it is modifiable better to use something like "Links_something" "just in case" and hoping that it is not matched against some "regular expression" that expect a sort of "Name+numbers" as Name property.

Sadly this sort of things are not written and sometimes only reading sources You could be aware of such "peculiar" behaviours.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
freedman
Veteran
Posts: 3441
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: [Solved] Selection of a Link, get the name and Placement

Post by freedman »

I'll make a general statement and say most folks aren't going to use "Link" if they just need one duplicate so the sub-sub is the typical one.
We have these:
Gui.ActiveDocument.getInEdit().Object
FreeCADGui.Selection.getSelection()[0]
FreeCADGui.Selection.getSelectionEx("",0)
FreeCADGui.Selection.getSelectionEx("",0)[0]

I would think there could be an option or a new getSelection() to retrieve the object "selected Link". When the models get bigger and objects are buried in 5 layers of Part there should be some support for Link.

It seems like there was a lot of work put into Link but the last step did not get taken, that would be link selection.
Suggest you use obj.TypeId == "App::Link" instead.
Yes, I will do that.

This came up because I wanted to post a file and it is 2 meg. There were a bunch of duplicates that I created as Bodies so I rebuilt the model with Links. Now the file is 900KB but I have to go rewrite the macro to use Links. :( It's all good, I wanted to learn how but it's always a time issue.
Thanks
freedman
Veteran
Posts: 3441
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: [Solved] Selection of a Link, get the name and Placement

Post by freedman »

When selecting in the 3D we need to look for "obj.TypeId == "App::LinkElements" or "obj.TypeId == "App::Link". After that we use two different processes to get a reference to the object.

Only "App::Link" has the attribute "ElementCount" which shows that it's the parent.
Post Reply