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:
parent
4c644d4715
commit
92fa0ff010
|
@ -800,6 +800,50 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex
|
||||||
|
|
||||||
CNumericLocalesSetter locales_setter;
|
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 {
|
try {
|
||||||
boost::nowide::ifstream ifs(file);
|
boost::nowide::ifstream ifs(file);
|
||||||
ifs >> j;
|
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);
|
substitution_context.unrecogized_keys.push_back(opt_key_src);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool valid = true, first = true, use_comma = true;
|
bool valid = true, first = true;
|
||||||
//bool test2 = (it.key() == std::string("filament_end_gcode"));
|
|
||||||
const ConfigOptionDef* optdef = config_def->get(opt_key);
|
const ConfigOptionDef* optdef = config_def->get(opt_key);
|
||||||
if (optdef == nullptr) {
|
if (optdef == nullptr) {
|
||||||
// If we didn't find an option, look for any other option having this as an alias.
|
// 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) {
|
char single_sep = ',';
|
||||||
use_comma = false;
|
char array_sep = '#'; // currenty not used
|
||||||
}
|
bool escape_string_type = false;
|
||||||
for (auto iter = it.value().begin(); iter != it.value().end(); iter++) {
|
if (optdef) {
|
||||||
if (iter.value().is_string()) {
|
switch (optdef->type)
|
||||||
if (!first) {
|
{
|
||||||
if (use_comma)
|
case coStrings:
|
||||||
value_str += ",";
|
escape_string_type = true;
|
||||||
else
|
single_sep = ';';
|
||||||
value_str += ";";
|
break;
|
||||||
}
|
case coPointsGroups:
|
||||||
else
|
single_sep = '#';
|
||||||
first = false;
|
break;
|
||||||
|
default:
|
||||||
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;
|
|
||||||
break;
|
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)
|
if (valid)
|
||||||
this->set_deserialize(opt_key, value_str, substitution_context);
|
this->set_deserialize(opt_key, value_str, substitution_context);
|
||||||
}
|
}
|
||||||
|
@ -1409,7 +1447,7 @@ void ConfigBase::save_to_json(const std::string &file, const std::string &name,
|
||||||
j[opt_key] = opt->serialize();
|
j[opt_key] = opt->serialize();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const ConfigOptionVectorBase *vec = static_cast<const ConfigOptionVectorBase*>(opt);
|
const ConfigOptionVectorBase* vec = static_cast<const ConfigOptionVectorBase*>(opt);
|
||||||
//if (!vec->empty())
|
//if (!vec->empty())
|
||||||
std::vector<std::string> string_values = vec->vserialize();
|
std::vector<std::string> string_values = vec->vserialize();
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,7 @@ enum ConfigOptionType {
|
||||||
coEnum = 9,
|
coEnum = 9,
|
||||||
// BBS: vector of enums
|
// BBS: vector of enums
|
||||||
coEnums = coEnum + coVectorType,
|
coEnums = coEnum + coVectorType,
|
||||||
|
coPointsGroups = 10 + coVectorType
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ConfigOptionMode {
|
enum ConfigOptionMode {
|
||||||
|
@ -1547,6 +1548,106 @@ private:
|
||||||
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionSingle<Vec3d>>(this)); }
|
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>
|
class ConfigOptionBool : public ConfigOptionSingle<bool>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -610,6 +610,21 @@ inline Point align_to_grid(Point coord, Point spacing, Point base)
|
||||||
}
|
}
|
||||||
} // namespace Slic3r
|
} // 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
|
// start Boost
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
#include <boost/polygon/polygon.hpp>
|
#include <boost/polygon/polygon.hpp>
|
||||||
|
|
|
@ -523,7 +523,6 @@ bool Preset::save(DynamicPrintConfig* parent_config)
|
||||||
if (parent_config) {
|
if (parent_config) {
|
||||||
DynamicPrintConfig temp_config;
|
DynamicPrintConfig temp_config;
|
||||||
std::vector<std::string> dirty_options = config.diff(*parent_config);
|
std::vector<std::string> dirty_options = config.diff(*parent_config);
|
||||||
|
|
||||||
std::string extruder_id_name, extruder_variant_name;
|
std::string extruder_id_name, extruder_variant_name;
|
||||||
std::set<std::string> *key_set1 = nullptr, *key_set2 = nullptr;
|
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);
|
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 {
|
static std::vector<std::string> s_Preset_printer_options {
|
||||||
"printer_technology",
|
"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",
|
"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",
|
"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",
|
"printable_height", "extruder_clearance_radius", "extruder_clearance_max_radius","extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
|
||||||
|
|
|
@ -489,6 +489,12 @@ void PrintConfigDef::init_common_params()
|
||||||
def->gui_type = ConfigOptionDef::GUIType::one_string;
|
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->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"
|
//BBS: add "bed_exclude_area"
|
||||||
def = this->add("bed_exclude_area", coPoints);
|
def = this->add("bed_exclude_area", coPoints);
|
||||||
def->label = L("Bed exclude area");
|
def->label = L("Bed exclude area");
|
||||||
|
@ -5187,6 +5193,7 @@ std::set<std::string> printer_extruder_options = {
|
||||||
"extruder_type",
|
"extruder_type",
|
||||||
"nozzle_diameter",
|
"nozzle_diameter",
|
||||||
"default_nozzle_volume_type",
|
"default_nozzle_volume_type",
|
||||||
|
"extruder_printable_area",
|
||||||
"min_layer_height",
|
"min_layer_height",
|
||||||
"max_layer_height"
|
"max_layer_height"
|
||||||
};
|
};
|
||||||
|
|
|
@ -1054,6 +1054,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||||
((ConfigOptionBool, reduce_crossing_wall))
|
((ConfigOptionBool, reduce_crossing_wall))
|
||||||
((ConfigOptionFloatOrPercent, max_travel_detour_distance))
|
((ConfigOptionFloatOrPercent, max_travel_detour_distance))
|
||||||
((ConfigOptionPoints, printable_area))
|
((ConfigOptionPoints, printable_area))
|
||||||
|
((ConfigOptionPointsGroups, extruder_printable_area))
|
||||||
((ConfigOptionFloats, extruder_change_length))
|
((ConfigOptionFloats, extruder_change_length))
|
||||||
//BBS: add bed_exclude_area
|
//BBS: add bed_exclude_area
|
||||||
((ConfigOptionPoints, bed_exclude_area))
|
((ConfigOptionPoints, bed_exclude_area))
|
||||||
|
|
Loading…
Reference in New Issue