Announcements
Due to scheduled maintenance, the Autodesk Community will be inaccessible from 10:00PM PDT on Oct 16th for approximately 1 hour. We appreciate your patience during this time.
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: 

ComponentOccurrence VS AllReferencedDocuments

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
ts2.cad3
714 Views, 8 Replies

ComponentOccurrence VS AllReferencedDocuments

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
8 REPLIES 8
Message 2 of 9
Frederick_Law
in reply to: ts2.cad3

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

 

Message 3 of 9

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

 

 

 

Message 4 of 9
WCrihfield
in reply to: ts2.cad3

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

EESignature

(Not an Autodesk Employee)

Message 5 of 9

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

 

Message 6 of 9
JhoelForshav
in reply to: ts2.cad3

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))

 

Message 7 of 9
ts2.cad3
in reply to: WCrihfield

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

 

 

Message 8 of 9


@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

Message 9 of 9
ts2.cad3
in reply to: JhoelForshav

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.

Post to forums  

Autodesk Design & Make Report