Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/paint_vertex.c
| Context not available. | |||||
| return true; | return true; | ||||
| } | } | ||||
| /* apply 'transform_fun' to each vertex of the active vertex color layer */ | |||||
| bool ED_vpaint_color_transform(struct Object *ob, void(*transform_fun)(const float col[3], void *user_data, | |||||
| float r_col[3]), void *user_data) | |||||
campbellbarton: Using varargs here is unnecessarily complicated, would rather each function has an associated… | |||||
| { | |||||
| Mesh *me; | |||||
| MPoly *mp; | |||||
| int i, j; | |||||
| bool selected; | |||||
| if (((me = BKE_mesh_from_object(ob)) == NULL) || | |||||
| (me->mloopcol == NULL && (make_vertexcol(ob) == false))) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| selected = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; | |||||
| mp = me->mpoly; | |||||
| for (i = 0; i < me->totpoly; i++, mp++) { | |||||
| MLoopCol *lcol = me->mloopcol + mp->loopstart; | |||||
| if (selected && !(mp->flag & ME_FACE_SEL)) | |||||
| continue; | |||||
| for (j = 0; j < mp->totloop; j++, lcol++) { | |||||
| float col[3]; | |||||
| rgb_uchar_to_float(col, lcol); | |||||
| (*transform_fun)(col, user_data, col); | |||||
| for (int comp = 0; comp < 3; comp++) | |||||
| CLAMP(col[comp], 0.0f, 1.0f); | |||||
| rgb_float_to_uchar(lcol, col); | |||||
| } | |||||
| } | |||||
| /* remove stale me->mcol, will be added later */ | |||||
| BKE_mesh_tessface_clear(me); | |||||
| DAG_id_tag_update(&me->id, 0); | |||||
| return true; | |||||
| } | |||||
| void vpaint_brightness_contrast(const float col[3], void *user_data, float r_col[3]) | |||||
| { | |||||
| float a, b; | |||||
| BrightContrastData *data = (BrightContrastData*) user_data; | |||||
| float brightness = data->brightness; | |||||
| float contrast = data->contrast; | |||||
| brightness /= 100.0f; | |||||
| float delta = contrast / 200.0f; | |||||
| a = 1.0f - delta * 2.0f; | |||||
| /* | |||||
| * The algorithm is by Werner D. Streidt | |||||
| * (http://visca.com/ffactory/archives/5-99/msg00021.html) | |||||
| * Extracted of OpenCV demhist.c | |||||
| */ | |||||
| if (contrast > 0) { | |||||
| a = 1.0f / a; | |||||
Not Done Inline ActionsWould rather this follow brightness/contrast of other areas of Blender. Best double check the code in the compositor's brightness/contrast node. campbellbarton: Would rather this follow brightness/contrast of other areas of Blender. Best double check the… | |||||
metaraptorUnsubmitted Not Done Inline ActionsIs it okay that evaluating 1.0f / a leads to division by 0 when contrast equals 100? metaraptor: Is it okay that evaluating `1.0f / a` leads to division by 0 when contrast equals 100? | |||||
| b = a * (brightness - delta); | |||||
| } | |||||
| else { | |||||
| delta *= -1; | |||||
| b = a * (brightness + delta); | |||||
| } | |||||
| for (int comp = 0; comp < 3; comp++) | |||||
| r_col[comp] = a * col[comp] + b; | |||||
| } | |||||
| void vpaint_hue_sat(const float col[3], void *user_data, float r_col[3]) | |||||
| { | |||||
| HueSatData *data = (HueSatData*) user_data; | |||||
| float hue = data->hue; | |||||
| float sat = data->sat; | |||||
| float val = data->val; | |||||
| float hsv[3]; | |||||
| rgb_to_hsv_v(col, hsv); | |||||
Done Inline Actionsstyle (function braces on newlines), see: https://wiki.blender.org/index.php/Dev:Doc/Code_Style campbellbarton: style (function braces on newlines), see: https://wiki.blender.org/index.php/Dev:Doc/Code_Style | |||||
| if (hue != 0.5 || sat != 1.0 || val != 1.0) { | |||||
| hsv[0] += (hue - 0.5f); | |||||
| if (hsv[0] > 1.0f) hsv[0] -= 1.0f; else if (hsv[0] < 0.0f) hsv[0] += 1.0f; | |||||
| hsv[1] *= sat; | |||||
| hsv[2] *= val; | |||||
| } | |||||
| hsv_to_rgb_v(hsv, r_col); | |||||
| } | |||||
| void vpaint_invert(const float col[3], void *user_data, float r_col[3]) | |||||
| { | |||||
| for (int comp = 0; comp < 3; comp++) | |||||
| r_col[comp] = 1.0f - col[comp]; | |||||
| } | |||||
| void vpaint_levels(const float col[3], void *user_data, float r_col[3]) | |||||
| { | |||||
| LevelsData *data = (LevelsData*) user_data; | |||||
| float gain = data->gain; | |||||
| float offset = data->offset; | |||||
| for (int comp = 0; comp < 3; comp++) | |||||
| r_col[comp] = gain * (col[comp] + offset); | |||||
| } | |||||
| /* XXX: should be re-implemented as a vertex/weight paint 'color correct' operator */ | /* XXX: should be re-implemented as a vertex/weight paint 'color correct' operator */ | ||||
| #if 0 | #if 0 | ||||
| void vpaint_dogamma(Scene *scene) | void vpaint_dogamma(Scene *scene) | ||||
| Context not available. | |||||
Using varargs here is unnecessarily complicated, would rather each function has an associated struct which can be passed as a void * pointer (we normally call this void *user_data), this was as long as the right struct is paired up with the callback, different data types can be used (not just floats), and theres less chance of errors by some accidental missing argument.