[Bf-blender-cvs] [2ac3bc6] gsoc2016-improved_extrusion: Curves: Extend tool
João Araújo
noreply at git.blender.org
Wed Jun 22 22:12:06 CEST 2016
Commit: 2ac3bc6b1b312f70555e9f24c78ca49080ee069b
Author: João Araújo
Date: Wed Jun 22 21:10:46 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB2ac3bc6b1b312f70555e9f24c78ca49080ee069b
Curves: Extend tool
Fixed a bug with memory that was generating wrong results.
This commit also contains some of the code for the Trim tool, though most of it is commented out.
===================================================================
M source/blender/editors/curve/curve_intern.h
M source/blender/editors/curve/curve_ops.c
M source/blender/editors/curve/editcurve.c
===================================================================
diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h
index 2fb7fc7..882af34 100644
--- a/source/blender/editors/curve/curve_intern.h
+++ b/source/blender/editors/curve/curve_intern.h
@@ -129,6 +129,7 @@ void CURVE_OT_cyclic_toggle(struct wmOperatorType *ot);
void CURVE_OT_match_texture_space(struct wmOperatorType *ot);
void CURVE_OT_extend_curve(struct wmOperatorType *ot);
+void CURVE_OT_trim_curve(struct wmOperatorType *ot);
bool ED_curve_pick_vert(
struct ViewContext *vc, short sel, const int mval[2],
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index e158ba4..e3b2096 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -140,6 +140,7 @@ void ED_operatortypes_curve(void)
WM_operatortype_append(CURVE_OT_extrude);
WM_operatortype_append(CURVE_OT_cyclic_toggle);
WM_operatortype_append(CURVE_OT_extend_curve);
+ WM_operatortype_append(CURVE_OT_trim_curve);
WM_operatortype_append(CURVE_OT_match_texture_space);
}
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index a96b188..4dd4c6e 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -6469,7 +6469,7 @@ static ListBase *interpolate_all_segments(Nurb *nu)
int bezier_points = nu->pntsu;
while (i < bezier_points-1+nu->flagu) {
- coord_array = MEM_callocN(dims * (nu->resolu) * sizeof(float), "interpolate_bezier2");
+ coord_array = MEM_callocN(dims * (nu->resolu + 1) * sizeof(float), "interpolate_bezier2");
link = MEM_callocN(sizeof(LinkData), "interpolate_bezier3");
link->data = coord_array;
for (int j = 0; j < dims; j++) {
@@ -6477,7 +6477,7 @@ static ListBase *interpolate_all_segments(Nurb *nu)
nu->bezt[i%bezier_points].vec[2][j],
nu->bezt[(i+1)%bezier_points].vec[0][j],
nu->bezt[(i+1)%bezier_points].vec[1][j],
- coord_array + j, nu->resolu - 1, sizeof(float) * dims);
+ coord_array + j, nu->resolu, sizeof(float) * dims);
}
BLI_addtail(pl, link);
i++;
@@ -6506,7 +6506,7 @@ static ListBase *get_intersections(float *p1, float *p2, ListBase *nubase)
{
/* return a list with all the intersection points of the segment p1p2 with the curve object */
ListBase *spline_list, *points_list;
- ListBase *il = (ListBase *)MEM_callocN(sizeof(ListBase), "get_intersections1");;
+ ListBase *il = (ListBase *)MEM_callocN(sizeof(ListBase), "get_intersections1");
LinkData *intersection, *link, *spl;
float *coord_array, *vi, p3[2], p4[2];
Nurb *nu = nubase->first;
@@ -6518,14 +6518,14 @@ static ListBase *get_intersections(float *p1, float *p2, ListBase *nubase)
points_list = spl->data; /* output of interpolate_all_segments */
for (link = points_list->first; link; link=link->next) {
coord_array = (float *)link->data;
- for (int i = 0; i < nu->resolu - 1; i++) {
+ for (int i = 0; i < nu->resolu; i++) {
vi = (float *) MEM_callocN(3 * sizeof(float), "get_intersections2");
p3[0] = coord_array[i * dims];
p3[1] = coord_array[i * dims + 1];
p4[0] = coord_array[(i + 1) * dims];
p4[1] = coord_array[(i + 1) * dims + 1];
result = isect_seg_seg_v2_point(p2, p1, p3, p4, vi);
- if (result == 1 && len_v2v2(vi, p1) > PRECISION) {
+ if (result == 1 && len_v2v2(vi, p1) > PRECISION && len_v2v2(vi, p2) > PRECISION) {
intersection = MEM_callocN(sizeof(LinkData), "get_intersections4");
intersection->data = vi;
BLI_addtail(il, intersection);
@@ -6681,3 +6681,478 @@ void CURVE_OT_extend_curve(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/******************** Trim curve operator ********************/
+
+/*import bpy
+from mathutils import Vector
+from mathutils.geometry import intersect_line_line_2d, intersect_line_line, interpolate_bezier
+
+
+PRECISION = 1.0e-5
+
+
+def active_spline_id(shape_ob):
+ '''
+ returns integer of active spline
+ '''
+ return [i for i,s in enumerate(shape_ob.data.splines) if s == shape_ob.data.splines.active][0]
+
+
+def sel_point_id(spline_ob):
+ '''
+ > spline_ob: bezier spline object
+ < returns integer of selected points
+ '''
+ return [i for i,bp in enumerate(spline_ob.bezier_points) if bp.select_control_point]
+
+
+def interpolate_all_segments(spline_ob):
+ '''
+ > spline_ob: bezier spline object
+ < returns interpolated splinepoints
+ '''
+ point_range = len(spline_ob.bezier_points)
+ pl = []
+
+ for i in range (0, point_range-1+spline_ob.use_cyclic_u):
+ if len(pl) > 0:
+ pl.pop()
+ seg = (interpolate_bezier(spline_ob.bezier_points[i%point_range].co,
+ spline_ob.bezier_points[i%point_range].handle_right,
+ spline_ob.bezier_points[(i+1)%point_range].handle_left,
+ spline_ob.bezier_points[(i+1)%point_range].co,
+ spline_ob.resolution_u+1))
+ pl += seg
+ return pl
+
+
+def interpolate_spline(spline_ob):
+ '''
+ > spline_ob: bezier spline object
+ < returns segments as lists of vectors
+ '''
+ point_range = len(spline_ob.bezier_points)
+ segments = []
+
+ for i in range (0, point_range-1+spline_ob.use_cyclic_u):
+ segments.append(interpolate_bezier(spline_ob.bezier_points[i%point_range].co,
+ spline_ob.bezier_points[i%point_range].handle_right,
+ spline_ob.bezier_points[(i+1)%point_range].handle_left,
+ spline_ob.bezier_points[(i+1)%point_range].co,
+ spline_ob.resolution_u+1))
+ return segments
+
+
+def linear_spline_list(shape_ob):
+ '''
+ > shape_ob: bezier shape object
+ < returns list of linear interpolated splinepoints
+ '''
+ return [interpolate_spline(spl) for spl in shape_ob.data.splines]
+
+
+
+
+
+def is_between(x, a, b):
+ '''
+ > x, a, b = point
+ < True if x lies between a and b
+ '''
+ cross = (x[1] - a[1]) * (b[0] - a[0]) - (x[0] - a[0]) * (b[1] - a[1])
+ if abs(cross) > PRECISION: return False
+ dot = (x[0] - a[0]) * (b[0] - a[0]) + (x[1] - a[1])*(b[1] - a[1])
+ if dot < 0 : return False
+ squaredlengthba = (b[0] - a[0])*(b[0] - a[0]) + (b[1] - a[1])*(b[1] - a[1])
+ if dot > squaredlengthba: return False
+
+ return True
+
+
+def ratio_to_segment(x, p1, p2, p3, p4, res):
+ '''
+ > x: intersection point
+ > p1,p2,p3,p4: cubic bezier control points
+ < ratio of x to length of the segment
+ '''
+ seg = interpolate_bezier(p1, p2, p3, p4, res+1)
+ seg_length = length = ratio = 0
+
+ for i in range (len(seg)-1):
+ seg_length += (seg[i+1] - seg[i]).length
+
+ for i in range (len(seg)-1):
+ if is_between(x, seg[i], seg[i+1]):
+ length += (x - seg[i].to_2d()).length
+ return length/seg_length
+ else:
+ length += (seg[i+1] - seg[i]).length
+
+
+def split_segment(t,p1,p2,p3,p4):
+ '''
+ > t: ratio
+ > p1,p2,p3,p4: cubic bezier control points
+ < two lists of 4 control points using de Casteljau's algorithm
+ '''
+ q1 = p1 + (p2-p1)*t
+ q2 = p2 + (p3-p2)*t
+ q3 = p3 + (p4-p3)*t
+
+ r1 = q1 + (q2-q1)*t
+ r2 = q2 + (q3-q2)*t
+ r3 = r1 + (r2-r1)*t
+
+ return ([p1,q1,r1,r3], [r3,r2,q3,p4])
+
+
+def chop(x, p1, p2, p3, p4, res):
+ '''
+ > x: intersection point
+ > p1,p2,p3,p4: cubic bezier control points
+ > res: spline resolution
+ < both chopped segment's cubic bezier control points
+ '''
+
+ ratio = ratio_to_segment(x, p1, p2, p3, p4, res)
+
+ if ratio != None:
+ return split_segment(ratio, p1, p2, p3, p4)
+ else:
+ return None
+
+
+def main(context):
+
+ shape_ob = context.active_object
+ spline_ob = shape_ob.data.splines.active
+ spline_id = active_spline_id(shape_ob)
+
+ # gather all intersections of the active spline
+ spl_int = spline_X_shape(shape_ob, spline_id)
+ point_id = sel_point_id(shape_ob.data.splines[spline_id])
+
+ if len(point_id) > 1: return
+ else: point_id = point_id[0]
+
+ low = [x for x in spl_int if x[1] < point_id]
+ high = spl_int[len(low):]
+
+ # case of cyclic spline
+ if spline_ob.use_cyclic_u:
+
+ if len(low) + len(high) <= 1:
+ print ("cyclic spline needs at least 2 intersections")
+ return
+
+ elif len(low) + len(high) > 1:
+ print ("breaking up cyclic spline")
+ if len(low) == 0:
+ low = high
+ npoints = high[-1][1] - high[0][1] + 2
+ elif len(high) == 0:
+ high = low
+ npoints = low[-1][1] - low[0][1] + 2
+ else:
+ npoints = len(spline_ob.bezier_points) - high[0][1] + low[-1][1] + 2
+
+ spline_ob_data = [[[bp.co, bp.handle_left_type, bp.handle_right_type, bp.handle_left, bp.handle_right] for bp in spline_ob.bezier_points], spline_ob.resolution_u, spline_ob.use_cyclic_u]
+
+ shape_ob.data.splines.new('BEZIER')
+ new_spl = shape_ob.data.splines[-1]
+ new_spl.bezier_points.add(npoints-1)
+
+ print (len(spline_ob_data[0]), len(new_spl.bezier_points), npoints)
+
+ for i, bp in enumerate(new_spl.bezier_points):
+ print((i+high[0][1])%npoints)
+ bp.co, bp.handle_left_type, bp.handle_right_type, bp.handle_left, bp.handle_right = spline_ob_data[0][(i+high[0][1])%(len(spline_ob_data[0]))]
+ new_spl.resolution_u = spline_ob_data[1]
+
+ s1, s2 = chop(low[-1][0],
+ spline_ob.bezier_points[low[-1][1]].co,
+ spline_ob.bezier_points[low[-1][1]].handle_right,
+ spline_ob.bezier_points[(low[-1][1]+1)%(len(spline_ob_data[0]))].handle_left,
+ spline_ob.bezier_points[(low[-1][1]+1)%(len(
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list