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
additional dialog to select reference set available in part
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
Wishes a variant of this.
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
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,
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
component to Body
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
re: reference set bodies
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.
Hello again,
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
solid of component
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
Even possible ?
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
Reference Set
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.
re: export assembly
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.
Re: export assembly
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.
Export Assembly
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.
Change refset
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)
Top Level Reference Set
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