Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/customdata.c
| Show First 20 Lines • Show All 249 Lines • ▼ Show 20 Lines | struct MDeformWeight_Link { | ||||
| 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; | int i, j, totweight; | ||||
| if (count <= 0) { | |||||
| return; | |||||
| } | |||||
| /* build a list of unique def_nrs for dest */ | /* build a list of unique def_nrs for dest */ | ||||
| totweight = 0; | totweight = 0; | ||||
| for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
| const MDeformVert *source = sources[i]; | const MDeformVert *source = sources[i]; | ||||
| float interp_weight = weights ? weights[i] : 1.0f; | float interp_weight = weights[i]; | ||||
| for (j = 0; j < source->totweight; j++) { | for (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; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 144 Lines • ▼ Show 20 Lines | |||||
| 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; | int i, j, k; | ||||
| float uv[4][2] = {{0.0f}}; | float uv[4][2] = {{0.0f}}; | ||||
| const float *sub_weight; | const float *sub_weight; | ||||
| if (count <= 0) { | |||||
| return; | |||||
| } | |||||
| sub_weight = sub_weights; | sub_weight = sub_weights; | ||||
| for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1; | const float interp_weight = weights[i]; | ||||
| const MTFace *src = sources[i]; | const MTFace *src = sources[i]; | ||||
| for (j = 0; j < 4; j++) { | for (j = 0; j < 4; j++) { | ||||
| if (sub_weights) { | if (sub_weights) { | ||||
| for (k = 0; k < 4; k++, sub_weight++) { | for (k = 0; k < 4; k++, sub_weight++) { | ||||
| madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight); | madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| madd_v2_v2fl(uv[j], src->uv[j], 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)); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
| 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; | int i, j, k; | ||||
| float uv[4][2] = {{0.0f}}; | float uv[4][2] = {{0.0f}}; | ||||
| const float *sub_weight; | const float *sub_weight; | ||||
| if (count <= 0) { | |||||
| return; | |||||
| } | |||||
| sub_weight = sub_weights; | sub_weight = sub_weights; | ||||
| for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1; | const float interp_weight = weights[i]; | ||||
| const OrigSpaceFace *src = sources[i]; | const OrigSpaceFace *src = sources[i]; | ||||
| for (j = 0; j < 4; j++) { | for (j = 0; j < 4; j++) { | ||||
| if (sub_weights) { | if (sub_weights) { | ||||
| for (k = 0; k < 4; k++, sub_weight++) { | for (k = 0; k < 4; k++, sub_weight++) { | ||||
| madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight); | madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * interp_weight); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| madd_v2_v2fl(uv[j], src->uv[j], 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)); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int count) | ||||
| size_t size = 0; | size_t size = 0; | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| size += sizeof(float[3]) * d[i].totdisp; | size += sizeof(float[3]) * d[i].totdisp; | ||||
| } | } | ||||
| return size; | return size; | ||||
| } | } | ||||
| static void layerInterp_paint_mask( | static void layerInterp_paint_mask(const void **sources, | ||||
| const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | const float *weights, | ||||
| const float *UNUSED(sub_weights), | |||||
| int count, | |||||
| void *dest) | |||||
| { | { | ||||
| float mask = 0.0f; | float mask = 0.0f; | ||||
| const float *sub_weight = sub_weights; | |||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1.0f; | const float interp_weight = weights[i]; | ||||
| const float *src = sources[i]; | const float *src = sources[i]; | ||||
| if (sub_weights) { | mask += (*src) * interp_weight; | ||||
| mask += (*src) * (*sub_weight) * weight; | |||||
| sub_weight++; | |||||
| } | |||||
| else { | |||||
| mask += (*src) * weight; | |||||
| } | |||||
| } | } | ||||
| *(float *)dest = mask; | *(float *)dest = mask; | ||||
| } | } | ||||
| static void layerCopy_grid_paint_mask(const void *source, void *dest, int count) | static void layerCopy_grid_paint_mask(const void *source, void *dest, int count) | ||||
| { | { | ||||
| const GridPaintMask *s = source; | const GridPaintMask *s = source; | ||||
| GridPaintMask *d = dest; | GridPaintMask *d = dest; | ||||
| ▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| MLoopCol default_mloopcol = {255, 255, 255, 255}; | MLoopCol default_mloopcol = {255, 255, 255, 255}; | ||||
| MLoopCol *mlcol = (MLoopCol *)data; | MLoopCol *mlcol = (MLoopCol *)data; | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| mlcol[i] = default_mloopcol; | mlcol[i] = default_mloopcol; | ||||
| } | } | ||||
| } | } | ||||
| static void layerInterp_mloopcol( | static void layerInterp_mloopcol(const void **sources, | ||||
| const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | const float *weights, | ||||
| const float *UNUSED(sub_weights), | |||||
| int count, | |||||
| void *dest) | |||||
| { | { | ||||
| MLoopCol *mc = dest; | MLoopCol *mc = dest; | ||||
| struct { | struct { | ||||
| float a; | float a; | ||||
| float r; | float r; | ||||
| float g; | float g; | ||||
| float b; | float b; | ||||
| } col = {0}; | } col = {0}; | ||||
| const float *sub_weight = sub_weights; | |||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1; | const float interp_weight = weights[i]; | ||||
| const MLoopCol *src = sources[i]; | const MLoopCol *src = sources[i]; | ||||
| if (sub_weights) { | col.r += src->r * interp_weight; | ||||
| col.r += src->r * (*sub_weight) * weight; | col.g += src->g * interp_weight; | ||||
| col.g += src->g * (*sub_weight) * weight; | col.b += src->b * interp_weight; | ||||
| col.b += src->b * (*sub_weight) * weight; | col.a += src->a * interp_weight; | ||||
| col.a += src->a * (*sub_weight) * weight; | |||||
| sub_weight++; | |||||
| } | |||||
| else { | |||||
| col.r += src->r * weight; | |||||
| col.g += src->g * weight; | |||||
| col.b += src->b * weight; | |||||
| col.a += src->a * weight; | |||||
| } | |||||
| } | } | ||||
| /* Subdivide smooth or fractal can cause problems without clamping | /* Subdivide smooth or fractal can cause problems without clamping | ||||
| * although weights should also not cause this situation */ | * although weights should also not cause this situation */ | ||||
| /* Also delay writing to the destination in case dest is in sources. */ | /* Also delay writing to the destination in case dest is in sources. */ | ||||
| mc->r = round_fl_to_uchar_clamp(col.r); | mc->r = round_fl_to_uchar_clamp(col.r); | ||||
| mc->g = round_fl_to_uchar_clamp(col.g); | mc->g = round_fl_to_uchar_clamp(col.g); | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
| static void layerAdd_mloopuv(void *data1, const void *data2) | static void layerAdd_mloopuv(void *data1, const void *data2) | ||||
| { | { | ||||
| MLoopUV *l1 = data1; | MLoopUV *l1 = data1; | ||||
| const MLoopUV *l2 = data2; | const MLoopUV *l2 = data2; | ||||
| add_v2_v2(l1->uv, l2->uv); | add_v2_v2(l1->uv, l2->uv); | ||||
| } | } | ||||
| static void layerInterp_mloopuv( | static void layerInterp_mloopuv(const void **sources, | ||||
| const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | const float *weights, | ||||
| const float *UNUSED(sub_weights), | |||||
| int count, | |||||
| void *dest) | |||||
| { | { | ||||
| float uv[2]; | float uv[2]; | ||||
| int flag = 0; | int flag = 0; | ||||
| zero_v2(uv); | zero_v2(uv); | ||||
| if (sub_weights) { | |||||
| const float *sub_weight = sub_weights; | |||||
| for (int i = 0; i < count; i++) { | |||||
| float weight = (weights ? weights[i] : 1.0f) * (*sub_weight); | |||||
| const MLoopUV *src = sources[i]; | |||||
| madd_v2_v2fl(uv, src->uv, weight); | |||||
| if (weight > 0.0f) { | |||||
| flag |= src->flag; | |||||
| } | |||||
| sub_weight++; | |||||
| } | |||||
| } | |||||
| else { | |||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1; | const float interp_weight = weights[i]; | ||||
| const MLoopUV *src = sources[i]; | const MLoopUV *src = sources[i]; | ||||
| madd_v2_v2fl(uv, src->uv, weight); | madd_v2_v2fl(uv, src->uv, interp_weight); | ||||
| if (weight > 0.0f) { | if (interp_weight > 0.0f) { | ||||
| flag |= src->flag; | flag |= src->flag; | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| /* Delay writing to the destination in case dest is in sources. */ | /* Delay writing to the destination in case dest is in sources. */ | ||||
| copy_v2_v2(((MLoopUV *)dest)->uv, uv); | copy_v2_v2(((MLoopUV *)dest)->uv, uv); | ||||
| ((MLoopUV *)dest)->flag = flag; | ((MLoopUV *)dest)->flag = flag; | ||||
| } | } | ||||
| static bool layerValidate_mloopuv(void *data, const uint totitems, const bool do_fixes) | static bool layerValidate_mloopuv(void *data, const uint totitems, const bool do_fixes) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
| static void layerAdd_mloop_origspace(void *data1, const void *data2) | static void layerAdd_mloop_origspace(void *data1, const void *data2) | ||||
| { | { | ||||
| OrigSpaceLoop *l1 = data1; | OrigSpaceLoop *l1 = data1; | ||||
| const OrigSpaceLoop *l2 = data2; | const OrigSpaceLoop *l2 = data2; | ||||
| add_v2_v2(l1->uv, l2->uv); | add_v2_v2(l1->uv, l2->uv); | ||||
| } | } | ||||
| static void layerInterp_mloop_origspace( | static void layerInterp_mloop_origspace(const void **sources, | ||||
| const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | const float *weights, | ||||
| const float *UNUSED(sub_weights), | |||||
| int count, | |||||
| void *dest) | |||||
| { | { | ||||
| float uv[2]; | float uv[2]; | ||||
| zero_v2(uv); | zero_v2(uv); | ||||
| if (sub_weights) { | |||||
| const float *sub_weight = sub_weights; | |||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1.0f; | const float interp_weight = weights[i]; | ||||
| const OrigSpaceLoop *src = sources[i]; | const OrigSpaceLoop *src = sources[i]; | ||||
| madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight); | madd_v2_v2fl(uv, src->uv, interp_weight); | ||||
| sub_weight++; | |||||
| } | |||||
| } | |||||
| else { | |||||
| for (int i = 0; i < count; i++) { | |||||
| float weight = weights ? weights[i] : 1.0f; | |||||
| const OrigSpaceLoop *src = sources[i]; | |||||
| madd_v2_v2fl(uv, src->uv, weight); | |||||
| } | |||||
| } | } | ||||
| /* Delay writing to the destination in case dest is in sources. */ | /* Delay writing to the destination in case dest is in sources. */ | ||||
| copy_v2_v2(((OrigSpaceLoop *)dest)->uv, uv); | copy_v2_v2(((OrigSpaceLoop *)dest)->uv, uv); | ||||
| } | } | ||||
| /* --- end copy */ | /* --- end copy */ | ||||
| static void layerInterp_mcol( | static void layerInterp_mcol( | ||||
| 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) | ||||
| { | { | ||||
| MCol *mc = dest; | MCol *mc = dest; | ||||
| struct { | struct { | ||||
| float a; | float a; | ||||
| float r; | float r; | ||||
| float g; | float g; | ||||
| float b; | float b; | ||||
| } col[4] = {{0.0f}}; | } col[4] = {{0.0f}}; | ||||
| if (count <= 0) { | |||||
| return; | |||||
| } | |||||
| const float *sub_weight = sub_weights; | const float *sub_weight = sub_weights; | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1; | const float interp_weight = weights[i]; | ||||
| for (int j = 0; j < 4; j++) { | for (int j = 0; j < 4; j++) { | ||||
| if (sub_weights) { | if (sub_weights) { | ||||
| const MCol *src = sources[i]; | const MCol *src = sources[i]; | ||||
| for (int k = 0; k < 4; k++, sub_weight++, src++) { | for (int k = 0; k < 4; k++, sub_weight++, src++) { | ||||
| const float w = (*sub_weight) * weight; | const float w = (*sub_weight) * interp_weight; | ||||
| col[j].a += src->a * w; | col[j].a += src->a * w; | ||||
| col[j].r += src->r * w; | col[j].r += src->r * w; | ||||
| col[j].g += src->g * w; | col[j].g += src->g * w; | ||||
| col[j].b += src->b * w; | col[j].b += src->b * w; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| const MCol *src = sources[i]; | const MCol *src = sources[i]; | ||||
| col[j].a += src[j].a * weight; | col[j].a += src[j].a * interp_weight; | ||||
| col[j].r += src[j].r * weight; | col[j].r += src[j].r * interp_weight; | ||||
| col[j].g += src[j].g * weight; | col[j].g += src[j].g * interp_weight; | ||||
| col[j].b += src[j].b * weight; | col[j].b += src[j].b * interp_weight; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Delay writing to the destination in case dest is in sources. */ | /* Delay writing to the destination in case dest is in sources. */ | ||||
| for (int j = 0; j < 4; j++) { | for (int j = 0; j < 4; j++) { | ||||
| /* Subdivide smooth or fractal can cause problems without clamping | /* Subdivide smooth or fractal can cause problems without clamping | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | static void layerInterp_bweight(const void **sources, | ||||
| float **in = (float **)sources; | float **in = (float **)sources; | ||||
| if (count <= 0) { | if (count <= 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| float f = 0.0f; | float f = 0.0f; | ||||
| if (weights) { | |||||
| for (int i = 0; i < count; i++) { | |||||
| f += *in[i] * weights[i]; | |||||
| } | |||||
| } | |||||
| else { | |||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| f += *in[i]; | const float interp_weight = weights[i]; | ||||
| } | f += *in[i] * interp_weight; | ||||
| } | } | ||||
| /* Delay writing to the destination in case dest is in sources. */ | /* Delay writing to the destination in case dest is in sources. */ | ||||
| *((float *)dest) = f; | *((float *)dest) = f; | ||||
| } | } | ||||
| static void layerInterp_shapekey(const void **sources, | static void layerInterp_shapekey(const void **sources, | ||||
| const float *weights, | const float *weights, | ||||
| const float *UNUSED(sub_weights), | const float *UNUSED(sub_weights), | ||||
| int count, | int count, | ||||
| void *dest) | void *dest) | ||||
| { | { | ||||
| float **in = (float **)sources; | float **in = (float **)sources; | ||||
| if (count <= 0) { | if (count <= 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| float co[3]; | float co[3]; | ||||
| zero_v3(co); | zero_v3(co); | ||||
| if (weights) { | |||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| madd_v3_v3fl(co, in[i], weights[i]); | const float interp_weight = weights[i]; | ||||
| } | madd_v3_v3fl(co, in[i], interp_weight); | ||||
| } | |||||
| else { | |||||
| for (int i = 0; i < count; i++) { | |||||
| add_v3_v3(co, in[i]); | |||||
| } | |||||
| } | } | ||||
| /* Delay writing to the destination in case dest is in sources. */ | /* Delay writing to the destination in case dest is in sources. */ | ||||
| copy_v3_v3((float *)dest, co); | copy_v3_v3((float *)dest, co); | ||||
| } | } | ||||
| static void layerDefault_mvert_skin(void *data, int count) | static void layerDefault_mvert_skin(void *data, int count) | ||||
| { | { | ||||
| Show All 17 Lines | static void layerInterp_mvert_skin(const void **sources, | ||||
| void *dest) | void *dest) | ||||
| { | { | ||||
| MVertSkin *vs_dst = dest; | MVertSkin *vs_dst = dest; | ||||
| float radius[3]; | float radius[3]; | ||||
| zero_v3(radius); | zero_v3(radius); | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| const float interp_weight = weights[i]; | |||||
| const MVertSkin *vs_src = sources[i]; | const MVertSkin *vs_src = sources[i]; | ||||
| float w = weights ? weights[i] : 1.0f; | |||||
| madd_v3_v3fl(radius, vs_src->radius, w); | madd_v3_v3fl(radius, vs_src->radius, interp_weight); | ||||
| } | } | ||||
| /* Delay writing to the destination in case dest is in sources. */ | /* Delay writing to the destination in case dest is in sources. */ | ||||
| vs_dst = dest; | vs_dst = dest; | ||||
| copy_v3_v3(vs_dst->radius, radius); | copy_v3_v3(vs_dst->radius, radius); | ||||
| vs_dst->flag &= ~MVERT_SKIN_ROOT; | vs_dst->flag &= ~MVERT_SKIN_ROOT; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | static void layerDefault_propcol(void *data, int count) | ||||
| /* Default to white, full alpha. */ | /* Default to white, full alpha. */ | ||||
| MPropCol default_propcol = {{1.0f, 1.0f, 1.0f, 1.0f}}; | MPropCol default_propcol = {{1.0f, 1.0f, 1.0f, 1.0f}}; | ||||
| MPropCol *pcol = (MPropCol *)data; | MPropCol *pcol = (MPropCol *)data; | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| copy_v4_v4(pcol[i].color, default_propcol.color); | copy_v4_v4(pcol[i].color, default_propcol.color); | ||||
| } | } | ||||
| } | } | ||||
| static void layerInterp_propcol( | static void layerInterp_propcol(const void **sources, | ||||
| const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | const float *weights, | ||||
| const float *UNUSED(sub_weights), | |||||
| int count, | |||||
| void *dest) | |||||
| { | { | ||||
| MPropCol *mc = dest; | MPropCol *mc = dest; | ||||
| float col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | float col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | ||||
| const float *sub_weight = sub_weights; | |||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1.0f; | const float interp_weight = weights[i]; | ||||
| const MPropCol *src = sources[i]; | const MPropCol *src = sources[i]; | ||||
| if (sub_weights) { | madd_v4_v4fl(col, src->color, interp_weight); | ||||
| madd_v4_v4fl(col, src->color, (*sub_weight) * weight); | |||||
| sub_weight++; | |||||
| } | |||||
| else { | |||||
| madd_v4_v4fl(col, src->color, weight); | |||||
| } | |||||
| } | } | ||||
| copy_v4_v4(mc->color, col); | copy_v4_v4(mc->color, col); | ||||
| } | } | ||||
| static int layerMaxNum_propcol(void) | static int layerMaxNum_propcol(void) | ||||
| { | { | ||||
| return MAX_MCOL; | return MAX_MCOL; | ||||
| } | } | ||||
| static void layerInterp_propfloat3( | static void layerInterp_propfloat3(const void **sources, | ||||
| const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | const float *weights, | ||||
| const float *UNUSED(sub_weights), | |||||
| int count, | |||||
| void *dest) | |||||
| { | { | ||||
| vec3f result = {0.0f, 0.0f, 0.0f}; | vec3f result = {0.0f, 0.0f, 0.0f}; | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1.0f; | const float interp_weight = weights[i]; | ||||
| const vec3f *src = sources[i]; | const vec3f *src = sources[i]; | ||||
| if (sub_weights) { | madd_v3_v3fl(&result.x, &src->x, interp_weight); | ||||
| madd_v3_v3fl(&result.x, &src->x, sub_weights[i] * weight); | |||||
| } | |||||
| else { | |||||
| madd_v3_v3fl(&result.x, &src->x, weight); | |||||
| } | |||||
| } | } | ||||
| copy_v3_v3((float *)dest, &result.x); | copy_v3_v3((float *)dest, &result.x); | ||||
| } | } | ||||
| static void layerMultiply_propfloat3(void *data, float fac) | static void layerMultiply_propfloat3(void *data, float fac) | ||||
| { | { | ||||
| vec3f *vec = data; | vec3f *vec = data; | ||||
| vec->x *= fac; | vec->x *= fac; | ||||
| Show All 20 Lines | if (!isfinite(values[i])) { | ||||
| values[i] = 0.0f; | values[i] = 0.0f; | ||||
| } | } | ||||
| has_errors = true; | has_errors = true; | ||||
| } | } | ||||
| } | } | ||||
| return has_errors; | return has_errors; | ||||
| } | } | ||||
| static void layerInterp_propfloat2( | static void layerInterp_propfloat2(const void **sources, | ||||
| const void **sources, const float *weights, const float *sub_weights, int count, void *dest) | const float *weights, | ||||
| const float *UNUSED(sub_weights), | |||||
| int count, | |||||
| void *dest) | |||||
| { | { | ||||
| vec2f result = {0.0f, 0.0f}; | vec2f result = {0.0f, 0.0f}; | ||||
| for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
| float weight = weights ? weights[i] : 1.0f; | const float interp_weight = weights[i]; | ||||
| const vec2f *src = sources[i]; | const vec2f *src = sources[i]; | ||||
| if (sub_weights) { | madd_v2_v2fl(&result.x, &src->x, interp_weight); | ||||
| madd_v2_v2fl(&result.x, &src->x, sub_weights[i] * weight); | |||||
| } | |||||
| else { | |||||
| madd_v2_v2fl(&result.x, &src->x, weight); | |||||
| } | |||||
| } | } | ||||
| copy_v2_v2((float *)dest, &result.x); | copy_v2_v2((float *)dest, &result.x); | ||||
| } | } | ||||
| static void layerMultiply_propfloat2(void *data, float fac) | static void layerMultiply_propfloat2(void *data, float fac) | ||||
| { | { | ||||
| vec2f *vec = data; | vec2f *vec = data; | ||||
| vec->x *= fac; | vec->x *= fac; | ||||
| ▲ Show 20 Lines • Show All 1,541 Lines • ▼ Show 20 Lines | if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { | ||||
| typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size); | typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| #define SOURCE_BUF_SIZE 100 | #define SOURCE_BUF_SIZE 100 | ||||
| /** | |||||
| * Interpolate given custom data source items into a single destination one. | |||||
| * | |||||
| * \param src_indices Indices of every source items to interpolate into the destination one. | |||||
| * \param weights: The weight to apply to each source value individually. If NULL, they will be | |||||
| * averaged. | |||||
| * \param sub_weights: The weights of sub-items, only used to affect each corners of a | |||||
| * tesselated face data (should alwasy be and array of four values). | |||||
| * \param count: The number of source items to interpolate. | |||||
| * \param dest_index: Index of the destination item, in ahich to put the result of the | |||||
| * interpolation. | |||||
| */ | |||||
| void CustomData_interp(const CustomData *source, | void CustomData_interp(const CustomData *source, | ||||
| CustomData *dest, | CustomData *dest, | ||||
| const int *src_indices, | const int *src_indices, | ||||
| const float *weights, | const float *weights, | ||||
| const float *sub_weights, | const float *sub_weights, | ||||
| int count, | int count, | ||||
| int dest_index) | int dest_index) | ||||
| { | { | ||||
| if (count <= 0) { | |||||
| return; | |||||
| } | |||||
| const void *source_buf[SOURCE_BUF_SIZE]; | const void *source_buf[SOURCE_BUF_SIZE]; | ||||
| const void **sources = source_buf; | const void **sources = 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. */ | |||||
| float default_weights_buf[SOURCE_BUF_SIZE]; | |||||
| float *default_weights = NULL; | |||||
| if (weights == NULL) { | |||||
| default_weights = (count > SOURCE_BUF_SIZE) ? | |||||
| MEM_mallocN(sizeof(*weights) * (size_t)count, __func__) : | |||||
| default_weights_buf; | |||||
| copy_vn_fl(default_weights, count, 1.0f / count); | |||||
| weights = default_weights; | |||||
| } | |||||
| /* interpolates a layer at a time */ | /* interpolates a layer at a time */ | ||||
| int dest_i = 0; | int dest_i = 0; | ||||
| for (int src_i = 0; src_i < source->totlayer; src_i++) { | for (int src_i = 0; src_i < source->totlayer; src_i++) { | ||||
| const LayerTypeInfo *typeInfo = layerType_getInfo(source->layers[src_i].type); | const LayerTypeInfo *typeInfo = layerType_getInfo(source->layers[src_i].type); | ||||
| if (!typeInfo->interp) { | if (!typeInfo->interp) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| Show All 30 Lines | if (dest->layers[dest_i].type == source->layers[src_i].type) { | ||||
| */ | */ | ||||
| dest_i++; | dest_i++; | ||||
| } | } | ||||
| } | } | ||||
| if (count > SOURCE_BUF_SIZE) { | if (count > SOURCE_BUF_SIZE) { | ||||
| MEM_freeN((void *)sources); | MEM_freeN((void *)sources); | ||||
| } | } | ||||
| if (!ELEM(default_weights, NULL, default_weights_buf)) { | |||||
| MEM_freeN(default_weights); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| * Swap data inside each item, for all layers. | * Swap data inside each item, for all layers. | ||||
| * This only applies to item types that may store several sub-item data | * This only applies to item types that may store several sub-item data | ||||
| * (e.g. corner data [UVs, VCol, ...] of tessellated faces). | * (e.g. corner data [UVs, VCol, ...] of tessellated faces). | ||||
| * | * | ||||
| * \param corner_indices: A mapping 'new_index -> old_index' of sub-item data. | * \param corner_indices: A mapping 'new_index -> old_index' of sub-item data. | ||||
| ▲ Show 20 Lines • Show All 912 Lines • ▼ Show 20 Lines | |||||
| void CustomData_bmesh_interp_n(CustomData *data, | void CustomData_bmesh_interp_n(CustomData *data, | ||||
| const void **src_blocks_ofs, | const void **src_blocks_ofs, | ||||
| const float *weights, | const float *weights, | ||||
| const float *sub_weights, | const float *sub_weights, | ||||
| int count, | int count, | ||||
| void *dst_block_ofs, | void *dst_block_ofs, | ||||
| int n) | int n) | ||||
| { | { | ||||
| BLI_assert(weights != NULL); | |||||
| BLI_assert(count > 0); | |||||
| 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_ofs, weights, sub_weights, count, dst_block_ofs); | typeInfo->interp(src_blocks_ofs, weights, sub_weights, count, dst_block_ofs); | ||||
| } | } | ||||
| void CustomData_bmesh_interp(CustomData *data, | void CustomData_bmesh_interp(CustomData *data, | ||||
| const void **src_blocks, | const void **src_blocks, | ||||
| const float *weights, | const float *weights, | ||||
| const float *sub_weights, | const float *sub_weights, | ||||
| int count, | int count, | ||||
| void *dst_block) | void *dst_block) | ||||
| { | { | ||||
| if (count <= 0) { | |||||
| return; | |||||
| } | |||||
| int i, j; | 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. */ | |||||
| float default_weights_buf[SOURCE_BUF_SIZE]; | |||||
| float *default_weights = NULL; | |||||
| if (weights == NULL) { | |||||
| default_weights = (count > SOURCE_BUF_SIZE) ? | |||||
| MEM_mallocN(sizeof(*weights) * (size_t)count, __func__) : | |||||
| default_weights_buf; | |||||
| copy_vn_fl(default_weights, count, 1.0f / count); | |||||
| weights = default_weights; | |||||
| } | |||||
| /* interpolates a layer at a time */ | /* interpolates a layer at a time */ | ||||
| for (i = 0; i < data->totlayer; i++) { | for (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 (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) { | ||||
| MEM_freeN((void *)sources); | MEM_freeN((void *)sources); | ||||
| } | } | ||||
| if (!ELEM(default_weights, NULL, default_weights_buf)) { | |||||
| MEM_freeN(default_weights); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| * \param use_default_init: initializes data which can't be copied, | * \param use_default_init: initializes data which can't be copied, | ||||
| * typically you'll want to use this if the BM_xxx create function | * typically you'll want to use this if the BM_xxx create function | ||||
| * is called with BM_CREATE_SKIP_CD flag | * is called with BM_CREATE_SKIP_CD flag | ||||
| */ | */ | ||||
| void CustomData_to_bmesh_block(const CustomData *source, | void CustomData_to_bmesh_block(const CustomData *source, | ||||
| ▲ Show 20 Lines • Show All 700 Lines • ▼ Show 20 Lines | |||||
| static void customdata_data_transfer_interp_generic(const CustomDataTransferLayerMap *laymap, | static void customdata_data_transfer_interp_generic(const CustomDataTransferLayerMap *laymap, | ||||
| void *data_dst, | void *data_dst, | ||||
| const void **sources, | const void **sources, | ||||
| const float *weights, | const float *weights, | ||||
| const int count, | const int count, | ||||
| const float mix_factor) | const float mix_factor) | ||||
| { | { | ||||
| BLI_assert(weights != NULL); | |||||
| BLI_assert(count > 0); | |||||
| /* Fake interpolation, we actually copy highest weighted source to dest. | /* Fake interpolation, we actually copy highest weighted source to dest. | ||||
| * Note we also handle bitflags here, | * Note we also handle bitflags here, | ||||
| * in which case we rather choose to transfer value of elements totaling | * in which case we rather choose to transfer value of elements totaling | ||||
| * more than 0.5 of weight. */ | * more than 0.5 of weight. */ | ||||
| int best_src_idx = 0; | int best_src_idx = 0; | ||||
| const int data_type = laymap->data_type; | const int data_type = laymap->data_type; | ||||
| const int mix_mode = laymap->mix_mode; | const int mix_mode = laymap->mix_mode; | ||||
| ▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
| /* Normals are special, we need to take care of source & destination spaces... */ | /* Normals are special, we need to take care of source & destination spaces... */ | ||||
| void customdata_data_transfer_interp_normal_normals(const CustomDataTransferLayerMap *laymap, | void customdata_data_transfer_interp_normal_normals(const CustomDataTransferLayerMap *laymap, | ||||
| void *data_dst, | void *data_dst, | ||||
| const void **sources, | const void **sources, | ||||
| const float *weights, | const float *weights, | ||||
| const int count, | const int count, | ||||
| const float mix_factor) | const float mix_factor) | ||||
| { | { | ||||
| BLI_assert(weights != NULL); | |||||
| BLI_assert(count > 0); | |||||
| const int data_type = laymap->data_type; | const int data_type = laymap->data_type; | ||||
| const int mix_mode = laymap->mix_mode; | const int mix_mode = laymap->mix_mode; | ||||
| SpaceTransform *space_transform = laymap->interp_data; | SpaceTransform *space_transform = laymap->interp_data; | ||||
| const LayerTypeInfo *type_info = layerType_getInfo(data_type); | const LayerTypeInfo *type_info = layerType_getInfo(data_type); | ||||
| cd_interp interp_cd = type_info->interp; | cd_interp interp_cd = type_info->interp; | ||||
| ▲ Show 20 Lines • Show All 271 Lines • Show Last 20 Lines | |||||