Creating rigid groups from sub-components using the API

Creating rigid groups from sub-components using the API

bungledb
Explorer Explorer
807 Views
4 Replies
Message 1 of 5

Creating rigid groups from sub-components using the API

bungledb
Explorer
Explorer

Hi, Folks.

 

I'm struggling to wrap my head around operations with components that are children of components. Specifically, in this case, I want to make a rigid joint between two subcomponents from different parents.

 

Following this example, I can create a rigid group from components in the root component with no problem.

I can get it to work if things are all in the root and there are no sub-components involved:

root
|
+-comp1
|
+-subcomp1
|
+-comp2
|
--subcomp2

 

But it fails if I put the subcomponents one or more layers deeper, like this:

 

root
|
+ comp1
|  |
|   -subcomp1
|
- comp2
   |
    -subcomp2



subcomp1 and subcomp2 are actually other models inserted into this one.

 

So this works:

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

def run(context):
    #Get system objects
    app = adsk.core.Application.get()
    project = app.data.activeProject
    design = adsk.fusion.Design.cast(app.activeProduct)
    root = design.rootComponent
    trans = adsk.core.Matrix3D.create()

    #Create top level components
    occ = root.occurrences.addNewComponent(trans)
    comp1 = occ.component
    comp1.name = 'comp1'
    occ = root.occurrences.addNewComponent(trans)
    comp2 = occ.component
    comp2.name = 'comp2'

    # Get folder containing other models
    for folder in project.rootFolder.dataFolders:
        if folder.name == "ExtComps":
            ext_folder = folder

    # Import each of the other models.
    for file in ext_folder.dataFiles:
        if file.name == 'Sphere':
            file_to_insert = file
            sub_comp1 = root.occurrences.addByInsert(file_to_insert, trans, True)

        elif file.name == 'Cube':
            file_to_insert = file
            sub_comp2 = root.occurrences.addByInsert(file_to_insert, trans, True)

    #Create a collection
    occs = adsk.core.ObjectCollection.create()
    occs.add(sub_comp1)
    occs.add(sub_comp2)

    #Create a rigid group.
    isIncludeChildren = True
    rigidGroups_ = root.rigidGroups
    rigidGroups_.add(occs, isIncludeChildren)

But this fails:

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

def run(context):
    #Get system objects
    app = adsk.core.Application.get()
    project = app.data.activeProject
    design = adsk.fusion.Design.cast(app.activeProduct)
    root = design.rootComponent
    trans = adsk.core.Matrix3D.create()

    #Create top level components
    occ = root.occurrences.addNewComponent(trans)
    comp1 = occ.component
    comp1.name = 'comp1'
    occ = root.occurrences.addNewComponent(trans)
    comp2 = occ.component
    comp2.name = 'comp2'

    # Get folder containing other models
    for folder in project.rootFolder.dataFolders:
        if folder.name == "ExtComps":
            ext_folder = folder

    # Import each of the other models.
    for file in ext_folder.dataFiles:
        if file.name == 'Sphere':
            file_to_insert = file
            sub_comp1 = comp1.occurrences.addByInsert(file_to_insert, trans, True)

        elif file.name == 'Cube':
            file_to_insert = file
            sub_comp2 = comp2.occurrences.addByInsert(file_to_insert, trans, True)

    #Create a collection
    occs = adsk.core.ObjectCollection.create()
    occs.add(sub_comp1)
    occs.add(sub_comp2)

    #Create a rigid group.
    isIncludeChildren = True
    rigidGroups_ = root.rigidGroups
    rigidGroups_.add(occs, isIncludeChildren)


-> "RuntimeError: 5 : Provided input paths or alignments are not valid."

It inserts the external files just fine, but hits a wall when I try to create the rigid group. It also fails if I put both of the external objects under the same parent (eg comp1).

 

It's frustrating, because I can make exactly that rigid group using the GUI with no issues, so it's an allowed action, but I just can't see what I need to do in the API to achieve the same result.

 

Can anyone tell me what I've missed?

0 Likes
Accepted solutions (1)
808 Views
4 Replies
Replies (4)
Message 2 of 5

kgrunawalt
Autodesk
Autodesk

To make the joint, you need two components that have full paths from root to component as context. I think the problem is that the two subcomponent objects are lacking that root-based occurrence path context.

 

I need to brush up on the api to be more specific!

0 Likes
Message 3 of 5

bungledb
Explorer
Explorer

Thanks, that helps. So I want to conceptually say "root/comp1/subcomp1," but my understanding of how to work contexts is shaky to say the least. 😕

Reading the docs again, it kind of feels like I should maybe use proxies - something like:

sc1proxy = sub_comp1.createForAssemblyContext(root)
sc2proxy = sub_comp2.createForAssemblyContext(root)

#Create a collection
occs = adsk.core.ObjectCollection.create()
occs.add(sc1proxy)
occs.add(sc2proxy)

#Create a rigid group.
isIncludeChildren = True
rigidGroups_ = root.rigidGroups
rigidGroups_.add(occs, isIncludeChildren)

 

but that throws a Type Error of course because I need to put something more than the bare root component in createForAssembly(). Trouble is, I can't figure out what.

0 Likes
Message 4 of 5

BrianEkins
Mentor
Mentor
Accepted solution

You're very close.  Here's a slightly modified version of your program that works.

 

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

def run(context):
    #Get system objects
    app = adsk.core.Application.get()
    project = app.data.activeProject
    design = adsk.fusion.Design.cast(app.activeProduct)
    root = design.rootComponent
    trans = adsk.core.Matrix3D.create()

    #Create top level components
    occ1 = root.occurrences.addNewComponent(trans)
    comp1 = occ1.component
    comp1.name = 'comp1'
    occ2 = root.occurrences.addNewComponent(trans)
    comp2 = occ2.component
    comp2.name = 'comp2'

    # Get folder containing other models
    for folder in project.rootFolder.dataFolders:
        if folder.name == "ExtComps":
            ext_folder = folder

    # Import each of the other models. Because these are being created in the 
    # context of the components, the occurrences returned are also in that context.
    # This then creates proxies for the occurrences that are relative to root.
    for file in ext_folder.dataFiles:
        if file.name == 'Sphere':
            file_to_insert = file
            sub_occ1 = comp1.occurrences.addByInsert(file_to_insert, trans, True)
            sub_occ1 = sub_occ1.createForAssemblyContext(occ1)

        elif file.name == 'Cube':
            file_to_insert = file
            sub_occ2 = comp2.occurrences.addByInsert(file_to_insert, trans, True)
            sub_occ2 = sub_occ2.createForAssemblyContext(occ2)

    #Create a collection
    occs = adsk.core.ObjectCollection.create()
    occs.add(sub_occ1)
    occs.add(sub_occ2)

    #Create a rigid group.
    isIncludeChildren = True
    rigidGroups_ = root.rigidGroups
    rigidGroups_.add(occs, isIncludeChildren)
---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes
Message 5 of 5

bungledb
Explorer
Explorer

Aaahh! The light bulb just came on over my head.

Thank you so much, @BrianEkins, that's great.

0 Likes