mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-16 11:17:51 -06:00
NEW: move selected model to the center of selected plate
Change-Id: I7af49e98e83f5eef690f7d30d10a2cc240046466
This commit is contained in:
parent
62da568e0b
commit
31ba41ec3e
11 changed files with 99 additions and 1 deletions
|
@ -3889,6 +3889,14 @@ void GLCanvas3D::do_flatten(const Vec3d& normal, const std::string& snapshot_typ
|
||||||
do_rotate(""); // avoid taking another snapshot
|
do_rotate(""); // avoid taking another snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLCanvas3D::do_center()
|
||||||
|
{
|
||||||
|
if (m_model == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_selection.center();
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas3D::do_mirror(const std::string& snapshot_type)
|
void GLCanvas3D::do_mirror(const std::string& snapshot_type)
|
||||||
{
|
{
|
||||||
if (m_model == nullptr)
|
if (m_model == nullptr)
|
||||||
|
|
|
@ -784,6 +784,7 @@ public:
|
||||||
void do_rotate(const std::string& snapshot_type);
|
void do_rotate(const std::string& snapshot_type);
|
||||||
void do_scale(const std::string& snapshot_type);
|
void do_scale(const std::string& snapshot_type);
|
||||||
void do_flatten(const Vec3d& normal, const std::string& snapshot_type);
|
void do_flatten(const Vec3d& normal, const std::string& snapshot_type);
|
||||||
|
void do_center();
|
||||||
void do_mirror(const std::string& snapshot_type);
|
void do_mirror(const std::string& snapshot_type);
|
||||||
|
|
||||||
void update_gizmos_on_off_state();
|
void update_gizmos_on_off_state();
|
||||||
|
|
|
@ -892,6 +892,8 @@ void MenuFactory::create_bbl_object_menu()
|
||||||
append_menu_item_fix_through_netfabb(&m_object_menu);
|
append_menu_item_fix_through_netfabb(&m_object_menu);
|
||||||
// Object Simplify
|
// Object Simplify
|
||||||
append_menu_item_simplify(&m_object_menu);
|
append_menu_item_simplify(&m_object_menu);
|
||||||
|
// Object Center
|
||||||
|
append_menu_item_center(&m_object_menu);
|
||||||
// Object Split
|
// Object Split
|
||||||
wxMenu* split_menu = new wxMenu();
|
wxMenu* split_menu = new wxMenu();
|
||||||
if (!split_menu)
|
if (!split_menu)
|
||||||
|
@ -983,6 +985,7 @@ void MenuFactory::create_bbl_part_menu()
|
||||||
append_menu_item_delete(menu);
|
append_menu_item_delete(menu);
|
||||||
append_menu_item_fix_through_netfabb(menu);
|
append_menu_item_fix_through_netfabb(menu);
|
||||||
append_menu_item_simplify(menu);
|
append_menu_item_simplify(menu);
|
||||||
|
append_menu_item_center(menu);
|
||||||
append_menu_items_mirror(menu);
|
append_menu_items_mirror(menu);
|
||||||
wxMenu* split_menu = new wxMenu();
|
wxMenu* split_menu = new wxMenu();
|
||||||
if (!split_menu)
|
if (!split_menu)
|
||||||
|
@ -1182,6 +1185,7 @@ wxMenu* MenuFactory::multi_selection_menu()
|
||||||
append_menu_item_merge_to_multipart_object(menu);
|
append_menu_item_merge_to_multipart_object(menu);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
append_menu_item_center(menu);
|
||||||
append_menu_item_fix_through_netfabb(menu);
|
append_menu_item_fix_through_netfabb(menu);
|
||||||
//append_menu_item_simplify(menu);
|
//append_menu_item_simplify(menu);
|
||||||
append_menu_item_delete(menu);
|
append_menu_item_delete(menu);
|
||||||
|
@ -1196,6 +1200,7 @@ wxMenu* MenuFactory::multi_selection_menu()
|
||||||
append_menu_item_export_stl(menu, true);
|
append_menu_item_export_stl(menu, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
append_menu_item_center(menu);
|
||||||
append_menu_item_fix_through_netfabb(menu);
|
append_menu_item_fix_through_netfabb(menu);
|
||||||
//append_menu_item_simplify(menu);
|
//append_menu_item_simplify(menu);
|
||||||
append_menu_item_delete(menu);
|
append_menu_item_delete(menu);
|
||||||
|
@ -1279,6 +1284,25 @@ void MenuFactory::append_menu_item_simplify(wxMenu* menu)
|
||||||
[]() {return plater()->can_simplify(); }, m_parent);
|
[]() {return plater()->can_simplify(); }, m_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuFactory::append_menu_item_center(wxMenu* menu)
|
||||||
|
{
|
||||||
|
append_menu_item(menu, wxID_ANY, _L("Center") , "",
|
||||||
|
[this](wxCommandEvent&) {
|
||||||
|
plater()->center_selection();
|
||||||
|
}, "", nullptr,
|
||||||
|
[]() {
|
||||||
|
if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
|
||||||
|
return false;
|
||||||
|
else {
|
||||||
|
Selection& selection = plater()->get_view3D_canvas3D()->get_selection();
|
||||||
|
PartPlate* plate = plater()->get_partplate_list().get_selected_plate();
|
||||||
|
Vec3d model_pos = selection.get_bounding_box().center();
|
||||||
|
Vec3d center_pos = plate->get_center_origin();
|
||||||
|
return !( (model_pos.x() == center_pos.x()) && (model_pos.y() == center_pos.y()) );
|
||||||
|
} //disable if model is at center / not in View3D
|
||||||
|
}, m_parent);
|
||||||
|
}
|
||||||
|
|
||||||
void MenuFactory::append_menu_item_per_object_settings(wxMenu* menu)
|
void MenuFactory::append_menu_item_per_object_settings(wxMenu* menu)
|
||||||
{
|
{
|
||||||
const std::vector<wxString> names = { _L("Edit in Parameter Table"), _L("Edit print parameters for a single object") };
|
const std::vector<wxString> names = { _L("Edit in Parameter Table"), _L("Edit print parameters for a single object") };
|
||||||
|
|
|
@ -138,6 +138,7 @@ private:
|
||||||
//BBS add bbl menu item
|
//BBS add bbl menu item
|
||||||
void append_menu_item_clone(wxMenu* menu);
|
void append_menu_item_clone(wxMenu* menu);
|
||||||
void append_menu_item_simplify(wxMenu* menu);
|
void append_menu_item_simplify(wxMenu* menu);
|
||||||
|
void append_menu_item_center(wxMenu* menu);
|
||||||
void append_menu_item_per_object_settings(wxMenu* menu);
|
void append_menu_item_per_object_settings(wxMenu* menu);
|
||||||
void append_menu_item_change_filament(wxMenu* menu);
|
void append_menu_item_change_filament(wxMenu* menu);
|
||||||
void append_menu_item_set_printable(wxMenu* menu);
|
void append_menu_item_set_printable(wxMenu* menu);
|
||||||
|
|
|
@ -148,6 +148,12 @@ void View3D::delete_selected()
|
||||||
m_canvas->delete_selected();
|
m_canvas->delete_selected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void View3D::center_selected()
|
||||||
|
{
|
||||||
|
if (m_canvas != nullptr)
|
||||||
|
m_canvas->do_center();
|
||||||
|
}
|
||||||
|
|
||||||
void View3D::mirror_selection(Axis axis)
|
void View3D::mirror_selection(Axis axis)
|
||||||
{
|
{
|
||||||
if (m_canvas != nullptr)
|
if (m_canvas != nullptr)
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
void select_all();
|
void select_all();
|
||||||
void deselect_all();
|
void deselect_all();
|
||||||
void delete_selected();
|
void delete_selected();
|
||||||
|
void center_selected();
|
||||||
void mirror_selection(Axis axis);
|
void mirror_selection(Axis axis);
|
||||||
|
|
||||||
bool is_dragging() const;
|
bool is_dragging() const;
|
||||||
|
|
|
@ -1250,7 +1250,7 @@ Vec3d PartPlate::get_center_origin()
|
||||||
Vec3d origin;
|
Vec3d origin;
|
||||||
|
|
||||||
origin(0) = (m_bounding_box.min(0) + m_bounding_box.max(0)) / 2;//m_origin.x() + m_width / 2;
|
origin(0) = (m_bounding_box.min(0) + m_bounding_box.max(0)) / 2;//m_origin.x() + m_width / 2;
|
||||||
origin(1) = (m_bounding_box.min(0) + m_bounding_box.max(0)) / 2; //m_origin.y() + m_depth / 2;
|
origin(1) = (m_bounding_box.min(1) + m_bounding_box.max(1)) / 2; //m_origin.y() + m_depth / 2;
|
||||||
origin(2) = m_origin.z();
|
origin(2) = m_origin.z();
|
||||||
|
|
||||||
return origin;
|
return origin;
|
||||||
|
|
|
@ -1676,6 +1676,7 @@ struct Plater::priv
|
||||||
void delete_object_from_model(size_t obj_idx, bool refresh_immediately = true); //BBS
|
void delete_object_from_model(size_t obj_idx, bool refresh_immediately = true); //BBS
|
||||||
void delete_all_objects_from_model();
|
void delete_all_objects_from_model();
|
||||||
void reset(bool apply_presets_change = false);
|
void reset(bool apply_presets_change = false);
|
||||||
|
void center_selection();
|
||||||
void mirror(Axis axis);
|
void mirror(Axis axis);
|
||||||
void split_object();
|
void split_object();
|
||||||
void split_volume();
|
void split_volume();
|
||||||
|
@ -3696,6 +3697,11 @@ void Plater::priv::reset(bool apply_presets_change)
|
||||||
m_saved_timestamp = m_backup_timestamp = size_t(-1);
|
m_saved_timestamp = m_backup_timestamp = size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Plater::priv::center_selection()
|
||||||
|
{
|
||||||
|
view3D->center_selected();
|
||||||
|
}
|
||||||
|
|
||||||
void Plater::priv::mirror(Axis axis)
|
void Plater::priv::mirror(Axis axis)
|
||||||
{
|
{
|
||||||
view3D->mirror_selection(axis);
|
view3D->mirror_selection(axis);
|
||||||
|
@ -9456,6 +9462,7 @@ void Plater::suppress_background_process(const bool stop_background_process)
|
||||||
this->p->suppressed_backround_processing_update = true;
|
this->p->suppressed_backround_processing_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Plater::center_selection() { p->center_selection(); }
|
||||||
void Plater::mirror(Axis axis) { p->mirror(axis); }
|
void Plater::mirror(Axis axis) { p->mirror(axis); }
|
||||||
void Plater::split_object() { p->split_object(); }
|
void Plater::split_object() { p->split_object(); }
|
||||||
void Plater::split_volume() { p->split_volume(); }
|
void Plater::split_volume() { p->split_volume(); }
|
||||||
|
|
|
@ -411,6 +411,7 @@ public:
|
||||||
void paste_from_clipboard();
|
void paste_from_clipboard();
|
||||||
//BBS: add clone logic
|
//BBS: add clone logic
|
||||||
void clone_selection();
|
void clone_selection();
|
||||||
|
void center_selection();
|
||||||
void search(bool plater_is_active, Preset::Type type, wxWindow *tag, wxTextCtrl *etag, wxWindow *stag);
|
void search(bool plater_is_active, Preset::Type type, wxWindow *tag, wxTextCtrl *etag, wxWindow *stag);
|
||||||
void mirror(Axis axis);
|
void mirror(Axis axis);
|
||||||
void split_object();
|
void split_object();
|
||||||
|
|
|
@ -450,6 +450,20 @@ void Selection::clone(int numbers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Selection::center()
|
||||||
|
{
|
||||||
|
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_selected_plate();
|
||||||
|
|
||||||
|
// calc distance
|
||||||
|
Vec3d src_pos = this->get_bounding_box().center();
|
||||||
|
Vec3d tar_pos = plate->get_center_origin();
|
||||||
|
Vec3d distance = Vec3d(tar_pos.x() - src_pos.x(), tar_pos.y() - src_pos.y(), 0);
|
||||||
|
|
||||||
|
this->move_to_center(distance);
|
||||||
|
wxGetApp().plater()->get_view3D_canvas3D()->do_move(L("Move Object"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//BBS
|
//BBS
|
||||||
void Selection::set_printable(bool printable)
|
void Selection::set_printable(bool printable)
|
||||||
{
|
{
|
||||||
|
@ -806,6 +820,39 @@ void Selection::start_dragging()
|
||||||
set_caches();
|
set_caches();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Selection::move_to_center(const Vec3d& displacement, bool local)
|
||||||
|
{
|
||||||
|
if (!m_valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
EMode translation_type = m_mode;
|
||||||
|
//BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": %1%, displacement {%2%, %3%, %4%}") % __LINE__ % displacement(X) % displacement(Y) % displacement(Z);
|
||||||
|
|
||||||
|
set_caches();
|
||||||
|
for (unsigned int i : m_list) {
|
||||||
|
GLVolume& v = *(*m_volumes)[i];
|
||||||
|
if (m_mode == Volume) {
|
||||||
|
if (local)
|
||||||
|
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement);
|
||||||
|
else {
|
||||||
|
const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||||
|
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_mode == Instance) {
|
||||||
|
if (is_from_fully_selected_instance(i)) {
|
||||||
|
v.set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||||
|
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||||
|
translation_type = Volume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->set_bounding_boxes_dirty();
|
||||||
|
}
|
||||||
|
|
||||||
void Selection::translate(const Vec3d& displacement, bool local)
|
void Selection::translate(const Vec3d& displacement, bool local)
|
||||||
{
|
{
|
||||||
if (!m_valid)
|
if (!m_valid)
|
||||||
|
|
|
@ -262,6 +262,7 @@ public:
|
||||||
void add_curr_plate();
|
void add_curr_plate();
|
||||||
void remove_curr_plate();
|
void remove_curr_plate();
|
||||||
void clone(int numbers = 1);
|
void clone(int numbers = 1);
|
||||||
|
void center();
|
||||||
void set_printable(bool printable);
|
void set_printable(bool printable);
|
||||||
|
|
||||||
void add_all();
|
void add_all();
|
||||||
|
@ -330,6 +331,7 @@ public:
|
||||||
bool is_dragging() const { return m_dragging; }
|
bool is_dragging() const { return m_dragging; }
|
||||||
|
|
||||||
void translate(const Vec3d& displacement, bool local = false);
|
void translate(const Vec3d& displacement, bool local = false);
|
||||||
|
void move_to_center(const Vec3d& displacement, bool local = false);
|
||||||
void rotate(const Vec3d& rotation, TransformationType transformation_type);
|
void rotate(const Vec3d& rotation, TransformationType transformation_type);
|
||||||
void flattening_rotate(const Vec3d& normal);
|
void flattening_rotate(const Vec3d& normal);
|
||||||
void scale(const Vec3d& scale, TransformationType transformation_type);
|
void scale(const Vec3d& scale, TransformationType transformation_type);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue