cura-engine学习(2)

在函数prepareModel(SliceDataStorage& storage, const std::vector<std::string> &files)中,在读取文件过后,有一个很关键的步骤,就是优化模型操作,是通过class OptimizedModel的构造函数OptimizedModel(model, Point3(config.objectPosition.X, config.objectPosition.Y, -config.objectSink));实现的。在本篇中就学习class OptimizedModel

  在optimizedModel.h和.cpp中记载着这个类的实现。

 1 class OptimizedModel
 2 {
 3 public:
 4     vector<OptimizedVolume> volumes;
 5     Point3 modelSize;
 6  Point3 vMin, vMax; 7 8 OptimizedModel(SimpleModel* model, Point3 center) 9  { 10 for(unsigned int i=0; i<model->volumes.size(); i++) 11 volumes.push_back(OptimizedVolume(&model->volumes[i], this)); 12 vMin = model->min(); 13 vMax = model->max(); 14 15 Point3 vOffset((vMin.x + vMax.x) / 2, (vMin.y + vMax.y) / 2, vMin.z); 16 //vOffset -= center; 17 if(ConfigSettings::config->autoCenter != 1) 18  { 19 vOffset.x = 0; 20 vOffset.y = 0; 21 if(ConfigSettings::config->autoCenter == 2) 22 vOffset.z = 0; 23  } 24 vOffset -= center; 25 for(unsigned int i=0; i<volumes.size(); i++) 26 for(unsigned int n=0; n<volumes[i].points.size(); n++) 27 volumes[i].points[n].p -= vOffset; 28 29 modelSize = vMax - vMin; 30 vMin -= vOffset; 31 vMax -= vOffset; 32  } 33 34 void saveDebugSTL(const char* filename); 35 };

  这个类中包含的主要内容是vector<OptimizedVolume> volumes;下面的构造函数实现了把每一个model->volumes全部进行OptimizedVolume()操作,然后在根据设置调整一下几何体的位置,之后保存调整之后的几何体信息的文件。关键步骤在于OptimizedVolume()。下面我们看class OptimizedVolume,这个类里面包含着一些算法方面的内容。

 1 class OptimizedVolume
 2 {
 3 public:
 4     OptimizedModel* model;
 5     vector<OptimizedPoint3> points;
 6     vector<OptimizedFace> faces;
 7 
 8     OptimizedVolume(SimpleVolume* volume, OptimizedModel* model);
 9 
10     int getFaceIdxWithPoints(int idx0, int idx1, int notFaceIdx)
11     {
12         for(unsigned int i=0;i<points[idx0].faceIndexList.size();i++)
13         {
14             int f0 = points[idx0].faceIndexList[i];
15             if (f0 == notFaceIdx) continue;
16             for(unsigned int j=0;j<points[idx1].faceIndexList.size();j++)
17             {
18                 int f1 = points[idx1].faceIndexList[j];
19                 if (f1 == notFaceIdx) continue;
20                 if (f0 == f1) return f0;
21             }
22         }
23         return -1;
24     }
25 };

  
 
 
此类代表着经过优化的几何体数据,但其实所谓优化,只是去除了STL文件中多余的顶点,而后建立了面与点之间的对应关系存入成员points和faces中。实际的STL文件优化还有很多内容,如质
量检测,空洞检测,修复等等,此处均无涉及。
下面重点研究一下函数OptimizedVolume(SimpleVolume* volume, OptimizedModel* model); 

 1 OptimizedVolume::OptimizedVolume(SimpleVolume* volume, OptimizedModel* model)
 2 : model(model)
 3 {
 4     points.reserve(volume->faces.size() * 3);
 5     faces.reserve(volume->faces.size());
 6 
 7     std::map<uint32_t, std::vector<uint32_t> > indexMap;
 8     
 9     double t = getTime();
10     for(uint32_t i=0; i<volume->faces.size(); i++)
11     {
12         OptimizedFace f;
13         if((i%1000==0) && (getTime()-t)>2.0) cura::logProgress("optimized", i + 1, volume->faces.size());
14         for(uint32_t j=0; j<3; j++)
15         {
16             Point3 p = volume->faces[i].v[j];
17             int hash = ((p.x + MELD_DIST/2) / MELD_DIST) ^ (((p.y + MELD_DIST/2) / MELD_DIST) << 10) ^ (((p.z + MELD_DIST/2) / MELD_DIST) << 20);
18             uint32_t idx;
19             bool add = true;
20             for(unsigned int n = 0; n < indexMap[hash].size(); n++)
21             {
22                 if ((points[indexMap[hash][n]].p - p).testLength(MELD_DIST))
23                 {
24                     idx = indexMap[hash][n];
25                     add = false;
26                     break;
27                 }
28             }
29             if (add)
30             {
31                 indexMap[hash].push_back(points.size());
32                 idx = points.size();
33                 points.push_back(p);
34             }
35             f.index[j] = idx;
36         }
37         if (f.index[0] != f.index[1] && f.index[0] != f.index[2] && f.index[1] != f.index[2])
38         {
39         
40             points[f.index[0]].faceIndexList.push_back(faces.size());
41             points[f.index[1]].faceIndexList.push_back(faces.size());
42             points[f.index[2]].faceIndexList.push_back(faces.size());
43             faces.push_back(f);
44             //}
45         }
46     }
47     //fprintf(stdout, "\rAll faces are optimized in %5.1fs.\n",timeElapsed(t));
48 
49     int openFacesCount = 0;
50     for(unsigned int i=0;i<faces.size();i++)
51     {
52         OptimizedFace* f = &faces[i];
53         f->touching[0] = getFaceIdxWithPoints(f->index[0], f->index[1], i);
54         f->touching[1] = getFaceIdxWithPoints(f->index[1], f->index[2], i);
55         f->touching[2] = getFaceIdxWithPoints(f->index[2], f->index[0], i);
56         if (f->touching[0] == -1)
57             openFacesCount++;
58         if (f->touching[1] == -1)
59             openFacesCount++;
60         if (f->touching[2] == -1)
61             openFacesCount++;
62     }
63     //fprintf(stdout, "  Number of open faces: %i\n", openFacesCount);
64 }

 

 
 

  此部分代码好长啊,它实现了利用hash表对多余的节点进行过滤和点面数据建立对应关系。

过程如下:

  首先 利用容器std::map<uint32_t, std::vector<uint32_t> > indexMap;建立一个hashtable;

  Point3 p = volume->faces[i].v[j];逐一取出待处理几何体中的每个面的每个节点。

  通过哈希函数计算出一个键值,赋予int hash;

  indexMap中的hash这个位置存储的是一个整型的vector数组,数据indexMap[hash][n]代表在hash位置上数组的第n个数,这个数代表着点p在points数组中的位置。恩,就是这么的绕。

  

1  for(unsigned int n = 0; n < indexMap[hash].size(); n++)
2             {
3                 if ((points[indexMap[hash][n]].p - p).testLength(MELD_DIST))
4                 {
5                     idx = indexMap[hash][n];
6                     add = false;
7                     break;
8                 }
9             }

 

   将点p逐一与表中hash位置的每一个索引对应的p进行比较,如果相同,就不进行处理,即add赋值为false

  如果经过比较后add不是false,则执行

1 if (add)
2             {
3                 indexMap[hash].push_back(points.size());
4                 idx = points.size();
5                 points.push_back(p);
6             }
7             f.index[j] = idx;

  就是说将当前points的大小(也就是马上要插入的p的位置)压入indexMap表中hash位置的数组,记录p的索引值(位置)idx,然后将p压入points数组,然后将idx赋予面类型f的索引中,使面中保存其三个顶点的索引值。经过此过程,重复的节点全部被去掉,后一个个存入points数组中。

1 points[f.index[0]].faceIndexList.push_back(faces.size());
2             points[f.index[1]].faceIndexList.push_back(faces.size());
3             points[f.index[2]].faceIndexList.push_back(faces.size());
4             faces.push_back(f);

  然后经过如上代码把face的索引存入points数组中的每个点,然后将f压入faces中,至此points数组记录着所有点(无相同)的坐标,对应的面;faces数组中记录着每个面对应的点。

  最后几行代码不列出了,它帮助每个面找到与其相邻的三个面,至此全部结束。

 这部分包含多个数据类,现连同上篇对其总结(就列出吧,用于都很短,倒是不难懂)
 1 class OptimizedFace
 2 {
 3 public:
 4     int index[3];
 5     int touching[3];
 6 };
 7 class OptimizedPoint3
 8 {
 9 public:
10     Point3 p;
11     vector<uint32_t> faceIndexList;
12 
13     OptimizedPoint3(Point3 p): p(p) {}
14 };
 
 

上一篇涉及到的

 1 class SimpleFace
 2 {
 3 public:
 4     Point3 v[3];
 5 
 6     SimpleFace(Point3& v0, Point3& v1, Point3& v2) { v[0] = v0; v[1] = v1; v[2] = v2; }
 7 };
 8 
 9 /* A SimpleVolume is the most basic reprisentation of a 3D model. It contains all the faces as SimpleTriangles, with nothing fancy. */
10 class SimpleVolume
11 {
12 public:
13     vector<SimpleFace> faces;
14 
15     void addFace(Point3& v0, Point3& v1, Point3& v2)
16     {
17         faces.push_back(SimpleFace(v0, v1, v2));
18     }
19 
20     Point3 min();//删去了实现,要不有点长
21     
22     Point3 max();
23    
24 };
25 
26 //A SimpleModel is a 3D model with 1 or more 3D volumes.
27 class SimpleModel
28 {
29 public:
30     vector<SimpleVolume> volumes;
31 
32     Point3 min();
33   
34     Point3 max();
35    
36 };

 

 

转载于:https://www.cnblogs.com/dama116/p/6480925.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
curaengine_vs2017-master是一个项目文件夹的名称,其中包含了CuraEngine的源代码,并且针对Visual Studio 2017进行了优化。 CuraEngine是一个用于3D打印的开源切片引擎,用于将3D模型切片成为多个薄片,然后通过3D打印机一层一层地堆叠起来,最终形成一个完整的3D打印对象。CuraEngine具有高效、精确的切片算法,可以根据用户的需求进行参数设置,例如打印速度、打印质量、填充密度等,从而实现不同要求的3D打印。 由于CuraEngine是开源的,因此可以在GitHub等平台上找到其源代码。curaengine_vs2017-master是对CuraEngine源代码进行了适配,使其可以在Visual Studio 2017开发环境下编译和运行。通过使用curaengine_vs2017-master,开发人员可以在Visual Studio 2017中更方便地进行CuraEngine的开发和调试工作,提高开发效率。 在curaengine_vs2017-master项目文件夹中,通常会包含CuraEngine的源代码文件、项目文件以及编译所需的相关文件。用户可以通过这些文件进行二次开发,自定义和修改CuraEngine的功能或算法,以满足自己的特定需求。最终,通过编译生成的可执行文件,可以在3D打印机或其他相关设备上运行CuraEngine,并进行3D打印工作。 总之,curaengine_vs2017-master是一个针对CuraEngine源代码进行适配的项目文件夹,方便开发人员在Visual Studio 2017中进行CuraEngine的开发和调试,以实现个性化的3D打印需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值