diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-11-07 17:46:27 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-11-07 17:46:27 +0300 |
commit | c1ba58c44dd771770037707cd06eb312e015280f (patch) | |
tree | f1a58e6c8a133f6482e9b5eff73ef90bc759de90 /source/blender | |
parent | 93dbd81796df663598df26119e1e1a5c595be840 (diff) | |
parent | e74e622776a53e4ab5696d4b6fd17638dc2e9210 (diff) |
Merge branch 'master' into blender2.8
Conflicts:
intern/cycles/blender/addon/properties.py
Diffstat (limited to 'source/blender')
37 files changed, 850 insertions, 402 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index c2323100205..78d6f6c7cb9 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -97,6 +97,7 @@ void BKE_armature_where_is(struct bArmature *arm); void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion); void BKE_pose_clear_pointers(struct bPose *pose); void BKE_pose_rebuild(struct Object *ob, struct bArmature *arm); +void BKE_pose_rebuild_ex(struct Object *ob, struct bArmature *arm, const bool sort_bones); void BKE_pose_where_is(struct Scene *scene, struct Object *ob); void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra); void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index c644fe09364..cc508aa0511 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1781,6 +1781,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected BLI_duplicatelist(&pose->agroups, &frompose->agroups); pose->active_group = frompose->active_group; + BKE_pose_channels_hash_make(frompose); for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { pchanp = BKE_pose_channel_find_name(frompose, pchan->name); @@ -1916,7 +1917,7 @@ void BKE_pose_clear_pointers(bPose *pose) /* only after leave editmode, duplicating, validating older files, library syncing */ /* NOTE: pose->flag is set for it */ -void BKE_pose_rebuild(Object *ob, bArmature *arm) +void BKE_pose_rebuild_ex(Object *ob, bArmature *arm, const bool sort_bones) { Bone *bone; bPose *pose; @@ -1963,8 +1964,9 @@ void BKE_pose_rebuild(Object *ob, bArmature *arm) #ifdef WITH_LEGACY_DEPSGRAPH /* the sorting */ /* Sorting for new dependnecy graph is done on the scene graph level. */ - if (counter > 1) + if (counter > 1 && sort_bones) { DAG_pose_sort(ob); + } #endif ob->pose->flag &= ~POSE_RECALC; @@ -1973,6 +1975,11 @@ void BKE_pose_rebuild(Object *ob, bArmature *arm) BKE_pose_channels_hash_make(ob->pose); } +void BKE_pose_rebuild(Object *ob, bArmature *arm) +{ + BKE_pose_rebuild_ex(ob, arm, true); +} + /* ********************** THE POSE SOLVER ******************* */ /* loc/rot/size to given mat4 */ diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index 6a08673144e..deeb35bd880 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -93,7 +93,9 @@ void BKE_cachefile_free(CacheFile *cache_file) ABC_free_handle(cache_file->handle); #endif - BLI_mutex_free(cache_file->handle_mutex); + if (cache_file->handle_mutex) { + BLI_mutex_free(cache_file->handle_mutex); + } BLI_freelistN(&cache_file->object_paths); } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 9abf09a0944..f747bdb91fa 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1761,7 +1761,8 @@ void BKE_library_make_local( it->link = NULL; do_loop = true; } - else { /* Only used by linked data, potential candidate to ugly lib-only dependency cycles... */ + /* Only used by linked data, potential candidate to ugly lib-only dependency cycles... */ + else if ((id->tag & LIB_TAG_DOIT) == 0) { /* Check TAG_DOIT to avoid adding same ID several times... */ /* Note that we store the node, not directly ID pointer, that way if it->link is set to NULL * later we can skip it in lib-dependency cycles search later. */ BLI_linklist_prepend_arena(&linked_loop_candidates, it, linklist_mem); @@ -1804,6 +1805,7 @@ void BKE_library_make_local( BKE_libblock_unlink(bmain, id, false, false); BKE_libblock_free(bmain, id); #endif + ((LinkNode *)it->link)->link = NULL; /* Not strictly necessary, but safer (see T49903)... */ it->link = NULL; } } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index fa113ef5eef..016c9c863f0 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -58,6 +58,7 @@ #include "BLI_strict_flags.h" +#include "atomic_ops.h" #include "mikktspace.h" // #define DEBUG_TIME @@ -236,7 +237,9 @@ static void mesh_calc_normals_poly_accum_task_cb(void *userdata, const int pidx) const float fac = saacos(-dot_v3v3(cur_edge, prev_edge)); /* accumulate */ - madd_v3_v3fl(vnors[ml[i].v], pnor, fac); + for (int k = 3; k--; ) { + atomic_add_fl(&vnors[ml[i].v][k], pnor[k] * fac); + } prev_edge = cur_edge; } } diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 9eefcbe4885..73678187e80 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -799,6 +799,18 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z); RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z); + RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X); + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x); + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x); + + RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y); + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y); + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y); + + RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z); + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z); + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z); + RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint); /* fall-through */ case RBC_TYPE_6DOF: @@ -1057,9 +1069,15 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *UNUSED(scene), Object *ob, rbc->spring_damping_x = 0.5f; rbc->spring_damping_y = 0.5f; rbc->spring_damping_z = 0.5f; + rbc->spring_damping_ang_x = 0.5f; + rbc->spring_damping_ang_y = 0.5f; + rbc->spring_damping_ang_z = 0.5f; rbc->spring_stiffness_x = 10.0f; rbc->spring_stiffness_y = 10.0f; rbc->spring_stiffness_z = 10.0f; + rbc->spring_stiffness_ang_x = 10.0f; + rbc->spring_stiffness_ang_y = 10.0f; + rbc->spring_stiffness_ang_z = 10.0f; rbc->motor_lin_max_impulse = 1.0f; rbc->motor_lin_target_velocity = 1.0f; diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index e9c51d5dc38..529233c0dac 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -52,6 +52,7 @@ #include "DNA_actuator_types.h" #include "DNA_view3d_types.h" #include "DNA_smoke_types.h" +#include "DNA_rigidbody_types.h" #include "DNA_genfile.h" @@ -1359,5 +1360,20 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } } + + if (!DNA_struct_elem_find(fd->filesdna, "RigidBodyCon", "float", "spring_stiffness_ang_x")) { + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + RigidBodyCon *rbc = ob->rigidbody_constraint; + if (rbc) { + rbc->spring_stiffness_ang_x = 10.0; + rbc->spring_stiffness_ang_y = 10.0; + rbc->spring_stiffness_ang_z = 10.0; + rbc->spring_damping_ang_x = 0.5; + rbc->spring_damping_ang_y = 0.5; + rbc->spring_damping_ang_z = 0.5; + } + } + } } } diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp index b16e2e2b0d3..908111ebae6 100644 --- a/source/blender/collada/TransformWriter.cpp +++ b/source/blender/collada/TransformWriter.cpp @@ -113,11 +113,6 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob, B node.addMatrix("transform",d_obmat); break; } - case BC_TRANSFORMATION_TYPE_BOTH: - { - node.addMatrix("transform",d_obmat); - /* fall-through */ - } case BC_TRANSFORMATION_TYPE_TRANSROTLOC: { float loc[3], rot[3], scale[3]; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 0017c66836a..a4416608584 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -43,8 +43,7 @@ typedef enum BC_export_mesh_type { typedef enum BC_export_transformation_type { BC_TRANSFORMATION_TYPE_MATRIX, - BC_TRANSFORMATION_TYPE_TRANSROTLOC, - BC_TRANSFORMATION_TYPE_BOTH + BC_TRANSFORMATION_TYPE_TRANSROTLOC } BC_export_transformation_type; struct bContext; diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp index bba5c8702b8..6bfd8ae3888 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cpp +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -118,7 +118,7 @@ void TextureBaseOperation::executePixelSampled(float output[4], float x, float y * interpolaiton and (b) in such configuration multitex() sinply floor's the value * which often produces artifacts. */ - if ((m_texture->imaflag & TEX_INTERPOL) == 0) { + if (m_texture != NULL && (m_texture->imaflag & TEX_INTERPOL) == 0) { u += 0.5f / cx; v += 0.5f / cy; } diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index fd2a521bec5..ab12a8d5b3e 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -45,6 +45,7 @@ set(SRC intern/builder/deg_builder_nodes.cc intern/builder/deg_builder_pchanmap.cc intern/builder/deg_builder_relations.cc + intern/builder/deg_builder_relations_keys.cc intern/builder/deg_builder_transitive.cc intern/debug/deg_debug_graphviz.cc intern/eval/deg_eval.cc diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc index 225cc64ae4d..d84a590b29f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc @@ -56,12 +56,14 @@ struct StackEntry { void deg_graph_detect_cycles(Depsgraph *graph) { - /* Not is not visited at all during traversal. */ - const int NODE_NOT_VISITED = 0; - /* Node has been visited during traversal and not in current stack. */ - const int NODE_VISITED = 1; - /* Node has been visited during traversal and is in current stack. */ - const int NODE_IN_STACK = 2; + enum { + /* Not is not visited at all during traversal. */ + NODE_NOT_VISITED = 0, + /* Node has been visited during traversal and not in current stack. */ + NODE_VISITED = 1, + /* Node has been visited during traversal and is in current stack. */ + NODE_IN_STACK = 2, + }; std::stack<StackEntry> traversal_stack; foreach (OperationDepsNode *node, graph->operations) { @@ -77,21 +79,23 @@ void deg_graph_detect_cycles(Depsgraph *graph) entry.from = NULL; entry.via_relation = NULL; traversal_stack.push(entry); - node->done = NODE_IN_STACK; + node->tag = NODE_IN_STACK; } else { - node->done = NODE_NOT_VISITED; + node->tag = NODE_NOT_VISITED; } + node->done = 0; } while (!traversal_stack.empty()) { - StackEntry &entry = traversal_stack.top(); + StackEntry entry = traversal_stack.top(); OperationDepsNode *node = entry.node; bool all_child_traversed = true; - foreach (DepsRelation *rel, node->outlinks) { + for (int i = node->done; i < node->outlinks.size(); ++i) { + DepsRelation *rel = node->outlinks[i]; if (rel->to->type == DEPSNODE_TYPE_OPERATION) { OperationDepsNode *to = (OperationDepsNode *)rel->to; - if (to->done == NODE_IN_STACK) { + if (to->tag == NODE_IN_STACK) { printf("Dependency cycle detected:\n"); printf(" '%s' depends on '%s' through '%s'\n", to->full_identifier().c_str(), @@ -107,23 +111,24 @@ void deg_graph_detect_cycles(Depsgraph *graph) current->via_relation->name); current = current->from; } - /* TODO(sergey): So called roussian rlette cycle solver. */ + /* TODO(sergey): So called russian roulette cycle solver. */ rel->flag |= DEPSREL_FLAG_CYCLIC; } - else if (to->done == NODE_NOT_VISITED) { + else if (to->tag == NODE_NOT_VISITED) { StackEntry new_entry; new_entry.node = to; new_entry.from = &entry; new_entry.via_relation = rel; traversal_stack.push(new_entry); - to->done = NODE_IN_STACK; + to->tag = NODE_IN_STACK; all_child_traversed = false; + node->done = i; break; } } } if (all_child_traversed) { - node->done = NODE_VISITED; + node->tag = NODE_VISITED; traversal_stack.pop(); } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index c470e6fb239..5230e7a38b0 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -34,7 +34,6 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> #include "MEM_guardedalloc.h" @@ -129,8 +128,7 @@ RootDepsNode *DepsgraphNodeBuilder::add_root_node() IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id) { - const char *idtype_name = BKE_idcode_to_name(GS(id->name)); - return m_graph->add_id_node(id, string(id->name + 2) + "[" + idtype_name + "]"); + return m_graph->add_id_node(id, id->name); } TimeSourceDepsNode *DepsgraphNodeBuilder::add_time_source(ID *id) @@ -177,7 +175,7 @@ TimeSourceDepsNode *DepsgraphNodeBuilder::add_time_source(ID *id) ComponentDepsNode *DepsgraphNodeBuilder::add_component_node( ID *id, eDepsNode_Type comp_type, - const string &comp_name) + const char *comp_name) { IDDepsNode *id_node = add_id_node(id); ComponentDepsNode *comp_node = id_node->add_component(comp_type, comp_name); @@ -190,15 +188,19 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string &description) + const char *name, + int name_tag) { - OperationDepsNode *op_node = comp_node->has_operation(opcode, description); + OperationDepsNode *op_node = comp_node->has_operation(opcode, + name, + name_tag); if (op_node == NULL) { - op_node = comp_node->add_operation(optype, op, opcode, description); + op_node = comp_node->add_operation(optype, op, opcode, name, name_tag); m_graph->operations.push_back(op_node); } else { - fprintf(stderr, "add_operation: Operation already exists - %s has %s at %p\n", + fprintf(stderr, + "add_operation: Operation already exists - %s has %s at %p\n", comp_node->identifier().c_str(), op_node->identifier().c_str(), op_node); @@ -210,14 +212,15 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( ID *id, eDepsNode_Type comp_type, - const string &comp_name, + const char *comp_name, eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string &description) + const char *name, + int name_tag) { ComponentDepsNode *comp_node = add_component_node(id, comp_type, comp_name); - return add_operation_node(comp_node, optype, op, opcode, description); + return add_operation_node(comp_node, optype, op, opcode, name, name_tag); } OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( @@ -226,38 +229,54 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string& description) + const char *name, + int name_tag) { - return add_operation_node(id, comp_type, "", optype, op, opcode, description); + return add_operation_node(id, + comp_type, + "", + optype, + op, + opcode, + name, + name_tag); } bool DepsgraphNodeBuilder::has_operation_node(ID *id, eDepsNode_Type comp_type, - const string &comp_name, + const char *comp_name, eDepsOperation_Code opcode, - const string &description) + const char *name, + int name_tag) { - return find_operation_node(id, comp_type, comp_name, opcode, description) != NULL; + return find_operation_node(id, + comp_type, + comp_name, + opcode, + name, + name_tag) != NULL; } OperationDepsNode *DepsgraphNodeBuilder::find_operation_node( ID *id, eDepsNode_Type comp_type, - const string &comp_name, + const char *comp_name, eDepsOperation_Code opcode, - const string &description) + const char *name, + int name_tag) { ComponentDepsNode *comp_node = add_component_node(id, comp_type, comp_name); - return comp_node->has_operation(opcode, description); + return comp_node->has_operation(opcode, name, name_tag); } OperationDepsNode *DepsgraphNodeBuilder::find_operation_node( ID *id, eDepsNode_Type comp_type, eDepsOperation_Code opcode, - const string& description) + const char *name, + int name_tag) { - return find_operation_node(id, comp_type, "", opcode, description); + return find_operation_node(id, comp_type, "", opcode, name, name_tag); } /* **** Build functions for entity nodes **** */ @@ -610,12 +629,17 @@ OperationDepsNode *DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu) OperationDepsNode *driver_op = find_operation_node(id, DEPSNODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, - deg_fcurve_id_name(fcu)); + fcu->rna_path, + fcu->array_index); if (driver_op == NULL) { - driver_op = add_operation_node(id, DEPSNODE_TYPE_PARAMETERS, - DEPSOP_TYPE_EXEC, function_bind(BKE_animsys_eval_driver, _1, id, fcu), - DEG_OPCODE_DRIVER, deg_fcurve_id_name(fcu)); + driver_op = add_operation_node(id, + DEPSNODE_TYPE_PARAMETERS, + DEPSOP_TYPE_EXEC, + function_bind(BKE_animsys_eval_driver, _1, id, fcu), + DEG_OPCODE_DRIVER, + fcu->rna_path, + fcu->array_index); } /* tag "scripted expression" drivers as needing Python (due to GIL issues, etc.) */ @@ -760,7 +784,7 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob) /* Rebuild pose if not up to date. */ if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) { - BKE_pose_rebuild(ob, arm); + BKE_pose_rebuild_ex(ob, arm, false); /* XXX: Without this animation gets lost in certain circumstances * after loading file. Need to investigate further since it does * not happen with simple scenes.. @@ -1124,15 +1148,20 @@ void DepsgraphNodeBuilder::build_nodetree(DepsNode *owner_node, bNodeTree *ntree /* nodetree's nodes... */ for (bNode *bnode = (bNode *)ntree->nodes.first; bnode; bnode = bnode->next) { - if (bnode->id) { - if (GS(bnode->id->name) == ID_MA) { - build_material(owner_node, (Material *)bnode->id); + ID *id = bnode->id; + if (id != NULL) { + short id_type = GS(id->name); + if (id_type == ID_MA) { + build_material(owner_node, (Material *)id); } - else if (bnode->type == ID_TE) { - build_texture(owner_node, (Tex *)bnode->id); + else if (id_type == ID_TE) { + build_texture(owner_node, (Tex *)id); + } + else if (id_type == ID_IM) { + build_image((Image *)id); } else if (bnode->type == NODE_GROUP) { - bNodeTree *group_ntree = (bNodeTree *)bnode->id; + bNodeTree *group_ntree = (bNodeTree *)id; if ((group_ntree->id.tag & LIB_TAG_DOIT) == 0) { build_nodetree(owner_node, group_ntree); } @@ -1189,10 +1218,33 @@ void DepsgraphNodeBuilder::build_texture(DepsNode *owner_node, Tex *tex) return; } tex_id->tag |= LIB_TAG_DOIT; - /* texture itself */ + /* Texture itself. */ build_animdata(tex_id); - /* texture's nodetree */ + /* Texture's nodetree. */ build_nodetree(owner_node, tex->nodetree); + /* Special cases for different IDs which texture uses. */ + if (tex->type == TEX_IMAGE) { + if (tex->ima != NULL) { + build_image(tex->ima); + } + } +} + +void DepsgraphNodeBuilder::build_image(Image *image) { + ID *image_id = &image->id; + if (image_id->tag & LIB_TAG_DOIT) { + return; + } + image_id->tag |= LIB_TAG_DOIT; + /* Image ID node itself. */ + add_id_node(image_id); + /* Placeholder so we can add relations and tag ID node for update. */ + add_operation_node(image_id, + DEPSNODE_TYPE_PARAMETERS, + DEPSOP_TYPE_EXEC, + NULL, + DEG_OPCODE_PLACEHOLDER, + "Image Eval"); } void DepsgraphNodeBuilder::build_compositor(Scene *scene) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index f378f076804..72dc73357bf 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -38,6 +38,7 @@ struct bGPdata; struct ListBase; struct GHash; struct ID; +struct Image; struct FCurve; struct Group; struct Key; @@ -75,43 +76,49 @@ struct DepsgraphNodeBuilder { ComponentDepsNode *add_component_node(ID *id, eDepsNode_Type comp_type, - const string& comp_name = ""); + const char *comp_name = ""); OperationDepsNode *add_operation_node(ComponentDepsNode *comp_node, eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string& description = ""); + const char *name = "", + int name_tag = -1); OperationDepsNode *add_operation_node(ID *id, eDepsNode_Type comp_type, - const string& comp_name, + const char *comp_name, eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string& description = ""); + const char *name = "", + int name_tag = -1); OperationDepsNode *add_operation_node(ID *id, eDepsNode_Type comp_type, eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string& description = ""); + const char *name = "", + int name_tag = -1); bool has_operation_node(ID *id, eDepsNode_Type comp_type, - const string& comp_name, + const char *comp_name, eDepsOperation_Code opcode, - const string& description = ""); + const char *name = "", + int name_tag = -1); OperationDepsNode *find_operation_node(ID *id, eDepsNode_Type comp_type, - const string &comp_name, + const char *comp_name, eDepsOperation_Code opcode, - const string &description = ""); + const char *name = "", + int name_tag = -1); OperationDepsNode *find_operation_node(ID *id, eDepsNode_Type comp_type, eDepsOperation_Code opcode, - const string &description = ""); + const char *name = "", + int name_tag = -1); void build_scene(Main *bmain, Scene *scene); SubgraphDepsNode *build_subgraph(Group *group); @@ -142,6 +149,7 @@ struct DepsgraphNodeBuilder { void build_material(DepsNode *owner_node, Material *ma); void build_texture(DepsNode *owner_node, Tex *tex); void build_texture_stack(DepsNode *owner_node, MTex **texture_stack); + void build_image(Image *image); void build_world(World *world); void build_compositor(Scene *scene); void build_gpencil(bGPdata *gpd); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 232c801563e..ccc4ea3d47b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -34,13 +34,12 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> +#include <cstring> /* required for STREQ later on. */ #include "MEM_guardedalloc.h" extern "C" { #include "BLI_blenlib.h" -#include "BLI_string.h" #include "BLI_utildefines.h" #include "DNA_action_types.h" @@ -209,10 +208,12 @@ OperationDepsNode *DepsgraphRelationBuilder::find_node( return NULL; } - OperationDepsNode *op_node = comp_node->find_operation(key.opcode, key.name); + OperationDepsNode *op_node = comp_node->find_operation(key.opcode, + key.name, + key.name_tag); if (!op_node) { fprintf(stderr, "find_node_operation: Failed for (%s, '%s')\n", - DEG_OPNAMES[key.opcode], key.name.c_str()); + DEG_OPNAMES[key.opcode], key.name); } return op_node; } @@ -234,7 +235,7 @@ OperationDepsNode *DepsgraphRelationBuilder::has_node( if (!comp_node) { return NULL; } - return comp_node->has_operation(key.opcode, key.name); + return comp_node->has_operation(key.opcode, key.name, key.name_tag); } void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc, @@ -483,7 +484,7 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o build_animdata(&ob->id); // XXX: This should be hooked up by the build_animdata code - if (ob->adt && (ob->adt->action || ob->adt->nla_tracks.first)) { + if (needs_animdata_node(&ob->id)) { ComponentKey adt_key(&ob->id, DEPSNODE_TYPE_ANIMATION); add_relation(adt_key, local_transform_key, DEPSREL_TYPE_OPERATION, "Object Animation"); } @@ -815,11 +816,66 @@ void DepsgraphRelationBuilder::build_animdata(ID *id) /* drivers */ for (FCurve *fcu = (FCurve *)adt->drivers.first; fcu; fcu = fcu->next) { - OperationKey driver_key(id, DEPSNODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, deg_fcurve_id_name(fcu)); + OperationKey driver_key(id, + DEPSNODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu->rna_path, + fcu->array_index); /* create the driver's relations to targets */ build_driver(id, fcu); + /* Special case for array drivers: we can not multithread them because + * of the way how they work internally: animation system will write the + * whole array back to RNA even when changing individual array value. + * + * Some tricky things here: + * - array_index is -1 for single channel drivers, meaning we only have + * to do some magic when array_index is not -1. + * - We do relation from next array index to a previous one, so we don't + * have to deal with array index 0. + * + * TODO(sergey): Avoid liner lookup somehow. + */ + if (fcu->array_index > 0) { + FCurve *fcu_prev = NULL; + for (FCurve *fcu_candidate = (FCurve *)adt->drivers.first; + fcu_candidate != NULL; + fcu_candidate = fcu_candidate->next) + { + /* Writing to different RNA paths is */ + if (!STREQ(fcu_candidate->rna_path, fcu->rna_path)) { + continue; + } + /* We only do relation from previous fcurve to previous one. */ + if (fcu_candidate->array_index >= fcu->array_index) { + continue; + } + /* Choose fcurve with highest possible array index. */ + if (fcu_prev == NULL || + fcu_candidate->array_index > fcu_prev->array_index) + { + fcu_prev = fcu_candidate; + } + } + if (fcu_prev != NULL) { + OperationKey prev_driver_key(id, + DEPSNODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu_prev->rna_path, + fcu_prev->array_index); + OperationKey driver_key(id, + DEPSNODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu->rna_path, + fcu->array_index); + add_relation(prev_driver_key, + driver_key, + DEPSREL_TYPE_OPERATION, + "[Driver Order]"); + } + } + /* prevent driver from occurring before own animation... */ if (adt->action || adt->nla_tracks.first) { add_relation(adt_key, driver_key, DEPSREL_TYPE_OPERATION, @@ -831,7 +887,11 @@ void DepsgraphRelationBuilder::build_animdata(ID *id) void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) { ChannelDriver *driver = fcu->driver; - OperationKey driver_key(id, DEPSNODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, deg_fcurve_id_name(fcu)); + OperationKey driver_key(id, + DEPSNODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu->rna_path, + fcu->array_index); bPoseChannel *pchan = NULL; /* create dependency between driver and data affected by it */ @@ -1384,7 +1444,7 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) "Armature Eval"); add_relation(armature_key, init_key, DEPSREL_TYPE_COMPONENT_ORDER, "Data dependency"); - if (ob->adt && (ob->adt->action || ob->adt->nla_tracks.first)) { + if (needs_animdata_node(&ob->id)) { ComponentKey animation_key(&ob->id, DEPSNODE_TYPE_ANIMATION); add_relation(animation_key, init_key, DEPSREL_TYPE_OPERATION, "Rig Animation"); } @@ -1622,7 +1682,7 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje * for either the modifier needing time, or that it is animated. */ /* XXX: Remove this hack when these links are added as part of build_animdata() instead */ - if (modifier_dependsOnTime(md) == false) { + if (modifier_dependsOnTime(md) == false && needs_animdata_node(&ob->id)) { ComponentKey animation_key(&ob->id, DEPSNODE_TYPE_ANIMATION); add_relation(animation_key, mod_key, DEPSREL_TYPE_OPERATION, "Modifier Animation"); } @@ -1920,7 +1980,7 @@ bool DepsgraphRelationBuilder::needs_animdata_node(ID *id) { AnimData *adt = BKE_animdata_from_id(id); if (adt != NULL) { - return adt->action != NULL; + return (adt->action != NULL) || (adt->nla_tracks.first != NULL); } return false; } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index ac6e6f8f095..28dd63a7c17 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -81,108 +81,83 @@ struct ComponentDepsNode; struct OperationDepsNode; struct RootPChanMap; -struct RootKey -{ - RootKey() {} +struct RootKey { + RootKey(); }; struct TimeSourceKey { - TimeSourceKey() : id(NULL) {} - TimeSourceKey(ID *id) : id(id) {} + TimeSourceKey(); + TimeSourceKey(ID *id); - string identifier() const - { - return string("TimeSourceKey"); - } + string identifier() const; ID *id; }; struct ComponentKey { - ComponentKey() : - id(NULL), type(DEPSNODE_TYPE_UNDEFINED), name("") - {} - ComponentKey(ID *id, eDepsNode_Type type, const string &name = "") : - id(id), type(type), name(name) - {} - - string identifier() const - { - const char *idname = (id) ? id->name : "<None>"; + ComponentKey(); + ComponentKey(ID *id, eDepsNode_Type type, const char *name = ""); - char typebuf[5]; - BLI_snprintf(typebuf, sizeof(typebuf), "%d", type); - - return string("ComponentKey(") + idname + ", " + typebuf + ", '" + name + "')"; - } + string identifier() const; ID *id; eDepsNode_Type type; - string name; + const char *name; }; struct OperationKey { - OperationKey() : - id(NULL), component_type(DEPSNODE_TYPE_UNDEFINED), component_name(""), opcode(DEG_OPCODE_OPERATION), name("") - {} - - OperationKey(ID *id, eDepsNode_Type component_type, const string &name) : - id(id), component_type(component_type), component_name(""), opcode(DEG_OPCODE_OPERATION), name(name) - {} - OperationKey(ID *id, eDepsNode_Type component_type, const string &component_name, const string &name) : - id(id), component_type(component_type), component_name(component_name), opcode(DEG_OPCODE_OPERATION), name(name) - {} - - OperationKey(ID *id, eDepsNode_Type component_type, eDepsOperation_Code opcode) : - id(id), component_type(component_type), component_name(""), opcode(opcode), name("") - {} - OperationKey(ID *id, eDepsNode_Type component_type, const string &component_name, eDepsOperation_Code opcode) : - id(id), component_type(component_type), component_name(component_name), opcode(opcode), name("") - {} - - OperationKey(ID *id, eDepsNode_Type component_type, eDepsOperation_Code opcode, const string &name) : - id(id), component_type(component_type), component_name(""), opcode(opcode), name(name) - {} - OperationKey(ID *id, eDepsNode_Type component_type, const string &component_name, eDepsOperation_Code opcode, const string &name) : - id(id), component_type(component_type), component_name(component_name), opcode(opcode), name(name) - {} - - string identifier() const - { - char typebuf[5]; - BLI_snprintf(typebuf, sizeof(typebuf), "%d", component_type); - - return string("OperationKey(") + "t: " + typebuf + ", cn: '" + component_name + "', c: " + DEG_OPNAMES[opcode] + ", n: '" + name + "')"; - } - + OperationKey(); + OperationKey(ID *id, + eDepsNode_Type component_type, + const char *name, + int name_tag = -1); + OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + const char *name, + int name_tag); + + OperationKey(ID *id, + eDepsNode_Type component_type, + eDepsOperation_Code opcode); + OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + eDepsOperation_Code opcode); + + OperationKey(ID *id, + eDepsNode_Type component_type, + eDepsOperation_Code opcode, + const char *name, + int name_tag = -1); + OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + eDepsOperation_Code opcode, + const char *name, + int name_tag = -1); + + string identifier() const; ID *id; eDepsNode_Type component_type; - string component_name; + const char *component_name; eDepsOperation_Code opcode; - string name; + const char *name; + int name_tag; }; struct RNAPathKey { - // Note: see depsgraph_build.cpp for implementation + /* NOTE: see depsgraph_build.cpp for implementation */ RNAPathKey(ID *id, const char *path); - RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop) : - id(id), ptr(ptr), prop(prop) - {} - - string identifier() const - { - const char *id_name = (id) ? id->name : "<No ID>"; - const char *prop_name = (prop) ? RNA_property_identifier(prop) : "<No Prop>"; - - return string("RnaPathKey(") + "id: " + id_name + ", prop: " + prop_name + "')"; - } + RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop); + string identifier() const; ID *id; PointerRNA ptr; @@ -270,7 +245,7 @@ protected: template <typename KeyType> DepsNodeHandle create_node_handle(const KeyType& key, - const string& default_name = ""); + const char *default_name = ""); bool needs_animdata_node(ID *id); @@ -280,7 +255,7 @@ private: struct DepsNodeHandle { - DepsNodeHandle(DepsgraphRelationBuilder *builder, OperationDepsNode *node, const string &default_name = "") : + DepsNodeHandle(DepsgraphRelationBuilder *builder, OperationDepsNode *node, const char *default_name = "") : builder(builder), node(node), default_name(default_name) @@ -290,7 +265,7 @@ struct DepsNodeHandle DepsgraphRelationBuilder *builder; OperationDepsNode *node; - const string &default_name; + const char *default_name; }; /* Utilities for Builders ----------------------------------------------------- */ @@ -318,6 +293,7 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, else { if (!op_from) { /* XXX TODO handle as error or report if needed */ + node_from = find_node(key_from); fprintf(stderr, "add_relation(%d, %s) - Could not find op_from (%s)\n", type, description, key_from.identifier().c_str()); } @@ -383,7 +359,7 @@ void DepsgraphRelationBuilder::add_node_handle_relation( template <typename KeyType> DepsNodeHandle DepsgraphRelationBuilder::create_node_handle( const KeyType &key, - const string &default_name) + const char *default_name) { return DepsNodeHandle(this, find_node(key), default_name); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc new file mode 100644 index 00000000000..7ada04e8f74 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc @@ -0,0 +1,211 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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) 2013 Blender Foundation. + * All rights reserved. + * + * Original Author: Joshua Leung + * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder_relations.cc + * \ingroup depsgraph + * + * Methods for constructing depsgraph + */ + +#include "intern/builder/deg_builder_relations.h" + +namespace DEG { + +///////////////////////////////////////// +// Root. + +RootKey::RootKey() +{ +} + +///////////////////////////////////////// +// Time source. + +TimeSourceKey::TimeSourceKey() + : id(NULL) +{ +} + +TimeSourceKey::TimeSourceKey(ID *id) + : id(id) +{ +} + +string TimeSourceKey::identifier() const +{ + return string("TimeSourceKey"); +} + +///////////////////////////////////////// +// Component. + +ComponentKey::ComponentKey() + : id(NULL), + type(DEPSNODE_TYPE_UNDEFINED), + name("") +{ +} + +ComponentKey::ComponentKey(ID *id, eDepsNode_Type type, const char *name) + : id(id), + type(type), + name(name) +{ +} + +string ComponentKey::identifier() const +{ + const char *idname = (id) ? id->name : "<None>"; + char typebuf[5]; + BLI_snprintf(typebuf, sizeof(typebuf), "%d", type); + return string("ComponentKey(") + + idname + ", " + typebuf + ", '" + name + "')"; +} + +///////////////////////////////////////// +// Operation. + +OperationKey::OperationKey() + : id(NULL), + component_type(DEPSNODE_TYPE_UNDEFINED), + component_name(""), + opcode(DEG_OPCODE_OPERATION), + name(""), + name_tag(-1) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + const char *name, + int name_tag) + : id(id), + component_type(component_type), + component_name(""), + opcode(DEG_OPCODE_OPERATION), + name(name), + name_tag(name_tag) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + const char *name, + int name_tag) + : id(id), + component_type(component_type), + component_name(component_name), + opcode(DEG_OPCODE_OPERATION), + name(name), + name_tag(name_tag) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + eDepsOperation_Code opcode) + : id(id), + component_type(component_type), + component_name(""), + opcode(opcode), + name(""), + name_tag(-1) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + eDepsOperation_Code opcode) + : id(id), + component_type(component_type), + component_name(component_name), + opcode(opcode), + name(""), + name_tag(-1) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + eDepsOperation_Code opcode, + const char *name, + int name_tag) + : id(id), + component_type(component_type), + component_name(""), + opcode(opcode), + name(name), + name_tag(name_tag) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + eDepsOperation_Code opcode, + const char *name, + int name_tag) + : id(id), + component_type(component_type), + component_name(component_name), + opcode(opcode), + name(name), + name_tag(name_tag) +{ +} + +string OperationKey::identifier() const +{ + char typebuf[5]; + BLI_snprintf(typebuf, sizeof(typebuf), "%d", component_type); + return string("OperationKey(") + + "t: " + typebuf + + ", cn: '" + component_name + + "', c: " + DEG_OPNAMES[opcode] + + ", n: '" + name + "')"; +} + +///////////////////////////////////////// +// RNA path. + +RNAPathKey::RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop) + : id(id), + ptr(ptr), + prop(prop) +{ +} + +string RNAPathKey::identifier() const +{ + const char *id_name = (id) ? id->name : "<No ID>"; + const char *prop_name = (prop) ? RNA_property_identifier(prop) : "<No Prop>"; + return string("RnaPathKey(") + "id: " + id_name + + ", prop: " + prop_name + "')"; +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc index 70cd5f11a47..0d56ce71c7d 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc @@ -321,7 +321,7 @@ static void deg_debug_graphviz_node_single(const DebugContext &ctx, static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx, const DepsNode *node) { - string name = node->identifier().c_str(); + string name = node->identifier(); if (node->type == DEPSNODE_TYPE_ID_REF) { IDDepsNode *id_node = (IDDepsNode *)node; char buf[256]; diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 2b7c63767ab..3502267d9ca 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -32,8 +32,6 @@ #include "intern/depsgraph.h" /* own include */ -#include <string.h> - #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" @@ -53,6 +51,8 @@ extern "C" { #include "RNA_access.h" } +#include <cstring> + #include "DEG_depsgraph.h" #include "intern/nodes/deg_node.h" @@ -116,7 +116,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr, const PropertyRNA *prop, ID **id, eDepsNode_Type *type, - string *subdata) + const char **subdata) { if (!ptr->type) return false; @@ -232,7 +232,7 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr, { ID *id; eDepsNode_Type type; - string name; + const char *name; /* Get querying conditions. */ if (pointer_to_id_node_criteria(ptr, prop, &id)) { @@ -240,8 +240,9 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr, } else if (pointer_to_component_node_criteria(ptr, prop, &id, &type, &name)) { IDDepsNode *id_node = find_id_node(id); - if (id_node) + if (id_node != NULL) { return id_node->find_component(type, name); + } } return NULL; @@ -328,7 +329,7 @@ IDDepsNode *Depsgraph::find_id_node(const ID *id) const return reinterpret_cast<IDDepsNode *>(BLI_ghash_lookup(id_hash, id)); } -IDDepsNode *Depsgraph::add_id_node(ID *id, const string &name) +IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name) { IDDepsNode *id_node = find_id_node(id); if (!id_node) { diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 08b264f8497..e668facd645 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -101,22 +101,6 @@ struct Depsgraph { ~Depsgraph(); /** - * Find node which matches the specified description. - * - * \param id: ID block that is associated with this - * \param subdata: identifier used for sub-ID data (e.g. bone) - * \param type: type of node we're dealing with - * \param name: custom identifier assigned to node - * - * \return A node matching the required characteristics if it exists - * or NULL if no such node exists in the graph. - */ - DepsNode *find_node(const ID *id, - eDepsNode_Type type, - const string &subdata, - const string &name); - - /** * Convenience wrapper to find node given just pointer + property. * * \param ptr: pointer to the data that node will represent @@ -136,7 +120,7 @@ struct Depsgraph { void clear_subgraph_nodes(); IDDepsNode *find_id_node(const ID *id) const; - IDDepsNode *add_id_node(ID *id, const string &name = ""); + IDDepsNode *add_id_node(ID *id, const char *name = ""); void remove_id_node(const ID *id); void clear_id_nodes(); diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index 119b2054d24..e139ff1f2bc 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -32,6 +32,8 @@ #include "MEM_guardedalloc.h" +// #define DEBUG_TIME + extern "C" { #include "DNA_cachefile_types.h" #include "DNA_object_types.h" @@ -41,6 +43,11 @@ extern "C" { #include "BLI_utildefines.h" #include "BLI_ghash.h" +#ifdef DEBUG_TIME +# include "PIL_time.h" +# include "PIL_time_utildefines.h" +#endif + #include "BKE_main.h" #include "BKE_collision.h" #include "BKE_effect.h" @@ -190,6 +197,10 @@ void DEG_add_special_eval_flag(Depsgraph *graph, ID *id, short flag) */ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene) { +#ifdef DEBUG_TIME + TIMEIT_START(DEG_graph_build_from_scene); +#endif + DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); /* 1) Generate all the nodes in the graph first */ @@ -239,6 +250,10 @@ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene) abort(); } #endif + +#ifdef DEBUG_TIME + TIMEIT_END(DEG_graph_build_from_scene); +#endif } /* Tag graph relations for update. */ diff --git a/source/blender/depsgraph/intern/depsgraph_intern.h b/source/blender/depsgraph/intern/depsgraph_intern.h index e5d3d1f5861..2d8e7dc841c 100644 --- a/source/blender/depsgraph/intern/depsgraph_intern.h +++ b/source/blender/depsgraph/intern/depsgraph_intern.h @@ -63,8 +63,8 @@ struct DepsNodeFactory { virtual const char *tname() const = 0; virtual DepsNode *create_node(const ID *id, - const string &subdata, - const string &name) const = 0; + const char *subdata, + const char *name) const = 0; }; template <class NodeType> @@ -73,7 +73,7 @@ struct DepsNodeFactoryImpl : public DepsNodeFactory { eDepsNode_Class tclass() const { return NodeType::typeinfo.tclass; } const char *tname() const { return NodeType::typeinfo.tname; } - DepsNode *create_node(const ID *id, const string &subdata, const string &name) const + DepsNode *create_node(const ID *id, const char *subdata, const char *name) const { DepsNode *node = OBJECT_GUARDED_NEW(NodeType); @@ -81,12 +81,14 @@ struct DepsNodeFactoryImpl : public DepsNodeFactory { node->type = type(); node->tclass = tclass(); - if (!name.empty()) + if (name[0] != '\0') { /* set name if provided ... */ node->name = name; - else + } + else { /* ... otherwise use default type name */ node->name = tname(); + } node->init(id, subdata); diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index b61b31a6be6..91eabbaf5d1 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -31,7 +31,7 @@ */ #include <stdio.h> -#include <cstring> +#include <cstring> /* required for memset */ #include <queue> extern "C" { diff --git a/source/blender/depsgraph/intern/eval/deg_eval_debug.cc b/source/blender/depsgraph/intern/eval/deg_eval_debug.cc index 67d64aae8bf..060544a4407 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_debug.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_debug.cc @@ -30,10 +30,10 @@ * Implementation of tools for debugging the depsgraph */ -#include <cstring> - #include "intern/eval/deg_eval_debug.h" +#include <cstring> /* required for STREQ later on. */ + extern "C" { #include "BLI_listbase.h" #include "BLI_ghash.h" @@ -53,10 +53,10 @@ namespace DEG { DepsgraphStats *DepsgraphDebug::stats = NULL; -static string get_component_name(eDepsNode_Type type, const string &name = "") +static string get_component_name(eDepsNode_Type type, const char *name = "") { DepsNodeFactory *factory = deg_get_node_factory(type); - if (name.empty()) { + if (name[0] != '\0') { return string(factory->tname()); } else { @@ -116,7 +116,7 @@ void DepsgraphDebug::task_started(Depsgraph *graph, */ DepsgraphStatsComponent *comp_stats = get_component_stats(id, get_component_name(comp->type, - comp->name), + comp->name).c_str(), true); times_clear(comp_stats->times); } @@ -146,7 +146,7 @@ void DepsgraphDebug::task_completed(Depsgraph *graph, DepsgraphStatsComponent *comp_stats = get_component_stats(id, get_component_name(comp->type, - comp->name), + comp->name).c_str(), true); times_add(comp_stats->times, time); } @@ -226,7 +226,7 @@ DepsgraphStatsID *DepsgraphDebug::get_id_stats(ID *id, bool create) DepsgraphStatsComponent *DepsgraphDebug::get_component_stats( DepsgraphStatsID *id_stats, - const string &name, + const char *name, bool create) { DepsgraphStatsComponent *comp_stats; @@ -234,13 +234,14 @@ DepsgraphStatsComponent *DepsgraphDebug::get_component_stats( comp_stats != NULL; comp_stats = comp_stats->next) { - if (STREQ(comp_stats->name, name.c_str())) + if (STREQ(comp_stats->name, name)) { break; + } } if (!comp_stats && create) { comp_stats = (DepsgraphStatsComponent *)MEM_callocN(sizeof(DepsgraphStatsComponent), "Depsgraph Component Stats"); - BLI_strncpy(comp_stats->name, name.c_str(), sizeof(comp_stats->name)); + BLI_strncpy(comp_stats->name, name, sizeof(comp_stats->name)); BLI_addtail(&id_stats->components, comp_stats); } return comp_stats; diff --git a/source/blender/depsgraph/intern/eval/deg_eval_debug.h b/source/blender/depsgraph/intern/eval/deg_eval_debug.h index 9109019eb2d..0bbe88cc9ca 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_debug.h +++ b/source/blender/depsgraph/intern/eval/deg_eval_debug.h @@ -66,10 +66,10 @@ struct DepsgraphDebug { static DepsgraphStatsID *get_id_stats(ID *id, bool create); static DepsgraphStatsComponent *get_component_stats(DepsgraphStatsID *id_stats, - const string &name, + const char *name, bool create); static DepsgraphStatsComponent *get_component_stats(ID *id, - const string &name, + const char *name, bool create) { return get_component_stats(get_id_stats(id, create), name, create); diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc index eb408f293de..57b25c10670 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node.cc @@ -31,7 +31,7 @@ #include "intern/nodes/deg_node.h" #include <stdio.h> -#include <string.h> +#include <cstring> /* required for STREQ later on. */ #include "BLI_utildefines.h" #include "BLI_ghash.h" @@ -72,7 +72,7 @@ DepsNode::TypeInfo::TypeInfo(eDepsNode_Type type, const char *tname) DepsNode::DepsNode() { - name[0] = '\0'; + name = ""; } DepsNode::~DepsNode() @@ -122,7 +122,7 @@ RootDepsNode::~RootDepsNode() OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode); } -TimeSourceDepsNode *RootDepsNode::add_time_source(const string &name) +TimeSourceDepsNode *RootDepsNode::add_time_source(const char *name) { if (!time_source) { DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_TIMESOURCE); @@ -142,12 +142,24 @@ static DepsNodeFactoryImpl<TimeSourceDepsNode> DNTI_TIMESOURCE; /* ID Node ================================================ */ +IDDepsNode::ComponentIDKey::ComponentIDKey(eDepsNode_Type type, + const char *name) + : type(type), name(name) +{ +} + +bool IDDepsNode::ComponentIDKey::operator== (const ComponentIDKey &other) const +{ + return type == other.type && + STREQ(name, other.name); +} + static unsigned int id_deps_node_hash_key(const void *key_v) { const IDDepsNode::ComponentIDKey *key = reinterpret_cast<const IDDepsNode::ComponentIDKey *>(key_v); return hash_combine(BLI_ghashutil_uinthash(key->type), - BLI_ghashutil_strhash_p(key->name.c_str())); + BLI_ghashutil_strhash_p(key->name)); } static bool id_deps_node_hash_key_cmp(const void *a, const void *b) @@ -173,7 +185,7 @@ static void id_deps_node_hash_value_free(void *value_v) } /* Initialize 'id' node - from pointer data given. */ -void IDDepsNode::init(const ID *id, const string &UNUSED(subdata)) +void IDDepsNode::init(const ID *id, const char *UNUSED(subdata)) { /* Store ID-pointer. */ BLI_assert(id != NULL); @@ -204,14 +216,14 @@ IDDepsNode::~IDDepsNode() } ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type, - const string &name) const + const char *name) const { ComponentIDKey key(type, name); return reinterpret_cast<ComponentDepsNode *>(BLI_ghash_lookup(components, &key)); } ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type, - const string &name) + const char *name) { ComponentDepsNode *comp_node = find_component(type, name); if (!comp_node) { @@ -226,7 +238,7 @@ ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type, return comp_node; } -void IDDepsNode::remove_component(eDepsNode_Type type, const string &name) +void IDDepsNode::remove_component(eDepsNode_Type type, const char *name) { ComponentDepsNode *comp_node = find_component(type, name); if (comp_node) { @@ -281,7 +293,7 @@ static DepsNodeFactoryImpl<IDDepsNode> DNTI_ID_REF; /* Subgraph Node ========================================== */ /* Initialize 'subgraph' node - from pointer data given. */ -void SubgraphDepsNode::init(const ID *id, const string &UNUSED(subdata)) +void SubgraphDepsNode::init(const ID *id, const char *UNUSED(subdata)) { /* Store ID-ref if provided. */ this->root_id = (ID *)id; diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h index b2262c4bd12..7c2f53840b6 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.h +++ b/source/blender/depsgraph/intern/nodes/deg_node.h @@ -32,6 +32,8 @@ #include "intern/depsgraph_types.h" +#include "BLI_utildefines.h" + struct ID; struct GHash; struct Scene; @@ -57,7 +59,7 @@ struct DepsNode { }; /* Identifier - mainly for debugging purposes. */ - string name; + const char *name; /* Structural type of node. */ eDepsNode_Type type; @@ -78,8 +80,9 @@ struct DepsNode { /* Nodes which depend on this one. */ Relations outlinks; - /* Generic tag for traversal algorithms */ + /* Generic tags for traversal algorithms. */ int done; + int tag; /* Methods. */ @@ -90,7 +93,7 @@ struct DepsNode { string full_identifier() const; virtual void init(const ID * /*id*/, - const string &/*subdata*/) {} + const char * /*subdata*/) {} virtual void tag_update(Depsgraph * /*graph*/) {} @@ -129,7 +132,7 @@ struct RootDepsNode : public DepsNode { RootDepsNode(); ~RootDepsNode(); - TimeSourceDepsNode *add_time_source(const string &name = ""); + TimeSourceDepsNode *add_time_source(const char *name = ""); /* scene that this corresponds to */ Scene *scene; @@ -143,26 +146,21 @@ struct RootDepsNode : public DepsNode { /* ID-Block Reference */ struct IDDepsNode : public DepsNode { struct ComponentIDKey { - ComponentIDKey(eDepsNode_Type type, const string &name = "") - : type(type), name(name) {} - - bool operator== (const ComponentIDKey &other) const - { - return type == other.type && name == other.name; - } + ComponentIDKey(eDepsNode_Type type, const char *name = ""); + bool operator==(const ComponentIDKey &other) const; eDepsNode_Type type; - string name; + const char *name; }; - void init(const ID *id, const string &subdata); + void init(const ID *id, const char *subdata); ~IDDepsNode(); ComponentDepsNode *find_component(eDepsNode_Type type, - const string &name = "") const; + const char *name = "") const; ComponentDepsNode *add_component(eDepsNode_Type type, - const string &name = ""); - void remove_component(eDepsNode_Type type, const string &name = ""); + const char *name = ""); + void remove_component(eDepsNode_Type type, const char *name = ""); void clear_components(); void tag_update(Depsgraph *graph); @@ -189,7 +187,7 @@ struct IDDepsNode : public DepsNode { /* Subgraph Reference. */ struct SubgraphDepsNode : public DepsNode { - void init(const ID *id, const string &subdata); + void init(const ID *id, const char *subdata); ~SubgraphDepsNode(); /* Instanced graph. */ diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 01f33b6368b..06f91ac7fdc 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -31,7 +31,7 @@ #include "intern/nodes/deg_node_component.h" #include <stdio.h> -#include <string.h> +#include <cstring> /* required for STREQ later on. */ extern "C" { #include "BLI_utildefines.h" @@ -53,12 +53,50 @@ namespace DEG { /* Standard Component Methods ============================= */ +ComponentDepsNode::OperationIDKey::OperationIDKey() + : opcode(DEG_OPCODE_OPERATION), + name(""), + name_tag(-1) +{ +} + +ComponentDepsNode::OperationIDKey::OperationIDKey(eDepsOperation_Code opcode) + : opcode(opcode), + name(""), + name_tag(-1) +{ +} + +ComponentDepsNode::OperationIDKey::OperationIDKey(eDepsOperation_Code opcode, + const char *name, + int name_tag) + : opcode(opcode), + name(name), + name_tag(name_tag) +{ +} + +string ComponentDepsNode::OperationIDKey::identifier() const +{ + char codebuf[5]; + BLI_snprintf(codebuf, sizeof(codebuf), "%d", opcode); + return string("OperationIDKey(") + codebuf + ", " + name + ")"; +} + +bool ComponentDepsNode::OperationIDKey::operator==( + const OperationIDKey &other) const +{ + return (opcode == other.opcode) && + (STREQ(name, other.name)) && + (name_tag == other.name_tag); +} + static unsigned int comp_node_hash_key(const void *key_v) { const ComponentDepsNode::OperationIDKey *key = reinterpret_cast<const ComponentDepsNode::OperationIDKey *>(key_v); return hash_combine(BLI_ghashutil_uinthash(key->opcode), - BLI_ghashutil_strhash_p(key->name.c_str())); + BLI_ghashutil_strhash_p(key->name)); } static bool comp_node_hash_key_cmp(const void *a, const void *b) @@ -95,7 +133,7 @@ ComponentDepsNode::ComponentDepsNode() : /* Initialize 'component' node - from pointer data given */ void ComponentDepsNode::init(const ID * /*id*/, - const string & /*subdata*/) + const char * /*subdata*/) { /* hook up eval context? */ // XXX: maybe this needs a special API? @@ -114,7 +152,7 @@ ComponentDepsNode::~ComponentDepsNode() string ComponentDepsNode::identifier() const { - string &idname = this->owner->name; + string idname = this->owner->name; char typebuf[16]; sprintf(typebuf, "(%d)", type); @@ -139,9 +177,11 @@ OperationDepsNode *ComponentDepsNode::find_operation(OperationIDKey key) const } } -OperationDepsNode *ComponentDepsNode::find_operation(eDepsOperation_Code opcode, const string &name) const +OperationDepsNode *ComponentDepsNode::find_operation(eDepsOperation_Code opcode, + const char *name, + int name_tag) const { - OperationIDKey key(opcode, name); + OperationIDKey key(opcode, name, name_tag); return find_operation(key); } @@ -151,21 +191,26 @@ OperationDepsNode *ComponentDepsNode::has_operation(OperationIDKey key) const } OperationDepsNode *ComponentDepsNode::has_operation(eDepsOperation_Code opcode, - const string &name) const + const char *name, + int name_tag) const { - OperationIDKey key(opcode, name); + OperationIDKey key(opcode, name, name_tag); return has_operation(key); } -OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, const string &name) +OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype, + DepsEvalOperationCb op, + eDepsOperation_Code opcode, + const char *name, + int name_tag) { - OperationDepsNode *op_node = has_operation(opcode, name); + OperationDepsNode *op_node = has_operation(opcode, name, name_tag); if (!op_node) { DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_OPERATION); op_node = (OperationDepsNode *)factory->create_node(this->owner->id, "", name); /* register opnode in this component's operation set */ - OperationIDKey *key = OBJECT_GUARDED_NEW(OperationIDKey, opcode, name); + OperationIDKey *key = OBJECT_GUARDED_NEW(OperationIDKey, opcode, name, name_tag); BLI_ghash_insert(operations_map, key, op_node); /* set as entry/exit node of component (if appropriate) */ @@ -197,16 +242,6 @@ OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype, return op_node; } -void ComponentDepsNode::remove_operation(eDepsOperation_Code opcode, const string &name) -{ - /* unregister */ - OperationIDKey key(opcode, name); - BLI_ghash_remove(operations_map, - &key, - comp_node_hash_key_free, - comp_node_hash_key_free); -} - void ComponentDepsNode::clear_operations() { if (operations_map != NULL) { @@ -337,7 +372,7 @@ static DepsNodeFactoryImpl<PoseComponentDepsNode> DNTI_EVAL_POSE; /* Bone Component ========================================= */ /* Initialize 'bone component' node - from pointer data given */ -void BoneComponentDepsNode::init(const ID *id, const string &subdata) +void BoneComponentDepsNode::init(const ID *id, const char *subdata) { /* generic component-node... */ ComponentDepsNode::init(id, subdata); @@ -350,7 +385,7 @@ void BoneComponentDepsNode::init(const ID *id, const string &subdata) /* bone-specific node data */ Object *ob = (Object *)id; - this->pchan = BKE_pose_channel_find_name(ob->pose, subdata.c_str()); + this->pchan = BKE_pose_channel_find_name(ob->pose, subdata); } DEG_DEPSNODE_DEFINE(BoneComponentDepsNode, DEPSNODE_TYPE_BONE, "Bone Component"); diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h index 7dec8eaaa90..969771a29c9 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h @@ -53,50 +53,38 @@ struct ComponentDepsNode : public DepsNode { struct OperationIDKey { eDepsOperation_Code opcode; - string name; - - - OperationIDKey() : - opcode(DEG_OPCODE_OPERATION), name("") - {} - OperationIDKey(eDepsOperation_Code opcode) : - opcode(opcode), name("") - {} - OperationIDKey(eDepsOperation_Code opcode, const string &name) : - opcode(opcode), name(name) - {} - - string identifier() const - { - char codebuf[5]; - BLI_snprintf(codebuf, sizeof(codebuf), "%d", opcode); - - return string("OperationIDKey(") + codebuf + ", " + name + ")"; - } - - bool operator==(const OperationIDKey &other) const - { - return (opcode == other.opcode) && (name == other.name); - } + const char *name; + int name_tag; + + OperationIDKey(); + OperationIDKey(eDepsOperation_Code opcode); + OperationIDKey(eDepsOperation_Code opcode, + const char *name, + int name_tag); + + string identifier() const; + bool operator==(const OperationIDKey &other) const; }; /* Typedef for container of operations */ ComponentDepsNode(); ~ComponentDepsNode(); - void init(const ID *id, const string &subdata); + void init(const ID *id, const char *subdata); string identifier() const; /* Find an existing operation, will throw an assert() if it does not exist. */ OperationDepsNode *find_operation(OperationIDKey key) const; OperationDepsNode *find_operation(eDepsOperation_Code opcode, - const string &name) const; + const char *name, + int name_tag) const; /* Check operation exists and return it. */ OperationDepsNode *has_operation(OperationIDKey key) const; OperationDepsNode *has_operation(eDepsOperation_Code opcode, - const string &name) const; + const char *name, + int name_tag) const; /** * Create a new node for representing an operation and add this to graph @@ -114,9 +102,9 @@ struct ComponentDepsNode : public DepsNode { OperationDepsNode *add_operation(eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string &name); + const char *name, + int name_tag); - void remove_operation(eDepsOperation_Code opcode, const string &name); void clear_operations(); void tag_update(Depsgraph *graph); @@ -194,7 +182,7 @@ struct PoseComponentDepsNode : public ComponentDepsNode { /* Bone Component */ struct BoneComponentDepsNode : public ComponentDepsNode { - void init(const ID *id, const string &subdata); + void init(const ID *id, const char *subdata); struct bPoseChannel *pchan; /* the bone that this component represents */ diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc index 5847af29ac2..9eed4dfe8d8 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc @@ -68,7 +68,7 @@ string OperationDepsNode::full_identifier() const { string owner_str = ""; if (owner->type == DEPSNODE_TYPE_BONE) { - owner_str = owner->owner->name + "." + owner->name; + owner_str = string(owner->owner->name) + "." + owner->name; } else { owner_str = owner->owner->name; diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 8659100df87..baae92f962e 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -305,7 +305,6 @@ void WM_OT_collada_export(wmOperatorType *ot) static EnumPropertyItem prop_bc_export_transformation_type[] = { {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations"}, {BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations"}, - {BC_TRANSFORMATION_TYPE_BOTH, "both", 0, "Both", "Use <matrix> AND <translate>, <rotate>, <scale> to specify transformations"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 4482a071c91..6e973740f7c 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1306,7 +1306,9 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, if (use_hierarchy || use_base_parent) { dupli_gh = BLI_ghash_ptr_new(__func__); - parent_gh = BLI_ghash_new(dupliobject_hash, dupliobject_cmp, __func__); + if (use_hierarchy) { + parent_gh = BLI_ghash_new(dupliobject_hash, dupliobject_cmp, __func__); + } } for (dob = lb->first; dob; dob = dob->next) { @@ -1343,10 +1345,17 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, copy_m4_m4(ob->obmat, dob->mat); BKE_object_apply_mat4(ob, ob->obmat, false, false); - if (dupli_gh) + if (dupli_gh) { BLI_ghash_insert(dupli_gh, dob, ob); - if (parent_gh) - BLI_ghash_insert(parent_gh, dob, ob); + } + if (parent_gh) { + void **val; + /* Due to nature of hash/comparison of this ghash, a lot of duplis may be considered as 'the same', + * this avoids trying to insert same key several time and raise asserts in debug builds... */ + if (!BLI_ghash_ensure_p(parent_gh, dob, &val)) { + *val = ob; + } + } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index b593ac0f2e8..a3ff8dcb676 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1739,10 +1739,16 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in clear_sca_new_poins(); /* sensor/contr/act */ - /* newid may still have some trash from Outliner tree building, - * so clear that first to avoid errors [#26002] */ - for (ob = bmain->object.first; ob; ob = ob->id.next) - ob->id.newid = NULL; + /* newid may still have some trash from Outliner tree building, so clear that first to avoid errors, see T26002. + * We have to clear whole datablocks, not only Object one may be accessed here, see T49905. */ + ListBase *lbarray[MAX_LIBARRAY]; + int a = set_listbasepointers(bmain, lbarray); + while (a--) { + ListBase *lb = lbarray[a]; + for (ID *id = lb->first; id; id = id->next) { + id->newid = NULL; + } + } /* duplicate (must set newid) */ for (base = FIRSTBASE; base; base = base->next) { diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h index 934028f2e5f..72805c7acb4 100644 --- a/source/blender/makesdna/DNA_rigidbody_types.h +++ b/source/blender/makesdna/DNA_rigidbody_types.h @@ -223,10 +223,16 @@ typedef struct RigidBodyCon { float spring_stiffness_x; float spring_stiffness_y; float spring_stiffness_z; + float spring_stiffness_ang_x; + float spring_stiffness_ang_y; + float spring_stiffness_ang_z; /* amount of velocity lost over time */ float spring_damping_x; float spring_damping_y; float spring_damping_z; + float spring_damping_ang_x; + float spring_damping_ang_y; + float spring_damping_ang_z; /* motor settings */ float motor_lin_target_velocity; /* linear velocity the motor tries to hold */ @@ -292,7 +298,11 @@ typedef enum eRigidBodyCon_Flag { RBC_FLAG_USE_SPRING_Z = (1 << 13), /* motors */ RBC_FLAG_USE_MOTOR_LIN = (1 << 14), - RBC_FLAG_USE_MOTOR_ANG = (1 << 15) + RBC_FLAG_USE_MOTOR_ANG = (1 << 15), + /* angular springs */ + RBC_FLAG_USE_SPRING_ANG_X = (1 << 16), + RBC_FLAG_USE_SPRING_ANG_Y = (1 << 17), + RBC_FLAG_USE_SPRING_ANG_Z = (1 << 18) } eRigidBodyCon_Flag; /* ******************************** */ diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index 074a24ad01f..45ca865ad78 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -504,6 +504,45 @@ static void rna_RigidBodyCon_spring_stiffness_z_set(PointerRNA *ptr, float value #endif } +static void rna_RigidBodyCon_spring_stiffness_ang_x_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_stiffness_ang_x = value; + +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) { + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value); + } +#endif +} + +static void rna_RigidBodyCon_spring_stiffness_ang_y_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_stiffness_ang_y = value; + +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) { + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value); + } +#endif +} + +static void rna_RigidBodyCon_spring_stiffness_ang_z_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_stiffness_ang_z = value; + +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) { + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value); + } +#endif +} + static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value) { RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; @@ -541,6 +580,43 @@ static void rna_RigidBodyCon_spring_damping_z_set(PointerRNA *ptr, float value) #endif } +static void rna_RigidBodyCon_spring_damping_ang_x_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_damping_ang_x = value; + +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) { + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value); + } +#endif +} + +static void rna_RigidBodyCon_spring_damping_ang_y_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_damping_ang_y = value; +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) { + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value); + } +#endif +} + +static void rna_RigidBodyCon_spring_damping_ang_z_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_damping_ang_z = value; +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) { + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value); + } +#endif +} + static void rna_RigidBodyCon_motor_lin_max_impulse_set(PointerRNA *ptr, float value) { RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; @@ -1052,6 +1128,21 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Z Spring", "Enable spring on Z axis"); RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "use_spring_ang_x", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_ANG_X); + RNA_def_property_ui_text(prop, "X Angle Spring", "Enable spring on X rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "use_spring_ang_y", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_ANG_Y); + RNA_def_property_ui_text(prop, "Y Angle Spring", "Enable spring on Y rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "use_spring_ang_z", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_ANG_Z); + RNA_def_property_ui_text(prop, "Z Angle Spring", "Enable spring on Z rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "use_motor_lin", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_MOTOR_LIN); RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_use_motor_lin_set"); @@ -1169,6 +1260,33 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Z Axis Stiffness", "Stiffness on the Z axis"); RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "spring_stiffness_ang_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_ang_x"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); + RNA_def_property_float_default(prop, 10.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_ang_x_set", NULL); + RNA_def_property_ui_text(prop, "X Angle Stiffness", "Stiffness on the X rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "spring_stiffness_ang_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_ang_y"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); + RNA_def_property_float_default(prop, 10.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_ang_y_set", NULL); + RNA_def_property_ui_text(prop, "Y Angle Stiffness", "Stiffness on the Y rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "spring_stiffness_ang_z", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_ang_z"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); + RNA_def_property_float_default(prop, 10.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_ang_z_set", NULL); + RNA_def_property_ui_text(prop, "Z Angle Stiffness", "Stiffness on the Z rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "spring_damping_x", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "spring_damping_x"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -1193,6 +1311,30 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Damping Z", "Damping on the Z axis"); RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "spring_damping_ang_x", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "spring_damping_ang_x"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_ang_x_set", NULL); + RNA_def_property_ui_text(prop, "Damping X Angle", "Damping on the X rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "spring_damping_ang_y", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "spring_damping_ang_y"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_ang_y_set", NULL); + RNA_def_property_ui_text(prop, "Damping Y Angle", "Damping on the Y rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "spring_damping_ang_z", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "spring_damping_ang_z"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_ang_z_set", NULL); + RNA_def_property_ui_text(prop, "Damping Z Angle", "Damping on the Z rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "motor_lin_target_velocity", PROP_FLOAT, PROP_UNIT_VELOCITY); RNA_def_property_float_sdna(prop, NULL, "motor_lin_target_velocity"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index fd5a9d9ecc5..b3aea604926 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -52,15 +52,6 @@ #include "BLT_lang.h" #include "GPU_buffers.h" -#ifdef WITH_CYCLES -static EnumPropertyItem compute_device_type_items[] = { - {USER_COMPUTE_DEVICE_NONE, "NONE", 0, "None", "Don't use compute device"}, - {USER_COMPUTE_DEVICE_CUDA, "CUDA", 0, "CUDA", "Use CUDA for GPU acceleration"}, - {USER_COMPUTE_DEVICE_OPENCL, "OPENCL", 0, "OpenCL", "Use OpenCL for GPU acceleration"}, - { 0, NULL, 0, NULL, NULL} -}; -#endif - #ifdef WITH_OPENSUBDIV static EnumPropertyItem opensubdiv_compute_type_items[] = { {USER_OPENSUBDIV_COMPUTE_NONE, "NONE", 0, "None", ""}, @@ -124,8 +115,6 @@ static EnumPropertyItem rna_enum_language_default_items[] = { #include "UI_interface.h" -#include "CCL_api.h" - #ifdef WITH_OPENSUBDIV # include "opensubdiv_capi.h" #endif @@ -476,78 +465,6 @@ static PointerRNA rna_Theme_space_list_generic_get(PointerRNA *ptr) } -#ifdef WITH_CYCLES -static EnumPropertyItem *rna_userdef_compute_device_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), - PropertyRNA *UNUSED(prop), bool *r_free) -{ - EnumPropertyItem *item = NULL; - int totitem = 0; - - /* add supported device types */ - RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_NONE); - if (CCL_compute_device_list(0)) - RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_CUDA); - if (CCL_compute_device_list(1)) - RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_OPENCL); - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} - -static int rna_userdef_compute_device_get(PointerRNA *UNUSED(ptr)) -{ - if (U.compute_device_type == USER_COMPUTE_DEVICE_NONE) - return 0; - - return U.compute_device_id; -} - -static EnumPropertyItem *rna_userdef_compute_device_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), - PropertyRNA *UNUSED(prop), bool *r_free) -{ - EnumPropertyItem tmp = {0, "", 0, "", ""}; - EnumPropertyItem *item = NULL; - int totitem = 0; - - if (U.compute_device_type == USER_COMPUTE_DEVICE_NONE) { - /* only add a single CPU device */ - tmp.value = 0; - tmp.name = "CPU"; - tmp.identifier = "CPU"; - RNA_enum_item_add(&item, &totitem, &tmp); - } - else { - /* get device list from cycles. it would be good to make this generic - * once we have more subsystems using opencl, for now this is easiest */ - int opencl = (U.compute_device_type == USER_COMPUTE_DEVICE_OPENCL); - CCLDeviceInfo *devices = CCL_compute_device_list(opencl); - int a; - - if (devices) { - for (a = 0; devices[a].identifier[0]; a++) { - tmp.value = devices[a].value; - tmp.identifier = devices[a].identifier; - tmp.name = devices[a].name; - RNA_enum_item_add(&item, &totitem, &tmp); - } - } - else { - tmp.value = 0; - tmp.name = "CPU"; - tmp.identifier = "CPU"; - RNA_enum_item_add(&item, &totitem, &tmp); - } - } - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} -#endif - #ifdef WITH_OPENSUBDIV static EnumPropertyItem *rna_userdef_opensubdiv_compute_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) @@ -3973,13 +3890,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; -#ifdef WITH_CYCLES - static EnumPropertyItem compute_device_items[] = { - {0, "CPU", 0, "CPU", ""}, - { 0, NULL, 0, NULL, NULL} - }; -#endif - static EnumPropertyItem image_draw_methods[] = { {IMAGE_DRAW_METHOD_2DTEXTURE, "2DTEXTURE", 0, "2D Texture", "Use CPU for display transform and draw image with 2D texture"}, {IMAGE_DRAW_METHOD_GLSL, "GLSL", 0, "GLSL", "Use GLSL shaders for display transform and draw image with 2D texture"}, @@ -4271,23 +4181,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) "Draw tool/property regions over the main region, when using Triple Buffer"); RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); -#ifdef WITH_CYCLES - prop = RNA_def_property(srna, "compute_device_type", PROP_ENUM, PROP_NONE); - RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); - RNA_def_property_enum_sdna(prop, NULL, "compute_device_type"); - RNA_def_property_enum_items(prop, compute_device_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_userdef_compute_device_type_itemf"); - RNA_def_property_ui_text(prop, "Compute Device Type", "Device to use for computation (rendering with Cycles)"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL); - - prop = RNA_def_property(srna, "compute_device", PROP_ENUM, PROP_NONE); - RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); - RNA_def_property_enum_sdna(prop, NULL, "compute_device_id"); - RNA_def_property_enum_items(prop, compute_device_items); - RNA_def_property_enum_funcs(prop, "rna_userdef_compute_device_get", NULL, "rna_userdef_compute_device_itemf"); - RNA_def_property_ui_text(prop, "Compute Device", "Device to use for computation"); -#endif - #ifdef WITH_OPENSUBDIV prop = RNA_def_property(srna, "opensubdiv_compute_type", PROP_ENUM, PROP_NONE); RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 83c4ca7984c..9186b10d8ca 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -145,12 +145,9 @@ static void updateDepsgraph(ModifierData *md, HookModifierData *hmd = (HookModifierData *)md; if (hmd->object != NULL) { if (hmd->subtarget[0]) { - DEG_add_bone_relation(node, hmd->object, hmd->subtarget, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); DEG_add_bone_relation(node, hmd->object, hmd->subtarget, DEG_OB_COMP_BONE, "Hook Modifier"); } - else { - DEG_add_object_relation(node, hmd->object, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); - } + DEG_add_object_relation(node, hmd->object, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); } /* We need own transformation as well. */ DEG_add_object_relation(node, ob, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); |