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()