forked from bartvdbraak/blender
2.5 - Start of Make Proxy Operator
The code has been ported to the operator+rna system, however, there are currently issues related to how the pointer-rna's work for use as operator properties. (NOTE: RNA_property_pointer_set only takes into account builtin props for now, but not id-props, while the corresponding get method seems to take them into account) The alternative to using pointer-properties for the operator, is to store strings and look up the relevant objects later, but there should be a nicer way...
This commit is contained in:
parent
fe881aa7ad
commit
8584507671
@ -2666,68 +2666,110 @@ void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d)
|
|||||||
DAG_scene_sort(scene);
|
DAG_scene_sort(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object *group_objects_menu(Group *group)
|
|
||||||
|
/* ******************** make proxy operator *********************** */
|
||||||
|
|
||||||
|
/* present menu listing the possible objects within the group to proxify */
|
||||||
|
static void proxy_group_objects_menu (bContext *C, wmOperator *op, Object *ob, Group *group)
|
||||||
{
|
{
|
||||||
|
PointerRNA gob_ptr;
|
||||||
|
uiPopupMenu *pup;
|
||||||
|
uiLayout *layout;
|
||||||
GroupObject *go;
|
GroupObject *go;
|
||||||
int len= 0;
|
int len=0;
|
||||||
short a, nr;
|
|
||||||
char *str;
|
/* check if there are any objects within the group to assign for */
|
||||||
|
for (go= group->gobject.first; go; go= go->next) {
|
||||||
for(go= group->gobject.first; go; go= go->next) {
|
if (go->ob) len++;
|
||||||
if(go->ob)
|
|
||||||
len++;
|
|
||||||
}
|
}
|
||||||
if(len==0) return NULL;
|
if (len==0) return;
|
||||||
|
|
||||||
str= MEM_callocN(40+32*len, "menu");
|
/* now create the menu to draw */
|
||||||
|
pup= uiPupMenuBegin(C, "Make Proxy For:", 0);
|
||||||
|
layout= uiPupMenuLayout(pup);
|
||||||
|
|
||||||
strcpy(str, "Make Proxy for: %t");
|
/* make RNA pointer for object that group belongs to */
|
||||||
a= strlen(str);
|
RNA_id_pointer_create((ID *)ob, &gob_ptr);
|
||||||
for(nr=1, go= group->gobject.first; go; go= go->next, nr++) {
|
|
||||||
a+= sprintf(str+a, "|%s %%x%d", go->ob->id.name+2, nr);
|
for (go= group->gobject.first; go; go= go->next) {
|
||||||
|
if (go->ob) {
|
||||||
|
PointerRNA props_ptr, ob_ptr;
|
||||||
|
|
||||||
|
/* create pointer for this object */
|
||||||
|
RNA_id_pointer_create((ID *)go->ob, &ob_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);
|
||||||
|
RNA_pointer_set(&props_ptr, "object", ob_ptr);
|
||||||
|
RNA_pointer_set(&props_ptr, "group_object", gob_ptr);
|
||||||
|
uiItemFullO(layout, go->ob->id.name+2, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a= pupmenu_col(str, 20);
|
/* display the menu, and be done */
|
||||||
MEM_freeN(str);
|
uiPupMenuEnd(C, pup);
|
||||||
if(a>0) {
|
|
||||||
go= BLI_findlink(&group->gobject, a-1);
|
|
||||||
return go->ob;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set the object to proxify */
|
||||||
/* adds empty object to become local replacement data of a library-linked object */
|
static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt)
|
||||||
void make_proxy(Scene *scene)
|
|
||||||
{
|
{
|
||||||
Object *ob= OBACT;
|
Scene *scene= CTX_data_scene(C);
|
||||||
Object *gob= NULL;
|
Object *ob= CTX_data_active_object(C);
|
||||||
|
|
||||||
if(scene->id.lib) return;
|
/* sanity checks */
|
||||||
if(ob==NULL) return;
|
if (!scene || scene->id.lib || !ob)
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
|
||||||
if(ob->dup_group && ob->dup_group->id.lib) {
|
/* Get object to work on - use a menu if we need to... */
|
||||||
gob= ob;
|
if (ob->dup_group && ob->dup_group->id.lib) {
|
||||||
/* gives menu with list of objects in group */
|
/* gives menu with list of objects in group */
|
||||||
ob= group_objects_menu(ob->dup_group);
|
proxy_group_objects_menu(C, op, ob, ob->dup_group);
|
||||||
}
|
}
|
||||||
else if(ob->id.lib) {
|
else if (ob->id.lib) {
|
||||||
if(okee("Make Proxy Object")==0)
|
uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION);
|
||||||
return;
|
uiLayout *layout= uiPupMenuLayout(pup);
|
||||||
|
PointerRNA ob_ptr, props_ptr;
|
||||||
|
|
||||||
|
/* create pointer for this object */
|
||||||
|
RNA_id_pointer_create((ID *)ob, &ob_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);
|
||||||
|
RNA_pointer_set(&props_ptr, "object", ob_ptr);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error("Can only make proxy for a referenced object or group");
|
/* error.. cannot continue */
|
||||||
return;
|
BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or group");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ob) {
|
/* this invoke just calls another instance of this operator... */
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int make_proxy_exec (bContext *C, wmOperator *op)
|
||||||
|
{
|
||||||
|
PointerRNA ob_ptr= RNA_pointer_get(op->ptr, "object");
|
||||||
|
PointerRNA gob_ptr= RNA_pointer_get(op->ptr, "group_object");
|
||||||
|
Object *ob= ob_ptr.data;
|
||||||
|
Object *gob= gob_ptr.data;
|
||||||
|
Scene *scene= CTX_data_scene(C);
|
||||||
|
|
||||||
|
if (ob) {
|
||||||
Object *newob;
|
Object *newob;
|
||||||
Base *newbase, *oldbase= BASACT;
|
Base *newbase, *oldbase= BASACT;
|
||||||
char name[32];
|
char name[32];
|
||||||
|
|
||||||
|
/* Add new object for the proxy */
|
||||||
newob= add_object(scene, OB_EMPTY);
|
newob= add_object(scene, OB_EMPTY);
|
||||||
if(gob)
|
if (gob)
|
||||||
strcpy(name, gob->id.name+2);
|
strcpy(name, gob->id.name+2);
|
||||||
else
|
else
|
||||||
strcpy(name, ob->id.name+2);
|
strcpy(name, ob->id.name+2);
|
||||||
@ -2740,15 +2782,43 @@ void make_proxy(Scene *scene)
|
|||||||
newob->lay= newbase->lay;
|
newob->lay= newbase->lay;
|
||||||
|
|
||||||
/* remove base, leave user count of object, it gets linked in object_make_proxy */
|
/* remove base, leave user count of object, it gets linked in object_make_proxy */
|
||||||
if(gob==NULL) {
|
if (gob==NULL) {
|
||||||
BLI_remlink(&scene->base, oldbase);
|
BLI_remlink(&scene->base, oldbase);
|
||||||
MEM_freeN(oldbase);
|
MEM_freeN(oldbase);
|
||||||
}
|
}
|
||||||
|
|
||||||
object_make_proxy(newob, ob, gob);
|
object_make_proxy(newob, ob, gob);
|
||||||
|
|
||||||
|
/* depsgraph flushes are needed for the new data */
|
||||||
DAG_scene_sort(scene);
|
DAG_scene_sort(scene);
|
||||||
DAG_object_flush_update(scene, newob, OB_RECALC);
|
DAG_object_flush_update(scene, newob, OB_RECALC);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
BKE_report(op->reports, RPT_ERROR, "No object to make proxy for");
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OPERATOR_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OBJECT_OT_proxy_make (wmOperatorType *ot)
|
||||||
|
{
|
||||||
|
/* identifiers */
|
||||||
|
ot->name= "Make Proxy";
|
||||||
|
ot->idname= "OBJECT_OT_proxy_make";
|
||||||
|
ot->description= "Add empty object to become local replacement data of a library-linked object";
|
||||||
|
|
||||||
|
/* callbacks */
|
||||||
|
ot->invoke= make_proxy_invoke;
|
||||||
|
ot->exec= make_proxy_exec;
|
||||||
|
ot->poll= ED_operator_object_active;
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
|
|
||||||
|
/* properties */
|
||||||
|
RNA_def_pointer(ot->srna, "object", "Object", "Proxy Object", "Lib-linked/grouped object to make a proxy for.");
|
||||||
|
RNA_def_pointer(ot->srna, "group_object", "Object", "Group Object", "Group instancer (if applicable).");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ******************** make parent operator *********************** */
|
/* ******************** make parent operator *********************** */
|
||||||
|
@ -66,6 +66,7 @@ void OBJECT_OT_object_add(struct wmOperatorType *ot);
|
|||||||
void OBJECT_OT_duplicate(struct wmOperatorType *ot);
|
void OBJECT_OT_duplicate(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_delete(struct wmOperatorType *ot);
|
void OBJECT_OT_delete(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_join(struct wmOperatorType *ot);
|
void OBJECT_OT_join(struct wmOperatorType *ot);
|
||||||
|
void OBJECT_OT_proxy_make(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_shade_smooth(struct wmOperatorType *ot);
|
void OBJECT_OT_shade_smooth(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_shade_flat(struct wmOperatorType *ot);
|
void OBJECT_OT_shade_flat(struct wmOperatorType *ot);
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@ void ED_operatortypes_object(void)
|
|||||||
WM_operatortype_append(OBJECT_OT_duplicates_make_real);
|
WM_operatortype_append(OBJECT_OT_duplicates_make_real);
|
||||||
WM_operatortype_append(OBJECT_OT_duplicate);
|
WM_operatortype_append(OBJECT_OT_duplicate);
|
||||||
WM_operatortype_append(OBJECT_OT_join);
|
WM_operatortype_append(OBJECT_OT_join);
|
||||||
|
WM_operatortype_append(OBJECT_OT_proxy_make);
|
||||||
WM_operatortype_append(OBJECT_OT_shade_smooth);
|
WM_operatortype_append(OBJECT_OT_shade_smooth);
|
||||||
WM_operatortype_append(OBJECT_OT_shade_flat);
|
WM_operatortype_append(OBJECT_OT_shade_flat);
|
||||||
WM_operatortype_append(GROUP_OT_group_create);
|
WM_operatortype_append(GROUP_OT_group_create);
|
||||||
@ -185,6 +186,7 @@ void ED_keymap_object(wmWindowManager *wm)
|
|||||||
WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
|
WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
|
||||||
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1);
|
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1);
|
||||||
WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
|
WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
|
||||||
|
WM_keymap_add_item(keymap, "OBJECT_OT_proxy_make", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
|
||||||
|
|
||||||
// XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith
|
// XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith
|
||||||
WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_menu", IKEY, KM_PRESS, 0, 0);
|
WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_menu", IKEY, KM_PRESS, 0, 0);
|
||||||
|
@ -2100,9 +2100,9 @@ static void view3d_edit_objectmenu(bContext *C, uiLayout *layout, void *arg_unus
|
|||||||
uiItemO(layout, NULL, 0, "OBJECT_OT_duplicate");
|
uiItemO(layout, NULL, 0, "OBJECT_OT_duplicate");
|
||||||
uiItemBooleanO(layout, "Duplicate Linked", 0, "OBJECT_OT_duplicate", "linked", 1);
|
uiItemBooleanO(layout, "Duplicate Linked", 0, "OBJECT_OT_duplicate", "linked", 1);
|
||||||
uiItemO(layout, NULL, 0, "OBJECT_OT_delete");
|
uiItemO(layout, NULL, 0, "OBJECT_OT_delete");
|
||||||
|
|
||||||
|
uiItemO(layout, NULL, 0, "OBJECT_OT_proxy_make");
|
||||||
#if 0
|
#if 0
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Proxy|Ctrl Alt P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
|
|
||||||
uiDefIconTextBlockBut(block, view3d_edit_object_makelinksmenu, NULL, ICON_RIGHTARROW_THIN, "Make Links", 0, yco-=20, 120, 19, "");
|
uiDefIconTextBlockBut(block, view3d_edit_object_makelinksmenu, NULL, ICON_RIGHTARROW_THIN, "Make Links", 0, yco-=20, 120, 19, "");
|
||||||
uiDefIconTextBlockBut(block, view3d_edit_object_singleusermenu, NULL, ICON_RIGHTARROW_THIN, "Make Single User", 0, yco-=20, 120, 19, "");
|
uiDefIconTextBlockBut(block, view3d_edit_object_singleusermenu, NULL, ICON_RIGHTARROW_THIN, "Make Single User", 0, yco-=20, 120, 19, "");
|
||||||
uiDefIconTextBlockBut(block, view3d_edit_object_makelocalmenu, NULL, ICON_RIGHTARROW_THIN, "Make Local", 0, yco-=20, 120, 19, "");
|
uiDefIconTextBlockBut(block, view3d_edit_object_makelocalmenu, NULL, ICON_RIGHTARROW_THIN, "Make Local", 0, yco-=20, 120, 19, "");
|
||||||
|
Loading…
Reference in New Issue
Block a user