OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::FilamentGroupUtils Namespace Reference

Classes

struct  FlushTimeMachine
struct  MemoryedGroup
struct  Color
struct  FilamentInfo
struct  MachineFilamentInfo
class  FilamentGroupException

Typedefs

using MemoryedGroupHeap = std::priority_queue<MemoryedGroup, std::vector<MemoryedGroup>, std::greater<MemoryedGroup>>

Functions

void update_memoryed_groups (const MemoryedGroup &item, const double gap_threshold, MemoryedGroupHeap &groups)
std::vector< int > calc_max_group_size (const std::vector< std::map< int, int > > &ams_counts, bool ignore_ext_filament)
static std::vector< std::vector< MachineFilamentInfo > > build_full_machine_filaments (const std::vector< std::vector< DynamicPrintConfig > > &filament_configs)
std::vector< std::vector< MachineFilamentInfo > > build_machine_filaments (const std::vector< std::vector< DynamicPrintConfig > > &filament_configs, const std::vector< std::map< int, int > > &ams_counts, bool ignore_ext_filament)
bool collect_unprintable_limits (const std::vector< std::set< int > > &physical_unprintables, const std::vector< std::set< int > > &geometric_unprintables, std::vector< std::set< int > > &unprintable_limits)
bool remove_intersection (std::set< int > &a, std::set< int > &b)
void extract_indices (const std::vector< unsigned int > &used_filaments, const std::vector< std::set< int > > &unprintable_elems, std::vector< std::set< int > > &unprintable_idxs)
void extract_unprintable_limit_indices (const std::vector< std::set< int > > &unprintable_elems, const std::vector< unsigned int > &used_filaments, std::map< int, int > &unplaceable_limits)
void extract_unprintable_limit_indices (const std::vector< std::set< int > > &unprintable_elems, const std::vector< unsigned int > &used_filaments, std::unordered_map< int, std::vector< int > > &unplaceable_limits)
bool check_printable (const std::vector< std::set< int > > &groups, const std::map< int, int > &unprintable)
int get_estimate_extruder_change_count (const std::vector< std::vector< unsigned int > > &layer_filaments, const MultiNozzleUtils::LayeredNozzleGroupResult &extruder_nozzle_info)
int get_estimate_nozzle_change_count (const std::vector< std::vector< unsigned int > > &layer_filaments, const MultiNozzleUtils::LayeredNozzleGroupResult &extruder_nozzle_info)
std::pair< int, int > get_estimate_extruder_filament_change_count (const MultiNozzleUtils::LayeredNozzleGroupResult &extruder_nozzle_info)
std::map< int, std::vector< int > > build_extruder_nozzle_list (const std::vector< MultiNozzleUtils::NozzleInfo > &nozzle_list)
std::vector< int > update_used_filament_values (const std::vector< int > &old_values, const std::vector< int > &new_values, const std::vector< unsigned int > &used_filaments)

Typedef Documentation

◆ MemoryedGroupHeap

using Slic3r::FilamentGroupUtils::MemoryedGroupHeap = std::priority_queue<MemoryedGroup, std::vector<MemoryedGroup>, std::greater<MemoryedGroup>>

Function Documentation

◆ build_extruder_nozzle_list()

std::map< int, std::vector< int > > Slic3r::FilamentGroupUtils::build_extruder_nozzle_list ( const std::vector< MultiNozzleUtils::NozzleInfo > & nozzle_list)
335 {
336 std::map<int, std::vector<int>> ret;
337 for (auto& nozzle : nozzle_list) {
338 ret[nozzle.extruder_id].emplace_back(nozzle.group_id);
339 }
340
341 for (auto& elem : ret)
342 std::sort(elem.second.begin(), elem.second.end());
343 return ret;
344 }

Referenced by Slic3r::build_filament_group_context().

Here is the caller graph for this function:

◆ build_full_machine_filaments()

std::vector< std::vector< MachineFilamentInfo > > Slic3r::FilamentGroupUtils::build_full_machine_filaments ( const std::vector< std::vector< DynamicPrintConfig > > & filament_configs)
static
107 {
108 auto extract_filament_type = [](const std::string& s)->std::string {
109 std::regex r1(R"(^Sup.(\w+)$)");
110 std::regex r2(R"(^(\w+)-S$)");
111
112 std::smatch m;
113 if (std::regex_match(s, m, r1))
114 return m[1].str();
115 if (std::regex_match(s, m, r2))
116 return m[1].str();
117 return s;
118 };
119
120 // change filament type to type format in preset
121 // defualt size set to 2
122 std::vector<std::vector<MachineFilamentInfo>> machine_filaments(2);
123 for (size_t idx = 0; idx < filament_configs.size(); ++idx) {
124 auto& arr = filament_configs[idx];
125 for (auto& item : arr) {
127 std::string type;
128 std::string color;
129 std::string tray_name;
130 bool is_support_filament = false;
131
132 if (auto color_ptr = item.option<ConfigOptionStrings>("filament_colour"); color_ptr)
133 color = color_ptr->get_at(0);
134 if (auto type_ptr = item.option<ConfigOptionStrings>("filament_type"); type_ptr) {
135 type = type_ptr->get_at(0);
136 type = extract_filament_type(type);
137 }
138 if (auto tray_ptr = item.option<ConfigOptionStrings>("tray_name"); tray_ptr)
139 tray_name = tray_ptr->get_at(0);
140 if (auto support_ptr = item.option<ConfigOptionBools>("filament_is_support"); support_ptr)
141 is_support_filament = support_ptr->get_at(0);
142
143 if (color.empty() || type.empty() || tray_name.empty())
144 continue;
145
146 temp.color = Color(color);
147 temp.type =type;
148 temp.extruder_id = idx;
149 temp.is_extended = tray_name == "Ext"; // hard-coded ext flag
150 temp.is_support = is_support_filament;
151 machine_filaments[idx].emplace_back(std::move(temp));
152 }
153 }
154 return machine_filaments;
155 }
Definition Config.hpp:1190
ConfigOptionBoolsTempl< false > ConfigOptionBools
Definition Config.hpp:2066
bool is_support
Definition FilamentGroupUtils.hpp:37
Color color
Definition FilamentGroupUtils.hpp:35
std::string type
Definition FilamentGroupUtils.hpp:36
Definition FilamentGroupUtils.hpp:44
int extruder_id
Definition FilamentGroupUtils.hpp:45
bool is_extended
Definition FilamentGroupUtils.hpp:46

References Slic3r::FilamentGroupUtils::FilamentInfo::color, Slic3r::FilamentGroupUtils::MachineFilamentInfo::extruder_id, Slic3r::FilamentGroupUtils::MachineFilamentInfo::is_extended, Slic3r::FilamentGroupUtils::FilamentInfo::is_support, and Slic3r::FilamentGroupUtils::FilamentInfo::type.

Referenced by build_machine_filaments().

Here is the caller graph for this function:

◆ build_machine_filaments()

std::vector< std::vector< MachineFilamentInfo > > Slic3r::FilamentGroupUtils::build_machine_filaments ( const std::vector< std::vector< DynamicPrintConfig > > & filament_configs,
const std::vector< std::map< int, int > > & ams_counts,
bool ignore_ext_filament )
158 {
159 std::vector<std::vector<MachineFilamentInfo>> ret(2);
160 std::vector<int> ams_size(2, 0);
161 std::vector<std::vector<MachineFilamentInfo>> full_machine_filaments = build_full_machine_filaments(filament_configs);
162 assert(full_machine_filaments.size() == 2);
163 for (size_t idx = 0; idx < std::min(ams_counts.size(),ams_size.size()); ++idx) {
164 const auto& ams_count = ams_counts[idx];
165 for (auto iter = ams_count.begin(); iter != ams_count.end(); ++iter) {
166 ams_size[idx] += iter->first * iter->second;
167 }
168 }
169
170 assert(full_machine_filaments.size() == ams_size.size());
171 for (size_t idx = 0; idx < std::min(ams_size.size(), full_machine_filaments.size()); ++idx) {
172 std::vector<MachineFilamentInfo> tmp;
173 for (size_t j = 0; j < full_machine_filaments[idx].size(); ++j) {
174 auto& machine_filament = full_machine_filaments[idx][j];
175 if (!machine_filament.is_extended)
176 tmp.emplace_back(machine_filament);
177 }
178
179 // if do not have valid ams filament, try to use ext filament
180 if (tmp.empty() && !ignore_ext_filament) {
181 for (size_t j = 0; j < full_machine_filaments[idx].size(); ++j) {
182 auto& machine_filament = full_machine_filaments[idx][j];
183 if (machine_filament.is_extended)
184 tmp.emplace_back(machine_filament);
185 }
186 }
187
188 ret[idx] = std::move(tmp);
189 }
190 return ret;
191 }
static std::vector< std::vector< MachineFilamentInfo > > build_full_machine_filaments(const std::vector< std::vector< DynamicPrintConfig > > &filament_configs)
Definition FilamentGroupUtils.cpp:106

References build_full_machine_filaments().

Referenced by Slic3r::build_filament_group_context().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calc_max_group_size()

std::vector< int > Slic3r::FilamentGroupUtils::calc_max_group_size ( const std::vector< std::map< int, int > > & ams_counts,
bool ignore_ext_filament )
88 {
89 // add default value to 2
90 std::vector<int>group_size(2, 0);
91 for (size_t idx = 0; idx < ams_counts.size(); ++idx) {
92 const auto& ams_count = ams_counts[idx];
93 for (auto iter = ams_count.begin(); iter != ams_count.end(); ++iter) {
94 group_size[idx] += iter->first * iter->second;
95 }
96 }
97
98 for (size_t idx = 0; idx < group_size.size(); ++idx) {
99 if (!ignore_ext_filament && group_size[idx] == 0)
100 group_size[idx] = 1;
101 }
102 return group_size;
103 }

Referenced by Slic3r::build_filament_group_context().

Here is the caller graph for this function:

◆ check_printable()

bool Slic3r::FilamentGroupUtils::check_printable ( const std::vector< std::set< int > > & groups,
const std::map< int, int > & unprintable )
283 {
284 for (size_t i = 0; i < groups.size(); ++i) {
285 auto& group = groups[i];
286 for (auto& filament : group) {
287 if (auto iter = unprintable.find(filament); iter != unprintable.end() && i == iter->second)
288 return false;
289 }
290 }
291 return true;
292 }

◆ collect_unprintable_limits()

bool Slic3r::FilamentGroupUtils::collect_unprintable_limits ( const std::vector< std::set< int > > & physical_unprintables,
const std::vector< std::set< int > > & geometric_unprintables,
std::vector< std::set< int > > & unprintable_limits )
194 {
195 unprintable_limits.clear();
196 unprintable_limits.resize(2);
197 // resize unprintables to 2
198 auto resized_physical_unprintables = physical_unprintables;
199 resized_physical_unprintables.resize(2);
200 auto resized_geometric_unprintables = geometric_unprintables;
201 resized_geometric_unprintables.resize(2);
202
203 bool conflict = false;
204 conflict |= remove_intersection(resized_physical_unprintables[0], resized_physical_unprintables[1]);
205 conflict |= remove_intersection(resized_geometric_unprintables[0], resized_geometric_unprintables[1]);
206
207 std::map<int, int>filament_unprintable_exts;
208 for (auto& ext_unprintables : { resized_physical_unprintables,resized_geometric_unprintables }) {
209 for (int eid = 0; eid < ext_unprintables.size(); ++eid) {
210 for (int fid : ext_unprintables[eid]) {
211 if (auto iter = filament_unprintable_exts.find(fid); iter != filament_unprintable_exts.end() && iter->second != eid)
212 conflict = true;
213 else
214 filament_unprintable_exts[fid] = eid;
215 }
216 }
217 }
218 for (auto& elem : filament_unprintable_exts)
219 unprintable_limits[elem.second].insert(elem.first);
220
221 return !conflict;
222 }
bool remove_intersection(std::set< int > &a, std::set< int > &b)
Definition FilamentGroupUtils.cpp:224

References remove_intersection().

Referenced by Slic3r::build_filament_group_context().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extract_indices()

void Slic3r::FilamentGroupUtils::extract_indices ( const std::vector< unsigned int > & used_filaments,
const std::vector< std::set< int > > & unprintable_elems,
std::vector< std::set< int > > & unprintable_idxs )
236 {
237 std::vector<std::set<int>>(unprintable_elems.size()).swap(unprintable_idxs);
238 for (size_t gid = 0; gid < unprintable_elems.size(); ++gid) {
239 for (auto& f : unprintable_elems[gid]) {
240 auto iter = std::find(used_filaments.begin(), used_filaments.end(), (unsigned)f);
241 if (iter != used_filaments.end())
242 unprintable_idxs[gid].insert(iter - used_filaments.begin());
243 }
244 }
245 }
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124

References Slic3r::f().

Referenced by extract_unprintable_limit_indices(), and extract_unprintable_limit_indices().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extract_unprintable_limit_indices() [1/2]

void Slic3r::FilamentGroupUtils::extract_unprintable_limit_indices ( const std::vector< std::set< int > > & unprintable_elems,
const std::vector< unsigned int > & used_filaments,
std::map< int, int > & unplaceable_limits )
248 {
249 unplaceable_limits.clear();
250 // map the unprintable filaments to idx of used filaments , if not used ,just ignore
251 std::vector<std::set<int>> unprintable_idxs;
252 extract_indices(used_filaments, unprintable_elems, unprintable_idxs);
253 if (unprintable_idxs.size() > 1)
254 remove_intersection(unprintable_idxs[0], unprintable_idxs[1]);
255
256 for (size_t idx = 0; idx < unprintable_idxs.size(); ++idx) {
257 for (auto f : unprintable_idxs[idx])
258 if (unplaceable_limits.count(f) == 0)
259 unplaceable_limits[f] = idx;
260 }
261 }
void extract_indices(const std::vector< unsigned int > &used_filaments, const std::vector< std::set< int > > &unprintable_elems, std::vector< std::set< int > > &unprintable_idxs)
Definition FilamentGroupUtils.cpp:235

References extract_indices(), Slic3r::f(), and remove_intersection().

Referenced by Slic3r::FilamentGroup::calc_filament_group_for_match(), Slic3r::FilamentGroup::calc_filament_group_for_tpu(), and Slic3r::FilamentGroup::calc_min_flush_group().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extract_unprintable_limit_indices() [2/2]

void Slic3r::FilamentGroupUtils::extract_unprintable_limit_indices ( const std::vector< std::set< int > > & unprintable_elems,
const std::vector< unsigned int > & used_filaments,
std::unordered_map< int, std::vector< int > > & unplaceable_limits )
265 {
266 unplaceable_limits.clear();
267 std::vector<std::set<int>>unprintable_idxs;
268 // map the unprintable filaments to idx of used filaments , if not used ,just ignore
269 extract_indices(used_filaments, unprintable_elems, unprintable_idxs);
270 // remove elems that cannot be printed in both extruder
271 if (unprintable_idxs.size() > 1)
272 remove_intersection(unprintable_idxs[0], unprintable_idxs[1]);
273
274 for (size_t group_id = 0; group_id < unprintable_idxs.size(); ++group_id)
275 for (auto f : unprintable_idxs[group_id])
276 unplaceable_limits[f].emplace_back(group_id);
277
278 for (auto& elem : unplaceable_limits)
279 sort_remove_duplicates(elem.second);
280 }
uint32_t group_id(std::vector< Bridge > &bridges, uint32_t src_id)
Definition LayerRegion.cpp:214
void sort_remove_duplicates(std::vector< T > &vec)
Definition libslic3r.h:231

References extract_indices(), Slic3r::f(), Slic3r::group_id(), remove_intersection(), and Slic3r::sort_remove_duplicates().

Here is the call graph for this function:

◆ get_estimate_extruder_change_count()

int Slic3r::FilamentGroupUtils::get_estimate_extruder_change_count ( const std::vector< std::vector< unsigned int > > & layer_filaments,
const MultiNozzleUtils::LayeredNozzleGroupResult & extruder_nozzle_info )
295 {
296 int ret = 0;
297 for (size_t layer_id = 0; layer_id < layer_filaments.size(); ++layer_id) {
298 int extruder_count = extruder_nozzle_info.get_used_extruders(layer_id).size();
299 ret += (extruder_count - 1);
300 }
301 return ret;
302 }
std::vector< int > get_used_extruders() const override
Definition MultiNozzleUtils.cpp:295

References Slic3r::MultiNozzleUtils::LayeredNozzleGroupResult::get_used_extruders().

Here is the call graph for this function:

◆ get_estimate_extruder_filament_change_count()

std::pair< int, int > Slic3r::FilamentGroupUtils::get_estimate_extruder_filament_change_count ( const MultiNozzleUtils::LayeredNozzleGroupResult & extruder_nozzle_info)
318 {
319 std::pair<int, int> ret{0,0};
320 int layer_nums = extruder_nozzle_info.get_layer_filament_sequences().size();
321 for (int layer_id = 0; layer_id < layer_nums; layer_id++) {
322 std::vector<int> extruders = extruder_nozzle_info.get_used_extruders(layer_id);
323 ret.first = extruders.size() - 1;
324
325 for (auto ext_id : extruders) {
326 int nozzles = extruder_nozzle_info.get_used_nozzles_in_extruder(ext_id, layer_id).size();
327 ret.second += nozzles;
328 }
329 ret.second = std::max(0, ret.second - ret.first);
330 }
331 return ret;
332 }
const std::vector< std::vector< unsigned int > > & get_layer_filament_sequences() const
Definition MultiNozzleUtils.hpp:185
std::vector< NozzleInfo > get_used_nozzles_in_extruder(int target_extruder_id=-1) const override
Definition MultiNozzleUtils.cpp:264

References Slic3r::MultiNozzleUtils::LayeredNozzleGroupResult::get_layer_filament_sequences(), Slic3r::MultiNozzleUtils::LayeredNozzleGroupResult::get_used_extruders(), and Slic3r::MultiNozzleUtils::LayeredNozzleGroupResult::get_used_nozzles_in_extruder().

Here is the call graph for this function:

◆ get_estimate_nozzle_change_count()

int Slic3r::FilamentGroupUtils::get_estimate_nozzle_change_count ( const std::vector< std::vector< unsigned int > > & layer_filaments,
const MultiNozzleUtils::LayeredNozzleGroupResult & extruder_nozzle_info )
305 {
306 int ret = 0;
307 for (size_t layer_id = 0; layer_id < layer_filaments.size(); ++layer_id) {
308 auto extruder_list = extruder_nozzle_info.get_used_extruders(layer_id);
309 for (auto extruder_id : extruder_list) {
310 int nozzle_count = extruder_nozzle_info.get_used_nozzles_in_extruder(extruder_id, layer_id).size();
311 if (nozzle_count > 1) ret += (nozzle_count - 1);
312 }
313 }
314 return ret;
315 }

References Slic3r::MultiNozzleUtils::LayeredNozzleGroupResult::get_used_extruders(), and Slic3r::MultiNozzleUtils::LayeredNozzleGroupResult::get_used_nozzles_in_extruder().

Here is the call graph for this function:

◆ remove_intersection()

bool Slic3r::FilamentGroupUtils::remove_intersection ( std::set< int > & a,
std::set< int > & b )
224 {
225 std::vector<int>intersection;
226 std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(intersection));
227 bool have_intersection = !intersection.empty();
228 for (auto& item : intersection) {
229 a.erase(item);
230 b.erase(item);
231 }
232 return have_intersection;
233 }
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:769

References Slic3r::intersection().

Referenced by Slic3r::can_swap_extruder_groups(), collect_unprintable_limits(), extract_unprintable_limit_indices(), and extract_unprintable_limit_indices().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_memoryed_groups()

void Slic3r::FilamentGroupUtils::update_memoryed_groups ( const MemoryedGroup & item,
const double gap_threshold,
MemoryedGroupHeap & groups )
519 {
520 auto emplace_if_accepatle = [gap_threshold](MemoryedGroupHeap& heap, const MemoryedGroup& elem, const MemoryedGroup& best) {
521 if (best.cost == 0) {
522 if (std::abs(elem.cost - best.cost) <= ABSOLUTE_FLUSH_GAP_TOLERANCE)
523 heap.push(elem);
524 return;
525 }
526 double gap_rate = (double)std::abs(elem.cost - best.cost) / (double)best.cost;
527 if (gap_rate <= gap_threshold)
528 heap.push(elem);
529 };
530
531 if (groups.empty()) {
532 groups.push(item);
533 }
534 else {
535 auto top = groups.top();
536 // we only memory items with the highest prefer level
537 if (top.prefer_level > item.prefer_level)
538 return;
539 else if (top.prefer_level == item.prefer_level) {
540 if (top.cost <= item.cost) {
541 emplace_if_accepatle(groups, item, top);
542 }
543 // find a group with lower cost, rebuild the heap
544 else {
545 MemoryedGroupHeap new_heap;
546 new_heap.push(item);
547 while (!groups.empty()) {
548 auto top = groups.top();
549 groups.pop();
550 emplace_if_accepatle(new_heap, top, item);
551 }
552 groups = std::move(new_heap);
553 }
554 }
555 // find a group with the higher prefer level, rebuild the heap
556 else {
557 groups = MemoryedGroupHeap();
558 groups.push(item);
559 }
560 }
561 }
static const int ABSOLUTE_FLUSH_GAP_TOLERANCE
Definition FilamentGroup.hpp:23
std::priority_queue< MemoryedGroup, std::vector< MemoryedGroup >, std::greater< MemoryedGroup > > MemoryedGroupHeap
Definition FilamentGroup.hpp:73
Definition FilamentGroup.hpp:61
int prefer_level
Definition FilamentGroup.hpp:69
double cost
Definition FilamentGroup.hpp:68

References ABSOLUTE_FLUSH_GAP_TOLERANCE, Slic3r::FilamentGroupUtils::MemoryedGroup::cost, and Slic3r::FilamentGroupUtils::MemoryedGroup::prefer_level.

Referenced by Slic3r::FilamentGroup::calc_group_by_enum(), and Slic3r::KMediods::do_clustering().

Here is the caller graph for this function:

◆ update_used_filament_values()

std::vector< int > Slic3r::FilamentGroupUtils::update_used_filament_values ( const std::vector< int > & old_values,
const std::vector< int > & new_values,
const std::vector< unsigned int > & used_filaments )
347 {
348 std::vector<int> res = old_values;
349 for (size_t i = 0; i < used_filaments.size(); ++i) {
350 // Orca: guard against filament ids beyond the map sizes (possible with
351 // mis-normalized per-filament arrays from CLI inputs); skip instead of UB.
352 if (used_filaments[i] >= res.size() || used_filaments[i] >= new_values.size())
353 continue;
354 res[used_filaments[i]] = new_values[used_filaments[i]];
355 }
356 return res;
357 }

Referenced by Slic3r::Print::update_to_config_by_nozzle_group_result().

Here is the caller graph for this function: