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
