Add code to extract sla supports outline for arrangement
Add functionality to libnest to support on_packed handler for all items. Use it to swap arrange polygon from envelope to core poly after packing was succesful. Solving brim issue by offset adjustments of arrange polygons Only in sla yet
This commit is contained in:
parent
e46891fa8c
commit
6b1c9119be
6 changed files with 93 additions and 2 deletions
|
@ -70,6 +70,7 @@ class _Item {
|
|||
|
||||
int binid_{BIN_ID_UNSET}, priority_{0};
|
||||
bool fixed_{false};
|
||||
std::function<void(_Item&)> on_packed_;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -205,6 +206,23 @@ public:
|
|||
sl::vertex(sh_, idx) = v;
|
||||
}
|
||||
|
||||
void setShape(RawShape rsh)
|
||||
{
|
||||
sh_ = std::move(rsh);
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
void setOnPackedFn(std::function<void(_Item&)> onpackedfn)
|
||||
{
|
||||
on_packed_ = onpackedfn;
|
||||
}
|
||||
|
||||
void onPacked()
|
||||
{
|
||||
if (on_packed_)
|
||||
on_packed_(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate the shape area.
|
||||
*
|
||||
|
|
|
@ -901,6 +901,7 @@ public:
|
|||
|
||||
if(can_pack) {
|
||||
ret = PackResult(item);
|
||||
item.onPacked();
|
||||
merged_pile_ = nfp::merge(merged_pile_, item.transformedShape());
|
||||
} else {
|
||||
ret = PackResult(best_overfit);
|
||||
|
|
|
@ -583,8 +583,12 @@ static void process_arrangeable(const ArrangePolygon &arrpoly,
|
|||
outp.emplace_back(std::move(p));
|
||||
outp.back().rotation(rotation);
|
||||
outp.back().translation({offs.x(), offs.y()});
|
||||
outp.back().inflate(arrpoly.inflation);
|
||||
outp.back().binId(arrpoly.bed_idx);
|
||||
outp.back().priority(arrpoly.priority);
|
||||
outp.back().setOnPackedFn([&arrpoly](Item &itm){
|
||||
itm.inflate(-arrpoly.inflation);
|
||||
});
|
||||
}
|
||||
|
||||
template<class Fn> auto call_with_bed(const Points &bed, Fn &&fn)
|
||||
|
|
|
@ -71,7 +71,7 @@ static const constexpr int UNARRANGED = -1;
|
|||
/// polygon belongs: UNARRANGED means no place for the polygon
|
||||
/// (also the initial state before arrange), 0..N means the index of the bed.
|
||||
/// Zero is the physical bed, larger than zero means a virtual bed.
|
||||
struct ArrangePolygon {
|
||||
struct ArrangePolygon {
|
||||
ExPolygon poly; /// The 2D silhouette to be arranged
|
||||
Vec2crd translation{0, 0}; /// The translation of the poly
|
||||
double rotation{0.0}; /// The rotation of the poly in radians
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include "libslic3r/BuildVolume.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/SLAPrint.hpp"
|
||||
#include "libslic3r/Geometry/ConvexHull.hpp"
|
||||
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
|
@ -11,6 +13,7 @@
|
|||
#include "slic3r/GUI/NotificationManager.hpp"
|
||||
#include "slic3r/GUI/format.hpp"
|
||||
|
||||
|
||||
#include "libnest2d/common.hpp"
|
||||
|
||||
#include <numeric>
|
||||
|
@ -76,6 +79,7 @@ void ArrangeJob::clear_input()
|
|||
m_selected.reserve(count + 1 /* for optional wti */);
|
||||
m_unselected.reserve(count + 1 /* for optional wti */);
|
||||
m_unprintable.reserve(cunprint /* for optional wti */);
|
||||
m_min_inflation = 0;
|
||||
}
|
||||
|
||||
void ArrangeJob::prepare_all() {
|
||||
|
@ -145,6 +149,50 @@ void ArrangeJob::prepare_selected() {
|
|||
for (auto &p : m_unselected) p.translation(X) -= p.bed_idx * stride;
|
||||
}
|
||||
|
||||
static void update_arrangepoly_slaprint(arrangement::ArrangePolygon &ret,
|
||||
const SLAPrintObject &po,
|
||||
const ModelInstance &inst,
|
||||
coord_t min_infl)
|
||||
{
|
||||
auto laststep = po.last_completed_step();
|
||||
|
||||
if (laststep < slaposCount && laststep > slaposSupportTree) {
|
||||
auto omesh = po.get_mesh_to_print();
|
||||
auto &smesh = po.support_mesh();
|
||||
|
||||
Vec3d rotation = inst.get_rotation();
|
||||
rotation.z() = 0.;
|
||||
Transform3f trafo_instance =
|
||||
Geometry::assemble_transform(inst.get_offset().z() * Vec3d::UnitZ(),
|
||||
rotation,
|
||||
inst.get_scaling_factor(),
|
||||
inst.get_mirror()).cast<float>();
|
||||
|
||||
trafo_instance = trafo_instance * po.trafo().cast<float>().inverse();
|
||||
|
||||
auto polys = reserve_vector<Polygon>(3);
|
||||
auto zlvl = -po.get_elevation();
|
||||
|
||||
if (omesh) {
|
||||
polys.emplace_back(its_convex_hull_2d_above(*omesh, trafo_instance, zlvl));
|
||||
ret.poly.contour = polys.back();
|
||||
ret.poly.holes = {};
|
||||
}
|
||||
|
||||
polys.emplace_back(its_convex_hull_2d_above(smesh.its, trafo_instance, zlvl));
|
||||
ret.poly.contour = Geometry::convex_hull(polys);
|
||||
ret.poly.holes = {};
|
||||
|
||||
// The 1.1 multiplier is a safety gap, as the offset might be bigger
|
||||
// in sharp edges of a polygon, depending on clipper's offset algorithm
|
||||
coord_t infl = 1.1 * scaled(po.config().pad_brim_size.getFloat() +
|
||||
po.config().pad_around_object.getBool() *
|
||||
po.config().pad_object_gap.getFloat());
|
||||
|
||||
ret.inflation = std::max(infl, min_infl);
|
||||
}
|
||||
}
|
||||
|
||||
arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi)
|
||||
{
|
||||
arrangement::ArrangePolygon ap = get_arrange_poly(mi, m_plater);
|
||||
|
@ -156,12 +204,28 @@ arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi)
|
|||
m_unarranged.emplace_back(mi);
|
||||
};
|
||||
|
||||
if (m_plater->printer_technology() == ptSLA) {
|
||||
auto obj_id = mi->get_object()->id();
|
||||
const SLAPrintObject *po =
|
||||
m_plater->sla_print().get_print_object_by_model_object_id(obj_id);
|
||||
|
||||
if (po) {
|
||||
update_arrangepoly_slaprint(ap, *po, *mi, m_min_inflation);
|
||||
m_min_inflation = std::max(m_min_inflation, ap.inflation);
|
||||
}
|
||||
} else {
|
||||
// TODO: get fff supports outline
|
||||
}
|
||||
|
||||
return ap;
|
||||
}
|
||||
|
||||
void ArrangeJob::prepare()
|
||||
{
|
||||
wxGetKeyState(WXK_SHIFT) ? prepare_selected() : prepare_all();
|
||||
for (auto &ap : m_selected) {
|
||||
ap.inflation = m_min_inflation;
|
||||
}
|
||||
}
|
||||
|
||||
void ArrangeJob::process(Ctl &ctl)
|
||||
|
@ -286,7 +350,9 @@ template<>
|
|||
arrangement::ArrangePolygon get_arrange_poly(ModelInstance *inst,
|
||||
const Plater * plater)
|
||||
{
|
||||
return get_arrange_poly(PtrWrapper{inst}, plater);
|
||||
auto ap = get_arrange_poly(PtrWrapper{inst}, plater);
|
||||
|
||||
return ap;
|
||||
}
|
||||
|
||||
arrangement::ArrangeParams get_arrange_params(Plater *p)
|
||||
|
|
|
@ -21,6 +21,8 @@ class ArrangeJob : public Job
|
|||
|
||||
ArrangePolygons m_selected, m_unselected, m_unprintable;
|
||||
std::vector<ModelInstance*> m_unarranged;
|
||||
coord_t m_min_inflation = 0;
|
||||
|
||||
Plater *m_plater;
|
||||
|
||||
// clear m_selected and m_unselected, reserve space for next usage
|
||||
|
|
Loading…
Add table
Reference in a new issue