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
WAVE "Hole Package" features geometry linker
Hi,
Does anyone know how to link "hole package" features for all parts in assembly / sub-assembly to one part?
Thanks for advance.
Marcin
WAVE "Hole Packaging" features geometry linker
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