Instead of the monolothic `depsgraph_type.hh` header that includes most types used in the despgraph, just add includes where they are actually necessary. Also remove the `using` keywords for `std` types. The lack of specificity isn't considered good practice nowadays. Removing unnecessary transitive includes can help improve compile times because the time spent parsing headers decreases. Using the "include what you use" pattern makes futher improvements much easier too, since it the path to further reduce transitive includes becomes much clearer. Pull Request: https://projects.blender.org/blender/blender/pulls/133749
102 lines
2.9 KiB
C++
102 lines
2.9 KiB
C++
/* SPDX-FileCopyrightText: 2020 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup depsgraph
|
|
*/
|
|
|
|
#include <deque>
|
|
|
|
#include "intern/builder/deg_builder_remove_noop.h"
|
|
|
|
#include "intern/node/deg_node.hh"
|
|
#include "intern/node/deg_node_operation.hh"
|
|
|
|
#include "intern/debug/deg_debug.h"
|
|
#include "intern/depsgraph.hh"
|
|
#include "intern/depsgraph_relation.hh"
|
|
|
|
#include "DEG_depsgraph_debug.hh"
|
|
|
|
namespace blender::deg {
|
|
|
|
static inline bool is_unused_noop(OperationNode *op_node)
|
|
{
|
|
if (op_node == nullptr) {
|
|
return false;
|
|
}
|
|
if (op_node->flag & OperationFlag::DEPSOP_FLAG_PINNED) {
|
|
return false;
|
|
}
|
|
return op_node->is_noop() && op_node->outlinks.is_empty();
|
|
}
|
|
|
|
static inline bool is_removable_relation(const Relation *relation)
|
|
{
|
|
if (relation->from->type != NodeType::OPERATION || relation->to->type != NodeType::OPERATION) {
|
|
return true;
|
|
}
|
|
|
|
const OperationNode *operation_from = static_cast<OperationNode *>(relation->from);
|
|
const OperationNode *operation_to = static_cast<OperationNode *>(relation->to);
|
|
|
|
/* If the relation connects two different IDs there is a high risk that the removal of the
|
|
* relation will make it so visibility flushing is not possible at runtime. This happens with
|
|
* relations like the DoF on camera of custom shape on bones: such relation do not lead to an
|
|
* actual depsgraph evaluation operation as they are handled on render engine level.
|
|
*
|
|
* The indirectly linked objects could have some of their components invisible as well, so
|
|
* also keep relations which connect different components of the same object so that visibility
|
|
* tracking happens correct in those cases as well. */
|
|
return operation_from->owner == operation_to->owner;
|
|
}
|
|
|
|
void deg_graph_remove_unused_noops(Depsgraph *graph)
|
|
{
|
|
std::deque<OperationNode *> queue;
|
|
|
|
for (OperationNode *node : graph->operations) {
|
|
if (is_unused_noop(node)) {
|
|
queue.push_back(node);
|
|
}
|
|
}
|
|
|
|
Vector<Relation *> relations_to_remove;
|
|
|
|
while (!queue.empty()) {
|
|
OperationNode *to_remove = queue.front();
|
|
queue.pop_front();
|
|
|
|
for (Relation *rel_in : to_remove->inlinks) {
|
|
if (!is_removable_relation(rel_in)) {
|
|
continue;
|
|
}
|
|
|
|
Node *dependency = rel_in->from;
|
|
relations_to_remove.append(rel_in);
|
|
|
|
/* Queue parent no-op node that has now become unused. */
|
|
OperationNode *operation = dependency->get_exit_operation();
|
|
if (is_unused_noop(operation)) {
|
|
queue.push_back(operation);
|
|
}
|
|
}
|
|
|
|
/* TODO(Sybren): Remove the node itself. */
|
|
}
|
|
|
|
/* Remove the relations. */
|
|
for (Relation *relation : relations_to_remove) {
|
|
relation->unlink();
|
|
delete relation;
|
|
}
|
|
|
|
DEG_DEBUG_PRINTF((::Depsgraph *)graph,
|
|
BUILD,
|
|
"Removed %d relations to no-op nodes\n",
|
|
int(relations_to_remove.size()));
|
|
}
|
|
|
|
} // namespace blender::deg
|