mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 09:56:04 +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>
|
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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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));
|
||||||
|
@ -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 {};
|
||||||
|
@ -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 {};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user