本帖最后由 HappyBird 于 2015-4-27 00:10 編輯
3D打印機(jī)的一個核心就是它的切片軟件,目前開源的有Slice3r, Skeinforge,Cura等..筆者見到國內(nèi)大部分的使用都只是將他們漢化而已,沒有真正發(fā)揮出開源軟件的作用。想起自己在研究這些開源軟件的源碼時(shí),走過了很多彎路,同時(shí)收獲也很大。在這里,分享一些個人的經(jīng)驗(yàn),希望對想通過修改核心軟件來提升打印機(jī)質(zhì)量得到提升的達(dá)人們有幫助。也歡迎各位一起來交流!加群383853870或Q:805318580 小知識補(bǔ)充: 在知道CuraEngine的工作原理之前,需要先知道STL格式的含義。.stl 文件是在計(jì)算機(jī)圖形應(yīng)用系統(tǒng)中,用于表示三角形網(wǎng)格的一種文件格式。它的文件格式非常簡單,應(yīng)用很廣泛。STL是最多快速原型系統(tǒng)所應(yīng)用的標(biāo)準(zhǔn)文件類型。STL是用三角網(wǎng)格來表現(xiàn)3D CAD模型。Stl文件中存放的是無數(shù)個空間三角面的位置信息(空間中,每個三角面的確定是通過它三個定點(diǎn)的坐標(biāo)來的)。所以,我們?nèi)绻獙σ粋3D模型進(jìn)行切割,實(shí)際上就是用一個平面來和無數(shù)小三角形做相交,得到很多條交線,我們把這些交線連接起來就得到了切平面。 CuraEngine基本工作流程 筆者一開始就選擇了Cura作為研究對象,有兩個原因:一是slice3R的切片速度明顯不如Cura,二是,Cura的切片引擎使用的是C++…這是筆者所鐘愛的開發(fā)語言。雖然Cura的界面是用Python語言寫的,但這不影響底層切片軟件引擎的使用。 下面是CuraEngine的github上關(guān)于Cura項(xiàng)目的介紹和描述。 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不是一個標(biāo)準(zhǔn)的C++工程,他大部分的函數(shù)都是在.h文件中實(shí)現(xiàn)的,這樣做,使得在編譯過程中優(yōu)化出現(xiàn)了很多的錯誤,這主要是由于懶的原因….(..請?zhí)^)。 切片程序的主要過程如下: i. 導(dǎo)入3D模型(STL,OBJ等等)。 ii. 分析并修復(fù)3D模型(源碼里面貌似木有這一步…)。 iii. 將3D模型切割成2D層。 iv. 用上一步得到的2D圖層形成LayerParts(他們自己的叫法),因?yàn)橐粚永锩,很有可能有很多個不同的多邊形,比如桌子,他的四個角,切出來后是四個圓形,上一步中只是得到了四個圓形,而沒有確定這四個圓形是屬于同一層的。 v. 進(jìn)一步確定LayerParts中,各個part間的關(guān)系,比如得到了兩個圓,大圓套小圓,我們就需要確認(rèn),小圓是空心的,而大圓和小圓形成的圓環(huán)是實(shí)心的。 vi. 將需要實(shí)心打印的部分標(biāo)記出來(100%填充)。 vii. 將需要空心打印的地方打印出來(部分填充)。 viii. 根據(jù)生成的LayerParts生成每一層的G-code。 上述的每一步都有更多的邏輯關(guān)系在里面,但這只是一個工作的大概流程。切割引擎所有的數(shù)據(jù)都存放在一個叫SliceDataStorage的類里面。記住,上述的每一步都是基于前一步的數(shù)據(jù)來進(jìn)行的。這里嚴(yán)格按照上述的流程來處理3D模型生成G-code。另外,在代碼里面,坐標(biāo)是用64位整數(shù)的形式存在的,比如,你在代碼中看到的1000,他實(shí)際代表了1mm。這樣做是因?yàn)?/font>Clipper使用了64為整數(shù)來表示距離。
1.2 源碼中幾個重要的類 1. OptimizedModelThe 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模型,只是他是對一開始導(dǎo)入的模型進(jìn)行的優(yōu)化,去除了3D模型中多余的數(shù)據(jù),同時(shí)確立了3D模型中每個三角面之間的拓?fù)潢P(guān)系。這是整個軟件最為核心的一部分之一。他為后面一步進(jìn)行切割做好了準(zhǔn)備,沒有他slice無法進(jìn)行。
2. SlicerWhile 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只是數(shù)量很小的一部分代碼,用于生成layers。每個layer都有閉合的2D多邊形。這些多邊形的形成有兩步。 - l 第一步,用一個切割平面同所有三角形做相交運(yùn)算,得到和這個平面相交的線段就是屬于這個layer的,這些切割后得到的線段稱之為”linesegment”。此時(shí),layer里面只是有一些零散的線段。
- l 第二步,將這些linesegment連起來,形成封閉的多邊形。
由于OptimizedModel已經(jīng)將各個相鄰三角形之間的關(guān)系確立好了,這里的slice速度變得很快。在進(jìn)行完slice之后,我們就得到了封閉的多邊形曲線,這些曲線,要交給Clipper庫來進(jìn)行下一步的處理。Clipper庫只能用于處理2D的封閉多邊形模型。(Clipper的用途請google)。
3. LayerPartsAn 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是一個單獨(dú)的layer中的一部分。比如,切割一個正方體,我們只會得到一個LayerPart,但是,如果切割一個桌子,這個桌子有四個腳,我們就會得到四個切面,也就是四個LayerPart,我們把這在同一平面的四個LayerPart稱為layer。在生成G-code的過程中,都是對每個LayerPart單獨(dú)操作,避免了打印機(jī)在兩個LayerPart之間打印多余的東西。同時(shí)也減少了噴頭運(yùn)動的距離。為了生成LayerPart,我們要使用到Clipper庫。
4.Up/Down skinThe 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庫里面的布爾運(yùn)算。如果自己看Cura的代碼會發(fā)現(xiàn),這里的skin(完全填充)和sparse fill(稀疏填充)的代碼是幾乎一樣的,只是設(shè)置了不同的填充比例而已。注意,這一步只是標(biāo)記了需要填充的區(qū)域,真正的填充操作是在下面一步生成G-code的過程中進(jìn)行。
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生成器有非常多的代碼,這里給出他主要的幾個點(diǎn): - l PathOrderOptimizer:這部分代碼是路徑優(yōu)化代碼,計(jì)算最優(yōu)路徑。提供很多歌多邊形,然后找到最好的順序和最好的路徑來走完他們。比如,你打印完這一個LayerPart后,你需要找到下一個離他最近的LayerPart多邊形來打印
- l Infill :這部分代碼會在一個區(qū)域里生成一組線。
- l Comb:這部分的代碼,是為了避免在打印機(jī)不噴絲時(shí)移動噴頭而不會同打印好的層發(fā)生接觸從而產(chǎn)生一些不好的洞。
- l GCodeExport:導(dǎo)出G-code分為兩個步驟,首先,他將需要打印的那一層(layer,不是LayerPart)的所有路徑收集起來,包括移動,打印,擠出寬度等。然后生成最終的G-code。只有這一部分的代碼是和G-code直接相關(guān)的。要生成不同的G-code,只需要在這里做少量的調(diào)整即可。另外,對模型體積的計(jì)算,也是在這一步中計(jì)算出來的。
|