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.