Index: source/blender/editors/metaball/mball_ops.c =================================================================== --- source/blender/editors/metaball/mball_ops.c (révision 45380) +++ source/blender/editors/metaball/mball_ops.c (copie de travail) @@ -51,6 +51,7 @@ WM_operatortype_append(MBALL_OT_reveal_metaelems); WM_operatortype_append(MBALL_OT_select_all); + WM_operatortype_append(MBALL_OT_select_similar); WM_operatortype_append(MBALL_OT_select_random_metaelems); } @@ -79,6 +80,8 @@ kmi = WM_keymap_add_item(keymap, "MBALL_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + kmi = WM_keymap_add_item(keymap, "MBALL_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0); + ED_object_generic_keymap(keyconf, keymap, 3); } Index: source/blender/editors/metaball/mball_intern.h =================================================================== --- source/blender/editors/metaball/mball_intern.h (révision 45380) +++ source/blender/editors/metaball/mball_intern.h (copie de travail) @@ -43,6 +43,7 @@ void MBALL_OT_duplicate_metaelems(struct wmOperatorType *ot); void MBALL_OT_select_all(struct wmOperatorType *ot); +void MBALL_OT_select_similar(struct wmOperatorType *ot); void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot); #endif Index: source/blender/editors/metaball/mball_edit.c =================================================================== --- source/blender/editors/metaball/mball_edit.c (révision 45380) +++ source/blender/editors/metaball/mball_edit.c (copie de travail) @@ -181,6 +181,146 @@ WM_operator_properties_select_all(ot); } +/* ****************** SIMILAR "group" SELECTS. ****************** */ + +enum { + SIMMBALL_RADIUS = 1, + SIMMBALL_TYPE, + SIMMBALL_ROTATION +}; + +static EnumPropertyItem prop_similar_types[] = { + {SIMMBALL_RADIUS, "RADIUS", 0, "Radius", ""}, + {SIMMBALL_TYPE, "TYPE", 0, "Type", ""}, + {SIMMBALL_ROTATION, "ROTATION", 0, "Rotation", ""}, + + {0, NULL, 0, NULL, NULL} +}; + +static void select_similar_radius(MetaBall *mb, float thresh) +{ + MetaElem *ml; + MetaElem *mlp; + + ml = mb->editelems->first; + while (ml) { + if (ml->flag & SELECT) { + mlp = mb->editelems->first; + + while (mlp) { + if (fabs(mlp->rad-ml->rad) <= thresh*ml->rad && mlp!=ml) + mlp->flag |=SELECT; + mlp = mlp->next; + } + } + ml= ml->next; + } +} + +static void select_similar_type(MetaBall *mb) +{ + MetaElem *ml; + MetaElem *mlp; + + ml = mb->editelems->first; + while (ml) { + if (ml->flag & SELECT) { + mlp = mb->editelems->first; + while (mlp) { + if (mlp->type == ml->type) + mlp->flag |=SELECT; + mlp = mlp->next; + } + } + ml= ml->next; + } +} + +static void select_similar_rotation(MetaBall *mb) +{ + MetaElem *ml; + MetaElem *mlp; + + ml = mb->editelems->first; + while (ml) { + if (ml->flag & SELECT) { + mlp = mb->editelems->first; + while (mlp) { + if (mlp->quat[0] == ml->quat[0] && mlp->quat[1] == ml->quat[1] + && mlp->quat[2] == ml->quat[2] && mlp->quat[3] == ml->quat[3]) + mlp->flag |=SELECT; + mlp = mlp->next; + } + } + ml= ml->next; + } +} + +static int mball_select_similar_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + MetaBall *mb = (MetaBall*)obedit->data; + + /*get the type from RNA */ + int type = RNA_enum_get(op->ptr, "type"); + float thresh = RNA_float_get(op->ptr, "threshold"); + + if (type == SIMMBALL_RADIUS) { + select_similar_radius(mb, thresh); + } + else if (type == SIMMBALL_TYPE) { + select_similar_type(mb); + } + else { + select_similar_rotation(mb); + } + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); + + return OPERATOR_FINISHED; +} + +static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), + int *free) +{ + Object *obedit = CTX_data_edit_object(C); + + if (obedit && obedit->type == OB_MBALL) { + EnumPropertyItem *item = NULL; + int a, totitem = 0; + for (a = SIMMBALL_RADIUS; a <= SIMMBALL_ROTATION; a++) { + RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a); + } + RNA_enum_item_end(&item, &totitem); + *free = 1; + return item; + } + return NULL; +} + +void MBALL_OT_select_similar(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Select Similar"; + ot->idname = "MBALL_OT_select_similar"; + + /* callback functions */ + ot->invoke = WM_menu_invoke; + ot->exec = mball_select_similar_exec; + ot->poll = ED_operator_editmball; + ot->description = "Select similar metaballs by property types"; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop = ot->prop = RNA_def_enum(ot->srna, "type", prop_similar_types, 0, "Type", ""); + RNA_def_enum_funcs(prop, select_similar_type_itemf); + + RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.01, 1.0); +} + /***************************** Select random operator *****************************/ /* Random metaball selection */