FIX:world cs is displayed incorrectly
The value of world coordinate system for model_volume is displayed incorrectly Jira: STUDIO-6399 code is from PrusaSlicer thanks for PrusaSlicer and enricoturri1966 commit 325709c5ae9b937867b36103a41d12a102c99292 Author: enricoturri1966 <enricoturri@seznam.cz> Date: Thu Jan 26 15:49:00 2023 +0100 SPE-1419 - Fixed reset skew resetting mirror, reset scale resetting mirror, changed labels in Object Manipulator panel, scale of instances using the Object Manipulator panel always made as absolute Change-Id: I30fdd39effd73b8dc027e4263fa7e64937b84326
This commit is contained in:
parent
b52817301c
commit
0b46b9848b
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/Geometry.hpp"
|
||||
#include "slic3r/GUI/Selection.hpp"
|
||||
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
|
||||
|
@ -117,14 +117,34 @@ void GizmoObjectManipulation::update_settings_value(const Selection& selection)
|
|||
m_new_title_string = L("Object Operations");
|
||||
}
|
||||
else if (selection.is_single_modifier() || selection.is_single_volume()) {
|
||||
// the selection contains a single volume
|
||||
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
m_new_position = volume->get_volume_offset();
|
||||
m_new_rotation = volume->get_volume_rotation() * (180. / M_PI);
|
||||
m_new_scale = volume->get_volume_scaling_factor() * 100.;
|
||||
m_new_size = volume->get_instance_transformation().get_scaling_factor().cwiseProduct(volume->get_volume_transformation().get_scaling_factor().cwiseProduct(volume->bounding_box().size()));
|
||||
const GLVolume *volume = selection.get_first_volume();
|
||||
if (is_world_coordinates()) {
|
||||
const Geometry::Transformation trafo(volume->world_matrix());
|
||||
|
||||
const Vec3d &offset = trafo.get_offset();
|
||||
|
||||
m_new_position = offset;
|
||||
m_new_rotate_label_string = L("Rotate (relative)");
|
||||
m_new_scale_label_string = L("Scale");
|
||||
m_new_scale = Vec3d(100.0, 100.0, 100.0);
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
|
||||
} else if (is_local_coordinates()) {
|
||||
m_new_move_label_string = L("Translate (relative) [World]");
|
||||
m_new_rotate_label_string = L("Rotate (relative)");
|
||||
m_new_position = Vec3d::Zero();
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
m_new_scale = volume->get_volume_scaling_factor() * 100.0;
|
||||
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
|
||||
} else {
|
||||
m_new_position = volume->get_volume_offset();
|
||||
m_new_rotate_label_string = L("Rotate (relative)");
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
m_new_scale_label_string = L("Scale");
|
||||
m_new_scale = Vec3d(100.0, 100.0, 100.0);
|
||||
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
|
||||
}
|
||||
m_new_enabled = true;
|
||||
m_new_title_string = L("Volume Operations");
|
||||
}
|
||||
else if (obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) {
|
||||
reset_settings_value();
|
||||
|
@ -445,7 +465,7 @@ void GizmoObjectManipulation::reset_scale_value()
|
|||
}
|
||||
|
||||
void GizmoObjectManipulation::set_uniform_scaling(const bool use_uniform_scale)
|
||||
{
|
||||
{
|
||||
if (!use_uniform_scale)
|
||||
// Recalculate cached values at this panel, refresh the screen.
|
||||
this->UpdateAndShow(true);
|
||||
|
@ -454,6 +474,24 @@ void GizmoObjectManipulation::set_uniform_scaling(const bool use_uniform_scale)
|
|||
set_dirty();
|
||||
}
|
||||
|
||||
void GizmoObjectManipulation::set_coordinates_type(ECoordinatesType type)
|
||||
{
|
||||
if (wxGetApp().get_mode() == comSimple)
|
||||
type = ECoordinatesType::World;
|
||||
|
||||
if (m_coordinates_type == type) return;
|
||||
|
||||
m_coordinates_type = type;
|
||||
m_world_coordinates = type == ECoordinatesType::World ? true : false;
|
||||
//m_word_local_combo->SetSelection((int) m_coordinates_type);
|
||||
this->UpdateAndShow(true);
|
||||
GLCanvas3D *canvas = wxGetApp().plater()->canvas3D();
|
||||
canvas->get_gizmos_manager().update_data();
|
||||
canvas->set_as_dirty();
|
||||
canvas->request_extra_frame();
|
||||
|
||||
}
|
||||
|
||||
static const char* label_values[2][3] = {
|
||||
{ "##position_x", "##position_y", "##position_z"},
|
||||
{ "##rotation_x", "##rotation_y", "##rotation_z"}
|
||||
|
|
|
@ -5,13 +5,12 @@
|
|||
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include <float.h>
|
||||
|
||||
#include "slic3r/GUI/Selection.hpp"
|
||||
//#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class Selection;
|
||||
class GLCanvas3D;
|
||||
|
||||
class GizmoObjectManipulation
|
||||
|
@ -83,6 +82,7 @@ public:
|
|||
bool m_uniform_scale {true};
|
||||
// Does the object manipulation panel work in World or Local coordinates?
|
||||
bool m_world_coordinates = true;
|
||||
ECoordinatesType m_coordinates_type{ECoordinatesType::World};
|
||||
|
||||
bool m_show_clear_rotation { false };
|
||||
bool m_show_clear_scale { false };
|
||||
|
@ -108,8 +108,11 @@ public:
|
|||
void set_uniform_scaling(const bool uniform_scale);
|
||||
bool get_uniform_scaling() const { return m_uniform_scale; }
|
||||
// Does the object manipulation panel work in World or Local coordinates?
|
||||
void set_world_coordinates(const bool world_coordinates) { m_world_coordinates = world_coordinates; this->UpdateAndShow(true); }
|
||||
bool get_world_coordinates() const { return m_world_coordinates; }
|
||||
void set_coordinates_type(ECoordinatesType type);
|
||||
ECoordinatesType get_coordinates_type() const { return m_coordinates_type; }
|
||||
bool is_world_coordinates() const { return m_coordinates_type == ECoordinatesType::World; }
|
||||
bool is_instance_coordinates() const { return m_coordinates_type == ECoordinatesType::Instance; }
|
||||
bool is_local_coordinates() const { return m_coordinates_type == ECoordinatesType::Local; }
|
||||
|
||||
void reset_cache() { m_cache.reset(); }
|
||||
|
||||
|
|
|
@ -865,6 +865,101 @@ const BoundingBoxf3& Selection::get_scaled_instance_bounding_box() const
|
|||
return *m_scaled_instance_bounding_box;
|
||||
}
|
||||
|
||||
const std::pair<BoundingBoxf3, Transform3d> &Selection::get_bounding_box_in_current_reference_system() const
|
||||
{
|
||||
static int last_coordinates_type = -1;
|
||||
|
||||
assert(!is_empty());
|
||||
|
||||
ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||
if (m_mode == Instance && coordinates_type == ECoordinatesType::Local) coordinates_type = ECoordinatesType::World;
|
||||
|
||||
if (last_coordinates_type != int(coordinates_type)) const_cast<std::optional<std::pair<BoundingBoxf3, Transform3d>> *>(&m_bounding_box_in_current_reference_system)->reset();
|
||||
|
||||
if (!m_bounding_box_in_current_reference_system.has_value()) {
|
||||
last_coordinates_type = int(coordinates_type);
|
||||
*const_cast<std::optional<std::pair<BoundingBoxf3, Transform3d>> *>(&m_bounding_box_in_current_reference_system) = get_bounding_box_in_reference_system(coordinates_type);
|
||||
}
|
||||
|
||||
return *m_bounding_box_in_current_reference_system;
|
||||
}
|
||||
|
||||
std::pair<BoundingBoxf3, Transform3d> Selection::get_bounding_box_in_reference_system(ECoordinatesType type) const
|
||||
{
|
||||
//
|
||||
// trafo to current reference system
|
||||
//
|
||||
Transform3d trafo;
|
||||
switch (type) {
|
||||
case ECoordinatesType::World: {
|
||||
trafo = Transform3d::Identity();
|
||||
break;
|
||||
}
|
||||
case ECoordinatesType::Instance: {
|
||||
trafo = get_first_volume()->get_instance_transformation().get_matrix();
|
||||
break;
|
||||
}
|
||||
case ECoordinatesType::Local: {
|
||||
trafo = get_first_volume()->world_matrix();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// trafo basis in world coordinates
|
||||
//
|
||||
Geometry::Transformation t(trafo);
|
||||
t.reset_scaling_factor();
|
||||
const Transform3d basis_trafo = t.get_matrix_no_offset();
|
||||
std::vector<Vec3d> axes = {Vec3d::UnitX(), Vec3d::UnitY(), Vec3d::UnitZ()};
|
||||
for (size_t i = 0; i < axes.size(); ++i) { axes[i] = basis_trafo * axes[i]; }
|
||||
|
||||
//
|
||||
// calculate bounding box aligned to trafo basis
|
||||
//
|
||||
Vec3d min = {DBL_MAX, DBL_MAX, DBL_MAX};
|
||||
Vec3d max = {-DBL_MAX, -DBL_MAX, -DBL_MAX};
|
||||
for (unsigned int id : m_list) {
|
||||
const GLVolume & vol = *get_volume(id);
|
||||
const Transform3d vol_world_rafo = vol.world_matrix();
|
||||
const TriangleMesh *mesh = vol.convex_hull();
|
||||
if (mesh == nullptr) mesh = &m_model->objects[vol.object_idx()]->volumes[vol.volume_idx()]->mesh();
|
||||
assert(mesh != nullptr);
|
||||
for (const stl_vertex &v : mesh->its.vertices) {
|
||||
const Vec3d world_v = vol_world_rafo * v.cast<double>();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const double i_comp = world_v.dot(axes[i]);
|
||||
min(i) = std::min(min(i), i_comp);
|
||||
max(i) = std::max(max(i), i_comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Vec3d box_size = max - min;
|
||||
Vec3d half_box_size = 0.5 * box_size;
|
||||
Geometry::Transformation out_trafo(trafo);
|
||||
Vec3d center = 0.5 * (min + max);
|
||||
|
||||
// Fix for non centered volume
|
||||
// by move with calculated center(to volume center) and extend half box size
|
||||
// e.g. for right aligned embossed text
|
||||
if (m_list.size() == 1 && type == ECoordinatesType::Local) {
|
||||
const GLVolume & vol = *get_volume(*m_list.begin());
|
||||
const Transform3d vol_world_trafo = vol.world_matrix();
|
||||
Vec3d world_zero = vol_world_trafo * Vec3d::Zero();
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
// move center to local volume zero
|
||||
center[i] = world_zero.dot(axes[i]);
|
||||
// extend half size to bigger distance from center
|
||||
half_box_size[i] = std::max(abs(center[i] - min[i]), abs(center[i] - max[i]));
|
||||
}
|
||||
}
|
||||
|
||||
const BoundingBoxf3 out_box(-half_box_size, half_box_size);
|
||||
out_trafo.set_offset(basis_trafo * center);
|
||||
return {out_box, out_trafo.get_matrix_no_scaling_factor()};
|
||||
}
|
||||
|
||||
void Selection::start_dragging()
|
||||
{
|
||||
if (!m_valid)
|
||||
|
|
|
@ -26,6 +26,12 @@ using ModelObjectPtrs = std::vector<ModelObject*>;
|
|||
|
||||
|
||||
namespace GUI {
|
||||
enum ECoordinatesType : unsigned char {
|
||||
World,
|
||||
Instance,
|
||||
Local
|
||||
};
|
||||
|
||||
class TransformationType
|
||||
{
|
||||
public:
|
||||
|
@ -214,6 +220,9 @@ private:
|
|||
std::optional<BoundingBoxf3> m_unscaled_instance_bounding_box;
|
||||
std::optional<BoundingBoxf3> m_scaled_instance_bounding_box;
|
||||
|
||||
// Bounding box aligned to the axis of the currently selected reference system (World/Object/Part)
|
||||
// and transform to place and orient it in world coordinates
|
||||
std::optional<std::pair<BoundingBoxf3, Transform3d>> m_bounding_box_in_current_reference_system;
|
||||
#if ENABLE_RENDER_SELECTION_CENTER
|
||||
GLModel m_vbo_sphere;
|
||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||
|
@ -330,6 +339,13 @@ public:
|
|||
const BoundingBoxf3& get_unscaled_instance_bounding_box() const;
|
||||
const BoundingBoxf3& get_scaled_instance_bounding_box() const;
|
||||
|
||||
// Returns the bounding box aligned to the axes of the currently selected reference system (World/Object/Part)
|
||||
// and the transform to place and orient it in world coordinates
|
||||
const std::pair<BoundingBoxf3, Transform3d> &get_bounding_box_in_current_reference_system() const;
|
||||
// Returns the bounding box aligned to the axes of the given reference system
|
||||
// and the transform to place and orient it in world coordinates
|
||||
std::pair<BoundingBoxf3, Transform3d> get_bounding_box_in_reference_system(ECoordinatesType type) const;
|
||||
|
||||
void start_dragging();
|
||||
void stop_dragging() { m_dragging = false; }
|
||||
bool is_dragging() const { return m_dragging; }
|
||||
|
@ -403,7 +419,11 @@ private:
|
|||
void do_remove_volume(unsigned int volume_idx);
|
||||
void do_remove_instance(unsigned int object_idx, unsigned int instance_idx);
|
||||
void do_remove_object(unsigned int object_idx);
|
||||
void set_bounding_boxes_dirty() { m_bounding_box.reset(); m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset(); }
|
||||
void set_bounding_boxes_dirty() {
|
||||
m_bounding_box.reset();
|
||||
m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset();
|
||||
m_bounding_box_in_current_reference_system.reset();
|
||||
}
|
||||
void render_selected_volumes() const;
|
||||
void render_synchronized_volumes() const;
|
||||
void render_bounding_box(const BoundingBoxf3& box, float* color) const;
|
||||
|
|
Loading…
Reference in New Issue