Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2019-02-15 14:45:56 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-02-15 17:42:58 +0300
commit0ecd587991e474ead562e8d9326146ccaa179849 (patch)
treee0171cacca0ecfa678243a2ebae81aaadd26de92 /source/blender/depsgraph/intern/builder/deg_builder_rna.cc
parent373b8e311d28ee907d6e1fb291e5318fd74867b7 (diff)
Depsgraph: Move RNA lookup to an own query class
Currently should have no functional changes, but allows to implement runction optimizations more localized and easily.
Diffstat (limited to 'source/blender/depsgraph/intern/builder/deg_builder_rna.cc')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc262
1 files changed, 262 insertions, 0 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
new file mode 100644
index 00000000000..0f745cfe56a
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -0,0 +1,262 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file \ingroup depsgraph
+ */
+
+#include "intern/builder/deg_builder_rna.h"
+
+#include <cstring>
+
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+
+extern "C" {
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_key_types.h"
+#include "DNA_object_types.h"
+#include "DNA_sequence_types.h"
+}
+
+#include "BKE_constraint.h"
+
+#include "RNA_access.h"
+
+#include "intern/depsgraph.h"
+#include "intern/node/deg_node.h"
+#include "intern/node/deg_node_component.h"
+#include "intern/node/deg_node_id.h"
+#include "intern/node/deg_node_operation.h"
+
+namespace DEG {
+
+namespace {
+
+bool pointer_to_component_node_criteria(
+ const PointerRNA *ptr,
+ const PropertyRNA *prop,
+ RNAPointerSource /*source*/,
+ ID **id,
+ NodeType *type,
+ const char **component_name,
+ OperationCode *operation_code,
+ const char **operation_name,
+ int *operation_name_tag)
+{
+ if (ptr->type == NULL) {
+ return false;
+ }
+ /* Set default values for returns. */
+ *id = (ID *)ptr->id.data;
+ *component_name = "";
+ *operation_code = OperationCode::OPERATION;
+ *operation_name = "";
+ *operation_name_tag = -1;
+ /* Handling of commonly known scenarios. */
+ if (ptr->type == &RNA_PoseBone) {
+ bPoseChannel *pchan = (bPoseChannel *)ptr->data;
+ if (prop != NULL && RNA_property_is_idprop(prop)) {
+ *type = NodeType::PARAMETERS;
+ *operation_code = OperationCode::ID_PROPERTY;
+ *operation_name = RNA_property_identifier((PropertyRNA *)prop);
+ *operation_name_tag = -1;
+ }
+ else {
+ /* Bone - generally, we just want the bone component. */
+ *type = NodeType::BONE;
+ *component_name = pchan->name;
+ /* But B-Bone properties should connect to the actual operation. */
+ if (!ELEM(NULL, pchan->bone, prop) && pchan->bone->segments > 1 &&
+ STRPREFIX(RNA_property_identifier(prop), "bbone_"))
+ {
+ *operation_code = OperationCode::BONE_SEGMENTS;
+ }
+ }
+ return true;
+ }
+ else if (ptr->type == &RNA_Bone) {
+ Bone *bone = (Bone *)ptr->data;
+ /* armature-level bone, but it ends up going to bone component anyway */
+ // NOTE: the ID in this case will end up being bArmature.
+ *type = NodeType::BONE;
+ *component_name = bone->name;
+ return true;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
+ Object *object = (Object *)ptr->id.data;
+ bConstraint *con = (bConstraint *)ptr->data;
+ /* Check whether is object or bone constraint. */
+ /* NOTE: Currently none of the area can address transform of an object
+ * at a given constraint, but for rigging one might use constraint
+ * influence to be used to drive some corrective shape keys or so. */
+ if (BLI_findindex(&object->constraints, con) != -1) {
+ *type = NodeType::TRANSFORM;
+ *operation_code = OperationCode::TRANSFORM_LOCAL;
+ return true;
+ }
+ else if (object->pose != NULL) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ if (BLI_findindex(&pchan->constraints, con) != -1) {
+ *type = NodeType::BONE;
+ *operation_code = OperationCode::BONE_LOCAL;
+ *component_name = pchan->name;
+ return true;
+ }
+ }
+ }
+ }
+ else if (ELEM(ptr->type, &RNA_ConstraintTarget, &RNA_ConstraintTargetBone)) {
+ Object *object = (Object *)ptr->id.data;
+ bConstraintTarget *tgt = (bConstraintTarget *)ptr->data;
+ /* Check whether is object or bone constraint. */
+ bPoseChannel *pchan = NULL;
+ bConstraint *con = BKE_constraint_find_from_target(object, tgt, &pchan);
+ if (con != NULL) {
+ if (pchan != NULL) {
+ *type = NodeType::BONE;
+ *operation_code = OperationCode::BONE_LOCAL;
+ *component_name = pchan->name;
+ }
+ else {
+ *type = NodeType::TRANSFORM;
+ *operation_code = OperationCode::TRANSFORM_LOCAL;
+ }
+ return true;
+ }
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_Modifier)) {
+ *type = NodeType::GEOMETRY;
+ return true;
+ }
+ else if (ptr->type == &RNA_Object) {
+ /* Transforms props? */
+ if (prop != NULL) {
+ const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
+ /* TODO(sergey): How to optimize this? */
+ if (strstr(prop_identifier, "location") ||
+ strstr(prop_identifier, "rotation") ||
+ strstr(prop_identifier, "scale") ||
+ strstr(prop_identifier, "matrix_"))
+ {
+ *type = NodeType::TRANSFORM;
+ return true;
+ }
+ else if (strstr(prop_identifier, "data")) {
+ /* We access object.data, most likely a geometry.
+ * Might be a bone tho. */
+ *type = NodeType::GEOMETRY;
+ return true;
+ }
+ }
+ }
+ else if (ptr->type == &RNA_ShapeKey) {
+ KeyBlock *key_block = (KeyBlock *)ptr->data;
+ *id = (ID *)ptr->id.data;
+ *type = NodeType::PARAMETERS;
+ *operation_code = OperationCode::PARAMETERS_EVAL;
+ *operation_name = key_block->name;
+ return true;
+ }
+ else if (ptr->type == &RNA_Key) {
+ *id = (ID *)ptr->id.data;
+ *type = NodeType::GEOMETRY;
+ return true;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
+ Sequence *seq = (Sequence *)ptr->data;
+ /* Sequencer strip */
+ *type = NodeType::SEQUENCER;
+ *component_name = seq->name;
+ return true;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
+ *type = NodeType::SHADING;
+ return true;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_ShaderNode)) {
+ *type = NodeType::SHADING;
+ return true;
+ }
+ else if (ELEM(ptr->type, &RNA_Curve, &RNA_TextCurve)) {
+ *id = (ID *)ptr->id.data;
+ *type = NodeType::GEOMETRY;
+ return true;
+ }
+ if (prop != NULL) {
+ /* All unknown data effectively falls under "parameter evaluation". */
+ if (RNA_property_is_idprop(prop)) {
+ *type = NodeType::PARAMETERS;
+ *operation_code = OperationCode::ID_PROPERTY;
+ *operation_name = RNA_property_identifier((PropertyRNA *)prop);
+ *operation_name_tag = -1;
+ }
+ else {
+ *type = NodeType::PARAMETERS;
+ *operation_code = OperationCode::PARAMETERS_EVAL;
+ *operation_name = "";
+ *operation_name_tag = -1;
+ }
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
+RNANodeQuery::RNANodeQuery(Depsgraph *depsgraph)
+ : depsgraph_(depsgraph)
+{
+}
+
+Node *RNANodeQuery::find_node(const PointerRNA *ptr,
+ const PropertyRNA *prop,
+ RNAPointerSource source)
+{
+ ID *id;
+ NodeType node_type;
+ const char *component_name, *operation_name;
+ OperationCode operation_code;
+ int operation_name_tag;
+ if (pointer_to_component_node_criteria(
+ ptr, prop, source,
+ &id, &node_type, &component_name,
+ &operation_code, &operation_name, &operation_name_tag))
+ {
+ IDNode *id_node = depsgraph_->find_id_node(id);
+ if (id_node == NULL) {
+ return NULL;
+ }
+ ComponentNode *comp_node =
+ id_node->find_component(node_type, component_name);
+ if (comp_node == NULL) {
+ return NULL;
+ }
+ if (operation_code == OperationCode::OPERATION) {
+ return comp_node;
+ }
+ return comp_node->find_operation(operation_code,
+ operation_name,
+ operation_name_tag);
+ }
+ return NULL;
+}
+
+} // namespace DEG