Find Assembly Components by Property with Code

Anonymous

Find Assembly Components by Property with Code

Anonymous
Not applicable

Can I do the following with iLogic, C#, VB.NET, ...?

I now have code to loop through all occurrences, but this would be a faster way to obtain the same result.

 

The reason for this is that I only want to keep the items visible with a custom property (SPL_Simple).

With this I could select all those items very quick.

 

I just can't find a way to do this in code:

Schermafdruk 2017-06-14 17.15.42.png

 

My current code to loop (iLogic -> slow solution and not always correct):

Sub Main()
	InventorVb.DocumentUpdate()
	iLogicVb.UpdateWhenDone = True
	
	Dim oAsmCompDef As AssemblyComponentDefinition
	oAsmCompDef = ThisApplication.ActiveDocument.ComponentDefinition
	
	SetRepresentation(oAsmCompDef)
	Iterate(oAsmCompDef,1,False)
End Sub

Sub SetRepresentation(ByVal oAsmCompDef As AssemblyComponentDefinition)
	Try		
		Dim oViewRep As DesignViewRepresentation
		For Each oViewRep In oAsmCompDef.RepresentationsManager.DesignViewRepresentations
			If oViewRep.Name = Globals._headRepresentation Then
				oViewRep.Activate
				oViewRep.HideAll()
			End If
		Next
	Catch
	End Try	
End Sub
		
Sub Iterate(ByVal oAsmCompDef As AssemblyComponentDefinition, ByVal top As Integer, ByVal visibleParam As Boolean)
	Dim oOccurrence As ComponentOccurrence
	For Each oOccurrence In oAsmCompDef.Occurrences
		Globals._countOcc(0) = Globals._countOcc(0) + 1
			Dim oOccName As String = oOccurrence.Name
			Try
				Dim doc = oOccurrence.Definition.Document
				Dim propSet = doc.propertySets(Globals._propSet)
				Dim isVisible As Boolean = visibleParam
				For Each prop In propSet
					If prop.Name = Globals._param Then
						If prop.Value.ToString = Globals._paramVal Then
							isVisible = True
							Exit For
						End If
					End If
				Next
				If isVisible = True
					oOccurrence.Visible = True
					Try
						Component.Visible(oOccurrence.Name) = True
					Catch ex As Exception
					End Try
					'Component.InventorComponent(oOccurrence.Name).Visible = True -> Not Working Propper
					If TypeOf oOccurrence.Definition Is AssemblyComponentDefinition Then
						oAsmCompDef = oOccurrence.Definition
						Iterate(oAsmCompDef,2,False)
					End If
				Else
					oOccurrence.Visible = False
					If TypeOf oOccurrence.Definition Is AssemblyComponentDefinition Then
						oAsmCompDef = oOccurrence.Definition
						Iterate(oAsmCompDef,2,False)
					End If
				End If
			Catch ex As Exception
			End Try
	Next
	If top = 1 Then
		Globals._countLoop(0) = Globals._countLoop(0) + 1
	End If
End Sub

Friend NotInheritable Class Globals
	Public Shared _countOcc = New Integer() {0}
	Public Shared _countLoop = New Integer() {0}
	Public Shared _headRepresentation As String = "Default"
	Public Shared _param As String = "SPL_Simple"
	Public Shared _paramVal As String = "True"
	Public Shared _propSet As String = "Inventor User Defined Properties"
End Class

 

Reply
Accepted solutions (1)
1,095 Views
8 Replies
Replies (8)

S_May
Mentor
Mentor

Hi @Anonymous

 

This is a cool thing, they want to share any information that makes them visible with the search, but why do not they do this about LOD, this tool is more reliable and powerful than a module with ilogic

I would like to give them a pattern as I also work with subassemblies up to 80.000 parts Smiley Happy

0 Likes

Owner2229
Advisor
Advisor

Hey, try it like this:

It should be a bit faster and more reliable.

 

Sub Main()
	InventorVb.DocumentUpdate()
	iLogicVb.UpdateWhenDone = True
	Dim oCD As AssemblyComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition
	SetRepresentation(oCD)
	Iterate(oCD.Occurrences)
End Sub

Private _countOcc As Integer = 0
Private _countLoop As Integer = 0
Private _headRepresentation As String = "Default"
Private _param As String = "SPL_Simple"
Private _paramVal As String = "True"
Private _propSet As String = "Inventor User Defined Properties"

Sub SetRepresentation(oCD As AssemblyComponentDefinition)
	Try
		Dim oVRs As DesignViewRepresentations = oCD.RepresentationsManager.DesignViewRepresentations
		Dim oVR As DesignViewRepresentation = oVRs(_headRepresentation)
		oVR.Activate()
		oVR.HideAll()
	Catch
	End Try
End Sub

Sub Iterate(oOccs As ComponentOccurrences, Optional level As Integer = 1)
	For Each oOcc As ComponentOccurrence In oOccs
		_countOcc = _countOcc + 1
		Try
			Dim oDoc As Document = oOcc.Definition.Document
			Dim isVisible As Boolean = False
			Try
				Dim oPropSet As PropertySet = oDoc.PropertySets(_propSet)
				Dim oProp As Inventor.Property = oPropSet(_param)
				Dim oVal As String = oProp.Expression
				isVisible = (oVal = _paramVal)
			Catch
			End Try
			oOcc.Visible = isVisible
			If TypeOf oOcc.Definition Is AssemblyComponentDefinition Then
				Iterate(oOcc.SubOccurrences, level + 1)
			End If
		Catch
		End Try
	Next
	If level = 1 Then _countLoop = _countLoop + 1
End Sub

 

Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods

Anonymous
Not applicable

I've already updated my code so that it runs much faster and is reliable.

Your solution was also good, but I'm going to stick with mine.

 

Still I would like to know if it's possible to use the "Find Assembly Components" in code, this would make a big difference.

 

My updated code for those who are interested:

Sub Main()
	InventorVb.DocumentUpdate()
	iLogicVb.UpdateWhenDone = True
	
	Globals._countLoop(0) = 0
	Globals._countOcc(0) = 0
	
	Dim oAsmCompDef As AssemblyComponentDefinition
	oAsmCompDef = ThisApplication.ActiveDocument.ComponentDefinition
	SetRepresentation(oAsmCompDef)
	Iterate(oAsmCompDef)
End Sub

Sub SetRepresentation(ByVal oAsmCompDef As AssemblyComponentDefinition)
	Try		
		Dim oViewRep As DesignViewRepresentation
		For Each oViewRep In oAsmCompDef.RepresentationsManager.DesignViewRepresentations
			If oViewRep.Name = Globals._headRepresentation Then
				oViewRep.Activate
				oViewRep.HideAll()
			End If
		Next
	Catch
	End Try	
End Sub

Sub Iterate(ByVal oAsmCompDef As AssemblyComponentDefinition)
	Dim oCompDef As Inventor.ComponentDefinition = oAsmCompDef
	Dim oCompOcc As Inventor.ComponentOccurrence
	Dim oSubCompOcc As Inventor.ComponentOccurrence

	For Each oOccurrence In oCompDef.Occurrences
		Globals._countLoop(0) = Globals._countLoop(0) + 1
		Dim doc = oOccurrence.Definition.Document
		Dim propSet = doc.propertySets(Globals._propSet)
		For Each prop In propSet
			If prop.Name = Globals._param Then
				If prop.Value.ToString = Globals._paramVal Then
					oOccurrence.Visible = True
					Try
						Component.Visible(oOccurrence.Name) = True
					Catch
					End Try
					Globals._countOcc(0) = Globals._countOcc(0) + 1
					Exit For
				End If
			End If
		Next
		
		For Each oSubOccurrence In oOccurrence.SubOccurrences
			Globals._countLoop(0) = Globals._countLoop(0) + 1
			Dim subdoc = oSubOccurrence.Definition.Document
			Dim subpropSet = subdoc.propertySets(Globals._propSet)
			For Each subprop In subpropSet
				If subprop.Name = Globals._param Then
					If subprop.Value.ToString = Globals._paramVal Then
						oSubOccurrence.Visible = True
						Try
							Component.Visible(oSubOccurrence.Name) = True
						Catch
						End Try
						Globals._countOcc(0) = Globals._countOcc(0) + 1
						Exit For
					End If
				End If
			Next
		Next
		
		If TypeOf oOccurrence.Definition Is AssemblyComponentDefinition Then
			oAsmCompDef = oOccurrence.Definition
			Iterate(oAsmCompDef)
		End If
    Next
End Sub

Friend NotInheritable Class Globals
	Public Shared _countOcc = New Integer() {0}
	Public Shared _countLoop = New Integer() {0}
	Public Shared _headRepresentation As String = "Default"
	Public Shared _param As String = "SPL_Simple"
	Public Shared _paramVal As String = "True"
	Public Shared _propSet As String = "Inventor User Defined Properties"
End Class

 

Owner2229
Advisor
Advisor
Accepted solution

You can't use the "Find Assembly Components" in code, as I believe it's not exposed to API.

You should re-check the code I send you and update the "newer" one you have.

In your code you're using way too many (unnecessary) "For Each" loops, leading to long delays, which are slowing down your code (a lot).

Also there's no need to declare the "Globals" as a class, since you're not re-using it.

Also, in your "newer" code you're iterating through the sub-occurrences twice (per level).

I can clean your "newer" code if you wish, but you might learn a thing or two if you do it yourself.

 

Here's the code I send before, cleaned of unnecessary counters and with some minor improvements for readability:

 

Sub Main()
	InventorVb.DocumentUpdate()
	iLogicVb.UpdateWhenDone = True
	Dim oDoc As Document = ThisApplication.ActiveDocument
	If oDoc.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Exit Sub
	Dim oCD As AssemblyComponentDefinition = oDoc.ComponentDefinition
	SetRepresentation(oCD)
	Iterate(oCD.Occurrences)
End Sub

Private _ViewRepre As String = "Default"
Private _PropName As String = "SPL_Simple"
Private _PropVal As String = "True"
Private _PropSet As String = "Inventor User Defined Properties"

Sub SetRepresentation(oCD As AssemblyComponentDefinition)
	Try
		Dim oVRs As DesignViewRepresentations = oCD.RepresentationsManager.DesignViewRepresentations
		Dim oVR As DesignViewRepresentation = oVRs(_ViewRepre)
		oVR.Activate()
		oVR.HideAll()
	Catch
	End Try
End Sub

Sub Iterate(oOccs As ComponentOccurrences)
	For Each oOcc As ComponentOccurrence In oOccs
		Try
			Dim isVisible As Boolean = False
			Try
				Dim oDoc As Document = oOcc.Definition.Document
				Dim oPropSet As PropertySet = oDoc.PropertySets(_PropSet)
				Dim oProp As Inventor.Property = oPropSet(_PropName)
				Dim oVal As String = oProp.Expression
				isVisible = (oVal = _PropVal)
			Catch
			End Try
			oOcc.Visible = isVisible
			If TypeOf oOcc.Definition Is AssemblyComponentDefinition Then
				Iterate(oOcc.SubOccurrences)
			End If
		Catch
		End Try
	Next
End Sub

 

Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
0 Likes

Owner2229
Advisor
Advisor

Here are some measurements and results (same assembly, 121 parts):

1) My code:

- runtime: 618 ms

- did hide/show everything correctly

 

2) Your code:

- runtime: 2017ms

 - doesn't hide anything (accordingly to the iProperty), only shows parts

Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
0 Likes

Anonymous
Not applicable

There's an app on the Inventor store that filters parts in assemblies by iProperty and adds them to view representations, if you want a ready-made solution. Its very fast - i'd be interested to benchmark the time. 

 

https://apps.autodesk.com/INVNTOR/en/Detail/Index?id=6357391234586136117&appLang=en&os=Win64

 

 

0 Likes

Owner2229
Advisor
Advisor

Well, I'm not gonna pay 20 bucks just to do some measurements on code I can write in a couple of mins ¯\_(ツ)_/¯

Consider using "Accept as Solution" / "Kudos" if you find this helpful.
- - - - - - - - - - - - - - -
Regards,
Mike

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - John F. Woods
0 Likes

Anonymous
Not applicable

 

Of course. However the OP (and other people viewing this thread) may not have your expertise, and may be looking for a ready-made solution for assembly filtering that doesn't require any code tinkering.

 

Although I suspect if they are looking on this forum they are the tinkering type 🙂

0 Likes