diff options
Diffstat (limited to 'source/blender/editors/object/object_add.c')
-rw-r--r-- | source/blender/editors/object/object_add.c | 360 |
1 files changed, 215 insertions, 145 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index e4f6d0da38f..839e5f415e2 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 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) { @@ -831,7 +925,7 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv { Scene *scene = CTX_data_scene(C); - Base *base = NULL; + BaseLegacy *base = NULL; Image *ima = NULL; Object *ob = 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_base_object_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_base_object_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_DATABLOCK(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_base_object_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,10 @@ 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, ob_src, ob_dst); + base_dst = BKE_scene_layer_base_find(sl, ob_dst); + + BKE_scene_object_base_flag_sync_from_base(base_dst); /* make sure apply works */ BKE_animdata_free(&ob_dst->id, true); @@ -1396,7 +1477,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 +1500,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 +1554,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 +1563,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 +1599,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 +1633,14 @@ static 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 +1648,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) { @@ -1592,7 +1672,7 @@ static int convert_poll(bContext *C) } /* 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 +1682,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,6 +1695,8 @@ 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); DerivedMesh *dm; @@ -1631,10 +1708,12 @@ 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; + BaseLegacy *base; for (base = scene->base.first; base; base = base->next) { ob = base->object; @@ -1665,7 +1744,7 @@ static int convert_exec(bContext *C, wmOperator *op) * on other objects data masks too, see: T50950. */ { for (CollectionPointerLink *link = selected_editable_bases.first; link; link = link->next) { - Base *base = link->ptr.data; + BaseLegacy *base = link->ptr.data; ob = base->object; /* The way object type conversion works currently (enforcing conversion of *all* objetcs using converted @@ -1679,7 +1758,7 @@ 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); } uint64_t customdata_mask_prev = scene->customdata_mask; @@ -1689,7 +1768,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; + BaseLegacy *base = link->ptr.data; ob = base->object; if (ob->flag & OB_DONE || !IS_TAGGED(ob->data)) { @@ -1711,7 +1790,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 +1804,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 +1815,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 +1827,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 +1846,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 +1893,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 +1906,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 +1917,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 +1930,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); @@ -1873,7 +1952,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 +1968,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 +1995,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 +2003,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; + FOREACH_SCENE_OBJECT(scene, ob_mball) + { if (ob->type == OB_MBALL) { if (ob->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_base_object_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 +2028,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_NEW = 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_NEW->object->flag & OB_DONE) { + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT_NEW->object); + WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT_NEW->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 +2075,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 +2213,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) { @@ -2239,14 +2312,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; } @@ -2273,6 +2346,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; @@ -2280,22 +2354,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_NEW == 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; @@ -2304,7 +2379,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); @@ -2340,9 +2417,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; @@ -2357,22 +2434,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) { @@ -2383,16 +2455,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); |