Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

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

Code Help Please

Status
Not open for further replies.

Kenja824

Automotive
Nov 5, 2014
949
Hey Cowski

I mention you specifically because you were the one who did this for me so I figured you would be the most knowledgable on it.

You might remember that the following code will let you select an edge to a component and place a label and the label would draw from an attribute on that component.

I am looking to make two new codes, each with a different change.
1) The only change would be to copy and paste the information from the attribute and not associate it with a code linked to it.

The reason I need this is because we have files now that we extract edges from the bodies and we turn the layer with the actual component off in the drafting view. When we do that and update the view, the labels become dissasociated.

If this is a very difficult change, we have found a work around. So even though this change would make the job easier from the start, its not the end of the world if it is asking too much right now.

2) On a separate code, I would ask for the same change if possible (again, not the end of the world if you cant at this time) plus I would like to select an actual "point" in the component instead of the edge of a component. It would draw the "ID" attribute from the object of the point instead of from the component.

We have weld spot files that are basically just a whole bunch of points. Each point has an "ID" attribute in its properties. We have a label program that already does the job but it is a GRX file that is impossible to read or change and it forces specific fonts and stuff. So every label we create has to have the font type, size and aspect ratio changed to fit GM's standards. I am hoping this would not be a major update to this code so that we can set the font in preferences and all of the labels would be correct as we make them.

I and a leader here have moved into a new area of the company to help get a hot job out and we were shocked at the amount of time that could be saved in the future with a few buttons for repeated actions. These two are two of the biggest ones on the list.




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

Module Module2

    Dim theSession As Session = Session.GetSession()
    Dim theUfSession As UFSession = UFSession.GetUFSession
    Dim theUI As UI = UI.GetUI()

    Dim workPart As Part = theSession.Parts.Work
    Dim displayPart As Part = theSession.Parts.Display
    Dim lw As ListingWindow = theSession.ListingWindow
    Dim lg As LogFile = theSession.LogFile

    Dim noteLength As Double
    Dim noteHeight As Double
    Dim alignPos As Annotations.AlignmentPosition = Nothing
    Dim curStubLength As Double
    Dim curPickEnd(1) As Double

    Sub Main()

        lg.WriteLine("~~ NXJ label component ~~")
        lg.WriteLine("800c0a41-139c-4682-b37f-cfd398de402c")
        lg.WriteLine("  timestamp: " & Now)

        If IsNothing(theSession.Parts.Work) Then
            'active part required
            lg.WriteLine("  no active part, exiting journal")
            Return
        End If

        lw.Open()

        Const undoMarkName As String = "create component labels"
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)


        Dim myDraftingCurve As Drawings.DraftingCurve = Nothing
        Dim myView As View = Nothing
        Dim myPickPt As Point3d

        While SelectDraftingCurve(myDraftingCurve, myPickPt, myView) <> Selection.Response.Cancel

            'lw.WriteLine("curve tag: " & myDraftingCurve.Tag.ToString)

            Dim obj_coords As Point3d = Nothing
            obj_coords = GetPositionOnObject(myDraftingCurve, myView, myPickPt)

            Dim obj_coords_dbl(2) As Double
            obj_coords_dbl(0) = obj_coords.X
            obj_coords_dbl(1) = obj_coords.Y
            obj_coords_dbl(2) = obj_coords.Z
            theUfSession.View.MapModelToDrawing(myView.Tag, obj_coords_dbl, curPickEnd)

            Dim parentCount As Integer
            Dim parents() As Tag = Nothing
            theUfSession.Draw.AskDraftingCurveParents(myDraftingCurve.Tag, parentCount, parents)
            Dim someComp As Assemblies.Component = Nothing

            'lw.WriteLine("parent count: " & parentCount.ToString)
            For Each temp As Tag In parents
                Dim tempObj As NXObject = Utilities.NXObjectManager.Get(temp)
                'lw.WriteLine("parent type: " & tempObj.GetType.ToString)
                'lw.WriteLine("is occurrence: " & tempObj.IsOccurrence.ToString)
                If tempObj.IsOccurrence Then
                    'lw.WriteLine("owning component: " & tempObj.OwningComponent.DisplayName)
                    someComp = tempObj.OwningComponent
                Else
                    'lw.WriteLine("owning part: " & tempObj.OwningPart.Leaf)
                End If
            Next

            If IsNothing(someComp) Then
                lw.WriteLine("no component selected")
                Return
            End If

            'lw.WriteLine("comp name: " & someComp.Name)
            'lw.WriteLine(myPickPt.ToString)
            'lw.WriteLine("selected from view: " & myView.Name)

            'Dim compToolID As String = GetComponentAttribute(someComp, "DB_PART_NO")
            'Dim compPartName As String = GetComponentAttribute(someComp, "DB_PART_NAME")
            'Dim compClassification As String = GetComponentAttribute(someComp, "TOOL_CLASS")

            'lw.WriteLine("compToolID: " & compToolID)
            'lw.WriteLine("compPartName: " & compPartName)
            'lw.WriteLine("compClassification: " & compClassification)

            Dim curLetterPrefs As Annotations.LetteringPreferences = theSession.Parts.Work.Annotations.Preferences.GetLetteringPreferences
            alignPos = curLetterPrefs.AlignmentPosition
            Dim userSymbolPreferences1 As Annotations.UserSymbolPreferences
            userSymbolPreferences1 = theSession.Parts.Work.Annotations.NewUserSymbolPreferences(Annotations.UserSymbolPreferences.SizeType.ScaleAspectRatio, 1, 1)
            Dim curDimPrefs As Annotations.LineAndArrowPreferences = theSession.Parts.Work.Annotations.Preferences.GetLineAndArrowPreferences
            curStubLength = curDimPrefs.StubLength

            MeasureNoteLength(MakeLabelText(someComp))

            'select point for label
            Dim labelPosition As Point3d = SelectScreenPoint()
            'lw.WriteLine("label position: " & labelPosition.ToString)

            'UF_DRF_create_label

            AddComponentLabel(someComp, myDraftingCurve, myView, obj_coords, labelPosition, MakeLabelText(someComp))

        End While

        lw.Close()

    End Sub

    Function SelectDraftingCurve(ByRef theDraftingCurve As Drawings.DraftingCurve,
                                 ByRef pickPt As Point3d,
                                 ByRef selView As View) As Selection.Response

        Dim message As String = "Drafting Curve:"
        Dim title As String = "Select a drafting curve"
        Dim scope As Integer = UFConstants.UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY
        Dim response As Integer
        Dim draftingCurveTag As Tag = Tag.Null
        Dim view As NXOpen.Tag
        Dim cursor(2) As Double
        Dim ip As UFUi.SelInitFnT = AddressOf mask_for_curves

        Dim cursorView As Integer
        theUfSession.Ui.AskCursorView(cursorView)

        theUfSession.Ui.SetCursorView(0)

        theUfSession.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)

        Try
            theUfSession.Ui.SelectWithSingleDialog(message, title, scope, ip,
                         Nothing, response, draftingCurveTag, cursor, view)
            theDraftingCurve = Utilities.NXObjectManager.Get(draftingCurveTag)
            selView = Utilities.NXObjectManager.Get(view)
            pickPt.X = cursor(0)
            pickPt.Y = cursor(1)
            pickPt.Z = cursor(2)
            If draftingCurveTag <> Tag.Null Then
                theUfSession.Disp.SetHighlight(draftingCurveTag, 0)
            End If
        Finally
            theUfSession.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
            theUfSession.Ui.SetCursorView(cursorView)
        End Try

        If response <> UFConstants.UF_UI_OBJECT_SELECTED And
           response <> UFConstants.UF_UI_OBJECT_SELECTED_BY_NAME Then
            Return Selection.Response.Cancel
        Else
            Return Selection.Response.Ok
        End If

    End Function

    Function mask_for_curves(ByVal select_ As IntPtr, ByVal userdata As IntPtr) As Integer

        Dim num_triples As Integer = 4
        Dim mask_triples(3) As UFUi.Mask

        mask_triples(0).object_type = UFConstants.UF_line_type
        mask_triples(0).object_subtype = 0
        mask_triples(0).solid_type = 0

        mask_triples(1).object_type = UFConstants.UF_circle_type
        mask_triples(1).object_subtype = 0
        mask_triples(1).solid_type = 0

        mask_triples(2).object_type = UFConstants.UF_conic_type
        mask_triples(2).object_subtype = 0
        mask_triples(2).solid_type = 0

        mask_triples(3).object_type = UFConstants.UF_spline_type
        mask_triples(3).object_subtype = 0
        mask_triples(3).solid_type = 0

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

        Return UFConstants.UF_UI_SEL_SUCCESS

    End Function

    Function GetComponentAttribute(ByVal theComp As Assemblies.Component, ByVal attributeTitle As String) As String

        If theComp.HasUserAttribute(attributeTitle, NXObject.AttributeType.String, -1) Then
            Return theComp.GetUserAttributeAsString(attributeTitle, NXObject.AttributeType.String, -1)
        Else
            Return Nothing
        End If

    End Function

    Function SelectScreenPoint() As Point3d

        'Allow user to interactively pick the point where the annotation
        'will be placed.

        'This Function needs Sub MotionCallback() to work properly.

        Dim myScreenPos(2) As Double
        Dim theViewTag As Tag = theSession.Parts.Display.Views.WorkView.Tag
        Dim theResponse As Integer

        theUfSession.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)

        theUfSession.Ui.SpecifyScreenPosition("pick a point", AddressOf MotionCallback, Nothing, myScreenPos, theViewTag, theResponse)

        theUfSession.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)

        If theResponse = UFConstants.UF_UI_PICK_RESPONSE Then
            Return New Point3d(myScreenPos(0), myScreenPos(1), myScreenPos(2))
        Else
            Return Nothing
        End If

    End Function

    Function GetPositionOnObject(ByVal obj As DisplayableObject, ByVal aView As View, ByRef coords As Point3d)

        Dim guess1 As Double() = New Double(2) {}
        Dim pt1 As Double() = New Double(2) {}
        Dim pt2 As Double() = New Double(2) {}
        Dim min_dist As Double

        Dim loc_view As Point3d = MapAbs2View(aView, coords)

        Dim sp_view As New Point3d(loc_view.X, loc_view.Y, loc_view.Z + 1000)
        Dim ep_view As New Point3d(loc_view.X, loc_view.Y, loc_view.Z - 1000)
        Dim sp_abs As Point3d = MapView2Abs(aView, sp_view)
        Dim ep_abs As Point3d = MapView2Abs(aView, ep_view)

        Dim line1 As Line = theSession.Parts.Work.Curves.CreateLine(sp_abs, ep_abs)
        line1.SetVisibility(NXOpen.SmartObject.VisibilityOption.Visible)
        line1.RedisplayObject()

        theUfSession.Modl.AskMinimumDist(obj.Tag, line1.Tag, 0, guess1, 0, guess1, min_dist, pt1, pt2)

        Dim markId2 As Session.UndoMarkId = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Delete")
        theSession.UpdateManager.AddToDeleteList(line1)
        theSession.UpdateManager.DoUpdate(markId2)

        Return New Point3d(pt1(0), pt1(1), pt1(2))
    End Function

    Function MapView2Abs(ByVal aView As View, ByVal coords As Point3d)
        Dim vmx As Matrix3x3 = aView.Matrix
        Dim vw() As Double = {0, 0, 0, vmx.Xx, vmx.Xy, vmx.Xz, vmx.Yx, vmx.Yy, vmx.Yz}
        Dim abs() As Double = {0, 0, 0, 1, 0, 0, 0, 1, 0}
        Dim mx(11) As Double
        Dim irc As Integer
        Dim c() As Double = {coords.X, coords.Y, coords.Z}

        theUfSession.Trns.CreateCsysMappingMatrix(vw, abs, mx, irc)
        theUfSession.Trns.MapPosition(c, mx)

        MapView2Abs = New Point3d(c(0), c(1), c(2))
    End Function

    Function MapAbs2View(ByVal aView As View, ByVal coords As Point3d)
        Dim vmx As Matrix3x3 = aView.Matrix
        Dim vw() As Double = {0, 0, 0, vmx.Xx, vmx.Xy, vmx.Xz, vmx.Yx, vmx.Yy, vmx.Yz}
        Dim abs() As Double = {0, 0, 0, 1, 0, 0, 0, 1, 0}
        Dim mx(11) As Double
        Dim irc As Integer
        Dim c() As Double = {coords.X, coords.Y, coords.Z}

        theUfSession.Trns.CreateCsysMappingMatrix(abs, vw, mx, irc)
        theUfSession.Trns.MapPosition(c, mx)

        MapAbs2View = New Point3d(c(0), c(1), c(2))
    End Function

    Sub MotionCallback(ByVal pos() As Double,
                   ByRef motion_cb_data As UFUi.MotionCbData,
                   ByVal client_data As System.IntPtr)

        'This sub will be called every time a cursor move is detected during the
        'SpecifyScreenPosition function.

        'The parameters motion_cb_data and client_data are not used in this implementation,
        'but the Sub must have the same signature as UFUI.MotionFnT to work properly.

        'disable (for now)
        'Return

        Dim wView As NXOpen.View = theSession.Parts.Display.Views.WorkView
        Dim topLeft(2) As Double
        Dim topRight(2) As Double
        Dim botLeft(2) As Double
        Dim botRight(2) As Double

        'Dim labelWidth As Double = 20
        'Dim labelHeight As Double = 5

        'draw rectangle(s) to represent tabular note boundary
        'Select Case alignPos
        '    Case Is = Annotations.AlignmentPosition.TopLeft
        '        'draw rectangle to the right and down
        '        'pos = top left corner
        '        topLeft(0) = pos(0)
        '        topLeft(1) = pos(1)
        '        topRight(0) = pos(0) + noteLength
        '        topRight(1) = pos(1)
        '        botLeft(0) = pos(0)
        '        botLeft(1) = pos(1) - noteHeight
        '        botRight(0) = topRight(0)
        '        botRight(1) = botLeft(1)
        '    Case Is = Annotations.AlignmentPosition.TopRight
        '        'draw rectangle to the left and down
        '        'pos = top right corner
        '        topRight(0) = pos(0)
        '        topRight(1) = pos(1)
        '        topLeft(0) = topRight(0) - noteLength
        '        topLeft(1) = topRight(1)
        '        botLeft(0) = topLeft(0)
        '        botLeft(1) = topLeft(1) - noteHeight
        '        botRight(0) = topRight(0)
        '        botRight(1) = botLeft(1)
        '    Case Else       'shouldn't happen

        'End Select

        'assume mid center alignment position for now
        topLeft(0) = pos(0) - noteLength / 2
        topLeft(1) = pos(1) + noteHeight / 2
        topRight(0) = topLeft(0) + noteLength
        topRight(1) = topLeft(1)
        botLeft(0) = topLeft(0)
        botLeft(1) = topLeft(1) - noteHeight
        botRight(0) = topRight(0)
        botRight(1) = topRight(1) - noteHeight

        Dim stubStart(1) As Double
        Dim stubEnd(1) As Double
        stubStart(0) = pos(0) - noteLength / 2
        stubStart(1) = pos(1)
        stubEnd(0) = stubStart(0) - curStubLength
        stubEnd(1) = stubStart(1)

        'for other temp graphics commands, see:
        '  DisplayOgpArc
        '  DisplayOgpCircle
        '  DisplayOgpLine
        '  DisplayOgpPolyline

        theUfSession.Disp.DisplayOgpLine(wView.Tag, topLeft, topRight)
        theUfSession.Disp.DisplayOgpLine(wView.Tag, topLeft, botLeft)
        theUfSession.Disp.DisplayOgpLine(wView.Tag, botLeft, botRight)
        theUfSession.Disp.DisplayOgpLine(wView.Tag, topRight, botRight)
        theUfSession.Disp.DisplayOgpLine(wView.Tag, stubStart, stubEnd)
        theUfSession.Disp.DisplayOgpLine(wView.Tag, stubEnd, curPickEnd)

    End Sub

    Sub AddComponentLabel(ByVal theComponent As Assemblies.Component,
                          ByVal theDraftingCurve As Drawings.DraftingCurve,
                          ByVal theView As View,
                          ByVal leaderPt As Point3d,
                          ByVal originPt As Point3d,
                          ByVal theText() As String)


        Dim markId1 As NXOpen.Session.UndoMarkId = Nothing
        markId1 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Note")

        Dim nullNXOpen_Annotations_SimpleDraftingAid As NXOpen.Annotations.SimpleDraftingAid = Nothing

        Dim draftingNoteBuilder1 As NXOpen.Annotations.DraftingNoteBuilder = Nothing
        draftingNoteBuilder1 = workPart.Annotations.CreateDraftingNoteBuilder(nullNXOpen_Annotations_SimpleDraftingAid)

        draftingNoteBuilder1.Origin.Anchor = NXOpen.Annotations.OriginBuilder.AlignmentPosition.MidCenter

        draftingNoteBuilder1.Origin.Plane.PlaneMethod = NXOpen.Annotations.PlaneBuilder.PlaneMethodType.XyPlane

        Dim leaderData1 As NXOpen.Annotations.LeaderData = Nothing
        leaderData1 = workPart.Annotations.CreateLeaderData()
        leaderData1.StubSize = theSession.Parts.Work.Annotations.Preferences.GetLineAndArrowPreferences.StubLength
     '   leaderData1.Arrowhead = theSession.Parts.Work.Annotations.Preferences.GetLineAndArrowPreferences.FirstArrowType
     leaderData1.Arrowhead = NXOpen.Annotations.LeaderData.ArrowheadType.FilledArrow
        'lw.WriteLine("first arrow type: " & theSession.Parts.Work.Annotations.Preferences.GetLineAndArrowPreferences.FirstArrowType.ToString)
        leaderData1.VerticalAttachment = NXOpen.Annotations.LeaderVerticalAttachment.Center
        leaderData1.StubSide = NXOpen.Annotations.LeaderSide.Inferred

        draftingNoteBuilder1.Leader.Leaders.Append(leaderData1)

        draftingNoteBuilder1.Text.TextBlock.SetText(theText)

        ' Jog position relocated or jog removed
        leaderData1.Jogs.Clear()

        Dim assocOrigin1 As NXOpen.Annotations.Annotation.AssociativeOriginData = Nothing
        assocOrigin1.OriginType = NXOpen.Annotations.AssociativeOriginType.Drag
        Dim nullNXOpen_View As NXOpen.View = Nothing

        draftingNoteBuilder1.Origin.SetAssociativeOrigin(assocOrigin1)

        draftingNoteBuilder1.Origin.Origin.SetValue(Nothing, nullNXOpen_View, originPt)

        draftingNoteBuilder1.Origin.SetInferRelativeToGeometry(False)

        '      leaderData1.Leader.SetValue(theDraftingCurve, theView, leaderPt)

        Dim nXObject1 As NXOpen.NXObject = Nothing
        nXObject1 = draftingNoteBuilder1.Commit()

        draftingNoteBuilder1.Destroy()

    End Sub

    Function MakeLabelText(ByVal theComponent As Assemblies.Component) As String()

        Dim labelText As New List(Of String)

        If theComponent.HasUserAttribute("DB_PART_NO", NXObject.AttributeType.String, -1) Then
            Dim associativeText1 As Annotations.AssociativeText
            associativeText1 = workPart.Annotations.CreateAssociativeText()

            labelText.Add(associativeText1.GetObjectAttributeText(theComponent, "DB_PART_NO"))

            associativeText1.Dispose()
        End If

 '       If GetComponentAttribute(theComponent, "TOOL_CLASS").ToUpper = "COMM" Then
  '          Dim associativeText1 As Annotations.AssociativeText
  '          associativeText1 = workPart.Annotations.CreateAssociativeText()
'
  '          labelText.Add(associativeText1.GetObjectAttributeText(theComponent, "DB_PART_NAME"))
'
  '          associativeText1.Dispose()
'
  '      End If

        Return labelText.ToArray

    End Function

    Sub MeasureNoteLength(ByVal noteText() As String)

        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "measure note")

        Dim noteOrigin(2) As Double
        noteOrigin(0) = 0
        noteOrigin(1) = 0
        noteOrigin(2) = 0
        Dim noteTag As Tag = Tag.Null

        theUfSession.Drf.CreateNote(noteText.Length, noteText, noteOrigin, 0, noteTag)

        Dim upLeft(2) As Double
        theUfSession.Drf.AskAnnotationTextBox(noteTag, upLeft, noteLength, noteHeight)
        'lw.WriteLine("note length: " & noteLength.ToString)
        'lw.WriteLine("note height: " & noteHeight.ToString)

        theSession.UndoToMark(markId1, "measure note")

    End Sub

    Public Function GetUnloadOption(ByVal dummy As String) As Integer

        'Unloads the image immediately after execution within NX
        GetUnloadOption = Session.LibraryUnloadOption.Immediately

    End Function

End Module
 
Replies continue below

Recommended for you

My current schedule hasn't left me much time for coding recently.

Kenja824 said:
The only change would be to copy and paste the information from the attribute and not associate it with a code linked to it.

The reason I need this is because we have files now that we extract edges from the bodies and we turn the layer with the actual component off in the drafting view. When we do that and update the view, the labels become dissasociated.

I suspect that this does not have to do with the note being linked to an attribute as much as the leader is disassociated from the component edge. In other words, the value of the note should update to the attribute value as long as the component is still loaded (if you are closing the component file, then the value probably wouldn't update and may show as retained). I think the issue is with the note leader becoming disassociated with the edge that has now disappeared. I'm not 100% sure of this theory, but it should be easy for you to test. Load up your drawing as normal, now delete the leader from the note and turn off the layer that the component resides on; if the note stays in the normal state - then the leader connection to the component edge is the issue.

www.nxjournaling.com
 
Sorry cowski, I just now saw you replied to this. I seem to have issues lately with this forum where I no longer get emails sent to me when someone replies, and when I check the filter to only show my own posts, it doesnt show any of my latter posts. The last it shows is back in March.

You are correct.It is the leader that is the issue. When the part layer is turned off (using Visible in View), the leader becomes disassociated. Which we cannot have. Since we only use leaders for these labels when needed and often just place them next to the object with no leader, I figured it best to just change the code to add the label with no leader. We can always add the leader if we need it afterwards.

I understand the time constraints. Overall, I have made some buttons that have helped them speed up their job quite a bit already. This code is not a game stopper if I dont get it done and nobody is going to complain if they dont know about it in the first place. lol I only wish I had the ability to return the favor for how many times you have helped me already in the past.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor