Fix error in recent vert/edge-slide commits

`CustomData_bmesh_interp_n` was expecting the 'dest' arg not to have its offset applied.

This was a bit confusing since the source args have it applied,
and in some cases we only have the destination with the offset.
This commit is contained in:
Campbell Barton
2015-02-23 13:43:09 +11:00
parent 50c977b54d
commit 5a372dbd89
6 changed files with 75 additions and 58 deletions

View File

@@ -204,7 +204,7 @@ void CustomData_copy_data(const struct CustomData *source,
void CustomData_copy_data_named(const struct CustomData *source, void CustomData_copy_data_named(const struct CustomData *source,
struct CustomData *dest, int source_index, struct CustomData *dest, int source_index,
int dest_index, int count); int dest_index, int count);
void CustomData_copy_elements(int type, void *source, void *dest, int count); void CustomData_copy_elements(int type, void *src_data_ofs, void *dst_data_ofs, int count);
void CustomData_bmesh_copy_data(const struct CustomData *source, void CustomData_bmesh_copy_data(const struct CustomData *source,
struct CustomData *dest, void *src_block, struct CustomData *dest, void *src_block,
void **dest_block); void **dest_block);
@@ -232,11 +232,11 @@ void CustomData_interp(
int count, int dest_index); int count, int dest_index);
void CustomData_bmesh_interp_n( void CustomData_bmesh_interp_n(
struct CustomData *data, const void **src_blocks, const float *weights, struct CustomData *data, const void **src_blocks, const float *weights,
const float *sub_weights, int count, void *dest_block_ofs, int n); const float *sub_weights, int count, void *dst_block_ofs, int n);
void CustomData_bmesh_interp( void CustomData_bmesh_interp(
struct CustomData *data, const void **src_blocks, struct CustomData *data, const void **src_blocks,
const float *weights, const float *sub_weights, int count, const float *weights, const float *sub_weights, int count,
void *dest_block); void *dst_block);
/* swaps the data in the element corners, to new corners with indices as /* swaps the data in the element corners, to new corners with indices as

View File

@@ -1790,7 +1790,8 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, int typ
int totelem, const char *name) int totelem, const char *name)
{ {
const LayerTypeInfo *typeInfo = layerType_getInfo(type); const LayerTypeInfo *typeInfo = layerType_getInfo(type);
int size = typeInfo->size * totelem, flag = 0, index = data->totlayer; const int size = totelem * typeInfo->size;
int flag = 0, index = data->totlayer;
void *newlayerdata = NULL; void *newlayerdata = NULL;
/* Passing a layerdata to copy from with an alloctype that won't copy is /* Passing a layerdata to copy from with an alloctype that won't copy is
@@ -2003,7 +2004,7 @@ static void *customData_duplicate_referenced_layer_index(CustomData *data, const
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if (typeInfo->copy) { if (typeInfo->copy) {
void *dst_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer"); void *dst_data = MEM_mallocN(totelem * typeInfo->size, "CD duplicate ref layer");
typeInfo->copy(layer->data, dst_data, totelem); typeInfo->copy(layer->data, dst_data, totelem);
layer->data = dst_data; layer->data = dst_data;
} }
@@ -2104,14 +2105,14 @@ void CustomData_set_only_copy(const struct CustomData *data,
data->layers[i].flag |= CD_FLAG_NOCOPY; data->layers[i].flag |= CD_FLAG_NOCOPY;
} }
void CustomData_copy_elements(int type, void *source, void *dest, int count) void CustomData_copy_elements(int type, void *src_data_ofs, void *dst_data_ofs, int count)
{ {
const LayerTypeInfo *typeInfo = layerType_getInfo(type); const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if (typeInfo->copy) if (typeInfo->copy)
typeInfo->copy(source, dest, count); typeInfo->copy(src_data_ofs, dst_data_ofs, count);
else else
memcpy(dest, source, typeInfo->size * count); memcpy(dst_data_ofs, src_data_ofs, count * typeInfo->size);
} }
static void CustomData_copy_data_layer( static void CustomData_copy_data_layer(
@@ -2123,28 +2124,28 @@ static void CustomData_copy_data_layer(
int dst_offset; int dst_offset;
const void *src_data = source->layers[src_i].data; const void *src_data = source->layers[src_i].data;
void *dest_data = dest->layers[dst_i].data; void *dst_data = dest->layers[dst_i].data;
typeInfo = layerType_getInfo(source->layers[src_i].type); typeInfo = layerType_getInfo(source->layers[src_i].type);
src_offset = src_index * typeInfo->size; src_offset = src_index * typeInfo->size;
dst_offset = dst_index * typeInfo->size; dst_offset = dst_index * typeInfo->size;
if (!src_data || !dest_data) { if (!src_data || !dst_data) {
if (!(src_data == NULL && dest_data == NULL)) { if (!(src_data == NULL && dst_data == NULL)) {
printf("%s: warning null data for %s type (%p --> %p), skipping\n", printf("%s: warning null data for %s type (%p --> %p), skipping\n",
__func__, layerType_getName(source->layers[src_i].type), __func__, layerType_getName(source->layers[src_i].type),
(void *)src_data, (void *)dest_data); (void *)src_data, (void *)dst_data);
} }
return; return;
} }
if (typeInfo->copy) if (typeInfo->copy)
typeInfo->copy(POINTER_OFFSET(src_data, src_offset), typeInfo->copy(POINTER_OFFSET(src_data, src_offset),
POINTER_OFFSET(dest_data, dst_offset), POINTER_OFFSET(dst_data, dst_offset),
count); count);
else else
memcpy(POINTER_OFFSET(dest_data, dst_offset), memcpy(POINTER_OFFSET(dst_data, dst_offset),
POINTER_OFFSET(src_data, src_offset), POINTER_OFFSET(src_data, src_offset),
count * typeInfo->size); count * typeInfo->size);
} }
@@ -2208,7 +2209,7 @@ void CustomData_free_elem(CustomData *data, int index, int count)
typeInfo = layerType_getInfo(data->layers[i].type); typeInfo = layerType_getInfo(data->layers[i].type);
if (typeInfo->free) { if (typeInfo->free) {
int offset = typeInfo->size * index; int offset = index * typeInfo->size;
typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size); typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size);
} }
@@ -2223,7 +2224,6 @@ void CustomData_interp(const CustomData *source, CustomData *dest,
int count, int dest_index) int count, int dest_index)
{ {
int src_i, dest_i; int src_i, dest_i;
int dest_offset;
int j; int j;
const void *source_buf[SOURCE_BUF_SIZE]; const void *source_buf[SOURCE_BUF_SIZE];
const void **sources = source_buf; const void **sources = source_buf;
@@ -2255,13 +2255,11 @@ void CustomData_interp(const CustomData *source, CustomData *dest,
void *src_data = source->layers[src_i].data; void *src_data = source->layers[src_i].data;
for (j = 0; j < count; ++j) { for (j = 0; j < count; ++j) {
sources[j] = POINTER_OFFSET(src_data, typeInfo->size * src_indices[j]); sources[j] = POINTER_OFFSET(src_data, src_indices[j] * typeInfo->size);
} }
dest_offset = dest_index * typeInfo->size;
typeInfo->interp(sources, weights, sub_weights, count, typeInfo->interp(sources, weights, sub_weights, count,
POINTER_OFFSET(dest->layers[dest_i].data, dest_offset)); POINTER_OFFSET(dest->layers[dest_i].data, dest_index * typeInfo->size));
/* if there are multiple source & dest layers of the same type, /* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so * we don't want to copy all source layers to the same dest, so
@@ -2283,7 +2281,7 @@ void CustomData_swap(struct CustomData *data, int index, const int *corner_indic
typeInfo = layerType_getInfo(data->layers[i].type); typeInfo = layerType_getInfo(data->layers[i].type);
if (typeInfo->swap) { if (typeInfo->swap) {
int offset = typeInfo->size * index; const int offset = index * typeInfo->size;
typeInfo->swap(POINTER_OFFSET(data->layers[i].data, offset), corner_indices); typeInfo->swap(POINTER_OFFSET(data->layers[i].data, offset), corner_indices);
} }
@@ -2986,24 +2984,24 @@ void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so
} }
/** /**
* \param src_blocks must be pointers to the data, offset by layer->offset already. * \note src_blocks_ofs & dst_block_ofs
* must be pointers to the data, offset by layer->offset already.
*/ */
void CustomData_bmesh_interp_n( void CustomData_bmesh_interp_n(
CustomData *data, const void **src_blocks, CustomData *data, const void **src_blocks_ofs,
const float *weights, const float *sub_weights, const float *weights, const float *sub_weights,
int count, void *dest_block, int n) int count, void *dst_block_ofs, int n)
{ {
CustomDataLayer *layer = &data->layers[n]; CustomDataLayer *layer = &data->layers[n];
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
typeInfo->interp(src_blocks, weights, sub_weights, count, typeInfo->interp(src_blocks_ofs, weights, sub_weights, count, dst_block_ofs);
POINTER_OFFSET(dest_block, layer->offset));
} }
void CustomData_bmesh_interp( void CustomData_bmesh_interp(
CustomData *data, const void **src_blocks, CustomData *data, const void **src_blocks,
const float *weights, const float *sub_weights, const float *weights, const float *sub_weights,
int count, void *dest_block) int count, void *dst_block)
{ {
int i, j; int i, j;
void *source_buf[SOURCE_BUF_SIZE]; void *source_buf[SOURCE_BUF_SIZE];
@@ -3023,7 +3021,10 @@ void CustomData_bmesh_interp(
for (j = 0; j < count; ++j) { for (j = 0; j < count; ++j) {
sources[j] = POINTER_OFFSET(src_blocks[j], layer->offset); sources[j] = POINTER_OFFSET(src_blocks[j], layer->offset);
} }
CustomData_bmesh_interp_n(data, sources, weights, sub_weights, count, dest_block, i); CustomData_bmesh_interp_n(
data, sources,
weights, sub_weights, count,
POINTER_OFFSET(dst_block, layer->offset), i);
} }
} }

View File

@@ -202,8 +202,8 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source, const b
BMLoop *l_iter; BMLoop *l_iter;
BMLoop *l_first; BMLoop *l_first;
void **blocks_l = BLI_array_alloca(blocks_l, source->len); const void **blocks_l = BLI_array_alloca(blocks_l, source->len);
void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, source->len) : NULL; const void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, source->len) : NULL;
float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len); float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len);
float axis_mat[3][3]; /* use normal to transform into 2d xy coords */ float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
int i; int i;
@@ -220,10 +220,8 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source, const b
if (do_vertex) blocks_v[i] = l_iter->v->head.data; if (do_vertex) blocks_v[i] = l_iter->v->head.data;
} while (i++, (l_iter = l_iter->next) != l_first); } while (i++, (l_iter = l_iter->next) != l_first);
BM_face_interp_from_face_ex( BM_face_interp_from_face_ex(bm, target, source, do_vertex,
bm, target, source, do_vertex, blocks_l, blocks_v, cos_2d, axis_mat);
(const void **)blocks_l, (const void **)blocks_v,
cos_2d, axis_mat);
} }
/** /**
@@ -1056,25 +1054,31 @@ LinkNode *BM_vert_loop_groups_data_layer_create(BMesh *bm, BMVert *v, int layer_
} }
static void bm_vert_loop_groups_data_layer_merge__single( static void bm_vert_loop_groups_data_layer_merge__single(
BMesh *bm, void *lf_p, void *data, int type) BMesh *bm, void *lf_p, int layer_n,
void *data_tmp)
{ {
struct LoopGroupCD *lf = lf_p; struct LoopGroupCD *lf = lf_p;
const int type = bm->ldata.layers[layer_n].type;
int i; int i;
const float *data_weights; const float *data_weights;
data_weights = lf->data_weights; data_weights = lf->data_weights;
CustomData_bmesh_interp(&bm->ldata, (const void **)lf->data, data_weights, NULL, lf->data_len, data); CustomData_bmesh_interp_n(
&bm->ldata, (const void **)lf->data,
data_weights, NULL, lf->data_len, data_tmp, layer_n);
for (i = 0; i < lf->data_len; i++) { for (i = 0; i < lf->data_len; i++) {
CustomData_copy_elements(type, data, lf->data[i], 1); CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
} }
} }
static void bm_vert_loop_groups_data_layer_merge_weights__single( static void bm_vert_loop_groups_data_layer_merge_weights__single(
BMesh *bm, void *lf_p, void *data, int type, const float *loop_weights) BMesh *bm, void *lf_p, const int layer_n, void *data_tmp,
const float *loop_weights)
{ {
struct LoopGroupCD *lf = lf_p; struct LoopGroupCD *lf = lf_p;
const int type = bm->ldata.layers[layer_n].type;
int i; int i;
const float *data_weights; const float *data_weights;
@@ -1096,25 +1100,28 @@ static void bm_vert_loop_groups_data_layer_merge_weights__single(
data_weights = lf->data_weights; data_weights = lf->data_weights;
} }
CustomData_bmesh_interp(&bm->ldata, (const void **)lf->data, data_weights, NULL, lf->data_len, data); CustomData_bmesh_interp_n(
&bm->ldata, (const void **)lf->data,
data_weights, NULL, lf->data_len, data_tmp, layer_n);
for (i = 0; i < lf->data_len; i++) { for (i = 0; i < lf->data_len; i++) {
CustomData_copy_elements(type, data, lf->data[i], 1); CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
} }
} }
/** /**
* Take existing custom data and merge each fan's data. * Take existing custom data and merge each fan's data.
*/ */
void BM_vert_loop_groups_data_layer_merge(BMesh *bm, LinkNode *groups, int layer_n) void BM_vert_loop_groups_data_layer_merge(BMesh *bm, LinkNode *groups, const int layer_n)
{ {
int type = bm->ldata.layers[layer_n].type; const int type = bm->ldata.layers[layer_n].type;
int size = CustomData_sizeof(type); const int size = CustomData_sizeof(type);
void *data = alloca(size); void *data_tmp = malloc(size);
do { do {
bm_vert_loop_groups_data_layer_merge__single(bm, groups->link, data, type); bm_vert_loop_groups_data_layer_merge__single(bm, groups->link, layer_n, data_tmp);
} while ((groups = groups->next)); } while ((groups = groups->next));
free(data_tmp);
} }
/** /**
@@ -1123,13 +1130,14 @@ void BM_vert_loop_groups_data_layer_merge(BMesh *bm, LinkNode *groups, int layer
*/ */
void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm, LinkNode *groups, int layer_n, const float *loop_weights) void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm, LinkNode *groups, int layer_n, const float *loop_weights)
{ {
int type = bm->ldata.layers[layer_n].type; const int type = bm->ldata.layers[layer_n].type;
int size = CustomData_sizeof(type); const int size = CustomData_sizeof(type);
void *data = alloca(size); void *data_tmp = malloc(size);
do { do {
bm_vert_loop_groups_data_layer_merge_weights__single(bm, groups->link, data, type, loop_weights); bm_vert_loop_groups_data_layer_merge_weights__single(bm, groups->link, layer_n, data_tmp, loop_weights);
} while ((groups = groups->next)); } while ((groups = groups->next));
free(data_tmp);
} }
/** \} */ /** \} */

View File

@@ -54,8 +54,13 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
const bool do_vertex, const bool do_multires); const bool do_vertex, const bool do_multires);
void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f); void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f);
struct LinkNode *BM_vert_loop_groups_data_layer_create(BMesh *bm, BMVert *v, int layer_n, struct MemArena *arena);
void BM_vert_loop_groups_data_layer_merge(BMesh *bm, struct LinkNode *groups, int layer_n); struct LinkNode *BM_vert_loop_groups_data_layer_create(
void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm, struct LinkNode *groups, int layer_n, const float *loop_weights); BMesh *bm, BMVert *v, const int layer_n, struct MemArena *arena);
void BM_vert_loop_groups_data_layer_merge(
BMesh *bm, struct LinkNode *groups, const int layer_n);
void BM_vert_loop_groups_data_layer_merge_weights(
BMesh *bm, struct LinkNode *groups, const int layer_n,
const float *loop_weights);
#endif /* __BMESH_INTERP_H__ */ #endif /* __BMESH_INTERP_H__ */

View File

@@ -527,7 +527,9 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle
/* detect seams */ /* detect seams */
if (CustomData_data_equals(type, cd_src[0], cd_iter)) { if (CustomData_data_equals(type, cd_src[0], cd_iter)) {
CustomData_bmesh_interp_n(&bm->ldata, cd_src, w, NULL, 2, l_iter->head.data, i); CustomData_bmesh_interp_n(
&bm->ldata, cd_src, w, NULL, ARRAY_SIZE(cd_src),
POINTER_OFFSET(l_iter->head.data, offset), i);
#ifdef USE_SEAM #ifdef USE_SEAM
is_seam = false; is_seam = false;
#endif #endif

View File

@@ -5317,16 +5317,17 @@ static void slide_origdata_interp_data_vert(
TransDataGenericSlideVert *sv) TransDataGenericSlideVert *sv)
{ {
BMIter liter; BMIter liter;
BMLoop *l; int j, l_num;
int j;
float *loop_weights; float *loop_weights;
const bool do_loop_weight = (len_squared_v3v3(sv->v->co, sv->co_orig_3d) > FLT_EPSILON); const bool do_loop_weight = (len_squared_v3v3(sv->v->co, sv->co_orig_3d) > FLT_EPSILON);
// BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) { // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
l = BM_iter_new(&liter, bm, BM_LOOPS_OF_VERT, sv->v); BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v);
loop_weights = do_loop_weight ? BLI_array_alloca(loop_weights, liter.count) : NULL; l_num = liter.count;
for (j = 0 ; l; l = BM_iter_step(&liter), j++) { loop_weights = do_loop_weight ? BLI_array_alloca(loop_weights, l_num) : NULL;
for (j = 0; j < l_num; j++) {
BMFace *f_copy; /* the copy of 'f' */ BMFace *f_copy; /* the copy of 'f' */
BMLoop *l = BM_iter_step(&liter);
f_copy = BLI_ghash_lookup(sod->origfaces, l->f); f_copy = BLI_ghash_lookup(sod->origfaces, l->f);