Hi @bruce.hodder. That code example seems to only be focused on the WorkSurface objects. Is that the only type of object that you want to be effected, or do you want to change the appearances of all parts and sub assemblies within the whole assembly, as you stated in your initial statements? Unfortunately, the WorkSurface object does not have a direct way to change its color/appearance, other than the WorkSurface.Translucent property, and the WorkSurface.Visible property. The effects of setting those properties is pretty obvious. I believe there is an indirect way to effect their appearance though. As you can see, these have a WorkSurface.SurfaceBodies property. This is because they are often associated with one or more SurfaceBody objects. Despite their name, these are normally 'Solid' bodies, but they can also be just surfaces. So, the SurfaceBody object has a ReadOnly SurfaceBody.IsSolid property for checking that status. When the value of that property is False, that usually means a WorkSurface was created, and will be associated with that SurfaceBody. We can do a lot with a regular SurfaceBody object, because it has a lot of methods and properties. We can set the overall appearance of the whole body using the SurfaceBody.Appearance property (if we have an Asset to set as its value), or we can iterate through its SurfaceBody.Faces collection, and attempt to set the Face.Appearance property values to a specific appearance Asset. However, those objects are found within the ComponentDefinition of parts. And you seem to be interested in changing the appearances of stuff in an assembly. The main objects you encounter in an assembly are ComponentOccurrence objects, instead of WorkSurfaces & SurfaceBodies. Those also have the same ComponentOccurrence.Appearance property that can be set. Just keep in mind that every time one of these appearances is set/changed, or the 'Visibility' of something changes, those actions are being recorded by whichever DVR (DesignViewRepresentation) that happens to be active in that document at the time those changes were made. And if there are other DVR's in that document, those changes will not effect, or be recorded by any of the other DVR's in that document. And if the assembly component it set to a different DVR than the model file it is referencing, then the assembly component and the model file it is referencing can have different appearances.
Maybe give this example code below a try, and see if it accomplishes what you seem to be wanting. It will attempt to find this appearance Asset named "Snow" in the main assembly, and if not found there, it will try to copy it to the assembly from the 'active' appearances library. If that fails too, it should let you know, then exit the rule. Then it will attempt to 'recursively' iterate through all levels of the assembly's components, and will try to set their appearance to that one appearance Asset. This example will attempt to do so in a way that will only effect their appearance as seen by the main assembly, without actually changing anything within any of the referenced model documents. If you need the code to also effect every referenced document, then please specify that, to clarify your overall design intent here.
Sub Main
oADoc = TryCast(ThisDoc.Document, Inventor.AssemblyDocument)
If oADoc Is Nothing Then
Logger.Debug("The iLogic rule named '" & iLogicVb.RuleName & "' exited, because no AssemblyDocument was obtained.")
Exit Sub
End If
'run custom function to get named appearance asset, and copy it to this assembly
oMyAppearance = GetAppearance(oADoc, sAppearanceName)
'check to make sure it returned something
If oMyAppearance Is Nothing Then
MessageBox.Show("The specified Appearance could not be found in the active document, or in the active appearances library!", _
"Appearance Not Found!", MessageBoxButtons.OK, MessageBoxIcon.Hand)
Return 'this will exit this routine (and the rule)
End If
'get the assembly components to a variable
Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
If oOccs.Count = 0 Then Return
'run custom Sub routine to recursively iterate through these components
RecurseComponents(oOccs, AddressOf ProcessComponent)
'update the assembly, if it needs it
If oADoc.RequiresUpdate Then oADoc.Update2(True)
oADoc.Views.Item(1).Update
'If oADoc.Dirty Then oADoc.Save2(True)
End Sub
'these variables can be accessed by all routines
Dim oADoc As AssemblyDocument
Const sAppearanceName As String = "Snow"
Dim oMyAppearance As Inventor.Asset
Function GetAppearance(TargetDoc As Inventor.Document, AppearanceName As String) As Inventor.Asset
Dim oDocApps, oLibApps As AssetsEnumerator, oMyApp As Inventor.Asset
Try : oDocApps = TargetDoc.AppearanceAssets : Catch : End Try
If oDocApps IsNot Nothing AndAlso oDocApps.Count > 0 Then
For Each oDocAppAsset As Inventor.Asset In oDocApps
If oDocAppAsset.Name = AppearanceName OrElse oDocAppAsset.DisplayName = AppearanceName Then
oMyApp = oDocAppAsset
End If
Next oDocAppAsset
End If
If oMyAppearance Is Nothing Then
oLibApps = ThisApplication.ActiveAppearanceLibrary.AppearanceAssets
For Each oLibAppAsset As Inventor.Asset In oLibApps
If oLibAppAsset.Name = AppearanceName OrElse oLibAppAsset.DisplayName = AppearanceName Then
oMyApp = oLibAppAsset.CopyTo(TargetDoc, True)
End If
Next oLibAppAsset
End If
Return oMyApp
End Function
Sub RecurseComponents(oComps As ComponentOccurrences, ComponentProcess As Action(Of ComponentOccurrence))
If oComps Is Nothing OrElse oComps.Count = 0 Then Return
For Each oComp As ComponentOccurrence In oComps
ComponentProcess(oComp)
If oComp.Suppressed = False AndAlso _
oComp.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
'RecurseComponents(oComp.Definition.Occurrences, ComponentProcess) 'ignore ancestry
RecurseComponents(oComp.SubOccurrences, ComponentProcess) 'maintain ancestry
End If
Next
End Sub
Sub ProcessComponent(oComp As ComponentOccurrence)
If (oComp Is Nothing) OrElse oComp.Suppressed OrElse
(TypeOf oComp.Definition Is VirtualComponentDefinition) OrElse
(TypeOf oComp.Definition Is WeldsComponentDefinition) Then
Return
End If
Try
oComp.Appearance = oMyAppearance
Catch
Logger.Error("Error setting component named " & oComp.Name _
& vbCrLf & "to Appearance named " & sAppearanceName)
End Try
End Sub
If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.
Wesley Crihfield

(Not an Autodesk Employee)