I wrote this rule to select and zoom in on assembly components that were saved in a certain path. It works relatively well on top-level components in the main assembly, but it doesn't work on second-level components (contained in subassemblies). Is there a way to do this on all components of the main assembly and subassemblies and subassembly components?
Sub Main
If TypeOf ThisApplication.ActiveDocument Is AssemblyDocument Then
Dim oAsmDoc As AssemblyDocument = TryCast(ThisApplication.ActiveDocument, AssemblyDocument)
Dim oRefDocs As DocumentsEnumerator = oAsmDoc.AllReferencedDocuments
If oRefDocs.Count = 0 Then
MessageBox.Show("Sembra un assieme vuoto, impossibile procedere", "iLogic")
Exit Sub ' Esci dalla subroutine
End If
For Each oRefDoc As Document In oRefDocs
Dim oRefDocName As String = Left(oRefDoc.FullFileName, 7)'oCompDoc
If oRefDocName = "T:\WORK" Then
For Each oCompO As ComponentOccurrence In oAsmDoc.ComponentDefinition.Occurrences
If oCompO.ReferencedDocumentDescriptor.ReferencedDocument Is oRefDoc Then
ThisApplication.ActiveDocument.SelectSet.Select(oCompO)
Call Zoom(oCompO)
Exit Sub
End If
Next
End If
Next
Else
MessageBox.Show("Please run this rule from the assembly file.", "iLogic")
End If
MessageBox.Show("Nessun file da codificare", "title")
End Sub
Solved! Go to Solution.
Solved by Curtis_Waguespack. Go to Solution.
Solved by JhoelForshav. Go to Solution.
Solved by WCrihfield. Go to Solution.
Yes, you'll need to go through each assembly.
Recursively.
VBA recursive sub to set iProperties in all children in assembly:
Private Sub processAllSubFiles(ByVal oRefFiles As DocumentsEnumerator)
Dim oRefFile As Document
Dim oPropsets As PropertySets
Dim oPropSet As PropertySet
For Each oRefFile In oRefFiles
If oRefFile.IsModifiable Then
Set oPropsets = oRefFile.PropertySets
Set oPropSet = oPropsets.Item("Design Tracking Properties")
If (oPropSet.Item("Project").value <> "Common") _
And (oPropSet.Item("Project").value <> "Purchase") _
And (oPropSet.Item("Project").value <> "Hardware") Then
Set oPropsets = oRefFile.PropertySets
Set oPropSet = oPropsets.Item("Summary Information")
oPropSet.Item("Title").value = TitleBox
oPropSet.Item("Revision Number").value = RevBox
oPropSet.Item("Author").value = AuthorBox
Set oPropSet = oPropsets.Item("Document Summary Information")
oPropSet.Item("Company").value = CompanyBox
Set oPropSet = oPropsets.Item("Design Tracking Properties")
oPropSet.Item("Project").value = ProjectBox
oPropSet.Item("Designer").value = DesignerBox
End If
End If
If oRefFile.ReferencedFiles.Count > 0 Then
processAllSubFiles oRefFile.ReferencedFiles
End If
Next
End Sub
Hi @ts2.cad3
Something like this might work for you as well.
I hope this helps.
Best of luck to you in all of your Inventor pursuits,
Curtis
http://inventortrenches.blogspot.com
Sub Main If Not TypeOf ThisApplication.ActiveDocument Is AssemblyDocument Then MessageBox.Show("Please run this rule from the assembly file.", "iLogic") Exit Sub End If Call TraverseAssembly(ThisApplication.ActiveDocument.ComponentDefinition.Occurrences) End Sub Sub TraverseAssembly(oOccs As ComponentOccurrences) Dim oOcc As ComponentOccurrence For Each oOcc In oOccs If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then Call TraverseAssembly(oOcc.SubOccurrences) Else 'parts If oOcc.Name = "T:\WORK" Then ThisApplication.ActiveDocument.SelectSet.Select(oOcc) ThisApplication.CommandManager.ControlDefinitions.Item("AppZoomSelectCmd").Execute Exit sub End If End If Next End Sub
Quick question...why simply zoom in on each one? Do you need to 'do' something to/with each one? If you simply zoom in on each one in a loop, it will go by really quickly. Anyways, since I also already had something related to this, I figured I might as well post it too, just in case it might help some. It does not do the selection or the zoom command, just gets the filtered objects into some handy collections for you, so you can process them later.
Sub Main
If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Exit Sub
Dim oADoc As AssemblyDocument = ThisDoc.Document
Dim oRefDocs As DocumentsEnumerator = oADoc.AllReferencedDocuments
Dim oFilteredRefDocs As List(Of Inventor.Document) = oRefDocs.Cast(Of Inventor.Document).Where(Function(d) d.FullFileName.StartsWith("T:\WORK")).ToList
If oFilteredRefDocs Is Nothing OrElse oFilteredRefDocs.Count = 0 Then Exit Sub
Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
Dim oDict As New Dictionary(Of Inventor.Document, Inventor.ComponentOccurrencesEnumerator)
Dim oAllFilteredOccs As New List(Of Inventor.ComponentOccurrence)
For Each oRefDoc As Document In oFilteredRefDocs
Dim oRefOccs As ComponentOccurrencesEnumerator = oOccs.AllReferencedOccurrences(oRefDoc)
If oRefOccs Is Nothing OrElse oRefOccs.Count = 0 Then Continue For
oDict.Add(oRefDoc, oRefOccs)
For Each oRefOcc As ComponentOccurrence In oRefOccs
oAllFilteredOccs.Add(oRefOcc)
Next 'oRefOcc
Next 'oRefDoc
'now you have a Dictionary entry for each document reference, and all associated components for it
'and you have a List with every component (from every level) that is associated with that starter path
'For Each .....
'do something with the component(s) here
'Next
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 @Curtis_Waguespack , and thanks for reply.
I think you got to the heart of the problem. Needing to work on the file path, I need access to the. FullFileName; And I do not succeed if I am in the context of the. ComponentOccurrence. The code you posted therefore unfortunately can not work; It would also ignore assemblies.
Dim oRefDocName As String = Left(oRefDoc.FullFileName, 7)
Else 'parts If oOcc.Name = "T:\WORK" Then
Hi @ts2.cad3
My approach would be a lambda expression to filter out the occurrences.
Something I use a lot when I need all the occurrences at all levels in an assembly is to use the AssemblyComponentDefinition as an argument for Occurrences.AllReferencedOccurrences.
See example below 🙂
Dim path As String = "T:\WORK"
Dim asm As AssemblyDocument = ThisDoc.Document
Dim asmDef As AssemblyComponentDefinition = asm.ComponentDefinition
For Each oOcc As ComponentOccurrence In asmDef.Occurrences.AllReferencedOccurrences(asmDef).OfType(Of ComponentOccurrence).Where(Function(x) x.Definition.Document.FullFileName.StartsWith(path))
asm.SelectSet.Select(oOcc)
ThisApplication.CommandManager.ControlDefinitions.Item("AppZoomSelectCmd").Execute
Next
This way you get all collection of all occurrences so you don't have to traverse every sub assembly with recursive functions 🙂
If you only want the code to zoom in to part occurrences, and not any eventual assembly occurrences then use this lambda expression:
asmDef.Occurrences.AllReferencedOccurrences(asmDef).OfType(Of ComponentOccurrence).Where(Function(x) x.DefinitionDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject AndAlso x.Definition.Document.FullFileName.StartsWith(path))
Jhoel Forshav
Download my free Inventor Addin - Hole Projector
LinkedIn | Ideas | Contributions | Blog posts | Website
Hi @WCrihfield and thanks for reply!
Actually in addition to the zoom the component is also selected, and this allows to perform subsequent operations with an external PDM that I can not use through ilogic unfortunately.
Your solution of using a dictionary to link.occurrences to documents is very elegant and solved my problem, I made some changes to fit my particular need and it seems to work perfectly. Here the complete code:
Sub Main
If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
MessageBox.Show("Please run this rule from the assembly file.", "iLogic")
Exit Sub
Else
Dim oADoc As AssemblyDocument = ThisDoc.Document
Dim oRefDocs As DocumentsEnumerator = oADoc.AllReferencedDocuments
Dim oFilteredRefDocs As List(Of Inventor.Document) = oRefDocs.Cast(Of Inventor.Document).Where(Function(d) d.FullFileName.StartsWith("T:\WORK")).ToList
If oFilteredRefDocs Is Nothing OrElse oFilteredRefDocs.Count = 0 Then
MessageBox.Show("Sembra un assieme vuoto, impossibile procedere", "iLogic")
Exit Sub
Else
'MessageBox.Show(oFilteredRefDocs.Count & " oFilteredRefDocs trovati", "iLogic")--CONTROLLO 1
Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
Dim oDict As New Dictionary(Of Inventor.Document, Inventor.ComponentOccurrencesEnumerator)
Dim oAllFilteredOccs As New List(Of Inventor.ComponentOccurrence)
For Each oRefDoc As Document In oFilteredRefDocs
Dim oRefOccs As ComponentOccurrencesEnumerator = oOccs.AllReferencedOccurrences(oRefDoc)
'MessageBox.Show(oRefOccs.Count & " oRefOccs trovati ","iLogic") -CONTROLLO 2
If oRefOccs Is Nothing OrElse oRefOccs.Count = 0 Then Continue For
'oDict.Add(oRefDoc, oRefOccs)
For Each oRefOcc As ComponentOccurrence In oRefOccs
oAllFilteredOccs.Add(oRefOcc)
Next 'oRefOcc
For Each oOcc As ComponentOccurrence In oAllFilteredOccs
ThisApplication.ActiveDocument.SelectSet.Select(oOcc)
Call Zoom(oOcc)
Exit Sub
Next
Next 'oRefDoc
End If
End If
End Sub
Sub Zoom(oCompO)
Dim cam As Camera = ThisApplication.ActiveView.Camera
'MessageBox.Show("zoom1", "Title")
Dim occur As ComponentOccurrence = oCompO
Dim min As Point
Dim Max As Point
min = occur.RangeBox.MinPoint
Max = occur.RangeBox.MaxPoint
' current camera target point
Dim curTarget As Point = cam.Target
'current camera eye point
Dim curEye As Point = cam.Eye
' get vector from current target to current eye
Dim toEyeVector As Vector = ThisApplication.TransientGeometry.CreateVector(curEye.X - curTarget.X, curEye.Y - curTarget.Y, curEye.Z - curTarget.Z)
' get new target point for camera
Dim targetPt As Point = ThisApplication.TransientGeometry.CreatePoint((Max.X + min.X) / 2#, (Max.Y + min.Y) / 2#, (Max.Z + min.Z) / 2#)
'create new eye point by starting at new target point
'and then translating point using the targetToEye vector
Dim newEye As Point = ThisApplication.TransientGeometry.CreatePoint(targetPt.X, targetPt.Y, targetPt.Z)
Call newEye.TranslateBy(toEyeVector)
' set new camera data
cam.Eye = newEye
cam.Target = targetPt
Call cam.SetExtents(40#, 40#)
' apply new camera
cam.Apply
End Sub
@ts2.cad3 wrote:
I think you got to the heart of the problem. Needing to work on the file path, I need access to the. FullFileName; And I do not succeed if I am in the context of the. ComponentOccurrence. The code you posted therefore unfortunately can not work; It would also ignore assemblies.
Hi @ts2.cad3 ,
My apologies, I think I did not complete the thought yesterday, as my example looked for the path in the occurrence name, which would not make sense.
To get the file name from the occurrence, we can use something like the example shown below. This example also zooms to all components, not just parts:
Sub Main Call TraverseAssembly(ThisApplication.ActiveDocument.ComponentDefinition.Occurrences) End Sub Sub TraverseAssembly(oOccs As ComponentOccurrences) Dim oOcc As ComponentOccurrence For Each oOcc In oOccs ThisApplication.ActiveDocument.SelectSet.clear ThisApplication.ActiveDocument.SelectSet.Select(oOcc) sFileName = oOcc.Definition.Document.FullFileName If sFileName.Contains("T:\WORK") Then _ ThisApplication.CommandManager.ControlDefinitions.Item("AppZoomSelectCmd").Execute If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then _ Call TraverseAssembly(oOcc.SubOccurrences) Next End Sub
I hope this helps.
Best of luck to you in all of your Inventor pursuits,
Curtis
http://inventortrenches.blogspot.com
hi @JhoelForshav and thanks for reply
I really like your solution and it works great!!!🙏
Can't find what you're looking for? Ask the community or share your knowledge.