FIX: several auto arranging bugs

1. fill bed crash (jira: STUDIO-10350)
2. reset arranging settings gives wrong sequential printing order (jira: STUDIO-10346)
3. do not show "arranging done" message when there is no model

Change-Id: Ic1c7eac75e3917b9f1d87ab6acc403f78e0c9f7c
This commit is contained in:
Arthur 2025-02-13 08:57:58 +08:00 committed by lane.wei
parent 65267b9866
commit c414e51999
8 changed files with 87 additions and 69 deletions

View File

@ -2,7 +2,6 @@
#define SRC_LIBSLIC3R_AABBTREELINES_HPP_
#include "Point.hpp"
#include "Utils.hpp"
#include "libslic3r.h"
#include "libslic3r/AABBTreeIndirect.hpp"
#include "libslic3r/Line.hpp"

View File

@ -3949,30 +3949,30 @@ double ModelInstance::get_auto_brim_width() const
void ModelInstance::get_arrange_polygon(void *ap, const Slic3r::DynamicPrintConfig &config_global) const
{
// static const double SIMPLIFY_TOLERANCE_MM = 0.1;
// static const double SIMPLIFY_TOLERANCE_MM = 0.1;
Geometry::Transformation trafo_instance = get_transformation();
//BOOST_LOG_TRIVIAL(debug) << "get_arrange_polygon: " << object->name << " instance trans:\n"
// << trafo_instance.get_matrix().matrix() << "\n object trans:\n"
// << object->volumes.front()->get_transformation().get_matrix().matrix();
// BOOST_LOG_TRIVIAL(debug) << "get_arrange_polygon: " << object->name << " instance trans:\n"
// << trafo_instance.get_matrix().matrix() << "\n object trans:\n"
// << object->volumes.front()->get_transformation().get_matrix().matrix();
trafo_instance.set_offset(Vec3d(0, 0, get_offset(Z)));
Polygon p = get_object()->convex_hull_2d(trafo_instance.get_matrix());
// if (!p.points.empty()) {
// Polygons pp{p};
// pp = p.simplify(scaled<double>(SIMPLIFY_TOLERANCE_MM));
// if (!pp.empty()) p = pp.front();
// }
// if (!p.points.empty()) {
// Polygons pp{p};
// pp = p.simplify(scaled<double>(SIMPLIFY_TOLERANCE_MM));
// if (!pp.empty()) p = pp.front();
// }
arrangement::ArrangePolygon& ret = *(arrangement::ArrangePolygon*)ap;
ret.poly.contour = std::move(p);
ret.translation = Vec2crd{scaled(get_offset(X)), scaled(get_offset(Y))};
ret.rotation = 0;
arrangement::ArrangePolygon &ret = *(arrangement::ArrangePolygon *) ap;
ret.poly.contour = std::move(p);
ret.translation = Vec2crd{scaled(get_offset(X)), scaled(get_offset(Y))};
ret.rotation = 0;
//BBS: add materials related information
// BBS: add materials related information
ModelVolume *volume = NULL;
for (size_t i = 0; i < object->volumes.size(); ++i) {
if (object->volumes[i]->is_model_part()) {
@ -3987,19 +3987,22 @@ void ModelInstance::get_arrange_polygon(void *ap, const Slic3r::DynamicPrintConf
}
// get per-object support extruders
auto op = object->get_config_value<ConfigOptionBool>(config_global, "enable_support");
auto op = object->get_config_value<ConfigOptionBool>(config_global, "enable_support");
bool is_support_enabled = op && op->getBool();
if (is_support_enabled) {
auto op1 = object->get_config_value<ConfigOptionInt>(config_global, "support_filament");
auto op2 = object->get_config_value<ConfigOptionInt>(config_global, "support_interface_filament");
int extruder_id;
int extruder_id;
// id==0 means follow previous material, so need not be recorded
if (op1 && (extruder_id = op1->getInt()) > 0) ret.extrude_ids.push_back(extruder_id);
if (op2 && (extruder_id = op2->getInt()) > 0) ret.extrude_ids.push_back(extruder_id);
}
if (ret.extrude_ids.empty()) //the default extruder
if (ret.extrude_ids.empty()) // the default extruder
ret.extrude_ids.push_back(1);
// filament types must be same size as extrude_ids
ret.filament_types.resize(ret.extrude_ids.size(), "PLA");
}
void ModelInstance::apply_arrange_result(const Vec2d &offs, double rotation)

View File

@ -2070,7 +2070,8 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor
gcode.do_export(this, path.c_str(), result, thumbnail_cb);
gcode.export_layer_filaments(result);
//BBS
result->conflict_result = m_conflict_result;
if (result != nullptr)
result->conflict_result = m_conflict_result;
return path.c_str();
}

View File

@ -668,25 +668,6 @@ inline std::string filter_characters(const std::string& str, const std::string&
return filteredStr;
}
// custom vector wrapper for outputting to log
template<typename T> struct VectorFormatter
{
const std::vector<T> &vec;
explicit VectorFormatter(const std::vector<T> &v) : vec(v) {}
friend std::ostream &operator<<(std::ostream &os, const VectorFormatter<T> &vf)
{
os << "[";
for (size_t i = 0; i < vf.vec.size(); ++i) {
os << vf.vec[i];
if (i != vf.vec.size() - 1) { os << ", "; }
}
os << "]";
return os;
}
};
} // namespace Slic3r
#if WIN32

View File

@ -0,0 +1,33 @@
#pragma once
#include <Eigen/Core>
#include <vector>
#include <iostream>
// custom vector wrapper for outputting to log
template<typename T> struct VectorFormatter
{
const std::vector<T>* vec = nullptr;
const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>* mat = nullptr;
explicit VectorFormatter(const std::vector<T>& v) : vec(&v) {}
explicit VectorFormatter(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& m) : mat(&m) {}
friend std::ostream& operator<<(std::ostream& os, const VectorFormatter<T>& vf)
{
os << "[";
if (vf.vec) {
for (size_t i = 0; i < vf.vec->size(); ++i) {
os << (*vf.vec)[i];
if (i != vf.vec->size() - 1) { os << ", "; }
}
}
else {
for (int i = 0; i < vf.mat->size(); ++i) {
os << (*vf.mat)(i);
if (i != vf.mat->size() - 1) { os << ", "; }
}
}
os << "]";
return os;
}
};

View File

@ -1122,12 +1122,16 @@ GLCanvas3D::ArrangeSettings& GLCanvas3D::get_arrange_settings()
if (ptech == ptSLA) {
ptr = &m_arrange_settings_sla;
ptr->postfix = "_sla";
}
else if (ptech == ptFFF) {
if (wxGetApp().global_print_sequence() == PrintSequence::ByObject)
ptr = &m_arrange_settings_fff_seq_print;
else
ptr = &m_arrange_settings_fff;
if (wxGetApp().global_print_sequence() == PrintSequence::ByObject) {
ptr = &m_arrange_settings_fff_seq_print;
ptr->postfix = "_fff_seq_print";
} else {
ptr = &m_arrange_settings_fff;
ptr->postfix = "_fff";
}
}
return *ptr;
@ -5909,20 +5913,9 @@ bool GLCanvas3D::_render_arrange_menu(float left, float right, float bottom, flo
std::string multi_material_key = "allow_multi_materials_on_same_plate";
std::string avoid_extrusion_key = "avoid_extrusion_cali_region";
std::string align_to_y_axis_key = "align_to_y_axis";
std::string postfix;
std::string postfix = settings.postfix;
//BBS:
bool seq_print = false;
if (ptech == ptSLA) {
postfix = "_sla";
} else if (ptech == ptFFF) {
seq_print = &settings == &m_arrange_settings_fff_seq_print;
if (seq_print) {
postfix = "_fff_seq_print";
} else {
postfix = "_fff";
}
}
bool seq_print = settings.is_seq_print;
dist_key += postfix;
rot_key += postfix;
@ -5998,8 +5991,7 @@ bool GLCanvas3D::_render_arrange_menu(float left, float right, float bottom, flo
ImGui::SameLine();
if (imgui->button(_L("Reset"))) {
settings_out = ArrangeSettings{};
settings_out.distance = std::max(dist_min, settings_out.distance);
settings_out.reset();
//BBS: add specific arrange settings
if (seq_print) settings_out.is_seq_print = true;

View File

@ -514,6 +514,17 @@ public:
//BBS: add more arrangeSettings
bool is_seq_print = false;
bool align_to_y_axis = false;
std::string postfix;
void reset()
{
distance = 0.f;
accuracy = 0.65f;
enable_rotation = false;
allow_multi_materials_on_same_plate = true;
avoid_extrusion_cali_region = true;
is_seq_print = false;
align_to_y_axis = false;
}
};
struct OrientSettings

View File

@ -2,6 +2,7 @@
#include "libslic3r/SVG.hpp"
#include "libslic3r/ModelArrange.hpp"
#include "libslic3r/VectorFormatter.hpp"
#include "slic3r/GUI/PartPlate.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
@ -519,10 +520,6 @@ void ArrangeJob::prepare_outside_plate() {
//BBS: add partplate logic
void ArrangeJob::prepare()
{
m_plater->get_notification_manager()->push_notification(NotificationType::ArrangeOngoing,
NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("Arranging..."));
m_plater->get_notification_manager()->bbl_close_plateinfo_notification();
params = init_arrange_params(m_plater);
//BBS update extruder params and speed table before arranging
@ -620,8 +617,8 @@ void ArrangeJob::on_exception(const std::exception_ptr &eptr)
if (eptr)
std::rethrow_exception(eptr);
} catch (libnest2d::GeometryException &) {
show_error(m_plater, _(L("Arrange failed. "
"Found some exceptions when processing object geometries.")));
show_error(m_plater, _L("Arrange failed. "
"Found some exceptions when processing object geometries."));
} catch (std::exception &) {
PlaterJob::on_exception(eptr);
}
@ -655,10 +652,10 @@ void ArrangeJob::process()
BOOST_LOG_TRIVIAL(warning)<< "Arrange full params: "<< params.to_json();
BOOST_LOG_TRIVIAL(info) << boost::format("arrange: items selected before arranging: %1%") % m_selected.size();
for (auto selected : m_selected) {
BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << VectorFormatter( selected.extrude_ids)
BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << VectorFormatter(selected.extrude_ids)
<< ", filament types: " << VectorFormatter(selected.filament_types) << ", bed: " << selected.bed_idx
<< ", filemant_type:" << selected.filament_temp_type << ", trans: " << selected.translation.transpose()
<< ", rotation: " << selected.rotation;
<< ", filemant_type:" << selected.filament_temp_type << ", trans: " << unscale<double>(selected.translation(X)) << ","
<< unscale<double>(selected.translation(Y)) << ", rotation: " << selected.rotation;
}
BOOST_LOG_TRIVIAL(debug) << "arrange: items unselected before arrange: " << m_unselected.size();
for (auto item : m_unselected)
@ -673,7 +670,7 @@ void ArrangeJob::process()
{
BOOST_LOG_TRIVIAL(info) << boost::format("arrange: items selected after arranging: %1%") % m_selected.size();
for (auto selected : m_selected)
BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx
BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << VectorFormatter(selected.extrude_ids) << ", bed: " << selected.bed_idx
<< ", bed_temp: " << selected.first_bed_temp << ", print_temp: " << selected.print_temp
<< ", trans: " << unscale<double>(selected.translation(X)) << "," << unscale<double>(selected.translation(Y))
<< ", rotation: " << selected.rotation;
@ -822,8 +819,9 @@ void ArrangeJob::finalize()
wxGetApp().obj_list()->reload_all_plates();
m_plater->update();
m_plater->get_notification_manager()->push_notification(NotificationType::ArrangeOngoing,
NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("Arranging done."));
if (!m_selected.empty())
m_plater->get_notification_manager()->push_notification(NotificationType::ArrangeOngoing, NotificationManager::NotificationLevel::RegularNotificationLevel,
_u8L("Arranging done."));
}
else {
m_plater->get_notification_manager()->push_notification(NotificationType::ArrangeOngoing,