Object mode select grouped operator (Shift+G and Select manu)
authorCampbell Barton <ideasman42@gmail.com>
Sat, 11 Jul 2009 11:31:49 +0000 (11:31 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 11 Jul 2009 11:31:49 +0000 (11:31 +0000)
Group option currently doesnt handle multiple groups.

Set makefiles python version to 2.6 for linux since its common now.

source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/intern/context.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_header.c
source/nan_definitions.mk

index f536e117b7b1ad3dbd926f216f2bc153c61eb67d..92c79ff757f7394f3ab42a8712fe343b4eb0a888 100644 (file)
@@ -186,6 +186,9 @@ int CTX_data_selected_bases(const bContext *C, ListBase *list);
 int CTX_data_visible_objects(const bContext *C, ListBase *list);
 int CTX_data_visible_bases(const bContext *C, ListBase *list);
 
+int CTX_data_selectable_objects(const bContext *C, ListBase *list);
+int CTX_data_selectable_bases(const bContext *C, ListBase *list);
+
 struct Object *CTX_data_active_object(const bContext *C);
 struct Base *CTX_data_active_base(const bContext *C);
 struct Object *CTX_data_edit_object(const bContext *C);
index 4a68d90a4ed8e093f9248ecacb4280ad73ba95db..1b4993848869a8276b78f21ac6ae5d166aa21526 100644 (file)
@@ -606,6 +606,16 @@ int CTX_data_visible_bases(const bContext *C, ListBase *list)
        return ctx_data_collection_get(C, "visible_bases", list);
 }
 
+int CTX_data_selectable_objects(const bContext *C, ListBase *list)
+{
+       return ctx_data_collection_get(C, "selectable_objects", list);
+}
+
+int CTX_data_selectable_bases(const bContext *C, ListBase *list)
+{
+       return ctx_data_collection_get(C, "selectable_bases", list);
+}
+
 struct Object *CTX_data_active_object(const bContext *C)
 {
        return ctx_data_pointer_get(C, "active_object");
index 9ea8907e172182f43fa0dc33dc2cecfed7fd7eb0..f122412fdd6c14507c6ec93e7b2923673ae0cdbe 100644 (file)
@@ -1690,6 +1690,309 @@ void OBJECT_OT_select_linked(wmOperatorType *ot)
        RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
 
 }
+
+/* ****** selection grouped *******/
+
+static EnumPropertyItem prop_select_grouped_types[] = {
+       {1, "CHILDREN_RECURSIVE", 0, "Children", ""}, // XXX depreceated animation system stuff...
+       {2, "CHILDREN", 0, "Immediate Children", ""},
+       {3, "PARENT", 0, "Parent", ""},
+       {4, "SIBLINGS", 0, "Siblings", "Shared Parent"},
+       {5, "TYPE", 0, "Type", "Shared object type"},
+       {6, "LAYER", 0, "Layer", "Shared layers"},
+       {7, "GROUP", 0, "Group", "Shared group"},
+       {8, "HOOK", 0, "Hook", ""},
+       {9, "PASS", 0, "Pass", "Render pass Index"},
+       {10, "COLOR", 0, "Color", "Object Color"},
+       {11, "PROPERTIES", 0, "Properties", "Game Properties"},
+       {0, NULL, 0, NULL, NULL}
+};
+
+
+static short select_grouped_children(bContext *C, Object *ob, int recursive)
+{
+       short changed = 0;
+
+       CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+               if (ob == base->object->parent) {
+                       if (!(base->flag & SELECT)) {
+                               ED_base_object_select(base, BA_SELECT);
+                               changed = 1;
+                       }
+
+                       if (recursive)
+                               changed |= select_grouped_children(C, base->object, 1);
+               }
+       }
+       CTX_DATA_END;
+       return changed;
+}
+
+static short select_grouped_parent(bContext *C)        /* Makes parent active and de-selected OBACT */
+{
+       Scene *scene= CTX_data_scene(C);
+       View3D *v3d= CTX_wm_view3d(C);
+
+       short changed = 0;
+       Base *baspar, *basact= CTX_data_active_base(C);
+
+       if (!basact || !(basact->object->parent)) return 0; /* we know OBACT is valid */
+
+       baspar= object_in_scene(basact->object->parent, scene);
+
+       /* can be NULL if parent in other scene */
+       if(baspar && BASE_SELECTABLE(v3d, baspar)) {
+               ED_base_object_select(basact, BA_DESELECT);
+               ED_base_object_select(baspar, BA_SELECT);
+               ED_base_object_activate(C, baspar);
+               changed = 1;
+       }
+       return changed;
+}
+
+
+#define GROUP_MENU_MAX 24
+static short select_grouped_group(bContext *C, Object *ob)     /* Select objects in the same group as the active */
+{
+       short changed = 0;
+       Base *base;
+       Group *group, *ob_groups[GROUP_MENU_MAX];
+       char str[10 + (24*GROUP_MENU_MAX)];
+       char *p = str;
+       int group_count=0, menu, i;
+
+       for (   group=G.main->group.first;
+                       group && group_count < GROUP_MENU_MAX;
+                       group=group->id.next
+               ) {
+               if (object_in_group (ob, group)) {
+                       ob_groups[group_count] = group;
+                       group_count++;
+               }
+       }
+
+       if (!group_count)
+               return 0;
+
+       else if (group_count == 1) {
+               group = ob_groups[0];
+               CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+                       if (!(base->flag & SELECT) && object_in_group(base->object, group)) {
+                               ED_base_object_select(base, BA_SELECT);
+                               changed = 1;
+                       }
+               }
+               CTX_DATA_END;
+               return changed;
+       }
+#if 0 // XXX hows this work in 2.5?
+       /* build the menu. */
+       p += sprintf(str, "Groups%%t");
+       for (i=0; i<group_count; i++) {
+               group = ob_groups[i];
+               p += sprintf (p, "|%s%%x%i", group->id.name+2, i);
+       }
+
+       menu = pupmenu (str);
+       if (menu == -1)
+               return 0;
+
+       group = ob_groups[menu];
+       for (base= FIRSTBASE; base; base= base->next) {
+               if (!(base->flag & SELECT) && object_in_group(base->object, group)) {
+                       ED_base_object_select(base, BA_SELECT);
+                       changed = 1;
+               }
+       }
+#endif
+       return changed;
+}
+
+static short select_grouped_object_hooks(bContext *C, Object *ob)
+{
+       Scene *scene= CTX_data_scene(C);
+       View3D *v3d= CTX_wm_view3d(C);
+
+       short changed = 0;
+       Base *base;
+       ModifierData *md;
+       HookModifierData *hmd;
+
+       for (md = ob->modifiers.first; md; md=md->next) {
+               if (md->type==eModifierType_Hook) {
+                       hmd= (HookModifierData*) md;
+                       if (hmd->object && !(hmd->object->flag & SELECT)) {
+                               base= object_in_scene(hmd->object, scene);
+                               if (base && (BASE_SELECTABLE(v3d, base))) {
+                                       ED_base_object_select(base, BA_SELECT);
+                                       changed = 1;
+                               }
+                       }
+               }
+       }
+       return changed;
+}
+
+/* Select objects woth the same parent as the active (siblings),
+ * parent can be NULL also */
+static short select_grouped_siblings(bContext *C, Object *ob)
+{
+       short changed = 0;
+
+       CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+               if ((base->object->parent==ob->parent)  && !(base->flag & SELECT)) {
+                       ED_base_object_select(base, BA_SELECT);
+                       changed = 1;
+               }
+       }
+       CTX_DATA_END;
+       return changed;
+}
+
+static short select_grouped_type(bContext *C, Object *ob)
+{
+       short changed = 0;
+
+       CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+               if ((base->object->type == ob->type) && !(base->flag & SELECT)) {
+                       ED_base_object_select(base, BA_SELECT);
+                       changed = 1;
+               }
+       }
+       CTX_DATA_END;
+       return changed;
+}
+
+static short select_grouped_layer(bContext *C, Object *ob)
+{
+       char changed = 0;
+
+       CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+               if ((base->lay & ob->lay) && !(base->flag & SELECT)) {
+                       ED_base_object_select(base, BA_SELECT);
+                       changed = 1;
+               }
+       }
+       CTX_DATA_END;
+       return changed;
+}
+
+static short select_grouped_index_object(bContext *C, Object *ob)
+{
+       char changed = 0;
+
+       CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+               if ((base->object->index == ob->index) && !(base->flag & SELECT)) {
+                       ED_base_object_select(base, BA_SELECT);
+                       changed = 1;
+               }
+       }
+       CTX_DATA_END;
+       return changed;
+}
+
+static short select_grouped_color(bContext *C, Object *ob)
+{
+       char changed = 0;
+
+       CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+               if (!(base->flag & SELECT) && (FloatCompare(base->object->col, ob->col, 0.005f))) {
+                       ED_base_object_select(base, BA_SELECT);
+                       changed = 1;
+               }
+       }
+       CTX_DATA_END;
+       return changed;
+}
+
+static short objects_share_gameprop(Object *a, Object *b)
+{
+       bProperty *prop;
+       /*make a copy of all its properties*/
+
+       for( prop= a->prop.first; prop; prop = prop->next ) {
+               if ( get_ob_property(b, prop->name) )
+                       return 1;
+       }
+       return 0;
+}
+
+static short select_grouped_gameprops(bContext *C, Object *ob)
+{
+       char changed = 0;
+
+       CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
+               if (!(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) {
+                       ED_base_object_select(base, BA_SELECT);
+                       changed = 1;
+               }
+       }
+       CTX_DATA_END;
+       return changed;
+}
+
+static int object_select_grouped_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob;
+       int nr = RNA_enum_get(op->ptr, "type");
+       short changed = 0, seltype;
+
+       seltype = RNA_enum_get(op->ptr, "seltype");
+       
+       if (seltype == 0) {
+               CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+                       ED_base_object_select(base, BA_DESELECT);
+               }
+               CTX_DATA_END;
+       }
+       
+       ob= OBACT;
+       if(ob==0){ 
+               BKE_report(op->reports, RPT_ERROR, "No Active Object");
+               return OPERATOR_CANCELLED;
+       }
+       
+       if(nr==1)               changed = select_grouped_children(C, ob, 1);
+       else if(nr==2)  changed = select_grouped_children(C, ob, 0);
+       else if(nr==3)  changed = select_grouped_parent(C);
+       else if(nr==4)  changed = select_grouped_siblings(C, ob);
+       else if(nr==5)  changed = select_grouped_type(C, ob);
+       else if(nr==6)  changed = select_grouped_layer(C, ob);
+       else if(nr==7)  changed = select_grouped_group(C, ob);
+       else if(nr==8)  changed = select_grouped_object_hooks(C, ob);
+       else if(nr==9)  changed = select_grouped_index_object(C, ob);
+       else if(nr==10) changed = select_grouped_color(C, ob);
+       else if(nr==11) changed = select_grouped_gameprops(C, ob);
+       
+       if (changed) {
+               WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
+               return OPERATOR_FINISHED;
+       }
+       
+       return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_select_grouped(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select Grouped";
+       ot->description = "Select all visible objects grouped by various properties.";
+       ot->idname= "OBJECT_OT_select_grouped";
+       
+       /* api callbacks */
+       ot->invoke= WM_menu_invoke;
+       ot->exec= object_select_grouped_exec;
+       ot->poll= ED_operator_scene_editable;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
+       RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
+
+}
+
 /* ****** selection by layer *******/
 
 static int object_select_by_layer_exec(bContext *C, wmOperator *op)
index 2173e79ac66e839e8ca44f0e16f5d058d86b7e36..748e8f7b39675b059b70ae1aad698445f3d98f52 100644 (file)
@@ -50,6 +50,7 @@ void OBJECT_OT_select_random(struct wmOperatorType *ot);
 void OBJECT_OT_select_by_type(struct wmOperatorType *ot);
 void OBJECT_OT_select_by_layer(struct wmOperatorType *ot);
 void OBJECT_OT_select_linked(struct wmOperatorType *ot);
+void OBJECT_OT_select_grouped(struct wmOperatorType *ot);
 void OBJECT_OT_location_clear(struct wmOperatorType *ot);
 void OBJECT_OT_rotation_clear(struct wmOperatorType *ot);
 void OBJECT_OT_scale_clear(struct wmOperatorType *ot);
index 50c1467393943208fbd1814b64cc2f4319dcf430..258fc3386cfe2edf3e0be752609a439f358fca37 100644 (file)
@@ -74,6 +74,7 @@ void ED_operatortypes_object(void)
        WM_operatortype_append(OBJECT_OT_select_by_type);
        WM_operatortype_append(OBJECT_OT_select_by_layer);
        WM_operatortype_append(OBJECT_OT_select_linked);
+       WM_operatortype_append(OBJECT_OT_select_grouped);
        WM_operatortype_append(OBJECT_OT_location_clear);
        WM_operatortype_append(OBJECT_OT_rotation_clear);
        WM_operatortype_append(OBJECT_OT_scale_clear);
@@ -144,6 +145,7 @@ void ED_keymap_object(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "OBJECT_OT_select_by_type", PADASTERKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "OBJECT_OT_select_by_layer", PADASTERKEY, KM_PRESS, KM_ALT, 0);
        WM_keymap_add_item(keymap, "OBJECT_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0);
+       WM_keymap_add_item(keymap, "OBJECT_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
        
        WM_keymap_verify_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_verify_item(keymap, "OBJECT_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
index e52d28864390bd7d5b68a3192b7351a682ca90b5..9b6b70eb396d577668db618e9939c055768886b4 100644 (file)
@@ -675,6 +675,22 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
                
                return 1;
        }
+       else if(CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
+               int selectable_objects= CTX_data_equals(member, "selectable_objects");
+
+               for(base=scene->base.first; base; base=base->next) {
+                       if(base->lay & v3d->lay) {
+                               if((base->object->restrictflag & OB_RESTRICT_VIEW)==0 && (base->object->restrictflag & OB_RESTRICT_SELECT)==0) {
+                                       if(selectable_objects)
+                                               CTX_data_id_list_add(result, &base->object->id);
+                                       else
+                                               CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
+                               }
+                       }
+               }
+               
+               return 1;
+       }
        else if(CTX_data_equals(member, "active_base")) {
                if(scene->basact && (scene->basact->lay & v3d->lay))
                        if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0)
index e6d3ec54d446832fea51a109fdb5d66bfd40fc0d..387c3c7626adc5db8f19dbbda207e0edc135b6d1 100644 (file)
@@ -1039,6 +1039,7 @@ static void view3d_select_objectmenu(bContext *C, uiLayout *layout, void *arg_un
        uiItemO(layout, "Random", 0, "OBJECT_OT_select_random");
        uiItemO(layout, "Select All by Layer", 0, "OBJECT_OT_select_by_layer");
        uiItemMenuEnumO(layout, "Select All by Type", 0, "OBJECT_OT_select_by_type", "type");
+       uiItemMenuEnumO(layout, "Select Grouped", 0, "OBJECT_OT_select_grouped", "type");
 
 #if 0
        uiDefIconTextBlockBut(block, view3d_select_object_layermenu, NULL, ICON_RIGHTARROW_THIN, "Select All by Layer", 0, yco-=20, 120, 19, "");
index 91f90525c1e5d66a1e1e09f9890651f0b1dd0e06..fc0f3a7aa1917a9449f08147a93a95c54ce73435 100644 (file)
@@ -307,7 +307,7 @@ endif
     export FREEDESKTOP ?= true
 
     export NAN_PYTHON ?= /usr
-    export NAN_PYTHON_VERSION ?= 2.5
+    export NAN_PYTHON_VERSION ?= 2.6
     export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
     export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
     export NAN_OPENAL ?= /usr