Scanning OutList of App::Part.

Need help, or want to share a macro? Post here!
keithsloan52
Posts: 1911
Joined: Mon Feb 27, 2012 5:31 pm

Scanning OutList of App::Part.

Postby keithsloan52 » Sun Apr 19, 2020 5:07 pm

Okay I wish to process the objects in a part ( App::Part)

I scan the OutList with something like

Code: Select all

     for obj in part.OutList :
          process(obj)
But the thing is some of the objects are boolean's or multifuse and I need to deal with them, which I can, but
the two objects that comprise the boolean and n objects that are part of fhe multifuse are still in the parts outlist
and I don't want to process them again.

Anybody else had to deal with this and is there a clean way to deal with the situation. i.e. is there a neat way to skip the
next 2 or n objects in the for in loop?

Thanks
vocx
Posts: 5205
Joined: Thu Oct 18, 2018 9:18 pm

Re: Scanning OutList of App::Part.

Postby vocx » Sun Apr 19, 2020 9:33 pm

keithsloan52 wrote: Sun Apr 19, 2020 5:07 pm and I don't want to process them again.
Use a list to add the processed objects and test against this list for each element during the iteration.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
keithsloan52
Posts: 1911
Joined: Mon Feb 27, 2012 5:31 pm

Re: Scanning OutList of App::Part.

Postby keithsloan52 » Mon Apr 20, 2020 4:55 am

vocx wrote: Sun Apr 19, 2020 9:33 pm
keithsloan52 wrote: Sun Apr 19, 2020 5:07 pm and I don't want to process them again.
Use a list to add the processed objects and test against this list for each element during the iteration.
Thanks for the suggestion, but does not seem very elegant, lots of scanning of lists and could really slow down the processing of large files.
CERN's Alice.gdml file has over 10,000 objects
keithsloan52
Posts: 1911
Joined: Mon Feb 27, 2012 5:31 pm

Re: Scanning OutList of App::Part.

Postby keithsloan52 » Mon Apr 20, 2020 5:03 am

Okay think I am going to try

Code: Select all

l = len(Part.OutList)
i = 0
while i < l :
     i = process (i,OutList)

and have process access OutList[i] and return i+1 for non Boolean & Multfuse
User avatar
onekk
Posts: 955
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Scanning OutList of App::Part.

Postby onekk » Mon Apr 20, 2020 9:11 am

each object like compound have a property that contains the object that belong to it and every objects has a property that return if an object is a part of something else:

Code: Select all

obj.InList[0].Name
Maybe usign some python function, like filter will speed things ups.

See this code, very simply it creates 1000 cylinders and organize then in row then use filter() to create a "list" that contains only the created compound ad then use a "normal" for loop to prin the names of each objects.

Code: Select all


import FreeCAD
from FreeCAD import Base, Rotation, Vector

DOC = FreeCAD.activeDocument() 

def test_map():
    row = 0
    cnt = 0
    cmps= []

    for x in range(0, 1000):
        obj = DOC.addObject("Part::Cylinder", "Name" + str(x))
        obj.Radius = 5
        obj.Height = 10
        print("row: ", row, "cnt: ", cnt)
        xpos =  cnt * 10
        obj.Placement = FreeCAD.Placement(Vector(xpos, row * 10, 0), Rotation())
        cnt += 1
        cmps.append(obj)
        if cnt > 50:
            obj_c = DOC.addObject("Part::Compound", "Row_" + str(row))
            obj_c.Links = cmps
            cmps = []
            row += 1 
            cnt = 0
        
    if len(cmps) > 0:
        obj_c = DOC.addObject("Part::Compound", "Row_" + str(row))
        obj_c.Links = cmps        

compound = test_map()

b_names = filter(lambda s: s.TypeId == "Part::Compound", DOC.Objects)

for obj in b_names:
    print(obj.Name)
    for comp in obj.OutList:	
       print(comp.Name)
Only an hint.

Regards

Carlo D.
Il mio Blog: https://onekk-maker.blogspot.com/

Introduzione a FreeCAD in Italiano: https://github.com/onekk/freecad-doc
galou_breizh
Posts: 362
Joined: Wed Sep 15, 2010 9:38 am

Re: Scanning OutList of App::Part.

Postby galou_breizh » Sat May 02, 2020 9:10 am

Maybe this:

Code: Select all

def get_all_subobjects(o):
    """Recursively get all subobjects
    Subobjects of objects having a Shape attribute are not included otherwise each
    single feature of the object would be copied. The result is that bodies,
    compounds, and the result of boolean operations will be converted into a
    simple copy of their shape.
    """
    # Depth-first search algorithm.
    discovered = []
    # We do not need an extra copy for stack because OutList is already a copy.
    stack = o.OutList
    while stack:
        v = stack.pop(0)
        if v not in discovered:
            discovered.append(v)
            if not hasattr(v, 'Shape'):
                stack += v.OutList
    return discovered
from DeepCopy.FCMacro?