Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations waross on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

Journaling question command for number of features in part 1

Status
Not open for further replies.

obe0009

Mechanical
Jun 7, 2012
50
Hello,

Thanks to NXjournaling.com I adapted a program that scans an assembly and gives
for each part or sub assembly the userid from the person who created it. So I could
check easily that my students made it themselves. But students become smarter and
I think they found a trick to fool me.

The answer to the trick is that I can retrieve the number of features or types of
features in the parts.

That is why i am looking for a function that returns the number of feature or
another function that can retrieve strings ( eg. revolve) from Model History in
the part navigator.

Any help is much appreciated.

Regards,

Olaf
 
Replies continue below

Recommended for you

Hello EngProgrammer,

Here below the code. The red text I added.
This gives me a logging.

Regards,

Olaf


' Journal to recursively walk through the assembly structure
' will run on assemblies or piece parts
' will step through all components of the displayed part
'NX 7.5, native
'NXJournaling.com February 24, 2012

Option Strict Off

Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies

Module NXJournal

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

Sub Main()
Dim workPart As Part = theSession.Parts.Work
Dim dispPart As Part = theSession.Parts.Display

lw.Open
Try
Dim c As ComponentAssembly = dispPart.ComponentAssembly
'to process the work part rather than the display part,
' comment the previous line and uncomment the following line
'Dim c As ComponentAssembly = workPart.ComponentAssembly
if not IsNothing(c.RootComponent) then
'*** insert code to process 'root component' (assembly file)
lw.WriteLine("Assembly: " & c.RootComponent.DisplayName)
lw.WriteLine(" + Active Arrangement: " & c.ActiveArrangement.Name)
'ovb top assembly

theSession.Information.DisplayPartHistory(workPart)

'ovb
'*** end of code to process root component
ReportComponentChildren(c.RootComponent, 0)
else
'*** insert code to process piece part
lw.WriteLine("Part has no components")
end if
Catch e As Exception
theSession.ListingWindow.WriteLine("Failed: " & e.ToString)
End Try
lw.Close

End Sub

'**********************************************************
Sub reportComponentChildren( ByVal comp As Component, _
ByVal indent As Integer)

For Each child As Component In comp.GetChildren()
'*** insert code to process component or subassembly
lw.WriteLine(New String(" ", indent * 2) & child.DisplayName())
Dim part1 As Part = CType(theSession.Parts.FindObject(child.DisplayName()), Part)

theSession.Information.DisplayPartHistory(part1)
'*** end of code to process component or subassembly
if child.GetChildren.Length <> 0 then
'*** this is a subassembly, add code specific to subassemblies
lw.WriteLine(New String(" ", indent * 2) & _
"* subassembly with " & _
child.GetChildren.Length & " components")
lw.WriteLine(New String(" ", indent * 2) & _
" + Active Arrangement: " & _
child.OwningPart.ComponentAssembly.ActiveArrangement.Name)
'*** end of code to process subassembly
else
'this component has no children (it is a leaf node)
'add any code specific to bottom level components
end if
reportComponentChildren(child, indent + 1)
Next
End Sub
'**********************************************************
Public Function GetUnloadOption(ByVal dummy As String) As Integer
Return Session.LibraryUnloadOption.Immediately
End Function
'**********************************************************

End Module
 
Here's a short journal that I often use when trying to learn more about specific features. It can easily be modified to count specific features or report other information.

Code:
Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.Features

Module NXJournal
Sub Main


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

Dim featArray() As Feature = theSession.Parts.Work.Features.GetFeatures()
Dim featEntities() as NXObject

lw.WriteLine("*** All Features ***")
For each myFeature as Feature in featArray
    lw.WriteLine(".GetFeatureName: " & myFeature.GetFeatureName)
	lw.writeline(".Name: " & myFeature.Name)
	lw.WriteLine(".FeatureType: " & myFeature.FeatureType)
	lw.WriteLine(".GetType: " & myFeature.GetType.ToString)
	lw.WriteLine(".Timestamp: " & myFeature.Timestamp.ToString)
	lw.WriteLine(".Suppressed: " & myFeature.Suppressed.ToString)
	
	try
		lw.writeline(".Location: " & myFeature.Location.ToString)
	catch ex as nxexception
	end try
	
	lw.writeline("")

Next
lw.Close

End Sub
End Module

www.nxjournaling.com
 
Hello Cowski,

Thanks, I modified your code to do what I want. But inserting into the main program gives me problems.
It will not run the For Next loop.

Regards,

Olaf

My modified code:
Code:
Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.Features

Module NXJournal
Sub Main
Dim i as Integer= 0
Dim strMyString As String = " "
Dim NameFeature As String = " "
Dim Bodystring As string = " "
Dim theSession As Session = Session.GetSession()
Dim lw As ListingWindow = theSession.ListingWindow
lw.Open()

Dim featArray() As Feature = theSession.Parts.Work.Features.GetFeatures()
Dim featEntities() as NXObject

lw.WriteLine("*** Last Feature ***")
For each myFeature as Feature in featArray
        NameFeature= myFeature.GetFeatureName
        Bodystring = Mid(Namefeature,1, 4)
         if bodystring = "Body" then
            i= i+1
         end if
	

        strMyString = myFeature.Timestamp.ToString        

Next

lw.WriteLine(".Timestamp: " & strMyString & " " & NameFeature)


if i > 0 then
     lw.WriteLine("Number of bodies: " & i )
end if 
 

lw.Close

End Sub
End Module
 
The code that I posted only works with the current work part. To make it work with the code that steps through the assembly, one strategy would be to make each component the work part in turn then call the code that checks the feature list.

www.nxjournaling.com
 
Hello,

I adapted the program a little but in my test assembly, only twice the features are listed (really once because the part is used two times).

The code is, bold is where I am working on :

Assembly is attached window_frame_assembly.prt is top assembly.

Any help is much appreciated.

Regards,

Olaf

Code:
' Journal to recursively walk through the assembly structure
' will run on assemblies or piece parts
' will step through all components of the displayed part
'NX 7.5, native
'NXJournaling.com February 24, 2012
 
Option Strict Off
 
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports NXOpen.features
 
Module NXJournal
 
    Public theSession As Session = Session.GetSession()
    Public ufs As UFSession = UFSession.GetUFSession()
    Public lw As ListingWindow = theSession.ListingWindow
 
    Sub Main()
    Dim workPart As Part = theSession.Parts.Work
    Dim dispPart As Part = theSession.Parts.Display
 
    lw.Open
    Try
        'Dim c As ComponentAssembly = dispPart.ComponentAssembly
        'to process the work part rather than the display part,
        '  comment the previous line and uncomment the following line
        Dim c As ComponentAssembly = workPart.ComponentAssembly
        if not IsNothing(c.RootComponent) then
            '*** insert code to process 'root component' (assembly file)
            lw.WriteLine("Assembly: " & c.RootComponent.DisplayName)
            lw.WriteLine(" + Active Arrangement: " & c.ActiveArrangement.Name)
'ovb top assembly
           lw.writeline("top asm  "& workpart.tostring)
'           theSession.Information.DisplayPartHistory(workPart)

'ovb 
           '*** end of code to process root component
            ReportComponentChildren(c.RootComponent, 0)
        else
            '*** insert code to process piece part
            lw.WriteLine("Part has no components")
        end if
    Catch e As Exception
        theSession.ListingWindow.WriteLine("Failed: " & e.ToString)
    End Try
    lw.Close
 
    End Sub
 
'**********************************************************
    Sub reportComponentChildren( ByVal comp As Component, _
        ByVal indent As Integer)
    dim namefeature as string = " "
 
        For Each child As Component In comp.GetChildren()
            '*** insert code to process component or subassembly
            lw.WriteLine(New String("1", indent * 2) & child.DisplayName())
            Dim part1 As Part = CType(theSession.Parts.FindObject(child.DisplayName()), Part)
            [b]lw.writeline("part 2 "& part1.tostring)
            'theSession.Information.DisplayPartHistory(part1)
            lw.writeline("comp 3 : "& comp.tostring)
            dim pls1 as PartLoadStatus
            thesession.parts.setworkcomponent(comp, pls1)
            dim farray() as feature = thesession.parts.work.features.getfeatures()
            lw.writeline(" features!!! from  " & comp.tostring)
            for each myfeature as feature in farray
                namefeature=myfeature.getfeaturename
                lw.writeline("  " & Namefeature)
            next
[/b]


            '*** end of code to process component or subassembly
            if child.GetChildren.Length <> 0 then
                '*** this is a subassembly, add code specific to subassemblies
                lw.WriteLine(New String("4", indent * 2) & _
                    "* subassembly with " & _
                    child.GetChildren.Length & " components")
                lw.WriteLine(New String("5", indent * 2) & _
                    " + Active Arrangement: " & _
                    child.OwningPart.ComponentAssembly.ActiveArrangement.Name)
                '*** end of code to process subassembly
            else
                'this component has no children (it is a leaf node)
                'add any code specific to bottom level components
            end if
            reportComponentChildren(child, indent + 1)
        Next
    End Sub
'**********************************************************
    Public Function GetUnloadOption(ByVal dummy As String) As Integer
        Return Session.LibraryUnloadOption.Immediately
    End Function
'**********************************************************
 
End Module
 
I think you used comp, when you should have used child.

Try this version:

Code:
' Journal to recursively walk through the assembly structure
' will run on assemblies or piece parts
' will step through all components of the displayed part
'NX 7.5, native
'NXJournaling.com February 24, 2012
 
Option Strict Off
 
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports NXOpen.features
 
Module NXJournal
 
    Public theSession As Session = Session.GetSession()
    Public ufs As UFSession = UFSession.GetUFSession()
    Public lw As ListingWindow = theSession.ListingWindow
 
    Sub Main()
    Dim workPart As Part = theSession.Parts.Work
    Dim dispPart As Part = theSession.Parts.Display
 
    lw.Open
    Try
        'Dim c As ComponentAssembly = dispPart.ComponentAssembly
        'to process the work part rather than the display part,
        '  comment the previous line and uncomment the following line
        Dim c As ComponentAssembly = workPart.ComponentAssembly
        if not IsNothing(c.RootComponent) then
            '*** insert code to process 'root component' (assembly file)
            lw.WriteLine("Assembly: " & c.RootComponent.DisplayName)
            lw.WriteLine(" + Active Arrangement: " & c.ActiveArrangement.Name)
'ovb top assembly
           lw.writeline("top asm  " & workpart.leaf)
'           theSession.Information.DisplayPartHistory(workPart)

'ovb 
           '*** end of code to process root component
		   lw.writeline("")
            ReportComponentChildren(c.RootComponent, 0)
        else
            '*** insert code to process piece part
            lw.WriteLine("Part has no components")
        end if
    Catch e As Exception
        theSession.ListingWindow.WriteLine("Failed: " & e.ToString)
    End Try
    lw.Close
 
    End Sub
 
'**********************************************************
    Sub reportComponentChildren( ByVal comp As Component, _
        ByVal indent As Integer)
    dim namefeature as string = " "
 
        For Each child As Component In comp.GetChildren()
            '*** insert code to process component or subassembly
            'lw.WriteLine(New String("1", indent * 2) & child.DisplayName())
			lw.WriteLine(child.DisplayName())
            'Dim part1 As Part = CType(theSession.Parts.FindObject(child.DisplayName()), Part)
			Dim part1 as Part = child.Prototype.OwningPart
            lw.writeline("part1: "& part1.leaf)
            'theSession.Information.DisplayPartHistory(part1)
            lw.writeline("comp: "& comp.displayname)
            dim pls1 as PartLoadStatus
            thesession.parts.setworkcomponent(child, pls1)
            dim farray() as feature = thesession.parts.work.features.getfeatures()
            lw.writeline(" features!!! from  " & child.displayname)
            for each myfeature as feature in farray
                namefeature=myfeature.getfeaturename
                lw.writeline("  " & Namefeature)
            next



            '*** end of code to process component or subassembly
            if child.GetChildren.Length <> 0 then
                '*** this is a subassembly, add code specific to subassemblies
                lw.WriteLine("* subassembly with " & _
                    child.GetChildren.Length & " components")
                lw.WriteLine(" + Active Arrangement: " & _
                    child.OwningPart.ComponentAssembly.ActiveArrangement.Name)
                '*** end of code to process subassembly
            else
                'this component has no children (it is a leaf node)
                'add any code specific to bottom level components
            end if
			lw.writeline("")
            reportComponentChildren(child, indent + 1)
        Next
    End Sub
'**********************************************************
    Public Function GetUnloadOption(ByVal dummy As String) As Integer
        Return Session.LibraryUnloadOption.Immediately
    End Function
'**********************************************************
 
End Module

www.nxjournaling.com
 
Hello Cowski,

Thanks, thanks!!!!!!

The code has become the following.
I am still testing.
But I found a caveat in the code.
In NX7554 the code runs correctly when the assembly is partially loaded, in NX10.01 the code
runs not correctly until all parts are loaded. Strange!!!

Many thanks for your time and help!!

Regards,

Olaf

Code:
' Journal to recursively walk through the assembly structure
' will run on assemblies or piece parts
' will step through all components of the displayed part
'NX 7.5, native
'NXJournaling.com February 24, 2012
 
Option Strict Off
 
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports NXOpen.features
 
Module NXJournal
 
    Public theSession As Session = Session.GetSession()
    Public ufs As UFSession = UFSession.GetUFSession()
    Public lw As ListingWindow = theSession.ListingWindow
 
    Sub Main()
    Dim workPart As Part = theSession.Parts.Work
    Dim dispPart As Part = theSession.Parts.Display
 
    lw.Open
   
    Try
        'Dim c As ComponentAssembly = dispPart.ComponentAssembly
        'to process the work part rather than the display part,
        '  comment the previous line and uncomment the following line
        Dim c As ComponentAssembly = workPart.ComponentAssembly
        if not IsNothing(c.RootComponent) then
            '*** insert code to process 'root component' (assembly file)
            lw.WriteLine("Assembly: " & c.RootComponent.DisplayName)
            lw.WriteLine(" + Active Arrangement: " & c.ActiveArrangement.Name)
'ovb top assembly
            lw.writeline("top asm  " & workpart.leaf)
            theSession.Information.DisplayPartHistory(workPart)

'ovb 
           '*** end of code to process root component
		   lw.writeline("")
            ReportComponentChildren(c.RootComponent, 0)
        else
            '*** insert code to process piece part
            lw.WriteLine("Part has no components")
        end if
    Catch e As Exception
        theSession.ListingWindow.WriteLine("Failed: " & e.ToString)
    End Try
    lw.Close
 
    End Sub
 
'**********************************************************
    Sub reportComponentChildren( ByVal comp As Component, _
        ByVal indent As Integer)
    dim namefeature as string = " "
    dim test as string = " "
    dim strMyString as string = " "
    dim Bodystring as string = " "
    dim i as integer = 0
    dim j as integer = 0
 
        For Each child As Component In comp.GetChildren()
            '*** insert code to process component or subassembly
            'lw.WriteLine(New String("1", indent * 2) & child.DisplayName())
	    'lw.WriteLine(child.DisplayName())
            'Dim part1 As Part = CType(theSession.Parts.FindObject(child.DisplayName()), Part)
	    Dim part1 as Part = child.Prototype.OwningPart
            'lw.writeline("part1: "& part1.leaf)
            'theSession.Information.DisplayPartHistory(part1)
            'lw.writeline("comp: "& comp.displayname)
            dim pls1 as PartLoadStatus
            '*** make work part
            thesession.parts.setworkcomponent(child, pls1)
            dim farray() as feature = thesession.parts.work.features.getfeatures()
            
            '*** test of work part is a part starting with Hex Par Dis indicating library element to be skipped for processing
            test= left(part1.leaf.tostring,3)
            select case test
               case "Hex"
                  lw.writeline("bout")
               case "Par"
                  lw.writeline("cilindrische pen")
               case "Dis" 
                  lw.writeline("onderleg ring")
               case Else
                    lw.writeline("Part met volgende features: "& part1.leaf)
                   'lw.writeline(" features!!! from  " & child.displayname)
                  
                   for each myfeature as feature in farray
                       namefeature=myfeature.getfeaturename
                       'lw.writeline(" each lus namefeature    :" & namefeature)
                       Bodystring = " "                       
                       Bodystring = Mid(Namefeature,1, 4)
                       if Bodystring = "Body" then
                           i= i+1
                           'lw.WriteLine("In lus each: " & i)
                          
                       end if
                       if Bodystring = "soli" then
                           j= j+1
                           'lw.WriteLine("In lus each: " & j)

                       end if
                        	
                       'lw.writeline("  " & Namefeature)
                       strMyString = myFeature.Timestamp.ToString     
                   next
                  lw.writeline(" ")
                  lw.WriteLine(" " & strMyString & " " & NameFeature)
                  lw.writeline(" ")      
                  theSession.Information.DisplayPartHistory(part1)
                  lw.writeline(" ")
                  if i > 0 then
                     lw.WriteLine("Number of bodies: " & i & "    bodies bodies bodies!!!!!!!!" )
                  end if
                  if j > 0 then
                     lw.WriteLine("Number of solids: " & j & "    solids solids solids!!!!!!!!" )
                  end if
                   i=0
                   j=0

                  lw.WriteLine(".Timestamp: " & strMyString & " " & NameFeature & " " & part1.leaf )
                  lw.writeline(" ")      
            end select  



            '*** end of code to process component or subassembly
            if child.GetChildren.Length <> 0 then
                '*** this is a subassembly, add code specific to subassemblies
                lw.WriteLine("* subassembly with " & _
                    child.GetChildren.Length & " components")
                lw.WriteLine(" + Active Arrangement: " & _
                    child.OwningPart.ComponentAssembly.ActiveArrangement.Name)
                '*** end of code to process subassembly
            else
                'this component has no children (it is a leaf node)
                'add any code specific to bottom level components
            end if
			lw.writeline("")
            reportComponentChildren(child, indent + 1)
        Next
    End Sub
'**********************************************************
    Public Function GetUnloadOption(ByVal dummy As String) As Integer
        Return Session.LibraryUnloadOption.Immediately
    End Function
'**********************************************************
 
End Module
 
Below is part of a subroutine that I use to load components. I did some editing, trying to make it a stand-alone subroutine; I have not tested the result, you may need to tweak it some to get it fully functional.

Code:
    Private Function LoadComponent(ByVal theComponent As Component) As Boolean
		
	Dim Sess as Session = Session.GetSession()
	Dim ufs as UfSession = UfSession.GetUfSession()
		
        Dim thePart As Part = theComponent.Prototype.OwningPart

        Dim partName As String = ""
        Dim refsetName As String = ""
        Dim instanceName As String = ""
        Dim origin(2) As Double
        Dim csysMatrix(8) As Double
        Dim transform(3, 3) As Double

        Try
            If thePart.IsFullyLoaded Then
                'component is fully loaded
            Else
                'component is partially loaded
            End If
            Return True
        Catch ex As NullReferenceException
            'component is not loaded
            Try
                Sess.Assem.AskComponentData(theComponent.Tag, partName, refsetName, instanceName, origin, csysMatrix, transform)

                Dim theLoadStatus As PartLoadStatus
                Sess.Parts.Open(partName, theLoadStatus)

                If theLoadStatus.NumberUnloadedParts > 0 Then

                    Dim allReadOnly As Boolean = True
                    For i As Integer = 0 To theLoadStatus.NumberUnloadedParts - 1
                        If theLoadStatus.GetStatus(i) = 641058 Then
                            'read-only warning, file loaded ok
                        Else
                            '641044: file not found
                            allReadOnly = False
                        End If
                    Next
                    If allReadOnly Then
                        Return True
                    Else
                        'warnings other than read-only...
                        Return False
                    End If
                Else
                    Return True
                End If

            Catch ex2 As NXException
                If ex2.Message.ToLower = "file not found" Then
				'code for "file not found" condition
                End If
                Return False
            End Try
        Catch ex As NXException
            'unexpected error
            Return False
        End Try

    End Function

www.nxjournaling.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor