CuraEngine 基本工作流程 绝对的干货 

3D打印技术 /[软件]
2017-01-06 14:07
   在知道 CuraEngine 的工作原理之前,需要先知道 STL 格式的含义。.stl 文件是在计算机图形应用系统中,用于表示三角形网格的一种文件格式。 它的文件格式非常简单, 应用很广泛。STL 是最多快速原型系统所应用的标准文件类型。STL 是用三角网格来表现 3D CAD 模型。

图 1.1.1 三角网格
Stl 文件中存放的是无数个空间三角面的位置信息(空间中,每个三角面的确定是通过它
三个定点的坐标来的)。所以,我们如果要对一个 3D 模型进行切割,实际上就是用一个平面
来和无数小三角形做相交,得到很多条交线,我们把这些交线连接起来就得到了切平面了。
.CuraEngine 基本工作流程
笔者一开始就选择了 Cura 作为研究对象,有两个原因:一是 slice3R 的切片速度明显不如 Cura,
二是,Cura 的切片引擎使用的是 C++…这是笔者所钟爱的开发语言。虽然 Cura 的界面是用
Python 语言写的,但这不影响底层切片软件引擎的使用。
下面是 CuraEngine 的 github 上关于 Cura 项目的介绍和描述。
(https://github.com/Ultimaker/CuraEngine)
1.1 总流程
The Cura Engine is structured as mainly .h files. This is not standard for an C++ project. However,
using less cpp files makes the optimizer work harder and removes linking error issues. It's partialy
a result of lazyness but also for optimalizations.
The .h files contain different steps called from the main.cpp file. The main.cpp file contains the
global slicing logic.
The slicing process follows the following global steps:

Load 3D model
Analize and fix 3D model
Slice 3D model into 2D layers
Build LayerParts from sliced layers
Generate Insets
Generate up/down skins areas
Generate sparse infill areas
Generate GCode for each layer
Each step has more logic in it. But this is a general overview. All data for the engine is stored in
the "SliceDataStorage". It's important to remember that only the data from the previous step is
valid.
Coordinates are stored in 64bit integers as microns in the code. So if you see a value of 1000 then
this mean 1mm of distance. This is because Clipper works on 64bit integers and microns give a
high enough resolution without limiting the size too much. Note that there are some bits and
pieces of code that need to be careful about 64bit overflows, especially calculating lengths
sqrt(x*x+y*y) can cause overflows.
下面我把自己理解的意思说一下,英文烂,勿喷。
首先,Cura 不是一个标准的 C++工程,他大部分的函数都是在.h 文件中实现的,这样做,使
得在编译过程中优化出现了很多的错误,这主要是由于懒的原因….(..请跳过)。
切片程序的主要过程如下:
      i.导入 3D 模型(STL,OBJ 等等)。
     ii.分析并修复 3D 模型(源码里面貌似木有这一步…)。
    iii.将 3D 模型切割成 2D 层。
    iv.用上一步得到的 2D 图层形成 LayerParts(他们自己的叫法),因为一层里面,很有可
          能有很多个不同的多边形,比如桌子,他的四个角,切出来后是四个圆形,上一步
          中只是得到了四个圆形,而没有确定这四个圆形是属于同一层的。
     v.进一步确定 LayerParts 中,各个 part 间的关系,比如得到了两个圆,大圆套小圆,
          我们就需要确认,小圆是空心的,而大圆和小圆形成的圆环是实心的。
    vi.将需要实心打印的部分标记出来(100%填充)。
   vii.将需要空心打印的地方打印出来(部分填充)。
  viii.根据生成的 LayerParts 生成每一层的 G-code。
上述的每一步都有更多的逻辑关系在里面,但这只是一个工作的大概流程。切割引擎所有的
数据都存放在一个叫 SliceDataStorage 的类里面。记住,上述的每一步都是基于前一步的数
据来进行的。这里严格按照上述的流程来处理 3D 模型生成 G-code。另外,在代码里面,坐
标是用 64 位整数的形式存在的,比如,你在代码中看到的 1000,他实际代表了 1mm。这
样做是因为 Clipper 使用了 64 为整数来表示距离。
1.2 源码中几个重要的类
1. OptimizedModel
The OptimizedModel is a 3D model stored with vertex<->face relations. This gives touching face
relations which are used later on to slice into layers faster.

OptimizedModel 也是一个 3D 模型,只是他是对一开始导入的模型进行的优化,去除了 3D
模型中多余的数据,同时确立了 3D 模型中每个三角面之间的拓扑关系。这是整个软件最为
核心的一部分之一。他为后面一步进行切割做好了准备,没有他 slice 无法进行。
2.Slicer
While usually the whole GCode generation process is called Slicing. The slicer in the CuraEngine is
the piece of code that generates layers. Each layer has closed 2D polygons. These polygons are
generated in a 2 step process. First all triangles are cut into lines per layer, for each layer a "line
segment" is added to that layer. Next all these line-segments are connected to eachother to make
Polygons. The vertex<->face relations of the OptimizedModel help to make this process fast, as
there is a huge chance that 2 connecting faces also make 2 connecting line-segments. This code
also fixes up small holes in the 3D model, so your model doesn't need to be perfect Manifold. It
also accounts for incorrect normals, so it can flip around line-segments to fit end-to-end.
After the Slicer we have closed Polygons which can be used in Clipper, as Clipper can only
opperate on closed 2D polygons.
我们通常都把由 3D 模型生成 G-code 的过程叫做 slicing.在 CuraEngine 中,Slicer 只是数量很
小的一部分代码,用于生成 layers。每个 layer 都有闭合的 2D 多边形。这些多边形的形成有
两步。
&#61548;&#61472;第一步,用一个切割平面同所有三角形做相交运算,得到和这个平面相交的线段就是属
     于这个 layer 的,这些切割后得到的线段称之为”linesegment”。此时,layer 里面只是有
     一些零散的线段。
&#61548;&#61472;第二步,将这些 linesegment 连起来,形成封闭的多边形。
由于 OptimizedModel 已经将各个相邻三角形之间的关系确立好了,这里的 slice 速度变得很
快。在进行完 slice 之后,我们就得到了封闭的多边形曲线,这些曲线,要交给 Clipper 库来
进行下一步的处理。Clipper 库只能用于处理 2D 的封闭多边形模型。(Clipper 的用途请 google)。
3. LayerParts
An important concept to grasp is the LayerParts. LayerParts are seperate parts inside a single layer.
For example, if you have a cube. Then each layer has a single LayerPart. However, if you have a
table, then the layers which build the legs have a LayerPart per leg, and thus there will be 4
LayerParts. A LayerPart is a seperated area inside a single layer which does not touch any other
LayerParts. Most operations run on LayerParts as it reduces the amount of data to process.
During GCode generation handling each LayerPart as an own step makes sure you never travel
between LayerParts and thus reducing the amount of external travel. LayerParts are generated
after the Slicer step.
To generate the LayerParts Clipper is used. A Clipper union with extended results gives a list of
Polygons with holes in them. Each polygon is a LayerPart, and the holes are added to this
LayerPart.
LayerParts 是需要掌握的一个重要概念。LayerParts 是一个单独的 layer 中的一部分。比如,
切割一个正方体,我们只会得到一个 LayerPart,但是,如果切割一个桌子,这个桌子有四
个脚,我们就会得到四个切面,也就是四个 LayerPart,我们把这在同一平面的四个 LayerPart

称为 layer。在生成 G-code 的过程中,都是对每个 LayerPart 单独操作,避免了打印机在两个
LayerPart 之间打印多余的东西。同时也减少了喷头运动的距离。为了生成 LayerPart,我们
要使用到 Clipper 库。
4 Up/Down skin
The skin code generates the fully filled areas, it does this with some heavy boolean Clipper action.
The skin step uses data from different layers to get the job done. Check the code for details. The
sparse infill area code is almost the same as the skin code. With the difference that it keeps the
other areas and uses different offsets.
Note that these steps generate the areas, not the actual infill lines. The infill line paths are
generated later on. So the result of this step are list of Polygons which are the areas that need to
be filled.
这部分的功能是确定模型中,需要完全被填充的部位,这里大量使用了 Clipper 库里面的布
尔运算。如果自己看 Cura 的代码会发现,这里的 skin(完全填充)和 sparse fill(稀疏填充)的代
码是几乎一样的,只是设置了不同的填充比例而已。注意,这一步只是标记了需要填充的区
域,真正的填充操作是在下面一步生成 G-code 的过程中进行。
5 G-code 生成器
The GCode generation is quite a large bit of code. As a lot is going on here. Important bits here
are:
PathOrderOptimizer: This piece of code needs to solve a TravelingSalesmanProblem. Given a list
of polygons/lines it tries to find the best order in which to print them. It currently does this by
finding the closest next polygon to print.
Infill: This code generates a group of lines from an area. This is the code that generates the
actuall infill pattern. There is also a concentric infill function, which is currently not used.
Comb: The combing code is the code that tries to avoid holes when moving around the head
without printing. This code also detects when it fails. The final GCode generator uses the
combing code while generating the final GCode. So they interact closely.
GCodeExport: The GCode export is a 2 step process. First it collects all the paths for a layer that it
needs to print, this includes all moves, prints, extrusion widths. And then it generates the final
GCode. This is the only piece of code that has knowledge about GCode, and to generate a
different flavor of GCode it will be the only piece that needs adjustment. All volumatric
calculations also happen here.
G-code 生成器有非常多的代码,这里给出他主要的几个点:
&#61548;&#61472;PathOrderOptimizer:这部分代码是路径优化代码,计算最优路径。提供很多歌多边形,
       然后找到最好的顺序和最好的路径来走完他们。比如,你打印完这一个 LayerPart 后,
       你需要找到下一个离他最近的 LayerPart 多边形来打印
&#61548;&#61472;Infill :这部分代码会在一个区域里生成一组线。
&#61548;&#61472;Comb:这部分的代码,是为了避免在打印机不喷丝时移动喷头而不会同打印好的层发
       生接触从而产生一些不好的洞。
&#61548;&#61472;GCodeExport:导出 G-code 分为两个步骤,首先,他将需要打印的那一层(layer,不是

LayerPart)的所有路径收集起来,包括移动,打印,挤出宽度等。然后生成最终的 G-code。
只有这一部分的代码是和 G-code 直接相关的。要生成不同的 G-code,只需要在这里做
少量的调整即可。另外,对模型体积的计算,也是在这一步中计算出来的。

声明:3D打印资源库(3dzyk)内网友所发表的所有内容及言论仅代表其本人,并不代表3D打印资源库(3dzyk)观点和立场;如对文章有异议或投诉,请联系kefu@3dzyk.cn。
标签:
CuraEngine 基本工作流程 绝对的干货 
快速回复 返回顶部 返回列表