ENH: rewrite ModelInstance::rotate with rotation matrix
1. Rotation operation should always work on rotation matrix. Euler angles are not reliable. 2. Remove the ambiguous set_rotation on single euler angle. 3. Fix the bug that the rotation of the mirrored object is not correct. jira: STUDIO-8752 Change-Id: I25d661b732a872b8378af87c0ba52d75afd75c1f
This commit is contained in:
parent
fff7873456
commit
f9a1ed7b24
|
@ -459,6 +459,13 @@ const Vec3d &Transformation::get_rotation_by_quaternion() const
|
|||
|
||||
Transform3d Transformation::get_rotation_matrix() const { return extract_rotation_matrix(m_matrix); }
|
||||
|
||||
void Transformation::set_rotation_matrix(const Transform3d &rot_mat)
|
||||
{
|
||||
const Vec3d offset = get_offset();
|
||||
m_matrix = rot_mat * extract_scale(m_matrix);
|
||||
m_matrix.translation() = offset;
|
||||
}
|
||||
|
||||
void Transformation::set_rotation(const Vec3d &rotation)
|
||||
{
|
||||
const Vec3d offset = get_offset();
|
||||
|
@ -466,20 +473,6 @@ void Transformation::set_rotation(const Vec3d &rotation)
|
|||
m_matrix.translation() = offset;
|
||||
}
|
||||
|
||||
void Transformation::set_rotation(Axis axis, double rotation)
|
||||
{
|
||||
rotation = angle_to_0_2PI(rotation);
|
||||
if (is_approx(std::abs(rotation), 2.0 * double(PI))) rotation = 0.0;
|
||||
|
||||
auto [curr_rotation, scale] = extract_rotation_scale(m_matrix);
|
||||
Vec3d angles = extract_rotation(curr_rotation);
|
||||
angles[axis] = rotation;
|
||||
|
||||
const Vec3d offset = get_offset();
|
||||
m_matrix = rotation_transform(angles) * scale;
|
||||
m_matrix.translation() = offset;
|
||||
}
|
||||
|
||||
const Vec3d &Transformation::get_scaling_factor() const
|
||||
{
|
||||
const Transform3d scale = extract_scale(m_matrix);
|
||||
|
|
|
@ -399,9 +399,9 @@ public:
|
|||
double get_rotation(Axis axis) const { return get_rotation()[axis]; }
|
||||
|
||||
Transform3d get_rotation_matrix() const;
|
||||
void set_rotation_matrix(const Transform3d &rot_mat);
|
||||
|
||||
void set_rotation(const Vec3d &rotation);
|
||||
void set_rotation(Axis axis, double rotation);
|
||||
|
||||
const Vec3d &get_scaling_factor() const;
|
||||
double get_scaling_factor(Axis axis) const { return get_scaling_factor()[axis]; }
|
||||
|
|
|
@ -3145,11 +3145,9 @@ void ModelVolume::calculate_convex_hull_2d(const Geometry::Transformation &tran
|
|||
return;
|
||||
|
||||
Points pts;
|
||||
Vec3d rotation = transformation.get_rotation();
|
||||
Vec3d mirror = transformation.get_mirror();
|
||||
Vec3d scale = transformation.get_scaling_factor();
|
||||
//rotation(2) = 0.f;
|
||||
Transform3d new_matrix = Geometry::assemble_transform(Vec3d::Zero(), rotation, scale, mirror);
|
||||
Geometry::Transformation new_trans(transformation);
|
||||
new_trans.reset_offset();
|
||||
Transform3d new_matrix = new_trans.get_matrix();
|
||||
|
||||
pts.reserve(its.vertices.size());
|
||||
// Using the shared vertices should be a bit quicker than using the STL faces.
|
||||
|
@ -3480,6 +3478,12 @@ void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) cons
|
|||
mesh->transform(get_matrix(dont_translate));
|
||||
}
|
||||
|
||||
void ModelInstance::rotate(Matrix3d rotation_matrix)
|
||||
{
|
||||
auto new_rotation_mat = Transform3d(rotation_matrix) * m_transformation.get_rotation_matrix();
|
||||
m_transformation.set_rotation_matrix(new_rotation_mat);
|
||||
}
|
||||
|
||||
BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh& mesh, bool dont_translate) const
|
||||
{
|
||||
// Rotate around mesh origin.
|
||||
|
@ -3947,12 +3951,10 @@ void ModelInstance::get_arrange_polygon(void *ap, const Slic3r::DynamicPrintConf
|
|||
{
|
||||
// static const double SIMPLIFY_TOLERANCE_MM = 0.1;
|
||||
|
||||
Vec3d rotation = get_rotation();
|
||||
rotation.z() = 0.;
|
||||
Transform3d trafo_instance =
|
||||
Geometry::assemble_transform(get_offset().z() * Vec3d::UnitZ(), rotation, get_scaling_factor(), get_mirror());
|
||||
Geometry::Transformation trafo_instance = get_transformation();
|
||||
trafo_instance.set_offset(Vec3d(0, 0, get_offset(Z)));
|
||||
|
||||
Polygon p = get_object()->convex_hull_2d(trafo_instance);
|
||||
Polygon p = get_object()->convex_hull_2d(trafo_instance.get_matrix());
|
||||
|
||||
// if (!p.points.empty()) {
|
||||
// Polygons pp{p};
|
||||
|
@ -3963,7 +3965,7 @@ void ModelInstance::get_arrange_polygon(void *ap, const Slic3r::DynamicPrintConf
|
|||
arrangement::ArrangePolygon& ret = *(arrangement::ArrangePolygon*)ap;
|
||||
ret.poly.contour = std::move(p);
|
||||
ret.translation = Vec2crd{scaled(get_offset(X)), scaled(get_offset(Y))};
|
||||
ret.rotation = get_rotation(Z);
|
||||
ret.rotation = 0;
|
||||
|
||||
//BBS: add materials related information
|
||||
ModelVolume *volume = NULL;
|
||||
|
@ -3995,6 +3997,15 @@ void ModelInstance::get_arrange_polygon(void *ap, const Slic3r::DynamicPrintConf
|
|||
ret.extrude_ids.push_back(1);
|
||||
}
|
||||
|
||||
void ModelInstance::apply_arrange_result(const Vec2d &offs, double rotation)
|
||||
{
|
||||
// write the transformation data into the model instance
|
||||
rotate(Eigen::AngleAxisd(rotation, Eigen::Vector3d::UnitZ()).toRotationMatrix());
|
||||
set_offset(X, unscale<double>(offs(X)));
|
||||
set_offset(Y, unscale<double>(offs(Y)));
|
||||
this->object->invalidate_bounding_box();
|
||||
}
|
||||
|
||||
indexed_triangle_set FacetsAnnotation::get_facets(const ModelVolume& mv, EnforcerBlockerType type) const
|
||||
{
|
||||
TriangleSelector selector(mv.mesh());
|
||||
|
|
|
@ -1031,7 +1031,6 @@ public:
|
|||
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); }
|
||||
|
||||
const Vec3d &get_scaling_factor() const { return m_transformation.get_scaling_factor(); }
|
||||
double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); }
|
||||
|
@ -1335,19 +1334,9 @@ public:
|
|||
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); }
|
||||
|
||||
// BBS
|
||||
void rotate(Matrix3d rotation_matrix) {
|
||||
auto R = m_transformation.get_rotation_matrix();
|
||||
auto R_new = rotation_matrix * R;
|
||||
auto euler_angles = Geometry::extract_euler_angles(R_new);
|
||||
//BOOST_LOG_TRIVIAL(debug) << "old R:\n"
|
||||
// << R.matrix() << "\nnew R:\n"
|
||||
// << R_new.matrix() << "\nold euler angles: " << m_transformation.get_rotation().transpose() << "\n"
|
||||
// << "new euler angles: " << euler_angles.transpose();
|
||||
set_rotation(euler_angles);
|
||||
}
|
||||
void rotate(Matrix3d rotation_matrix);
|
||||
|
||||
const Vec3d& get_scaling_factor() const { return m_transformation.get_scaling_factor(); }
|
||||
double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); }
|
||||
|
@ -1390,14 +1379,7 @@ public:
|
|||
void get_arrange_polygon(void *arrange_polygon, const Slic3r::DynamicPrintConfig &config = Slic3r::DynamicPrintConfig()) const;
|
||||
|
||||
// Apply the arrange result on the ModelInstance
|
||||
void apply_arrange_result(const Vec2d& offs, double rotation)
|
||||
{
|
||||
// write the transformation data into the model instance
|
||||
set_rotation(Z, rotation);
|
||||
set_offset(X, unscale<double>(offs(X)));
|
||||
set_offset(Y, unscale<double>(offs(Y)));
|
||||
this->object->invalidate_bounding_box();
|
||||
}
|
||||
void apply_arrange_result(const Vec2d &offs, double rotation);
|
||||
|
||||
protected:
|
||||
friend class Print;
|
||||
|
|
|
@ -577,9 +577,10 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
|
|||
// 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.
|
||||
Geometry::Transformation new_trans(model_instance0->get_transformation());
|
||||
new_trans.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,
|
||||
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())));
|
||||
print_object->model_object()->convex_hull_2d(new_trans.get_matrix()));
|
||||
}
|
||||
// Make a copy, so it may be rotated for instances.
|
||||
Polygon convex_hull0 = it_convex_hull->second;
|
||||
|
|
|
@ -508,7 +508,6 @@ public:
|
|||
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(); }
|
||||
void set_instance_rotation(Axis axis, double rotation) { m_instance_transformation.set_rotation(axis, rotation); set_bounding_boxes_as_dirty(); }
|
||||
|
||||
Vec3d get_instance_scaling_factor() const { return m_instance_transformation.get_scaling_factor(); }
|
||||
double get_instance_scaling_factor(Axis axis) const { return m_instance_transformation.get_scaling_factor(axis); }
|
||||
|
@ -536,7 +535,6 @@ public:
|
|||
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(); }
|
||||
|
||||
const Vec3d& get_volume_scaling_factor() const { return m_volume_transformation.get_scaling_factor(); }
|
||||
double get_volume_scaling_factor(Axis axis) const { return m_volume_transformation.get_scaling_factor(axis); }
|
||||
|
|
|
@ -5446,7 +5446,7 @@ std::vector<Vec2f> GLCanvas3D::get_empty_cells(const Vec2f start_point, const Ve
|
|||
Geometry::Transformation transformation;
|
||||
const Vec3d& offset = instance->get_offset();
|
||||
transformation.set_offset({ scale_(offset.x()), scale_(offset.y()), 0.0 });
|
||||
transformation.set_rotation(Z, instance->get_rotation().z() - rotation_z0);
|
||||
transformation.set_rotation({0, 0, instance->get_rotation().z() - rotation_z0});
|
||||
const Transform3d& trafo = transformation.get_matrix();
|
||||
Polygon inst_hull_2d = hull_2d.transform(trafo);
|
||||
|
||||
|
@ -5626,7 +5626,7 @@ void GLCanvas3D::update_sequential_clearance()
|
|||
Geometry::Transformation transformation;
|
||||
const Vec3d& offset = instance->get_offset();
|
||||
transformation.set_offset({ offset.x(), offset.y(), 0.0 });
|
||||
transformation.set_rotation(Z, instance->get_rotation().z() - rotation_z0);
|
||||
transformation.set_rotation({0, 0, instance->get_rotation().z() - rotation_z0});
|
||||
const Transform3d& trafo = transformation.get_matrix();
|
||||
const Pointf3s& hull_2d = m_sequential_print_clearance.m_hull_2d_cache[i];
|
||||
Points inst_pts;
|
||||
|
|
|
@ -633,8 +633,9 @@ void ArrangeJob::process()
|
|||
BOOST_LOG_TRIVIAL(warning)<< "Arrange full params: "<< params.to_json();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("arrange: items selected before arranging: %1%") % m_selected.size();
|
||||
for (auto selected : m_selected) {
|
||||
BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx << ", filemant_type:" << selected.filament_temp_type
|
||||
<< ", trans: " << selected.translation.transpose();
|
||||
BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx
|
||||
<< ", filemant_type:" << selected.filament_temp_type << ", trans: " << selected.translation.transpose()
|
||||
<< ", rotation: " << selected.rotation;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << "arrange: items unselected before arrange: " << m_unselected.size();
|
||||
for (auto item : m_unselected)
|
||||
|
@ -651,10 +652,11 @@ void ArrangeJob::process()
|
|||
for (auto selected : m_selected)
|
||||
BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx
|
||||
<< ", bed_temp: " << selected.first_bed_temp << ", print_temp: " << selected.print_temp
|
||||
<< ", trans: " << unscale<double>(selected.translation(X)) << ","<< unscale<double>(selected.translation(Y));
|
||||
<< ", trans: " << unscale<double>(selected.translation(X)) << "," << unscale<double>(selected.translation(Y))
|
||||
<< ", rotation: " << selected.rotation;
|
||||
BOOST_LOG_TRIVIAL(debug) << "arrange: items unselected after arrange: "<< m_unselected.size();
|
||||
for (auto item : m_unselected)
|
||||
BOOST_LOG_TRIVIAL(debug) << item.name << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose();
|
||||
BOOST_LOG_TRIVIAL(debug) << item.name << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose() << ", rotation: " << item.rotation;
|
||||
}
|
||||
|
||||
// put unpackable items to m_unprintable so they goes outside
|
||||
|
|
Loading…
Reference in New Issue