diff options
-rw-r--r-- | source/blender/blenkernel/BKE_context.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/context.c | 10 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 303 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 16 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_header.c | 1 | ||||
-rw-r--r-- | source/nan_definitions.mk | 2 |
8 files changed, 337 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index f536e117b7b..92c79ff757f 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -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); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 4a68d90a4ed..1b499384886 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -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"); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 9ea8907e172..f122412fdd6 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -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) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 2173e79ac66..748e8f7b396 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -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); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 50c14673939..258fc3386cf 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -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); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index e52d2886439..9b6b70eb396 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -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) diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index e6d3ec54d44..387c3c7626a 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -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, ""); diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index 91f90525c1e..fc0f3a7aa19 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -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 |