Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations SSS148 on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

ChamferBuilder

Status
Not open for further replies.

EngProgrammer

Aerospace
Jan 14, 2015
150
Anyone have experience using ChamferBuilder. I wrote a function for the creation of a chamfer; however, in some instances the chamfer is coming in the wrong direction and needs to be flipped. This is typically done manually in NX when installing a chamfer, the designer looks at the resulting chamfer and then reverses the direction. However, in my situation with code, I don't want to have to write code in interrogate the chamfer and then reverse direction. These chamfers are being applied to hole feature, so the depth is always along the length of the hole.

Any ideas?

Here's my function:

Code:
Private Function CreateChamfer(ByVal iDepth As Double, ByVal iAngle As Double, ByVal iEdge As Edge) As Features.Feature

        Dim chamferBuilder1 As Features.ChamferBuilder
        chamferBuilder1 = workPart.Features.CreateChamferBuilder(Nothing)

        chamferBuilder1.Option = Features.ChamferBuilder.ChamferOption.OffsetAndAngle

        chamferBuilder1.Method = Features.ChamferBuilder.OffsetMethod.EdgesAlongFaces

        chamferBuilder1.FirstOffset = iDepth.ToString()

        chamferBuilder1.Angle = iAngle.ToString()

        chamferBuilder1.Tolerance = 0.001

        Dim scCollector1 As ScCollector
        scCollector1 = workPart.ScCollectors.CreateCollector()

        Dim nullEdge As Edge = Nothing

        Dim edgeTangentRule1 As EdgeTangentRule
        edgeTangentRule1 = workPart.ScRuleFactory.CreateRuleEdgeTangent(iEdge, nullEdge, False, 0.5, False, False)

        Dim rules1(0) As SelectionIntentRule
        rules1(0) = edgeTangentRule1
        scCollector1.ReplaceRules(rules1, False)

        chamferBuilder1.SmartCollector = scCollector1

        Dim feature1 As Features.Feature
        feature1 = chamferBuilder1.CommitFeature()

        chamferBuilder1.Destroy()

        Return feature1

    End Function
 
Replies continue below

Recommended for you

I suggest you also ask this in the Siemens PLM programming forum Link

Mark Rief
NX CAM Customer Success
Siemens PLM Software
 
EngProgrammer said:
I don't want to have to write code in interrogate the chamfer and then reverse direction
I don't see any good alternatives...

Below is a proof of concept journal.
Caveats:[ul]
[li]it expects that the selected edge is attached to a cylindrical face (it assumes this cylindrical face is the hole)[/li]
[li]if the chamfer feature creates more than 2 edges, the journal will almost certainly fall over[/li]
[/ul]
I believe that both of these limitations can be overcome with additional code checks. The code seems to work well in simple test cases (the edge chosen is a single entity and it connects a planar face to a cylindrical face).


Code:
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()

        If IsNothing(theSession.Parts.BaseWork) Then
            'active part required
            Return
        End If

        lw.Open()

        Const undoMarkName As String = "chamfer along depth"
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

        Dim myEdge As Edge = Nothing

        If SelectEdge("Select an edge", myEdge) = Selection.Response.Cancel Then
            Return
        End If

        CreateChamfer(0.06, 15, myEdge)

        lw.Close()

    End Sub

    Function SelectEdge(ByVal prompt As String, ByRef selEdge As Edge) As Selection.Response

        Dim theUI As UI = UI.GetUI
        Dim title As String = "Select an edge"
        Dim includeFeatures As Boolean = False
        Dim keepHighlighted As Boolean = False
        Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
        Dim cursor As Point3d
        Dim scope As Selection.SelectionScope = Selection.SelectionScope.WorkPart
        Dim selectionMask_array(0) As Selection.MaskTriple
        Dim selObj As TaggedObject = Nothing

        With selectionMask_array(0)
            .Type = UFConstants.UF_solid_type
            .SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
        End With

        Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObject(prompt, _
         title, scope, selAction, _
         includeFeatures, keepHighlighted, selectionMask_array, _
         selObj, cursor)
        If resp = Selection.Response.ObjectSelected OrElse resp = Selection.Response.ObjectSelectedByName Then
            selEdge = selObj
            Return Selection.Response.Ok
        Else
            Return Selection.Response.Cancel
        End If

    End Function

    Private Function CreateChamfer(ByVal iDepth As Double, ByVal iAngle As Double, ByVal iEdge As Edge) As Features.Feature

        Dim holeDirection As Direction = Nothing
        Dim dirError As Boolean = True
        Try
            holeDirection = FindHoleDirection(iEdge)
            dirError = False
        Catch ex As Exception
            lw.WriteLine("FindHoleDirection error: " & ex.Message)
        End Try

        Dim chamferBuilder1 As Features.ChamferBuilder
        chamferBuilder1 = workPart.Features.CreateChamferBuilder(Nothing)

        With chamferBuilder1
            .Option = Features.ChamferBuilder.ChamferOption.OffsetAndAngle
            .Method = Features.ChamferBuilder.OffsetMethod.EdgesAlongFaces
            .ReverseOffsets = False
            .FirstOffset = iDepth.ToString()
            .Angle = iAngle.ToString()
            .Tolerance = 0.001
        End With

        Dim scCollector1 As ScCollector
        scCollector1 = workPart.ScCollectors.CreateCollector()

        Dim nullEdge As Edge = Nothing

        Dim edgeTangentRule1 As EdgeTangentRule
        edgeTangentRule1 = workPart.ScRuleFactory.CreateRuleEdgeTangent(iEdge, nullEdge, False, 0.5, False, False)

        Dim rules1(0) As SelectionIntentRule
        rules1(0) = edgeTangentRule1
        scCollector1.ReplaceRules(rules1, False)

        chamferBuilder1.SmartCollector = scCollector1

        Dim feature1 As Features.Feature
        feature1 = chamferBuilder1.CommitFeature()

        chamferBuilder1.Destroy()

        If Not dirError Then
            CheckChamfer(iDepth, iAngle, holeDirection, feature1)
        End If

        Return feature1

    End Function

    Private Sub FlipChamfer(ByVal theChamfer As Features.Chamfer)

        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Edit Feature Parameters")

        Dim chamferBuilder1 As Features.ChamferBuilder
        chamferBuilder1 = workPart.Features.CreateChamferBuilder(theChamfer)

        chamferBuilder1.ReverseOffsets = Not chamferBuilder1.ReverseOffsets

        Dim feature1 As Features.Feature
        feature1 = chamferBuilder1.CommitFeature()

        chamferBuilder1.Destroy()

        Dim nErrs1 As Integer
        nErrs1 = theSession.UpdateManager.DoUpdate(markId1)

        theSession.Preferences.Modeling.UpdatePending = False


    End Sub

    Private Sub CheckChamfer(ByVal iDepth As Double, ByVal iAngle As Double, ByVal theDirection As Direction, ByVal theChamfer As Features.Chamfer)

        Dim theAngularTolerance As Double
        theUfSession.Modl.AskAngleTolerance(theAngularTolerance)

        If Math.Abs(45 - iAngle) < theAngularTolerance Then
            'chamfer is close to 45°, no need to flip chamfer
            Return
        End If

        Dim depth1 As Double = MeasureChamferDepth(theChamfer, theDirection)
        Dim diff1 As Double = Math.Abs(iDepth - depth1)

        FlipChamfer(theChamfer)

        Dim depth2 As Double = MeasureChamferDepth(theChamfer, theDirection)
        Dim diff2 As Double = Math.Abs(iDepth - depth2)

        If diff1 < diff2 Then
            FlipChamfer(theChamfer)
        End If

    End Sub

    Private Function FindHoleDirection(ByVal theEdge As Edge) As Direction

        'finds the axis of a cylindrical hole
        Dim holeFaceTags() As Tag = Nothing
        theUfSession.Modl.AskEdgeFaces(theEdge.Tag, holeFaceTags)

        'get faces connected to selected edge
        Dim holeFaces As New List(Of Face)
        For Each temp As Tag In holeFaceTags
            holeFaces.Add(Utilities.NXObjectManager.Get(temp))
        Next

        Dim holeFace As Face
        Dim holeFaceRadius As Double
        Dim found As Boolean = False
        Dim dirArray(2) As Double

        For Each temp As Face In holeFaces
            If temp.SolidFaceType = Face.FaceType.Cylindrical Then
                Dim faceType As Integer
                Dim pt(2) As Double
                Dim dir(2) As Double
                Dim box(5) As Double
                Dim rad As Double
                Dim radData As Double
                Dim normDir As Integer

                theUfSession.Modl.AskFaceData(temp.Tag, faceType, pt, dir, box, rad, radData, normDir)
                If found Then
                    'not the first cylindrical face found, check to see if it is smaller than the first
                    If rad < holeFaceRadius Then
                        holeFace = temp
                        holeFaceRadius = rad
                        dirArray(0) = dir(0)
                        dirArray(1) = dir(1)
                        dirArray(2) = dir(2)
                    End If
                Else
                    'first cylindrical face found, use it as hole face
                    holeFace = temp
                    dirArray(0) = dir(0)
                    dirArray(1) = dir(1)
                    dirArray(2) = dir(2)
                    holeFaceRadius = rad
                    found = True
                End If
            End If
        Next

        If Not found Then
            Throw (New Exception("no cylindrical face found"))
            Return Nothing
        End If

        Dim holeDir As Direction
        Dim origin1 As Point3d = New Point3d(0.0, 0.0, 0.0)
        Dim vector1 As Vector3d = New Vector3d(dirArray(0), dirArray(1), dirArray(2))
        holeDir = workPart.Directions.CreateDirection(origin1, vector1, SmartObject.UpdateOption.AfterModeling)

        Return holeDir

    End Function

    Private Function MeasureChamferDepth(ByVal theChamfer As Features.Chamfer, ByVal chamferDirection As Direction) As Double

        Dim depth As Double

        'if the chamfer feature creates more than 2 edges, this code will need to be improved
        Dim chamferEdges() As Edge = theChamfer.GetEdges

        Dim nullNXObject As NXObject = Nothing

        Dim measureDistanceBuilder1 As MeasureDistanceBuilder
        measureDistanceBuilder1 = workPart.MeasureManager.CreateMeasureDistanceBuilder(nullNXObject)
        With measureDistanceBuilder1
            .InfoWindow = False
            .AnnotationMode = MeasureBuilder.AnnotationType.None
            .Mtype = MeasureDistanceBuilder.MeasureType.Minimum
            .ProjectionVector = chamferDirection
            .Object1.Value = chamferEdges(0)
            .Object2.Value = chamferEdges(1)
        End With

        Dim unit1 As Unit
        If workPart.PartUnits = BasePart.Units.Inches Then
            unit1 = workPart.UnitCollection.FindObject("Inch")
        Else
            unit1 = workPart.UnitCollection.FindObject("MilliMeter")
        End If

        Dim measureDistance1 As MeasureDistance
        measureDistance1 = workPart.MeasureManager.NewDistance(unit1, chamferEdges(0), chamferEdges(1), chamferDirection, MeasureManager.ProjectionType.Minimum)

        depth = measureDistance1.Value

        measureDistance1.Dispose()

        measureDistanceBuilder1.Destroy()

        Return depth

    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

www.nxjournaling.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor