Balloon Without PartList

Hello !

Before Nx 1847 i used this VB code (Journaling) to create a Balloon without PartList

I used this code and it worked great and it was fast !!!!

By clicking on a component in a view, it would look for the value of the attribute "PRT_BALLON_NUM" of this component which corresponds to the component numbers (Callout) and it created a balloon with this number.

But since the NX updates it no longer works.

I have this message in my LW:

~~ Auto balloon without parts list ~~
timestamp: 2/28/2020 10:10:23 AM
User has selected an edge.
selected object type: NXOpen.Drawings.DraftingCurve
selected in view: Explosioin - Master
View type: NXOpen.Drawings.BaseView
selected point: 14.1740488845779, -4.22070758212917, 17.1759836408613
Get the component from the selected edge.
mySelEdgeTag = 34104566
Could not find component of edge, skip to next edge selection

It seems to be a TAG problem…….

You can Help me ?

Best regards!

Pat

' NX1847
' Journal créé par Patrick Letarte
' Modifié le 2019-01-04
' This journal allows a user to select an edge of a component on an assembly drawing, then
' select a location to place the balloon. The callout within the balloon will be associated
' to the callout of the component.

Option Strict Off
Imports System
Imports System.Windows.Forms
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI

Module AutoBalloon
Dim theSession As Session = Session.GetSession()
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 lg As ListingWindow = theSession.ListingWindow
Dim ufs As UFSession = UFSession.GetUFSession
Dim theUI As UI = UI.GetUI
Dim dicSectionEdges As New Dictionary(Of Tag, Tag)
Dim viewList As New List(Of Tag)

Sub Main()

Dim myPointBalloon As Point3d
Dim strCallout As String
Dim myComponent As Assemblies.Component
Dim mySelPoint(2) As Double
Dim mySelViewTag As Tag = Tag.Null
Dim mySelEdgeTag As Tag = Nothing
Dim myEdgeCurve As DisplayableObject

'lw.Open()
Echo("~~ Auto balloon without parts list ~~")
Echo(" timestamp: " & Now)

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

Const undoMarkName As String = "Auto balloon without parts list"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

Do Until UserSelectEdge("Select edge to attach balloon", mySelPoint, mySelViewTag, mySelEdgeTag) = Selection.Response.Cancel

Echo(" User has selected an edge.")
'return the object from the given tag
ufs.Disp.SetHighlight(mySelEdgeTag, 0)
myEdgeCurve = Utilities.NXObjectManager.Get(mySelEdgeTag)
If IsNothing(myEdgeCurve) Then
Echo(" UserSelectEdge() returned Nothing, skip to next edge selection")
Continue Do
End If

Echo(" selected object type: " & myEdgeCurve.GetType.ToString)
Dim selView As NXOpen.View = Utilities.NXObjectManager.Get(mySelViewTag)
Echo(" selected in view: " & selView.Name)
Echo(" View type: " & selView.GetType.ToString)
Echo(" selected point: " & mySelPoint(0) & ", " & mySelPoint(1) & ", " & mySelPoint(2))

If TypeOf (selView) Is Drawings.SectionView Then
Echo(" View is a section view. Building dictionary of sections edges.")
BuildSectionDictionary(selView)
End If

Echo(" Get the component from the selected edge.")
myComponent = GetComponentOfEdge(mySelEdgeTag)
Echo(" mySelEdgeTag = " & mySelEdgeTag.ToString)
If IsNothing(myComponent) Then
Echo(" Could not find component of edge, skip to next edge selection")
Continue Do
End If
Echo(" GetComponentOfEdge(mySelEdgeTag) = " & myComponent.DisplayName)

Echo(" Find out if the selected component is a child of the current assembly or if it is a child of a subassembly.")
'Do Until workPart.ComponentAssembly.RootComponent.DisplayName = myComponent.Parent.Parent.DisplayName
Echo(" myComponent = " & myComponent.DisplayName & ": No")
'myComponent = myComponent.Parent
'Loop
strCallout = ""
Echo(" myComponent = " & myComponent.DisplayName & ": Yes")
Echo(" strCallout = " & strCallout)

Dim symPt As Point3d
symPt.X = mySelPoint(0)
symPt.Y = mySelPoint(1)
symPt.Z = mySelPoint(2)

Echo(" Building the new ID symbol...")
Dim nullAnnotations_IdSymbol As Annotations.IdSymbol = Nothing

Dim idSymbolBuilder1 As Annotations.IdSymbolBuilder
'idSymbolBuilder1 = workPart.Annotations.IdSymbols.CreateIdSymbolBuilder(nullAnnotations_IdSymbol)
'idSymbolBuilder1.UpperText = strCallout
'idSymbolBuilder1.Size = 0.500

'-------------------------
idSymbolBuilder1 = workPart.Annotations.IdSymbols.CreateIdSymbolBuilder(nullAnnotations_IdSymbol)
idSymbolBuilder1.Origin.SetInferRelativeToGeometry(True)
idSymbolBuilder1.Type = NXOpen.Annotations.IdSymbolBuilder.SymbolTypes.RoundedBox
idSymbolBuilder1.Origin.SetInferRelativeToGeometry(True)
idSymbolBuilder1.Origin.Anchor = NXOpen.Annotations.OriginBuilder.AlignmentPosition.MidCenter
idSymbolBuilder1.UpperText = strCallout '""
idSymbolBuilder1.Size = 0.5
'----------------------------------------------------

Dim leaderData1 As Annotations.LeaderData
'leaderData1 = workPart.Annotations.CreateLeaderData()
'leaderData1.Arrowhead = Annotations.LeaderData.ArrowheadType.FilledArrow
'leaderData1.TerminatorType = Annotations.LeaderData.LeaderType.PlainWithoutStub

'----------------------------------------------------
leaderData1 = workPart.Annotations.CreateLeaderData()
leaderData1.StubSize = 0.14999999999999999
leaderData1.Arrowhead = Annotations.LeaderData.ArrowheadType.FilledArrow
leaderData1.VerticalAttachment = NXOpen.Annotations.LeaderVerticalAttachment.Center
'----------------------------------------------------
idSymbolBuilder1.Leader.Leaders.Append(leaderData1)
idSymbolBuilder1.Origin.SetInferRelativeToGeometry(True)

Dim nullView As NXOpen.View = Nothing

'Arrow location
Echo(" Creating the leader.")
leaderData1.Leader.SetValue(myEdgeCurve, selView, symPt)

Dim assocOrigin1 As Annotations.Annotation.AssociativeOriginData
idSymbolBuilder1.Origin.SetAssociativeOrigin(assocOrigin1)

'Balloon location
Echo(" Getting the screen position to place the balloon.")
Dim response2 As Selection.DialogResponse = UserSelectScreenPos("Place balloon", myPointBalloon)
If response2 <> Selection.DialogResponse.Pick Then
Return
End If

Dim point3 As Point3d = New Point3d(myPointBalloon.X, myPointBalloon.Y, 0.0)
idSymbolBuilder1.Origin.Origin.SetValue(Nothing, nullView, point3)

Echo(" Committing the ID symbol.")
Dim nXObject1 As NXObject
nXObject1 = idSymbolBuilder1.Commit()

idSymbolBuilder1.Destroy()

Loop
Echo("~~ End Auto balloon without parts list ~~")
lw.Close()

End Sub

Function UserSelectEdge(ByVal prompt As String, ByRef theCursor() As Double, ByRef theView As Tag, ByRef theObject As Tag) As Selection.Response

'Allow user to interactively select an edge
Dim response As Integer = 0
Dim user_data As System.IntPtr

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

Try
ufs.Ui.SetCursorView(0)
'SelectWithSingleDialog allows the user to make a single selection and returns the object, the point and the view.
ufs.Ui.SelectWithSingleDialog("Select component: ", prompt, _
UFConstants.UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY, AddressOf init_proc_body, _
user_data, response, theObject, theCursor, theView)
Finally
ufs.Ui.SetCursorView(curCursorView)
ufs.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
End Try

Select Case response
Case UFConstants.UF_UI_BACK
Return Selection.Response.Back
Case UFConstants.UF_UI_OK
Return Selection.Response.Ok
Case UFConstants.UF_UI_OBJECT_SELECTED
Return Selection.Response.ObjectSelected
Case UFConstants.UF_UI_OBJECT_SELECTED_BY_NAME
Return Selection.Response.ObjectSelectedByName
Case Else
Return Selection.Response.Cancel
End Select
End Function

Public Function init_proc_body(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 edges or curves
Dim num_triples As Integer = 7
Dim mask_triples(num_triples - 1) As UFUi.Mask

mask_triples(0).object_type = UFConstants.UF_solid_type
mask_triples(0).object_subtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE

mask_triples(1).object_type = UFConstants.UF_line_type
mask_triples(1).object_subtype = UFConstants.UF_all_subtype

mask_triples(2).object_type = UFConstants.UF_circle_type
mask_triples(2).object_subtype = UFConstants.UF_all_subtype

mask_triples(3).object_type = UFConstants.UF_conic_type
mask_triples(3).object_subtype = UFConstants.UF_all_subtype

mask_triples(4).object_type = UFConstants.UF_spline_type
mask_triples(4).object_subtype = UFConstants.UF_all_subtype

mask_triples(5).object_type = UFConstants.UF_solid_silhouette_type
mask_triples(5).object_subtype = UFConstants.UF_all_subtype

mask_triples(6).object_type = UFConstants.UF_section_edge_type
mask_triples(6).object_subtype = UFConstants.UF_all_subtype

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

Return UFConstants.UF_UI_SEL_SUCCESS

End Function

Function GetComponentOfEdge(ByVal theEdgeTag As Tag) As Assemblies.Component
'Find the owning componet of the edge

Dim dwgObj As NXObject
dwgObj = Utilities.NXObjectManager.Get(theEdgeTag)

If dwgObj.IsOccurrence Then
'object is owned by a component (edge, face, etc)

Return dwgObj.OwningComponent
Else
'object is owned by the drawing (silhouette edge curve, section edge curve, extracted edge curve, etc)

If TypeOf (dwgObj) Is NXOpen.Line Or TypeOf (dwgObj) Is NXOpen.Arc Or _
TypeOf (dwgObj) Is NXOpen.Spline Or TypeOf (dwgObj) Is NXOpen.Conic Then

Dim groupTag As Tag
Dim groupType As Integer
Dim groupSubType As Integer
'determine if this is a section or silhouette curve
ufs.Draw.AskGroupOfCurve(dwgObj.Tag, groupTag, groupType, groupSubType)

Select Case groupType
Case Is = UFConstants.UF_solid_silhouette_type
'silhouette type 201
Dim theFaceTag As Tag
ufs.Draw.AskFaceOfSil(dwgObj.Tag, theFaceTag)
Echo(" theFaceTag = " & theFaceTag)

Dim theFace As NXObject = Utilities.NXObjectManager.Get(theFaceTag)
Echo(" theFace = " & theFace.ToString)
Return theFace.OwningComponent

Case Is = UFConstants.UF_solid_section_type
'section curve type 198

Dim tempComp As Assemblies.Component
tempComp = ComponentOfSectionEdge(dwgObj.Tag)

Return tempComp

Case Else
Return Nothing

End Select

End If
'theObject is not a line, arc, conic, or spline
Return Nothing
End If

End Function

Sub BuildSectionDictionary(ByVal sectionView As Drawings.SectionView)

'If you have previously built a dictionary for this view, exit sub.
If viewList.IndexOf(sectionView.Tag) = -1 Then
viewList.Add(sectionView.Tag)
Else
Exit Sub
End If

Dim sxSolidTags() As Tag
Dim numSxSolids As Integer
ufs.Draw.AskSxsolidsOfSxview(sectionView.Tag, Nothing, numSxSolids, sxSolidTags)

For Each sxSolidTag As Tag In sxSolidTags

Dim numSxEdges As Integer
Dim sxEdgeTags() As Tag
ufs.Draw.AskSxedgesOfSxsolid(sxSolidTag, numSxEdges, sxEdgeTags)

For Each sxEdgeTag As Tag In sxEdgeTags

dicSectionEdges.Add(sxEdgeTag, sxSolidTag)

Next

Next

End Sub

Function ComponentOfSectionEdge(ByVal sectionEdgeTag As Tag) As Assemblies.Component

Dim tempComp As Assemblies.Component

If dicSectionEdges.ContainsKey(sectionEdgeTag) Then
Dim sxSolidTag As Tag = dicSectionEdges.Item(sectionEdgeTag)

Dim solidTag As Tag
ufs.Draw.AskSolidOfSection(sxSolidTag, solidTag)

Dim tempSolid As Body = Utilities.NXObjectManager.Get(solidTag)
tempComp = tempSolid.OwningComponent

Return tempComp

Else
Return Nothing
End If

End Function

Sub Echo(ByVal output As String)

theSession.ListingWindow.Open()
theSession.ListingWindow.WriteLine(output)
theSession.LogFile.WriteLine(output)

End Sub

Function UserSelectScreenPos(ByVal prompt As String, ByRef selPoint As Point3d) As Selection.DialogResponse
'Allow user to interactively select a screen position
Dim view As NXOpen.View = Nothing
Return theUI.SelectionManager.SelectScreenPosition(prompt, view, selPoint)
End Function

End Module

Your log file indicates that a drafting curve was selected:
selected object type: NXOpen.Drawings.DraftingCurve

This indicates to me that you are using "Exact" type drafting views.

Some of your code looks quite similar to the "move parts list balloon" journal found here:
http://nxjournaling.com/content/move-parts-list-callout-leader-location

In the link above, it explains that it works only with the drafting view type "Pre NX 8.5"; if you use the new "Exact" view type, the code won't work correctly. With the old "pre NX 8.5" views, the geometry in the drafting views consisted of edges, silhouette curves, and section edges. The edges could be queried directly to find out what component they belonged to, but the silhouette curves and section edges took more work.

In the new "exact" drafting view type all the view geometry is represented by "drafting curves". The curves are generated for the view and do not come directly from the component. This means that you can't use the .OwningComponent property to trace it directly back to a component. A new method has been added to the API to make up for this deficiency: .AskDraftingCurveParents. This relatively new method allows you to trace the drafting curve back to the component that it represents.

Hi,

You can help me to fix this code ?

We can fix it?

Best regards !!!

Pat