void TextureBaseOperation::deinitExecution() { this->m_inputSize = NULL; this->m_inputOffset = NULL; BKE_image_pool_free(this->m_pool); this->m_pool = NULL; SingleThreadedOperation::deinitExecution(); }
void TextureBaseOperation::deinitExecution() { this->m_inputSize = NULL; this->m_inputOffset = NULL; BKE_image_pool_free(this->m_pool); this->m_pool = NULL; if (this->m_texture != NULL && this->m_texture->use_nodes && this->m_texture->nodetree != NULL && this->m_texture->nodetree->execdata != NULL) { ntreeTexEndExecTree(this->m_texture->nodetree->execdata); } NodeOperation::deinitExecution(); }
/* Renders texture directly to render buffer. */ static void shader_preview_texture(ShaderPreview *sp, Tex *tex, Scene *sce, Render *re) { /* Setup output buffer. */ int width = sp->sizex; int height = sp->sizey; /* This is needed otherwise no RenderResult is created. */ sce->r.scemode &= ~R_BUTS_PREVIEW; RE_InitState(re, NULL, &sce->r, &sce->view_layers, NULL, width, height, NULL); RE_SetScene(re, sce); /* Create buffer in empty RenderView created in the init step. */ RenderResult *rr = RE_AcquireResultWrite(re); RenderView *rv = (RenderView *)rr->views.first; rv->rectf = MEM_callocN(sizeof(float) * 4 * width * height, "texture render result"); RE_ReleaseResult(re); /* Get texture image pool (if any) */ struct ImagePool *img_pool = BKE_image_pool_new(); BKE_texture_fetch_images_for_pool(tex, img_pool); /* Fill in image buffer. */ float *rect_float = rv->rectf; float tex_coord[3] = {0.0f, 0.0f, 0.0f}; bool color_manage = true; for (int y = 0; y < height; y++) { /* Tex coords between -1.0f and 1.0f. */ tex_coord[1] = ((float)y / (float)height) * 2.0f - 1.0f; for (int x = 0; x < width; x++) { tex_coord[0] = ((float)x / (float)height) * 2.0f - 1.0f; /* Evaluate texture at tex_coord .*/ TexResult texres = {0}; BKE_texture_get_value_ex(sce, tex, tex_coord, &texres, img_pool, color_manage); rect_float[0] = texres.tr; rect_float[1] = texres.tg; rect_float[2] = texres.tb; rect_float[3] = 1.0f; rect_float += 4; } /* Check if we should cancel texture preview. */ if (shader_preview_break(sp)) { break; } } BKE_image_pool_free(img_pool); }
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; }