diff options
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r-- | source/blender/editors/object/object_add.c | 68 | ||||
-rw-r--r-- | source/blender/editors/object/object_bake_api.c | 26 | ||||
-rw-r--r-- | source/blender/editors/object/object_constraint.c | 25 | ||||
-rw-r--r-- | source/blender/editors/object/object_data_transfer.c | 9 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 88 | ||||
-rw-r--r-- | source/blender/editors/object/object_hook.c | 5 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 13 | ||||
-rw-r--r-- | source/blender/editors/object/object_lattice.c | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 110 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 8 | ||||
-rw-r--r-- | source/blender/editors/object/object_random.c | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 29 | ||||
-rw-r--r-- | source/blender/editors/object/object_shapekey.c | 89 | ||||
-rw-r--r-- | source/blender/editors/object/object_transform.c | 6 | ||||
-rw-r--r-- | source/blender/editors/object/object_vgroup.c | 336 | ||||
-rw-r--r-- | source/blender/editors/object/object_warp.c | 4 |
16 files changed, 521 insertions, 301 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 99b351561c7..075e382f628 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -57,6 +57,7 @@ #include "BLF_translation.h" +#include "BKE_action.h" #include "BKE_anim.h" #include "BKE_animsys.h" #include "BKE_armature.h" @@ -262,7 +263,7 @@ void ED_object_add_unit_props(wmOperatorType *ot) { PropertyRNA *prop; - prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); + prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius", "", 0.001, 100.00); RNA_def_property_subtype(prop, PROP_DISTANCE); } @@ -280,11 +281,12 @@ void ED_object_add_generic_props(wmOperatorType *ot, bool do_editmode) RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } - prop = RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", - "Location for the newly added object", -FLT_MAX, FLT_MAX); + prop = RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -OBJECT_ADD_SIZE_MAXF, OBJECT_ADD_SIZE_MAXF, + "Location", "Location for the newly added object", -1000.0f, 1000.0f); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation", - "Rotation for the newly added object", (float)-M_PI * 2.0f, (float)M_PI * 2.0f); + prop = RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -OBJECT_ADD_SIZE_MAXF, OBJECT_ADD_SIZE_MAXF, + "Rotation", "Rotation for the newly added object", + DEG2RADF(-360.0f), DEG2RADF(360.0f)); RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", ""); @@ -394,8 +396,11 @@ bool ED_object_add_generic_get_opts(bContext *C, wmOperator *op, const char view /* For object add primitive operators. * Do not call undo push in this function (users of this function have to). */ -Object *ED_object_add_type(bContext *C, int type, const float loc[3], const float rot[3], - bool enter_editmode, unsigned int layer) +Object *ED_object_add_type( + bContext *C, + int type, const char *name, + const float loc[3], const float rot[3], + bool enter_editmode, unsigned int layer) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -406,7 +411,7 @@ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const floa ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */ /* deselects all, sets scene->basact */ - ob = BKE_object_add(bmain, scene, type); + ob = BKE_object_add(bmain, scene, type, name); BASACT->lay = ob->lay = layer; /* editor level activate, notifiers */ ED_base_object_activate(C, BASACT); @@ -447,7 +452,7 @@ static int object_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; radius = RNA_float_get(op->ptr, "radius"); - ob = ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer); + ob = ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), NULL, loc, rot, enter_editmode, layer); if (ob->type == OB_LATTICE) { /* lattice is a special case! @@ -504,9 +509,9 @@ static int effector_add_exec(bContext *C, wmOperator *op) if (type == PFIELD_GUIDE) { Curve *cu; - ob = ED_object_add_type(C, OB_CURVE, loc, rot, false, layer); + const char *name = CTX_DATA_(BLF_I18NCONTEXT_ID_OBJECT, "CurveGuide"); + ob = ED_object_add_type(C, OB_CURVE, name, loc, rot, false, layer); - rename_id(&ob->id, CTX_DATA_(BLF_I18NCONTEXT_ID_OBJECT, "CurveGuide")); cu = ob->data; cu->flag |= CU_PATH | CU_3D; ED_object_editmode_enter(C, 0); @@ -516,9 +521,9 @@ static int effector_add_exec(bContext *C, wmOperator *op) ED_object_editmode_exit(C, EM_FREEDATA); } else { - ob = ED_object_add_type(C, OB_EMPTY, loc, rot, false, layer); + const char *name = CTX_DATA_(BLF_I18NCONTEXT_ID_OBJECT, "Field"); + ob = ED_object_add_type(C, OB_EMPTY, name, loc, rot, false, layer); BKE_object_obdata_size_init(ob, dia); - rename_id(&ob->id, CTX_DATA_(BLF_I18NCONTEXT_ID_OBJECT, "Field")); if (ELEM(type, PFIELD_WIND, PFIELD_VORTEX)) ob->empty_drawtype = OB_SINGLE_ARROW; } @@ -569,7 +574,7 @@ static int object_camera_add_exec(bContext *C, wmOperator *op) if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; - ob = ED_object_add_type(C, OB_CAMERA, loc, rot, false, layer); + ob = ED_object_add_type(C, OB_CAMERA, NULL, loc, rot, false, layer); if (v3d) { if (v3d->camera == NULL) @@ -626,7 +631,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; if (obedit == NULL || obedit->type != OB_MBALL) { - obedit = ED_object_add_type(C, OB_MBALL, loc, rot, true, layer); + obedit = ED_object_add_type(C, OB_MBALL, NULL, loc, rot, true, layer); newob = true; } else { @@ -685,7 +690,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op) if (obedit && obedit->type == OB_FONT) return OPERATOR_CANCELLED; - obedit = ED_object_add_type(C, OB_FONT, loc, rot, enter_editmode, layer); + obedit = ED_object_add_type(C, OB_FONT, NULL, loc, rot, enter_editmode, layer); BKE_object_obdata_size_init(obedit, RNA_float_get(op->ptr, "radius")); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); @@ -729,7 +734,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; if ((obedit == NULL) || (obedit->type != OB_ARMATURE)) { - obedit = ED_object_add_type(C, OB_ARMATURE, loc, rot, true, layer); + obedit = ED_object_add_type(C, OB_ARMATURE, NULL, loc, rot, true, layer); ED_object_editmode_enter(C, 0); newob = true; } @@ -786,7 +791,7 @@ static int object_empty_add_exec(bContext *C, wmOperator *op) if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; - ob = ED_object_add_type(C, OB_EMPTY, loc, rot, false, layer); + ob = ED_object_add_type(C, OB_EMPTY, NULL, loc, rot, false, layer); BKE_object_empty_draw_type_set(ob, type); BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius")); @@ -846,7 +851,7 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv if (!ED_object_add_generic_get_opts(C, op, 'Z', NULL, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; - ob = ED_object_add_type(C, OB_EMPTY, NULL, rot, false, layer); + ob = ED_object_add_type(C, OB_EMPTY, NULL, NULL, rot, false, layer); /* add under the mouse */ ED_object_location_from_view(C, ob->loc); @@ -916,13 +921,11 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; - ob = ED_object_add_type(C, OB_LAMP, loc, rot, false, layer); + ob = ED_object_add_type(C, OB_LAMP, get_lamp_defname(type), loc, rot, false, layer); BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius")); la = (Lamp *)ob->data; la->type = type; - rename_id(&ob->id, get_lamp_defname(type)); - rename_id(&la->id, get_lamp_defname(type)); if (BKE_scene_use_new_shading_nodes(scene)) { ED_node_shader_default(C, &la->id); @@ -988,8 +991,7 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) if (group) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Object *ob = ED_object_add_type(C, OB_EMPTY, loc, rot, false, layer); - rename_id(&ob->id, group->id.name + 2); + Object *ob = ED_object_add_type(C, OB_EMPTY, group->id.name + 2, loc, rot, false, layer); ob->dup_group = group; ob->transflag |= OB_DUPLIGROUP; id_lib_extern(&group->id); @@ -1044,14 +1046,14 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; - ob = ED_object_add_type(C, OB_SPEAKER, loc, rot, false, layer); + ob = ED_object_add_type(C, OB_SPEAKER, NULL, loc, rot, false, layer); /* to make it easier to start using this immediately in NLA, a default sound clip is created * ready to be moved around to retime the sound and/or make new sound clips */ { /* create new data for NLA hierarchy */ - AnimData *adt = BKE_id_add_animdata(&ob->id); + AnimData *adt = BKE_animdata_add_id(&ob->id); NlaTrack *nlt = add_nlatrack(adt, NULL); NlaStrip *strip = add_nla_soundstrip(scene, ob->data); strip->start = CFRA; @@ -1358,7 +1360,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, basen->object = ob; /* make sure apply works */ - BKE_free_animdata(&ob->id); + BKE_animdata_free(&ob->id); ob->adt = NULL; /* Proxies are not to be copied. */ @@ -1976,7 +1978,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base /* duplicates using userflags */ if (dupflag & USER_DUP_ACT) { - BKE_copy_animdata_id_action(&obn->id); + BKE_animdata_copy_id_action(&obn->id); } if (dupflag & USER_DUP_MAT) { @@ -1989,7 +1991,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base id->us--; if (dupflag & USER_DUP_ACT) { - BKE_copy_animdata_id_action(&obn->mat[a]->id); + BKE_animdata_copy_id_action(&obn->mat[a]->id); } } } @@ -2004,7 +2006,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base psys->part = BKE_particlesettings_copy(psys->part); if (dupflag & USER_DUP_ACT) { - BKE_copy_animdata_id_action(&psys->part->id); + BKE_animdata_copy_id_action(&psys->part->id); } id->us--; @@ -2082,7 +2084,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base case OB_ARMATURE: DAG_id_tag_update(&obn->id, OB_RECALC_DATA); if (obn->pose) - obn->pose->flag |= POSE_RECALC; + BKE_pose_tag_recalc(bmain, obn->pose); if (dupflag & USER_DUP_ARM) { ID_NEW_US2(obn->data) else { @@ -2132,9 +2134,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base if (dupflag & USER_DUP_ACT) { bActuator *act; - BKE_copy_animdata_id_action((ID *)obn->data); + BKE_animdata_copy_id_action((ID *)obn->data); if (key) { - BKE_copy_animdata_id_action((ID *)key); + BKE_animdata_copy_id_action((ID *)key); } /* Update the duplicated action in the action actuators */ diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index fe9ee71aa8e..b382fbafcfd 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -574,6 +574,7 @@ static int bake( float *result = NULL; BakePixel *pixel_array_low = NULL; + BakePixel *pixel_array_high = NULL; const bool is_save_internal = (save_mode == R_BAKE_SAVE_INTERNAL); const bool is_noncolor = is_noncolor_pass(pass_type); @@ -682,6 +683,7 @@ static int bake( } pixel_array_low = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly"); + pixel_array_high = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly"); result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels"); /* get the mesh as it arrives in the renderer */ @@ -755,8 +757,6 @@ static int bake( /* initialize highpoly_data */ highpoly[i].ob = ob_iter; highpoly[i].restrict_flag = ob_iter->restrictflag; - highpoly[i].pixel_array = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly"); - /* triangulating so BVH returns the primitive_id that will be used for rendering */ highpoly[i].tri_mod = ED_object_modifier_add( @@ -775,11 +775,7 @@ static int bake( copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat); invert_m4_m4(highpoly[i].imat, highpoly[i].obmat); - /* rotation */ - normalize_m4_m4(highpoly[i].rotmat, highpoly[i].imat); - zero_v3(highpoly[i].rotmat[3]); - if (is_negative_m4(highpoly[i].rotmat)) - negate_mat3_m4(highpoly[i].rotmat); + highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat); i++; } @@ -790,7 +786,7 @@ static int bake( /* populate the pixel arrays with the corresponding face data for each high poly object */ if (!RE_bake_pixels_populate_from_objects( - me_low, pixel_array_low, highpoly, tot_highpoly, num_pixels, ob_cage != NULL, + me_low, pixel_array_low, pixel_array_high, highpoly, tot_highpoly, num_pixels, ob_cage != NULL, cage_extrusion, ob_low->obmat, (ob_cage ? ob_cage->obmat : ob_low->obmat), me_cage)) { BKE_report(reports, RPT_ERROR, "Error handling selected objects"); @@ -799,8 +795,8 @@ static int bake( /* the baking itself */ for (i = 0; i < tot_highpoly; i++) { - ok = RE_bake_engine(re, highpoly[i].ob, highpoly[i].pixel_array, num_pixels, - depth, pass_type, result); + ok = RE_bake_engine(re, highpoly[i].ob, i, pixel_array_high, + num_pixels, depth, pass_type, result); if (!ok) { BKE_reportf(reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2); goto cage_cleanup; @@ -826,7 +822,7 @@ cage_cleanup: ob_low->restrictflag &= ~OB_RESTRICT_RENDER; if (RE_bake_has_engine(re)) { - ok = RE_bake_engine(re, ob_low, pixel_array_low, num_pixels, depth, pass_type, result); + ok = RE_bake_engine(re, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, result); } else { BKE_report(reports, RPT_ERROR, "Current render engine does not support baking"); @@ -929,7 +925,7 @@ cage_cleanup: BakeData *bake = &scene->r.bake; char name[FILE_MAX]; - BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false); + BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false, NULL); if (is_automatic_name) { BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_"); @@ -990,9 +986,6 @@ cleanup: for (i = 0; i < tot_highpoly; i++) { highpoly[i].ob->restrictflag = highpoly[i].restrict_flag; - if (highpoly[i].pixel_array) - MEM_freeN(highpoly[i].pixel_array); - if (highpoly[i].tri_mod) ED_object_modifier_remove(reports, bmain, highpoly[i].ob, highpoly[i].tri_mod); @@ -1010,6 +1003,9 @@ cleanup: if (pixel_array_low) MEM_freeN(pixel_array_low); + if (pixel_array_high) + MEM_freeN(pixel_array_high); + if (bake_images.data) MEM_freeN(bake_images.data); diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index f1b349d5a44..e14674ef517 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -226,7 +226,7 @@ static void update_pyconstraint_cb(void *arg1, void *arg2) /* helper function for add_constriant - sets the last target for the active constraint */ static void set_constraint_nth_target(bConstraint *con, Object *target, const char subtarget[], int index) { - bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; int num_targets, i; @@ -262,7 +262,7 @@ static void set_constraint_nth_target(bConstraint *con, Object *target, const ch static void test_constraint(Object *owner, bPoseChannel *pchan, bConstraint *con, int type) { - bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); + const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; bool check_targets = true; @@ -1194,9 +1194,9 @@ void ED_object_constraint_update(Object *ob) DAG_id_tag_update(&ob->id, OB_RECALC_OB); } -static void object_pose_tag_update(Object *ob) +static void object_pose_tag_update(Main *bmain, Object *ob) { - ob->pose->flag |= POSE_RECALC; /* Checks & sort pose channels. */ + BKE_pose_tag_recalc(bmain, ob->pose); /* Checks & sort pose channels. */ if (ob->proxy && ob->adt) { /* We need to make use of ugly POSE_ANIMATION_WORKAROUND here too, else anim data are not reloaded * after calling `BKE_pose_rebuild()`, which causes T43872. @@ -1212,7 +1212,7 @@ void ED_object_constraint_dependency_update(Main *bmain, Object *ob) ED_object_constraint_update(ob); if (ob->pose) { - object_pose_tag_update(ob); + object_pose_tag_update(bmain, ob); } DAG_relations_tag_update(bmain); } @@ -1236,7 +1236,7 @@ void ED_object_constraint_dependency_tag_update(Main *bmain, Object *ob, bConstr ED_object_constraint_tag_update(ob, con); if (ob->pose) { - object_pose_tag_update(ob); + object_pose_tag_update(bmain, ob); } DAG_relations_tag_update(bmain); } @@ -1260,7 +1260,10 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* there's no active constraint now, so make sure this is the case */ BKE_constraints_active_set(&ob->constraints, NULL); ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */ - + + /* relatiols */ + DAG_relations_tag_update(CTX_data_main(C)); + /* notifiers */ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob); @@ -1484,8 +1487,8 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op) BKE_constraints_copy(&chan->constraints, &pchan->constraints, true); /* update flags (need to add here, not just copy) */ chan->constflag |= pchan->constflag; - - ob->pose->flag |= POSE_RECALC; + + BKE_pose_tag_recalc(bmain, ob->pose); DAG_id_tag_update((ID *)ob, OB_RECALC_DATA); } } @@ -1662,7 +1665,7 @@ static short get_new_constraint_target(bContext *C, int con_type, Object **tar_o Object *obt; /* add new target object */ - obt = BKE_object_add(bmain, scene, OB_EMPTY); + obt = BKE_object_add(bmain, scene, OB_EMPTY, NULL); /* set layers OK */ newbase = BASACT; @@ -1796,7 +1799,7 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase DAG_relations_tag_update(bmain); if ((ob->type == OB_ARMATURE) && (pchan)) { - ob->pose->flag |= POSE_RECALC; /* sort pose channels */ + BKE_pose_tag_recalc(bmain, ob->pose); /* sort pose channels */ if (BKE_constraints_proxylocked_owner(ob, pchan) && ob->adt) { /* We need to make use of ugly POSE_ANIMATION_WORKAROUND here too, else anim data are not reloaded * after calling `BKE_pose_rebuild()`, which causes T43872. diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index b39e8470a95..d6a1694b4b0 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -29,8 +29,6 @@ * \ingroup edobj */ -#include "MEM_guardedalloc.h" - #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" @@ -59,7 +57,6 @@ #include "ED_object.h" #include "UI_interface.h" -#include "UI_resources.h" #include "object_intern.h" @@ -325,7 +322,7 @@ static bool data_transfer_exec_is_object_valid( static int data_transfer_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Object *ob_src = CTX_data_active_object(C); + Object *ob_src = ED_object_active_context(C); ListBase ctx_objects; CollectionPointerLink *ctx_ob_dst; @@ -419,7 +416,7 @@ static int data_transfer_exec(bContext *C, wmOperator *op) /* Note this context poll is only really partial, it cannot check for all possible invalid cases. */ static int data_transfer_poll(bContext *C) { - Object *ob = ED_object_context(C); + Object *ob = ED_object_active_context(C); ID *data = (ob) ? ob->data : NULL; return (ob && ob->type == OB_MESH && data); } @@ -534,7 +531,7 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot) /* Mapping options and filtering. */ RNA_def_boolean(ot->srna, "use_object_transform", true, "Object Transform", - "Evaluate source and destination meshes in their respective object spaces"); + "Evaluate source and destination meshes in global space"); RNA_def_boolean(ot->srna, "use_max_distance", false, "Only Neighbor Geometry", "Source elements must be closer than given distance from destination one"); prop = RNA_def_float(ot->srna, "max_distance", 1.0f, 0.0f, FLT_MAX, "Max Distance", diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index f7d51eb403f..3499a3cc364 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -65,6 +65,7 @@ #include "BKE_curve.h" #include "BKE_effect.h" #include "BKE_depsgraph.h" +#include "BKE_global.h" #include "BKE_image.h" #include "BKE_lattice.h" #include "BKE_library.h" @@ -318,7 +319,7 @@ void OBJECT_OT_hide_render_set(wmOperatorType *ot) * Load EditMode data back into the object, * optionally freeing the editmode data. */ -static bool ED_object_editmode_load_ex(Object *obedit, const bool freedata) +static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool freedata) { if (obedit == NULL) { return false; @@ -348,6 +349,11 @@ static bool ED_object_editmode_load_ex(Object *obedit, const bool freedata) ED_armature_from_edit(obedit->data); if (freedata) ED_armature_edit_free(obedit->data); + /* TODO(sergey): Pose channels might have been changed, so need + * to inform dependency graph about this. But is it really the + * best place to do this? + */ + DAG_relations_tag_update(bmain); } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { load_editNurb(obedit); @@ -376,7 +382,8 @@ static bool ED_object_editmode_load_ex(Object *obedit, const bool freedata) bool ED_object_editmode_load(Object *obedit) { - return ED_object_editmode_load_ex(obedit, false); + /* TODO(sergey): use proper main here? */ + return ED_object_editmode_load_ex(G.main, obedit, false); } void ED_object_editmode_exit(bContext *C, int flag) @@ -389,7 +396,7 @@ void ED_object_editmode_exit(bContext *C, int flag) if (flag & EM_WAITCURSOR) waitcursor(1); - if (ED_object_editmode_load_ex(obedit, freedata) == false) { + if (ED_object_editmode_load_ex(CTX_data_main(C), obedit, freedata) == false) { /* in rare cases (background mode) its possible active object * is flagged for editmode, without 'obedit' being set [#35489] */ if (UNLIKELY(scene->basact && (scene->basact->object->mode & OB_MODE_EDIT))) { @@ -898,6 +905,8 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) base->object->rdamping = ob->rdamping; base->object->min_vel = ob->min_vel; base->object->max_vel = ob->max_vel; + base->object->min_angvel = ob->min_angvel; + base->object->max_angvel = ob->max_angvel; if (ob->gameflag & OB_BOUNDS) { base->object->collision_boundtype = ob->collision_boundtype; } @@ -1769,6 +1778,77 @@ 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 GAME_PROPERTY_MOVE_UP 1 +#define GAME_PROPERTY_MOVE_DOWN -1 + +static int game_property_move(bContext *C, wmOperator *op) +{ + Object *ob = CTX_data_active_object(C); + bProperty *prop; + bProperty *otherprop = NULL; + const int index = RNA_int_get(op->ptr, "index"); + const int dir = RNA_enum_get(op->ptr, "direction"); + + if (ob == NULL) + return OPERATOR_CANCELLED; + + prop = BLI_findlink(&ob->prop, index); + /* invalid index */ + if (prop == NULL) + return OPERATOR_CANCELLED; + + if (dir == GAME_PROPERTY_MOVE_UP) { + otherprop = prop->prev; + } + else if (dir == GAME_PROPERTY_MOVE_DOWN) { + otherprop = prop->next; + } + else { + BLI_assert(0); + } + + if (prop && otherprop) { + BLI_listbase_swaplinks(&ob->prop, prop, otherprop); + + WM_event_add_notifier(C, NC_LOGIC, NULL); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void OBJECT_OT_game_property_move(wmOperatorType *ot) +{ + static EnumPropertyItem direction_property_move[] = { + {GAME_PROPERTY_MOVE_UP, "UP", 0, "Up", ""}, + {GAME_PROPERTY_MOVE_DOWN, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL} + }; + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Move Game Property"; + ot->description = "Move game property"; + ot->idname = "OBJECT_OT_game_property_move"; + + /* api callbacks */ + ot->exec = game_property_move; + ot->poll = ED_operator_object_active_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Property index to move", 0, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN); + RNA_def_enum(ot->srna, "direction", direction_property_move, 0, "Direction", + "Direction for moving the property"); +} + +#undef GAME_PROPERTY_MOVE_UP +#undef GAME_PROPERTY_MOVE_DOWN + #define COPY_PROPERTIES_REPLACE 1 #define COPY_PROPERTIES_MERGE 2 #define COPY_PROPERTIES_COPY 3 @@ -1966,6 +2046,8 @@ static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op)) ob_iter->rdamping = ob->rdamping; ob_iter->min_vel = ob->min_vel; ob_iter->max_vel = ob->max_vel; + ob_iter->min_angvel = ob->min_angvel; + ob_iter->max_angvel = ob->max_angvel; ob_iter->obstacleRad = ob->obstacleRad; ob_iter->mass = ob->mass; copy_v3_v3(ob_iter->anisotropicFriction, ob->anisotropicFriction); diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index 1d764ced524..8797b75a801 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -448,11 +448,12 @@ static Object *add_hook_object_new(Main *bmain, Scene *scene, Object *obedit) Base *base, *basedit; Object *ob; - ob = BKE_object_add(bmain, scene, OB_EMPTY); + ob = BKE_object_add(bmain, scene, OB_EMPTY, NULL); basedit = BKE_scene_base_find(scene, obedit); - base = BKE_scene_base_find(scene, ob); + base = scene->basact; base->lay = ob->lay = obedit->lay; + BLI_assert(scene->basact->object == ob); /* icky, BKE_object_add sets new base as active. * so set it back to the original edit object */ diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 64fddf1b6a1..6344e04ef1b 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -32,17 +32,12 @@ #define __OBJECT_INTERN_H__ struct wmOperatorType; -struct KeyBlock; -struct Lattice; -struct Curve; struct Object; -struct Mesh; struct bContext; struct StructRNA; struct wmOperator; struct ModifierData; -struct HookModifierData; /* add hook menu */ enum eObject_Hook_Add_Mode { @@ -99,6 +94,7 @@ 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_game_property_move(struct wmOperatorType *ot); void OBJECT_OT_logic_bricks_copy(struct wmOperatorType *ot); void OBJECT_OT_game_physics_copy(struct wmOperatorType *ot); @@ -179,6 +175,7 @@ void OBJECT_OT_multires_higher_levels_delete(struct wmOperatorType *ot); void OBJECT_OT_multires_base_apply(struct wmOperatorType *ot); void OBJECT_OT_multires_external_save(struct wmOperatorType *ot); void OBJECT_OT_multires_external_pack(struct wmOperatorType *ot); +void OBJECT_OT_correctivesmooth_bind(struct wmOperatorType *ot); void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot); void OBJECT_OT_explode_refresh(struct wmOperatorType *ot); void OBJECT_OT_ocean_bake(struct wmOperatorType *ot); @@ -233,7 +230,7 @@ void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_lock(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot); -void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_smooth(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_quantize(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_limit_total(struct wmOperatorType *ot); @@ -248,7 +245,7 @@ void OBJECT_OT_vertex_weight_normalize_active_vertex(struct wmOperatorType *ot); void OBJECT_OT_vertex_weight_copy(struct wmOperatorType *ot); /* object_warp.c */ -void OBJECT_OT_vertex_warp(struct wmOperatorType *ot); +void TRANSFORM_OT_vertex_warp(struct wmOperatorType *ot); /* object_shapekey.c */ void OBJECT_OT_shape_key_add(struct wmOperatorType *ot); @@ -274,7 +271,7 @@ void OBJECT_OT_lod_add(struct wmOperatorType *ot); void OBJECT_OT_lod_remove(struct wmOperatorType *ot); /* object_random.c */ -void OBJECT_OT_vertex_random(struct wmOperatorType *ot); +void TRANSFORM_OT_vertex_random(struct wmOperatorType *ot); /* object_transfer_data.c */ void OBJECT_OT_data_transfer(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index b577dab8a77..76d9facf701 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -713,7 +713,7 @@ static int lattice_flip_exec(bContext *C, wmOperator *op) break; default: - printf("lattice_flip(): Unknown flipping axis (%d)\n", axis); + printf("lattice_flip(): Unknown flipping axis (%u)\n", axis); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 710cf2dbdd2..ce9693793a4 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -96,7 +96,7 @@ static void modifier_skin_customdata_delete(struct Object *ob); ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type) { ModifierData *md = NULL, *new_md = NULL; - ModifierTypeInfo *mti = modifierType_getInfo(type); + const ModifierTypeInfo *mti = modifierType_getInfo(type); /* only geometry objects should be able to get modifiers [#25291] */ if (!ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { @@ -152,10 +152,10 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc ob->pd = object_add_collision_fields(0); ob->pd->deflect = 1; - DAG_relations_tag_update(bmain); } - else if (type == eModifierType_Surface) - DAG_relations_tag_update(bmain); + else if (type == eModifierType_Surface) { + /* pass */ + } else if (type == eModifierType_Multires) { /* set totlvl from existing MDISPS layer if object already had it */ multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob); @@ -172,6 +172,7 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DAG_relations_tag_update(bmain); return new_md; } @@ -247,7 +248,7 @@ static bool object_has_modifier_cb(Object *ob, void *data) bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v) { ModifierData *md; - int totlevel = *((int *)totlevel_v); + int totlevel = *((char *)totlevel_v); for (md = ob->modifiers.first; md; md = md->next) { if (md->type == eModifierType_Multires) { @@ -319,6 +320,8 @@ static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md, ob->mode &= ~OB_MODE_PARTICLE_EDIT; } + DAG_relations_tag_update(bmain); + BLI_remlink(&ob->modifiers, md); modifier_free(md); @@ -368,10 +371,10 @@ void ED_object_modifier_clear(Main *bmain, Object *ob) int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md) { if (md->prev) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (mti->type != eModifierTypeType_OnlyDeform) { - ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type); + const ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type); if (nmti->flags & eModifierTypeFlag_RequiresOriginalData) { BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data"); @@ -389,10 +392,10 @@ int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md) { if (md->next) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (mti->flags & eModifierTypeFlag_RequiresOriginalData) { - ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type); + const ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type); if (nmti->type != eModifierTypeType_OnlyDeform) { BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier"); @@ -459,7 +462,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene * if (totvert == 0) return 0; /* add new mesh */ - obn = BKE_object_add(bmain, scene, OB_MESH); + obn = BKE_object_add(bmain, scene, OB_MESH, NULL); me = obn->data; me->totvert = totvert; @@ -518,7 +521,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene * static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene = scene; @@ -578,7 +581,7 @@ 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); + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene = scene; @@ -742,7 +745,7 @@ static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr) { Object *ob = ED_object_active_context(C); EnumPropertyItem *item = NULL, *md_item, *group_item = NULL; - ModifierTypeInfo *mti; + const ModifierTypeInfo *mti; int totitem = 0, a; if (!ob) @@ -1704,7 +1707,7 @@ static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object * NULL, me->totvert); - arm_ob = BKE_object_add(bmain, scene, OB_ARMATURE); + arm_ob = BKE_object_add(bmain, scene, OB_ARMATURE, NULL); BKE_object_transform_copy(arm_ob, skin_ob); arm = arm_ob->data; arm->layer = 1; @@ -1815,6 +1818,73 @@ void OBJECT_OT_skin_armature_create(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; edit_modifier_properties(ot); } +/************************ delta mush bind operator *********************/ + +static int correctivesmooth_poll(bContext *C) +{ + return edit_modifier_poll_generic(C, &RNA_CorrectiveSmoothModifier, 0); +} + +static int correctivesmooth_bind_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *ob = ED_object_active_context(C); + CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)edit_modifier_property_get(op, ob, eModifierType_CorrectiveSmooth); + bool is_bind; + + if (!csmd) { + return OPERATOR_CANCELLED; + } + + if (!modifier_isEnabled(scene, &csmd->modifier, eModifierMode_Realtime)) { + BKE_report(op->reports, RPT_ERROR, "Modifier is disabled"); + return OPERATOR_CANCELLED; + } + + is_bind = (csmd->bind_coords != NULL); + + MEM_SAFE_FREE(csmd->bind_coords); + MEM_SAFE_FREE(csmd->delta_cache); + + if (is_bind) { + /* toggle off */ + csmd->bind_coords_num = 0; + } + else { + /* signal to modifier to recalculate */ + csmd->bind_coords_num = (unsigned int)-1; + } + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (edit_modifier_invoke_properties(C, op)) + return correctivesmooth_bind_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_correctivesmooth_bind(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Corrective Smooth Bind"; + ot->description = "Bind base pose in Corrective Smooth modifier"; + ot->idname = "OBJECT_OT_correctivesmooth_bind"; + + /* api callbacks */ + ot->poll = correctivesmooth_poll; + ot->invoke = correctivesmooth_bind_invoke; + ot->exec = correctivesmooth_bind_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_modifier_properties(ot); +} /************************ mdef bind operator *********************/ @@ -1978,7 +2048,7 @@ static void init_ocean_modifier_bake(struct Ocean *oc, struct OceanModifierData do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS); do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM); - BKE_init_ocean(oc, omd->resolution * omd->resolution, omd->resolution * omd->resolution, omd->spatial_size, omd->spatial_size, + BKE_ocean_init(oc, omd->resolution * omd->resolution, omd->resolution * omd->resolution, omd->spatial_size, omd->spatial_size, omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment, omd->depth, omd->time, do_heightfield, do_chop, do_normals, do_jacobian, @@ -2036,7 +2106,7 @@ static void oceanbake_startjob(void *customdata, short *stop, short *do_update, G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */ - BKE_bake_ocean(oj->ocean, oj->och, oceanbake_update, (void *)oj); + BKE_ocean_bake(oj->ocean, oj->och, oceanbake_update, (void *)oj); *do_update = true; *stop = 0; @@ -2047,7 +2117,7 @@ static void oceanbake_endjob(void *customdata) OceanBakeJob *oj = customdata; if (oj->ocean) { - BKE_free_ocean(oj->ocean); + BKE_ocean_free(oj->ocean); oj->ocean = NULL; } @@ -2078,7 +2148,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - och = BKE_init_ocean_cache(omd->cachepath, modifier_path_relbase(ob), + och = BKE_ocean_init_cache(omd->cachepath, modifier_path_relbase(ob), omd->bakestart, omd->bakeend, omd->wave_scale, omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution); @@ -2112,11 +2182,11 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) } /* make a copy of ocean to use for baking - threadsafety */ - ocean = BKE_add_ocean(); + ocean = BKE_ocean_add(); init_ocean_modifier_bake(ocean, omd); #if 0 - BKE_bake_ocean(ocean, och); + BKE_ocean_bake(ocean, och); omd->oceancache = och; omd->cached = true; diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 15eb9090ce5..22cac8638d9 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -144,6 +144,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_skin_radii_equalize); WM_operatortype_append(OBJECT_OT_skin_armature_create); + WM_operatortype_append(OBJECT_OT_correctivesmooth_bind); WM_operatortype_append(OBJECT_OT_meshdeform_bind); WM_operatortype_append(OBJECT_OT_explode_refresh); WM_operatortype_append(OBJECT_OT_ocean_bake); @@ -185,7 +186,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_fix); WM_operatortype_append(OBJECT_OT_vertex_group_invert); WM_operatortype_append(OBJECT_OT_vertex_group_levels); - WM_operatortype_append(OBJECT_OT_vertex_group_blend); + WM_operatortype_append(OBJECT_OT_vertex_group_smooth); WM_operatortype_append(OBJECT_OT_vertex_group_clean); WM_operatortype_append(OBJECT_OT_vertex_group_quantize); WM_operatortype_append(OBJECT_OT_vertex_group_limit_total); @@ -199,12 +200,13 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_weight_normalize_active_vertex); WM_operatortype_append(OBJECT_OT_vertex_weight_copy); - WM_operatortype_append(OBJECT_OT_vertex_warp); + WM_operatortype_append(TRANSFORM_OT_vertex_warp); 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_game_property_move); WM_operatortype_append(OBJECT_OT_logic_bricks_copy); WM_operatortype_append(OBJECT_OT_game_physics_copy); @@ -247,7 +249,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_lod_add); WM_operatortype_append(OBJECT_OT_lod_remove); - WM_operatortype_append(OBJECT_OT_vertex_random); + WM_operatortype_append(TRANSFORM_OT_vertex_random); WM_operatortype_append(OBJECT_OT_data_transfer); WM_operatortype_append(OBJECT_OT_datalayout_transfer); diff --git a/source/blender/editors/object/object_random.c b/source/blender/editors/object/object_random.c index 41b26b98047..a293f7a950e 100644 --- a/source/blender/editors/object/object_random.c +++ b/source/blender/editors/object/object_random.c @@ -124,12 +124,12 @@ static int object_rand_verts_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void OBJECT_OT_vertex_random(struct wmOperatorType *ot) +void TRANSFORM_OT_vertex_random(struct wmOperatorType *ot) { /* identifiers */ ot->name = "Randomize"; ot->description = "Randomize vertices"; - ot->idname = "OBJECT_OT_vertex_random"; + ot->idname = "TRANSFORM_OT_vertex_random"; /* api callbacks */ ot->exec = object_rand_verts_exec; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index bfa501c3732..c2d2bffbbe5 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -342,12 +342,10 @@ static int make_proxy_exec(bContext *C, wmOperator *op) Base *newbase, *oldbase = BASACT; char name[MAX_ID_NAME + 4]; - /* Add new object for the proxy */ - newob = BKE_object_add(bmain, scene, OB_EMPTY); - BLI_snprintf(name, sizeof(name), "%s_proxy", ((ID *)(gob ? gob : ob))->name + 2); - rename_id(&newob->id, name); + /* Add new object for the proxy */ + newob = BKE_object_add(bmain, scene, OB_EMPTY, name); /* set layers OK */ newbase = BASACT; /* BKE_object_add sets active... */ @@ -573,6 +571,9 @@ void ED_object_parent(Object *ob, Object *par, const int type, const char *subst return; } + /* Other partypes are deprecated, do not use here! */ + BLI_assert(ELEM(type & PARTYPE, PAROBJECT, PARSKEL, PARVERT1, PARVERT3, PARBONE)); + /* this could use some more checks */ ob->parent = par; @@ -1574,13 +1575,13 @@ static int make_links_data_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob_dst->id, 0); break; case MAKE_LINKS_ANIMDATA: - BKE_copy_animdata_id((ID *)ob_dst, (ID *)ob_src, false); + BKE_animdata_copy_id((ID *)ob_dst, (ID *)ob_src, false); if (ob_dst->data && ob_src->data) { if (obdata_id->lib) { is_lib = true; break; } - BKE_copy_animdata_id((ID *)ob_dst->data, (ID *)ob_src->data, false); + BKE_animdata_copy_id((ID *)ob_dst->data, (ID *)ob_src->data, false); } DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); break; @@ -1871,7 +1872,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag) case OB_MESH: ob->data = me = BKE_mesh_copy(ob->data); if (me->key) - BKE_copy_animdata_id_action((ID *)me->key); + BKE_animdata_copy_id_action((ID *)me->key); break; case OB_MBALL: ob->data = BKE_mball_copy(ob->data); @@ -1883,12 +1884,12 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag) ID_NEW(cu->bevobj); ID_NEW(cu->taperobj); if (cu->key) - BKE_copy_animdata_id_action((ID *)cu->key); + BKE_animdata_copy_id_action((ID *)cu->key); break; case OB_LATTICE: ob->data = lat = BKE_lattice_copy(ob->data); if (lat->key) - BKE_copy_animdata_id_action((ID *)lat->key); + BKE_animdata_copy_id_action((ID *)lat->key); break; case OB_ARMATURE: DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -1909,7 +1910,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag) * AnimData structure, which is not what we want. * (sergey) */ - BKE_copy_animdata_id_action((ID *)ob->data); + BKE_animdata_copy_id_action((ID *)ob->data); id->us--; id->newid = ob->data; @@ -1933,7 +1934,7 @@ static void single_object_action_users(Scene *scene, const int flag) ob = base->object; if (ob->id.lib == NULL && (flag == 0 || (base->flag & SELECT)) ) { DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - BKE_copy_animdata_id_action(&ob->id); + BKE_animdata_copy_id_action(&ob->id); } } } @@ -1956,7 +1957,7 @@ static void single_mat_users(Scene *scene, const int flag, const bool do_texture if (ma->id.us > 1) { man = BKE_material_copy(ma); - BKE_copy_animdata_id_action(&man->id); + BKE_animdata_copy_id_action(&man->id); man->id.us = 0; assign_material(ob, man, a, BKE_MAT_ASSIGN_USERPREF); @@ -1967,7 +1968,7 @@ static void single_mat_users(Scene *scene, const int flag, const bool do_texture if (tex->id.us > 1) { tex->id.us--; tex = BKE_texture_copy(tex); - BKE_copy_animdata_id_action(&tex->id); + BKE_animdata_copy_id_action(&tex->id); man->mtex[b]->tex = tex; } } @@ -1994,7 +1995,7 @@ static void do_single_tex_user(Tex **from) } else if (tex->id.us > 1) { texn = BKE_texture_copy(tex); - BKE_copy_animdata_id_action(&texn->id); + BKE_animdata_copy_id_action(&texn->id); tex->id.newid = (ID *)texn; tex->id.us--; *from = texn; diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 674eb25942f..ed71af71ac9 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -48,7 +48,6 @@ #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_scene_types.h" #include "DNA_object_types.h" #include "BKE_context.h" @@ -78,7 +77,7 @@ static void ED_object_shape_key_add(bContext *C, Object *ob, const bool from_mix) { KeyBlock *kb; - if ((kb = BKE_object_insert_shape_key(ob, NULL, from_mix))) { + if ((kb = BKE_object_shapekey_insert(ob, NULL, from_mix))) { Key *key = BKE_key_from_object(ob); /* for absolute shape keys, new keys may not be added last */ ob->shapenr = BLI_findindex(&key->block, kb) + 1; @@ -89,89 +88,21 @@ static void ED_object_shape_key_add(bContext *C, Object *ob, const bool from_mix /*********************** remove shape key ***********************/ -static bool ED_object_shape_key_remove_all(Main *bmain, Object *ob) +static bool object_shapekey_remove(Main *bmain, Object *ob) { - Key *key; + KeyBlock *kb; + Key *key = BKE_key_from_object(ob); - key = BKE_key_from_object(ob); - if (key == NULL) + if (key == NULL) { return false; - - switch (GS(key->from->name)) { - case ID_ME: ((Mesh *)key->from)->key = NULL; break; - case ID_CU: ((Curve *)key->from)->key = NULL; break; - case ID_LT: ((Lattice *)key->from)->key = NULL; break; } - BKE_libblock_free_us(bmain, key); - - return true; -} - -static bool ED_object_shape_key_remove(Main *bmain, Object *ob) -{ - KeyBlock *kb, *rkb; - Key *key; - - key = BKE_key_from_object(ob); - if (key == NULL) - return false; - kb = BLI_findlink(&key->block, ob->shapenr - 1); - if (kb) { - for (rkb = key->block.first; rkb; rkb = rkb->next) { - if (rkb->relative == ob->shapenr - 1) { - /* remap to the 'Basis' */ - rkb->relative = 0; - } - else if (rkb->relative >= ob->shapenr) { - /* Fix positional shift of the keys when kb is deleted from the list */ - rkb->relative -= 1; - } - } - - BLI_remlink(&key->block, kb); - key->totkey--; - if (key->refkey == kb) { - key->refkey = key->block.first; - - if (key->refkey) { - /* apply new basis key on original data */ - switch (ob->type) { - case OB_MESH: - BKE_keyblock_convert_to_mesh(key->refkey, ob->data); - break; - case OB_CURVE: - case OB_SURF: - BKE_keyblock_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data)); - break; - case OB_LATTICE: - BKE_keyblock_convert_to_lattice(key->refkey, ob->data); - break; - } - } - } - - if (kb->data) MEM_freeN(kb->data); - MEM_freeN(kb); - - if (ob->shapenr > 1) { - ob->shapenr--; - } - } - - if (key->totkey == 0) { - switch (GS(key->from->name)) { - case ID_ME: ((Mesh *)key->from)->key = NULL; break; - case ID_CU: ((Curve *)key->from)->key = NULL; break; - case ID_LT: ((Lattice *)key->from)->key = NULL; break; - } - - BKE_libblock_free_us(bmain, key); + return BKE_object_shapekey_remove(bmain, ob, kb); } - return true; + return false; } static bool object_shape_key_mirror(bContext *C, Object *ob, @@ -333,6 +264,7 @@ static int shape_key_add_exec(bContext *C, wmOperator *op) ED_object_shape_key_add(C, ob, from_mix); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DAG_relations_tag_update(CTX_data_main(C)); return OPERATOR_FINISHED; } @@ -362,14 +294,15 @@ static int shape_key_remove_exec(bContext *C, wmOperator *op) bool changed = false; if (RNA_boolean_get(op->ptr, "all")) { - changed = ED_object_shape_key_remove_all(bmain, ob); + changed = BKE_object_shapekey_free(bmain, ob); } else { - changed = ED_object_shape_key_remove(bmain, ob); + changed = object_shapekey_remove(bmain, ob); } if (changed) { DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DAG_relations_tag_update(CTX_data_main(C)); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 92fe5ded4dd..340b662c0ef 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -939,8 +939,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* convert the offset to parent space */ BKE_object_to_mat4(ob, obmat); - copy_v3_v3(centn, cent); - mul_mat3_m4_v3(obmat, centn); /* omit translation part */ + mul_v3_mat3_m4v3(centn, obmat, cent); /* omit translation part */ add_v3_v3(ob->loc, centn); @@ -970,8 +969,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) ob_other->flag |= OB_DONE; DAG_id_tag_update(&ob_other->id, OB_RECALC_OB | OB_RECALC_DATA); - copy_v3_v3(centn, cent); - mul_mat3_m4_v3(ob_other->obmat, centn); /* omit translation part */ + mul_v3_mat3_m4v3(centn, ob_other->obmat, cent); /* omit translation part */ add_v3_v3(ob_other->loc, centn); BKE_object_where_is_calc(scene, ob_other); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index f885cbbb24f..f2b2923ee0d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -50,6 +50,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_linklist_stack.h" +#include "BLI_stackdefines.h" #include "BKE_context.h" @@ -427,6 +428,48 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from) return true; } +void ED_vgroup_parray_to_weight_array( + const MDeformVert **dvert_array, const int dvert_tot, + float *dvert_weights, const int def_nr) +{ + int i; + + for (i = 0; i < dvert_tot; i++) { + const MDeformVert *dv = dvert_array[i]; + dvert_weights[i] = dv ? defvert_find_weight(dv, def_nr) : 0.0f; + } +} + +void ED_vgroup_parray_from_weight_array( + MDeformVert **dvert_array, const int dvert_tot, + const float *dvert_weights, const int def_nr, const bool remove_zero) +{ + int i; + + for (i = 0; i < dvert_tot; i++) { + MDeformVert *dv = dvert_array[i]; + if (dv) { + if (dvert_weights[i] > 0.0f) { + MDeformWeight *dw = defvert_verify_index(dv, def_nr); + BLI_assert(IN_RANGE_INCL(dvert_weights[i], 0.0f, 1.0f)); + dw->weight = dvert_weights[i]; + } + else { + MDeformWeight *dw = defvert_find_index(dv, def_nr); + if (dw) { + if (remove_zero) { + defvert_remove_group(dv, dw); + } + else { + dw->weight = 0.0f; + } + } + } + } + } +} + + /* TODO, cache flip data to speedup calls within a loop. */ static void mesh_defvert_mirror_update_internal(Object *ob, MDeformVert *dvert_dst, MDeformVert *dvert_src, @@ -1177,7 +1220,7 @@ static void getVerticalAndHorizontalChange(const float norm[3], float d, const f dists[index] = dot_v3v3(norm, end) + d; /* vertical change */ changes[index][0] = dists[index] - distToStart; - //printf("vc %f %f\n", distance(end, projB, 3)-distance(start, projA, 3), changes[index][0]); + //printf("vc %f %f\n", distance(end, projB, 3) - distance(start, projA, 3), changes[index][0]); /* horizontal change */ changes[index][1] = len_v3v3(projA, projB); } @@ -1631,9 +1674,17 @@ static void vgroup_invert_subset(Object *ob, } } -static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot, - const int subset_count, - const float fac) +enum { + WEIGHT_SMOOTH_ALL = -1, + WEIGHT_SMOOTH_DESELECT = false, + WEIGHT_SMOOTH_SELECT = true, +}; + +static void vgroup_smooth_subset( + Object *ob, const bool *vgroup_validmap, const int vgroup_tot, + const int subset_count, + const float fac, const int repeat, + const float fac_expand, const int source) { const float ifac = 1.0f - fac; MDeformVert **dvert_array = NULL; @@ -1642,6 +1693,10 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i float *vgroup_subset_weights = BLI_array_alloca(vgroup_subset_weights, subset_count); const bool use_mirror = (ob->type == OB_MESH) ? (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X) != 0 : false; + const int expand_sign = signum_i(fac_expand); + const float expand = fabsf(fac_expand); + const float iexpand = 1.0f - expand; + BMEditMesh *em = BKE_editmesh_from_object(ob); BMesh *bm = em ? em->bm : NULL; Mesh *me = em ? NULL : ob->data; @@ -1649,7 +1704,15 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i MeshElemMap *emap; int *emap_mem; - BLI_SMALLSTACK_DECLARE(dv_stack, MDeformVert *); + float *weight_accum_prev; + float *weight_accum_curr; + + unsigned int subset_index; + + /* vertex indices that will be smoothed, (only to avoid iterating over verts that do nothing) */ + unsigned int *verts_used; + STACK_DECLARE(verts_used); + BKE_object_defgroup_subset_to_index_array(vgroup_validmap, vgroup_tot, vgroup_subset_map); ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false); @@ -1657,87 +1720,159 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i if (bm) { BM_mesh_elem_table_ensure(bm, BM_VERT); + BM_mesh_elem_index_ensure(bm, BM_VERT); emap = NULL; emap_mem = NULL; } else { - BKE_mesh_vert_edge_map_create(&emap, &emap_mem, - me->medge, me->totvert, me->totedge); + BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge); } + weight_accum_prev = MEM_mallocN(sizeof(*weight_accum_prev) * dvert_tot, __func__); + weight_accum_curr = MEM_mallocN(sizeof(*weight_accum_curr) * dvert_tot, __func__); + + verts_used = MEM_mallocN(sizeof(*verts_used) * dvert_tot, __func__); + STACK_INIT(verts_used, dvert_tot); - for (i = 0; i < dvert_tot; i++) { - MDeformVert *dv; - int dv_stack_tot = 0; - int j; - /* in case its not selected */ - if (bm) { + /* initialize used verts */ + if (bm) { + for (i = 0; i < dvert_tot; i++) { BMVert *v = BM_vert_at_index(bm, i); if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { BMIter eiter; BMEdge *e; BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { BMVert *v_other = BM_edge_other_vert(e, v); - const int i_other = BM_elem_index_get(v_other); - - if (BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) { - dv = dvert_array[i_other]; - BLI_SMALLSTACK_PUSH(dv_stack, dv); - dv_stack_tot++; + if ((source == WEIGHT_SMOOTH_ALL) || + (source == (BM_elem_flag_test(v_other, BM_ELEM_SELECT) != 0))) + { + STACK_PUSH(verts_used, i); + break; } } } } - else { + } + else { + for (i = 0; i < dvert_tot; i++) { MVert *v = &me->mvert[i]; if (v->flag & SELECT) { + int j; for (j = 0; j < emap[i].count; j++) { MEdge *e = &me->medge[emap[i].indices[j]]; const int i_other = (e->v1 == i ? e->v2 : e->v1); MVert *v_other = &me->mvert[i_other]; - - if ((v_other->flag & SELECT) == 0) { - dv = dvert_array[i_other]; - BLI_SMALLSTACK_PUSH(dv_stack, dv); - dv_stack_tot++; + if ((source == WEIGHT_SMOOTH_ALL) || + (source == ((v_other->flag & SELECT) != 0))) + { + STACK_PUSH(verts_used, i); + break; } } } } + } - if (dv_stack_tot) { - const float dv_mul = 1.0f / (float)dv_stack_tot; - - /* vgroup_subset_weights is zero'd at this point */ - while ((dv = BLI_SMALLSTACK_POP(dv_stack))) { - for (j = 0; j < subset_count; j++) { - vgroup_subset_weights[j] += dv_mul * defvert_find_weight(dv, vgroup_subset_map[j]); - } - } - - dv = dvert_array[i]; - for (j = 0; j < subset_count; j++) { - MDeformWeight *dw; - if (vgroup_subset_weights[j] > 0.0f) { - dw = defvert_verify_index(dv, vgroup_subset_map[j]); + for (subset_index = 0; subset_index < subset_count; subset_index++) { + const int def_nr = vgroup_subset_map[subset_index]; + int iter; + + ED_vgroup_parray_to_weight_array((const MDeformVert **)dvert_array, dvert_tot, weight_accum_prev, def_nr); + memcpy(weight_accum_curr, weight_accum_prev, sizeof(*weight_accum_curr) * dvert_tot); + + for (iter = 0; iter < repeat; iter++) { + unsigned *vi_step, *vi_end = verts_used + STACK_SIZE(verts_used); + + /* avoid looping over all verts */ + // for (i = 0; i < dvert_tot; i++) + for (vi_step = verts_used; vi_step != vi_end; vi_step++) { + const unsigned int i = *vi_step; + float weight_tot = 0.0f; + float weight = 0.0f; + +#define WEIGHT_ACCUMULATE \ + { \ + float weight_other = weight_accum_prev[i_other]; \ + float tot_factor = 1.0f; \ + if (expand_sign == 1) { /* expand */ \ + if (weight_other < weight_accum_prev[i]) { \ + weight_other = (weight_accum_prev[i_other] * iexpand) + (weight_other * expand); \ + tot_factor = iexpand; \ + } \ + } \ + else if (expand_sign == -1) { /* contract */ \ + if (weight_other > weight_accum_prev[i]) { \ + weight_other = (weight_accum_prev[i_other] * iexpand) + (weight_other * expand); \ + tot_factor = iexpand; \ + } \ + } \ + weight += tot_factor * weight_other; \ + weight_tot += tot_factor; \ + } ((void)0) + + + if (bm) { + BMVert *v = BM_vert_at_index(bm, i); + BMIter eiter; + BMEdge *e; + + /* checked already */ + BLI_assert(BM_elem_flag_test(v, BM_ELEM_SELECT)); + + BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { + BMVert *v_other = BM_edge_other_vert(e, v); + if ((source == WEIGHT_SMOOTH_ALL) || + (source == (BM_elem_flag_test(v_other, BM_ELEM_SELECT) != 0))) + { + const int i_other = BM_elem_index_get(v_other); + + WEIGHT_ACCUMULATE; + } + } } else { - dw = defvert_find_index(dv, vgroup_subset_map[j]); - } + int j; - if (dw) { - dw->weight = (fac * vgroup_subset_weights[j]) + (ifac * dw->weight); - CLAMP(dw->weight, 0.0f, 1.0f); + /* checked already */ + BLI_assert(me->mvert[i].flag & SELECT); + + for (j = 0; j < emap[i].count; j++) { + MEdge *e = &me->medge[emap[i].indices[j]]; + const int i_other = (e->v1 == i ? e->v2 : e->v1); + MVert *v_other = &me->mvert[i_other]; + + if ((source == WEIGHT_SMOOTH_ALL) || + (source == ((v_other->flag & SELECT) != 0))) + { + WEIGHT_ACCUMULATE; + } + } } - /* zero for next iteration */ - vgroup_subset_weights[j] = 0.0f; +#undef WEIGHT_ACCUMULATE + + if (weight_tot != 0.0f) { + weight /= weight_tot; + weight = (weight_accum_prev[i] * ifac) + (weight * fac); + + /* should be within range, just clamp because of float precision */ + CLAMP(weight, 0.0f, 1.0f); + weight_accum_curr[i] = weight; + } } + + SWAP(float *, weight_accum_curr, weight_accum_prev); } + + ED_vgroup_parray_from_weight_array(dvert_array, dvert_tot, weight_accum_prev, def_nr, true); } + MEM_freeN(weight_accum_curr); + MEM_freeN(weight_accum_prev); + MEM_freeN(verts_used); + if (bm) { /* pass */ } @@ -2062,7 +2197,7 @@ void ED_vgroup_mirror(Object *ob, /* object mode / weight paint */ MVert *mv, *mv_mirr; int vidx, vidx_mirr; - const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; + const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; if (me->dvert == NULL) { goto cleanup; @@ -2315,16 +2450,43 @@ static int UNUSED_FUNCTION(vertex_group_poll_edit) (bContext *C) } /* editmode _or_ weight paint vertex sel */ -static int vertex_group_vert_select_poll(bContext *C) +static int vertex_group_vert_select_poll_ex(bContext *C, const short ob_type_flag) { Object *ob = ED_object_context(C); ID *data = (ob) ? ob->data : NULL; if (!(ob && !ob->id.lib && data && !data->lib)) - return 0; + return false; - return (BKE_object_is_in_editmode_vgroup(ob) || - BKE_object_is_in_wpaint_select_vert(ob)); + if (ob_type_flag && (((1 << ob->type) & ob_type_flag)) == 0) { + return false; + } + + if (BKE_object_is_in_editmode_vgroup(ob)) { + return true; + } + else if (ob->mode & OB_MODE_WEIGHT_PAINT) { + if (BKE_object_is_in_wpaint_select_vert(ob)) { + return true; + } + else { + CTX_wm_operator_poll_msg_set(C, "Vertex select needs to be enabled in weight paint mode"); + return false; + } + } + else { + return false; + } +} + +static int vertex_group_vert_select_poll(bContext *C) +{ + return vertex_group_vert_select_poll_ex(C, 0); +} + +static int vertex_group_mesh_vert_select_poll(bContext *C) +{ + return vertex_group_vert_select_poll_ex(C, (1 << OB_MESH)); } /* editmode _or_ weight paint vertex sel and active group unlocked */ @@ -2851,17 +3013,19 @@ void OBJECT_OT_vertex_group_invert(wmOperatorType *ot) "Remove verts from groups that have zero weight after inverting"); } - -static int vertex_group_blend_exec(bContext *C, wmOperator *op) +static int vertex_group_smooth_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); - float fac = RNA_float_get(op->ptr, "factor"); + const float fac = RNA_float_get(op->ptr, "factor"); + const int repeat = RNA_int_get(op->ptr, "repeat"); eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + const int source = RNA_enum_get(op->ptr, "source"); + const float fac_expand = RNA_float_get(op->ptr, "expand"); int subset_count, vgroup_tot; const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); - vgroup_blend_subset(ob, vgroup_validmap, vgroup_tot, subset_count, fac); + vgroup_smooth_subset(ob, vgroup_validmap, vgroup_tot, subset_count, fac, repeat, fac_expand, source); MEM_freeN((void *)vgroup_validmap); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -2871,60 +3035,34 @@ static int vertex_group_blend_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/* check we have a vertex selection, either in weight paint or editmode */ -static int vertex_group_blend_poll(bContext *C) +void OBJECT_OT_vertex_group_smooth(wmOperatorType *ot) { - Object *ob = ED_object_context(C); - ID *data = (ob) ? ob->data : NULL; - - if (!(ob && !ob->id.lib && data && !data->lib)) - return false; - - if (ob->type != OB_MESH) { - return false; - } - - if (BKE_object_is_in_editmode_vgroup(ob)) { - return true; - } - else if (ob->mode & OB_MODE_WEIGHT_PAINT) { - if (ME_EDIT_PAINT_SEL_MODE(((Mesh *)data)) == SCE_SELECT_VERTEX) { - return true; - } - else { - CTX_wm_operator_poll_msg_set(C, "Vertex select needs to be enabled in weight paint mode"); - return false; - } - - } - else { - return false; - } -} - -void OBJECT_OT_vertex_group_blend(wmOperatorType *ot) -{ - PropertyRNA *prop; + static EnumPropertyItem smooth_source_item[] = { + {WEIGHT_SMOOTH_ALL, "ALL", 0, "All", ""}, + {WEIGHT_SMOOTH_SELECT, "SELECT", 0, "Only Selected", ""}, + {WEIGHT_SMOOTH_DESELECT, "DESELECT", 0, "Only Deselected", ""}, + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ - ot->name = "Blend Vertex Group"; - ot->idname = "OBJECT_OT_vertex_group_blend"; - ot->description = "Blend selected vertex weights with unselected for the active group"; + ot->name = "Smooth Vertex Weights"; + ot->idname = "OBJECT_OT_vertex_group_smooth"; + ot->description = "Smooth weights for selected vertices"; /* api callbacks */ - ot->poll = vertex_group_blend_poll; - ot->exec = vertex_group_blend_exec; + ot->poll = vertex_group_mesh_vert_select_poll; + ot->exec = vertex_group_smooth_exec; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; vgroup_operator_subset_select_props(ot, true); - prop = RNA_def_property(ot->srna, "factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_ui_text(prop, "Factor", ""); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_float_default(prop, 1.0f); -} + RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 1.0, "Factor", "", 0.0f, 1.0f); + RNA_def_int(ot->srna, "repeat", 1, 1, 10000, "Iterations", "", 1, 200); + RNA_def_float(ot->srna, "expand", 0.0f, -1.0f, 1.0, "Expand/Contract", "Expand/contract weights", -1.0f, 1.0f); + RNA_def_enum(ot->srna, "source", smooth_source_item, -1, "Source", "Vertices to mix with"); +} static int vertex_group_clean_exec(bContext *C, wmOperator *op) { diff --git a/source/blender/editors/object/object_warp.c b/source/blender/editors/object/object_warp.c index 7413bb07c4c..9f4da87903d 100644 --- a/source/blender/editors/object/object_warp.c +++ b/source/blender/editors/object/object_warp.c @@ -275,14 +275,14 @@ static int object_warp_verts_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void OBJECT_OT_vertex_warp(struct wmOperatorType *ot) +void TRANSFORM_OT_vertex_warp(struct wmOperatorType *ot) { PropertyRNA *prop; /* identifiers */ ot->name = "Warp"; ot->description = "Warp vertices around the cursor"; - ot->idname = "OBJECT_OT_vertex_warp"; + ot->idname = "TRANSFORM_OT_vertex_warp"; /* api callbacks */ ot->exec = object_warp_verts_exec; |