Merge branch 'main' into dev/bbs-support

This commit is contained in:
SoftFever 2024-10-07 16:44:01 +08:00 committed by GitHub
commit 338f89a15b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
167 changed files with 8834 additions and 3461 deletions

View file

@ -82,6 +82,40 @@ struct CSGPart {
{}
};
//Prusa
// Check if there are only positive parts (Union) within the collection.
template<class Cont> bool is_all_positive(const Cont &csgmesh)
{
bool is_all_pos =
std::all_of(csgmesh.begin(),
csgmesh.end(),
[](auto &part) {
return csg::get_operation(part) == csg::CSGType::Union;
});
return is_all_pos;
}
//Prusa
// Merge all the positive parts of the collection into a single triangle mesh without performing
// any booleans.
template<class Cont>
indexed_triangle_set csgmesh_merge_positive_parts(const Cont &csgmesh)
{
indexed_triangle_set m;
for (auto &csgpart : csgmesh) {
auto op = csg::get_operation(csgpart);
const indexed_triangle_set * pmesh = csg::get_mesh(csgpart);
if (pmesh && op == csg::CSGType::Union) {
indexed_triangle_set mcpy = *pmesh;
its_transform(mcpy, csg::get_transform(csgpart), true);
its_merge(m, mcpy);
}
}
return m;
}
}} // namespace Slic3r::csg
#endif // CSGMESH_HPP

View file

@ -257,7 +257,7 @@ void perform_csgmesh_booleans_mcut(MeshBoolean::mcut::McutMeshPtr& mcutm,
template<class It, class Visitor>
std::tuple<BooleanFailReason,std::string> check_csgmesh_booleans(const Range<It> &csgrange, Visitor &&vfn)
std::tuple<BooleanFailReason,std::string, It> check_csgmesh_booleans(const Range<It> &csgrange, Visitor &&vfn)
{
using namespace detail_cgal;
BooleanFailReason fail_reason = BooleanFailReason::OK;
@ -304,23 +304,23 @@ std::tuple<BooleanFailReason,std::string> check_csgmesh_booleans(const Range<It>
};
execution::for_each(ex_tbb, size_t(0), csgrange.size(), check_part);
//It ret = csgrange.end();
//for (size_t i = 0; i < csgrange.size(); ++i) {
// if (!cgalmeshes[i]) {
// auto it = csgrange.begin();
// std::advance(it, i);
// vfn(it);
It ret = csgrange.end();
for (size_t i = 0; i < csgrange.size(); ++i) {
if (!cgalmeshes[i]) {
auto it = csgrange.begin();
std::advance(it, i);
vfn(it);
// if (ret == csgrange.end())
// ret = it;
// }
//}
if (ret == csgrange.end())
ret = it;
}
}
return { fail_reason,fail_part_name };
return { fail_reason,fail_part_name, ret};
}
template<class It>
std::tuple<BooleanFailReason, std::string> check_csgmesh_booleans(const Range<It> &csgrange, bool use_mcut=false)
std::tuple<BooleanFailReason, std::string, It> check_csgmesh_booleans(const Range<It> &csgrange, bool use_mcut=false)
{
if(!use_mcut)
return check_csgmesh_booleans(csgrange, [](auto &) {});
@ -354,7 +354,7 @@ std::tuple<BooleanFailReason, std::string> check_csgmesh_booleans(const Range<It
McutMeshes[i] = std::move(m);
};
execution::for_each(ex_tbb, size_t(0), csgrange.size(), check_part);
return { fail_reason,fail_part_name };
return { fail_reason,fail_part_name, csgrange.end() };
}
}

View file

@ -729,6 +729,8 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
gcode += gcodegen.writer().unlift(); // Make sure there is no z-hop (in most cases, there isn't).
double current_z = gcodegen.writer().get_position().z();
if (z == -1.) // in case no specific z was provided, print at current_z pos
z = current_z;
@ -741,7 +743,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|| !needs_toolchange // this is just finishing the tower with no toolchange
|| is_ramming);
if (should_travel_to_tower) {
if (should_travel_to_tower || gcodegen.m_need_change_layer_lift_z) {
// FIXME: It would be better if the wipe tower set the force_travel flag for all toolchanges,
// then we could simplify the condition and make it more readable.
gcode += gcodegen.retract();
@ -767,10 +769,10 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
toolchange_gcode_str = gcodegen.set_extruder(new_extruder_id, tcr.print_z); // TODO: toolchange_z vs print_z
if (gcodegen.config().enable_prime_tower) {
deretraction_str += gcodegen.writer().travel_to_z(z, "restore layer Z");
Vec3d position{gcodegen.writer().get_position()};
position.z() = z;
gcodegen.writer().set_position(position);
deretraction_str += gcodegen.unretract();
Vec3d position{gcodegen.writer().get_position()};
position.z() = z;
gcodegen.writer().set_position(position);
deretraction_str += gcodegen.unretract();
}
}
@ -4516,12 +4518,11 @@ std::string GCode::change_layer(coordf_t print_z)
comment << "move to next layer (" << m_layer_index << ")";
gcode += m_writer.travel_to_z(z, comment.str());
}
else {
//BBS: set m_need_change_layer_lift_z to be true so that z lift can be done in travel_to() function
m_need_change_layer_lift_z = true;
}
m_need_change_layer_lift_z = true;
m_nominal_z = z;
m_writer.get_position().z() = z;
// forget last wiping path as wiping after raising Z is pointless
// BBS. Dont forget wiping path to reduce stringing.
@ -6005,14 +6006,15 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string
if (m_spiral_vase) {
// No lazy z lift for spiral vase mode
for (size_t i = 1; i < travel.size(); ++i) {
gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment + " travel_to_xy");
gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment);
}
} else {
if (travel.size() == 2) {
// No extra movements emitted by avoid_crossing_perimeters, simply move to the end point with z change
const auto& dest2d = this->point_to_gcode(travel.points.back());
Vec3d dest3d(dest2d(0), dest2d(1), z == DBL_MAX ? m_nominal_z : z);
gcode += m_writer.travel_to_xyz(dest3d, comment + " travel_to_xyz");
gcode += m_writer.travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z);
m_need_change_layer_lift_z = false;
} else {
// Extra movements emitted by avoid_crossing_perimeters, lift the z to normal height at the beginning, then apply the z
// ratio at the last point
@ -6021,21 +6023,23 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string
// Lift to normal z at beginning
Vec2d dest2d = this->point_to_gcode(travel.points[i]);
Vec3d dest3d(dest2d(0), dest2d(1), m_nominal_z);
gcode += m_writer.travel_to_xyz(dest3d, comment + " travel_to_xyz");
gcode += m_writer.travel_to_xyz(dest3d, comment, m_need_change_layer_lift_z);
m_need_change_layer_lift_z = false;
} else if (z != DBL_MAX && i == travel.size() - 1) {
// Apply z_ratio for the very last point
Vec2d dest2d = this->point_to_gcode(travel.points[i]);
Vec3d dest3d(dest2d(0), dest2d(1), z);
gcode += m_writer.travel_to_xyz(dest3d, comment + " travel_to_xyz");
gcode += m_writer.travel_to_xyz(dest3d, comment);
} else {
// For all points in between, no z change
gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment + " travel_to_xy");
gcode += m_writer.travel_to_xy(this->point_to_gcode(travel.points[i]), comment);
}
}
}
}
this->set_last_pos(travel.points.back());
}
return gcode;
}

View file

@ -893,7 +893,8 @@ void WipeTower2::toolchange_Unload(
float remaining = xr - xl ; // keeps track of distance to the next turnaround
float e_done = 0; // measures E move done from each segment
const bool do_ramming = m_semm || m_filpar[m_current_tool].multitool_ramming;
// Orca: Do ramming when SEMM and ramming is enabled or when multi tool head when ramming is enabled on the multi tool.
const bool do_ramming = (m_semm && m_enable_filament_ramming) || m_filpar[m_current_tool].multitool_ramming;
const bool cold_ramming = m_is_mk4mmu3;
if (do_ramming) {
@ -1126,7 +1127,7 @@ void WipeTower2::toolchange_Load(
WipeTowerWriter2 &writer,
const WipeTower::box_coordinates &cleaning_box)
{
if (m_semm && (m_parking_pos_retraction != 0 || m_extra_loading_move != 0)) {
if (m_semm && m_enable_filament_ramming && (m_parking_pos_retraction != 0 || m_extra_loading_move != 0)) {
float xl = cleaning_box.ld.x() + m_perimeter_width * 0.75f;
float xr = cleaning_box.rd.x() - m_perimeter_width * 0.75f;
float oldx = writer.x(); // the nozzle is in place to do the first wiping moves, we will remember the position
@ -1544,7 +1545,8 @@ void WipeTower2::plan_toolchange(float z_par, float layer_height_par, unsigned i
float length_to_extrude = volume_to_length(0.25f * std::accumulate(m_filpar[old_tool].ramming_speed.begin(), m_filpar[old_tool].ramming_speed.end(), 0.f),
m_perimeter_width * m_filpar[old_tool].ramming_line_width_multiplicator,
layer_height_par);
float ramming_depth = (int(length_to_extrude / width) + 1) * (m_perimeter_width * m_filpar[old_tool].ramming_line_width_multiplicator * m_filpar[old_tool].ramming_step_multiplicator) * m_extra_spacing_ramming;
// Orca: Set ramming depth to 0 if ramming is disabled.
float ramming_depth = m_enable_filament_ramming ? ((int(length_to_extrude / width) + 1) * (m_perimeter_width * m_filpar[old_tool].ramming_line_width_multiplicator * m_filpar[old_tool].ramming_step_multiplicator) * m_extra_spacing_ramming) : 0;
float first_wipe_line = - (width*((length_to_extrude / width)-int(length_to_extrude / width)) - width);
float first_wipe_volume = length_to_volume(first_wipe_line, m_perimeter_width * m_extra_flow, layer_height_par);

View file

@ -440,7 +440,7 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com
return w.string();
}
std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment)
std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment, bool force_z)
{
// FIXME: This function was not being used when travel_speed_z was separated (bd6badf).
// Calculation of feedrate was not updated accordingly. If you want to use
@ -526,7 +526,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
this->set_current_position_clear(true);
return slop_move + xy_z_move;
}
else if (!this->will_move_z(point(2))) {
else if (!force_z && !this->will_move_z(point(2))) {
double nominal_z = m_pos(2) - m_lifted;
m_lifted -= (point(2) - nominal_z);
// In case that z_hop == layer_height we could end up with almost zero in_m_lifted

View file

@ -69,7 +69,7 @@ public:
// SoftFever NOTE: the returned speed is mm/minute
double get_current_speed() const { return m_current_speed;}
std::string travel_to_xy(const Vec2d &point, const std::string &comment = std::string());
std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string());
std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string(), bool force_z = false);
std::string travel_to_z(double z, const std::string &comment = std::string());
bool will_move_z(double z) const;
std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false);
@ -81,7 +81,8 @@ public:
std::string unretract();
std::string lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false);
std::string unlift();
Vec3d get_position() const { return m_pos; }
const Vec3d& get_position() const { return m_pos; }
Vec3d& get_position() { return m_pos; }
void set_position(const Vec3d& in) { m_pos = in; }
double get_zhop() const { return m_lifted; }

View file

@ -735,6 +735,12 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
if(paths.empty()) continue;
chain_and_reorder_extrusion_paths(paths, &paths.front().first_point());
} else {
if (overhangs_reverse && perimeter_generator.layer_id > perimeter_generator.object_config->raft_layers) {
// Always reverse if detect overhang wall is not enabled
steep_overhang_contour = true;
steep_overhang_hole = true;
}
ExtrusionPath path(role);
//BBS.
path.polyline = polygon.split_at_first_point();
@ -1219,6 +1225,12 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p
}
}
else {
if (overhangs_reverse && perimeter_generator.layer_id > perimeter_generator.object_config->raft_layers) {
// Always reverse if detect overhang wall is not enabled
steep_overhang_contour = true;
steep_overhang_hole = true;
}
extrusion_paths_append(paths, *extrusion, role, is_external ? perimeter_generator.ext_perimeter_flow : perimeter_generator.perimeter_flow);
}

View file

@ -1056,7 +1056,8 @@ void PrintConfigDef::init_fff_params()
def->category = L("Quality");
// xgettext:no-c-format, no-boost-format
def->tooltip = L("Number of mm the overhang need to be for the reversal to be considered useful. Can be a % of the perimeter width."
"\nValue 0 enables reversal on every even layers regardless.");
"\nValue 0 enables reversal on every even layers regardless."
"\nWhen Detect overhang wall is not enabled, this option is ignored and reversal happens on every even layers regardless.");
def->sidetext = L("mm or %");
def->ratio_over = "line_width";
def->min = 0;
@ -2124,6 +2125,7 @@ void PrintConfigDef::init_fff_params()
def->enum_values.push_back("PET-CF");
def->enum_values.push_back("PETG");
def->enum_values.push_back("PETG-CF");
def->enum_values.push_back("PETG-CF10");
def->enum_values.push_back("PHA");
def->enum_values.push_back("PLA");
def->enum_values.push_back("PLA-AERO");