change the color of a body using the api with python

change the color of a body using the api with python

andrew
Explorer Explorer
880 Views
7 Replies
Message 1 of 8

change the color of a body using the api with python

andrew
Explorer
Explorer

Hello 🙂

I have a functioning python script i wish to extend.

I want to change the color of the bodies in the design, I can do this via screen menus, but i want to do this via a script.

 

My searches have not shown any promise.

 

Thank you for your time 🙂

 

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

j4n.vokurka
Advocate
Advocate

Hello,

if you just want to play with appearance of a body for visual purposes you can just use the:

bRepBody_var.appearance = propertyValue

 

The tricky thing is how to obtain the appearance you want to to assign to the body. For that you need to load it from appropriate library, if it exists. If it doesn't you will have to copy existing appearance and set its properties to your liking.

This is a sample code that first checks if the desired appearance already exists in one of the libraries and if not, creates new one by copying an existing appearance and editing it. 

 

 

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

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

        design = app.activeProduct
        if not design:
            ui.messageBox('No active Fusion 360 design', 'No Design')
            return
        
        # get the body 
        ui.messageBox("Select a body you want to change", "Body selection")
        body = adsk.fusion.BRepBody.cast(ui.selectEntity('Select a body', 'Bodies').entity)

        # body appearance 
        BodyA = body.appearance; 
        ui.messageBox(BodyA.name, "Body Appearance")


        # Check to see if the "MyColor1" exists in the local appearances
        try:
            myColor = design.appearances.itemByName('MyColor1')
        except:
            myColor = None
            
        if myColor:
            body.appearance = myColor
        else:
            # Get the existing appearance.            
            AppearanceLibrary = app.materialLibraries.itemByName('Fusion Appearance Library')
            yellowColor = AppearanceLibrary.appearances.itemByName('Paint - Enamel Glossy (Yellow)')
        
            # Copy yellow color to the design, giving it a new name.
            newColor = design.appearances.addByCopy(yellowColor, 'MyColor1')
                        
            # Change the color property of the appearance to what you want.
            colorProperty = adsk.core.ColorProperty.cast(newColor.appearanceProperties.itemByName('Color'))
            colorProperty.value = adsk.core.Color.create(0, 204, 0, 0)
            # Assign it to the body.            
            body.appearance = newColor

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

 

 


 hope this helps

Message 3 of 8

andrew
Explorer
Explorer

Thank you for your prompt reply j4n  🙂

I'll apply it shortly.

Regards Andrew

 

P.S. a comment: I find the documentation difficult to search. Your code uses the the words color and appearance and these failed to guide me closer to methods I could follow.

0 Likes
Message 4 of 8

andrew
Explorer
Explorer

Hello j4n 🙂

Thank you for the code 🙂

 

bRepBody_var.appearance = propertyValue

shows no context hints in the Visual Studio environment and as per my last message I am unable to effectively search...so being a dummy i cannot use this.

 

The larger code example is great except I want the body to be programmatically selected.

In my case the body is Bodies:piece, ie the body i want to change color of is named "piece".

 

I have user input functioning in other ways and I'd like the user input to cause "piece" to be colored:

hexx_red="Paint - Enamel Glossy (Red)"
hexx_yellow="Paint - Enamel Glossy (Yellow)"
hexx_green="Paint - Enamel Glossy (Green)"
hexx_white="Paint - Enamel Glossy (white)"
 

 

To highlight my confusion:

piece=design.findEntityByToken('piece')

returns null.

 

Thanks in advance.

 

P.S.

This effort is part of my project in making the world's most difficult jigsaw. see: hexx.au

If you contact me by email with your address I'll send you a puzzle ( if that appeals )

 

0 Likes
Message 5 of 8

andrew
Explorer
Explorer

Good afternoon 4jn 🙂

 

I have success.

I used chatgpt which provided the clue to finding the body by name.

 

        # locate the body
        bodies=root_comp.bRepBodies
        selected_body = None
        for body in bodies:
            if body.name == 'piece':
                #ui.messageBox(body.name, "Body Appearance")
                selected_body = body
                break

 

and setting the color:

 

           selected_body.appearance=AppearanceLibrary.appearances.itemByName('Paint - Enamel Glossy (White)')

 

Its always so exasperating to find the simple solution...

Chatgpt will make stuff up ( pseudo code ) but a clue is a clue 🙂

 

Regards Andrew

 

 

0 Likes
Message 6 of 8

j4n.vokurka
Advocate
Advocate

Hello,

I provided the previous sample so that you could test/debug how the actual appearance assignment works. To choose the correct object for the assignment is another task which mainly depends on how you have set your model structure to suit your purposes. Without knowing that it's hard to tailor the code to your need.

You can of course select bodies via API. I don't know how familiar you are with the concept of component/occurrences, but based on your sample you try to work with bodies belonging to the root component. If that is always the case you can continue in the logic of your sample. If you however intend to work with bodies belonging to components on different levels in the model structure, this sample will be insufficient.

Feel free to let me know, if you need further help with or clarification of any of the topics I mentioned. If the concept of components/occurrences is new to you in Fusion, take a look at this article.

 

Jan

0 Likes
Message 7 of 8

j4n.vokurka
Advocate
Advocate
Accepted solution

This should be the script you need:

 

 

 

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

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

        design = app.activeProduct
        if not design:
            ui.messageBox('No active Fusion 360 design', 'No Design')
            return
        
        root_comp = design.rootComponent

        # get the body 
        searchedBodyName: str = 'searchedBodyName'
        searchedBody: adsk.fusion.BRepBody = None

        bodies = root_comp.bRepBodies

        for body in bodies:
            if body.name == searchedBodyName:
                searchedBody = body
                break

        # body appearance 
        BodyAppearance = searchedBody.appearance; 
        # ui.messageBox(BodyA.name, "Body Appearance")

        # Check if the color that user chose i.e. hexx_red="Paint - Enamel Glossy (Red)" etc is loaded from the library, otherwise load it
        try:
            myColor = design.appearances.itemByName('MyColor1')
        except:
            myColor = None
            
        if myColor:
            body.appearance = myColor
        else:
            # Get the existing appearance.            
            AppearanceLibrary = app.materialLibraries.itemByName('Fusion Appearance Library')
            yellowColor = AppearanceLibrary.appearances.itemByName('Paint - Enamel Glossy (Yellow)')
        
            # Copy yellow color to the design, giving it a new name.
            newColor = design.appearances.addByCopy(yellowColor, 'MyColor1')
                        
            # Change the color property of the appearance to what you want.
            colorProperty = adsk.core.ColorProperty.cast(newColor.appearanceProperties.itemByName('Color'))
            colorProperty.value = adsk.core.Color.create(0, 204, 0, 0)
            # Assign it to the body.            
            body.appearance = newColor

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

 

 

 

 
This could of course be further adjusted so you don't have to manually rewrite the wanted color every time you want to use the script. For that I would advise you to create an add-in instead of a script. In this add-in you could create a dialog which lets you select the color you have just decided to work with and you could then edit multiple bodies without the need to run the script every time.

Also a small recommendation, if you are just writing in python it is better to stick to using VS Code because Fusion is primarily configured to work with that IDE. Thread discussing this topic here . Interesting project btw 🙂

Message 8 of 8

andrew
Explorer
Explorer

Thanks j4n 🙂

My code works as desired now 🙂

My script receives information to set the color via user prompt.

I have been using the VS IDE

Regards Andrew

0 Likes