[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [47108] branches/soc-2011-tomato/source/ blender: many small improvements to adding points
Campbell Barton
ideasman42 at gmail.com
Mon May 28 11:53:59 CEST 2012
Revision: 47108
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=47108
Author: campbellbarton
Date: 2012-05-28 09:53:59 +0000 (Mon, 28 May 2012)
Log Message:
-----------
many small improvements to adding points
- splines are open by default (double ctrl+click closes them)
- adding new points can be done even when a point in the middle of the spline is selected.
- adding new points re-orients the handles of previous point.
- fix for crash with open curve with one point only.
Workflow is Ctrl+Click about and double click to finish - works fast and gives nicer result then before.
Modified Paths:
--------------
branches/soc-2011-tomato/source/blender/blenkernel/BKE_mask.h
branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c
branches/soc-2011-tomato/source/blender/editors/mask/mask_intern.h
branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c
Modified: branches/soc-2011-tomato/source/blender/blenkernel/BKE_mask.h
===================================================================
--- branches/soc-2011-tomato/source/blender/blenkernel/BKE_mask.h 2012-05-28 09:20:04 UTC (rev 47107)
+++ branches/soc-2011-tomato/source/blender/blenkernel/BKE_mask.h 2012-05-28 09:53:59 UTC (rev 47108)
@@ -91,8 +91,10 @@
void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene, const int do_newframe);
void BKE_mask_parent_init(struct MaskParent *parent);
void BKE_mask_calc_handle_adjacent_length(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point);
+void BKE_mask_calc_tangent_polyline(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, float t[2]);
void BKE_mask_calc_handle_point(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point);
-void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point);
+void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point,
+ const short do_recalc_length);
void BKE_mask_get_handle_point_adjacent(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point,
struct MaskSplinePoint **r_point_prev, struct MaskSplinePoint **r_point_next);
void BKE_mask_calc_handles(struct Mask *mask);
Modified: branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c
===================================================================
--- branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c 2012-05-28 09:20:04 UTC (rev 47107)
+++ branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c 2012-05-28 09:53:59 UTC (rev 47108)
@@ -123,7 +123,7 @@
spline->tot_point = 1;
/* cyclic shapes are more usually used */
- spline->flag |= MASK_SPLINE_CYCLIC;
+ // spline->flag |= MASK_SPLINE_CYCLIC; // disable because its not so nice for drawing. could be done differently
spline->weight_interp = MASK_SPLINE_INTERP_LINEAR;
@@ -855,7 +855,9 @@
next_bezt = &next_point->bezt;
#if 1
- BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0);
+ if (prev_bezt || next_bezt) {
+ BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0);
+ }
#else
if (handle_type == HD_VECT) {
BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0);
@@ -922,6 +924,37 @@
*r_point_next = next_point;
}
+/* calculates the tanget of a point by its previous and next
+ * (ignoring handles - as if its a poly line) */
+void BKE_mask_calc_tangent_polyline(Mask *mask, MaskSpline *spline, MaskSplinePoint *point, float t[2])
+{
+ float tvec_a[2], tvec_b[2];
+
+ MaskSplinePoint *prev_point, *next_point;
+
+ BKE_mask_get_handle_point_adjacent(mask, spline, point,
+ &prev_point, &next_point);
+
+ if (prev_point) {
+ sub_v2_v2v2(tvec_a, point->bezt.vec[1], prev_point->bezt.vec[1]);
+ normalize_v2(tvec_a);
+ }
+ else {
+ zero_v2(tvec_a);
+ }
+
+ if (next_point) {
+ sub_v2_v2v2(tvec_b, next_point->bezt.vec[1], point->bezt.vec[1]);
+ normalize_v2(tvec_b);
+ }
+ else {
+ zero_v2(tvec_b);
+ }
+
+ add_v2_v2v2(t, tvec_a, tvec_b);
+ normalize_v2(t);
+}
+
void BKE_mask_calc_handle_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *point)
{
MaskSplinePoint *prev_point, *next_point;
@@ -945,7 +978,7 @@
void BKE_mask_calc_handle_adjacent_length(Mask *mask, MaskSpline *spline, MaskSplinePoint *point)
{
- /* TODO! - make this aspect aware! */
+ /* TODO! - make this interpolate between siblings - not always midpoint! */
int length_tot = 0;
float length_average = 0.0f;
@@ -977,11 +1010,14 @@
*
* Useful for giving sane defaults.
*/
-void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point)
+void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point,
+ const short do_recalc_length)
{
- /* TODO! - make this aspect aware! */
MaskSplinePoint *prev_point, *next_point;
const char h_back[2] = {point->bezt.h1, point->bezt.h2};
+ const float length_average = (do_recalc_length) ? 0.0f /* dummy value */ :
+ (len_v3v3(point->bezt.vec[0], point->bezt.vec[1]) +
+ len_v3v3(point->bezt.vec[1], point->bezt.vec[2])) / 2.0f;
BKE_mask_get_handle_point_adjacent(mask, spline, point,
&prev_point, &next_point);
@@ -992,6 +1028,12 @@
point->bezt.h1 = h_back[0];
point->bezt.h2 = h_back[1];
+
+ /* preserve length by applying it back */
+ if (do_recalc_length == FALSE) {
+ enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
+ enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
+ }
}
void BKE_mask_calc_handles(Mask *mask)
Modified: branches/soc-2011-tomato/source/blender/editors/mask/mask_intern.h
===================================================================
--- branches/soc-2011-tomato/source/blender/editors/mask/mask_intern.h 2012-05-28 09:20:04 UTC (rev 47107)
+++ branches/soc-2011-tomato/source/blender/editors/mask/mask_intern.h 2012-05-28 09:53:59 UTC (rev 47108)
@@ -73,8 +73,6 @@
int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point);
int ED_mask_select_check(struct Mask *mask);
-void ED_mask_point_select_set(struct MaskSplinePoint *point, int action);
-void ED_mask_point_select_set_handle(struct MaskSplinePoint *point, int select);
void ED_mask_select_toggle_all(struct Mask *mask, int action);
void ED_mask_select_flush_all(struct Mask *mask);
Modified: branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c
===================================================================
--- branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c 2012-05-28 09:20:04 UTC (rev 47107)
+++ branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c 2012-05-28 09:53:59 UTC (rev 47108)
@@ -301,7 +301,7 @@
return FALSE;
}
-static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], int threshold, int feather,
+static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather,
MaskObject **maskobj_r, MaskSpline **spline_r, MaskSplinePoint **point_r,
float *u_r, float tangent[2])
{
@@ -937,7 +937,7 @@
add_v2_v2(bezt->vec[0], vec);
sub_v2_v2(bezt->vec[2], vec);
#else
- BKE_mask_calc_handle_point_auto(mask, spline, new_point);
+ BKE_mask_calc_handle_point_auto(mask, spline, new_point, TRUE);
BKE_mask_calc_handle_adjacent_length(mask, spline, new_point);
#endif
@@ -952,8 +952,23 @@
/* **** add subdivide vertex **** */
-static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2])
+static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index)
{
+ MaskSplinePoint *new_point_array;
+
+ new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points");
+
+ memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1));
+ memcpy(new_point_array + point_index + 2, spline->points + point_index + 1,
+ sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1));
+
+ MEM_freeN(spline->points);
+ spline->points = new_point_array;
+ spline->tot_point++;
+}
+
+static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2])
+{
MaskObject *maskobj;
MaskSpline *spline;
MaskSplinePoint *point = NULL;
@@ -961,23 +976,15 @@
float tangent[2];
if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &maskobj, &spline, &point, NULL, tangent)) {
- MaskSplinePoint *new_point_array, *new_point;
+ MaskSplinePoint *new_point;
int point_index = point - spline->points;
ED_mask_select_toggle_all(mask, SEL_DESELECT);
- new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points");
+ mask_spline_add_point_at_index(spline, point_index);
- memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1));
- memcpy(new_point_array + point_index + 2, spline->points + point_index + 1,
- sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1));
+ new_point = &spline->points[point_index + 1];
- MEM_freeN(spline->points);
- spline->points = new_point_array;
- spline->tot_point++;
-
- new_point = &new_point_array[point_index + 1];
-
setup_vertex_point(C, mask, spline, new_point, co, tangent, NULL, TRUE);
/* TODO - we could pass the spline! */
@@ -1036,18 +1043,121 @@
}
}
-static int add_vertex_extrude(bContext *C, Mask *mask, float co[2])
+static int add_vertex_extrude(bContext *C, Mask *mask, const float co[2])
{
MaskObject *maskobj;
MaskSpline *spline;
MaskSplinePoint *point;
MaskSplinePoint *new_point = NULL, *ref_point = NULL;
+ /* check on which side we want to add the point */
+ int point_index;
+ float tangent_point[2];
+ float tangent_co[2];
+ int do_cyclic_correct = FALSE;
+ int do_recalc_src = FALSE; /* when extruding from endpoints only */
+ int do_prev; /* use prev point rather then next?? */
+
ED_mask_select_toggle_all(mask, SEL_DESELECT);
maskobj = BKE_mask_object_active(mask);
if (!maskobj) {
+ return FALSE;
+ }
+ else {
+ finSelectedSplinePoint(maskobj, &spline, &point, TRUE);
+ }
+
+ point_index = (point - spline->points);
+
+ MASKPOINT_DESEL(point);
+
+ if ((spline->flag & MASK_SPLINE_CYCLIC) ||
+ (point_index > 0 && point_index != spline->tot_point - 1))
+ {
+ BKE_mask_calc_tangent_polyline(mask, spline, point, tangent_point);
+ sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]);
+
+ if (dot_v2v2(tangent_point, tangent_co) < 0.0f) {
+ do_prev = TRUE;
+ }
+ else {
+ do_prev = FALSE;
+ }
+ }
+ else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) {
+ do_prev = TRUE;
+ do_recalc_src = TRUE;
+ }
+ else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) {
+ do_prev = FALSE;
+ do_recalc_src = TRUE;
+ }
+ else {
+ /* should never get here */
+ BLI_assert(0);
+ }
+
+ /* use the point before the active one */
+ if (do_prev) {
+ point_index--;
+ if (point_index < 0) {
+ point_index += spline->tot_point; /* wrap index */
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list