FreeCAD框架解析



FreeCAD模塊開發指南

1. 整體印象

FreeCAD的設計核心特征

  1. 跨平台

  2. 支持命令行模式進行操作

  3. 參數化建模

  4. 插件式架構,便於功能的結構與增減

  5. 支持多種模型格式

    定制的文件格式:*.FCstd is a zip file container of many different types of information, such as geometry, scripts or thumbnail icons.

軟件結構層次

  1. CAD引擎(App)
  2. GUI交互界面

模型對象

  1. 應用程序文檔:結構參數
  2. 視圖文檔:顏色、線條表示、燈光、視角與渲染方式

依賴:

  • OpenCASCADE as CAD kernel
  • OpenInventor/Coin3D/pivy for 3D scene rendering
  • Qt and 'Qt for Python' (aka PySide2) for GUI
  • Python scripting and wrapping: PyCXX, swig, boost.python
  • Other powerful software libraries like Xerces XML, boost

其他知識點:

  1. 3D模型通過OpenGL渲染,借助OpenInventor庫實現

    使用OpenInventor開發包,程序員可以快速、簡潔地開發出各種類型的交互式三維圖形軟件。OIV具有平台無關性,它可以在Microsoft Windows、Unix、Linux等多種操作系統中使用。OIV允許使用C、C++、Java、DotNet多種編程語言進行程序開發。經過多年的發展,OIV已經基本上成為面向對象的3D圖形開發“事實上”的工業標准。廣泛地應用於機械工程設計與仿真、醫學和科學圖像、地理科學、石油鑽探、虛擬現實、科學數據可視化等領域。

    obj = FreeCAD.ActiveDocument.ActiveObject
    viewprovider = obj.ViewObject
    print viewprovider.toString()
    
  2. 什么是Coin3D: 開源的OpenInventor實現

    目前世界上比較成熟的Open Inventor(以下簡稱OIV)開發包有三個,它們分別由SGI(http://www.sgi.com),TGS(http://www.tgs.com)和SIM(http://www.coin3d.org)公司開發的。SGI是最早提出並開發OIV的公司。但SGI的OIV主要用在UNIX操作系統下,沒有提供對Microsoft Windows操作系統的支持。TGS公司是最早將OIV由Unix系統移植到Microsoft Windows下的公司。TGS的OIV是目前世界上使用最多的OIV版本。但TGS的OIV是一個商業軟件開發包,其購買開發版權的費用非常昂貴,不適合普通用戶學習和使用。SIM公司開發的Coin3D OIV可以同時在UNIX和Microsoft Windows下使用。這是一個開放源碼的OIV開發包,使用協議采用的是GPL協議。非常適合希望學習使用OIV的普通用戶。

  3. Pivy又是什么:Coin3D's Python wrapping

    Coin3D implements the same API but not source code with Open Inventor, via clean room implementation compatible Stable release Open Inventor v2.1. Kongsberg ended development of Coin3D in 2011 and released the code under the BSD 3-clause license. It is possible to draw object in OpenInventor Scene by Python, via Coin3D's python wrapper pivy , see https://www.freecadweb.org/wiki/Pivy

    VTK, is another open source and cross-platform visualization library, which ParaView is based on. Interoperation is possible, see Method for converting output from the VTK pipeline into Inventor nodes. From 0.17 and beyond, VTK pipeline is added to Fem mpivy trackers - A small python library of pivy/coin3D-based objects for rendering lines / nodes at the scenegraph level for user interface feedback. Implemented originally as a part of the FreeCAD Trails Workbench. odule.

  4. OpenCASCADE: CAD kernel,但僅用在Part_Workbench中

    First of all FreeCAD works without OpenCASCADE. That is an important feature, not everything needs geometric modeling, for example the Robot Workbench. OCC is only incorporated by the Part Workbench.

學習路徑

  1. 熟悉FreeCADGui的操作流程
  2. 熟悉Python腳本編程,從錄制宏開始
  3. 熟悉FreeCAD的關鍵class,例如:Base, App, Gui, Part
  4. 開發Python的拓展模塊
  5. C++與Python混合開發
  6. 開發3D渲染代碼(繼承自ViewProvider類)

2. 源碼目錄與模塊划分

  • Base: 基類對象定義
  • App: 非GUI的代碼,包括:
    • 文檔
    • 屬性
    • 文檔對象
  • Gui: 基於Qt的的Gui代碼
  • CXX: 修改PyCXX的Python子模塊
  • Ext: 全部的子模塊,每個模塊獨立一個目錄命名
  • Main: FreeCADCmd.exe, FreeCADGui.exe
  • Mod: 子模塊代碼目錄
  • Tools: 編譯工具fcbt.py
  • Doc: 通過doxygen生成文檔

其他

  • 3rdParty: boost/pivy/zlib等
  • zipios++: zip庫
  • Build: 設置版本號
  • FCConfig.h & fc.sh: OpenCASCADE相關的環境變量
  • XDGData: 用於生成Linux的桌面圖標

list of Mod:

  • Sketcher: 草繪工具
  • OpenSCAD: Part的底層函數,推薦用戶換用Part模塊函數操作
  • Part: 用於實體圖像的表達
  • PartDesign: 用於創建實體(Skecher -> Part)
  • Draft
  • Drawing: 3D圖像生成平面圖(Part -> DXF/SVG)
  • Assembly
  • Cam: CAM & CNC
  • Path: CAM的刀具軌跡

3. 編譯源碼

homepage: 官方編譯教程

安裝依賴

sudo apt build-dep freecad

編譯

mkdir freecad-build
cd freecad-build
cmake ../freecad-source -DBUILD_QT5=ON -DPYTHON_EXECUTABLE=/usr/bin/python3
make -j$(nproc --ignore=2)

-j2 選項用於選擇編譯時占用的內核數量(默認為1),可以用於加速編譯。

4. 定制FreeCAD

homepage: 官方入門教程

homepage: FreeCAD腳本基礎

homepage: FreeCAD腳本教程

4.1. 腳本操作

示例:

  • FreeCAD.ActiveDocument : 將返回當前(活動)的文件
  • FreeCAD.ActiveDocument.Blob : 在你的文檔中訪問一個被稱為“斑點”對象
  • FreeCADGui.ActiveDocument : 將返回到當前文檔相關的文檔視圖
  • FreeCADGui.ActiveDocument.Blob : 要訪問的圖形表示(視圖)我們的blob對象部分
  • FreeCADGui.ActiveDocument.ActiveView : 將返回當前視圖

4.1.1. 基本操作

When you start FreeCAD, the Python console already loads two base modules: FreeCAD and FreeCADGui (which can also be accessed by their shortcuts App and Gui).

新建文檔(模型):

>>> doc = FreeCAD.newDocument()
# 以下內容在Python cosole中自動完成
>>> App.setActiveDocument("Unnamed1")
>>> App.ActiveDocument=App.getDocument("Unnamed1")
>>> Gui.ActiveDocument=Gui.getDocument("Unnamed1")

創建對象:

box = doc.addObject("Part::Box", "myBox")
doc.recompute()  # 刷新並顯示模型

訪問和設置模型參數:

box.Height = 5

Vectors and placements

myvec = FreeCAD.Vector(2, 0, 0)
myvec.x
myvec.y
othervec = FreeCAD.Vector(0, 3, 0)
sumvec = myvec.add(othervec)

box.Placement
box.Placement.Base  # 以及 Rotation 屬性
box.Placement.Base = sumvec

otherpla = FreeCAD.Placement()
box.Placement = otherpla

圖形顯示的操作:

vo = box.ViewObject

vo.Transparency = 80
vo.hide()
vo.show()

4.1.2. 模塊簡介

The most important modules in FreeCAD that we'll look at in this tutorial are: Part, Mesh, Sketcher and Draft.

Mesh網格

import Mesh
mymesh = Mesh.createSphere()
mymesh.Facets
mymesh.Points

meshobj = doc.addObject("Mesh::Feature", "MyMesh")
meshobj.Mesh = mymesh
doc.recompute()

Part零件

import Part
myshape = Part.makeSphere(10)
myshape.Volume
myshape.Area
# Part.show(myshape)  # 等同於下面3行
shapeobj = doc.addObject("Part::Feature", "MyShape")
shapeobj.Shape = myshape
doc.recompute()

Draft

import Draft
rec = Draft.makeRectangle(5, 2)
mvec = FreeCAD.Vector(4, 4, 0)
Draft.move(rec, mvec)
Draft.move(box, mvec)

Gui

from PySide import QtGui
QtGui.QMessageBox.information(None, "Apollo program", "Houston, we have a problem")

4.2. API

homepage

FreeCAD API

FreeCADGui API

ViewObject API

Part API

Mesh API

Draft API

Selection API

4.2.1. Part Module

homepage

The Part Workbench is the basic layer that exposes the OCCT drawing functions to all workbenches in FreeCAD.

Primitives Tools:

Modifying objects:

Measure Tools:

Other tools:

4.3. 創建工作台

homepage: Workbench creation

class MyWorkbench (Workbench):

    MenuText = "My Workbench"
    ToolTip = "A description of my workbench"
    Icon = """paste here the contents of a 16x16 xpm icon"""

    def Initialize(self):
        """This function is executed when FreeCAD starts"""
        import MyModuleA, MyModuleB # import here all the needed files that create your FreeCAD commands
        self.list = ["MyCommand1, MyCommand2"] # A list of command names created in the line above
        self.appendToolbar("My Commands",self.list) # creates a new toolbar with your commands
        self.appendMenu("My New Menu",self.list) # creates a new menu
        self.appendMenu(["An existing Menu","My submenu"],self.list) # appends a submenu to an existing menu

    def Activated(self):
        """This function is executed when the workbench is activated"""
        return

    def Deactivated(self):
        """This function is executed when the workbench is deactivated"""
        return

    def ContextMenu(self, recipient):
        """This is executed whenever the user right-clicks on screen"""
        # "recipient" will be either "view" or "tree"
        self.appendContextMenu("My commands",self.list) # add commands to the context menu

    def GetClassName(self):
        # this function is mandatory if this is a full python workbench
        return "Gui::PythonWorkbench"

Gui.addWorkbench(MyWorkbench())

Python command definition

class My_Command_Class():
    """My new command"""

    def GetResources(self):
        return {'Pixmap'  : 'My_Command_Icon', # the name of a svg file available in the resources
                'Accel' : "Shift+S", # a default shortcut (optional)
                'MenuText': "My New Command",
                'ToolTip' : "What my new command does"}

    def Activated(self):
        """Do something here"""
        return

    def IsActive(self):
        """Here you can define if the command must be active or not (greyed) if certain conditions
        are met or not. This function is optional."""
        return True

FreeCADGui.addCommand('My_Command',My_Command_Class())

"Compiling" your resource file

import os, glob

qrc_filename = 'temp.qrc'
if os.path.exists(qrc_filename):
    os.remove(qrc_filename)

qrc = '''<RCC>
\t<qresource prefix="/">'''
for fn in glob.glob('./icons/*.svg'):
    qrc = qrc + '\n\t\t<file>%s</file>' % fn
qrc = qrc + '''\n\t</qresource>
</RCC>'''

print(qrc)

f = open(qrc_filename,'w')
f.write(qrc)
f.close()

os.system(
    'pyside-rcc -o a2p_Resources2.py {}'.format(qrc_filename))
os.system(
    'pyside-rcc -py3 -o a2p_Resources3.py {}'.format(qrc_filename))

os.remove(qrc_filename)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM