Filter 3d objects

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
AtD
Posts: 50
Joined: Mon Mar 18, 2019 7:14 am

Filter 3d objects

Post by AtD »

Hi all,
This time I have a scripting question. I doubt I am the first one doing this, but a I could not find a good search tag to get a reasonable number of results here. So I just go to ask straight.

For a script I want to determine from the available objects in my document, the 3d objects or anything that has faces, really. My focus is on Part and PartDesign objects, but I would rather include anything that is suitable by this criterium.
First I get all possible objects by doing

Code: Select all

 doc_obj_list = App.ActiveDocument.Objects 
And then, I am struggling, which is partly confusion / lack of understanding how this should work in FreeCAD. Depending on the objects I have in my doc, the doc_obj_list might look like this (omitting Sketches, GeoObjects here):

Code: Select all

 doc_obj_list = [<Part::PartFeature>, <PartDesign::Pad>, <PartDesign::Pocket>] 
Normally in Python, I would compare types or use isinstance, but this seems to be working inconsistently. For my Part::PartFeature, which is a Fusion object I can successfully perform this:

Code: Select all

part0 = doc_obj_list[0]
type(part0)
>>> <class 'Part.Feature'>
isinstance(part0, Part.Feature)
>>> True
 
But when I do it accordingly for a PartDesign object (a Pad), I get AttributeError: module 'PartDesign' has no attribute 'Feature'.

Code: Select all

obp = App.ActiveDocument.Pad
isinstance(obp, PartDesign.Feature)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: module 'PartDesign' has no attribute 'Feature'
Then again, I tried another way. Instead of going for the type, I tried with the TypeId attribute:

Code: Select all

suitable_features = ['PartDesign::Pad', 'PartDesign::Pocket', 'Part::PartFeature']
feat_name_list = [item.Label for item in doc_object_list if '{}'.format(item.TypeId) in suitable_features]
Which in turn works for the PartDesign objects, but not for the Part objects.

What is a consistent general approach on filtering these objects to my needs? Maybe I am doing a stupid thing at some point?
Happy for any help!
AtD
Posts: 50
Joined: Mon Mar 18, 2019 7:14 am

Re: Filter 3d objects

Post by AtD »

I see, the latter works if I use Part::Fuse instead of Part::PartFeature.
But I don't like this approach, as I have to go through all feature types and including them in my list. A more general approach would be better.
User avatar
Roy_043
Veteran
Posts: 8450
Joined: Thu Dec 27, 2018 12:28 pm

Re: Filter 3d objects

Post by Roy_043 »

Code: Select all

out_list = []
for obj in App.ActiveDocument.Objects:
    if hasattr(obj, "Shape") and obj.Shape.Faces:
        out_list.append(obj)
AtD
Posts: 50
Joined: Mon Mar 18, 2019 7:14 am

Re: Filter 3d objects

Post by AtD »

Good one. I will try that. Thanks!
freedman
Veteran
Posts: 3440
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: Filter 3d objects

Post by freedman »

Here is one I use.

Code: Select all

FreeCAD.Console.PrintMessage("obj.Name = "+obj.Name+"\nobj.Label = "+obj.Label+"\nstr(obj) = "+str(obj)+"\nstr(type(obj)) = "+str(type(obj))+ "\nobj.TypeId = "+obj.TypeId  +  " \n\n")
Post Reply