From 392dbba96f13026041e97f6d0e8042d05e326423 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Tue, 28 Mar 2023 17:10:56 +0200 Subject: [PATCH] Fix offsets for SLA Text dragging with visible supports. --- src/slic3r/GUI/SurfaceDrag.cpp | 72 ++++++++++++---------------------- src/slic3r/GUI/SurfaceDrag.hpp | 3 ++ 2 files changed, 27 insertions(+), 48 deletions(-) diff --git a/src/slic3r/GUI/SurfaceDrag.cpp b/src/slic3r/GUI/SurfaceDrag.cpp index a202ae5de4..40b01a2af8 100644 --- a/src/slic3r/GUI/SurfaceDrag.cpp +++ b/src/slic3r/GUI/SurfaceDrag.cpp @@ -9,50 +9,6 @@ #include "libslic3r/Emboss.hpp" namespace Slic3r::GUI { - -/// -/// Calculate offset from mouse position to center of text -/// -/// Position on screen[in Px] e.g. mouse position -/// Selected volume(text) -/// Actual position and view direction of camera -/// Offset in screen coordinate -static Vec2d calc_screen_offset_to_volume_center(const Vec2d &screen_coor, const ModelVolume &volume, const Camera &camera) -{ - const Transform3d &volume_tr = volume.get_matrix(); - assert(volume.text_configuration.has_value()); - - auto calc_offset = [&screen_coor, &volume_tr, &camera, &volume](const Transform3d &instrance_tr) -> Vec2d { - Transform3d to_world = instrance_tr * volume_tr; - - // Use fix of .3mf loaded tranformation when exist - if (volume.text_configuration->fix_3mf_tr.has_value()) - to_world = to_world * (*volume.text_configuration->fix_3mf_tr); - // zero point of volume in world coordinate system - Vec3d volume_center = to_world.translation(); - // screen coordinate of volume center - Vec2i coor = CameraUtils::project(camera, volume_center); - return coor.cast() - screen_coor; - }; - - auto object = volume.get_object(); - assert(!object->instances.empty()); - // Speed up for one instance - if (object->instances.size() == 1) - return calc_offset(object->instances.front()->get_matrix()); - - Vec2d nearest_offset; - double nearest_offset_size = std::numeric_limits::max(); - for (const ModelInstance *instance : object->instances) { - Vec2d offset = calc_offset(instance->get_matrix()); - double offset_size = offset.norm(); - if (nearest_offset_size < offset_size) - continue; - nearest_offset_size = offset_size; - nearest_offset = offset; - } - return nearest_offset; -} // Calculate scale in world for check in debug [[maybe_unused]] static std::optional calc_scale(const Matrix3d &from, const Matrix3d &to, const Vec3d &dir) @@ -109,7 +65,8 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event, gl_volumes[hovered_idx_] != gl_volume) return false; - const ModelObject *object = get_model_object(*gl_volume, canvas.get_model()->objects); + const ModelObjectPtrs &objects = canvas.get_model()->objects; + const ModelObject *object = get_model_object(*gl_volume, objects); assert(object != nullptr); if (object == nullptr) return false; @@ -148,7 +105,26 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event, // wxCoord == int --> wx/types.h Vec2i mouse_coord(mouse_event.GetX(), mouse_event.GetY()); Vec2d mouse_pos = mouse_coord.cast(); - Vec2d mouse_offset = calc_screen_offset_to_volume_center(mouse_pos, *volume, camera); + + // world_matrix_fixed() without sla shift + Transform3d to_world = world_matrix_fixed(*gl_volume, objects); + + // zero point of volume in world coordinate system + Vec3d volume_center = to_world.translation(); + // screen coordinate of volume center + Vec2i coor = CameraUtils::project(camera, volume_center); + Vec2d mouse_offset = coor.cast() - mouse_pos; + Vec2d mouse_offset_without_sla_shift = mouse_offset; + if (double sla_shift = gl_volume->get_sla_shift_z(); !is_approx(sla_shift, 0.)) { + Transform3d to_world_without_sla_move = instance->get_matrix() * volume->get_matrix(); + if (volume->text_configuration.has_value() && volume->text_configuration->fix_3mf_tr.has_value()) + to_world_without_sla_move = to_world_without_sla_move * (*volume->text_configuration->fix_3mf_tr); + // zero point of volume in world coordinate system + volume_center = to_world_without_sla_move.translation(); + // screen coordinate of volume center + coor = CameraUtils::project(camera, volume_center); + mouse_offset_without_sla_shift = coor.cast() - mouse_pos; + } Transform3d volume_tr = gl_volume->get_volume_transformation().get_matrix(); @@ -165,7 +141,7 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event, std::optional start_angle; if (up_limit.has_value()) start_angle = Emboss::calc_up(world_tr, *up_limit); - surface_drag = SurfaceDrag{mouse_offset, world_tr, instance_tr_inv, gl_volume, condition, start_angle}; + surface_drag = SurfaceDrag{mouse_offset, world_tr, instance_tr_inv, gl_volume, condition, start_angle, true, mouse_offset_without_sla_shift}; // disable moving with object by mouse canvas.enable_moving(false); @@ -181,7 +157,7 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event, // wxCoord == int --> wx/types.h Vec2i mouse_coord(mouse_event.GetX(), mouse_event.GetY()); Vec2d mouse_pos = mouse_coord.cast(); - Vec2d offseted_mouse = mouse_pos + surface_drag->mouse_offset; + Vec2d offseted_mouse = mouse_pos + surface_drag->mouse_offset_without_sla_shift; std::optional hit = ray_from_camera( raycast_manager, offseted_mouse, camera, &surface_drag->condition); diff --git a/src/slic3r/GUI/SurfaceDrag.hpp b/src/slic3r/GUI/SurfaceDrag.hpp index bb2600c28f..48d6a33fe2 100644 --- a/src/slic3r/GUI/SurfaceDrag.hpp +++ b/src/slic3r/GUI/SurfaceDrag.hpp @@ -39,6 +39,9 @@ struct SurfaceDrag // Flag whether coordinate hit some volume bool exist_hit = true; + + // hold screen coor offset of cursor from object center without SLA shift + Vec2d mouse_offset_without_sla_shift; }; ///