diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 9e3d088c4..bf9033230 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -87,7 +87,7 @@ // Enable editing volumes transformation in world coordinates and instances in local coordinates #define ENABLE_WORLD_COORDINATE (1 && ENABLE_2_4_0_ALPHA4) // Enable showing world coordinates of volumes' offset relative to the instance containing them -#define ENABLE_WORLD_COORDINATE_VOLUMES_LOCAL_OFFSET (1 && ENABLE_WORLD_COORDINATE) +#define ENABLE_WORLD_COORDINATE_VOLUMES_LOCAL_OFFSET (0 && ENABLE_WORLD_COORDINATE) // Enable editing instance coordinates of volumes #define ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES (1 && ENABLE_WORLD_COORDINATE) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 9a5252949..489b8f270 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -85,6 +85,8 @@ set(SLIC3R_GUI_SOURCES GUI/GUI_App.hpp GUI/GUI_Utils.cpp GUI/GUI_Utils.hpp + GUI/GUI_Geometry.cpp + GUI/GUI_Geometry.hpp GUI/I18N.cpp GUI/I18N.hpp GUI/MainFrame.cpp diff --git a/src/slic3r/GUI/GUI_Geometry.cpp b/src/slic3r/GUI/GUI_Geometry.cpp new file mode 100644 index 000000000..b0ed0e04f --- /dev/null +++ b/src/slic3r/GUI/GUI_Geometry.cpp @@ -0,0 +1,9 @@ +#include "libslic3r/libslic3r.h" +#include "GUI_Geometry.hpp" + +namespace Slic3r { +namespace GUI { + + +} // namespace Slic3r +} // namespace GUI diff --git a/src/slic3r/GUI/GUI_Geometry.hpp b/src/slic3r/GUI/GUI_Geometry.hpp new file mode 100644 index 000000000..23dd36c39 --- /dev/null +++ b/src/slic3r/GUI/GUI_Geometry.hpp @@ -0,0 +1,72 @@ +#ifndef slic3r_GUI_Geometry_hpp_ +#define slic3r_GUI_Geometry_hpp_ + +namespace Slic3r { +namespace GUI { + +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES +enum class ECoordinatesType : unsigned char +{ + World, + Instance, + Local +}; + +class TransformationType +{ +public: + enum Enum { + // Transforming in a world coordinate system + World = 0, + // Transforming in a local coordinate system + Local = 1, + // Absolute transformations, allowed in local coordinate system only. + Absolute = 0, + // Relative transformations, allowed in both local and world coordinate system. + Relative = 2, + // For group selection, the transformation is performed as if the group made a single solid body. + Joint = 0, + // For group selection, the transformation is performed on each object independently. + Independent = 4, + + World_Relative_Joint = World | Relative | Joint, + World_Relative_Independent = World | Relative | Independent, + Local_Absolute_Joint = Local | Absolute | Joint, + Local_Absolute_Independent = Local | Absolute | Independent, + Local_Relative_Joint = Local | Relative | Joint, + Local_Relative_Independent = Local | Relative | Independent, + }; + + TransformationType() : m_value(World) {} + TransformationType(Enum value) : m_value(value) {} + TransformationType& operator=(Enum value) { m_value = value; return *this; } + + Enum operator()() const { return m_value; } + bool has(Enum v) const { return ((unsigned int)m_value & (unsigned int)v) != 0; } + + void set_world() { this->remove(Local); } + void set_local() { this->add(Local); } + void set_absolute() { this->remove(Relative); } + void set_relative() { this->add(Relative); } + void set_joint() { this->remove(Independent); } + void set_independent() { this->add(Independent); } + + bool world() const { return !this->has(Local); } + bool local() const { return this->has(Local); } + bool absolute() const { return !this->has(Relative); } + bool relative() const { return this->has(Relative); } + bool joint() const { return !this->has(Independent); } + bool independent() const { return this->has(Independent); } + +private: + void add(Enum v) { m_value = Enum((unsigned int)m_value | (unsigned int)v); } + void remove(Enum v) { m_value = Enum((unsigned int)m_value & (~(unsigned int)v)); } + + Enum m_value; +}; +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES + +} // namespace Slic3r +} // namespace GUI + +#endif // slic3r_GUI_Geometry_hpp_ diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index a9c69c730..b7ba3a210 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -53,10 +53,10 @@ static choice_ctrl* create_word_local_combo(wxWindow *parent) if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); #if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES - temp->Append(ObjectManipulation::coordinate_type_str(ObjectManipulation::ECoordinatesType::World)); - temp->Append(ObjectManipulation::coordinate_type_str(ObjectManipulation::ECoordinatesType::Instance)); - temp->Append(ObjectManipulation::coordinate_type_str(ObjectManipulation::ECoordinatesType::Local)); - temp->Select((int)ObjectManipulation::ECoordinatesType::World); + temp->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::World)); + temp->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Instance)); + temp->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Local)); + temp->Select((int)ECoordinatesType::World); #else temp->Append(_L("World coordinates")); temp->Append(_L("Local coordinates")); @@ -978,7 +978,7 @@ wxString ObjectManipulation::coordinate_type_str(ECoordinatesType type) case ECoordinatesType::World: { return _L("World coordinates"); } case ECoordinatesType::Instance: { return _L("Instance coordinates"); } case ECoordinatesType::Local: { return _L("Local coordinates"); } - default: { assert(false); break; } + default: { assert(false); return _L("Unknown"); } } } #endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES @@ -1008,7 +1008,7 @@ void ObjectManipulation::change_position_value(int axis, double value) selection.start_dragging(); #if ENABLE_WORLD_COORDINATE #if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES - selection.translate(position - m_cache.position, !is_world_coordinates()); + selection.translate(position - m_cache.position, get_coordinates_type()); #else selection.translate(position - m_cache.position, !m_world_coordinates); #endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index d0c38cc47..6a074f339 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -5,6 +5,9 @@ #include "GUI_ObjectSettings.hpp" #include "GUI_ObjectList.hpp" +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES +#include "GUI_Geometry.hpp" +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES #include "libslic3r/Point.hpp" #include @@ -72,15 +75,6 @@ public: static const double in_to_mm; static const double mm_to_in; -#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES - enum class ECoordinatesType : unsigned char - { - World, - Instance, - Local - }; -#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES - private: struct Cache { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 88cb84137..d41c938df 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -75,13 +75,20 @@ void GLGizmoMove3D::on_start_dragging() m_displacement = Vec3d::Zero(); #if ENABLE_WORLD_COORDINATE #if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES - if (wxGetApp().obj_manipul()->is_world_coordinates()) + const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); + const Selection& selection = m_parent.get_selection(); + if (coordinates_type == ECoordinatesType::World) #else if (wxGetApp().obj_manipul()->get_world_coordinates()) #endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES m_starting_drag_position = m_center + m_grabbers[m_hover_id].center; +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES + else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) { + const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin()); + m_starting_drag_position = m_center + Geometry::assemble_transform(Vec3d::Zero(), v.get_instance_rotation()) * Geometry::assemble_transform(Vec3d::Zero(), v.get_volume_rotation()) * m_grabbers[m_hover_id].center; + } +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES else { - const Selection& selection = m_parent.get_selection(); const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin()); m_starting_drag_position = m_center + Geometry::assemble_transform(Vec3d::Zero(), v.get_instance_rotation()) * m_grabbers[m_hover_id].center; } @@ -320,25 +327,39 @@ void GLGizmoMove3D::transform_to_local(const Selection& selection) const #if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES if (!wxGetApp().obj_manipul()->is_world_coordinates()) { + const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin()); + Transform3d orient_matrix = v.get_instance_transformation().get_matrix(true, false, true, true); + if (selection.is_single_volume_or_modifier() && wxGetApp().obj_manipul()->is_local_coordinates()) + orient_matrix = orient_matrix * v.get_volume_transformation().get_matrix(true, false, true, true); + glsafe(::glMultMatrixd(orient_matrix.data())); + } #else if (!wxGetApp().obj_manipul()->get_world_coordinates()) { -#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES const Transform3d orient_matrix = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true); glsafe(::glMultMatrixd(orient_matrix.data())); } +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES } void GLGizmoMove3D::calc_selection_box_and_center() { const Selection& selection = m_parent.get_selection(); #if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES - if (wxGetApp().obj_manipul()->is_world_coordinates()) { + const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); + if (coordinates_type == ECoordinatesType::World) { #else if (wxGetApp().obj_manipul()->get_world_coordinates()) { #endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES m_bounding_box = selection.get_bounding_box(); m_center = m_bounding_box.center(); } +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES + else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) { + const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin()); + m_bounding_box = v.transformed_convex_hull_bounding_box(v.get_instance_transformation().get_matrix(true, true, false, true) * v.get_volume_transformation().get_matrix(true, true, false, true)); + m_center = v.world_matrix() * m_bounding_box.center(); + } +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES else { m_bounding_box.reset(); const Selection::IndicesList& ids = selection.get_volume_idxs(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 632070485..7202f1bff 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -622,7 +622,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) // Apply new temporary offset #if ENABLE_WORLD_COORDINATE #if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES - selection.translate(get_displacement(), !wxGetApp().obj_manipul()->is_world_coordinates()); + selection.translate(get_displacement(), wxGetApp().obj_manipul()->get_coordinates_type()); #else selection.translate(get_displacement(), !wxGetApp().obj_manipul()->get_world_coordinates()); #endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES @@ -652,7 +652,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) if (control_down) #if ENABLE_WORLD_COORDINATE #if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES - selection.translate(get_scale_offset(), !wxGetApp().obj_manipul()->is_world_coordinates()); + selection.translate(get_scale_offset(), wxGetApp().obj_manipul()->get_coordinates_type()); #else selection.translate(get_scale_offset(), !wxGetApp().obj_manipul()->get_world_coordinates()); #endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9ae9af2ef..814c7dafa 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -56,6 +56,9 @@ #include "GUI_ObjectManipulation.hpp" #include "GUI_ObjectLayers.hpp" #include "GUI_Utils.hpp" +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES +#include "GUI_Geometry.hpp" +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES #include "GUI_Factories.hpp" #include "wxExtensions.hpp" #include "MainFrame.hpp" @@ -1447,7 +1450,7 @@ void Sidebar::update_mode() #if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES if (m_mode == comSimple) - p->object_manipulation->set_coordinates_type(ObjectManipulation::ECoordinatesType::World); + p->object_manipulation->set_coordinates_type(ECoordinatesType::World); #endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES p->object_list->get_sizer()->Show(m_mode > comSimple); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index fa99d5309..e388c8cbd 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -714,7 +714,11 @@ void Selection::start_dragging() set_caches(); } +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES +void Selection::translate(const Vec3d& displacement, ECoordinatesType type) +#else void Selection::translate(const Vec3d& displacement, bool local) +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES { if (!m_valid) return; @@ -724,8 +728,19 @@ void Selection::translate(const Vec3d& displacement, bool local) for (unsigned int i : m_list) { GLVolume& v = *(*m_volumes)[i]; if (m_mode == Volume || v.is_wipe_tower) { +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES + if (type == ECoordinatesType::Instance) +#else if (local) +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement); +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES + else if (type == ECoordinatesType::Local) { + const VolumeCache& volume_data = m_cache.volumes_data[i]; + const Vec3d local_displacement = (volume_data.get_volume_rotation_matrix() * volume_data.get_volume_scale_matrix() * volume_data.get_volume_mirror_matrix()) * displacement; + v.set_volume_offset(volume_data.get_volume_position() + local_displacement); + } +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES else { #if ENABLE_WORLD_COORDINATE const VolumeCache& volume_data = m_cache.volumes_data[i]; @@ -740,7 +755,11 @@ void Selection::translate(const Vec3d& displacement, bool local) else if (m_mode == Instance) { #if ENABLE_WORLD_COORDINATE if (is_from_fully_selected_instance(i)) { +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES + if (type == ECoordinatesType::Local) { +#else if (local) { +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES const VolumeCache& volume_data = m_cache.volumes_data[i]; const Vec3d world_displacement = (volume_data.get_instance_rotation_matrix() * volume_data.get_instance_mirror_matrix()) * displacement; v.set_instance_offset(volume_data.get_instance_position() + world_displacement); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 827e6812b..b259ba402 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -2,6 +2,9 @@ #define slic3r_GUI_Selection_hpp_ #include "libslic3r/Geometry.hpp" +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES +#include "slic3r/GUI/GUI_Geometry.hpp" +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES #include "GLModel.hpp" #include @@ -23,6 +26,7 @@ using ModelObjectPtrs = std::vector; namespace GUI { +#if !ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES class TransformationType { public: @@ -75,6 +79,7 @@ private: Enum m_value; }; +#endif // !ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES class Selection { @@ -324,7 +329,11 @@ public: bool is_dragging() const { return m_dragging; } #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS +#if ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES + void translate(const Vec3d& displacement, ECoordinatesType type = ECoordinatesType::World); +#else void translate(const Vec3d& displacement, bool local = false); +#endif // ENABLE_INSTANCE_COORDINATES_FOR_VOLUMES void rotate(const Vec3d& rotation, TransformationType transformation_type); void flattening_rotate(const Vec3d& normal); void scale(const Vec3d& scale, TransformationType transformation_type);