cancel
Showing results for 
Search instead for 
Did you mean: 

Find promoted Bodies in Assembly

Experimenter
Experimenter

Hello everybody,

 

i am trying to collect all bodies inside a multi-level assembly via NX Open (NX 7.5) for an export (step, igs, whatever). For "normal" bodies my routine is looping over all components and is there then looping over  - depending on the ReferenceSet - either all Bodies of a component ("Entire Part")

For Each bodyItem As Body In componentPart.Bodies
    If layerMaskList.Contains(bodyItem.Layer) Then
          'Do something
    End If
Next

or all direct members of a ReferenceSet

 

 For Each refsetItem As DisplayableObject In refSet.AskAllDirectMembers()
    If layerMaskList.Contains(refsetItem.Layer) Then
       If TypeOf refsetItem Is Body Then
            'Do Something
       End If
   End If                    
Next

 I only have problems with promoted bodies. They are not caught by the routine. On the top level i can catch them by looping the features inside the part:

'loop promoted features
For Each featItem As Feature In thisPart.Features
    If TypeOf featItem Is Promotion Then
        Dim promo As Promotion = CType(featItem, Promotion)
        For Each bodyItem As Body In promo.GetBodies
            If layerMaskList.Contains(bodyItem.Layer) Then
                'Do Something
            End If
        Next
    End If
Next

But on the component level I don't have a clue how to catch their positioned occurence?

Any help or idea?

 

Best regards

 

5 REPLIES

Re: Find promoted Bodies in Assembly

Solution Partner Creator Solution Partner Creator
Solution Partner Creator

Try this:

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

Module NXJournal

    Dim s As session = session.GetSession()
    Dim lw As ListingWindow = s.ListingWindow

    Sub ShowAssemblyTree(ByVal c As Component, ByVal indent As String)
        Dim children As Component() = c.GetChildren()
        Dim newIndent As String
        For Each child As Component In children
            If indent.Length = 0 Then
                newIndent = " "
            Else
                newIndent = indent & " "
            End If
            lw.WriteLine(newIndent & child.DisplayName)
			feat_list(child.Prototype.OwningPart)
'Exit For
            ShowAssemblyTree(child, newIndent)
'Exit For
        Next

    End Sub
	
	Sub feat_list(ByVal p As Part)

        Dim s As Session = Session.GetSession()
        Dim lw As ListingWindow = s.ListingWindow
        Dim ufs As UFSession = UFSession.GetUFSession()
		        Try
            Dim inx As Integer = 0
            'Dim errMsgs() As String
            Dim dispPart As Part = p
            If dispPart.Tag = NXOpen.Tag.Null Then
                Return
            End If

            Dim allFeats As Features.FeatureCollection = dispPart.Features
            lw.Open()
			
			For Each thisFeat As Features.Feature In allFeats
                    'lw.WriteLine(" ")
                    lw.WriteLine("Name: " & thisFeat.GetFeatureName())
                    lw.WriteLine("Type: " & thisFeat.FeatureType())
                    lw.WriteLine("Feat Name: " & thisFeat.Name)
                    'Dim errorcode As Integer = 0
                    'Dim log_message As String()
                    'log_message = thisFeat.GetFeatureInformationalMessages()
                    'lw.WriteLine("log_message: " & log_message(0))
					
					Next
		        Catch ex As Exception
            lw.Open()
            lw.WriteLine("Error: " & ex.GetBaseException.ToString)

        End Try
End Sub

    Sub Main()

        lw.Open()

        If s.Parts.Work Is Nothing Then
            lw.WriteLine("Part file argument expected or work part required")
            Return
        End If

        Try
            Dim part1 As Part

                part1 = s.Parts.Work

            Dim c As Component = part1.ComponentAssembly.RootComponent
            lw.WriteLine(c.DisplayName)
            ShowAssemblyTree(c, "")

        Catch e As Exception
            lw.WriteLine("Failed: " & e.Message)
        End Try
    End Sub
End Module
Attila Szepesi, Application Engineer, graphIT Ltd.
Production: NX11.0.2 | TcUA 11.2 MP2 Patch 1 (11.2.2.1)
Development: VB.NET Testing: NX12.0

Re: Find promoted Bodies in Assembly

Phenom
Phenom

"But on the component level I don't have a clue how to catch their positioned occurence?"

 

 

So you have a reference to a promoted body and now you want to find out which component it came from? If so, you can use the PromotionBuilder object to query the promotion feature in the assembly to find the occurrence body (promotionBuilder.Body.GetArray) and from there get a reference to the component that owns the occurrence body.

 

But for the export operation, I'd guess that you would want to export the promoted body, not the initial body that was promoted...

Re: Find promoted Bodies in Assembly

Phenom
Phenom

Another one to watch out for is "deformed components". These are similar to promoted bodies in that the deformed body is owned by the assembly. The assembly will contain a reference to the component, but there will be no component instance body to be found.

Re: Find promoted Bodies in Assembly

Experimenter
Experimenter

Thank you for your replies cowski,

 

deformed bodies are next on my to do list.

 

Can you tell me how to get a reference to the component that owns the occurrence body?

 

Regarding the PromotionBuilder and .Bodies.GetArray() I thougt with looping the features in the parent component and identifing the Promotion-Features and its bodies, i have already the bodies or will the other way return the occurrence?

Re: Find promoted Bodies in Assembly

Phenom
Phenom

First some terms & definitions so that we are on the same page.

 

Let's imagine that we have a very simple assembly that has one component; the component contains exactly one solid body. When we open the assembly, what we see is an occurrence body. The component owns the occurrence body and the model part file contains the prototype body which defines the occurrence body in the assembly.

 

When we promote that body, NX  creates a copy of it in the assembly file and hides the original from our view. The body that we see on screen is no longer an occurrence; it is owned by the assembly file. Behind the scenes, NX maintains a link between the promoted body and the body in the component that was promoted (the base body). When we highlight the component in the ANT, NX keeps us happy by highlighting the promoted body even though the component no longer technically owns that body.

 

If you have a reference to a promotion feature, you can get a reference to the promoted body (the one owned by the assembly that you see onscreen) by using the feature's .GetBodies method. I've not found a way to get a reference to the component body used in the promotion feature from the promotion feature itself. For that you can use the promotion builder object's .Body property. There are some UF functions that can also get at this information, but I find that using the feature and builder to be fairly straightforward.

 

If you are collecting bodies for an export operation, you will probably want to export the promoted body. It may have additional features added at the assembly level that are not present in the base body.

 

The code below is for illustration, it is by no means bulletproof. It was only tested on simple, single level assemblies.

 

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

Module Module2

    Sub Main()

        Dim theSession As Session = Session.GetSession()
        Dim theUfSession As UFSession = UFSession.GetUFSession()
        If IsNothing(theSession.Parts.BaseWork) Then
            'active part required
            Return
        End If

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

        If Not workPart.Equals(displayPart) Then
            lw.WriteLine("make the top level assembly the work part and re-run the journal")
            Return
        End If

        Const undoMarkName As String = "report promoted body"
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

        For Each temp As Features.Feature In workPart.Features
            If temp.FeatureType <> "PROMOTION" Then
                Continue For
            End If
            Dim thePromotion As Features.Promotion = temp
            lw.WriteLine("name: " & thePromotion.GetFeatureName)

            Dim promBodies() As Body = thePromotion.GetBodies
            '{promotionFeature}.GetBodies will return the body that has been promoted up into the assembly (owned by the assembly part)
            'A single body will be returned.
            'if multiple bodies are selected in the promote body dialog, a separate promote body feature
            '  will be created for each

            lw.WriteLine("  number of promoted bodies: " & promBodies.Length.ToString)
            For Each promBod As Body In promBodies
                lw.WriteLine("    body tag: " & promBod.Tag.ToString)
                lw.WriteLine("    body IsOccurrence: " & promBod.IsOccurrence.ToString)

                If promBod.IsOccurrence Then    'this will return False
                    lw.WriteLine("      owning component: " & promBod.OwningComponent.DisplayName)
                Else
                    lw.WriteLine("    owning part: " & promBod.OwningPart.FullPath)
                End If

                'This will return the tag of the body that was promoted.
                Dim baseTag As Tag = Tag.Null
                theUfSession.Modl.PromMapObjectDown(promBod.Tag, baseTag)
                lw.WriteLine("    base body tag: " & baseTag.ToString)

            Next


            '----------------------------------
            'Find out which component was used for this promote feature.
            Dim promotionBuilder As Features.PromotionBuilder
            promotionBuilder = workPart.Features.CreatePromotionBuilder(thePromotion)

            Dim theBodies() As Body = promotionBuilder.Body.GetArray
            'the body that is being promoted (owned by the component)
            lw.WriteLine("  promotion builder number of bodies: " & promotionBuilder.Body.Size.ToString)
            For Each tempBody As Body In theBodies
                lw.WriteLine("    body IsOccurrence: " & tempBody.IsOccurrence.ToString)
                If tempBody.IsOccurrence Then
                    Dim protoBod As Body = tempBody.Prototype
                    lw.WriteLine("    owning component: " & tempBody.OwningComponent.DisplayName)
                    lw.WriteLine("    parent part: " & tempBody.OwningComponent.Prototype.OwningPart.FullPath)
                    lw.WriteLine("    owning component ref set: " & tempBody.OwningComponent.ReferenceSet)
                    Dim compBodies As New List(Of Body)
                    compBodies = GetCompBodies(tempBody.OwningComponent)
                    lw.WriteLine("    owning component bodies (component bodies in the reference set): ")
                    For Each junk As Body In compBodies
                        lw.WriteLine("      body tag: " & junk.Tag.ToString)
                    Next

                End If
            Next

            lw.WriteLine("")

        Next

        lw.WriteLine("")

        lw.Close()

    End Sub

    Private Function GetCompBodies(ByVal theComponent As Assemblies.Component) As List(Of Body)

        Dim refSetName As String = theComponent.ReferenceSet
        Dim refSetBodies As New List(Of Body)

        If refSetName.ToLower = "empty" Then
            Return Nothing
        End If

        If refSetName.ToLower = "entire part" Then
            For Each tempBody As Body In CType(theComponent.Prototype.OwningPart, NXOpen.Part).Bodies
                If tempBody.IsSolidBody Then
                    refSetBodies.Add(tempBody)
                End If
            Next
            Return refSetBodies
        End If

        For Each theRefSet As ReferenceSet In theComponent.Prototype.OwningPart.GetAllReferenceSets

            If theRefSet.Name = refSetName Then
                Dim refObjs() As NXObject = theRefSet.AskAllDirectMembers
                For Each temp As NXObject In refObjs
                    If TypeOf (temp) Is Body Then
                        Dim theBody As Body = temp
                        If theBody.IsSolidBody Then
                            refSetBodies.Add(theBody)

                        End If
                    End If
                Next
            End If
        Next

        Return refSetBodies

    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