Implement correct centroid in DecomposedShape

This commit is contained in:
tamasmeszaros 2023-07-21 17:11:49 +02:00
parent ccc7009719
commit 9c7fd4f692
6 changed files with 81 additions and 6 deletions

View File

@ -19,7 +19,7 @@ struct GravityKernel {
template<class ArrItem>
double placement_fitness(const ArrItem &itm, const Vec2crd &transl) const
{
Vec2d center = unscaled(envelope_bounding_box(itm).center());
Vec2d center = unscaled(envelope_centroid(itm));
center += unscaled(transl);

View File

@ -65,6 +65,8 @@ public:
// Candidate item bounding box
auto ibb = envelope_bounding_box(item);
ibb.translate(transl);
auto itmcntr = envelope_centroid(item);
itmcntr += transl;
// Calculate the full bounding box of the pile with the candidate item
auto fullbb = m_pilebb;
@ -115,7 +117,7 @@ public:
switch (compute_case) {
case WIPE_TOWER: {
score = (unscaled(ibb.center()) - unscaled(active_sink)).squaredNorm();
score = (unscaled(itmcntr) - unscaled(active_sink)).squaredNorm();
break;
}
case BIG_ITEM: {
@ -132,7 +134,7 @@ public:
auto cc = fullbb.center(); // The gravity center
dists[0] = (minc - cc).cast<double>().norm();
dists[1] = (maxc - cc).cast<double>().norm();
dists[2] = (ibb.center() - cc).template cast<double>().norm();
dists[2] = (itmcntr - cc).template cast<double>().norm();
dists[3] = (top_left - cc).cast<double>().norm();
dists[4] = (bottom_right - cc).cast<double>().norm();
@ -191,7 +193,7 @@ public:
break;
}
case LAST_BIG_ITEM: {
score = norm((ibb.center() - m_pilebb.center()).template cast<double>().norm());
score = norm((itmcntr - m_pilebb.center()).template cast<double>().norm());
break;
}
case SMALL_ITEM: {
@ -199,7 +201,7 @@ public:
// already processed bigger items.
// No need to play around with the anchor points, the center will be
// just fine for small items
score = norm((ibb.center() - bigbb.center()).template cast<double>().norm());
score = norm((itmcntr - bigbb.center()).template cast<double>().norm());
break;
}
}

View File

@ -74,6 +74,16 @@ template<class ArrItem, class En = void> struct NFPArrangeItemTraits_
{
return std::array{0.};
}
static Vec2crd fixed_centroid(const ArrItem &itm)
{
return fixed_bounding_box(itm).center();
}
static Vec2crd envelope_centroid(const ArrItem &itm)
{
return envelope_bounding_box(itm).center();
}
};
template<class T>
@ -137,6 +147,16 @@ template<class ArrItem> double fixed_area(const ArrItem &itm)
return NFPArrangeItemTraits<ArrItem>::fixed_area(itm);
}
template<class ArrItem> Vec2crd fixed_centroid(const ArrItem &itm)
{
return NFPArrangeItemTraits<ArrItem>::fixed_centroid(itm);
}
template<class ArrItem> Vec2crd envelope_centroid(const ArrItem &itm)
{
return NFPArrangeItemTraits<ArrItem>::envelope_centroid(itm);
}
template<class ArrItem>
auto allowed_rotations(const ArrItem &itm)
{

View File

@ -13,6 +13,8 @@ namespace Slic3r { namespace arr2 {
const Polygons &DecomposedShape::transformed_outline() const
{
constexpr auto sc = scaled<double>(1.) * scaled<double>(1.);
if (!m_transformed_outline_valid) {
m_transformed_outline = contours();
for (Polygon &poly : m_transformed_outline) {
@ -20,7 +22,6 @@ const Polygons &DecomposedShape::transformed_outline() const
poly.translate(translation());
}
auto sc = scaled<double>(1.) * scaled<double>(1.);
m_area = std::accumulate(m_transformed_outline.begin(),
m_transformed_outline.end(), 0.,
[sc](double s, const auto &p) {
@ -88,6 +89,29 @@ const Vec2crd &DecomposedShape::min_vertex(size_t idx) const
return m_mins[idx];
}
Vec2crd DecomposedShape::centroid() const
{
constexpr double area_sc = scaled<double>(1.) * scaled(1.);
if (!m_centroid_valid) {
double total_area = 0.0;
Vec2d cntr = Vec2d::Zero();
for (const Polygon& poly : transformed_outline()) {
double parea = poly.area() / area_sc;
Vec2d pcntr = unscaled(poly.centroid());
total_area += parea;
cntr += pcntr * parea;
}
cntr /= total_area;
m_centroid = scaled(cntr);
m_centroid_valid = true;
}
return m_centroid;
}
DecomposedShape decompose(const ExPolygons &shape)
{
ExPolygons shape_s = expolygons_simplify(shape, scaled(.2));

View File

@ -55,6 +55,9 @@ class DecomposedShape
mutable std::vector<Point> m_mins;
mutable bool m_reference_vertex_valid = false;
mutable Point m_centroid;
mutable bool m_centroid_valid = false;
mutable Polygon m_convex_hull;
mutable BoundingBox m_bounding_box;
mutable double m_area = 0;
@ -87,6 +90,7 @@ public:
m_translation = v;
m_transformed_outline_valid = false;
m_reference_vertex_valid = false;
m_centroid_valid = false;
}
void rotation(double v)
@ -94,6 +98,7 @@ public:
m_rotation = v;
m_transformed_outline_valid = false;
m_reference_vertex_valid = false;
m_centroid_valid = false;
}
const Polygons &transformed_outline() const;
@ -115,6 +120,8 @@ public:
return m_area;
}
Vec2crd centroid() const;
};
DecomposedShape decompose(const ExPolygons &polys);
@ -188,6 +195,8 @@ public:
{
m_shape.reference_vertex();
m_envelope->reference_vertex();
m_shape.centroid();
m_envelope->centroid();
}
};
@ -412,6 +421,16 @@ template<> struct NFPArrangeItemTraits_<ArrangeItem> {
return *ret_ptr;
}
static Vec2crd fixed_centroid(const ArrangeItem &itm)
{
return itm.shape().centroid();
}
static Vec2crd envelope_centroid(const ArrangeItem &itm)
{
return itm.envelope().centroid();
}
};
template<> struct IsWritableItem_<ArrangeItem>: public std::true_type {};

View File

@ -138,6 +138,16 @@ template<> struct NFPArrangeItemTraits_<SimpleArrangeItem>
{
return itm.allowed_rotations();
}
static Vec2crd fixed_centroid(const SimpleArrangeItem &itm) noexcept
{
return itm.shape().centroid();
}
static Vec2crd envelope_centroid(const SimpleArrangeItem &itm) noexcept
{
return itm.shape().centroid();
}
};
template<> struct IsWritableItem_<SimpleArrangeItem>: public std::true_type {};