diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 144272b8e36..493ae950a7c 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -353,6 +353,7 @@ class ModelObject final : public ObjectBase /// It operates on the total size by duplicating the object according to all the instances. /// \param size Sizef3 the size vector void scale_to_fit(const Vec3d &size); + /// Rotate the model along its internal position (does not take its position into account) void rotate(double angle, Axis axis); void rotate(double angle, const Vec3d& axis); void mirror(Axis axis); diff --git a/src/slic3r/GUI/CalibrationAbstractDialog.cpp b/src/slic3r/GUI/CalibrationAbstractDialog.cpp index 385d5e0cfbb..f3eaebbb664 100644 --- a/src/slic3r/GUI/CalibrationAbstractDialog.cpp +++ b/src/slic3r/GUI/CalibrationAbstractDialog.cpp @@ -5,6 +5,7 @@ #include "GUI.hpp" #include "GUI_ObjectList.hpp" #include "Tab.hpp" +#include "Plater.hpp" #include #include @@ -101,7 +102,7 @@ void CalibrationAbstractDialog::close_me(wxCommandEvent& event_args) { this->Destroy(); } -ModelObject* CalibrationAbstractDialog::add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale) { +void CalibrationAbstractDialog::add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale, bool rotate) { Model model; try { model = Model::read_from_file(input_file); @@ -124,6 +125,8 @@ ModelObject* CalibrationAbstractDialog::add_part(ModelObject* model_object, std: if (scale != Vec3d{ 1,1,1 }) { volume->scale(scale); } + if(rotate) + volume->rotate(Geometry::deg2rad(this->main_frame->plater()->config()->opt_float("init_z_rotate")), Axis::Z); ModelVolume* new_volume = model_object->add_volume(*volume); new_volume->set_type(ModelVolumeType::MODEL_PART); new_volume->name = boost::filesystem::path(input_file).filename().string(); @@ -145,7 +148,6 @@ ModelObject* CalibrationAbstractDialog::add_part(ModelObject* model_object, std: } } assert(model.objects.size() == 1); - return model.objects.empty()?nullptr: model.objects[0]; } void CalibrationAbstractDialog::on_dpi_changed(const wxRect& suggested_rect) diff --git a/src/slic3r/GUI/CalibrationAbstractDialog.hpp b/src/slic3r/GUI/CalibrationAbstractDialog.hpp index 1cb50c4257b..a54fa6d72b3 100644 --- a/src/slic3r/GUI/CalibrationAbstractDialog.hpp +++ b/src/slic3r/GUI/CalibrationAbstractDialog.hpp @@ -29,7 +29,7 @@ class CalibrationAbstractDialog : public DPIDialog virtual void create_buttons(wxStdDialogButtonSizer*) = 0; void on_dpi_changed(const wxRect& suggested_rect) override; void close_me(wxCommandEvent& event_args); - ModelObject* add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale = Vec3d{ 1,1,1 }); + void add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale = Vec3d{ 1,1,1 }, bool rotate = true); wxHtmlWindow* html_viewer; MainFrame* main_frame; diff --git a/src/slic3r/GUI/CalibrationBridgeDialog.cpp b/src/slic3r/GUI/CalibrationBridgeDialog.cpp index 0d703d42915..30a98d55a08 100644 --- a/src/slic3r/GUI/CalibrationBridgeDialog.cpp +++ b/src/slic3r/GUI/CalibrationBridgeDialog.cpp @@ -101,6 +101,16 @@ void CalibrationBridgeDialog::create_geometry(std::string setting_to_test, bool } else { z_scale = 1; } + + // it's rotated but not around the good origin: correct that + double init_z_rotate_angle = Geometry::deg2rad(plat->config()->opt_float("init_z_rotate")); + Matrix3d rot_matrix = Eigen::Quaterniond(Eigen::AngleAxisd(init_z_rotate_angle, Vec3d{0,0,1})).toRotationMatrix(); + auto translate_from_rotation = [&rot_matrix, &model, &objs_idx](int idx, Vec3d &&translation) { + ModelVolume *vol = model.objects[objs_idx[idx]]->volumes[model.objects[objs_idx[idx]]->volumes.size()-1]; + Geometry::Transformation trsf = vol->get_transformation(); + trsf.set_offset(rot_matrix * translation - translation + trsf.get_offset()); + vol->set_transformation(trsf); + }; //add sub-part after scale const ConfigOptionPercent* bridge_flow_ratio = print_config->option(setting_to_test); @@ -109,11 +119,12 @@ void CalibrationBridgeDialog::create_geometry(std::string setting_to_test, bool for (size_t i = 0; i < nb_items; i++) { int step_num = (start + (add ? 1 : -1) * i * step); if (step_num < 180 && step_num > 20 && step_num%5 == 0) { - add_part(model.objects[objs_idx[i]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "bridge_flow" / ("f" + std::to_string(step_num) + ".amf")).string(), Vec3d{ -10,0, zshift + 4.6 * z_scale }, Vec3d{ 1,1,z_scale }); + add_part(model.objects[objs_idx[i]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "bridge_flow" / ("f" + std::to_string(step_num) + ".amf")).string(), Vec3d{ -10, 0, zshift + 4.6 * z_scale }, Vec3d{ 1,1,z_scale }); + translate_from_rotation(i, Vec3d{ -10, 0, zshift + 4.6 * z_scale }); } } /// --- translate ---; - bool has_to_arrange = false; + bool has_to_arrange = init_z_rotate_angle != 0; const float brim_width = std::max(print_config->option("brim_width")->value, nozzle_diameter * 5.); const ConfigOptionFloat* extruder_clearance_radius = print_config->option("extruder_clearance_radius"); const ConfigOptionPoints* bed_shape = printer_config->option("bed_shape"); diff --git a/src/slic3r/GUI/CalibrationFlowDialog.cpp b/src/slic3r/GUI/CalibrationFlowDialog.cpp index d697aad6f20..f128b9923d4 100644 --- a/src/slic3r/GUI/CalibrationFlowDialog.cpp +++ b/src/slic3r/GUI/CalibrationFlowDialog.cpp @@ -92,6 +92,17 @@ void CalibrationFlowDialog::create_geometry(float start, float delta) { The 0.3 constant is the same as the delta calculated in add_part below, this should probably be calculated per the model object */ float zshift = -(zscale / 2) + ((first_layer_height + layer_height) / 2) + 0.3; + + // it's rotated but not around the good origin: correct that + double init_z_rotate_angle = Geometry::deg2rad(plat->config()->opt_float("init_z_rotate")); + Matrix3d rot_matrix = Eigen::Quaterniond(Eigen::AngleAxisd(init_z_rotate_angle, Vec3d{0,0,1})).toRotationMatrix(); + auto translate_from_rotation = [&rot_matrix, &model, &objs_idx](int idx, Vec3d &&translation) { + ModelVolume *vol = model.objects[objs_idx[idx]]->volumes[model.objects[objs_idx[idx]]->volumes.size()-1]; + Geometry::Transformation trsf = vol->get_transformation(); + trsf.set_offset(rot_matrix * translation - translation + trsf.get_offset()); + vol->set_transformation(trsf); + }; + if (delta == 10.f && start == 80.f) { add_part(model.objects[objs_idx[0]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_flow" / "m20.amf").string(), Vec3d{ 10 * xyScale,0,zshift }, Vec3d{ xyScale , xyScale, zscale_number}); add_part(model.objects[objs_idx[1]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_flow" / "m10.amf").string(), Vec3d{ 10 * xyScale,0,zshift }, Vec3d{ xyScale , xyScale, zscale_number }); @@ -106,11 +117,13 @@ void CalibrationFlowDialog::create_geometry(float start, float delta) { add_part(model.objects[objs_idx[4]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_flow" / "_0.amf").string(), Vec3d{ 10 * xyScale,0,zshift }, Vec3d{ xyScale , xyScale, zscale_number}); } for (size_t i = 0; i < 5; i++) { + translate_from_rotation(i, Vec3d{ 10 * xyScale,0,zshift }); add_part(model.objects[objs_idx[i]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_flow" / "O.amf").string(), Vec3d{ 0,0,zscale/2.f + 0.5 }, Vec3d{xyScale , xyScale, layer_height / 0.2}); // base: 0.2mm height } + /// --- translate ---; - bool has_to_arrange = false; + bool has_to_arrange = init_z_rotate_angle != 0; const ConfigOptionFloat* extruder_clearance_radius = print_config->option("extruder_clearance_radius"); const ConfigOptionPoints* bed_shape = printerConfig->option("bed_shape"); const double brim_width = nozzle_diameter * 3.5; diff --git a/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp b/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp index 847edbf5e55..4ad8cf4818a 100644 --- a/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp +++ b/src/slic3r/GUI/CalibrationOverBridgeDialog.cpp @@ -79,6 +79,16 @@ void CalibrationOverBridgeDialog::create_geometry(bool over_bridge) { } for (size_t i = 0; i < 6; i++) model.objects[objs_idx[i]]->scale(xyz_scale * 1.5f, xyz_scale * 1.5f, xyz_scale); + + // it's rotated but not around the good origin: correct that + double init_z_rotate_angle = Geometry::deg2rad(plat->config()->opt_float("init_z_rotate")); + Matrix3d rot_matrix = Eigen::Quaterniond(Eigen::AngleAxisd(init_z_rotate_angle, Vec3d{0,0,1})).toRotationMatrix(); + auto translate_from_rotation = [&rot_matrix, &model, &objs_idx](int idx, Vec3d &&translation) { + ModelVolume *vol = model.objects[objs_idx[idx]]->volumes[model.objects[objs_idx[idx]]->volumes.size()-1]; + Geometry::Transformation trsf = vol->get_transformation(); + trsf.set_offset(rot_matrix * translation - translation + trsf.get_offset()); + vol->set_transformation(trsf); + }; //add sub-part after scale const ConfigOptionFloatOrPercent* first_layer_height = print_config->option("first_layer_height"); @@ -86,11 +96,12 @@ void CalibrationOverBridgeDialog::create_geometry(bool over_bridge) { float zshift = 0.8 * (1 - xyz_scale); for (size_t i = 0; i < 6; i++) { model.objects[objs_idx[i]]->rotate(PI / 2, { 0,0,1 }); - ModelObject* obj = add_part(model.objects[objs_idx[i]], (boost::filesystem::path(Slic3r::resources_dir()) /"calibration" / "bridge_flow" / ("f"+std::to_string(100 + i * 5)+".amf")).string(), Vec3d{ 0, 10 * xyz_scale ,zshift }, Vec3d{ 1, 1, patch_zscale }); + add_part(model.objects[objs_idx[i]], (boost::filesystem::path(Slic3r::resources_dir()) /"calibration" / "bridge_flow" / ("f"+std::to_string(100 + i * 5)+".amf")).string(), Vec3d{ 0, 10 * xyz_scale ,zshift }, Vec3d{ 1, 1, patch_zscale }); + translate_from_rotation(i, Vec3d{ 0, 10 * xyz_scale ,zshift }); } /// --- translate ---; - bool has_to_arrange = false; + bool has_to_arrange = init_z_rotate_angle != 0; const ConfigOptionFloat* extruder_clearance_radius = print_config->option("extruder_clearance_radius"); const ConfigOptionPoints* bed_shape = printer_config->option("bed_shape"); const float brim_width = print_config->option("brim_width")->get_float(); diff --git a/src/slic3r/GUI/CalibrationRetractionDialog.cpp b/src/slic3r/GUI/CalibrationRetractionDialog.cpp index edd3b598b37..e276e8d08e3 100644 --- a/src/slic3r/GUI/CalibrationRetractionDialog.cpp +++ b/src/slic3r/GUI/CalibrationRetractionDialog.cpp @@ -176,27 +176,28 @@ void CalibrationRetractionDialog::create_geometry(wxCommandEvent& event_args) { //add sub-part after scale float zscale_number = (first_layer_height + layer_height) / 0.4; - std::vector < std::vector> part_tower; std::vector filament_temp_item_name; for (size_t id_item = 0; id_item < nb_items; id_item++) { - part_tower.emplace_back(); int mytemp = temp - temp_decr * id_item; if (mytemp <= 285 && mytemp >= 180 && mytemp % 5 == 0) { filament_temp_item_name.push_back("t" + std::to_string(mytemp) + ".amf"); + assert(model.objects[objs_idx[id_item]]->volumes.size() == 1); add_part(model.objects[objs_idx[id_item]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_temp" / filament_temp_item_name.back()).string(), Vec3d{ 0,0, scale * 0.0 - 4.8 }, Vec3d{ scale,scale,scale }); + assert(model.objects[objs_idx[id_item]]->volumes.size() == 2); model.objects[objs_idx[id_item]]->volumes[1]->rotate(PI / 2, Vec3d(0, 0, 1)); model.objects[objs_idx[id_item]]->volumes[1]->rotate(-PI / 2, Vec3d(1, 0, 0)); + //model.objects[objs_idx[id_item]]->volumes[1]->rotate(Geometry::deg2rad(plat->config()->opt_float("init_z_rotate")), Axis::Z); } for (int num_retract = 0; num_retract < nb_retract; num_retract++) { - part_tower.back().push_back(add_part(model.objects[objs_idx[id_item]], + add_part(model.objects[objs_idx[id_item]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "retraction" / "retraction_calibration_pillar.amf").string(), - Vec3d{ 0,0,scale * 0.7 - 0.3 + scale * num_retract }, Vec3d{ scale,scale,scale })); + Vec3d{ 0,0,scale * 0.7 - 0.3 + scale * num_retract }, Vec3d{ scale,scale,scale }); } } /// --- translate ---; - bool has_to_arrange = false; + bool has_to_arrange = plat->config()->opt_float("init_z_rotate").value != 0; const ConfigOptionFloat* extruder_clearance_radius = print_config->option("extruder_clearance_radius"); const ConfigOptionPoints* bed_shape = printer_config->option("bed_shape"); const float brim_width = std::max(print_config->option("brim_width")->value, nozzle_diameter * 5.); @@ -214,41 +215,42 @@ void CalibrationRetractionDialog::create_geometry(wxCommandEvent& event_args) { assert(filament_temp_item_name.size() == nb_items); assert(model.objects.size() == nb_items); for (size_t i = 0; i < nb_items; i++) { + ModelObject *current_obj = model.objects[objs_idx[i]]; //speed double perimeter_speed = full_print_config.get_computed_value("perimeter_speed"); double external_perimeter_speed = full_print_config.get_computed_value("external_perimeter_speed"); //brim to have some time to build up pressure in the nozzle - model.objects[objs_idx[i]]->config.set_key_value("brim_width", new ConfigOptionFloat(0)); - model.objects[objs_idx[i]]->config.set_key_value("perimeters", new ConfigOptionInt(2)); - model.objects[objs_idx[i]]->config.set_key_value("external_perimeters_first", new ConfigOptionBool(false)); - model.objects[objs_idx[i]]->config.set_key_value("bottom_solid_layers", new ConfigOptionInt(0)); - for(auto& volume : model.objects[objs_idx[i]]->volumes) + current_obj->config.set_key_value("brim_width", new ConfigOptionFloat(0)); + current_obj->config.set_key_value("perimeters", new ConfigOptionInt(2)); + current_obj->config.set_key_value("external_perimeters_first", new ConfigOptionBool(false)); + current_obj->config.set_key_value("bottom_solid_layers", new ConfigOptionInt(0)); + for(auto& volume : current_obj->volumes) if( volume->name == filament_temp_item_name[i] || volume->name.empty()) // if temperature patch or the main retraction patch (empty name because it's the initial volume) volume->config.set_key_value("bottom_solid_layers", new ConfigOptionInt(2)); - model.objects[objs_idx[i]]->config.set_key_value("top_solid_layers", new ConfigOptionInt(0)); - model.objects[objs_idx[i]]->config.set_key_value("fill_density", new ConfigOptionPercent(0)); - //model.objects[objs_idx[i]]->config.set_key_value("fill_pattern", new ConfigOptionEnum(ipRectilinear)); - model.objects[objs_idx[i]]->config.set_key_value("only_one_perimeter_top", new ConfigOptionBool(false)); - model.objects[objs_idx[i]]->config.set_key_value("overhangs_width_speed", new ConfigOptionFloatOrPercent(0,false)); - model.objects[objs_idx[i]]->config.set_key_value("thin_walls", new ConfigOptionBool(true)); - model.objects[objs_idx[i]]->config.set_key_value("thin_walls_min_width", new ConfigOptionFloatOrPercent(2,true)); - model.objects[objs_idx[i]]->config.set_key_value("gap_fill_enabled", new ConfigOptionBool(false)); - model.objects[objs_idx[i]]->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(nozzle_diameter / 2., false)); - model.objects[objs_idx[i]]->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter / 2.)); + current_obj->config.set_key_value("top_solid_layers", new ConfigOptionInt(0)); + current_obj->config.set_key_value("fill_density", new ConfigOptionPercent(0)); + //current_obj->config.set_key_value("fill_pattern", new ConfigOptionEnum(ipRectilinear)); + current_obj->config.set_key_value("only_one_perimeter_top", new ConfigOptionBool(false)); + current_obj->config.set_key_value("overhangs_width_speed", new ConfigOptionFloatOrPercent(0,false)); + current_obj->config.set_key_value("thin_walls", new ConfigOptionBool(true)); + current_obj->config.set_key_value("thin_walls_min_width", new ConfigOptionFloatOrPercent(2,true)); + current_obj->config.set_key_value("gap_fill_enabled", new ConfigOptionBool(false)); + current_obj->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(nozzle_diameter / 2., false)); + current_obj->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter / 2.)); //temp - model.objects[objs_idx[i]]->config.set_key_value("print_temperature", new ConfigOptionInt(int(temp - temp_decr * i))); + current_obj->config.set_key_value("print_temperature", new ConfigOptionInt(int(temp - temp_decr * i))); //set retraction override - size_t num_part = 0; + const int mytemp = temp - temp_decr * i; const int extra_vol = (mytemp <= 285 && mytemp >= 180 && mytemp % 5 == 0) ? 2 : 1; - for (ModelObject* part : part_tower[i]) { - model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("print_retract_length", new ConfigOptionFloat(retraction_start + num_part * retraction_steps)); - model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false)); - model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("perimeter_speed", new ConfigOptionFloatOrPercent(std::min(external_perimeter_speed, perimeter_speed), false)); - model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("external_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false)); - //model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false)); - //model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("infill_speed", new ConfigOptionFloatOrPercent(std::min(print_config->option("infill_speed")->value, 10.*scale)), false); - num_part++; + for (size_t num_part = extra_vol; num_part < current_obj->volumes.size(); num_part++) { + current_obj->volumes[num_part]->config.set_key_value("print_retract_length", new ConfigOptionFloat(retraction_start + num_part * retraction_steps)); + current_obj->volumes[num_part]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false)); + current_obj->volumes[num_part]->config.set_key_value("perimeter_speed", new ConfigOptionFloatOrPercent(std::min(external_perimeter_speed, perimeter_speed), false)); + current_obj->volumes[num_part]->config.set_key_value("external_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false)); + //current_obj->volumes[num_part + extra_vol]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false)); + //current_obj->volumes[num_part + extra_vol]->config.set_key_value("infill_speed", new ConfigOptionFloatOrPercent(std::min(print_config->option("infill_speed")->value, 10.*scale)), false); + } } diff --git a/src/slic3r/GUI/CalibrationTempDialog.cpp b/src/slic3r/GUI/CalibrationTempDialog.cpp index 4ccb00a5116..7ca7edfaf74 100644 --- a/src/slic3r/GUI/CalibrationTempDialog.cpp +++ b/src/slic3r/GUI/CalibrationTempDialog.cpp @@ -104,21 +104,19 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) { } //add 8 others - std::vectortower; - tower.push_back(model.objects[objs_idx[0]]); float zshift = (1 - xyzScale) / 2; if (temperature > 175 && temperature < 290 && temperature%5==0) { - tower.push_back(add_part(model.objects[objs_idx[0]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_temp" / ("t"+std::to_string(temperature)+".amf")).string(), + add_part(model.objects[objs_idx[0]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_temp" / ("t"+std::to_string(temperature)+".amf")).string(), //Vec3d{ xyzScale * 5, - xyzScale * 2.5, zshift - xyzScale * 2.5}, Vec3d{ xyzScale, xyzScale, xyzScale * 0.43 })); - Vec3d{ 8 - xyzScale * 5, -xyzScale * 2.3, xyzScale * (0 * 10 - 2.45) }, Vec3d{ xyzScale, xyzScale, xyzScale * 0.43 })); + Vec3d{ 8 - xyzScale * 5, -xyzScale * 2.3, xyzScale * (0 * 10 - 2.45) }, Vec3d{ xyzScale, xyzScale, xyzScale * 0.43 }); } for (int16_t i = 1; i < nb_items; i++) { - tower.push_back(add_part(model.objects[objs_idx[0]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_temp" / ("Smart_compact_temperature_calibration_item.amf")).string(), - Vec3d{ 0,0, i * 10 * xyzScale }, Vec3d{ xyzScale, xyzScale * 0.5, xyzScale })); + add_part(model.objects[objs_idx[0]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_temp" / ("Smart_compact_temperature_calibration_item.amf")).string(), + Vec3d{ 0,0, i * 10 * xyzScale }, Vec3d{ xyzScale, xyzScale * 0.5, xyzScale }); int sub_temp = temperature - i * step_temp; if (sub_temp > 175 && sub_temp < 290 && sub_temp % 5 == 0) { - tower.push_back(add_part(model.objects[objs_idx[0]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_temp" / ("t" + std::to_string(sub_temp) + ".amf")).string(), - Vec3d{ 8 - xyzScale * 5, -xyzScale * 2.3, xyzScale * (i * 10 - 2.5) }, Vec3d{ xyzScale, xyzScale, xyzScale * 0.43 })); + add_part(model.objects[objs_idx[0]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_temp" / ("t" + std::to_string(sub_temp) + ".amf")).string(), + Vec3d{ 8 - xyzScale * 5, -xyzScale * 2.3, xyzScale * (i * 10 - 2.5) }, Vec3d{ xyzScale, xyzScale, xyzScale * 0.43 }); } }