| 377 | } |
| 378 | |
| 379 | void weldPatchPool() |
| 380 | { |
| 381 | auto selectedPatches = selection::algorithm::getSelectedPatches(); |
| 382 | |
| 383 | // Sort these patches into buckets according to their parents |
| 384 | // This step may not be strictly necessary as weldPatches() checks the parents |
| 385 | // but we might save a bit of unnecessary comparison work |
| 386 | std::map<scene::INodePtr, std::vector<PatchNodePtr>> patchesByEntity; |
| 387 | |
| 388 | for (const auto& patch : selectedPatches) |
| 389 | { |
| 390 | patchesByEntity[patch->getParent()].push_back(patch); |
| 391 | } |
| 392 | |
| 393 | std::size_t numPatchesCreated = 0; |
| 394 | |
| 395 | for (const auto& pair : patchesByEntity) |
| 396 | { |
| 397 | // Try to combine each patch of this list with the rest of them O(2n) |
| 398 | for (auto p1 = pair.second.begin(); p1 != pair.second.end(); ++p1) |
| 399 | { |
| 400 | if (!(*p1)->getParent()) continue; // patch has been merged already |
| 401 | |
| 402 | for (auto p2 = p1 + 1; p2 != pair.second.end(); ++p2) |
| 403 | { |
| 404 | if (!(*p2)->getParent()) continue;// patch has been merged already |
| 405 | |
| 406 | try |
| 407 | { |
| 408 | weldPatches(*p1, *p2); |
| 409 | ++numPatchesCreated; |
| 410 | } |
| 411 | catch (const cmd::ExecutionFailure&) |
| 412 | { |
| 413 | continue; // failed to merge these two |
| 414 | } |
| 415 | } |
| 416 | } |
| 417 | } |
| 418 | |
| 419 | if (numPatchesCreated == 0) |
| 420 | { |
| 421 | throw cmd::ExecutionFailure(_("Cannot weld, patches need have the same parent entity.")); |
| 422 | } |
| 423 | } |
| 424 | |
| 425 | void weldSelectedPatches(const cmd::ArgumentList& args) |
| 426 | { |
no test coverage detected