This function unifies the old _rebuildDependencyList() and getDependencyList(). The algorithm basically obtains the object dependency by recrusivly visiting the OutList of each object in the given object array. It makes sure to call getOutList() of each object once and only once, which makes it much more efficient than calling getRecursiveOutList() on each individual object. The problem with the
| 2570 | // external object. |
| 2571 | // |
| 2572 | static void buildDependencyList(const std::vector<DocumentObject*>& objectArray, |
| 2573 | const int options, |
| 2574 | std::vector<DocumentObject*>* depObjs, |
| 2575 | DependencyList* depList, |
| 2576 | std::map<DocumentObject*, Vertex>* objectMap, |
| 2577 | bool* touchCheck = nullptr) |
| 2578 | { |
| 2579 | std::map<DocumentObject*, std::vector<DocumentObject*>> outLists; |
| 2580 | std::deque<DocumentObject*> objs; |
| 2581 | |
| 2582 | if (objectMap) { |
| 2583 | objectMap->clear(); |
| 2584 | } |
| 2585 | if (depList) { |
| 2586 | depList->clear(); |
| 2587 | } |
| 2588 | |
| 2589 | auto getOutListFineGrained = [](DocumentObject* obj, int op) { |
| 2590 | // Convert an OutListProp to a regular outlist with only DocumentObject* |
| 2591 | std::vector<DocumentObject*> outList; |
| 2592 | std::unordered_set<DocumentObject*> outListSet; // For O(1) avg lookup |
| 2593 | |
| 2594 | std::vector<DepEdge> outListProp = obj->getOutListProp(op); |
| 2595 | for (const auto& [objFrom, propFrom, objTo, propNameTo] : outListProp) { |
| 2596 | // Add dependencies on HEAD |
| 2597 | if (propNameTo.empty()) { |
| 2598 | if (outListSet.insert(objTo).second) { |
| 2599 | outList.push_back(objTo); |
| 2600 | } |
| 2601 | continue; |
| 2602 | } |
| 2603 | // Add additional dependencies on specific properties unless it is |
| 2604 | // an input property. This to avoid over dependencies. |
| 2605 | if (!outListSet.contains(objTo) && !objTo->isInputProperty(propNameTo)) { |
| 2606 | outListSet.insert(objTo); |
| 2607 | outList.push_back(objTo); |
| 2608 | } |
| 2609 | } |
| 2610 | |
| 2611 | return outList; |
| 2612 | }; |
| 2613 | |
| 2614 | const int op = ((options & Document::DepNoXLinked) != 0) ? DocumentObject::OutListNoXLinked : 0; |
| 2615 | for (auto obj : objectArray) { |
| 2616 | objs.push_back(obj); |
| 2617 | while (!objs.empty()) { |
| 2618 | auto objF = objs.front(); |
| 2619 | objs.pop_front(); |
| 2620 | if (!objF || !objF->isAttachedToDocument()) { |
| 2621 | continue; |
| 2622 | } |
| 2623 | |
| 2624 | auto it = outLists.find(objF); |
| 2625 | if (it != outLists.end()) { |
| 2626 | continue; |
| 2627 | } |
| 2628 | |
| 2629 | if (touchCheck) { |
no test coverage detected