STL (STereoLithography, 立体光刻)是由3D Systems软件公司创立、原本用于立体光刻计算机辅助设计软件的文件格式。STL文件仅描述三维物体的表面几何形状,没有颜色、材质贴图或其它常见三维模型的属性。STL只能用来表示封闭的面或者体,STL格式有文字和二进码两种型式。二进码型式因较简洁而较常见。
STL档描述原始非结构化三角网格由表面单位法线和由右手定则排序的顶点用三维三角形笛卡儿座标系。STL座标必须是正数,没有尺度信息,且计量单位为任意的。
STL文件格式看似能用多边形来定义多面体,但在实用上它只被用过三角形。这表示ASCII协议的语法是多余的。
要能正确组成3D体,STL档表示的表面必须是封闭同相连的,且每个边都正好是二个三角形的一部分,且没有交叉。 由于STL语法对此属性不严紧,应用程序能忽视其封闭性。
作为切片的该软件的封闭性仅事项只要三角形需要它以确保所得到的二维的多边形是封闭的。对切片三角形后须确保所得到的2D多边形是封关闭的软件而言,封闭性才会重要。
ASCII码格式的STL文件逐行给出三角面片的几何信息,每一行以1个或2个关键字开头。
在STL文件中的三角面片的信息单元 facet 是一个带矢量方向的三角面片,STL三维模型就是由一系列这样的三角面片构成。
整个STL文件的首行给出了文件路径及文件名。
在一个 STL文件中,每一个facet由7 行数据组成,
facet normal 是三角面片指向实体外部的法矢量坐标,
outer loop 说明随后的3行数据分别是三角面片的3个顶点坐标,3顶点沿指向实体外部的法矢量方向逆时针排列。 [2]
ASCII格式的STL 文件结构如下:
明码://字符段意义
solidfilenamestl//文件路径及文件名
facetnormalxyz//三角面片法向量的3个分量值
outerloop
vertexxyz//三角面片第一个顶点坐标
vertexxyz//三角面片第二个顶点坐标
vertexxyz//三角面片第三个顶点坐标
endloop
endfacet//完成一个三角面片定义
......//其他facet
endsolidfilenamestl//整个STL文件定义结束
由于文字STL档会非常大,因此有二进码版的STL。
二进制STL文件用固定的字节数来给出三角面片的几何信息。
文件起始的80个字节是文件头,用于存贮文件名;
紧接着用 4 个字节的整数来描述模型的三角面片个数,后面逐个给出每个三角面片的几何信息。每个三角面片占用固定的50个字节,依次是:
3个4字节浮点数(角面片的法矢量);
3个4字节浮点数(1个顶点的坐标);
3个4字节浮点数(2个顶点的坐标);
3个4字节浮点数(3个顶点的坐标)个;
三角面片的最后2个字节用来描述三角面片的属性信息。
一个完整二进制STL文件的大小为三角形面片数乘以 50再加上84个字节。
二进制:
UINT8//Header//文件头
UINT32//Numberoftriangles//三角面片数量
//foreachtriangle(每个三角面片中)
REAL32[3]//Normalvector//法线矢量
REAL32[3]//Vertex1//顶点1坐标
REAL32[3]//Vertex2//顶点2坐标
REAL32[3]//Vertex3//顶点3坐标
UINT16//Attributebytecountend//文件属性统计
使用vtkSTLWriter生产的stl文件,格式好像与上文的内容不同;
文件开始部分为:Visualization Toolkit generated SLA File
读取ASCII或二进制立体光刻文件
vtkSTLReader是读取ASCII或二进制立体光刻文件(.stl文件)的源对象。必须将文件名指定给vtkSTLReader。对象自动检测文件是ASCII还是二进制。
.stl文件效率很低,因为它们重复顶点定义。通过设置合并布尔值,可以控制读取后是否合并点数据。默认情况下执行合并,但是,合并需要大量的临时存储,因为必须构造3D哈希表。
注意:在一个系统上写入的二进制文件在其他系统上可能不可读。vtkSTLWriter使用VAX或PC字节排序,并在其他系统上交换字节。在STL文件中的二进制字节顺序,不同系统下的大端法或者小端法的读取和写入是不同的;
vtkSTLReader继承自vtkAbstractPolyDataReader;
重载了函数virtual void SetFileName (const char *);
使用也很简单;
vtkNew<vtkSTLReader> reader;
reader->SetFileName(inputFilename.c_str());
reader->Update();
一个可以使用vtk-8.2的例子:
#include "pch.h"
#include
#include "vtkSTLReader.h"
#include "vtkShrinkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkLODActor.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkCamera.h"
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);
using namespace std;
int main()
{
vtkSTLReader *part = vtkSTLReader::New();
part->SetFileName("G:\\out.stl");
vtkPolyDataMapper *partMapper = vtkPolyDataMapper::New();
partMapper->SetInputConnection(part->GetOutputPort());
vtkLODActor *partActor = vtkLODActor::New();
partActor->SetMapper(partMapper);
partActor->GetProperty()->SetColor(0.8275, 0.8275, 0.8275);
partActor->RotateX(30.0);
partActor->RotateY(-45.0);
vtkRenderer *ren1 = vtkRenderer::New();
ren1->AddActor(partActor);
ren1->SetBackground(0.1, 0.2, 0.4);
ren1->ResetCamera();
ren1->GetActiveCamera()->Zoom(1.5);
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(ren1);
renWin->SetSize(200, 200);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
iren->Initialize();
iren->Start();
system("pause");
return 0;
}
附上可以使用的vtk lib库地址:
链接:https://pan.baidu.com/s/1019lasMC9J1URvcpSbkpUQ 提取码:3sp1
运行效果如下图:
vtkSTLWriter以ASCII或二进制格式写入立体光刻(.stl)文件。
立体光刻文件只包含三角形。由于VTK 8.1,此vtkSTLWriter将非三角形多边形转换为三角形,因此如果输入包含具有三个以上顶点的多边形,则在使用此vtkSTLWriter之前不再需要使用vtkTriangleFilter。
同vtkSTLReader一样,不同系统需要注意大端法和小端法的问题;
使用SetInputData和SetInputConnection函数接受需要保存STL文件的输入流;
vtkSTLWriter提供函数:
vtkSetClampMacro(FileType, int, VTK_ASCII, VTK_BINARY);
vtkGetMacro(FileType, int);
void SetFileTypeToASCII() { this->SetFileType(VTK_ASCII); }
void SetFileTypeToBinary() { this->SetFileType(VTK_BINARY); }
用来控制STL文件是ASCII码文件还是二进制文件;
通常设置输出的STL文件为二进制类型,二进制占用更小的内存;
使用也很简单:
vtkNew<vtkSTLWriter> stlWriter;
stlWriter->SetFileName(filename.c_str());
stlWriter->SetInputConnection(sphereSource->GetOutputPort());
stlWriter->Write();
生成一个圆锥体,生成STL文件;
vtkConeSource *cone = vtkConeSource::New();
cone->SetHeight(3.0);
cone->SetRadius(1.0);
cone->SetResolution(10);
cone->Update();
vtkNew<vtkSTLWriter> stlWriter;
stlWriter->SetFileName("G:\\out.stl");
stlWriter->SetInputConnection(cone->GetOutputPort());
stlWriter->Write();
没有设置FileType时,默认为ASCII文件;
这段代码会生成下图的STL文件,文件大小为3KB;
vtkConeSource *cone = vtkConeSource::New();
cone->SetHeight(3.0);
cone->SetRadius(1.0);
cone->SetResolution(10);
cone->Update();
vtkNew<vtkSTLWriter> stlWriter;
stlWriter->SetFileName("G:\\out.stl");
stlWriter->SetInputConnection(cone->GetOutputPort());
stlWriter->SetFileTypeToBinary();
stlWriter->Write();
设置了SetFileTypeToBinary;生成二进制文件;
STL文件中的内容如下,STL文件大小为1KB:
1.stl格式
2.《医学图像编程技术》
3.VTK C++ 例子