I have a little bit of iLogic experience but have exhausted all of the threads & iLogic code found so far with no success.
I regularly import SEMA Tech Transfer files which sometimes contains a mix of dozens (or hundreds) of sub-assemblies, sub-part files & surface files. I want to change all colors of all parts & surfaces to one specific color (Snow).
Typically, I can simply select all parts & assemblies then select APPEARANCE > SNOW. I accept the pop-up window ASSOCIATIVE DESIGN VIEW REPRESENTATIONS and REMOVE ASSOCIATIVITY to set my new color. This sometimes works, sometimes does not work.
When it does not work, I have found I have to drill down to each individual surface, select all of the surfaces manually & then I am able to change the color. This, of course, is not productive when there are hundreds or thousands of surfaces.
I want to have an iLogic rule that can reliably change the color appearance from DEFAULT (or whatever the initial color is) to SNOW on all sub-parts & surface faces & automatically override any colors set in Design View Representations.
Any help?
Here's an image of the type of assembly I'm working with. This particular assembly file has multiple subassemblies & hundreds of sub-parts & surfaces.
I have a little bit of iLogic experience but have exhausted all of the threads & iLogic code found so far with no success.
I regularly import SEMA Tech Transfer files which sometimes contains a mix of dozens (or hundreds) of sub-assemblies, sub-part files & surface files. I want to change all colors of all parts & surfaces to one specific color (Snow).
Typically, I can simply select all parts & assemblies then select APPEARANCE > SNOW. I accept the pop-up window ASSOCIATIVE DESIGN VIEW REPRESENTATIONS and REMOVE ASSOCIATIVITY to set my new color. This sometimes works, sometimes does not work.
When it does not work, I have found I have to drill down to each individual surface, select all of the surfaces manually & then I am able to change the color. This, of course, is not productive when there are hundreds or thousands of surfaces.
I want to have an iLogic rule that can reliably change the color appearance from DEFAULT (or whatever the initial color is) to SNOW on all sub-parts & surface faces & automatically override any colors set in Design View Representations.
Any help?
Here's an image of the type of assembly I'm working with. This particular assembly file has multiple subassemblies & hundreds of sub-parts & surfaces.
I received a PM from an awesome contributor who explained that this may or not be possible. Thank you for your PM. I appreciate you taking the time to read & PM me privately.
My initial thought was "can I modify this iLogic?" (below) for changing the translucency of surface bodies to rework it to simply find all of the surfaces (as it currently appears to do) & edit the lower portion of code for "oWorksurface" to change the color of the surface. Is that even doable?
Sub Main
Dim oDoc As Inventor.Document
oDoc = ThisApplication.ActiveDocument
Call Translucent(oDoc)
End Sub
Function Translucent(ByVal oDoc As Document)
If oDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Dim oAssembly As Inventor.AssemblyDocument
oAssembly = oDoc
Dim oRefDoc As Inventor.Document
For Each oRefDoc In oAssembly.AllReferencedDocuments
Call Translucent(oRefDoc)
Next
ElseIf oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
Dim oPart As Inventor.PartDocument
oPart = oDoc
Dim oWorkSurface As Inventor.WorkSurface
For Each oWorkSurface In oPart.ComponentDefinition.WorkSurfaces
oWorkSurface.Translucent = False
Next
End If
End Function
Can this line:
oWorksurface.Translucent = False
Be edited to:
oWorksurface. (whatever this needs to be to change the color) = Snow
Or something to this effect?
I received a PM from an awesome contributor who explained that this may or not be possible. Thank you for your PM. I appreciate you taking the time to read & PM me privately.
My initial thought was "can I modify this iLogic?" (below) for changing the translucency of surface bodies to rework it to simply find all of the surfaces (as it currently appears to do) & edit the lower portion of code for "oWorksurface" to change the color of the surface. Is that even doable?
Sub Main
Dim oDoc As Inventor.Document
oDoc = ThisApplication.ActiveDocument
Call Translucent(oDoc)
End Sub
Function Translucent(ByVal oDoc As Document)
If oDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Dim oAssembly As Inventor.AssemblyDocument
oAssembly = oDoc
Dim oRefDoc As Inventor.Document
For Each oRefDoc In oAssembly.AllReferencedDocuments
Call Translucent(oRefDoc)
Next
ElseIf oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
Dim oPart As Inventor.PartDocument
oPart = oDoc
Dim oWorkSurface As Inventor.WorkSurface
For Each oWorkSurface In oPart.ComponentDefinition.WorkSurfaces
oWorkSurface.Translucent = False
Next
End If
End Function
Can this line:
oWorksurface.Translucent = False
Be edited to:
oWorksurface. (whatever this needs to be to change the color) = Snow
Or something to this effect?
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)
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)
Can't find what you're looking for? Ask the community or share your knowledge.