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:
enricoturri1966 2022-05-04 10:28:59 +02:00
parent 55be16d158
commit 9f503b95e8
7 changed files with 256 additions and 77 deletions

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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()

View File

@ -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;

View File

@ -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: