void ConvertRGBToHSVOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) { float inputColor[4]; this->m_inputOperation->read(inputColor, x, y, sampler); rgb_to_hsv_v(inputColor, output); output[3] = inputColor[3]; }
static int Color_channel_hsv_set(ColorObject *self, PyObject *value, void *type) { float hsv[3]; int i = GET_INT_FROM_POINTER(type); float f = PyFloat_AsDouble(value); if (f == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "color.h/s/v = value: " "assigned value not a number"); return -1; } if (BaseMath_ReadCallback(self) == -1) return -1; rgb_to_hsv_v(self->col, hsv); CLAMP(f, 0.0f, 1.0f); hsv[i] = f; hsv_to_rgb_v(hsv, self->col); if (BaseMath_WriteCallback(self) == -1) return -1; return 0; }
void IMB_saturation(ImBuf *ibuf, float sat) { size_t i; unsigned char *rct = (unsigned char *)ibuf->rect; float *rct_fl = ibuf->rect_float; float hsv[3]; if (rct) { float rgb[3]; for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct += 4) { rgb_uchar_to_float(rgb, rct); rgb_to_hsv_v(rgb, hsv); hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb + 1, rgb + 2); rgb_float_to_uchar(rct, rgb); } } if (rct_fl) { for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct_fl += 4) { rgb_to_hsv_v(rct_fl, hsv); hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rct_fl, rct_fl + 1, rct_fl + 2); } } }
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4]) { const CBData *cbd1, *cbd2, *cbd0, *cbd3; float fac; int ipotype; int a; if (coba == NULL || coba->tot == 0) return false; cbd1 = coba->data; ipotype = (coba->color_mode == COLBAND_BLEND_RGB) ? coba->ipotype : COLBAND_INTERP_LINEAR; if (coba->tot == 1) { out[0] = cbd1->r; out[1] = cbd1->g; out[2] = cbd1->b; out[3] = cbd1->a; } else if ((in <= cbd1->pos) && ELEM(ipotype, COLBAND_INTERP_LINEAR, COLBAND_INTERP_EASE)) { out[0] = cbd1->r; out[1] = cbd1->g; out[2] = cbd1->b; out[3] = cbd1->a; } else { CBData left, right; /* we're looking for first pos > in */ for (a = 0; a < coba->tot; a++, cbd1++) { if (cbd1->pos > in) { break; } } if (a == coba->tot) { cbd2 = cbd1 - 1; right = *cbd2; right.pos = 1.0f; cbd1 = &right; } else if (a == 0) { left = *cbd1; left.pos = 0.0f; cbd2 = &left; } else { cbd2 = cbd1 - 1; } if ((in >= cbd1->pos) && ELEM(ipotype, COLBAND_INTERP_LINEAR, COLBAND_INTERP_EASE)) { out[0] = cbd1->r; out[1] = cbd1->g; out[2] = cbd1->b; out[3] = cbd1->a; } else { if (cbd2->pos != cbd1->pos) { fac = (in - cbd1->pos) / (cbd2->pos - cbd1->pos); } else { /* was setting to 0.0 in 2.56 & previous, but this * is incorrect for the last element, see [#26732] */ fac = (a != coba->tot) ? 0.0f : 1.0f; } if (ipotype == COLBAND_INTERP_CONSTANT) { /* constant */ out[0] = cbd2->r; out[1] = cbd2->g; out[2] = cbd2->b; out[3] = cbd2->a; } else if (ipotype >= COLBAND_INTERP_B_SPLINE) { /* ipo from right to left: 3 2 1 0 */ float t[4]; if (a >= coba->tot - 1) cbd0 = cbd1; else cbd0 = cbd1 + 1; if (a < 2) cbd3 = cbd2; else cbd3 = cbd2 - 1; CLAMP(fac, 0.0f, 1.0f); if (ipotype == COLBAND_INTERP_CARDINAL) { key_curve_position_weights(fac, t, KEY_CARDINAL); } else { key_curve_position_weights(fac, t, KEY_BSPLINE); } out[0] = t[3] * cbd3->r + t[2] * cbd2->r + t[1] * cbd1->r + t[0] * cbd0->r; out[1] = t[3] * cbd3->g + t[2] * cbd2->g + t[1] * cbd1->g + t[0] * cbd0->g; out[2] = t[3] * cbd3->b + t[2] * cbd2->b + t[1] * cbd1->b + t[0] * cbd0->b; out[3] = t[3] * cbd3->a + t[2] * cbd2->a + t[1] * cbd1->a + t[0] * cbd0->a; CLAMP(out[0], 0.0f, 1.0f); CLAMP(out[1], 0.0f, 1.0f); CLAMP(out[2], 0.0f, 1.0f); CLAMP(out[3], 0.0f, 1.0f); } else { float mfac; if (ipotype == COLBAND_INTERP_EASE) { mfac = fac * fac; fac = 3.0f * mfac - 2.0f * mfac * fac; } mfac = 1.0f - fac; if (UNLIKELY(coba->color_mode == COLBAND_BLEND_HSV)) { float col1[3], col2[3]; rgb_to_hsv_v(&cbd1->r, col1); rgb_to_hsv_v(&cbd2->r, col2); out[0] = colorband_hue_interp(coba->ipotype_hue, mfac, fac, col1[0], col2[0]); out[1] = mfac * col1[1] + fac * col2[1]; out[2] = mfac * col1[2] + fac * col2[2]; out[3] = mfac * cbd1->a + fac * cbd2->a; hsv_to_rgb_v(out, out); } else if (UNLIKELY(coba->color_mode == COLBAND_BLEND_HSL)) { float col1[3], col2[3]; rgb_to_hsl_v(&cbd1->r, col1); rgb_to_hsl_v(&cbd2->r, col2); out[0] = colorband_hue_interp(coba->ipotype_hue, mfac, fac, col1[0], col2[0]); out[1] = mfac * col1[1] + fac * col2[1]; out[2] = mfac * col1[2] + fac * col2[2]; out[3] = mfac * cbd1->a + fac * cbd2->a; hsl_to_rgb_v(out, out); } else { /* COLBAND_BLEND_RGB */ out[0] = mfac * cbd1->r + fac * cbd2->r; out[1] = mfac * cbd1->g + fac * cbd2->g; out[2] = mfac * cbd1->b + fac * cbd2->b; out[3] = mfac * cbd1->a + fac * cbd2->a; } } } } return true; /* OK */ }
/* Applies new_w weights to org_w ones, using either a texture, vgroup or constant value as factor. * Return values are in org_w. * If indices is not NULL, it must be a table of same length as org_w and new_w, mapping to the real * vertex index (in case the weight tables do not cover the whole vertices...). * XXX The standard "factor" value is assumed in [0.0, 1.0] range. Else, weird results might appear. */ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *new_w, Object *ob, DerivedMesh *dm, float fact, const char defgrp_name[MAX_VGROUP_NAME], Scene *scene, Tex *texture, int tex_use_channel, int tex_mapping, Object *tex_map_object, const char *tex_uvlayer_name) { int ref_didx; int i; /* If influence factor is null, nothing to do! */ if (fact == 0.0f) return; /* If we want to mask vgroup weights from a texture. */ if (texture) { /* The texture coordinates. */ float (*tex_co)[3]; /* See mapping note below... */ MappingInfoModifierData t_map; float (*v_co)[3]; int numVerts = dm->getNumVerts(dm); /* Use new generic get_texture_coords, but do not modify our DNA struct for it... * XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters ? * What e.g. if a modifier wants to use several textures ? * Why use only v_co, and not MVert (or both) ? */ t_map.texture = texture; t_map.map_object = tex_map_object; BLI_strncpy(t_map.uvlayer_name, tex_uvlayer_name, sizeof(t_map.uvlayer_name)); t_map.texmapping = tex_mapping; v_co = MEM_mallocN(sizeof(*v_co) * numVerts, "WeightVG Modifier, TEX mode, v_co"); dm->getVertCos(dm, v_co); tex_co = MEM_callocN(sizeof(*tex_co) * numVerts, "WeightVG Modifier, TEX mode, tex_co"); get_texture_coords(&t_map, ob, dm, v_co, tex_co, num); MEM_freeN(v_co); modifier_init_texture(scene, texture); /* For each weight (vertex), make the mix between org and new weights. */ for (i = 0; i < num; ++i) { int idx = indices ? indices[i] : i; TexResult texres; float hsv[3]; /* For HSV color space. */ bool do_color_manage; do_color_manage = tex_use_channel != MOD_WVG_MASK_TEX_USE_INT; texres.nor = NULL; BKE_texture_get_value(scene, texture, tex_co[idx], &texres, do_color_manage); /* Get the good channel value... */ switch (tex_use_channel) { case MOD_WVG_MASK_TEX_USE_INT: org_w[i] = (new_w[i] * texres.tin * fact) + (org_w[i] * (1.0f - (texres.tin * fact))); break; case MOD_WVG_MASK_TEX_USE_RED: org_w[i] = (new_w[i] * texres.tr * fact) + (org_w[i] * (1.0f - (texres.tr * fact))); break; case MOD_WVG_MASK_TEX_USE_GREEN: org_w[i] = (new_w[i] * texres.tg * fact) + (org_w[i] * (1.0f - (texres.tg * fact))); break; case MOD_WVG_MASK_TEX_USE_BLUE: org_w[i] = (new_w[i] * texres.tb * fact) + (org_w[i] * (1.0f - (texres.tb * fact))); break; case MOD_WVG_MASK_TEX_USE_HUE: rgb_to_hsv_v(&texres.tr, hsv); org_w[i] = (new_w[i] * hsv[0] * fact) + (org_w[i] * (1.0f - (hsv[0] * fact))); break; case MOD_WVG_MASK_TEX_USE_SAT: rgb_to_hsv_v(&texres.tr, hsv); org_w[i] = (new_w[i] * hsv[1] * fact) + (org_w[i] * (1.0f - (hsv[1] * fact))); break; case MOD_WVG_MASK_TEX_USE_VAL: rgb_to_hsv_v(&texres.tr, hsv); org_w[i] = (new_w[i] * hsv[2] * fact) + (org_w[i] * (1.0f - (hsv[2] * fact))); break; case MOD_WVG_MASK_TEX_USE_ALPHA: org_w[i] = (new_w[i] * texres.ta * fact) + (org_w[i] * (1.0f - (texres.ta * fact))); break; default: org_w[i] = (new_w[i] * texres.tin * fact) + (org_w[i] * (1.0f - (texres.tin * fact))); break; } } MEM_freeN(tex_co); } else if ((ref_didx = defgroup_name_index(ob, defgrp_name)) != -1) { MDeformVert *dvert = NULL; /* Check whether we want to set vgroup weights from a constant weight factor or a vertex * group. */ /* Get vgroup idx from its name. */ /* Proceed only if vgroup is valid, else use constant factor. */ /* Get actual dverts (ie vertex group data). */ dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); /* Proceed only if vgroup is valid, else assume factor = O. */ if (dvert == NULL) return; /* For each weight (vertex), make the mix between org and new weights. */ for (i = 0; i < num; i++) { int idx = indices ? indices[i] : i; const float f = defvert_find_weight(&dvert[idx], ref_didx) * fact; org_w[i] = (new_w[i] * f) + (org_w[i] * (1.0f - f)); /* If that vertex is not in ref vgroup, assume null factor, and hence do nothing! */ } } else { /* Default "influence" behavior. */ /* For each weight (vertex), make the mix between org and new weights. */ const float ifact = 1.0f - fact; for (i = 0; i < num; i++) { org_w[i] = (new_w[i] * fact) + (org_w[i] * ifact); } } }
void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect) { CurveMapping *cumap; CurveMap *cuma; CurveMapPoint *cmp; float fx, fy, fac[2], zoomx, zoomy, offsx, offsy; GLint scissor[4]; rcti scissor_new; int a; if (but->editcumap) { cumap = but->editcumap; } else { cumap = (CurveMapping *)but->poin; } cuma = &cumap->cm[cumap->cur]; /* need scissor test, curve can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); scissor_new.xmin = ar->winrct.xmin + rect->xmin; scissor_new.ymin = ar->winrct.ymin + rect->ymin; scissor_new.xmax = ar->winrct.xmin + rect->xmax; scissor_new.ymax = ar->winrct.ymin + rect->ymax; BLI_rcti_isect(&scissor_new, &ar->winrct, &scissor_new); glScissor(scissor_new.xmin, scissor_new.ymin, BLI_rcti_size_x(&scissor_new), BLI_rcti_size_y(&scissor_new)); /* calculate offset and zoom */ zoomx = (BLI_rcti_size_x(rect) - 2.0f * but->aspect) / BLI_rctf_size_x(&cumap->curr); zoomy = (BLI_rcti_size_y(rect) - 2.0f * but->aspect) / BLI_rctf_size_y(&cumap->curr); offsx = cumap->curr.xmin - but->aspect / zoomx; offsy = cumap->curr.ymin - but->aspect / zoomy; /* backdrop */ if (but->a1 == UI_GRAD_H) { /* magic trigger for curve backgrounds */ rcti grid; float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */ grid.xmin = rect->xmin + zoomx * (-offsx); grid.xmax = rect->xmax + zoomx * (-offsx); grid.ymin = rect->ymin + zoomy * (-offsy); grid.ymax = rect->ymax + zoomy * (-offsy); ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f); /* grid, hsv uses different grid */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4ub(0, 0, 0, 48); ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.1666666f); glDisable(GL_BLEND); } else { if (cumap->flag & CUMA_DO_CLIP) { gl_shaded_color((unsigned char *)wcol->inner, -20); glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax); glColor3ubv((unsigned char *)wcol->inner); glRectf(rect->xmin + zoomx * (cumap->clipr.xmin - offsx), rect->ymin + zoomy * (cumap->clipr.ymin - offsy), rect->xmin + zoomx * (cumap->clipr.xmax - offsx), rect->ymin + zoomy * (cumap->clipr.ymax - offsy)); } else { glColor3ubv((unsigned char *)wcol->inner); glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax); } /* grid, every 0.25 step */ gl_shaded_color((unsigned char *)wcol->inner, -16); ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.25f); /* grid, every 1.0 step */ gl_shaded_color((unsigned char *)wcol->inner, -24); ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 1.0f); /* axes */ gl_shaded_color((unsigned char *)wcol->inner, -50); glBegin(GL_LINES); glVertex2f(rect->xmin, rect->ymin + zoomy * (-offsy)); glVertex2f(rect->xmax, rect->ymin + zoomy * (-offsy)); glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymax); glEnd(); } /* cfra option */ /* XXX 2.48 */ #if 0 if (cumap->flag & CUMA_DRAW_CFRA) { glColor3ub(0x60, 0xc0, 0x40); glBegin(GL_LINES); glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax); glEnd(); } #endif /* sample option */ if (cumap->flag & CUMA_DRAW_SAMPLE) { if (but->a1 == UI_GRAD_H) { float tsample[3]; float hsv[3]; linearrgb_to_srgb_v3_v3(tsample, cumap->sample); rgb_to_hsv_v(tsample, hsv); glColor3ub(240, 240, 240); glBegin(GL_LINES); glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax); glEnd(); } else if (cumap->cur == 3) { float lum = rgb_to_bw(cumap->sample); glColor3ub(240, 240, 240); glBegin(GL_LINES); glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymax); glEnd(); } else { if (cumap->cur == 0) glColor3ub(240, 100, 100); else if (cumap->cur == 1) glColor3ub(100, 240, 100); else glColor3ub(100, 100, 240); glBegin(GL_LINES); glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin); glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax); glEnd(); } } /* the curve */ glColor3ubv((unsigned char *)wcol->item); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBegin(GL_LINE_STRIP); if (cuma->table == NULL) curvemapping_changed(cumap, FALSE); cmp = cuma->table; /* first point */ if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { glVertex2f(rect->xmin, rect->ymin + zoomy * (cmp[0].y - offsy)); } else { fx = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]); fy = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]); glVertex2f(fx, fy); } for (a = 0; a <= CM_TABLE; a++) { fx = rect->xmin + zoomx * (cmp[a].x - offsx); fy = rect->ymin + zoomy * (cmp[a].y - offsy); glVertex2f(fx, fy); } /* last point */ if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { glVertex2f(rect->xmax, rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy)); } else { fx = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]); fy = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]); glVertex2f(fx, fy); } glEnd(); glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); /* the points, use aspect to make them visible on edges */ cmp = cuma->curve; glPointSize(3.0f); bglBegin(GL_POINTS); for (a = 0; a < cuma->totpoint; a++) { if (cmp[a].flag & CUMA_SELECT) UI_ThemeColor(TH_TEXT_HI); else UI_ThemeColor(TH_TEXT); fac[0] = rect->xmin + zoomx * (cmp[a].x - offsx); fac[1] = rect->ymin + zoomy * (cmp[a].y - offsy); bglVertex2fv(fac); } bglEnd(); glPointSize(1.0f); /* restore scissortest */ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); /* outline */ glColor3ubv((unsigned char *)wcol->outline); fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); }