Exemplo n.º 1
0
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];
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
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);
    }
  }
}
Exemplo n.º 4
0
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);
		}
	}
}
Exemplo n.º 6
0
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);
}