diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index 082bf1e8e..b65c56aa6 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -772,9 +772,9 @@ add_executable(slic3r EXCLUDE_FROM_ALL ${PROJECT_SOURCE_DIR}/src/slic3r.cpp) target_include_directories(XS PRIVATE src src/libslic3r) target_link_libraries(slic3r libslic3r libslic3r_gui admesh miniz ${Boost_LIBRARIES} clipper ${EXPAT_LIBRARIES} ${GLEW_LIBRARIES} polypartition poly2tri ${TBB_LIBRARIES} ${wxWidgets_LIBRARIES}) -add_executable(slabasebed ${PROJECT_SOURCE_DIR}/src/slabasebed.cpp) +add_executable(slabasebed EXCLUDE_FROM_ALL ${PROJECT_SOURCE_DIR}/src/slabasebed.cpp) target_include_directories(slabasebed PRIVATE src src/libslic3r) -target_link_libraries(slabasebed libslic3r libslic3r_gui qhull admesh miniz ${Boost_LIBRARIES} clipper ${EXPAT_LIBRARIES} ${GLEW_LIBRARIES} polypartition poly2tri ${TBB_LIBRARIES} ${wxWidgets_LIBRARIES}) +target_link_libraries(slabasebed libslic3r libslic3r_gui qhull admesh miniz ${Boost_LIBRARIES} clipper ${EXPAT_LIBRARIES} ${GLEW_LIBRARIES} polypartition poly2tri ${TBB_LIBRARIES} ${wxWidgets_LIBRARIES} ${CMAKE_DL_LIBS}) if(SLIC3R_PROFILE) target_link_libraries(Shiny) diff --git a/xs/src/libslic3r/Format/3mf.cpp b/xs/src/libslic3r/Format/3mf.cpp index d05460408..363c4db2c 100644 --- a/xs/src/libslic3r/Format/3mf.cpp +++ b/xs/src/libslic3r/Format/3mf.cpp @@ -87,8 +87,6 @@ const char* INVALID_OBJECT_TYPES[] = "other" }; -typedef Eigen::Matrix Matrix4x4; - const char* get_attribute_value_charptr(const char** attributes, unsigned int attributes_size, const char* attribute_key) { if ((attributes == nullptr) || (attributes_size == 0) || (attributes_size % 2 != 0) || (attribute_key == nullptr)) @@ -121,11 +119,11 @@ int get_attribute_value_int(const char** attributes, unsigned int attributes_siz return (text != nullptr) ? ::atoi(text) : 0; } -Matrix4x4 get_matrix_from_string(const std::string& mat_str) +Slic3r::Transform3d get_transform_from_string(const std::string& mat_str) { if (mat_str.empty()) // empty string means default identity matrix - return Matrix4x4::Identity(); + return Slic3r::Transform3d::Identity(); std::vector mat_elements_str; boost::split(mat_elements_str, mat_str, boost::is_any_of(" "), boost::token_compress_on); @@ -133,9 +131,9 @@ Matrix4x4 get_matrix_from_string(const std::string& mat_str) unsigned int size = (unsigned int)mat_elements_str.size(); if (size != 12) // invalid data, return identity matrix - return Matrix4x4::Identity(); + return Slic3r::Transform3d::Identity(); - Matrix4x4 ret = Matrix4x4::Identity(); + Slic3r::Transform3d ret = Slic3r::Transform3d::Identity(); unsigned int i = 0; // matrices are stored into 3mf files as 4x3 // we need to transpose them @@ -143,7 +141,7 @@ Matrix4x4 get_matrix_from_string(const std::string& mat_str) { for (unsigned int r = 0; r < 3; ++r) { - ret(r, c) = (float)::atof(mat_elements_str[i++].c_str()); + ret(r, c) = ::atof(mat_elements_str[i++].c_str()); } } return ret; @@ -209,17 +207,17 @@ namespace Slic3r { struct Component { int object_id; - Matrix4x4 matrix; + Transform3d transform; explicit Component(int object_id) : object_id(object_id) - , matrix(Matrix4x4::Identity()) + , transform(Transform3d::Identity()) { } - Component(int object_id, const Matrix4x4& matrix) + Component(int object_id, const Transform3d& transform) : object_id(object_id) - , matrix(matrix) + , transform(transform) { } }; @@ -273,11 +271,11 @@ namespace Slic3r { struct Instance { ModelInstance* instance; - Matrix4x4 matrix; + Transform3d transform; - Instance(ModelInstance* instance, const Matrix4x4& matrix) + Instance(ModelInstance* instance, const Transform3d& transform) : instance(instance) - , matrix(matrix) + , transform(transform) { } }; @@ -405,9 +403,9 @@ namespace Slic3r { bool _handle_start_metadata(const char** attributes, unsigned int num_attributes); bool _handle_end_metadata(); - bool _create_object_instance(int object_id, const Matrix4x4& matrix, unsigned int recur_counter); + bool _create_object_instance(int object_id, const Transform3d& transform, unsigned int recur_counter); - void _apply_transform(ModelInstance& instance, const Matrix4x4& matrix); + void _apply_transform(ModelInstance& instance, const Transform3d& transform); bool _handle_start_config(const char** attributes, unsigned int num_attributes); bool _handle_end_config(); @@ -934,8 +932,8 @@ namespace Slic3r { ModelObject* object = instance.instance->get_object(); if (object != nullptr) { - // apply the matrix to the instance - _apply_transform(*instance.instance, instance.matrix); + // apply the transform to the instance + _apply_transform(*instance.instance, instance.transform); } } } @@ -1119,7 +1117,7 @@ namespace Slic3r { bool _3MF_Importer::_handle_start_component(const char** attributes, unsigned int num_attributes) { int object_id = get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR); - Matrix4x4 matrix = get_matrix_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR)); + Transform3d transform = get_transform_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR)); IdToModelObjectMap::iterator object_item = m_objects.find(object_id); if (object_item == m_objects.end()) @@ -1132,7 +1130,7 @@ namespace Slic3r { } } - m_curr_object.components.emplace_back(object_id, matrix); + m_curr_object.components.emplace_back(object_id, transform); return true; } @@ -1165,9 +1163,9 @@ namespace Slic3r { // see specifications int object_id = get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR); - Matrix4x4 matrix = get_matrix_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR)); + Transform3d transform = get_transform_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR)); - return _create_object_instance(object_id, matrix, 1); + return _create_object_instance(object_id, transform, 1); } bool _3MF_Importer::_handle_end_item() @@ -1195,7 +1193,7 @@ namespace Slic3r { return true; } - bool _3MF_Importer::_create_object_instance(int object_id, const Matrix4x4& matrix, unsigned int recur_counter) + bool _3MF_Importer::_create_object_instance(int object_id, const Transform3d& transform, unsigned int recur_counter) { static const unsigned int MAX_RECURSIONS = 10; @@ -1232,7 +1230,7 @@ namespace Slic3r { return false; } - m_instances.emplace_back(instance, matrix); + m_instances.emplace_back(instance, transform); } } else @@ -1240,7 +1238,7 @@ namespace Slic3r { // recursively process nested components for (const Component& component : it->second) { - if (!_create_object_instance(component.object_id, matrix * component.matrix, recur_counter + 1)) + if (!_create_object_instance(component.object_id, transform * component.transform, recur_counter + 1)) return false; } } @@ -1248,20 +1246,20 @@ namespace Slic3r { return true; } - void _3MF_Importer::_apply_transform(ModelInstance& instance, const Matrix4x4& matrix) + void _3MF_Importer::_apply_transform(ModelInstance& instance, const Transform3d& transform) { // slic3r ModelInstance cannot be transformed using a matrix // we extract from the given matrix only the values currently used // translation - double offset_x = (double)matrix(0, 3); - double offset_y = (double)matrix(1, 3); - double offset_z = (double)matrix(2, 3); + double offset_x = transform(0, 3); + double offset_y = transform(1, 3); + double offset_z = transform(2, 3); // scale - double sx = ::sqrt(sqr((double)matrix(0, 0)) + sqr((double)matrix(1, 0)) + sqr((double)matrix(2, 0))); - double sy = ::sqrt(sqr((double)matrix(0, 1)) + sqr((double)matrix(1, 1)) + sqr((double)matrix(2, 1))); - double sz = ::sqrt(sqr((double)matrix(0, 2)) + sqr((double)matrix(1, 2)) + sqr((double)matrix(2, 2))); + double sx = ::sqrt(sqr(transform(0, 0)) + sqr(transform(1, 0)) + sqr(transform(2, 0))); + double sy = ::sqrt(sqr(transform(0, 1)) + sqr(transform(1, 1)) + sqr(transform(2, 1))); + double sz = ::sqrt(sqr(transform(0, 2)) + sqr(transform(1, 2)) + sqr(transform(2, 2))); // invalid scale value, return if ((sx == 0.0) || (sy == 0.0) || (sz == 0.0)) @@ -1271,86 +1269,23 @@ namespace Slic3r { if ((std::abs(sx - sy) > 0.00001) || (std::abs(sx - sz) > 0.00001)) return; -#if 0 // use quaternions - // rotations (extracted using quaternion) - double inv_sx = 1.0 / sx; - double inv_sy = 1.0 / sy; - double inv_sz = 1.0 / sz; - - Eigen::Matrix m3x3; - m3x3 << (double)matrix(0, 0) * inv_sx, (double)matrix(0, 1) * inv_sy, (double)matrix(0, 2) * inv_sz, - (double)matrix(1, 0) * inv_sx, (double)matrix(1, 1) * inv_sy, (double)matrix(1, 2) * inv_sz, - (double)matrix(2, 0) * inv_sx, (double)matrix(2, 1) * inv_sy, (double)matrix(2, 2) * inv_sz; - - double qw = 0.5 * ::sqrt(std::max(0.0, 1.0 + m3x3(0, 0) + m3x3(1, 1) + m3x3(2, 2))); - double qx = 0.5 * ::sqrt(std::max(0.0, 1.0 + m3x3(0, 0) - m3x3(1, 1) - m3x3(2, 2))); - double qy = 0.5 * ::sqrt(std::max(0.0, 1.0 - m3x3(0, 0) + m3x3(1, 1) - m3x3(2, 2))); - double qz = 0.5 * ::sqrt(std::max(0.0, 1.0 - m3x3(0, 0) - m3x3(1, 1) + m3x3(2, 2))); - - double q_magnitude = ::sqrt(sqr(qw) + sqr(qx) + sqr(qy) + sqr(qz)); - - // invalid length, return - if (q_magnitude == 0.0) - return; - - double inv_q_magnitude = 1.0 / q_magnitude; - - qw *= inv_q_magnitude; - qx *= inv_q_magnitude; - qy *= inv_q_magnitude; - qz *= inv_q_magnitude; - - double test = qx * qy + qz * qw; - double angle_x, angle_y, angle_z; - - if (test > 0.499) - { - // singularity at north pole - angle_x = 0.0; - angle_y = 2.0 * ::atan2(qx, qw); - angle_z = 0.5 * PI; - } - else if (test < -0.499) - { - // singularity at south pole - angle_x = 0.0; - angle_y = -2.0 * ::atan2(qx, qw); - angle_z = -0.5 * PI; - } - else - { - angle_x = ::atan2(2.0 * qx * qw - 2.0 * qy * qz, 1.0 - 2.0 * sqr(qx) - 2.0 * sqr(qz)); - angle_y = ::atan2(2.0 * qy * qw - 2.0 * qx * qz, 1.0 - 2.0 * sqr(qy) - 2.0 * sqr(qz)); - angle_z = ::asin(2.0 * qx * qy + 2.0 * qz * qw); - - if (angle_x < 0.0) - angle_x += 2.0 * PI; - - if (angle_y < 0.0) - angle_y += 2.0 * PI; - - if (angle_z < 0.0) - angle_z += 2.0 * PI; - } -#else // use eigen library double inv_sx = 1.0 / sx; double inv_sy = 1.0 / sy; double inv_sz = 1.0 / sz; Eigen::Matrix3d m3x3; - m3x3 << (double)matrix(0, 0) * inv_sx, (double)matrix(0, 1) * inv_sy, (double)matrix(0, 2) * inv_sz, - (double)matrix(1, 0) * inv_sx, (double)matrix(1, 1) * inv_sy, (double)matrix(1, 2) * inv_sz, - (double)matrix(2, 0) * inv_sx, (double)matrix(2, 1) * inv_sy, (double)matrix(2, 2) * inv_sz; + m3x3 << transform(0, 0) * inv_sx, transform(0, 1) * inv_sy, transform(0, 2) * inv_sz, + transform(1, 0) * inv_sx, transform(1, 1) * inv_sy, transform(1, 2) * inv_sz, + transform(2, 0) * inv_sx, transform(2, 1) * inv_sy, transform(2, 2) * inv_sz; Eigen::AngleAxisd rotation; rotation.fromRotationMatrix(m3x3); // invalid rotation axis, we currently handle only rotations around Z axis - if ((rotation.angle() != 0.0) && (rotation.axis() != Eigen::Vector3d::UnitZ()) && (rotation.axis() != -Eigen::Vector3d::UnitZ())) + if ((rotation.angle() != 0.0) && (rotation.axis() != Vec3d::UnitZ()) && (rotation.axis() != -Vec3d::UnitZ())) return; - double angle_z = (rotation.axis() == Eigen::Vector3d::UnitZ()) ? rotation.angle() : -rotation.angle(); -#endif + double angle_z = (rotation.axis() == Vec3d::UnitZ()) ? rotation.angle() : -rotation.angle(); instance.offset(0) = offset_x; instance.offset(1) = offset_y; @@ -1548,11 +1483,11 @@ namespace Slic3r { struct BuildItem { unsigned int id; - Matrix4x4 matrix; + Transform3d transform; - BuildItem(unsigned int id, const Matrix4x4& matrix) + BuildItem(unsigned int id, const Transform3d& transform) : id(id) - , matrix(matrix) + , transform(transform) { } }; @@ -1801,9 +1736,11 @@ namespace Slic3r { stream << " \n"; } - Eigen::Affine3f transform; - transform = Eigen::Translation3f((float)instance->offset(0), (float)instance->offset(1), 0.0f) * Eigen::AngleAxisf((float)instance->rotation, Eigen::Vector3f::UnitZ()) * Eigen::Scaling((float)instance->scaling_factor); - build_items.emplace_back(instance_id, transform.matrix()); + Transform3d t = Transform3d::Identity(); + t.translate(Vec3d(instance->offset(0), instance->offset(1), 0.0)); + t.rotate(Eigen::AngleAxisd(instance->rotation, Vec3d::UnitZ())); + t.scale(instance->scaling_factor); + build_items.emplace_back(instance_id, t); stream << " \n"; @@ -1904,7 +1841,7 @@ namespace Slic3r { { for (unsigned r = 0; r < 3; ++r) { - stream << item.matrix(r, c); + stream << item.transform(r, c); if ((r != 2) || (c != 3)) stream << " "; } diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp index f723ca856..1cd3b1413 100644 --- a/xs/src/libslic3r/Model.cpp +++ b/xs/src/libslic3r/Model.cpp @@ -743,21 +743,6 @@ void ModelObject::rotate(float angle, const Vec3d& axis) this->invalidate_bounding_box(); } -void ModelObject::transform(const float* matrix3x4) -{ - if (matrix3x4 == nullptr) - return; - - for (ModelVolume* v : volumes) - { - v->mesh.transform(matrix3x4); - v->m_convex_hull.transform(matrix3x4); - } - - this->origin_translation = Vec3d::Zero(); - this->invalidate_bounding_box(); -} - void ModelObject::mirror(const Axis &axis) { for (ModelVolume *v : this->volumes) diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp index 140a0270a..f8a36527d 100644 --- a/xs/src/libslic3r/Model.hpp +++ b/xs/src/libslic3r/Model.hpp @@ -122,7 +122,6 @@ public: void scale(const Vec3d &versor); void rotate(float angle, const Axis &axis); void rotate(float angle, const Vec3d& axis); - void transform(const float* matrix3x4); // <<<<<<<<< FIXME (using eigen) void mirror(const Axis &axis); size_t materials_count() const; size_t facets_count() const; diff --git a/xs/src/libslic3r/SLABasePool.cpp b/xs/src/libslic3r/SLABasePool.cpp index 17cc251a5..adf43eaf2 100644 --- a/xs/src/libslic3r/SLABasePool.cpp +++ b/xs/src/libslic3r/SLABasePool.cpp @@ -294,6 +294,8 @@ inline Contour3D inner_bed(const ExPolygon& poly, double depth_mm, /// Unification of polygons (with clipper) preserving holes as well. inline ExPolygons unify(const ExPolygons& shapes) { + using ClipperLib::ptSubject; + ExPolygons retv; bool closed = true; @@ -303,11 +305,15 @@ inline ExPolygons unify(const ExPolygons& shapes) { for(auto& path : shapes) { auto clipperpath = Slic3rMultiPoint_to_ClipperPath(path.contour); - valid &= clipper.AddPath(clipperpath, ClipperLib::ptSubject, closed); + + if(!clipperpath.empty()) + valid &= clipper.AddPath(clipperpath, ptSubject, closed); auto clipperholes = Slic3rMultiPoints_to_ClipperPaths(path.holes); + for(auto& hole : clipperholes) { - valid &= clipper.AddPath(hole, ClipperLib::ptSubject, closed); + if(!hole.empty()) + valid &= clipper.AddPath(hole, ptSubject, closed); } } @@ -382,7 +388,7 @@ inline Point centroid(const ExPolygon& poly) { /// with explicit bridges. Bridges are generated from each shape's centroid /// to the center of the "scene" which is the centroid calculated from the shape /// centroids (a star is created...) -inline ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 0) +inline ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 50) { if(polys.empty()) return ExPolygons(); @@ -408,8 +414,9 @@ inline ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 0) double dx = x(c) - x(cc), dy = y(c) - y(cc); double l = std::sqrt(dx * dx + dy * dy); double nx = dx / l, ny = dy / l; + double max_dist = mm(max_dist_mm); - if(l < max_dist_mm) return ExPolygon(); + if(l > max_dist) return ExPolygon(); ExPolygon r; auto& ctour = r.contour.points; @@ -427,9 +434,6 @@ inline ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 0) punion = unify(punion); - if(punion.size() != 1) - BOOST_LOG_TRIVIAL(error) << "Cannot generate correct SLA base pool!"; - return punion; } @@ -449,9 +453,10 @@ void ground_layer(const TriangleMesh &mesh, ExPolygons &output, float h) void create_base_pool(const ExPolygons &ground_layer, TriangleMesh& out, double min_wall_thickness_mm, - double min_wall_height_mm) + double min_wall_height_mm, + double max_merge_distance_mm) { - auto concavehs = concave_hull(ground_layer); + auto concavehs = concave_hull(ground_layer, max_merge_distance_mm); for(ExPolygon& concaveh : concavehs) { if(concaveh.contour.points.empty()) return; concaveh.holes.clear(); @@ -460,7 +465,7 @@ void create_base_pool(const ExPolygons &ground_layer, TriangleMesh& out, coord_t w = x(bb.max) - x(bb.min); coord_t h = y(bb.max) - y(bb.min); - auto wall_thickness = coord_t(std::pow((w+h)*0.1, 0.8)); + auto wall_thickness = coord_t((w+h)*0.01); const coord_t WALL_THICKNESS = mm(min_wall_thickness_mm) + wall_thickness; diff --git a/xs/src/libslic3r/SLABasePool.hpp b/xs/src/libslic3r/SLABasePool.hpp index 52adabfbc..55c94df07 100644 --- a/xs/src/libslic3r/SLABasePool.hpp +++ b/xs/src/libslic3r/SLABasePool.hpp @@ -20,8 +20,9 @@ void ground_layer(const TriangleMesh& mesh, /// Calculate the pool for the mesh for SLA printing void create_base_pool(const ExPolygons& ground_layer, TriangleMesh& output_mesh, - double min_wall_thickness_mm = 4, - double min_wall_height_mm = 5 + double min_wall_thickness_mm = 2, + double min_wall_height_mm = 5, + double max_merge_distance_mm = 50 ); } diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp index 91432f3b5..6840bc96e 100644 --- a/xs/src/libslic3r/TriangleMesh.cpp +++ b/xs/src/libslic3r/TriangleMesh.cpp @@ -279,15 +279,6 @@ void TriangleMesh::mirror(const Axis &axis) stl_invalidate_shared_vertices(&this->stl); } -void TriangleMesh::transform(const float* matrix3x4) -{ - if (matrix3x4 == nullptr) - return; - - stl_transform(&stl, const_cast(matrix3x4)); - stl_invalidate_shared_vertices(&stl); -} - void TriangleMesh::align_to_origin() { this->translate( diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp index c42a0934d..666252887 100644 --- a/xs/src/libslic3r/TriangleMesh.hpp +++ b/xs/src/libslic3r/TriangleMesh.hpp @@ -48,7 +48,6 @@ public: void mirror_x() { this->mirror(X); } void mirror_y() { this->mirror(Y); } void mirror_z() { this->mirror(Z); } - void transform(const float* matrix3x4); void align_to_origin(); void rotate(double angle, Point* center); TriangleMeshPtrs split() const; diff --git a/xs/src/slic3r/AppController.cpp b/xs/src/slic3r/AppController.cpp index 8727da695..d313b2d38 100644 --- a/xs/src/slic3r/AppController.cpp +++ b/xs/src/slic3r/AppController.cpp @@ -214,6 +214,35 @@ void PrintController::gen_support_material(PrintObject *pobj) } } +PrintController::PngExportData +PrintController::query_png_export_data(const DynamicPrintConfig& conf) +{ + PngExportData ret; + + auto zippath = query_destination_path("Output zip file", "*.zip", "out"); + + ret.zippath = zippath; + + ret.width_mm = conf.opt_float("display_width"); + ret.height_mm = conf.opt_float("display_height"); + + ret.width_px = conf.opt_int("display_pixels_x"); + ret.height_px = conf.opt_int("display_pixels_y"); + + auto opt_corr = conf.opt("printer_correction"); + + if(opt_corr) { + ret.corr_x = opt_corr->values[0]; + ret.corr_y = opt_corr->values[1]; + ret.corr_z = opt_corr->values[2]; + } + + ret.exp_time_first_s = conf.opt_float("initial_exposure_time"); + ret.exp_time_s = conf.opt_float("exposure_time"); + + return ret; +} + void PrintController::slice(AppControllerBoilerplate::ProgresIndicatorPtr pri) { auto st = pri->state(); @@ -262,18 +291,23 @@ void PrintController::slice_to_png() { using Pointf3 = Vec3d; - auto exd = query_png_export_data(); - - if(exd.zippath.empty()) return; - auto presetbundle = GUI::get_preset_bundle(); assert(presetbundle); - auto conf = presetbundle->full_config(); + auto pt = presetbundle->printers.get_selected_preset().printer_technology(); + if(pt != ptSLA) { + report_issue(IssueType::ERR, _("Printer technology is not SLA!"), + _("Error")); + return; + } + auto conf = presetbundle->full_config(); conf.validate(); + auto exd = query_png_export_data(conf); + if(exd.zippath.empty()) return; + try { print_->apply_config(conf); print_->validate(); diff --git a/xs/src/slic3r/AppController.hpp b/xs/src/slic3r/AppController.hpp index 97b8da493..d22f49028 100644 --- a/xs/src/slic3r/AppController.hpp +++ b/xs/src/slic3r/AppController.hpp @@ -190,7 +190,7 @@ protected: }; // Should display a dialog with the input fields for printing to png - PngExportData query_png_export_data(); + PngExportData query_png_export_data(const DynamicPrintConfig&); // The previous export data, to pre-populate the dialog PngExportData prev_expdata_; diff --git a/xs/src/slic3r/AppControllerWx.cpp b/xs/src/slic3r/AppControllerWx.cpp index 7d4987e17..5fc18dbf8 100644 --- a/xs/src/slic3r/AppControllerWx.cpp +++ b/xs/src/slic3r/AppControllerWx.cpp @@ -309,120 +309,120 @@ void AppController::set_global_progress_indicator( } } -PrintController::PngExportData PrintController::query_png_export_data() -{ +//PrintController::PngExportData PrintController::collect_png_export_data() +//{ - // Implement the logic of the PngExportDialog - class PngExportView: public PngExportDialog { - double ratio_, bs_ratio_; - PrintController& ctl_; - public: +// // Implement the logic of the PngExportDialog +// class PngExportView: public PngExportDialog { +// double ratio_, bs_ratio_; +// PrintController& ctl_; +// public: - PngExportView(PrintController& ctl): - PngExportDialog(wxTheApp->GetTopWindow()), ctl_(ctl) - { - ratio_ = double(spin_reso_width_->GetValue()) / - spin_reso_height_->GetValue(); +// PngExportView(PrintController& ctl): +// PngExportDialog(wxTheApp->GetTopWindow()), ctl_(ctl) +// { +// ratio_ = double(spin_reso_width_->GetValue()) / +// spin_reso_height_->GetValue(); - bs_ratio_ = bed_width_spin_->GetValue() / - bed_height_spin_->GetValue(); - } +// bs_ratio_ = bed_width_spin_->GetValue() / +// bed_height_spin_->GetValue(); +// } - PngExportData export_data() const { - PrintController::PngExportData ret; - ret.zippath = filepick_ctl_->GetPath(); - ret.width_px = spin_reso_width_->GetValue(); - ret.height_px = spin_reso_height_->GetValue(); - ret.width_mm = bed_width_spin_->GetValue(); - ret.height_mm = bed_height_spin_->GetValue(); - ret.exp_time_s = exptime_spin_->GetValue(); - ret.exp_time_first_s = exptime_first_spin_->GetValue(); - ret.corr_x = corr_spin_x_->GetValue(); - ret.corr_y = corr_spin_y_->GetValue(); - ret.corr_z = corr_spin_z_->GetValue(); - return ret; - } +// PngExportData export_data() const { +// PrintController::PngExportData ret; +// ret.zippath = filepick_ctl_->GetPath(); +// ret.width_px = spin_reso_width_->GetValue(); +// ret.height_px = spin_reso_height_->GetValue(); +// ret.width_mm = bed_width_spin_->GetValue(); +// ret.height_mm = bed_height_spin_->GetValue(); +// ret.exp_time_s = exptime_spin_->GetValue(); +// ret.exp_time_first_s = exptime_first_spin_->GetValue(); +// ret.corr_x = corr_spin_x_->GetValue(); +// ret.corr_y = corr_spin_y_->GetValue(); +// ret.corr_z = corr_spin_z_->GetValue(); +// return ret; +// } - void prefill(const PngExportData& data) { - filepick_ctl_->SetPath(data.zippath); - spin_reso_width_->SetValue(data.width_px); - spin_reso_height_->SetValue(data.height_px); - bed_width_spin_->SetValue(data.width_mm); - bed_height_spin_->SetValue(data.height_mm); - exptime_spin_->SetValue(data.exp_time_s); - exptime_first_spin_->SetValue(data.exp_time_first_s); - corr_spin_x_->SetValue(data.corr_x); - corr_spin_y_->SetValue(data.corr_y); - corr_spin_z_->SetValue(data.corr_z); - if(data.zippath.empty()) export_btn_->Disable(); - else export_btn_->Enable(); - } +// void prefill(const PngExportData& data) { +// filepick_ctl_->SetPath(data.zippath); +// spin_reso_width_->SetValue(data.width_px); +// spin_reso_height_->SetValue(data.height_px); +// bed_width_spin_->SetValue(data.width_mm); +// bed_height_spin_->SetValue(data.height_mm); +// exptime_spin_->SetValue(data.exp_time_s); +// exptime_first_spin_->SetValue(data.exp_time_first_s); +// corr_spin_x_->SetValue(data.corr_x); +// corr_spin_y_->SetValue(data.corr_y); +// corr_spin_z_->SetValue(data.corr_z); +// if(data.zippath.empty()) export_btn_->Disable(); +// else export_btn_->Enable(); +// } - virtual void ResoLock( wxCommandEvent& /*event*/ ) override { - ratio_ = double(spin_reso_width_->GetValue()) / - double(spin_reso_height_->GetValue()); - } +// virtual void ResoLock( wxCommandEvent& /*event*/ ) override { +// ratio_ = double(spin_reso_width_->GetValue()) / +// double(spin_reso_height_->GetValue()); +// } - virtual void BedsizeLock( wxCommandEvent& /*event*/ ) override { - bs_ratio_ = bed_width_spin_->GetValue() / - bed_height_spin_->GetValue(); - } +// virtual void BedsizeLock( wxCommandEvent& /*event*/ ) override { +// bs_ratio_ = bed_width_spin_->GetValue() / +// bed_height_spin_->GetValue(); +// } - virtual void EvalResoSpin( wxCommandEvent& event ) override { - if(reso_lock_btn_->GetValue()) { - if(event.GetId() == spin_reso_width_->GetId()) { - spin_reso_height_->SetValue( - std::round(spin_reso_width_->GetValue()/ratio_)); - spin_reso_height_->Update(); - } else { - spin_reso_width_->SetValue( - std::round(spin_reso_height_->GetValue()*ratio_)); - spin_reso_width_->Update(); - } - } - } +// virtual void EvalResoSpin( wxCommandEvent& event ) override { +// if(reso_lock_btn_->GetValue()) { +// if(event.GetId() == spin_reso_width_->GetId()) { +// spin_reso_height_->SetValue( +// std::round(spin_reso_width_->GetValue()/ratio_)); +// spin_reso_height_->Update(); +// } else { +// spin_reso_width_->SetValue( +// std::round(spin_reso_height_->GetValue()*ratio_)); +// spin_reso_width_->Update(); +// } +// } +// } - virtual void EvalBedSpin( wxCommandEvent& event ) override { - if(bedsize_lock_btn_->GetValue()) { - if(event.GetId() == bed_width_spin_->GetId()) { - bed_height_spin_->SetValue( - std::round(bed_width_spin_->GetValue()/bs_ratio_)); - bed_height_spin_->Update(); - } else { - bed_width_spin_->SetValue( - std::round(bed_height_spin_->GetValue()*bs_ratio_)); - bed_width_spin_->Update(); - } - } - } +// virtual void EvalBedSpin( wxCommandEvent& event ) override { +// if(bedsize_lock_btn_->GetValue()) { +// if(event.GetId() == bed_width_spin_->GetId()) { +// bed_height_spin_->SetValue( +// std::round(bed_width_spin_->GetValue()/bs_ratio_)); +// bed_height_spin_->Update(); +// } else { +// bed_width_spin_->SetValue( +// std::round(bed_height_spin_->GetValue()*bs_ratio_)); +// bed_width_spin_->Update(); +// } +// } +// } - virtual void onFileChanged( wxFileDirPickerEvent& event ) { - if(filepick_ctl_->GetPath().IsEmpty()) export_btn_->Disable(); - else export_btn_->Enable(); - } +// virtual void onFileChanged( wxFileDirPickerEvent& event ) { +// if(filepick_ctl_->GetPath().IsEmpty()) export_btn_->Disable(); +// else export_btn_->Enable(); +// } - virtual void Close( wxCommandEvent& /*event*/ ) { - auto ret = wxID_OK; +// virtual void Close( wxCommandEvent& /*event*/ ) { +// auto ret = wxID_OK; - if(wxFileName(filepick_ctl_->GetPath()).Exists()) - if(!ctl_.report_issue(PrintController::IssueType::WARN_Q, - _(L("File already exists. Overwrite?")), - _(L("Warning")))) ret = wxID_CANCEL; - EndModal(ret); - } - }; +// if(wxFileName(filepick_ctl_->GetPath()).Exists()) +// if(!ctl_.report_issue(PrintController::IssueType::WARN_Q, +// _(L("File already exists. Overwrite?")), +// _(L("Warning")))) ret = wxID_CANCEL; +// EndModal(ret); +// } +// }; - PngExportView exdlg(*this); +// PngExportView exdlg(*this); - exdlg.prefill(prev_expdata_); +// exdlg.prefill(prev_expdata_); - auto r = exdlg.ShowModal(); +// auto r = exdlg.ShowModal(); - auto ret = exdlg.export_data(); - prev_expdata_ = ret; +// auto ret = exdlg.export_data(); +// prev_expdata_ = ret; - if(r != wxID_OK) ret.zippath.clear(); +// if(r != wxID_OK) ret.zippath.clear(); - return ret; -} +// return ret; +//} } diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index c9607ccf9..08a1b1457 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -198,6 +198,8 @@ GLVolume::GLVolume(float r, float g, float b, float a) : m_origin(0, 0, 0) , m_angle_z(0.0f) , m_scale_factor(1.0f) + , m_world_matrix(Transform3f::Identity()) + , m_world_matrix_dirty(true) , m_transformed_bounding_box_dirty(true) , m_transformed_convex_hull_bounding_box_dirty(true) , m_convex_hull(nullptr) @@ -268,6 +270,7 @@ void GLVolume::set_origin(const Vec3d& origin) if (m_origin != origin) { m_origin = origin; + m_world_matrix_dirty = true; m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; } @@ -278,6 +281,7 @@ void GLVolume::set_angle_z(float angle_z) if (m_angle_z != angle_z) { m_angle_z = angle_z; + m_world_matrix_dirty = true; m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; } @@ -288,6 +292,7 @@ void GLVolume::set_scale_factor(float scale_factor) if (m_scale_factor != scale_factor) { m_scale_factor = scale_factor; + m_world_matrix_dirty = true; m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; } @@ -298,16 +303,20 @@ void GLVolume::set_convex_hull(const TriangleMesh& convex_hull) m_convex_hull = &convex_hull; } -Transform3f GLVolume::world_matrix() const +const Transform3f& GLVolume::world_matrix() const { - Transform3f matrix = Transform3f::Identity(); - matrix.translate(Vec3f((float)m_origin(0), (float)m_origin(1), (float)m_origin(2))); - matrix.rotate(Eigen::AngleAxisf(m_angle_z, Vec3f::UnitZ())); - matrix.scale(m_scale_factor); - return matrix; + if (m_world_matrix_dirty) + { + m_world_matrix = Transform3f::Identity(); + m_world_matrix.translate(Vec3f((float)m_origin(0), (float)m_origin(1), (float)m_origin(2))); + m_world_matrix.rotate(Eigen::AngleAxisf(m_angle_z, Vec3f::UnitZ())); + m_world_matrix.scale(m_scale_factor); + m_world_matrix_dirty = false; + } + return m_world_matrix; } -BoundingBoxf3 GLVolume::transformed_bounding_box() const +const BoundingBoxf3& GLVolume::transformed_bounding_box() const { if (m_transformed_bounding_box_dirty) { @@ -318,7 +327,7 @@ BoundingBoxf3 GLVolume::transformed_bounding_box() const return m_transformed_bounding_box; } -BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box() const +const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const { if (m_transformed_convex_hull_bounding_box_dirty) { diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index b4aa6ce95..69f1e1d35 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -260,6 +260,10 @@ private: float m_angle_z; // Scale factor of the volume to be rendered. float m_scale_factor; + // World matrix of the volume to be rendered. + mutable Transform3f m_world_matrix; + // Whether or not is needed to recalculate the world matrix. + mutable bool m_world_matrix_dirty; // Bounding box of this volume, in unscaled coordinates. mutable BoundingBoxf3 m_transformed_bounding_box; // Whether or not is needed to recalculate the transformed bounding box. @@ -334,9 +338,9 @@ public: int volume_idx() const { return (this->composite_id / 1000) % 1000; } int instance_idx() const { return this->composite_id % 1000; } - Transform3f world_matrix() const; - BoundingBoxf3 transformed_bounding_box() const; - BoundingBoxf3 transformed_convex_hull_bounding_box() const; + const Transform3f& world_matrix() const; + const BoundingBoxf3& transformed_bounding_box() const; + const BoundingBoxf3& transformed_convex_hull_bounding_box() const; bool empty() const { return this->indexed_vertex_array.empty(); } bool indexed() const { return this->indexed_vertex_array.indexed(); } diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 8793bcf6f..bbc73b896 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -1134,11 +1134,7 @@ GLCanvas3D::Gizmos::~Gizmos() bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent) { -#if ENABLE_GIZMOS_3D GLGizmoBase* gizmo = new GLGizmoScale3D(parent); -#else - GLGizmoBase* gizmo = new GLGizmoScale(parent); -#endif // ENABLE_GIZMOS_3D if (gizmo == nullptr) return false; @@ -1147,11 +1143,7 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent) m_gizmos.insert(GizmosMap::value_type(Scale, gizmo)); -#if ENABLE_GIZMOS_3D gizmo = new GLGizmoRotate3D(parent); -#else - gizmo = new GLGizmoRotate(parent, GLGizmoRotate::Z); -#endif // ENABLE_GIZMOS_3D if (gizmo == nullptr) { _reset(); @@ -1379,11 +1371,7 @@ float GLCanvas3D::Gizmos::get_scale() const return 1.0f; GizmosMap::const_iterator it = m_gizmos.find(Scale); -#if ENABLE_GIZMOS_3D return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_scale_x() : 1.0f; -#else - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_scale() : 1.0f; -#endif // ENABLE_GIZMOS_3D } void GLCanvas3D::Gizmos::set_scale(float scale) @@ -1393,11 +1381,7 @@ void GLCanvas3D::Gizmos::set_scale(float scale) GizmosMap::const_iterator it = m_gizmos.find(Scale); if (it != m_gizmos.end()) -#if ENABLE_GIZMOS_3D reinterpret_cast(it->second)->set_scale(scale); -#else - reinterpret_cast(it->second)->set_scale(scale); -#endif // ENABLE_GIZMOS_3D } float GLCanvas3D::Gizmos::get_angle_z() const @@ -1406,11 +1390,7 @@ float GLCanvas3D::Gizmos::get_angle_z() const return 0.0f; GizmosMap::const_iterator it = m_gizmos.find(Rotate); -#if ENABLE_GIZMOS_3D return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_angle_z() : 0.0f; -#else - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_angle() : 0.0f; -#endif // ENABLE_GIZMOS_3D } void GLCanvas3D::Gizmos::set_angle_z(float angle_z) @@ -1420,11 +1400,7 @@ void GLCanvas3D::Gizmos::set_angle_z(float angle_z) GizmosMap::const_iterator it = m_gizmos.find(Rotate); if (it != m_gizmos.end()) -#if ENABLE_GIZMOS_3D -reinterpret_cast(it->second)->set_angle_z(angle_z); -#else - reinterpret_cast(it->second)->set_angle(angle_z); -#endif // ENABLE_GIZMOS_3D + reinterpret_cast(it->second)->set_angle_z(angle_z); } Vec3d GLCanvas3D::Gizmos::get_flattening_normal() const @@ -2487,10 +2463,12 @@ void GLCanvas3D::reload_scene(bool force) // 1st call to reset if no objects left update_gizmos_data(); update_volumes_selection(m_objects_selections); - // 2nd call to restore if something selected + // 2nd call to restore selection, if any if (!m_objects_selections.empty()) update_gizmos_data(); + m_gizmos.refresh(); + if (m_config->has("nozzle_diameter")) { // Should the wipe tower be visualized ? @@ -3157,7 +3135,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } else if (evt.Dragging() && m_gizmos.is_dragging()) { - m_canvas->CaptureMouse(); + if (!m_canvas->HasCapture()) + m_canvas->CaptureMouse(); m_mouse.dragging = true; m_gizmos.update(mouse_ray(pos)); diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp index a107b3d17..1dcf35de0 100644 --- a/xs/src/slic3r/GUI/GLGizmo.cpp +++ b/xs/src/slic3r/GUI/GLGizmo.cpp @@ -26,10 +26,8 @@ const float GLGizmoBase::Grabber::HalfSize = 2.0f; const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f; GLGizmoBase::Grabber::Grabber() - : center(0.0, 0.0, 0.0) - , angle_x(0.0f) - , angle_y(0.0f) - , angle_z(0.0f) + : center(Vec3d::Zero()) + , angles(Vec3d::Zero()) , dragging(false) { color[0] = 1.0f; @@ -49,29 +47,14 @@ void GLGizmoBase::Grabber::render(bool hover) const else ::memcpy((void*)render_color, (const void*)color, 3 * sizeof(float)); -#if ENABLE_GIZMOS_3D render(render_color, true); -#else - render(render_color); -#endif // ENABLE_GIZMOS_3D } -#if ENABLE_GIZMOS_3D void GLGizmoBase::Grabber::render(const float* render_color, bool use_lighting) const -#else -void GLGizmoBase::Grabber::render(const float* render_color) const -#endif // ENABLE_GIZMOS_3D { float half_size = dragging ? HalfSize * DraggingScaleFactor : HalfSize; -#if ENABLE_GIZMOS_3D if (use_lighting) ::glEnable(GL_LIGHTING); -#else - float min_x = -half_size; - float max_x = +half_size; - float min_y = -half_size; - float max_y = +half_size; -#endif // !ENABLE_GIZMOS_3D ::glColor3f((GLfloat)render_color[0], (GLfloat)render_color[1], (GLfloat)render_color[2]); @@ -79,11 +62,10 @@ void GLGizmoBase::Grabber::render(const float* render_color) const ::glTranslatef((GLfloat)center(0), (GLfloat)center(1), (GLfloat)center(2)); float rad_to_deg = 180.0f / (GLfloat)PI; - ::glRotatef((GLfloat)angle_x * rad_to_deg, 1.0f, 0.0f, 0.0f); - ::glRotatef((GLfloat)angle_y * rad_to_deg, 0.0f, 1.0f, 0.0f); - ::glRotatef((GLfloat)angle_z * rad_to_deg, 0.0f, 0.0f, 1.0f); + ::glRotatef((GLfloat)angles(0) * rad_to_deg, 1.0f, 0.0f, 0.0f); + ::glRotatef((GLfloat)angles(1) * rad_to_deg, 0.0f, 1.0f, 0.0f); + ::glRotatef((GLfloat)angles(2) * rad_to_deg, 0.0f, 0.0f, 1.0f); -#if ENABLE_GIZMOS_3D // face min x ::glPushMatrix(); ::glTranslatef(-(GLfloat)half_size, 0.0f, 0.0f); @@ -124,28 +106,13 @@ void GLGizmoBase::Grabber::render(const float* render_color) const ::glTranslatef(0.0f, 0.0f, (GLfloat)half_size); render_face(half_size); ::glPopMatrix(); -#else - ::glDisable(GL_CULL_FACE); - ::glBegin(GL_TRIANGLES); - ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f); - ::glVertex3f((GLfloat)max_x, (GLfloat)min_y, 0.0f); - ::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f); - ::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f); - ::glVertex3f((GLfloat)min_x, (GLfloat)max_y, 0.0f); - ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f); - ::glEnd(); - ::glEnable(GL_CULL_FACE); -#endif // ENABLE_GIZMOS_3D ::glPopMatrix(); -#if ENABLE_GIZMOS_3D if (use_lighting) ::glDisable(GL_LIGHTING); -#endif // ENABLE_GIZMOS_3D } -#if ENABLE_GIZMOS_3D void GLGizmoBase::Grabber::render_face(float half_size) const { ::glBegin(GL_TRIANGLES); @@ -158,7 +125,6 @@ void GLGizmoBase::Grabber::render_face(float half_size) const ::glVertex3f(-(GLfloat)half_size, -(GLfloat)half_size, 0.0f); ::glEnd(); } -#endif // ENABLE_GIZMOS_3D GLGizmoBase::GLGizmoBase(GLCanvas3D& parent) : m_parent(parent) @@ -265,41 +231,24 @@ const float GLGizmoRotate::GrabberOffset = 5.0f; GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis) : GLGizmoBase(parent) , m_axis(axis) - , m_angle(0.0f) + , m_angle(0.0) , m_center(0.0, 0.0, 0.0) , m_radius(0.0f) , m_keep_initial_values(false) { } -void GLGizmoRotate::set_angle(float angle) +void GLGizmoRotate::set_angle(double angle) { - if (std::abs(angle - 2.0f * PI) < EPSILON) - angle = 0.0f; + if (std::abs(angle - 2.0 * (double)PI) < EPSILON) + angle = 0.0; m_angle = angle; } bool GLGizmoRotate::on_init() { -#if !ENABLE_GIZMOS_3D - std::string path = resources_dir() + "/icons/overlay/"; - - std::string filename = path + "rotate_off.png"; - if (!m_textures[Off].load_from_file(filename, false)) - return false; - - filename = path + "rotate_hover.png"; - if (!m_textures[Hover].load_from_file(filename, false)) - return false; - - filename = path + "rotate_on.png"; - if (!m_textures[On].load_from_file(filename, false)) - return false; -#endif // !ENABLE_GIZMOS_3D - m_grabbers.push_back(Grabber()); - return true; } @@ -339,7 +288,7 @@ void GLGizmoRotate::on_update(const Linef3& mouse_ray) if (theta == 2.0 * (double)PI) theta = 0.0; - m_angle = (float)theta; + m_angle = theta; } void GLGizmoRotate::on_render(const BoundingBoxf3& box) const @@ -347,55 +296,33 @@ void GLGizmoRotate::on_render(const BoundingBoxf3& box) const if (m_grabbers[0].dragging) set_tooltip(format(m_angle * 180.0f / (float)PI, 4)); -#if ENABLE_GIZMOS_3D ::glEnable(GL_DEPTH_TEST); -#else - ::glDisable(GL_DEPTH_TEST); -#endif // ENABLE_GIZMOS_3D if (!m_keep_initial_values) { m_center = box.center(); -#if !ENABLE_GIZMOS_3D - const Vec3d& size = box.size(); - m_center(2) = 0.0; -#endif // !ENABLE_GIZMOS_3D - -#if ENABLE_GIZMOS_3D m_radius = Offset + box.radius(); -#else - m_radius = Offset + ::sqrt(sqr(0.5f * (float)size(0)) + sqr(0.5f * (float)size(1))); -#endif // ENABLE_GIZMOS_3D m_keep_initial_values = true; } ::glPushMatrix(); transform_to_local(); -#if ENABLE_GIZMOS_3D ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f); ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color); -#else - ::glLineWidth(2.0f); - ::glColor3fv(m_drag_color); -#endif // ENABLE_GIZMOS_3D render_circle(); -#if ENABLE_GIZMOS_3D + if (m_hover_id != -1) { -#endif // ENABLE_GIZMOS_3D render_scale(); render_snap_radii(); render_reference_radius(); -#if ENABLE_GIZMOS_3D } -#endif // ENABLE_GIZMOS_3D ::glColor3fv(m_highlight_color); -#if ENABLE_GIZMOS_3D + if (m_hover_id != -1) -#endif // ENABLE_GIZMOS_3D render_angle(); render_grabber(); @@ -491,7 +418,7 @@ void GLGizmoRotate::render_reference_radius() const void GLGizmoRotate::render_angle() const { - float step_angle = m_angle / AngleResolution; + float step_angle = (float)m_angle / AngleResolution; float ex_radius = m_radius + GrabberOffset; ::glBegin(GL_LINE_STRIP); @@ -508,15 +435,11 @@ void GLGizmoRotate::render_angle() const void GLGizmoRotate::render_grabber() const { - float grabber_radius = m_radius + GrabberOffset; + double grabber_radius = (double)(m_radius + GrabberOffset); m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0); - m_grabbers[0].angle_z = m_angle; + m_grabbers[0].angles(2) = m_angle; -#if ENABLE_GIZMOS_3D ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color); -#else - ::glColor3fv(m_drag_color); -#endif // ENABLE_GIZMOS_3D ::glBegin(GL_LINES); ::glVertex3f(0.0f, 0.0f, 0.0f); @@ -584,17 +507,7 @@ Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray) cons m.translate(-m_center); - Eigen::Matrix world_ray; - Eigen::Matrix local_ray; - world_ray(0, 0) = mouse_ray.a(0); - world_ray(1, 0) = mouse_ray.a(1); - world_ray(2, 0) = mouse_ray.a(2); - world_ray(0, 1) = mouse_ray.b(0); - world_ray(1, 1) = mouse_ray.b(1); - world_ray(2, 1) = mouse_ray.b(2); - local_ray = m * world_ray.colwise().homogeneous(); - - return Linef3(Vec3d(local_ray(0, 0), local_ray(1, 0), local_ray(2, 0)), Vec3d(local_ray(0, 1), local_ray(1, 1), local_ray(2, 1))).intersect_plane(0.0); + return transform(mouse_ray, m).intersect_plane(0.0); } GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent) @@ -698,116 +611,13 @@ void GLGizmoRotate3D::on_render(const BoundingBoxf3& box) const m_z.render(box); } -const float GLGizmoScale::Offset = 5.0f; - -GLGizmoScale::GLGizmoScale(GLCanvas3D& parent) - : GLGizmoBase(parent) - , m_scale(1.0f) - , m_starting_scale(1.0f) -{ -} - -bool GLGizmoScale::on_init() -{ - std::string path = resources_dir() + "/icons/overlay/"; - - std::string filename = path + "scale_off.png"; - if (!m_textures[Off].load_from_file(filename, false)) - return false; - - filename = path + "scale_hover.png"; - if (!m_textures[Hover].load_from_file(filename, false)) - return false; - - filename = path + "scale_on.png"; - if (!m_textures[On].load_from_file(filename, false)) - return false; - - for (unsigned int i = 0; i < 4; ++i) - { - m_grabbers.push_back(Grabber()); - } - - return true; -} - -void GLGizmoScale::on_start_dragging() -{ - if (m_hover_id != -1) - m_starting_drag_position = to_2d(m_grabbers[m_hover_id].center); -} - -void GLGizmoScale::on_update(const Linef3& mouse_ray) -{ - Vec2d mouse_pos = to_2d(mouse_ray.intersect_plane(0.0)); - Vec2d center(0.5 * (m_grabbers[1].center(0) + m_grabbers[0].center(0)), 0.5 * (m_grabbers[3].center(1) + m_grabbers[0].center(1))); - - double orig_len = (m_starting_drag_position - center).norm(); - double new_len = (mouse_pos - center).norm(); - double ratio = (orig_len != 0.0) ? new_len / orig_len : 1.0; - - m_scale = m_starting_scale * (float)ratio; -} - -void GLGizmoScale::on_render(const BoundingBoxf3& box) const -{ - if (m_grabbers[0].dragging || m_grabbers[1].dragging || m_grabbers[2].dragging || m_grabbers[3].dragging) - set_tooltip(format(100.0f * m_scale, 4) + "%"); - - ::glDisable(GL_DEPTH_TEST); - - double min_x = box.min(0) - (double)Offset; - double max_x = box.max(0) + (double)Offset; - double min_y = box.min(1) - (double)Offset; - double max_y = box.max(1) + (double)Offset; - - m_grabbers[0].center = Vec3d(min_x, min_y, 0.0); - m_grabbers[1].center = Vec3d(max_x, min_y, 0.0); - m_grabbers[2].center = Vec3d(max_x, max_y, 0.0); - m_grabbers[3].center = Vec3d(min_x, max_y, 0.0); - - ::glLineWidth(2.0f); - ::glColor3fv(m_drag_color); - - // draw outline - ::glBegin(GL_LINE_LOOP); - for (unsigned int i = 0; i < 4; ++i) - { - ::glVertex3f((GLfloat)m_grabbers[i].center(0), (GLfloat)m_grabbers[i].center(1), 0.0f); - } - ::glEnd(); - - // draw grabbers - for (unsigned int i = 0; i < 4; ++i) - { - ::memcpy((void*)m_grabbers[i].color, (const void*)m_highlight_color, 3 * sizeof(float)); - } - render_grabbers(); -} - -void GLGizmoScale::on_render_for_picking(const BoundingBoxf3& box) const -{ - ::glDisable(GL_DEPTH_TEST); - - for (unsigned int i = 0; i < 4; ++i) - { - m_grabbers[i].color[0] = 1.0f; - m_grabbers[i].color[1] = 1.0f; - m_grabbers[i].color[2] = picking_color_component(i); - } - render_grabbers_for_picking(); -} - const float GLGizmoScale3D::Offset = 5.0f; GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent) : GLGizmoBase(parent) - , m_scale_x(1.0f) - , m_scale_y(1.0f) - , m_scale_z(1.0f) - , m_starting_scale_x(1.0f) - , m_starting_scale_y(1.0f) - , m_starting_scale_z(1.0f) + , m_scale(Vec3d::Ones()) + , m_starting_scale(Vec3d::Ones()) + , m_starting_center(Vec3d::Zero()) { } @@ -832,15 +642,15 @@ bool GLGizmoScale3D::on_init() m_grabbers.push_back(Grabber()); } - float half_pi = 0.5f * (float)PI; + double half_pi = 0.5 * (double)PI; // x axis - m_grabbers[0].angle_y = half_pi; - m_grabbers[1].angle_y = half_pi; + m_grabbers[0].angles(1) = half_pi; + m_grabbers[1].angles(1) = half_pi; // y axis - m_grabbers[2].angle_x = half_pi; - m_grabbers[3].angle_x = half_pi; + m_grabbers[2].angles(0) = half_pi; + m_grabbers[3].angles(0) = half_pi; return true; } @@ -869,16 +679,16 @@ void GLGizmoScale3D::on_update(const Linef3& mouse_ray) void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const { if (m_grabbers[0].dragging || m_grabbers[1].dragging) - set_tooltip("X: " + format(100.0f * m_scale_x, 4) + "%"); + set_tooltip("X: " + format(100.0f * m_scale(0), 4) + "%"); else if (m_grabbers[2].dragging || m_grabbers[3].dragging) - set_tooltip("Y: " + format(100.0f * m_scale_y, 4) + "%"); + set_tooltip("Y: " + format(100.0f * m_scale(1), 4) + "%"); else if (m_grabbers[4].dragging || m_grabbers[5].dragging) - set_tooltip("Z: " + format(100.0f * m_scale_z, 4) + "%"); + set_tooltip("Z: " + format(100.0f * m_scale(2), 4) + "%"); else if (m_grabbers[6].dragging || m_grabbers[7].dragging || m_grabbers[8].dragging || m_grabbers[9].dragging) { - std::string tooltip = "X: " + format(100.0f * m_scale_x, 4) + "%\n"; - tooltip += "Y: " + format(100.0f * m_scale_y, 4) + "%\n"; - tooltip += "Z: " + format(100.0f * m_scale_z, 4) + "%"; + std::string tooltip = "X: " + format(100.0f * m_scale(0), 4) + "%\n"; + tooltip += "Y: " + format(100.0f * m_scale(1), 4) + "%\n"; + tooltip += "Z: " + format(100.0f * m_scale(2), 4) + "%"; set_tooltip(tooltip); } @@ -1025,7 +835,7 @@ void GLGizmoScale3D::do_scale_x(const Linef3& mouse_ray) double ratio = calc_ratio(1, mouse_ray, m_starting_center); if (ratio > 0.0) - m_scale_x = m_starting_scale_x * (float)ratio; + m_scale(0) = m_starting_scale(0) * ratio; } void GLGizmoScale3D::do_scale_y(const Linef3& mouse_ray) @@ -1033,8 +843,8 @@ void GLGizmoScale3D::do_scale_y(const Linef3& mouse_ray) double ratio = calc_ratio(2, mouse_ray, m_starting_center); if (ratio > 0.0) - m_scale_x = m_starting_scale_y * (float)ratio; // << this is temporary -// m_scale_y = m_starting_scale_y * (float)ratio; + m_scale(0) = m_starting_scale(1) * ratio; // << this is temporary +// m_scale(1) = m_starting_scale(1) * ratio; } void GLGizmoScale3D::do_scale_z(const Linef3& mouse_ray) @@ -1042,8 +852,8 @@ void GLGizmoScale3D::do_scale_z(const Linef3& mouse_ray) double ratio = calc_ratio(1, mouse_ray, m_starting_center); if (ratio > 0.0) - m_scale_x = m_starting_scale_z * (float)ratio; // << this is temporary -// m_scale_z = m_starting_scale_z * (float)ratio; + m_scale(0) = m_starting_scale(2) * ratio; // << this is temporary +// m_scale(2) = m_starting_scale(2) * ratio; } void GLGizmoScale3D::do_scale_uniform(const Linef3& mouse_ray) @@ -1053,11 +863,7 @@ void GLGizmoScale3D::do_scale_uniform(const Linef3& mouse_ray) double ratio = calc_ratio(0, mouse_ray, center); if (ratio > 0.0) - { - m_scale_x = m_starting_scale_x * (float)ratio; - m_scale_y = m_starting_scale_y * (float)ratio; - m_scale_z = m_starting_scale_z * (float)ratio; - } + m_scale = m_starting_scale * ratio; } double GLGizmoScale3D::calc_ratio(unsigned int preferred_plane_id, const Linef3& mouse_ray, const Vec3d& center) const diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp index ddfd9a7a5..35335c1a8 100644 --- a/xs/src/slic3r/GUI/GLGizmo.hpp +++ b/xs/src/slic3r/GUI/GLGizmo.hpp @@ -7,8 +7,6 @@ #include -#define ENABLE_GIZMOS_3D 1 - namespace Slic3r { class BoundingBoxf3; @@ -28,30 +26,18 @@ protected: static const float DraggingScaleFactor; Vec3d center; - float angle_x; - float angle_y; - float angle_z; + Vec3d angles; float color[3]; bool dragging; Grabber(); void render(bool hover) const; -#if ENABLE_GIZMOS_3D void render_for_picking() const { render(color, false); } -#else - void render_for_picking() const { render(color); } -#endif // ENABLE_GIZMOS_3D private: -#if ENABLE_GIZMOS_3D void render(const float* render_color, bool use_lighting) const; -#else - void render(const float* render_color) const; -#endif // ENABLE_GIZMOS_3D -#if ENABLE_GIZMOS_3D void render_face(float half_size) const; -#endif // ENABLE_GIZMOS_3D }; public: @@ -146,7 +132,7 @@ public: private: Axis m_axis; - float m_angle; + double m_angle; mutable Vec3d m_center; mutable float m_radius; @@ -155,8 +141,8 @@ private: public: GLGizmoRotate(GLCanvas3D& parent, Axis axis); - float get_angle() const { return m_angle; } - void set_angle(float angle); + double get_angle() const { return m_angle; } + void set_angle(double angle); protected: virtual bool on_init(); @@ -188,14 +174,14 @@ class GLGizmoRotate3D : public GLGizmoBase public: explicit GLGizmoRotate3D(GLCanvas3D& parent); - float get_angle_x() const { return m_x.get_angle(); } - void set_angle_x(float angle) { m_x.set_angle(angle); } + double get_angle_x() const { return m_x.get_angle(); } + void set_angle_x(double angle) { m_x.set_angle(angle); } - float get_angle_y() const { return m_y.get_angle(); } - void set_angle_y(float angle) { m_y.set_angle(angle); } + double get_angle_y() const { return m_y.get_angle(); } + void set_angle_y(double angle) { m_y.set_angle(angle); } - float get_angle_z() const { return m_z.get_angle(); } - void set_angle_z(float angle) { m_z.set_angle(angle); } + double get_angle_z() const { return m_z.get_angle(); } + void set_angle_z(double angle) { m_z.set_angle(angle); } protected: virtual bool on_init(); @@ -234,64 +220,31 @@ protected: } }; -class GLGizmoScale : public GLGizmoBase -{ - static const float Offset; - - float m_scale; - float m_starting_scale; - - Vec2d m_starting_drag_position; - -public: - explicit GLGizmoScale(GLCanvas3D& parent); - - float get_scale() const { return m_scale; } - void set_scale(float scale) { m_starting_scale = scale; } - -protected: - virtual bool on_init(); - virtual void on_start_dragging(); - virtual void on_update(const Linef3& mouse_ray); - virtual void on_render(const BoundingBoxf3& box) const; - virtual void on_render_for_picking(const BoundingBoxf3& box) const; -}; - class GLGizmoScale3D : public GLGizmoBase { static const float Offset; mutable BoundingBoxf3 m_box; - float m_scale_x; - float m_scale_y; - float m_scale_z; - - float m_starting_scale_x; - float m_starting_scale_y; - float m_starting_scale_z; + Vec3d m_scale; + Vec3d m_starting_scale; Vec3d m_starting_drag_position; Vec3d m_starting_center; public: explicit GLGizmoScale3D(GLCanvas3D& parent); - float get_scale_x() const { return m_scale_x; } - void set_scale_x(float scale) { m_starting_scale_x = scale; } + double get_scale_x() const { return m_scale(0); } + void set_scale_x(double scale) { m_starting_scale(0) = scale; } - float get_scale_y() const { return m_scale_y; } - void set_scale_y(float scale) { m_starting_scale_y = scale; } + double get_scale_y() const { return m_scale(1); } + void set_scale_y(double scale) { m_starting_scale(1) = scale; } - float get_scale_z() const { return m_scale_z; } - void set_scale_z(float scale) { m_starting_scale_z = scale; } + double get_scale_z() const { return m_scale(2); } + void set_scale_z(double scale) { m_starting_scale(2) = scale; } - void set_scale(float scale) - { - m_starting_scale_x = scale; - m_starting_scale_y = scale; - m_starting_scale_z = scale; - } + void set_scale(double scale) { m_starting_scale = scale * Vec3d::Ones(); } protected: virtual bool on_init();