SelObserver, accessing body name

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: 3466
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

SelObserver, accessing body name

Post by freedman »

I'm stuck. My ultimate goal is to mouse select an object using SelObserver, then find all sketches that make up the selected object, then set their deviations/properties. The problem it appears, getselection() returns the name of the last feature instead of the name of the body. I need the top level name to trigger the search so I can find all the sketches in that body. How do I find the top level name?

I included a simple macro example that prints to Report. If you run it and select an object it will report. It's best to have more than one body on the screen.

Thanks
Attachments
SEL_test1.FCMacro
(1.94 KiB) Downloaded 28 times
ickby
Veteran
Posts: 3116
Joined: Wed Oct 05, 2011 7:36 am

Re: SelObserver, accessing body name

Post by ickby »

Objects have methods to get the group they are in. Right know I cannot look up the exact names, but they are something like

Code: Select all

GetParentGroup //all possible groups
GetParentGeoFeatureGroups // only geofeature groups, e.g. part or body
freedman
Veteran
Posts: 3466
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: SelObserver, accessing body name

Post by freedman »

Thanks, If anyone has some examples it would be good to see them. I have found a work around so I'm OK.
Thanks
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: SelObserver, accessing body name

Post by openBrain »

Hi freedman,

The below snippet will list all objects that are of Sketch type and that are really used to build the Body (i.e. it will ignore sketches that are in the body but not used for operations).

Code: Select all

[obj for obj in Gui.Selection.getSelection()[0].getParentGeoFeatureGroup().OutListRecursive if obj not in Gui.Selection.getSelection()[0].getParentGeoFeatureGroup().ViewObject.claimChildren() and obj.TypeId == 'Sketcher::SketchObject']
It makes a lot of assumptions :
  • It assumes that the object of interest is the first of the selection
  • It assumes the selected object is really in a body
Also it uses getSelection() instead of the "object" parameter of the Selection Observer. ;)

HTH
freedman
Veteran
Posts: 3466
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: SelObserver, accessing body name

Post by freedman »

I ran this:

Code: Select all

  s=[obj for obj in Gui.Selection.getSelection()[0].getParentGeoFeatureGroup().OutListRecursive if obj not in Gui.Selection.getSelection()[0].getParentGeoFeatureGroup().ViewObject.claimChildren() and obj.TypeId == 'Sketcher::SketchObject']
           App.Console.PrintWarning("Found sketch name " + str(obj.Name)+"\n")   
and it worked OK until I got to this, see pic. You can see the selection is a chamfer but the code report spit out the prior object feature which is a polar pattern without a name. Don't know why, maybe because there is no associated sketch. ;)
Anyway, this code is close. If nothing else it's interesting to see python power. Wow! If you want to try to fix this I will do some testing.

I will use my hack for now, you will see later. Eventually FreeCAD will have some standardized ways of looking thru models using Part, Part Design and others. Right now it's difficult to handle all situations and takes more test time than I have.

Thanks
Attachments
chamfer1.JPG
chamfer1.JPG (15.01 KiB) Viewed 756 times
polar_snip.JPG
polar_snip.JPG (51.98 KiB) Viewed 756 times
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: SelObserver, accessing body name

Post by openBrain »

freedman wrote: Mon Jul 01, 2019 7:44 am I ran this:

Code: Select all

  s=[obj for obj in Gui.Selection.getSelection()[0].getParentGeoFeatureGroup().OutListRecursive if obj not in Gui.Selection.getSelection()[0].getParentGeoFeatureGroup().ViewObject.claimChildren() and obj.TypeId == 'Sketcher::SketchObject']
           App.Console.PrintWarning("Found sketch name " + str(obj.Name)+"\n")   
There is some inconsistency between your code and your screenshot. Especially "PrintWarning" seems to be called in a loop that isn't in the code.
Just looking the code, I suspect that printing 'obj' out of the list comprehension leads to weird result. In your example, you should print the 's' variable instead.
Also some indentation problem in your code but maybe due to forum. ;)
If you want to see your list correctly :

Code: Select all

s=[obj for obj in Gui.Selection.getSelection()[0].getParentGeoFeatureGroup().OutListRecursive if obj not in Gui.Selection.getSelection()[0].getParentGeoFeatureGroup().ViewObject.claimChildren() and obj.TypeId == 'Sketcher::SketchObject']
App.Console.PrintWarning("Found sketches named " + str([obj.Name for obj in s])+"\n") 
Could you provide the file you use, so I can test instead of guess ? ;)
freedman
Veteran
Posts: 3466
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: SelObserver, accessing body name

Post by freedman »

My goal of getting all the sketches has worked, thank you openbrain. I have run into an issue, when there is a shapebinder in the Body I get all of the shapebinder sketches also. I have not figured out how to remove them, yet! I don't want them in my list.

Also, I'm working to target object types. I attached a macro that Reports them when mouse selected. Question: When in Part design and a body is in a Part container, how do I get the Part container name on mouse selection?

Thanks all
Attachments
Best_report1.FCMacro
(1.81 KiB) Downloaded 16 times
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: SelObserver, accessing body name

Post by openBrain »

freedman wrote: Mon Jul 08, 2019 6:04 pm My goal of getting all the sketches has worked, thank you openbrain. I have run into an issue, when there is a shapebinder in the Body I get all of the shapebinder sketches also. I have not figured out how to remove them, yet! I don't want them in my list.
I can't reproduce that behavior ATM. Do you have a FC file that demonstrates ?
Also, I'm working to target object types. I attached a macro that Reports them when mouse selected. Question: When in Part design and a body is in a Part container, how do I get the Part container name on mouse selection?
Let say 'obj' is a Body sketch. 'obj.getParentGeoFeatureGroup()' returns the Body. If the Body is inside a Part Container, then 'obj.getParentGeoFeatureGroup().getParentGeoFeatureGroup()' will return the Part Container. ;)
You can also check if there is a <Part object> in 'obj.InListRecursive'.

From the code you posted, I don't exactly understand why you use 'Gui.Selection.getSelection()' rather than the 'object' which comes as a parameter of the observer. :?
Post Reply