Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Creating rigid groups from sub-components using the API

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
bungledb
248 Views, 4 Replies

Creating rigid groups from sub-components using the API

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?

Labels (3)
4 REPLIES 4
Message 2 of 5
kgrunawalt
in reply to: bungledb

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!

Message 3 of 5
bungledb
in reply to: kgrunawalt

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.

Message 4 of 5
BrianEkins
in reply to: bungledb

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
Message 5 of 5
bungledb
in reply to: BrianEkins

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

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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report