diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 9270d3887..2857b428e 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -174,6 +174,7 @@ int CLI::run(int argc, char **argv) m_print_config.apply(fff_print_config, true); } else if (printer_technology == ptSLA) { // The default value has to be different from the one in fff mode. + sla_print_config.printer_technology.value = ptSLA; sla_print_config.output_filename_format.value = "[input_filename_base].sl1"; // The default bed shape should reflect the default display parameters @@ -186,6 +187,8 @@ int CLI::run(int argc, char **argv) m_print_config.apply(sla_print_config, true); } + double min_obj_dist = min_object_distance(m_print_config); + // Loop through transform options. bool user_center_specified = false; for (auto const &opt_key : m_transforms) { @@ -199,7 +202,7 @@ int CLI::run(int argc, char **argv) m.add_default_instances(); const BoundingBoxf &bb = fff_print_config.bed_shape.values; m.arrange_objects( - fff_print_config.min_object_distance(), + min_obj_dist, // If we are going to use the merged model for printing, honor // the configured print bed for arranging, otherwise do it freely. this->has_print_action() ? &bb : nullptr @@ -216,10 +219,10 @@ int CLI::run(int argc, char **argv) ); if (all_objects_have_instances) { // if all input objects have defined position(s) apply duplication to the whole model - model.duplicate(m_config.opt_int("duplicate"), fff_print_config.min_object_distance(), &bb); + model.duplicate(m_config.opt_int("duplicate"), min_obj_dist, &bb); } else { model.add_default_instances(); - model.duplicate_objects(m_config.opt_int("duplicate"), fff_print_config.min_object_distance(), &bb); + model.duplicate_objects(m_config.opt_int("duplicate"), min_obj_dist, &bb); } } } else if (opt_key == "duplicate_grid") { @@ -424,7 +427,7 @@ int CLI::run(int argc, char **argv) PrintBase *print = (printer_technology == ptFFF) ? static_cast(&fff_print) : static_cast(&sla_print); if (! m_config.opt_bool("dont_arrange")) { //FIXME make the min_object_distance configurable. - model.arrange_objects(fff_print.config().min_object_distance()); + model.arrange_objects(min_obj_dist); model.center_instances_around_point((! user_center_specified && m_print_config.has("bed_shape")) ? BoundingBoxf(m_print_config.opt("bed_shape")->values).center() : m_config.option("center")->value); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index c7a7a9c8e..cba027d66 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3060,6 +3060,42 @@ DynamicPrintConfig* DynamicPrintConfig::new_from_defaults_keys(const std::vector return out; } +double min_object_distance(const ConfigBase &cfg) +{ + double ret = 0.; + + if (printer_technology(cfg) == ptSLA) ret = 6.; + else { + auto ecr_opt = cfg.option("extruder_clearance_radius"); + auto dd_opt = cfg.option("duplicate_distance"); + auto co_opt = cfg.option("complete_objects"); + + if (!ecr_opt || !dd_opt || !co_opt) ret = 0.; + else { + // min object distance is max(duplicate_distance, clearance_radius) + ret = (co_opt->value && ecr_opt->value > dd_opt->value) ? + ecr_opt->value : dd_opt->value; + } + } + + return ret; +} + +PrinterTechnology printer_technology(const ConfigBase &cfg) +{ + const ConfigOptionEnum *opt = cfg.option>("printer_technology"); + + if (opt) return opt->value; + + const ConfigOptionBool *export_opt = cfg.option("export_sla"); + if (export_opt && export_opt->getBool()) return ptSLA; + + export_opt = cfg.option("export_gcode"); + if (export_opt && export_opt->getBool()) return ptFFF; + + return ptUnknown; +} + void DynamicPrintConfig::normalize() { if (this->has("extruder")) { @@ -3130,22 +3166,6 @@ std::string DynamicPrintConfig::validate() } } -double PrintConfig::min_object_distance() const -{ - return PrintConfig::min_object_distance(static_cast(this)); -} - -double PrintConfig::min_object_distance(const ConfigBase *config) -{ - double extruder_clearance_radius = config->option("extruder_clearance_radius")->getFloat(); - double duplicate_distance = config->option("duplicate_distance")->getFloat(); - - // min object distance is max(duplicate_distance, clearance_radius) - return (config->option("complete_objects")->getBool() && extruder_clearance_radius > duplicate_distance) - ? extruder_clearance_radius - : duplicate_distance; -} - //FIXME localize this function. std::string FullPrintConfig::validate() { diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index ca509e37a..695629416 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -194,6 +194,9 @@ extern const PrintConfigDef print_config_def; class StaticPrintConfig; +PrinterTechnology printer_technology(const ConfigBase &cfg); +double min_object_distance(const ConfigBase &cfg); + // Slic3r dynamic configuration, used to override the configuration // per object, per modification volume or per printing material. // The dynamic configuration is also used to store user modifications of the print global parameters, @@ -749,8 +752,6 @@ class PrintConfig : public MachineEnvelopeConfig, public GCodeConfig STATIC_PRINT_CONFIG_CACHE_DERIVED(PrintConfig) PrintConfig() : MachineEnvelopeConfig(0), GCodeConfig(0) { initialize_cache(); *this = s_cache_PrintConfig.defaults(); } public: - double min_object_distance() const; - static double min_object_distance(const ConfigBase *config); ConfigOptionBool avoid_crossing_perimeters; ConfigOptionPoints bed_shape; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c7c5798ce..55772f456 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2868,13 +2868,8 @@ void Plater::priv::find_new_position(const ModelInstancePtrs &instances, void Plater::priv::ArrangeJob::process() { static const auto arrangestr = _L("Arranging"); - // FIXME: I don't know how to obtain the minimum distance, it depends - // on printer technology. I guess the following should work but it crashes. - double dist = 6; // PrintConfig::min_object_distance(config); - if (plater().printer_technology == ptFFF) { - dist = PrintConfig::min_object_distance(plater().config); - } - + double dist = min_object_distance(*plater().config); + coord_t min_d = scaled(dist); auto count = unsigned(m_selected.size() + m_unprintable.size()); arrangement::BedShapeHint bedshape = plater().get_bed_shape_hint(); diff --git a/tests/fff_print/test_data.cpp b/tests/fff_print/test_data.cpp index c2c6a5f33..77c82d77b 100644 --- a/tests/fff_print/test_data.cpp +++ b/tests/fff_print/test_data.cpp @@ -167,7 +167,7 @@ void init_print(std::vector &&meshes, Slic3r::Print &print, Slic3r object->add_volume(std::move(t)); object->add_instance(); } - model.arrange_objects(PrintConfig::min_object_distance(&config)); + model.arrange_objects(min_object_distance(config)); model.center_instances_around_point(Slic3r::Vec2d(100, 100)); for (ModelObject *mo : model.objects) { mo->ensure_on_bed(); diff --git a/tests/fff_print/test_model.cpp b/tests/fff_print/test_model.cpp index 3378a8363..addb2cd7a 100644 --- a/tests/fff_print/test_model.cpp +++ b/tests/fff_print/test_model.cpp @@ -41,7 +41,7 @@ SCENARIO("Model construction", "[Model]") { } } model_object->add_instance(); - model.arrange_objects(PrintConfig::min_object_distance(&config)); + model.arrange_objects(min_object_distance(config)); model.center_instances_around_point(Slic3r::Vec2d(100, 100)); model_object->ensure_on_bed(); print.auto_assign_extruders(model_object); diff --git a/xs/xsp/Config.xsp b/xs/xsp/Config.xsp index 435dda5a2..63dc5b312 100644 --- a/xs/xsp/Config.xsp +++ b/xs/xsp/Config.xsp @@ -50,7 +50,7 @@ void erase(t_config_option_key opt_key); void normalize(); %name{setenv} void setenv_(); - double min_object_distance() %code{% PrintConfig cfg; cfg.apply(*THIS, true); RETVAL = cfg.min_object_distance(); %}; + double min_object_distance() %code{% RETVAL = Slic3r::min_object_distance(*THIS); %}; static DynamicPrintConfig* load(char *path) %code%{ auto config = new DynamicPrintConfig(); @@ -114,7 +114,7 @@ } %}; %name{setenv} void setenv_(); - double min_object_distance() %code{% RETVAL = PrintConfig::min_object_distance(THIS); %}; + double min_object_distance() %code{% RETVAL = Slic3r::min_object_distance(*THIS); %}; static StaticPrintConfig* load(char *path) %code%{ auto config = new FullPrintConfig();