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:
authorJoseph Eagar <joeedh@gmail.com>2009-08-26 14:27:04 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-08-26 14:27:04 +0400
commitde7f08cc41c7087ecde096c89ee58f43ccb1cf91 (patch)
tree401ab2a2a7429c2caa63c3135341958155a86935 /source/blender/editors/object
parenta34ffefa0025d144826cd1bf7a136af743847f1b (diff)
parentd893b0f9ff5fc21277b9c24568e224961537c23c (diff)
merge with 2.5 at r22793
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r--source/blender/editors/object/editconstraint.c4
-rw-r--r--source/blender/editors/object/object_edit.c272
-rw-r--r--source/blender/editors/object/object_intern.h12
-rw-r--r--source/blender/editors/object/object_modifier.c317
-rw-r--r--source/blender/editors/object/object_ops.c17
-rw-r--r--source/blender/editors/object/object_vgroup.c5
6 files changed, 466 insertions, 161 deletions
diff --git a/source/blender/editors/object/editconstraint.c b/source/blender/editors/object/editconstraint.c
index 9e8205e58ab..23b3caf8e26 100644
--- a/source/blender/editors/object/editconstraint.c
+++ b/source/blender/editors/object/editconstraint.c
@@ -87,7 +87,7 @@ ListBase *get_active_constraints (Object *ob)
if (ob == NULL)
return NULL;
- if (ob->flag & OB_POSEMODE) {
+ if (ob->mode & OB_MODE_POSE) {
bPoseChannel *pchan;
pchan = get_active_posechannel(ob);
@@ -1065,7 +1065,7 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
{
/* if this constraint is being added to a posechannel, make sure
* the constraint gets evaluated in pose-space */
- if (ob->flag & OB_POSEMODE) {
+ if (ob->mode & OB_MODE_POSE) {
con->ownspace = CONSTRAINT_SPACE_POSE;
con->flag |= CONSTRAINT_SPACEONCE;
}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 780fa526b33..db94dfb1ec8 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -99,6 +99,7 @@
#include "BKE_tessmesh.h"
#include "BKE_nla.h"
#include "BKE_object.h"
+#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_property.h"
#include "BKE_report.h"
@@ -127,6 +128,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
/* for menu/popup icons etc etc*/
#include "UI_interface.h"
@@ -178,10 +180,6 @@ void ED_base_object_activate(bContext *C, Base *base)
Scene *scene= CTX_data_scene(C);
Base *tbase;
- /* activating a non-mesh, should end a couple of modes... */
- if(base && base->object->type!=OB_MESH)
- ED_view3d_exit_paint_modes(C);
-
/* sets scene->basact */
BASACT= base;
@@ -273,9 +271,6 @@ static Object *object_add_type(bContext *C, int type)
Scene *scene= CTX_data_scene(C);
Object *ob;
- /* XXX hrms, this is editor level operator, remove? */
- ED_view3d_exit_paint_modes(C);
-
/* for as long scene has editmode... */
if (CTX_data_edit_object(C))
ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */
@@ -752,8 +747,6 @@ static int object_delete_exec(bContext *C, wmOperator *op)
if(CTX_data_edit_object(C))
return OPERATOR_CANCELLED;
- ED_view3d_exit_paint_modes(C);
-
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
if(base->object->type==OB_LAMP) islamp= 1;
@@ -989,6 +982,8 @@ static void select_editmesh_hook(Object *ob, HookModifierData *hmd)
BMIter iter;
int index=0, nr=0;
+ if (hmd->indexar == NULL)
+ return;
BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
if(nr==hmd->indexar[index]) {
BM_Select(em->bm, eve, 1);
@@ -1158,7 +1153,7 @@ void ED_object_apply_obmat(Object *ob)
}
-int hook_getIndexArray(Object *obedit, int *tot, int **indexar, char *name, float *cent_r)
+int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r)
{
*indexar= NULL;
*tot= 0;
@@ -1237,9 +1232,8 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd)
}
}
-void obedit_hook_select(Object *ob, HookModifierData *hmd)
+void object_hook_select(Object *ob, HookModifierData *hmd)
{
-
if(ob->type==OB_MESH) select_editmesh_hook(ob, hmd);
else if(ob->type==OB_LATTICE) select_editlattice_hook(ob, hmd);
else if(ob->type==OB_CURVE) select_editcurve_hook(ob, hmd);
@@ -1323,7 +1317,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
int tot, ok, *indexar;
char name[32];
- ok = hook_getIndexArray(obedit, &tot, &indexar, name, cent);
+ ok = object_hook_index_array(obedit, &tot, &indexar, name, cent);
if(ok==0) {
error("Requires selected vertices or active Vertex Group");
@@ -1367,6 +1361,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
hmd->totindex= tot;
BLI_strncpy(hmd->name, name, 32);
+ // TODO: need to take into account bone targets here too now...
if(mode==1 || mode==2) {
/* matrix calculus */
/* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
@@ -1386,9 +1381,11 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
modifier_free(md);
}
else if(mode==5) { /* select */
- obedit_hook_select(obedit, hmd);
+ // FIXME: this is now OBJECT_OT_hook_select
+ object_hook_select(obedit, hmd);
}
else if(mode==6) { /* clear offset */
+ // FIXME: this is now OBJECT_OT_hook_reset operator
where_is_object(scene, ob); /* ob is hook->parent */
Mat4Invert(ob->imat, ob->obmat);
@@ -1400,6 +1397,25 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
DAG_scene_sort(scene);
}
+void add_hook_menu(Scene *scene, View3D *v3d)
+{
+ Object *obedit= scene->obedit; // XXX get from context
+ int mode;
+
+ if(obedit==NULL) return;
+
+ if(modifiers_findByType(obedit, eModifierType_Hook))
+ mode= pupmenu("Hooks %t|Add, To New Empty %x1|Add, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6");
+ else
+ mode= pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2");
+
+ if(mode<1) return;
+
+ /* do operations */
+ add_hook(scene, v3d, mode);
+}
+
+
/* use this when the loc/size/rot of the parent has changed but the children should stay in the same place
* apply-size-rot or object center for eg */
@@ -1418,25 +1434,6 @@ static void ignore_parent_tx(Scene *scene, Object *ob )
}
}
-
-void add_hook_menu(Scene *scene, View3D *v3d)
-{
- Object *obedit= scene->obedit; // XXX get from context
- int mode;
-
- if(obedit==NULL) return;
-
- if(modifiers_findByType(obedit, eModifierType_Hook))
- mode= pupmenu("Hooks %t|Add, To New Empty %x1|Add, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6");
- else
- mode= pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2");
-
- if(mode<1) return;
-
- /* do operations */
- add_hook(scene, v3d, mode);
-}
-
/* ******************** clear parent operator ******************* */
static EnumPropertyItem prop_clear_parent_types[] = {
@@ -2244,7 +2241,7 @@ static int object_location_clear_exec(bContext *C, wmOperator *op)
int armature_clear= 0;
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
- if((G.f & G_WEIGHTPAINT)==0) {
+ if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
if ((ob->protectflag & OB_LOCK_LOCX)==0)
ob->loc[0]= ob->dloc[0]= 0.0f;
if ((ob->protectflag & OB_LOCK_LOCY)==0)
@@ -2287,7 +2284,7 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op)
int armature_clear= 0;
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
- if((G.f & G_WEIGHTPAINT)==0) {
+ if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
/* eulers can only get cleared if they are not protected */
if ((ob->protectflag & OB_LOCK_ROTX)==0)
ob->rot[0]= ob->drot[0]= 0.0f;
@@ -2331,7 +2328,7 @@ static int object_scale_clear_exec(bContext *C, wmOperator *op)
int armature_clear= 0;
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
- if((G.f & G_WEIGHTPAINT)==0) {
+ if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
if ((ob->protectflag & OB_LOCK_SCALEX)==0) {
ob->dsize[0]= 0.0f;
ob->size[0]= 1.0f;
@@ -2758,13 +2755,10 @@ static void proxy_group_objects_menu (bContext *C, wmOperator *op, Object *ob, G
if (go->ob) {
PointerRNA props_ptr;
- /* create operator properties, and assign the relevant pointers to that,
- * and add a menu entry which uses these props
- */
- WM_operator_properties_create(&props_ptr, op->idname);
+ /* create operator menu item with relevant properties filled in */
+ props_ptr= uiItemFullO(layout, go->ob->id.name+2, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
RNA_string_set(&props_ptr, "object", go->ob->id.name+2);
RNA_string_set(&props_ptr, "group_object", go->ob->id.name+2);
- uiItemFullO(layout, go->ob->id.name+2, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN);
}
}
@@ -2792,12 +2786,9 @@ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt)
uiLayout *layout= uiPupMenuLayout(pup);
PointerRNA props_ptr;
- /* create operator properties, and assign the relevant pointers to that,
- * and add a menu entry which uses these props
- */
- WM_operator_properties_create(&props_ptr, op->idname);
+ /* create operator menu item with relevant properties filled in */
+ props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
RNA_string_set(&props_ptr, "object", ob->id.name+2);
- uiItemFullO(layout, op->type->name, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN);
/* present the menu and be done... */
uiPupMenuEnd(C, pup);
@@ -3696,7 +3687,7 @@ void ED_object_exit_editmode(bContext *C, int flag)
me->edit_btmesh= NULL;
}
- if(G.f & G_WEIGHTPAINT)
+ if(obedit->restore_mode & OB_MODE_WEIGHT_PAINT)
mesh_octree_table(obedit, NULL, NULL, 'e');
}
else if (obedit->type==OB_ARMATURE) {
@@ -3735,6 +3726,9 @@ void ED_object_exit_editmode(bContext *C, int flag)
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene);
}
+
+ obedit->mode &= ~OB_MODE_EDIT;
+ ED_object_toggle_modes(C, obedit->restore_mode);
}
@@ -3768,7 +3762,10 @@ void ED_object_enter_editmode(bContext *C, int flag)
if(flag & EM_WAITCURSOR) waitcursor(1);
- ED_view3d_exit_paint_modes(C);
+ ob->restore_mode = ob->mode;
+ ED_object_toggle_modes(C, ob->mode);
+
+ ob->mode |= OB_MODE_EDIT;
if(ob->type==OB_MESH) {
Mesh *me= ob->data;
@@ -3856,6 +3853,16 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int editmode_toggle_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+
+ return ob && (ob->type == OB_MESH || ob->type == OB_ARMATURE ||
+ ob->type == OB_FONT || ob->type == OB_MBALL ||
+ ob->type == OB_LATTICE || ob->type == OB_SURF ||
+ ob->type == OB_CURVE);
+}
+
void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
{
@@ -3867,7 +3874,7 @@ void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
/* api callbacks */
ot->exec= editmode_toggle_exec;
- ot->poll= ED_operator_object_active;
+ ot->poll= editmode_toggle_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -3884,7 +3891,7 @@ static int posemode_exec(bContext *C, wmOperator *op)
ED_object_exit_editmode(C, EM_FREEDATA);
ED_armature_enter_posemode(C, base);
}
- else if(base->object->flag & OB_POSEMODE)
+ else if(base->object->mode & OB_MODE_POSE)
ED_armature_exit_posemode(C, base);
else
ED_armature_enter_posemode(C, base);
@@ -4107,10 +4114,10 @@ void special_editmenu(Scene *scene, View3D *v3d)
if(obedit==NULL) {
- if(ob->flag & OB_POSEMODE) {
+ if(ob->mode & OB_MODE_POSE) {
// XXX pose_special_editmenu();
}
- else if(FACESEL_PAINT_TEST) {
+ else if(paint_facesel_test(ob)) {
Mesh *me= get_mesh(ob);
MTFace *tface;
MFace *mface;
@@ -4156,7 +4163,7 @@ void special_editmenu(Scene *scene, View3D *v3d)
}
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
}
- else if(G.f & G_VERTEXPAINT) {
+ else if(ob->mode & OB_MODE_VERTEX_PAINT) {
Mesh *me= get_mesh(ob);
if(me==0 || (me->mcol==NULL && me->mtface==NULL) ) return;
@@ -4169,17 +4176,17 @@ void special_editmenu(Scene *scene, View3D *v3d)
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
}
}
- else if(G.f & G_WEIGHTPAINT) {
+ else if(ob->mode & OB_MODE_WEIGHT_PAINT) {
Object *par= modifiers_isDeformedByArmature(ob);
- if(par && (par->flag & OB_POSEMODE)) {
+ if(par && (par->mode & OB_MODE_POSE)) {
nr= pupmenu("Specials%t|Apply Bone Envelopes to Vertex Groups %x1|Apply Bone Heat Weights to Vertex Groups %x2");
// XXX if(nr==1 || nr==2)
// XXX pose_adds_vgroups(ob, (nr == 2));
}
}
- else if(G.f & G_PARTICLEEDIT) {
+ else if(ob->mode & OB_MODE_PARTICLE_EDIT) {
#if 0
// XXX
ParticleSystem *psys = PE_get_current(ob);
@@ -5721,7 +5728,7 @@ void new_id_matar(Material **matar, int totcol)
}
}
-void single_obdata_users(Scene *scene, View3D *v3d, int flag)
+void single_obdata_users(Scene *scene, int flag)
{
Object *ob;
Lamp *la;
@@ -5844,7 +5851,7 @@ void single_obdata_users(Scene *scene, View3D *v3d, int flag)
}
}
-void single_ipo_users(Scene *scene, View3D *v3d, int flag)
+void single_ipo_users(Scene *scene, int flag)
{
#if 0 // XXX old animation system
Object *ob;
@@ -5867,7 +5874,7 @@ void single_ipo_users(Scene *scene, View3D *v3d, int flag)
#endif // XXX old animation system
}
-void single_mat_users(Scene *scene, View3D *v3d, int flag)
+void single_mat_users(Scene *scene, int flag)
{
Object *ob;
Base *base;
@@ -6053,19 +6060,19 @@ void single_user(Scene *scene, View3D *v3d)
else if(nr==2) {
single_object_users(scene, v3d, 1);
- single_obdata_users(scene, v3d, 1);
+ single_obdata_users(scene, 1);
}
else if(nr==3) {
single_object_users(scene, v3d, 1);
- single_obdata_users(scene, v3d, 1);
- single_mat_users(scene, v3d, 1); /* also tex */
+ single_obdata_users(scene, 1);
+ single_mat_users(scene, 1); /* also tex */
}
else if(nr==4) {
- single_mat_users(scene, v3d, 1);
+ single_mat_users(scene, 1);
}
else if(nr==5) {
- single_ipo_users(scene, v3d, 1);
+ single_ipo_users(scene, 1);
}
@@ -6074,6 +6081,20 @@ void single_user(Scene *scene, View3D *v3d)
}
}
+/* used for copying scenes */
+void ED_object_single_users(Scene *scene, int full)
+{
+ single_object_users(scene, NULL, 0);
+
+ if(full) {
+ single_obdata_users(scene, 0);
+ single_mat_users_expand();
+ single_tex_users_expand();
+ }
+
+ clear_id_newpoins();
+}
+
/* ************************************************************* */
/* helper for below, ma was checked to be not NULL */
@@ -6278,7 +6299,7 @@ static Base *object_add_duplicate_internal(Scene *scene, Base *base, int dupflag
int a, didit;
ob= base->object;
- if(ob->flag & OB_POSEMODE) {
+ if(ob->mode & OB_MODE_POSE) {
; /* nothing? */
}
else {
@@ -7014,3 +7035,124 @@ void hookmenu(Scene *scene, View3D *v3d)
if (changed) {
}
}
+
+static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *ptr, int *free)
+{
+ EnumPropertyItem *input = object_mode_items;
+ EnumPropertyItem *item= NULL;
+ Object *ob;
+ int totitem= 0;
+
+ if(!C) /* needed for docs */
+ return object_mode_items;
+
+ ob = CTX_data_active_object(C);
+ while(ob && input->identifier) {
+ if((input->value == OB_MODE_EDIT && ((ob->type == OB_MESH) || (ob->type == OB_ARMATURE) ||
+ (ob->type == OB_CURVE) || (ob->type == OB_SURF) ||
+ (ob->type == OB_FONT) || (ob->type == OB_MBALL) || (ob->type == OB_LATTICE))) ||
+ (input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) ||
+ (input->value == OB_MODE_PARTICLE_EDIT && ob->particlesystem.first) ||
+ ((input->value == OB_MODE_SCULPT || input->value == OB_MODE_VERTEX_PAINT ||
+ input->value == OB_MODE_WEIGHT_PAINT || input->value == OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) ||
+ (input->value == OB_MODE_OBJECT))
+ RNA_enum_item_add(&item, &totitem, input);
+ ++input;
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+
+ *free= 1;
+
+ return item;
+}
+
+static const char *object_mode_op_string(int mode)
+{
+ if(mode == OB_MODE_EDIT)
+ return "OBJECT_OT_editmode_toggle";
+ if(mode == OB_MODE_SCULPT)
+ return "SCULPT_OT_sculptmode_toggle";
+ if(mode == OB_MODE_VERTEX_PAINT)
+ return "PAINT_OT_vertex_paint_toggle";
+ if(mode == OB_MODE_WEIGHT_PAINT)
+ return "PAINT_OT_weight_paint_toggle";
+ if(mode == OB_MODE_TEXTURE_PAINT)
+ return "PAINT_OT_texture_paint_toggle";
+ if(mode == OB_MODE_PARTICLE_EDIT)
+ return "PARTICLE_OT_particle_edit_toggle";
+ if(mode == OB_MODE_POSE)
+ return "OBJECT_OT_posemode_toggle";
+ return NULL;
+}
+
+static int object_mode_set_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_active_object(C);
+ ObjectMode mode = RNA_enum_get(op->ptr, "mode");
+ ObjectMode restore_mode = ob->mode;
+ int toggle = RNA_boolean_get(op->ptr, "toggle");
+
+ if(!ob)
+ return OPERATOR_CANCELLED;
+
+ /* Exit current mode if it's not the mode we're setting */
+ if(ob->mode != OB_MODE_OBJECT && ob->mode != mode)
+ WM_operator_name_call(C, object_mode_op_string(ob->mode), WM_OP_EXEC_REGION_WIN, NULL);
+
+ if(mode != OB_MODE_OBJECT) {
+ /* Enter new mode */
+ if(ob->mode != mode || toggle)
+ WM_operator_name_call(C, object_mode_op_string(mode), WM_OP_EXEC_REGION_WIN, NULL);
+
+ if(toggle) {
+ if(ob->mode == mode)
+ /* For toggling, store old mode so we know what to go back to */
+ ob->restore_mode = restore_mode;
+ else if(ob->restore_mode != OB_MODE_OBJECT && ob->restore_mode != mode) {
+ WM_operator_name_call(C, object_mode_op_string(ob->restore_mode), WM_OP_EXEC_REGION_WIN, NULL);
+ }
+ }
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_mode_set(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name= "Set Object Mode";
+ ot->description = "Sets the object interaction mode.";
+ ot->idname= "OBJECT_OT_mode_set";
+
+ /* api callbacks */
+ ot->exec= object_mode_set_exec;
+
+ ot->poll= ED_operator_object_active;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ prop= RNA_def_enum(ot->srna, "mode", object_mode_items, 0, "Mode", "");
+ RNA_def_enum_funcs(prop, object_mode_set_itemsf);
+
+ RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "");
+}
+
+
+
+void ED_object_toggle_modes(bContext *C, int mode)
+{
+ if(mode & OB_MODE_SCULPT)
+ WM_operator_name_call(C, "SCULPT_OT_sculptmode_toggle", WM_OP_EXEC_REGION_WIN, NULL);
+ if(mode & OB_MODE_VERTEX_PAINT)
+ WM_operator_name_call(C, "PAINT_OT_vertex_paint_toggle", WM_OP_EXEC_REGION_WIN, NULL);
+ if(mode & OB_MODE_WEIGHT_PAINT)
+ WM_operator_name_call(C, "PAINT_OT_weight_paint_toggle", WM_OP_EXEC_REGION_WIN, NULL);
+ if(mode & OB_MODE_TEXTURE_PAINT)
+ WM_operator_name_call(C, "PAINT_OT_texture_paint_toggle", WM_OP_EXEC_REGION_WIN, NULL);
+ if(mode & OB_MODE_PARTICLE_EDIT)
+ WM_operator_name_call(C, "PARTICLE_OT_particle_edit_toggle", WM_OP_EXEC_REGION_WIN, NULL);
+}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 17d4f5deaae..2f164102be2 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -34,11 +34,13 @@ struct Lattice;
struct Curve;
struct Object;
struct Mesh;
+struct HookModifierData;
/* internal exports only */
/* object_edit.c */
+void OBJECT_OT_mode_set(struct wmOperatorType *ot);
void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot);
void OBJECT_OT_posemode_toggle(struct wmOperatorType *ot);
void OBJECT_OT_parent_set(struct wmOperatorType *ot);
@@ -79,6 +81,9 @@ void OBJECT_OT_armature_add(struct wmOperatorType *ot);
/* only used as menu */
void OBJECT_OT_primitive_add(struct wmOperatorType *ot);
+int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r);
+void object_hook_select(Object *obedit, struct HookModifierData *hmd);
+
/* editlattice.c */
void free_editLatt(Object *ob);
void make_editLatt(Object *obedit);
@@ -103,7 +108,12 @@ void OBJECT_OT_modifier_apply(struct wmOperatorType *ot);
void OBJECT_OT_modifier_convert(struct wmOperatorType *ot);
void OBJECT_OT_modifier_copy(struct wmOperatorType *ot);
void OBJECT_OT_multires_subdivide(struct wmOperatorType *ot);
-void OBJECT_OT_modifier_mdef_bind(struct wmOperatorType *ot);
+void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot);
+void OBJECT_OT_hook_reset(struct wmOperatorType *ot);
+void OBJECT_OT_hook_recenter(struct wmOperatorType *ot);
+void OBJECT_OT_hook_select(struct wmOperatorType *ot);
+void OBJECT_OT_hook_assign(struct wmOperatorType *ot);
+void OBJECT_OT_explode_refresh(struct wmOperatorType *ot);
/* editconstraint.c */
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 6b9f2db0d96..0b8fedd2eda 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -31,6 +31,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_action_types.h"
#include "DNA_curve_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -39,8 +40,10 @@
#include "DNA_object_force.h"
#include "DNA_scene_types.h"
+#include "BLI_arithb.h"
#include "BLI_listbase.h"
+#include "BKE_action.h"
#include "BKE_curve.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
@@ -226,7 +229,7 @@ int ED_object_modifier_convert(ReportList *reports, Scene *scene, Object *ob, Mo
int totpart=0, totchild=0;
if(md->type != eModifierType_ParticleSystem) return 0;
- if(G.f & G_PARTICLEEDIT) return 0;
+ if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
psys=((ParticleSystemModifierData *)md)->psys;
part= psys->part;
@@ -403,6 +406,11 @@ int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md)
/***************************** OPERATORS ****************************/
+static int modifier_poll(bContext *C)
+{
+ return (CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier).data != NULL);
+}
+
/************************ add modifier operator *********************/
static int modifier_add_exec(bContext *C, wmOperator *op)
@@ -419,8 +427,46 @@ static int modifier_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *ptr, int *free)
+{
+ EnumPropertyItem *item= NULL, *md_item;
+ ModifierTypeInfo *mti;
+ Object *ob;
+ int totitem= 0, a;
+
+ if(!C) /* needed for docs */
+ return modifier_type_items;
+
+ ob= CTX_data_active_object(C);
+
+ for(a=0; modifier_type_items[a].identifier; a++) {
+ md_item= &modifier_type_items[a];
+
+ if(md_item->identifier[0]) {
+ mti= modifierType_getInfo(md_item->value);
+
+ if(mti->flags & eModifierTypeFlag_NoUserAdd)
+ continue;
+
+ if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
+ (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
+ continue;
+ }
+
+ RNA_enum_item_add(&item, &totitem, md_item);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+
+ *free= 1;
+
+ return item;
+}
+
void OBJECT_OT_modifier_add(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name= "Add Modifier";
ot->description = "Add a modifier to the active object.";
@@ -429,14 +475,14 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot)
/* api callbacks */
ot->invoke= WM_menu_invoke;
ot->exec= modifier_add_exec;
-
ot->poll= ED_operator_object_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- /* XXX only some types should be here */
- RNA_def_enum(ot->srna, "type", modifier_type_items, 0, "Type", "");
+ /* properties */
+ prop= RNA_def_enum(ot->srna, "type", modifier_type_items, eModifierType_Subsurf, "Type", "");
+ RNA_def_enum_funcs(prop, modifier_add_itemf);
}
/************************ remove modifier operator *********************/
@@ -448,7 +494,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
Object *ob= ptr.id.data;
ModifierData *md= ptr.data;
- if(!ob || !md || !ED_object_modifier_remove(op->reports, scene, ob, md))
+ if(!ED_object_modifier_remove(op->reports, scene, ob, md))
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
@@ -464,6 +510,7 @@ void OBJECT_OT_modifier_remove(wmOperatorType *ot)
ot->poll= ED_operator_object_active;
ot->exec= modifier_remove_exec;
+ ot->poll= modifier_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -478,7 +525,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op)
Object *ob= ptr.id.data;
ModifierData *md= ptr.data;
- if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
+ if(!ED_object_modifier_move_up(op->reports, ob, md))
return OPERATOR_CANCELLED;
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
@@ -495,6 +542,7 @@ void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
ot->poll= ED_operator_object_active;
ot->exec= modifier_move_up_exec;
+ ot->poll= modifier_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -526,6 +574,7 @@ void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
ot->poll= ED_operator_object_active;
ot->exec= modifier_move_down_exec;
+ ot->poll= modifier_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -557,6 +606,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
ot->poll= ED_operator_object_active;
ot->exec= modifier_apply_exec;
+ ot->poll= modifier_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -588,6 +638,7 @@ void OBJECT_OT_modifier_convert(wmOperatorType *ot)
ot->poll= ED_operator_object_active;
ot->exec= modifier_convert_exec;
+ ot->poll= modifier_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -619,6 +670,7 @@ void OBJECT_OT_modifier_copy(wmOperatorType *ot)
ot->poll= ED_operator_object_active;
ot->exec= modifier_copy_exec;
+ ot->poll= modifier_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -632,22 +684,26 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
Object *ob= ptr.id.data;
MultiresModifierData *mmd= ptr.data;
- if(mmd) {
- multiresModifier_subdivide(mmd, ob, 1, 0, mmd->simple);
- WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
- }
+ multiresModifier_subdivide(mmd, ob, 1, 0, mmd->simple);
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
return OPERATOR_FINISHED;
}
+static int multires_subdivide_poll(bContext *C)
+{
+ return (CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier).data != NULL) &&
+ CTX_data_edit_object(C) == NULL;
+}
+
void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
{
ot->name= "Multires Subdivide";
ot->description= "Add a new level of subdivision.";
ot->idname= "OBJECT_OT_multires_subdivide";
- ot->poll= ED_operator_object_active;
ot->exec= multires_subdivide_exec;
+ ot->poll= multires_subdivide_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -655,12 +711,12 @@ void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
/************************ mdef bind operator *********************/
-static int modifier_mdef_bind_poll(bContext *C)
+static int meshdeform_poll(bContext *C)
{
return CTX_data_pointer_get_type(C, "modifier", &RNA_MeshDeformModifier).data != NULL;
}
-static int modifier_mdef_bind_exec(bContext *C, wmOperator *op)
+static int meshdeform_bind_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
PointerRNA ptr= CTX_data_pointer_get(C, "modifier");
@@ -711,41 +767,22 @@ static int modifier_mdef_bind_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_modifier_mdef_bind(wmOperatorType *ot)
+void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Mesh Deform Bind";
ot->description = "Bind mesh to cage in mesh deform modifier.";
- ot->idname= "OBJECT_OT_modifier_mdef_bind";
+ ot->idname= "OBJECT_OT_meshdeform_bind";
/* api callbacks */
- ot->poll= modifier_mdef_bind_poll;
- ot->exec= modifier_mdef_bind_exec;
+ ot->poll= meshdeform_poll;
+ ot->exec= meshdeform_bind_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
#if 0
-static void modifiers_add(void *ob_v, int type)
-{
- Object *ob = ob_v;
- ModifierTypeInfo *mti = modifierType_getInfo(type);
-
- if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
- ModifierData *md = ob->modifiers.first;
-
- while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
- md = md->next;
- }
-
- BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
- } else {
- BLI_addtail(&ob->modifiers, modifier_new(type));
- }
- ED_undo_push("Add modifier");
-}
-
typedef struct MenuEntry {
char *name;
int ID;
@@ -797,89 +834,189 @@ static uiBlock *modifiers_add_menu(void *ob_v)
}
#endif
-#if 0
-static void modifiers_clearHookOffset(bContext *C, void *ob_v, void *md_v)
+/******************** hook operators ************************/
+
+static int hook_poll(bContext *C)
{
- Object *ob = ob_v;
- ModifierData *md = md_v;
- HookModifierData *hmd = (HookModifierData*) md;
-
- if (hmd->object) {
- Mat4Invert(hmd->object->imat, hmd->object->obmat);
- Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
- ED_undo_push(C, "Clear hook offset");
+ return CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier).data != NULL;
+}
+
+static int hook_reset_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
+ Object *ob= ptr.id.data;
+ HookModifierData *hmd= ptr.data;
+
+ if(hmd->object) {
+ bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
+
+ if(hmd->subtarget[0] && pchan) {
+ float imat[4][4], mat[4][4];
+
+ /* calculate the world-space matrix for the pose-channel target first, then carry on as usual */
+ Mat4MulMat4(mat, pchan->pose_mat, hmd->object->obmat);
+
+ Mat4Invert(imat, mat);
+ Mat4MulSerie(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+ else {
+ Mat4Invert(hmd->object->imat, hmd->object->obmat);
+ Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
}
+
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
}
-static void modifiers_cursorHookCenter(bContext *C, void *ob_v, void *md_v)
+void OBJECT_OT_hook_reset(wmOperatorType *ot)
{
- /* XXX
- Object *ob = ob_v;
- ModifierData *md = md_v;
- HookModifierData *hmd = (HookModifierData*) md;
+ ot->name= "Hook Reset";
+ ot->description= "Recalculate and and clear offset transformation.";
+ ot->idname= "OBJECT_OT_hook_reset";
- if(G.vd) {
- float *curs = give_cursor();
- float bmat[3][3], imat[3][3];
+ ot->exec= hook_reset_exec;
+ ot->poll= hook_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
- where_is_object(ob);
+static int hook_recenter_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
+ Object *ob= ptr.id.data;
+ HookModifierData *hmd= ptr.data;
+ float bmat[3][3], imat[3][3];
+
+ Mat3CpyMat4(bmat, ob->obmat);
+ Mat3Inv(imat, bmat);
+
+ VECSUB(hmd->cent, scene->cursor, ob->obmat[3]);
+ Mat3MulVecfl(imat, hmd->cent);
+
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
- Mat3CpyMat4(bmat, ob->obmat);
- Mat3Inv(imat, bmat);
+ return OPERATOR_FINISHED;
+}
- curs= give_cursor();
- hmd->cent[0]= curs[0]-ob->obmat[3][0];
- hmd->cent[1]= curs[1]-ob->obmat[3][1];
- hmd->cent[2]= curs[2]-ob->obmat[3][2];
- Mat3MulVecfl(imat, hmd->cent);
+void OBJECT_OT_hook_recenter(wmOperatorType *ot)
+{
+ ot->name= "Hook Recenter";
+ ot->description= "Set hook center to cursor position.";
+ ot->idname= "OBJECT_OT_hook_recenter";
- ED_undo_push(C, "Hook cursor center");
- }*/
+ ot->exec= hook_recenter_exec;
+ ot->poll= hook_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static void modifiers_selectHook(bContext *C, void *ob_v, void *md_v)
+static int hook_select_exec(bContext *C, wmOperator *op)
{
- /* XXX ModifierData *md = md_v;
- HookModifierData *hmd = (HookModifierData*) md;
+ PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
+ Object *ob= ptr.id.data;
+ HookModifierData *hmd= ptr.data;
+
+ object_hook_select(ob, hmd);
- hook_select(hmd);*/
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_hook_select(wmOperatorType *ot)
+{
+ ot->name= "Hook Select";
+ ot->description= "Selects effected vertices on mesh.";
+ ot->idname= "OBJECT_OT_hook_select";
+
+ ot->exec= hook_select_exec;
+ ot->poll= hook_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static void modifiers_reassignHook(bContext *C, void *ob_v, void *md_v)
+static int hook_assign_exec(bContext *C, wmOperator *op)
{
- /* XXX ModifierData *md = md_v;
- HookModifierData *hmd = (HookModifierData*) md;
+ Scene *scene= CTX_data_scene(C);
+ PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
+ Object *ob= ptr.id.data;
+ HookModifierData *hmd= ptr.data;
float cent[3];
- int *indexar, tot, ok;
char name[32];
+ int *indexar, tot;
- ok= hook_getIndexArray(&tot, &indexar, name, cent);
+ if(!object_hook_index_array(ob, &tot, &indexar, name, cent)) {
+ BKE_report(op->reports, RPT_WARNING, "Requires selected vertices or active vertex group");
+ return OPERATOR_CANCELLED;
+ }
- if (!ok) {
- uiPupMenuError(C, "Requires selected vertices or active Vertex Group");
- } else {
- if (hmd->indexar) {
- MEM_freeN(hmd->indexar);
- }
+ if(hmd->indexar)
+ MEM_freeN(hmd->indexar);
- VECCOPY(hmd->cent, cent);
- hmd->indexar = indexar;
- hmd->totindex = tot;
- }*/
+ VECCOPY(hmd->cent, cent);
+ hmd->indexar= indexar;
+ hmd->totindex= tot;
+
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
}
-void modifiers_explodeFacepa(bContext *C, void *arg1, void *arg2)
+void OBJECT_OT_hook_assign(wmOperatorType *ot)
{
- ExplodeModifierData *emd=arg1;
+ ot->name= "Hook Assign";
+ ot->description= "Reassigns selected vertices to hook.";
+ ot->idname= "OBJECT_OT_hook_assign";
- emd->flag |= eExplodeFlag_CalcFaces;
+ ot->exec= hook_assign_exec;
+ ot->poll= hook_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-void modifiers_explodeDelVg(bContext *C, void *arg1, void *arg2)
+/****************** explode refresh operator *********************/
+
+static int explode_refresh_poll(bContext *C)
{
- ExplodeModifierData *emd=arg1;
- emd->vgroup = 0;
+ return CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier).data != NULL;
}
-#endif
+static int explode_refresh_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier);
+ Object *ob= ptr.id.data;
+ ExplodeModifierData *emd= ptr.data;
+
+ emd->flag |= eExplodeFlag_CalcFaces;
+
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_explode_refresh(wmOperatorType *ot)
+{
+ ot->name= "Explode Refresh";
+ ot->description= "Refresh data in the Explode modifier.";
+ ot->idname= "OBJECT_OT_explode_refresh";
+
+ ot->exec= explode_refresh_exec;
+ ot->poll= explode_refresh_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index c1509e78502..239b162c14f 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -65,6 +65,7 @@ void ED_operatortypes_object(void)
{
wmOperatorType *ot;
+ WM_operatortype_append(OBJECT_OT_mode_set);
WM_operatortype_append(OBJECT_OT_editmode_toggle);
WM_operatortype_append(OBJECT_OT_posemode_toggle);
WM_operatortype_append(OBJECT_OT_parent_set);
@@ -117,7 +118,12 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_modifier_convert);
WM_operatortype_append(OBJECT_OT_modifier_copy);
WM_operatortype_append(OBJECT_OT_multires_subdivide);
- WM_operatortype_append(OBJECT_OT_modifier_mdef_bind);
+ WM_operatortype_append(OBJECT_OT_meshdeform_bind);
+ WM_operatortype_append(OBJECT_OT_hook_reset);
+ WM_operatortype_append(OBJECT_OT_hook_recenter);
+ WM_operatortype_append(OBJECT_OT_hook_select);
+ WM_operatortype_append(OBJECT_OT_hook_assign);
+ WM_operatortype_append(OBJECT_OT_explode_refresh);
WM_operatortype_append(OBJECT_OT_constraint_add);
WM_operatortype_append(OBJECT_OT_constraint_add_with_targets);
@@ -161,10 +167,19 @@ void ED_operatortypes_object(void)
void ED_keymap_object(wmWindowManager *wm)
{
ListBase *keymap= WM_keymap_listbase(wm, "Object Non-modal", 0, 0);
+ wmKeymapItem *kmi;
/* Note: this keymap works disregarding mode */
WM_keymap_add_item(keymap, "OBJECT_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_posemode_toggle", TABKEY, KM_PRESS, KM_CTRL, 0);
+
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", VKEY, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "mode", OB_MODE_VERTEX_PAINT);
+ RNA_boolean_set(kmi->ptr, "toggle", 1);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_enum_set(kmi->ptr, "mode", OB_MODE_WEIGHT_PAINT);
+ RNA_boolean_set(kmi->ptr, "toggle", 1);
+
WM_keymap_add_item(keymap, "OBJECT_OT_center_set", CKEY, KM_PRESS, KM_ALT|KM_SHIFT|KM_CTRL, 0);
/* Note: this keymap gets disabled in non-objectmode, */
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 3d3e29bcc22..154ab14df60 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -57,6 +57,7 @@
#include "BKE_global.h"
#include "BKE_lattice.h"
#include "BKE_mesh.h"
+#include "BKE_paint.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -1028,11 +1029,11 @@ void vgroup_assign_with_menu(Scene *scene, Object *ob)
switch (mode) {
case 1: /* add to new group */
add_defgroup(ob);
- assign_verts_defgroup(ob, wp->brush->alpha);
+ assign_verts_defgroup(ob, paint_brush(&wp->paint)->alpha);
BIF_undo_push("Assign to vertex group");
break;
case 2: /* add to current group */
- assign_verts_defgroup(ob, wp->brush->alpha);
+ assign_verts_defgroup(ob, paint_brush(&wp->paint)->alpha);
BIF_undo_push("Assign to vertex group");
break;
case 3: /* remove from current group */