mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 01:07:57 -06:00
Polishing autoplacement feature for testing
This commit is contained in:
parent
f129a92405
commit
4e8c570d52
3 changed files with 66 additions and 45 deletions
|
@ -911,12 +911,13 @@ private:
|
||||||
if(config_.object_function) _objfunc = config_.object_function;
|
if(config_.object_function) _objfunc = config_.object_function;
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// Inside check has to be strict if no alignment was enabled.
|
// Inside check has to be strict if no alignment was enabled
|
||||||
std::function<double(const Box&)> ins_check;
|
std::function<double(const Box&)> ins_check;
|
||||||
if(config_.alignment == Config::Alignment::DONT_ALIGN)
|
if(config_.alignment == Config::Alignment::DONT_ALIGN)
|
||||||
ins_check = [&binbb, norm](const Box& fullbb) {
|
ins_check = [&binbb, norm](const Box& fullbb) {
|
||||||
double ret = 0;
|
double ret = 0;
|
||||||
if(sl::isInside<RawShape>(fullbb, binbb)) ret += norm;
|
if(sl::isInside<RawShape>(fullbb, binbb))
|
||||||
|
ret += norm*norm;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
else
|
else
|
||||||
|
|
|
@ -434,8 +434,8 @@ template<> class AutoArranger<lnCircle>: public _ArrBase<lnCircle> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AutoArranger(const lnCircle& bin, Distance dist,
|
AutoArranger(const lnCircle& bin, Distance dist,
|
||||||
std::function<void(unsigned)> progressind,
|
std::function<void(unsigned)> progressind = [](unsigned){},
|
||||||
std::function<bool(void)> stopcond):
|
std::function<bool(void)> stopcond = [](){return false;}):
|
||||||
_ArrBase<lnCircle>(bin, dist, progressind, stopcond) {
|
_ArrBase<lnCircle>(bin, dist, progressind, stopcond) {
|
||||||
|
|
||||||
// As with the box, only the inside check is different.
|
// As with the box, only the inside check is different.
|
||||||
|
@ -479,8 +479,8 @@ public:
|
||||||
template<> class AutoArranger<PolygonImpl>: public _ArrBase<PolygonImpl> {
|
template<> class AutoArranger<PolygonImpl>: public _ArrBase<PolygonImpl> {
|
||||||
public:
|
public:
|
||||||
AutoArranger(const PolygonImpl& bin, Distance dist,
|
AutoArranger(const PolygonImpl& bin, Distance dist,
|
||||||
std::function<void(unsigned)> progressind,
|
std::function<void(unsigned)> progressind = [](unsigned){},
|
||||||
std::function<bool(void)> stopcond):
|
std::function<bool(void)> stopcond = [](){return false;}):
|
||||||
_ArrBase<PolygonImpl>(bin, dist, progressind, stopcond)
|
_ArrBase<PolygonImpl>(bin, dist, progressind, stopcond)
|
||||||
{
|
{
|
||||||
m_pconf.object_function = [this, &bin] (const Item &item) {
|
m_pconf.object_function = [this, &bin] (const Item &item) {
|
||||||
|
@ -846,8 +846,8 @@ void find_new_position(const Model &model,
|
||||||
});
|
});
|
||||||
|
|
||||||
for(auto it = shapemap.begin(); it != shapemap.end(); ++it) {
|
for(auto it = shapemap.begin(); it != shapemap.end(); ++it) {
|
||||||
if(std::find(toadd.begin(), toadd.end(), it->first) == toadd.end() &&
|
if(std::find(toadd.begin(), toadd.end(), it->first) == toadd.end()) {
|
||||||
it->second.isInside(binbb)) { // just ignore items which are outside
|
if(it->second.isInside(binbb)) // just ignore items which are outside
|
||||||
preshapes.front().emplace_back(std::ref(it->second));
|
preshapes.front().emplace_back(std::ref(it->second));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -856,15 +856,12 @@ void find_new_position(const Model &model,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(bedhint.type) {
|
auto try_first_to_center = [&shapes, &shapes_ptr, &binbb]
|
||||||
case BedShapeType::BOX: {
|
(std::function<bool(const Item&)> is_colliding,
|
||||||
|
std::function<void(Item&)> preload)
|
||||||
// Create the arranger for the box shaped bed
|
{
|
||||||
AutoArranger<Box> arrange(binbb, min_obj_distance);
|
// Try to put the first item to the center, as the arranger will not
|
||||||
std::cout << "preload size: " << preshapes.front().size() << std::endl;
|
// do this for us.
|
||||||
|
|
||||||
if(!preshapes.front().empty()) arrange.preload(preshapes);
|
|
||||||
|
|
||||||
auto shptrit = shapes_ptr.begin();
|
auto shptrit = shapes_ptr.begin();
|
||||||
for(auto shit = shapes.begin(); shit != shapes.end(); ++shit, ++shptrit)
|
for(auto shit = shapes.begin(); shit != shapes.end(); ++shit, ++shptrit)
|
||||||
{
|
{
|
||||||
|
@ -873,8 +870,8 @@ void find_new_position(const Model &model,
|
||||||
auto ibb = itm.boundingBox();
|
auto ibb = itm.boundingBox();
|
||||||
auto d = binbb.center() - ibb.center();
|
auto d = binbb.center() - ibb.center();
|
||||||
itm.translate(d);
|
itm.translate(d);
|
||||||
if(!arrange.is_colliding(itm)) {
|
if(!is_colliding(itm)) {
|
||||||
arrange.preload({{itm}});
|
preload(itm);
|
||||||
|
|
||||||
auto offset = itm.translation();
|
auto offset = itm.translation();
|
||||||
Radians rot = itm.rotation();
|
Radians rot = itm.rotation();
|
||||||
|
@ -892,6 +889,21 @@ void find_new_position(const Model &model,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(bedhint.type) {
|
||||||
|
case BedShapeType::BOX: {
|
||||||
|
|
||||||
|
// Create the arranger for the box shaped bed
|
||||||
|
AutoArranger<Box> arrange(binbb, min_obj_distance);
|
||||||
|
|
||||||
|
if(!preshapes.front().empty()) { // If there is something on the plate
|
||||||
|
arrange.preload(preshapes);
|
||||||
|
try_first_to_center(
|
||||||
|
[&arrange](const Item& itm) {return arrange.is_colliding(itm);},
|
||||||
|
[&arrange](Item& itm) { arrange.preload({{itm}}); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Arrange and return the items with their respective indices within the
|
// Arrange and return the items with their respective indices within the
|
||||||
// input sequence.
|
// input sequence.
|
||||||
|
@ -900,26 +912,45 @@ void find_new_position(const Model &model,
|
||||||
}
|
}
|
||||||
case BedShapeType::CIRCLE: {
|
case BedShapeType::CIRCLE: {
|
||||||
|
|
||||||
// auto c = bedhint.shape.circ;
|
auto c = bedhint.shape.circ;
|
||||||
// auto cc = to_lnCircle(c);
|
auto cc = to_lnCircle(c);
|
||||||
|
|
||||||
// AutoArranger<lnCircle> arrange(cc, min_obj_distance, progressind, cfn);
|
// Create the arranger for the box shaped bed
|
||||||
// result = arrange(shapes.begin(), shapes.end());
|
AutoArranger<lnCircle> arrange(cc, min_obj_distance);
|
||||||
|
|
||||||
|
if(!preshapes.front().empty()) { // If there is something on the plate
|
||||||
|
arrange.preload(preshapes);
|
||||||
|
try_first_to_center(
|
||||||
|
[&arrange](const Item& itm) {return arrange.is_colliding(itm);},
|
||||||
|
[&arrange](Item& itm) { arrange.preload({{itm}}); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrange and return the items with their respective indices within the
|
||||||
|
// input sequence.
|
||||||
|
result = arrange(shapes.begin(), shapes.end());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BedShapeType::IRREGULAR:
|
case BedShapeType::IRREGULAR:
|
||||||
case BedShapeType::WHO_KNOWS: {
|
case BedShapeType::WHO_KNOWS: {
|
||||||
|
using P = libnest2d::PolygonImpl;
|
||||||
|
|
||||||
// using P = libnest2d::PolygonImpl;
|
auto ctour = Slic3rMultiPoint_to_ClipperPath(bed);
|
||||||
|
P irrbed = sl::create<PolygonImpl>(std::move(ctour));
|
||||||
|
|
||||||
// auto ctour = Slic3rMultiPoint_to_ClipperPath(bed);
|
AutoArranger<P> arrange(irrbed, min_obj_distance);
|
||||||
// P irrbed = sl::create<PolygonImpl>(std::move(ctour));
|
|
||||||
|
|
||||||
// AutoArranger<P> arrange(irrbed, min_obj_distance, progressind, cfn);
|
if(!preshapes.front().empty()) { // If there is something on the plate
|
||||||
|
arrange.preload(preshapes);
|
||||||
|
try_first_to_center(
|
||||||
|
[&arrange](const Item& itm) {return arrange.is_colliding(itm);},
|
||||||
|
[&arrange](Item& itm) { arrange.preload({{itm}}); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// // Arrange and return the items with their respective indices within the
|
// Arrange and return the items with their respective indices within the
|
||||||
// // input sequence.
|
// input sequence.
|
||||||
// result = arrange(shapes.begin(), shapes.end());
|
result = arrange(shapes.begin(), shapes.end());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1399,8 +1399,6 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||||
if (one_by_one) {
|
if (one_by_one) {
|
||||||
auto loaded_idxs = load_model_objects(model.objects);
|
auto loaded_idxs = load_model_objects(model.objects);
|
||||||
obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
|
obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
|
||||||
|
|
||||||
std::cout << "New model objects added..." << std::endl;
|
|
||||||
} else {
|
} else {
|
||||||
// This must be an .stl or .obj file, which may contain a maximum of one volume.
|
// This must be an .stl or .obj file, which may contain a maximum of one volume.
|
||||||
for (const ModelObject* model_object : model.objects) {
|
for (const ModelObject* model_object : model.objects) {
|
||||||
|
@ -1450,7 +1448,6 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
|
||||||
const BoundingBoxf bed_shape = bed_shape_bb();
|
const BoundingBoxf bed_shape = bed_shape_bb();
|
||||||
const Vec3d bed_size = Slic3r::to_3d(bed_shape.size().cast<double>(), 1.0) - 2.0 * Vec3d::Ones();
|
const Vec3d bed_size = Slic3r::to_3d(bed_shape.size().cast<double>(), 1.0) - 2.0 * Vec3d::Ones();
|
||||||
|
|
||||||
// bool need_arrange = false;
|
|
||||||
bool scaled_down = false;
|
bool scaled_down = false;
|
||||||
std::vector<size_t> obj_idxs;
|
std::vector<size_t> obj_idxs;
|
||||||
unsigned int obj_count = model.objects.size();
|
unsigned int obj_count = model.objects.size();
|
||||||
|
@ -1462,16 +1459,8 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
|
||||||
obj_idxs.push_back(obj_count++);
|
obj_idxs.push_back(obj_count++);
|
||||||
|
|
||||||
if (model_object->instances.empty()) {
|
if (model_object->instances.empty()) {
|
||||||
// if object has no defined position(s) we need to rearrange everything after loading
|
|
||||||
// need_arrange = true;
|
|
||||||
|
|
||||||
object->center_around_origin();
|
object->center_around_origin();
|
||||||
new_instances.emplace_back(object->add_instance());
|
new_instances.emplace_back(object->add_instance());
|
||||||
|
|
||||||
// // add a default instance and center object around origin
|
|
||||||
// object->center_around_origin(); // also aligns object to Z = 0
|
|
||||||
// ModelInstance* instance = object->add_instance();
|
|
||||||
// instance->set_offset(Slic3r::to_3d(bed_shape.center().cast<double>(), -object->origin_translation(2)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vec3d size = object->bounding_box().size();
|
const Vec3d size = object->bounding_box().size();
|
||||||
|
@ -1498,7 +1487,7 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
|
||||||
// print.add_model_object(object);
|
// print.add_model_object(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME distance should be a config value
|
// FIXME distance should be a config value /////////////////////////////////
|
||||||
auto min_obj_distance = static_cast<coord_t>(6/SCALING_FACTOR);
|
auto min_obj_distance = static_cast<coord_t>(6/SCALING_FACTOR);
|
||||||
const auto *bed_shape_opt = config->opt<ConfigOptionPoints>("bed_shape");
|
const auto *bed_shape_opt = config->opt<ConfigOptionPoints>("bed_shape");
|
||||||
assert(bed_shape_opt);
|
assert(bed_shape_opt);
|
||||||
|
@ -1506,8 +1495,8 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
|
||||||
Polyline bed; bed.points.reserve(bedpoints.size());
|
Polyline bed; bed.points.reserve(bedpoints.size());
|
||||||
for(auto& v : bedpoints) bed.append(Point::new_scale(v(0), v(1)));
|
for(auto& v : bedpoints) bed.append(Point::new_scale(v(0), v(1)));
|
||||||
|
|
||||||
arr::find_new_position(model, new_instances,
|
arr::find_new_position(model, new_instances, min_obj_distance, bed);
|
||||||
min_obj_distance, bed);
|
// /////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (scaled_down) {
|
if (scaled_down) {
|
||||||
GUI::show_info(q,
|
GUI::show_info(q,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue