mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -06:00
pa calib: batch mode for pa pattern (#7199)
* pa calib: batch mode option
This commit is contained in:
parent
538db07127
commit
ecc16bfabf
13 changed files with 299 additions and 106 deletions
|
@ -9468,12 +9468,10 @@ void Plater::calib_pa(const Calib_Params& params)
|
|||
|
||||
void Plater::_calib_pa_pattern(const Calib_Params& params)
|
||||
{
|
||||
// add "handle" cube
|
||||
sidebar().obj_list()->load_generic_subobject("Cube", ModelVolumeType::INVALID);
|
||||
orient();
|
||||
changed_objects({ 0 });
|
||||
_calib_pa_select_added_objects();
|
||||
|
||||
std::vector<double> speeds{params.speeds};
|
||||
std::vector<double> accels{params.accelerations};
|
||||
std::vector<size_t> object_idxs{};
|
||||
/* Set common parameters */
|
||||
DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
|
||||
|
@ -9491,17 +9489,18 @@ void Plater::_calib_pa_pattern(const Calib_Params& params)
|
|||
accel = print_config.option<ConfigOptionFloat>("default_acceleration")->value;
|
||||
// Orca: Set all accelerations except first layer, as the first layer accel doesnt affect the PA test since accel
|
||||
// is set to the travel accel before printing the pattern.
|
||||
print_config.set_key_value( "default_acceleration", new ConfigOptionFloat(accel));
|
||||
if (accels.empty()) {
|
||||
accels.assign({accel});
|
||||
const auto msg{_L("INFO:") + "\n" +
|
||||
_L("No accelerations provided for calibration. Use default acceleration value ") + std::to_string(long(accel)) + _L("mm/s²")};
|
||||
get_notification_manager()->push_notification(msg.ToStdString());
|
||||
} else {
|
||||
// set max acceleration in case of batch mode to get correct test pattern size
|
||||
accel = *std::max_element(accels.begin(), accels.end());
|
||||
}
|
||||
print_config.set_key_value( "outer_wall_acceleration", new ConfigOptionFloat(accel));
|
||||
print_config.set_key_value( "inner_wall_acceleration", new ConfigOptionFloat(accel));
|
||||
print_config.set_key_value( "bridge_acceleration", new ConfigOptionFloatOrPercent(accel, false));
|
||||
print_config.set_key_value( "sparse_infill_acceleration", new ConfigOptionFloatOrPercent(accel, false));
|
||||
print_config.set_key_value( "internal_solid_infill_acceleration", new ConfigOptionFloatOrPercent(accel, false));
|
||||
print_config.set_key_value( "top_surface_acceleration", new ConfigOptionFloat(accel));
|
||||
print_config.set_key_value( "travel_acceleration", new ConfigOptionFloat(accel));
|
||||
print_config.set_key_value( "print_sequence", new ConfigOptionEnum(PrintSequence::ByLayer));
|
||||
|
||||
|
||||
//Orca: find jerk value to use in the test
|
||||
if(print_config.option<ConfigOptionFloat>("default_jerk")->value > 0){ // we have set a jerk value
|
||||
auto jerk = print_config.option<ConfigOptionFloat>("outer_wall_jerk")->value; // get outer wall jerk
|
||||
|
@ -9547,12 +9546,24 @@ void Plater::_calib_pa_pattern(const Calib_Params& params)
|
|||
);
|
||||
|
||||
// Orca: Set the outer wall speed to the optimal speed for the test, cap it with max volumetric speed
|
||||
print_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(CalibPressureAdvance::find_optimal_PA_speed(
|
||||
wxGetApp().preset_bundle->full_config(),
|
||||
(fabs(print_config.get_abs_value("line_width", nozzle_diameter)) <= DBL_EPSILON) ?
|
||||
(nozzle_diameter * 1.125) :
|
||||
print_config.get_abs_value("line_width", nozzle_diameter),
|
||||
print_config.get_abs_value("layer_height"), 0)));
|
||||
if (speeds.empty()) {
|
||||
double speed = CalibPressureAdvance::find_optimal_PA_speed(
|
||||
wxGetApp().preset_bundle->full_config(),
|
||||
(fabs(print_config.get_abs_value("line_width", nozzle_diameter)) <= DBL_EPSILON) ?
|
||||
(nozzle_diameter * 1.125) :
|
||||
print_config.get_abs_value("line_width", nozzle_diameter),
|
||||
print_config.get_abs_value("layer_height"), 0);
|
||||
print_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(speed));
|
||||
|
||||
speeds.assign({speed});
|
||||
const auto msg{_L("INFO:") + "\n" +
|
||||
_L("No speeds provided for calibration. Use default optimal speed ") + std::to_string(long(speed)) + _L("mm/s")};
|
||||
get_notification_manager()->push_notification(msg.ToStdString());
|
||||
} else if (speeds.size() == 1) {
|
||||
// If we have single value provided, set speed using global configuration.
|
||||
// per-object config is not set in this case
|
||||
print_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(speeds.front()));
|
||||
}
|
||||
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
|
||||
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
|
||||
|
@ -9564,54 +9575,133 @@ void Plater::_calib_pa_pattern(const Calib_Params& params)
|
|||
const DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config();
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
const bool is_bbl_machine = preset_bundle->is_bbl_vendor();
|
||||
const Vec3d plate_origin = get_partplate_list().get_current_plate_origin();
|
||||
auto cur_plate = get_partplate_list().get_plate(0);
|
||||
|
||||
// add "handle" cube
|
||||
sidebar().obj_list()->load_generic_subobject("Cube", ModelVolumeType::INVALID);
|
||||
auto *cube = model().objects[0];
|
||||
|
||||
CalibPressureAdvancePattern pa_pattern(
|
||||
params,
|
||||
full_config,
|
||||
is_bbl_machine,
|
||||
model(),
|
||||
plate_origin
|
||||
*cube,
|
||||
cur_plate->get_origin()
|
||||
);
|
||||
|
||||
// scale cube to suit test
|
||||
GizmoObjectManipulation& giz_obj_manip = p->view3D->get_canvas3d()->
|
||||
get_gizmos_manager().get_object_manipulation();
|
||||
giz_obj_manip.set_uniform_scaling(true);
|
||||
giz_obj_manip.on_change(
|
||||
"size",
|
||||
0,
|
||||
pa_pattern.handle_xy_size()
|
||||
);
|
||||
giz_obj_manip.set_uniform_scaling(false);
|
||||
giz_obj_manip.on_change(
|
||||
"size",
|
||||
2,
|
||||
pa_pattern.max_layer_z()
|
||||
);
|
||||
// start with pattern centered on plate
|
||||
center_selection();
|
||||
const Vec3d plate_center = get_partplate_list().get_curr_plate()->get_center_origin();
|
||||
giz_obj_manip.on_change(
|
||||
"position",
|
||||
0,
|
||||
plate_center.x() - (pa_pattern.print_size_x() / 2)
|
||||
);
|
||||
giz_obj_manip.on_change(
|
||||
"position",
|
||||
1,
|
||||
plate_center.y() -
|
||||
(pa_pattern.print_size_y() / 2) -
|
||||
pa_pattern.handle_spacing()
|
||||
);
|
||||
/* Having PA pattern configured, we could make a set of polygons resembling N test patterns.
|
||||
* We'll arrange this set of polygons, so we would know position of each test pattern and
|
||||
* could position test cubes later on
|
||||
*
|
||||
* We'll take advantage of already existing cube: scale it up to test pattern size to use
|
||||
* as a reference for objects arrangement. Polygon is slightly oversized to add spaces between patterns.
|
||||
* That arrangement will be used to place 'handle cubes' for each test. */
|
||||
auto cube_bb = cube->raw_bounding_box();
|
||||
cube->scale((pa_pattern.print_size_x() + 4) / cube_bb.size().x(),
|
||||
(pa_pattern.print_size_y() + 4) / cube_bb.size().y(),
|
||||
pa_pattern.max_layer_z() / cube_bb.size().z());
|
||||
|
||||
arrangement::ArrangePolygons arranged_items;
|
||||
{
|
||||
arrangement::ArrangeParams ap;
|
||||
Points bedpts = arrangement::get_shrink_bedpts(&full_config, ap);
|
||||
|
||||
for(size_t i = 0; i < speeds.size() * accels.size(); i++) {
|
||||
arrangement::ArrangePolygon p;
|
||||
cube->instances[0]->get_arrange_polygon(&p);
|
||||
p.bed_idx = 0;
|
||||
arranged_items.emplace_back(p);
|
||||
}
|
||||
|
||||
arrangement::arrange(arranged_items, bedpts, ap);
|
||||
}
|
||||
|
||||
/* scale cube back to the size of test pattern 'handle' */
|
||||
cube_bb = cube->raw_bounding_box();
|
||||
cube->scale(pa_pattern.handle_xy_size() / cube_bb.size().x(),
|
||||
pa_pattern.handle_xy_size() / cube_bb.size().y(),
|
||||
pa_pattern.max_layer_z() / cube_bb.size().z());
|
||||
|
||||
/* Set speed and acceleration on per-object basis and arrange anchor object on the plates.
|
||||
* Test gcode will be genecated during plate slicing */
|
||||
for(size_t test_idx = 0; test_idx < arranged_items.size(); test_idx++) {
|
||||
const auto &ai = arranged_items[test_idx];
|
||||
size_t plate_idx = arranged_items[test_idx].bed_idx;
|
||||
auto tspd = speeds[test_idx % speeds.size()];
|
||||
auto tacc = accels[test_idx / speeds.size()];
|
||||
|
||||
/* make an own copy of anchor cube for each test */
|
||||
auto obj = test_idx == 0 ? cube : model().add_object(*cube);
|
||||
auto obj_idx = std::distance(model().objects.begin(), std::find(model().objects.begin(), model().objects.end(), obj));
|
||||
obj->name.assign(std::string("pa_pattern_") + std::to_string(int(tspd)) + std::string("_") + std::to_string(int(tacc)));
|
||||
|
||||
auto &obj_config = obj->config;
|
||||
if (speeds.size() > 1)
|
||||
obj_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(tspd));
|
||||
if (accels.size() > 1)
|
||||
obj_config.set_key_value("outer_wall_acceleration", new ConfigOptionFloat(tacc));
|
||||
|
||||
auto cur_plate = get_partplate_list().get_plate(plate_idx);
|
||||
if (!cur_plate) {
|
||||
plate_idx = get_partplate_list().create_plate();
|
||||
cur_plate = get_partplate_list().get_plate(plate_idx);
|
||||
}
|
||||
|
||||
object_idxs.emplace_back(obj_idx);
|
||||
get_partplate_list().add_to_plate(obj_idx, 0, plate_idx);
|
||||
const Vec3d obj_offset{unscale<double>(ai.translation(X)),
|
||||
unscale<double>(ai.translation(Y)),
|
||||
0};
|
||||
obj->instances[0]->set_offset(cur_plate->get_origin() + obj_offset + pa_pattern.handle_pos_offset());
|
||||
obj->ensure_on_bed();
|
||||
|
||||
if (obj_idx == 0)
|
||||
sidebar().obj_list()->update_name_for_items();
|
||||
else
|
||||
sidebar().obj_list()->add_object_to_list(obj_idx);
|
||||
}
|
||||
|
||||
pa_pattern.generate_custom_gcodes(
|
||||
full_config,
|
||||
is_bbl_machine,
|
||||
model(),
|
||||
plate_origin
|
||||
);
|
||||
model().calib_pa_pattern = std::make_unique<CalibPressureAdvancePattern>(pa_pattern);
|
||||
changed_objects({ 0 });
|
||||
changed_objects(object_idxs);
|
||||
}
|
||||
|
||||
void Plater::_calib_pa_pattern_gen_gcode()
|
||||
{
|
||||
if (!model().calib_pa_pattern)
|
||||
return;
|
||||
|
||||
auto cur_plate = get_partplate_list().get_curr_plate();
|
||||
if (cur_plate->empty())
|
||||
return;
|
||||
|
||||
/* Container to store custom g-codes genereted by the test generator.
|
||||
* We'll store gcode for all tests on a single plate here. Once the plate handling is done,
|
||||
* all the g-codes will be merged into a single one on per-layer basis */
|
||||
std::vector<CustomGCode::Info> mgc;
|
||||
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
|
||||
|
||||
/* iterate over all cubes on current plate and generate gcode for them */
|
||||
for (auto obj : cur_plate->get_objects_on_this_plate()) {
|
||||
auto gcode = model().calib_pa_pattern->generate_custom_gcodes(
|
||||
preset_bundle->full_config(),
|
||||
preset_bundle->is_bbl_vendor(),
|
||||
*obj,
|
||||
cur_plate->get_origin()
|
||||
);
|
||||
mgc.emplace_back(gcode);
|
||||
}
|
||||
|
||||
// move first item into model custom gcode
|
||||
auto &pcgc = model().plates_custom_gcodes[get_partplate_list().get_curr_plate_index()];
|
||||
pcgc = std::move(mgc[0]);
|
||||
mgc.erase(mgc.begin());
|
||||
|
||||
// concat layer gcodes for each test
|
||||
for (size_t i = 0; i < pcgc.gcodes.size(); i++) {
|
||||
for (auto &gc : mgc) {
|
||||
pcgc.gcodes[i].extra += gc.gcodes[i].extra;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Plater::cut_horizontal(size_t obj_idx, size_t instance_idx, double z, ModelObjectCutAttributes attributes)
|
||||
|
@ -12385,14 +12475,7 @@ void Plater::reslice()
|
|||
|
||||
// Orca: regenerate CalibPressureAdvancePattern custom G-code to apply changes
|
||||
if (model().calib_pa_pattern) {
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
|
||||
model().calib_pa_pattern->generate_custom_gcodes(
|
||||
wxGetApp().preset_bundle->full_config(),
|
||||
preset_bundle->is_bbl_vendor(),
|
||||
model(),
|
||||
get_partplate_list().get_current_plate_origin()
|
||||
);
|
||||
_calib_pa_pattern_gen_gcode();
|
||||
}
|
||||
|
||||
if (printer_technology() == ptSLA) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue