Controlling Part Colors

There was a recent discussion on the newsgroup regarding setting the color of a part.  It’s not particularly easy to figure out the API to do this so I thought I would put together a little primer on the concepts and some sample code that demonstrates it.

Overall Color of a Part
First, a part has a defined overall color.  By default this is defined as “As Material” which means it will use whatever color is assigned to the current material.  Using the material combo box in the part you can override this and change the part color to any other available color.

PartColorList

The available colors are defined in the style library, which you can see using the Style and Standard Editor, as shown below.

ColorStyleEditor

In the API, these colors are referred to as RenderStyles.  Here’s a small program that sets the color of the active part to “Red”.  When getting a render style you specify the style using its name.  In the example below, if there isn’t a color named “Red” the line where it tries to get the color will fail.  When using the Item property to get a specific RenderStyle the name specified is case insensitive so “Red”, “red” or “RED” will all work.

Public Sub SetPartColor()        Dim oPartDoc As PartDocument         Set oPartDoc = ThisApplication.ActiveDocument             ' Get a reference to the RenderStyle named "Red".            Dim oRenderStyle As RenderStyle         Set oRenderStyle = oPartDoc.RenderStyles.Item("Red")             ' Assign the render style to the part.            oPartDoc.ActiveRenderStyle = oRenderStyle             ' Force the view to update to see the change.            ThisApplication.ActiveView.Update     End Sub

If you want to set the part color back to “As Material” then you need to set the color currently assigned to part to be the render style associated with the active material.  Inventor recognizes that the assigned render style is the same as that associated with the active material and will change the setting to “As Material”.  This is demonstrated below.

Public Sub SetPartToMaterialColor()        Dim oPartDoc As PartDocument         Set oPartDoc = ThisApplication.ActiveDocument
Dim oPartDef As PartComponentDefinition
Set oPartDef = oPartDoc.ComponentDefinition            ' Get a reference to the material render style.            Dim oRenderStyle As RenderStyle         Set oRenderStyle = oPartDef.Material.RenderStyle             ' Assign the render style to the part.            oPartDoc.ActiveRenderStyle = oRenderStyle             ' Force the view to update to see the change.            ThisApplication.ActiveView.Update     End Sub

 

Override Colors for Features and Faces
What I’ve talked about so far is the overall color for the part.  It’s also possible to assign override colors to faces and features.  In the user-interface this is done by right-clicking on the feature or the face and running the Properties command from the context menu.  As you can see in the pictures below, the Properties dialogs for a feature and face allow you to select a color style for the feature or face.  These override the color defined by the part for that specific feature or face.  There’s a level of priority when assigning colors.  The part color colors the entire part.  A feature color overrides the part color and colors the feature.  A face color override the part or feature color and will color the face.  To remove the override of a face you set it’s color style to “As Feature” or “As Part” and to remove the override from a feature you set it to “As Part”.

FeatureColor  FaceColor

Below is an example program that sets the color of a feature and a face.  It uses the second feature created in the active part and an arbitrary face of that feature.

Public Sub SetFeatureAndFaceColor()        Dim oPartDoc As PartDocument         Set oPartDoc = ThisApplication.ActiveDocument          ' Get the second feature.            Dim oFeature As PartFeature         Set oFeature = oPartDoc.ComponentDefinition.Features.Item(2)             ' Set the color of the feature to "Yellow"            Call oFeature.SetRenderStyle(kOverrideRenderStyle, _                                   oPartDoc.RenderStyles.Item("Yellow"))             ' Get one of the faces of the feature.       ' This could be any face in the part.             Dim oFace As Face         Set oFace = oFeature.Faces.Item(1)             ' Se
t the color of the face to "Green"            Call oFace.SetRenderStyle(kOverrideRenderStyle, _                                 oPartDoc.RenderStyles.Item("Green"))     End Sub

The example below removes these color overrides and resets all features to use the part color and all faces to use the feature color. 

Public Sub RemoveFeatureAndFaceColorOverrides()        Dim oPartDoc As PartDocument         Set oPartDoc = ThisApplication.ActiveDocument
Dim oPartDef As PartComponentDefinition
Set oPartDef = oPartDoc.ComponentDefinition            ' Iterate through all features.            Dim oFeature As PartFeature         For Each oFeature In oPartDoc.ComponentDefinition.Features             ' Set the render style to be "As Part".                Call oFeature.SetRenderStyle(kPartRenderStyle)         Next             ' Iterate through all faces.            Dim oFace As Face         For Each oFace In oPartDef.SurfaceBodies.Item(1).Faces             ' Set the render style to be "As Feature".                Call oFace.SetRenderStyle(kFeatureRenderStyle)         Next     End Sub

 

Part models can have very many faces and typically only a few of those will have color overrides.  Iterating and setting every face can be expensive.  To improve performance there is a trick to quickly find only those faces that have overrides.  The trick takes advantage of the fact that face color overrides are implemented internally using standard API attributes.  The program below does the same thing as the previous program but uses this trick so it will be more efficient on large models.

Public Sub RemoveFeatureAndFaceColorOverrides2()        Dim oPartDoc As PartDocument         Set oPartDoc = ThisApplication.ActiveDocument             ' Iterate through all features.            Dim oFeature As PartFeature         For Each oFeature In oPartDoc.ComponentDefinition.Features             ' Set the render style to be "As Part".                Call oFeature.SetRenderStyle(kPartRenderStyle)         Next             ' Get all of the faces that have the "FaceColor" attribute.            Dim oFaces As ObjectCollection         Set oFaces = oPartDoc.AttributeManager.FindObjects( _                     "com.autodesk.inventor.FaceAttributes", "FaceColor")             ' Iterate through all faces that have colors.            Dim oFace As Face         For Each oFace In oFaces             ' Set the render style to be "As Feature".                Call oFace.SetRenderStyle(kFeatureRenderStyle)         Next     End Sub

 

If you want to find out what the current color of a feature or face is you can use the GetRenderStyle method.  This returns the current color of the feature or face and also indicates why it is that color.  For example, if you get the color of a face it can be that color because of the part color, feature color, or the face color.  In most cases you probably don’t care why it’s the color it is and can just use the color returned and ignore why it’s that color.  The sample below displays the name of the color of the selected feature or face and why it’s that color.

Public Sub ShowPartColors()        Dim oPartDoc As PartDocument         Set oPartDoc = ThisApplication.ActiveDocument             ' Check that an entity is selected.            If oPartDoc.SelectSet.Count  1 Then             MsgBox "A feature or face must be selected."             Exit Sub         End If             ' Check to see if it is a face or feature that's selected.            Dim ColorSource As StyleSourceTypeEnum         Dim oRenderStyle As RenderStyle         If TypeOf oPartDoc.SelectSet.Item(1) Is PartFeature Then             Dim oFeature As PartFeature             Set oFeature = oPartDoc.SelectSet.Item(1)                 Set oRenderStyle = oFeature.GetRenderStyle(ColorSource)                 MsgBox "Feature color: " & oRenderStyle.Name & vbCr & _                    "Reason: " & StyleSourceTypeEnumName(ColorSource)         ElseIf TypeOf oPartDoc.SelectSet.Item(1) Is Face Then             Dim oFace As Face             Set oFace = oPartDoc.SelectSet.Item(1)                 Set oRenderStyle = oFace.GetRenderStyle(ColorSource)                 MsgBox "Face color: " & oRenderStyle.Name & vbCr & _                    "Reason: " & StyleSourceTypeEnumName(ColorSource)         Else             MsgBox "A feature or face must be selected."             Exit Sub         End If     End Sub             ' Utility function used to get a readable name for an enum value.        Private Function StyleSourceTypeEnumName( _                      EnumValue As S
tyleSourceTypeEnum) As String         Select Case EnumValue             Case kFeatureRenderStyle                 StyleSourceTypeEnumName = "Feature color"             Case kOverrideRenderStyle                 StyleSourceTypeEnumName = "Override color"             Case kPartRenderStyle                 StyleSourceTypeEnumName = "Part color"             Case kWeldBeadRenderStyle                 StyleSourceTypeEnumName = "Weld bead color"         End Select     End Function

 

Override Colors for Occurrences in an Assembly
The concepts of applying an override color also apply when coloring objects in an assembly.  The default color of any part in an assembly is the color defined in the part.  You can choose to override the part color and assign any other color.  In an assembly, the override applies to the entire occurrence.  You override the color of a part in the user-interface by selecting a part and then choosing a color from the color combo box, as shown below. You can’t override the color of feature or faces in an assembly, only the entire part.

PartColorList

The ComponentOccurrence object supports both the SetRenderStyle and GetRenderStyle methods.  A ComponentOccurrence object can represent an individual part or a subassembly.  If you set the render style of a component occurrence that represents a part it will override the color for that single instance of the part.  If you set it for a component occurrence that represents a subassembly it will override the color for all of the parts within the subassembly.  The sample below illustrates this by randomly setting the color of all of the top-level occurrences in an assembly.  The occurrences can be parts or subassemblies.   Remember, this is overriding the color as defined by the part. 

Public Sub SetOccurrenceOverrideColors()        Dim oAsmDoc As AssemblyDocument         Set oAsmDoc = ThisApplication.ActiveDocument             ' Initialize the random number generator and get            ' the number of render styles defined.             Randomize         Dim iColorCount As Long         iColorCount = oAsmDoc.RenderStyles.Count             ' Iterate through the top-level occurrences in the assembly.         Dim oOcc As ComponentOccurrence         For Each oOcc In oAsmDoc.ComponentDefinition.Occurrences             ' Set the color to a random color.             Call oOcc.SetRenderStyle(kOverrideRenderStyle, _                 oAsmDoc.RenderStyles.Item(Int((iColorCount * Rnd) + 1)))         Next     End Sub

 

This next sample goes through the top-level occurrences in an assembly and removes any color overrides so they all revert back to the original part color.

Public Sub RemoveOccurrenceOverrideColors()        Dim oAsmDoc As AssemblyDocument         Set oAsmDoc = ThisApplication.ActiveDocument             ' Iterate through the top-level occurrences in the assembly.         Dim oOcc As ComponentOccurrence         For Each oOcc In oAsmDoc.ComponentDefinition.Occurrences             ' Set each occurrence to use the part defined color.                Call oOcc.SetRenderStyle(kPartRenderStyle)         Next     End Sub

 

This final sample is similar to the previous part sample that reports the color of the selected feature or face except this reports the color of the selected occurrence.

Public Sub ShowOccurrenceColor()        Dim oAsmDoc As AssemblyDocument         Set oAsmDoc = ThisApplication.ActiveDocument             ' Check that an occurence is selected.            Dim oOcc As ComponentOccurrence         On Error Resume Next         Set oOcc = oAsmDoc.SelectSet.Item(1)         If Err Then             MsgBox "An occurrence must be selected."             Exit Sub         End If         On Error GoTo 0             ' Check to see if it is a face or feature that's selected.            Dim ColorSource As StyleSourceTypeEnum         Dim oRenderStyle As RenderStyle         Set oRenderStyle = oOcc.GetRenderStyle(ColorSource)         MsgBox "Occurence color: " & oRenderStyle.Name & vbCr & _                "Reason: " & StyleSourceTypeEnumName(ColorSource)     End Sub             ' Utility function used to get a readable name for an enum value.        Private Function StyleSourceTypeEnumName( _                      EnumValue As StyleSourceTypeEnum) As String         Select Case EnumValue             Case kFeatureRenderStyle                 StyleSourceTypeEnumName = "Feature color"             Case kOverrideRenderStyle                 StyleSourceTypeEnumName = "Override color"             Case kPartRenderStyle                 StyleSourceTypeEnumName = "Part color"             Case kWeldBeadRenderStyle                 StyleSourceTypeEnumName = "Weld bead color"         End Select     End Function

Comments

5 responses to “Controlling Part Colors”

  1. YAYYYYYYYY thank you very much! this is the most helpful inventor text ive seen online.. very well written!
    thank you again

  2. I created this macro to change selected parts to a clear color, “green” or “blue” or set it back to “as material”, it has a small selection window. Using that dailly.
    Check it out in this zip:
    http://www.inventorwizard.be/tools/macro/change_color_2_clear.zip

  3. Did you try it?

  4. this is a nice base for what i’m trieing to accomplisch. how can I change colors of parts which are in a sub assy? (and offcourse leave the colors of the sub assemblies unchanged then)
    my sincere compliments on your blog, it makes alot off stuf much clearer. thank you!
    Francis, netherlands

  5. Brian Ekins Avatar
    Brian Ekins

    It’s possible to iterate through the entire assembly structure. This is discussed in detail in a more recent blog posting:
    http://modthemachine.typepad.com/my_weblog/2009/03/accessing-assembly-components.html
    Each occurrence obtained while traversing can have it’s color set. This is an override that’s defined at the level of the top-level assembly and does not change the subassemblies or parts.

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading