Check 'area' in NX for annotations

I want to be able to check an area on the drawing sheet for any annotations. I can define the areas a (x1-x2,y1-y2), but does anyone know how I could go about 'checking' the enclosed area for any annotations?

http://nxjournaling.com/comment/2281#comment-2281

Ah, I think I see what you are up to now.

So, to check if an annotation is within the given area, you want to use the rectangle's .Contains() method to see if the annotation "rectangle" is inside the area?

Might work. Just remember that System.Drawing.Rectangle uses integers for the point locations while NX uses doubles. If you cast the values from double to integer, you may run into a case where you get an incorrect answer due to rounding. Perhaps with some pre-processing of the values, these can be eliminated.

Thanks! Yes, my main goal is to place balloons in with a smarter, algorithmic approach. I want to check areas surrounding the dimension and choose the optimal location for the balloon (i.e. the area where it would not collide with existing dimension labels)

As for the rectangle's .Contains() method, do you know if this covers "partial containment/collision" of the shapes, or only if the shape is entirely enclosed in the area? I primarily want to detect collisions.

Thanks for your help - of course I'll be looking all this up myself too, but your expertise is always quite helpful!

Looks like it only tells you if the other rectangle is fully contained or not.

reference:
https://msdn.microsoft.com/en-us/library/0kh3ee9e%28v=vs.110%29.aspx

However, there is also the .IntersectsWith method that might come in handy.
https://msdn.microsoft.com/en-us/library/system.drawing.rectangle.inters...

Thanks! Just a quick question - when I change the dimension alignment using the GUI, I don't actually see any changes in positioning of the dimension text. Do you know why that might be?

I just want to make sure that the alignment position is actually giving me the X,Y coordinate of the origin I want.

When you change the alignment in the GUI, the position may change slightly if the annotation is associated to another object. If the annotation has no associations to other objects, it will not move but the alignment option will change.

Thanks! When I check for collisions with other dimensions/balloons, I need to search through all of the dimensions on the active sheet.


Dim openSheet As Drawings.DrawingSheet = CType(AskDrawingSheet(myDimension), Drawings.DrawingSheet)
openSheet.Open()
For each collidingdim as Annotations.Dimension in openSheet.Dimensions

Is there a way to define "openSheet.Dimensions"? I don't think what I have will compile.

The code below will iterate through the dimension collection and sort them by sheet. The code will provide a dictionary object that you can query; given a particular sheet, it will return a list of dimensions that are on the given sheet. The code below was not tested with PMI dimensions, only drafting dimensions.

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

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 = "sort dimensions by sheet"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

Dim dimDictionary As New Dictionary(Of Drawings.DrawingSheet, List(Of Annotations.Dimension))

'add all the drawing sheets to the dictionary object
For Each tempSheet As Drawings.DrawingSheet In workPart.DrawingSheets
dimDictionary.Add(tempSheet, New List(Of Annotations.Dimension))
Next

'process the dimensions, add each to the proper list
For Each temp As Annotations.Dimension In workPart.Dimensions

Dim owningSheet As Drawings.DrawingSheet
owningSheet = AskDrawingSheet(temp)

If IsNothing(owningSheet) Then
'skip this dim
Continue For
End If

If dimDictionary.ContainsKey(owningSheet) Then
dimDictionary.Item(owningSheet).Add(temp)
Else
'error, sheet does not exist in dictionary!
End If

Next

'report dimensions by sheet
lw.WriteLine("dimensions by drawing sheet:")
lw.WriteLine("------------------------------")

For Each pair As KeyValuePair(Of Drawings.DrawingSheet, List(Of Annotations.Dimension)) In dimDictionary
lw.WriteLine(" Sheet name: " & pair.Key.Name & " [" & pair.Value.Count.ToString & " dimensions]")
For Each temp As Annotations.Dimension In pair.Value
lw.WriteLine(" dimension tag: " & temp.Tag.ToString)
Next
lw.WriteLine("")
Next

lw.Close()

End Sub

' This function will work for:
' an object which "Resides on drawing" or is "View Dependent In" a DraftingView
' a DraftingView
' a DrawingSheet.View
' Returns Nothing for all other (ie. model mode) objects
Function AskDrawingSheet(ByVal theObject As TaggedObject) As Drawings.DrawingSheet

'code by Amy Webster
'GTAC document nx_api4937

Dim theView As View = TryCast(theObject, View)
If Not theView Is Nothing Then
Dim sheetTag As Tag = Nothing
Try
theUFSession.Draw.AskDrawingOfView(theView.Tag, sheetTag)
Return Utilities.NXObjectManager.Get(sheetTag) ' the drawing it is on
Catch ex As NXException
Return Nothing ' it is a model view
End Try
End If

Dim viewName As String = Nothing
Dim status As Integer = Nothing
Try
theUFSession.View.AskViewDependentStatus(theObject.Tag, status, viewName)
Catch ex As NXException
Return Nothing
End Try
If status = 0 Then Return Nothing ' it is a model mode object

Dim viewTag As Tag = Nothing
theUFSession.View.AskTagOfViewName(viewName, viewTag)
Dim viewType As Integer = Nothing
Dim viewSubtype As Integer = Nothing
theUFSession.View.AskType(viewTag, viewType, viewSubtype)
If viewType = 0 Then Return Nothing ' it is view dependent in a modeling view

Dim drawingTag As Tag = Nothing
theUFSession.Draw.AskDrawingOfView(viewTag, drawingTag)
Return Utilities.NXObjectManager.Get(drawingTag) ' the drawing it is on!

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

Just to clarify, are the tags associated with each dimension truly unique to that specific dimension? If the order of the dimensions change on the drawing, or they are moved around, or new dimensions are added, do the existing dimensions retain their identifiers/tags?

An object's tag will uniquely identify that object *within the current NX session*. NX will generate tags for objects when a part is opened; the tag will uniquely identify the object in the current NX session. The tag is not saved with the object in the part file. If you close NX, restart it and open the same part, the objects may (most likely will) have different tags associated to them. But as long as the part file is open in the same NX session, the tag will stay with the object even if the object is moved around or new objects are added.

Thanks. If I wanted to keep track of the unique objects even after the session is closed, is there another identifier I can use? I was looking into hash code - is this the best option to pursue?

I essentially want a way to keep track of all features with a unique tag even after closing the files, that way if I want to alter the drawing later, I can access the dimensions through their unique identifier and make edits to them.

Thanks so much!

I've not yet had the need to use it, but there is an "object ID" that may get what you want. You can find a code sample (from GTAC) at the following link:
http://nxjournaling.com/comment/458#comment-458