Beispiel #1
0
void copyTree(VisualNode* node_t, NodeTree& tree_t,
              const VisualNode* node_s, const NodeTree& tree_s) {

  auto& na_t = tree_t.getNA();
  const auto& na_s = tree_s.getNA();

  stack<VisualNode*> stk_t;
  stack<const VisualNode*> stk_s;

  stk_s.push(node_s);
  stk_t.push(node_t);

  while (stk_s.size() > 0) {

      const VisualNode* n = stk_s.top(); stk_s.pop();
      VisualNode*    next = stk_t.top(); stk_t.pop();

      auto kids = n->getNumberOfChildren();
      next->setNumberOfChildren(kids, na_t);

      next->setStatus(n->getStatus());
      next->dirtyUp(na_t);

      for (auto i = 0u; i < kids; ++i) {
          stk_s.push(n->getChild(na_s, i));
          stk_t.push(next->getChild(na_t, i));
      }
  }

}
Beispiel #2
0
void applyToEachNodePO(NodeTree& nt, const NodeAction& action) {

  /// PO-traversal requires two stacks
  std::stack<VisualNode*> stk_1;
  std::stack<VisualNode*> stk_2;

  auto* root = nt.getRoot();
  auto& na = nt.getNA();

  stk_1.push(root);

  while (stk_1.size() > 0) {
    auto* node = stk_1.top(); stk_1.pop();

    stk_2.push(node);

    for (auto i = 0u; i < node->getNumberOfChildren(); ++i) {
      auto kid = node->getChild(na, i);
      stk_1.push(kid);
    }
  }

  while (stk_2.size() > 0) {
    auto* node = stk_2.top(); stk_2.pop();

    action(node);
  }

}
Beispiel #3
0
void applyToEachNode(NodeTree& nt, const NodeAction& action) {
  auto& na = nt.getNA();

  for (int i = 0; i < na.size(); ++i) {
    action(na[i]);
  }
}
Beispiel #4
0
void highlightSubtrees(NodeTree& nt, const std::vector<VisualNode*>& nodes) {

  QMutexLocker lock(&nt.getMutex());

  auto& na = nt.getNA();
  auto* root = nt.getRoot();

  root->unhideAll(na);

  {
    QMutexLocker lock(&nt.getLayoutMutex());
    root->layout(na);
  }

  // unhighlight all
  applyToEachNode(nt, [](VisualNode* n) {
    n->setHighlighted(false);
  });

  for (auto node : nodes) {
    node->setHighlighted(true);
  }

  // TODO: hide not highlighted
  // HideNotHighlightedCursor hnhc(root, na);
  // PostorderNodeVisitor<HideNotHighlightedCursor>(hnhc).run();

  nt.treeModified();

}
Beispiel #5
0
int calculateMaxDepth(const NodeTree& nt) {

  const auto& na = nt.getNA();
  const auto* root = nt.getRoot();

  return calcDepth(na, root);
}
Beispiel #6
0
int calculateDepth(const NodeTree& nt, const VisualNode& node) {
  int count = 0;

  auto it = &node;
  auto& na = nt.getNA();

  while ( (it = it->getParent(na)) ) { count++; }

  return count;
}
Beispiel #7
0
void addChildren(VisualNode* node, NodeTree& nt, int kids) {

  auto& na = nt.getNA();

  node->setNumberOfChildren(kids, na);
  node->dirtyUp(na);

  auto& stats = nt.getStatistics();
  stats.undetermined += kids;

  int depth = tree_utils::calculateDepth(nt, *node) + 1;
  int new_depth = depth + 1;

  stats.maxDepth = std::max(stats.maxDepth, new_depth);

};
Beispiel #8
0
void applyToEachNode(NodeTree& nt, VisualNode* node, const NodeAction& action) {

  auto& na = nt.getNA();

  std::stack<VisualNode*> stk;

  stk.push(node);

  while(stk.size() > 0) {

    auto* curr_node = stk.top(); stk.pop();
    action(curr_node);

    for (auto i = 0u; i < curr_node->getNumberOfChildren(); ++i) {
      auto child = curr_node->getChild(na, i);
      stk.push(child);
    }
  }
}
//--------------------------------------------
//-------- FINDING IDENTICAL SUBTREES --------
//--------------------------------------------
// TODO/NOTE(maxim): This algorithm isn't supposed to work
// (new groups pushed to the end), but I've failed
// to find any cases where it produces a wrong result
GroupsOfNodes_t findIdenticalShapes(NodeTree& nt) {
  /// ------ 0) group by height ------
  std::vector<Group> groups = groupByHeight(nt);

  /// ------ 1) assign a group id to each node -------
  std::unordered_map<const VisualNode*, PosInGroups> node2groupID;
  for (auto group_idx = 1u; group_idx < groups.size(); ++group_idx) {
    auto& group = groups[group_idx];

    for (auto i = 0u; i < group.items.size(); ++i) {
      auto* node = group.items[i].node;
      node2groupID[node].g_id = group_idx;
      node2groupID[node].inner_idx = i;
    }
  }

  // printGroups(groups);
  // qDebug() << " ";

  /// ------ 2) select the first block (with height 1)

  for (auto group_id = 0u; group_id < groups.size(); ++group_id) {

    for (auto alt = 0; alt < 2; ++alt) {

      auto& block = groups[group_id];

      std::vector<int> groups_to_split;

      // qDebug() << "left children:";
      for (auto& e : block.items) {
        if (e.alt == alt) {
          /// 3.1) get its parent
          auto& na = nt.getNA();
          auto parent = e.node->getParent(na);
          // std::cerr << parent->debug_id << " ";

          /// 3.2 )find it in groups

          auto location = detail::findNodeInGroups(groups, node2groupID, parent);

          // std::cerr << parent->debug_id << " in group: " << location.first << "\n";

          /// group g_idx will potentially need splitting
          auto g_idx = location.first;
          groups_to_split.push_back(g_idx); /// NOTE(maxim): has duplicate elements (?)

          detail::separateNode(groups[g_idx], node2groupID, location.second);
          // qDebug() << "node: " << e.node->debug_id;
          // qDebug() << "separate: " << parent->debug_id;
          /// split only affected groups
        }
      }

      // qDebug() << "groups before:";
      // printGroups(groups);
      detail::splitGroups(groups, groups_to_split, node2groupID);
      // qDebug() << "groups after:";
      // printGroups(groups);
      // qDebug() << " ";
      groups_to_split.clear();
      // qDebug() << "groups: " << groups;
    }
  }
/// ----- sort the groups -----
#ifdef MAXIM_DEBUG
  sort(begin(groups), end(groups), [](const Group& lhs, const Group& rhs) {
    if (lhs.items.size() == 0 && rhs.items.size() == 0) {
      return false;
    }
    if (lhs.items.size() == 0) {
      return false;
    }
    if (rhs.items.size() == 0) {
      return true;
    }
    return lhs.items[0].node->debug_id < rhs.items[0].node->debug_id;
  });
#endif


  /// convert groups to a vector of vectors of Nodes

  std::vector<std::vector<VisualNode*>> result(groups.size());
  for (auto i = 0u; i < groups.size(); ++i) {
    auto& items = groups[i].items;

    result[i].reserve(items.size());

    // qDebug() << "copying " << items.size() << " elements";
    for (auto j = 0u; j < items.size(); ++j) {
      result[i].push_back(items[j].node);
    }
  }

  return result;
}