[Feature] Add a new feature that allow user to insert extra solid infills (#10611)

* refactor Infill rotation template

* clean up comments

* set default solid_infill_rotate_template to empty

* Fix an issue that infill_direction solid_infill_direction not working as expected

* Add Extra Solid Infill Feature
Introduced a new feature to insert extra solid infills at specific layers for enhanced strength in 3D prints.

* fix doc error

* fix image name

* support "#K" for Explicit Layer List

* update wiki
This commit is contained in:
SoftFever
2025-09-03 22:16:31 +08:00
committed by GitHub
parent 266bfeb9e2
commit 31869bfbd1
11 changed files with 175 additions and 18 deletions

View File

@@ -1566,4 +1566,91 @@ void load_string_file(const boost::filesystem::path& p, std::string& str)
file.read(&str[0], sz);
}
// pattern string supprt these pattern: "
// 1. 5#1, insert 1 solid layer every 5 layers. this can be simplified to 5
// 2."1,7,9", explicitly insert solid layer at layer 1, 7, 9
bool check_layer_id_pattern(const std::string& pattern, int layer_id){
if (pattern.empty() || layer_id < 0)
return false;
// layer_id is 0-based, so we need to add 1 to make it 1-based
layer_id++;
// Remove whitespace and surrounding quotes.
std::string p; p.reserve(pattern.size());
for (char c : pattern) {
if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
continue;
p.push_back(c);
}
if (!p.empty() && (p.front() == '"' || p.front() == '\''))
p.erase(p.begin());
if (!p.empty() && (p.back() == '"' || p.back() == '\''))
p.pop_back();
if (p.empty())
return false;
// Explicit list form: "1,7,9" or with counts per entry: "5,9#2,18"
if (p.find(',') != std::string::npos) {
size_t start = 0;
while (start < p.size()) {
size_t end = p.find(',', start);
std::string token = p.substr(start, (end == std::string::npos) ? std::string::npos : end - start);
if (!token.empty()) {
try {
size_t hash_pos_token = token.find('#');
if (hash_pos_token == std::string::npos) {
int value = std::stoi(token);
if (value == layer_id)
return true;
} else {
int base_layer = std::stoi(token.substr(0, hash_pos_token));
std::string count_str = token.substr(hash_pos_token + 1);
int local_count = 1;
if (!count_str.empty())
local_count = std::stoi(count_str);
if (base_layer > 0 && local_count > 0) {
if (layer_id >= base_layer && layer_id < base_layer + local_count)
return true;
}
}
} catch (...) {
// Ignore invalid tokens
}
}
if (end == std::string::npos)
break;
start = end + 1;
}
return false;
}
// Interval form: "N#K" or simplified "N" (equals to N#1)
int interval = 0;
int count = 1;
size_t hash_pos = p.find('#');
try {
if (hash_pos == std::string::npos) {
interval = std::stoi(p);
} else {
interval = std::stoi(p.substr(0, hash_pos));
std::string count_str = p.substr(hash_pos + 1);
if (!count_str.empty())
count = std::stoi(count_str);
}
} catch (...) {
return false;
}
if (interval <= 0 || count <= 0)
return false;
// Layers are 1-based. Match layers interval, interval+1, ..., interval+count-1, then repeat every interval.
if (layer_id < interval)
return false;
int mod = layer_id % interval; // For multiples, mod == 0
return mod >= 0 && mod < count;
}
}; // namespace Slic3r