LayerPlan::addLinesByOptimizer
的函数,它的主要功能是在给定的多边形集合(polygons)中按照最优顺序添加每个线条Line。函数使用了优化器类(LineOrderOptimizer)来对多边形进行排序,以便得到最优顺序。以下是该函数的详细步骤:
源码
这里涉及三个类LayerPlan(自己类)、Polygons(传参类)、LineOrderOptimizer (用到的优化器类)
void LayerPlan::addLinesByOptimizer(const Polygons& polygons, const GCodePathConfig& config, SpaceFillType space_fill_type, bool enable_travel_optimization, int wipe_dist, float flow_ratio, std::optional<Point> near_start_location, double fan_speed)
{
Polygons boundary;
if (enable_travel_optimization && comb_boundary_inside2.size() > 0)
{
// use the combing boundary inflated so that all infill lines are inside the boundary
int dist = 0;
if (layer_nr >= 0)
{
// determine how much the skin/infill lines overlap the combing boundary
for (const SliceMeshStorage& mesh : storage.meshes)
{
const coord_t overlap = std::max(mesh.settings.get<coord_t>("skin_overlap_mm"), mesh.settings.get<coord_t>("infill_overlap_mm"));
if (overlap > dist)
{
dist = overlap;
}
}
dist += 100; // ensure boundary is slightly outside all skin/infill lines
}
boundary.add(comb_boundary_inside2.offset(dist));
// simplify boundary to cut down processing time
boundary.simplify(100, 100);
}
LineOrderOptimizer orderOptimizer(near_start_location.value_or(getLastPlannedPositionOrStartingPosition()), &boundary);
for (unsigned int line_idx = 0; line_idx < polygons.size(); line_idx++)
{
orderOptimizer.addPolygon(polygons[line_idx]);
}
orderOptimizer.optimize();
for (unsigned int order_idx = 0; order_idx < orderOptimizer.polyOrder.size(); order_idx++)
{
const unsigned int poly_idx = orderOptimizer.polyOrder[order_idx];
ConstPolygonRef polygon = polygons[poly_idx];
// const size_t start = orderOptimizer.polyStart[poly_idx];
// const size_t end = 1 - start;
// modified by zjn --20240410 fang ann 3
size_t start = orderOptimizer.polyStart[poly_idx];
size_t end = 1 - start;
if (order_idx % 2 == 1 && layer_nr.value == 0)
{
// std::swap(start, end);
start = 1 - start;
end = 1 -end;
}
// end modified by zjn --20240410 fang ann 3
const Point& p0 = polygon[start];
addTravel(p0);
const Point& p1 = polygon[end];
addExtrusionMove(p1, config, space_fill_type, flow_ratio, false, 1.0, fan_speed);
// Wipe
if (wipe_dist != 0)
{
bool wipe = true;
int line_width = config.getLineWidth();
// Don't wipe is current extrusion is too small
if (vSize2(p1 - p0) <= line_width * line_width * 4)
{
wipe = false;
}
// Don't wipe if next starting point is very near
if (wipe && (order_idx < orderOptimizer.polyOrder.size() - 1))
{
const unsigned int next_poly_idx = orderOptimizer.polyOrder[order_idx + 1];
ConstPolygonRef next_polygon = polygons[next_poly_idx];
const size_t next_start = orderOptimizer.polyStart[next_poly_idx];
const Point& next_p0 = next_polygon[next_start];
if (vSize2(next_p0 - p1) <= line_width * line_width * 4)
{
wipe = false;
}
}
if (wipe)
{
addExtrusionMove(p1 + normal(p1-p0, wipe_dist), config, space_fill_type, 0.0, false, 1.0, fan_speed);
}
}
}
}
流程
第一步、大if语句计算dist并添加入boundary:
- 初始化一个名为
boundary
的多边形对象。如果启用了旅行优化(enable_travel_optimization)并且comb_boundary_inside2
的大小大于0,则使用comb_boundary_inside2
的偏移量作为边界。
第二步、创建优化器并把传来的polygons传入优化器以进行对polygons的排序优化
-
创建一个名为
orderOptimizer
的LineOrderOptimizer
对象,用于对多边形进行排序。将near_start_location
或起始位置作为参数传递给优化器。 -
遍历输入的多边形集合(polygons),将每个多边形添加到
orderOptimizer
中。 -
调用
orderOptimizer.optimize()
方法对多边形进行排序。
第三步、遍历已经优化好(排序好的)的polygons进行挤出打印
-
遍历排序后的多边形顺序(
orderOptimizer.polyOrder
),对于每个多边形:a. 获取多边形的起始和结束点(p0和p1)。
b. 添加从当前位置到起始点的移动(
addTravel(p0)
)。c. 添加从起始点到结束点的挤出移动(
addExtrusionMove(p1, config, space_fill_type, flow_ratio, false, 1.0, fan_speed)
)。d. 如果设置了wipe_dist(擦拭距离),则根据一定的条件判断是否需要进行擦拭操作。如果满足条件,则添加一个擦拭移动(
addExtrusionMove(p1 + normal(p1-p0, wipe_dist), config, space_fill_type, 0.0, false, 1.0, fan_speed)
)。
关于ExtrusionMove
这个函数LayerPlan::addExtrusionMove的功能是主要作用是在3D打印的层计划中添加一个新的挤出移动,包括移动到的位置、使用的配置、风扇速度等信息,并更新打印头的最后位置。这是3D打印切片和路径规划过程中的一个重要步骤,确保打印头能够按照预定的路径和参数进行挤出操作,从而完成打印任务。
void LayerPlan::addExtrusionMove(Point p, const GCodePathConfig& config, SpaceFillType space_fill_type, const Ratio& flow, bool spiralize, Ratio speed_factor, double fan_speed)
{
GCodePath* path = getLatestPathWithConfig(config, space_fill_type, flow, spiralize, speed_factor);
path->points.push_back(p);
path->setFanSpeed(fan_speed);
last_planned_position = p;
}
获取最新的路径:使用getLatestPathWithConfig函数,根据给定的配置(config)、空间填充类型(space_fill_type)、挤出率(flow)、是否螺旋化(spiralize)和速度因子(speed_factor)来获取或创建一个最新的GCodePath对象。这个对象通常代表了一个挤出路径,即打印头在打印层上移动以挤出材料的路径。
添加点到路径:将传入的点p添加到获取到的GCodePath对象的points列表中。这表示在打印过程中,打印头需要移动到点p的位置进行挤出操作。
设置风扇速度:调用setFanSpeed方法,为GCodePath对象设置风扇速度。这可以帮助在打印过程中控制冷却速度,确保打印质量。
更新最后计划的位置:将last_planned_position变量更新为当前添加的点p。这通常用于跟踪打印头在层计划中的最后位置,可能用于后续的路径规划或碰撞检测。