Merge remote-tracking branch 'origin/et_transformations' into et_sequential
This commit is contained in:
commit
89b82ed5ea
38 changed files with 173 additions and 2555 deletions
src
libslic3r
slic3r/GUI
3DBed.cpp3DBed.hpp3DScene.cpp3DScene.hppCoordAxes.cppCoordAxes.hppGLCanvas3D.cppGLCanvas3D.hppGUI_Geometry.hppGUI_ObjectList.cppGUI_ObjectManipulation.cppGUI_ObjectManipulation.hpp
Gizmos
GLGizmoBase.cppGLGizmoBase.hppGLGizmoFdmSupports.cppGLGizmoFlatten.cppGLGizmoHollow.cppGLGizmoMove.cppGLGizmoMove.hppGLGizmoPainterBase.cppGLGizmoRotate.cppGLGizmoRotate.hppGLGizmoScale.cppGLGizmoScale.hppGLGizmoSlaSupports.cpp
MeshUtils.cppPlater.cppSelection.cppSelection.hppwxExtensions.cpp
|
@ -395,7 +395,6 @@ Vec3d extract_rotation(const Transform3d& transform)
|
|||
return extract_rotation(m);
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Transform3d Transformation::get_offset_matrix() const
|
||||
{
|
||||
return translation_transform(get_offset());
|
||||
|
@ -461,57 +460,12 @@ Transform3d Transformation::get_rotation_matrix() const
|
|||
{
|
||||
return extract_rotation_matrix(m_matrix);
|
||||
}
|
||||
#else
|
||||
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);
|
||||
}
|
||||
|
||||
void Transformation::Flags::set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror)
|
||||
{
|
||||
this->dont_translate = dont_translate;
|
||||
this->dont_rotate = dont_rotate;
|
||||
this->dont_scale = dont_scale;
|
||||
this->dont_mirror = dont_mirror;
|
||||
}
|
||||
|
||||
Transformation::Transformation()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
Transformation::Transformation(const Transform3d& transform)
|
||||
{
|
||||
set_from_transform(transform);
|
||||
}
|
||||
|
||||
void Transformation::set_offset(const Vec3d& offset)
|
||||
{
|
||||
set_offset(X, offset.x());
|
||||
set_offset(Y, offset.y());
|
||||
set_offset(Z, offset.z());
|
||||
}
|
||||
|
||||
void Transformation::set_offset(Axis axis, double offset)
|
||||
{
|
||||
if (m_offset(axis) != offset) {
|
||||
m_offset(axis) = offset;
|
||||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Transformation::set_rotation(const Vec3d& rotation)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Vec3d offset = get_offset();
|
||||
m_matrix = rotation_transform(rotation) * extract_scale(m_matrix);
|
||||
m_matrix.translation() = offset;
|
||||
#else
|
||||
set_rotation(X, rotation.x());
|
||||
set_rotation(Y, rotation.y());
|
||||
set_rotation(Z, rotation.z());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
void Transformation::set_rotation(Axis axis, double rotation)
|
||||
|
@ -520,7 +474,6 @@ void Transformation::set_rotation(Axis axis, double rotation)
|
|||
if (is_approx(std::abs(rotation), 2.0 * double(PI)))
|
||||
rotation = 0.0;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
auto [curr_rotation, scale] = extract_rotation_scale(m_matrix);
|
||||
Vec3d angles = extract_rotation(curr_rotation);
|
||||
angles[axis] = rotation;
|
||||
|
@ -528,15 +481,8 @@ void Transformation::set_rotation(Axis axis, double rotation)
|
|||
const Vec3d offset = get_offset();
|
||||
m_matrix = rotation_transform(angles) * scale;
|
||||
m_matrix.translation() = offset;
|
||||
#else
|
||||
if (m_rotation(axis) != rotation) {
|
||||
m_rotation(axis) = rotation;
|
||||
m_dirty = true;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d Transformation::get_scaling_factor() const
|
||||
{
|
||||
const Transform3d scale = extract_scale(m_matrix);
|
||||
|
@ -551,26 +497,18 @@ Transform3d Transformation::get_scaling_factor_matrix() const
|
|||
scale(2, 2) = std::abs(scale(2, 2));
|
||||
return scale;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Transformation::set_scaling_factor(const Vec3d& scaling_factor)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
assert(scaling_factor.x() > 0.0 && scaling_factor.y() > 0.0 && scaling_factor.z() > 0.0);
|
||||
|
||||
const Vec3d offset = get_offset();
|
||||
m_matrix = extract_rotation_matrix(m_matrix) * scale_transform(scaling_factor);
|
||||
m_matrix.translation() = offset;
|
||||
#else
|
||||
set_scaling_factor(X, scaling_factor.x());
|
||||
set_scaling_factor(Y, scaling_factor.y());
|
||||
set_scaling_factor(Z, scaling_factor.z());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
assert(scaling_factor > 0.0);
|
||||
|
||||
auto [rotation, scale] = extract_rotation_scale(m_matrix);
|
||||
|
@ -579,15 +517,8 @@ void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
|
|||
const Vec3d offset = get_offset();
|
||||
m_matrix = rotation * scale;
|
||||
m_matrix.translation() = offset;
|
||||
#else
|
||||
if (m_scaling_factor(axis) != std::abs(scaling_factor)) {
|
||||
m_scaling_factor(axis) = std::abs(scaling_factor);
|
||||
m_dirty = true;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d Transformation::get_mirror() const
|
||||
{
|
||||
const Transform3d scale = extract_scale(m_matrix);
|
||||
|
@ -602,11 +533,9 @@ Transform3d Transformation::get_mirror_matrix() const
|
|||
scale(2, 2) = scale(2, 2) / std::abs(scale(2, 2));
|
||||
return scale;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Transformation::set_mirror(const Vec3d& mirror)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d copy(mirror);
|
||||
const Vec3d abs_mirror = copy.cwiseAbs();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
|
@ -627,11 +556,6 @@ void Transformation::set_mirror(const Vec3d& mirror)
|
|||
const Vec3d offset = get_offset();
|
||||
m_matrix = rotation * scale;
|
||||
m_matrix.translation() = offset;
|
||||
#else
|
||||
set_mirror(X, mirror.x());
|
||||
set_mirror(Y, mirror.y());
|
||||
set_mirror(Z, mirror.z());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
void Transformation::set_mirror(Axis axis, double mirror)
|
||||
|
@ -642,7 +566,6 @@ void Transformation::set_mirror(Axis axis, double mirror)
|
|||
else if (abs_mirror != 1.0)
|
||||
mirror /= abs_mirror;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
auto [rotation, scale] = extract_rotation_scale(m_matrix);
|
||||
const double curr_scale = scale(axis, axis);
|
||||
const double sign = curr_scale * mirror;
|
||||
|
@ -652,74 +575,18 @@ void Transformation::set_mirror(Axis axis, double mirror)
|
|||
const Vec3d offset = get_offset();
|
||||
m_matrix = rotation * scale;
|
||||
m_matrix.translation() = offset;
|
||||
#else
|
||||
if (m_mirror(axis) != mirror) {
|
||||
m_mirror(axis) = mirror;
|
||||
m_dirty = true;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
bool Transformation::has_skew() const
|
||||
{
|
||||
return contains_skew(m_matrix);
|
||||
}
|
||||
#else
|
||||
void Transformation::set_from_transform(const Transform3d& transform)
|
||||
{
|
||||
// offset
|
||||
set_offset(transform.matrix().block(0, 3, 3, 1));
|
||||
|
||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> m3x3 = transform.matrix().block(0, 0, 3, 3);
|
||||
|
||||
// mirror
|
||||
// it is impossible to reconstruct the original mirroring factors from a matrix,
|
||||
// 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
|
||||
Vec3d mirror = Vec3d::Ones();
|
||||
if (m3x3.col(0).dot(m3x3.col(1).cross(m3x3.col(2))) < 0.0) {
|
||||
mirror.x() = -1.0;
|
||||
// remove mirror
|
||||
m3x3.col(0) *= -1.0;
|
||||
}
|
||||
set_mirror(mirror);
|
||||
|
||||
// scale
|
||||
set_scaling_factor(Vec3d(m3x3.col(0).norm(), m3x3.col(1).norm(), m3x3.col(2).norm()));
|
||||
|
||||
// remove scale
|
||||
m3x3.col(0).normalize();
|
||||
m3x3.col(1).normalize();
|
||||
m3x3.col(2).normalize();
|
||||
|
||||
// rotation
|
||||
set_rotation(extract_rotation(m3x3));
|
||||
|
||||
// forces matrix recalculation matrix
|
||||
m_matrix = get_matrix();
|
||||
|
||||
// // debug check
|
||||
// if (!m_matrix.isApprox(transform))
|
||||
// std::cout << "something went wrong in extracting data from matrix" << std::endl;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Transformation::reset()
|
||||
{
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
m_offset = Vec3d::Zero();
|
||||
m_rotation = Vec3d::Zero();
|
||||
m_scaling_factor = Vec3d::Ones();
|
||||
m_mirror = Vec3d::Ones();
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
m_matrix = Transform3d::Identity();
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
m_dirty = false;
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Transformation::reset_rotation()
|
||||
{
|
||||
const Geometry::TransformationSVD svd(*this);
|
||||
|
@ -755,88 +622,12 @@ Transform3d Transformation::get_matrix_no_scaling_factor() const
|
|||
copy.reset_scaling_factor();
|
||||
return copy.get_matrix();
|
||||
}
|
||||
#else
|
||||
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)) {
|
||||
m_matrix = Geometry::assemble_transform(
|
||||
dont_translate ? Vec3d::Zero() : m_offset,
|
||||
dont_rotate ? Vec3d::Zero() : m_rotation,
|
||||
dont_scale ? Vec3d::Ones() : m_scaling_factor,
|
||||
dont_mirror ? Vec3d::Ones() : m_mirror
|
||||
);
|
||||
|
||||
m_flags.set(dont_translate, dont_rotate, dont_scale, dont_mirror);
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
return m_matrix;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
Transformation Transformation::operator * (const Transformation& other) const
|
||||
{
|
||||
return Transformation(get_matrix() * other.get_matrix());
|
||||
}
|
||||
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
Transformation Transformation::volume_to_bed_transformation(const Transformation& instance_transformation, const BoundingBoxf3& bbox)
|
||||
{
|
||||
Transformation out;
|
||||
|
||||
if (instance_transformation.is_scaling_uniform()) {
|
||||
// No need to run the non-linear least squares fitting for uniform scaling.
|
||||
// Just set the inverse.
|
||||
out.set_from_transform(instance_transformation.get_matrix(true).inverse());
|
||||
}
|
||||
else if (is_rotation_ninety_degrees(instance_transformation.get_rotation())) {
|
||||
// Anisotropic scaling, rotation by multiples of ninety degrees.
|
||||
Eigen::Matrix3d instance_rotation_trafo =
|
||||
(Eigen::AngleAxisd(instance_transformation.get_rotation().z(), Vec3d::UnitZ()) *
|
||||
Eigen::AngleAxisd(instance_transformation.get_rotation().y(), Vec3d::UnitY()) *
|
||||
Eigen::AngleAxisd(instance_transformation.get_rotation().x(), Vec3d::UnitX())).toRotationMatrix();
|
||||
Eigen::Matrix3d volume_rotation_trafo =
|
||||
(Eigen::AngleAxisd(-instance_transformation.get_rotation().x(), Vec3d::UnitX()) *
|
||||
Eigen::AngleAxisd(-instance_transformation.get_rotation().y(), Vec3d::UnitY()) *
|
||||
Eigen::AngleAxisd(-instance_transformation.get_rotation().z(), Vec3d::UnitZ())).toRotationMatrix();
|
||||
|
||||
// 8 corners of the bounding box.
|
||||
auto pts = Eigen::MatrixXd(8, 3);
|
||||
pts(0, 0) = bbox.min.x(); pts(0, 1) = bbox.min.y(); pts(0, 2) = bbox.min.z();
|
||||
pts(1, 0) = bbox.min.x(); pts(1, 1) = bbox.min.y(); pts(1, 2) = bbox.max.z();
|
||||
pts(2, 0) = bbox.min.x(); pts(2, 1) = bbox.max.y(); pts(2, 2) = bbox.min.z();
|
||||
pts(3, 0) = bbox.min.x(); pts(3, 1) = bbox.max.y(); pts(3, 2) = bbox.max.z();
|
||||
pts(4, 0) = bbox.max.x(); pts(4, 1) = bbox.min.y(); pts(4, 2) = bbox.min.z();
|
||||
pts(5, 0) = bbox.max.x(); pts(5, 1) = bbox.min.y(); pts(5, 2) = bbox.max.z();
|
||||
pts(6, 0) = bbox.max.x(); pts(6, 1) = bbox.max.y(); pts(6, 2) = bbox.min.z();
|
||||
pts(7, 0) = bbox.max.x(); pts(7, 1) = bbox.max.y(); pts(7, 2) = bbox.max.z();
|
||||
|
||||
// Corners of the bounding box transformed into the modifier mesh coordinate space, with inverse rotation applied to the modifier.
|
||||
auto qs = pts *
|
||||
(instance_rotation_trafo *
|
||||
Eigen::Scaling(instance_transformation.get_scaling_factor().cwiseProduct(instance_transformation.get_mirror())) *
|
||||
volume_rotation_trafo).inverse().transpose();
|
||||
// Fill in scaling based on least squares fitting of the bounding box corners.
|
||||
Vec3d scale;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
scale(i) = pts.col(i).dot(qs.col(i)) / pts.col(i).dot(pts.col(i));
|
||||
|
||||
out.set_rotation(Geometry::extract_rotation(volume_rotation_trafo));
|
||||
out.set_scaling_factor(Vec3d(std::abs(scale.x()), std::abs(scale.y()), std::abs(scale.z())));
|
||||
out.set_mirror(Vec3d(scale.x() > 0 ? 1. : -1, scale.y() > 0 ? 1. : -1, scale.z() > 0 ? 1. : -1));
|
||||
}
|
||||
else {
|
||||
// General anisotropic scaling, general rotation.
|
||||
// Keep the modifier mesh in the instance coordinate system, so the modifier mesh will not be aligned with the world.
|
||||
// Scale it to get the required size.
|
||||
out.set_scaling_factor(instance_transformation.get_scaling_factor().cwiseInverse());
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationSVD::TransformationSVD(const Transform3d& trafo)
|
||||
{
|
||||
const auto &m0 = trafo.matrix().block<3, 3>(0, 0);
|
||||
|
@ -883,7 +674,6 @@ TransformationSVD::TransformationSVD(const Transform3d& trafo)
|
|||
} else
|
||||
skew = false;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// For parsing a transformation matrix from 3MF / AMF.
|
||||
Transform3d transform3d_from_string(const std::string& transform_str)
|
||||
|
|
|
@ -383,32 +383,9 @@ Vec3d extract_rotation(const Transform3d& transform);
|
|||
|
||||
class Transformation
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Transform3d m_matrix{ Transform3d::Identity() };
|
||||
#else
|
||||
struct Flags
|
||||
{
|
||||
bool dont_translate{ true };
|
||||
bool dont_rotate{ true };
|
||||
bool dont_scale{ true };
|
||||
bool dont_mirror{ true };
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
Vec3d m_offset{ Vec3d::Zero() }; // In unscaled coordinates
|
||||
Vec3d m_rotation{ Vec3d::Zero() }; // Rotation around the three axes, in radians around mesh center point
|
||||
Vec3d m_scaling_factor{ Vec3d::Ones() }; // Scaling factors along the three axes
|
||||
Vec3d m_mirror{ Vec3d::Ones() }; // Mirroring along the three axes
|
||||
|
||||
mutable Transform3d m_matrix{ Transform3d::Identity() };
|
||||
mutable Flags m_flags;
|
||||
mutable bool m_dirty{ false };
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
public:
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Transformation() = default;
|
||||
explicit Transformation(const Transform3d& transform) : m_matrix(transform) {}
|
||||
|
||||
|
@ -424,26 +401,10 @@ public:
|
|||
double get_rotation(Axis axis) const { return get_rotation()[axis]; }
|
||||
|
||||
Transform3d get_rotation_matrix() const;
|
||||
#else
|
||||
Transformation();
|
||||
explicit Transformation(const Transform3d& transform);
|
||||
|
||||
const Vec3d& get_offset() const { return m_offset; }
|
||||
double get_offset(Axis axis) const { return m_offset(axis); }
|
||||
|
||||
void set_offset(const Vec3d& offset);
|
||||
void set_offset(Axis axis, double offset);
|
||||
|
||||
const Vec3d& get_rotation() const { return m_rotation; }
|
||||
double get_rotation(Axis axis) const { return m_rotation(axis); }
|
||||
|
||||
Transform3d get_rotation_matrix() const { return rotation_transform(get_rotation()); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void set_rotation(const Vec3d& rotation);
|
||||
void set_rotation(Axis axis, double rotation);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_scaling_factor() const;
|
||||
double get_scaling_factor(Axis axis) const { return get_scaling_factor()[axis]; }
|
||||
|
||||
|
@ -453,17 +414,10 @@ public:
|
|||
const Vec3d scale = get_scaling_factor();
|
||||
return std::abs(scale.x() - scale.y()) < 1e-8 && std::abs(scale.x() - scale.z()) < 1e-8;
|
||||
}
|
||||
#else
|
||||
const Vec3d& get_scaling_factor() const { return m_scaling_factor; }
|
||||
double get_scaling_factor(Axis axis) const { return m_scaling_factor(axis); }
|
||||
|
||||
Transform3d get_scaling_factor_matrix() const { return scale_transform(get_scaling_factor()); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void set_scaling_factor(const Vec3d& scaling_factor);
|
||||
void set_scaling_factor(Axis axis, double scaling_factor);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_mirror() const;
|
||||
double get_mirror(Axis axis) const { return get_mirror()[axis]; }
|
||||
|
||||
|
@ -472,25 +426,13 @@ public:
|
|||
bool is_left_handed() const {
|
||||
return m_matrix.linear().determinant() < 0;
|
||||
}
|
||||
#else
|
||||
bool is_scaling_uniform() const { return std::abs(m_scaling_factor.x() - m_scaling_factor.y()) < 1e-8 && std::abs(m_scaling_factor.x() - m_scaling_factor.z()) < 1e-8; }
|
||||
|
||||
const Vec3d& get_mirror() const { return m_mirror; }
|
||||
double get_mirror(Axis axis) const { return m_mirror(axis); }
|
||||
bool is_left_handed() const { return m_mirror.x() * m_mirror.y() * m_mirror.z() < 0.; }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void set_mirror(const Vec3d& mirror);
|
||||
void set_mirror(Axis axis, double mirror);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
bool has_skew() const;
|
||||
#else
|
||||
void set_from_transform(const Transform3d& transform);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void reset();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void reset_offset() { set_offset(Vec3d::Zero()); }
|
||||
void reset_rotation();
|
||||
void reset_scaling_factor();
|
||||
|
@ -502,22 +444,11 @@ public:
|
|||
Transform3d get_matrix_no_scaling_factor() const;
|
||||
|
||||
void set_matrix(const Transform3d& transform) { m_matrix = transform; }
|
||||
#else
|
||||
const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
Transformation operator * (const Transformation& other) const;
|
||||
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
// Find volume transformation, so that the chained (instance_trafo * volume_trafo) will be as close to identity
|
||||
// as possible in least squares norm in regard to the 8 corners of bbox.
|
||||
// Bounding box is expected to be centered around zero in all axes.
|
||||
static Transformation volume_to_bed_transformation(const Transformation& instance_transformation, const BoundingBoxf3& bbox);
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
private:
|
||||
friend class cereal::access;
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
template<class Archive> void serialize(Archive& ar) { ar(m_matrix); }
|
||||
explicit Transformation(int) {}
|
||||
template <class Archive> static void load_and_construct(Archive& ar, cereal::construct<Transformation>& construct)
|
||||
|
@ -526,24 +457,13 @@ private:
|
|||
construct(1);
|
||||
ar(construct.ptr()->m_matrix);
|
||||
}
|
||||
#else
|
||||
template<class Archive> void serialize(Archive& ar) { ar(m_offset, m_rotation, m_scaling_factor, m_mirror); }
|
||||
explicit Transformation(int) : m_dirty(true) {}
|
||||
template <class Archive> static void load_and_construct(Archive& ar, cereal::construct<Transformation>& construct)
|
||||
{
|
||||
// Calling a private constructor with special "int" parameter to indicate that no construction is necessary.
|
||||
construct(1);
|
||||
ar(construct.ptr()->m_offset, construct.ptr()->m_rotation, construct.ptr()->m_scaling_factor, construct.ptr()->m_mirror);
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
};
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
struct TransformationSVD
|
||||
{
|
||||
Matrix3d u = Matrix3d::Identity();
|
||||
Matrix3d s = Matrix3d::Identity();
|
||||
Matrix3d v = Matrix3d::Identity();
|
||||
Matrix3d u{ Matrix3d::Identity() };
|
||||
Matrix3d s{ Matrix3d::Identity() };
|
||||
Matrix3d v{ Matrix3d::Identity() };
|
||||
|
||||
bool mirror{ false };
|
||||
bool scale{ false };
|
||||
|
@ -557,7 +477,6 @@ struct TransformationSVD
|
|||
|
||||
Eigen::DiagonalMatrix<double, 3, 3> mirror_matrix() const { return Eigen::DiagonalMatrix<double, 3, 3>(this->mirror ? -1. : 1., 1., 1.); }
|
||||
};
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// For parsing a transformation matrix from 3MF / AMF.
|
||||
extern Transform3d transform3d_from_string(const std::string& transform_str);
|
||||
|
|
|
@ -1030,11 +1030,7 @@ const BoundingBoxf3& ModelObject::raw_bounding_box() const
|
|||
if (this->instances.empty())
|
||||
throw Slic3r::InvalidArgument("Can't call raw_bounding_box() with no instances");
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d inst_matrix = this->instances.front()->get_transformation().get_matrix_no_offset();
|
||||
#else
|
||||
const Transform3d& inst_matrix = this->instances.front()->get_transformation().get_matrix(true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
for (const ModelVolume *v : this->volumes)
|
||||
if (v->is_model_part())
|
||||
m_raw_bounding_box.merge(v->mesh().transformed_bounding_box(inst_matrix * v->get_matrix()));
|
||||
|
@ -1046,14 +1042,10 @@ const BoundingBoxf3& ModelObject::raw_bounding_box() const
|
|||
BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx, bool dont_translate) const
|
||||
{
|
||||
BoundingBoxf3 bb;
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d inst_matrix = dont_translate ?
|
||||
this->instances[instance_idx]->get_transformation().get_matrix_no_offset() :
|
||||
this->instances[instance_idx]->get_transformation().get_matrix();
|
||||
|
||||
#else
|
||||
const Transform3d& inst_matrix = this->instances[instance_idx]->get_transformation().get_matrix(dont_translate);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
for (ModelVolume *v : this->volumes) {
|
||||
if (v->is_model_part())
|
||||
bb.merge(v->mesh().transformed_bounding_box(inst_matrix * v->get_matrix()));
|
||||
|
@ -1669,17 +1661,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix,
|
|||
// in the transformation matrix and not applied to the mesh transform.
|
||||
|
||||
// const auto instance_matrix = instances[instance]->get_matrix(true);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const auto instance_matrix = instances[instance]->get_transformation().get_matrix_no_offset();
|
||||
#else
|
||||
const auto instance_matrix = assemble_transform(
|
||||
Vec3d::Zero(), // don't apply offset
|
||||
instances[instance]->get_rotation(),
|
||||
instances[instance]->get_scaling_factor(),
|
||||
instances[instance]->get_mirror()
|
||||
);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
const Transformation cut_transformation = Transformation(cut_matrix);
|
||||
const Transform3d inverse_cut_matrix = cut_transformation.get_rotation_matrix().inverse() * translation_transform(-1. * cut_transformation.get_offset());
|
||||
|
||||
|
@ -1821,11 +1803,7 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
|
|||
new_vol->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||
|
||||
for (ModelInstance* model_instance : new_object->instances) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d shift = model_instance->get_transformation().get_matrix_no_offset() * new_vol->get_offset();
|
||||
#else
|
||||
Vec3d shift = model_instance->get_transformation().get_matrix(true) * new_vol->get_offset();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
const Vec3d shift = model_instance->get_transformation().get_matrix_no_offset() * new_vol->get_offset();
|
||||
model_instance->set_offset(model_instance->get_offset() + shift);
|
||||
}
|
||||
|
||||
|
@ -1866,13 +1844,7 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx)
|
|||
{
|
||||
assert(instance_idx < this->instances.size());
|
||||
|
||||
const Geometry::Transformation reference_trafo = this->instances[instance_idx]->get_transformation();
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
if (Geometry::is_rotation_ninety_degrees(reference_trafo.get_rotation()))
|
||||
// nothing to do, scaling in the world coordinate space is possible in the representation of Geometry::Transformation.
|
||||
return;
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
const Geometry::Transformation reference_trafo = this->instances[instance_idx]->get_transformation();
|
||||
bool left_handed = reference_trafo.is_left_handed();
|
||||
bool has_mirrorring = ! reference_trafo.get_mirror().isApprox(Vec3d(1., 1., 1.));
|
||||
bool uniform_scaling = std::abs(reference_trafo.get_scaling_factor().x() - reference_trafo.get_scaling_factor().y()) < EPSILON &&
|
||||
|
@ -1889,7 +1861,6 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx)
|
|||
|
||||
// Adjust the meshes.
|
||||
// Transformation to be applied to the meshes.
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Geometry::Transformation reference_trafo_mod = reference_trafo;
|
||||
reference_trafo_mod.reset_offset();
|
||||
if (uniform_scaling)
|
||||
|
@ -1897,9 +1868,6 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx)
|
|||
if (!has_mirrorring)
|
||||
reference_trafo_mod.reset_mirror();
|
||||
Eigen::Matrix3d mesh_trafo_3x3 = reference_trafo_mod.get_matrix().matrix().block<3, 3>(0, 0);
|
||||
#else
|
||||
Eigen::Matrix3d mesh_trafo_3x3 = reference_trafo.get_matrix(true, false, uniform_scaling, ! has_mirrorring).matrix().block<3, 3>(0, 0);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
Transform3d volume_offset_correction = this->instances[instance_idx]->get_transformation().get_matrix().inverse() * reference_trafo.get_matrix();
|
||||
for (ModelVolume *model_volume : this->volumes) {
|
||||
const Geometry::Transformation volume_trafo = model_volume->get_transformation();
|
||||
|
@ -1909,7 +1877,6 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx)
|
|||
std::abs(volume_trafo.get_scaling_factor().x() - volume_trafo.get_scaling_factor().z()) < EPSILON;
|
||||
double volume_new_scaling_factor = volume_uniform_scaling ? volume_trafo.get_scaling_factor().x() : 1.;
|
||||
// Transform the mesh.
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Geometry::Transformation volume_trafo_mod = volume_trafo;
|
||||
volume_trafo_mod.reset_offset();
|
||||
if (volume_uniform_scaling)
|
||||
|
@ -1917,11 +1884,8 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx)
|
|||
if (!volume_has_mirrorring)
|
||||
volume_trafo_mod.reset_mirror();
|
||||
Eigen::Matrix3d volume_trafo_3x3 = volume_trafo_mod.get_matrix().matrix().block<3, 3>(0, 0);
|
||||
#else
|
||||
Matrix3d volume_trafo_3x3 = volume_trafo.get_matrix(true, false, volume_uniform_scaling, !volume_has_mirrorring).matrix().block<3, 3>(0, 0);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
// Following method creates a new shared_ptr<TriangleMesh>
|
||||
model_volume->transform_this_mesh(mesh_trafo_3x3 * volume_trafo_3x3, left_handed != volume_left_handed);
|
||||
model_volume->transform_this_mesh(mesh_trafo_3x3 * volume_trafo_3x3, left_handed != volume_left_handed);
|
||||
// Reset the rotation, scaling and mirroring.
|
||||
model_volume->set_rotation(Vec3d(0., 0., 0.));
|
||||
model_volume->set_scaling_factor(Vec3d(volume_new_scaling_factor, volume_new_scaling_factor, volume_new_scaling_factor));
|
||||
|
@ -1940,11 +1904,7 @@ double ModelObject::get_instance_min_z(size_t instance_idx) const
|
|||
double min_z = DBL_MAX;
|
||||
|
||||
const ModelInstance* inst = instances[instance_idx];
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d mi = inst->get_matrix_no_offset();
|
||||
#else
|
||||
const Transform3d& mi = inst->get_matrix(true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
for (const ModelVolume* v : volumes) {
|
||||
if (!v->is_model_part())
|
||||
|
@ -1965,11 +1925,7 @@ double ModelObject::get_instance_max_z(size_t instance_idx) const
|
|||
double max_z = -DBL_MAX;
|
||||
|
||||
const ModelInstance* inst = instances[instance_idx];
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d mi = inst->get_matrix_no_offset();
|
||||
#else
|
||||
const Transform3d& mi = inst->get_matrix(true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
for (const ModelVolume* v : volumes) {
|
||||
if (!v->is_model_part())
|
||||
|
@ -2409,29 +2365,17 @@ void ModelVolume::convert_from_meters()
|
|||
|
||||
void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
mesh->transform(dont_translate ? get_matrix_no_offset() : get_matrix());
|
||||
#else
|
||||
mesh->transform(get_matrix(dont_translate));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate) const
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
return bbox.transformed(dont_translate ? get_matrix_no_offset() : get_matrix());
|
||||
#else
|
||||
return bbox.transformed(get_matrix(dont_translate));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
Vec3d ModelInstance::transform_vector(const Vec3d& v, bool dont_translate) const
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
return dont_translate ? get_matrix_no_offset() * v : get_matrix() * v;
|
||||
#else
|
||||
return get_matrix(dont_translate) * v;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
void ModelInstance::transform_polygon(Polygon* polygon) const
|
||||
|
|
|
@ -880,26 +880,16 @@ public:
|
|||
|
||||
const Geometry::Transformation& get_transformation() const { return m_transformation; }
|
||||
void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; }
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void set_transformation(const Transform3d& trafo) { m_transformation.set_matrix(trafo); }
|
||||
|
||||
Vec3d get_offset() const { return m_transformation.get_offset(); }
|
||||
#else
|
||||
void set_transformation(const Transform3d &trafo) { m_transformation.set_from_transform(trafo); }
|
||||
|
||||
const Vec3d& get_offset() const { return m_transformation.get_offset(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
double get_offset(Axis axis) const { return m_transformation.get_offset(axis); }
|
||||
|
||||
void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); }
|
||||
void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_rotation() const { return m_transformation.get_rotation(); }
|
||||
#else
|
||||
const Vec3d& get_rotation() const { return m_transformation.get_rotation(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); }
|
||||
|
||||
void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); }
|
||||
|
@ -911,11 +901,7 @@ public:
|
|||
void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); }
|
||||
void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_mirror() const { return m_transformation.get_mirror(); }
|
||||
#else
|
||||
const Vec3d& get_mirror() const { return m_transformation.get_mirror(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); }
|
||||
bool is_left_handed() const { return m_transformation.is_left_handed(); }
|
||||
|
||||
|
@ -924,12 +910,8 @@ public:
|
|||
void convert_from_imperial_units();
|
||||
void convert_from_meters();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d& get_matrix() const { return m_transformation.get_matrix(); }
|
||||
Transform3d get_matrix_no_offset() const { return m_transformation.get_matrix_no_offset(); }
|
||||
#else
|
||||
const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.get_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void set_new_unique_id() {
|
||||
ObjectBase::set_new_unique_id();
|
||||
|
@ -1141,43 +1123,27 @@ public:
|
|||
const Geometry::Transformation& get_transformation() const { return m_transformation; }
|
||||
void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_offset() const { return m_transformation.get_offset(); }
|
||||
#else
|
||||
const Vec3d& get_offset() const { return m_transformation.get_offset(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_offset(Axis axis) const { return m_transformation.get_offset(axis); }
|
||||
|
||||
void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); }
|
||||
void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_rotation() const { return m_transformation.get_rotation(); }
|
||||
#else
|
||||
const Vec3d& get_rotation() const { return m_transformation.get_rotation(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); }
|
||||
|
||||
void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); }
|
||||
void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); }
|
||||
#else
|
||||
const Vec3d& get_scaling_factor() const { return m_transformation.get_scaling_factor(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); }
|
||||
|
||||
void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); }
|
||||
void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_mirror() const { return m_transformation.get_mirror(); }
|
||||
#else
|
||||
const Vec3d& get_mirror() const { return m_transformation.get_mirror(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); }
|
||||
bool is_left_handed() const { return m_transformation.is_left_handed(); }
|
||||
bool is_left_handed() const { return m_transformation.is_left_handed(); }
|
||||
|
||||
void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); }
|
||||
void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); }
|
||||
|
@ -1191,12 +1157,8 @@ public:
|
|||
// To be called on an external polygon. It does not translate the polygon, only rotates and scales.
|
||||
void transform_polygon(Polygon* polygon) const;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d& get_matrix() const { return m_transformation.get_matrix(); }
|
||||
Transform3d get_matrix_no_offset() const { return m_transformation.get_matrix_no_offset(); }
|
||||
#else
|
||||
const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.get_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
bool is_printable() const { return object->printable && printable && (print_volume_state == ModelInstancePVS_Inside); }
|
||||
|
||||
|
|
|
@ -392,7 +392,6 @@ bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Poly
|
|||
// FIXME: Arrangement has different parameters for offsetting (jtMiter, limit 2)
|
||||
// which causes that the warning will be showed after arrangement with the
|
||||
// appropriate object distance. Even if I set this to jtMiter the warning still shows up.
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Geometry::Transformation trafo = model_instance0->get_transformation();
|
||||
trafo.set_offset({ 0.0, 0.0, model_instance0->get_offset().z() });
|
||||
it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id,
|
||||
|
@ -401,15 +400,6 @@ bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Poly
|
|||
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
|
||||
float(scale_(0.5 * print.config().extruder_clearance_radius.value - BuildVolume::BedEpsilon)),
|
||||
jtRound, scale_(0.1)).front());
|
||||
#else
|
||||
it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id,
|
||||
offset(print_object->model_object()->convex_hull_2d(
|
||||
Geometry::assemble_transform({ 0.0, 0.0, model_instance0->get_offset().z() }, model_instance0->get_rotation(), model_instance0->get_scaling_factor(), model_instance0->get_mirror())),
|
||||
// Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects
|
||||
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
|
||||
float(scale_(0.5 * print.config().extruder_clearance_radius.value - BuildVolume::BedEpsilon)),
|
||||
jtRound, scale_(0.1)).front());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
// Make a copy, so it may be rotated for instances.
|
||||
Polygon convex_hull0 = it_convex_hull->second;
|
||||
|
|
|
@ -791,13 +791,8 @@ void update_volume_bboxes(
|
|||
if (it != volumes_old.end() && it->volume_id == model_volume->id())
|
||||
layer_range.volumes.emplace_back(*it);
|
||||
} else
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
layer_range.volumes.push_back({ model_volume->id(),
|
||||
transformed_its_bbox2d(model_volume->mesh().its, trafo_for_bbox(object_trafo, model_volume->get_matrix()), offset) });
|
||||
#else
|
||||
layer_range.volumes.push_back({ model_volume->id(),
|
||||
transformed_its_bbox2d(model_volume->mesh().its, trafo_for_bbox(object_trafo, model_volume->get_matrix(false)), offset) });
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
} else {
|
||||
std::vector<std::vector<PrintObjectRegions::VolumeExtents>> volumes_old;
|
||||
|
@ -829,11 +824,7 @@ void update_volume_bboxes(
|
|||
layer_range.volumes.emplace_back(*it);
|
||||
}
|
||||
} else {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
transformed_its_bboxes_in_z_ranges(model_volume->mesh().its, trafo_for_bbox(object_trafo, model_volume->get_matrix()), ranges, bboxes, offset);
|
||||
#else
|
||||
transformed_its_bboxes_in_z_ranges(model_volume->mesh().its, trafo_for_bbox(object_trafo, model_volume->get_matrix(false)), ranges, bboxes, offset);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
for (PrintObjectRegions::LayerRangeRegions &layer_range : layer_ranges)
|
||||
if (auto &bbox = bboxes[&layer_range - layer_ranges.data()]; bbox.second)
|
||||
layer_range.volumes.push_back({ model_volume->id(), bbox.first });
|
||||
|
|
|
@ -300,18 +300,8 @@ struct RotfinderBoilerplate {
|
|||
TriangleMesh mesh = mo.raw_mesh();
|
||||
|
||||
ModelInstance *mi = mo.instances[0];
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Geometry::Transformation trafo = mi->get_transformation();
|
||||
Transform3d trafo_instance = trafo.get_scaling_factor_matrix() * trafo.get_mirror_matrix();
|
||||
#else
|
||||
auto rotation = Vec3d::Zero();
|
||||
auto offset = Vec3d::Zero();
|
||||
Transform3d trafo_instance =
|
||||
Geometry::assemble_transform(offset, rotation,
|
||||
mi->get_scaling_factor(),
|
||||
mi->get_mirror());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
mesh.transform(trafo_instance);
|
||||
|
||||
return mesh;
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
#define ENABLE_RAYCAST_PICKING_DEBUG 0
|
||||
// Shows an imgui dialog with GLModel statistics data
|
||||
#define ENABLE_GLMODEL_STATISTICS 0
|
||||
// Shows an imgui dialog containing the matrices of the selected volumes
|
||||
#define ENABLE_MATRICES_DEBUG 0
|
||||
// Shows an imgui dialog containing data from class ObjectManipulation
|
||||
#define ENABLE_OBJECT_MANIPULATION_DEBUG 0
|
||||
|
||||
|
||||
// Enable rendering of objects using environment map
|
||||
|
@ -39,22 +43,19 @@
|
|||
// Enable smoothing of objects normals
|
||||
#define ENABLE_SMOOTH_NORMALS 0
|
||||
|
||||
|
||||
//====================
|
||||
// 2.6.0.alpha1 techs
|
||||
//====================
|
||||
#define ENABLE_2_6_0_ALPHA1 1
|
||||
|
||||
// Enable OpenGL ES
|
||||
#define ENABLE_OPENGL_ES 0
|
||||
// Enable OpenGL core profile context (tested against Mesa 20.1.8 on Windows)
|
||||
#define ENABLE_GL_CORE_PROFILE (1 && !ENABLE_OPENGL_ES)
|
||||
// Enable OpenGL debug messages using debug context
|
||||
#define ENABLE_OPENGL_DEBUG_OPTION (1 && ENABLE_GL_CORE_PROFILE)
|
||||
// Enable editing volumes transformation in world coordinates and instances in local coordinates
|
||||
#define ENABLE_WORLD_COORDINATE (1 && ENABLE_2_6_0_ALPHA1)
|
||||
// Shows an imgui dialog containing the matrices of the selected volumes
|
||||
#define ENABLE_WORLD_COORDINATE_DEBUG (0 && ENABLE_WORLD_COORDINATE)
|
||||
|
||||
|
||||
//====================
|
||||
// 2.6.0.alpha1 techs
|
||||
//====================
|
||||
#define ENABLE_2_6_0_ALPHA1 1
|
||||
|
||||
// Enable alternative version of file_wildcards()
|
||||
#define ENABLE_ALTERNATIVE_FILE_WILDCARDS_GENERATOR (1 && ENABLE_2_6_0_ALPHA1)
|
||||
|
||||
|
|
|
@ -29,54 +29,6 @@ static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
const float Bed3D::Axes::DefaultStemRadius = 0.5f;
|
||||
const float Bed3D::Axes::DefaultStemLength = 25.0f;
|
||||
const float Bed3D::Axes::DefaultTipRadius = 2.5f * Bed3D::Axes::DefaultStemRadius;
|
||||
const float Bed3D::Axes::DefaultTipLength = 5.0f;
|
||||
|
||||
void Bed3D::Axes::render()
|
||||
{
|
||||
auto render_axis = [this](GLShaderProgram* shader, const Transform3d& transform) {
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
shader->set_uniform("view_model_matrix", view_matrix * transform);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * transform.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", view_normal_matrix);
|
||||
m_arrow.render();
|
||||
};
|
||||
|
||||
if (!m_arrow.is_initialized())
|
||||
m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length));
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
|
||||
// x axis
|
||||
m_arrow.set_color(ColorRGBA::X());
|
||||
render_axis(shader, Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }));
|
||||
|
||||
// y axis
|
||||
m_arrow.set_color(ColorRGBA::Y());
|
||||
render_axis(shader, Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }));
|
||||
|
||||
// z axis
|
||||
m_arrow.set_color(ColorRGBA::Z());
|
||||
render_axis(shader, Geometry::assemble_transform(m_origin));
|
||||
|
||||
shader->stop_using();
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
}
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom)
|
||||
{
|
||||
auto check_texture = [](const std::string& texture) {
|
||||
|
@ -201,11 +153,7 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box() const
|
|||
out.merge(m_axes.get_origin());
|
||||
// extend to contain axes
|
||||
out.merge(m_axes.get_origin() + m_axes.get_total_length() * Vec3d::Ones());
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
out.merge(out.min + Vec3d(-m_axes.get_tip_radius(), -m_axes.get_tip_radius(), out.max.z()));
|
||||
#else
|
||||
out.merge(out.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, out.max.z()));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
// extend to contain model, if any
|
||||
BoundingBoxf3 model_bb = m_model.model.get_bounding_box();
|
||||
if (model_bb.defined) {
|
||||
|
@ -364,11 +312,7 @@ std::tuple<Bed3D::Type, std::string, std::string> Bed3D::detect_type(const Point
|
|||
void Bed3D::render_axes()
|
||||
{
|
||||
if (m_build_volume.valid())
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_axes.render(Transform3d::Identity(), 0.25f);
|
||||
#else
|
||||
m_axes.render();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture)
|
||||
|
|
|
@ -3,11 +3,7 @@
|
|||
|
||||
#include "GLTexture.hpp"
|
||||
#include "3DScene.hpp"
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#include "CoordAxes.hpp"
|
||||
#else
|
||||
#include "GLModel.hpp"
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
#include "MeshUtils.hpp"
|
||||
|
||||
#include "libslic3r/BuildVolume.hpp"
|
||||
|
@ -23,32 +19,6 @@ class GLCanvas3D;
|
|||
|
||||
class Bed3D
|
||||
{
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
class Axes
|
||||
{
|
||||
public:
|
||||
static const float DefaultStemRadius;
|
||||
static const float DefaultStemLength;
|
||||
static const float DefaultTipRadius;
|
||||
static const float DefaultTipLength;
|
||||
|
||||
private:
|
||||
Vec3d m_origin{ Vec3d::Zero() };
|
||||
float m_stem_length{ DefaultStemLength };
|
||||
GLModel m_arrow;
|
||||
|
||||
public:
|
||||
const Vec3d& get_origin() const { return m_origin; }
|
||||
void set_origin(const Vec3d& origin) { m_origin = origin; }
|
||||
void set_stem_length(float length) {
|
||||
m_stem_length = length;
|
||||
m_arrow.reset();
|
||||
}
|
||||
float get_total_length() const { return m_stem_length + DefaultTipLength; }
|
||||
void render();
|
||||
};
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
public:
|
||||
enum class Type : unsigned char
|
||||
{
|
||||
|
@ -77,11 +47,7 @@ private:
|
|||
GLTexture m_temp_texture;
|
||||
PickingModel m_model;
|
||||
Vec3d m_model_offset{ Vec3d::Zero() };
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
CoordAxes m_axes;
|
||||
#else
|
||||
Axes m_axes;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
float m_scale_factor{ 1.0f };
|
||||
|
||||
|
|
|
@ -494,7 +494,7 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
|||
height = 0.1f;
|
||||
|
||||
static const float brim_height = 0.2f;
|
||||
const float scaled_brim_height = brim_height / height;
|
||||
// const float scaled_brim_height = brim_height / height;
|
||||
|
||||
TriangleMesh mesh;
|
||||
ColorRGBA color = ColorRGBA::DARK_YELLOW();
|
||||
|
|
|
@ -212,23 +212,15 @@ public:
|
|||
|
||||
const Geometry::Transformation& get_instance_transformation() const { return m_instance_transformation; }
|
||||
void set_instance_transformation(const Geometry::Transformation& transformation) { m_instance_transformation = transformation; set_bounding_boxes_as_dirty(); }
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void set_instance_transformation(const Transform3d& transform) { m_instance_transformation.set_matrix(transform); set_bounding_boxes_as_dirty(); }
|
||||
|
||||
Vec3d get_instance_offset() const { return m_instance_transformation.get_offset(); }
|
||||
#else
|
||||
const Vec3d& get_instance_offset() const { return m_instance_transformation.get_offset(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_instance_offset(Axis axis) const { return m_instance_transformation.get_offset(axis); }
|
||||
|
||||
void set_instance_offset(const Vec3d& offset) { m_instance_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); }
|
||||
void set_instance_offset(Axis axis, double offset) { m_instance_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_instance_rotation() const { return m_instance_transformation.get_rotation(); }
|
||||
#else
|
||||
const Vec3d& get_instance_rotation() const { return m_instance_transformation.get_rotation(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_instance_rotation(Axis axis) const { return m_instance_transformation.get_rotation(axis); }
|
||||
|
||||
void set_instance_rotation(const Vec3d& rotation) { m_instance_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); }
|
||||
|
@ -240,11 +232,7 @@ public:
|
|||
void set_instance_scaling_factor(const Vec3d& scaling_factor) { m_instance_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); }
|
||||
void set_instance_scaling_factor(Axis axis, double scaling_factor) { m_instance_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_instance_mirror() const { return m_instance_transformation.get_mirror(); }
|
||||
#else
|
||||
const Vec3d& get_instance_mirror() const { return m_instance_transformation.get_mirror(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_instance_mirror(Axis axis) const { return m_instance_transformation.get_mirror(axis); }
|
||||
|
||||
void set_instance_mirror(const Vec3d& mirror) { m_instance_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); }
|
||||
|
@ -252,43 +240,27 @@ public:
|
|||
|
||||
const Geometry::Transformation& get_volume_transformation() const { return m_volume_transformation; }
|
||||
void set_volume_transformation(const Geometry::Transformation& transformation) { m_volume_transformation = transformation; set_bounding_boxes_as_dirty(); }
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void set_volume_transformation(const Transform3d& transform) { m_volume_transformation.set_matrix(transform); set_bounding_boxes_as_dirty(); }
|
||||
|
||||
Vec3d get_volume_offset() const { return m_volume_transformation.get_offset(); }
|
||||
#else
|
||||
const Vec3d& get_volume_offset() const { return m_volume_transformation.get_offset(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_volume_offset(Axis axis) const { return m_volume_transformation.get_offset(axis); }
|
||||
|
||||
void set_volume_offset(const Vec3d& offset) { m_volume_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); }
|
||||
void set_volume_offset(Axis axis, double offset) { m_volume_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_volume_rotation() const { return m_volume_transformation.get_rotation(); }
|
||||
#else
|
||||
const Vec3d& get_volume_rotation() const { return m_volume_transformation.get_rotation(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_volume_rotation(Axis axis) const { return m_volume_transformation.get_rotation(axis); }
|
||||
|
||||
void set_volume_rotation(const Vec3d& rotation) { m_volume_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); }
|
||||
void set_volume_rotation(Axis axis, double rotation) { m_volume_transformation.set_rotation(axis, rotation); set_bounding_boxes_as_dirty(); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_volume_scaling_factor() const { return m_volume_transformation.get_scaling_factor(); }
|
||||
#else
|
||||
const Vec3d& get_volume_scaling_factor() const { return m_volume_transformation.get_scaling_factor(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_volume_scaling_factor(Axis axis) const { return m_volume_transformation.get_scaling_factor(axis); }
|
||||
|
||||
void set_volume_scaling_factor(const Vec3d& scaling_factor) { m_volume_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); }
|
||||
void set_volume_scaling_factor(Axis axis, double scaling_factor) { m_volume_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d get_volume_mirror() const { return m_volume_transformation.get_mirror(); }
|
||||
#else
|
||||
const Vec3d& get_volume_mirror() const { return m_volume_transformation.get_mirror(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double get_volume_mirror(Axis axis) const { return m_volume_transformation.get_mirror(axis); }
|
||||
|
||||
void set_volume_mirror(const Vec3d& mirror) { m_volume_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); }
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
|
@ -63,5 +61,3 @@ void CoordAxes::render(const Transform3d& trafo, float emission_factor)
|
|||
|
||||
} // GUI
|
||||
} // Slic3r
|
||||
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef slic3r_CoordAxes_hpp_
|
||||
#define slic3r_CoordAxes_hpp_
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#include "GLModel.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
@ -55,6 +54,4 @@ public:
|
|||
} // GUI
|
||||
} // Slic3r
|
||||
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#endif // slic3r_CoordAxes_hpp_
|
||||
|
|
|
@ -954,9 +954,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent);
|
|||
wxDEFINE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
||||
|
@ -1643,6 +1641,9 @@ void GLCanvas3D::render()
|
|||
#if ENABLE_GLMODEL_STATISTICS
|
||||
GLModel::render_statistics();
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
#if ENABLE_OBJECT_MANIPULATION_DEBUG
|
||||
wxGetApp().obj_manipul()->render_debug_window();
|
||||
#endif // ENABLE_OBJECT_MANIPULATION_DEBUG
|
||||
|
||||
std::string tooltip;
|
||||
|
||||
|
@ -1813,7 +1814,6 @@ std::vector<int> GLCanvas3D::load_object(const Model& model, int obj_idx)
|
|||
|
||||
void GLCanvas3D::mirror_selection(Axis axis)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType transformation_type;
|
||||
if (wxGetApp().obj_manipul()->is_local_coordinates())
|
||||
transformation_type.set_local();
|
||||
|
@ -1824,9 +1824,7 @@ void GLCanvas3D::mirror_selection(Axis axis)
|
|||
|
||||
m_selection.setup_cache();
|
||||
m_selection.mirror(axis, transformation_type);
|
||||
#else
|
||||
m_selection.mirror(axis);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
do_mirror(L("Mirror Object"));
|
||||
wxGetApp().obj_manipul()->set_dirty();
|
||||
}
|
||||
|
@ -2620,13 +2618,9 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
else
|
||||
displacement = multiplier * direction;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType trafo_type;
|
||||
trafo_type.set_relative();
|
||||
m_selection.translate(displacement, trafo_type);
|
||||
#else
|
||||
m_selection.translate(displacement);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_dirty = true;
|
||||
}
|
||||
);
|
||||
|
@ -3233,14 +3227,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_moving = true;
|
||||
TransformationType trafo_type;
|
||||
trafo_type.set_relative();
|
||||
m_selection.translate(cur_pos - m_mouse.drag.start_position_3D, trafo_type);
|
||||
#else
|
||||
m_selection.translate(cur_pos - m_mouse.drag.start_position_3D);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects)
|
||||
update_sequential_clearance();
|
||||
wxGetApp().obj_manipul()->set_dirty();
|
||||
|
@ -3505,17 +3495,9 @@ 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_WORLD_COORDINATE
|
||||
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_WORLD_COORDINATE
|
||||
else if (volume_idx >= 0 && selection_mode == Selection::Volume)
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
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_WORLD_COORDINATE
|
||||
|
||||
object_moved = true;
|
||||
model_object->invalidate_bounding_box();
|
||||
|
@ -3586,13 +3568,9 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
|||
for (const GLVolume* v : m_volumes.volumes) {
|
||||
if (v->is_wipe_tower) {
|
||||
const Vec3d offset = v->get_volume_offset();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d rot_unit_x = v->get_volume_transformation().get_matrix().linear() * Vec3d::UnitX();
|
||||
double z_rot = std::atan2(rot_unit_x.y(), rot_unit_x.x());
|
||||
post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), z_rot)));
|
||||
#else
|
||||
post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), v->get_volume_rotation().z())));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
const int object_idx = v->object_idx();
|
||||
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
|
||||
|
@ -3606,22 +3584,10 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
|||
// Rotate instances/volumes.
|
||||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr) {
|
||||
if (selection_mode == Selection::Instance) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (selection_mode == Selection::Instance)
|
||||
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_WORLD_COORDINATE
|
||||
}
|
||||
else if (selection_mode == Selection::Volume) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
else if (selection_mode == Selection::Volume)
|
||||
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_WORLD_COORDINATE
|
||||
}
|
||||
model_object->invalidate_bounding_box();
|
||||
}
|
||||
}
|
||||
|
@ -3682,23 +3648,11 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
|
|||
// Rotate instances/volumes
|
||||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr) {
|
||||
if (selection_mode == Selection::Instance) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (selection_mode == Selection::Instance)
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
#else
|
||||
model_object->instances[instance_idx]->set_scaling_factor(v->get_instance_scaling_factor());
|
||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
else if (selection_mode == Selection::Volume && volume_idx >= 0) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||
#else
|
||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||
model_object->volumes[volume_idx]->set_scaling_factor(v->get_volume_scaling_factor());
|
||||
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
model_object->invalidate_bounding_box();
|
||||
}
|
||||
|
@ -3760,18 +3714,9 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type)
|
|||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr) {
|
||||
if (selection_mode == Selection::Instance)
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
#else
|
||||
model_object->instances[instance_idx]->set_mirror(v->get_instance_mirror());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
else if (selection_mode == Selection::Volume)
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||
#else
|
||||
model_object->volumes[volume_idx]->set_mirror(v->get_volume_mirror());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
model_object->invalidate_bounding_box();
|
||||
}
|
||||
}
|
||||
|
@ -3794,7 +3739,6 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type)
|
|||
m_dirty = true;
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void GLCanvas3D::do_reset_skew(const std::string& snapshot_type)
|
||||
{
|
||||
if (m_model == nullptr)
|
||||
|
@ -3856,7 +3800,6 @@ void GLCanvas3D::do_reset_skew(const std::string& snapshot_type)
|
|||
|
||||
m_dirty = true;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void GLCanvas3D::update_gizmos_on_off_state()
|
||||
{
|
||||
|
@ -4035,7 +3978,6 @@ void GLCanvas3D::update_sequential_clearance()
|
|||
for (size_t i = 0; i < m_model->objects.size(); ++i) {
|
||||
ModelObject* model_object = m_model->objects[i];
|
||||
ModelInstance* model_instance0 = model_object->instances.front();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Geometry::Transformation trafo = model_instance0->get_transformation();
|
||||
trafo.set_offset({ 0.0, 0.0, model_instance0->get_offset().z() });
|
||||
const Polygon hull_2d = offset(model_object->convex_hull_2d(trafo.get_matrix()),
|
||||
|
@ -4043,14 +3985,6 @@ void GLCanvas3D::update_sequential_clearance()
|
|||
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
|
||||
shrink_factor,
|
||||
jtRound, mitter_limit).front();
|
||||
#else
|
||||
Polygon hull_2d = offset(model_object->convex_hull_2d(Geometry::assemble_transform({ 0.0, 0.0, model_instance0->get_offset().z() }, model_instance0->get_rotation(),
|
||||
model_instance0->get_scaling_factor(), model_instance0->get_mirror())),
|
||||
// Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects
|
||||
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
|
||||
shrink_factor,
|
||||
jtRound, mitter_limit).front();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
Pointf3s& cache_hull_2d = m_sequential_print_clearance.m_hull_2d_cache.emplace_back(Pointf3s());
|
||||
cache_hull_2d.reserve(hull_2d.points.size());
|
||||
|
@ -5637,9 +5571,9 @@ void GLCanvas3D::_render_selection()
|
|||
if (!m_gizmos.is_running())
|
||||
m_selection.render(scale_factor);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_DEBUG
|
||||
#if ENABLE_MATRICES_DEBUG
|
||||
m_selection.render_debug_window();
|
||||
#endif // ENABLE_WORLD_COORDINATE_DEBUG
|
||||
#endif // ENABLE_MATRICES_DEBUG
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_sequential_clearance()
|
||||
|
@ -6055,18 +5989,11 @@ void GLCanvas3D::_render_sla_slices()
|
|||
|
||||
for (const SLAPrintObject::Instance& inst : obj->instances()) {
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Transform3d view_model_matrix = camera.get_view_matrix() *
|
||||
Geometry::translation_transform({ unscale<double>(inst.shift.x()), unscale<double>(inst.shift.y()), 0.0 }) *
|
||||
Geometry::rotation_transform(inst.rotation * Vec3d::UnitZ());
|
||||
if (obj->is_left_handed())
|
||||
view_model_matrix = view_model_matrix * Geometry::scale_transform({ -1.0f, 1.0f, 1.0f });
|
||||
#else
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() *
|
||||
Geometry::assemble_transform(Vec3d(unscale<double>(inst.shift.x()), unscale<double>(inst.shift.y()), 0.0),
|
||||
inst.rotation * Vec3d::UnitZ(), Vec3d::Ones(),
|
||||
obj->is_left_handed() ? /* The polygons are mirrored by X */ Vec3d(-1.0f, 1.0f, 1.0f) : Vec3d::Ones());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
@ -7217,11 +7144,10 @@ const ModelVolume *get_model_volume(const GLVolume &v, const Model &model)
|
|||
{
|
||||
const ModelVolume * ret = nullptr;
|
||||
|
||||
if (v.object_idx() < model.objects.size()) {
|
||||
if (v.object_idx() < (int)model.objects.size()) {
|
||||
const ModelObject *obj = model.objects[v.object_idx()];
|
||||
if (v.volume_idx() < obj->volumes.size()) {
|
||||
if (v.volume_idx() < (int)obj->volumes.size())
|
||||
ret = obj->volumes[v.volume_idx()];
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -157,9 +157,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
|
|||
wxDECLARE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
|
||||
|
@ -772,11 +770,7 @@ public:
|
|||
|
||||
void update_volumes_colors_by_extruder();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
bool is_dragging() const { return m_gizmos.is_dragging() || (m_moving && !m_mouse.scene_position.isApprox(m_mouse.drag.start_position_3D)); }
|
||||
#else
|
||||
bool is_dragging() const { return m_gizmos.is_dragging() || m_moving; }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void render();
|
||||
// printable_only == false -> render also non printable volumes as grayed
|
||||
|
@ -846,9 +840,7 @@ public:
|
|||
void do_rotate(const std::string& snapshot_type);
|
||||
void do_scale(const std::string& snapshot_type);
|
||||
void do_mirror(const std::string& snapshot_type);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void do_reset_skew(const std::string& snapshot_type);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void update_gizmos_on_off_state();
|
||||
void reset_all_gizmos() { m_gizmos.reset_all_states(); }
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
enum class ECoordinatesType : unsigned char
|
||||
{
|
||||
World,
|
||||
|
@ -73,8 +72,6 @@ private:
|
|||
Enum m_value;
|
||||
};
|
||||
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
} // namespace Slic3r
|
||||
} // namespace GUI
|
||||
|
||||
|
|
|
@ -1603,11 +1603,7 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo
|
|||
// First (any) GLVolume of the selected instance. They all share the same instance matrix.
|
||||
const GLVolume* v = selection.get_first_volume();
|
||||
const Geometry::Transformation inst_transform = v->get_instance_transformation();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d inv_inst_transform = inst_transform.get_matrix_no_offset().inverse();
|
||||
#else
|
||||
const Transform3d inv_inst_transform = inst_transform.get_matrix(true).inverse();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
const Vec3d instance_offset = v->get_instance_offset();
|
||||
|
||||
for (size_t i = 0; i < input_files.size(); ++i) {
|
||||
|
@ -1655,15 +1651,9 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo
|
|||
new_volume->source.mesh_offset = model.objects.front()->volumes.front()->source.mesh_offset;
|
||||
|
||||
if (from_galery) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
// Transform the new modifier to be aligned with the print bed.
|
||||
new_volume->set_transformation(v->get_instance_transformation().get_matrix_no_offset().inverse());
|
||||
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
|
||||
#else
|
||||
// Transform the new modifier to be aligned with the print bed.
|
||||
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
|
||||
new_volume->set_transformation(Geometry::Transformation::volume_to_bed_transformation(inst_transform, mesh_bb));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
// Set the modifier position.
|
||||
// Translate the new modifier to be pickable: move to the left front corner of the instance's bounding box, lift to print bed.
|
||||
const Vec3d offset = Vec3d(instance_bb.max.x(), instance_bb.min.y(), instance_bb.min.z()) + 0.5 * mesh_bb.size() - instance_offset;
|
||||
|
@ -1732,15 +1722,9 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
|
|||
|
||||
// First (any) GLVolume of the selected instance. They all share the same instance matrix.
|
||||
const GLVolume* v = selection.get_first_volume();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
// Transform the new modifier to be aligned with the print bed.
|
||||
new_volume->set_transformation(v->get_instance_transformation().get_matrix_no_offset().inverse());
|
||||
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
|
||||
#else
|
||||
// Transform the new modifier to be aligned with the print bed.
|
||||
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
|
||||
new_volume->set_transformation(Geometry::Transformation::volume_to_bed_transformation(v->get_instance_transformation(), mesh_bb));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
// Set the modifier position.
|
||||
Vec3d offset;
|
||||
if (type_name == "Slab") {
|
||||
|
@ -1752,11 +1736,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
|
|||
// Translate the new modifier to be pickable: move to the left front corner of the instance's bounding box, lift to print bed.
|
||||
offset = Vec3d(instance_bb.max.x(), instance_bb.min.y(), instance_bb.min.z()) + 0.5 * mesh_bb.size() - v->get_instance_offset();
|
||||
}
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
new_volume->set_offset(v->get_instance_transformation().get_matrix_no_offset().inverse() * offset);
|
||||
#else
|
||||
new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
const wxString name = _L("Generic") + "-" + _(type_name);
|
||||
new_volume->name = into_u8(name);
|
||||
|
@ -2688,6 +2668,8 @@ void ObjectList::part_selection_changed()
|
|||
bool disable_ss_manipulation {false};
|
||||
bool disable_ununiform_scale {false};
|
||||
|
||||
ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||
|
||||
const auto item = GetSelection();
|
||||
|
||||
GLGizmosManager& gizmos_mgr = wxGetApp().plater()->canvas3D()->get_gizmos_manager();
|
||||
|
@ -2704,6 +2686,7 @@ void ObjectList::part_selection_changed()
|
|||
|
||||
if (selection.is_single_full_object()) {
|
||||
og_name = _L("Object manipulation");
|
||||
coordinates_type = ECoordinatesType::World;
|
||||
update_and_show_manipulations = true;
|
||||
|
||||
obj_idx = selection.get_object_idx();
|
||||
|
@ -2713,6 +2696,7 @@ void ObjectList::part_selection_changed()
|
|||
}
|
||||
else {
|
||||
og_name = _L("Group manipulation");
|
||||
coordinates_type = ECoordinatesType::World;
|
||||
|
||||
// don't show manipulation panel for case of all Object's parts selection
|
||||
update_and_show_manipulations = !selection.is_single_full_instance();
|
||||
|
@ -2768,6 +2752,8 @@ void ObjectList::part_selection_changed()
|
|||
|| type == itInfo) {
|
||||
og_name = _L("Object manipulation");
|
||||
m_config = &object->config;
|
||||
if (!scene_selection().is_single_full_instance() || coordinates_type > ECoordinatesType::Instance)
|
||||
coordinates_type = ECoordinatesType::World;
|
||||
update_and_show_manipulations = true;
|
||||
|
||||
if (type == itInfo) {
|
||||
|
@ -2845,6 +2831,8 @@ void ObjectList::part_selection_changed()
|
|||
|
||||
if (update_and_show_manipulations) {
|
||||
wxGetApp().obj_manipul()->get_og()->set_name(" " + og_name + " ");
|
||||
if (wxGetApp().obj_manipul()->get_coordinates_type() != coordinates_type)
|
||||
wxGetApp().obj_manipul()->set_coordinates_type(coordinates_type);
|
||||
|
||||
if (item) {
|
||||
wxGetApp().obj_manipul()->update_item_name(m_objects_model->GetName(item));
|
||||
|
@ -2876,7 +2864,6 @@ void ObjectList::part_selection_changed()
|
|||
Sidebar& panel = wxGetApp().sidebar();
|
||||
panel.Freeze();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
std::string opt_key;
|
||||
if (m_selected_object_id >= 0) {
|
||||
const ManipulationEditor* const editor = wxGetApp().obj_manipul()->get_focused_editor();
|
||||
|
@ -2884,9 +2871,6 @@ void ObjectList::part_selection_changed()
|
|||
opt_key = editor->get_full_opt_name();
|
||||
}
|
||||
wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, !opt_key.empty());
|
||||
#else
|
||||
wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
wxGetApp().plater()->canvas3D()->enable_moving(enable_manipulation); // ysFIXME
|
||||
wxGetApp().obj_manipul() ->UpdateAndShow(update_and_show_manipulations);
|
||||
wxGetApp().obj_settings()->UpdateAndShow(update_and_show_settings);
|
||||
|
@ -3705,11 +3689,7 @@ void ObjectList::update_selections()
|
|||
return;
|
||||
sels.Add(m_objects_model->GetItemById(selection.get_object_idx()));
|
||||
}
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
else if (selection.is_single_volume_or_modifier()) {
|
||||
#else
|
||||
else if (selection.is_single_volume() || selection.is_any_modifier()) {
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
const auto gl_vol = selection.get_first_volume();
|
||||
if (m_objects_model->GetVolumeIdByItem(m_objects_model->GetParent(item)) == gl_vol->volume_idx())
|
||||
return;
|
||||
|
|
|
@ -52,17 +52,10 @@ static choice_ctrl* create_word_local_combo(wxWindow *parent)
|
|||
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
temp->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::World));
|
||||
temp->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Instance));
|
||||
temp->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Local));
|
||||
temp->Select((int)ECoordinatesType::World);
|
||||
#else
|
||||
temp->Append(_L("World coordinates"));
|
||||
temp->Append(_L("Local coordinates"));
|
||||
temp->SetSelection(0);
|
||||
temp->SetValue(temp->GetString(0));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
temp->SetToolTip(_L("Select coordinate space, in which the transformation will be performed."));
|
||||
return temp;
|
||||
|
@ -88,14 +81,9 @@ void msw_rescale_word_local_combo(choice_ctrl* combo)
|
|||
// Set rescaled size
|
||||
combo->SetSize(size);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
combo->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::World));
|
||||
combo->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Instance));
|
||||
combo->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Local));
|
||||
#else
|
||||
combo->Append(_L("World coordinates"));
|
||||
combo->Append(_L("Local coordinates"));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
combo->SetValue(selection);
|
||||
#else
|
||||
|
@ -125,10 +113,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
|
||||
// Load bitmaps to be used for the mirroring buttons:
|
||||
m_mirror_bitmap_on = ScalableBitmap(parent, "mirroring_on");
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
m_mirror_bitmap_off = ScalableBitmap(parent, "mirroring_off");
|
||||
m_mirror_bitmap_hidden = ScalableBitmap(parent, "mirroring_transparent");
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
const int border = wxOSX ? 0 : 4;
|
||||
const int em = wxGetApp().em_unit();
|
||||
|
@ -172,13 +156,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
|
||||
// Add world local combobox
|
||||
m_word_local_combo = create_word_local_combo(parent);
|
||||
m_word_local_combo->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent& evt) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
this->set_coordinates_type(evt.GetString());
|
||||
#else
|
||||
this->set_world_coordinates(evt.GetSelection() != 1);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}), m_word_local_combo->GetId());
|
||||
m_word_local_combo->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent& evt) { this->set_coordinates_type(evt.GetString()); }), m_word_local_combo->GetId());
|
||||
|
||||
// Small trick to correct layouting in different view_mode :
|
||||
// Show empty string of a same height as a m_word_local_combo, when m_word_local_combo is hidden
|
||||
|
@ -235,11 +213,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
|
||||
add_label(&m_scale_Label, L("Scale"), v_sizer);
|
||||
wxStaticText* size_Label {nullptr};
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
add_label(&size_Label, L("Size [World]"), v_sizer);
|
||||
#else
|
||||
add_label(&size_Label, L("Size"), v_sizer);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
if (wxOSX) set_font_and_background_style(size_Label, wxGetApp().normal_font());
|
||||
|
||||
sizer->Add(v_sizer, 0, wxLEFT, border);
|
||||
|
@ -271,32 +245,16 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
|
||||
// We will add a button to toggle mirroring to each axis:
|
||||
auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
btn->SetToolTip(_L("Mirror along") + wxString::Format(_L(" %c "), (int)label) + _L("axis"));
|
||||
|
||||
m_mirror_buttons[axis_idx] = btn;
|
||||
#else
|
||||
btn->SetToolTip(wxString::Format(_L("Toggle %c axis mirroring"), (int)label));
|
||||
btn->SetBitmapDisabled_(m_mirror_bitmap_hidden);
|
||||
|
||||
m_mirror_buttons[axis_idx].first = btn;
|
||||
m_mirror_buttons[axis_idx].second = mbShown;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
sizer->AddStretchSpacer(2);
|
||||
sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
btn->Bind(wxEVT_BUTTON, [this, axis_idx](wxCommandEvent&) {
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
Axis axis = (Axis)(axis_idx + X);
|
||||
if (m_mirror_buttons[axis_idx].second == mbHidden)
|
||||
return;
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||
Selection& selection = canvas->get_selection();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType transformation_type;
|
||||
if (is_local_coordinates())
|
||||
transformation_type.set_local();
|
||||
|
@ -307,24 +265,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
|
||||
selection.setup_cache();
|
||||
selection.mirror((Axis)axis_idx, transformation_type);
|
||||
#else
|
||||
if (selection.is_single_volume() || selection.is_single_modifier()) {
|
||||
GLVolume* volume = const_cast<GLVolume*>(selection.get_first_volume());
|
||||
volume->set_volume_mirror(axis, -volume->get_volume_mirror(axis));
|
||||
}
|
||||
else if (selection.is_single_full_instance()) {
|
||||
for (unsigned int idx : selection.get_volume_idxs()) {
|
||||
GLVolume* volume = const_cast<GLVolume*>(selection.get_volume(idx));
|
||||
volume->set_instance_mirror(axis, -volume->get_instance_mirror(axis));
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
// Update mirroring at the GLVolumes.
|
||||
selection.synchronize_unselected_instances(Selection::SyncRotationType::GENERAL);
|
||||
selection.synchronize_unselected_volumes();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
// Copy mirroring values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing.
|
||||
canvas->do_mirror(L("Set Mirror"));
|
||||
UpdateAndShow(true);
|
||||
|
@ -333,12 +274,8 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
editors_grid_sizer->Add(sizer, 0, wxALIGN_CENTER_HORIZONTAL);
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_mirror_warning_bitmap = new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap);
|
||||
editors_grid_sizer->Add(m_mirror_warning_bitmap, 0, wxALIGN_CENTER_VERTICAL);
|
||||
#else
|
||||
editors_grid_sizer->AddStretchSpacer(1);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
editors_grid_sizer->AddStretchSpacer(1);
|
||||
|
||||
// add EditBoxes
|
||||
|
@ -377,7 +314,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||
Selection& selection = canvas->get_selection();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (selection.is_single_volume_or_modifier()) {
|
||||
const GLVolume* volume = selection.get_first_volume();
|
||||
const double min_z = get_volume_min_z(*volume);
|
||||
|
@ -393,19 +329,8 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Drop to bed"));
|
||||
change_position_value(2, m_cache.position.z() - min_z);
|
||||
}
|
||||
#else
|
||||
if (selection.is_single_volume() || selection.is_single_modifier()) {
|
||||
const GLVolume* volume = selection.get_first_volume();
|
||||
const Vec3d diff = m_cache.position - volume->get_instance_transformation().get_matrix(true).inverse() * (get_volume_min_z(*volume) * Vec3d::UnitZ());
|
||||
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Drop to bed"));
|
||||
change_position_value(0, diff.x());
|
||||
change_position_value(1, diff.y());
|
||||
change_position_value(2, diff.z());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
else if (selection.is_single_full_instance()) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const double min_z = selection.get_scaled_instance_bounding_box().min.z();
|
||||
if (!is_world_coordinates()) {
|
||||
const GLVolume* volume = selection.get_first_volume();
|
||||
|
@ -417,20 +342,9 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
change_position_value(2, diff.z());
|
||||
}
|
||||
else {
|
||||
#else
|
||||
const ModelObjectPtrs& objects = wxGetApp().model().objects;
|
||||
const int idx = selection.get_object_idx();
|
||||
if (0 <= idx && idx < static_cast<int>(objects.size())) {
|
||||
const ModelObject* mo = wxGetApp().model().objects[idx];
|
||||
const double min_z = mo->bounding_box().min.z();
|
||||
if (std::abs(min_z) > SINKING_Z_THRESHOLD) {
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Drop to bed"));
|
||||
change_position_value(2, m_cache.position.z() - min_z);
|
||||
}
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Drop to bed"));
|
||||
change_position_value(2, m_cache.position.z() - min_z);
|
||||
}
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
});
|
||||
editors_grid_sizer->Add(m_drop_to_bed_button);
|
||||
|
@ -447,17 +361,12 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||
Selection& selection = canvas->get_selection();
|
||||
selection.setup_cache();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (selection.is_single_volume_or_modifier()) {
|
||||
GLVolume* vol = const_cast<GLVolume*>(selection.get_first_volume());
|
||||
Geometry::Transformation trafo = vol->get_volume_transformation();
|
||||
trafo.reset_rotation();
|
||||
vol->set_volume_transformation(trafo);
|
||||
}
|
||||
#else
|
||||
if (selection.is_single_volume() || selection.is_single_modifier())
|
||||
const_cast<GLVolume*>(selection.get_first_volume())->set_volume_rotation(Vec3d::Zero());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
else if (selection.is_single_full_instance()) {
|
||||
Geometry::Transformation trafo = selection.get_first_volume()->get_instance_transformation();
|
||||
trafo.reset_rotation();
|
||||
|
@ -489,7 +398,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
m_reset_scale_button = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo"));
|
||||
m_reset_scale_button->SetToolTip(_L("Reset scale"));
|
||||
m_reset_scale_button->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||
Selection& selection = canvas->get_selection();
|
||||
selection.setup_cache();
|
||||
|
@ -515,12 +423,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
|
||||
canvas->do_scale(L("Reset scale"));
|
||||
UpdateAndShow(true);
|
||||
#else
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Reset scale"));
|
||||
change_scale_value(0, 100.);
|
||||
change_scale_value(1, 100.);
|
||||
change_scale_value(2, 100.);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
});
|
||||
editors_grid_sizer->Add(m_reset_scale_button);
|
||||
|
||||
|
@ -531,7 +433,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
|
||||
m_main_grid_sizer->Add(editors_grid_sizer, 1, wxEXPAND);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_skew_label = new wxStaticText(parent, wxID_ANY, _L("Skew"));
|
||||
m_main_grid_sizer->Add(m_skew_label, 1, wxEXPAND);
|
||||
|
||||
|
@ -548,7 +449,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
}
|
||||
});
|
||||
m_main_grid_sizer->Add(m_reset_skew_button);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
m_check_inch = new wxCheckBox(parent, wxID_ANY, _L("Inches"));
|
||||
m_check_inch->SetFont(wxGetApp().normal_font());
|
||||
|
@ -568,9 +468,9 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
|
||||
void ObjectManipulation::Show(const bool show)
|
||||
{
|
||||
if (show != IsShown()) {
|
||||
// Show all lines of the panel. Some of these lines will be hidden in the lines below.
|
||||
m_og->Show(show);
|
||||
if (show != IsShown()) {
|
||||
// Show all lines of the panel. Some of these lines will be hidden in the lines below.
|
||||
m_og->Show(show);
|
||||
|
||||
if (show && wxGetApp().get_mode() != comSimple) {
|
||||
// Show the label and the name of the STL in simple mode only.
|
||||
|
@ -581,9 +481,10 @@ void ObjectManipulation::Show(const bool show)
|
|||
}
|
||||
}
|
||||
|
||||
if (show) {
|
||||
// Show the "World Coordinates" / "Local Coordintes" Combo in Advanced / Expert mode only.
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (show) {
|
||||
ECoordinatesType coordinates_type = m_coordinates_type;
|
||||
|
||||
// Show the "World Coordinates" / "Local Coordintes" Combo in Advanced / Expert mode only.
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
bool show_world_local_combo = wxGetApp().get_mode() != comSimple && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier());
|
||||
if (selection.is_single_volume_or_modifier() && m_word_local_combo->GetCount() < 3) {
|
||||
|
@ -592,20 +493,15 @@ void ObjectManipulation::Show(const bool show)
|
|||
#else
|
||||
m_word_local_combo->Insert(coordinate_type_str(ECoordinatesType::Local), wxNullBitmap, 2);
|
||||
#endif // __linux__
|
||||
m_word_local_combo->Select((int)ECoordinatesType::World);
|
||||
this->set_coordinates_type(m_word_local_combo->GetString(m_word_local_combo->GetSelection()));
|
||||
}
|
||||
else if (selection.is_single_full_instance() && m_word_local_combo->GetCount() > 2) {
|
||||
m_word_local_combo->Delete(2);
|
||||
m_word_local_combo->Select((int)ECoordinatesType::World);
|
||||
this->set_coordinates_type(m_word_local_combo->GetString(m_word_local_combo->GetSelection()));
|
||||
if (coordinates_type > ECoordinatesType::Instance)
|
||||
coordinates_type = ECoordinatesType::World;
|
||||
}
|
||||
#else
|
||||
bool show_world_local_combo = wxGetApp().plater()->canvas3D()->get_selection().is_single_full_instance() && wxGetApp().get_mode() != comSimple;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_word_local_combo->Show(show_world_local_combo);
|
||||
m_empty_str->Show(!show_world_local_combo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ObjectManipulation::IsShown()
|
||||
|
@ -628,10 +524,7 @@ void ObjectManipulation::Enable(const bool enadle)
|
|||
for (auto editor : m_editors)
|
||||
editor->Enable(enadle);
|
||||
for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_reset_rotation_button, m_drop_to_bed_button, m_check_inch, m_lock_bnt
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
,m_reset_skew_button
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
})
|
||||
, m_reset_skew_button })
|
||||
win->Enable(enadle);
|
||||
}
|
||||
|
||||
|
@ -639,11 +532,7 @@ void ObjectManipulation::DisableScale()
|
|||
{
|
||||
for (auto editor : m_editors)
|
||||
editor->Enable(editor->has_opt_key("scale") || editor->has_opt_key("size") ? false : true);
|
||||
for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_lock_bnt
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
,m_reset_skew_button
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
})
|
||||
for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_lock_bnt, m_reset_skew_button })
|
||||
win->Enable(false);
|
||||
}
|
||||
|
||||
|
@ -717,52 +606,24 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
|||
m_new_rotate_label_string = L("Rotation");
|
||||
m_new_scale_label_string = L("Scale factors");
|
||||
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
if (wxGetApp().get_mode() == comSimple)
|
||||
m_world_coordinates = true;
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
ObjectList* obj_list = wxGetApp().obj_list();
|
||||
if (selection.is_single_full_instance()) {
|
||||
// all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one
|
||||
const GLVolume* volume = selection.get_first_volume();
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
m_new_position = volume->get_instance_offset();
|
||||
|
||||
// Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible.
|
||||
if (m_world_coordinates && ! m_uniform_scale &&
|
||||
! Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) {
|
||||
// Manipulating an instance in the world coordinate system, rotation is not multiples of ninety degrees, therefore enforce uniform scaling.
|
||||
m_uniform_scale = true;
|
||||
m_lock_bnt->SetLock(true);
|
||||
}
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (is_world_coordinates()) {
|
||||
m_new_position = volume->get_instance_offset();
|
||||
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
|
||||
m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0;
|
||||
m_new_rotate_label_string = L("Rotate (relative)");
|
||||
#else
|
||||
if (m_world_coordinates) {
|
||||
m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0;
|
||||
m_new_size = selection.get_scaled_instance_bounding_box().size();
|
||||
m_new_rotate_label_string = L("Rotate");
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
}
|
||||
else {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
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_size = selection.get_bounding_box_in_current_reference_system().first.size();
|
||||
#else
|
||||
m_new_rotation = volume->get_instance_rotation() * (180.0 / M_PI);
|
||||
m_new_size = volume->get_instance_scaling_factor().cwiseProduct(wxGetApp().model().objects[volume->object_idx()]->raw_mesh_bounding_box().size());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_new_scale = m_new_size.cwiseQuotient(selection.get_full_unscaled_instance_local_bounding_box().size()) * 100.0;
|
||||
}
|
||||
|
||||
|
@ -773,23 +634,14 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
|||
m_new_position = box.center();
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
m_new_scale = Vec3d(100.0, 100.0, 100.0);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
|
||||
#else
|
||||
m_new_size = box.size();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_new_rotate_label_string = L("Rotate");
|
||||
m_new_scale_label_string = L("Scale");
|
||||
m_new_enabled = true;
|
||||
}
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
else if (selection.is_single_volume_or_modifier()) {
|
||||
#else
|
||||
else if (selection.is_single_modifier() || selection.is_single_volume()) {
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
// the selection contains a single volume
|
||||
const GLVolume* volume = selection.get_first_volume();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (is_world_coordinates()) {
|
||||
const Geometry::Transformation trafo(volume->world_matrix());
|
||||
|
||||
|
@ -811,23 +663,13 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
|||
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
|
||||
}
|
||||
else {
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_new_position = volume->get_volume_offset();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_new_rotate_label_string = L("Rotate (relative)");
|
||||
#else
|
||||
m_new_rotate_label_string = L("Rotate");
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
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();
|
||||
}
|
||||
#else
|
||||
m_new_scale = volume->get_volume_scaling_factor() * 100.0;
|
||||
m_new_size = volume->get_instance_scaling_factor().cwiseProduct(volume->get_volume_scaling_factor().cwiseProduct(volume->bounding_box().size()));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_new_enabled = true;
|
||||
}
|
||||
else if (obj_list->is_connectors_item_selected() || obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) {
|
||||
|
@ -835,11 +677,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
|||
m_new_move_label_string = L("Translate");
|
||||
m_new_rotate_label_string = L("Rotate");
|
||||
m_new_scale_label_string = L("Scale");
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
|
||||
#else
|
||||
m_new_size = selection.get_bounding_box().size();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_new_enabled = true;
|
||||
}
|
||||
}
|
||||
|
@ -900,29 +738,9 @@ void ObjectManipulation::update_if_dirty()
|
|||
update(m_cache.rotation, m_cache.rotation_rounded, meRotation, m_new_rotation);
|
||||
}
|
||||
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
if (selection.requires_uniform_scale()) {
|
||||
m_lock_bnt->SetLock(true);
|
||||
m_lock_bnt->SetToolTip(_L("You cannot use non-uniform scaling mode for multiple objects/parts selection"));
|
||||
m_lock_bnt->disable();
|
||||
}
|
||||
else {
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
m_lock_bnt->SetLock(m_uniform_scale);
|
||||
m_lock_bnt->SetToolTip(wxEmptyString);
|
||||
m_lock_bnt->enable();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (m_word_local_combo->GetSelection() != (int)m_coordinates_type)
|
||||
m_word_local_combo->SetSelection((int)m_coordinates_type);
|
||||
#else
|
||||
}
|
||||
|
||||
{
|
||||
int new_selection = m_world_coordinates ? 0 : 1;
|
||||
if (m_word_local_combo->GetSelection() != new_selection)
|
||||
m_word_local_combo->SetSelection(new_selection);
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_lock_bnt->SetLock(m_uniform_scale);
|
||||
m_lock_bnt->SetToolTip(wxEmptyString);
|
||||
m_lock_bnt->enable();
|
||||
|
||||
if (m_new_enabled)
|
||||
m_og->enable();
|
||||
|
@ -937,9 +755,6 @@ void ObjectManipulation::update_if_dirty()
|
|||
m_dirty = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void ObjectManipulation::update_reset_buttons_visibility()
|
||||
{
|
||||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||
|
@ -991,109 +806,13 @@ void ObjectManipulation::update_reset_buttons_visibility()
|
|||
}
|
||||
});
|
||||
}
|
||||
#else
|
||||
void ObjectManipulation::update_reset_buttons_visibility()
|
||||
{
|
||||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||
if (!canvas)
|
||||
return;
|
||||
const Selection& selection = canvas->get_selection();
|
||||
|
||||
bool show_rotation = false;
|
||||
bool show_scale = false;
|
||||
bool show_drop_to_bed = false;
|
||||
if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) {
|
||||
const GLVolume* volume = selection.get_first_volume();
|
||||
Vec3d rotation;
|
||||
Vec3d scale;
|
||||
double min_z = 0.0;
|
||||
|
||||
if (selection.is_single_full_instance()) {
|
||||
rotation = volume->get_instance_rotation();
|
||||
scale = volume->get_instance_scaling_factor();
|
||||
min_z = selection.get_scaled_instance_bounding_box().min.z();
|
||||
}
|
||||
else {
|
||||
rotation = volume->get_volume_rotation();
|
||||
scale = volume->get_volume_scaling_factor();
|
||||
min_z = get_volume_min_z(*volume);
|
||||
}
|
||||
show_rotation = !rotation.isApprox(Vec3d::Zero());
|
||||
show_scale = !scale.isApprox(Vec3d::Ones());
|
||||
show_drop_to_bed = std::abs(min_z) > SINKING_Z_THRESHOLD;
|
||||
}
|
||||
|
||||
wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed] {
|
||||
// There is a case (under OSX), when this function is called after the Manipulation panel is hidden
|
||||
// So, let check if Manipulation panel is still shown for this moment
|
||||
if (!this->IsShown())
|
||||
return;
|
||||
m_reset_rotation_button->Show(show_rotation);
|
||||
m_reset_scale_button->Show(show_scale);
|
||||
m_drop_to_bed_button->Show(show_drop_to_bed);
|
||||
|
||||
// Because of CallAfter we need to layout sidebar after Show/hide of reset buttons one more time
|
||||
Sidebar& panel = wxGetApp().sidebar();
|
||||
if (!panel.IsFrozen()) {
|
||||
panel.Freeze();
|
||||
panel.Layout();
|
||||
panel.Thaw();
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
|
||||
|
||||
void ObjectManipulation::update_mirror_buttons_visibility()
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const bool can_mirror = wxGetApp().plater()->can_mirror();
|
||||
for (ScalableButton* button : m_mirror_buttons) {
|
||||
button->Enable(can_mirror);
|
||||
}
|
||||
#else
|
||||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||
Selection& selection = canvas->get_selection();
|
||||
|
||||
std::array<MirrorButtonState, 3> new_states = { mbHidden, mbHidden, mbHidden };
|
||||
|
||||
if (!m_world_coordinates) {
|
||||
if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) {
|
||||
const GLVolume* volume = selection.get_first_volume();
|
||||
Vec3d mirror;
|
||||
|
||||
if (selection.is_single_full_instance())
|
||||
mirror = volume->get_instance_mirror();
|
||||
else
|
||||
mirror = volume->get_volume_mirror();
|
||||
|
||||
for (unsigned char i=0; i<3; ++i)
|
||||
new_states[i] = (mirror[i] < 0. ? mbActive : mbShown);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// the mirroring buttons should be hidden in world coordinates,
|
||||
// unless we make it actually mirror in world coords.
|
||||
}
|
||||
|
||||
// Hiding the buttons through Hide() always messed up the sizers. As a workaround, the button
|
||||
// is assigned a transparent bitmap. We must of course remember the actual state.
|
||||
wxGetApp().CallAfter([this, new_states]{
|
||||
for (int i=0; i<3; ++i) {
|
||||
if (new_states[i] != m_mirror_buttons[i].second) {
|
||||
const ScalableBitmap* bmp = nullptr;
|
||||
switch (new_states[i]) {
|
||||
case mbHidden : bmp = &m_mirror_bitmap_hidden; m_mirror_buttons[i].first->Enable(false); break;
|
||||
case mbShown : bmp = &m_mirror_bitmap_off; m_mirror_buttons[i].first->Enable(true); break;
|
||||
case mbActive : bmp = &m_mirror_bitmap_on; m_mirror_buttons[i].first->Enable(true); break;
|
||||
}
|
||||
m_mirror_buttons[i].first->SetBitmap_(*bmp);
|
||||
m_mirror_buttons[i].second = new_states[i];
|
||||
}
|
||||
}
|
||||
});
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
|
||||
|
@ -1125,7 +844,6 @@ void ObjectManipulation::update_warning_icon_state(const MeshErrorsInfo& warning
|
|||
m_fix_throught_netfab_bitmap->SetToolTip(tooltip);
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
wxString ObjectManipulation::coordinate_type_str(ECoordinatesType type)
|
||||
{
|
||||
switch (type)
|
||||
|
@ -1136,7 +854,19 @@ wxString ObjectManipulation::coordinate_type_str(ECoordinatesType type)
|
|||
default: { assert(false); return _L("Unknown"); }
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_OBJECT_MANIPULATION_DEBUG
|
||||
void ObjectManipulation::render_debug_window()
|
||||
{
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
// ImGui::SetNextWindowCollapsed(true, ImGuiCond_Once);
|
||||
imgui.begin(std::string("ObjectManipulation"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize);
|
||||
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "Coordinates type");
|
||||
ImGui::SameLine();
|
||||
imgui.text(coordinate_type_str(m_coordinates_type));
|
||||
imgui.end();
|
||||
}
|
||||
#endif // ENABLE_OBJECT_MANIPULATION_DEBUG
|
||||
|
||||
void ObjectManipulation::reset_settings_value()
|
||||
{
|
||||
|
@ -1161,7 +891,6 @@ void ObjectManipulation::change_position_value(int axis, double value)
|
|||
auto canvas = wxGetApp().plater()->canvas3D();
|
||||
Selection& selection = canvas->get_selection();
|
||||
selection.setup_cache();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType trafo_type;
|
||||
trafo_type.set_relative();
|
||||
switch (get_coordinates_type())
|
||||
|
@ -1171,9 +900,6 @@ void ObjectManipulation::change_position_value(int axis, double value)
|
|||
default: { break; }
|
||||
}
|
||||
selection.translate(position - m_cache.position, trafo_type);
|
||||
#else
|
||||
selection.translate(position - m_cache.position, selection.requires_local_axes());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
canvas->do_move(L("Set Position"));
|
||||
|
||||
m_cache.position = position;
|
||||
|
@ -1192,7 +918,6 @@ void ObjectManipulation::change_rotation_value(int axis, double value)
|
|||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||
Selection& selection = canvas->get_selection();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType transformation_type;
|
||||
transformation_type.set_relative();
|
||||
if (selection.is_single_full_instance())
|
||||
|
@ -1203,16 +928,6 @@ void ObjectManipulation::change_rotation_value(int axis, double value)
|
|||
|
||||
if (is_instance_coordinates())
|
||||
transformation_type.set_instance();
|
||||
#else
|
||||
TransformationType transformation_type(TransformationType::World_Relative_Joint);
|
||||
if (selection.is_single_full_instance() || selection.requires_local_axes())
|
||||
transformation_type.set_independent();
|
||||
if (selection.is_single_full_instance() && ! m_world_coordinates) {
|
||||
//FIXME Selection::rotate() does not process absoulte rotations correctly: It does not recognize the axis index, which was changed.
|
||||
// transformation_type.set_absolute();
|
||||
transformation_type.set_local();
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
selection.setup_cache();
|
||||
selection.rotate(
|
||||
|
@ -1236,7 +951,6 @@ void ObjectManipulation::change_scale_value(int axis, double value)
|
|||
Vec3d scale = m_cache.scale;
|
||||
scale(axis) = value;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
Vec3d ref_scale = m_cache.scale;
|
||||
if (selection.is_single_volume_or_modifier()) {
|
||||
|
@ -1247,9 +961,6 @@ void ObjectManipulation::change_scale_value(int axis, double value)
|
|||
ref_scale = 100.0 * Vec3d::Ones();
|
||||
|
||||
this->do_scale(axis, scale.cwiseQuotient(ref_scale));
|
||||
#else
|
||||
this->do_scale(axis, 0.01 * scale);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
m_cache.scale = scale;
|
||||
m_cache.scale_rounded(axis) = DBL_MAX;
|
||||
|
@ -1278,39 +989,18 @@ void ObjectManipulation::change_size_value(int axis, double value)
|
|||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
|
||||
Vec3d ref_size = m_cache.size;
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (selection.is_single_volume_or_modifier()) {
|
||||
size = size.cwiseQuotient(ref_size);
|
||||
ref_size = Vec3d::Ones();
|
||||
#else
|
||||
if (selection.is_single_volume() || selection.is_single_modifier()) {
|
||||
const GLVolume* v = selection.get_first_volume();
|
||||
const Vec3d local_size = size.cwiseQuotient(v->get_instance_scaling_factor());
|
||||
const Vec3d local_ref_size = v->bounding_box().size().cwiseProduct(v->get_volume_scaling_factor());
|
||||
const Vec3d local_change = local_size.cwiseQuotient(local_ref_size);
|
||||
|
||||
size = local_change.cwiseProduct(v->get_volume_scaling_factor());
|
||||
ref_size = Vec3d::Ones();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
else if (selection.is_single_full_instance()) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (is_world_coordinates())
|
||||
ref_size = selection.get_full_unscaled_instance_bounding_box().size();
|
||||
else
|
||||
ref_size = selection.get_full_unscaled_instance_local_bounding_box().size();
|
||||
#else
|
||||
ref_size = m_world_coordinates ?
|
||||
selection.get_unscaled_instance_bounding_box().size() :
|
||||
wxGetApp().model().objects[selection.get_first_volume()->object_idx()]->raw_mesh_bounding_box().size();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
this->do_size(axis, size.cwiseQuotient(ref_size));
|
||||
#else
|
||||
this->do_scale(axis, size.cwiseQuotient(ref_size));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
m_cache.size = size;
|
||||
m_cache.size_rounded(axis) = DBL_MAX;
|
||||
|
@ -1319,40 +1009,22 @@ void ObjectManipulation::change_size_value(int axis, double value)
|
|||
|
||||
void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
|
||||
{
|
||||
Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
Vec3d scaling_factor = scale;
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType transformation_type;
|
||||
if (is_local_coordinates())
|
||||
transformation_type.set_local();
|
||||
else if (is_instance_coordinates())
|
||||
transformation_type.set_instance();
|
||||
|
||||
Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
if (selection.is_single_volume_or_modifier() && !is_local_coordinates())
|
||||
transformation_type.set_relative();
|
||||
|
||||
const Vec3d scaling_factor = m_uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
|
||||
#else
|
||||
TransformationType transformation_type(TransformationType::World_Relative_Joint);
|
||||
if (selection.is_single_full_instance()) {
|
||||
transformation_type.set_absolute();
|
||||
if (! m_world_coordinates)
|
||||
transformation_type.set_local();
|
||||
}
|
||||
|
||||
if (m_uniform_scale || selection.requires_uniform_scale())
|
||||
scaling_factor = scale(axis) * Vec3d::Ones();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
selection.setup_cache();
|
||||
selection.scale(scaling_factor, transformation_type);
|
||||
wxGetApp().plater()->canvas3D()->do_scale(L("Set Scale"));
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void ObjectManipulation::do_size(int axis, const Vec3d& scale) const
|
||||
{
|
||||
Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
|
@ -1368,7 +1040,6 @@ void ObjectManipulation::do_size(int axis, const Vec3d& scale) const
|
|||
selection.scale(scaling_factor, transformation_type);
|
||||
wxGetApp().plater()->canvas3D()->do_scale(L("Set Size"));
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void ObjectManipulation::on_change(const std::string& opt_key, int axis, double new_value)
|
||||
{
|
||||
|
@ -1407,51 +1078,14 @@ void ObjectManipulation::on_change(const std::string& opt_key, int axis, double
|
|||
|
||||
void ObjectManipulation::set_uniform_scaling(const bool use_uniform_scale)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (!use_uniform_scale)
|
||||
// Recalculate cached values at this panel, refresh the screen.
|
||||
this->UpdateAndShow(true);
|
||||
|
||||
m_uniform_scale = use_uniform_scale;
|
||||
|
||||
set_dirty();
|
||||
#else
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
if (selection.is_single_full_instance() && m_world_coordinates && !use_uniform_scale) {
|
||||
// Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible.
|
||||
// all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one
|
||||
const GLVolume* volume = selection.get_first_volume();
|
||||
// Is the angle close to a multiple of 90 degrees?
|
||||
if (!Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) {
|
||||
// Cannot apply scaling in the world coordinate system.
|
||||
//wxMessageDialog dlg(GUI::wxGetApp().mainframe,
|
||||
MessageDialog dlg(GUI::wxGetApp().mainframe,
|
||||
_L("The currently manipulated object is tilted (rotation angles are not multiples of 90°).\n"
|
||||
"Non-uniform scaling of tilted objects is only possible in the World coordinate system,\n"
|
||||
"once the rotation is embedded into the object coordinates.") + "\n" +
|
||||
_L("This operation is irreversible.\n"
|
||||
"Do you want to proceed?"),
|
||||
SLIC3R_APP_NAME,
|
||||
wxYES_NO | wxCANCEL | wxCANCEL_DEFAULT | wxICON_QUESTION);
|
||||
if (dlg.ShowModal() != wxID_YES) {
|
||||
// Enforce uniform scaling.
|
||||
m_lock_bnt->SetLock(true);
|
||||
return;
|
||||
}
|
||||
// Bake the rotation into the meshes of the object.
|
||||
wxGetApp().model().objects[volume->composite_id.object_id]->bake_xy_rotation_into_meshes(volume->composite_id.instance_id);
|
||||
// Update the 3D scene, selections etc.
|
||||
wxGetApp().plater()->update();
|
||||
// Recalculate cached values at this panel, refresh the screen.
|
||||
this->UpdateAndShow(true);
|
||||
}
|
||||
}
|
||||
|
||||
m_uniform_scale = use_uniform_scale;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void ObjectManipulation::set_coordinates_type(ECoordinatesType type)
|
||||
{
|
||||
if (wxGetApp().get_mode() == comSimple)
|
||||
|
@ -1461,6 +1095,7 @@ void ObjectManipulation::set_coordinates_type(ECoordinatesType type)
|
|||
return;
|
||||
|
||||
m_coordinates_type = type;
|
||||
m_word_local_combo->SetSelection((int)m_coordinates_type);
|
||||
this->UpdateAndShow(true);
|
||||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||
canvas->get_gizmos_manager().update_data();
|
||||
|
@ -1470,13 +1105,8 @@ void ObjectManipulation::set_coordinates_type(ECoordinatesType type)
|
|||
|
||||
ECoordinatesType ObjectManipulation::get_coordinates_type() const
|
||||
{
|
||||
const wxString og_name = get_og()->get_name();
|
||||
if (og_name.Contains(_L("Group manipulation")))
|
||||
return ECoordinatesType::World;
|
||||
|
||||
return m_coordinates_type;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void ObjectManipulation::msw_rescale()
|
||||
{
|
||||
|
@ -1517,37 +1147,25 @@ void ObjectManipulation::sys_color_changed()
|
|||
editor->sys_color_changed(this);
|
||||
|
||||
m_mirror_bitmap_on.sys_color_changed();
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
m_mirror_bitmap_off.sys_color_changed();
|
||||
m_mirror_bitmap_hidden.sys_color_changed();
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
m_reset_scale_button->sys_color_changed();
|
||||
m_reset_rotation_button->sys_color_changed();
|
||||
m_drop_to_bed_button->sys_color_changed();
|
||||
m_lock_bnt->sys_color_changed();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
for (int id = 0; id < 3; ++id) {
|
||||
m_mirror_buttons[id]->sys_color_changed();
|
||||
}
|
||||
#else
|
||||
for (int id = 0; id < 3; ++id)
|
||||
m_mirror_buttons[id].first->sys_color_changed();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void ObjectManipulation::set_coordinates_type(const wxString& type_string)
|
||||
{
|
||||
ECoordinatesType type = ECoordinatesType::World;
|
||||
if (type_string == coordinate_type_str(ECoordinatesType::Instance))
|
||||
type = ECoordinatesType::Instance;
|
||||
else if (type_string == coordinate_type_str(ECoordinatesType::Local))
|
||||
type = ECoordinatesType::Local;
|
||||
|
||||
this->set_coordinates_type(type);
|
||||
if (type_string == coordinate_type_str(ECoordinatesType::Instance))
|
||||
this->set_coordinates_type(ECoordinatesType::Instance);
|
||||
else if (type_string == coordinate_type_str(ECoordinatesType::Local))
|
||||
this->set_coordinates_type(ECoordinatesType::Local);
|
||||
else
|
||||
this->set_coordinates_type(ECoordinatesType::World);
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
static const char axes[] = { 'x', 'y', 'z' };
|
||||
ManipulationEditor::ManipulationEditor(ObjectManipulation* parent,
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
|
||||
#include "GUI_ObjectSettings.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#include "GUI_Geometry.hpp"
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include <float.h>
|
||||
|
||||
|
@ -60,9 +58,7 @@ public:
|
|||
void set_value(const wxString& new_value);
|
||||
void kill_focus(ObjectManipulation *parent);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const std::string& get_full_opt_name() const { return m_full_opt_name; }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
bool has_opt_key(const std::string& key) { return m_opt_key == key; }
|
||||
|
||||
|
@ -125,31 +121,15 @@ private:
|
|||
// Non-owning pointers to the reset buttons, so we can hide and show them.
|
||||
ScalableButton* m_reset_scale_button{ nullptr };
|
||||
ScalableButton* m_reset_rotation_button{ nullptr };
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
ScalableButton* m_reset_skew_button{ nullptr };
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
ScalableButton* m_drop_to_bed_button{ nullptr };
|
||||
|
||||
wxCheckBox* m_check_inch {nullptr};
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
std::array<ScalableButton*, 3> m_mirror_buttons;
|
||||
#else
|
||||
// Mirroring buttons and their current state
|
||||
enum MirrorButtonState {
|
||||
mbHidden,
|
||||
mbShown,
|
||||
mbActive
|
||||
};
|
||||
std::array<std::pair<ScalableButton*, MirrorButtonState>, 3> m_mirror_buttons;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// Bitmaps for the mirroring buttons.
|
||||
ScalableBitmap m_mirror_bitmap_on;
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
ScalableBitmap m_mirror_bitmap_off;
|
||||
ScalableBitmap m_mirror_bitmap_hidden;
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
// Needs to be updated from OnIdle?
|
||||
bool m_dirty = false;
|
||||
|
@ -163,37 +143,21 @@ private:
|
|||
Vec3d m_new_size;
|
||||
bool m_new_enabled {true};
|
||||
bool m_uniform_scale {true};
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
ECoordinatesType m_coordinates_type{ ECoordinatesType::World };
|
||||
#else
|
||||
// Does the object manipulation panel work in World or Local coordinates?
|
||||
bool m_world_coordinates = true;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
LockButton* m_lock_bnt{ nullptr };
|
||||
choice_ctrl* m_word_local_combo { nullptr };
|
||||
|
||||
ScalableBitmap m_manifold_warning_bmp;
|
||||
wxStaticBitmap* m_fix_throught_netfab_bitmap{ nullptr };
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
wxStaticBitmap* m_mirror_warning_bitmap{ nullptr };
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
// Currently focused editor (nullptr if none)
|
||||
ManipulationEditor* m_focused_editor{ nullptr };
|
||||
#else
|
||||
#ifndef __APPLE__
|
||||
// Currently focused editor (nullptr if none)
|
||||
ManipulationEditor* m_focused_editor {nullptr};
|
||||
#endif // __APPLE__
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
wxFlexGridSizer* m_main_grid_sizer;
|
||||
wxFlexGridSizer* m_labels_grid_sizer;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
wxStaticText* m_skew_label{ nullptr };
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// sizers, used for msw_rescale
|
||||
wxBoxSizer* m_word_local_combo_sizer;
|
||||
|
@ -221,17 +185,12 @@ public:
|
|||
|
||||
void set_uniform_scaling(const bool use_uniform_scale);
|
||||
bool get_uniform_scaling() const { return m_uniform_scale; }
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
|
||||
void set_coordinates_type(ECoordinatesType type);
|
||||
ECoordinatesType get_coordinates_type() const;
|
||||
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; }
|
||||
#else
|
||||
// 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; }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void reset_cache() { m_cache.reset(); }
|
||||
#ifndef __APPLE__
|
||||
|
@ -247,22 +206,16 @@ public:
|
|||
void sys_color_changed();
|
||||
void on_change(const std::string& opt_key, int axis, double new_value);
|
||||
void set_focused_editor(ManipulationEditor* focused_editor) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_focused_editor = focused_editor;
|
||||
#else
|
||||
#ifndef __APPLE__
|
||||
m_focused_editor = focused_editor;
|
||||
#endif // __APPLE__
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
ManipulationEditor* get_focused_editor() { return m_focused_editor; }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
static wxString coordinate_type_str(ECoordinatesType type);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_OBJECT_MANIPULATION_DEBUG
|
||||
void render_debug_window();
|
||||
#endif // ENABLE_OBJECT_MANIPULATION_DEBUG
|
||||
|
||||
private:
|
||||
void reset_settings_value();
|
||||
|
@ -279,11 +232,9 @@ private:
|
|||
void change_scale_value(int axis, double value);
|
||||
void change_size_value(int axis, double value);
|
||||
void do_scale(int axis, const Vec3d &scale) const;
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void do_size(int axis, const Vec3d& scale) const;
|
||||
|
||||
void set_coordinates_type(const wxString& type_string);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -262,39 +262,13 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
|
|||
return true;
|
||||
}
|
||||
else if (mouse_event.LeftUp() || is_leaving || is_dragging_finished) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
do_stop_dragging(is_leaving);
|
||||
#else
|
||||
for (auto &grabber : m_grabbers) grabber.dragging = false;
|
||||
m_dragging = false;
|
||||
|
||||
// NOTE: This should be part of GLCanvas3D
|
||||
// Reset hover_id when leave window
|
||||
if (is_leaving) m_parent.mouse_up_cleanup();
|
||||
|
||||
on_stop_dragging();
|
||||
|
||||
// There is prediction that after draggign, data are changed
|
||||
// Data are updated twice also by canvas3D::reload_scene.
|
||||
// Should be fixed.
|
||||
m_parent.get_gizmos_manager().update_data();
|
||||
|
||||
wxGetApp().obj_manipul()->set_dirty();
|
||||
|
||||
// Let the plater know that the dragging finished, so a delayed
|
||||
// refresh of the scene with the background processing data should
|
||||
// be performed.
|
||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
|
||||
// updates camera target constraints
|
||||
m_parent.refresh_camera_scene_box();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void GLGizmoBase::do_stop_dragging(bool perform_mouse_cleanup)
|
||||
{
|
||||
for (auto& grabber : m_grabbers) grabber.dragging = false;
|
||||
|
@ -320,7 +294,6 @@ void GLGizmoBase::do_stop_dragging(bool perform_mouse_cleanup)
|
|||
// updates camera target constraints
|
||||
m_parent.refresh_camera_scene_box();
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
std::string GLGizmoBase::format(float value, unsigned int decimals) const
|
||||
{
|
||||
|
|
|
@ -235,9 +235,7 @@ protected:
|
|||
/// <returns>same as on_mouse</returns>
|
||||
bool use_grabbers(const wxMouseEvent &mouse_event);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void do_stop_dragging(bool perform_mouse_cleanup);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
private:
|
||||
// Flag for dirty visible state of Gizmo
|
||||
|
|
|
@ -357,11 +357,7 @@ void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block)
|
|||
|
||||
++mesh_id;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d trafo_matrix = mi->get_matrix_no_offset() * mv->get_matrix_no_offset();
|
||||
#else
|
||||
const Transform3d trafo_matrix = mi->get_matrix(true) * mv->get_matrix(true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
Vec3f down = (trafo_matrix.inverse() * (-Vec3d::UnitZ())).cast<float>().normalized();
|
||||
Vec3f limit = (trafo_matrix.inverse() * Vec3d(std::sin(threshold), 0, -std::cos(threshold))).cast<float>().normalized();
|
||||
|
||||
|
|
|
@ -179,11 +179,7 @@ void GLGizmoFlatten::update_planes()
|
|||
ch = ch.convex_hull_3d();
|
||||
m_planes.clear();
|
||||
on_unregister_raycasters_for_picking();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d inst_matrix = mo->instances.front()->get_matrix_no_offset();
|
||||
#else
|
||||
const Transform3d& inst_matrix = mo->instances.front()->get_matrix(true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// Following constants are used for discarding too small polygons.
|
||||
const float minimal_area = 5.f; // in square mm (world coordinates)
|
||||
|
|
|
@ -135,11 +135,7 @@ void GLGizmoHollow::render_points(const Selection& selection)
|
|||
trafo.translation()(2) += shift_z;
|
||||
const Geometry::Transformation transformation{trafo};
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d instance_scaling_matrix_inverse = transformation.get_scaling_factor_matrix().inverse();
|
||||
#else
|
||||
const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
#include "GLGizmoMove.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
||||
|
@ -23,8 +21,7 @@ GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filenam
|
|||
|
||||
std::string GLGizmoMove3D::get_tooltip() const
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (m_hover_id == 0)
|
||||
if (m_hover_id == 0)
|
||||
return "X: " + format(m_displacement.x(), 2);
|
||||
else if (m_hover_id == 1)
|
||||
return "Y: " + format(m_displacement.y(), 2);
|
||||
|
@ -32,20 +29,6 @@ std::string GLGizmoMove3D::get_tooltip() const
|
|||
return "Z: " + format(m_displacement.z(), 2);
|
||||
else
|
||||
return "";
|
||||
#else
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const bool show_position = selection.is_single_full_instance();
|
||||
const Vec3d& position = selection.get_bounding_box().center();
|
||||
|
||||
if (m_hover_id == 0 || m_grabbers[0].dragging)
|
||||
return "X: " + format(show_position ? position.x() : m_displacement.x(), 2);
|
||||
else if (m_hover_id == 1 || m_grabbers[1].dragging)
|
||||
return "Y: " + format(show_position ? position.y() : m_displacement.y(), 2);
|
||||
else if (m_hover_id == 2 || m_grabbers[2].dragging)
|
||||
return "Z: " + format(show_position ? position.z() : m_displacement.z(), 2);
|
||||
else
|
||||
return "";
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
bool GLGizmoMove3D::on_mouse(const wxMouseEvent &mouse_event) {
|
||||
|
@ -87,7 +70,6 @@ void GLGizmoMove3D::on_start_dragging()
|
|||
assert(m_hover_id != -1);
|
||||
|
||||
m_displacement = Vec3d::Zero();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||
if (coordinates_type == ECoordinatesType::World)
|
||||
|
@ -103,13 +85,6 @@ void GLGizmoMove3D::on_start_dragging()
|
|||
m_starting_box_center = m_center;
|
||||
m_starting_box_bottom_center = m_center;
|
||||
m_starting_box_bottom_center.z() = m_bounding_box.min.z();
|
||||
#else
|
||||
const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box();
|
||||
m_starting_drag_position = m_grabbers[m_hover_id].center;
|
||||
m_starting_box_center = box.center();
|
||||
m_starting_box_bottom_center = box.center();
|
||||
m_starting_box_bottom_center.z() = box.min.z();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
void GLGizmoMove3D::on_stop_dragging()
|
||||
|
@ -128,7 +103,6 @@ void GLGizmoMove3D::on_dragging(const UpdateData& data)
|
|||
m_displacement.z() = calc_projection(data);
|
||||
|
||||
Selection &selection = m_parent.get_selection();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType trafo_type;
|
||||
trafo_type.set_relative();
|
||||
switch (wxGetApp().obj_manipul()->get_coordinates_type())
|
||||
|
@ -138,9 +112,6 @@ void GLGizmoMove3D::on_dragging(const UpdateData& data)
|
|||
default: { break; }
|
||||
}
|
||||
selection.translate(m_displacement, trafo_type);
|
||||
#else
|
||||
selection.translate(m_displacement);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
void GLGizmoMove3D::on_render()
|
||||
|
@ -148,7 +119,6 @@ void GLGizmoMove3D::on_render()
|
|||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const auto& [box, box_trafo] = selection.get_bounding_box_in_current_reference_system();
|
||||
m_bounding_box = box;
|
||||
|
@ -172,42 +142,16 @@ void GLGizmoMove3D::on_render()
|
|||
// z axis
|
||||
m_grabbers[2].center = { 0.0, 0.0, half_box_size.z() + Offset };
|
||||
m_grabbers[2].color = AXES_COLOR[2];
|
||||
#else
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const BoundingBoxf3& box = selection.get_bounding_box();
|
||||
const Vec3d& center = box.center();
|
||||
|
||||
// x axis
|
||||
m_grabbers[0].center = { box.max.x() + Offset, center.y(), center.z() };
|
||||
m_grabbers[0].color = AXES_COLOR[0];
|
||||
|
||||
// y axis
|
||||
m_grabbers[1].center = { center.x(), box.max.y() + Offset, center.z() };
|
||||
m_grabbers[1].color = AXES_COLOR[1];
|
||||
|
||||
// z axis
|
||||
m_grabbers[2].center = { center.x(), center.y(), box.max.z() + Offset };
|
||||
m_grabbers[2].color = AXES_COLOR[2];
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile())
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
auto render_grabber_connection = [this, &zero](unsigned int id) {
|
||||
#else
|
||||
auto render_grabber_connection = [this, ¢er](unsigned int id) {
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
if (m_grabbers[id].enabled) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (!m_grabber_connections[id].model.is_initialized() || !m_grabber_connections[id].old_center.isApprox(m_grabbers[id].center)) {
|
||||
m_grabber_connections[id].old_center = m_grabbers[id].center;
|
||||
#else
|
||||
if (!m_grabber_connections[id].model.is_initialized() || !m_grabber_connections[id].old_center.isApprox(center)) {
|
||||
m_grabber_connections[id].old_center = center;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_grabber_connections[id].model.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
|
@ -217,11 +161,7 @@ void GLGizmoMove3D::on_render()
|
|||
init_data.indices.reserve(2);
|
||||
|
||||
// vertices
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
init_data.add_vertex((Vec3f)zero.cast<float>());
|
||||
#else
|
||||
init_data.add_vertex((Vec3f)center.cast<float>());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
init_data.add_vertex((Vec3f)m_grabbers[id].center.cast<float>());
|
||||
|
||||
// indices
|
||||
|
@ -243,11 +183,7 @@ void GLGizmoMove3D::on_render()
|
|||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * base_matrix);
|
||||
#else
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
|
@ -265,11 +201,7 @@ void GLGizmoMove3D::on_render()
|
|||
}
|
||||
|
||||
// draw grabbers
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
render_grabbers(m_bounding_box);
|
||||
#else
|
||||
render_grabbers(box);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
else {
|
||||
// draw axis
|
||||
|
@ -282,11 +214,7 @@ void GLGizmoMove3D::on_render()
|
|||
shader->start_using();
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix()* base_matrix);
|
||||
#else
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
|
@ -304,11 +232,7 @@ void GLGizmoMove3D::on_render()
|
|||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
// draw grabber
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Vec3d box_size = m_bounding_box.size();
|
||||
#else
|
||||
const Vec3d box_size = box.size();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
const float mean_size = (float)((box_size.x() + box_size.y() + box_size.z()) / 3.0);
|
||||
m_grabbers[m_hover_id].render(true, mean_size);
|
||||
shader->stop_using();
|
||||
|
@ -353,7 +277,6 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const
|
|||
return projection;
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Transform3d GLGizmoMove3D::local_transform(const Selection& selection) const
|
||||
{
|
||||
Transform3d ret = Geometry::translation_transform(m_center);
|
||||
|
@ -366,7 +289,6 @@ Transform3d GLGizmoMove3D::local_transform(const Selection& selection) const
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
|
@ -7,19 +7,15 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
class Selection;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
class GLGizmoMove3D : public GLGizmoBase
|
||||
{
|
||||
static const double Offset;
|
||||
|
||||
Vec3d m_displacement{ Vec3d::Zero() };
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d m_center{ Vec3d::Zero() };
|
||||
BoundingBoxf3 m_bounding_box;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
double m_snap_step{ 1.0 };
|
||||
Vec3d m_starting_drag_position{ Vec3d::Zero() };
|
||||
Vec3d m_starting_box_center{ Vec3d::Zero() };
|
||||
|
@ -65,9 +61,7 @@ protected:
|
|||
|
||||
private:
|
||||
double calc_projection(const UpdateData& data) const;
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Transform3d local_transform(const Selection& selection) const;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -267,11 +267,7 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
|
|||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_scaling_factor_matrix().inverse();
|
||||
#else
|
||||
const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_matrix(true, true, false, true).inverse();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
ColorRGBA render_color = { 0.0f, 0.0f, 0.0f, 0.25f };
|
||||
if (m_button_down == Button::Left)
|
||||
|
@ -466,11 +462,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
const Selection &selection = m_parent.get_selection();
|
||||
const ModelObject *mo = m_c->selection_info()->model_object();
|
||||
const ModelInstance *mi = mo->instances[selection.get_instance_idx()];
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d trafo_matrix_not_translate = mi->get_transformation().get_matrix_no_offset() * mo->volumes[m_rr.mesh_id]->get_matrix_no_offset();
|
||||
#else
|
||||
const Transform3d trafo_matrix_not_translate = mi->get_transformation().get_matrix(true) * mo->volumes[m_rr.mesh_id]->get_matrix(true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
const Transform3d trafo_matrix = mi->get_transformation().get_matrix() * mo->volumes[m_rr.mesh_id]->get_matrix();
|
||||
m_triangle_selectors[m_rr.mesh_id]->seed_fill_select_triangles(m_rr.hit, int(m_rr.facet), trafo_matrix_not_translate, this->get_clipping_plane_in_volume_coordinates(trafo_matrix), m_smart_fill_angle,
|
||||
m_paint_on_overhangs_only ? m_highlight_by_angle_threshold_deg : 0.f, true);
|
||||
|
@ -509,11 +501,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
const ModelObject *mo = m_c->selection_info()->model_object();
|
||||
const ModelInstance *mi = mo->instances[selection.get_instance_idx()];
|
||||
const Transform3d instance_trafo = mi->get_transformation().get_matrix();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix_no_offset();
|
||||
#else
|
||||
const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix(true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// Precalculate transformations of individual meshes.
|
||||
std::vector<Transform3d> trafo_matrices;
|
||||
|
@ -521,11 +509,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
for (const ModelVolume *mv : mo->volumes)
|
||||
if (mv->is_model_part()) {
|
||||
trafo_matrices.emplace_back(instance_trafo * mv->get_matrix());
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix_no_offset());
|
||||
#else
|
||||
trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix(true));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
std::vector<std::vector<ProjectedMousePosition>> projected_mouse_positions_by_mesh = get_projected_mouse_positions(mouse_position, 1., trafo_matrices);
|
||||
|
@ -607,11 +591,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
const ModelObject *mo = m_c->selection_info()->model_object();
|
||||
const ModelInstance *mi = mo->instances[selection.get_instance_idx()];
|
||||
const Transform3d instance_trafo = mi->get_transformation().get_matrix();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix_no_offset();
|
||||
#else
|
||||
const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix(true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// Precalculate transformations of individual meshes.
|
||||
std::vector<Transform3d> trafo_matrices;
|
||||
|
@ -619,11 +599,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
for (const ModelVolume *mv : mo->volumes)
|
||||
if (mv->is_model_part()) {
|
||||
trafo_matrices.emplace_back(instance_trafo * mv->get_matrix());
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate* mv->get_matrix_no_offset());
|
||||
#else
|
||||
trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix(true));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
// Now "click" into all the prepared points and spill paint around them.
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
#include "GLGizmoRotate.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/ImGuiWrapper.hpp"
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
|
@ -101,27 +99,12 @@ bool GLGizmoRotate::on_init()
|
|||
|
||||
void GLGizmoRotate::on_start_dragging()
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
init_data_from_selection(m_parent.get_selection());
|
||||
#else
|
||||
const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box();
|
||||
m_center = box.center();
|
||||
m_radius = Offset + box.radius();
|
||||
m_snap_coarse_in_radius = m_radius / 3.0f;
|
||||
m_snap_coarse_out_radius = 2.0f * m_snap_coarse_in_radius;
|
||||
m_snap_fine_in_radius = m_radius;
|
||||
m_snap_fine_out_radius = m_snap_fine_in_radius + m_radius * ScaleLongTooth;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
void GLGizmoRotate::on_dragging(const UpdateData &data)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray));
|
||||
#else
|
||||
const Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray, m_parent.get_selection()));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
const Vec2d orig_dir = Vec2d::UnitX();
|
||||
const Vec2d new_dir = mouse_pos.normalized();
|
||||
|
||||
|
@ -156,22 +139,8 @@ void GLGizmoRotate::on_render()
|
|||
return;
|
||||
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
const BoundingBoxf3& box = selection.get_bounding_box();
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
if (m_hover_id != 0 && !m_grabbers.front().dragging) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (m_hover_id != 0 && !m_grabbers.front().dragging)
|
||||
init_data_from_selection(selection);
|
||||
#else
|
||||
m_center = box.center();
|
||||
m_radius = Offset + box.radius();
|
||||
m_snap_coarse_in_radius = m_radius / 3.0f;
|
||||
m_snap_coarse_out_radius = 2.0f * m_snap_coarse_in_radius;
|
||||
m_snap_fine_in_radius = m_radius;
|
||||
m_snap_fine_out_radius = m_radius * (1.0f + ScaleLongTooth);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
const double grabber_radius = (double)m_radius * (1.0 + (double)GrabberOffset);
|
||||
m_grabbers.front().center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
|
||||
|
@ -224,14 +193,9 @@ void GLGizmoRotate::on_render()
|
|||
shader->stop_using();
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
render_grabber(m_bounding_box);
|
||||
#else
|
||||
render_grabber(box);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void GLGizmoRotate::init_data_from_selection(const Selection& selection)
|
||||
{
|
||||
const auto [box, box_trafo] = m_force_local_coordinate ?
|
||||
|
@ -246,7 +210,6 @@ void GLGizmoRotate::init_data_from_selection(const Selection& selection)
|
|||
m_snap_fine_in_radius = m_radius;
|
||||
m_snap_fine_out_radius = m_snap_fine_in_radius + m_radius * ScaleLongTooth;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limit)
|
||||
{
|
||||
|
@ -473,20 +436,12 @@ Transform3d GLGizmoRotate::local_transform(const Selection& selection) const
|
|||
{
|
||||
case X:
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
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_WORLD_COORDINATE
|
||||
break;
|
||||
}
|
||||
case Y:
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
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_WORLD_COORDINATE
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -497,21 +452,10 @@ Transform3d GLGizmoRotate::local_transform(const Selection& selection) const
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
return m_orient_matrix * ret;
|
||||
#else
|
||||
if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes())
|
||||
ret = selection.get_first_volume()->get_instance_transformation().get_matrix(true, false, true, true) * ret;
|
||||
|
||||
return Geometry::assemble_transform(m_center) * ret;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray) const
|
||||
#else
|
||||
Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
{
|
||||
const double half_pi = 0.5 * double(PI);
|
||||
|
||||
|
@ -539,12 +483,7 @@ Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, cons
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m = m * Geometry::Transformation(m_orient_matrix).get_matrix_no_offset().inverse();
|
||||
#else
|
||||
if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes())
|
||||
m = m * selection.get_first_volume()->get_instance_transformation().get_matrix(true, false, true, true).inverse();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
m.translate(-m_center);
|
||||
|
||||
|
@ -578,7 +517,6 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event)
|
|||
{
|
||||
if (mouse_event.Dragging() && m_dragging) {
|
||||
// Apply new temporary rotations
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType transformation_type;
|
||||
if (m_parent.get_selection().is_wipe_tower())
|
||||
transformation_type = TransformationType::World_Relative_Joint;
|
||||
|
@ -591,9 +529,6 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event)
|
|||
case ECoordinatesType::Local: { transformation_type = TransformationType::Local_Relative_Joint; break; }
|
||||
}
|
||||
}
|
||||
#else
|
||||
TransformationType transformation_type(TransformationType::World_Relative_Joint);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
if (mouse_event.AltDown())
|
||||
transformation_type.set_independent();
|
||||
m_parent.get_selection().rotate(get_rotation(), transformation_type);
|
||||
|
@ -603,26 +538,14 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event)
|
|||
|
||||
void GLGizmoRotate3D::data_changed() {
|
||||
if (m_parent.get_selection().is_wipe_tower()) {
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
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_WORLD_COORDINATE
|
||||
m_gizmos[0].disable_grabber();
|
||||
m_gizmos[1].disable_grabber();
|
||||
}
|
||||
else {
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
set_rotation(Vec3d::Zero());
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
m_gizmos[0].enable_grabber();
|
||||
m_gizmos[1].enable_grabber();
|
||||
}
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
set_rotation(Vec3d::Zero());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
bool GLGizmoRotate3D::on_init()
|
||||
|
|
|
@ -35,10 +35,8 @@ private:
|
|||
float m_snap_coarse_out_radius{ 0.0f };
|
||||
float m_snap_fine_in_radius{ 0.0f };
|
||||
float m_snap_fine_out_radius{ 0.0f };
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
BoundingBoxf3 m_bounding_box;
|
||||
Transform3d m_orient_matrix{ Transform3d::Identity() };
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
GLModel m_circle;
|
||||
GLModel m_scale;
|
||||
|
@ -109,15 +107,9 @@ private:
|
|||
Transform3d local_transform(const Selection& selection) const;
|
||||
|
||||
// returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray) const;
|
||||
#else
|
||||
Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void init_data_from_selection(const Selection& selection);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
};
|
||||
|
||||
class GLGizmoRotate3D : public GLGizmoBase
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
#include "GLGizmoScale.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
||||
|
@ -21,7 +19,6 @@ const double GLGizmoScale3D::Offset = 5.0;
|
|||
GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||
, m_scale(Vec3d::Ones())
|
||||
, m_offset(Vec3d::Zero())
|
||||
, m_snap_step(0.05)
|
||||
, m_base_color(DEFAULT_BASE_COLOR)
|
||||
, m_drag_color(DEFAULT_DRAG_COLOR)
|
||||
|
@ -38,17 +35,7 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen
|
|||
|
||||
std::string GLGizmoScale3D::get_tooltip() const
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Vec3d scale = 100.0 * m_scale;
|
||||
#else
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
|
||||
Vec3d scale = 100.0 * Vec3d::Ones();
|
||||
if (selection.is_single_full_instance())
|
||||
scale = 100.0 * selection.get_first_volume()->get_instance_scaling_factor();
|
||||
else if (selection.is_single_modifier() || selection.is_single_volume())
|
||||
scale = 100.0 * selection.get_first_volume()->get_volume_scaling_factor();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
if (m_hover_id == 0 || m_hover_id == 1 || m_grabbers[0].dragging || m_grabbers[1].dragging)
|
||||
return "X: " + format(scale.x(), 4) + "%";
|
||||
|
@ -68,12 +55,17 @@ std::string GLGizmoScale3D::get_tooltip() const
|
|||
return "";
|
||||
}
|
||||
|
||||
static int constraint_id(int grabber_id)
|
||||
{
|
||||
static const std::vector<int> id_map = { 1, 0, 3, 2, 5, 4, 8, 9, 6, 7 };
|
||||
return (0 <= grabber_id && grabber_id < (int)id_map.size()) ? id_map[grabber_id] : -1;
|
||||
}
|
||||
|
||||
bool GLGizmoScale3D::on_mouse(const wxMouseEvent &mouse_event)
|
||||
{
|
||||
if (mouse_event.Dragging()) {
|
||||
if (m_dragging) {
|
||||
// Apply new temporary scale factors
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType transformation_type;
|
||||
if (wxGetApp().obj_manipul()->is_local_coordinates())
|
||||
transformation_type.set_local();
|
||||
|
@ -81,20 +73,22 @@ bool GLGizmoScale3D::on_mouse(const wxMouseEvent &mouse_event)
|
|||
transformation_type.set_instance();
|
||||
|
||||
transformation_type.set_relative();
|
||||
#else
|
||||
TransformationType transformation_type(TransformationType::Local_Absolute_Joint);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
if (mouse_event.AltDown())
|
||||
transformation_type.set_independent();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_parent.get_selection().scale_and_translate(m_scale, m_offset, transformation_type);
|
||||
#else
|
||||
Selection& selection = m_parent.get_selection();
|
||||
selection.scale(m_scale, transformation_type);
|
||||
if (mouse_event.CmdDown()) selection.translate(m_offset, true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
if (m_starting.ctrl_down) {
|
||||
// constrained scale:
|
||||
// uses the performed scale to calculate the new position of the constrained grabber
|
||||
// and from that calculates the offset (in world coordinates) to be applied to fullfill the constraint
|
||||
update_render_data();
|
||||
const Vec3d constraint_position = m_grabbers_transform * m_grabbers[constraint_id(m_hover_id)].center;
|
||||
// re-apply the scale because the selection always applies the transformations with respect to the initial state
|
||||
// set into on_start_dragging() with the call to selection.setup_cache()
|
||||
m_parent.get_selection().scale_and_translate(m_scale, m_starting.constraint_position - constraint_position, transformation_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
return use_grabbers(mouse_event);
|
||||
|
@ -108,29 +102,7 @@ void GLGizmoScale3D::enable_ununiversal_scale(bool enable)
|
|||
|
||||
void GLGizmoScale3D::data_changed()
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
set_scale(Vec3d::Ones());
|
||||
#else
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
bool enable_scale_xyz = selection.is_single_full_instance() ||
|
||||
selection.is_single_volume() ||
|
||||
selection.is_single_modifier();
|
||||
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
m_grabbers[i].enabled = enable_scale_xyz;
|
||||
|
||||
if (enable_scale_xyz) {
|
||||
// all volumes in the selection belongs to the same instance, any of
|
||||
// them contains the needed data, so we take the first
|
||||
const GLVolume* volume = selection.get_first_volume();
|
||||
if (selection.is_single_full_instance())
|
||||
set_scale(volume->get_instance_scaling_factor());
|
||||
else if (selection.is_single_volume() || selection.is_single_modifier())
|
||||
set_scale(volume->get_volume_scaling_factor());
|
||||
}
|
||||
else
|
||||
set_scale(Vec3d::Ones());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
bool GLGizmoScale3D::on_init()
|
||||
|
@ -139,20 +111,7 @@ bool GLGizmoScale3D::on_init()
|
|||
m_grabbers.push_back(Grabber());
|
||||
}
|
||||
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
double half_pi = 0.5 * (double)PI;
|
||||
|
||||
// x axis
|
||||
m_grabbers[0].angles.y() = half_pi;
|
||||
m_grabbers[1].angles.y() = half_pi;
|
||||
|
||||
// y axis
|
||||
m_grabbers[2].angles.x() = half_pi;
|
||||
m_grabbers[3].angles.x() = half_pi;
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
m_shortcut_key = WXK_CONTROL_S;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -171,27 +130,17 @@ void GLGizmoScale3D::on_start_dragging()
|
|||
{
|
||||
assert(m_hover_id != -1);
|
||||
m_starting.ctrl_down = wxGetKeyState(WXK_CONTROL);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_starting.drag_position = m_grabbers_transform * m_grabbers[m_hover_id].center;
|
||||
m_starting.box = m_bounding_box;
|
||||
m_starting.center = m_center;
|
||||
m_starting.instance_center = m_instance_center;
|
||||
#else
|
||||
m_starting.drag_position = m_grabbers[m_hover_id].center;
|
||||
m_starting.box = (m_starting.ctrl_down && m_hover_id < 6) ? m_bounding_box : m_parent.get_selection().get_bounding_box();
|
||||
|
||||
const Vec3d& center = m_starting.box.center();
|
||||
m_starting.pivots[0] = m_transform * Vec3d(m_starting.box.max.x(), center.y(), center.z());
|
||||
m_starting.pivots[1] = m_transform * Vec3d(m_starting.box.min.x(), center.y(), center.z());
|
||||
m_starting.pivots[2] = m_transform * Vec3d(center.x(), m_starting.box.max.y(), center.z());
|
||||
m_starting.pivots[3] = m_transform * Vec3d(center.x(), m_starting.box.min.y(), center.z());
|
||||
m_starting.pivots[4] = m_transform * Vec3d(center.x(), center.y(), m_starting.box.max.z());
|
||||
m_starting.pivots[5] = m_transform * Vec3d(center.x(), center.y(), m_starting.box.min.z());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_starting.constraint_position = m_grabbers_transform * m_grabbers[constraint_id(m_hover_id)].center;
|
||||
}
|
||||
|
||||
void GLGizmoScale3D::on_stop_dragging() {
|
||||
void GLGizmoScale3D::on_stop_dragging()
|
||||
{
|
||||
m_parent.do_scale(L("Gizmo-Scale"));
|
||||
m_starting.ctrl_down = false;
|
||||
}
|
||||
|
||||
void GLGizmoScale3D::on_dragging(const UpdateData& data)
|
||||
|
@ -206,60 +155,18 @@ void GLGizmoScale3D::on_dragging(const UpdateData& data)
|
|||
do_scale_uniform(data);
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void GLGizmoScale3D::on_render()
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
|
||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
const auto& [box, box_trafo] = selection.get_bounding_box_in_current_reference_system();
|
||||
m_bounding_box = box;
|
||||
m_center = box_trafo.translation();
|
||||
m_grabbers_transform = box_trafo;
|
||||
m_instance_center = (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) ? selection.get_first_volume()->get_instance_offset() : m_center;
|
||||
|
||||
// x axis
|
||||
const Vec3d box_half_size = 0.5 * m_bounding_box.size();
|
||||
bool use_constrain = wxGetKeyState(WXK_CONTROL) && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier());
|
||||
|
||||
m_grabbers[0].center = { -(box_half_size.x() + Offset), 0.0, 0.0 };
|
||||
m_grabbers[0].color = (use_constrain && m_hover_id == 1) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
m_grabbers[1].center = { box_half_size.x() + Offset, 0.0, 0.0 };
|
||||
m_grabbers[1].color = (use_constrain && m_hover_id == 0) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
|
||||
// y axis
|
||||
m_grabbers[2].center = { 0.0, -(box_half_size.y() + Offset), 0.0 };
|
||||
m_grabbers[2].color = (use_constrain && m_hover_id == 3) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
m_grabbers[3].center = { 0.0, box_half_size.y() + Offset, 0.0 };
|
||||
m_grabbers[3].color = (use_constrain && m_hover_id == 2) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
|
||||
// z axis
|
||||
m_grabbers[4].center = { 0.0, 0.0, -(box_half_size.z() + Offset) };
|
||||
m_grabbers[4].color = (use_constrain && m_hover_id == 5) ? CONSTRAINED_COLOR : AXES_COLOR[2];
|
||||
m_grabbers[5].center = { 0.0, 0.0, box_half_size.z() + Offset };
|
||||
m_grabbers[5].color = (use_constrain && m_hover_id == 4) ? CONSTRAINED_COLOR : AXES_COLOR[2];
|
||||
|
||||
// uniform
|
||||
m_grabbers[6].center = { -(box_half_size.x() + Offset), -(box_half_size.y() + Offset), 0.0 };
|
||||
m_grabbers[6].color = (use_constrain && m_hover_id == 8) ? CONSTRAINED_COLOR : m_highlight_color;
|
||||
m_grabbers[7].center = { box_half_size.x() + Offset, -(box_half_size.y() + Offset), 0.0 };
|
||||
m_grabbers[7].color = (use_constrain && m_hover_id == 9) ? CONSTRAINED_COLOR : m_highlight_color;
|
||||
m_grabbers[8].center = { box_half_size.x() + Offset, box_half_size.y() + Offset, 0.0 };
|
||||
m_grabbers[8].color = (use_constrain && m_hover_id == 6) ? CONSTRAINED_COLOR : m_highlight_color;
|
||||
m_grabbers[9].center = { -(box_half_size.x() + Offset), box_half_size.y() + Offset, 0.0 };
|
||||
m_grabbers[9].color = (use_constrain && m_hover_id == 7) ? CONSTRAINED_COLOR : m_highlight_color;
|
||||
update_render_data();
|
||||
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile())
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
m_grabbers[i].matrix = m_grabbers_transform;
|
||||
}
|
||||
|
||||
const float grabber_mean_size = (float)((m_bounding_box.size().x() + m_bounding_box.size().y() + m_bounding_box.size().z()) / 3.0);
|
||||
|
||||
if (m_hover_id == -1) {
|
||||
|
@ -424,267 +331,6 @@ void GLGizmoScale3D::on_render()
|
|||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void GLGizmoScale3D::on_render()
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
|
||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
m_bounding_box.reset();
|
||||
m_transform = Transform3d::Identity();
|
||||
// Transforms grabbers' offsets to world refefence system
|
||||
Transform3d offsets_transform = Transform3d::Identity();
|
||||
m_offsets_transform = Transform3d::Identity();
|
||||
Vec3d angles = Vec3d::Zero();
|
||||
|
||||
if (selection.is_single_full_instance()) {
|
||||
// calculate bounding box in instance local reference system
|
||||
const Selection::IndicesList& idxs = selection.get_volume_idxs();
|
||||
for (unsigned int idx : idxs) {
|
||||
const GLVolume& v = *selection.get_volume(idx);
|
||||
m_bounding_box.merge(v.transformed_convex_hull_bounding_box(v.get_volume_transformation().get_matrix()));
|
||||
}
|
||||
|
||||
// gets transform from first selected volume
|
||||
const GLVolume& v = *selection.get_first_volume();
|
||||
m_transform = v.get_instance_transformation().get_matrix();
|
||||
|
||||
// gets angles from first selected volume
|
||||
angles = v.get_instance_rotation();
|
||||
// consider rotation+mirror only components of the transform for offsets
|
||||
offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles, Vec3d::Ones(), v.get_instance_mirror());
|
||||
m_offsets_transform = offsets_transform;
|
||||
}
|
||||
else if (selection.is_single_modifier() || selection.is_single_volume()) {
|
||||
const GLVolume& v = *selection.get_first_volume();
|
||||
m_bounding_box = v.bounding_box();
|
||||
m_transform = v.world_matrix();
|
||||
angles = Geometry::extract_rotation(m_transform);
|
||||
// consider rotation+mirror only components of the transform for offsets
|
||||
offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles, Vec3d::Ones(), v.get_instance_mirror());
|
||||
m_offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), v.get_volume_rotation(), Vec3d::Ones(), v.get_volume_mirror());
|
||||
}
|
||||
else
|
||||
m_bounding_box = selection.get_bounding_box();
|
||||
|
||||
const Vec3d& center = m_bounding_box.center();
|
||||
const Vec3d offset_x = offsets_transform * Vec3d((double)Offset, 0.0, 0.0);
|
||||
const Vec3d offset_y = offsets_transform * Vec3d(0.0, (double)Offset, 0.0);
|
||||
const Vec3d offset_z = offsets_transform * Vec3d(0.0, 0.0, (double)Offset);
|
||||
|
||||
const bool ctrl_down = (m_dragging && m_starting.ctrl_down) || (!m_dragging && wxGetKeyState(WXK_CONTROL));
|
||||
|
||||
// x axis
|
||||
m_grabbers[0].center = m_transform * Vec3d(m_bounding_box.min.x(), center.y(), center.z()) - offset_x;
|
||||
m_grabbers[0].color = (ctrl_down && m_hover_id == 1) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
m_grabbers[1].center = m_transform * Vec3d(m_bounding_box.max.x(), center.y(), center.z()) + offset_x;
|
||||
m_grabbers[1].color = (ctrl_down && m_hover_id == 0) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
|
||||
// y axis
|
||||
m_grabbers[2].center = m_transform * Vec3d(center.x(), m_bounding_box.min.y(), center.z()) - offset_y;
|
||||
m_grabbers[2].color = (ctrl_down && m_hover_id == 3) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
m_grabbers[3].center = m_transform * Vec3d(center.x(), m_bounding_box.max.y(), center.z()) + offset_y;
|
||||
m_grabbers[3].color = (ctrl_down && m_hover_id == 2) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
|
||||
// z axis
|
||||
m_grabbers[4].center = m_transform * Vec3d(center.x(), center.y(), m_bounding_box.min.z()) - offset_z;
|
||||
m_grabbers[4].color = (ctrl_down && m_hover_id == 5) ? CONSTRAINED_COLOR : AXES_COLOR[2];
|
||||
m_grabbers[5].center = m_transform * Vec3d(center.x(), center.y(), m_bounding_box.max.z()) + offset_z;
|
||||
m_grabbers[5].color = (ctrl_down && m_hover_id == 4) ? CONSTRAINED_COLOR : AXES_COLOR[2];
|
||||
|
||||
// uniform
|
||||
m_grabbers[6].center = m_transform * Vec3d(m_bounding_box.min.x(), m_bounding_box.min.y(), center.z()) - offset_x - offset_y;
|
||||
m_grabbers[7].center = m_transform * Vec3d(m_bounding_box.max.x(), m_bounding_box.min.y(), center.z()) + offset_x - offset_y;
|
||||
m_grabbers[8].center = m_transform * Vec3d(m_bounding_box.max.x(), m_bounding_box.max.y(), center.z()) + offset_x + offset_y;
|
||||
m_grabbers[9].center = m_transform * Vec3d(m_bounding_box.min.x(), m_bounding_box.max.y(), center.z()) - offset_x + offset_y;
|
||||
|
||||
for (int i = 6; i < 10; ++i) {
|
||||
m_grabbers[i].color = m_highlight_color;
|
||||
}
|
||||
|
||||
// sets grabbers orientation
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
m_grabbers[i].angles = angles;
|
||||
}
|
||||
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile())
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
||||
|
||||
const BoundingBoxf3& selection_box = selection.get_bounding_box();
|
||||
const float grabber_mean_size = (float)((selection_box.size().x() + selection_box.size().y() + selection_box.size().z()) / 3.0);
|
||||
|
||||
if (m_hover_id == -1) {
|
||||
// draw connections
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
|
||||
#else
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3])));
|
||||
shader->set_uniform("width", 0.25f);
|
||||
shader->set_uniform("gap_size", 0.0f);
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
if (m_grabbers[0].enabled && m_grabbers[1].enabled)
|
||||
render_grabbers_connection(0, 1, m_grabbers[0].color);
|
||||
if (m_grabbers[2].enabled && m_grabbers[3].enabled)
|
||||
render_grabbers_connection(2, 3, m_grabbers[2].color);
|
||||
if (m_grabbers[4].enabled && m_grabbers[5].enabled)
|
||||
render_grabbers_connection(4, 5, m_grabbers[4].color);
|
||||
render_grabbers_connection(6, 7, m_base_color);
|
||||
render_grabbers_connection(7, 8, m_base_color);
|
||||
render_grabbers_connection(8, 9, m_base_color);
|
||||
render_grabbers_connection(9, 6, m_base_color);
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
// draw grabbers
|
||||
render_grabbers(grabber_mean_size);
|
||||
}
|
||||
else if ((m_hover_id == 0 || m_hover_id == 1) && m_grabbers[0].enabled && m_grabbers[1].enabled) {
|
||||
// draw connections
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
|
||||
#else
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3])));
|
||||
shader->set_uniform("width", 0.25f);
|
||||
shader->set_uniform("gap_size", 0.0f);
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
render_grabbers_connection(0, 1, m_grabbers[0].color);
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
// draw grabbers
|
||||
shader = wxGetApp().get_shader("gouraud_light");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
m_grabbers[0].render(true, grabber_mean_size);
|
||||
m_grabbers[1].render(true, grabber_mean_size);
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
else if ((m_hover_id == 2 || m_hover_id == 3) && m_grabbers[2].enabled && m_grabbers[3].enabled) {
|
||||
// draw connections
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
|
||||
#else
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3])));
|
||||
shader->set_uniform("width", 0.25f);
|
||||
shader->set_uniform("gap_size", 0.0f);
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
render_grabbers_connection(2, 3, m_grabbers[2].color);
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
// draw grabbers
|
||||
shader = wxGetApp().get_shader("gouraud_light");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
m_grabbers[2].render(true, grabber_mean_size);
|
||||
m_grabbers[3].render(true, grabber_mean_size);
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
else if ((m_hover_id == 4 || m_hover_id == 5) && m_grabbers[4].enabled && m_grabbers[5].enabled) {
|
||||
// draw connections
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
|
||||
#else
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3])));
|
||||
shader->set_uniform("width", 0.25f);
|
||||
shader->set_uniform("gap_size", 0.0f);
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
render_grabbers_connection(4, 5, m_grabbers[4].color);
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
// draw grabbers
|
||||
shader = wxGetApp().get_shader("gouraud_light");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
m_grabbers[4].render(true, grabber_mean_size);
|
||||
m_grabbers[5].render(true, grabber_mean_size);
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
else if (m_hover_id >= 6) {
|
||||
// draw connections
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
|
||||
#else
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3])));
|
||||
shader->set_uniform("width", 0.25f);
|
||||
shader->set_uniform("gap_size", 0.0f);
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
render_grabbers_connection(6, 7, m_drag_color);
|
||||
render_grabbers_connection(7, 8, m_drag_color);
|
||||
render_grabbers_connection(8, 9, m_drag_color);
|
||||
render_grabbers_connection(9, 6, m_drag_color);
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
// draw grabbers
|
||||
shader = wxGetApp().get_shader("gouraud_light");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
for (int i = 6; i < 10; ++i) {
|
||||
m_grabbers[i].render(true, grabber_mean_size);
|
||||
}
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void GLGizmoScale3D::on_register_raycasters_for_picking()
|
||||
{
|
||||
|
@ -737,127 +383,27 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int
|
|||
m_grabber_connections[id].model.render();
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
|
||||
{
|
||||
double ratio = calc_ratio(data);
|
||||
if (ratio > 0.0) {
|
||||
Vec3d curr_scale = m_scale;
|
||||
const Vec3d starting_scale = m_starting.scale;
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||
|
||||
curr_scale(axis) = starting_scale(axis) * ratio;
|
||||
curr_scale(axis) = m_starting.scale(axis) * ratio;
|
||||
m_scale = curr_scale;
|
||||
|
||||
if (m_starting.ctrl_down && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier())) {
|
||||
double local_offset = 0.5 * (ratio - 1.0) * m_starting.box.size()(axis);
|
||||
|
||||
if (m_hover_id == 2 * axis)
|
||||
local_offset *= -1.0;
|
||||
|
||||
switch (axis)
|
||||
{
|
||||
case X: { m_offset = local_offset * Vec3d::UnitX(); break; }
|
||||
case Y: { m_offset = local_offset * Vec3d::UnitY(); break; }
|
||||
case Z: { m_offset = local_offset * Vec3d::UnitZ(); break; }
|
||||
default: { m_offset = Vec3d::Zero(); break; }
|
||||
}
|
||||
|
||||
if (selection.is_single_volume_or_modifier()) {
|
||||
if (coordinates_type == ECoordinatesType::Instance)
|
||||
m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() * m_offset;
|
||||
else if (coordinates_type == ECoordinatesType::Local) {
|
||||
m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() *
|
||||
selection.get_first_volume()->get_volume_transformation().get_rotation_matrix() * m_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_offset = Vec3d::Zero();
|
||||
}
|
||||
}
|
||||
#else
|
||||
void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
|
||||
{
|
||||
const double ratio = calc_ratio(data);
|
||||
if (ratio > 0.0) {
|
||||
m_scale(axis) = m_starting.scale(axis) * ratio;
|
||||
|
||||
if (m_starting.ctrl_down) {
|
||||
double local_offset = 0.5 * (m_scale(axis) - m_starting.scale(axis)) * m_starting.box.size()(axis);
|
||||
|
||||
if (m_hover_id == 2 * axis)
|
||||
local_offset *= -1.0;
|
||||
|
||||
Vec3d local_offset_vec;
|
||||
switch (axis)
|
||||
{
|
||||
case X: { local_offset_vec = local_offset * Vec3d::UnitX(); break; }
|
||||
case Y: { local_offset_vec = local_offset * Vec3d::UnitY(); break; }
|
||||
case Z: { local_offset_vec = local_offset * Vec3d::UnitZ(); break; }
|
||||
default: break;
|
||||
}
|
||||
|
||||
m_offset = m_offsets_transform * local_offset_vec;
|
||||
}
|
||||
else
|
||||
m_offset = Vec3d::Zero();
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void GLGizmoScale3D::do_scale_uniform(const UpdateData & data)
|
||||
{
|
||||
const double ratio = calc_ratio(data);
|
||||
if (ratio > 0.0) {
|
||||
if (ratio > 0.0)
|
||||
m_scale = m_starting.scale * ratio;
|
||||
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||
if (m_starting.ctrl_down && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier())) {
|
||||
m_offset = 0.5 * (ratio - 1.0) * m_starting.box.size();
|
||||
|
||||
if (m_hover_id == 6 || m_hover_id == 9)
|
||||
m_offset.x() *= -1.0;
|
||||
if (m_hover_id == 6 || m_hover_id == 7)
|
||||
m_offset.y() *= -1.0;
|
||||
|
||||
if (selection.is_single_volume_or_modifier()) {
|
||||
if (coordinates_type == ECoordinatesType::Instance)
|
||||
m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() * m_offset;
|
||||
else if (coordinates_type == ECoordinatesType::Local) {
|
||||
m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() *
|
||||
selection.get_first_volume()->get_volume_transformation().get_rotation_matrix() * m_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_offset = Vec3d::Zero();
|
||||
}
|
||||
}
|
||||
#else
|
||||
void GLGizmoScale3D::do_scale_uniform(const UpdateData& data)
|
||||
{
|
||||
const double ratio = calc_ratio(data);
|
||||
if (ratio > 0.0) {
|
||||
m_scale = m_starting.scale * ratio;
|
||||
m_offset = Vec3d::Zero();
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
|
||||
{
|
||||
double ratio = 0.0;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Vec3d starting_vec = m_starting.drag_position - m_starting.center;
|
||||
#else
|
||||
const Vec3d pivot = (m_starting.ctrl_down && m_hover_id < 6) ? m_starting.pivots[m_hover_id] : m_starting.box.center();
|
||||
const Vec3d starting_vec = m_starting.drag_position - pivot;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
const double len_starting_vec = starting_vec.norm();
|
||||
|
||||
|
@ -883,5 +429,50 @@ double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
|
|||
return ratio;
|
||||
}
|
||||
|
||||
void GLGizmoScale3D::update_render_data()
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const auto& [box, box_trafo] = selection.get_bounding_box_in_current_reference_system();
|
||||
m_bounding_box = box;
|
||||
m_center = box_trafo.translation();
|
||||
m_grabbers_transform = box_trafo;
|
||||
m_instance_center = (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) ? selection.get_first_volume()->get_instance_offset() : m_center;
|
||||
|
||||
const Vec3d box_half_size = 0.5 * m_bounding_box.size();
|
||||
bool use_constrain = wxGetKeyState(WXK_CONTROL);
|
||||
|
||||
// x axis
|
||||
m_grabbers[0].center = { -(box_half_size.x() + Offset), 0.0, 0.0 };
|
||||
m_grabbers[0].color = (use_constrain && m_hover_id == 1) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
m_grabbers[1].center = { box_half_size.x() + Offset, 0.0, 0.0 };
|
||||
m_grabbers[1].color = (use_constrain && m_hover_id == 0) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||
|
||||
// y axis
|
||||
m_grabbers[2].center = { 0.0, -(box_half_size.y() + Offset), 0.0 };
|
||||
m_grabbers[2].color = (use_constrain && m_hover_id == 3) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
m_grabbers[3].center = { 0.0, box_half_size.y() + Offset, 0.0 };
|
||||
m_grabbers[3].color = (use_constrain && m_hover_id == 2) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||
|
||||
// z axis
|
||||
m_grabbers[4].center = { 0.0, 0.0, -(box_half_size.z() + Offset) };
|
||||
m_grabbers[4].color = (use_constrain && m_hover_id == 5) ? CONSTRAINED_COLOR : AXES_COLOR[2];
|
||||
m_grabbers[5].center = { 0.0, 0.0, box_half_size.z() + Offset };
|
||||
m_grabbers[5].color = (use_constrain && m_hover_id == 4) ? CONSTRAINED_COLOR : AXES_COLOR[2];
|
||||
|
||||
// uniform
|
||||
m_grabbers[6].center = { -(box_half_size.x() + Offset), -(box_half_size.y() + Offset), 0.0 };
|
||||
m_grabbers[6].color = (use_constrain && m_hover_id == 8) ? CONSTRAINED_COLOR : m_highlight_color;
|
||||
m_grabbers[7].center = { box_half_size.x() + Offset, -(box_half_size.y() + Offset), 0.0 };
|
||||
m_grabbers[7].color = (use_constrain && m_hover_id == 9) ? CONSTRAINED_COLOR : m_highlight_color;
|
||||
m_grabbers[8].center = { box_half_size.x() + Offset, box_half_size.y() + Offset, 0.0 };
|
||||
m_grabbers[8].color = (use_constrain && m_hover_id == 6) ? CONSTRAINED_COLOR : m_highlight_color;
|
||||
m_grabbers[9].center = { -(box_half_size.x() + Offset), box_half_size.y() + Offset, 0.0 };
|
||||
m_grabbers[9].color = (use_constrain && m_hover_id == 7) ? CONSTRAINED_COLOR : m_highlight_color;
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
m_grabbers[i].matrix = m_grabbers_transform;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
|
@ -3,16 +3,10 @@
|
|||
|
||||
#include "GLGizmoBase.hpp"
|
||||
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
class Selection;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
class GLGizmoScale3D : public GLGizmoBase
|
||||
{
|
||||
|
@ -23,28 +17,17 @@ class GLGizmoScale3D : public GLGizmoBase
|
|||
bool ctrl_down{ false };
|
||||
Vec3d scale{ Vec3d::Ones() };
|
||||
Vec3d drag_position{ Vec3d::Zero() };
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d center{ Vec3d::Zero() };
|
||||
Vec3d instance_center{ Vec3d::Zero() };
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
Vec3d constraint_position{ Vec3d::Zero() };
|
||||
BoundingBoxf3 box;
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
std::array<Vec3d, 6> pivots{ Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero() };
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
};
|
||||
|
||||
BoundingBoxf3 m_bounding_box;
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Transform3d m_grabbers_transform;
|
||||
Vec3d m_center{ Vec3d::Zero() };
|
||||
Vec3d m_instance_center{ Vec3d::Zero() };
|
||||
#else
|
||||
Transform3d m_transform;
|
||||
// Transforms grabbers offsets to the proper reference system (world for instances, instance for volumes)
|
||||
Transform3d m_offsets_transform;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
Vec3d m_scale{ Vec3d::Ones() };
|
||||
Vec3d m_offset{ Vec3d::Zero() };
|
||||
double m_snap_step{ 0.05 };
|
||||
StartingData m_starting;
|
||||
|
||||
|
@ -67,11 +50,7 @@ public:
|
|||
void set_snap_step(double step) { m_snap_step = step; }
|
||||
|
||||
const Vec3d& get_scale() const { return m_scale; }
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = scale; m_offset = Vec3d::Zero(); }
|
||||
#else
|
||||
void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = scale; }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
std::string get_tooltip() const override;
|
||||
|
||||
|
@ -102,6 +81,7 @@ private:
|
|||
void do_scale_uniform(const UpdateData& data);
|
||||
|
||||
double calc_ratio(const UpdateData& data) const;
|
||||
void update_render_data();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -167,11 +167,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection)
|
|||
trafo.translation()(2) += shift_z;
|
||||
const Geometry::Transformation transformation{trafo};
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d instance_scaling_matrix_inverse = transformation.get_scaling_factor_matrix().inverse();
|
||||
#else
|
||||
const Transform3d& instance_scaling_matrix_inverse = transformation.get_matrix(true, true, false, true).inverse();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
|
|
@ -436,11 +436,7 @@ std::vector<unsigned> MeshRaycaster::get_unobscured_idxs(const Geometry::Transfo
|
|||
{
|
||||
std::vector<unsigned> out;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Transform3d instance_matrix_no_translation_no_scaling = trafo.get_rotation_matrix();
|
||||
#else
|
||||
const Transform3d& instance_matrix_no_translation_no_scaling = trafo.get_matrix(true,false,true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
Vec3d direction_to_camera = -camera.get_dir_forward();
|
||||
Vec3d direction_to_camera_mesh = (instance_matrix_no_translation_no_scaling.inverse() * direction_to_camera).normalized().eval();
|
||||
direction_to_camera_mesh = direction_to_camera_mesh.cwiseProduct(trafo.get_scaling_factor());
|
||||
|
|
|
@ -60,9 +60,7 @@
|
|||
#include "GUI_ObjectManipulation.hpp"
|
||||
#include "GUI_ObjectLayers.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#include "GUI_Geometry.hpp"
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
#include "GUI_Factories.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
|
@ -1543,10 +1541,8 @@ void Sidebar::update_mode()
|
|||
|
||||
wxWindowUpdateLocker noUpdates(this);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (m_mode == comSimple)
|
||||
p->object_manipulation->set_coordinates_type(ECoordinatesType::World);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
p->object_list->get_sizer()->Show(m_mode > comSimple);
|
||||
|
||||
|
@ -2112,9 +2108,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this);
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this);
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); });
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_RESET_SKEW, [this](SimpleEvent&) { update(); });
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent&) { update(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event<bool>& evt) { this->sidebar->enable_buttons(evt.data); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_GEOMETRY, &priv::on_update_geometry, this);
|
||||
|
@ -3535,11 +3529,7 @@ bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const
|
|||
new_volume->set_type(old_volume->type());
|
||||
new_volume->set_material_id(old_volume->material_id());
|
||||
new_volume->set_transformation(old_volume->get_transformation());
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix_no_offset() * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
#else
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
assert(!old_volume->source.is_converted_from_inches || !old_volume->source.is_converted_from_meters);
|
||||
if (old_volume->source.is_converted_from_inches)
|
||||
new_volume->convert_from_imperial_units();
|
||||
|
@ -3820,19 +3810,12 @@ void Plater::priv::reload_from_disk()
|
|||
new_volume->config.apply(old_volume->config);
|
||||
new_volume->set_type(old_volume->type());
|
||||
new_volume->set_material_id(old_volume->material_id());
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
new_volume->set_transformation(
|
||||
old_volume->get_transformation().get_matrix() *
|
||||
old_volume->source.transform.get_matrix_no_offset() *
|
||||
Geometry::translation_transform(new_volume->source.mesh_offset - old_volume->source.mesh_offset) *
|
||||
new_volume->source.transform.get_matrix_no_offset().inverse()
|
||||
);
|
||||
#else
|
||||
new_volume->set_transformation(Geometry::assemble_transform(old_volume->source.transform.get_offset()) *
|
||||
old_volume->get_transformation().get_matrix(true) *
|
||||
old_volume->source.transform.get_matrix(true));
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
new_volume->source.object_idx = old_volume->source.object_idx;
|
||||
new_volume->source.volume_idx = old_volume->source.volume_idx;
|
||||
assert(!old_volume->source.is_converted_from_inches || !old_volume->source.is_converted_from_meters);
|
||||
|
@ -4361,11 +4344,7 @@ void Plater::priv::on_right_click(RBtnEvent& evt)
|
|||
const bool is_some_full_instances = selection.is_single_full_instance() ||
|
||||
selection.is_single_full_object() ||
|
||||
selection.is_multiple_full_instance();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const bool is_part = selection.is_single_volume_or_modifier() && ! selection.is_any_connector();
|
||||
#else
|
||||
const bool is_part = selection.is_single_volume() || selection.is_single_modifier();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
if (is_some_full_instances)
|
||||
menu = printer_technology == ptSLA ? menus.sla_object_menu() : menus.object_menu();
|
||||
else if (is_part)
|
||||
|
@ -4663,11 +4642,7 @@ bool Plater::priv::layers_height_allowed() const
|
|||
|
||||
bool Plater::priv::can_mirror() const
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
return !sidebar->obj_list()->has_selected_cut_object();
|
||||
#else
|
||||
return !sidebar->obj_list()->has_selected_cut_object() && get_selection().is_from_single_instance();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
#include "GUI_ObjectList.hpp"
|
||||
#include "Camera.hpp"
|
||||
#include "Plater.hpp"
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#include "MsgDialog.hpp"
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#include "Gizmos/GLGizmoBase.hpp"
|
||||
|
||||
|
@ -40,18 +38,11 @@ Selection::VolumeCache::TransformCache::TransformCache(const Geometry::Transform
|
|||
, scaling_factor(transform.get_scaling_factor())
|
||||
, mirror(transform.get_mirror())
|
||||
, full_matrix(transform.get_matrix())
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
, transform(transform)
|
||||
, rotation_matrix(transform.get_rotation_matrix())
|
||||
, scale_matrix(transform.get_scaling_factor_matrix())
|
||||
, mirror_matrix(transform.get_mirror_matrix())
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
{
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
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_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
Selection::VolumeCache::VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform)
|
||||
|
@ -118,12 +109,10 @@ Selection::Selection()
|
|||
, m_scale_factor(1.0f)
|
||||
{
|
||||
this->set_bounding_boxes_dirty();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_axes.set_stem_radius(0.5f);
|
||||
m_axes.set_stem_length(20.0f);
|
||||
m_axes.set_tip_radius(1.5f);
|
||||
m_axes.set_tip_length(5.0f);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
|
||||
|
@ -595,11 +584,7 @@ bool Selection::is_sla_compliant() const
|
|||
|
||||
bool Selection::is_single_text() const
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (!is_single_volume_or_modifier())
|
||||
#else
|
||||
if (!is_single_volume() && !is_single_modifier())
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
return false;
|
||||
|
||||
const GLVolume* gl_volume = (*m_volumes)[*m_list.begin()];
|
||||
|
@ -653,16 +638,6 @@ bool Selection::matches(const std::vector<unsigned int>& volume_idxs) const
|
|||
return count == (unsigned int)m_list.size();
|
||||
}
|
||||
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
bool Selection::requires_uniform_scale() const
|
||||
{
|
||||
if (is_single_full_instance() || is_single_modifier() || is_single_volume())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
int Selection::get_object_idx() const
|
||||
{
|
||||
return (m_cache.content.size() == 1) ? m_cache.content.begin()->first : -1;
|
||||
|
@ -721,11 +696,7 @@ const BoundingBoxf3& Selection::get_unscaled_instance_bounding_box() const
|
|||
const GLVolume& volume = *(*m_volumes)[i];
|
||||
if (volume.is_modifier)
|
||||
continue;
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Transform3d trafo = volume.get_instance_transformation().get_matrix_no_scaling_factor() * volume.get_volume_transformation().get_matrix();
|
||||
#else
|
||||
Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, true, false) * volume.get_volume_transformation().get_matrix();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
trafo.translation().z() += volume.get_sla_shift_z();
|
||||
(*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
|
||||
}
|
||||
|
@ -755,7 +726,6 @@ const BoundingBoxf3& Selection::get_scaled_instance_bounding_box() const
|
|||
return *m_scaled_instance_bounding_box;
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const BoundingBoxf3& Selection::get_full_unscaled_instance_bounding_box() const
|
||||
{
|
||||
assert(is_single_full_instance());
|
||||
|
@ -886,9 +856,7 @@ std::pair<BoundingBoxf3, Transform3d> Selection::get_bounding_box_in_reference_s
|
|||
const Vec3d center = 0.5 * (min + max);
|
||||
out_trafo.set_offset(basis_trafo * center);
|
||||
return { out_box, out_trafo.get_matrix_no_scaling_factor() };
|
||||
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Selection::setup_cache()
|
||||
{
|
||||
|
@ -898,7 +866,6 @@ void Selection::setup_cache()
|
|||
set_caches();
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Selection::translate(const Vec3d& displacement, TransformationType transformation_type)
|
||||
{
|
||||
if (!m_valid)
|
||||
|
@ -947,50 +914,8 @@ void Selection::translate(const Vec3d& displacement, TransformationType transfor
|
|||
set_bounding_boxes_dirty();
|
||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||
}
|
||||
#else
|
||||
void Selection::translate(const Vec3d& displacement, bool local)
|
||||
{
|
||||
if (!m_valid)
|
||||
return;
|
||||
|
||||
EMode translation_type = m_mode;
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume& v = *(*m_volumes)[i];
|
||||
if (m_mode == Volume || v.is_wipe_tower) {
|
||||
if (local)
|
||||
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement);
|
||||
else {
|
||||
const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||
}
|
||||
}
|
||||
else if (m_mode == Instance) {
|
||||
if (is_from_fully_selected_instance(i))
|
||||
v.set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
|
||||
else {
|
||||
const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||
translation_type = Volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
if (translation_type == Instance)
|
||||
synchronize_unselected_instances(SyncRotationType::NONE);
|
||||
else if (translation_type == Volume)
|
||||
synchronize_unselected_volumes();
|
||||
#endif // !DISABLE_INSTANCES_SYNCH
|
||||
|
||||
ensure_not_below_bed();
|
||||
set_bounding_boxes_dirty();
|
||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// Rotate an object around one of the axes. Only one rotation component is expected to be changing.
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type)
|
||||
{
|
||||
if (!m_valid)
|
||||
|
@ -1072,119 +997,6 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
|||
set_bounding_boxes_dirty();
|
||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||
}
|
||||
#else
|
||||
void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type)
|
||||
{
|
||||
if (!m_valid)
|
||||
return;
|
||||
|
||||
// Only relative rotation values are allowed in the world coordinate system.
|
||||
assert(!transformation_type.world() || transformation_type.relative());
|
||||
|
||||
if (!is_wipe_tower()) {
|
||||
int rot_axis_max = 0;
|
||||
if (rotation.isApprox(Vec3d::Zero())) {
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume &v = *(*m_volumes)[i];
|
||||
if (m_mode == Instance) {
|
||||
v.set_instance_rotation(m_cache.volumes_data[i].get_instance_rotation());
|
||||
v.set_instance_offset(m_cache.volumes_data[i].get_instance_position());
|
||||
}
|
||||
else if (m_mode == Volume) {
|
||||
v.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation());
|
||||
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position());
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // this is not the wipe tower
|
||||
//FIXME this does not work for absolute rotations (transformation_type.absolute() is true)
|
||||
rotation.cwiseAbs().maxCoeff(&rot_axis_max);
|
||||
|
||||
// if ( single instance or single volume )
|
||||
// Rotate around center , if only a single object or volume
|
||||
// transformation_type.set_independent();
|
||||
|
||||
// For generic rotation, we want to rotate the first volume in selection, and then to synchronize the other volumes with it.
|
||||
std::vector<int> object_instance_first(m_model->objects.size(), -1);
|
||||
auto rotate_instance = [this, &rotation, &object_instance_first, rot_axis_max, transformation_type](GLVolume &volume, int i) {
|
||||
const int first_volume_idx = object_instance_first[volume.object_idx()];
|
||||
if (rot_axis_max != 2 && first_volume_idx != -1) {
|
||||
// Generic rotation, but no rotation around the Z axis.
|
||||
// Always do a local rotation (do not consider the selection to be a rigid body).
|
||||
assert(is_approx(rotation.z(), 0.0));
|
||||
const GLVolume &first_volume = *(*m_volumes)[first_volume_idx];
|
||||
const Vec3d &rotation = first_volume.get_instance_rotation();
|
||||
const 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.x(), rotation.y(), rotation.z() + z_diff));
|
||||
}
|
||||
else {
|
||||
// extracts rotations from the composed transformation
|
||||
const Vec3d new_rotation = transformation_type.world() ?
|
||||
Geometry::extract_rotation(Geometry::assemble_transform(Vec3d::Zero(), rotation) * m_cache.volumes_data[i].get_instance_rotation_matrix()) :
|
||||
transformation_type.absolute() ? rotation : rotation + m_cache.volumes_data[i].get_instance_rotation();
|
||||
if (rot_axis_max == 2 && transformation_type.joint()) {
|
||||
// Only allow rotation of multiple instances as a single rigid body when rotating around the Z axis.
|
||||
const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), new_rotation);
|
||||
volume.set_instance_offset(m_cache.dragging_center + Eigen::AngleAxisd(z_diff, Vec3d::UnitZ()) * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
}
|
||||
volume.set_instance_rotation(new_rotation);
|
||||
object_instance_first[volume.object_idx()] = i;
|
||||
}
|
||||
};
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume &v = *(*m_volumes)[i];
|
||||
if (is_single_full_instance())
|
||||
rotate_instance(v, i);
|
||||
else if (is_single_volume() || is_single_modifier()) {
|
||||
if (transformation_type.independent())
|
||||
v.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation() + rotation);
|
||||
else {
|
||||
const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
const Vec3d new_rotation = Geometry::extract_rotation(m * m_cache.volumes_data[i].get_volume_rotation_matrix());
|
||||
v.set_volume_rotation(new_rotation);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_mode == Instance)
|
||||
rotate_instance(v, i);
|
||||
else if (m_mode == Volume) {
|
||||
// extracts rotations from the composed transformation
|
||||
const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation);
|
||||
const Vec3d new_rotation = Geometry::extract_rotation(m * m_cache.volumes_data[i].get_volume_rotation_matrix());
|
||||
if (transformation_type.joint()) {
|
||||
const Vec3d local_pivot = m_cache.volumes_data[i].get_instance_full_matrix().inverse() * m_cache.dragging_center;
|
||||
const Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() - local_pivot);
|
||||
v.set_volume_offset(local_pivot + offset);
|
||||
}
|
||||
v.set_volume_rotation(new_rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
if (m_mode == Instance)
|
||||
synchronize_unselected_instances((rot_axis_max == 2) ? SyncRotationType::NONE : SyncRotationType::GENERAL);
|
||||
else if (m_mode == Volume)
|
||||
synchronize_unselected_volumes();
|
||||
#endif // !DISABLE_INSTANCES_SYNCH
|
||||
}
|
||||
else { // it's the wipe tower that's selected and being rotated
|
||||
GLVolume& volume = *((*m_volumes)[*m_list.begin()]); // the wipe tower is always alone in the selection
|
||||
|
||||
// make sure the wipe tower rotates around its center, not origin
|
||||
// we can assume that only Z rotation changes
|
||||
const Vec3d center_local = volume.transformed_bounding_box().center() - volume.get_volume_offset();
|
||||
const Vec3d center_local_new = Eigen::AngleAxisd(rotation.z()-volume.get_volume_rotation().z(), Vec3d::UnitZ()) * center_local;
|
||||
volume.set_volume_rotation(rotation);
|
||||
volume.set_volume_offset(volume.get_volume_offset() + center_local - center_local_new);
|
||||
}
|
||||
|
||||
set_bounding_boxes_dirty();
|
||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Selection::flattening_rotate(const Vec3d& normal)
|
||||
{
|
||||
|
@ -1199,21 +1011,11 @@ void Selection::flattening_rotate(const Vec3d& normal)
|
|||
for (unsigned int i : m_list) {
|
||||
GLVolume& v = *(*m_volumes)[i];
|
||||
// Normal transformed from the object coordinate space to the world coordinate space.
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Geometry::Transformation& old_inst_trafo = v.get_instance_transformation();
|
||||
const Vec3d tnormal = old_inst_trafo.get_matrix().matrix().block(0, 0, 3, 3).inverse().transpose() * normal;
|
||||
// Additional rotation to align tnormal with the down vector in the world coordinate space.
|
||||
const Transform3d rotation_matrix = Transform3d(Eigen::Quaterniond().setFromTwoVectors(tnormal, -Vec3d::UnitZ()));
|
||||
v.set_instance_transformation(old_inst_trafo.get_offset_matrix() * rotation_matrix * old_inst_trafo.get_matrix_no_offset());
|
||||
#else
|
||||
const auto& voldata = m_cache.volumes_data[i];
|
||||
Vec3d tnormal = (Geometry::assemble_transform(
|
||||
Vec3d::Zero(), voldata.get_instance_rotation(),
|
||||
voldata.get_instance_scaling_factor().cwiseInverse(), voldata.get_instance_mirror()) * normal).normalized();
|
||||
// Additional rotation to align tnormal with the down vector in the world coordinate space.
|
||||
auto extra_rotation = Eigen::Quaterniond().setFromTwoVectors(tnormal, -Vec3d::UnitZ());
|
||||
v.set_instance_rotation(Geometry::extract_rotation(extra_rotation.toRotationMatrix() * m_cache.volumes_data[i].get_instance_rotation_matrix()));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
|
@ -1226,79 +1028,10 @@ void Selection::flattening_rotate(const Vec3d& normal)
|
|||
this->set_bounding_boxes_dirty();
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Selection::scale(const Vec3d& scale, TransformationType transformation_type)
|
||||
{
|
||||
scale_and_translate(scale, Vec3d::Zero(), transformation_type);
|
||||
}
|
||||
#else
|
||||
void Selection::scale(const Vec3d& scale, TransformationType transformation_type)
|
||||
{
|
||||
if (!m_valid)
|
||||
return;
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume &v = *(*m_volumes)[i];
|
||||
if (is_single_full_instance()) {
|
||||
if (transformation_type.relative()) {
|
||||
const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
|
||||
const Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3);
|
||||
// extracts scaling factors from the composed transformation
|
||||
const Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
||||
if (transformation_type.joint())
|
||||
v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
|
||||
v.set_instance_scaling_factor(new_scale);
|
||||
}
|
||||
else {
|
||||
if (transformation_type.world() && (std::abs(scale.x() - scale.y()) > EPSILON || std::abs(scale.x() - scale.z()) > EPSILON)) {
|
||||
// Non-uniform scaling. Transform the scaling factors into the local coordinate system.
|
||||
// This is only possible, if the instance rotation is mulitples of ninety degrees.
|
||||
assert(Geometry::is_rotation_ninety_degrees(v.get_instance_rotation()));
|
||||
v.set_instance_scaling_factor((v.get_instance_transformation().get_matrix(true, false, true, true).matrix().block<3, 3>(0, 0).transpose() * scale).cwiseAbs());
|
||||
}
|
||||
else
|
||||
v.set_instance_scaling_factor(scale);
|
||||
}
|
||||
}
|
||||
else if (is_single_volume() || is_single_modifier())
|
||||
v.set_volume_scaling_factor(scale);
|
||||
else {
|
||||
const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
|
||||
if (m_mode == Instance) {
|
||||
const Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3);
|
||||
// extracts scaling factors from the composed transformation
|
||||
const Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
||||
if (transformation_type.joint())
|
||||
v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
|
||||
v.set_instance_scaling_factor(new_scale);
|
||||
}
|
||||
else if (m_mode == Volume) {
|
||||
const Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_volume_scale_matrix()).matrix().block(0, 0, 3, 3);
|
||||
// extracts scaling factors from the composed transformation
|
||||
const Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
||||
if (transformation_type.joint()) {
|
||||
const Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() + m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center);
|
||||
v.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset);
|
||||
}
|
||||
v.set_volume_scaling_factor(new_scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
if (m_mode == Instance)
|
||||
synchronize_unselected_instances(SyncRotationType::NONE);
|
||||
else if (m_mode == Volume)
|
||||
synchronize_unselected_volumes();
|
||||
#endif // !DISABLE_INSTANCES_SYNCH
|
||||
|
||||
ensure_on_bed();
|
||||
set_bounding_boxes_dirty();
|
||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Selection::scale_to_fit_print_volume(const BuildVolume& volume)
|
||||
{
|
||||
|
@ -1322,13 +1055,9 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume)
|
|||
// center selection on print bed
|
||||
setup_cache();
|
||||
offset.z() = -get_bounding_box().min.z();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType trafo_type;
|
||||
trafo_type.set_relative();
|
||||
translate(offset, trafo_type);
|
||||
#else
|
||||
translate(offset);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
wxGetApp().plater()->canvas3D()->do_move(""); // avoid storing another snapshot
|
||||
|
||||
wxGetApp().obj_manipul()->set_dirty();
|
||||
|
@ -1423,39 +1152,13 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume)
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Selection::mirror(Axis axis, TransformationType transformation_type)
|
||||
{
|
||||
const Vec3d mirror((axis == X) ? -1.0 : 1.0, (axis == Y) ? -1.0 : 1.0, (axis == Z) ? -1.0 : 1.0);
|
||||
scale_and_translate(mirror, Vec3d::Zero(), transformation_type);
|
||||
}
|
||||
#else
|
||||
void Selection::mirror(Axis axis)
|
||||
{
|
||||
if (!m_valid)
|
||||
return;
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume& v = *(*m_volumes)[i];
|
||||
if (is_single_full_instance())
|
||||
v.set_instance_mirror(axis, -v.get_instance_mirror(axis));
|
||||
else if (m_mode == Volume)
|
||||
v.set_volume_mirror(axis, -v.get_volume_mirror(axis));
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
if (m_mode == Instance)
|
||||
synchronize_unselected_instances(SyncRotationType::NONE);
|
||||
else if (m_mode == Volume)
|
||||
synchronize_unselected_volumes();
|
||||
#endif // !DISABLE_INSTANCES_SYNCH
|
||||
|
||||
set_bounding_boxes_dirty();
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation, TransformationType transformation_type)
|
||||
void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& world_translation, TransformationType transformation_type)
|
||||
{
|
||||
if (!m_valid)
|
||||
return;
|
||||
|
@ -1489,32 +1192,28 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation
|
|||
const Vec3d local_inst_pivot = inst_trafo.get_matrix_no_offset().inverse() * world_inst_pivot;
|
||||
Matrix3d inst_rotation, inst_scale;
|
||||
inst_trafo.get_matrix().computeRotationScaling(&inst_rotation, &inst_scale);
|
||||
const Transform3d offset_trafo = Geometry::translation_transform(inst_trafo.get_offset() + inst_rotation * translation);
|
||||
const Transform3d offset_trafo = Geometry::translation_transform(inst_trafo.get_offset() + world_translation);
|
||||
const Transform3d scale_trafo = Transform3d(inst_scale) * Geometry::scale_transform(relative_scale);
|
||||
v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * offset_trafo * Transform3d(inst_rotation) * scale_trafo * Geometry::translation_transform(-local_inst_pivot));
|
||||
}
|
||||
else
|
||||
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center);
|
||||
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center);
|
||||
}
|
||||
else {
|
||||
if (!is_single_volume_or_modifier()) {
|
||||
assert(transformation_type.world());
|
||||
transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale), m_cache.dragging_center);
|
||||
transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(scale), m_cache.dragging_center);
|
||||
}
|
||||
else {
|
||||
if (transformation_type.local() && transformation_type.absolute()) {
|
||||
const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform();
|
||||
Matrix3d vol_rotation, vol_scale;
|
||||
vol_trafo.get_matrix().computeRotationScaling(&vol_rotation, &vol_scale);
|
||||
const Transform3d offset_trafo = Geometry::translation_transform(vol_trafo.get_offset() + vol_rotation * translation);
|
||||
const Transform3d scale_trafo = Transform3d(vol_scale) * Geometry::scale_transform(scale);
|
||||
v.set_volume_transformation(offset_trafo * Transform3d(vol_rotation) * scale_trafo);
|
||||
}
|
||||
else {
|
||||
transformation_type.set_independent();
|
||||
transformation_type.set_relative();
|
||||
transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale), m_cache.dragging_center);
|
||||
}
|
||||
transformation_type.set_independent();
|
||||
Vec3d translation;
|
||||
if (transformation_type.local())
|
||||
translation = volume_data.get_volume_transform().get_matrix_no_offset().inverse() * inst_trafo.get_matrix_no_offset().inverse() * world_translation;
|
||||
else if (transformation_type.instance())
|
||||
translation = inst_trafo.get_matrix_no_offset().inverse() * world_translation;
|
||||
else
|
||||
translation = world_translation;
|
||||
transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale), m_cache.dragging_center);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1592,50 +1291,6 @@ void Selection::reset_skew()
|
|||
set_bounding_boxes_dirty();
|
||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||
}
|
||||
#else
|
||||
void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
|
||||
{
|
||||
if (!m_valid)
|
||||
return;
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume& v = *(*m_volumes)[i];
|
||||
if (v.object_idx() == (int)object_idx)
|
||||
v.set_instance_offset(v.get_instance_offset() + displacement);
|
||||
}
|
||||
|
||||
std::set<unsigned int> done; // prevent processing volumes twice
|
||||
done.insert(m_list.begin(), m_list.end());
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
if ((*m_volumes)[i]->is_wipe_tower)
|
||||
continue;
|
||||
|
||||
int object_idx = (*m_volumes)[i]->object_idx();
|
||||
|
||||
// Process unselected volumes of the object.
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
if (done.find(j) != done.end())
|
||||
continue;
|
||||
|
||||
GLVolume& v = *(*m_volumes)[j];
|
||||
if (v.object_idx() != object_idx)
|
||||
continue;
|
||||
|
||||
v.set_instance_offset(v.get_instance_offset() + displacement);
|
||||
done.insert(j);
|
||||
}
|
||||
}
|
||||
|
||||
this->set_bounding_boxes_dirty();
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Selection::translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement)
|
||||
{
|
||||
|
@ -1645,11 +1300,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
|
|||
for (unsigned int i : m_list) {
|
||||
GLVolume& v = *(*m_volumes)[i];
|
||||
if (v.object_idx() == (int)object_idx && v.instance_idx() == (int)instance_idx)
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
v.set_instance_transformation(Geometry::translation_transform(displacement) * v.get_instance_transformation().get_matrix());
|
||||
#else
|
||||
v.set_instance_offset(v.get_instance_offset() + displacement);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
|
||||
std::set<unsigned int> done; // prevent processing volumes twice
|
||||
|
@ -1676,11 +1327,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
|
|||
if (v.object_idx() != object_idx || v.instance_idx() != (int)instance_idx)
|
||||
continue;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
v.set_instance_transformation(Geometry::translation_transform(displacement) * v.get_instance_transformation().get_matrix());
|
||||
#else
|
||||
v.set_instance_offset(v.get_instance_offset() + displacement);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
done.insert(j);
|
||||
}
|
||||
}
|
||||
|
@ -1688,7 +1335,6 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
|
|||
this->set_bounding_boxes_dirty();
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
int Selection::bake_transform_if_needed() const
|
||||
{
|
||||
if ((is_single_full_instance() && wxGetApp().obj_manipul()->is_world_coordinates()) ||
|
||||
|
@ -1739,7 +1385,6 @@ int Selection::bake_transform_if_needed() const
|
|||
|
||||
return 1;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Selection::erase()
|
||||
{
|
||||
|
@ -1853,12 +1498,8 @@ void Selection::render(float scale_factor)
|
|||
|
||||
m_scale_factor = scale_factor;
|
||||
// render cumulative bounding box of selected volumes
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const auto& [box, trafo] = get_bounding_box_in_current_reference_system();
|
||||
render_bounding_box(box, trafo, ColorRGB::WHITE());
|
||||
#else
|
||||
render_bounding_box(get_bounding_box(), ColorRGB::WHITE());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
render_synchronized_volumes();
|
||||
}
|
||||
|
||||
|
@ -1907,39 +1548,15 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field)
|
|||
const Transform3d base_matrix = Geometry::translation_transform(get_bounding_box().center());
|
||||
Transform3d orient_matrix = Transform3d::Identity();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Vec3d center = get_bounding_box().center();
|
||||
Vec3d axes_center = center;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
if (!boost::starts_with(sidebar_field, "layer")) {
|
||||
shader->set_uniform("emission_factor", 0.05f);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (is_single_full_instance() && !wxGetApp().obj_manipul()->is_world_coordinates()) {
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
||||
axes_center = (*m_volumes)[*m_list.begin()]->get_instance_offset();
|
||||
#else
|
||||
const Vec3d& center = get_bounding_box().center();
|
||||
if (is_single_full_instance() && !wxGetApp().obj_manipul()->get_world_coordinates()) {
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
if (!boost::starts_with(sidebar_field, "position")) {
|
||||
if (boost::starts_with(sidebar_field, "scale"))
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
else if (boost::starts_with(sidebar_field, "rotation")) {
|
||||
if (boost::ends_with(sidebar_field, "x"))
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
else if (boost::ends_with(sidebar_field, "y")) {
|
||||
const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation();
|
||||
if (rotation.x() == 0.0)
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
else
|
||||
orient_matrix.rotate(Eigen::AngleAxisd(rotation.z(), Vec3d::UnitZ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
else if (is_single_volume_or_modifier()) {
|
||||
if (!wxGetApp().obj_manipul()->is_world_coordinates()) {
|
||||
if (wxGetApp().obj_manipul()->is_local_coordinates()) {
|
||||
|
@ -1952,32 +1569,18 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field)
|
|||
axes_center = (*m_volumes)[*m_list.begin()]->get_instance_offset();
|
||||
}
|
||||
}
|
||||
#else
|
||||
else if (is_single_volume() || is_single_modifier()) {
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
if (!boost::starts_with(sidebar_field, "position"))
|
||||
orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_matrix(true, false, true, true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
else {
|
||||
if (requires_local_axes())
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
||||
#else
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
}
|
||||
|
||||
if (!boost::starts_with(sidebar_field, "layer"))
|
||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (!boost::starts_with(sidebar_field, "layer")) {
|
||||
if (!boost::starts_with(sidebar_field, "layer"))
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
if (boost::starts_with(sidebar_field, "position"))
|
||||
render_sidebar_position_hints(sidebar_field, *shader, base_matrix * orient_matrix);
|
||||
|
@ -1988,12 +1591,10 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field)
|
|||
else if (boost::starts_with(sidebar_field, "layer"))
|
||||
render_sidebar_layers_hints(sidebar_field, *shader);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (!boost::starts_with(sidebar_field, "layer")) {
|
||||
if (wxGetApp().obj_manipul()->is_instance_coordinates())
|
||||
m_axes.render(Geometry::translation_transform(axes_center) * orient_matrix, 0.25f);
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
|
@ -2434,11 +2035,9 @@ void Selection::render_synchronized_volumes()
|
|||
if (m_mode == Instance)
|
||||
return;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||
BoundingBoxf3 box;
|
||||
Transform3d trafo;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
const GLVolume& volume = *(*m_volumes)[i];
|
||||
|
@ -2452,7 +2051,6 @@ void Selection::render_synchronized_volumes()
|
|||
if (v.object_idx() != object_idx || v.volume_idx() != volume_idx)
|
||||
continue;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (coordinates_type == ECoordinatesType::World) {
|
||||
box = v.transformed_convex_hull_bounding_box();
|
||||
trafo = Transform3d::Identity();
|
||||
|
@ -2466,18 +2064,11 @@ void Selection::render_synchronized_volumes()
|
|||
trafo = v.get_instance_transformation().get_matrix();
|
||||
}
|
||||
render_bounding_box(box, trafo, ColorRGB::YELLOW());
|
||||
#else
|
||||
render_bounding_box(v.transformed_convex_hull_bounding_box(), ColorRGB::YELLOW());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Selection::render_bounding_box(const BoundingBoxf3& box, const Transform3d& trafo, const ColorRGB& color)
|
||||
#else
|
||||
void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color)
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
{
|
||||
const BoundingBoxf3& curr_box = m_box.get_bounding_box();
|
||||
|
||||
|
@ -2574,11 +2165,7 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& co
|
|||
|
||||
shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo);
|
||||
#else
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
|
@ -2660,11 +2247,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field,
|
|||
|
||||
void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const bool uniform_scale = wxGetApp().obj_manipul()->get_uniform_scaling();
|
||||
#else
|
||||
const bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis, GLShaderProgram& shader, const Transform3d& view_matrix, const Transform3d& model_matrix) {
|
||||
m_arrow.set_color(uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis));
|
||||
|
@ -2796,7 +2379,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field, GL
|
|||
glsafe(::glDisable(GL_BLEND));
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_DEBUG
|
||||
#if ENABLE_MATRICES_DEBUG
|
||||
void Selection::render_debug_window() const
|
||||
{
|
||||
if (m_list.empty())
|
||||
|
@ -2916,7 +2499,7 @@ void Selection::render_debug_window() const
|
|||
|
||||
imgui.end();
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE_DEBUG
|
||||
#endif // ENABLE_MATRICES_DEBUG
|
||||
|
||||
static bool is_left_handed(const Transform3d::ConstLinearPart& m)
|
||||
{
|
||||
|
@ -3015,7 +2598,6 @@ static void verify_instances_rotation_synchronized(const Model &model, const GLV
|
|||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_type)
|
||||
{
|
||||
std::set<unsigned int> done; // prevent processing volumes twice
|
||||
|
@ -3064,69 +2646,6 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
|
|||
verify_instances_rotation_synchronized(*m_model, *m_volumes);
|
||||
#endif /* NDEBUG */
|
||||
}
|
||||
#else
|
||||
void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_type)
|
||||
{
|
||||
std::set<unsigned int> done; // prevent processing volumes twice
|
||||
done.insert(m_list.begin(), m_list.end());
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
const GLVolume* volume_i = (*m_volumes)[i];
|
||||
if (volume_i->is_wipe_tower)
|
||||
continue;
|
||||
|
||||
const int object_idx = volume_i->object_idx();
|
||||
const int instance_idx = volume_i->instance_idx();
|
||||
const Vec3d& rotation = volume_i->get_instance_rotation();
|
||||
const Vec3d& scaling_factor = volume_i->get_instance_scaling_factor();
|
||||
const Vec3d& mirror = volume_i->get_instance_mirror();
|
||||
|
||||
// Process unselected instances.
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
|
||||
if (done.size() == m_volumes->size())
|
||||
break;
|
||||
|
||||
if (done.find(j) != done.end())
|
||||
continue;
|
||||
|
||||
GLVolume* volume_j = (*m_volumes)[j];
|
||||
if (volume_j->object_idx() != object_idx || volume_j->instance_idx() == instance_idx)
|
||||
continue;
|
||||
|
||||
assert(is_rotation_xy_synchronized(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation()));
|
||||
|
||||
switch (sync_rotation_type) {
|
||||
case SyncRotationType::NONE: {
|
||||
// z only rotation -> synch instance z
|
||||
// The X,Y rotations should be synchronized from start to end of the rotation.
|
||||
assert(is_rotation_xy_synchronized(rotation, volume_j->get_instance_rotation()));
|
||||
if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA)
|
||||
volume_j->set_instance_offset(Z, volume_i->get_instance_offset().z());
|
||||
break;
|
||||
}
|
||||
case SyncRotationType::GENERAL: {
|
||||
// generic rotation -> update instance z with the delta of the rotation.
|
||||
const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation());
|
||||
volume_j->set_instance_rotation({ rotation.x(), rotation.y(), rotation.z() + z_diff });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
volume_j->set_instance_scaling_factor(scaling_factor);
|
||||
volume_j->set_instance_mirror(mirror);
|
||||
|
||||
done.insert(j);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
verify_instances_rotation_synchronized(*m_model, *m_volumes);
|
||||
#endif /* NDEBUG */
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void Selection::synchronize_unselected_volumes()
|
||||
{
|
||||
|
@ -3137,14 +2656,7 @@ void Selection::synchronize_unselected_volumes()
|
|||
|
||||
const int object_idx = volume->object_idx();
|
||||
const int volume_idx = volume->volume_idx();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Geometry::Transformation& trafo = volume->get_volume_transformation();
|
||||
#else
|
||||
const Vec3d& offset = volume->get_volume_offset();
|
||||
const Vec3d& rotation = volume->get_volume_rotation();
|
||||
const Vec3d& scaling_factor = volume->get_volume_scaling_factor();
|
||||
const Vec3d& mirror = volume->get_volume_mirror();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// Process unselected volumes.
|
||||
for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
|
||||
|
@ -3155,14 +2667,7 @@ void Selection::synchronize_unselected_volumes()
|
|||
if (v->object_idx() != object_idx || v->volume_idx() != volume_idx)
|
||||
continue;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
v->set_volume_transformation(trafo);
|
||||
#else
|
||||
v->set_volume_offset(offset);
|
||||
v->set_volume_rotation(rotation);
|
||||
v->set_volume_scaling_factor(scaling_factor);
|
||||
v->set_volume_mirror(mirror);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3282,13 +2787,8 @@ void Selection::paste_volumes_from_clipboard()
|
|||
{
|
||||
ModelInstance* dst_instance = dst_object->instances[dst_inst_idx];
|
||||
BoundingBoxf3 dst_instance_bb = dst_object->instance_bounding_box(dst_inst_idx);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Transform3d src_matrix = src_object->instances[0]->get_transformation().get_matrix_no_offset();
|
||||
Transform3d dst_matrix = dst_instance->get_transformation().get_matrix_no_offset();
|
||||
#else
|
||||
Transform3d src_matrix = src_object->instances[0]->get_transformation().get_matrix(true);
|
||||
Transform3d dst_matrix = dst_instance->get_transformation().get_matrix(true);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
bool from_same_object = (src_object->input_file == dst_object->input_file) && src_matrix.isApprox(dst_matrix);
|
||||
|
||||
// used to keep relative position of multivolume selections when pasting from another object
|
||||
|
@ -3366,7 +2866,6 @@ void Selection::paste_objects_from_clipboard()
|
|||
#endif /* _DEBUG */
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Selection::transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||
const Transform3d& transform, const Vec3d& world_pivot)
|
||||
{
|
||||
|
@ -3408,7 +2907,6 @@ void Selection::transform_volume_relative(GLVolume& volume, const VolumeCache& v
|
|||
else
|
||||
assert(false);
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
#define slic3r_GUI_Selection_hpp_
|
||||
|
||||
#include "libslic3r/Geometry.hpp"
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#include "GUI_Geometry.hpp"
|
||||
#include "CoordAxes.hpp"
|
||||
#else
|
||||
#include "GLModel.hpp"
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#include <set>
|
||||
#include <optional>
|
||||
|
@ -29,60 +25,6 @@ using ModelObjectPtrs = std::vector<ModelObject*>;
|
|||
|
||||
|
||||
namespace GUI {
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
class TransformationType
|
||||
{
|
||||
public:
|
||||
enum Enum {
|
||||
// Transforming in a world coordinate system
|
||||
World = 0,
|
||||
// Transforming in a local coordinate system
|
||||
Local = 1,
|
||||
// Absolute transformations, allowed in local coordinate system only.
|
||||
Absolute = 0,
|
||||
// Relative transformations, allowed in both local and world coordinate system.
|
||||
Relative = 2,
|
||||
// For group selection, the transformation is performed as if the group made a single solid body.
|
||||
Joint = 0,
|
||||
// For group selection, the transformation is performed on each object independently.
|
||||
Independent = 4,
|
||||
|
||||
World_Relative_Joint = World | Relative | Joint,
|
||||
World_Relative_Independent = World | Relative | Independent,
|
||||
Local_Absolute_Joint = Local | Absolute | Joint,
|
||||
Local_Absolute_Independent = Local | Absolute | Independent,
|
||||
Local_Relative_Joint = Local | Relative | Joint,
|
||||
Local_Relative_Independent = Local | Relative | Independent,
|
||||
};
|
||||
|
||||
TransformationType() : m_value(World) {}
|
||||
TransformationType(Enum value) : m_value(value) {}
|
||||
TransformationType& operator=(Enum value) { m_value = value; return *this; }
|
||||
|
||||
Enum operator()() const { return m_value; }
|
||||
bool has(Enum v) const { return ((unsigned int)m_value & (unsigned int)v) != 0; }
|
||||
|
||||
void set_world() { this->remove(Local); }
|
||||
void set_local() { this->add(Local); }
|
||||
void set_absolute() { this->remove(Relative); }
|
||||
void set_relative() { this->add(Relative); }
|
||||
void set_joint() { this->remove(Independent); }
|
||||
void set_independent() { this->add(Independent); }
|
||||
|
||||
bool world() const { return !this->has(Local); }
|
||||
bool local() const { return this->has(Local); }
|
||||
bool absolute() const { return !this->has(Relative); }
|
||||
bool relative() const { return this->has(Relative); }
|
||||
bool joint() const { return !this->has(Independent); }
|
||||
bool independent() const { return this->has(Independent); }
|
||||
|
||||
private:
|
||||
void add(Enum v) { m_value = Enum((unsigned int)m_value | (unsigned int)v); }
|
||||
void remove(Enum v) { m_value = Enum((unsigned int)m_value & (~(unsigned int)v)); }
|
||||
|
||||
Enum m_value;
|
||||
};
|
||||
#endif // !ENABLE_WORLD_COORDINATE
|
||||
|
||||
class Selection
|
||||
{
|
||||
|
@ -125,9 +67,7 @@ private:
|
|||
Transform3d scale_matrix{ Transform3d::Identity() };
|
||||
Transform3d mirror_matrix{ Transform3d::Identity() };
|
||||
Transform3d full_matrix{ Transform3d::Identity() };
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Geometry::Transformation transform;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
TransformCache() = default;
|
||||
explicit TransformCache(const Geometry::Transformation& transform);
|
||||
|
@ -141,18 +81,11 @@ private:
|
|||
VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform);
|
||||
|
||||
const Vec3d& get_volume_position() const { return m_volume.position; }
|
||||
#if !ENABLE_WORLD_COORDINATE
|
||||
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_WORLD_COORDINATE
|
||||
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_WORLD_COORDINATE
|
||||
const Geometry::Transformation& get_volume_transform() const { return m_volume.transform; }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
const Vec3d& get_instance_position() const { return m_instance.position; }
|
||||
const Vec3d& get_instance_rotation() const { return m_instance.rotation; }
|
||||
|
@ -162,9 +95,7 @@ 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_WORLD_COORDINATE
|
||||
const Geometry::Transformation& get_instance_transform() const { return m_instance.transform; }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -232,7 +163,6 @@ private:
|
|||
// Bounding box of a single full instance selection, in world coordinates.
|
||||
// Modifiers are NOT taken in account
|
||||
std::optional<BoundingBoxf3> m_scaled_instance_bounding_box;
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
// Bounding box of a single full instance selection, in world coordinates, with no instance scaling applied.
|
||||
// Modifiers are taken in account
|
||||
std::optional<BoundingBoxf3> m_full_unscaled_instance_bounding_box;
|
||||
|
@ -245,15 +175,12 @@ private:
|
|||
// 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;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_RENDER_SELECTION_CENTER
|
||||
GLModel m_vbo_sphere;
|
||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
CoordAxes m_axes;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
GLModel m_arrow;
|
||||
GLModel m_curved_arrow;
|
||||
GLModel m_box;
|
||||
|
@ -328,9 +255,7 @@ public:
|
|||
bool is_from_single_object() const;
|
||||
bool is_sla_compliant() const;
|
||||
bool is_instance_mode() const { return m_mode == Instance; }
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
bool is_single_volume_or_modifier() const { return is_single_volume() || is_single_modifier(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
bool is_single_volume_instance() const { return is_single_full_instance() && m_list.size() == 1; }
|
||||
bool is_single_text() const;
|
||||
|
||||
|
@ -344,7 +269,6 @@ public:
|
|||
// returns true if the selection contains all and only the given indices
|
||||
bool matches(const std::vector<unsigned int>& volume_idxs) const;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
enum class EUniformScaleRequiredReason : unsigned char
|
||||
{
|
||||
NotRequired,
|
||||
|
@ -353,9 +277,6 @@ public:
|
|||
VolumeNotAxisAligned_Instance,
|
||||
MultipleSelection,
|
||||
};
|
||||
#else
|
||||
bool requires_uniform_scale() const;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
// Returns the the object id if the selection is from a single object, otherwise is -1
|
||||
int get_object_idx() const;
|
||||
|
@ -381,7 +302,6 @@ public:
|
|||
// Bounding box of a single full instance selection, in world coordinates.
|
||||
// Modifiers are NOT taken in account
|
||||
const BoundingBoxf3& get_scaled_instance_bounding_box() const;
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
// Bounding box of a single full instance selection, in world coordinates, with no instance scaling applied.
|
||||
// Modifiers are taken in account
|
||||
const BoundingBoxf3& get_full_unscaled_instance_bounding_box() const;
|
||||
|
@ -397,36 +317,24 @@ public:
|
|||
// 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;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void setup_cache();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void translate(const Vec3d& displacement, TransformationType transformation_type);
|
||||
#else
|
||||
void translate(const Vec3d& displacement, bool local = false);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
void rotate(const Vec3d& rotation, TransformationType transformation_type);
|
||||
void flattening_rotate(const Vec3d& normal);
|
||||
void scale(const Vec3d& scale, TransformationType transformation_type);
|
||||
void scale_to_fit_print_volume(const BuildVolume& volume);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void scale_and_translate(const Vec3d& scale, const Vec3d& translation, TransformationType transformation_type);
|
||||
void scale_and_translate(const Vec3d& scale, const Vec3d& world_translation, TransformationType transformation_type);
|
||||
void mirror(Axis axis, TransformationType transformation_type);
|
||||
void reset_skew();
|
||||
#else
|
||||
void mirror(Axis axis);
|
||||
void translate(unsigned int object_idx, const Vec3d& displacement);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
void translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
// returns:
|
||||
// -1 if the user refused to proceed with baking when asked
|
||||
// 0 if the baking was performed
|
||||
// 1 if no baking was needed
|
||||
int bake_transform_if_needed() const;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
void erase();
|
||||
|
||||
|
@ -456,9 +364,9 @@ public:
|
|||
// returns the list of idxs of the objects which are in the selection
|
||||
std::set<unsigned int> get_object_idxs() const;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_DEBUG
|
||||
#if ENABLE_MATRICES_DEBUG
|
||||
void render_debug_window() const;
|
||||
#endif // ENABLE_WORLD_COORDINATE_DEBUG
|
||||
#endif // ENABLE_MATRICES_DEBUG
|
||||
|
||||
private:
|
||||
void update_valid();
|
||||
|
@ -469,7 +377,6 @@ 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);
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void set_bounding_boxes_dirty() {
|
||||
m_bounding_box.reset();
|
||||
m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset();
|
||||
|
@ -477,15 +384,8 @@ private:
|
|||
m_full_unscaled_instance_local_bounding_box.reset();
|
||||
m_bounding_box_in_current_reference_system.reset();
|
||||
}
|
||||
#else
|
||||
void set_bounding_boxes_dirty() { m_bounding_box.reset(); m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset(); }
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
void render_synchronized_volumes();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void render_bounding_box(const BoundingBoxf3& box, const Transform3d& trafo, const ColorRGB& color);
|
||||
#else
|
||||
void render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
void render_selected_volumes() const;
|
||||
void render_bounding_box(const BoundingBoxf3& box, float* color) const;
|
||||
void render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix);
|
||||
|
@ -499,10 +399,8 @@ public:
|
|||
NONE = 0,
|
||||
// Synchronize after rotation by an axis not parallel with Z.
|
||||
GENERAL = 1,
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
// Synchronize after rotation reset.
|
||||
RESET = 2
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
};
|
||||
void synchronize_unselected_instances(SyncRotationType sync_rotation_type);
|
||||
void synchronize_unselected_volumes();
|
||||
|
@ -515,12 +413,10 @@ private:
|
|||
void paste_volumes_from_clipboard();
|
||||
void paste_objects_from_clipboard();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||
const Transform3d& transform, const Vec3d& world_pivot);
|
||||
void transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||
const Transform3d& transform, const Vec3d& world_pivot);
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
@ -552,13 +552,7 @@ void LockButton::OnButton(wxCommandEvent& event)
|
|||
if (m_disabled)
|
||||
return;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
SetLock(!m_is_pushed);
|
||||
#else
|
||||
m_is_pushed = !m_is_pushed;
|
||||
update_button_bitmaps();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue