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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to