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: 

Accessing derived components and their parameters

6 REPLIES 6
Reply
Message 1 of 7
chris.midgley
471 Views, 6 Replies

Accessing derived components and their parameters

I'm trying to find the parameters of an "Insert Derive" object.  As a simple test case, I created a simple model with a single parameter marked as favorite and saved it.  I then created another model, and did an Insert Derive of the first model with adding favorite parameters. The parameter appears as expected in the Parameters dialog under the derived component in the second model.

 

When using the API on the second model, the allParameters list does not contain any entries (count == 0), nor does the userParameters list.  I looked at the list of components (allComponents), of which there is only one (the original model) and no reference to the derived model (allComponents[0] is the model itself not the derived, same as if I had an empty model without any insert derive). 

 

I also tried marking that parameter, in the second model, as a favorite and it still does not appear.  If I then delete the derive feature, which leaves behind the favorite parameter, the allParameters now shows the parameter (of course, no longer derived).

 

My goal is very simply - to be able to access parameters from derived objects to be able to use those parameters when generating models.

 

Perhaps the API does not (yet) support accessing derived objects and their parameters?  Hoping there is another way to access them (read-only is fine).

 

Thanks for any help,

 

Chris

6 REPLIES 6
Message 2 of 7
JelteDeJong
in reply to: chris.midgley

Hi

 

does this work for you?

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

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

        doc = app.activeDocument
        childReferences = doc.dataFile.childReferences

        if (childReferences.count > 0): 

            derivedDoc = childReferences.item(0)
            ui.messageBox(derivedDoc.name)

            design = adsk.fusion.Design.cast(app.activeProduct)
            param = design.allParameters.itemByName('testParameter')
            ui.messageBox(param.name + ': ' + param.expression) 
        

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

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

Message 3 of 7
JelteDeJong
in reply to: chris.midgley

edit: exedently posted 2x the same

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

Message 4 of 7
chris.midgley
in reply to: JelteDeJong

Thank you for your response.  While I learned more about activeDocument.dataFile from your example, it does not resolve my problem (or at least I've not been able to get it to do so).

 

The dataFile member on activeDocument appears to represent stored data objects (files), and contains information on history and versioning, etc.  With a new, empty-yet-saved model and after an insert-derive (not yet saved), the activeDocument.dataFile.childReferences is empty even though the derived model exists.  When you save the model, then dataFile.childReferences then contains access to the file/version information.  This is useful to learn more about file versioning (etc), but I don't yet see any model information such as parameters that I can access.

 

To that point, later in your code sample you access the parameters with the following snippet:

 

design = adsk.fusion.Design.cast(app.activeProduct)
param = design.allParameters.itemByName('testParameter')
ui.messageBox(param.name + ': ' + param.expression) 

 

This is accessing parameters of the main model (app.activeProduct) and not parameters from the dataFile.childReferences from the prior section.  That casting line (asdk.Fusion.Design.cast) appears to be functionally the same as:

 

design = app.activeProduct

 

Which also means that it is accessing the same model parameters as the main model where I seem unable to access any of the derived model parameters.  Also worth noting, the call to allParameters.itemByName does not appear to resolve names that are in derived models, even those marked as favorites.

 

So thank you very much for your help, but unfortunately I don't yet see how to bridge the gap from dataFile (which represents storage-files) and parameters of an in-memory derived model, or more to the point, any technique to access parameters of derived models.

 

Any other hints out there?  Or does the API just not provide support for accessing derived models?

 

Chris

Message 5 of 7

I'm really hoping someone can verify this is a bug, or even better point me in the right direction! 

 

After too many hours doing experiments, I have failed find any API that works to get a parameter value from a derived model (meaning, a model inserted via insert-derive).  Even though the Fusion UI shows the parameters (marked as favorite in the base model, and even in the inheriting model), and I can type the value into a field with auto-completion, I am unable to access the values from an API.  

 

The core problem comes down to the following:

 

1) The "<activeProduct>.design.allParameters" collection does not include the insert-derive model parameters

2) Using <design>.allComponents[...] you can find the model, and access items such as bodies and sketches, but the modelParameters collection is empty

3) I've not found a way to access a Design of a component, and it is Design that has userParameters and allParameters (components only have modelParameters).  If I use component.parentDesign, it points to the base design (same as <activeProduct>.design.allParameters) not a design object that reflects the insert-derive component.

 

Maybe not worth much, but if the base derive model is (or was recently) open, you can find it under <app>.documents[...].products[...] and in that case, allParameters[...] works fine.  That of course means you not only have to have the derive document open, you also would need to make sure it is the same version.  Not really a viable solution.  Likelywise, you can use adsk.core.dataFile to locate the various components (once saved) but no access to models/parameters.

 

The problem can be seen using the attached model, and the following code.  There are two models:

  • DeriveBase (which is the object that will get inserted into the second model) that has many parameters of different types (user, model, favorite and not). 
  • ContainsDeriveModel, which simply has DeriveBase inserted into it (using insert-derive), along with a single User Parameter just to make sure the code is working.  

 

With ContainsDeriveModel open, run the script and you will see the popups showing that the derive model / user parameters are not available.   The user parameter directly attached to ContainsDeriveModel appears, but nothing else.  

 

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

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

        showCollection('design.appParameters', design.allParameters)
        for component in design.allComponents:
            showCollection('Component {}'.format(component.name), component.modelParameters)
            
        # Directly access parameters - uncomment to test
        # checkParam('LocalUserParameter')
        # checkParam('DerivedFavorite_Ref')
        # checkParam('DerivedModelParameter_Ref')
        # checkParam('DerivedFavoriteModelParameter_Ref')
        # checkParam('DerivedUserParameter_Ref')
        # checkParam('d5_Ref')
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def checkParam(name):
    try:
        param = design.allParameters.itemByName(name)
        ui.messageBox(param.name + ': ' + param.expression) 
    except:
        ui.messageBox("Unable to locate {}".format(name))

def showCollection(name, collection):
    first = True
    message = '{} ({} items): '.format(name, collection.count)
    for item in collection:
        message += ('' if first else ', ') + item.name
        first = False
    ui.messageBox(message)

 

Thanks in advance for any help,

 

Chris

 

Message 6 of 7
BrianEkins
in reply to: chris.midgley

This is a limitation of the current API.  The derived functionality is a relatively recent addition to Fusion and the API has not been updated to support it yet.  It would be a good addition.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 7 of 7
chris.midgley
in reply to: BrianEkins

Thanks for the confirmation, I was guessing as much.  Anybody know who the best PM is at Autodesk to contact to see if this API is planned and where it might be on a roadmap?  Thx!

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