Ejemplo n.º 1
0
static void mask_evaluate_apply_point_parent(MaskSplinePoint *point, float ctime)
{
	float parent_matrix[3][3];
	BKE_mask_point_parent_matrix_get(point, ctime, parent_matrix);
	mul_m3_v2(parent_matrix, point->bezt.vec[0]);
	mul_m3_v2(parent_matrix, point->bezt.vec[1]);
	mul_m3_v2(parent_matrix, point->bezt.vec[2]);
}
Ejemplo n.º 2
0
static void setup_vertex_point(
        Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point,
        const float point_co[2], const float u, const float ctime,
        const MaskSplinePoint *reference_point, const bool reference_adjacent)
{
	const MaskSplinePoint *reference_parent_point = NULL;
	BezTriple *bezt;
	float co[3];

	copy_v2_v2(co, point_co);
	co[2] = 0.0f;

	/* point coordinate */
	bezt = &new_point->bezt;

	bezt->h1 = bezt->h2 = HD_ALIGN;

	if (reference_point) {
		if (reference_point->bezt.h1 == HD_VECT && reference_point->bezt.h2 == HD_VECT) {
			/* If the reference point is sharp try using some smooth point as reference
			 * for handles.
			 */
			int point_index = reference_point - spline->points;
			int delta = new_point == spline->points ? 1 : -1;
			int i = 0;
			for (i = 0; i < spline->tot_point - 1; ++i) {
				MaskSplinePoint *current_point;

				point_index += delta;
				if (point_index == -1 || point_index >= spline->tot_point) {
					if (spline->flag & MASK_SPLINE_CYCLIC) {
						if (point_index == -1) {
							point_index = spline->tot_point - 1;
						}
						else if (point_index >= spline->tot_point) {
							point_index = 0;
						}
					}
					else {
						break;
					}
				}

				current_point = &spline->points[point_index];
				if (current_point->bezt.h1 != HD_VECT || current_point->bezt.h2 != HD_VECT) {
					bezt->h1 = bezt->h2 = MAX2(current_point->bezt.h2, current_point->bezt.h1);
					break;
				}
			}
		}
		else {
			bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1);
		}

		reference_parent_point = reference_point;
	}
	else if (reference_adjacent) {
		if (spline->tot_point != 1) {
			MaskSplinePoint *prev_point, *next_point, *close_point;

			const int index = (int)(new_point - spline->points);
			if (spline->flag & MASK_SPLINE_CYCLIC) {
				prev_point = &spline->points[mod_i(index - 1, spline->tot_point)];
				next_point = &spline->points[mod_i(index + 1, spline->tot_point)];
			}
			else {
				prev_point = (index != 0)                     ? &spline->points[index - 1] : NULL;
				next_point = (index != spline->tot_point - 1) ? &spline->points[index + 1] : NULL;
			}

			if (prev_point && next_point) {
				close_point = (len_squared_v2v2(new_point->bezt.vec[1], prev_point->bezt.vec[1]) <
				               len_squared_v2v2(new_point->bezt.vec[1], next_point->bezt.vec[1])) ?
				               prev_point : next_point;
			}
			else {
				close_point = prev_point ? prev_point : next_point;
			}

			/* handle type */
			char handle_type = 0;
			if (prev_point) {
				handle_type = prev_point->bezt.h2;
			}
			if (next_point) {
				handle_type = MAX2(next_point->bezt.h2, handle_type);
			}
			bezt->h1 = bezt->h2 = handle_type;

			/* parent */
			reference_parent_point = close_point;

			/* note, we may want to copy other attributes later, radius? pressure? color? */
		}
	}

	copy_v3_v3(bezt->vec[0], co);
	copy_v3_v3(bezt->vec[1], co);
	copy_v3_v3(bezt->vec[2], co);

	if (reference_parent_point) {
		new_point->parent = reference_parent_point->parent;

		if (new_point->parent.id) {
			float parent_matrix[3][3];
			BKE_mask_point_parent_matrix_get(new_point, ctime, parent_matrix);
			invert_m3(parent_matrix);
			mul_m3_v2(parent_matrix, new_point->bezt.vec[1]);
		}
	}
	else {
		BKE_mask_parent_init(&new_point->parent);
	}

	if (spline->tot_point != 1) {
		BKE_mask_calc_handle_adjacent_interp(spline, new_point, u);
	}

	/* select new point */
	MASKPOINT_SEL_ALL(new_point);
	ED_mask_select_flush_all(mask);
}