SLA打印機之Slc文件解析
SLA打印機
打印文件SLC
解析和java
實現。
SLC format
SLC format
The SLC file format is a “21/2D” contour representation of a CAD model.
SLC術語定義
Segment (線段):兩點(x/y)之間的連線
Polyline(折線):一組連續線段的集合,折現必須是閉合的(最後一個點和第一個點坐標一致)
Boundary(輪廓):輪廓是一個閉合的折線(Polyline)來表示的填充固體材料範圍。輪廓又分為外輪廓和內輪廓。外輪廓(Boundary)為逆時針,內輪廓為順時針。
slc
文件包括 Header section
3-D reserved section
,Sample Table section
以及Contour Data section
Header section
頭文件部分為ASCII字符串,包括部分全局參數信息。
頭文件以回車、換行符和control-Z 字符(0x0d,0x0a,0x1a) 結束
最大2018bytes(包括換行符)
頭部你可以用關鍵字追蹤你需要的參數
-SLCVER <X.X>
SLC
文件格式版本號-UNIT <INCH/MM>
SLC
文件單位 INCH(英寸)或是MM(毫米)-TYPE <PART/SUPPORT/WEB>
CAD模型類型
PART
SUPPORT
必須是閉合輪廓 ,WEB
可以是打開的-PACKAGE <vendor specific>
供應商名稱,最多可以有32字節-EXTENTS <minx,maxx miny,maxy minz,maxz>
CAD模型
x,y,z軸的範圍
其他參照上述文檔。
3-D reserved section
This 256 byte section is reserved for future use.
跳過 256byte
即可。
Sample Table section
Sample Table
中每個 entry
表示一組Layer Thickness
每層層高、,Line Width Compensation
每個 entry
的信息,包括Minimum Z Level
z軸最小值(垂直方向起始位置),Layer Thickness
每層層高,Line Width Compensation
線寬補償,Reserved
預留字段
Sampling Table Size (1 Byte)
Sampling Table Entry (4 Floats)
Minimum Z Level (1 Float)
Layer Thickness (1 Float)
Line Width Compensation (1 Float)
Reserved (1 Float)
Contour Data Section
輪廓數據
數據格式:
Z layer
Z軸高度Number of Boundaries
輪廓數量Number of Vertices for the 1st Boundary
第一個輪廓點個數Number of Gaps for the 1st Boundary
第一個輪廓間隙數Vertex List for 1st Boundary
第一個輪廓點List
最後一個層由Z layer
和Termination Value Unsigned Integer
結束字符串 0xFFFFFFFF
表示
Z Layer 0.4 (1Float)
Number of Boundaries 2 (1 Unsigned Integer)
Number of Vertices for the 1st Boundary 5 (1 Unsigned Integer)
Number of Gaps for the 1st Boundary 0 (1 Unsigned Integer)
Vertex List for 1st Boundary 0.0, 0.0 (Number of Vertices * 2 Float)
1.0, 0.0
1.0, 1.0
0.0, 1.0
0.0, 0.0187
Number of Vertices for the 2nd Boundary 5
Number of Gaps for the 2nd Boundary 0
Vertex List for the 2nd Boundary 0.2, 0.2
0.2, 0.8
0.8, 0.8
0.8, 0.2
0.2, 0.2
A SLC File Example
[Header]
HeaderStr=-SLCVER 2.0 -UNIT MM -TYPE PART -PACKAGE
MATERIALISE C-TOOLS 2.xx -EXTENTS 10.000000,38.000000
10.000000,66.660600 6.000000,14.000000 –CHORDDEV
[Sampling_Table]:
Sampling_Table_Size=1
TableEntry_N=Minimum Z Level,Layer Thickness,Line Width
Compensation,Reserved
TE0=6.0000000000,0.1250000000,0.0250000000,0.0250000000
[Layer1]
z=6.0000000000
NContours=2.0000000000
VC1=5
GC1=0
C1PT0=10.125000000,26.785600000
C1PT1=10.125000000,66.535600000
C1PT2=37.875000000,66.535600000
C1PT3=37.875000000,26.785600000194
C1PT4=10.125000000,26.785600000
VC2=5
GC2=0
C2PT0=30.000000000,40.000000000
C2PT1=20.000000000,40.000000000
C2PT2=20.000000000,30.000000000
C2PT3=30.000000000,30.000000000
C2PT4=30.000000000,40.000000000
VC3=5
GC3=0
C3PT0=30.000000000,47.000000000
C3PT1=20.000000000,47.000000000
C3PT2=20.000000000,42.000000000
C3PT3=30.000000000,42.000000000
C3PT4=30.000000000,47.000000000
VC4=5
GC4=0
C4PT0=30.000000000,60.000000000
C4PT1=20.000000000,60.000000000
C4PT2=20.000000000,50.000000000
C4PT3=30.000000000,50.000000000
C4PT4=30.000000000,60.000000000
Java實現
try {
modelFis = new FileInputStream(modelFile);
/**
*
* header string 最大字符串2048
* header string 結束字符 0x0d,0x0a,0x1a
*/
int b;
StringBuilder builder = new StringBuilder();
while (builder.length() < 2048) {
b = modelFis.read();
builder.append((char) b);
if (b == 0x0d) {
b = modelFis.read();
builder.append((char) b);
if(b == 0x0a){
b = modelFis.read();
builder.append((char) b);
if(b == 0x1a){
break;
}
}
}
}
/**
* reserved section 跳過預留的256byte
*
*/
modelFis.skip(256);
/**
* sampleing table section
* sampleing table 每個entry 1 byte size
* sampleing table 每個entry 4 float ,將minZ和thickness 保存
*/
b = modelFis.read();
layerMap = new HashMap<>(b);
byte[] entry = new byte[16];
for (int i = 0; i < b; i++) {
modelFis.read(entry);
float minZ = Float.intBitsToFloat(Utils.getIntByLittleEndian(entry, 0));
float thickness = Float.intBitsToFloat(Utils.getIntByLittleEndian(entry, 4));
layerMap.put(minZ, thickness);
if(i == 0){
layerThickness = thickness;
}
}
/**
* Contour Data Section
* 如果是最後一層 `z layer`和終止符 2 float , 打印結束
* 如果不是 `z layer`和邊界數量
*
*
*/
supportFis.read(tmp);
supportBoundary = getIntByLittleEndian(tmp, 4);
if(supportBoundary == 0xFFFFFFFF){
LogUtil.w(TAG, "support finished");
return false;
}else{
for(int i=0;i<supportBoundary;i++){
supportFis.read(tmp);
int vertices = Utils.getIntByLittleEndian(tmp, 0);
// 這裏的 vertices * 8 便是每層的點
supportFis.skip(vertices*8);
}
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
到這一步你就已經取到了所有的vertices
,結合一定的掃描填充算法就可以完成slc文件的打印。
打印
掃描填充算法
例仿 UnionTech聯泰
,
可以模型的每層自下往上生成一系列連續的輔助線,求出輔助線和模型內外輪廓交線。
如下圖:
藍色為輔助線,紅色、綠色為輔助線和輪廓交線也就是最後填充部分,為了較大程度避免激光的開關將先填充部分分為兩塊,先填充紅色部分再填充綠色部分。
打印效果:
SLA打印機之Slc文件解析