NX Journal 再帰的に全属性を取得するジャーナル

2022/01/01 categories:NX Journal| tags:NX Journal|Python|

スタンドアロン版のNXでアセンブリの子部品の全属性を再帰的に取得し、CSVとして保存するジャーナルを作成しました。

出力されるCSV

parts_list.csv

以下のように、1列目はパートファイルのフルパス、2行目以降は属性を羅列したCSVが出力されます。行方向にはユニークなフルパスのみ羅列します。

FullPath attribute1 attribute2
path1 attribute value1 attribute value2
. . .
. . .
. . .

tree_list.csv

アセンブリナビゲータのツリーの階層をrankとして記述したツリーのリストをCSVとして出力します。

rank FullPath attribute1 attribute2
0 path1 attribute value1 attribute value2
1 . . .
. . . .
. . . .

Pythonコード

import csv
import NXOpen

def main():
    theSession  = NXOpen.Session.GetSession()
    workPart = theSession.Parts.Work
    parts_list = {}
    tree_list = []
    attribute_titles = []
 
    recursion( workPart.ComponentAssembly.RootComponent, 0, tree_list, parts_list, attribute_titles )
    attribute_titles = list(set(attribute_titles))

    output = [ ['FullPath'] + [ a for a in attribute_titles ] ]
    for key in parts_list:
        output.append([key] + [ parts_list[key][a] if a in parts_list[key] else None for a in attribute_titles ])
    saveCSV('C:/parts_list.csv', output)

    output = [ ['rank', 'FullPath'] + [ a for a in attribute_titles ] ]
    for line in tree_list:
        array = [ line[0], line[1] ]
        array.extend([ parts_list[line[1]][a] if a in parts_list[line[1]] else None for a in attribute_titles ])
        output.append(array)
    saveCSV('C:/tree_list.csv', output)

def saveCSV(filename, lists):
    with open(filename, 'w', encoding='cp932') as f:
        writer = csv.writer(f, lineterminator='\n')
        writer.writerows(lists)
 
def recursion( component, rank, tree_list, parts_list, attribute_titles ):

    part = component.Prototype.OwningPart
    tree_list.append([rank, part.FullPath])

    if not part.FullPath in parts_list:
        attributes = get_attributes(part)
        attribute_titles.extend( attributes.keys() )
        
        parts_list[part.FullPath] = attributes

    for child1 in component.GetChildren():
        if not child1.IsSuppressed:
            recursion( child1, rank + 1, tree_list, parts_list, attribute_titles )

def get_attributes(part):
    attributes = {}

    for attribute in part.GetUserAttributes(True, True):

        attribute_size = part.GetUserAttributeSize(attribute.Title, attribute.Type)

        if attribute_size == 0:
            attributes[attribute.Title] = None
        elif attribute_size == 1:
            attributes[attribute.Title] = get_attribute(part, attribute.Title, attribute.Type, -1)
        else:
            attributes[attribute.Title] = [ get_attribute(part, attribute.Title, attribute.Type, i) for i in range(attribute_size) ]

    return attributes

def get_attribute(part, title, type, index):
    if type == NXOpen.NXObject.AttributeType.Invalid:
        return None
    if type == NXOpen.NXObject.AttributeType.Null:
        return None
    if type == NXOpen.NXObject.AttributeType.Boolean:
        return part.GetUserAttribute(title, type, index).BooleanValue
    if type == NXOpen.NXObject.AttributeType.Integer:
        return part.GetUserAttribute(title, type, index).IntegerValue
    if type == NXOpen.NXObject.AttributeType.Real:
        attribute = part.GetUserAttribute(title, type, index)
        return '{} {}'.format(attribute.RealValue, attribute.Unit.Abbreviation)
    if type == NXOpen.NXObject.AttributeType.String:
        return part.GetUserAttribute(title, type, index).StringValue
    if type == NXOpen.NXObject.AttributeType.Time:
        return part.GetUserAttribute(title, type, index).TimeValue
    if type == NXOpen.NXObject.AttributeType.Reference:
        return part.GetUserAttribute(title, type, index).ReferenceValue
    return None

if __name__ == '__main__':
    main()

Share post

Related Posts

コメント