Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/slic3r/GUI/GUI_ObjectManipulation.cpp')
-rw-r--r--src/slic3r/GUI/GUI_ObjectManipulation.cpp146
1 files changed, 108 insertions, 38 deletions
diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
index 36293525a..8a4c28096 100644
--- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp
+++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
@@ -2,12 +2,16 @@
#include "GUI_ObjectList.hpp"
#include "I18N.hpp"
+#include "GLCanvas3D.hpp"
#include "OptionsGroup.hpp"
+#include "GUI_App.hpp"
#include "wxExtensions.hpp"
-#include "PresetBundle.hpp"
+#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/Geometry.hpp"
#include "Selection.hpp"
+#include "Plater.hpp"
+#include "MainFrame.hpp"
#include <boost/algorithm/string.hpp>
#include "slic3r/Utils/FixModelByWin10.hpp"
@@ -17,6 +21,8 @@ namespace Slic3r
namespace GUI
{
+const double ObjectManipulation::in_to_mm = 25.4;
+const double ObjectManipulation::mm_to_in = 0.0393700787;
// Helper function to be used by drop to bed button. Returns lowest point of this
// volume in world coordinate system.
@@ -59,8 +65,8 @@ static wxBitmapComboBox* create_word_local_combo(wxWindow *parent)
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
- temp->Append(_(L("World coordinates")));
- temp->Append(_(L("Local coordinates")));
+ temp->Append(_L("World coordinates"));
+ temp->Append(_L("Local coordinates"));
temp->SetSelection(0);
temp->SetValue(temp->GetString(0));
@@ -79,7 +85,7 @@ static wxBitmapComboBox* create_word_local_combo(wxWindow *parent)
temp->SetItemBitmap(0, empty_bmp);
#endif
- temp->SetToolTip(_(L("Select coordinate space, in which the transformation will be performed.")));
+ temp->SetToolTip(_L("Select coordinate space, in which the transformation will be performed."));
return temp;
}
@@ -102,8 +108,8 @@ void msw_rescale_word_local_combo(wxBitmapComboBox* combo)
// Set rescaled size
combo->SetSize(size);
- combo->Append(_(L("World coordinates")));
- combo->Append(_(L("Local coordinates")));
+ combo->Append(_L("World coordinates"));
+ combo->Append(_L("Local coordinates"));
wxBitmap empty_bmp(1, combo->GetFont().GetPixelSize().y + 2);
empty_bmp.SetWidth(0);
@@ -121,6 +127,8 @@ static void set_font_and_background_style(wxWindow* win, const wxFont& font)
ObjectManipulation::ObjectManipulation(wxWindow* parent) :
OG_Settings(parent, true)
{
+ m_imperial_units = wxGetApp().app_config->get("use_inches") == "1";
+
m_manifold_warning_bmp = ScalableBitmap(parent, "exclamation");
// Load bitmaps to be used for the mirroring buttons:
@@ -150,9 +158,9 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
sizer->Add(m_fix_throught_netfab_bitmap);
- auto name_label = new wxStaticText(m_parent, wxID_ANY, _(L("Name"))+":");
+ auto name_label = new wxStaticText(m_parent, wxID_ANY, _L("Name")+":");
set_font_and_background_style(name_label, wxGetApp().normal_font());
- name_label->SetToolTip(_(L("Object name")));
+ name_label->SetToolTip(_L("Object name"));
sizer->Add(name_label);
m_main_grid_sizer->Add(sizer);
@@ -260,7 +268,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
// We will add a button to toggle mirroring to each axis:
auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW);
- btn->SetToolTip(wxString::Format(_(L("Toggle %c axis mirroring")), (int)label));
+ btn->SetToolTip(wxString::Format(_L("Toggle %c axis mirroring"), (int)label));
btn->SetBitmapDisabled_(m_mirror_bitmap_hidden);
m_mirror_buttons[axis_idx].first = btn;
@@ -314,15 +322,15 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
};
// add Units
- auto add_unit_text = [this, parent, editors_grid_sizer, height](std::string unit)
+ auto add_unit_text = [this, parent, editors_grid_sizer, height](std::string unit, wxStaticText** unit_text)
{
- wxStaticText* unit_text = new wxStaticText(parent, wxID_ANY, _(unit));
- set_font_and_background_style(unit_text, wxGetApp().normal_font());
+ *unit_text = new wxStaticText(parent, wxID_ANY, _(unit));
+ set_font_and_background_style(*unit_text, wxGetApp().normal_font());
// Unit text should be the same height as labels
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->SetMinSize(wxSize(-1, height));
- sizer->Add(unit_text, 0, wxALIGN_CENTER_VERTICAL);
+ sizer->Add(*unit_text, 0, wxALIGN_CENTER_VERTICAL);
editors_grid_sizer->Add(sizer);
m_rescalable_sizers.push_back(sizer);
@@ -330,11 +338,11 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
for (size_t axis_idx = 0; axis_idx < sizeof(axes); axis_idx++)
add_edit_boxes("position", axis_idx);
- add_unit_text(L("mm"));
+ add_unit_text(m_imperial_units ? L("in") : L("mm"), &m_position_unit);
// Add drop to bed button
m_drop_to_bed_button = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "drop_to_bed"));
- m_drop_to_bed_button->SetToolTip(_(L("Drop to bed")));
+ m_drop_to_bed_button->SetToolTip(_L("Drop to bed"));
m_drop_to_bed_button->Bind(wxEVT_BUTTON, [=](wxCommandEvent& e) {
// ???
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
@@ -346,7 +354,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
const Geometry::Transformation& instance_trafo = volume->get_instance_transformation();
Vec3d diff = m_cache.position - instance_trafo.get_matrix(true).inverse() * Vec3d(0., 0., get_volume_min_z(volume));
- Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Drop to bed")));
+ Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Drop to bed"));
change_position_value(0, diff.x());
change_position_value(1, diff.y());
change_position_value(2, diff.z());
@@ -356,11 +364,12 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
for (size_t axis_idx = 0; axis_idx < sizeof(axes); axis_idx++)
add_edit_boxes("rotation", axis_idx);
- add_unit_text("°");
+ wxStaticText* rotation_unit{ nullptr };
+ add_unit_text("°", &rotation_unit);
// Add reset rotation button
m_reset_rotation_button = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo"));
- m_reset_rotation_button->SetToolTip(_(L("Reset rotation")));
+ m_reset_rotation_button->SetToolTip(_L("Reset rotation"));
m_reset_rotation_button->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
Selection& selection = canvas->get_selection();
@@ -390,13 +399,14 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
for (size_t axis_idx = 0; axis_idx < sizeof(axes); axis_idx++)
add_edit_boxes("scale", axis_idx);
- add_unit_text("%");
+ wxStaticText* scale_unit{ nullptr };
+ add_unit_text("%", &scale_unit);
// Add reset scale button
m_reset_scale_button = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo"));
- m_reset_scale_button->SetToolTip(_(L("Reset scale")));
+ m_reset_scale_button->SetToolTip(_L("Reset scale"));
m_reset_scale_button->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
- Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Reset scale")));
+ Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Reset scale"));
change_scale_value(0, 100.);
change_scale_value(1, 100.);
change_scale_value(2, 100.);
@@ -405,11 +415,23 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
for (size_t axis_idx = 0; axis_idx < sizeof(axes); axis_idx++)
add_edit_boxes("size", axis_idx);
- add_unit_text("mm");
+ add_unit_text(m_imperial_units ? L("in") : L("mm"), &m_size_unit);
editors_grid_sizer->AddStretchSpacer(1);
m_main_grid_sizer->Add(editors_grid_sizer, 1, wxEXPAND);
+ m_check_inch = new wxCheckBox(parent, wxID_ANY, _L("Inches"));
+ m_check_inch->SetFont(wxGetApp().normal_font());
+
+ m_check_inch->SetValue(m_imperial_units);
+ m_check_inch->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) {
+ wxGetApp().app_config->set("use_inches", m_check_inch->GetValue() ? "1" : "0");
+ wxGetApp().sidebar().update_ui_from_settings();
+ });
+
+ m_main_grid_sizer->Add(m_check_inch, 1, wxEXPAND);
+
+ m_og->activate();
m_og->sizer->Clear(true);
m_og->sizer->Add(m_main_grid_sizer, 1, wxEXPAND | wxALL, border);
}
@@ -452,6 +474,32 @@ void ObjectManipulation::UpdateAndShow(const bool show)
OG_Settings::UpdateAndShow(show);
}
+void ObjectManipulation::update_ui_from_settings()
+{
+ if (m_imperial_units != (wxGetApp().app_config->get("use_inches") == "1")) {
+ m_imperial_units = wxGetApp().app_config->get("use_inches") == "1";
+
+ auto update_unit_text = [](const wxString& new_unit_text, wxStaticText* widget) {
+ widget->SetLabel(new_unit_text);
+ if (wxOSX) set_font_and_background_style(widget, wxGetApp().normal_font());
+ };
+ update_unit_text(m_imperial_units ? _L("in") : _L("mm"), m_position_unit);
+ update_unit_text(m_imperial_units ? _L("in") : _L("mm"), m_size_unit);
+
+ for (int i = 0; i < 3; ++i) {
+ auto update = [this, i](/*ManipulationEditorKey*/int key_id, const Vec3d& new_value) {
+ wxString new_text = double_to_string(m_imperial_units ? new_value(i) * mm_to_in : new_value(i), 2);
+ const int id = key_id * 3 + i;
+ if (id >= 0) m_editors[id]->set_value(new_text);
+ };
+ update(0/*mePosition*/, m_new_position);
+ update(3/*meSize*/, m_new_size);
+ }
+ }
+
+ m_check_inch->SetValue(m_imperial_units);
+}
+
void ObjectManipulation::update_settings_value(const Selection& selection)
{
m_new_move_label_string = L("Position");
@@ -462,8 +510,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
m_world_coordinates = true;
ObjectList* obj_list = wxGetApp().obj_list();
- if (selection.is_single_full_instance())
- {
+ if (selection.is_single_full_instance()) {
// all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
m_new_position = volume->get_instance_offset();
@@ -481,7 +528,8 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
m_new_rotation = Vec3d::Zero();
m_new_size = selection.get_scaled_instance_bounding_box().size();
m_new_scale = m_new_size.cwiseProduct(selection.get_unscaled_instance_bounding_box().size().cwiseInverse()) * 100.;
- } else {
+ }
+ else {
m_new_rotation = volume->get_instance_rotation() * (180. / M_PI);
m_new_size = volume->get_instance_transformation().get_scaling_factor().cwiseProduct(wxGetApp().model().objects[volume->object_idx()]->raw_mesh_bounding_box().size());
m_new_scale = volume->get_instance_scaling_factor() * 100.;
@@ -489,8 +537,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
m_new_enabled = true;
}
- else if (selection.is_single_full_object() && obj_list->is_selected(itObject))
- {
+ else if (selection.is_single_full_object() && obj_list->is_selected(itObject)) {
const BoundingBoxf3& box = selection.get_bounding_box();
m_new_position = box.center();
m_new_rotation = Vec3d::Zero();
@@ -500,18 +547,16 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
m_new_scale_label_string = L("Scale");
m_new_enabled = true;
}
- else if (selection.is_single_modifier() || selection.is_single_volume())
- {
+ else if (selection.is_single_modifier() || selection.is_single_volume()) {
// the selection contains a single volume
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
m_new_position = volume->get_volume_offset();
m_new_rotation = volume->get_volume_rotation() * (180. / M_PI);
m_new_scale = volume->get_volume_scaling_factor() * 100.;
- m_new_size = volume->get_volume_transformation().get_scaling_factor().cwiseProduct(volume->bounding_box().size());
+ m_new_size = volume->get_instance_transformation().get_scaling_factor().cwiseProduct(volume->get_volume_transformation().get_scaling_factor().cwiseProduct(volume->bounding_box().size()));
m_new_enabled = true;
}
- else if (obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot))
- {
+ else if (obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) {
reset_settings_value();
m_new_move_label_string = L("Translate");
m_new_rotate_label_string = L("Rotate");
@@ -562,6 +607,8 @@ void ObjectManipulation::update_if_dirty()
if (std::abs(cached_rounded(i) - new_rounded) > EPSILON) {
cached_rounded(i) = new_rounded;
const int id = key_id*3+i;
+ if (m_imperial_units && (key_id == mePosition || key_id == meSize))
+ new_text = double_to_string(new_value(i)*mm_to_in, 2);
if (id >= 0) m_editors[id]->set_value(new_text);
}
cached(i) = new_value(i);
@@ -575,7 +622,7 @@ void ObjectManipulation::update_if_dirty()
if (selection.requires_uniform_scale()) {
m_lock_bnt->SetLock(true);
- m_lock_bnt->SetToolTip(_(L("You cannot use non-uniform scaling mode for multiple objects/parts selection")));
+ m_lock_bnt->SetToolTip(_L("You cannot use non-uniform scaling mode for multiple objects/parts selection"));
m_lock_bnt->disable();
}
else {
@@ -851,6 +898,9 @@ void ObjectManipulation::on_change(const std::string& opt_key, int axis, double
if (!m_cache.is_valid())
return;
+ if (m_imperial_units && (opt_key == "position" || opt_key == "size"))
+ new_value *= in_to_mm;
+
if (opt_key == "position")
change_position_value(axis, new_value);
else if (opt_key == "rotation")
@@ -872,11 +922,11 @@ void ObjectManipulation::set_uniform_scaling(const bool new_value)
if (! Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) {
// Cannot apply scaling in the world coordinate system.
wxMessageDialog dlg(GUI::wxGetApp().mainframe,
- _(L("The currently manipulated object is tilted (rotation angles are not multiples of 90°).\n"
+ _L("The currently manipulated object is tilted (rotation angles are not multiples of 90°).\n"
"Non-uniform scaling of tilted objects is only possible in the World coordinate system,\n"
- "once the rotation is embedded into the object coordinates.")) + "\n" +
- _(L("This operation is irreversible.\n"
- "Do you want to proceed?")),
+ "once the rotation is embedded into the object coordinates.") + "\n" +
+ _L("This operation is irreversible.\n"
+ "Do you want to proceed?"),
SLIC3R_APP_NAME,
wxYES_NO | wxCANCEL | wxCANCEL_DEFAULT | wxICON_QUESTION);
if (dlg.ShowModal() != wxID_YES) {
@@ -929,15 +979,35 @@ void ObjectManipulation::msw_rescale()
for (ManipulationEditor* editor : m_editors)
editor->msw_rescale();
+ // rescale "inches" checkbox
+ m_check_inch->SetMinSize(wxSize(-1, int(1.5f * m_check_inch->GetFont().GetPixelSize().y + 0.5f)));
+
get_og()->msw_rescale();
}
+void ObjectManipulation::sys_color_changed()
+{
+ // btn...->msw_rescale() updates icon on button, so use it
+ m_mirror_bitmap_on.msw_rescale();
+ m_mirror_bitmap_off.msw_rescale();
+ m_mirror_bitmap_hidden.msw_rescale();
+ m_reset_scale_button->msw_rescale();
+ m_reset_rotation_button->msw_rescale();
+ m_drop_to_bed_button->msw_rescale();
+ m_lock_bnt->msw_rescale();
+
+ for (int id = 0; id < 3; ++id)
+ m_mirror_buttons[id].first->msw_rescale();
+
+ get_og()->sys_color_changed();
+}
+
static const char axes[] = { 'x', 'y', 'z' };
ManipulationEditor::ManipulationEditor(ObjectManipulation* parent,
const std::string& opt_key,
int axis) :
wxTextCtrl(parent->parent(), wxID_ANY, wxEmptyString, wxDefaultPosition,
- wxSize(5*int(wxGetApp().em_unit()), wxDefaultCoord), wxTE_PROCESS_ENTER),
+ wxSize((wxOSX ? 5 : 6)*int(wxGetApp().em_unit()), wxDefaultCoord), wxTE_PROCESS_ENTER),
m_opt_key(opt_key),
m_axis(axis)
{