Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/customdata.c
| Show First 20 Lines • Show All 206 Lines • ▼ Show 20 Lines | if (dvert->dw) { | ||||
| dvert->totweight = 0; | dvert->totweight = 0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* copy just zeros in this case */ | /* copy just zeros in this case */ | ||||
| static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest, int count) | static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest, int count) | ||||
| { | { | ||||
| int i, size = sizeof(void *); | const int size = sizeof(void *); | ||||
| for (i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| void **ptr = POINTER_OFFSET(dest, i * size); | void **ptr = POINTER_OFFSET(dest, i * size); | ||||
| *ptr = NULL; | *ptr = NULL; | ||||
| } | } | ||||
| } | } | ||||
| #ifndef WITH_PYTHON | #ifndef WITH_PYTHON | ||||
| void bpy_bm_generic_invalidate(struct BPy_BMGeneric *UNUSED(self)) | void bpy_bm_generic_invalidate(struct BPy_BMGeneric *UNUSED(self)) | ||||
| { | { | ||||
| Show All 22 Lines | static void layerInterp_mdeformvert(const void **sources, | ||||
| struct MDeformWeight_Link { | struct MDeformWeight_Link { | ||||
| struct MDeformWeight_Link *next; | struct MDeformWeight_Link *next; | ||||
| MDeformWeight dw; | MDeformWeight dw; | ||||
| }; | }; | ||||
| MDeformVert *dvert = dest; | MDeformVert *dvert = dest; | ||||
| struct MDeformWeight_Link *dest_dwlink = NULL; | struct MDeformWeight_Link *dest_dwlink = NULL; | ||||
| struct MDeformWeight_Link *node; | struct MDeformWeight_Link *node; | ||||
| int i, j, totweight; | |||||
| /* build a list of unique def_nrs for dest */ | /* build a list of unique def_nrs for dest */ | ||||
| totweight = 0; | int totweight = 0; | ||||
| for (i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| const MDeformVert *source = sources[i]; | const MDeformVert *source = sources[i]; | ||||
| float interp_weight = weights[i]; | float interp_weight = weights[i]; | ||||
| for (j = 0; j < source->totweight; j++) { | for (int j = 0; j < source->totweight; j++) { | ||||
| MDeformWeight *dw = &source->dw[j]; | MDeformWeight *dw = &source->dw[j]; | ||||
| float weight = dw->weight * interp_weight; | float weight = dw->weight * interp_weight; | ||||
| if (weight == 0.0f) { | if (weight == 0.0f) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| for (node = dest_dwlink; node; node = node->next) { | for (node = dest_dwlink; node; node = node->next) { | ||||
| Show All 33 Lines | else { | ||||
| if (totweight) { | if (totweight) { | ||||
| dvert->dw = MEM_malloc_arrayN(totweight, sizeof(*dvert->dw), __func__); | dvert->dw = MEM_malloc_arrayN(totweight, sizeof(*dvert->dw), __func__); | ||||
| } | } | ||||
| } | } | ||||
| if (totweight) { | if (totweight) { | ||||
| dvert->totweight = totweight; | dvert->totweight = totweight; | ||||
| for (i = 0, node = dest_dwlink; node; node = node->next, i++) { | int i = 0; | ||||
| for (node = dest_dwlink; node; node = node->next, i++) { | |||||
| if (node->dw.weight > 1.0f) { | if (node->dw.weight > 1.0f) { | ||||
| node->dw.weight = 1.0f; | node->dw.weight = 1.0f; | ||||
| } | } | ||||
| dvert->dw[i] = node->dw; | dvert->dw[i] = node->dw; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| memset(dvert, 0, sizeof(*dvert)); | memset(dvert, 0, sizeof(*dvert)); | ||||
| ▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | for (int i = 0; i < count; i++) { | ||||
| dest_tf[i] = source_tf[i]; | dest_tf[i] = source_tf[i]; | ||||
| } | } | ||||
| } | } | ||||
| static void layerInterp_tface( | static void layerInterp_tface( | ||||
| const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | ||||
| { | { | ||||
| MTFace *tf = dest; | MTFace *tf = dest; | ||||
| int i, j, k; | |||||
| float uv[4][2] = {{0.0f}}; | float uv[4][2] = {{0.0f}}; | ||||
| const float *sub_weight; | |||||
| sub_weight = sub_weights; | const float *sub_weight = sub_weights; | ||||
| for (i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| const float interp_weight = weights[i]; | const float interp_weight = weights[i]; | ||||
| const MTFace *src = sources[i]; | const MTFace *src = sources[i]; | ||||
| for (j = 0; j < 4; j++) { | for (int j = 0; j < 4; j++) { | ||||
| if (sub_weights) { | if (sub_weights) { | ||||
| for (k = 0; k < 4; k++, sub_weight++) { | for (int k = 0; k < 4; k++, sub_weight++) { | ||||
| madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight); | madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| madd_v2_v2fl(uv[j], src->uv[j], interp_weight); | madd_v2_v2fl(uv[j], src->uv[j], interp_weight); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Delay writing to the destination in case dest is in sources. */ | /* Delay writing to the destination in case dest is in sources. */ | ||||
| *tf = *(MTFace *)(*sources); | *tf = *(MTFace *)(*sources); | ||||
| memcpy(tf->uv, uv, sizeof(tf->uv)); | memcpy(tf->uv, uv, sizeof(tf->uv)); | ||||
| } | } | ||||
| static void layerSwap_tface(void *data, const int *corner_indices) | static void layerSwap_tface(void *data, const int *corner_indices) | ||||
| { | { | ||||
| MTFace *tf = data; | MTFace *tf = data; | ||||
| float uv[4][2]; | float uv[4][2]; | ||||
| int j; | |||||
| for (j = 0; j < 4; j++) { | for (int j = 0; j < 4; j++) { | ||||
| const int source_index = corner_indices[j]; | const int source_index = corner_indices[j]; | ||||
| copy_v2_v2(uv[j], tf->uv[source_index]); | copy_v2_v2(uv[j], tf->uv[source_index]); | ||||
| } | } | ||||
| memcpy(tf->uv, uv, sizeof(tf->uv)); | memcpy(tf->uv, uv, sizeof(tf->uv)); | ||||
| } | } | ||||
| static void layerDefault_tface(void *data, int count) | static void layerDefault_tface(void *data, int count) | ||||
| ▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | for (int i = 0; i < count; i++) { | ||||
| dest_tf[i] = source_tf[i]; | dest_tf[i] = source_tf[i]; | ||||
| } | } | ||||
| } | } | ||||
| static void layerInterp_origspace_face( | static void layerInterp_origspace_face( | ||||
| const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | ||||
| { | { | ||||
| OrigSpaceFace *osf = dest; | OrigSpaceFace *osf = dest; | ||||
| int i, j, k; | |||||
| float uv[4][2] = {{0.0f}}; | float uv[4][2] = {{0.0f}}; | ||||
| const float *sub_weight; | |||||
| sub_weight = sub_weights; | const float *sub_weight = sub_weights; | ||||
| for (i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| const float interp_weight = weights[i]; | const float interp_weight = weights[i]; | ||||
| const OrigSpaceFace *src = sources[i]; | const OrigSpaceFace *src = sources[i]; | ||||
| for (j = 0; j < 4; j++) { | for (int j = 0; j < 4; j++) { | ||||
| if (sub_weights) { | if (sub_weights) { | ||||
| for (k = 0; k < 4; k++, sub_weight++) { | for (int k = 0; k < 4; k++, sub_weight++) { | ||||
| madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight); | madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| madd_v2_v2fl(uv[j], src->uv[j], interp_weight); | madd_v2_v2fl(uv[j], src->uv[j], interp_weight); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Delay writing to the destination in case dest is in sources. */ | /* Delay writing to the destination in case dest is in sources. */ | ||||
| memcpy(osf->uv, uv, sizeof(osf->uv)); | memcpy(osf->uv, uv, sizeof(osf->uv)); | ||||
| } | } | ||||
| static void layerSwap_origspace_face(void *data, const int *corner_indices) | static void layerSwap_origspace_face(void *data, const int *corner_indices) | ||||
| { | { | ||||
| OrigSpaceFace *osf = data; | OrigSpaceFace *osf = data; | ||||
| float uv[4][2]; | float uv[4][2]; | ||||
| int j; | |||||
| for (j = 0; j < 4; j++) { | for (int j = 0; j < 4; j++) { | ||||
| copy_v2_v2(uv[j], osf->uv[corner_indices[j]]); | copy_v2_v2(uv[j], osf->uv[corner_indices[j]]); | ||||
| } | } | ||||
| memcpy(osf->uv, uv, sizeof(osf->uv)); | memcpy(osf->uv, uv, sizeof(osf->uv)); | ||||
| } | } | ||||
| static void layerDefault_origspace_face(void *data, int count) | static void layerDefault_origspace_face(void *data, int count) | ||||
| { | { | ||||
| static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}}; | static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}}; | ||||
| OrigSpaceFace *osf = (OrigSpaceFace *)data; | OrigSpaceFace *osf = (OrigSpaceFace *)data; | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| osf[i] = default_osf; | osf[i] = default_osf; | ||||
| } | } | ||||
| } | } | ||||
| static void layerSwap_mdisps(void *data, const int *ci) | static void layerSwap_mdisps(void *data, const int *ci) | ||||
| { | { | ||||
| MDisps *s = data; | MDisps *s = data; | ||||
| float(*d)[3] = NULL; | |||||
| int corners, cornersize, S; | |||||
| if (s->disps) { | if (s->disps) { | ||||
| int nverts = (ci[1] == 3) ? 4 : 3; /* silly way to know vertex count of face */ | int nverts = (ci[1] == 3) ? 4 : 3; /* silly way to know vertex count of face */ | ||||
| corners = multires_mdisp_corners(s); | int corners = multires_mdisp_corners(s); | ||||
| cornersize = s->totdisp / corners; | int cornersize = s->totdisp / corners; | ||||
| if (corners != nverts) { | if (corners != nverts) { | ||||
| /* happens when face changed vertex count in edit mode | /* happens when face changed vertex count in edit mode | ||||
| * if it happened, just forgot displacement */ | * if it happened, just forgot displacement */ | ||||
| MEM_freeN(s->disps); | MEM_freeN(s->disps); | ||||
| s->totdisp = (s->totdisp / corners) * nverts; | s->totdisp = (s->totdisp / corners) * nverts; | ||||
| s->disps = MEM_calloc_arrayN(s->totdisp, sizeof(float[3]), "mdisp swap"); | s->disps = MEM_calloc_arrayN(s->totdisp, sizeof(float[3]), "mdisp swap"); | ||||
| return; | return; | ||||
| } | } | ||||
| d = MEM_calloc_arrayN(s->totdisp, sizeof(float[3]), "mdisps swap"); | float(*d)[3] = MEM_calloc_arrayN(s->totdisp, sizeof(float[3]), "mdisps swap"); | ||||
| for (S = 0; S < corners; S++) { | for (int S = 0; S < corners; S++) { | ||||
| memcpy(d + cornersize * S, s->disps + cornersize * ci[S], sizeof(float[3]) * cornersize); | memcpy(d + cornersize * S, s->disps + cornersize * ci[S], sizeof(float[3]) * cornersize); | ||||
| } | } | ||||
| MEM_freeN(s->disps); | MEM_freeN(s->disps); | ||||
| s->disps = d; | s->disps = d; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 524 Lines • ▼ Show 20 Lines | for (int j = 0; j < 4; j++) { | ||||
| mc[j].b = round_fl_to_uchar_clamp(col[j].b); | mc[j].b = round_fl_to_uchar_clamp(col[j].b); | ||||
| } | } | ||||
| } | } | ||||
| static void layerSwap_mcol(void *data, const int *corner_indices) | static void layerSwap_mcol(void *data, const int *corner_indices) | ||||
| { | { | ||||
| MCol *mcol = data; | MCol *mcol = data; | ||||
| MCol col[4]; | MCol col[4]; | ||||
| int j; | |||||
| for (j = 0; j < 4; j++) { | for (int j = 0; j < 4; j++) { | ||||
| col[j] = mcol[corner_indices[j]]; | col[j] = mcol[corner_indices[j]]; | ||||
| } | } | ||||
| memcpy(mcol, col, sizeof(col)); | memcpy(mcol, col, sizeof(col)); | ||||
| } | } | ||||
| static void layerDefault_mcol(void *data, int count) | static void layerDefault_mcol(void *data, int count) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 917 Lines • ▼ Show 20 Lines | static CustomDataLayer *customData_add_layer__internal(CustomData *data, | ||||
| int type, | int type, | ||||
| eCDAllocType alloctype, | eCDAllocType alloctype, | ||||
| void *layerdata, | void *layerdata, | ||||
| int totelem, | int totelem, | ||||
| const char *name); | const char *name); | ||||
| void CustomData_update_typemap(CustomData *data) | void CustomData_update_typemap(CustomData *data) | ||||
| { | { | ||||
| int i, lasttype = -1; | int lasttype = -1; | ||||
| for (i = 0; i < CD_NUMTYPES; i++) { | for (int i = 0; i < CD_NUMTYPES; i++) { | ||||
| data->typemap[i] = -1; | data->typemap[i] = -1; | ||||
| } | } | ||||
| for (i = 0; i < data->totlayer; i++) { | for (int i = 0; i < data->totlayer; i++) { | ||||
| const int type = data->layers[i].type; | const int type = data->layers[i].type; | ||||
| if (type != lasttype) { | if (type != lasttype) { | ||||
| data->typemap[type] = i; | data->typemap[type] = i; | ||||
| lasttype = type; | lasttype = type; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Show All 10 Lines | |||||
| bool CustomData_merge(const struct CustomData *source, | bool CustomData_merge(const struct CustomData *source, | ||||
| struct CustomData *dest, | struct CustomData *dest, | ||||
| CustomDataMask mask, | CustomDataMask mask, | ||||
| eCDAllocType alloctype, | eCDAllocType alloctype, | ||||
| int totelem) | int totelem) | ||||
| { | { | ||||
| /*const LayerTypeInfo *typeInfo;*/ | /*const LayerTypeInfo *typeInfo;*/ | ||||
| CustomDataLayer *layer, *newlayer; | CustomDataLayer *layer, *newlayer; | ||||
| void *data; | int lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0; | ||||
| int i, type, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, | |||||
| flag = 0; | |||||
| int number = 0, maxnumber = -1; | int number = 0, maxnumber = -1; | ||||
| bool changed = false; | bool changed = false; | ||||
| for (i = 0; i < source->totlayer; i++) { | for (int i = 0; i < source->totlayer; i++) { | ||||
| layer = &source->layers[i]; | layer = &source->layers[i]; | ||||
| /*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/ | /*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/ | ||||
| type = layer->type; | int type = layer->type; | ||||
| flag = layer->flag; | int flag = layer->flag; | ||||
| if (type != lasttype) { | if (type != lasttype) { | ||||
| number = 0; | number = 0; | ||||
| maxnumber = CustomData_layertype_layers_max(type); | maxnumber = CustomData_layertype_layers_max(type); | ||||
| lastactive = layer->active; | lastactive = layer->active; | ||||
| lastrender = layer->active_rnd; | lastrender = layer->active_rnd; | ||||
| lastclone = layer->active_clone; | lastclone = layer->active_clone; | ||||
| lastmask = layer->active_mask; | lastmask = layer->active_mask; | ||||
| Show All 11 Lines | for (int i = 0; i < source->totlayer; i++) { | ||||
| } | } | ||||
| if ((maxnumber != -1) && (number >= maxnumber)) { | if ((maxnumber != -1) && (number >= maxnumber)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) { | if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| void *data; | |||||
| switch (alloctype) { | switch (alloctype) { | ||||
| case CD_ASSIGN: | case CD_ASSIGN: | ||||
| case CD_REFERENCE: | case CD_REFERENCE: | ||||
| case CD_DUPLICATE: | case CD_DUPLICATE: | ||||
| data = layer->data; | data = layer->data; | ||||
| break; | break; | ||||
| default: | default: | ||||
| data = NULL; | data = NULL; | ||||
| ▲ Show 20 Lines • Show All 366 Lines • ▼ Show 20 Lines | static CustomDataLayer *customData_add_layer__internal(CustomData *data, | ||||
| const char *name) | const char *name) | ||||
| { | { | ||||
| const LayerTypeInfo *typeInfo = layerType_getInfo(type); | const LayerTypeInfo *typeInfo = layerType_getInfo(type); | ||||
| int flag = 0, index = data->totlayer; | int flag = 0, index = data->totlayer; | ||||
| void *newlayerdata = NULL; | void *newlayerdata = NULL; | ||||
| /* Passing a layer-data to copy from with an alloctype that won't copy is | /* Passing a layer-data to copy from with an alloctype that won't copy is | ||||
| * most likely a bug */ | * most likely a bug */ | ||||
| BLI_assert(!layerdata || (alloctype == CD_ASSIGN) || (alloctype == CD_DUPLICATE) || | BLI_assert(!layerdata || ELEM(alloctype, CD_ASSIGN, CD_DUPLICATE, CD_REFERENCE)); | ||||
| (alloctype == CD_REFERENCE)); | |||||
| if (!typeInfo->defaultname && CustomData_has_layer(data, type)) { | if (!typeInfo->defaultname && CustomData_has_layer(data, type)) { | ||||
| return &data->layers[CustomData_get_layer_index(data, type)]; | return &data->layers[CustomData_get_layer_index(data, type)]; | ||||
| } | } | ||||
| if (ELEM(alloctype, CD_ASSIGN, CD_REFERENCE)) { | if (ELEM(alloctype, CD_ASSIGN, CD_REFERENCE)) { | ||||
| newlayerdata = layerdata; | newlayerdata = layerdata; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | static CustomDataLayer *customData_add_layer__internal(CustomData *data, | ||||
| customData_update_offsets(data); | customData_update_offsets(data); | ||||
| return &data->layers[index]; | return &data->layers[index]; | ||||
| } | } | ||||
| void *CustomData_add_layer( | void *CustomData_add_layer( | ||||
| CustomData *data, int type, eCDAllocType alloctype, void *layerdata, int totelem) | CustomData *data, int type, eCDAllocType alloctype, void *layerdata, int totelem) | ||||
| { | { | ||||
| CustomDataLayer *layer; | |||||
| const LayerTypeInfo *typeInfo = layerType_getInfo(type); | const LayerTypeInfo *typeInfo = layerType_getInfo(type); | ||||
| layer = customData_add_layer__internal( | CustomDataLayer *layer = customData_add_layer__internal( | ||||
| data, type, alloctype, layerdata, totelem, typeInfo->defaultname); | data, type, alloctype, layerdata, totelem, typeInfo->defaultname); | ||||
| CustomData_update_typemap(data); | CustomData_update_typemap(data); | ||||
| if (layer) { | if (layer) { | ||||
| return layer->data; | return layer->data; | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /*same as above but accepts a name*/ | /*same as above but accepts a name*/ | ||||
| void *CustomData_add_layer_named(CustomData *data, | void *CustomData_add_layer_named(CustomData *data, | ||||
| int type, | int type, | ||||
| eCDAllocType alloctype, | eCDAllocType alloctype, | ||||
| void *layerdata, | void *layerdata, | ||||
| int totelem, | int totelem, | ||||
| const char *name) | const char *name) | ||||
| { | { | ||||
| CustomDataLayer *layer; | CustomDataLayer *layer = customData_add_layer__internal( | ||||
| data, type, alloctype, layerdata, totelem, name); | |||||
| layer = customData_add_layer__internal(data, type, alloctype, layerdata, totelem, name); | |||||
| CustomData_update_typemap(data); | CustomData_update_typemap(data); | ||||
| if (layer) { | if (layer) { | ||||
| return layer->data; | return layer->data; | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | bool CustomData_is_referenced_layer(struct CustomData *data, int type) | ||||
| CustomDataLayer *layer = &data->layers[layer_index]; | CustomDataLayer *layer = &data->layers[layer_index]; | ||||
| return (layer->flag & CD_FLAG_NOFREE) != 0; | return (layer->flag & CD_FLAG_NOFREE) != 0; | ||||
| } | } | ||||
| void CustomData_free_temporary(CustomData *data, int totelem) | void CustomData_free_temporary(CustomData *data, int totelem) | ||||
| { | { | ||||
| CustomDataLayer *layer; | |||||
| int i, j; | int i, j; | ||||
| bool changed = false; | bool changed = false; | ||||
| for (i = 0, j = 0; i < data->totlayer; i++) { | for (i = 0, j = 0; i < data->totlayer; i++) { | ||||
| layer = &data->layers[i]; | CustomDataLayer *layer = &data->layers[i]; | ||||
| if (i != j) { | if (i != j) { | ||||
| data->layers[j] = data->layers[i]; | data->layers[j] = data->layers[i]; | ||||
| } | } | ||||
| if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY) { | if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY) { | ||||
| customData_free_layer__internal(layer, totelem); | customData_free_layer__internal(layer, totelem); | ||||
| changed = true; | changed = true; | ||||
| ▲ Show 20 Lines • Show All 831 Lines • ▼ Show 20 Lines | if ((CD_TYPE_AS_MASK(data->layers[i].type) & mask_exclude) == 0) { | ||||
| } | } | ||||
| memset(POINTER_OFFSET(block, offset), 0, typeInfo->size); | memset(POINTER_OFFSET(block, offset), 0, typeInfo->size); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n) | static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n) | ||||
| { | { | ||||
| const LayerTypeInfo *typeInfo; | |||||
| int offset = data->layers[n].offset; | int offset = data->layers[n].offset; | ||||
| const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type); | |||||
| typeInfo = layerType_getInfo(data->layers[n].type); | |||||
| if (typeInfo->set_default) { | if (typeInfo->set_default) { | ||||
| typeInfo->set_default(POINTER_OFFSET(*block, offset), 1); | typeInfo->set_default(POINTER_OFFSET(*block, offset), 1); | ||||
| } | } | ||||
| else { | else { | ||||
| memset(POINTER_OFFSET(*block, offset), 0, typeInfo->size); | memset(POINTER_OFFSET(*block, offset), 0, typeInfo->size); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 349 Lines • ▼ Show 20 Lines | void CustomData_bmesh_interp(CustomData *data, | ||||
| const float *sub_weights, | const float *sub_weights, | ||||
| int count, | int count, | ||||
| void *dst_block) | void *dst_block) | ||||
| { | { | ||||
| if (count <= 0) { | if (count <= 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| int i, j; | |||||
| void *source_buf[SOURCE_BUF_SIZE]; | void *source_buf[SOURCE_BUF_SIZE]; | ||||
| const void **sources = (const void **)source_buf; | const void **sources = (const void **)source_buf; | ||||
| /* Slow fallback in case we're interpolating a ridiculous number of elements. */ | /* Slow fallback in case we're interpolating a ridiculous number of elements. */ | ||||
| if (count > SOURCE_BUF_SIZE) { | if (count > SOURCE_BUF_SIZE) { | ||||
| sources = MEM_malloc_arrayN(count, sizeof(*sources), __func__); | sources = MEM_malloc_arrayN(count, sizeof(*sources), __func__); | ||||
| } | } | ||||
| /* If no weights are given, generate default ones to produce an average result. */ | /* If no weights are given, generate default ones to produce an average result. */ | ||||
| float default_weights_buf[SOURCE_BUF_SIZE]; | float default_weights_buf[SOURCE_BUF_SIZE]; | ||||
| float *default_weights = NULL; | float *default_weights = NULL; | ||||
| if (weights == NULL) { | if (weights == NULL) { | ||||
| default_weights = (count > SOURCE_BUF_SIZE) ? | default_weights = (count > SOURCE_BUF_SIZE) ? | ||||
| MEM_mallocN(sizeof(*weights) * (size_t)count, __func__) : | MEM_mallocN(sizeof(*weights) * (size_t)count, __func__) : | ||||
| default_weights_buf; | default_weights_buf; | ||||
| copy_vn_fl(default_weights, count, 1.0f / count); | copy_vn_fl(default_weights, count, 1.0f / count); | ||||
| weights = default_weights; | weights = default_weights; | ||||
| } | } | ||||
| /* interpolates a layer at a time */ | /* interpolates a layer at a time */ | ||||
| for (i = 0; i < data->totlayer; i++) { | for (int i = 0; i < data->totlayer; i++) { | ||||
| CustomDataLayer *layer = &data->layers[i]; | CustomDataLayer *layer = &data->layers[i]; | ||||
| const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | ||||
| if (typeInfo->interp) { | if (typeInfo->interp) { | ||||
| for (j = 0; j < count; j++) { | for (int 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( | CustomData_bmesh_interp_n( | ||||
| data, sources, weights, sub_weights, count, POINTER_OFFSET(dst_block, layer->offset), i); | data, sources, weights, sub_weights, count, POINTER_OFFSET(dst_block, layer->offset), i); | ||||
| } | } | ||||
| } | } | ||||
| if (count > SOURCE_BUF_SIZE) { | if (count > SOURCE_BUF_SIZE) { | ||||
| ▲ Show 20 Lines • Show All 361 Lines • ▼ Show 20 Lines | if (typeInfo->validate != NULL) { | ||||
| return typeInfo->validate(layer->data, totitems, do_fixes); | return typeInfo->validate(layer->data, totitems, do_fixes); | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void CustomData_layers__print(CustomData *data) | void CustomData_layers__print(CustomData *data) | ||||
| { | { | ||||
| printf("{\n"); | printf("{\n"); | ||||
| int i; | int i; | ||||
| const CustomDataLayer *layer; | const CustomDataLayer *layer; | ||||
| for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) { | for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) { | ||||
| const char *name = CustomData_layertype_name(layer->type); | const char *name = CustomData_layertype_name(layer->type); | ||||
| const int size = CustomData_sizeof(layer->type); | const int size = CustomData_sizeof(layer->type); | ||||
| const char *structname; | const char *structname; | ||||
| Show All 38 Lines | for (int i = 0; i < data->totlayer; i++) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem) | void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem) | ||||
| { | { | ||||
| CustomDataExternal *external = data->external; | CustomDataExternal *external = data->external; | ||||
| CustomDataLayer *layer; | CustomDataLayer *layer; | ||||
| CDataFile *cdf; | |||||
| CDataFileLayer *blay; | |||||
| char filename[FILE_MAX]; | char filename[FILE_MAX]; | ||||
| const LayerTypeInfo *typeInfo; | |||||
| int update = 0; | int update = 0; | ||||
| if (!external) { | if (!external) { | ||||
| return; | return; | ||||
| } | } | ||||
| for (int i = 0; i < data->totlayer; i++) { | for (int i = 0; i < data->totlayer; i++) { | ||||
| layer = &data->layers[i]; | layer = &data->layers[i]; | ||||
| typeInfo = layerType_getInfo(layer->type); | const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | ||||
| if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if (layer->flag & CD_FLAG_IN_MEMORY) { | else if (layer->flag & CD_FLAG_IN_MEMORY) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { | else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { | ||||
| update = 1; | update = 1; | ||||
| } | } | ||||
| } | } | ||||
| if (!update) { | if (!update) { | ||||
| return; | return; | ||||
| } | } | ||||
| customdata_external_filename(filename, id, external); | customdata_external_filename(filename, id, external); | ||||
| cdf = cdf_create(CDF_TYPE_MESH); | CDataFile *cdf = cdf_create(CDF_TYPE_MESH); | ||||
| if (!cdf_read_open(cdf, filename)) { | if (!cdf_read_open(cdf, filename)) { | ||||
| cdf_free(cdf); | cdf_free(cdf); | ||||
| CLOG_ERROR(&LOG, "Failed to read %s layer from %s.", layerType_getName(layer->type), filename); | CLOG_ERROR(&LOG, "Failed to read %s layer from %s.", layerType_getName(layer->type), filename); | ||||
| return; | return; | ||||
| } | } | ||||
| for (int i = 0; i < data->totlayer; i++) { | for (int i = 0; i < data->totlayer; i++) { | ||||
| layer = &data->layers[i]; | layer = &data->layers[i]; | ||||
| typeInfo = layerType_getInfo(layer->type); | const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | ||||
| if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if (layer->flag & CD_FLAG_IN_MEMORY) { | else if (layer->flag & CD_FLAG_IN_MEMORY) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { | else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { | ||||
| blay = cdf_layer_find(cdf, layer->type, layer->name); | CDataFileLayer *blay = cdf_layer_find(cdf, layer->type, layer->name); | ||||
| if (blay) { | if (blay) { | ||||
| if (cdf_read_layer(cdf, blay)) { | if (cdf_read_layer(cdf, blay)) { | ||||
| if (typeInfo->read(cdf, layer->data, totelem)) { | if (typeInfo->read(cdf, layer->data, totelem)) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else { | else { | ||||
| break; | break; | ||||
| Show All 10 Lines | void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem) | ||||
| cdf_read_close(cdf); | cdf_read_close(cdf); | ||||
| cdf_free(cdf); | cdf_free(cdf); | ||||
| } | } | ||||
| void CustomData_external_write( | void CustomData_external_write( | ||||
| CustomData *data, ID *id, CustomDataMask mask, int totelem, int free) | CustomData *data, ID *id, CustomDataMask mask, int totelem, int free) | ||||
| { | { | ||||
| CustomDataExternal *external = data->external; | CustomDataExternal *external = data->external; | ||||
| CustomDataLayer *layer; | |||||
| CDataFile *cdf; | |||||
| CDataFileLayer *blay; | |||||
| const LayerTypeInfo *typeInfo; | |||||
| int update = 0; | int update = 0; | ||||
| char filename[FILE_MAX]; | char filename[FILE_MAX]; | ||||
| if (!external) { | if (!external) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* test if there is anything to write */ | /* test if there is anything to write */ | ||||
| for (int i = 0; i < data->totlayer; i++) { | for (int i = 0; i < data->totlayer; i++) { | ||||
| layer = &data->layers[i]; | CustomDataLayer *layer = &data->layers[i]; | ||||
| typeInfo = layerType_getInfo(layer->type); | const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | ||||
| if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | if (!(mask & CD_TYPE_AS_MASK(layer->type))) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { | else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { | ||||
| update = 1; | update = 1; | ||||
| } | } | ||||
| } | } | ||||
| if (!update) { | if (!update) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* make sure data is read before we try to write */ | /* make sure data is read before we try to write */ | ||||
| CustomData_external_read(data, id, mask, totelem); | CustomData_external_read(data, id, mask, totelem); | ||||
| customdata_external_filename(filename, id, external); | customdata_external_filename(filename, id, external); | ||||
| cdf = cdf_create(CDF_TYPE_MESH); | CDataFile *cdf = cdf_create(CDF_TYPE_MESH); | ||||
| for (int i = 0; i < data->totlayer; i++) { | for (int i = 0; i < data->totlayer; i++) { | ||||
| layer = &data->layers[i]; | CustomDataLayer *layer = &data->layers[i]; | ||||
| typeInfo = layerType_getInfo(layer->type); | const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | ||||
| if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize) { | if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize) { | ||||
| if (layer->flag & CD_FLAG_IN_MEMORY) { | if (layer->flag & CD_FLAG_IN_MEMORY) { | ||||
| cdf_layer_add( | cdf_layer_add( | ||||
| cdf, layer->type, layer->name, typeInfo->filesize(cdf, layer->data, totelem)); | cdf, layer->type, layer->name, typeInfo->filesize(cdf, layer->data, totelem)); | ||||
| } | } | ||||
| else { | else { | ||||
| cdf_free(cdf); | cdf_free(cdf); | ||||
| return; /* read failed for a layer! */ | return; /* read failed for a layer! */ | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (!cdf_write_open(cdf, filename)) { | if (!cdf_write_open(cdf, filename)) { | ||||
| CLOG_ERROR(&LOG, "Failed to open %s for writing.", filename); | CLOG_ERROR(&LOG, "Failed to open %s for writing.", filename); | ||||
| cdf_free(cdf); | cdf_free(cdf); | ||||
| return; | return; | ||||
| } | } | ||||
| int i; | int i; | ||||
| for (i = 0; i < data->totlayer; i++) { | for (i = 0; i < data->totlayer; i++) { | ||||
| layer = &data->layers[i]; | CustomDataLayer *layer = &data->layers[i]; | ||||
| typeInfo = layerType_getInfo(layer->type); | const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | ||||
| if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { | if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { | ||||
| blay = cdf_layer_find(cdf, layer->type, layer->name); | CDataFileLayer *blay = cdf_layer_find(cdf, layer->type, layer->name); | ||||
| if (cdf_write_layer(cdf, blay)) { | if (cdf_write_layer(cdf, blay)) { | ||||
| if (typeInfo->write(cdf, layer->data, totelem)) { | if (typeInfo->write(cdf, layer->data, totelem)) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else { | else { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (i != data->totlayer) { | if (i != data->totlayer) { | ||||
| CLOG_ERROR(&LOG, "Failed to write data to %s.", filename); | CLOG_ERROR(&LOG, "Failed to write data to %s.", filename); | ||||
| cdf_write_close(cdf); | cdf_write_close(cdf); | ||||
| cdf_free(cdf); | cdf_free(cdf); | ||||
| return; | return; | ||||
| } | } | ||||
| for (i = 0; i < data->totlayer; i++) { | for (i = 0; i < data->totlayer; i++) { | ||||
| layer = &data->layers[i]; | CustomDataLayer *layer = &data->layers[i]; | ||||
| typeInfo = layerType_getInfo(layer->type); | const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); | ||||
| if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { | if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { | ||||
| if (free) { | if (free) { | ||||
| if (typeInfo->free) { | if (typeInfo->free) { | ||||
| typeInfo->free(layer->data, totelem, typeInfo->size); | typeInfo->free(layer->data, totelem, typeInfo->size); | ||||
| } | } | ||||
| layer->flag &= ~CD_FLAG_IN_MEMORY; | layer->flag &= ~CD_FLAG_IN_MEMORY; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| cdf_write_close(cdf); | cdf_write_close(cdf); | ||||
| cdf_free(cdf); | cdf_free(cdf); | ||||
| } | } | ||||
| void CustomData_external_add( | void CustomData_external_add( | ||||
| CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename) | CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename) | ||||
| { | { | ||||
| CustomDataExternal *external = data->external; | CustomDataExternal *external = data->external; | ||||
| CustomDataLayer *layer; | |||||
| int layer_index; | |||||
| layer_index = CustomData_get_active_layer_index(data, type); | int layer_index = CustomData_get_active_layer_index(data, type); | ||||
| if (layer_index == -1) { | if (layer_index == -1) { | ||||
| return; | return; | ||||
| } | } | ||||
| layer = &data->layers[layer_index]; | CustomDataLayer *layer = &data->layers[layer_index]; | ||||
| if (layer->flag & CD_FLAG_EXTERNAL) { | if (layer->flag & CD_FLAG_EXTERNAL) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (!external) { | if (!external) { | ||||
| external = MEM_callocN(sizeof(CustomDataExternal), "CustomDataExternal"); | external = MEM_callocN(sizeof(CustomDataExternal), "CustomDataExternal"); | ||||
| data->external = external; | data->external = external; | ||||
| ▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | static void customdata_data_transfer_interp_generic(const CustomDataTransferLayerMap *laymap, | ||||
| const int mix_mode = laymap->mix_mode; | const int mix_mode = laymap->mix_mode; | ||||
| size_t data_size; | size_t data_size; | ||||
| const uint64_t data_flag = laymap->data_flag; | const uint64_t data_flag = laymap->data_flag; | ||||
| cd_interp interp_cd = NULL; | cd_interp interp_cd = NULL; | ||||
| cd_copy copy_cd = NULL; | cd_copy copy_cd = NULL; | ||||
| void *tmp_dst; | |||||
| if (!sources) { | if (!sources) { | ||||
| /* Not supported here, abort. */ | /* Not supported here, abort. */ | ||||
| return; | return; | ||||
| } | } | ||||
| if (data_type & CD_FAKE) { | if (data_type & CD_FAKE) { | ||||
| data_size = laymap->data_size; | data_size = laymap->data_size; | ||||
| } | } | ||||
| else { | else { | ||||
| const LayerTypeInfo *type_info = layerType_getInfo(data_type); | const LayerTypeInfo *type_info = layerType_getInfo(data_type); | ||||
| data_size = (size_t)type_info->size; | data_size = (size_t)type_info->size; | ||||
| interp_cd = type_info->interp; | interp_cd = type_info->interp; | ||||
| copy_cd = type_info->copy; | copy_cd = type_info->copy; | ||||
| } | } | ||||
| tmp_dst = MEM_mallocN(data_size, __func__); | void *tmp_dst = MEM_mallocN(data_size, __func__); | ||||
| if (count > 1 && !interp_cd) { | if (count > 1 && !interp_cd) { | ||||
| if (data_flag) { | if (data_flag) { | ||||
| /* Boolean case, we can 'interpolate' in two groups, | /* Boolean case, we can 'interpolate' in two groups, | ||||
| * and choose value from highest weighted group. */ | * and choose value from highest weighted group. */ | ||||
| float tot_weight_true = 0.0f; | float tot_weight_true = 0.0f; | ||||
| int item_true_idx = -1, item_false_idx = -1; | int item_true_idx = -1, item_false_idx = -1; | ||||
| ▲ Show 20 Lines • Show All 369 Lines • Show Last 20 Lines | |||||