Example #1
0
static void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points)[2], float (*diff_points)[2],
                                                            const unsigned int tot_diff_point, const float ofs,
                                                            const bool do_test)
{
	unsigned int k_prev = tot_diff_point - 2;
	unsigned int k_curr = tot_diff_point - 1;
	unsigned int k_next = 0;

	unsigned int k;

	float d_prev[2];
	float d_next[2];
	float d[2];

	const float *co_prev;
	const float *co_curr;
	const float *co_next;

	const float ofs_squared = ofs * ofs;

	co_prev = diff_points[k_prev];
	co_curr = diff_points[k_curr];
	co_next = diff_points[k_next];

	/* precalc */
	sub_v2_v2v2(d_prev, co_prev, co_curr);
	normalize_v2(d_prev);

	for (k = 0; k < tot_diff_point; k++) {

		/* co_prev = diff_points[k_prev]; */ /* precalc */
		co_curr = diff_points[k_curr];
		co_next = diff_points[k_next];

		/* sub_v2_v2v2(d_prev, co_prev, co_curr); */ /* precalc */
		sub_v2_v2v2(d_next, co_curr, co_next);

		/* normalize_v2(d_prev); */ /* precalc */
		normalize_v2(d_next);

		if ((do_test == FALSE) ||
		    (len_squared_v2v2(diff_feather_points[k], diff_points[k]) < ofs_squared))
		{

			add_v2_v2v2(d, d_prev, d_next);

			normalize_v2(d);

			diff_feather_points[k][0] = diff_points[k][0] + ( d[1] * ofs);
			diff_feather_points[k][1] = diff_points[k][1] + (-d[0] * ofs);
		}

		/* use next iter */
		copy_v2_v2(d_prev, d_next);

		/* k_prev = k_curr; */ /* precalc */
		k_curr = k_next;
		k_next++;
	}
}
Example #2
0
static void stencil_set_target(StencilControlData *scd)
{
	Brush *br = scd->br;
	float mdiff[2];
	if (scd->mask) {
		copy_v2_v2(scd->init_sdim, br->mask_stencil_dimension);
		copy_v2_v2(scd->init_spos, br->mask_stencil_pos);
		scd->init_rot = br->mask_mtex.rot;

		scd->dim_target = br->mask_stencil_dimension;
		scd->rot_target = &br->mask_mtex.rot;
		scd->pos_target = br->mask_stencil_pos;

		sub_v2_v2v2(mdiff, scd->init_mouse, br->mask_stencil_pos);
	}
	else {
		copy_v2_v2(scd->init_sdim, br->stencil_dimension);
		copy_v2_v2(scd->init_spos, br->stencil_pos);
		scd->init_rot = br->mtex.rot;

		scd->dim_target = br->stencil_dimension;
		scd->rot_target = &br->mtex.rot;
		scd->pos_target = br->stencil_pos;

		sub_v2_v2v2(mdiff, scd->init_mouse, br->stencil_pos);
	}

	scd->lenorig = len_v2(mdiff);

	scd->init_angle = atan2(mdiff[1], mdiff[0]);
}
static bool check_corners(float corners[4][2])
{
  int i, next, prev;
  float cross = 0.0f;

  for (i = 0; i < 4; i++) {
    float v1[2], v2[2], cur_cross;

    next = (i + 1) % 4;
    prev = (4 + i - 1) % 4;

    sub_v2_v2v2(v1, corners[i], corners[prev]);
    sub_v2_v2v2(v2, corners[next], corners[i]);

    cur_cross = cross_v2v2(v1, v2);
    if (fabsf(cur_cross) <= FLT_EPSILON) {
      return false;
    }

    if (cross == 0.0f) {
      cross = cur_cross;
    }
    else if (cross * cur_cross < 0.0f) {
      return false;
    }
  }

  return true;
}
Example #4
0
/* Use 2D quad corners to create a matrix that set
 * a [-1..1] quad at the right position. */
static void v2_quad_corners_to_mat4(float corners[4][2], float r_mat[4][4])
{
  unit_m4(r_mat);
  sub_v2_v2v2(r_mat[0], corners[1], corners[0]);
  sub_v2_v2v2(r_mat[1], corners[3], corners[0]);
  mul_v2_fl(r_mat[0], 0.5f);
  mul_v2_fl(r_mat[1], 0.5f);
  copy_v2_v2(r_mat[3], corners[0]);
  add_v2_v2(r_mat[3], r_mat[0]);
  add_v2_v2(r_mat[3], r_mat[1]);
}
Example #5
0
static void stencil_control_calculate(StencilControlData *scd, const int mval[2])
{
#define PIXEL_MARGIN 5

	float mdiff[2];
	float mvalf[2] = {mval[0], mval[1]};
	switch (scd->mode) {
		case STENCIL_TRANSLATE:
			sub_v2_v2v2(mdiff, mvalf, scd->init_mouse);
			add_v2_v2v2(scd->pos_target, scd->init_spos,
			            mdiff);
			CLAMP(scd->pos_target[0],
			      -scd->dim_target[0] + PIXEL_MARGIN,
			      scd->area_size[0] + scd->dim_target[0] - PIXEL_MARGIN);

			CLAMP(scd->pos_target[1],
			      -scd->dim_target[1] + PIXEL_MARGIN,
			      scd->area_size[1] + scd->dim_target[1] - PIXEL_MARGIN);

			break;
		case STENCIL_SCALE:
		{
			float len, factor;
			sub_v2_v2v2(mdiff, mvalf, scd->pos_target);
			len = len_v2(mdiff);
			factor = len / scd->lenorig;
			copy_v2_v2(mdiff, scd->init_sdim);
			if (scd->constrain_mode != STENCIL_CONSTRAINT_Y)
				mdiff[0] = factor * scd->init_sdim[0];
			if (scd->constrain_mode != STENCIL_CONSTRAINT_X)
				mdiff[1] = factor * scd->init_sdim[1];
			CLAMP(mdiff[0], 5.0f, 10000.0f);
			CLAMP(mdiff[1], 5.0f, 10000.0f);
			copy_v2_v2(scd->dim_target, mdiff);
			break;
		}
		case STENCIL_ROTATE:
		{
			float angle;
			sub_v2_v2v2(mdiff, mvalf, scd->pos_target);
			angle = atan2(mdiff[1], mdiff[0]);
			angle = scd->init_rot + angle - scd->init_angle;
			if (angle < 0.0f)
				angle += (float)(2 * M_PI);
			if (angle > (float)(2 * M_PI))
				angle -= (float)(2 * M_PI);
			*scd->rot_target = angle;
			break;
		}
	}
#undef PIXEL_MARGIN
}
MINLINE float len_manhattan_v2v2(const float a[2], const float b[2])
{
	float d[2];

	sub_v2_v2v2(d, b, a);
	return len_manhattan_v2(d);
}
Example #7
0
/* Project screenspace coordinates to 3D-space
 * NOTE: We include this as a utility function, since the standard method
 *       involves quite a few steps, which are invariably always the same
 *       for all GPencil operations. So, it's nicer to just centralise these.
 * WARNING: Assumes that it is getting called in a 3D view only
 */
bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen_co[2], float r_out[3])
{
	View3D *v3d = gsc->sa->spacedata.first;
	RegionView3D *rv3d = gsc->ar->regiondata;
	float *rvec = ED_view3d_cursor3d_get(scene, v3d);
	float ref[3] = {rvec[0], rvec[1], rvec[2]};
	float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
	
	float mval_f[2], mval_prj[2];
	float dvec[3];
	
	copy_v2_v2(mval_f, screen_co);
	
	if (ED_view3d_project_float_global(gsc->ar, ref, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
		sub_v2_v2v2(mval_f, mval_prj, mval_f);
		ED_view3d_win_to_delta(gsc->ar, mval_f, dvec, zfac);
		sub_v3_v3v3(r_out, rvec, dvec);
		
		return true;
	}
	else {
		zero_v3(r_out);
		
		return false;
	}
}
MINLINE float len_squared_v2v2(const float a[2], const float b[2])
{
	float d[2];

	sub_v2_v2v2(d, b, a);
	return dot_v2v2(d, d);
}
Example #9
0
void dist_ensure_v2_v2fl(float v1[2], const float v2[2], const float dist)
{
	if (!equals_v2v2(v2, v1)) {
		float nor[2];

		sub_v2_v2v2(nor, v1, v2);
		normalize_v2(nor);
		madd_v2_v2v2fl(v1, v2, nor, dist);
	}
}
static void marker_unified_to_search_pixel(int frame_width, int frame_height,
                                           const MovieTrackingMarker *marker,
                                           const float marker_unified[2], float search_pixel[2])
{
	float frame_pixel[2];
	float search_origin_frame_pixel[2];

	marker_unified_to_frame_pixel_coordinates(frame_width, frame_height, marker, marker_unified, frame_pixel);
	tracking_get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel);
	sub_v2_v2v2(search_pixel, frame_pixel, search_origin_frame_pixel);
}
/* Calculate stabilization data (translation, scale and rotation) from
 * given median of first and current frame medians, tracking data and
 * frame number.
 *
 * NOTE: frame number should be in clip space, not scene space
 */
static void stabilization_calculate_data(MovieTracking *tracking, int framenr, int width, int height,
                                         const float firstmedian[2], const float median[2],
                                         float translation[2], float *scale, float *angle)
{
	MovieTrackingStabilization *stab = &tracking->stabilization;

	*scale = (stab->scale - 1.0f) * stab->scaleinf + 1.0f;
	*angle = 0.0f;

	translation[0] = (firstmedian[0] - median[0]) * width * (*scale);
	translation[1] = (firstmedian[1] - median[1]) * height * (*scale);

	mul_v2_fl(translation, stab->locinf);

	if ((stab->flag & TRACKING_STABILIZE_ROTATION) && stab->rot_track && stab->rotinf) {
		MovieTrackingMarker *marker;
		float a[2], b[2];
		float x0 = (float)width / 2.0f, y0 = (float)height / 2.0f;
		float x = median[0] * width, y = median[1] * height;

		marker = BKE_tracking_marker_get(stab->rot_track, 1);
		sub_v2_v2v2(a, marker->pos, firstmedian);
		a[0] *= width;
		a[1] *= height;

		marker = BKE_tracking_marker_get(stab->rot_track, framenr);
		sub_v2_v2v2(b, marker->pos, median);
		b[0] *= width;
		b[1] *= height;

		*angle = -atan2f(a[0] * b[1] - a[1] * b[0], a[0] * b[0] + a[1] * b[1]);
		*angle *= stab->rotinf;

		/* convert to rotation around image center */
		translation[0] -= (x0 + (x - x0) * cosf(*angle) - (y - y0) * sinf(*angle) - x) * (*scale);
		translation[1] -= (y0 + (x - x0) * sinf(*angle) + (y - y0) * cosf(*angle) - y) * (*scale);
	}
}
static void search_pixel_to_marker_unified(int frame_width, int frame_height,
                                           const MovieTrackingMarker *marker,
                                           const float search_pixel[2], float marker_unified[2])
{
	float frame_unified[2];
	float search_origin_frame_pixel[2];

	tracking_get_search_origin_frame_pixel(frame_width, frame_height, marker, search_origin_frame_pixel);
	add_v2_v2v2(frame_unified, search_pixel, search_origin_frame_pixel);
	pixel_to_unified(frame_width, frame_height, frame_unified, frame_unified);

	/* marker pos is in frame unified */
	sub_v2_v2v2(marker_unified, frame_unified, marker->pos);
}
Example #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;
}
Example #14
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 #15
0
void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, const float mouse_pos[2])
{
	const float u = 0.5f;
	const float r = RAKE_THRESHHOLD;

	float dpos[2];
	sub_v2_v2v2(dpos, ups->last_rake, mouse_pos);

	if (len_squared_v2(dpos) >= r * r) {
		ups->brush_rotation = atan2(dpos[0], dpos[1]);

		interp_v2_v2v2(ups->last_rake, ups->last_rake,
		               mouse_pos, u);
	}
}
/**
 * \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;
}
static bool mesh_bisect_interactive_calc(
        bContext *C, wmOperator *op,
        BMEditMesh *em,
        float plane_co[3], float plane_no[3])
{
	wmGesture *gesture = op->customdata;
	BisectData *opdata;

	ARegion *ar = CTX_wm_region(C);
	RegionView3D *rv3d = ar->regiondata;

	int x_start = RNA_int_get(op->ptr, "xstart");
	int y_start = RNA_int_get(op->ptr, "ystart");
	int x_end = RNA_int_get(op->ptr, "xend");
	int y_end = RNA_int_get(op->ptr, "yend");

	/* reference location (some point in front of the view) for finding a point on a plane */
	const float *co_ref = rv3d->ofs;
	float co_a_ss[2] = {x_start, y_start}, co_b_ss[2] = {x_end, y_end}, co_delta_ss[2];
	float co_a[3], co_b[3];
	const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL);

	opdata = gesture->userdata;

	/* view vector */
	ED_view3d_win_to_vector(ar, co_a_ss, co_a);

	/* view delta */
	sub_v2_v2v2(co_delta_ss, co_a_ss, co_b_ss);
	ED_view3d_win_to_delta(ar, co_delta_ss, co_b, zfac);

	/* cross both to get a normal */
	cross_v3_v3v3(plane_no, co_a, co_b);
	normalize_v3(plane_no);  /* not needed but nicer for user */

	/* point on plane, can use either start or endpoint */
	ED_view3d_win_to_3d(ar, co_ref, co_a_ss, plane_co);

	if (opdata->is_first == false)
		EDBM_redo_state_restore(opdata->mesh_backup, em, false);

	opdata->is_first = false;

	return true;
}
Example #18
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 #19
0
static int paintcurve_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
	PointSlideData *psd = op->customdata;

	if (event->type == psd->event && event->val == KM_RELEASE) {
		MEM_freeN(psd);
		ED_paintcurve_undo_push_begin(op->type->name);
		ED_paintcurve_undo_push_end();
		return OPERATOR_FINISHED;
	}

	switch (event->type) {
		case MOUSEMOVE:
		{
			ARegion *ar = CTX_wm_region(C);
			wmWindow *window = CTX_wm_window(C);
			float diff[2] = {
				event->mval[0] - psd->initial_loc[0],
				event->mval[1] - psd->initial_loc[1]};
			if (psd->select == 1) {
				int i;
				for (i = 0; i < 3; i++)
					add_v2_v2v2(psd->pcp->bez.vec[i], diff, psd->point_initial_loc[i]);
			}
			else {
				add_v2_v2(diff, psd->point_initial_loc[psd->select]);
				copy_v2_v2(psd->pcp->bez.vec[psd->select], diff);

				if (psd->align) {
					char opposite = (psd->select == 0) ? 2 : 0;
					sub_v2_v2v2(diff, psd->pcp->bez.vec[1], psd->pcp->bez.vec[psd->select]);
					add_v2_v2v2(psd->pcp->bez.vec[opposite], psd->pcp->bez.vec[1], diff);
				}
			}
			WM_paint_cursor_tag_redraw(window, ar);
			break;
		}
		default:
			break;
	}

	return OPERATOR_RUNNING_MODAL;
}
Example #20
0
float BLI_dial_angle(Dial *dial, float current_position[2])
{
	float current_direction[2];
	
	sub_v2_v2v2(current_direction, current_position, dial->center);

	/* only update when we have enough precision, by having the mouse adequately away from center */
	if (len_squared_v2(current_direction) > dial->threshold_squared) {
		float angle;
		float cosval, sinval;

		normalize_v2(current_direction);

		if (!dial->initialized) {
			copy_v2_v2(dial->initial_direction, current_direction);
			dial->initialized = true;
		}
		
		/* calculate mouse angle between initial and final mouse position */
		cosval = dot_v2v2(current_direction, dial->initial_direction);
		sinval = cross_v2v2(current_direction, dial->initial_direction);
		
		/* clamp to avoid nans in acos */
		angle = atan2f(sinval, cosval);
		
		/* change of sign, we passed the 180 degree threshold. This means we need to add a turn.
		 * to distinguish between transition from 0 to -1 and -PI to +PI, use comparison with PI/2 */
		if ((angle * dial->last_angle < 0.0f) &&
		    (fabsf(dial->last_angle) > (float)M_PI_2))
		{
			if (dial->last_angle < 0.0f)
				dial->rotations--;
			else
				dial->rotations++;
		}
		dial->last_angle = angle;
		
		return angle + 2.0f * (float)M_PI * dial->rotations;
	}
	
	return dial->last_angle;
}
Example #21
0
static void tracking_error_segment_point_cb(void *userdata,
                                            MovieTrackingTrack *track, MovieTrackingMarker *marker,
                                            int coord, int scene_framenr, float UNUSED(value))
{
	if (coord == 1) {
		TrackErrorCurveUserData *data = (TrackErrorCurveUserData *) userdata;
		float reprojected_position[4], bundle_position[4], marker_position[2], delta[2];
		float reprojection_error;
		float weight = BKE_tracking_track_get_weight_for_marker(data->clip, track, marker);

		if (!data->matrix_initialized || data->matrix_frame != scene_framenr) {
			BKE_tracking_get_projection_matrix(data->tracking, data->tracking_object,
			                                   scene_framenr, data->width, data->height,
			                                   data->projection_matrix);
		}

		copy_v3_v3(bundle_position, track->bundle_pos);
		bundle_position[3] = 1;

		mul_v4_m4v4(reprojected_position, data->projection_matrix, bundle_position);
		reprojected_position[0] = (reprojected_position[0] /
		                          (reprojected_position[3] * 2.0f) + 0.5f) * data->width;
		reprojected_position[1] = (reprojected_position[1] /
		                          (reprojected_position[3] * 2.0f) + 0.5f) * data->height * data->aspy;

		BKE_tracking_distort_v2(data->tracking, reprojected_position, reprojected_position);

		marker_position[0] = (marker->pos[0] + track->offset[0]) * data->width;
		marker_position[1] = (marker->pos[1] + track->offset[1]) * data->height * data->aspy;

		sub_v2_v2v2(delta, reprojected_position, marker_position);
		reprojection_error = len_v2(delta) * weight;

		glVertex2f(scene_framenr, reprojection_error);
	}
}
Example #22
0
UvVertMap *BKE_mesh_uv_vert_map_create(
        struct MPoly *mpoly, struct MLoop *mloop, struct MLoopUV *mloopuv,
        unsigned int totpoly, unsigned int totvert,
        const float limit[2], const bool selected, const bool use_winding)
{
	UvVertMap *vmap;
	UvMapVert *buf;
	MPoly *mp;
	unsigned int a;
	int i, totuv, nverts;

	bool *winding = NULL;
	BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, 32);

	totuv = 0;

	/* generate UvMapVert array */
	mp = mpoly;
	for (a = 0; a < totpoly; a++, mp++)
		if (!selected || (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL)))
			totuv += mp->totloop;

	if (totuv == 0)
		return NULL;

	vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap");
	buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * (size_t)totuv, "UvMapVert");
	vmap->vert = (UvMapVert **)MEM_callocN(sizeof(*vmap->vert) * totvert, "UvMapVert*");
	if (use_winding) {
		winding = MEM_callocN(sizeof(*winding) * totpoly, "winding");
	}

	if (!vmap->vert || !vmap->buf) {
		BKE_mesh_uv_vert_map_free(vmap);
		return NULL;
	}

	mp = mpoly;
	for (a = 0; a < totpoly; a++, mp++) {
		if (!selected || (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL))) {
			float (*tf_uv)[2] = NULL;

			if (use_winding) {
				tf_uv = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, (size_t)mp->totloop);
			}

			nverts = mp->totloop;

			for (i = 0; i < nverts; i++) {
				buf->tfindex = (unsigned char)i;
				buf->f = a;
				buf->separate = 0;
				buf->next = vmap->vert[mloop[mp->loopstart + i].v];
				vmap->vert[mloop[mp->loopstart + i].v] = buf;

				if (use_winding) {
					copy_v2_v2(tf_uv[i], mloopuv[mpoly[a].loopstart + i].uv);
				}

				buf++;
			}

			if (use_winding) {
				winding[a] = cross_poly_v2((const float (*)[2])tf_uv, (unsigned int)nverts) > 0;
			}
		}
	}

	/* sort individual uvs for each vert */
	for (a = 0; a < totvert; a++) {
		UvMapVert *newvlist = NULL, *vlist = vmap->vert[a];
		UvMapVert *iterv, *v, *lastv, *next;
		float *uv, *uv2, uvdiff[2];

		while (vlist) {
			v = vlist;
			vlist = vlist->next;
			v->next = newvlist;
			newvlist = v;

			uv = mloopuv[mpoly[v->f].loopstart + v->tfindex].uv;
			lastv = NULL;
			iterv = vlist;

			while (iterv) {
				next = iterv->next;

				uv2 = mloopuv[mpoly[iterv->f].loopstart + iterv->tfindex].uv;
				sub_v2_v2v2(uvdiff, uv2, uv);


				if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1] &&
				    (!use_winding || winding[iterv->f] == winding[v->f]))
				{
					if (lastv) lastv->next = next;
					else vlist = next;
					iterv->next = newvlist;
					newvlist = iterv;
				}
				else
					lastv = iterv;

				iterv = next;
			}

			newvlist->separate = 1;
		}

		vmap->vert[a] = newvlist;
	}

	if (use_winding)  {
		MEM_freeN(winding);
	}

	BLI_buffer_free(&tf_uv_buf);

	return vmap;
}
Example #23
0
/* reduced copy of garbled calchandleNurb() code in curve.c */
static void calchandle_curvemap(BezTriple *bezt, BezTriple *prev, BezTriple *next, int UNUSED(mode))
{
	float *p1, *p2, *p3, pt[3];
	float len, len_a, len_b;
	float dvec_a[2], dvec_b[2];

	if (bezt->h1 == 0 && bezt->h2 == 0) {
		return;
	}
	
	p2 = bezt->vec[1];
	
	if (prev == NULL) {
		p3 = next->vec[1];
		pt[0] = 2.0f * p2[0] - p3[0];
		pt[1] = 2.0f * p2[1] - p3[1];
		p1 = pt;
	}
	else {
		p1 = prev->vec[1];
	}
	
	if (next == NULL) {
		p1 = prev->vec[1];
		pt[0] = 2.0f * p2[0] - p1[0];
		pt[1] = 2.0f * p2[1] - p1[1];
		p3 = pt;
	}
	else {
		p3 = next->vec[1];
	}

	sub_v2_v2v2(dvec_a, p2, p1);
	sub_v2_v2v2(dvec_b, p3, p2);

	len_a = len_v2(dvec_a);
	len_b = len_v2(dvec_b);

	if (len_a == 0.0f) len_a = 1.0f;
	if (len_b == 0.0f) len_b = 1.0f;

	if (bezt->h1 == HD_AUTO || bezt->h2 == HD_AUTO) { /* auto */
		float tvec[2];
		tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a;
		tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a;

		len = len_v2(tvec) * 2.5614f;
		if (len != 0.0f) {
			
			if (bezt->h1 == HD_AUTO) {
				len_a /= len;
				madd_v2_v2v2fl(p2 - 3, p2, tvec, -len_a);
			}
			if (bezt->h2 == HD_AUTO) {
				len_b /= len;
				madd_v2_v2v2fl(p2 + 3, p2, tvec,  len_b);
			}
		}
	}

	if (bezt->h1 == HD_VECT) {    /* vector */
		madd_v2_v2v2fl(p2 - 3, p2, dvec_a, -1.0f / 3.0f);
	}
	if (bezt->h2 == HD_VECT) {
		madd_v2_v2v2fl(p2 + 3, p2, dvec_b,  1.0f / 3.0f);
	}
}
Example #24
0
static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
	SlidePointData *data = (SlidePointData *)op->customdata;
	BezTriple *bezt = &data->point->bezt;
	float co[2], dco[2];

	switch (event->type) {
		case LEFTALTKEY:
		case RIGHTALTKEY:
		case LEFTSHIFTKEY:
		case RIGHTSHIFTKEY:
			if (ELEM(event->type, LEFTALTKEY, RIGHTALTKEY)) {
				if (data->action == SLIDE_ACTION_FEATHER)
					data->overall_feather = (event->val == KM_PRESS);
				else
					data->curvature_only = (event->val == KM_PRESS);
			}

			if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY))
				data->accurate = (event->val == KM_PRESS);

			/* fall-through */  /* update CV position */
		case MOUSEMOVE:
		{
			ScrArea *sa = CTX_wm_area(C);
			ARegion *ar = CTX_wm_region(C);

			ED_mask_mouse_pos(sa, ar, event->mval, co);
			sub_v2_v2v2(dco, co, data->co);

			if (data->action == SLIDE_ACTION_HANDLE) {
				float delta[2], offco[2];

				sub_v2_v2v2(delta, data->handle, data->co);

				sub_v2_v2v2(offco, co, data->co);
				if (data->accurate)
					mul_v2_fl(offco, 0.2f);
				add_v2_v2(offco, data->co);
				add_v2_v2(offco, delta);

				BKE_mask_point_set_handle(data->point, offco, data->curvature_only, data->handle, data->vec);
			}
			else if (data->action == SLIDE_ACTION_POINT) {
				float delta[2];

				copy_v2_v2(delta, dco);
				if (data->accurate)
					mul_v2_fl(delta, 0.2f);

				add_v2_v2v2(bezt->vec[0], data->vec[0], delta);
				add_v2_v2v2(bezt->vec[1], data->vec[1], delta);
				add_v2_v2v2(bezt->vec[2], data->vec[2], delta);
			}
			else if (data->action == SLIDE_ACTION_FEATHER) {
				float vec[2], no[2], p[2], c[2], w, offco[2];
				float *weight = NULL;
				float weight_scalar = 1.0f;
				int overall_feather = data->overall_feather || data->initial_feather;

				add_v2_v2v2(offco, data->feather, dco);

				if (data->uw) {
					/* project on both sides and find the closest one,
					 * prevents flickering when projecting onto both sides can happen */
					const float u_pos = BKE_mask_spline_project_co(data->spline, data->point,
					                                               data->uw->u, offco, MASK_PROJ_NEG);
					const float u_neg = BKE_mask_spline_project_co(data->spline, data->point,
					                                               data->uw->u, offco, MASK_PROJ_POS);
					float dist_pos = FLT_MAX;
					float dist_neg = FLT_MAX;
					float co_pos[2];
					float co_neg[2];
					float u;

					if (u_pos > 0.0f && u_pos < 1.0f) {
						BKE_mask_point_segment_co(data->spline, data->point, u_pos, co_pos);
						dist_pos = len_squared_v2v2(offco, co_pos);
					}

					if (u_neg > 0.0f && u_neg < 1.0f) {
						BKE_mask_point_segment_co(data->spline, data->point, u_neg, co_neg);
						dist_neg = len_squared_v2v2(offco, co_neg);
					}

					u = dist_pos < dist_neg ? u_pos : u_neg;

					if (u > 0.0f && u < 1.0f) {
						data->uw->u = u;

						data->uw = BKE_mask_point_sort_uw(data->point, data->uw);
						weight = &data->uw->w;
						weight_scalar = BKE_mask_point_weight_scalar(data->spline, data->point, u);
						if (weight_scalar != 0.0f) {
							weight_scalar = 1.0f / weight_scalar;
						}

						BKE_mask_point_normal(data->spline, data->point, data->uw->u, no);
						BKE_mask_point_segment_co(data->spline, data->point, data->uw->u, p);
					}
				}
				else {
					weight = &bezt->weight;
					/* weight_scalar = 1.0f; keep as is */
					copy_v2_v2(no, data->no);
					copy_v2_v2(p, bezt->vec[1]);
				}

				if (weight) {
					sub_v2_v2v2(c, offco, p);
					project_v2_v2v2(vec, c, no);

					w = len_v2(vec);

					if (overall_feather) {
						float delta;

						if (dot_v2v2(no, vec) <= 0.0f)
							w = -w;

						delta = w - data->weight * data->weight_scalar;

						if (data->orig_spline == NULL) {
							/* restore weight for currently sliding point, so orig_spline would be created
							 * with original weights used
							 */
							*weight = data->weight;

							data->orig_spline = BKE_mask_spline_copy(data->spline);
						}

						slide_point_delta_all_feather(data, delta);
					}
					else {
						if (dot_v2v2(no, vec) <= 0.0f)
							w = 0.0f;

						if (data->orig_spline) {
							/* restore possible overall feather changes */
							slide_point_restore_spline(data);

							BKE_mask_spline_free(data->orig_spline);
							data->orig_spline = NULL;
						}

						if (weight_scalar != 0.0f) {
							*weight = w * weight_scalar;
						}
					}
				}
			}

			WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask);
			DAG_id_tag_update(&data->mask->id, 0);

			break;
		}

		case LEFTMOUSE:
			if (event->val == KM_RELEASE) {
				Scene *scene = CTX_data_scene(C);

				/* dont key sliding feather uw's */
				if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == FALSE) {
					if (IS_AUTOKEY_ON(scene)) {
						ED_mask_layer_shape_auto_key(data->masklay, CFRA);
					}
				}

				WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask);
				DAG_id_tag_update(&data->mask->id, 0);

				free_slide_point_data(op->customdata); /* keep this last! */
				return OPERATOR_FINISHED;
			}

			break;

		case ESCKEY:
			cancel_slide_point(op->customdata);

			WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask);
			DAG_id_tag_update(&data->mask->id, 0);

			free_slide_point_data(op->customdata); /* keep this last! */
			return OPERATOR_CANCELLED;
	}

	return OPERATOR_RUNNING_MODAL;
}
Example #25
0
bool ED_mask_find_nearest_diff_point(const bContext *C,
                                     struct Mask *mask,
                                     const float normal_co[2],
                                     int threshold, bool feather,
                                     MaskLayer **masklay_r,
                                     MaskSpline **spline_r,
                                     MaskSplinePoint **point_r,
                                     float *u_r, float tangent[2],
                                     const bool use_deform,
                                     const bool use_project)
{
	ScrArea *sa = CTX_wm_area(C);
	ARegion *ar = CTX_wm_region(C);

	MaskLayer *masklay, *point_masklay;
	MaskSpline *point_spline;
	MaskSplinePoint *point = NULL;
	float dist = FLT_MAX, co[2];
	int width, height;
	float u;
	float scalex, scaley;

	ED_mask_get_size(sa, &width, &height);
	ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley);

	co[0] = normal_co[0] * scalex;
	co[1] = normal_co[1] * scaley;

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			int i;
			MaskSplinePoint *cur_point;

			for (i = 0, cur_point = use_deform ? spline->points_deform : spline->points;
			     i < spline->tot_point;
			     i++, cur_point++)
			{
				float *diff_points;
				unsigned int tot_diff_point;

				diff_points = BKE_mask_point_segment_diff(spline, cur_point, width, height,
				                                          &tot_diff_point);

				if (diff_points) {
					int j, tot_point;
					unsigned int tot_feather_point;
					float *feather_points = NULL, *points;

					if (feather) {
						feather_points = BKE_mask_point_segment_feather_diff(spline, cur_point,
						                                                     width, height,
						                                                     &tot_feather_point);

						points = feather_points;
						tot_point = tot_feather_point;
					}
					else {
						points = diff_points;
						tot_point = tot_diff_point;
					}

					for (j = 0; j < tot_point - 1; j++) {
						float cur_dist, a[2], b[2];

						a[0] = points[2 * j] * scalex;
						a[1] = points[2 * j + 1] * scaley;

						b[0] = points[2 * j + 2] * scalex;
						b[1] = points[2 * j + 3] * scaley;

						cur_dist = dist_to_line_segment_v2(co, a, b);

						if (cur_dist < dist) {
							if (tangent)
								sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]);

							point_masklay = masklay;
							point_spline = spline;
							point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point;
							dist = cur_dist;
							u = (float)j / tot_point;
						}
					}

					if (feather_points)
						MEM_freeN(feather_points);

					MEM_freeN(diff_points);
				}
			}
		}
	}

	if (point && dist < threshold) {
		if (masklay_r)
			*masklay_r = point_masklay;

		if (spline_r)
			*spline_r = point_spline;

		if (point_r)
			*point_r = point;

		if (u_r) {
			/* TODO(sergey): Projection fails in some weirdo cases.. */
			if (use_project) {
				u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY);
			}

			*u_r = u;
		}

		return true;
	}

	if (masklay_r)
		*masklay_r = NULL;

	if (spline_r)
		*spline_r = NULL;

	if (point_r)
		*point_r = NULL;

	return false;
}
Example #26
0
static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *arg)
{
	Scene *scene = CTX_data_scene(C);
	UnitSettings *unit = &scene->unit;
	RulerItem *ruler_item;
	RulerInfo *ruler_info = arg;
	RegionView3D *rv3d = ruler_info->ar->regiondata;
//	ARegion *ar = ruler_info->ar;
	const float cap_size = 4.0f;
	const float bg_margin = 4.0f * U.pixelsize;
	const float bg_radius = 4.0f * U.pixelsize;
	const float arc_size = 64.0f * U.pixelsize;
#define ARC_STEPS 24
	const int arc_steps = ARC_STEPS;
	int i;
	//unsigned int color_act = 0x666600;
	unsigned int color_act = 0xffffff;
	unsigned int color_base = 0x0;
	unsigned char color_back[4] = {0xff, 0xff, 0xff, 0x80};
	unsigned char color_text[3];
	unsigned char color_wire[3];

	/* anti-aliased lines for more consistent appearance */
	glEnable(GL_LINE_SMOOTH);

	BLF_enable(blf_mono_font, BLF_ROTATION);
	BLF_size(blf_mono_font, 14 * U.pixelsize, U.dpi);
	BLF_rotation(blf_mono_font, 0.0f);

	UI_GetThemeColor3ubv(TH_TEXT, color_text);
	UI_GetThemeColor3ubv(TH_WIRE, color_wire);

	for (ruler_item = ruler_info->items.first, i = 0; ruler_item; ruler_item = ruler_item->next, i++) {
		const bool is_act = (i == ruler_info->item_active);
		float dir_ruler[2];
		float co_ss[3][2];
		int j;

		/* should these be checked? - ok for now not to */
		for (j = 0; j < 3; j++) {
			ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP);
		}

		glEnable(GL_BLEND);

		cpack(is_act ? color_act : color_base);

		if (ruler_item->flag & RULERITEM_USE_ANGLE) {
			glBegin(GL_LINE_STRIP);
			for (j = 0; j < 3; j++) {
				glVertex2fv(co_ss[j]);
			}
			glEnd();
			cpack(0xaaaaaa);
			setlinestyle(3);
			glBegin(GL_LINE_STRIP);
			for (j = 0; j < 3; j++) {
				glVertex2fv(co_ss[j]);
			}
			glEnd();
			setlinestyle(0);

			/* arc */
			{
				float dir_tmp[3];
				float co_tmp[3];
				float arc_ss_coords[ARC_STEPS + 1][2];

				float dir_a[3];
				float dir_b[3];
				float quat[4];
				float axis[3];
				float angle;
				const float px_scale = (ED_view3d_pixel_size(rv3d, ruler_item->co[1]) *
				                        min_fff(arc_size,
				                                len_v2v2(co_ss[0], co_ss[1]) / 2.0f,
				                                len_v2v2(co_ss[2], co_ss[1]) / 2.0f));

				sub_v3_v3v3(dir_a, ruler_item->co[0], ruler_item->co[1]);
				sub_v3_v3v3(dir_b, ruler_item->co[2], ruler_item->co[1]);
				normalize_v3(dir_a);
				normalize_v3(dir_b);

				cross_v3_v3v3(axis, dir_a, dir_b);
				angle = angle_normalized_v3v3(dir_a, dir_b);

				axis_angle_to_quat(quat, axis, angle / arc_steps);

				copy_v3_v3(dir_tmp, dir_a);

				glColor3ubv(color_wire);

				for (j = 0; j <= arc_steps; j++) {
					madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale);
					ED_view3d_project_float_global(ar, co_tmp, arc_ss_coords[j], V3D_PROJ_TEST_NOP);
					mul_qt_v3(quat, dir_tmp);
				}

				glEnableClientState(GL_VERTEX_ARRAY);
				glVertexPointer(2, GL_FLOAT, 0, arc_ss_coords);
				glDrawArrays(GL_LINE_STRIP, 0, arc_steps + 1);
				glDisableClientState(GL_VERTEX_ARRAY);
			}

			/* text */
			{
				char numstr[256];
				float numstr_size[2];
				float pos[2];
				const int prec = 2;  /* XXX, todo, make optional */

				ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);

				BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);

				pos[0] = co_ss[1][0] + (cap_size * 2.0f);
				pos[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);

				/* draw text (bg) */
				glColor4ubv(color_back);
				uiSetRoundBox(UI_CNR_ALL);
				uiRoundBox(pos[0] - bg_margin,                  pos[1] - bg_margin,
				           pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
				           bg_radius);
				/* draw text */
				glColor3ubv(color_text);
				BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
				BLF_rotation(blf_mono_font, 0.0f);
				BLF_draw(blf_mono_font, numstr, sizeof(numstr));
			}

			/* capping */
			{
				float rot_90_vec_a[2];
				float rot_90_vec_b[2];
				float cap[2];

				sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[1]);
				rot_90_vec_a[0] = -dir_ruler[1];
				rot_90_vec_a[1] =  dir_ruler[0];
				normalize_v2(rot_90_vec_a);

				sub_v2_v2v2(dir_ruler, co_ss[1], co_ss[2]);
				rot_90_vec_b[0] = -dir_ruler[1];
				rot_90_vec_b[1] =  dir_ruler[0];
				normalize_v2(rot_90_vec_b);

				glEnable(GL_BLEND);

				glColor3ubv(color_wire);

				glBegin(GL_LINES);

				madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
				glVertex2fv(cap);
				madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
				glVertex2fv(cap);

				madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
				glVertex2fv(cap);
				madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
				glVertex2fv(cap);

				/* angle vertex */
				glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
				glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
				glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
				glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
				glEnd();

				glDisable(GL_BLEND);
			}
		}
		else {
			glBegin(GL_LINE_STRIP);
			for (j = 0; j < 3; j += 2) {
				glVertex2fv(co_ss[j]);
			}
			glEnd();
			cpack(0xaaaaaa);
			setlinestyle(3);
			glBegin(GL_LINE_STRIP);
			for (j = 0; j < 3; j += 2) {
				glVertex2fv(co_ss[j]);
			}
			glEnd();
			setlinestyle(0);

			sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);

			/* text */
			{
				char numstr[256];
				float numstr_size[2];
				const int prec = 6;  /* XXX, todo, make optional */
				float pos[2];

				ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);

				BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]);

				mid_v2_v2v2(pos, co_ss[0], co_ss[2]);

				/* center text */
				pos[0] -= numstr_size[0] / 2.0f;
				pos[1] -= numstr_size[1] / 2.0f;

				/* draw text (bg) */
				glColor4ubv(color_back);
				uiSetRoundBox(UI_CNR_ALL);
				uiRoundBox(pos[0] - bg_margin,                  pos[1] - bg_margin,
				           pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
				           bg_radius);
				/* draw text */
				glColor3ubv(color_text);
				BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
				BLF_draw(blf_mono_font, numstr, sizeof(numstr));
			}

			/* capping */
			{
				float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]};
				float cap[2];

				normalize_v2(rot_90_vec);

				glEnable(GL_BLEND);
				glColor3ubv(color_wire);

				glBegin(GL_LINES);
				madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
				glVertex2fv(cap);
				madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
				glVertex2fv(cap);

				madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
				glVertex2fv(cap);
				madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
				glVertex2fv(cap);
				glEnd();

				glDisable(GL_BLEND);
			}
		}
	}

	glDisable(GL_LINE_SMOOTH);

	BLF_disable(blf_mono_font, BLF_ROTATION);

#undef ARC_STEPS

	/* draw snap */
	if ((ruler_info->snap_flag & RULER_SNAP_OK) && (ruler_info->state == RULER_STATE_DRAG)) {
		ruler_item = ruler_item_active_get(ruler_info);
		if (ruler_item) {
			/* size from drawSnapping */
			const float size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
			float co_ss[3];
			ED_view3d_project_float_global(ar, ruler_item->co[ruler_item->co_index], co_ss, V3D_PROJ_TEST_NOP);

			cpack(color_act);
			circ(co_ss[0], co_ss[1], size * U.pixelsize);
		}
	}

}
static void setNearestAxis3d(TransInfo *t)
{
	float zfac;
	float mvec[3], proj[3];
	float len[3];
	int i;

	/* calculate mouse movement */
	mvec[0] = (float)(t->mval[0] - t->con.imval[0]);
	mvec[1] = (float)(t->mval[1] - t->con.imval[1]);
	mvec[2] = 0.0f;

	/* we need to correct axis length for the current zoomlevel of view,
	 * this to prevent projected values to be clipped behind the camera
	 * and to overflow the short integers.
	 * The formula used is a bit stupid, just a simplification of the subtraction
	 * of two 2D points 30 pixels apart (that's the last factor in the formula) after
	 * projecting them with ED_view3d_win_to_delta and then get the length of that vector.
	 */
	zfac = mul_project_m4_v3_zfac(t->persmat, t->center);
	zfac = len_v3(t->persinv[0]) * 2.0f / t->ar->winx * zfac * 30.0f;

	for (i = 0; i < 3; i++) {
		float axis[3], axis_2d[2];

		copy_v3_v3(axis, t->con.mtx[i]);

		mul_v3_fl(axis, zfac);
		/* now we can project to get window coordinate */
		add_v3_v3(axis, t->center_global);
		projectFloatView(t, axis, axis_2d);

		sub_v2_v2v2(axis, axis_2d, t->center2d);
		axis[2] = 0.0f;

		if (normalize_v3(axis) > 1e-3f) {
			project_v3_v3v3(proj, mvec, axis);
			sub_v3_v3v3(axis, mvec, proj);
			len[i] = normalize_v3(axis);
		}
		else {
			len[i] = 1e10f;
		}
	}

	if (len[0] <= len[1] && len[0] <= len[2]) {
		if (t->modifiers & MOD_CONSTRAINT_PLANE) {
			t->con.mode |= (CON_AXIS1 | CON_AXIS2);
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s X axis"), t->spacename);
		}
		else {
			t->con.mode |= CON_AXIS0;
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s X axis"), t->spacename);
		}
	}
	else if (len[1] <= len[0] && len[1] <= len[2]) {
		if (t->modifiers & MOD_CONSTRAINT_PLANE) {
			t->con.mode |= (CON_AXIS0 | CON_AXIS2);
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s Y axis"), t->spacename);
		}
		else {
			t->con.mode |= CON_AXIS1;
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s Y axis"), t->spacename);
		}
	}
	else if (len[2] <= len[1] && len[2] <= len[0]) {
		if (t->modifiers & MOD_CONSTRAINT_PLANE) {
			t->con.mode |= (CON_AXIS0 | CON_AXIS1);
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s Z axis"), t->spacename);
		}
		else {
			t->con.mode |= CON_AXIS2;
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s Z axis"), t->spacename);
		}
	}
}
Example #28
0
static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
                              const float marker_pos[2], int width, int height, int act, int sel)
{
	int tiny = sc->flag & SC_SHOW_TINY_MARKER;
	bool show_search = false;
	float col[3], scol[3], px[2];

	track_colors(track, act, col, scol);

	px[0] = 1.0f / width / sc->zoom;
	px[1] = 1.0f / height / sc->zoom;

	/* marker position and offset position */
	if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) {
		float pos[2], p[2];

		if (track->flag & TRACK_LOCKED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->flag & SELECT)
				UI_ThemeColorShade(TH_LOCK_MARKER, 64);
			else
				UI_ThemeColor(TH_LOCK_MARKER);
		}
		else {
			if (track->flag & SELECT)
				glColor3fv(scol);
			else
				glColor3fv(col);
		}

		add_v2_v2v2(pos, marker->pos, track->offset);
		ED_clip_point_undistorted_pos(sc, pos, pos);

		sub_v2_v2v2(p, pos, marker_pos);

		if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
		                        marker->pattern_corners[2], marker->pattern_corners[3]))
		{
			if (!tiny)
				glPointSize(2.0f);

			glBegin(GL_POINTS);
			glVertex2f(pos[0], pos[1]);
			glEnd();

			if (!tiny)
				glPointSize(1.0f);
		}
		else {
			glBegin(GL_LINES);
			glVertex2f(pos[0] + px[0] * 3, pos[1]);
			glVertex2f(pos[0] + px[0] * 7, pos[1]);

			glVertex2f(pos[0] - px[0] * 3, pos[1]);
			glVertex2f(pos[0] - px[0] * 7, pos[1]);

			glVertex2f(pos[0], pos[1] - px[1] * 3);
			glVertex2f(pos[0], pos[1] - px[1] * 7);

			glVertex2f(pos[0], pos[1] + px[1] * 3);
			glVertex2f(pos[0], pos[1] + px[1] * 7);
			glEnd();

			glColor3f(0.0f, 0.0f, 0.0f);
			glLineStipple(3, 0xaaaa);
			glEnable(GL_LINE_STIPPLE);
			glEnable(GL_COLOR_LOGIC_OP);
			glLogicOp(GL_NOR);

			glBegin(GL_LINES);
			glVertex2fv(pos);
			glVertex2fv(marker_pos);
			glEnd();

			glDisable(GL_COLOR_LOGIC_OP);
			glDisable(GL_LINE_STIPPLE);
		}
	}

	/* pattern */
	glPushMatrix();
	glTranslatef(marker_pos[0], marker_pos[1], 0);

	if (tiny) {
		glLineStipple(3, 0xaaaa);
		glEnable(GL_LINE_STIPPLE);
	}

	if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
		if (track->flag & TRACK_LOCKED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->pat_flag & SELECT)
				UI_ThemeColorShade(TH_LOCK_MARKER, 64);
			else UI_ThemeColor(TH_LOCK_MARKER);
		}
		else if (marker->flag & MARKER_DISABLED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->pat_flag & SELECT)
				UI_ThemeColorShade(TH_DIS_MARKER, 128);
			else UI_ThemeColor(TH_DIS_MARKER);
		}
		else {
			if (track->pat_flag & SELECT)
				glColor3fv(scol);
			else glColor3fv(col);
		}

		glBegin(GL_LINE_LOOP);
		glVertex2fv(marker->pattern_corners[0]);
		glVertex2fv(marker->pattern_corners[1]);
		glVertex2fv(marker->pattern_corners[2]);
		glVertex2fv(marker->pattern_corners[3]);
		glEnd();
	}

	/* search */
	show_search = (TRACK_VIEW_SELECTED(sc, track) &&
	               ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
	if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
		if (track->flag & TRACK_LOCKED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->search_flag & SELECT)
				UI_ThemeColorShade(TH_LOCK_MARKER, 64);
			else UI_ThemeColor(TH_LOCK_MARKER);
		}
		else if (marker->flag & MARKER_DISABLED) {
			if (act)
				UI_ThemeColor(TH_ACT_MARKER);
			else if (track->search_flag & SELECT)
				UI_ThemeColorShade(TH_DIS_MARKER, 128);
			else UI_ThemeColor(TH_DIS_MARKER);
		}
		else {
			if (track->search_flag & SELECT)
				glColor3fv(scol);
			else
				glColor3fv(col);
		}

		glBegin(GL_LINE_LOOP);
		glVertex2f(marker->search_min[0], marker->search_min[1]);
		glVertex2f(marker->search_max[0], marker->search_min[1]);
		glVertex2f(marker->search_max[0], marker->search_max[1]);
		glVertex2f(marker->search_min[0], marker->search_max[1]);
		glEnd();
	}

	if (tiny)
		glDisable(GL_LINE_STIPPLE);

	glPopMatrix();
}
Example #29
0
static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
                                const float marker_pos[2], int width, int height)
{
	int tiny = sc->flag & SC_SHOW_TINY_MARKER;
	bool show_search = false;
	float px[2];

	UI_ThemeColor(TH_MARKER_OUTLINE);

	px[0] = 1.0f / width / sc->zoom;
	px[1] = 1.0f / height / sc->zoom;

	if ((marker->flag & MARKER_DISABLED) == 0) {
		float pos[2];
		float p[2];

		add_v2_v2v2(pos, marker->pos, track->offset);

		ED_clip_point_undistorted_pos(sc, pos, pos);

		sub_v2_v2v2(p, pos, marker_pos);

		if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
		                        marker->pattern_corners[2], marker->pattern_corners[3]))
		{
			if (tiny) glPointSize(3.0f);
			else glPointSize(4.0f);
			glBegin(GL_POINTS);
			glVertex2f(pos[0], pos[1]);
			glEnd();
			glPointSize(1.0f);
		}
		else {
			if (!tiny) glLineWidth(3.0f);
			glBegin(GL_LINES);
			glVertex2f(pos[0] + px[0] * 2, pos[1]);
			glVertex2f(pos[0] + px[0] * 8, pos[1]);

			glVertex2f(pos[0] - px[0] * 2, pos[1]);
			glVertex2f(pos[0] - px[0] * 8, pos[1]);

			glVertex2f(pos[0], pos[1] - px[1] * 2);
			glVertex2f(pos[0], pos[1] - px[1] * 8);

			glVertex2f(pos[0], pos[1] + px[1] * 2);
			glVertex2f(pos[0], pos[1] + px[1] * 8);
			glEnd();
			if (!tiny) glLineWidth(1.0f);
		}
	}

	/* pattern and search outline */
	glPushMatrix();
	glTranslatef(marker_pos[0], marker_pos[1], 0);

	if (!tiny)
		glLineWidth(3.0f);

	if (sc->flag & SC_SHOW_MARKER_PATTERN) {
		glBegin(GL_LINE_LOOP);
		glVertex2fv(marker->pattern_corners[0]);
		glVertex2fv(marker->pattern_corners[1]);
		glVertex2fv(marker->pattern_corners[2]);
		glVertex2fv(marker->pattern_corners[3]);
		glEnd();
	}

	show_search = (TRACK_VIEW_SELECTED(sc, track) &&
	               ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
	if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) {
		glBegin(GL_LINE_LOOP);
		glVertex2f(marker->search_min[0], marker->search_min[1]);
		glVertex2f(marker->search_max[0], marker->search_min[1]);
		glVertex2f(marker->search_max[0], marker->search_max[1]);
		glVertex2f(marker->search_min[0], marker->search_max[1]);
		glEnd();
	}
	glPopMatrix();

	if (!tiny)
		glLineWidth(1.0f);
}
Example #30
0
static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
                            int width, int height, float zoomx, float zoomy)
{
	float x, y;
	const int n = 10;
	int i, j, a;
	float pos[2], tpos[2], grid[11][11][2];
	MovieTracking *tracking = &clip->tracking;
	bGPdata *gpd = NULL;
	float aspy = 1.0f / tracking->camera.pixel_aspect;
	float dx = (float)width / n, dy = (float)height / n * aspy;
	float offsx = 0.0f, offsy = 0.0f;

	if (!tracking->camera.focal)
		return;

	if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0)
		return;

	UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);

	glPushMatrix();
	glTranslatef(x, y, 0);
	glScalef(zoomx, zoomy, 0);
	glMultMatrixf(sc->stabmat);
	glScalef(width, height, 0);

	/* grid */
	if (sc->flag & SC_SHOW_GRID) {
		float val[4][2], idx[4][2];
		float min[2], max[2];

		for (a = 0; a < 4; a++) {
			if (a < 2)
				val[a][a % 2] = FLT_MAX;
			else
				val[a][a % 2] = -FLT_MAX;
		}

		zero_v2(pos);
		for (i = 0; i <= n; i++) {
			for (j = 0; j <= n; j++) {
				if (i == 0 || j == 0 || i == n || j == n) {
					BKE_tracking_distort_v2(tracking, pos, tpos);

					for (a = 0; a < 4; a++) {
						int ok;

						if (a < 2)
							ok = tpos[a % 2] < val[a][a % 2];
						else
							ok = tpos[a % 2] > val[a][a % 2];

						if (ok) {
							copy_v2_v2(val[a], tpos);
							idx[a][0] = j;
							idx[a][1] = i;
						}
					}
				}

				pos[0] += dx;
			}

			pos[0] = 0.0f;
			pos[1] += dy;
		}

		INIT_MINMAX2(min, max);

		for (a = 0; a < 4; a++) {
			pos[0] = idx[a][0] * dx;
			pos[1] = idx[a][1] * dy;

			BKE_tracking_undistort_v2(tracking, pos, tpos);

			minmax_v2v2_v2(min, max, tpos);
		}

		copy_v2_v2(pos, min);
		dx = (max[0] - min[0]) / n;
		dy = (max[1] - min[1]) / n;

		for (i = 0; i <= n; i++) {
			for (j = 0; j <= n; j++) {
				BKE_tracking_distort_v2(tracking, pos, grid[i][j]);

				grid[i][j][0] /= width;
				grid[i][j][1] /= height * aspy;

				pos[0] += dx;
			}

			pos[0] = min[0];
			pos[1] += dy;
		}

		glColor3f(1.0f, 0.0f, 0.0f);

		for (i = 0; i <= n; i++) {
			glBegin(GL_LINE_STRIP);
			for (j = 0; j <= n; j++) {
				glVertex2fv(grid[i][j]);
			}
			glEnd();
		}

		for (j = 0; j <= n; j++) {
			glBegin(GL_LINE_STRIP);
			for (i = 0; i <= n; i++) {
				glVertex2fv(grid[i][j]);
			}
			glEnd();
		}
	}

	if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
		MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);

		if (track) {
			int framenr = ED_space_clip_get_clip_frame_number(sc);
			MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);

			offsx = marker->pos[0];
			offsy = marker->pos[1];

			gpd = track->gpd;
		}

	}
	else {
		gpd = clip->gpd;
	}

	if (sc->flag & SC_MANUAL_CALIBRATION && gpd) {
		bGPDlayer *layer = gpd->layers.first;

		while (layer) {
			bGPDframe *frame = layer->frames.first;

			if (layer->flag & GP_LAYER_HIDE) {
				layer = layer->next;
				continue;
			}

			glColor4fv(layer->color);
			glLineWidth(layer->thickness);
			glPointSize((float)(layer->thickness + 2));

			while (frame) {
				bGPDstroke *stroke = frame->strokes.first;

				while (stroke) {
					if (stroke->flag & GP_STROKE_2DSPACE) {
						if (stroke->totpoints > 1) {
							glBegin(GL_LINE_STRIP);
							for (i = 0; i < stroke->totpoints - 1; i++) {
								float npos[2], dpos[2], len;
								int steps;

								pos[0] = (stroke->points[i].x + offsx) * width;
								pos[1] = (stroke->points[i].y + offsy) * height * aspy;

								npos[0] = (stroke->points[i + 1].x + offsx) * width;
								npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy;

								len = len_v2v2(pos, npos);
								steps = ceil(len / 5.0f);

								/* we want to distort only long straight lines */
								if (stroke->totpoints == 2) {
									BKE_tracking_undistort_v2(tracking, pos, pos);
									BKE_tracking_undistort_v2(tracking, npos, npos);
								}

								sub_v2_v2v2(dpos, npos, pos);
								mul_v2_fl(dpos, 1.0f / steps);

								for (j = 0; j <= steps; j++) {
									BKE_tracking_distort_v2(tracking, pos, tpos);
									glVertex2f(tpos[0] / width, tpos[1] / (height * aspy));

									add_v2_v2(pos, dpos);
								}
							}
							glEnd();
						}
						else if (stroke->totpoints == 1) {
							glBegin(GL_POINTS);
							glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy);
							glEnd();
						}
					}

					stroke = stroke->next;
				}

				frame = frame->next;
			}

			layer = layer->next;
		}

		glLineWidth(1.0f);
		glPointSize(1.0f);
	}

	glPopMatrix();
}