diff --git a/src/libnest2d/include/libnest2d/geometry_traits.hpp b/src/libnest2d/include/libnest2d/geometry_traits.hpp index 5df87c5ba5..f93e4495e0 100644 --- a/src/libnest2d/include/libnest2d/geometry_traits.hpp +++ b/src/libnest2d/include/libnest2d/geometry_traits.hpp @@ -203,6 +203,20 @@ public: inline Unit area() const BP2D_NOEXCEPT { return Unit(width())*height(); } + + _Box intersection(_Box other) { + _Box inter; + inter.p1.x() = std::max(p1.x(), other.p1.x()); + inter.p1.y() = std::max(p1.y(), other.p1.y()); + inter.p2.x() = std::min(p2.x(), other.p2.x()); + inter.p2.y() = std::min(p2.y(), other.p2.y()); + inter.defined = true; + if (inter.p2.y() < inter.p1.y() || inter.p2.x() < inter.p1.x()) { + inter.p2 = inter.p1; + inter.defined = false; + } + return inter; + } static inline _Box infinite(const P ¢er = {TCoord

(0), TCoord

(0)}); }; diff --git a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp index d70c5cb8f0..9e0e7149eb 100644 --- a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp +++ b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp @@ -1083,9 +1083,13 @@ private: auto d = cb - ci; // BBS TODO we assume the exclude region contains bottom left corner. If not, change the code below - if (!config_.m_excluded_regions.empty()) { - d.x() = d.x() < 0 ? 0 : d.x(); - d.y() = d.y() < 0 ? 0 : d.y(); + if (!config_.m_excluded_regions.empty()) { // do not move to left to much to avoid clash with excluded regions + if (d.x() < 0) { + d.x() = 0;// std::max(long(d.x()), long(bbin.maxCorner().x() - bb.maxCorner().x())); + } + if (d.y() < 0) { + d.y() = 0;// std::max(long(d.y()), long(bbin.maxCorner().y() - bb.maxCorner().y())); + } } for(Item& item : items_) if (!item.is_virt_object) diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index c184e1039e..f0f7f351b5 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -136,6 +136,25 @@ static double fixed_overfit(const std::tuple& result, const Box &bi return score; } +// useful for arranging big circle objects +static double fixed_overfit_topright_sliding(const std::tuple& result, const Box& binbb) +{ + double score = std::get<0>(result); + Box pilebb = std::get<1>(result); + + auto shift = binbb.maxCorner() - pilebb.maxCorner(); + shift.x() = std::max(0, shift.x()); // do not allow left shift + shift.y() = std::max(0, shift.y()); // do not allow bottom shift + pilebb.minCorner() += shift; + pilebb.maxCorner() += shift; + + Box fullbb = sl::boundingBox(pilebb, binbb); + auto diff = double(fullbb.area()) - binbb.area(); + if (diff > 0) score += diff; + + return score; +} + // A class encapsulating the libnest2d Nester class and extending it with other // management and spatial index structures for acceleration. template @@ -503,8 +522,9 @@ public: break; } } + cfg.object_function = [this, bb, starting_point](const Item& item) { - return fixed_overfit(objfunc(item, starting_point), bb); + return fixed_overfit_topright_sliding(objfunc(item, starting_point), bb); }; }; diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index 98d8a7e711..d9a510a45b 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -65,8 +65,7 @@ struct ArrangePolygon { int itemid{ 0 }; // item id in the vector, used for accessing all possible params like extrude_id int is_applied{ 0 }; // transform has been applied double height{ 0 }; // item height - double auto_brim_width{ 0 }; // auto brim width - double user_brim_width{ 0 }; // user defined brim width + double brim_width{ 0 }; // brim width std::string name; // If empty, any rotation is allowed (currently unsupported) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 349e8f513b..5f9c8c1cbc 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -2885,6 +2885,14 @@ double getTemperatureFromExtruder(const ModelVolumePtrs objectVolumes) { #endif } +double ModelInstance::get_auto_brim_width() const +{ + double adhcoeff = getadhesionCoeff(object->volumes); + double DeltaT = getTemperatureFromExtruder(object->volumes); + // get auto brim width (Note even if the global brim_type=btOuterBrim, we can still go into this branch) + return get_auto_brim_width(DeltaT, adhcoeff); +} + void ModelInstance::get_arrange_polygon(void* ap) const { // static const double SIMPLIFY_TOLERANCE_MM = 0.1; @@ -2924,18 +2932,6 @@ void ModelInstance::get_arrange_polygon(void* ap) const ret.extrude_ids = volume->get_extruders(); if (ret.extrude_ids.empty()) //the default extruder ret.extrude_ids.push_back(1); - - // get user specified brim width per object - // Note: if global brim_type=btNoBrim or brAutoBrim, user can't set individual brim_width - if (object->config.has("brim_width")) - ret.user_brim_width = object->config.opt_float("brim_width"); - else { - // BBS: get DeltaT, adhcoeff before calculating brim width - double adhcoeff = getadhesionCoeff(object->volumes); - double DeltaT = getTemperatureFromExtruder(object->volumes); - // get auto brim width (Note even if the global brim_type=btOuterBrim, we can still go into this branch) - ret.auto_brim_width = get_auto_brim_width(DeltaT, adhcoeff); - } } indexed_triangle_set FacetsAnnotation::get_facets(const ModelVolume& mv, EnforcerBlockerType type) const diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index ed27749138..b9aca56de6 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -297,6 +297,12 @@ public: const Model* get_model() const { return m_model; } // BBS: production extension int get_backup_id() const; + template const T* get_config_value(const DynamicPrintConfig& global_config, const std::string& config_option) { + if (config.has(config_option)) + return static_cast(config.option(config_option)); + else + return global_config.option(config_option); + } ModelVolume* add_volume(const TriangleMesh &mesh); ModelVolume* add_volume(TriangleMesh &&mesh, ModelVolumeType type = ModelVolumeType::MODEL_PART); @@ -1083,6 +1089,7 @@ public: //BBS double get_auto_brim_width(double deltaT, double adhension) const; + double get_auto_brim_width() const; // BBS Polygon convex_hull_2d(); void invalidate_convex_hull_2d(); diff --git a/src/libslic3r/ModelArrange.cpp b/src/libslic3r/ModelArrange.cpp index 00e39aa3f1..6501799029 100644 --- a/src/libslic3r/ModelArrange.cpp +++ b/src/libslic3r/ModelArrange.cpp @@ -144,8 +144,22 @@ ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const Slic3r:: for (int i = 0; i < BedType::btCount; i++) ap.vitrify_temp += tmp * pow(100, BedType::btCount - i - 1); } - ap.height = instance->get_object()->bounding_box().size().z(); - ap.name = instance->get_object()->name; + + // get brim width + auto obj = instance->get_object(); + ap.brim_width = instance->get_auto_brim_width(); + auto brim_type_ptr = obj->get_config_value>(config, "brim_type"); + if (brim_type_ptr) { + auto brim_type = brim_type_ptr->getInt(); + if (brim_type == btOuterOnly) + ap.brim_width = obj->get_config_value(config, "brim_width")->getFloat(); + else if (brim_type == btNoBrim) + ap.brim_width = 0; + } + + + ap.height = obj->bounding_box().size().z(); + ap.name = obj->name; return ap; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d11f0508bf..e07b31ce65 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -361,7 +361,7 @@ public: // float distance_seq_print = 6.; // Used when sequential print is ON // float distance_sla = 6.; float accuracy = 0.65f; // Unused currently - bool enable_rotation = true; + bool enable_rotation = false; bool allow_multi_materials_on_same_plate = true; bool avoid_extrusion_cali_region = true; //BBS: add more arrangeSettings diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 25aaa5f80f..5475820586 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -403,7 +403,7 @@ void ArrangeJob::prepare() int state = m_plater->get_prepare_state(); if (state == Job::JobPrepareState::PREPARE_STATE_DEFAULT) { only_on_partplate = false; - prepare_selected(); + prepare_all(); } else if (state == Job::JobPrepareState::PREPARE_STATE_MENU) { only_on_partplate = true; // only arrange items on current plate @@ -508,16 +508,8 @@ void ArrangeJob::process() double skirt_distance = print.has_skirt() ? print.config().skirt_distance.value : 0; - bool is_auto_brim = print.has_auto_brim(); double brim_max = 0; - if (is_auto_brim) { - brim_max = 0; - std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon ap) { brim_max = std::max(brim_max, ap.auto_brim_width); }); - } - else { - brim_max = print.has_brim() ? print.default_object_config().brim_width : 0; - std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon ap) { brim_max = std::max(brim_max, ap.user_brim_width); }); - } + std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon ap) { brim_max = std::max(brim_max, ap.brim_width); }); // Note: skirt_distance is now defined between outermost brim and skirt, not the object and skirt. // So we can't do max but do adding instead.