[Bf-blender-cvs] [027361c] master: Fix T41834: Ctrl+LMB, Extrude Curves 2+ splines

Campbell Barton noreply at git.blender.org
Mon Jan 26 11:12:15 CET 2015


Commit: 027361c898b343a9c89182ebc15c1737e60946fc
Author: Campbell Barton
Date:   Mon Jan 26 20:55:41 2015 +1100
Branches: master
https://developer.blender.org/rB027361c898b343a9c89182ebc15c1737e60946fc

Fix T41834: Ctrl+LMB, Extrude Curves 2+ splines

Extrude and Ctrl+LMB now support multiple selected vertices.
Also maintain active vertices.

D964 by Tyler Sliwkanich with own modifications

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

M	source/blender/blenkernel/BKE_curve.h
M	source/blender/blenkernel/intern/curve.c
M	source/blender/editors/curve/editcurve.c

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

diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 13a1468..60cbf8b 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -176,6 +176,7 @@ void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_p
 void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev,  struct BezTriple *next,
                           const bool is_fcurve);
 void BKE_nurb_handle_calc_simple(struct Nurb *nu, struct BezTriple *bezt);
+void BKE_nurb_handle_calc_simple_auto(struct Nurb *nu, struct BezTriple *bezt);
 
 void BKE_nurb_handles_calc(struct Nurb *nu);
 void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index f1e9f2b..51330f2 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -3351,6 +3351,21 @@ void BKE_nurb_handle_calc_simple(Nurb *nu, BezTriple *bezt)
 	}
 }
 
+void BKE_nurb_handle_calc_simple_auto(Nurb *nu, BezTriple *bezt)
+{
+	if (nu->pntsu > 1) {
+		const char h1_back = bezt->h1, h2_back = bezt->h2;
+
+		bezt->h1 = bezt->h2 = HD_AUTO;
+
+		/* Override handle types to HD_AUTO and recalculate */
+		BKE_nurb_handle_calc_simple(nu, bezt);
+
+		bezt->h1 = h1_back;
+		bezt->h2 = h2_back;
+	}
+}
+
 /**
  * Use when something has changed handle positions.
  *
@@ -3608,24 +3623,12 @@ void BKE_nurbList_handles_recalculate(ListBase *editnurb, const bool calc_length
 
 				if (h1_select || h2_select) {
 
-					/* Override handle types to HD_AUTO and recalculate */
-
-					char h1_back, h2_back;
 					float co1_back[3], co2_back[3];
 
-					h1_back = bezt->h1;
-					h2_back = bezt->h2;
-
-					bezt->h1 = HD_AUTO;
-					bezt->h2 = HD_AUTO;
-
 					copy_v3_v3(co1_back, bezt->vec[0]);
 					copy_v3_v3(co2_back, bezt->vec[2]);
 
-					BKE_nurb_handle_calc_simple(nu, bezt);
-
-					bezt->h1 = h1_back;
-					bezt->h2 = h2_back;
+					BKE_nurb_handle_calc_simple_auto(nu, bezt);
 
 					if (h1_select) {
 						if (!calc_length) {
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 25dedee..f17c462 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -2007,7 +2007,7 @@ static void ed_curve_delete_selected(Object *obedit)
 }
 
 /* only for OB_SURF */
-bool ed_editnurb_extrude_flag(EditNurb *editnurb, short flag)
+bool ed_editnurb_extrude_flag(EditNurb *editnurb, const short flag)
 {
 	Nurb *nu;
 	BPoint *bp, *bpn, *newbp;
@@ -4888,285 +4888,405 @@ void CURVE_OT_spin(wmOperatorType *ot)
 	RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f);
 }
 
-/***************** add vertex operator **********************/
+/***************** extrude vertex operator **********************/
 
-static int addvert_Nurb(bContext *C, short mode, float location[3])
+static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb)
 {
-	Object *obedit = CTX_data_edit_object(C);
-	Curve *cu = (Curve *)obedit->data;
-	EditNurb *editnurb = cu->editnurb;
-	Nurb *nu, *newnu = NULL;
-	BezTriple *bezt, *newbezt = NULL;
-	BPoint *bp, *newbp = NULL;
-	float imat[4][4], temp[3];
-	bool ok = false;
-	BezTriple *bezt_recalc[3] = {NULL};
+	Nurb *nu = NULL;
+	Nurb *nu_last = NULL;
 
-	invert_m4_m4(imat, obedit->obmat);
+	bool changed = false;
 
-	findselectedNurbvert(&editnurb->nurbs, &nu, &bezt, &bp);
-
-	if ((nu == NULL) || (nu->type == CU_BEZIER && bezt == NULL) || (nu->type != CU_BEZIER && bp == NULL)) {
-		if (mode != 'e') {
-			if (cu->actnu != CU_ACT_NONE)
-				nu = BLI_findlink(&editnurb->nurbs, cu->actnu);
-
-			if (!nu || nu->type == CU_BEZIER) {
-				newbezt = (BezTriple *)MEM_callocN(sizeof(BezTriple), "addvert_Nurb");
-				newbezt->radius = 1;
-				newbezt->alfa = 0;
-				BEZ_SEL(newbezt);
-				newbezt->h2 = newbezt->h1 = HD_AUTO;
-
-				newnu = (Nurb *)MEM_callocN(sizeof(Nurb), "addvert_Nurb newnu");
-				if (!nu) {
-					/* no selected segment -- create new one which is BEZIER type
-					 * type couldn't be determined from Curve bt could be changed
-					 * in the future, so shouldn't make much headache */
-					newnu->type = CU_BEZIER;
-					newnu->resolu = cu->resolu;
-					newnu->flag |= CU_SMOOTH;
-				}
-				else {
-					memcpy(newnu, nu, sizeof(Nurb));
-				}
+	Nurb *cu_actnu;
+	union {
+		BezTriple *bezt;
+		BPoint    *bp;
+		void      *p;
+	} cu_actvert;
 
-				BLI_addtail(&editnurb->nurbs, newnu);
-				newnu->bezt = newbezt;
-				newnu->pntsu = 1;
+	BKE_curve_nurb_vert_active_get(cu, &cu_actnu, &cu_actvert.p);
+	BKE_curve_nurb_vert_active_set(cu, NULL, NULL);
 
-				temp[0] = 1;
-				temp[1] = 0;
-				temp[2] = 0;
+	/* first pass (endpoints) */
+	for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
 
-				copy_v3_v3(newbezt->vec[1], location);
-				sub_v3_v3v3(newbezt->vec[0], newbezt->vec[1], temp);
-				add_v3_v3v3(newbezt->vec[2], newbezt->vec[1], temp);
+		if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) {
+			continue;
+		}
 
-				mul_m4_v3(imat, newbezt->vec[0]);
-				mul_m4_v3(imat, newbezt->vec[1]);
-				mul_m4_v3(imat, newbezt->vec[2]);
+		if (nu->type == CU_BEZIER) {
 
-				ok = 1;
-				nu = newnu;
-			}
-			else if (nu->pntsv == 1) {
-				newbp = (BPoint *)MEM_callocN(sizeof(BPoint), "addvert_Nurb5");
-				newbp->radius = 1;
-				newbp->alfa = 0;
-				newbp->f1 |= SELECT;
+			/* Check to see if the first bezier point is selected */
+			if (nu->pntsu > 0 && nu->bezt != NULL) {
+				BezTriple *nu_bezt_old = nu->bezt;
+				BezTriple *bezt = nu->bezt;
 
-				newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
-				memcpy(newnu, nu, sizeof(Nurb));
-				BLI_addtail(&editnurb->nurbs, newnu);
-				newnu->bp = newbp;
-				newnu->orderu = 2;
-				newnu->pntsu = 1;
+				if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+					BezTriple *bezt_new;
+					BEZ_DESEL(bezt);
 
-				mul_v3_m4v3(newbp->vec, imat, location);
-				newbp->vec[3] = 1.0;
+					bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
+					ED_curve_beztcpy(editnurb, bezt_new + 1, bezt, nu->pntsu);
+					*bezt_new = *bezt;
 
-				newnu->knotsu = newnu->knotsv = NULL;
-				BKE_nurb_knot_calc_u(newnu);
 
-				ok = 1;
-				nu = newnu;
+					MEM_freeN(nu->bezt);
+					nu->bezt = bezt_new;
+
+					nu->pntsu += 1;
+
+					if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
+						cu_actvert.bezt = (cu_actvert.bezt == bezt) ?
+						                  bezt_new : &nu->bezt[(cu_actvert.bezt - nu_bezt_old) + 1];
+						BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
+					}
+
+					BEZ_SEL(bezt_new);
+					changed = true;
+				}
 			}
 
+			/* Check to see if the last bezier point is selected */
+			if (nu->pntsu > 1) {
+				BezTriple *nu_bezt_old = nu->bezt;
+				BezTriple *bezt = &nu->bezt[nu->pntsu - 1];
+
+				if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+					BezTriple *bezt_new;
+					BEZ_DESEL(bezt);
+
+					bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
+					ED_curve_beztcpy(editnurb, bezt_new, nu->bezt, nu->pntsu);
+					bezt_new[nu->pntsu] = *bezt;
+
+					MEM_freeN(nu->bezt);
+					nu->bezt = bezt_new;
+
+					bezt_new += nu->pntsu;
+					nu->pntsu += 1;
+
+					if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
+						cu_actvert.bezt = (cu_actvert.bezt == bezt) ?
+						                  bezt_new : &nu->bezt[cu_actvert.bezt - nu_bezt_old];
+						BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
+					}
+
+					BEZ_SEL(bezt_new);
+					changed = true;
+				}
+			}
 		}
+		else {
 
-		if (!ok)
-			return OPERATOR_CANCELLED;
-	}
+			/* Check to see if the first bpoint is selected */
+			if (nu->pntsu > 0 && nu->bp != NULL) {
+				BPoint *nu_bp_old = nu->bp;
+				BPoint *bp = nu->bp;
 
-	if (!ok && nu->type == CU_BEZIER) {
-		/* which bezpoint? */
-		if (bezt == &nu->bezt[nu->pntsu - 1]) {  /* last */
-			BEZ_DESEL(bezt);
-			newbezt = (BezTriple *)MEM_callocN((nu->pntsu + 1) * sizeof(BezTriple), "addvert_Nurb");
-			ED_curve_beztcpy(editnurb, newbezt, nu->bezt, nu->pntsu);
-			newbezt[nu->pntsu] = *bezt;
-			copy_v3_v3(temp, bezt->vec[1]);
-			MEM_freeN(nu->bezt);
-			nu->bezt = newbezt;
-			newbezt += nu->pntsu;
-			BEZ_SEL(newbezt);
-			newbezt->h1 = newbezt->h2;
-			bezt = &nu->bezt[nu->pntsu - 1];
-			ok = 1;
+				if (bp->f1 & SELECT) {
+					BPoint *bp_new;
+					bp->f1 &= ~SELECT;
 
-			if (nu->pntsu > 1) {
-				bezt_recalc[1] = newbezt;
-				bezt_recalc[0] = newbezt - 1;
-			}
-		}
-		else if (bezt == nu->bezt) {   /* first */
-			BEZ_DESEL(bezt);
-			newbezt = (BezTriple *)MEM_callocN((nu->pntsu + 1) * sizeof(BezTriple), "addvert_Nurb");
-			ED_curve_beztcpy(editnurb, newbezt + 1, bezt, nu->pntsu);
-			*newbezt = *bezt;
-			BEZ_SEL(newbezt);
-			newbezt->h2 = newbezt->h1;
-			copy_v3_v3(temp, bezt->vec[1]);
-			MEM_freeN(nu->bezt);
-			nu->bezt = newbezt;
-			bezt = newbezt + 1;
-			ok = 1;
+					bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__);
+					ED_curve_bpcpy(editnurb, bp_new + 1, bp, nu->pntsu);
+					*bp_new = *bp;
+
+					MEM_freeN(nu->bp);
+					nu->bp = bp_new;
+
+					nu->pntsu += 1;
+					BKE_nurb_knot_calc_u(nu);
 
+					if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) {
+						cu_actvert.bp = (cu_actvert.bp == bp) ?
+						                 bp_new : &nu->bp[(cu_actvert.bp - nu_bp_old) + 1];
+						BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp);
+					}
+
+					bp_new->f1 |= SELECT;
+					changed = true;
+				}
+			}
+
+			/* Check to see if the last bpoint is selected */
 			if (nu->pntsu > 1) {
-				bezt_recalc[1] = newbezt;
-				bezt_recalc[2] = newbezt + 1;
+				BPoint *nu_bp_old = nu->bp;
+				BPoint *bp = &nu->bp[nu->pntsu - 1];
+
+				if (bp->f1 & SELECT) {
+					BPoint *bp_new;
+					bp->f1 &= ~SELECT;
+
+					bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__);
+					ED_curve_bpcpy(editnurb, bp_new, nu->bp, nu->pntsu);
+					bp_new[nu->pntsu] = *bp;
+
+					MEM_freeN(nu->bp);
+					nu->bp = bp_new;
+
+					bp_new += nu->pntsu;
+					nu->pntsu += 1;
+
+					if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list