ENH: add ConfigOptionPointsGroups

1.Add extruder printable area

jira:NONE

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I753344917a67e3d8ac361c15c3d374b5ef951d21
This commit is contained in:
xun.zhang 2024-08-23 15:29:15 +08:00 committed by lane.wei
parent 4c644d4715
commit 92fa0ff010
6 changed files with 194 additions and 33 deletions

View File

@ -800,6 +800,50 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex
CNumericLocalesSetter locales_setter;
std::function<bool(const json::const_iterator&, const char,const char,const bool,std::string&)> parse_str_arr = [&parse_str_arr](const json::const_iterator& it, const char single_sep,const char array_sep,const bool escape_string_style,std::string& value_str)->bool {
// must have consistent type name
std::string consistent_type;
for (auto iter = it.value().begin(); iter != it.value().end(); ++iter) {
if (consistent_type.empty())
consistent_type = iter.value().type_name();
else {
if (consistent_type != iter.value().type_name())
return false;
}
}
bool first = true;
for (auto iter = it.value().begin(); iter != it.value().end(); iter++) {
if (iter.value().is_array()) {
if (!first)
value_str += array_sep;
else
first = false;
bool success = parse_str_arr(iter, single_sep, array_sep,escape_string_style, value_str);
if (!success)
return false;
}
else if (iter.value().is_string()) {
if (!first)
value_str += single_sep;
else
first = false;
if (!escape_string_style)
value_str += iter.value();
else {
value_str += "\"";
value_str += escape_string_cstyle(iter.value());
value_str += "\"";
}
}
else {
//should not happen
return false;
}
}
return true;
};
try {
boost::nowide::ifstream ifs(file);
ifs >> j;
@ -882,8 +926,7 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex
substitution_context.unrecogized_keys.push_back(opt_key_src);
continue;
}
bool valid = true, first = true, use_comma = true;
//bool test2 = (it.key() == std::string("filament_end_gcode"));
bool valid = true, first = true;
const ConfigOptionDef* optdef = config_def->get(opt_key);
if (optdef == nullptr) {
// If we didn't find an option, look for any other option having this as an alias.
@ -900,35 +943,30 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex
}
}
if (optdef && optdef->type == coStrings) {
use_comma = false;
}
for (auto iter = it.value().begin(); iter != it.value().end(); iter++) {
if (iter.value().is_string()) {
if (!first) {
if (use_comma)
value_str += ",";
else
value_str += ";";
}
else
first = false;
if (use_comma)
value_str += iter.value();
else {
value_str += "\"";
value_str += escape_string_cstyle(iter.value());
value_str += "\"";
}
}
else {
//should not happen
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<<file<<" error, invalid json array for " << it.key();
valid = false;
char single_sep = ',';
char array_sep = '#'; // currenty not used
bool escape_string_type = false;
if (optdef) {
switch (optdef->type)
{
case coStrings:
escape_string_type = true;
single_sep = ';';
break;
case coPointsGroups:
single_sep = '#';
break;
default:
break;
}
}
// BBS: we only support 2 depth array
valid = parse_str_arr(it, single_sep, array_sep,escape_string_type, value_str);
if (!valid) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << file << " error, invalid json array for " << it.key();
break;
}
if (valid)
this->set_deserialize(opt_key, value_str, substitution_context);
}
@ -1409,14 +1447,14 @@ void ConfigBase::save_to_json(const std::string &file, const std::string &name,
j[opt_key] = opt->serialize();
}
else {
const ConfigOptionVectorBase *vec = static_cast<const ConfigOptionVectorBase*>(opt);
const ConfigOptionVectorBase* vec = static_cast<const ConfigOptionVectorBase*>(opt);
//if (!vec->empty())
std::vector<std::string> string_values = vec->vserialize();
/*for (int i = 0; i < string_values.size(); i++)
{
std::string string_value = escape_string_cstyle(string_values[i]);
j[opt_key][i] = string_value;
std::string string_value = escape_string_cstyle(string_values[i]);
j[opt_key][i] = string_value;
}*/
json j_array(string_values);

View File

@ -196,6 +196,7 @@ enum ConfigOptionType {
coEnum = 9,
// BBS: vector of enums
coEnums = coEnum + coVectorType,
coPointsGroups = 10 + coVectorType
};
enum ConfigOptionMode {
@ -1547,6 +1548,106 @@ private:
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionSingle<Vec3d>>(this)); }
};
class ConfigOptionPointsGroups :public ConfigOptionVector<Vec2ds>
{
public:
ConfigOptionPointsGroups() :ConfigOptionVector<Vec2ds>() {}
explicit ConfigOptionPointsGroups(std::initializer_list<Vec2ds> il) :ConfigOptionVector<Vec2ds>(std::move(il)) {}
explicit ConfigOptionPointsGroups(const std::vector<Vec2ds>& values) :ConfigOptionVector<Vec2ds>(values) {}
static ConfigOptionType static_type() { return coPointsGroups; }
ConfigOptionType type()const override { return static_type(); }
ConfigOption* clone()const override { return new ConfigOptionPointsGroups(*this); }
ConfigOptionPointsGroups& operator=(const ConfigOption* opt) { this->set(opt); return *this; }
bool operator == (const ConfigOptionPointsGroups& rhs)const throw() { return this->values == rhs.values; }
bool operator == (const ConfigOption& rhs) const override {
if (rhs.type() != this->type())
throw ConfigurationError("ConfigOptionPointsGroupsTempl: Comparing incompatible types");
assert(dynamic_cast<const ConfigOptionVector<Vec2ds>*>(&rhs));
return this->values == static_cast<const ConfigOptionVector<Vec2ds>*>(&rhs)->values;
}
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& points : this->values) {
std::ostringstream ss;
serialize_single_value(ss, points);
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, '#')) {
Vec2ds group;
std::istringstream iss(group_str);
std::string point_str;
while (std::getline(iss, point_str, ',')) {
Vec2d point(Vec2d::Zero());
std::istringstream iss(point_str);
std::string coord_str;
if (std::getline(iss, coord_str, 'x')) {
std::istringstream(coord_str) >> point(0);
if (std::getline(iss, coord_str, 'x')) {
std::istringstream(coord_str) >> point(1);
}
}
group.push_back(point);
}
this->values.emplace_back(std::move(group));
}
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)(0);
ss << "x";
ss << (*iter)(1);
ret.emplace_back(ss.str());
}
return ret;
}
protected:
void serialize_single_value(std::ostringstream& ss, const Vec2ds& v) const {
for (auto iter = v.begin(); iter != v.end(); ++iter) {
if (iter - v.begin() != 0)
ss << ",";
ss << (*iter)(0);
ss << "x";
ss << (*iter)(1);
}
}
private:
friend class cereal::access;
template<class Archive> void serialize(Archive& ar) { ar(cereal::base_class<ConfigOptionVector>(this)); }
};
class ConfigOptionBool : public ConfigOptionSingle<bool>
{
public:

View File

@ -610,6 +610,21 @@ inline Point align_to_grid(Point coord, Point spacing, Point base)
}
} // namespace Slic3r
// requseted by ConfigOptionPointsGroups
namespace std {
template<>
struct hash<Slic3r::Vec2ds> {
size_t operator()(const Slic3r::Vec2ds& vec) {
size_t seed = 0;
for (const auto& element : vec) {
seed ^= std::hash<double>()(element[0]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= std::hash<double>()(element[1]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
};
}
// start Boost
#include <boost/version.hpp>
#include <boost/polygon/polygon.hpp>

View File

@ -523,7 +523,6 @@ bool Preset::save(DynamicPrintConfig* parent_config)
if (parent_config) {
DynamicPrintConfig temp_config;
std::vector<std::string> dirty_options = config.diff(*parent_config);
std::string extruder_id_name, extruder_variant_name;
std::set<std::string> *key_set1 = nullptr, *key_set2 = nullptr;
Preset::get_extruder_names_and_keysets(type, extruder_id_name, extruder_variant_name, &key_set1, &key_set2);
@ -942,7 +941,7 @@ static std::vector<std::string> s_Preset_machine_limits_options {
static std::vector<std::string> s_Preset_printer_options {
"printer_technology",
"printable_area", "bed_exclude_area","bed_custom_texture", "bed_custom_model", "gcode_flavor",
"printable_area", "extruder_printable_area", "bed_exclude_area","bed_custom_texture", "bed_custom_model", "gcode_flavor",
"single_extruder_multi_material", "machine_start_gcode", "machine_end_gcode","printing_by_object_gcode","before_layer_change_gcode", "layer_change_gcode", "time_lapse_gcode", "change_filament_gcode",
"printer_model", "printer_variant", "printer_extruder_id", "printer_extruder_variant", "extruder_variant_list", "default_nozzle_volume_type",
"printable_height", "extruder_clearance_radius", "extruder_clearance_max_radius","extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",

View File

@ -489,6 +489,12 @@ void PrintConfigDef::init_common_params()
def->gui_type = ConfigOptionDef::GUIType::one_string;
def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) });
def = this->add("extruder_printable_area", coPointsGroups);
def->label = L("Extruder printable area");
def->mode = comAdvanced;
def->gui_type = ConfigOptionDef::GUIType::one_string;
def->set_default_value(new ConfigOptionPointsGroups{ { Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) } });
//BBS: add "bed_exclude_area"
def = this->add("bed_exclude_area", coPoints);
def->label = L("Bed exclude area");
@ -5187,6 +5193,7 @@ std::set<std::string> printer_extruder_options = {
"extruder_type",
"nozzle_diameter",
"default_nozzle_volume_type",
"extruder_printable_area",
"min_layer_height",
"max_layer_height"
};

View File

@ -1054,6 +1054,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionBool, reduce_crossing_wall))
((ConfigOptionFloatOrPercent, max_travel_detour_distance))
((ConfigOptionPoints, printable_area))
((ConfigOptionPointsGroups, extruder_printable_area))
((ConfigOptionFloats, extruder_change_length))
//BBS: add bed_exclude_area
((ConfigOptionPoints, bed_exclude_area))