diff options
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r-- | source/blender/editors/object/object_add.c | 61 | ||||
-rw-r--r-- | source/blender/editors/object/object_bake.c | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_bake_api.c | 211 | ||||
-rw-r--r-- | source/blender/editors/object/object_constraint.c | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 23 | ||||
-rw-r--r-- | source/blender/editors/object/object_group.c | 64 | ||||
-rw-r--r-- | source/blender/editors/object/object_hook.c | 3 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/object/object_lattice.c | 15 | ||||
-rw-r--r-- | source/blender/editors/object/object_lod.c | 7 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 3 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 105 | ||||
-rw-r--r-- | source/blender/editors/object/object_select.c | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_shapekey.c | 75 | ||||
-rw-r--r-- | source/blender/editors/object/object_transform.c | 57 | ||||
-rw-r--r-- | source/blender/editors/object/object_vgroup.c | 59 |
17 files changed, 482 insertions, 216 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 99dd8b75609..8972dd7cf08 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -34,6 +34,7 @@ #include "MEM_guardedalloc.h" #include "DNA_anim_types.h" +#include "DNA_camera_types.h" #include "DNA_curve_types.h" #include "DNA_group_types.h" #include "DNA_lamp_types.h" @@ -83,6 +84,7 @@ #include "BKE_report.h" #include "BKE_sca.h" #include "BKE_scene.h" +#include "BKE_screen.h" #include "BKE_speaker.h" #include "BKE_texture.h" @@ -95,6 +97,7 @@ #include "ED_armature.h" #include "ED_curve.h" +#include "ED_lattice.h" #include "ED_mball.h" #include "ED_mesh.h" #include "ED_node.h" @@ -336,10 +339,7 @@ bool ED_object_add_generic_get_opts(bContext *C, wmOperator *op, const char view } else { Scene *scene = CTX_data_scene(C); - if (v3d) - *layer = (v3d->scenelock && !v3d->localvd) ? scene->layact : v3d->layact; - else - *layer = scene->layact; + *layer = BKE_screen_view3d_layer_active_ex(v3d, scene, false); for (a = 0; a < 20; a++) { layer_values[a] = *layer & (1 << a); } @@ -446,14 +446,17 @@ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const floa /* for object add operator */ static int object_add_exec(bContext *C, wmOperator *op) { + Object *ob; bool enter_editmode; unsigned int layer; float loc[3], rot[3]; + 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; - ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer); + ob = ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer); + BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius")); return OPERATOR_FINISHED; } @@ -472,6 +475,8 @@ void OBJECT_OT_add(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + /* properties */ + ED_object_add_unit_props(ot); RNA_def_enum(ot->srna, "type", object_type_items, 0, "Type", ""); ED_object_add_generic_props(ot, true); @@ -488,32 +493,31 @@ static int effector_add_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; float mat[4][4]; + float dia; + 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"); + dia = RNA_float_get(op->ptr, "radius"); if (type == PFIELD_GUIDE) { Curve *cu; ob = ED_object_add_type(C, OB_CURVE, loc, rot, false, layer); - if (!ob) - return OPERATOR_CANCELLED; rename_id(&ob->id, CTX_DATA_(BLF_I18NCONTEXT_ID_OBJECT, "CurveGuide")); cu = ob->data; cu->flag |= CU_PATH | CU_3D; ED_object_editmode_enter(C, 0); ED_object_new_primitive_matrix(C, ob, loc, rot, mat, false); - BLI_addtail(&cu->editnurb->nurbs, add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1)); + BLI_addtail(&cu->editnurb->nurbs, add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, dia)); if (!enter_editmode) ED_object_editmode_exit(C, EM_FREEDATA); } else { ob = ED_object_add_type(C, OB_EMPTY, loc, rot, false, layer); - if (!ob) - return OPERATOR_CANCELLED; - + BKE_object_obdata_size_init(ob, dia); rename_id(&ob->id, CTX_DATA_(BLF_I18NCONTEXT_ID_OBJECT, "Field")); if (ELEM(type, PFIELD_WIND, PFIELD_VORTEX)) ob->empty_drawtype = OB_SINGLE_ARROW; @@ -540,8 +544,10 @@ void OBJECT_OT_effector_add(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + /* properties */ ot->prop = RNA_def_enum(ot->srna, "type", field_type_items, 0, "Type", ""); + ED_object_add_unit_props(ot); ED_object_add_generic_props(ot, true); } @@ -552,6 +558,7 @@ static int object_camera_add_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); Object *ob; + Camera *cam; bool enter_editmode; unsigned int layer; float loc[3], rot[3]; @@ -572,6 +579,9 @@ static int object_camera_add_exec(bContext *C, wmOperator *op) } } + cam = ob->data; + cam->drawsize = v3d ? ED_view3d_grid_scale(scene, v3d, NULL) : ED_scene_grid_scale(scene, NULL); + return OPERATOR_FINISHED; } @@ -668,6 +678,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; + 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; @@ -675,6 +686,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; obedit = ED_object_add_type(C, OB_FONT, loc, rot, enter_editmode, layer); + BKE_object_obdata_size_init(obedit, RNA_float_get(op->ptr, "radius")); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit); @@ -694,6 +706,9 @@ void OBJECT_OT_text_add(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ED_object_add_unit_props(ot); ED_object_add_generic_props(ot, true); } @@ -706,9 +721,10 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) bool newob = false; bool enter_editmode; unsigned int layer; - float loc[3], rot[3]; + float loc[3], rot[3], dia; bool view_aligned = rv3d && (U.flag & USER_ADD_VIEWALIGNED); + 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; @@ -726,7 +742,8 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - add_primitive_bone(obedit, view_aligned); + dia = RNA_float_get(op->ptr, "radius"); + ED_armature_edit_bone_add_primitive(obedit, dia, view_aligned); /* userdef */ if (newob && !enter_editmode) @@ -750,6 +767,9 @@ void OBJECT_OT_armature_add(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ED_object_add_unit_props(ot); ED_object_add_generic_props(ot, true); } @@ -762,12 +782,14 @@ static int object_empty_add_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; + WM_operator_view3d_unit_defaults(C, op); if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; ob = ED_object_add_type(C, OB_EMPTY, loc, rot, false, layer); BKE_object_empty_draw_type_set(ob, type); + BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius")); return OPERATOR_FINISHED; } @@ -790,6 +812,7 @@ void OBJECT_OT_empty_add(wmOperatorType *ot) /* properties */ ot->prop = RNA_def_enum(ot->srna, "type", object_empty_drawtype_items, 0, "Type", ""); + ED_object_add_unit_props(ot); ED_object_add_generic_props(ot, false); } @@ -899,12 +922,14 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; + WM_operator_view3d_unit_defaults(C, op); if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; ob = ED_object_add_type(C, OB_LAMP, loc, rot, false, layer); - la = (Lamp *)ob->data; + BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius")); + la = (Lamp *)ob->data; la->type = type; rename_id(&ob->id, get_lamp_defname(type)); rename_id(&la->id, get_lamp_defname(type)); @@ -936,6 +961,7 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", lamp_type_items, 0, "Type", ""); RNA_def_property_translation_context(ot->prop, BLF_I18NCONTEXT_ID_LAMP); + ED_object_add_unit_props(ot); ED_object_add_generic_props(ot, false); } @@ -1470,7 +1496,7 @@ static void convert_ensure_curve_cache(Main *bmain, Scene *scene, Object *ob) /* Force creation. This is normally not needed but on operator * redo we might end up with an object which isn't evaluated yet. */ - if (ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) { + if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) { BKE_displist_make_curveTypes(scene, ob, false); } else if (ob->type == OB_MBALL) { @@ -2191,6 +2217,7 @@ 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; Object *ob; @@ -2223,7 +2250,7 @@ static int add_named_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - basen->lay = basen->object->lay = scene->lay; + basen->lay = basen->object->lay = BKE_screen_view3d_layer_active(v3d, scene); basen->object->restrictflag &= ~OB_RESTRICT_VIEW; if (event) { @@ -2274,7 +2301,7 @@ static int join_poll(bContext *C) if (!ob || ob->id.lib) return 0; - if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE)) + if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE)) return ED_operator_screenactive(C); else return 0; diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 94574e81b81..2402ecb498d 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -770,7 +770,7 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const static bool is_multires_bake(Scene *scene) { - if (ELEM4(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_AO)) + if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_AO)) return scene->r.bake_flag & R_BAKE_MULTIRES; return 0; diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index b45ac124b43..372ca33fa4b 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -51,6 +51,7 @@ #include "BKE_image.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_report.h" #include "BKE_modifier.h" #include "BKE_mesh.h" @@ -74,6 +75,63 @@ #include "object_intern.h" + +typedef struct BakeAPIRender { + Object *ob; + Main *main; + Scene *scene; + ReportList *reports; + ListBase selected_objects; + + ScenePassType pass_type; + int margin; + + int save_mode; + + bool is_clear; + bool is_split_materials; + bool is_automatic_name; + bool is_selected_to_active; + bool is_cage; + + float cage_extrusion; + int normal_space; + BakeNormalSwizzle normal_swizzle[3]; + + char uv_layer[MAX_CUSTOMDATA_LAYER_NAME]; + char custom_cage[MAX_NAME]; + char filepath[FILE_MAX]; + + int width; + int height; + const char *identifier; + + int result; + bool ready; + + /* callbacks */ + Render *render; + float *progress; + short *do_update; + + /* for redrawing */ + ScrArea *sa; +} BakeAPIRender; + +/* callbacks */ + +static void bake_progress_update(void *bjv, float progress) +{ + BakeAPIRender *bj = bjv; + + if (bj->progress && *bj->progress != progress) { + *bj->progress = progress; + + /* make jobs timer to send notifier */ + *(bj->do_update) = true; + } +} + /* catch esc */ static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { @@ -120,7 +178,7 @@ static bool write_internal_bake_pixels( void *lock; bool is_float; char *mask_buffer = NULL; - const int num_pixels = width * height; + const size_t num_pixels = (size_t)width * (size_t)height; ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); @@ -156,7 +214,7 @@ static bool write_internal_bake_pixels( IMB_buffer_float_from_float( ibuf->rect_float, buffer, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false, - ibuf->x, ibuf->y, ibuf->x, ibuf->y); + ibuf->x, ibuf->y, ibuf->x, ibuf->x); } else { IMB_buffer_byte_from_float( @@ -169,7 +227,7 @@ static bool write_internal_bake_pixels( if (is_float) { IMB_buffer_float_from_float_mask( ibuf->rect_float, buffer, ibuf->channels, - ibuf->x, ibuf->y, ibuf->x, ibuf->y, mask_buffer); + ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer); } else { IMB_buffer_byte_from_float_mask( @@ -235,7 +293,7 @@ static bool write_external_bake_pixels( IMB_buffer_float_from_float( ibuf->rect_float, buffer, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false, - ibuf->x, ibuf->y, ibuf->x, ibuf->y); + ibuf->x, ibuf->y, ibuf->x, ibuf->x); } else { if (!is_noncolor) { @@ -253,7 +311,7 @@ static bool write_external_bake_pixels( /* margins */ if (margin > 0) { char *mask_buffer = NULL; - const int num_pixels = width * height; + const size_t num_pixels = (size_t)width * (size_t)height; mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask"); RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer); @@ -278,14 +336,14 @@ static bool write_external_bake_pixels( static bool is_noncolor_pass(ScenePassType pass_type) { - return ELEM7(pass_type, - SCE_PASS_Z, - SCE_PASS_NORMAL, - SCE_PASS_VECTOR, - SCE_PASS_INDEXOB, - SCE_PASS_UV, - SCE_PASS_RAYHITS, - SCE_PASS_INDEXMA); + return ELEM(pass_type, + SCE_PASS_Z, + SCE_PASS_NORMAL, + SCE_PASS_VECTOR, + SCE_PASS_INDEXOB, + SCE_PASS_UV, + SCE_PASS_RAYHITS, + SCE_PASS_INDEXMA); } /* if all is good tag image and return true */ @@ -310,10 +368,22 @@ static bool bake_object_check(Object *ob, ReportList *reports) } for (i = 0; i < ob->totcol; i++) { - ED_object_get_active_image(ob, i + 1, &image, NULL, NULL); + bNodeTree *ntree = NULL; + bNode *node = NULL; + ED_object_get_active_image(ob, i + 1, &image, NULL, &node, &ntree); if (image) { - ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); + ImBuf *ibuf; + + if (node) { + if (BKE_node_is_connected_to_output(ntree, node)) { + BKE_reportf(reports, RPT_ERROR, + "Circular dependency for image \"%s\" from object \"%s\"", + image->id.name + 2, ob->id.name + 2); + } + } + + ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); if (ibuf) { BKE_image_release_ibuf(image, ibuf, lock); @@ -372,7 +442,7 @@ static bool bake_objects_check(Main *bmain, Object *ob, ListBase *selected_objec if (ob_iter == ob) continue; - if (ELEM5(ob_iter->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL) == false) { + if (ELEM(ob_iter->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL) == false) { BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh or can't be converted to a mesh (Curve, Text, Surface or Metaball)", ob_iter->id.name + 2); return false; } @@ -420,7 +490,7 @@ static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images) for (i = 0; i < tot_mat; i++) { Image *image; - ED_object_get_active_image(ob, i + 1, &image, NULL, NULL); + ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL); if ((image->id.flag & LIB_DOIT)) { for (j = 0; j < i; j++) { @@ -444,10 +514,10 @@ static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images) /* * returns the total number of pixels */ -static int initialize_internal_images(BakeImages *bake_images, ReportList *reports) +static size_t initialize_internal_images(BakeImages *bake_images, ReportList *reports) { int i; - int tot_size = 0; + size_t tot_size = 0; for (i = 0; i < bake_images->size; i++) { ImBuf *ibuf; @@ -461,7 +531,7 @@ static int initialize_internal_images(BakeImages *bake_images, ReportList *repor bk_image->height = ibuf->y; bk_image->offset = tot_size; - tot_size += ibuf->x * ibuf->y; + tot_size += (size_t)ibuf->x * (size_t)ibuf->y; } else { BKE_image_release_ibuf(bk_image->image, ibuf, lock); @@ -473,45 +543,8 @@ static int initialize_internal_images(BakeImages *bake_images, ReportList *repor return tot_size; } -typedef struct BakeAPIRender { - Object *ob; - Main *main; - Scene *scene; - ReportList *reports; - ListBase selected_objects; - - ScenePassType pass_type; - int margin; - - int save_mode; - - bool is_clear; - bool is_split_materials; - bool is_automatic_name; - bool is_selected_to_active; - bool is_cage; - - float cage_extrusion; - int normal_space; - BakeNormalSwizzle normal_swizzle[3]; - - char uv_layer[MAX_CUSTOMDATA_LAYER_NAME]; - char custom_cage[MAX_NAME]; - char filepath[FILE_MAX]; - - int width; - int height; - const char *identifier; - - int result; - bool ready; - - /* for redrawing */ - ScrArea *sa; -} BakeAPIRender; - static int bake( - Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports, + Render *re, Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports, const ScenePassType pass_type, const int margin, const BakeSaveMode 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, @@ -528,11 +561,10 @@ static int bake( int tot_highpoly; char restrict_flag_low = ob_low->restrictflag; - char restrict_flag_cage; + char restrict_flag_cage = 0; Mesh *me_low = NULL; Mesh *me_cage = NULL; - Render *re; float *result = NULL; @@ -544,13 +576,10 @@ static int bake( BakeImages bake_images = {NULL}; - int num_pixels; + size_t num_pixels; int tot_materials; int i; - re = RE_NewRender(scene->id.name); - RE_SetReports(re, NULL); - RE_bake_engine_set_engine_parameters(re, bmain, scene); if (!RE_bake_has_engine(re)) { @@ -589,8 +618,8 @@ static int bake( } /* we overallocate in case there is more materials than images */ - bake_images.data = MEM_callocN(sizeof(BakeImage) * tot_materials, "bake images dimensions (width, height, offset)"); - bake_images.lookup = MEM_callocN(sizeof(int) * tot_materials, "bake images lookup (from material to BakeImage)"); + bake_images.data = MEM_mallocN(sizeof(BakeImage) * tot_materials, "bake images dimensions (width, height, offset)"); + bake_images.lookup = MEM_mallocN(sizeof(int) * tot_materials, "bake images lookup (from material to BakeImage)"); build_image_lookup(bmain, ob_low, &bake_images); @@ -604,7 +633,7 @@ static int bake( else { /* when saving extenally always use the size specified in the UI */ - num_pixels = width * height * bake_images.size; + num_pixels = (size_t)width * (size_t)height * bake_images.size; for (i = 0; i < bake_images.size; i++) { bake_images.data[i].width = width; @@ -647,12 +676,7 @@ static int bake( } } - /* blender_test_break uses this global */ - G.is_break = false; - - RE_test_break_cb(re, NULL, bake_break); - - pixel_array_low = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly"); + pixel_array_low = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly"); result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels"); /* get the mesh as it arrives in the renderer */ @@ -719,10 +743,8 @@ static int bake( /* initialize highpoly_data */ highpoly[i].ob = ob_iter; - highpoly[i].me = NULL; - highpoly[i].tri_mod = NULL; highpoly[i].restrict_flag = ob_iter->restrictflag; - highpoly[i].pixel_array = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly"); + highpoly[i].pixel_array = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly"); /* triangulating so BVH returns the primitive_id that will be used for rendering */ @@ -1038,6 +1060,8 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) bkr->result = OPERATOR_CANCELLED; + bkr->render = RE_NewRender(bkr->scene->id.name); + /* XXX hack to force saving to always be internal. Whether (and how) to support * external saving will be addressed later */ bkr->save_mode = R_BAKE_SAVE_INTERNAL; @@ -1045,10 +1069,15 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) static int bake_exec(bContext *C, wmOperator *op) { + Render *re; int result = OPERATOR_CANCELLED; BakeAPIRender bkr = {NULL}; bake_init_api_data(op, C, &bkr); + re = bkr.render; + + /* setup new render */ + RE_test_break_cb(re, NULL, bake_break); if (!bake_objects_check(bkr.main, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) return OPERATOR_CANCELLED; @@ -1058,9 +1087,11 @@ static int bake_exec(bContext *C, wmOperator *op) bake_images_clear(bkr.main, is_tangent); } + RE_SetReports(re, bkr.reports); + if (bkr.is_selected_to_active) { result = bake( - bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, + bkr.render, bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.pass_type, 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, @@ -1073,7 +1104,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.main, bkr.scene, ob_iter, NULL, bkr.reports, + bkr.render, bkr.main, bkr.scene, ob_iter, NULL, bkr.reports, bkr.pass_type, 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, @@ -1082,14 +1113,22 @@ static int bake_exec(bContext *C, wmOperator *op) } } + RE_SetReports(re, NULL); + BLI_freelistN(&bkr.selected_objects); return result; } -static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_update), float *UNUSED(progress)) +static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, float *progress) { BakeAPIRender *bkr = (BakeAPIRender *)bkv; + /* setup new render */ + bkr->do_update = do_update; + bkr->progress = progress; + + RE_SetReports(bkr->render, bkr->reports); + if (!bake_objects_check(bkr->main, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) { bkr->result = OPERATOR_CANCELLED; return; @@ -1102,7 +1141,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_updat if (bkr->is_selected_to_active) { bkr->result = bake( - bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, + bkr->render, bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->pass_type, 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, @@ -1115,7 +1154,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_updat for (link = bkr->selected_objects.first; link; link = link->next) { Object *ob_iter = link->ptr.data; bkr->result = bake( - bkr->main, bkr->scene, ob_iter, NULL, bkr->reports, + bkr->render, bkr->main, bkr->scene, ob_iter, NULL, bkr->reports, bkr->pass_type, 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, @@ -1126,6 +1165,8 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_updat return; } } + + RE_SetReports(bkr->render, NULL); } static void bake_freejob(void *bkv) @@ -1228,6 +1269,7 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) { wmJob *wm_job; BakeAPIRender *bkr; + Render *re; Scene *scene = CTX_data_scene(C); bake_set_props(op, scene); @@ -1236,10 +1278,15 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_OBJECT_BAKE)) return OPERATOR_CANCELLED; - bkr = MEM_callocN(sizeof(BakeAPIRender), "render bake"); + bkr = MEM_mallocN(sizeof(BakeAPIRender), "render bake"); /* init bake render */ bake_init_api_data(op, C, bkr); + re = bkr->render; + + /* setup new render */ + RE_test_break_cb(re, NULL, bake_break); + RE_progress_cb(re, bkr, bake_progress_update); /* setup job */ wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 85e4bbce8dc..92ed84b7f5e 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -485,7 +485,7 @@ static void test_constraints(Object *owner, bPoseChannel *pchan) } /* target checks for specific constraints */ - if (ELEM3(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK)) { + if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK)) { if (ct->tar) { if (ct->tar->type != OB_CURVE) { ct->tar = NULL; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index aba792413af..93956128b84 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -139,7 +139,9 @@ static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) /* 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) { - base->flag |= SELECT; + if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) { + base->flag |= SELECT; + } base->object->flag = base->flag; base->object->restrictflag &= ~OB_RESTRICT_VIEW; changed = true; @@ -361,6 +363,11 @@ static bool ED_object_editmode_load_ex(Object *obedit, const bool freedata) if (freedata) free_editMball(obedit); } + /* Tag update so no access to freed data referenced from + * derived cache will happen. + */ + DAG_id_tag_update((ID *)obedit->data, 0); + return true; } @@ -447,7 +454,7 @@ void ED_object_editmode_enter(bContext *C, int flag) base = scene->basact; } - if (ELEM3(NULL, base, base->object, base->object->data)) return; + if (ELEM(NULL, base, base->object, base->object->data)) return; ob = base->object; @@ -589,7 +596,7 @@ static int editmode_toggle_poll(bContext *C) if ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)) return 0; - return (ELEM7(ob->type, OB_MESH, OB_ARMATURE, OB_FONT, OB_MBALL, OB_LATTICE, OB_SURF, OB_CURVE)); + return OB_TYPE_SUPPORT_EDITMODE(ob->type); } void OBJECT_OT_editmode_toggle(wmOperatorType *ot) @@ -760,7 +767,7 @@ static void copy_texture_space(Object *to, Object *ob) texflag = ((Mesh *)ob->data)->texflag; poin2 = ((Mesh *)ob->data)->loc; } - else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { + else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { texflag = ((Curve *)ob->data)->texflag; poin2 = ((Curve *)ob->data)->loc; } @@ -775,7 +782,7 @@ static void copy_texture_space(Object *to, Object *ob) ((Mesh *)to->data)->texflag = texflag; poin1 = ((Mesh *)to->data)->loc; } - else if (ELEM3(to->type, OB_CURVE, OB_SURF, OB_FONT)) { + else if (ELEM(to->type, OB_CURVE, OB_SURF, OB_FONT)) { ((Curve *)to->data)->texflag = texflag; poin1 = ((Curve *)to->data)->loc; } @@ -1112,7 +1119,7 @@ void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object) /* add/remove modifier as needed */ if (!md) { if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) && ELEM(pd->forcefield, PFIELD_GUIDE, PFIELD_TEXTURE) == 0) - if (ELEM4(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) + if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) ED_object_modifier_add(NULL, bmain, scene, object, NULL, eModifierType_Surface); } else { @@ -1453,7 +1460,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d) BKE_mesh_texspace_get(ob->data, NULL, NULL, size); space = size[0] / size[1]; } - else if (ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF)) { + else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) { float size[3]; BKE_curve_texspace_get(ob->data, NULL, NULL, size); space = size[0] / size[1]; @@ -1500,7 +1507,7 @@ static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *UNUSED( if ((input->value == OB_MODE_EDIT && OB_TYPE_SUPPORT_EDITMODE(ob->type)) || (input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) || (input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) || - (ELEM4(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, + (ELEM(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || (input->value == OB_MODE_OBJECT)) { diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 47b5f1605e7..20e2e22cdf8 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -563,3 +563,67 @@ void OBJECT_OT_group_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +static int group_unlink_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Group *group = CTX_data_pointer_get_type(C, "group", &RNA_Group).data; + + if (!group) + return OPERATOR_CANCELLED; + + BKE_group_unlink(group); + + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_group_unlink(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Unlink Group"; + ot->idname = "OBJECT_OT_group_unlink"; + ot->description = "Unlink the group from all objects"; + + /* api callbacks */ + ot->exec = group_unlink_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op)) /* Select objects in the same group as the active */ +{ + Group *group = CTX_data_pointer_get_type(C, "group", &RNA_Group).data; + + if (!group) + return OPERATOR_CANCELLED; + + 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); + } + } + CTX_DATA_END; + + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_grouped_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Grouped"; + ot->idname = "OBJECT_OT_grouped_select"; + ot->description = "Select all objects in group"; + + /* api callbacks */ + ot->exec = select_grouped_exec; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index afff367b939..9f9a647c9f1 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -528,8 +528,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob invert_m4_m4(ob->imat, ob->obmat); /* apparently this call goes from right to left... */ - mul_serie_m4(hmd->parentinv, pose_mat, ob->imat, obedit->obmat, - NULL, NULL, NULL, NULL, NULL); + mul_m4_series(hmd->parentinv, pose_mat, ob->imat, obedit->obmat); DAG_relations_tag_update(bmain); diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index fd6b9a1bad0..6fa3caa6172 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -72,6 +72,7 @@ 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); /* object_edit.c */ void OBJECT_OT_mode_set(struct wmOperatorType *ot); @@ -251,6 +252,8 @@ void OBJECT_OT_shape_key_move(struct wmOperatorType *ot); void OBJECT_OT_group_add(struct wmOperatorType *ot); void OBJECT_OT_group_link(struct wmOperatorType *ot); void OBJECT_OT_group_remove(struct wmOperatorType *ot); +void OBJECT_OT_group_unlink(struct wmOperatorType *ot); +void OBJECT_OT_grouped_select(struct wmOperatorType *ot); /* object_bake.c */ void OBJECT_OT_bake_image(wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 3897e452d0d..c24a127ed8b 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -174,21 +174,6 @@ void load_editLatt(Object *obedit) } } -/*************************** Transform Operator ************************/ - -void ED_lattice_transform(Lattice *lt, float mat[4][4]) -{ - BPoint *bp = lt->def; - int a = lt->pntsu * lt->pntsv * lt->pntsw; - - while (a--) { - mul_m4_v3(mat, bp->vec); - bp++; - } - - DAG_id_tag_update(<->id, 0); -} - static void bpoint_select_set(BPoint *bp, bool select) { if (select) { diff --git a/source/blender/editors/object/object_lod.c b/source/blender/editors/object/object_lod.c index 8bcbba6be96..48e980015a7 100644 --- a/source/blender/editors/object/object_lod.c +++ b/source/blender/editors/object/object_lod.c @@ -29,15 +29,11 @@ * \ingroup edobj */ - #include "DNA_object_types.h" #include "BKE_context.h" #include "BKE_object.h" -#include "ED_screen.h" -#include "ED_object.h" - #include "WM_api.h" #include "WM_types.h" @@ -45,6 +41,9 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "ED_screen.h" +#include "ED_object.h" + #include "object_intern.h" static int object_lod_add_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 1249beb4517..b05840b5823 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -98,7 +98,7 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc ModifierTypeInfo *mti = modifierType_getInfo(type); /* only geometry objects should be able to get modifiers [#25291] */ - if (!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { + if (!ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2); return NULL; } @@ -1876,7 +1876,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) else if (ob->type == OB_MBALL) { BKE_displist_make_mball(CTX_data_main(C)->eval_ctx, scene, ob); } - else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { + else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { BKE_displist_make_curveTypes(scene, ob, 0); } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index a8f07747d3a..7cf661de52c 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -229,6 +229,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_group_add); WM_operatortype_append(OBJECT_OT_group_link); WM_operatortype_append(OBJECT_OT_group_remove); + WM_operatortype_append(OBJECT_OT_group_unlink); + WM_operatortype_append(OBJECT_OT_grouped_select); WM_operatortype_append(OBJECT_OT_hook_add_selob); WM_operatortype_append(OBJECT_OT_hook_add_newob); @@ -241,6 +243,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_bake_image); WM_operatortype_append(OBJECT_OT_bake); WM_operatortype_append(OBJECT_OT_drop_named_material); + WM_operatortype_append(OBJECT_OT_unlink_data); WM_operatortype_append(OBJECT_OT_laplaciandeform_bind); WM_operatortype_append(OBJECT_OT_lod_add); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 3059d84a085..0d58eaee5fa 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -444,7 +444,7 @@ EnumPropertyItem prop_clear_parent_types[] = { /* Helper for ED_object_parent_clear() - Remove deform-modifiers associated with parent */ static void object_remove_parent_deform_modifiers(Object *ob, const Object *par) { - if (ELEM3(par->type, OB_ARMATURE, OB_LATTICE, OB_CURVE)) { + if (ELEM(par->type, OB_ARMATURE, OB_LATTICE, OB_CURVE)) { ModifierData *md, *mdn; /* assume that we only need to remove the first instance of matching deform modifier here */ @@ -593,7 +593,7 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object int partype, bool xmirror, bool keep_transform, const int vert_par[3]) { bPoseChannel *pchan = NULL; - int pararm = ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); + int pararm = ELEM(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); DAG_id_tag_update(&par->id, OB_RECALC_OB); @@ -678,7 +678,7 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object * assuming that the parent is selected too... */ // XXX currently this should only happen for meshes, curves, surfaces, and lattices - this stuff isn't available for metas yet - if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { + if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { ModifierData *md; switch (partype) { @@ -1128,7 +1128,7 @@ static int object_track_clear_exec(bContext *C, wmOperator *op) /* also remove all tracking constraints */ for (con = ob->constraints.last; con; con = pcon) { pcon = con->prev; - if (ELEM3(con->type, CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_DAMPTRACK)) + if (ELEM(con->type, CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_DAMPTRACK)) BKE_constraint_remove(&ob->constraints, con); } @@ -1192,7 +1192,7 @@ static int track_set_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* Lamp, Camera and Speaker track differently by default */ - if (ELEM3(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { + if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { data->trackflag = TRACK_nZ; } } @@ -1213,7 +1213,7 @@ static int track_set_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* Lamp, Camera and Speaker track differently by default */ - if (ELEM3(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { + if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { data->reserved1 = TRACK_nZ; data->reserved2 = UP_Y; } @@ -1235,7 +1235,7 @@ static int track_set_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* Lamp, Camera and Speaker track differently by default */ - if (ELEM3(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { + if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { data->trackflag = TRACK_nZ; data->lockflag = LOCK_Y; } @@ -2143,9 +2143,40 @@ static void tag_localizable_objects(bContext *C, int mode) /* TODO(sergey): Drivers targets? */ } +/** + * 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) +{ + Object *ob; + bool changed = false; + + for (ob = bmain->object.first; ob; ob = ob->id.next) { + if (ob->id.lib && (ob->id.us == 0)) { + Base *base; + + ob->id.us = 1; + + /* not essential, but for correctness */ + id_lib_extern(&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); + + changed = true; + } + } + + return changed; +} + static int make_local_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); AnimData *adt; ParticleSystem *psys; Material *ma, ***matarar; @@ -2154,6 +2185,14 @@ static int make_local_exec(bContext *C, wmOperator *op) int a, b, mode = RNA_enum_get(op->ptr, "type"); if (mode == MAKE_LOCAL_ALL) { + /* de-select so the user can differentiate newly instanced from existing objects */ + BKE_scene_base_deselect_all(scene); + + if (make_local_all__instance_indirect_unused(bmain, scene)) { + BKE_report(op->reports, RPT_INFO, + "Orphan library objects added to the current scene to avoid loss"); + } + BKE_library_make_local(bmain, NULL, false); /* NULL is all libs */ WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; @@ -2399,3 +2438,55 @@ void OBJECT_OT_drop_named_material(wmOperatorType *ot) /* properties */ RNA_def_string(ot->srna, "name", "Material", MAX_ID_NAME - 2, "Name", "Material name to assign"); } + +static int object_unlink_data_exec(bContext *C, wmOperator *op) +{ + ID *id; + PropertyPointerRNA pprop; + + uiIDContextProperty(C, &pprop.ptr, &pprop.prop); + + if (pprop.prop == NULL) { + BKE_report(op->reports, RPT_ERROR, "Incorrect context for running object data unlink"); + return OPERATOR_CANCELLED; + } + + id = pprop.ptr.id.data; + + if (GS(id->name) == ID_OB) { + Object *ob = (Object *)id; + if (ob->data) { + ID *id_data = ob->data; + + if (GS(id_data->name) == ID_IM) { + id_us_min(id_data); + ob->data = NULL; + } + else { + BKE_report(op->reports, RPT_ERROR, "Can't unlink this object data"); + return OPERATOR_CANCELLED; + } + } + } + + RNA_property_update(C, &pprop.ptr, pprop.prop); + + return OPERATOR_FINISHED; +} + +/** + * \note Only for empty-image objects, this operator is needed + */ +void OBJECT_OT_unlink_data(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Unlink"; + ot->idname = "OBJECT_OT_unlink_data"; + ot->description = ""; + + /* api callbacks */ + ot->exec = object_unlink_data_exec; + + /* flags */ + ot->flag = OPTYPE_INTERNAL; +} diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 9b1aa054f84..e295a63848a 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -753,11 +753,11 @@ static bool select_grouped_color(bContext *C, Object *ob) static bool objects_share_gameprop(Object *a, Object *b) { bProperty *prop; - /*make a copy of all its properties*/ for (prop = a->prop.first; prop; prop = prop->next) { - if (BKE_bproperty_object_get(b, prop->name) ) + if (BKE_bproperty_object_get(b, prop->name)) { return 1; + } } return 0; } diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index cfd1c4d3b0a..85104c14395 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -485,27 +485,22 @@ void OBJECT_OT_shape_key_mirror(wmOperatorType *ot) static int shape_key_move_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); - - int type = RNA_enum_get(op->ptr, "type"); Key *key = BKE_key_from_object(ob); - if (key) { - KeyBlock *kb, *kb_other; - int shapenr_act = ob->shapenr - 1; - int shapenr_swap = shapenr_act + type; - kb = BLI_findlink(&key->block, shapenr_act); + if (!key) { + return OPERATOR_CANCELLED; + } - if ((type == -1 && kb->prev == NULL) || (type == 1 && kb->next == NULL)) { - return OPERATOR_CANCELLED; - } + { + KeyBlock *kb, *kb_other, *kb_iter; + const int type = RNA_enum_get(op->ptr, "type"); + const int shape_tot = key->totkey; + const int shapenr_act = ob->shapenr - 1; + const int shapenr_swap = (shape_tot + shapenr_act + type) % shape_tot; - for (kb_other = key->block.first; kb_other; kb_other = kb_other->next) { - if (kb_other->relative == shapenr_act) { - kb_other->relative += type; - } - else if (kb_other->relative == shapenr_swap) { - kb_other->relative -= type; - } + kb = BLI_findlink(&key->block, shapenr_act); + if (!kb || shape_tot == 1) { + return OPERATOR_CANCELLED; } if (type == -1) { @@ -513,17 +508,57 @@ static int shape_key_move_exec(bContext *C, wmOperator *op) kb_other = kb->prev; BLI_remlink(&key->block, kb); BLI_insertlinkbefore(&key->block, kb_other, kb); - ob->shapenr--; } else { /* move next */ kb_other = kb->next; BLI_remlink(&key->block, kb); BLI_insertlinkafter(&key->block, kb_other, kb); - ob->shapenr++; } - SWAP(float, kb_other->pos, kb->pos); /* for absolute shape keys */ + ob->shapenr = shapenr_swap + 1; + + /* for relative shape keys */ + if (kb_other) { + for (kb_iter = key->block.first; kb_iter; kb_iter = kb_iter->next) { + if (kb_iter->relative == shapenr_act) { + kb_iter->relative = shapenr_swap; + } + else if (kb_iter->relative == shapenr_swap) { + kb_iter->relative = shapenr_act; + } + } + } + /* First key became last, or vice-versa, we have to change all keys' relative value. */ + else { + for (kb_iter = key->block.first; kb_iter; kb_iter = kb_iter->next) { + if (kb_iter->relative == shapenr_act) { + kb_iter->relative = shapenr_swap; + } + else { + kb_iter->relative += type; + } + } + } + + /* for absolute shape keys */ + if (kb_other) { + SWAP(float, kb_other->pos, kb->pos); + } + /* First key became last, or vice-versa, we have to change all keys' pos value. */ + else { + float pos = kb->pos; + if (type == -1) { + for (kb_iter = key->block.first; kb_iter; kb_iter = kb_iter->next) { + SWAP(float, kb_iter->pos, pos); + } + } + else { + for (kb_iter = key->block.last; kb_iter; kb_iter = kb_iter->prev) { + SWAP(float, kb_iter->pos, pos); + } + } + } /* First key is refkey, matches interface and BKE_key_sort */ key->refkey = key->block.first; diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 6e59f9f4aea..a1b8478a0e1 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -385,7 +385,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l /* first check if we can execute */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { - if (ELEM6(ob->type, OB_MESH, OB_ARMATURE, OB_LATTICE, OB_MBALL, OB_CURVE, OB_SURF)) { + if (ELEM(ob->type, OB_MESH, OB_ARMATURE, OB_LATTICE, OB_MBALL, OB_CURVE, OB_SURF)) { ID *obdata = ob->data; if (ID_REAL_USERS(obdata) > 1) { BKE_reportf(reports, RPT_ERROR, @@ -472,27 +472,12 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l /* apply to object data */ if (ob->type == OB_MESH) { Mesh *me = ob->data; - MVert *mvert; - int a; if (apply_scale) multiresModifier_scale_disp(scene, ob); /* adjust data */ - mvert = me->mvert; - for (a = 0; a < me->totvert; a++, mvert++) - mul_m4_v3(mat, mvert->co); - - if (me->key) { - KeyBlock *kb; - - for (kb = me->key->block.first; kb; kb = kb->next) { - float *fp = kb->data; - - for (a = 0; a < kb->totelem; a++, fp += 3) - mul_m4_v3(mat, fp); - } - } + BKE_mesh_transform(me, mat, true); /* update normals */ BKE_mesh_calc_normals(me); @@ -502,45 +487,17 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l } else if (ob->type == OB_LATTICE) { Lattice *lt = ob->data; - BPoint *bp = lt->def; - int a = lt->pntsu * lt->pntsv * lt->pntsw; - - while (a--) { - mul_m4_v3(mat, bp->vec); - bp++; - } + + BKE_lattice_transform(lt, mat, true); } else if (ob->type == OB_MBALL) { MetaBall *mb = ob->data; - ED_mball_transform(mb, mat); + BKE_mball_transform(mb, mat); } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu = ob->data; - - Nurb *nu; - BPoint *bp; - BezTriple *bezt; - int a; - scale = mat3_to_scale(rsmat); - - for (nu = cu->nurb.first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - a = nu->pntsu; - for (bezt = nu->bezt; a--; bezt++) { - mul_m4_v3(mat, bezt->vec[0]); - mul_m4_v3(mat, bezt->vec[1]); - mul_m4_v3(mat, bezt->vec[2]); - bezt->radius *= scale; - } - BKE_nurb_handles_calc(nu); - } - else { - a = nu->pntsu * nu->pntsv; - for (bp = nu->bp; a--; bp++) - mul_m4_v3(mat, bp->vec); - } - } + BKE_curve_transform_ex(cu, mat, true, scale); } else if (ob->type == OB_CAMERA) { MovieClip *clip = BKE_object_movieclip_get(scene, ob, false); @@ -784,7 +741,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } if (ctx_ob_act) { - BLI_rotatelist_first(&ctx_data_list, (LinkData *)ctx_ob_act); + BLI_listbase_rotate_first(&ctx_data_list, (LinkData *)ctx_ob_act); } for (tob = bmain->object.first; tob; tob = tob->id.next) { diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index ccc3e2e8278..6897861c81c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -62,6 +62,7 @@ #include "BKE_depsgraph.h" #include "BKE_mesh_mapping.h" #include "BKE_editmesh.h" +#include "BKE_modifier.h" #include "BKE_report.h" #include "BKE_DerivedMesh.h" #include "BKE_object_deform.h" @@ -2301,7 +2302,6 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i if (dvert_array) MEM_freeN(dvert_array); - BLI_SMALLSTACK_FREE(dv_stack); /* not so efficient to get 'dvert_array' again just so unselected verts are NULL'd */ if (use_mirror) { @@ -4324,7 +4324,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op) return OPERATOR_FINISHED; } -static int vgroup_sort(void *def_a_ptr, void *def_b_ptr) +static int vgroup_sort_name(void *def_a_ptr, void *def_b_ptr) { bDeformGroup *def_a = (bDeformGroup *)def_a_ptr; bDeformGroup *def_b = (bDeformGroup *)def_b_ptr; @@ -4332,18 +4332,59 @@ static int vgroup_sort(void *def_a_ptr, void *def_b_ptr) return BLI_natstrcmp(def_a->name, def_b->name); } +/* Sorts the weight groups according to the bone hierarchy of the + associated armature (similar to how bones are ordered in the Outliner) */ +static void vgroup_sort_bone_hierarchy(Object *ob, ListBase *bonebase) +{ + if (bonebase == NULL) { + Object *armobj = modifiers_isDeformedByArmature(ob); + if (armobj != NULL) { + bArmature *armature = armobj->data; + bonebase = &armature->bonebase; + } + } + + if (bonebase != NULL) { + Bone *bone; + for (bone = bonebase->last; bone; bone = bone->prev) { + bDeformGroup *dg = defgroup_find_name(ob, bone->name); + vgroup_sort_bone_hierarchy(ob, &bone->childbase); + + if (dg != NULL) { + BLI_remlink(&ob->defbase, dg); + BLI_addhead(&ob->defbase, dg); + } + } + } + + return; +} + +enum { + SORT_TYPE_NAME = 0, + SORT_TYPE_BONEHIERARCHY = 1 +}; + static int vertex_group_sort_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); char *name_array; int ret; + int sort_type = RNA_enum_get(op->ptr, "sort_type"); /*init remapping*/ name_array = vgroup_init_remap(ob); /*sort vgroup names*/ - BLI_sortlist(&ob->defbase, vgroup_sort); - + switch (sort_type) { + case SORT_TYPE_NAME: + BLI_sortlist(&ob->defbase, vgroup_sort_name); + break; + case SORT_TYPE_BONEHIERARCHY: + vgroup_sort_bone_hierarchy(ob, NULL); + break; + } + /*remap vgroup data to map to correct names*/ ret = vgroup_do_remap(ob, name_array, op); @@ -4359,9 +4400,15 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op) void OBJECT_OT_vertex_group_sort(wmOperatorType *ot) { + static EnumPropertyItem vgroup_sort_type[] = { + {SORT_TYPE_NAME, "NAME", 0, "Name", ""}, + {SORT_TYPE_BONEHIERARCHY, "BONE_HIERARCHY", 0, "Bone Hierarchy", ""}, + {0, NULL, 0, NULL, NULL} + }; + ot->name = "Sort Vertex Groups"; ot->idname = "OBJECT_OT_vertex_group_sort"; - ot->description = "Sort vertex groups alphabetically"; + ot->description = "Sort vertex groups"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -4369,6 +4416,8 @@ void OBJECT_OT_vertex_group_sort(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "sort_type", vgroup_sort_type, SORT_TYPE_NAME, "Sort type", "Sort type"); } static int vgroup_move_exec(bContext *C, wmOperator *op) |