3D打印切片软件支撑算法研究

3D打印切片软件支撑算法研究

一、为何需要自动支撑?

3D打印与传统模具制造方式不同,3D打印是增材制造,将模型整体分割成n层,逐层打印的过程,每一层是基于上一层的基础之上的累加。目前根据设备机构主要分为以下几个大类:FDM,LCD,SLM,SLA,DLP。
其中:
FDM也称耗材3d打印,主要材料为pla,abs等,如创想三维、anycubic,目前消费级机型售价大概1500–3000之间,各种变种,如最新比较潜力的“发光字打印机”、以水泥为打印材料,多彩色打印(以磨合为辅助,切片时记录纹理信息)
LCD为两年前开始出现的机型,属于光固化系列,材料为光敏树脂,精度比FDM高很多,可以打印的很精细,市面低端1500–3000如anycubic,浙江锐辰等,高端的上万元或以上,如Preform,诺瓦智能,金达雷等,目前局限是打印尺寸小,以及分辨率大多数为2k,少部分企业正在尝试4k屏,如能顺利即可解决水波纹、大尺寸等问题,将是一个新的提升
SLM为金属粉末烧结技术,材料为金属,精度非常高,可打印航空材料,都是有钱的大公司才会研发这样的设备,如先临
SLA激光束在液态树脂表面勾画出物体形状,层层打印出模型,速度比较慢,但精度较高,成本也较大,大公司sla设备以极光尔沃、大族激光等为主
DLP和LCD类似,但比LCD精度更高,利用数字光投影技术,目前成本较大,感兴趣的可具体去了解
为何要支撑?
3d打印,逐层累加,就无法避免层突变,即悬空打印,上一层无材料的情况下,突变当前层,无支撑时必然会“掉”到工作平台之上,导致打印失败。

  • 1、解决悬空的情况。
  • 2、防止特有的几何面被破坏,故意抬升添加支撑
  • 3、保持横截面变化均匀,受力均匀,以免模型内应力导致模型变形

二、扫描待支撑的区域

目前待打印模型多数为stl、obj、3mf等数字化模型文件,都是以三角面片为载体记录模型信息,模型文件的可视化效果如下:

很多切片软件中对三角面片的边不显示,看起来就为一体,对于用户来讲是透明的,而对于研发人员,三角面片才是数据的重点。 既然待打印模型都是三角面片的集合,应该如何寻找自动支撑的区域呢? 根据模型每个面片、每条边、给个顶点而言,具备局部的集合信息,需要对这些信息进行分析,分类,处理以达到支撑的效果。如典型的FDM,大多数都是基于curaengin为基础,很多人基于后面拓展。cura的支撑算法为,先分层切片,然后在当前层对比前面n层然后求差,得到当前层“超出”下方的部分,即为带支撑的部分,然后直接把支撑结构也进行切片,在打印过程中,一并打印。然而这种算法不适用于LCD类型设备,为何?因为LCD类型设备不可能打印这么多支撑,否则模型表面会全部磨坏,本身高精度的模型表面会稀巴烂。所以目前很多光固化设备的切片软件的自动支撑算法是:检测带支撑区域、然后对支撑区域进行采样支撑。

自动支撑常规步骤:

  • 1、检测模型的最低点
  • 2、检测模型的最低边
  • 3、检测法向量朝下的悬空面片
  • 4、对悬空面进行分区域处理
  • 5、对每个区域进行xy平面投影
  • 6、用栅格划分投影平面,然后得到栅格交点
  • 7、将交点利用重心坐标映射回模型的面片中
  • 8、将最低点+最低边+采样点组合为最终的支撑点
  • 9、生成支撑结构(如垂直结构、树状结构等)

检测模型的最低点:

如上图所示,模型非常复杂,怎么利用模型数据把最低点都检测出来呢?
如上图所示,Vi 点比邻域内vj点低,那么Vi就是局部最低点
int vn=mesh.vertexs.size();
for(int i=0;i<vn;i++)
{
	vector<int>neibors=mesh.neibors[i];
	vec vi=mesh.vertexs[i];
	int n=neibors.size();
	bool is_min_p=true;
	for(int j=0;j<n;j++)
	{
		int id=neibors[j];
		vec vj=mesh.vertexs[id];
		if(vi[2]>=vj[2])
		{
			is_min_p=false;
			break;
		}
	}
	if(is_min_p)
	{
		vertex_list.push_back(vi);
	}
}
检测最低边:
如上图所示,两个面片的公共边,en为边的法向量,由两个面片法向量fn加权平均求得,同时边与水平面的夹角alpha小于给定的阈值如45°,则认为是最低边
float angle=45*PI/180;
vec fn0=mesh.facenormal[i];
vec fn1=mesh.facenormal[j];
vec en=fn0+fn1;
normalize(en);
if(en DOT vec(0,0,1)<0)
{
	vec v0=mesh.vertexs[id0];
	vec v1=mesh.vertexs[id1];
	vec vp=v0-v1;
	float l0=len(vp);
	vp[2]=0;
	float l1=len(vp);
	float theta=acos(l1/l0);
	if(theta<angle)
	{
		edges_lists.push_back(eid);
	}
}
检测悬空面片
int fn=mesh.faces.size();
for(int i=0;i<fn;i++)
{
vec fn=mesh.facenormal[i];
if(fn DOT vec(0,0,1)<0)
{
face_lists.push_back(i);
}
}

分区域:

set<int>flist;
set<int>check_flags;
vector<vector<int>>regionset;
for(auto item:face_lists)flist.insert(item);
while(!flist.empty())
{
	vector<int>region;
	queue<int> Q;
	auto it=flist.begin();
	Q.push(*it);
	check_flags.inset(*it);
	flist.erase(it);
	while(!Q.empty())
	{
		int id=Q.front();
		Q.pop();
		region.push_back(id);
		Face f=mesh.faces[id];
		for(int i=0;i<3;i++)
		{
			int vid=f[i];
			vector<int>adsf=mesh.adjfaces[vid];
			for(auto fid:adsf)
			{
				auto itf=check_flags.find(fid);
				if(itf!=check_flags.end())continue;
				auto itlst=flist.find(fid);
				if(itlst!=flist.end())
				{
					flist.erase(itlsl);
					Q.push(fid);
				}
			}
		}
     }
     if(region.empty())continue;
     regionset.push_back(region);
}

采样点重映射回网格

float step=2;
int fn=region.size();
for(int i=0;i<fn;i++)
{
	auto f=mesh.faces[i];
	auto&v0=mesh.vertexs[f[0]];
	auto&v1=mesh.vertexs[f[1]];
	auto&v2=mesh.vertexs[f[2]];
	int minx=min(min(v0[0],v1[0]),v2[0]);
	int miny=min(min(v0[1],v1[1]),v2[1]);
	int maxx=max(max(v0[0],v1[0]),v2[0]);
	int maxy=max(max(v0[1],v1[1]),v2[1]);
	int xsid=floor((minx-mesh.min[0])/step);
	int ysid=floor((miny-mesh.min[1])/step);
	int xeid=floor((maxx-mesh.min[0])/step)+1;
	int yeid=floor((maxy-mesh.min[1])/step)+1;
	for(auto n=xsid;n<=xeid;n++)
		for(auto m=ysid;m<=yeid;m++)
		{
			vec v(mesh.min[0]+xsid*step,mesh.min[1]+ysid*step,0);
			flaot a,b,c;
			if(Point2DTo3D(v0,v1,v2,v,a,b,c))
			{
				vec p=a*v0+b*v1+c*v2;
				sample_lists.push_back(p);
			}
		}
}

三、生成支撑结构

支撑结构分多种,最常用的就是垂直方式,也有树状结构。垂直结构,比较牢固,但比较耗材,支撑也是成本。树状支撑比较省成本,但算法计算复杂,越往下根越少,趋于稀疏。

上面两幅图为一样的支撑点数量,生成的垂直支撑和树状支撑。 技巧:悬空区域大时建议用垂直支撑,更加牢固,稳定,若选用树状支撑,适当加粗枝干参数

四、自动支撑的局限与难点

  • 1、无法根据人为经验判断该处是否添加支撑
  • 2、复杂拓补结构的网格支撑非常困难
  • 3、建立网格拓补关系需要大量的内存消耗,大模型加支撑非常吃力,并导致渲染系统卡顿
  • 4、复杂模型的支撑碰撞检测相当繁琐
  • 5、支撑密度根据不同类型模型控制较为繁琐,需要不断测试,并无最合适的密度参数
  • 6、栅格采样法,会错过很多细小的特征,step跨度越大,错过概率越大,导致有些模型恰好都错过面片,支撑失败。后续升级为更好的支撑算法,支撑效果更理想。
发布了83 篇原创文章 · 获赞 24 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/LittleLittleFish_xyg/article/details/90474800
今日推荐