diff options
Diffstat (limited to 'source/blender/depsgraph/util/depsgraph_util_pchanmap.cc')
-rw-r--r-- | source/blender/depsgraph/util/depsgraph_util_pchanmap.cc | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/source/blender/depsgraph/util/depsgraph_util_pchanmap.cc b/source/blender/depsgraph/util/depsgraph_util_pchanmap.cc new file mode 100644 index 00000000000..36bd72108ed --- /dev/null +++ b/source/blender/depsgraph/util/depsgraph_util_pchanmap.cc @@ -0,0 +1,132 @@ +/* + * ***** 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) 2015 Blender Foundation. + * All rights reserved. + * + * Original Author: Sergey Sharybin + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "depsgraph_util_pchanmap.h" + +#include <stdio.h> +#include <string.h> + +extern "C" { +#include "BLI_utildefines.h" +#include "BLI_ghash.h" +} + +static void free_rootpchanmap_valueset(void *val) +{ + /* Just need to free the set itself - the names stored are all references. */ + GSet *values = (GSet *)val; + BLI_gset_free(values, NULL); +} + +RootPChanMap::RootPChanMap() +{ + /* Just create empty map. */ + m_map = BLI_ghash_str_new("RootPChanMap"); +} + +RootPChanMap::~RootPChanMap() +{ + /* Free the map, and all the value sets. */ + BLI_ghash_free(m_map, NULL, free_rootpchanmap_valueset); +} + +/* Debug contents of map */ +void RootPChanMap::print_debug() +{ + GHashIterator it1; + GSetIterator it2; + + printf("Root PChan Map:\n"); + GHASH_ITER(it1, m_map) { + const char *item = (const char *)BLI_ghashIterator_getKey(&it1); + GSet *values = (GSet *)BLI_ghashIterator_getValue(&it1); + + printf(" %s : { ", item); + GSET_ITER(it2, values) { + const char *val = (const char *)BLI_gsetIterator_getKey(&it2); + printf("%s, ", val); + } + printf("}\n"); + } +} + +/* Add a mapping. */ +void RootPChanMap::add_bone(const char *bone, const char *root) +{ + if (BLI_ghash_haskey(m_map, bone)) { + /* Add new entry, but only add the root if it doesn't already + * exist in there. + */ + GSet *values = (GSet *)BLI_ghash_lookup(m_map, bone); + BLI_gset_add(values, (void *)root); + } + else { + /* Create new set and mapping. */ + GSet *values = BLI_gset_new(BLI_ghashutil_strhash_p, + BLI_ghashutil_strcmp, + "RootPChanMap Value Set"); + BLI_ghash_insert(m_map, (void *)bone, (void *)values); + + /* Add new entry now. */ + BLI_gset_insert(values, (void *)root); + } +} + +/* Check if there's a common root bone between two bones. */ +bool RootPChanMap::has_common_root(const char *bone1, const char *bone2) +{ + /* Ensure that both are in the map... */ + if (BLI_ghash_haskey(m_map, bone1) == false) { + //fprintf("RootPChanMap: bone1 '%s' not found (%s => %s)\n", bone1, bone1, bone2); + //print_debug(); + return false; + } + + if (BLI_ghash_haskey(m_map, bone2) == false) { + //fprintf("RootPChanMap: bone2 '%s' not found (%s => %s)\n", bone2, bone1, bone2); + //print_debug(); + return false; + } + + GSet *bone1_roots = (GSet *)BLI_ghash_lookup(m_map, (void *)bone1); + GSet *bone2_roots = (GSet *)BLI_ghash_lookup(m_map, (void *)bone2); + + GSetIterator it1, it2; + GSET_ITER(it1, bone1_roots) { + GSET_ITER(it2, bone2_roots) { + const char *v1 = (const char *)BLI_gsetIterator_getKey(&it1); + const char *v2 = (const char *)BLI_gsetIterator_getKey(&it2); + + if (strcmp(v1, v2) == 0) { + //fprintf("RootPchanMap: %s in common for %s => %s\n", v1, bone1, bone2); + return true; + } + } + } + + //fprintf("RootPChanMap: No common root found (%s => %s)\n", bone1, bone2); + return false; +} |