Cancel
Showing results for 
Search instead for 
Did you mean: 

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

Genius
Genius
Hello,
I have not read the whole Thread so maybe my answer is not fitting but in NX you have a selection intent rule called "Boss or Pocket Faces" where you select one face of the pocket and NX automatically selects the whole pocket. Maybe this can be helpful here?
Regards,
Josch

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

PLM World Member Valued Contributor PLM World Member Valued Contributor
PLM World Member Valued Contributor

Josch,

 

Do you know if that could be addressed programmatically? I remembered the option, but never had seen anything in the APIs that looked like it followed that function. Hence, the large amounts of code....

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

Genius
Genius
I know that I used other rule before. Please search for "ScRuleFactory" in the API documentation. And then have a look at "CreateRuleFaceBossPocket".
I think you can also record a journal to learn how it is used...
Highlighted

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

PLM World Member Valued Contributor PLM World Member Valued Contributor
PLM World Member Valued Contributor

I'm not familar with the Selection Intent rules. Are they intended to be used as a filter during active selection, or do they act like a collector?

 

I am dealing with an imported step model from a foreign CAD system and need to "convert" holes in the step model to threaded holes that can be recognized by Feature Based Machining. My current process is for the user to select a cylindrical hole face and then I programmatically gather all other cylindrical faces that are the same radius. The user has the option to deselect any of the automatically selected faces to limit the affected holes. I'm then adding face attributes that are used by FBM to each of the selected hole faces. To allow FBM to map the holes in the step model to threaded holes, I need all the faces of the hole to be a specific color. That is what most of this thread has been addressing.

 

Along that line, where in NX are you presented the option to select pocket faces? I've seen some functions allow you to select adjacent faces, but don't recall an option for pocket or boss faces? If I had that info, I would like to do the journal to see if I might make use of it.

 

Thanks!

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

PLM World Member Valued Contributor PLM World Member Valued Contributor
PLM World Member Valued Contributor

The face normal direction returned by AskFaceData seems to do the trick.

 

Any of the faces that are >0 are on the outside and I have skipped them.

 

This is the result:

Capture.JPG

The boss surfaces are no longer affected by my function.

 

I'm going to do some more testing to see what combinations can still get me in trouble. I'm thinking intersecting holes are not going to behave very well.

 

...and here is the code for changing all the selected cylinders associated faces:

    Function SetFaceColor(color As Integer, holeSelected As List(Of NXObject))
        Dim displayModification1 As DisplayModification

        Dim pointx As Double() = New Double(2) {}
        Dim dir As Double() = New Double(2) {}
        Dim box As Double() = New Double(5) {}
        Dim radius As Double
        Dim rad_data As Double
        Dim norm_dir As Integer
        Dim type As Integer = 0

        displayModification1 = theSession.DisplayManager.NewDisplayModification()
        displayModification1.ApplyToAllFaces = False
        displayModification1.NewColor = color

        For i = 0 To holeSelected.Count - 1
            Dim k As Integer = 0
            Dim l As Integer = 0
            Dim adjFaceTag(l) As Tag
            Dim origAdjFacesTag(0) As Tag
            Dim nextAdjFacesTag(0) As Tag
            Dim checkFace As Tag
            Dim done As Boolean
            Dim found As Boolean
            Dim dispObj(k) As DisplayableObject

            dispObj(k) = CType(NXObjectManager.Get(holeSelected(i).Tag), DisplayableObject)
            adjFaceTag(l) = holeSelected(i).Tag
            theUfSession.Modl.AskAdjacFaces(holeSelected(i).Tag, origAdjFacesTag)
            For j = 0 To origAdjFacesTag.Length - 1
                done = False
                checkFace = origAdjFacesTag(j)
                l += 1
                ReDim Preserve adjFaceTag(l)
                adjFaceTag(l) = checkFace
                While Not done
                    theUfSession.Modl.AskAdjacFaces(checkFace, nextAdjFacesTag)
                    If nextAdjFacesTag.Length = 1 Then
                        k += 1
                        ReDim Preserve dispObj(k)
                        dispObj(k) = CType(NXObjectManager.Get(checkFace), DisplayableObject)
                        done = True
                    ElseIf nextAdjFacesTag.Length = 2 Then
                        For n = 0 To 1
                            found = False
                            For m = 0 To adjFaceTag.Length - 1
                                If adjFaceTag(m) = nextAdjFacesTag(n) Then
                                    found = True
                                End If
                            Next
                            If Not found Then
                                theUfSession.Modl.AskFaceData(checkFace, type, pointx, dir, box, radius, rad_data, norm_dir)
                                If norm_dir < 0 Then
                                    k += 1
                                    ReDim Preserve dispObj(k)
                                    dispObj(k) = CType(NXObjectManager.Get(checkFace), DisplayableObject)
                                End If
                                l += 1
                                ReDim Preserve adjFaceTag(l)
                                adjFaceTag(l) = nextAdjFacesTag(n)
                                checkFace = nextAdjFacesTag(n)
                            End If
                        Next
                    Else
                        done = True
                    End If
                End While
            Next
            displayModification1.Apply(dispObj)
        Next
        Return 0
    End Function

 

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

PLM World Member Valued Contributor PLM World Member Valued Contributor
PLM World Member Valued Contributor

Not sure why my code was truncated, here it is again:

    Function SetFaceColor(color As Integer, holeSelected As List(Of NXObject))
        Dim displayModification1 As DisplayModification

        Dim pointx As Double() = New Double(2) {}
        Dim dir As Double() = New Double(2) {}
        Dim box As Double() = New Double(5) {}
        Dim radius As Double
        Dim rad_data As Double
        Dim norm_dir As Integer
        Dim type As Integer = 0

        displayModification1 = theSession.DisplayManager.NewDisplayModification()
        displayModification1.ApplyToAllFaces = False
        displayModification1.NewColor = color

        For i = 0 To holeSelected.Count - 1
            Dim k As Integer = 0
            Dim l As Integer = 0
            Dim adjFaceTag(l) As Tag
            Dim origAdjFacesTag(0) As Tag
            Dim nextAdjFacesTag(0) As Tag
            Dim checkFace As Tag
            Dim done As Boolean
            Dim found As Boolean
            Dim dispObj(k) As DisplayableObject

            dispObj(k) = CType(NXObjectManager.Get(holeSelected(i).Tag), DisplayableObject)
            adjFaceTag(l) = holeSelected(i).Tag
            theUfSession.Modl.AskAdjacFaces(holeSelected(i).Tag, origAdjFacesTag)
            For j = 0 To origAdjFacesTag.Length - 1
                done = False
                checkFace = origAdjFacesTag(j)
                l += 1
                ReDim Preserve adjFaceTag(l)
                adjFaceTag(l) = checkFace
                While Not done
                    theUfSession.Modl.AskAdjacFaces(checkFace, nextAdjFacesTag)
                    If nextAdjFacesTag.Length = 1 Then
                        k += 1
                        ReDim Preserve dispObj(k)
                        dispObj(k) = CType(NXObjectManager.Get(checkFace), DisplayableObject)
                        done = True
                    ElseIf nextAdjFacesTag.Length = 2 Then
                        For n = 0 To 1
                            found = False
                            For m = 0 To adjFaceTag.Length - 1
                                If adjFaceTag(m) = nextAdjFacesTag(n) Then
                                    found = True
                                End If
                            Next
                            If Not found Then
                                theUfSession.Modl.AskFaceData(checkFace, type, pointx, dir, box, radius, rad_data, norm_dir)
                                If norm_dir < 0 Then
                                    k += 1
                                    ReDim Preserve dispObj(k)
                                    dispObj(k) = CType(NXObjectManager.Get(checkFace), DisplayableObject)
                                End If
                                l += 1
                                ReDim Preserve adjFaceTag(l)
                                adjFaceTag(l) = nextAdjFacesTag(n)
                                checkFace = nextAdjFacesTag(n)
                            End If
                        Next
                    Else
                        done = True
                    End If
                End While
            Next
            displayModification1.Apply(dispObj)
        Next
        Return 0
    End Function

 

Thanks for all the help!

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

Gears Esteemed Contributor Gears Esteemed Contributor
Gears Esteemed Contributor

For what it's worth, here is some code that limits the face selection to a potential hole face (blend faces and boss faces will not pass through the selection filter).

 

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

Module Module4

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

    Sub Main()

        If IsNothing(theSession.Parts.BaseWork) 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 = "select hole face journal"
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

        Dim selFace As Face = Nothing
        If SelectHoleFace(selFace) = Selection.Response.Cancel Then
            Return
        End If

        lw.WriteLine("selected face tag: " & selFace.Tag.ToString)

        lw.Close()

    End Sub

    Function IsHoleFace(ByVal cylindricalFace As Face) As Boolean

        'distinguish between a hole face and a boss face
        'hole face: face normal points toward the face axis
        'boss face: face normal points away from the face axis

        'ask face type
        Dim faceType As Integer
        theUfSession.Modl.AskFaceType(cylindricalFace.Tag, faceType)
        Select Case faceType
            Case Is = UFConstants.UF_MODL_CYLINDRICAL_FACE
                'so far, so good
            Case Is = UFConstants.UF_MODL_CONICAL_FACE
                'also Ok
            Case Else
                Return False
        End Select

        'find cylindrical face axis and point on the axis
        Dim axisPt(2) As Double
        Dim axisDir(2) As Double
        Dim bbox(5) As Double
        Dim faceMajorRadius As Double
        Dim faceMinorRadius As Double
        Dim normalDir As Integer
        theUfSession.Modl.AskFaceData(cylindricalFace.Tag, faceType, axisPt, axisDir, bbox, faceMajorRadius, faceMinorRadius, normalDir)
        'lw.WriteLine("normalDir: " & normalDir.ToString)
        '+1 = boss face
        '-1 = hole face

        If normalDir < 0 Then
            Return True
        Else
            Return False
        End If

    End Function

    Public Function SelectHoleFace(ByRef theHoleFace As Face) As Selection.Response

        Dim response As Integer = 0
        Dim user_data As System.IntPtr
        Dim selObj As Tag = Nothing
        Dim myCursor(2) As Double
        Dim myView As Tag = Nothing

        theUfSession.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
        Dim curCursorView As Integer
        theUfSession.Ui.AskCursorView(curCursorView)

        Try
            theUfSession.Ui.SetCursorView(0)
            theUfSession.Ui.SelectWithSingleDialog("Select: ", "Select hole face", _
                UFConstants.UF_UI_SEL_SCOPE_WORK_PART, AddressOf Mask1, _
                user_data, response, selObj, myCursor, myView)
        Finally
            theUfSession.Ui.SetCursorView(curCursorView)
            theUfSession.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
        End Try

        If response = UFConstants.UF_UI_BACK Or response = UFConstants.UF_UI_CANCEL Then
            Return Selection.Response.Cancel
        Else
            If Not selObj.Equals(Tag.Null) Then
                'the SelectWithSingleDialog method returns a tag,
                'return the object from the given tag
                theHoleFace = Utilities.NXObjectManager.Get(selObj)
                theUfSession.Disp.SetHighlight(selObj, 0)
            Else
                'selObj = Tag.Null
                'should not happen
                Return Selection.Response.Cancel
            End If

            Return Selection.Response.Ok
        End If


    End Function

    Public Function Mask1(ByVal select_ As IntPtr, _
                              ByVal userdata As IntPtr) As Integer
        'this function must have the same signature as UFUi.SelInitFnT Delegate

        'setup mask to filter for cylindrical or conical faces
        Dim num_triples As Integer = 2
        Dim mask_triples(num_triples - 1) As UFUi.Mask

        mask_triples(0).object_type = UFConstants.UF_solid_type
        mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_CYLINDRICAL_FACE

        mask_triples(1).object_type = UFConstants.UF_solid_type
        mask_triples(1).solid_type = UFConstants.UF_UI_SEL_FEATURE_CONICAL_FACE

        theUfSession.Ui.SetSelMask(select_, _
                          UFUi.SelMaskAction.SelMaskClearAndEnableSpecific, _
                          num_triples, mask_triples)

        theUfSession.Ui.SetSelProcs(select_, AddressOf Filter1, Nothing, userdata)


        Return UFConstants.UF_UI_SEL_SUCCESS

    End Function

    Public Function Filter1(ByVal _object As Tag, _
                                        ByVal type As Integer(), _
                                        ByVal user_data As IntPtr, _
                                        ByVal select_ As IntPtr) As Integer
        'type, user_data, and select_ are unused, but this function must have
        'the same signature as UFUi.SelFilterFnT Delegate

        Dim tempFace As Face = Utilities.NXObjectManager.Get(_object)

        If IsHoleFace(tempFace) Then
            Return UFConstants.UF_UI_SEL_ACCEPT
        Else
            Return UFConstants.UF_UI_SEL_REJECT
        End If

    End Function

    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

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

PLM World Member Valued Contributor PLM World Member Valued Contributor
PLM World Member Valued Contributor

OK, does anyone know how to post a code listing that won't get truncated at the curly braces?

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

PLM World Member Valued Contributor PLM World Member Valued Contributor
PLM World Member Valued Contributor

Haven't been able to figure out how to get the code to show with a closing curly brace, so took them out. Please realize that Dim pointx, Dim dir, and Dim box actually have a closing curly brace in the actual code.

 

I enclosed the code in a function and now pass in the desired color and list of selected hole cylinders that need all the associated faces colored.

 

I apologize for the lack of comments, too busy trying to get it to work to make polite coding. Please ask if anything doesn't make sense! I also expect there are situations that will not behave entirely as expected, but hope that I will still get functionally enough to make FBM work as required.

 

Anyway, here's the code:

    Function SetFaceColor(color As Integer, holeSelected As List(Of NXObject))
        Dim displayModification1 As DisplayModification

        Dim pointx As Double() = New Double(2) {
        Dim dir As Double() = New Double(2) {
        Dim box As Double() = New Double(5) {
        Dim radius As Double
        Dim rad_data As Double
        Dim norm_dir As Integer
        Dim type As Integer = 0

        displayModification1 = theSession.DisplayManager.NewDisplayModification()
        displayModification1.ApplyToAllFaces = False
        displayModification1.NewColor = color

        For i = 0 To holeSelected.Count - 1
            Dim k As Integer = 0
            Dim l As Integer = 0
            Dim adjFaceTag(l) As Tag
            Dim origAdjFacesTag(0) As Tag
            Dim nextAdjFacesTag(0) As Tag
            Dim checkFace As Tag
            Dim done As Boolean
            Dim found As Boolean
            Dim dispObj(k) As DisplayableObject

            dispObj(k) = CType(NXObjectManager.Get(holeSelected(i).Tag), DisplayableObject)
            adjFaceTag(l) = holeSelected(i).Tag
            theUfSession.Modl.AskAdjacFaces(holeSelected(i).Tag, origAdjFacesTag)
            For j = 0 To origAdjFacesTag.Length - 1
                done = False
                checkFace = origAdjFacesTag(j)
                l += 1
                ReDim Preserve adjFaceTag(l)
                adjFaceTag(l) = checkFace
                While Not done
                    theUfSession.Modl.AskAdjacFaces(checkFace, nextAdjFacesTag)
                    If nextAdjFacesTag.Length = 1 Then
                        k += 1
                        ReDim Preserve dispObj(k)
                        dispObj(k) = CType(NXObjectManager.Get(checkFace), DisplayableObject)
                        done = True
                    ElseIf nextAdjFacesTag.Length = 2 Then
                        For n = 0 To 1
                            found = False
                            For m = 0 To adjFaceTag.Length - 1
                                If adjFaceTag(m) = nextAdjFacesTag(n) Then
                                    found = True
                                End If
                            Next
                            If Not found Then
                                theUfSession.Modl.AskFaceData(checkFace, type, pointx, dir, box, radius, rad_data, norm_dir)
                                If norm_dir < 0 Then
                                    k += 1
                                    ReDim Preserve dispObj(k)
                                    dispObj(k) = CType(NXObjectManager.Get(checkFace), DisplayableObject)
                                End If
                                l += 1
                                ReDim Preserve adjFaceTag(l)
                                adjFaceTag(l) = nextAdjFacesTag(n)
                                checkFace = nextAdjFacesTag(n)
                            End If
                        Next
                    Else
                        done = True
                    End If
                End While
            Next
            displayModification1.Apply(dispObj)
        Next
        Return 0
    End Function

 

Re: Collect Associated Faces of a Selected Cylindrical Face (Rest of the hole faces..)

Genius
Genius

Hi,
I want to add my code with the FaceRules :-)

Option Strict Off
Imports System
Imports NXOpen

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 theFace As Face = select_a_face("Select a Face:")

If theFace Is Nothing Then
Return
End If

Dim theScCollector As ScCollector = workPart.ScCollectors.CreateCollector()
Dim theFaceBossPocketFacesRule As FaceBossPocketFacesRule = workPart.ScRuleFactory.CreateRuleFaceBossPocket(theFace)
Dim theSelectionIntentRules(0) As SelectionIntentRule

Dim theDisplayModification As NXOpen.DisplayModification = theSession.DisplayManager.NewDisplayModification()

theDisplayModification.ApplyToAllFaces = True
theDisplayModification.ApplyToOwningParts = False
theDisplayModification.NewColor = 216

theSelectionIntentRules(0) = theFaceBossPocketFacesRule
theScCollector.ReplaceRules(theSelectionIntentRules, false)

Dim theBossFaces As DisplayableObject() = Nothing
Dim i As Integer = 0

Redim theBossFaces(theScCollector.GetObjects().Length - 1)

For i = 0 To theScCollector.GetObjects().Length - 1
theBossFaces(i) = theScCollector.GetObjects(i)
Next i

theDisplayModification.Apply(theBossFaces)

theDisplayModification.Dispose()

End Sub

Function select_a_face(ByRef prompt As String) As Face

Dim mask(0) As Selection.MaskTriple
With mask(0)
.Type = UF.UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UF.UFConstants.UF_UI_SEL_FEATURE_ANY_FACE
End With
Dim cursor As Point3d = Nothing
select_a_face = Nothing

UI.GetUI.SelectionManager.SelectObject(prompt, "Select a face", _
Selection.SelectionScope.AnyInAssembly, _
Selection.SelectionAction.ClearAndEnableSpecific, False, _
False, mask, select_a_face, cursor)

End Function

End Module