修改基本特征
關於編輯特征,自己在學習這塊的時候被坑過,原因在於官方提供的《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來自定義菜單
