Fixed rotation of SLA instances in case a rotation in X or Y was applied
to the instances.
This commit is contained in:
parent
9bc93134f9
commit
ca6a5af1dc
4 changed files with 47 additions and 34 deletions
|
@ -1455,4 +1455,28 @@ Transformation Transformation::operator * (const Transformation& other) const
|
||||||
return Transformation(get_matrix() * other.get_matrix());
|
return Transformation(get_matrix() * other.get_matrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
// From the current coordinate system to world.
|
||||||
|
Eigen::AngleAxisd(rot_xyz_to(2), Vec3d::UnitZ()) * Eigen::AngleAxisd(rot_xyz_to(1), Vec3d::UnitY()) * Eigen::AngleAxisd(rot_xyz_to(0), Vec3d::UnitX()) *
|
||||||
|
// From world to the initial coordinate system.
|
||||||
|
Eigen::AngleAxisd(-rot_xyz_from(0), Vec3d::UnitX()) * Eigen::AngleAxisd(-rot_xyz_from(1), Vec3d::UnitY()) * Eigen::AngleAxisd(-rot_xyz_from(2), Vec3d::UnitZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should only be called if it is known, that the two rotations only differ in rotation around the Z axis.
|
||||||
|
double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
|
||||||
|
{
|
||||||
|
Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
|
||||||
|
Vec3d axis = angle_axis.axis();
|
||||||
|
double angle = angle_axis.angle();
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (std::abs(angle) > 1e-8) {
|
||||||
|
assert(std::abs(axis.x()) < 1e-8);
|
||||||
|
assert(std::abs(axis.y()) < 1e-8);
|
||||||
|
}
|
||||||
|
#endif /* NDEBUG */
|
||||||
|
return (axis.z() < 0) ? -angle : angle;
|
||||||
|
}
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -262,6 +262,13 @@ public:
|
||||||
Transformation operator * (const Transformation& other) const;
|
Transformation operator * (const Transformation& other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Rotation when going from the first coordinate system with rotation rot_xyz_from applied
|
||||||
|
// to a coordinate system with rot_xyz_to applied.
|
||||||
|
extern Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to);
|
||||||
|
// Rotation by Z to align rot_xyz_from to rot_xyz_to.
|
||||||
|
// This should only be called if it is known, that the two rotations only differ in rotation around the Z axis.
|
||||||
|
extern double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to);
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "SLA/SLABasePool.hpp"
|
#include "SLA/SLABasePool.hpp"
|
||||||
#include "SLA/SLAAutoSupports.hpp"
|
#include "SLA/SLAAutoSupports.hpp"
|
||||||
#include "ClipperUtils.hpp"
|
#include "ClipperUtils.hpp"
|
||||||
|
#include "Geometry.hpp"
|
||||||
#include "MTUtils.hpp"
|
#include "MTUtils.hpp"
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
@ -103,13 +104,18 @@ static Transform3d sla_trafo(const ModelObject &model_object)
|
||||||
static std::vector<SLAPrintObject::Instance> sla_instances(const ModelObject &model_object)
|
static std::vector<SLAPrintObject::Instance> sla_instances(const ModelObject &model_object)
|
||||||
{
|
{
|
||||||
std::vector<SLAPrintObject::Instance> instances;
|
std::vector<SLAPrintObject::Instance> instances;
|
||||||
for (ModelInstance *model_instance : model_object.instances)
|
assert(! model_object.instances.empty());
|
||||||
if (model_instance->is_printable()) {
|
if (! model_object.instances.empty()) {
|
||||||
instances.emplace_back(
|
Vec3d rotation0 = model_object.instances.front()->get_rotation();
|
||||||
model_instance->id(),
|
rotation0(2) = 0.;
|
||||||
Point::new_scale(model_instance->get_offset(X), model_instance->get_offset(Y)),
|
for (ModelInstance *model_instance : model_object.instances)
|
||||||
float(model_instance->get_rotation(Z)));
|
if (model_instance->is_printable()) {
|
||||||
}
|
instances.emplace_back(
|
||||||
|
model_instance->id(),
|
||||||
|
Point::new_scale(model_instance->get_offset(X), model_instance->get_offset(Y)),
|
||||||
|
float(Geometry::rotation_diff_z(rotation0, model_instance->get_rotation())));
|
||||||
|
}
|
||||||
|
}
|
||||||
return instances;
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -482,30 +482,6 @@ void Selection::translate(const Vec3d& displacement, bool local)
|
||||||
m_bounding_box_dirty = true;
|
m_bounding_box_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
// From the current coordinate system to world.
|
|
||||||
Eigen::AngleAxisd(rot_xyz_to(2), Vec3d::UnitZ()) * Eigen::AngleAxisd(rot_xyz_to(1), Vec3d::UnitY()) * Eigen::AngleAxisd(rot_xyz_to(0), Vec3d::UnitX()) *
|
|
||||||
// From world to the initial coordinate system.
|
|
||||||
Eigen::AngleAxisd(-rot_xyz_from(0), Vec3d::UnitX()) * Eigen::AngleAxisd(-rot_xyz_from(1), Vec3d::UnitY()) * Eigen::AngleAxisd(-rot_xyz_from(2), Vec3d::UnitZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should only be called if it is known, that the two rotations only differ in rotation around the Z axis.
|
|
||||||
static double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
|
|
||||||
{
|
|
||||||
Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
|
|
||||||
Vec3d axis = angle_axis.axis();
|
|
||||||
double angle = angle_axis.angle();
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (std::abs(angle) > 1e-8) {
|
|
||||||
assert(std::abs(axis.x()) < 1e-8);
|
|
||||||
assert(std::abs(axis.y()) < 1e-8);
|
|
||||||
}
|
|
||||||
#endif /* NDEBUG */
|
|
||||||
return (axis.z() < 0) ? -angle : angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rotate an object around one of the axes. Only one rotation component is expected to be changing.
|
// Rotate an object around one of the axes. Only one rotation component is expected to be changing.
|
||||||
void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type)
|
void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type)
|
||||||
{
|
{
|
||||||
|
@ -548,7 +524,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||||
assert(is_approx(rotation.z(), 0.0));
|
assert(is_approx(rotation.z(), 0.0));
|
||||||
const GLVolume &first_volume = *(*m_volumes)[first_volume_idx];
|
const GLVolume &first_volume = *(*m_volumes)[first_volume_idx];
|
||||||
const Vec3d &rotation = first_volume.get_instance_rotation();
|
const Vec3d &rotation = first_volume.get_instance_rotation();
|
||||||
double z_diff = rotation_diff_z(m_cache.volumes_data[first_volume_idx].get_instance_rotation(), m_cache.volumes_data[i].get_instance_rotation());
|
double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[first_volume_idx].get_instance_rotation(), m_cache.volumes_data[i].get_instance_rotation());
|
||||||
volume.set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff));
|
volume.set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1538,7 +1514,7 @@ void Selection::render_sidebar_size_hint(Axis axis, double length) const
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
|
static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
|
||||||
{
|
{
|
||||||
Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
|
Eigen::AngleAxisd angle_axis(Geometry::rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
|
||||||
Vec3d axis = angle_axis.axis();
|
Vec3d axis = angle_axis.axis();
|
||||||
double angle = angle_axis.angle();
|
double angle = angle_axis.angle();
|
||||||
if (std::abs(angle) < 1e-8)
|
if (std::abs(angle) < 1e-8)
|
||||||
|
@ -1618,7 +1594,7 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
|
||||||
break;
|
break;
|
||||||
case SYNC_ROTATION_GENERAL:
|
case SYNC_ROTATION_GENERAL:
|
||||||
// generic rotation -> update instance z with the delta of the rotation.
|
// generic rotation -> update instance z with the delta of the rotation.
|
||||||
double z_diff = rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation());
|
double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation());
|
||||||
v->set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff));
|
v->set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue