FreeCAD框架解析
1. 整体印象
-
跨平台
-
支持命令行模式进行操作
-
参数化建模
-
插件式架构,便于功能的结构与增减
-
支持多种模型格式
定制的文件格式:
*.FCstd
is a zip file container of many different types of information, such as geometry, scripts or thumbnail icons.
软件结构层次
- CAD引擎(App)
- GUI交互界面
模型对象
- 应用程序文档:结构参数
- 视图文档:颜色、线条表示、灯光、视角与渲染方式
依赖:
- 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
其他知识点:
-
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()
-
什么是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的普通用户。
-
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.
-
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.
学习路径:
- 熟悉FreeCADGui的操作流程
- 熟悉Python脚本编程,从录制宏开始
- 熟悉FreeCAD的关键class,例如:Base, App, Gui, Part
- 开发Python的拓展模块
- C++与Python混合开发
- 开发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. 编译源码
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
- 界面定制: 从头开始:工具栏和快捷方式
- 用宏工作: 轻松录制多遍任务或Python代码
- 宏菜单
- 定制工具栏
- 安装更多工作台
- 插件装载器
- Addons installer.FCMacro
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
4.2.1. Part Module
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. 创建工作台
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)