WAVE "Hole Packaging" features geometry linker

Hello,

I would like to Link all simple hole, c'bore hole and thread hole features for all parts in my assembly / sub-assembly to one part. Structure as below:

Assembly
- part 1
- part 2
- part 3 -> for this part I would like to link simple hole futures)
- part n
+ Sub-assembly 1
- part 1.1
- part 1.2

- part 1.n
+ Sub-assembly 2
- part 2.1
- part 2.2

- part 2.n

I have simple code to find features which I would like to link but to I am not sure if it is good way.
On the end of this code is what I recorded .

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI

Module NXJournal
Sub Main (ByVal args() As String)

Dim theSession As NXOpen.Session = NXOpen.Session.GetSession()
Dim workPart As NXOpen.Part = theSession.Parts.Work
Dim displayPart As NXOpen.Part = theSession.Parts.Display
Dim theUISession As UI = UI.GetUI
Dim lw As ListingWindow = theSession.ListingWindow

lw.Open()

Const undoMarkName As String = "WAVE Face geometry linker"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

Dim HoleDiameter1 As String
Dim i As Integer = 0
Dim SimpleHoleCounter As Integer = 0

Do
HoleDiameter1 = UCase(NXInputBox.GetInputString("Enter hole diameter :", "Hole diameter", " "))

If HoleDiameter1 = "" Then Exit Sub
Loop Until HoleDiameter1.Trim.Length > 0

For Each theFeature As Features.Feature In workPart.Features
If theFeature.FeatureType = "HOLE PACKAGE" Then
Dim theHolePackageBuilder As Features.HolePackageBuilder = workPart.Features.CreateHolePackageBuilder(theFeature)

'*********** SimpleHole *****************

if IsNumeric(HoleDiameter1)= true then

If theHolePackageBuilder.Type = Features.HolePackageBuilder.Types.GeneralHole Then

'lw.WriteLine("Diameter: " & theHolePackageBuilder.GeneralSimpleHoleDiameter.Value)
'lw.WriteLine("Counter Bore Diameter: " & theHolePackageBuilder.GeneralCounterboreDiameter.Value)

If theHolePackageBuilder.GeneralSimpleHoleDiameter.Value = HoleDiameter1 Then
'----------------------------------------
' how to correctly call the Wavelink function?
' WaveLink(theHolePackageBuilder.GeneralSimpleHoleDiameter.Value)
'----------------------------------------------
SimpleHoleCounter = i + 1
End If

End if

End if
theHolePackageBuilder.Destroy()

End if

Next

If SimpleHoleCounter = 0 Then
Dim msg As String
Dim title As String
Dim style As MsgBoxStyle
msg = "Nie znaleziono otworu: " & HoleDiameter1
title = "Brak otworu"
'style = MsgBoxStyle.Information
style = NXMessageBox.DialogType.Information
'MsgBox(msg, style,title)
theUISession.NXMessageBox.Show(msg, style,title)

End if

lw.Close()

End Sub

Sub WaveLink(ByVal face1 As Face)

' ----------------------------------------------
' RECORDED CODE
' ----------------------------------------------
' Menu: Insert->Associative Copy->WAVE Geometry Linker...
' ----------------------------------------------

Dim nullNXOpen_Features_Feature As NXOpen.Features.Feature = Nothing

Dim waveLinkBuilder1 As NXOpen.Features.WaveLinkBuilder
waveLinkBuilder1 = workPart.BaseFeatures.CreateWaveLinkBuilder(nullNXOpen_Features_Feature)

Dim extractFaceBuilder1 As NXOpen.Features.ExtractFaceBuilder
extractFaceBuilder1 = waveLinkBuilder1.ExtractFaceBuilder

extractFaceBuilder1.FaceOption = NXOpen.Features.ExtractFaceBuilder.FaceOptionType.FaceChain
waveLinkBuilder1.Type = NXOpen.Features.WaveLinkBuilder.Types.FaceLink

extractFaceBuilder1.FaceOption = NXOpen.Features.ExtractFaceBuilder.FaceOptionType.SingleFace
extractFaceBuilder1.AngleTolerance = 45.0
extractFaceBuilder1.ParentPart = NXOpen.Features.ExtractFaceBuilder.ParentPartType.OtherPart

extractFaceBuilder1.Associative = True
extractFaceBuilder1.MakePositionIndependent = False
extractFaceBuilder1.FixAtCurrentTimestamp = False
extractFaceBuilder1.HideOriginal = False
extractFaceBuilder1.DeleteHoles = False
extractFaceBuilder1.InheritDisplayProperties = False

Dim selectDisplayableObjectList1 As NXOpen.SelectDisplayableObjectList
selectDisplayableObjectList1 = extractFaceBuilder1.ObjectToExtract

Dim component1 As NXOpen.Assemblies.Component = CType(displayPart.ComponentAssembly.RootComponent.FindObject("COMPONENT 20A2221A00_Pin half 1"), NXOpen.Assemblies.Component)

Dim component2 As NXOpen.Assemblies.Component = CType(component1.FindObject("COMPONENT 20A2221A05_bottom pin half 1"), NXOpen.Assemblies.Component)

Dim face1 As NXOpen.Face = CType(component2.FindObject("PROTO#.Features|SIMPLE HOLE(72:1A)|FACE 3 {(-68.7852138422798,-188.893381229,98.1684051732037) EXTRUDE(2)}"), NXOpen.Face)

Dim added1 As Boolean
added1 = selectDisplayableObjectList1.Add(face1)

Dim nXObject1 As NXOpen.NXObject
nXObject1 = waveLinkBuilder1.Commit()

waveLinkBuilder1.Destroy()

' ----------------------------------------------
' Menu: Tools->Journal->Stop Recording
' ----------------------------------------------

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

Example for "part 3" I make work part and I want to link all "hole package" features for entire assembly to this part. I need to creat journal which will be search the entire assembly / sub-assembly / child sub-assembly and link "hole package" features to make work part.

Could you help me with this code?

I use NX10
Thanks for help.

Marcin

Hi,

Does anyone know how to link "hole package" features for all parts in assembly / sub-assembly to one part?

Thanks for advance.
Marcin

I solved my issue. Below is complete code which I use to link Hole Package features (Simple hole, Threaded hole) and Extrude features.
I am aware that this code is not perfect but working. So if you are going to test / use it please let me know your improved version. Journal link hole diameter which you entered on begining and standard EXTRUDE deep and Threaded hole which you can define inside program. For correct journal operation you have to be in file which name will be contain "water" word e.g. water channels file (as work part).Going further program search the file names in assembly. When file contains "bushing half" or "pin half" names then looking at previously defined features.

To test it you need to have assembly structure as below.

Assembly
- part 1_bushing half
- part 2_bushing half
- water cahnnels -> for this part will be link features

- part n_bushing half

- part 1_pin half
- part 2_pin half

- part n_pin half

I use NX10 so for this version journal was created. Some files which I tested was created in previous NX version and to be honest sometimes working very well but was situation when journal exit with unknow for me failed.

Option Strict Off

Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI
Imports NXOpen.Assemblies

Module WaveGeometryLinker

Dim theSession As NXOpen.Session = NXOpen.Session.GetSession()
Dim workPart As NXOpen.Part = theSession.Parts.Work
Dim displayPart As NXOpen.Part = theSession.Parts.Display
Dim theUISession As UI = UI.GetUI
Dim theUfSession As UFSession = UFSession.GetUFSession

Dim tablica() As String
Dim i As Integer

Dim wyjscie As Boolean

Dim lw As ListingWindow = theSession.ListingWindow
Dim HoleDiaArray() As Double

Sub Main (ByVal args() As String)

If IsNothing(theSession.Parts.Work) Then
'active part required
theUISession.NXMessageBox.Show("Error", NXMessageBox.DialogType.Error, "Active part required")
Return
End If

Dim currentApplication As Integer
theUfSession.UF.AskApplicationModule(currentApplication)

If Not currentApplication = UFConstants.UF_APP_MODELING Then

theUISession.NXMessageBox.Show("Error !!!", NXMessageBox.DialogType.Error, "Journal will be working only in ""MODELING"" module")
Exit Sub

End If

Const undoMarkName As String = "Wave Geometry Linker"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

If Not IO.Path.GetFileNameWithoutExtension(workPart.FullPath).Contains("water") Then

theUISession.NXMessageBox.Show("Error", NXMessageBox.DialogType.Warning, "For the correct journal operation you have to be in "" water channels "" file")
Exit sub
End if

theUfSession.Ui.ExitListingWindow()
lw.Open()

Try

Dim c As ComponentAssembly = displayPart.ComponentAssembly

If Not IsNothing(c.RootComponent) Then

'*** insert code to process 'root component' (assembly file)
Dim answer As String
Dim HoleDia As Double
Dim wyjscie2 As Boolean
Dim j As Integer

Do
answer = NXInputBox.GetInputString("Enter the diameter of hole which you want to link:", "Enter the diameter of hole", " ")

If answer.Contains(".") then answer = replace(answer, ".", ",")

If answer = "" Then Exit Sub 'if cancel exit sub
If not IsNumeric(answer) = true and answer.Trim.Length > 0 then theUISession.NXMessageBox.Show("ERROR", NXMessageBox.DialogType.Warning, "Entered incorrectly value. Try again.")

Loop Until Double.TryParse(answer, HoleDia) and HoleDia > 0

Do
'lw.writeline(HoleDia)
ReDim Preserve HoleDiaArray(j)
HoleDiaArray(j) = HoleDia
answer = NXInputBox.GetInputString("Do you want to enter next hole diameter:", "Enter diameter of next hole", " ")

If answer.Contains(".") then answer = replace(answer, ".", ",")

If not IsNumeric(answer) = true and answer.Trim.Length > 0 then theUISession.NXMessageBox.Show("ERROR", NXMessageBox.DialogType.Warning, "Entered incorrectly value. Try again.")

If answer.Trim.Length > 0 Then
wyjscie2 = false
else
wyjscie2 = true
End If

j = j + 1

If answer = "" Then wyjscie = true 'if cancel exit sub

Loop Until Double.TryParse(answer, HoleDia) and HoleDia > 0 and wyjscie2 = true or wyjscie = true

lw.WriteLine("Assembly: " & c.RootComponent.DisplayName)
lw.writeline("")
'*** end of code to process root component
ReportComponentChildren(c.RootComponent, 0)

lw.writeline("")
lw.writeline("************************* Journal completed *************************")
theUISession.NXMessageBox.Show("Completed", NXMessageBox.DialogType.Information, "Journal completed")

Else
'*** insert code to process piece part
lw.WriteLine("Part has no components")

End If

Catch error1 As Exception
'lw.WriteFullLine(" Failed: " & error1.ToString)
lw.WriteFullLine(" Failed: " & error1.Message)

End Try

lw.Close()
lw.SelectDevice(ListingWindow.DeviceType.Window, "")

End Sub

'**********************************************************

Sub ReportComponentChildren( ByVal comp As Component, ByVal indent As Integer)

Dim ExtrudeDeep() As String = {"1.6", "3", "3+1.6", "3+9", "9+3", "8", "9", "9.5"} 'enter standard deep of EXTRUDE features which will be always linked
Dim Thread() As String = {"G 1-8", "G 1-4", "G 3-8", "G 1-2", "G 3-4", "G 1", "1/2-NPT", "M5 x 0.8", "M6 x 1.0", "M8 x 1.25"} 'enter standard THREAD features which will be always linked

Dim SimpleHoleCounter As Integer = 0

For Each child As Component In comp.GetChildren()

ReDim Preserve tablica(i)
tablica(i) = child.DisplayName()

Dim j As Integer = Array.IndexOf(tablica, child.DisplayName.ToString)

If i = j then

Dim part1 As Part = child.Prototype.OwningPart

lw.WriteLine(New String("- ", indent * 1) & "Searching features in file: " & child.DisplayName())

If child.DisplayName.Contains("bushing half") or child.DisplayName.Contains("pin half") Then

If IsNothing(child.Prototype.OwningPart) Then
lw.writeline("")
lw.writeline(New String("!", indent * 6) & " Failed: File """& child.DisplayName & """ is not loaded !!!" )
lw.writeline("")

Else

If child.IsSuppressed = False then

If part1.IsFullyLoaded Then
'component is fully loaded
'lw.writeline(New String(" ", indent * 4) & "component: " & child.journalIdentifier & " is Fully Loaded")

Else

'component is partially loaded
lw.writeline(New String(" ", indent * 6) & "Loading component: """ & child.DisplayName() & """ to memory ")
lw.writeline("")

Try

Dim markId2 As NXOpen.Session.UndoMarkId
markId2 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Open Component Fully")
Dim option1 As Boolean
option1 = theSession.Parts.LoadOptions.UsePartialLoading

theSession.Parts.LoadOptions.UsePartialLoading = False
Dim componentsToOpen1(0) As NXOpen.Assemblies.Component
Dim component3 As NXOpen.Assemblies.Component = child.OwningComponent
Dim component4 As NXOpen.Assemblies.Component = CType(component3.FindObject(child.journalIdentifier), NXOpen.Assemblies.Component)
componentsToOpen1(0) = component4

Dim openStatus1() As NXOpen.Assemblies.ComponentAssembly.OpenComponentStatus
Dim partLoadStatus1 As NXOpen.PartLoadStatus

partLoadStatus1 = displayPart.ComponentAssembly.OpenComponents(NXOpen.Assemblies.ComponentAssembly.OpenOption.ComponentOnly, componentsToOpen1, openStatus1)

lw.open()
theSession.Parts.LoadOptions.UsePartialLoading = True

partLoadStatus1.Dispose()
theSession.DeleteUndoMark(markId2, Nothing)

Catch error2 As Exception
lw.writeline("")
'lw.WriteFullLine("Part Loaded Failed: " & error2.ToString)
lw.WriteFullLine("Part Loaded Failed: " & error2.Message)
lw.writeline("")

End Try

End If

For Each theFeature As Features.Feature In Part1.Features

Dim nullNXOpen_Features_Feature As NXOpen.Features.Feature = Nothing

Dim waveLinkBuilder1 As NXOpen.Features.WaveLinkBuilder
waveLinkBuilder1 = displayPart.BaseFeatures.CreateWaveLinkBuilder(nullNXOpen_Features_Feature)

Dim extractFaceBuilder1 As NXOpen.Features.ExtractFaceBuilder
extractFaceBuilder1 = waveLinkBuilder1.ExtractFaceBuilder

extractFaceBuilder1.FaceOption = NXOpen.Features.ExtractFaceBuilder.FaceOptionType.FaceChain

waveLinkBuilder1.Type = NXOpen.Features.WaveLinkBuilder.Types.FaceLink

extractFaceBuilder1.FaceOption = NXOpen.Features.ExtractFaceBuilder.FaceOptionType.FaceChain

extractFaceBuilder1.FeatureOption = NXOpen.Features.ExtractFaceBuilder.FeatureOptionType.SeparateFeatureForEachBody

extractFaceBuilder1.ParentPart = NXOpen.Features.ExtractFaceBuilder.ParentPartType.OtherPart

extractFaceBuilder1.Associative = True

extractFaceBuilder1.MakePositionIndependent = False

extractFaceBuilder1.FixAtCurrentTimestamp = False

extractFaceBuilder1.HideOriginal = False

extractFaceBuilder1.DeleteHoles = False

extractFaceBuilder1.InheritDisplayProperties = False

Dim selectDisplayableObjectList1 As NXOpen.SelectDisplayableObjectList
selectDisplayableObjectList1 = extractFaceBuilder1.ObjectToExtract

Dim component1 As NXOpen.Assemblies.Component = child.OwningComponent
Dim component2 As NXOpen.Assemblies.Component = CType(component1.FindObject(child.journalIdentifier), NXOpen.Assemblies.Component)

If theFeature.FeatureType = "HOLE PACKAGE" Then

Try
Dim theHolePackageBuilder As Features.HolePackageBuilder = displayPart.Features.CreateHolePackageBuilder(theFeature)

If theHolePackageBuilder.Type = Features.HolePackageBuilder.Types.GeneralHole Then

'*********** SimpleHole *****************

Dim CurrentHoleDiaArray As Integer = Array.IndexOf(HoleDiaArray, theHolePackageBuilder.GeneralSimpleHoleDiameter.Value)

If CurrentHoleDiaArray > = 0 Then
If theHolePackageBuilder.GeneralSimpleHoleDiameter.Value = HoleDiaArray(CurrentHoleDiaArray) Then

If Not theFeature.Suppressed = true Then

Dim features1(0) As NXOpen.Features.Feature

Dim holePackage1 As NXOpen.Features.HolePackage = CType(part1.Features.FindObject(theFeature.journalIdentifier), NXOpen.Features.HolePackage)
features1(0) = holePackage1

Dim faceFeatureRule1 As NXOpen.FaceFeatureRule
faceFeatureRule1 = workPart.ScRuleFactory.CreateRuleFaceFeature(features1, component2)

Dim rules1(0) As NXOpen.SelectionIntentRule
rules1(0) = faceFeatureRule1
extractFaceBuilder1.FaceChain.ReplaceRules(rules1, False)

Try

Dim nXObject1 As NXOpen.NXObject
nXObject1 = waveLinkBuilder1.Commit()

Catch error2 As Exception
lw.writeline("")
lw.WriteFullLine("Simple Hole WAVE Geometry Linker Failed: " & error2.Message)
'lw.WriteFullLine("Simple Hole WAVE Geometry Linker Failed: " & error2.ToString)
lw.WriteLine("Simple Hole Diameter: " & theHolePackageBuilder.GeneralSimpleHoleDiameter.Value)
lw.writeline("NAME OF Simple Hole feature: " & theFeature.journalIdentifier)
lw.writeline("")

End Try

waveLinkBuilder1.Destroy()
Else

'lw.writeline(" SUPPRESSED FEATURE: " & theFeature.journalIdentifier & " !!!")

End If

End If

End If

End If

'*********** Threaded Hole *****************

If theHolePackageBuilder.Type = Features.HolePackageBuilder.Types.ThreadedHole Then

Dim CurrentThread As String = Array.IndexOf(Thread, theHolePackageBuilder.ThreadSize)

If CurrentThread > = 0 Then

If theHolePackageBuilder.ThreadSize = Thread(CurrentThread) Then

If Not theFeature.Suppressed = true Then
Dim features1(0) As NXOpen.Features.Feature
Dim holePackage1 As NXOpen.Features.HolePackage = CType(part1.Features.FindObject(theFeature.journalIdentifier), NXOpen.Features.HolePackage)
features1(0) = holePackage1

Dim faceFeatureRule1 As NXOpen.FaceFeatureRule
faceFeatureRule1 = workPart.ScRuleFactory.CreateRuleFaceFeature(features1, component2)

Dim rules1(0) As NXOpen.SelectionIntentRule
rules1(0) = faceFeatureRule1
extractFaceBuilder1.FaceChain.ReplaceRules(rules1, False)

Try

Dim nXObject1 As NXOpen.NXObject
nXObject1 = waveLinkBuilder1.Commit()

Catch error3 As Exception
lw.writeline("")
'lw.WriteFullLine("Threaded Hole WAVE Geometry Linker Failed: " & error3.ToString)
lw.WriteFullLine("Threaded Hole WAVE Geometry Linker Failed: " & error3.Message)
lw.WriteLine("thread size: " & theHolePackageBuilder.ThreadSize)
lw.WriteLine("thread standard: " & theHolePackageBuilder.ThreadStandard)
lw.writeline("NAME OF Threaded Hole feature: " & theFeature.journalIdentifier)
lw.writeline("")

End Try

waveLinkBuilder1.Destroy()
Else
'lw.writeline(" SUPPRESSED FEATURE: " & theFeature.journalIdentifier & " !!!")
End If

End If

End If

End If

theHolePackageBuilder.Destroy()

Catch error5 as exception
lw.writeline("")
'lw.WriteFullLine(" Failed: " & error5.ToString )
lw.WriteFullLine(" Failed: " & error5.Message )
lw.writeline(" Name of feature: " & theFeature.journalIdentifier)
lw.writeline("")
End Try

End if

'*********** Extrude *****************

If theFeature.FeatureType = "EXTRUDE" Then

If Not theFeature.Suppressed = true Then

Dim extrudeBuilder1 As Features.ExtrudeBuilder
extrudeBuilder1 = displayPart.Features.CreateExtrudeBuilder(theFeature)

Dim CurrentExtrudeDeep As String = Array.IndexOf(ExtrudeDeep, extrudeBuilder1.Limits.EndExtend.Value.RightHandSide)

If CurrentExtrudeDeep > = 0 Then

If extrudeBuilder1.Limits.EndExtend.Value.RightHandSide = ExtrudeDeep(CurrentExtrudeDeep) Then

Dim features1(0) As NXOpen.Features.Feature

Dim extrude1 As NXOpen.Features.Extrude = CType(part1.Features.FindObject(theFeature.journalIdentifier), NXOpen.Features.Extrude)
features1(0) = extrude1

Dim faceFeatureRule1 As NXOpen.FaceFeatureRule
faceFeatureRule1 = workPart.ScRuleFactory.CreateRuleFaceFeature(features1, component2)

Dim rules1(0) As NXOpen.SelectionIntentRule
rules1(0) = faceFeatureRule1
extractFaceBuilder1.FaceChain.ReplaceRules(rules1, False)

Try

Dim nXObject1 As NXOpen.NXObject
nXObject1 = waveLinkBuilder1.Commit()

Catch error6 As Exception
lw.writeline("")
'lw.WriteFullLine("Extrude WAVE Geometry Linker Failed: " & error6.ToString)
lw.WriteFullLine("Extrude WAVE Geometry Linker Failed: " & error6.Message)
lw.writeline("NAME OF Extrude feature: " & theFeature.journalIdentifier)
lw.writeline("")

End Try

End If

End If

extrudeBuilder1.Destroy()

Else
'lw.writeline(" SUPPRESSED FEATURE: " & theFeature.journalIdentifier & " !!!")

End If

End If

Next

Else
lw.writeline("")
lw.WriteFullLine(New String("!", indent * 6) & " Failed: File """ & child.DisplayName & """ is suppressed !!!" )
lw.writeline("")

End If

End If

If child.GetChildren.Length <> 0 Then
'*** this is a subassembly, add code specific to subassemblies
lw.WriteLine(New String(" ", indent * 2) & "* subassembly with " & child.GetChildren.Length & " components")
lw.writeline("")
'lw.WriteLine(New String(" ", indent * 2) & " + Active Arrangement: " & child.OwningPart.ComponentAssembly.ActiveArrangement.Name)
'*** end of code to process subassembly
Else
'this component has no children (it is a leaf node)
'add any code specific to bottom level components
End If

End If

End If

i = i + 1
reportComponentChildren(child, indent + 1)

Next

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

Thanks
Marcin