OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::DevMappingUtil Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/DeviceCore/DevMapping.h>

Public Member Functions

 DevMappingUtil ()=delete
 ~DevMappingUtil ()=delete

Static Public Member Functions

static bool is_valid_mapping_result (const MachineObject *obj, std::vector< FilamentInfo > &result, bool check_empty_slot=false)
static int ams_filament_mapping (const MachineObject *obj, const std::vector< FilamentInfo > &filaments, std::vector< FilamentInfo > &result, std::vector< bool > map_opt, std::vector< int > exclude_id=std::vector< int >(), bool nozzle_has_ams_then_ignore_ext=false)

Detailed Description

Constructor & Destructor Documentation

◆ DevMappingUtil()

Slic3r::DevMappingUtil::DevMappingUtil ( )
delete

◆ ~DevMappingUtil()

Slic3r::DevMappingUtil::~DevMappingUtil ( )
delete

Member Function Documentation

◆ ams_filament_mapping()

int Slic3r::DevMappingUtil::ams_filament_mapping ( const MachineObject * obj,
const std::vector< FilamentInfo > & filaments,
std::vector< FilamentInfo > & result,
std::vector< bool > map_opt,
std::vector< int > exclude_id = std::vector<int>(),
bool nozzle_has_ams_then_ignore_ext = false )
static
120 {
121 if (filaments.empty())
122 return -1;
123
125 // Step 1: collect filaments in machine
126 std::map<int, FilamentInfo> tray_filaments; // tray_index : tray_color
127 bool left_nozzle_has_ams = false, right_nozzle_has_ams = false;
128
129 const auto& ams_list = obj->GetFilaSystem()->GetAmsList();
130 for (auto ams = ams_list.begin(); ams != ams_list.end(); ams++)
131 {
132 std::string ams_id = ams->second->GetAmsId();
133 auto ams_type = ams->second->GetAmsType();
134 // GetAmsType() maps mixed -> AMS_LITE; recover the mixed type so N9 trays index at 24+slot.
135 if (ams_type == DevAms::AMS_LITE && ams->second->IsAmsLiteMixed())
136 {
137 ams_type = DevAms::AMS_LITE_MIXED;
138 }
139 for (auto tray = ams->second->GetTrays().begin(); tray != ams->second->GetTrays().end(); tray++)
140 {
141 int ams_id = atoi(ams->first.c_str());
142 int tray_id = atoi(tray->first.c_str());
143 int tray_index = 0;
144 if (ams_type == DevAms::AMS || ams_type == DevAms::AMS_LITE || ams_type == DevAms::N3F)
145 {
146 tray_index = ams_id * 4 + tray_id;
147 }
148 else if (ams_type == DevAms::AMS_LITE_MIXED)
149 {
150 tray_index = AMS_LITE_MIXED_TRAY_INDEX_OFFSET + tray_id;
151 }
152 else if (ams_type == DevAms::N3S)
153 {
154 tray_index = ams_id + tray_id;
155 }
156 else
157 {
158 assert(0);
159 }
160
161 // skip exclude id
162 for (int i = 0; i < exclude_id.size(); i++)
163 {
164 if (tray_index == exclude_id[i])
165 continue;
166 }
167 // push
168 FilamentInfo info;
169 if (tray->second->is_tray_info_ready())
170 {
171 _parse_tray_info(ams_id, tray_id, ams_type, *(tray->second), info);
172 }
173
174 //first: left,nozzle=1,map=1 second: right,nozzle=0,map=2
175 bool right_ams_valid = (ams->second->GetBindedExtruderSet().count(MAIN_EXTRUDER_ID) != 0) && map_opt[MappingOption::USE_RIGHT_AMS];
176 bool left_ams_valid = (ams->second->GetBindedExtruderSet().count(DEPUTY_EXTRUDER_ID) != 0) && map_opt[MappingOption::USE_LEFT_AMS];
177 if (right_ams_valid || left_ams_valid)
178 {
179 tray_filaments.emplace(std::make_pair(tray_index, info));
180 if (right_ams_valid)
181 {
182 right_nozzle_has_ams = true;
183 }
184 if (left_ams_valid)
185 {
186 left_nozzle_has_ams = true;
187 }
188 }
189 }
190 }
191
193 {
194 for (auto tray : obj->vt_slot)
195 {
196 bool right_ext_valid = (tray.id == std::to_string(VIRTUAL_TRAY_MAIN_ID) && map_opt[MappingOption::USE_RIGHT_EXT]);
197 bool left_ext_valid = (tray.id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID) && map_opt[MappingOption::USE_LEFT_EXT]);
198 if (right_ext_valid || left_ext_valid)
199 {
200 if (nozzle_has_ams_then_ignore_ext)
201 {
202 if (right_ext_valid && right_nozzle_has_ams)
203 {
204 continue;
205 }
206 if (left_ext_valid && left_nozzle_has_ams)
207 {
208 continue;
209 }
210 }
211 FilamentInfo info;
212 _parse_tray_info(atoi(tray.id.c_str()), 0, DevAms::EXT_SPOOL, tray, info);
213 tray_filaments.emplace(std::make_pair(info.tray_id, info));
214 }
215 }
216 }
217
219 // Step 2: collect the distances of filaments_in_slicing to filaments_in_machine
220 char buffer[256];
221 std::vector<std::vector<DisValue>> distance_map;
222
223 // print title
224 ::sprintf(buffer, "F(id)");
225 std::string line = std::string(buffer);
226 for (auto tray = tray_filaments.begin(); tray != tray_filaments.end(); tray++)
227 {
228 ::sprintf(buffer, " AMS%02d", tray->second.id + 1);
229 line += std::string(buffer);
230 }
231 BOOST_LOG_TRIVIAL(info) << "ams_mapping_distance:" << line;// Print the collected filaments
232
233 for (int i = 0; i < filaments.size(); i++)
234 {
235 std::vector<DisValue> rol;
236 ::sprintf(buffer, "F(%02d)", filaments[i].id + 1);
237 line = std::string(buffer);
238 for (auto tray = tray_filaments.begin(); tray != tray_filaments.end(); tray++)
239 {
240 DisValue val;
241 val.tray_id = tray->second.id;
242 wxColour c = wxColour(filaments[i].color);
243 wxColour tray_c = DevAmsTray::decode_color(tray->second.color);
244 val.distance = GUI::calc_color_distance(c, tray_c);
245 if (filaments[i].type != tray->second.type)
246 {
247 val.distance = 999999;
248 val.is_type_match = false;
249 }
250 else
251 {
252 if (c.Alpha() != tray_c.Alpha())
253 val.distance = 999999;
254 val.is_type_match = true;
255 }
256 ::sprintf(buffer, " %6.0f", val.distance);
257 line += std::string(buffer);
258 rol.push_back(val);
259 }
260 BOOST_LOG_TRIVIAL(info) << "ams_mapping_distance:" << line;
261 distance_map.push_back(rol);
262 }
263
265 // Step 3: do mapping algorithm
266
267 // setup the mapping result
268 for (int i = 0; i < filaments.size(); i++)
269 {
270 FilamentInfo info;
271 info.id = filaments[i].id;
272 info.tray_id = -1;
273 info.type = filaments[i].type;
274 info.filament_id = filaments[i].filament_id;
275 result.push_back(info);
276 }
277
278 // traverse the mapping
279 std::set<int> picked_src;
280 std::set<int> picked_tar;
281 for (int k = 0; k < distance_map.size(); k++)
282 {
283 float min_val = std::numeric_limits<float>::max();
284 int picked_src_idx = -1;
285 int picked_tar_idx = -1;
286 for (int i = 0; i < distance_map.size(); i++)
287 {
288 if (picked_src.find(i) != picked_src.end())
289 continue;
290
291 // try to mapping to different tray
292 for (int j = 0; j < distance_map[i].size(); j++)
293 {
294 if (picked_tar.find(j) != picked_tar.end())
295 {
296 if (distance_map[i][j].is_same_color
297 && distance_map[i][j].is_type_match
298 && distance_map[i][j].distance < (float)0.0001)
299 {
300 min_val = distance_map[i][j].distance;
301 picked_src_idx = i;
302 picked_tar_idx = j;
303 tray_filaments[picked_tar_idx].distance = min_val;
304 }
305 continue;
306 }
307
308 if (distance_map[i][j].is_same_color
309 && distance_map[i][j].is_type_match)
310 {
311 if (min_val > distance_map[i][j].distance)
312 {
313
314 min_val = distance_map[i][j].distance;
315 picked_src_idx = i;
316 picked_tar_idx = j;
317 tray_filaments[picked_tar_idx].distance = min_val;
318 }
319 else if (min_val == distance_map[i][j].distance && filaments[picked_src_idx].filament_id != tray_filaments[picked_tar_idx].filament_id && filaments[i].filament_id == tray_filaments[j].filament_id)
320 {
321
322 picked_src_idx = i;
323 picked_tar_idx = j;
324 }
325 }
326 }
327
328 // take a retry to mapping to used tray
329 if (picked_src_idx < 0 || picked_tar_idx < 0)
330 {
331 for (int j = 0; j < distance_map[i].size(); j++)
332 {
333 if (distance_map[i][j].is_same_color && distance_map[i][j].is_type_match)
334 {
335 if (min_val > distance_map[i][j].distance)
336 {
337 min_val = distance_map[i][j].distance;
338 picked_src_idx = i;
339 picked_tar_idx = j;
340 tray_filaments[picked_tar_idx].distance = min_val;
341 }
342 else if (min_val == distance_map[i][j].distance && filaments[picked_src_idx].filament_id != tray_filaments[picked_tar_idx].filament_id && filaments[i].filament_id == tray_filaments[j].filament_id)
343 {
344 picked_src_idx = i;
345 picked_tar_idx = j;
346 }
347 }
348 }
349 }
350 }
351
352 if (picked_src_idx >= 0 && picked_tar_idx >= 0)
353 {
354 auto tray = tray_filaments.find(distance_map[k][picked_tar_idx].tray_id);
355
356 if (tray != tray_filaments.end())
357 {
358 result[picked_src_idx].tray_id = tray->first;
359
360 result[picked_src_idx].color = tray->second.color;
361 result[picked_src_idx].type = tray->second.type;
362 result[picked_src_idx].distance = tray->second.distance;
363 result[picked_src_idx].filament_id = tray->second.filament_id;
364 result[picked_src_idx].ctype = tray->second.ctype;
365 result[picked_src_idx].colors = tray->second.colors;
366
367 /*for new ams mapping*/
368 result[picked_src_idx].ams_id = tray->second.ams_id;
369 result[picked_src_idx].slot_id = tray->second.slot_id;
370 }
371
372 ::sprintf(buffer, "ams_mapping, picked F(%02d) AMS(%02d), distance=%6.0f", picked_src_idx + 1, picked_tar_idx + 1,
373 distance_map[picked_src_idx][picked_tar_idx].distance);
374 BOOST_LOG_TRIVIAL(info) << std::string(buffer);
375 picked_src.insert(picked_src_idx);
376 picked_tar.insert(picked_tar_idx);
377 }
378 }
379
380 // Orca: special cases that no AMS available, we select ext slot automatically because we don't have other choice anyway
381 if (tray_filaments.size() == 1 && devPrinterUtil::IsVirtualSlot(tray_filaments.begin()->first)) {
382 auto ext_tray = tray_filaments.begin();
383 for (auto & r : result) {
384 if (r.tray_id < 0) {
385 r.tray_id = ext_tray->first;
386
387 r.color = ext_tray->second.color;
388 r.type = ext_tray->second.type;
389 r.distance = ext_tray->second.distance;
390 r.filament_id = ext_tray->second.filament_id;
391 r.ctype = ext_tray->second.ctype;
392 r.colors = ext_tray->second.colors;
393
394 /*for new ams mapping*/
395 r.ams_id = ext_tray->second.ams_id;
396 r.slot_id = ext_tray->second.slot_id;
397 }
398 }
399 }
400
401 //check ams mapping result
402 if (DevMappingUtil::is_valid_mapping_result(obj, result, true))
403 {
404 return 0;
405 }
406
407 /* for (auto it = result.begin(); it != result.end(); it++) {//This code has never been effective before 2025.03.18
408 if (it->distance >= 6000) {
409 it->tray_id = -1;
410 }
411 }*/
412 return 0;
413 }
static unsigned int count
Definition AuxiliaryDataViewModel.cpp:246
#define DEPUTY_EXTRUDER_ID
Definition DevDefs.h:102
#define AMS_LITE_MIXED_TRAY_INDEX_OFFSET
Definition DevDefs.h:96
#define VIRTUAL_TRAY_DEPUTY_ID
Definition DevDefs.h:90
#define VIRTUAL_TRAY_MAIN_ID
Definition DevDefs.h:89
#define MAIN_EXTRUDER_ID
Definition DevDefs.h:101
static wxColour decode_color(const std::string &color)
Definition DevFilaSystem.cpp:38
static constexpr AmsType AMS_LITE_MIXED
Definition DevFilaSystem.h:148
static constexpr AmsType EXT_SPOOL
Definition DevFilaSystem.h:143
static constexpr AmsType AMS
Definition DevFilaSystem.h:144
static constexpr AmsType N3F
Definition DevFilaSystem.h:146
static constexpr AmsType AMS_LITE
Definition DevFilaSystem.h:145
static constexpr AmsType N3S
Definition DevFilaSystem.h:147
static bool is_valid_mapping_result(const MachineObject *obj, std::vector< FilamentInfo > &result, bool check_empty_slot=false)
Definition DevMapping.cpp:25
static bool IsVirtualSlot(int ams_id)
Definition DevDefs.h:165
float calc_color_distance(wxColour c1, wxColour c2)
Definition GuiColor.cpp:28
static void _parse_tray_info(int ams_id, int slot_id, DevAms::AmsType type, DevAmsTray tray, FilamentInfo &result)
Definition DevMapping.cpp:85
@ USE_RIGHT_AMS
Definition DevMapping.h:16
@ USE_LEFT_AMS
Definition DevMapping.h:15
@ USE_LEFT_EXT
Definition DevMapping.h:17
@ USE_RIGHT_EXT
Definition DevMapping.h:18

References Slic3r::_parse_tray_info(), Slic3r::DevAms::AMS, Slic3r::DevAms::AMS_LITE, Slic3r::DevAms::AMS_LITE_MIXED, AMS_LITE_MIXED_TRAY_INDEX_OFFSET, Slic3r::GUI::calc_color_distance(), count, Slic3r::DevAmsTray::decode_color(), DEPUTY_EXTRUDER_ID, Slic3r::DisValue::distance, Slic3r::DevAms::EXT_SPOOL, Slic3r::MachineObject::GetFilaSystem(), Slic3r::DisValue::is_type_match, is_valid_mapping_result(), Slic3r::devPrinterUtil::IsVirtualSlot(), MAIN_EXTRUDER_ID, Slic3r::DevAms::N3F, Slic3r::DevAms::N3S, Slic3r::DisValue::tray_id, Slic3r::FilamentGroupUtils::FilamentInfo::type, Slic3r::USE_LEFT_AMS, Slic3r::USE_LEFT_EXT, Slic3r::USE_RIGHT_AMS, Slic3r::USE_RIGHT_EXT, VIRTUAL_TRAY_DEPUTY_ID, VIRTUAL_TRAY_MAIN_ID, and Slic3r::MachineObject::vt_slot.

Referenced by Slic3r::GUI::SelectMachineDialog::do_ams_mapping(), and Slic3r::GUI::SyncAmsInfoDialog::do_ams_mapping().

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

◆ is_valid_mapping_result()

bool Slic3r::DevMappingUtil::is_valid_mapping_result ( const MachineObject * obj,
std::vector< FilamentInfo > & result,
bool check_empty_slot = false )
static
26 {
27 if (result.empty()) return false;
28
29 for (int i = 0; i < result.size(); i++)
30 {
31 // invalid mapping result
32 if (result[i].tray_id < 0)
33 {
34 if (result[i].ams_id.empty() && result[i].slot_id.empty())
35 {
36 return false;
37 }
38 }
39 else
40 {
41
42 auto ams_item = obj->GetFilaSystem()->GetAmsById(result[i].ams_id);
43 if (ams_item == nullptr)
44 {
45 if ((result[i].ams_id != std::to_string(VIRTUAL_TRAY_MAIN_ID)) &&
46 (result[i].ams_id != std::to_string(VIRTUAL_TRAY_DEPUTY_ID)))
47 {
48 result[i].tray_id = -1;
49 return false;
50 }
51 }
52 else
53 {
54 if (check_empty_slot)
55 {
56 auto tray_item = ams_item->GetTrays().find(result[i].slot_id);
57 if (tray_item == ams_item->GetTrays().end())
58 {
59 result[i].tray_id = -1;
60 return false;
61 }
62 else
63 {
64 if (!tray_item->second->is_exists)
65 {
66 result[i].tray_id = -1;
67 return false;
68 }
69 }
70 }
71 }
72 }
73 }
74 return true;
75 }

References Slic3r::MachineObject::GetFilaSystem(), VIRTUAL_TRAY_DEPUTY_ID, and VIRTUAL_TRAY_MAIN_ID.

Referenced by ams_filament_mapping(), Slic3r::GUI::SelectMachineDialog::do_ams_mapping(), Slic3r::GUI::SyncAmsInfoDialog::do_ams_mapping(), and Slic3r::GUI::SelectMachineDialog::update_show_status().

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

The documentation for this class was generated from the following files:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/DeviceCore/DevMapping.h
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/DeviceCore/DevMapping.cpp