mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 05:52:02 +08:00
Fix rotation by gizmo of embossed text on reflected object
+ refactoring code to do same for svg and text
This commit is contained in:
parent
371a3753f2
commit
73060ecee7
@ -424,7 +424,7 @@ bool GLGizmoEmboss::do_mirror(size_t axis)
|
||||
selection.setup_cache();
|
||||
|
||||
auto selection_mirror_fnc = [&selection, &axis]() { selection.mirror((Axis) axis, get_drag_transformation_type(selection)); };
|
||||
selection_transform(selection, selection_mirror_fnc, m_volume);
|
||||
selection_transform(selection, selection_mirror_fnc);
|
||||
|
||||
m_parent.do_mirror(L("Set Mirror"));
|
||||
wxGetApp().obj_manipul()->UpdateAndShow(true);
|
||||
@ -500,34 +500,13 @@ bool GLGizmoEmboss::on_mouse_for_rotation(const wxMouseEvent &mouse_event)
|
||||
if (!m_dragging) return used;
|
||||
|
||||
if (mouse_event.Dragging()) {
|
||||
if (!m_rotate_start_angle.has_value()) {
|
||||
// when m_rotate_start_angle is not set mean it is not Dragging
|
||||
// when angle_opt is not set than angle is Zero
|
||||
const std::optional<float> &angle_opt = m_style_manager.get_style().angle;
|
||||
m_rotate_start_angle = angle_opt.value_or(0.f);
|
||||
}
|
||||
|
||||
double angle = m_rotate_gizmo.get_angle();
|
||||
angle -= PI / 2; // Grabber is upward
|
||||
|
||||
// temporary rotation
|
||||
Selection& selection = m_parent.get_selection();
|
||||
selection.rotate(Vec3d(0., 0., angle), get_drag_transformation_type(selection));
|
||||
|
||||
angle += *m_rotate_start_angle;
|
||||
// move to range <-M_PI, M_PI>
|
||||
Geometry::to_range_pi_pi(angle);
|
||||
|
||||
// set into activ style
|
||||
// check that style is activ
|
||||
assert(m_style_manager.is_active_font());
|
||||
if (m_style_manager.is_active_font()) {
|
||||
std::optional<float> angle_opt;
|
||||
if (!is_approx(angle, 0.))
|
||||
angle_opt = angle;
|
||||
m_style_manager.get_style().angle = angle_opt;
|
||||
}
|
||||
if (!m_style_manager.is_active_font())
|
||||
return used;
|
||||
|
||||
volume_transformation_changing();
|
||||
std::optional<float> &angle_opt = m_style_manager.get_style().angle;
|
||||
dragging_rotate_gizmo(m_rotate_gizmo.get_angle(), angle_opt, m_rotate_start_angle, m_parent.get_selection());
|
||||
}
|
||||
return used;
|
||||
}
|
||||
|
@ -239,39 +239,9 @@ bool GLGizmoSVG::on_mouse_for_rotation(const wxMouseEvent &mouse_event)
|
||||
bool used = use_grabbers(mouse_event);
|
||||
if (!m_dragging) return used;
|
||||
|
||||
if (mouse_event.Dragging()) {
|
||||
if (!m_rotate_start_angle.has_value())
|
||||
m_rotate_start_angle = m_angle.value_or(0.f);
|
||||
double angle = m_rotate_gizmo.get_angle();
|
||||
angle -= PI / 2; // Grabber is upward
|
||||
|
||||
double new_angle = angle + *m_rotate_start_angle;
|
||||
|
||||
bool is_volume_mirrored = has_reflection(m_volume->get_matrix());
|
||||
bool is_instance_mirrored = has_reflection(m_parent.get_selection().get_first_volume()->get_instance_transformation().get_matrix());
|
||||
if (is_volume_mirrored != is_instance_mirrored)
|
||||
new_angle = -angle + *m_rotate_start_angle;
|
||||
|
||||
// move to range <-M_PI, M_PI>
|
||||
Geometry::to_range_pi_pi(new_angle);
|
||||
|
||||
double z_rotation = m_volume->emboss_shape->fix_3mf_tr.has_value()?
|
||||
(new_angle - m_angle.value_or(0.f)) : // relative angle
|
||||
angle; // relativity is keep by selection cache
|
||||
|
||||
Selection &selection = m_parent.get_selection();
|
||||
auto selection_rotate_fnc = [z_rotation, &selection]() {
|
||||
selection.rotate(Vec3d(0., 0., z_rotation), get_drag_transformation_type(selection));
|
||||
};
|
||||
selection_transform(selection, selection_rotate_fnc, m_volume);
|
||||
|
||||
// propagate angle into property
|
||||
m_angle = static_cast<float>(new_angle);
|
||||
|
||||
// do not store zero
|
||||
if (is_approx(*m_angle, 0.f))
|
||||
m_angle.reset();
|
||||
}
|
||||
if (mouse_event.Dragging())
|
||||
dragging_rotate_gizmo(m_rotate_gizmo.get_angle(), m_angle, m_rotate_start_angle, m_parent.get_selection());
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
@ -1790,7 +1760,7 @@ void GLGizmoSVG::draw_size()
|
||||
auto selection_scale_fnc = [&selection, rel_scale = *new_relative_scale]() {
|
||||
selection.scale(rel_scale, get_drag_transformation_type(selection));
|
||||
};
|
||||
selection_transform(selection, selection_scale_fnc, m_volume);
|
||||
selection_transform(selection, selection_scale_fnc);
|
||||
|
||||
m_parent.do_scale(L("Resize"));
|
||||
wxGetApp().obj_manipul()->set_dirty();
|
||||
@ -1952,7 +1922,7 @@ void GLGizmoSVG::draw_mirroring()
|
||||
auto selection_mirror_fnc = [&selection, &axis](){
|
||||
selection.mirror(axis, get_drag_transformation_type(selection));
|
||||
};
|
||||
selection_transform(selection, selection_mirror_fnc, m_volume);
|
||||
selection_transform(selection, selection_mirror_fnc);
|
||||
m_parent.do_mirror(L("Set Mirror"));
|
||||
|
||||
// Mirror is ignoring keep up !!
|
||||
|
@ -61,6 +61,14 @@ Transform3d get_volume_transformation(
|
||||
// distinguish between transformation of volume inside object
|
||||
// and object(single full instance with one volume)
|
||||
bool is_embossed_object(const Selection &selection);
|
||||
|
||||
/// <summary>
|
||||
/// Get fix transformation for selected volume
|
||||
/// Fix after store to 3mf
|
||||
/// </summary>
|
||||
/// <param name="selection">Select only wanted volume</param>
|
||||
/// <returns>Pointer on fix transformation from ModelVolume when exists otherwise nullptr</returns>
|
||||
const Transform3d *get_fix_transformation(const Selection &selection);
|
||||
}
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
@ -278,27 +286,11 @@ Transform3d world_matrix_fixed(const Selection &selection)
|
||||
return world_matrix_fixed(*gl_volume, selection.get_model()->objects);
|
||||
}
|
||||
|
||||
void selection_transform(Selection &selection, const std::function<void()> &selection_transformation_fnc, const ModelVolume *volume)
|
||||
{
|
||||
GLVolume *gl_volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
auto get_fix = [&selection, &volume, &gl_volume]() -> const Transform3d * {
|
||||
if (gl_volume == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (volume == nullptr) {
|
||||
volume = get_model_volume(*gl_volume, selection.get_model()->objects);
|
||||
if (volume == nullptr)
|
||||
return nullptr;
|
||||
}
|
||||
const std::optional<EmbossShape> &es = volume->emboss_shape;
|
||||
if (!volume->emboss_shape.has_value())
|
||||
return nullptr;
|
||||
if (!es->fix_3mf_tr.has_value())
|
||||
return nullptr;
|
||||
return &(*es->fix_3mf_tr);
|
||||
};
|
||||
|
||||
if (const Transform3d *fix = get_fix(); fix != nullptr) {
|
||||
void selection_transform(Selection &selection, const std::function<void()> &selection_transformation_fnc)
|
||||
{
|
||||
if (const Transform3d *fix = get_fix_transformation(selection); fix != nullptr) {
|
||||
// NOTE: need editable gl volume .. can't use selection.get_first_volume()
|
||||
GLVolume *gl_volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
Transform3d volume_tr = gl_volume->get_volume_transformation().get_matrix();
|
||||
gl_volume->set_volume_transformation(volume_tr * fix->inverse());
|
||||
selection.setup_cache();
|
||||
@ -460,6 +452,47 @@ TransformationType get_drag_transformation_type(const Selection &selection)
|
||||
TransformationType::Instance_Relative_Joint :
|
||||
TransformationType::Local_Relative_Joint;
|
||||
}
|
||||
|
||||
void dragging_rotate_gizmo(double gizmo_angle, std::optional<float>& current_angle, std::optional<float> &start_angle, Selection &selection)
|
||||
{
|
||||
if (!start_angle.has_value())
|
||||
// create cache for initial angle
|
||||
start_angle = current_angle.value_or(0.f);
|
||||
|
||||
gizmo_angle -= PI / 2; // Grabber is upward
|
||||
|
||||
double new_angle = gizmo_angle + *start_angle;
|
||||
|
||||
const GLVolume *gl_volume = selection.get_first_volume();
|
||||
assert(gl_volume != nullptr);
|
||||
if (gl_volume == nullptr)
|
||||
return;
|
||||
|
||||
bool is_volume_mirrored = has_reflection(gl_volume->get_volume_transformation().get_matrix());
|
||||
bool is_instance_mirrored = has_reflection(gl_volume->get_instance_transformation().get_matrix());
|
||||
if (is_volume_mirrored != is_instance_mirrored)
|
||||
new_angle = -gizmo_angle + *start_angle;
|
||||
|
||||
// move to range <-M_PI, M_PI>
|
||||
Geometry::to_range_pi_pi(new_angle);
|
||||
|
||||
const Transform3d* fix = get_fix_transformation(selection);
|
||||
double z_rotation = (fix!=nullptr) ? (new_angle - current_angle.value_or(0.f)) : // relative angle
|
||||
gizmo_angle; // relativity is keep by selection cache
|
||||
|
||||
auto selection_rotate_fnc = [z_rotation, &selection]() {
|
||||
selection.rotate(Vec3d(0., 0., z_rotation), get_drag_transformation_type(selection));
|
||||
};
|
||||
selection_transform(selection, selection_rotate_fnc);
|
||||
|
||||
// propagate angle into property
|
||||
current_angle = static_cast<float>(new_angle);
|
||||
|
||||
// do not store zero
|
||||
if (is_approx(*current_angle, 0.f))
|
||||
current_angle.reset();
|
||||
}
|
||||
|
||||
} // namespace Slic3r::GUI
|
||||
|
||||
// private implementation
|
||||
@ -677,4 +710,23 @@ bool is_embossed_object(const Selection &selection)
|
||||
return selection.is_single_full_object() || selection.is_single_full_instance();
|
||||
}
|
||||
|
||||
const Transform3d *get_fix_transformation(const Selection &selection) {
|
||||
const GLVolume *gl_volume = get_selected_gl_volume(selection);
|
||||
assert(gl_volume != nullptr);
|
||||
if (gl_volume == nullptr)
|
||||
return nullptr;
|
||||
|
||||
const ModelVolume *volume = get_model_volume(*gl_volume, selection.get_model()->objects);
|
||||
assert(volume != nullptr);
|
||||
if (volume == nullptr)
|
||||
return nullptr;
|
||||
|
||||
const std::optional<EmbossShape> &es = volume->emboss_shape;
|
||||
if (!volume->emboss_shape.has_value())
|
||||
return nullptr;
|
||||
if (!es->fix_3mf_tr.has_value())
|
||||
return nullptr;
|
||||
return &(*es->fix_3mf_tr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -122,9 +122,7 @@ Transform3d world_matrix_fixed(const Selection &selection);
|
||||
/// </summary>
|
||||
/// <param name="selection">Selected gl volume will be modified</param>
|
||||
/// <param name="selection_transformation_fnc">Function modified Selection transformation</param>
|
||||
/// <param name="volume">Same as selected GLVolume, volume may(or may not) contain fix matrix,
|
||||
/// when nullptr it is gathered from selection</param>
|
||||
void selection_transform(Selection &selection, const std::function<void()>& selection_transformation_fnc, const ModelVolume *volume = nullptr);
|
||||
void selection_transform(Selection &selection, const std::function<void()>& selection_transformation_fnc);
|
||||
|
||||
/// <summary>
|
||||
/// Apply camera direction for emboss direction
|
||||
@ -150,11 +148,22 @@ void do_local_z_rotate(GLCanvas3D &canvas, double relative_angle);
|
||||
void do_local_z_move(GLCanvas3D &canvas, double relative_move);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Distiguish between object and volume
|
||||
/// Differ in possible transformation type
|
||||
/// </summary>
|
||||
/// <param name="selection"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="selection">Contain selected volume/object</param>
|
||||
/// <returns>Transformation to use</returns>
|
||||
TransformationType get_drag_transformation_type(const Selection &selection);
|
||||
|
||||
/// <summary>
|
||||
/// On dragging rotate gizmo func
|
||||
/// Transform GLVolume from selection
|
||||
/// </summary>
|
||||
/// <param name="gizmo_angle">GLGizmoRotate::get_angle()</param>
|
||||
/// <param name="current_angle">In/Out current angle visible in UI</param>
|
||||
/// <param name="start_angle">Cache for start dragging angle</param>
|
||||
/// <param name="selection">Selected only Actual embossed volume</param>
|
||||
void dragging_rotate_gizmo(double gizmo_angle, std::optional<float>& current_angle, std::optional<float> &start_angle, Selection &selection);
|
||||
|
||||
} // namespace Slic3r::GUI
|
||||
#endif // slic3r_SurfaceDrag_hpp_
|
Loading…
x
Reference in New Issue
Block a user