Create part files of curves created in an assembly

Hi All, I am somewhat new to NX and very new to site. And am just getting started in VB. Have a question about Journaling.

Does anyone know of a journal (or can create a journal) that would be able to take curves created in a assembly and make them a part file with in the assembly. I am currently doing this manually such that I create the curve, typically a straight line ( which is being used to simulate a weld joint )and then in that assembly file, using the "create new part". Here I am able to give it a name desired and have it as a separate .prt file.
To be clear, I would like this to be done individually for each curve/line, not collectively making all curves/line one part file.

The desire here is to have some automation for assemblies that may have more than 50 "Welds" curves/line in it. I know that adding the curves/lines has to be done manually, and we prefer that, but being able to run a journal that would take those created and perform the above mentioned would be a great time saver.

Hoping that there maybe something already created that could be of help, or any input if this can actually be done. Looking forward to any feedback.

Thank you in advance.
Mark

What type of curves are being created in the assembly? Are they sketch curves, associative curve features, or unassociative (dumb) curves?

Dumb curves would be the easiest to deal with. If the curves are associative (sketches or associative curve features), do you need to maintain any of the associativity after exporting them to a component part?

My apologies for not explaining that. I am creating the curves by using points that are created in the assembly, and going point to point. That being said, I would not expect the associativity to be maintained, I am foreseeing that if the assembly had changed, the "weld" may be different, and may call for a different weld type which is depicted in our naming of the file itself.

Which raises another point, could the name of the curve be changed and assigned to the .prt file name? That would be a great advantage.

Thanks for reply.
Mp

"could the name of the curve be changed and assigned to the .prt file name?"

Are you using Teamcenter or some other PLM system? If so, there may be some rules in place to assign part names/numbers.

If you are not using a PLM system, we could use the curve name as the part name. Do you want the new files saved to the same location as the assembly? Also, what to do if a part with the desired name already exists or the curve doesn't have a name?

*We are not currently using a PLM, so that should not be an issue.
*Saving the parts to the same folder location as the assembly would be beneficial.
*If name already exists, would be best to give warning and reject cancel creation, that way it could be investigated and changed if necessary.
*In the case of no "name" assuming it is using the name from the feature properties, I would foresee using the default name. Correct me if I am wrong, but the file name once created could be changed in the location folder.

"Correct me if I am wrong, but the file name once created could be changed in the location folder"

If you mean opening Windows explorer and renaming the .prt file, this is possible, but NOT recommended. References between parts (assembly components, wave links, etc) will be broken. The preferred approach would be to open the part file and other related files (assembly, drawing, etc) and performing a "save-as" on the file. This will give you a choice to keep the other file names or rename them as well all while maintaining the links.

Anyway, here is some code to try out. It isn't heavily tested, so it could probably use some more error handling code; but it looks through the .Curves collection of the current display part and attempts to export each to its own component file. If it cannot find a name for a curve or if a part file with the name already exists, the operation is aborted. It writes some data to the information window, you may want to remove that or add more, depending on your preferences.

Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF

Module Module1

Dim theSession As Session = Session.GetSession()
Dim theUfSession As UFSession = UFSession.GetUFSession()

Dim theUI As UI = UI.GetUI()
Dim lw As ListingWindow = theSession.ListingWindow

Sub Main()

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "curves to components")

Dim newFileNames As New Dictionary(Of String, Curve)
Dim curvesNoName As New List(Of Curve)
Dim curvesDuplicateNames As New List(Of String)

lw.Open()

'save the assembly location
Dim parentFolder As String = IO.Path.GetDirectoryName(theSession.Parts.Display.FullPath)

'iterate through the curves in the display part (the assembly)
For Each tempCurve As Curve In theSession.Parts.Display.Curves
Dim curveFileName As String = Nothing
Dim featTag As Tag = Tag.Null
Dim myFeature As Features.Feature

'lw.WriteLine("curve tag: " & tempCurve.Tag.ToString)

theUfSession.Modl.AskObjectFeat(tempCurve.Tag, featTag)
If featTag = Tag.Null Then
'curve is unused
'lw.WriteLine("not a feature curve")
If String.IsNullOrEmpty(tempCurve.Name) Then
'lw.WriteLine("curve has no name")
curvesNoName.Add(tempCurve)
Else
'lw.WriteLine("curve name: " & tempCurve.Name)
If Not newFileNames.ContainsKey(tempCurve.Name) Then
newFileNames.Add(tempCurve.Name, tempCurve)
Else
'name is already taken
curvesDuplicateNames.Add(tempCurve.Name)
End If
End If
Else
myFeature = Utilities.NXObjectManager.Get(featTag)
'lw.WriteLine("used by: " & myFeature.GetFeatureName)

If Not String.IsNullOrWhiteSpace(myFeature.Name) Then
'lw.WriteLine("feature name: " & myFeature.Name)
If Not newFileNames.ContainsKey(myFeature.Name) Then
newFileNames.Add(myFeature.Name, tempCurve)
Else
'name alredy in dictionary
curvesDuplicateNames.Add(myFeature.Name)
End If
Else
'lw.WriteLine("feature: " & myFeature.GetFeatureName.Substring(0, myFeature.GetFeatureName.IndexOf("(")))
curveFileName = myFeature.GetFeatureName.Substring(0, myFeature.GetFeatureName.IndexOf("("))
If Not newFileNames.ContainsKey(curveFileName) Then
newFileNames.Add(curveFileName, tempCurve)
Else
'name already in dictionary
curvesDuplicateNames.Add(curveFileName)
End If
End If

End If

'lw.WriteLine("")

Next

If curvesDuplicateNames.Count > 0 Then
lw.WriteLine(curvesDuplicateNames.Count.ToString & " curve objects have duplicate names. Journal exiting.")
End If

If curvesNoName.Count > 0 Then
lw.WriteLine(curvesNoName.Count.ToString & " curves have no name. Journal exiting.")
End If

If curvesDuplicateNames.Count > 0 OrElse curvesNoName.Count > 0 Then
Return
End If

'check for existing files
Dim prtFileExists As Boolean = False
For Each tempKey As String In newFileNames.Keys
lw.WriteLine("checking file name: " & IO.Path.Combine(parentFolder, tempKey & ".prt"))
If IO.File.Exists(IO.Path.Combine(parentFolder, tempKey & ".prt")) Then
prtFileExists = True
lw.WriteLine(" !! file already exists")
Else
lw.WriteLine(" file Name OK")
End If
Next

If prtFileExists Then
lw.WriteLine("")
lw.WriteLine("one or more part file names already exist, journal exiting")
Return
End If

'create new components
For Each temp As KeyValuePair(Of String, Curve) In newFileNames
CreateNewComponent({temp.Value}, IO.Path.Combine(parentFolder, temp.Key & ".prt"), theSession.Parts.Display.PartUnits)
Next

'save the display part (the assembly)
Dim theSaveStatus As PartSaveStatus
theSaveStatus = theSession.Parts.Display.Save(BasePart.SaveComponents.True, False)

lw.Close()

End Sub

Sub CreateNewComponent(ByVal objects() As DisplayableObject, ByVal fileName As String, ByVal units As Part.Units)

Dim fileNew1 As FileNew
fileNew1 = theSession.Parts.FileNew()

'if using your template, change to False
fileNew1.UseBlankTemplate = True

If units = Part.Units.Inches Then
'change to your desired template
'fileNew1.TemplateFileName = "C:\NX\templates\NX9_templates\model-plain-1-inch-template.prt"
fileNew1.Units = Part.Units.Inches

fileNew1.TemplateFileName = "Blank"

Else
'change to your desired template
'fileNew1.TemplateFileName = "C:\NX\templates\NX9_templates\model-plain-1-mm-template.prt"
fileNew1.Units = Part.Units.Millimeters

fileNew1.TemplateFileName = "Blank"

End If

fileNew1.ApplicationName = "GatewayTemplate"
'fileNew1.ApplicationName = "ModelTemplate"

fileNew1.RelationType = ""

fileNew1.UsesMasterModel = "No"

fileNew1.TemplateType = FileNewTemplateType.Item

fileNew1.NewFileName = fileName

fileNew1.MasterFileName = ""

fileNew1.MakeDisplayedPart = False

Dim createNewComponentBuilder1 As Assemblies.CreateNewComponentBuilder
createNewComponentBuilder1 = theSession.Parts.Work.AssemblyManager.CreateNewComponentBuilder()

createNewComponentBuilder1.LayerOption = Assemblies.CreateNewComponentBuilder.ComponentLayerOptionType.AsSpecified

createNewComponentBuilder1.DefiningObjectsAdded = False

Dim added1 As Boolean
added1 = createNewComponentBuilder1.ObjectForNewComponent.Add(objects)

createNewComponentBuilder1.ComponentOrigin = Assemblies.CreateNewComponentBuilder.ComponentOriginType.Absolute

createNewComponentBuilder1.NewFile = fileNew1

createNewComponentBuilder1.ReferenceSet = createNewComponentBuilder1.ComponentReferenceSetType.EntirePartOnly
createNewComponentBuilder1.ReferenceSetName = "Entire Part"

Dim nXObject2 As NXObject
nXObject2 = createNewComponentBuilder1.Commit()

createNewComponentBuilder1.Destroy()

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

'Unloads the image immediately after execution within NX
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately

End Function

End Module

NXJ, First, my apologies for not replying sooner. As for the code you provided, this was fantastic! So far I have only tried it some smaller assemblies, but it has worked great. As I had mentioned earlier in the post, I am very new to this, so this was a great help! I did notice in VB that VB says there is an error (Line 114 Col 21)I am not sure of the error, but learning as I go. Will try to keep the post informed and hopefully update as I go on.

Thanks again!
Markp

Depending on the version of NX that you are using, it may not like the {temp.Value} notation. The use of the curly braces is a shortcut way to create an array out of a single variable (the subroutine expects an array, but we want to pass in a single value). Recent versions of NX which use the newer .net framework libraries allow this notation, older versions do not. If your version of NX does not like the notation, you can create an array of the proper type, assign the temp.Value to the array, and pass in the array.

Hi,

Did you have the same code for unparametrized bodies in a part ?

Thanks in advance

Regards

Didier