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:
authorTon Roosendaal <ton@blender.org>2009-01-17 21:35:33 +0300
committerTon Roosendaal <ton@blender.org>2009-01-17 21:35:33 +0300
commita6edbba8ec49f628259c61555e5f0b4ad27b6c09 (patch)
tree5322a7aecdcc17a9604e10a362cd856c4e96d548
parent69e49c6f0c33743d32ba5313e735c1320911c679 (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
-rw-r--r--source/blender/blenkernel/BKE_context.h4
-rw-r--r--source/blender/blenkernel/intern/context.c19
-rw-r--r--source/blender/editors/include/ED_object.h1
-rw-r--r--source/blender/editors/mesh/mesh_ops.c41
-rw-r--r--source/blender/editors/object/object_edit.c525
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_ops.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c32
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c5
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 */