cura-engine学习(3)
目前,我们还在函数prepareModel中徘徊,因为这函数实在是太长了,近乎包含了整个数据处理过程。通过前面两篇,几何图形已经被导入到内存中,并且由一个simplemodel变成了一个optimizedmodel。现在程序拿起了屠刀,开始了切片过程。
通常来讲,在3D打印中所说的slicer过程包含了切割几何体,连接多边形,生成Gcode的所有过程,但在此程序中,slicer步仅为生成切片的切割操作。每一个切包含若干个闭合平面多边形。这些多边形的产生分两步。第一,所有的三角形面片被切割成为一条线段;第二,将每层的线段连接起来形成闭合多边形。前篇所述的点-面对应关系可以帮助这一过程快速进行,因为两个相邻的面上的切割线段很有可能就是相邻线段。这段程序还可以帮助修补几何图形中的空洞,因此STL模型不需要那么完美。它也可以处理错误的法向量,所以它可以翻转线段来满足端点到端点的连接。slicer步骤之后我们得到了一系列闭合多边形,然后会用到clipper来处理这些多边形(clipper只可以处理2D闭合多边形)。这一段来自cura-engine github主页的介绍。
切割过程代码在slicer.h和slicer.cpp这两个文件中。首先我们看其中的class slicer
SlicerSegment project2D(Point3& p0, Point3& p1, Point3& p2, int32_t z) const
{
SlicerSegment seg;
seg.start.X = p0.x + int64_t(p1.x - p0.x) * int64_t(z - p0.z) / int64_t(p1.z - p0.z);
seg.start.Y = p0.y + int64_t(p1.y - p0.y) * int64_t(z - p0.z) / int64_t(p1.z - p0.z);
seg.end.X = p0.x + int64_t(p2.x - p0.x) * int64_t(z - p0.z) / int64_t(p2.z - p0.z);
seg.end.Y = p0.y + int64_t(p2.y - p0.y) * int64_t(z - p0.z) / int64_t(p2.z - p0.z);
return seg;
}
class slicer中的这段代码是计算一个三角形p0,p1,p2和平面z的相交线的过程。就算公式也比较简单粗暴,如下

画得虽丑,但科学是美丽的,咳咳.。。。函数project2D所表达的就是上面的公式了,至于六种情况的分类,我们可以在构造函数slicer()里面找到。没错,就是那六排if-else
Slicer(OptimizedVolume* ov, int32_t initial, int32_t thickness, bool keepNoneClosed, bool extensiveStitching) 把优化过的几何体ov按照厚度(thickness)切割成片片即layer。函数的前大半部分计算了三角面上被切割得到的线段,这些线段只有起点和终点,之间没有什么联系。后小部分使用makepolygon函数将线段们连接成多边形。
for(unsigned int layerNr=; layerNr<layers.size(); layerNr++)
{
layers[layerNr].makePolygons(ov, keepNoneClosed, extensiveStitching);
}
那么makepolygon函数又如何呢,这是一个200多行的大函数。本篇只能学习一小部分,欲窥其全貌,要等到之后我们学习了class Polygons和class Polygon这些类之后才能领悟。本篇先看这一段:
Polygons openPolygonList;
for(unsigned int startSegment=; startSegment < segmentList.size(); startSegment++)
{
if (segmentList[startSegment].addedToPolygon)
continue;
Polygon poly;
poly.add(segmentList[startSegment].start);
unsigned int segmentIndex = startSegment;
bool canClose;
while(true)
{
canClose = false;
segmentList[segmentIndex].addedToPolygon = true;
Point p0 = segmentList[segmentIndex].end;
poly.add(p0);
int nextIndex = -;
OptimizedFace* face = &ov->faces[segmentList[segmentIndex].faceIndex];
for(unsigned int i=;i<;i++)
{
if (face->touching[i] > - && faceToSegmentIndex.find(face->touching[i]) != faceToSegmentIndex.end())
{
Point p1 = segmentList[faceToSegmentIndex[face->touching[i]]].start;
Point diff = p0 - p1;
if (shorterThen(diff, MM2INT(0.01)))
{
if (faceToSegmentIndex[face->touching[i]] == static_cast<int>(startSegment))
canClose = true;
if (segmentList[faceToSegmentIndex[face->touching[i]]].addedToPolygon)
continue;
nextIndex = faceToSegmentIndex[face->touching[i]];
}
}
}
if (nextIndex == -)
break;
segmentIndex = nextIndex;
}
if (canClose)
polygonList.add(poly);
else
openPolygonList.add(poly);
}
这一段讲述了把刚才求得的线段们连接成多边形的故事。可以看到,首先选取一个线段,然后通过它所在的三角面,找到和其相邻的三角面,在找到相邻三角面上的线段,查看其是否匹配,依次进行下去,最后会回到最初的那个三角面上,连接结束。

然而这种方法并不能完成所有的情况,比如几何体有一些缺陷什么的,后面的代码是针对各种情况所作的处理,这些目前还很难懂,因为在这之前要搞懂Polygon这个基础类到底是如何构建的。咱们下回分解。
cura-engine学习(3)的更多相关文章
- Google App Engine 学习和实践
这个周末玩了玩Google App Engine,随手写点东西,算是学习笔记吧.不当之处,请多多指正. 作者:liigo,2009/04/26夜,大连 原创链接:http://blog.csdn.ne ...
- Google Earth Engine学习资源分享
最近在学习Google Earth Engine的使用,发现这个平台确实是一个非常好用.非常强大的平台.在GEE官网上找到了一些中文的学习资料,现在搬运过来分享给大家共同学习.教程分为两个部分 教程一 ...
- Diligent Engine学习笔记初衷
2020年过去一个月了,回首过去的一年,工作确实很忙,但是自己个人的技术也没得到什么成长,项目当中一些比较难搞的问题也没得到更深入的研究.思来想去,希望新的一年能改变自己的工作方式,将工作上的事物进一 ...
- QLoo graphql engine 学习三 架构
一张官方的参考图 说明 Storage Layer API 参考了kubernetes 的设计 qloo 组成 qloo 有qloo 服务以及envoy proxy 组合而成,envoy proxy ...
- QLoo graphql engine 学习二 基本试用(kubernetes)
已经测试过docker&& docker-compose 的运行模式,下面测试下kubernetes的运行模式 kubernetes 我使用docker for mac qloo 安装 ...
- QLoo graphql engine 学习一 基本试用(docker&&docker-compose)
说明:使用docker-compose 进行安装 代码框架 使用命令行工具创建 qlooctl install docker qloo-docker 运行qloo&&gloo 启动 ...
- CE学习记录1
主题 春节放假终于有空学习下怎么制作外挂啦......学习写外挂大概是我一开始学习计算机的动力吧....只是一直似懂非懂..看教学视频各种不明白为什么....也没有专门的时间学习下怎么写....春节有 ...
- Gcode命令【转】
https://www.jianshu.com/p/f8a328457a45 简述 研究过3D打印机的朋友,都会用到G-code文件.要使用3D打印机打印东西要经过几个步骤: 1.创建3 ...
- 收购公司、孵化(产品)和被收购的20个短篇故事-BI产品的历史
原文地址: 20 short tales of acquiring companies, incubating (ideas into products) and being acquired. | ...
- SQLAlchemy 学习笔记(一):Engine 与 SQL 表达式语言
个人笔记,如有错误烦请指正. SQLAlchemy 是一个用 Python 实现的 ORM (Object Relational Mapping)框架,它由多个组件构成,这些组件可以单独使用,也能独立 ...
随机推荐
- Xcode 之 snippet 代码重用
1. 选中代码 2. 拖入xcode 右下侧的 snippet 区域 3. 修改名称 4. 修改快捷输入 (shortcut) 5. <#content#> ,可选修改项
- CodeForces 755C PolandBall and Forest (并查集)
题意:给定每一点离他最远的点,问是这个森林里有多少棵树. 析:并查集,最后统计不同根结点的数目即可. 代码如下: #pragma comment(linker, "/STACK:102400 ...
- Arcgis js API使用wmts方式加载GeoWebCache中的切片地图(转载)
使用GeoWebCache的主要目的是其独立安装版能够发布arcgis的切片.我们知道,使用openlayer是调用geoserver最方便的方法,那么在发布完arcgis的切片后,怎么用arcgis ...
- fold change(ratio)
fold change 英文简称 : FC 中文全称 : 倍性变化 所属分类 : 生物科学 词条简介 : 一种用于描述两个用于相比的对象数量差异的方法.例如,第一个样本和第二个样本的量是50/10,那 ...
- Myeclipse快捷键集合
Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+↓ 当 ...
- lepus3.7 天兔监控安装手册 CentOS6.5+mysql5.6
lepus3.7 天兔监控安装配置手册 CentOS6.5+mysql5.6 整体环境 192.168.1.250为监控机 192.168.1.248为被监控机 安装LAMP环境 [root@HE3~ ...
- HTML 表单和输入
HTML 表单 表单是一个包含表单元素的区域. 表单元素是允许用户在表单中输入内容,比如:文本域(textarea).下拉列表.单选框(radio-buttons).复选框(checkboxes)等等 ...
- PHP安全编程
转自:http://www.nowamagic.net/librarys/veda/detail/2076 1.关闭register_globals,以提高安全性 2.在部署环境,不要让不相关的人 ...
- V8引擎嵌入指南
如果已读过V8编程入门那你已经熟悉了如句柄(handle).作用域(scope)和上下文(context)之类的关键概念,以及如何将V8引擎作为一个独立的虚拟机来使用.本文将进一步讨论这些概念,并介绍 ...
- bootstrap 基本页面元素,代码,列表
bootstrap 基本页面元素,代码,列表 <!DOCTYPE html> <html> <head> <title></title> & ...