修改基本特征
关于编辑特征,自己在学习这块的时候被坑过,原因在于官方提供的《nxopen_getting_started_v12》中有这样一段描述:
You can actually use the CreateSphereBuilder function for either creation or editing purposes: if you input an existing Sphere object, then the Commit method will edit this sphere; if you input Nothing, then the Commit method will create a new sphere object, as in our code above
大致意思就是:创建特征和编辑特征差不多,如果你创建builder时传入的参数是一个存在的特征,当你commit时就会编辑这个特征,如果你创建builder时传入的参数是NULL,当你commit的时候就会创建一个新的特征,我按照这个方法在NX12.0中怎么都编辑不成功,后来查询文档,终于发现了EditWithRollbackManager这个类,多余的不细说,可以去看文档,只把修改特征的流程贴下面:
NXOpen.Features.FeatureCollection.StartEditWithRollbackManager()
- Feature edit using builder
NXOpen.Features.EditWithRollbackManager.UpdateFeature()
NXOpen.Features.EditWithRollbackManager.Stop()
NXOpen.Features.EditWithRollbackManager.Destroy()
也就是说除了第二步外,我们还有1,3,4,5需要做,文档中提到这个是在NX11.0.0中新提出的,不知道是不是NX10.0不需要,下面以一个例子来说明
首先,自定义菜单文件,CreateAndEdit.men,内容如下:
VERSION 120
EDIT UG_GATEWAY_MAIN_MENUBAR
MENU MY_MENU
BUTTON MY_ITEM1
LABEL createBlock
ACTIONS createBlock
BUTTON MY_ITEM2
LABEL editBlock
ACTIONS editBlock
END_OF_MENU
TOP_MENU
CASCADE_BUTTON MY_MENU
LABEL My App
END_OF_TOP_MENU
该文件放置在startup文件夹
然后创建edit_feature.py,内容如下:
import NXOpen import NXOpen.Features import NXOpen.MenuBar import tkinter as tk from tkinter.ttk import Label, Button, Entry class EditUI(): def __init__(self, length, width, height): self.win = tk.Tk(baseName=\'edit\') self.length = tk.DoubleVar(value=length) self.width = tk.DoubleVar(value=width) self.height = tk.DoubleVar(value=height) self.createUI() self.win.mainloop()
def createUI(self): self.win.title(\'编辑长方体\') Label(master=self.win, text=\'请输入需要编辑的参数\').grid( row=0, column=0, columnspan=2) Label(master=self.win, text=\'长度\').grid(row=1, column=0) Entry(master=self.win, textvariable=self.length).grid(row=1, column=1) Label(master=self.win, text=\'宽度\').grid(row=2, column=0) Entry(master=self.win, textvariable=self.width).grid(row=2, column=1) Label(master=self.win, text=\'高度\').grid(row=3, column=0) Entry(master=self.win, textvariable=self.height).grid(row=3, column=1) Button(master=self.win, text=\'确定\', command=self.clickButton).grid( row=4, column=0, columnspan=2) def clickButton(self): self.win.destroy() self.result = (self.length.get(), self.width.get(), self.height.get()) class CreateAndEditBlock(): def __init__(self): self.block_feature = None self.theSession = NXOpen.Session.GetSession() self.theUI = NXOpen.UI.GetUI() def createBlock(self, e): self.workPart = self.theSession.Parts.Work if self.block_feature: self.theUI.NXMessageBox.Show( "", NXOpen.NXMessageBoxDialogType.Information, \'长方体已经存在\') return NXOpen.MenuBar.MenuBarManagerCallbackStatus.Continue # 创建builder blockFeatureBuilder1 = self.workPart.Features.CreateBlockFeatureBuilder( NXOpen.Features.Block.Null) # 类型-原点和边长 blockFeatureBuilder1.Type = NXOpen.Features.BlockFeatureBuilder.Types.OriginAndEdgeLengths # 布尔 blockFeatureBuilder1.BooleanType = NXOpen.Features.FeatureBooleanType.Create # 原点和边长参数 originPoint1 = NXOpen.Point3d(0.0, 0.0, 0.0) blockFeatureBuilder1.SetOriginAndLengths( originPoint1, "100", "100", "100") # commit self.block_feature = blockFeatureBuilder1.CommitFeature() blockFeatureBuilder1.Destroy() return NXOpen.MenuBar.MenuBarManagerCallbackStatus.Continue def editBlock(self, e): if not self.block_feature: self.theUI.NXMessageBox.Show( "", NXOpen.NXMessageBoxDialogType.Information, \'长方体还未创建,请先创建\') return NXOpen.MenuBar.MenuBarManagerCallbackStatus.Continue # 创建builder,由于是编辑特征,以要修改的特征作为参数 blockFeatureBuilder1 = self.workPart.Features.CreateBlockFeatureBuilder( self.block_feature) # 创建修改参数输入界面 ui = EditUI(blockFeatureBuilder1.Length.Value, blockFeatureBuilder1.Width.Value, blockFeatureBuilder1.Height.Value) markId1 = self.theSession.SetUndoMark( NXOpen.Session.MarkVisibility.Visible, "Redefine Feature") editWithRollbackManager1 = self.workPart.Features.StartEditWithRollbackManager( self.block_feature, markId1) try: blockFeatureBuilder1.SetLength(str(ui.result[0])) blockFeatureBuilder1.SetWidth(str(ui.result[1])) blockFeatureBuilder1.SetHeight(str(ui.result[2])) self.block_feature = blockFeatureBuilder1.CommitFeature() except Exception as ex: NXOpen.UI.GetUI().NXMessageBox.Show( "Python", NXOpen.NXMessageBox.DialogType.Error, str(ex)) finally: editWithRollbackManager1.UpdateFeature(False) blockFeatureBuilder1.Destroy() editWithRollbackManager1.Stop() editWithRollbackManager1.Destroy() return NXOpen.MenuBar.MenuBarManagerCallbackStatus.Continue def startup(argc, args): create_and_edit = CreateAndEditBlock() menubarMan = create_and_edit.theUI.MenuBarManager menubarMan.AddMenuAction("createBlock", create_and_edit.createBlock) menubarMan.AddMenuAction("editBlock", create_and_edit.editBlock) return 0
打开UG,新建模型,会出现自定义的菜单项
点击createBlock会创建一个100X100X100的长方体,点击editBlock会弹出输入界面,提示输入参数:
输入框里面的数值为长方体长宽高现有的数值,更改为其它数值后,点击确定,就可以修改长方体属性,比如说我们将宽度改为150,点击确定:
下次再点击editBlock,输入框里的宽度显示为150
由于涉及的点较多,做一个总结
- 通过代码可以看出NXOpen利用Builder编辑特征的流程,与前面提到的一致
- 脚本的运行的方式为执行回调函数,也就是将editBlock函数和createBlock函数分别与菜单中的editBlock和createBlock绑定,NX12.0的官方文档中NXOpen-Python并没有这种方式,官方文档中只有C++,.NET,JAVA才有回调。
- 回调函数的绑定,即MenuBarManager.AddMenuAction的执行是在NX启动时完成的,对于这点,NX12.0的官方文档也缺乏说明,在Automatically at NX Start up这一章节中只针对C++,.NET,JAVA作出了说明,其中C/C++的函数签名为int ufsta( void ),VB.NET的函数签名为Function Startup ( ) As Integer,JAVA的函数签名为int startup (void),需要在NX启动时加载的程序文件应放置在startup文件夹下,Python的函数签名为startup(argc, args)
- 文中长方体参数的编辑输入UI是用tkinter完成的,其实也可以使用Block UI Styler来完成
- 利用MenuScript来自定义菜单