void TextureBaseOperation::deinitExecution()
{
	this->m_inputSize = NULL;
	this->m_inputOffset = NULL;
	BKE_image_pool_free(this->m_pool);
	this->m_pool = NULL;
	SingleThreadedOperation::deinitExecution();
}
Exemplo n.º 2
0
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();
}
Exemplo n.º 3
0
/* 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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}