Fix for leaving the object outside bed after "optimize orientation"
This commit is contained in:
parent
763a91e2ca
commit
b56991d780
1 changed files with 58 additions and 3 deletions
|
@ -38,6 +38,8 @@
|
||||||
#include "libslic3r/SLA/SLARotfinder.hpp"
|
#include "libslic3r/SLA/SLARotfinder.hpp"
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
|
|
||||||
|
#include "libnest2d/optimizers/nlopt/genetic.hpp"
|
||||||
|
|
||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
#include "GUI_ObjectList.hpp"
|
#include "GUI_ObjectList.hpp"
|
||||||
|
@ -2100,7 +2102,9 @@ void Plater::priv::sla_optimize_rotation() {
|
||||||
rotoptimizing.store(true);
|
rotoptimizing.store(true);
|
||||||
|
|
||||||
int obj_idx = get_selected_object_idx();
|
int obj_idx = get_selected_object_idx();
|
||||||
ModelObject * o = model.objects[obj_idx];
|
if(obj_idx < 0) { rotoptimizing.store(false); return; }
|
||||||
|
|
||||||
|
ModelObject * o = model.objects[size_t(obj_idx)];
|
||||||
|
|
||||||
background_process.stop();
|
background_process.stop();
|
||||||
|
|
||||||
|
@ -2108,7 +2112,7 @@ void Plater::priv::sla_optimize_rotation() {
|
||||||
statusbar()->set_range(100);
|
statusbar()->set_range(100);
|
||||||
|
|
||||||
auto stfn = [this] (unsigned st, const std::string& msg) {
|
auto stfn = [this] (unsigned st, const std::string& msg) {
|
||||||
statusbar()->set_progress(st);
|
statusbar()->set_progress(int(st));
|
||||||
statusbar()->set_status_text(msg);
|
statusbar()->set_status_text(msg);
|
||||||
|
|
||||||
// could be problematic, but we need the cancel button.
|
// could be problematic, but we need the cancel button.
|
||||||
|
@ -2126,8 +2130,59 @@ void Plater::priv::sla_optimize_rotation() {
|
||||||
[this](){ return !rotoptimizing.load(); }
|
[this](){ return !rotoptimizing.load(); }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const auto *bed_shape_opt = config->opt<ConfigOptionPoints>("bed_shape");
|
||||||
|
assert(bed_shape_opt);
|
||||||
|
|
||||||
|
auto& bedpoints = bed_shape_opt->values;
|
||||||
|
Polyline bed; bed.points.reserve(bedpoints.size());
|
||||||
|
for(auto& v : bedpoints) bed.append(Point::new_scale(v(0), v(1)));
|
||||||
|
|
||||||
|
double mindist = 6.0; // FIXME
|
||||||
|
double offs = mindist / 2.0 - EPSILON;
|
||||||
|
|
||||||
if(rotoptimizing.load()) // wasn't canceled
|
if(rotoptimizing.load()) // wasn't canceled
|
||||||
for(ModelInstance * oi : o->instances) oi->set_rotation({r[X], r[Y], r[Z]});
|
for(ModelInstance * oi : o->instances) {
|
||||||
|
oi->set_rotation({r[X], r[Y], r[Z]});
|
||||||
|
|
||||||
|
auto trchull = o->convex_hull_2d(oi->get_transformation().get_matrix());
|
||||||
|
|
||||||
|
namespace opt = libnest2d::opt;
|
||||||
|
opt::StopCriteria stopcr;
|
||||||
|
stopcr.relative_score_difference = 0.01;
|
||||||
|
stopcr.max_iterations = 10000;
|
||||||
|
stopcr.stop_score = 0.0;
|
||||||
|
opt::GeneticOptimizer solver(stopcr);
|
||||||
|
Polygon pbed(bed);
|
||||||
|
|
||||||
|
auto bin = pbed.bounding_box();
|
||||||
|
double binw = bin.size()(X) * SCALING_FACTOR - offs;
|
||||||
|
double binh = bin.size()(Y) * SCALING_FACTOR - offs;
|
||||||
|
|
||||||
|
auto result = solver.optimize_min([&trchull, binw, binh](double rot){
|
||||||
|
auto chull = trchull;
|
||||||
|
chull.rotate(rot);
|
||||||
|
|
||||||
|
auto bb = chull.bounding_box();
|
||||||
|
double bbw = bb.size()(X) * SCALING_FACTOR;
|
||||||
|
double bbh = bb.size()(Y) * SCALING_FACTOR;
|
||||||
|
|
||||||
|
auto wdiff = bbw - binw;
|
||||||
|
auto hdiff = bbh - binh;
|
||||||
|
double diff = 0;
|
||||||
|
if(wdiff < 0 && hdiff < 0) diff = wdiff + hdiff;
|
||||||
|
if(wdiff > 0) diff += wdiff;
|
||||||
|
if(hdiff > 0) diff += hdiff;
|
||||||
|
|
||||||
|
return diff;
|
||||||
|
}, opt::initvals(0.0), opt::bound(-PI/2, PI/2));
|
||||||
|
|
||||||
|
double r = std::get<0>(result.optimum);
|
||||||
|
|
||||||
|
Vec3d rt = oi->get_rotation(); rt(Z) += r;
|
||||||
|
oi->set_rotation(rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
arr::find_new_position(model, o->instances, coord_t(mindist/SCALING_FACTOR), bed);
|
||||||
|
|
||||||
// Correct the z offset of the object which was corrupted be the rotation
|
// Correct the z offset of the object which was corrupted be the rotation
|
||||||
o->ensure_on_bed();
|
o->ensure_on_bed();
|
||||||
|
|
Loading…
Reference in a new issue