diff options
author | Joseph Eagar <joeedh@gmail.com> | 2010-07-19 08:44:37 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2010-07-19 08:44:37 +0400 |
commit | c11c196efadf5ef52293d782638497f86a209722 (patch) | |
tree | 43abcd60b2400d28db8686f4dbea68f17475ef58 /source/blender/editors/object | |
parent | f54aa7811029c90b6071ccc9e27e57a758e5884d (diff) | |
parent | 7f083c45bee15f7540e2a35a725efe28fc962239 (diff) |
part 1 of merge from trunk at r30358; it compiles, but doesn't link quite yet :)
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r-- | source/blender/editors/object/CMakeLists.txt | 48 | ||||
-rw-r--r-- | source/blender/editors/object/object_add.c | 675 | ||||
-rw-r--r-- | source/blender/editors/object/object_bake.c | 23 | ||||
-rw-r--r-- | source/blender/editors/object/object_constraint.c | 392 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 397 | ||||
-rw-r--r-- | source/blender/editors/object/object_group.c | 86 | ||||
-rw-r--r-- | source/blender/editors/object/object_hook.c | 40 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 25 | ||||
-rw-r--r-- | source/blender/editors/object/object_lattice.c | 9 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 445 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 51 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 178 | ||||
-rw-r--r-- | source/blender/editors/object/object_select.c | 121 | ||||
-rw-r--r-- | source/blender/editors/object/object_shapekey.c | 8 | ||||
-rw-r--r-- | source/blender/editors/object/object_transform.c | 119 | ||||
-rw-r--r-- | source/blender/editors/object/object_vgroup.c | 323 |
16 files changed, 1922 insertions, 1018 deletions
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt new file mode 100644 index 00000000000..e1085fd87ca --- /dev/null +++ b/source/blender/editors/object/CMakeLists.txt @@ -0,0 +1,48 @@ +# $Id: CMakeLists.txt 12931 2007-12-17 18:20:48Z theeth $ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributor(s): Jacques Beaurain. +# +# ***** END GPL LICENSE BLOCK ***** + +FILE(GLOB SRC *.c) + +SET(INC + ../include + ../../blenkernel + ../../blenlib + ../../bmesh + ../../gpu + ../../ikplugin + ../../imbuf + ../../makesdna + ../../makesrna + ../../python + ../../windowmanager + ../../render/extern/include + ../../../../intern/guardedalloc +) + +IF(NOT WITH_PYTHON) + ADD_DEFINITIONS(-DDISABLE_PYTHON) +ENDIF(NOT WITH_PYTHON) + +IF(WIN32) + SET(INC ${INC} ${PTHREADS_INC}) +ENDIF(WIN32) + +BLENDERLIB(bf_editor_object "${SRC}" "${INC}") diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 7620d503f49..5fa643200f4 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -30,7 +30,6 @@ #include "MEM_guardedalloc.h" -#include "DNA_action_types.h" #include "DNA_curve_types.h" #include "DNA_group_types.h" #include "DNA_lamp_types.h" @@ -38,12 +37,8 @@ #include "DNA_mesh_types.h" #include "DNA_meta_types.h" #include "DNA_object_fluidsim.h" -#include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_userdef_types.h" -#include "DNA_view3d_types.h" #include "DNA_vfont_types.h" #include "BLI_math.h" @@ -83,7 +78,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_anim_api.h" #include "ED_armature.h" #include "ED_curve.h" #include "ED_mball.h" @@ -92,6 +86,7 @@ #include "ED_render.h" #include "ED_screen.h" #include "ED_transform.h" +#include "ED_view3d.h" #include "UI_interface.h" #include "UI_resources.h" @@ -104,20 +99,16 @@ void ED_object_location_from_view(bContext *C, float *loc) { View3D *v3d= CTX_wm_view3d(C); Scene *scene= CTX_data_scene(C); + float *cursor; - if (v3d) { - if (v3d->localvd) - copy_v3_v3(loc, v3d->cursor); - else - copy_v3_v3(loc, scene->cursor); - } else { - copy_v3_v3(loc, scene->cursor); - } + cursor = give_cursor(scene, v3d); + + copy_v3_v3(loc, cursor); } void ED_object_rotation_from_view(bContext *C, float *rot) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); + RegionView3D *rv3d= ED_view3d_context_rv3d(C); if(rv3d) { rv3d->viewquat[0]= -rv3d->viewquat[0]; @@ -146,9 +137,8 @@ void ED_object_base_init_transform(bContext *C, Base *base, float *loc, float *r /* uses context to figure out transform for primitive */ /* returns standard diameter */ -float ED_object_new_primitive_matrix(bContext *C, float *loc, float *rot, float primmat[][4]) +float ED_object_new_primitive_matrix(bContext *C, Object *obedit, float *loc, float *rot, float primmat[][4]) { - Object *obedit= CTX_data_edit_object(C); View3D *v3d =CTX_wm_view3d(C); float mat[3][3], rmat[3][3], cmat[3][3], imat[3][3]; @@ -164,8 +154,8 @@ float ED_object_new_primitive_matrix(bContext *C, float *loc, float *rot, float copy_m4_m3(primmat, imat); /* center */ - VECCOPY(primmat[3], loc); - VECSUB(primmat[3], primmat[3], obedit->obmat[3]); + copy_v3_v3(primmat[3], loc); + sub_v3_v3v3(primmat[3], primmat[3], obedit->obmat[3]); invert_m3_m3(imat, mat); mul_m3_v3(imat, primmat[3]); @@ -185,13 +175,15 @@ void ED_object_add_generic_props(wmOperatorType *ot, int do_editmode) PropertyRNA *prop; RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view."); - if(do_editmode) - RNA_def_boolean(ot->srna, "enter_editmode", 0, "Enter Editmode", "Enter editmode when adding this object."); + if(do_editmode) { + prop= RNA_def_boolean(ot->srna, "enter_editmode", 0, "Enter Editmode", "Enter editmode when adding this object."); + RNA_def_property_flag(prop, PROP_HIDDEN); + } RNA_def_float_vector(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Location for the newly added object.", -FLT_MAX, FLT_MAX); RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation", "Rotation for the newly added object", -FLT_MAX, FLT_MAX); - prop = RNA_def_boolean_layer_member(ot->srna, "layer", 32, NULL, "Layer", ""); + prop = RNA_def_boolean_layer_member(ot->srna, "layer", 20, NULL, "Layer", ""); RNA_def_property_flag(prop, PROP_HIDDEN); } @@ -201,47 +193,28 @@ static void object_add_generic_invoke_options(bContext *C, wmOperator *op) if (!RNA_property_is_set(op->ptr, "enter_editmode")) RNA_boolean_set(op->ptr, "enter_editmode", U.flag & USER_ADD_EDITMODE); - if (!RNA_property_is_set(op->ptr, "location")) { + if(!RNA_property_is_set(op->ptr, "location")) { float loc[3]; ED_object_location_from_view(C, loc); RNA_float_set_array(op->ptr, "location", loc); } - - if (!RNA_property_is_set(op->ptr, "rotation")) { - int view_align; - float rot[3] = {0.f, 0.f, 0.f}; - - /* view align property is just used to set rotation property */ - if (!RNA_property_is_set(op->ptr, "view_align")) - view_align = U.flag & USER_ADD_VIEWALIGNED; - else - view_align = RNA_boolean_get(op->ptr, "view_align"); - - if (view_align) - ED_object_rotation_from_view(C, rot); - - RNA_float_set_array(op->ptr, "rotation", rot); - } - - if (!RNA_property_is_set(op->ptr, "layer")) { + + if(!RNA_property_is_set(op->ptr, "layer")) { View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); - int a, values[32], layer; + int a, values[20], layer; - if (v3d) { - if (v3d->localvd) { - layer = v3d->layact + v3d->lay; - for(a=0; a<32; a++) - values[a]= (layer & (1<<a)); - } else { - layer = v3d->layact; - for(a=0; a<32; a++) - values[a]= (layer & (1<<a)); - } - } else { - layer = scene->lay; - for(a=0; a<32; a++) + if(v3d) { + layer = (v3d->scenelock && !v3d->localvd)? scene->layact: v3d->layact; + + for(a=0; a<20; a++) + values[a]= (layer & (1<<a)); + } + else { + layer = scene->layact; + + for(a=0; a<20; a++) values[a]= (layer & (1<<a)); } @@ -255,24 +228,57 @@ int ED_object_add_generic_invoke(bContext *C, wmOperator *op, wmEvent *event) return op->type->exec(C, op); } -void ED_object_add_generic_get_opts(wmOperator *op, float *loc, float *rot, int *enter_editmode, unsigned int *layer) +int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float *loc, float *rot, int *enter_editmode, unsigned int *layer) { - int a, layer_values[32]; + View3D *v3d = CTX_wm_view3d(C); + int a, layer_values[20]; + int view_align; *enter_editmode = FALSE; if(RNA_struct_find_property(op->ptr, "enter_editmode") && RNA_boolean_get(op->ptr, "enter_editmode")) { *enter_editmode = TRUE; } + + if(RNA_property_is_set(op->ptr, "layer")) { + RNA_boolean_get_array(op->ptr, "layer", layer_values); + + for(a=0; a<20; a++) { + if(layer_values[a]) + *layer |= (1 << a); + else + *layer &= ~(1 << a); + } + } + else { + /* not set, use the scenes layers */ + Scene *scene = CTX_data_scene(C); + *layer = scene->layact; + } + + /* in local view we additionally add local view layers, + not part of operator properties */ + if(v3d && v3d->localvd) + *layer |= v3d->lay; + + if (RNA_property_is_set(op->ptr, "view_align")) + view_align = RNA_boolean_get(op->ptr, "view_align"); + else + view_align = U.flag & USER_ADD_VIEWALIGNED; + + if (view_align) + ED_object_rotation_from_view(C, rot); + else + RNA_float_get_array(op->ptr, "rotation", rot); + RNA_float_get_array(op->ptr, "location", loc); - RNA_float_get_array(op->ptr, "rotation", rot); - RNA_boolean_get_array(op->ptr, "layer", layer_values); - - for(a=0; a<32; a++) - if(layer_values[a]) - *layer |= (1 << a); - else - *layer &= ~(1 << a); + + if(*layer == 0) { + BKE_report(op->reports, RPT_ERROR, "Property 'layer' has no values set"); + return 0; + } + + return 1; } /* for object add primitive operators */ @@ -310,7 +316,9 @@ static int object_add_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); + if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) + return OPERATOR_CANCELLED; + ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer); return OPERATOR_FINISHED; @@ -369,7 +377,9 @@ static Object *effector_add_type(bContext *C, wmOperator *op, int type) float mat[4][4]; object_add_generic_invoke_options(C, op); - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); + + if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) + return NULL; if(type==PFIELD_GUIDE) { ob= ED_object_add_type(C, OB_CURVE, loc, rot, FALSE, layer); @@ -377,7 +387,7 @@ static Object *effector_add_type(bContext *C, wmOperator *op, int type) ((Curve*)ob->data)->flag |= CU_PATH|CU_3D; ED_object_enter_editmode(C, 0); - ED_object_new_primitive_matrix(C, loc, rot, mat); + ED_object_new_primitive_matrix(C, ob, loc, rot, mat); BLI_addtail(curve_get_editcurve(ob), add_nurbs_primitive(C, mat, CU_NURBS|CU_PRIM_PATH, 1)); if(!enter_editmode) @@ -403,8 +413,9 @@ static Object *effector_add_type(bContext *C, wmOperator *op, int type) /* for object add operator */ static int effector_add_exec(bContext *C, wmOperator *op) { - effector_add_type(C, op, RNA_int_get(op->ptr, "type")); - + if(effector_add_type(C, op, RNA_int_get(op->ptr, "type")) == NULL) + return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } @@ -444,7 +455,9 @@ static int object_camera_add_exec(bContext *C, wmOperator *op) RNA_boolean_set(op->ptr, "view_align", 1); object_add_generic_invoke_options(C, op); - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); + + if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) + return OPERATOR_CANCELLED; ob= ED_object_add_type(C, OB_CAMERA, loc, rot, FALSE, layer); @@ -479,160 +492,6 @@ void OBJECT_OT_camera_add(wmOperatorType *ot) /* ***************** add primitives *************** */ -static EnumPropertyItem prop_curve_types[] = { - {CU_BEZIER|CU_PRIM_CURVE, "BEZIER_CURVE", ICON_CURVE_BEZCURVE, "Bezier Curve", ""}, - {CU_BEZIER|CU_PRIM_CIRCLE, "BEZIER_CIRCLE", ICON_CURVE_BEZCIRCLE, "Bezier Circle", ""}, - {CU_NURBS|CU_PRIM_CURVE, "NURBS_CURVE", ICON_CURVE_NCURVE, "NURBS Curve", ""}, - {CU_NURBS|CU_PRIM_CIRCLE, "NURBS_CIRCLE", ICON_CURVE_NCIRCLE, "NURBS Circle", ""}, - {CU_NURBS|CU_PRIM_PATH, "PATH", ICON_CURVE_PATH, "Path", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int object_add_curve_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - ListBase *editnurb; - Nurb *nu; - int newob= 0, type= RNA_enum_get(op->ptr, "type"); - int enter_editmode; - unsigned int layer; - float loc[3], rot[3]; - float mat[4][4]; - - object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); - - if(obedit==NULL || obedit->type!=OB_CURVE) { - obedit= ED_object_add_type(C, OB_CURVE, loc, rot, TRUE, layer); - newob = 1; - - if(type & CU_PRIM_PATH) - ((Curve*)obedit->data)->flag |= CU_PATH|CU_3D; - } - else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - - ED_object_new_primitive_matrix(C, loc, rot, mat); - - nu= add_nurbs_primitive(C, mat, type, newob); - editnurb= curve_get_editcurve(obedit); - BLI_addtail(editnurb, nu); - - /* userdef */ - if (newob && !enter_editmode) { - ED_object_exit_editmode(C, EM_FREEDATA); - } - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - - return OPERATOR_FINISHED; -} - -static int object_add_curve_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - Object *obedit= CTX_data_edit_object(C); - uiPopupMenu *pup; - uiLayout *layout; - - object_add_generic_invoke_options(C, op); - - pup= uiPupMenuBegin(C, op->type->name, 0); - layout= uiPupMenuLayout(pup); - if(!obedit || obedit->type == OB_CURVE) - uiItemsEnumO(layout, op->type->idname, "type"); - else - uiItemsEnumO(layout, "OBJECT_OT_surface_add", "type"); - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -void OBJECT_OT_curve_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Curve"; - ot->description = "Add a curve object to the scene"; - ot->idname= "OBJECT_OT_curve_add"; - - /* api callbacks */ - ot->invoke= object_add_curve_invoke; - ot->exec= object_add_curve_exec; - - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_curve_types, 0, "Primitive", ""); - - ED_object_add_generic_props(ot, TRUE); -} - -static EnumPropertyItem prop_surface_types[]= { - {CU_PRIM_CURVE|CU_NURBS, "NURBS_CURVE", ICON_SURFACE_NCURVE, "NURBS Curve", ""}, - {CU_PRIM_CIRCLE|CU_NURBS, "NURBS_CIRCLE", ICON_SURFACE_NCIRCLE, "NURBS Circle", ""}, - {CU_PRIM_PATCH|CU_NURBS, "NURBS_SURFACE", ICON_SURFACE_NSURFACE, "NURBS Surface", ""}, - {CU_PRIM_TUBE|CU_NURBS, "NURBS_TUBE", ICON_SURFACE_NTUBE, "NURBS Tube", ""}, - {CU_PRIM_SPHERE|CU_NURBS, "NURBS_SPHERE", ICON_SURFACE_NSPHERE, "NURBS Sphere", ""}, - {CU_PRIM_DONUT|CU_NURBS, "NURBS_DONUT", ICON_SURFACE_NDONUT, "NURBS Donut", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int object_add_surface_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - ListBase *editnurb; - Nurb *nu; - int newob= 0; - int enter_editmode; - unsigned int layer; - float loc[3], rot[3]; - float mat[4][4]; - - object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); - - if(obedit==NULL || obedit->type!=OB_SURF) { - obedit= ED_object_add_type(C, OB_SURF, loc, rot, TRUE, layer); - newob = 1; - } - else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - - ED_object_new_primitive_matrix(C, loc, rot, mat); - - nu= add_nurbs_primitive(C, mat, RNA_enum_get(op->ptr, "type"), newob); - editnurb= curve_get_editcurve(obedit); - BLI_addtail(editnurb, nu); - - /* userdef */ - if (newob && !enter_editmode) { - ED_object_exit_editmode(C, EM_FREEDATA); - } - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_surface_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Surface"; - ot->description = "Add a surface object to the scene"; - ot->idname= "OBJECT_OT_surface_add"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_add_surface_exec; - - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - ot->prop= RNA_def_enum(ot->srna, "type", prop_surface_types, 0, "Primitive", ""); - ED_object_add_generic_props(ot, TRUE); -} - static EnumPropertyItem prop_metaball_types[]= { {MB_BALL, "MBALL_BALL", ICON_META_BALL, "Meta Ball", ""}, {MB_TUBE, "MBALL_TUBE", ICON_META_TUBE, "Meta Tube", ""}, @@ -654,7 +513,9 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) float mat[4][4]; object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); + + if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) + return OPERATOR_CANCELLED; if(obedit==NULL || obedit->type!=OB_MBALL) { obedit= ED_object_add_type(C, OB_MBALL, loc, rot, TRUE, layer); @@ -662,7 +523,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) } else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - ED_object_new_primitive_matrix(C, loc, rot, mat); + ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); elem= (MetaElem*)add_metaball_primitive(C, mat, RNA_enum_get(op->ptr, "type"), newob); mball= (MetaBall*)obedit->data; @@ -724,7 +585,8 @@ static int object_add_text_exec(bContext *C, wmOperator *op) float loc[3], rot[3]; object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); + if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) + return OPERATOR_CANCELLED; if(obedit && obedit->type==OB_FONT) return OPERATOR_CANCELLED; @@ -764,7 +626,8 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) float loc[3], rot[3]; object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); + if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) + return OPERATOR_CANCELLED; if ((obedit==NULL) || (obedit->type != OB_ARMATURE)) { obedit= ED_object_add_type(C, OB_ARMATURE, loc, rot, TRUE, layer); @@ -810,6 +673,19 @@ void OBJECT_OT_armature_add(wmOperatorType *ot) ED_object_add_generic_props(ot, TRUE); } +static char *get_lamp_defname(int type) +{ + switch (type) { + case LA_LOCAL: return "Point"; + case LA_SUN: return "Sun"; + case LA_SPOT: return "Spot"; + case LA_HEMI: return "Hemi"; + case LA_AREA: return "Area"; + default: + return "Lamp"; + } +} + static int object_lamp_add_exec(bContext *C, wmOperator *op) { Object *ob; @@ -819,12 +695,16 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) float loc[3], rot[3]; object_add_generic_invoke_options(C, op); - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); + if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) + return OPERATOR_CANCELLED; ob= ED_object_add_type(C, OB_LAMP, loc, rot, FALSE, layer); if(ob && ob->data) ((Lamp*)ob->data)->type= type; + rename_id((ID *)ob, get_lamp_defname(type)); + rename_id((ID *)ob->data, get_lamp_defname(type)); + return OPERATOR_FINISHED; } @@ -859,22 +739,22 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot) static int group_instance_add_exec(bContext *C, wmOperator *op) { - Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "type")); + Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); int enter_editmode; unsigned int layer; float loc[3], rot[3]; object_add_generic_invoke_options(C, op); - ED_object_add_generic_get_opts(op, loc, rot, &enter_editmode, &layer); + if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) + return OPERATOR_CANCELLED; if(group) { Object *ob= ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer); rename_id(&ob->id, group->id.name+2); ob->dup_group= group; ob->transflag |= OB_DUPLIGROUP; - id_us_plus(&group->id); - + id_lib_extern(&group->id); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -904,7 +784,7 @@ void OBJECT_OT_group_instance_add(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", ""); + prop= RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", ""); RNA_def_enum_funcs(prop, RNA_group_itemf); ot->prop= prop; ED_object_add_generic_props(ot, FALSE); @@ -933,14 +813,13 @@ static int object_delete_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN(C, Base*, base, selected_bases) { if(base->object->type==OB_LAMP) islamp= 1; - /* remove from current scene only */ ED_base_object_free_and_unlink(scene, base); } CTX_DATA_END; if(islamp) reshadeall_displist(scene); /* only frees displist */ - + DAG_scene_sort(scene); DAG_ids_flush_update(0); @@ -968,7 +847,7 @@ void OBJECT_OT_delete(wmOperatorType *ot) /**************************** Copy Utilities ******************************/ static void copy_object__forwardModifierLinks(void *userData, Object *ob, - ID **idpoin) + ID **idpoin) { /* this is copied from ID_NEW; it might be better to have a macro */ if(*idpoin && (*idpoin)->newid) *idpoin = (*idpoin)->newid; @@ -979,10 +858,6 @@ static void copy_object_set_idnew(bContext *C, int dupflag) { Material *ma, *mao; ID *id; -#if 0 // XXX old animation system - Ipo *ipo; - bActionStrip *strip; -#endif // XXX old animation system int a; /* XXX check object pointers */ @@ -996,17 +871,8 @@ static void copy_object_set_idnew(bContext *C, int dupflag) } modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL); ID_NEW(ob->parent); - ID_NEW(ob->track); ID_NEW(ob->proxy); ID_NEW(ob->proxy_group); - -#if 0 // XXX old animation system - for(strip= ob->nlastrips.first; strip; strip= strip->next) { - bActionModifier *amod; - for(amod= strip->modifiers.first; amod; amod= amod->next) - ID_NEW(amod->ob); - } -#endif // XXX old animation system } CTX_DATA_END; @@ -1118,7 +984,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base) ob->lay= base->lay; copy_m4_m4(ob->obmat, dob->mat); - ED_object_apply_obmat(ob); + object_apply_mat4(ob, ob->obmat); } copy_object_set_idnew(C, 0); @@ -1142,6 +1008,7 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) DAG_scene_sort(scene); DAG_ids_flush_update(0); WM_event_add_notifier(C, NC_SCENE, scene); + WM_main_add_notifier(NC_OBJECT|ND_DRAW, NULL); return OPERATOR_FINISHED; } @@ -1167,7 +1034,7 @@ void OBJECT_OT_duplicates_make_real(wmOperatorType *ot) static EnumPropertyItem convert_target_items[]= { {OB_CURVE, "CURVE", ICON_OUTLINER_OB_CURVE, "Curve from Mesh/Text", ""}, - {OB_MESH, "MESH", ICON_OUTLINER_OB_MESH, "Mesh from Curve/Meta/Surf/Mesh", ""}, + {OB_MESH, "MESH", ICON_OUTLINER_OB_MESH, "Mesh from Curve/Meta/Surf/Text", ""}, {0, NULL, 0, NULL, NULL}}; static void curvetomesh(Scene *scene, Object *ob) @@ -1191,11 +1058,36 @@ static int convert_poll(bContext *C) return (!scene->id.lib && obact && scene->obedit != obact && (obact->flag & SELECT) && !(obact->id.lib)); } +/* Helper for convert_exec */ +static Base *duplibase_for_convert(Scene *scene, Base *base, Object *ob) +{ + Object *obn; + Base *basen; + + if (ob == NULL) { + ob= base->object; + } + + obn= copy_object(ob); + obn->recalc |= OB_RECALC_ALL; + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */ + basen->object= obn; + basen->flag |= SELECT; + obn->flag |= SELECT; + base->flag &= ~SELECT; + ob->flag &= ~SELECT; + + return basen; +} + static int convert_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Base *basen=NULL, *basact=NULL, *basedel=NULL; - Object *ob, *ob1, *obact= CTX_data_active_object(C); + Object *ob, *ob1, *newob, *obact= CTX_data_active_object(C); DerivedMesh *dm; Curve *cu; Nurb *nu; @@ -1203,8 +1095,8 @@ static int convert_exec(bContext *C, wmOperator *op) Mesh *me; int target= RNA_enum_get(op->ptr, "target"); int keep_original= RNA_boolean_get(op->ptr, "keep_original"); - int a; - + int a, mballConverted= 0; + /* don't forget multiple users! */ /* reset flags */ @@ -1216,67 +1108,87 @@ static int convert_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { ob= base->object; - - if(ob->flag & OB_DONE) - continue; + + if(ob->flag & OB_DONE) { + if (ob->type != target) { + base->flag &= ~SELECT; + ob->flag &= ~SELECT; + } + } else if (ob->type==OB_MESH && target == OB_CURVE) { ob->flag |= OB_DONE; - ob1= copy_object(ob); - ob1->recalc |= OB_RECALC; + if (keep_original) { + basen= duplibase_for_convert(scene, base, NULL); + newob= basen->object; - basen= MEM_mallocN(sizeof(Base), "duplibase"); - *basen= *base; - BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */ - basen->object= ob1; - basen->flag |= SELECT; - base->flag &= ~SELECT; - ob->flag &= ~SELECT; + /* decrement original mesh's usage count */ + me= newob->data; + me->id.us--; - mesh_to_curve(scene, ob1); + /* make a new copy of the mesh */ + newob->data= copy_mesh(me); + } else { + newob = ob; + } - if(ob1->type==OB_CURVE) - object_free_modifiers(ob1); /* after derivedmesh calls! */ + mesh_to_curve(scene, newob); + + if(newob->type==OB_CURVE) + object_free_modifiers(newob); /* after derivedmesh calls! */ } else if(ob->type==OB_MESH && ob->modifiers.first) { /* converting a mesh with no modifiers causes a segfault */ ob->flag |= OB_DONE; - basedel = base; - ob1= copy_object(ob); - ob1->recalc |= OB_RECALC; + if (keep_original) { + basen= duplibase_for_convert(scene, base, NULL); + newob= basen->object; - basen= MEM_mallocN(sizeof(Base), "duplibase"); - *basen= *base; - BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */ - basen->object= ob1; - basen->flag |= SELECT; - base->flag &= ~SELECT; - ob->flag &= ~SELECT; - - /* decrement original mesh's usage count */ - me= ob1->data; - me->id.us--; + /* decrement original mesh's usage count */ + me= newob->data; + me->id.us--; - /* make a new copy of the mesh */ - ob1->data= copy_mesh(me); + /* make a new copy of the mesh */ + newob->data= copy_mesh(me); + } else { + newob = ob; + ob->recalc |= OB_RECALC_ALL; + } /* make new mesh data from the original copy */ /* note: get the mesh from the original, not from the copy in some * cases this doesnt give correct results (when MDEF is used for eg) */ - dm= mesh_get_derived_final(scene, ob, CD_MASK_MESH); + dm= mesh_get_derived_final(scene, newob, CD_MASK_MESH); /* dm= mesh_create_derived_no_deform(ob1, NULL); this was called original (instead of get_derived). man o man why! (ton) */ - DM_to_mesh(dm, ob1->data); + DM_to_mesh(dm, newob->data); dm->release(dm); - object_free_modifiers(ob1); /* after derivedmesh calls! */ + object_free_modifiers(newob); /* after derivedmesh calls! */ } else if(ob->type==OB_FONT) { ob->flag |= OB_DONE; - ob->type= OB_CURVE; - cu= ob->data; + if (keep_original) { + basen= duplibase_for_convert(scene, base, NULL); + newob= basen->object; + + /* decrement original curve's usage count */ + ((Curve *)newob->data)->id.us--; + + /* make a new copy of the curve */ + newob->data= copy_curve(ob->data); + } else { + newob= ob; + } + + cu= newob->data; + + if (!cu->disp.first) + makeDispListCurveTypes(scene, newob, 0); + + newob->type= OB_CURVE; if(cu->vfont) { cu->vfont->id.us--; @@ -1293,13 +1205,16 @@ static int convert_exec(bContext *C, wmOperator *op) if(cu->vfontbi) { cu->vfontbi->id.us--; cu->vfontbi= 0; - } - /* other users */ - if(cu->id.us>1) { - for(ob1= G.main->object.first; ob1; ob1=ob1->id.next) { - if(ob1->data==cu) { - ob1->type= OB_CURVE; - ob1->recalc |= OB_RECALC; + } + + if (!keep_original) { + /* other users */ + if(cu->id.us>1) { + for(ob1= G.main->object.first; ob1; ob1=ob1->id.next) { + if(ob1->data==ob->data) { + ob1->type= OB_CURVE; + ob1->recalc |= OB_RECALC_ALL; + } } } } @@ -1308,46 +1223,76 @@ static int convert_exec(bContext *C, wmOperator *op) nu->charidx= 0; if(target == OB_MESH) - curvetomesh(scene, ob); + curvetomesh(scene, newob); } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { ob->flag |= OB_DONE; - if(target == OB_MESH) - curvetomesh(scene, ob); + if(target == OB_MESH) { + if (keep_original) { + basen= duplibase_for_convert(scene, base, NULL); + newob= basen->object; + + /* decrement original curve's usage count */ + ((Curve *)newob->data)->id.us--; + + /* make a new copy of the curve */ + newob->data= copy_curve(ob->data); + } else { + newob= ob; + } + + curvetomesh(scene, newob); + } } else if(ob->type==OB_MBALL) { - ob= find_basis_mball(scene, ob); - - if(ob->disp.first && !(ob->flag & OB_DONE)) { + Object *baseob; + + if (target != OB_MESH) { ob->flag |= OB_DONE; - basedel = base; + continue; + } - ob1= copy_object(ob); - ob1->recalc |= OB_RECALC; + base->flag &= ~SELECT; + ob->flag &= ~SELECT; - basen= MEM_mallocN(sizeof(Base), "duplibase"); - *basen= *base; - BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */ - basen->object= ob1; - basen->flag |= SELECT; - basedel->flag &= ~SELECT; - ob->flag &= ~SELECT; - - mb= ob1->data; + baseob= find_basis_mball(scene, ob); + + if (ob != baseob) { + /* if motherball is converting it would be marked as done later */ + ob->flag |= OB_DONE; + } + + if (!baseob->disp.first) { + makeDispListMBall(scene, baseob); + } + + if(!(baseob->flag & OB_DONE)) { + baseob->flag |= OB_DONE; + + basen= duplibase_for_convert(scene, base, baseob); + newob= basen->object; + + mb= newob->data; mb->id.us--; - - ob1->data= add_mesh("Mesh"); - ob1->type= OB_MESH; - - me= ob1->data; + + newob->data= add_mesh("Mesh"); + newob->type= OB_MESH; + + me= newob->data; me->totcol= mb->totcol; - if(ob1->totcol) { + if(newob->totcol) { me->mat= MEM_dupallocN(mb->mat); - for(a=0; a<ob1->totcol; a++) id_us_plus((ID *)me->mat[a]); + for(a=0; a<newob->totcol; a++) id_us_plus((ID *)me->mat[a]); } - - mball_to_mesh(&ob->disp, ob1->data); + + mball_to_mesh(&baseob->disp, newob->data); + + if (obact->type == OB_MBALL) { + basact= basen; + } + + mballConverted= 1; } else continue; @@ -1358,8 +1303,6 @@ static int convert_exec(bContext *C, wmOperator *op) /* If the original object is active then make this object active */ if(basen) { if(ob == obact) { - ED_base_object_activate(C, basen); - /* store new active base to update BASACT */ basact= basen; } @@ -1367,6 +1310,10 @@ static int convert_exec(bContext *C, wmOperator *op) basen= NULL; } + if (!keep_original) { + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + } + /* delete original if needed */ if(basedel) { if(!keep_original) @@ -1376,24 +1323,39 @@ static int convert_exec(bContext *C, wmOperator *op) } } CTX_DATA_END; - - /* delete object should renew depsgraph */ - if(!keep_original) + + if(!keep_original) { + if (mballConverted) { + Base *base= scene->base.first, *tmpbase; + while (base) { + ob= base->object; + tmpbase= base; + base= base->next; + + if (ob->type == OB_MBALL) { + ED_base_object_free_and_unlink(scene, tmpbase); + } + } + } + + /* delete object should renew depsgraph */ DAG_scene_sort(scene); + } // XXX ED_object_enter_editmode(C, 0); // XXX exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */ if (basact) { /* active base was changed */ + ED_base_object_activate(C, basact); BASACT= basact; + } else if (BASACT->object->flag & OB_DONE) { + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER|ND_DATA, BASACT->object); } DAG_scene_sort(scene); WM_event_add_notifier(C, NC_SCENE|NC_OBJECT|ND_DRAW, scene); /* is NC_SCENE needed ? */ - - return OPERATOR_FINISHED; } @@ -1442,7 +1404,7 @@ static Base *object_add_duplicate_internal(Scene *scene, Base *base, int dupflag } else { obn= copy_object(ob); - obn->recalc |= OB_RECALC; + obn->recalc |= OB_RECALC_ALL; basen= MEM_mallocN(sizeof(Base), "duplibase"); *basen= *base; @@ -1637,13 +1599,17 @@ Base *ED_object_add_duplicate(Scene *scene, Base *base, int dupflag) clear_id_newpoins(); clear_sca_new_poins(); /* sensor/contr/act */ - + basen= object_add_duplicate_internal(scene, base, dupflag); + if (basen == NULL) { + return NULL; + } + ob= basen->object; - + DAG_scene_sort(scene); ED_render_id_flush_update(G.main, ob->data); - + return basen; } @@ -1664,6 +1630,10 @@ static int duplicate_exec(bContext *C, wmOperator *op) the list is made in advance */ ED_base_object_select(base, BA_DESELECT); + if (basen == NULL) { + continue; + } + /* new object becomes active */ if(BASACT==base) ED_base_object_activate(C, basen); @@ -1684,6 +1654,8 @@ static int duplicate_exec(bContext *C, wmOperator *op) void OBJECT_OT_duplicate(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name= "Duplicate"; ot->description = "Duplicate selected objects"; @@ -1698,7 +1670,8 @@ void OBJECT_OT_duplicate(wmOperatorType *ot) /* to give to transform */ RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data."); - RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); + prop= RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN); } /* **************** add named object, for dragdrop ************* */ @@ -1726,36 +1699,42 @@ static int add_named_exec(bContext *C, wmOperator *op) int linked= RNA_boolean_get(op->ptr, "linked"); int dupflag= (linked)? 0: U.dupflag; char name[32]; - + /* find object, create fake base */ RNA_string_get(op->ptr, "name", name); ob= (Object *)find_id("OB", name); if(ob==NULL) return OPERATOR_CANCELLED; - + base= MEM_callocN(sizeof(Base), "duplibase"); base->object= ob; base->flag= ob->flag; - + /* prepare dupli */ clear_id_newpoins(); clear_sca_new_poins(); /* sensor/contr/act */ - + basen= object_add_duplicate_internal(scene, base, dupflag); + + if (basen == NULL) { + MEM_freeN(base); + return OPERATOR_CANCELLED; + } + basen->lay= basen->object->lay= scene->lay; - + ED_object_location_from_view(C, basen->object->loc); ED_base_object_activate(C, basen); - + copy_object_set_idnew(C, dupflag); - + DAG_scene_sort(scene); DAG_ids_flush_update(0); - + MEM_freeN(base); - + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index a4f419cf996..9f9d41147b6 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -1,5 +1,5 @@ /** - * $Id: + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -35,7 +35,6 @@ #include "MEM_guardedalloc.h" -#include "DNA_image_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" @@ -103,7 +102,8 @@ typedef struct BakeRender { short *stop; short *do_update; - + float *progress; + ListBase threads; /* backup */ @@ -141,7 +141,7 @@ static void init_bake_internal(BakeRender *bkr, bContext *C) bkr->sa= biggest_image_area(CTX_wm_screen(C)); /* can be NULL */ bkr->scene= scene; bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL; - bkr->re= RE_NewRender("_Bake View_", RE_SLOT_DEFAULT); + bkr->re= RE_NewRender("_Bake View_"); if(scene->r.bake_mode==RE_BAKE_AO) { /* If raytracing or AO is disabled, switch it on temporarily for baking. */ @@ -186,27 +186,28 @@ static void *do_bake_render(void *bake_v) { BakeRender *bkr= bake_v; - bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL); + bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress); bkr->ready= 1; return NULL; } -static void bake_startjob(void *bkv, short *stop, short *do_update) +static void bake_startjob(void *bkv, short *stop, short *do_update, float *progress) { BakeRender *bkr= bkv; Scene *scene= bkr->scene; bkr->stop= stop; bkr->do_update= do_update; + bkr->progress= progress; RE_test_break_cb(bkr->re, NULL, thread_break); G.afbreek= 0; /* blender_test_break uses this global */ - RE_Database_Baking(bkr->re, scene, scene->r.bake_mode, bkr->actob); + RE_Database_Baking(bkr->re, scene, scene->lay, scene->r.bake_mode, bkr->actob); /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */ - bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update); + bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress); } static void bake_update(void *bkv) @@ -261,10 +262,10 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *_eve bkr->reports= op->reports; /* setup job */ - steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY); + steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS); WM_jobs_customdata(steve, bkr, bake_freejob); WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ - WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update); + WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL); G.afbreek= 0; @@ -301,7 +302,7 @@ static int bake_image_exec(bContext *C, wmOperator *op) RE_test_break_cb(bkr.re, NULL, thread_break); G.afbreek= 0; /* blender_test_break uses this global */ - RE_Database_Baking(bkr.re, scene, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL); + RE_Database_Baking(bkr.re, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL); /* baking itself is threaded, cannot use test_break in threads */ BLI_init_threads(&threads, do_bake_render, 1); diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 2b880f17e90..8d48b76fb51 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -36,15 +36,10 @@ #include "BLI_math.h" #include "BLI_dynstr.h" -#include "DNA_action_types.h" -#include "DNA_armature_types.h" #include "DNA_constraint_types.h" #include "DNA_curve_types.h" -#include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_screen_types.h" #include "DNA_text_types.h" -#include "DNA_view3d_types.h" #include "BKE_action.h" #include "BKE_armature.h" @@ -68,7 +63,6 @@ #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" -#include "RNA_types.h" #include "ED_object.h" #include "ED_screen.h" @@ -139,6 +133,7 @@ bConstraint *get_active_constraint (Object *ob) { return constraints_get_active(get_active_constraints(ob)); } + /* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */ /* ------------- PyConstraints ------------------ */ @@ -204,9 +199,9 @@ char *buildmenu_pyconstraints (Text *con_text, int *pyconindex) /* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */ void update_pyconstraint_cb (void *arg1, void *arg2) { +#ifndef DISABLE_PYTHON Object *owner= (Object *)arg1; bConstraint *con= (bConstraint *)arg2; -#ifndef DISABLE_PYTHON if (owner && con) BPY_pyconstraint_update(owner, con); #endif @@ -328,6 +323,23 @@ static void test_constraints (Object *owner, bPoseChannel *pchan) /* targets have already been checked for this */ continue; } + else if (curcon->type == CONSTRAINT_TYPE_PIVOT) { + bPivotConstraint *data = curcon->data; + + /* target doesn't have to exist, but if it is non-null, it must exist! */ + if (data->tar && exist_object(data->tar)==0) { + data->tar = NULL; + curcon->flag |= CONSTRAINT_DISABLE; + } + else if (data->tar == owner) { + if (!get_named_bone(get_armature(owner), data->subtarget)) { + curcon->flag |= CONSTRAINT_DISABLE; + } + } + + /* targets have already been checked for this */ + continue; + } else if (curcon->type == CONSTRAINT_TYPE_ACTION) { bActionConstraint *data = curcon->data; @@ -424,40 +436,139 @@ static void test_constraints (Object *owner, bPoseChannel *pchan) void object_test_constraints (Object *owner) { - if(owner->constraints.first) + if (owner->constraints.first) test_constraints(owner, NULL); - + if (owner->type==OB_ARMATURE && owner->pose) { bPoseChannel *pchan; - - for (pchan= owner->pose->chanbase.first; pchan; pchan= pchan->next) - if(pchan->constraints.first) + + for (pchan= owner->pose->chanbase.first; pchan; pchan= pchan->next) { + if (pchan->constraints.first) test_constraints(owner, pchan); + } } } -/* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */ -/* ---------- Distance-Dependent Constraints ---------- */ -/* StretchTo, Limit Distance */ +/************************ generic functions for operators using constraint names and data context *********************/ + +#define EDIT_CONSTRAINT_OWNER_OBJECT 0 +#define EDIT_CONSTRAINT_OWNER_BONE 1 + +static EnumPropertyItem constraint_owner_items[] = { + {EDIT_CONSTRAINT_OWNER_OBJECT, "OBJECT", 0, "Object", "Edit a constraint on the active object"}, + {EDIT_CONSTRAINT_OWNER_BONE, "BONE", 0, "Bone", "Edit a constraint on the active bone"}, + {0, NULL, 0, NULL, NULL}}; -static int stretchto_poll(bContext *C) + +static int edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_StretchToConstraint); - return (ptr.id.data && ptr.data); + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", rna_type); + Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C); + + if (!ob || ob->id.lib) return 0; + if (ptr.data && ((ID*)ptr.id.data)->lib) return 0; + + return 1; +} + +static int edit_constraint_poll(bContext *C) +{ + return edit_constraint_poll_generic(C, &RNA_Constraint); } +static void edit_constraint_properties(wmOperatorType *ot) +{ + RNA_def_string(ot->srna, "constraint", "", 32, "Constraint", "Name of the constraint to edit"); + RNA_def_enum(ot->srna, "owner", constraint_owner_items, 0, "Owner", "The owner of this constraint"); +} + +static int edit_constraint_invoke_properties(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); + Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C); + bConstraint *con; + ListBase *list; + + if (RNA_property_is_set(op->ptr, "constraint") && RNA_property_is_set(op->ptr, "owner")) + return 1; + + if (ptr.data) { + con = ptr.data; + RNA_string_set(op->ptr, "constraint", con->name); + + list = get_constraint_lb(ob, con, NULL); + + if (&ob->constraints == list) + RNA_enum_set(op->ptr, "owner", EDIT_CONSTRAINT_OWNER_OBJECT); + else + RNA_enum_set(op->ptr, "owner", EDIT_CONSTRAINT_OWNER_BONE); + + return 1; + } + + return 0; +} + +static bConstraint *edit_constraint_property_get(bContext *C, wmOperator *op, Object *ob, int type) +{ + char constraint_name[32]; + int owner = RNA_enum_get(op->ptr, "owner"); + bConstraint *con; + ListBase *list=NULL; + + RNA_string_get(op->ptr, "constraint", constraint_name); + + if (owner == EDIT_CONSTRAINT_OWNER_OBJECT) { + list = &ob->constraints; + } + else if (owner == EDIT_CONSTRAINT_OWNER_BONE) { + bPoseChannel *pchan= get_active_posechannel(ob); + if (pchan) + list = &pchan->constraints; + else + return NULL; + } + + con = constraints_findByName(list, constraint_name); + + if (con && (type != 0) && (con->type != type)) + con = NULL; + + return con; +} + +/* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */ + +/* ---------- Distance-Dependent Constraints ---------- */ +/* StretchTo, Limit Distance */ + static int stretchto_reset_exec (bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_StretchToConstraint); + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_STRETCHTO); + bStretchToConstraint *data= (con) ? (bStretchToConstraint *)con->data : NULL; + + /* despite 3 layers of checks, we may still not be able to find a constraint */ + if (data == NULL) + return OPERATOR_CANCELLED; /* just set original length to 0.0, which will cause a reset on next recalc */ - RNA_float_set(&ptr, "original_length", 0.0f); + data->orglength = 0.0f; + ED_object_constraint_update(ob); WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL); return OPERATOR_FINISHED; } +static int stretchto_reset_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_constraint_invoke_properties(C, op)) + return stretchto_reset_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void CONSTRAINT_OT_stretchto_reset (wmOperatorType *ot) { /* identifiers */ @@ -466,28 +577,39 @@ void CONSTRAINT_OT_stretchto_reset (wmOperatorType *ot) ot->description= "Reset original length of bone for Stretch To Constraint"; ot->exec= stretchto_reset_exec; - ot->poll= stretchto_poll; + ot->invoke= stretchto_reset_invoke; + ot->poll= edit_constraint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_constraint_properties(ot); } static int limitdistance_reset_exec (bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_LimitDistanceConstraint); + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_DISTLIMIT); + bDistLimitConstraint *data= (con) ? (bDistLimitConstraint *)con->data : NULL; - /* just set distance to 0.0, which will cause a reset on next recalc */ - RNA_float_set(&ptr, "distance", 0.0f); + /* despite 3 layers of checks, we may still not be able to find a constraint */ + if (data == NULL) + return OPERATOR_CANCELLED; + + /* just set original length to 0.0, which will cause a reset on next recalc */ + data->dist = 0.0f; + ED_object_constraint_update(ob); WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL); return OPERATOR_FINISHED; } -static int limitdistance_poll(bContext *C) +static int limitdistance_reset_invoke(bContext *C, wmOperator *op, wmEvent *event) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_LimitDistanceConstraint); - return (ptr.id.data && ptr.data); + if (edit_constraint_invoke_properties(C, op)) + return limitdistance_reset_exec(C, op); + else + return OPERATOR_CANCELLED; } void CONSTRAINT_OT_limitdistance_reset (wmOperatorType *ot) @@ -498,30 +620,29 @@ void CONSTRAINT_OT_limitdistance_reset (wmOperatorType *ot) ot->description= "Reset limiting distance for Limit Distance Constraint"; ot->exec= limitdistance_reset_exec; - ot->poll= limitdistance_poll; + ot->invoke= limitdistance_reset_invoke; + ot->poll= edit_constraint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_constraint_properties(ot); } /* ------------- Child-Of Constraint ------------------ */ -static int childof_poll(bContext *C) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); - return (ptr.id.data && ptr.data); -} - /* ChildOf Constraint - set inverse callback */ static int childof_set_inverse_exec (bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); Scene *scene= CTX_data_scene(C); - Object *ob= ptr.id.data; - bConstraint *con= ptr.data; - bChildOfConstraint *data= (bChildOfConstraint *)con->data; + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_CHILDOF); + bChildOfConstraint *data= (con) ? (bChildOfConstraint *)con->data : NULL; bPoseChannel *pchan= NULL; - + + /* despite 3 layers of checks, we may still not be able to find a constraint */ + if (data == NULL) + return OPERATOR_CANCELLED; + /* try to find a pose channel */ // TODO: get from context instead? if (ob && ob->pose) @@ -570,6 +691,14 @@ static int childof_set_inverse_exec (bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int childof_set_inverse_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_constraint_invoke_properties(C, op)) + return childof_set_inverse_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void CONSTRAINT_OT_childof_set_inverse (wmOperatorType *ot) { /* identifiers */ @@ -578,19 +707,20 @@ void CONSTRAINT_OT_childof_set_inverse (wmOperatorType *ot) ot->description= "Set inverse correction for ChildOf constraint"; ot->exec= childof_set_inverse_exec; - ot->poll= childof_poll; + ot->invoke= childof_set_inverse_invoke; + ot->poll= edit_constraint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_constraint_properties(ot); } /* ChildOf Constraint - clear inverse callback */ static int childof_clear_inverse_exec (bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); - Object *ob= ptr.id.data; - bConstraint *con= ptr.data; - bChildOfConstraint *data= (bChildOfConstraint *)con->data; + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(C, op, ob, CONSTRAINT_TYPE_CHILDOF); + bChildOfConstraint *data= (con) ? (bChildOfConstraint *)con->data : NULL; /* simply clear the matrix */ unit_m4(data->invmat); @@ -600,6 +730,14 @@ static int childof_clear_inverse_exec (bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int childof_clear_inverse_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_constraint_invoke_properties(C, op)) + return childof_clear_inverse_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot) { /* identifiers */ @@ -608,10 +746,12 @@ void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot) ot->description= "Clear inverse correction for ChildOf constraint"; ot->exec= childof_clear_inverse_exec; - ot->poll= childof_poll; + ot->invoke= childof_clear_inverse_invoke; + ot->poll= edit_constraint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_constraint_properties(ot); } /***************************** BUTTONS ****************************/ @@ -644,7 +784,7 @@ void ED_object_constraint_dependency_update(Scene *scene, Object *ob) ED_object_constraint_update(ob); if(ob->pose) ob->pose->flag |= POSE_RECALC; // checks & sorts pose channels - DAG_scene_sort(scene); + DAG_scene_sort(scene); } static int constraint_poll(bContext *C) @@ -681,7 +821,7 @@ void CONSTRAINT_OT_delete (wmOperatorType *ot) /* identifiers */ ot->name= "Delete Constraint"; ot->idname= "CONSTRAINT_OT_delete"; - ot->description= "Remove constraitn from constraint stack"; + ot->description= "Remove constraint from constraint stack"; /* callbacks */ ot->exec= constraint_delete_exec; @@ -693,11 +833,10 @@ void CONSTRAINT_OT_delete (wmOperatorType *ot) static int constraint_move_down_exec (bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); - Object *ob= ptr.id.data; - bConstraint *con= ptr.data; + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(C, op, ob, 0); - if (con->next) { + if (con && con->next) { ListBase *conlist= get_constraint_lb(ob, con, NULL); bConstraint *nextCon= con->next; @@ -713,29 +852,39 @@ static int constraint_move_down_exec (bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } +static int constraint_move_down_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_constraint_invoke_properties(C, op)) + return constraint_move_down_exec(C, op); + else + return OPERATOR_CANCELLED; +} + + void CONSTRAINT_OT_move_down (wmOperatorType *ot) { /* identifiers */ ot->name= "Move Constraint Down"; ot->idname= "CONSTRAINT_OT_move_down"; - ot->description= "Move constraint down constraint stack"; + ot->description= "Move constraint down in constraint stack"; /* callbacks */ ot->exec= constraint_move_down_exec; - ot->poll= constraint_poll; + ot->invoke= constraint_move_down_invoke; + ot->poll= edit_constraint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_constraint_properties(ot); } static int constraint_move_up_exec (bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); - Object *ob= ptr.id.data; - bConstraint *con= ptr.data; + Object *ob = ED_object_active_context(C); + bConstraint *con = edit_constraint_property_get(C, op, ob, 0); - if (con->prev) { + if (con && con->prev) { ListBase *conlist= get_constraint_lb(ob, con, NULL); bConstraint *prevCon= con->prev; @@ -751,19 +900,29 @@ static int constraint_move_up_exec (bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } +static int constraint_move_up_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_constraint_invoke_properties(C, op)) + return constraint_move_up_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void CONSTRAINT_OT_move_up (wmOperatorType *ot) { /* identifiers */ ot->name= "Move Constraint Up"; ot->idname= "CONSTRAINT_OT_move_up"; - ot->description= "Move constraint up constraint stack"; + ot->description= "Move constraint up in constraint stack"; /* callbacks */ ot->exec= constraint_move_up_exec; - ot->poll= constraint_poll; + ot->invoke= constraint_move_up_invoke; + ot->poll= edit_constraint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_constraint_properties(ot); } /***************************** OPERATORS ****************************/ @@ -808,19 +967,21 @@ void POSE_OT_constraints_clear(wmOperatorType *ot) static int object_constraints_clear_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); Scene *scene= CTX_data_scene(C); /* do freeing */ - // TODO: we should free constraints for all selected objects instead (to be more consistent with bones) - free_constraints(&ob->constraints); + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) + { + free_constraints(&ob->constraints); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); + } + CTX_DATA_END; /* force depsgraph to get recalculated since relationships removed */ DAG_scene_sort(scene); /* sort order of objects */ /* do updates */ - DAG_id_flush_update(&ob->id, OB_RECALC_OB); - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL); return OPERATOR_FINISHED; } @@ -837,12 +998,90 @@ void OBJECT_OT_constraints_clear(wmOperatorType *ot) ot->poll= ED_operator_object_active_editable; } +/************************ copy all constraints operators *********************/ + +static int pose_constraint_copy_exec(bContext *C, wmOperator *op) +{ + bPoseChannel *pchan = CTX_data_active_pose_bone(C); + Scene *scene = CTX_data_scene(C); + + /* don't do anything if bone doesn't exist or doesn't have any constraints */ + if (ELEM(NULL, pchan, pchan->constraints.first)) { + BKE_report(op->reports, RPT_ERROR, "No active bone with constraints for copying"); + return OPERATOR_CANCELLED; + } + + /* copy all constraints from active posebone to all selected posebones */ + CTX_DATA_BEGIN(C, bPoseChannel*, chan, selected_pose_bones) + { + /* if we're not handling the object we're copying from, copy all constraints over */ + if (pchan != chan) + copy_constraints(&chan->constraints, &pchan->constraints, TRUE); + } + CTX_DATA_END; + + /* force depsgraph to get recalculated since new relationships added */ + DAG_scene_sort(scene); /* sort order of objects/bones */ + + return OPERATOR_FINISHED; +} + +void POSE_OT_constraints_copy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy Constraints to Selected"; + ot->idname= "POSE_OT_constraints_copy"; + ot->description = "Copy constraints to other selected bones."; + + /* api callbacks */ + ot->exec= pose_constraint_copy_exec; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int object_constraint_copy_exec(bContext *C, wmOperator *op) +{ + Object *obact = ED_object_active_context(C); + Scene *scene = CTX_data_scene(C); + + /* copy all constraints from active object to all selected objects */ + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) + { + /* if we're not handling the object we're copying from, copy all constraints over */ + if (obact != ob) + copy_constraints(&ob->constraints, &obact->constraints, TRUE); + } + CTX_DATA_END; + + /* force depsgraph to get recalculated since new relationships added */ + DAG_scene_sort(scene); /* sort order of objects */ + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_constraints_copy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy Constraints to Selected"; + ot->idname= "OBJECT_OT_constraints_copy"; + ot->description = "Copy constraints to other selected objects."; + + /* api callbacks */ + ot->exec= object_constraint_copy_exec; + ot->poll= ED_operator_object_active_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /************************ add constraint operators *********************/ /* get the Object and/or PoseChannel to use as target */ static short get_new_constraint_target(bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, short add) { - Object *obact= CTX_data_active_object(C); + Object *obact= ED_object_active_context(C); bPoseChannel *pchanact= get_active_posechannel(obact); short only_curve= 0, only_mesh= 0, only_ob= 0; short found= 0; @@ -864,6 +1103,7 @@ static short get_new_constraint_target(bContext *C, int con_type, Object **tar_o case CONSTRAINT_TYPE_LOCLIMIT: case CONSTRAINT_TYPE_ROTLIMIT: case CONSTRAINT_TYPE_SIZELIMIT: + case CONSTRAINT_TYPE_SAMEVOL: return 0; /* restricted target-type constraints -------------- */ @@ -1006,7 +1246,7 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase } /* create a new constraint of the type requried, and add it to the active/given constraints list */ - if(pchan) + if (pchan) con = add_pose_constraint(ob, pchan, NULL, type); else con = add_ob_constraint(ob, NULL, type); @@ -1046,9 +1286,9 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase case CONSTRAINT_TYPE_PYTHON: // FIXME: this code is not really valid anymore { +#ifndef DISABLE_PYTHON char *menustr; int scriptint= 0; -#ifndef DISABLE_PYTHON /* popup a list of usable scripts */ menustr = buildmenu_pyconstraints(NULL, &scriptint); // XXX scriptint = pupmenu(menustr); @@ -1096,17 +1336,10 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase /* dummy operator callback */ static int object_constraint_add_exec(bContext *C, wmOperator *op) { - ScrArea *sa= CTX_wm_area(C); - Object *ob; + Object *ob=ED_object_active_context(C); int type= RNA_enum_get(op->ptr, "type"); short with_targets= 0; - /* get active object from context */ - if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - else - ob= CTX_data_active_object(C); - if (!ob) { BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to."); return OPERATOR_CANCELLED; @@ -1124,17 +1357,10 @@ static int object_constraint_add_exec(bContext *C, wmOperator *op) /* dummy operator callback */ static int pose_constraint_add_exec(bContext *C, wmOperator *op) { - ScrArea *sa= CTX_wm_area(C); - Object *ob; + Object *ob= ED_object_active_context(C); int type= RNA_enum_get(op->ptr, "type"); short with_targets= 0; - /* get active object from context */ - if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - else - ob= CTX_data_active_object(C); - if (!ob) { BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to."); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 2e72f51bee9..fcd3a73c84d 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -30,41 +30,20 @@ #include <time.h> #include <float.h> #include <ctype.h> +#include <stddef.h> //for offsetof #include "MEM_guardedalloc.h" #include "IMB_imbuf_types.h" -#include "DNA_action_types.h" #include "DNA_armature_types.h" -#include "DNA_camera_types.h" -#include "DNA_constraint_types.h" #include "DNA_curve_types.h" -#include "DNA_effect_types.h" #include "DNA_group_types.h" -#include "DNA_image_types.h" -#include "DNA_key_types.h" -#include "DNA_lamp_types.h" #include "DNA_lattice_types.h" #include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "DNA_meta_types.h" -#include "DNA_nla_types.h" -#include "DNA_object_types.h" -#include "DNA_object_fluidsim.h" -#include "DNA_object_force.h" -#include "DNA_scene_types.h" -#include "DNA_space_types.h" -#include "DNA_screen_types.h" -#include "DNA_texture_types.h" -#include "DNA_particle_types.h" #include "DNA_property_types.h" -#include "DNA_userdef_types.h" -#include "DNA_view3d_types.h" #include "DNA_vfont_types.h" -#include "DNA_world_types.h" -#include "DNA_modifier_types.h" #include "BLI_blenlib.h" #include "BLI_math.h" @@ -75,12 +54,10 @@ #include "BKE_action.h" #include "BKE_anim.h" #include "BKE_armature.h" -#include "BKE_booleanops.h" #include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_blender.h" -#include "BKE_booleanops.h" #include "BKE_cloth.h" #include "BKE_curve.h" #include "BKE_displist.h" @@ -114,36 +91,29 @@ #include "BKE_modifier.h" #include "BKE_tessmesh.h" -#include "ED_anim_api.h" #include "ED_armature.h" #include "ED_curve.h" -#include "ED_particle.h" #include "ED_mesh.h" #include "ED_mball.h" #include "ED_object.h" #include "ED_screen.h" -#include "ED_transform.h" -#include "ED_types.h" #include "ED_util.h" -#include "ED_view3d.h" -#include "UI_interface.h" #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" /* for menu/popup icons etc etc*/ -#include "UI_interface.h" -#include "UI_resources.h" +#include "UI_interface.h" #include "WM_api.h" #include "WM_types.h" #include "object_intern.h" // own include /* ************* XXX **************** */ -static void error() {} +static void error(const char *dummy) {} static void waitcursor(int val) {} static int pupmenu(const char *msg) {return 0;} @@ -151,34 +121,20 @@ static int pupmenu(const char *msg) {return 0;} static bContext *C; static void error_libdata() {} -/* ********************************** */ -/* --------------------------------- */ - -void ED_object_apply_obmat(Object *ob) +/* find the correct active object per context + * note: context can be NULL when called from a enum with PROP_ENUM_NO_CONTEXT */ +Object *ED_object_active_context(bContext *C) { - float mat[3][3], imat[3][3], tmat[3][3]; - - /* from obmat to loc rot size */ - - if(ob==NULL) return; - copy_m3_m4(mat, ob->obmat); - - VECCOPY(ob->loc, ob->obmat[3]); - - mat3_to_eul( ob->rot,mat); - eul_to_mat3( tmat,ob->rot); - - invert_m3_m3(imat, tmat); - - mul_m3_m3m3(tmat, imat, mat); - - ob->size[0]= tmat[0][0]; - ob->size[1]= tmat[1][1]; - ob->size[2]= tmat[2][2]; - + Object *ob= NULL; + if(C) { + ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + if (!ob) ob= CTX_data_active_object(C); + } + return ob; } + /* ********* clear/set restrict view *********/ static int object_restrictview_clear_exec(bContext *C, wmOperator *op) { @@ -276,6 +232,79 @@ void OBJECT_OT_restrictview_set(wmOperatorType *ot) } +/* 99% same as above except no need for scene refreshing (TODO, update render preview) */ +static int object_restrictrender_clear_exec(bContext *C, wmOperator *op) +{ + short changed= 0; + + /* XXX need a context loop to handle such cases */ + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(ob->restrictflag & OB_RESTRICT_RENDER) { + ob->restrictflag &= ~OB_RESTRICT_RENDER; + changed= 1; + } + } + CTX_DATA_END; + + if(changed) + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_OUTLINER, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_restrictrender_clear(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Clear Restrict Render"; + ot->description = "Reveal the render object by setting the restrictrender flag"; + ot->idname= "OBJECT_OT_restrictrender_clear"; + + /* api callbacks */ + ot->exec= object_restrictrender_clear_exec; + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int object_restrictrender_set_exec(bContext *C, wmOperator *op) +{ + int unselected= RNA_boolean_get(op->ptr, "unselected"); + + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if(!unselected) { + if (base->flag & SELECT){ + base->object->restrictflag |= OB_RESTRICT_RENDER; + } + } + else { + if (!(base->flag & SELECT)){ + base->object->restrictflag |= OB_RESTRICT_RENDER; + } + } + } + CTX_DATA_END; + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_OUTLINER, NULL); + return OPERATOR_FINISHED; +} + +void OBJECT_OT_restrictrender_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Restrict Render"; + ot->description = "Hide the render object by setting the restrictrender flag"; + ot->idname= "OBJECT_OT_restrictrender_set"; + + /* api callbacks */ + ot->exec= object_restrictrender_set_exec; + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects."); +} /* ******************* toggle editmode operator ***************** */ @@ -311,8 +340,10 @@ void ED_object_exit_editmode(bContext *C, int flag) me->edit_btmesh= NULL; } - if(obedit->restore_mode & OB_MODE_WEIGHT_PAINT) - mesh_octree_table(obedit, NULL, NULL, 'e'); + if(obedit->restore_mode & OB_MODE_WEIGHT_PAINT) { + mesh_octree_table(NULL, NULL, NULL, 'e'); + mesh_mirrtopo_table(NULL, 'e'); + } } else if (obedit->type==OB_ARMATURE) { ED_armature_from_edit(obedit); @@ -338,8 +369,19 @@ void ED_object_exit_editmode(bContext *C, int flag) /* freedata only 0 now on file saves and render */ if(freedata) { + ListBase pidlist; + PTCacheID *pid; + /* for example; displist make is different in editmode */ scene->obedit= NULL; // XXX for context + + /* flag object caches as outdated */ + BKE_ptcache_ids_from_object(&pidlist, obedit, NULL, 0); + for(pid=pidlist.first; pid; pid=pid->next) { + if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ + pid->cache->flag |= PTCACHE_OUTDATED; + } + BLI_freelistN(&pidlist); BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_DEPSGRAPH); @@ -354,7 +396,6 @@ void ED_object_exit_editmode(bContext *C, int flag) WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); obedit->mode &= ~OB_MODE_EDIT; - ED_object_toggle_modes(C, obedit->restore_mode); } } @@ -397,8 +438,7 @@ void ED_object_enter_editmode(bContext *C, int flag) ob->restore_mode = ob->mode; ED_object_toggle_modes(C, ob->mode); - - ob->mode |= OB_MODE_EDIT; + ob->mode= OB_MODE_EDIT; if(ob->type==OB_MESH) { Mesh *me= ob->data; @@ -430,14 +470,14 @@ void ED_object_enter_editmode(bContext *C, int flag) scene->obedit= ob; ED_armature_to_edit(ob); /* to ensure all goes in restposition and without striding */ - DAG_id_flush_update(&ob->id, OB_RECALC); + DAG_id_flush_update(&ob->id, OB_RECALC_ALL); // XXX: should this be OB_RECALC_DATA? WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, scene); } else if(ob->type==OB_FONT) { scene->obedit= ob; // XXX for context ok= 1; - make_editText(ob); + make_editText(ob); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_TEXT, scene); } @@ -495,9 +535,9 @@ static int editmode_toggle_poll(bContext *C) return 0; return ob && (ob->type == OB_MESH || ob->type == OB_ARMATURE || - ob->type == OB_FONT || ob->type == OB_MBALL || - ob->type == OB_LATTICE || ob->type == OB_SURF || - ob->type == OB_CURVE); + ob->type == OB_FONT || ob->type == OB_MBALL || + ob->type == OB_LATTICE || ob->type == OB_SURF || + ob->type == OB_CURVE); } void OBJECT_OT_editmode_toggle(wmOperatorType *ot) @@ -1062,6 +1102,7 @@ void flip_subdivison(Scene *scene, View3D *v3d, int level) static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) { +//XXX no longer used - to be removed - replaced by game_properties_copy_exec bProperty *prop; Base *base; int nr, tot=0; @@ -1120,6 +1161,7 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob) { +//XXX no longer used - to be removed - replaced by logicbricks_copy_exec Base *base; for(base= FIRSTBASE; base; base= base->next) { @@ -1368,7 +1410,7 @@ void copy_attr(Scene *scene, View3D *v3d, short event) base->object->dup_group= ob->dup_group; if(ob->dup_group) - id_us_plus((ID *)ob->dup_group); + id_lib_extern(&ob->dup_group->id); } else if(event==7) { /* mass */ base->object->mass= ob->mass; @@ -1487,7 +1529,7 @@ void copy_attr(Scene *scene, View3D *v3d, short event) } else if(event==22) { /* Copy the constraint channels over */ - copy_constraints(&base->object->constraints, &ob->constraints); + copy_constraints(&base->object->constraints, &ob->constraints, TRUE); do_scene_sort= 1; } @@ -1678,6 +1720,7 @@ void ED_objects_clear_paths(bContext *C, Scene *scene) if (ob->mpath) { animviz_free_motionpath(ob->mpath); ob->mpath= NULL; + ob->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS; } } CTX_DATA_END; @@ -1751,6 +1794,11 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) return (done)? OPERATOR_FINISHED: OPERATOR_CANCELLED; } +static int shade_poll(bContext *C) +{ + return (ED_operator_object_active_editable(C) && !ED_operator_editmesh(C)); +} + void OBJECT_OT_shade_flat(wmOperatorType *ot) { /* identifiers */ @@ -1758,7 +1806,7 @@ void OBJECT_OT_shade_flat(wmOperatorType *ot) ot->idname= "OBJECT_OT_shade_flat"; /* api callbacks */ - ot->poll= ED_operator_object_active_editable; + ot->poll= shade_poll; ot->exec= shade_smooth_exec; /* flags */ @@ -1772,7 +1820,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot) ot->idname= "OBJECT_OT_shade_smooth"; /* api callbacks */ - ot->poll= ED_operator_object_active_editable; + ot->poll= shade_poll; ot->exec= shade_smooth_exec; /* flags */ @@ -1950,12 +1998,12 @@ static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *ptr, in ob = CTX_data_active_object(C); while(ob && input->identifier) { if((input->value == OB_MODE_EDIT && ((ob->type == OB_MESH) || (ob->type == OB_ARMATURE) || - (ob->type == OB_CURVE) || (ob->type == OB_SURF) || - (ob->type == OB_FONT) || (ob->type == OB_MBALL) || (ob->type == OB_LATTICE))) || + (ob->type == OB_CURVE) || (ob->type == OB_SURF) || + (ob->type == OB_FONT) || (ob->type == OB_MBALL) || (ob->type == OB_LATTICE))) || (input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) || (input->value == OB_MODE_PARTICLE_EDIT && ob->particlesystem.first) || ((input->value == OB_MODE_SCULPT || input->value == OB_MODE_VERTEX_PAINT || - input->value == OB_MODE_WEIGHT_PAINT || input->value == OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || + input->value == OB_MODE_WEIGHT_PAINT || input->value == OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || (input->value == OB_MODE_OBJECT)) RNA_enum_item_add(&item, &totitem, input); ++input; @@ -2030,7 +2078,7 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); ObjectMode mode = RNA_enum_get(op->ptr, "mode"); - ObjectMode restore_mode = ob->mode; + ObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT; int toggle = RNA_boolean_get(op->ptr, "toggle"); if(!ob || !object_mode_set_compat(C, op, ob)) @@ -2097,6 +2145,8 @@ void ED_object_toggle_modes(bContext *C, int mode) WM_operator_name_call(C, "PARTICLE_OT_particle_edit_toggle", WM_OP_EXEC_REGION_WIN, NULL); if(mode & OB_MODE_POSE) WM_operator_name_call(C, "OBJECT_OT_posemode_toggle", WM_OP_EXEC_REGION_WIN, NULL); + if(mode & OB_MODE_EDIT) + WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); } /************************ Game Properties ***********************/ @@ -2113,6 +2163,7 @@ static int game_property_new(bContext *C, wmOperator *op) BLI_addtail(&ob->prop, prop); unique_property(NULL, prop, 0); // make_unique_prop_names(prop->name); + WM_event_add_notifier(C, NC_LOGIC, NULL); return OPERATOR_FINISHED; } @@ -2135,23 +2186,23 @@ static int game_property_remove(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); bProperty *prop; - int index; + int index= RNA_int_get(op->ptr, "index"); if(!ob) return OPERATOR_CANCELLED; - index = RNA_int_get(op->ptr, "index"); + prop= BLI_findlink(&ob->prop, index); - prop= BLI_findlink(&ob->prop, index); - - if(prop) { + if(prop) { BLI_remlink(&ob->prop, prop); free_property(prop); + + WM_event_add_notifier(C, NC_LOGIC, NULL); return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } + } + else { + return OPERATOR_CANCELLED; + } } void OBJECT_OT_game_property_remove(wmOperatorType *ot) @@ -2169,3 +2220,181 @@ void OBJECT_OT_game_property_remove(wmOperatorType *ot) RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Property index to remove ", 0, INT_MAX); } + +#define COPY_PROPERTIES_REPLACE 1 +#define COPY_PROPERTIES_MERGE 2 +#define COPY_PROPERTIES_COPY 3 + +static EnumPropertyItem game_properties_copy_operations[] ={ + {COPY_PROPERTIES_REPLACE, "REPLACE", 0, "Replace Properties", ""}, + {COPY_PROPERTIES_MERGE, "MERGE", 0, "Merge Properties", ""}, + {COPY_PROPERTIES_COPY, "COPY", 0, "Copy a Property", ""}, + {0, NULL, 0, NULL, NULL}}; + +static EnumPropertyItem gameprops_items[]= { + {0, NULL, 0, NULL, NULL}}; + +static EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Object *ob= ED_object_active_context(C); + EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem *item= NULL; + bProperty *prop; + int a, totitem= 0; + + if(!ob) + return gameprops_items; + + for(a=1, prop= ob->prop.first; prop; prop=prop->next, a++) { + tmp.value= a; + tmp.identifier= prop->name; + tmp.name= prop->name; + RNA_enum_item_add(&item, &totitem, &tmp); + } + + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; +} + +static int game_property_copy_exec(bContext *C, wmOperator *op) +{ + Object *ob=ED_object_active_context(C); + bProperty *prop; + int type = RNA_enum_get(op->ptr, "operation"); + int propid= RNA_enum_get(op->ptr, "property"); + + if(propid > 0) { /* copy */ + prop = BLI_findlink(&ob->prop, propid-1); + + if(prop) { + CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { + if (ob != ob_iter) { + if (ob->data != ob_iter->data) + set_ob_property(ob_iter, prop); + } + } CTX_DATA_END; + } + } + else if (ELEM(type, COPY_PROPERTIES_REPLACE, COPY_PROPERTIES_MERGE)) { + CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { + if (ob != ob_iter) { + if (ob->data != ob_iter->data){ + if (type == 2) {/* merge */ + for(prop = ob->prop.first; prop; prop= prop->next ) { + set_ob_property(ob_iter, prop); + } + } else /* replace */ + copy_properties( &ob_iter->prop, &ob->prop ); + } + } + } + CTX_DATA_END; + } + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_game_property_copy(wmOperatorType *ot) +{ + PropertyRNA *prop; + /* identifiers */ + ot->name= "Copy Game Property"; + ot->idname= "OBJECT_OT_game_property_copy"; + + /* api callbacks */ + ot->exec= game_property_copy_exec; + ot->poll= ED_operator_object_active_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "operation", game_properties_copy_operations, 3, "Operation", ""); + prop=RNA_def_enum(ot->srna, "property", gameprops_items, 0, "Property", "Properties to copy"); + RNA_def_enum_funcs(prop, gameprops_itemf); + ot->prop=prop; +} + +static int game_property_clear_exec(bContext *C, wmOperator *op) +{ + CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { + free_properties(&ob_iter->prop); + } + CTX_DATA_END; + + WM_event_add_notifier(C, NC_LOGIC, NULL); + return OPERATOR_FINISHED; +} +void OBJECT_OT_game_property_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Game Property"; + ot->idname= "OBJECT_OT_game_property_clear"; + + /* api callbacks */ + ot->exec= game_property_clear_exec; + ot->poll= ED_operator_object_active_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/************************ Copy Logic Bricks ***********************/ + +static int logicbricks_copy_exec(bContext *C, wmOperator *op) +{ + Object *ob=ED_object_active_context(C); + + CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { + if(ob != ob_iter) { + if (ob->data != ob_iter->data){ + /* first: free all logic */ + free_sensors(&ob_iter->sensors); + unlink_controllers(&ob_iter->controllers); + free_controllers(&ob_iter->controllers); + unlink_actuators(&ob_iter->actuators); + free_actuators(&ob_iter->actuators); + + /* now copy it, this also works without logicbricks! */ + clear_sca_new_poins_ob(ob); + copy_sensors(&ob_iter->sensors, &ob->sensors); + copy_controllers(&ob_iter->controllers, &ob->controllers); + copy_actuators(&ob_iter->actuators, &ob->actuators); + set_sca_new_poins_ob(ob_iter); + + /* some menu settings */ + ob_iter->scavisflag= ob->scavisflag; + ob_iter->scaflag= ob->scaflag; + + /* set the initial state */ + ob_iter->state= ob->state; + ob_iter->init_state= ob->init_state; + } + if(ob_iter->totcol==ob->totcol) { + ob_iter->actcol= ob->actcol; + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob_iter); + } + } + } + CTX_DATA_END; + + WM_event_add_notifier(C, NC_LOGIC, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_logic_bricks_copy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy Logic Bricks to Selected"; + ot->description = "Copy logic bricks to other selected objects."; + ot->idname= "OBJECT_OT_logic_bricks_copy"; + + /* api callbacks */ + ot->exec= logicbricks_copy_exec; + ot->poll= ED_operator_object_active_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 73ca6e02132..ba609bd9bb3 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -52,6 +52,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "object_intern.h" @@ -224,84 +225,71 @@ void GROUP_OT_create(wmOperatorType *ot) static int group_add_exec(bContext *C, wmOperator *op) { - Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Base *base; Group *group; - int value= RNA_enum_get(op->ptr, "group"); - if(!ob) + if(ob == NULL) return OPERATOR_CANCELLED; - - base= object_in_scene(ob, scene); - if(!base) - return OPERATOR_CANCELLED; - - if(value == -1) - group= add_group( "Group" ); - else - group= BLI_findlink(&bmain->group, value); - if(group) { - add_to_group(group, ob, scene, NULL); /* base will be used if found */ - } + group= add_group("Group"); + add_to_group(group, ob, scene, NULL); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - + return OPERATOR_FINISHED; } -static EnumPropertyItem group_items[]= { - {-1, "ADD_NEW", 0, "Add New Group", ""}, - {0, NULL, 0, NULL, NULL}}; - -static EnumPropertyItem *group_itemf(bContext *C, PointerRNA *ptr, int *free) -{ - Main *bmain= CTX_data_main(C); - Group *group; - EnumPropertyItem tmp = {0, "", 0, "", ""}; - EnumPropertyItem *item= NULL; - int a, totitem= 0; +void OBJECT_OT_group_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add to Group"; + ot->idname= "OBJECT_OT_group_add"; + ot->description = "Add an object to a new group"; - RNA_enum_items_add_value(&item, &totitem, group_items, -1); + /* api callbacks */ + ot->exec= group_add_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} - if (bmain) { - if(bmain->group.first) - RNA_enum_item_add_separator(&item, &totitem); +static int group_link_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); - for(a=0, group=bmain->group.first; group; group=group->id.next, a++) { - tmp.value= a; - tmp.identifier= group->id.name+2; - tmp.name= group->id.name+2; - RNA_enum_item_add(&item, &totitem, &tmp); - } - } + if(ELEM(NULL, ob, group)) + return OPERATOR_CANCELLED; + + add_to_group(group, ob, scene, NULL); - RNA_enum_item_end(&item, &totitem); - *free= 1; + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - return item; + return OPERATOR_FINISHED; } -void OBJECT_OT_group_add(wmOperatorType *ot) +void OBJECT_OT_group_link(wmOperatorType *ot) { PropertyRNA *prop; /* identifiers */ - ot->name= "Add to Group"; - ot->idname= "OBJECT_OT_group_add"; - ot->description = "Add an object to an existing group, or create new"; + ot->name= "Link to Group"; + ot->idname= "OBJECT_OT_group_link"; + ot->description = "Add an object to an existing group"; /* api callbacks */ - ot->exec= group_add_exec; + ot->exec= group_link_exec; + ot->invoke= WM_enum_search_invoke; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "group", group_items, -1, "Group", "Group to add object to."); - RNA_def_enum_funcs(prop, group_itemf); + prop= RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", ""); + RNA_def_enum_funcs(prop, RNA_group_local_itemf); + ot->prop= prop; } static int group_remove_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index 2f2b0987e05..8b171bae34d 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -35,16 +35,11 @@ #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" #include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_view3d_types.h" -#include "DNA_windowmanager_types.h" #include "BKE_action.h" #include "BKE_context.h" @@ -60,17 +55,15 @@ #include "RNA_define.h" #include "RNA_access.h" +#include "RNA_enum_types.h" #include "ED_curve.h" #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 "UI_interface.h" #include "UI_resources.h" #include "object_intern.h" @@ -94,7 +87,7 @@ static int return_editmesh_indexar(BMEditMesh *em, int *tot, int **indexar, floa BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { if(BM_TestHFlag(eve, BM_SELECT)) { *index= nr; index++; - add_v3_v3v3(cent, cent, eve->co); + add_v3_v3(cent, eve->co); } nr++; } @@ -123,7 +116,7 @@ static int return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *name, fl for(i=0; i<dvert->totweight; i++){ if(dvert->dw[i].def_nr == (obedit->actdef-1)) { totvert++; - add_v3_v3v3(cent, cent, eve->co); + add_v3_v3(cent, eve->co); } } } @@ -190,7 +183,7 @@ static int return_editlattice_indexar(Lattice *editlatt, int *tot, int **indexar if(bp->f1 & SELECT) { if(bp->hide==0) { *index= nr; index++; - add_v3_v3v3(cent, cent, bp->vec); + add_v3_v3(cent, bp->vec); } } bp++; @@ -263,17 +256,17 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo while(a--) { if(bezt->f1 & SELECT) { *index= nr; index++; - add_v3_v3v3(cent, cent, bezt->vec[0]); + add_v3_v3(cent, bezt->vec[0]); } nr++; if(bezt->f2 & SELECT) { *index= nr; index++; - add_v3_v3v3(cent, cent, bezt->vec[1]); + add_v3_v3(cent, bezt->vec[1]); } nr++; if(bezt->f3 & SELECT) { *index= nr; index++; - add_v3_v3v3(cent, cent, bezt->vec[2]); + add_v3_v3(cent, bezt->vec[2]); } nr++; bezt++; @@ -285,7 +278,7 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo while(a--) { if(bp->f1 & SELECT) { *index= nr; index++; - add_v3_v3v3(cent, cent, bp->vec); + add_v3_v3(cent, bp->vec); } nr++; bp++; @@ -540,9 +533,6 @@ void OBJECT_OT_hook_add_newobj(wmOperatorType *ot) 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"); @@ -577,7 +567,7 @@ static EnumPropertyItem *hook_mod_itemf(bContext *C, PointerRNA *ptr, int *free) int a, totitem= 0; if(!ob) - return hook_mod_items; + return DummyRNA_NULL_items; for(a=0, md=ob->modifiers.first; md; md= md->next, a++) { if (md->type==eModifierType_Hook) { @@ -613,7 +603,7 @@ void OBJECT_OT_hook_remove(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to remove."); + prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to remove."); RNA_def_enum_funcs(prop, hook_mod_itemf); ot->prop= prop; } @@ -669,7 +659,7 @@ void OBJECT_OT_hook_reset(wmOperatorType *ot) /* identifiers */ ot->name= "Reset Hook"; - ot->description= "Recalculate and and clear offset transformation"; + ot->description= "Recalculate and clear offset transformation"; ot->idname= "OBJECT_OT_hook_reset"; /* callbacks */ @@ -680,7 +670,7 @@ void OBJECT_OT_hook_reset(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to assign to."); + prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to."); RNA_def_enum_funcs(prop, hook_mod_itemf); } @@ -736,7 +726,7 @@ void OBJECT_OT_hook_recenter(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to assign to."); + prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to."); RNA_def_enum_funcs(prop, hook_mod_itemf); } @@ -799,7 +789,7 @@ void OBJECT_OT_hook_assign(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to assign to."); + prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to."); RNA_def_enum_funcs(prop, hook_mod_itemf); } @@ -848,7 +838,7 @@ void OBJECT_OT_hook_select(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "modifier", hook_mod_items, 0, "Modifier", "Modifier number to remove."); + prop= RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to remove."); RNA_def_enum_funcs(prop, hook_mod_itemf); } diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 5331de02560..8bd0da3b43f 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -1,5 +1,5 @@ /** - * $Id: + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -77,12 +77,20 @@ void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot); void OBJECT_OT_posemode_toggle(struct wmOperatorType *ot); void OBJECT_OT_restrictview_set(struct wmOperatorType *ot); void OBJECT_OT_restrictview_clear(struct wmOperatorType *ot); +void OBJECT_OT_restrictrender_set(struct wmOperatorType *ot); +void OBJECT_OT_restrictrender_clear(struct wmOperatorType *ot); void OBJECT_OT_proxy_make(struct wmOperatorType *ot); void OBJECT_OT_shade_smooth(struct wmOperatorType *ot); void OBJECT_OT_shade_flat(struct wmOperatorType *ot); void OBJECT_OT_paths_calculate(struct wmOperatorType *ot); void OBJECT_OT_paths_clear(struct wmOperatorType *ot); +void OBJECT_OT_game_property_new(struct wmOperatorType *ot); +void OBJECT_OT_game_property_remove(struct wmOperatorType *ot); +void OBJECT_OT_game_property_copy(struct wmOperatorType *ot); +void OBJECT_OT_game_property_clear(struct wmOperatorType *ot); +void OBJECT_OT_logic_bricks_copy(struct wmOperatorType *ot); + /* object_select.c */ void OBJECT_OT_select_all(struct wmOperatorType *ot); void OBJECT_OT_select_inverse(struct wmOperatorType *ot); @@ -93,12 +101,11 @@ void OBJECT_OT_select_linked(struct wmOperatorType *ot); void OBJECT_OT_select_grouped(struct wmOperatorType *ot); void OBJECT_OT_select_mirror(struct wmOperatorType *ot); void OBJECT_OT_select_name(struct wmOperatorType *ot); +void OBJECT_OT_select_same_group(struct wmOperatorType *ot); /* object_add.c */ void OBJECT_OT_add(struct wmOperatorType *ot); void OBJECT_OT_add_named(struct wmOperatorType *ot); -void OBJECT_OT_curve_add(struct wmOperatorType *ot); -void OBJECT_OT_surface_add(struct wmOperatorType *ot); void OBJECT_OT_metaball_add(struct wmOperatorType *ot); void OBJECT_OT_text_add(struct wmOperatorType *ot); void OBJECT_OT_armature_add(struct wmOperatorType *ot); @@ -149,8 +156,8 @@ void OBJECT_OT_modifier_copy(struct wmOperatorType *ot); void OBJECT_OT_multires_subdivide(struct wmOperatorType *ot); void OBJECT_OT_multires_reshape(struct wmOperatorType *ot); void OBJECT_OT_multires_higher_levels_delete(struct wmOperatorType *ot); -void OBJECT_OT_multires_save_external(struct wmOperatorType *ot); -void OBJECT_OT_multires_pack_external(struct wmOperatorType *ot); +void OBJECT_OT_multires_external_save(struct wmOperatorType *ot); +void OBJECT_OT_multires_external_pack(struct wmOperatorType *ot); void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot); void OBJECT_OT_explode_refresh(struct wmOperatorType *ot); @@ -160,6 +167,9 @@ void OBJECT_OT_constraint_add_with_targets(struct wmOperatorType *ot); void POSE_OT_constraint_add(struct wmOperatorType *ot); void POSE_OT_constraint_add_with_targets(struct wmOperatorType *ot); +void OBJECT_OT_constraints_copy(struct wmOperatorType *ot); +void POSE_OT_constraints_copy(struct wmOperatorType *ot); + void OBJECT_OT_constraints_clear(struct wmOperatorType *ot); void POSE_OT_constraints_clear(struct wmOperatorType *ot); @@ -195,9 +205,7 @@ void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_sort(struct wmOperatorType *ot); - -void OBJECT_OT_game_property_new(struct wmOperatorType *ot); -void OBJECT_OT_game_property_remove(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_move(struct wmOperatorType *ot); /* object_shapekey.c */ void OBJECT_OT_shape_key_add(struct wmOperatorType *ot); @@ -208,6 +216,7 @@ void OBJECT_OT_shape_key_move(struct wmOperatorType *ot); /* object_group.c */ void OBJECT_OT_group_add(struct wmOperatorType *ot); +void OBJECT_OT_group_link(struct wmOperatorType *ot); void OBJECT_OT_group_remove(struct wmOperatorType *ot); /* object_bake.c */ diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 404335ca1ca..afd4f7a88a7 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -47,7 +47,6 @@ #include "BKE_mesh.h" #include "BKE_utildefines.h" -#include "ED_object.h" #include "ED_screen.h" #include "ED_view3d.h" #include "ED_util.h" @@ -228,7 +227,7 @@ void LATTICE_OT_select_all(wmOperatorType *ot) { /* identifiers */ ot->name= "Select or Deselect All"; - ot->description= "Change selection of all UVW control points"; + ot->description= "Change selection of all UVW control points"; ot->idname= "LATTICE_OT_select_all"; /* api callbacks */ @@ -276,7 +275,7 @@ void LATTICE_OT_make_regular(wmOperatorType *ot) { /* identifiers */ ot->name= "Make Regular"; - ot->description= "Set UVW control points a uniform distance apart"; + ot->description= "Set UVW control points a uniform distance apart"; ot->idname= "LATTICE_OT_make_regular"; /* api callbacks */ @@ -389,8 +388,8 @@ static int validate_undoLatt(void *data, void *edata) Lattice *editlatt= (Lattice *)edata; return (ult->pntsu == editlatt->pntsu && - ult->pntsv == editlatt->pntsv && - ult->pntsw == editlatt->pntsw); + ult->pntsv == editlatt->pntsv && + ult->pntsw == editlatt->pntsw); } static void *get_editlatt(bContext *C) diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 36475eaeaa1..8792803bf0c 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -31,13 +31,10 @@ #include "MEM_guardedalloc.h" -#include "DNA_action_types.h" #include "DNA_curve_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" -#include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_scene_types.h" @@ -178,13 +175,13 @@ int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, Mod if(ob->pd) ob->pd->deflect= 0; - DAG_scene_sort(scene); + DAG_scene_sort(scene); } else if(md->type == eModifierType_Surface) { if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE) ob->pd->shape = PFIELD_SHAPE_PLANE; - DAG_scene_sort(scene); + DAG_scene_sort(scene); } else if(md->type == eModifierType_Smoke) { ob->dt = OB_TEXTURE; @@ -403,50 +400,65 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) { + ModifierTypeInfo *mti= modifierType_getInfo(md->type); + + if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md, 0))) { + BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); + return 0; + } + if (ob->type==OB_MESH) { DerivedMesh *dm; Mesh *me = ob->data; + MultiresModifierData *mmd= find_multires_modifier_before(scene, md); + if( me->key) { BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys"); return 0; } - + mesh_pmv_off(ob, me); - + /* Multires: ensure that recent sculpting is applied */ if(md->type == eModifierType_Multires) multires_force_update(ob); - - dm = mesh_create_derived_for_modifier(scene, ob, md); - if (!dm) { - BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply"); - return 0; + + if (mmd && mmd->totlvl && mti->type==eModifierTypeType_OnlyDeform) { + if(!multiresModifier_reshapeFromDeformMod (scene, mmd, ob, md)) { + BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply"); + return 0; + } + } else { + dm = mesh_create_derived_for_modifier(scene, ob, md); + if (!dm) { + BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply"); + return 0; + } + + DM_to_mesh(dm, me); + + dm->release(dm); } - - DM_to_mesh(dm, me); - - dm->release(dm); } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); - Curve *cu = ob->data; + Curve *cu; int numVerts; float (*vertexCos)[3]; - - - BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices"); - - if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md, 0))) { - BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); + + if (mti->type==eModifierTypeType_Constructive) { + BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve"); return 0; } - + + cu = ob->data; + BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices"); + vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts); mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0); curve_applyVertexCos(cu, &cu->nurb, vertexCos); MEM_freeN(vertexCos); - + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { @@ -495,20 +507,12 @@ int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md) return 1; } -/***************************** OPERATORS ****************************/ - -static int modifier_poll(bContext *C) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); - return (ptr.data != NULL && !((ID*)ptr.id.data)->lib); -} - /************************ add modifier operator *********************/ static int modifier_add_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); + Object *ob = ED_object_active_context(C); int type= RNA_enum_get(op->ptr, "type"); if(!ED_object_modifier_add(op->reports, scene, ob, NULL, type)) @@ -521,7 +525,7 @@ static int modifier_add_exec(bContext *C, wmOperator *op) static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *ptr, int *free) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_active_context(C); EnumPropertyItem *item= NULL, *md_item; ModifierTypeInfo *mti; int totitem= 0, a; @@ -575,16 +579,69 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot) ot->prop= prop; } +/************************ generic functions for operators using mod names and data context *********************/ + +static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type); + Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C); + + if (!ob || ob->id.lib) return 0; + if (ptr.data && ((ID*)ptr.id.data)->lib) return 0; + + return 1; +} + +static int edit_modifier_poll(bContext *C) +{ + return edit_modifier_poll_generic(C, &RNA_Modifier); +} + +static void edit_modifier_properties(wmOperatorType *ot) +{ + RNA_def_string(ot->srna, "modifier", "", 32, "Modifier", "Name of the modifier to edit"); +} + +static int edit_modifier_invoke_properties(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); + ModifierData *md; + + if (RNA_property_is_set(op->ptr, "modifier")) + return 1; + + if (ptr.data) { + md = ptr.data; + RNA_string_set(op->ptr, "modifier", md->name); + return 1; + } + + return 0; +} + +static ModifierData *edit_modifier_property_get(bContext *C, wmOperator *op, Object *ob, int type) +{ + char modifier_name[32]; + ModifierData *md; + RNA_string_get(op->ptr, "modifier", modifier_name); + + md = modifiers_findByName(ob, modifier_name); + + if (md && type != 0 && md->type != type) + md = NULL; + + return md; +} + /************************ remove modifier operator *********************/ static int modifier_remove_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); - Object *ob= ptr.id.data; - ModifierData *md= ptr.data; - - if(!ED_object_modifier_remove(op->reports, scene, ob, md)) + Object *ob = ED_object_active_context(C); + ModifierData *md = edit_modifier_property_get(C, op, ob, 0); + + if(!ob || !md || !ED_object_modifier_remove(op->reports, scene, ob, md)) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); @@ -592,28 +649,37 @@ static int modifier_remove_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return modifier_remove_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void OBJECT_OT_modifier_remove(wmOperatorType *ot) { ot->name= "Remove Modifier"; ot->description= "Remove a modifier from the active object"; ot->idname= "OBJECT_OT_modifier_remove"; + ot->invoke= modifier_remove_invoke; ot->exec= modifier_remove_exec; - ot->poll= modifier_poll; + ot->poll= edit_modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } /************************ move up modifier operator *********************/ static int modifier_move_up_exec(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); - Object *ob= ptr.id.data; - ModifierData *md= ptr.data; + Object *ob = ED_object_active_context(C); + ModifierData *md = edit_modifier_property_get(C, op, ob, 0); - if(!ED_object_modifier_move_up(op->reports, ob, md)) + if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md)) return OPERATOR_CANCELLED; DAG_id_flush_update(&ob->id, OB_RECALC_DATA); @@ -622,26 +688,35 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return modifier_move_up_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void OBJECT_OT_modifier_move_up(wmOperatorType *ot) { ot->name= "Move Up Modifier"; ot->description= "Move modifier up in the stack"; ot->idname= "OBJECT_OT_modifier_move_up"; + ot->invoke= modifier_move_up_invoke; ot->exec= modifier_move_up_exec; - ot->poll= modifier_poll; + ot->poll= edit_modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } /************************ move down modifier operator *********************/ static int modifier_move_down_exec(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); - Object *ob= ptr.id.data; - ModifierData *md= ptr.data; + Object *ob = ED_object_active_context(C); + ModifierData *md = edit_modifier_property_get(C, op, ob, 0); if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md)) return OPERATOR_CANCELLED; @@ -652,17 +727,27 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return modifier_move_down_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void OBJECT_OT_modifier_move_down(wmOperatorType *ot) { ot->name= "Move Down Modifier"; ot->description= "Move modifier down in the stack"; ot->idname= "OBJECT_OT_modifier_move_down"; + ot->invoke= modifier_move_down_invoke; ot->exec= modifier_move_down_exec; - ot->poll= modifier_poll; + ot->poll= edit_modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } /************************ apply modifier operator *********************/ @@ -670,13 +755,13 @@ void OBJECT_OT_modifier_move_down(wmOperatorType *ot) static int modifier_apply_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); - Object *ob= ptr.id.data; - ModifierData *md= ptr.data; + Object *ob = ED_object_active_context(C); + ModifierData *md = edit_modifier_property_get(C, op, ob, 0); int apply_as= RNA_enum_get(op->ptr, "apply_as"); - - if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) + + if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) { return OPERATOR_CANCELLED; + } DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); @@ -684,6 +769,14 @@ static int modifier_apply_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return modifier_apply_exec(C, op); + else + return OPERATOR_CANCELLED; +} + static EnumPropertyItem modifier_apply_as_items[] = { {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"}, {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"}, @@ -695,14 +788,15 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot) ot->description= "Apply modifier and remove from the stack"; ot->idname= "OBJECT_OT_modifier_apply"; - //ot->invoke= WM_menu_invoke; + ot->invoke= modifier_apply_invoke; ot->exec= modifier_apply_exec; - ot->poll= modifier_poll; + ot->poll= edit_modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry"); + edit_modifier_properties(ot); } /************************ convert modifier operator *********************/ @@ -710,10 +804,9 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot) static int modifier_convert_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); - Object *ob= ptr.id.data; - ModifierData *md= ptr.data; - + Object *ob = ED_object_active_context(C); + ModifierData *md = edit_modifier_property_get(C, op, ob, 0); + if(!ob || !md || !ED_object_modifier_convert(op->reports, scene, ob, md)) return OPERATOR_CANCELLED; @@ -723,26 +816,35 @@ static int modifier_convert_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return modifier_convert_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void OBJECT_OT_modifier_convert(wmOperatorType *ot) { ot->name= "Convert Modifier"; ot->description= "Convert particles to a mesh object"; ot->idname= "OBJECT_OT_modifier_convert"; + ot->invoke= modifier_convert_invoke; ot->exec= modifier_convert_exec; - ot->poll= modifier_poll; + ot->poll= edit_modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } /************************ copy modifier operator *********************/ static int modifier_copy_exec(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); - Object *ob= ptr.id.data; - ModifierData *md= ptr.data; + Object *ob = ED_object_active_context(C); + ModifierData *md = edit_modifier_property_get(C, op, ob, 0); if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md)) return OPERATOR_CANCELLED; @@ -753,62 +855,83 @@ static int modifier_copy_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return modifier_copy_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void OBJECT_OT_modifier_copy(wmOperatorType *ot) { ot->name= "Copy Modifier"; ot->description= "Duplicate modifier at the same position in the stack"; ot->idname= "OBJECT_OT_modifier_copy"; + ot->invoke= modifier_copy_invoke; ot->exec= modifier_copy_exec; - ot->poll= modifier_poll; + ot->poll= edit_modifier_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } /************* multires delete higher levels operator ****************/ static int multires_poll(bContext *C) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); - ID *id= ptr.id.data; - return (ptr.data && id && !id->lib); + return edit_modifier_poll_generic(C, &RNA_MultiresModifier); } static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); - Object *ob= ptr.id.data; - MultiresModifierData *mmd= ptr.data; - - if(mmd) { - multiresModifier_del_levels(mmd, ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - } + Object *ob = ED_object_active_context(C); + MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Multires); + + if (!mmd) + return OPERATOR_CANCELLED; + + multiresModifier_del_levels(mmd, ob, 1); + + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; } +static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return multires_higher_levels_delete_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot) { ot->name= "Delete Higher Levels"; ot->idname= "OBJECT_OT_multires_higher_levels_delete"; ot->poll= multires_poll; + ot->invoke= multires_higher_levels_delete_invoke; ot->exec= multires_higher_levels_delete_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } /****************** multires subdivide operator *********************/ static int multires_subdivide_exec(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); - Object *ob= ptr.id.data; - MultiresModifierData *mmd= ptr.data; - + Object *ob = ED_object_active_context(C); + MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Multires); + + if (!mmd) + return OPERATOR_CANCELLED; + multiresModifier_subdivide(mmd, ob, 0, mmd->simple); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); @@ -817,6 +940,14 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return multires_subdivide_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void OBJECT_OT_multires_subdivide(wmOperatorType *ot) { ot->name= "Multires Subdivide"; @@ -824,25 +955,25 @@ void OBJECT_OT_multires_subdivide(wmOperatorType *ot) ot->idname= "OBJECT_OT_multires_subdivide"; ot->poll= multires_poll; + ot->invoke= multires_subdivide_invoke; ot->exec= multires_subdivide_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } /****************** multires reshape operator *********************/ static int multires_reshape_exec(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); - Object *ob= ptr.id.data, *secondob= NULL; - MultiresModifierData *mmd= ptr.data; + Object *ob= ED_object_active_context(C), *secondob= NULL; + Scene *scene= CTX_data_scene(C); + MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Multires); - if(ob->derivedFinal == NULL || ob->derivedFinal->type != DM_TYPE_CCGDM) { - BKE_report(op->reports, RPT_ERROR, "Active objects multires is disabled, can't reshape multires data."); + if (!mmd) return OPERATOR_CANCELLED; - } - + CTX_DATA_BEGIN(C, Object*, selob, selected_editable_objects) { if(selob->type == OB_MESH && selob != ob) { secondob= selob; @@ -855,18 +986,26 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from."); return OPERATOR_CANCELLED; } - - if(!multiresModifier_reshape(mmd, ob, secondob)) { + + if(!multiresModifier_reshape(scene, mmd, ob, secondob)) { BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices."); return OPERATOR_CANCELLED; } DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - + return OPERATOR_FINISHED; } +static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return multires_reshape_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void OBJECT_OT_multires_reshape(wmOperatorType *ot) { ot->name= "Multires Reshape"; @@ -874,27 +1013,33 @@ void OBJECT_OT_multires_reshape(wmOperatorType *ot) ot->idname= "OBJECT_OT_multires_reshape"; ot->poll= multires_poll; + ot->invoke= multires_reshape_invoke; ot->exec= multires_reshape_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } /****************** multires save external operator *********************/ -static int multires_save_external_exec(bContext *C, wmOperator *op) +static int multires_external_save_exec(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); - Object *ob= ptr.id.data; + Object *ob = ED_object_active_context(C); Mesh *me= (ob)? ob->data: op->customdata; char path[FILE_MAX]; + int relative= RNA_boolean_get(op->ptr, "relative_path"); + + if(!me) + return OPERATOR_CANCELLED; if(CustomData_external_test(&me->fdata, CD_MDISPS)) return OPERATOR_CANCELLED; - RNA_string_get(op->ptr, "path", path); - if(G.save_over) - BLI_makestringcode(G.sce, path); /* make relative */ + RNA_string_get(op->ptr, "filepath", path); + + if(relative) + BLI_path_rel(path, G.sce); CustomData_external_add(&me->fdata, &me->id, CD_MDISPS, me->totface, path); CustomData_external_write(&me->fdata, &me->id, CD_MASK_MESH, me->totface, 0); @@ -902,51 +1047,63 @@ static int multires_save_external_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int multires_save_external_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *event) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); - Object *ob= ptr.id.data; + Object *ob = ED_object_active_context(C); + MultiresModifierData *mmd; Mesh *me= ob->data; char path[FILE_MAX]; + if (!edit_modifier_invoke_properties(C, op)) + return OPERATOR_CANCELLED; + + mmd = (MultiresModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Multires); + + if (!mmd) + return OPERATOR_CANCELLED; + if(CustomData_external_test(&me->fdata, CD_MDISPS)) return OPERATOR_CANCELLED; - if(RNA_property_is_set(op->ptr, "path")) - return multires_save_external_exec(C, op); + if(!RNA_property_is_set(op->ptr, "relative_path")) + RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS); + + if(RNA_property_is_set(op->ptr, "filepath")) + return multires_external_save_exec(C, op); op->customdata= me; BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name+2); - RNA_string_set(op->ptr, "path", path); + RNA_string_set(op->ptr, "filepath", path); WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; } -void OBJECT_OT_multires_save_external(wmOperatorType *ot) +void OBJECT_OT_multires_external_save(wmOperatorType *ot) { ot->name= "Multires Save External"; ot->description= "Save displacements to an external file"; - ot->idname= "OBJECT_OT_multires_save_external"; + ot->idname= "OBJECT_OT_multires_external_save"; + // XXX modifier no longer in context after file browser .. ot->poll= multires_poll; + ot->exec= multires_external_save_exec; + ot->invoke= multires_external_save_invoke; ot->poll= multires_poll; - ot->exec= multires_save_external_exec; - ot->invoke= multires_save_external_invoke; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE); + WM_operator_properties_filesel(ot, FOLDERFILE|BTXFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); + edit_modifier_properties(ot); } /****************** multires pack operator *********************/ -static int multires_pack_external_exec(bContext *C, wmOperator *op) +static int multires_external_pack_exec(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); - Object *ob= ptr.id.data; + Object *ob = ED_object_active_context(C); Mesh *me= ob->data; if(!CustomData_external_test(&me->fdata, CD_MDISPS)) @@ -958,14 +1115,14 @@ static int multires_pack_external_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void OBJECT_OT_multires_pack_external(wmOperatorType *ot) +void OBJECT_OT_multires_external_pack(wmOperatorType *ot) { ot->name= "Multires Pack External"; ot->description= "Pack displacements from an external file"; - ot->idname= "OBJECT_OT_multires_pack_external"; + ot->idname= "OBJECT_OT_multires_external_pack"; ot->poll= multires_poll; - ot->exec= multires_pack_external_exec; + ot->exec= multires_external_pack_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -975,32 +1132,35 @@ void OBJECT_OT_multires_pack_external(wmOperatorType *ot) static int meshdeform_poll(bContext *C) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MeshDeformModifier); - ID *id= ptr.id.data; - return (ptr.data && id && !id->lib); + return edit_modifier_poll_generic(C, &RNA_MeshDeformModifier); } static int meshdeform_bind_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - PointerRNA ptr= CTX_data_pointer_get(C, "modifier"); - Object *ob= ptr.id.data; - MeshDeformModifierData *mmd= ptr.data; + Object *ob = ED_object_active_context(C); + MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_MeshDeform); + + if (!mmd) + return OPERATOR_CANCELLED; - if(mmd->bindcos) { + if(mmd->bindcagecos) { if(mmd->bindweights) MEM_freeN(mmd->bindweights); - if(mmd->bindcos) MEM_freeN(mmd->bindcos); + if(mmd->bindcagecos) MEM_freeN(mmd->bindcagecos); if(mmd->dyngrid) MEM_freeN(mmd->dyngrid); if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences); if(mmd->dynverts) MEM_freeN(mmd->dynverts); mmd->bindweights= NULL; - mmd->bindcos= NULL; + mmd->bindcagecos= NULL; mmd->dyngrid= NULL; mmd->dyninfluences= NULL; mmd->dynverts= NULL; mmd->totvert= 0; mmd->totcagevert= 0; mmd->totinfluence= 0; + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); } else { DerivedMesh *dm; @@ -1031,6 +1191,14 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return meshdeform_bind_exec(C, op); + else + return OPERATOR_CANCELLED; +} + void OBJECT_OT_meshdeform_bind(wmOperatorType *ot) { /* identifiers */ @@ -1040,26 +1208,28 @@ void OBJECT_OT_meshdeform_bind(wmOperatorType *ot) /* api callbacks */ ot->poll= meshdeform_poll; + ot->invoke= meshdeform_bind_invoke; ot->exec= meshdeform_bind_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } /****************** explode refresh operator *********************/ -static int explode_refresh_poll(bContext *C) +static int explode_poll(bContext *C) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier); - ID *id= ptr.id.data; - return (ptr.data && id && !id->lib); + return edit_modifier_poll_generic(C, &RNA_ExplodeModifier); } static int explode_refresh_exec(bContext *C, wmOperator *op) { - PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier); - Object *ob= ptr.id.data; - ExplodeModifierData *emd= ptr.data; + Object *ob = ED_object_active_context(C); + ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Explode); + + if (!emd) + return OPERATOR_CANCELLED; emd->flag |= eExplodeFlag_CalcFaces; @@ -1069,16 +1239,27 @@ static int explode_refresh_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (edit_modifier_invoke_properties(C, op)) + return explode_refresh_exec(C, op); + else + return OPERATOR_CANCELLED; +} + + void OBJECT_OT_explode_refresh(wmOperatorType *ot) { ot->name= "Explode Refresh"; ot->description= "Refresh data in the Explode modifier"; ot->idname= "OBJECT_OT_explode_refresh"; + ot->poll= explode_poll; + ot->invoke= explode_refresh_invoke; ot->exec= explode_refresh_exec; - ot->poll= explode_refresh_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + edit_modifier_properties(ot); } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index ab50bd4c37c..ba706a0d4b9 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -1,5 +1,5 @@ /** - * $Id: + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -33,11 +33,6 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" -#include "DNA_userdef_types.h" -#include "DNA_view3d_types.h" -#include "DNA_windowmanager_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -79,6 +74,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_proxy_make); WM_operatortype_append(OBJECT_OT_restrictview_clear); WM_operatortype_append(OBJECT_OT_restrictview_set); + WM_operatortype_append(OBJECT_OT_restrictrender_clear); + WM_operatortype_append(OBJECT_OT_restrictrender_set); WM_operatortype_append(OBJECT_OT_shade_smooth); WM_operatortype_append(OBJECT_OT_shade_flat); WM_operatortype_append(OBJECT_OT_paths_calculate); @@ -101,6 +98,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_select_inverse); WM_operatortype_append(OBJECT_OT_select_random); WM_operatortype_append(OBJECT_OT_select_all); + WM_operatortype_append(OBJECT_OT_select_same_group); WM_operatortype_append(OBJECT_OT_select_by_type); WM_operatortype_append(OBJECT_OT_select_by_layer); WM_operatortype_append(OBJECT_OT_select_linked); @@ -114,9 +112,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(GROUP_OT_objects_remove_active); WM_operatortype_append(OBJECT_OT_delete); - WM_operatortype_append(OBJECT_OT_curve_add); WM_operatortype_append(OBJECT_OT_text_add); - WM_operatortype_append(OBJECT_OT_surface_add); WM_operatortype_append(OBJECT_OT_armature_add); WM_operatortype_append(OBJECT_OT_lamp_add); WM_operatortype_append(OBJECT_OT_camera_add); @@ -141,8 +137,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_multires_subdivide); WM_operatortype_append(OBJECT_OT_multires_reshape); WM_operatortype_append(OBJECT_OT_multires_higher_levels_delete); - WM_operatortype_append(OBJECT_OT_multires_save_external); - WM_operatortype_append(OBJECT_OT_multires_pack_external); + WM_operatortype_append(OBJECT_OT_multires_external_save); + WM_operatortype_append(OBJECT_OT_multires_external_pack); WM_operatortype_append(OBJECT_OT_meshdeform_bind); WM_operatortype_append(OBJECT_OT_explode_refresh); @@ -150,6 +146,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_constraint_add_with_targets); WM_operatortype_append(POSE_OT_constraint_add); WM_operatortype_append(POSE_OT_constraint_add_with_targets); + WM_operatortype_append(OBJECT_OT_constraints_copy); + WM_operatortype_append(POSE_OT_constraints_copy); WM_operatortype_append(OBJECT_OT_constraints_clear); WM_operatortype_append(POSE_OT_constraints_clear); WM_operatortype_append(POSE_OT_ik_add); @@ -180,9 +178,13 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_mirror); WM_operatortype_append(OBJECT_OT_vertex_group_set_active); WM_operatortype_append(OBJECT_OT_vertex_group_sort); + WM_operatortype_append(OBJECT_OT_vertex_group_move); WM_operatortype_append(OBJECT_OT_game_property_new); WM_operatortype_append(OBJECT_OT_game_property_remove); + WM_operatortype_append(OBJECT_OT_game_property_copy); + WM_operatortype_append(OBJECT_OT_game_property_clear); + WM_operatortype_append(OBJECT_OT_logic_bricks_copy); WM_operatortype_append(OBJECT_OT_shape_key_add); WM_operatortype_append(OBJECT_OT_shape_key_remove); @@ -194,6 +196,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(LATTICE_OT_make_regular); WM_operatortype_append(OBJECT_OT_group_add); + WM_operatortype_append(OBJECT_OT_group_link); WM_operatortype_append(OBJECT_OT_group_remove); WM_operatortype_append(OBJECT_OT_hook_add_selobj); @@ -279,7 +282,7 @@ void ED_keymap_object(wmKeyConfig *keyconf) keymap->poll= object_mode_poll; /* object mode supports PET now */ - ED_object_generic_keymap(keyconf, keymap, TRUE); + ED_object_generic_keymap(keyconf, keymap, 1); WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0); @@ -319,10 +322,16 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, 0, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + /* same as above but for rendering */ + WM_keymap_add_item(keymap, "OBJECT_OT_restrictrender_clear", HKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); + WM_keymap_add_item(keymap, "OBJECT_OT_restrictrender_set", HKEY, KM_PRESS, KM_CTRL, 0); +// RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_restrictrender_set", HKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "unselected", 1); // conflicts, removing + WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "OBJECT_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0); WM_keymap_add_menu(keymap, "INFO_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_duplicates_make_real", AKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); @@ -342,6 +351,7 @@ void ED_keymap_object(wmKeyConfig *keyconf) // XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith WM_keymap_verify_item(keymap, "ANIM_OT_keyframe_insert_menu", IKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "ANIM_OT_keyframe_delete_v3d", IKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_verify_item(keymap, "ANIM_OT_keying_set_active_set", IKEY, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0); WM_keymap_verify_item(keymap, "GROUP_OT_create", GKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove", GKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); @@ -366,7 +376,7 @@ void ED_keymap_object(wmKeyConfig *keyconf) /* menus */ WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0); - ED_object_generic_keymap(keyconf, keymap, TRUE); + ED_object_generic_keymap(keyconf, keymap, 1); } void ED_object_generic_keymap(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int do_pet) @@ -374,20 +384,23 @@ void ED_object_generic_keymap(struct wmKeyConfig *keyconf, struct wmKeyMap *keym wmKeyMapItem *kmi; /* used by mesh, curve & lattice only */ - if(do_pet) { + if(do_pet > 0) { /* context ops */ kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_enum", OKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "path", "tool_settings.proportional_editing_falloff"); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.proportional_editing_falloff"); kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", OKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "path", "tool_settings.proportional_editing"); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.proportional_editing"); RNA_string_set(kmi->ptr, "value_1", "DISABLED"); RNA_string_set(kmi->ptr, "value_2", "ENABLED"); - kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", OKEY, KM_PRESS, KM_ALT, 0); - RNA_string_set(kmi->ptr, "path", "tool_settings.proportional_editing"); - RNA_string_set(kmi->ptr, "value_1", "DISABLED"); - RNA_string_set(kmi->ptr, "value_2", "CONNECTED"); + /* for modes/object types that allow 'conencted' mode, add the Alt O key */ + if (do_pet > 1) { + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", OKEY, KM_PRESS, KM_ALT, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.proportional_editing"); + RNA_string_set(kmi->ptr, "value_1", "DISABLED"); + RNA_string_set(kmi->ptr, "value_2", "CONNECTED"); + } } } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 3233954748a..cc9df09dc38 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -32,20 +32,14 @@ #include "MEM_guardedalloc.h" #include "DNA_anim_types.h" -#include "DNA_armature_types.h" -#include "DNA_camera_types.h" #include "DNA_constraint_types.h" -#include "DNA_curve_types.h" #include "DNA_group_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" #include "DNA_material_types.h" -#include "DNA_mesh_types.h" #include "DNA_meta_types.h" -#include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_scene_types.h" -#include "DNA_view3d_types.h" #include "DNA_world_types.h" #include "BLI_math.h" @@ -87,7 +81,6 @@ #include "RNA_define.h" #include "RNA_enum_types.h" -#include "ED_anim_api.h" #include "ED_armature.h" #include "ED_curve.h" #include "ED_object.h" @@ -197,7 +190,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if(ob != obedit) { - ob->recalc |= OB_RECALC; + ob->recalc |= OB_RECALC_ALL; par= obedit->parent; while(par) { @@ -283,7 +276,7 @@ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) PointerRNA props_ptr; /* create operator menu item with relevant properties filled in */ - props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); + props_ptr= uiItemFullO(layout, op->idname, op->type->name, 0, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); /* present the menu and be done... */ uiPupMenuEnd(C, pup); @@ -343,7 +336,7 @@ static int make_proxy_exec (bContext *C, wmOperator *op) /* depsgraph flushes are needed for the new data */ DAG_scene_sort(scene); - DAG_id_flush_update(&newob->id, OB_RECALC); + DAG_id_flush_update(&newob->id, OB_RECALC_ALL); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, newob); } else { @@ -409,7 +402,7 @@ void OBJECT_OT_proxy_make (wmOperatorType *ot) static EnumPropertyItem prop_clear_parent_types[] = { {0, "CLEAR", 0, "Clear Parent", ""}, - {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation (Clear Track)", ""}, + {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, {0, NULL, 0, NULL, NULL} }; @@ -426,13 +419,12 @@ static int parent_clear_exec(bContext *C, wmOperator *op) } else if(type == 1) { ob->parent= NULL; - ob->track= NULL; - ED_object_apply_obmat(ob); + object_apply_mat4(ob, ob->obmat); } else if(type == 2) unit_m4(ob->parentinv); - ob->recalc |= OB_RECALC; + ob->recalc |= OB_RECALC_ALL; } CTX_DATA_END; @@ -569,7 +561,7 @@ static int parent_set_exec(bContext *C, wmOperator *op) Object workob; /* apply transformation of previous parenting */ - ED_object_apply_obmat(ob); + object_apply_mat4(ob, ob->obmat); /* set the parent (except for follow-path constraint option) */ if(partype != PAR_PATH_CONST) @@ -676,23 +668,23 @@ static int parent_set_invoke(bContext *C, wmOperator *op, wmEvent *event) uiLayout *layout= uiPupMenuLayout(pup); uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_OBJECT); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_OBJECT); /* ob becomes parent, make the associated menus */ if(ob->type==OB_ARMATURE) { - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE_NAME); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE_ENVELOPE); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE_AUTO); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_BONE); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE_NAME); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE_ENVELOPE); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_ARMATURE_AUTO); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_BONE); } else if(ob->type==OB_CURVE) { - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_CURVE); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_FOLLOW); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_PATH_CONST); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_CURVE); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_FOLLOW); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_PATH_CONST); } else if(ob->type == OB_LATTICE) { - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_LATTICE); + uiItemEnumO(layout, "OBJECT_OT_parent_set", NULL, 0, "type", PAR_LATTICE); } uiPupMenuEnd(C, pup); @@ -874,7 +866,7 @@ static int object_track_clear_exec(bContext *C, wmOperator *op) /* remove track-object for old track */ ob->track= NULL; - ob->recalc |= OB_RECALC; + ob->recalc |= OB_RECALC_ALL; /* also remove all tracking constraints */ for (con= ob->constraints.last; con; con= pcon) { @@ -884,7 +876,7 @@ static int object_track_clear_exec(bContext *C, wmOperator *op) } if(type == 1) - ED_object_apply_obmat(ob); + object_apply_mat4(ob, ob->obmat); } CTX_DATA_END; @@ -920,7 +912,6 @@ static EnumPropertyItem prop_make_track_types[] = { {1, "DAMPTRACK", 0, "Damped Track Constraint", ""}, {2, "TRACKTO", 0, "Track To Constraint", ""}, {3, "LOCKTRACK", 0, "Lock Track Constraint", ""}, - {4, "OLDTRACK", 0, "Old Track", ""}, {0, NULL, 0, NULL, NULL} }; @@ -941,7 +932,7 @@ static int track_set_exec(bContext *C, wmOperator *op) data = con->data; data->tar = obact; - ob->recalc |= OB_RECALC; + ob->recalc |= OB_RECALC_ALL; /* Lamp and Camera track differently by default */ if (ob->type == OB_LAMP || ob->type == OB_CAMERA) @@ -960,7 +951,7 @@ static int track_set_exec(bContext *C, wmOperator *op) data = con->data; data->tar = obact; - ob->recalc |= OB_RECALC; + ob->recalc |= OB_RECALC_ALL; /* Lamp and Camera track differently by default */ if (ob->type == OB_LAMP || ob->type == OB_CAMERA) { @@ -981,7 +972,7 @@ static int track_set_exec(bContext *C, wmOperator *op) data = con->data; data->tar = obact; - ob->recalc |= OB_RECALC; + ob->recalc |= OB_RECALC_ALL; /* Lamp and Camera track differently by default */ if (ob->type == OB_LAMP || ob->type == OB_CAMERA) { @@ -992,15 +983,6 @@ static int track_set_exec(bContext *C, wmOperator *op) } CTX_DATA_END; } - else { - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(ob!=obact) { - ob->track= obact; - ob->recalc |= OB_RECALC; - } - } - CTX_DATA_END; - } DAG_scene_sort(scene); DAG_ids_flush_update(0); @@ -1161,7 +1143,7 @@ void link_to_scene(unsigned short nr) static int make_links_scene_exec(bContext *C, wmOperator *op) { - Scene *scene_to= BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "type")); + Scene *scene_to= BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene")); if(scene_to==NULL) { BKE_report(op->reports, RPT_ERROR, "Scene not found"); @@ -1203,6 +1185,30 @@ enum { MAKE_LINKS_MODIFIERS }; +/* Return 1 if make link data is allow, zero otherwise */ +static int allow_make_links_data(int ev, Object *ob, Object *obt) +{ + switch(ev) { + case MAKE_LINKS_OBDATA: + if (ob->type == obt->type && ob->type != OB_EMPTY) + return 1; + break; + case MAKE_LINKS_MATERIALS: + if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_MBALL) && + ELEM5(obt->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_MBALL)) + return 1; + break; + case MAKE_LINKS_ANIMDATA: + case MAKE_LINKS_DUPLIGROUP: + return 1; + case MAKE_LINKS_MODIFIERS: + if (ob->type != OB_EMPTY && obt->type != OB_EMPTY) + return 1; + break; + } + return 0; +} + static int make_links_data_exec(bContext *C, wmOperator *op) { int event = RNA_int_get(op->ptr, "type"); @@ -1214,43 +1220,44 @@ static int make_links_data_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN(C, Object*, obt, selected_editable_objects) { if(ob != obt) { - switch(event) { - case MAKE_LINKS_OBDATA: /* obdata */ - id= obt->data; - id->us--; + if (allow_make_links_data(event, ob, obt)) { + switch(event) { + case MAKE_LINKS_OBDATA: /* obdata */ + id= obt->data; + id->us--; - id= ob->data; - id_us_plus(id); - obt->data= id; + id= ob->data; + id_us_plus(id); + obt->data= id; - /* if amount of material indices changed: */ - test_object_materials(obt->data); + /* if amount of material indices changed: */ + test_object_materials(obt->data); - obt->recalc |= OB_RECALC_DATA; - break; - case MAKE_LINKS_MATERIALS: - /* new approach, using functions from kernel */ - for(a=0; a<ob->totcol; a++) { - Material *ma= give_current_material(ob, a+1); - assign_material(obt, ma, a+1); /* also works with ma==NULL */ - } - break; - case MAKE_LINKS_ANIMDATA: - BKE_copy_animdata_id((ID *)obt, (ID *)ob); - BKE_copy_animdata_id((ID *)obt->data, (ID *)ob->data); - break; - case MAKE_LINKS_DUPLIGROUP: - if(ob->dup_group) ob->dup_group->id.us--; + obt->recalc |= OB_RECALC_DATA; + break; + case MAKE_LINKS_MATERIALS: + /* new approach, using functions from kernel */ + for(a=0; a<ob->totcol; a++) { + Material *ma= give_current_material(ob, a+1); + assign_material(obt, ma, a+1); /* also works with ma==NULL */ + } + break; + case MAKE_LINKS_ANIMDATA: + BKE_copy_animdata_id((ID *)obt, (ID *)ob); + BKE_copy_animdata_id((ID *)obt->data, (ID *)ob->data); + break; + case MAKE_LINKS_DUPLIGROUP: obt->dup_group= ob->dup_group; if(obt->dup_group) { - id_us_plus((ID *)obt->dup_group); + id_lib_extern(&obt->dup_group->id); obt->transflag |= OB_DUPLIGROUP; } - break; - case MAKE_LINKS_MODIFIERS: - object_link_modifiers(obt, ob); - obt->recalc |= OB_RECALC; - break; + break; + case MAKE_LINKS_MODIFIERS: + object_link_modifiers(obt, ob); + obt->recalc |= OB_RECALC_ALL; + break; + } } } } @@ -1279,8 +1286,9 @@ void OBJECT_OT_make_links_scene(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", ""); - RNA_def_enum_funcs(prop, RNA_scene_itemf); + prop= RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", ""); + RNA_def_enum_funcs(prop, RNA_scene_local_itemf); + ot->prop= prop; } void OBJECT_OT_make_links_data(wmOperatorType *ot) @@ -1357,7 +1365,6 @@ void single_object_users(Scene *scene, View3D *v3d, int flag) modifiers_foreachObjectLink(base->object, single_object_users__forwardModifierLinks, NULL); ID_NEW(ob->parent); - ID_NEW(ob->track); } } @@ -1678,13 +1685,13 @@ static void single_mat_users_expand(void) /* used for copying scenes */ void ED_object_single_users(Scene *scene, int full) { - single_object_users(scene, NULL, 0); + single_object_users(scene, NULL, 0); - if(full) { - single_obdata_users(scene, 0); - single_mat_users_expand(); - single_tex_users_expand(); - } + if(full) { + single_obdata_users(scene, 0); + single_mat_users_expand(); + single_tex_users_expand(); + } clear_id_newpoins(); } @@ -1726,22 +1733,21 @@ static int make_local_exec(bContext *C, wmOperator *op) clear_id_newpoins(); - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { if(ob->id.lib) id_make_local(&ob->id, 0); } CTX_DATA_END; /* maybe object pointers */ - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { if(ob->id.lib==NULL) { ID_NEW(ob->parent); - ID_NEW(ob->track); } } CTX_DATA_END; - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { id= ob->data; if(id && mode>1) { @@ -1759,7 +1765,7 @@ static int make_local_exec(bContext *C, wmOperator *op) CTX_DATA_END; if(mode>1) { - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { if(ob->type==OB_LAMP) { la= ob->data; @@ -1824,7 +1830,7 @@ static int make_single_user_exec(bContext *C, wmOperator *op) int flag= RNA_enum_get(op->ptr, "type"); /* 0==ALL, SELECTED==selected objecs */ if(RNA_boolean_get(op->ptr, "object")) - single_object_users(scene, v3d, flag); + single_object_users(scene, v3d, flag); if(RNA_boolean_get(op->ptr, "obdata")) single_obdata_users(scene, flag); diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index b3c104dcb56..8e3d613e02e 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -35,10 +35,8 @@ #include "DNA_group_types.h" #include "DNA_material_types.h" #include "DNA_modifier_types.h" -#include "DNA_object_types.h" #include "DNA_property_types.h" #include "DNA_scene_types.h" -#include "DNA_texture_types.h" #include "BLI_math.h" #include "BLI_listbase.h" @@ -47,7 +45,6 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" -#include "BKE_global.h" #include "BKE_group.h" #include "BKE_main.h" #include "BKE_material.h" @@ -60,9 +57,10 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_object.h" #include "ED_screen.h" +#include "UI_interface.h" + #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -164,11 +162,13 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot) static EnumPropertyItem prop_select_linked_types[] = { //{1, "IPO", 0, "Object IPO", ""}, // XXX depreceated animation system stuff... - {2, "OBDATA", 0, "Ob Data", ""}, + {2, "OBDATA", 0, "Object Data", ""}, {3, "MATERIAL", 0, "Material", ""}, {4, "TEXTURE", 0, "Texture", ""}, {5, "DUPGROUP", 0, "Dupligroup", ""}, {6, "PARTICLE", 0, "Particle System", ""}, + {7, "LIBRARY", 0, "Library", ""}, + {8, "LIBRARY_OBDATA", 0, "Library (Object Data)", ""}, {0, NULL, 0, NULL, NULL} }; @@ -201,7 +201,7 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) } ob= OBACT; - if(ob==0){ + if(ob==NULL){ BKE_report(op->reports, RPT_ERROR, "No Active Object"); return OPERATOR_CANCELLED; } @@ -230,7 +230,14 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) else if(nr==6) { if(ob->particlesystem.first==NULL) return OPERATOR_CANCELLED; } - else return OPERATOR_CANCELLED; + else if(nr==7) { + /* do nothing */ + } + else if(nr==8) { + if(ob->data==NULL) return OPERATOR_CANCELLED; + } + else + return OPERATOR_CANCELLED; CTX_DATA_BEGIN(C, Base*, base, visible_bases) { if(nr==1) { @@ -289,6 +296,18 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) } } } + else if(nr==7) { + if(ob->id.lib == base->object->id.lib) { + base->flag |= SELECT; + changed= 1; + } + } + else if(nr==8) { + if(base->object->data && ((ID *)ob->data)->lib == ((ID *)base->object->data)->lib) { + base->flag |= SELECT; + changed= 1; + } + } base->object->flag= base->flag; } CTX_DATA_END; @@ -385,14 +404,11 @@ static short select_grouped_group(bContext *C, Object *ob) /* Select objects in { short changed = 0; Group *group, *ob_groups[GROUP_MENU_MAX]; - //char str[10 + (24*GROUP_MENU_MAX)]; - //char *p = str; - int group_count=0; //, menu, i; - - for ( group=G.main->group.first; - group && group_count < GROUP_MENU_MAX; - group=group->id.next - ) { + int group_count=0, i; + uiPopupMenu *pup; + uiLayout *layout; + + for (group=CTX_data_main(C)->group.first; group && group_count < GROUP_MENU_MAX; group=group->id.next) { if (object_in_group (ob, group)) { ob_groups[group_count] = group; group_count++; @@ -401,7 +417,6 @@ static short select_grouped_group(bContext *C, Object *ob) /* Select objects in if (!group_count) return 0; - else if (group_count == 1) { group = ob_groups[0]; CTX_DATA_BEGIN(C, Base*, base, visible_bases) { @@ -413,27 +428,18 @@ static short select_grouped_group(bContext *C, Object *ob) /* Select objects in CTX_DATA_END; return changed; } -#if 0 // XXX hows this work in 2.5? + /* build the menu. */ - p += sprintf(str, "Groups%%t"); + pup= uiPupMenuBegin(C, "Select Group", 0); + layout= uiPupMenuLayout(pup); + for (i=0; i<group_count; i++) { group = ob_groups[i]; - p += sprintf (p, "|%s%%x%i", group->id.name+2, i); + uiItemStringO(layout, group->id.name+2, 0, "OBJECT_OT_select_same_group", "group", group->id.name); } - menu = pupmenu (str); - if (menu == -1) - return 0; - - group = ob_groups[menu]; - for (base= FIRSTBASE; base; base= base->next) { - if (!(base->flag & SELECT) && object_in_group(base->object, group)) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } -#endif - return changed; + uiPupMenuEnd(C, pup); + return changed; // The operator already handle this! } static short select_grouped_object_hooks(bContext *C, Object *ob) @@ -768,6 +774,55 @@ void OBJECT_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } +/**************************** Select In The Same Group ****************************/ + +static int object_select_same_group_exec(bContext *C, wmOperator *op) +{ + Group *group; + char group_name[32]; + + /* passthrough if no objects are visible */ + if (CTX_DATA_COUNT(C, visible_bases) == 0) return OPERATOR_PASS_THROUGH; + + RNA_string_get(op->ptr, "group", group_name); + + for (group=CTX_data_main(C)->group.first; group; group=group->id.next) { + if (!strcmp(group->id.name, group_name)) + break; + } + + if (!group) + return OPERATOR_PASS_THROUGH; + + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if (!(base->flag & SELECT) && object_in_group(base->object, group)) + ED_base_object_select(base, BA_SELECT); + } + CTX_DATA_END; + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_select_same_group(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "select same group"; + ot->description = "Select object in the same group"; + ot->idname= "OBJECT_OT_select_same_group"; + + /* api callbacks */ + ot->exec= object_select_same_group_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_string(ot->srna, "group", "", 32, "Group", "Name of the group to select."); +} + /**************************** Select Mirror ****************************/ /* finds the best possible flipped name. For renaming; check for unique names afterwards */ @@ -944,7 +999,9 @@ static int object_select_name_exec(bContext *C, wmOperator *op) } CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + /* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */ if(strcmp(name, base->object->id.name+2)==0) { + ED_base_object_activate(C, base); ED_base_object_select(base, BA_SELECT); changed= 1; } diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 3cf29cd3eaf..6735d07b591 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -39,19 +39,12 @@ #include "BLI_blenlib.h" #include "BLI_math.h" -#include "DNA_action_types.h" #include "DNA_curve_types.h" -#include "DNA_ipo_types.h" #include "DNA_key_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" -#include "DNA_userdef_types.h" -#include "DNA_view2d_types.h" #include "BKE_action.h" #include "BKE_anim.h" @@ -69,7 +62,6 @@ #include "BLO_sys_types.h" // for intptr_t support -#include "ED_object.h" #include "ED_mesh.h" #include "RNA_access.h" diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 0faca76e881..50764aeb192 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -29,16 +29,11 @@ #include <string.h> #include "DNA_anim_types.h" -#include "DNA_action_types.h" #include "DNA_armature_types.h" -#include "DNA_curve_types.h" #include "DNA_key_types.h" -#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" #include "BLI_math.h" #include "BLI_editVert.h" @@ -61,12 +56,10 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_anim_api.h" #include "ED_armature.h" #include "ED_curve.h" #include "ED_keyframing.h" #include "ED_mesh.h" -#include "ED_object.h" #include "ED_screen.h" #include "ED_view3d.h" @@ -76,32 +69,35 @@ static int object_location_clear_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); - + Scene *scene = CTX_data_scene(C); KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location"); - bCommonKeySrc cks; - ListBase dsources = {&cks, &cks}; - - /* init common-key-source for use by KeyingSets */ - memset(&cks, 0, sizeof(bCommonKeySrc)); /* clear location of selected objects if not in weight-paint mode */ CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { - if((ob->protectflag & OB_LOCK_LOCX)==0) + if (!(ob->mode & OB_MODE_WEIGHT_PAINT)) { + /* clear location if not locked */ + if ((ob->protectflag & OB_LOCK_LOCX)==0) ob->loc[0]= ob->dloc[0]= 0.0f; - if((ob->protectflag & OB_LOCK_LOCY)==0) + if ((ob->protectflag & OB_LOCK_LOCY)==0) ob->loc[1]= ob->dloc[1]= 0.0f; - if((ob->protectflag & OB_LOCK_LOCZ)==0) + if ((ob->protectflag & OB_LOCK_LOCZ)==0) ob->loc[2]= ob->dloc[2]= 0.0f; - /* do auto-keyframing as appropriate */ + /* auto keyframing */ if (autokeyframe_cfra_can_key(scene, &ob->id)) { - /* init cks for this object, then use the relative KeyingSets to keyframe it */ - cks.id= &ob->id; - modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + ListBase dsources = {NULL, NULL}; + + /* now insert the keyframe(s) using the Keying Set + * 1) add datasource override for the PoseChannel + * 2) insert keyframes + * 3) free the extra info + */ + ANIM_relative_keyingset_add_source(&dsources, &ob->id, NULL, NULL); + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + BLI_freelistN(&dsources); } } + ob->recalc |= OB_RECALC_OB; } CTX_DATA_END; @@ -132,17 +128,12 @@ void OBJECT_OT_location_clear(wmOperatorType *ot) static int object_rotation_clear_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation"); - bCommonKeySrc cks; - ListBase dsources = {&cks, &cks}; - - /* init common-key-source for use by KeyingSets */ - memset(&cks, 0, sizeof(bCommonKeySrc)); /* clear rotation of selected objects if not in weight-paint mode */ CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { + /* clear rotations that aren't locked */ if (ob->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) { if (ob->protectflag & OB_LOCK_ROT4D) { /* perform clamping on a component by component basis */ @@ -218,7 +209,7 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op) VECCOPY(ob->rot, eul); } } - } + } // Duplicated in source/blender/editors/armature/editarmature.c else { if (ob->rotmode == ROT_MODE_QUAT) { ob->quat[1]=ob->quat[2]=ob->quat[3]= 0.0f; @@ -234,13 +225,21 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op) } } - /* do auto-keyframing as appropriate */ + /* auto keyframing */ if (autokeyframe_cfra_can_key(scene, &ob->id)) { - /* init cks for this object, then use the relative KeyingSets to keyframe it */ - cks.id= &ob->id; - modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + ListBase dsources = {NULL, NULL}; + + /* now insert the keyframe(s) using the Keying Set + * 1) add datasource override for the PoseChannel + * 2) insert keyframes + * 3) free the extra info + */ + ANIM_relative_keyingset_add_source(&dsources, &ob->id, NULL, NULL); + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + BLI_freelistN(&dsources); } } + ob->recalc |= OB_RECALC_OB; } CTX_DATA_END; @@ -271,35 +270,37 @@ void OBJECT_OT_rotation_clear(wmOperatorType *ot) static int object_scale_clear_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scaling"); - bCommonKeySrc cks; - ListBase dsources = {&cks, &cks}; - - /* init common-key-source for use by KeyingSets */ - memset(&cks, 0, sizeof(bCommonKeySrc)); /* clear scales of selected objects if not in weight-paint mode */ CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { - if((ob->protectflag & OB_LOCK_SCALEX)==0) { + /* clear scale factors which are not locked */ + if ((ob->protectflag & OB_LOCK_SCALEX)==0) { ob->dsize[0]= 0.0f; ob->size[0]= 1.0f; } - if((ob->protectflag & OB_LOCK_SCALEY)==0) { + if ((ob->protectflag & OB_LOCK_SCALEY)==0) { ob->dsize[1]= 0.0f; ob->size[1]= 1.0f; } - if((ob->protectflag & OB_LOCK_SCALEZ)==0) { + if ((ob->protectflag & OB_LOCK_SCALEZ)==0) { ob->dsize[2]= 0.0f; ob->size[2]= 1.0f; } - /* do auto-keyframing as appropriate */ + /* auto keyframing */ if (autokeyframe_cfra_can_key(scene, &ob->id)) { - /* init cks for this object, then use the relative KeyingSets to keyframe it */ - cks.id= &ob->id; - modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + ListBase dsources = {NULL, NULL}; + + /* now insert the keyframe(s) using the Keying Set + * 1) add datasource override for the PoseChannel + * 2) insert keyframes + * 3) free the extra info + */ + ANIM_relative_keyingset_add_source(&dsources, &ob->id, NULL, NULL); + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + BLI_freelistN(&dsources); } } ob->recalc |= OB_RECALC_OB; @@ -385,7 +386,7 @@ static void ignore_parent_tx(Main *bmain, Scene *scene, Object *ob ) /* a change was made, adjust the children to compensate */ for(ob_child=bmain->object.first; ob_child; ob_child=ob_child->id.next) { if(ob_child->parent == ob) { - ED_object_apply_obmat(ob_child); + object_apply_mat4(ob_child, ob_child->obmat); what_does_parent(scene, ob_child, &workob); invert_m4_m4(ob_child->parentinv, workob.obmat); } @@ -432,6 +433,10 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo BKE_report(reports, RPT_ERROR, "Can't apply to a multi user curve, doing nothing."); return OPERATOR_CANCELLED; } + if(!(cu->flag & CU_3D) && (apply_rot || apply_loc)) { + BKE_report(reports, RPT_ERROR, "Neither rotation nor location could be applied to a 2d curve, doing nothing."); + return OPERATOR_CANCELLED; + } if(cu->key) { BKE_report(reports, RPT_ERROR, "Can't apply to a curve with vertex keys, doing nothing."); return OPERATOR_CANCELLED; @@ -498,7 +503,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo cu= ob->data; scale = mat3_to_scale(rsmat); - + for(nu=cu->nurb.first; nu; nu=nu->next) { if(nu->type == CU_BEZIER) { a= nu->pntsu; @@ -759,7 +764,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { - sub_v3_v3v3(eve->co, eve->co, cent); + sub_v3_v3(eve->co, cent); } EDBM_RecalcNormals(em); @@ -804,7 +809,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) mvert= me->mvert; for(a=0; a<me->totvert; a++, mvert++) { - sub_v3_v3v3(mvert->co, mvert->co, cent); + sub_v3_v3(mvert->co, cent); } if (me->key) { @@ -813,7 +818,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) float *fp= kb->data; for (a=0; a<kb->totelem; a++, fp+=3) { - sub_v3_v3v3(fp, fp, cent); + sub_v3_v3(fp, cent); } } } @@ -855,7 +860,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) if(tme && (tme->flag & ME_ISDONE)==0) { mvert= tme->mvert; for(a=0; a<tme->totvert; a++, mvert++) { - sub_v3_v3v3(mvert->co, mvert->co, cent); + sub_v3_v3(mvert->co, cent); } if (tme->key) { @@ -864,7 +869,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) float *fp= kb->data; for (a=0; a<kb->totelem; a++, fp+=3) { - sub_v3_v3v3(fp, fp, cent); + sub_v3_v3(fp, cent); } } } @@ -924,15 +929,15 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) if(nu->type == CU_BEZIER) { a= nu->pntsu; while (a--) { - sub_v3_v3v3(nu->bezt[a].vec[0], nu->bezt[a].vec[0], cent); - sub_v3_v3v3(nu->bezt[a].vec[1], nu->bezt[a].vec[1], cent); - sub_v3_v3v3(nu->bezt[a].vec[2], nu->bezt[a].vec[2], cent); + sub_v3_v3(nu->bezt[a].vec[0], cent); + sub_v3_v3(nu->bezt[a].vec[1], cent); + sub_v3_v3(nu->bezt[a].vec[2], cent); } } else { a= nu->pntsu*nu->pntsv; while (a--) - sub_v3_v3v3(nu->bp[a].vec, nu->bp[a].vec, cent); + sub_v3_v3(nu->bp[a].vec, cent); } nu= nu->next; } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 1b20042b25e..ea118602c6c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -36,14 +36,13 @@ #include "DNA_cloth_types.h" #include "DNA_curve_types.h" #include "DNA_lattice_types.h" -#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_scene_types.h" #include "DNA_particle_types.h" -#include "DNA_windowmanager_types.h" #include "BLI_blenlib.h" #include "BLI_cellalloc.h" @@ -69,9 +68,7 @@ #include "WM_types.h" #include "ED_mesh.h" -#include "ED_view3d.h" -#include "UI_interface.h" #include "UI_resources.h" #include "object_intern.h" @@ -98,7 +95,7 @@ bDeformGroup *ED_vgroup_add_name(Object *ob, char *name) defgroup = MEM_callocN(sizeof(bDeformGroup), "add deformGroup"); - BLI_strncpy(defgroup->name, name, 32); + BLI_strncpy(defgroup->name, name, sizeof(defgroup->name)); BLI_addtail(&ob->defbase, defgroup); defgroup_unique_name(defgroup, ob); @@ -127,6 +124,78 @@ void ED_vgroup_data_create(ID *id) } } +int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot) +{ + if(id) { + switch(GS(id->name)) { + case ID_ME: + { + Mesh *me = (Mesh *)id; + + if(me->edit_btmesh) { + BMEditMesh *em = me->edit_btmesh; + BMIter iter; + BMVert *eve; + int i; + + if (!CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT)) { + *dvert_tot = 0; + *dvert_arr = NULL; + return 0; + } + + i = em->bm->totvert; + + *dvert_arr= MEM_mallocN(sizeof(void*)*i, "vgroup parray from me"); + *dvert_tot = i; + + i = 0; + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + (*dvert_arr)[i] = CustomData_em_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); + i++; + } + + return 1; + } + else if(me->dvert) { + int i; + + *dvert_tot= me->totvert; + *dvert_arr= MEM_mallocN(sizeof(void*)*me->totvert, "vgroup parray from me"); + + for (i=0; i<me->totvert; i++) { + (*dvert_arr)[i] = me->dvert + i; + } + + return 1; + } + else + return 0; + } + case ID_LT: + { + int i=0; + + Lattice *lt= (Lattice *)id; + lt= (lt->editlatt)? lt->editlatt: lt; + + *dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + *dvert_arr= MEM_mallocN(sizeof(void*)*(*dvert_tot), "vgroup parray from me"); + + for (i=0; i<*dvert_tot; i++) { + (*dvert_arr)[i] = lt->dvert + i; + } + + return 1; + } + } + } + + *dvert_arr= NULL; + *dvert_tot= 0; + return 0; +} + /* returns true if the id type supports weights */ int ED_vgroup_give_array(ID *id, MDeformVert **dvert_arr, int *dvert_tot) { @@ -158,20 +227,22 @@ int ED_vgroup_give_array(ID *id, MDeformVert **dvert_arr, int *dvert_tot) /* matching index only */ int ED_vgroup_copy_array(Object *ob, Object *ob_from) { - MDeformVert *dvert_array_from, *dvf; - MDeformVert *dvert_array, *dv; - + MDeformVert **dvert_array_from, **dvf; + MDeformVert **dvert_array, **dv; int dvert_tot_from; int dvert_tot; int i; int totdef_from= BLI_countlist(&ob_from->defbase); int totdef= BLI_countlist(&ob->defbase); - ED_vgroup_give_array(ob_from->data, &dvert_array_from, &dvert_tot_from); - ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); - if(ob==ob_from || dvert_tot==0 || (dvert_tot != dvert_tot_from) || dvert_array_from==NULL || dvert_array==NULL) + if(ob==ob_from || dvert_tot==0 || (dvert_tot != dvert_tot_from) || dvert_array_from==NULL || dvert_array==NULL) { + if (dvert_array) MEM_freeN(dvert_array); + if (dvert_array_from) MEM_freeN(dvert_array_from); return 0; + } /* do the copy */ BLI_freelistN(&ob->defbase); @@ -192,15 +263,18 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) dv= dvert_array; for(i=0; i<dvert_tot; i++, dvf++, dv++) { - if(dv->dw) - MEM_freeN(dv->dw); + if((*dv)->dw) + MEM_freeN((*dv)->dw); - *dv= *dvf; + *(*dv)= *(*dvf); - if(dv->dw) - dv->dw= MEM_dupallocN(dv->dw); + if((*dv)->dw) + (*dv)->dw= MEM_dupallocN((*dv)->dw); } + MEM_freeN(dvert_array); + MEM_freeN(dvert_array_from); + return 1; } @@ -289,7 +363,11 @@ void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, in if(dv==NULL) return; - dv+= vertnum; + /* check that vertnum is valid before trying to get the relevant dvert */ + if ((vertnum < 0) || (vertnum >= tot)) + return; + else + dv += vertnum; /* Lets first check to see if this vert is * already in the weight group -- if so @@ -536,7 +614,7 @@ static void vgroup_duplicate(Object *ob) bDeformGroup *dg, *cdg; char name[32], s[32]; MDeformWeight *org, *cpy; - MDeformVert *dvert, *dvert_array=NULL; + MDeformVert *dvert, **dvert_array=NULL; int i, idg, icdg, dvert_tot=0; dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); @@ -569,13 +647,13 @@ static void vgroup_duplicate(Object *ob) ob->actdef = BLI_countlist(&ob->defbase); icdg = (ob->actdef-1); - ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); if(!dvert_array) return; for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; + dvert = dvert_array[i]; org = defvert_find_index(dvert, idg); if(org) { float weight = org->weight; @@ -584,16 +662,18 @@ static void vgroup_duplicate(Object *ob) cpy->weight = weight; } } + + MEM_freeN(dvert_array); } static void vgroup_normalize(Object *ob) { bDeformGroup *dg; MDeformWeight *dw; - MDeformVert *dvert, *dvert_array=NULL; + MDeformVert *dvert, **dvert_array=NULL; int i, def_nr, dvert_tot=0; - ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); @@ -603,7 +683,7 @@ static void vgroup_normalize(Object *ob) def_nr= ob->actdef-1; for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; + dvert = dvert_array[i]; dw = defvert_find_index(dvert, def_nr); if(dw) { weight_max = MAX2(dw->weight, weight_max); @@ -612,7 +692,7 @@ static void vgroup_normalize(Object *ob) if(weight_max > 0.0f) { for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; + dvert = dvert_array[i]; dw = defvert_find_index(dvert, def_nr); if(dw) { dw->weight /= weight_max; @@ -623,16 +703,18 @@ static void vgroup_normalize(Object *ob) } } } + + if (dvert_array) MEM_freeN(dvert_array); } static void vgroup_levels(Object *ob, float offset, float gain) { bDeformGroup *dg; MDeformWeight *dw; - MDeformVert *dvert, *dvert_array=NULL; + MDeformVert *dvert, **dvert_array=NULL; int i, def_nr, dvert_tot=0; - ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); @@ -640,7 +722,7 @@ static void vgroup_levels(Object *ob, float offset, float gain) def_nr= ob->actdef-1; for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; + dvert = dvert_array[i]; dw = defvert_find_index(dvert, def_nr); if(dw) { dw->weight = gain * (dw->weight + offset); @@ -649,17 +731,19 @@ static void vgroup_levels(Object *ob, float offset, float gain) } } } + + if (dvert_array) MEM_freeN(dvert_array); } /* TODO - select between groups */ static void vgroup_normalize_all(Object *ob, int lock_active) { MDeformWeight *dw, *dw_act; - MDeformVert *dvert, *dvert_array=NULL; + MDeformVert *dvert, **dvert_array=NULL; int i, dvert_tot=0; float tot_weight; - ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); if(dvert_array) { if(lock_active) { @@ -671,7 +755,7 @@ static void vgroup_normalize_all(Object *ob, int lock_active) tot_weight= 0.0f; dw_act= NULL; - dvert = dvert_array+i; + dvert = dvert_array[i]; j= dvert->totweight; while(j--) { @@ -709,7 +793,7 @@ static void vgroup_normalize_all(Object *ob, int lock_active) for(i = 0; i < dvert_tot; i++) { int j; tot_weight= 0.0f; - dvert = dvert_array+i; + dvert = dvert_array[i]; j= dvert->totweight; while(j--) { @@ -730,6 +814,8 @@ static void vgroup_normalize_all(Object *ob, int lock_active) } } } + + if (dvert_array) MEM_freeN(dvert_array); } @@ -737,10 +823,10 @@ static void vgroup_invert(Object *ob, int auto_assign, int auto_remove) { bDeformGroup *dg; MDeformWeight *dw; - MDeformVert *dvert, *dvert_array=NULL; + MDeformVert *dvert, **dvert_array=NULL; int i, def_nr, dvert_tot=0; - ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); @@ -749,7 +835,7 @@ static void vgroup_invert(Object *ob, int auto_assign, int auto_remove) for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; + dvert = dvert_array[i]; if(auto_assign) { dw= defvert_verify_index(dvert, def_nr); @@ -767,6 +853,8 @@ static void vgroup_invert(Object *ob, int auto_assign, int auto_remove) } } } + + if (dvert_array) MEM_freeN(dvert_array); } static void vgroup_blend(Object *ob) @@ -858,10 +946,10 @@ static void vgroup_clean(Object *ob, float eul, int keep_single) { bDeformGroup *dg; MDeformWeight *dw; - MDeformVert *dvert, *dvert_array=NULL; + MDeformVert *dvert, **dvert_array=NULL; int i, def_nr, dvert_tot=0; - ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); /* only the active group */ dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); @@ -869,7 +957,7 @@ static void vgroup_clean(Object *ob, float eul, int keep_single) def_nr= ob->actdef-1; for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; + dvert = dvert_array[i]; dw= defvert_find_index(dvert, def_nr); @@ -880,21 +968,23 @@ static void vgroup_clean(Object *ob, float eul, int keep_single) } } } + + if (dvert_array) MEM_freeN(dvert_array); } static void vgroup_clean_all(Object *ob, float eul, int keep_single) { MDeformWeight *dw; - MDeformVert *dvert, *dvert_array=NULL; + MDeformVert *dvert, **dvert_array=NULL; int i, dvert_tot=0; - ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); if(dvert_array) { for(i = 0; i < dvert_tot; i++) { int j; - dvert = dvert_array+i; + dvert = dvert_array[i]; j= dvert->totweight; while(j--) { @@ -910,6 +1000,8 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single) } } } + + if (dvert_array) MEM_freeN(dvert_array); } void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups) @@ -1287,7 +1379,7 @@ static void vgroup_assign_verts(Object *ob, float weight) done=1; break; } - } + } /* If not: Add the group and set its weight */ if(!done){ newdw = BLI_cellalloc_calloc(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight"); @@ -1459,7 +1551,11 @@ static int vertex_group_remove_from_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_edit_object(C); - vgroup_remove_verts(ob, 0); + if(RNA_boolean_get(op->ptr, "all")) + vgroup_remove_verts(ob, 0); + else + vgroup_active_remove_verts(ob, 0); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); @@ -1917,41 +2013,38 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot) ot->prop= prop; } -static int vgroup_sort(void *def_a_ptr, void *def_b_ptr) +/*creates the name_array parameter for vgroup_do_remap, call this before fiddling + with the order of vgroups then call vgroup_do_remap after*/ +static char *vgroup_init_remap(Object *ob) { - bDeformGroup *def_a= (bDeformGroup *)def_a_ptr; - bDeformGroup *def_b= (bDeformGroup *)def_b_ptr; + bDeformGroup *def; + int def_tot = BLI_countlist(&ob->defbase); + char *name_array= MEM_mallocN(MAX_VGROUP_NAME * sizeof(char) * def_tot, "sort vgroups"); + char *name; - return strcmp(def_a->name, def_b->name); + name= name_array; + for(def = ob->defbase.first; def; def=def->next) { + BLI_strncpy(name, def->name, MAX_VGROUP_NAME); + name += MAX_VGROUP_NAME; + } + + return name_array; } -#define DEF_GROUP_SIZE (sizeof(((bDeformGroup *)NULL)->name)) -static int vertex_group_sort_exec(bContext *C, wmOperator *op) +static int vgroup_do_remap(Object *ob, char *name_array, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + MDeformVert *dvert= NULL; bDeformGroup *def; int def_tot = BLI_countlist(&ob->defbase); - char *name; - char *name_array= MEM_mallocN(DEF_GROUP_SIZE * sizeof(char) * def_tot, "sort vgroups"); - int *sort_map_update= MEM_mallocN(DEF_GROUP_SIZE * sizeof(int) * def_tot + 1, "sort vgroups"); /* needs a dummy index at the start*/ + int *sort_map_update= MEM_mallocN(MAX_VGROUP_NAME * sizeof(int) * def_tot + 1, "sort vgroups"); /* needs a dummy index at the start*/ int *sort_map= sort_map_update + 1; + char *name; int i; - MDeformVert *dvert= NULL; - int dvert_tot; - - name= name_array; - for(def = ob->defbase.first; def; def=def->next){ - BLI_strncpy(name, def->name, DEF_GROUP_SIZE); - name += DEF_GROUP_SIZE; - } - - BLI_sortlist(&ob->defbase, vgroup_sort); - name= name_array; for(def= ob->defbase.first, i=0; def; def=def->next, i++){ sort_map[i]= BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)); - name += DEF_GROUP_SIZE; + name += MAX_VGROUP_NAME; } if(ob->mode == OB_MODE_EDIT) { @@ -1973,7 +2066,11 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op) } } else { + int dvert_tot=0; + ED_vgroup_give_array(ob->data, &dvert, &dvert_tot); + + /*create as necassary*/ while(dvert && dvert_tot--) { if(dvert->totweight) defvert_remap(dvert, sort_map); @@ -1986,21 +2083,45 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op) sort_map[i]++; sort_map_update[0]= 0; - vgroup_remap_update_users(ob, sort_map_update); ob->actdef= sort_map_update[ob->actdef]; - MEM_freeN(name_array); - MEM_freeN(sort_map_update); + return OPERATOR_FINISHED; +} - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob); +static int vgroup_sort(void *def_a_ptr, void *def_b_ptr) +{ + bDeformGroup *def_a= (bDeformGroup *)def_a_ptr; + bDeformGroup *def_b= (bDeformGroup *)def_b_ptr; - return OPERATOR_FINISHED; + return strcmp(def_a->name, def_b->name); } -#undef DEF_GROUP_SIZE +static int vertex_group_sort_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + char *name_array; + int ret; + + /*init remapping*/ + name_array = vgroup_init_remap(ob); + + /*sort vgroup names*/ + BLI_sortlist(&ob->defbase, vgroup_sort); + + /*remap vgroup data to map to correct names*/ + ret = vgroup_do_remap(ob, name_array, op); + + if (ret != OPERATOR_CANCELLED) { + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob); + } + + if (name_array) MEM_freeN(name_array); + + return ret; +} void OBJECT_OT_vertex_group_sort(wmOperatorType *ot) { @@ -2015,3 +2136,63 @@ void OBJECT_OT_vertex_group_sort(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } + +static int vgroup_move_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + bDeformGroup *def; + char *name_array; + int dir= RNA_enum_get(op->ptr, "direction"), ret; + + def = BLI_findlink(&ob->defbase, ob->actdef - 1); + if (!def) { + return OPERATOR_CANCELLED; + } + + name_array = vgroup_init_remap(ob); + + if (dir == 1) { /*up*/ + void *prev = def->prev; + + BLI_remlink(&ob->defbase, def); + BLI_insertlinkbefore(&ob->defbase, prev, def); + } else { /*down*/ + void *next = def->next; + + BLI_remlink(&ob->defbase, def); + BLI_insertlinkafter(&ob->defbase, next, def); + } + + ret = vgroup_do_remap(ob, name_array, op); + + if (name_array) MEM_freeN(name_array); + + if (ret != OPERATOR_CANCELLED) { + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob); + } + + return ret; +} + +void OBJECT_OT_vertex_group_move(wmOperatorType *ot) +{ + static EnumPropertyItem vgroup_slot_move[] = { + {1, "UP", 0, "Up", ""}, + {-1, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Move Vertex Group"; + ot->idname= "OBJECT_OT_vertex_group_move"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vgroup_move_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "direction", vgroup_slot_move, 0, "Direction", "Direction to move, UP or DOWN"); +} |