Merge remote-tracking branch 'upstream/main' into libvgcode

# Conflicts:
#	src/libslic3r/GCode/GCodeProcessor.cpp
This commit is contained in:
Andrew Sun
2025-11-18 19:53:58 -05:00
1153 changed files with 385954 additions and 2728 deletions

View File

@@ -288,6 +288,9 @@ ConflictComputeOpt ConflictChecker::line_intersect(const LineWithID &l1, const L
constexpr double SUPPORT_THRESHOLD = 100; // this large almost disables conflict check of supports
constexpr double OTHER_THRESHOLD = 0.01;
if (l1._id == l2._id) { return {}; } // return true if lines are from same object
double overlap_length = 0.;
bool overlap = l1._line.overlap(l2._line, overlap_length);
if (overlap && overlap_length > scaled(OTHER_THRESHOLD)) return std::make_optional<ConflictComputeResult>(l1._id, l2._id);
Point inter;
bool intersect = l1._line.intersection(l2._line, &inter);

View File

@@ -33,8 +33,9 @@ struct ExtrusionLayer
enum class ExtrusionLayersType { INFILL, PERIMETERS, SUPPORT, WIPE_TOWER };
struct ExtrusionLayers : public std::vector<ExtrusionLayer>
class ExtrusionLayers : public std::vector<ExtrusionLayer>
{
public:
ExtrusionLayersType type;
};

View File

@@ -2478,6 +2478,13 @@ void GCodeProcessor::process_file(const std::string& filename, std::function<voi
// thus a probability of incorrect substitution is low and the G-code viewer is a consumer-only anyways.
config.load_from_gcode_file(filename, ForwardCompatibilitySubstitutionRule::EnableSilent);
// Get the correct printer vendor based on the `printer_model` field
auto printer_model_opt = config.opt<ConfigOptionString>("printer_model");
if (printer_model_opt && !printer_model_opt->value.empty()) {
// TODO: Orca hack, proper vendor check?
GCodeProcessor::s_IsBBLPrinter = boost::starts_with(printer_model_opt->value, "Bambu Lab");
}
ConfigOptionStrings *filament_color = config.opt<ConfigOptionStrings>("filament_colour");
ConfigOptionInts *filament_map = config.opt<ConfigOptionInts>("filament_map", true);
if (filament_color && filament_color->size() != filament_map->size()) {
@@ -2554,6 +2561,8 @@ void GCodeProcessor::finalize(bool post_process)
update_estimated_times_stats();
m_result.initial_layer_time = get_first_layer_time(PrintEstimatedStatistics::ETimeMode::Normal);
if (post_process){
run_post_process();
}

View File

@@ -152,6 +152,7 @@ class Print;
ConflictResultOpt conflict_result;
GCodeCheckResult gcode_check_result;
FilamentPrintableResult filament_printable_reuslt;
float initial_layer_time;
struct SettingsIds
{
@@ -281,6 +282,7 @@ class Print;
filament_printable_reuslt = other.filament_printable_reuslt;
layer_filaments = other.layer_filaments;
filament_change_count_map = other.filament_change_count_map;
initial_layer_time = other.initial_layer_time;
#if ENABLE_GCODE_VIEWER_STATISTICS
time = other.time;
#endif

View File

@@ -78,6 +78,7 @@ struct PlateBBoxData
int first_extruder = 0;
float nozzle_diameter = 0.4;
std::string bed_type;
float first_layer_time;
// version 1: use view type ColorPrint (filament color)
// version 2: use view type FilamentId (filament id)
int version = 2;
@@ -91,6 +92,7 @@ struct PlateBBoxData
j["nozzle_diameter"] = nozzle_diameter;
j["version"] = version;
j["bed_type"] = bed_type;
j["first_layer_time"] = first_layer_time;
for (const auto& bbox : bbox_objs) {
nlohmann::json j_bbox;
bbox.to_json(j_bbox);

View File

@@ -380,19 +380,42 @@ namespace Slic3r {
std::priority_queue<CandidatePoint> max_heap;
double min_distance = std::numeric_limits<double>::max();
Point nearest_point = DefaultTimelapsePos;
const double candidate_point_segment = scale_(5), weight_of_camera=1./3.;
auto penaltyFunc = [&weight_of_camera](const Point &curr_post, const Point &CameraPos, const Point &candidatet) -> double {
// move distance + Camera occlusion penalty function
double ret_pen = (curr_post - candidatet).cwiseAbs().sum() - weight_of_camera * (CameraPos - candidatet).cwiseAbs().sum();
return ret_pen;
};
for (const auto& expoly : safe_areas) {
Polygons polys = to_polygons(expoly);
for (auto& poly : polys) {
for (size_t idx = 0; idx < poly.points.size(); ++idx) {
Line line(poly.points[idx], poly.points[next_idx_modulo(idx, poly.points)]);
Point candidate;
double dist = line.distance_to_squared(curr_pos, &candidate);
max_heap.push({ dist,candidate });
if (max_heap.size() > MAX_CANDIDATE_SIZE)
max_heap.pop();
double best_penalty = std::numeric_limits<double>::max();
Point best_candidate = DefaultTimelapsePos; // the best candidate form current line
//std::vector<Point> candidate_source;
if ((poly.points[idx] - poly.points[next_idx_modulo(idx, poly.points)]).cwiseAbs().sum() < candidate_point_segment) {
best_candidate = poly.points[idx]; // only check the start point if the line is short
best_penalty = penaltyFunc(curr_pos, DefaultCameraPos, best_candidate);
}else{
Point direct_of_line = poly.points[next_idx_modulo(idx, poly.points)] - poly.points[idx];
double length_L1 = direct_of_line.cwiseAbs().sum();
int num_steps = static_cast<int>(length_L1 / candidate_point_segment); // for long line use 5mm segmentation to check
// devide by length_L1 instead of steps, prevent lose accuracy for the step length
direct_of_line.x() = static_cast<coord_t>(static_cast<double> (direct_of_line.x()) * candidate_point_segment / length_L1);
direct_of_line.y() = static_cast<coord_t>(static_cast<double> (direct_of_line.y()) * candidate_point_segment / length_L1);
Point candidate;
for (int line_seg_i = 0; line_seg_i <= num_steps; ++line_seg_i) {
candidate=poly.points[idx] + direct_of_line * line_seg_i;
double dist = penaltyFunc(curr_pos, DefaultCameraPos, candidate);
if (dist < best_penalty) {
best_penalty = dist;
best_candidate = candidate;
}//only push the best point into heap for the whole line
}
}
max_heap.push({best_penalty, best_candidate});
if (max_heap.size() > MAX_CANDIDATE_SIZE) max_heap.pop();
}
}
}

View File

@@ -928,6 +928,22 @@ void ToolOrdering::cal_most_used_extruder(const PrintConfig &config)
}
}
float ToolOrdering::cal_max_additional_fan(const PrintConfig &config)
{
// record
float max_fan = 0;
for (LayerTools &layer_tools : m_layer_tools) {
std::vector<unsigned int> filaments = layer_tools.extruders;
std::set<int> layer_extruder_count;
// count once only
for (unsigned int &filament : filaments)
if (max_fan < config.additional_cooling_fan_speed.get_at(filament))
max_fan = config.additional_cooling_fan_speed.get_at(filament);
}
return max_fan;
}
//BBS: find first non support filament
bool ToolOrdering::cal_non_support_filaments(const PrintConfig &config,
unsigned int & first_non_support_filament,

View File

@@ -246,6 +246,7 @@ public:
// should be called after doing reorder
FilamentChangeStats get_filament_change_stats(FilamentChangeMode mode);
void cal_most_used_extruder(const PrintConfig &config);
float cal_max_additional_fan(const PrintConfig &config);
bool cal_non_support_filaments(const PrintConfig &config,
unsigned int & first_non_support_filament,
std::vector<int> & initial_non_support_filaments,

View File

@@ -3745,9 +3745,10 @@ void WipeTower::plan_tower_new()
}
update_all_layer_depth(max_depth);
m_rib_length = std::max({m_rib_length, sqrt(m_wipe_tower_depth * m_wipe_tower_depth + m_wipe_tower_width * m_wipe_tower_width)});
float diagonal = sqrt(m_wipe_tower_depth * m_wipe_tower_depth + m_wipe_tower_width * m_wipe_tower_width);
m_rib_length = std::max({m_rib_length, diagonal});
m_rib_length += m_extra_rib_length;
m_rib_length = std::max(0.f, m_rib_length);
m_rib_length = std::max(diagonal, m_rib_length);
m_rib_width = std::min(m_rib_width, std::min(m_wipe_tower_depth, m_wipe_tower_width) / 2.f); // Ensure that the rib wall of the wipetower are attached to the infill.
}