Example #1
0
static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pressure)
{
	if (brush_use_alpha_pressure(brush)) 
		brush_set_alpha(brush, MAX2(0.0f, painter->startalpha*pressure));
	if (brush_use_size_pressure(brush))
		brush_set_size(brush, MAX2(1.0f, painter->startsize*pressure));
	if (brush->flag & BRUSH_JITTER_PRESSURE)
		brush->jitter = MAX2(0.0f, painter->startjitter*pressure);
	if (brush->flag & BRUSH_SPACING_PRESSURE)
		brush->spacing = MAX2(1.0f, painter->startspacing*(1.5f-pressure));
}
Example #2
0
void brush_painter_free(BrushPainter *painter)
{
	Brush *brush = painter->brush;

	brush_set_size(brush, painter->startsize);
	brush_set_alpha(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);
}
Example #3
0
static int brush_scale_size_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);
	Paint  *paint=  paint_get_active(scene);
	struct Brush  *brush=  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= brush_size(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

			brush_set_size(scene, brush, size);
		}

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

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

			brush_set_unprojected_radius(scene, brush, unprojected_radius);
		}
	}

	return OPERATOR_FINISHED;
}
Example #4
0
int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user, int use_color_correction)
{
	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_apply_pressure(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= brush_size(brush);

		/* compute brush spacing adapted to brush radius, spacing may depend
		   on pressure, so update it */
		brush_apply_pressure(painter, brush, painter->lastpressure);
		spacing= MAX2(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_apply_pressure(painter, brush, press);
				spacing= MAX2(1.0f, radius)*brush->spacing*0.01f;

				brush_jitter_pos(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 {
			brush_jitter_pos(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_apply_pressure(painter, brush, pressure);

				brush_jitter_pos(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;

	brush_set_alpha(brush, painter->startalpha);
	brush_set_size(brush, painter->startsize);
	brush->jitter = painter->startjitter;
	brush->spacing = painter->startspacing;

	return totpaintops;
}