void MultilayerColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
    if (this->m_imageFloatBuffer == NULL) {
        zero_v4(output);
    }
    else {
        if (this->m_numberOfChannels == 4) {
            switch (sampler) {
            case COM_PS_NEAREST:
                nearest_interpolation_color(this->m_buffer, NULL, output, x, y);
                break;
            case COM_PS_BILINEAR:
                bilinear_interpolation_color(this->m_buffer, NULL, output, x, y);
                break;
            case COM_PS_BICUBIC:
                bicubic_interpolation_color(this->m_buffer, NULL, output, x, y);
                break;
            }
        }
        else {
            int yi = y;
            int xi = x;
            if (xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight())
                zero_v4(output);
            else {
                int offset = (yi * this->getWidth() + xi) * 3;
                copy_v3_v3(output, &this->m_imageFloatBuffer[offset]);
            }
        }
    }
}
Esempio n. 2
0
void MovieClipBaseOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
	ImBuf *ibuf = this->m_movieClipBuffer;

	if (ibuf == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) {
		zero_v4(output);
	}
	else if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
		/* Happens for multilayer exr, i.e. */
		zero_v4(output);
	}
	else {
		switch (sampler) {
			case COM_PS_NEAREST:
				nearest_interpolation_color(ibuf, NULL, output, x, y);
				break;
			case COM_PS_BILINEAR:
				bilinear_interpolation_color(ibuf, NULL, output, x, y);
				break;
			case COM_PS_BICUBIC:
				bicubic_interpolation_color(ibuf, NULL, output, x, y);
				break;
		}
	}
}
void ImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
	int ix = x, iy = y;
	if (this->m_imageFloatBuffer == NULL && this->m_imageByteBuffer == NULL) {
		zero_v4(output);
	}
	else if (ix < 0 || iy < 0 || ix >= this->m_buffer->x || iy >= this->m_buffer->y) {
		zero_v4(output);
	}
	else {
		sampleImageAtLocation(this->m_buffer, x, y, sampler, true, output);
	}
}
void RenderLayersBaseProg::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
#if 0
	const RenderData *rd = this->m_rd;

	int dx = 0, dy = 0;

	if (rd->mode & R_BORDER && rd->mode & R_CROP) {
		/* see comment in executeRegion describing coordinate mapping,
		 * here it simply goes other way around
		 */
		int full_width  = rd->xsch * rd->size / 100;
		int full_height = rd->ysch * rd->size / 100;

		dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f;
		dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f;
	}

	int ix = x - dx;
	int iy = y - dy;
#else
	int ix = x;
	int iy = y;
#endif

	if (this->m_inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
		zero_v4(output);
	}
	else {
		doInterpolation(output, ix, iy, sampler);
	}
}
static void node_composit_exec_dilateerode(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: mask */
	/* stack order out: mask */
	if (out[0]->hasoutput == 0)
		return;
	
	/* input no image? then only color operation */
	if (in[0]->data == NULL) {
		zero_v4(out[0]->vec);
	}
	else {
		/* make output size of input image */
		CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_VAL);
		CompBuf *stackbuf = dupalloc_compbuf(cbuf);
		short i;
		
		if (node->custom2 > 0) { // positive, dilate
			for (i = 0; i < node->custom2; i++)
				morpho_dilate(stackbuf);
		}
		else if (node->custom2 < 0) { // negative, erode
			for (i = 0; i > node->custom2; i--)
				morpho_erode(stackbuf);
		}
		
		if (cbuf != in[0]->data)
			free_compbuf(cbuf);
		
		out[0]->data = stackbuf;
	}
}
Esempio n. 6
0
CBData *BKE_colorband_element_add(struct ColorBand *coba, float position)
{
	if (coba->tot == MAXCOLORBAND) {
		return NULL;
	}
	else {
		CBData *xnew;

		xnew = &coba->data[coba->tot];
		xnew->pos = position;

		if (coba->tot != 0) {
			BKE_colorband_evaluate(coba, position, &xnew->r);
		}
		else {
			zero_v4(&xnew->r);
		}
	}

	coba->tot++;
	coba->cur = coba->tot - 1;

	BKE_colorband_update_sort(coba);

	return coba->data + coba->cur;
}
void ScreenLensDistortionOperation::executePixel(float output[4], int x, int y, void *data)
{
	MemoryBuffer *buffer = (MemoryBuffer *)data;
	float xy[2] = { (float)x, (float)y };
	float uv[2];
	get_uv(xy, uv);
	float uv_dot = len_squared_v2(uv);

	int count[3] = { 0, 0, 0 };
	float delta[3][2];
	float sum[4] = { 0, 0, 0, 0 };

	bool valid_r = get_delta(uv_dot, m_k4[0], uv, delta[0]);
	bool valid_g = get_delta(uv_dot, m_k4[1], uv, delta[1]);
	bool valid_b = get_delta(uv_dot, m_k4[2], uv, delta[2]);

	if (valid_r && valid_g && valid_b) {
		accumulate(buffer, 0, 1, uv_dot, uv, delta, sum, count);
		accumulate(buffer, 1, 2, uv_dot, uv, delta, sum, count);
		
		if (count[0]) output[0] = 2.0f * sum[0] / (float)count[0];
		if (count[1]) output[1] = 2.0f * sum[1] / (float)count[1];
		if (count[2]) output[2] = 2.0f * sum[2] / (float)count[2];
		
		/* set alpha */
		output[3] = 1.0f;
	}
	else {
		zero_v4(output);
	}
}
void BokehBlurOperation::executePixel(float output[4], int x, int y, void *data)
{
  float color_accum[4];
  float tempBoundingBox[4];
  float bokeh[4];

  this->m_inputBoundingBoxReader->readSampled(tempBoundingBox, x, y, COM_PS_NEAREST);
  if (tempBoundingBox[0] > 0.0f) {
    float multiplier_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
    MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
    float *buffer = inputBuffer->getBuffer();
    int bufferwidth = inputBuffer->getWidth();
    int bufferstartx = inputBuffer->getRect()->xmin;
    int bufferstarty = inputBuffer->getRect()->ymin;
    const float max_dim = max(this->getWidth(), this->getHeight());
    int pixelSize = this->m_size * max_dim / 100.0f;
    zero_v4(color_accum);

    if (pixelSize < 2) {
      this->m_inputProgram->readSampled(color_accum, x, y, COM_PS_NEAREST);
      multiplier_accum[0] = 1.0f;
      multiplier_accum[1] = 1.0f;
      multiplier_accum[2] = 1.0f;
      multiplier_accum[3] = 1.0f;
    }
    int miny = y - pixelSize;
    int maxy = y + pixelSize;
    int minx = x - pixelSize;
    int maxx = x + pixelSize;
    miny = max(miny, inputBuffer->getRect()->ymin);
    minx = max(minx, inputBuffer->getRect()->xmin);
    maxy = min(maxy, inputBuffer->getRect()->ymax);
    maxx = min(maxx, inputBuffer->getRect()->xmax);

    int step = getStep();
    int offsetadd = getOffsetAdd() * COM_NUM_CHANNELS_COLOR;

    float m = this->m_bokehDimension / pixelSize;
    for (int ny = miny; ny < maxy; ny += step) {
      int bufferindex = ((minx - bufferstartx) * COM_NUM_CHANNELS_COLOR) +
                        ((ny - bufferstarty) * COM_NUM_CHANNELS_COLOR * bufferwidth);
      for (int nx = minx; nx < maxx; nx += step) {
        float u = this->m_bokehMidX - (nx - x) * m;
        float v = this->m_bokehMidY - (ny - y) * m;
        this->m_inputBokehProgram->readSampled(bokeh, u, v, COM_PS_NEAREST);
        madd_v4_v4v4(color_accum, bokeh, &buffer[bufferindex]);
        add_v4_v4(multiplier_accum, bokeh);
        bufferindex += offsetadd;
      }
    }
    output[0] = color_accum[0] * (1.0f / multiplier_accum[0]);
    output[1] = color_accum[1] * (1.0f / multiplier_accum[1]);
    output[2] = color_accum[2] * (1.0f / multiplier_accum[2]);
    output[3] = color_accum[3] * (1.0f / multiplier_accum[3]);
  }
  else {
    this->m_inputProgram->readSampled(output, x, y, COM_PS_NEAREST);
  }
}
void CropImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
	if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
		this->m_inputOperation->readSampled(output, (x + this->m_xmin), (y + this->m_ymin), sampler);
	}
	else {
		zero_v4(output);
	}
}
Esempio n. 10
0
void ImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
	if ((this->m_imageFloatBuffer == NULL && this->m_imageByteBuffer == NULL) || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) {
		zero_v4(output);
	}
	else {
		sampleImageAtLocation(this->m_buffer, x, y, sampler, true, output);
	}
}
void CropOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
	if ((x < this->m_xmax && x >= this->m_xmin) && (y < this->m_ymax && y >= this->m_ymin)) {
		this->m_inputOperation->readSampled(output, x, y, sampler);
	}
	else {
		zero_v4(output);
	}
}
Esempio n. 12
0
static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, int p)
{
	ParticleThreadContext *ctx= thread->ctx;
	MFace *mface;

	mface = ctx->dm->getTessFaceDataArray(ctx->dm, CD_MFACE);

	int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */

	/* TODO_PARTICLE - use original index */
	pa->num = ctx->index[p];

	zero_v4(pa->fuv);

	if (pa->num != DMCACHE_NOTFOUND && pa->num < ctx->dm->getNumVerts(ctx->dm)) {

		/* This finds the first face to contain the emitting vertex,
		 * this is not ideal, but is mostly fine as UV seams generally
		 * map to equal-colored parts of a texture */
		for (int i = 0; i < ctx->dm->getNumTessFaces(ctx->dm); i++, mface++) {
			if (ELEM(pa->num, mface->v1, mface->v2, mface->v3, mface->v4)) {
				unsigned int *vert = &mface->v1;

				for (int j = 0; j < 4; j++, vert++) {
					if (*vert == pa->num) {
						pa->fuv[j] = 1.0f;
						break;
					}
				}

				break;
			}
		}
	}

#if ONLY_WORKING_WITH_PA_VERTS
	if (ctx->tree) {
		KDTreeNearest ptn[3];
		int w, maxw;

		psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
		BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1);
		maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3);

		for (w=0; w<maxw; w++) {
			pa->verts[w]=ptn->num;
		}
	}
#endif

	if (rng_skip_tot > 0) /* should never be below zero */
		BLI_rng_skip(thread->rng, rng_skip_tot);
}
void ConvolutionFilterOperation::executePixel(float output[4], int x, int y, void * /*data*/)
{
	float in1[4];
	float in2[4];
	int x1 = x - 1;
	int x2 = x;
	int x3 = x + 1;
	int y1 = y - 1;
	int y2 = y;
	int y3 = y + 1;
	CLAMP(x1, 0, getWidth() - 1);
	CLAMP(x2, 0, getWidth() - 1);
	CLAMP(x3, 0, getWidth() - 1);
	CLAMP(y1, 0, getHeight() - 1);
	CLAMP(y2, 0, getHeight() - 1);
	CLAMP(y3, 0, getHeight() - 1);
	float value[4];
	this->m_inputValueOperation->read(value, x2, y2, NULL);
	const float mval = 1.0f - value[0];

	zero_v4(output);
	this->m_inputOperation->read(in1, x1, y1, NULL);
	madd_v4_v4fl(output, in1, this->m_filter[0]);
	this->m_inputOperation->read(in1, x2, y1, NULL);
	madd_v4_v4fl(output, in1, this->m_filter[1]);
	this->m_inputOperation->read(in1, x3, y1, NULL);
	madd_v4_v4fl(output, in1, this->m_filter[2]);
	this->m_inputOperation->read(in1, x1, y2, NULL);
	madd_v4_v4fl(output, in1, this->m_filter[3]);
	this->m_inputOperation->read(in2, x2, y2, NULL);
	madd_v4_v4fl(output, in2, this->m_filter[4]);
	this->m_inputOperation->read(in1, x3, y2, NULL);
	madd_v4_v4fl(output, in1, this->m_filter[5]);
	this->m_inputOperation->read(in1, x1, y3, NULL);
	madd_v4_v4fl(output, in1, this->m_filter[6]);
	this->m_inputOperation->read(in1, x2, y3, NULL);
	madd_v4_v4fl(output, in1, this->m_filter[7]);
	this->m_inputOperation->read(in1, x3, y3, NULL);
	madd_v4_v4fl(output, in1, this->m_filter[8]);

	output[0] = output[0] * value[0] + in2[0] * mval;
	output[1] = output[1] * value[0] + in2[1] * mval;
	output[2] = output[2] * value[0] + in2[2] * mval;
	output[3] = output[3] * value[0] + in2[3] * mval;

	/* Make sure we don't return negative color. */
	output[0] = max(output[0], 0.0f);
	output[1] = max(output[1], 0.0f);
	output[2] = max(output[2], 0.0f);
	output[3] = max(output[3], 0.0f);
}
Esempio n. 14
0
static void move_stack(bNodeStack *to, bNodeStack *from)
{
	if (to != from) {
		copy_v4_v4(to->vec, from->vec);
		to->data = from->data;
		to->datatype = from->datatype;
		to->is_copy = from->is_copy;
		
		zero_v4(from->vec);
		from->data = NULL;
		from->datatype = 0;
		from->is_copy = 0;
	}
}
Esempio n. 15
0
void RenderLayersProg::doInterpolation(float output[4], float x, float y, PixelSampler sampler)
{
  unsigned int offset;
  int width = this->getWidth(), height = this->getHeight();

  int ix = x, iy = y;
  if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
    if (this->m_elementsize == 1) {
      output[0] = 0.0f;
    }
    else if (this->m_elementsize == 3) {
      zero_v3(output);
    }
    else {
      zero_v4(output);
    }
    return;
  }

  switch (sampler) {
    case COM_PS_NEAREST: {
      offset = (iy * width + ix) * this->m_elementsize;

      if (this->m_elementsize == 1) {
        output[0] = this->m_inputBuffer[offset];
      }
      else if (this->m_elementsize == 3) {
        copy_v3_v3(output, &this->m_inputBuffer[offset]);
      }
      else {
        copy_v4_v4(output, &this->m_inputBuffer[offset]);
      }
      break;
    }

    case COM_PS_BILINEAR:
      BLI_bilinear_interpolation_fl(
          this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
      break;

    case COM_PS_BICUBIC:
      BLI_bicubic_interpolation_fl(
          this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
      break;
  }
}
Esempio n. 16
0
static GPUTexture *create_flame_spectrum_texture(void)
{
#define SPEC_WIDTH 256
#define FIRE_THRESH 7
#define MAX_FIRE_ALPHA 0.06f
#define FULL_ON_FIRE 100

	GPUTexture *tex;
	int i, j, k;
	float *spec_data = MEM_mallocN(SPEC_WIDTH * 4 * sizeof(float), "spec_data");
	float *spec_pixels = MEM_mallocN(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float), "spec_pixels");

	blackbody_temperature_to_rgb_table(spec_data, SPEC_WIDTH, 1500, 3000);

	for (i = 0; i < 16; i++) {
		for (j = 0; j < 16; j++) {
			for (k = 0; k < SPEC_WIDTH; k++) {
				int index = (j * SPEC_WIDTH * 16 + i * SPEC_WIDTH + k) * 4;
				if (k >= FIRE_THRESH) {
					spec_pixels[index] = (spec_data[k * 4]);
					spec_pixels[index + 1] = (spec_data[k * 4 + 1]);
					spec_pixels[index + 2] = (spec_data[k * 4 + 2]);
					spec_pixels[index + 3] = MAX_FIRE_ALPHA * (
					        (k > FULL_ON_FIRE) ? 1.0f : (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH));
				}
				else {
					zero_v4(&spec_pixels[index]);
				}
			}
		}
	}

	tex = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL);

	MEM_freeN(spec_data);
	MEM_freeN(spec_pixels);

#undef SPEC_WIDTH
#undef FIRE_THRESH
#undef MAX_FIRE_ALPHA
#undef FULL_ON_FIRE

	return tex;
}
void NodeOperationBuilder::add_input_constant_value(NodeOperationInput *input, NodeInput *node_input)
{
	switch (input->getDataType()) {
		case COM_DT_VALUE: {
			float value;
			if (node_input && node_input->getbNodeSocket())
				value = node_input->getEditorValueFloat();
			else
				value = 0.0f;
			
			SetValueOperation *op = new SetValueOperation();
			op->setValue(value);
			addOperation(op);
			addLink(op->getOutputSocket(), input);
			break;
		}
		case COM_DT_COLOR: {
			float value[4];
			if (node_input && node_input->getbNodeSocket())
				node_input->getEditorValueColor(value);
			else
				zero_v4(value);
			
			SetColorOperation *op = new SetColorOperation();
			op->setChannels(value);
			addOperation(op);
			addLink(op->getOutputSocket(), input);
			break;
		}
		case COM_DT_VECTOR: {
			float value[3];
			if (node_input && node_input->getbNodeSocket())
				node_input->getEditorValueVector(value);
			else
				zero_v3(value);
			
			SetVectorOperation *op = new SetVectorOperation();
			op->setVector(value);
			addOperation(op);
			addLink(op->getOutputSocket(), input);
			break;
		}
	}
}
void PlaneDistortWarpImageOperation::executePixelSampled(float output[4],
                                                         float x,
                                                         float y,
                                                         PixelSampler /*sampler*/)
{
  float uv[2];
  float deriv[2][2];
  if (this->m_motion_blur_samples == 1) {
    warpCoord(x, y, this->m_samples[0].perspectiveMatrix, uv, deriv);
    m_pixelReader->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1]);
  }
  else {
    zero_v4(output);
    for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
      float color[4];
      warpCoord(x, y, this->m_samples[sample].perspectiveMatrix, uv, deriv);
      m_pixelReader->readFiltered(color, uv[0], uv[1], deriv[0], deriv[1]);
      add_v4_v4(output, color);
    }
    mul_v4_fl(output, 1.0f / (float)this->m_motion_blur_samples);
  }
}
Esempio n. 19
0
void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4], struct ImagePool *pool)
{
	TexResult texres;
	ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, NULL, pool);
	
	if (UNLIKELY(ibuf == NULL)) {
		zero_v4(result);
		return;
	}
	
	if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
		ibuf->rect+= (ibuf->x*ibuf->y);

	texres.talpha = true; /* boxsample expects to be initialized */
	boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1);
	copy_v4_v4(result, &texres.tr);
	
	if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
		ibuf->rect-= (ibuf->x*ibuf->y);

	ima->flag|= IMA_USED_FOR_RENDER;

	BKE_image_pool_release_ibuf(ima, ibuf, pool);
}
Esempio n. 20
0
/* BICUBIC INTERPOLATION */
BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer, const float *float_buffer,
                                      unsigned char *byte_output, float *float_output, int width, int height,
                                      int components, float u, float v)
{
	int i, j, n, m, x1, y1;
	float a, b, w, wx, wy[4], out[4];

	/* sample area entirely outside image? */
	if (ceil(u) < 0 || floor(u) > width - 1 || ceil(v) < 0 || floor(v) > height - 1) {
		if (float_output)
			float_output[0] = float_output[1] = float_output[2] = float_output[3] = 0.0f;
		if (byte_output)
			byte_output[0] = byte_output[1] = byte_output[2] = byte_output[3] = 0;
		return;
	}

	i = (int)floor(u);
	j = (int)floor(v);
	a = u - (float)i;
	b = v - (float)j;

	zero_v4(out);

/* Optimized and not so easy to read */

	/* avoid calling multiple times */
	wy[0] = P(b - (-1));
	wy[1] = P(b -  0);
	wy[2] = P(b -  1);
	wy[3] = P(b -  2);

	for (n = -1; n <= 2; n++) {
		x1 = i + n;
		CLAMP(x1, 0, width - 1);
		wx = P((float)n - a);
		for (m = -1; m <= 2; m++) {
			float data[4];

			y1 = j + m;
			CLAMP(y1, 0, height - 1);
			/* normally we could do this */
			/* w = P(n-a) * P(b-m); */
			/* except that would call P() 16 times per pixel therefor pow() 64 times, better precalc these */
			w = wx * wy[m + 1];

			if (float_output) {
				const float *float_data = float_buffer + width * y1 * components + components * x1;

				vector_from_float(float_data, data, components);
			}
			else {
				const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;

				vector_from_byte(byte_data, data, components);
			}

			if (components == 1) {
				out[0] += data[0] * w;
			}
			else if (components == 3) {
				out[0] += data[0] * w;
				out[1] += data[1] * w;
				out[2] += data[2] * w;
			}
			else {
				out[0] += data[0] * w;
				out[1] += data[1] * w;
				out[2] += data[2] * w;
				out[3] += data[3] * w;
			}
		}
	}

/* Done with optimized part */

#if 0
	/* older, slower function, works the same as above */
	for (n = -1; n <= 2; n++) {
		for (m = -1; m <= 2; m++) {
			x1 = i + n;
			y1 = j + m;
			if (x1 > 0 && x1 < width && y1 > 0 && y1 < height) {
				float data[4];

				if (float_output) {
					const float *float_data = float_buffer + width * y1 * components + components * x1;

					vector_from_float(float_data, data, components);
				}
				else {
					const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;

					vector_from_byte(byte_data, data, components);
				}

				if (components == 1) {
					out[0] += data[0] * P(n - a) * P(b - m);
				}
				else if (components == 3) {
					out[0] += data[0] * P(n - a) * P(b - m);
					out[1] += data[1] * P(n - a) * P(b - m);
					out[2] += data[2] * P(n - a) * P(b - m);
				}
				else {
					out[0] += data[0] * P(n - a) * P(b - m);
					out[1] += data[1] * P(n - a) * P(b - m);
					out[2] += data[2] * P(n - a) * P(b - m);
					out[3] += data[3] * P(n - a) * P(b - m);
				}
			}
		}
	}
#endif

	if (float_output) {
		if (components == 1) {
			float_output[0] = out[0];
		}
		else if (components == 3) {
			copy_v3_v3(float_output, out);
		}
		else {
			copy_v4_v4(float_output, out);
		}
	}
	else {
		if (components == 1) {
			byte_output[0] = (unsigned char)(out[0] + 0.5f);
		}
		else if (components == 3) {
			byte_output[0] = (unsigned char)(out[0] + 0.5f);
			byte_output[1] = (unsigned char)(out[1] + 0.5f);
			byte_output[2] = (unsigned char)(out[2] + 0.5f);
		}
		else {
			byte_output[0] = (unsigned char)(out[0] + 0.5f);
			byte_output[1] = (unsigned char)(out[1] + 0.5f);
			byte_output[2] = (unsigned char)(out[2] + 0.5f);
			byte_output[3] = (unsigned char)(out[3] + 0.5f);
		}
	}
}
Esempio n. 21
0
/**
 * Filtering method based on
 * "Creating raster omnimax images from multiple perspective views using the elliptical weighted average filter"
 * by Ned Greene and Paul S. Heckbert (1986)
 */
void MemoryBuffer::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler)
{
	zero_v4(result);
	int width = this->getWidth(), height = this->getHeight();
	if (width == 0 || height == 0)
		return;

	float u = uv[0], v = uv[1];
	float Ux = derivatives[0][0], Vx = derivatives[1][0], Uy = derivatives[0][1], Vy = derivatives[1][1];
	float A, B, C, F, ue, ve;
	ellipse_params(Ux, Uy, Vx, Vy, A, B, C, F, ue, ve);

	/* Note: highly eccentric ellipses can lead to large texture space areas to filter!
	 * This is limited somewhat by the EWA_WTS size in the loop, but a nicer approach
	 * could be the one found in
	 * "High Quality Elliptical Texture Filtering on GPU"
	 * by Pavlos Mavridis and Georgios Papaioannou
	 * in which the eccentricity of the ellipse is clamped.
	 */

	int U0 = (int)u;
	int V0 = (int)v;
	/* pixel offset for interpolation */
	float ufac = u - floorf(u), vfac = v - floorf(v);
	/* filter size */
	int u1 = (int)(u - ue);
	int u2 = (int)(u + ue);
	int v1 = (int)(v - ve);
	int v2 = (int)(v + ve);

	/* sane clamping to avoid unnecessarily huge loops */
	/* note: if eccentricity gets clamped (see above),
	 * the ue/ve limits can also be lowered accordingly
	 */
	if (U0 - u1 > EWA_MAXIDX) u1 = U0 - EWA_MAXIDX;
	if (u2 - U0 > EWA_MAXIDX) u2 = U0 + EWA_MAXIDX;
	if (V0 - v1 > EWA_MAXIDX) v1 = V0 - EWA_MAXIDX;
	if (v2 - V0 > EWA_MAXIDX) v2 = V0 + EWA_MAXIDX;

	float DDQ = 2.0f * A;
	float U = u1 - U0;
	float ac1 = A * (2.0f * U + 1.0f);
	float ac2 = A * U * U;
	float BU = B * U;

	float sum = 0.0f;
	for (int v = v1; v <= v2; ++v) {
		float V = v - V0;

		float DQ = ac1 + B * V;
		float Q = (C * V + BU) * V + ac2;
		for (int u = u1; u <= u2; ++u) {
			if (Q < F) {
				float tc[4];
				const float wt = EWA_WTS[CLAMPIS((int)Q, 0, EWA_MAXIDX)];
				switch (sampler) {
					case COM_PS_NEAREST: read(tc, u, v); break;
					case COM_PS_BILINEAR: readBilinear(tc, (float)u + ufac, (float)v + vfac); break;
					case COM_PS_BICUBIC: readBilinear(tc, (float)u + ufac, (float)v + vfac); break; /* XXX no readBicubic method yet */
					default: zero_v4(tc); break;
				}
				madd_v4_v4fl(result, tc, wt);
				sum += wt;
			}
			Q += DQ;
			DQ += DDQ;
		}
	}
	
	mul_v4_fl(result, (sum != 0.0f ? 1.0f / sum : 0.0f));
}
Esempio n. 22
0
/* used by node view too */
void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_default_view, int channels, int x, int y,
                        const unsigned char cp[4], const float fp[4], int *zp, float *zpf)
{
	char str[256];
	float dx = 6;
	/* text colors */
	/* XXX colored text not allowed in Blender UI */
	#if 0
	unsigned char red[3] = {255, 50, 50};
	unsigned char green[3] = {0, 255, 0};
	unsigned char blue[3] = {100, 100, 255};
	#else
	unsigned char red[3] = {255, 255, 255};
	unsigned char green[3] = {255, 255, 255};
	unsigned char blue[3] = {255, 255, 255};
	#endif
	float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0;
	float col[4], finalcol[4];

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);

	/* noisy, high contrast make impossible to read if lower alpha is used. */
	glColor4ub(0, 0, 0, 190);
	glRecti(0.0, 0.0, BLI_rcti_size_x(&ar->winrct) + 1, 20);
	glDisable(GL_BLEND);

	BLF_size(blf_mono_font, 11, 72);

	glColor3ub(255, 255, 255);
	BLI_snprintf(str, sizeof(str), "X:%-4d  Y:%-4d |", x, y);
	// UI_DrawString(6, 6, str); // works ok but fixed width is nicer.
	BLF_position(blf_mono_font, dx, 6, 0);
	BLF_draw_ascii(blf_mono_font, str, sizeof(str));
	dx += BLF_width(blf_mono_font, str);

	if (zp) {
		glColor3ub(255, 255, 255);
		BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff));
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
	}
	if (zpf) {
		glColor3ub(255, 255, 255);
		BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
	}

	if (channels >= 3) {
		glColor3ubv(red);
		if (fp)
			BLI_snprintf(str, sizeof(str), "  R:%-.5f", fp[0]);
		else if (cp)
			BLI_snprintf(str, sizeof(str), "  R:%-3d", cp[0]);
		else
			BLI_snprintf(str, sizeof(str), "  R:-");
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
		
		glColor3ubv(green);
		if (fp)
			BLI_snprintf(str, sizeof(str), "  G:%-.5f", fp[1]);
		else if (cp)
			BLI_snprintf(str, sizeof(str), "  G:%-3d", cp[1]);
		else
			BLI_snprintf(str, sizeof(str), "  G:-");
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
		
		glColor3ubv(blue);
		if (fp)
			BLI_snprintf(str, sizeof(str), "  B:%-.5f", fp[2]);
		else if (cp)
			BLI_snprintf(str, sizeof(str), "  B:%-3d", cp[2]);
		else
			BLI_snprintf(str, sizeof(str), "  B:-");
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
		
		if (channels == 4) {
			glColor3ub(255, 255, 255);
			if (fp)
				BLI_snprintf(str, sizeof(str), "  A:%-.4f", fp[3]);
			else if (cp)
				BLI_snprintf(str, sizeof(str), "  A:%-3d", cp[3]);
			else
				BLI_snprintf(str, sizeof(str), "- ");
			BLF_position(blf_mono_font, dx, 6, 0);
			BLF_draw_ascii(blf_mono_font, str, sizeof(str));
			dx += BLF_width(blf_mono_font, str);
		}

		if (color_manage && channels == 4) {
			float pixel[4];

			if (use_default_view)
				IMB_colormanagement_pixel_to_display_space_v4(pixel, fp,  NULL, &scene->display_settings);
			else
				IMB_colormanagement_pixel_to_display_space_v4(pixel, fp,  &scene->view_settings, &scene->display_settings);

			BLI_snprintf(str, sizeof(str), "  |  CM  R:%-.4f  G:%-.4f  B:%-.4f", pixel[0], pixel[1], pixel[2]);
			BLF_position(blf_mono_font, dx, 6, 0);
			BLF_draw_ascii(blf_mono_font, str, sizeof(str));
			dx += BLF_width(blf_mono_font, str);
		}
	}
	
	/* color rectangle */
	if (channels == 1) {
		if (fp) {
			col[0] = col[1] = col[2] = fp[0];
		}
		else if (cp) {
			col[0] = col[1] = col[2] = (float)cp[0] / 255.0f;
		}
		else {
			col[0] = col[1] = col[2] = 0.0f;
		}
		col[3] = 1.0f;
	}
	else if (channels == 3) {
		if (fp) {
			copy_v3_v3(col, fp);
		}
		else if (cp) {
			rgb_uchar_to_float(col, cp);
		}
		else {
			zero_v3(col);
		}
		col[3] = 1.0f;
	}
	else if (channels == 4) {
		if (fp)
			copy_v4_v4(col, fp);
		else if (cp) {
			rgba_uchar_to_float(col, cp);
		}
		else {
			zero_v4(col);
		}
	}
	else {
		BLI_assert(0);
		zero_v4(col);
	}

	if (color_manage) {
		if (use_default_view)
			IMB_colormanagement_pixel_to_display_space_v4(finalcol, col,  NULL, &scene->display_settings);
		else
			IMB_colormanagement_pixel_to_display_space_v4(finalcol, col,  &scene->view_settings, &scene->display_settings);
	}
	else {
		copy_v4_v4(finalcol, col);
	}

	glDisable(GL_BLEND);
	glColor3fv(finalcol);
	dx += 5;
	glBegin(GL_QUADS);
	glVertex2f(dx, 3);
	glVertex2f(dx, 17);
	glVertex2f(dx + 30, 17);
	glVertex2f(dx + 30, 3);
	glEnd();

	/* draw outline */
	glColor3ub(128, 128, 128);
	glBegin(GL_LINE_LOOP);
	glVertex2f(dx, 3);
	glVertex2f(dx, 17);
	glVertex2f(dx + 30, 17);
	glVertex2f(dx + 30, 3);
	glEnd();

	dx += 35;

	glColor3ub(255, 255, 255);
	if (channels == 1) {
		if (fp) {
			rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val);
			rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v);
		}
		else if (cp) {
			rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &hue, &sat, &val);
			rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &lum, &u, &v);
		}
		
		BLI_snprintf(str, sizeof(str), "V:%-.4f", val);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);

		BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
	}
	else if (channels >= 3) {
		if (fp) {
			rgb_to_hsv(fp[0], fp[1], fp[2], &hue, &sat, &val);
			rgb_to_yuv(fp[0], fp[1], fp[2], &lum, &u, &v);
		}
		else if (cp) {
			rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[1] / 255.0f, (float)cp[2] / 255.0f, &hue, &sat, &val);
			rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[1] / 255.0f, (float)cp[2] / 255.0f, &lum, &u, &v);
		}

		BLI_snprintf(str, sizeof(str), "H:%-.4f", hue);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);

		BLI_snprintf(str, sizeof(str), "  S:%-.4f", sat);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);

		BLI_snprintf(str, sizeof(str), "  V:%-.4f", val);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);

		BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
	}

	(void)dx;
}
Esempio n. 23
0
void RenderLayersProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
#if 0
  const RenderData *rd = this->m_rd;

  int dx = 0, dy = 0;

  if (rd->mode & R_BORDER && rd->mode & R_CROP) {
    /* see comment in executeRegion describing coordinate mapping,
     * here it simply goes other way around
     */
    int full_width = rd->xsch * rd->size / 100;
    int full_height = rd->ysch * rd->size / 100;

    dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f;
    dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f;
  }

  int ix = x - dx;
  int iy = y - dy;
#endif

#ifndef NDEBUG
  {
    const DataType data_type = this->getOutputSocket()->getDataType();
    int actual_element_size = this->m_elementsize;
    int expected_element_size;
    if (data_type == COM_DT_VALUE) {
      expected_element_size = 1;
    }
    else if (data_type == COM_DT_VECTOR) {
      expected_element_size = 3;
    }
    else if (data_type == COM_DT_COLOR) {
      expected_element_size = 4;
    }
    else {
      expected_element_size = 0;
      BLI_assert(!"Something horribly wrong just happened");
    }
    BLI_assert(expected_element_size == actual_element_size);
  }
#endif

  if (this->m_inputBuffer == NULL) {
    int elemsize = this->m_elementsize;
    if (elemsize == 1) {
      output[0] = 0.0f;
    }
    else if (elemsize == 3) {
      zero_v3(output);
    }
    else {
      BLI_assert(elemsize == 4);
      zero_v4(output);
    }
  }
  else {
    doInterpolation(output, x, y, sampler);
  }
}
Esempio n. 24
0
void BLI_ewa_filter(const int width, const int height,
                    const bool intpol,
                    const bool use_alpha,
                    const float uv[2],
                    const float du[2],
                    const float dv[2],
                    ewa_filter_read_pixel_cb read_pixel_cb,
                    void *userdata,
                    float result[4])
{
	/* scaling dxt/dyt by full resolution can cause overflow because of huge A/B/C and esp. F values,
	 * scaling by aspect ratio alone does the opposite, so try something in between instead... */
	const float ff2 = (float)width, ff = sqrtf(ff2), q = (float)height / ff;
	const float Ux = du[0] * ff, Vx = du[1] * q, Uy = dv[0] * ff, Vy = dv[1] * q;
	float A = Vx * Vx + Vy * Vy;
	float B = -2.0f * (Ux * Vx + Uy * Vy);
	float C = Ux * Ux + Uy * Uy;
	float F = A * C - B * B * 0.25f;
	float a, b, th, ecc, a2, b2, ue, ve, U0, V0, DDQ, U, ac1, ac2, BU, d;
	int u, v, u1, u2, v1, v2;

	/* The so-called 'high' quality ewa method simply adds a constant of 1 to both A & C,
	 * so the ellipse always covers at least some texels. But since the filter is now always larger,
	 * it also means that everywhere else it's also more blurry then ideally should be the case.
	 * So instead here the ellipse radii are modified instead whenever either is too low.
	 * Use a different radius based on interpolation switch, just enough to anti-alias when interpolation is off,
	 * and slightly larger to make result a bit smoother than bilinear interpolation when interpolation is on
	 * (minimum values: const float rmin = intpol ? 1.f : 0.5f;) */
	const float rmin = (intpol ? 1.5625f : 0.765625f) / ff2;
	BLI_ewa_imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
	if ((b2 = b * b) < rmin) {
		if ((a2 = a * a) < rmin) {
			B = 0.0f;
			A = C = rmin;
			F = A * C;
		}
		else {
			b2 = rmin;
			radangle2imp(a2, b2, th, &A, &B, &C, &F);
		}
	}

	ue = ff * sqrtf(C);
	ve = ff * sqrtf(A);
	d = (float)(EWA_MAXIDX + 1) / (F * ff2);
	A *= d;
	B *= d;
	C *= d;

	U0 = uv[0] * (float)width;
	V0 = uv[1] * (float)height;
	u1 = (int)(floorf(U0 - ue));
	u2 = (int)(ceilf(U0 + ue));
	v1 = (int)(floorf(V0 - ve));
	v2 = (int)(ceilf(V0 + ve));

	/* sane clamping to avoid unnecessarily huge loops */
	/* note: if eccentricity gets clamped (see above),
	 * the ue/ve limits can also be lowered accordingly
	 */
	if (U0 - (float)u1 > EWA_MAXIDX) u1 = (int)U0 - EWA_MAXIDX;
	if ((float)u2 - U0 > EWA_MAXIDX) u2 = (int)U0 + EWA_MAXIDX;
	if (V0 - (float)v1 > EWA_MAXIDX) v1 = (int)V0 - EWA_MAXIDX;
	if ((float)v2 - V0 > EWA_MAXIDX) v2 = (int)V0 + EWA_MAXIDX;

	/* Early output check for cases the whole region is outside of the buffer. */
	if ((u2 < 0 || u1 >= width) ||  (v2 < 0 || v1 >= height)) {
		zero_v4(result);
		return;
	}

	U0 -= 0.5f;
	V0 -= 0.5f;
	DDQ = 2.0f * A;
	U = (float)u1 - U0;
	ac1 = A * (2.0f * U + 1.0f);
	ac2 = A * U * U;
	BU = B * U;

	d = 0.0f;
	zero_v4(result);
	for (v = v1; v <= v2; ++v) {
		const float V = (float)v - V0;
		float DQ = ac1 + B * V;
		float Q = (C * V + BU) * V + ac2;
		for (u = u1; u <= u2; ++u) {
			if (Q < (float)(EWA_MAXIDX + 1)) {
				float tc[4];
				const float wt = EWA_WTS[(Q < 0.0f) ? 0 : (unsigned int)Q];
				read_pixel_cb(userdata, u, v, tc);
				madd_v3_v3fl(result, tc, wt);
				result[3] += use_alpha ? tc[3] * wt : 0.0f;
				d += wt;
			}
			Q += DQ;
			DQ += DDQ;
		}
	}

	/* d should hopefully never be zero anymore */
	d = 1.0f / d;
	mul_v3_fl(result, d);
	/* clipping can be ignored if alpha used, texr->ta already includes filtered edge */
	result[3] = use_alpha ? result[3] * d : 1.0f;
}
Esempio n. 25
0
/* used by node view too */
void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_default_view, int channels, int x, int y,
                        const unsigned char cp[4], const float fp[4], const float linearcol[4], int *zp, float *zpf)
{
	rcti color_rect;
	char str[256];
	int dx = 6;
	const int dy = 0.3f * UI_UNIT_Y;
	/* text colors */
	/* XXX colored text not allowed in Blender UI */
#if 0
	unsigned char red[3] = {255, 50, 50};
	unsigned char green[3] = {0, 255, 0};
	unsigned char blue[3] = {100, 100, 255};
#else
	unsigned char red[3] = {255, 255, 255};
	unsigned char green[3] = {255, 255, 255};
	unsigned char blue[3] = {255, 255, 255};
#endif
	float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0;
	float col[4], finalcol[4];

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);

	/* noisy, high contrast make impossible to read if lower alpha is used. */
	glColor4ub(0, 0, 0, 190);
	glRecti(0.0, 0.0, BLI_rcti_size_x(&ar->winrct) + 1, UI_UNIT_Y);
	glDisable(GL_BLEND);

	BLF_size(blf_mono_font, 11 * U.pixelsize, U.dpi);

	glColor3ub(255, 255, 255);
	BLI_snprintf(str, sizeof(str), "X:%-4d  Y:%-4d |", x, y);
	BLF_position(blf_mono_font, dx, dy, 0);
	BLF_draw_ascii(blf_mono_font, str, sizeof(str));
	dx += BLF_width(blf_mono_font, str, sizeof(str));

	if (zp) {
		glColor3ub(255, 255, 255);
		BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff));
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
	}
	if (zpf) {
		glColor3ub(255, 255, 255);
		BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
	}

	if (channels >= 3) {
		glColor3ubv(red);
		if (fp)
			BLI_snprintf(str, sizeof(str), "  R:%-.5f", fp[0]);
		else if (cp)
			BLI_snprintf(str, sizeof(str), "  R:%-3d", cp[0]);
		else
			BLI_snprintf(str, sizeof(str), "  R:-");
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
		
		glColor3ubv(green);
		if (fp)
			BLI_snprintf(str, sizeof(str), "  G:%-.5f", fp[1]);
		else if (cp)
			BLI_snprintf(str, sizeof(str), "  G:%-3d", cp[1]);
		else
			BLI_snprintf(str, sizeof(str), "  G:-");
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
		
		glColor3ubv(blue);
		if (fp)
			BLI_snprintf(str, sizeof(str), "  B:%-.5f", fp[2]);
		else if (cp)
			BLI_snprintf(str, sizeof(str), "  B:%-3d", cp[2]);
		else
			BLI_snprintf(str, sizeof(str), "  B:-");
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
		
		if (channels == 4) {
			glColor3ub(255, 255, 255);
			if (fp)
				BLI_snprintf(str, sizeof(str), "  A:%-.4f", fp[3]);
			else if (cp)
				BLI_snprintf(str, sizeof(str), "  A:%-3d", cp[3]);
			else
				BLI_snprintf(str, sizeof(str), "- ");
			BLF_position(blf_mono_font, dx, dy, 0);
			BLF_draw_ascii(blf_mono_font, str, sizeof(str));
			dx += BLF_width(blf_mono_font, str, sizeof(str));
		}

		if (color_manage) {
			float rgba[4];

			copy_v3_v3(rgba, linearcol);
			if (channels == 3)
				rgba[3] = 1.0f;
			else
				rgba[3] = linearcol[3];

			if (use_default_view)
				IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba,  NULL, &scene->display_settings);
			else
				IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba,  &scene->view_settings, &scene->display_settings);

			BLI_snprintf(str, sizeof(str), "  |  CM  R:%-.4f  G:%-.4f  B:%-.4f", rgba[0], rgba[1], rgba[2]);
			BLF_position(blf_mono_font, dx, dy, 0);
			BLF_draw_ascii(blf_mono_font, str, sizeof(str));
			dx += BLF_width(blf_mono_font, str, sizeof(str));
		}
	}
	
	/* color rectangle */
	if (channels == 1) {
		if (fp) {
			col[0] = col[1] = col[2] = fp[0];
		}
		else if (cp) {
			col[0] = col[1] = col[2] = (float)cp[0] / 255.0f;
		}
		else {
			col[0] = col[1] = col[2] = 0.0f;
		}
		col[3] = 1.0f;
	}
	else if (channels == 3) {
		copy_v3_v3(col, linearcol);
		col[3] = 1.0f;
	}
	else if (channels == 4) {
		copy_v4_v4(col, linearcol);
	}
	else {
		BLI_assert(0);
		zero_v4(col);
	}

	if (color_manage) {
		if (use_default_view)
			IMB_colormanagement_pixel_to_display_space_v4(finalcol, col,  NULL, &scene->display_settings);
		else
			IMB_colormanagement_pixel_to_display_space_v4(finalcol, col,  &scene->view_settings, &scene->display_settings);
	}
	else {
		copy_v4_v4(finalcol, col);
	}

	glDisable(GL_BLEND);
	dx += 0.25f * UI_UNIT_X;

	BLI_rcti_init(&color_rect, dx, dx + (1.5f * UI_UNIT_X), 0.15f * UI_UNIT_Y, 0.85f * UI_UNIT_Y);

	if (channels == 4) {
		rcti color_rect_half;
		int color_quater_x, color_quater_y;

		color_rect_half = color_rect;
		color_rect_half.xmax = BLI_rcti_cent_x(&color_rect);
		glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);

		color_rect_half = color_rect;
		color_rect_half.xmin = BLI_rcti_cent_x(&color_rect);

		color_quater_x = BLI_rcti_cent_x(&color_rect_half);
		color_quater_y = BLI_rcti_cent_y(&color_rect_half);

		glColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255);
		glRecti(color_rect_half.xmin, color_rect_half.ymin, color_rect_half.xmax, color_rect_half.ymax);

		glColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255);
		glRecti(color_quater_x, color_quater_y, color_rect_half.xmax, color_rect_half.ymax);
		glRecti(color_rect_half.xmin, color_rect_half.ymin, color_quater_x, color_quater_y);

		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glColor4f(UNPACK3(finalcol), fp ? fp[3] : (cp[3] / 255.0f));
		glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
		glDisable(GL_BLEND);
	}
	else {
		glColor3fv(finalcol);
		glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
	}

	/* draw outline */
	glColor3ub(128, 128, 128);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	dx += 1.75f * UI_UNIT_X;

	glColor3ub(255, 255, 255);
	if (channels == 1) {
		if (fp) {
			rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val);
			rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v);
		}
		else if (cp) {
			rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &hue, &sat, &val);
			rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &lum, &u, &v);
		}
		
		BLI_snprintf(str, sizeof(str), "V:%-.4f", val);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));

		BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
	}
	else if (channels >= 3) {
		rgb_to_hsv(finalcol[0], finalcol[1], finalcol[2], &hue, &sat, &val);
		rgb_to_yuv(finalcol[0], finalcol[1], finalcol[2], &lum, &u, &v);

		BLI_snprintf(str, sizeof(str), "H:%-.4f", hue);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));

		BLI_snprintf(str, sizeof(str), "  S:%-.4f", sat);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));

		BLI_snprintf(str, sizeof(str), "  V:%-.4f", val);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));

		BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
	}

	(void)dx;
}
Esempio n. 26
0
/* Generic texture sampler for 3D painting systems. point has to be either in
 * region space mouse coordinates, or 3d world coordinates for 3D mapping.
 *
 * rgba outputs straight alpha. */
float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
                              const float point[3],
                              float rgba[4], const int thread,
                              struct ImagePool *pool)
{
	UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
	MTex *mtex = &br->mtex;
	float intensity = 1.0;
	bool hasrgb = false;

	if (!mtex->tex) {
		intensity = 1;
	}
	else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
		/* Get strength by feeding the vertex
		 * location directly into a texture */
		hasrgb = externtex(mtex, point, &intensity,
		                   rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}
	else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
		float rotation = -mtex->rot;
		float point_2d[2] = {point[0], point[1]};
		float x, y;
		float co[3];

		x = point_2d[0] - br->stencil_pos[0];
		y = point_2d[1] - br->stencil_pos[1];

		if (rotation > 0.001f || rotation < -0.001f) {
			const float angle    = atan2f(y, x) + rotation;
			const float flen     = sqrtf(x * x + y * y);

			x = flen * cosf(angle);
			y = flen * sinf(angle);
		}

		if (fabsf(x) > br->stencil_dimension[0] || fabsf(y) > br->stencil_dimension[1]) {
			zero_v4(rgba);
			return 0.0f;
		}
		x /= (br->stencil_dimension[0]);
		y /= (br->stencil_dimension[1]);

		co[0] = x;
		co[1] = y;
		co[2] = 0.0f;

		hasrgb = externtex(mtex, co, &intensity,
		                   rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}
	else {
		float rotation = -mtex->rot;
		float point_2d[2] = {point[0], point[1]};
		float x = 0.0f, y = 0.0f; /* Quite warnings */
		float invradius = 1.0f; /* Quite warnings */
		float co[3];

		if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
			/* keep coordinates relative to mouse */

			rotation += ups->brush_rotation;

			x = point_2d[0] - ups->tex_mouse[0];
			y = point_2d[1] - ups->tex_mouse[1];

			/* use pressure adjusted size for fixed mode */
			invradius = 1.0f / ups->pixel_radius;
		}
		else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
			/* leave the coordinates relative to the screen */

			/* use unadjusted size for tiled mode */
			invradius = 1.0f / BKE_brush_size_get(scene, br);

			x = point_2d[0];
			y = point_2d[1];
		}
		else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
			rotation += ups->brush_rotation;
			/* these contain a random coordinate */
			x = point_2d[0] - ups->tex_mouse[0];
			y = point_2d[1] - ups->tex_mouse[1];

			invradius = 1.0f / ups->pixel_radius;
		}

		x *= invradius;
		y *= invradius;

		/* it is probably worth optimizing for those cases where
		 * the texture is not rotated by skipping the calls to
		 * atan2, sqrtf, sin, and cos. */
		if (rotation > 0.001f || rotation < -0.001f) {
			const float angle    = atan2f(y, x) + rotation;
			const float flen     = sqrtf(x * x + y * y);

			x = flen * cosf(angle);
			y = flen * sinf(angle);
		}

		co[0] = x;
		co[1] = y;
		co[2] = 0.0f;

		hasrgb = externtex(mtex, co, &intensity,
		                   rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}

	intensity += br->texture_sample_bias;

	if (!hasrgb) {
		rgba[0] = intensity;
		rgba[1] = intensity;
		rgba[2] = intensity;
		rgba[3] = 1.0f;
	}
	/* For consistency, sampling always returns color in linear space */
	else if (ups->do_linear_conversion) {
		IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, ups->colorspace);
	}

	return intensity;
}
Esempio n. 27
0
static void paint_2d_lift_soften(ImagePaintState *s, ImBuf *ibuf, ImBuf *ibufb, int *pos, const short tile)
{
	bool sharpen = (s->painter->cache.invert ^ ((s->brush->flag & BRUSH_DIR_IN) != 0));
	float threshold = s->brush->sharp_threshold;
	int x, y, xi, yi, xo, yo, xk, yk;
	float count;
	int out_off[2], in_off[2], dim[2];
	int diff_pos[2];
	float outrgb[4];
	float rgba[4];
	BlurKernel *kernel = s->blurkernel;

	dim[0] = ibufb->x;
	dim[1] = ibufb->y;
	in_off[0] = pos[0];
	in_off[1] = pos[1];
	out_off[0] = out_off[1] = 0;

	if (!tile) {
		IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
		             &out_off[1], &dim[0], &dim[1]);

		if ((dim[0] == 0) || (dim[1] == 0))
			return;
	}

	/* find offset inside mask buffers to sample them */
	sub_v2_v2v2_int(diff_pos, out_off, in_off);

	for (y = 0; y < dim[1]; y++) {
		for (x = 0; x < dim[0]; x++) {
			/* get input pixel */
			xi = in_off[0] + x;
			yi = in_off[1] + y;

			count = 0.0;
			if (tile) {
				paint_2d_ibuf_tile_convert(ibuf, &xi, &yi, tile);
				if (xi < ibuf->x && xi >= 0 && yi < ibuf->y && yi >= 0)
					paint_2d_ibuf_rgb_get(ibuf, xi, yi, rgba);
				else
					zero_v4(rgba);
			}
			else {
				/* coordinates have been clipped properly here, it should be safe to do this */
				paint_2d_ibuf_rgb_get(ibuf, xi, yi, rgba);
			}
			zero_v4(outrgb);

			for (yk = 0; yk < kernel->side; yk++) {
				for (xk = 0; xk < kernel->side; xk++) {
					count += paint_2d_ibuf_add_if(ibuf, xi + xk - kernel->pixel_len,
					                               yi + yk - kernel->pixel_len, outrgb, tile,
					                               kernel->wdata[xk + yk * kernel->side]);
				}
			}

			if (count > 0.0f) {
				mul_v4_fl(outrgb, 1.0f / (float)count);

				if (sharpen) {
					/* subtract blurred image from normal image gives high pass filter */
					sub_v3_v3v3(outrgb, rgba, outrgb);

					/* now rgba_ub contains the edge result, but this should be converted to luminance to avoid
					 * colored speckles appearing in final image, and also to check for threshold */
					outrgb[0] = outrgb[1] = outrgb[2] = IMB_colormanagement_get_luminance(outrgb);
					if (fabsf(outrgb[0]) > threshold) {
						float mask = BKE_brush_alpha_get(s->scene, s->brush);
						float alpha = rgba[3];
						rgba[3] = outrgb[3] = mask;

						/* add to enhance edges */
						blend_color_add_float(outrgb, rgba, outrgb);
						outrgb[3] = alpha;
					}
					else
						copy_v4_v4(outrgb, rgba);
				}
			}
			else
				copy_v4_v4(outrgb, rgba);
			/* write into brush buffer */
			xo = out_off[0] + x;
			yo = out_off[1] + y;
			paint_2d_ibuf_rgb_set(ibufb, xo, yo, 0, outrgb);
		}
	}
}
Esempio n. 28
0
void draw_image_info(ARegion *ar, int color_manage, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf)
{
	char str[256];
	float dx= 6;
	/* text colors */
	/* XXX colored text not allowed in Blender UI */
	#if 0
	unsigned char red[3] = {255, 50, 50};
	unsigned char green[3] = {0, 255, 0};
	unsigned char blue[3] = {100, 100, 255};
	#else
	unsigned char red[3] = {255, 255, 255};
	unsigned char green[3] = {255, 255, 255};
	unsigned char blue[3] = {255, 255, 255};
	#endif
	float hue=0, sat=0, val=0, lum=0, u=0, v=0;
	float col[4], finalcol[4];

	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);

	/* noisy, high contrast make impossible to read if lower alpha is used. */
	glColor4ub(0, 0, 0, 190);
	glRecti(0.0, 0.0, ar->winrct.xmax - ar->winrct.xmin + 1, 20);
	glDisable(GL_BLEND);

	BLF_size(blf_mono_font, 11, 72);

	glColor3ub(255, 255, 255);
	sprintf(str, "X:%-4d  Y:%-4d |", x, y);
	// UI_DrawString(6, 6, str); // works ok but fixed width is nicer.
	BLF_position(blf_mono_font, dx, 6, 0);
	BLF_draw_ascii(blf_mono_font, str, sizeof(str));
	dx += BLF_width(blf_mono_font, str);

	if(zp) {
		glColor3ub(255, 255, 255);
		sprintf(str, " Z:%-.4f |", 0.5f+0.5f*(((float)*zp)/(float)0x7fffffff));
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
	}
	if(zpf) {
		glColor3ub(255, 255, 255);
		sprintf(str, " Z:%-.3f |", *zpf);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
	}

	if(channels >= 3) {
		glColor3ubv(red);
		if (fp)
			sprintf(str, "  R:%-.4f", fp[0]);
		else if (cp)
			sprintf(str, "  R:%-3d", cp[0]);
		else
			sprintf(str, "  R:-");
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
		
		glColor3ubv(green);
		if (fp)
			sprintf(str, "  G:%-.4f", fp[1]);
		else if (cp)
			sprintf(str, "  G:%-3d", cp[1]);
		else
			sprintf(str, "  G:-");
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
		
		glColor3ubv(blue);
		if (fp)
			sprintf(str, "  B:%-.4f", fp[2]);
		else if (cp)
			sprintf(str, "  B:%-3d", cp[2]);
		else
			sprintf(str, "  B:-");
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
		
		if(channels == 4) {
			glColor3ub(255, 255, 255);
			if (fp)
				sprintf(str, "  A:%-.4f", fp[3]);
			else if (cp)
				sprintf(str, "  A:%-3d", cp[3]);
			else
				sprintf(str, "- ");
			BLF_position(blf_mono_font, dx, 6, 0);
			BLF_draw_ascii(blf_mono_font, str, sizeof(str));
			dx += BLF_width(blf_mono_font, str);
		}
	}
	
	/* color rectangle */
	if (channels==1) {
		if (fp)
			col[0] = col[1] = col[2] = fp[0];
		else if (cp)
			col[0] = col[1] = col[2] = (float)cp[0]/255.0f;
		else
			col[0] = col[1] = col[2] = 0.0f;
	}
	else if (channels==3) {
		if (fp)
			copy_v3_v3(col, fp);
		else if (cp) {
			col[0] = (float)cp[0]/255.0f;
			col[1] = (float)cp[1]/255.0f;
			col[2] = (float)cp[2]/255.0f;
		}
		else
			zero_v3(col);
	}
	else if (channels==4) {
		if (fp)
			copy_v4_v4(col, fp);
		else if (cp) {
			col[0] = (float)cp[0]/255.0f;
			col[1] = (float)cp[1]/255.0f;
			col[2] = (float)cp[2]/255.0f;
			col[3] = (float)cp[3]/255.0f;
		}
		else
			zero_v4(col);
	}
	if (color_manage) {
		linearrgb_to_srgb_v3_v3(finalcol, col);
		finalcol[3] = col[3];
	}
	else {
		copy_v4_v4(finalcol, col);
	}
	glDisable(GL_BLEND);
	glColor3fv(finalcol);
	dx += 5;
	glBegin(GL_QUADS);
	glVertex2f(dx, 3);
	glVertex2f(dx, 17);
	glVertex2f(dx+30, 17);
	glVertex2f(dx+30, 3);
	glEnd();
	dx += 35;

	glColor3ub(255, 255, 255);
	if(channels == 1) {
		if (fp) {
			rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val);
			rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v);
		}
		else if (cp) {
			rgb_to_hsv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &hue, &sat, &val);
			rgb_to_yuv((float)cp[0]/255.0f, (float)cp[0]/255.0f, (float)cp[0]/255.0f, &lum, &u, &v);
		}
		
		sprintf(str, "V:%-.4f", val);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);

		sprintf(str, "   L:%-.4f", lum);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
	}
	else if(channels >= 3) {
		if (fp) {
			rgb_to_hsv(fp[0], fp[1], fp[2], &hue, &sat, &val);
			rgb_to_yuv(fp[0], fp[1], fp[2], &lum, &u, &v);
		}
		else if (cp) {
			rgb_to_hsv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &hue, &sat, &val);
			rgb_to_yuv((float)cp[0]/255.0f, (float)cp[1]/255.0f, (float)cp[2]/255.0f, &lum, &u, &v);
		}

		sprintf(str, "H:%-.4f", hue);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);

		sprintf(str, "  S:%-.4f", sat);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);

		sprintf(str, "  V:%-.4f", val);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);

		sprintf(str, "   L:%-.4f", lum);
		BLF_position(blf_mono_font, dx, 6, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str);
	}

	(void)dx;
}
Esempio n. 29
0
float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
                               const float point[2],
                               const int thread,
                               struct ImagePool *pool)
{
	UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
	MTex *mtex = &br->mask_mtex;
	float rgba[4], intensity;

	if (!mtex->tex) {
		return 1.0f;
	}
	if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
		float rotation = -mtex->rot;
		float point_2d[2] = {point[0], point[1]};
		float x, y;
		float co[3];

		x = point_2d[0] - br->mask_stencil_pos[0];
		y = point_2d[1] - br->mask_stencil_pos[1];

		if (rotation > 0.001f || rotation < -0.001f) {
			const float angle    = atan2f(y, x) + rotation;
			const float flen     = sqrtf(x * x + y * y);

			x = flen * cosf(angle);
			y = flen * sinf(angle);
		}

		if (fabsf(x) > br->mask_stencil_dimension[0] || fabsf(y) > br->mask_stencil_dimension[1]) {
			zero_v4(rgba);
			return 0.0f;
		}
		x /= (br->mask_stencil_dimension[0]);
		y /= (br->mask_stencil_dimension[1]);

		co[0] = x;
		co[1] = y;
		co[2] = 0.0f;

		externtex(mtex, co, &intensity,
		          rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}
	else {
		float rotation = -mtex->rot;
		float point_2d[2] = {point[0], point[1]};
		float x = 0.0f, y = 0.0f; /* Quite warnings */
		float invradius = 1.0f; /* Quite warnings */
		float co[3];

		if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
			/* keep coordinates relative to mouse */

			rotation += ups->brush_rotation_sec;

			x = point_2d[0] - ups->mask_tex_mouse[0];
			y = point_2d[1] - ups->mask_tex_mouse[1];

			/* use pressure adjusted size for fixed mode */
			invradius = 1.0f / ups->pixel_radius;
		}
		else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
			/* leave the coordinates relative to the screen */

			/* use unadjusted size for tiled mode */
			invradius = 1.0f / BKE_brush_size_get(scene, br);

			x = point_2d[0];
			y = point_2d[1];
		}
		else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
			rotation += ups->brush_rotation_sec;
			/* these contain a random coordinate */
			x = point_2d[0] - ups->mask_tex_mouse[0];
			y = point_2d[1] - ups->mask_tex_mouse[1];

			invradius = 1.0f / ups->pixel_radius;
		}

		x *= invradius;
		y *= invradius;

		/* it is probably worth optimizing for those cases where
		 * the texture is not rotated by skipping the calls to
		 * atan2, sqrtf, sin, and cos. */
		if (rotation > 0.001f || rotation < -0.001f) {
			const float angle    = atan2f(y, x) + rotation;
			const float flen     = sqrtf(x * x + y * y);

			x = flen * cosf(angle);
			y = flen * sinf(angle);
		}

		co[0] = x;
		co[1] = y;
		co[2] = 0.0f;

		externtex(mtex, co, &intensity,
		          rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false);
	}

	CLAMP(intensity, 0.0f, 1.0f);

	switch (br->mask_pressure) {
		case BRUSH_MASK_PRESSURE_CUTOFF:
			intensity  = ((1.0f - intensity) < ups->size_pressure_value) ? 1.0f : 0.0f;
			break;
		case BRUSH_MASK_PRESSURE_RAMP:
			intensity = ups->size_pressure_value + intensity * (1.0f - ups->size_pressure_value);
			break;
		default:
			break;
	}

	return intensity;
}
Esempio n. 30
0
void DespeckleOperation::executePixel(float output[4], int x, int y, void * /*data*/)
{
  float w = 0.0f;
  float color_org[4];
  float color_mid[4];
  float color_mid_ok[4];
  float in1[4];
  int x1 = x - 1;
  int x2 = x;
  int x3 = x + 1;
  int y1 = y - 1;
  int y2 = y;
  int y3 = y + 1;
  CLAMP(x1, 0, getWidth() - 1);
  CLAMP(x2, 0, getWidth() - 1);
  CLAMP(x3, 0, getWidth() - 1);
  CLAMP(y1, 0, getHeight() - 1);
  CLAMP(y2, 0, getHeight() - 1);
  CLAMP(y3, 0, getHeight() - 1);
  float value[4];
  this->m_inputValueOperation->read(value, x2, y2, NULL);
  // const float mval = 1.0f - value[0];

  this->m_inputOperation->read(color_org, x2, y2, NULL);

#define TOT_DIV_ONE 1.0f
#define TOT_DIV_CNR (float)M_SQRT1_2

#define WTOT (TOT_DIV_ONE * 4 + TOT_DIV_CNR * 4)

#define COLOR_ADD(fac) \
  { \
    madd_v4_v4fl(color_mid, in1, fac); \
    if (color_diff(in1, color_org, this->m_threshold)) { \
      w += fac; \
      madd_v4_v4fl(color_mid_ok, in1, fac); \
    } \
  }

  zero_v4(color_mid);
  zero_v4(color_mid_ok);

  this->m_inputOperation->read(in1, x1, y1, NULL);
  COLOR_ADD(TOT_DIV_CNR)
  this->m_inputOperation->read(in1, x2, y1, NULL);
  COLOR_ADD(TOT_DIV_ONE)
  this->m_inputOperation->read(in1, x3, y1, NULL);
  COLOR_ADD(TOT_DIV_CNR)
  this->m_inputOperation->read(in1, x1, y2, NULL);
  COLOR_ADD(TOT_DIV_ONE)

#if 0
  this->m_inputOperation->read(in2, x2, y2, NULL);
  madd_v4_v4fl(color_mid, in2, this->m_filter[4]);
#endif

  this->m_inputOperation->read(in1, x3, y2, NULL);
  COLOR_ADD(TOT_DIV_ONE)
  this->m_inputOperation->read(in1, x1, y3, NULL);
  COLOR_ADD(TOT_DIV_CNR)
  this->m_inputOperation->read(in1, x2, y3, NULL);
  COLOR_ADD(TOT_DIV_ONE)
  this->m_inputOperation->read(in1, x3, y3, NULL);
  COLOR_ADD(TOT_DIV_CNR)

  mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * (float)M_SQRT1_2)));
  // mul_v4_fl(color_mid, 1.0f / w);

  if ((w != 0.0f) && ((w / WTOT) > (this->m_threshold_neighbor)) &&
      color_diff(color_mid, color_org, this->m_threshold)) {
    mul_v4_fl(color_mid_ok, 1.0f / w);
    interp_v4_v4v4(output, color_org, color_mid_ok, value[0]);
  }
  else {
    copy_v4_v4(output, color_org);
  }
}