mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 16:45:53 +08:00
Implement correct centroid in DecomposedShape
This commit is contained in:
parent
ccc7009719
commit
9c7fd4f692
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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));
|
||||
|
@ -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 {};
|
||||
|
@ -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 {};
|
||||
|
Loading…
x
Reference in New Issue
Block a user