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> template<class ArrItem>
double placement_fitness(const ArrItem &itm, const Vec2crd &transl) const 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); center += unscaled(transl);

View File

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

View File

@ -74,6 +74,16 @@ template<class ArrItem, class En = void> struct NFPArrangeItemTraits_
{ {
return std::array{0.}; 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> template<class T>
@ -137,6 +147,16 @@ template<class ArrItem> double fixed_area(const ArrItem &itm)
return NFPArrangeItemTraits<ArrItem>::fixed_area(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> template<class ArrItem>
auto allowed_rotations(const ArrItem &itm) auto allowed_rotations(const ArrItem &itm)
{ {

View File

@ -13,6 +13,8 @@ namespace Slic3r { namespace arr2 {
const Polygons &DecomposedShape::transformed_outline() const const Polygons &DecomposedShape::transformed_outline() const
{ {
constexpr auto sc = scaled<double>(1.) * scaled<double>(1.);
if (!m_transformed_outline_valid) { if (!m_transformed_outline_valid) {
m_transformed_outline = contours(); m_transformed_outline = contours();
for (Polygon &poly : m_transformed_outline) { for (Polygon &poly : m_transformed_outline) {
@ -20,7 +22,6 @@ const Polygons &DecomposedShape::transformed_outline() const
poly.translate(translation()); poly.translate(translation());
} }
auto sc = scaled<double>(1.) * scaled<double>(1.);
m_area = std::accumulate(m_transformed_outline.begin(), m_area = std::accumulate(m_transformed_outline.begin(),
m_transformed_outline.end(), 0., m_transformed_outline.end(), 0.,
[sc](double s, const auto &p) { [sc](double s, const auto &p) {
@ -88,6 +89,29 @@ const Vec2crd &DecomposedShape::min_vertex(size_t idx) const
return m_mins[idx]; 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) DecomposedShape decompose(const ExPolygons &shape)
{ {
ExPolygons shape_s = expolygons_simplify(shape, scaled(.2)); ExPolygons shape_s = expolygons_simplify(shape, scaled(.2));

View File

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

View File

@ -138,6 +138,16 @@ template<> struct NFPArrangeItemTraits_<SimpleArrangeItem>
{ {
return itm.allowed_rotations(); 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 {}; template<> struct IsWritableItem_<SimpleArrangeItem>: public std::true_type {};