cura-engine为开源3D打印软件cura的核心引擎代码,详细介绍参看github主页。现在学习的是一个简单版的https://github.com/repetier/CuraEngine,最新版https://github.com/Ultimaker/CuraEngine添加了很多功能,尤其通信部分有点难懂。本系列文章主要是为了保存本人阅读记忆,一面吃过就忘,所以完全按照阅读顺序编写,故稍有凌乱。下面直接进入学习。

  首先看fffProcessor.h中的读取STL文件部分:

函数ProsessFile:功能:STL文件读取prepareModel、生成切片数据processSliceData、生成Gcode writeGcode。(log函数现在滤去,单独研究)

函数prepareModel:功能:STL文件读取、优化STL文件、生成LayerParts。涉及到的类:class SimpleModel、class SimpleVolume、class OptimizedModel、cura class Slicer、cura class SupportStorage。

文件读取的实现:

  if (files.size() ==  && files[][] == '$')
{
const char *input_filename = files[].c_str();
model = new SimpleModel();
for(unsigned int n=; input_filename[n]; n++)
{
model->volumes.push_back(SimpleVolume());
SimpleVolume* volume = &model->volumes[model->volumes.size()-];
guiSocket.sendNr(GUI_CMD_REQUEST_MESH); int32_t vertexCount = guiSocket.recvNr();
int pNr = ;
cura::log("Reading mesh from socket with %i vertexes\n", vertexCount);
Point3 v[];
while(vertexCount)
{
float f[];
guiSocket.recvAll(f, * sizeof(float));
FPoint3 fp(f[], f[], f[]);
v[pNr++] = config.matrix.apply(fp);
if (pNr == )
{
volume->addFace(v[], v[], v[]);
pNr = ;
}
vertexCount--;
}
}
}else{
model = new SimpleModel();
for(unsigned int i=;i < files.size(); i++) {
if(files[i] == "-")
model->volumes.push_back(SimpleVolume());
else {
cura::log("Loading %s from disk...\n", files[i].c_str());
SimpleModel *test = loadModelFromFile(model,files[i].c_str(), config.matrix);
if(test == nullptr) { // error while reading occurred
cura::logError("Failed to load model: %s\n", files[i].c_str());
return false;
}
}
}
}

  此处读入文件来源有两种,一是通过guiSocket从通信中接收的数据,二是从硬盘中读取STL文件,通信部分暂且不提,先学习后者。这就到了loadModelFromFile函数,此函数名字就已透露其作用-读文件。代码在文件modelFile.cpp中,如下:

 SimpleModel* loadModelFromFile(SimpleModel *m,const char* filename, FMatrix3x3& matrix)
{
const char* ext = strrchr(filename, '.');
if (ext && stringcasecompare(ext, ".stl") == )
{
return loadModelSTL(m,filename, matrix);
}
if (filename[] == '#' && binaryMeshBlob != nullptr)
{
while(*filename == '#')
{
filename++; m->volumes.push_back(SimpleVolume());
SimpleVolume* vol = &m->volumes[m->volumes.size()-];
int32_t n, pNr = ;
if (fread(&n, , sizeof(int32_t), binaryMeshBlob) < )
return nullptr;
cura::log("Reading mesh from binary blob with %i vertexes\n", n);
Point3 v[];
while(n)
{
float f[];
if (fread(f, , sizeof(float), binaryMeshBlob) < )
return nullptr;
FPoint3 fp(f[], f[], f[]);
v[pNr++] = matrix.apply(fp);
if (pNr == )
{
vol->addFace(v[], v[], v[]);
pNr = ;
}
n--;
}
}
return m;
}
return nullptr;
}

  此处可以看出分两种情况,一是读取.stl后缀的STL文件,二是读取blob(binary large object)二进制大对象,blob同样来源与硬盘数据文件,至于到底是神马,还不知道。

  m->volumes.push_back(SimpleVolume());
SimpleVolume* vol = &m->volumes[m->volumes.size()-];

  代码作者超级喜欢这种先推入一个初始的几何体,然后在通过引用取出到vol,再赋值,貌似我一般都是相反的顺序,不知这种有何优势。下面还是看一看函数LoadModelSTL()吧,就在正上方。

 SimpleModel* loadModelSTL(SimpleModel *m,const char* filename, FMatrix3x3& matrix)
{
FILE* f = fopen(filename, "r");
char buffer[];
if (f == nullptr)
return nullptr; if (fread(buffer, , , f) != )
{
fclose(f);
return nullptr;
}
fclose(f); buffer[] = '\0';
if (stringcasecompare(buffer, "solid") == )
{
SimpleModel* asciiModel = loadModelSTL_ascii(m, filename, matrix);
if (!asciiModel)
return nullptr; // This logic is used to handle the case where the file starts with
// "solid" but is a binary file.
if (m->volumes[m->volumes.size()-].faces.size() < )
{
m->volumes.erase(m->volumes.end() - );
return loadModelSTL_binary(m, filename, matrix);
}
return asciiModel;
}
return loadModelSTL_binary(m, filename, matrix);
}

  此函数同样分两种情况(看来码农都喜欢二分)。很简单,读入开头5个字母,如果是solid,则按Ascii读入,否则按照二进制读入。然而作者心思谨慎,开头是solid时也有二进制情况,所以检查一下读入最后一个几何体如果一个面都没有,那就错了呗,滚回用二进制重新读。

  函数loadModelSTL_ascii(SimpleModel *m,const char* filename, FMatrix3x3& matrix)

   和loadModelSTL_binary(SimpleModel *m,const char* filename, FMatrix3x3& matrix)是我们这部分的最后一站,代码不是很难,但有个小小的问题,matrix到底是干什么用的。这个matrix来自最初的函数loadModelFromFile(model,files[i].c_str(), config.matrix);config据我目前所知是整个系统一些参数设置的一个汇总类class ConfigSettings。这里面保存了大量的参数设置。这个matrix是的用途就是每个读入的坐标与其相乘,结果再存入model->volume.faces,就是将几何体坐标根据需要做了个变换,至于变换的作用,现在还不清楚。

  至此,文件读入功能结束,文中还有一些问题没有解决,主要有log相关函数,socket相关函数和config相关,这些都是贯穿整个程序的,以后详细学习。

  哦也。

cura-engine学习(1)的更多相关文章

  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. sql2000/sql2005/sql2008数据库变为0字节修复/MDF文件0字节恢复

    [数据恢复故障描述]  这个客户是生产型数据库,数据比较重要,产生量也比较大,客户要求必须尽快修复,保证生产尽快恢复运行.sql数据库文件,由于碎片链接过长,mdf文件突然变为0字节,开始客户尝试自行 ...

  2. post请求时2种传参方式

    @Testpublic void dopost(){ String httpurl = "https://jin.caimao.com/api/user/loginSalt"; M ...

  3. Swoole:重新定义PHP

    Swoole PHP语言的高性能网络通信框架,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异 ...

  4. Angular - - ngApp、ngBind、ngBindHtml、ngNonBindable

    对于ng-系列的指令,每篇文章写2-5个吧,不然显得文章好短.... ngApp 使用这个指令自动启动一个AngularJS应用.ngApp指令指定了应用程序的根节点,通常会将ngApp放置在网页的根 ...

  5. Repeated Substring Pattern Leetcode

    Given a non-empty string check if it can be constructed by taking a substring of it and appending mu ...

  6. JS 继承(类式 与 原型式)

    1. /* -- 类式继承 -- *///先声明一个超类 function Person(name) { this.name = name;}//给这个超类的原型对象上添加方法 getName Per ...

  7. 利用Navicat实现MySQL数据库结构对比和同步

    在生产环境中,我们总会因为这样或那样的原因导致主从不同步,亦或者是测试环境要和生产环境进行同步,利用Navicat结构同步工具,不但能找出库结构差异,还可以针对create.modify.drop等进 ...

  8. Nodejs.sublime-build 在sublime3中的配置

    { "cmd": ["node", "$file"], "file_regex": "^[ ]*File \& ...

  9. aJax请求结果中包含form的问题

    jsp页面a.jsp如下: <form action='login' id='formId' method='post'> <input name='user'> </f ...

  10. Backdoor CTF 2013: 电子取证 250

    0x00 题目 h4x0r厌烦了你对他的城堡的所有攻击,所以他决定报复攻击你,他给你发来一封带有图片的邮件作为警告,希望你能找出他的警告消息:-) 消息的MD5值就是flag. 0x01 解题法1 给 ...