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 boundaryint dist = 0;if (layer_nr >= 0){// determine how much the skin/infill lines overlap the combing boundaryfor (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 timeboundary.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 3size_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 3const Point& p0 = polygon[start];addTravel(p0);const Point& p1 = polygon[end];addExtrusionMove(p1, config, space_fill_type, flow_ratio, false, 1.0, fan_speed);// Wipeif (wipe_dist != 0){bool wipe = true;int line_width = config.getLineWidth();// Don't wipe is current extrusion is too smallif (vSize2(p1 - p0) <= line_width * line_width * 4){wipe = false;}// Don't wipe if next starting point is very nearif (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。这通常用于跟踪打印头在层计划中的最后位置,可能用于后续的路径规划或碰撞检测。