示例#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);
}
示例#2
0
static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p)
{
	const struct VertSortContext *vs_ctx = vs_ctx_p;
	const BoxVert *v1, *v2;
	float a1, a2;

	v1 = &vs_ctx->vertarray[*((const uint *)p1)];
	v2 = &vs_ctx->vertarray[*((const uint *)p2)];

#ifdef USE_FREE_STRIP
	/* push free verts to the end so we can strip */
	if      (UNLIKELY(v1->free == 0 && v2->free == 0)) return  0;
	else if (UNLIKELY(v1->free == 0))                  return  1;
	else if (UNLIKELY(v2->free == 0))                  return -1;
#endif

	a1 = max_ff(v1->x + vs_ctx->box_width, v1->y + vs_ctx->box_height);
	a2 = max_ff(v2->x + vs_ctx->box_width, v2->y + vs_ctx->box_height);

#ifdef USE_PACK_BIAS
	a1 += v1->bias;
	a2 += v2->bias;
#endif

	/* sort largest to smallest */
	if      (a1 > a2) return 1;
	else if (a1 < a2) return -1;
	return 0;
}
示例#3
0
	/**
	 * Set up the initial buffer pointer and calculate necessary variables for looping.
	 *
	 * Note that sector space is centered around the "source" point while the loop starts
	 * at dist_min from the target pt. This way the loop can be canceled as soon as it runs
	 * out of the buffer rect, because no pixels further along the line can contribute.
	 *
	 * \param x, y  Start location in the buffer
	 * \param num  Total steps in the loop
	 * \param v, dv  Vertical offset in sector space, for line offset perpendicular to the loop axis
	 */
	static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float pt_ofs[2],
	                                   float dist_min, float dist_max,
	                                   int &x, int &y, int &num, float &v, float &dv, float &falloff_factor)
	{
		float pu, pv;
		buffer_to_sector(pt_ofs[0], pt_ofs[1], pu, pv);

		/* line angle */
		float tan_phi = pv / pu;
		float dr = sqrtf(tan_phi * tan_phi + 1.0f);
		float cos_phi = 1.0f / dr;

		/* clamp u range to avoid influence of pixels "behind" the source */
		float umin = max_ff(pu - cos_phi * dist_min, 0.0f);
		float umax = max_ff(pu - cos_phi * dist_max, 0.0f);
		v = umin * tan_phi;
		dv = tan_phi;

		int start = (int)floorf(umax);
		int end = (int)ceilf(umin);
		num = end - start;

		sector_to_buffer(end, (int)ceilf(v), x, y);
		x += (int)source[0];
		y += (int)source[1];

		falloff_factor = dist_max > dist_min ? dr / (float)(dist_max - dist_min) : 0.0f;

		float *iter = input->getBuffer() + COM_NUMBER_OF_CHANNELS * (x + input->getWidth() * y);
		return iter;
	}
示例#4
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;
}
示例#5
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];
}
示例#6
0
static int vertex_sort(const void *p1, const void *p2)
{
	BoxVert *v1, *v2;
	float a1, a2;

	v1 = vertarray + ((int *)p1)[0];
	v2 = vertarray + ((int *)p2)[0];

#ifdef USE_FREE_STRIP
	/* push free verts to the end so we can strip */
	if      (UNLIKELY(v1->free == 0 && v2->free == 0)) return  0;
	else if (UNLIKELY(v1->free == 0))                  return  1;
	else if (UNLIKELY(v2->free == 0))                  return -1;
#endif

	a1 = max_ff(v1->x + box_width, v1->y + box_height);
	a2 = max_ff(v2->x + box_width, v2->y + box_height);

#ifdef USE_PACK_BIAS
	a1 += v1->bias;
	a2 += v2->bias;
#endif

	/* sort largest to smallest */
	if      (a1 > a2) return 1;
	else if (a1 < a2) return -1;
	return 0;
}
示例#7
0
static void tonemapmodifier_apply_threaded_simple(int width,
                                                  int height,
                                                  unsigned char *rect,
                                                  float *rect_float,
                                                  unsigned char *mask_rect,
                                                  float *mask_rect_float,
                                                  void *data_v)
{
	AvgLogLum *avg = (AvgLogLum *)data_v;
	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			int pixel_index = (y * width + x) * 4;
			float input[4], output[4], mask[3] = {1.0f, 1.0f, 1.0f};
			/* Get input value. */
			if (rect_float) {
				copy_v4_v4(input, &rect_float[pixel_index]);
			}
			else {
				straight_uchar_to_premul_float(input, &rect[pixel_index]);
			}
			IMB_colormanagement_colorspace_to_scene_linear_v3(input, avg->colorspace);
			copy_v4_v4(output, input);
			/* Get mask value. */
			if (mask_rect_float) {
				copy_v3_v3(mask, mask_rect_float + pixel_index);
			}
			else if (mask_rect) {
				rgb_uchar_to_float(mask, mask_rect + pixel_index);
			}
			/* Apply correction. */
			mul_v3_fl(output, avg->al);
			float dr = output[0] + avg->tmmd->offset;
			float dg = output[1] + avg->tmmd->offset;
			float db = output[2] + avg->tmmd->offset;
			output[0] /= ((dr == 0.0f) ? 1.0f : dr);
			output[1] /= ((dg == 0.0f) ? 1.0f : dg);
			output[2] /= ((db == 0.0f) ? 1.0f : db);
			const float igm = avg->igm;
			if (igm != 0.0f) {
				output[0] = powf(max_ff(output[0], 0.0f), igm);
				output[1] = powf(max_ff(output[1], 0.0f), igm);
				output[2] = powf(max_ff(output[2], 0.0f), igm);
			}
			/* Apply mask. */
			output[0] = input[0] * (1.0f - mask[0]) + output[0] * mask[0];
			output[1] = input[1] * (1.0f - mask[1]) + output[1] * mask[1];
			output[2] = input[2] * (1.0f - mask[2]) + output[2] * mask[2];
			/* Copy result back. */
			IMB_colormanagement_scene_linear_to_colorspace_v3(output, avg->colorspace);
			if (rect_float) {
				copy_v4_v4(&rect_float[pixel_index], output);
			}
			else {
				premul_float_to_straight_uchar(&rect[pixel_index], output);
			}
		}
	}
}
示例#8
0
/* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickness, short dflag, short sflag)
{
	tGPspoint *pt;
	int i;
	
	/* error checking */
	if ((points == NULL) || (totpoints <= 0))
		return;
	
	/* check if buffer can be drawn */
	if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D))
		return;
	
	if (totpoints == 1) {
		/* if drawing a single point, draw it larger */
		glPointSize((float)(thickness + 2) * points->pressure);
		glBegin(GL_POINTS);
		glVertex2iv(&points->x);
		glEnd();
	}
	else if (sflag & GP_STROKE_ERASER) {
		/* don't draw stroke at all! */
	}
	else {
		float oldpressure = points[0].pressure;
		
		/* draw stroke curve */
		if (G.debug & G_DEBUG) setlinestyle(2);
		
		glLineWidth(max_ff(oldpressure * thickness, 1.0));
		glBegin(GL_LINE_STRIP);
		
		for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
			/* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
			 * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
			 */
			if (fabsf(pt->pressure - oldpressure) > 0.2f) {
				glEnd();
				glLineWidth(max_ff(pt->pressure * thickness, 1.0f));
				glBegin(GL_LINE_STRIP);
				
				/* need to roll-back one point to ensure that there are no gaps in the stroke */
				if (i != 0) glVertex2iv(&(pt - 1)->x);
				
				/* now the point we want... */
				glVertex2iv(&pt->x);
				
				oldpressure = pt->pressure;
			}
			else
				glVertex2iv(&pt->x);
		}
		glEnd();

		if (G.debug & G_DEBUG) setlinestyle(0);
	}
}
示例#9
0
static float P(float k)
{
	float p1, p2, p3, p4;
	p1 = max_ff(k + 2.0f, 0.0f);
	p2 = max_ff(k + 1.0f, 0.0f);
	p3 = max_ff(k, 0.0f);
	p4 = max_ff(k - 1.0f, 0.0f);
	return (float)(1.0f / 6.0f) * (p1 * p1 * p1 - 4.0f * p2 * p2 * p2 + 6.0f * p3 * p3 * p3 - 4.0f * p4 * p4 * p4);
}
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]);
}
void ConvertHSVToRGBOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
	float inputColor[4];
	this->m_inputOperation->readSampled(inputColor, x, y, sampler);
	hsv_to_rgb_v(inputColor, output);
	output[0] = max_ff(output[0], 0.0f);
	output[1] = max_ff(output[1], 0.0f);
	output[2] = max_ff(output[2], 0.0f);
	output[3] = inputColor[3];
}
示例#12
0
static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure)
{
	if (BKE_brush_use_alpha_pressure(painter->scene, brush))
		BKE_brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure));
	if (BKE_brush_use_size_pressure(painter->scene, brush))
		BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure));
	if (brush->flag & BRUSH_JITTER_PRESSURE)
		brush->jitter = max_ff(0.0f, painter->startjitter * pressure);
	if (brush->flag & BRUSH_SPACING_PRESSURE)
		brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure));
}
示例#13
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;
}
static void node_shader_exec_layer_weight(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
	ShadeInput *shi = ((ShaderCallData *)data)->shi;
	float blend = in[0]->vec[0];
	float eta = max_ff(1 - blend, 0.00001);

	float n[3];
	if (in[1]->hasinput) {
		copy_v3_v3(n, in[1]->vec);
	}
	else {
		copy_v3_v3(n, shi->vn);
	}

	if (shi->use_world_space_shading)
		mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), n);

	out[0]->vec[0] = RE_fresnel_dielectric(shi->view, n, shi->flippednor ? eta : 1/eta);

	float facing = fabs(dot_v3v3(shi->view, n));
	if (blend != 0.5) {
		CLAMP(blend, 0.0, 0.99999);
		blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend);
		facing = pow(facing, blend);
	}
	out[1]->vec[0] = 1.0 - facing;
}
示例#15
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;
}
示例#16
0
static void alpha_clip_aniso(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, int extflag, TexResult *texres)
{
	float alphaclip;
	rctf rf;

	/* TXF apha: we're doing the same alphaclip here as boxsample, but i'm doubting
	 * if this is actually correct for the all the filtering algorithms .. */

	if (!(extflag == TXC_REPT || extflag == TXC_EXTD)) {
		rf.xmin = minx*(ibuf->x);
		rf.xmax = maxx*(ibuf->x);
		rf.ymin = miny*(ibuf->y);
		rf.ymax = maxy*(ibuf->y);

		alphaclip  = clipx_rctf(&rf, 0.0, (float)(ibuf->x));
		alphaclip *= clipy_rctf(&rf, 0.0, (float)(ibuf->y));
		alphaclip  = max_ff(alphaclip, 0.0f);

		if (alphaclip!=1.0f) {
			/* premul it all */
			texres->tr*= alphaclip;
			texres->tg*= alphaclip;
			texres->tb*= alphaclip;
			texres->ta*= alphaclip;
		}
	}
}
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);
}
static void heat_set_H(LaplacianSystem *sys, int vertex)
{
	float dist, mindist, h;
	int j, numclosest = 0;

	mindist = 1e10;

	/* compute minimum distance */
	for (j = 0; j < sys->heat.numsource; j++) {
		dist = heat_source_distance(sys, vertex, j);

		if (dist < mindist)
			mindist = dist;
	}

	sys->heat.mindist[vertex] = mindist;

	/* count number of sources with approximately this minimum distance */
	for (j = 0; j < sys->heat.numsource; j++)
		if (heat_source_closest(sys, vertex, j))
			numclosest++;

	sys->heat.p[vertex] = (numclosest > 0) ? 1.0f / numclosest : 0.0f;

	/* compute H entry */
	if (numclosest > 0) {
		mindist = max_ff(mindist, 1e-4f);
		h = numclosest * C_WEIGHT / (mindist * mindist);
	}
	else
		h = 0.0f;
	
	sys->heat.H[vertex] = h;
}
示例#19
0
static int vertex_sort(const void *p1, const void *p2)
{
	BoxVert *v1, *v2;
	float a1, a2;

	v1 = vertarray + ((int *)p1)[0];
	v2 = vertarray + ((int *)p2)[0];

	a1 = max_ff(v1->x + box_width, v1->y + box_height);
	a2 = max_ff(v2->x + box_width, v2->y + box_height);

	/* sort largest to smallest */
	if      (a1 > a2) return 1;
	else if (a1 < a2) return -1;
	return 0;
}
示例#20
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;
}
示例#21
0
static void do_vert_pair(GPUVertBuf *vbo, uint pos, uint *vidx, int corner, int i)
{
  float inter[2], exter[2];
  inter[0] = cosf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f)));
  inter[1] = sinf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f)));

  /* Snap point to edge */
  float div = 1.0f / max_ff(fabsf(inter[0]), fabsf(inter[1]));
  mul_v2_v2fl(exter, inter, div);
  exter[0] = roundf(exter[0]);
  exter[1] = roundf(exter[1]);

  if (i == 0 || i == (CORNER_RESOLUTION - 1)) {
    copy_v2_v2(inter, exter);
  }

  /* Line width is 20% of the entire corner size. */
  const float line_width = 0.2f; /* Keep in sync with shader */
  mul_v2_fl(inter, 1.0f - line_width);
  mul_v2_fl(exter, 1.0f + line_width);

  switch (corner) {
    case 0:
      add_v2_v2(inter, (float[2]){-1.0f, -1.0f});
      add_v2_v2(exter, (float[2]){-1.0f, -1.0f});
示例#22
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]);
	}
}
示例#23
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]);
	}
}
示例#24
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_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;
}
示例#25
0
void curvemapping_set_black_white_ex(const float black[3], const float white[3], float r_bwmul[3])
{
	int a;

	for (a = 0; a < 3; a++) {
		const float delta = max_ff(white[a] - black[a], 1e-5f);
		r_bwmul[a] = 1.0f / delta;
	}
}
void GaussianAlphaXBlurOperation::updateGauss()
{
	if (this->m_gausstab == NULL) {
		updateSize();
		float rad = max_ff(m_size * m_data.sizex, 0.0f);
		m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
		
		m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
	}

	if (this->m_distbuf_inv == NULL) {
		updateSize();
		float rad = max_ff(m_size * m_data.sizex, 0.0f);
		m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
		
		m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);
	}
}
void GaussianYBlurOperation::updateGauss()
{
	if (this->m_gausstab == NULL) {
		updateSize();
		float rad = max_ff(m_size * m_data->sizey, 0.0f);
		m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
		
		this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);
	}
}
示例#28
0
/**
 * Overlap indices reference the looptri's
 */
BVHTreeOverlap *BKE_bmbvh_overlap(const BMBVHTree *bmtree_a, const BMBVHTree *bmtree_b, unsigned int *r_overlap_tot)
{
	struct BMBVHTree_OverlapData data;

	data.tree_pair[0] = bmtree_a;
	data.tree_pair[1] = bmtree_b;
	data.epsilon = max_ff(BLI_bvhtree_getepsilon(bmtree_a->tree), BLI_bvhtree_getepsilon(bmtree_b->tree));

	return BLI_bvhtree_overlap(bmtree_a->tree, bmtree_b->tree, r_overlap_tot, bmbvh_overlap_cb, &data);
}
示例#29
0
/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */
static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness, bool debug, short UNUSED(sflag))
{
	bGPDspoint *pt;
	float curpressure = points[0].pressure;
	int i;
	
	/* draw stroke curve */
	glLineWidth(max_ff(curpressure * thickness, 1.0f));
	glBegin(GL_LINE_STRIP);
	for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
		/* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
		 * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
		 * Note: we want more visible levels of pressures when thickness is bigger.
		 */
		if (fabsf(pt->pressure - curpressure) > 0.2f / (float)thickness) {
			glEnd();
			curpressure = pt->pressure;
			glLineWidth(max_ff(curpressure * thickness, 1.0f));
			glBegin(GL_LINE_STRIP);
			
			/* need to roll-back one point to ensure that there are no gaps in the stroke */
			if (i != 0) glVertex3fv(&(pt - 1)->x);
			
			/* now the point we want... */
			glVertex3fv(&pt->x);
		}
		else {
			glVertex3fv(&pt->x);
		}
	}
	glEnd();

	/* draw debug points of curve on top? */
	/* XXX: for now, we represent "selected" strokes in the same way as debug, which isn't used anymore */
	if (debug) {
		glPointSize((float)(thickness + 2));
		
		glBegin(GL_POINTS);
		for (i = 0, pt = points; i < totpoints && pt; i++, pt++)
			glVertex3fv(&pt->x);
		glEnd();
	}
}
static int track_mouse_area(const bContext *C, float co[2], MovieTrackingTrack *track)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	int framenr = ED_space_clip_get_clip_frame_number(sc);
	MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
	float pat_min[2], pat_max[2];
	float epsx, epsy;
	int width, height;

	ED_space_clip_get_size(sc, &width, &height);

	BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);

	epsx = min_ffff(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0],
	                fabsf(pat_min[0]), fabsf(pat_max[0])) / 2;
	epsy = min_ffff(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1],
	                fabsf(pat_min[1]), fabsf(pat_max[1])) / 2;

	epsx = max_ff(epsx, 2.0f / width);
	epsy = max_ff(epsy, 2.0f / height);

	if (sc->flag & SC_SHOW_MARKER_SEARCH) {
		if (mouse_on_rect(co, marker->pos, marker->search_min, marker->search_max, epsx, epsy))
			return TRACK_AREA_SEARCH;
	}

	if ((marker->flag & MARKER_DISABLED) == 0) {
		if (sc->flag & SC_SHOW_MARKER_PATTERN)
			if (mouse_on_crns(co, marker->pos, marker->pattern_corners, epsx, epsy))
				return TRACK_AREA_PAT;

		epsx = 12.0f / width;
		epsy = 12.0f / height;

		if (fabsf(co[0] - marker->pos[0] - track->offset[0]) < epsx &&
		    fabsf(co[1] - marker->pos[1] - track->offset[1]) <= epsy)
		{
			return TRACK_AREA_POINT;
		}
	}

	return TRACK_AREA_NONE;
}