mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-19 13:41:03 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
252bbbf9f5 | ||
|
|
4c2ae6d202 |
No files matched your search
@@ -15648,6 +15648,12 @@ msgstr ""
|
||||
msgid "Enable this option to add EXCLUDE OBJECT command in G-code."
|
||||
msgstr ""
|
||||
|
||||
msgid "Outline tolerance"
|
||||
msgstr ""
|
||||
|
||||
msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point."
|
||||
msgstr ""
|
||||
|
||||
msgid "Verbose G-code"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -988,7 +988,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
|
||||
MetadataList metadata;
|
||||
VolumeMetadataList volumes;
|
||||
bool auto_drop { true };
|
||||
std::optional<bool> auto_drop;
|
||||
};
|
||||
|
||||
struct CutObjectInfo
|
||||
@@ -1208,6 +1208,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
//IdToGeometryMap m_orig_geometries; // backup & restore
|
||||
CurrentConfig m_curr_config;
|
||||
IdToMetadataMap m_objects_metadata;
|
||||
std::set<int> m_items_auto_drop_off; // object ids with a build item auto_drop="0" (2.4.x layout)
|
||||
IdToCutObjectInfoMap m_cut_object_infos;
|
||||
IdToLayerHeightsProfileMap m_layer_heights_profiles;
|
||||
IdToLayerConfigRangesMap m_layer_config_ranges;
|
||||
@@ -1463,6 +1464,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
m_objects.clear();
|
||||
m_instances.clear();
|
||||
m_objects_metadata.clear();
|
||||
m_items_auto_drop_off.clear();
|
||||
m_curr_metadata_name.clear();
|
||||
m_curr_characters.clear();
|
||||
|
||||
@@ -1502,6 +1504,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
m_curr_config.object_id = -1;
|
||||
m_curr_config.volume_id = -1;
|
||||
m_objects_metadata.clear();
|
||||
m_items_auto_drop_off.clear();
|
||||
m_layer_heights_profiles.clear();
|
||||
m_layer_config_ranges.clear();
|
||||
m_brim_ear_points.clear();
|
||||
@@ -2257,11 +2260,14 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
ObjectMetadata::VolumeMetadataList volumes;
|
||||
ObjectMetadata::VolumeMetadataList* volumes_ptr = nullptr;
|
||||
|
||||
// 2.4.x stored auto_drop on build items, shared by all instances of an object; any "off" wins
|
||||
const bool legacy_auto_drop = !m_items_auto_drop_off.count(object.first.second);
|
||||
|
||||
IdToMetadataMap::iterator obj_metadata = m_objects_metadata.find(object.first.second);
|
||||
if (obj_metadata != m_objects_metadata.end()) {
|
||||
// config data has been found, this model was saved using slic3r pe
|
||||
|
||||
model_object->auto_drop = obj_metadata->second.auto_drop;
|
||||
model_object->auto_drop = obj_metadata->second.auto_drop.value_or(legacy_auto_drop);
|
||||
|
||||
// apply object's name and config data
|
||||
for (const Metadata& metadata : obj_metadata->second.metadata) {
|
||||
@@ -2279,6 +2285,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
}
|
||||
else {
|
||||
// config data not found, this model was not saved using slic3r pe
|
||||
model_object->auto_drop = legacy_auto_drop;
|
||||
|
||||
// add the entire geometry as the single volume to generate
|
||||
//volumes.emplace_back(0, (int)obj_geometry->second.triangles.size() - 1);
|
||||
@@ -4121,6 +4128,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
std::string path = bbs_get_attribute_value_string(attributes, num_attributes, PPATH_ATTR);
|
||||
Transform3d transform = bbs_get_transform_from_3mf_specs_string(bbs_get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
|
||||
int printable = bbs_get_attribute_value_bool(attributes, num_attributes, PRINTABLE_ATTR);
|
||||
if (const char* auto_drop = bbs_get_attribute_value_charptr(attributes, num_attributes, AUTO_DROP_ATTR); auto_drop != nullptr && !::atoi(auto_drop))
|
||||
m_items_auto_drop_off.insert(object_id);
|
||||
return !m_load_model || _create_object_instance(path, object_id, transform, printable, 1);
|
||||
}
|
||||
|
||||
@@ -4489,7 +4498,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
// int instances_count_id = bbs_get_attribute_value_int(attributes, num_attributes, INSTANCESCOUNT_ATTR);
|
||||
|
||||
ObjectMetadata metadata;
|
||||
metadata.auto_drop = bbs_get_attribute_value_bool(attributes, num_attributes, AUTO_DROP_ATTR);
|
||||
if (bbs_get_attribute_value_charptr(attributes, num_attributes, AUTO_DROP_ATTR) != nullptr)
|
||||
metadata.auto_drop = bbs_get_attribute_value_bool(attributes, num_attributes, AUTO_DROP_ATTR);
|
||||
m_objects_metadata.insert({ object_id, std::move(metadata) });
|
||||
m_curr_config.object_id = object_id;
|
||||
return true;
|
||||
|
||||
@@ -1421,6 +1421,7 @@ static std::vector<std::string> s_Preset_print_options{
|
||||
"initial_layer_travel_acceleration",
|
||||
"initial_layer_travel_jerk",
|
||||
"exclude_object",
|
||||
"exclude_object_tolerance",
|
||||
"slow_down_layers",
|
||||
"infill_anchor",
|
||||
"infill_anchor_max",
|
||||
|
||||
@@ -309,6 +309,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
"gcode_comments",
|
||||
"gcode_label_objects",
|
||||
"exclude_object",
|
||||
"exclude_object_tolerance",
|
||||
"support_material_interface_fan_speed",
|
||||
"internal_bridge_fan_speed", // ORCA: Add support for separate internal bridge fan speed control
|
||||
"ironing_fan_speed",
|
||||
@@ -6929,7 +6930,7 @@ BoundingBoxf3 PrintInstance::get_bounding_box() const {
|
||||
|
||||
Polygon PrintInstance::get_convex_hull_2d() {
|
||||
Polygon poly = print_object->model_object()->convex_hull_2d(model_instance->get_matrix());
|
||||
poly.douglas_peucker(scale_(0.1));
|
||||
poly.douglas_peucker(scale_(print_object->print()->config().exclude_object_tolerance.value));
|
||||
return poly;
|
||||
}
|
||||
|
||||
|
||||
@@ -4629,6 +4629,17 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("exclude_object_tolerance", coFloat);
|
||||
def->label = L("Outline tolerance");
|
||||
def->tooltip = L("Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the "
|
||||
"original outline. Larger values give fewer points, which helps firmware that stalls "
|
||||
"while parsing G-code with many objects. 0 keeps every point.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->max = 5;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0.1));
|
||||
|
||||
def = this->add("gcode_comments", coBool);
|
||||
def->label = L("Verbose G-code");
|
||||
def->tooltip = L("Enable this to get a commented G-code file, with each line explained by a descriptive text. "
|
||||
|
||||
@@ -2130,6 +2130,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionPercents, filament_shrinkage_compensation_z))
|
||||
((ConfigOptionBool, gcode_label_objects))
|
||||
((ConfigOptionBool, exclude_object))
|
||||
((ConfigOptionFloat, exclude_object_tolerance))
|
||||
((ConfigOptionFloats, grab_length))
|
||||
((ConfigOptionBool, gcode_comments))
|
||||
((ConfigOptionInt, slow_down_layers))
|
||||
|
||||
@@ -435,7 +435,7 @@ void CalibrationWizard::cache_preset_info(MachineObject *obj, float nozzle_dia,
|
||||
if (obj->is_multi_extruders()) {
|
||||
int ams_id, slot_id, tray_id;
|
||||
get_tray_ams_and_slot_id(curr_obj, result.tray_id, ams_id, slot_id, tray_id);
|
||||
result.extruder_id = preset_page->get_extruder_id_by_tray_id(result.tray_id);
|
||||
result.extruder_id = preset_page->get_extruder_id(ams_id);
|
||||
result.nozzle_diameter = preset_page->get_nozzle_diameter(result.extruder_id);
|
||||
}
|
||||
else {
|
||||
@@ -753,7 +753,7 @@ void PressureAdvanceWizard::on_cali_start()
|
||||
|
||||
X1CCalibInfos::X1CCalibInfo calib_info;
|
||||
get_tray_ams_and_slot_id(curr_obj, item.first, calib_info.ams_id, calib_info.slot_id, calib_info.tray_id);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id_by_tray_id(item.first);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id(calib_info.ams_id);
|
||||
calib_info.extruder_type = preset_page->get_extruder_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_volume_type = preset_page->get_nozzle_volume_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_diameter = preset_page->get_nozzle_diameter(calib_info.extruder_id);
|
||||
@@ -792,7 +792,7 @@ void PressureAdvanceWizard::on_cali_start()
|
||||
CalibInfo calib_info;
|
||||
calib_info.dev_id = curr_obj->get_dev_id();
|
||||
get_tray_ams_and_slot_id(curr_obj, selected_filaments.begin()->first, calib_info.ams_id, calib_info.slot_id, selected_tray_id);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id_by_tray_id(selected_filaments.begin()->first);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id(calib_info.ams_id);
|
||||
calib_info.extruder_type = preset_page->get_extruder_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_volume_type = preset_page->get_nozzle_volume_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_diameter = preset_page->get_nozzle_diameter(calib_info.extruder_id);
|
||||
@@ -877,7 +877,7 @@ void PressureAdvanceWizard::on_cali_start()
|
||||
calib_info.dev_id = curr_obj->get_dev_id();
|
||||
get_tray_ams_and_slot_id(curr_obj, item.first, calib_info.ams_id, calib_info.slot_id, selected_tray_id);
|
||||
calib_info.index = preset_page->get_index_by_tray_id(item.first);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id_by_tray_id(item.first);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id(calib_info.ams_id);
|
||||
calib_info.nozzle_diameter = preset_page->get_nozzle_diameter(calib_info.extruder_id);
|
||||
calib_info.extruder_type = preset_page->get_extruder_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_volume_type = preset_page->get_nozzle_volume_type(calib_info.extruder_id);
|
||||
@@ -1252,7 +1252,7 @@ void FlowRateWizard::on_cali_start(CaliPresetStage stage, float cali_value, Flow
|
||||
X1CCalibInfos::X1CCalibInfo calib_info;
|
||||
calib_info.tray_id = item.first;
|
||||
get_tray_ams_and_slot_id(curr_obj, item.first, calib_info.ams_id, calib_info.slot_id, calib_info.tray_id);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id_by_tray_id(item.first);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id(calib_info.ams_id);
|
||||
calib_info.extruder_type = preset_page->get_extruder_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_volume_type = preset_page->get_nozzle_volume_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_diameter = preset_page->get_nozzle_diameter(calib_info.extruder_id);
|
||||
@@ -1308,15 +1308,7 @@ void FlowRateWizard::on_cali_start(CaliPresetStage stage, float cali_value, Flow
|
||||
int selected_tray_id = 0;
|
||||
get_tray_ams_and_slot_id(curr_obj, selected_filaments.begin()->first, calib_info.ams_id, calib_info.slot_id, selected_tray_id);
|
||||
calib_info.select_ams = std::to_string(selected_tray_id);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id_by_tray_id(selected_filaments.begin()->first);
|
||||
if (from_page == FlowRatioCaliSource::FROM_COARSE_PAGE) {
|
||||
// The fine pass must run on the extruder the coarse pass used. The cache records it;
|
||||
// the preset page's selection may have changed or been reset since.
|
||||
const auto cached = get_cached_selected_filament_for_multi_extruder(curr_obj);
|
||||
const auto it = cached.find(selected_filaments.begin()->first);
|
||||
if (it != cached.end())
|
||||
calib_info.extruder_id = it->second.extruder_id;
|
||||
}
|
||||
calib_info.extruder_id = preset_page->get_extruder_id(calib_info.ams_id);
|
||||
calib_info.extruder_type = preset_page->get_extruder_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_volume_type = preset_page->get_nozzle_volume_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_diameter = preset_page->get_nozzle_diameter(calib_info.extruder_id);
|
||||
@@ -1732,7 +1724,7 @@ void MaxVolumetricSpeedWizard::on_cali_start()
|
||||
int selected_tray_id = 0;
|
||||
get_tray_ams_and_slot_id(curr_obj, selected_filaments.begin()->first, calib_info.ams_id, calib_info.slot_id, selected_tray_id);
|
||||
calib_info.select_ams = std::to_string(selected_tray_id);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id_by_tray_id(selected_filaments.begin()->first);
|
||||
calib_info.extruder_id = preset_page->get_extruder_id(calib_info.ams_id);
|
||||
calib_info.extruder_type = preset_page->get_extruder_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_volume_type = preset_page->get_nozzle_volume_type(calib_info.extruder_id);
|
||||
calib_info.nozzle_diameter = preset_page->get_nozzle_diameter(calib_info.extruder_id);
|
||||
|
||||
@@ -587,23 +587,8 @@ void CalibrationPresetPage::on_sys_color_changed()
|
||||
m_ams_sync_button->msw_rescale();
|
||||
}
|
||||
|
||||
int CalibrationPresetPage::get_extruder_id_by_tray_id(int tray_id)
|
||||
int CalibrationPresetPage::get_extruder_id(int ams_id)
|
||||
{
|
||||
// An AMS behind a Filament Track Switch feeds both extruders, so the extruder is the one
|
||||
// whose panel the filament was selected in.
|
||||
if (curr_obj && curr_obj->is_multi_extruders()) {
|
||||
for (FilamentComboBox *fcb : get_selected_filament_combobox()) {
|
||||
if (fcb->get_tray_id() != tray_id)
|
||||
continue;
|
||||
const bool is_deputy = std::find(m_deputy_filament_comboBox_list.begin(), m_deputy_filament_comboBox_list.end(), fcb) !=
|
||||
m_deputy_filament_comboBox_list.end();
|
||||
return is_deputy ? DEPUTY_EXTRUDER_ID : MAIN_EXTRUDER_ID;
|
||||
}
|
||||
}
|
||||
|
||||
int ams_id = tray_id / 4, slot_id, unused_tray_id;
|
||||
if (curr_obj)
|
||||
get_tray_ams_and_slot_id(curr_obj, tray_id, ams_id, slot_id, unused_tray_id);
|
||||
if (m_ams_id_to_extruder_id_map.find(ams_id) != m_ams_id_to_extruder_id_map.end()) {
|
||||
return m_ams_id_to_extruder_id_map[ams_id];
|
||||
}
|
||||
@@ -881,18 +866,6 @@ static void fill_nozzle_volume_combo(ComboBox *combo)
|
||||
select_nozzle_volume(combo, NozzleVolumeType::nvtStandard);
|
||||
}
|
||||
|
||||
static DynamicPrintConfig empty_tray_config()
|
||||
{
|
||||
DynamicPrintConfig config;
|
||||
config.set_key_value("filament_id", new ConfigOptionStrings{""});
|
||||
config.set_key_value("tag_uid", new ConfigOptionStrings{""});
|
||||
config.set_key_value("filament_type", new ConfigOptionStrings{""});
|
||||
config.set_key_value("tray_name", new ConfigOptionStrings{""});
|
||||
config.set_key_value("filament_colour", new ConfigOptionStrings{""});
|
||||
config.set_key_value("filament_exist", new ConfigOptionBools{false});
|
||||
return config;
|
||||
}
|
||||
|
||||
void CalibrationPresetPage::init_selection_values()
|
||||
{
|
||||
// init nozzle diameter and nozzle volume
|
||||
@@ -2299,36 +2272,27 @@ void CalibrationPresetPage::sync_ams_info(MachineObject* obj)
|
||||
}
|
||||
}
|
||||
|
||||
// init virtual tray info. With a Filament Track Switch installed the external spools feed
|
||||
// through the switch, so they can't be calibrated as their own trays.
|
||||
if (obj->GetFilaSwitch()->IsInstalled()) {
|
||||
filament_ams_list[VIRTUAL_TRAY_MAIN_ID] = empty_tray_config();
|
||||
filament_ams_list[VIRTUAL_TRAY_DEPUTY_ID] = empty_tray_config();
|
||||
} else {
|
||||
if (full_filament_ams_list.find(VIRTUAL_TRAY_MAIN_ID) != full_filament_ams_list.end()) {
|
||||
filament_ams_list[VIRTUAL_TRAY_MAIN_ID] = full_filament_ams_list[VIRTUAL_TRAY_MAIN_ID];
|
||||
}
|
||||
// init virtual tray info
|
||||
if (full_filament_ams_list.find(VIRTUAL_TRAY_MAIN_ID) != full_filament_ams_list.end()) {
|
||||
filament_ams_list[VIRTUAL_TRAY_MAIN_ID] = full_filament_ams_list[VIRTUAL_TRAY_MAIN_ID];
|
||||
}
|
||||
|
||||
if (full_filament_ams_list.find(VIRTUAL_TRAY_DEPUTY_ID) != full_filament_ams_list.end()) {
|
||||
filament_ams_list[VIRTUAL_TRAY_DEPUTY_ID] = full_filament_ams_list[VIRTUAL_TRAY_DEPUTY_ID];
|
||||
}
|
||||
if (full_filament_ams_list.find(VIRTUAL_TRAY_DEPUTY_ID) != full_filament_ams_list.end()) {
|
||||
filament_ams_list[VIRTUAL_TRAY_DEPUTY_ID] = full_filament_ams_list[VIRTUAL_TRAY_DEPUTY_ID];
|
||||
}
|
||||
|
||||
// update filament from panel, display only obj has ams
|
||||
// update multi ams panel, display only obj has multi ams
|
||||
if (obj->HasAms()) {
|
||||
if (obj->is_multi_extruders()) {
|
||||
// An AMS behind a Filament Track Switch is bound to both extruders and appears in both panels.
|
||||
bool main_done = false;
|
||||
bool deputy_done = false;
|
||||
for (auto &ams_item : obj->GetFilaSystem()->GetAmsList()) {
|
||||
const auto &extruder_set = ams_item.second->GetBindedExtruderSet();
|
||||
if (!main_done && extruder_set.count(MAIN_EXTRUDER_ID) != 0) {
|
||||
update_multi_extruder_filament_combobox(ams_item.second->GetAmsId(), MAIN_EXTRUDER_ID);
|
||||
if (ams_item.second->GetExtruderId() == 0 && !main_done) {
|
||||
update_multi_extruder_filament_combobox(ams_item.second->GetAmsId(), ams_item.second->GetExtruderId());
|
||||
main_done = true;
|
||||
}
|
||||
if (!deputy_done && extruder_set.count(DEPUTY_EXTRUDER_ID) != 0) {
|
||||
update_multi_extruder_filament_combobox(ams_item.second->GetAmsId(), DEPUTY_EXTRUDER_ID);
|
||||
} else if (ams_item.second->GetExtruderId() == 1 && !deputy_done) {
|
||||
update_multi_extruder_filament_combobox(ams_item.second->GetAmsId(), ams_item.second->GetExtruderId());
|
||||
deputy_done = true;
|
||||
}
|
||||
}
|
||||
@@ -2369,11 +2333,10 @@ void CalibrationPresetPage::sync_ams_info(MachineObject* obj)
|
||||
if (ams->second->IsExist()
|
||||
&& info.parse_ams_info(obj, ams->second, obj->GetFilaSystem()->IsDetectRemainEnabled(), obj->is_support_ams_humidity)) {
|
||||
ams_info.push_back(info);
|
||||
for (int extruder_id : ams->second->GetBindedExtruderSet()) {
|
||||
if (extruder_id == MAIN_EXTRUDER_ID)
|
||||
main_ams_info.push_back(info);
|
||||
else
|
||||
deputy_ams_info.push_back(info);
|
||||
if (info.nozzle_id == 0) {
|
||||
main_ams_info.push_back(info);
|
||||
} else {
|
||||
deputy_ams_info.push_back(info);
|
||||
}
|
||||
}
|
||||
m_ams_id_to_extruder_id_map[stoi(info.ams_id)] = info.nozzle_id;
|
||||
@@ -2621,7 +2584,13 @@ void CalibrationPresetPage::update_multi_extruder_filament_combobox(const std::s
|
||||
}
|
||||
}
|
||||
|
||||
DynamicPrintConfig empty_config = empty_tray_config();
|
||||
DynamicPrintConfig empty_config;
|
||||
empty_config.set_key_value("filament_id", new ConfigOptionStrings{""});
|
||||
empty_config.set_key_value("tag_uid", new ConfigOptionStrings{""});
|
||||
empty_config.set_key_value("filament_type", new ConfigOptionStrings{""});
|
||||
empty_config.set_key_value("tray_name", new ConfigOptionStrings{""});
|
||||
empty_config.set_key_value("filament_colour", new ConfigOptionStrings{""});
|
||||
empty_config.set_key_value("filament_exist", new ConfigOptionBools{false});
|
||||
|
||||
if (filament_ams_list.empty()) return;
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ public:
|
||||
void msw_rescale() override;
|
||||
void on_sys_color_changed() override;
|
||||
|
||||
int get_extruder_id_by_tray_id(int tray_id);
|
||||
int get_extruder_id(int ams_id);
|
||||
float get_nozzle_diameter(int extruder_id) const;
|
||||
NozzleVolumeType get_nozzle_volume_type(int extruder_id) const;
|
||||
ExtruderType get_extruder_type(int extruder_id) const;
|
||||
|
||||
@@ -1245,6 +1245,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in
|
||||
if(gcf_is_klipper)
|
||||
toggle_field("accel_to_decel_factor", config->opt_bool("accel_to_decel_enable"));
|
||||
|
||||
toggle_line("exclude_object_tolerance", gcf_is_klipper && config->opt_bool("exclude_object"));
|
||||
|
||||
bool have_make_overhang_printable = config->opt_bool("make_overhang_printable");
|
||||
toggle_line("make_overhang_printable_angle", have_make_overhang_printable);
|
||||
toggle_line("make_overhang_printable_hole_size", have_make_overhang_printable);
|
||||
|
||||
@@ -3269,6 +3269,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("gcode_comments", "others_settings_g_code_output#verbose-g-code");
|
||||
optgroup->append_single_option_line("gcode_label_objects", "others_settings_g_code_output#label-objects");
|
||||
optgroup->append_single_option_line("exclude_object", "others_settings_g_code_output#exclude-objects");
|
||||
optgroup->append_single_option_line("exclude_object_tolerance", "others_settings_g_code_output#outline-tolerance");
|
||||
option = optgroup->get_option("filename_format");
|
||||
// option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
|
||||
@@ -51,6 +51,44 @@ TEST_CASE("Klipper object labels name each copy without the characters Klipper c
|
||||
}
|
||||
}
|
||||
|
||||
// The outline written to EXCLUDE_OBJECT_DEFINE is simplified with exclude_object_tolerance. A larger value must
|
||||
// leave fewer points, which keeps the exclude-object array small on printers that stall while parsing it.
|
||||
TEST_CASE("A larger exclude object tolerance writes fewer outline points", "[GCode]")
|
||||
{
|
||||
const auto slice_with_tolerance = [](const std::string &tolerance) {
|
||||
DynamicPrintConfig config = DynamicPrintConfig::full_print_config();
|
||||
config.set_deserialize_strict({{"gcode_flavor", "klipper"}, {"exclude_object", "1"},
|
||||
{"exclude_object_tolerance", tolerance}});
|
||||
// Default facet angle (2 degrees): 180 hull points, well inside either tolerance.
|
||||
return Test::slice({make_cylinder(20., 5.)}, config);
|
||||
};
|
||||
// Points of the POLYGON=[[x,y],...] on the first EXCLUDE_OBJECT_DEFINE line.
|
||||
const auto polygon_points = [](const std::string &gcode) {
|
||||
const size_t define = gcode.find("EXCLUDE_OBJECT_DEFINE");
|
||||
REQUIRE(define != std::string::npos);
|
||||
const size_t begin = gcode.find("POLYGON=", define);
|
||||
REQUIRE(begin != std::string::npos);
|
||||
const std::string polygon = gcode.substr(begin, gcode.find('\n', begin) - begin);
|
||||
size_t points = 1;
|
||||
for (size_t pos = polygon.find("],["); pos != std::string::npos; pos = polygon.find("],[", pos + 1))
|
||||
++points;
|
||||
return points;
|
||||
};
|
||||
|
||||
const size_t fine = polygon_points(slice_with_tolerance("0.1"));
|
||||
const size_t coarse = polygon_points(slice_with_tolerance("0.4"));
|
||||
INFO("points at 0.1 mm: " << fine << ", at 0.4 mm: " << coarse);
|
||||
CHECK(coarse >= 4);
|
||||
CHECK(coarse < fine);
|
||||
}
|
||||
|
||||
// Existing profiles must keep writing the outlines they wrote when the tolerance was a constant 0.1 mm.
|
||||
TEST_CASE("The exclude object tolerance defaults to the former fixed 0.1 mm", "[GCode]")
|
||||
{
|
||||
CHECK_THAT(DynamicPrintConfig::full_print_config().opt_float("exclude_object_tolerance"),
|
||||
Catch::Matchers::WithinAbs(0.1, 1e-9));
|
||||
}
|
||||
|
||||
// Firmwares read the compatibility header lines (Anycubic's GoKlipper heats the bed with
|
||||
// first_layer_bed_temperature), so they must describe the filament the plate prints, not filament 1.
|
||||
TEST_CASE("The G-code header names the first layer temperatures of the filament the plate prints", "[GCode]")
|
||||
|
||||
@@ -505,6 +505,28 @@ TEST_CASE("A project whose components reference themselves fails to load", "[3mf
|
||||
REQUIRE_FALSE(loaded);
|
||||
}
|
||||
|
||||
TEST_CASE("A project in the 2.4.x layout keeps auto drop off from its build item", "[3mf][Regression]")
|
||||
{
|
||||
// 2.4.x wrote auto_drop on the build item and left it off the object, so the object is re-laid out here.
|
||||
ScopedTemporaryFile temp(".3mf");
|
||||
{
|
||||
Model model;
|
||||
ModelObject* object = model.add_object();
|
||||
object->add_volume(make_cube(10., 10., 10.));
|
||||
object->add_instance();
|
||||
object->auto_drop = false;
|
||||
store_project(model, temp.string(), SaveStrategy::Zip64 | SaveStrategy::Silence);
|
||||
}
|
||||
REQUIRE(replace_in_3mf_entry(temp.string(), "model_settings.config", " auto_drop=\"0\"", ""));
|
||||
REQUIRE(replace_in_3mf_entry(temp.string(), "3dmodel.model", "printable=\"1\"/>", "printable=\"1\" auto_drop=\"0\"/>"));
|
||||
|
||||
ScopedTemporaryDir backup_dir("orca_auto_drop_dst");
|
||||
Model model;
|
||||
REQUIRE(load_project(temp.string(), model, backup_dir));
|
||||
REQUIRE(model.objects.size() == 1);
|
||||
CHECK_FALSE(model.objects.front()->auto_drop);
|
||||
}
|
||||
|
||||
TEST_CASE("An object loads up to the component reference budget and fails past it", "[3mf][Regression]")
|
||||
{
|
||||
// The importer queues at most 100000 component references per object. Every reference besides the
|
||||
|
||||
Reference in new issue
Block a user