240{
241 if (objs.empty() && !wtdptr) { return {}; }
242
243
244 size_t total_instances = 0;
245 for (auto obj : objs) total_instances += obj->instances().size();
246 if (total_instances <= 1 && !wtdptr) return {};
247
248 LinesBucketQueue conflictQueue;
249
250 if (wtdptr.has_value()) {
251
252 ExtrusionLayers wtels = wtdptr.value()->getTrueExtrusionLayersFromWipeTower();
253
254
255
256
257
258
259
260
261 conflictQueue.emplace_back_bucket(std::move(wtels), wtdptr.value(), {wtdptr.value()->plate_origin.x(), wtdptr.value()->plate_origin.y()});
262 }
263 for (PrintObject *obj : objs) {
265
266 const auto& instances = obj->instances();
267 for (size_t inst_idx = 0; inst_idx < instances.size(); ++inst_idx) {
268 const PrintInstance& inst = instances[inst_idx];
269 const bool is_last_instance = inst_idx + 1 == instances.size();
270 if (is_last_instance) {
271 conflictQueue.emplace_back_bucket(std::move(layers.perimeters), &inst, inst.shift);
272 conflictQueue.emplace_back_bucket(std::move(layers.support), &inst, inst.shift);
273 } else {
274 conflictQueue.emplace_back_bucket(ExtrusionLayers(layers.perimeters), &inst, inst.shift);
275 conflictQueue.emplace_back_bucket(ExtrusionLayers(layers.support), &inst, inst.shift);
276 }
277 }
278 }
279
280 std::vector<LineWithIDs> layersLines;
281 std::vector<float> bottomZs;
282 while (conflictQueue.valid()) {
284 float curBottomZ = conflictQueue.getCurrBottomZ();
285 bottomZs.push_back(curBottomZ);
286 layersLines.push_back(std::move(lines));
287 }
288
290 tbb::concurrent_vector<std::pair<ConflictComputeResult, float>> conflict;
291 tbb::parallel_for(tbb::blocked_range<size_t>(0, layersLines.size()), [&](tbb::blocked_range<size_t>
range) {
292 for (size_t i = range.begin(); i < range.end(); i++) {
293 auto interRes = find_inter_of_lines(layersLines[i]);
294 if (interRes.has_value()) {
295 find = true;
296 conflict.emplace_back(interRes.value(), bottomZs[i]);
297 break;
298 }
299 }
300 });
301
302 if (find) {
303 const void *ptr1 = conflict[0].first._obj1;
304 const void *ptr2 = conflict[0].first._obj2;
305 float conflictPrintZ = conflict[0].second;
306 if (wtdptr.has_value()) {
307 const FakeWipeTower *wtdp = wtdptr.value();
308 if (ptr1 == wtdp || ptr2 == wtdp) {
309 if (ptr2 == wtdp) { std::swap(ptr1, ptr2); }
310
311 const PrintInstance *inst2 = reinterpret_cast<const PrintInstance *>(ptr2);
312 const PrintObject *obj2 = inst2->print_object;
313 return std::make_optional<ConflictResult>("WipeTower", obj2->model_object()->name, conflictPrintZ, nullptr, inst2);
314 }
315 }
316
317 const PrintInstance *inst1 = reinterpret_cast<const PrintInstance *>(ptr1);
318 const PrintInstance *inst2 = reinterpret_cast<const PrintInstance *>(ptr2);
319 const PrintObject *obj1 = inst1->print_object;
320 const PrintObject *obj2 = inst2->print_object;
321 return std::make_optional<ConflictResult>(obj1->model_object()->name, obj2->model_object()->name, conflictPrintZ, inst1, inst2);
322 } else
323 return {};
324}
std::vector< LineWithID > LineWithIDs
Definition ConflictChecker.hpp:33
ObjectExtrusions getAllLayersExtrusionPathsFromObject(PrintObject *obj)
Definition ConflictChecker.cpp:204
auto range(Cont &&cont)
Definition libslic3r.h:405
RaycastManager::TrItems::iterator find(RaycastManager::TrItems &items, const RaycastManager::TrKey &key)
Definition RaycastManager.cpp:298