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:
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
Solved! Go to Solution.
Solved by Owner2229. Go to Solution.
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
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
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
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
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
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
Well, I'm not gonna pay 20 bucks just to do some measurements on code I can write in a couple of mins ¯\_(ツ)_/¯
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 🙂
Can't find what you're looking for? Ask the community or share your knowledge.