Show Reference Set Objects

While working with assemblies in NX, your parts' reference sets can pick up a lot of junk. Ok, maybe the junk is perfectly good and useable geometry, but you often don't want to keep it where NX put it. These extras show up from operations like wave linking, working in context of an assembly, importing/exporting geometry, etc etc. The reference set dialog will gladly tell you how many objects are in a given reference set, but it stubbornly refuses to show you where they are. Wouldn't it be great if reference sets had a command similar to the part navigator's show or show parents?

Below is a journal that will show you all the objects in the reference set. If an object is hidden or on an invisible layer, the object will be shown or the layer will be made visible. When you run the journal, all the objects in the specified reference set will be visible and highlighted. The journal will prompt you to select objects; you can select any new objects to add to the reference set or deselect any objects you no longer want in the reference set. When you press OK, only the currently selected objects will remain in the reference set. There is a line near the beginning of the journal that tells it which reference set to look for, it is currently set to MODEL, a common reference set in NX. If you use a custom reference set, change this line of the journal to the name of your reference set.

[vbnet]
' April 10, 2012
' Purpose: journal to add/remove objects from a certain reference set
' This journal will unblank and/or show the layer for all objects
' in the reference set, this works in a similar manner to the
' "show" or "show parents" command in the part navigator.
' This allows all current members of the reference set to be seen
' to aid in deselection if necessary.
'
' Helpful when the reference set picks up unnecessary objects along the way
' due to working in context of the assembly, exporting temp geometry, wave linking, etc.
'
' Developed and tested on NX 7.5
' www.NXJournaling.com

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UI
Imports NXOpen.UF

Module Select_ref_set

Dim ufs As UFSession = UFSession.GetUFSession()

' These global variables are necessary
Dim init_proc_ref As UFUi.SelInitFnT = AddressOf init_proc_body
Dim refMembers(-1) As NXObject
Dim refMemberTags() As Tag

Dim theSession As Session = Session.GetSession()
Dim lw As ListingWindow = theSession.ListingWindow

Sub Main()

'Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim myReferenceSets As ReferenceSet()
myReferenceSets = workPart.GetAllReferenceSets()
Dim theReferenceSet As ReferenceSet = Nothing

'%%%%%%%%%% Change the following line to point to the name of your reference set %%%%%%%%%%
Const whatRefSet As String = "MODEL"
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Dim stateArray1(0) As Layer.StateInfo
Dim i As Integer

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

lw.Open()
For Each myRefSet As ReferenceSet In myReferenceSets
If myRefSet.Name.ToUpper() = whatRefSet Then
theReferenceSet = myRefSet
refMembers = myRefSet.AskAllDirectMembers()
i = 0
For Each myObject As DisplayableObject In refMembers
myObject.Unblank()
If (myObject.Layer <> 0) And (myObject.Layer <> workPart.Layers.WorkLayer) Then
stateArray1(0).Layer = myObject.Layer
stateArray1(0).State = Layer.State.Selectable
workPart.Layers.ChangeStates(stateArray1, True)
End If
'lw.WriteLine(myObject.GetType.ToString)
ReDim Preserve refMemberTags(i)
refMemberTags(i) = myObject.Tag
i += 1
Next
End If
Next

Dim refSetObjs() As DisplayableObject = select_objects("Select Objects for reference set:")
If refSetObjs IsNot Nothing Then
theReferenceSet.RemoveObjectsFromReferenceSet(theReferenceSet.AskAllDirectMembers())
theReferenceSet.AddObjectsToReferenceSet(refSetObjs)
End If

lw.Close()

theSession.SetUndoMarkName(markId1, "Show Reference Set Objects")
theSession.SetUndoMarkVisibility(markId1, Nothing, Session.MarkVisibility.Visible)

End Sub

Public Function select_objects(ByRef prompt As String) As DisplayableObject()

Dim response As Integer = 0
Dim cnt As Integer = 0
Dim objs() As Tag = Nothing
Dim user_data As System.IntPtr

ufs.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)

Try
ufs.Ui.SelectWithClassDialog("Select Objects: ", prompt, _
UFConstants.UF_UI_SEL_SCOPE_WORK_PART, init_proc_ref, _
user_data, response, cnt, objs)
Finally
ufs.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
End Try

If response <> UFConstants.UF_UI_OK Then
Return Nothing
End If

If cnt = 0 Then
Return Nothing
Else
Dim selObjs(cnt - 1) As DisplayableObject
For ii As Integer = 0 To cnt - 1
ufs.Disp.SetHighlight(objs(ii), 0)
selObjs(ii) = Utilities.NXObjectManager.Get(objs(ii))
Next
Return selObjs
End If
End Function

Public Function init_proc_body(ByVal select_ As IntPtr, _
ByVal userdata As IntPtr) As Integer

'add objects already in reference set to the selection list
'select_ is the pointer to the selection
ufs.Ui.AddToSelList(select_, refMemberTags.Length, refMemberTags, True)

Return UFConstants.UF_UI_SEL_SUCCESS
End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer

'Unloads the image when the NX session terminates
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination

End Function

End Module[/vbnet]

Comments

Hello!
Do you have an extended version of this script to select the reference set available in the active part?
The listed script shows the elements just from one hardcoded reference set.
Thanks for your help.
Kind regards, Martin

Would be nice to have a variant of this which removes objects on a specific layer (101) from the Reference Set (MODEL).
I have tried without luck.

Best Regards
Gunnar

I think this thread moved away from my question.
Even though it is interesting to see the different questions and suggestions I cannot see that it is a solution for me.
How could I get the code to remove objects on a specific layer from the reference set?

Best Regards
Gunnar

Hello,

This refers to gunnars post before and also has a new question. I made a script that selects all bodies of a certain reference-set with a layer-check. Maybe it helps a little bit.

Everything was fine until i tried to process an assembly. If the script runs with an assembly it will select bodies, but only on the actual level of the reference set. It is not selecting the bodies the levels below, even if they are included in the reference set of the assembly part.

Why doesn't help display part in this case? Does someone know what i am doing wrong and can give me a hint what to change to get the solids of the assembly ( including the lower parts) as well?

Thank you and best regards

(Const RefSet As String = "MODEL")

Public Function SelectBodyRefset

Dim theSession As NXOpen.Session = NXOpen.Session.GetSession()
Dim displayPart As NXOpen.Part = theSession.Parts.Display

Dim myReferenceSets As ReferenceSet()
myReferenceSets = displayPart.GetAllReferenceSets()
Dim theReferenceSet As ReferenceSet = Nothing

For Each myRefSet As ReferenceSet In myReferenceSets
If myRefSet.Name.ToUpper() = RefSet Then

theReferenceSet = myRefSet
refMembers = myRefSet.AskMembersInReferenceSet()

For Each myObject As DisplayableObject In refMembers
If TypeOf myObject Is Body Then

Dim body As Body = myObject
If Not solid.Layer = 10 Then
nxSelectedObjects.Add(body)
End If

End If
Next
End If
Next

End Function

Figured out that the right approach would be ReferenceSet.AskAllDirectMembers

"Includes solid bodies, facet bodies, miscellaneous entities other than solid and facet bodies and assembly components"

The missing link is how to extract a solid body of a component? Do I have to check the components to the refering parts and do a For loop with the Askallbody-function? I can't get it to run.

Would this be the right approach?

Thank you and best regards

For Each Mycomp As Component In refMembers
Part(Mycomp.OwningPart)
Next

For Each MyBody As Body In AskAllBodies(MyP).ToArray
nxSelectedObjects.Add(MyBody)
Next

Are you starting with the assembly or a component part?
Do you want to get the occurrence bodies in the assembly or the prototype bodies from the part?

Some more information on your overall goal may help to inform the answer.

Thank you for deleting my posts. The starting part is either an assemly or a part. I don't know this information in advance. The selection is used to catch all bodies (sometimes just one) in the reference-set "model" in order to export them together as a stl-File. There are some bodies in the assembly that i do not want to export (casting-cores that do not belong to the actual volume). These bodies are not included in the reference-set. I tried it already with your AskAllBodies-Function with all bodies in the assembly and that works in 99% of the times (when the cores below are on a different layer) But if the top-level contain linked bodies to welding parts that are also on the same layer like the volumes at the top assembly level, the parts below are exported as well (works as designed, see attached code at the end).

I want to get rid of the volumes a stage below that are not included in the reference set. Therefore i tried to cycle through all bodies and components that are defined by the RefSet and grab all bodies of the top level and the root components.

The question is what do I get back from refMembers = myRefSet.AskMembersInReferenceSet()? I would like to get the occurence bodies of the assembly as a listofbodies + the bodies of the features in the part of the top-Level of the assembly (to forward them to stl-Export). I tried already to get the owning parts of the components in the Refset with .OwningPart in order to cycle through the parts to get all bodies in the levels below, but it seems i am on the wrong track?

Hopefully i did not confuse you more. English wasn't my best subject. Best regards from Austria

Current selection at the moment:

For Each solid As Body In AskAllBodies(displayPart)

If Not solid.Layer = 10 Then
nxSelectedObjects.Add(solid)
Next

Function AskAllBodies(ByVal thePart As Part) As Body()
Dim theBodies As New System.Collections.ArrayList()

Dim aBodyTag As Tag = Tag.Null
Do
theUfSession.Obj.CycleObjsInPart(thePart.Tag, _
UFConstants.UF_solid_type, aBodyTag)
If aBodyTag = Tag.Null Then
Exit Do
End If

Dim theType As Integer, theSubtype As Integer
theUfSession.Obj.AskTypeAndSubtype(aBodyTag, theType, theSubtype)
If theSubtype = UFConstants.UF_solid_body_subtype Then
theBodies.Add(theSession.GetObjectManager.GetTaggedObject(aBodyTag))
End If
Loop While True

Return DirectCast(theBodies.ToArray(GetType(Body)), Body())
End Function

Hello,

The .owningpart Method is in fact the wrong attempt. The script below recognises the right amount of components in the reference set. But at the moment i am getting back the top-part of the assembly, where unfortunately all components are processed. This is what I get when I run the script:

object type: NXOpen.Body
object type: NXOpen.Assemblies.Component
OwningPart: Part 123586
object type: NXOpen.Assemblies.Component
OwningPart: Part 123586
object type: NXOpen.Assemblies.Component
OwningPart: Part 123586
object type: NXOpen.Assemblies.Component
OwningPart: Part 123586

Is it possibile to get just all solids of the found NXOpen.Assemblies.Components? Thank you and best regards

For Each myRefSet As ReferenceSet In myReferenceSets
If myRefSet.Name.ToUpper() = RefSet Then
theReferenceSet = myRefSet
refMembers = myRefSet.AskAllDirectMembers()
lw.Open()
For Each myObject As DisplayableObject In refMembers

lw.WriteFullline("object type: " & myObject.GetType.ToString)
If TypeOf myObject Is NXOpen.Body Then
Dim myBody As NXOpen.Body = myObject
nxSelectedObjects.Add(myBody)
ElseIf TypeOf myObject Is NXOpen.Assemblies.Component Then
myPart=(myObject.OwningPart)
lw.WriteFullline("OwningPart: " & myPart.ToString)
For Each mySolid As NXOpen.Body In AskAllBodies(myPart)
nxSelectedObjects.Add(mySolid)
Next
End If
Next
lw.Close()
End If
Next

Hello, I tried to make the parts to a work part and export them after cycling trough the assembly structure. If I add them to the bodycollection, the zero point of the parts switches and all parts are then exported at their original point.

Is it even possible to get just all solids of Components by Displayable Objects or do I just waste my time?

Thank you and best regards

Hi,
why don't you temporarily switch reference set of all components to the one you want and export all bodies (which are occurrences) from top assy level? By body.Prototype.OwningComponent you could get original component only for file naming purposes.

If you are exporting the assembly to STL and want all the components in the assembly position, you will need to export the occurrence bodies (as mentioned by wizdar). The "AskAllBodies" function should get these for you.

I'm not sure what you mean by:
"I want to get rid of the volumes a stage below that are not included in the reference set."
If the body is not in the component's used reference set, it won't show up in the assembly; and therefore should not be returned by the "AskAllBodies" function.

Other possibility as you already have the code for exporting what you need is to transform bodies by orientation matrix of parent component.
By using Component.GetTransform and applying it to each body. But the method to askallbodies.

Cowski? :D : by "getting rid of volumes at stage below", I guess he has more bodies in the prototype part which are members of various reference sets and he want to export only members of one refset.
That's why the easiest method for me would be to switch components to desired refset, and then get visible bodies by askallbodies.

Wizdar is right, there are bodies in the parts below and further subassemblies as well.

What I don't understand is how to "switch components to desired refset". Could you explain that to me with some more detail?

When I use "Askallbodies"-function with the displayed part, all bodies of the subassembly components are selected (also the excluded bodies of the refset).

Is there a possibility to check "abodyTag" whether it is included in the current refset? Am I missing something? Thank you in advance and best regards.

If you see all bodies from Refsets then probably you either have component with Refset "Entire Part" or just a refset than contains more than you want.
If there is a refset that contains what you need, just set the component to the desired Reference Set.
like a code i recorded a while ago:

Dim components1(0) As NXOpen.Assemblies.Component
Dim component1 As NXOpen.Assemblies.Component

components1(0) = component1
Dim errorList1 As NXOpen.ErrorList = Nothing
errorList1 = workPart.ComponentAssembly.ReplaceReferenceSetInOwners("DRAWING", components1)

Thank you for your reply. Sorry for my bad explanation and my bad English. Your suggestion is already included and works fine for subassemblies a level below.

-Top Assembly contains bodies and components
+ Component1 contains bodies and components
+Component11 contains bodies
+Component11 contains bodies
+ Component2 contains bodies (wave-Link to top assy)
+ Component3 contains bodies (wave-Link to top assy)

I want to ged rid of component 2 and 3 (not in refset of top assembly) because the contour is wave-linked and further manufactured in the top assembly. My Problem is to tell Nx that some of the components of the current top level Assembly are not included in a certain reference set. These ones are the parts that i can't manage to seperate. Do I have to supress them before manually or is it possible to neglect them automatically?

Best regards