diff options
Diffstat (limited to 'source/blender/editors/object')
19 files changed, 1889 insertions, 1190 deletions
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index b3d02d45e13..8050508983b 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -24,6 +24,7 @@ set(INC ../../blenlib ../../blentranslation ../../bmesh + ../../depsgraph ../../gpu ../../ikplugin ../../imbuf @@ -46,6 +47,7 @@ set(SRC object_bake_api.c object_constraint.c object_edit.c + object_facemap_ops.c object_group.c object_hook.c object_lattice.c diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 3f82298f5b3..ea2c688daa3 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -45,6 +45,7 @@ #include "DNA_object_fluidsim.h" #include "DNA_object_force.h" #include "DNA_object_types.h" +#include "DNA_lightprobe_types.h" #include "DNA_scene_types.h" #include "DNA_vfont_types.h" #include "DNA_actuator_types.h" @@ -63,10 +64,10 @@ #include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_camera.h" +#include "BKE_collection.h" #include "BKE_context.h" #include "BKE_constraint.h" #include "BKE_curve.h" -#include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_displist.h" #include "BKE_effect.h" @@ -74,6 +75,7 @@ #include "BKE_group.h" #include "BKE_lamp.h" #include "BKE_lattice.h" +#include "BKE_layer.h" #include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_library_remap.h" @@ -92,6 +94,9 @@ #include "BKE_speaker.h" #include "BKE_texture.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -113,7 +118,7 @@ #include "UI_resources.h" -#include "GPU_material.h" +#include "GPU_lamp.h" #include "object_intern.h" @@ -147,6 +152,16 @@ static const EnumPropertyItem field_type_items[] = { {0, NULL, 0, NULL, NULL} }; +static EnumPropertyItem lightprobe_type_items[] = { + {LIGHTPROBE_TYPE_CUBE, "SPHERE", ICON_MESH_UVSPHERE, "Reflection Cubemap", + "Reflection probe with spherical or cubic attenuation"}, + {LIGHTPROBE_TYPE_PLANAR, "PLANAR", ICON_MESH_PLANE, "Reflection Plane", + "Planar reflection probe"}, + {LIGHTPROBE_TYPE_GRID, "GRID", ICON_MESH_GRID, "Irradiance Volume", + "Irradiance probe to capture diffuse indirect lighting"}, + {0, NULL, 0, NULL, NULL} +}; + /************************** Exported *****************************/ void ED_object_location_from_view(bContext *C, float loc[3]) @@ -209,16 +224,19 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3], { Object *ob = base->object; Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; if (!scene) return; + CTX_data_eval_ctx(C, &eval_ctx); + if (loc) copy_v3_v3(ob->loc, loc); if (rot) copy_v3_v3(ob->rot, rot); - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); } /* Uses context to figure out transform for primitive. @@ -406,10 +424,11 @@ 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) + bool enter_editmode, unsigned int UNUSED(layer)) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *ob; /* for as long scene has editmode... */ @@ -417,13 +436,12 @@ Object *ED_object_add_type( 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, name); - BASACT->lay = ob->lay = layer; + ob = BKE_object_add(bmain, scene, sl, type, name); /* editor level activate, notifiers */ - ED_base_object_activate(C, BASACT); + ED_object_base_activate(C, sl->basact); /* more editor stuff */ - ED_object_base_init_transform(C, BASACT, loc, rot); + ED_object_base_init_transform(C, sl->basact, loc, rot); /* Ignore collisions by default for non-mesh objects */ if (type != OB_MESH) { @@ -431,8 +449,8 @@ Object *ED_object_add_type( ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH); /* copied from rna_object.c */ } - DAG_id_type_tag(bmain, ID_OB); - DAG_relations_tag_update(bmain); + DEG_id_type_tag(bmain, ID_OB); + DEG_relations_tag_update(bmain); if (ob->data) { ED_render_id_flush_update(bmain, ob->data); } @@ -442,6 +460,9 @@ Object *ED_object_add_type( WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); + /* TODO(sergey): Use proper flag for tagging here. */ + DEG_id_tag_update(&scene->id, 0); + return ob; } @@ -493,6 +514,79 @@ void OBJECT_OT_add(wmOperatorType *ot) ED_object_add_generic_props(ot, true); } +/********************** Add Probe Operator **********************/ + +/* for object add operator */ +static int lightprobe_add_exec(bContext *C, wmOperator *op) +{ + Object *ob; + LightProbe *probe; + int type; + bool enter_editmode; + unsigned int layer; + float loc[3], rot[3]; + float radius; + + WM_operator_view3d_unit_defaults(C, op); + if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &layer, NULL)) + return OPERATOR_CANCELLED; + + type = RNA_enum_get(op->ptr, "type"); + radius = RNA_float_get(op->ptr, "radius"); + + const char *name = CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Light Probe"); + ob = ED_object_add_type(C, OB_LIGHTPROBE, name, loc, rot, false, layer); + BKE_object_obdata_size_init(ob, radius); + + probe = (LightProbe *)ob->data; + probe->type = type; + + switch (type) { + case LIGHTPROBE_TYPE_GRID: + probe->distinf = 0.3f; + probe->falloff = 1.0f; + probe->clipsta = 0.01f; + break; + case LIGHTPROBE_TYPE_PLANAR: + probe->distinf = 0.1f; + probe->falloff = 0.5f; + probe->clipsta = 0.001f; + ob->empty_drawsize = 0.5f; + break; + case LIGHTPROBE_TYPE_CUBE: + probe->attenuation_type = LIGHTPROBE_SHAPE_ELIPSOID; + break; + default: + BLI_assert(!"Lightprobe type not configured."); + break; + } + + DEG_relations_tag_update(CTX_data_main(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_lightprobe_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Light Probe"; + ot->description = "Add a light probe object"; + ot->idname = "OBJECT_OT_lightprobe_add"; + + /* api callbacks */ + ot->exec = lightprobe_add_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", lightprobe_type_items, 0, "Type", ""); + + ED_object_add_unit_props(ot); + ED_object_add_generic_props(ot, true); +} + /********************* Add Effector Operator ********************/ /* for object add operator */ @@ -536,7 +630,7 @@ static int effector_add_exec(bContext *C, wmOperator *op) ob->pd = object_add_collision_fields(type); - DAG_relations_tag_update(CTX_data_main(C)); + DEG_relations_tag_update(CTX_data_main(C)); return OPERATOR_FINISHED; } @@ -641,7 +735,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) newob = true; } else { - DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + DEG_id_tag_update(&obedit->id, OB_RECALC_DATA); } ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); @@ -745,7 +839,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) newob = true; } else { - DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + DEG_id_tag_update(&obedit->id, OB_RECALC_DATA); } if (obedit == NULL) { @@ -1003,7 +1097,7 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) id_us_plus(&group->id); /* works without this except if you try render right after, see: 22027 */ - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); @@ -1110,22 +1204,20 @@ static void object_delete_check_glsl_update(Object *ob) /* remove base from a specific scene */ /* note: now unlinks constraints as well */ -void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base) +void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob) { - if (BKE_library_ID_is_indirectly_used(bmain, base->object) && - ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) + if (BKE_library_ID_is_indirectly_used(bmain, ob) && + ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) { /* We cannot delete indirectly used object... */ printf("WARNING, undeletable object '%s', should have been catched before reaching this function!", - base->object->id.name + 2); + ob->id.name + 2); return; } - BKE_scene_base_unlink(scene, base); - object_delete_check_glsl_update(base->object); - BKE_libblock_free_us(bmain, base->object); - MEM_freeN(base); - DAG_id_type_tag(bmain, ID_OB); + object_delete_check_glsl_update(ob); + BKE_collections_object_remove(bmain, scene, ob, true); + DEG_id_type_tag(bmain, ID_OB); } static int object_delete_exec(bContext *C, wmOperator *op) @@ -1140,18 +1232,18 @@ static int object_delete_exec(bContext *C, wmOperator *op) if (CTX_data_edit_object(C)) return OPERATOR_CANCELLED; - CTX_DATA_BEGIN (C, Base *, base, selected_bases) + CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { - const bool is_indirectly_used = BKE_library_ID_is_indirectly_used(bmain, base->object); - if (base->object->id.tag & LIB_TAG_INDIRECT) { + const bool is_indirectly_used = BKE_library_ID_is_indirectly_used(bmain, ob); + if (ob->id.tag & LIB_TAG_INDIRECT) { /* Can this case ever happen? */ - BKE_reportf(op->reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", base->object->id.name + 2); + BKE_reportf(op->reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", ob->id.name + 2); continue; } - else if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) { + else if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) { BKE_reportf(op->reports, RPT_WARNING, "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user", - base->object->id.name + 2, scene->id.name + 2); + ob->id.name + 2, scene->id.name + 2); continue; } @@ -1159,9 +1251,9 @@ static int object_delete_exec(bContext *C, wmOperator *op) * custom scene/object/base handling, and use generic lib remap/query for that. * But this is for later (aka 2.8, once layers & co are settled and working). */ - if (use_global && base->object->id.lib == NULL) { + if (use_global && ob->id.lib == NULL) { /* We want to nuke the object, let's nuke it the easy way (not for linked data though)... */ - BKE_libblock_delete(bmain, &base->object->id); + BKE_libblock_delete(bmain, &ob->id); changed = true; continue; } @@ -1172,38 +1264,28 @@ static int object_delete_exec(bContext *C, wmOperator *op) for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) { for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { if (gpl->parent != NULL) { - Object *ob = gpl->parent; - Object *curob = base->object; - if (ob == curob) { + if (gpl->parent == ob) { gpl->parent = NULL; } } } } - /* deselect object -- it could be used in other scenes */ - base->object->flag &= ~SELECT; - /* remove from current scene only */ - ED_base_object_free_and_unlink(bmain, scene, base); + ED_object_base_free_and_unlink(bmain, scene, ob); changed = true; if (use_global) { Scene *scene_iter; - Base *base_other; - for (scene_iter = bmain->scene.first; scene_iter; scene_iter = scene_iter->id.next) { if (scene_iter != scene && !ID_IS_LINKED(scene_iter)) { - base_other = BKE_scene_base_find(scene_iter, base->object); - if (base_other) { - if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) { - BKE_reportf(op->reports, RPT_WARNING, - "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user", - base->object->id.name + 2, scene_iter->id.name + 2); - break; - } - ED_base_object_free_and_unlink(bmain, scene_iter, base_other); + if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) { + BKE_reportf(op->reports, RPT_WARNING, + "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user", + ob->id.name + 2, scene_iter->id.name + 2); + break; } + ED_object_base_free_and_unlink(bmain, scene_iter, ob); } } } @@ -1217,12 +1299,12 @@ static int object_delete_exec(bContext *C, wmOperator *op) /* delete has to handle all open scenes */ BKE_main_id_tag_listbase(&bmain->scene, LIB_TAG_DOIT, true); for (win = wm->windows.first; win; win = win->next) { - scene = win->screen->scene; - + scene = WM_window_get_active_scene(win); + if (scene->id.tag & LIB_TAG_DOIT) { scene->id.tag &= ~LIB_TAG_DOIT; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); @@ -1344,6 +1426,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, const bool use_hierarchy) { Main *bmain = CTX_data_main(C); + SceneLayer *sl = CTX_data_scene_layer(C); ListBase *lb_duplis; DupliObject *dob; GHash *dupli_gh, *parent_gh = NULL; @@ -1376,12 +1459,11 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, ob_dst->totcol = 0; } - base_dst = MEM_dupallocN(base); - base_dst->flag &= ~(OB_FROMDUPLI | OB_FROMGROUP); - ob_dst->flag = base_dst->flag; - base_dst->lay = base->lay; - BLI_addhead(&scene->base, base_dst); /* addhead: othwise eternal loop */ - base_dst->object = ob_dst; + BKE_collection_object_add_from(scene, base->object, ob_dst); + base_dst = BKE_scene_layer_base_find(sl, ob_dst); + BLI_assert(base_dst != NULL); + + BKE_scene_object_base_flag_sync_from_base(base_dst); /* make sure apply works */ BKE_animdata_free(&ob_dst->id, true); @@ -1396,7 +1478,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, BKE_constraints_free(&ob_dst->constraints); ob_dst->curve_cache = NULL; ob_dst->transflag &= ~OB_DUPLI; - ob_dst->lay = base->lay; copy_m4_m4(ob_dst->obmat, dob->mat); BKE_object_apply_mat4(ob_dst, ob_dst->obmat, false, false); @@ -1420,7 +1501,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, BKE_libblock_relink_to_newid(&ob_dst->id); set_sca_new_poins_ob(ob_dst); - DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); if (use_hierarchy) { /* original parents */ @@ -1474,7 +1555,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, BKE_object_apply_mat4(ob_dst, dob->mat, false, true); /* to set ob_dst->orig and in case theres any other discrepicies */ - DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB); } } @@ -1483,7 +1564,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, if (ob->proxy_group == base->object) { ob->proxy = NULL; ob->proxy_from = NULL; - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } } } @@ -1519,7 +1600,7 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_SCENE, scene); WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL); @@ -1553,14 +1634,14 @@ static const EnumPropertyItem convert_target_items[] = { {0, NULL, 0, NULL, NULL} }; -static void convert_ensure_curve_cache(Main *bmain, Scene *scene, Object *ob) +static void convert_ensure_curve_cache(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Object *ob) { if (ob->curve_cache == NULL) { /* Force creation. This is normally not needed but on operator * redo we might end up with an object which isn't evaluated yet. */ if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) { - BKE_displist_make_curveTypes(scene, ob, false); + BKE_displist_make_curveTypes(eval_ctx, scene, ob, false); } else if (ob->type == OB_MBALL) { BKE_displist_make_mball(bmain->eval_ctx, scene, ob); @@ -1568,9 +1649,9 @@ static void convert_ensure_curve_cache(Main *bmain, Scene *scene, Object *ob) } } -static void curvetomesh(Main *bmain, Scene *scene, Object *ob) +static void curvetomesh(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Object *ob) { - convert_ensure_curve_cache(bmain, scene, ob); + convert_ensure_curve_cache(eval_ctx, bmain, scene, ob); BKE_mesh_from_nurbs(ob); /* also does users */ if (ob->type == OB_MESH) { @@ -1584,15 +1665,16 @@ static void curvetomesh(Main *bmain, Scene *scene, Object *ob) static int convert_poll(bContext *C) { - Object *obact = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); + Base *base_act = CTX_data_active_base(C); + Object *obact = base_act ? base_act->object : NULL; return (!ID_IS_LINKED(scene) && obact && scene->obedit != obact && - (obact->flag & SELECT) && !ID_IS_LINKED(obact)); + (base_act->flag & BASE_SELECTED) && !ID_IS_LINKED(obact)); } /* Helper for convert_exec */ -static Base *duplibase_for_convert(Main *bmain, Scene *scene, Base *base, Object *ob) +static Base *duplibase_for_convert(Main *bmain, Scene *scene, SceneLayer *sl, Base *base, Object *ob) { Object *obn; Base *basen; @@ -1602,17 +1684,12 @@ static Base *duplibase_for_convert(Main *bmain, Scene *scene, Base *base, Object } obn = BKE_object_copy(bmain, ob); - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); - - 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; + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + BKE_collection_object_add_from(scene, ob, obn); + basen = BKE_scene_layer_base_find(sl, obn); + ED_object_base_select(basen, BA_SELECT); + ED_object_base_select(basen, BA_DESELECT); return basen; } @@ -1620,8 +1697,10 @@ static int convert_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); + EvaluationContext eval_ctx; Base *basen = NULL, *basact = NULL; - Object *ob, *ob1, *newob, *obact = CTX_data_active_object(C); + Object *ob1, *newob, *obact = CTX_data_active_object(C); DerivedMesh *dm; Curve *cu; Nurb *nu; @@ -1631,13 +1710,13 @@ static int convert_exec(bContext *C, wmOperator *op) bool keep_original = RNA_boolean_get(op->ptr, "keep_original"); int a, mballConverted = 0; + CTX_data_eval_ctx(C, &eval_ctx); + /* don't forget multiple users! */ { - Base *base; - - for (base = scene->base.first; base; base = base->next) { - ob = base->object; + FOREACH_SCENE_OBJECT(scene, ob) + { ob->flag &= ~OB_DONE; /* flag data thats not been edited (only needed for !keep_original) */ @@ -1656,6 +1735,7 @@ static int convert_exec(bContext *C, wmOperator *op) } } } + FOREACH_SCENE_OBJECT_END } ListBase selected_editable_bases = CTX_data_collection_get(C, "selected_editable_bases"); @@ -1666,7 +1746,7 @@ static int convert_exec(bContext *C, wmOperator *op) { for (CollectionPointerLink *link = selected_editable_bases.first; link; link = link->next) { Base *base = link->ptr.data; - ob = base->object; + Object *ob = base->object; /* The way object type conversion works currently (enforcing conversion of *all* objetcs using converted * obdata, even some un-selected/hidden/inother scene ones, sounds totally bad to me. @@ -1679,18 +1759,19 @@ static int convert_exec(bContext *C, wmOperator *op) "Converting some linked object/object data, enforcing 'Keep Original' option to True"); } - DAG_id_tag_update(&base->object->id, OB_RECALC_DATA); + DEG_id_tag_update(&base->object->id, OB_RECALC_DATA); } + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, sl, true); uint64_t customdata_mask_prev = scene->customdata_mask; scene->customdata_mask |= CD_MASK_MESH; - BKE_scene_update_tagged(bmain->eval_ctx, bmain, scene); + BKE_scene_graph_update_tagged(bmain->eval_ctx, depsgraph, bmain, scene, sl); scene->customdata_mask = customdata_mask_prev; } for (CollectionPointerLink *link = selected_editable_bases.first; link; link = link->next) { Base *base = link->ptr.data; - ob = base->object; + Object *ob = base->object; if (ob->flag & OB_DONE || !IS_TAGGED(ob->data)) { if (ob->type != target) { @@ -1711,7 +1792,7 @@ static int convert_exec(bContext *C, wmOperator *op) ob->flag |= OB_DONE; if (keep_original) { - basen = duplibase_for_convert(bmain, scene, base, NULL); + basen = duplibase_for_convert(bmain, scene, sl, base, NULL); newob = basen->object; /* decrement original mesh's usage count */ @@ -1725,7 +1806,7 @@ static int convert_exec(bContext *C, wmOperator *op) newob = ob; } - BKE_mesh_to_curve(scene, newob); + BKE_mesh_to_curve(&eval_ctx, scene, newob); if (newob->type == OB_CURVE) { BKE_object_free_modifiers(newob); /* after derivedmesh calls! */ @@ -1736,7 +1817,7 @@ static int convert_exec(bContext *C, wmOperator *op) ob->flag |= OB_DONE; if (keep_original) { - basen = duplibase_for_convert(bmain, scene, base, NULL); + basen = duplibase_for_convert(bmain, scene, sl, base, NULL); newob = basen->object; /* decrement original mesh's usage count */ @@ -1748,14 +1829,14 @@ static int convert_exec(bContext *C, wmOperator *op) } else { newob = ob; - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); } /* 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, newob, CD_MASK_MESH); + dm = mesh_get_derived_final(&eval_ctx, scene, newob, CD_MASK_MESH); DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH, true); @@ -1767,7 +1848,7 @@ static int convert_exec(bContext *C, wmOperator *op) ob->flag |= OB_DONE; if (keep_original) { - basen = duplibase_for_convert(bmain, scene, base, NULL); + basen = duplibase_for_convert(bmain, scene, sl, base, NULL); newob = basen->object; /* decrement original curve's usage count */ @@ -1814,7 +1895,7 @@ static int convert_exec(bContext *C, wmOperator *op) for (ob1 = bmain->object.first; ob1; ob1 = ob1->id.next) { if (ob1->data == ob->data) { ob1->type = OB_CURVE; - DAG_id_tag_update(&ob1->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob1->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); } } } @@ -1827,7 +1908,7 @@ static int convert_exec(bContext *C, wmOperator *op) BKE_curve_curve_dimension_update(cu); if (target == OB_MESH) { - curvetomesh(bmain, scene, newob); + curvetomesh(&eval_ctx, bmain, scene, newob); /* meshes doesn't use displist */ BKE_object_free_curve_cache(newob); @@ -1838,7 +1919,7 @@ static int convert_exec(bContext *C, wmOperator *op) if (target == OB_MESH) { if (keep_original) { - basen = duplibase_for_convert(bmain, scene, base, NULL); + basen = duplibase_for_convert(bmain, scene, sl, base, NULL); newob = basen->object; /* decrement original curve's usage count */ @@ -1851,7 +1932,7 @@ static int convert_exec(bContext *C, wmOperator *op) newob = ob; } - curvetomesh(bmain, scene, newob); + curvetomesh(&eval_ctx, bmain, scene, newob); /* meshes doesn't use displist */ BKE_object_free_curve_cache(newob); @@ -1860,8 +1941,8 @@ static int convert_exec(bContext *C, wmOperator *op) else if (ob->type == OB_MBALL && target == OB_MESH) { Object *baseob; - base->flag &= ~SELECT; - ob->flag &= ~SELECT; + base->flag &= ~BASE_SELECTED; + ob->base_flag &= ~BASE_SELECTED; baseob = BKE_mball_basis_find(scene, ob); @@ -1873,7 +1954,7 @@ static int convert_exec(bContext *C, wmOperator *op) if (!(baseob->flag & OB_DONE)) { baseob->flag |= OB_DONE; - basen = duplibase_for_convert(bmain, scene, base, baseob); + basen = duplibase_for_convert(bmain, scene, sl, base, baseob); newob = basen->object; mb = newob->data; @@ -1889,7 +1970,7 @@ static int convert_exec(bContext *C, wmOperator *op) for (a = 0; a < newob->totcol; a++) id_us_plus((ID *)me->mat[a]); } - convert_ensure_curve_cache(bmain, scene, baseob); + convert_ensure_curve_cache(&eval_ctx, bmain, scene, baseob); BKE_mesh_from_metaball(&baseob->curve_cache->disp, newob->data); if (obact->type == OB_MBALL) { @@ -1916,7 +1997,7 @@ static int convert_exec(bContext *C, wmOperator *op) } if (!keep_original && (ob->flag & OB_DONE)) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); ((ID *)ob->data)->tag &= ~LIB_TAG_DOIT; /* flag not to convert this datablock again */ } } @@ -1924,27 +2005,24 @@ static int convert_exec(bContext *C, wmOperator *op) if (!keep_original) { if (mballConverted) { - Base *base, *base_next; - - for (base = scene->base.first; base; base = base_next) { - base_next = base->next; - - ob = base->object; - if (ob->type == OB_MBALL) { - if (ob->flag & OB_DONE) { + FOREACH_SCENE_OBJECT(scene, ob_mball) + { + if (ob_mball->type == OB_MBALL) { + if (ob_mball->flag & OB_DONE) { Object *ob_basis = NULL; - if (BKE_mball_is_basis(ob) || - ((ob_basis = BKE_mball_basis_find(scene, ob)) && (ob_basis->flag & OB_DONE))) + if (BKE_mball_is_basis(ob_mball) || + ((ob_basis = BKE_mball_basis_find(scene, ob_mball)) && (ob_basis->flag & OB_DONE))) { - ED_base_object_free_and_unlink(bmain, scene, base); + ED_object_base_free_and_unlink(bmain, scene, ob_mball); } } } } + FOREACH_SCENE_OBJECT_END } /* delete object should renew depsgraph */ - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); } // XXX ED_object_editmode_enter(C, 0); @@ -1952,15 +2030,15 @@ static int convert_exec(bContext *C, wmOperator *op) if (basact) { /* active base was changed */ - ED_base_object_activate(C, basact); - BASACT = basact; + ED_object_base_activate(C, basact); + BASACT(sl) = basact; } - else if (BASACT->object->flag & OB_DONE) { - WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT->object); - WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT->object); + else if (BASACT(sl)->object->flag & OB_DONE) { + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT(sl)->object); + WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT(sl)->object); } - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); @@ -1999,39 +2077,36 @@ void OBJECT_OT_convert(wmOperatorType *ot) /* used below, assumes id.new is correct */ /* leaves selection of base/object unaltered */ /* Does set ID->newid pointers. */ -static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base, int dupflag) +static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, SceneLayer *sl, Object *ob, int dupflag) { #define ID_NEW_REMAP_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; } #define ID_NEW_REMAP_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; } Base *basen = NULL; Material ***matarar; - Object *ob, *obn; + Object *obn; ID *id; int a, didit; - ob = base->object; if (ob->mode & OB_MODE_POSE) { ; /* nothing? */ } else { obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); - DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); - basen = MEM_mallocN(sizeof(Base), "duplibase"); - *basen = *base; - BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */ - basen->object = obn; + BKE_collection_object_add_from(scene, ob, obn); + basen = BKE_scene_layer_base_find(sl, obn); /* 1) duplis should end up in same group as the original * 2) Rigid Body sim participants MUST always be part of a group... */ // XXX: is 2) really a good measure here? - if ((basen->flag & OB_FROMGROUP) || ob->rigidbody_object || ob->rigidbody_constraint) { + if ((ob->flag & OB_FROMGROUP) != 0 || ob->rigidbody_object || ob->rigidbody_constraint) { Group *group; for (group = bmain->group.first; group; group = group->id.next) { if (BKE_group_object_exists(group, ob)) - BKE_group_object_add(group, obn, scene, basen); + BKE_group_object_add(group, obn); } } @@ -2140,7 +2215,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base } break; case OB_ARMATURE: - DAG_id_tag_update(&obn->id, OB_RECALC_DATA); + DEG_id_tag_update(&obn->id, OB_RECALC_DATA); if (obn->pose) BKE_pose_tag_recalc(bmain, obn->pose); if (dupflag & USER_DUP_ARM) { @@ -2244,14 +2319,14 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base * note: don't call this within a loop since clear_* funcs loop over the entire database. * note: caller must do DAG_relations_tag_update(bmain); * this is not done automatic since we may duplicate many objects in a batch */ -Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag) +Base *ED_object_add_duplicate(Main *bmain, Scene *scene, SceneLayer *sl, Base *base, int dupflag) { Base *basen; Object *ob; clear_sca_new_poins(); /* BGE logic */ - basen = object_add_duplicate_internal(bmain, scene, base, dupflag); + basen = object_add_duplicate_internal(bmain, scene, sl, base->object, dupflag); if (basen == NULL) { return NULL; } @@ -2278,6 +2353,7 @@ static int duplicate_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); const bool linked = RNA_boolean_get(op->ptr, "linked"); int dupflag = (linked) ? 0 : U.dupflag; @@ -2285,22 +2361,23 @@ static int duplicate_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, selected_bases) { - Base *basen = object_add_duplicate_internal(bmain, scene, base, dupflag); + Base *basen = object_add_duplicate_internal(bmain, scene, sl, base->object, dupflag); /* note that this is safe to do with this context iterator, * the list is made in advance */ - ED_base_object_select(base, BA_DESELECT); + ED_object_base_select(base, BA_DESELECT); + ED_object_base_select(basen, BA_SELECT); if (basen == NULL) { continue; } /* new object becomes active */ - if (BASACT == base) - ED_base_object_activate(C, basen); + if (BASACT(sl) == base) + ED_object_base_activate(C, basen); if (basen->object->data) { - DAG_id_tag_update(basen->object->data, 0); + DEG_id_tag_update(basen->object->data, 0); } } CTX_DATA_END; @@ -2309,7 +2386,9 @@ static int duplicate_exec(bContext *C, wmOperator *op) BKE_main_id_clear_newpoins(bmain); - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); + /* TODO(sergey): Use proper flag for tagging here. */ + DEG_id_tag_update(&CTX_data_scene(C)->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); @@ -2345,9 +2424,9 @@ static int add_named_exec(bContext *C, wmOperator *op) wmWindow *win = CTX_wm_window(C); const wmEvent *event = win ? win->eventstate : NULL; Main *bmain = CTX_data_main(C); - View3D *v3d = CTX_wm_view3d(C); /* may be NULL */ Scene *scene = CTX_data_scene(C); - Base *basen, *base; + SceneLayer *sl = CTX_data_scene_layer(C); + Base *basen; Object *ob; const bool linked = RNA_boolean_get(op->ptr, "linked"); int dupflag = (linked) ? 0 : U.dupflag; @@ -2362,22 +2441,17 @@ static int add_named_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - base = MEM_callocN(sizeof(Base), "duplibase"); - base->object = ob; - base->flag = ob->flag; - /* prepare dupli */ clear_sca_new_poins(); /* BGE logic */ - basen = object_add_duplicate_internal(bmain, scene, base, dupflag); + basen = object_add_duplicate_internal(bmain, scene, sl, ob, dupflag); + BKE_scene_object_base_flag_sync_from_object(basen); if (basen == NULL) { - MEM_freeN(base); BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated"); return OPERATOR_CANCELLED; } - basen->lay = basen->object->lay = BKE_screen_view3d_layer_active(v3d, scene); basen->object->restrictflag &= ~OB_RESTRICT_VIEW; if (event) { @@ -2388,16 +2462,14 @@ static int add_named_exec(bContext *C, wmOperator *op) ED_view3d_cursor3d_position(C, basen->object->loc, mval); } - ED_base_object_select(basen, BA_SELECT); - ED_base_object_activate(C, basen); + ED_object_base_select(basen, BA_SELECT); + ED_object_base_activate(C, basen); copy_object_set_idnew(C); BKE_main_id_clear_newpoins(bmain); - DAG_relations_tag_update(bmain); - - MEM_freeN(base); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT | ND_OB_ACTIVE, scene); diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 11d96da5786..0fd1d32c8b8 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -52,15 +52,17 @@ #include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_multires.h" #include "BKE_report.h" #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" #include "BKE_DerivedMesh.h" -#include "BKE_depsgraph.h" #include "BKE_mesh.h" #include "BKE_scene.h" +#include "DEG_depsgraph.h" + #include "RE_pipeline.h" #include "RE_shader_ext.h" #include "RE_multires_bake.h" @@ -86,6 +88,11 @@ * needed to make job totally thread-safe */ typedef struct MultiresBakerJobData { struct MultiresBakerJobData *next, *prev; + /* material aligned image array (for per-face bake image) */ + struct { + Image **array; + int len; + } ob_image; DerivedMesh *lores_dm, *hires_dm; bool simple; int lvl, tot_lvl; @@ -152,7 +159,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) break; } - if (!me->mtpoly) { + if (!me->mloopuv) { BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); ok = false; @@ -160,7 +167,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) else { a = me->totpoly; while (ok && a--) { - Image *ima = me->mtpoly[a].tpage; + Image *ima = BKE_object_material_edit_image_get(ob, me->mpoly[a].mat_nr); if (!ima) { BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker"); @@ -283,20 +290,27 @@ static void clear_single_image(Image *image, ClearFlag flag) } } -static void clear_images_poly(MTexPoly *mtpoly, int totpoly, ClearFlag flag) +static void clear_images_poly(Image **ob_image_array, int ob_image_array_len, ClearFlag flag) { - int a; - - for (a = 0; a < totpoly; a++) { - mtpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT; + for (int i = 0; i < ob_image_array_len; i++) { + Image *image = ob_image_array[i]; + if (image) { + image->id.tag &= ~LIB_TAG_DOIT; + } } - for (a = 0; a < totpoly; a++) { - clear_single_image(mtpoly[a].tpage, flag); + for (int i = 0; i < ob_image_array_len; i++) { + Image *image = ob_image_array[i]; + if (image) { + clear_single_image(image, flag); + } } - for (a = 0; a < totpoly; a++) { - mtpoly[a].tpage->id.tag &= ~LIB_TAG_DOIT; + for (int i = 0; i < ob_image_array_len; i++) { + Image *image = ob_image_array[i]; + if (image) { + image->id.tag &= ~LIB_TAG_DOIT; + } } } @@ -312,11 +326,10 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) if (scene->r.bake_flag & R_BAKE_CLEAR) { /* clear images */ CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - Mesh *me; ClearFlag clear_flag = 0; ob = base->object; - me = (Mesh *)ob->data; + // me = (Mesh *)ob->data; if (scene->r.bake_mode == RE_BAKE_NORMALS) { clear_flag = CLEAR_TANGENT_NORMAL; @@ -325,7 +338,11 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) clear_flag = CLEAR_DISPLACEMENT; } - clear_images_poly(me->mtpoly, me->totpoly, clear_flag); + { + Image **ob_image_array = BKE_object_material_edit_image_get_array(ob); + clear_images_poly(ob_image_array, ob->totcol, clear_flag); + MEM_freeN(ob_image_array); + } } CTX_DATA_END; } @@ -351,11 +368,16 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) //bkr.reports= op->reports; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ + bkr.ob_image.array = BKE_object_material_edit_image_get_array(ob); + bkr.ob_image.len = ob->totcol; + bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); RE_multires_bake_images(&bkr); + MEM_freeN(bkr.ob_image.array); + BLI_freelistN(&bkr.image); bkr.lores_dm->release(bkr.lores_dm); @@ -401,6 +423,9 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); + data->ob_image.array = BKE_object_material_edit_image_get_array(ob); + data->ob_image.len = ob->totcol; + /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple); data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); @@ -421,8 +446,6 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa if (bkj->bake_clear) { /* clear images */ for (data = bkj->data.first; data; data = data->next) { - DerivedMesh *dm = data->lores_dm; - MTexPoly *mtexpoly = CustomData_get_layer(&dm->polyData, CD_MTEXPOLY); ClearFlag clear_flag = 0; if (bkj->mode == RE_BAKE_NORMALS) { @@ -432,7 +455,7 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa clear_flag = CLEAR_DISPLACEMENT; } - clear_images_poly(mtexpoly, dm->getNumPolys(dm), clear_flag); + clear_images_poly(data->ob_image.array, data->ob_image.len, clear_flag); } } @@ -445,6 +468,8 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa bkr.use_lores_mesh = bkj->use_lores_mesh; bkr.user_scale = bkj->user_scale; //bkr.reports = bkj->reports; + bkr.ob_image.array = data->ob_image.array; + bkr.ob_image.len = data->ob_image.len; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ bkr.lores_dm = data->lores_dm; @@ -493,6 +518,8 @@ static void multiresbake_freejob(void *bkv) GPU_free_image(ima); } + MEM_freeN(data->ob_image.array); + BLI_freelistN(&data->images); MEM_freeN(data); @@ -589,6 +616,7 @@ static int test_bake_internal(bContext *C, ReportList *reports) static void init_bake_internal(BakeRender *bkr, bContext *C) { Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); bScreen *sc = CTX_wm_screen(C); /* get editmode results */ @@ -597,7 +625,7 @@ static void init_bake_internal(BakeRender *bkr, bContext *C) bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL; /* can be NULL */ bkr->main = CTX_data_main(C); bkr->scene = scene; - bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL; + bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(sl) : NULL; bkr->re = RE_NewRender("_Bake View_"); if (scene->r.bake_mode == RE_BAKE_AO) { @@ -661,7 +689,7 @@ static void finish_bake_internal(BakeRender *bkr) } BKE_image_release_ibuf(ima, ibuf, NULL); - DAG_id_tag_update(&ima->id, 0); + DEG_id_tag_update(&ima->id, 0); } } @@ -671,7 +699,7 @@ static void finish_bake_internal(BakeRender *bkr) BLI_assert(BLI_thread_is_main()); for (me = G.main->mesh.first; me; me = me->id.next) { if (me->id.tag & LIB_TAG_DOIT) { - DAG_id_tag_update(&me->id, OB_RECALC_DATA); + DEG_id_tag_update(&me->id, OB_RECALC_DATA); BKE_mesh_tessface_clear(me); } } @@ -810,6 +838,7 @@ static int bake_image_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); int result = OPERATOR_CANCELLED; if (is_multires_bake(scene)) { @@ -829,7 +858,7 @@ static int bake_image_exec(bContext *C, wmOperator *op) RE_test_break_cb(bkr.re, NULL, thread_break); G.is_break = false; /* BKE_blender_test_break uses this global */ - RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL); + RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(sl) : 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_bake_api.c b/source/blender/editors/object/object_bake_api.c index 4825271876c..0174a307c16 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -57,7 +57,8 @@ #include "BKE_modifier.h" #include "BKE_mesh.h" #include "BKE_screen.h" -#include "BKE_depsgraph.h" + +#include "DEG_depsgraph.h" #include "RE_engine.h" #include "RE_pipeline.h" @@ -83,6 +84,7 @@ static void bake_set_props(wmOperator *op, Scene *scene); typedef struct BakeAPIRender { Object *ob; Main *main; + Depsgraph *depsgraph; Scene *scene; ReportList *reports; ListBase selected_objects; @@ -272,7 +274,7 @@ static void refresh_images(BakeImages *bake_images) Image *ima = bake_images->data[i].image; if (ima->ok == IMA_OK_LOADED) { GPU_free_image(ima); - DAG_id_tag_update(&ima->id, 0); + DEG_id_tag_update(&ima->id, 0); } } } @@ -619,12 +621,12 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re } /* create new mesh with edit mode changes and modifiers applied */ -static Mesh *bake_mesh_new_from_object(Main *bmain, Scene *scene, Object *ob) +static Mesh *bake_mesh_new_from_object(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Object *ob) { if (ob->mode & OB_MODE_EDIT) ED_object_editmode_load(ob); - Mesh *me = BKE_mesh_new_from_object(bmain, scene, ob, 1, 2, 0, 0); + Mesh *me = BKE_mesh_new_from_object(eval_ctx, bmain, scene, ob, 1, 2, 0, 0); if (me->flag & ME_AUTOSMOOTH) { BKE_mesh_split_faces(me, true); } @@ -633,7 +635,7 @@ static Mesh *bake_mesh_new_from_object(Main *bmain, Scene *scene, Object *ob) } static int bake( - Render *re, Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports, + Render *re, Main *bmain, Depsgraph *graph, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports, const eScenePassType pass_type, const int pass_filter, const int margin, const eBakeSaveMode save_mode, const bool is_clear, const bool is_split_materials, const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage, @@ -672,7 +674,7 @@ static int bake( size_t num_pixels; int tot_materials; - RE_bake_engine_set_engine_parameters(re, bmain, scene); + RE_bake_engine_set_engine_parameters(re, bmain, graph, scene); if (!RE_bake_has_engine(re)) { BKE_report(reports, RPT_ERROR, "Current render engine does not support baking"); @@ -783,7 +785,7 @@ static int bake( } /* get the mesh as it arrives in the renderer */ - me_low = bake_mesh_new_from_object(bmain, scene, ob_low); + me_low = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, ob_low); /* populate the pixel array with the face data */ if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false) @@ -798,7 +800,7 @@ static int bake( /* prepare cage mesh */ if (ob_cage) { - me_cage = bake_mesh_new_from_object(bmain, scene, ob_cage); + me_cage = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, ob_cage); if ((me_low->totpoly != me_cage->totpoly) || (me_low->totloop != me_cage->totloop)) { BKE_report(reports, RPT_ERROR, "Invalid cage object, the cage mesh must have the same number " @@ -830,7 +832,7 @@ static int bake( ob_low->modifiers = modifiers_tmp; /* get the cage mesh as it arrives in the renderer */ - me_cage = bake_mesh_new_from_object(bmain, scene, ob_low); + me_cage = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, ob_low); RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer); } @@ -856,7 +858,7 @@ static int bake( tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED; tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP; - highpoly[i].me = bake_mesh_new_from_object(bmain, scene, highpoly[i].ob); + highpoly[i].me = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, highpoly[i].ob); highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER; /* lowpoly to highpoly transformation matrix */ @@ -959,7 +961,7 @@ cage_cleanup: md->mode &= ~eModifierMode_Render; } - me_nores = bake_mesh_new_from_object(bmain, scene, ob_low); + me_nores = bake_mesh_new_from_object(RE_GetEvalCtx(re), bmain, scene, ob_low); RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer); RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle, ob_low->obmat); @@ -1120,6 +1122,7 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) bkr->ob = CTX_data_active_object(C); bkr->main = CTX_data_main(C); + bkr->depsgraph = CTX_data_depsgraph(C); bkr->scene = CTX_data_scene(C); bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL; @@ -1203,7 +1206,7 @@ static int bake_exec(bContext *C, wmOperator *op) if (bkr.is_selected_to_active) { result = bake( - bkr.render, bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, + bkr.render, bkr.main, bkr.depsgraph, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode, bkr.is_clear, bkr.is_split_materials, bkr.is_automatic_name, true, bkr.is_cage, bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle, @@ -1216,7 +1219,7 @@ static int bake_exec(bContext *C, wmOperator *op) for (link = bkr.selected_objects.first; link; link = link->next) { Object *ob_iter = link->ptr.data; result = bake( - bkr.render, bkr.main, bkr.scene, ob_iter, NULL, bkr.reports, + bkr.render, bkr.main, bkr.depsgraph, bkr.scene, ob_iter, NULL, bkr.reports, bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode, is_clear, bkr.is_split_materials, bkr.is_automatic_name, false, bkr.is_cage, bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle, @@ -1261,7 +1264,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa if (bkr->is_selected_to_active) { bkr->result = bake( - bkr->render, bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, + bkr->render, bkr->main, bkr->depsgraph, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode, bkr->is_clear, bkr->is_split_materials, bkr->is_automatic_name, true, bkr->is_cage, bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle, @@ -1274,7 +1277,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa for (link = bkr->selected_objects.first; link; link = link->next) { Object *ob_iter = link->ptr.data; bkr->result = bake( - bkr->render, bkr->main, bkr->scene, ob_iter, NULL, bkr->reports, + bkr->render, bkr->main, bkr->depsgraph, bkr->scene, ob_iter, NULL, bkr->reports, bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode, is_clear, bkr->is_split_materials, bkr->is_automatic_name, false, bkr->is_cage, bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle, diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 94caaedec19..80fd44be364 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -53,7 +53,6 @@ #include "BKE_armature.h" #include "BKE_constraint.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_main.h" @@ -62,6 +61,9 @@ #include "BKE_tracking.h" #include "BIK_api.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #ifdef WITH_PYTHON #include "BPY_extern.h" #endif @@ -773,8 +775,12 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot) /* ------------- Child-Of Constraint ------------------ */ -static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, float invmat[4][4], const int owner) +static void child_get_inverse_matrix(const bContext *C, Scene *scene, Object *ob, bConstraint *con, float invmat[4][4], const int owner) { + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); + /* nullify inverse matrix first */ unit_m4(invmat); @@ -800,7 +806,7 @@ static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, * to use as baseline ("pmat") to derive delta from. This extra calc saves users * from having pressing "Clear Inverse" first */ - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); copy_m4_m4(pmat, pchan->pose_mat); /* 2. knock out constraints starting from this one */ @@ -817,7 +823,7 @@ static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, } /* 3. solve pose without disabled constraints */ - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); /* 4. determine effect of constraint by removing the newly calculated * pchan->pose_mat from the original pchan->pose_mat, thus determining @@ -840,7 +846,7 @@ static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, } /* 6. recalculate pose with new inv-mat applied */ - BKE_pose_where_is(scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); } } if (owner == EDIT_CONSTRAINT_OWNER_OBJECT) { @@ -851,7 +857,7 @@ static void child_get_inverse_matrix(Scene *scene, Object *ob, bConstraint *con, BLI_assert(BLI_findindex(&ob->constraints, con) != -1); /* use BKE_object_workob_calc_parent to find inverse - just like for normal parenting */ - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(invmat, workob.obmat); } } @@ -873,7 +879,7 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - child_get_inverse_matrix(scene, ob, con, data->invmat, owner); + child_get_inverse_matrix(C, scene, ob, con, data->invmat, owner); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); @@ -1095,7 +1101,7 @@ static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - child_get_inverse_matrix(scene, ob, con, data->invmat, owner); + child_get_inverse_matrix(C, scene, ob, con, data->invmat, owner); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); @@ -1196,9 +1202,9 @@ void ED_object_constraint_update(Object *ob) object_test_constraints(ob); if (ob->type == OB_ARMATURE) - DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); else - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } static void object_pose_tag_update(Main *bmain, Object *ob) @@ -1221,7 +1227,7 @@ void ED_object_constraint_dependency_update(Main *bmain, Object *ob) if (ob->pose) { object_pose_tag_update(bmain, ob); } - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); } void ED_object_constraint_tag_update(Object *ob, bConstraint *con) @@ -1233,9 +1239,9 @@ void ED_object_constraint_tag_update(Object *ob, bConstraint *con) object_test_constraint(ob, con); if (ob->type == OB_ARMATURE) - DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); else - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } void ED_object_constraint_dependency_tag_update(Main *bmain, Object *ob, bConstraint *con) @@ -1245,7 +1251,7 @@ void ED_object_constraint_dependency_tag_update(Main *bmain, Object *ob, bConstr if (ob->pose) { object_pose_tag_update(bmain, ob); } - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); } static int constraint_poll(bContext *C) @@ -1269,7 +1275,7 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op)) ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */ /* relatiols */ - DAG_relations_tag_update(CTX_data_main(C)); + DEG_relations_tag_update(CTX_data_main(C)); /* notifiers */ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob); @@ -1411,12 +1417,12 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_END; /* force depsgraph to get recalculated since relationships removed */ - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); /* note, calling BIK_clear_data() isn't needed here */ /* do updates */ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob); return OPERATOR_FINISHED; @@ -1443,12 +1449,12 @@ static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { BKE_constraints_free(&ob->constraints); - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } CTX_DATA_END; /* force depsgraph to get recalculated since relationships removed */ - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); /* do updates */ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, NULL); @@ -1496,13 +1502,13 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op) chan->constflag |= pchan->constflag; BKE_pose_tag_recalc(bmain, ob->pose); - DAG_id_tag_update((ID *)ob, OB_RECALC_DATA); + DEG_id_tag_update((ID *)ob, OB_RECALC_DATA); } } BLI_freelistN(&lb); /* force depsgraph to get recalculated since new relationships added */ - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, NULL); @@ -1535,13 +1541,13 @@ static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op)) /* if we're not handling the object we're copying from, copy all constraints over */ if (obact != ob) { BKE_constraints_copy(&ob->constraints, &obact->constraints, true); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } } CTX_DATA_END; /* force depsgraph to get recalculated since new relationships added */ - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_ADDED, NULL); @@ -1682,14 +1688,15 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob if ((found == false) && (add)) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Base *base = BASACT, *newbase = NULL; + SceneLayer *sl = CTX_data_scene_layer(C); + Base *base = BASACT(sl), *newbase = NULL; Object *obt; /* add new target object */ - obt = BKE_object_add(bmain, scene, OB_EMPTY, NULL); + obt = BKE_object_add(bmain, scene, sl, OB_EMPTY, NULL); /* set layers OK */ - newbase = BASACT; + newbase = BASACT(sl); newbase->lay = base->lay; obt->lay = newbase->lay; @@ -1708,8 +1715,8 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob } /* restore, BKE_object_add sets active */ - BASACT = base; - base->flag |= SELECT; + BASACT(sl) = base; + base->flag |= BASE_SELECTED; /* make our new target the new object */ *tar_ob = obt; @@ -1817,7 +1824,7 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase /* force depsgraph to get recalculated since new relationships added */ - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); if ((ob->type == OB_ARMATURE) && (pchan)) { BKE_pose_tag_recalc(bmain, ob->pose); /* sort pose channels */ @@ -1827,10 +1834,10 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase * XXX Temp hack until new depsgraph hopefully solves this. */ ob->adt->recalc |= ADT_RECALC_ANIM; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB); } else - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_ADDED, ob); @@ -2070,7 +2077,7 @@ static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_END; /* refresh depsgraph */ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob); diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 7845cfe1022..2daa8652335 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -40,13 +40,14 @@ #include "BKE_context.h" #include "BKE_data_transfer.h" -#include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_mesh_mapping.h" #include "BKE_mesh_remap.h" #include "BKE_object.h" #include "BKE_report.h" +#include "DEG_depsgraph.h" + #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -93,15 +94,17 @@ static const EnumPropertyItem DT_layer_items[] = { static const EnumPropertyItem *dt_layers_select_src_itemf( bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) { + EvaluationContext eval_ctx; EnumPropertyItem *item = NULL, tmp_item = {0}; int totitem = 0; - const int data_type = RNA_enum_get(ptr, "data_type"); if (!C) { /* needed for docs and i18n tools */ return rna_enum_dt_layers_select_src_items; } + CTX_data_eval_ctx(C, &eval_ctx); + RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_ACTIVE_SRC); RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_ALL_SRC); @@ -135,19 +138,19 @@ static const EnumPropertyItem *dt_layers_select_src_itemf( if (ob_src) { DerivedMesh *dm_src; - CustomData *pdata; + CustomData *ldata; int num_data, i; /* XXX Is this OK? */ - dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MTEXPOLY); - pdata = dm_src->getPolyDataLayout(dm_src); - num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY); + dm_src = mesh_get_derived_final(&eval_ctx, scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPUV); + ldata = dm_src->getLoopDataLayout(dm_src); + num_data = CustomData_number_of_layers(ldata, CD_MLOOPUV); RNA_enum_item_add_separator(&item, &totitem); for (i = 0; i < num_data; i++) { tmp_item.value = i; - tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i); + tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPUV, i); RNA_enum_item_add(&item, &totitem, &tmp_item); } } @@ -162,7 +165,7 @@ static const EnumPropertyItem *dt_layers_select_src_itemf( int num_data, i; /* XXX Is this OK? */ - dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL); + dm_src = mesh_get_derived_final(&eval_ctx, scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL); ldata = dm_src->getLoopDataLayout(dm_src); num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL); @@ -344,6 +347,9 @@ static int data_transfer_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob_src = ED_object_active_context(C); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); ListBase ctx_objects; CollectionPointerLink *ctx_ob_dst; @@ -412,7 +418,7 @@ static int data_transfer_exec(bContext *C, wmOperator *op) } if (BKE_object_data_transfer_mesh( - scene, ob_src, ob_dst, data_type, use_create, + &eval_ctx, scene, ob_src, ob_dst, data_type, use_create, map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode, space_transform, use_auto_transform, max_distance, ray_radius, islands_precision, @@ -423,7 +429,7 @@ static int data_transfer_exec(bContext *C, wmOperator *op) } } - DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); if (reverse_transfer) { SWAP(Object *, ob_src, ob_dst); @@ -622,8 +628,11 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob_act = ED_object_active_context(C); + EvaluationContext eval_ctx; DataTransferModifierData *dtmd; + CTX_data_eval_ctx(C, &eval_ctx); + dtmd = (DataTransferModifierData *)edit_modifier_property_get(op, ob_act, eModifierType_DataTransfer); /* If we have a modifier, we transfer data layout from this modifier's source object to active one. @@ -638,10 +647,10 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BKE_object_data_transfer_layout(scene, ob_src, ob_dst, dtmd->data_types, use_delete, + BKE_object_data_transfer_layout(&eval_ctx, scene, ob_src, ob_dst, dtmd->data_types, use_delete, dtmd->layers_select_src, dtmd->layers_select_dst); - DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); } else { Object *ob_src = ob_act; @@ -668,11 +677,11 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op) for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) { Object *ob_dst = ctx_ob_dst->ptr.data; if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, false)) { - BKE_object_data_transfer_layout(scene, ob_src, ob_dst, data_type, use_delete, + BKE_object_data_transfer_layout(&eval_ctx, scene, ob_src, ob_dst, data_type, use_delete, layers_select_src, layers_select_dst); } - DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); } BLI_freelistN(&ctx_objects); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index d7c7976c344..eaf42d4a53c 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -58,6 +58,7 @@ #include "DNA_meshdata_types.h" #include "DNA_vfont_types.h" #include "DNA_mesh_types.h" +#include "DNA_workspace_types.h" #include "IMB_imbuf_types.h" @@ -66,7 +67,6 @@ #include "BKE_context.h" #include "BKE_curve.h" #include "BKE_effect.h" -#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_lattice.h" @@ -83,6 +83,10 @@ #include "BKE_modifier.h" #include "BKE_editmesh.h" #include "BKE_report.h" +#include "BKE_workspace.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" #include "ED_armature.h" #include "ED_curve.h" @@ -132,192 +136,6 @@ Object *ED_object_active_context(bContext *C) } -/* ********* clear/set restrict view *********/ -static int object_hide_view_clear_exec(bContext *C, wmOperator *op) -{ - Main *bmain = CTX_data_main(C); - ScrArea *sa = CTX_wm_area(C); - View3D *v3d = sa->spacedata.first; - Scene *scene = CTX_data_scene(C); - Base *base; - bool changed = false; - const bool select = RNA_boolean_get(op->ptr, "select"); - - /* XXX need a context loop to handle such cases */ - for (base = FIRSTBASE; base; base = base->next) { - if ((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) { - if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) { - SET_FLAG_FROM_TEST(base->flag, select, SELECT); - } - base->object->flag = base->flag; - base->object->restrictflag &= ~OB_RESTRICT_VIEW; - changed = true; - } - } - if (changed) { - DAG_id_type_tag(bmain, ID_OB); - DAG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - } - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_hide_view_clear(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name = "Clear Restrict View"; - ot->description = "Reveal the object by setting the hide flag"; - ot->idname = "OBJECT_OT_hide_view_clear"; - - /* api callbacks */ - ot->exec = object_hide_view_clear_exec; - ot->poll = ED_operator_view3d_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_boolean(ot->srna, "select", true, "Select", ""); -} - -static int object_hide_view_set_exec(bContext *C, wmOperator *op) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - bool changed = false; - const bool unselected = RNA_boolean_get(op->ptr, "unselected"); - - CTX_DATA_BEGIN(C, Base *, base, visible_bases) - { - if (!unselected) { - if (base->flag & SELECT) { - base->flag &= ~SELECT; - base->object->flag = base->flag; - base->object->restrictflag |= OB_RESTRICT_VIEW; - changed = true; - if (base == BASACT) { - ED_base_object_activate(C, NULL); - } - } - } - else { - if (!(base->flag & SELECT)) { - base->object->restrictflag |= OB_RESTRICT_VIEW; - changed = true; - if (base == BASACT) { - ED_base_object_activate(C, NULL); - } - } - } - } - CTX_DATA_END; - - if (changed) { - DAG_id_type_tag(bmain, ID_OB); - DAG_relations_tag_update(bmain); - - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - - } - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_hide_view_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set Restrict View"; - ot->description = "Hide the object by setting the hide flag"; - ot->idname = "OBJECT_OT_hide_view_set"; - - /* api callbacks */ - ot->exec = object_hide_view_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"); - -} - -/* 99% same as above except no need for scene refreshing (TODO, update render preview) */ -static int object_hide_render_clear_exec(bContext *C, wmOperator *UNUSED(op)) -{ - bool changed = false; - - /* 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 = true; - } - } - CTX_DATA_END; - - if (changed) - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_hide_render_clear(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name = "Clear Restrict Render"; - ot->description = "Reveal the render object by setting the hide render flag"; - ot->idname = "OBJECT_OT_hide_render_clear"; - - /* api callbacks */ - ot->exec = object_hide_render_clear_exec; - ot->poll = ED_operator_view3d_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -static int object_hide_render_set_exec(bContext *C, wmOperator *op) -{ - const bool 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_hide_render_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set Restrict Render"; - ot->description = "Hide the render object by setting the hide render flag"; - ot->idname = "OBJECT_OT_hide_render_set"; - - /* api callbacks */ - ot->exec = object_hide_render_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 ***************** */ static bool mesh_needs_keyindex(const Mesh *me) @@ -379,7 +197,7 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f * to inform dependency graph about this. But is it really the * best place to do this? */ - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { ED_curve_editnurb_load(obedit); @@ -401,7 +219,7 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f /* Tag update so no access to freed data referenced from * derived cache will happen. */ - DAG_id_tag_update((ID *)obedit->data, 0); + DEG_id_tag_update((ID *)obedit->data, 0); return true; } @@ -417,6 +235,7 @@ void ED_object_editmode_exit(bContext *C, int flag) /* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */ /* Note! if 'EM_FREEDATA' isn't in the flag, use ED_object_editmode_load directly */ Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *obedit = CTX_data_edit_object(C); const bool freedata = (flag & EM_FREEDATA) != 0; @@ -425,8 +244,8 @@ void ED_object_editmode_exit(bContext *C, int flag) 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))) { - scene->basact->object->mode &= ~OB_MODE_EDIT; + if (UNLIKELY(sl->basact && (sl->basact->object->mode & OB_MODE_EDIT))) { + sl->basact->object->mode &= ~OB_MODE_EDIT; } if (flag & EM_WAITCURSOR) waitcursor(0); return; @@ -451,7 +270,7 @@ void ED_object_editmode_exit(bContext *C, int flag) BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED); /* also flush ob recalc, doesn't take much overhead, but used for particles */ - DAG_id_tag_update(&obedit->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&obedit->id, OB_RECALC_OB | OB_RECALC_DATA); if (flag & EM_DO_UNDO) ED_undo_push(C, "Editmode"); @@ -462,37 +281,31 @@ void ED_object_editmode_exit(bContext *C, int flag) } if (flag & EM_WAITCURSOR) waitcursor(0); + + /* This way we ensure scene's obedit is copied into all CoW scenes. */ + DEG_id_tag_update(&scene->id, 0); } void ED_object_editmode_enter(bContext *C, int flag) { Scene *scene = CTX_data_scene(C); - Base *base = NULL; + SceneLayer *sl = CTX_data_scene_layer(C); Object *ob; - ScrArea *sa = CTX_wm_area(C); - View3D *v3d = NULL; bool ok = false; if (ID_IS_LINKED(scene)) return; - if (sa && sa->spacetype == SPACE_VIEW3D) - v3d = sa->spacedata.first; - if ((flag & EM_IGNORE_LAYER) == 0) { - base = CTX_data_active_base(C); /* active layer checked here for view3d */ + ob = CTX_data_active_object(C); /* active layer checked here for view3d */ - if (base == NULL) return; - else if (v3d && (base->lay & v3d->lay) == 0) return; - else if (!v3d && (base->lay & scene->lay) == 0) return; + if (ob == NULL) return; } else { - base = scene->basact; + ob = sl->basact->object; } - if (ELEM(NULL, base, base->object, base->object->data)) return; - - ob = base->object; + if (ELEM(NULL, ob, ob->data)) return; /* this checks actual object->data, for cases when other scenes have it in editmode context */ if (BKE_object_is_in_editmode(ob)) @@ -551,7 +364,7 @@ void ED_object_editmode_enter(bContext *C, int flag) scene->obedit = ob; ED_armature_to_edit(arm); /* to ensure all goes in restposition and without striding */ - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* XXX: should this be OB_RECALC_DATA? */ + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* XXX: should this be OB_RECALC_DATA? */ WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_EDITMODE_ARMATURE, scene); } @@ -585,7 +398,9 @@ void ED_object_editmode_enter(bContext *C, int flag) } if (ok) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + /* This way we ensure scene's obedit is copied into all CoW scenes. */ + DEG_id_tag_update(&scene->id, 0); } else { scene->obedit = NULL; /* XXX for context */ @@ -697,7 +512,7 @@ void OBJECT_OT_posemode_toggle(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) +static void copymenu_properties(SceneLayer *sl, Object *ob) { //XXX no longer used - to be removed - replaced by game_properties_copy_exec bProperty *prop; @@ -730,8 +545,8 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) nr = pupmenu(str); if (nr == 1 || nr == 2) { - for (base = FIRSTBASE; base; base = base->next) { - if ((base != BASACT) && (TESTBASELIB(v3d, base))) { + for (base = FIRSTBASE(sl); base; base = base->next) { + if ((base != BASACT(sl)) && (TESTBASELIB(base))) { if (nr == 1) { /* replace */ BKE_bproperty_copy_list(&base->object->prop, &ob->prop); } @@ -747,8 +562,8 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) prop = BLI_findlink(&ob->prop, nr - 4); /* account for first 3 menu items & menu index starting at 1*/ if (prop) { - for (base = FIRSTBASE; base; base = base->next) { - if ((base != BASACT) && (TESTBASELIB(v3d, base))) { + for (base = FIRSTBASE(sl); base; base = base->next) { + if ((base != BASACT(sl)) && (TESTBASELIB(base))) { BKE_bproperty_object_set(base->object, prop); } } @@ -758,14 +573,14 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) } -static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob) +static void copymenu_logicbricks(SceneLayer *sl, Object *ob) { //XXX no longer used - to be removed - replaced by logicbricks_copy_exec Base *base; - for (base = FIRSTBASE; base; base = base->next) { + for (base = FIRSTBASE(sl); base; base = base->next) { if (base->object != ob) { - if (TESTBASELIB(v3d, base)) { + if (TESTBASELIB(base)) { /* first: free all logic */ free_sensors(&base->object->sensors); @@ -844,7 +659,7 @@ static void copy_texture_space(Object *to, Object *ob) } /* UNUSED, keep in case we want to copy functionality for use elsewhere */ -static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) +static void copy_attr(Main *bmain, Scene *scene, SceneLayer *sl, short event) { Object *ob; Base *base; @@ -854,18 +669,18 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) if (ID_IS_LINKED(scene)) return; - if (!(ob = OBACT)) return; + if (!(ob = OBACT(sl))) return; if (scene->obedit) { // XXX get from context /* obedit_copymenu(); */ return; } if (event == 9) { - copymenu_properties(scene, v3d, ob); + copymenu_properties(sl, ob); return; } else if (event == 10) { - copymenu_logicbricks(scene, v3d, ob); + copymenu_logicbricks(sl, ob); return; } else if (event == 24) { @@ -874,10 +689,10 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) return; } - for (base = FIRSTBASE; base; base = base->next) { - if (base != BASACT) { - if (TESTBASELIB(v3d, base)) { - DAG_id_tag_update(&base->object->id, OB_RECALC_DATA); + for (base = FIRSTBASE(sl); base; base = base->next) { + if (base != BASACT(sl)) { + if (TESTBASELIB(base)) { + DEG_id_tag_update(&base->object->id, OB_RECALC_DATA); if (event == 1) { /* loc */ copy_v3_v3(base->object->loc, ob->loc); @@ -980,7 +795,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) BLI_strncpy(cu1->family, cu->family, sizeof(cu1->family)); - DAG_id_tag_update(&base->object->id, OB_RECALC_DATA); + DEG_id_tag_update(&base->object->id, OB_RECALC_DATA); } } else if (event == 19) { /* bevel settings */ @@ -996,7 +811,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) cu1->ext1 = cu->ext1; cu1->ext2 = cu->ext2; - DAG_id_tag_update(&base->object->id, OB_RECALC_DATA); + DEG_id_tag_update(&base->object->id, OB_RECALC_DATA); } } else if (event == 25) { /* curve resolution */ @@ -1015,7 +830,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) nu = nu->next; } - DAG_id_tag_update(&base->object->id, OB_RECALC_DATA); + DEG_id_tag_update(&base->object->id, OB_RECALC_DATA); } } else if (event == 21) { @@ -1031,7 +846,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) } modifier_copyData(md, tmd); - DAG_id_tag_update(&base->object->id, OB_RECALC_DATA); + DEG_id_tag_update(&base->object->id, OB_RECALC_DATA); } } } @@ -1092,16 +907,16 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) } if (do_depgraph_update) - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); } -static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, View3D *v3d) +static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, SceneLayer *sl) { Object *ob; short event; char str[512]; - if (!(ob = OBACT)) return; + if (!(ob = OBACT(sl))) return; if (scene->obedit) { /* XXX get from context */ /* if (ob->type == OB_MESH) */ @@ -1149,7 +964,7 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, View3D * event = pupmenu(str); if (event <= 0) return; - copy_attr(bmain, scene, v3d, event); + copy_attr(bmain, scene, sl, event); } /* ******************* force field toggle operator ***************** */ @@ -1218,6 +1033,9 @@ void OBJECT_OT_forcefield_toggle(wmOperatorType *ot) */ void ED_objects_recalculate_paths(bContext *C, Scene *scene) { + struct Main *bmain = CTX_data_main(C); + EvaluationContext eval_ctx; + CTX_data_eval_ctx(C, &eval_ctx); ListBase targets = {NULL, NULL}; /* loop over objects in scene */ @@ -1230,7 +1048,7 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene) CTX_DATA_END; /* recalculate paths, then free */ - animviz_calc_motionpaths(scene, &targets); + animviz_calc_motionpaths(&eval_ctx, bmain, scene, &targets); BLI_freelistN(&targets); } @@ -1451,7 +1269,8 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) if (ob->type == OB_MESH) { BKE_mesh_smooth_flag_set(ob, !clear); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); done = true; @@ -1464,7 +1283,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) else nu->flag &= ~ME_SMOOTH; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); done = true; @@ -1515,7 +1334,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot) /* ********************** */ -static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d) +static void UNUSED_FUNCTION(image_aspect) (Scene *scene, SceneLayer *sl) { /* all selected objects with an image map: scale in image aspect */ Base *base; @@ -1528,8 +1347,8 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d) if (scene->obedit) return; // XXX get from context if (ID_IS_LINKED(scene)) return; - for (base = FIRSTBASE; base; base = base->next) { - if (TESTBASELIB(v3d, base)) { + for (base = FIRSTBASE(sl); base; base = base->next) { + if (TESTBASELIB(base)) { ob = base->object; done = false; @@ -1562,7 +1381,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d) else ob->size[1] = ob->size[0] * y / x; done = true; - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); BKE_image_release_ibuf(tex->ima, ibuf, NULL); } @@ -1697,8 +1516,15 @@ bool ED_object_mode_compat_set(bContext *C, Object *ob, int mode, ReportList *re { bool ok; if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) { + WorkSpace *workspace = CTX_wm_workspace(C); const char *opstring = object_mode_op_string(ob->mode); + WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL); +#ifdef USE_WORKSPACE_MODE + BKE_workspace_object_mode_set(workspace, ob->mode); +#else + UNUSED_VARS(workspace); +#endif ok = ELEM(ob->mode, mode, OB_MODE_OBJECT); if (!ok) { wmOperatorType *ot = WM_operatortype_find(opstring, false); @@ -1808,13 +1634,23 @@ void OBJECT_OT_mode_set(wmOperatorType *ot) } - void ED_object_toggle_modes(bContext *C, int mode) { if (mode != OB_MODE_OBJECT) { const char *opstring = object_mode_op_string(mode); + if (opstring) { +#ifdef USE_WORKSPACE_MODE + WorkSpace *workspace = CTX_wm_workspace(C); +#endif WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL); + +#ifdef USE_WORKSPACE_MODE + Object *ob = CTX_data_active_object(C); + if (ob) { + BKE_workspace_object_mode_set(workspace, ob->mode); + } +#endif } } } diff --git a/source/blender/editors/object/object_facemap_ops.c b/source/blender/editors/object/object_facemap_ops.c new file mode 100644 index 00000000000..857446ac6b0 --- /dev/null +++ b/source/blender/editors/object/object_facemap_ops.c @@ -0,0 +1,492 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BLI_listbase.h" + +#include "DNA_object_types.h" +#include "DNA_mesh_types.h" + +#include "BKE_context.h" +#include "BKE_customdata.h" +#include "BKE_editmesh.h" +#include "BKE_object.h" +#include "BKE_object_facemap.h" +#include "BKE_object_deform.h" + +#include "DEG_depsgraph.h" + +#include "RNA_define.h" +#include "RNA_access.h" + +#include "WM_types.h" +#include "WM_api.h" + +#include "ED_mesh.h" +#include "ED_object.h" + +#include "object_intern.h" + +/* called while not in editmode */ +void ED_object_facemap_face_add(Object *ob, bFaceMap *fmap, int facenum) +{ + int fmap_nr; + if (GS(((ID *)ob->data)->name) != ID_ME) + return; + + /* get the face map number, exit if it can't be found */ + fmap_nr = BLI_findindex(&ob->fmaps, fmap); + + if (fmap_nr != -1) { + int *facemap; + Mesh *me = ob->data; + + /* if there's is no facemap layer then create one */ + if ((facemap = CustomData_get_layer(&me->pdata, CD_FACEMAP)) == NULL) + facemap = CustomData_add_layer(&me->pdata, CD_FACEMAP, CD_DEFAULT, NULL, me->totpoly); + + facemap[facenum] = fmap_nr; + } +} + +/* called while not in editmode */ +void ED_object_facemap_face_remove(Object *ob, bFaceMap *fmap, int facenum) +{ + int fmap_nr; + if (GS(((ID *)ob->data)->name) != ID_ME) + return; + + /* get the face map number, exit if it can't be found */ + fmap_nr = BLI_findindex(&ob->fmaps, fmap); + + if (fmap_nr != -1) { + int *facemap; + Mesh *me = ob->data; + + /* if there's is no facemap layer then create one */ + if ((facemap = CustomData_get_layer(&me->pdata, CD_FACEMAP)) == NULL) + return; + + facemap[facenum] = -1; + } +} + +static void object_fmap_swap_edit_mode(Object *ob, int num1, int num2) +{ + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + + if (me->edit_btmesh) { + BMEditMesh *em = me->edit_btmesh; + const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP); + + if (cd_fmap_offset != -1) { + BMFace *efa; + BMIter iter; + int *map; + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset); + + if (map) { + if (num1 != -1) { + if (*map == num1) + *map = num2; + else if (*map == num2) + *map = num1; + } + } + } + } + } + } +} + +static void object_fmap_swap_object_mode(Object *ob, int num1, int num2) +{ + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + + if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) { + int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP); + int i; + + if (map) { + for (i = 0; i < me->totpoly; i++) { + if (num1 != -1) { + if (map[i] == num1) + map[i] = num2; + else if (map[i] == num2) + map[i] = num1; + } + } + } + } + } +} + +static void object_facemap_swap(Object *ob, int num1, int num2) +{ + if (BKE_object_is_in_editmode(ob)) + object_fmap_swap_edit_mode(ob, num1, num2); + else + object_fmap_swap_object_mode(ob, num1, num2); +} + +static int face_map_supported_poll(bContext *C) +{ + Object *ob = ED_object_context(C); + ID *data = (ob) ? ob->data : NULL; + return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib); +} + +static int face_map_supported_edit_mode_poll(bContext *C) +{ + Object *ob = ED_object_context(C); + ID *data = (ob) ? ob->data : NULL; + return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib && ob->mode == OB_MODE_EDIT); +} + +static int face_map_add_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = ED_object_context(C); + + BKE_object_facemap_add(ob); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_face_map_add(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Face Map"; + ot->idname = "OBJECT_OT_face_map_add"; + ot->description = "Add a new face map to the active object"; + + /* api callbacks */ + ot->poll = face_map_supported_poll; + ot->exec = face_map_add_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int face_map_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = ED_object_context(C); + bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1); + + if (fmap) { + BKE_object_facemap_remove(ob, fmap); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + } + return OPERATOR_FINISHED; +} + +void OBJECT_OT_face_map_remove(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Face Map"; + ot->idname = "OBJECT_OT_face_map_remove"; + ot->description = "Remove a face map from the active object"; + + /* api callbacks */ + ot->poll = face_map_supported_poll; + ot->exec = face_map_remove_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int face_map_assign_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = ED_object_context(C); + bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1); + + if (fmap) { + Mesh *me = ob->data; + BMEditMesh *em = me->edit_btmesh; + BMFace *efa; + BMIter iter; + int *map; + int cd_fmap_offset; + + if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP)) + BM_data_layer_add(em->bm, &em->bm->pdata, CD_FACEMAP); + + cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset); + + if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + *map = ob->actfmap - 1; + } + } + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + } + return OPERATOR_FINISHED; +} + +void OBJECT_OT_face_map_assign(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Assign Face Map"; + ot->idname = "OBJECT_OT_face_map_assign"; + ot->description = "Assign faces to a face map"; + + /* api callbacks */ + ot->poll = face_map_supported_edit_mode_poll; + ot->exec = face_map_assign_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int face_map_remove_from_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = ED_object_context(C); + bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1); + + if (fmap) { + Mesh *me = ob->data; + BMEditMesh *em = me->edit_btmesh; + BMFace *efa; + BMIter iter; + int *map; + int cd_fmap_offset; + int mapindex = ob->actfmap - 1; + + if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP)) + return OPERATOR_CANCELLED; + + cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset); + + if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && *map == mapindex) { + *map = -1; + } + } + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + } + return OPERATOR_FINISHED; +} + +void OBJECT_OT_face_map_remove_from(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove From Face Map"; + ot->idname = "OBJECT_OT_face_map_remove_from"; + ot->description = "Remove faces from a face map"; + + /* api callbacks */ + ot->poll = face_map_supported_edit_mode_poll; + ot->exec = face_map_remove_from_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static void fmap_select(Object *ob, bool select) +{ + Mesh *me = ob->data; + BMEditMesh *em = me->edit_btmesh; + BMFace *efa; + BMIter iter; + int *map; + int cd_fmap_offset; + int mapindex = ob->actfmap - 1; + + if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP)) + BM_data_layer_add(em->bm, &em->bm->pdata, CD_FACEMAP); + + cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset); + + if (*map == mapindex) { + BM_face_select_set(em->bm, efa, select); + } + } +} + +static int face_map_select_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = ED_object_context(C); + bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1); + + if (fmap) { + fmap_select(ob, true); + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + } + return OPERATOR_FINISHED; +} + +void OBJECT_OT_face_map_select(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Face Map Faces"; + ot->idname = "OBJECT_OT_face_map_select"; + ot->description = "Select faces belonging to a face map"; + + /* api callbacks */ + ot->poll = face_map_supported_edit_mode_poll; + ot->exec = face_map_select_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int face_map_deselect_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = ED_object_context(C); + bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1); + + if (fmap) { + fmap_select(ob, false); + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + } + return OPERATOR_FINISHED; +} + +void OBJECT_OT_face_map_deselect(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Deselect Face Map Faces"; + ot->idname = "OBJECT_OT_face_map_deselect"; + ot->description = "Deselect faces belonging to a face map"; + + /* api callbacks */ + ot->poll = face_map_supported_edit_mode_poll; + ot->exec = face_map_deselect_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + +static int face_map_move_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_context(C); + bFaceMap *fmap; + int dir = RNA_enum_get(op->ptr, "direction"); + int pos1, pos2 = -1, count; + + fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1); + if (!fmap) { + return OPERATOR_CANCELLED; + } + + count = BLI_listbase_count(&ob->fmaps); + pos1 = BLI_findindex(&ob->fmaps, fmap); + + if (dir == 1) { /*up*/ + void *prev = fmap->prev; + + if (prev) { + pos2 = pos1 - 1; + } + else { + pos2 = count - 1; + } + + BLI_remlink(&ob->fmaps, fmap); + BLI_insertlinkbefore(&ob->fmaps, prev, fmap); + } + else { /*down*/ + void *next = fmap->next; + + if (next) { + pos2 = pos1 + 1; + } + else { + pos2 = 0; + } + + BLI_remlink(&ob->fmaps, fmap); + BLI_insertlinkafter(&ob->fmaps, next, fmap); + } + + /* iterate through mesh and substitute the indices as necessary */ + object_facemap_swap(ob, pos2, pos1); + + ob->actfmap = pos2 + 1; + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob); + + return OPERATOR_FINISHED; +} + + +void OBJECT_OT_face_map_move(wmOperatorType *ot) +{ + static EnumPropertyItem fmap_slot_move[] = { + {1, "UP", 0, "Up", ""}, + {-1, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Move Face Map"; + ot->idname = "OBJECT_OT_face_map_move"; + ot->description = "Move the active face map up/down in the list"; + + /* api callbacks */ + ot->poll = face_map_supported_poll; + ot->exec = face_map_move_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "direction", fmap_slot_move, 0, "Direction", "Direction to move, UP or DOWN"); +} diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 46c2c4e4b7d..27c1a03190a 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -40,7 +40,6 @@ #include "DNA_scene_types.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_group.h" #include "BKE_library.h" #include "BKE_library_remap.h" @@ -48,6 +47,8 @@ #include "BKE_report.h" #include "BKE_object.h" +#include "DEG_depsgraph_build.h" + #include "ED_screen.h" #include "ED_object.h" @@ -128,7 +129,6 @@ static int objects_add_active_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); int single_group_index = RNA_enum_get(op->ptr, "group"); Group *single_group = group_object_active_find_index(ob, single_group_index); Group *group; @@ -151,7 +151,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op) continue; if (!BKE_group_object_cyclic_check(bmain, base->object, group)) { - BKE_group_object_add(group, base->object, scene, base); + BKE_group_object_add(group, base->object); updated = true; } else { @@ -167,7 +167,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op) if (!updated) return OPERATOR_CANCELLED; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -200,8 +200,8 @@ void GROUP_OT_objects_add_active(wmOperatorType *ot) static int objects_remove_active_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - Object *ob = OBACT; + SceneLayer *sl = CTX_data_scene_layer(C); + Object *ob = OBACT(sl); int single_group_index = RNA_enum_get(op->ptr, "group"); Group *single_group = group_object_active_find_index(ob, single_group_index); Group *group; @@ -221,7 +221,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op) /* Remove groups from selected objects */ CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - BKE_group_object_unlink(group, base->object, scene, base); + BKE_group_object_unlink(group, base->object); ok = 1; } CTX_DATA_END; @@ -231,7 +231,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op) if (!ok) BKE_report(op->reports, RPT_ERROR, "Active object contains no groups"); - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -264,15 +264,14 @@ void GROUP_OT_objects_remove_active(wmOperatorType *ot) static int group_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - BKE_object_groups_clear(scene, base, base->object); + BKE_object_groups_clear(base->object); } CTX_DATA_END; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -297,7 +296,6 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); int single_group_index = RNA_enum_get(op->ptr, "group"); Group *single_group = group_object_active_find_index(ob, single_group_index); Group *group; @@ -315,7 +313,7 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op) /* now remove all selected objects from the group */ CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - BKE_group_object_unlink(group, base->object, scene, base); + BKE_group_object_unlink(group, base->object); updated = true; } CTX_DATA_END; @@ -324,7 +322,7 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op) if (!updated) return OPERATOR_CANCELLED; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -357,7 +355,6 @@ void GROUP_OT_objects_remove(wmOperatorType *ot) static int group_create_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); Group *group = NULL; char name[MAX_ID_NAME - 2]; /* id name */ @@ -367,11 +364,11 @@ static int group_create_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, selected_bases) { - BKE_group_object_add(group, base->object, scene, base); + BKE_group_object_add(group, base->object); } CTX_DATA_END; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -398,7 +395,6 @@ void GROUP_OT_create(wmOperatorType *ot) static int group_add_exec(bContext *C, wmOperator *UNUSED(op)) { - Scene *scene = CTX_data_scene(C); Object *ob = ED_object_context(C); Main *bmain = CTX_data_main(C); Group *group; @@ -407,7 +403,7 @@ static int group_add_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; group = BKE_group_add(bmain, "Group"); - BKE_group_object_add(group, ob, scene, NULL); + BKE_group_object_add(group, ob); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -432,7 +428,6 @@ void OBJECT_OT_group_add(wmOperatorType *ot) static int group_link_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); Object *ob = ED_object_context(C); Group *group = BLI_findlink(&bmain->group, RNA_enum_get(op->ptr, "group")); @@ -457,7 +452,7 @@ static int group_link_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BKE_group_object_add(group, ob, scene, NULL); + BKE_group_object_add(group, ob); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -490,14 +485,13 @@ void OBJECT_OT_group_link(wmOperatorType *ot) static int group_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Scene *scene = CTX_data_scene(C); Object *ob = ED_object_context(C); Group *group = CTX_data_pointer_get_type(C, "group", &RNA_Group).data; if (!ob || !group) return OPERATOR_CANCELLED; - BKE_group_object_unlink(group, ob, scene, NULL); /* base will be used if found */ + BKE_group_object_unlink(group, ob); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -559,8 +553,10 @@ static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op)) /* Select o CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object)) { - ED_base_object_select(base, BA_SELECT); + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { + if (BKE_group_object_exists(group, base->object)) { + ED_object_base_select(base, BA_SELECT); + } } } CTX_DATA_END; diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index 42e3a4a6837..3f6651299be 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -48,7 +48,7 @@ #include "BKE_action.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" +#include "BKE_layer.h" #include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_object.h" @@ -57,6 +57,9 @@ #include "BKE_deform.h" #include "BKE_editmesh.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "RNA_define.h" #include "RNA_access.h" #include "RNA_enum_types.h" @@ -318,7 +321,7 @@ static bool object_hook_index_array(Scene *scene, Object *obedit, EDBM_mesh_load(obedit); EDBM_mesh_make(scene->toolsettings, obedit, true); - DAG_id_tag_update(obedit->data, 0); + DEG_id_tag_update(obedit->data, 0); em = me->edit_btmesh; @@ -445,34 +448,37 @@ static int hook_op_edit_poll(bContext *C) return 0; } -static Object *add_hook_object_new(Main *bmain, Scene *scene, Object *obedit) +static Object *add_hook_object_new(Main *bmain, Scene *scene, SceneLayer *sl, Object *obedit) { Base *base, *basedit; Object *ob; - ob = BKE_object_add(bmain, scene, OB_EMPTY, NULL); + ob = BKE_object_add(bmain, scene, sl, OB_EMPTY, NULL); - basedit = BKE_scene_base_find(scene, obedit); - base = scene->basact; + basedit = BKE_scene_layer_base_find(sl, obedit); + base = sl->basact; base->lay = ob->lay = obedit->lay; - BLI_assert(scene->basact->object == ob); + BLI_assert(sl->basact->object == ob); /* icky, BKE_object_add sets new base as active. * so set it back to the original edit object */ - scene->basact = basedit; + sl->basact = basedit; return ob; } -static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob, int mode, ReportList *reports) +static int add_hook_object(const bContext *C, Main *bmain, Scene *scene, SceneLayer *sl, Object *obedit, Object *ob, int mode, ReportList *reports) { ModifierData *md = NULL; HookModifierData *hmd = NULL; + EvaluationContext eval_ctx; float cent[3]; float pose_mat[4][4]; int tot, ok, *indexar; char name[MAX_NAME]; + CTX_data_eval_ctx(C, &eval_ctx); + ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent); if (!ok) { @@ -482,7 +488,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob if (mode == OBJECT_ADDHOOK_NEWOB && !ob) { - ob = add_hook_object_new(bmain, scene, obedit); + ob = add_hook_object_new(bmain, scene, sl, obedit); /* transform cent to global coords for loc */ mul_v3_m4v3(ob->loc, obedit->obmat, cent); @@ -541,13 +547,13 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob /* matrix calculus */ /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */ /* (parentinv ) */ - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); invert_m4_m4(ob->imat, ob->obmat); /* apparently this call goes from right to left... */ mul_m4_series(hmd->parentinv, pose_mat, ob->imat, obedit->obmat); - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); return true; } @@ -556,6 +562,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *obedit = CTX_data_edit_object(C); Object *obsel = NULL; const bool use_bone = RNA_boolean_get(op->ptr, "use_bone"); @@ -580,7 +587,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (add_hook_object(bmain, scene, obedit, obsel, mode, op->reports)) { + if (add_hook_object(C, bmain, scene, sl, obedit, obsel, mode, op->reports)) { WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit); return OPERATOR_FINISHED; } @@ -611,9 +618,10 @@ static int object_add_hook_newob_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *obedit = CTX_data_edit_object(C); - if (add_hook_object(bmain, scene, obedit, NULL, OBJECT_ADDHOOK_NEWOB, op->reports)) { + if (add_hook_object(C, bmain, scene, sl, obedit, NULL, OBJECT_ADDHOOK_NEWOB, op->reports)) { WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit); return OPERATOR_FINISHED; @@ -655,7 +663,7 @@ static int object_hook_remove_exec(bContext *C, wmOperator *op) BLI_remlink(&ob->modifiers, (ModifierData *)hmd); modifier_free((ModifierData *)hmd); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -729,7 +737,7 @@ static int object_hook_reset_exec(bContext *C, wmOperator *op) BKE_object_modifier_hook_reset(ob, hmd); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -779,7 +787,7 @@ static int object_hook_recenter_exec(bContext *C, wmOperator *op) sub_v3_v3v3(hmd->cent, scene->cursor, ob->obmat[3]); mul_m3_v3(imat, hmd->cent); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -837,7 +845,7 @@ static int object_hook_assign_exec(bContext *C, wmOperator *op) hmd->indexar = indexar; hmd->totindex = tot; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index b8957bdedf9..3e655fa04a4 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -55,6 +55,7 @@ void OBJECT_OT_scale_clear(struct wmOperatorType *ot); void OBJECT_OT_origin_clear(struct wmOperatorType *ot); void OBJECT_OT_visual_transform_apply(struct wmOperatorType *ot); void OBJECT_OT_transform_apply(struct wmOperatorType *ot); +void OBJECT_OT_transform_axis_target(struct wmOperatorType *ot); void OBJECT_OT_origin_set(struct wmOperatorType *ot); /* object_relations.c */ @@ -70,7 +71,6 @@ void OBJECT_OT_make_local(struct wmOperatorType *ot); void OBJECT_OT_make_single_user(struct wmOperatorType *ot); void OBJECT_OT_make_links_scene(struct wmOperatorType *ot); void OBJECT_OT_make_links_data(struct wmOperatorType *ot); -void OBJECT_OT_move_to_layer(struct wmOperatorType *ot); void OBJECT_OT_drop_named_material(struct wmOperatorType *ot); void OBJECT_OT_unlink_data(struct wmOperatorType *ot); @@ -78,10 +78,6 @@ void OBJECT_OT_unlink_data(struct wmOperatorType *ot); void OBJECT_OT_mode_set(struct wmOperatorType *ot); void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot); void OBJECT_OT_posemode_toggle(struct wmOperatorType *ot); -void OBJECT_OT_hide_view_set(struct wmOperatorType *ot); -void OBJECT_OT_hide_view_clear(struct wmOperatorType *ot); -void OBJECT_OT_hide_render_set(struct wmOperatorType *ot); -void OBJECT_OT_hide_render_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); @@ -117,6 +113,7 @@ void OBJECT_OT_metaball_add(struct wmOperatorType *ot); void OBJECT_OT_text_add(struct wmOperatorType *ot); void OBJECT_OT_armature_add(struct wmOperatorType *ot); void OBJECT_OT_empty_add(struct wmOperatorType *ot); +void OBJECT_OT_lightprobe_add(struct wmOperatorType *ot); void OBJECT_OT_drop_named_image(struct wmOperatorType *ot); void OBJECT_OT_lamp_add(struct wmOperatorType *ot); void OBJECT_OT_effector_add(struct wmOperatorType *ot); @@ -247,6 +244,15 @@ void OBJECT_OT_vertex_weight_set_active(struct wmOperatorType *ot); void OBJECT_OT_vertex_weight_normalize_active_vertex(struct wmOperatorType *ot); void OBJECT_OT_vertex_weight_copy(struct wmOperatorType *ot); +/* object_facemap_ops.c */ +void OBJECT_OT_face_map_add(struct wmOperatorType *ot); +void OBJECT_OT_face_map_remove(struct wmOperatorType *ot); +void OBJECT_OT_face_map_assign(struct wmOperatorType *ot); +void OBJECT_OT_face_map_remove_from(struct wmOperatorType *ot); +void OBJECT_OT_face_map_select(struct wmOperatorType *ot); +void OBJECT_OT_face_map_deselect(struct wmOperatorType *ot); +void OBJECT_OT_face_map_move(struct wmOperatorType *ot); + /* object_warp.c */ void TRANSFORM_OT_vertex_warp(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 57053ddc020..b2f9bee27ff 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -52,12 +52,13 @@ #include "RNA_enum_types.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_deform.h" #include "BKE_report.h" +#include "DEG_depsgraph.h" + #include "ED_lattice.h" #include "ED_object.h" #include "ED_screen.h" @@ -590,7 +591,7 @@ static int make_regular_exec(bContext *C, wmOperator *UNUSED(op)) BKE_lattice_resize(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); return OPERATOR_FINISHED; @@ -810,7 +811,7 @@ static int lattice_flip_exec(bContext *C, wmOperator *op) } /* updates */ - DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + DEG_id_tag_update(&obedit->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); return OPERATOR_FINISHED; diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 4e90a9bc7c4..a498e8a1564 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -54,7 +54,6 @@ #include "BKE_animsys.h" #include "BKE_curve.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_DerivedMesh.h" #include "BKE_effect.h" @@ -75,6 +74,9 @@ #include "BKE_softbody.h" #include "BKE_editmesh.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -171,8 +173,8 @@ 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); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); return new_md; } @@ -253,7 +255,7 @@ bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v) for (md = ob->modifiers.first; md; md = md->next) { if (md->type == eModifierType_Multires) { multires_set_tot_level(ob, (MultiresModifierData *)md, totlevel); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } } return false; @@ -320,7 +322,7 @@ static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md, ob->mode &= ~OB_MODE_PARTICLE_EDIT; } - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); BLI_remlink(&ob->modifiers, md); modifier_free(md); @@ -341,8 +343,8 @@ bool ED_object_modifier_remove(ReportList *reports, Main *bmain, Object *ob, Mod return 0; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - DAG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); return 1; } @@ -365,8 +367,8 @@ void ED_object_modifier_clear(Main *bmain, Object *ob) md = next_md; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - DAG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); } int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md) @@ -411,7 +413,7 @@ int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData * return 1; } -int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md) +int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, SceneLayer *sl, Object *ob, ModifierData *md) { Object *obn; ParticleSystem *psys; @@ -463,7 +465,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, NULL); + obn = BKE_object_add(bmain, scene, sl, OB_MESH, NULL); me = obn->data; me->totvert = totvert; @@ -515,14 +517,17 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene * } } - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); return 1; } -static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) +static int modifier_apply_shape(ReportList *reports, const bContext *C, Scene *scene, Object *ob, ModifierData *md) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); md->scene = scene; @@ -553,7 +558,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M return 0; } - dm = mesh_create_derived_for_modifier(scene, ob, md, 0); + dm = mesh_create_derived_for_modifier(&eval_ctx, scene, ob, md, 0); if (!dm) { BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply"); return 0; @@ -580,9 +585,12 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M return 1; } -static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) +static int modifier_apply_obdata(ReportList *reports, const bContext *C, Scene *scene, Object *ob, ModifierData *md) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); md->scene = scene; @@ -606,13 +614,13 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, multires_force_update(ob); if (mmd && mmd->totlvl && mti->type == eModifierTypeType_OnlyDeform) { - if (!multiresModifier_reshapeFromDeformMod(scene, mmd, ob, md)) { + if (!multiresModifier_reshapeFromDeformMod(&eval_ctx, 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, 1); + dm = mesh_create_derived_for_modifier(&eval_ctx, scene, ob, md, 1); if (!dm) { BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply"); return 0; @@ -638,12 +646,12 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tessellated/bevel vertices"); vertexCos = BKE_curve_nurbs_vertexCos_get(&cu->nurb, &numVerts); - mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0); + mti->deformVerts(md, &eval_ctx, ob, NULL, vertexCos, numVerts, 0); BK_curve_nurbs_vertexCos_apply(&cu->nurb, vertexCos); MEM_freeN(vertexCos); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); @@ -660,14 +668,14 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, if (psys->part->type != PART_HAIR) continue; - psys_apply_hair_lattice(scene, ob, psys); + psys_apply_hair_lattice(&eval_ctx, scene, ob, psys); } } return 1; } -int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode) +int ED_object_modifier_apply(ReportList *reports, const bContext *C, Scene *scene, Object *ob, ModifierData *md, int mode) { int prev_mode; @@ -695,13 +703,13 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi md->mode |= eModifierMode_Realtime; if (mode == MODIFIER_APPLY_SHAPE) { - if (!modifier_apply_shape(reports, scene, ob, md)) { + if (!modifier_apply_shape(reports, C, scene, ob, md)) { md->mode = prev_mode; return 0; } } else { - if (!modifier_apply_obdata(reports, scene, ob, md)) { + if (!modifier_apply_obdata(reports, C, scene, ob, md)) { md->mode = prev_mode; return 0; } @@ -874,7 +882,7 @@ ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type) static int modifier_remove_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); int mode_orig = ob->mode; @@ -887,7 +895,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op) /* if cloth/softbody was removed, particle mode could be cleared */ if (mode_orig & OB_MODE_PARTICLE_EDIT) if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) - if (scene->basact && scene->basact->object == ob) + if (sl->basact && sl->basact->object == ob) WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL); return OPERATOR_FINISHED; @@ -926,7 +934,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op) if (!md || !ED_object_modifier_move_up(op->reports, ob, md)) return OPERATOR_CANCELLED; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -965,7 +973,7 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op) if (!md || !ED_object_modifier_move_down(op->reports, ob, md)) return OPERATOR_CANCELLED; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1003,11 +1011,11 @@ static int modifier_apply_exec(bContext *C, wmOperator *op) ModifierData *md = edit_modifier_property_get(op, ob, 0); int apply_as = RNA_enum_get(op->ptr, "apply_as"); - if (!md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) { + if (!md || !ED_object_modifier_apply(op->reports, C, scene, ob, md, apply_as)) { return OPERATOR_CANCELLED; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1050,13 +1058,14 @@ static int modifier_convert_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md)) + if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, sl, ob, md)) return OPERATOR_CANCELLED; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1095,7 +1104,7 @@ static int modifier_copy_exec(bContext *C, wmOperator *op) if (!md || !ED_object_modifier_copy(op->reports, ob, md)) return OPERATOR_CANCELLED; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1189,7 +1198,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) ED_object_multires_update_totlevels_cb, &mmd->totlvl); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); if (ob->mode & OB_MODE_SCULPT) { @@ -1229,8 +1238,11 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C), *secondob = NULL; Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires); + CTX_data_eval_ctx(C, &eval_ctx); + if (!mmd) return OPERATOR_CANCELLED; @@ -1253,12 +1265,12 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (!multiresModifier_reshape(scene, mmd, ob, secondob)) { + if (!multiresModifier_reshape(&eval_ctx, scene, mmd, ob, secondob)) { BKE_report(op->reports, RPT_ERROR, "Objects do not have the same number of vertices"); return OPERATOR_CANCELLED; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1406,7 +1418,7 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op) multiresModifier_base_apply(mmd, ob); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1512,7 +1524,7 @@ static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op)) BLI_gset_free(visited, NULL); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1567,7 +1579,7 @@ static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op) } } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1617,7 +1629,7 @@ static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op)) } } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1686,8 +1698,10 @@ static void skin_armature_bone_create(Object *skin_ob, } } -static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object *skin_ob) +static Object *modifier_skin_armature_create(const bContext *C, Scene *scene, SceneLayer *sl, Object *skin_ob) { + Main *bmain = CTX_data_main(C); + EvaluationContext eval_ctx; BLI_bitmap *edges_visited; DerivedMesh *deform_dm; MVert *mvert; @@ -1699,7 +1713,9 @@ static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object * int *emap_mem; int v; - deform_dm = mesh_get_derived_deform(scene, skin_ob, CD_MASK_BAREMESH); + CTX_data_eval_ctx(C, &eval_ctx); + + deform_dm = mesh_get_derived_deform(&eval_ctx, scene, skin_ob, CD_MASK_BAREMESH); mvert = deform_dm->getVertArray(deform_dm); /* add vertex weights to original mesh */ @@ -1709,7 +1725,7 @@ static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object * NULL, me->totvert); - arm_ob = BKE_object_add(bmain, scene, OB_ARMATURE, NULL); + arm_ob = BKE_object_add(bmain, scene, sl, OB_ARMATURE, NULL); BKE_object_transform_copy(arm_ob, skin_ob); arm = arm_ob->data; arm->layer = 1; @@ -1768,6 +1784,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *ob = CTX_data_active_object(C), *arm_ob; Mesh *me = ob->data; ModifierData *skin_md; @@ -1779,7 +1796,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op) } /* create new armature */ - arm_ob = modifier_skin_armature_create(bmain, scene, ob); + arm_ob = modifier_skin_armature_create(C, scene, sl, ob); /* add a modifier to connect the new armature to the mesh */ arm_md = (ArmatureModifierData *)modifier_new(eModifierType_Armature); @@ -1789,8 +1806,8 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op) arm_md->object = arm_ob; arm_md->deformflag = ARM_DEF_VGROUP | ARM_DEF_QUATERNION; - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -1857,7 +1874,7 @@ static int correctivesmooth_bind_exec(bContext *C, wmOperator *op) csmd->bind_coords_num = (unsigned int)-1; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1899,8 +1916,11 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); + EvaluationContext eval_ctx; MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform); + CTX_data_eval_ctx(C, &eval_ctx); + if (!mmd) return OPERATOR_CANCELLED; @@ -1926,7 +1946,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) mmd->totcagevert = 0; mmd->totinfluence = 0; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); } else { @@ -1938,17 +1958,17 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) mmd->modifier.mode |= eModifierMode_Realtime; if (ob->type == OB_MESH) { - dm = mesh_create_derived_view(scene, ob, 0); + dm = mesh_create_derived_view(&eval_ctx, scene, ob, 0); dm->release(dm); } else if (ob->type == OB_LATTICE) { - BKE_lattice_modifiers_calc(scene, ob); + BKE_lattice_modifiers_calc(&eval_ctx, scene, ob); } else if (ob->type == OB_MBALL) { - BKE_displist_make_mball(CTX_data_main(C)->eval_ctx, scene, ob); + BKE_displist_make_mball(&eval_ctx, scene, ob); } else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { - BKE_displist_make_curveTypes(scene, ob, 0); + BKE_displist_make_curveTypes(&eval_ctx, scene, ob, 0); } mmd->bindfunc = NULL; @@ -2000,7 +2020,7 @@ static int explode_refresh_exec(bContext *C, wmOperator *op) emd->flag |= eExplodeFlag_CalcFaces; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -2145,7 +2165,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) if (free) { omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; } @@ -2173,7 +2193,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) * this part of the process before a threaded job is created */ //scene->r.cfra = f; - //ED_update_for_newframe(CTX_data_main(C), scene, 1); + //ED_update_for_newframe(CTX_data_main(C), scene); /* ok, this doesn't work with drivers, but is way faster. * let's use this for now and hope nobody wants to drive the time value... */ @@ -2195,7 +2215,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) scene->r.cfra = cfra; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); #endif @@ -2268,7 +2288,7 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op) else { lmd->flag |= MOD_LAPLACIANDEFORM_BIND; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; } @@ -2320,7 +2340,7 @@ static int surfacedeform_bind_exec(bContext *C, wmOperator *op) smd->flags |= MOD_SDEF_BIND; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 9b9f77a1dbb..c87df877d5c 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -61,16 +61,13 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_origin_clear); WM_operatortype_append(OBJECT_OT_visual_transform_apply); WM_operatortype_append(OBJECT_OT_transform_apply); + WM_operatortype_append(OBJECT_OT_transform_axis_target); WM_operatortype_append(OBJECT_OT_origin_set); WM_operatortype_append(OBJECT_OT_mode_set); WM_operatortype_append(OBJECT_OT_editmode_toggle); WM_operatortype_append(OBJECT_OT_posemode_toggle); WM_operatortype_append(OBJECT_OT_proxy_make); - WM_operatortype_append(OBJECT_OT_hide_view_clear); - WM_operatortype_append(OBJECT_OT_hide_view_set); - WM_operatortype_append(OBJECT_OT_hide_render_clear); - WM_operatortype_append(OBJECT_OT_hide_render_set); WM_operatortype_append(OBJECT_OT_shade_smooth); WM_operatortype_append(OBJECT_OT_shade_flat); WM_operatortype_append(OBJECT_OT_paths_calculate); @@ -90,13 +87,11 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_make_single_user); WM_operatortype_append(OBJECT_OT_make_links_scene); WM_operatortype_append(OBJECT_OT_make_links_data); - WM_operatortype_append(OBJECT_OT_move_to_layer); 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); WM_operatortype_append(OBJECT_OT_select_grouped); WM_operatortype_append(OBJECT_OT_select_mirror); @@ -113,6 +108,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_text_add); WM_operatortype_append(OBJECT_OT_armature_add); WM_operatortype_append(OBJECT_OT_empty_add); + WM_operatortype_append(OBJECT_OT_lightprobe_add); WM_operatortype_append(OBJECT_OT_drop_named_image); WM_operatortype_append(OBJECT_OT_lamp_add); WM_operatortype_append(OBJECT_OT_camera_add); @@ -202,6 +198,14 @@ 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_face_map_add); + WM_operatortype_append(OBJECT_OT_face_map_remove); + WM_operatortype_append(OBJECT_OT_face_map_assign); + WM_operatortype_append(OBJECT_OT_face_map_remove_from); + WM_operatortype_append(OBJECT_OT_face_map_select); + WM_operatortype_append(OBJECT_OT_face_map_deselect); + WM_operatortype_append(OBJECT_OT_face_map_move); + WM_operatortype_append(TRANSFORM_OT_vertex_warp); WM_operatortype_append(OBJECT_OT_game_property_new); @@ -376,25 +380,6 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "OBJECT_OT_origin_clear", OKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0); - kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0); - RNA_boolean_set(kmi->ptr, "unselected", false); - - kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "unselected", true); - - /* same as above but for rendering */ - WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_clear", HKEY, KM_PRESS, KM_ALT | KM_CTRL, 0); - WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_CTRL, 0); - - /* conflicts, removing */ -#if 0 - kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0) - RNA_boolean_set(kmi->ptr, "unselected", true); -#endif - - WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0); - kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "use_global", false); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index f8c80f2a933..eee1ae64505 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -63,10 +63,10 @@ #include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_camera.h" +#include "BKE_collection.h" #include "BKE_context.h" #include "BKE_constraint.h" #include "BKE_curve.h" -#include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_displist.h" #include "BKE_global.h" @@ -75,6 +75,7 @@ #include "BKE_idprop.h" #include "BKE_lamp.h" #include "BKE_lattice.h" +#include "BKE_layer.h" #include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_library_remap.h" @@ -92,6 +93,9 @@ #include "BKE_texture.h" #include "BKE_editmesh.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "WM_api.h" #include "WM_types.h" @@ -123,7 +127,9 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *obedit = CTX_data_edit_object(C); + EvaluationContext eval_ctx; BMVert *eve; BMIter iter; Curve *cu; @@ -133,6 +139,8 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) Object *par; int a, v1 = 0, v2 = 0, v3 = 0, v4 = 0, nr = 1; + CTX_data_eval_ctx(C, &eval_ctx); + /* we need 1 to 3 selected vertices */ if (obedit->type == OB_MESH) { @@ -142,7 +150,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) EDBM_mesh_load(obedit); EDBM_mesh_make(scene->toolsettings, obedit, true); - DAG_id_tag_update(obedit->data, 0); + DEG_id_tag_update(obedit->data, 0); em = me->edit_btmesh; @@ -151,7 +159,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) /* derivedMesh might be needed for solving parenting, * so re-create it here */ - makeDerivedMesh(scene, obedit, em, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX, false); + makeDerivedMesh(&eval_ctx, scene, obedit, em, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX, false); BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { @@ -230,7 +238,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { if (ob != obedit) { - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); par = obedit->parent; if (BKE_object_parent_loop_check(par, ob)) { @@ -239,7 +247,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) else { Object workob; - ob->parent = BASACT->object; + ob->parent = BASACT(sl)->object; if (v3) { ob->partype = PARVERT3; ob->par1 = v1 - 1; @@ -247,7 +255,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) ob->par3 = v3 - 1; /* inverse parent matrix */ - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } else { @@ -255,7 +263,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) ob->par1 = v1 - 1; /* inverse parent matrix */ - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } } @@ -263,7 +271,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT, NULL); @@ -334,6 +342,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op) Object *ob, *gob = ED_object_active_context(C); GroupObject *go; Scene *scene = CTX_data_scene(C); + SceneLayer *scene_layer = CTX_data_scene_layer(C); if (gob->dup_group != NULL) { go = BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "object")); @@ -346,30 +355,28 @@ static int make_proxy_exec(bContext *C, wmOperator *op) if (ob) { Object *newob; - Base *newbase, *oldbase = BASACT; char name[MAX_ID_NAME + 4]; BLI_snprintf(name, sizeof(name), "%s_proxy", ((ID *)(gob ? gob : ob))->name + 2); /* Add new object for the proxy */ - newob = BKE_object_add(bmain, scene, OB_EMPTY, name); + newob = BKE_object_add_from(bmain, scene, scene_layer, OB_EMPTY, name, gob ? gob : ob); /* set layers OK */ - newbase = BASACT; /* BKE_object_add sets active... */ - newbase->lay = oldbase->lay; - newob->lay = newbase->lay; - - /* remove base, leave user count of object, it gets linked in BKE_object_make_proxy */ - if (gob == NULL) { - BKE_scene_base_unlink(scene, oldbase); - MEM_freeN(oldbase); - } - BKE_object_make_proxy(newob, ob, gob); + /* Set back pointer immediately so dependency graph knows that this is + * is a proxy and will act accordingly. Otherwise correctness of graph + * will depend on order of bases. + * + * TODO(sergey): We really need to get rid of this bi-directional links + * in proxies with something like static overrides. + */ + newob->proxy->proxy_from = newob; + /* depsgraph flushes are needed for the new data */ - DAG_relations_tag_update(bmain); - DAG_id_tag_update(&newob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&newob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, newob); } else { @@ -524,7 +531,7 @@ void ED_object_parent_clear(Object *ob, const int type) /* Always clear parentinv matrix for sake of consistency, see T41950. */ unit_m4(ob->parentinv); - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); } /* note, poll should check for editable scene */ @@ -539,7 +546,7 @@ static int parent_clear_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); return OPERATOR_FINISHED; @@ -607,13 +614,17 @@ EnumPropertyItem prop_make_parent_types[] = { {0, NULL, 0, NULL, NULL} }; -bool ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object *ob, Object *par, +bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene, Object *ob, Object *par, int partype, const bool xmirror, const bool keep_transform, const int vert_par[3]) { + Main *bmain = CTX_data_main(C); + EvaluationContext eval_ctx; bPoseChannel *pchan = NULL; const bool pararm = ELEM(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); - DAG_id_tag_update(&par->id, OB_RECALC_OB); + CTX_data_eval_ctx(C, &eval_ctx); + + DEG_id_tag_update(&par->id, OB_RECALC_OB); /* preconditions */ if (partype == PAR_FOLLOW || partype == PAR_PATH_CONST) { @@ -624,7 +635,7 @@ bool ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object if ((cu->flag & CU_PATH) == 0) { cu->flag |= CU_PATH | CU_FOLLOW; - BKE_displist_make_curveTypes(scene, par, 0); /* force creation of path data */ + BKE_displist_make_curveTypes(&eval_ctx, scene, par, 0); /* force creation of path data */ } else { cu->flag |= CU_FOLLOW; @@ -710,7 +721,7 @@ bool ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object ((CurveModifierData *)md)->object = par; } if (par->curve_cache && par->curve_cache->path == NULL) { - DAG_id_tag_update(&par->id, OB_RECALC_DATA); + DEG_id_tag_update(&par->id, OB_RECALC_DATA); } } break; @@ -766,34 +777,36 @@ bool ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object data = con->data; data->tar = par; - BKE_constraint_target_matrix_get(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra); + BKE_constraint_target_matrix_get(&eval_ctx, scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra); sub_v3_v3v3(vec, ob->obmat[3], cmat[3]); copy_v3_v3(ob->loc, vec); } else if (pararm && (ob->type == OB_MESH) && (par->type == OB_ARMATURE)) { - if (partype == PAR_ARMATURE_NAME) - create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_NAME, false); - else if (partype == PAR_ARMATURE_ENVELOPE) - create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror); + if (partype == PAR_ARMATURE_NAME) { + create_vgroups_from_armature(reports, &eval_ctx, scene, ob, par, ARM_GROUPS_NAME, false); + } + else if (partype == PAR_ARMATURE_ENVELOPE) { + create_vgroups_from_armature(reports, &eval_ctx, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror); + } else if (partype == PAR_ARMATURE_AUTO) { WM_cursor_wait(1); - create_vgroups_from_armature(reports, scene, ob, par, ARM_GROUPS_AUTO, xmirror); + create_vgroups_from_armature(reports, &eval_ctx, scene, ob, par, ARM_GROUPS_AUTO, xmirror); WM_cursor_wait(0); } /* get corrected inverse */ ob->partype = PAROBJECT; - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } else { /* calculate inverse parent matrix */ - BKE_object_workob_calc_parent(scene, ob, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); } } @@ -864,7 +877,7 @@ static int parent_set_exec(bContext *C, wmOperator *op) parent_set_vert_find(tree, ob, vert_par, is_tri); } - if (!ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, xmirror, keep_transform, vert_par_p)) { + if (!ED_object_parent_set(op->reports, C, scene, ob, par, partype, xmirror, keep_transform, vert_par_p)) { ok = false; break; } @@ -879,7 +892,7 @@ static int parent_set_exec(bContext *C, wmOperator *op) if (!ok) return OPERATOR_CANCELLED; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); @@ -996,7 +1009,7 @@ static int parent_noinv_set_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Object *par = ED_object_active_context(C); - DAG_id_tag_update(&par->id, OB_RECALC_OB); + DEG_id_tag_update(&par->id, OB_RECALC_OB); /* context iterator */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) @@ -1011,7 +1024,7 @@ static int parent_noinv_set_exec(bContext *C, wmOperator *op) memset(ob->loc, 0, 3 * sizeof(float)); /* set recalc flags */ - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); /* set parenting type for object - object only... */ ob->parent = par; @@ -1021,7 +1034,7 @@ static int parent_noinv_set_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; @@ -1048,15 +1061,18 @@ void OBJECT_OT_parent_no_inverse_set(wmOperatorType *ot) static int object_slow_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { if (ob->parent) { if (ob->partype & PARSLOW) { ob->partype -= PARSLOW; - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); ob->partype |= PARSLOW; - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } } } @@ -1094,7 +1110,7 @@ static int object_slow_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) if (ob->parent) ob->partype |= PARSLOW; - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } CTX_DATA_END; @@ -1148,7 +1164,7 @@ static int object_track_clear_exec(bContext *C, wmOperator *op) /* remove track-object for old track */ ob->track = NULL; - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* also remove all tracking constraints */ for (con = ob->constraints.last; con; con = pcon) { @@ -1162,7 +1178,7 @@ static int object_track_clear_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; @@ -1222,7 +1238,7 @@ static int track_set_exec(bContext *C, wmOperator *op) data = con->data; data->tar = obact; - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* Lamp, Camera and Speaker track differently by default */ if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { @@ -1245,7 +1261,7 @@ static int track_set_exec(bContext *C, wmOperator *op) data = con->data; data->tar = obact; - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* Lamp, Camera and Speaker track differently by default */ if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { @@ -1269,7 +1285,7 @@ static int track_set_exec(bContext *C, wmOperator *op) data = con->data; data->tar = obact; - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* Lamp, Camera and Speaker track differently by default */ if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { @@ -1283,7 +1299,7 @@ static int track_set_exec(bContext *C, wmOperator *op) } } - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; @@ -1309,119 +1325,6 @@ void OBJECT_OT_track_set(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_make_track_types, 0, "Type", ""); } -/************************** Move to Layer Operator *****************************/ - -static unsigned int move_to_layer_init(bContext *C, wmOperator *op) -{ - int values[20], a; - unsigned int lay = 0; - - if (!RNA_struct_property_is_set(op->ptr, "layers")) { - /* note: layers are set in bases, library objects work for this */ - CTX_DATA_BEGIN (C, Base *, base, selected_bases) - { - lay |= base->lay; - } - CTX_DATA_END; - - for (a = 0; a < 20; a++) - values[a] = (lay & (1 << a)) != 0; - - RNA_boolean_set_array(op->ptr, "layers", values); - } - else { - RNA_boolean_get_array(op->ptr, "layers", values); - - for (a = 0; a < 20; a++) - if (values[a]) - lay |= (1 << a); - } - - return lay; -} - -static int move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - View3D *v3d = CTX_wm_view3d(C); - if (v3d && v3d->localvd) { - return WM_operator_confirm_message(C, op, "Move out of Local View"); - } - else { - move_to_layer_init(C, op); - return WM_operator_props_popup(C, op, event); - } -} - -static int move_to_layer_exec(bContext *C, wmOperator *op) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - unsigned int lay, local; - /* bool is_lamp = false; */ /* UNUSED */ - - lay = move_to_layer_init(C, op); - lay &= 0xFFFFFF; - - if (lay == 0) return OPERATOR_CANCELLED; - - if (v3d && v3d->localvd) { - /* now we can move out of localview. */ - /* note: layers are set in bases, library objects work for this */ - CTX_DATA_BEGIN (C, Base *, base, selected_bases) - { - lay = base->lay & ~v3d->lay; - base->lay = lay; - base->object->lay = lay; - base->object->flag &= ~SELECT; - base->flag &= ~SELECT; - /* if (base->object->type == OB_LAMP) is_lamp = true; */ - } - CTX_DATA_END; - } - else { - /* normal non localview operation */ - /* note: layers are set in bases, library objects work for this */ - CTX_DATA_BEGIN (C, Base *, base, selected_bases) - { - /* upper byte is used for local view */ - local = base->lay & 0xFF000000; - base->lay = lay + local; - base->object->lay = base->lay; - /* if (base->object->type == OB_LAMP) is_lamp = true; */ - } - CTX_DATA_END; - } - - /* warning, active object may be hidden now */ - - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene); - WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); - - DAG_relations_tag_update(bmain); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_move_to_layer(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Move to Layer"; - ot->description = "Move the object to different layers"; - ot->idname = "OBJECT_OT_move_to_layer"; - - /* api callbacks */ - ot->invoke = move_to_layer_invoke; - ot->exec = move_to_layer_exec; - ot->poll = ED_operator_objectmode; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", ""); -} - /************************** Link to Scene Operator *****************************/ #if 0 @@ -1444,20 +1347,6 @@ static void link_to_scene(Main *UNUSED(bmain), unsigned short UNUSED(nr)) } #endif -Base *ED_object_scene_link(Scene *scene, Object *ob) -{ - Base *base; - - if (BKE_scene_base_find(scene, ob)) { - return NULL; - } - - base = BKE_scene_base_add(scene, ob); - id_us_plus(&ob->id); - - return base; -} - 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, "scene")); @@ -1477,9 +1366,10 @@ static int make_links_scene_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + SceneCollection *sc_to = BKE_collection_master(scene_to); CTX_DATA_BEGIN (C, Base *, base, selected_bases) { - ED_object_scene_link(scene_to, base->object); + BKE_collection_object_add(scene_to, sc_to, base->object); } CTX_DATA_END; @@ -1535,7 +1425,6 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst static int make_links_data_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); const int type = RNA_enum_get(op->ptr, "type"); Object *ob_src; ID *obdata_id; @@ -1572,7 +1461,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op) /* if amount of material indices changed: */ test_object_materials(ob_dst, ob_dst->data); - DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); break; case MAKE_LINKS_MATERIALS: /* new approach, using functions from kernel */ @@ -1580,7 +1469,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op) Material *ma = give_current_material(ob_src, a + 1); assign_material(ob_dst, ma, a + 1, BKE_MAT_ASSIGN_USERPREF); /* also works with ma==NULL */ } - DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA); break; case MAKE_LINKS_ANIMDATA: BKE_animdata_copy_id(bmain, (ID *)ob_dst, (ID *)ob_src, false); @@ -1591,19 +1480,19 @@ static int make_links_data_exec(bContext *C, wmOperator *op) } BKE_animdata_copy_id(bmain, (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); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); break; case MAKE_LINKS_GROUP: { LinkNode *group_node; /* first clear groups */ - BKE_object_groups_clear(scene, base_dst, ob_dst); + BKE_object_groups_clear(ob_dst); /* now add in the groups from the link nodes */ for (group_node = ob_groups; group_node; group_node = group_node->next) { if (ob_dst->dup_group != group_node->link) { - BKE_group_object_add(group_node->link, ob_dst, scene, base_dst); + BKE_group_object_add(group_node->link, ob_dst); } else { is_cycle = true; @@ -1620,7 +1509,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op) break; case MAKE_LINKS_MODIFIERS: BKE_object_link_modifiers(ob_dst, ob_src); - DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); break; case MAKE_LINKS_FONTS: { @@ -1649,7 +1538,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op) cu_dst->vfontbi = cu_src->vfontbi; id_us_plus((ID *)cu_dst->vfontbi); - DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); break; } } @@ -1672,7 +1561,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_WARNING, "Skipped editing library object data"); } - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, CTX_wm_view3d(C)); WM_event_add_notifier(C, NC_OBJECT, NULL); @@ -1736,48 +1625,82 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot) /**************************** Make Single User ********************************/ +static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob, const bool copy_groups) +{ + if (!ID_IS_LINKED(ob) && ob->id.us > 1) { + /* base gets copy of object */ + Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); + + if (copy_groups) { + if (ob->flag & OB_FROMGROUP) { + obn->flag |= OB_FROMGROUP; + } + } + else { + /* copy already clears */ + } + /* remap gpencil parenting */ + + if (scene->gpd) { + bGPdata *gpd = scene->gpd; + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if (gpl->parent == ob) { + gpl->parent = obn; + } + } + } + + id_us_min(&ob->id); + return obn; + } + return NULL; +} + +static void libblock_relink_scene_collection(SceneCollection *sc) +{ + for (LinkData *link = sc->objects.first; link; link = link->next) { + BKE_libblock_relink_to_newid(link->data); + } + + for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { + libblock_relink_scene_collection(nsc); + } +} + +static void single_object_users_scene_collection(Main *bmain, Scene *scene, SceneCollection *sc, const int flag, const bool copy_groups) +{ + for (LinkData *link = sc->objects.first; link; link = link->next) { + Object *ob = link->data; + /* an object may be in more than one collection */ + if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) { + link->data = single_object_users_object(bmain, scene, link->data, copy_groups); + } + } + + /* we reset filter objects because they should be regenerated after this */ + BLI_freelistN(&sc->filter_objects); + + for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { + single_object_users_scene_collection(bmain, scene, nsc, flag, copy_groups); + } +} + /* Warning, sets ID->newid pointers of objects and groups, but does not clear them. */ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups) { - Base *base; - Object *ob, *obn; Group *group, *groupn; GroupObject *go; clear_sca_new_poins(); /* BGE logic */ - /* duplicate (must set newid) */ - for (base = FIRSTBASE; base; base = base->next) { - ob = base->object; + /* duplicate all the objects of the scene */ + SceneCollection *msc = BKE_collection_master(scene); + single_object_users_scene_collection(bmain, scene, msc, flag, copy_groups); - if ((base->flag & flag) == flag) { - if (!ID_IS_LINKED(ob) && ob->id.us > 1) { - /* base gets copy of object */ - base->object = obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); - - if (copy_groups) { - if (ob->flag & OB_FROMGROUP) { - obn->flag |= OB_FROMGROUP; - } - } - else { - /* copy already clears */ - } - /* remap gpencil parenting */ - - if (scene->gpd) { - bGPdata *gpd = scene->gpd; - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - if (gpl->parent == ob) { - gpl->parent = obn; - } - } - } - - base->flag = obn->flag; - - id_us_min(&ob->id); - } + /* loop over SceneLayers and assign the pointers accordingly */ + for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) { + for (Base *base = sl->object_bases.first; base; base = base->next) { + ID_NEW_REMAP(base->object); } } @@ -1810,27 +1733,28 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in if (v3d) ID_NEW_REMAP(v3d->camera); /* object and group pointers */ - for (base = FIRSTBASE; base; base = base->next) { - BKE_libblock_relink_to_newid(&base->object->id); - } + libblock_relink_scene_collection(msc); set_sca_new_poins(); + + /* TODO redo filter */ + TODO_LAYER_SYNC_FILTER } /* not an especially efficient function, only added so the single user * button can be functional.*/ void ED_object_single_user(Main *bmain, Scene *scene, Object *ob) { - Base *base; - const bool copy_groups = false; - - for (base = FIRSTBASE; base; base = base->next) { - if (base->object == ob) base->flag |= OB_DONE; - else base->flag &= ~OB_DONE; + FOREACH_SCENE_OBJECT(scene, ob_iter) + { + ob_iter->flag &= ~OB_DONE; } + FOREACH_SCENE_OBJECT_END - single_object_users(bmain, scene, NULL, OB_DONE, copy_groups); + /* tag only the one object */ + ob->flag |= OB_DONE; + single_object_users(bmain, scene, NULL, OB_DONE, false); BKE_main_id_clear_newpoins(bmain); } @@ -1855,25 +1779,23 @@ static void new_id_matar(Main *bmain, Material **matar, const int totcol) } } -static void single_obdata_users(Main *bmain, Scene *scene, const int flag) +static void single_obdata_users(Main *bmain, Scene *scene, SceneLayer *sl, const int flag) { - Object *ob; Lamp *la; Curve *cu; /* Camera *cam; */ - Base *base; Mesh *me; Lattice *lat; ID *id; int a; - for (base = FIRSTBASE; base; base = base->next) { - ob = base->object; - if (!ID_IS_LINKED(ob) && (base->flag & flag) == flag) { + FOREACH_OBJECT_FLAG(scene, sl, flag, ob) + { + if (!ID_IS_LINKED(ob)) { id = ob->data; if (id && id->us > 1 && !ID_IS_LINKED(id)) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); switch (ob->type) { case OB_LAMP: @@ -1911,7 +1833,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag) BKE_animdata_copy_id_action((ID *)lat->key, false); break; case OB_ARMATURE: - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); ob->data = ID_NEW_SET(ob->data, BKE_armature_copy(bmain, ob->data)); BKE_pose_rebuild(ob, ob->data); break; @@ -1935,6 +1857,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag) } } } + FOREACH_OBJECT_FLAG_END me = bmain->mesh.first; while (me) { @@ -1943,31 +1866,24 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag) } } -static void single_object_action_users(Scene *scene, const int flag) +static void single_object_action_users(Scene *scene, SceneLayer *sl, const int flag) { - Object *ob; - Base *base; - - for (base = FIRSTBASE; base; base = base->next) { - ob = base->object; - if (!ID_IS_LINKED(ob) && (flag == 0 || (base->flag & SELECT)) ) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + FOREACH_OBJECT_FLAG(scene, sl, flag, ob) + if (!ID_IS_LINKED(ob)) { + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); BKE_animdata_copy_id_action(&ob->id, false); } - } + FOREACH_OBJECT_FLAG_END } -static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bool do_textures) +static void single_mat_users(Main *bmain, Scene *scene, SceneLayer *sl, const int flag, const bool do_textures) { - Object *ob; - Base *base; Material *ma, *man; Tex *tex; int a, b; - for (base = FIRSTBASE; base; base = base->next) { - ob = base->object; - if (!ID_IS_LINKED(ob) && (flag == 0 || (base->flag & SELECT)) ) { + FOREACH_OBJECT_FLAG(scene, sl, flag, ob) + if (!ID_IS_LINKED(ob)) { for (a = 1; a <= ob->totcol; a++) { ma = give_current_material(ob, a); if (ma) { @@ -1996,7 +1912,7 @@ static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bo } } } - } + FOREACH_OBJECT_FLAG_END } static void do_single_tex_user(Main *bmain, Tex **from) @@ -2099,8 +2015,8 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo single_object_users(bmain, scene, NULL, 0, copy_groups); if (full) { - single_obdata_users(bmain, scene, 0); - single_object_action_users(scene, 0); + single_obdata_users(bmain, scene, NULL, 0); + single_object_action_users(scene, NULL, 0); single_mat_users_expand(bmain); single_tex_users_expand(bmain); } @@ -2121,12 +2037,13 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo { IDP_RelinkProperty(scene->id.properties); - for (Base *base = scene->base.first; base; base = base->next) { - Object *ob = base->object; + FOREACH_SCENE_OBJECT(scene, ob) + { if (!ID_IS_LINKED(ob)) { IDP_RelinkProperty(ob->id.properties); } } + FOREACH_SCENE_OBJECT_END if (scene->nodetree) { IDP_RelinkProperty(scene->nodetree->id.properties); @@ -2148,7 +2065,7 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo } } BKE_main_id_clear_newpoins(bmain); - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); } /******************************* Make Local ***********************************/ @@ -2215,7 +2132,7 @@ static void tag_localizable_objects(bContext *C, const int mode) * Instance indirectly referenced zero user objects, * otherwise they're lost on reload, see T40595. */ -static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene) +static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene, SceneLayer *sl, SceneCollection *sc) { Object *ob; bool changed = false; @@ -2226,10 +2143,11 @@ static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene) id_us_plus(&ob->id); - base = BKE_scene_base_add(scene, ob); - base->flag |= SELECT; - base->object->flag = base->flag; - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + BKE_collection_object_add(scene, sc, ob); + base = BKE_scene_layer_base_find(sl, ob); + base->flag |= BASE_SELECTED; + BKE_scene_object_base_flag_sync_from_base(base); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); changed = true; } @@ -2308,12 +2226,15 @@ static int make_local_exec(bContext *C, wmOperator *op) /* Note: we (ab)use LIB_TAG_PRE_EXISTING to cherry pick which ID to make local... */ if (mode == MAKE_LOCAL_ALL) { + SceneLayer *scene_layer = CTX_data_scene_layer(C); + SceneCollection *scene_collection = CTX_data_scene_collection(C); + BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); - /* de-select so the user can differentiate newly instanced from existing objects */ - BKE_scene_base_deselect_all(scene); + /* De-select so the user can differentiate newly instanced from existing objects. */ + BKE_scene_layer_base_deselect_all(scene_layer); - if (make_local_all__instance_indirect_unused(bmain, scene)) { + if (make_local_all__instance_indirect_unused(bmain, scene, scene_layer, scene_collection)) { BKE_report(op->reports, RPT_INFO, "Orphan library objects added to the current scene to avoid loss"); } } @@ -2413,24 +2334,31 @@ static int make_single_user_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); View3D *v3d = CTX_wm_view3d(C); /* ok if this is NULL */ const int flag = (RNA_enum_get(op->ptr, "type") == MAKE_SINGLE_USER_SELECTED) ? SELECT : 0; const bool copy_groups = false; bool update_deps = false; if (RNA_boolean_get(op->ptr, "object")) { - single_object_users(bmain, scene, v3d, flag, copy_groups); + if (flag == SELECT) { + BKE_scene_layer_selected_objects_tag(sl, OB_DONE); + single_object_users(bmain, scene, v3d, OB_DONE, copy_groups); + } + else { + single_object_users(bmain, scene, v3d, 0, copy_groups); + } /* needed since object relationships may have changed */ update_deps = true; } if (RNA_boolean_get(op->ptr, "obdata")) { - single_obdata_users(bmain, scene, flag); + single_obdata_users(bmain, scene, sl, flag); } if (RNA_boolean_get(op->ptr, "material")) { - single_mat_users(bmain, scene, flag, RNA_boolean_get(op->ptr, "texture")); + single_mat_users(bmain, scene, sl, flag, RNA_boolean_get(op->ptr, "texture")); } #if 0 /* can't do this separate from materials */ @@ -2438,7 +2366,7 @@ static int make_single_user_exec(bContext *C, wmOperator *op) single_mat_users(scene, flag, true); #endif if (RNA_boolean_get(op->ptr, "animation")) { - single_object_action_users(scene, flag); + single_object_action_users(scene, sl, flag); } BKE_main_id_clear_newpoins(bmain); @@ -2446,7 +2374,7 @@ static int make_single_user_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_WINDOW, NULL); if (update_deps) { - DAG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); } return OPERATOR_FINISHED; @@ -2496,7 +2424,7 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent assign_material(base->object, ma, 1, BKE_MAT_ASSIGN_USERPREF); - DAG_id_tag_update(&base->object->id, OB_RECALC_OB); + DEG_id_tag_update(&base->object->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, base->object); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 8d5c2387fe9..1542978041e 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -41,6 +41,7 @@ #include "DNA_scene_types.h" #include "DNA_armature_types.h" #include "DNA_lamp_types.h" +#include "DNA_workspace_types.h" #include "BLI_math.h" #include "BLI_listbase.h" @@ -52,12 +53,14 @@ #include "BKE_context.h" #include "BKE_group.h" +#include "BKE_layer.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_particle.h" #include "BKE_property.h" #include "BKE_report.h" #include "BKE_scene.h" +#include "BKE_workspace.h" #include "BKE_library.h" #include "BKE_deform.h" @@ -86,37 +89,48 @@ /* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or * or a NC_SCENE|ND_OB_VISIBLE in case of visibility toggling */ -void ED_base_object_select(Base *base, short mode) +void ED_object_base_select(Base *base, eObjectSelect_Mode mode) { + if (mode == BA_INVERT) { + mode = (base->flag & BASE_SELECTED) != 0 ? BA_DESELECT : BA_SELECT; + } + if (base) { - if (mode == BA_SELECT) { - if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) - base->flag |= SELECT; - } - else if (mode == BA_DESELECT) { - base->flag &= ~SELECT; + switch (mode) { + case BA_SELECT: + if ((base->flag & BASE_SELECTABLED) != 0) { + base->flag |= BASE_SELECTED; + } + break; + case BA_DESELECT: + base->flag &= ~BASE_SELECTED; + break; + case BA_INVERT: + /* Never happens. */ + break; } - base->object->flag = base->flag; + BKE_scene_object_base_flag_sync_from_base(base); } } -/* also to set active NULL */ -void ED_base_object_activate(bContext *C, Base *base) +/** + * Change active base, it includes the notifier + */ +void ED_object_base_activate(bContext *C, Base *base) { - Scene *scene = CTX_data_scene(C); - - /* sets scene->basact */ - BASACT = base; - + SceneLayer *scene_layer = CTX_data_scene_layer(C); + scene_layer->basact = base; + if (base) { - - /* XXX old signals, remember to handle notifiers now! */ - // select_actionchannel_by_name(base->object->action, "Object", 1); - - WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); +#ifdef USE_WORKSPACE_MODE + WorkSpace *workspace = CTX_wm_workspace(C); + BKE_workspace_object_mode_set(workspace, base->object->mode); +#endif + WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene_layer); } - else + else { WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, NULL); + } } /********************** Selection Operators **********************/ @@ -147,7 +161,7 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op) if (extend == 0) { CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - ED_base_object_select(base, BA_DESELECT); + ED_object_base_select(base, BA_DESELECT); } CTX_DATA_END; } @@ -155,7 +169,7 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, visible_bases) { if (base->object->type == obtype) { - ED_base_object_select(base, BA_SELECT); + ED_object_base_select(base, BA_SELECT); } } CTX_DATA_END; @@ -210,38 +224,15 @@ static const EnumPropertyItem prop_select_linked_types[] = { {0, NULL, 0, NULL, NULL} }; -// XXX old animation system -#if 0 -static int object_select_all_by_ipo(bContext *C, Ipo *ipo) -{ - bool changed = false; - - CTX_DATA_BEGIN (C, Base *, base, visible_bases) - { - if (base->object->ipo == ipo) { - base->flag |= SELECT; - base->object->flag = base->flag; - - changed = true; - } - } - CTX_DATA_END; - - return changed; -} -#endif - static bool object_select_all_by_obdata(bContext *C, void *obdata) { bool changed = false; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if ((base->flag & SELECT) == 0) { + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { if (base->object->data == obdata) { - base->flag |= SELECT; - base->object->flag = base->flag; - + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -257,7 +248,7 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture, CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if ((base->flag & SELECT) == 0) { + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { Object *ob = base->object; Material *mat1; int a, b; @@ -267,7 +258,7 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture, if (!use_texture) { if (mat1 == mat) { - base->flag |= SELECT; + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -275,7 +266,7 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture, for (b = 0; b < MAX_MTEX; b++) { if (mat1->mtex[b]) { if (tex == mat1->mtex[b]->tex) { - base->flag |= SELECT; + ED_object_base_select(base, BA_SELECT); changed = true; break; } @@ -283,8 +274,6 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture, } } } - - base->object->flag = base->flag; } } CTX_DATA_END; @@ -299,12 +288,10 @@ static bool object_select_all_by_dup_group(bContext *C, Object *ob) CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if ((base->flag & SELECT) == 0) { + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { Group *dup_group_other = (base->object->transflag & OB_DUPLIGROUP) ? base->object->dup_group : NULL; if (dup_group == dup_group_other) { - base->flag |= SELECT; - base->object->flag = base->flag; - + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -321,23 +308,21 @@ static bool object_select_all_by_particle(bContext *C, Object *ob) CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if ((base->flag & SELECT) == 0) { + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { /* loop through other particles*/ ParticleSystem *psys; for (psys = base->object->particlesystem.first; psys; psys = psys->next) { if (psys->part == psys_act->part) { - base->flag |= SELECT; + ED_object_base_select(base, BA_SELECT); changed = true; break; } - if (base->flag & SELECT) { + if (base->flag & BASE_SELECTED) { break; } } - - base->object->flag = base->flag; } } CTX_DATA_END; @@ -351,11 +336,9 @@ static bool object_select_all_by_library(bContext *C, Library *lib) CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if ((base->flag & SELECT) == 0) { + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { if (lib == base->object->id.lib) { - base->flag |= SELECT; - base->object->flag = base->flag; - + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -371,11 +354,9 @@ static bool object_select_all_by_library_obdata(bContext *C, Library *lib) CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if ((base->flag & SELECT) == 0) { + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { if (base->object->data && lib == ((ID *)base->object->data)->lib) { - base->flag |= SELECT; - base->object->flag = base->flag; - + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -408,6 +389,7 @@ void ED_object_select_linked_by_id(bContext *C, ID *id) static int object_select_linked_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *ob; int nr = RNA_enum_get(op->ptr, "type"); bool changed = false, extend; @@ -417,12 +399,12 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) if (extend == 0) { CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - ED_base_object_select(base, BA_DESELECT); + ED_object_base_select(base, BA_DESELECT); } CTX_DATA_END; } - ob = OBACT; + ob = OBACT(sl); if (ob == NULL) { BKE_report(op->reports, RPT_ERROR, "No active object"); return OPERATOR_CANCELLED; @@ -517,7 +499,7 @@ enum { OBJECT_GRPSEL_PARENT = 2, OBJECT_GRPSEL_SIBLINGS = 3, OBJECT_GRPSEL_TYPE = 4, - OBJECT_GRPSEL_LAYER = 5, + /*OBJECT_GRPSEL_LAYER = 5,*/ OBJECT_GRPSEL_GROUP = 6, OBJECT_GRPSEL_HOOK = 7, OBJECT_GRPSEL_PASS = 8, @@ -533,7 +515,6 @@ static const EnumPropertyItem prop_select_grouped_types[] = { {OBJECT_GRPSEL_PARENT, "PARENT", 0, "Parent", ""}, {OBJECT_GRPSEL_SIBLINGS, "SIBLINGS", 0, "Siblings", "Shared Parent"}, {OBJECT_GRPSEL_TYPE, "TYPE", 0, "Type", "Shared object type"}, - {OBJECT_GRPSEL_LAYER, "LAYER", 0, "Layer", "Shared layers"}, {OBJECT_GRPSEL_GROUP, "GROUP", 0, "Group", "Shared group"}, {OBJECT_GRPSEL_HOOK, "HOOK", 0, "Hook", ""}, {OBJECT_GRPSEL_PASS, "PASS", 0, "Pass", "Render pass Index"}, @@ -551,13 +532,14 @@ static bool select_grouped_children(bContext *C, Object *ob, const bool recursiv CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if (ob == base->object->parent) { - if (!(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); + if ((base->flag & BASE_SELECTED) == 0) { + ED_object_base_select(base, BA_SELECT); changed = true; } - if (recursive) + if (recursive) { changed |= select_grouped_children(C, base->object, 1); + } } } CTX_DATA_END; @@ -566,20 +548,20 @@ static bool select_grouped_children(bContext *C, Object *ob, const bool recursiv static bool select_grouped_parent(bContext *C) /* Makes parent active and de-selected OBACT */ { - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - - bool changed = false; + SceneLayer *sl = CTX_data_scene_layer(C); Base *baspar, *basact = CTX_data_active_base(C); + bool changed = false; - if (!basact || !(basact->object->parent)) return 0; /* we know OBACT is valid */ + if (!basact || !(basact->object->parent)) { + return 0; /* we know OBACT is valid */ + } - baspar = BKE_scene_base_find(scene, basact->object->parent); + baspar = BKE_scene_layer_base_find(sl, basact->object->parent); /* can be NULL if parent in other scene */ - if (baspar && BASE_SELECTABLE(v3d, baspar)) { - ED_base_object_select(baspar, BA_SELECT); - ED_base_object_activate(C, baspar); + if (baspar && BASE_SELECTABLE(baspar)) { + ED_object_base_select(baspar, BA_SELECT); + ED_object_base_activate(C, baspar); changed = true; } return changed; @@ -608,9 +590,11 @@ static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in group = ob_groups[0]; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object)) { - ED_base_object_select(base, BA_SELECT); - changed = true; + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { + if (BKE_group_object_exists(group, base->object)) { + ED_object_base_select(base, BA_SELECT); + changed = true; + } } } CTX_DATA_END; @@ -632,8 +616,7 @@ static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in static bool select_grouped_object_hooks(bContext *C, Object *ob) { - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); + SceneLayer *sl = CTX_data_scene_layer(C); bool changed = false; Base *base; @@ -644,9 +627,9 @@ static bool select_grouped_object_hooks(bContext *C, Object *ob) if (md->type == eModifierType_Hook) { hmd = (HookModifierData *) md; if (hmd->object && !(hmd->object->flag & SELECT)) { - base = BKE_scene_base_find(scene, hmd->object); - if (base && (BASE_SELECTABLE(v3d, base))) { - ED_base_object_select(base, BA_SELECT); + base = BKE_scene_layer_base_find(sl, hmd->object); + if (base && (BASE_SELECTABLE(base))) { + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -663,8 +646,8 @@ static bool select_grouped_siblings(bContext *C, Object *ob) CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { - if ((base->object->parent == ob->parent) && !(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); + if ((base->object->parent == ob->parent) && ((base->flag & BASE_SELECTED) == 0)) { + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -681,8 +664,8 @@ static bool select_grouped_lamptype(bContext *C, Object *ob) { if (base->object->type == OB_LAMP) { Lamp *la_test = base->object->data; - if ((la->type == la_test->type) && !(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); + if ((la->type == la_test->type) && ((base->flag & BASE_SELECTED) == 0)) { + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -696,23 +679,8 @@ static bool select_grouped_type(bContext *C, Object *ob) CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { - if ((base->object->type == ob->type) && !(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); - changed = true; - } - } - CTX_DATA_END; - return changed; -} - -static bool select_grouped_layer(bContext *C, Object *ob) -{ - bool changed = false; - - CTX_DATA_BEGIN (C, Base *, base, selectable_bases) - { - if ((base->lay & ob->lay) && !(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); + if ((base->object->type == ob->type) && ((base->flag & BASE_SELECTED) == 0)) { + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -726,8 +694,8 @@ static bool select_grouped_index_object(bContext *C, Object *ob) CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { - if ((base->object->index == ob->index) && !(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); + if ((base->object->index == ob->index) && ((base->flag & BASE_SELECTED) == 0)) { + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -741,8 +709,8 @@ static bool select_grouped_color(bContext *C, Object *ob) CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { - if (!(base->flag & SELECT) && (compare_v3v3(base->object->col, ob->col, 0.005f))) { - ED_base_object_select(base, BA_SELECT); + if (((base->flag & BASE_SELECTED) == 0) && (compare_v3v3(base->object->col, ob->col, 0.005f))) { + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -768,8 +736,8 @@ static bool select_grouped_gameprops(bContext *C, Object *ob) CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { - if (!(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) { - ED_base_object_select(base, BA_SELECT); + if (((base->flag & BASE_SELECTED) == 0) && (objects_share_gameprop(base->object, ob))) { + ED_object_base_select(base, BA_SELECT); changed = true; } } @@ -807,7 +775,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { /* only check for this object if it isn't selected already, to limit time wasted */ - if ((base->flag & SELECT) == 0) { + if ((base->flag & BASE_SELECTED) == 0) { KS_Path *ksp; /* this is the slow way... we could end up with > 500 items here, @@ -816,7 +784,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList for (ksp = ks->paths.first; ksp; ksp = ksp->next) { /* if id matches, select then stop looping (match found) */ if (ksp->id == (ID *)base->object) { - ED_base_object_select(base, BA_SELECT); + ED_object_base_select(base, BA_SELECT); changed = true; break; } @@ -831,6 +799,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList static int object_select_grouped_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); Object *ob; const int type = RNA_enum_get(op->ptr, "type"); bool changed = false, extend; @@ -840,13 +809,13 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op) if (extend == 0) { CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - ED_base_object_select(base, BA_DESELECT); + ED_object_base_select(base, BA_DESELECT); changed = true; } CTX_DATA_END; } - ob = OBACT; + ob = OBACT(sl); if (ob == NULL) { BKE_report(op->reports, RPT_ERROR, "No active object"); return OPERATOR_CANCELLED; @@ -868,9 +837,6 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op) case OBJECT_GRPSEL_TYPE: changed |= select_grouped_type(C, ob); break; - case OBJECT_GRPSEL_LAYER: - changed |= select_grouped_layer(C, ob); - break; case OBJECT_GRPSEL_GROUP: changed |= select_grouped_group(C, ob); break; @@ -928,85 +894,6 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", ""); } -/************************* Select by Layer **********************/ -enum { - OB_SEL_LAYERMATCH_EXACT = 1, - OB_SEL_LAYERMATCH_SHARED = 2, -}; - -static int object_select_by_layer_exec(bContext *C, wmOperator *op) -{ - unsigned int layernum; - bool extend; - int match; - - extend = RNA_boolean_get(op->ptr, "extend"); - layernum = RNA_int_get(op->ptr, "layers"); - match = RNA_enum_get(op->ptr, "match"); - - if (extend == false) { - CTX_DATA_BEGIN (C, Base *, base, visible_bases) - { - ED_base_object_select(base, BA_DESELECT); - } - CTX_DATA_END; - } - - CTX_DATA_BEGIN (C, Base *, base, visible_bases) - { - bool ok = false; - - switch (match) { - case OB_SEL_LAYERMATCH_EXACT: - /* Mask out bits used for local view, only work on real layer ones, see T45783. */ - ok = ((base->lay & ((1 << 20) - 1)) == (1 << (layernum - 1))); - break; - case OB_SEL_LAYERMATCH_SHARED: - ok = (base->lay & (1 << (layernum - 1))) != 0; - break; - default: - break; - } - - if (ok) { - ED_base_object_select(base, BA_SELECT); - } - } - CTX_DATA_END; - - /* undo? */ - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_select_by_layer(wmOperatorType *ot) -{ - static const EnumPropertyItem match_items[] = { - {OB_SEL_LAYERMATCH_EXACT, "EXACT", 0, "Exact Match", ""}, - {OB_SEL_LAYERMATCH_SHARED, "SHARED", 0, "Shared Layers", ""}, - {0, NULL, 0, NULL, NULL} - }; - - /* identifiers */ - ot->name = "Select by Layer"; - ot->description = "Select all visible objects on a layer"; - ot->idname = "OBJECT_OT_select_by_layer"; - - /* api callbacks */ - /*ot->invoke = XXX - need a int grid popup*/ - ot->exec = object_select_by_layer_exec; - ot->poll = objects_selectable_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "match", match_items, OB_SEL_LAYERMATCH_EXACT, "Match", ""); - RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first"); - RNA_def_int(ot->srna, "layers", 1, 1, 20, "Layer", "", 1, 20); -} - /**************************** (De)select All ****************************/ static int object_select_all_exec(bContext *C, wmOperator *op) @@ -1020,7 +907,7 @@ static int object_select_all_exec(bContext *C, wmOperator *op) action = SEL_SELECT; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if (base->flag & SELECT) { + if ((base->flag & BASE_SELECTED) != 0) { action = SEL_DESELECT; break; } @@ -1032,17 +919,17 @@ static int object_select_all_exec(bContext *C, wmOperator *op) { switch (action) { case SEL_SELECT: - ED_base_object_select(base, BA_SELECT); + ED_object_base_select(base, BA_SELECT); break; case SEL_DESELECT: - ED_base_object_select(base, BA_DESELECT); + ED_object_base_select(base, BA_DESELECT); break; case SEL_INVERT: - if (base->flag & SELECT) { - ED_base_object_select(base, BA_DESELECT); + if ((base->flag & BASE_SELECTED) != 0) { + ED_object_base_select(base, BA_DESELECT); } else { - ED_base_object_select(base, BA_SELECT); + ED_object_base_select(base, BA_SELECT); } break; } @@ -1092,8 +979,11 @@ static int object_select_same_group_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object)) - ED_base_object_select(base, BA_SELECT); + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { + if (BKE_group_object_exists(group, base->object)) { + ED_object_base_select(base, BA_SELECT); + } + } } CTX_DATA_END; @@ -1124,6 +1014,7 @@ void OBJECT_OT_select_same_group(wmOperatorType *ot) static int object_select_mirror_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); + SceneLayer *sl = CTX_data_scene_layer(C); bool extend; extend = RNA_boolean_get(op->ptr, "extend"); @@ -1137,15 +1028,15 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op) if (!STREQ(name_flip, primbase->object->id.name + 2)) { Object *ob = (Object *)BKE_libblock_find_name(ID_OB, name_flip); if (ob) { - Base *secbase = BKE_scene_base_find(scene, ob); + Base *secbase = BKE_scene_layer_base_find(sl, ob); if (secbase) { - ED_base_object_select(secbase, BA_SELECT); + ED_object_base_select(secbase, BA_SELECT); } } } - if (extend == false) ED_base_object_select(primbase, BA_DESELECT); + if (extend == false) ED_object_base_select(primbase, BA_DESELECT); } CTX_DATA_END; @@ -1180,9 +1071,9 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot) static bool object_select_more_less(bContext *C, const bool select) { - Scene *scene = CTX_data_scene(C); + SceneLayer *scene_layer = CTX_data_scene_layer(C); - for (Base *base = scene->base.first; base; base = base->next) { + for (Base *base = scene_layer->object_bases.first; base; base = base->next) { Object *ob = base->object; ob->flag &= ~OB_DONE; ob->id.tag &= ~LIB_TAG_DOIT; @@ -1223,7 +1114,7 @@ static bool object_select_more_less(bContext *C, const bool select) Base *base = ctx_base->ptr.data; Object *ob = base->object; if ((ob->id.tag & LIB_TAG_DOIT) && ((ob->flag & SELECT) != select_flag)) { - ED_base_object_select(base, select_mode); + ED_object_base_select(base, select_mode); changed = true; } } @@ -1305,7 +1196,7 @@ static int object_select_random_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if (BLI_rng_get_float(rng) < randfac) { - ED_base_object_select(base, select); + ED_object_base_select(base, select); } } CTX_DATA_END; diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 27da607c696..1f80cb5f0bc 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -51,7 +51,6 @@ #include "DNA_object_types.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" #include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" @@ -59,6 +58,9 @@ #include "BKE_lattice.h" #include "BKE_curve.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + #include "BLI_sys_types.h" // for intptr_t support #include "ED_object.h" @@ -213,7 +215,7 @@ static bool object_shape_key_mirror(bContext *C, Object *ob, *r_totmirr = totmirr; *r_totfail = totfail; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return 1; @@ -264,8 +266,8 @@ 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)); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(CTX_data_main(C)); return OPERATOR_FINISHED; } @@ -302,8 +304,8 @@ static int shape_key_remove_exec(bContext *C, wmOperator *op) } if (changed) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - DAG_relations_tag_update(CTX_data_main(C)); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(CTX_data_main(C)); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -343,7 +345,7 @@ static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) for (kb = key->block.first; kb; kb = kb->next) kb->curval = 0.0f; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -378,7 +380,7 @@ static int shape_key_retime_exec(bContext *C, wmOperator *UNUSED(op)) for (kb = key->block.first; kb; kb = kb->next) kb->pos = (cfra += 0.1f); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -469,7 +471,7 @@ static int shape_key_move_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); 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 9fea7bf5b89..100b9018d00 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -39,14 +39,15 @@ #include "DNA_scene_types.h" #include "DNA_group_types.h" #include "DNA_lattice_types.h" +#include "DNA_lamp_types.h" #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" +#include "BLI_array.h" #include "BKE_context.h" #include "BKE_curve.h" -#include "BKE_depsgraph.h" #include "BKE_main.h" #include "BKE_idcode.h" #include "BKE_mball.h" @@ -59,6 +60,8 @@ #include "BKE_lattice.h" #include "BKE_tracking.h" +#include "DEG_depsgraph.h" + #include "RNA_define.h" #include "RNA_access.h" @@ -71,6 +74,8 @@ #include "ED_screen.h" #include "ED_view3d.h" +#include "MEM_guardedalloc.h" + #include "object_intern.h" /*************************** Clear Transformation ****************************/ @@ -265,7 +270,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op, ED_autokeyframe_object(C, scene, ob, ks); /* tag for updates */ - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } } CTX_DATA_END; @@ -371,7 +376,7 @@ static int object_origin_clear_exec(bContext *C, wmOperator *UNUSED(op)) mul_m3_v3(mat, v3); } - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); } CTX_DATA_END; @@ -399,16 +404,19 @@ void OBJECT_OT_origin_clear(wmOperatorType *ot) /* use this when the loc/size/rot of the parent has changed but the children * should stay in the same place, e.g. for apply-size-rot or object center */ -static void ignore_parent_tx(Main *bmain, Scene *scene, Object *ob) +static void ignore_parent_tx(const bContext *C, Main *bmain, Scene *scene, Object *ob) { Object workob; Object *ob_child; + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); /* 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) { BKE_object_apply_mat4(ob_child, ob_child->obmat, true, false); - BKE_object_workob_calc_parent(scene, ob_child, &workob); + BKE_object_workob_calc_parent(&eval_ctx, scene, ob_child, &workob); invert_m4_m4(ob_child->parentinv, workob.obmat); } } @@ -421,8 +429,11 @@ static int apply_objects_internal( { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; float rsmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; bool changed = true; + + CTX_data_eval_ctx(C, &eval_ctx); /* first check if we can execute */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) @@ -525,7 +536,7 @@ static int apply_objects_internal( Mesh *me = ob->data; if (apply_scale) - multiresModifier_scale_disp(scene, ob); + multiresModifier_scale_disp(&eval_ctx, scene, ob); /* adjust data */ BKE_mesh_transform(me, mat, true); @@ -615,14 +626,14 @@ static int apply_objects_internal( unit_axis_angle(ob->rotAxis, &ob->rotAngle); } - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); if (ob->type == OB_ARMATURE) { - BKE_pose_where_is(scene, ob); /* needed for bone parents */ + BKE_pose_where_is(&eval_ctx, scene, ob); /* needed for bone parents */ } - ignore_parent_tx(bmain, scene, ob); + ignore_parent_tx(C, bmain, scene, ob); - DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); changed = true; } @@ -640,16 +651,19 @@ static int apply_objects_internal( static int visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); + EvaluationContext eval_ctx; bool changed = false; + CTX_data_eval_ctx(C, &eval_ctx); + CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); BKE_object_apply_mat4(ob, ob->obmat, true, true); - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); /* update for any children that may get moved */ - DAG_id_tag_update(&ob->id, OB_RECALC_OB); + DEG_id_tag_update(&ob->id, OB_RECALC_OB); changed = true; } @@ -730,6 +744,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); + EvaluationContext eval_ctx; Object *tob; float cursor[3], cent[3], cent_neg[3], centn[3]; int centermode = RNA_enum_get(op->ptr, "type"); @@ -739,6 +754,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) CollectionPointerLink *ctx_ob; CollectionPointerLink *ctx_ob_act = NULL; + CTX_data_eval_ctx(C, &eval_ctx); + /* keep track of what is changed */ int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0; @@ -793,7 +810,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) EDBM_mesh_normals_update(em); tot_change++; - DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + DEG_id_tag_update(&obedit->id, OB_RECALC_DATA); } } @@ -918,7 +935,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) if (obedit) { if (centermode == GEOMETRY_TO_ORIGIN) { - DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + DEG_id_tag_update(&obedit->id, OB_RECALC_DATA); } break; } @@ -971,10 +988,10 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) arm->id.tag |= LIB_TAG_DOIT; /* do_inverse_offset = true; */ /* docenter_armature() handles this */ - BKE_object_where_is_calc(scene, ob); - BKE_pose_where_is(scene, ob); /* needed for bone parents */ + BKE_object_where_is_calc(&eval_ctx, scene, ob); + BKE_pose_where_is(&eval_ctx, scene, ob); /* needed for bone parents */ - ignore_parent_tx(bmain, scene, ob); + ignore_parent_tx(C, bmain, scene, ob); if (obedit) break; @@ -996,7 +1013,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) if (obedit) { if (centermode == GEOMETRY_TO_ORIGIN) { - DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + DEG_id_tag_update(&obedit->id, OB_RECALC_DATA); } break; } @@ -1030,12 +1047,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) add_v3_v3(ob->loc, centn); - BKE_object_where_is_calc(scene, ob); + BKE_object_where_is_calc(&eval_ctx, scene, ob); if (ob->type == OB_ARMATURE) { - BKE_pose_where_is(scene, ob); /* needed for bone parents */ + BKE_pose_where_is(&eval_ctx, scene, ob); /* needed for bone parents */ } - ignore_parent_tx(bmain, scene, ob); + ignore_parent_tx(C, bmain, scene, ob); /* other users? */ //CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) @@ -1054,16 +1071,16 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) (ob->transflag | ob_other->transflag) & OB_DUPLIGROUP))) { ob_other->flag |= OB_DONE; - DAG_id_tag_update(&ob_other->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&ob_other->id, OB_RECALC_OB | OB_RECALC_DATA); 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); + BKE_object_where_is_calc(&eval_ctx, scene, ob_other); if (ob_other->type == OB_ARMATURE) { - BKE_pose_where_is(scene, ob_other); /* needed for bone parents */ + BKE_pose_where_is(&eval_ctx, scene, ob_other); /* needed for bone parents */ } - ignore_parent_tx(bmain, scene, ob_other); + ignore_parent_tx(C, bmain, scene, ob_other); } } //CTX_DATA_END; @@ -1072,9 +1089,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } BLI_freelistN(&ctx_data_list); - for (tob = bmain->object.first; tob; tob = tob->id.next) - if (tob->data && (((ID *)tob->data)->tag & LIB_TAG_DOIT)) - DAG_id_tag_update(&tob->id, OB_RECALC_OB | OB_RECALC_DATA); + for (tob = bmain->object.first; tob; tob = tob->id.next) { + if (tob->data && (((ID *)tob->data)->tag & LIB_TAG_DOIT)) { + BKE_mesh_batch_cache_dirty(tob->data, BKE_MESH_BATCH_DIRTY_ALL); + DEG_id_tag_update(&tob->id, OB_RECALC_OB | OB_RECALC_DATA); + } + } if (tot_change) { WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -1131,3 +1151,389 @@ void OBJECT_OT_origin_set(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_set_center_types, 0, "Type", ""); RNA_def_enum(ot->srna, "center", prop_set_bounds_types, V3D_AROUND_CENTER_MEAN, "Center", ""); } + +/* -------------------------------------------------------------------- */ + +/** \name Transform Axis Target + * + * Note this is an experemental operator to point lamps/cameras at objects. + * We may re-work how this behaves based on user feedback. + * - campbell. + * \{ */ + +/* When using multiple objects, apply their relative rotational offset to the active object. */ +#define USE_RELATIVE_ROTATION + +struct XFormAxisItem { + Object *ob; + float rot_mat[3][3]; + void *obtfm; + float xform_dist; + +#ifdef USE_RELATIVE_ROTATION + /* use when translating multiple */ + float xform_rot_offset[3][3]; +#endif +}; + +struct XFormAxisData { + ViewContext vc; + struct { + float depth; + float normal[3]; + bool is_depth_valid; + bool is_normal_valid; + } prev; + + struct XFormAxisItem *object_data; + uint object_data_len; + bool is_translate; + + int init_event; +}; + +static bool object_is_target_compat(const Object *ob) +{ + if (ob->type == OB_LAMP) { + const Lamp *la = ob->data; + if (ELEM(la->type, LA_SUN, LA_SPOT, LA_HEMI, LA_AREA)) { + return true; + } + } + /* We might want to enable this later, for now just lamps */ +#if 0 + else if (ob->type == OB_CAMERA) { + return true; + } +#endif + return false; +} + +static void object_transform_axis_target_free_data(wmOperator *op) +{ + struct XFormAxisData *xfd = op->customdata; + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + MEM_freeN(item->obtfm); + } + MEM_freeN(xfd->object_data); + MEM_freeN(xfd); + op->customdata = NULL; +} + +/* We may want to expose as alternative to: BKE_object_apply_rotation */ +static void object_apply_rotation(Object *ob, const float rmat[3][3]) +{ + float size[3]; + float loc[3]; + float rmat4[4][4]; + copy_m4_m3(rmat4, rmat); + + copy_v3_v3(size, ob->size); + copy_v3_v3(loc, ob->loc); + BKE_object_apply_mat4(ob, rmat4, true, true); + copy_v3_v3(ob->size, size); + copy_v3_v3(ob->loc, loc); +} +/* We may want to extract this to: BKE_object_apply_location */ +static void object_apply_location(Object *ob, const float loc[3]) +{ + /* quick but weak */ + Object ob_prev = *ob; + float mat[4][4]; + copy_m4_m4(mat, ob->obmat); + copy_v3_v3(mat[3], loc); + BKE_object_apply_mat4(ob, mat, true, true); + copy_v3_v3(mat[3], ob->loc); + *ob = ob_prev; + copy_v3_v3(ob->loc, mat[3]); +} + +static void object_orient_to_location( + Object *ob, float rot_orig[3][3], const float axis[3], const float location[3]) +{ + float delta[3]; + sub_v3_v3v3(delta, ob->obmat[3], location); + if (normalize_v3(delta) != 0.0f) { + if (len_squared_v3v3(delta, axis) > FLT_EPSILON) { + float delta_rot[3][3]; + float final_rot[3][3]; + rotation_between_vecs_to_mat3(delta_rot, axis, delta); + + mul_m3_m3m3(final_rot, delta_rot, rot_orig); + + object_apply_rotation(ob, final_rot); + + DEG_id_tag_update(&ob->id, OB_RECALC_OB); + } + } +} + +static void object_transform_axis_target_cancel(bContext *C, wmOperator *op) +{ + struct XFormAxisData *xfd = op->customdata; + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + BKE_object_tfm_restore(item->ob, item->obtfm); + DEG_id_tag_update(&item->ob->id, OB_RECALC_OB); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob); + } + + object_transform_axis_target_free_data(op); +} + +static int object_transform_axis_target_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ViewContext vc; + view3d_set_viewcontext(C, &vc); + + if (!object_is_target_compat(vc.obact)) { + /* Falls back to texture space transform. */ + return OPERATOR_PASS_THROUGH; + } + + EvaluationContext eval_ctx; + + CTX_data_eval_ctx(C, &eval_ctx); + + ED_view3d_autodist_init(&eval_ctx, vc.depsgraph, vc.ar, vc.v3d, 0); + + if (vc.rv3d->depths != NULL) { + vc.rv3d->depths->damaged = true; + } + ED_view3d_depth_update(vc.ar); + + if (vc.rv3d->depths == NULL) { + BKE_report(op->reports, RPT_WARNING, "Unable to access depth buffer, using view plane"); + return OPERATOR_CANCELLED; + } + + ED_region_tag_redraw(vc.ar); + + struct XFormAxisData *xfd; + xfd = op->customdata = MEM_callocN(sizeof(struct XFormAxisData), __func__); + + /* Don't change this at runtime. */ + xfd->vc = vc; + xfd->vc.mval[0] = event->mval[0]; + xfd->vc.mval[1] = event->mval[1]; + + xfd->prev.depth = 1.0f; + xfd->prev.is_depth_valid = false; + xfd->prev.is_normal_valid = false; + xfd->is_translate = false; + + xfd->init_event = WM_userdef_event_type_from_keymap_type(event->type); + + { + struct XFormAxisItem *object_data = NULL; + BLI_array_declare(object_data); + + struct XFormAxisItem *item = BLI_array_append_ret(object_data); + item->ob = xfd->vc.obact; + + CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + { + if ((ob != xfd->vc.obact) && object_is_target_compat(ob)) { + item = BLI_array_append_ret(object_data); + item->ob = ob; + } + } + CTX_DATA_END; + + xfd->object_data = object_data; + xfd->object_data_len = BLI_array_count(object_data); + + if (xfd->object_data_len != BLI_array_count(object_data)) { + xfd->object_data = MEM_reallocN(xfd->object_data, xfd->object_data_len * sizeof(*xfd->object_data)); + } + } + + { + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + item->obtfm = BKE_object_tfm_backup(item->ob); + BKE_object_rot_to_mat3(item->ob, item->rot_mat, true); + } + } + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + struct XFormAxisData *xfd = op->customdata; + ARegion *ar = xfd->vc.ar; + + view3d_operator_needs_opengl(C); + + const bool is_translate = (event->ctrl != 0); + const bool is_translate_init = is_translate && (xfd->is_translate != is_translate); + + if (event->type == MOUSEMOVE || is_translate_init) { + const ViewDepths *depths = xfd->vc.rv3d->depths; + if (depths && + ((unsigned int)event->mval[0] < depths->w) && + ((unsigned int)event->mval[1] < depths->h)) + { + double depth = (double)ED_view3d_depth_read_cached(&xfd->vc, event->mval); + float location_world[3]; + if (depth == 1.0f) { + if (xfd->prev.is_depth_valid) { + depth = (double)xfd->prev.depth; + } + } + if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { + xfd->prev.depth = depth; + xfd->prev.is_depth_valid = true; + if (ED_view3d_depth_unproject(ar, event->mval, depth, location_world)) { + if (is_translate) { + + float normal[3]; + bool normal_found = false; + if (ED_view3d_depth_read_cached_normal(&xfd->vc, event->mval, normal)) { + normal_found = true; + + /* cheap attempt to smooth normals out a bit! */ + const uint ofs = 2; + for (uint x = -ofs; x <= ofs; x += ofs / 2) { + for (uint y = -ofs; y <= ofs; y += ofs / 2) { + if (x != 0 && y != 0) { + int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y}; + float n[3]; + if (ED_view3d_depth_read_cached_normal( + &xfd->vc, mval_ofs, n)) + { + add_v3_v3(normal, n); + } + } + } + } + normalize_v3(normal); + } + else if (xfd->prev.is_normal_valid) { + copy_v3_v3(normal, xfd->prev.normal); + normal_found = true; + } + + if (normal_found) { +#ifdef USE_RELATIVE_ROTATION + if (is_translate_init && xfd->object_data_len > 1) { + float xform_rot_offset_inv_first[3][3]; + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + copy_m3_m4(item->xform_rot_offset, item->ob->obmat); + normalize_m3(item->xform_rot_offset); + + if (i == 0) { + invert_m3_m3(xform_rot_offset_inv_first, xfd->object_data[0].xform_rot_offset); + } + else { + mul_m3_m3m3(item->xform_rot_offset, + item->xform_rot_offset, + xform_rot_offset_inv_first); + } + } + } + +#endif + + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + if (is_translate_init) { + float ob_axis[3]; + item->xform_dist = len_v3v3(item->ob->obmat[3], location_world); + normalize_v3_v3(ob_axis, item->ob->obmat[2]); + /* Scale to avoid adding distance when moving between surfaces. */ + float scale = fabsf(dot_v3v3(ob_axis, normal)); + item->xform_dist *= scale; + } + + float target_normal[3]; + copy_v3_v3(target_normal, normal); + +#ifdef USE_RELATIVE_ROTATION + if (i != 0) { + mul_m3_v3(item->xform_rot_offset, target_normal); + } +#endif + { + float loc[3]; + + copy_v3_v3(loc, location_world); + madd_v3_v3fl(loc, target_normal, item->xform_dist); + object_apply_location(item->ob, loc); + copy_v3_v3(item->ob->obmat[3], loc); /* so orient behaves as expected */ + } + + object_orient_to_location(item->ob, item->rot_mat, item->rot_mat[2], location_world); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob); + } + copy_v3_v3(xfd->prev.normal, normal); + xfd->prev.is_normal_valid = true; + } + } + else { + struct XFormAxisItem *item = xfd->object_data; + for (int i = 0; i < xfd->object_data_len; i++, item++) { + object_orient_to_location(item->ob, item->rot_mat, item->rot_mat[2], location_world); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob); + } + xfd->prev.is_normal_valid = false; + } + } + } + } + xfd->is_translate = is_translate; + + ED_region_tag_redraw(xfd->vc.ar); + } + + bool is_finished = false; + + if (ISMOUSE(xfd->init_event)) { + if ((event->type == xfd->init_event) && (event->val == KM_RELEASE)) { + is_finished = true; + } + } + else { + if (ELEM(event->type, LEFTMOUSE, RETKEY, PADENTER)) { + is_finished = true; + } + } + + if (is_finished) { + object_transform_axis_target_free_data(op); + return OPERATOR_FINISHED; + } + else if (ELEM(event->type, ESCKEY, RIGHTMOUSE)) { + object_transform_axis_target_cancel(C, op); + return OPERATOR_CANCELLED; + } + + + return OPERATOR_RUNNING_MODAL; +} + +void OBJECT_OT_transform_axis_target(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Interactive Lamp Track to Cursor"; + ot->description = "Interactively point cameras and lamps to a location (Ctrl translates)"; + ot->idname = "OBJECT_OT_transform_axis_target"; + + /* api callbacks */ + ot->invoke = object_transform_axis_target_invoke; + ot->cancel = object_transform_axis_target_cancel; + ot->modal = object_transform_axis_target_modal; + ot->poll = ED_operator_region_view3d_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; +} + +#undef USE_RELATIVE_ROTATION + +/** \} */ diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 9afc3772f90..bf2da284591 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -56,9 +56,9 @@ #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_deform.h" -#include "BKE_depsgraph.h" #include "BKE_mesh_mapping.h" #include "BKE_editmesh.h" +#include "BKE_layer.h" #include "BKE_modifier.h" #include "BKE_report.h" #include "BKE_DerivedMesh.h" @@ -66,6 +66,8 @@ #include "BKE_object.h" #include "BKE_lattice.h" +#include "DEG_depsgraph.h" + #include "DNA_armature_types.h" #include "RNA_access.h" #include "RNA_define.h" @@ -1259,9 +1261,9 @@ static void dm_deform_clear(DerivedMesh *dm, Object *ob) } /* recalculate the deformation */ -static DerivedMesh *dm_deform_recalc(Scene *scene, Object *ob) +static DerivedMesh *dm_deform_recalc(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { - return mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + return mesh_get_derived_deform(eval_ctx, scene, ob, CD_MASK_BAREMESH); } /* by changing nonzero weights, try to move a vertex in me->mverts with index 'index' to @@ -1273,7 +1275,7 @@ static DerivedMesh *dm_deform_recalc(Scene *scene, Object *ob) * norm and d are the plane's properties for the equation: ax + by + cz + d = 0 * coord is a point on the plane */ -static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, int index, float norm[3], +static void moveCloserToDistanceFromPlane(EvaluationContext *eval_ctx, Scene *scene, Object *ob, Mesh *me, int index, float norm[3], float coord[3], float d, float distToBe, float strength, float cp) { DerivedMesh *dm; @@ -1300,7 +1302,7 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in float originalDistToBe = distToBe; do { wasChange = false; - dm = dm_deform_recalc(scene, ob); + dm = dm_deform_recalc(eval_ctx, scene, ob); dm->getVert(dm, index, &m); copy_v3_v3(oldPos, m.co); distToStart = dot_v3v3(norm, oldPos) + d; @@ -1338,7 +1340,7 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in if (dw->weight > 1) { dw->weight = 1; } - dm = dm_deform_recalc(scene, ob); + dm = dm_deform_recalc(eval_ctx, scene, ob); dm->getVert(dm, index, &m); getVerticalAndHorizontalChange(norm, d, coord, oldPos, distToStart, m.co, changes, dists, i); dw->weight = oldw; @@ -1448,10 +1450,13 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in /* this is used to try to smooth a surface by only adjusting the nonzero weights of a vertex * but it could be used to raise or lower an existing 'bump.' */ -static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength, float cp) +static void vgroup_fix(const bContext *C, Scene *scene, Object *ob, float distToBe, float strength, float cp) { + EvaluationContext eval_ctx; int i; + CTX_data_eval_ctx(C, &eval_ctx); + Mesh *me = ob->data; MVert *mvert = me->mvert; int *verts = NULL; @@ -1465,7 +1470,7 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength, MVert *p = MEM_callocN(sizeof(MVert) * (count), "deformedPoints"); int k; - DerivedMesh *dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + DerivedMesh *dm = mesh_get_derived_deform(&eval_ctx, scene, ob, CD_MASK_BAREMESH); k = count; while (k--) { dm->getVert(dm, verts[k], &m); @@ -1483,7 +1488,7 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength, if (mag) { /* zeros fix */ d = -dot_v3v3(norm, coord); /* dist = (dot_v3v3(norm, m.co) + d); */ /* UNUSED */ - moveCloserToDistanceFromPlane(scene, ob, me, i, norm, coord, d, distToBe, strength, cp); + moveCloserToDistanceFromPlane(&eval_ctx, scene, ob, me, i, norm, coord, d, distToBe, strength, cp); } } @@ -2609,7 +2614,7 @@ static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op)) Object *ob = ED_object_context(C); BKE_object_defgroup_add(ob); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -2642,7 +2647,7 @@ static int vertex_group_remove_exec(bContext *C, wmOperator *op) else vgroup_delete_active(ob); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -2677,7 +2682,7 @@ static int vertex_group_assign_exec(bContext *C, wmOperator *UNUSED(op)) Object *ob = ED_object_context(C); vgroup_assign_verts(ob, ts->vgroup_weight); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); return OPERATOR_FINISHED; @@ -2750,7 +2755,7 @@ static int vertex_group_remove_from_exec(bContext *C, wmOperator *op) } } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); return OPERATOR_FINISHED; @@ -2839,7 +2844,7 @@ static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op)) Object *ob = ED_object_context(C); vgroup_duplicate(ob); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data); @@ -2875,7 +2880,7 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op) vgroup_levels_subset(ob, vgroup_validmap, vgroup_tot, subset_count, offset, gain); MEM_freeN((void *)vgroup_validmap); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -2909,7 +2914,7 @@ static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op)) changed = vgroup_normalize(ob); if (changed) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -2948,7 +2953,7 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op) MEM_freeN((void *)vgroup_validmap); if (changed) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -3001,9 +3006,9 @@ static int vertex_group_fix_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "This operator does not support an active mirror modifier"); return OPERATOR_CANCELLED; } - vgroup_fix(scene, ob, distToBe, strength, cp); + vgroup_fix(C, scene, ob, distToBe, strength, cp); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -3075,7 +3080,7 @@ static int vertex_group_invert_exec(bContext *C, wmOperator *op) vgroup_invert_subset(ob, vgroup_validmap, vgroup_tot, subset_count, auto_assign, auto_remove); MEM_freeN((void *)vgroup_validmap); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -3117,7 +3122,7 @@ static int vertex_group_smooth_exec(bContext *C, wmOperator *op) vgroup_smooth_subset(ob, vgroup_validmap, vgroup_tot, subset_count, fac, repeat, fac_expand); MEM_freeN((void *)vgroup_validmap); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -3159,7 +3164,7 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op) vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single); MEM_freeN((void *)vgroup_validmap); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -3200,7 +3205,7 @@ static int vertex_group_quantize_exec(bContext *C, wmOperator *op) vgroup_quantize_subset(ob, vgroup_validmap, vgroup_tot, subset_count, steps); MEM_freeN((void *)vgroup_validmap); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -3241,7 +3246,7 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) BKE_reportf(op->reports, remove_tot ? RPT_INFO : RPT_WARNING, "%d vertex weights limited", remove_tot); if (remove_tot) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -3286,7 +3291,7 @@ static int vertex_group_mirror_exec(bContext *C, wmOperator *op) ED_mesh_report_mirror(op, totmirr, totfail); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); @@ -3319,25 +3324,26 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot) static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Object *ob = ED_object_context(C); - Base *base; + Object *ob_active = ED_object_context(C); int retval = OPERATOR_CANCELLED; - for (base = scene->base.first; base; base = base->next) { - if (base->object->type == ob->type) { - if (base->object != ob && base->object->data == ob->data) { - BLI_freelistN(&base->object->defbase); - BLI_duplicatelist(&base->object->defbase, &ob->defbase); - base->object->actdef = ob->actdef; + FOREACH_SCENE_OBJECT(scene, ob_iter) + { + if (ob_iter->type == ob_active->type) { + if (ob_iter != ob_active && ob_iter->data == ob_active->data) { + BLI_freelistN(&ob_iter->defbase); + BLI_duplicatelist(&ob_iter->defbase, &ob_active->defbase); + ob_iter->actdef = ob_active->actdef; - DAG_id_tag_update(&base->object->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, base->object); - WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, base->object->data); + DEG_id_tag_update(&ob_iter->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter); + WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob_iter->data); retval = OPERATOR_FINISHED; } } } + FOREACH_SCENE_OBJECT_END return retval; } @@ -3367,7 +3373,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) { if (obact != ob) { if (ED_vgroup_array_copy(ob, obact)) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob); changed_tot++; } @@ -3410,7 +3416,7 @@ static int set_active_group_exec(bContext *C, wmOperator *op) BLI_assert(nr + 1 >= 0); ob->actdef = nr + 1; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob); return OPERATOR_FINISHED; @@ -3624,7 +3630,7 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op) ret = vgroup_do_remap(ob, name_array, op); if (ret != OPERATOR_CANCELLED) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob); } @@ -3674,7 +3680,7 @@ static int vgroup_move_exec(bContext *C, wmOperator *op) ret = vgroup_do_remap(ob, name_array, op); if (ret != OPERATOR_CANCELLED) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob); } } @@ -3803,7 +3809,7 @@ static int vertex_weight_paste_exec(bContext *C, wmOperator *op) vgroup_copy_active_to_sel_single(ob, def_nr); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -3840,7 +3846,7 @@ static int vertex_weight_delete_exec(bContext *C, wmOperator *op) vgroup_remove_weight(ob, def_nr); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -3873,7 +3879,7 @@ static int vertex_weight_set_active_exec(bContext *C, wmOperator *op) if (wg_index != -1) { ob->actdef = wg_index + 1; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); } @@ -3910,7 +3916,7 @@ static int vertex_weight_normalize_active_vertex_exec(bContext *C, wmOperator *U changed = vgroup_normalize_active_vertex(ob, subset_type); if (changed) { - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -3943,7 +3949,7 @@ static int vertex_weight_copy_exec(bContext *C, wmOperator *UNUSED(op)) vgroup_copy_active_to_sel(ob, subset_type); - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; |