bool MergeInfillLines::tryMerge(const bool first_is_already_merged, GCodePath& first_path, const Point first_path_start, GCodePath& second_path, const Point second_path_start, Point& new_first_path_start, coord_t& error_area) const { const Point first_path_end = first_path.points.back(); const Point second_path_end = second_path.points.back(); const coord_t line_width = first_path.config->getLineWidth(); //Lines may be adjacent side-by-side then. Point first_path_leave_point; coord_t merged_size2; if (first_is_already_merged) { first_path_leave_point = first_path.points.back(); // this is the point that's going to merge } else { first_path_leave_point = (first_path_start + first_path_end) / 2; } const Point second_path_destination_point = (second_path_start + second_path_end) / 2; const Point merged_direction = second_path_destination_point - first_path_leave_point; if (first_is_already_merged) { merged_size2 = vSize2(second_path_destination_point - first_path.points.back()); // check distance with last point in merged line that is to be replaced } else { merged_size2 = vSize2(merged_direction); } if (merged_size2 > 25 * line_width * line_width) { return false; //Lines are too far away from each other. } if (merged_direction.X == 0 && merged_direction.Y == 0) { return true; // we can just disregard the second point as it's exactly at the leave point of the first path. } // Max 1 line width to the side of the merged_direction if (LinearAlg2D::getDist2FromLine(first_path_end, second_path_destination_point, second_path_destination_point + merged_direction) > line_width * line_width || LinearAlg2D::getDist2FromLine(second_path_start, first_path_leave_point, first_path_leave_point + merged_direction) > line_width * line_width || LinearAlg2D::getDist2FromLine(second_path_end, first_path_leave_point, first_path_leave_point + merged_direction) > line_width * line_width //|| abs(dot(normal(merged_direction, 1000), normal(second_path_end - second_path_start, 1000))) > 866000 // 866000 angle of old second_path with new merged direction should not be too small (30 degrees), as it will introduce holes ) { return false; //One of the lines is too far from the merged line. Lines would be too wide or too far off. } if (first_is_already_merged && first_path.points.size() > 1 && first_path.points[first_path.points.size() - 2] == second_path_destination_point) // yes this can actually happen { return false; } return mergeLinesSideBySide(first_is_already_merged, first_path, first_path_start, second_path, second_path_start, new_first_path_start, error_area); }
bool MergeInfillLines::tryMerge(const bool first_is_already_merged, GCodePath& first_path, const Point first_path_start, GCodePath& second_path, const Point second_path_start, Point& new_first_path_start, coord_t& error_area) const { const Point first_path_end = first_path.points.back(); const Point second_path_end = second_path.points.back(); const coord_t line_width = first_path.config->getLineWidth(); // This check prevents [CURA-5690] fat skin lines: const coord_t line_width_squared = line_width * line_width; if (vSize2(first_path_end - second_path_start) < line_width_squared || vSize2(first_path_start - second_path_end) < line_width_squared) { // Define max_dot_product_squared as 20*20, where 20 micron is the allowed inaccuracy in the dot product, allowing a slight curve: constexpr coord_t max_dot_product_squared = 400; const Point first_direction = first_path_end - first_path_start; const Point second_direction = second_path_end - second_path_start; // Only continue to try-merge at this point if the lines line up straight: if (dot(first_direction, second_direction) + max_dot_product_squared > vSize(first_direction) * vSize(second_direction)) { return false; } } //Lines may be adjacent side-by-side then. Point first_path_leave_point; coord_t merged_size2; if (first_is_already_merged) { first_path_leave_point = first_path.points.back(); // this is the point that's going to merge } else { first_path_leave_point = (first_path_start + first_path_end) / 2; } const Point second_path_destination_point = (second_path_start + second_path_end) / 2; const Point merged_direction = second_path_destination_point - first_path_leave_point; if (first_is_already_merged) { merged_size2 = vSize2(second_path_destination_point - first_path.points.back()); // check distance with last point in merged line that is to be replaced } else { merged_size2 = vSize2(merged_direction); } if (merged_size2 > 25 * line_width * line_width) { return false; //Lines are too far away from each other. } if (merged_direction.X == 0 && merged_direction.Y == 0) { new_first_path_start = first_path_start; return false; // returning true will not work for the gradual infill } // Max 1 line width to the side of the merged_direction if (LinearAlg2D::getDist2FromLine(first_path_end, second_path_destination_point, second_path_destination_point + merged_direction) > line_width * line_width || LinearAlg2D::getDist2FromLine(second_path_start, first_path_leave_point, first_path_leave_point + merged_direction) > line_width * line_width || LinearAlg2D::getDist2FromLine(second_path_end, first_path_leave_point, first_path_leave_point + merged_direction) > line_width * line_width //|| abs(dot(normal(merged_direction, 1000), normal(second_path_end - second_path_start, 1000))) > 866000 // 866000 angle of old second_path with new merged direction should not be too small (30 degrees), as it will introduce holes ) { return false; //One of the lines is too far from the merged line. Lines would be too wide or too far off. } if (first_is_already_merged && first_path.points.size() > 1 && first_path.points[first_path.points.size() - 2] == second_path_destination_point) // yes this can actually happen { return false; } return mergeLinesSideBySide(first_is_already_merged, first_path, first_path_start, second_path, second_path_start, new_first_path_start, error_area); }