Unable to delete multiple sub assembly (occurences) under the top node (root component)

Unable to delete multiple sub assembly (occurences) under the top node (root component)

seb.quevillon.1
Participant Participant
930 Views
8 Replies
Message 1 of 9

Unable to delete multiple sub assembly (occurences) under the top node (root component)

seb.quevillon.1
Participant
Participant

Hi,

 

The code below is supposed to delete every single occurrence (sub assembly) under the top node (root Component) that contain 'MALE' or 'FEMALE' in their name. When I run the script, I get an error message (see error message below). Can you please let me know what is the best way to do it.

 

ERROR MESSAGE :

ErrorMessage.png

Design:

Design.jpg

 

Code:

 

 

import adsk.core, adsk.fusion, adsk.cam, traceback

def run(context):

    ui = None

    try:

        app = adsk.core.Application.get()
        ui  = app.userInterface

        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        rootComp = design.rootComponent

        occs = rootComp.occurrences  

        for occ in occs:
            occName = occ.name
            occName = occName.upper()

            if occName.find('MALE') != -1 or occName.find('FEMALE') != -1:
                occ.deleteMe()

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

 

 

 

 

 

 

 

 

 

 

 

 

0 Likes
931 Views
8 Replies
Replies (8)
Message 2 of 9

seb.quevillon.1
Participant
Participant

@BrianEkins , can you please take a look

0 Likes
Message 3 of 9

j.han97
Advocate
Advocate

Hi @seb.quevillon.1 ,

 

Try replacing this line

occs = rootComp.occurrences

by this

occs = list(rootComp.occurrences)
Message 4 of 9

tykapl.breuil
Advocate
Advocate

As @seb.quevillon.1 mentionned, you need to make a copy of the occurences list because when you are iterating through rootComp.occurences deleting an occurence changes the object you are iterating through.

To be clear : imagine you have two occurences that you both want to delete, you start iterating and delete the first one. Then the API checks to see if there is a second occurence to keep iterating but since the first occurence was deleted, the second occurence has become the first and there are no more occurences to iterate through and the program stops.

 

However I do not get an error message either way so if that doesn't solve your problem I invite you to give us an f3d displaying the problem so we can more effectively help you.

 
0 Likes
Message 5 of 9

seb.quevillon.1
Participant
Participant

Hi @tykapl.breuil  and @j.han97 , I modified the code but I still get a bug. As requested, I attached the f3d file and also a video. Thank you for your help.

 

 

0 Likes
Message 6 of 9

tykapl.breuil
Advocate
Advocate

It seems there are problems with the fact that the component are linked and also a problem with test Male v1:1.

With the ui I can't even manage to remove the latter and the former causes problem when trying to break the links with the API.

I had tried adding :

if occ.isReferencedComponent:
    occ.breakLink()
0 Likes
Message 7 of 9

seb.quevillon.1
Participant
Participant

Thank you for investigating, any idea how i can fix it ?

0 Likes
Message 8 of 9

BrianEkins
Mentor
Mentor

I've spent some time looking at this and have come to two conclusions.

 

First, there appears to be a bug when deleting occurrences that are an external reference using the API.

 

Second, the assembly you provided is somehow corrupt. I suspect it's a result of using the API on it and that causing problems.

 

I created a new top-level assembly using the subassemblies and parts you had. It has less problems and when deleting the occurrences the API calls all succeed but the result isn't correct. The timeline looks good and the nodes representing the occurrences are no longer there but the occurrences still show up in the graphics and in the browser. That's wrong and something that needs to be fixed. If I added a line to first break the link so it's now a local assembly, then everything works as expected. 

 

Here's my slightly modified code and the new assembly.

 

import adsk.core, adsk.fusion, adsk.cam, traceback

def run(context):

    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface

        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        rootComp = design.rootComponent

        occs = rootComp.occurrences.asArray() 

        occ: adsk.fusion.Occurrence
        for occ in occs:
            occName = occ.name
            occName = occName.upper()

            if occName.find('MALE') != -1 or occName.find('FEMALE') != -1:
                if occ.isVisible:
                    #occ.breakLink()
                    occ.deleteMe()
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

Until this is fixed, I think the best you can do is start with a good assembly and use the breakLink before deleting.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes
Message 9 of 9

seb.quevillon.1
Participant
Participant

Thank you it works however it takes a really long time to break the links. Using the API, is it possible to insert an existing component from the current project without having it linked ?

0 Likes