diff options
author | Ton Roosendaal <ton@blender.org> | 2009-01-17 21:35:33 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-01-17 21:35:33 +0300 |
commit | a6edbba8ec49f628259c61555e5f0b4ad27b6c09 (patch) | |
tree | 5322a7aecdcc17a9604e10a362cd856c4e96d548 /source/blender | |
parent | 69e49c6f0c33743d32ba5313e735c1320911c679 (diff) |
2.5
- Added shift+d duplicate for object and editmode mesh.
Note it uses WM_operator_name_call(), which is fine now,
but in future might put again 2 undo's and operators on
the stack.
Will have to spend some time on how Macros will work!
- added itterator CTX_selected_editable_objects()
(named it first "edible" but that was too funny!)
Also cleaned object_edit.c to use this correctly.
- added CTX_wm_view3d(), especially for hybrid tools
that *can* use view3d, but don't have to.
- moved debug -d print for operators to the real invoke call
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_context.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/context.c | 19 | ||||
-rw-r--r-- | source/blender/editors/include/ED_object.h | 1 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_ops.c | 41 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 525 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 32 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 5 |
11 files changed, 360 insertions, 276 deletions
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index d9988abdaab..7d6542ada08 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -95,6 +95,7 @@ struct wmWindow *CTX_wm_window(const bContext *C); struct bScreen *CTX_wm_screen(const bContext *C); struct ScrArea *CTX_wm_area(const bContext *C); struct SpaceLink *CTX_wm_space_data(const bContext *C); +struct View3D *CTX_wm_view3d(const bContext *C); struct ARegion *CTX_wm_region(const bContext *C); void *CTX_wm_region_data(const bContext *C); struct uiBlock *CTX_wm_ui_block(const bContext *C); @@ -141,6 +142,9 @@ struct ToolSettings *CTX_data_tool_settings(const bContext *C); void CTX_data_main_set(bContext *C, struct Main *bmain); void CTX_data_scene_set(bContext *C, struct Scene *bmain); +int CTX_data_selected_editable_objects(const bContext *C, ListBase *list); +int CTX_data_selected_editable_bases(const bContext *C, ListBase *list); + int CTX_data_selected_objects(const bContext *C, ListBase *list); int CTX_data_selected_bases(const bContext *C, ListBase *list); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index ceac604aace..1fd569e1081 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -31,6 +31,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_view3d_types.h" #include "DNA_windowmanager_types.h" #include "RNA_access.h" @@ -163,6 +164,14 @@ SpaceLink *CTX_wm_space_data(const bContext *C) return (C->wm.area)? C->wm.area->spacedata.first: NULL; } +View3D *CTX_wm_view3d(const bContext *C) +{ + if(C->wm.area && C->wm.area->spacetype==SPACE_VIEW3D) + return C->wm.area->spacedata.first; + return NULL; +} + + ARegion *CTX_wm_region(const bContext *C) { return C->wm.region; @@ -367,6 +376,16 @@ int CTX_data_selected_nodes(const bContext *C, ListBase *list) return ctx_data_collection_get(C, CTX_data_selected_nodes, list); } +int CTX_data_selected_editable_objects(const bContext *C, ListBase *list) +{ + return ctx_data_collection_get(C, CTX_data_selected_editable_objects, list); +} + +int CTX_data_selected_editable_bases(const bContext *C, ListBase *list) +{ + return ctx_data_collection_get(C, CTX_data_selected_editable_bases, list); +} + int CTX_data_selected_objects(const bContext *C, ListBase *list) { return ctx_data_collection_get(C, CTX_data_selected_objects, list); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index ad7d54d7062..0b61f8b50a7 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -64,7 +64,6 @@ void ED_object_base_init_from_view(struct Scene *scene, struct View3D *v3d, stru /* cleanup */ int object_data_is_libdata(struct Object *ob); -int object_is_libdata(struct Object *ob); /* constraints */ struct bConstraint *add_new_constraint (short type); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 050db75399c..7804f698c9b 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -57,9 +57,48 @@ #include "ED_mesh.h" #include "ED_view3d.h" +#include "BIF_transform.h" + #include "mesh_intern.h" +static int mesh_add_duplicate_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_edit_object(C); + EditMesh *em= ((Mesh *)ob->data)->edit_mesh; + + adduplicateflag(em, SELECT); + + return OPERATOR_FINISHED; +} + +static int mesh_add_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + mesh_add_duplicate_exec(C, op); + RNA_int_set(op->ptr, "mode", TFM_TRANSLATION); + WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr, NULL); + + return OPERATOR_FINISHED; +} + +static void MESH_OT_add_duplicate(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Add Duplicate"; + ot->idname= "MESH_OT_add_duplicate"; + + /* api callbacks */ + ot->invoke= mesh_add_duplicate_invoke; + ot->exec= mesh_add_duplicate_exec; + + ot->poll= ED_operator_editmesh; + + /* to give to transform */ + RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); +} + + /* ************************** registration **********************************/ void ED_operatortypes_mesh(void) @@ -90,6 +129,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_add_primitive_monkey); WM_operatortype_append(MESH_OT_add_primitive_uv_sphere); WM_operatortype_append(MESH_OT_add_primitive_ico_sphere); + WM_operatortype_append(MESH_OT_add_duplicate); } @@ -127,6 +167,7 @@ void ED_keymap_mesh(wmWindowManager *wm) WM_keymap_add_item(keymap, "MESH_OT_subdivide_smooth", WKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); /* add */ + WM_keymap_add_item(keymap, "MESH_OT_add_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "MESH_OT_add_primitive_plane", ZEROKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_add_primitive_cube", ONEKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_add_primitive_circle", TWOKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 2f0f224b033..57a766897a2 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -120,6 +120,8 @@ #include "BMF_Api.h" +#include "BIF_transform.h" + #include "UI_interface.h" #include "RNA_access.h" @@ -204,20 +206,6 @@ void ED_base_object_activate(bContext *C, Base *base) } - - -/* - * Returns true if the Object is a from an external blend file (libdata) - */ -int object_is_libdata(Object *ob) -{ - if (!ob) return 0; - if (ob->proxy) return 0; - if (ob->id.lib) return 1; - return 0; -} - - /* * Returns true if the Object data is a from an external blend file (libdata) */ @@ -290,9 +278,7 @@ void add_object_draw(Scene *scene, View3D *v3d, int type) /* for toolbox or menu static int object_add_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - ScrArea *sa= CTX_wm_area(C); Object *ob; - View3D *v3d= NULL; int type= RNA_int_get(op->ptr, "type"); /* hrms, this is editor level operator */ @@ -307,9 +293,7 @@ static int object_add_exec(bContext *C, wmOperator *op) ED_base_object_activate(C, BASACT); /* more editor stuff */ - if(sa && sa->spacetype==SPACE_VIEW3D) - v3d= sa->spacedata.first; - ED_object_base_init_from_view(scene, v3d, BASACT); + ED_object_base_init_from_view(scene, CTX_wm_view3d(C), BASACT); DAG_scene_sort(scene); @@ -1066,7 +1050,7 @@ static EnumPropertyItem prop_clear_parent_types[] = { static int clear_parent_exec(bContext *C, wmOperator *op) { - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if(RNA_enum_is_equal(op->ptr, "type", "CLEAR")) { ob->parent= NULL; @@ -1121,15 +1105,13 @@ static int object_clear_track_exec(bContext *C, wmOperator *op) { if(CTX_data_edit_object(C)) return OPERATOR_CANCELLED; - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { - /*if(TESTBASELIB(v3d, base)) {*/ - ob->track= NULL; - ob->recalc |= OB_RECALC; - - if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_KEEP_TRANSFORM")) { - ED_object_apply_obmat(ob); - } - /*}*/ + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + ob->track= NULL; + ob->recalc |= OB_RECALC; + + if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_KEEP_TRANSFORM")) { + ED_object_apply_obmat(ob); + } } CTX_DATA_END; @@ -1487,7 +1469,7 @@ static int object_clear_location_exec(bContext *C, wmOperator *op) Scene *scene= CTX_data_scene(C); int armature_clear= 0; - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if ((ob->flag & OB_POSEMODE)) { /* only clear pose transforms if: * - with a mesh in weightpaint mode, it's related armature needs to be cleared @@ -1538,7 +1520,7 @@ static int object_clear_rotation_exec(bContext *C, wmOperator *op) Scene *scene= CTX_data_scene(C); int armature_clear= 0; - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if ((ob->flag & OB_POSEMODE)) { /* only clear pose transforms if: * - with a mesh in weightpaint mode, it's related armature needs to be cleared @@ -1590,7 +1572,7 @@ static int object_clear_scale_exec(bContext *C, wmOperator *op) Scene *scene= CTX_data_scene(C); int armature_clear= 0; - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if ((ob->flag & OB_POSEMODE)) { /* only clear pose transforms if: * - with a mesh in weightpaint mode, it's related armature needs to be cleared @@ -1646,7 +1628,7 @@ static int object_clear_origin_exec(bContext *C, wmOperator *op) float *v1, *v3, mat[3][3]; int armature_clear= 0; - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if(ob->parent) { v1= ob->loc; v3= ob->parentinv[3]; @@ -1786,8 +1768,8 @@ void OBJECT_OT_set_restrictview(wmOperatorType *ot) static int object_set_slowparent_exec(bContext *C, wmOperator *op) { - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + if(base->object->parent) base->object->partype |= PARSLOW; base->object->recalc |= OB_RECALC_OB; @@ -1819,7 +1801,7 @@ static int object_clear_slowparent_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { if(base->object->parent) { if(base->object->partype & PARSLOW) { base->object->partype -= PARSLOW; @@ -2154,7 +2136,7 @@ static int make_parent_exec(bContext *C, wmOperator *op) } /* context itterator */ - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if(ob!=par) { @@ -2300,33 +2282,27 @@ static EnumPropertyItem prop_make_track_types[] = { static int make_track_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - ScrArea *sa= CTX_wm_area(C); - View3D *v3d= sa->spacedata.first; - if(scene->id.lib) return OPERATOR_CANCELLED; - if(RNA_enum_is_equal(op->ptr, "type", "TRACKTO")){ bConstraint *con; bTrackToConstraint *data; - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if(TESTBASELIB(v3d, base)) { - if(base!=BASACT) { - con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO); - strcpy (con->name, "AutoTrack"); - - data = con->data; - data->tar = BASACT->object; - base->object->recalc |= OB_RECALC; - - /* Lamp and Camera track differently by default */ - if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { - data->reserved1 = TRACK_nZ; - data->reserved2 = UP_Y; - } + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + if(base!=BASACT) { + con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO); + strcpy (con->name, "AutoTrack"); - add_constraint_to_object(con, base->object); + data = con->data; + data->tar = BASACT->object; + base->object->recalc |= OB_RECALC; + + /* Lamp and Camera track differently by default */ + if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { + data->reserved1 = TRACK_nZ; + data->reserved2 = UP_Y; } + + add_constraint_to_object(con, base->object); } } CTX_DATA_END; @@ -2335,35 +2311,31 @@ static int make_track_exec(bContext *C, wmOperator *op) bConstraint *con; bLockTrackConstraint *data; - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if(TESTBASELIB(v3d, base)) { - if(base!=BASACT) { - con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK); - strcpy (con->name, "AutoTrack"); - - data = con->data; - data->tar = BASACT->object; - base->object->recalc |= OB_RECALC; - - /* Lamp and Camera track differently by default */ - if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { - data->trackflag = TRACK_nZ; - data->lockflag = LOCK_Y; - } + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + if(base!=BASACT) { + con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK); + strcpy (con->name, "AutoTrack"); - add_constraint_to_object(con, base->object); + data = con->data; + data->tar = BASACT->object; + base->object->recalc |= OB_RECALC; + + /* Lamp and Camera track differently by default */ + if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { + data->trackflag = TRACK_nZ; + data->lockflag = LOCK_Y; } + + add_constraint_to_object(con, base->object); } } CTX_DATA_END; } else if(RNA_enum_is_equal(op->ptr, "type", "OLDTRACK")){ - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if(TESTBASELIB(v3d, base)) { - if(base!=BASACT) { - base->object->track= BASACT->object; - base->object->recalc |= OB_RECALC; - } + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + if(base!=BASACT) { + base->object->track= BASACT->object; + base->object->recalc |= OB_RECALC; } } CTX_DATA_END; @@ -2444,7 +2416,7 @@ static int object_make_dupli_real_exec(bContext *C, wmOperator *op) clear_id_newpoins(); - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { make_object_duplilist_real(scene, v3d, base); } CTX_DATA_END; @@ -2544,7 +2516,7 @@ static int object_set_center_exec(bContext *C, wmOperator *op) } /* reset flags */ - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { base->object->flag &= ~OB_DONE; } CTX_DATA_END; @@ -2553,14 +2525,11 @@ static int object_set_center_exec(bContext *C, wmOperator *op) me->flag &= ~ME_ISDONE; } - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { if((base->object->flag & OB_DONE)==0) { base->object->flag |= OB_DONE; - if(base->object->id.lib) { - tot_lib_error++; - } - else if(obedit==0 && (me=get_mesh(base->object)) ) { + if(obedit==NULL && (me=get_mesh(base->object)) ) { if (me->id.lib) { tot_lib_error++; } else { @@ -2611,7 +2580,7 @@ static int object_set_center_exec(bContext *C, wmOperator *op) ignore_parent_tx(scene, base->object); /* other users? */ - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { ob = base->object; if((ob->flag & OB_DONE)==0) { tme= get_mesh(ob); @@ -5584,237 +5553,257 @@ void make_local_menu(Scene *scene, View3D *v3d) make_local(scene, v3d, mode); } -/* This function duplicated the current visible selection, its used by Duplicate and Linked Duplicate -Alt+D/Shift+D as well as Pythons Object.Duplicate(), it takes -mode: - 0: Duplicate with transform, Redraw. - 1: Duplicate, no transform, Redraw - 2: Duplicate, no transform, no redraw (Only used by python) -if true the user will not be dropped into grab mode directly after and.. -dupflag: a flag made from constants declared in DNA_userdef_types.h +/* ************************ ADD DUPLICATE ******************** */ + +/* + dupflag: a flag made from constants declared in DNA_userdef_types.h The flag tells adduplicate() weather to copy data linked to the object, or to reference the existing data. U.dupflag for default operations or you can construct a flag as python does if the dupflag is 0 then no data will be copied (linked duplicate) */ -void adduplicate(Scene *scene, View3D *v3d, int mode, int dupflag) +static int add_duplicate_exec(bContext *C, wmOperator *op) { - Base *base, *basen; + Scene *scene= CTX_data_scene(C); + View3D *v3d= CTX_wm_view3d(C); + Base *basen; Material ***matarar; Object *ob, *obn; ID *id; + int dupflag= U.dupflag; int a, didit; - if(scene->id.lib) return; clear_id_newpoins(); clear_sca_new_poins(); /* sensor/contr/act */ - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASE(v3d, base)) { + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - ob= base->object; - if(ob->flag & OB_POSEMODE) { - ; /* nothing? */ - } - else { - obn= copy_object(ob); - obn->recalc |= OB_RECALC; - - basen= MEM_mallocN(sizeof(Base), "duplibase"); - *basen= *base; - BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */ - basen->object= obn; - base->flag &= ~SELECT; - - if(basen->flag & OB_FROMGROUP) { - Group *group; - for(group= G.main->group.first; group; group= group->id.next) { - if(object_in_group(ob, group)) - add_to_group(group, obn); - } - obn->flag |= OB_FROMGROUP; /* this flag is unset with copy_object() */ + ob= base->object; + if(ob->flag & OB_POSEMODE) { + ; /* nothing? */ + } + else { + obn= copy_object(ob); + obn->recalc |= OB_RECALC; + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */ + basen->object= obn; + base->flag &= ~SELECT; + + if(basen->flag & OB_FROMGROUP) { + Group *group; + for(group= G.main->group.first; group; group= group->id.next) { + if(object_in_group(ob, group)) + add_to_group(group, obn); } - - if(BASACT==base) BASACT= basen; + obn->flag |= OB_FROMGROUP; /* this flag is unset with copy_object() */ + } + + if(BASACT==base) + ED_base_object_activate(C, basen); - /* duplicates using userflags */ + /* duplicates using userflags */ #if 0 // XXX old animation system - if(dupflag & USER_DUP_IPO) { - bConstraintChannel *chan; - id= (ID *)obn->ipo; - + if(dupflag & USER_DUP_IPO) { + bConstraintChannel *chan; + id= (ID *)obn->ipo; + + if(id) { + ID_NEW_US( obn->ipo) + else obn->ipo= copy_ipo(obn->ipo); + id->us--; + } + /* Handle constraint ipos */ + for (chan=obn->constraintChannels.first; chan; chan=chan->next){ + id= (ID *)chan->ipo; if(id) { - ID_NEW_US( obn->ipo) - else obn->ipo= copy_ipo(obn->ipo); + ID_NEW_US( chan->ipo) + else chan->ipo= copy_ipo(chan->ipo); id->us--; } - /* Handle constraint ipos */ - for (chan=obn->constraintChannels.first; chan; chan=chan->next){ - id= (ID *)chan->ipo; - if(id) { - ID_NEW_US( chan->ipo) - else chan->ipo= copy_ipo(chan->ipo); - id->us--; - } - } } - if(dupflag & USER_DUP_ACT){ /* Not buttons in the UI to modify this, add later? */ - id= (ID *)obn->action; - if (id){ - ID_NEW_US(obn->action) - else{ - obn->action= copy_action(obn->action); - } - id->us--; + } + if(dupflag & USER_DUP_ACT){ /* Not buttons in the UI to modify this, add later? */ + id= (ID *)obn->action; + if (id){ + ID_NEW_US(obn->action) + else{ + obn->action= copy_action(obn->action); } + id->us--; } + } #endif // XXX old animation system - if(dupflag & USER_DUP_MAT) { - for(a=0; a<obn->totcol; a++) { - id= (ID *)obn->mat[a]; - if(id) { - ID_NEW_US(obn->mat[a]) - else obn->mat[a]= copy_material(obn->mat[a]); - id->us--; - } - } - } - - id= obn->data; - didit= 0; - - switch(obn->type) { - case OB_MESH: - if(dupflag & USER_DUP_MESH) { - ID_NEW_US2( obn->data ) - else { - obn->data= copy_mesh(obn->data); - - if(obn->fluidsimSettings) { - obn->fluidsimSettings->orgMesh = (Mesh *)obn->data; - } - - didit= 1; - } + if(dupflag & USER_DUP_MAT) { + for(a=0; a<obn->totcol; a++) { + id= (ID *)obn->mat[a]; + if(id) { + ID_NEW_US(obn->mat[a]) + else obn->mat[a]= copy_material(obn->mat[a]); id->us--; } - break; - case OB_CURVE: - if(dupflag & USER_DUP_CURVE) { - ID_NEW_US2(obn->data ) - else { - obn->data= copy_curve(obn->data); - didit= 1; + } + } + + id= obn->data; + didit= 0; + + switch(obn->type) { + case OB_MESH: + if(dupflag & USER_DUP_MESH) { + ID_NEW_US2( obn->data ) + else { + obn->data= copy_mesh(obn->data); + + if(obn->fluidsimSettings) { + obn->fluidsimSettings->orgMesh = (Mesh *)obn->data; } - id->us--; + + didit= 1; } - break; - case OB_SURF: - if(dupflag & USER_DUP_SURF) { - ID_NEW_US2( obn->data ) - else { - obn->data= copy_curve(obn->data); - didit= 1; - } - id->us--; + id->us--; + } + break; + case OB_CURVE: + if(dupflag & USER_DUP_CURVE) { + ID_NEW_US2(obn->data ) + else { + obn->data= copy_curve(obn->data); + didit= 1; } - break; - case OB_FONT: - if(dupflag & USER_DUP_FONT) { - ID_NEW_US2( obn->data ) - else { - obn->data= copy_curve(obn->data); - didit= 1; - } - id->us--; + id->us--; + } + break; + case OB_SURF: + if(dupflag & USER_DUP_SURF) { + ID_NEW_US2( obn->data ) + else { + obn->data= copy_curve(obn->data); + didit= 1; } - break; - case OB_MBALL: - if(dupflag & USER_DUP_MBALL) { - ID_NEW_US2(obn->data ) - else { - obn->data= copy_mball(obn->data); - didit= 1; - } - id->us--; + id->us--; + } + break; + case OB_FONT: + if(dupflag & USER_DUP_FONT) { + ID_NEW_US2( obn->data ) + else { + obn->data= copy_curve(obn->data); + didit= 1; } - break; - case OB_LAMP: - if(dupflag & USER_DUP_LAMP) { - ID_NEW_US2(obn->data ) - else obn->data= copy_lamp(obn->data); - id->us--; + id->us--; + } + break; + case OB_MBALL: + if(dupflag & USER_DUP_MBALL) { + ID_NEW_US2(obn->data ) + else { + obn->data= copy_mball(obn->data); + didit= 1; } - break; + id->us--; + } + break; + case OB_LAMP: + if(dupflag & USER_DUP_LAMP) { + ID_NEW_US2(obn->data ) + else obn->data= copy_lamp(obn->data); + id->us--; + } + break; - case OB_ARMATURE: - obn->recalc |= OB_RECALC_DATA; - if(obn->pose) obn->pose->flag |= POSE_RECALC; - - if(dupflag & USER_DUP_ARM) { - ID_NEW_US2(obn->data ) - else { - obn->data= copy_armature(obn->data); - armature_rebuild_pose(obn, obn->data); - didit= 1; - } - id->us--; - } - - break; - - case OB_LATTICE: - if(dupflag!=0) { - ID_NEW_US2(obn->data ) - else obn->data= copy_lattice(obn->data); - id->us--; - } - break; - case OB_CAMERA: - if(dupflag!=0) { - ID_NEW_US2(obn->data ) - else obn->data= copy_camera(obn->data); - id->us--; + case OB_ARMATURE: + obn->recalc |= OB_RECALC_DATA; + if(obn->pose) obn->pose->flag |= POSE_RECALC; + + if(dupflag & USER_DUP_ARM) { + ID_NEW_US2(obn->data ) + else { + obn->data= copy_armature(obn->data); + armature_rebuild_pose(obn, obn->data); + didit= 1; } - break; + id->us--; } - if(dupflag & USER_DUP_MAT) { - matarar= give_matarar(obn); - if(didit && matarar) { - for(a=0; a<obn->totcol; a++) { - id= (ID *)(*matarar)[a]; - if(id) { - ID_NEW_US( (*matarar)[a] ) - else (*matarar)[a]= copy_material((*matarar)[a]); - - id->us--; - } + break; + + case OB_LATTICE: + if(dupflag!=0) { + ID_NEW_US2(obn->data ) + else obn->data= copy_lattice(obn->data); + id->us--; + } + break; + case OB_CAMERA: + if(dupflag!=0) { + ID_NEW_US2(obn->data ) + else obn->data= copy_camera(obn->data); + id->us--; + } + break; + } + + if(dupflag & USER_DUP_MAT) { + matarar= give_matarar(obn); + if(didit && matarar) { + for(a=0; a<obn->totcol; a++) { + id= (ID *)(*matarar)[a]; + if(id) { + ID_NEW_US( (*matarar)[a] ) + else (*matarar)[a]= copy_material((*matarar)[a]); + + id->us--; } } } } - } } + CTX_DATA_END; copy_object_set_idnew(scene, v3d, dupflag); DAG_scene_sort(scene); ED_anim_dag_flush_update(C); - if(mode==0) { -// XX BIF_TransformSetUndo("Add Duplicate"); -// initTransform(TFM_TRANSLATION, CTX_NONE); -// Transform(); - } - // XXX ED_base_object_activate(C, BASACT); - if(mode!=2) { /* mode of 2 is used by python to avoid unrequested redraws */ - allqueue(REDRAWNLA, 0); - allqueue(REDRAWACTION, 0); /* also oops */ - allqueue(REDRAWIPO, 0); /* also oops */ - } + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + + return OPERATOR_FINISHED; +} + +static int add_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + + add_duplicate_exec(C, op); + + RNA_int_set(op->ptr, "mode", TFM_TRANSLATION); + WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_add_duplicate(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Add Duplicate"; + ot->idname= "OBJECT_OT_add_duplicate"; + + /* api callbacks */ + ot->invoke= add_duplicate_invoke; + ot->exec= add_duplicate_exec; + + ot->poll= ED_operator_scene_editable; + + /* to give to transform */ + RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); } + +/* ********************** */ + void image_aspect(Scene *scene, View3D *v3d) { /* all selected objects with an image map: scale in image aspect */ diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 8c1092ae0d7..eea6194da8c 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -64,6 +64,7 @@ void OBJECT_OT_clear_slowparent(struct wmOperatorType *ot); void OBJECT_OT_set_center(struct wmOperatorType *ot); void OBJECT_OT_make_dupli_real(struct wmOperatorType *ot); void OBJECT_OT_object_add(struct wmOperatorType *ot); +void OBJECT_OT_add_duplicate(struct wmOperatorType *ot); /* editlattice.c */ void free_editLatt(Object *ob); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index d10f3730318..0e686bbb6ae 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -85,6 +85,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_set_center); WM_operatortype_append(OBJECT_OT_make_dupli_real); WM_operatortype_append(OBJECT_OT_object_add); + WM_operatortype_append(OBJECT_OT_add_duplicate); } void ED_keymap_object(wmWindowManager *wm) @@ -119,6 +120,7 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_verify_item(keymap, "OBJECT_OT_set_restrictview", HKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "OBJECT_OT_object_add", AKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_verify_item(keymap, "OBJECT_OT_add_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0); // 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", IKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 675fbc5aab2..a645f8f359d 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -320,13 +320,25 @@ static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn) } } +/* + * Returns true if the Object is a from an external blend file (libdata) + */ +static int object_is_libdata(Object *ob) +{ + if (!ob) return 0; + if (ob->proxy) return 0; + if (ob->id.lib) return 1; + return 0; +} static int view3d_context(const bContext *C, const bContextDataMember *member, bContextDataResult *result) { - View3D *v3d= (View3D*)CTX_wm_space_data(C); + View3D *v3d= CTX_wm_view3d(C); Scene *scene= CTX_data_scene(C); Base *base; + if(v3d==NULL) return 0; + if(ELEM(member, CTX_data_selected_objects, CTX_data_selected_bases)) { for(base=scene->base.first; base; base=base->next) { if((base->flag & SELECT) && (base->lay & v3d->lay)) { @@ -341,11 +353,27 @@ static int view3d_context(const bContext *C, const bContextDataMember *member, b return 1; } + else if(ELEM(member, CTX_data_selected_editable_objects, CTX_data_selected_editable_bases)) { + for(base=scene->base.first; base; base=base->next) { + if((base->flag & SELECT) && (base->lay & v3d->lay)) { + if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) { + if(0==object_is_libdata(base->object)) { + if(member == CTX_data_selected_editable_objects) + CTX_data_list_add(result, base->object); + else + CTX_data_list_add(result, base); + } + } + } + } + + return 1; + } else if(ELEM(member, CTX_data_visible_objects, CTX_data_visible_bases)) { for(base=scene->base.first; base; base=base->next) { if(base->lay & v3d->lay) { if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) { - if(member == CTX_data_selected_objects) + if(member == CTX_data_visible_objects) CTX_data_list_add(result, base->object); else CTX_data_list_add(result, base); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index a83621b48e9..3ccb5eb026c 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1503,7 +1503,7 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event) { Scene *scene= CTX_data_scene(C); ARegion *ar= CTX_wm_region(C); - View3D *v3d= (View3D *)CTX_wm_space_data(C); + View3D *v3d= CTX_wm_view3d(C); float dx, dy, fz, *fp = NULL, dvec[3], oldcurs[3]; short mx, my, mval[2]; // short ctrl= 0; // XXX diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 4f86c5e0c36..29990511391 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -95,7 +95,7 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc) memset(vc, 0, sizeof(ViewContext)); vc->ar= CTX_wm_region(C); vc->scene= CTX_data_scene(C); - vc->v3d= (View3D *)CTX_wm_space_data(C); + vc->v3d= CTX_wm_view3d(C); vc->obact= CTX_data_active_object(C); vc->obedit= CTX_data_edit_object(C); } @@ -911,7 +911,7 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter) { ViewContext vc; ARegion *ar= CTX_wm_region(C); - View3D *v3d= (View3D *)CTX_wm_space_data(C); + View3D *v3d= CTX_wm_view3d(C); Scene *scene= CTX_data_scene(C); Base *base, *startbase=NULL, *basact=NULL, *oldbasact=NULL; unsigned int buffer[4*MAXPICKBUF]; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 6a8895f2f67..cca8bce9432 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -448,6 +448,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P if(ot->poll==NULL || ot->poll(C)) { wmOperator *op= MEM_callocN(sizeof(wmOperator), ot->idname); /* XXX operatortype names are static still. for debug */ + if((G.f & G_DEBUG) && event->type!=MOUSEMOVE) + printf("handle evt %d win %d op %s\n", event?event->type:0, CTX_wm_screen(C)->subwinactive, ot->idname); + /* XXX adding new operator could be function, only happens here now */ op->type= ot; BLI_strncpy(op->idname, ot->idname, OP_MAX_TYPENAME); @@ -838,8 +841,6 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) for(kmi= handler->keymap->first; kmi; kmi= kmi->next) { if(wm_eventmatch(event, kmi)) { - if((G.f & G_DEBUG) && event->type!=MOUSEMOVE) - printf("handle evt %d win %d op %s\n", event->type, CTX_wm_screen(C)->subwinactive, kmi->idname); event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */ |