本文目标在于记录在FreeCAD源码阅读中了解到的一些东西。

FreeCAD编译

FreeCAD源码的编译最好使用官方提供的LibPack,否则第三方库难以找全,找到之后还需要自己编译,此外还不知道CMake是否能够那么顺利找好(find_package)自己设的第三方库。采用官方提供的LibPack可以免除这一大堆的麻烦。但是官方的LibPack仅有提供针对VS2008, VS2013, VS2012x64的版本,分别可以在FreeCAD在github上的发布地址0.16和0.15版本位置找到(VC9, VC12),而sourceforge地址还可以找到x64的VS2012。

我采用的LibPack是FreeCADLibs_11.0_x64_VC11.7z版本,这个版本在boost_python上有lib和dll缺失,可以从boost官方预编译版本1.55.0版本拷贝x64位相应的lib和dll,也可以从FreeCADLibs_10.0_x64_VC11.7z里边把4个文件拷贝出来。

源码采用0.16的,没有使用0.17_pre,目标主要在于编译出来看看,没有去追求官方最新的版本。解压source,LibPack默认是与源码放置同一目录的,如果要放置在不同的目录,可以将CMakeLists.txt第125行set(FREECAD_LIBPACK_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Directory of the FreeCAD LibPack")中的${CMAKE_SOURCE_DIR}改为${CMAKE_BINARY_DIR},cmake-gui.exe可以完美通过。

第三方库粗略记录

没列举齐全的第三方库表格如下:

Lib Name version in LibPack_11.0_x64_VC11 Link to get it
Python Python 2.7.8 http://www.python.org/
PySide 1.2.2 http://wiki.qt.io/PySide
shiboken 1.2.2 http://shiboken.readthedocs.io/en/latest/
Qt Qt 4 https://www.qt.io/
Boost 1.55.0 http://www.boost.org/
Coin3D 4.0 https://bitbucket.org/Coin3D/coin/wiki/Home
SoQt 1.2 https://bitbucket.org/Coin3D/soqt
OpenCASCADE oce-16(对应6.7.1) http://www.opencascade.com

在以上第三方库中,PySide是Python与Qt的融合,可以使用Python语言构建Gui。建议是在Python2.7系列中使用,支持部分Python3,与PySide有相同功能的PyQt相对成熟一些,但商用需要付费,估计这是FreeCAD采用PySide的原因,PySide是Qt官方出的,完成了对Qt4.8版本的完整实现,支持Qt5的PySide2也可以在github中找到。shiboken作何用途,我还没弄得很明白。

FreeCAD对Python是重度依赖,不能缺失。如果自己来搞第三方库,就必须先搞定Python,PySide,Boost,shiboken,所以使用官方提供的LibPack是可以节省不少麻烦的。

工程项目的简要分析

可以将FreeCAD_trunk.sln目录之下的项目分为两类,一类为 FreeCAD打头的基础工程项目;另一类为Mod模块工程。基础工程项目列表如下:

工程项目 产生文件 备注
FreeCADMain FreeCAD.exe FreeCAD主执行启动文件,main()函数所在地
FreeCADMainPy FreeCAD.pyd 兼容Python的扩展dll,导出initFreeCAD()
FreeCADMainCmd FreeCADCmd.exe App::Application::Config()["RunMode"]有三种模式,Gui、Exit、Console,这里对应的是Exit模式,执行(argc, argv)之后自动退出
FreeCADGui FreeCADGui.dll 命名空间Gui,Command,Workbench,View3dInventor(视图),Gui层的Document
FreeCADGuiPy FreeCADGui.pyd 兼容Python的扩展dll
FreeCADBase FreeCADBase.dll 代码基础与上层,命名空间Base,Type类型体系,InterpreterSingleton脚本解释器
FreeCADApp FreeCADApp.dll 表征exe执行所在的应用,命名空间App,App::GetApplication()可以获取唯一的那个pcSingleton指针,App层Document

以上这些就建构了FreeCAD运行的基础框架,它们实际上仅使用了Python, Boost, PySide, shiboken, xerces-c, zlib, coin3d等这些,其余的Mod都是模块扩展,依赖诸如OCE,PCL,Eigen3,libqhull等等,每个Mod工程项目分为带Gui的及不带Gui的版本。带Gui的项目定义了可用的Command,Workbench(工作台),显示等这些。

之所以FreeCAD对Python依赖如此之深,是因为本质上FreeCAD所有的命令实现都是通过Python语句来实现的。比如一个Box的创建命令是这样的:

C++
void CmdPartBox::activated(int iMsg)
{
    QString cmd;
    cmd = qApp->translate("CmdPartBox","Cube");
    openCommand((const char*)cmd.toUtf8());

    doCommand(Doc,"App.ActiveDocument.addObject(\"Part::Box\",\"Box\")");
    cmd = QString::fromLatin1("App.ActiveDocument.ActiveObject.Label = \"%1\"")
        .arg(qApp->translate("CmdPartBox","Cube"));
    doCommand(Doc,(const char*)cmd.toUtf8());
    commitCommand();
    updateActive();
    doCommand(Gui, "Gui.SendMsgToActiveView(\"ViewFit\")");
}

里边这些都是发送给解释器的Python语句呀,执行后会在界面上的Python Console窗口播报Python执行语句,这样录制宏就简单极了,此外也可以全部采用Python来建模或者写个功能实现,比如就有个SheetMetal就完全是用Python来实现。

Command命令的目标是产生NewObject加入Document,特征附有属性,然后recompute()执行计算,这样就可以重生成,响应修改属性的结果。

fcstd文件格式分析

fcstd是FreeCAD存储下来的文件,这个格式实际上就是zip压缩文件,可以修改后缀成为zip或者直接拖拽至刚打开的WinRAR可以看到里边的文件,简单的话就4个,多的话数量不少。其中Document.xml是对应FreeCADApp里边的Doc,GuiDocument.xml对应FreeCADGui里边的Doc,另外有PartShape.brp文件就是OpenCASCADE官方的brep格式呀。

Sketcher草图

之所以说草图,是发现FreeCAD的草图看起来还不错,实时可见(不同于实体的创建),可以捕捉到线段的端点,中点,两条线的交点等这些。

  • CmdSketcherCreateLine 是草图绘制线段的命令,该命令在激活时会调用ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerLine())将这个handler交给SketcherGui::ViewProviderSketch激活
  • DrawSketchHandlerLine 派生自 DrawSketchHandler,会有个mouseMove()的函数重载定义鼠标行为,并调用seekAutoConstraint(), renderSuggestConstraitsCursor()
  • App里边有个planegcs文件夹,里边可以对约束求解,代码稍微有点多没细看,相比D-Cubed怎么样就不知道了

关于BUILD_JTREADER

因为笔者对JT格式做过分析,发现FreeCAD里边有这个选项,就特别留意了一下。需要提醒的是BUILD_JTREADER在这个版本无效,因为src/Mod下边没有JtReader文件夹,0.17_pre里边也没有,但是github最新版的源码里有该文件夹。略略地看了一下,实现很简略,跳过很多东西,相比OpenCASCADE官方提供的TKJT弱很多(不过OCC的TKJT也很久没更新了,一更新就到了需要付费方可得到里边去了)。不过FreeCAD还有个JTREADER.h文件,调用了JtOpen的头文件呀,这个牛,可惜JtOpen试用版一般只有一个月吧。

小结

2017/12/22 FreeCAD架构体系还是很清晰的,也实现了不少要点(比如Undo/Redo,参数化,自动保存等),模块也包揽很多;Python嵌入好坏不好评价,但我个人不大习惯。总的来说给我的感觉是不精细。

FreeCAD源码阅读笔记的更多相关文章

  1. CI框架源码阅读笔记5 基准测试 BenchMark.php

    上一篇博客(CI框架源码阅读笔记4 引导文件CodeIgniter.php)中,我们已经看到:CI中核心流程的核心功能都是由不同的组件来完成的.这些组件类似于一个一个单独的模块,不同的模块完成不同的功 ...

  2. CI框架源码阅读笔记4 引导文件CodeIgniter.php

    到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...

  3. CI框架源码阅读笔记3 全局函数Common.php

    从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...

  4. CI框架源码阅读笔记2 一切的入口 index.php

    上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...

  5. 源码阅读笔记 - 1 MSVC2015中的std::sort

    大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...

  6. Three.js源码阅读笔记-5

    Core::Ray 该类用来表示空间中的“射线”,主要用来进行碰撞检测. THREE.Ray = function ( origin, direction ) { this.origin = ( or ...

  7. PHP源码阅读笔记一(explode和implode函数分析)

    PHP源码阅读笔记一一.explode和implode函数array explode ( string separator, string string [, int limit] )此函数返回由字符 ...

  8. AQS源码阅读笔记(一)

    AQS源码阅读笔记 先看下这个类张非常重要的一个静态内部类Node.如下: static final class Node { //表示当前节点以共享模式等待锁 static final Node S ...

  9. libevent源码阅读笔记(一):libevent对epoll的封装

    title: libevent源码阅读笔记(一):libevent对epoll的封装 最近开始阅读网络库libevent的源码,阅读源码之前,大致看了张亮写的几篇博文(libevent源码深度剖析 h ...

随机推荐

  1. 前端基于react,后端基于.net core2.0的开发之路(1) 介绍

    文章提纲目录 1.前端基于react,后端基于.net core2.0的开发之路(1) 介绍 2.前端基于react,后端基于.net core2.0的开发之路(2) 开发环境的配置,注意事项,后端数 ...

  2. unity下跨平台excel读写

    这是以前写的跨windows和ios读写excel的工具,因为原来导表工具引用的第三方读写excel的dll只能在windos下使用,造成要在mac机器上跑PC端或者打包的时候,每次都要先在windo ...

  3. Dev控件 galleryControl

    发现一个规律,不会的控件先拖到界面上,右上角需要add 的就对应add一个.然后就是找属性和集合手动添加几个. 然后把XXXForm.Designer.cs 里面的代码提取到逻辑代码中,就把常量换成变 ...

  4. 用C#生成不重复的随机数

    我们在做能自动生成试卷的考试系统时,常常需要随机生成一组不重复的题目,在.net Framework中提供了一个专门用来产生随机数的类System.Random. 对于随机数,大家都知道,计算机不 可 ...

  5. mysql数据库第二弹

    mysql数据库针对表的操作 表记录的增删改查 1.增加一张表 插入记录之前必须得先有表结构! CREATE TABLE score( id int PRIMARY KEY auto_incremen ...

  6. [C#源代码]使用SCPI指令对指定通信端口(RS232/USB/GPIB/LAN)的仪器编程

    本文为原创文章,源代码为原创代码,如转载/复制,请在网页明显位置标明原文名称.作者及网址,谢谢! 本软件是基于NI-VISA/VISA32(Virtual Instrument Software Ar ...

  7. StackExchange.Redis学习笔记(三)

    这一章主要写一些StackExchange.Redis的配置及不太经常用到的函数 数据库连接 下面是我的连接字符串,里面指定了地址,密码,及默认的数据库 Redis启动后默认会分成0-15个数据库,不 ...

  8. WinForm 窗体之间相互嵌套

    public FrmScan() { InitializeComponent(); Form1 frm = new Form1(); frm.Dock = DockStyle.Fill; frm.Fo ...

  9. Android 之旅开始了!先自我了解下Android与Linux之间的关系

    Android是在Linux2.6的内核基础之上运行的,提供核心系统服务:安全.内存管理.进程管理.网络组.驱动模型.内核部分还相当于一个介于硬件层和系统中其他软件组之间的一个抽象层次.但是严格来说它 ...

  10. CentOS 6.4安装配置LNMP服务器(Nginx+PHP+MySQL)

    一 安装篇 1. 安装nginx yum check-update #更新yum源 yum remove httpd* php* #删除系统自带的软件包 yum install nginx #安装ng ...