mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-26 08:54:27 +08:00
Fixed uninitialized variables reported by MemorySanitizer in Geometry::Transformation
This commit is contained in:
parent
2673994471
commit
bcaa0d38bd
@ -325,40 +325,36 @@ Vec3d extract_euler_angles(const Eigen::Matrix<double, 3, 3, Eigen::DontAlign>&
|
|||||||
// reference: http://www.gregslabaugh.net/publications/euler.pdf
|
// reference: http://www.gregslabaugh.net/publications/euler.pdf
|
||||||
Vec3d angles1 = Vec3d::Zero();
|
Vec3d angles1 = Vec3d::Zero();
|
||||||
Vec3d angles2 = Vec3d::Zero();
|
Vec3d angles2 = Vec3d::Zero();
|
||||||
if (std::abs(std::abs(rotation_matrix(2, 0)) - 1.0) < 1e-5)
|
if (std::abs(std::abs(rotation_matrix(2, 0)) - 1.0) < 1e-5) {
|
||||||
{
|
angles1.z() = 0.0;
|
||||||
angles1(2) = 0.0;
|
if (rotation_matrix(2, 0) < 0.0) { // == -1.0
|
||||||
if (rotation_matrix(2, 0) < 0.0) // == -1.0
|
angles1.y() = 0.5 * double(PI);
|
||||||
{
|
angles1.x() = angles1.z() + ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2));
|
||||||
angles1(1) = 0.5 * (double)PI;
|
|
||||||
angles1(0) = angles1(2) + ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2));
|
|
||||||
}
|
}
|
||||||
else // == 1.0
|
else { // == 1.0
|
||||||
{
|
angles1.y() = - 0.5 * double(PI);
|
||||||
angles1(1) = - 0.5 * (double)PI;
|
angles1.x() = - angles1.y() + ::atan2(- rotation_matrix(0, 1), - rotation_matrix(0, 2));
|
||||||
angles1(0) = - angles1(2) + ::atan2(- rotation_matrix(0, 1), - rotation_matrix(0, 2));
|
|
||||||
}
|
}
|
||||||
angles2 = angles1;
|
angles2 = angles1;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
angles1.y() = -::asin(rotation_matrix(2, 0));
|
||||||
angles1(1) = -::asin(rotation_matrix(2, 0));
|
const double inv_cos1 = 1.0 / ::cos(angles1.y());
|
||||||
double inv_cos1 = 1.0 / ::cos(angles1(1));
|
angles1.x() = ::atan2(rotation_matrix(2, 1) * inv_cos1, rotation_matrix(2, 2) * inv_cos1);
|
||||||
angles1(0) = ::atan2(rotation_matrix(2, 1) * inv_cos1, rotation_matrix(2, 2) * inv_cos1);
|
angles1.z() = ::atan2(rotation_matrix(1, 0) * inv_cos1, rotation_matrix(0, 0) * inv_cos1);
|
||||||
angles1(2) = ::atan2(rotation_matrix(1, 0) * inv_cos1, rotation_matrix(0, 0) * inv_cos1);
|
|
||||||
|
|
||||||
angles2(1) = (double)PI - angles1(1);
|
angles2.y() = double(PI) - angles1.y();
|
||||||
double inv_cos2 = 1.0 / ::cos(angles2(1));
|
const double inv_cos2 = 1.0 / ::cos(angles2.y());
|
||||||
angles2(0) = ::atan2(rotation_matrix(2, 1) * inv_cos2, rotation_matrix(2, 2) * inv_cos2);
|
angles2.x() = ::atan2(rotation_matrix(2, 1) * inv_cos2, rotation_matrix(2, 2) * inv_cos2);
|
||||||
angles2(2) = ::atan2(rotation_matrix(1, 0) * inv_cos2, rotation_matrix(0, 0) * inv_cos2);
|
angles2.z() = ::atan2(rotation_matrix(1, 0) * inv_cos2, rotation_matrix(0, 0) * inv_cos2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following euristic is the best found up to now (in the sense that it works fine with the greatest number of edge use-cases)
|
// The following euristic is the best found up to now (in the sense that it works fine with the greatest number of edge use-cases)
|
||||||
// but there are other use-cases were it does not
|
// but there are other use-cases were it does not
|
||||||
// We need to improve it
|
// We need to improve it
|
||||||
double min_1 = angles1.cwiseAbs().minCoeff();
|
const double min_1 = angles1.cwiseAbs().minCoeff();
|
||||||
double min_2 = angles2.cwiseAbs().minCoeff();
|
const double min_2 = angles2.cwiseAbs().minCoeff();
|
||||||
bool use_1 = (min_1 < min_2) || (is_approx(min_1, min_2) && (angles1.norm() <= angles2.norm()));
|
const bool use_1 = (min_1 < min_2) || (is_approx(min_1, min_2) && (angles1.norm() <= angles2.norm()));
|
||||||
|
|
||||||
return use_1 ? angles1 : angles2;
|
return use_1 ? angles1 : angles2;
|
||||||
}
|
}
|
||||||
@ -374,14 +370,6 @@ Vec3d extract_euler_angles(const Transform3d& transform)
|
|||||||
return extract_euler_angles(m);
|
return extract_euler_angles(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
Transformation::Flags::Flags()
|
|
||||||
: dont_translate(true)
|
|
||||||
, dont_rotate(true)
|
|
||||||
, dont_scale(true)
|
|
||||||
, dont_mirror(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
|
bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
|
||||||
{
|
{
|
||||||
return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale) || (this->dont_mirror != dont_mirror);
|
return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale) || (this->dont_mirror != dont_mirror);
|
||||||
@ -407,15 +395,14 @@ Transformation::Transformation(const Transform3d& transform)
|
|||||||
|
|
||||||
void Transformation::set_offset(const Vec3d& offset)
|
void Transformation::set_offset(const Vec3d& offset)
|
||||||
{
|
{
|
||||||
set_offset(X, offset(0));
|
set_offset(X, offset.x());
|
||||||
set_offset(Y, offset(1));
|
set_offset(Y, offset.y());
|
||||||
set_offset(Z, offset(2));
|
set_offset(Z, offset.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformation::set_offset(Axis axis, double offset)
|
void Transformation::set_offset(Axis axis, double offset)
|
||||||
{
|
{
|
||||||
if (m_offset(axis) != offset)
|
if (m_offset(axis) != offset) {
|
||||||
{
|
|
||||||
m_offset(axis) = offset;
|
m_offset(axis) = offset;
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
@ -423,19 +410,18 @@ void Transformation::set_offset(Axis axis, double offset)
|
|||||||
|
|
||||||
void Transformation::set_rotation(const Vec3d& rotation)
|
void Transformation::set_rotation(const Vec3d& rotation)
|
||||||
{
|
{
|
||||||
set_rotation(X, rotation(0));
|
set_rotation(X, rotation.x());
|
||||||
set_rotation(Y, rotation(1));
|
set_rotation(Y, rotation.y());
|
||||||
set_rotation(Z, rotation(2));
|
set_rotation(Z, rotation.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformation::set_rotation(Axis axis, double rotation)
|
void Transformation::set_rotation(Axis axis, double rotation)
|
||||||
{
|
{
|
||||||
rotation = angle_to_0_2PI(rotation);
|
rotation = angle_to_0_2PI(rotation);
|
||||||
if (is_approx(std::abs(rotation), 2.0 * (double)PI))
|
if (is_approx(std::abs(rotation), 2.0 * double(PI)))
|
||||||
rotation = 0.0;
|
rotation = 0.0;
|
||||||
|
|
||||||
if (m_rotation(axis) != rotation)
|
if (m_rotation(axis) != rotation) {
|
||||||
{
|
|
||||||
m_rotation(axis) = rotation;
|
m_rotation(axis) = rotation;
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
@ -443,15 +429,14 @@ void Transformation::set_rotation(Axis axis, double rotation)
|
|||||||
|
|
||||||
void Transformation::set_scaling_factor(const Vec3d& scaling_factor)
|
void Transformation::set_scaling_factor(const Vec3d& scaling_factor)
|
||||||
{
|
{
|
||||||
set_scaling_factor(X, scaling_factor(0));
|
set_scaling_factor(X, scaling_factor.x());
|
||||||
set_scaling_factor(Y, scaling_factor(1));
|
set_scaling_factor(Y, scaling_factor.y());
|
||||||
set_scaling_factor(Z, scaling_factor(2));
|
set_scaling_factor(Z, scaling_factor.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
|
void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
|
||||||
{
|
{
|
||||||
if (m_scaling_factor(axis) != std::abs(scaling_factor))
|
if (m_scaling_factor(axis) != std::abs(scaling_factor)) {
|
||||||
{
|
|
||||||
m_scaling_factor(axis) = std::abs(scaling_factor);
|
m_scaling_factor(axis) = std::abs(scaling_factor);
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
@ -459,9 +444,9 @@ void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
|
|||||||
|
|
||||||
void Transformation::set_mirror(const Vec3d& mirror)
|
void Transformation::set_mirror(const Vec3d& mirror)
|
||||||
{
|
{
|
||||||
set_mirror(X, mirror(0));
|
set_mirror(X, mirror.x());
|
||||||
set_mirror(Y, mirror(1));
|
set_mirror(Y, mirror.y());
|
||||||
set_mirror(Z, mirror(2));
|
set_mirror(Z, mirror.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformation::set_mirror(Axis axis, double mirror)
|
void Transformation::set_mirror(Axis axis, double mirror)
|
||||||
@ -472,8 +457,7 @@ void Transformation::set_mirror(Axis axis, double mirror)
|
|||||||
else if (abs_mirror != 1.0)
|
else if (abs_mirror != 1.0)
|
||||||
mirror /= abs_mirror;
|
mirror /= abs_mirror;
|
||||||
|
|
||||||
if (m_mirror(axis) != mirror)
|
if (m_mirror(axis) != mirror) {
|
||||||
{
|
|
||||||
m_mirror(axis) = mirror;
|
m_mirror(axis) = mirror;
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
@ -491,9 +475,8 @@ void Transformation::set_from_transform(const Transform3d& transform)
|
|||||||
// we can only detect if the matrix contains a left handed reference system
|
// we can only detect if the matrix contains a left handed reference system
|
||||||
// in which case we reorient it back to right handed by mirroring the x axis
|
// in which case we reorient it back to right handed by mirroring the x axis
|
||||||
Vec3d mirror = Vec3d::Ones();
|
Vec3d mirror = Vec3d::Ones();
|
||||||
if (m3x3.col(0).dot(m3x3.col(1).cross(m3x3.col(2))) < 0.0)
|
if (m3x3.col(0).dot(m3x3.col(1).cross(m3x3.col(2))) < 0.0) {
|
||||||
{
|
mirror.x() = -1.0;
|
||||||
mirror(0) = -1.0;
|
|
||||||
// remove mirror
|
// remove mirror
|
||||||
m3x3.col(0) *= -1.0;
|
m3x3.col(0) *= -1.0;
|
||||||
}
|
}
|
||||||
@ -530,8 +513,7 @@ void Transformation::reset()
|
|||||||
|
|
||||||
const Transform3d& Transformation::get_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
|
const Transform3d& Transformation::get_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
|
||||||
{
|
{
|
||||||
if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale, dont_mirror))
|
if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale, dont_mirror)) {
|
||||||
{
|
|
||||||
m_matrix = Geometry::assemble_transform(
|
m_matrix = Geometry::assemble_transform(
|
||||||
dont_translate ? Vec3d::Zero() : m_offset,
|
dont_translate ? Vec3d::Zero() : m_offset,
|
||||||
dont_rotate ? Vec3d::Zero() : m_rotation,
|
dont_rotate ? Vec3d::Zero() : m_rotation,
|
||||||
@ -560,8 +542,7 @@ Transformation Transformation::volume_to_bed_transformation(const Transformation
|
|||||||
// Just set the inverse.
|
// Just set the inverse.
|
||||||
out.set_from_transform(instance_transformation.get_matrix(true).inverse());
|
out.set_from_transform(instance_transformation.get_matrix(true).inverse());
|
||||||
}
|
}
|
||||||
else if (is_rotation_ninety_degrees(instance_transformation.get_rotation()))
|
else if (is_rotation_ninety_degrees(instance_transformation.get_rotation())) {
|
||||||
{
|
|
||||||
// Anisotropic scaling, rotation by multiples of ninety degrees.
|
// Anisotropic scaling, rotation by multiples of ninety degrees.
|
||||||
Eigen::Matrix3d instance_rotation_trafo =
|
Eigen::Matrix3d instance_rotation_trafo =
|
||||||
(Eigen::AngleAxisd(instance_transformation.get_rotation().z(), Vec3d::UnitZ()) *
|
(Eigen::AngleAxisd(instance_transformation.get_rotation().z(), Vec3d::UnitZ()) *
|
||||||
@ -594,8 +575,8 @@ Transformation Transformation::volume_to_bed_transformation(const Transformation
|
|||||||
scale(i) = pts.col(i).dot(qs.col(i)) / pts.col(i).dot(pts.col(i));
|
scale(i) = pts.col(i).dot(qs.col(i)) / pts.col(i).dot(pts.col(i));
|
||||||
|
|
||||||
out.set_rotation(Geometry::extract_euler_angles(volume_rotation_trafo));
|
out.set_rotation(Geometry::extract_euler_angles(volume_rotation_trafo));
|
||||||
out.set_scaling_factor(Vec3d(std::abs(scale(0)), std::abs(scale(1)), std::abs(scale(2))));
|
out.set_scaling_factor(Vec3d(std::abs(scale.x()), std::abs(scale.y()), std::abs(scale.z())));
|
||||||
out.set_mirror(Vec3d(scale(0) > 0 ? 1. : -1, scale(1) > 0 ? 1. : -1, scale(2) > 0 ? 1. : -1));
|
out.set_mirror(Vec3d(scale.x() > 0 ? 1. : -1, scale.y() > 0 ? 1. : -1, scale.z() > 0 ? 1. : -1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -614,19 +595,15 @@ Transform3d transform3d_from_string(const std::string& transform_str)
|
|||||||
assert(is_decimal_separator_point()); // for atof
|
assert(is_decimal_separator_point()); // for atof
|
||||||
Transform3d transform = Transform3d::Identity();
|
Transform3d transform = Transform3d::Identity();
|
||||||
|
|
||||||
if (!transform_str.empty())
|
if (!transform_str.empty()) {
|
||||||
{
|
|
||||||
std::vector<std::string> mat_elements_str;
|
std::vector<std::string> mat_elements_str;
|
||||||
boost::split(mat_elements_str, transform_str, boost::is_any_of(" "), boost::token_compress_on);
|
boost::split(mat_elements_str, transform_str, boost::is_any_of(" "), boost::token_compress_on);
|
||||||
|
|
||||||
unsigned int size = (unsigned int)mat_elements_str.size();
|
const unsigned int size = (unsigned int)mat_elements_str.size();
|
||||||
if (size == 16)
|
if (size == 16) {
|
||||||
{
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (unsigned int r = 0; r < 4; ++r)
|
for (unsigned int r = 0; r < 4; ++r) {
|
||||||
{
|
for (unsigned int c = 0; c < 4; ++c) {
|
||||||
for (unsigned int c = 0; c < 4; ++c)
|
|
||||||
{
|
|
||||||
transform(r, c) = ::atof(mat_elements_str[i++].c_str());
|
transform(r, c) = ::atof(mat_elements_str[i++].c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,17 +617,17 @@ Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec3d &rot
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
// From the current coordinate system to world.
|
// 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()) *
|
Eigen::AngleAxisd(rot_xyz_to.z(), Vec3d::UnitZ()) * Eigen::AngleAxisd(rot_xyz_to.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(rot_xyz_to.x(), Vec3d::UnitX()) *
|
||||||
// From world to the initial coordinate system.
|
// 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());
|
Eigen::AngleAxisd(-rot_xyz_from.x(), Vec3d::UnitX()) * Eigen::AngleAxisd(-rot_xyz_from.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(-rot_xyz_from.z(), Vec3d::UnitZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should only be called if it is known, that the two rotations only differ in rotation around the Z axis.
|
// 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)
|
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));
|
const Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
|
||||||
Vec3d axis = angle_axis.axis();
|
const Vec3d axis = angle_axis.axis();
|
||||||
double angle = angle_axis.angle();
|
const double angle = angle_axis.angle();
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (std::abs(angle) > 1e-8) {
|
if (std::abs(angle) > 1e-8) {
|
||||||
assert(std::abs(axis.x()) < 1e-8);
|
assert(std::abs(axis.x()) < 1e-8);
|
||||||
|
@ -347,25 +347,23 @@ class Transformation
|
|||||||
{
|
{
|
||||||
struct Flags
|
struct Flags
|
||||||
{
|
{
|
||||||
bool dont_translate;
|
bool dont_translate{ true };
|
||||||
bool dont_rotate;
|
bool dont_rotate{ true };
|
||||||
bool dont_scale;
|
bool dont_scale{ true };
|
||||||
bool dont_mirror;
|
bool dont_mirror{ true };
|
||||||
|
|
||||||
Flags();
|
|
||||||
|
|
||||||
bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const;
|
bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const;
|
||||||
void set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror);
|
void set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror);
|
||||||
};
|
};
|
||||||
|
|
||||||
Vec3d m_offset; // In unscaled coordinates
|
Vec3d m_offset{ Vec3d::Zero() }; // In unscaled coordinates
|
||||||
Vec3d m_rotation; // Rotation around the three axes, in radians around mesh center point
|
Vec3d m_rotation{ Vec3d::Zero() }; // Rotation around the three axes, in radians around mesh center point
|
||||||
Vec3d m_scaling_factor; // Scaling factors along the three axes
|
Vec3d m_scaling_factor{ Vec3d::Ones() }; // Scaling factors along the three axes
|
||||||
Vec3d m_mirror; // Mirroring along the three axes
|
Vec3d m_mirror{ Vec3d::Ones() }; // Mirroring along the three axes
|
||||||
|
|
||||||
mutable Transform3d m_matrix;
|
mutable Transform3d m_matrix{ Transform3d::Identity() };
|
||||||
mutable Flags m_flags;
|
mutable Flags m_flags;
|
||||||
mutable bool m_dirty;
|
mutable bool m_dirty{ false };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Transformation();
|
Transformation();
|
||||||
@ -435,7 +433,7 @@ extern double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to
|
|||||||
// Is the angle close to a multiple of 90 degrees?
|
// Is the angle close to a multiple of 90 degrees?
|
||||||
inline bool is_rotation_ninety_degrees(double a)
|
inline bool is_rotation_ninety_degrees(double a)
|
||||||
{
|
{
|
||||||
a = fmod(std::abs(a), 0.5 * M_PI);
|
a = fmod(std::abs(a), 0.5 * PI);
|
||||||
if (a > 0.25 * PI)
|
if (a > 0.25 * PI)
|
||||||
a = 0.5 * PI - a;
|
a = 0.5 * PI - a;
|
||||||
return a < 0.001;
|
return a < 0.001;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user