Page MenuHome

Join operator with override crashes Blender 2.79
Closed, ResolvedPublic

Description

System Information
Linux Mint 18.2, GTX 660 Ti

Blender Version
Broken: 2.79.5bd8ac9abfa
Worked: 2.78c.e92f2352830

Short description of error
When setting active object trough context override on "bpy.ops.object.join" operator, blender crashes.

Exact steps for others to reproduce the error

  1. Open attached blend file:
  2. Press execute the script (Alt+P in text editor)
  3. Crash!

Event Timeline

Simon (notallowed) updated the task description. (Show Details)
Sergey Sharybin (sergey) triaged this task as Confirmed, Medium priority.

@Bastien Montagne (mont29), comes from rB9f67367. I'm not sure why we need a base for join, all the logic uses base->object anyway. Here is a proposed fix:

1diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
2index ba57cda6916..c900373a59c 100644
3--- a/source/blender/editors/mesh/meshtools.c
4+++ b/source/blender/editors/mesh/meshtools.c
5@@ -78,7 +78,7 @@
6
7 static void join_mesh_single(
8 Main *bmain, Scene *scene,
9- Object *ob_dst, Base *base_src, float imat[4][4],
10+ Object *ob_dst, Object *ob_src, float imat[4][4],
11 MVert **mvert_pp, MEdge **medge_pp, MLoop **mloop_pp, MPoly **mpoly_pp,
12 CustomData *vdata, CustomData *edata, CustomData *ldata, CustomData *pdata,
13 int totvert, int totedge, int totloop, int totpoly,
14@@ -88,7 +88,7 @@ static void join_mesh_single(
15 {
16 int a, b;
17
18- Mesh *me = base_src->object->data;
19+ Mesh *me = ob_src->data;
20 MVert *mvert = *mvert_pp;
21 MEdge *medge = *medge_pp;
22 MLoop *mloop = *mloop_pp;
23@@ -112,10 +112,10 @@ static void join_mesh_single(
24
25 /* Build src to merged mapping of vgroup indices. */
26 bDeformGroup *dg_src;
27- int *vgroup_index_map = alloca(sizeof(*vgroup_index_map) * BLI_listbase_count(&base_src->object->defbase));
28+ int *vgroup_index_map = alloca(sizeof(*vgroup_index_map) * BLI_listbase_count(&ob_src->defbase));
29 bool is_vgroup_remap_needed = false;
30
31- for (dg_src = base_src->object->defbase.first, b = 0; dg_src; dg_src = dg_src->next, b++) {
32+ for (dg_src = ob_src->defbase.first, b = 0; dg_src; dg_src = dg_src->next, b++) {
33 vgroup_index_map[b] = defgroup_name_index(ob_dst, dg_src->name);
34 is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[b] != b);
35 }
36@@ -130,11 +130,11 @@ static void join_mesh_single(
37 }
38
39 /* if this is the object we're merging into, no need to do anything */
40- if (base_src->object != ob_dst) {
41+ if (ob_src != ob_dst) {
42 float cmat[4][4];
43
44 /* watch this: switch matmul order really goes wrong */
45- mul_m4_m4m4(cmat, imat, base_src->object->obmat);
46+ mul_m4_m4m4(cmat, imat, ob_src->obmat);
47
48 /* transform vertex coordinates into new space */
49 for (a = 0, mvert = *mvert_pp; a < me->totvert; a++, mvert++) {
50@@ -211,13 +211,13 @@ static void join_mesh_single(
51 }
52
53 if (me->totloop) {
54- if (base_src->object != ob_dst) {
55+ if (ob_src != ob_dst) {
56 MultiresModifierData *mmd;
57
58- multiresModifier_prepare_join(scene, base_src->object, ob_dst);
59+ multiresModifier_prepare_join(scene, ob_src, ob_dst);
60
61- if ((mmd = get_multires_modifier(scene, base_src->object, true))) {
62- ED_object_iter_other(bmain, base_src->object, true,
63+ if ((mmd = get_multires_modifier(scene, ob_src, true))) {
64+ ED_object_iter_other(bmain, ob_src, true,
65 ED_object_multires_update_totlevels_cb,
66 &mmd->totlvl);
67 }
68@@ -235,8 +235,8 @@ static void join_mesh_single(
69 if (me->totpoly) {
70 if (matmap) {
71 /* make mapping for materials */
72- for (a = 1; a <= base_src->object->totcol; a++) {
73- Material *ma = give_current_material(base_src->object, a);
74+ for (a = 1; a <= ob_src->totcol; a++) {
75+ Material *ma = give_current_material(ob_src, a);
76
77 for (b = 0; b < totcol; b++) {
78 if (ma == matar[b]) {
79@@ -271,8 +271,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
80 {
81 Main *bmain = CTX_data_main(C);
82 Scene *scene = CTX_data_scene(C);
83- Base *ob_base = CTX_data_active_base(C);
84- Object *ob = ob_base->object;
85+ Object *ob = CTX_data_active_object(C);
86 Material **matar = NULL, *ma;
87 Mesh *me;
88 MVert *mvert = NULL;
89@@ -495,7 +494,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
90 */
91 join_mesh_single(
92 bmain, scene,
93- ob, ob_base, imat,
94+ ob, ob, imat,
95 &mvert, &medge, &mloop, &mpoly,
96 &vdata, &edata, &ldata, &pdata,
97 totvert, totedge, totloop, totpoly,
98@@ -512,7 +511,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
99 if (base->object->type == OB_MESH) {
100 join_mesh_single(
101 bmain, scene,
102- ob, base, imat,
103+ ob, base->object, imat,
104 &mvert, &medge, &mloop, &mpoly,
105 &vdata, &edata, &ldata, &pdata,
106 totvert, totedge, totloop, totpoly,

@Sergey Sharybin (sergey) indeed, cannot see any reason to pass base if we only use object, your fix lgtm.