diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2016-09-30 02:18:41 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2016-09-30 02:18:41 +0300 |
commit | 42ed1f0e3cbd9d477b7a535b52030c7905ca5362 (patch) | |
tree | 2dec6287c35367d6771b38327642db8a7f8f3c49 /source | |
parent | 47bba7e15f4b7a105655b81affea9f2d48a3a767 (diff) | |
parent | 344a669c412a5eb5b71555a18aa85ef7a16b253f (diff) |
Merge branch 'master' into blender2.8
Conflicts:
source/blender/blenloader/intern/writefile.c
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/dynamicpaint.c | 103 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sca.c | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/polyfill2d_beautify.c | 5 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_connect_pair.c | 16 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_eval.cc | 11 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_channels_defines.c | 11 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 13 | ||||
-rw-r--r-- | source/blender/editors/armature/pose_lib.c | 5 | ||||
-rw-r--r-- | source/blender/editors/include/ED_keyframing.h | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_view.c | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_modifier.c | 38 |
11 files changed, 153 insertions, 59 deletions
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 419a1cd854b..587e4a35806 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -100,6 +100,10 @@ static const float gaussianTotal = 3.309425f; static int neighX[8] = {1, 1, 0, -1, -1, -1, 0, 1}; static int neighY[8] = {0, 1, 1, 1, 0, -1, -1, -1}; +/* Neighbor x/y list that prioritizes grid directions over diagonals */ +static int neighStraightX[8] = {1, 0, -1, 0, 1, -1, -1, 1}; +static int neighStraightY[8] = {0, 1, 0, -1, 1, 1, -1, -1}; + /* subframe_updateObject() flags */ #define SUBFRAME_RECURSION 5 /* surface_getBrushFlags() return vals */ @@ -2187,9 +2191,12 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(void *userdata, const in point[0] = ((float)tx + 0.5f) / w; point[1] = ((float)ty + 0.5f) / h; - /* search through defined area for neighbor */ - for (int u = u_min; u <= u_max; u++) { - for (int v = v_min; v <= v_max; v++) { + /* search through defined area for neighbor, checking grid directions first */ + for (int ni = 0; ni < 8; ni++) { + int u = neighStraightX[ni]; + int v = neighStraightY[ni]; + + if (u >= u_min && u <= u_max && v >= v_min && v <= v_max) { /* if not this pixel itself */ if (u != 0 || v != 0) { const int ind = (tx + u) + w * (ty + v); @@ -2227,7 +2234,6 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(void *userdata, const in tPoint->v2 = mloop[mlooptri[i].tri[1]].v; tPoint->v3 = mloop[mlooptri[i].tri[2]].v; - u = u_max + 1; /* make sure we exit outer loop as well */ break; } } @@ -2399,7 +2405,22 @@ static int dynamic_paint_find_neighbour_pixel( ((s_uv2[0] == t_uv1[0] && s_uv2[1] == t_uv1[1]) && (s_uv1[0] == t_uv2[0] && s_uv1[1] == t_uv2[1]))) { - return ((px + neighX[n_index]) + w * (py + neighY[n_index])); + final_index = x + w * y; + + /* If not an active pixel, bail out */ + if (tempPoints[final_index].tri_index == -1) + return NOT_FOUND; + + /* If final point is an "edge pixel", use it's "real" neighbor instead */ + if (tempPoints[final_index].neighbour_pixel != -1) { + final_index = tempPoints[final_index].neighbour_pixel; + + /* If we ended up to our origin point */ + if (final_index == (px + w * py)) + return NOT_FOUND; + } + + return final_index; } /* @@ -2421,8 +2442,8 @@ static int dynamic_paint_find_neighbour_pixel( copy_v2_v2(pixel, mloopuv[mlooptri[target_tri].tri[target_uv1]].uv); add_v2_v2(pixel, dir_vec); - pixel[0] = (pixel[0] * (float)w) - 0.5f; - pixel[1] = (pixel[1] * (float)h) - 0.5f; + pixel[0] = (pixel[0] * (float)w); + pixel[1] = (pixel[1] * (float)h); final_pixel[0] = (int)floorf(pixel[0]); final_pixel[1] = (int)floorf(pixel[1]); @@ -2441,8 +2462,13 @@ static int dynamic_paint_find_neighbour_pixel( return NOT_FOUND; /* If final point is an "edge pixel", use it's "real" neighbor instead */ - if (tempPoints[final_index].neighbour_pixel != -1) - final_index = cPoint->neighbour_pixel; + if (tempPoints[final_index].neighbour_pixel != -1) { + final_index = tempPoints[final_index].neighbour_pixel; + + /* If we ended up to our origin point */ + if (final_index == (px + w * py)) + return NOT_FOUND; + } return final_index; } @@ -2601,6 +2627,7 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface, flo const int index = tx + w * ty; if (tempPoints[index].tri_index != -1) { + int start_pos = n_pos; ed->n_index[final_index[index]] = n_pos; ed->n_num[final_index[index]] = 0; @@ -2609,10 +2636,20 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface, flo const int n_target = dynamic_paint_find_neighbour_pixel( &data, vert_to_looptri_map, w, h, tx, ty, i); - if (n_target >= 0) { - ed->n_target[n_pos] = final_index[n_target]; - ed->n_num[final_index[index]]++; - n_pos++; + if (n_target >= 0 && n_target != index) { + bool duplicate = false; + for (int j = start_pos; j < n_pos; j++) { + if (ed->n_target[j] == final_index[n_target]) { + duplicate = true; + break; + } + } + + if (!duplicate) { + ed->n_target[n_pos] = final_index[n_target]; + ed->n_num[final_index[index]]++; + n_pos++; + } } else if (n_target == ON_MESH_EDGE || n_target == OUT_OF_TEXTURE) { ed->flags[final_index[index]] |= ADJ_ON_MESH_EDGE; @@ -4455,6 +4492,8 @@ static void dynamic_paint_effect_drip_cb(void *userdata, const int index) return; CLAMP(w_factor, 0.0f, 1.0f); + float ppoint_wetness_diff = 0.0f; + /* get force affect points */ surface_determineForceTargetPoints(sData, index, &force[index * 4], closest_d, closest_id); @@ -4476,9 +4515,9 @@ static void dynamic_paint_effect_drip_cb(void *userdata, const int index) /* Sort of spinlock, but only for given ePoint. * Since the odds a same ePoint is modified at the same time by several threads is very low, this is * much more efficient than a global spin lock. */ - const unsigned int pointlock_idx = n_trgt / 8; - const uint8_t pointlock_bitmask = 1 << (n_trgt & 7); /* 7 == 0b111 */ - while (atomic_fetch_and_or_uint8(&point_locks[pointlock_idx], pointlock_bitmask) & pointlock_bitmask); + const unsigned int epointlock_idx = n_trgt / 8; + const uint8_t epointlock_bitmask = 1 << (n_trgt & 7); /* 7 == 0b111 */ + while (atomic_fetch_and_or_uint8(&point_locks[epointlock_idx], epointlock_bitmask) & epointlock_bitmask); PaintPoint *ePoint = &((PaintPoint *)sData->type_data)[n_trgt]; const float e_wet = ePoint->wetness; @@ -4499,18 +4538,38 @@ static void dynamic_paint_effect_drip_cb(void *userdata, const int index) CLAMP_MAX(ePoint->e_color[3], pPoint_prev->e_color[3]); } - /* decrease paint wetness on current point */ - pPoint->wetness -= (ePoint->wetness - e_wet); - CLAMP(pPoint->wetness, 0.0f, MAX_WETNESS); + /* Decrease paint wetness on current point + * (just store diff here, that way we can only lock current point once at the end to apply it). */ + ppoint_wetness_diff += (ePoint->wetness - e_wet); #ifndef NDEBUG - uint8_t ret = atomic_fetch_and_and_uint8(&point_locks[pointlock_idx], ~pointlock_bitmask); - BLI_assert(ret & pointlock_bitmask); + { + uint8_t ret = atomic_fetch_and_and_uint8(&point_locks[epointlock_idx], ~epointlock_bitmask); + BLI_assert(ret & epointlock_bitmask); + } #else - atomic_fetch_and_and_uint8(&point_locks[pointlock_idx], ~pointlock_bitmask); + atomic_fetch_and_and_uint8(&point_locks[epointlock_idx], ~epointlock_bitmask); #endif } } + + { + const unsigned int ppointlock_idx = index / 8; + const uint8_t ppointlock_bitmask = 1 << (index & 7); /* 7 == 0b111 */ + while (atomic_fetch_and_or_uint8(&point_locks[ppointlock_idx], ppointlock_bitmask) & ppointlock_bitmask); + + pPoint->wetness -= ppoint_wetness_diff; + CLAMP(pPoint->wetness, 0.0f, MAX_WETNESS); + +#ifndef NDEBUG + { + uint8_t ret = atomic_fetch_and_and_uint8(&point_locks[ppointlock_idx], ~ppointlock_bitmask); + BLI_assert(ret & ppointlock_bitmask); + } +#else + atomic_fetch_and_and_uint8(&point_locks[ppointlock_idx], ~ppointlock_bitmask); +#endif + } } static void dynamicPaint_doEffectStep( diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 61aa8c7589f..c7f406089d9 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -789,7 +789,7 @@ void BKE_sca_logic_copy(Object *ob_new, Object *ob) copy_controllers(&ob_new->controllers, &ob->controllers); copy_actuators(&ob_new->actuators, &ob->actuators); - for (bSensor *sens = ob->sensors.first; sens; sens = sens->next) { + for (bSensor *sens = ob_new->sensors.first; sens; sens = sens->next) { if (sens->flag & SENS_NEW) { for (int a = 0; a < sens->totlinks; a++) { if (sens->links[a] && sens->links[a]->mynew) { @@ -799,7 +799,7 @@ void BKE_sca_logic_copy(Object *ob_new, Object *ob) } } - for (bController *cont = ob->controllers.first; cont; cont = cont->next) { + for (bController *cont = ob_new->controllers.first; cont; cont = cont->next) { if (cont->flag & CONT_NEW) { for (int a = 0; a < cont->totlinks; a++) { if (cont->links[a] && cont->links[a]->mynew) { diff --git a/source/blender/blenlib/intern/polyfill2d_beautify.c b/source/blender/blenlib/intern/polyfill2d_beautify.c index 46f9251bea7..896177f436c 100644 --- a/source/blender/blenlib/intern/polyfill2d_beautify.c +++ b/source/blender/blenlib/intern/polyfill2d_beautify.c @@ -239,8 +239,9 @@ static void polyedge_beauty_cost_update_single( const float cost = polyedge_rotate_beauty_calc(coords, tris, e); /* We can get cases where both choices generate very small negative costs, which leads to infinite loop. * Anyway, costs above that are not worth recomputing, maybe we could even optimize it to a smaller limit? - * See T43578. */ - if (cost < -FLT_EPSILON) { + * Actually, FLT_EPSILON is too small in some cases, 1e-6f seems to work OK hopefully? + * See T43578, T49478. */ + if (cost < -1e-6f) { eheap_table[i] = BLI_heap_insert(eheap, cost, e); } else { diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c index 05322a570a7..a73c86fd122 100644 --- a/source/blender/bmesh/operators/bmo_connect_pair.c +++ b/source/blender/bmesh/operators/bmo_connect_pair.c @@ -48,7 +48,7 @@ * - store a heap of paths which are being scanned (#PathContext.states). * - continuously search the shortest path in the heap. * - never step over the same element twice (tag elements as #ELE_TOUCHED). - * this avoids going into an eternal loop of there are many possible branches (see T45582). + * this avoids going into an eternal loop if there are many possible branches (see T45582). * - when running into a branch, create a new #PathLinkState state and add to the heap. * - when the target is reached, finish - since none of the other paths can be shorter then the one just found. * - if the connection can't be found - fail. @@ -82,13 +82,13 @@ #define ELE_TOUCH_TEST_VERT(v) BMO_vert_flag_test(pc->bm_bmoflag, v, ELE_TOUCHED) -// #define ELE_TOUCH_MARK_VERT(v) BMO_vert_flag_enable(pc->bm_bmoflag, (BMElemF *)e, ELE_TOUCHED) +// #define ELE_TOUCH_MARK_VERT(v) BMO_vert_flag_enable(pc->bm_bmoflag, (BMElemF *)v, ELE_TOUCHED) -// #define ELE_TOUCH_TEST_EDGE(v) BMO_edge_flag_test(pc->bm_bmoflag, v, ELE_TOUCHED) -// #define ELE_TOUCH_MARK_EDGE(v) BMO_edge_flag_enable(pc->bm_bmoflag, (BMElemF *)e, ELE_TOUCHED) +#define ELE_TOUCH_TEST_EDGE(e) BMO_edge_flag_test(pc->bm_bmoflag, e, ELE_TOUCHED) +// #define ELE_TOUCH_MARK_EDGE(e) BMO_edge_flag_enable(pc->bm_bmoflag, (BMElemF *)e, ELE_TOUCHED) -// #define ELE_TOUCH_TEST_FACE(v) BMO_face_flag_test(pc->bm_bmoflag, v, ELE_TOUCHED) -// #define ELE_TOUCH_MARK_FACE(v) BMO_face_flag_enable(pc->bm_bmoflag, (BMElemF *)e, ELE_TOUCHED) +// #define ELE_TOUCH_TEST_FACE(f) BMO_face_flag_test(pc->bm_bmoflag, f, ELE_TOUCHED) +// #define ELE_TOUCH_MARK_FACE(f) BMO_face_flag_enable(pc->bm_bmoflag, (BMElemF *)f, ELE_TOUCHED) // #define DEBUG_PRINT @@ -363,7 +363,7 @@ static PathLinkState *state_step__face_edges( BMElem *ele_next_from = (BMElem *)l_iter->f; if (FACE_WALK_TEST((BMFace *)ele_next_from) && - (ELE_TOUCH_TEST_VERT((BMVert *)ele_next) == false)) + (ELE_TOUCH_TEST_EDGE((BMEdge *)ele_next) == false)) { min_dist_dir_update(mddir, dist_dir); mddir->dist_min[index] = dist_test; @@ -661,7 +661,7 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op) while (!BLI_heap_is_empty(pc.states)) { #ifdef DEBUG_PRINT - printf("\n%s: stepping %d\n", __func__, BLI_heap_size(pc.states)); + printf("\n%s: stepping %u\n", __func__, BLI_heap_size(pc.states)); #endif while (!BLI_heap_is_empty(pc.states)) { diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index a0435c318f0..c41f28b07e8 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -33,6 +33,8 @@ #include "MEM_guardedalloc.h" extern "C" { +#include "DNA_scene_types.h" + #include "BLI_utildefines.h" #include "BLI_ghash.h" @@ -125,7 +127,14 @@ void DEG_evaluate_on_refresh(EvaluationContext *eval_ctx, /* Update time on primary timesource. */ DEG::TimeSourceDepsNode *tsrc = deg_graph->find_time_source(); tsrc->cfra = BKE_scene_frame_get(scene); - DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph, deg_graph->layers); + unsigned int layers = deg_graph->layers; + /* XXX(sergey): This works around missing updates in temp scenes used + * by various scripts, but is weak and needs closer investigation. + */ + if (layers == 0) { + layers = scene->lay; + } + DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph, layers); } /* Frame-change happened for root scene that graph belongs to. */ diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 4ad593b7059..5e39e059ec9 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -389,7 +389,10 @@ static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem /* select is ok for most "ds*" channels (e.g. dsmat) */ case ACHANNEL_SETTING_SELECT: return true; - + + case ACHANNEL_SETTING_ALWAYS_VISIBLE: + return true; + /* other flags are never supported */ default: return false; @@ -1703,7 +1706,10 @@ static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting case ACHANNEL_SETTING_SELECT: /* selected */ return ADT_UI_SELECTED; - + + case ACHANNEL_SETTING_ALWAYS_VISIBLE: + return ADT_CURVES_ALWAYS_VISIBLE; + default: /* unsupported */ return 0; } @@ -1724,6 +1730,7 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ + case ACHANNEL_SETTING_ALWAYS_VISIBLE: if (ca->adt) return GET_ACF_FLAG_PTR(ca->adt->flag, type); return NULL; diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index c41251578e7..66e4cae2f3e 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -2762,6 +2762,19 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base return true; } + /* Special case. + * We don't do recursive checks for pin, but we need to deal with tricky + * setup like animated camera lens without animated camera location. + * Without such special handle here we wouldn't be able to bin such + * camera data only animation to the editor. + */ + if (ob->adt == NULL && ob->data != NULL) { + AnimData *data_adt = BKE_animdata_from_id(ob->data); + if (data_adt != NULL && (data_adt->flag & ADT_CURVES_ALWAYS_VISIBLE)) { + return true; + } + } + /* check selection and object type filters */ if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/)) { /* only selected should be shown */ diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c index 4af7f3f8727..9309592bb46 100644 --- a/source/blender/editors/armature/pose_lib.c +++ b/source/blender/editors/armature/pose_lib.c @@ -461,7 +461,7 @@ static int poselib_add_exec(bContext *C, wmOperator *op) bAction *act = poselib_validate(ob); bPose *pose = (ob) ? ob->pose : NULL; TimeMarker *marker; - KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_WHOLE_CHARACTER_ID); /* this includes custom props :)*/ + KeyingSet *ks; int frame = RNA_int_get(op->ptr, "frame"); char name[64]; @@ -495,8 +495,7 @@ static int poselib_add_exec(bContext *C, wmOperator *op) BLI_uniquename(&act->markers, marker, DATA_("Pose"), '.', offsetof(TimeMarker, name), sizeof(marker->name)); /* use Keying Set to determine what to store for the pose */ - /* FIXME: in the past, the Keying Set respected selections (LocRotScale), but the current one doesn't - * (WholeCharacter) so perhaps we need either a new Keying Set, or just to add overrides here... */ + ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_WHOLE_CHARACTER_SELECTED_ID); /* this includes custom props :)*/ ANIM_apply_keyingset(C, NULL, act, ks, MODIFYKEY_MODE_INSERT, (float)frame); /* store new 'active' pose number */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 602e203a381..07cdff687a3 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -389,6 +389,7 @@ bool ED_autokeyframe_pchan(struct bContext *C, struct Scene *scene, struct Objec #define ANIM_KS_LOC_ROT_SCALE_ID "LocRotScale" #define ANIM_KS_AVAILABLE_ID "Available" #define ANIM_KS_WHOLE_CHARACTER_ID "WholeCharacter" +#define ANIM_KS_WHOLE_CHARACTER_SELECTED_ID "WholeCharacterSelected" #ifdef __cplusplus } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index bc7a9989c72..af86fb72070 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -627,7 +627,10 @@ static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op) .dist = &rv3d->dist, .lens = &v3d->lens}); } - WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS | NC_OBJECT | ND_DRAW, CTX_data_scene(C)); + if (v3d->scenelock) { + WM_event_add_notifier(C, NC_SCENE, scene); + } + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene); } return OPERATOR_FINISHED; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index df6c6c913ab..6cd9fe8f525 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -918,17 +918,18 @@ static EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf(bConte CustomData *pdata; int num_data, i; - /* XXX Is this OK? */ - dm_src = mesh_get_derived_final(dtmd->modifier.scene, ob_src, CD_MASK_BAREMESH | CD_MTEXPOLY); - pdata = dm_src->getPolyDataLayout(dm_src); - num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY); + dm_src = object_get_derived_final(ob_src, false); + if (dm_src != NULL) { + pdata = dm_src->getPolyDataLayout(dm_src); + num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY); - RNA_enum_item_add_separator(&item, &totitem); + RNA_enum_item_add_separator(&item, &totitem); - for (i = 0; i < num_data; i++) { - tmp_item.value = i; - tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i); - RNA_enum_item_add(&item, &totitem, &tmp_item); + for (i = 0; i < num_data; i++) { + tmp_item.value = i; + tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i); + RNA_enum_item_add(&item, &totitem, &tmp_item); + } } } } @@ -940,17 +941,18 @@ static EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf(bConte CustomData *ldata; int num_data, i; - /* XXX Is this OK? */ - dm_src = mesh_get_derived_final(dtmd->modifier.scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL); - ldata = dm_src->getLoopDataLayout(dm_src); - num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL); + dm_src = object_get_derived_final(ob_src, false); + if (dm_src != NULL) { + ldata = dm_src->getLoopDataLayout(dm_src); + num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL); - RNA_enum_item_add_separator(&item, &totitem); + RNA_enum_item_add_separator(&item, &totitem); - for (i = 0; i < num_data; i++) { - tmp_item.value = i; - tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPCOL, i); - RNA_enum_item_add(&item, &totitem, &tmp_item); + for (i = 0; i < num_data; i++) { + tmp_item.value = i; + tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPCOL, i); + RNA_enum_item_add(&item, &totitem, &tmp_item); + } } } } |