SelectionSet.add - unable to get this working

SelectionSet.add - unable to get this working

gvisca44
Advocate Advocate
1,057 Views
7 Replies
Message 1 of 8

SelectionSet.add - unable to get this working

gvisca44
Advocate
Advocate

Several posts on this in the past.  Pretty simple.  Create a SelectionSet via the API (I use large assemblies - and want selection sets for the different components in my designs - mainly so I can simplify creation of drawings).

 

Advice ?  or BUG ?

 

Failing:

Failed:
Traceback (most recent call last):
  File "D:/Users/Public/G2VDesign_OneDrive/OneDrive - G2V DESIGN PTY LTD/Fusion 360 Tools/Add-ins/$GV Test Bed/$GV Test Bed.py", line 36, in run
    design.selectionSets.add(compsToAdd,'NewSelectionSet')
  File "C:\Users/gvisc/AppData/Local/Autodesk/webdeploy/production/99249ee497b13684a43f5bacd5f1f09974049c6b/Api/Python/packages\adsk\core.py", line 17723, in add
    return _core.SelectionSets_add(self, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: 2 : InternalValidationError : owningCompOfEntity == owningCompOfGroups

 

Code:

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

app = None
ui = None
design:adsk.fusion.Design = None

def isDesignLoaded():
    root = design.rootComponent
    occs = root.allOccurrences

    if len(occs) == 0:
        return False
    else:
        return True

def run(context):
	global app, ui, design
	ui = None
	try:
		app = adsk.core.Application.get()
		ui  = app.userInterface
		design = app.activeProduct

		allComponents = design.allComponents

		if not isDesignLoaded():
			ui.messageBox('There are no components in this design.')
			return

		compsToAdd = []
		compsToAdd.append(allComponents[0])
		
		msg = f'{compsToAdd[0].name}'
		app.log(msg)

		design.selectionSets.add(compsToAdd,'NewSelectionSet')

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

 

0 Likes
Accepted solutions (1)
1,058 Views
7 Replies
Replies (7)
Message 2 of 8

kandennti
Mentor
Mentor

Hi @gvisca44 -San.

 

I tried with the data I had on hand and I got the same error.

 

I tried using occurrence instead of the component and made various changes, but I still got the same error.

 

Then I changed it back to the original code and it worked correctly, although I don't know why. However, only that data succeeded and other data still gave the same error.

 

I exported the successful data to attach to the forum, reopened it and ran the script again, but still the same error appears.

 

I don't know why, but I feel that it is not a problem with the code, but with the state of the data in the file, but I have not been able to determine the cause because I have not been able to reproduce it.

0 Likes
Message 3 of 8

gvisca44
Advocate
Advocate

Thanks @kandennti 

 

Anyone at Autodesk have a view on this ? 

 

Or have a working example of creation a selection set full of components or occurrences ?

 

 

0 Likes
Message 4 of 8

gvisca44
Advocate
Advocate

I've had some success with this - but still not satisfactory.

 

I think the key piece of information lies in the guide for selectionSets.add method:

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-35C13BD1-39BA-48CA-BFC0-DB6BBCDE3B70

 

When describing the array that forms an argument to the function:

 An array of entities that will be in the created selection set. All entities must be in the context of the root component. This means if the entity isn't directly owned by the root component, it must be a proxy.

 

Referring to the attached model - the root component contains a sketch and a body.

There are other components (and their occurrences) under the root of course.

 

I am able to create an empty selectionSet, and I can create a selectionSet of the bodies under the root.

 

I am still failing to create a selectionSet containing an occurrence (or anything under an occurrence).

import adsk.core 
import adsk.fusion 
import traceback

app = None
ui = None
design:adsk.fusion.Design = None

def isDesignLoaded():
    root = design.rootComponent
    occs = root.allOccurrences

    if len(occs) == 0:
        return False        
    else:
        return True

def run(context):
    global app, ui, design
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        root:adsk.fusion.Component = design.rootComponent

        if not isDesignLoaded():
            ui.messageBox('There are no components in this design.')
            return

        newEmptyEntity:adsk.core.Base = []
        newBodiesEntity:adsk.core.Base = []
        newOccsEntity:adsk.core.Base = []
        adsk.doEvents()
        design.selectionSets.add(newEmptyEntity,'NewEmpty')

        for body in root.bRepBodies: # Body must exist within the root
            newBodiesEntity.append(body)
        design.selectionSets.add(newBodiesEntity,'NewBodies')

        for occ in root.occurrences:
            newOccsEntity.append(occ)
        design.selectionSets.add(newOccsEntity,'NewOccurrences')    # Fails

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

 

design.selectionSets.add(newOccsEntity,'NewOccurrences') fails with:
RuntimeError: 2 : InternalValidationError : owningCompOfEntity

 

is there something I need to do with "createForAssemblyContext" ?

 

 

0 Likes
Message 5 of 8

kandennti
Mentor
Mentor

@gvisca44 -San.

 

I tried with a proxy and got an error.
I think this is a bug.
I found the same description in the past.

https://forums.autodesk.com/t5/fusion-api-and-scripts/how-to-create-selectionset-using-the-api/m-p/1... 

 

I made a sample using text commands.
It works well.

・・・
        for occ in root.occurrences:
            newOccsEntity.append(occ)
        # design.selectionSets.add(newOccsEntity,'NewOccurrences')    # Fails
        create_selectionSet_txtCmds(newOccsEntity, 'NewOccurrences')

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


def create_selectionSet_txtCmds(
    entities: list[adsk.core.Base],
    name: str) -> adsk.core.SelectionSet:

    app: adsk.core.Application = adsk.core.Application.get()
    ui: adsk.core.UserInterface = app.userInterface
    des: adsk.fusion.Design = app.activeProduct

    selSets: adsk.core.SelectionSets = des.selectionSets
    beforeCount = selSets.count

    sels: adsk.core.Selections = ui.activeSelections
    sels.clear()
    [sels.add(entity) for entity in entities]

    app.executeTextCommand('NuComponents.CreateSelectionGroupCmd')

    sels.clear()

    if not design.selectionSets.count == beforeCount + 1:
        return None

    newSet: adsk.core.SelectionSet = selSets[-1]
    newSet.name = name

    return newSet

You should be able to use the same arguments.

Message 6 of 8

gvisca44
Advocate
Advocate

Thanks @kandennti !  That seems to work well.

 

I am now trying to integrate that code into my add-in, which does things a little differently to my original post.

 

1. If the selection set does NOT exist - create a new one (which your code will do).

2. If the selection set DOES exist - update that selection set with the revised set of Occurrences.

 

I have found NuComponents.UpdateSelectionGroupCmd and as far as I can tell by using the UI, we must first select the "selection set" we want to update, and then select the occurrences.  Then enter the text command above.  

 

But when I try to implement in code - I get an error.

 

sels.add(entity)
  File "C:\Users/gvisc/AppData/Local/Autodesk/webdeploy/production/57cd45aa09be2d79663784069561ec17eda99ca8/Api/Python/packages\adsk\core.py", line 17453, in add
    return _core.Selections_add(self, entity)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: 3 : invalid argument entity

 

 

This code snippet requires a selection set called "UpdateExisting" to be created.

...

        for occ in root.occurrences:
            newOccsEntity.append(occ)
        #design.selectionSets.add(newOccsEntity,'NewOccurrences')    # Fails
        create_selectionSet_txtCmds(newOccsEntity,'NewOccurrences')
        update_selectionSet_txtCmds(newOccsEntity,'UpdateExisting')     # A Selection Set by this name must exist


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

def update_selectionSet_txtCmds(
    entities: list[adsk.core.Base],
    name: str) -> adsk.core.SelectionSet:

    app: adsk.core.Application = adsk.core.Application.get()
    ui: adsk.core.UserInterface = app.userInterface
    des: adsk.fusion.Design = app.activeProduct

    selSet: adsk.core.SelectionSet = des.selectionSets.itemByName(name)

    sels: adsk.core.Selections = ui.activeSelections
    sels.clear()
    
    sels.add(selSet)                                     # Fails

    [sels.add(entity) for entity in entities]
    app.executeTextCommand('NuComponents.UpdateSelectionGroupCmd')

    sels.clear()

    return selSet.name

 

0 Likes
Message 7 of 8

kandennti
Mentor
Mentor
Accepted solution

@gvisca44 -San.

 

I don't want to do something like this, but I had the SelectionSet selected using a text command.

import json

・・・
        for occ in root.occurrences:
            newOccsEntity.append(occ)
        # design.selectionSets.add(newOccsEntity,'NewOccurrences')    # Fails
        # create_selectionSet_txtCmds(newOccsEntity, 'NewOccurrences')
        update_selectionSet_txtCmds(newOccsEntity,'UpdateExisting')

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


def update_selectionSet_txtCmds(
    entities: list[adsk.core.Base],
    name: str) -> bool:

    app: adsk.core.Application = adsk.core.Application.get()
    ui: adsk.core.UserInterface = app.userInterface
    des: adsk.fusion.Design = app.activeProduct

    selSet: adsk.core.SelectionSet = des.selectionSets.itemByName(name)

    sels: adsk.core.Selections = ui.activeSelections
    sels.clear()

    # sels.add(selSet)                                     # Fails
    if not select_selectionSet_by_name(name): return

    [sels.add(entity) for entity in entities]
    app.executeTextCommand('NuComponents.UpdateSelectionGroupCmd')

    sels.clear()

    # return selSet.name
    return True if len(entities) == len(selSet.entities) else False


def select_selectionSet_by_name(
        name: str) -> bool:

    app = adsk.core.Application.get()

    rootInstanceId = int(
        app.executeTextCommand(
            u'PEntity.ID rootInstance'
        )
    )

    rootInstanceProps = json.loads(
        app.executeTextCommand(
            u'PEntity.Properties rootInstance'
        )
    )

    targetComponentId = rootInstanceProps['rTargetComponent']['entityId']

    targetComponentProps = json.loads(
        app.executeTextCommand(
            u'PEntity.Properties {}'.format(targetComponentId)
        )
    )

    selectionGroupsId = targetComponentProps['rSelectionGroups']['entityId']

    selectionGroupsCount = int(
        app.executeTextCommand(
            u'Managed.Children {}'.format(selectionGroupsId)
        )
    )

    targetSelectSetId = -1
    for idx in range(selectionGroupsCount):
        childProps = json.loads(
            app.executeTextCommand(
                u'Managed.Child {} {}'.format(
                    selectionGroupsId,
                    idx
                )
            )
        )

        childId = childProps['entityId']

        childName = app.executeTextCommand(
            u'PInterfaces.GetUserName {}'.format(childId)
        )

        if name == childName:
            targetSelectSetId = childId
            break

    if targetSelectSetId < 1:
        return False

    sels: adsk.core.Selections = app.userInterface.activeSelections
    sels.clear()

    paths = f"{rootInstanceId}:{targetComponentId}:{selectionGroupsId}:{targetSelectSetId}"

    app.executeTextCommand(
        u'Selections.Add {}'.format(paths)
    )

    return True if sels.count > 0 else False


I believe the SelectionSet object has a bug.

Message 8 of 8

gvisca44
Advocate
Advocate

@kandennti -San

 

that works well !  Thank you !  (I never would have worked that out !)

 

How do we get a bug report filed about the selectionSet/selectionSets object bugs ?

 

Glenn. 

0 Likes