FIX: modify unprintable_filament_ids should regroup

jira: none
Change-Id: Ifb8105f6e301aaed9ca4e62a37b9d3a1616e755b
This commit is contained in:
zhimin.zeng 2024-09-12 12:25:04 +08:00 committed by lane.wei
parent d56bf872cf
commit fec7129437
10 changed files with 199 additions and 22 deletions

View File

@ -196,7 +196,8 @@ enum ConfigOptionType {
coEnum = 9,
// BBS: vector of enums
coEnums = coEnum + coVectorType,
coPointsGroups = 10 + coVectorType
coPointsGroups = 10 + coVectorType,
coIntsGroups = 11 + coVectorType
};
enum ConfigOptionMode {
@ -1647,6 +1648,110 @@ private:
template<class Archive> void serialize(Archive& ar) { ar(cereal::base_class<ConfigOptionVector>(this)); }
};
class ConfigOptionIntsGroups : public ConfigOptionVector<std::vector<int>>
{
public:
ConfigOptionIntsGroups() : ConfigOptionVector<std::vector<int>>() {}
explicit ConfigOptionIntsGroups(std::initializer_list<std::vector<int>> il) : ConfigOptionVector<std::vector<int>>(std::move(il)) {}
explicit ConfigOptionIntsGroups(const std::vector<std::vector<int>> &values) : ConfigOptionVector<std::vector<int>>(values) {}
static ConfigOptionType static_type() { return coIntsGroups; }
ConfigOptionType type() const override { return static_type(); }
ConfigOption *clone() const override { return new ConfigOptionIntsGroups(*this); }
ConfigOptionIntsGroups &operator=(const ConfigOption *opt)
{
this->set(opt);
return *this;
}
bool operator==(const ConfigOptionIntsGroups &rhs) const throw() { return this->values == rhs.values; }
bool operator==(const ConfigOption &rhs) const override
{
if (rhs.type() != this->type()) throw ConfigurationError("ConfigConfigOptionIntsGroups: Comparing incompatible types");
assert(dynamic_cast<const ConfigOptionVector<std::vector<int>> *>(&rhs));
return this->values == static_cast<const ConfigOptionVector<std::vector<int>> *>(&rhs)->values;
}
bool operator<(const ConfigOptionIntsGroups &rhs) const throw() {
bool is_lower = true;
for (size_t i = 0; i < values.size(); ++i) {
if (this->values[i] == rhs.values[i])
continue;
return (this->values[i] < rhs.values[i]);
}
return is_lower;
}
bool nullable() const override { return false; }
bool is_nil(size_t) const override { return false; }
std::string serialize() const override
{
std::ostringstream ss;
for (auto iter = this->values.begin(); iter != this->values.end(); ++iter) {
if (iter != this->values.begin())
ss << "#";
serialize_single_value(ss, *iter);
}
return ss.str();
}
std::vector<std::string> vserialize() const override
{
std::vector<std::string> ret;
for (const auto &value : this->values) {
std::ostringstream ss;
serialize_single_value(ss, value);
ret.emplace_back(ss.str());
}
return ret;
}
bool deserialize(const std::string &str, bool append = false) override
{
if (!append) this->values.clear();
std::istringstream is(str);
std::string group_str;
while (std::getline(is, group_str, '#')) {
std::vector<int> group_values;
std::istringstream iss(group_str);
std::string value_str;
while (std::getline(iss, value_str, ',')) {
int value;
std::istringstream(value_str) >> value;
group_values.push_back(value);
}
this->values.emplace_back(std::move(group_values));
}
return true;
}
std::vector<std::string> vserialize_single(int idx) const
{
std::vector<std::string> ret;
assert(idx < this->size());
for (auto iter = values[idx].begin(); iter != values[idx].end(); ++iter) {
std::ostringstream ss;
ss << (*iter);
ret.emplace_back(ss.str());
}
return ret;
}
protected:
void serialize_single_value(std::ostringstream &ss, const std::vector<int> &v) const
{
for (auto iter = v.begin(); iter != v.end(); ++iter) {
if (iter - v.begin() != 0)
ss << ",";
ss << (*iter);
}
}
private:
friend class cereal::access;
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionVector>(this)); }
};
class ConfigOptionBool : public ConfigOptionSingle<bool>
{
@ -2101,6 +2206,7 @@ public:
case coEnum: { auto opt = new ConfigOptionEnumGeneric(this->enum_keys_map); archive(*opt); return opt; }
// BBS
case coEnums: { auto opt = new ConfigOptionEnumsGeneric(this->enum_keys_map); archive(*opt); return opt; }
case coIntsGroups: { auto opt = new ConfigOptionIntsGroups(); archive(*opt); return opt; }
default: throw ConfigurationError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown option type for option ") + this->opt_key);
}
}
@ -2136,6 +2242,7 @@ public:
case coEnum: archive(*static_cast<const ConfigOptionEnumGeneric*>(opt)); break;
// BBS
case coEnums: archive(*static_cast<const ConfigOptionEnumsGeneric*>(opt)); break;
case coIntsGroups: archive(*static_cast<const ConfigOptionIntsGroups *>(opt)); break;
default: throw ConfigurationError(std::string("ConfigOptionDef::save_option_to_archive(): Unknown option type for option ") + this->opt_key);
}
}

View File

@ -298,6 +298,7 @@ static constexpr const char* OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR = "other_laye
static constexpr const char* SPIRAL_VASE_MODE = "spiral_mode";
static constexpr const char* FILAMENT_MAP_MODE_ATTR = "filament_map_mode";
static constexpr const char* FILAMENT_MAP_ATTR = "filament_maps";
static constexpr const char* UNPRINTABLE_FILAMENT_MAP_ATTR = "unprintable_filament_maps";
static constexpr const char* LIMIT_FILAMENT_MAP_ATTR = "limit_filament_maps";
static constexpr const char* GCODE_FILE_ATTR = "gcode_file";
static constexpr const char* THUMBNAIL_FILE_ATTR = "thumbnail_file";
@ -4089,6 +4090,24 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
return results;
};
auto get_vector_array_from_string = [get_vector_from_string](const std::string &str) -> std::vector<std::vector<int>> {
std::vector<std::string> sub_strs;
size_t pos = 0;
size_t found = 0;
while ((found = str.find('#', pos)) != std::string::npos) {
std::string sub_str = str.substr(pos, found - pos);
sub_strs.push_back(sub_str);
pos = found + 1;
}
std::vector<std::vector<int>> results;
for (std::string sub_str : sub_strs) {
results.emplace_back(get_vector_from_string(sub_str));
}
return results;
};
if ((m_curr_plater == nullptr)&&!m_parsing_slice_info)
{
IdToMetadataMap::iterator object = m_objects_metadata.find(m_curr_config.object_id);
@ -4153,6 +4172,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
m_curr_plater->config.set_key_value("filament_map", new ConfigOptionInts(get_vector_from_string(value)));
}
else if (key == UNPRINTABLE_FILAMENT_MAP_ATTR)
{
m_curr_plater->config.set_key_value("unprintable_filament_map", new ConfigOptionIntsGroups(get_vector_array_from_string(value)));
}
else if (key == GCODE_FILE_ATTR)
{
m_curr_plater->gcode_file = value;
@ -7571,6 +7594,23 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
stream << "\"/>\n";
}
ConfigOptionIntsGroups *unprintable_filament_maps_opt = plate_data->config.option<ConfigOptionIntsGroups>("unprintable_filament_map");
if (unprintable_filament_maps_opt != nullptr) {
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << UNPRINTABLE_FILAMENT_MAP_ATTR << "\" " << VALUE_ATTR << "=\"";
const std::vector<std::vector<int>> &values = unprintable_filament_maps_opt->values;
for (size_t i = 0; i < values.size(); ++i) {
if (i > 0)
stream << "#";
std::vector<int> index_values = values[i];
for (int j = 0; j < index_values.size(); ++j) {
if (j > 0)
stream << " ";
stream << index_values[j];
}
}
stream << "\"/>\n";
}
if (save_gcode)
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << xml_escape(plate_data->gcode_file) << "\"/>\n";
if (!plate_data->gcode_file.empty()) {

View File

@ -623,6 +623,19 @@ namespace std {
return seed;
}
};
template<>
struct hash<std::vector<int>>
{
size_t operator()(const std::vector<int> &vec)
{
size_t seed = 0;
for (const auto &element : vec) {
seed ^= std::hash<double>()(element) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
};
}
// start Boost

View File

@ -260,6 +260,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|| opt_key == "extruder_ams_count"
|| opt_key == "filament_map_mode"
|| opt_key == "filament_map"
|| opt_key == "unprintable_filament_map"
//|| opt_key == "wipe_tower_bridging"
|| opt_key == "wipe_tower_no_sparse_layers"
|| opt_key == "flush_volumes_matrix"
@ -2375,6 +2376,11 @@ void Print::update_filament_maps_to_config(std::vector<int> f_maps)
m_has_auto_filament_map_result = true;
}
const std::vector<std::vector<int>>& Print::get_unprintable_filament_ids() const
{
return m_config.unprintable_filament_map.values;
}
std::vector<int> Print::get_filament_maps() const
{
return m_config.filament_map.values;

View File

@ -832,8 +832,7 @@ public:
void set_extruder_filament_info(const std::vector<std::vector<DynamicPrintConfig>>& filament_info) { m_extruder_filament_info = filament_info; }
// 1 based ids
const std::vector<std::vector<int>>& get_unprintable_filament_ids() const { return m_unprintable_filament_ids; }
void set_unprintable_filament_ids(const std::vector<std::vector<int>> &filament_ids) { m_unprintable_filament_ids = filament_ids; }
const std::vector<std::vector<int>> &get_unprintable_filament_ids() const;
std::vector<Vec2d> get_printable_area();
std::vector<std::vector<Vec2d>> get_extruder_printable_area();

View File

@ -1611,6 +1611,12 @@ void PrintConfigDef::init_fff_params()
def->mode = comDevelop;
def->set_default_value(new ConfigOptionInts{1});
def = this->add("unprintable_filament_map", coIntsGroups);
def->label = L("Unprintable filament map to extruder");
def->tooltip = L("Unprintable filament map to extruder");
def->mode = comDevelop;
def->set_default_value(new ConfigOptionIntsGroups{});
def = this->add("filament_map_mode", coEnum);
def->label = L("filament mapping mode");
def->tooltip = ("filament mapping mode used as plate param");

View File

@ -982,6 +982,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionInts, required_nozzle_HRC))
((ConfigOptionEnum<FilamentMapMode>, filament_map_mode))
((ConfigOptionInts, filament_map))
((ConfigOptionIntsGroups, unprintable_filament_map))
//((ConfigOptionInts, filament_extruder_id))
((ConfigOptionStrings, filament_extruder_variant))
((ConfigOptionFloat, machine_load_filament_time))

View File

@ -1720,7 +1720,7 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
BuildVolume plate_build_volume(pp_bed_shape, build_volume.printable_height(), build_volume.extruder_areas());
const std::vector<BoundingBoxf3>& exclude_areas = curr_plate->get_exclude_areas();
curr_plate->clear_unprintable_filament_ids();
std::vector<std::set<int>> unprintable_filament_ids;
for (GLVolume* volume : this->volumes)
{
if (! volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (! volume->is_wipe_tower && volume->composite_id.volume_id >= 0))) {
@ -1738,13 +1738,14 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
std::vector<bool> inside_extruders;
state = plate_build_volume.check_volume_bbox_state_with_extruder_areas(bb, inside_extruders);
if (state == BuildVolume::ObjectState::Limited) {
unprintable_filament_ids.resize(inside_extruders.size());
const ModelObjectPtrs &model_objects = model.objects;
ModelObject *model_object = model_objects[volume->object_idx()];
ModelVolume *model_volume = model_object->volumes[volume->volume_idx()];
for (size_t i = 0; i < inside_extruders.size(); ++i) {
if (!inside_extruders[i]) {
std::vector<int> extruders = model_volume->get_extruders();
curr_plate->append_unprintable_filament_ids(i, extruders);
unprintable_filament_ids[i].insert(extruders.begin(), extruders.end());
}
}
}
@ -1822,6 +1823,13 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
}
}
std::vector<std::vector<int>> unprintable_filament_vec;
for (const std::set<int>& filamnt_ids : unprintable_filament_ids) {
unprintable_filament_vec.emplace_back(std::vector<int>(filamnt_ids.begin(), filamnt_ids.end()));
}
curr_plate->set_unprintable_filament_ids(unprintable_filament_vec);
/*for (GLVolume* volume : this->volumes)
{
if (! volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (! volume->is_wipe_tower && volume->composite_id.volume_id >= 0)))

View File

@ -2518,7 +2518,6 @@ void PartPlate::update_slice_context(BackgroundSlicingProcess & process)
process.select_technology(this->printer_technology);
process.set_current_plate(this);
m_print->set_status_callback(statuscb);
m_print->set_unprintable_filament_ids(m_unprintable_filament_ids);
process.switch_print_preprocess();
return;
@ -2878,21 +2877,24 @@ std::vector<int> PartPlate::get_filament_maps()
return filament_maps;
}
void PartPlate::append_unprintable_filament_ids(int extruder_id, const std::vector<int> &filament_ids)
{
if (extruder_id > m_unprintable_filament_ids.size()) {
m_unprintable_filament_ids.resize(extruder_id + 1);
}
m_unprintable_filament_ids[extruder_id].insert(m_unprintable_filament_ids[extruder_id].end(), filament_ids.begin(), filament_ids.end());
}
void PartPlate::set_filament_maps(const std::vector<int>& f_maps)
{
std::vector<int>& filament_maps = m_config.option<ConfigOptionInts>("filament_map", true)->values;
filament_maps = f_maps;
}
const std::vector<std::vector<int>>& PartPlate::get_unprintable_filament_ids()
{
std::vector<std::vector<int>> & unprintabel_filament_maps = m_config.option<ConfigOptionIntsGroups>("unprintable_filament_map", true)->values;
return unprintabel_filament_maps;
}
void PartPlate::set_unprintable_filament_ids(const std::vector<std::vector<int>> &filament_ids)
{
std::vector<std::vector<int>> &unprintabel_filament_maps = m_config.option<ConfigOptionIntsGroups>("unprintable_filament_map", true)->values;
unprintabel_filament_maps = filament_ids;
}
void PartPlate::on_extruder_count_changed(int extruder_count)
{
std::vector<int>& filament_maps = m_config.option<ConfigOptionInts>("filament_map", true)->values;

View File

@ -111,9 +111,6 @@ private:
std::vector<FilamentInfo> slice_filaments_info;
int m_print_index;
// filament ids of extruder
std::vector<std::vector<int>> m_unprintable_filament_ids;
std::string m_tmp_gcode_path; //use a temp path to store the gcode
std::string m_temp_config_3mf_path; //use a temp path to store the config 3mf
std::string m_gcode_path_from_3mf; //use a path to store the gcode loaded from 3mf
@ -493,10 +490,8 @@ public:
std::vector<int> get_filament_maps();
void set_filament_maps(const std::vector<int>& f_maps);
const std::vector<std::vector<int>> &get_unprintable_filament_ids() const { return m_unprintable_filament_ids; }
void set_unprintable_filament_ids(const std::vector<std::vector<int>> &filament_ids) { m_unprintable_filament_ids = filament_ids; }
void clear_unprintable_filament_ids() { m_unprintable_filament_ids.clear(); }
void append_unprintable_filament_ids(int extruder_id, const std::vector<int> &filament_ids);
const std::vector<std::vector<int>> &get_unprintable_filament_ids();
void set_unprintable_filament_ids(const std::vector<std::vector<int>> &filament_ids);
void on_extruder_count_changed(int extruder_count);
void set_filament_count(int filament_count);