diff --git a/src/admesh/stl.h b/src/admesh/stl.h index d682b2434..f867e197b 100644 --- a/src/admesh/stl.h +++ b/src/admesh/stl.h @@ -180,8 +180,67 @@ extern void stl_rotate_z(stl_file *stl, float angle); extern void stl_mirror_xy(stl_file *stl); extern void stl_mirror_yz(stl_file *stl); extern void stl_mirror_xz(stl_file *stl); -extern void stl_transform(stl_file *stl, float *trafo3x4); -extern void stl_transform(stl_file *stl, const Eigen::Transform& t); + +extern void stl_get_size(stl_file *stl); + +template +extern void stl_transform(stl_file *stl, T *trafo3x4) +{ + if (stl->error) + return; + + for (uint32_t i_face = 0; i_face < stl->stats.number_of_facets; ++ i_face) { + stl_facet &face = stl->facet_start[i_face]; + for (int i_vertex = 0; i_vertex < 3; ++ i_vertex) { + stl_vertex &v_dst = face.vertex[i_vertex]; + stl_vertex v_src = v_dst; + v_dst(0) = T(trafo3x4[0] * v_src(0) + trafo3x4[1] * v_src(1) + trafo3x4[2] * v_src(2) + trafo3x4[3]); + v_dst(1) = T(trafo3x4[4] * v_src(0) + trafo3x4[5] * v_src(1) + trafo3x4[6] * v_src(2) + trafo3x4[7]); + v_dst(2) = T(trafo3x4[8] * v_src(0) + trafo3x4[9] * v_src(1) + trafo3x4[10] * v_src(2) + trafo3x4[11]); + } + stl_vertex &v_dst = face.normal; + stl_vertex v_src = v_dst; + v_dst(0) = T(trafo3x4[0] * v_src(0) + trafo3x4[1] * v_src(1) + trafo3x4[2] * v_src(2)); + v_dst(1) = T(trafo3x4[4] * v_src(0) + trafo3x4[5] * v_src(1) + trafo3x4[6] * v_src(2)); + v_dst(2) = T(trafo3x4[8] * v_src(0) + trafo3x4[9] * v_src(1) + trafo3x4[10] * v_src(2)); + } + + stl_get_size(stl); +} + +template +inline void stl_transform(stl_file *stl, const Eigen::Transform& t) +{ + if (stl->error) + return; + + const Eigen::Matrix r = t.matrix().template block<3, 3>(0, 0); + for (size_t i = 0; i < stl->stats.number_of_facets; ++i) { + stl_facet &f = stl->facet_start[i]; + for (size_t j = 0; j < 3; ++j) + f.vertex[j] = (t * f.vertex[j].template cast()).template cast().eval(); + f.normal = (r * f.normal.template cast()).template cast().eval(); + } + + stl_get_size(stl); +} + +template +inline void stl_transform(stl_file *stl, const Eigen::Matrix& m) +{ + if (stl->error) + return; + + for (size_t i = 0; i < stl->stats.number_of_facets; ++i) { + stl_facet &f = stl->facet_start[i]; + for (size_t j = 0; j < 3; ++j) + f.vertex[j] = (m * f.vertex[j].template cast()).template cast().eval(); + f.normal = (m * f.normal.template cast()).template cast().eval(); + } + + stl_get_size(stl); +} + extern void stl_open_merge(stl_file *stl, char *file); extern void stl_invalidate_shared_vertices(stl_file *stl); extern void stl_generate_shared_vertices(stl_file *stl); @@ -214,7 +273,6 @@ extern void stl_read(stl_file *stl, int first_facet, bool first); extern void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first); extern void stl_reallocate(stl_file *stl); extern void stl_add_facet(stl_file *stl, stl_facet *new_facet); -extern void stl_get_size(stl_file *stl); extern void stl_clear_error(stl_file *stl); extern int stl_get_error(stl_file *stl); diff --git a/src/admesh/util.cpp b/src/admesh/util.cpp index 7cb69bccd..305a58e22 100644 --- a/src/admesh/util.cpp +++ b/src/admesh/util.cpp @@ -137,65 +137,6 @@ static void calculate_normals(stl_file *stl) } } -void stl_transform(stl_file *stl, float *trafo3x4) { - int i_face, i_vertex; - if (stl->error) - return; - for (i_face = 0; i_face < stl->stats.number_of_facets; ++ i_face) { - stl_vertex *vertices = stl->facet_start[i_face].vertex; - for (i_vertex = 0; i_vertex < 3; ++ i_vertex) { - stl_vertex &v_dst = vertices[i_vertex]; - stl_vertex v_src = v_dst; - v_dst(0) = trafo3x4[0] * v_src(0) + trafo3x4[1] * v_src(1) + trafo3x4[2] * v_src(2) + trafo3x4[3]; - v_dst(1) = trafo3x4[4] * v_src(0) + trafo3x4[5] * v_src(1) + trafo3x4[6] * v_src(2) + trafo3x4[7]; - v_dst(2) = trafo3x4[8] * v_src(0) + trafo3x4[9] * v_src(1) + trafo3x4[10] * v_src(2) + trafo3x4[11]; - } - } - stl_get_size(stl); - calculate_normals(stl); -} - -void stl_transform(stl_file *stl, const Eigen::Transform& t) -{ - if (stl->error) - return; - - unsigned int vertices_count = 3 * (unsigned int)stl->stats.number_of_facets; - if (vertices_count == 0) - return; - - Eigen::MatrixXf src_vertices(3, vertices_count); - stl_facet* facet_ptr = stl->facet_start; - unsigned int v_id = 0; - while (facet_ptr < stl->facet_start + stl->stats.number_of_facets) - { - for (int i = 0; i < 3; ++i) - { - ::memcpy((void*)src_vertices.col(v_id).data(), (const void*)&facet_ptr->vertex[i], 3 * sizeof(float)); - ++v_id; - } - facet_ptr += 1; - } - - Eigen::MatrixXf dst_vertices(3, vertices_count); - dst_vertices = t.cast() * src_vertices.colwise().homogeneous(); - - facet_ptr = stl->facet_start; - v_id = 0; - while (facet_ptr < stl->facet_start + stl->stats.number_of_facets) - { - for (int i = 0; i < 3; ++i) - { - ::memcpy((void*)&facet_ptr->vertex[i], (const void*)dst_vertices.col(v_id).data(), 3 * sizeof(float)); - ++v_id; - } - facet_ptr += 1; - } - - stl_get_size(stl); - calculate_normals(stl); -} - void stl_rotate_x(stl_file *stl, float angle) { int i; diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index a7db29b8e..7273fda01 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -280,7 +280,7 @@ std::ostream& ConfigDef::print_cli_help(std::ostream& out, bool show_defaults, s // right: option description std::string descr = def.tooltip; - if (show_defaults && def.default_value != nullptr && def.type != coBool + if (show_defaults && def.default_value && def.type != coBool && (def.type != coString || !def.default_value->serialize().empty())) { descr += " ("; if (!def.sidetext.empty()) { @@ -627,7 +627,7 @@ ConfigOption* DynamicConfig::optptr(const t_config_option_key &opt_key, bool cre // Let the parent decide what to do if the opt_key is not defined by this->def(). return nullptr; ConfigOption *opt = nullptr; - if (optdef->default_value != nullptr) { + if (optdef->default_value) { opt = (optdef->default_value->type() == coEnum) ? // Special case: For a DynamicConfig, convert a templated enum to a generic enum. new ConfigOptionEnumGeneric(optdef->enum_keys_map, optdef->default_value->getInt()) : @@ -783,8 +783,8 @@ void StaticConfig::set_defaults() for (const std::string &key : this->keys()) { const ConfigOptionDef *def = defs->get(key); ConfigOption *opt = this->option(key); - if (def != nullptr && opt != nullptr && def->default_value != nullptr) - opt->set(def->default_value); + if (def != nullptr && opt != nullptr && def->default_value) + opt->set(def->default_value.get()); } } } diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 1e5972701..ee4bc4e46 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -12,6 +12,7 @@ #include #include #include "libslic3r.h" +#include "clonable_ptr.hpp" #include "Point.hpp" #include @@ -1010,7 +1011,10 @@ public: // What type? bool, int, string etc. ConfigOptionType type = coNone; // Default value of this option. The default value object is owned by ConfigDef, it is released in its destructor. - const ConfigOption *default_value = nullptr; + Slic3r::clonable_ptr default_value; + void set_default_value(const ConfigOption* ptr) { this->default_value = Slic3r::clonable_ptr(ptr); } + template + const T* get_default_value() const { return static_cast(this->default_value.get()); } // Usually empty. // Special values - "i_enum_open", "f_enum_open" to provide combo box for int or float selection, @@ -1099,12 +1103,6 @@ typedef std::map t_optiondef_map; class ConfigDef { public: - ~ConfigDef() { - for (std::pair &def : this->options) - delete def.second.default_value; - this->options.clear(); - } - t_optiondef_map options; bool has(const t_config_option_key &opt_key) const { return this->options.count(opt_key) > 0; } diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index 25b849d8c..7b5abd2e5 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -269,6 +269,21 @@ extern Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec // This should only be called if it is known, that the two rotations only differ in rotation around the Z axis. extern double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to); +// Is the angle close to a multiple of 90 degrees? +inline bool is_rotation_ninety_degrees(double a) +{ + a = fmod(std::abs(a), 0.5 * M_PI); + if (a > 0.25 * PI) + a = 0.5 * PI - a; + return a < 0.001; +} + +// Is the angle close to a multiple of 90 degrees? +inline bool is_rotation_ninety_degrees(const Vec3d &rotation) +{ + return is_rotation_ninety_degrees(rotation.x()) && is_rotation_ninety_degrees(rotation.y()) && is_rotation_ninety_degrees(rotation.z()); +} + } } #endif diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index ec95eb578..fbcc3a04b 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -24,6 +24,19 @@ unsigned int Model::s_auto_extruder_id = 1; size_t ModelBase::s_last_id = 0; +// Unique object / instance ID for the wipe tower. +ModelID wipe_tower_object_id() +{ + static ModelBase mine; + return mine.id(); +} + +ModelID wipe_tower_instance_id() +{ + static ModelBase mine; + return mine.id(); +} + Model& Model::assign_copy(const Model &rhs) { this->copy_id(rhs); @@ -1320,6 +1333,58 @@ void ModelObject::repair() v->mesh.repair(); } +// Support for non-uniform scaling of instances. If an instance is rotated by angles, which are not multiples of ninety degrees, +// then the scaling in world coordinate system is not representable by the Geometry::Transformation structure. +// This situation is solved by baking in the instance transformation into the mesh vertices. +// Rotation and mirroring is being baked in. In case the instance scaling was non-uniform, it is baked in as well. +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 (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; + + 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 && + std::abs(reference_trafo.get_scaling_factor().x() - reference_trafo.get_scaling_factor().z()) < EPSILON; + double new_scaling_factor = uniform_scaling ? reference_trafo.get_scaling_factor().x() : 1.; + + // Adjust the instances. + for (size_t i = 0; i < this->instances.size(); ++ i) { + ModelInstance &model_instance = *this->instances[i]; + model_instance.set_rotation(Vec3d(0., 0., Geometry::rotation_diff_z(reference_trafo.get_rotation(), model_instance.get_rotation()))); + model_instance.set_scaling_factor(Vec3d(new_scaling_factor, new_scaling_factor, new_scaling_factor)); + model_instance.set_mirror(Vec3d(1., 1., 1.)); + } + + // Adjust the meshes. + // Transformation to be applied to the meshes. + Eigen::Matrix3d mesh_trafo_3x3 = reference_trafo.get_matrix(true, false, uniform_scaling, ! has_mirrorring).matrix().block<3, 3>(0, 0); + 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(); + bool volume_left_handed = volume_trafo.is_left_handed(); + bool volume_has_mirrorring = ! volume_trafo.get_mirror().isApprox(Vec3d(1., 1., 1.)); + bool volume_uniform_scaling = std::abs(volume_trafo.get_scaling_factor().x() - volume_trafo.get_scaling_factor().y()) < EPSILON && + 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. + Matrix3d volume_trafo_3x3 = volume_trafo.get_matrix(true, false, volume_uniform_scaling, !volume_has_mirrorring).matrix().block<3, 3>(0, 0); + model_volume->transform_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)); + model_volume->set_mirror(Vec3d(1., 1., 1.)); + // Move the reference point of the volume to compensate for the change of the instance trafo. + model_volume->set_offset(volume_offset_correction * volume_trafo.get_offset()); + } + + this->invalidate_bounding_box(); +} + double ModelObject::get_min_z() const { if (instances.empty()) @@ -1708,6 +1773,22 @@ void ModelVolume::scale_geometry(const Vec3d& versor) m_convex_hull.scale(versor); } +void ModelVolume::transform_mesh(const Transform3d &mesh_trafo, bool fix_left_handed) +{ + this->mesh.transform(mesh_trafo, fix_left_handed); + this->m_convex_hull.transform(mesh_trafo, fix_left_handed); + // Let the rest of the application know that the geometry changed, so the meshes have to be reloaded. + this->set_new_unique_id(); +} + +void ModelVolume::transform_mesh(const Matrix3d &matrix, bool fix_left_handed) +{ + this->mesh.transform(matrix, fix_left_handed); + this->m_convex_hull.transform(matrix, fix_left_handed); + // Let the rest of the application know that the geometry changed, so the meshes have to be reloaded. + this->set_new_unique_id(); +} + void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const { mesh->transform(get_matrix(dont_translate)); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 4efc19f58..a11c50300 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -54,6 +54,10 @@ struct ModelID size_t id; }; +// Unique object / instance ID for the wipe tower. +extern ModelID wipe_tower_object_id(); +extern ModelID wipe_tower_instance_id(); + // Base for Model, ModelObject, ModelVolume, ModelInstance or ModelMaterial to provide a unique ID // to synchronize the front end (UI) with the back end (BackgroundSlicingProcess / Print / PrintObject). // Achtung! The s_last_id counter is not thread safe, so it is expected, that the ModelBase derived instances @@ -85,6 +89,9 @@ private: static inline ModelID generate_new_id() { return ModelID(++ s_last_id); } static size_t s_last_id; + + friend ModelID wipe_tower_object_id(); + friend ModelID wipe_tower_instance_id(); }; #define MODELBASE_DERIVED_COPY_MOVE_CLONE(TYPE) \ @@ -265,6 +272,11 @@ public: ModelObjectPtrs cut(size_t instance, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false); // Note: z is in world coordinates void split(ModelObjectPtrs* new_objects); void repair(); + // Support for non-uniform scaling of instances. If an instance is rotated by angles, which are not multiples of ninety degrees, + // then the scaling in world coordinate system is not representable by the Geometry::Transformation structure. + // This situation is solved by baking in the instance transformation into the mesh vertices. + // Rotation and mirroring is being baked in. In case the instance scaling was non-uniform, it is baked in as well. + void bake_xy_rotation_into_meshes(size_t instance_idx); double get_min_z() const; double get_instance_min_z(size_t instance_idx) const; @@ -421,6 +433,8 @@ protected: explicit ModelVolume(const ModelVolume &rhs) = default; void set_model_object(ModelObject *model_object) { object = model_object; } + void transform_mesh(const Transform3d& t, bool fix_left_handed); + void transform_mesh(const Matrix3d& m, bool fix_left_handed); private: // Parent object owning this ModelVolume. diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp index 6b35600cb..b02ead299 100644 --- a/src/libslic3r/Point.hpp +++ b/src/libslic3r/Point.hpp @@ -40,6 +40,11 @@ typedef std::vector Points3; typedef std::vector Pointfs; typedef std::vector Pointf3s; +typedef Eigen::Matrix Matrix2f; +typedef Eigen::Matrix Matrix2d; +typedef Eigen::Matrix Matrix3f; +typedef Eigen::Matrix Matrix3d; + typedef Eigen::Transform Transform2f; typedef Eigen::Transform Transform2d; typedef Eigen::Transform Transform3f; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index f2aba0e97..cffa4bf0c 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -44,12 +44,12 @@ void PrintConfigDef::init_common_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("FFF"); def->enum_values.push_back("SLA"); - def->default_value = new ConfigOptionEnum(ptFFF); + def->set_default_value(new ConfigOptionEnum(ptFFF)); def = this->add("bed_shape", coPoints); def->label = L("Bed shape"); def->mode = comAdvanced; - def->default_value = new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) }; + def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) }); def = this->add("layer_height", coFloat); def->label = L("Layer height"); @@ -58,14 +58,14 @@ void PrintConfigDef::init_common_params() "Thinner layers give better accuracy but take more time to print."); def->sidetext = L("mm"); def->min = 0; - def->default_value = new ConfigOptionFloat(0.3); + def->set_default_value(new ConfigOptionFloat(0.3)); def = this->add("max_print_height", coFloat); def->label = L("Max print height"); def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing."); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(200.0); + def->set_default_value(new ConfigOptionFloat(200.0)); def = this->add("slice_closing_radius", coFloat); def->label = L("Slice gap closing radius"); @@ -75,28 +75,28 @@ void PrintConfigDef::init_common_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0.049); + def->set_default_value(new ConfigOptionFloat(0.049)); def = this->add("print_host", coString); def->label = L("Hostname, IP or URL"); def->tooltip = L("Slic3r can upload G-code files to a printer host. This field should contain " "the hostname, IP address or URL of the printer host instance."); def->mode = comAdvanced; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("printhost_apikey", coString); def->label = L("API Key / Password"); def->tooltip = L("Slic3r can upload G-code files to a printer host. This field should contain " "the API Key or the password required for authentication."); def->mode = comAdvanced; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("printhost_cafile", coString); def->label = L("HTTPS CA File"); def->tooltip = L("Custom CA certificate file can be specified for HTTPS OctoPrint connections, in crt/pem format. " "If left blank, the default OS CA certificate repository is used."); def->mode = comAdvanced; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); } void PrintConfigDef::init_fff_params() @@ -113,7 +113,7 @@ void PrintConfigDef::init_fff_params() "This is mostly useful with Bowden extruders which suffer from oozing. " "This feature slows down both the print and the G-code generation."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("bed_temperature", coInts); def->label = L("Other layers"); @@ -122,7 +122,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Bed temperature"); def->min = 0; def->max = 300; - def->default_value = new ConfigOptionInts { 0 }; + def->set_default_value(new ConfigOptionInts { 0 }); def = this->add("before_layer_gcode", coString); def->label = L("Before layer change G-code"); @@ -133,7 +133,7 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 5; def->mode = comExpert; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("between_objects_gcode", coString); def->label = L("Between objects G-code"); @@ -142,7 +142,7 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 12; def->mode = comExpert; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("bottom_solid_layers", coInt); //TRN To be shown in Print Settings "Bottom solid layers" @@ -151,7 +151,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Number of solid layers to generate on bottom surfaces."); def->full_label = L("Bottom solid layers"); def->min = 0; - def->default_value = new ConfigOptionInt(3); + def->set_default_value(new ConfigOptionInt(3)); def = this->add("bridge_acceleration", coFloat); def->label = L("Bridge"); @@ -160,7 +160,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s²"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("bridge_angle", coFloat); def->label = L("Bridging angle"); @@ -171,7 +171,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("°"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0.); + def->set_default_value(new ConfigOptionFloat(0.)); def = this->add("bridge_fan_speed", coInts); def->label = L("Bridges fan speed"); @@ -180,7 +180,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 100; def->mode = comExpert; - def->default_value = new ConfigOptionInts { 100 }; + def->set_default_value(new ConfigOptionInts { 100 }); def = this->add("bridge_flow_ratio", coFloat); def->label = L("Bridge flow ratio"); @@ -192,7 +192,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 2; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(1); + def->set_default_value(new ConfigOptionFloat(1)); def = this->add("bridge_speed", coFloat); def->label = L("Bridges"); @@ -202,7 +202,7 @@ void PrintConfigDef::init_fff_params() def->aliases = { "bridge_feed_rate" }; def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(60); + def->set_default_value(new ConfigOptionFloat(60)); def = this->add("brim_width", coFloat); def->label = L("Brim width"); @@ -210,7 +210,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comSimple; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("clip_multipart_objects", coBool); def->label = L("Clip multi-part objects"); @@ -218,17 +218,17 @@ void PrintConfigDef::init_fff_params() "to clip the overlapping object parts one by the other " "(2nd part will be clipped by the 1st, 3rd part will be clipped by the 1st and 2nd etc)."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("colorprint_heights", coFloats); def->label = L("Colorprint height"); def->tooltip = L("Heights at which a filament change is to occur. "); - def->default_value = new ConfigOptionFloats { }; + def->set_default_value(new ConfigOptionFloats { }); def = this->add("compatible_printers", coStrings); def->label = L("Compatible printers"); def->mode = comAdvanced; - def->default_value = new ConfigOptionStrings(); + def->set_default_value(new ConfigOptionStrings()); def->cli = ConfigOptionDef::nocli; def = this->add("compatible_printers_condition", coString); @@ -237,13 +237,13 @@ void PrintConfigDef::init_fff_params() "If this expression evaluates to true, this profile is considered compatible " "with the active printer profile."); def->mode = comExpert; - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; def = this->add("compatible_prints", coStrings); def->label = L("Compatible print profiles"); def->mode = comAdvanced; - def->default_value = new ConfigOptionStrings(); + def->set_default_value(new ConfigOptionStrings()); def->cli = ConfigOptionDef::nocli; def = this->add("compatible_prints_condition", coString); @@ -252,16 +252,16 @@ void PrintConfigDef::init_fff_params() "If this expression evaluates to true, this profile is considered compatible " "with the active print profile."); def->mode = comExpert; - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; // The following value is to be stored into the project file (AMF, 3MF, Config ...) // and it contains a sum of "compatible_printers_condition" values over the print and filament profiles. def = this->add("compatible_printers_condition_cummulative", coStrings); - def->default_value = new ConfigOptionStrings(); + def->set_default_value(new ConfigOptionStrings()); def->cli = ConfigOptionDef::nocli; def = this->add("compatible_prints_condition_cummulative", coStrings); - def->default_value = new ConfigOptionStrings(); + def->set_default_value(new ConfigOptionStrings()); def->cli = ConfigOptionDef::nocli; def = this->add("complete_objects", coBool); @@ -271,13 +271,13 @@ void PrintConfigDef::init_fff_params() "This feature is useful to avoid the risk of ruined prints. " "Slic3r should warn and prevent you from extruder collisions, but beware."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("cooling", coBools); def->label = L("Enable auto cooling"); def->tooltip = L("This flag enables the automatic cooling logic that adjusts print speed " "and fan speed according to layer printing time."); - def->default_value = new ConfigOptionBools { true }; + def->set_default_value(new ConfigOptionBools { true }); def = this->add("cooling_tube_retraction", coFloat); def->label = L("Cooling tube position"); @@ -285,7 +285,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(91.5f); + def->set_default_value(new ConfigOptionFloat(91.5f)); def = this->add("cooling_tube_length", coFloat); def->label = L("Cooling tube length"); @@ -293,7 +293,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(5.f); + def->set_default_value(new ConfigOptionFloat(5.f)); def = this->add("default_acceleration", coFloat); def->label = L("Default"); @@ -303,20 +303,20 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s²"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("default_filament_profile", coStrings); def->label = L("Default filament profile"); def->tooltip = L("Default filament profile associated with the current printer profile. " "On selection of the current printer profile, this filament profile will be activated."); - def->default_value = new ConfigOptionStrings(); + def->set_default_value(new ConfigOptionStrings()); def->cli = ConfigOptionDef::nocli; def = this->add("default_print_profile", coString); def->label = L("Default print profile"); def->tooltip = L("Default print profile associated with the current printer profile. " "On selection of the current printer profile, this print profile will be activated."); - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; def = this->add("disable_fan_first_layers", coInts); @@ -327,7 +327,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 1000; def->mode = comExpert; - def->default_value = new ConfigOptionInts { 3 }; + def->set_default_value(new ConfigOptionInts { 3 }); def = this->add("dont_support_bridges", coBool); def->label = L("Don't support bridges"); @@ -335,7 +335,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Experimental option for preventing support material from being generated " "under bridged areas."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("duplicate_distance", coFloat); def->label = L("Distance between copies"); @@ -343,7 +343,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->aliases = { "multiply_distance" }; def->min = 0; - def->default_value = new ConfigOptionFloat(6); + def->set_default_value(new ConfigOptionFloat(6)); def = this->add("elefant_foot_compensation", coFloat); def->label = L("Elephant foot compensation"); @@ -353,7 +353,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("end_gcode", coString); def->label = L("End G-code"); @@ -363,7 +363,7 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 12; def->mode = comExpert; - def->default_value = new ConfigOptionString("M104 S0 ; turn off temperature\nG28 X0 ; home X axis\nM84 ; disable motors\n"); + def->set_default_value(new ConfigOptionString("M104 S0 ; turn off temperature\nG28 X0 ; home X axis\nM84 ; disable motors\n")); def = this->add("end_filament_gcode", coStrings); def->label = L("End G-code"); @@ -374,7 +374,7 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 120; def->mode = comExpert; - def->default_value = new ConfigOptionStrings { "; Filament-specific end gcode \n;END gcode for filament\n" }; + def->set_default_value(new ConfigOptionStrings { "; Filament-specific end gcode \n;END gcode for filament\n" }); def = this->add("ensure_vertical_shell_thickness", coBool); def->label = L("Ensure vertical shell thickness"); @@ -382,7 +382,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Add solid infill near sloping surfaces to guarantee the vertical shell thickness " "(top+bottom solid layers)."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); auto def_top_fill_pattern = def = this->add("top_fill_pattern", coEnum); def->label = L("Top fill pattern"); @@ -402,14 +402,14 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Octagram Spiral")); // solid_fill_pattern is an obsolete equivalent to top_fill_pattern/bottom_fill_pattern. def->aliases = { "solid_fill_pattern", "external_fill_pattern" }; - def->default_value = new ConfigOptionEnum(ipRectilinear); + def->set_default_value(new ConfigOptionEnum(ipRectilinear)); def = this->add("bottom_fill_pattern", coEnum); *def = *def_top_fill_pattern; def->label = L("Bottom fill pattern"); def->tooltip = L("Fill pattern for bottom infill. This only affects the bottom external visible layer, and not its adjacent solid shells."); def->cli = "bottom-fill-pattern|external-fill-pattern|solid-fill-pattern"; - def->default_value = new ConfigOptionEnum(ipRectilinear); + def->set_default_value(new ConfigOptionEnum(ipRectilinear)); def = this->add("external_perimeter_extrusion_width", coFloatOrPercent); def->label = L("External perimeters"); @@ -419,7 +419,7 @@ void PrintConfigDef::init_fff_params() "If expressed as percentage (for example 200%), it will be computed over layer height."); def->sidetext = L("mm or % (leave 0 for default)"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(0, false); + def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); def = this->add("external_perimeter_speed", coFloatOrPercent); def->label = L("External perimeters"); @@ -431,7 +431,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "perimeter_speed"; def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(50, true); + def->set_default_value(new ConfigOptionFloatOrPercent(50, true)); def = this->add("external_perimeters_first", coBool); def->label = L("External perimeters first"); @@ -439,7 +439,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Print contour perimeters from the outermost one to the innermost one " "instead of the default inverse order."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("extra_perimeters", coBool); def->label = L("Extra perimeters if needed"); @@ -448,7 +448,7 @@ void PrintConfigDef::init_fff_params() "Slic3r keeps adding perimeters, until more than 70% of the loop immediately above " "is supported."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("extruder", coInt); def->gui_type = "i_enum_open"; @@ -473,7 +473,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(20); + def->set_default_value(new ConfigOptionFloat(20)); def = this->add("extruder_clearance_radius", coFloat); def->label = L("Radius"); @@ -484,14 +484,14 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(20); + def->set_default_value(new ConfigOptionFloat(20)); def = this->add("extruder_colour", coStrings); def->label = L("Extruder Color"); def->tooltip = L("This is only used in the Slic3r interface as a visual help."); def->gui_type = "color"; // Empty string means no color assigned yet. - def->default_value = new ConfigOptionStrings { "" }; + def->set_default_value(new ConfigOptionStrings { "" }); def = this->add("extruder_offset", coPoints); def->label = L("Extruder offset"); @@ -501,13 +501,13 @@ void PrintConfigDef::init_fff_params() "from the XY coordinate)."); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionPoints { Vec2d(0,0) }; + def->set_default_value(new ConfigOptionPoints { Vec2d(0,0) }); def = this->add("extrusion_axis", coString); def->label = L("Extrusion axis"); def->tooltip = L("Use this option to set the axis letter associated to your printer's extruder " "(usually E but some printers use A)."); - def->default_value = new ConfigOptionString("E"); + def->set_default_value(new ConfigOptionString("E")); def = this->add("extrusion_multiplier", coFloats); def->label = L("Extrusion multiplier"); @@ -516,7 +516,7 @@ void PrintConfigDef::init_fff_params() "Usual values are between 0.9 and 1.1. If you think you need to change this more, " "check filament diameter and your firmware E steps."); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 1. }; + def->set_default_value(new ConfigOptionFloats { 1. }); def = this->add("extrusion_width", coFloatOrPercent); def->label = L("Default extrusion width"); @@ -527,13 +527,13 @@ void PrintConfigDef::init_fff_params() "If expressed as percentage (for example: 230%), it will be computed over layer height."); def->sidetext = L("mm or % (leave 0 for auto)"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(0, false); + def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); def = this->add("fan_always_on", coBools); def->label = L("Keep fan always on"); def->tooltip = L("If this is enabled, fan will never be disabled and will be kept running at least " "at its minimum speed. Useful for PLA, harmful for ABS."); - def->default_value = new ConfigOptionBools { false }; + def->set_default_value(new ConfigOptionBools { false }); def = this->add("fan_below_layer_time", coInts); def->label = L("Enable fan if layer print time is below"); @@ -544,13 +544,13 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 1000; def->mode = comExpert; - def->default_value = new ConfigOptionInts { 60 }; + def->set_default_value(new ConfigOptionInts { 60 }); def = this->add("filament_colour", coStrings); def->label = L("Color"); def->tooltip = L("This is only used in the Slic3r interface as a visual help."); def->gui_type = "color"; - def->default_value = new ConfigOptionStrings { "#29B2B2" }; + def->set_default_value(new ConfigOptionStrings { "#29B2B2" }); def = this->add("filament_notes", coStrings); def->label = L("Filament notes"); @@ -559,7 +559,7 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 13; def->mode = comAdvanced; - def->default_value = new ConfigOptionStrings { "" }; + def->set_default_value(new ConfigOptionStrings { "" }); def = this->add("filament_max_volumetric_speed", coFloats); def->label = L("Max volumetric speed"); @@ -569,7 +569,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm³/s"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("filament_loading_speed", coFloats); def->label = L("Loading speed"); @@ -577,7 +577,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 28. }; + def->set_default_value(new ConfigOptionFloats { 28. }); def = this->add("filament_loading_speed_start", coFloats); def->label = L("Loading speed at the start"); @@ -585,7 +585,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 3. }; + def->set_default_value(new ConfigOptionFloats { 3. }); def = this->add("filament_unloading_speed", coFloats); def->label = L("Unloading speed"); @@ -594,7 +594,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 90. }; + def->set_default_value(new ConfigOptionFloats { 90. }); def = this->add("filament_unloading_speed_start", coFloats); def->label = L("Unloading speed at the start"); @@ -602,7 +602,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 100. }; + def->set_default_value(new ConfigOptionFloats { 100. }); def = this->add("filament_toolchange_delay", coFloats); def->label = L("Delay after unloading"); @@ -612,7 +612,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("filament_cooling_moves", coInts); def->label = L("Number of cooling moves"); @@ -621,7 +621,7 @@ void PrintConfigDef::init_fff_params() def->max = 0; def->max = 20; def->mode = comExpert; - def->default_value = new ConfigOptionInts { 4 }; + def->set_default_value(new ConfigOptionInts { 4 }); def = this->add("filament_cooling_initial_speed", coFloats); def->label = L("Speed of the first cooling move"); @@ -629,7 +629,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 2.2f }; + def->set_default_value(new ConfigOptionFloats { 2.2f }); def = this->add("filament_minimal_purge_on_wipe_tower", coFloats); def->label = L("Minimal purge on wipe tower"); @@ -640,7 +640,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm³"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 15.f }; + def->set_default_value(new ConfigOptionFloats { 15.f }); def = this->add("filament_cooling_final_speed", coFloats); def->label = L("Speed of the last cooling move"); @@ -648,7 +648,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 3.4f }; + def->set_default_value(new ConfigOptionFloats { 3.4f }); def = this->add("filament_load_time", coFloats); def->label = L("Filament load time"); @@ -656,14 +656,14 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 0.0f }; + def->set_default_value(new ConfigOptionFloats { 0.0f }); def = this->add("filament_ramming_parameters", coStrings); def->label = L("Ramming parameters"); def->tooltip = L("This string is edited by RammingDialog and contains ramming specific parameters "); def->mode = comExpert; - def->default_value = new ConfigOptionStrings { "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0|" - " 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" }; + def->set_default_value(new ConfigOptionStrings { "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0|" + " 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" }); def = this->add("filament_unload_time", coFloats); def->label = L("Filament unload time"); @@ -671,7 +671,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 0.0f }; + def->set_default_value(new ConfigOptionFloats { 0.0f }); def = this->add("filament_diameter", coFloats); def->label = L("Diameter"); @@ -679,7 +679,7 @@ void PrintConfigDef::init_fff_params() "and do multiple measurements along the filament, then compute the average."); def->sidetext = L("mm"); def->min = 0; - def->default_value = new ConfigOptionFloats { 3. }; + def->set_default_value(new ConfigOptionFloats { 3. }); def = this->add("filament_density", coFloats); def->label = L("Density"); @@ -688,7 +688,7 @@ void PrintConfigDef::init_fff_params() "of the length to volume. Better is to calculate the volume directly through displacement."); def->sidetext = L("g/cm³"); def->min = 0; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("filament_type", coStrings); def->label = L("Filament type"); @@ -705,23 +705,23 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("NGEN"); def->enum_values.push_back("PVA"); def->mode = comAdvanced; - def->default_value = new ConfigOptionStrings { "PLA" }; + def->set_default_value(new ConfigOptionStrings { "PLA" }); def = this->add("filament_soluble", coBools); def->label = L("Soluble material"); def->tooltip = L("Soluble material is most likely used for a soluble support."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBools { false }; + def->set_default_value(new ConfigOptionBools { false }); def = this->add("filament_cost", coFloats); def->label = L("Cost"); def->tooltip = L("Enter your filament cost per kg here. This is only for statistical information."); def->sidetext = L("money/kg"); def->min = 0; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("filament_settings_id", coStrings); - def->default_value = new ConfigOptionStrings { "" }; + def->set_default_value(new ConfigOptionStrings { "" }); def->cli = ConfigOptionDef::nocli; def = this->add("fill_angle", coFloat); @@ -734,7 +734,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 360; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(45); + def->set_default_value(new ConfigOptionFloat(45)); def = this->add("fill_density", coPercent); def->gui_type = "f_enum_open"; @@ -773,7 +773,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back("80%"); def->enum_labels.push_back("90%"); def->enum_labels.push_back("100%"); - def->default_value = new ConfigOptionPercent(20); + def->set_default_value(new ConfigOptionPercent(20)); def = this->add("fill_pattern", coEnum); def->label = L("Fill pattern"); @@ -806,7 +806,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Hilbert Curve")); def->enum_labels.push_back(L("Archimedean Chords")); def->enum_labels.push_back(L("Octagram Spiral")); - def->default_value = new ConfigOptionEnum(ipStars); + def->set_default_value(new ConfigOptionEnum(ipStars)); def = this->add("first_layer_acceleration", coFloat); def->label = L("First layer"); @@ -815,7 +815,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s²"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("first_layer_bed_temperature", coInts); def->label = L("First layer"); @@ -823,7 +823,7 @@ void PrintConfigDef::init_fff_params() "bed temperature control commands in the output."); def->max = 0; def->max = 300; - def->default_value = new ConfigOptionInts { 0 }; + def->set_default_value(new ConfigOptionInts { 0 }); def = this->add("first_layer_extrusion_width", coFloatOrPercent); def->label = L("First layer"); @@ -835,7 +835,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm or % (leave 0 for default)"); def->ratio_over = "first_layer_height"; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(200, true); + def->set_default_value(new ConfigOptionFloatOrPercent(200, true)); def = this->add("first_layer_height", coFloatOrPercent); def->label = L("First layer height"); @@ -846,7 +846,7 @@ void PrintConfigDef::init_fff_params() "over the default layer height."); def->sidetext = L("mm or %"); def->ratio_over = "layer_height"; - def->default_value = new ConfigOptionFloatOrPercent(0.35, false); + def->set_default_value(new ConfigOptionFloatOrPercent(0.35, false)); def = this->add("first_layer_speed", coFloatOrPercent); def->label = L("First layer speed"); @@ -856,7 +856,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s or %"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(30, false); + def->set_default_value(new ConfigOptionFloatOrPercent(30, false)); def = this->add("first_layer_temperature", coInts); def->label = L("First layer"); @@ -864,7 +864,7 @@ void PrintConfigDef::init_fff_params() "during print, set this to zero to disable temperature control commands in the output file."); def->min = 0; def->max = max_temp; - def->default_value = new ConfigOptionInts { 200 }; + def->set_default_value(new ConfigOptionInts { 200 }); def = this->add("gap_fill_speed", coFloat); def->label = L("Gap fill"); @@ -874,7 +874,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(20); + def->set_default_value(new ConfigOptionFloat(20)); def = this->add("gcode_comments", coBool); def->label = L("Verbose G-code"); @@ -882,7 +882,7 @@ void PrintConfigDef::init_fff_params() "If you print from SD card, the additional weight of the file could make your firmware " "slow down."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(0); + def->set_default_value(new ConfigOptionBool(0)); def = this->add("gcode_flavor", coEnum); def->label = L("G-code flavor"); @@ -911,7 +911,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back("Smoothie"); def->enum_labels.push_back(L("No extrusion")); def->mode = comExpert; - def->default_value = new ConfigOptionEnum(gcfRepRap); + def->set_default_value(new ConfigOptionEnum(gcfRepRap)); def = this->add("gcode_label_objects", coBool); def->label = L("Label objects"); @@ -919,7 +919,7 @@ void PrintConfigDef::init_fff_params() " which is useful for the Octoprint CancelObject plugin. This settings is NOT compatible with " "Single Extruder Multi Material setup and Wipe into Object / Wipe into Infill."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBool(0); + def->set_default_value(new ConfigOptionBool(0)); def = this->add("high_current_on_filament_swap", coBool); def->label = L("High extruder current on filament swap"); @@ -927,7 +927,7 @@ void PrintConfigDef::init_fff_params() " sequence to allow for rapid ramming feed rates and to overcome resistance when loading" " a filament with an ugly shaped tip."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(0); + def->set_default_value(new ConfigOptionBool(0)); def = this->add("infill_acceleration", coFloat); def->label = L("Infill"); @@ -936,7 +936,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s²"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("infill_every_layers", coInt); def->label = L("Combine infill every"); @@ -947,7 +947,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Combine infill every n layers"); def->min = 1; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(1); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("infill_extruder", coInt); def->label = L("Infill extruder"); @@ -955,7 +955,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("The extruder to use when printing infill."); def->min = 1; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(1); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("infill_extrusion_width", coFloatOrPercent); def->label = L("Infill"); @@ -966,13 +966,13 @@ void PrintConfigDef::init_fff_params() "If expressed as percentage (for example 90%) it will be computed over layer height."); def->sidetext = L("mm or % (leave 0 for default)"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(0, false); + def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); def = this->add("infill_first", coBool); def->label = L("Infill before perimeters"); def->tooltip = L("This option will switch the print order of perimeters and infill, making the latter first."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("infill_only_where_needed", coBool); def->label = L("Only infill where needed"); @@ -981,7 +981,7 @@ void PrintConfigDef::init_fff_params() "(it will act as internal support material). If enabled, slows down the G-code generation " "due to the multiple checks involved."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("infill_overlap", coFloatOrPercent); def->label = L("Infill/perimeters overlap"); @@ -992,7 +992,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm or %"); def->ratio_over = "perimeter_extrusion_width"; def->mode = comExpert; - def->default_value = new ConfigOptionFloatOrPercent(25, true); + def->set_default_value(new ConfigOptionFloatOrPercent(25, true)); def = this->add("infill_speed", coFloat); def->label = L("Infill"); @@ -1002,20 +1002,20 @@ void PrintConfigDef::init_fff_params() def->aliases = { "print_feed_rate", "infill_feed_rate" }; def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(80); + def->set_default_value(new ConfigOptionFloat(80)); def = this->add("inherits", coString); def->label = L("Inherits profile"); def->tooltip = L("Name of the profile, from which this profile inherits."); def->full_width = true; def->height = 5; - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; // The following value is to be stored into the project file (AMF, 3MF, Config ...) // and it contains a sum of "inherits" values over the print and filament profiles. def = this->add("inherits_cummulative", coStrings); - def->default_value = new ConfigOptionStrings(); + def->set_default_value(new ConfigOptionStrings()); def->cli = ConfigOptionDef::nocli; def = this->add("interface_shells", coBool); @@ -1025,7 +1025,7 @@ void PrintConfigDef::init_fff_params() "support material."); def->category = L("Layers and Perimeters"); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("layer_gcode", coString); def->label = L("After layer change G-code"); @@ -1037,7 +1037,7 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 5; def->mode = comExpert; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("remaining_times", coBool); def->label = L("Supports remaining times"); @@ -1046,13 +1046,13 @@ void PrintConfigDef::init_fff_params() " As of now only the Prusa i3 MK3 firmware recognizes M73." " Also the i3 MK3 firmware supports M73 Qxx Sxx for the silent mode."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("silent_mode", coBool); def->label = L("Supports silent mode"); def->tooltip = L("Set silent mode for the G-code flavor"); def->mode = comExpert; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); const int machine_limits_opt_width = 7; { @@ -1080,7 +1080,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats(axis.max_feedrate); + def->set_default_value(new ConfigOptionFloats(axis.max_feedrate)); // Add the machine acceleration limits for XYZE axes (M201) def = this->add("machine_max_acceleration_" + axis.name, coFloats); def->full_label = (boost::format(L("Maximum acceleration %1%")) % axis_upper).str(); @@ -1090,7 +1090,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats(axis.max_acceleration); + def->set_default_value(new ConfigOptionFloats(axis.max_acceleration)); // Add the machine jerk limits for XYZE axes (M205) def = this->add("machine_max_jerk_" + axis.name, coFloats); def->full_label = (boost::format(L("Maximum jerk %1%")) % axis_upper).str(); @@ -1100,7 +1100,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats(axis.max_jerk); + def->set_default_value(new ConfigOptionFloats(axis.max_jerk)); } } @@ -1113,7 +1113,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats{ 0., 0. }; + def->set_default_value(new ConfigOptionFloats{ 0., 0. }); // M205 T... [mm/sec] def = this->add("machine_min_travel_rate", coFloats); @@ -1124,7 +1124,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats{ 0., 0. }; + def->set_default_value(new ConfigOptionFloats{ 0., 0. }); // M204 S... [mm/sec^2] def = this->add("machine_max_acceleration_extruding", coFloats); @@ -1135,7 +1135,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats{ 1500., 1250. }; + def->set_default_value(new ConfigOptionFloats{ 1500., 1250. }); // M204 T... [mm/sec^2] def = this->add("machine_max_acceleration_retracting", coFloats); @@ -1146,7 +1146,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->width = machine_limits_opt_width; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats{ 1500., 1250. }; + def->set_default_value(new ConfigOptionFloats{ 1500., 1250. }); def = this->add("max_fan_speed", coInts); def->label = L("Max"); @@ -1155,7 +1155,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 100; def->mode = comExpert; - def->default_value = new ConfigOptionInts { 100 }; + def->set_default_value(new ConfigOptionInts { 100 }); def = this->add("max_layer_height", coFloats); def->label = L("Max"); @@ -1166,7 +1166,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("max_print_speed", coFloat); def->label = L("Max print speed"); @@ -1176,7 +1176,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 1; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(80); + def->set_default_value(new ConfigOptionFloat(80)); def = this->add("max_volumetric_speed", coFloat); def->label = L("Max volumetric speed"); @@ -1185,7 +1185,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm³/s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); #ifdef HAS_PRESSURE_EQUALIZER def = this->add("max_volumetric_extrusion_rate_slope_positive", coFloat); @@ -1197,7 +1197,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm³/s²"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("max_volumetric_extrusion_rate_slope_negative", coFloat); def->label = L("Max volumetric slope negative"); @@ -1208,7 +1208,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm³/s²"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); #endif /* HAS_PRESSURE_EQUALIZER */ def = this->add("min_fan_speed", coInts); @@ -1218,7 +1218,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 100; def->mode = comExpert; - def->default_value = new ConfigOptionInts { 35 }; + def->set_default_value(new ConfigOptionInts { 35 }); def = this->add("min_layer_height", coFloats); def->label = L("Min"); @@ -1227,7 +1227,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 0.07 }; + def->set_default_value(new ConfigOptionFloats { 0.07 }); def = this->add("min_print_speed", coFloats); def->label = L("Min print speed"); @@ -1235,7 +1235,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 10. }; + def->set_default_value(new ConfigOptionFloats { 10. }); def = this->add("min_skirt_length", coFloat); def->label = L("Minimal filament extrusion length"); @@ -1245,7 +1245,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("notes", coString); def->label = L("Configuration notes"); @@ -1255,13 +1255,13 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 13; def->mode = comAdvanced; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("nozzle_diameter", coFloats); def->label = L("Nozzle diameter"); def->tooltip = L("This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)"); def->sidetext = L("mm"); - def->default_value = new ConfigOptionFloats { 0.5 }; + def->set_default_value(new ConfigOptionFloats { 0.5 }); def = this->add("host_type", coEnum); def->label = L("Host Type"); @@ -1273,14 +1273,14 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back("OctoPrint"); def->enum_labels.push_back("Duet"); def->mode = comAdvanced; - def->default_value = new ConfigOptionEnum(htOctoPrint); + def->set_default_value(new ConfigOptionEnum(htOctoPrint)); def = this->add("only_retract_when_crossing_perimeters", coBool); def->label = L("Only retract when crossing perimeters"); def->tooltip = L("Disables retraction when the travel path does not exceed the upper layer's perimeters " "(and thus any ooze will be probably invisible)."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("ooze_prevention", coBool); def->label = L("Enable"); @@ -1288,7 +1288,7 @@ void PrintConfigDef::init_fff_params() "It will enable a tall skirt automatically and move extruders outside such " "skirt when changing temperatures."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("output_filename_format", coString); def->label = L("Output filename format"); @@ -1298,7 +1298,7 @@ void PrintConfigDef::init_fff_params() "[input_filename_base]."); def->full_width = true; def->mode = comExpert; - def->default_value = new ConfigOptionString("[input_filename_base]"); + def->set_default_value(new ConfigOptionString("[input_filename_base]")); def = this->add("overhangs", coBool); def->label = L("Detect bridging perimeters"); @@ -1306,7 +1306,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Experimental option to adjust flow for overhangs (bridge flow will be used), " "to apply bridge speed to them and enable fan."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("parking_pos_retraction", coFloat); def->label = L("Filament parking position"); @@ -1315,7 +1315,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(92.f); + def->set_default_value(new ConfigOptionFloat(92.f)); def = this->add("extra_loading_move", coFloat); def->label = L("Extra loading distance"); @@ -1324,7 +1324,7 @@ void PrintConfigDef::init_fff_params() " if negative, the loading move is shorter than unloading. "); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(-2.f); + def->set_default_value(new ConfigOptionFloat(-2.f)); def = this->add("perimeter_acceleration", coFloat); def->label = L("Perimeters"); @@ -1333,7 +1333,7 @@ void PrintConfigDef::init_fff_params() "Set zero to disable acceleration control for perimeters."); def->sidetext = L("mm/s²"); def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("perimeter_extruder", coInt); def->label = L("Perimeter extruder"); @@ -1342,7 +1342,7 @@ void PrintConfigDef::init_fff_params() def->aliases = { "perimeters_extruder" }; def->min = 1; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(1); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("perimeter_extrusion_width", coFloatOrPercent); def->label = L("Perimeters"); @@ -1354,7 +1354,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm or % (leave 0 for default)"); def->aliases = { "perimeters_extrusion_width" }; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(0, false); + def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); def = this->add("perimeter_speed", coFloat); def->label = L("Perimeters"); @@ -1364,7 +1364,7 @@ void PrintConfigDef::init_fff_params() def->aliases = { "perimeter_feed_rate" }; def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(60); + def->set_default_value(new ConfigOptionFloat(60)); def = this->add("perimeters", coInt); def->label = L("Perimeters"); @@ -1377,7 +1377,7 @@ void PrintConfigDef::init_fff_params() def->aliases = { "perimeter_offsets" }; def->min = 0; def->max = 10000; - def->default_value = new ConfigOptionInt(3); + def->set_default_value(new ConfigOptionInt(3)); def = this->add("post_process", coStrings); def->label = L("Post-processing scripts"); @@ -1390,12 +1390,12 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 6; def->mode = comExpert; - def->default_value = new ConfigOptionStrings(); + def->set_default_value(new ConfigOptionStrings()); def = this->add("printer_model", coString); def->label = L("Printer type"); def->tooltip = L("Type of the printer."); - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; def = this->add("printer_notes", coString); @@ -1405,26 +1405,26 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 13; def->mode = comAdvanced; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("printer_vendor", coString); def->label = L("Printer vendor"); def->tooltip = L("Name of the printer vendor."); - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; def = this->add("printer_variant", coString); def->label = L("Printer variant"); def->tooltip = L("Name of the printer variant. For example, the printer variants may be differentiated by a nozzle diameter."); - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; def = this->add("print_settings_id", coString); - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def->cli = ConfigOptionDef::nocli; def = this->add("printer_settings_id", coString); - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def->cli = ConfigOptionDef::nocli; def = this->add("raft_layers", coInt); @@ -1435,7 +1435,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("layers"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(0); + def->set_default_value(new ConfigOptionInt(0)); def = this->add("resolution", coFloat); def->label = L("Resolution"); @@ -1446,14 +1446,14 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("retract_before_travel", coFloats); def->label = L("Minimum travel after retraction"); def->tooltip = L("Retraction is not triggered when travel moves are shorter than this length."); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 2. }; + def->set_default_value(new ConfigOptionFloats { 2. }); def = this->add("retract_before_wipe", coPercents); def->label = L("Retract amount before wipe"); @@ -1461,13 +1461,13 @@ void PrintConfigDef::init_fff_params() "before doing the wipe movement."); def->sidetext = L("%"); def->mode = comAdvanced; - def->default_value = new ConfigOptionPercents { 0. }; + def->set_default_value(new ConfigOptionPercents { 0. }); def = this->add("retract_layer_change", coBools); def->label = L("Retract on layer change"); def->tooltip = L("This flag enforces a retraction whenever a Z move is done."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBools { false }; + def->set_default_value(new ConfigOptionBools { false }); def = this->add("retract_length", coFloats); def->label = L("Length"); @@ -1475,7 +1475,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("When retraction is triggered, filament is pulled back by the specified amount " "(the length is measured on raw filament, before it enters the extruder)."); def->sidetext = L("mm (zero to disable)"); - def->default_value = new ConfigOptionFloats { 2. }; + def->set_default_value(new ConfigOptionFloats { 2. }); def = this->add("retract_length_toolchange", coFloats); def->label = L("Length"); @@ -1485,7 +1485,7 @@ void PrintConfigDef::init_fff_params() "the extruder)."); def->sidetext = L("mm (zero to disable)"); def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 10. }; + def->set_default_value(new ConfigOptionFloats { 10. }); def = this->add("retract_lift", coFloats); def->label = L("Lift Z"); @@ -1493,7 +1493,7 @@ void PrintConfigDef::init_fff_params() "is triggered. When using multiple extruders, only the setting for the first extruder " "will be considered."); def->sidetext = L("mm"); - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("retract_lift_above", coFloats); def->label = L("Above Z"); @@ -1502,7 +1502,7 @@ void PrintConfigDef::init_fff_params() "absolute Z. You can tune this setting for skipping lift on the first layers."); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("retract_lift_below", coFloats); def->label = L("Below Z"); @@ -1512,7 +1512,7 @@ void PrintConfigDef::init_fff_params() "to the first layers."); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("retract_restart_extra", coFloats); def->label = L("Extra length on restart"); @@ -1520,7 +1520,7 @@ void PrintConfigDef::init_fff_params() "this additional amount of filament. This setting is rarely needed."); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("retract_restart_extra_toolchange", coFloats); def->label = L("Extra length on restart"); @@ -1528,7 +1528,7 @@ void PrintConfigDef::init_fff_params() "this additional amount of filament."); def->sidetext = L("mm"); def->mode = comExpert; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("retract_speed", coFloats); def->label = L("Retraction Speed"); @@ -1536,7 +1536,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("The speed for retractions (it only applies to the extruder motor)."); def->sidetext = L("mm/s"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 40. }; + def->set_default_value(new ConfigOptionFloats { 40. }); def = this->add("deretract_speed", coFloats); def->label = L("Deretraction Speed"); @@ -1545,7 +1545,7 @@ void PrintConfigDef::init_fff_params() "(it only applies to the extruder motor). If left to zero, the retraction speed is used."); def->sidetext = L("mm/s"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloats { 0. }; + def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("seam_position", coEnum); def->label = L("Seam position"); @@ -1561,7 +1561,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Aligned")); def->enum_labels.push_back(L("Rear")); def->mode = comSimple; - def->default_value = new ConfigOptionEnum(spAligned); + def->set_default_value(new ConfigOptionEnum(spAligned)); #if 0 def = this->add("seam_preferred_direction", coFloat); @@ -1572,7 +1572,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Seam preferred direction"); def->min = 0; def->max = 360; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("seam_preferred_direction_jitter", coFloat); // def->gui_type = "slider"; @@ -1582,7 +1582,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Preferred direction of the seam - jitter"); def->min = 0; def->max = 360; - def->default_value = new ConfigOptionFloat(30); + def->set_default_value(new ConfigOptionFloat(30)); #endif def = this->add("serial_port", coString); @@ -1591,7 +1591,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Serial port"); def->tooltip = L("USB/serial port for printer connection."); def->width = 20; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("serial_speed", coInt); def->gui_type = "i_enum_open"; @@ -1603,7 +1603,7 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("115200"); def->enum_values.push_back("250000"); def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(250000); + def->set_default_value(new ConfigOptionInt(250000)); def = this->add("skirt_distance", coFloat); def->label = L("Distance from object"); @@ -1611,7 +1611,7 @@ void PrintConfigDef::init_fff_params() "to the object(s) and get a brim for better adhesion."); def->sidetext = L("mm"); def->min = 0; - def->default_value = new ConfigOptionFloat(6); + def->set_default_value(new ConfigOptionFloat(6)); def = this->add("skirt_height", coInt); def->label = L("Skirt height"); @@ -1619,7 +1619,7 @@ void PrintConfigDef::init_fff_params() "as a shield against drafts."); def->sidetext = L("layers"); def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(1); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("skirts", coInt); def->label = L("Loops (minimum)"); @@ -1629,7 +1629,7 @@ void PrintConfigDef::init_fff_params() "to disable skirt completely."); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(1); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("slowdown_below_layer_time", coInts); def->label = L("Slow down if layer print time is below"); @@ -1640,7 +1640,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 1000; def->mode = comExpert; - def->default_value = new ConfigOptionInts { 5 }; + def->set_default_value(new ConfigOptionInts { 5 }); def = this->add("small_perimeter_speed", coFloatOrPercent); def->label = L("Small perimeters"); @@ -1652,7 +1652,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "perimeter_speed"; def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(15, false); + def->set_default_value(new ConfigOptionFloatOrPercent(15, false)); def = this->add("solid_infill_below_area", coFloat); def->label = L("Solid infill threshold area"); @@ -1661,7 +1661,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm²"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(70); + def->set_default_value(new ConfigOptionFloat(70)); def = this->add("solid_infill_extruder", coInt); def->label = L("Solid infill extruder"); @@ -1669,7 +1669,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("The extruder to use when printing solid infill."); def->min = 1; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(1); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("solid_infill_every_layers", coInt); def->label = L("Solid infill every"); @@ -1681,7 +1681,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("layers"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionInt(0); + def->set_default_value(new ConfigOptionInt(0)); def = this->add("solid_infill_extrusion_width", coFloatOrPercent); def->label = L("Solid infill"); @@ -1691,7 +1691,7 @@ void PrintConfigDef::init_fff_params() "If expressed as percentage (for example 90%) it will be computed over layer height."); def->sidetext = L("mm or % (leave 0 for default)"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(0, false); + def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); def = this->add("solid_infill_speed", coFloatOrPercent); def->label = L("Solid infill"); @@ -1704,7 +1704,7 @@ void PrintConfigDef::init_fff_params() def->aliases = { "solid_infill_feed_rate" }; def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(20, false); + def->set_default_value(new ConfigOptionFloatOrPercent(20, false)); def = this->add("solid_layers", coInt); def->label = L("Solid layers"); @@ -1720,7 +1720,7 @@ void PrintConfigDef::init_fff_params() "no infill, no top solid layers and no support material. You can still set " "any number of bottom solid layers as well as skirt/brim loops. " "It won't work when printing more than an object."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("standby_temperature_delta", coInt); def->label = L("Temperature variation"); @@ -1730,7 +1730,7 @@ void PrintConfigDef::init_fff_params() def->min = -max_temp; def->max = max_temp; def->mode = comExpert; - def->default_value = new ConfigOptionInt(-5); + def->set_default_value(new ConfigOptionInt(-5)); def = this->add("start_gcode", coString); def->label = L("Start G-code"); @@ -1745,7 +1745,7 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 12; def->mode = comExpert; - def->default_value = new ConfigOptionString("G28 ; home all axes\nG1 Z5 F5000 ; lift nozzle\n"); + def->set_default_value(new ConfigOptionString("G28 ; home all axes\nG1 Z5 F5000 ; lift nozzle\n")); def = this->add("start_filament_gcode", coStrings); def->label = L("Start G-code"); @@ -1761,25 +1761,25 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 12; def->mode = comExpert; - def->default_value = new ConfigOptionStrings { "; Filament gcode\n" }; + def->set_default_value(new ConfigOptionStrings { "; Filament gcode\n" }); def = this->add("single_extruder_multi_material", coBool); def->label = L("Single Extruder Multi Material"); def->tooltip = L("The printer multiplexes filaments into a single hot end."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("single_extruder_multi_material_priming", coBool); def->label = L("Prime all printing extruders"); def->tooltip = L("If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("support_material", coBool); def->label = L("Generate support material"); def->category = L("Support material"); def->tooltip = L("Enable support material generation."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("support_material_auto", coBool); def->label = L("Auto generated supports"); @@ -1787,7 +1787,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("If checked, supports will be generated automatically based on the overhang threshold value."\ " If unchecked, supports will be generated inside the \"Support Enforcer\" volumes only."); def->mode = comSimple; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("support_material_xy_spacing", coFloatOrPercent); def->label = L("XY separation between an object and its support"); @@ -1799,7 +1799,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->mode = comAdvanced; // Default is half the external perimeter width. - def->default_value = new ConfigOptionFloatOrPercent(50, true); + def->set_default_value(new ConfigOptionFloatOrPercent(50, true)); def = this->add("support_material_angle", coFloat); def->label = L("Pattern angle"); @@ -1809,14 +1809,14 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 359; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("support_material_buildplate_only", coBool); def->label = L("Support on build plate only"); def->category = L("Support material"); def->tooltip = L("Only create support if it lies on a build plate. Don't create support on a print."); def->mode = comSimple; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("support_material_contact_distance", coFloat); def->gui_type = "f_enum_open"; @@ -1832,7 +1832,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back((boost::format("0 (%1%)") % L("soluble")).str()); def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("detachable")).str()); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0.2); + def->set_default_value(new ConfigOptionFloat(0.2)); def = this->add("support_material_enforce_layers", coInt); def->label = L("Enforce support for the first"); @@ -1845,7 +1845,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Enforce support for the first n layers"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionInt(0); + def->set_default_value(new ConfigOptionInt(0)); def = this->add("support_material_extruder", coInt); def->label = L("Support material/raft/skirt extruder"); @@ -1854,7 +1854,7 @@ void PrintConfigDef::init_fff_params() "(1+, 0 to use the current extruder to minimize tool changes)."); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(1); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("support_material_extrusion_width", coFloatOrPercent); def->label = L("Support material"); @@ -1864,14 +1864,14 @@ void PrintConfigDef::init_fff_params() "If expressed as percentage (for example 90%) it will be computed over layer height."); def->sidetext = L("mm or % (leave 0 for default)"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(0, false); + def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); def = this->add("support_material_interface_contact_loops", coBool); def->label = L("Interface loops"); def->category = L("Support material"); def->tooltip = L("Cover the top contact layer of the supports with loops. Disabled by default."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("support_material_interface_extruder", coInt); def->label = L("Support material/raft interface extruder"); @@ -1880,7 +1880,7 @@ void PrintConfigDef::init_fff_params() "(1+, 0 to use the current extruder to minimize tool changes). This affects raft too."); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(1); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("support_material_interface_layers", coInt); def->label = L("Interface layers"); @@ -1889,7 +1889,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("layers"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(3); + def->set_default_value(new ConfigOptionInt(3)); def = this->add("support_material_interface_spacing", coFloat); def->label = L("Interface pattern spacing"); @@ -1898,7 +1898,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("support_material_interface_speed", coFloatOrPercent); def->label = L("Support material interface"); @@ -1909,7 +1909,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "support_material_speed"; def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(100, true); + def->set_default_value(new ConfigOptionFloatOrPercent(100, true)); def = this->add("support_material_pattern", coEnum); def->label = L("Pattern"); @@ -1923,7 +1923,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Rectilinear grid")); def->enum_labels.push_back(L("Honeycomb")); def->mode = comAdvanced; - def->default_value = new ConfigOptionEnum(smpRectilinear); + def->set_default_value(new ConfigOptionEnum(smpRectilinear)); def = this->add("support_material_spacing", coFloat); def->label = L("Pattern spacing"); @@ -1932,7 +1932,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(2.5); + def->set_default_value(new ConfigOptionFloat(2.5)); def = this->add("support_material_speed", coFloat); def->label = L("Support material"); @@ -1941,7 +1941,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(60); + def->set_default_value(new ConfigOptionFloat(60)); def = this->add("support_material_synchronize_layers", coBool); def->label = L("Synchronize with object layers"); @@ -1949,7 +1949,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Synchronize support layers with the object print layers. This is useful " "with multi-material printers, where the extruder switch is expensive."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("support_material_threshold", coInt); def->label = L("Overhang threshold"); @@ -1963,7 +1963,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 90; def->mode = comAdvanced; - def->default_value = new ConfigOptionInt(0); + def->set_default_value(new ConfigOptionInt(0)); def = this->add("support_material_with_sheath", coBool); def->label = L("With sheath around the support"); @@ -1971,7 +1971,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Add a sheath (a single perimeter line) around the base support. This makes " "the support more reliable, but also more difficult to remove."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("temperature", coInts); def->label = L("Other layers"); @@ -1980,7 +1980,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Temperature"); def->min = 0; def->max = max_temp; - def->default_value = new ConfigOptionInts { 200 }; + def->set_default_value(new ConfigOptionInts { 200 }); def = this->add("thin_walls", coBool); def->label = L("Detect thin walls"); @@ -1988,7 +1988,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Detect single-width walls (parts where two extrusions don't fit and we need " "to collapse them into a single trace)."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("threads", coInt); def->label = L("Threads"); @@ -1998,7 +1998,7 @@ void PrintConfigDef::init_fff_params() def->min = 1; { int threads = (unsigned int)boost::thread::hardware_concurrency(); - def->default_value = new ConfigOptionInt(threads > 0 ? threads : 2); + def->set_default_value(new ConfigOptionInt(threads > 0 ? threads : 2)); def->cli == ConfigOptionDef::nocli; } @@ -2011,7 +2011,7 @@ void PrintConfigDef::init_fff_params() def->full_width = true; def->height = 5; def->mode = comExpert; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("top_infill_extrusion_width", coFloatOrPercent); def->label = L("Top solid infill"); @@ -2022,7 +2022,7 @@ void PrintConfigDef::init_fff_params() "If expressed as percentage (for example 90%) it will be computed over layer height."); def->sidetext = L("mm or % (leave 0 for default)"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(0, false); + def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); def = this->add("top_solid_infill_speed", coFloatOrPercent); def->label = L("Top solid infill"); @@ -2036,7 +2036,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "solid_infill_speed"; def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloatOrPercent(15, false); + def->set_default_value(new ConfigOptionFloatOrPercent(15, false)); def = this->add("top_solid_layers", coInt); //TRN To be shown in Print Settings "Top solid layers" @@ -2045,7 +2045,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Number of solid layers to generate on top surfaces."); def->full_label = L("Top solid layers"); def->min = 0; - def->default_value = new ConfigOptionInt(3); + def->set_default_value(new ConfigOptionInt(3)); def = this->add("travel_speed", coFloat); def->label = L("Travel"); @@ -2054,21 +2054,21 @@ void PrintConfigDef::init_fff_params() def->aliases = { "travel_feed_rate" }; def->min = 1; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(130); + def->set_default_value(new ConfigOptionFloat(130)); def = this->add("use_firmware_retraction", coBool); def->label = L("Use firmware retraction"); def->tooltip = L("This experimental setting uses G10 and G11 commands to have the firmware " "handle the retraction. This is only supported in recent Marlin."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("use_relative_e_distances", coBool); def->label = L("Use relative E distances"); def->tooltip = L("If your firmware requires relative E values, check this, " "otherwise leave it unchecked. Most firmwares use absolute values."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("use_volumetric_e", coBool); def->label = L("Use volumetric E"); @@ -2079,73 +2079,73 @@ void PrintConfigDef::init_fff_params() "diameter associated to the filament selected in Slic3r. This is only supported " "in recent Marlin."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("variable_layer_height", coBool); def->label = L("Enable variable layer height feature"); def->tooltip = L("Some printers or printer setups may have difficulties printing " "with a variable layer height. Enabled by default."); def->mode = comExpert; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("wipe", coBools); def->label = L("Wipe while retracting"); def->tooltip = L("This flag will move the nozzle while retracting to minimize the possible blob " "on leaky extruders."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBools { false }; + def->set_default_value(new ConfigOptionBools { false }); def = this->add("wipe_tower", coBool); def->label = L("Enable"); def->tooltip = L("Multi material printers may need to prime or purge extruders on tool changes. " "Extrude the excess material into the wipe tower."); def->mode = comAdvanced; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("wiping_volumes_extruders", coFloats); def->label = L("Purging volumes - load/unload volumes"); def->tooltip = L("This vector saves required volumes to change from/to each tool used on the " "wipe tower. These values are used to simplify creation of the full purging " "volumes below. "); - def->default_value = new ConfigOptionFloats { 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f }; + def->set_default_value(new ConfigOptionFloats { 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f }); def = this->add("wiping_volumes_matrix", coFloats); def->label = L("Purging volumes - matrix"); def->tooltip = L("This matrix describes volumes (in cubic milimetres) required to purge the" " new filament on the wipe tower for any given pair of tools. "); - def->default_value = new ConfigOptionFloats { 0.f, 140.f, 140.f, 140.f, 140.f, - 140.f, 0.f, 140.f, 140.f, 140.f, - 140.f, 140.f, 0.f, 140.f, 140.f, - 140.f, 140.f, 140.f, 0.f, 140.f, - 140.f, 140.f, 140.f, 140.f, 0.f }; + def->set_default_value(new ConfigOptionFloats { 0.f, 140.f, 140.f, 140.f, 140.f, + 140.f, 0.f, 140.f, 140.f, 140.f, + 140.f, 140.f, 0.f, 140.f, 140.f, + 140.f, 140.f, 140.f, 0.f, 140.f, + 140.f, 140.f, 140.f, 140.f, 0.f }); def = this->add("wipe_tower_x", coFloat); def->label = L("Position X"); def->tooltip = L("X coordinate of the left front corner of a wipe tower"); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(180.); + def->set_default_value(new ConfigOptionFloat(180.)); def = this->add("wipe_tower_y", coFloat); def->label = L("Position Y"); def->tooltip = L("Y coordinate of the left front corner of a wipe tower"); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(140.); + def->set_default_value(new ConfigOptionFloat(140.)); def = this->add("wipe_tower_width", coFloat); def->label = L("Width"); def->tooltip = L("Width of a wipe tower"); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(60.); + def->set_default_value(new ConfigOptionFloat(60.)); def = this->add("wipe_tower_rotation_angle", coFloat); def->label = L("Wipe tower rotation angle"); def->tooltip = L("Wipe tower rotation angle with respect to x-axis "); def->sidetext = L("°"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0.); + def->set_default_value(new ConfigOptionFloat(0.)); def = this->add("wipe_into_infill", coBool); def->category = L("Extruders"); @@ -2153,7 +2153,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Purging after toolchange will done inside this object's infills. " "This lowers the amount of waste but may result in longer print time " " due to additional travel moves."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("wipe_into_objects", coBool); def->category = L("Extruders"); @@ -2161,14 +2161,14 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Object will be used to purge the nozzle after a toolchange to save material " "that would otherwise end up in the wipe tower and decrease print time. " "Colours of the objects will be mixed as a result."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("wipe_tower_bridging", coFloat); def->label = L("Maximal bridging distance"); def->tooltip = L("Maximal distance between supports on sparse infill sections. "); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(10.); + def->set_default_value(new ConfigOptionFloat(10.)); def = this->add("xy_size_compensation", coFloat); def->label = L("XY Size Compensation"); @@ -2178,7 +2178,7 @@ void PrintConfigDef::init_fff_params() "for fine-tuning hole sizes."); def->sidetext = L("mm"); def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("z_offset", coFloat); def->label = L("Z offset"); @@ -2188,7 +2188,7 @@ void PrintConfigDef::init_fff_params() "from the print bed, set this to -0.3 (or fix your endstop)."); def->sidetext = L("mm"); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); } void PrintConfigDef::init_sla_params() @@ -2202,26 +2202,26 @@ void PrintConfigDef::init_sla_params() def->label = L("Display width"); def->tooltip = L("Width of the display"); def->min = 1; - def->default_value = new ConfigOptionFloat(120.); + def->set_default_value(new ConfigOptionFloat(120.)); def = this->add("display_height", coFloat); def->label = L("Display height"); def->tooltip = L("Height of the display"); def->min = 1; - def->default_value = new ConfigOptionFloat(68.); + def->set_default_value(new ConfigOptionFloat(68.)); def = this->add("display_pixels_x", coInt); def->full_label = L("Number of pixels in"); def->label = ("X"); def->tooltip = L("Number of pixels in X"); def->min = 100; - def->default_value = new ConfigOptionInt(2560); + def->set_default_value(new ConfigOptionInt(2560)); def = this->add("display_pixels_y", coInt); def->label = ("Y"); def->tooltip = L("Number of pixels in Y"); def->min = 100; - def->default_value = new ConfigOptionInt(1440); + def->set_default_value(new ConfigOptionInt(1440)); def = this->add("display_orientation", coEnum); def->label = L("Display orientation"); @@ -2234,7 +2234,7 @@ void PrintConfigDef::init_sla_params() def->enum_labels.push_back(L("Landscape")); def->enum_labels.push_back(L("Portrait")); def->mode = comExpert; - def->default_value = new ConfigOptionEnum(sladoPortrait); + def->set_default_value(new ConfigOptionEnum(sladoPortrait)); def = this->add("fast_tilt_time", coFloat); def->label = L("Fast"); @@ -2243,7 +2243,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(5.); + def->set_default_value(new ConfigOptionFloat(5.)); def = this->add("slow_tilt_time", coFloat); def->label = L("Slow"); @@ -2252,7 +2252,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("s"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(8.); + def->set_default_value(new ConfigOptionFloat(8.)); def = this->add("area_fill", coFloat); def->label = L("Area fill"); @@ -2260,7 +2260,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("%"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(50.); + def->set_default_value(new ConfigOptionFloat(50.)); def = this->add("relative_correction", coFloats); def->label = L("Printer scaling correction"); @@ -2268,7 +2268,7 @@ void PrintConfigDef::init_sla_params() def->tooltip = L("Printer scaling correction"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats( { 1., 1. } ); + def->set_default_value(new ConfigOptionFloats( { 1., 1. } )); def = this->add("absolute_correction", coFloat); def->label = L("Printer absolute correction"); @@ -2276,7 +2276,7 @@ void PrintConfigDef::init_sla_params() def->tooltip = L("Will inflate or deflate the sliced 2D polygons according " "to the sign of the correction."); def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0.0); + def->set_default_value(new ConfigOptionFloat(0.0)); def = this->add("gamma_correction", coFloat); def->label = L("Printer gamma correction"); @@ -2287,7 +2287,7 @@ void PrintConfigDef::init_sla_params() "antialiasing without losing holes in polygons."); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(1.0); + def->set_default_value(new ConfigOptionFloat(1.0)); // SLA Material settings. @@ -2296,7 +2296,7 @@ void PrintConfigDef::init_sla_params() def->tooltip = L("Initial layer height"); def->sidetext = L("mm"); def->min = 0; - def->default_value = new ConfigOptionFloat(0.3); + def->set_default_value(new ConfigOptionFloat(0.3)); def = this->add("faded_layers", coInt); def->label = L("Faded layers"); @@ -2304,28 +2304,28 @@ void PrintConfigDef::init_sla_params() def->min = 3; def->max = 20; def->mode = comExpert; - def->default_value = new ConfigOptionInt(10); + def->set_default_value(new ConfigOptionInt(10)); def = this->add("exposure_time", coFloat); def->label = L("Exposure time"); def->tooltip = L("Exposure time"); def->sidetext = L("s"); def->min = 0; - def->default_value = new ConfigOptionFloat(10); + def->set_default_value(new ConfigOptionFloat(10)); def = this->add("initial_exposure_time", coFloat); def->label = L("Initial exposure time"); def->tooltip = L("Initial exposure time"); def->sidetext = L("s"); def->min = 0; - def->default_value = new ConfigOptionFloat(15); + def->set_default_value(new ConfigOptionFloat(15)); def = this->add("material_correction", coFloats); def->full_label = L("Correction for expansion"); def->tooltip = L("Correction for expansion"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloats( { 1. , 1. } ); + def->set_default_value(new ConfigOptionFloats( { 1. , 1. } )); def = this->add("material_notes", coString); def->label = L("SLA print material notes"); @@ -2334,28 +2334,28 @@ void PrintConfigDef::init_sla_params() def->full_width = true; def->height = 13; def->mode = comAdvanced; - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def = this->add("default_sla_material_profile", coString); def->label = L("Default SLA material profile"); def->tooltip = L("Default print profile associated with the current printer profile. " "On selection of the current printer profile, this print profile will be activated."); - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; def = this->add("sla_material_settings_id", coString); - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def->cli = ConfigOptionDef::nocli; def = this->add("default_sla_print_profile", coString); def->label = L("Default SLA material profile"); def->tooltip = L("Default print profile associated with the current printer profile. " "On selection of the current printer profile, this print profile will be activated."); - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; def = this->add("sla_print_settings_id", coString); - def->default_value = new ConfigOptionString(""); + def->set_default_value(new ConfigOptionString("")); def->cli = ConfigOptionDef::nocli; def = this->add("supports_enable", coBool); @@ -2363,7 +2363,7 @@ void PrintConfigDef::init_sla_params() def->category = L("Supports"); def->tooltip = L("Generate supports for the models"); def->mode = comSimple; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("support_head_front_diameter", coFloat); def->label = L("Support head front diameter"); @@ -2372,7 +2372,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0.4); + def->set_default_value(new ConfigOptionFloat(0.4)); def = this->add("support_head_penetration", coFloat); def->label = L("Support head penetration"); @@ -2381,7 +2381,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("mm"); def->mode = comAdvanced; def->min = 0; - def->default_value = new ConfigOptionFloat(0.2); + def->set_default_value(new ConfigOptionFloat(0.2)); def = this->add("support_head_width", coFloat); def->label = L("Support head width"); @@ -2391,7 +2391,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->max = 20; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(1.0); + def->set_default_value(new ConfigOptionFloat(1.0)); def = this->add("support_pillar_diameter", coFloat); def->label = L("Support pillar diameter"); @@ -2401,7 +2401,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->max = 15; def->mode = comSimple; - def->default_value = new ConfigOptionFloat(1.0); + def->set_default_value(new ConfigOptionFloat(1.0)); def = this->add("support_pillar_connection_mode", coEnum); def->label = L("Support pillar connection mode"); @@ -2417,14 +2417,14 @@ void PrintConfigDef::init_sla_params() def->enum_labels.push_back(L("Cross")); def->enum_labels.push_back(L("Dynamic")); def->mode = comAdvanced; - def->default_value = new ConfigOptionEnum(slapcmDynamic); + def->set_default_value(new ConfigOptionEnum(slapcmDynamic)); def = this->add("support_buildplate_only", coBool); def->label = L("Support on build plate only"); def->category = L("Supports"); def->tooltip = L("Only create support if it lies on a build plate. Don't create support on a print."); def->mode = comSimple; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("support_pillar_widening_factor", coFloat); def->label = L("Pillar widening factor"); @@ -2435,7 +2435,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->max = 1; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0.0); + def->set_default_value(new ConfigOptionFloat(0.0)); def = this->add("support_base_diameter", coFloat); def->label = L("Support base diameter"); @@ -2445,7 +2445,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->max = 30; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(4.0); + def->set_default_value(new ConfigOptionFloat(4.0)); def = this->add("support_base_height", coFloat); def->label = L("Support base height"); @@ -2454,7 +2454,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(1.0); + def->set_default_value(new ConfigOptionFloat(1.0)); def = this->add("support_critical_angle", coFloat); def->label = L("Critical angle"); @@ -2464,7 +2464,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->max = 90; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(45); + def->set_default_value(new ConfigOptionFloat(45)); def = this->add("support_max_bridge_length", coFloat); def->label = L("Max bridge length"); @@ -2473,7 +2473,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(15.0); + def->set_default_value(new ConfigOptionFloat(15.0)); def = this->add("support_max_pillar_link_distance", coFloat); def->label = L("Max pillar linking distance"); @@ -2483,7 +2483,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("mm"); def->min = 0; // 0 means no linking def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(10.0); + def->set_default_value(new ConfigOptionFloat(10.0)); def = this->add("support_object_elevation", coFloat); def->label = L("Object elevation"); @@ -2493,7 +2493,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->max = 150; // This is the max height of print on SL1 def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(5.0); + def->set_default_value(new ConfigOptionFloat(5.0)); def = this->add("support_points_density_relative", coInt); def->label = L("Support points density"); @@ -2501,7 +2501,7 @@ void PrintConfigDef::init_sla_params() def->tooltip = L("This is a relative measure of support points density."); def->sidetext = L("%"); def->min = 0; - def->default_value = new ConfigOptionInt(100); + def->set_default_value(new ConfigOptionInt(100)); def = this->add("support_points_minimal_distance", coFloat); def->label = L("Minimal distance of the support points"); @@ -2509,14 +2509,14 @@ void PrintConfigDef::init_sla_params() def->tooltip = L("No support points will be placed closer than this threshold."); def->sidetext = L("mm"); def->min = 0; - def->default_value = new ConfigOptionFloat(1.f); + def->set_default_value(new ConfigOptionFloat(1.f)); def = this->add("pad_enable", coBool); def->label = L("Use pad"); def->category = L("Pad"); def->tooltip = L("Add a pad underneath the supported model"); def->mode = comSimple; - def->default_value = new ConfigOptionBool(true); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("pad_wall_thickness", coFloat); def->label = L("Pad wall thickness"); @@ -2526,7 +2526,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->max = 30; def->mode = comSimple; - def->default_value = new ConfigOptionFloat(2.0); + def->set_default_value(new ConfigOptionFloat(2.0)); def = this->add("pad_wall_height", coFloat); def->label = L("Pad wall height"); @@ -2540,7 +2540,7 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->max = 30; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(0.); + def->set_default_value(new ConfigOptionFloat(0.)); def = this->add("pad_max_merge_distance", coFloat); def->label = L("Max merge distance"); @@ -2552,7 +2552,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("mm"); def->min = 0; def->mode = comExpert; - def->default_value = new ConfigOptionFloat(50.0); + def->set_default_value(new ConfigOptionFloat(50.0)); // This is disabled on the UI. I hope it will never be enabled. def = this->add("pad_edge_radius", coFloat); @@ -2562,7 +2562,7 @@ void PrintConfigDef::init_sla_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(1.0); + def->set_default_value(new ConfigOptionFloat(1.0)); def = this->add("pad_wall_slope", coFloat); def->label = L("Pad wall slope"); @@ -2573,7 +2573,7 @@ void PrintConfigDef::init_sla_params() def->min = 45; def->max = 90; def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(45.0); + def->set_default_value(new ConfigOptionFloat(45.0)); } void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value) @@ -2930,73 +2930,73 @@ CLIActionsConfigDef::CLIActionsConfigDef() def = this->add("export_obj", coBool); def->label = L("Export OBJ"); def->tooltip = L("Export the model(s) as OBJ."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); /* def = this->add("export_svg", coBool); def->label = L("Export SVG"); def->tooltip = L("Slice the model and export solid slices as SVG."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); */ def = this->add("export_sla", coBool); def->label = L("Export SLA"); def->tooltip = L("Slice the model and export SLA printing layers as PNG."); def->cli = "export-sla|sla"; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("export_3mf", coBool); def->label = L("Export 3MF"); def->tooltip = L("Export the model(s) as 3MF."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("export_amf", coBool); def->label = L("Export AMF"); def->tooltip = L("Export the model(s) as AMF."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("export_stl", coBool); def->label = L("Export STL"); def->tooltip = L("Export the model(s) as STL."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("export_gcode", coBool); def->label = L("Export G-code"); def->tooltip = L("Slice the model and export toolpaths as G-code."); def->cli = "export-gcode|gcode|g"; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("slice", coBool); def->label = L("Slice"); def->tooltip = L("Slice the model as FFF or SLA based on the printer_technology configuration value."); def->cli = "slice|s"; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("help", coBool); def->label = L("Help"); def->tooltip = L("Show this help."); def->cli = "help|h"; - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("help_fff", coBool); def->label = L("Help (FFF options)"); def->tooltip = L("Show the full list of print/G-code configuration options."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("help_sla", coBool); def->label = L("Help (SLA options)"); def->tooltip = L("Show the full list of SLA print configuration options."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("info", coBool); def->label = L("Output Model Info"); def->tooltip = L("Write information about the model to the console."); - def->default_value = new ConfigOptionBool(false); + def->set_default_value(new ConfigOptionBool(false)); def = this->add("save", coString); def->label = L("Save config file"); def->tooltip = L("Save configuration to the specified file."); - def->default_value = new ConfigOptionString(); + def->set_default_value(new ConfigOptionString()); } CLITransformConfigDef::CLITransformConfigDef() @@ -3007,34 +3007,34 @@ CLITransformConfigDef::CLITransformConfigDef() def = this->add("align_xy", coPoint); def->label = L("Align XY"); def->tooltip = L("Align the model to the given point."); - def->default_value = new ConfigOptionPoint(Vec2d(100,100)); + def->set_default_value(new ConfigOptionPoint(Vec2d(100,100))); def = this->add("cut", coFloat); def->label = L("Cut"); def->tooltip = L("Cut model at the given Z."); - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); /* def = this->add("cut_grid", coFloat); def->label = L("Cut"); def->tooltip = L("Cut model in the XY plane into tiles of the specified max size."); - def->default_value = new ConfigOptionPoint(); + def->set_default_value(new ConfigOptionPoint()); def = this->add("cut_x", coFloat); def->label = L("Cut"); def->tooltip = L("Cut model at the given X."); - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("cut_y", coFloat); def->label = L("Cut"); def->tooltip = L("Cut model at the given Y."); - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); */ def = this->add("center", coPoint); def->label = L("Center"); def->tooltip = L("Center the print around the given center."); - def->default_value = new ConfigOptionPoint(Vec2d(100,100)); + def->set_default_value(new ConfigOptionPoint(Vec2d(100,100))); def = this->add("dont_arrange", coBool); def->label = L("Don't arrange"); @@ -3061,22 +3061,22 @@ CLITransformConfigDef::CLITransformConfigDef() def = this->add("rotate", coFloat); def->label = L("Rotate"); def->tooltip = L("Rotation angle around the Z axis in degrees."); - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("rotate_x", coFloat); def->label = L("Rotate around X"); def->tooltip = L("Rotation angle around the X axis in degrees."); - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("rotate_y", coFloat); def->label = L("Rotate around Y"); def->tooltip = L("Rotation angle around the Y axis in degrees."); - def->default_value = new ConfigOptionFloat(0); + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("scale", coFloatOrPercent); def->label = L("Scale"); def->tooltip = L("Scaling factor or percentage."); - def->default_value = new ConfigOptionFloatOrPercent(1, false); + def->set_default_value(new ConfigOptionFloatOrPercent(1, false)); def = this->add("split", coBool); def->label = L("Split"); @@ -3085,7 +3085,7 @@ CLITransformConfigDef::CLITransformConfigDef() def = this->add("scale_to_fit", coPoint3); def->label = L("Scale to Fit"); def->tooltip = L("Scale to fit the given volume."); - def->default_value = new ConfigOptionPoint3(Vec3d(0,0,0)); + def->set_default_value(new ConfigOptionPoint3(Vec3d(0,0,0))); } CLIMiscConfigDef::CLIMiscConfigDef() diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index db3e63fe7..d4ad1db8c 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -307,8 +307,8 @@ protected: m_keys.emplace_back(kvp.first); const ConfigOptionDef *def = defs->get(kvp.first); assert(def != nullptr); - if (def->default_value != nullptr) - opt->set(def->default_value); + if (def->default_value) + opt->set(def->default_value.get()); } } diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 128124c97..20c9a9cf9 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -330,6 +330,17 @@ void TriangleMesh::transform(const Transform3d& t, bool fix_left_handed) } } +void TriangleMesh::transform(const Matrix3d& m, bool fix_left_handed) +{ + stl_transform(&stl, m); + stl_invalidate_shared_vertices(&stl); + if (fix_left_handed && m.determinant() < 0.) { + // Left handed transformation is being applied. It is a good idea to flip the faces and their normals. + this->repair(); + stl_reverse_all_facets(&stl); + } +} + void TriangleMesh::align_to_origin() { this->translate( diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 60ddcca08..c284f6482 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -52,6 +52,7 @@ public: void mirror_y() { this->mirror(Y); } void mirror_z() { this->mirror(Z); } void transform(const Transform3d& t, bool fix_left_handed = false); + void transform(const Matrix3d& t, bool fix_left_handed = false); void align_to_origin(); void rotate(double angle, Point* center); TriangleMeshPtrs split() const; diff --git a/src/libslic3r/clonable_ptr.hpp b/src/libslic3r/clonable_ptr.hpp new file mode 100644 index 000000000..a3b7ee244 --- /dev/null +++ b/src/libslic3r/clonable_ptr.hpp @@ -0,0 +1,168 @@ +// clonable_ptr: a smart pointer with a usage similar to unique_ptr, with the exception, that +// the copy constructor / copy assignment operator work by calling the ->clone() method. + +// derived from https://github.com/SRombauts/shared_ptr/blob/master/include/unique_ptr.hpp +/** + * @file clonable_ptr.hpp + * @brief clonable_ptr is a fake implementation to use in place of a C++11 std::clonable_ptr when compiling on an older compiler. + * + * @see http://www.cplusplus.com/reference/memory/clonable_ptr/ + * + * Copyright (c) 2014-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com) + * + * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt + * or copy at http://opensource.org/licenses/MIT) + */ + +#include "assert.h" + +namespace Slic3r { + +// Detect whether the compiler supports C++11 noexcept exception specifications. +#if defined(_MSC_VER) && _MSC_VER < 1900 && ! defined(noexcept) + #define noexcept throw() +#endif + +template +class clonable_ptr +{ +public: + /// The type of the managed object, aliased as member type + typedef T element_type; + + /// @brief Default constructor + clonable_ptr() noexcept : + px(nullptr) + { + } + /// @brief Constructor with the provided pointer to manage + explicit clonable_ptr(T* p) noexcept : + px(p) + { + } + /// @brief Copy constructor, clones by calling the rhs.clone() method + clonable_ptr(const clonable_ptr& rhs) : + px(rhs ? rhs.px->clone() : nullptr) + { + } + /// @brief Move constructor, never throws + clonable_ptr(clonable_ptr&& rhs) noexcept : + px(rhs.px) + { + rhs.px = nullptr; + } + /// @brief Assignment operator + clonable_ptr& operator=(const clonable_ptr& rhs) + { + delete px; + px = rhs ? rhs.px->clone() : nullptr; + return *this; + } + /// @brief Move operator, never throws + clonable_ptr& operator=(clonable_ptr&& rhs) + { + delete px; + px = rhs.px; + rhs.px = nullptr; + return *this; + } + /// @brief the destructor releases its ownership and destroy the object + inline ~clonable_ptr() noexcept + { + destroy(); + } + /// @brief this reset releases its ownership and destroy the object + inline void reset() noexcept + { + destroy(); + } + /// @brief this reset release its ownership and re-acquire another one + void reset(T* p) noexcept + { + assert((nullptr == p) || (px != p)); // auto-reset not allowed + destroy(); + px = p; + } + + /// @brief Swap method for the copy-and-swap idiom (copy constructor and swap method) + void swap(clonable_ptr& rhs) noexcept + { + T *tmp = px; + px = rhs.px; + rhs.px = tmp; + } + + /// @brief release the ownership of the px pointer without destroying the object! + inline void release() noexcept + { + px = nullptr; + } + + // reference counter operations : + inline operator bool() const noexcept + { + return (nullptr != px); // TODO nullptrptr + } + + // underlying pointer operations : + inline T& operator*() const noexcept + { + assert(nullptr != px); + return *px; + } + inline T* operator->() const noexcept + { + assert(nullptr != px); + return px; + } + inline T* get() const noexcept + { + // no assert, can return nullptr + return px; + } + +private: + /// @brief release the ownership of the px pointer and destroy the object + inline void destroy() noexcept + { + delete px; + px = nullptr; + } + + /// @brief hack: const-cast release the ownership of the px pointer without destroying the object! + inline void release() const noexcept + { + px = nullptr; + } + +private: + T* px; //!< Native pointer +}; + +// comparison operators +template inline bool operator==(const clonable_ptr& l, const clonable_ptr& r) noexcept +{ + return (l.get() == r.get()); +} +template inline bool operator!=(const clonable_ptr& l, const clonable_ptr& r) noexcept +{ + return (l.get() != r.get()); +} +template inline bool operator<=(const clonable_ptr& l, const clonable_ptr& r) noexcept +{ + return (l.get() <= r.get()); +} +template inline bool operator<(const clonable_ptr& l, const clonable_ptr& r) noexcept +{ + return (l.get() < r.get()); +} +template inline bool operator>=(const clonable_ptr& l, const clonable_ptr& r) noexcept +{ + return (l.get() >= r.get()); +} +template inline bool operator>(const clonable_ptr& l, const clonable_ptr& r) noexcept +{ + return (l.get() > r.get()); +} + +} // namespace Slic3r diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 037f70962..9d120132d 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -365,19 +365,18 @@ const BoundingBoxf3& GLVolume::transformed_bounding_box() const const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const { - if (m_transformed_convex_hull_bounding_box_dirty) - { - if ((m_convex_hull != nullptr) && (m_convex_hull->stl.stats.number_of_facets > 0)) - m_transformed_convex_hull_bounding_box = m_convex_hull->transformed_bounding_box(world_matrix()); - else - m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix()); - - m_transformed_convex_hull_bounding_box_dirty = false; - } - + if (m_transformed_convex_hull_bounding_box_dirty) + m_transformed_convex_hull_bounding_box = this->transformed_convex_hull_bounding_box(world_matrix()); return m_transformed_convex_hull_bounding_box; } +BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box(const Transform3d &trafo) const +{ + return (m_convex_hull != nullptr && m_convex_hull->stl.stats.number_of_facets > 0) ? + m_convex_hull->transformed_bounding_box(trafo) : + bounding_box.transformed(trafo); +} + void GLVolume::set_range(double min_z, double max_z) { this->qverts_range.first = 0; @@ -719,6 +718,8 @@ int GLVolumeCollection::load_wipe_tower_preview( v.bounding_box = v.indexed_vertex_array.bounding_box(); v.indexed_vertex_array.finalize_geometry(use_VBOs); v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0); + v.geometry_id.first = 0; + v.geometry_id.second = wipe_tower_instance_id().id; v.is_wipe_tower = true; v.shader_outside_printer_detection_enabled = ! size_unknown; return int(this->volumes.size() - 1); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 377d89fe7..fc2126d3e 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -283,6 +283,8 @@ public: int volume_id; // Instance ID, which is equal to the index of the respective ModelInstance in ModelObject.instances array. int instance_id; + bool operator==(const CompositeID &rhs) const { return object_id == rhs.object_id && volume_id == rhs.volume_id && instance_id == rhs.instance_id; } + bool operator!=(const CompositeID &rhs) const { return ! (*this == rhs); } }; CompositeID composite_id; // Fingerprint of the source geometry. For ModelVolumes, it is the ModelVolume::ID and ModelInstanceID, @@ -403,6 +405,9 @@ public: bool is_left_handed() const; const BoundingBoxf3& transformed_bounding_box() const; + // non-caching variant + BoundingBoxf3 transformed_convex_hull_bounding_box(const Transform3d &trafo) const; + // caching variant const BoundingBoxf3& transformed_convex_hull_bounding_box() const; bool empty() const { return this->indexed_vertex_array.empty(); } diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 00ebf117c..fbbca7c70 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -68,14 +68,14 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) auto optgroup = init_shape_options_page(_(L("Rectangular"))); ConfigOptionDef def; def.type = coPoints; - def.default_value = new ConfigOptionPoints{ Vec2d(200, 200) }; + def.set_default_value(new ConfigOptionPoints{ Vec2d(200, 200) }); def.label = L("Size"); def.tooltip = L("Size in X and Y of the rectangular plate."); Option option(def, "rect_size"); optgroup->append_single_option_line(option); def.type = coPoints; - def.default_value = new ConfigOptionPoints{ Vec2d(0, 0) }; + def.set_default_value(new ConfigOptionPoints{ Vec2d(0, 0) }); def.label = L("Origin"); def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle."); option = Option(def, "rect_origin"); @@ -83,7 +83,7 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) optgroup = init_shape_options_page(_(L("Circular"))); def.type = coFloat; - def.default_value = new ConfigOptionFloat(200); + def.set_default_value(new ConfigOptionFloat(200)); def.sidetext = L("mm"); def.label = L("Diameter"); def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center."); diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 93c780909..4fbaa4563 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -499,7 +499,7 @@ PageFirmware::PageFirmware(ConfigWizard *parent) gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices); const auto &enum_values = gcode_opt.enum_values; auto needle = enum_values.cend(); - if (gcode_opt.default_value != nullptr) { + if (gcode_opt.default_value) { needle = std::find(enum_values.cbegin(), enum_values.cend(), gcode_opt.default_value->serialize()); } if (needle != enum_values.cend()) { @@ -544,14 +544,12 @@ PageDiameters::PageDiameters(ConfigWizard *parent) { spin_nozzle->SetDigits(2); spin_nozzle->SetIncrement(0.1); - const auto &def_nozzle = *print_config_def.get("nozzle_diameter"); - auto *default_nozzle = dynamic_cast(def_nozzle.default_value); + auto *default_nozzle = print_config_def.get("nozzle_diameter")->get_default_value(); spin_nozzle->SetValue(default_nozzle != nullptr && default_nozzle->size() > 0 ? default_nozzle->get_at(0) : 0.5); spin_filam->SetDigits(2); spin_filam->SetIncrement(0.25); - const auto &def_filam = *print_config_def.get("filament_diameter"); - auto *default_filam = dynamic_cast(def_filam.default_value); + auto *default_filam = print_config_def.get("filament_diameter")->get_default_value(); spin_filam->SetValue(default_filam != nullptr && default_filam->size() > 0 ? default_filam->get_at(0) : 3.0); append_text(_(L("Enter the diameter of your printer's hot end nozzle."))); @@ -596,13 +594,13 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent) spin_extr->SetIncrement(5.0); const auto &def_extr = *print_config_def.get("temperature"); spin_extr->SetRange(def_extr.min, def_extr.max); - auto *default_extr = dynamic_cast(def_extr.default_value); + auto *default_extr = def_extr.get_default_value(); spin_extr->SetValue(default_extr != nullptr && default_extr->size() > 0 ? default_extr->get_at(0) : 200); spin_bed->SetIncrement(5.0); const auto &def_bed = *print_config_def.get("bed_temperature"); spin_bed->SetRange(def_bed.min, def_bed.max); - auto *default_bed = dynamic_cast(def_bed.default_value); + auto *default_bed = def_bed.get_default_value(); spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0); append_text(_(L("Enter the temperature needed for extruding your filament."))); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 655a81ce4..5e06efa29 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -15,19 +15,7 @@ namespace Slic3r { namespace GUI { wxString double_to_string(double const value, const int max_precision /*= 4*/) { - if (value - int(value) == 0) - return wxString::Format(_T("%i"), int(value)); - - int precision = max_precision; - for (size_t p = 1; p < max_precision; p++) - { - double cur_val = pow(10, p)*value; - if (cur_val - int(cur_val) == 0) { - precision = p; - break; - } - } - return wxNumberFormatter::ToString(value, precision, wxNumberFormatter::Style_None); + return wxNumberFormatter::ToString(value, max_precision, wxNumberFormatter::Style_NoTrailingZeroes); } void Field::PostInitialize() @@ -215,7 +203,7 @@ void TextCtrl::BUILD() { case coFloatOrPercent: { text_value = double_to_string(m_opt.default_value->getFloat()); - if (static_cast(m_opt.default_value)->percent) + if (m_opt.get_default_value()->percent) text_value += "%"; break; } @@ -230,19 +218,19 @@ void TextCtrl::BUILD() { case coFloat: { double val = m_opt.type == coFloats ? - static_cast(m_opt.default_value)->get_at(m_opt_idx) : + m_opt.get_default_value()->get_at(m_opt_idx) : m_opt.type == coFloat ? m_opt.default_value->getFloat() : - static_cast(m_opt.default_value)->get_at(m_opt_idx); + m_opt.get_default_value()->get_at(m_opt_idx); text_value = double_to_string(val); break; } case coString: - text_value = static_cast(m_opt.default_value)->value; + text_value = m_opt.get_default_value()->value; break; case coStrings: { - const ConfigOptionStrings *vec = static_cast(m_opt.default_value); + const ConfigOptionStrings *vec = m_opt.get_default_value(); if (vec == nullptr || vec->empty()) break; //for the case of empty default value text_value = vec->get_at(m_opt_idx); break; @@ -385,8 +373,8 @@ void CheckBox::BUILD() { bool check_value = m_opt.type == coBool ? m_opt.default_value->getBool() : m_opt.type == coBools ? - static_cast(m_opt.default_value)->get_at(m_opt_idx) : - false; + m_opt.get_default_value()->get_at(m_opt_idx) : + false; // Set Label as a string of at least one space simbol to correct system scaling of a CheckBox auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size); @@ -439,7 +427,7 @@ void SpinCtrl::BUILD() { break; case coInts: { - const ConfigOptionInts *vec = static_cast(m_opt.default_value); + const ConfigOptionInts *vec = m_opt.get_default_value(); if (vec == nullptr || vec->empty()) break; for (size_t id = 0; id < vec->size(); ++id) { @@ -641,7 +629,7 @@ void Choice::set_selection() break; } case coEnum:{ - int id_value = static_cast*>(m_opt.default_value)->value; //!! + int id_value = m_opt.get_default_value>()->value; //!! field->SetSelection(id_value); break; } @@ -661,7 +649,7 @@ void Choice::set_selection() break; } case coStrings:{ - text_value = static_cast(m_opt.default_value)->get_at(m_opt_idx); + text_value = m_opt.get_default_value()->get_at(m_opt_idx); size_t idx = 0; for (auto el : m_opt.enum_values) @@ -898,7 +886,7 @@ void ColourPicker::BUILD() if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); // Validate the color - wxString clr_str(static_cast(m_opt.default_value)->get_at(m_opt_idx)); + wxString clr_str(m_opt.get_default_value()->get_at(m_opt_idx)); wxColour clr(clr_str); if (! clr.IsOk()) { clr = wxTransparentColour; @@ -932,7 +920,7 @@ void PointCtrl::BUILD() const wxSize field_size(4 * m_em_unit, -1); - auto default_pt = static_cast(m_opt.default_value)->values.at(0); + auto default_pt = m_opt.get_default_value()->values.at(0); double val = default_pt(0); wxString X = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None); val = default_pt(1); @@ -1031,7 +1019,7 @@ void StaticText::BUILD() if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); - const wxString legend(static_cast(m_opt.default_value)->value); + const wxString legend(m_opt.get_default_value()->value); auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetBackgroundStyle(wxBG_STYLE_PAINT); @@ -1066,7 +1054,7 @@ void SliderCtrl::BUILD() auto temp = new wxBoxSizer(wxHORIZONTAL); - auto def_val = static_cast(m_opt.default_value)->value; + auto def_val = m_opt.get_default_value()->value; auto min = m_opt.min == INT_MIN ? 0 : m_opt.min; auto max = m_opt.max == INT_MAX ? 100 : m_opt.max; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 005b9db9d..df8124efa 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1783,7 +1783,7 @@ void GLCanvas3D::mirror_selection(Axis axis) { m_selection.mirror(axis); do_mirror(); - wxGetApp().obj_manipul()->update_settings_value(m_selection); + wxGetApp().obj_manipul()->set_dirty(); } // Reload the 3D scene of @@ -1828,6 +1828,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re // State of the sla_steps for all SLAPrintObjects. std::vector sla_support_state; + std::vector instance_ids_selected; std::vector map_glvolume_old_to_new(m_volumes.volumes.size(), size_t(-1)); std::vector glvolumes_new; glvolumes_new.reserve(m_volumes.volumes.size()); @@ -1892,6 +1893,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re if (it != model_volume_state.end() && it->geometry_id == key.geometry_id) mvs = &(*it); } + // Emplace instance ID of the volume. Both the aux volumes and model volumes share the same instance ID. + // The wipe tower has its own wipe_tower_instance_id(). + if (m_selection.contains_volume(volume_id)) + instance_ids_selected.emplace_back(volume->geometry_id.second); if (mvs == nullptr || force_full_scene_refresh) { // This GLVolume will be released. if (volume->is_wipe_tower) { @@ -1923,13 +1928,18 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re } } } + sort_remove_duplicates(instance_ids_selected); } if (m_reload_delayed) return; + bool update_object_list = false; + if (m_regenerate_volumes) { + if (m_volumes.volumes != glvolumes_new) + update_object_list = true; m_volumes.volumes = std::move(glvolumes_new); for (unsigned int obj_idx = 0; obj_idx < (unsigned int)m_model->objects.size(); ++ obj_idx) { const ModelObject &model_object = *m_model->objects[obj_idx]; @@ -1944,12 +1954,16 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re // New volume. m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_color_by, m_use_VBOs && m_initialized); m_volumes.volumes.back()->geometry_id = key.geometry_id; + update_object_list = true; } else { // Recycling an old GLVolume. GLVolume &existing_volume = *m_volumes.volumes[it->volume_idx]; assert(existing_volume.geometry_id == key.geometry_id); // Update the Object/Volume/Instance indices into the current Model. - existing_volume.composite_id = it->composite_id; + if (existing_volume.composite_id != it->composite_id) { + existing_volume.composite_id = it->composite_id; + update_object_list = true; + } } } } @@ -2051,13 +2065,17 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re update_volumes_colors_by_extruder(); // Update selection indices based on the old/new GLVolumeCollection. - m_selection.volumes_changed(map_glvolume_old_to_new); + if (m_selection.get_mode() == Selection::Instance) + m_selection.instances_changed(instance_ids_selected); + else + m_selection.volumes_changed(map_glvolume_old_to_new); } m_gizmos.update_data(*this); // Update the toolbar - post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); + if (update_object_list) + post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); // checks for geometry outside the print volume to render it accordingly if (!m_volumes.empty()) @@ -2108,7 +2126,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re // to force a reset of its cache auto manip = wxGetApp().obj_manipul(); if (manip != nullptr) - manip->update_settings_value(m_selection); + manip->set_dirty(); } // and force this canvas to be redrawn. @@ -2796,7 +2814,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_regenerate_volumes = false; m_selection.translate(cur_pos - m_mouse.drag.start_position_3D); - wxGetApp().obj_manipul()->update_settings_value(m_selection); + wxGetApp().obj_manipul()->set_dirty(); m_dirty = true; } } @@ -2856,7 +2874,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { m_regenerate_volumes = false; do_move(); - wxGetApp().obj_manipul()->update_settings_value(m_selection); + wxGetApp().obj_manipul()->set_dirty(); // Let the platter know that the dragging finished, so a delayed refresh // of the scene with the background processing data should be performed. post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); @@ -2875,7 +2893,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { m_selection.clear(); m_selection.set_mode(Selection::Instance); - wxGetApp().obj_manipul()->update_settings_value(m_selection); + wxGetApp().obj_manipul()->set_dirty(); m_gizmos.reset_all_states(); m_gizmos.update_data(*this); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); @@ -2902,7 +2920,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_gizmos.refresh_on_off_state(m_selection); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); m_gizmos.update_data(*this); - wxGetApp().obj_manipul()->update_settings_value(m_selection); + wxGetApp().obj_manipul()->set_dirty(); // forces a frame render to update the view before the context menu is shown render(); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 09a6e94a8..368ccc977 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -120,7 +120,7 @@ ObjectList::ObjectList(wxWindow* parent) : #endif //__WXMSW__ }); - Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { key_event(event); }); // doesn't work on OSX +// Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { key_event(event); }); // doesn't work on OSX #ifdef __WXMSW__ GetMainWindow()->Bind(wxEVT_MOTION, [this](wxMouseEvent& event) { @@ -142,9 +142,27 @@ ObjectList::ObjectList(wxWindow* parent) : Bind(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, [this](wxCommandEvent& e) { last_volume_is_deleted(e.GetInt()); }); #ifdef __WXOSX__ - Bind(wxEVT_KEY_DOWN, &ObjectList::OnChar, this); +// Bind(wxEVT_KEY_DOWN, &ObjectList::OnChar, this); #endif //__WXOSX__ + { + // Accelerators + wxAcceleratorEntry entries[6]; + entries[0].Set(wxACCEL_CTRL, (int) 'C', wxID_COPY); + entries[1].Set(wxACCEL_CTRL, (int) 'X', wxID_CUT); + entries[2].Set(wxACCEL_CTRL, (int) 'V', wxID_PASTE); + entries[3].Set(wxACCEL_CTRL, (int) 'A', wxID_SELECTALL); + entries[4].Set(wxACCEL_NORMAL, WXK_DELETE, wxID_DELETE); + entries[5].Set(wxACCEL_NORMAL, WXK_BACK, wxID_DELETE); + wxAcceleratorTable accel(6, entries); + SetAcceleratorTable(accel); + + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_COPY)); }, wxID_COPY); + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { wxPostEvent((wxEvtHandler*)wxGetApp().plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_PASTE)); }, wxID_PASTE); + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->select_item_all_children(); }, wxID_SELECTALL); + this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->remove(); }, wxID_DELETE); + } + Bind(wxEVT_SIZE, ([this](wxSizeEvent &e) { this->EnsureVisible(this->GetCurrentItem()); e.Skip(); })); } @@ -1466,19 +1484,12 @@ Geometry::Transformation volume_to_bed_transformation(const Geometry::Transforma { Geometry::Transformation out; - // Is the angle close to a multiple of 90 degrees? - auto ninety_degrees = [](double a) { - a = fmod(std::abs(a), 0.5 * PI); - if (a > 0.25 * PI) - a = 0.5 * PI - a; - return a < 0.001; - }; 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 (ninety_degrees(instance_transformation.get_rotation().x()) && ninety_degrees(instance_transformation.get_rotation().y()) && ninety_degrees(instance_transformation.get_rotation().z())) + else if (Geometry::is_rotation_ninety_degrees(instance_transformation.get_rotation())) { // Anisotropic scaling, rotation by multiples of ninety degrees. Eigen::Matrix3d instance_rotation_trafo = diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index d50f03050..96a69e464 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -17,6 +17,50 @@ namespace Slic3r namespace GUI { +static wxBitmapComboBox* create_word_local_combo(wxWindow *parent) +{ + wxSize size(15 * wxGetApp().em_unit(), -1); + + wxBitmapComboBox *temp = nullptr; +#ifdef __WXOSX__ + /* wxBitmapComboBox with wxCB_READONLY style return NULL for GetTextCtrl(), + * so ToolTip doesn't shown. + * Next workaround helps to solve this problem + */ + temp = new wxBitmapComboBox(); + temp->SetTextCtrlStyle(wxTE_READONLY); + temp->Create(parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr); +#else + temp = new wxBitmapComboBox(parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY); +#endif //__WXOSX__ + + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); + + temp->Append(_(L("World"))); + temp->Append(_(L("Local"))); + temp->SetSelection(0); + temp->SetValue(temp->GetString(0)); + +#ifndef __WXGTK__ + /* Workaround for a correct rendering of the control without Bitmap (under MSW and OSX): + * + * 1. We should create small Bitmap to fill Bitmaps RefData, + * ! in this case wxBitmap.IsOK() return true. + * 2. But then set width to 0 value for no using of bitmap left and right spacing + * 3. Set this empty bitmap to the at list one item and BitmapCombobox will be recreated correct + * + * Note: Set bitmap height to the Font size because of OSX rendering. + */ + wxBitmap empty_bmp(1, temp->GetFont().GetPixelSize().y + 2); + empty_bmp.SetWidth(0); + temp->SetItemBitmap(0, empty_bmp); +#endif + + temp->SetToolTip(_(L("Select coordinate space, in which the transformation will be performed."))); + return temp; +} + ObjectManipulation::ObjectManipulation(wxWindow* parent) : OG_Settings(parent, true) #ifndef __APPLE__ @@ -76,11 +120,12 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : def.label = ""; def.gui_type = "legend"; def.tooltip = L("Object name"); - def.width = 21; #ifdef __APPLE__ def.width = 19; +#else + def.width = 21; #endif - def.default_value = new ConfigOptionString{ " " }; + def.set_default_value(new ConfigOptionString{ " " }); line.append_option(Option(def, "object_name")); m_og->append_line(line); @@ -92,22 +137,26 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : def.type = coString; def.width = field_width/*50*/; - std::vector axes{ "x", "y", "z" }; - for (const auto axis : axes) { - const auto label = boost::algorithm::to_upper_copy(axis); - def.default_value = new ConfigOptionString{ " " + label }; + for (const std::string axis : { "x", "y", "z" }) { + const std::string label = boost::algorithm::to_upper_copy(axis); + def.set_default_value(new ConfigOptionString{ " " + label }); Option option = Option(def, axis + "_axis_legend"); line.append_option(option); } + line.near_label_widget = [this](wxWindow* parent) { + wxBitmapComboBox *combo = create_word_local_combo(parent); + combo->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent &evt) { this->set_world_coordinates(evt.GetSelection() != 1); }), combo->GetId()); + m_word_local_combo = combo; + return combo; + }; m_og->append_line(line); - auto add_og_to_object_settings = [this, field_width](const std::string& option_name, const std::string& sidetext) { Line line = { _(option_name), "" }; ConfigOptionDef def; def.type = coFloat; - def.default_value = new ConfigOptionFloat(0.0); + def.set_default_value(new ConfigOptionFloat(0.0)); def.width = field_width/*50*/; // Add "uniform scaling" button in front of "Scale" option @@ -133,11 +182,10 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : const std::string lower_name = boost::algorithm::to_lower_copy(option_name); - std::vector axes{ "x", "y", "z" }; - for (auto axis : axes) { - if (axis == "z") + for (const char *axis : { "_x", "_y", "_z" }) { + if (axis[1] == 'z') def.sidetext = sidetext; - Option option = Option(def, lower_name + "_" + axis); + Option option = Option(def, lower_name + axis); option.opt.full_width = true; line.append_option(option); } @@ -163,15 +211,19 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : void ObjectManipulation::Show(const bool show) { - if (show == IsShown()) - return; + if (show != IsShown()) { + m_og->Show(show); - m_og->Show(show); + if (show && wxGetApp().get_mode() != comSimple) { + m_og->get_grid_sizer()->Show(size_t(0), false); + m_og->get_grid_sizer()->Show(size_t(1), false); + } + } - if (show && wxGetApp().get_mode() != comSimple) { - m_og->get_grid_sizer()->Show(size_t(0), false); - m_og->get_grid_sizer()->Show(size_t(1), false); - } + if (show) { + bool show_world_local_combo = wxGetApp().plater()->canvas3D()->get_selection().is_single_full_instance(); + m_word_local_combo->Show(show_world_local_combo); + } } bool ObjectManipulation::IsShown() @@ -181,9 +233,10 @@ bool ObjectManipulation::IsShown() void ObjectManipulation::UpdateAndShow(const bool show) { - if (show) { - update_settings_value(wxGetApp().plater()->canvas3D()->get_selection()); - } + if (show) { + this->set_dirty(); + this->update_if_dirty(); + } OG_Settings::UpdateAndShow(show); } @@ -200,35 +253,34 @@ void ObjectManipulation::update_settings_value(const Selection& selection) // 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_volume(*selection.get_volume_idxs().begin()); m_new_position = volume->get_instance_offset(); - m_new_rotation = volume->get_instance_rotation(); - m_new_scale = volume->get_instance_scaling_factor(); - int obj_idx = volume->object_idx(); - int instance_idx = volume->instance_idx(); - if ((0 <= obj_idx) && (obj_idx < (int)wxGetApp().model_objects()->size())) - { - bool changed_box = false; - if (!m_cache.instance.matches_object(obj_idx)) - { - m_cache.instance.set(obj_idx, instance_idx, (*wxGetApp().model_objects())[obj_idx]->raw_mesh_bounding_box().size()); - changed_box = true; - } - if (changed_box || !m_cache.instance.matches_instance(instance_idx) || !m_cache.scale.isApprox(100.0 * m_new_scale)) - m_new_size = (volume->get_instance_transformation().get_matrix(true, true) * m_cache.instance.box_size).cwiseAbs(); - } - else - // this should never happen - m_new_size = Vec3d::Zero(); + + // 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); + } + + if (m_world_coordinates) { + m_new_rotate_label_string = L("Rotate"); + m_new_rotation = Vec3d::Zero(); + m_new_size = selection.get_bounding_box().size(); + m_new_scale = m_new_size.cwiseProduct(selection.get_unscaled_instance_bounding_box().size().cwiseInverse()) * 100.; + } else { + m_new_rotation = volume->get_instance_rotation() * (180. / M_PI); + m_new_size = volume->get_instance_transformation().get_scaling_factor().cwiseProduct((*wxGetApp().model_objects())[volume->object_idx()]->raw_mesh_bounding_box().size()); + m_new_scale = volume->get_instance_scaling_factor() * 100.; + } m_new_enabled = true; } else if (selection.is_single_full_object() && obj_list->is_selected(itObject)) { - m_cache.instance.reset(); - const BoundingBoxf3& box = selection.get_bounding_box(); m_new_position = box.center(); m_new_rotation = Vec3d::Zero(); - m_new_scale = Vec3d(1.0, 1.0, 1.0); + m_new_scale = Vec3d(100., 100., 100.); m_new_size = box.size(); m_new_rotate_label_string = L("Rotate"); m_new_scale_label_string = L("Scale"); @@ -236,14 +288,12 @@ void ObjectManipulation::update_settings_value(const Selection& selection) } else if (selection.is_single_modifier() || selection.is_single_volume()) { - m_cache.instance.reset(); - // the selection contains a single volume const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); m_new_position = volume->get_volume_offset(); - m_new_rotation = volume->get_volume_rotation(); - m_new_scale = volume->get_volume_scaling_factor(); - m_new_size = (volume->get_volume_transformation().get_matrix(true, true) * volume->bounding_box.size()).cwiseAbs(); + m_new_rotation = volume->get_volume_rotation() * (180. / M_PI); + m_new_scale = volume->get_volume_scaling_factor() * 100.; + m_new_size = volume->get_volume_transformation().get_scaling_factor().cwiseProduct(volume->bounding_box.size()); m_new_enabled = true; } else if (obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) @@ -255,87 +305,51 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_size = selection.get_bounding_box().size(); m_new_enabled = true; } - else - reset_settings_value(); - - m_dirty = true; + else { + // No selection, reset the cache. +// assert(selection.is_empty()); + reset_settings_value(); + } } void ObjectManipulation::update_if_dirty() { - if (!m_dirty) + if (! m_dirty) return; - if (m_cache.move_label_string != _(m_new_move_label_string)+ ":") - { - m_cache.move_label_string = _(m_new_move_label_string)+ ":"; - m_move_Label->SetLabel(m_cache.move_label_string); + const Selection &selection = wxGetApp().plater()->canvas3D()->get_selection(); + this->update_settings_value(selection); + + auto update_label = [](wxString &label_cache, const std::string &new_label, wxStaticText *widget) { + wxString new_label_localized = _(new_label) + ":"; + if (label_cache != new_label_localized) { + label_cache = new_label_localized; + widget->SetLabel(new_label_localized); + } + }; + update_label(m_cache.move_label_string, m_new_move_label_string, m_move_Label); + update_label(m_cache.rotate_label_string, m_new_rotate_label_string, m_rotate_Label); + update_label(m_cache.scale_label_string, m_new_scale_label_string, m_scale_Label); + + char axis[2] = "x"; + for (int i = 0; i < 3; ++ i, ++ axis[0]) { + auto update = [this, i, &axis](Vec3d &cached, Vec3d &cached_rounded, const char *key, const Vec3d &new_value) { + wxString new_text = double_to_string(new_value(i), 2); + double new_rounded; + new_text.ToDouble(&new_rounded); + if (std::abs(cached_rounded(i) - new_rounded) > EPSILON) { + cached_rounded(i) = new_rounded; + m_og->set_value(std::string(key) + axis, new_text); + } + cached(i) = new_value(i); + }; + update(m_cache.position, m_cache.position_rounded, "position_", m_new_position); + update(m_cache.scale, m_cache.scale_rounded, "scale_", m_new_scale); + update(m_cache.size, m_cache.size_rounded, "size_", m_new_size); + update(m_cache.rotation, m_cache.rotation_rounded, "rotation_", m_new_rotation); } - if (m_cache.rotate_label_string != _(m_new_rotate_label_string)+ ":") - { - m_cache.rotate_label_string = _(m_new_rotate_label_string)+ ":"; - m_rotate_Label->SetLabel(m_cache.rotate_label_string); - } - - if (m_cache.scale_label_string != _(m_new_scale_label_string)+ ":") - { - m_cache.scale_label_string = _(m_new_scale_label_string)+ ":"; - m_scale_Label->SetLabel(m_cache.scale_label_string); - } - - if (m_cache.position(0) != m_new_position(0)) - m_og->set_value("position_x", double_to_string(m_new_position(0), 2)); - - if (m_cache.position(1) != m_new_position(1)) - m_og->set_value("position_y", double_to_string(m_new_position(1), 2)); - - if (m_cache.position(2) != m_new_position(2)) - m_og->set_value("position_z", double_to_string(m_new_position(2), 2)); - - m_cache.position = m_new_position; - - auto scale = m_new_scale * 100.0; - if (m_cache.scale(0) != scale(0)) - m_og->set_value("scale_x", double_to_string(scale(0), 2)); - - if (m_cache.scale(1) != scale(1)) - m_og->set_value("scale_y", double_to_string(scale(1), 2)); - - if (m_cache.scale(2) != scale(2)) - m_og->set_value("scale_z", double_to_string(scale(2), 2)); - - m_cache.scale = scale; - - if (m_cache.size(0) != m_new_size(0)) - m_og->set_value("size_x", double_to_string(m_new_size(0), 2)); - - if (m_cache.size(1) != m_new_size(1)) - m_og->set_value("size_y", double_to_string(m_new_size(1), 2)); - - if (m_cache.size(2) != m_new_size(2)) - m_og->set_value("size_z", double_to_string(m_new_size(2), 2)); - - m_cache.size = m_new_size; - - Vec3d deg_rotation; - for (size_t i = 0; i < 3; ++i) - { - deg_rotation(i) = Geometry::rad2deg(m_new_rotation(i)); - } - - if ((m_cache.rotation(0) != m_new_rotation(0)) || (m_new_rotation(0) == 0.0)) - m_og->set_value("rotation_x", double_to_string(deg_rotation(0), 2)); - - if ((m_cache.rotation(1) != m_new_rotation(1)) || (m_new_rotation(1) == 0.0)) - m_og->set_value("rotation_y", double_to_string(deg_rotation(1), 2)); - - if ((m_cache.rotation(2) != m_new_rotation(2)) || (m_new_rotation(2) == 0.0)) - m_og->set_value("rotation_z", double_to_string(deg_rotation(2), 2)); - - m_cache.rotation = deg_rotation; - - if (wxGetApp().plater()->canvas3D()->get_selection().requires_uniform_scale()) { + if (selection.requires_uniform_scale()) { m_lock_bnt->SetLock(true); m_lock_bnt->Disable(); } @@ -344,6 +358,12 @@ void ObjectManipulation::update_if_dirty() m_lock_bnt->Enable(); } + { + int new_selection = m_world_coordinates ? 0 : 1; + if (m_word_local_combo->GetSelection() != new_selection) + m_word_local_combo->SetSelection(new_selection); + } + if (m_new_enabled) m_og->enable(); else @@ -382,12 +402,19 @@ void ObjectManipulation::reset_settings_value() m_new_scale = Vec3d::Ones(); m_new_size = Vec3d::Zero(); m_new_enabled = false; - m_cache.instance.reset(); - m_dirty = true; + // no need to set the dirty flag here as this method is called from update_settings_value(), + // which is called from update_if_dirty(), which resets the dirty flag anyways. +// m_dirty = true; } -void ObjectManipulation::change_position_value(const Vec3d& position) +void ObjectManipulation::change_position_value(int axis, double value) { + if (std::abs(m_cache.position_rounded(axis) - value) < EPSILON) + return; + + Vec3d position = m_cache.position; + position(axis) = value; + auto canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); selection.start_dragging(); @@ -395,113 +422,102 @@ void ObjectManipulation::change_position_value(const Vec3d& position) canvas->do_move(); m_cache.position = position; + m_cache.position_rounded(axis) = DBL_MAX; + this->UpdateAndShow(true); } -void ObjectManipulation::change_rotation_value(const Vec3d& rotation) +void ObjectManipulation::change_rotation_value(int axis, double value) { + if (std::abs(m_cache.rotation_rounded(axis) - value) < EPSILON) + return; + + Vec3d rotation = m_cache.rotation; + rotation(axis) = value; + GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); - const Selection& selection = canvas->get_selection(); + Selection& selection = canvas->get_selection(); 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()) { + 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(); } - Vec3d rad_rotation; - for (size_t i = 0; i < 3; ++i) - rad_rotation(i) = Geometry::deg2rad((transformation_type.absolute()) ? rotation(i) : rotation(i) - m_cache.rotation(i)); - - canvas->get_selection().start_dragging(); - canvas->get_selection().rotate(rad_rotation, transformation_type); + selection.start_dragging(); + selection.rotate( + (M_PI / 180.0) * (transformation_type.absolute() ? rotation : rotation - m_cache.rotation), + transformation_type); canvas->do_rotate(); m_cache.rotation = rotation; + m_cache.rotation_rounded(axis) = DBL_MAX; + this->UpdateAndShow(true); } -void ObjectManipulation::change_scale_value(const Vec3d& scale) +void ObjectManipulation::change_scale_value(int axis, double value) { - Vec3d scaling_factor = scale; - const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); - if (m_uniform_scale || selection.requires_uniform_scale()) - { - Vec3d abs_scale_diff = (scale - m_cache.scale).cwiseAbs(); - double max_diff = abs_scale_diff(X); - Axis max_diff_axis = X; - if (max_diff < abs_scale_diff(Y)) - { - max_diff = abs_scale_diff(Y); - max_diff_axis = Y; - } - if (max_diff < abs_scale_diff(Z)) - { - max_diff = abs_scale_diff(Z); - max_diff_axis = Z; - } - scaling_factor = scale(max_diff_axis) * Vec3d::Ones(); - } + if (std::abs(m_cache.scale_rounded(axis) - value) < EPSILON) + return; - scaling_factor *= 0.01; + Vec3d scale = m_cache.scale; + scale(axis) = value; - auto canvas = wxGetApp().plater()->canvas3D(); - canvas->get_selection().start_dragging(); - canvas->get_selection().scale(scaling_factor, false); - canvas->do_scale(); - - if (!m_cache.scale.isApprox(scale)) - m_cache.instance.instance_idx = -1; + this->do_scale(axis, scale); m_cache.scale = scale; + m_cache.scale_rounded(axis) = DBL_MAX; + this->UpdateAndShow(true); } -void ObjectManipulation::change_size_value(const Vec3d& size) +void ObjectManipulation::change_size_value(int axis, double value) { + if (std::abs(m_cache.size_rounded(axis) - value) < EPSILON) + return; + + Vec3d size = m_cache.size; + size(axis) = value; + const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); Vec3d ref_size = m_cache.size; - if (selection.is_single_volume() || selection.is_single_modifier()) - { - const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); - ref_size = volume->bounding_box.size(); - } - else if (selection.is_single_full_instance()) - ref_size = m_cache.instance.box_size; + if (selection.is_single_volume() || selection.is_single_modifier()) + ref_size = selection.get_volume(*selection.get_volume_idxs().begin())->bounding_box.size(); + else if (selection.is_single_full_instance()) + ref_size = m_world_coordinates ? + selection.get_unscaled_instance_bounding_box().size() : + (*wxGetApp().model_objects())[selection.get_volume(*selection.get_volume_idxs().begin())->object_idx()]->raw_mesh_bounding_box().size(); - Vec3d scale = 100.0 * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2)); - Vec3d scaling_factor = scale; - - if (m_uniform_scale || selection.requires_uniform_scale()) - { - Vec3d abs_scale_diff = (scale - m_cache.scale).cwiseAbs(); - double max_diff = abs_scale_diff(X); - Axis max_diff_axis = X; - if (max_diff < abs_scale_diff(Y)) - { - max_diff = abs_scale_diff(Y); - max_diff_axis = Y; - } - if (max_diff < abs_scale_diff(Z)) - { - max_diff = abs_scale_diff(Z); - max_diff_axis = Z; - } - scaling_factor = scale(max_diff_axis) * Vec3d::Ones(); - } - - scaling_factor *= 0.01; - - auto canvas = wxGetApp().plater()->canvas3D(); - canvas->get_selection().start_dragging(); - canvas->get_selection().scale(scaling_factor, false); - canvas->do_scale(); + this->do_scale(axis, 100. * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2))); m_cache.size = size; + m_cache.size_rounded(axis) = DBL_MAX; + this->UpdateAndShow(true); } -void ObjectManipulation::on_change(const t_config_option_key& opt_key, const boost::any& value) +void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const +{ + Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); + Vec3d scaling_factor = scale; + + 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(); + + selection.start_dragging(); + selection.scale(scaling_factor * 0.01, transformation_type); + wxGetApp().plater()->canvas3D()->do_scale(); +} + +void ObjectManipulation::on_change(t_config_option_key opt_key, const boost::any& value) { // needed to hide the visual hints in 3D scene wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, false); @@ -512,24 +528,17 @@ void ObjectManipulation::on_change(const t_config_option_key& opt_key, const boo if (!m_cache.is_valid()) return; - std::vector axes{ "_x", "_y", "_z" }; + int axis = opt_key.back() - 'x'; + double new_value = boost::any_cast(m_og->get_value(opt_key)); - std::string param; - std::copy(opt_key.begin(), opt_key.end() - 2, std::back_inserter(param)); - - size_t i = 0; - Vec3d new_value; - for (auto axis : axes) - new_value(i++) = boost::any_cast(m_og->get_value(param + axis)); - - if (param == "position") - change_position_value(new_value); - else if (param == "rotation") - change_rotation_value(new_value); - else if (param == "scale") - change_scale_value(new_value); - else if (param == "size") - change_size_value(new_value); + if (boost::starts_with(opt_key, "position_")) + change_position_value(axis, new_value); + else if (boost::starts_with(opt_key, "rotation_")) + change_rotation_value(axis, new_value); + else if (boost::starts_with(opt_key, "scale_")) + change_scale_value(axis, new_value); + else if (boost::starts_with(opt_key, "size_")) + change_size_value(axis, new_value); } void ObjectManipulation::on_fill_empty_value(const std::string& opt_key) @@ -543,21 +552,62 @@ void ObjectManipulation::on_fill_empty_value(const std::string& opt_key) if (!m_cache.is_valid()) return; - std::string param; - std::copy(opt_key.begin(), opt_key.end() - 2, std::back_inserter(param)); + const Vec3d *vec = nullptr; + Vec3d *rounded = nullptr; + if (boost::starts_with(opt_key, "position_")) { + vec = &m_cache.position; + rounded = &m_cache.position_rounded; + } else if (boost::starts_with(opt_key, "rotation_")) { + vec = &m_cache.rotation; + rounded = &m_cache.rotation_rounded; + } else if (boost::starts_with(opt_key, "scale_")) { + vec = &m_cache.scale; + rounded = &m_cache.scale_rounded; + } else if (boost::starts_with(opt_key, "size_")) { + vec = &m_cache.size; + rounded = &m_cache.size_rounded; + } else + assert(false); - double value = 0.0; - auto opt_key_to_axis = [&opt_key]() { return opt_key.back() == 'x' ? 0 : opt_key.back() == 'y' ? 1 : 2; }; - if (param == "position") - value = m_cache.position(opt_key_to_axis()); - else if (param == "rotation") - value = m_cache.rotation(opt_key_to_axis()); - else if (param == "scale") - value = m_cache.scale(opt_key_to_axis()); - else if (param == "size") - value = m_cache.size(opt_key_to_axis()); + if (vec != nullptr) { + int axis = opt_key.back() - 'x'; + wxString new_text = double_to_string((*vec)(axis)); + m_og->set_value(opt_key, new_text); + new_text.ToDouble(&(*rounded)(axis)); + } +} - m_og->set_value(opt_key, double_to_string(value)); +void ObjectManipulation::set_uniform_scaling(const bool new_value) +{ + const Selection &selection = wxGetApp().plater()->canvas3D()->get_selection(); + if (selection.is_single_full_instance() && m_world_coordinates && !new_value) { + // 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_volume(*selection.get_volume_idxs().begin()); + // 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, + _(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" + "Do you want to proceed?")), + SLIC3R_APP_NAME, + wxYES_NO | wxNO_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 = new_value; } void ObjectManipulation::msw_rescale() @@ -569,4 +619,4 @@ void ObjectManipulation::msw_rescale() } } //namespace GUI -} //namespace Slic3r \ No newline at end of file +} //namespace Slic3r diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index f86cd6e56..7c359f3d7 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -6,6 +6,7 @@ #include "GUI_ObjectSettings.hpp" #include "GLCanvas3D.hpp" +class wxBitmapComboBox; class wxStaticText; class LockButton; class wxStaticBitmap; @@ -20,41 +21,28 @@ class ObjectManipulation : public OG_Settings struct Cache { Vec3d position; + Vec3d position_rounded; Vec3d rotation; + Vec3d rotation_rounded; Vec3d scale; + Vec3d scale_rounded; Vec3d size; + Vec3d size_rounded; - std::string move_label_string; - std::string rotate_label_string; - std::string scale_label_string; - - struct Instance - { - int object_idx; - int instance_idx; - Vec3d box_size; - - Instance() { reset(); } - void reset() { this->object_idx = -1; this->instance_idx = -1; this->box_size = Vec3d::Zero(); } - void set(int object_idx, int instance_idx, const Vec3d& box_size) { this->object_idx = object_idx; this->instance_idx = instance_idx; this->box_size = box_size; } - bool matches(int object_idx, int instance_idx) const { return (this->object_idx == object_idx) && (this->instance_idx == instance_idx); } - bool matches_object(int object_idx) const { return (this->object_idx == object_idx); } - bool matches_instance(int instance_idx) const { return (this->instance_idx == instance_idx); } - }; - - Instance instance; + wxString move_label_string; + wxString rotate_label_string; + wxString scale_label_string; Cache() { reset(); } void reset() { - position = Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); - rotation = Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); - scale = Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); - size = Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); - move_label_string = ""; - rotate_label_string = ""; - scale_label_string = ""; - instance.reset(); + position = position_rounded = Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); + rotation = rotation_rounded = Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); + scale = scale_rounded = Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); + size = size_rounded = Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); + move_label_string = wxString(); + rotate_label_string = wxString(); + scale_label_string = wxString(); } bool is_valid() const { return position != Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); } }; @@ -77,7 +65,10 @@ class ObjectManipulation : public OG_Settings Vec3d m_new_size; bool m_new_enabled; bool m_uniform_scale {true}; + // Does the object manipulation panel work in World or Local coordinates? + bool m_world_coordinates = true; LockButton* m_lock_bnt{ nullptr }; + wxBitmapComboBox* m_word_local_combo = nullptr; ScalableBitmap m_manifold_warning_bmp; wxStaticBitmap* m_fix_throught_netfab_bitmap; @@ -95,13 +86,15 @@ public: bool IsShown() override; void UpdateAndShow(const bool show) override; - void update_settings_value(const Selection& selection); - + void set_dirty() { m_dirty = true; } // Called from the App to update the UI if dirty. void update_if_dirty(); - void set_uniform_scaling(const bool uniform_scale) { m_uniform_scale = uniform_scale;} + void set_uniform_scaling(const bool uniform_scale); bool get_uniform_scaling() const { return m_uniform_scale; } + // 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; } void reset_cache() { m_cache.reset(); } #ifndef __APPLE__ @@ -116,6 +109,7 @@ public: private: void reset_settings_value(); + void update_settings_value(const Selection& selection); // update size values after scale unit changing or "gizmos" void update_size_value(const Vec3d& size); @@ -123,12 +117,13 @@ private: void update_rotation_value(const Vec3d& rotation); // change values - void change_position_value(const Vec3d& position); - void change_rotation_value(const Vec3d& rotation); - void change_scale_value(const Vec3d& scale); - void change_size_value(const Vec3d& size); + void change_position_value(int axis, double value); + void change_rotation_value(int axis, double value); + 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; - void on_change(const t_config_option_key& opt_key, const boost::any& value); + void on_change(t_config_option_key opt_key, const boost::any& value); void on_fill_empty_value(const std::string& opt_key); }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index a00303634..dd4e454ae 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -590,7 +590,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) // Rotate the object so the normal points downward: selection.flattening_rotate(get_flattening_normal()); canvas.do_flatten(); - wxGetApp().obj_manipul()->update_settings_value(selection); + wxGetApp().obj_manipul()->set_dirty(); } canvas.set_as_dirty(); @@ -623,14 +623,17 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) { // Apply new temporary offset selection.translate(get_displacement()); - wxGetApp().obj_manipul()->update_settings_value(selection); + wxGetApp().obj_manipul()->set_dirty(); break; } case Scale: { // Apply new temporary scale factors - selection.scale(get_scale(), evt.AltDown()); - wxGetApp().obj_manipul()->update_settings_value(selection); + TransformationType transformation_type(TransformationType::Local_Absolute_Joint); + if (evt.AltDown()) + transformation_type.set_independent(); + selection.scale(get_scale(), transformation_type); + wxGetApp().obj_manipul()->set_dirty(); break; } case Rotate: @@ -640,7 +643,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) if (evt.AltDown()) transformation_type.set_independent(); selection.rotate(get_rotation(), transformation_type); - wxGetApp().obj_manipul()->update_settings_value(selection); + wxGetApp().obj_manipul()->set_dirty(); break; } default: @@ -677,7 +680,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) stop_dragging(); update_data(canvas); - wxGetApp().obj_manipul()->update_settings_value(selection); + wxGetApp().obj_manipul()->set_dirty(); // Let the platter know that the dragging finished, so a delayed refresh // of the scene with the background processing data should be performed. canvas.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index c80ee2ce4..7042c125a 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -109,8 +109,8 @@ void KBShortcutsDialog::fill_shortcuts() main_shortcuts.push_back(Shortcut(ctrl+"S" ,L("Save project (3MF)"))); main_shortcuts.push_back(Shortcut(ctrl+alt+"L" ,L("Load Config from .ini/amf/3mf/gcode and merge"))); main_shortcuts.push_back(Shortcut(ctrl+"R" ,L("(Re)slice"))); - main_shortcuts.push_back(Shortcut(ctrl+"U" ,L("Quick slice"))); - main_shortcuts.push_back(Shortcut(ctrl+"Shift+U" ,L("Repeat last quick slice"))); +// main_shortcuts.push_back(Shortcut(ctrl+"U" ,L("Quick slice"))); +// main_shortcuts.push_back(Shortcut(ctrl+"Shift+U" ,L("Repeat last quick slice"))); main_shortcuts.push_back(Shortcut(ctrl+"1" ,L("Select Plater Tab"))); main_shortcuts.push_back(Shortcut(ctrl+alt+"U" ,L("Quick slice and Save as"))); main_shortcuts.push_back(Shortcut(ctrl+"2" ,L("Select Print Settings Tab"))); diff --git a/src/slic3r/GUI/LambdaObjectDialog.cpp b/src/slic3r/GUI/LambdaObjectDialog.cpp index 0146db5f6..4d1cb0658 100644 --- a/src/slic3r/GUI/LambdaObjectDialog.cpp +++ b/src/slic3r/GUI/LambdaObjectDialog.cpp @@ -49,7 +49,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, }; def.type = coFloat; - def.default_value = new ConfigOptionFloat{ 1.0 }; + def.set_default_value(new ConfigOptionFloat{ 1.0 }); def.label = L("Length"); Option option(def, "l"); optgroup->append_single_option_line(option); @@ -75,7 +75,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, }; def.type = coInt; - def.default_value = new ConfigOptionInt{ 1 }; + def.set_default_value(new ConfigOptionInt{ 1 }); def.label = L("Radius"); auto option = Option(def, "cyl_r"); optgroup->append_single_option_line(option); @@ -94,7 +94,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, }; def.type = coFloat; - def.default_value = new ConfigOptionFloat{ 1.0 }; + def.set_default_value(new ConfigOptionFloat{ 1.0 }); def.label = L("Rho"); auto option = Option(def, "sph_rho"); optgroup->append_single_option_line(option); @@ -112,7 +112,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, }; def.type = coFloat; - def.default_value = new ConfigOptionFloat{ 1.0 }; + def.set_default_value(new ConfigOptionFloat{ 1.0 }); def.label = L("Height"); auto option = Option(def, "slab_h"); optgroup->append_single_option_line(option); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 144662a9f..cdcde972a 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -175,18 +175,21 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // Build a label if we have it wxStaticText* label=nullptr; if (label_width != 0) { - long label_style = staticbox ? 0 : wxALIGN_RIGHT; + if (! line.near_label_widget || ! line.label.IsEmpty()) { + // Only create the label if it is going to be displayed. + long label_style = staticbox ? 0 : wxALIGN_RIGHT; #ifdef __WXGTK__ - // workaround for correct text align of the StaticBox on Linux - // flags wxALIGN_RIGHT and wxALIGN_CENTRE don't work when Ellipsize flags are _not_ given. - // Text is properly aligned only when Ellipsize is checked. - label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END; + // workaround for correct text align of the StaticBox on Linux + // flags wxALIGN_RIGHT and wxALIGN_CENTRE don't work when Ellipsize flags are _not_ given. + // Text is properly aligned only when Ellipsize is checked. + label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END; #endif /* __WXGTK__ */ - label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "), - wxDefaultPosition, wxSize(label_width*wxGetApp().em_unit(), -1), label_style); - label->SetBackgroundStyle(wxBG_STYLE_PAINT); - label->SetFont(wxGetApp().normal_font()); - label->Wrap(label_width*wxGetApp().em_unit()); // avoid a Linux/GTK bug + label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "), + wxDefaultPosition, wxSize(label_width*wxGetApp().em_unit(), -1), label_style); + label->SetBackgroundStyle(wxBG_STYLE_PAINT); + label->SetFont(wxGetApp().normal_font()); + label->Wrap(label_width*wxGetApp().em_unit()); // avoid a Linux/GTK bug + } if (!line.near_label_widget) grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5); else { @@ -203,7 +206,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5); } } - if (line.label_tooltip.compare("") != 0) + if (label != nullptr && line.label_tooltip != "") label->SetToolTip(line.label_tooltip); } @@ -426,22 +429,21 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, void ConfigOptionsGroup::on_kill_focus(const std::string& opt_key) { - if (m_fill_empty_value) { + if (m_fill_empty_value) m_fill_empty_value(opt_key); - return; - } - reload_config(); + else + reload_config(); } -void ConfigOptionsGroup::reload_config() { - for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) { - auto opt_id = it->first; - std::string opt_key = m_opt_map.at(opt_id).first; - int opt_index = m_opt_map.at(opt_id).second; - auto option = m_options.at(opt_id).opt; - set_value(opt_id, config_value(opt_key, opt_index, option.gui_flags.compare("serialized") == 0 )); +void ConfigOptionsGroup::reload_config() +{ + for (auto &kvp : m_opt_map) { + const std::string &opt_id = kvp.first; + const std::string &opt_key = kvp.second.first; + int opt_index = kvp.second.second; + const ConfigOptionDef &option = m_options.at(opt_id).opt; + this->set_value(opt_key, config_value(opt_key, opt_index, option.gui_flags == "serialized")); } - } void ConfigOptionsGroup::Hide() diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 67875587a..fa8a19940 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -260,7 +260,7 @@ public: void back_to_initial_value(const std::string& opt_key) override; void back_to_sys_value(const std::string& opt_key) override; void back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key); - void on_kill_focus(const std::string& opt_key) override;// { reload_config(); } + void on_kill_focus(const std::string& opt_key) override; void reload_config(); // return value shows visibility : false => all options are hidden void Hide(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d79de9c28..4aa1ce80f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -394,16 +394,27 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : } new_conf.set_key_value("brim_width", new ConfigOptionFloat(new_val)); } - else { //(opt_key == "support") + else { + assert(opt_key == "support"); const wxString& selection = boost::any_cast(value); + PrinterTechnology printer_technology = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology(); auto support_material = selection == _("None") ? false : true; new_conf.set_key_value("support_material", new ConfigOptionBool(support_material)); - if (selection == _("Everywhere")) + if (selection == _("Everywhere")) { new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false)); - else if (selection == _("Support on build plate only")) + if (printer_technology == ptFFF) + new_conf.set_key_value("support_material_auto", new ConfigOptionBool(true)); + } else if (selection == _("Support on build plate only")) { new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(true)); + if (printer_technology == ptFFF) + new_conf.set_key_value("support_material_auto", new ConfigOptionBool(true)); + } else if (selection == _("For support enforcers only")) { + assert(printer_technology == ptFFF); + new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false)); + new_conf.set_key_value("support_material_auto", new ConfigOptionBool(false)); + } } tab_print->load_config(new_conf); } @@ -421,12 +432,9 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : support_def.tooltip = L("Select what kind of support do you need"); support_def.enum_labels.push_back(L("None")); support_def.enum_labels.push_back(L("Support on build plate only")); + support_def.enum_labels.push_back(L("For support enforcers only")); support_def.enum_labels.push_back(L("Everywhere")); - std::string selection = !config->opt_bool("support_material") ? - "None" : config->opt_bool("support_material_buildplate_only") ? - "Support on build plate only" : - "Everywhere"; - support_def.default_value = new ConfigOptionStrings{ selection }; + support_def.set_default_value(new ConfigOptionStrings{ "None" }); Option option = Option(support_def, "support"); option.opt.full_width = true; line.append_option(option); @@ -447,7 +455,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : def.type = coBool; def.tooltip = L("This flag enables the brim that will be printed around each object on the first layer."); def.gui_type = ""; - def.default_value = new ConfigOptionBool{ m_brim_width > 0.0 ? true : false }; + def.set_default_value(new ConfigOptionBool{ m_brim_width > 0.0 ? true : false }); option = Option(def, "brim"); option.opt.sidetext = " "; line.append_option(option); @@ -493,8 +501,9 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : tab->set_value(opt_key, value); tab->update(); } - else //(opt_key == "support") + else { + assert(opt_key == "support"); DynamicPrintConfig new_conf = *config_sla; const wxString& selection = boost::any_cast(value); @@ -514,17 +523,15 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) : line = Line{ "", "" }; - selection = !config_sla->opt_bool("supports_enable") ? - "None" : config_sla->opt_bool("support_buildplate_only") ? - "Support on build plate only" : - "Everywhere"; - support_def.default_value = new ConfigOptionStrings{ selection }; - option = Option(support_def, "support"); + ConfigOptionDef support_def_sla = support_def; + support_def_sla.set_default_value(new ConfigOptionStrings{ "None" }); + assert(support_def_sla.enum_labels[2] == L("For support enforcers only")); + support_def_sla.enum_labels.erase(support_def_sla.enum_labels.begin() + 2); + option = Option(support_def_sla, "support"); option.opt.full_width = true; line.append_option(option); m_og_sla->append_line(line); - line = Line{ "", "" }; option = m_og_sla->get_option("pad_enable"); @@ -1099,9 +1106,9 @@ void Sidebar::enable_buttons(bool enable) p->btn_send_gcode->Enable(enable); } -void Sidebar::show_reslice(bool show) const { p->btn_reslice->Show(show); } -void Sidebar::show_export(bool show) const { p->btn_export_gcode->Show(show); } -void Sidebar::show_send(bool show) const { p->btn_send_gcode->Show(show); } +bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); } +bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); } +bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); } bool Sidebar::is_multifilament() { @@ -3194,17 +3201,18 @@ void Plater::priv::show_action_buttons(const bool is_ready_to_slice) const // when a background processing is ON, export_btn and/or send_btn are showing if (wxGetApp().app_config->get("background_processing") == "1") { - sidebar->show_reslice(false); - sidebar->show_export(true); - sidebar->show_send(send_gcode_shown); - } + if (sidebar->show_reslice(false) | + sidebar->show_export(true) | + sidebar->show_send(send_gcode_shown)) + sidebar->Layout(); + } else { - sidebar->show_reslice(is_ready_to_slice); - sidebar->show_export(!is_ready_to_slice); - sidebar->show_send(send_gcode_shown && !is_ready_to_slice); - } - sidebar->Layout(); + if (sidebar->show_reslice(is_ready_to_slice) | + sidebar->show_export(!is_ready_to_slice) | + sidebar->show_send(send_gcode_shown && !is_ready_to_slice)) + sidebar->Layout(); + } } void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString& label) const diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 5118fdd6c..e4327f433 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -103,9 +103,9 @@ public: void show_sliced_info_sizer(const bool show); void enable_buttons(bool enable); void set_btn_label(const ActionButtonType btn_type, const wxString& label) const; - void show_reslice(bool show) const; - void show_export(bool show) const; - void show_send(bool show) const; + bool show_reslice(bool show) const; + bool show_export(bool show) const; + bool show_send(bool show) const; bool is_multifilament(); void update_mode(); diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index b6a340d08..2bf9b6332 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -37,7 +37,7 @@ void PreferencesDialog::build() def.type = coBool; def.tooltip = L("If this is enabled, Slic3r will prompt the last output directory " "instead of the one containing the input files."); - def.default_value = new ConfigOptionBool{ app_config->has("remember_output_path") ? app_config->get("remember_output_path") == "1" : true }; + def.set_default_value(new ConfigOptionBool{ app_config->has("remember_output_path") ? app_config->get("remember_output_path") == "1" : true }); Option option(def, "remember_output_path"); m_optgroup->append_single_option_line(option); @@ -45,7 +45,7 @@ void PreferencesDialog::build() def.type = coBool; def.tooltip = L("If this is enabled, Slic3r will auto-center objects " "around the print bed center."); - def.default_value = new ConfigOptionBool{ app_config->get("autocenter") == "1" }; + def.set_default_value(new ConfigOptionBool{ app_config->get("autocenter") == "1" }); option = Option (def,"autocenter"); m_optgroup->append_single_option_line(option); @@ -53,7 +53,7 @@ void PreferencesDialog::build() def.type = coBool; def.tooltip = L("If this is enabled, Slic3r will pre-process objects as soon " "as they\'re loaded in order to save time when exporting G-code."); - def.default_value = new ConfigOptionBool{ app_config->get("background_processing") == "1" }; + def.set_default_value(new ConfigOptionBool{ app_config->get("background_processing") == "1" }); option = Option (def,"background_processing"); m_optgroup->append_single_option_line(option); @@ -61,7 +61,7 @@ void PreferencesDialog::build() def.label = L("Check for application updates"); def.type = coBool; def.tooltip = L("If enabled, Slic3r checks for new versions of " SLIC3R_APP_NAME " online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done."); - def.default_value = new ConfigOptionBool(app_config->get("version_check") == "1"); + def.set_default_value(new ConfigOptionBool(app_config->get("version_check") == "1")); option = Option (def, "version_check"); m_optgroup->append_single_option_line(option); @@ -69,7 +69,7 @@ void PreferencesDialog::build() def.label = L("Update built-in Presets automatically"); def.type = coBool; def.tooltip = L("If enabled, Slic3r downloads updates of built-in system presets in the background. These updates are downloaded into a separate temporary location. When a new preset version becomes available it is offered at application startup."); - def.default_value = new ConfigOptionBool(app_config->get("preset_update") == "1"); + def.set_default_value(new ConfigOptionBool(app_config->get("preset_update") == "1")); option = Option (def, "preset_update"); m_optgroup->append_single_option_line(option); @@ -77,7 +77,7 @@ void PreferencesDialog::build() def.type = coBool; def.tooltip = L("Suppress \" - default - \" presets in the Print / Filament / Printer " "selections once there are any other valid presets available."); - def.default_value = new ConfigOptionBool{ app_config->get("no_defaults") == "1" }; + def.set_default_value(new ConfigOptionBool{ app_config->get("no_defaults") == "1" }); option = Option (def,"no_defaults"); m_optgroup->append_single_option_line(option); @@ -85,7 +85,7 @@ void PreferencesDialog::build() def.type = coBool; def.tooltip = L("When checked, the print and filament presets are shown in the preset editor " "even if they are marked as incompatible with the active printer"); - def.default_value = new ConfigOptionBool{ app_config->get("show_incompatible_presets") == "1" }; + def.set_default_value(new ConfigOptionBool{ app_config->get("show_incompatible_presets") == "1" }); option = Option (def,"show_incompatible_presets"); m_optgroup->append_single_option_line(option); @@ -95,7 +95,7 @@ void PreferencesDialog::build() def.tooltip = L("If you have rendering issues caused by a buggy OpenGL 2.0 driver, " "you may try to check this checkbox. This will disable the layer height " "editing and anti aliasing, so it is likely better to upgrade your graphics driver."); - def.default_value = new ConfigOptionBool{ app_config->get("use_legacy_opengl") == "1" }; + def.set_default_value(new ConfigOptionBool{ app_config->get("use_legacy_opengl") == "1" }); option = Option (def,"use_legacy_opengl"); m_optgroup->append_single_option_line(option); @@ -104,7 +104,7 @@ void PreferencesDialog::build() def.type = coBool; def.tooltip = L("If enabled, the 3D scene will be rendered in Retina resolution. " "If you are experiencing 3D performance problems, disabling this option may help."); - def.default_value = new ConfigOptionBool{ app_config->get("use_retina_opengl") == "1" }; + def.set_default_value(new ConfigOptionBool{ app_config->get("use_retina_opengl") == "1" }); option = Option (def, "use_retina_opengl"); m_optgroup->append_single_option_line(option); #endif diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index e014851ab..28cab3eba 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -54,10 +54,10 @@ Selection::Selection() , m_mode(Instance) , m_type(Empty) , m_valid(false) - , m_bounding_box_dirty(true) , m_curved_arrow(16) , m_scale_factor(1.0f) { + this->set_bounding_boxes_dirty(); #if ENABLE_RENDER_SELECTION_CENTER m_quadric = ::gluNewQuadric(); if (m_quadric != nullptr) @@ -148,7 +148,7 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection, bool chec } update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::remove(unsigned int volume_idx) @@ -173,7 +173,7 @@ void Selection::remove(unsigned int volume_idx) } update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::add_object(unsigned int object_idx, bool as_single_selection) @@ -190,7 +190,7 @@ void Selection::add_object(unsigned int object_idx, bool as_single_selection) do_add_object(object_idx); update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::remove_object(unsigned int object_idx) @@ -201,7 +201,7 @@ void Selection::remove_object(unsigned int object_idx) do_remove_object(object_idx); update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::add_instance(unsigned int object_idx, unsigned int instance_idx, bool as_single_selection) @@ -218,7 +218,7 @@ void Selection::add_instance(unsigned int object_idx, unsigned int instance_idx, do_add_instance(object_idx, instance_idx); update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::remove_instance(unsigned int object_idx, unsigned int instance_idx) @@ -229,7 +229,7 @@ void Selection::remove_instance(unsigned int object_idx, unsigned int instance_i do_remove_instance(object_idx, instance_idx); update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::add_volume(unsigned int object_idx, unsigned int volume_idx, int instance_idx, bool as_single_selection) @@ -254,7 +254,7 @@ void Selection::add_volume(unsigned int object_idx, unsigned int volume_idx, int } update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::remove_volume(unsigned int object_idx, unsigned int volume_idx) @@ -270,7 +270,7 @@ void Selection::remove_volume(unsigned int object_idx, unsigned int volume_idx) } update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::add_all() @@ -288,7 +288,7 @@ void Selection::add_all() } update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::clear() @@ -304,51 +304,44 @@ void Selection::clear() m_list.clear(); update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); // resets the cache in the sidebar wxGetApp().obj_manipul()->reset_cache(); } +// Update the selection based on the new instance IDs. +void Selection::instances_changed(const std::vector &instance_ids_selected) +{ + assert(m_valid); + assert(m_mode == Instance); + m_list.clear(); + for (unsigned int volume_idx = 0; volume_idx < (unsigned int)m_volumes->size(); ++ volume_idx) { + const GLVolume *volume = (*m_volumes)[volume_idx]; + auto it = std::lower_bound(instance_ids_selected.begin(), instance_ids_selected.end(), volume->geometry_id.second); + if (it != instance_ids_selected.end() && *it == volume->geometry_id.second) + this->do_add_volume(volume_idx); + } + update_type(); + this->set_bounding_boxes_dirty(); +} + // Update the selection based on the map from old indices to new indices after m_volumes changed. // If the current selection is by instance, this call may select newly added volumes, if they belong to already selected instances. void Selection::volumes_changed(const std::vector &map_volume_old_to_new) { assert(m_valid); - - // 1) Update the selection set. + assert(m_mode == Volume); IndicesList list_new; - std::vector> model_instances; - for (unsigned int idx : m_list) { + for (unsigned int idx : m_list) if (map_volume_old_to_new[idx] != size_t(-1)) { unsigned int new_idx = (unsigned int)map_volume_old_to_new[idx]; + assert((*m_volumes)[new_idx]->selected); list_new.insert(new_idx); - if (m_mode == Instance) { - // Save the object_idx / instance_idx pair of selected old volumes, - // so we may add the newly added volumes of the same object_idx / instance_idx pair - // to the selection. - const GLVolume *volume = (*m_volumes)[new_idx]; - model_instances.emplace_back(volume->object_idx(), volume->instance_idx()); - } } - } m_list = std::move(list_new); - - if (!model_instances.empty()) { - // Instance selection mode. Add the newly added volumes of the same object_idx / instance_idx pair - // to the selection. - assert(m_mode == Instance); - sort_remove_duplicates(model_instances); - for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) { - const GLVolume* volume = (*m_volumes)[i]; - for (const std::pair &model_instance : model_instances) - if (volume->object_idx() == model_instance.first && volume->instance_idx() == model_instance.second) - do_add_volume(i); - } - } - update_type(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } bool Selection::is_single_full_instance() const @@ -433,6 +426,14 @@ const BoundingBoxf3& Selection::get_bounding_box() const return m_bounding_box; } +const BoundingBoxf3& Selection::get_unscaled_instance_bounding_box() const +{ + if (m_unscaled_instance_bounding_box_dirty) + calc_unscaled_instance_bounding_box(); + + return m_unscaled_instance_bounding_box; +} + void Selection::start_dragging() { if (!m_valid) @@ -480,7 +481,7 @@ void Selection::translate(const Vec3d& displacement, bool local) synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } // Rotate an object around one of the axes. Only one rotation component is expected to be changing. @@ -587,7 +588,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::flattening_rotate(const Vec3d& normal) @@ -628,20 +629,29 @@ void Selection::flattening_rotate(const Vec3d& normal) synchronize_unselected_instances(SYNC_ROTATION_FULL); #endif // !DISABLE_INSTANCES_SYNCH - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } -void Selection::scale(const Vec3d& scale, bool local) +void Selection::scale(const Vec3d& scale, TransformationType transformation_type) { if (!m_valid) return; for (unsigned int i : m_list) { - if (is_single_full_instance()) - (*m_volumes)[i]->set_instance_scaling_factor(scale); + GLVolume &volume = *(*m_volumes)[i]; + if (is_single_full_instance()) { + assert(transformation_type.absolute()); + 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(volume.get_instance_rotation())); + volume.set_instance_scaling_factor((volume.get_instance_transformation().get_matrix(true, false, true, true).matrix().block<3, 3>(0, 0).transpose() * scale).cwiseAbs()); + } else + volume.set_instance_scaling_factor(scale); + } else if (is_single_volume() || is_single_modifier()) - (*m_volumes)[i]->set_volume_scaling_factor(scale); + volume.set_volume_scaling_factor(scale); else { Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale); @@ -650,22 +660,22 @@ void Selection::scale(const Vec3d& scale, bool local) Eigen::Matrix 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 Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); - if (!local) - (*m_volumes)[i]->set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center)); + if (transformation_type.joint()) + volume.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center)); - (*m_volumes)[i]->set_instance_scaling_factor(new_scale); + volume.set_instance_scaling_factor(new_scale); } else if (m_mode == Volume) { Eigen::Matrix 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 Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); - if (!local) + if (transformation_type.joint()) { Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() + m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center); - (*m_volumes)[i]->set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset); + volume.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset); } - (*m_volumes)[i]->set_volume_scaling_factor(new_scale); + volume.set_volume_scaling_factor(new_scale); } } } @@ -679,7 +689,7 @@ void Selection::scale(const Vec3d& scale, bool local) ensure_on_bed(); - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::mirror(Axis axis) @@ -704,7 +714,7 @@ void Selection::mirror(Axis axis) synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::translate(unsigned int object_idx, const Vec3d& displacement) @@ -749,7 +759,7 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement) } } - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement) @@ -794,7 +804,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co } } - m_bounding_box_dirty = true; + this->set_bounding_boxes_dirty(); } void Selection::erase() @@ -959,7 +969,7 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const const Vec3d& center = get_bounding_box().center(); - if (is_single_full_instance()) + if (is_single_full_instance() && ! wxGetApp().obj_manipul()->get_world_coordinates()) { glsafe(::glTranslated(center(0), center(1), center(2))); if (!boost::starts_with(sidebar_field, "position")) @@ -1400,7 +1410,23 @@ void Selection::calc_bounding_box() const m_bounding_box.merge((*m_volumes)[i]->transformed_convex_hull_bounding_box()); } } - m_bounding_box_dirty = false; + m_bounding_box_dirty = false; +} + +void Selection::calc_unscaled_instance_bounding_box() const +{ + m_unscaled_instance_bounding_box = BoundingBoxf3(); + if (m_valid) + { + for (unsigned int i : m_list) + { + const GLVolume &volume = *(*m_volumes)[i]; + Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, true, false) * volume.get_volume_transformation().get_matrix(); + trafo.translation()(2) += volume.get_sla_shift_z(); + m_unscaled_instance_bounding_box.merge(volume.transformed_convex_hull_bounding_box(trafo)); + } + } + m_unscaled_instance_bounding_box_dirty = false; } void Selection::render_selected_volumes() const diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 87c919680..d808bee07 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -183,6 +183,10 @@ private: Clipboard m_clipboard; mutable BoundingBoxf3 m_bounding_box; mutable bool m_bounding_box_dirty; + // Bounding box of a selection, with no instance scaling applied. This bounding box + // is useful for absolute scaling of tilted objects in world coordinate space. + mutable BoundingBoxf3 m_unscaled_instance_bounding_box; + mutable bool m_unscaled_instance_bounding_box_dirty; #if ENABLE_RENDER_SELECTION_CENTER GLUquadricObj* m_quadric; @@ -224,6 +228,8 @@ public: void add_all(); + // Update the selection based on the new instance IDs. + void instances_changed(const std::vector &instance_ids_selected); // Update the selection based on the map from old indices to new indices after m_volumes changed. // If the current selection is by instance, this call may select newly added volumes, if they belong to already selected instances. void volumes_changed(const std::vector &map_volume_old_to_new); @@ -245,7 +251,7 @@ public: bool is_from_single_instance() const { return get_instance_idx() != -1; } bool is_from_single_object() const; - bool contains_volume(unsigned int volume_idx) const { return std::find(m_list.begin(), m_list.end(), volume_idx) != m_list.end(); } + bool contains_volume(unsigned int volume_idx) const { return m_list.find(volume_idx) != m_list.end(); } bool requires_uniform_scale() const; // Returns the the object id if the selection is from a single object, otherwise is -1 @@ -263,13 +269,16 @@ public: unsigned int volumes_count() const { return (unsigned int)m_list.size(); } const BoundingBoxf3& get_bounding_box() const; + // Bounding box of a selection, with no instance scaling applied. This bounding box + // is useful for absolute scaling of tilted objects in world coordinate space. + const BoundingBoxf3& get_unscaled_instance_bounding_box() const; void start_dragging(); void translate(const Vec3d& displacement, bool local = false); void rotate(const Vec3d& rotation, TransformationType transformation_type); void flattening_rotate(const Vec3d& normal); - void scale(const Vec3d& scale, bool local); + void scale(const Vec3d& scale, TransformationType transformation_type); void mirror(Axis axis); void translate(unsigned int object_idx, const Vec3d& displacement); @@ -301,6 +310,8 @@ private: void do_remove_instance(unsigned int object_idx, unsigned int instance_idx); void do_remove_object(unsigned int object_idx); void calc_bounding_box() const; + void calc_unscaled_instance_bounding_box() const; + void set_bounding_boxes_dirty() { m_bounding_box_dirty = true; m_unscaled_instance_bounding_box_dirty = true; } void render_selected_volumes() const; void render_synchronized_volumes() const; void render_bounding_box(const BoundingBoxf3& box, float* color) const; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index b97623648..c6043e802 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -816,6 +816,19 @@ void Tab::load_key_value(const std::string& opt_key, const boost::any& value, bo update(); } +static wxString support_combo_value_for_config(const DynamicPrintConfig &config, bool is_fff) +{ + const std::string support = is_fff ? "support_material" : "supports_enable"; + const std::string buildplate_only = is_fff ? "support_material_buildplate_only" : "support_buildplate_only"; + return + ! config.opt_bool(support) ? + _("None") : + (is_fff && !config.opt_bool("support_material_auto")) ? + _("For support enforcers only") : + (config.opt_bool(buildplate_only) ? _("Support on build plate only") : + _("Everywhere")); +} + void Tab::on_value_change(const std::string& opt_key, const boost::any& value) { if (wxGetApp().plater() == nullptr) { @@ -823,23 +836,17 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) } const bool is_fff = supports_printer_technology(ptFFF); - ConfigOptionsGroup* og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(is_fff); + ConfigOptionsGroup* og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(is_fff); if (opt_key == "fill_density" || opt_key == "pad_enable") { boost::any val = og_freq_chng_params->get_config_value(*m_config, opt_key); og_freq_chng_params->set_value(opt_key, val); } - if ( is_fff && (opt_key == "support_material" || opt_key == "support_material_buildplate_only") || - !is_fff && (opt_key == "supports_enable" || opt_key == "support_buildplate_only")) - { - const std::string support = is_fff ? "support_material" : "supports_enable"; - const std::string buildplate_only = is_fff ? "support_material_buildplate_only" : "support_buildplate_only"; - wxString new_selection = !m_config->opt_bool(support) ? _("None") : - m_config->opt_bool(buildplate_only) ? _("Support on build plate only") : - _("Everywhere"); - og_freq_chng_params->set_value("support", new_selection); - } + if (is_fff ? + (opt_key == "support_material" || opt_key == "support_material_auto" || opt_key == "support_material_buildplate_only") : + (opt_key == "supports_enable" || opt_key == "support_buildplate_only")) + og_freq_chng_params->set_value("support", support_combo_value_for_config(*m_config, is_fff)); if (opt_key == "brim_width") { @@ -965,18 +972,11 @@ void Tab::update_preset_description_line() void Tab::update_frequently_changed_parameters() { - auto og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(supports_printer_technology(ptFFF)); + const bool is_fff = supports_printer_technology(ptFFF); + auto og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(is_fff); if (!og_freq_chng_params) return; - const bool is_fff = supports_printer_technology(ptFFF); - - const std::string support = is_fff ? "support_material" : "supports_enable"; - const std::string buildplate_only = is_fff ? "support_material_buildplate_only" : "support_buildplate_only"; - - wxString new_selection = !m_config->opt_bool(support) ? _("None") : - m_config->opt_bool(buildplate_only) ? _("Support on build plate only") : - _("Everywhere"); - og_freq_chng_params->set_value("support", new_selection); + og_freq_chng_params->set_value("support", support_combo_value_for_config(*m_config, is_fff)); const std::string updated_value_key = is_fff ? "fill_density" : "pad_enable"; @@ -1841,7 +1841,7 @@ void TabPrinter::build_fff() optgroup = page->new_optgroup(_(L("Capabilities"))); ConfigOptionDef def; def.type = coInt, - def.default_value = new ConfigOptionInt(1); + def.set_default_value(new ConfigOptionInt(1)); def.label = L("Extruders"); def.tooltip = L("Number of extruders of the printer."); def.min = 1; @@ -2149,13 +2149,13 @@ PageShp TabPrinter::build_kinematics_page() def.gui_type = "legend"; def.mode = comAdvanced; def.tooltip = L("Values in this column are for Full Power mode"); - def.default_value = new ConfigOptionString{ L("Full Power") }; + def.set_default_value(new ConfigOptionString{ L("Full Power") }); auto option = Option(def, "full_power_legend"); line.append_option(option); def.tooltip = L("Values in this column are for Silent mode"); - def.default_value = new ConfigOptionString{ L("Silent") }; + def.set_default_value(new ConfigOptionString{ L("Silent") }); option = Option(def, "silent_legend"); line.append_option(option); diff --git a/xs/xsp/Config.xsp b/xs/xsp/Config.xsp index f9482bd3b..4d48a2c6f 100644 --- a/xs/xsp/Config.xsp +++ b/xs/xsp/Config.xsp @@ -223,8 +223,8 @@ print_config_def() (void)hv_stores( hv, "labels", newRV_noinc((SV*)av) ); } - if (optdef->default_value != NULL) - (void)hv_stores( hv, "default", ConfigOption_to_SV(*optdef->default_value, *optdef) ); + if (optdef->default_value) + (void)hv_stores( hv, "default", ConfigOption_to_SV(*optdef->default_value.get(), *optdef) ); (void)hv_store( options_hv, opt_key.c_str(), opt_key.length(), newRV_noinc((SV*)hv), 0 ); }