CuraEngine之代码阅读(1)之路径优化函数(全)
注:整理一些突然学到的C++知识,随时mark一下
例如:忘记的关键字用法,新关键字,新数据结构
C++ 的 STL
- CuraEngine之代码阅读(1)之路径优化函数(全)
- 一、路径优化函数
- 1、完整代码(来自于CuraEngine源码)
- 总结
提示:本文为curaengine 中 路径优化函数代码
CuraEngine的功能:用于3D打印,接受STL文件(或其他格式的文件,如AMF文件)作为输入,并输出G代码(GCode)。G代码类似于汇编代码,可以直接在底层硬件上运行,控制电机等运动单元动作。
一、路径优化函数
1、完整代码(来自于CuraEngine源码)
void PathOrderOptimizer::optimize()
{// NOTE: Keep this vector fixed-size, it replaces an (non-standard, sized at runtime) array:std::vector<bool> picked(polygons.size(), false);loc_to_line = nullptr;for (unsigned poly_idx = 0; poly_idx < polygons.size(); ++poly_idx) /// find closest point to initial starting point within each polygon +initialize picked{const ConstPolygonRef poly = *polygons[poly_idx];switch (config.type){case EZSeamType::USER_SPECIFIED:polyStart.push_back(getClosestPointInPolygon(config.pos, poly_idx));break;case EZSeamType::RANDOM:polyStart.push_back(getRandomPointInPolygon(poly_idx));break;case EZSeamType::SHARPEST_CORNER:case EZSeamType::SHORTEST:default:polyStart.push_back(getClosestPointInPolygon(startPoint, poly_idx));break;}assert(poly.size() != 2);}Point prev_point;switch (config.type){case EZSeamType::USER_SPECIFIED:prev_point = config.pos;break;case EZSeamType::RANDOM: //TODO: Starting position of the first polygon isn't random.case EZSeamType::SHARPEST_CORNER:case EZSeamType::SHORTEST:default:prev_point = startPoint;}for (unsigned int poly_order_idx = 0; poly_order_idx < polygons.size(); poly_order_idx++) /// actual path order optimizer{int best_poly_idx = -1;float bestDist2 = std::numeric_limits<float>::infinity();for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++){if (picked[poly_idx] || polygons[poly_idx]->size() < 1) /// skip single-point-polygons{continue;}assert (polygons[poly_idx]->size() != 2);const Point& p = (*polygons[poly_idx])[polyStart[poly_idx]];float dist2 = vSize2f(p - prev_point);if (dist2 < bestDist2 && combing_boundary){// using direct routing, this poly is the closest so far but as the combing boundary// is available see if the travel would cross the combing boundary and, if so, either get// the combed distance and use that instead or increase the distance to make it less attractiveif (PolygonUtils::polygonCollidesWithLineSegment(*combing_boundary, p, prev_point)){if ((polygons.size() - poly_order_idx) > 100){// calculating the combing distance for lots of polygons is too time consuming so, instead,// just increase the distance to penalise travels that hit the combing boundarydist2 *= 5;}else{if (!loc_to_line){// the combing boundary has been provided so do the initialisation// required to be able to calculate realistic travel distances to the start of new pathsconst int travel_avoid_distance = 2000; // assume 2mm - not really critical for our purposesloc_to_line = PolygonUtils::createLocToLineGrid(*combing_boundary, travel_avoid_distance);}CombPath comb_path;if (LinePolygonsCrossings::comb(*combing_boundary, *loc_to_line, p, prev_point, comb_path, -40, 0, false)){float dist = 0;Point last_point = p;for (const Point& comb_point : comb_path){dist += vSize(comb_point - last_point);last_point = comb_point;}dist2 = dist * dist;}}}}if (dist2 < bestDist2){best_poly_idx = poly_idx;bestDist2 = dist2;}}if (best_poly_idx > -1) /// should always be true; we should have been able to identify the best next polygon{assert(polygons[best_poly_idx]->size() != 2);prev_point = (*polygons[best_poly_idx])[polyStart[best_poly_idx]];picked[best_poly_idx] = true;polyOrder.push_back(best_poly_idx);}else{logError("Failed to find next closest polygon.\n");}}if (loc_to_line != nullptr){delete loc_to_line;}
}
这段代码是一个名为PathOrderOptimizer::optimize()
的函数,它的主要目的是优化多边形路径的顺序(gcode打印顺序)。以下是代码的分段讲解:
1、初始化一个布尔类型的向量picked
,用于记录每个多边形是否已被选中。向量的大小与多边形的数量相同,初始值都为false
。
std::vector<bool> picked(polygons.size(), false);
2、将loc_to_line
指针设置为nullptr
。
loc_to_line = nullptr;
3、遍历所有多边形,根据配置类型(config.type
)确定每个多边形的起始点(polyStart
)。(本人创造的逻辑简略标记:for
each polygon in
polygons to
polyStart,遍历循环向量中的每个元最后为了得到polyStart。)
for (unsigned poly_idx = 0; poly_idx < polygons.size(); ++poly_idx) {const ConstPolygonRef poly = *polygons[poly_idx];switch (config.type) {case EZSeamType::USER_SPECIFIED:polyStart.push_back(getClosestPointInPolygon(config.pos, poly_idx));break;case EZSeamType::RANDOM:polyStart.push_back(getRandomPointInPolygon(poly_idx));break;case EZSeamType::SHARPEST_CORNER:case EZSeamType::SHORTEST:default:polyStart.push_back(getClosestPointInPolygon(startPoint, poly_idx));break;}assert(poly.size() != 2);
}
4、根据配置类型更新上一个点的位置(prev_point
)。
switch (config.type) {case EZSeamType::USER_SPECIFIED:prev_point = config.pos;break;case EZSeamType::RANDOM: //TODO: Starting position of the first polygon isn't random.case EZSeamType::SHARPEST_CORNER:case EZSeamType::SHORTEST:default:prev_point = startPoint;
}
5、第二层循环遍历所有多边形,寻找距离上一个点prev_point
最短邻的多边形。在这个过程中,会跳过单点多边形和已经被选中的多边形。对于每个多边形,计算其起始点到上一个点prevpoint的距离平方(dist2
)。如果当前多边形与上一个点之间的距离小于之前找到的最佳距离,并且存在边界限制(combing_boundary
),则检查是否需要调整距离。
(本人创造的逻辑简略标记:for
each polygon in
polygons to
bestDist bestpolyidx,遍历循环向量中的每个元最后为了得到最优多边形)
for (unsigned int poly_order_idx = 0; poly_order_idx < polygons.size(); poly_order_idx++) {int best_poly_idx = -1;float bestDist2 = std::numeric_limits<float>::infinity();for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++) {if (picked[poly_idx] || polygons[poly_idx]->size() < 1) {continue;}assert (polygons[poly_idx]->size() != 2);const Point& p = (*polygons[poly_idx])[polyStart[poly_idx]];float dist2 = vSize2f(p - prev_point);if (dist2 < bestDist2 && combing_boundary) {// ...省略部分代码...}if (dist2 < bestDist2) {best_poly_idx = poly_idx;bestDist2 = dist2;}}
6、条件语句,根据best_poly_idx
的值进行不同的操作。如果best_poly_idx
大于-1,表示找到了最接近的多边形索引。然后通过断言(assert)确保该多边形的大小不为2。接下来,将prev_point
更新为本次比较后得到的最优的多边形的起始点,即(*polygons[best_poly_idx])[polyStart[best_poly_idx]]
。然后将picked[best_poly_idx]
标记为true,表示已经选择了该多边形。最后,将best_poly_idx
添加到polyOrder
向量中,用于记录选择的多边形顺序。
如果best_poly_idx
小于等于-1,表示没有找到最close即距离最短的多边形。在这种情况下,会调用logError
函数输出错误信息:“Failed to find next closest polygon.”
if (best_poly_idx > -1) {assert(polygons[best_poly_idx]->size() != 2);prev_point = (*polygons[best_poly_idx])[polyStart[best_poly_idx]];picked[best_poly_idx] = true;polyOrder.push_back(best_poly_idx);
} else {logError("Failed to find next closest polygon.\n");
}
- 最后,如果
loc_to_line
不为空,则删掉它。
if (loc_to_line != nullptr) {delete loc_to_line;
}
总结
PathOrderOptimizer::optimize()
的函数的主要目的是优化多边形路径的顺序。以下是代码的步骤总结:
-
初始化一个布尔类型的向量
picked
,用于记录每个多边形是否已被选中。向量的大小与多边形的数量相同,初始值都为false
。 -
将
loc_to_line
指针设置为nullptr
。 -
遍历所有多边形,根据配置类型(
config.type
)确定每个多边形的起始点(polyStart
)。 -
根据配置类型设置上一个点(
prev_point
)。 -
遍历所有多边形,寻找距离上一个点最近的多边形。在这个过程中,会跳过单点多边形和已经被选中的多边形。
-
对于每个多边形,计算其起始点到上一个点的距离平方(
dist2
)。如果当前多边形与上一个点之间的距离小于之前找到的最佳距离,并且存在边界限制(combing_boundary
),则检查是否需要调整距离。 -
如果找到了距离上一个点最近的多边形,将其索引(
best_poly_idx
)添加到路径顺序向量(polyOrder
)中,并将对应的picked
值设为true
。 -
最后,如果
loc_to_line
不为空,则删掉它。