Measure distance between 2 csys

Hello

I'm creating 1 journal that create a txt with some values, but now i have 1 problem, there is a way to measure the distance between the active csys and an csys with a default name and measure what is the rotation between the Y csys (because Z csys's have always the same direction on both csys)

I'm using NX10

The following code will look for a saved csys object (not a datum csys feature) that is named "MYCSYS"; if found, it will measure the distance and angles from the current WCS to the saved csys. There is probably a more straightforward way to go about this, it was cobbled together from various other journals that I had on hand.

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module Module2

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

Sub Main()

Dim workPart As Part = theSession.Parts.Work
lw.Open()

Dim myStartObject As CoordinateSystem = theSession.Parts.Work.WCS.CoordinateSystem

Dim startPoint As Point3d = myStartObject.Origin
Dim startOrientation As NXMatrix = myStartObject.Orientation
Dim startCsys(8) As Double
'0-2 = origin point in abs coordinates
startCsys(0) = startPoint.X
startCsys(1) = startPoint.Y
startCsys(2) = startPoint.Z
'3-8 = X & Y vectors in abs coordinates
startCsys(3) = startOrientation.Element.Xx
startCsys(4) = startOrientation.Element.Xy
startCsys(5) = startOrientation.Element.Xz
startCsys(6) = startOrientation.Element.Yx
startCsys(7) = startOrientation.Element.Yy
startCsys(8) = startOrientation.Element.Yz
'NX derives the Z vector from the given X and Y vectors

Dim myEndObject As CoordinateSystem = Nothing
Dim foundEnd As Boolean = False

For Each tempCsys As CoordinateSystem In workPart.CoordinateSystems
If tempCsys.Name = "MYCSYS" Then
myEndObject = tempCsys
foundEnd = True
Exit For
End If
Next

If Not foundEnd Then
lw.WriteLine("End csys not found")
Return
End If

Dim endPoint As Point3d = myEndObject.Origin
Dim endOrientation As NXMatrix = myEndObject.Orientation
Dim endCsys(8) As Double
'0-2 = origin point in abs coordinates
endCsys(0) = endPoint.X
endCsys(1) = endPoint.Y
endCsys(2) = endPoint.Z
'3-8 = X & Y vectors in abs coordinates
endCsys(3) = endOrientation.Element.Xx
endCsys(4) = endOrientation.Element.Xy
endCsys(5) = endOrientation.Element.Xz
endCsys(6) = endOrientation.Element.Yx
endCsys(7) = endOrientation.Element.Yy
endCsys(8) = endOrientation.Element.Yz
'NX derives the Z vector from the given X and Y vectors

Dim fromOrigin() As Double = {startPoint.X, startPoint.Y, startPoint.Z}
Dim fromXAxis() As Double = {startOrientation.Element.Xx, startOrientation.Element.Xy, startOrientation.Element.Xz}
Dim fromYAxis() As Double = {startOrientation.Element.Yx, startOrientation.Element.Yy, startOrientation.Element.Yz}

Dim toOrigin() As Double = {endPoint.X, endPoint.Y, endPoint.Z}
Dim toXAxis() As Double = {endOrientation.Element.Xx, endOrientation.Element.Xy, endOrientation.Element.Xz}
Dim toYAxis() As Double = {endOrientation.Element.Yx, endOrientation.Element.Yy, endOrientation.Element.Yz}

Dim mtx4Transform(15) As Double

theUfSession.Mtx4.CsysToCsys(fromOrigin, fromXAxis, fromYAxis, toOrigin, toXAxis, toYAxis, mtx4Transform)

'rotation angles
Dim rotationAboutX As Double
Dim rotationAboutY As Double
Dim rotationAboutZ As Double

RotationAngles(mtx4Transform, rotationAboutX, rotationAboutY, rotationAboutZ)

lw.WriteLine("")

lw.WriteLine("absolute X distance: " & (endPoint.X - startPoint.X).ToString)
lw.WriteLine("absolute Y distance: " & (endPoint.Y - startPoint.Y).ToString)
lw.WriteLine("absolute Z distance: " & (endPoint.Z - startPoint.Z).ToString)
lw.WriteLine("")
lw.WriteLine("rotation about X: " & rotationAboutX.ToString)
lw.WriteLine("rotation about Y: " & rotationAboutY.ToString)
lw.WriteLine("rotation about Z: " & rotationAboutZ.ToString)

End Sub

Sub RotationAngles(ByVal mtx4x4() As Double, ByRef RX1 As Double, ByRef RY1 As Double, ByRef RZ1 As Double)

'extract euler angles from rotation matrix:

Dim rotationMatrix(8) As Double
theUfSession.Mtx4.AskRotation(mtx4x4, rotationMatrix)

Dim c1, c2, s1 As Double

RX1 = Math.Atan2(rotationMatrix(7), rotationMatrix(8))
c2 = Math.Sqrt(rotationMatrix(0) ^ 2 + rotationMatrix(3) ^ 2)
RY1 = Math.Atan2(-rotationMatrix(6), c2)
s1 = Math.Sin(RX1)
c1 = Math.Cos(RX1)
RZ1 = Math.Atan2(s1 * rotationMatrix(2) - c1 * rotationMatrix(1), c1 * rotationMatrix(4) - s1 * rotationMatrix(5))

'convert angles from radians to degrees
RX1 *= (180 / Math.PI)
RY1 *= (180 / Math.PI)
RZ1 *= (180 / Math.PI)

End Sub

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

but there is a way to do with a datum csys feature?

its only change tempCsys to datumCsys?

It's solve, with this http://www.nxjournaling.com/content/wrangling-wcs i complete what i needed to do with datum csys. Thanks

I'm glad to hear that you got it worked out. I'd like to add a few things that may help you (or a future thread reader). You can find features of a given type (or with a given name) using code similar to that found in:
http://nxjournaling.com/content/nxopenfeaturesfeature-and-feature-collec...

You can get the components (planes, axes, csys, and point) of a datum csys feature with code similar to this:
http://nxjournaling.com/content/how-select-datum-coordinate-system-features

or this:
http://www.eng-tips.com/viewthread.cfm?qid=363348

Once you have a reference to the csys of the datum csys feature, the code posted originally should work.

That was my problema now, get the name of 1 selected body, i used this code to select 1 body, and get the size in x, y and z but now i needed the name of this body but i always have 1 error on lw.WriteLine(".Name: " & ufs.tostring), i'm doing something wrong but i dont know what. This is a part of the code

Option Strict Off

Imports System
Imports System.IO

Imports NXOpen
Imports NXOpenUI
Imports NXOpen.UI
Imports NXOpen.Utilities
Imports NXOpen.UF

Module NXJournal

Dim ufs As UFSession = UFSession.GetUFSession()
Dim theUfSession As UFSession = UFSession.GetUFSession()

Sub Main()

Dim s As Session = Session.GetSession()
Dim lw As ListingWindow = s.ListingWindow()
Dim a_body As NXOpen.Tag = NXOpen.Tag.Null
Dim csys As NXOpen.Tag = NXOpen.Tag.Null
Dim target As NXOpen.Tag = NXOpen.Tag.Null
Dim blockFeature As NXOpen.Tag = NXOpen.Tag.Null
Dim ufs As UFSession = UFSession.GetUFSession()

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim parentFolder As String = IO.Path.GetDirectoryName(workPart.FullPath)
Dim theUISession As UI = UI.GetUI

Dim min_corner(2) As Double
Dim directions(2, 2) As Double
Dim distances(2) As Double
Dim distances1(2) As Decimal
Dim decimal1(2) As String
Dim decimal2(2) As String

Dim qtd_desb As String = ""
Dim qtd_acab As String = ""
Dim gap_desb As String = ""
Dim gap_acab As String = ""
Dim espe As String = ""

Dim wp As Part = s.Parts.Work
Dim objStreamWriter As StreamWriter

Dim scope As Integer = UFConstants.UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY
Dim response As Integer

Dim view As NXOpen.Tag
Dim cursor(2) As Double
Dim ip As UFUi.SelInitFnT = AddressOf body_init_proc

ufs.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)

'Selecionar o body
Try
ufs.Ui.SelectWithSingleDialog("Body", "Selecionar o body", scope, ip, Nothing, response, a_body, cursor, view)
Finally
ufs.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
End Try

If response <> UFConstants.UF_UI_OBJECT_SELECTED And response <> UFConstants.UF_UI_OBJECT_SELECTED_BY_NAME Then
Exit Sub
Else
ufs.Disp.SetHighlight(a_body, 0)
End If

lw.Open()
lw.WriteLine(".Name: " & ufs.tostring)

'Comprimento em cada direcção
ufs.Csys.AskWcs(csys)
ufs.Modl.AskBoundingBoxExact(a_body, csys, min_corner, directions, distances)

lw.WriteLine("X=" & replace(formatnumber(distances(0),2).ToString,",",".") & ", " & _
"Y=" & replace(formatnumber(distances(1),2).ToString,",",".") & ", " & _
"Z=" & replace(formatnumber(distances(2),2).ToString,",","."))

'... more code

End Sub

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

Dim num_triples As Integer = 1
Dim mask_triples(0) As UFUi.Mask
mask_triples(0).object_type = UFConstants.UF_solid_type
mask_triples(0).object_subtype = UFConstants.UF_solid_body_subtype
mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_BODY

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

Return UFConstants.UF_UI_SEL_SUCCESS

End Function

End Module

Your "ufs" variable references the UFSession object, not the object that the selection function returns. The selection function that you are using returns a "tag" of an object, not the object itself. Below is a line of code that will get the object, given the tag. It looks like the returned tag is named "a_body" in your code.

Dim myObj As TaggedObject = Utilities.NXObjectManager.Get(a_body)

If you know the type of object that will be returned, you can use it in place of "TaggedObject". Once you have a reference to the object, you can use "myObj.Name" to access the name of the object (if it has been assigned a name, otherwise it will return a null reference).

The selection function that you are using allows for some advanced filtering. As such, it can be a bit difficult to work with; for a selection function that is a bit easier to work with see:

http://www.nxjournaling.com/content/adding-interactive-selection-routine...

and

http://www.nxjournaling.com/content/using-mask-triples-selectobject-routine

How can i get the first 5 caracteres of my prt?
For exemple, if the name of my file is A1596_NX_13565, there are a way to get A1596?

If you have a reference to a part, you can use the .Leaf property to get the part name. From there, you can use the .NET string functions to manipulate the string data as you see fit.

dim firstFive as string = myPart.Leaf.SubString(0,5)

https://msdn.microsoft.com/en-us/library/aka44szs(v=vs.110).aspx

https://www.dotnetperls.com/substring-vbnet

The problema it's get the name of prt that i'm working

Dim MyBody As Body = Utilities.NXObjectManager.Get(a_body)
lw.Open()
lw.WriteLine(".Name: " & MyBody.Name)

Regards,

Joe

My code snippet above assumes that "myPart" has been set to reference the part that you are interested in. Is the issue setting this reference? If you currently have a reference to a component, you can get to the part through the .Prototype property:

myPart = myComp.Prototype.OwningPart

If you don't have a reference to a part or component, please post back with what you do have and what you need.

how can i post my code in the square like you do to show my problems?


exemple

With this program i need to click twice in the body then click ok, 1º to get max x,y and z and the 2º to get the name of the body after that it's just click ok go to forward on default values

So i have 2 problems now, the first one it's because i need to click twice in the body, do you can change this to do just 1 click and without click ok at the end?
second problem, i still cant get the name of my prt, the name of my prt is A1596_NX_13565 and the body that i click is 200_01 and i wanted see A1596_200_01 at the end and this still dont work.
can you help me with this?


Option Strict Off

Imports System
Imports System.IO

Imports NXOpen
Imports NXOpenUI
Imports NXOpen.UI
Imports NXOpen.Utilities
Imports NXOpen.UF

Module NXJournal

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

Sub Main()

Dim s As Session = Session.GetSession()
Dim lw As ListingWindow = s.ListingWindow()
Dim a_body As NXOpen.Tag = NXOpen.Tag.Null
Dim csys As NXOpen.Tag = NXOpen.Tag.Null

Dim workPart As Part = theSession.Parts.Work
Dim parentFolder As String = IO.Path.GetDirectoryName(workPart.FullPath)

Dim min_corner(2) As Double
Dim directions(2, 2) As Double
Dim distances(2) As Double
Dim distances1(2) As Decimal
Dim decimal1(2) As String
Dim decimal2(2) As String

Dim qtd_desb As String = ""
Dim qtd_acab As String = ""
Dim gap_desb As String = ""
Dim gap_acab As String = ""
Dim espe As String = ""
Dim Nome As String =""

Dim mySelectedObject As NXObject

Dim wp As Part = s.Parts.Work
Dim objStreamWriter As StreamWriter

Dim scope As Integer = UFConstants.UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY
Dim response As Integer

Dim view As NXOpen.Tag
Dim cursor(2) As Double
Dim ip As UFUi.SelInitFnT = AddressOf body_init_proc

ufs.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)

'Select a body to get max X, Y and Z
Try
ufs.Ui.SelectWithSingleDialog("Body", "Select a body", scope, ip, Nothing, response, a_body, cursor, view)
Finally
ufs.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
End Try

If response <> UFConstants.UF_UI_OBJECT_SELECTED And response <> UFConstants.UF_UI_OBJECT_SELECTED_BY_NAME Then
Exit Sub
Else
ufs.Disp.SetHighlight(a_body, 0)
End If

ufs.Csys.AskWcs(csys)
ufs.Modl.AskBoundingBoxExact(a_body, csys, min_corner, directions, distances)

'Select a body to get the name of the body and click ok
Do Until SelectAnObject("Select 1 Body", mySelectedObject) = Selection.Response.Cancel
Nome = mySelectedObject.Name.ToString
Loop

'Nº ele des
Do
qtd_desb = NXInputBox.GetInputString("Num Des?", "Nº desb", "1")
If qtd_desb = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

'Nº ele aca
Do
qtd_acab = NXInputBox.GetInputString("Num Aca?", "Nº Acab", "1")
If qtd_acab = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

'GAP des
Do
gap_desb = NXInputBox.GetInputString("GAP Des?", "GAP desb", "0.50")
If gap_desb = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

'GAP aca
Do
gap_acab = NXInputBox.GetInputString("GAP Aca?", "GAP acab", "0.30")
If gap_acab = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

'Mirror
Do
espe = NXInputBox.GetInputString("Mirror?", "Mirror?", " ")
If espe = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

Dim myStartObject As CoordinateSystem = theSession.Parts.Work.WCS.CoordinateSystem

Dim startPoint As Point3d = myStartObject.Origin
Dim startOrientation As NXMatrix = myStartObject.Orientation

Dim foundEnd As Boolean = False

Dim endPoint As Point3d
Dim rotationAboutX As Double
Dim rotationAboutY As Double
Dim rotationAboutZ As Double

' Distances and rotation between ele csys and main body csys
For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If myFeature.GetFeatureName = "Datum Coordinate System(0)" Then
Dim csysTag As Tag
Dim originTag As Tag
Dim daxesTags(2) As Tag
Dim dplanesTags(2) As Tag

theUfSession.Modl.AskDatumCsysComponents(myFeature.Tag, csysTag, originTag, daxesTags, dplanesTags)
Dim theCsys As CoordinateSystem = Utilities.NXObjectManager.Get(csysTag)

endPoint = theCsys.Origin

Dim endOrientation As NXMatrix = theCsys.Orientation

Dim fromOrigin() As Double = {startPoint.X, startPoint.Y, startPoint.Z}
Dim fromXAxis() As Double = {startOrientation.Element.Xx, startOrientation.Element.Xy, startOrientation.Element.Xz}
Dim fromYAxis() As Double = {startOrientation.Element.Yx, startOrientation.Element.Yy, startOrientation.Element.Yz}

Dim toOrigin() As Double = {endPoint.X, endPoint.Y, endPoint.Z}
Dim toXAxis() As Double = {endOrientation.Element.Xx, endOrientation.Element.Xy, endOrientation.Element.Xz}
Dim toYAxis() As Double = {endOrientation.Element.Yx, endOrientation.Element.Yy, endOrientation.Element.Yz}

Dim mtx4Transform(15) As Double

theUfSession.Mtx4.CsysToCsys(fromOrigin, fromXAxis, fromYAxis, toOrigin, toXAxis, toYAxis, mtx4Transform)

RotationAngles(mtx4Transform, rotationAboutX, rotationAboutY, rotationAboutZ)

foundEnd = True
Exit For
End If
Next

If Not foundEnd Then
lw.WriteLine("End csys not found")
Return
End If

' Get the name of PRT
Dim MyBody As Body = Utilities.NXObjectManager.Get(a_body)

'Show all values
lw.Open()
lw.WriteLine("")
lw.WriteLine("Name of the PRT: " & MyBody.Name) 'just to check if show the name

lw.WriteLine("")
lw.WriteLine("A1596_" & Nome )

lw.WriteLine("X=" & replace(formatnumber(distances(0),2).ToString,",",".") & ", " & _
"Y=" & replace(formatnumber(distances(1),2).ToString,",",".") & ", " & _
"Z=" & replace(formatnumber(distances(2),2).ToString,",","."))
lw.WriteLine("Qtd des: " & qtd_desb)
lw.WriteLine("Qtd aca: " & qtd_acab)
lw.WriteLine("Gap des: " & gap_desb)
lw.WriteLine("Gap aca: " & gap_acab)
lw.WriteLine("Mirror: " & espe)
lw.WriteLine("X= " & replace(formatnumber((endPoint.X - startPoint.X),2).ToString,",",".") & ", " & _
"Y= " & replace(formatnumber((endPoint.Y - startPoint.Y),2).ToString,",",".") & ", " & _
"Z= " & replace(formatnumber((endPoint.Z - startPoint.Z),2).ToString,",",".") & ", " & _
"C= " & replace(formatnumber((rotationAboutY.ToString),2).ToString,",","."))

' Write in the TXT
objStreamWriter = New StreamWriter(parentFolder & "\2D\COTAS\" & Nome & ".txt")

End Sub

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

Dim num_triples As Integer = 1
Dim mask_triples(0) As UFUi.Mask
mask_triples(0).object_type = UFConstants.UF_solid_type
mask_triples(0).object_subtype = UFConstants.UF_solid_body_subtype
mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_BODY

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

Return UFConstants.UF_UI_SEL_SUCCESS

End Function

Function SelectAnObject(prompt As String, ByRef selObj As NXObject) As Selection.Response

Dim theUI As UI = UI.GetUI
Dim cursor As Point3d
Dim typeArray() As Selection.SelectionType = {Selection.SelectionType.All, Selection.SelectionType.Faces, _
Selection.SelectionType.Edges, Selection.SelectionType.Features}

Dim resp As Selection.Response = theUI.SelectionManager.SelectObject( prompt, "Selection", _
Selection.SelectionScope.AnyInAssembly, False, typeArray, selobj, cursor)

If resp = Selection.Response.ObjectSelected Or _
resp = Selection.Response.ObjectSelectedByName Then
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

Sub RotationAngles(ByVal mtx4x4() As Double, ByRef RX1 As Double, ByRef RY1 As Double, ByRef RZ1 As Double)

'extract euler angles from rotation matrix:

Dim rotationMatrix(8) As Double
theUfSession.Mtx4.AskRotation(mtx4x4, rotationMatrix)

Dim c1, c2, s1 As Double

RX1 = Math.Atan2(rotationMatrix(7), rotationMatrix(8))
c2 = Math.Sqrt(rotationMatrix(0) ^ 2 + rotationMatrix(3) ^ 2)
RY1 = Math.Atan2(-rotationMatrix(6), c2)
s1 = Math.Sin(RX1)
c1 = Math.Cos(RX1)
RZ1 = Math.Atan2(s1 * rotationMatrix(2) - c1 * rotationMatrix(1), c1 * rotationMatrix(4) - s1 * rotationMatrix(5))

'convert angles from radians to degrees
RX1 *= (180 / Math.PI)
RY1 *= (180 / Math.PI)
RZ1 *= (180 / Math.PI)

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

GetUnloadOption = UFConstants.UF_UNLOAD_IMMEDIATELY

End Function

End Module

If you are working with Teamcenter and want the name of the current work part, Alto Joe's solution should work just fine for you.

If you are working with native NX (no Teamcenter), you can get the full path of the work part with:

workPart.FullPath

This will return a string representing the full path of the work part that you can assign to a variable or use in your program.

If you want the name of the work part without the path information or file extension, you can use the .Leaf property.

workpart.Leaf

If you want to get the name of the file that owns the selected body, you can do that too. The selection function in your code returns the Tag of the body, you can use the tag to get the Body object and use the Body object to get the OwningPart:

dim selectedBody as Body = NXOpen.Utilities.NXObjectManager.Get(a_body)
dim bodyOwningPart as Part
if selectedBody.IsOccurrence then
bodyOwningPart = selectedBody.Prototype.OwningPart
else
bodyOwningPart = selectedBody.OwningPart
end if

Now that you have a reference to the part that owns the body, you can use the .FullPath or .Leaf properties to get the part path/name.

dim firstFive as string = bodyOwningPart.Leaf.Substring(0,5)

Now you can use one click. The line
Dim PartName As String = workPart.GetStringAttribute("DB_PART_NAME")
will give you the Name of the Part, If it is not giving, In assembly navigator right click on part and go to properties. In that see which title gives you the part name and replace "DB_PART_NAME" with that. If you want only first five letters of your part name use this line to trim.

PartName = Left(PartName, 5)

Option Strict Off

Imports System
Imports System.IO

Imports NXOpen
Imports NXOpenUI
Imports NXOpen.UI
Imports NXOpen.Utilities
Imports NXOpen.UF

Module NXJournal

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

Sub Main()

Dim lw As ListingWindow = theSession.ListingWindow()
Dim a_body As NXOpen.Tag = NXOpen.Tag.Null
Dim csys As NXOpen.Tag = NXOpen.Tag.Null
lw.Open()
Dim workPart As Part = theSession.Parts.Work
Dim PartName As String = workPart.GetStringAttribute("DB_PART_NAME")
lw.WriteLine("Part Name is " & PartName)
Dim parentFolder As String = IO.Path.GetDirectoryName(workPart.FullPath)

Dim min_corner(2) As Double
Dim directions(2, 2) As Double
Dim distances(2) As Double
Dim distances1(2) As Decimal
Dim decimal1(2) As String
Dim decimal2(2) As String

Dim qtd_desb As String = ""
Dim qtd_acab As String = ""
Dim gap_desb As String = ""
Dim gap_acab As String = ""
Dim espe As String = ""
Dim Name As String = ""

Dim mySelectedObject As NXObject = Nothing

Dim wp As Part = theSession.Parts.Work
Dim objStreamWriter As StreamWriter

'Select a body Forcalculating Boundbox
Dim MyBody As Body = Nothing
If SelectBody("select a body", MyBody) = Selection.Response.Cancel Then
Return
End If
a_body = MyBody.Tag

ufs.Csys.AskWcs(csys)
ufs.Modl.AskBoundingBoxExact(a_body, csys, min_corner, directions, distances)

'Nº ele des
Do
qtd_desb = NXInputBox.GetInputString("Num Des?", "Nº desb", "1")
If qtd_desb = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

'Nº ele aca
Do
qtd_acab = NXInputBox.GetInputString("Num Aca?", "Nº Acab", "1")
If qtd_acab = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

'GAP des
Do
gap_desb = NXInputBox.GetInputString("GAP Des?", "GAP desb", "0.50")
If gap_desb = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

'GAP aca
Do
gap_acab = NXInputBox.GetInputString("GAP Aca?", "GAP acab", "0.30")
If gap_acab = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

'Mirror
Do
espe = NXInputBox.GetInputString("Mirror?", "Mirror?", " ")
If espe = "" Then Exit Sub
Loop Until qtd_desb.Trim.Length > 0

Dim myStartObject As CoordinateSystem = theSession.Parts.Work.WCS.CoordinateSystem

Dim startPoint As Point3d = myStartObject.Origin
Dim startOrientation As NXMatrix = myStartObject.Orientation

Dim foundEnd As Boolean = False

Dim endPoint As Point3d
Dim rotationAboutX As Double
Dim rotationAboutY As Double
Dim rotationAboutZ As Double

' Distances and rotation between ele csys and main body csys
For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If myFeature.GetFeatureName = "Datum Coordinate System(0)" Then
Dim csysTag As Tag
Dim originTag As Tag
Dim daxesTags(2) As Tag
Dim dplanesTags(2) As Tag

theUfSession.Modl.AskDatumCsysComponents(myFeature.Tag, csysTag, originTag, daxesTags, dplanesTags)
Dim theCsys As CoordinateSystem = Utilities.NXObjectManager.Get(csysTag)

endPoint = theCsys.Origin

Dim endOrientation As NXMatrix = theCsys.Orientation

Dim fromOrigin() As Double = {startPoint.X, startPoint.Y, startPoint.Z}
Dim fromXAxis() As Double = {startOrientation.Element.Xx, startOrientation.Element.Xy, startOrientation.Element.Xz}
Dim fromYAxis() As Double = {startOrientation.Element.Yx, startOrientation.Element.Yy, startOrientation.Element.Yz}

Dim toOrigin() As Double = {endPoint.X, endPoint.Y, endPoint.Z}
Dim toXAxis() As Double = {endOrientation.Element.Xx, endOrientation.Element.Xy, endOrientation.Element.Xz}
Dim toYAxis() As Double = {endOrientation.Element.Yx, endOrientation.Element.Yy, endOrientation.Element.Yz}

Dim mtx4Transform(15) As Double

theUfSession.Mtx4.CsysToCsys(fromOrigin, fromXAxis, fromYAxis, toOrigin, toXAxis, toYAxis, mtx4Transform)

RotationAngles(mtx4Transform, rotationAboutX, rotationAboutY, rotationAboutZ)

foundEnd = True
Exit For
End If
Next

If Not foundEnd Then
lw.WriteLine("End csys not found")
Return
End If

'Show all values

lw.WriteLine("")
lw.WriteLine(PartName & "_" & Name)

lw.WriteLine("X=" & Replace(FormatNumber(distances(0), 2).ToString, ",", ".") & ", " & _
"Y=" & Replace(FormatNumber(distances(1), 2).ToString, ",", ".") & ", " & _
"Z=" & Replace(FormatNumber(distances(2), 2).ToString, ",", "."))
lw.WriteLine("Qtd des: " & qtd_desb)
lw.WriteLine("Qtd aca: " & qtd_acab)
lw.WriteLine("Gap des: " & gap_desb)
lw.WriteLine("Gap aca: " & gap_acab)
lw.WriteLine("Mirror: " & espe)
lw.WriteLine("X= " & Replace(FormatNumber((endPoint.X - startPoint.X), 2).ToString, ",", ".") & ", " & _
"Y= " & Replace(FormatNumber((endPoint.Y - startPoint.Y), 2).ToString, ",", ".") & ", " & _
"Z= " & Replace(FormatNumber((endPoint.Z - startPoint.Z), 2).ToString, ",", ".") & ", " & _
"C= " & Replace(FormatNumber((rotationAboutY.ToString), 2).ToString, ",", "."))

' Write in the TXT
objStreamWriter = New StreamWriter(parentFolder & "\2D\COTAS\" & Name & ".txt")

End Sub

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

Dim num_triples As Integer = 1
Dim mask_triples(0) As UFUi.Mask
mask_triples(0).object_type = UFConstants.UF_solid_type
mask_triples(0).object_subtype = UFConstants.UF_solid_body_subtype
mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_BODY

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

Return UFConstants.UF_UI_SEL_SUCCESS

End Function

Function SelectBody(ByVal prompt As String, ByRef selObj As TaggedObject) As Selection.Response

Dim theUI As UI = UI.GetUI
Dim title As String = "Select a solid body"
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.AnyInAssembly
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_solid_type
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
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
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

Sub RotationAngles(ByVal mtx4x4() As Double, ByRef RX1 As Double, ByRef RY1 As Double, ByRef RZ1 As Double)

'extract euler angles from rotation matrix:

Dim rotationMatrix(8) As Double
theUfSession.Mtx4.AskRotation(mtx4x4, rotationMatrix)

Dim c1, c2, s1 As Double

RX1 = Math.Atan2(rotationMatrix(7), rotationMatrix(8))
c2 = Math.Sqrt(rotationMatrix(0) ^ 2 + rotationMatrix(3) ^ 2)
RY1 = Math.Atan2(-rotationMatrix(6), c2)
s1 = Math.Sin(RX1)
c1 = Math.Cos(RX1)
RZ1 = Math.Atan2(s1 * rotationMatrix(2) - c1 * rotationMatrix(1), c1 * rotationMatrix(4) - s1 * rotationMatrix(5))

'convert angles from radians to degrees
RX1 *= (180 / Math.PI)
RY1 *= (180 / Math.PI)
RZ1 *= (180 / Math.PI)

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

GetUnloadOption = UFConstants.UF_UNLOAD_IMMEDIATELY

End Function

End Module

Regards,

Joe

Hello
I was a litle busy but now i returned to this litle project.

As you can see, i initialized the variable "Name" that was to get the FeatureName of the body that was selected, so after


'Select a body Forcalculating Boundbox
Dim MyBody As Body = Nothing
If SelectBody("select a body", MyBody) = Selection.Response.Cancel Then
Return
End If
a_body = MyBody.Tag

i used Name = MyBody. (...) , but everything that i used there, always said that wasn't a member of NXOpen.Body, i already included "Imports NXOpen.Features" and still nothing.
So, what i need to put there to get the FeatureName of the selected Body?

When you have a reference to a body object, you can use the .GetFeatures method to get an array of features that are used to construct the body.

thanks, it's working well but now i changed a litle my program to measure all bodys at same time, the problem is that i have 1 csys for each body, because few bodys are rotated, so i need to active the csys of each body before use .AskBoundingBoxExact.
How can i active a csys using their names?

If your part has single CSYS for all the bodies you can follow this method for taking the CSYS with respect to the part which the body belongs.

Dim MyBodypart As Part = Mybody.OwningPart
Dim MyCsyslist As List(Of CoordinateSystem) = New List(Of CoordinateSystem)
For Each Mycsys As CoordinateSystem In MyBodypart.CoordinateSystems
MyCsyslist.Add(Mycsys)
Next

If MyCsyslist.Count = 1 Then
csys = MyCsyslist(0).Tag
Else
'Here you can add user selection csys if you want
MsgBox("Part have more than one CSYS to proceed taking First CSYS to proceed ")
csys = MyCsyslist(0).Tag
End If

Regards,

Joe

No, i have always few csys and bodys in each part.
I tried change your code to do with more csys but i'm blocked now because each csys only have FeatureName, dont have any name

Do you need to get the csys based on the datum csys feature name? If so, you can iterate through the features looking for the datum csys feature with the required name; once you have that, you can get the csys of the datum csys feature.

Or do you have a different requirement in mind?

No,i dont need a to create a csys, i have few csys, 1 or 2 for each body, the problem is when i measure the bodys with .AskBoundingBoxExact, i need to measure with the csys of each body, the problem is that i dont know active 1 csys, i just want select 1 csys by Feat

I'm not suggesting that you create another csys. I'm asking if you have a datum csys feature and if so, if you know the name of the feature that you need to use. If you have a datum csys feature with a given name, you can find it in the feature collection, get its csys, and use it for the bounding box function.

Thats the problem, i dont have the name, only the feature name

In that case, go back and carefully read my response with the "11:19" timestamp. Below is a link to some code that shows how to iterate through the feature collection and query the feature names.

http://nxjournaling.com/content/nxopenfeaturesfeature-and-feature-collec...

And the code in the link below shows 2 different ways to get the csys object of the datum csys feature:

http://www.eng-tips.com/viewthread.cfm?qid=363348

Sorry, i didn't explain myself

I want convert 1 csys in WCS
In this code, the csys of each body have the same name of the body plus "_1"


If SelectBody("select a body", MyBody) = Selection.Response.Cancel Then
Return
End If
a_body = MyBody.Tag

For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If myFeature.tag = MyBody.getfeatures(0).tag.tostring Then
Name = myFeature.Name
End If
Next
For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If Name + "_1" = myFeature.name Then
csys = myFeature.Tag
lw.WriteLine("Name: " & myFeature.name)
lw.WriteLine("csys: " & csys)
End If
Next

ufs.Csys.AskWcs(csys)
ufs.Modl.AskBoundingBoxExact(a_body, csys, min_corner, directions, distances)

But first i need to make WCS from the csys of the body, so after that i can do .AskBoundingBoxExact
I think that is with displayPart.WCS.SetCoordinateSystemCartesianAtCsys but i dont know how to do that

You don't need to make it wcs to calculate bounding box. You already tagged in
csys = myFeature.Tag 'line
Just remove
ufs.Csys.AskWcs(csys) 'line
from your script.

Regards,

Joe

csys = myFeature.tag and ufs.Csys.AskWcs(csys) have diferente values with the same csys so when i run the code, say that "the record area asked for does not exist this object"

This is a part of the code:


Option Strict Off

Imports System
Imports System.IO

Imports NXOpen
Imports NXOpen.Features
Imports NXOpenUI
Imports NXOpen.UI
Imports NXOpen.Utilities
Imports NXOpen.UF

Module NXJournal

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

Sub Main()

Dim lw As ListingWindow = theSession.ListingWindow()
Dim a_body As NXOpen.Tag = NXOpen.Tag.Null
Dim csys As NXOpen.Tag = NXOpen.Tag.Null

Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display

Dim PartName As String = workPart.GetStringAttribute("NAME")
Dim parentFolder As String = IO.Path.GetDirectoryName(workPart.FullPath)

Dim min_corner(2) As Double
Dim directions(2, 2) As Double
Dim distances(2) As Double
Dim distances1(2) As Decimal

Dim Name As String =""

Dim mySelectedObject As NXObject

Dim wp As Part =theSession.Parts.Work
Dim objStreamWriter As StreamWriter

Dim MyBody As Body = Nothing

lw.open()
lw.WriteLine("")

'Get the body
If SelectBody("select a body", MyBody) = Selection.Response.Cancel Then
Return
End If
a_body = MyBody.Tag

'Get the name of the body
For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If myFeature is MyBody.getfeatures(0) Then
name = myFeature.Name
End If
Next

'Get the csys of the body
For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
'lw.WriteLine("Name of csys: " & myfeature.tag.tostring)
If name + "_1" = myFeature.name Then

'csys = myFeature.Tag

'lw.WriteLine("myFeature.tag: " & csys.tostring)
End If
Next

ufs.Csys.AskWcs(csys)
'lw.WriteLine("ufs.Csys.AskWcs(csys)" & csys)

ufs.Modl.AskBoundingBoxExact(a_body, csys , min_corner, directions, distances)

'show the outputs
lw.Open()
lw.WriteLine("")
lw.WriteLine(PartName & "_" & Name )
lw.WriteLine("")
lw.WriteLine("X=" & replace(formatnumber(distances(0),2).ToString,",",".") & ", " & _
"Y=" & replace(formatnumber(distances(1),2).ToString,",",".") & ", " & _
"Z=" & replace(formatnumber(distances(2),2).ToString,",","."))

End Sub

Function SelectBody(ByVal prompt As String, ByRef selObj As TaggedObject) As Selection.Response

Dim theUI As UI = UI.GetUI
Dim title As String = "Select a solid body"
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.AnyInAssembly
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_solid_type
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
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
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer

GetUnloadOption = UFConstants.UF_UNLOAD_IMMEDIATELY

End Function

End Module

So when i select 1 body, i wanted make the csys associated to that body in WCS and after that measure, but this code dont change the wcs

Its solve with this follow code, thanks for all your help, final it's done


Dim csysTag As Tag
Dim originTag As Tag
Dim daxesTags(2) As Tag
Dim dplanesTags(2) As Tag

theUfSession.Modl.AskDatumCsysComponents(myFeature.Tag, csysTag, originTag, daxesTags, dplanesTags)
Dim theCsys As CoordinateSystem = Utilities.NXObjectManager.Get(csysTag)
displayPart.WCS.SetCoordinateSystemCartesianAtCsys(theCsys)

A couple of suggestions:

1) If you have a reference to a datum csys feature, you can use its .SetWcsAtCsys method to move the WCS to the csys of the datum csys feature. Using this method might simplify your current code a little (it would eliminate the call to .AskDatumCsysComponents and the related variables).

OR

2) Once you have the csys of the datum csys feature (it is returned from the .AskDatumCsysComponents method), you can pass that csys into the .AskBoundingBoxExact method; it is not necessary to move the WCS.

It's much more easy with the 2º, on the 1º i didnt find so much information about .SetWcsAtCsys() on internet.
Thank you

But now i tried to do with all bodys at same time without have to click on each body, but i have na error saying "the first parameter passed in was invalid"


For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()

If myFeature.FeatureType = "BREP" Then

name = myFeature.Name.ToString

For Each NCsys As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If nome + "_1" = NCsys.name Then

Dim csysTag As Tag
Dim originTag As Tag
Dim daxesTags(2) As Tag
Dim dplanesTags(2) As Tag

theUfSession.Modl.AskDatumCsysComponents(NCsys.Tag, csysTag, originTag, daxesTags, dplanesTags)
ufs.Modl.AskBoundingBoxExact(myFeature.tag, csysTag, min_corner, directions, distances)

End If
Next

Does the error message indicate which line of code is throwing the error? If so, could you post that information?

At a guess, I'd say the .AskDatumCsysComponents is throwing the error because you are passing in an object of type "Features.Feature" rather than a "Features.DatumCsys". If this is the case, you will need to cast the feature to the proper type for the method to process it. The code snippet below shows one way of doing it.

For Each NCsys As Features.Feature In theSession.Parts.Work.Features
If TypeOf (NCsys) Is Features.DatumCsys Then
If name & "_1" = NCsys.Name Then
Dim myDatumCsysFeature As Features.DatumCsys = NCsys
'get csys components of datum csys feature
'calculate bounding box
Else
'datum csys feature name does not match
Continue For
End If

Else
'not a datum csys feature
Continue For
End If
Next

I found that with this code, when i select 1 body, i can get the Brep number and the Body number


If SelectBody("select a body", MyBody) = Selection.Response.Cancel Then
Return
End If
lw.WriteLine("this show the body number: " & MyBody.ToString)
lw.WriteLine("this show the brep number: " & MyBody.getfeatures(0).tostring)

and with this code i can only get the Brep number


For Each myFeature As Features.Feature In theSession.Parts.Work.Features
If myFeature.FeatureType = "BREP" Then
lw.WriteLine("Features: " & myFeature.ToString)
lw.WriteLine("Features.tag: " & myFeature.tag.ToString)
End If
Next

but to use "theUfSession.Modl.AskDatumCsysComponents(Features.Tag, csysTag, originTag, daxesTags, dplanesTags)" i need the Body number and not the Brep number, thats why i have an error saying that "the first parameter passed in was invalid", because i give the wrong number.
There is a way to get the brep number with the 2º code?

In the first case you are using the body's .GetFeatures method to return the feature that creates/contains the body.

In the second case you have a reference to a feature object; in this case, you can use the .GetBodies method to get the body that the feature creates/contains.

NOTE:
The .AskDatumCsysComponents function requires the tag of a datum csys feature to be passed in. If you pass in the tag of a body or BREP feature, you will get an error.

It is solve.
I created an array and inserted all bodys there with a Function AskAllbodies, after that was easy get the body numbers.
Thank you

I have a new question, i know create a feature group and put everything i want inside in the moment that i create that group with:
theUfSession.Modl.CreateSetOfFeature("Pts" , feat_Group.ToArray, i, 1, FGTag)

the problem is when i try create another feature group inside the 1º feature group.
Do you know how?

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

The code here shows how to create empty feature groups within a feature group. Other code in the thread shows how to add features to a feature group. Combining the methods should get what you need.

I saw that code, the problem is that code only create the "main" feature group after have all features groups that will be inside that main, but i already have the "main" feature group and i want create other inside that

The .EditSetMembers method will allow you to edit an existing feature group. I've not tested it yet, but I assume you will need to use .AskAllMembersOfSet to get the existing members, add the new members that you want to the array and pass the updated array to .EditSetMembers.

Dim markId3 As Session.UndoMarkId
markId3 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Add members To Feature Set")

Dim featureGroup1 As Features.FeatureGroup = CType(workPart.Features.FindObject("FEATURE_SET(4)"), Features.FeatureGroup)

Dim members1(0) As Features.Feature
Dim featureGroup2 As Features.FeatureGroup = CType(workPart.Features.FindObject("FEATURE_SET(10)"), Features.FeatureGroup)

members1(0) = featureGroup2
featureGroup1.AddMembersWithRelocation(members1, True, False)

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

Regards,

Joe

ok, i will test on monday, and i will tell you if that worked
Thanks for your help

I dont know what i'm doing wrong, when i run the code for the 1º time, this create 1 group with name "Grps_1" and after that create another Group with name "Groups", after that move the 1º group into the 2º group, but when i run the 2º time this needed to create a "Grps_2" and moved into the group with name "Groups" but this have 1 error on the function EditSetMembers.
Can you see what is wrong with this code?
All i want is every time i run the code, this create 1 new group and move into the group "Groups"


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

Module Module1

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

Sub Main()

Dim toBeGrouped() As Features.Feature = getFeatures
Dim N As double = (toBeGrouped.Length + 1)
Dim List_groups(20) As tag
Dim i As integer = 0
Dim j As integer = 0
Dim FGTag As Tag = Tag.Null
Dim FGITag As Tag = Tag.Null

lw.open()

Dim featuresToGroup As Tag() = Nothing
ufs.Modl.CreateSetOfFeature("Grps_" & N, featuresToGroup, 0, 1, FGITag)

J = 0
For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If myFeature.name = "Groups" Then
J = 1
End If
Next

If J = 0 Then
ufs.Modl.CreateSetOfFeature("Groups", featuresToGroup, 0, 1, FGTag)
lw.WriteLine("Created an group")
Else
For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If myFeature.Name = "Groups" Then
FGTag = myFeature.tag
lw.WriteLine("Group already exist")
End If
Next
End If

ufs.Modl.AskAllMembersOfSet(FGtag, List_groups, i)
lw.WriteLine("length before: " & List_groups.Length)
lw.WriteLine("")

Dim List(i) As tag
For ii As Integer = 0 To i - 1
List(ii) = List_groups(ii)
lw.WriteLine("Add the group to the List(" & ii & ") with tag: " & List(ii))
Next

lw.WriteLine("toBeGrouped.Length: " & toBeGrouped.Length)

List(i) = FGITag

For ii As Integer = 0 To List.Length - 1
lw.WriteLine("List(" & ii & "): " & List(ii))
Next

lw.WriteLine("")
lw.WriteLine("length after: " & List.Length)
lw.WriteLine("")

ufs.Modl.EditSetMembers(FGTag, List, List.length)

End Sub

Function getFeatures

Dim gotFeature As ArrayList = New ArrayList
Dim feats As Features.FeatureCollection = theSession.Parts.Work.Features

For Each feat As Feature In feats

Try
if feat.FeatureType = "FSET" and left(feat.Name,4) = "Grps" Then
gotFeature.add(feat)
End if
Catch ex As Exception
End Try
Next

return gotfeature.ToArray(GetType(Features.Feature))
End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer
Return CType(Session.LibraryUnloadOption.Immediately, Integer)
End Function
End Module

This one works fine for your requirement.

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

Module Module1

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

Sub Main()

Dim toBeGrouped() As Features.Feature = getFeatures
Dim N As Double = (toBeGrouped.Length + 1)
Dim List_groups(20) As tag
Dim i As Integer = 0
Dim j As Integer = 0
Dim FGTag As Tag = Tag.Null
Dim FGITag As Tag = Tag.Null

lw.open()

Dim featuresToGroup As Tag() = Nothing
ufs.Modl.CreateSetOfFeature("Grps_" & N, featuresToGroup, 0, 1, FGITag)
Dim Subgroup As Features.FeatureGroup = Utilities.NXObjectManager.Get(FGITag)
lw.WriteLine(Subgroup.GetType.ToString)
Dim members1(0) As Features.Feature
members1(0) = Subgroup
J = 0
For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If myFeature.name = "Groups" Then
J = 1
End If
Next

If J = 0 Then
ufs.Modl.CreateSetOfFeature("Groups", featuresToGroup, 0, 1, FGTag)
lw.WriteLine("Created an group")
Else
For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If myFeature.Name = "Groups" Then
FGTag = myFeature.tag
lw.WriteLine("Group already exist")
End If
Next
End If

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Add members To Feature Set")

Dim TopLvlGrp As Features.FeatureGroup = Utilities.NXObjectManager.Get(FGTag)
Try
TopLvlGrp.AddMembersWithRelocation(members1, True, False)
Catch ex As Exception
lw.WriteLine("Move Failed")
End Try

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

ufs.Modl.AskAllMembersOfSet(FGTag, List_groups, i)
lw.WriteLine("length before: " & List_groups.Length)
lw.WriteLine("")

'Dim List(i) As Tag
'For ii As Integer = 0 To i - 1
' List(ii) = List_groups(ii)
' lw.WriteLine("Add the group to the List(" & ii & ") with tag: " & List(ii))
'Next

'lw.WriteLine("toBeGrouped.Length: " & toBeGrouped.Length)

'List(i) = FGITag

'For ii As Integer = 0 To List.Length - 1
' lw.WriteLine("List(" & ii & "): " & List(ii))
'Next

'lw.WriteLine("")
'lw.WriteLine("length after: " & List.Length)
'lw.WriteLine("")

'ufs.Modl.EditSetMembers(FGTag, List, List.Length)

End Sub

Function getFeatures()

Dim gotFeature As ArrayList = New ArrayList
Dim feats As Features.FeatureCollection = theSession.Parts.Work.Features

For Each feat As Feature In feats

Try
If feat.FeatureType = "FSET" And left(feat.Name, 4) = "Grps" Then
gotFeature.add(feat)
End If
Catch ex As Exception
End Try
Next

Return gotfeature.ToArray(GetType(Features.Feature))
End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer
Return CType(Session.LibraryUnloadOption.Immediately, Integer)
End Function
End Module

Regards,

Joe

This is all i wanted, i tried used your code but i didnt know how to use

Dim featureGroup1 As Features.FeatureGroup = CType(workPart.Features.FindObject("FEATURE_SET(4)"), Features.FeatureGroup)

but now i see that was more easy that i was expecting.
Realy thank you Joe

Now i'm trying start with drawing, converting the visible body in Drawing, but i dont find anything that can help me to begin, everything that i find, it's so advanced.
Do you know articles or posts for a beginer like me, to learn how to use drawing with journal?

Any one have 1 simple program just click in 1 body and open the drafting with any views.
I just want something to get start

It sounds like you want to select a body then switch to the drafting application. On the surface, this sounds like a pretty simple task; however, due to the various options within NX, it may be simple or difficult depending on exactly what you are asking for.

If you are working in a piece part and the drawing is saved in the same file, this would be really easy. No need to select a body, just switch to the drafting application. However, the general recommended practice is to separate the drawing from the model with each in their own file (aka the master model technique). When using this method, it is common to name the drawing file after the model and add "_dwg". So, if your model file is "12345.prt", the drawing would be "12345_dwg.prt". If you start in the model file and run your journal, it would have to find the corresponding drawing file and switch to the drafting application. This is considerably more difficult than the first scenario, but within the realm of possiblility (if you search this site, you'll find at least one such example). If you are working in the context of an assembly and you select a component body, do you want to switch to the assembly drawing or the drawing for the component part file? If you want the component drawing, where should we look? It may be in the component part file, a separate part file, or detailed as its own sheet in the assembly drawing (or somewhere else entirely, but we'll ignore that option for now).

So, this may not be a "simple" program that you are asking for. If you provide more detail, we may be able to guide you to something useful.

Pages