目前,我们还在函数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)的更多相关文章

  1. Google App Engine 学习和实践

    这个周末玩了玩Google App Engine,随手写点东西,算是学习笔记吧.不当之处,请多多指正. 作者:liigo,2009/04/26夜,大连 原创链接:http://blog.csdn.ne ...

  2. Google Earth Engine学习资源分享

    最近在学习Google Earth Engine的使用,发现这个平台确实是一个非常好用.非常强大的平台.在GEE官网上找到了一些中文的学习资料,现在搬运过来分享给大家共同学习.教程分为两个部分 教程一 ...

  3. Diligent Engine学习笔记初衷

    2020年过去一个月了,回首过去的一年,工作确实很忙,但是自己个人的技术也没得到什么成长,项目当中一些比较难搞的问题也没得到更深入的研究.思来想去,希望新的一年能改变自己的工作方式,将工作上的事物进一 ...

  4. QLoo graphql engine 学习三 架构

    一张官方的参考图 说明 Storage Layer API 参考了kubernetes 的设计 qloo 组成 qloo 有qloo 服务以及envoy proxy 组合而成,envoy proxy ...

  5. QLoo graphql engine 学习二 基本试用(kubernetes)

    已经测试过docker&& docker-compose 的运行模式,下面测试下kubernetes的运行模式 kubernetes 我使用docker for mac qloo 安装 ...

  6. QLoo graphql engine 学习一 基本试用(docker&&docker-compose)

      说明:使用docker-compose 进行安装 代码框架 使用命令行工具创建 qlooctl install docker qloo-docker 运行qloo&&gloo 启动 ...

  7. CE学习记录1

    主题 春节放假终于有空学习下怎么制作外挂啦......学习写外挂大概是我一开始学习计算机的动力吧....只是一直似懂非懂..看教学视频各种不明白为什么....也没有专门的时间学习下怎么写....春节有 ...

  8. Gcode命令【转】

    https://www.jianshu.com/p/f8a328457a45 简述 研究过3D打印机的朋友,都会用到G-code文件.要使用3D打印机打印东西要经过几个步骤:        1.创建3 ...

  9. 收购公司、孵化(产品)和被收购的20个短篇故事-BI产品的历史

    原文地址: 20 short tales of acquiring companies, incubating (ideas into products) and being acquired. | ...

  10. SQLAlchemy 学习笔记(一):Engine 与 SQL 表达式语言

    个人笔记,如有错误烦请指正. SQLAlchemy 是一个用 Python 实现的 ORM (Object Relational Mapping)框架,它由多个组件构成,这些组件可以单独使用,也能独立 ...

随机推荐

  1. Cannot create PoolableConnectionFactory (ORA-28040: No matching authentication protocol

    Oracle 12c 如果java报这个错误,用oracle自带的ojdbc6.jar,可以解决这个问题.

  2. 分享Grunt.js配置: watch + liveReload 实时监测文件变化自动刷新浏览器

    http://www.tuicool.com/articles/2eaQJn 用Grunt配置watch和liveReload组件,可以实时检测指定的文件变化并自动刷新浏览器.目前基本已经成为了我的必 ...

  3. ThinkPHP使用技巧经验总结

    add方法返回主键(id)的值 在往数据表中添加数据时调用add方法,默认返回值就是刚添加的id值,就不用再去查询了. save方法返回值的判断 在修改数据时,如果修改成功返回的是1,不成功则是0,如 ...

  4. Eclipse和debug的一些快捷键

    F5单步调试进入函数内部.  F6单步调试不进入函数内部,如果装了金山词霸2006则要把“取词开关”的快捷键改成其他的.  F7由函数内部返回到调用处.  F8一直执行到下一个断点.  F11 这个好 ...

  5. 插入排序法-java案例详解

    /** * 功能:插入排序法 * 基本思想:把n个待排序的元素看成一个有序和无序表,开始时有序表中只包含一个元素, * 无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码 ...

  6. Java 读写Properties配置文件

    Java 读写Properties配置文件 JAVA操作properties文件 1.Properties类与Properties配置文件 Properties类继承自Hashtable类并且实现了M ...

  7. 国内值得关注的官方API集合

    项目地址:https://github.com/marktony/Awesome_API 本页仅收集国内部分官方API,如需查看其他版本,请点击这里. 目录 笔记 出行 词典 电商 地图 电影 后端云 ...

  8. inline「一」:从 image 底部白边初识 line-height

    本文首发于个人博客 http://www.lijundong.com/image-and-line-height/ 今天在做一个静态页面时,图片底部出现一条 3px 高度的白边,既不是 margin ...

  9. 我的2016年终总结(PF项目框架设计心得分享 2.0rc)

    在无数的日夜里,熬出了多少的黑眼圈,致勤勤恳恳工作的各位朋友与自己.每到了年末的时候总想写的什么,主要是为了回顾以往一年里到底做了什么,这便是年终总结的主要意义.在此我将要总结的是和我在技术层面上成长 ...

  10. 三分钟解读springmvc依赖

    长期以来都在写SSM框架的项目,却未能深入理解框架的搭建原理,而只是浅薄的理解前辈的架构,然后不断套用,项目做过几个,但框架的内涵却没有把握.小编打算今天从SpringMVC的依赖分析做起,一步步进行 ...