finding the App::Link of a selected object

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
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

finding the App::Link of a selected object

Post by Zolko »

Hello,

I have an assembly with multiple linked parts in it (App::Link to App::Part), and when I select an object, either in the 3D window or in the tree, I would like to get the App::Link instance to which the selected object belongs. I know how to get the App::Part to which the selected object belongs with getParentGeoFeatureGroup() :

Code: Select all

selectedObj = Gui.Selection.getSelection()[0]
# loop until exhaustion or until we encounter an App::Part
parentPart = selectedObj
while parentPart:
    if parentPart.TypeId=='App::Part':
        break
    parentPart = parentPart.getParentGeoFeatureGroup()
But if I have included this App::Part multiple times with several App::Link instances, this always gives me the parent App::Part. What I would want is the particular App::Link instance in which I have selected the object.

Is there a (similar) way to get the App::Link where the selected object belongs ?
try the Assembly4 workbench for FreCAD — tutorials here and here
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: finding the App::Link of a selected object

Post by DeepSOIC »

I think you need to use new selection API, probably Gui.Selection.getSelectionFromStack(). I don't know the details yet :oops:
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: finding the App::Link of a selected object

Post by Zolko »

Zolko wrote: Wed Dec 04, 2019 9:25 am I have an assembly with multiple linked parts in it (App::Link to App::Part), and when I select an object, either in the 3D window or in the tree, I would like to get the App::Link instance to which the selected object belongs.
DeepSOIC wrote: Wed Dec 04, 2019 12:16 pm I think you need to use new selection API, probably Gui.Selection.getSelectionFromStack().
hi realthunder, may-be you know some more on this topic ?

realthunder wrote: Wed Dec 04, 2019 10:19 pm ping
try the Assembly4 workbench for FreCAD — tutorials here and here
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: finding the App::Link of a selected object

Post by realthunder »

If you want it for coding, there is App.getLinksTo(). Check the python docstring for more info.

If you want it as a command
Screenshot from 2019-12-05 18-38-50.png
Screenshot from 2019-12-05 18-38-50.png (35.65 KiB) Viewed 1915 times
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
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: finding the App::Link of a selected object

Post by Zolko »

realthunder wrote: Thu Dec 05, 2019 10:40 am If you want it for coding, there is App.getLinksTo(). Check the python docstring for more info.
Thank-you, yes that works, but that's not the function I need. What I have is:

EDIT:
  • an assembly (App::Part)
  • that contains App::Links to other App::Parts
  • one of these App::Parts contains an Body LCS (PartDesign::CoordinateSystem)
  • this body has a solid made with PartDesign stuff
  • this solid has a hole
  • I have selected the edge of the hole with the mouse in the assembly window, in one of the instances of the App::Part (there are 2 App::Links pointing to the same App::Part)
  • so I have selected a circular edge the LCS that belongs to an App::Link, which is a instance of the App::Part, either in the 3D window or the model tree
I know how to get the App::Part containing the Body LCS, but I need the particular App::Link that points to the App::Part. If I get the Name or the object itself doesn't matter. But there can be several other instances of the same App::Part.
try the Assembly4 workbench for FreCAD — tutorials here and here
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: finding the App::Link of a selected object

Post by realthunder »

Zolko wrote: Thu Dec 05, 2019 1:36 pm I know how to get the App::Part containing the Body LCS, but I need the particular App::Link that points to the App::Part. If I get the Name or the object itself doesn't matter. But there can be several other instances of the same App::Part.
Here is some code based on your description above. Assuming 'Assembly' is the give parent container.

Code: Select all


for obj in App.ActiveDocument.Assembly.Group:
	linked = obj.getLinkedObject()
	# if you accept both link and non-link, then delete the following two lines.
	if linked == obj:
		continue
	if not linked.isDerivedFrom('App::Part'):
		continue
	lcs = [ o for o in linked.Group if o.isDerivedFrom('PartDesign::CoordinateSystem') ]


If that's still not what you want, maybe you can provide an example file, and tell me which object you want to obtain given which object.
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
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: finding the App::Link of a selected object

Post by Zolko »

realthunder wrote: Thu Dec 05, 2019 10:49 pm If that's still not what you want, maybe you can provide an example file, and tell me which object you want to obtain given which object.
I'll try to describe with the model tree: I have an App::Part clled myPart in a document, that contains an LCS_0, a Body, and an LCS_1. I then have an assembly (it's an App::Part called Model) that has several LCS, and notably LCS_1 and LCS_2. I have inserted myPart twice into the assembly, the first one called myLink_1 and attached to LCS_1, and the second called myLink_2 and attached to LCS_2. Finallly, I have an LCS_3 in the assembly.

Code: Select all

myPart (App::Part)
  │
  ├─ LCS_0
  ├─ Body
  │    ├─ Sketch-1
  │    ├─ Extrusion
  │    ├─ Sketch-2
  │    └─ Extrusion
  └─ LCS_1

  
Model (App::Part)
  │
  ├─ LCS_0
  ├─ Sketch-1
  ├─ LCS_1
  ├─ LCS_2
  │
  ├─ myLink_1 (App::Link to myPart, attached to LCS_1)
  │    ├─ LCS_0
  │    ├─ Body
  │    │   ├─ Sketch-1
  │    │   ├─ Extrusion
  │    │   ├─ Sketch-2
  │    │   └─ Extrusion
  │    └─ LCS_1
  │
  ├─ myLink_2 (App::Link to myPart, attached to LCS_2)
  │    ├─ LCS_0
  │    ├─ Body
  │    │   ├─ Sketch-1
  │    │   ├─ Extrusion
  │    │   ├─ Sketch-2
  │    │   └─ Extrusion
  │    └─ LCS_1                            ← this is selected
  │
  └─ LCS_3
Now, I have selected, in the assembly window, the LCS_1 belonging to myLink_2. I am able to retrieve that it (the selected LCS_1) belongs to myPart, but what I would need to know is that I have selected the LCS_1 the belongs to the instance myLink_2 of myPart.

(because I want to attach, by its ExpressionEngine, LCS_3 of the assembly to the LCS_1 in myLink_2, therefore I need to know the Placement of LCS_1 in myPart → easy, and also the Placement of myLink_2 in the assembly → hard)
try the Assembly4 workbench for FreCAD — tutorials here and here
User avatar
alonso_jamm
Posts: 77
Joined: Mon Nov 11, 2019 11:32 pm

Re: finding the App::Link of a selected object

Post by alonso_jamm »

Zolko wrote: Thu Dec 05, 2019 11:44 pm
Now, I have selected, in the assembly window, the LCS_1 belonging to myLink_2. I am able to retrieve that it (the selected LCS_1) belongs to myPart, but what I would need to know is that I have selected the LCS_1 the belongs to the instance myLink_2 of myPart.
I have tried to do something like that before. I went to the source code of the selection api to found out that I could use

Code: Select all

 
Gui.Selection.getSelectionEx("", 0)[0].SubElementNames 
It returns a list separated with names separated by dots. The first name is the name of the linked part. However, if the linked part is a sub-assembly, then the first name will be the name of the sub-assembly.

I am not sure if this is exactly what you want, but it may be helpful.
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: finding the App::Link of a selected object

Post by realthunder »

Zolko wrote: Thu Dec 05, 2019 11:44 pm Now, I have selected, in the assembly window, the LCS_1 belonging to myLink_2. I am able to retrieve that it (the selected LCS_1) belongs to myPart, but what I would need to know is that I have selected the LCS_1 the belongs to the instance myLink_2 of myPart.
@alonso_jamm is right. Use Gui.Selection.getSelectionEx("",0). This gives you a list of selection with full object hierarchy, inside 'SubElementNames'. Select any object in tree view, and run the following code,

Code: Select all

for sel in Gui.Selection.getSelectionEx("",0):
	# sel.Object is the top parent object
	print(sel.Object.Name)
	for subname in sel.SubElementNames:
		print('\t' + subname)
		
		# getSubObjectList() split the subname with dots to obtain all
		# sub-objects in the path, including the top parent
		
		for obj in sel.Object.getSubObjectList(subname):
			print ('\t\t' + obj.Name)
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
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: finding the App::Link of a selected object

Post by Zolko »

alonso_jamm wrote: Fri Dec 06, 2019 2:21 am

Code: Select all

Gui.Selection.getSelectionEx("", 0)[0].SubElementNames 
I am not sure if this is exactly what you want, but it may be helpful.
yes, this is exactly what I wanted, thank-you
try the Assembly4 workbench for FreCAD — tutorials here and here
Post Reply