Change Hole Color

When run, the following script will change the color of the face of simple holes to blue (color 211), and threaded holes to yellow (color 6). The journal has been tested with NX 7.5.

 

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Features
 
Module HoleColours
 
Sub Main()
 
  Dim s As Session = Session.GetSession()
  Dim ufs As UFSession = UFSession.GetUFSession()
  Dim dp As Part = s.Parts.Work
  Dim expstring As String = Nothing
  Dim index2 As Integer = -1
  Dim exps() As Expression
  Dim holewiththread As Boolean = False
  Dim holeexpstring As String = "Threaded"
  Dim hole As BodyFeature
  Dim faces() As Face
  Dim nFaces As Integer = 0
  Dim obj(-1) As DisplayableObject
  Dim displayModification1 As DisplayModification
  Dim featcoll As FeatureCollection = dp.Features
 
  For Each f As Feature In featcoll
 
    If f.FeatureType = "SIMPLE HOLE" Then
      holewiththread = False
      exps = f.GetExpressions()
      index2 = exps(0).Description.IndexOf(holeexpstring)
 
      If index2 > 0 Then
        holewiththread = True
      End If
 
      If holewiththread = True Then
        hole = DirectCast(f, BodyFeature)
        faces = hole.GetFaces()
        nFaces = faces.Length
        ReDim obj(nFaces - 1)
 
        For i As Integer = 0 To nFaces - 1
          obj(i) = faces(i)
        Next
 
        displayModification1 = s.DisplayManager.NewDisplayModification()
        displayModification1.ApplyToAllFaces = False
        displayModification1.NewColor = 6
        displayModification1.Apply(obj)
 
      Else 'holewiththread is false
 
        hole = DirectCast(f, BodyFeature)
        faces = hole.GetFaces()
        nFaces = faces.Length
        ReDim obj(nFaces - 1)
 
        For i As Integer = 0 To nFaces - 1
          obj(i) = faces(i)
        Next
 
        displayModification1 = s.DisplayManager.NewDisplayModification()
        displayModification1.ApplyToAllFaces = False
        displayModification1.NewColor = 211
        displayModification1.Apply(obj)
 
      End If
    End If
  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

Comments

I have painted Holes, chamfers, blends, pockets, subtracted faces etc. But with one feature I have a problem. I am using NX 7.5, and for shells:
shell = DirectCast(f, Shell)
we don't have a method faces = shell.GetFaces()
there is a class ShellFace but I can't figure out how to use it.
Any ideas?

Oddly, the NX7.5 documentation doesn't show the .GetFaces method for the Shell class, but the NX8 documentation does (and it notes it was added in NX3). Perhaps it is just an error in the documentation. Try to use the .GetFaces method and see what happens.

If you are still having problems, email your code to info@nxjournaling.com

I cannot build the solution with the GetFaces() method. From Siemens NX Forum I know that in NX8
shell can be casted to BodyFeature class which contains GetFaces() method, but it also doesn't work under NX7.5. I will send my code to nxjournaling. Thanks for helping me.

The Shell.GetFaces method seems to be broken in NX7.5. I would suggest you log a call with GTAC to report it; they are the only ones who are able to fix it.

How would i get this to work for counterbored and counter sunk holes as well?

Instead of looking for a feature type of "SIMPLE HOLE", you will want to look for "CBORE_HOLE" or "CSUNK_HOLE" as desired.

stil i am not getting indexof ?
index of simplehole(i.e.=-1) & index of threaded(i.e.=1) are they fixed ?

IndexOf is a string method. It searches for a substring within a string; if the substring is found, it will return the start position in the main string where the substring was found. If the substring cannot be found in the main string, it will return the value: -1. As an alternative, we could have used the string.Contains() method.

For some string code examples, see:
http://www.dotnetperls.com/indexof-vbnet

In this journal we are looking for the word "Threaded" within the expression description. If the return value is -1, we are dealing with a hole; if the return value is >= 0, we are dealing with a threaded hole.

thanks..got it.

Is there a way to find out if a cylindrical face has thread?
We have many holes created by subtracted linked bodies, with thread.
Or can we find out the cylindrical face attached into symbolic thread?

I have found this in the nx.net reference, but I cannot make it work (in vb):
-----
UF_MODL_symb_thread_data_s
Also known as:
UF_MODL_symb_thread_data_t
UF_MODL_symb_thread_data_p_t

Overview

This structure is used in creating and inquiring symbolic threads.

Data Members

cyl_face

tag_t

Cylindrical face to be threaded.
etc.
-------

-------
kukelyk

The following code will look for symbolic thread features in your work part. If/when one if found, it will assign the 'thread callout' as the name of the cylindrical face. Hopefully, it will serve as a starting point for your needs.

Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
 
Module Module1
 
    Sub Main()
 
        Dim theSession As Session = Session.GetSession()
        Dim theUfSession As UFSession = UFSession.GetUFSession()
        Dim workPart As Part = theSession.Parts.Work
        Dim lw As ListingWindow = theSession.ListingWindow
        lw.Open()
 
        Dim threadFeatures As New List(Of Features.Feature)
 
        For Each myFeature As Features.Feature In workPart.Features
            If myFeature.FeatureType.ToUpper = "SYMBOLIC_THREAD" Then
                threadFeatures.Add(myFeature)
            End If
        Next
 
        Dim myThreadParameters As UFModl.SymbThreadData
        For Each myFeature As Features.Feature In threadFeatures
 
            theUfSession.Modl.AskSymbThreadParms(myFeature.Tag, myThreadParameters)
            Dim threadedFace As Face
            threadedFace = Utilities.NXObjectManager.Get(myThreadParameters.cyl_face)
            'if you highlight the face with the following line, you must remove the highlighting
            'with the part cleanup -> remove extraneous highlighting command
            'threadedFace.Highlight()
 
            'apply thread callout as face name
            threadedFace.SetName(myThreadParameters.callout)
 
            'change preferences to show names in work view
            workPart.Preferences.NamesBorderVisualization.ObjectNameDisplay = Preferences.PartVisualizationNamesBorders.NameDisplay.WorkView
 
        Next
 
 
 
        lw.Close()
 
    End Sub
 
 
    Public Function GetUnloadOption(ByVal dummy As String) As Integer
 
        'Unloads the image when the NX session terminates
        GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination
 
        '----Other unload options-------
        'Unloads the image immediately after execution within NX
        'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
 
        'Unloads the image explicitly, via an unload dialog
        'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Explicitly
        '-------------------------------
 
    End Function
 
End Module

Thanks for Your response. Unfortunately I had no time dealing with it. I tried it, it works fine, but.
I added only this:

theUfSession.Obj.SetColor(threadedFace.Tag, 100)

to the journal.
If I run the journal, it makes everything well, but if I delete a thread feature, the callout remains displayed. I have never used (and have not known) callout. Could You please give some more help?

-------
kukelyk

The following code will run through the part and remove any custom names from faces before looking for symbolic threads. The code will then assign the thread callout as the name of the threaded face.

If you assign custom names to other faces in the file, the code will need to be modified to avoid removing those...

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 workPart As Part = theSession.Parts.Work
    Dim lw As ListingWindow = theSession.ListingWindow
 
    Sub Main()
 
        lw.Open()
 
        RemoveNames()
 
        Dim threadFeatures As New List(Of Features.Feature)
        Dim threadFaces As New List(Of Face)
 
        For Each myFeature As Features.Feature In workPart.Features
            If myFeature.FeatureType.ToUpper = "SYMBOLIC_THREAD" Then
                threadFeatures.Add(myFeature)
            End If
        Next
 
        Dim myThreadParameters As UFModl.SymbThreadData
        For Each myFeature As Features.Feature In threadFeatures
 
            theUfSession.Modl.AskSymbThreadParms(myFeature.Tag, myThreadParameters)
            Dim threadedFace As Face
            threadedFace = Utilities.NXObjectManager.Get(myThreadParameters.cyl_face)
            'if you highlight the face with the following line, you must remove the highlighting
            'with the part cleanup -> remove extraneous highlighting command
            'threadedFace.Highlight()
 
            threadFaces.Add(threadedFace)
 
            'apply thread callout as face name
            threadedFace.SetName(myThreadParameters.callout)
 
        Next
 
        'change preferences to show names in work view
        workPart.Preferences.NamesBorderVisualization.ObjectNameDisplay = Preferences.PartVisualizationNamesBorders.NameDisplay.WorkView
 
        lw.Close()
 
    End Sub
 
    Sub RemoveNames()
 
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Start")
 
        Dim tFaces() As Face
 
        For Each tBody As Body In workPart.Bodies
            tFaces = tBody.GetFaces
 
            For Each tFace As Face In tFaces
                tFace.SetName("")
            Next
            Array.Clear(tFaces, 0, tFaces.Length)
        Next
 
        theSession.UpdateManager.DoUpdate(markId1)
 
    End Sub
 
End Module

I have created an application which paints every machined face of a model. It paints all feature faces (and each subtract)
which removes a material from a model. It works very good. But there is one condition: it only works for 1 part.
When I use this app on the assembly, where I have "PROMOTED" or "LINKED" bodies and added some features it changes the colors, But it is no permanent. When I save, close and reopen the assembly all changes are gone.

Can somebody give me some advice how can I keep the new colors permanently?

In the "Edit Object Display" dialog box, in the "settings" section, there is an option: "Apply changes to owning part"; in your assembly, change the color of a face of a component with this option set. Save your parts, close them, and reopen to see if the change 'stuck'. If it works, record a journal of the actions to see what code you need to change/add.

I would like to change in my part color of holes but only holes e.g. dia. 11. Anybody can give me advice how to do it?

What version of NX are you using?
Are you working with a parameterized file (a native NX file with hole features) or a dumb solid (imported data or a 'body' object with no features)?

If you are working with a native NX file, you can search through the features for hole features and query the diameter of the hole.

I am using NX10 version and I am working with parameterized file (with hole features).Anybody know what code should be added to on the existing journal ( on the beginning of this post ) ?

Thanks
Marcin

Here is a journal for changing colour for simple holes based on hole diameter. Note you need to edit the code for hole diameter and face colour.

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Features
 
Module HoleColours
    Sub Main()
        Dim s As Session = Session.GetSession()
        Dim ufs As UFSession = UFSession.GetUFSession()
        Dim wp As Part = s.Parts.Work
        Dim exps() As Expression
        Dim holeexpstring As String = "Diameter"
        Dim hole As BodyFeature
        Dim faces() As Face
        Dim nFaces As Integer = 0
        Dim obj(-1) As DisplayableObject
        Dim displayModification1 As DisplayModification
        Dim featcoll As FeatureCollection = wp.Features
        Dim holedia As Double = Nothing
        Dim facecolour As Integer = 3
        Dim holediachange As Double = 1.0
        For Each f As Feature In featcoll
            If f.FeatureType = "SIMPLE HOLE" Then
                hole = DirectCast(f, BodyFeature)
                exps = f.GetExpressions()
                For Each exp1 As Expression In exps
                    If exp1.Description.Contains(holeexpstring) Then
                        holedia = exp1.Value
                    End If
                Next
                If holedia = holediachange Then
                    faces = hole.GetFaces()
                    nFaces = faces.Length
                    ReDim obj(nFaces - 1)
                    For i As Integer = 0 To nFaces - 1
                        obj(i) = faces(i)
                    Next
                End If
                displayModification1 = s.DisplayManager.NewDisplayModification()
                displayModification1.ApplyToAllFaces = False
                displayModification1.NewColor = facecolour
                displayModification1.Apply(obj)
            End If
        Next
    End Sub
End Module<code>
 
Frank Swinkels

I would like to add on last Frank journal, code which change color e.g. G1/8" thread. I tried to do it base on "hole color" journel it means instead of "SIMPLE HOLE" feature typ add "THREADED HOLE" feature - is it correct value? Maybe should be "THREADED_HOLE" or "THREAD". Where can I find correct "FeatureType" name? - for simple hole is SIMPLE HOLE; for Counterbored hole is CBORE_HOLE; for Countersunk hole is CSUNK_HOLE; where I can find the others (e.g. threaded hole)?.
Anyway in
 Dim holeexpstring As String = "Thread Size" ' Instead of "Diameter"
and
Dim holediachange As Double = G 1-8 ' Instead of e.g. 1.0
but G1/8 can not be "Double" so I changed it on String Dim holediachange As String = "G 1-8"
I feel that it is not correct way.
Frank any idea?
I use NX10 version and I am working with parameterized files.

Thanks
Marcin

Are you specifying the thread in the "hole" feature? If so, you can look for "hole package" type features in the feature collection and query the thread type from the feature.

If you are using the "thread" feature to add the thread to an existing hole or boss, you will need to look for the corresponding feature type in the collection.

I can't seem to find a reference to a G1/8" thread anywhere. What thread standard does it belong to? Or is this a custom thread that you have added to your NX install?

To be honest I forgot that G1/8" thread is not standard NX thread in custom NX installation. G threads were added in my NX installation. OK, forget about the thread G - instead of this kind of thread use M8 standard metric thread. Mayby this is reason why my scribble not working. Anyway I use "hole" feature where I chose thread holes (metric or inch standard).
So you suggest as below (basic on last Frank "hole color" journal):

  Dim holeexpstring As String = "Thread Size"
  Dim holediachange As String = "M8"
  Dim holedia As Double = Nothing
 
For Each f As Feature In featcoll
            If f.FeatureType = "HOLE PACKAGE" Then
                hole = DirectCast(f, BodyFeature)
                exps = f.GetExpressions()
                For Each exp1 As Expression In exps
                    If exp1.Description.Contains(holeexpstring) Then
                        holedia = exp1.Value
                    End If
                Next
                If holedia = holediachange Then
                    faces = hole.GetFaces()
                    nFaces = faces.Length
                    ReDim obj(nFaces - 1)
                    For i As Integer = 0 To nFaces - 1
                        obj(i) = faces(i)
                    Next
                End If
                displayModification1 = s.DisplayManager.NewDisplayModification()
                displayModification1.ApplyToAllFaces = False
                displayModification1.NewColor = facecolour
                displayModification1.Apply(obj)
            End If
        Next

If you find a "HOLE PACKAGE" feature, you can use the appropriate builder object to see if the hole is threaded and if so what the thread size is. If the hole/thread is the size that you are looking for, you can get the hole faces and change their color.

Option Strict Off
Imports System
Imports NXOpen
 
Module change_hole_color_2
 
    Sub Main()
 
        Dim theSession As Session = Session.GetSession()
        If IsNothing(theSession.Parts.Work) Then
            'active part required
            Return
        End If
 
        Dim workPart As Part = theSession.Parts.Work
        Dim lw As ListingWindow = theSession.ListingWindow
        lw.Open()
 
        Const undoMarkName As String = "change hole color"
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)
 
        'Const holeColor As Integer = 211
        Const holeThreadedColor As Integer = 6
        Dim newColor As Integer
 
        For Each theFeature As Features.Feature In workPart.Features
 
            If TypeOf (theFeature) Is NXOpen.Features.HolePackage Then
                Dim theHolePackageBuilder As Features.HolePackageBuilder = workPart.Features.CreateHolePackageBuilder(theFeature)
 
                If theHolePackageBuilder.Type = Features.HolePackageBuilder.Types.ThreadedHole Then
                    newColor = holeThreadedColor
                    'lw.WriteLine("thread size: " & theHolePackageBuilder.ThreadSize)
                    'lw.WriteLine("thread standard: " & theHolePackageBuilder.ThreadStandard)
                    If theHolePackageBuilder.ThreadSize.Contains("M8") Then
 
                        Dim displayModification1 As DisplayModification
                        displayModification1 = theSession.DisplayManager.NewDisplayModification()
                        displayModification1.ApplyToAllFaces = False
                        displayModification1.NewColor = newColor
                        displayModification1.Apply(CType(theFeature, Features.HolePackage).GetFaces)
                        displayModification1.Dispose()
 
                    End If
                End If
 
                theHolePackageBuilder.Destroy()
 
 
            End If
 
        Next
 
 
        lw.Close()
 
    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

Below journal which recognizes holes dia.8, 10 11, 11.5; C'bore holes dia.10, 12, 14 and thread holes M3, M6, M8 and changes their colors face - written on the basic on your code. I am happy with myself because I am learning slowly read VB.NET reference guide (net_ref.chm file). I put it because maybe someone come in handy.

Option Strict Off
Imports System
Imports NXOpen
 
Module change_hole_color
 
  Sub Main()
 
        Dim theSession As Session = Session.GetSession()
        If IsNothing(theSession.Parts.Work) Then
            'active part required
            Return
        End If
 
        Dim workPart As Part = theSession.Parts.Work
        Dim lw As ListingWindow = theSession.ListingWindow
 
        lw.Open()
 
        Const undoMarkName As String = "change hole color"
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)
 
        Const holeColor As Integer = 211
        Const holeThreadedColor As Integer = 6
        Dim newColor As Integer
        Dim holedia() As Double = {8,10,11,11.5}
        Dim cboredia() As Double = {10,12,14}
 
        For Each theFeature As Features.Feature In workPart.Features
 
            If theFeature.FeatureType = "HOLE PACKAGE" Then
            'If TypeOf (theFeature) Is NXOpen.Features.HolePackage Then
                Dim theHolePackageBuilder As Features.HolePackageBuilder = workPart.Features.CreateHolePackageBuilder(theFeature)
 
                If theHolePackageBuilder.Type = Features.HolePackageBuilder.Types.GeneralHole Then
                 newColor = holeColor
                'lw.WriteLine("Diameter: " & theHolePackageBuilder.GeneralSimpleHoleDiameter.Value)
                'lw.WriteLine("Counter Bore Diameter: " & theHolePackageBuilder.GeneralCounterboreDiameter.Value)
 
                For i As Integer = 0 To holedia.GetUpperBound(0)
                For j As Integer = 0 To cboredia.GetUpperBound(0)
                If theHolePackageBuilder.GeneralSimpleHoleDiameter.Value = holedia(i) or theHolePackageBuilder.GeneralCounterboreDiameter.Value = cboredia(j) Then
 
               Dim displayModification1 As DisplayModification
               displayModification1 = theSession.DisplayManager.NewDisplayModification()
               displayModification1.ApplyToAllFaces = False
               displayModification1.NewColor = newColor
               displayModification1.Apply(CType(theFeature, Features.HolePackage).GetFaces)
               displayModification1.Dispose()
 
             End If
             Next
             Next
           End if			
 
           If theHolePackageBuilder.Type = Features.HolePackageBuilder.Types.ThreadedHole Then
 
           newColor = holeThreadedColor
               'lw.WriteLine("thread size: " & theHolePackageBuilder.ThreadSize)
               'lw.WriteLine("thread standard: " & theHolePackageBuilder.ThreadStandard)
               If theHolePackageBuilder.ThreadSize.Contains("M3") or theHolePackageBuilder.ThreadSize.Contains("M6") or theHolePackageBuilder.ThreadSize.Contains("M8") Then
 
	Dim displayModification1 As DisplayModification
               displayModification1 = theSession.DisplayManager.NewDisplayModification()
               displayModification1.ApplyToAllFaces = False
               displayModification1.NewColor = newColor
               displayModification1.Apply(CType(theFeature, Features.HolePackage).GetFaces)
               displayModification1.Dispose()
 
	 End If
           End if			
	           theHolePackageBuilder.Destroy()
       End If
 
        Next
 
        lw.Close()
 
    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