mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 07:11:59 +08:00
Face the camera allowed for instances
Refresh volume data in manipulation panel during drag over surface
This commit is contained in:
parent
bac6bd183c
commit
b570944bfc
@ -377,13 +377,10 @@ bool GLGizmoSVG::on_init()
|
|||||||
std::string GLGizmoSVG::on_get_name() const { return _u8L("SVG"); }
|
std::string GLGizmoSVG::on_get_name() const { return _u8L("SVG"); }
|
||||||
|
|
||||||
void GLGizmoSVG::on_render() {
|
void GLGizmoSVG::on_render() {
|
||||||
// no volume selected
|
if (const Selection &selection = m_parent.get_selection();
|
||||||
const Selection &selection = m_parent.get_selection();
|
selection.volumes_count() != 1 || // only one selected volume
|
||||||
if (m_volume == nullptr ||
|
m_volume == nullptr || // already selected volume in gizmo
|
||||||
get_model_volume(m_volume_id, selection.get_model()->objects) == nullptr)
|
get_model_volume(m_volume_id, selection.get_model()->objects) == nullptr) // still exist model
|
||||||
return;
|
|
||||||
|
|
||||||
if (selection.volumes_count() != 1)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool is_surface_dragging = m_surface_drag.has_value();
|
bool is_surface_dragging = m_surface_drag.has_value();
|
||||||
@ -1380,17 +1377,12 @@ void GLGizmoSVG::draw_window()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoSVG::draw_face_the_camera(){
|
void GLGizmoSVG::draw_face_the_camera(){
|
||||||
// multi instance has to have same rotation only world z rotation is allowed
|
|
||||||
bool disabled = m_parent.get_selection().is_single_full_instance();
|
|
||||||
m_imgui->disabled_begin(disabled);
|
|
||||||
|
|
||||||
if (ImGui::Button(_u8L("Face the camera").c_str())) {
|
if (ImGui::Button(_u8L("Face the camera").c_str())) {
|
||||||
const Camera &cam = wxGetApp().plater()->get_camera();
|
const Camera &cam = wxGetApp().plater()->get_camera();
|
||||||
auto wanted_up_limit = (m_keep_up) ? std::optional<double>(UP_LIMIT) : std::optional<double>{};
|
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 (face_selected_volume_to_camera(cam, m_parent, wanted_up_limit))
|
||||||
volume_transformation_changed();
|
volume_transformation_changed();
|
||||||
}
|
}
|
||||||
m_imgui->disabled_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoSVG::draw_preview(){
|
void GLGizmoSVG::draw_preview(){
|
||||||
|
@ -4,13 +4,18 @@
|
|||||||
///|/
|
///|/
|
||||||
#include "SurfaceDrag.hpp"
|
#include "SurfaceDrag.hpp"
|
||||||
|
|
||||||
#include "libslic3r/Model.hpp" // ModelVolume
|
#include <libslic3r/Model.hpp> // ModelVolume
|
||||||
#include "GLCanvas3D.hpp"
|
#include <libslic3r/Emboss.hpp>
|
||||||
|
|
||||||
#include "slic3r/Utils/RaycastManager.hpp"
|
#include "slic3r/Utils/RaycastManager.hpp"
|
||||||
#include "slic3r/GUI/Camera.hpp"
|
|
||||||
#include "slic3r/GUI/CameraUtils.hpp"
|
#include "GLCanvas3D.hpp"
|
||||||
#include "slic3r/GUI/I18N.hpp"
|
#include "Camera.hpp"
|
||||||
#include "libslic3r/Emboss.hpp"
|
#include "CameraUtils.hpp"
|
||||||
|
#include "I18N.hpp"
|
||||||
|
#include "GUI_App.hpp"
|
||||||
|
#include "GUI_ObjectManipulation.hpp"
|
||||||
|
|
||||||
|
|
||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
using namespace Slic3r::GUI;
|
using namespace Slic3r::GUI;
|
||||||
@ -83,6 +88,7 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event,
|
|||||||
if (surface_drag.has_value() && !mouse_event.Dragging()) {
|
if (surface_drag.has_value() && !mouse_event.Dragging()) {
|
||||||
// write transformation from UI into model
|
// write transformation from UI into model
|
||||||
canvas.do_move(L("Move over surface"));
|
canvas.do_move(L("Move over surface"));
|
||||||
|
wxGetApp().obj_manipul()->set_dirty();
|
||||||
|
|
||||||
// allow moving with object again
|
// allow moving with object again
|
||||||
canvas.enable_moving(true);
|
canvas.enable_moving(true);
|
||||||
@ -275,31 +281,39 @@ Transform3d world_matrix_fixed(const Selection &selection)
|
|||||||
void selection_transform(Selection &selection, const std::function<void()> &selection_transformation_fnc, const ModelVolume *volume)
|
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());
|
GLVolume *gl_volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
if (gl_volume == nullptr)
|
auto get_fix = [&selection, &volume, &gl_volume]() -> const Transform3d * {
|
||||||
return selection_transformation_fnc();
|
if (gl_volume == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
if (volume == nullptr) {
|
if (volume == nullptr) {
|
||||||
volume = get_model_volume(*gl_volume, selection.get_model()->objects);
|
volume = get_model_volume(*gl_volume, selection.get_model()->objects);
|
||||||
if (volume == nullptr)
|
if (volume == nullptr)
|
||||||
return selection_transformation_fnc();
|
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) {
|
||||||
|
Transform3d volume_tr = gl_volume->get_volume_transformation().get_matrix();
|
||||||
|
gl_volume->set_volume_transformation(volume_tr * fix->inverse());
|
||||||
|
selection.setup_cache();
|
||||||
|
|
||||||
|
selection_transformation_fnc();
|
||||||
|
|
||||||
|
volume_tr = gl_volume->get_volume_transformation().get_matrix();
|
||||||
|
gl_volume->set_volume_transformation(volume_tr * (*fix));
|
||||||
|
selection.setup_cache();
|
||||||
|
} else {
|
||||||
|
selection_transformation_fnc();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!volume->emboss_shape.has_value())
|
if (selection.is_single_full_instance())
|
||||||
return selection_transformation_fnc();
|
selection.synchronize_unselected_instances(Selection::SyncRotationType::GENERAL);
|
||||||
|
|
||||||
const std::optional<Transform3d> &fix_tr = volume->emboss_shape->fix_3mf_tr;
|
|
||||||
if (!fix_tr.has_value())
|
|
||||||
return selection_transformation_fnc();
|
|
||||||
|
|
||||||
Transform3d volume_tr = gl_volume->get_volume_transformation().get_matrix();
|
|
||||||
gl_volume->set_volume_transformation(volume_tr * fix_tr->inverse());
|
|
||||||
selection.setup_cache();
|
|
||||||
|
|
||||||
selection_transformation_fnc();
|
|
||||||
|
|
||||||
volume_tr = gl_volume->get_volume_transformation().get_matrix();
|
|
||||||
gl_volume->set_volume_transformation(volume_tr * (*fix_tr));
|
|
||||||
selection.setup_cache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas, const std::optional<double> &wanted_up_limit)
|
bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas, const std::optional<double> &wanted_up_limit)
|
||||||
@ -345,26 +359,37 @@ bool face_selected_volume_to_camera(const Camera &camera, GLCanvas3D &canvas, co
|
|||||||
current_angle = Emboss::calc_up(world_tr, *wanted_up_limit);
|
current_angle = Emboss::calc_up(world_tr, *wanted_up_limit);
|
||||||
|
|
||||||
Vec3d world_position = gl_volume.world_matrix()*Vec3d::Zero();
|
Vec3d world_position = gl_volume.world_matrix()*Vec3d::Zero();
|
||||||
Vec3d wanted_direction = -camera.get_dir_forward();
|
|
||||||
|
assert(camera.get_type() == Camera::EType::Perspective ||
|
||||||
|
camera.get_type() == Camera::EType::Ortho);
|
||||||
|
Vec3d wanted_direction = (camera.get_type() == Camera::EType::Perspective) ?
|
||||||
|
Vec3d(camera.get_position() - world_position) :
|
||||||
|
(-camera.get_dir_forward());
|
||||||
|
|
||||||
Transform3d new_volume_tr = get_volume_transformation(world_tr, wanted_direction, world_position,
|
Transform3d new_volume_tr = get_volume_transformation(world_tr, wanted_direction, world_position,
|
||||||
fix, instance_tr_inv, current_angle, wanted_up_limit);
|
fix, instance_tr_inv, current_angle, wanted_up_limit);
|
||||||
|
|
||||||
if (is_embossed_object(canvas.get_selection())) {
|
Selection &selection = canvas.get_selection();
|
||||||
|
if (is_embossed_object(selection)) {
|
||||||
// transform instance instead of volume
|
// transform instance instead of volume
|
||||||
Transform3d new_instance_tr = instance_tr * new_volume_tr * volume.get_matrix().inverse();
|
Transform3d new_instance_tr = instance_tr * new_volume_tr * volume.get_matrix().inverse();
|
||||||
instance.set_transformation(Geometry::Transformation(new_instance_tr));
|
|
||||||
gl_volume.set_instance_transformation(new_instance_tr);
|
gl_volume.set_instance_transformation(new_instance_tr);
|
||||||
|
|
||||||
|
// set same transformation to other instances when instance is embossed object
|
||||||
|
if (selection.is_single_full_instance())
|
||||||
|
selection.synchronize_unselected_instances(Selection::SyncRotationType::GENERAL);
|
||||||
} else {
|
} else {
|
||||||
// write result transformation
|
// write result transformation
|
||||||
gl_volume.set_volume_transformation(new_volume_tr);
|
gl_volume.set_volume_transformation(new_volume_tr);
|
||||||
volume.set_transformation(new_volume_tr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (volume.type() == ModelVolumeType::MODEL_PART) {
|
if (volume.type() == ModelVolumeType::MODEL_PART) {
|
||||||
object.invalidate_bounding_box();
|
object.invalidate_bounding_box();
|
||||||
object.ensure_on_bed();
|
object.ensure_on_bed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvas.do_rotate(L("Face the camera"));
|
||||||
|
wxGetApp().obj_manipul()->set_dirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,6 +663,8 @@ bool dragging(const Vec2d &mouse_pos,
|
|||||||
}
|
}
|
||||||
|
|
||||||
canvas.set_as_dirty();
|
canvas.set_as_dirty();
|
||||||
|
// Show current position in manipulation panel
|
||||||
|
wxGetApp().obj_manipul()->set_dirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user