diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2020-05-27 21:04:09 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2020-05-27 21:04:46 +0300 |
commit | d7282537f0165b957efc6b0dc16208906f0202a8 (patch) | |
tree | 27fe0ef36f948ffe6a2fab2311b758eb8f62d412 | |
parent | 80d6421f28474eff0ac491d6a873cdaa9c34db5b (diff) |
CD_PROP_COL datalayer
This implements a generic color datalayer and its functions. Based on
D5975.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D7838
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 149 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.h | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector.c | 29 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_customdata_types.h | 8 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_meshdata_types.h | 4 |
5 files changed, 188 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index a022f3f5d14..24e60803b29 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1339,6 +1339,132 @@ static void layerDefault_fmap(void *data, int count) } } +static void layerCopyValue_propcol(const void *source, + void *dest, + const int mixmode, + const float mixfactor) +{ + const MPropCol *m1 = source; + MPropCol *m2 = dest; + float tmp_col[4]; + + if (ELEM(mixmode, + CDT_MIX_NOMIX, + CDT_MIX_REPLACE_ABOVE_THRESHOLD, + CDT_MIX_REPLACE_BELOW_THRESHOLD)) { + /* Modes that do a full copy or nothing. */ + if (ELEM(mixmode, CDT_MIX_REPLACE_ABOVE_THRESHOLD, CDT_MIX_REPLACE_BELOW_THRESHOLD)) { + /* TODO: Check for a real valid way to get 'factor' value of our dest color? */ + const float f = (m2->col[0] + m2->col[1] + m2->col[2]) / 3.0f; + if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) { + return; /* Do Nothing! */ + } + else if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) { + return; /* Do Nothing! */ + } + } + copy_v3_v3(m2->col, m1->col); + } + else { /* Modes that support 'real' mix factor. */ + if (mixmode == CDT_MIX_MIX) { + blend_color_mix_float(tmp_col, m2->col, m1->col); + } + else if (mixmode == CDT_MIX_ADD) { + blend_color_add_float(tmp_col, m2->col, m1->col); + } + else if (mixmode == CDT_MIX_SUB) { + blend_color_sub_float(tmp_col, m2->col, m1->col); + } + else if (mixmode == CDT_MIX_MUL) { + blend_color_mul_float(tmp_col, m2->col, m1->col); + } + else { + memcpy(tmp_col, m1->col, sizeof(tmp_col)); + } + blend_color_interpolate_float(m2->col, m2->col, tmp_col, mixfactor); + + copy_v3_v3(m2->col, m1->col); + } + m2->col[3] = m1->col[3]; +} + +static bool layerEqual_propcol(const void *data1, const void *data2) +{ + const MPropCol *m1 = data1, *m2 = data2; + float tot = 0; + + for (int i = 0; i < 4; i++) { + float c = (m1->col[i] - m2->col[i]); + tot += c * c; + } + + return tot < 0.001f; +} + +static void layerMultiply_propcol(void *data, float fac) +{ + MPropCol *m = data; + mul_v4_fl(m->col, fac); +} + +static void layerAdd_propcol(void *data1, const void *data2) +{ + MPropCol *m = data1; + const MPropCol *m2 = data2; + add_v4_v4(m->col, m2->col); +} + +static void layerDoMinMax_propcol(const void *data, void *vmin, void *vmax) +{ + const MPropCol *m = data; + MPropCol *min = vmin, *max = vmax; + minmax_v4v4_v4(min->col, max->col, m->col); +} + +static void layerInitMinMax_propcol(void *vmin, void *vmax) +{ + MPropCol *min = vmin, *max = vmax; + + copy_v4_fl(min->col, FLT_MAX); + copy_v4_fl(max->col, FLT_MIN); +} + +static void layerDefault_propcol(void *data, int count) +{ + /* Default to white, full alpha. */ + MPropCol default_propcol = {1.0f, 1.0f, 1.0f, 1.0f}; + MPropCol *pcol = (MPropCol *)data; + int i; + for (i = 0; i < count; i++) { + copy_v4_v4(pcol[i].col, default_propcol.col); + } +} + +static void layerInterp_propcol( + const void **sources, const float *weights, const float *sub_weights, int count, void *dest) +{ + MPropCol *mc = dest; + float col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float *sub_weight = sub_weights; + for (int i = 0; i < count; i++) { + float weight = weights ? weights[i] : 1.0f; + const MPropCol *src = sources[i]; + if (sub_weights) { + madd_v4_v4fl(col, src->col, (*sub_weight) * weight); + sub_weight++; + } + else { + madd_v4_v4fl(col, src->col, weight); + } + } + copy_v4_v4(mc->col, col); +} + +static int layerMaxNum_propcol(void) +{ + return MAX_MCOL; +} + static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* 0: CD_MVERT */ {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL}, @@ -1654,7 +1780,27 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(HairCurve), "HairCurve", 1, NULL, NULL, NULL, NULL, NULL, NULL}, /* 46: CD_HAIR_MAPPING */ {sizeof(HairMapping), "HairMapping", 1, NULL, NULL, NULL, NULL, NULL, NULL}, -}; + /* 47: CD_PROP_COL */ + {sizeof(MPropCol), + "PropCol", + 1, + N_("Col"), + NULL, + NULL, + layerInterp_propcol, + NULL, + layerDefault_propcol, + NULL, + layerEqual_propcol, + layerMultiply_propcol, + layerInitMinMax_propcol, + layerAdd_propcol, + layerDoMinMax_propcol, + layerCopyValue_propcol, + NULL, + NULL, + NULL, + layerMaxNum_propcol}}; static const char *LAYERTYPENAMES[CD_NUMTYPES] = { /* 0-4 */ "CDMVert", @@ -1706,6 +1852,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDHairCurve", "CDHairMapping", "CDPoint", + "CDPropCol", }; const CustomData_MeshMasks CD_MASK_BAREMESH = { diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index af28e826e84..d46c02a961c 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -436,6 +436,7 @@ MINLINE void normal_short_to_float_v3(float r[3], const short n[3]); MINLINE void normal_float_to_short_v3(short r[3], const float n[3]); MINLINE void normal_float_to_short_v4(short r[4], const float n[4]); +void minmax_v4v4_v4(float min[4], float max[4], const float vec[4]); void minmax_v3v3_v3(float min[3], float max[3], const float vec[3]); void minmax_v2v2_v2(float min[2], float max[2], const float vec[2]); diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 9009f73a62f..6ec7c960d6b 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -949,6 +949,35 @@ void print_vn(const char *str, const float v[], const int n) printf("\n"); } +void minmax_v4v4_v4(float min[4], float max[4], const float vec[4]) +{ + if (min[0] > vec[0]) { + min[0] = vec[0]; + } + if (min[1] > vec[1]) { + min[1] = vec[1]; + } + if (min[2] > vec[2]) { + min[2] = vec[2]; + } + if (min[3] > vec[3]) { + min[3] = vec[3]; + } + + if (max[0] < vec[0]) { + max[0] = vec[0]; + } + if (max[1] < vec[1]) { + max[1] = vec[1]; + } + if (max[2] < vec[2]) { + max[2] = vec[2]; + } + if (max[3] < vec[3]) { + max[3] = vec[3]; + } +} + void minmax_v3v3_v3(float min[3], float max[3], const float vec[3]) { if (min[0] > vec[0]) { diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index e99d7fd5609..ef3b2015758 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -76,7 +76,8 @@ typedef struct CustomData { * MUST be >= CD_NUMTYPES, but we cant use a define here. * Correct size is ensured in CustomData_update_typemap assert(). */ - int typemap[47]; + int typemap[48]; + char _pad[4]; /** Number of layers, size of layers array. */ int totlayer, maxlayer; /** In editmode, total size of all data layers. */ @@ -153,7 +154,9 @@ typedef enum CustomDataType { CD_HAIRCURVE = 45, CD_HAIRMAPPING = 46, - CD_NUMTYPES = 47, + CD_PROP_COLOR = 47, + + CD_NUMTYPES = 48, } CustomDataType; /* Bits for CustomDataMask */ @@ -202,6 +205,7 @@ typedef enum CustomDataType { #define CD_MASK_TESSLOOPNORMAL (1LL << CD_TESSLOOPNORMAL) #define CD_MASK_CUSTOMLOOPNORMAL (1LL << CD_CUSTOMLOOPNORMAL) #define CD_MASK_SCULPT_FACE_SETS (1LL << CD_SCULPT_FACE_SETS) +#define CD_MASK_PROP_COLOR (1LL << CD_PROP_COLOR) /** Data types that may be defined for all mesh elements types. */ #define CD_MASK_GENERIC_DATA (CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR) diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index f48024cd55a..04deecde43e 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -344,6 +344,10 @@ typedef struct MLoopCol { unsigned char r, g, b, a; } MLoopCol; +typedef struct MPropCol { + float col[4]; +} MPropCol; + /** Multi-Resolution loop data. */ typedef struct MDisps { /* Strange bug in SDNA: if disps pointer comes first, it fails to see totdisp */ |