Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r--source/blender/editors/object/object_add.c61
-rw-r--r--source/blender/editors/object/object_bake.c2
-rw-r--r--source/blender/editors/object/object_bake_api.c211
-rw-r--r--source/blender/editors/object/object_constraint.c2
-rw-r--r--source/blender/editors/object/object_edit.c23
-rw-r--r--source/blender/editors/object/object_group.c64
-rw-r--r--source/blender/editors/object/object_hook.c3
-rw-r--r--source/blender/editors/object/object_intern.h3
-rw-r--r--source/blender/editors/object/object_lattice.c15
-rw-r--r--source/blender/editors/object/object_lod.c7
-rw-r--r--source/blender/editors/object/object_modifier.c4
-rw-r--r--source/blender/editors/object/object_ops.c3
-rw-r--r--source/blender/editors/object/object_relations.c105
-rw-r--r--source/blender/editors/object/object_select.c4
-rw-r--r--source/blender/editors/object/object_shapekey.c75
-rw-r--r--source/blender/editors/object/object_transform.c57
-rw-r--r--source/blender/editors/object/object_vgroup.c59
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(&lt->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)