Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iLogic to change appearance color on all parts & surfaces within assembly

2 REPLIES 2
Reply
Message 1 of 3
bruce.hodder
270 Views, 2 Replies

iLogic to change appearance color on all parts & surfaces within assembly

bruce.hodder
Contributor
Contributor

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. 

Screenshot 2024-07-19 125258.png

0 Likes

iLogic to change appearance color on all parts & surfaces within assembly

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. 

Screenshot 2024-07-19 125258.png

2 REPLIES 2
Message 2 of 3
bruce.hodder
in reply to: bruce.hodder

bruce.hodder
Contributor
Contributor

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?

0 Likes

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?

Message 3 of 3
WCrihfield
in reply to: bruce.hodder

WCrihfield
Mentor
Mentor

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

EESignature

(Not an Autodesk Employee)

0 Likes

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

EESignature

(Not an Autodesk Employee)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report