示例#1
0
static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure)
{
	if (BKE_brush_use_alpha_pressure(painter->scene, brush))
		BKE_brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure));
	if (BKE_brush_use_size_pressure(painter->scene, brush))
		BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure));
	if (brush->flag & BRUSH_JITTER_PRESSURE)
		brush->jitter = max_ff(0.0f, painter->startjitter * pressure);
	if (brush->flag & BRUSH_SPACING_PRESSURE)
		brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure));
}
示例#2
0
void BKE_brush_painter_free(BrushPainter *painter)
{
	Brush *brush = painter->brush;

	BKE_brush_size_set(painter->scene, brush, painter->startsize);
	BKE_brush_alpha_set(painter->scene, brush, painter->startalpha);
	brush->jitter = painter->startjitter;
	brush->spacing = painter->startspacing;

	if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
	if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
	if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
	MEM_freeN(painter);
}
示例#3
0
static int brush_scale_size_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);
	Paint  *paint =  BKE_paint_get_active_from_context(C);
	Brush  *brush =  BKE_paint_brush(paint);
	// Object *ob = CTX_data_active_object(C);
	float scalar = RNA_float_get(op->ptr, "scalar");

	if (brush) {
		// pixel radius
		{
			const int old_size = BKE_brush_size_get(scene, brush);
			int size = (int)(scalar * old_size);

			if (abs(old_size - size) < U.pixelsize) {
				if (scalar > 1) {
					size += U.pixelsize;
				}
				else if (scalar < 1) {
					size -= U.pixelsize;
				}
			}

			BKE_brush_size_set(scene, brush, size);
		}

		// unprojected radius
		{
			float unprojected_radius = scalar * BKE_brush_unprojected_radius_get(scene, brush);

			if (unprojected_radius < 0.001f) // XXX magic number
				unprojected_radius = 0.001f;

			BKE_brush_unprojected_radius_set(scene, brush, unprojected_radius);
		}

		WM_main_add_notifier(NC_BRUSH | NA_EDITED, brush);
	}

	return OPERATOR_FINISHED;
}
示例#4
0
static int brush_scale_size_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);
	Paint  *paint =  BKE_paint_get_active_from_context(C);
	Brush  *brush =  BKE_paint_brush(paint);
	// Object *ob = CTX_data_active_object(C);
	float scalar = RNA_float_get(op->ptr, "scalar");

	if (brush) {
		// pixel radius
		{
			const int old_size = BKE_brush_size_get(scene, brush);
			int size = (int)(scalar * old_size);

			if (old_size == size) {
				if (scalar > 1) {
					size++;
				}
				else if (scalar < 1) {
					size--;
				}
			}
			CLAMP(size, 1, 2000); // XXX magic number

			BKE_brush_size_set(scene, brush, size);
		}

		// unprojected radius
		{
			float unprojected_radius = scalar * BKE_brush_unprojected_radius_get(scene, brush);

			if (unprojected_radius < 0.001f) // XXX magic number
				unprojected_radius = 0.001f;

			BKE_brush_unprojected_radius_set(scene, brush, unprojected_radius);
		}
	}

	return OPERATOR_FINISHED;
}
示例#5
0
int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2], double time, float pressure,
                            void *user, int use_color_correction)
{
	Scene *scene = painter->scene;
	Brush *brush = painter->brush;
	int totpaintops = 0;

	if (pressure == 0.0f) {
		if (painter->lastpressure) // XXX - hack, operator misses
			pressure = painter->lastpressure;
		else
			pressure = 1.0f;    /* zero pressure == not using tablet */
	}
	if (painter->firsttouch) {
		/* paint exactly once on first touch */
		painter->startpaintpos[0] = pos[0];
		painter->startpaintpos[1] = pos[1];

		brush_pressure_apply(painter, brush, pressure);
		if (painter->cache.enabled)
			brush_painter_refresh_cache(painter, pos, use_color_correction);
		totpaintops += func(user, painter->cache.ibuf, pos, pos);
		
		painter->lasttime = time;
		painter->firsttouch = 0;
		painter->lastpaintpos[0] = pos[0];
		painter->lastpaintpos[1] = pos[1];
	}
#if 0
	else if (painter->brush->flag & BRUSH_AIRBRUSH) {
		float spacing, step, paintpos[2], dmousepos[2], len;
		double starttime, curtime = time;

		/* compute brush spacing adapted to brush size */
		spacing = brush->rate; //radius*brush->spacing * 0.01f;

		/* setup starting time, direction vector and accumulated time */
		starttime = painter->accumtime;
		sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
		len = normalize_v2(dmousepos);
		painter->accumtime += curtime - painter->lasttime;

		/* do paint op over unpainted time distance */
		while (painter->accumtime >= spacing) {
			step = (spacing - starttime) * len;
			paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
			paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;

			if (painter->cache.enabled)
				brush_painter_refresh_cache(painter);
			totpaintops += func(user, painter->cache.ibuf,
			                    painter->lastpaintpos, paintpos);

			painter->lastpaintpos[0] = paintpos[0];
			painter->lastpaintpos[1] = paintpos[1];
			painter->accumtime -= spacing;
			starttime -= spacing;
		}
		
		painter->lasttime = curtime;
	}
#endif
	else {
		float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
		float t, len, press;
		const int radius = BKE_brush_size_get(scene, brush);

		/* compute brush spacing adapted to brush radius, spacing may depend
		 * on pressure, so update it */
		brush_pressure_apply(painter, brush, painter->lastpressure);
		spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;

		/* setup starting distance, direction vector and accumulated distance */
		startdistance = painter->accumdistance;
		sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
		len = normalize_v2(dmousepos);
		painter->accumdistance += len;

		if (brush->flag & BRUSH_SPACE) {
			/* do paint op over unpainted distance */
			while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
				step = spacing - startdistance;
				paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
				paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;

				t = step / len;
				press = (1.0f - t) * painter->lastpressure + t * pressure;
				brush_pressure_apply(painter, brush, press);
				spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;

				BKE_brush_jitter_pos(scene, brush, paintpos, finalpos);

				if (painter->cache.enabled)
					brush_painter_refresh_cache(painter, finalpos, use_color_correction);

				totpaintops +=
				    func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);

				painter->lastpaintpos[0] = paintpos[0];
				painter->lastpaintpos[1] = paintpos[1];
				painter->accumdistance -= spacing;
				startdistance -= spacing;
			}
		}
		else {
			BKE_brush_jitter_pos(scene, brush, pos, finalpos);

			if (painter->cache.enabled)
				brush_painter_refresh_cache(painter, finalpos, use_color_correction);

			totpaintops += func(user, painter->cache.ibuf, pos, finalpos);

			painter->lastpaintpos[0] = pos[0];
			painter->lastpaintpos[1] = pos[1];
			painter->accumdistance = 0;
		}

		/* do airbrush paint ops, based on the number of paint ops left over
		 * from regular painting. this is a temporary solution until we have
		 * accurate time stamps for mouse move events */
		if (brush->flag & BRUSH_AIRBRUSH) {
			double curtime = time;
			double painttime = brush->rate * totpaintops;

			painter->accumtime += curtime - painter->lasttime;
			if (painter->accumtime <= painttime)
				painter->accumtime = 0.0;
			else
				painter->accumtime -= painttime;

			while (painter->accumtime >= (double)brush->rate) {
				brush_pressure_apply(painter, brush, pressure);

				BKE_brush_jitter_pos(scene, brush, pos, finalpos);

				if (painter->cache.enabled)
					brush_painter_refresh_cache(painter, finalpos, use_color_correction);

				totpaintops +=
				    func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
				painter->accumtime -= (double)brush->rate;
			}

			painter->lasttime = curtime;
		}
	}

	painter->lastmousepos[0] = pos[0];
	painter->lastmousepos[1] = pos[1];
	painter->lastpressure = pressure;

	BKE_brush_alpha_set(scene, brush, painter->startalpha);
	BKE_brush_size_set(scene, brush, painter->startsize);
	brush->jitter = painter->startjitter;
	brush->spacing = painter->startspacing;

	return totpaintops;
}