Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/object/object_add.c
| Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_collection.h" | #include "BKE_collection.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_constraint.h" | #include "BKE_constraint.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "BKE_DerivedMesh.h" | #include "BKE_DerivedMesh.h" | ||||
| #include "BKE_displist.h" | #include "BKE_displist.h" | ||||
| #include "BKE_effect.h" | #include "BKE_effect.h" | ||||
| #include "BKE_font.h" | #include "BKE_font.h" | ||||
| #include "BKE_group.h" | |||||
| #include "BKE_lamp.h" | #include "BKE_lamp.h" | ||||
| #include "BKE_lattice.h" | #include "BKE_lattice.h" | ||||
| #include "BKE_layer.h" | #include "BKE_layer.h" | ||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_library_query.h" | #include "BKE_library_query.h" | ||||
| #include "BKE_library_remap.h" | #include "BKE_library_remap.h" | ||||
| #include "BKE_key.h" | #include "BKE_key.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| ▲ Show 20 Lines • Show All 960 Lines • ▼ Show 20 Lines | void OBJECT_OT_lamp_add(wmOperatorType *ot) | ||||
| /* properties */ | /* properties */ | ||||
| ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_lamp_type_items, 0, "Type", ""); | ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_lamp_type_items, 0, "Type", ""); | ||||
| RNA_def_property_translation_context(ot->prop, BLT_I18NCONTEXT_ID_LAMP); | RNA_def_property_translation_context(ot->prop, BLT_I18NCONTEXT_ID_LAMP); | ||||
| ED_object_add_unit_props(ot); | ED_object_add_unit_props(ot); | ||||
| ED_object_add_generic_props(ot, false); | ED_object_add_generic_props(ot, false); | ||||
| } | } | ||||
| /********************* Add Group Instance Operator ********************/ | /********************* Add Collection Instance Operator ********************/ | ||||
| static int group_instance_add_exec(bContext *C, wmOperator *op) | static int collection_instance_add_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Group *group; | Collection *collection; | ||||
| unsigned int layer; | unsigned int layer; | ||||
| float loc[3], rot[3]; | float loc[3], rot[3]; | ||||
| if (RNA_struct_property_is_set(op->ptr, "name")) { | if (RNA_struct_property_is_set(op->ptr, "name")) { | ||||
| char name[MAX_ID_NAME - 2]; | char name[MAX_ID_NAME - 2]; | ||||
| RNA_string_get(op->ptr, "name", name); | RNA_string_get(op->ptr, "name", name); | ||||
| group = (Group *)BKE_libblock_find_name(ID_GR, name); | collection = (Collection *)BKE_libblock_find_name(ID_GR, name); | ||||
| if (0 == RNA_struct_property_is_set(op->ptr, "location")) { | if (0 == RNA_struct_property_is_set(op->ptr, "location")) { | ||||
| const wmEvent *event = CTX_wm_window(C)->eventstate; | const wmEvent *event = CTX_wm_window(C)->eventstate; | ||||
| ARegion *ar = CTX_wm_region(C); | ARegion *ar = CTX_wm_region(C); | ||||
| const int mval[2] = {event->x - ar->winrct.xmin, | const int mval[2] = {event->x - ar->winrct.xmin, | ||||
| event->y - ar->winrct.ymin}; | event->y - ar->winrct.ymin}; | ||||
| ED_object_location_from_view(C, loc); | ED_object_location_from_view(C, loc); | ||||
| ED_view3d_cursor3d_position(C, loc, mval); | ED_view3d_cursor3d_position(C, loc, mval); | ||||
| RNA_float_set_array(op->ptr, "location", loc); | RNA_float_set_array(op->ptr, "location", loc); | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); | collection = BLI_findlink(&CTX_data_main(C)->collection, RNA_enum_get(op->ptr, "collection")); | ||||
| if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL)) | if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL)) | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| if (group) { | if (collection) { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Object *ob = ED_object_add_type(C, OB_EMPTY, group->id.name + 2, loc, rot, false, layer); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| ob->dup_group = group; | |||||
| /* Avoid dependency cycles. */ | |||||
| LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer); | |||||
| while (BKE_collection_find_cycle(active_lc->collection, collection)) { | |||||
| active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc); | |||||
| } | |||||
| Object *ob = ED_object_add_type(C, OB_EMPTY, collection->id.name + 2, loc, rot, false, layer); | |||||
| ob->dup_group = collection; | |||||
| ob->transflag |= OB_DUPLIGROUP; | ob->transflag |= OB_DUPLIGROUP; | ||||
| id_us_plus(&group->id); | id_us_plus(&collection->id); | ||||
| /* works without this except if you try render right after, see: 22027 */ | /* works without this except if you try render right after, see: 22027 */ | ||||
| DEG_relations_tag_update(bmain); | DEG_relations_tag_update(bmain); | ||||
| DEG_id_tag_update(&group->id, 0); | DEG_id_tag_update(&collection->id, 0); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); | WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* only used as menu */ | /* only used as menu */ | ||||
| void OBJECT_OT_group_instance_add(wmOperatorType *ot) | void OBJECT_OT_collection_instance_add(wmOperatorType *ot) | ||||
| { | { | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Add Group Instance"; | ot->name = "Add Collection Instance"; | ||||
| ot->description = "Add a dupligroup instance"; | ot->description = "Add a collection instance"; | ||||
| ot->idname = "OBJECT_OT_group_instance_add"; | ot->idname = "OBJECT_OT_collection_instance_add"; | ||||
| /* api callbacks */ | /* api callbacks */ | ||||
| ot->invoke = WM_enum_search_invoke; | ot->invoke = WM_enum_search_invoke; | ||||
| ot->exec = group_instance_add_exec; | ot->exec = collection_instance_add_exec; | ||||
| ot->poll = ED_operator_objectmode; | ot->poll = ED_operator_objectmode; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| /* properties */ | /* properties */ | ||||
| RNA_def_string(ot->srna, "name", "Group", MAX_ID_NAME - 2, "Name", "Group name to add"); | RNA_def_string(ot->srna, "name", "Collection", MAX_ID_NAME - 2, "Name", "Collection name to add"); | ||||
| prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", ""); | prop = RNA_def_enum(ot->srna, "collection", DummyRNA_NULL_items, 0, "Collection", ""); | ||||
| RNA_def_enum_funcs(prop, RNA_group_itemf); | RNA_def_enum_funcs(prop, RNA_collection_itemf); | ||||
| RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); | RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); | ||||
| ot->prop = prop; | ot->prop = prop; | ||||
| ED_object_add_generic_props(ot, false); | ED_object_add_generic_props(ot, false); | ||||
| } | } | ||||
| /********************* Add Speaker Operator ********************/ | /********************* Add Speaker Operator ********************/ | ||||
| static int object_speaker_add_exec(bContext *C, wmOperator *op) | static int object_speaker_add_exec(bContext *C, wmOperator *op) | ||||
| ▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | if (BKE_library_ID_is_indirectly_used(bmain, ob) && | ||||
| /* We cannot delete indirectly used object... */ | /* We cannot delete indirectly used object... */ | ||||
| printf("WARNING, undeletable object '%s', should have been catched before reaching this function!", | printf("WARNING, undeletable object '%s', should have been catched before reaching this function!", | ||||
| ob->id.name + 2); | ob->id.name + 2); | ||||
| return; | return; | ||||
| } | } | ||||
| DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_BASE_FLAGS_UPDATE); | DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_BASE_FLAGS_UPDATE); | ||||
| BKE_collections_object_remove(bmain, &scene->id, ob, true); | BKE_scene_collections_object_remove(bmain, scene, ob, true); | ||||
| } | } | ||||
| static int object_delete_exec(bContext *C, wmOperator *op) | static int object_delete_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| wmWindow *win; | wmWindow *win; | ||||
| ▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | for (dob = lb_duplis->first; dob; dob = dob->next) { | ||||
| /* font duplis can have a totcol without material, we get them from parent | /* font duplis can have a totcol without material, we get them from parent | ||||
| * should be implemented better... | * should be implemented better... | ||||
| */ | */ | ||||
| if (ob_dst->mat == NULL) { | if (ob_dst->mat == NULL) { | ||||
| ob_dst->totcol = 0; | ob_dst->totcol = 0; | ||||
| } | } | ||||
| BKE_collection_object_add_from(scene, base->object, ob_dst); | BKE_collection_object_add_from(bmain, scene, base->object, ob_dst); | ||||
| base_dst = BKE_view_layer_base_find(view_layer, ob_dst); | base_dst = BKE_view_layer_base_find(view_layer, ob_dst); | ||||
| BLI_assert(base_dst != NULL); | BLI_assert(base_dst != NULL); | ||||
| BKE_scene_object_base_flag_sync_from_base(base_dst); | BKE_scene_object_base_flag_sync_from_base(base_dst); | ||||
| /* make sure apply works */ | /* make sure apply works */ | ||||
| BKE_animdata_free(&ob_dst->id, true); | BKE_animdata_free(&ob_dst->id, true); | ||||
| ob_dst->adt = NULL; | ob_dst->adt = NULL; | ||||
| ▲ Show 20 Lines • Show All 204 Lines • ▼ Show 20 Lines | static Base *duplibase_for_convert(Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base, Object *ob) | ||||
| Base *basen; | Base *basen; | ||||
| if (ob == NULL) { | if (ob == NULL) { | ||||
| ob = base->object; | ob = base->object; | ||||
| } | } | ||||
| obn = BKE_object_copy(bmain, ob); | obn = BKE_object_copy(bmain, ob); | ||||
| DEG_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); | ||||
| BKE_collection_object_add_from(scene, ob, obn); | BKE_collection_object_add_from(bmain, scene, ob, obn); | ||||
| basen = BKE_view_layer_base_find(view_layer, obn); | basen = BKE_view_layer_base_find(view_layer, obn); | ||||
| ED_object_base_select(basen, BA_SELECT); | ED_object_base_select(basen, BA_SELECT); | ||||
| ED_object_base_select(basen, BA_DESELECT); | ED_object_base_select(basen, BA_DESELECT); | ||||
| return basen; | return basen; | ||||
| } | } | ||||
| static int convert_exec(bContext *C, wmOperator *op) | static int convert_exec(bContext *C, wmOperator *op) | ||||
| ▲ Show 20 Lines • Show All 392 Lines • ▼ Show 20 Lines | if (ob->mode & OB_MODE_POSE) { | ||||
| ; /* nothing? */ | ; /* nothing? */ | ||||
| } | } | ||||
| else { | else { | ||||
| obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); | obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); | ||||
| DEG_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); | ||||
| base = BKE_view_layer_base_find(view_layer, ob); | base = BKE_view_layer_base_find(view_layer, ob); | ||||
| if ((base != NULL) && (base->flag & BASE_VISIBLED)) { | if ((base != NULL) && (base->flag & BASE_VISIBLED)) { | ||||
| BKE_collection_object_add_from(scene, ob, obn); | BKE_collection_object_add_from(bmain, scene, ob, obn); | ||||
| } | } | ||||
| else { | else { | ||||
| LayerCollection *layer_collection = BKE_layer_collection_get_active_ensure(scene, view_layer); | LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer); | ||||
| BKE_collection_object_add(&scene->id, layer_collection->scene_collection, obn); | BKE_collection_object_add(bmain, layer_collection->collection, obn); | ||||
| } | } | ||||
| basen = BKE_view_layer_base_find(view_layer, obn); | basen = BKE_view_layer_base_find(view_layer, obn); | ||||
| /* 1) duplis should end up in same group as the original | /* 1) duplis should end up in same collection as the original | ||||
| * 2) Rigid Body sim participants MUST always be part of a group... | * 2) Rigid Body sim participants MUST always be part of a collection... | ||||
| */ | */ | ||||
| // XXX: is 2) really a good measure here? | // XXX: is 2) really a good measure here? | ||||
| if ((ob->flag & OB_FROMGROUP) != 0 || ob->rigidbody_object || ob->rigidbody_constraint) { | if (ob->rigidbody_object || ob->rigidbody_constraint) { | ||||
| Group *group; | Collection *collection; | ||||
| for (group = bmain->group.first; group; group = group->id.next) { | for (collection = bmain->collection.first; collection; collection = collection->id.next) { | ||||
| if (BKE_group_object_exists(group, ob)) | if (BKE_collection_has_object(collection, ob)) | ||||
| BKE_group_object_add(group, obn); | BKE_collection_object_add(bmain, collection, obn); | ||||
| } | } | ||||
| } | } | ||||
| /* duplicates using userflags */ | /* duplicates using userflags */ | ||||
| if (dupflag & USER_DUP_ACT) { | if (dupflag & USER_DUP_ACT) { | ||||
| BKE_animdata_copy_id_action(&obn->id, true); | BKE_animdata_copy_id_action(&obn->id, true); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 459 Lines • Show Last 20 Lines | |||||