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)); }
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); }
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; }
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; }