[Bf-blender-cvs] [2548ca3] gsoc2016-improved_extrusion: Curves: Extend tool/ Trim tool
João Araújo
noreply at git.blender.org
Sun Jun 26 00:29:07 CEST 2016
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. @@
More information about the Bf-blender-cvs
mailing list