Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortamasmeszaros <meszaros.q@gmail.com>2018-08-07 20:48:00 +0300
committertamasmeszaros <meszaros.q@gmail.com>2018-08-07 20:51:23 +0300
commit20b7aad6d1cbb4b282586a3844fb66843c81f10d (patch)
tree649241d67c41b813764ae6ee5eeb87e0cdcec246 /xs/src/libslic3r
parent08fb677583518382f3ff4a42fadc431d0a9870f0 (diff)
Bug fixes for the neighborhood detection
Diffstat (limited to 'xs/src/libslic3r')
-rw-r--r--xs/src/libslic3r/ModelArrange.hpp126
1 files changed, 82 insertions, 44 deletions
diff --git a/xs/src/libslic3r/ModelArrange.hpp b/xs/src/libslic3r/ModelArrange.hpp
index f4ce0daca..952a9e3a6 100644
--- a/xs/src/libslic3r/ModelArrange.hpp
+++ b/xs/src/libslic3r/ModelArrange.hpp
@@ -99,6 +99,7 @@ namespace bgi = boost::geometry::index;
using SpatElement = std::pair<Box, unsigned>;
using SpatIndex = bgi::rtree< SpatElement, bgi::rstar<16, 4> >;
+using ItemGroup = std::vector<std::reference_wrapper<Item>>;
std::tuple<double /*score*/, Box /*farthest point from bin center*/>
objfunc(const PointImpl& bincenter,
@@ -109,24 +110,21 @@ objfunc(const PointImpl& bincenter,
double norm, // A norming factor for physical dimensions
std::vector<double>& areacache, // pile item areas will be cached
// a spatial index to quickly get neighbors of the candidate item
- SpatIndex& spatindex
+ SpatIndex& spatindex,
+ const ItemGroup& remaining
)
{
using pl = PointLike;
using sl = ShapeLike;
+ using Coord = TCoord<PointImpl>;
static const double BIG_ITEM_TRESHOLD = 0.02;
static const double ROUNDNESS_RATIO = 0.5;
static const double DENSITY_RATIO = 1.0 - ROUNDNESS_RATIO;
// We will treat big items (compared to the print bed) differently
-
auto isBig = [&areacache, bin_area](double a) {
- double farea = areacache.empty() ? 0 : areacache.front();
- bool fbig = farea / bin_area > BIG_ITEM_TRESHOLD;
- bool abig = a/bin_area > BIG_ITEM_TRESHOLD;
- bool rbig = fbig && a > 0.5*farea;
- return abig || rbig;
+ return a/bin_area > BIG_ITEM_TRESHOLD ;
};
// If a new bin has been created:
@@ -195,39 +193,74 @@ objfunc(const PointImpl& bincenter,
auto dist = *(std::min_element(dists.begin(), dists.end())) / norm;
// Density is the pack density: how big is the arranged pile
- auto density = std::sqrt(fullbb.width()*fullbb.height()) / norm;
-
- // Prepare a variable for the alignment score.
- // This will indicate: how well is the candidate item aligned with
- // its neighbors. We will check the aligment with all neighbors and
- // return the score for the best alignment. So it is enough for the
- // candidate to be aligned with only one item.
- auto alignment_score = std::numeric_limits<double>::max();
-
- auto& trsh = item.transformedShape();
-
- auto querybb = item.boundingBox();
-
- // Query the spatial index for the neigbours
- std::vector<SpatElement> result;
- spatindex.query(bgi::intersects(querybb), std::back_inserter(result));
+ double density = 0;
+
+ if(remaining.empty()) {
+ pile.emplace_back(item.transformedShape());
+ auto chull = sl::convexHull(pile);
+ pile.pop_back();
+ strategies::EdgeCache<PolygonImpl> ec(chull);
+
+ double circ = ec.circumference() / norm;
+ double bcirc = 2.0*(fullbb.width() + fullbb.height()) / norm;
+ score = 0.5*circ + 0.5*bcirc;
+
+ } else {
+ // Prepare a variable for the alignment score.
+ // This will indicate: how well is the candidate item aligned with
+ // its neighbors. We will check the aligment with all neighbors and
+ // return the score for the best alignment. So it is enough for the
+ // candidate to be aligned with only one item.
+ auto alignment_score = std::numeric_limits<double>::max();
+
+ density = (fullbb.width()*fullbb.height()) / (norm*norm);
+ auto& trsh = item.transformedShape();
+ auto querybb = item.boundingBox();
+ auto wp = querybb.width()*0.2;
+ auto hp = querybb.height()*0.2;
+ auto pad = PointImpl( Coord(wp), Coord(hp));
+ querybb = Box({ querybb.minCorner() - pad,
+ querybb.maxCorner() + pad
+ });
+
+ // Query the spatial index for the neigbours
+ std::vector<SpatElement> result;
+ result.reserve(spatindex.size());
+ spatindex.query(bgi::intersects(querybb),
+ std::back_inserter(result));
+
+// if(result.empty()) {
+// std::cout << "Error while arranging!" << std::endl;
+// std::cout << spatindex.size() << " " << pile.size() << std::endl;
+
+// auto ib = spatindex.bounds();
+// Box ibb;
+// boost::geometry::convert(ib, ibb);
+// std::cout << "Inside: " << (sl::isInside<PolygonImpl>(querybb, ibb) ||
+// boost::geometry::intersects(querybb, ibb)) << std::endl;
+// }
+
+ for(auto& e : result) { // now get the score for the best alignment
+ auto idx = e.second;
+ auto& p = pile[idx];
+ auto parea = areacache[idx];
+ auto bb = sl::boundingBox(sl::Shapes<PolygonImpl>{p, trsh});
+ auto bbarea = bb.area();
+ auto ascore = 1.0 - (item.area() + parea)/bbarea;
+
+ if(ascore < alignment_score) alignment_score = ascore;
+ }
- for(auto& e : result) { // now get the score for the best alignment
- auto idx = e.second;
- auto& p = pile[idx];
- auto parea = areacache[idx];
- auto bb = sl::boundingBox(sl::Shapes<PolygonImpl>{p, trsh});
- auto bbarea = bb.area();
- auto ascore = 1.0 - (item.area() + parea)/bbarea;
+ // The final mix of the score is the balance between the distance
+ // from the full pile center, the pack density and the
+ // alignment with the neigbours
+ if(result.empty())
+ score = 0.5 * dist + 0.5 * density;
+ else
+ score = 0.45 * dist + 0.45 * density + 0.1 * alignment_score;
- if(ascore < alignment_score) alignment_score = ascore;
}
- // The final mix of the score is the balance between the distance
- // from the full pile center, the pack density and the
- // alignment with the neigbours
- score = 0.45 * dist + 0.45 * density + 0.1 * alignment_score;
-
} else if( !isBig(item.area()) && spatindex.empty()) {
// If there are no big items, only small, we should consider the
// density here as well to not get silly results
@@ -312,10 +345,12 @@ public:
const Item &item,
double pile_area,
double norm,
- double /*penality*/) {
+ const ItemGroup& rem) {
auto result = objfunc(bin.center(), bin_area_, pile,
- pile_area, item, norm, areacache_, rtree_);
+ pile_area, item, norm, areacache_,
+ rtree_,
+ rem);
double score = std::get<0>(result);
auto& fullbb = std::get<1>(result);
@@ -346,10 +381,11 @@ public:
const Item &item,
double pile_area,
double norm,
- double /*penality*/) {
+ const ItemGroup& rem) {
auto result = objfunc(bin.center(), bin_area_, pile,
- pile_area, item, norm, areacache_, rtree_);
+ pile_area, item, norm, areacache_,
+ rtree_, rem);
double score = std::get<0>(result);
auto& fullbb = std::get<1>(result);
@@ -391,11 +427,12 @@ public:
const Item &item,
double pile_area,
double norm,
- double /*penality*/) {
+ const ItemGroup& rem) {
auto binbb = ShapeLike::boundingBox(bin);
auto result = objfunc(binbb.center(), bin_area_, pile,
- pile_area, item, norm, areacache_, rtree_);
+ pile_area, item, norm, areacache_,
+ rtree_, rem);
double score = std::get<0>(result);
return score;
@@ -417,10 +454,11 @@ public:
const Item &item,
double pile_area,
double norm,
- double /*penality*/) {
+ const ItemGroup& rem) {
auto result = objfunc({0, 0}, 0, pile, pile_area,
- item, norm, areacache_, rtree_);
+ item, norm, areacache_,
+ rtree_, rem);
return std::get<0>(result);
};