当前位置: 首页 > 工具软件 > CuraEngine > 使用案例 >

3D打印机切片引擎CuraEngine源码分析<四> CuraEngine中的ReadMe解读,CuraEngine的版本介绍

薛坚
2023-12-01

这篇博客是关于CuraEngine的ReadMe文件解读以及Cura相关的版本问题的汇总。很多遇到的问题,其实在官方的ReadMe文件中都能找到答案。

1. CuraEngine的ReadMe

这里把自己一年前在南极熊上翻译的一篇文章拿过来吧。

1.1    总流程
The Cura Engine is structured as mainly .hfiles. This is not standard for an C++ project. However, using less cpp filesmakes the optimizer work harder and removes linking error issues. It's partialya result of lazyness but also for optimalizations.
The .h files contain different steps calledfrom the main.cpp file. The main.cpp file contains the global slicing logic.
The slicing process follows the followingglobal 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 isa general overview. All data for the engine is stored in the"SliceDataStorage". It's important to remember that only the data fromthe previous step is valid.
Coordinates are stored in 64bit integers asmicrons in the code. So if you see a value of 1000 then this mean 1mm ofdistance. This is because Clipper works on 64bit integers and microns give ahigh enough resolution without limiting the size too much. Note that there aresome 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 storedwith vertex<->face relations. This gives touching face relations whichare used later on to slice into layers faster.
OptimizedModel也是一个3D模型,只是他是对一开始导入的模型进行的优化,去除了3D模型中多余的数据,同时确立了3D模型中每个三角面之间的拓扑关系。这是整个软件最为核心的一部分之一。他为后面一步进行切割做好了准备,没有他slice无法进行。
  2.   Slicer
While usually the whole GCode generationprocess is called Slicing. The slicer in the CuraEngine is the piece of codethat generates layers. Each layer has closed 2D polygons. These polygons aregenerated in a 2 step process. First all triangles are cut into lines perlayer, for each layer a "line segment" is added to that layer. Nextall these line-segments are connected to eachother to make Polygons. Thevertex<->face relations of the OptimizedModel help to make this processfast, as there is a huge chance that 2 connecting faces also make 2 connectingline-segments. This code also fixes up small holes in the 3D model, so yourmodel doesn't need to be perfect Manifold. It also accounts for incorrectnormals, so it can flip around line-segments to fit end-to-end.
After the Slicer we have closed Polygonswhich can be used in Clipper, as Clipper can only opperate on closed 2Dpolygons.

我们通常都把由3D模型生成G-code的过程叫做slicing.在CuraEngine中,Slicer只是数量很小的一部分代码,用于生成layers。每个layer都有闭合的2D多边形。这些多边形的形成有两步。
l  第一步,用一个切割平面同所有三角形做相交运算,得到和这个平面相交的线段就是属于这个layer的,这些切割后得到的线段称之为”linesegment”。此时,layer里面只是有一些零散的线段。
l  第二步,将这些linesegment连起来,形成封闭的多边形。
由于OptimizedModel已经将各个相邻三角形之间的关系确立好了,这里的slice速度变得很快。在进行完slice之后,我们就得到了封闭的多边形曲线,这些曲线,要交给Clipper库来进行下一步的处理。Clipper库只能用于处理2D的封闭多边形模型。(Clipper的用途请google)。

  3. LayerParts
An important concept to grasp is theLayerParts. LayerParts are seperate parts inside a single layer. For example,if you have a cube. Then each layer has a single LayerPart. However, if youhave 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 asingle layer which does not touch any other LayerParts. Most operations run onLayerParts as it reduces the amount of data to process. During GCode generationhandling each LayerPart as an own step makes sure you never travel betweenLayerParts and thus reducing the amount of external travel. LayerParts are generatedafter the Slicer step.
To generate the LayerParts Clipper is used.A Clipper union with extended results gives a list of Polygons with holes inthem. 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 filledareas, it does this with some heavy boolean Clipper action. The skin step usesdata from different layers to get the job done. Check the code for details. Thesparse infill area code is almost the same as the skin code. With thedifference 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. Sothe result of this step are list of Polygons which are the areas that need tobe filled.
这部分的功能是确定模型中,需要完全被填充的部位,这里大量使用了Clipper库里面的布尔运算。如果自己看Cura的代码会发现,这里的skin(完全填充)和sparse fill(稀疏填充)的代码是几乎一样的,只是设置了不同的填充比例而已。注意,这一步只是标记了需要填充的区域,真正的填充操作是在下面一步生成G-code的过程中进行。
  5. G-code 生成器
The GCode generation is quite a large bitof code. As a lot is going on here. Important bits here are:
PathOrderOptimizer: This piece of codeneeds to solve a TravelingSalesmanProblem. Given a list of polygons/lines ittries to find the best order in which to print them. It currently does this byfinding the closest next polygon to print.
Infill: This code generates a group oflines 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 thattries to avoid holes when moving around the head without printing. This codealso detects when it fails. The final GCode generator uses the combing codewhile generating the final GCode. So they interact closely.
GCodeExport: The GCode export is a 2 stepprocess. 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 thefinal GCode. This is the only piece of code that has knowledge about GCode, andto generate a different flavor of GCode it will be the only piece that needsadjustment. All volumatric calculations also happen here.


G-code生成器有非常多的代码,这里给出他主要的几个点:
l  PathOrderOptimizer:这部分代码是路径优化代码,计算最优路径。提供很多歌多边形,然后找到最好的顺序和最好的路径来走完他们。比如,你打印完这一个LayerPart后,你需要找到下一个离他最近的LayerPart多边形来打印
l  Infill :这部分代码会在一个区域里生成一组线。
l  Comb:这部分的代码,是为了避免在打印机不喷丝时移动喷头而不会同打印好的层发生接触从而产生一些不好的洞。
l  GCodeExport:导出G-code分为两个步骤,首先,他将需要打印的那一层(layer,不是LayerPart)的所有路径收集起来,包括移动,打印,挤出宽度等。然后生成最终的G-code。只有这一部分的代码是和G-code直接相关的。要生成不同的G-code,只需要在这里做少量的调整即可。另外,对模型体积的计算,也是在这一步中计算出来的。

2. CuraEngine的版本问题

首先,要搞清楚,cura和curaengine是放在两个不同的项目中的,cura只是一个客户端,一个用来显示和编辑三维模型的软件,curaengine是一个切片引擎,cura在源码中,直接调用了curaengine程序。另外,cura只是负责界面,使用python进行开发,而curaengine是一个引擎,使用C++进行开发。目前,最新发布的是15.06版本,在cura和curaengine的master下拉框中,都能找到对应的已经发布的版本源码。目前的master版本已经超出了发布版本很多,代码几乎每天都有变化,所以,如果是第一次尝试去学习cura或者curaengine的源码,建议不要下最新的版本(master版本和15.xx的版本)。

这里建议使用legacy这个版本。这个版本之后的一些版本,数据结构有很大的变化,使用了很多C++11的特性。编译这些今年最新的版本需要特别细心。

3. 怎么编译

如果是在Linux环境下编译,那么好好看文档,一步一步照着来,就能通过,但如果是在win下面编译,会有比较多的问题。这里列举编译新版本的几点:
    
  • 使用支持C++11特性的编译器,Mingw4.8以上
  • 从源码编译时,去掉所有socket相关的代码。
主要是这两点。其他的问题,按照编译出错去修改,很快就能搞定。


 类似资料: