Merge branch 'master' of https://github.com/prusa3d/Slic3r into svg_icons

This commit is contained in:
Enrico Turri 2019-02-25 09:32:02 +01:00
commit fab87ff1d9
42 changed files with 314 additions and 203 deletions

View file

@ -1,4 +1,5 @@
min_slic3r_version = 1.42.0-alpha6
0.8.0-alpha7
0.8.0-alpha6
min_slic3r_version = 1.42.0-alpha
0.8.0-alpha

View file

@ -5,7 +5,7 @@
name = Prusa Research
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the Slic3r configuration to be downgraded.
config_version = 0.8.0-alpha
config_version = 0.8.0-alpha7
# Where to get the updates from?
config_update_url = https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch/
@ -1560,27 +1560,19 @@ inherits = *common 0.05*
exposure_time = 6.5
initial_exposure_time = 40
########### Materials 0.035
[sla_material:Jamg He Orange 0.035]
[sla_material:Jamg He PJHC-30 Orange 0.035]
inherits = *common 0.035*
exposure_time = 9
initial_exposure_time = 35
########### Materials 0.1
## [sla_material:Jamg He Transparent Clear 0.1]
## inherits = *common 0.1*
## [sla_material:Jamg He Transparent Green 0.1]
## inherits = *common 0.1*
## [sla_material:Jamg He Transparent Orange 0.1]
## inherits = *common 0.1*
## [sla_material:Jamg He Transparent Red 0.1]
## inherits = *common 0.1*
[sla_material:Jamg He PJHC-30 Orange 0.1]
inherits = *common 0.1*
exposure_time = 10
initial_exposure_time = 45
[printer:*common*]
printer_technology = FFF

View file

@ -169,22 +169,22 @@
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "avrdude"
#define PACKAGE "avrdude-slic3r"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "avrdude-dev@nongnu.org"
#define PACKAGE_BUGREPORT "https://github.com/prusa3d/Slic3r/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "avrdude"
#define PACKAGE_NAME "avrdude-slic3r"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "avrdude 6.3-20160220"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "avrdude"
#define PACKAGE_TARNAME "avrdude-slic3r"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
#define PACKAGE_URL "https://github.com/prusa3d/Slic3r"
/* Define to the version of this package. */
#define PACKAGE_VERSION "6.3-20160220"

View file

@ -96,13 +96,20 @@ void AvrDude::priv::unset_handlers()
int AvrDude::priv::run_one(const std::vector<std::string> &args) {
std::vector<char*> c_args {{ const_cast<char*>(PACKAGE_NAME) }};
std::vector<char*> c_args {{ const_cast<char*>(PACKAGE) }};
std::string command_line { PACKAGE };
for (const auto &arg : args) {
c_args.push_back(const_cast<char*>(arg.data()));
command_line.push_back(' ');
command_line.append(arg);
}
command_line.push_back('\n');
HandlerGuard guard(*this);
message_fn(command_line.c_str(), command_line.size());
const auto res = ::avrdude_main(static_cast<int>(c_args.size()), c_args.data(), sys_config.c_str());
return res;

View file

@ -1082,6 +1082,7 @@ int avrdude_main(int argc, char * argv [], const char *sys_config)
if (rc < 0) {
exitrc = 1;
pgm->ppidata = 0; /* clear all bits at exit */
avrdude_message(MSG_INFO, "%s: Could not open port: %s\n", progname, port);
goto main_exit;
}
is_open = 1;

View file

@ -69,7 +69,9 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
if (surface.is_solid() && (!surface.is_bridge() || layerm.layer()->id() == 0)) {
group_attrib[i].is_solid = true;
group_attrib[i].flow_width = (surface.surface_type == stTop) ? top_solid_infill_flow.width : solid_infill_flow.width;
group_attrib[i].pattern = surface.is_external() ? layerm.region()->config().external_fill_pattern.value : ipRectilinear;
group_attrib[i].pattern = surface.is_external() ?
(surface.is_top() ? layerm.region()->config().top_fill_pattern.value : layerm.region()->config().bottom_fill_pattern.value) :
ipRectilinear;
}
}
// Loop through solid groups, find compatible groups and append them to this one.
@ -161,7 +163,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
if (surface.is_solid()) {
density = 100.;
fill_pattern = (surface.is_external() && ! is_bridge) ?
layerm.region()->config().external_fill_pattern.value :
(surface.is_top() ? layerm.region()->config().top_fill_pattern.value : layerm.region()->config().bottom_fill_pattern.value) :
ipRectilinear;
} else if (density <= 0)
continue;

View file

@ -1506,7 +1506,7 @@ namespace Slic3r {
if (metadata.key == NAME_KEY)
volume->name = metadata.value;
else if ((metadata.key == MODIFIER_KEY) && (metadata.value == "1"))
volume->set_type(ModelVolume::PARAMETER_MODIFIER);
volume->set_type(ModelVolumeType::PARAMETER_MODIFIER);
else if (metadata.key == VOLUME_TYPE_KEY)
volume->set_type(ModelVolume::type_from_string(metadata.value));
else

View file

@ -604,7 +604,7 @@ void AMFParserContext::endElement(const char * /* name */)
if (strcmp(opt_key, "modifier") == 0) {
// Is this volume a modifier volume?
// "modifier" flag comes first in the XML file, so it may be later overwritten by the "type" flag.
m_volume->set_type((atoi(m_value[1].c_str()) == 1) ? ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART);
m_volume->set_type((atoi(m_value[1].c_str()) == 1) ? ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART);
} else if (strcmp(opt_key, "volume_type") == 0) {
m_volume->set_type(ModelVolume::type_from_string(m_value[1]));
}

View file

@ -1480,32 +1480,32 @@ const TriangleMesh& ModelVolume::get_convex_hull() const
return m_convex_hull;
}
ModelVolume::Type ModelVolume::type_from_string(const std::string &s)
ModelVolumeType ModelVolume::type_from_string(const std::string &s)
{
// Legacy support
if (s == "1")
return PARAMETER_MODIFIER;
return ModelVolumeType::PARAMETER_MODIFIER;
// New type (supporting the support enforcers & blockers)
if (s == "ModelPart")
return MODEL_PART;
return ModelVolumeType::MODEL_PART;
if (s == "ParameterModifier")
return PARAMETER_MODIFIER;
return ModelVolumeType::PARAMETER_MODIFIER;
if (s == "SupportEnforcer")
return SUPPORT_ENFORCER;
return ModelVolumeType::SUPPORT_ENFORCER;
if (s == "SupportBlocker")
return SUPPORT_BLOCKER;
return ModelVolumeType::SUPPORT_BLOCKER;
assert(s == "0");
// Default value if invalud type string received.
return MODEL_PART;
return ModelVolumeType::MODEL_PART;
}
std::string ModelVolume::type_to_string(const Type t)
std::string ModelVolume::type_to_string(const ModelVolumeType t)
{
switch (t) {
case MODEL_PART: return "ModelPart";
case PARAMETER_MODIFIER: return "ParameterModifier";
case SUPPORT_ENFORCER: return "SupportEnforcer";
case SUPPORT_BLOCKER: return "SupportBlocker";
case ModelVolumeType::MODEL_PART: return "ModelPart";
case ModelVolumeType::PARAMETER_MODIFIER: return "ParameterModifier";
case ModelVolumeType::SUPPORT_ENFORCER: return "SupportEnforcer";
case ModelVolumeType::SUPPORT_BLOCKER: return "SupportBlocker";
default:
assert(false);
return "ModelPart";
@ -1671,7 +1671,7 @@ bool model_object_list_extended(const Model &model_old, const Model &model_new)
return true;
}
bool model_volume_list_changed(const ModelObject &model_object_old, const ModelObject &model_object_new, const ModelVolume::Type type)
bool model_volume_list_changed(const ModelObject &model_object_old, const ModelObject &model_object_new, const ModelVolumeType type)
{
bool modifiers_differ = false;
size_t i_old, i_new;

View file

@ -295,6 +295,15 @@ private:
mutable bool m_raw_mesh_bounding_box_valid;
};
// Declared outside of ModelVolume, so it could be forward declared.
enum class ModelVolumeType : int {
INVALID = -1,
MODEL_PART = 0,
PARAMETER_MODIFIER,
SUPPORT_ENFORCER,
SUPPORT_BLOCKER,
};
// An object STL, or a modifier volume, over which a different set of parameters shall be applied.
// ModelVolume instances are owned by a ModelObject.
class ModelVolume : public ModelBase
@ -307,23 +316,15 @@ public:
// overriding the global Slic3r settings and the ModelObject settings.
DynamicPrintConfig config;
enum Type {
MODEL_TYPE_INVALID = -1,
MODEL_PART = 0,
PARAMETER_MODIFIER,
SUPPORT_ENFORCER,
SUPPORT_BLOCKER,
};
// A parent object owning this modifier volume.
ModelObject* get_object() const { return this->object; };
Type type() const { return m_type; }
void set_type(const Type t) { m_type = t; }
bool is_model_part() const { return m_type == MODEL_PART; }
bool is_modifier() const { return m_type == PARAMETER_MODIFIER; }
bool is_support_enforcer() const { return m_type == SUPPORT_ENFORCER; }
bool is_support_blocker() const { return m_type == SUPPORT_BLOCKER; }
bool is_support_modifier() const { return m_type == SUPPORT_BLOCKER || m_type == SUPPORT_ENFORCER; }
ModelVolumeType type() const { return m_type; }
void set_type(const ModelVolumeType t) { m_type = t; }
bool is_model_part() const { return m_type == ModelVolumeType::MODEL_PART; }
bool is_modifier() const { return m_type == ModelVolumeType::PARAMETER_MODIFIER; }
bool is_support_enforcer() const { return m_type == ModelVolumeType::SUPPORT_ENFORCER; }
bool is_support_blocker() const { return m_type == ModelVolumeType::SUPPORT_BLOCKER; }
bool is_support_modifier() const { return m_type == ModelVolumeType::SUPPORT_BLOCKER || m_type == ModelVolumeType::SUPPORT_ENFORCER; }
t_model_material_id material_id() const { return m_material_id; }
void set_material_id(t_model_material_id material_id);
ModelMaterial* material() const;
@ -357,8 +358,8 @@ public:
const TriangleMesh& get_convex_hull() const;
// Helpers for loading / storing into AMF / 3MF files.
static Type type_from_string(const std::string &s);
static std::string type_to_string(const Type t);
static ModelVolumeType type_from_string(const std::string &s);
static std::string type_to_string(const ModelVolumeType t);
const Geometry::Transformation& get_transformation() const { return m_transformation; }
void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; }
@ -403,7 +404,7 @@ private:
// Parent object owning this ModelVolume.
ModelObject* object;
// Is it an object to be printed, or a modifier volume?
Type m_type;
ModelVolumeType m_type;
t_model_material_id m_material_id;
// The convex hull of this model's mesh.
TriangleMesh m_convex_hull;
@ -415,13 +416,13 @@ private:
// 1 -> is splittable
int m_is_splittable {-1};
ModelVolume(ModelObject *object, const TriangleMesh &mesh) : mesh(mesh), m_type(MODEL_PART), object(object)
ModelVolume(ModelObject *object, const TriangleMesh &mesh) : mesh(mesh), m_type(ModelVolumeType::MODEL_PART), object(object)
{
if (mesh.stl.stats.number_of_facets > 1)
calculate_convex_hull();
}
ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull) :
mesh(std::move(mesh)), m_convex_hull(std::move(convex_hull)), m_type(MODEL_PART), object(object) {}
mesh(std::move(mesh)), m_convex_hull(std::move(convex_hull)), m_type(ModelVolumeType::MODEL_PART), object(object) {}
// Copying an existing volume, therefore this volume will get a copy of the ID assigned.
ModelVolume(ModelObject *object, const ModelVolume &other) :
@ -633,7 +634,7 @@ extern bool model_object_list_extended(const Model &model_old, const Model &mode
// Test whether the new ModelObject contains a different set of volumes (or sorted in a different order)
// than the old ModelObject.
extern bool model_volume_list_changed(const ModelObject &model_object_old, const ModelObject &model_object_new, const ModelVolume::Type type);
extern bool model_volume_list_changed(const ModelObject &model_object_old, const ModelObject &model_object_new, const ModelVolumeType type);
#ifndef NDEBUG
// Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.

View file

@ -571,7 +571,7 @@ void Print::model_volume_list_update_supports(ModelObject &model_object_dst, con
delete mv_with_status.first;
}
static inline void model_volume_list_copy_configs(ModelObject &model_object_dst, const ModelObject &model_object_src, const ModelVolume::Type type)
static inline void model_volume_list_copy_configs(ModelObject &model_object_dst, const ModelObject &model_object_src, const ModelVolumeType type)
{
size_t i_src, i_dst;
for (i_src = 0, i_dst = 0; i_src < model_object_src.volumes.size() && i_dst < model_object_dst.volumes.size();) {
@ -841,10 +841,10 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
assert(it_status->status == ModelObjectStatus::Old || it_status->status == ModelObjectStatus::Moved);
const ModelObject &model_object_new = *model.objects[idx_model_object];
// Check whether a model part volume was added or removed, their transformations or order changed.
bool model_parts_differ = model_volume_list_changed(model_object, model_object_new, ModelVolume::MODEL_PART);
bool modifiers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolume::PARAMETER_MODIFIER);
bool support_blockers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolume::SUPPORT_BLOCKER);
bool support_enforcers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolume::SUPPORT_ENFORCER);
bool model_parts_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::MODEL_PART);
bool modifiers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::PARAMETER_MODIFIER);
bool support_blockers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::SUPPORT_BLOCKER);
bool support_enforcers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::SUPPORT_ENFORCER);
if (model_parts_differ || modifiers_differ ||
model_object.origin_translation != model_object_new.origin_translation ||
model_object.layer_height_ranges != model_object_new.layer_height_ranges ||
@ -886,8 +886,8 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
}
// Synchronize (just copy) the remaining data of ModelVolumes (name, config).
//FIXME What to do with m_material_id?
model_volume_list_copy_configs(model_object /* dst */, model_object_new /* src */, ModelVolume::MODEL_PART);
model_volume_list_copy_configs(model_object /* dst */, model_object_new /* src */, ModelVolume::PARAMETER_MODIFIER);
model_volume_list_copy_configs(model_object /* dst */, model_object_new /* src */, ModelVolumeType::MODEL_PART);
model_volume_list_copy_configs(model_object /* dst */, model_object_new /* src */, ModelVolumeType::PARAMETER_MODIFIER);
// Copy the ModelObject name, input_file and instances. The instances will compared against PrintObject instances in the next step.
model_object.name = model_object_new.name;
model_object.input_file = model_object_new.input_file;

View file

@ -362,12 +362,11 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->default_value = new ConfigOptionBool(false);
def = this->add("external_fill_pattern", coEnum);
def->label = L("Top/bottom fill pattern");
auto def_top_fill_pattern = def = this->add("top_fill_pattern", coEnum);
def->label = L("Top fill pattern");
def->category = L("Infill");
def->tooltip = L("Fill pattern for top/bottom infill. This only affects the external visible layer, "
"and not its adjacent solid shells.");
def->cli = "external-fill-pattern|solid-fill-pattern=s";
def->tooltip = L("Fill pattern for top infill. This only affects the top visible layer, and not its adjacent solid shells.");
def->cli = "top-fill-pattern|external-fill-pattern|solid-fill-pattern=s";
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
def->enum_values.push_back("rectilinear");
def->enum_values.push_back("concentric");
@ -379,8 +378,15 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back(L("Hilbert Curve"));
def->enum_labels.push_back(L("Archimedean Chords"));
def->enum_labels.push_back(L("Octagram Spiral"));
// solid_fill_pattern is an obsolete equivalent to external_fill_pattern.
def->aliases = { "solid_fill_pattern" };
// solid_fill_pattern is an obsolete equivalent to top_fill_pattern/bottom_fill_pattern.
def->aliases = { "solid_fill_pattern", "external_fill_pattern" };
def->default_value = new ConfigOptionEnum<InfillPattern>(ipRectilinear);
def = this->add("bottom_fill_pattern", coEnum);
*def = *def_top_fill_pattern;
def->label = L("Bottom Pattern");
def->tooltip = L("Fill pattern for bottom infill. This only affects the bottom external visible layer, and not its adjacent solid shells.");
def->cli = "bottom-fill-pattern|external-fill-pattern|solid-fill-pattern=s";
def->default_value = new ConfigOptionEnum<InfillPattern>(ipRectilinear);
def = this->add("external_perimeter_extrusion_width", coFloatOrPercent);
@ -2939,13 +2945,17 @@ std::string FullPrintConfig::validate()
if (! print_config_def.get("fill_pattern")->has_enum_value(this->fill_pattern.serialize()))
return "Invalid value for --fill-pattern";
// --external-fill-pattern
if (! print_config_def.get("external_fill_pattern")->has_enum_value(this->external_fill_pattern.serialize()))
return "Invalid value for --external-fill-pattern";
// --top-fill-pattern
if (! print_config_def.get("top_fill_pattern")->has_enum_value(this->top_fill_pattern.serialize()))
return "Invalid value for --top-fill-pattern";
// --bottom-fill-pattern
if (! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->bottom_fill_pattern.serialize()))
return "Invalid value for --bottom-fill-pattern";
// --fill-density
if (fabs(this->fill_density.value - 100.) < EPSILON &&
! print_config_def.get("external_fill_pattern")->has_enum_value(this->fill_pattern.serialize()))
! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize()))
return "The selected fill pattern is not supposed to work at 100% density";
// --infill-every-layers

View file

@ -462,7 +462,8 @@ public:
ConfigOptionFloat bridge_flow_ratio;
ConfigOptionFloat bridge_speed;
ConfigOptionBool ensure_vertical_shell_thickness;
ConfigOptionEnum<InfillPattern> external_fill_pattern;
ConfigOptionEnum<InfillPattern> top_fill_pattern;
ConfigOptionEnum<InfillPattern> bottom_fill_pattern;
ConfigOptionFloatOrPercent external_perimeter_extrusion_width;
ConfigOptionFloatOrPercent external_perimeter_speed;
ConfigOptionBool external_perimeters_first;
@ -504,7 +505,8 @@ protected:
OPT_PTR(bridge_flow_ratio);
OPT_PTR(bridge_speed);
OPT_PTR(ensure_vertical_shell_thickness);
OPT_PTR(external_fill_pattern);
OPT_PTR(top_fill_pattern);
OPT_PTR(bottom_fill_pattern);
OPT_PTR(external_perimeter_extrusion_width);
OPT_PTR(external_perimeter_speed);
OPT_PTR(external_perimeters_first);

View file

@ -155,14 +155,8 @@ template<> class FilePrinter<FilePrinterFormat::SLA_PNGZIP>
"jobDir = ") + projectname + "\n" +
"expTime = " + expt_str + "\n"
"expTimeFirst = " + expt_first_str + "\n"
// "stepNum = " + stepnum_str + "\n"
// "wifiOn = 1\n"
// "tiltSlow = 60\n"
// "tiltFast = 15\n"
"numFade = " + cnt_fade_layers + "\n"
// "startdelay = 0\n"
"layerHeight = " + layerh_str + "\n"
"noteInfo = "
"expTime = "+expt_str+" + resinType = generic+layerHeight = "
+layerh_str+" + printer = DWARF3\n"
"usedMaterial = " + used_material + "\n"

View file

@ -498,7 +498,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|| opt_key == "bridge_angle") {
steps.emplace_back(posPrepareInfill);
} else if (
opt_key == "external_fill_pattern"
opt_key == "top_fill_pattern"
|| opt_key == "bottom_fill_pattern"
|| opt_key == "external_fill_link_max_length"
|| opt_key == "fill_angle"
|| opt_key == "fill_pattern"

View file

@ -310,7 +310,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
if (it_print_object_status != print_object_status.end() && it_print_object_status->id != model_object.id())
it_print_object_status = print_object_status.end();
// Check whether a model part volume was added or removed, their transformations or order changed.
bool model_parts_differ = model_volume_list_changed(model_object, model_object_new, ModelVolume::MODEL_PART);
bool model_parts_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::MODEL_PART);
bool sla_trafo_differs = model_object.instances.empty() != model_object_new.instances.empty() ||
(! model_object.instances.empty() && ! sla_trafo(model_object).isApprox(sla_trafo(model_object_new)));
if (model_parts_differ || sla_trafo_differs) {
@ -975,7 +975,7 @@ void SLAPrint::process()
this->fill_statistics();
// Set statistics values to the printer
m_printer->set_statistics({(m_print_statistics.objects_used_material + m_print_statistics.support_used_material)/1000,
10.0,
double(m_default_object_config.faded_layers.getInt()),
double(m_print_statistics.slow_layers_count),
double(m_print_statistics.fast_layers_count)
});
@ -1318,7 +1318,8 @@ bool SLAPrintObject::invalidate_state_by_config_options(const std::vector<t_conf
std::vector<SLAPrintObjectStep> steps;
bool invalidated = false;
for (const t_config_option_key &opt_key : opt_keys) {
if (opt_key == "layer_height") {
if ( opt_key == "layer_height"
|| opt_key == "faded_layers") {
steps.emplace_back(slaposObjectSlice);
} else if (
opt_key == "supports_enable"

View file

@ -42,6 +42,12 @@ Surface::is_internal() const
|| this->surface_type == stInternalVoid;
}
bool
Surface::is_top() const
{
return this->surface_type == stTop;
}
bool
Surface::is_bottom() const
{

View file

@ -98,6 +98,7 @@ public:
bool is_solid() const;
bool is_external() const;
bool is_internal() const;
bool is_top() const;
bool is_bottom() const;
bool is_bridge() const;
};

View file

@ -638,7 +638,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
}
case coEnum: {
int val = boost::any_cast<int>(value);
if (m_opt_id.compare("external_fill_pattern") == 0)
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern")
{
if (!m_opt.enum_values.empty()) {
std::string key;
@ -707,7 +707,7 @@ boost::any& Choice::get_value()
if (m_opt.type == coEnum)
{
int ret_enum = static_cast<wxComboBox*>(window)->GetSelection();
if (m_opt_id.compare("external_fill_pattern") == 0)
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern")
{
if (!m_opt.enum_values.empty()) {
std::string key = m_opt.enum_values[ret_enum];

View file

@ -446,7 +446,7 @@ void FirmwareDialog::priv::prepare_common()
"-U", (boost::format("flash:w:0:%1%:i") % hex_file.path.string()).str(),
}};
BOOST_LOG_TRIVIAL(info) << "Invoking avrdude, arguments: "
BOOST_LOG_TRIVIAL(info) << "Preparing arguments avrdude: "
<< std::accumulate(std::next(args.begin()), args.end(), args[0], [](std::string a, const std::string &b) {
return a + ' ' + b;
});
@ -492,7 +492,7 @@ void FirmwareDialog::priv::prepare_mk3()
"-U", (boost::format("flash:w:1:%1%:i") % hex_file.path.string()).str(),
}};
BOOST_LOG_TRIVIAL(info) << "Invoking avrdude for external flash flashing, arguments: "
BOOST_LOG_TRIVIAL(info) << "Preparing avrdude arguments for external flash flashing: "
<< std::accumulate(std::next(args.begin()), args.end(), args[0], [](std::string a, const std::string &b) {
return a + ' ' + b;
});
@ -522,7 +522,7 @@ void FirmwareDialog::priv::prepare_mm_control()
"-U", (boost::format("flash:w:0:%1%:i") % hex_file.path.string()).str(),
}};
BOOST_LOG_TRIVIAL(info) << "Invoking avrdude, arguments: "
BOOST_LOG_TRIVIAL(info) << "Preparing avrdude arguments: "
<< std::accumulate(std::next(args.begin()), args.end(), args[0], [](std::string a, const std::string &b) {
return a + ' ' + b;
});
@ -588,6 +588,13 @@ void FirmwareDialog::priv::perform_upload()
auto evt = new wxCommandEvent(EVT_AVRDUDE, q->GetId());
auto wxmsg = wxString::FromUTF8(msg);
#ifdef WIN32
// The string might be in local encoding
if (wxmsg.IsEmpty() && *msg != '\0') {
wxmsg = wxString(msg);
}
#endif
evt->SetExtraLong(AE_MESSAGE);
evt->SetString(std::move(wxmsg));
wxQueueEvent(q, evt);

View file

@ -4777,15 +4777,22 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
evt.SetY(evt.GetY() * scale);
#endif
Point pos(evt.GetX(), evt.GetY());
#if ENABLE_IMGUI
auto imgui = wxGetApp().imgui();
ImGuiWrapper *imgui = wxGetApp().imgui();
if (imgui->update_mouse_data(evt)) {
m_mouse.position = evt.Leaving() ? Vec2d(-1.0, -1.0) : pos.cast<double>();
render();
return;
}
#endif // ENABLE_IMGUI
Point pos(evt.GetX(), evt.GetY());
if (! evt.Entering() && ! evt.Leaving() && m_mouse.position.x() == -1.0) {
// Workaround for SPE-832: There seems to be a mouse event sent to the window before evt.Entering()
m_mouse.position = pos.cast<double>();
render();
}
if (m_picking_enabled)
_set_current();

View file

@ -1470,7 +1470,7 @@ void GLGizmoFlatten::update_planes()
TriangleMesh ch;
for (const ModelVolume* vol : m_model_object->volumes)
{
if (vol->type() != ModelVolume::Type::MODEL_PART)
if (vol->type() != ModelVolumeType::MODEL_PART)
continue;
TriangleMesh vol_ch = vol->get_convex_hull();
vol_ch.transform(vol->get_matrix());

View file

@ -401,7 +401,7 @@ private:
// This holds information to decide whether recalculation is necessary:
std::vector<Transform3d> m_volumes_matrices;
std::vector<ModelVolume::Type> m_volumes_types;
std::vector<ModelVolumeType> m_volumes_types;
Vec3d m_first_instance_scale;
Vec3d m_first_instance_mirror;

View file

@ -211,8 +211,9 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
}
break;
case coEnum:{
if (opt_key.compare("external_fill_pattern") == 0 ||
opt_key.compare("fill_pattern") == 0)
if (opt_key == "top_fill_pattern" ||
opt_key == "bottom_fill_pattern" ||
opt_key == "fill_pattern")
config.set_key_value(opt_key, new ConfigOptionEnum<InfillPattern>(boost::any_cast<InfillPattern>(value)));
else if (opt_key.compare("gcode_flavor") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<GCodeFlavor>(boost::any_cast<GCodeFlavor>(value)));

View file

@ -161,7 +161,7 @@ bool GUI_App::OnInit()
Bind(wxEVT_IDLE, [this](wxIdleEvent& event)
{
if (app_config->dirty())
if (app_config->dirty() && app_config->get("autosave") == "1")
app_config->save();
// ! Temporary workaround for the correct behavior of the Scrolled sidebar panel

View file

@ -818,7 +818,7 @@ void ObjectList::update_settings_item()
}
}
void ObjectList::append_menu_item_add_generic(wxMenuItem* menu, const int type) {
void ObjectList::append_menu_item_add_generic(wxMenuItem* menu, const ModelVolumeType type) {
auto sub_menu = new wxMenu;
if (wxGetApp().get_mode() == comExpert) {
@ -827,10 +827,9 @@ void ObjectList::append_menu_item_add_generic(wxMenuItem* menu, const int type)
sub_menu->AppendSeparator();
}
std::vector<std::string> menu_items = { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") };
for (auto& item : menu_items) {
for (auto& item : { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") }) {
append_menu_item(sub_menu, wxID_ANY, _(item), "",
[this, type, item](wxCommandEvent&) { load_generic_subobject(_(item).ToUTF8().data(), type); }, "", menu->GetMenu());
[this, type, item](wxCommandEvent&) { load_generic_subobject(item, type); }, "", menu->GetMenu());
}
menu->SetSubMenu(sub_menu);
@ -839,10 +838,10 @@ void ObjectList::append_menu_item_add_generic(wxMenuItem* menu, const int type)
void ObjectList::append_menu_items_add_volume(wxMenu* menu)
{
// Note: id accords to type of the sub-object, so sequence of the menu items is important
std::vector<std::string> menu_object_types_items = {L("Add part"), // ~ModelVolume::MODEL_PART
L("Add modifier"), // ~ModelVolume::PARAMETER_MODIFIER
L("Add support enforcer"), // ~ModelVolume::SUPPORT_ENFORCER
L("Add support blocker") }; // ~ModelVolume::SUPPORT_BLOCKER
std::vector<std::string> menu_object_types_items = {L("Add part"), // ~ModelVolumeType::MODEL_PART
L("Add modifier"), // ~ModelVolumeType::PARAMETER_MODIFIER
L("Add support enforcer"), // ~ModelVolumeType::SUPPORT_ENFORCER
L("Add support blocker") }; // ~ModelVolumeType::SUPPORT_BLOCKER
// Update "add" items(delete old & create new) settings popupmenu
for (auto& item : menu_object_types_items){
@ -856,15 +855,15 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
if (mode < comExpert)
{
append_menu_item(menu, wxID_ANY, _(L("Add part")), "",
[this](wxCommandEvent&) { load_subobject(ModelVolume::MODEL_PART); }, *m_bmp_vector[ModelVolume::MODEL_PART]);
[this](wxCommandEvent&) { load_subobject(ModelVolumeType::MODEL_PART); }, *m_bmp_vector[int(ModelVolumeType::MODEL_PART)]);
}
if (mode == comSimple) {
append_menu_item(menu, wxID_ANY, _(L("Add support enforcer")), "",
[this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToUTF8().data(), ModelVolume::SUPPORT_ENFORCER); },
*m_bmp_vector[ModelVolume::SUPPORT_ENFORCER]);
[this](wxCommandEvent&) { load_generic_subobject(L("Box"), ModelVolumeType::SUPPORT_ENFORCER); },
*m_bmp_vector[int(ModelVolumeType::SUPPORT_ENFORCER)]);
append_menu_item(menu, wxID_ANY, _(L("Add support blocker")), "",
[this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToUTF8().data(), ModelVolume::SUPPORT_BLOCKER); },
*m_bmp_vector[ModelVolume::SUPPORT_BLOCKER]);
[this](wxCommandEvent&) { load_generic_subobject(L("Box"), ModelVolumeType::SUPPORT_BLOCKER); },
*m_bmp_vector[int(ModelVolumeType::SUPPORT_BLOCKER)]);
return;
}
@ -875,7 +874,7 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
auto menu_item = new wxMenuItem(menu, wxID_ANY, _(item));
menu_item->SetBitmap(*m_bmp_vector[type]);
append_menu_item_add_generic(menu_item, type);
append_menu_item_add_generic(menu_item, ModelVolumeType(type));
menu->Append(menu_item);
}
@ -924,7 +923,7 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
menu->DestroySeparators(); // delete old separators
const auto sel_vol = get_selected_model_volume();
if (sel_vol && sel_vol->type() >= ModelVolume::SUPPORT_ENFORCER)
if (sel_vol && sel_vol->type() >= ModelVolumeType::SUPPORT_ENFORCER)
return nullptr;
const ConfigOptionMode mode = wxGetApp().get_mode();
@ -948,7 +947,7 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
menu_item->SetBitmap(m_bmp_cog);
// const auto sel_vol = get_selected_model_volume();
// if (sel_vol && sel_vol->type() >= ModelVolume::SUPPORT_ENFORCER)
// if (sel_vol && sel_vol->type() >= ModelVolumeType::SUPPORT_ENFORCER)
// menu_item->Enable(false);
// else
menu_item->SetSubMenu(create_settings_popupmenu(menu));
@ -1103,7 +1102,7 @@ void ObjectList::update_opt_keys(t_config_option_keys& opt_keys)
opt_keys.erase(opt_keys.begin() + i);
}
void ObjectList::load_subobject(int type)
void ObjectList::load_subobject(ModelVolumeType type)
{
auto item = GetSelection();
if (!item || m_objects_model->GetParent(item) != wxDataViewItem(0))
@ -1126,7 +1125,7 @@ void ObjectList::load_subobject(int type)
void ObjectList::load_part( ModelObject* model_object,
wxArrayString& part_names,
int type)
ModelVolumeType type)
{
wxWindow* parent = wxGetApp().tab_panel()->GetPage(0);
@ -1159,7 +1158,7 @@ void ObjectList::load_part( ModelObject* model_object,
#endif // !ENABLE_VOLUMES_CENTERING_FIXES
volume->translate(delta);
auto new_volume = model_object->add_volume(*volume);
new_volume->set_type(static_cast<ModelVolume::Type>(type));
new_volume->set_type(type);
new_volume->name = boost::filesystem::path(input_file).filename().string();
part_names.Add(from_u8(new_volume->name));
@ -1174,28 +1173,28 @@ void ObjectList::load_part( ModelObject* model_object,
}
void ObjectList::load_generic_subobject(const std::string& type_name, const int type)
void ObjectList::load_generic_subobject(const std::string& type_name, const ModelVolumeType type)
{
const auto obj_idx = get_selected_obj_idx();
if (obj_idx < 0) return;
const std::string name = "lambda-" + type_name;
const wxString name = _(L("Generic")) + "-" + _(type_name);
TriangleMesh mesh;
auto& bed_shape = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionPoints>("bed_shape")->values;
const auto& sz = BoundingBoxf(bed_shape).size();
const auto side = 0.1 * std::max(sz(0), sz(1));
if (type_name == _("Box")) {
if (type_name == "Box") {
mesh = make_cube(side, side, side);
// box sets the base coordinate at 0, 0, move to center of plate
mesh.translate(-side * 0.5, -side * 0.5, 0);
}
else if (type_name == _("Cylinder"))
else if (type_name == "Cylinder")
mesh = make_cylinder(0.5*side, side);
else if (type_name == _("Sphere"))
else if (type_name == "Sphere")
mesh = make_sphere(0.5*side, PI/18);
else if (type_name == _("Slab")) {
else if (type_name == "Slab") {
const auto& size = (*m_objects)[obj_idx]->bounding_box().size();
mesh = make_cube(size(0)*1.5, size(1)*1.5, size(2)*0.5);
// box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z
@ -1204,7 +1203,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const int
mesh.repair();
auto new_volume = (*m_objects)[obj_idx]->add_volume(mesh);
new_volume->set_type(static_cast<ModelVolume::Type>(type));
new_volume->set_type(type);
#if !ENABLE_GENERIC_SUBPARTS_PLACEMENT
new_volume->set_offset(Vec3d(0.0, 0.0, (*m_objects)[obj_idx]->origin_translation(2) - mesh.stl.stats.min(2)));
@ -1231,7 +1230,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const int
}
#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT
new_volume->name = name;
new_volume->name = into_u8(name);
// set a default extruder value, since user can't add it manually
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
@ -1239,7 +1238,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const int
parts_changed(obj_idx);
const auto object_item = m_objects_model->GetTopParent(GetSelection());
select_item(m_objects_model->AddVolumeChild(object_item, from_u8(name), type));
select_item(m_objects_model->AddVolumeChild(object_item, name, type));
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
selection_changed();
#endif //no __WXOSX__ //__WXMSW__
@ -1371,7 +1370,7 @@ void ObjectList::split()
for (auto id = 0; id < model_object->volumes.size(); id++) {
const auto vol_item = m_objects_model->AddVolumeChild(parent, from_u8(model_object->volumes[id]->name),
model_object->volumes[id]->is_modifier() ?
ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART,
ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART,
model_object->volumes[id]->config.has("extruder") ?
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
false);
@ -1973,15 +1972,15 @@ void ObjectList::change_part_type()
if (!volume)
return;
const auto type = volume->type();
if (type == ModelVolume::MODEL_PART)
const ModelVolumeType type = volume->type();
if (type == ModelVolumeType::MODEL_PART)
{
const int obj_idx = get_selected_obj_idx();
if (obj_idx < 0) return;
int model_part_cnt = 0;
for (auto vol : (*m_objects)[obj_idx]->volumes) {
if (vol->type() == ModelVolume::MODEL_PART)
if (vol->type() == ModelVolumeType::MODEL_PART)
++model_part_cnt;
}
@ -1993,13 +1992,13 @@ void ObjectList::change_part_type()
const wxString names[] = { "Part", "Modifier", "Support Enforcer", "Support Blocker" };
auto new_type = wxGetSingleChoiceIndex("Type: ", _(L("Select type of part")), wxArrayString(4, names), type);
auto new_type = ModelVolumeType(wxGetSingleChoiceIndex("Type: ", _(L("Select type of part")), wxArrayString(4, names), int(type)));
if (new_type == type || new_type < 0)
if (new_type == type || new_type == ModelVolumeType::INVALID)
return;
const auto item = GetSelection();
volume->set_type(static_cast<ModelVolume::Type>(new_type));
volume->set_type(new_type);
m_objects_model->SetVolumeType(item, new_type);
m_parts_changed = true;
@ -2009,11 +2008,11 @@ void ObjectList::change_part_type()
//(we show additional settings for Part and Modifier and hide it for Support Blocker/Enforcer)
const auto settings_item = m_objects_model->GetSettingsItem(item);
if (settings_item &&
(new_type == ModelVolume::SUPPORT_ENFORCER || new_type == ModelVolume::SUPPORT_BLOCKER)) {
(new_type == ModelVolumeType::SUPPORT_ENFORCER || new_type == ModelVolumeType::SUPPORT_BLOCKER)) {
m_objects_model->Delete(settings_item);
}
else if (!settings_item &&
(new_type == ModelVolume::MODEL_PART || new_type == ModelVolume::PARAMETER_MODIFIER)) {
(new_type == ModelVolumeType::MODEL_PART || new_type == ModelVolumeType::PARAMETER_MODIFIER)) {
select_item(m_objects_model->AddSettingsChild(item));
}
}

View file

@ -21,6 +21,7 @@ class ConfigOptionsGroup;
class DynamicPrintConfig;
class ModelObject;
class ModelVolume;
enum class ModelVolumeType : int;
// FIXME: broken build on mac os because of this is missing:
typedef std::vector<std::string> t_config_option_keys;
@ -173,7 +174,7 @@ public:
void get_freq_settings_choice(const wxString& bundle_name);
void update_settings_item();
void append_menu_item_add_generic(wxMenuItem* menu, const int type);
void append_menu_item_add_generic(wxMenuItem* menu, const ModelVolumeType type);
void append_menu_items_add_volume(wxMenu* menu);
wxMenuItem* append_menu_item_split(wxMenu* menu);
wxMenuItem* append_menu_item_settings(wxMenu* menu);
@ -190,9 +191,9 @@ public:
void update_opt_keys(t_config_option_keys& t_optopt_keys);
void load_subobject(int type);
void load_part(ModelObject* model_object, wxArrayString& part_names, int type);
void load_generic_subobject(const std::string& type_name, const int type);
void load_subobject(ModelVolumeType type);
void load_part(ModelObject* model_object, wxArrayString& part_names, ModelVolumeType type);
void load_generic_subobject(const std::string& type_name, const ModelVolumeType type);
void del_object(const int obj_idx);
void del_subobject_item(wxDataViewItem& item);
void del_settings_from_config();

View file

@ -101,6 +101,10 @@ void ImGuiWrapper::set_style_scaling(float scaling)
bool ImGuiWrapper::update_mouse_data(wxMouseEvent& evt)
{
if (! display_initialized()) {
return false;
}
ImGuiIO& io = ImGui::GetIO();
io.MousePos = ImVec2((float)evt.GetX(), (float)evt.GetY());
io.MouseDown[0] = evt.LeftDown();
@ -116,6 +120,10 @@ bool ImGuiWrapper::update_mouse_data(wxMouseEvent& evt)
bool ImGuiWrapper::update_key_data(wxKeyEvent &evt)
{
if (! display_initialized()) {
return false;
}
ImGuiIO& io = ImGui::GetIO();
if (evt.GetEventType() == wxEVT_CHAR) {
@ -521,6 +529,12 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
}
bool ImGuiWrapper::display_initialized() const
{
const ImGuiIO& io = ImGui::GetIO();
return io.DisplaySize.x >= 0.0f && io.DisplaySize.y >= 0.0f;
}
void ImGuiWrapper::destroy_device_objects()
{
destroy_fonts_texture();

View file

@ -75,6 +75,7 @@ private:
void init_input();
void init_style();
void render_draw_data(ImDrawData *draw_data);
bool display_initialized() const;
void destroy_device_objects();
void destroy_fonts_texture();

View file

@ -147,11 +147,11 @@ void MainFrame::init_tabpanel()
wxGetApp().obj_list()->create_popup_menus();
// The following event is emited by Tab implementation on config value change.
Bind(EVT_TAB_VALUE_CHANGED, &MainFrame::on_value_changed, this);
Bind(EVT_TAB_VALUE_CHANGED, &MainFrame::on_value_changed, this); // #ys_FIXME_to_delete
// The following event is emited by Tab on preset selection,
// or when the preset's "modified" status changes.
Bind(EVT_TAB_PRESETS_CHANGED, &MainFrame::on_presets_changed, this);
Bind(EVT_TAB_PRESETS_CHANGED, &MainFrame::on_presets_changed, this); // #ys_FIXME_to_delete
create_preset_tabs();
@ -833,6 +833,7 @@ void MainFrame::select_view(const std::string& direction)
m_plater->select_view(direction);
}
// #ys_FIXME_to_delete
void MainFrame::on_presets_changed(SimpleEvent &event)
{
auto *tab = dynamic_cast<Tab*>(event.GetEventObject());
@ -857,6 +858,7 @@ void MainFrame::on_presets_changed(SimpleEvent &event)
}
}
// #ys_FIXME_to_delete
void MainFrame::on_value_changed(wxCommandEvent& event)
{
auto *tab = dynamic_cast<Tab*>(event.GetEventObject());
@ -872,12 +874,12 @@ void MainFrame::on_value_changed(wxCommandEvent& event)
m_plater->on_extruders_change(value);
}
}
// Don't save while loading for the first time.
if (m_loaded) {
AppConfig &cfg = *wxGetApp().app_config;
if (cfg.get("autosave") == "1")
cfg.save();
}
}
void MainFrame::on_config_changed(DynamicPrintConfig* config) const
{
if (m_plater)
m_plater->on_config_change(*config); // propagate config change events to the plater
}
// Called after the Preferences dialog is closed and the program settings are saved.

View file

@ -96,6 +96,8 @@ public:
void load_config(const DynamicPrintConfig& config);
void select_tab(size_t tab) const;
void select_view(const std::string& direction);
// Propagate changed configuration from the Tab to the Platter and save changes to the AppConfig
void on_config_changed(DynamicPrintConfig* cfg) const ;
PrintHostQueueDialog* printhost_queue_dlg() { return m_printhost_queue_dlg; }

View file

@ -559,8 +559,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
ret = config.opt_int(opt_key, idx);
break;
case coEnum:{
if (opt_key.compare("external_fill_pattern") == 0 ||
opt_key.compare("fill_pattern") == 0 ) {
if (opt_key == "top_fill_pattern" ||
opt_key == "bottom_fill_pattern" ||
opt_key == "fill_pattern" ) {
ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
}
else if (opt_key.compare("gcode_flavor") == 0 ) {

View file

@ -521,7 +521,7 @@ struct Sidebar::priv
void Sidebar::priv::show_preset_comboboxes()
{
const bool showSLA = plater->printer_technology() == ptSLA;
const bool showSLA = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA;
wxWindowUpdateLocker noUpdates_scrolled(scrolled->GetParent());
@ -682,11 +682,12 @@ void Sidebar::remove_unused_filament_combos(const int current_extruder_count)
void Sidebar::update_presets(Preset::Type preset_type)
{
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology();
switch (preset_type) {
case Preset::TYPE_FILAMENT:
{
const int extruder_cnt = p->plater->printer_technology() != ptFFF ? 1 :
const int extruder_cnt = print_tech != ptFFF ? 1 :
dynamic_cast<ConfigOptionFloats*>(preset_bundle.printers.get_edited_preset().config.option("nozzle_diameter"))->values.size();
const int filament_cnt = p->combos_filament.size() > extruder_cnt ? extruder_cnt : p->combos_filament.size();
@ -718,7 +719,7 @@ void Sidebar::update_presets(Preset::Type preset_type)
case Preset::TYPE_PRINTER:
{
// Update the print choosers to only contain the compatible presets, update the dirty flags.
if (p->plater->printer_technology() == ptFFF)
if (print_tech == ptFFF)
preset_bundle.prints.update_platter_ui(p->combo_print);
else {
preset_bundle.sla_prints.update_platter_ui(p->combo_sla_print);
@ -731,7 +732,7 @@ void Sidebar::update_presets(Preset::Type preset_type)
p->combo_printer->check_selection();
// Update the filament choosers to only contain the compatible presets, update the color preview,
// update the dirty flags.
if (p->plater->printer_technology() == ptFFF) {
if (print_tech == ptFFF) {
for (size_t i = 0; i < p->combos_filament.size(); ++ i)
preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]);
}
@ -1991,6 +1992,7 @@ void Plater::priv::split_volume()
void Plater::priv::schedule_background_process()
{
delayed_error_message.clear();
// Trigger the timer event after 0.5s
this->background_process_timer.Start(500, wxTIMER_ONE_SHOT);
// Notify the Canvas3D that something has changed, so it may invalidate some of the layer editing stuff.

View file

@ -356,7 +356,7 @@ const std::vector<std::string>& Preset::print_options()
static std::vector<std::string> s_opts {
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "top_solid_layers", "bottom_solid_layers",
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "external_fill_pattern",
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed",
"max_volumetric_speed",

View file

@ -1435,7 +1435,8 @@ bool PresetBundle::parse_color(const std::string &scolor, unsigned char *rgb_out
void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui)
{
if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA)
if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA ||
this->filament_presets.size() <= idx_extruder )
return;
unsigned char rgb[3];

View file

@ -669,7 +669,6 @@ void Tab::load_config(const DynamicPrintConfig& config)
bool modified = 0;
for(auto opt_key : m_config->diff(config)) {
m_config->set_key_value(opt_key, config.option(opt_key)->clone());
m_dirty_options.emplace(opt_key);
modified = 1;
}
if (modified) {
@ -752,8 +751,6 @@ void Tab::load_key_value(const std::string& opt_key, const boost::any& value, bo
void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
{
m_dirty_options.erase(opt_key);
ConfigOptionsGroup* og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(supports_printer_technology(ptFFF));
if (opt_key == "fill_density" || opt_key == "supports_enable" || opt_key == "pad_enable")
{
@ -778,22 +775,29 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
if (opt_key == "wipe_tower" || opt_key == "single_extruder_multi_material" || opt_key == "extruders_count" )
update_wiping_button_visibility();
if (opt_key == "extruders_count")
wxGetApp().plater()->on_extruders_change(boost::any_cast<size_t>(value));
update();
// #ys_FIXME_to_delete
// Post event to the Plater after updating of the all dirty options
// It helps to avoid needless schedule_background_processing
if (update_completed()) {
wxCommandEvent event(EVT_TAB_VALUE_CHANGED);
event.SetEventObject(this);
event.SetString(opt_key);
if (opt_key == "extruders_count")
{
const int val = boost::any_cast<size_t>(value);
event.SetInt(val);
}
wxPostEvent(this, event);
}
// if (update_completed())
// if (m_update_stack.empty())
// {
// // wxCommandEvent event(EVT_TAB_VALUE_CHANGED);
// // event.SetEventObject(this);
// // event.SetString(opt_key);
// // if (opt_key == "extruders_count")
// // {
// // const int val = boost::any_cast<size_t>(value);
// // event.SetInt(val);
// // }
// //
// // wxPostEvent(this, event);
// wxGetApp().mainframe->on_value_changed(m_config);
// }
}
// Show/hide the 'purging volumes' button
@ -826,10 +830,18 @@ void Tab::on_presets_changed()
// refresh the print or filament/sla_material tab page.
wxGetApp().get_tab(t)->load_current_preset();
}
// clear m_dependent_tabs after first update from select_preset()
// to avoid needless preset loading from update() function
m_dependent_tabs.clear();
// #ys_FIXME_to_delete
// wxCommandEvent event(EVT_TAB_PRESETS_CHANGED);
// event.SetEventObject(this);
// wxPostEvent(this, event);
// Instead of PostEvent (EVT_TAB_PRESETS_CHANGED) just call update_presets
wxGetApp().plater()->sidebar().update_presets(m_type);
wxCommandEvent event(EVT_TAB_PRESETS_CHANGED);
event.SetEventObject(this);
wxPostEvent(this, event);
update_preset_description_line();
}
@ -971,7 +983,8 @@ void TabPrint::build()
optgroup = page->new_optgroup(_(L("Infill")));
optgroup->append_single_option_line("fill_density");
optgroup->append_single_option_line("fill_pattern");
optgroup->append_single_option_line("external_fill_pattern");
optgroup->append_single_option_line("top_fill_pattern");
optgroup->append_single_option_line("bottom_fill_pattern");
optgroup = page->new_optgroup(_(L("Reducing printing time")));
optgroup->append_single_option_line("infill_every_layers");
@ -1165,6 +1178,7 @@ void TabPrint::update()
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
return; // ys_FIXME
// #ys_FIXME_to_delete
//! Temporary workaround for the correct updates of the SpinCtrl (like "perimeters"):
// KillFocus() for the wxSpinCtrl use CallAfter function. So,
// to except the duplicate call of the update() after dialog->ShowModal(),
@ -1172,6 +1186,7 @@ void TabPrint::update()
// if (is_msg_dlg_already_exist) // ! It looks like a fixed problem after start to using of a m_dirty_options
// return; // ! TODO Let delete this part of code after a common aplication testing
m_update_cnt++;
Freeze();
double fill_density = m_config->option<ConfigOptionPercent>("fill_density")->value;
@ -1280,7 +1295,7 @@ void TabPrint::update()
}
}
if (!str_fill_pattern.empty()) {
const std::vector<std::string> &external_fill_pattern = m_config->def()->get("external_fill_pattern")->enum_values;
const std::vector<std::string> &external_fill_pattern = m_config->def()->get("top_fill_pattern")->enum_values;
bool correct_100p_fill = false;
for (const std::string &fill : external_fill_pattern)
{
@ -1321,7 +1336,7 @@ void TabPrint::update()
bool have_solid_infill = m_config->opt_int("top_solid_layers") > 0 || m_config->opt_int("bottom_solid_layers") > 0;
// solid_infill_extruder uses the same logic as in Print::extruders()
for (auto el : {"external_fill_pattern", "infill_first", "solid_infill_extruder",
for (auto el : {"top_fill_pattern", "bottom_fill_pattern", "infill_first", "solid_infill_extruder",
"solid_infill_extrusion_width", "solid_infill_speed" })
get_field(el)->toggle(have_solid_infill);
@ -1384,6 +1399,10 @@ void TabPrint::update()
from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle)));
Thaw();
m_update_cnt--;
if (m_update_cnt==0)
wxGetApp().mainframe->on_config_changed(m_config);
}
void TabPrint::OnActivate()
@ -1553,6 +1572,7 @@ void TabFilament::update()
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
return; // ys_FIXME
m_update_cnt++;
Freeze();
wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset()));
m_cooling_description_line->SetText(text);
@ -1567,7 +1587,11 @@ void TabFilament::update()
for (auto el : { "min_fan_speed", "disable_fan_first_layers" })
get_field(el)->toggle(fan_always_on);
Thaw();
Thaw();
m_update_cnt--;
if (m_update_cnt == 0)
wxGetApp().mainframe->on_config_changed(m_config);
}
void TabFilament::OnActivate()
@ -2241,7 +2265,12 @@ void TabPrinter::update_pages()
void TabPrinter::update()
{
m_update_cnt++;
m_presets->get_edited_preset().printer_technology() == ptFFF ? update_fff() : update_sla();
m_update_cnt--;
if (m_update_cnt == 0)
wxGetApp().mainframe->on_config_changed(m_config);
}
void TabPrinter::update_fff()
@ -3206,6 +3235,14 @@ void TabSLAMaterial::update()
{
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF)
return; // #ys_FIXME
// #ys_FIXME
// m_update_cnt++;
// ! something to update
// m_update_cnt--;
//
// if (m_update_cnt == 0)
wxGetApp().mainframe->on_config_changed(m_config);
}
void TabSLAPrint::build()
@ -3290,6 +3327,14 @@ void TabSLAPrint::update()
{
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF)
return; // #ys_FIXME
// #ys_FIXME
// m_update_cnt++;
// ! something to update
// m_update_cnt--;
//
// if (m_update_cnt == 0)
wxGetApp().mainframe->on_config_changed(m_config);
}
} // GUI

View file

@ -204,7 +204,6 @@ protected:
void set_type();
int m_em_unit;
std::set<std::string> m_dirty_options;
public:
PresetBundle* m_preset_bundle;
@ -213,6 +212,11 @@ public:
DynamicPrintConfig* m_config;
ogStaticText* m_parent_preset_description_line;
wxStaticText* m_colored_Label = nullptr;
// Counter for the updating (because of an update() function can have a recursive behavior):
// 1. increase value from the very beginning of an update() function
// 2. decrease value at the end of an update() function
// 3. propagate changed configuration to the Platter when (m_update_cnt == 0) only
int m_update_cnt = 0;
public:
Tab(wxNotebook* parent, const wxString& title, const char* name);
@ -284,7 +288,6 @@ protected:
void update_frequently_changed_parameters();
void fill_icon_descriptions();
void set_tooltips_text();
bool update_completed() const { return m_dirty_options.empty(); }
};
class TabPrint : public Tab

View file

@ -492,7 +492,7 @@ wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name, const int ext
wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &parent_item,
const wxString &name,
const int volume_type,
const Slic3r::ModelVolumeType volume_type,
const int extruder/* = 0*/,
const bool create_frst_child/* = true*/)
{
@ -518,7 +518,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddVolumeChild(const wxDataViewItem &pa
if (insert_position > 0) insert_position++;
}
const auto node = new PrusaObjectDataViewModelNode(root, name, *m_volume_bmps[volume_type], extruder_str, root->m_volumes_cnt);
const auto node = new PrusaObjectDataViewModelNode(root, name, *m_volume_bmps[int(volume_type)], extruder_str, root->m_volumes_cnt);
insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position);
// notify control
const wxDataViewItem child((void*)node);
@ -1280,13 +1280,13 @@ void PrusaObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item,
ItemChanged(item);
}
void PrusaObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const int type)
void PrusaObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type)
{
if (!item.IsOk() || GetItemType(item) != itVolume)
return;
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
node->SetBitmap(*m_volume_bmps[type]);
node->SetBitmap(*m_volume_bmps[int(type)]);
ItemChanged(item);
}

View file

@ -16,6 +16,10 @@
#include <set>
#include <functional>
namespace Slic3r {
enum class ModelVolumeType : int;
};
wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
std::function<void(wxCommandEvent& event)> cb, const wxBitmap& icon, wxEvtHandler* event_handler = nullptr);
wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
@ -448,7 +452,7 @@ public:
wxDataViewItem Add(const wxString &name, const int extruder);
wxDataViewItem AddVolumeChild(const wxDataViewItem &parent_item,
const wxString &name,
const int volume_type,
const Slic3r::ModelVolumeType volume_type,
const int extruder = 0,
const bool create_frst_child = true);
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
@ -516,7 +520,7 @@ public:
void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector<std::string>& categories);
void SetVolumeBitmaps(const std::vector<wxBitmap*>& volume_bmps) { m_volume_bmps = volume_bmps; }
void SetVolumeType(const wxDataViewItem &item, const int type);
void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type);
void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; }
};

View file

@ -353,14 +353,6 @@ Updates PresetUpdater::priv::get_config_updates() const
// Perform a basic load and check the version
const auto vp = VendorProfile::from_ini(bundle_path, false);
const auto ver_current = idx.find(vp.config_version);
if (ver_current == idx.end()) {
auto message = (boost::format("Preset bundle `%1%` version not found in index: %2%") % idx.vendor() % vp.config_version.to_string()).str();
BOOST_LOG_TRIVIAL(error) << message;
GUI::show_error(nullptr, GUI::from_u8(message));
continue;
}
// Getting a recommended version from the latest index, wich may have been downloaded
// from the internet, or installed / updated from the installation resources.
const auto recommended = idx.recommended();
@ -368,15 +360,24 @@ Updates PresetUpdater::priv::get_config_updates() const
BOOST_LOG_TRIVIAL(error) << boost::format("No recommended version for vendor: %1%, invalid index?") % idx.vendor();
}
BOOST_LOG_TRIVIAL(debug) << boost::format("Vendor: %1%, version installed: %2%, version cached: %3%")
const auto ver_current = idx.find(vp.config_version);
const bool ver_current_found = ver_current != idx.end();
if (! ver_current_found) {
auto message = (boost::format("Preset bundle `%1%` version not found in index: %2%") % idx.vendor() % vp.config_version.to_string()).str();
BOOST_LOG_TRIVIAL(error) << message;
GUI::show_error(nullptr, GUI::from_u8(message));
}
BOOST_LOG_TRIVIAL(debug) << boost::format("Vendor: %1%, version installed: %2%%3%, version cached: %4%")
% vp.name
% ver_current->config_version.to_string()
% vp.config_version.to_string()
% (ver_current_found ? "" : " (not found in index!)")
% recommended->config_version.to_string();
if (! ver_current->is_current_slic3r_supported()) {
if (ver_current_found && !ver_current->is_current_slic3r_supported()) {
BOOST_LOG_TRIVIAL(warning) << "Current Slic3r incompatible with installed bundle: " << bundle_path.string();
updates.incompats.emplace_back(std::move(bundle_path), *ver_current);
} else if (recommended->config_version > ver_current->config_version) {
} else if (recommended->config_version > vp.config_version) {
// Config bundle update situation
// Check if the update is already present in a snapshot

View file

@ -166,7 +166,8 @@ for my $pattern (qw(rectilinear honeycomb hilbertcurve concentric)) {
my $config = Slic3r::Config::new_from_defaults;
$config->set('nozzle_diameter', [0.4,0.4,0.4,0.4]);
$config->set('fill_pattern', $pattern);
$config->set('external_fill_pattern', $pattern);
$config->set('top_fill_pattern', $pattern);
$config->set('bottom_fill_pattern', $pattern);
$config->set('perimeters', 1);
$config->set('skirts', 0);
$config->set('fill_density', 20);

View file

@ -258,17 +258,17 @@ ModelMaterial::attributes()
bool modifier()
%code%{ RETVAL = THIS->is_modifier(); %};
void set_modifier(bool modifier)
%code%{ THIS->set_type(modifier ? ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART); %};
%code%{ THIS->set_type(modifier ? ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART); %};
bool model_part()
%code%{ RETVAL = THIS->is_model_part(); %};
bool support_enforcer()
%code%{ RETVAL = THIS->is_support_enforcer(); %};
void set_support_enforcer()
%code%{ THIS->set_type(ModelVolume::SUPPORT_ENFORCER); %};
%code%{ THIS->set_type(ModelVolumeType::SUPPORT_ENFORCER); %};
bool support_blocker()
%code%{ RETVAL = THIS->is_support_blocker(); %};
void set_support_blocker()
%code%{ THIS->set_type(ModelVolume::SUPPORT_BLOCKER); %};
%code%{ THIS->set_type(ModelVolumeType::SUPPORT_BLOCKER); %};
size_t split(unsigned int max_extruders);
};