diff options
-rw-r--r-- | source/blender/editors/include/ED_object.h | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 72 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_edit.c | 42 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/space_outliner.c | 16 |
4 files changed, 81 insertions, 53 deletions
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index dc7bfd6aff2..3036e73c811 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -85,8 +85,8 @@ extern struct EnumPropertyItem prop_clear_parent_types[]; extern struct EnumPropertyItem prop_make_parent_types[]; int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, struct Object *par, int partype); -void ED_object_parent_clear(struct bContext *C, int type); -struct Base *ED_object_scene_link(struct ReportList *reports, struct Scene *scene, struct Object *ob); +void ED_object_parent_clear(struct Object *ob, int type); +struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob); /* generic editmode keys like pet * do_pet diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 8657ac3622c..34fb2ca6c32 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -424,27 +424,35 @@ EnumPropertyItem prop_clear_parent_types[] = { {0, NULL, 0, NULL, NULL} }; -void ED_object_parent_clear(bContext *C, int type) +void ED_object_parent_clear(Object *ob, int type) +{ + + if (ob->parent == NULL) + return; + + if (type == 0) { + ob->parent = NULL; + } + else if (type == 1) { + ob->parent = NULL; + BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE); + } + else if (type == 2) + unit_m4(ob->parentinv); + + ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; +} + +/* note, poll should check for editable scene */ +static int parent_clear_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + int type = RNA_enum_get(op->ptr, "type"); CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { - if (ob->parent == NULL) - continue; - - if (type == 0) { - ob->parent = NULL; - } - else if (type == 1) { - ob->parent = NULL; - BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE); - } - else if (type == 2) - unit_m4(ob->parentinv); - - ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; + ED_object_parent_clear(ob, type); } CTX_DATA_END; @@ -452,13 +460,6 @@ void ED_object_parent_clear(bContext *C, int type) DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); -} - -/* note, poll should check for editable scene */ -static int parent_clear_exec(bContext *C, wmOperator *op) -{ - ED_object_parent_clear(C, RNA_enum_get(op->ptr, "type")); - return OPERATOR_FINISHED; } @@ -1195,22 +1196,11 @@ static void link_to_scene(Main *UNUSED(bmain), unsigned short UNUSED(nr)) } #endif -Base *ED_object_scene_link(ReportList *reports, Scene *scene, Object *ob) +Base *ED_object_scene_link(Scene *scene, Object *ob) { Base *base; - if (ELEM(NULL, ob, scene)) { - BKE_report(reports, RPT_ERROR, "Couldn't find scene"); - return NULL; - } - if (BKE_scene_base_find(scene, ob)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is already in scene \"%s\"", ob->id.name + 2, scene->id.name + 2); - return NULL; - } - - if (scene->id.lib) { - BKE_report(reports, RPT_ERROR, "Can't link objects into a linked scene"); return NULL; } @@ -1225,16 +1215,24 @@ static int make_links_scene_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Scene *scene_to = BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene")); + if (scene_to == NULL) { + BKE_report(op->reports, RPT_ERROR, "Couldn't find scene"); + return OPERATOR_CANCELLED; + } + if (scene_to == CTX_data_scene(C)) { BKE_report(op->reports, RPT_ERROR, "Can't link objects into the same scene"); return OPERATOR_CANCELLED; } + if (scene_to->id.lib) { + BKE_report(op->reports, RPT_ERROR, "Can't link objects into a linked scene"); + return OPERATOR_CANCELLED; + } + CTX_DATA_BEGIN (C, Base *, base, selected_bases) { - if (ED_object_scene_link(op->reports, scene_to, base->object) == NULL) { - return OPERATOR_CANCELLED; - } + ED_object_scene_link(scene_to, base->object); } CTX_DATA_END; diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 79a1e0c7634..8a332e9329a 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1453,7 +1453,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) SpaceOops *soops = CTX_wm_space_outliner(C); ARegion *ar = CTX_wm_region(C); Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); + Scene *scene = NULL; TreeElement *te = NULL; TreeElement *te_found = NULL; char childname[MAX_ID_NAME]; @@ -1485,10 +1485,12 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } - /* check dragged object (child) is active */ - if (ob != CTX_data_active_object(C)) - ED_base_object_select(BKE_scene_base_find(scene, ob), BA_SELECT); - + scene = (Scene *)outliner_search_back(soops, te_found, ID_SCE); + + if(scene == NULL) { + return OPERATOR_CANCELLED; + } + if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { if (ED_object_parent_set(op->reports, bmain, scene, ob, par, partype)) { DAG_scene_sort(bmain, scene); @@ -1654,19 +1656,31 @@ int outliner_dropzone_parent_clear(bContext *C, wmEvent *event, TreeElement *te, static int parent_clear_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { - Scene *scene = CTX_data_scene(C); + Main *bmain = CTX_data_main(C); + Scene *scene = NULL; Object *ob = NULL; + SpaceOops *soops = CTX_wm_space_outliner(C); + TreeElement *te; char obname[MAX_ID_NAME]; RNA_string_get(op->ptr, "dragged_obj", obname); ob = (Object *)BKE_libblock_find_name(ID_OB, obname); - /* check dragged object (child) is active */ - if (ob != CTX_data_active_object(C)) - ED_base_object_select(BKE_scene_base_find(scene, ob), BA_SELECT); + /* search forwards to find the object */ + te = outliner_find_id(soops, &soops->tree, (ID *)ob); + /* then search backwards to get the scene */ + scene = (Scene *)outliner_search_back(soops, te, ID_SCE); - ED_object_parent_clear(C, RNA_enum_get(op->ptr, "type")); + if(scene == NULL) { + return OPERATOR_CANCELLED; + } + + ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type")); + DAG_scene_sort(bmain, scene); + DAG_ids_flush_update(bmain, 0); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); return OPERATOR_FINISHED; } @@ -1735,8 +1749,12 @@ static int scene_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) RNA_string_get(op->ptr, "object", obname); ob = (Object *)BKE_libblock_find_name(ID_OB, obname); - - base = ED_object_scene_link(op->reports, scene, ob); + + if (ELEM(NULL, ob, scene) || scene->id.lib != NULL) { + return OPERATOR_CANCELLED; + } + + base = ED_object_scene_link(scene, ob); if (base == NULL) { return OPERATOR_CANCELLED; diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index f3f6e3cf49f..4d45be561c6 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -41,6 +41,7 @@ #include "BKE_context.h" #include "BKE_screen.h" +#include "BKE_scene.h" #include "ED_space_api.h" #include "ED_screen.h" @@ -52,6 +53,9 @@ #include "RNA_access.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" + #include "UI_resources.h" #include "UI_view2d.h" @@ -91,7 +95,13 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) for (te = soops->tree.first; te; te = te->next) { TreeElement *te_valid; te_valid = outliner_dropzone_parent(C, event, te, fmval); - if (te_valid) return 1; + if (te_valid) { + /* check that parent/child are both in the same scene */ + Scene *scene = (Scene *)outliner_search_back(soops, te_valid, ID_SCE); + if (BKE_scene_base_find(scene, (Object *)id)) { + return 1; + } + } } } } @@ -117,7 +127,9 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, wmEvent *event) if (drag->type == WM_DRAG_ID) { ID *id = (ID *)drag->poin; if (GS(id->name) == ID_OB) { - //TODO: Check if no parent? + if (((Object *)id)->parent == NULL) { + return 0; + } /* Ensure location under cursor is valid dropzone */ for (te = soops->tree.first; te; te = te->next) { if (outliner_dropzone_parent_clear(C, event, te, fmval)) return 1; |