How to copy a part in an assembly using iLogic or API?

How to copy a part in an assembly using iLogic or API?

alewis
Contributor Contributor
1,993 Views
5 Replies
Message 1 of 6

How to copy a part in an assembly using iLogic or API?

alewis
Contributor
Contributor

Hello Knowledge network community

 

My goal is to use iLogic or the Inventory API to create a unique copy of a part (.ipt file) in an assembly and place the new unique copy in that assembly. This would be the same as the inventor interface command “Copy components”.

 

Thank you for your help.

0 Likes
1,994 Views
5 Replies
Replies (5)
Message 2 of 6

WCrihfield
Mentor
Mentor

Hi @alewis.  There are likely several paths that could be taken within the code to make this happen, but I chose a fairly straight forward, basic, and logical route.  It doesn't attempt to do any thing further, like re-constrain the component or place it any specific orientation/position, just copy it, and place the copy back into the assembly.  Within this process it needs to know the path & file name that you want to use for the 'new' document, so I simply choose to make the copy within the same directory/folder as the original, then just append "_copy" to the end of the file name.  If you need to change that, it should be fairly easy, due to how I have laid all the data out within the code.

Here's the iLogic rule code I created for this task, that worked as planned when tested:

If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
	MsgBox("An Assembly Document must be active for this rule to work. Exiting.",vbCritical, "WRONG DOCUMENT TYPE")
	Exit Sub
End If
Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
'create variable to represent original component
Dim oOriginal As ComponentOccurrence
'set its value however you prefer
'oOriginal = oADef.Occurrences.ItemByName("MyComponent:1")
oOriginal = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select a component to copy.")
'now get the actual document / file it represents
Dim oOrigDoc As Document = oOriginal.Definition.Document
'get its full file name (path, name, & extension)
Dim oOrigFile As String = oOrigDoc.FullFileName

'<<< now specify the new path & file name for the new file (after copied) >>>
'capture 'path' of original
Dim oPath As String = System.IO.Path.GetDirectoryName(oOrigFile)
'capture file name only (without path or extension) of the original
Dim oOrigName As String = System.IO.Path.GetFileNameWithoutExtension(oOrigFile)
'capture extension of original
Dim oExt As String = System.IO.Path.GetExtension(oOrigFile)
'get 'local' directory seperator character (just in case it's different on your computer)
Dim oDirSep As Char = System.IO.Path.DirectorySeparatorChar
'now assemble the new path, name, & extension
Dim oCopiedFile As String = oPath & oDirSep & oOrigName & "_copy" & oExt

'now copy it
ThisApplication.FileManager.CopyFile(oOrigFile, oCopiedFile, FileManagementEnum.kCopyFileMask)

'now insert the copied document back into the assembly as a component
Dim oPosition As Matrix = ThisApplication.TransientGeometry.CreateMatrix
oADef.Occurrences.Add(oCopiedFile, oPosition)

If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.

If you want and have time, I would appreciate your Vote(s) for My IDEAS 💡or you can Explore My CONTRIBUTIONS

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 6

alewis
Contributor
Contributor

Thank you very much for your help. You even anticipated an alternative possibility of choosing a specific name for the copied part, which is the option I used. As I was researching a solution I could not find any object in the object model that directly related to a copy command. This gives me a look into how, through various approaches, commands can be executed.

Another thing I realized would be needed with this model is having multiple copies. There is the potential of needing to add more than one copy to this assembly. When I run the code a second time it makes an instance copy, the same as Ctrl+c and Ctrl+v. How would you write the code to copy the original part, "MyComponent:1" into multiple unique copies?

 

Thank you 

0 Likes
Message 4 of 6

WCrihfield
Mentor
Mentor

OK.  So you were using the ItemByName() instead of the Pick method, that's just fine.  Looking back over the code I posted above, I can see now that I left out an important step that might have prevented this behavior.  There needed to be a step in there just before the CopyFile line, where it checks to see if that file already exists, before trying to save over it.  Something like this:

If System.IO.File.Exists(oCopiedFile) Then
	MsgBox("A file by that name already exists.  Exiting rule.", vbCritical, "")
	Exit Sub 'or Return
End If

  Once we add that step in, we still need to deal with the new challenge of making multiple copies of the same part, with each having a unique file name.  To do this, we will either need to hard code a quantity number into the code, or prompt the user for a quantity.  Maybe something like this:

Dim oQty As Integer = CInt(InputBox("Specify Quantity Of Copies To Make.", "QUANTITY","1"))

(I put the InputBox within CInt() to change its return data Type from String to Integer.) 

Then, we will need to work on a naming scheme, or plan for making each file name unique.  What would you like to see happen with the file names instead of just appending "_copy" to the end?  One fairly simple option might be to add a simple Integer to the end of the file name, then increment that number by 1 for each copy in the quantity.

This would be an example of this idea:

For oCopy As Integer = 1 To oQty
	Dim oCopiedFile As String = oPath & oDirSep & oOrigName & oCopy & oExt
	Try
		ThisApplication.FileManager.CopyFile(oOrigFile, oCopiedFile, FileManagementEnum.kCopyFileMask)
	Catch
		MsgBox("Failed to copy file.", vbInformation, "")
	End Try
	Dim oPosition As Matrix = ThisApplication.TransientGeometry.CreateMatrix
	oADef.Occurrences.Add(oCopiedFile, oPosition)
Next

  Also, if you wanted we could capture the 'position/orientation' (Matrix) of the original component, before we copy it, then use that when we insert the copied versions of it, instead of placing them at the origin.  The way to capture this would be like this:

Dim oPosition As Matrix = oOriginal.Transformation

Then don't re-create that same variable again down below, because it has already been created and its value set here.

Does all this make sense to you?

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 5 of 6

alewis
Contributor
Contributor

Yes, since you have laid it out organized and explained, it does make sense. I don’t know some of the language but I can follow the code as to what functions are taking place. Thank you.

The input box is similar to what I was planning. Because there will be other parameters to enter, I will be using a form. So, the quantity will be entered into a parameter. I’ll make an attempt here. In order to use a parameter would I switch out the input box for the user parameter?

Dim oQty As Integer = MyComponent_Quantity 

The naming scheme example you wrote I think will work. The first part is named LS-1 and each copy after this will be in numerical sequence, LS-2, LS-3,… Although, I wonder then if I should start with an empty assembly and copy the first part from the assembly folder naming the original LS-. Otherwise, would the names be copied as LS-11, LS-12,LS-13,…?

Placing each copy is definitely something I was needing, but did not want to ask for too much. I have researched this and found methods of assigning names to faces and then using relationship snippets, such as AddFlush. These constraints will be simple and repetitive. The part is a cylinder and the end of the cylinder needs to be constrained to the end of the copy, just stacking them. So, the constraints would be one face mate, axis mate and a directed angle so to prevent from rotating.

Thank you for all your help.

0 Likes
Message 6 of 6

alewis
Contributor
Contributor

WCrihfield

     Hello again. I finally got a chance to work on this rule and added the code you suggested from your last message. I named the part LS-. This works good naming each subsequent part LS-1, LS-2, LS-3, etc.

I would like to start with the part named LS-1, copy it and then name each subsequent part LS-2, LS-3,etc. This way I can get rid of the unused part. I added the following code and tried it in the two places where the name is defined.

 

Dim oOrigName As String = Left(System.IO.Path.GetFileNameWithoutExtension(oOrigFile),3)

 

So, it takes the name LS-1 and does return LS-, but the code breaks down when trying the CopyFile method.

I don’t see how this could be affecting the method when all I’m doing is changing an independent variable.

Thank you

If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
	
MsgBox("An Assembly Document must be active for this rule to work. Exiting.", vbCritical, "WRONG DOCUMENT TYPE")
	
End If
Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
'create variable to represent original component
Dim oOriginal As ComponentOccurrence
'set its value however you prefer
oOriginal = oADef.Occurrences.ItemByName("LS-1.ipt")
'oOriginal = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select a component to copy.")
'now get the actual document / file it represents
Dim oOrigDoc As Document = oOriginal.Definition.Document
'get its full file name (path, name, & extension)
Dim oOrigFile As String = oOrigDoc.FullFileName

'<<< now specify the new path & file name for the new file (after copied) >>>
'capture 'path' of original
Dim oPath As String = System.IO.Path.GetDirectoryName(oOrigFile)
'capture file name only (without path or extension) of the original
Dim oOrigName As String = Left(System.IO.Path.GetFileNameWithoutExtension(oOrigFile),3)
'capture extension of original
Dim oExt As String = System.IO.Path.GetExtension(oOrigFile)
'get 'local' directory seperator character (just in case it's different on your computer)
Dim oDirSep As Char = System.IO.Path.DirectorySeparatorChar

'MessageBox.Show(oOrigName, "Title")

'how many copies
Dim oQty As Integer = CInt(InputBox("Specify Quantity Of Copies To Make.", "QUANTITY", "1"))

For oCopy As Integer = 1 To oQty
	'now assemble the new path, name, & extension
	Dim oCopiedFile As String = oPath & oDirSep & oOrigName & oCopy & oExt
'MessageBox.Show(oCopiedFile, "Title")
	
	Try
		'now copy it
		ThisApplication.FileManager.CopyFile(oOrigFile, oCopiedFile, FileManagementEnum.kCopyFileMask)
	Catch
		MsgBox("Failed to copy file.", vbInformation, "")
	End Try
	'now insert the copied document back into the assembly as a component
	Dim oPosition As Matrix = ThisApplication.TransientGeometry.CreateMatrix
	oADef.Occurrences.Add(oCopiedFile, oPosition)
Next

 

0 Likes