Merge some BS1.7 changes:

Port object canceling for BL X1 from BS.

Todo: refactor
This commit is contained in:
SoftFever
2023-08-08 00:13:33 +08:00
parent e111f97d26
commit 2d036026fc
15 changed files with 557 additions and 162 deletions

View File

@ -260,7 +260,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
osteps.emplace_back(posPerimeters);
osteps.emplace_back(posInfill);
osteps.emplace_back(posSupportMaterial);
osteps.emplace_back(posSimplifyPath);
osteps.emplace_back(posSimplifyPath);
osteps.emplace_back(posSimplifyInfill);
osteps.emplace_back(posSimplifySupportPath);
steps.emplace_back(psSkirtBrim);
}
@ -332,6 +333,18 @@ std::vector<unsigned int> Print::object_extruders() const
extruders.push_back(extruder - 1);
}
}
// layer range
for (auto layer_range : mo->layer_config_ranges) {
if (layer_range.second.has("extruder")) {
//BBS: actually when user doesn't change filament by height range(value is default 0), height range should not save key "extruder".
//Don't know why height range always save key "extruder" because of no change(should only save difference)...
//Add protection here to avoid overflow
auto value = layer_range.second.option("extruder")->getInt();
if (value > 0)
extruders.push_back(value - 1);
}
}
}
#endif
sort_remove_duplicates(extruders);
@ -436,6 +449,25 @@ bool Print::has_brim() const
}
//BBS
std::vector<size_t> Print::layers_sorted_for_object(float start, float end, std::vector<LayerPtrs> &layers_of_objects, std::vector<BoundingBox> &boundingBox_for_objects, std::vector<Points> &objects_instances_shift)
{
std::vector<size_t> idx_of_object_sorted;
size_t idx = 0;
for (const auto &object : m_objects) {
idx_of_object_sorted.push_back(idx++);
object->get_certain_layers(start, end, layers_of_objects, boundingBox_for_objects);
}
std::sort(idx_of_object_sorted.begin(), idx_of_object_sorted.end(),
[boundingBox_for_objects](auto left, auto right) { return boundingBox_for_objects[left].area() > boundingBox_for_objects[right].area(); });
objects_instances_shift.clear();
objects_instances_shift.reserve(m_objects.size());
for (const auto& object : m_objects)
objects_instances_shift.emplace_back(object->get_instances_shift_without_plate_offset());
return idx_of_object_sorted;
};
StringObjectException Print::sequential_print_clearance_valid(const Print &print, Polygons *polygons, std::vector<std::pair<Polygon, float>>* height_polygons)
{
StringObjectException single_object_exception;
@ -534,19 +566,24 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
// if output needed, collect indices (inside convex_hulls_other) of intersecting hulls
for (size_t i = 0; i < convex_hulls_other.size(); ++i) {
if (! intersection(convex_hulls_other[i], convex_hull).empty()) {
bool has_exception = false;
if (single_object_exception.string.empty()) {
single_object_exception.string = (boost::format(L("%1% is too close to others, and collisions may be caused.")) %instance.model_instance->get_object()->name).str();
single_object_exception.object = instance.model_instance->get_object();
has_exception = true;
}
else {
single_object_exception.string += "\n"+(boost::format(L("%1% is too close to others, and collisions may be caused.")) %instance.model_instance->get_object()->name).str();
single_object_exception.object = nullptr;
has_exception = true;
}
if (polygons) {
intersecting_idxs.emplace_back(i);
intersecting_idxs.emplace_back(convex_hulls_other.size());
}
if (has_exception) break;
}
}
struct print_instance_info print_info {&instance, convex_hull.bounding_box(), convex_hull};
@ -865,40 +902,51 @@ static StringObjectException layered_print_cleareance_valid(const Print &print,
return {};
}
//BBS
static std::map<std::string, bool> filament_is_high_temp {
{"PLA", false},
{"PLA-CF", false},
//{"PETG", true},
{"ABS", true},
{"TPU", false},
{"PA", true},
{"PA-CF", true},
{"PET-CF", true},
{"PC", true},
{"ASA", true}
};
//BBS: this function is used to check whether multi filament can be printed
StringObjectException Print::check_multi_filament_valid(const Print& print)
bool Print::check_multi_filaments_compatibility(const std::vector<std::string>& filament_types)
{
static std::map<std::string, bool> filament_is_high_temp{
{"PLA", false},
{"PLA-CF", false},
//{"PETG", true},
{"ABS", true},
{"TPU", false},
{"PA", true},
{"PA-CF", true},
{"PET-CF", true},
{"PC", true},
{"ASA", true},
{"HIPS", true}
};
bool has_high_temperature_filament = false;
bool has_low_temperature_filament = false;
auto print_config = print.config();
std::vector<unsigned int> extruders = print.extruders();
for (const auto& extruder_idx : extruders) {
std::string filament_type = print_config.filament_type.get_at(extruder_idx);
if (filament_is_high_temp.find(filament_type) != filament_is_high_temp.end()) {
if (filament_is_high_temp[filament_type])
for (const auto& type : filament_types)
if (filament_is_high_temp.find(type) != filament_is_high_temp.end()) {
if (filament_is_high_temp[type])
has_high_temperature_filament = true;
else
has_low_temperature_filament = true;
}
}
if (has_high_temperature_filament && has_low_temperature_filament)
return false;
return true;
}
//BBS: this function is used to check whether multi filament can be printed
StringObjectException Print::check_multi_filament_valid(const Print& print)
{
auto print_config = print.config();
std::vector<unsigned int> extruders = print.extruders();
std::vector<std::string> filament_types;
filament_types.reserve(extruders.size());
for (const auto& extruder_idx : extruders)
filament_types.push_back(print_config.filament_type.get_at(extruder_idx));
if (!check_multi_filaments_compatibility(filament_types))
return { L("Can not print multiple filaments which have large difference of temperature together. Otherwise, the extruder and nozzle may be blocked or damaged during printing") };
return {std::string()};
@ -917,28 +965,11 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
return { L("No extrusions under current settings.") };
if (extruders.size() > 1 && m_config.print_sequence != PrintSequence::ByObject) {
if (m_config.single_extruder_multi_material) {
auto ret = check_multi_filament_valid(*this);
if (!ret.string.empty())
return ret;
}
if (warning) {
for (unsigned int extruder_a: extruders) {
const ConfigOptionInts* bed_temp_opt = m_config.option<ConfigOptionInts>(get_bed_temp_key(m_config.curr_bed_type));
const ConfigOptionInts* bed_temp_1st_opt = m_config.option<ConfigOptionInts>(get_bed_temp_1st_layer_key(m_config.curr_bed_type));
int bed_temp_a = bed_temp_opt->get_at(extruder_a);
int bed_temp_1st_a = bed_temp_1st_opt->get_at(extruder_a);
for (unsigned int extruder_b: extruders) {
int bed_temp_b = bed_temp_opt->get_at(extruder_b);
int bed_temp_1st_b = bed_temp_1st_opt->get_at(extruder_b);
if (std::abs(bed_temp_a - bed_temp_b) > 15 || std::abs(bed_temp_1st_a - bed_temp_1st_b) > 15) {
warning->string = L("Bed temperatures for the used filaments differ significantly.");
goto DONE;
}
}
}
DONE:;
auto ret = check_multi_filament_valid(*this);
if (!ret.string.empty())
{
ret.type = STRING_EXCEPT_FILAMENTS_DIFFERENT_TEMP;
return ret;
}
}
@ -948,13 +979,16 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
//BBS: refine seq-print validation logic
auto ret = sequential_print_clearance_valid(*this, collison_polygons, height_polygons);
if (!ret.string.empty())
if (!ret.string.empty()) {
ret.type = STRING_EXCEPT_OBJECT_COLLISION_IN_SEQ_PRINT;
return ret;
}
}
else {
//BBS
auto ret = layered_print_cleareance_valid(*this, warning);
if (!ret.string.empty()) {
ret.type = STRING_EXCEPT_OBJECT_COLLISION_IN_LAYER_PRINT;
return ret;
}
}
@ -984,10 +1018,9 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
// BBS: remove L()
return { ("Different nozzle diameters and different filament diameters is not allowed when prime tower is enabled.") };
}
if (! m_config.use_relative_e_distances)
return { ("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).") };
if (m_config.ooze_prevention)
return { ("Ooze prevention is currently not supported with the prime tower enabled.") };
@ -1393,6 +1426,20 @@ void PrintObject::copy_layers_from_shared_object()
}
}
void PrintObject::copy_layers_overhang_from_shared_object()
{
if (m_shared_object) {
for (size_t index = 0; index < m_layers.size() && index < m_shared_object->m_layers.size(); index++)
{
Layer* layer_src = m_layers[index];
layer_src->loverhangs = m_shared_object->m_layers[index]->loverhangs;
layer_src->loverhangs_bbox = m_shared_object->m_layers[index]->loverhangs_bbox;
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, copied layer overhang from object %2%")%this%m_shared_object;
}
}
// BBS
BoundingBox PrintObject::get_first_layer_bbox(float& a, float& layer_height, std::string& name)
{
@ -1403,7 +1450,7 @@ BoundingBox PrintObject::get_first_layer_bbox(float& a, float& layer_height, std
auto layer = get_layer(0);
layer_height = layer->height;
// only work for object with single instance
auto shift = instances()[0].shift;
auto shift = instances()[0].shift_without_plate_offset();
for (auto bb : layer->lslices_bboxes)
{
bb.translate(shift.x(), shift.y());
@ -1494,6 +1541,7 @@ void Print::process(bool use_cache)
};
int object_count = m_objects.size();
std::set<PrintObject*> need_slicing_objects;
std::set<PrintObject*> re_slicing_objects;
if (!use_cache) {
for (int index = 0; index < object_count; index++)
{
@ -1530,8 +1578,12 @@ void Print::process(bool use_cache)
}
}
if (!found_shared) {
BOOST_LOG_TRIVIAL(error) << boost::format("Also can not find the shared object, identify_id %1%")%obj->model_object()->instances[0]->loaded_id;
throw Slic3r::SlicingError("Can not find the cached data.");
BOOST_LOG_TRIVIAL(warning) << boost::format("Also can not find the shared object, identify_id %1%, maybe shared object is skipped")%obj->model_object()->instances[0]->loaded_id;
//throw Slic3r::SlicingError("Can not find the cached data.");
//don't report errot, set use_cache to false, and reslice these objects
need_slicing_objects.insert(obj);
re_slicing_objects.insert(obj);
//use_cache = false;
}
}
}
@ -1589,18 +1641,26 @@ void Print::process(bool use_cache)
}
else {
for (PrintObject *obj : m_objects) {
if (obj->set_started(posSlice))
obj->set_done(posSlice);
if (obj->set_started(posPerimeters))
obj->set_done(posPerimeters);
if (obj->set_started(posPrepareInfill))
obj->set_done(posPrepareInfill);
if (obj->set_started(posInfill))
obj->set_done(posInfill);
if (obj->set_started(posIroning))
obj->set_done(posIroning);
if (obj->set_started(posSupportMaterial))
obj->set_done(posSupportMaterial);
if (re_slicing_objects.count(obj) == 0) {
if (obj->set_started(posSlice))
obj->set_done(posSlice);
if (obj->set_started(posPerimeters))
obj->set_done(posPerimeters);
if (obj->set_started(posPrepareInfill))
obj->set_done(posPrepareInfill);
if (obj->set_started(posInfill))
obj->set_done(posInfill);
if (obj->set_started(posIroning))
obj->set_done(posIroning);
if (obj->set_started(posSupportMaterial))
obj->set_done(posSupportMaterial);
}
else {
obj->make_perimeters();
obj->infill();
obj->ironing();
obj->generate_support_material();
}
}
}
@ -1713,12 +1773,15 @@ void Print::process(bool use_cache)
}
//BBS
for (PrintObject *obj : m_objects) {
if ((!use_cache)&&(need_slicing_objects.count(obj) != 0)) {
if (((!use_cache)&&(need_slicing_objects.count(obj) != 0))
|| (use_cache &&(re_slicing_objects.count(obj) != 0))){
obj->simplify_extrusion_path();
}
else {
if (obj->set_started(posSimplifyPath))
obj->set_done(posSimplifyPath);
if (obj->set_started(posSimplifyInfill))
obj->set_done(posSimplifyInfill);
if (obj->set_started(posSimplifySupportPath))
obj->set_done(posSimplifySupportPath);
}
@ -1730,6 +1793,7 @@ void Print::process(bool use_cache)
obj->detect_overhangs_for_lift();
}
else {
obj->copy_layers_overhang_from_shared_object();
if (obj->set_started(posDetectOverhangsForLift))
obj->set_done(posDetectOverhangsForLift);
}
@ -3094,7 +3158,14 @@ int Print::export_cached_data(const std::string& directory, bool with_space)
if (fs::exists(directory_path)) {
fs::remove_all(directory_path);
}
if (!fs::create_directory(directory_path)) {
try {
if (!fs::create_directory(directory_path)) {
BOOST_LOG_TRIVIAL(error) << boost::format("create directory %1% failed")%directory;
return CLI_EXPORT_CACHE_DIRECTORY_CREATE_FAILED;
}
}
catch (...)
{
BOOST_LOG_TRIVIAL(error) << boost::format("create directory %1% failed")%directory;
return CLI_EXPORT_CACHE_DIRECTORY_CREATE_FAILED;
}
@ -3528,4 +3599,12 @@ Polygon PrintInstance::get_convex_hull_2d() {
return poly;
}
//BBS: instance_shift is too large because of multi-plate, apply without plate offset.
Point PrintInstance::shift_without_plate_offset() const
{
const Print* print = print_object->print();
const Vec3d plate_offset = print->get_plate_origin();
return shift - Point(scaled(plate_offset.x()), scaled(plate_offset.y()));
}
} // namespace Slic3r