通過上一篇筆記的梳理,對工作臺開發(fā)的整體概念和必要的文件已經(jīng)有了大概的了解,接下來需要深入了解一下各個模塊的具體作用及其使用方法。
本節(jié)學(xué)習(xí)目標
- 了解
FreeCAD里的基本功能模塊; - 實現(xiàn)點擊功能按鈕,創(chuàng)建一個帶有屬性的基本三維對象;
- 調(diào)整屬性,觀察三維對象是否發(fā)生變化;
- 保存文檔并重新打開,確認所有屬性保存完整。
一、工作臺可使用的主要模塊
在 FreeCAD 里有很多模塊,他們在 工作臺 和 宏腳本 里都可以使用,最常使用的有兩個:
-
FreeCAD
-
FreeCAD又可以簡寫為App,主要用來調(diào)用和操作與界面(UI)無關(guān)的功能,它有以下幾種引用方式:# 方式一 from freecad import app # 方式二 import FreeCAD as App - 常用的方法和屬性
-
app.ActiveDocument: 獲取當前活動的文檔; -
app.newDocument(): 創(chuàng)建一個新的文檔; -
app.Console.PrintMessage(): 在FreeCAD的報告瀏覽器中輸出字符,如:app.Console.PrintMessage("測試內(nèi)容") -
app.ActiveDocument.recompute(): 重新計算當前文檔,即重新繪制三維對象。
-
-
-
FreeCADGui
-
FreeCADGui是用來調(diào)用和界面(UI)相關(guān)的功能,它有以下幾種引用方式:# 方式一 from freecad import gui # 方式二 import FreeCADGui as Gui - 常用的方法和屬性
-
gui.addCommand(): 向FreeCAD注冊一個命令,如:gui.addCommand('createThing', createThing()) -
gui.addWorkbench(): 向FreeCAD注冊一個工作臺,如:gui.addWorkbench(MazeWorkbench()) -
gui.Selection.getSelection(): 獲取當前選中的對象,返回是一個數(shù)組
-
-
二、調(diào)用其他工作臺的功能
- 有時候需要在代碼中調(diào)用系統(tǒng)其他工作臺里的功能,比如
Part工作臺里的功能,那就需要先將其導(dǎo)入,如:import Part - 導(dǎo)入后就可以正常使用了,如:
# 創(chuàng)建一個 10x10x10 的立方體 Part.makeBox(10,10,10)
三、命令(按鈕)基本定義
- 在上一次的筆記中使用過一個基本的命令(按鈕):
class CreateMaze(): def GetResources(self): return {"Pixmap" : APPICON, "MenuText": "創(chuàng)建迷宮", "ToolTip" : "創(chuàng)建一個3D迷宮"} def Activated(self): app.Console.PrintMessage("迷宮已創(chuàng)建完成\n") return def IsActive(self): ''' 判斷當前命令是否可用 ''' return True-
GetResources(): 用于獲取命令(按鈕)的圖標、名稱、提示等基本屬性,該方法 必需 定義; -
Activated(): 用于命令被調(diào)用時執(zhí)行的功能,該方法 必需 定義; -
IsActive(): 判斷當前命令是否可用,該方法可選,默認命令為可用;
-
- 一個命令通常為一個
python的類,通過以上規(guī)則進行定義; - 在一個工作臺里通常會有多個命令,所以為了方便擴展,可以定義一個基類,如:
class BaseCommand(object): def GetResources(self): return {'Pixmap': self.Pixmap, 'MenuText': self.MenuText, 'ToolTip': self.ToolTip} def Activated(self): return def IsActive(self): if app.ActiveDocument is None: return False else: return True - 然后其他命令通過這個基類來繼承,如:
class CreateMazeA(BaseCommand): Pixmap = APPICON MenuText = "創(chuàng)建迷宮A" ToolTip = "創(chuàng)建一個3D迷宮A" def Activated(self): app.Console.PrintMessage("迷宮A已創(chuàng)建完成\n") return class CreateMazeB(BaseCommand): Pixmap = APPICON MenuText = "創(chuàng)建迷宮B" ToolTip = "創(chuàng)建一個3D迷宮B" def Activated(self): app.Console.PrintMessage("迷宮B已創(chuàng)建完成\n") return - 這樣就可以方便的進行多個命令的創(chuàng)建了。
四、繪制自定義的三維對象
- 上面只學(xué)習(xí)了基本命令的創(chuàng)建和調(diào)用,但在 FreeCAD 里主要目的還是要創(chuàng)建三維對象,比如常規(guī)的立方體、圓柱體等,他們可以通過不同的工作臺去創(chuàng)建;
- 這些三維對象都有自己的屬性,比如:高度、寬度、直徑等等;
- 那創(chuàng)建一個迷宮對象,也會有自己的屬性,比如:墻高度、墻厚度等等;
- 這里就需要引入
FreeCAD里的一個概念:腳本對象;- 通俗點可以理解為通過腳本創(chuàng)建的對象,它需要可被序列化后保存到
FreeCAD文件中,以便重新打開時進行反序列化; - 它在
FreeCAD內(nèi)部被稱為FeaturePython,用App::FeaturePython類型來表示;
- 通俗點可以理解為通過腳本創(chuàng)建的對象,它需要可被序列化后保存到
- 通過以上概念的了解,再回來和上面的
命令結(jié)合,生成一個真正的帶屬性的三維對象; - 首先來定義一個三維對象,如(示例在官網(wǎng)的基礎(chǔ)上稍作調(diào)整):
class Box: def __init__(self, obj): '''對象實始化,可以添加一些屬性''' obj.addProperty("App::PropertyLength", "Length", "Box", "Length of the box").Length = 1.0 obj.addProperty("App::PropertyLength", "Width", "Box", "Width of the box").Width = 1.0 obj.addProperty("App::PropertyLength", "Height", "Box", "Height of the box").Height = 1.0 obj.Proxy = self def onChanged(self, fp, prop): '''Do something when a property has changed''' FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n") def execute(self, fp): '''在調(diào)用重新計算時會執(zhí)行該方法''' FreeCAD.Console.PrintMessage("Recompute Python Box feature\n")-
__init__():- 初始化方法,它接收一個
obj對象,通常為App::FeaturePython對象; - 可通過
FreeCAD.ActiveDocument.addObject()方法來添加,如:box = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Box") Box(box) -
obj.Proxy: 這個必需要指定self,它會在FreeCAD內(nèi)部被調(diào)用
- 初始化方法,它接收一個
-
onChanged(): 當屬性變更時被調(diào)用,需要注意的點:- 在初始化時,類似這樣
obj.addProperty("App::PropertyLength", "Length", "Box", "").Length = 1.0的語句也會觸發(fā)onChanged方法,所以如果檢測或?qū)ζ渌麑傩赃M行計算時要小心,可能指定的屬性還不存在。
- 在初始化時,類似這樣
execute(): 當執(zhí)行重新計算時,該方法會被調(diào)用
-
- 通過上面的代碼,已經(jīng)定義了一個基本的三維對象————立方體,他包含三個屬性:
Length,Width,Height; - 這些屬性是通過一個
addProperty方法來添加的,該方法有7個參數(shù):- 原型定義:
addProperty(self,typ,name='',group='',doc='',attr=0,readonly=False,hidden=False) -
typ: 屬性類型,如:整型、浮點等,在FreeCAD內(nèi)部定義了很多類型;- 比如上面使用的
App::PropertyLength他用來表示長度,是浮點類型的擴展,默認帶有單位; - 更多類型可參考:https://wiki.freecad.org/Property
- 比如上面使用的
-
name: 屬性的名稱,用英文表示,他會在代碼里用到; -
group: 屬性的分組,可用中文,相同的分組會在FreeCAD的屬性頁中顯示到一起; -
doc: 屬性的詳細描述,可用中文,當鼠標在對應(yīng)的屬性上停留時顯示; -
attr: 這是屬性的附加屬性,默認為0,表示沒有特殊的限制,可用值為:- 0 -- Prop_None, 無特殊限制
- 1 -- Prop_ReadOnly, 在屬性編輯器里只讀
- 2 -- Prop_Transient, 表示屬性值不會在文件里保存,但屬性名稱和類型這些會保存
- 4 -- Prop_Hidden, 在屬性編輯器里隱藏
- 8 -- Prop_Output, 作用暫不明,原文描述為:Modified property doesn't touch its parent container
- 16 -- Prop_NoRecompute, 修改屬性時,不會觸發(fā)重新計算
- 32 -- Prop_NoPersist, 表示屬性值不會在文件里保存,屬性名稱和類型也都不會保存
-
readonly: 是否只讀,默認為False -
hidden: 是否隱藏,默認為False
- 原型定義:
五、代碼實現(xiàn)
在概念了解清楚后,進入實際操作
-
在
init_gui.py同目錄下,創(chuàng)建一個maze.py文件,內(nèi)容如下:import Part class Maze: def __init__(self, obj): '''對象實始化,可以添加一些屬性''' obj.addProperty("App::PropertyLength", "Length", "Maze", "長").Length = 10.0 obj.addProperty("App::PropertyLength", "Width", "Maze", "寬").Width = 10.0 obj.addProperty("App::PropertyLength", "Height", "Maze", "高").Height = 10.0 obj.Proxy = self def execute(self, fp): '''在調(diào)用重新計算時會執(zhí)行該方法''' # 創(chuàng)建一個立方體 box = Part.makeBox(fp.Length, fp.Width, fp.Height) # 返回給 Shape 對象,用于 FreeCAD 界面顯示 fp.Shape = box -
修改
init_gui.py文件,添加創(chuàng)建迷宮的代碼,找到以下代碼:class CreateMaze(): ... def Activated(self): app.Console.PrintMessage("迷宮已創(chuàng)建完成\n") return ...修改為:
class CreateMaze(): ... def Activated(self): from .maze import Maze maze = app.ActiveDocument.addObject("Part::FeaturePython", "Maze") Maze(maze) maze.ViewObject.Proxy = 0 app.ActiveDocument.recompute() app.Console.PrintMessage("迷宮已創(chuàng)建完成\n") return ... -
保存并重新啟動
FreeCAD,新建一個文檔,然后切換到迷宮工作臺;
FreeCAD_2024-08-29_21-02-21.png 點擊
創(chuàng)建迷宮按鈕,如果執(zhí)行正確,將會在FreeCAD里看到一個10x10x10的立方體;-
因為還沒有寫真正的迷宮算法,所以僅用一個立方體來做演示;
FreeCAD_2024-08-29_21-07-05.png
小結(jié)
通過兩篇內(nèi)容的學(xué)習(xí),已將工作臺創(chuàng)建、功能按鈕創(chuàng)建、自定義三維模型創(chuàng)建等功能基本掌握,后面繼續(xù)深入了解通過三維模型的組合完成一個真正三維迷宮的創(chuàng)建。
完整代碼參考:https://github.com/ronggang/study-freecad

