MCPcopy Create free account
hub / github.com/AcademySoftwareFoundation/MaterialX / topologicalSort

Method topologicalSort

source/MaterialXCore/Node.cpp:406–475  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

404}
405
406ElementVec GraphElement::topologicalSort() const
407{
408 // Calculate a topological order of the children, using Kahn's algorithm
409 // to avoid recursion.
410 //
411 // Running time: O(numNodes + numEdges).
412
413 const ElementVec& children = getChildren();
414
415 // Calculate in-degrees for all children.
416 std::unordered_map<ElementPtr, size_t> inDegree(children.size());
417 std::deque<ElementPtr> childQueue;
418 for (ElementPtr child : children)
419 {
420 size_t connectionCount = 0;
421 for (size_t i = 0; i < child->getUpstreamEdgeCount(); ++i)
422 {
423 Edge upstreamEdge = child->getUpstreamEdge(i);
424 if (upstreamEdge)
425 {
426 if (upstreamEdge.getUpstreamElement())
427 {
428 ElementPtr elem = upstreamEdge.getUpstreamElement()->getParent();
429 if (elem == child->getParent())
430 {
431 connectionCount++;
432 }
433 }
434 }
435 }
436
437 inDegree[child] = connectionCount;
438
439 // Enqueue children with in-degree 0.
440 if (connectionCount == 0)
441 {
442 childQueue.push_back(child);
443 }
444 }
445
446 ElementVec result;
447 while (!childQueue.empty())
448 {
449 // Pop the queue and add to topological order.
450 ElementPtr child = childQueue.front();
451 childQueue.pop_front();
452 result.push_back(child);
453
454 // Find connected nodes and decrease their in-degree,
455 // adding node to the queue if in-degrees becomes 0.
456 if (child->isA<Node>())
457 {
458 for (PortElementPtr port : child->asA<Node>()->getDownstreamPorts())
459 {
460 const ElementPtr downstreamElem = port->isA<Output>() ? port : port->getParent();
461 if (inDegree[downstreamElem] > 1)
462 {
463 inDegree[downstreamElem]--;

Callers 1

Node.cppFile · 0.45

Calls 6

getUpstreamElementMethod · 0.80
push_backMethod · 0.80
getDownstreamPortsMethod · 0.80
sizeMethod · 0.45
getUpstreamEdgeMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected