Rule crashes when run twice - shrinkwrap

Rule crashes when run twice - shrinkwrap

dialunau
Advocate Advocate
454 Views
7 Replies
Message 1 of 8

Rule crashes when run twice - shrinkwrap

dialunau
Advocate
Advocate

Hello everyone,

I'm making a rule that creates a shrinkwrap of a part in an assembly, save that shrinkwrap part and then place it in the original assembly. My rule works perfectly fine when I run it the first time, however, it always crashes when I run it a second time. Then if I run it a third time it works fine, but the fourth time it crashes again and so on. The problem seems to be in the line that makes the .saveas command.

 

Any ideas of what is happening and how to fix it?

Here is my code:

 

 

Sub Main()
    Dim oAssy As AssemblyDocument = ThisApplication.ActiveDocument
    Dim oAssyDef As AssemblyComponentDefinition = oAssy.ComponentDefinition
	
    'Select the occurrences
	Dim oOcc1 As ComponentOccurrence = ThisApplication.CommandManager.Pick(kAssemblyLeafOccurrenceFilter,"Select the first occurrence")
    Dim oOcc2 As ComponentOccurrence = ThisApplication.CommandManager.Pick(kAssemblyLeafOccurrenceFilter,"Select the second occurrence")
    Dim oOcc1Def As PartComponentDefinition = oOcc1.Definition
	Dim oSWPath As String
	
	oSWPath = SWrap(oAssy, oAssyDef, oOcc2, oSWPath)
	Call AddToAssy(oAssyDef, oSWPath)
End Sub

Function SWrap(oAssy As AssemblyDocument, oAssyDef As AssemblyComponentDefinition, oOcc2 As ComponentOccurrence, oSWPath As String)
	Dim oSWDoc As PartDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject)
	Dim oSWD As ShrinkwrapDefinition = oSWDoc.ComponentDefinition.ReferenceComponents.ShrinkwrapComponents.CreateDefinition(oAssy.FullDocumentName)
	Dim oExclude As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	Dim oOcc As ComponentOccurrence
	
	'Add only the second occurrence
	For Each oOcc In oAssyDef.Occurrences
		If Not oOcc Is oOcc2 Then
			Call oExclude.Add(oOcc)
		End If
	Next oOcc
	
	oSWD.AdditionalExcludedOccurrences = oExclude
	oSWD.RemoveHolesStyle = ShrinkwrapRemoveStyleEnum.kShrinkwrapRemoveAll
	oSWD.BreakLink = True
	
	Dim oSWComp As ShrinkwrapComponent
	oSWComp = oSWDoc.ComponentDefinition.ReferenceComponents.ShrinkwrapComponents.Add(oSWD)
	
	oSWPath = ThisDoc.PathAndFileName(True) & "_SW.ipt"
	
	'//// Delete previous file if it already exists ////
	If System.IO.File.Exists(oSWPath) = True Then
		System.IO.File.Delete(oSWPath)
	End If
	
	oSWDoc.SaveAs(oSWPath, False) '/ THE CODE CRASHES EXACTLY AT THIS LINE EVERY SECOND TIME I RUN IT /
	oSWDoc.Close
	
	Return(oSWPath)
End Function

Sub AddToAssy(oAssyDef As AssemblyComponentDefinition, oSWPath As String)
	
	Dim oMat As Matrix = ThisApplication.TransientGeometry.CreateMatrix()
    oMat.SetTranslation(ThisApplication.TransientGeometry.CreateVector(0, 0, 0))
	
	Dim oNewOcc As ComponentOccurrence = oAssyDef.Occurrences.Add(oSWPath, oMat)
End Sub

 

dialunau_1-1660138383461.png

 

 

0 Likes
455 Views
7 Replies
Replies (7)
Message 2 of 8

WCrihfield
Mentor
Mentor

Hi @dialunau.  This is just somewhat of an educated guess, but after reviewing this it seems a bit odd to be setting the initial value of the oSWPath variable using a function which requires that oSWPath as one of its input variables.  Seems like a circular paradox situation (the function needs to run in order to set its value, but the function needs an initial value to run).  Also, the one line you are using within the function to re-set the value of oSWPath seems a bit ambiguous, because it uses the term "ThisDoc", which can be pointing to different documents in different situations.  Just my initial thoughts.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 8

WCrihfield
Mentor
Mentor

Also, if the term 'ThisDoc' within your function is supposed to be referring to the new PartDocument that you just created, that new PartDocument will not have a path or file name yet, because it has not been saved yet, which will cause a problem when you try to get it with that line of code.  Then when you run it the second time, maybe it is still seeing the previously created new PartDocument which has been saved, and uses its path and file name in that second run.  Just some more thoughts.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 4 of 8

dialunau
Advocate
Advocate

Thanks for the comments.

I fixed those inconsistencies by defining the path as the assembly path which is already saved in the location, and replacing the 'ThisDoc' line with the part document variable 'oSWDoc'.

 

Even so, the code still crashes when I run it twice.

Here are the changes I made:

 

Sub Main()
    Dim oAssy As AssemblyDocument = ThisApplication.ActiveDocument
    Dim oAssyDef As AssemblyComponentDefinition = oAssy.ComponentDefinition
	
    'Select the occurrences
	Dim oOcc1 As ComponentOccurrence = ThisApplication.CommandManager.Pick(kAssemblyLeafOccurrenceFilter,"Select the first occurrence")
    Dim oOcc2 As ComponentOccurrence = ThisApplication.CommandManager.Pick(kAssemblyLeafOccurrenceFilter,"Select the second occurrence")
    Dim oOcc1Def As PartComponentDefinition = oOcc1.Definition
	Dim oSWPath As String = oAssy.FullDocumentName & "_SW.ipt" '// fixed so it has a reference to an already saved document //
	
	Call SWrap(oAssy, oAssyDef, oOcc2, oSWPath)
	Call AddToAssy(oAssyDef, oSWPath)
End Sub

Sub SWrap(oAssy As AssemblyDocument, oAssyDef As AssemblyComponentDefinition, oOcc2 As ComponentOccurrence, oSWPath As String)
	Dim oSWDoc As PartDocument = ThisApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject)
	Dim oSWD As ShrinkwrapDefinition = oSWDoc.ComponentDefinition.ReferenceComponents.ShrinkwrapComponents.CreateDefinition(oAssy.FullDocumentName)
	Dim oExclude As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	Dim oOcc As ComponentOccurrence
	
	'Add only the second occurrence
	For Each oOcc In oAssyDef.Occurrences
		If Not oOcc Is oOcc2 Then
			Call oExclude.Add(oOcc)
		End If
	Next oOcc
	
	oSWD.AdditionalExcludedOccurrences = oExclude
	oSWD.RemoveHolesStyle = ShrinkwrapRemoveStyleEnum.kShrinkwrapRemoveAll
	oSWD.BreakLink = True
	
	Dim oSWComp As ShrinkwrapComponent
	oSWComp = oSWDoc.ComponentDefinition.ReferenceComponents.ShrinkwrapComponents.Add(oSWD)
	
	'/// Delete previous file if it already exists ///
	If System.IO.File.Exists(oSWPath) = True Then
		System.IO.File.Delete(oSWPath)
	End If
	
	oSWDoc.SaveAs(oSWPath, False) '/// The code still crashes at this exact line ///
	oSWDoc.Close
End Sub

Sub AddToAssy(oAssyDef As AssemblyComponentDefinition, oSWPath As String)
	Dim oMat As Matrix = ThisApplication.TransientGeometry.CreateMatrix()
    oMat.SetTranslation(ThisApplication.TransientGeometry.CreateVector(0, 0, 0))
	
	Dim oNewOcc As ComponentOccurrence = oAssyDef.Occurrences.Add(oSWPath, oMat)
End Sub
0 Likes
Message 5 of 8

Michael.Navara
Advisor
Advisor

Deleting a file that may be open in inventor is very dangerous and may cause unexpected behavior.

Replace this part of your code with something different. For example generate new sequentially numbered file name. 

 

	'//// Delete previous file if it already exists ////
	If System.IO.File.Exists(oSWPath) = True Then
		System.IO.File.Delete(oSWPath)
	End If

 

 

0 Likes
Message 6 of 8

dialunau
Advocate
Advocate

I edited that fragment to instead of deleting the file, make the new file sequential.

No luck, the code still crashes at that specific line.

0 Likes
Message 7 of 8

SevInventor
Advocate
Advocate

Hello

Hello dialunau
 

if you add the timestring to the filename you can avoid multiple same filenames.

There are no Errors when i tested it

 

	Dim oTime as string = TimeString
	oTime = Replace(oTime, ".", "-")
	oTime = Replace(oTime, ":", "-")
	Dim oSWPath As String = oAssy.FullDocumentName & oTime & "_SW.ipt" '// fixed so it has a reference to an already saved document //

 

0 Likes
Message 8 of 8

whashtonjrGV2BR
Explorer
Explorer

Hi dialunau.

 

Maybe it might be the IO method is general .Net and the save method built in is likely VB specific?

 

You might want to try the VB methods "My.Computer.FileSystem.FileExist("C:\test.txt")" "My.Computer.FileSystem.DeleteFile("C:\test.txt")".

 

It might be "InventorVb.Application.FileManager.DeleteFile()" in iLogic.

 

Here's a link for more detail How to: Delete a File - Visual Basic | Microsoft Docs and  FileSystem.FileExists(String) Method (Microsoft.VisualBasic.FileIO) | Microsoft Docs

 

Hope that helps.

 

Regards,

Bill Ashton