mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 18:19:12 +08:00
Core refactor -> preparation to face the came
This commit is contained in:
parent
7324d032a1
commit
00c1c9a4c1
@ -544,12 +544,9 @@ bool GLGizmoEmboss::on_mouse_for_translate(const wxMouseEvent &mouse_event)
|
||||
if (m_volume == nullptr)
|
||||
return false;
|
||||
|
||||
std::optional<double> wanted_up_limit;
|
||||
if (m_keep_up)
|
||||
wanted_up_limit = up_limit;
|
||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||
bool was_dragging = m_surface_drag.has_value();
|
||||
bool res = on_mouse_surface_drag(mouse_event, camera, m_surface_drag, m_parent, m_raycast_manager, up_limit);
|
||||
bool res = on_mouse_surface_drag(mouse_event, camera, m_surface_drag, m_parent, m_raycast_manager, UP_LIMIT);
|
||||
bool is_dragging = m_surface_drag.has_value();
|
||||
|
||||
// End with surface dragging?
|
||||
@ -570,12 +567,13 @@ bool GLGizmoEmboss::on_mouse_for_translate(const wxMouseEvent &mouse_event)
|
||||
|
||||
// Recalculate angle for GUI
|
||||
if (!m_keep_up) {
|
||||
const GLVolume *gl_volume = get_selected_gl_volume(m_parent.get_selection());
|
||||
const Selection &selection = m_parent.get_selection();
|
||||
const GLVolume *gl_volume = get_selected_gl_volume(selection);
|
||||
assert(gl_volume != nullptr);
|
||||
assert(m_style_manager.is_active_font());
|
||||
if (gl_volume == nullptr || !m_style_manager.is_active_font())
|
||||
return res;
|
||||
m_style_manager.get_style().angle = calc_up(gl_volume->world_matrix(), Slic3r::GUI::up_limit);
|
||||
m_style_manager.get_style().angle = calc_angle(selection);
|
||||
}
|
||||
|
||||
volume_transformation_changing();
|
||||
@ -994,11 +992,12 @@ void GLGizmoEmboss::on_stop_dragging()
|
||||
m_parent.do_rotate(L("Text-Rotate"));
|
||||
|
||||
// Re-Calculate current angle of up vector
|
||||
const GLVolume *gl_volume = get_selected_gl_volume(m_parent.get_selection());
|
||||
const Selection &selection = m_parent.get_selection();
|
||||
const GLVolume *gl_volume = get_selected_gl_volume(selection);
|
||||
assert(m_style_manager.is_active_font());
|
||||
assert(gl_volume != nullptr);
|
||||
if (m_style_manager.is_active_font() && gl_volume != nullptr)
|
||||
m_style_manager.get_style().angle = calc_up(gl_volume->world_matrix(), Slic3r::GUI::up_limit);
|
||||
m_style_manager.get_style().angle = calc_angle(selection);
|
||||
|
||||
m_rotate_start_angle.reset();
|
||||
|
||||
@ -1235,7 +1234,7 @@ void GLGizmoEmboss::set_volume_by_selection()
|
||||
|
||||
StyleManager::Style style_{style}; // copy
|
||||
style_.projection = volume->emboss_shape->projection;
|
||||
style_.angle = calc_up(gl_volume->world_matrix(), Slic3r::GUI::up_limit);
|
||||
style_.angle = calc_angle(selection);
|
||||
style_.distance = calc_distance(*gl_volume, m_raycast_manager, m_parent);
|
||||
|
||||
if (auto it = std::find_if(styles.begin(), styles.end(), has_same_name);
|
||||
@ -1283,7 +1282,7 @@ void GLGizmoEmboss::set_volume_by_selection()
|
||||
// Calculate current angle of up vector
|
||||
assert(m_style_manager.is_active_font());
|
||||
if (m_style_manager.is_active_font())
|
||||
m_style_manager.get_style().angle = calc_up(gl_volume->world_matrix(), up_limit);
|
||||
m_style_manager.get_style().angle = calc_angle(selection);
|
||||
|
||||
// calculate scale for height and depth inside of scaled object instance
|
||||
calculate_scale();
|
||||
@ -2890,11 +2889,12 @@ void GLGizmoEmboss::draw_advanced()
|
||||
do_local_z_rotate(m_parent, diff_angle);
|
||||
|
||||
// calc angle after rotation
|
||||
const GLVolume *gl_volume = get_selected_gl_volume(m_parent.get_selection());
|
||||
const Selection &selection = m_parent.get_selection();
|
||||
const GLVolume *gl_volume = get_selected_gl_volume(selection);
|
||||
assert(gl_volume != nullptr);
|
||||
assert(m_style_manager.is_active_font());
|
||||
if (m_style_manager.is_active_font() && gl_volume != nullptr)
|
||||
m_style_manager.get_style().angle = calc_up(gl_volume->world_matrix(), Slic3r::GUI::up_limit);
|
||||
m_style_manager.get_style().angle = calc_angle(selection);
|
||||
|
||||
if (font_prop.per_glyph)
|
||||
reinit_text_lines(m_text_lines.get_lines().size());
|
||||
@ -2955,12 +2955,26 @@ void GLGizmoEmboss::draw_advanced()
|
||||
if (ImGui::Button(_u8L("Set text to face camera").c_str())) {
|
||||
assert(get_selected_volume(m_parent.get_selection()) == m_volume);
|
||||
const Camera &cam = wxGetApp().plater()->get_camera();
|
||||
|
||||
auto wanted_up_limit = (m_keep_up) ? std::optional<double>(UP_LIMIT) : std::optional<double>{};
|
||||
if (face_selected_volume_to_camera(cam, m_parent, wanted_up_limit)) {
|
||||
if (!m_keep_up) {
|
||||
// update current style
|
||||
m_style_manager.get_style().angle = calc_angle(m_parent.get_selection());
|
||||
} else {
|
||||
// after set face to camera, angle should be the same
|
||||
assert(is_approx(m_style_manager.get_style().angle, calc_angle(m_parent.get_selection())));
|
||||
}
|
||||
|
||||
FontProp &fp = m_style_manager.get_font_prop();
|
||||
if (face_selected_volume_to_camera(cam, m_parent) &&
|
||||
(use_surface || fp.per_glyph)) {
|
||||
if (use_surface || fp.per_glyph) {
|
||||
if (fp.per_glyph)
|
||||
reinit_text_lines();
|
||||
process();
|
||||
} else {
|
||||
// Check outside bed
|
||||
m_parent.requires_check_outside_state();
|
||||
}
|
||||
}
|
||||
} else if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s", _u8L("Orient the text towards the camera.").c_str());
|
||||
|
@ -279,38 +279,13 @@ bool GLGizmoSVG::on_mouse_for_rotation(const wxMouseEvent &mouse_event)
|
||||
return used;
|
||||
}
|
||||
|
||||
namespace{
|
||||
std::optional<float> calculate_angle(const Selection& selection)
|
||||
{
|
||||
const GLVolume *gl_volume = selection.get_first_volume();
|
||||
assert(gl_volume != nullptr);
|
||||
if (gl_volume == nullptr)
|
||||
return {};
|
||||
|
||||
Transform3d to_world = gl_volume->world_matrix();
|
||||
const ModelVolume* volume = get_model_volume(*gl_volume, selection.get_model()->objects);
|
||||
assert(volume != nullptr);
|
||||
assert(volume->emboss_shape.has_value());
|
||||
if (volume == nullptr ||
|
||||
!volume->emboss_shape.has_value() ||
|
||||
!volume->emboss_shape->fix_3mf_tr)
|
||||
return calc_up(to_world, Slic3r::GUI::up_limit);
|
||||
|
||||
// exist fix matrix and must be applied before calculation
|
||||
to_world = to_world * volume->emboss_shape->fix_3mf_tr->inverse();
|
||||
return calc_up(to_world, Slic3r::GUI::up_limit);
|
||||
}
|
||||
}
|
||||
|
||||
bool GLGizmoSVG::on_mouse_for_translate(const wxMouseEvent &mouse_event)
|
||||
{
|
||||
// exist selected volume?
|
||||
if (m_volume == nullptr)
|
||||
return false;
|
||||
|
||||
std::optional<double> up_limit;
|
||||
if (m_keep_up)
|
||||
up_limit = Slic3r::GUI::up_limit;
|
||||
auto up_limit = m_keep_up ? std::optional<double>(UP_LIMIT) : std::optional<double>{};
|
||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||
|
||||
bool was_dragging = m_surface_drag.has_value();
|
||||
@ -346,7 +321,7 @@ bool GLGizmoSVG::on_mouse_for_translate(const wxMouseEvent &mouse_event)
|
||||
|
||||
// Recalculate angle for GUI
|
||||
if (!m_keep_up)
|
||||
m_angle = calculate_angle(m_parent.get_selection());
|
||||
m_angle = calc_angle(m_parent.get_selection());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -1213,7 +1188,7 @@ void GLGizmoSVG::set_volume_by_selection()
|
||||
m_shape_warnings = create_shape_warnings(es, get_scale_for_tolerance());
|
||||
|
||||
// Calculate current angle of up vector
|
||||
m_angle = calculate_angle(selection);
|
||||
m_angle = calc_angle(selection);
|
||||
m_distance = calc_distance(*gl_volume, m_raycast_manager, m_parent);
|
||||
|
||||
m_shape_bb = get_extents(m_volume_shape.shapes_with_ids);
|
||||
@ -1351,9 +1326,22 @@ void GLGizmoSVG::draw_window()
|
||||
|
||||
if (ImGui::Button(_u8L("Face the camera").c_str())) {
|
||||
const Camera &cam = wxGetApp().plater()->get_camera();
|
||||
if (face_selected_volume_to_camera(cam, m_parent) &&
|
||||
m_volume->emboss_shape->projection.use_surface)
|
||||
auto wanted_up_limit = (m_keep_up) ? std::optional<double>(UP_LIMIT) : std::optional<double>{};
|
||||
if (face_selected_volume_to_camera(cam, m_parent, wanted_up_limit)) {
|
||||
if (!m_keep_up) {
|
||||
m_angle = calc_angle(m_parent.get_selection());
|
||||
} else {
|
||||
// after set face to camera, angle should be the same
|
||||
assert(is_approx(m_angle, calc_angle(m_parent.get_selection())));
|
||||
}
|
||||
|
||||
if (m_volume->emboss_shape->projection.use_surface) {
|
||||
process();
|
||||
} else {
|
||||
// Check outside bed
|
||||
m_parent.requires_check_outside_state();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Unindent(m_gui_cfg->icon_width);
|
||||
@ -1895,7 +1883,7 @@ void GLGizmoSVG::draw_rotation()
|
||||
do_local_z_rotate(m_parent, diff_angle);
|
||||
|
||||
// calc angle after rotation
|
||||
m_angle = calculate_angle(m_parent.get_selection());
|
||||
m_angle = calc_angle(m_parent.get_selection());
|
||||
|
||||
// recalculate for surface cut
|
||||
if (m_volume->emboss_shape->projection.use_surface)
|
||||
|
@ -1561,7 +1561,7 @@ bool start_create_volume_on_surface_job(CreateVolumeParams &input, DataBasePtr d
|
||||
return on_bad_state(std::move(data), object);
|
||||
|
||||
// Create result volume transformation
|
||||
Transform3d surface_trmat = create_transformation_onto_surface(hit->position, hit->normal, Slic3r::GUI::up_limit);
|
||||
Transform3d surface_trmat = create_transformation_onto_surface(hit->position, hit->normal, UP_LIMIT);
|
||||
apply_transformation(input.angle, input.distance, surface_trmat);
|
||||
Transform3d transform = instance->get_matrix().inverse() * surface_trmat;
|
||||
auto gizmo_type = static_cast<GLGizmosManager::EType>(input.gizmo);
|
||||
|
@ -56,7 +56,7 @@ bool start_dragging(const Vec2d &mouse_pos,
|
||||
/// <returns></returns>
|
||||
bool dragging(const Vec2d &mouse_pos,
|
||||
const Camera &camera,
|
||||
std::optional<SurfaceDrag> &surface_drag,
|
||||
SurfaceDrag &surface_drag, // need to write whether exist hit
|
||||
GLCanvas3D &canvas,
|
||||
const RaycastManager &raycast_manager,
|
||||
const std::optional<double> &up_limit);
|
||||
@ -80,7 +80,7 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event,
|
||||
std::optional<SurfaceDrag> &surface_drag,
|
||||
GLCanvas3D &canvas,
|
||||
RaycastManager &raycast_manager,
|
||||
std::optional<double> up_limit)
|
||||
const std::optional<double>&up_limit)
|
||||
{
|
||||
// Fix when leave window during dragging
|
||||
// Fix when click right button
|
||||
@ -109,7 +109,7 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event,
|
||||
return false;
|
||||
|
||||
if (mouse_event.Dragging())
|
||||
return dragging(mouse_position(mouse_event), camera, surface_drag, canvas, raycast_manager, up_limit);
|
||||
return dragging(mouse_position(mouse_event), camera, *surface_drag, canvas, raycast_manager, up_limit);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -228,6 +228,25 @@ std::optional<float> calc_distance(const GLVolume &gl_volume, const RaycastManag
|
||||
return sign * static_cast<float>(sqrt(distance_sq));
|
||||
}
|
||||
|
||||
std::optional<float> calc_angle(const Selection &selection)
|
||||
{
|
||||
const GLVolume *gl_volume = selection.get_first_volume();
|
||||
assert(gl_volume != nullptr);
|
||||
if (gl_volume == nullptr)
|
||||
return {};
|
||||
|
||||
Transform3d to_world = gl_volume->world_matrix();
|
||||
const ModelVolume *volume = get_model_volume(*gl_volume, selection.get_model()->objects);
|
||||
assert(volume != nullptr);
|
||||
assert(volume->emboss_shape.has_value());
|
||||
if (volume == nullptr || !volume->emboss_shape.has_value() || !volume->emboss_shape->fix_3mf_tr)
|
||||
return Emboss::calc_up(to_world, UP_LIMIT);
|
||||
|
||||
// exist fix matrix and must be applied before calculation
|
||||
to_world = to_world * volume->emboss_shape->fix_3mf_tr->inverse();
|
||||
return Emboss::calc_up(to_world, UP_LIMIT);
|
||||
}
|
||||
|
||||
Transform3d world_matrix_fixed(const GLVolume &gl_volume, const ModelObjectPtrs &objects)
|
||||
{
|
||||
Transform3d res = gl_volume.world_matrix();
|
||||
@ -287,15 +306,40 @@ void selection_transform(Selection &selection, const std::function<void()> &sele
|
||||
selection.setup_cache();
|
||||
}
|
||||
|
||||
bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas)
|
||||
bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas, const std::optional<double>& wanted_up_limit)
|
||||
{
|
||||
const Vec3d &cam_dir = camera.get_dir_forward();
|
||||
Selection &sel = canvas.get_selection();
|
||||
if (sel.is_empty())
|
||||
const Selection &selection = canvas.get_selection();
|
||||
if (selection.is_empty())
|
||||
return false;
|
||||
|
||||
GLVolume *gl_volume_ptr = get_selected_gl_volume(canvas);
|
||||
if (gl_volume_ptr == nullptr)
|
||||
return false;
|
||||
const GLVolume &gl_volume = *gl_volume_ptr;
|
||||
|
||||
const ModelObjectPtrs &objects = canvas.get_model()->objects;
|
||||
const ModelObject *object_ptr = get_model_object(gl_volume, objects);
|
||||
assert(object_ptr != nullptr);
|
||||
if (object_ptr == nullptr)
|
||||
return false;
|
||||
const ModelObject &object = *object_ptr;
|
||||
|
||||
const ModelInstance *instance_ptr = get_model_instance(gl_volume, object);
|
||||
assert(instance_ptr != nullptr);
|
||||
if (instance_ptr == nullptr)
|
||||
return false;
|
||||
const ModelInstance &instance = *instance_ptr;
|
||||
|
||||
const ModelVolume *volume_ptr = get_model_volume(gl_volume, object);
|
||||
assert(volume_ptr != nullptr);
|
||||
if (volume_ptr == nullptr)
|
||||
return false;
|
||||
const ModelVolume &volume = *volume_ptr;
|
||||
|
||||
const Vec3d &cam_dir = camera.get_dir_forward();
|
||||
|
||||
// camera direction transformed into volume coordinate system
|
||||
Transform3d to_world = world_matrix_fixed(sel);
|
||||
Transform3d to_world = world_matrix_fixed(gl_volume, objects);
|
||||
Vec3d cam_dir_tr = to_world.inverse().linear() * cam_dir;
|
||||
cam_dir_tr.normalize();
|
||||
|
||||
@ -305,11 +349,12 @@ bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas)
|
||||
if (is_approx(cam_dir_tr, emboss_dir))
|
||||
return false;
|
||||
|
||||
assert(sel.get_volume_idxs().size() == 1);
|
||||
GLVolume *gl_volume = sel.get_volume(*sel.get_volume_idxs().begin());
|
||||
assert(selection.get_volume_idxs().size() == 1);
|
||||
if (selection.get_volume_idxs().size() != 1)
|
||||
return false;
|
||||
|
||||
Transform3d vol_rot;
|
||||
Transform3d vol_tr = gl_volume->get_volume_transformation().get_matrix();
|
||||
Transform3d vol_tr = gl_volume.get_volume_transformation().get_matrix();
|
||||
// check whether cam_dir is opposit to emboss dir
|
||||
if (is_approx(cam_dir_tr, -emboss_dir)) {
|
||||
// rotate 180 DEG by y
|
||||
@ -325,9 +370,24 @@ bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas)
|
||||
Vec3d offset = vol_tr * Vec3d::Zero();
|
||||
Vec3d offset_inv = vol_rot.inverse() * offset;
|
||||
Transform3d res = vol_tr * Eigen::Translation<double, 3>(-offset) * vol_rot * Eigen::Translation<double, 3>(offset_inv);
|
||||
|
||||
// Transform3d res = vol_tr * vol_rot;
|
||||
gl_volume->set_volume_transformation(Geometry::Transformation(res));
|
||||
get_model_volume(*gl_volume, sel.get_model()->objects)->set_transformation(res);
|
||||
|
||||
// Need modifiable gl volume
|
||||
GLVolume *gl_volume_ptr_ = canvas.get_selection().get_volume(*selection.get_volume_idxs().begin());
|
||||
assert(gl_volume_ptr_ != nullptr);
|
||||
if (gl_volume_ptr_ == nullptr)
|
||||
return false;
|
||||
|
||||
// Need modifiable model volume
|
||||
ModelVolume *model_volume_ptr_ = get_model_volume(gl_volume, objects);
|
||||
assert(model_volume_ptr_ != nullptr);
|
||||
if (model_volume_ptr_ == nullptr)
|
||||
return false;
|
||||
|
||||
// write result transformation
|
||||
gl_volume_ptr_->set_volume_transformation(Geometry::Transformation(res));
|
||||
model_volume_ptr_->set_transformation(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -501,25 +561,19 @@ bool start_dragging(const Vec2d &mouse_pos,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dragging(const Vec2d &mouse_pos,
|
||||
const Camera &camera,
|
||||
std::optional<SurfaceDrag> &surface_drag,
|
||||
GLCanvas3D &canvas,
|
||||
const RaycastManager &raycast_manager,
|
||||
const std::optional<double> &up_limit)
|
||||
Transform3d get_volume_transformation(
|
||||
Transform3d world, // from volume
|
||||
const Vec3d& world_dir, // wanted new direction
|
||||
const Vec3d& world_position, // wanted new position
|
||||
const std::optional<Transform3d>& fix, // [optional] fix matrix
|
||||
// Invers transformation of text volume instance
|
||||
// Help convert world transformation to instance space
|
||||
const Transform3d& instance_inv,
|
||||
// initial rotation in Z axis
|
||||
std::optional<float> current_angle = {},
|
||||
const std::optional<double> &up_limit = {})
|
||||
{
|
||||
Vec2d offseted_mouse = mouse_pos + surface_drag->mouse_offset_without_sla_shift;
|
||||
std::optional<RaycastManager::Hit> hit = ray_from_camera(
|
||||
raycast_manager, offseted_mouse, camera, &surface_drag->condition);
|
||||
|
||||
surface_drag->exist_hit = hit.has_value();
|
||||
if (!hit.has_value()) {
|
||||
// cross hair need redraw
|
||||
canvas.set_as_dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto world_linear = surface_drag->world.linear();
|
||||
auto world_linear = world.linear();
|
||||
// Calculate offset: transformation to wanted position
|
||||
{
|
||||
// Reset skew of the text Z axis:
|
||||
@ -530,8 +584,8 @@ bool dragging(const Vec2d &mouse_pos,
|
||||
}
|
||||
|
||||
Vec3d text_z_world = world_linear.col(2); // world_linear * Vec3d::UnitZ()
|
||||
auto z_rotation = Eigen::Quaternion<double, Eigen::DontAlign>::FromTwoVectors(text_z_world, hit->normal);
|
||||
Transform3d world_new = z_rotation * surface_drag->world;
|
||||
auto z_rotation = Eigen::Quaternion<double, Eigen::DontAlign>::FromTwoVectors(text_z_world, world_dir);
|
||||
Transform3d world_new = z_rotation * world;
|
||||
auto world_new_linear = world_new.linear();
|
||||
|
||||
// Fix direction of up vector to zero initial rotation
|
||||
@ -548,32 +602,59 @@ bool dragging(const Vec2d &mouse_pos,
|
||||
}
|
||||
|
||||
// Edit position from right
|
||||
Transform3d volume_new{Eigen::Translation<double, 3>(surface_drag->instance_inv * hit->position)};
|
||||
volume_new.linear() = surface_drag->instance_inv.linear() * world_new_linear;
|
||||
Transform3d volume_new{Eigen::Translation<double, 3>(instance_inv * world_position)};
|
||||
volume_new.linear() = instance_inv.linear() * world_new_linear;
|
||||
|
||||
// Check that transformation matrix is valid transformation
|
||||
assert(volume_new.matrix()(0, 0) == volume_new.matrix()(0, 0)); // Check valid transformation not a NAN
|
||||
if (volume_new.matrix()(0, 0) != volume_new.matrix()(0, 0))
|
||||
return true;
|
||||
return Transform3d::Identity();
|
||||
|
||||
// Check that scale in world did not changed
|
||||
assert(!calc_scale(world_linear, world_new_linear, Vec3d::UnitY()).has_value());
|
||||
assert(!calc_scale(world_linear, world_new_linear, Vec3d::UnitZ()).has_value());
|
||||
|
||||
const ModelVolume *volume = get_model_volume(*surface_drag->gl_volume, canvas.get_model()->objects);
|
||||
// fix baked transformation from .3mf store process
|
||||
if (volume != nullptr && volume->emboss_shape.has_value()) {
|
||||
const std::optional<Slic3r::Transform3d> &fix = volume->emboss_shape->fix_3mf_tr;
|
||||
if (fix.has_value())
|
||||
volume_new = volume_new * (*fix);
|
||||
|
||||
// apply move in Z direction and rotation by up vector
|
||||
Emboss::apply_transformation(surface_drag->start_angle, surface_drag->start_distance, volume_new);
|
||||
Emboss::apply_transformation(current_angle, {}, volume_new);
|
||||
|
||||
return volume_new;
|
||||
}
|
||||
|
||||
bool dragging(const Vec2d &mouse_pos,
|
||||
const Camera &camera,
|
||||
SurfaceDrag &surface_drag,
|
||||
GLCanvas3D &canvas,
|
||||
const RaycastManager &raycast_manager,
|
||||
const std::optional<double> &up_limit)
|
||||
{
|
||||
Vec2d offseted_mouse = mouse_pos + surface_drag.mouse_offset_without_sla_shift;
|
||||
std::optional<RaycastManager::Hit> hit = ray_from_camera(
|
||||
raycast_manager, offseted_mouse, camera, &surface_drag.condition);
|
||||
|
||||
surface_drag.exist_hit = hit.has_value();
|
||||
if (!hit.has_value()) {
|
||||
// cross hair need redraw
|
||||
canvas.set_as_dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
const ModelVolume *volume = get_model_volume(*surface_drag.gl_volume, canvas.get_model()->objects);
|
||||
std::optional<Transform3d> fix;
|
||||
if (volume !=nullptr &&
|
||||
volume->emboss_shape.has_value() &&
|
||||
volume->emboss_shape->fix_3mf_tr.has_value())
|
||||
fix = volume->emboss_shape->fix_3mf_tr;
|
||||
Transform3d volume_new = get_volume_transformation(surface_drag.world, hit->normal, hit->position,
|
||||
fix, surface_drag.instance_inv, surface_drag.start_angle, up_limit);
|
||||
|
||||
// Update transformation for all instances
|
||||
for (GLVolume *vol : canvas.get_volumes().volumes) {
|
||||
if (vol->object_idx() != surface_drag->gl_volume->object_idx() || vol->volume_idx() != surface_drag->gl_volume->volume_idx())
|
||||
if (vol->object_idx() != surface_drag.gl_volume->object_idx() ||
|
||||
vol->volume_idx() != surface_drag.gl_volume->volume_idx())
|
||||
continue;
|
||||
vol->set_volume_transformation(volume_new);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ struct SurfaceDrag
|
||||
|
||||
// Limit direction of up vector on model
|
||||
// Between side and top surface
|
||||
constexpr double up_limit = 0.9;
|
||||
constexpr double UP_LIMIT = 0.9;
|
||||
|
||||
/// <summary>
|
||||
/// Mouse event handler, when move(drag&drop) volume over model surface
|
||||
@ -70,7 +70,7 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event,
|
||||
std::optional<SurfaceDrag> &surface_drag,
|
||||
GLCanvas3D &canvas,
|
||||
RaycastManager &raycast_manager,
|
||||
std::optional<double> up_limit = {});
|
||||
const std::optional<double>&up_limit = {});
|
||||
|
||||
/// <summary>
|
||||
/// Calculate translation of volume onto surface of model
|
||||
@ -90,6 +90,13 @@ std::optional<Vec3d> calc_surface_offset(const Selection &selection, RaycastMana
|
||||
std::optional<float> calc_distance(const GLVolume &gl_volume, RaycastManager &raycaster, GLCanvas3D &canvas);
|
||||
std::optional<float> calc_distance(const GLVolume &gl_volume, const RaycastManager &raycaster, const RaycastManager::ISkip *condition);
|
||||
|
||||
/// <summary>
|
||||
/// Calculate up vector angle
|
||||
/// </summary>
|
||||
/// <param name="selection">Calculation of angle is for selected one volume</param>
|
||||
/// <returns></returns>
|
||||
std::optional<float> calc_angle(const Selection &selection);
|
||||
|
||||
/// <summary>
|
||||
/// Get transformation to world
|
||||
/// - use fix after store to 3mf when exists
|
||||
@ -123,8 +130,9 @@ void selection_transform(Selection &selection, const std::function<void()>& sele
|
||||
/// </summary>
|
||||
/// <param name="camera">Define view vector</param>
|
||||
/// <param name="canvas">Containe Selected ModelVolume to modify orientation</param>
|
||||
/// <param name="wanted_up_limit">[Optional]Limit for direction of up vector</param>
|
||||
/// <returns>True when apply change otherwise false</returns>
|
||||
bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas);
|
||||
bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas, const std::optional<double> &wanted_up_limit = {});
|
||||
|
||||
/// <summary>
|
||||
/// Rotation around z Axis(emboss direction)
|
||||
|
Loading…
x
Reference in New Issue
Block a user