Tech ENABLE_TRANSFORMATIONS_BY_MATRICES - Reworked method void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type) to use matrix multiplication
Fixed conflicts during rebase with master
This commit is contained in:
parent
55be16d158
commit
9f503b95e8
@ -314,6 +314,18 @@ Transform3d assemble_transform(const Vec3d& translation, const Vec3d& rotation,
|
||||
}
|
||||
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
void assemble_transform(Transform3d& transform, const Transform3d& translation, const Transform3d& rotation, const Transform3d& scale, const Transform3d& mirror)
|
||||
{
|
||||
transform = translation * rotation * scale * mirror;
|
||||
}
|
||||
|
||||
Transform3d assemble_transform(const Transform3d& translation, const Transform3d& rotation, const Transform3d& scale, const Transform3d& mirror)
|
||||
{
|
||||
Transform3d transform;
|
||||
assemble_transform(transform, translation, rotation, scale, mirror);
|
||||
return transform;
|
||||
}
|
||||
|
||||
void rotation_transform(Transform3d& transform, const Vec3d& rotation)
|
||||
{
|
||||
transform = Transform3d::Identity();
|
||||
|
@ -323,7 +323,8 @@ bool arrange(
|
||||
// 4) rotate Y
|
||||
// 5) rotate Z
|
||||
// 6) translate
|
||||
void assemble_transform(Transform3d& transform, const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(), const Vec3d& scale = Vec3d::Ones(), const Vec3d& mirror = Vec3d::Ones());
|
||||
void assemble_transform(Transform3d& transform, const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(),
|
||||
const Vec3d& scale = Vec3d::Ones(), const Vec3d& mirror = Vec3d::Ones());
|
||||
|
||||
// Returns the transform obtained by assembling the given transformations in the following order:
|
||||
// 1) mirror
|
||||
@ -332,9 +333,21 @@ void assemble_transform(Transform3d& transform, const Vec3d& translation = Vec3d
|
||||
// 4) rotate Y
|
||||
// 5) rotate Z
|
||||
// 6) translate
|
||||
Transform3d assemble_transform(const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(), const Vec3d& scale = Vec3d::Ones(), const Vec3d& mirror = Vec3d::Ones());
|
||||
Transform3d assemble_transform(const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(),
|
||||
const Vec3d& scale = Vec3d::Ones(), const Vec3d& mirror = Vec3d::Ones());
|
||||
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
// Sets the given transform by multiplying the given transformations in the following order:
|
||||
// T = translation * rotation * scale * mirror
|
||||
void assemble_transform(Transform3d& transform, const Transform3d& translation = Transform3d::Identity(),
|
||||
const Transform3d& rotation = Transform3d::Identity(), const Transform3d& scale = Transform3d::Identity(),
|
||||
const Transform3d& mirror = Transform3d::Identity());
|
||||
|
||||
// Returns the transform obtained by multiplying the given transformations in the following order:
|
||||
// T = translation * rotation * scale * mirror
|
||||
Transform3d assemble_transform(const Transform3d& translation = Transform3d::Identity(), const Transform3d& rotation = Transform3d::Identity(),
|
||||
const Transform3d& scale = Transform3d::Identity(), const Transform3d& mirror = Transform3d::Identity());
|
||||
|
||||
// Sets the given transform by assembling the given rotations in the following order:
|
||||
// 1) rotate X
|
||||
// 2) rotate Y
|
||||
@ -391,10 +404,10 @@ class Transformation
|
||||
public:
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
Transformation() = default;
|
||||
explicit Transformation(const Transform3d & transform) : m_matrix(transform) {}
|
||||
explicit Transformation(const Transform3d& transform) : m_matrix(transform) {}
|
||||
#else
|
||||
Transformation();
|
||||
explicit Transformation(const Transform3d & transform);
|
||||
explicit Transformation(const Transform3d& transform);
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
|
@ -3825,9 +3825,17 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
|
||||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr) {
|
||||
if (selection_mode == Selection::Instance)
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
#else
|
||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
else if (selection_mode == Selection::Volume)
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||
#else
|
||||
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
|
||||
object_moved = true;
|
||||
model_object->invalidate_bounding_box();
|
||||
@ -3907,8 +3915,8 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
||||
int object_idx = v->object_idx();
|
||||
if (object_idx == 1000) { // the wipe tower
|
||||
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||
Vec3d offset = v->get_volume_offset();
|
||||
post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset(0), offset(1), v->get_volume_rotation()(2))));
|
||||
const Vec3d offset = v->get_volume_offset();
|
||||
post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), v->get_volume_rotation().z())));
|
||||
}
|
||||
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||
int object_idx = v->object_idx();
|
||||
@ -3916,8 +3924,8 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
||||
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
|
||||
continue;
|
||||
|
||||
int instance_idx = v->instance_idx();
|
||||
int volume_idx = v->volume_idx();
|
||||
const int instance_idx = v->instance_idx();
|
||||
const int volume_idx = v->volume_idx();
|
||||
|
||||
done.insert(std::pair<int, int>(object_idx, instance_idx));
|
||||
|
||||
@ -3925,12 +3933,20 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
||||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr) {
|
||||
if (selection_mode == Selection::Instance) {
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
#else
|
||||
model_object->instances[instance_idx]->set_rotation(v->get_instance_rotation());
|
||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
}
|
||||
else if (selection_mode == Selection::Volume) {
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||
#else
|
||||
model_object->volumes[volume_idx]->set_rotation(v->get_volume_rotation());
|
||||
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
}
|
||||
model_object->invalidate_bounding_box();
|
||||
}
|
||||
@ -7347,13 +7363,11 @@ bool GLCanvas3D::_is_any_volume_outside() const
|
||||
void GLCanvas3D::_update_selection_from_hover()
|
||||
{
|
||||
bool ctrl_pressed = wxGetKeyState(WXK_CONTROL);
|
||||
bool selection_changed = false;
|
||||
|
||||
if (m_hover_volume_idxs.empty()) {
|
||||
if (!ctrl_pressed && m_rectangle_selection.get_state() == GLSelectionRectangle::EState::Select) {
|
||||
selection_changed = ! m_selection.is_empty();
|
||||
if (!ctrl_pressed && m_rectangle_selection.get_state() == GLSelectionRectangle::EState::Select)
|
||||
m_selection.remove_all();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GLSelectionRectangle::EState state = m_rectangle_selection.get_state();
|
||||
@ -7366,6 +7380,7 @@ void GLCanvas3D::_update_selection_from_hover()
|
||||
}
|
||||
}
|
||||
|
||||
bool selection_changed = false;
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (!m_rectangle_selection.is_empty()) {
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
|
@ -54,9 +54,7 @@ bool GLGizmoMove3D::on_mouse(const wxMouseEvent &mouse_event) {
|
||||
}
|
||||
|
||||
void GLGizmoMove3D::data_changed() {
|
||||
const Selection &selection = m_parent.get_selection();
|
||||
bool is_wipe_tower = selection.is_wipe_tower();
|
||||
m_grabbers[2].enabled = !is_wipe_tower;
|
||||
m_grabbers[2].enabled = !m_parent.get_selection().is_wipe_tower();
|
||||
}
|
||||
|
||||
bool GLGizmoMove3D::on_init()
|
||||
@ -100,11 +98,19 @@ void GLGizmoMove3D::on_start_dragging()
|
||||
m_starting_drag_position = m_center + m_grabbers[m_hover_id].center;
|
||||
else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) {
|
||||
const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
m_starting_drag_position = m_center + v.get_instance_transformation().get_rotation_matrix() * v.get_volume_transformation().get_rotation_matrix() * m_grabbers[m_hover_id].center;
|
||||
#else
|
||||
m_starting_drag_position = m_center + Geometry::assemble_transform(Vec3d::Zero(), v.get_instance_rotation()) * Geometry::assemble_transform(Vec3d::Zero(), v.get_volume_rotation()) * m_grabbers[m_hover_id].center;
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
}
|
||||
else {
|
||||
const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
m_starting_drag_position = m_center + v.get_instance_transformation().get_rotation_matrix() * m_grabbers[m_hover_id].center;
|
||||
#else
|
||||
m_starting_drag_position = m_center + Geometry::assemble_transform(Vec3d::Zero(), v.get_instance_rotation()) * m_grabbers[m_hover_id].center;
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
}
|
||||
m_starting_box_center = m_center;
|
||||
m_starting_box_bottom_center = m_center;
|
||||
|
@ -287,7 +287,15 @@ void GLGizmoRotate::on_render_for_picking()
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void GLGizmoRotate::init_data_from_selection(const Selection& selection)
|
||||
{
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
ECoordinatesType coordinates_type;
|
||||
if (selection.is_wipe_tower())
|
||||
coordinates_type = ECoordinatesType::Local;
|
||||
else
|
||||
coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||
#else
|
||||
const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
if (coordinates_type == ECoordinatesType::World) {
|
||||
m_bounding_box = selection.get_bounding_box();
|
||||
m_center = m_bounding_box.center();
|
||||
@ -326,7 +334,11 @@ void GLGizmoRotate::init_data_from_selection(const Selection& selection)
|
||||
|
||||
if (coordinates_type == ECoordinatesType::World)
|
||||
m_orient_matrix = Transform3d::Identity();
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
else if (coordinates_type == ECoordinatesType::Local && (selection.is_wipe_tower() || selection.is_single_volume_or_modifier())) {
|
||||
#else
|
||||
else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) {
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const GLVolume& v = *selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
m_orient_matrix = v.get_instance_transformation().get_rotation_matrix() * v.get_volume_transformation().get_rotation_matrix();
|
||||
@ -749,12 +761,20 @@ Transform3d GLGizmoRotate::local_transform(const Selection& selection) const
|
||||
{
|
||||
case X:
|
||||
{
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
ret = Geometry::rotation_transform(0.5 * PI * Vec3d::UnitY()) * Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitZ());
|
||||
#else
|
||||
ret = Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY()) * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ());
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
break;
|
||||
}
|
||||
case Y:
|
||||
{
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
ret = Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitZ()) * Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitY());
|
||||
#else
|
||||
ret = Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ()) * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitY());
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -868,13 +888,21 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event)
|
||||
// Apply new temporary rotations
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType transformation_type;
|
||||
switch (wxGetApp().obj_manipul()->get_coordinates_type())
|
||||
{
|
||||
default:
|
||||
case ECoordinatesType::World: { transformation_type = TransformationType::World_Relative_Joint; break; }
|
||||
case ECoordinatesType::Instance: { transformation_type = TransformationType::Instance_Relative_Joint; break; }
|
||||
case ECoordinatesType::Local: { transformation_type = TransformationType::Local_Relative_Joint; break; }
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
if (m_parent.get_selection().is_wipe_tower())
|
||||
transformation_type = TransformationType::Instance_Relative_Joint;
|
||||
else {
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
switch (wxGetApp().obj_manipul()->get_coordinates_type())
|
||||
{
|
||||
default:
|
||||
case ECoordinatesType::World: { transformation_type = TransformationType::World_Relative_Joint; break; }
|
||||
case ECoordinatesType::Instance: { transformation_type = TransformationType::Instance_Relative_Joint; break; }
|
||||
case ECoordinatesType::Local: { transformation_type = TransformationType::Local_Relative_Joint; break; }
|
||||
}
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
}
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
#else
|
||||
TransformationType transformation_type(TransformationType::World_Relative_Joint);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
@ -885,22 +913,27 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event)
|
||||
}
|
||||
|
||||
void GLGizmoRotate3D::data_changed() {
|
||||
const Selection &selection = m_parent.get_selection();
|
||||
bool is_wipe_tower = selection.is_wipe_tower();
|
||||
if (is_wipe_tower) {
|
||||
DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
float wipe_tower_rotation_angle =
|
||||
dynamic_cast<const ConfigOptionFloat *>(
|
||||
config.option("wipe_tower_rotation_angle"))
|
||||
->value;
|
||||
if (m_parent.get_selection().is_wipe_tower()) {
|
||||
#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
const float wipe_tower_rotation_angle =
|
||||
dynamic_cast<const ConfigOptionFloat*>(
|
||||
config.option("wipe_tower_rotation_angle"))->value;
|
||||
set_rotation(Vec3d(0., 0., (M_PI / 180.) * wipe_tower_rotation_angle));
|
||||
#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
m_gizmos[0].disable_grabber();
|
||||
m_gizmos[1].disable_grabber();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
set_rotation(Vec3d::Zero());
|
||||
#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
m_gizmos[0].enable_grabber();
|
||||
m_gizmos[1].enable_grabber();
|
||||
}
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
set_rotation(Vec3d::Zero());
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
}
|
||||
|
||||
bool GLGizmoRotate3D::on_init()
|
||||
|
@ -35,29 +35,25 @@ static const Slic3r::ColorRGBA TRANSPARENT_PLANE_COLOR = { 0.8f, 0.8f, 0.8f, 0.5
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
Selection::VolumeCache::TransformCache::TransformCache()
|
||||
: position(Vec3d::Zero())
|
||||
, rotation(Vec3d::Zero())
|
||||
, scaling_factor(Vec3d::Ones())
|
||||
, mirror(Vec3d::Ones())
|
||||
, rotation_matrix(Transform3d::Identity())
|
||||
, scale_matrix(Transform3d::Identity())
|
||||
, mirror_matrix(Transform3d::Identity())
|
||||
, full_matrix(Transform3d::Identity())
|
||||
{
|
||||
}
|
||||
|
||||
Selection::VolumeCache::TransformCache::TransformCache(const Geometry::Transformation& transform)
|
||||
: position(transform.get_offset())
|
||||
, rotation(transform.get_rotation())
|
||||
, scaling_factor(transform.get_scaling_factor())
|
||||
, mirror(transform.get_mirror())
|
||||
, full_matrix(transform.get_matrix())
|
||||
{
|
||||
rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
scale_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scaling_factor);
|
||||
mirror_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d::Ones(), mirror);
|
||||
}
|
||||
Selection::VolumeCache::TransformCache::TransformCache(const Geometry::Transformation& transform)
|
||||
: position(transform.get_offset())
|
||||
, rotation(transform.get_rotation())
|
||||
, scaling_factor(transform.get_scaling_factor())
|
||||
, mirror(transform.get_mirror())
|
||||
, full_matrix(transform.get_matrix())
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
, transform(transform)
|
||||
, rotation_matrix(transform.get_rotation_matrix())
|
||||
, scale_matrix(transform.get_scaling_factor_matrix())
|
||||
, mirror_matrix(transform.get_mirror_matrix())
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
{
|
||||
#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
scale_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scaling_factor);
|
||||
mirror_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d::Ones(), mirror);
|
||||
#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
}
|
||||
|
||||
Selection::VolumeCache::VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform)
|
||||
: m_volume(volume_transform)
|
||||
@ -772,27 +768,19 @@ void Selection::translate(const Vec3d& displacement, ECoordinatesType type)
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume& v = *(*m_volumes)[i];
|
||||
const VolumeCache& volume_data = m_cache.volumes_data[i];
|
||||
if (m_mode == Instance && !v.is_wipe_tower) {
|
||||
if (m_mode == Instance && !is_wipe_tower()) {
|
||||
assert(is_from_fully_selected_instance(i));
|
||||
switch (type)
|
||||
{
|
||||
case ECoordinatesType::World:
|
||||
{
|
||||
if (is_from_fully_selected_instance(i))
|
||||
v.set_instance_transformation(Geometry::assemble_transform(displacement) * volume_data.get_instance_full_matrix());
|
||||
else
|
||||
assert(false);
|
||||
|
||||
v.set_instance_transformation(Geometry::assemble_transform(displacement) * volume_data.get_instance_full_matrix());
|
||||
break;
|
||||
}
|
||||
case ECoordinatesType::Local:
|
||||
{
|
||||
if (is_from_fully_selected_instance(i)) {
|
||||
const Vec3d world_displacemet = volume_data.get_instance_rotation_matrix() * displacement;
|
||||
v.set_instance_transformation(Geometry::assemble_transform(world_displacemet) * volume_data.get_instance_full_matrix());
|
||||
}
|
||||
else
|
||||
assert(false);
|
||||
|
||||
const Vec3d world_displacemet = volume_data.get_instance_rotation_matrix() * displacement;
|
||||
v.set_instance_transformation(Geometry::assemble_transform(world_displacemet) * volume_data.get_instance_full_matrix());
|
||||
break;
|
||||
}
|
||||
default: { assert(false); break; }
|
||||
@ -913,6 +901,88 @@ void Selection::translate(const Vec3d& displacement, bool local)
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
|
||||
// Rotate an object around one of the axes. Only one rotation component is expected to be changing.
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type)
|
||||
{
|
||||
if (!m_valid)
|
||||
return;
|
||||
|
||||
assert(transformation_type.relative() || (transformation_type.absolute() && transformation_type.local()));
|
||||
|
||||
const Transform3d rotation_matrix = Geometry::rotation_transform(rotation);
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume& v = *(*m_volumes)[i];
|
||||
const VolumeCache& volume_data = m_cache.volumes_data[i];
|
||||
if (m_mode == Instance && !is_wipe_tower()) {
|
||||
assert(is_from_fully_selected_instance(i));
|
||||
const Geometry::Transformation& old_trafo = volume_data.get_instance_transform();
|
||||
Transform3d new_rotation_matrix = Transform3d::Identity();
|
||||
if (transformation_type.absolute())
|
||||
new_rotation_matrix = rotation_matrix;
|
||||
else {
|
||||
if (transformation_type.world())
|
||||
new_rotation_matrix = rotation_matrix * old_trafo.get_rotation_matrix();
|
||||
else if (transformation_type.local())
|
||||
new_rotation_matrix = old_trafo.get_rotation_matrix() * rotation_matrix;
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
|
||||
const Vec3d new_offset = transformation_type.independent() ? old_trafo.get_offset() :
|
||||
m_cache.dragging_center + new_rotation_matrix * old_trafo.get_rotation_matrix().inverse() *
|
||||
(old_trafo.get_offset() - m_cache.dragging_center);
|
||||
v.set_instance_transformation(Geometry::assemble_transform(Geometry::assemble_transform(new_offset), new_rotation_matrix,
|
||||
old_trafo.get_scaling_factor_matrix(), old_trafo.get_mirror_matrix()));
|
||||
}
|
||||
else {
|
||||
const Geometry::Transformation& old_trafo = volume_data.get_volume_transform();
|
||||
Transform3d new_rotation_matrix = Transform3d::Identity();
|
||||
|
||||
if (transformation_type.absolute())
|
||||
new_rotation_matrix = rotation_matrix;
|
||||
else {
|
||||
if (transformation_type.world()) {
|
||||
const Transform3d inst_rotation_matrix = volume_data.get_instance_transform().get_rotation_matrix();
|
||||
new_rotation_matrix = inst_rotation_matrix.inverse() * rotation_matrix * inst_rotation_matrix * old_trafo.get_rotation_matrix();
|
||||
}
|
||||
else if (transformation_type.instance())
|
||||
new_rotation_matrix = rotation_matrix * old_trafo.get_rotation_matrix();
|
||||
else if (transformation_type.local())
|
||||
new_rotation_matrix = old_trafo.get_rotation_matrix() * rotation_matrix;
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
|
||||
const Vec3d new_offset = !is_wipe_tower() ? old_trafo.get_offset() :
|
||||
m_cache.dragging_center + new_rotation_matrix * old_trafo.get_rotation_matrix().inverse() *
|
||||
(old_trafo.get_offset() - m_cache.dragging_center);
|
||||
v.set_volume_transformation(Geometry::assemble_transform(Geometry::assemble_transform(new_offset), new_rotation_matrix,
|
||||
old_trafo.get_scaling_factor_matrix(), old_trafo.get_mirror_matrix()));
|
||||
}
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
if (m_mode == Instance) {
|
||||
int rot_axis_max = 0;
|
||||
rotation.cwiseAbs().maxCoeff(&rot_axis_max);
|
||||
SyncRotationType synch;
|
||||
if (transformation_type.world() && rot_axis_max == 2)
|
||||
synch = SyncRotationType::NONE;
|
||||
else if (transformation_type.local())
|
||||
synch = SyncRotationType::FULL;
|
||||
else
|
||||
synch = SyncRotationType::GENERAL;
|
||||
synchronize_unselected_instances(synch);
|
||||
}
|
||||
else if (m_mode == Volume)
|
||||
synchronize_unselected_volumes();
|
||||
#endif // !DISABLE_INSTANCES_SYNCH
|
||||
|
||||
set_bounding_boxes_dirty();
|
||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||
}
|
||||
#else
|
||||
void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type)
|
||||
{
|
||||
if (!m_valid)
|
||||
@ -1073,6 +1143,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||
set_bounding_boxes_dirty();
|
||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||
}
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
|
||||
void Selection::flattening_rotate(const Vec3d& normal)
|
||||
{
|
||||
@ -2975,7 +3046,13 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
|
||||
if (v->object_idx() != object_idx || v->instance_idx() == instance_idx)
|
||||
continue;
|
||||
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const Vec3d inst_rotation_i = m_cache.volumes_data[i].get_instance_transform().get_rotation();
|
||||
const Vec3d inst_rotation_j = m_cache.volumes_data[j].get_instance_transform().get_rotation();
|
||||
assert(is_rotation_xy_synchronized(inst_rotation_i, inst_rotation_j));
|
||||
#else
|
||||
assert(is_rotation_xy_synchronized(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation()));
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
switch (sync_rotation_type) {
|
||||
case SyncRotationType::NONE: {
|
||||
// z only rotation -> synch instance z
|
||||
@ -2987,17 +3064,29 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
|
||||
}
|
||||
case SyncRotationType::GENERAL: {
|
||||
// generic rotation -> update instance z with the delta of the rotation.
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const double z_diff = Geometry::rotation_diff_z(inst_rotation_i, inst_rotation_j);
|
||||
#else
|
||||
const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation());
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
v->set_instance_rotation({ rotation.x(), rotation.y(), rotation.z() + z_diff });
|
||||
break;
|
||||
}
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
case SyncRotationType::FULL: {
|
||||
// generic rotation -> update instance z with the delta of the rotation.
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const Eigen::AngleAxisd angle_axis(Geometry::rotation_xyz_diff(rotation, inst_rotation_j));
|
||||
#else
|
||||
const Eigen::AngleAxisd angle_axis(Geometry::rotation_xyz_diff(rotation, m_cache.volumes_data[j].get_instance_rotation()));
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const Vec3d& axis = angle_axis.axis();
|
||||
const double z_diff = (std::abs(axis.x()) > EPSILON || std::abs(axis.y()) > EPSILON) ?
|
||||
angle_axis.angle() * axis.z() : Geometry::rotation_diff_z(rotation, m_cache.volumes_data[j].get_instance_rotation());
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
angle_axis.angle() * axis.z() : Geometry::rotation_diff_z(rotation, inst_rotation_j);
|
||||
#else
|
||||
angle_axis.angle()* axis.z() : Geometry::rotation_diff_z(rotation, m_cache.volumes_data[j].get_instance_rotation());
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
|
||||
v->set_instance_rotation({ rotation.x(), rotation.y(), rotation.z() + z_diff });
|
||||
break;
|
||||
|
@ -121,16 +121,19 @@ private:
|
||||
private:
|
||||
struct TransformCache
|
||||
{
|
||||
Vec3d position;
|
||||
Vec3d rotation;
|
||||
Vec3d scaling_factor;
|
||||
Vec3d mirror;
|
||||
Transform3d rotation_matrix;
|
||||
Transform3d scale_matrix;
|
||||
Transform3d mirror_matrix;
|
||||
Transform3d full_matrix;
|
||||
Vec3d position{ Vec3d::Zero() };
|
||||
Vec3d rotation{ Vec3d::Zero() };
|
||||
Vec3d scaling_factor{ Vec3d::Ones() };
|
||||
Vec3d mirror{ Vec3d::Ones() };
|
||||
Transform3d rotation_matrix{ Transform3d::Identity() };
|
||||
Transform3d scale_matrix{ Transform3d::Identity() };
|
||||
Transform3d mirror_matrix{ Transform3d::Identity() };
|
||||
Transform3d full_matrix{ Transform3d::Identity() };
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
Geometry::Transformation transform;
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
|
||||
TransformCache();
|
||||
TransformCache() = default;
|
||||
explicit TransformCache(const Geometry::Transformation& transform);
|
||||
};
|
||||
|
||||
@ -142,13 +145,18 @@ private:
|
||||
VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform);
|
||||
|
||||
const Vec3d& get_volume_position() const { return m_volume.position; }
|
||||
#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const Vec3d& get_volume_rotation() const { return m_volume.rotation; }
|
||||
const Vec3d& get_volume_scaling_factor() const { return m_volume.scaling_factor; }
|
||||
const Vec3d& get_volume_mirror() const { return m_volume.mirror; }
|
||||
#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const Transform3d& get_volume_rotation_matrix() const { return m_volume.rotation_matrix; }
|
||||
const Transform3d& get_volume_scale_matrix() const { return m_volume.scale_matrix; }
|
||||
const Transform3d& get_volume_mirror_matrix() const { return m_volume.mirror_matrix; }
|
||||
const Transform3d& get_volume_full_matrix() const { return m_volume.full_matrix; }
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const Geometry::Transformation& get_volume_transform() const { return m_volume.transform; }
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
|
||||
const Vec3d& get_instance_position() const { return m_instance.position; }
|
||||
const Vec3d& get_instance_rotation() const { return m_instance.rotation; }
|
||||
@ -158,6 +166,9 @@ private:
|
||||
const Transform3d& get_instance_scale_matrix() const { return m_instance.scale_matrix; }
|
||||
const Transform3d& get_instance_mirror_matrix() const { return m_instance.mirror_matrix; }
|
||||
const Transform3d& get_instance_full_matrix() const { return m_instance.full_matrix; }
|
||||
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
const Geometry::Transformation& get_instance_transform() const { return m_instance.transform; }
|
||||
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
|
||||
};
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user