static void brush_painter_2d_refresh_cache(ImagePaintState *s, BrushPainter *painter, const float pos[2], const float mouse[2]) { const Scene *scene = painter->scene; UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; Brush *brush = painter->brush; BrushPainterCache *cache = &painter->cache; const int diameter = 2 * BKE_brush_size_get(scene, brush); const int size = (cache->size) ? cache->size : diameter; const float alpha = BKE_brush_alpha_get(scene, brush); const bool use_masking = painter->cache.use_masking; bool do_random = false; bool do_partial_update = false; bool do_view = false; float tex_rotation = -brush->mtex.rot; float mask_rotation = -brush->mask_mtex.rot; /* determine how can update based on textures used */ if (painter->cache.is_texbrush) { if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) { do_view = true; tex_rotation += ups->brush_rotation; } else if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) do_random = true; else do_partial_update = true; brush_painter_2d_tex_mapping(s, size, painter->startpaintpos, pos, mouse, brush->mtex.brush_map_mode, &painter->tex_mapping); } if (painter->cache.is_maskbrush) { if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) { do_view = true; mask_rotation += ups->brush_rotation; } else if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) do_random = true; else do_partial_update = true; brush_painter_2d_tex_mapping(s, size, painter->startpaintpos, pos, mouse, brush->mask_mtex.brush_map_mode, &painter->mask_mapping); } if (do_view || do_random) do_partial_update = false; painter->pool = BKE_image_pool_new(); /* detect if we need to recreate image brush buffer */ if (diameter != cache->lastsize || alpha != cache->lastalpha || brush->jitter != cache->lastjitter || tex_rotation != cache->last_tex_rotation || mask_rotation != cache->last_mask_rotation || do_random) { if (cache->ibuf) { IMB_freeImBuf(cache->ibuf); cache->ibuf = NULL; } if (cache->mask) { MEM_freeN(cache->mask); cache->mask = NULL; } if (do_partial_update) { /* do partial update of texture + recreate mask */ cache->mask = brush_painter_mask_new(painter, size); brush_painter_imbuf_partial_update(painter, pos); } else { /* create brush and mask from scratch */ if (use_masking) cache->mask = brush_painter_mask_new(painter, size); cache->ibuf = brush_painter_imbuf_new(painter, size); } cache->lastsize = diameter; cache->lastalpha = alpha; cache->lastjitter = brush->jitter; cache->last_tex_rotation = tex_rotation; cache->last_mask_rotation = mask_rotation; } else if (do_partial_update) { /* do only partial update of texture */ int dx = (int)painter->lastpaintpos[0] - (int)pos[0]; int dy = (int)painter->lastpaintpos[1] - (int)pos[1]; if ((dx != 0) || (dy != 0)) { brush_painter_imbuf_partial_update(painter, pos); } } BKE_image_pool_free(painter->pool); painter->pool = NULL; }
static void brush_painter_2d_refresh_cache(ImagePaintState *s, BrushPainter *painter, const float pos[2], const float mouse[2], float pressure, float distance, float size) { const Scene *scene = painter->scene; UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; Brush *brush = painter->brush; BrushPainterCache *cache = &painter->cache; const int diameter = 2 * size; bool do_random = false; bool do_partial_update = false; bool update_color = (brush->flag & BRUSH_USE_GRADIENT) && ((ELEM(brush->gradient_stroke_mode, BRUSH_GRADIENT_SPACING_REPEAT, BRUSH_GRADIENT_SPACING_CLAMP)) || (cache->last_pressure != pressure)); float tex_rotation = -brush->mtex.rot; float mask_rotation = -brush->mask_mtex.rot; painter->pool = BKE_image_pool_new(); /* determine how can update based on textures used */ if (painter->cache.is_texbrush) { if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) { tex_rotation += ups->brush_rotation; } else if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) do_random = true; else if (!((brush->flag & BRUSH_ANCHORED) || update_color)) do_partial_update = true; brush_painter_2d_tex_mapping(s, diameter, painter->startpaintpos, pos, mouse, brush->mtex.brush_map_mode, &painter->tex_mapping); } if (painter->cache.is_maskbrush) { bool renew_maxmask = false; bool do_partial_update_mask = false; /* invalidate case for all mapping modes */ if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) { mask_rotation += ups->brush_rotation_sec; } else if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) { renew_maxmask = true; } else if (!(brush->flag & BRUSH_ANCHORED)) { do_partial_update_mask = true; renew_maxmask = true; } /* explicilty disable partial update even if it has been enabled above */ if (brush->mask_pressure) { do_partial_update_mask = false; renew_maxmask = true; } if ((diameter != cache->lastdiameter) || (mask_rotation != cache->last_mask_rotation) || renew_maxmask) { if (cache->tex_mask) { MEM_freeN(cache->tex_mask); cache->tex_mask = NULL; } brush_painter_2d_tex_mapping(s, diameter, painter->startpaintpos, pos, mouse, brush->mask_mtex.brush_map_mode, &painter->mask_mapping); if (do_partial_update_mask) brush_painter_mask_imbuf_partial_update(painter, pos, diameter); else cache->tex_mask = brush_painter_mask_ibuf_new(painter, diameter); cache->last_mask_rotation = mask_rotation; } } /* curve mask can only change if the size changes */ if (diameter != cache->lastdiameter) { if (cache->curve_mask) { MEM_freeN(cache->curve_mask); cache->curve_mask = NULL; } cache->curve_mask = brush_painter_curve_mask_new(painter, diameter, size); } /* detect if we need to recreate image brush buffer */ if ((diameter != cache->lastdiameter) || (tex_rotation != cache->last_tex_rotation) || do_random || update_color) { if (cache->ibuf) { IMB_freeImBuf(cache->ibuf); cache->ibuf = NULL; } if (do_partial_update) { /* do partial update of texture */ brush_painter_imbuf_partial_update(painter, pos, diameter); } else { /* create brush from scratch */ cache->ibuf = brush_painter_imbuf_new(painter, diameter, pressure, distance); } cache->lastdiameter = diameter; cache->last_tex_rotation = tex_rotation; cache->last_pressure = pressure; } else if (do_partial_update) { /* do only partial update of texture */ int dx = (int)painter->lastpaintpos[0] - (int)pos[0]; int dy = (int)painter->lastpaintpos[1] - (int)pos[1]; if ((dx != 0) || (dy != 0)) { brush_painter_imbuf_partial_update(painter, pos, diameter); } } BKE_image_pool_free(painter->pool); painter->pool = NULL; }