Submitted by peter.t on Wed, 01/13/2016 - 04:38
Forums:
Hello,
is there a nice and easy way to get the owning component of a workpart? I have a big assembly as the displayed part and made a component of a sub-assembly the workpart. Now I need to find out to which sub-assembly this part belongs. I tried workPart.OwningComponent but this function does not return anything at all.
Thanks in advance.
re: owning component
An individual part (where the geometry is created and stored) is known as a "prototype" object. When you add this part as a component to an assembly, the component is known as an "occurrence" object. The occurrences (components) link back to the prototype (part file) so that when the part is modified, the components update accordingly. The prototype (part file) has no knowledge of what assemblies use it as a component. As such, you will need to query the assembly to see where the part is used as a component.
However, if you have a reference to a component, it is fairly easy to get the owning assembly part. A component object has a .Parent property that will return a component object that owns this component (it will return null if no part owns it).
This link shows one way of processing all of the components of a given assembly:
http://nxjournaling.com/content/creating-subroutine-process-all-componen...
This code could be modified to test each component to see if the prototype is the same as the work part. Something like:
if child.Prototype.OwningPart.Equals(workPart) then
'this component is an occurrence of the work part
'query its parent
end if
re: re: owning component
I tried this code. It works but it may return the wrong parent component if the workpart-prototype is used in more than one subassembly. Any ideas how to get it right?
Public Function getWorkPartParent() As Component
Dim c As ComponentAssembly = displayPart.ComponentAssembly
reportComponentChildren(c.RootComponent, 0)
Return publicWorkComp
End Function
Sub reportComponentChildren(ByVal comp As Component, ByVal indent As Integer)
For Each child As Component In comp.GetChildren()
If child.Prototype.OwningPart.Equals(workPart) Then
publicWorkComp = child.Parent
Exit Sub
End If
reportComponentChildren(child, indent + 1)
Next
End Sub
re: owning assembly
To find the parent assembly, you will need to start with a component reference. Assemblies own component occurrences, they do not own parts. You'll need to get a reference to the component of interest and go from there.
The code above can tell you all of the parts that own a component occurrence of a given part; that's about the best you can do if your starting point is a part reference.
What workflow are you trying to automate? There may be a fairly easy way to get there. For instance, if the user selects a body occurrence in the assembly, you can query it to see what component it belongs to and what parent assembly owns that component reference.
re: re: owning assembly
Thanks for your advice. I was afraid there was no "easy" way to get the owning assembly since NX does not know the exact component occurrence I am searching for when I made it a work part.
I made a journal that allows you to perform various "Save As"-Actions for example saving a part with a higher revision or saving a part with a different name. There are options to save (or copy) the drawing, too (in native NX) and not replace or replace the old part in the displayed assembly. I created a WinForm and a user-defined Button to run this journal and it works great. I could post the code if you're interested...
The problem however is when the user wants to save the work part with a different name and NOT replace every instance in the session but only in the assembly it is directly subordinated to. To use ReplaceComponentBuilder I have to know the exact component occurrence and the assembly it belongs to.
re: owning assembly
Is your code running when the user changes the work part? If so, you should be able to get a reference to the chosen component.
If the work part is changed before your code is called, perhaps the form could show all the assemblies that use that part as a component and prompt the user to select which one(s) to replace the component.
There is a "change work part" user exit that you should be able to take advantage of if you have a development license. Once you register your code properly with NX, it will execute the code whenever that event happens in NX. Perhaps your code could take advantage of this directly, or perhaps there would be a "helper" program that somehow records or saves a reference to the component chosen in the change work part event. Your main program could then query the last component chosen to be the work part for its operations. According the the NX help, the "change work part" exit should fire "before a Component is chosen or when the work part is about to be changed from any other explicit user interface entry point ".
User code submissions are always welcome!
If you email it to me (info@nxjournaling.com) along with a short explanation of its intended use, I'll post it as an article on the site. There will be a link to it on the front page (until newer articles eventually bump it down).
re: re: owning assembly
The code is called after changing the work part and unfortunately we don't have a development license.
I decided to let the user choose a new option called "save selected part as and replace in assembly" when a component is selected. Once NX knows the selected component it is fairly easy to trace the assembly.
I'll send you an e-mail once I finished debugging. Thanks for your help! Here's the code to get the selected components assembly:
Public Function getCompParent(ByVal comp As Component) As Component
Return comp.OwningComponent
End Function
Public Function getSelectedComp() As Component
' Abfrage ob ein Teil selektiert ist
Dim intNumSelected As Integer = theUI.SelectionManager.GetNumSelectedObjects()
If intNumSelected = 0 Then Exit Function
Dim SelectedList As New List(Of Component)
For i As Integer = 0 To intNumSelected - 1
Dim intType As Integer
Dim intSubType As Integer
Dim objSelected As NXObject = theUI.SelectionManager.GetSelectedObject(i)
theUFS.Obj.AskTypeAndSubtype(objSelected.Tag, intType, intSubType)
If intType = UFConstants.UF_component_type Then
Dim theComp As Component = DirectCast(objSelected, Component)
If inList(theComp, SelectedList) = False Then SelectedList.Add(theComp)
End If
Next
If SelectedList.Count = 1 Then
Return SelectedList.Item(0)
Else
theUISession.NXMessageBox.Show("Fehler", NXOpen.NXMessageBox.DialogType.Error, "Mehr als eine oder keine Komponente ausgewählt!")
End If
End Function
Public Function inList(ByVal comp As Component, ByVal l As List(Of Component)) As Boolean
For x As Integer = 0 To l.Count - 1
If l.Item(x).DisplayName = comp.DisplayName Then
Return True
Exit For
End If
Next
End Function
re: inList function
The inList function should return False if the component is not found. Also, you can use the .Contains method of the list object to simplify the code a bit.
Public Function inList(ByVal comp As Component, ByVal l As List(Of Component)) As Boolean
If l.Contains(comp) then
Return True
Else
Return False
End if
End Function
List versus HashSet
If you use a HashSet rather than a List, you don't need the InList function. Each item in a HashSet occurs exactly once. When you add an item, the Add function checks to see if that item is already present.
Start with Single Component as Displayed Part
I am not sure if I am following this post correctly but it seems like you need to start with the assembly or sub assembly as the displayed part and the component file as the work part. I am trying to start with a single component part as the displayed part and the owning assembly or assemblies are loaded in the current session. Would it be possible to search all of the parts in the current session and get a list of the owning assemblies of the currently displayed component? This would be the same list as shown when the part is right clicked and "Display Parent" is selected.
re: parent of part
"Would it be possible to search all of the parts in the current session and get a list of the owning assemblies of the currently displayed component?"
Yes this is possible.
There is some code posted on the eng-tips website by user CNSZU that may be of interest to you.
http://www.eng-tips.com/viewthread.cfm?qid=351100
http://www.eng-tips.com/viewthread.cfm?qid=351988
Owning Component Of Workpart
How about
Session.GetSession().Parts.WorkComponent
The API reference says
"This is the component in the displayed part's NXOpen.Assemblies.ComponentAssembly which represents the current work part. "
Component has object
Hello,
What is the line code that recognizes if the component of the assembly (children no assemblies or subassemblies) is empty with no object or body or displayableobject for example
Public Sub AddComponentsToList(ByRef Father As Component, ByRef compList As ArrayList)
For Each Newchild As Component In Father.GetChildren()
If Newchild.GetChildren.Length = 0
compList.Add(Newchild)
End If
AddComponentsToList(Newchild, compList)
Next
End Sub
What I am looking for is the children only which has no object or no body or no displayableobject.In Other word, empty component.
I found this UF_ASSEM_count_objs_in_comp in NXOPEN user Function and I am not sure if this will help too.
https://docs.plm.automation.siemens.com/data_services/resources/nx/11/nx...
The current example in C language.
https://docs.plm.automation.siemens.com/data_services/resources/nx/11/nx...
Your help is really appreciated.Thank You
Raeed Kena
{Mechanical / Civil Engineer}
re: component has object
I've not used the UF_ASSEM_count_objs_in_comp function, but it looks promising for what you are trying to do. The UF_ASSEM_cycle_objs_in_comp might be a viable alternative. I'm not sure if either of those functions will report components. Some assemblies will have components but no other geometry in the file; don't forget to check for this condition.