Example #1
0
/* note; only does current curvemap! */
void curvemapping_changed(CurveMapping *cumap, int rem_doubles)
{
	CurveMap *cuma = cumap->cm + cumap->cur;
	CurveMapPoint *cmp = cuma->curve;
	rctf *clipr = &cumap->clipr;
	float thresh = 0.01f * BLI_rctf_size_x(clipr);
	float dx = 0.0f, dy = 0.0f;
	int a;

	cumap->changed_timestamp++;

	/* clamp with clip */
	if (cumap->flag & CUMA_DO_CLIP) {
		for (a = 0; a < cuma->totpoint; a++) {
			if (cmp[a].flag & CUMA_SELECT) {
				if (cmp[a].x < clipr->xmin)
					dx = min_ff(dx, cmp[a].x - clipr->xmin);
				else if (cmp[a].x > clipr->xmax)
					dx = max_ff(dx, cmp[a].x - clipr->xmax);
				if (cmp[a].y < clipr->ymin)
					dy = min_ff(dy, cmp[a].y - clipr->ymin);
				else if (cmp[a].y > clipr->ymax)
					dy = max_ff(dy, cmp[a].y - clipr->ymax);
			}
		}
		for (a = 0; a < cuma->totpoint; a++) {
			if (cmp[a].flag & CUMA_SELECT) {
				cmp[a].x -= dx;
				cmp[a].y -= dy;
			}
		}
	}
	
	
	qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints);
	
	/* remove doubles, threshold set on 1% of default range */
	if (rem_doubles && cuma->totpoint > 2) {
		for (a = 0; a < cuma->totpoint - 1; a++) {
			dx = cmp[a].x - cmp[a + 1].x;
			dy = cmp[a].y - cmp[a + 1].y;
			if (sqrtf(dx * dx + dy * dy) < thresh) {
				if (a == 0) {
					cmp[a + 1].flag |= CUMA_VECTOR;
					if (cmp[a + 1].flag & CUMA_SELECT)
						cmp[a].flag |= CUMA_SELECT;
				}
				else {
					cmp[a].flag |= CUMA_VECTOR;
					if (cmp[a].flag & CUMA_SELECT)
						cmp[a + 1].flag |= CUMA_SELECT;
				}
				break;  /* we assume 1 deletion per edit is ok */
			}
		}
		if (a != cuma->totpoint - 1)
			curvemap_remove(cuma, 2);
	}
	curvemap_make_table(cuma, clipr);
}
Example #2
0
void MixDarkenOperation::executePixelSampled(float output[4],
                                             float x,
                                             float y,
                                             PixelSampler sampler)
{
  float inputColor1[4];
  float inputColor2[4];
  float inputValue[4];

  this->m_inputValueOperation->readSampled(inputValue, x, y, sampler);
  this->m_inputColor1Operation->readSampled(inputColor1, x, y, sampler);
  this->m_inputColor2Operation->readSampled(inputColor2, x, y, sampler);

  float value = inputValue[0];
  if (this->useValueAlphaMultiply()) {
    value *= inputColor2[3];
  }
  float valuem = 1.0f - value;
  output[0] = min_ff(inputColor1[0], inputColor2[0]) * value + inputColor1[0] * valuem;
  output[1] = min_ff(inputColor1[1], inputColor2[1]) * value + inputColor1[1] * valuem;
  output[2] = min_ff(inputColor1[2], inputColor2[2]) * value + inputColor1[2] * valuem;
  output[3] = inputColor1[3];

  clampIfNeeded(output);
}
Example #3
0
void curvemapping_set_defaults(CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy)
{
	int a;
	float clipminx, clipminy, clipmaxx, clipmaxy;
	
	cumap->flag = CUMA_DO_CLIP;
	if (tot == 4) cumap->cur = 3;   /* rhms, hack for 'col' curve? */
	
	clipminx = min_ff(minx, maxx);
	clipminy = min_ff(miny, maxy);
	clipmaxx = max_ff(minx, maxx);
	clipmaxy = max_ff(miny, maxy);
	
	BLI_rctf_init(&cumap->curr, clipminx, clipmaxx, clipminy, clipmaxy);
	cumap->clipr = cumap->curr;
	
	cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f;
	cumap->bwmul[0] = cumap->bwmul[1] = cumap->bwmul[2] = 1.0f;
	
	for (a = 0; a < tot; a++) {
		cumap->cm[a].flag = CUMA_EXTEND_EXTRAPOLATE;
		cumap->cm[a].totpoint = 2;
		cumap->cm[a].curve = MEM_callocN(2 * sizeof(CurveMapPoint), "curve points");

		cumap->cm[a].curve[0].x = minx;
		cumap->cm[a].curve[0].y = miny;
		cumap->cm[a].curve[1].x = maxx;
		cumap->cm[a].curve[1].y = maxy;
	}

	cumap->changed_timestamp = 0;
}
Example #4
0
static void dm_get_bounds(DerivedMesh *dm, float *sx, float *sy, float *ox, float *oy)
{
	/* get bounding box of underlying dm */
	int v, totvert = dm->getNumVerts(dm);
	float min[3], max[3], delta[3];

	MVert *mvert = dm->getVertDataArray(dm, 0);

	copy_v3_v3(min, mvert->co);
	copy_v3_v3(max, mvert->co);

	for (v = 1; v < totvert; v++, mvert++) {
		min[0] = min_ff(min[0], mvert->co[0]);
		min[1] = min_ff(min[1], mvert->co[1]);
		min[2] = min_ff(min[2], mvert->co[2]);

		max[0] = max_ff(max[0], mvert->co[0]);
		max[1] = max_ff(max[1], mvert->co[1]);
		max[2] = max_ff(max[2], mvert->co[2]);
	}

	sub_v3_v3v3(delta, max, min);

	*sx = delta[0];
	*sy = delta[1];

	*ox = min[0];
	*oy = min[1];
}
static void make_box_union(const BoundBox *a, const Box *b, Box *r_out)
{
	r_out->min[0] = min_ff(a->vec[0][0], b->min[0]);
	r_out->min[1] = min_ff(a->vec[0][1], b->min[1]);
	r_out->min[2] = min_ff(a->vec[0][2], b->min[2]);

	r_out->max[0] = max_ff(a->vec[6][0], b->max[0]);
	r_out->max[1] = max_ff(a->vec[6][1], b->max[1]);
	r_out->max[2] = max_ff(a->vec[6][2], b->max[2]);
}
Example #6
0
/**
 * \return The best angle for fitting the convex hull to an axis aligned bounding box.
 *
 * Intended to be used with #BLI_convexhull_2d
 *
 * \param points  Orded hull points
 * (result of #BLI_convexhull_2d mapped to a contiguous array).
 *
 * \note we could return the index of the best edge too if its needed.
 */
float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n)
{
	unsigned int i, i_prev;
	float area_best = FLT_MAX;
	float angle_best = 0.0f;

	i_prev = n - 1;
	for (i = 0; i < n; i++) {
		const float *ev_a = points_hull[i];
		const float *ev_b = points_hull[i_prev];
		float dvec[2];

		sub_v2_v2v2(dvec, ev_a, ev_b);
		if (normalize_v2(dvec) != 0.0f) {
			float mat[2][2];
			float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};

			unsigned int j;
			const float angle = atan2f(dvec[0], dvec[1]);
			float area;

			angle_to_mat2(mat, angle);

			for (j = 0; j < n; j++) {
				float tvec[2];
				mul_v2_m2v2(tvec, mat, points_hull[j]);

				min[0] = min_ff(min[0], tvec[0]);
				min[1] = min_ff(min[1], tvec[1]);

				max[0] = max_ff(max[0], tvec[0]);
				max[1] = max_ff(max[1], tvec[1]);

				area = (max[0] - min[0]) * (max[1] - min[1]);
				if (area > area_best) {
					break;
				}
			}

			if (area < area_best) {
				area_best = area;
				angle_best = angle;
			}
		}

		i_prev = i;
	}

	return angle_best;
}
Example #7
0
static int view_all_exec(bContext *C, wmOperator *op)
{
	SpaceClip *sc;
	ARegion *ar;
	int w, h, width, height;
	float aspx, aspy;
	int fit_view = RNA_boolean_get(op->ptr, "fit_view");
	float zoomx, zoomy;

	/* retrieve state */
	sc = CTX_wm_space_clip(C);
	ar = CTX_wm_region(C);

	ED_space_clip_get_size(sc, &w, &h);
	ED_space_clip_get_aspect(sc, &aspx, &aspy);

	w = w * aspx;
	h = h * aspy;

	/* check if the image will fit in the image with zoom == 1 */
	width  = BLI_rcti_size_x(&ar->winrct) + 1;
	height = BLI_rcti_size_y(&ar->winrct) + 1;

	if (fit_view) {
		const int margin = 5; /* margin from border */

		zoomx = (float) width / (w + 2 * margin);
		zoomy = (float) height / (h + 2 * margin);

		sclip_zoom_set(C, min_ff(zoomx, zoomy), NULL);
	}
	else {
		if ((w >= width || h >= height) && (width > 0 && height > 0)) {
			zoomx = (float) width / w;
			zoomy = (float) height / h;

			/* find the zoom value that will fit the image in the image space */
			sclip_zoom_set(C, 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy)), NULL);
		}
		else
			sclip_zoom_set(C, 1.0f, NULL);
	}

	sc->xof = sc->yof = 0.0f;

	ED_region_tag_redraw(CTX_wm_region(C));

	return OPERATOR_FINISHED;
}
Example #8
0
static void object_warp_transverts_minmax_x(TransVertStore *tvs,
                                            float mat_view[4][4], const float center_view[3],
                                            float *r_min, float *r_max)
{
	/* no need to apply translation and cursor offset for every vertex, delay this */
	const float x_ofs = (mat_view[3][0] - center_view[0]);
	float min = FLT_MAX, max = -FLT_MAX;

	TransVert *tv;
	int i;


	tv = tvs->transverts;
	for (i = 0; i < tvs->transverts_tot; i++, tv++) {
		float val;

		/* convert objectspace->viewspace */
		val = dot_m4_v3_row_x(mat_view, tv->loc);

		min = min_ff(min, val);
		max = max_ff(max, val);
	}

	*r_min = min + x_ofs;
	*r_max = max + x_ofs;
}
Example #9
0
void IMB_buffer_float_clamp(float *buf, int width, int height)
{
	int i, total = width * height * 4;
	for (i = 0; i < total; i++) {
		buf[i] = min_ff(1.0, buf[i]);
	}
}
void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device,
                                       MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, 
                                       MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, 
                                       list<cl_kernel> * /*clKernelsToCleanUp*/)
{
	cl_kernel defocusKernel = device->COM_clCreateKernel("defocusKernel", NULL);

	cl_int step = this->getStep();
	cl_int maxBlur;
	cl_float threshold = this->m_threshold;
	
	MemoryBuffer *sizeMemoryBuffer = this->m_inputSizeProgram->getInputMemoryBuffer(inputMemoryBuffers);

	const float max_dim = max(m_width, m_height);
	cl_float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f;

	maxBlur = (cl_int)min_ff(sizeMemoryBuffer->getMaximumValue() * scalar,
	                         (float)this->m_maxBlur);

	device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 0, -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
	device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 1,  -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputBokehProgram);
	device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 2,  4, clMemToCleanUp, inputMemoryBuffers, this->m_inputSizeProgram);
	device->COM_clAttachOutputMemoryBufferToKernelParameter(defocusKernel, 3, clOutputBuffer);
	device->COM_clAttachMemoryBufferOffsetToKernelParameter(defocusKernel, 5, outputMemoryBuffer);
	clSetKernelArg(defocusKernel, 6, sizeof(cl_int), &step);
	clSetKernelArg(defocusKernel, 7, sizeof(cl_int), &maxBlur);
	clSetKernelArg(defocusKernel, 8, sizeof(cl_float), &threshold);
	clSetKernelArg(defocusKernel, 9, sizeof(cl_float), &scalar);
	device->COM_clAttachSizeToKernelParameter(defocusKernel, 10, this);
	
	device->COM_clEnqueueRange(defocusKernel, outputMemoryBuffer, 11, this);
}
Example #11
0
static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *result, int steps)
{
	ClothSolverResult *sres = clmd->solver_result;
	
	if (sres->status) { /* already initialized ? */
		/* error only makes sense for successful iterations */
		if (result->status == BPH_SOLVER_SUCCESS) {
			sres->min_error = min_ff(sres->min_error, result->error);
			sres->max_error = max_ff(sres->max_error, result->error);
			sres->avg_error += result->error / (float)steps;
		}
		
		sres->min_iterations = min_ii(sres->min_iterations, result->iterations);
		sres->max_iterations = max_ii(sres->max_iterations, result->iterations);
		sres->avg_iterations += (float)result->iterations / (float)steps;
	}
	else {
		/* error only makes sense for successful iterations */
		if (result->status == BPH_SOLVER_SUCCESS) {
			sres->min_error = sres->max_error = result->error;
			sres->avg_error += result->error / (float)steps;
		}
		
		sres->min_iterations = sres->max_iterations  = result->iterations;
		sres->avg_iterations += (float)result->iterations / (float)steps;
	}
	
	sres->status |= result->status;
}
void ScreenLensDistortionOperation::updateVariables(float distortion, float dispersion)
{
	m_k[1] = max_ff(min_ff(distortion, 1.0f), -0.999f);
	// smaller dispersion range for somewhat more control
	float d = 0.25f * max_ff(min_ff(dispersion, 1.0f), 0.0f);
	m_k[0] = max_ff(min_ff((m_k[1] + d), 1.0f), -0.999f);
	m_k[2] = max_ff(min_ff((m_k[1] - d), 1.0f), -0.999f);
	m_maxk = max_fff(m_k[0], m_k[1], m_k[2]);
	m_sc = (m_fit && (m_maxk > 0.0f)) ? (1.0f / (1.0f + 2.0f * m_maxk)) :
	                                    (1.0f / (1.0f +        m_maxk));
	m_dk4[0] = 4.0f * (m_k[1] - m_k[0]);
	m_dk4[1] = 4.0f * (m_k[2] - m_k[1]);
	m_dk4[2] = 0.0f; /* unused */

	mul_v3_v3fl(m_k4, m_k, 4.0f);
}
Example #13
0
/* Expand the bounding box to include a new coordinate */
void BB_expand(BB *bb, const float co[3])
{
	int i;
	for (i = 0; i < 3; ++i) {
		bb->bmin[i] = min_ff(bb->bmin[i], co[i]);
		bb->bmax[i] = max_ff(bb->bmax[i], co[i]);
	}
}
/**
 * \return The best angle for fitting the convex hull to an axis aligned bounding box.
 *
 * Intended to be used with #BLI_convexhull_2d
 *
 * \param points_hull  Ordered hull points
 * (result of #BLI_convexhull_2d mapped to a contiguous array).
 *
 * \note we could return the index of the best edge too if its needed.
 */
float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n)
{
	unsigned int i, i_prev;
	float area_best = FLT_MAX;
	float dvec_best[2];  /* best angle, delay atan2 */

	i_prev = n - 1;
	for (i = 0; i < n; i++) {
		const float *ev_a = points_hull[i];
		const float *ev_b = points_hull[i_prev];
		float dvec[2];  /* 2d rotation matrix */

		sub_v2_v2v2(dvec, ev_a, ev_b);
		if (normalize_v2(dvec) != 0.0f) {
			/* rotation matrix */
			float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
			unsigned int j;
			float area;

			for (j = 0; j < n; j++) {
				float tvec[2];
				mul_v2_v2_cw(tvec, dvec, points_hull[j]);

				min[0] = min_ff(min[0], tvec[0]);
				min[1] = min_ff(min[1], tvec[1]);

				max[0] = max_ff(max[0], tvec[0]);
				max[1] = max_ff(max[1], tvec[1]);

				area = (max[0] - min[0]) * (max[1] - min[1]);
				if (area > area_best) {
					break;
				}
			}

			if (area < area_best) {
				area_best = area;
				copy_v2_v2(dvec_best, dvec);
			}
		}

		i_prev = i;
	}

	return (area_best != FLT_MAX) ? atan2f(dvec_best[0], dvec_best[1]) : 0.0f;
}
Example #15
0
/* Expand the bounding box to include another bounding box */
void BB_expand_with_bb(BB *bb, BB *bb2)
{
	int i;
	for (i = 0; i < 3; ++i) {
		bb->bmin[i] = min_ff(bb->bmin[i], bb2->bmin[i]);
		bb->bmax[i] = max_ff(bb->bmax[i], bb2->bmax[i]);
	}
}
Example #16
0
/* clamp handles to defined size in pixel space */
static float draw_seq_handle_size_get_clamped(Sequence *seq, const float pixelx)
{
	const float minhandle = pixelx * SEQ_HANDLE_SIZE_MIN;
	const float maxhandle = pixelx * SEQ_HANDLE_SIZE_MAX;
	float size = CLAMPIS(seq->handsize, minhandle, maxhandle);

	/* ensure we're not greater than half width */
	return min_ff(size, ((float)(seq->enddisp - seq->startdisp) / 2.0f) / pixelx);
}
Example #17
0
static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length)
{
	float co[2] = {(float)x, (float)y};
	float dir[2], dist;

	/* move (x,y) vector toward the source by ray_length distance */
	sub_v2_v2v2(dir, co, source);
	dist = normalize_v2(dir);
	mul_v2_fl(dir, min_ff(dist, ray_length));
	sub_v2_v2(co, dir);

	int ico[2] = {(int)co[0], (int)co[1]};
	BLI_rcti_do_minmax_v(rect, ico);
}
Example #18
0
static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, int x, int y)
{
	BakeShade *bs = handle;
	float disp;

	if (R.r.bake_flag & R_BAKE_NORMALIZE) {
		if (R.r.bake_maxdist)
			disp = (dist + R.r.bake_maxdist) / (R.r.bake_maxdist * 2);  /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
		else
			disp = dist;
	}
	else {
		disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
	}

	if (bs->displacement_buffer) {
		float *displacement = bs->displacement_buffer + (bs->rectx * y + x);
		*displacement = disp;
		bs->displacement_min = min_ff(bs->displacement_min, disp);
		bs->displacement_max = max_ff(bs->displacement_max, disp);
	}

	if (bs->rect_float && !bs->vcol) {
		float *col = bs->rect_float + 4 * (bs->rectx * y + x);
		col[0] = col[1] = col[2] = disp;
		col[3] = 1.0f;
	}
	else {
		/* Target is char (LDR). */
		unsigned char col[4];
		col[0] = col[1] = col[2] = FTOCHAR(disp);
		col[3] = 255;

		if (bs->vcol) {
			/* Vertex color baking. Vcol has no useful alpha channel (it exists
			 * but is used only for vertex painting). */
			bs->vcol->r = col[0];
			bs->vcol->g = col[1];
			bs->vcol->b = col[2];
		}
		else {
			char *imcol = (char *)(bs->rect + bs->rectx * y + x);
			copy_v4_v4_char((char *)imcol, (char *)col);
		}
	}
	if (bs->rect_mask) {
		bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED;
	}
}
void ProjectorLensDistortionOperation::updateDispersion()
{
  if (this->m_dispersionAvailable) {
    return;
  }
  this->lockMutex();
  if (!this->m_dispersionAvailable) {
    float result[4];
    this->getInputSocketReader(1)->readSampled(result, 1, 1, COM_PS_NEAREST);
    this->m_dispersion = result[0];
    this->m_kr = 0.25f * max_ff(min_ff(this->m_dispersion, 1.0f), 0.0f);
    this->m_kr2 = this->m_kr * 20;
    this->m_dispersionAvailable = true;
  }
  this->unlockMutex();
}
Example #20
0
static float get_shortest_pattern_side(MovieTrackingMarker *marker)
{
	int i, next;
	float len_sq = FLT_MAX;

	for (i = 0; i < 4; i++) {
		float cur_len;

		next = (i + 1) % 4;

		cur_len = len_squared_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]);

		len_sq = min_ff(cur_len, len_sq);
	}

	return sqrtf(len_sq);
}
Example #21
0
static void getArrowEndPoint(const int width, const int height, const float zoom,
                             const float start_corner[2], const float end_corner[2],
                             float end_point[2])
{
	float direction[2];
	float max_length;

	sub_v2_v2v2(direction, end_corner, start_corner);

	direction[0] *= width;
	direction[1] *= height;
	max_length = normalize_v2(direction);
	mul_v2_fl(direction, min_ff(32.0f / zoom, max_length));
	direction[0] /= width;
	direction[1] /= height;

	add_v2_v2v2(end_point, start_corner, direction);
}
Example #22
0
/* Note this modifies nos_new in-place. */
static void mix_normals(
        const float mix_factor, MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup,
        const float mix_limit, const short mix_mode,
        const int num_verts, MLoop *mloop, float (*nos_old)[3], float (*nos_new)[3], const int num_loops)
{
	/* Mix with org normals... */
	float *facs = NULL, *wfac;
	float (*no_new)[3], (*no_old)[3];
	int i;

	if (dvert) {
		facs = MEM_malloc_arrayN((size_t)num_loops, sizeof(*facs), __func__);
		BKE_defvert_extract_vgroup_to_loopweights(
		            dvert, defgrp_index, num_verts, mloop, num_loops, facs, use_invert_vgroup);
	}

	for (i = num_loops, no_new = nos_new, no_old = nos_old, wfac = facs; i--; no_new++, no_old++, wfac++) {
		const float fac = facs ? *wfac * mix_factor : mix_factor;

		switch (mix_mode) {
			case MOD_NORMALEDIT_MIX_ADD:
				add_v3_v3(*no_new, *no_old);
				normalize_v3(*no_new);
				break;
			case MOD_NORMALEDIT_MIX_SUB:
				sub_v3_v3(*no_new, *no_old);
				normalize_v3(*no_new);
				break;
			case MOD_NORMALEDIT_MIX_MUL:
				mul_v3_v3(*no_new, *no_old);
				normalize_v3(*no_new);
				break;
			case MOD_NORMALEDIT_MIX_COPY:
				break;
		}

		interp_v3_v3v3_slerp_safe(
		        *no_new, *no_old, *no_new,
		        (mix_limit < (float)M_PI) ? min_ff(fac, mix_limit / angle_v3v3(*no_new, *no_old)) : fac);
	}

	MEM_SAFE_FREE(facs);
}
Example #23
0
bool ED_clip_view_selection(const bContext *C, ARegion *ar, bool fit)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	int w, h, frame_width, frame_height;
	float min[2], max[2];

	ED_space_clip_get_size(sc, &frame_width, &frame_height);

	if ((frame_width == 0) || (frame_height == 0) || (sc->clip == NULL))
		return false;

	if (!selected_boundbox(sc, min, max))
		return false;

	/* center view */
	clip_view_center_to_point(sc, (max[0] + min[0]) / (2 * frame_width),
	                              (max[1] + min[1]) / (2 * frame_height));

	w = max[0] - min[0];
	h = max[1] - min[1];

	/* set zoom to see all selection */
	if (w > 0 && h > 0) {
		int width, height;
		float zoomx, zoomy, newzoom, aspx, aspy;

		ED_space_clip_get_aspect(sc, &aspx, &aspy);

		width  = BLI_rcti_size_x(&ar->winrct) + 1;
		height = BLI_rcti_size_y(&ar->winrct) + 1;

		zoomx = (float)width / w / aspx;
		zoomy = (float)height / h / aspy;

		newzoom = 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy));

		if (fit || sc->zoom > newzoom)
			sc->zoom = newzoom;
	}

	return true;
}
Example #24
0
static void voronoi_finishEdge(VoronoiProcess *process, VoronoiParabola *parabola)
{
	float mx;

	if (parabola->is_leaf) {
		MEM_freeN(parabola);
		return;
	}

	if (parabola->edge->direction[0] > 0.0f)
		mx = max_ff(process->width, parabola->edge->start[0] + 10);
	else
		mx = min_ff(0.0f, parabola->edge->start[0] - 10.0f);

	parabola->edge->end[0] = mx;
	parabola->edge->end[1] = mx * parabola->edge->f + parabola->edge->g;

	voronoi_finishEdge(process, parabola->left);
	voronoi_finishEdge(process, parabola->right);

	MEM_freeN(parabola);
}
Example #25
0
static float voronoi_getXOfEdge(VoronoiProcess *process, VoronoiParabola *par, float y)
{
  VoronoiParabola *left = voronoiParabola_getLeftChild(par);
  VoronoiParabola *right = voronoiParabola_getRightChild(par);
  float p[2], r[2];
  float dp, a1, b1, c1, a2, b2, c2, a, b, c, disc, ry, x1, x2;
  float ly = process->current_y;

  copy_v2_v2(p, left->site);
  copy_v2_v2(r, right->site);

  dp = 2.0f * (p[1] - y);
  a1 = 1.0f / dp;
  b1 = -2.0f * p[0] / dp;
  c1 = y + dp / 4 + p[0] * p[0] / dp;

  dp = 2.0f * (r[1] - y);
  a2 = 1.0f / dp;
  b2 = -2.0f * r[0] / dp;
  c2 = ly + dp / 4 + r[0] * r[0] / dp;

  a = a1 - a2;
  b = b1 - b2;
  c = c1 - c2;

  disc = b * b - 4 * a * c;
  x1 = (-b + sqrtf(disc)) / (2 * a);
  x2 = (-b - sqrtf(disc)) / (2 * a);

  if (p[1] < r[1]) {
    ry = max_ff(x1, x2);
  }
  else {
    ry = min_ff(x1, x2);
  }

  return ry;
}
Example #26
0
static int backimage_fit_exec(bContext *C, wmOperator *UNUSED(op))
{
    SpaceNode *snode = CTX_wm_space_node(C);
    ARegion *ar = CTX_wm_region(C);

    Image *ima;
    ImBuf *ibuf;

    const float pad = 32.0f;

    void *lock;

    float facx, facy;

    ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
    ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);

    if (ibuf == NULL) {
        BKE_image_release_ibuf(ima, ibuf, lock);
        return OPERATOR_CANCELLED;
    }

    facx = 1.0f * (ar->sizex - pad) / (ibuf->x * snode->zoom);
    facy = 1.0f * (ar->sizey - pad) / (ibuf->y * snode->zoom);

    BKE_image_release_ibuf(ima, ibuf, lock);

    snode->zoom *= min_ff(facx, facy);

    snode->xof = 0;
    snode->yof = 0;

    ED_region_tag_redraw(ar);
    WM_main_add_notifier(NC_NODE | ND_DISPLAY, NULL);

    return OPERATOR_FINISHED;
}
void LuminanceMatteOperation::executePixelSampled(float output[4],
                                                  float x,
                                                  float y,
                                                  PixelSampler sampler)
{
  float inColor[4];
  this->m_inputImageProgram->readSampled(inColor, x, y, sampler);

  const float high = this->m_settings->t1;
  const float low = this->m_settings->t2;
  const float luminance = IMB_colormanagement_get_luminance(inColor);

  float alpha;

  /* one line thread-friend algorithm:
   * output[0] = min(inputValue[3], min(1.0f, max(0.0f, ((luminance - low) / (high - low))));
   */

  /* test range */
  if (luminance > high) {
    alpha = 1.0f;
  }
  else if (luminance < low) {
    alpha = 0.0f;
  }
  else { /*blend */
    alpha = (luminance - low) / (high - low);
  }

  /* store matte(alpha) value in [0] to go with
   * COM_SetAlphaOperation and the Value output
   */

  /* don't make something that was more transparent less transparent */
  output[0] = min_ff(alpha, inColor[3]);
}
Example #28
0
ScatterSettings *scatter_settings_new(float refl, float radius, float ior, float reflfac, float frontweight, float backweight)
{
	ScatterSettings *ss;
	
	ss= MEM_callocN(sizeof(ScatterSettings), "ScatterSettings");

	/* see [1] and [3] for these formulas */
	ss->eta= ior;
	ss->Fdr= -1.440f/ior*ior + 0.710f/ior + 0.668f + 0.0636f*ior;
	ss->A= (1.0f + ss->Fdr)/(1.0f - ss->Fdr);
	ss->ld= radius;
	ss->ro= min_ff(refl, 0.999f);
	ss->color= ss->ro*reflfac + (1.0f-reflfac);

	ss->alpha_= compute_reduced_albedo(ss);

	ss->sigma= 1.0f/ss->ld;
	ss->sigma_t_= ss->sigma/sqrtf(3.0f*(1.0f - ss->alpha_));
	ss->sigma_s_= ss->alpha_*ss->sigma_t_;
	ss->sigma_a= ss->sigma_t_ - ss->sigma_s_;

	ss->D= 1.0f/(3.0f*ss->sigma_t_);

	ss->zr= 1.0f/ss->sigma_t_;
	ss->zv= ss->zr + 4.0f*ss->A*ss->D;

	ss->invsigma_t_= 1.0f/ss->sigma_t_;

	ss->frontweight= frontweight;
	ss->backweight= backweight;

	/* precompute a table of Rd values for quick lookup */
	build_Rd_table(ss);

	return ss;
}
Example #29
0
/* Evaluate spline IK for a given bone */
static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan,
                                   int index, float ctime)
{
	bSplineIKConstraint *ikData = tree->ikData;
	float poseHead[3], poseTail[3], poseMat[4][4];
	float splineVec[3], scaleFac, radius = 1.0f;

	/* firstly, calculate the bone matrix the standard way, since this is needed for roll control */
	BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1);

	copy_v3_v3(poseHead, pchan->pose_head);
	copy_v3_v3(poseTail, pchan->pose_tail);

	/* step 1: determine the positions for the endpoints of the bone */
	{
		float vec[4], dir[3], rad;
		float tailBlendFac = 1.0f;

		/* determine if the bone should still be affected by SplineIK */
		if (tree->points[index + 1] >= 1.0f) {
			/* spline doesn't affect the bone anymore, so done... */
			pchan->flag |= POSE_DONE;
			return;
		}
		else if ((tree->points[index] >= 1.0f) && (tree->points[index + 1] < 1.0f)) {
			/* blending factor depends on the amount of the bone still left on the chain */
			tailBlendFac = (1.0f - tree->points[index + 1]) / (tree->points[index] - tree->points[index + 1]);
		}

		/* tail endpoint */
		if (where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad, NULL)) {
			/* apply curve's object-mode transforms to the position
			 * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
			 */
			if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0)
				mul_m4_v3(ikData->tar->obmat, vec);

			/* convert the position to pose-space, then store it */
			mul_m4_v3(ob->imat, vec);
			interp_v3_v3v3(poseTail, pchan->pose_tail, vec, tailBlendFac);

			/* set the new radius */
			radius = rad;
		}

		/* head endpoint */
		if (where_on_path(ikData->tar, tree->points[index + 1], vec, dir, NULL, &rad, NULL)) {
			/* apply curve's object-mode transforms to the position
			 * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
			 */
			if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0)
				mul_m4_v3(ikData->tar->obmat, vec);

			/* store the position, and convert it to pose space */
			mul_m4_v3(ob->imat, vec);
			copy_v3_v3(poseHead, vec);

			/* set the new radius (it should be the average value) */
			radius = (radius + rad) / 2;
		}
	}

	/* step 2: determine the implied transform from these endpoints
	 *     - splineVec: the vector direction that the spline applies on the bone
	 *     - scaleFac: the factor that the bone length is scaled by to get the desired amount
	 */
	sub_v3_v3v3(splineVec, poseTail, poseHead);
	scaleFac = len_v3(splineVec) / pchan->bone->length;

	/* step 3: compute the shortest rotation needed to map from the bone rotation to the current axis
	 *      - this uses the same method as is used for the Damped Track Constraint (see the code there for details)
	 */
	{
		float dmat[3][3], rmat[3][3], tmat[3][3];
		float raxis[3], rangle;

		/* compute the raw rotation matrix from the bone's current matrix by extracting only the
		 * orientation-relevant axes, and normalizing them
		 */
		copy_v3_v3(rmat[0], pchan->pose_mat[0]);
		copy_v3_v3(rmat[1], pchan->pose_mat[1]);
		copy_v3_v3(rmat[2], pchan->pose_mat[2]);
		normalize_m3(rmat);

		/* also, normalize the orientation imposed by the bone, now that we've extracted the scale factor */
		normalize_v3(splineVec);

		/* calculate smallest axis-angle rotation necessary for getting from the
		 * current orientation of the bone, to the spline-imposed direction
		 */
		cross_v3_v3v3(raxis, rmat[1], splineVec);

		rangle = dot_v3v3(rmat[1], splineVec);
		CLAMP(rangle, -1.0f, 1.0f);
		rangle = acosf(rangle);

		/* multiply the magnitude of the angle by the influence of the constraint to
		 * control the influence of the SplineIK effect
		 */
		rangle *= tree->con->enforce;

		/* construct rotation matrix from the axis-angle rotation found above
		 *	- this call takes care to make sure that the axis provided is a unit vector first
		 */
		axis_angle_to_mat3(dmat, raxis, rangle);

		/* combine these rotations so that the y-axis of the bone is now aligned as the spline dictates,
		 * while still maintaining roll control from the existing bone animation
		 */
		mul_m3_m3m3(tmat, dmat, rmat); /* m1, m3, m2 */
		normalize_m3(tmat); /* attempt to reduce shearing, though I doubt this'll really help too much now... */
		copy_m4_m3(poseMat, tmat);
	}

	/* step 4: set the scaling factors for the axes */
	{
		/* only multiply the y-axis by the scaling factor to get nice volume-preservation */
		mul_v3_fl(poseMat[1], scaleFac);

		/* set the scaling factors of the x and z axes from... */
		switch (ikData->xzScaleMode) {
			case CONSTRAINT_SPLINEIK_XZS_ORIGINAL:
			{
				/* original scales get used */
				float scale;

				/* x-axis scale */
				scale = len_v3(pchan->pose_mat[0]);
				mul_v3_fl(poseMat[0], scale);
				/* z-axis scale */
				scale = len_v3(pchan->pose_mat[2]);
				mul_v3_fl(poseMat[2], scale);
				break;
			}
			case CONSTRAINT_SPLINEIK_XZS_INVERSE:
			{
				/* old 'volume preservation' method using the inverse scale */
				float scale;

				/* calculate volume preservation factor which is
				 * basically the inverse of the y-scaling factor
				 */
				if (fabsf(scaleFac) != 0.0f) {
					scale = 1.0f / fabsf(scaleFac);

					/* we need to clamp this within sensible values */
					/* NOTE: these should be fine for now, but should get sanitised in future */
					CLAMP(scale, 0.0001f, 100000.0f);
				}
				else
					scale = 1.0f;

				/* apply the scaling */
				mul_v3_fl(poseMat[0], scale);
				mul_v3_fl(poseMat[2], scale);
				break;
			}
			case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC:
			{
				/* improved volume preservation based on the Stretch To constraint */
				float final_scale;
				
				/* as the basis for volume preservation, we use the inverse scale factor... */
				if (fabsf(scaleFac) != 0.0f) {
					/* NOTE: The method here is taken wholesale from the Stretch To constraint */
					float bulge = powf(1.0f / fabsf(scaleFac), ikData->bulge);
					
					if (bulge > 1.0f) {
						if (ikData->flag & CONSTRAINT_SPLINEIK_USE_BULGE_MAX) {
							float bulge_max = max_ff(ikData->bulge_max, 1.0f);
							float hard = min_ff(bulge, bulge_max);
							
							float range = bulge_max - 1.0f;
							float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
							float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (float)M_PI_2;
							
							bulge = interpf(soft, hard, ikData->bulge_smooth);
						}
					}
					if (bulge < 1.0f) {
						if (ikData->flag & CONSTRAINT_SPLINEIK_USE_BULGE_MIN) {
							float bulge_min = CLAMPIS(ikData->bulge_min, 0.0f, 1.0f);
							float hard = max_ff(bulge, bulge_min);
							
							float range = 1.0f - bulge_min;
							float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
							float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (float)M_PI_2;
							
							bulge = interpf(soft, hard, ikData->bulge_smooth);
						}
					}
					
					/* compute scale factor for xz axes from this value */
					final_scale = sqrtf(bulge);
				}
				else {
					/* no scaling, so scale factor is simple */
					final_scale = 1.0f;
				}
				
				/* apply the scaling (assuming normalised scale) */
				mul_v3_fl(poseMat[0], final_scale);
				mul_v3_fl(poseMat[2], final_scale);
				break;
			}
		}

		/* finally, multiply the x and z scaling by the radius of the curve too,
		 * to allow automatic scales to get tweaked still
		 */
		if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) {
			mul_v3_fl(poseMat[0], radius);
			mul_v3_fl(poseMat[2], radius);
		}
	}

	/* step 5: set the location of the bone in the matrix */
	if (ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) {
		/* when the 'no-root' option is affected, the chain can retain
		 * the shape but be moved elsewhere
		 */
		copy_v3_v3(poseHead, pchan->pose_head);
	}
	else if (tree->con->enforce < 1.0f) {
		/* when the influence is too low
		 *	- blend the positions for the 'root' bone
		 *	- stick to the parent for any other
		 */
		if (pchan->parent) {
			copy_v3_v3(poseHead, pchan->pose_head);
		}
		else {
			/* FIXME: this introduces popping artifacts when we reach 0.0 */
			interp_v3_v3v3(poseHead, pchan->pose_head, poseHead, tree->con->enforce);
		}
	}
	copy_v3_v3(poseMat[3], poseHead);

	/* finally, store the new transform */
	copy_m4_m4(pchan->pose_mat, poseMat);
	copy_v3_v3(pchan->pose_head, poseHead);

	/* recalculate tail, as it's now outdated after the head gets adjusted above! */
	BKE_pose_where_is_bone_tail(pchan);

	/* done! */
	pchan->flag |= POSE_DONE;
}
Example #30
0
/* simple deform modifier */
static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct DerivedMesh *dm,
                                    float (*vertexCos)[3], int numVerts)
{
	static const float lock_axis[2] = {0.0f, 0.0f};

	int i;
	int limit_axis = 0;
	float smd_limit[2], smd_factor;
	SpaceTransform *transf = NULL, tmp_transf;
	void (*simpleDeform_callback)(const float factor, const float dcut[3], float co[3]) = NULL;  /* Mode callback */
	int vgroup;
	MDeformVert *dvert;

	/* Safe-check */
	if (smd->origin == ob) smd->origin = NULL;  /* No self references */

	if (smd->limit[0] < 0.0f) smd->limit[0] = 0.0f;
	if (smd->limit[0] > 1.0f) smd->limit[0] = 1.0f;

	smd->limit[0] = min_ff(smd->limit[0], smd->limit[1]);  /* Upper limit >= than lower limit */

	/* Calculate matrixs do convert between coordinate spaces */
	if (smd->origin) {
		transf = &tmp_transf;

		if (smd->originOpts & MOD_SIMPLEDEFORM_ORIGIN_LOCAL) {
			space_transform_from_matrixs(transf, ob->obmat, smd->origin->obmat);
		}
		else {
			copy_m4_m4(transf->local2target, smd->origin->obmat);
			invert_m4_m4(transf->target2local, transf->local2target);
		}
	}

	/* Setup vars,
	 * Bend limits on X.. all other modes limit on Z */
	limit_axis  = (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) ? 0 : 2;

	/* Update limits if needed */
	{
		float lower =  FLT_MAX;
		float upper = -FLT_MAX;

		for (i = 0; i < numVerts; i++) {
			float tmp[3];
			copy_v3_v3(tmp, vertexCos[i]);

			if (transf) space_transform_apply(transf, tmp);

			lower = min_ff(lower, tmp[limit_axis]);
			upper = max_ff(upper, tmp[limit_axis]);
		}


		/* SMD values are normalized to the BV, calculate the absolut values */
		smd_limit[1] = lower + (upper - lower) * smd->limit[1];
		smd_limit[0] = lower + (upper - lower) * smd->limit[0];

		smd_factor   = smd->factor / max_ff(FLT_EPSILON, smd_limit[1] - smd_limit[0]);
	}

	modifier_get_vgroup(ob, dm, smd->vgroup_name, &dvert, &vgroup);

	switch (smd->mode) {
		case MOD_SIMPLEDEFORM_MODE_TWIST:   simpleDeform_callback = simpleDeform_twist;     break;
		case MOD_SIMPLEDEFORM_MODE_BEND:    simpleDeform_callback = simpleDeform_bend;      break;
		case MOD_SIMPLEDEFORM_MODE_TAPER:   simpleDeform_callback = simpleDeform_taper;     break;
		case MOD_SIMPLEDEFORM_MODE_STRETCH: simpleDeform_callback = simpleDeform_stretch;   break;
		default:
			return; /* No simpledeform mode? */
	}

	for (i = 0; i < numVerts; i++) {
		float weight = defvert_array_find_weight_safe(dvert, i, vgroup);

		if (weight != 0.0f) {
			float co[3], dcut[3] = {0.0f, 0.0f, 0.0f};

			if (transf) {
				space_transform_apply(transf, vertexCos[i]);
			}

			copy_v3_v3(co, vertexCos[i]);

			/* Apply axis limits */
			if (smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) { /* Bend mode shoulnt have any lock axis */
				if (smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) axis_limit(0, lock_axis, co, dcut);
				if (smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) axis_limit(1, lock_axis, co, dcut);
			}
			axis_limit(limit_axis, smd_limit, co, dcut);

			simpleDeform_callback(smd_factor, dcut, co);  /* apply deform */
			interp_v3_v3v3(vertexCos[i], vertexCos[i], co, weight);  /* Use vertex weight has coef of linear interpolation */

			if (transf) {
				space_transform_invert(transf, vertexCos[i]);
			}
		}
	}
}