From 1acee8900695b7060f2ee136b4da8e3778b407cb Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 7 Sep 2018 12:03:49 +0200 Subject: Refinements for small item arrangement using the increased cpu power. --- xs/src/libslic3r/ModelArrange.hpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'xs/src/libslic3r') diff --git a/xs/src/libslic3r/ModelArrange.hpp b/xs/src/libslic3r/ModelArrange.hpp index 618230cb7..b1ccf4d13 100644 --- a/xs/src/libslic3r/ModelArrange.hpp +++ b/xs/src/libslic3r/ModelArrange.hpp @@ -130,6 +130,7 @@ objfunc(const PointImpl& bincenter, double norm, // A norming factor for physical dimensions // a spatial index to quickly get neighbors of the candidate item const SpatIndex& spatindex, + const SpatIndex& smalls_spatindex, const ItemGroup& remaining ) { @@ -161,7 +162,7 @@ objfunc(const PointImpl& bincenter, // Will hold the resulting score double score = 0; - if(isBig(item.area())) { + if(isBig(item.area()) || spatindex.empty()) { // This branch is for the bigger items.. auto minc = ibb.minCorner(); // bottom left corner @@ -183,6 +184,8 @@ objfunc(const PointImpl& bincenter, // The smalles distance from the arranged pile center: auto dist = *(std::min_element(dists.begin(), dists.end())) / norm; + auto bindist = pl::distance(ibb.center(), bincenter) / norm; + dist = 0.8*dist + 0.2*bindist; // Density is the pack density: how big is the arranged pile double density = 0; @@ -207,14 +210,20 @@ objfunc(const PointImpl& bincenter, // candidate to be aligned with only one item. auto alignment_score = 1.0; - density = (fullbb.width()*fullbb.height()) / (norm*norm); + density = std::sqrt((fullbb.width() / norm )* + (fullbb.height() / norm)); auto querybb = item.boundingBox(); // Query the spatial index for the neighbors std::vector result; result.reserve(spatindex.size()); - spatindex.query(bgi::intersects(querybb), - std::back_inserter(result)); + if(isBig(item.area())) { + spatindex.query(bgi::intersects(querybb), + std::back_inserter(result)); + } else { + smalls_spatindex.query(bgi::intersects(querybb), + std::back_inserter(result)); + } for(auto& e : result) { // now get the score for the best alignment auto idx = e.second; @@ -235,12 +244,8 @@ objfunc(const PointImpl& bincenter, if(result.empty()) score = 0.5 * dist + 0.5 * density; else - score = 0.45 * dist + 0.45 * density + 0.1 * alignment_score; + score = 0.40 * dist + 0.40 * density + 0.2 * alignment_score; } - } else if( !isBig(item.area()) && spatindex.empty()) { - auto bindist = pl::distance(ibb.center(), bincenter) / norm; - // Bindist is surprisingly enough... - score = bindist; } else { // Here there are the small items that should be placed around the // already processed bigger items. @@ -291,6 +296,7 @@ protected: PConfig pconf_; // Placement configuration double bin_area_; SpatIndex rtree_; + SpatIndex smallsrtree_; double norm_; Pile merged_pile_; Box pilebb_; @@ -317,6 +323,7 @@ public: pilebb_ = sl::boundingBox(merged_pile); rtree_.clear(); + smallsrtree_.clear(); // We will treat big items (compared to the print bed) differently auto isBig = [this](double a) { @@ -326,6 +333,7 @@ public: for(unsigned idx = 0; idx < items.size(); ++idx) { Item& itm = items[idx]; if(isBig(itm.area())) rtree_.insert({itm.boundingBox(), idx}); + smallsrtree_.insert({itm.boundingBox(), idx}); } }; @@ -357,6 +365,7 @@ public: bin_area_, norm_, rtree_, + smallsrtree_, remaining_); double score = std::get<0>(result); @@ -393,6 +402,7 @@ public: bin_area_, norm_, rtree_, + smallsrtree_, remaining_); double score = std::get<0>(result); @@ -435,6 +445,7 @@ public: bin_area_, norm_, rtree_, + smallsrtree_, remaining_); double score = std::get<0>(result); @@ -462,6 +473,7 @@ public: 0, norm_, rtree_, + smallsrtree_, remaining_); return std::get<0>(result); }; -- cgit v1.2.3