App.ActiveDocument.findObjects parameters

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
nic
Posts: 135
Joined: Thu Apr 18, 2019 1:14 pm
Location: France

App.ActiveDocument.findObjects parameters

Post by nic »

Hello,

I try to figure how to look for a specific sketch in my document. App.ActiveDocument.findObjects() looks to be what I want.

the function's signature is findObjects([string(type)], [string (name)]) -> list

However, I don't understand how to fill the type's string. In the following example, I try to get a sketch called "hull":

Code: Select all

>>> App.ActiveDocument.findObjects('Sketcher.SketchObject', 'hull')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
Base.FreeCADError: 'Sketcher.SketchObject' is not a valid type
>>> # next try:
>>> App.ActiveDocument.findObjects('SketchObject', 'hull')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
Base.FreeCADError: 'SketchObject' is not a valid type
User avatar
gbroques
Posts: 167
Joined: Thu Jan 23, 2020 3:28 am
Location: St. Louis, Missouri

Re: App.ActiveDocument.findObjects parameters

Post by gbroques »

nic wrote: Fri Jun 26, 2020 12:33 pm Hello,

I try to figure how to look for a specific sketch in my document. App.ActiveDocument.findObjects() looks to be what I want.

the function's signature is findObjects([string(type)], [string (name)]) -> list

However, I don't understand how to fill the type's string. In the following example, I try to get a sketch called "hull":
I'm not sure what to pass in for the type. :?

Code: Select all

>>> help(App.ActiveDocument.findObjects)
Help on built-in function findObjects:

findObjects(...) method of App.Document instance
    findObjects([string (type)], [string (name)]) -> list
    Return a list of objects that match the specified type and name.
    Both parameters are optional.
You could use getObject or getObjectsByLabel depending upon if you have the Name or Label of the sketch.

I'm assuming "hull" is either the name or label.
nic
Posts: 135
Joined: Thu Apr 18, 2019 1:14 pm
Location: France

Re: App.ActiveDocument.findObjects parameters

Post by nic »

gbroques wrote: Fri Jun 26, 2020 12:42 pm
Yes, this is the workaround I currently use:

Code: Select all

hulls = App.ActiveDocument.getObjectsByLabel('hull')
hulls = [h for h in hulls if h.Module == 'Sketcher']  # keep only sketches
if len(hulls) != 1:
    raise ValueError('more than one sketch called hull was found')
hull = hulls[0]
User avatar
gbroques
Posts: 167
Joined: Thu Jan 23, 2020 3:28 am
Location: St. Louis, Missouri

Re: App.ActiveDocument.findObjects parameters

Post by gbroques »

nic wrote: Fri Jun 26, 2020 12:46 pm
gbroques wrote: Fri Jun 26, 2020 12:42 pm
Yes, this is the workaround I currently use:

Code: Select all

hulls = App.ActiveDocument.getObjectsByLabel('hull')
hulls = [h for h in hulls if h.Module == 'Sketcher']  # keep only sketches
if len(hulls) != 1:
    raise ValueError('more than one sketch called hull was found')
hull = hulls[0]
I think you need Sketcher::SketchObject for the type as opposed to Sketcher.SketchObject. Note, the double colon "::".

See Also: https://forum.freecadweb.org/viewtopic.php?t=208
Last edited by gbroques on Fri Jun 26, 2020 12:52 pm, edited 3 times in total.
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: App.ActiveDocument.findObjects parameters

Post by Zolko »

nic wrote: Fri Jun 26, 2020 12:33 pm

Code: Select all

>>> App.ActiveDocument.findObjects('Sketcher.SketchObject', 'hull')

Code: Select all

>>> App.ActiveDocument.findObjects('Sketcher::SketchObject','hull')
[]
try the Assembly4 workbench for FreCAD — tutorials here and here
wmayer
Founder
Posts: 20245
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: App.ActiveDocument.findObjects parameters

Post by wmayer »

With type the C++ class name including namespace is meant. E.g. for a sketch object it is: Sketcher::SketchObject

Let's say you have a document with a sketch as last created object. Then you get its type string with:

Code: Select all

doc=App.ActiveDocument
doc.ActiveObject.TypeId
# 'Sketcher::SketchObject'
You get all sketches with:

Code: Select all

doc.findObjects("Sketcher::SketchObject")
EDIT: The second name is about the internal name of an object and it supports regular expressions. If the sketches have names of the form Sketch, Sketch001, ... you get them with
doc.findObjects("Sketcher::SketchObject","Sketch\\d{0,}")
nic
Posts: 135
Joined: Thu Apr 18, 2019 1:14 pm
Location: France

[solved] Re: App.ActiveDocument.findObjects parameters

Post by nic »

understood

However, findObjects look for obect's Name (and not Label). I'll keep the workaround described above, even if it's not elegant, as I need to search by Label.

thanks to all for the support and this great Software.

[my life]
A friend of mine came yesterday and ask me why I was working with FreeCAD, and why I was not using my my (costly) CREO licence. I think it would be really hard for me to go back now that I have this FreeCAD and Python power together!

Still need to learn C++
[/my life]
wmayer
Founder
Posts: 20245
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: App.ActiveDocument.findObjects parameters

Post by wmayer »

nic wrote: Fri Jun 26, 2020 1:13 pm However, findObjects look for obect's Name (and not Label). I'll keep the workaround described above, even if it's not elegant, as I need to search by Label.
The findObjects() function can be easily extended by a third parameter to also handle the Label.
nic
Posts: 135
Joined: Thu Apr 18, 2019 1:14 pm
Location: France

Re: App.ActiveDocument.findObjects parameters

Post by nic »

wmayer wrote: Fri Jun 26, 2020 1:20 pm The findObjects() function can be easily extended by a third parameter to also handle the Label.
That would be nice, indeed!
wmayer
Founder
Posts: 20245
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: App.ActiveDocument.findObjects parameters

Post by wmayer »

git commit 79e11ce8a

findObject now has a third parameter to allow to search by label.

The changes in detail are:
* Add third paramater to search by label

* Support of Python keywords. Because all three parameters are optional and you may only want to search by type and label but not the internal name you can write

Code: Select all

doc.findObjects(Type="Sketcher::SketchObject", Label="hull")
The old syntax is still supported. So if you write

Code: Select all

doc.findObjects("Sketcher::SketchObject", "hull")
then it checks for the type and internal name. The label is ignored. The three keywords are: Type, Name and Label

* For Name and Label regular expressions are supported and internally boost's implementation is used. In the past we used boost::regex_match so that the whole string must match. But this can make things difficult to find the correct expression. That's why it has been replaced with boost::regex_search.
In case an exact match is required then this can be achieved by changing the expression itself. So, instead of expression you have to write ^expression$
Post Reply