diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 51e6fbb7a..a8a9784cd 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -940,7 +940,6 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr m_result.moves[i].layer_duration = 0; } #if ENABLE_GCODE_VIEWER_DATA_CHECKING - std::cout << "\n"; m_mm3_per_mm_compare.output(); m_height_compare.output(); m_width_compare.output(); @@ -1050,7 +1049,6 @@ void GCodeProcessor::process_klipper_ACTIVATE_EXTRUDER(const GCodeReader::GCodeL void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { -/* std::cout << line.raw() << std::endl; */ // update start position m_start_position = m_end_position; @@ -1078,6 +1076,8 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { case 0: { process_G0(line); break; } // Move case 1: { process_G1(line); break; } // Move + case 2: { process_G2_G3(line, false); break; } // Move + case 3: { process_G2_G3(line, true); break; } // Move case 10: { process_G10(line); break; } // Retract case 11: { process_G11(line); break; } // Unretract case 20: { process_G20(line); break; } // Set Units to Inches @@ -1876,6 +1876,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) if (type == EMoveType::Extrude && m_end_position[Z] == 0.0f) type = EMoveType::Travel; + float height_saved = -1; if (type == EMoveType::Extrude) { double delta_xyz = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); #if !ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING @@ -1935,9 +1936,10 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) // cross section: rectangle + 2 semicircles m_width = float(delta_pos[E] * (M_PI * sqr(filament_radius)) / (delta_xyz * m_height) + (1.0 - 0.25 * M_PI) * m_height); - // if teh value seems wrong, fall back to circular extrusion from flow + // if the value seems wrong, fall back to circular extrusion from flow if (m_width > m_height * 10 || m_width < m_height) { m_width = 2 * std::sqrt(m_mm3_per_mm / float(PI)); + height_saved = m_height; m_height = m_width; } } @@ -2114,6 +2116,123 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) // store move store_move_vertex(type); + + //restore + if(height_saved > 0) + m_height = height_saved; +} + +void GCodeProcessor::emit_G1_from_G2(Vec2d dest, float e, float f) { + GCodeReader::FakeGCodeLine line_fake; + line_fake.set_x(dest.x()); + line_fake.set_y(dest.y()); + //line_fake.set_z(dest.z()); + line_fake.set_e(e); + if( f > 0) + line_fake.set_f(f); + process_G1(line_fake); +} + +void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool direct) +{ + //check it has everything + float i = 0, j = 0; + bool has_i = line.has_value('I', i); + bool has_j = line.has_value('J', j); + if(!((line.has_x() || line.has_y()) && (has_i || has_j))) + return; + //compute points + // compute mult factor + float lengthsScaleFactor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; + Vec2d p_start = { m_end_position[Axis::X], m_end_position[Axis::Y] }; + Vec2d p_end = { line.x() * lengthsScaleFactor, line.y() * lengthsScaleFactor }; + Vec2d p_center = { i * lengthsScaleFactor, j * lengthsScaleFactor }; + p_center += p_start; + // if relative positioning + if ((m_global_positioning_type == EPositioningType::Relative)) { + Vec2d p_to_add = { m_start_position[Axis::X], m_start_position[Axis::Y] }; + p_end += p_to_add; + p_center += p_to_add; + } + // get missing values + if (!line.has_x()) + p_end.x() = p_start.x(); + if (!line.has_y()) + p_end.y() = p_start.y(); + if (!has_i) + p_center.x() = p_start.x(); + if (!has_j) + p_center.y() = p_start.y(); + + //compute angles + double min_dist = m_width == 0 ? 1 : m_width * 4; + const double pi2 = 2 * PI; + const double radius = (p_start - p_center).norm(); + const double radius2 = (p_end - p_center).norm(); + if (std::abs(radius - radius2) > min_dist*0.1) { + BOOST_LOG_TRIVIAL(error) << "error, radius from start & end are too different in command '" << line.raw() << "'."; + return; + } + Vec2d p_start_rel = p_start - p_center; + Vec2d p_end_rel = p_end - p_center; + const double a1 = atan2(p_start_rel.y(), p_start_rel.x()); + const double a2 = atan2(p_end_rel.y(), p_end_rel.x()); + double adiff = a2 - a1; + //if (a1 < 0) + // a1 += pi2; + //if (a2 < 0) + // a2 += pi2; + if (adiff > pi2) + adiff -= pi2; + if (adiff < -pi2) + adiff += pi2; + //check order + if (direct) { + if (adiff < 0) + adiff += pi2; + } else { + if (adiff > 0) + adiff -= pi2; + } + double distance = std::abs(adiff * radius); + //get E + float dE = 0; + float start_e = m_start_position[E]; + bool e_relative = true; + if (line.has_e()) { + e_relative = (m_e_local_positioning_type == EPositioningType::Relative); + double ret = line.e() * lengthsScaleFactor; +#if ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING + if (m_use_volumetric_e) { + float filament_diameter = (static_cast(m_extruder_id) < m_filament_diameters.size()) ? m_filament_diameters[m_extruder_id] : m_filament_diameters.back(); + float filament_radius = 0.5f * filament_diameter; + double area_filament_cross_section = M_PI * sqr(filament_radius); + ret /= area_filament_cross_section; + } +#endif // ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING + dE = e_relative ? ret : m_origin[E] + ret - start_e; + } + + //compute how much sections we need (~1 per 4 * width/nozzle) + int nb_sections = std::min(30, 1 + int(distance / min_dist)); + Vec2d p_current = p_start; + float angle_incr = adiff / nb_sections; + float dE_incr = dE / nb_sections; + float current_angle = a1; + //create smaller sections + for (int i = 1; i < nb_sections;i++) { + current_angle += angle_incr; + p_current = { std::cos(current_angle) * radius, std::sin(current_angle) * radius }; + p_current += p_center; + emit_G1_from_G2(p_current, e_relative ? dE_incr : start_e + i * dE_incr, line.has_f() ? line.f() : -1); + // update start position for next fake G1 + m_start_position[X] = p_current.x(); + m_start_position[Y] = p_current.y(); + m_start_position[E] += dE_incr; + } + //emit last + emit_G1_from_G2(p_end, e_relative ? dE_incr : start_e + dE, line.has_f() ? line.f() : -1); + } void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line) diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 8c1dfaf7e..d672fc5ea 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -507,6 +507,8 @@ namespace Slic3r { // Move void process_G0(const GCodeReader::GCodeLine& line); void process_G1(const GCodeReader::GCodeLine& line); + void process_G2_G3(const GCodeReader::GCodeLine& line, bool direct); + void emit_G1_from_G2(Vec2d dest, float de, float f); // Retract void process_G10(const GCodeReader::GCodeLine& line); diff --git a/src/libslic3r/GCodeReader.hpp b/src/libslic3r/GCodeReader.hpp index d90a23160..cb20e2642 100644 --- a/src/libslic3r/GCodeReader.hpp +++ b/src/libslic3r/GCodeReader.hpp @@ -72,6 +72,14 @@ public: uint32_t m_mask; friend class GCodeReader; }; + class FakeGCodeLine : public GCodeLine { + public: + void set_x(float x) { m_axis[X] = x; m_mask = (m_mask | (1 << int(X))); } + void set_y(float y) { m_axis[Y] = y; m_mask = (m_mask | (1 << int(Y))); } + void set_z(float z) { m_axis[Z] = z; m_mask = (m_mask | (1 << int(Z))); } + void set_e(float e) { m_axis[E] = e; m_mask = (m_mask | (1 << int(E))); } + void set_f(float f) { m_axis[F] = f; m_mask = (m_mask | (1 << int(F))); } + }; typedef std::function callback_t; diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 4dcea595e..54ddeac97 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -337,7 +337,11 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) Polylines axes_lines; Polylines axes_lines_big; Polylines axes_lines_small; - for (coord_t x = bed_bbox.min(0), idx= 0; x <= bed_bbox.max(0); x += scale_(5.0), idx++) { + coord_t square = scale_(5); + while (bed_bbox.radius() > square * 100) { + square *= 10; + } + for (coord_t x = bed_bbox.min(0), idx= 0; x <= bed_bbox.max(0); x += square, idx++) { Polyline line; line.append(Point(x, bed_bbox.min(1))); line.append(Point(x, bed_bbox.max(1))); @@ -348,7 +352,7 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) else axes_lines.push_back(line); } - for (coord_t y = bed_bbox.min(1), idx = 0; y <= bed_bbox.max(1); y += scale_(5.0), idx++) { + for (coord_t y = bed_bbox.min(1), idx = 0; y <= bed_bbox.max(1); y += square, idx++) { Polyline line; line.append(Point(bed_bbox.min(0), y)); line.append(Point(bed_bbox.max(0), y));