Squash merge of pull request Raft enhancements #6003

Squashed commit of the following:

commit a16674fa9fb5b6f6b7ef10fcdc10838b118142f5
Merge: a5972e64f 28e5e41a7
Author: Vojtech Bubnik <bubnikv@gmail.com>
Date:   Wed Feb 10 08:56:21 2021 +0100

    Merge branch 'rafting_extras_2' of https://github.com/nemart69/PrusaSlicer into nemart69-rafting_extras_2

commit 28e5e41a7802a1ad9b363e1e45d7c2c20aa9dd74
Author: nemart69 <78763471+nemart69@users.noreply.github.com>
Date:   Wed Feb 10 00:58:50 2021 +0100

    Fix after merge with master

    Fixed missing curly brace after improperly solved merge conflict.

commit 02b71f724d4a1be670f4a2e1115b97821c0de0f2
Merge: 08131f065 8fbafbea8
Author: nemart69 <78763471+nemart69@users.noreply.github.com>
Date:   Tue Feb 9 22:12:26 2021 +0100

    Merge branch 'master' into rafting_extras_2

commit 08131f065b3f4f0b60d2bfe16c746d78b361c327
Author: nemart69 <78763471+nemart69@users.noreply.github.com>
Date:   Tue Feb 9 21:17:19 2021 +0100

    Raft changes, GUI part

commit 69aae4a2ad4be803b9622a3c2718ec7d3f8dbbb3
Author: nemart69 <78763471+nemart69@users.noreply.github.com>
Date:   Tue Feb 9 21:15:33 2021 +0100

    Raft changes, libslic3r part
This commit is contained in:
Vojtech Bubnik 2021-02-10 09:03:03 +01:00
parent a5972e64fa
commit 8e9526e977
13 changed files with 259 additions and 147 deletions

View File

@ -154,7 +154,10 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
// detect overhanging/bridging perimeters
ExtrusionPaths paths;
if (perimeter_generator.config->overhangs && perimeter_generator.layer_id > 0
if ( ( (perimeter_generator.config->overhangs && perimeter_generator.layer_id > perimeter_generator.object_config->raft_layers)
|| (perimeter_generator.object_config->raft_overhangs
&& perimeter_generator.object_config->raft_layers > 0
&& perimeter_generator.layer_id == perimeter_generator.object_config->raft_layers)) // RaftingEdition
&& !(perimeter_generator.object_config->support_material && perimeter_generator.object_config->support_material_contact_distance.value == 0)) {
// get non-overhang paths by intersecting this loop with the grown lower slices
extrusion_paths_append(

View File

@ -15,7 +15,7 @@
// !!! If you needed to translate some string,
// !!! please use _L(string)
// !!! _() - is a standard wxWidgets macro to translate
// !!! L() is used only for marking localizable string
// !!! L() is used only for marking localizable string
// !!! It will be used in "xgettext" to create a Locating Message Catalog.
#define L(s) s
#endif /* L */
@ -386,7 +386,7 @@ void Preset::set_visible_from_appconfig(const AppConfig &app_config)
} else if (type == TYPE_FILAMENT || type == TYPE_SLA_MATERIAL) {
const std::string &section_name = (type == TYPE_FILAMENT) ? AppConfig::SECTION_FILAMENTS : AppConfig::SECTION_MATERIALS;
if (app_config.has_section(section_name)) {
// Check whether this profile is marked as "installed" in PrusaSlicer.ini,
// Check whether this profile is marked as "installed" in PrusaSlicer.ini,
// or whether a profile is marked as "installed", which this profile may have been renamed from.
const std::map<std::string, std::string> &installed = app_config.get_section(section_name);
auto has = [&installed](const std::string &name) {
@ -403,12 +403,12 @@ void Preset::set_visible_from_appconfig(const AppConfig &app_config)
const std::vector<std::string>& Preset::print_options()
{
static std::vector<std::string> s_opts {
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius",
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius",
"top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness",
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
"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",
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first",
"ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing",
"max_print_speed", "max_volumetric_speed", "avoid_crossing_perimeters_max_detour",
"fuzzy_skin_perimeter_mode", /* "fuzzy_skin_shape", */ "fuzzy_skin_thickness", "fuzzy_skin_point_dist",
@ -420,6 +420,7 @@ const std::vector<std::string>& Preset::print_options()
"bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
"min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
"raft_overhangs", "raft_contact_distance", "raft_xy_size_compensation", "raft_size_adjust",
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
"support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
@ -485,7 +486,7 @@ const std::vector<std::string>& Preset::printer_options()
"between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height",
"default_print_profile", "inherits",
"remaining_times", "silent_mode",
"remaining_times", "silent_mode",
"machine_limits_usage", "thumbnails"
};
s_opts.insert(s_opts.end(), Preset::machine_limits_options().begin(), Preset::machine_limits_options().end());
@ -646,7 +647,7 @@ void PresetCollection::add_default_preset(const std::vector<std::string> &keys,
// Throws an exception on error.
void PresetCollection::load_presets(const std::string &dir_path, const std::string &subdir)
{
// Don't use boost::filesystem::canonical() on Windows, it is broken in regard to reparse points,
// Don't use boost::filesystem::canonical() on Windows, it is broken in regard to reparse points,
// see https://github.com/prusa3d/PrusaSlicer/issues/732
boost::filesystem::path dir = boost::filesystem::absolute(boost::filesystem::path(dir_path) / subdir).make_preferred();
m_dir_path = dir.string();
@ -970,7 +971,7 @@ const Preset* PresetCollection::get_selected_preset_parent() const
// Resolve the "renamed_from" field.
assert(! inherits.empty());
auto it = this->find_preset_renamed(inherits);
if (it != m_presets.end())
if (it != m_presets.end())
preset = &(*it);
}
return (preset == nullptr/* || preset->is_default*/ || preset->is_external) ? nullptr : preset;
@ -985,17 +986,17 @@ const Preset* PresetCollection::get_preset_parent(const Preset& child) const
const Preset* preset = this->find_preset(inherits, false);
if (preset == nullptr) {
auto it = this->find_preset_renamed(inherits);
if (it != m_presets.end())
if (it != m_presets.end())
preset = &(*it);
}
return
return
// not found
(preset == nullptr/* || preset->is_default */||
(preset == nullptr/* || preset->is_default */||
// this should not happen, user profile should not derive from an external profile
preset->is_external ||
// this should not happen, however people are creative, see GH #4996
preset == &child) ?
nullptr :
preset == &child) ?
nullptr :
preset;
}
@ -1022,7 +1023,7 @@ const std::string& PresetCollection::get_preset_name_by_alias(const std::string&
// Continue over all profile names with the same alias.
it != m_map_alias_to_profile_name.end() && it->first == alias; ++ it)
if (auto it_preset = this->find_preset_internal(it->second);
it_preset != m_presets.end() && it_preset->name == it->second &&
it_preset != m_presets.end() && it_preset->name == it->second &&
it_preset->is_visible && (it_preset->is_compatible || size_t(it_preset - m_presets.begin()) == m_idx_selected))
return it_preset->name;
return alias;
@ -1092,7 +1093,7 @@ size_t PresetCollection::update_compatible_internal(const PresetWithVendorProfil
some_compatible |= preset_edited.is_compatible;
if (active_print != nullptr)
preset_edited.is_compatible &= is_compatible_with_print(this_preset_with_vendor_profile, *active_print, active_printer);
if (! preset_edited.is_compatible && selected &&
if (! preset_edited.is_compatible && selected &&
(unselect_if_incompatible == PresetSelectCompatibleType::Always || (unselect_if_incompatible == PresetSelectCompatibleType::OnlyIfWasCompatible && was_compatible)))
m_idx_selected = size_t(-1);
if (selected)
@ -1433,13 +1434,13 @@ const std::set<std::string>& PhysicalPrinter::get_preset_names() const
return preset_names;
}
bool PhysicalPrinter::has_empty_config() const
bool PhysicalPrinter::has_empty_config() const
{
return config.opt_string("print_host" ).empty() &&
config.opt_string("printhost_apikey" ).empty() &&
config.opt_string("printhost_cafile" ).empty() &&
return config.opt_string("print_host" ).empty() &&
config.opt_string("printhost_apikey" ).empty() &&
config.opt_string("printhost_cafile" ).empty() &&
config.opt_string("printhost_port" ).empty() &&
config.opt_string("printhost_user" ).empty() &&
config.opt_string("printhost_user" ).empty() &&
config.opt_string("printhost_password").empty();
}
@ -1451,7 +1452,7 @@ void PhysicalPrinter::update_preset_names_in_config()
name += el + ";";
name.pop_back();
config.set_key_value("preset_name", new ConfigOptionString(name));
}
}
}
void PhysicalPrinter::save(const std::string& file_name_from, const std::string& file_name_to)
@ -1500,7 +1501,7 @@ bool PhysicalPrinter::delete_preset(const std::string& preset_name)
return preset_names.erase(preset_name) > 0;
}
PhysicalPrinter::PhysicalPrinter(const std::string& name, const DynamicPrintConfig& default_config) :
PhysicalPrinter::PhysicalPrinter(const std::string& name, const DynamicPrintConfig& default_config) :
name(name), config(default_config)
{
update_from_config(config);
@ -1557,7 +1558,7 @@ PhysicalPrinterCollection::PhysicalPrinterCollection( const std::vector<std::str
// Throws an exception on error.
void PhysicalPrinterCollection::load_printers(const std::string& dir_path, const std::string& subdir)
{
// Don't use boost::filesystem::canonical() on Windows, it is broken in regard to reparse points,
// Don't use boost::filesystem::canonical() on Windows, it is broken in regard to reparse points,
// see https://github.com/prusa3d/PrusaSlicer/issues/732
boost::filesystem::path dir = boost::filesystem::absolute(boost::filesystem::path(dir_path) / subdir).make_preferred();
m_dir_path = dir.string();
@ -1709,7 +1710,7 @@ PhysicalPrinter* PhysicalPrinterCollection::find_printer_with_same_config(const
for (const char *opt : legacy_print_host_options)
if (is_equal && printer.config.opt_string(opt) != config.opt_string(opt))
is_equal = false;
if (is_equal)
return find_printer(printer.name);
}
@ -1725,7 +1726,7 @@ std::string PhysicalPrinterCollection::path_from_name(const std::string& new_nam
void PhysicalPrinterCollection::save_printer(PhysicalPrinter& edited_printer, const std::string& renamed_from/* = ""*/)
{
// controll and update preset_names in edited_printer config
// controll and update preset_names in edited_printer config
edited_printer.update_preset_names_in_config();
std::string name = renamed_from.empty() ? edited_printer.name : renamed_from;
@ -1817,7 +1818,7 @@ std::vector<std::string> PhysicalPrinterCollection::get_printers_with_preset(con
for (auto printer : m_printers) {
if (printer.preset_names.size() == 1)
continue;
continue;
if (printer.preset_names.find(preset_name) != printer.preset_names.end())
printers.emplace_back(printer.name);
}
@ -1887,7 +1888,7 @@ void PhysicalPrinterCollection::unselect_printer()
bool PhysicalPrinterCollection::is_selected(PhysicalPrinterCollection::ConstIterator it, const std::string& preset_name) const
{
return m_idx_selected == size_t(it - m_printers.begin()) &&
return m_idx_selected == size_t(it - m_printers.begin()) &&
m_selected_preset == preset_name;
}

View File

@ -1809,6 +1809,48 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInt(0));
// RaftingEdition
def = this->add("raft_overhangs", coBool);
def->label = L("Bridge flow above raft");
def->category = L("Support material");
def->tooltip = L("Use bridge flow and speed for the bottom layer. Quality of the layer improves significantly when this setting is off, however it could be difficult to remove the object from raft. Ignored for soluble interface.");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
def = this->add("raft_contact_distance", coFloat);
def->label = L("Raft contact Z distance");
def->category = L("Support material");
def->tooltip = L("The vertical distance between object and raft. Ignored for soluble interface.");
def->sidetext = L("mm");
def->min = 0;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.1));
def = this->add("raft_xy_size_compensation", coFloat);
def->label = L("Bottom layer expansion");
def->category = L("Support material");
def->tooltip = L("XY plane expansion of the bottom layer. This is useful to compensate shrinking, especially for higher contact Z distances and / or specific materials.");
def->sidetext = L("mm");
def->min = 0;
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloat(0.0));
def = this->add("raft_size_adjust", coEnum);
def->label = L("Raft size");
def->category = L("Support material");
def->tooltip = L("Raft size adjustment. Can be used to improve adhesion or reduce material consumption / save some printing area.");
def->enum_keys_map = &ConfigOptionEnum<RaftSizeAdjust>::get_enum_values();
def->enum_values.push_back("small");
def->enum_values.push_back("normal");
def->enum_values.push_back("large");
def->enum_values.push_back("extralarge");
def->enum_labels.push_back("Small");
def->enum_labels.push_back("Normal");
def->enum_labels.push_back("Large");
def->enum_labels.push_back("Extra large");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum<RaftSizeAdjust>(rsaNormal));
def = this->add("resolution", coFloat);
def->label = L("Resolution");
def->tooltip = L("Minimum detail resolution, used to simplify the input file for speeding up "

View File

@ -110,6 +110,13 @@ enum BrimType {
btOuterAndInner,
};
enum RaftSizeAdjust {
rsaSmall,
rsaNormal,
rsaLarge,
rsaExtraLarge
};
template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
@ -282,6 +289,18 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<BrimType>::get_en
return keys_map;
}
template<> inline const t_config_enum_values& ConfigOptionEnum<RaftSizeAdjust>::get_enum_values() {
static const t_config_enum_values keys_map = {
{ "small", rsaSmall },
{ "normal", rsaNormal },
{ "large", rsaLarge },
{ "extralarge", rsaExtraLarge }
};
return keys_map;
}
// Defines each and every confiuration option of Slic3r, including the properties of the GUI dialogs.
// Does not store the actual values, but defines default values.
class PrintConfigDef : public ConfigDef
@ -512,6 +531,10 @@ public:
ConfigOptionBool interface_shells;
ConfigOptionFloat layer_height;
ConfigOptionInt raft_layers;
ConfigOptionBool raft_overhangs;
ConfigOptionFloat raft_contact_distance;
ConfigOptionFloat raft_xy_size_compensation;
ConfigOptionEnum<RaftSizeAdjust> raft_size_adjust;
ConfigOptionEnum<SeamPosition> seam_position;
// ConfigOptionFloat seam_preferred_direction;
// ConfigOptionFloat seam_preferred_direction_jitter;
@ -563,6 +586,10 @@ protected:
OPT_PTR(interface_shells);
OPT_PTR(layer_height);
OPT_PTR(raft_layers);
OPT_PTR(raft_overhangs);
OPT_PTR(raft_contact_distance);
OPT_PTR(raft_xy_size_compensation);
OPT_PTR(raft_size_adjust);
OPT_PTR(seam_position);
OPT_PTR(slice_closing_radius);
// OPT_PTR(seam_preferred_direction);
@ -1120,7 +1147,7 @@ public:
// The percentage of smaller pillars compared to the normal pillar diameter
// which are used in problematic areas where a normal pilla cannot fit.
ConfigOptionPercent support_small_pillar_diameter_percent;
// How much bridge (supporting another pinhead) can be placed on a pillar.
ConfigOptionInt support_max_bridges_on_pillar;
@ -1172,7 +1199,7 @@ public:
// The height of the pad from the bottom to the top not considering the pit
ConfigOptionFloat pad_wall_height /*= 5*/;
// How far should the pad extend around the contained geometry
ConfigOptionFloat pad_brim_size;
@ -1196,7 +1223,7 @@ public:
// Disable the elevation (ignore its value) and use the zero elevation mode
ConfigOptionBool pad_around_object;
ConfigOptionBool pad_around_object_everywhere;
// This is the gap between the object bottom and the generated pad
@ -1210,7 +1237,7 @@ public:
// How much should the tiny connectors penetrate into the model body
ConfigOptionFloat pad_object_connector_penetration;
// /////////////////////////////////////////////////////////////////////////
// Model hollowing parameters:
// - Models can be hollowed out as part of the SLA print process
@ -1219,17 +1246,17 @@ public:
// - Additional holes will be drilled into the hollow model to allow for
// - resin removal.
// /////////////////////////////////////////////////////////////////////////
ConfigOptionBool hollowing_enable;
// The minimum thickness of the model walls to maintain. Note that the
// The minimum thickness of the model walls to maintain. Note that the
// resulting walls may be thicker due to smoothing out fine cavities where
// resin could stuck.
ConfigOptionFloat hollowing_min_thickness;
// Indirectly controls the voxel size (resolution) used by openvdb
ConfigOptionFloat hollowing_quality;
// Indirectly controls the minimum size of created cavities.
ConfigOptionFloat hollowing_closing_distance;
@ -1451,13 +1478,13 @@ Points get_bed_shape(const SLAPrinterConfig &cfg);
// ModelConfig is a wrapper around DynamicPrintConfig with an addition of a timestamp.
// Each change of ModelConfig is tracked by assigning a new timestamp from a global counter.
// The counter is used for faster synchronization of the background slicing thread
// with the front end by skipping synchronization of equal config dictionaries.
// The global counter is also used for avoiding unnecessary serialization of config
// with the front end by skipping synchronization of equal config dictionaries.
// The global counter is also used for avoiding unnecessary serialization of config
// dictionaries when taking an Undo snapshot.
//
// The global counter is NOT thread safe, therefore it is recommended to use ModelConfig from
// the main thread only.
//
//
// As there is a global counter and it is being increased with each change to any ModelConfig,
// if two ModelConfig dictionaries differ, they should differ with their timestamp as well.
// Therefore copying the ModelConfig including its timestamp is safe as there is no harm

View File

@ -535,6 +535,10 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
opt_key == "layer_height"
|| opt_key == "first_layer_height"
|| opt_key == "raft_layers"
|| opt_key == "raft_overhangs"
|| opt_key == "raft_contact_distance"
|| opt_key == "raft_xy_size_compensation"
|| opt_key == "raft_size_adjust"
|| opt_key == "slice_closing_radius") {
steps.emplace_back(posSlice);
} else if (
@ -760,7 +764,8 @@ void PrintObject::detect_surfaces_type()
[this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
// If we have raft layers, consider bottom layer as a bridge just like any other bottom surface lying on the void.
SurfaceType surface_type_bottom_1st =
(m_config.raft_layers.value > 0 && m_config.support_material_contact_distance.value > 0) ?
(m_config.raft_layers.value > 0 && m_config.support_material_contact_distance.value > 0 &&
/* RaftingEdition */ m_config.raft_overhangs.value) ?
stBottomBridge : stBottom;
// If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating
// the support from the print.
@ -1937,7 +1942,10 @@ end:
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - begin";
{
// Compensation value, scaled.
const float xy_compensation_scaled = float(scale_(m_config.xy_size_compensation.value));
const float _xy_compensation_scaled = float(scale_(m_config.xy_size_compensation.value));
const float _xy_compensation_1st_scaled = _xy_compensation_scaled + (m_config.raft_layers > 0) ?
// Apply optional compensation / expand the first layer above the raft. (RaftingEdition)
float(scale_(m_config.raft_xy_size_compensation.value)) : 0.f;
const float elephant_foot_compensation_scaled = (m_config.raft_layers == 0) ?
// Only enable Elephant foot compensation if printing directly on the print bed.
float(scale_(m_config.elefant_foot_compensation.value)) :
@ -1946,13 +1954,14 @@ end:
ExPolygons lslices_1st_layer;
tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_layers.size()),
[this, upscaled, clipped, xy_compensation_scaled, elephant_foot_compensation_scaled, &lslices_1st_layer]
[this, upscaled, clipped, _xy_compensation_scaled, _xy_compensation_1st_scaled, elephant_foot_compensation_scaled, &lslices_1st_layer]
(const tbb::blocked_range<size_t>& range) {
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
m_print->throw_if_canceled();
Layer *layer = m_layers[layer_id];
// Apply size compensation and perform clipping of multi-part objects.
float elfoot = (layer_id == 0) ? elephant_foot_compensation_scaled : 0.f;
float xy_compensation_scaled = (layer_id == 0) ? _xy_compensation_1st_scaled : _xy_compensation_scaled; // RaftingEdition
if (layer->m_regions.size() == 1) {
assert(! upscaled);
assert(! clipped);

View File

@ -110,8 +110,9 @@ SlicingParameters SlicingParameters::create_from_config(
params.min_layer_height = std::min(params.min_layer_height, params.layer_height);
params.max_layer_height = std::max(params.max_layer_height, params.layer_height);
// RaftingEdition: independent contact distance for raft, first object layer height not messed up
if (! soluble_interface) {
params.gap_raft_object = object_config.support_material_contact_distance.value;
params.gap_raft_object = object_config.raft_contact_distance.value;
params.gap_object_support = object_config.support_material_contact_distance.value;
params.gap_support_object = object_config.support_material_contact_distance.value;
}
@ -127,16 +128,18 @@ SlicingParameters SlicingParameters::create_from_config(
#if 1
params.contact_raft_layer_height = std::max(params.layer_height, 0.75 * support_material_interface_extruder_dmr);
if (! soluble_interface) {
// Compute the average of all nozzles used for printing the object over a raft.
//FIXME It is expected, that the 1st layer of the object is printed with a bridging flow over a full raft. Shall it not be vice versa?
coordf_t average_object_extruder_dmr = 0.;
if (! object_extruders.empty()) {
for (unsigned int extruder_id : object_extruders)
average_object_extruder_dmr += print_config.nozzle_diameter.get_at(extruder_id);
average_object_extruder_dmr /= coordf_t(object_extruders.size());
if (object_config.raft_overhangs.value) {
// Compute the average of all nozzles used for printing the object over a raft.
//FIXME It is expected, that the 1st layer of the object is printed with a bridging flow over a full raft. Shall it not be vice versa?
coordf_t average_object_extruder_dmr = 0.;
if (! object_extruders.empty()) {
for (unsigned int extruder_id : object_extruders)
average_object_extruder_dmr += print_config.nozzle_diameter.get_at(extruder_id);
average_object_extruder_dmr /= coordf_t(object_extruders.size());
}
params.first_object_layer_height = average_object_extruder_dmr;
params.first_object_layer_bridging = true;
}
params.first_object_layer_height = average_object_extruder_dmr;
params.first_object_layer_bridging = true;
}
#else
params.contact_raft_layer_height = soluble_interface ? support_material_interface_extruder_dmr : 0.75 * support_material_interface_extruder_dmr;
@ -150,13 +153,13 @@ SlicingParameters SlicingParameters::create_from_config(
//FIXME The last raft layer is the contact layer, which shall be printed with a bridging flow for ease of separation. Currently it is not the case.
if (params.raft_layers() == 1) {
// There is only the contact layer.
params.contact_raft_layer_height = first_layer_height;
params.raft_contact_top_z = first_layer_height;
params.first_print_layer_height = params.contact_raft_layer_height;
params.raft_contact_top_z = params.contact_raft_layer_height;
} else {
assert(params.base_raft_layers > 0);
assert(params.interface_raft_layers > 0);
// Number of the base raft layers is decreased by the first layer.
params.raft_base_top_z = first_layer_height + coordf_t(params.base_raft_layers - 1) * params.base_raft_layer_height;
params.first_print_layer_height = params.base_raft_layer_height;
params.raft_base_top_z = coordf_t(params.base_raft_layers) * params.base_raft_layer_height;
// Number of the interface raft layers is decreased by the contact layer.
params.raft_interface_top_z = params.raft_base_top_z + coordf_t(params.interface_raft_layers - 1) * params.interface_raft_layer_height;
params.raft_contact_top_z = params.raft_interface_top_z + params.contact_raft_layer_height;

View File

@ -1040,8 +1040,17 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
// we're here just to get the object footprint for the raft.
// We only consider contours and discard holes to get a more continuous raft.
overhang_polygons = collect_slices_outer(layer);
// Extend by SUPPORT_MATERIAL_MARGIN, which is 1.5mm
contact_polygons = offset(overhang_polygons, scale_(SUPPORT_MATERIAL_MARGIN));
// RaftingEdition
float adjust;
switch (m_object_config->raft_size_adjust.value) {
case rsaSmall: adjust = scale_(SUPPORT_MATERIAL_MARGIN / 2); break;
default:
case rsaNormal: adjust = scale_(SUPPORT_MATERIAL_MARGIN * 1); break;
case rsaLarge: adjust = scale_(SUPPORT_MATERIAL_MARGIN * 3); break;
case rsaExtraLarge: adjust = scale_(SUPPORT_MATERIAL_MARGIN * 4); break;
}
// Extend by a multiple of SUPPORT_MATERIAL_MARGIN, which is 1.5mm
contact_polygons = offset(overhang_polygons, adjust);
} else {
// Generate overhang / contact_polygons for non-raft layers.
const Layer &lower_layer = *object.layers()[layer_id-1];
@ -1841,7 +1850,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
assert(extr2z > extr1z || (extr1 != nullptr && extr2->layer_type == sltBottomContact));
if (std::abs(extr1z) < EPSILON) {
// This layer interval starts with the 1st layer. Print the 1st layer using the prescribed 1st layer thickness.
assert(! m_slicing_params.has_raft());
// assert(! m_slicing_params.has_raft()); RaftingEdition: unclear where the issue is: assert fails with 1-layer raft & base supports
assert(intermediate_layers.empty() || intermediate_layers.back()->print_z <= m_slicing_params.first_print_layer_height);
// At this point only layers above first_print_layer_heigth + EPSILON are expected as the other cases were captured earlier.
assert(extr2z >= m_slicing_params.first_print_layer_height + EPSILON);
@ -2169,7 +2178,9 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
{
// How much to inflate the support columns to be stable. This also applies to the 1st layer, if no raft layers are to be printed.
const float inflate_factor_fine = float(scale_((m_slicing_params.raft_layers() > 1) ? 0.5 : EPSILON));
const float inflate_factor_1st_layer = float(scale_(3.)) - inflate_factor_fine;
const float inflate_factor_1st_layer = float(scale_((m_slicing_params.raft_layers() > 0 &&
m_object_config->raft_size_adjust.value == rsaSmall) ?
1.5 /* RaftingEdition */ : 3.)) - inflate_factor_fine;
MyLayer *contacts = top_contacts .empty() ? nullptr : top_contacts .front();
MyLayer *interfaces = interface_layers.empty() ? nullptr : interface_layers.front();
MyLayer *columns_base = base_layers .empty() ? nullptr : base_layers .front();

View File

@ -294,6 +294,11 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
toggle_field("support_material_extruder", have_support_material || have_skirt);
toggle_field("support_material_speed", have_support_material || have_brim || have_skirt);
for (auto el : { "raft_xy_size_compensation", "raft_size_adjust" })
toggle_field(el, have_raft);
for (auto el : { "raft_overhangs", "raft_contact_distance" })
toggle_field(el, have_raft && !have_support_soluble);
bool has_ironing = config->opt_bool("ironing");
for (auto el : { "ironing_type", "ironing_flowrate", "ironing_spacing", "ironing_speed" })
toggle_field(el, has_ironing);

View File

@ -92,8 +92,8 @@ void Field::PostInitialize()
{
case coPercents:
case coFloats:
case coStrings:
case coBools:
case coStrings:
case coBools:
case coInts: {
auto tag_pos = m_opt_id.find("#");
if (tag_pos != std::string::npos)
@ -111,7 +111,7 @@ void Field::PostInitialize()
BUILD();
// For the mode, when settings are in non-modal dialog, neither dialog nor tabpanel doesn't receive wxEVT_KEY_UP event, when some field is selected.
// So, like a workaround check wxEVT_KEY_UP event for the Filed and switch between tabs if Ctrl+(1-4) was pressed
// So, like a workaround check wxEVT_KEY_UP event for the Filed and switch between tabs if Ctrl+(1-4) was pressed
if (getWindow())
getWindow()->Bind(wxEVT_KEY_UP, [](wxKeyEvent& evt) {
if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) {
@ -135,7 +135,7 @@ void Field::PostInitialize()
// tab panel should be focused for correct navigation between tabs
wxGetApp().tab_panel()->SetFocus();
}
evt.Skip();
});
}
@ -148,7 +148,7 @@ int Field::def_width_thinner() { return 4; }
void Field::on_kill_focus()
{
// call the registered function if it is available
if (m_on_kill_focus!=nullptr)
if (m_on_kill_focus!=nullptr)
m_on_kill_focus(m_opt_id);
}
@ -157,7 +157,7 @@ void Field::on_set_focus(wxEvent& event)
// to allow the default behavior
event.Skip();
// call the registered function if it is available
if (m_on_set_focus!=nullptr)
if (m_on_set_focus!=nullptr)
m_on_set_focus(m_opt_id);
}
@ -196,7 +196,7 @@ wxString Field::get_tooltip_text(const wxString& default_string)
if (tooltip.length() > 0)
tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " +
(boost::iends_with(opt_id, "_gcode") ? "\n" : "") + default_string +
(boost::iends_with(opt_id, "_gcode") ? "" : "\n") +
(boost::iends_with(opt_id, "_gcode") ? "" : "\n") +
_(L("parameter name")) + "\t: " + opt_id;
return tooltip_text;
@ -220,7 +220,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
case coPercents:
case coFloats:
case coFloat:{
if (m_opt.type == coPercent && !str.IsEmpty() && str.Last() == '%')
if (m_opt.type == coPercent && !str.IsEmpty() && str.Last() == '%')
str.RemoveLast();
else if (!str.IsEmpty() && str.Last() == '%')
{
@ -332,7 +332,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
set_value(stVal, false); // it's no needed but can be helpful, when inputted value contained "," instead of "."
}
}
m_value = std::string(str.ToUTF8().data());
break; }
@ -359,8 +359,8 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
out_of_range_val = true;
break;
}
}
}
}
}
invalid_val = true;
break;
}
@ -413,7 +413,7 @@ void TextCtrl::BUILD() {
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
wxString text_value = wxString("");
wxString text_value = wxString("");
switch (m_opt.type) {
case coFloatOrPercent:
@ -428,21 +428,21 @@ void TextCtrl::BUILD() {
text_value = wxString::Format(_T("%i"), int(m_opt.default_value->getFloat()));
text_value += "%";
break;
}
}
case coPercents:
case coFloats:
case coFloat:
{
double val = m_opt.type == coFloats ?
m_opt.get_default_value<ConfigOptionFloats>()->get_at(m_opt_idx) :
m_opt.type == coFloat ?
m_opt.type == coFloat ?
m_opt.default_value->getFloat() :
m_opt.get_default_value<ConfigOptionPercents>()->get_at(m_opt_idx);
text_value = double_to_string(val);
m_last_meaningful_value = text_value;
break;
}
case coString:
case coString:
text_value = m_opt.get_default_value<ConfigOptionString>()->value;
break;
case coStrings:
@ -456,7 +456,7 @@ void TextCtrl::BUILD() {
text_value = get_thumbnails_string(m_opt.get_default_value<ConfigOptionPoints>()->values);
break;
default:
break;
break;
}
const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/;
@ -490,7 +490,7 @@ void TextCtrl::BUILD() {
}
temp->Bind(wxEVT_SET_FOCUS, ([this](wxEvent& e) { on_set_focus(e); }), temp->GetId());
temp->Bind(wxEVT_LEFT_DOWN, ([temp](wxEvent& event)
{
//! to allow the default handling
@ -508,7 +508,7 @@ void TextCtrl::BUILD() {
{
e.Skip();
#ifdef __WXOSX__
// OSX issue: For some unknown reason wxEVT_KILL_FOCUS is emitted twice in a row in some cases
// OSX issue: For some unknown reason wxEVT_KILL_FOCUS is emitted twice in a row in some cases
// (like when information dialog is shown during an update of the option value)
// Thus, suppress its second call
if (bKilledFocus)
@ -539,7 +539,7 @@ void TextCtrl::BUILD() {
*/
// recast as a wxWindow to fit the calling convention
window = dynamic_cast<wxWindow*>(temp);
}
}
bool TextCtrl::value_was_changed()
{
@ -559,7 +559,7 @@ bool TextCtrl::value_was_changed()
case coPercents:
case coFloats:
case coFloat: {
if (m_opt.nullable && std::isnan(boost::any_cast<double>(m_value)) &&
if (m_opt.nullable && std::isnan(boost::any_cast<double>(m_value)) &&
std::isnan(boost::any_cast<double>(val)))
return false;
return boost::any_cast<double>(m_value) != boost::any_cast<double>(val);
@ -597,9 +597,9 @@ void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/)
if (!change_event) {
wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue();
/* Update m_value to correct work of next value_was_changed().
* But after checking of entered value, don't fix the "incorrect" value and don't show a warning message,
* just clear m_value in this case.
/* Update m_value to correct work of next value_was_changed().
* But after checking of entered value, don't fix the "incorrect" value and don't show a warning message,
* just clear m_value in this case.
*/
get_value_by_opt_type(ret_str, false);
}
@ -631,7 +631,7 @@ void TextCtrl::msw_rescale()
Field::msw_rescale();
auto size = wxSize(def_width() * m_em_unit, wxDefaultCoord);
if (m_opt.height >= 0)
if (m_opt.height >= 0)
size.SetHeight(m_opt.height*m_em_unit);
else if (parent_is_custom_ctrl && opt_height > 0)
size.SetHeight(lround(opt_height*m_em_unit));
@ -665,15 +665,15 @@ void CheckBox::BUILD() {
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
bool check_value = m_opt.type == coBool ?
m_opt.default_value->getBool() : m_opt.type == coBools ?
m_opt.get_default_value<ConfigOptionBools>()->get_at(m_opt_idx) :
bool check_value = m_opt.type == coBool ?
m_opt.default_value->getBool() : m_opt.type == coBools ?
m_opt.get_default_value<ConfigOptionBools>()->get_at(m_opt_idx) :
false;
m_last_meaningful_value = static_cast<unsigned char>(check_value);
// Set Label as a string of at least one space simbol to correct system scaling of a CheckBox
auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size);
// Set Label as a string of at least one space simbol to correct system scaling of a CheckBox
auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size);
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
temp->SetValue(check_value);
@ -684,7 +684,7 @@ void CheckBox::BUILD() {
on_change_field();
}), temp->GetId());
temp->SetToolTip(get_tooltip_text(check_value ? "true" : "false"));
temp->SetToolTip(get_tooltip_text(check_value ? "true" : "false"));
// recast as a wxWindow to fit the calling convention
window = dynamic_cast<wxWindow*>(temp);
@ -770,14 +770,14 @@ void SpinCtrl::BUILD() {
break;
}
const int min_val = m_opt.min == INT_MIN
const int min_val = m_opt.min == INT_MIN
#ifdef __WXOSX__
// We will forcibly set the input value for SpinControl, since the value
// We will forcibly set the input value for SpinControl, since the value
// inserted from the keyboard is not updated under OSX.
// So, we can't set min control value bigger then 0.
// Otherwise, it couldn't be possible to input from keyboard value
// Otherwise, it couldn't be possible to input from keyboard value
// less then min_val.
|| m_opt.min > 0
|| m_opt.min > 0
#endif
? 0 : m_opt.min;
const int max_val = m_opt.max < 2147483647 ? m_opt.max : 2147483647;
@ -813,8 +813,8 @@ void SpinCtrl::BUILD() {
propagate_value();
}));
temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { propagate_value(); }), temp->GetId());
temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { propagate_value(); }), temp->GetId());
temp->Bind(wxEVT_TEXT_ENTER, ([this](wxCommandEvent e)
{
e.Skip();
@ -835,7 +835,7 @@ void SpinCtrl::BUILD() {
tmp_value = parsed && value >= INT_MIN && value <= INT_MAX ? (int)value : UNDEF_VALUE;
#ifdef __WXOSX__
// Forcibly set the input value for SpinControl, since the value
// Forcibly set the input value for SpinControl, since the value
// inserted from the keyboard or clipboard is not updated under OSX
if (tmp_value != UNDEF_VALUE) {
wxSpinCtrl* spin = static_cast<wxSpinCtrl*>(window);
@ -847,7 +847,7 @@ void SpinCtrl::BUILD() {
}
#endif
}), temp->GetId());
temp->SetToolTip(get_tooltip_text(text_value));
// recast as a wxWindow to fit the calling convention
@ -899,7 +899,7 @@ void Choice::BUILD() {
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
choice_ctrl* temp;
choice_ctrl* temp;
if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) {
m_is_editable = true;
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size);
@ -1051,10 +1051,10 @@ void Choice::set_value(const std::string& value, bool change_event) //! Redunda
}
choice_ctrl* field = dynamic_cast<choice_ctrl*>(window);
idx == m_opt.enum_values.size() ?
idx == m_opt.enum_values.size() ?
field->SetValue(value) :
field->SetSelection(idx);
m_disable_change_event = false;
}
@ -1072,7 +1072,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
case coString:
case coStrings: {
wxString text_value;
if (m_opt.type == coInt)
if (m_opt.type == coInt)
text_value = wxString::Format(_T("%i"), int(boost::any_cast<int>(value)));
else
text_value = boost::any_cast<wxString>(value);
@ -1100,7 +1100,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
{
if (!m_opt.enum_values.empty()) {
std::string key;
t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values();
t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values();
for (auto it : map_names) {
if (val == it.second) {
key = it.first;
@ -1175,7 +1175,7 @@ boost::any& Choice::get_value()
{
choice_ctrl* field = dynamic_cast<choice_ctrl*>(window);
wxString ret_str = field->GetValue();
wxString ret_str = field->GetValue();
// options from right panel
std::vector <std::string> right_panel_options{ "support", "pad", "scale_unit" };
@ -1185,7 +1185,7 @@ boost::any& Choice::get_value()
if (m_opt.type == coEnum)
{
int ret_enum = field->GetSelection();
int ret_enum = field->GetSelection();
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "fill_pattern")
{
if (!m_opt.enum_values.empty()) {
@ -1222,6 +1222,9 @@ boost::any& Choice::get_value()
m_value = static_cast<AuthorizationType>(ret_enum);
else if (m_opt_id == "brim_type")
m_value = static_cast<BrimType>(ret_enum);
else if (m_opt_id == "raft_size_adjust")
m_value = static_cast<RaftSizeAdjust>(ret_enum);
}
else if (m_opt.gui_type == "f_enum_open") {
const int ret_enum = field->GetSelection();
@ -1234,7 +1237,7 @@ boost::any& Choice::get_value()
else
m_value = atof(m_opt.enum_values[ret_enum].c_str());
}
else
else
// modifies ret_string!
get_value_by_opt_type(ret_str);
@ -1252,8 +1255,8 @@ void Choice::msw_rescale()
#ifdef __WXOSX__
const wxString selection = field->GetValue();// field->GetString(index);
/* To correct scaling (set new controll size) of a wxBitmapCombobox
* we need to refill control with new bitmaps. So, in our case :
/* To correct scaling (set new controll size) of a wxBitmapCombobox
* we need to refill control with new bitmaps. So, in our case :
* 1. clear control
* 2. add content
* 3. add scaled "empty" bitmap to the at least one item
@ -1261,7 +1264,7 @@ void Choice::msw_rescale()
field->Clear();
wxSize size(wxDefaultSize);
size.SetWidth((m_opt.width > 0 ? m_opt.width : def_width_wider()) * m_em_unit);
// Set rescaled min height to correct layout
field->SetMinSize(wxSize(-1, int(1.5f*field->GetFont().GetPixelSize().y + 0.5f)));
// Set rescaled size
@ -1373,7 +1376,7 @@ void ColourPicker::msw_rescale()
wxColourPickerCtrl* field = dynamic_cast<wxColourPickerCtrl*>(window);
auto size = wxSize(def_width() * m_em_unit, wxDefaultCoord);
if (m_opt.height >= 0)
if (m_opt.height >= 0)
size.SetHeight(m_opt.height * m_em_unit);
else if (parent_is_custom_ctrl && opt_height > 0)
size.SetHeight(lround(opt_height * m_em_unit));
@ -1509,7 +1512,7 @@ boost::any& PointCtrl::get_value()
else
if (m_opt.min > x || x > m_opt.max ||
m_opt.min > y || y > m_opt.max)
{
{
if (m_opt.min > x) x = m_opt.min;
if (x > m_opt.max) x = m_opt.max;
if (m_opt.min > y) y = m_opt.min;
@ -1575,7 +1578,7 @@ void SliderCtrl::BUILD()
m_slider->SetBackgroundStyle(wxBG_STYLE_PAINT);
wxSize field_size(40, -1);
m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale),
m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale),
wxDefaultPosition, field_size);
m_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font());
m_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT);
@ -1625,5 +1628,3 @@ boost::any& SliderCtrl::get_value()
} // GUI
} // Slic3r

View File

@ -36,7 +36,7 @@ void disable_screensaver()
#if __APPLE__
CFStringRef reasonForActivity = CFSTR("Slic3r");
[[maybe_unused]]IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
// ignore result: success == kIOReturnSuccess
#elif _WIN32
SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_CONTINUOUS);
@ -71,7 +71,7 @@ void break_to_debugger()
const std::string& shortkey_ctrl_prefix()
{
static const std::string str =
static const std::string str =
#ifdef __APPLE__
""
#else
@ -83,7 +83,7 @@ const std::string& shortkey_ctrl_prefix()
const std::string& shortkey_alt_prefix()
{
static const std::string str =
static const std::string str =
#ifdef __APPLE__
""
#else
@ -132,13 +132,13 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
ConfigOptionFloats* vec_new = new ConfigOptionFloats{ boost::any_cast<double>(value) };
config.option<ConfigOptionFloats>(opt_key)->set_at(vec_new, opt_index, opt_index);
break;
}
}
case coString:
config.set_key_value(opt_key, new ConfigOptionString(boost::any_cast<std::string>(value)));
break;
case coStrings:{
if (opt_key == "compatible_prints" || opt_key == "compatible_printers") {
config.option<ConfigOptionStrings>(opt_key)->values =
config.option<ConfigOptionStrings>(opt_key)->values =
boost::any_cast<std::vector<std::string>>(value);
}
else if (config.def()->get(opt_key)->gui_flags.compare("serialized") == 0) {
@ -179,17 +179,17 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
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)));
config.set_key_value(opt_key, new ConfigOptionEnum<InfillPattern>(boost::any_cast<InfillPattern>(value)));
else if (opt_key.compare("ironing_type") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<IroningType>(boost::any_cast<IroningType>(value)));
config.set_key_value(opt_key, new ConfigOptionEnum<IroningType>(boost::any_cast<IroningType>(value)));
else if (opt_key.compare("fuzzy_skin_perimeter_mode") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<FuzzySkinPerimeterMode>(boost::any_cast<FuzzySkinPerimeterMode>(value)));
config.set_key_value(opt_key, new ConfigOptionEnum<FuzzySkinPerimeterMode>(boost::any_cast<FuzzySkinPerimeterMode>(value)));
// else if (opt_key.compare("fuzzy_skin_shape") == 0)
// config.set_key_value(opt_key, new ConfigOptionEnum<FuzzySkinShape>(boost::any_cast<FuzzySkinShape>(value)));
// config.set_key_value(opt_key, new ConfigOptionEnum<FuzzySkinShape>(boost::any_cast<FuzzySkinShape>(value)));
else if (opt_key.compare("gcode_flavor") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<GCodeFlavor>(boost::any_cast<GCodeFlavor>(value)));
config.set_key_value(opt_key, new ConfigOptionEnum<GCodeFlavor>(boost::any_cast<GCodeFlavor>(value)));
else if (opt_key.compare("machine_limits_usage") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<MachineLimitsUsage>(boost::any_cast<MachineLimitsUsage>(value)));
config.set_key_value(opt_key, new ConfigOptionEnum<MachineLimitsUsage>(boost::any_cast<MachineLimitsUsage>(value)));
else if (opt_key.compare("support_material_pattern") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialPattern>(boost::any_cast<SupportMaterialPattern>(value)));
else if (opt_key.compare("seam_position") == 0)
@ -204,6 +204,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
config.set_key_value(opt_key, new ConfigOptionEnum<AuthorizationType>(boost::any_cast<AuthorizationType>(value)));
else if(opt_key == "brim_type")
config.set_key_value(opt_key, new ConfigOptionEnum<BrimType>(boost::any_cast<BrimType>(value)));
else if (opt_key == "raft_size_adjust")
config.set_key_value(opt_key, new ConfigOptionEnum<RaftSizeAdjust>(boost::any_cast<RaftSizeAdjust>(value)));
}
break;
case coPoints:{

View File

@ -30,7 +30,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
m_fields.emplace(id, Choice::Create<Choice>(this->ctrl_parent(), opt, id));
} else if (opt.gui_type == "color") {
m_fields.emplace(id, ColourPicker::Create<ColourPicker>(this->ctrl_parent(), opt, id));
} else if (opt.gui_type == "f_enum_open" ||
} else if (opt.gui_type == "f_enum_open" ||
opt.gui_type == "i_enum_open" ||
opt.gui_type == "i_enum_closed") {
m_fields.emplace(id, Choice::Create<Choice>(this->ctrl_parent(), opt, id));
@ -41,7 +41,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
m_fields.emplace(id, StaticText::Create<StaticText>(this->ctrl_parent(), opt, id));
} else if (opt.gui_type == "one_string") {
m_fields.emplace(id, TextCtrl::Create<TextCtrl>(this->ctrl_parent(), opt, id));
} else {
} else {
switch (opt.type) {
case coFloatOrPercent:
case coFloat:
@ -74,19 +74,19 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
// Grab a reference to fields for convenience
const t_field& field = m_fields[id];
field->m_on_change = [this](const std::string& opt_id, const boost::any& value) {
//! This function will be called from Field.
//! This function will be called from Field.
//! Call OptionGroup._on_change(...)
if (!m_disabled)
if (!m_disabled)
this->on_change_OG(opt_id, value);
};
field->m_on_kill_focus = [this](const std::string& opt_id) {
//! This function will be called from Field.
if (!m_disabled)
//! This function will be called from Field.
if (!m_disabled)
this->on_kill_focus(opt_id);
};
field->m_on_set_focus = [this](const std::string& opt_id) {
//! This function will be called from Field.
if (!m_disabled)
//! This function will be called from Field.
if (!m_disabled)
this->on_set_focus(opt_id);
};
field->m_parent = parent();
@ -99,7 +99,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
if (!this->m_disabled)
this->back_to_sys_value(opt_id);
};
// assign function objects for callbacks, etc.
return field;
}
@ -178,7 +178,7 @@ void OptionsGroup::append_line(const Line& line)
return;
auto option_set = line.get_options();
for (auto opt : option_set)
for (auto opt : option_set)
m_options.emplace(opt.opt_id, opt);
// add mode value for current line to m_options_mode
@ -232,7 +232,7 @@ void OptionsGroup::activate_line(Line& line)
// if we have a single option with no label, no sidetext just add it directly to sizer
if (option_set.size() == 1 && label_width == 0 && option_set.front().opt.full_width &&
option_set.front().opt.label.empty() &&
option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr &&
option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr &&
line.get_extra_widgets().size() == 0) {
const auto& option = option_set.front();
@ -334,7 +334,7 @@ void OptionsGroup::activate_line(Line& line)
wxString str_label = (option.label == L_CONTEXT("Top", "Layers") || option.label == L_CONTEXT("Bottom", "Layers")) ?
_CTX(option.label, "Layers") :
_(option.label);
label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, //wxDefaultSize);
label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, //wxDefaultSize);
wxSize(sublabel_width != -1 ? sublabel_width * wxGetApp().em_unit() : -1, -1), wxALIGN_RIGHT);
label->SetBackgroundStyle(wxBG_STYLE_PAINT);
label->SetFont(wxGetApp().normal_font());
@ -379,7 +379,7 @@ void OptionsGroup::activate_line(Line& line)
}
// add extra sizers if any
for (auto extra_widget : line.get_extra_widgets())
for (auto extra_widget : line.get_extra_widgets())
{
if (line.get_extra_widgets().size() == 1 && !staticbox)
{
@ -504,7 +504,7 @@ void OptionsGroup::clear_fields_except_of(const std::vector<std::string> left_fi
while (it != m_fields.end()) {
if (std::find(left_fields.begin(), left_fields.end(), it->first) == left_fields.end())
it = m_fields.erase(it);
else
else
it++;
}
}
@ -530,7 +530,7 @@ Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index
std::pair<std::string, int> pair(opt_key, opt_index);
m_opt_map.emplace(opt_id, pair);
if (m_use_custom_ctrl) // fill group and category values just for options from Settings Tab
if (m_use_custom_ctrl) // fill group and category values just for options from Settings Tab
wxGetApp().sidebar().get_searcher().add_key(opt_id, title, this->config_category());
return Option(*m_config->def()->get(opt_key), opt_id);
@ -545,7 +545,7 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b
{
OptionsGroup::on_change_OG(opt_id, value);
return;
}
}
auto itOption = it->second;
const std::string &opt_key = itOption.first;
@ -554,7 +554,7 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b
this->change_opt_value(opt_key, value, opt_index == -1 ? 0 : opt_index);
}
OptionsGroup::on_change_OG(opt_id, value);
OptionsGroup::on_change_OG(opt_id, value);
}
void ConfigOptionsGroup::back_to_initial_value(const std::string& opt_key)
@ -582,7 +582,7 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config,
}
else if (m_opt_map.find(opt_key) == m_opt_map.end() ||
// This option don't have corresponded field
opt_key == "bed_shape" || opt_key == "filament_ramming_parameters" ||
opt_key == "bed_shape" || opt_key == "filament_ramming_parameters" ||
opt_key == "compatible_printers" || opt_key == "compatible_prints" ) {
value = get_config_value(config, opt_key);
this->change_opt_value(opt_key, value);
@ -765,7 +765,7 @@ boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_
boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index /*= -1*/)
{
size_t idx = opt_index == -1 ? 0 : opt_index;
boost::any ret;
wxString text_value = wxString("");
const ConfigOptionDef* opt = config.def()->get(opt_key);
@ -901,6 +901,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
}
else if (opt_key == "brim_type") {
ret = static_cast<int>(config.option<ConfigOptionEnum<BrimType>>(opt_key)->value);
}
else if (opt_key == "raft_size_adjust") {
ret = static_cast<int>(config.option<ConfigOptionEnum<RaftSizeAdjust>>(opt_key)->value);
}
}
break;
@ -958,7 +961,7 @@ void ConfigOptionsGroup::change_opt_value(const t_config_option_key& opt_key, co
m_modelconfig->touch();
}
ogStaticText::ogStaticText(wxWindow* parent, const wxString& text) :
ogStaticText::ogStaticText(wxWindow* parent, const wxString& text) :
wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize)
{
if (!text.IsEmpty()) {

View File

@ -1941,7 +1941,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor.
"layer_height", "first_layer_height", "min_layer_height", "max_layer_height",
"brim_width", "perimeters", "perimeter_extruder", "fill_density", "infill_extruder", "top_solid_layers",
"support_material", "support_material_extruder", "support_material_interface_extruder", "support_material_contact_distance", "raft_layers"
"support_material", "support_material_extruder", "support_material_interface_extruder", "support_material_contact_distance", "raft_layers",
"raft_overhangs", "raft_contact_distance", "raft_xy_size_compensation", "raft_size_adjust"
}))
, sidebar(new Sidebar(q))
, m_ui_jobs(this)

View File

@ -1500,7 +1500,11 @@ void TabPrint::build()
optgroup = page->new_optgroup(L("Raft"));
optgroup->append_single_option_line("raft_layers", category_path + "raft-layers");
// # optgroup->append_single_option_line(get_option_("raft_contact_distance");
// RaftingEdition
optgroup->append_single_option_line("raft_overhangs");
optgroup->append_single_option_line("raft_contact_distance");
optgroup->append_single_option_line("raft_xy_size_compensation");
optgroup->append_single_option_line("raft_size_adjust");
optgroup = page->new_optgroup(L("Options for support material and raft"));
optgroup->append_single_option_line("support_material_contact_distance", category_path + "contact-z-distance");