mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-21 18:02:09 +00:00
Merge branch 'main' into belt/baseChanges
This commit is contained in:
@@ -4507,7 +4507,7 @@ struct Plater::priv
|
||||
|
||||
// BBS: backup & restore
|
||||
std::vector<size_t> load_files(const std::vector<fs::path>& input_files, LoadStrategy strategy, bool ask_multi = false);
|
||||
std::vector<size_t> load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z = false, bool split_object = false);
|
||||
std::vector<size_t> load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z = false, bool split_object = false, bool auto_drop = true);
|
||||
|
||||
fs::path get_export_file_path(GUI::FileType file_type);
|
||||
wxString get_export_file(GUI::FileType file_type);
|
||||
@@ -4538,7 +4538,8 @@ struct Plater::priv
|
||||
void center_selection();
|
||||
void drop_selection();
|
||||
void mirror(Axis axis);
|
||||
void split_object();
|
||||
void split_object(bool auto_drop = true);
|
||||
void split_object(int obj_idx, bool auto_drop = true);
|
||||
void split_volume();
|
||||
void scale_selection_to_fit_print_volume();
|
||||
|
||||
@@ -6715,14 +6716,37 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
if (new_model != nullptr && new_model->objects.size() > 1) {
|
||||
//BBS do not popup this dialog
|
||||
|
||||
bool new_model_auto_drop = true;
|
||||
int single_object_answer = false;
|
||||
if (ask_multi) {
|
||||
MessageDialog msg_dlg(q, _L("Load these files as a single object with multiple parts?\n"), _L("Object with multiple parts was detected"),
|
||||
wxICON_WARNING | wxYES | wxNO);
|
||||
if (msg_dlg.ShowModal() == wxID_YES) { new_model->convert_multipart_object(filaments_cnt); }
|
||||
RichMessageDialog dlg(q, _L("Load these files as a single object with multiple parts?\n"),
|
||||
_L("Object with multiple parts was detected"), wxICON_QUESTION | wxYES_NO);
|
||||
|
||||
dlg.ShowCheckBox(_L("Auto-Drop"), true);
|
||||
single_object_answer = dlg.ShowModal();
|
||||
|
||||
if (dlg.IsCheckBoxChecked() == false)
|
||||
new_model_auto_drop = false;
|
||||
|
||||
// convert to multipart and split after load_model_objects
|
||||
// to keep relative positioning if auto_drop == false
|
||||
if (single_object_answer == wxID_YES || new_model_auto_drop == false)
|
||||
new_model->convert_multipart_object(filaments_cnt);
|
||||
}
|
||||
|
||||
auto loaded_idxs = load_model_objects(new_model->objects);
|
||||
// TODO
|
||||
// DONE always convert to multipart, split afterwards to retain relative position
|
||||
// DONE if !auto_drop move all objects over the z-position 0, so that none are clipped by the bed.
|
||||
// DONE retain auto_drop (and printable) state when assembling or splitting objects.
|
||||
// DONE when manually split to object ask users if looks_like_multipart and none have auto_drob disabled if they want to disable auto_drop for all resulting objects.
|
||||
// - add icon in object list, similar to fuzzy painting, etc.
|
||||
|
||||
auto loaded_idxs = load_model_objects(new_model->objects, false, false, new_model_auto_drop);
|
||||
obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
|
||||
|
||||
if (single_object_answer == wxID_NO && new_model_auto_drop == false) {
|
||||
split_object(loaded_idxs[0], new_model_auto_drop);
|
||||
}
|
||||
}
|
||||
|
||||
if (load_config) {
|
||||
@@ -6889,7 +6913,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
|
||||
#define AUTOPLACEMENT_ON_LOAD
|
||||
|
||||
std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z, bool split_object)
|
||||
std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& model_objects, bool allow_negative_z, bool split_object, bool auto_drop)
|
||||
{
|
||||
const Vec3d bed_size = Slic3r::to_3d(this->bed.build_volume().bounding_volume2d().size(), 1.0) - 2.0 * Vec3d::Ones();
|
||||
|
||||
@@ -6916,7 +6940,7 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
|
||||
#else /* AUTOPLACEMENT_ON_LOAD */
|
||||
// if object has no defined position(s) we need to rearrange everything after loading
|
||||
// need_arrange = true;
|
||||
// add a default instance and center object around origin
|
||||
// add a default instance and center object around origin
|
||||
object->center_around_origin(); // also aligns object to Z = 0
|
||||
ModelInstance* instance = object->add_instance();
|
||||
|
||||
@@ -6925,7 +6949,7 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
|
||||
instance->set_offset(Slic3r::to_3d(this->bed.build_volume().bed_center(), -object->origin_translation(2)));
|
||||
#endif /* AUTOPLACEMENT_ON_LOAD */
|
||||
}
|
||||
|
||||
|
||||
//BBS: when the object is too large, let the user choose whether to scale it down
|
||||
for (size_t i = 0; i < object->instances.size(); ++i) {
|
||||
ModelInstance* instance = object->instances[i];
|
||||
@@ -6955,7 +6979,20 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
|
||||
}
|
||||
}
|
||||
|
||||
object->ensure_on_bed(allow_negative_z);
|
||||
if (!auto_drop) {
|
||||
for (size_t i = 0; i < object->instances.size(); ++i) {
|
||||
ModelInstance* instance = object->instances[i];
|
||||
instance->auto_drop = auto_drop;
|
||||
}
|
||||
|
||||
// if under the bed, move over the bed
|
||||
double dist_to_bed = std::min(object->min_z(), double(0));
|
||||
object->translate_instances(Vec3d(0, 0, -dist_to_bed));
|
||||
}
|
||||
else {
|
||||
object->ensure_on_bed(allow_negative_z);
|
||||
}
|
||||
|
||||
if (!split_object) {
|
||||
//BBS initial assemble transformation
|
||||
for (ModelObject* model_object : model.objects) {
|
||||
@@ -6965,7 +7002,7 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
|
||||
model_object->instances[i]->set_assemble_transformation(model_object->instances[i]->get_transformation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7032,7 +7069,7 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs& mode
|
||||
// which is updated after a view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH) call
|
||||
for (const size_t idx : obj_idxs)
|
||||
wxGetApp().obj_list()->update_info_items(idx);
|
||||
|
||||
|
||||
object_list_changed();
|
||||
|
||||
this->schedule_background_process();
|
||||
@@ -7484,9 +7521,16 @@ void Plater::find_new_position(const ModelInstancePtrs &instances)
|
||||
m.apply();
|
||||
}
|
||||
|
||||
void Plater::priv::split_object()
|
||||
{
|
||||
// split selected object into multiple objects by its volumes
|
||||
void Plater::priv::split_object(bool auto_drop /* = true */)
|
||||
{
|
||||
int obj_idx = get_selected_object_idx();
|
||||
priv::split_object(obj_idx, auto_drop);
|
||||
}
|
||||
|
||||
// split provided object into multiple objects by its volumes
|
||||
void Plater::priv::split_object(int obj_idx, bool auto_drop /* = true */)
|
||||
{
|
||||
if (obj_idx == -1)
|
||||
return;
|
||||
|
||||
@@ -7512,12 +7556,30 @@ void Plater::priv::split_object()
|
||||
|
||||
Plater::TakeSnapshot snapshot(q, "Split to Objects");
|
||||
|
||||
auto is_atleast_one_floating = [new_objects]() {
|
||||
for (ModelObject* new_object : new_objects) {
|
||||
if (new_object->get_instance_min_z(0) >= SINKING_MIN_Z_THRESHOLD)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
bool split_auto_drop = auto_drop;
|
||||
if (current_model_object->instances[0]->auto_drop && is_atleast_one_floating()) {
|
||||
MessageDialog dlg(q, _L("Disable Auto-Drop to preserve z positioning?\n"),
|
||||
_L("Object with floating parts was detected"), wxICON_QUESTION | wxYES_NO);
|
||||
|
||||
if (dlg.ShowModal() == wxID_YES)
|
||||
split_auto_drop = false;
|
||||
}
|
||||
|
||||
remove(obj_idx);
|
||||
|
||||
// load all model objects at once, otherwise the plate would be rearranged after each one
|
||||
// causing original positions not to be kept
|
||||
//BBS: set split_object to true to avoid re-compute assemble matrix
|
||||
std::vector<size_t> idxs = load_model_objects(new_objects, false, true);
|
||||
std::vector<size_t> idxs = load_model_objects(new_objects, false, true, split_auto_drop);
|
||||
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_instance_printable_state_for_objects(idxs);
|
||||
|
||||
// select newly added objects
|
||||
for (size_t idx : idxs)
|
||||
@@ -16750,7 +16812,7 @@ const GLCanvas3D* Plater::canvas3D() const
|
||||
|
||||
GLCanvas3D* Plater::get_view3D_canvas3D()
|
||||
{
|
||||
return p->view3D->get_canvas3d();
|
||||
return p ? p->view3D->get_canvas3d() : nullptr;
|
||||
}
|
||||
|
||||
GLCanvas3D* Plater::get_preview_canvas3D()
|
||||
@@ -16941,11 +17003,11 @@ void Plater::suppress_background_process(const bool stop_background_process)
|
||||
this->p->suppressed_backround_processing_update = true;
|
||||
}
|
||||
|
||||
void Plater::center_selection() { p->center_selection(); }
|
||||
void Plater::drop_selection() { p->drop_selection(); }
|
||||
void Plater::mirror(Axis axis) { p->mirror(axis); }
|
||||
void Plater::split_object() { p->split_object(); }
|
||||
void Plater::split_volume() { p->split_volume(); }
|
||||
void Plater::center_selection() { p->center_selection(); }
|
||||
void Plater::drop_selection() { p->drop_selection(); }
|
||||
void Plater::mirror(Axis axis) { p->mirror(axis); }
|
||||
void Plater::split_object(bool auto_drop) { p->split_object(auto_drop); }
|
||||
void Plater::split_volume() { p->split_volume(); }
|
||||
void Plater::optimize_rotation()
|
||||
{
|
||||
auto &w = get_ui_job_worker();
|
||||
|
||||
Reference in New Issue
Block a user