From 87565a06866b6d0271313d01e9af76ba45f117b5 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 28 Aug 2018 09:03:03 +0200 Subject: [PATCH] Tweaks to GLGizmoFlatten --- xs/src/libslic3r/Line.cpp | 12 ++++++ xs/src/libslic3r/Line.hpp | 2 + xs/src/libslic3r/Point.cpp | 38 +++++++++++++++++ xs/src/libslic3r/Point.hpp | 3 ++ xs/src/slic3r/GUI/GLCanvas3D.cpp | 2 +- xs/src/slic3r/GUI/GLGizmo.cpp | 72 ++++++++++---------------------- 6 files changed, 77 insertions(+), 52 deletions(-) diff --git a/xs/src/libslic3r/Line.cpp b/xs/src/libslic3r/Line.cpp index a29e4ce4e..35cfa2b76 100644 --- a/xs/src/libslic3r/Line.cpp +++ b/xs/src/libslic3r/Line.cpp @@ -7,6 +7,18 @@ namespace Slic3r { +Linef3 transform(const Linef3& line, const Transform3d& t) +{ + typedef Eigen::Matrix LineInMatrixForm; + + LineInMatrixForm world_line; + ::memcpy((void*)world_line.col(0).data(), (const void*)line.a.data(), 3 * sizeof(double)); + ::memcpy((void*)world_line.col(1).data(), (const void*)line.b.data(), 3 * sizeof(double)); + + LineInMatrixForm local_line = t * world_line.colwise().homogeneous(); + return Linef3(Vec3d(local_line(0, 0), local_line(1, 0), local_line(2, 0)), Vec3d(local_line(0, 1), local_line(1, 1), local_line(2, 1))); +} + bool Line::intersection_infinite(const Line &other, Point* point) const { Vec2d a1 = this->a.cast(); diff --git a/xs/src/libslic3r/Line.hpp b/xs/src/libslic3r/Line.hpp index 5b77a4b61..36e02247c 100644 --- a/xs/src/libslic3r/Line.hpp +++ b/xs/src/libslic3r/Line.hpp @@ -15,6 +15,8 @@ typedef std::vector Lines; typedef std::vector Lines3; typedef std::vector ThickLines; +Linef3 transform(const Linef3& line, const Transform3d& t); + class Line { public: diff --git a/xs/src/libslic3r/Point.cpp b/xs/src/libslic3r/Point.cpp index ec6c28fe8..c2417d0dc 100644 --- a/xs/src/libslic3r/Point.cpp +++ b/xs/src/libslic3r/Point.cpp @@ -6,6 +6,44 @@ namespace Slic3r { +std::vector transform(const std::vector& points, const Transform3f& t) +{ + unsigned int vertices_count = (unsigned int)points.size(); + if (vertices_count == 0) + return std::vector(); + + unsigned int data_size = 3 * vertices_count * sizeof(float); + + Eigen::MatrixXf src(3, vertices_count); + ::memcpy((void*)src.data(), (const void*)points.data(), data_size); + + Eigen::MatrixXf dst(3, vertices_count); + dst = t * src.colwise().homogeneous(); + + std::vector ret_points(vertices_count, Vec3f::Zero()); + ::memcpy((void*)ret_points.data(), (const void*)dst.data(), data_size); + return ret_points; +} + +Pointf3s transform(const Pointf3s& points, const Transform3d& t) +{ + unsigned int vertices_count = (unsigned int)points.size(); + if (vertices_count == 0) + return Pointf3s(); + + unsigned int data_size = 3 * vertices_count * sizeof(double); + + Eigen::MatrixXd src(3, vertices_count); + ::memcpy((void*)src.data(), (const void*)points.data(), data_size); + + Eigen::MatrixXd dst(3, vertices_count); + dst = t * src.colwise().homogeneous(); + + Pointf3s ret_points(vertices_count, Vec3d::Zero()); + ::memcpy((void*)ret_points.data(), (const void*)dst.data(), data_size); + return ret_points; +} + void Point::rotate(double angle) { double cur_x = (double)(*this)(0); diff --git a/xs/src/libslic3r/Point.hpp b/xs/src/libslic3r/Point.hpp index b969b9839..c1aff561f 100644 --- a/xs/src/libslic3r/Point.hpp +++ b/xs/src/libslic3r/Point.hpp @@ -67,6 +67,9 @@ inline std::string to_string(const Vec2d &pt) { return std::string("[") + std: inline std::string to_string(const Vec3crd &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + ", " + std::to_string(pt(2)) + "]"; } inline std::string to_string(const Vec3d &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + ", " + std::to_string(pt(2)) + "]"; } +std::vector transform(const std::vector& points, const Transform3f& t); +Pointf3s transform(const Pointf3s& points, const Transform3d& t); + class Point : public Vec2crd { public: diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 3e22ddefb..8793bcf6f 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -4491,7 +4491,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ if (m_print->m_wipe_tower_final_purge) ctxt.final.emplace_back(*m_print->m_wipe_tower_final_purge.get()); - ctxt.wipe_tower_angle = ctxt.print->config.wipe_tower_rotation_angle.value/180.f * M_PI; + ctxt.wipe_tower_angle = ctxt.print->config.wipe_tower_rotation_angle.value/180.f * PI; ctxt.wipe_tower_pos = WipeTower::xy(ctxt.print->config.wipe_tower_x.value, ctxt.print->config.wipe_tower_y.value); BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start"; diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp index fa5b931e9..a107b3d17 100644 --- a/xs/src/slic3r/GUI/GLGizmo.cpp +++ b/xs/src/slic3r/GUI/GLGizmo.cpp @@ -1020,21 +1020,6 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int } } -Linef3 transform(const Linef3& line, const Transform3d& t) -{ - Eigen::Matrix world_line; - Eigen::Matrix local_line; - world_line(0, 0) = line.a(0); - world_line(1, 0) = line.a(1); - world_line(2, 0) = line.a(2); - world_line(0, 1) = line.b(0); - world_line(1, 1) = line.b(1); - world_line(2, 1) = line.b(2); - local_line = t * world_line.colwise().homogeneous(); - - return Linef3(Vec3d(local_line(0, 0), local_line(1, 0), local_line(2, 0)), Vec3d(local_line(0, 1), local_line(1, 1), local_line(2, 1))); -} - void GLGizmoScale3D::do_scale_x(const Linef3& mouse_ray) { double ratio = calc_ratio(1, mouse_ray, m_starting_center); @@ -1219,10 +1204,13 @@ void GLGizmoFlatten::on_render(const BoundingBoxf3& box) const for (Vec2d offset : m_instances_positions) { offset += to_2d(dragged_offset); + ::glPushMatrix(); + ::glTranslatef((GLfloat)offset(0), (GLfloat)offset(1), 0.0f); ::glBegin(GL_POLYGON); for (const Vec3d& vertex : m_planes[i].vertices) - ::glVertex3f((GLfloat)(vertex(0) + offset(0)), (GLfloat)(vertex(1) + offset(1)), (GLfloat)vertex(2)); + ::glVertex3f((GLfloat)vertex(0), (GLfloat)vertex(1), (GLfloat)vertex(2)); ::glEnd(); + ::glPopMatrix(); } } @@ -1234,45 +1222,25 @@ void GLGizmoFlatten::on_render(const BoundingBoxf3& box) const void GLGizmoFlatten::on_render_for_picking(const BoundingBoxf3& box) const { - static const GLfloat INV_255 = 1.0f / 255.0f; - ::glDisable(GL_DEPTH_TEST); for (unsigned int i = 0; i < m_planes.size(); ++i) { - ::glColor3f(1.0f, 1.0f, (254.0f - (float)i) * INV_255); + // FIXME: the color assignement will fail if the planes count is greater than 254 + // use the other color components in that case !! + ::glColor3f(1.0f, 1.0f, picking_color_component(i)); for (const Vec2d& offset : m_instances_positions) { + ::glPushMatrix(); + ::glTranslatef((GLfloat)offset(0), (GLfloat)offset(1), 0.0f); ::glBegin(GL_POLYGON); for (const Vec3d& vertex : m_planes[i].vertices) - ::glVertex3f((GLfloat)(vertex(0) + offset(0)), (GLfloat)vertex(1) + offset(1), (GLfloat)vertex(2)); + ::glVertex3f((GLfloat)vertex(0), (GLfloat)vertex(1), (GLfloat)vertex(2)); ::glEnd(); + ::glPopMatrix(); } } } -// TODO - remove and use Eigen instead -static Vec3d super_rotation(Vec3d axis, float angle, const Vec3d& point) -{ - axis.normalize(); - float x = (float)axis(0); - float y = (float)axis(1); - float z = (float)axis(2); - float s = sin(angle); - float c = cos(angle); - float D = 1 - c; - float matrix[3][3] = { { c + x*x*D, x*y*D - z*s, x*z*D + y*s }, - { y*x*D + z*s, c + y*y*D, y*z*D - x*s }, - { z*x*D - y*s, z*y*D + x*s, c + z*z*D } }; - float in[3] = { (float)point(0), (float)point(1), (float)point(2) }; - float out[3] = { 0, 0, 0 }; - - for (unsigned char i = 0; i<3; ++i) - for (unsigned char j = 0; j<3; ++j) - out[i] += matrix[i][j] * in[j]; - - return Vec3d((double)out[0], (double)out[1], (double)out[2]); -} - void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object) { m_center.release(); // object is not being dragged (this would not be called otherwise) - we must forget about the bounding box position... @@ -1359,14 +1327,15 @@ void GLGizmoFlatten::update_planes() angle_y = -atan2(normal(0)*cos(angle_z) - normal(1)*sin(angle_z), normal(2)); // angle to rotate to make normal point upwards else { // In case it already was in z-direction, we must ensure it is not the wrong way: - angle_y = normal(2) > 0.f ? 0 : -PI; + angle_y = normal(2) > 0.f ? 0.f : -PI; } // Rotate all points to the xy plane: - for (auto& vertex : polygon) { - vertex = super_rotation(Vec3d::UnitZ(), angle_z, vertex); - vertex = super_rotation(Vec3d::UnitY(), angle_y, vertex); - } + Transform3d m = Transform3d::Identity(); + m.rotate(Eigen::AngleAxisd((double)angle_y, Vec3d::UnitY())); + m.rotate(Eigen::AngleAxisd((double)angle_z, Vec3d::UnitZ())); + polygon = transform(polygon, m); + polygon = Slic3r::Geometry::convex_hull(polygon); // To remove the inner points // We will calculate area of the polygon and discard ones that are too small @@ -1429,10 +1398,11 @@ void GLGizmoFlatten::update_planes() // Transform back to 3D; for (auto& b : polygon) { - b(0) += 0.1f; // raise a bit above the object surface to avoid flickering - b = super_rotation(Vec3d::UnitY(), -angle_y, b); - b = super_rotation(Vec3d::UnitZ(), -angle_z, b); + b(2) += 0.1f; // raise a bit above the object surface to avoid flickering } + + m = m.inverse(); + polygon = transform(polygon, m); } // We'll sort the planes by area and only keep the 255 largest ones (because of the picking pass limitations):