Commit: 2548ca35e2b1ed32d00eff801cde5433d9b3d4bf
Author: João Araújo
Date:   Sat Jun 25 23:27:33 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rB2548ca35e2b1ed32d00eff801cde5433d9b3d4bf

Curves: Extend tool/ Trim tool

Extend tool: fixed a few bugs, as described by dphantom in
http://blenderartists.org/forum/showthread.php?397450-GSoC-2016-Improvements-to-Bezier-Curves&p=3066750&viewfull=1#post3066750

Trim tool: Implemented spline_X_shape (helper function)

===================================================================

M       source/blender/editors/curve/editcurve.c

===================================================================

diff --git a/source/blender/editors/curve/editcurve.c 
b/source/blender/editors/curve/editcurve.c
index 4dd4c6e..5eb5c0c 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -6310,53 +6310,63 @@ void CURVE_OT_match_texture_space(wmOperatorType *ot)
 
 static ListBase *get_selected_splines(ListBase *nubase, int *r_number_splines, 
bool return_cyclic)
 {
-       /* receives a list with all splines in a "curve" object
+       /* receives a list with all Bezier splines in a "curve" object
         * returns the first spline of a linked list with all the selected 
splines,
         * along with the number of selected splines
         * if "return_cyclic" is false, it ignores cyclic splines */
 
        Nurb *nu, *nu_copy;
        BezTriple *bezt;
-       ListBase spline_list = {NULL, NULL};
+       ListBase *spline_list = (ListBase *)MEM_callocN(sizeof(ListBase), 
"get_selected_splines1");
        int handles;
 
-       for(nu=nubase->first; nu; nu = nu->next) {
+       for(nu=nubase->first; nu; nu = nu->next)
+       {
                handles = nu->pntsu;
                bezt = nu->bezt;
-               while (handles--) { /* cycle through all the handles. see if 
any is selected */
-                       if (BEZT_ISSEL_ANY(bezt) && (!nu->flagu || 
return_cyclic)) { /* this expression was deduced using truth tables */
+               while (handles--)
+               { /* cycle through all the handles. see if any is selected */
+                       if (BEZT_ISSEL_ANY(bezt) && (!nu->flagu || 
return_cyclic))
+                       { /* this expression was deduced using truth tables */
                                *r_number_splines += 1;
                                nu_copy = BKE_nurb_duplicate(nu);
                                nu_copy->next = NULL;
                                nu_copy->prev = NULL;
-                               BLI_addtail(&spline_list, nu_copy);
+                               BLI_addtail(spline_list, nu_copy);
                                break;
                        }
                        bezt++;
                }
        }
-       return &spline_list;
+       return spline_list;
 }
 
-static void get_selected_handles(Nurb* nu, BezTriple **r_handle_list)
+static ListBase *get_selected_handles(Nurb* nu, int *r_num_sel_handles)
 {
        /* Takes in the first element of a linked list of nurbs
-        * and returns an array with the BezTriple of the selected handles. */
+        * and returns a ListBase with the BezTriple of the selected handles. */
        BezTriple *bezt;
-       int i = 0, a;
+       LinkData *link;
+       ListBase *sel_handles = (ListBase *)MEM_callocN(sizeof(ListBase), 
"get_selected_handles1");
+       int a;
 
+       *r_num_sel_handles = 0;
        while (nu) {
                a = nu->pntsu;
                bezt = nu->bezt;
                while (a--) {
                        if (BEZT_ISSEL_ANY(bezt)) {
-                               r_handle_list[i] = bezt;
-                               i++;
+                               link = MEM_callocN(sizeof(LinkData), 
"get_selected_handles2");
+                               link->data = bezt;
+                               BLI_addtail(sel_handles, link);
+                               *r_num_sel_handles = *r_num_sel_handles + 1;
                        }
                        bezt++;
                }
                nu = nu->next;
        }
+
+       return sel_handles;
 }
 
 static void get_selected_endpoints(Nurb* nu, BezTriple **r_handle_list)
@@ -6525,7 +6535,7 @@ static ListBase *get_intersections(float *p1, float *p2, 
ListBase *nubase)
                                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 
&& len_v2v2(vi, p2) > PRECISION) {
+                               if (result == 1 && len_v2v2(vi, p1) > 
PRECISION) {
                                        intersection = 
MEM_callocN(sizeof(LinkData), "get_intersections4");
                                        intersection->data = vi;
                                        BLI_addtail(il, intersection);
@@ -6548,6 +6558,15 @@ static int extend_curve_exec(bContext *C, wmOperator *op)
        int n_selected_splines = 0, result = 0, a = 0;
        float p1[3], p2[3], p1_handle[3], bound_box[4], p1_extend[2];
 
+       for (nu = nubase->first; nu; nu = nu->next)
+       {
+               if (!(nu->type & CU_BEZIER))
+               {
+                       BKE_report(op->reports, RPT_ERROR, "Only Bezier curves 
can be extended");
+                       return OPERATOR_CANCELLED;
+               }
+       }
+
        spline_list = get_selected_splines(nubase, &n_selected_splines, false);
 
        /* the user can only select one or two splines */
@@ -6684,437 +6703,157 @@ void CURVE_OT_extend_curve(wmOperatorType *ot)
 
 /******************** 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]
+static int get_selected_spline_id(ListBase *nubase)
+{
+       /* receives a list with all splines in a "curve" object
+        * returns the number of the first selected spline */
 
+       Nurb *nu;
+       BezTriple *bezt;
+       int handles, i = 0;
 
+       for(nu=nubase->first; nu; nu = nu->next) {
+               handles = nu->pntsu;
+               bezt = nu->bezt;
+               while (handles--) { /* cycle through all the handles. see if 
any is selected */
+                       if (BEZT_ISSEL_ANY(bezt)) {
+                               return i;
+                       }
+                       bezt++;
+               }
+               i++;
+       }
+       return -1;
+}
 
+typedef struct XShape{
+       struct XShape *next, *prev;
+       float *intersections;
+       int order;
+       float distance;
+} XShape;
 
+static int XShape_cmp(const void *xs1, const void *xs2)
+{
+       XShape *x1 = (XShape *)xs1, *x2 = (XShape *)xs2;
+       return x1->distance > x2->distance ? 1 : 0;
+}
 
-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
+static ListBase *spline_X_shape(Object *obedit, int selected_spline)
+{
+       ListBase *nubase, *shape_list, *all_segments;
+       Nurb *nu;
+       const float PRECISION = 1e-05;
 
+       nubase = object_editcurve_get(obedit);
+       shape_list = linear_spline_list(nubase);
+       nu = BLI_findlink(nubase, selected_spline);
+       all_segments = interpolate_all_segments(nu);
+
+       /* check for self intersections */
+       ListBase *intersections;
+       XShape *xshape;
+       LinkData *segment, *spline;
+       float *coord_array, *full_coord_array, *vi, helper[3], 
*segment_coord_array;
+       int i = 0, a = 0, j = 0, k = 0;
+       intersections = (ListBase *)MEM_callocN(sizeof(ListBase), 
"splineXshape2");
+       full_coord_array = (float *)MEM_callocN(3 * (nu->pntsu * nu->resolu - 
1) * sizeof(float), "splineXshape3");
+
+       /* get the full coord_array for nu */
+       float *original_first_coord_array;
+       original_first_coord_array = (float *)MEM_callocN(3 * (nu->resolu + 1) 
* sizeof(float), "splineXshape7");
+       original_first_coord_array = ((LinkData *)all_segments->first)->data;
+       for (segment = all_segments->first; segment; segment = segment->next) {
+               coord_array = segment->data;
+               for (i = 0; i < 3 * (nu->resolu); i++) {
+                       full_coord_array[(a * 3 * (nu->resolu)) + i] = 
coord_array[i];
+               }
+               a++;
+       }
+       /* last point */
+       for (i = 0; i < 3; i++) {
+               full_coord_array[a * 3 * (nu->resolu) + i] = coord_array[3 * 
(nu->resolu) + i];
+       }
+
+       int sl_length = 0, result = 0;
+       for (i = 0; i < nu->resolu * (nu->pntsu - 1); i++) {
+               for (j = i + 2; j < nu->resolu * (nu->pntsu - 1); j++) {
+                       vi = (float *)MEM_callocN(3 * sizeof(float), 
"splineXshape4");
+                       result = isect_seg_seg_v2_point(&full_coord_array[i * 
3], &full_coord_array[(i + 1) * 3],
+                                                                               
        &full_coord_array[j * 3], &full_coord_array[(j + 1) * 3], vi);
+                       if (result == 1) {
+                               xshape = (XShape *)MEM_callocN(sizeof(XShape), 
"splineXshape1");
+                               xshape->intersections = vi;
+                               xshape->order = i / nu->resolu;
+                               copy_v3_v3(helper, vi);
+                               sub_v3_v3(helper, &full_coord_array[i * 3]);
+                               xshape->distance = sl_length + len_v3(helper);
+                               BLI_addtail(intersections, xshape);
+                       }
+               }
+               copy_v3_v3(helper, &full_coord_array[(i + 1) * 3]);
+               sub_v3_v3(helper, &full_coord_array[i * 3]);
+               sl_length += len_v3(helper);
+       }
+
+       /* check all other intersections with active spline */
+       sl_length = 0;
+       float l1, l2, l3, l4;
+       l1 = l2 = l3 = l4 = 0;
+       for (i = 0; i < nu->resolu * (nu->pntsu - 1); i++) {
+               j = 0;
+               for (spline = shape_list->first; spline; spline = spline->next, 
j++) {
+                       k = 0;
+                       for (segment = ((ListBase *)spline->data)->first; 
segment; segment = segment->next, k++) {
+                               segment_coord_array = segment->data;
+                               if (!(memcmp(original_first_coord_array, 
segment_c

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