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:
authorGaia Clary <gaia.clary@machinimatrix.org>2012-06-13 01:23:51 +0400
committerGaia Clary <gaia.clary@machinimatrix.org>2012-06-13 01:23:51 +0400
commit92d948307549ce1d69ec4e41e42b442360b9bade (patch)
tree7beceda365db381b424cdaa379a21fdd53ca43c2
parentaace651e51cfaa725847ef1345418ec6a6e42b6e (diff)
patch #31794 Added new function BKE_object_relational_superset()
-rw-r--r--source/blender/blenkernel/BKE_object.h20
-rw-r--r--source/blender/blenkernel/intern/object.c134
2 files changed, 154 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 890fc40c284..29979f62d60 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -158,6 +158,26 @@ void BKE_object_relink(struct Object *ob);
struct MovieClip *BKE_object_movieclip_get(struct Scene *scene, struct Object *ob, int use_default);
+/* this function returns a superset of the scenes selection based on relationships */
+
+typedef enum eObRelationTypes {
+ OB_REL_NONE = 0, /* just the selection as is */
+ OB_REL_PARENT = (1<<0), /* immediate parent */
+ OB_REL_PARENT_RECURSIVE = (1<<1), /* parents up to root of selection tree*/
+ OB_REL_CHILDREN = (1<<2), /* immediate children */
+ OB_REL_CHILDREN_RECURSIVE = (1<<3), /* All children */
+ OB_REL_MOD_ARMATURE = (1<<4), /* Armatures related to the selected objects */
+ OB_REL_SCENE_CAMERA = (1<<5), /* you might want the scene camera too even if unselected? */
+} eObRelationTypes;
+
+typedef enum eObjectSet {
+ OB_SET_SELECTED, /* Selected Objects */
+ OB_SET_VISIBLE, /* Visible Objects */
+ OB_SET_ALL /* All Objects */
+} eObjectSet;
+
+struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index a01024acfd3..91fd5811911 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -63,6 +63,7 @@
#include "BLI_math.h"
#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
+#include "BLI_linklist.h"
#include "BKE_main.h"
#include "BKE_global.h"
@@ -3076,3 +3077,136 @@ MovieClip *BKE_object_movieclip_get(Scene *scene, Object *ob, int use_default)
return clip;
}
+
+
+/*
+ * Find an associated Armature object
+ */
+static Object *obrel_armature_find(Object *ob)
+{
+ Object *ob_arm = NULL;
+
+ if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
+ ob_arm = ob->parent;
+ }
+ else {
+ ModifierData *mod = (ModifierData*)ob->modifiers.first;
+ while (mod) {
+ if (mod->type == eModifierType_Armature) {
+ ob_arm = ((ArmatureModifierData*)mod)->object;
+ }
+
+ mod = mod->next;
+ }
+ }
+
+ return ob_arm;
+}
+
+static int obrel_is_recursive_child(Object *ob, Object *child) {
+ Object *ancestor = child->parent;
+ while (ancestor)
+ {
+ if(ancestor == ob) return TRUE;
+ ancestor = ancestor->parent;
+ }
+ return FALSE;
+}
+
+
+static int obrel_list_test(Object *ob)
+{
+ return ob && !(ob->id.flag & LIB_DOIT);
+}
+
+static void obrel_list_add(LinkNode **links, Object *ob)
+{
+ BLI_linklist_prepend(links, ob);
+ ob->id.flag |= LIB_DOIT;
+}
+
+/*
+ * Iterates over all objects of the given scene.
+ * Depending on the eObjectSet flag:
+ * collect either OB_SET_ALL, OB_SET_VISIBLE or OB_SET_SELECTED objects.
+ * If OB_SET_VISIBLE or OB_SET_SELECTED are collected,
+ * then also add related objects according to the given includeFilters.
+ */
+struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter)
+{
+ LinkNode *links = NULL;
+
+ Base *base;
+
+ /* Remove markers from all objects */
+ for (base = scene->base.first; base; base = base->next) {
+ base->object->id.flag &= ~LIB_DOIT;
+ }
+
+ /* iterate over all selected and visible objects */
+ for (base = scene->base.first; base; base = base->next) {
+ if (objectSet == OB_SET_ALL) {
+ // as we get all anyways just add it
+ Object *ob = base->object;
+ obrel_list_add(&links, ob);
+ }
+ else {
+ if ( (objectSet == OB_SET_SELECTED && TESTBASELIB_BGMODE(((View3D *)NULL), scene, base))
+ || (objectSet == OB_SET_VISIBLE && BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, base))
+ ) {
+ Object *ob = base->object;
+
+ if (obrel_list_test(ob))
+ obrel_list_add(&links, ob);
+
+ /* parent relationship */
+ if (includeFilter & ( OB_REL_PARENT | OB_REL_PARENT_RECURSIVE )) {
+ Object *parent = ob->parent;
+ if (obrel_list_test(parent)) {
+
+ obrel_list_add(&links, parent);
+
+ /* recursive parent relationship */
+ if (includeFilter & OB_REL_PARENT_RECURSIVE) {
+ parent = parent->parent;
+ while (obrel_list_test(parent)){
+
+ obrel_list_add(&links, parent);
+ parent = parent->parent;
+ }
+ }
+ }
+ }
+
+ /* child relationship */
+ if (includeFilter & ( OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE )) {
+ Base *local_base;
+ for (local_base = scene->base.first; local_base; local_base = local_base->next) {
+ if (BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, local_base)) {
+
+ Object *child = local_base->object;
+ if (obrel_list_test(child)) {
+ if ((includeFilter & OB_REL_CHILDREN_RECURSIVE && obrel_is_recursive_child(ob,child))
+ || (includeFilter & OB_REL_CHILDREN && child->parent && child->parent == ob )) {
+ obrel_list_add(&links, child);
+ }
+ }
+ }
+ }
+ }
+
+
+ /* include related armatures */
+ if (includeFilter & OB_REL_MOD_ARMATURE) {
+ Object *arm = obrel_armature_find(ob);
+ if (obrel_list_test(arm)) {
+ obrel_list_add(&links, arm);
+ }
+ }
+
+ }
+ }
+ } // end for
+
+ return links;
+}