* Re-implemented/refactored 3D View hooks menu.
Now shares the same operators as the modifier buttons, works context-sensitive, and uses Python menu too. * Cleanups/tweaks in 3D View vertex group menu
This commit is contained in:
@@ -746,9 +746,40 @@ class VIEW3D_MT_hook(bpy.types.Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.operator_context = 'EXEC_AREA'
|
||||
layout.items_enumO("object.hook_add", "type")
|
||||
# layout.itemS()
|
||||
# Other operators still need porting
|
||||
layout.itemO("object.hook_add_newob")
|
||||
layout.itemO("object.hook_add_selob")
|
||||
|
||||
if [mod.type == 'HOOK' for mod in context.active_object.modifiers]:
|
||||
layout.itemS()
|
||||
layout.item_menu_enumO("object.hook_assign", "modifier")
|
||||
layout.item_menu_enumO("object.hook_remove", "modifier")
|
||||
layout.itemS()
|
||||
layout.item_menu_enumO("object.hook_select", "modifier")
|
||||
layout.item_menu_enumO("object.hook_reset", "modifier")
|
||||
layout.item_menu_enumO("object.hook_recenter", "modifier")
|
||||
|
||||
|
||||
class VIEW3D_MT_vertex_group(bpy.types.Menu):
|
||||
bl_label = "Vertex Groups"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.operator_context = 'EXEC_AREA'
|
||||
layout.item_booleanO("object.vertex_group_assign", "new", True, text="Assign to New Group")
|
||||
|
||||
ob = context.active_object
|
||||
if ob.mode == 'EDIT':
|
||||
if ob.vertex_groups and ob.active_vertex_group:
|
||||
layout.itemS()
|
||||
layout.itemO("object.vertex_group_assign", text="Assign to Active Group")
|
||||
layout.itemO("object.vertex_group_remove_from", text="Remove from Active Group")
|
||||
layout.item_booleanO("object.vertex_group_remove_from", "all", True, text="Remove from All")
|
||||
layout.itemS()
|
||||
|
||||
if ob.vertex_groups and ob.active_vertex_group:
|
||||
layout.item_menu_enumO("object.vertex_group_set_active", "group", text="Set Active Group")
|
||||
layout.itemO("object.vertex_group_remove", text="Remove Active Group")
|
||||
layout.item_booleanO("object.vertex_group_remove", "all", True, text="Remove All Groups")
|
||||
|
||||
|
||||
# ********** Sculpt menu **********
|
||||
@@ -1062,6 +1093,7 @@ class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.itemM("VIEW3D_MT_vertex_group")
|
||||
layout.itemM("VIEW3D_MT_hook")
|
||||
|
||||
|
||||
@@ -1830,6 +1862,7 @@ bpy.types.register(VIEW3D_MT_make_single_user)
|
||||
bpy.types.register(VIEW3D_MT_make_links)
|
||||
|
||||
bpy.types.register(VIEW3D_MT_hook)
|
||||
bpy.types.register(VIEW3D_MT_vertex_group)
|
||||
|
||||
bpy.types.register(VIEW3D_MT_sculpt) # Sculpt Menu
|
||||
|
||||
|
||||
@@ -297,9 +297,6 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, 0, KKEY);
|
||||
|
||||
// TODO: this should probably be made to a menu instead...
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_vertex_group_menu", GKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
/* menus */
|
||||
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_specials", WKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_faces", FKEY, KM_PRESS, KM_CTRL, 0);
|
||||
@@ -307,7 +304,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
|
||||
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_vertices", VKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_menu(keymap, "VIEW3D_MT_uv_map", UKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_menu(keymap, "VIEW3D_MT_vertex_group", GKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
ED_object_generic_keymap(keyconf, keymap, TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_lattice_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
@@ -45,12 +46,15 @@
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_access.h"
|
||||
@@ -59,13 +63,15 @@
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_view3d.h"
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "object_intern.h"
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
/* XXX operators for this are not implemented yet */
|
||||
#include "object_intern.h"
|
||||
|
||||
static int return_editmesh_indexar(EditMesh *em, int *tot, int **indexar, float *cent)
|
||||
{
|
||||
@@ -286,7 +292,7 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo
|
||||
return totvert;
|
||||
}
|
||||
|
||||
int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r)
|
||||
static int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r)
|
||||
{
|
||||
*indexar= NULL;
|
||||
*tot= 0;
|
||||
@@ -368,7 +374,7 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd)
|
||||
}
|
||||
}
|
||||
|
||||
void object_hook_select(Object *ob, HookModifierData *hmd)
|
||||
static void object_hook_select(Object *ob, HookModifierData *hmd)
|
||||
{
|
||||
if (hmd->indexar == NULL)
|
||||
return;
|
||||
@@ -379,281 +385,440 @@ void object_hook_select(Object *ob, HookModifierData *hmd)
|
||||
else if(ob->type==OB_SURF) select_editcurve_hook(ob, hmd);
|
||||
}
|
||||
|
||||
|
||||
void add_hook(Scene *scene, View3D *v3d, int mode)
|
||||
static Object *add_hook_object_new(Scene *scene, Object *obedit)
|
||||
{
|
||||
ModifierData *md = NULL;
|
||||
Base *base, *basedit;
|
||||
Object *ob;
|
||||
|
||||
ob= add_object(scene, OB_EMPTY);
|
||||
|
||||
basedit = object_in_scene(obedit, scene);
|
||||
base = object_in_scene(ob, scene);
|
||||
base->lay = ob->lay = obedit->lay;
|
||||
|
||||
/* icky, add_object sets new base as active.
|
||||
* so set it back to the original edit object */
|
||||
scene->basact = basedit;
|
||||
|
||||
return ob;
|
||||
}
|
||||
|
||||
|
||||
static void add_hook_object(Scene *scene, Object *obedit, Object *ob, int mode)
|
||||
{
|
||||
ModifierData *md=NULL;
|
||||
HookModifierData *hmd = NULL;
|
||||
Object *ob=NULL;
|
||||
Object *obedit= scene->obedit; // XXX get from context
|
||||
float cent[3];
|
||||
int tot, ok, *indexar;
|
||||
char name[32];
|
||||
|
||||
if(obedit==NULL) return;
|
||||
ok = object_hook_index_array(obedit, &tot, &indexar, name, cent);
|
||||
|
||||
/* preconditions */
|
||||
if(mode==2) { /* selected object */
|
||||
Base *base;
|
||||
for(base= FIRSTBASE; base; base= base->next) {
|
||||
if(TESTBASELIB(v3d, base)) {
|
||||
if(base!=BASACT) {
|
||||
ob= base->object;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ob==NULL) {
|
||||
// XXX error("Requires selected Object");
|
||||
return;
|
||||
}
|
||||
if (!ok) return; // XXX error("Requires selected vertices or active Vertex Group");
|
||||
|
||||
if (mode==OBJECT_ADDHOOK_NEWOB && !ob) {
|
||||
|
||||
ob = add_hook_object_new(scene, obedit);
|
||||
|
||||
/* transform cent to global coords for loc */
|
||||
mul_v3_m4v3(ob->loc, obedit->obmat, cent);
|
||||
}
|
||||
else if(mode!=1) {
|
||||
int maxlen=0, a, nr;
|
||||
char *cp;
|
||||
|
||||
/* make pupmenu with hooks */
|
||||
for(md=obedit->modifiers.first; md; md= md->next) {
|
||||
if (md->type==eModifierType_Hook)
|
||||
maxlen+=32;
|
||||
}
|
||||
|
||||
if(maxlen==0) {
|
||||
// XXX error("Object has no hooks yet");
|
||||
return;
|
||||
}
|
||||
|
||||
cp= MEM_callocN(maxlen+32, "temp string");
|
||||
if(mode==3) strcpy(cp, "Remove %t|");
|
||||
else if(mode==4) strcpy(cp, "Reassign %t|");
|
||||
else if(mode==5) strcpy(cp, "Select %t|");
|
||||
else if(mode==6) strcpy(cp, "Clear Offset %t|");
|
||||
|
||||
for(md=obedit->modifiers.first; md; md= md->next) {
|
||||
if (md->type==eModifierType_Hook) {
|
||||
strcat(cp, md->name);
|
||||
strcat(cp, " |");
|
||||
}
|
||||
}
|
||||
|
||||
nr= 0; // XXX pupmenu(cp);
|
||||
MEM_freeN(cp);
|
||||
|
||||
if(nr<1) return;
|
||||
|
||||
a= 1;
|
||||
for(md=obedit->modifiers.first; md; md=md->next) {
|
||||
if (md->type==eModifierType_Hook) {
|
||||
if(a==nr) break;
|
||||
a++;
|
||||
}
|
||||
}
|
||||
|
||||
hmd = (HookModifierData*) md;
|
||||
ob= hmd->object;
|
||||
|
||||
md = obedit->modifiers.first;
|
||||
while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
|
||||
md = md->next;
|
||||
}
|
||||
|
||||
/* do it, new hooks or reassign */
|
||||
if(mode==1 || mode==2 || mode==4) {
|
||||
float cent[3];
|
||||
int tot, ok, *indexar;
|
||||
char name[32];
|
||||
|
||||
ok = object_hook_index_array(obedit, &tot, &indexar, name, cent);
|
||||
|
||||
if(ok==0) {
|
||||
// XXX error("Requires selected vertices or active Vertex Group");
|
||||
}
|
||||
else {
|
||||
|
||||
if(mode==1) {
|
||||
Base *base= BASACT, *newbase;
|
||||
|
||||
ob= add_object(scene, OB_EMPTY);
|
||||
/* set layers OK */
|
||||
newbase= BASACT;
|
||||
newbase->lay= base->lay;
|
||||
ob->lay= newbase->lay;
|
||||
|
||||
/* transform cent to global coords for loc */
|
||||
mul_v3_m4v3(ob->loc, obedit->obmat, cent);
|
||||
|
||||
/* restore, add_object sets active */
|
||||
BASACT= base;
|
||||
}
|
||||
/* if mode is 2 or 4, ob has been set */
|
||||
|
||||
/* new hook */
|
||||
if(mode==1 || mode==2) {
|
||||
ModifierData *md = obedit->modifiers.first;
|
||||
|
||||
while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
|
||||
md = md->next;
|
||||
}
|
||||
|
||||
hmd = (HookModifierData*) modifier_new(eModifierType_Hook);
|
||||
BLI_insertlinkbefore(&obedit->modifiers, md, hmd);
|
||||
sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2);
|
||||
modifier_unique_name(&obedit->modifiers, (ModifierData*)hmd);
|
||||
}
|
||||
else if (hmd->indexar) MEM_freeN(hmd->indexar); /* reassign, hook was set */
|
||||
|
||||
hmd->object= ob;
|
||||
hmd->indexar= indexar;
|
||||
copy_v3_v3(hmd->cent, cent);
|
||||
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 */
|
||||
/* (parentinv ) */
|
||||
|
||||
where_is_object(scene, ob);
|
||||
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
/* apparently this call goes from right to left... */
|
||||
mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(mode==3) { /* remove */
|
||||
BLI_remlink(&obedit->modifiers, md);
|
||||
modifier_free(md);
|
||||
}
|
||||
else if(mode==5) { /* select */
|
||||
// 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 */
|
||||
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
/* this call goes from right to left... */
|
||||
mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
hmd = (HookModifierData*) modifier_new(eModifierType_Hook);
|
||||
BLI_insertlinkbefore(&obedit->modifiers, md, hmd);
|
||||
sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2);
|
||||
modifier_unique_name(&obedit->modifiers, (ModifierData*)hmd);
|
||||
|
||||
hmd->object= ob;
|
||||
hmd->indexar= indexar;
|
||||
copy_v3_v3(hmd->cent, cent);
|
||||
hmd->totindex= tot;
|
||||
BLI_strncpy(hmd->name, name, 32);
|
||||
|
||||
/* matrix calculus */
|
||||
/* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
|
||||
/* (parentinv ) */
|
||||
where_is_object(scene, ob);
|
||||
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
/* apparently this call goes from right to left... */
|
||||
mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
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= 0; // XXX pupmenu("Hooks %t|Add, To New Empty %x1|Add, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6");
|
||||
else
|
||||
mode= 0; // XXX pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2");
|
||||
|
||||
if(mode<1) return;
|
||||
|
||||
/* do operations */
|
||||
add_hook(scene, v3d, mode);
|
||||
}
|
||||
|
||||
void hookmenu(Scene *scene, View3D *v3d)
|
||||
{
|
||||
/* only called in object mode */
|
||||
short event, changed=0;
|
||||
Object *ob;
|
||||
Base *base;
|
||||
ModifierData *md;
|
||||
HookModifierData *hmd;
|
||||
|
||||
event= 0; // XXX pupmenu("Modify Hooks for Selected...%t|Reset Offset%x1|Recenter at Cursor%x2");
|
||||
if (event==-1) return;
|
||||
if (event==2 && !(v3d)) {
|
||||
// XXX error("Cannot perform this operation without a 3d view");
|
||||
return;
|
||||
}
|
||||
|
||||
for (base= FIRSTBASE; base; base= base->next) {
|
||||
if(TESTBASELIB(v3d, base)) {
|
||||
for (md = base->object->modifiers.first; md; md=md->next) {
|
||||
if (md->type==eModifierType_Hook) {
|
||||
ob = base->object;
|
||||
hmd = (HookModifierData*) md;
|
||||
|
||||
/*
|
||||
* Copied from modifiers_cursorHookCenter and
|
||||
* modifiers_clearHookOffset, should consolidate
|
||||
* */
|
||||
|
||||
if (event==1) {
|
||||
if(hmd->object) {
|
||||
invert_m4_m4(hmd->object->imat, hmd->object->obmat);
|
||||
mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
changed= 1;
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
} else {
|
||||
float *curs = give_cursor(scene, v3d);
|
||||
float bmat[3][3], imat[3][3];
|
||||
|
||||
where_is_object(scene, ob);
|
||||
|
||||
copy_m3_m4(bmat, ob->obmat);
|
||||
invert_m3_m3(imat, bmat);
|
||||
|
||||
curs= give_cursor(scene, v3d);
|
||||
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];
|
||||
mul_m3_v3(imat, hmd->cent);
|
||||
|
||||
changed= 1;
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
}
|
||||
}
|
||||
|
||||
static int object_add_hook_exec(bContext *C, wmOperator *op)
|
||||
static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
|
||||
int mode= RNA_enum_get(op->ptr, "type");
|
||||
|
||||
// XXX - todo, break up this function for different operators
|
||||
// and detect if this finished correctly or not,
|
||||
add_hook(scene, v3d, mode);
|
||||
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Object *obsel=NULL;
|
||||
|
||||
CTX_DATA_BEGIN(C, Object*, ob, selected_objects)
|
||||
{
|
||||
if (ob != obedit) {
|
||||
obsel = ob;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
if (!obsel) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't add hook with no other selected objects.");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
add_hook_object(scene, obedit, obsel, OBJECT_ADDHOOK_SELOB);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_hook_add(wmOperatorType *ot)
|
||||
void OBJECT_OT_hook_add_selobj(wmOperatorType *ot)
|
||||
{
|
||||
static EnumPropertyItem prop_new_hook_types[] = {
|
||||
{1, "NEW", 0, "New Object", "Create a new object and assign the verts to it."},
|
||||
{2, "SELECTED", 0, "Selection", "Add the hook to the selected object."},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
/* identifiers */
|
||||
ot->name= "Add Hook";
|
||||
ot->description= "Add hook to selected verts.";
|
||||
ot->idname= "OBJECT_OT_hook_add";
|
||||
|
||||
ot->name= "Hook to Selected Object";
|
||||
ot->description= "Hook selected vertices to the first selected Object.";
|
||||
ot->idname= "OBJECT_OT_hook_add_selob";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= WM_menu_invoke;
|
||||
ot->exec= object_add_hook_exec;
|
||||
// ot->poll= ED_operator_editmesh;
|
||||
|
||||
ot->exec= object_add_hook_selob_exec;
|
||||
ot->poll= ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
RNA_def_enum(ot->srna, "type", prop_new_hook_types, 0, "Type", "");
|
||||
}
|
||||
|
||||
static int object_add_hook_newob_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
|
||||
add_hook_object(scene, obedit, NULL, OBJECT_ADDHOOK_NEWOB);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_hook_add_newobj(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Hook to New Object";
|
||||
ot->description= "Hook selected vertices to the first selected Object.";
|
||||
ot->idname= "OBJECT_OT_hook_add_newob";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= object_add_hook_newob_exec;
|
||||
ot->poll= ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static EnumPropertyItem hook_mod_items[]= {
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static int object_hook_remove_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
int num= RNA_enum_get(op->ptr, "modifier");
|
||||
Object *ob=NULL;
|
||||
HookModifierData *hmd=NULL;
|
||||
|
||||
ob = CTX_data_edit_object(C);
|
||||
hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
|
||||
|
||||
if (!ob || !hmd) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* remove functionality */
|
||||
|
||||
BLI_remlink(&ob->modifiers, (ModifierData *)hmd);
|
||||
modifier_free((ModifierData *)hmd);
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static EnumPropertyItem *hook_mod_itemf(bContext *C, PointerRNA *ptr, int *free)
|
||||
{
|
||||
Object *ob = CTX_data_edit_object(C);
|
||||
EnumPropertyItem tmp = {0, "", 0, "", ""};
|
||||
EnumPropertyItem *item= NULL;
|
||||
ModifierData *md = NULL;
|
||||
int a, totitem= 0;
|
||||
|
||||
if(!ob)
|
||||
return hook_mod_items;
|
||||
|
||||
for(a=0, md=ob->modifiers.first; md; md= md->next, a++) {
|
||||
if (md->type==eModifierType_Hook) {
|
||||
tmp.value= a;
|
||||
tmp.icon = ICON_HOOK;
|
||||
tmp.identifier= md->name;
|
||||
tmp.name= md->name;
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
}
|
||||
}
|
||||
|
||||
RNA_enum_item_end(&item, &totitem);
|
||||
*free= 1;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void OBJECT_OT_hook_remove(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name= "Remove Hook";
|
||||
ot->idname= "OBJECT_OT_hook_remove";
|
||||
ot->description= "Remove a hook from the active object.";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= ED_operator_editmesh;
|
||||
ot->exec= object_hook_remove_exec;
|
||||
ot->invoke= WM_menu_invoke;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to remove.");
|
||||
RNA_def_enum_funcs(prop, hook_mod_itemf);
|
||||
}
|
||||
|
||||
static int object_hook_reset_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
|
||||
int num= RNA_enum_get(op->ptr, "modifier");
|
||||
Object *ob=NULL;
|
||||
HookModifierData *hmd=NULL;
|
||||
|
||||
if (ptr.data) { /* if modifier context is available, use that */
|
||||
ob = ptr.id.data;
|
||||
hmd= ptr.data;
|
||||
} else { /* use the provided property */
|
||||
ob = CTX_data_edit_object(C);
|
||||
hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
|
||||
}
|
||||
if (!ob || !hmd) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* reset functionality */
|
||||
|
||||
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 */
|
||||
mul_m4_m4m4(mat, pchan->pose_mat, hmd->object->obmat);
|
||||
|
||||
invert_m4_m4(imat, mat);
|
||||
mul_serie_m4(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
invert_m4_m4(hmd->object->imat, hmd->object->obmat);
|
||||
mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_hook_reset(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
ot->name= "Reset Hook";
|
||||
ot->description= "Recalculate and and clear offset transformation.";
|
||||
ot->idname= "OBJECT_OT_hook_reset";
|
||||
|
||||
ot->poll= ED_operator_editmesh;
|
||||
ot->exec= object_hook_reset_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to assign to.");
|
||||
RNA_def_enum_funcs(prop, hook_mod_itemf);
|
||||
}
|
||||
|
||||
static int object_hook_recenter_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
|
||||
int num= RNA_enum_get(op->ptr, "modifier");
|
||||
Object *ob=NULL;
|
||||
HookModifierData *hmd=NULL;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
float bmat[3][3], imat[3][3];
|
||||
|
||||
if (ptr.data) { /* if modifier context is available, use that */
|
||||
ob = ptr.id.data;
|
||||
hmd= ptr.data;
|
||||
} else { /* use the provided property */
|
||||
ob = CTX_data_edit_object(C);
|
||||
hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
|
||||
}
|
||||
if (!ob || !hmd) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* recenter functionality */
|
||||
|
||||
copy_m3_m4(bmat, ob->obmat);
|
||||
invert_m3_m3(imat, bmat);
|
||||
|
||||
sub_v3_v3v3(hmd->cent, scene->cursor, ob->obmat[3]);
|
||||
mul_m3_v3(imat, hmd->cent);
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_hook_recenter(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
ot->name= "Recenter Hook";
|
||||
ot->description= "Set hook center to cursor position.";
|
||||
ot->idname= "OBJECT_OT_hook_recenter";
|
||||
|
||||
ot->poll= ED_operator_editmesh;
|
||||
ot->exec= object_hook_recenter_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to assign to.");
|
||||
RNA_def_enum_funcs(prop, hook_mod_itemf);
|
||||
}
|
||||
|
||||
static int object_hook_assign_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
|
||||
int num= RNA_enum_get(op->ptr, "modifier");
|
||||
Object *ob=NULL;
|
||||
HookModifierData *hmd=NULL;
|
||||
float cent[3];
|
||||
char name[32];
|
||||
int *indexar, tot;
|
||||
|
||||
if (ptr.data) { /* if modifier context is available, use that */
|
||||
ob = ptr.id.data;
|
||||
hmd= ptr.data;
|
||||
} else { /* use the provided property */
|
||||
ob = CTX_data_edit_object(C);
|
||||
hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
|
||||
}
|
||||
if (!ob || !hmd) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* assign functionality */
|
||||
|
||||
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(hmd->indexar)
|
||||
MEM_freeN(hmd->indexar);
|
||||
|
||||
copy_v3_v3(hmd->cent, cent);
|
||||
hmd->indexar= indexar;
|
||||
hmd->totindex= tot;
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_hook_assign(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
ot->name= "Assign to Hook";
|
||||
ot->description= "Assign the selected vertices to a hook.";
|
||||
ot->idname= "OBJECT_OT_hook_assign";
|
||||
|
||||
ot->poll= ED_operator_editmesh;
|
||||
ot->exec= object_hook_assign_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to assign to.");
|
||||
RNA_def_enum_funcs(prop, hook_mod_itemf);
|
||||
}
|
||||
|
||||
static int object_hook_select_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
|
||||
int num= RNA_enum_get(op->ptr, "modifier");
|
||||
Object *ob=NULL;
|
||||
HookModifierData *hmd=NULL;
|
||||
|
||||
if (ptr.data) { /* if modifier context is available, use that */
|
||||
ob = ptr.id.data;
|
||||
hmd= ptr.data;
|
||||
} else { /* use the provided property */
|
||||
ob = CTX_data_edit_object(C);
|
||||
hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num);
|
||||
}
|
||||
if (!ob || !hmd) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* select functionality */
|
||||
|
||||
object_hook_select(ob, hmd);
|
||||
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_hook_select(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
ot->name= "Select Hook";
|
||||
ot->description= "Selects effected vertices on mesh.";
|
||||
ot->idname= "OBJECT_OT_hook_select";
|
||||
|
||||
ot->poll= ED_operator_editmesh;
|
||||
ot->exec= object_hook_select_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to remove.");
|
||||
RNA_def_enum_funcs(prop, hook_mod_itemf);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,12 @@ struct Object;
|
||||
struct Mesh;
|
||||
struct HookModifierData;
|
||||
|
||||
/* add hook menu */
|
||||
enum {
|
||||
OBJECT_ADDHOOK_NEWOB = 1,
|
||||
OBJECT_ADDHOOK_SELOB,
|
||||
} eObject_Hook_Add_Mode;
|
||||
|
||||
/* internal exports only */
|
||||
|
||||
/* object_transform.c */
|
||||
@@ -103,10 +109,13 @@ void OBJECT_OT_join(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_convert(struct wmOperatorType *ot);
|
||||
|
||||
/* object_hook.c */
|
||||
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);
|
||||
|
||||
void OBJECT_OT_hook_add(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hook_add_selobj(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hook_add_newobj(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hook_remove(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hook_select(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hook_assign(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hook_reset(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hook_recenter(struct wmOperatorType *ot);
|
||||
|
||||
/* object_lattice.c */
|
||||
void free_editLatt(Object *ob);
|
||||
@@ -134,10 +143,6 @@ void OBJECT_OT_modifier_copy(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_multires_subdivide(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_multires_higher_levels_delete(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);
|
||||
|
||||
/* object_constraint.c */
|
||||
@@ -177,7 +182,6 @@ void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_menu(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot);
|
||||
|
||||
void OBJECT_OT_game_property_new(struct wmOperatorType *ot);
|
||||
|
||||
@@ -822,157 +822,6 @@ void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/******************** hook operators ************************/
|
||||
|
||||
static int hook_poll(bContext *C)
|
||||
{
|
||||
PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
|
||||
ID *id= ptr.id.data;
|
||||
return (ptr.data && id && !id->lib);
|
||||
}
|
||||
|
||||
static int hook_reset_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
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 */
|
||||
mul_m4_m4m4(mat, pchan->pose_mat, hmd->object->obmat);
|
||||
|
||||
invert_m4_m4(imat, mat);
|
||||
mul_serie_m4(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
invert_m4_m4(hmd->object->imat, hmd->object->obmat);
|
||||
mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_hook_reset(wmOperatorType *ot)
|
||||
{
|
||||
ot->name= "Hook Reset";
|
||||
ot->description= "Recalculate and and clear offset transformation.";
|
||||
ot->idname= "OBJECT_OT_hook_reset";
|
||||
|
||||
ot->exec= hook_reset_exec;
|
||||
ot->poll= hook_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
copy_m3_m4(bmat, ob->obmat);
|
||||
invert_m3_m3(imat, bmat);
|
||||
|
||||
VECSUB(hmd->cent, scene->cursor, ob->obmat[3]);
|
||||
mul_m3_v3(imat, hmd->cent);
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
ot->exec= hook_recenter_exec;
|
||||
ot->poll= hook_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int hook_select_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
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);
|
||||
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
|
||||
|
||||
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 int hook_assign_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
|
||||
Object *ob= ptr.id.data;
|
||||
HookModifierData *hmd= ptr.data;
|
||||
float cent[3];
|
||||
char name[32];
|
||||
int *indexar, tot;
|
||||
|
||||
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(hmd->indexar)
|
||||
MEM_freeN(hmd->indexar);
|
||||
|
||||
VECCOPY(hmd->cent, cent);
|
||||
hmd->indexar= indexar;
|
||||
hmd->totindex= tot;
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_hook_assign(wmOperatorType *ot)
|
||||
{
|
||||
ot->name= "Hook Assign";
|
||||
ot->description= "Reassigns selected vertices to hook.";
|
||||
ot->idname= "OBJECT_OT_hook_assign";
|
||||
|
||||
ot->exec= hook_assign_exec;
|
||||
ot->poll= hook_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/****************** explode refresh operator *********************/
|
||||
|
||||
static int explode_refresh_poll(bContext *C)
|
||||
|
||||
@@ -136,12 +136,8 @@ void ED_operatortypes_object(void)
|
||||
WM_operatortype_append(OBJECT_OT_multires_subdivide);
|
||||
WM_operatortype_append(OBJECT_OT_multires_higher_levels_delete);
|
||||
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);
|
||||
WM_operatortype_append(POSE_OT_constraint_add);
|
||||
@@ -172,7 +168,6 @@ void ED_operatortypes_object(void)
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_levels);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_blend);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_clean);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_menu);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_set_active);
|
||||
|
||||
WM_operatortype_append(OBJECT_OT_game_property_new);
|
||||
@@ -190,7 +185,13 @@ void ED_operatortypes_object(void)
|
||||
WM_operatortype_append(OBJECT_OT_group_add);
|
||||
WM_operatortype_append(OBJECT_OT_group_remove);
|
||||
|
||||
WM_operatortype_append(OBJECT_OT_hook_add);
|
||||
WM_operatortype_append(OBJECT_OT_hook_add_selobj);
|
||||
WM_operatortype_append(OBJECT_OT_hook_add_newobj);
|
||||
WM_operatortype_append(OBJECT_OT_hook_remove);
|
||||
WM_operatortype_append(OBJECT_OT_hook_select);
|
||||
WM_operatortype_append(OBJECT_OT_hook_assign);
|
||||
WM_operatortype_append(OBJECT_OT_hook_reset);
|
||||
WM_operatortype_append(OBJECT_OT_hook_recenter);
|
||||
}
|
||||
|
||||
void ED_operatormacros_object(void)
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "object_intern.h"
|
||||
|
||||
@@ -1753,6 +1754,7 @@ static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *ptr, int *free)
|
||||
|
||||
for(a=0, def=ob->defbase.first; def; def=def->next, a++) {
|
||||
tmp.value= a;
|
||||
tmp.icon= ICON_GROUP_VERTEX;
|
||||
tmp.identifier= def->name;
|
||||
tmp.name= def->name;
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
@@ -1784,51 +1786,4 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
|
||||
/* properties */
|
||||
prop= RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active.");
|
||||
RNA_def_enum_funcs(prop, vgroup_itemf);
|
||||
}
|
||||
|
||||
static int vertex_group_menu_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
uiPopupMenu *pup;
|
||||
uiLayout *layout;
|
||||
|
||||
pup= uiPupMenuBegin(C, "Vertex Groups", 0);
|
||||
layout= uiPupMenuLayout(pup);
|
||||
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
|
||||
|
||||
if(vgroup_object_in_edit_mode(ob)) {
|
||||
uiItemBooleanO(layout, "Assign to New Group", 0, "OBJECT_OT_vertex_group_assign", "new", 1);
|
||||
|
||||
if(BLI_countlist(&ob->defbase) && ob->actdef) {
|
||||
uiItemO(layout, "Assign to Group", 0, "OBJECT_OT_vertex_group_assign");
|
||||
uiItemO(layout, "Remove from Group", 0, "OBJECT_OT_vertex_group_remove_from");
|
||||
uiItemBooleanO(layout, "Remove from All", 0, "OBJECT_OT_vertex_group_remove_from", "all", 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(BLI_countlist(&ob->defbase) && ob->actdef) {
|
||||
if(vgroup_object_in_edit_mode(ob))
|
||||
uiItemS(layout);
|
||||
|
||||
uiItemMenuEnumO(layout, "Set Active Group", 0, "OBJECT_OT_vertex_group_set_active", "group");
|
||||
uiItemO(layout, "Remove Group", 0, "OBJECT_OT_vertex_group_remove");
|
||||
uiItemBooleanO(layout, "Remove All Groups", 0, "OBJECT_OT_vertex_group_remove", "all", 1);
|
||||
}
|
||||
|
||||
uiPupMenuEnd(C, pup);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_vertex_group_menu(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Vertex Group Menu";
|
||||
ot->idname= "OBJECT_OT_vertex_group_menu";
|
||||
ot->description= "Menu showing the operators available for editing Vertex Groups";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= vertex_group_poll;
|
||||
ot->exec= vertex_group_menu_exec;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user